前端工程师面试题自检篇(二)

2022-10-12 08:15:38 浏览数 (2)

请实现 DOM2JSON 一个函数,可以把一个 DOM 节点输出 JSON 的格式

题目描述:

代码语言:css复制
<div>
  <span>
    <a></a>
  </span>
  <span>
    <a></a>
    <a></a>
  </span>
</div>

把上诉dom结构转成下面的JSON格式

{
  tag: 'DIV',
  children: [
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] }
      ]
    },
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] },
        { tag: 'A', children: [] }
      ]
    }
  ]
}

实现代码如下:

代码语言:javascript复制
function dom2Json(domtree) {
  let obj = {};
  obj.name = domtree.tagName;
  obj.children = [];
  domtree.childNodes.forEach((child) => obj.children.push(dom2Json(child)));
  return obj;
}

扩展思考:如果给定的不是一个 Dom 树结构 而是一段 html 字符串 该如何解析?

那么这个问题就类似 Vue 的模板编译原理 我们可以利用正则 匹配 html 字符串 遇到开始标签 结束标签和文本 解析完毕之后生成对应的 ast 并建立相应的父子关联 不断的 advance 截取剩余的字符串 直到 html 全部解析完毕

关于原型的继承我们借助寄生组合继承

代码语言:javascript复制
function Person(obj) {
    this.name = obj.name
    this.age = obj.age
}
Person.prototype.add = function(value){
    console.log(value)
}
var p1 = new Person({name:"番茄", age: 18})

function Person1(obj) {
    Person.call(this, obj)
    this.sex = obj.sex
}
// 这一步是继承的关键
Person1.prototype = Object.create(Person.prototype)
Person1.prototype.play = function(value){
    console.log(value)
}
var p2 = new Person1({name:"鸡蛋", age: 118, sex: "男"})

说一下数组如何去重,你有几种方法?

代码语言:javascript复制
let arr = [1,1,"1","1",true,true,"true",{},{},"{}",null,null,undefined,undefined]

// 方法1
let uniqueOne = Array.from(new Set(arr)) console.log(uniqueOne)

// 方法2
let uniqueTwo = arr => {
    let map = new Map(); //或者用空对象 let obj = {} 利用对象属性不能重复得特性
    let brr = []
    arr.forEach( item => {
        if(!map.has(item)) { //如果是对象得话就判断 !obj[item]
            map.set(item,true) //如果是对象得话就obj[item] =true 其他一样
            brr.push(item)
        }
    })
    return brr
}
console.log(uniqueTwo(arr))

//方法3
let uniqueThree = arr => {
    let brr = []
    arr.forEach(item => {
        // 使用indexOf 返回数组是否包含某个值 没有就返回-1 有就返回下标
        if(brr.indexOf(item) === -1) brr.push(item)
        // 或者使用includes 返回数组是否包含某个值 没有就返回false 有就返回true
        if(!brr.includes(item)) brr.push(item)
    })
    return brr
}
console.log(uniqueThree(arr))

//方法4
let uniqueFour = arr => {                                         
     // 使用 filter 返回符合条件的集合
    let brr = arr.filter((item,index) => {
        return arr.indexOf(item) === index
    })
    return brr
}
console.log(uniqueFour(arr))

说一下类组件和函数组件的区别?

代码语言:javascript复制
1. 语法上的区别:

函数式组件是一个纯函数,它是需要接受props参数并且返回一个React元素就可以了。类组件是需要继承React.Component的,而且class组件需要创建render并且返回React元素,语法上来讲更复杂。

2. 调用方式

函数式组件可以直接调用,返回一个新的React元素;类组件在调用时是需要创建一个实例的,然后通过调用实例里的render方法来返回一个React元素。

3. 状态管理

函数式组件没有状态管理,类组件有状态管理。

4. 使用场景

类组件没有具体的要求。函数式组件一般是用在大型项目中来分割大组件(函数式组件不用创建实例,所有更高效),一般情况下能用函数式组件就不用类组件,提升效率。

说一下你对盒模型的理解?

代码语言:javascript复制
CSS3中的盒模型有以下两种:标准盒模型、IE盒模型
盒模型都是由四个部分组成的,分别是margin、border、padding和content
标准盒模型和IE盒模型的区别在于设置width和height时, 所对应的范围不同
1、标准盒模型的width和height属性的范围只包含了content
2、IE盒模型的width和height属性的范围包含了border、padding和content
可以通过修改元素的box-sizing属性来改变元素的盒模型;
1、box-sizing:content-box表示标准盒模型(默认值)
2、box-sizing:border-box表示IE盒模型(怪异盒模型)

写版本号排序的方法

题目描述:有一组版本号如下'0.1.1', '2.3.3', '0.302.1', '4.2', '4.3.5', '4.3.4.5'。现在需要对其进行排序,排序的结果为 '4.3.5','4.3.4.5','2.3.3','0.302.1','0.1.1'

实现代码如下:

代码语言:javascript复制
arr.sort((a, b) => {
  let i = 0;
  const arr1 = a.split(".");
  const arr2 = b.split(".");

  while (true) {
    const s1 = arr1[i];
    const s2 = arr2[i];
    i  ;
    if (s1 === undefined || s2 === undefined) {
      return arr2.length - arr1.length;
    }

    if (s1 === s2) continue;

    return s2 - s1;
  }
});
console.log(arr);

冒泡排序--时间复杂度 n^2

题目描述:实现一个冒泡排序

实现代码如下:

代码语言:javascript复制
function bubbleSort(arr) {
  // 缓存数组长度
  const len = arr.length;
  // 外层循环用于控制从头到尾的比较 交换到底有多少轮
  for (let i = 0; i < len; i  ) {
    // 内层循环用于完成每一轮遍历过程中的重复比较 交换
    for (let j = 0; j < len - 1; j  ) {
      // 若相邻元素前面的数比后面的大
      if (arr[j] > arr[j   1]) {
        // 交换两者
        [arr[j], arr[j   1]] = [arr[j   1], arr[j]];
      }
    }
  }
  // 返回数组
  return arr;
}
// console.log(bubbleSort([3, 6, 2, 4, 1]));

DNS如何工作的

DNS 的作用就是通过域名查询到具体的 IP。DNS 协议提供的是一种主机名到 IP 地址的转换服务,就是我们常说的域名系统。是应用层协议,通常该协议运行在UDP协议之上,使用的是53端口号。

因为 IP 存在数字和英文的组合(IPv6),很不利于人类记忆,所以就出现了域名。你可以把域名看成是某个 IP 的别名,DNS 就是去查询这个别名的真正名称是什么。

当你在浏览器中想访问 www.google.com 时,会通过进行以下操作:

  • 本地客户端向服务器发起请求查询 IP 地址
  • 查看浏览器有没有该域名的 IP 缓存
  • 查看操作系统有没有该域名的 IP 缓存
  • 查看 Host 文件有没有该域名的解析配置
  • 如果这时候还没得话,会通过直接去 DNS 根服务器查询,这一步查询会找出负责 com 这个一级域名的服务器
  • 然后去该服务器查询 google.com 这个二级域名
  • 接下来查询 www.google.com 这个三级域名的地址
  • 返回给 DNS 客户端并缓存起来

我们通过一张图来看看它的查询过程吧

0 人点赞