真实面经题目 · 原创解析

TCP 如何进行拥塞控制?

TCP 拥塞控制通过动态调整拥塞窗口 cwnd 来控制网络中未确认数据量,目标是在尽量提高吞吐的同时避免把网络打爆。经典机制包括慢启动、拥塞避免、快速重传和快速恢复,现代实现还会结合 RTT、丢包、带宽估计和不同拥塞控制算法优化。

出现于:字节跳动 · 后端开发

60 秒回答模板

可以围绕拥塞窗口回答。TCP 发送方真正能发送的未确认数据量受接收窗口 rwnd 和拥塞窗口 cwnd 共同限制,取两者较小值。连接开始或超时后进入慢启动,cwnd 从较小值开始按 ACK 近似指数增长,快速探测可用带宽;达到慢启动阈值 ssthresh 后进入拥塞避免,cwnd 近似线性增长。检测到丢包时,超时通常说明拥塞严重,会把 ssthresh 降低并重新慢启动;收到三个重复 ACK 通常触发快速重传和快速恢复,认为只是个别报文丢失,降低 cwnd 后继续发送。整个过程本质是加性增、乘性减,让发送速率围绕网络可承载能力波动。

考点 窗口核心
难度 真实面经高频题
回答目标 讲清机制、边界和追问

深入解析

01

控制目标

拥塞控制解决的是发送方不要向网络注入超过承载能力的数据。它不同于流量控制:流量控制保护接收端缓存,用接收窗口 rwnd 表示;拥塞控制保护网络路径,用拥塞窗口 cwnd 表示。实际发送窗口通常是 min(rwnd, cwnd),既不能压垮接收方,也不能压垮网络。

02

慢启动

慢启动名字容易误导,它不是增长慢,而是从保守窗口开始快速增长。每收到 ACK,cwnd 增加,按一个 RTT 观察近似翻倍。这样连接不用一上来就按很高速率发送,而是逐步探测路径容量。慢启动持续到 cwnd 达到 ssthresh,或发生丢包等拥塞信号。

03

拥塞避免

当 cwnd 到达慢启动阈值后,继续指数增长容易造成拥塞,于是进入拥塞避免阶段。这个阶段窗口增长变得更温和,典型效果是每个 RTT 近似增加一个 MSS。它体现加性增思想:在网络看起来正常时谨慎提高发送速率,逐步逼近可用带宽。

04

丢包反应

TCP 把丢包、超时和重复 ACK 视作拥塞信号,但严重程度不同。RTO 超时通常说明网络或对端响应问题较严重,发送方会大幅降低 cwnd,重新慢启动。三个重复 ACK 则说明后续包仍能到达,对应快速重传丢失报文,并进入快速恢复,窗口降低但不必完全回到初始状态。

05

算法演进

经典教材常讲 Tahoe、Reno 的慢启动和拥塞避免,但真实系统可能使用 CUBIC、BBR 等算法。CUBIC 通过三次函数改善高带宽长延迟链路利用率,BBR 更关注带宽和最小 RTT 估计。无论算法如何变化,核心仍是根据网络反馈调节发送速率,避免持续排队和丢包崩溃。

易错点

  • 把拥塞控制说成接收方缓存不够,混淆了拥塞控制和流量控制。
  • 认为慢启动是线性增长,忽略它在阈值前按 ACK 反馈近似指数增长。
  • 只说丢包就重传,不说明 cwnd、ssthresh、快速恢复等窗口调整。
  • 把所有 TCP 都当成 Reno,忽略 CUBIC、BBR 等现代实现可能采用不同策略。

面试官追问

拥塞控制和流量控制有什么区别?

流量控制避免发送方压垮接收方,由接收窗口 rwnd 表达;拥塞控制避免发送方压垮网络路径,由拥塞窗口 cwnd 表达。发送方要同时遵守两者。

慢启动为什么叫慢启动?

它相对一开始就全速发送而言是慢的,因为从小窗口起步;但窗口增长本身很快,按 ACK 反馈在每个 RTT 近似翻倍,直到达到阈值或出现拥塞。

三个重复 ACK 为什么能触发快速重传?

重复 ACK 表示接收方一直期待同一个缺失序号,同时后续数据已经到达,说明某个报文很可能丢失但路径并未完全中断,因此可以不等超时就重传。

BBR 和传统丢包型算法思路有什么不同?

传统算法多把丢包视为拥塞信号,BBR 更关注估计瓶颈带宽和最小 RTT,试图把发送速率控制在路径可承载范围附近,减少依赖丢包作为反馈。