美文网首页
十道前端面试题第【03】篇

十道前端面试题第【03】篇

作者: 夏海峰 | 来源:发表于2021-03-21 02:44 被阅读0次

摘要:本篇分享了10道面试题——Web性能优化方案、JS严格模式、五道算法题、自定义JS事件系统、输入URL到浏览器渲染的全过程、HTTP和HTTPS相关。



面试题

1、你知道的 Web 性能优化方案有哪些?

2、什么是严格模式?严格模式下,代码有哪些规范?

3、封装函数 flat() ,实现数组的扁平化。

需求:所谓扁平化,就是将一个嵌套多层的数组,转换为只有一层的数组。示例如下:

var arr = [1, [2, [3, 4]]]
flat(arr)  //  [1, 2, 3, 4]
function flat(arr) {
    return arr.reduce((prev, cur)=>{
        return prev.concat(Array.isArray(cur) ? flat(cur) : cur)
    }, [])
}

4、求柱状图中面积最大的矩形。

需求:给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。求在该柱状图中,能够勾勒出来的矩形的最大面积。

以上是柱状图的示例,其中每个柱子的宽度为 1,给定的高度为 [2,1,5,6,2,3] 举例:图中阴影部分为所能勾勒出的最大矩形面积 10
# 暴力实现
function maxArea(arr) {
    if (!arr || !arr.length) return 0
    let maxArea = 0
    for (let i = 0; i < arr.length; i++) {
        let minHeight = Infinity
        for (let j = i; j < arr.length; j++) {
            minHeight = Math.min(minHeight, arr[j])
            maxArea = Math.max(maxArea, (j - i + 1) * minHeight)
        }
    }
    return maxArea
}
# 优化实现
function maxArea(arr) {
    let maxArea = 0
    const stack = []
    arr = [0].concat(arr).concat([0])
    for (let i = 0; i < arr.length; i++) {
        while (stack && arr[stack[stack.length - 1]] > arr[i]) {
            const j = stack.pop()
            maxArea = Math.max((i - stack[stack.length - 1] - 1) * arr[j], maxArea)
        }
        stack.push(i)
    }
    return maxArea
}

5、封装快速排序算法。

快速排序
const quickSort = arr => {
    const a = [...arr];
    if (a.length < 2) return a;
    const pivotIndex = Math.floor(arr.length / 2);
    const pivot = a[pivotIndex];
    const [lo, hi] = a.reduce(
        (acc, val, i) => {
            if (val < pivot || (val === pivot && i != pivotIndex)) {
                acc[0].push(val);
            } else if (val > pivot) {
                acc[1].push(val);
            }
            return acc;
        },
        [[], []]
    );
    return [...quickSort(lo), pivot, ...quickSort(hi)];
};

6、封装选择排序算法。

选择排序
const selectionSort = arr => {
  const a = [...arr];
  for (let i = 0; i < a.length; i++) {
    const min = a
      .slice(i + 1)
      .reduce((acc, val, j) => (val < a[acc] ? j + i + 1 : acc), i);
    if (min !== i) [a[i], a[min]] = [a[min], a[i]];
  }
  return a;
};

7、封装插入排序算法。

插入排序
const insertionSort = arr =>
  arr.reduce((acc, x) => {
    if (!acc.length) return [x];
    acc.some((y, j) => {
      if (x <= y) {
        acc.splice(j, 0, x);
        return true;
      }
      if (x > y && j === acc.length - 1) {
        acc.splice(j + 1, 0, x);
        return true;
      }
      return false;
    });
    return acc;
  }, []);

8、自定义实现一个 JS 事件系统。

  • 自定义EventBus类,它的eventArr属性用于存放所有注册成功的自定义事件,这是一个事件容器。
  • 原型链上的 on() 方法,用于绑定一个自定义事件,这类事件可以被多次触发。
  • 原型链上的 once() 方法,用于绑定只能被触发一次的自定义事件。
  • 原型链上的 off() 方法,用于解绑指定的自定义事件。
  • 原型链上的 emit() 方法,用于触发事件容器中的指定类型的自定义事件。
function Event() {
    this.eventArr = []
}

// on() 方法,用于绑定一个自定义事件
Event.prototype.on = function (eventType, callbackFn) {
    this.eventArr.push({
        eventType,
        callbackFn,
        once: false,
        done: false
    })
}

// once() 方法,用于绑定只能触发一次的自定义事件
Event.prototype.once = function (eventType, callbackFn) {
    this.eventArr.push({
        eventType,
        callbackFn,
        once: true,
        done: false
    })
}

// off() 方法,用于解绑自定义事件
Event.prototype.off = function (eventType, callbackFn) {
    this.eventArr.map((ele, idx) => {
        if (ele.eventType === eventArr && ele.callbackFn === callbackFn) {
            this.eventArr.splice(idx, 1)
        }
    })
}

// emit() 方法,用于触发事件模型中指定类型的自定义事件
Event.prototype.emit = function (eventType) {
    this.eventArr.map((ele, idx) => {
        if (ele.eventType === eventType) {
            if (!ele.done) {
                ele.callbackFn()
                if (ele.once) {
                    this.eventArr[idx].done = true  // 把once注册的事件,标记为“done”
                }
            }
        }
    })
}

// 测试一下
const bus = new Event()
bus.on('xxx', ()=>console.log('xxx'))
bus.emit('xxx')

9、描述浏览器输入URL到页面渲染的整个过程。

  • 浏览器的地址栏输入URL并按下回车;
  • DNS 解析:将域名解析成 IP 地址;
  • TCP 连接:TCP 三次握手;(三次握手的目的:为了防止已经失效的连接请求报文段突然又传送到了服务器端,从而产生错误)
  • 发送 HTTP 请求;
  • 服务器处理请求并返回 HTTP 报文;
  • 浏览器解析渲染页面;
  • 断开连接:TCP 四次挥手。
HTTP HTTP事务的过程

10、HTTP和HTTPS有哪些区别?HTTP报文由哪些部分组成?

HTTPS = HTTP + 加密 + 身份验证 + 数据完整性保护。

从 HTTP 协议栈层面来看,我们可以在 TCP 和 HTTP 之间插入一个安全层,所有经过安全层的数据都会被加密或者解密(如下图所示)。

HTTP vs. HTTPS

本周结束,下周继续!!!

相关文章

网友评论

      本文标题:十道前端面试题第【03】篇

      本文链接:https://www.haomeiwen.com/subject/fnogcltx.html