通俗易懂!看了不会忘的网络面试知识点
前言
关于网络,我想各位大兄弟是又爱又恨
爱的是各种强大的技术框架早已把网络封装的又简单又好用,天天 request,fetchData 用的飞起
恨的是每次面试的时候都要被问:
“HTTP 和 TCP 有什么区别?”
“HTTP 和 Socket 有什么区别?”
“什么是三次握手,四次挥手?”
“为什么不两次握手要三次握手?”
“为什么不三次挥手要四次挥手”
“为什么四次挥手的时候要等待 2msl?”
“http1.0 http1.1 http2.0 有什么区别?”
“http 和 https 有什么区别?”
....
??? 难道我每次请求数据的时候都要把这些默背一遍吗?这面试八股文呐,真真是让人头痛不已

别怕!为了让哥哥们能够一劳永逸,拒绝死记硬背!小弟我梳理了这份不怕忘的网络基础知识指南,供大家品尝~
什么是 HTTP 和 TCP ?
首先,我们要知道这两个都是协议,完整的叫法是 Http 协议和 TCP/IP 协议
协议,就是双方约定的内容。比如我和你约定,我给你个苹果,你要给我香蕉。苹果换香蕉就是我们协议的具体内容
所以 HTTP 和 TCP 本质上没什么神秘的地方,只是对网络请求做了一些规范。
那么问题来了,既然都是协议,它们有什么不同呢?
具体的不同当然有很多。但如果不是专业的网络技术人员的话,只需要有个整体的了解即可。这时候就要搬出老师教我们的 TCP/IP 分层模型图。

嘻嘻,熟不熟悉?这里我们只需要记住应用层和传输层就可以了,其他的基本很少用到
从这个模型可以知道,网络请求是一个很复杂的过程,复杂到必须分好几层,每层把自己的任务完成好才可以请求成功
传输层的任务就是建立网络连接
应用层就是在建立好的网络连接上传递各种类型数据。比如文本,图像,视频等等
既然网络请求这么复杂,指望用一个协议来描述整个网络请求过程是不可能的
所以 HTTP 对应的就是应用层协议,TCP 对应的是传输层协议
这就是 HTTP 和 TCP 的最大不同
Socket
这时候就引出一个概念,socket
什么是 socket 呢?
通过前文我们知道,HTTP 和 TCP 只是协议而已,协议本身没有是实现功能的能力的,需要一个载体实现它。
socket 就是 tcp 协议的实现。
它定义了一些建立连接的接口。比如 connect,listen,read 等等,这些接口方法的具体实现严格遵循 TCP 协议
好了,知道了是什么,接下来就是面试的重头戏
三次握手和四次挥手
我们首先明确,三次握手和四次挥手是 TCP/IP 协议的内容,它是属于运输层的,是网络请求在传输数据时建立连接和断开连接的方式
如何建立一个网络连接
在了解什么是三次握手之前,我们先探讨一个问题
现在有客户端 client 和服务端 serve,我们怎么样建立一个网络连接?
最简单的当然是客户端向服务端发送一个建立连接的请求,然后爱管不管,我就当连接已经建立了,美滋滋的原地等待,等服务端给我发送数据
这样可以吗?

当然不行了兄弟
万一服务端压根就没开机,万一人家理都不理你呢
就像给妹妹写情书一样,妹妹回应你这事才有戏。你不管妹妹回不回应一个劲给人家写,还傻傻的在那等。
那不叫爱,那是 X 骚扰和备胎

所以我们得出建立连接的一个基本准则
“请求必须要有回应”
继续往下想。既然要有回应,那我客户端向你发个请求,等接收到服务端的回应,再发下个请求。依次进行,是不是显得非常有秩序?

不愧是你,这就是“停止等待协议”
超时重传
“停止等待”就是网络请求最简单的版本
简单就意味着问题,因为网络环境是不稳定的
比如客户端的每个请求都要等收到上个请求的回复才发送,如果上个请求因为网络波动延迟了,或者干脆丢掉了,那客户端的下个请求岂不是永远发不出去了?数据就卡在这里了?
为了解决这个问题,TCP 协议里有个超时重传机制,如果长时间没收到回复就把原来的包再发一遍。还没收到再发,直到正常。

序列号
明白了网络连接建立时,“请求必须有回应”,“超时重传”,接下来我们再思考一个问题
我们知道,连接请求传输的数据是以数据包的形式传输的。也就是说,一次请求的数据是由多个数据包组成的。
如果一个数据包因为网络波动延迟了,在这延迟的期间触发了超时重传,这时候服务端就会接收到两个相同的包,服务端怎么处理呢?

处理的方法很简单。就是客户端在发送数据包的时候往里面加点“东西”,让服务端能够辨别这个包是从哪里来的
这个过程就是给数据包编号。这个号叫做数据包的序列号,这是接下来三次握手的关键
三次握手
终于到三次握手了,要不兄弟们先点个赞,换换脑子?

