1. 1. 计网面试
    1. 1.0.1. 什么是三次握手 (three-way handshake)?
      1. 1.0.1.1. TCP建立连接可以两次握手吗?为什么?
      2. 1.0.1.2. 可以采用四次握手吗?为什么?
      3. 1.0.1.3. 第三次握手中,如果客户端的ACK未送达服务器,会怎样?
      4. 1.0.1.4. 如果已经建立了连接,但客户端出现了故障怎么办?
      5. 1.0.1.5. 初始序列号是什么?
      6. 1.0.1.6. 为什么初始序列号要是随机的?
      7. 1.0.1.7. 注意
    2. 1.0.2. 什么是四次挥手?
      1. 1.0.2.0.1. 为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态意义是什么)?
      2. 1.0.2.0.2. 如果第二次挥手时服务器的ACK没有送达客户端,会怎样?
      3. 1.0.2.0.3. 客户端TIME_WAIT状态的意义是什么?
  2. 1.0.3. TCP如何实现流量控制?
    1. 1.0.3.0.1. 什么是零窗口(接收窗口为0时会怎样)?
  • 1.0.4. TCP的拥塞控制是怎么实现的?
  • 1.0.5. TCP与UDP的区别
  • 1.0.6. 什么时候选择TCP,什么时候选UDP?
    1. 1.0.6.0.1. HTTP可以使用UDP吗?
  • 1.0.6.1. 面向连接和无连接的区别
  • 1.0.6.2. TCP如何保证传输的可靠性
  • 1.0.6.3. 简述TCP粘包现象
  • 1.0.6.4. TCP粘包现象处理方法
  • 1.0.7. TCP的缺陷
    1. 1.0.7.1. 升级 TCP 的工作很困难
    2. 1.0.7.2. TCP 建立连接的延迟
    3. 1.0.7.3. TCP 存在队头阻塞问题
    4. 1.0.7.4. 网络迁移需要重新建立 TCP 连接
  • 1.0.8. 怎么用UDP来实现TCP?
    1. 1.0.8.1. 实现可靠传输—头部设计
      1. 1.0.8.1.1. TCP 重传的歧义问题
    2. 1.0.8.2. QUIC 是如何解决 TCP 队头阻塞问题的?
      1. 1.0.8.2.1. HTTP/2 的队头阻塞
      2. 1.0.8.2.2. 没有队头阻塞的 QUIC
    3. 1.0.8.3. QUIC 是如何做流量控制的?
    4. 1.0.8.4. QUIC 对拥塞控制改进
    5. 1.0.8.5. QUIC 更快的连接建立
    6. 1.0.8.6. QUIC 是如何迁移连接的?
  • 1.0.9. HTTP和HTTPS有什么区别?
    1. 1.0.9.1. 简述半连接队列和全连接队列
      1. 1.0.9.1.1. 半连接队列
      2. 1.0.9.1.2. 全连接队列
    2. 1.0.9.2. 简述SYN攻击
      1. 1.0.9.2.1. Https的连接过程?
      2. 1.0.9.2.2. 输入 www.baidu.com,怎么变成 https://www.baidu.com 的,怎么确定用HTTP还是HTTPS?
      3. 1.0.9.2.3. 什么是对称加密、非对称加密?区别是什么?
      4. 1.0.9.2.4. 数字签名、报文摘要的原理
  • 1.0.10. GET与POST的区别?
  • 1.0.11. Session与Cookie的区别?
    1. 1.0.11.1. 什么是Cookie?
    2. 1.0.11.2. 什么是Session?
    3. 1.0.11.3. Cookie与Session的区别
    4. 1.0.11.4. 禁用Cookie会怎样?
  • 1.0.12. 从输入网址到获得页面的过程 (越详细越好)?
  • 1.0.13. 什么是DNS?
    1. 1.0.13.1. 转发和重定向的区别
  • 1.0.14. 简述DNS协议
  • 1.0.15. 简述DNS劫持
  • 1.0.16. 简述dos攻击
  • 1.0.17. HTTP请求有哪些常见状态码?
  • 1.0.18. 什么是RIP (Routing Information Protocol, 距离矢量路由协议)? 算法是什么?
  • 1.0.19. 计算机网络体系结构
    1. 1.0.19.1. 物理层有什么作用
    2. 1.0.19.2. 数据链路层有什么作用
    3. 1.0.19.3. 网络层有什么作用
    4. 1.0.19.4. 传输层有什么作用
    5. 1.0.19.5. 会话层有什么作用
    6. 1.0.19.6. 表示层有什么作用
    7. 1.0.19.7. 应用层有什么作用
  • 1.0.20. IP地址的分类?
    1. 1.0.20.0.1. 私有地址
  • 1.0.21. 什么叫划分子网?
  • 1.0.22. 什么是ARP协议 (Address Resolution Protocol)?
  • 1.0.23. 什么是NAT (Network Address Translation, 网络地址转换)?
  • 计算机网络知识点

    计网面试

    什么是三次握手 (three-way handshake)?

    三次握手

    • 第一次握手:Client将SYN置1,随机产生一个初始序列号seq发送给Server,进入SYN_SENT状态;
    • 第二次握手:Server收到Client的SYN=1之后,知道客户端请求建立连接,将自己的SYN置1,ACK置1,产生一个acknowledge number=sequence number+1,并随机产生一个自己的初始序列号,发送给客户端;进入SYN_RCVD状态;
    • 第三次握手:客户端检查acknowledge number是否为序列号+1,ACK是否为1,检查正确之后将自己的ACK置为1,产生一个acknowledge number=服务器发的序列号+1,发送给服务器;进入ESTABLISHED状态;服务器检查ACK为1和acknowledge number为序列号+1之后,也进入ESTABLISHED状态;完成三次握手,连接建立。

    TCP建立连接可以两次握手吗?为什么?

    展开

    不可以。有两个原因:

    首先,可能会出现已失效的连接请求报文段又传到了服务器端

    client 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 server。本来这是一个早已失效的报文段。但 server 收到此失效的连接请求报文段后,就误认为是 client 再次发出的一个新的连接请求。于是就向 client 发出确认报文段,同意建立连接。假设不采用 “三次握手”,那么只要 server 发出确认,新的连接就建立了。由于现在 client 并没有发出建立连接的请求,因此不会理睬 server 的确认,也不会向 server 发送数据。但 server 却以为新的运输连接已经建立,并一直等待 client 发来数据。这样,server 的很多资源就白白浪费掉了。采用 “三次握手” 的办法可以防止上述现象发生。例如刚才那种情况,client 不会向 server 的确认发出确认。server 由于收不到确认,就知道 client 并没有要求建立连接。

    其次,两次握手无法保证Client正确接收第二次握手的报文(Server无法确认Client是否收到),也无法保证Client和Server之间成功互换初始序列号。

    可以采用四次握手吗?为什么?

    展开

    可以。但是会降低传输的效率。

    四次握手是指:第二次握手:Server只发送ACK和acknowledge number;而Server的SYN和初始序列号在第三次握手时发送;原来协议中的第三次握手变为第四次握手。出于优化目的,四次握手中的二、三可以合并。

    第三次握手中,如果客户端的ACK未送达服务器,会怎样?

    展开

    Server端:
    由于Server没有收到ACK确认,因此会重发之前的SYN+ACK(默认重发五次,之后自动关闭连接进入CLOSED状态),Client收到后会重新传ACK给Server。

    Client端,两种情况:

    1. 在Server进行超时重发的过程中,如果Client向服务器发送数据,数据头部的ACK是为1的,所以服务器收到数据之后会读取 ACK number,进入 establish 状态
    2. 在Server进入CLOSED状态之后,如果Client向服务器发送数据,服务器会以RST包(连接异常终止包)应答。

    如果已经建立了连接,但客户端出现了故障怎么办?

    展开

    服务器每收到一次客户端的请求后都会重新复位一个计时器,时间通常是设置为2小时,若两小时还没有收到客户端的任何数据,服务器就会发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文仍然没反应,服务器就认为客户端出了故障,接着就关闭连接。

    初始序列号是什么?

    展开

    TCP连接的一方A,随机选择一个32位的序列号(Sequence Number)作为发送数据的初始序列号(Initial Sequence Number,ISN),比如为1000,以该序列号为原点,对要传送的数据进行编号:1001、1002...三次握手时,把这个初始序列号传送给另一方B,以便在传输数据时,B可以确认什么样的数据编号是合法的;同时在进行数据传输时,A还可以确认B收到的每一个字节,如果A收到了B的确认编号(acknowledge number)是2001,就说明编号为1001-2000的数据已经被B成功接受。

    为什么初始序列号要是随机的?

    • 减少将那些仍在网络中存在的来自两台主机之间先前已终止的链接的报文段,误认为是后来这两台主机之间新建连接所产生的有效报文段的可能性。(它碰巧与旧连接使用了相同的序列号)
    • 如果初始序列号都是有规律的,容易被伪造收报方攻击。例如客户端每次都以0为初始序列号,那另一个伪造的收报方只要不停的发1就可以。

    注意

    初始化序列号时是采用随机的方式来提升攻击者猜测序列号的难度,以增加安全性。

    但是这种方式只能避免攻击者预测出合法的 RST 报文,而无法避免攻击者截获客户端的报文,然后中途伪造出合法 RST 报文的攻击的方式。

    图片

    什么是四次挥手?

    四次挥手

    • 第一次挥手:Client将FIN置为1,发送一个序列号seq给Server;进入FIN_WAIT_1状态;
    • 第二次挥手:Server收到FIN之后,发送一个ACK=1,acknowledge number=收到的序列号+1;进入CLOSE_WAIT状态。此时客户端已经没有要发送的数据了,但仍可以接受服务器发来的数据。
    • 第三次挥手:Server将FIN置1,发送一个序列号给Client;进入LAST_ACK状态;
    • 第四次挥手:Client收到服务器的FIN后,进入TIME_WAIT状态;接着将ACK置1,发送一个acknowledge number=序列号+1给服务器;服务器收到后,确认acknowledge number后,变为CLOSED状态,不再向客户端发送数据。客户端等待2*MSL(报文段最长寿命)时间后,也进入CLOSED状态。完成四次挥手。
    为什么不能把服务器发送的ACK和FIN合并起来,变成三次挥手(CLOSE_WAIT状态意义是什么)?
    展开

    因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复ACK,表示接收到了断开连接的请求。等到数据发完之后再发FIN,断开服务器到客户端的数据传送。

    如果第二次挥手时服务器的ACK没有送达客户端,会怎样?
    展开

    客户端没有收到ACK确认,会重新发送FIN请求。

    客户端TIME_WAIT状态的意义是什么?
    展开

    第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT状态就是用来重发可能丢失的ACK报文。如果Server没有收到ACK,就会重发FIN,如果Client在2*MSL的时间内收到了FIN,就会重新发送ACK并再次等待2MSL,防止Server没有收到ACK而不断重发FIN。

    MSL(Maximum Segment Lifetime),指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

    TCP如何实现流量控制?

    滑动窗口

    使用滑动窗口协议实现流量控制。防止发送方发送速率太快,接收方缓存区不够导致溢出。接收方会维护一个接收窗口 receiver window(窗口大小单位是字节),接受窗口的大小是根据自己的资源情况动态调整的,在返回ACK时将接受窗口大小放在TCP报文中的窗口字段告知发送方。发送窗口的大小不能超过接受窗口的大小,只有当发送方发送并收到确认之后,才能将发送窗口右移。

    发送窗口的上限为接受窗口和拥塞窗口中的较小值。==接受窗口表明了接收方的接收能力,拥塞窗口表明了网络的传送能力==。

    滑动窗口

    什么是零窗口(接收窗口为0时会怎样)?
    展开

    如果接收方没有能力接收数据,就会将接收窗口设置为0,这时发送方必须暂停发送数据,但是会启动一个持续计时器(persistencetimer),到期后发送一个大小为1字节的探测数据包,以查看接收窗口状态。如果接收方能够接收数据,就会在返回的报文中更新接收窗口大小,恢复数据传送。

    TCP的拥塞控制是怎么实现的?

    拥塞控制

    拥塞控制主要由四个算法组成:慢启动(Slow Start)、拥塞避免(Congestion voidance)、快重传 (Fast Retransmit)、快恢复(Fast Recovery)

    1. 慢启动:刚开始发送数据时,先把拥塞窗口(congestion window)设置为一个最大报文段MSS的数值,每收到一个新的确认报文之后,就把拥塞窗口加1个MSS。这样每经过一个传输轮次(或者说是每经过一个往返时间RTT),拥塞窗口的大小就会加倍

    slow start

    2.拥塞避免:当拥塞窗口的大小达到慢开始门限(slow start threshold)时,开始执行拥塞避免算法,拥塞窗口大小不再指数增加,而是线性增加,即每经过一个传输轮次只增加1MSS.

    无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(其根据就是没有收到确认),就要把慢开始门限ssthresh设置为出现拥塞时的发送方窗口值的一半(但不能小于2)。然后把拥塞窗口cwnd重新设置为1,执行慢开始算法。(这是不使用快重传的情况)

    3.快重传:快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。

    快重传

    4.快恢复:当发送方连续收到三个重复确认时,就把慢开始门限减半,然后执行拥塞避免算法。不执行慢开始算法的原因:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方认为现在网络可能没有出现拥塞。
    也有的快恢复是把开始时的拥塞窗口cwnd值再增大一点,即等于 ssthresh + 3*MSS 。这样做的理由是:既然发送方收到三个重复的确认,就表明有三个分组已经离开了网络。这三个分组不再消耗网络的资源而是停留在接收方的缓存中。可见现在网络中减少了三个分组。因此可以适当把拥塞窗口扩大些。

    TCP与UDP的区别

    1. TCP是面向连接的,UDP是无连接的;
    什么叫无连接?

    UDP发送数据之前不需要建立连接

    1. TCP是可靠的,UDP不可靠;
    什么叫不可靠?

    UDP接收方收到报文后,不需要给出任何确认

    1. TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多;
    2. TCP是面向字节流的,UDP是面向报文的;
    什么意思?

    面向字节流是指发送数据时以字节为单位,一个数据包可以拆分成若干组进行发送,而UDP一个报文只能一次发完。

    1. TCP有拥塞控制机制,UDP没有。网络出现的拥塞不会使源主机的发送速率降低,这对某些实时应用是很重要的,比如媒体通信,游戏;
    2. TCP首部开销(20字节)比UDP首部开销(8字节)要大
    3. UDP 的主机不需要维持复杂的连接状态表

    什么时候选择TCP,什么时候选UDP?

    展开 对某些实时性要求比较高的情况,选择UDP,比如游戏,媒体通信,实时视频流(直播),即使出现传输错误也可以容忍;其它大部分情况下,HTTP都是用TCP,因为要求传输的内容可靠,不出现丢失
    ### TCP 和 UDP 可以使用同一个端口吗?

    可以

    TCP 和 UDP 传输协议,在内核中是由两个完全独立的软件模块实现的。

    当主机收到数据包后,可以在 IP 包头的「协议号」字段知道该数据包是 TCP/UDP,所以可以根据这个信息确定送给哪个模块(TCP/UDP)处理,送给 TCP/UDP 模块的报文根据「端口号」确定送给哪个应用程序处理。

    因此, TCP/UDP 各自的端口号也相互独立,互不影响。

    image-20240327111424516

    HTTP可以使用UDP吗?
    展开 HTTP不可以使用UDP,HTTP需要基于可靠的传输协议,而UDP不可靠

    面向连接和无连接的区别

    无连接的网络服务(数据报服务)– 面向连接的网络服务(虚电路服务)

    虚电路服务:首先建立连接,所有的数据包经过相同的路径,服务质量有较好的保证;

    数据报服务:每个数据包含目的地址,数据路由相互独立(路径可能变化);网络尽最大努力交付数据,但不保证不丢失、不保证先后顺序、不保证在时限内交付;网络发生拥塞时,可能会将一些分组丢弃;

    TCP如何保证传输的可靠性

    1. 数据包校验
    2. 对失序数据包重新排序(TCP报文具有序列号)
    3. 丢弃重复数据
    4. 应答机制:接收方收到数据之后,会发送一个确认(通常延迟几分之一秒);
    5. 超时重发:发送方发出数据之后,启动一个定时器,超时未收到接收方的确认,则重新发送这个数据;
    6. 流量控制:确保接收端能够接收发送方的数据而不会缓冲区溢出

    简述TCP粘包现象

    TCP是面向流协议,发送的单位是字节流,因此会有将多个小尺寸数据被封装在一个tcp报文中发出去的可能性。 可以简单的理解成客户端调用了两次send,服务器端一个recv就把信息都读出来了。

    TCP粘包现象处理方法

    固定发送信息长度,或在两个信息之间加入分隔符。

    TCP的缺陷

    升级 TCP 的工作很困难

    TCP 协议是在内核中实现的,应用程序只能使用不能修改,如果要想升级 TCP 协议,那么只能升级内核。

    由于内核升级涉及到底层软件和运行库的更新,服务程序就需要回归测试是否兼容新的内核版本,所以服务器的内核升级比较保守和缓慢。

    • 回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其他代码产生错误。

    TCP 建立连接的延迟

    现在大多数网站都是使用 HTTPS 的,这意味着在 TCP 三次握手之后,还需要经过 TLS 四次握手后,才能进行 HTTP 数据的传输,这在一定程序上增加了数据传输的延迟。

    TCP 三次握手和 TLS 握手延迟,如图:

    图片

    TCP 三次握手的延迟被 TCP Fast Open (快速打开)这个特性解决了,这个特性可以在「第二次建立连接」时减少 TCP 连接建立的时延。

    图片

    过程如下:

    • 在第一次建立连接的时候,服务端在第二次握手产生一个 Cookie (已加密)并通过 SYN、ACK 包一起发给客户端,于是客户端就会缓存这个 Cookie,所以第一次发起 HTTP Get 请求的时候,还是需要 2 个 RTT 的时延;
    • 在下次请求的时候,客户端在 SYN 包带上 Cookie 发给服务端,就提前可以跳过三次握手的过程,因为 Cookie 中维护了一些信息,服务端可以从 Cookie 获取 TCP 相关的信息,这时发起的 HTTP GET 请求就只需要 1 个 RTT 的时延;

    TCP 存在队头阻塞问题

    TCP 是字节流协议,TCP 层必须保证收到的字节数据是完整且有序的,如果序列号较低的 TCP 段在网络传输中丢失了,即使序列号较高的 TCP 段已经被接收了,应用层也无法从内核中读取到这部分数据。

    图片

    图中发送方发送了很多个 packet,每个 packet 都有自己的序号,你可以认为是 TCP 的序列号,其中 packet #3 在网络中丢失了,即使 packet #4-6 被接收方收到后,由于内核中的 TCP 数据不是连续的,于是接收方的应用层就无法从内核中读取到,只有等到 packet #3 重传后,接收方的应用层才可以从内核中读取到数据。

    网络迁移需要重新建立 TCP 连接

    基于 TCP 传输协议的 HTTP 协议,由于是通过四元组(源 IP、源端口、目的 IP、目的端口)确定一条 TCP 连接。

    当移动设备的网络从 4G 切换到 WIFI 时,意味着 IP 地址变化了,那么就必须要断开连接,然后重新建立 TCP 连接

    而建立连接的过程包含 TCP 三次握手和 TLS 四次握手的时延,以及 TCP 慢启动的减速过程,给用户的感觉就是网络突然卡顿了一下,因此连接的迁移成本是很高的。

    怎么用UDP来实现TCP?

    小林图解

    • UDP是传输层的协议,要在应用层全部实现一遍

    现在市面上已经有基于 UDP 协议实现的可靠传输协议的成熟方案了,那就是 QUIC 协议,已经应用在了 HTTP/3。

    图片

    实现可靠传输—头部设计

    图片

    Packet Header 首次建立连接时和日常传输数据时使用的 Header 是不同的。如下图,注意我没有把 Header 所有字段都画出来,只是画出了重要的字段:

    图片Packet Header

    细分这两种:

    • Long Packet Header 用于首次建立连接。
    • Short Packet Header 用于日常传输数据。

    QUIC 也是需要三次握手来建立连接的,主要目的是为了确定连接 ID。

    建立连接时,连接 ID 是由服务器根据客户端的 Source Connection ID 字段生成的,这样后续传输时,双方只需要固定住 Destination Connection ID(连接 ID ),从而实现连接迁移功能。所以,你可以看到日常传输数据的 Short Packet Header 不需要在传输 Source Connection ID 字段了。

    Short Packet Header 中的 Packet Number 是每个报文独一无二的编号,它是严格递增的,也就是说就算 Packet N 丢失了,重传的 Packet N 的 Packet Number 已经不是 N,而是一个比 N 大的值。

    图片

    为什么要这么设计呢?

    我们先来看看 TCP 的问题,TCP 在重传报文时的序列号和原始报文的序列号是一样的,也正是由于这个特性,引入了 TCP 重传的歧义问题。

    图片TCP 重传的歧义问题

    比如上图,当 TCP 发生超时重传后,客户端发起重传,然后接收到了服务端确认 ACK 。由于客户端原始报文和重传报文序列号都是一样的,那么服务端针对这两个报文回复的都是相同的 ACK。

    这样的话,客户端就无法判断出是原始报文的响应还是重传报文的响应,这样在计算 RTT(往返时间) 时应该选择从发送原始报文开始计算,还是重传原始报文开始计算呢?

    • 如果算成原始报文的响应,但实际上是重传报文的响应(上图右),会导致采样 RTT 变大;
    • 如果算成重传报文的响应,但实际上是原始报文的响应(上图左),又很容易导致采样 RTT 过小;

    RTT 计算不精确的话,那么 RTO (超时时间)也就不精确,因为 RTO 是基于 RTT 来计算的,RTO 计算不准确可能导致重传的概率事件增大。

    QUIC 报文中的 Pakcet Number 是严格递增的, 即使是重传报文,它的 Pakcet Number 也是递增的,这样就能更加精确计算出报文的 RTT。

    图片

    如果 ACK 的 Packet Number 是 N+M,就根据重传报文计算采样 RTT。如果 ACK 的 Pakcet Number 是 N,就根据原始报文的时间计算采样 RTT,没有歧义性的问题。

    另外,还有一个好处,QUIC 使用的 Packet Number 单调递增的设计,可以让数据包不再像TCP 那样必须有序确认,QUIC 支持乱序确认,当数据包Packet N 丢失后,只要有新的已接收数据包确认,当前窗口就会继续向右滑动

    待发送端超过一定时间没收到 Packet N 的确认报文后,会将需要重传的数据包放到待发送队列,重新编号比如数据包 Packet N+M 后重新发送给接收端,对重传数据包的处理跟发送新的数据包类似,这样就不会因为丢包重传将当前窗口阻塞在原地,从而解决了队头阻塞问题。

    所以,Packet Number 单调递增的两个好处:

    • 可以更加精确计算 RTT,没有 TCP 重传的歧义性问题;
    • 可以支持乱序确认,防止因为丢包重传将当前窗口阻塞在原地,而 TCP 必须是顺序确认的,丢包时会导致窗口不滑动;

    QUIC 是如何解决 TCP 队头阻塞问题的?

    HTTP/2 的队头阻塞

    HTTP/2 通过抽象出 Stream 的概念,实现了 HTTP 并发传输,一个 Stream 就代表 HTTP/1.1 里的请求和响应。

    图片HTTP/2

    在 HTTP/2 连接上,不同 Stream 的帧是可以乱序发送的(因此可以并发不同的 Stream ),因为每个帧的头部会携带 Stream ID 信息,所以接收端可以通过 Stream ID 有序组装成 HTTP 消息,而同一 Stream 内部的帧必须是严格有序的。

    但是 HTTP/2 多个 Stream 请求都是在一条 TCP 连接上传输,这意味着多个 Stream 共用同一个 TCP 滑动窗口,那么当发生数据丢失,滑动窗口是无法往前移动的,此时就会阻塞住所有的 HTTP 请求,这属于 TCP 层队头阻塞

    图片

    没有队头阻塞的 QUIC

    QUIC 也借鉴 HTTP/2 里的 Stream 的概念,在一条 QUIC 连接上可以并发发送多个 HTTP 请求 (Stream)。

    但是 QUIC 给每一个 Stream 都分配了一个独立的滑动窗口,这样使得一个连接上的多个 Stream 之间没有依赖关系,都是相互独立的,各自控制的滑动窗口

    假如 Stream2 丢了一个 UDP 包,也只会影响 Stream2 的处理,不会影响其他 Stream,与 HTTP/2 不同,HTTP/2 只要某个流中的数据包丢失了,其他流也会因此受影响。

    图片

    QUIC 是如何做流量控制的?

    QUIC 对拥塞控制改进

    QUIC 更快的连接建立

    QUIC 是如何迁移连接的?

    QUIC 协议没有用四元组的方式来“绑定”连接,而是通过连接 ID来标记通信的两个端点,客户端和服务器可以各自选择一组 ID 来标记自己,因此即使移动设备的网络变化后,导致 IP 地址变化了,只要仍保有上下文信息(比如连接 ID、TLS 密钥等),就可以“无缝”地复用原连接,消除重连的成本,没有丝毫卡顿感,达到了连接迁移的功能。

    HTTP和HTTPS有什么区别?

    1. 端口不同:HTTP使用的是80端口,HTTPS使用443端口;
    2. HTTP(超文本传输协议)信息是明文传输,HTTPS运行在SSL(Secure Socket Layer)之上,添加了加密和认证机制,更加安全;
    3. HTTPS由于加密解密会带来更大的CPU和内存开销;
    4. HTTPS通信需要证书,一般需要向证书颁发机构(CA)购买

    简述半连接队列和全连接队列

    半连接队列

    当客户端发起 SYN 到服务端,服务端收到以后会回 ACK 和自己的 SYN。这时服务端这边的 TCP 从 listen 状态变为 SYN_RCVD (SYN Received),此时会将这个连接信息放入「半连接队列」,半连接队列也被称为 SYN Queue,存储的是 “inbound SYN packets”。

    旦收到客户端的 ACK,服务端就开始尝试把它加入另外一个全连接队列(Accept Queue)。

    全连接队列

    「全连接队列」包含了服务端所有完成了三次握手,但是还未被应用调用 accept 取走的连接队列。

    此时的 socket 处于 ESTABLISHED 状态。每次应用调用 accept() 函数会移除队列头的连接。如果队列为空,accept() 通常会阻塞。全连接队列也被称为 Accept 队列。

    简述SYN攻击

    SYN攻击即利用TCP协议缺陷,通过发送大量的半连接请求,占用半连接队列,耗费CPU和内存资源。

    优化方式:

    1. 缩短SYN Timeout时间
    2. 记录IP,若连续受到某个IP的重复SYN报文,从这个IP地址来的包会被一概丢弃。
    Https的连接过程?
    展开
    1. 客户端向服务器发送请求,同时发送客户端支持的一套加密规则(包括对称加密、非对称加密、摘要算法);
    2. 服务器从中选出一组加密算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥(用于非对称加密),以及证书的颁发机构等信息(证书中的私钥只能用于服务器端进行解密);
    3. 客户端验证服务器的合法性,包括:证书是否过期,CA 是否可靠,发行者证书的公钥能否正确解开服务器证书的“发行者的数字签名”,服务器证书上的域名是否和服务器的实际域名相匹配;
    4. 如果证书受信任,或者用户接收了不受信任的证书,浏览器会生成一个随机密钥(用于对称算法),并用服务器提供的公钥加密(采用非对称算法对密钥加密);使用Hash算法对握手消息进行计算,并对摘要使用之前产生的密钥加密(对称算法);将加密后的随机密钥和摘要一起发送给服务器;
    5. 服务器使用自己的私钥解密,得到对称加密的密钥,用这个密钥解密出Hash摘要值,并验证握手消息是否一致;如果一致,服务器使用对称加密的密钥加密握手消息发给浏览器;
    6. 浏览器解密并验证摘要,若一致,则握手结束。之后的数据传送都使用对称加密的密钥进行加密

    总结:非对称加密算法用于在握手过程中加密生成的密码;对称加密算法用于对真正传输的数据进行加密;HASH算法用于验证数据的完整性。

    image-20240327103416107
    输入 www.baidu.com,怎么变成 https://www.baidu.com 的,怎么确定用HTTP还是HTTPS?

    一种是原始的302跳转,服务器把所有的HTTp流量跳转到HTTPS。(要重定向)但这样有一个漏洞,就是中间人可能在第一次访问站点的时候就劫持。 解决方法是引入HSTS机制,用户浏览器在访问站点的时候强制使用HTTPS。(不重定向,直接冲)

    什么是对称加密、非对称加密?区别是什么?
    展开
    • 对称加密:加密和解密采用相同的密钥。如:DES、RC2、RC4
    • 非对称加密:需要两个密钥:公钥和私钥。如果用公钥加密,需要用私钥才能解密。如:RSA
    • 区别:对称加密速度更快,通常用于大量数据的加密;非对称加密安全性更高(不需要传送私钥)
    数字签名、报文摘要的原理
    展开
    • 发送者A用私钥进行签名,接收者B用公钥验证签名。因为除A外没有人有私钥,所以B相信签名是来自A。A不可抵赖,B也不能伪造报文。
    • 摘要算法:MD5、SHA

    GET与POST的区别?

    1. GET是幂等的,即读取同一个资源(只是查询数据不会影响到资源的变化),总是得到相同的数据,POST不是幂等的;(每次调用可能会改变服务器上的资源)
    2. 请求形式上:GET请求的数据附在URL之后,在HTTP请求头中;POST请求的数据在请求体中;
    3. 安全性:GET请求可被缓存、收藏、保留到历史记录,且其请求数据明文出现在URL中。POST的参数不会被保存,安全性相对较高;
    4. GET只允许ASCII字符,POST对数据类型没有要求,也允许二进制数据;
    5. GET的长度有限制(一般HTTP协议里并不限制参数大小限制。但一般由于get请求是直接附加到地址栏里面的,由于浏览器地址栏有长度限制,因此使GET请求在浏览器实现层面上看会有长度限制。),而POST数据大小无限制
    6. Get:指定资源请求数据,刷新无害,Get请求的数据会附加到URL中,传输数据的大小受到url的限制。Post:向指定资源提交要被处理的数据。刷新会使数据会被重复提交。post在发送数据前会先将请求头发送给服务器进行确认,然后才真正发送数据。

    Session与Cookie的区别?

    什么是Cookie?

    我们知道HTTP协议是无状态的,一次请求完成,不会持久化请求与相应的信息。那么,在购物车、用户登录状态、页面个性化设置等场景下,就无法识别特定用户的信息。这时Cookie就出现了。

    Cookie是客户端保存用户信息的一种机制,将服务器发送到浏览器的数据保存在本地,下次向同一服务器再发起请求时被携带发送。对于Cookie,可以设置过期时间。

    通常,Cookie用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。这样就解决了HTTP无状态的问题。

    Cookie主要用于以下方面:

    • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
    • 个性化设置(如用户自定义设置、主题等)
    • 浏览器行为跟踪(如跟踪分析用户行为等)

    Cookie存储在客户端,这就意味着,可以通过一些方式进行修改,欺骗服务器。针对这个问题,怎么解决呢?那就引入了Session。

    什么是Session?

    Session代表服务器和客户端一次会话的过程。

    对照Cookie,Session是一种在服务器端保存数据的机制,用来跟踪用户状态的数据结构,可以保存在文件、数据库或者集群中。

    当在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而会在整个用户会话中一直存在下去。当客户端关闭会话,或者Session超时失效时会话结束。

    目前大多数的应用都是用Cookie实现Session跟踪的。第一次创建Session时,服务端会通过在HTTP协议中返回给客户端,在Cookie中记录SessionID,后续请求时传递SessionID给服务,以便后续每次请求时都可分辨你是谁。

    Cookie与Session的区别

    如果说Cookie机制是通过检查客户身上的“通行证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建立的一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

    1、cookie数据存放在客户的浏览器上,session数据放在服务器上.

    Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionID,用该SessionID 为标识符来存取服务器端的Session存储空间。而SessionID这一数据则是保存到客户端,用Cookie保存的,用户提交页面时,会将这一 SessionID提交到服务器端,来存取Session数据。这一过程,是不用开发人员干预的。所以一旦客户端禁用Cookie,那么Session也会失效。

    2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。

    3、设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。

    4、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。

    5、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型)

    注意:

    session很容易失效,用户体验很差;

    虽然cookie不安全,但是可以加密 ;

    cookie也分为永久和暂时存在的;

    浏览器 有禁止cookie功能 ,但一般用户都不会设置;

    一定要设置失效时间,要不然浏览器关闭就消失了;

    例如:

    ​ 记住密码功能就是使用永久cookie写在客户端电脑,下次登录时,自动将cookie信息附加发送给服务端。

    ​ application是全局性信息,是所有用户共享的信息,如可以记录有多少用户现在登录过本网站,并把该信息展示个所有用户。

    两者最大的区别在于生存周期,一个是IE启动到IE关闭.(浏览器页面一关 ,session就消失了),一个是预先设置的生存周期,或永久的保存于本地的文件。(cookie)

    Session信息是存放在server端,但session id是存放在client cookie的,当然php的session存放方法是多样化的,这样就算禁用cookie一样可以跟踪

    Cookie是完全保持在客户端的如:IE firefox 当客户端禁止cookie时将不能再使用

    禁用Cookie会怎样?

    如果客户在浏览器禁用了Cookie,该怎么办呢?

    方案一:拼接SessionId参数。在GET或POST请求中拼接SessionID,GET请求通常通过URL后面拼接参数来实现,POST请求可以放在Body中。无论哪种形式都需要与服务器获取保持一致。

    这种方案比较常见,比如老外的网站,经常会提示是否开启Cookie。如果未点同意或授权,会发现浏览器的URL路径中往往有”?sessionId=123abc”这样的参数。

    方案二:基于Token(令牌)。在APP应用中经常会用到Token来与服务器进行交互。Token本质上就是一个唯一的字符串,登录成功后由服务器返回,标识客户的临时授权,客户端对其进行存储,在后续请求时,通常会将其放在HTTP的Header中传递给服务器,用于服务器验证请求用户的身份。

    从输入网址到获得页面的过程 (越详细越好)?

    • 请求一旦发起,浏览器首先要做的事情就是解析这个域名,一般来说,浏览器会首先查看本地硬盘的 hosts 文件,看看其中有没有和这个域名对应的规则,如果有的话就直接使用 hosts 文件里面的 ip 地址。

      • 如果在本地的 hosts 文件没有能够找到对应的 ip 地址,浏览器会发出一个 DNS请求到本地DNS服务器 。本地DNS服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。
      • 查询你输入的网址的DNS请求到达本地DNS服务器之后,本地DNS服务器会首先查询它的缓存记录,如果缓存中有此条记录,就可以直接返回结果,此过程是递归的方式进行查询。如果没有,本地DNS服务器还要向DNS根服务器进行查询。
      • 根DNS服务器没有记录具体的域名和IP地址的对应关系,而是告诉本地DNS服务器,你可以到域服务器上去继续查询,并给出域服务器的地址。这种过程是迭代的过程。
      • 本地DNS服务器继续向域服务器发出请求,在这个例子中,请求的对象是.com域服务器。.com域服务器收到请求之后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。
      • 最后,本地DNS服务器向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不仅要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,可以直接返回结果,加快网络访问。
    • 浏览器获得域名对应的IP地址以后,浏览器向服务器请求建立链接,发起三次握手;

    • TCP/IP链接建立起来后,浏览器向服务器发送HTTP请求;

    • 服务器接收到这个请求,并根据路径参数映射到特定的请求处理器进行处理,并将处理结果及相应的视图返回给浏览器;

    • 浏览器解析并渲染视图,若遇到对js文件、css文件及图片等静态资源的引用,则重复上述步骤并向服务器请求这些资源;

    • 浏览器根据其请求到的资源、数据渲染页面,最终向用户呈现一个完整的页面。

    什么是DNS?

    DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。   通俗的讲,我们更习惯于记住一个网站的名字,比如www.baidu.com,而不是记住它的ip地址,比如:167.23.10.2。而计算机更擅长记住网站的ip地址,而不是像[http://www.baidu.com](https://link.zhihu.com/?target=http%3A//www.baidu.com)等链接。因为,DNS就相当于一个电话本,比如你要找[http://www.baidu.com](https://link.zhihu.com/?target=http%3A//www.baidu.com)这个域名,那我翻一翻我的电话本,我就知道,哦,它的电话(ip)是167.23.10.2。

    转发和重定向的区别

    转发是服务器行为。服务器直接向目标地址访问URL,将相应内容读取之后发给浏览器,用户浏览器地址栏URL不变,转发页面和转发到的页面可以共享request里面的数据。

    重定向是利用服务器返回的状态码来实现的,如果服务器返回301或者302,浏览器收到新的消息后自动跳转到新的网址重新请求资源。用户的地址栏url会发生改变,而且不能共享数据。

    简述DNS协议

    DNS协议是基于UDP的应用层协议,它的功能是根据用户输入的域名,解析出该域名对应的IP地址,从而给客户端进行访问。

    简述DNS劫持

    DNS是指将网页域名翻译为对应的IP的一种方法。DNS劫持指攻击者篡改结果,使用户对域名的解析IP变成了另一个IP。

    简述dos攻击

    DoS是Denial of Service的简称,也称为拒绝服务攻击,通过发送大量的无用请求数据包给服务器,耗尽服务器资源,从而无法通过正常的访问服务器资源,导致服务器崩溃。

    HTTP请求有哪些常见状态码?

    1. 2xx状态码:操作成功。200 OK
    2. 3xx状态码:重定向。301 永久重定向;302暂时重定向
    3. 4xx状态码:客户端错误。400 Bad Request;401 Unauthorized;403 Forbidden;404 Not Found;
    4. 5xx状态码:服务端错误。500服务器内部错误;501服务不可用

    什么是RIP (Routing Information Protocol, 距离矢量路由协议)? 算法是什么?

    每个路由器维护一张表,记录该路由器到其它网络的”跳数“,路由器到与其直接连接的网络的跳数是1,每多经过一个路由器跳数就加1;更新该表时和相邻路由器交换路由信息;路由器允许一个路径最多包含15个路由器,如果跳数为16,则不可达。交付数据报时优先选取距离最短的路径。

    • Bellman-ford

    • 好消息传得快,坏消息传得慢。

      • 当网络出现故障时,要经过较长的时间才能将此信息传送到所有的路由器,“慢收敛”。

    image-20240327141053186

    当出现坏消息时,比如网1出现了故障:

    image-20240327141117025

    • 这个时候R1是知道是无法到达的,则其到网1的距离为16,并且为直接交付。
    • 但是R2在收到R1报文之前,即在R2并不知道R1出故障时,发送了原来的报文,网1 2 R1。
    • 于是,R1收到R2跟新报文后,误以为可以经过R2到网1,于是更新自己的路由表,网1 3 R2,并且将次更新信息发送给R2.
    • 然后R2以后又跟新自己的路由表为网1 4 R1, 30s后,又把这个信息发送给R1.
    • 一直到知道了距离等于16为止,这个时候才知道,噢噢噢噢原来,如此原来,是不可以达到呀。

    计算机网络体系结构

    OSI七层协议包括:物理层,数据链路层,网络层,运输层,会话层,表示层, 应用层

    image-20220210172724812

    • 应用层:常见协议:
      • FTP(21端口):文件传输协议
      • SSH(22端口):远程登陆
      • TELNET(23端口):远程登录
      • SMTP(25端口):发送邮件
      • POP3(110端口):接收邮件
      • HTTP(80端口):超文本传输协议
      • DNS(53端口):运行在UDP上,域名解析服务
    • 传输层:TCP/UDP
    • 网络层:IP、ARP、NAT、RIP…
    路由器、交换机位于哪一层?
    • 路由器网络层,根据IP地址进行寻址;
    • 交换机数据链路层,根据MAC地址进行寻址

    物理层有什么作用

    主要解决两台物理机之间的通信,通过二进制比特流的传输来实现,二进制数据表现为电流电压上的强弱,到达目的地再转化为二进制机器码。网卡、集线器工作在这一层。

    数据链路层有什么作用

    在不可靠的物理介质上提供可靠的传输,接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层。这一层在物理层提供的比特流的基础上,通过差错控制、流量控制方法,使有差错的物理线路变为无差错的数据链路。提供物理地址寻址功能。交换机工作在这一层。

    网络层有什么作用

    将网络地址翻译成对应的物理地址,并决定如何将数据从发送方路由到接收方,通过路由选择算法为分组通过通信子网选择最佳路径。路由器工作在这一层。

    传输层有什么作用

    传输层提供了进程间的逻辑通信,传输层向高层用户屏蔽了下面网络层的核心细节,使应用程序看起来像是在两个传输层实体之间有一条端到端的逻辑通信信道。

    会话层有什么作用

    建立会话:身份验证,权限鉴定等; 保持会话:对该会话进行维护,在会话维持期间两者可以随时使用这条会话传输局; 断开会话:当应用程序或应用层规定的超时时间到期后,OSI会话层才会释放这条会话。

    表示层有什么作用

    数据格式进行编译,对收到或发出的数据根据应用层的特征进行处理,如处理为文字、图片、音频、视频、文档等,还可以对压缩文件进行解压缩、对加密文件进行解密等。

    应用层有什么作用

    提供应用层协议,如HTTP协议,FTP协议等等,方便应用程序之间进行通信。

    IP地址的分类?

    image-20210423105710272

    image-20210423111715385

    私有地址

    私有ip属于非注册地址,专门为组织机构内部使用。RFC1918定义了私有IP地址范围:

    A: 10.0.0.0~10.255.255.255 即10.0.0.0/8

    B:172.16.0.0~172.31.255.255即172.16.0.0/12

    C:192.168.0.0~192.168.255.255 即192.168.0.0/16

    什么叫划分子网?

    从主机号host-id借用若干个比特作为子网号subnet-id;子网掩码:网络号和子网号都为1,主机号为0;数据报仍然先按照网络号找到目的网络,发送到路由器,路由器再按照网络号和子网号找到目的子网:将子网掩码与目标地址逐比特与操作,若结果为某个子网的网络地址,则送到该子网。

    什么是ARP协议 (Address Resolution Protocol)?

    ARP协议完成了IP地址与物理地址的映射。每一个主机都设有一个 ARP 高速缓存,里面有所在的局域网上的各主机和路由器的 IP 地址到硬件地址的映射表。当源主机要发送数据包到目的主机时,会先检查自己的ARP高速缓存中有没有目的主机的MAC地址,如果有,就直接将数据包发到这个MAC地址,如果没有,就向所在的局域网发起一个ARP请求的广播包(在发送自己的 ARP 请求时,同时会带上自己的 IP 地址到硬件地址的映射),收到请求的主机检查自己的IP地址和目的主机的IP地址是否一致,如果一致,则先保存源主机的映射到自己的ARP缓存,然后给源主机发送一个ARP响应数据包。源主机收到响应数据包之后,先添加目的主机的IP地址与MAC地址的映射,再进行数据传送。如果源主机一直没有收到响应,表示ARP查询失败。

    如果所要找的主机和源主机不在同一个局域网上,那么就要通过 ARP 找到一个位于本局域网上的某个路由器的硬件地址,然后把分组发送给这个路由器,让这个路由器把分组转发给下一个网络。剩下的工作就由下一个网络来做

    什么是NAT (Network Address Translation, 网络地址转换)?

    用于解决内网中的主机要和因特网上的主机通信。由NAT路由器将主机的本地IP地址转换为全球IP地址,分为静态转换(转换得到的全球IP地址固定不变)和动态NAT转换。