前言
惯例,上次一面完后十分钟来电话约好二面面试时间。二面官是个叔叔,可是他是为数不多的早到了的面试官,很爽快,一进来就直接开视频。他提出的问题都很有学习的价值。
面试时长:40 分钟
题目列表:
1. 假如现在 Function 的原型上没有bind 函数,请实现一个 bind 函数,请尽量考虑全面
我如果传入了第二个参数呢
这么写会断开原型,我如果想保持它的原型呢
如果我要使用你这个写了的 bind 方法 new 呢,就是作为构造函数
2. 二叉搜索树了解过吗,如何判断一个二叉树是二叉搜索树
3. 回流和重绘
4. 有什么避免回流的方法
5. * 防抖和事件节流
6. cookie 有什么属性,如何禁止别人访问 cookie
7. * 你知道 强会话 和 维持会话 吗(依稀记得可能是这么问的)
8. http缓存机制了解过吗?说下对于缓存有什么配置
9. * 如果http头里面同时设置了 Expires 和 Max-age 的话,怎么判断生命周期呢
10. 跨域的解决方案了解过吗,说一下
11. * HTTPS有了解过吗,HTTPS的建立连接的过程有了解过吗
12. * webpack 里面的 tree shaking了解过吗
13. 描述一下TCP的建立连接和断开连接的机制
14. 为什么TCP四次挥手最后是两倍最大包生存时间呢?
15. * 如果我等待1.5倍的最大包生存时间呢?
16. 括号匹配算法
题目
1.假如现在 Function 的原型上没有bind 函数,请实现一个 bind 函数,请尽量考虑全面
个人觉得实现一个 bind 函数最难的部分在于如果我想用 bind 函数返回的函数去new 一个实例呢?这么做就要区分是普通调用函数还是作为构造函数了。在上网查阅资料后发现了 new.target 的说法,如果是作为普通函数调用,new.target的值为 undefined,如果是作为构造函数调用,值为初始化类的类定义。
Function.prototype.bind = function (thisArg, ...params) {
const self = this;
const result = function () {
const arr = params.concat([].slice.call(arguments));
const _result = self.apply(thisArg, arr);
// 判断是否 用作 new 构造函数,如果是 普通函数调用, new.target 为 undefined
return (new.target ? thisArg : _result);
};
// 防止断开原型,让返回结果 继承 函数对象
result.prototype = Object.create(this.prototype);
result.prototype.constructor = result;
return result;
};
2.二叉搜索树了解过吗,如何判断一个二叉树是二叉搜索树
二叉搜索树,左子树的值小于根小于右子树。可以通过对二叉树进行中序遍历出来的序列是否是递增序列来判断是否是二叉搜索树。
3.回流和重绘
render tree 中添加或者删除节点,节点的几何属性发生变化,导致页面需要重新构建,就会引发回流;如果仅是节点的外观风格发生变化,页面仅需要渲染那部分的区域,则引发重绘。
回流必定引发重绘,重绘不一定引发回流。
4.有什么避免回流的方法
答案有很多,我答了一部分。如,将改变DOM元素的操作集中到一起操作,减少回流的次数;将可能发生频繁回流的元素做成 position: absolute 或者 fixed,让浏览器回流的时候仅回流那部分区域;避免使用table布局等等。
5.* 防抖和事件节流
这里我将防抖和节流的概念记混了,我说我了解节流,然后把防抖的知识说出来了,面试官笑着说其实你说的是防抖。。。
防抖:当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次
如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
效果是最终当用户停下操作时,只执行了一次
举例:实时搜索框
节流:当持续触发事件时,保证一定时间内只调用一次事件处理函数。
效果是一定时间间隔执行一次事件
举例:滚动事件
参考博客:https://blog.csdn.net/qq_41000891/article/details/82733532
6.cookie 有什么属性,如何禁止别人访问 cookie
cookie 的属性有:
- Expires,Max Age
- Domain和Path
- Size
- Secure
- httpOnly
- 等等
可以通过设置 domain 和 path 指定哪个域和哪个路径能访问cookie;还可以通过设置 httpOnly 表示 cookie 能否通过js 去访问
7. * 你知道 强会话 和 维持会话 吗(依稀记得可能是这么问的)
感觉面试官问的应该是 websocket 吧,当时没太听清楚,说了不了解。
8.http缓存机制了解过吗?说下对于缓存有什么配置
服务器端可以设置响应头的属性,如 Cache-Control,Expires,Max-age,Last-Modified,ETag等
由于我说了Expires 和 Max-age 属性,面试官抛出下一问。
9.* 如果http头里面同时设置了 Expires 和 Max-age 的话,怎么判断生命周期呢
Cache-control里的max-age会覆盖Expires
那么为何还要同时设置 max-age 和 Expires 呢:
因为 Expires 是 HTTP 1.0 定义的字段,而 Cache-Control 是 HTTP 1.1 的字段,万一客户端只支持 HTTP 1.0,那么 Cache-Control 有可能就会不工作,所以一般为了兼容会都写上。
10.跨域的解决方案了解过吗,说一下
jsonp,CORS(跨域资源共享)
11. * HTTPS有了解过吗,HTTPS的建立连接的过程有了解过吗
HTTPS = HTTP + SSL/TLS
- 客户端发送支持的加密协议及版本,SSL、TLS
- 服务器端从中筛选选择合适的加密协议
- 服务器端返回证书,证书中有公钥
- 客户端使用根证书验证证书合法性
- 客户端生成对称密钥,通过证书中的公钥加密,发送到服务器端
- 服务器端使用私钥解密,获取对称密钥,使用对称密钥加密数据
- 客户端解密数据,SSL开始通信
12. * webpack 里面的 tree shaking了解过吗
这个以前完全没有接触过,也是经过这次面试之后知道了有这个优化策略。
要了解 tree shaking,首先要知道 DCE(Dead Code Elimination):指在保持代码运行结果不变的前提下,去除无用的代码。
所谓 Dead Code 主要包括:
- 程序中没有执行的代码;如不可能进入的分支,return 之后的语句等
- 导致 dead variable 的代码;写入变量之后不再读取的代码(这种代码虽然执行了但是没有意义)
简单来说 tree shaking 就是 DCE 优化的一种方式。
13.描述一下TCP的建立连接和断开连接的机制
TCP三次握手和四次挥手。我将四次挥手里面的等待两倍最大包生存时间也说出来了。于是抛出下一问。
14.为什么TCP四次挥手最后是两倍最大包生存时间呢?
我当时回答了防止 ACK 包的丢包;如果ACK 丢包了,那么 对方会再次回送 FIN 包,两个包加起来的时间就是两倍最大保生存时间;所以最保险是要等两个最大包生存时间。面试官继续追问。
15. * 如果我等待1.5倍的最大包生存时间呢?
懵了,面试官说,如果只是等待1.5倍最大包生存时间就关闭,下次这个端口开启了的话将可能收到上次遗留的包信息。
16.括号匹配算法
匹配一个只存在 小括号(),中括号[],大括号{}的表达式是否合法
funciton fun(str) {
cosnt stack = [];
const map = {
')' : '(',
']' : '[',
'}' : '{'
};
const len = str.length;
for(let i = 0;i < len;i++) {
if(str[i] === '(' || str[i] === '[' || str[i] === '{') {
stack.push(str[i]);
} else {
if(stack[stack.length - 1] === map[str[i]]) {
stack.pop();
} else {
return false;
}
}
}
return stack.length === 0;
}
感想
面试虽然很心很累,但是面试可以问出你之前没有了解过的知识点;要善于总结面试经验,查漏补缺。