还是先上一个简单的前提
三次握手本质上其实是四次握手,只是把中间两次握手合并了而已。

因为建立连接是连续的。 服务端在第一次握手收到客户端的请求后,要马上发送回应, 同时发送自己的请求,所以把回应和请求合并成一次请求,也就是第二次握手
为什么不是两次握手而是三次握手呢?
那么问题来了,根据上面的“请求必须要有回应”基本准则
为什么不是两次握手而是三次握手呢?
谢希仁著的《计算机网络》第四版中,讲到“三次握手” 的目的是 “为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。
这句话当做面试八股文背下来也没什么问题。但其实这里面跳过了一个关键原因
还记得我们说数据包为什么要有序列号吗?
是为了让服务端能够辨别数据包的来源,区分是否是过时的数据包。
我们把眼光从数据包上升到一次网络连接。如果一个数据包延迟比较久,久到这次连接断开,下次连接建立,这时候服务端收到了旧连接的包,如何区分这两次连接呢?
答案是再加一个序列号
这个序列号叫初始序列号,用来标识一个连接。
这样结论就很清晰了。
初始序列号用来标识是否是同一个连接,数据包序列号用来标识一次连接中数据包的来源。
所以客户端需要向服务端发送表示本次连接的初始序列号
慢着,你还是不懂为什么是三次握手不是两次?
哈呀,你忘了 TCP 协议是全双工通信吗?客户端和服务端的概念是相对的,性别互换,亲妈不爱
客户端给服务端发送初始序列号是客户端建立的连接,服务端同时也可以作为客户端,也要向对方发送建立连接的初始序列号。再加上之前说的握手合并,不就是三次握手了嘛

恍然大悟了吧? 嘿嘿

来,自我检查一下,把自己当成面试官问自己
“为什么是三次握手不是四次握手”
“为什么是三次握手不是两次握手”
四次挥手
漫漫长征走过了一半,接下来我们看断开连接的四次挥手
其实四次挥手和三次握手差不多,不同的是第二次和第三次挥手不能合并
这是为什么呢?
前面说三次握手能合并的原因是 「建立连接是连续的」,服务端收到第一次握手请求后要马上回应同时发送请求。但因为 TCP 是全双工通信,客户端断开连接后服务端可能还需要发送数据。
所以客户端一次“请求--回应”
只是断开了客户端-->服务端
的连接,服务端过一会后才发送请求断开服务端-->客户端
的连接
为什么要等待 2MSL
这里有个小知识点,客户端在最后一次挥手发送回应后,会等待 2msl(msl 就是一个报文在网络上的最大存活时间)时间才完全关闭,这是为什么呢?
还是网络不稳定的问题。客户端最后一次挥手发出的回应报文如果延迟了或者丢了,服务端等待 1 个 MSL 没有收到的话会超时重传,重复第③次挥手的过程。
这样最多 2MSL 的时间客户端又会收到断开连接的请求,所以要最少等待 2MSL 时间再断开

好了,HTTP 和 TCP 的大部分知识点就讲完了。当然可拓展的地方还有非常多,比如“超时重传”那里,为了解决性能问题又引入了连续传输,滑动窗口,拥塞控制等等。不过这些算 HTTP 知识的枝干,只要掌握主干知识,其余枝叶还不是手到擒来

当然面试官还会问一些简单记忆就可以回答的问题,比如:
“你来说说 Http1.0 Http1.1 和 Http2.0 的区别”
Http1.0,Http1.1 和 Http2.0 的区别
刚才我们说的其实都是 Http1.0 的内容,用脚指头想 Http1.1 和 2.0 一定是做了优化。
Http1.1 的优化主要是实现了 长连接 ,同时也是目前最广泛的 Http 协议。
长连接的意思很简单。在 Http1.0 中,我们每请求一张图片就要建立一次 Tcp 连接,请求一个网页往往有几十上百次 Tcp 建立连接,断开连接,这样非常耗时,长连接的意思就是多个请求可以复用一个 Tcp 连接,提高了 Tcp 连接的利用率

如果面试官问你还有呢,你就跟他说还有断点续传
这个很容易理解吧,在 Http1.0 中,我们想知道一段视频中间的数据,必须先把整个视频下载下来。Http1.1 优化了这个逗比的场景,在请求头中加入了 range,可以只请求数据的一部分
如果问你还有呢....
你就说常用的差不多就这些了,不行我回去好好看看,等我们做了同事我再跟你好好说..

至于 Http2.0 就更牛逼了
它支持多路复用。 之前讲 Http1.1 只是复用 Tcp 连接,Http2.0 可以在一个请求上请求多个资源

类似于把两个请求合并成一个请求。服务端一次返回两次请求的资源。Amazing
未完待续
不知不觉就写了这么多了。尽可能通俗地把知识讲出来,是为了能给大家的理解起到一点点小小的帮助,不用每次痛苦地背八股文。
作者:方木 Rudy
链接:https://juejin.cn/post/6935611048862941220
来源:掘金
评论