📡 C++面试宝典:网络篇(第二十二期)

划重点! 这些网络问题面试必考,赶紧收藏备用~ [🤖干货预警]



🌐 1. OSI七层模型 vs TCP/IP四层模型
OSI模型协议举例TCP/IP模型协议举例
应用层(Application)HTTP、FTP应用层DNS、SMTP
表示层(Presentation)JPEG、SSL
会话层(Session)RPC、NetBIOS
传输层(Transport)TCP、UDP传输层TCP、UDP
网络层(Network)IP、ICMP网络层IP、ARP
数据链路层(Data Link)PPP、MAC链路层Ethernet、Wi-Fi
物理层(Physical)USB、光纤

💡 小贴士:TCP/IP更贴近实际应用,OSI是理论标杆!面试时建议两者对比回答~


🛡️ 2. TCP如何保证可靠性?
  • 确认应答(ACK):接收方收到数据后必须回复ACK报文。
  • 超时重传:发送方未收到ACK时自动重发数据包。
  • 滑动窗口:动态调整发送速率,避免接收方缓冲区溢出。
  • 流量控制:通过窗口大小字段 w i n win win限制发送速率。
  • 拥塞控制(见第10点):根据网络状态调整发送窗口。

[🤯 灵魂拷问]:丢包?延迟?不存在的!TCP用这5招搞定一切!


🤝 3. TCP连接管理

三次握手(建立连接)

  1. Client → SYN=1, seq=x
  2. Server → SYN=1, ACK=1, seq=y, ack=x+1
  3. Client → ACK=1, seq=x+1, ack=y+1

四次挥手(断开连接)

  1. A → FIN=1, seq=u
  2. B → ACK=1, seq=v, ack=u+1
  3. B → FIN=1, ACK=1, seq=w, ack=u+1
  4. A → ACK=1, seq=u+1, ack=w+1

🕒 为啥挥手多一次? 因为TCP支持半关闭状态(B需确认数据发送完毕再发FIN)!


📜 4. TCP报文格式
 0                   1                   2                   3  
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1  
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  
|         源端口号         |         目的端口号        |  
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  
|                       序列号(seq)                          |  
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  
|                     确认号(ack)                            |  
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  
| 数据偏移 | 保留 |URG|ACK|PSH|RST|SYN|FIN|      窗口大小       |  
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  
|           校验和          |        紧急指针(URG)          |  
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  
|                     选项(可选)                             |  
|                     数据(Payload)                          |  

🔢 5. 握手/挥手中的seq和ack含义
  • seq(序列号):标识当前报文段第一个字节的编号(防止乱序)。
  • ack(确认号):期望收到的下一个字节的序列号(确认此前所有数据)。
    公式:若发送方发数据 [ s e q = a , l e n = L ] [seq=a, len=L] [seq=a,len=L],则接收方回复 a c k = a + L ack = a + L ack=a+L

举个栗子:Client发送seq=100, len=20,Server回复ack=120(表示期待第120字节)。


6. 为什么是三次握手 & 四次挥手?
  • 三次握手
    • 防止历史连接干扰(旧SYN到达时,Server可通过第三次ACK判断有效性)。
    • 最少次数保证双方收发能力正常(Client←→Server双向验证)。
  • 四次挥手
    • TCP连接是全双工的,必须双方分别关闭(Client关发送 + Server关发送 = 两次FIN)。

[💥 真相]:不是不想省,是省不了啊!


📦 7. TCP粘包 & 拆包

原因

  • 粘包:发送方多次小数据合并发送(如Nagle算法优化)。
  • 拆包:数据大于MSS(最大报文段大小)被分割发送。

解决方案

  1. 定长协议:所有数据包固定长度(如512字节)。
  2. 分隔符:用特殊字符标记结束(如\n)。
  3. 头部声明长度:在数据前添加长度字段(推荐!)。
// C++示例:自定义协议头
struct PacketHeader {
    uint32_t length; // 数据长度
    uint32_t type;   // 数据类型
};

⚖️ 8. TCP vs UDP 区别
特性TCPUDP
连接性面向连接无连接
可靠性可靠传输(重传机制)尽最大努力交付
速度慢(需握手/确认)快(直接发数据包)
报文边界可能粘包/拆包保留报文边界
适用场景文件传输、网页浏览视频流、实时游戏

🚀 UDP逆袭:谁说UDP不能可靠?看第9点!


🔧 9. UDP如何实现可靠传输?

在应用层模拟TCP机制:

  1. 添加序列号:为每个包标记seq,接收方排序去重。
  2. ACK确认:接收方回复ack(可累积确认)。
  3. 超时重传:设定定时器检测丢包。
  4. 流量控制:动态调整发送窗口(如QUIC协议)。

🌟 经典方案:Google的QUIC协议(HTTP/3底层)就是基于UDP的可靠传输!


🚦 10. TCP拥塞控制

目标:避免网络过载,通过动态调整发送窗口 c w n d cwnd cwnd(拥塞窗口)。

核心算法

  1. 慢启动(Slow Start)
    • c w n d cwnd cwnd从1开始,每RTT(往返时间)翻倍: c w n d = 2 n cwnd = 2^n cwnd=2n
    • 何时减速:当 c w n d ≥ s s t h r e s h cwnd \geq ssthresh cwndssthresh(慢启动阈值)时,进入拥塞避免。
  2. 拥塞避免(AIMD)
    • 每RTT线性增加: c w n d = c w n d + 1 cwnd = cwnd + 1 cwnd=cwnd+1
    • 何时减速:检测到丢包(超时或3个重复ACK)时, s s t h r e s h = c w n d / 2 ssthresh = cwnd/2 ssthresh=cwnd/2,重置 c w n d = 1 cwnd=1 cwnd=1
  3. 快重传 & 快恢复
    • 收到3个重复ACK立即重传丢失包,不等待超时。

何时减慢增速

  • 慢启动阶段: c w n d ≥ s s t h r e s h cwnd \geq ssthresh cwndssthresh
  • 拥塞避免阶段:检测到丢包(网络拥塞的信号!)

📉 减速口诀:网络一卡,立马刹车!


🎯 总结:TCP/IP是C++后端开发的基石,理解这些细节才能写出高性能网络代码!快转发给一起备战的小伙伴吧~ [👬求组队刷题]

恭喜你坚持到这里!👏 本期我们覆盖了计算机网络中的基本原理,并实战解决了十个高频面试题。记住:理解其中的实现思想比硬背八股更重要,多练习才能在面试中游刃有余。😊 如果有疑问,欢迎评论区讨论~ 下期见!🚀

更多推荐