作者:沈自在
1 Get 和 Post 有什么区别?
这个区别要建立在RFC规范的基础上去讨论,那么就有以下几点区别:
- 安全性和幂等性:因为RFC规范了GET请求只能进行资源获取,而Post请求则可以操作服务器资源,那么单纯的获取而不更改的操作便是安全和幂等的了
- Get请求可以用做标签收藏,这也离不开Get请求的语意
- 参数传递不同:Get请求会在URL中去拼接参数,而Post请求则是在Body中传递参数,这样的话就对参数的大小有了限制,这也是一些浏览也所带来的限制,比如Chrome浏览器就限制了8182个字符。
- 缓存问题:由于Get请求的语意是对资源的获取,那么这个操纵就可以添加缓存来提高效率
- 发送次数:比较有特点是Post请求可能会比Get多发一次数据包(第一次为:OPTION预检请求)
2 了解HTTP缓存吗?
这个HTTP缓存呢主要分为俩种,分别是协商缓存和强制缓存。
-
对于强制缓存,意思是直接使用本地缓存,这个是根据响应中对缓存有效期的定义来看的,比如可以使用Cache-Control,Expires对它定义:其中Cache-Control所定义的是相对时间,而Expires则是绝对时间
-
对于协商缓存,其本质在于询问服务端本地缓存是否可用,这就有俩种情况:
-
第一:返回304代表本地缓存可以用
-
第二:返回200则代表有更新,不能用本地缓存
那么对于协商这个过程有俩种判断缓存是否过期的办法:
- 第一:通过修改时间,具体的话就是 Last-Modifed-since 如果实际时间超前则判断有更新
- 第二:通过唯一标示,具体而言就是使用 Etag ,如果不一样则代表更改了。
3 HTTPS 解决了哪些问题?
HTTPS 相对于 HTTP 而言,它主要解决的是信息安全的问题,比如由于HTTP的明文传输,那么就很容易会被拦截篡改,像早年前的一些网站会被植入广告之类的,而HTTPS的解决方案就在于在HTTP和TCP层之间引入了SSL/TLS协议,而这个握手机制有这么几个关键点:
- 混合加密(在会话建立前使用非对称加密交换会话密钥,建立后用对称加密保护数据),这里解决的是窃听问题。
- 摘要算法:将数据和内容的HASH一起发出去,如果在没有被篡改的情况下客户端对数据的Hash计算应该和服务端的是吻合的,这就可以防止内容被篡改
- 数字签名算法:将摘要算法得到内容通过数字签名算法加密传输到客户端,用公钥解密。来防止信息不被冒充(如果反过来则是保证内容传输安全)
4 讲解一下 HTTPS 的 RSA 握手
TLS的握手过程中主要四次握手:
-
第一次握手是客户端向服务端发送 ClientHello,主要包含的内容有客户端使用的TLS版本号、支持的密码套件列表、和第一个随机数
-
第二次握手中是服务端向客户端发送ServerHello,主要包括的内容有确定的TLS版本号,选择的密码套件和第二个随机数(密码套件的基本形式是:密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法)
-
随后还会发送 Server Certificate 给客户端证明身份
-
最后发送 ServerHelloDone 消息,告诉客户端传输完毕
-
第三次握手是客户端生成一个新的随机数,用服务端的RSA公钥加密传输给服务端,服务端收到后用私钥解密结合三个随机数,双方会生成会话密钥,接着客户端会像服务端再发俩条消息:
-
第一条是Change Cipher spec,告诉服务端开始用加密方式发送信息
-
第二条是对之前所有的消息做一个摘要加密验证加密是否可行
-
第四次握手类似第三次握手的后俩条
5 RSA 算法的缺陷是什么?
最大的缺陷在于不支持前向保密,因为客户端传递随机数(用于生成对称加密密钥的条件之一)给服务端时使用的是公钥加密的,服务端收到后,会用私钥解密得到随机数。所以一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通讯密文都会被破解。
6 讲解一下HTTPS ECDHE握手
ECDHE握手主要也是四次握手:
-
第一次握手和RSA类似,主要包括TLS版本号、支持的协议套件、一个随机数
-
第二次握手的区别就有点大了,
-
第一次发送是确定TLS版本号、选择的加密套件、一个随机数(这个加密套件的协商算法会变成ECDHE)
-
第二次发送则是数字证书
-
发送证书后则会发送 Server Key Change消息,会用RSA签名算法给椭圆曲线公钥加密并传输
-
最后发送Server Hello Done
-
第三次握手,是客户端的椭圆曲线公钥传输给服务端,至此双方会计算出共享密钥x,用于后续的会话密钥生成(会话密钥是根据客户端随机数和服务端随机数加x生成的)
-
当密钥生成后会发送开始加密通信的标识
-
以及一次数据验证
-
第四次握手,同上。
7 你了解 HTTP 的历史演进吗?
HTTP至今一共有五个版本:分别是 0.9、1.0、1.1、2.0、3.0
- HTTP0.9:只支持 Get,只能返回HTML,很快就被废弃
- HTTP1.0:任何格式的内容都可发送,支持了Get Post,请求响应的格式也发生了变化,缺点在于只能发送一次
- HTTP1.1:引入了长连接和管道机制(管道就是一个TCP连接客户端可以发送多次请求)缺点在于响应需要排序容器产生
- HTTP2.0:引入了SPDY协议,可以通过压缩、多路复用和优先级等技术,缩短网页的加载时间并提高安全性
- HTTP3.0:基于UDP实现的可靠传输
8 TCP 和 UDP 有什么区别?
- TCP是面向连接的而UDP是无连接的
- TCP是一对一的俩点传输,而UDP支持一对一、一对多、多对多
- TCP时可靠交付的,而UDP不可卡片
- TCP具备拥塞控制、流量控制,而UDP没有
- TCP的首部开销大而UDP只有8字节
9 简单介绍一些TCP的三次握手?
对于TCP的三次握手其实就是双方序列号的发送与确认:
-
第一次握手:客户端向服务端发送数据包,数据包中有自己的序列号并且syn位是1
-
第二次握手:其实包含俩个过程,分别是服务端向客户端发送自己的序列号,以及对客户端sync的ack
-
syn和ack都标志为1
-
序列号初始化为服务端自己的
-
应答号为客户端序列号加1
-
第三次握手:这次握手是对服务端数据包的确认,值得一提的是,客户端在发送这个ack后就进入了建立状态,也就意味着第三次握手是可以携带数据的,当服务端接收到ack后也会进入建立状态。
10 为什么是三次握手,不是俩次或者四次
首先三次握手具备三个优点:
-
第一:可以避免历史连接(提供中间状态,方便中断连接)
-
先收到新Syn、则会ChallengeAck(上一次的序列号+1),客户端发现预期不对,则会发送RST断开连接
-
先收到RST,旧的就会失效
-
第二:同步双方序列号(双向确认)
-
第三:避免资源浪费
11 为什么每次建立 TCP 连接时,初始化的序列号都要求不一样呢?
原因有俩方面:
- 第一是要避免历史报文被相同四元组接收(发送数据包后被阻塞,导致超时重传,但服务端此时断电重启,连接断开了,客户端因此发送了RST。紧接着又建立了一个相同的四元组,则正好会接收被阻塞的数据包)
- 为了安全性,防止被伪造
12 初始序列号ISN是如何随机的?
起始 ISN 是基于时钟的,每 4 微秒 + 1,转一圈要 4.55 个小时。
13 简单介绍一下握手丢失会出现哪些情况
第一次握手丢失:客户端会超时重传
第二次握手丢失:客户端会超市重传,服务端也会(因为第二次握手包含俩个概念 ack + syn)
第三次握手丢失:服务端会超市重传
⚠️****注意:ACK是不会出发超时重传的
14 什么是 SYN 攻击?如何避免 SYN 攻击?
首先在TCP连接的建立过程中会维护俩个队列,分别是:
- 半连接队列
- 全连接队列
二次第二次握手后,服务端会进入Syn_Rcvd状态,此时就会进入半连接队列(只有当收到ACK后才会进入全连接队列),但是如果有人恶意发起第一次握手,而不去响应第二次握手,那么半连接队列就会被占满,此时服务端就不能正常提供服务了。
15 简单介绍一下四次挥手的过程
假设客户端主动断开连接
第一次:客户端发送fin,自己进入FIn_wait_1状态
第二次:服务端在收到fin后返回ack,自己进入close wait 状态,而客户端在收到ack后进入fin_wait_2
第三次:服务端close wait结束后发送 fin标记
第四次:客户端在收到fin后并发送ack自己进入time_wait状态
如果服务端没有要发送的数据,则会变成三次挥手
🌎MSL 默认30s TTL默认64跳
16 四次挥手丢失情况分析
第一次丢失:客户端重传
第二次丢失:客户端重传
第三次丢失:服务端重传
第四次丢失:第三次重发
17 讲解一下TCP的重传机制?
对于TCP的重传机制,一共有四种重传机制:
- 超时重传:对于超时重传,是定时器驱动的,如果一定时间没得到回复则会触发超时重传。
- 快速重传:连续收到三次同样的ack则证明消息丢失所触发的重传
- SACK:在TCP头部中会存储已经接收到的数据编号,如果发送方收到三次同样的ack就会触发快速重传
- D-SACK:是借用SACK去告诉发送方消息被重复发送了,
18 讲解一下滑动窗口机制
滑动窗口呢其实是TCP实现流量控制的一个算法,他主要分为发送方窗口和接收方窗口。(发送窗口和接收窗口的默认大小是360)
对于发送方窗口:
它主要分为四段分别是:已发送已ack、已发送未ack、未发送但在接收方处理能力范围内、未发送但超过处理能力(可用窗口大小指的是窗口大小减去已发送未ack的部分)
**窗口缩小:**对于窗口的缩小和接收方的缓冲区有关系,比如发送140字节的数据,接收方只处理了40的数据,剩下的100则会进入缓冲区,而在ack的过程中会将窗口大小缩减100
**窗口关闭:**如果发送方窗口大小减小为0则会触发窗口关闭,此后则会去发送探测报文去判断窗口大小是否发生改变(定时器处理,超过三次则断开,每次30-60s)
**窗口死锁:**因为窗口大小的变化是拼接ack返回的,如果发送方窗口为0,同时接收方返回的非0ack丢失了,那么就会触发窗口死锁
⚠️****注意:MSS是最大报问长度
19 讲解一下糊涂窗口综合症
由于接收方处理能力问题,窗口大小最终会变得很小,比如只比TCP/IP的头部稍大一点,那么每次传输的数据就是很有限的,这无疑是极大的浪费资源,解决方案呢也有俩种。
-
让接收方不通告小窗口给发送方(当窗口大小小于一定尺寸后则直接ack0)
-
避免发送小数据
-
这个就是Nagle算法的使用了,Nagle算法的条件如下:
-
只有当窗口大小和数据大小均大于MSS才会发送
-
收到ack
20 讲解一下TCP的拥塞控制
对于TCP的拥塞控制主要是四个算法,分别是:
- 满启动算法
- 拥塞避免算法
- 拥塞发生算法
- 快速回复算法
这里面有俩个比较重要的参数,一个拥塞窗口的大小,一个是满启动门限。
对于满启动算法,拥塞窗口会每在每收到一个ack就会增加1,直到增加到满启动门限,那么如果超过了满启动门限,则会进行拥塞避免算法,对于拥塞避免其实就是缩减了增长速度,有以前的每个ack增加1变成了1/满启动门限。
而拥塞发生则会有俩种情况,分别是超时重传触发和快速重传触发,如果是超时重传,则证明当前网络拥塞严重,则满启动窗口会直接回到初始状态,满启动门限减半。如果是快速重传,则会分别减半同时触发快速恢复算法,含义是每收到ack或者重复ack则加1.