【C++上岸】C++常见面试题目--网络篇(第二十二期)
📡 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连接管理
三次握手(建立连接):
- Client → SYN=1, seq=x
- Server → SYN=1, ACK=1, seq=y, ack=x+1
- Client → ACK=1, seq=x+1, ack=y+1
四次挥手(断开连接):
- A → FIN=1, seq=u
- B → ACK=1, seq=v, ack=u+1
- B → FIN=1, ACK=1, seq=w, ack=u+1
- 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(最大报文段大小)被分割发送。
解决方案:
- 定长协议:所有数据包固定长度(如512字节)。
- 分隔符:用特殊字符标记结束(如
\n)。 - 头部声明长度:在数据前添加长度字段(推荐!)。
// C++示例:自定义协议头
struct PacketHeader {
uint32_t length; // 数据长度
uint32_t type; // 数据类型
};
⚖️ 8. TCP vs UDP 区别
| 特性 | TCP | UDP |
|---|---|---|
| 连接性 | 面向连接 | 无连接 |
| 可靠性 | 可靠传输(重传机制) | 尽最大努力交付 |
| 速度 | 慢(需握手/确认) | 快(直接发数据包) |
| 报文边界 | 可能粘包/拆包 | 保留报文边界 |
| 适用场景 | 文件传输、网页浏览 | 视频流、实时游戏 |
🚀 UDP逆袭:谁说UDP不能可靠?看第9点!
🔧 9. UDP如何实现可靠传输?
在应用层模拟TCP机制:
- 添加序列号:为每个包标记seq,接收方排序去重。
- ACK确认:接收方回复ack(可累积确认)。
- 超时重传:设定定时器检测丢包。
- 流量控制:动态调整发送窗口(如QUIC协议)。
🌟 经典方案:Google的QUIC协议(HTTP/3底层)就是基于UDP的可靠传输!
🚦 10. TCP拥塞控制
目标:避免网络过载,通过动态调整发送窗口 c w n d cwnd cwnd(拥塞窗口)。
核心算法:
- 慢启动(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 cwnd≥ssthresh(慢启动阈值)时,进入拥塞避免。
- 拥塞避免(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个重复ACK立即重传丢失包,不等待超时。
何时减慢增速:
- 慢启动阶段: c w n d ≥ s s t h r e s h cwnd \geq ssthresh cwnd≥ssthresh
- 拥塞避免阶段:检测到丢包(网络拥塞的信号!)
📉 减速口诀:网络一卡,立马刹车!
🎯 总结:TCP/IP是C++后端开发的基石,理解这些细节才能写出高性能网络代码!快转发给一起备战的小伙伴吧~ [👬求组队刷题]
恭喜你坚持到这里!👏 本期我们覆盖了计算机网络中的基本原理,并实战解决了十个高频面试题。记住:理解其中的实现思想比硬背八股更重要,多练习才能在面试中游刃有余。😊 如果有疑问,欢迎评论区讨论~ 下期见!🚀
更多推荐
所有评论(0)