前端面试每日3+2(第30天)
当你发现自己的才华撑不起你的野心时,就请安静下来学习吧!
鲁迅说过:
答案仅供参考...
# 1、谈谈你对TCP三次握手和四次挥手的理解。
解析:
三次握手(建立链接):
- A->B:你好我是A;
(A向B发送syn)
- B->A:收到,我是B;
(B接受syn,并返回A一个syn+ack的包给A)
- A->B:好的我们建立链接了。
(A确认接受syn+ack包,并向B发送ack,建立链接)
4次挥手(断开链接):
- A->B:你好,我要挂了 ;
(A向B发送fin)
- B->A: 好的,等会儿;
(B确认收到fin,向A发送ack,进入close-wait-1状态,不能再读取数据,但可以继续给A发送数据,)
- A收到后开始等待;
(A收到fin后,此时A进入close-wait-2等待状态)
- B->A: 好了,可以挂了;
(B向A发送fin,进入last-wait状态,等A回馈,不能读数据也不能发送数据)
- A->B: 收到,等两秒确认所有资料都受到了,和B说可以挂了!
(A收到fin后,向B发送ack,等2msl后,关闭,释放网络资源)
- B收到后,挂了。
(B收到ack,关闭,释放网络资源)
其它解读:
两次握手 (不安全,都没考量一下,万一加到的是个铁憨憨呢)
- 男:我喜欢你!加个微信吧
- 女:通过好友验证,开始交往。
三次握手 (安全、高效)
- 男:我喜欢你!可以加个微信吗?
- 女:长得还不错。是个渣男。我扫你。
- 通过好友验证,开始交往。
四次握手(浪费时间,影响效率)
- 男:我喜欢你!可以加个微信吗?
- 女:让我考虑一下。我去问下姐妹意见。
- 女:我考虑好了,我们加微信吧?
- 通过好友验证,开始交往。
四次挥手
- 男:分手!
- 女:呵呵,渣男!滚!将对方微信拉黑。
- 男:那你是同意了吗?(消息已发出,但被对方拒收了)继续等待对方回复确认分手。
- 女:经过一阵痛苦煎熬之后,好吧,分手吧。请把我送你的东西还回来。
- 男:快递寄出归还物品。等待2MSL,确认对方收到货物之后,删除对方。
- 女:收到货物,伤心欲绝,删除对方。释放自己单身资源。
参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)
# 2、 A、B 机器正常连接后,B 机器突然重启,问 A 此时处于 TCP 什么状态
如果A 与 B 建立了正常连接后,从未相互发过数据,这个时候 B 突然机器重启,问 A 此时处于 TCP 什么状态?如何消除服务器程序中的这个状态?(超纲题,了解即可)
解析:
这时候对于A机器来说,如果是刚打开网页的时候,那么浏览器选项卡左上角图标这时候会一直转圈,如果在短时间内B机器重新启动服务了,A机器会连接成功,如果超过了A机器的等待时间,这条请求会挂掉
参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)
# 3、(微医)React 中 setState 什么时候是同步的,什么时候是异步的?
解析:
在React中,如果是由React引发的事件处理(比如通过onClick引发的事件处理),调用setState不会同步更新this.state,除此之外的setState调用会同步执行this.state。所谓“除此之外”,指的是绕过React通过addEventListener直接添加的事件处理函数,还有通过setTimeout/setInterval产生的异步调用。
原因在React的setState函数实现中,会根据一个变量isBatchingUpdates判断是直接更新this.state还是放到队列中回头再说,而isBatchingUpdates默认是false,也就表示setState会同步更新this.state,但是,有一个函数batchedUpdates,这个函数会把isBatchingUpdates修改为true,而当React在调用事件处理函数之前就会调用这个batchedUpdates,造成的后果,就是由React控制的事件处理过程setState不会同步更新this.state。
参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)
详细解读 深入 setState 机制 (opens new window)
# 4、React setState 笔试题,下面的代码输出什么?
class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}
componentDidMount() {
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 1 次 log
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 2 次 log
setTimeout(() => {
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 3 次 log
this.setState({val: this.state.val + 1});
console.log(this.state.val); // 第 4 次 log
}, 0);
}
render() {
return null;
}
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
解析:
答案是: 0 0 2 3
参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)
# 5、介绍下 npm 模块安装机制,为什么输入 npm install 就可以自动安装对应的模块?
解析:
模块安装机制:
- npm install命令
- 查询node_modules目录中是否已经存在制定的模块
- 若存在,不需要重新安装
- 若不存在,
- npm向registry查询模块压缩包的网址
- 下载压缩包,存放在根目录下的.npm目录里
- 解压压缩包到当前项目的node_modules目录
npm实现原理: 输入npm install命令敲下回车后,会经历以下阶段(以npm5.5.1为例):
执行自身的的preinstall
确定首层依赖模块:
- 就是确定dependencies和devDependencies属性中指定的模块(假设没有添加npm install参数)
- npm会开启多进程从首层依赖模块逐步寻找更深的节点
获取模块
获取模块是个递归的过程。- (1)获取模块信息
- (2)获取模块实体,缓存-下载
- (3)查找该模块依赖,如果有返回(1),如果没有则停止
模块扁平化
上面会得到一个模块依赖树,其中包含大量的重复模块,起初npm3会重复安装,造成冗余,后来会通过dedupe过程去除重复模块
安装模块: 更新工程中的node_modules,并执行模块中的生命周期(preinstall、install、postinstall顺序)
执行工程自身的生命周期:npm工程自定义的生命钩子会执行
最后生产版本或更新版本的描述文件,npm install 过程完成
参考答案 (opens new window) --- 感谢【Daily-Interview-Question】 (opens new window)