小红书 C++ 开发 业务面 面经
1. 自我介绍
(根据个人情况准备)
2. 说说HTTP的发展历程,HTTP/1.1、HTTP/2、HTTP/3有什么区别
答案:
HTTP/1.0:
- 短连接:每次请求都要建立TCP连接
- 无状态
- 只支持GET、POST等基本方法
HTTP/1.1:
- 长连接:Connection: keep-alive
- 管道化:可以同时发送多个请求
- 缓存控制:Cache-Control
- 分块传输:Transfer-Encoding: chunked
- Host头:支持虚拟主机
HTTP/2:
- 二进制分帧:不再是文本协议
- 多路复用:一个TCP连接处理多个请求
- 头部压缩:HPACK算法
- 服务器推送:Server Push
- 优先级和依赖:请求可以设置优先级
HTTP/3:
- 基于QUIC协议(UDP)
- 解决队头阻塞:丢包不影响其他流
- 0-RTT连接建立:更快
- 连接迁移:IP变化不影响连接
- 内置加密:TLS 1.3
对比总结:
传输层 |
TCP |
TCP |
QUIC(UDP) |
多路复用 |
否 |
是 |
是 |
队头阻塞 |
有 |
有(TCP层) |
无 |
头部压缩 |
否 |
是 |
是 |
连接建立 |
慢 |
慢 |
快(0-RTT) |
3. TCP的滑动窗口机制是什么?它能变小或向左移动吗
答案:
滑动窗口作用:
- 流量控制:防止发送方发太快
- 提高效率:不用每发一个包就等ACK
工作原理:
发送窗口:[已发送已确认][已发送未确认][可发送][不可发送] 接收窗口:[已接收已确认][可接收][不可接收]
窗口大小:
- 接收方通过ACK告知发送方窗口大小
- 窗口大小 = 接收方缓冲区剩余空间
窗口能变小吗:
- 可以变小:接收方缓冲区满了,窗口变小
- 可以变为0:接收方处理不过来,窗口为0,发送方停止发送
- 窗口探测:窗口为0时,发送方定期发送探测包
窗口能向左移动吗:
- 理论上不应该:已确认的数据不应该撤回
- 实际上不会:TCP协议规定窗口左边界只能右移或不动
- 如果左移:会导致数据混乱,协议错误
示例:
初始窗口:[1-10] 发送1-5,窗口:[6-10] 收到ACK 3,窗口:[4-13](右移) 接收方缓冲区满,窗口:[4-8](变小)
4. 如果网络波动很大,TCP协议有什么问题?如何优化
答案:
TCP在弱网下的问题:
- 队头阻塞:一个包丢失,后续包都要等待影响整体传输效率
- 重传开销大:超时重传时间长快速重传也需要等3个重复ACK
- 拥塞控制过于保守:丢包就认为网络拥塞大幅降低发送速率恢复慢
- 连接建立慢:三次握手延迟高弱网下更明显
优化方案:
- 应用层优化:减少请求次数:合并请求压缩数据:减少传输量分片传输:大文件分小块断点续传:失败后从断点继续
- 协议层优化:使用QUIC:基于UDP,无队头阻塞使用KCP:可靠UDP协议,牺牲带宽换延迟使用MPTCP:多路径TCP,同时用WiFi和4G
- 传输策略优化:自适应码率:根据网络调整数据量前向纠错(FEC):发送冗余数据选择性重传:只重传丢失的包
- TCP参数调优:调整初始拥塞窗口调整重传超时时间启用TCP Fast Open
实际应用:
- 视频直播:用QUIC或自研协议
- 文件传输:断点续传+分片
- 实时通信:WebRTC(基于UDP)
5. TCP第一次真正发送数据是在什么时候
答案:
TCP连接建立过程:
- 第一次握手:客户端发送SYN
- 第二次握手:服务端发送SYN+ACK
- 第三次握手:客户端发送ACK
第一次发送数据:
- 第三次握手时可以携带数据
- 客户端发送ACK的同时可以发送应用数据
- 这是TCP第一次真正发送业务数据
为什么第三次握手可以带数据:
- 此时客户端已经确认服务端存在且可达
- 连接已经建立(客户端视角)
- 可以开始传输数据
为什么前两次握手不能带数据:
- 第一次握手带数据:容易被攻击(SYN Flood)
- 第二次握手带数据:服务端还不确定客户端是否真实
TCP Fast Open(TFO):
- 优化:第一次握手就可以带数据
- 通过Cookie机制验证客户端
- 减少一个RTT
6. 如果你是微信的开发工程师,如何设计"检测当前网络"功能
答案:
需求分析:
- 检测网络是否可用
- 检测网络质量(延迟、丢包率、带宽)
- 给用户友好提示
设计方案:
1. 网络可达性检测:
bool checkNetworkReachability() {
// 方法1:ping微信服务器
bool pingSuccess = ping("wechat.com", timeout);
// 方法2:HTTP请求
bool httpSuccess = httpGet("https://wechat.com/health", timeout);
// 方法3:检查本地网络接口
bool hasNetwork = checkNetworkInterface();
return pingSuccess || httpSuccess;
}
2. 网络质量检测:
struct NetworkQuality {
int latency; // 延迟(ms)
float packetLoss; // 丢包率
int bandwidth; // 带宽(kbps)
};
NetworkQuality detectNetworkQuality() {
// 1. 延迟检测:ping多次取平均
int latency = 0;
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
C++八股文全集 文章被收录于专栏
本专栏系统梳理C++技术面试核心考点,涵盖语言基础、面向对象、内存管理、STL容器、模板编程及经典算法。从引用指针、虚函数表、智能指针等底层原理,到继承多态、运算符重载等OOP特性从const、static、inline等关键字辨析,到动态规划、KMP算法、并查集等手写实现。每个知识点以面试答题形式呈现,注重原理阐述而非冗长代码,帮助你快速构建完整知识体系,从容应对面试官提问,顺利拿下offer。