📋 摘要
- C++ 网络编程面试高频问答,每题只保留回答重点与扩展知识
- 详细原理解析与代码示例见 03-Resources/cpp/C++ 网络编程
- 持续补充中
1. 用过哪些 C++ 网络框架?都有什么优缺点?
📋 回答重点
- 先给框架定性:C/C++、Reactor/Proactor、是否跨平台,再谈优缺点。
- libevent:老牌 C 库、轻量稳定、自带 HTTP/DNS/bufferevent,但回调地狱、无内置线程模型。
- libuv:跨平台最好(Node.js 底层)、自带线程池/异步文件,但 C 风格、手动内存。
- Boost.Asio:C++ 头文件、Proactor 模型、同步/异步统一 + 协程,但编译慢、学习曲线陡。
- muduo:仅 Linux、one loop per thread 多线程模型清晰、高性能。
- 结尾落到「我在 XX 项目用它解决了 XX」,补齐个人经验。
扩展知识
- 选型:跨平台 + 异步文件用 libuv;纯 C++ 统一异步接口用 Boost.Asio;Linux 高性能用 muduo;C 老项目用 libevent。
- 详细讲解:03-Resources/cpp/C++ 网络编程
2. 用过哪些 C++ 数据库框架?都有什么优缺点?
📋 回答重点
- 分两类:底层 C API(MySQL C API / libpq / SQLite C API)与 C++ 抽象层(SOCI / ODBC)。
- MySQL C API:功能全、性能好,但 C 风格、手动管理 MYSQL/MYSQL_RES、易内存泄漏、字符串拼接易注入。
- libpq:PG 官方、支持异步/COPY,同样 C 风格、连接与结果管理繁琐。
- SQLite:嵌入式、零配置、单文件、事务,但并发写受限。
- SOCI:类型安全 + RAII + 后端插件化,文档少、较冷门;ODBC 跨库但 API 繁琐。
- 选型:单库要性能用官方 C API,跨数据库/要类型安全用 SOCI 或 ODBC。
扩展知识
- 底层 C API 要记得
mysql_free_result/PQclear/sqlite3_finalize,这正是 C++ 封装层 RAII 的价值。 - 详细讲解:03-Resources/cpp/C++ 网络编程
3. 用过哪些 C++ 日志框架?都有什么优缺点?
📋 回答重点
- 对比维度:性能(异步/零拷贝)、易用性(头文件 vs 链接)、可配置性、集成成本。
- spdlog:现代头文件库、极快、异步 + 多 sink、编译期级别开关零开销。
- glog:分级 + 崩溃栈 + 线程安全 + FLAGS 控制,但格式固定、需全局初始化、不宜作库依赖。
- log4cxx:配置灵活(XML/properties)、Appender/Layout 丰富,但较重、性能一般。
- 新项目默认 spdlog;要崩溃栈选 glog;要运行时改配置选 log4cxx。
扩展知识
- 加分点:主动提「异步日志 + 双缓冲/队列」「编译期宏屏蔽低级别日志、接近零开销」。
- 详细讲解:03-Resources/cpp/C++ 网络编程
4. 用过哪些 C++ 单元测试框架?都有什么优缺点?
📋 回答重点
- 对比维度:断言表达力、编译速度、集成度(fixture/参数化/mock)、生态与 CI。
- GoogleTest + GMock:功能最全、CI/CMake 集成好,编译慢、体积大。
- Catch2:头文件、REQUIRE 失败打印两侧实际值、BDD 风格,头文件重、编译慢。
- doctest:编译最快、可单头文件嵌入、支持子用例,功能较少、生态小。
- Boost.Test:数据驱动/浮点比较丰富,依赖 Boost、编译慢、宏复杂。
- 选型:大工程 + Mock 用 gtest;快速上手选 Catch2;编译敏感选 doctest。
扩展知识
- 加分点:单测接入 CI + 覆盖率(gcov/lcov),或用 GMock 隔离 DB/网络等外部依赖。
- 详细讲解:03-Resources/cpp/C++ 网络编程
5. 介绍下 socket 的多路复用?epoll 有哪些优点?
📋 回答重点
- IO 多路复用:单线程同时监听多个 fd,就绪才处理,避免「一线程一连接」的资源浪费。
- select:fd_set 上限 1024、每次全量拷贝、O(n) 遍历、仅水平触发。
- poll:pollfd 数组无数量上限,但仍 O(n) 遍历、仅水平触发。
- epoll:红黑树管注册(epoll_ctl O(log n))、就绪链表管派发(epoll_wait O(1))、mmap 减拷贝、支持 ET/LT。
- ET 需非阻塞 IO + 循环读到 EAGAIN;LT(默认)只要缓冲区有数据就反复通知。
扩展知识
- 加分点:答出「红黑树管注册、就绪链表管派发、mmap 减拷贝」三点,区分「背过」与「真懂」。
- 详细讲解:03-Resources/cpp/C++ 网络编程
6. Reactor 和 Proactor 模式的区别?epoll 属于哪种?
📋 回答重点
- Reactor = 同步非阻塞 + 事件回调:事件循环监听「就绪」事件,用户代码自己同步
read/write。 - Proactor = 异步 IO + 完成事件回调:用户先发起异步 IO,内核/运行时完成读写后回调通知「已完成」。
- 区别核心:谁执行读写 + 通知的是「就绪」还是「完成」。
- epoll 属于 Reactor;Boost.Asio、io_uring、IOCP 属于 Proactor。
- 一句话记忆:Reactor「可以读了,你去读」;Proactor「已经读好了,你用吧」。
扩展知识
- Reactor 典型实现:muduo、Netty(基于 epoll/kqueue)。
- io_uring 让 Linux 也有了原生 Proactor(异步 IO)。
- 详细讲解:03-Resources/cpp/C++ 网络编程
7. 零拷贝技术(mmap、sendfile、splice)的原理?
📋 回答重点
- 目的:减少内核态 ↔ 用户态之间的数据拷贝与上下文切换,降低 CPU 开销。
- mmap:文件映射到用户地址空间,内核缓冲区与用户空间共享同一物理页,省「内核→用户」拷贝。
- sendfile:内核内直接把数据从「文件页缓存」搬到「socket 缓冲区」,全程不进用户态。
- splice:内核内用管道连接两个 fd,数据在内核内「拼接」搬运,不经用户态。
- 传统路径 4 次拷贝,sendfile 可减到 2 次,配合 SG-DMA 更少。
扩展知识
- 适用场景:sendfile 用于静态文件/HTTP 下载;splice 用于 fd 间转发(代理)。
- mmap 代价:缺页中断、TLB 抖动、写保护(COW),小文件不如直接 read/write。
- 详细讲解:03-Resources/cpp/C++ 网络编程
8. TCP 粘包/拆包如何解决?如何设计应用层协议?
📋 回答重点
- 根因:TCP 是字节流、无消息边界;Nagle 合并小包、MTU 分片导致粘包/拆包。
- 三种解法:定长消息、分隔符、长度字段(头+体)。
- 工业主流:长度字段——固定长度消息头存 body 长度,再读 body。
- 应用层协议设计:消息头(定长字段)+ 消息体(变长)。
- 接收端必须维护累积缓冲区 + 处理半包,按协议规则切出完整消息。
扩展知识
- HTTP:
\r\n\r\n分隔头部 + Content-Length 定 body;Redis:RESP 行分隔。 - 半包兜底只能靠应用层逻辑,TCP 自身解决不了。
- 详细讲解:03-Resources/cpp/C++ 网络编程
9. 到底什么是 TCP 连接?
📋 回答重点
- TCP 连接是逻辑/虚拟概念,不是物理独占链路。
- 由四元组(源IP、源端口、目的IP、目的端口)唯一标识,加上两端各自维护的状态(seq/ack、窗口、拥塞状态、状态机)。
- 「建立连接」本质是双方内核创建并同步一套状态、对四元组达成一致。
- 底层数据仍是逐包 IP 转发,路由器并不知道连接的存在。
扩展知识
- TCP 状态机共 11 种状态(LISTEN、SYN_SENT、SYN_RECV、ESTABLISHED 等)。
- 详细讲解:03-Resources/cpp/C++ 网络编程
10. TCP 是用来解决什么问题?
📋 回答重点
- IP 只提供尽力而为投递:会丢、乱序、重复、损坏。
- TCP 在 IP 之上提供可靠、有序、面向字节流、全双工的传输能力。
- 机制一一对应:丢包→重传、乱序→序号排序、重复→序号去重、损坏→校验和、压垮对端→流量控制、压垮网络→拥塞控制。
扩展知识
- 字节流无消息边界 → 引发粘包/拆包问题,见 03-Resources/cpp/C++ 网络编程。
- 详细讲解:03-Resources/cpp/C++ 网络编程
11. 一台服务器,最多能建立多少 TCP 连接?
📋 回答重点
- 理论上限由四元组决定,不是「65535 端口」——对端源IP×源端口组合空间约 2^48。
- 实际瓶颈是内存(每连接几 KB~几十 KB)和文件描述符上限。
- 单机几十万到百万级连接可行,但需调优 fd、缓冲区、内核参数、epoll、多队列。
扩展知识
- 相关内核参数:
ulimit -n、/proc/sys/fs/file-max、net.ipv4.ip_local_port_range、net.core.somaxconn。 - 详细讲解:03-Resources/cpp/C++ 网络编程
12. TCP 和 UDP 有什么区别?
📋 回答重点
- TCP:面向连接、可靠、字节流(无边界)、有序、全双工、有流量/拥塞控制,头部 20~60 字节。
- UDP:无连接、不可靠、数据报(有边界)、不保证顺序、无流量/拥塞控制,头部固定 8 字节。
- TCP 用于文件/HTTP/SSH/数据库;UDP 用于 DNS/音视频/直播/游戏/IoT。
扩展知识
- 字节流 vs 数据报是核心追问点:TCP 因此有粘包/拆包问题,见 03-Resources/cpp/C++ 网络编程。
- 详细讲解:03-Resources/cpp/C++ 网络编程
13. 为什么要 TCP,IP 层实现控制不行么?
📋 回答重点
- 依据端到端原则(end-to-end argument):可靠传输应由通信两端保证,不下沉到网络层。
- IP 层若强制可靠,每台路由器都要为每条流维护状态、缓存重传,扩展性和转发性能崩溃。
- 网络层保持「简单、无状态、尽力而为」;应用需求多样(实时 vs 可靠),选择权留在传输层。
扩展知识
- 出处:Saltzer / Reed / Clark 的 end-to-end argument。
- 详细讲解:03-Resources/cpp/C++ 网络编程
14. 说说 TCP 的三次握手?
📋 回答重点
- 目的:确认双方收发能力正常 + 同步初始序列号 ISN。
- ① 客户端 SYN(seq=x) → ② 服务端 SYN+ACK(seq=y, ack=x+1) → ③ 客户端 ACK(ack=y+1)。
- 为什么三次:防止失效的重复 SYN 建立无效连接 + 确认双向收发能力。
- 服务端的 SYN 与 ACK 可合并,所以不需要四次。
扩展知识
- 第三次握手可携带数据(TFO 快速打开思想)。
- 详细讲解:03-Resources/cpp/C++ 网络编程
15. TCP 初始序列号 ISN 怎么取值的?
📋 回答重点
- ISN 必须随机化,不能固定为 0 或可预测值。
- 现代实现 = 随时间单调递增的时间分量(每 4μs +1)+ 随机偏移(IP/端口/密钥的 hash)。
- 目的:防序列号预测攻击、防新旧连接串包、防半开连接误认。
扩展知识
- Linux 的 timestamp 选项配合 PAWS 防序列号回绕。
- 详细讲解:03-Resources/cpp/C++ 网络编程
16. TCP 三次握手时,发送 SYN 之后就宕机了会怎么?
📋 回答重点
- 服务端进入 SYN_RECV 后,按 1s→2s→4s→8s→16s→32s 指数退避重传 SYN+ACK。
- 默认重传
tcp_synack_retries=5次后放弃并回收连接(约 63s)。 - 若客户端重启后收到迟到的 SYN+ACK,会回 RST,服务端收到 RST 立即释放。
扩展知识
- 半连接堆积正是 SYN Flood 的利用点,受
tcp_max_syn_backlog限制。 - 详细讲解:03-Resources/cpp/C++ 网络编程
17. 什么是 SYN Flood 攻击?
📋 回答重点
- 攻击者伪造大量源 IP 不可达的 SYN,服务端回 SYN+ACK 后进入 SYN_RECV 等待,永远等不到 ACK。
- 把半连接队列(SYN queue)打满,导致正常连接无法建立(DoS)。
- 核心防御:SYN Cookie——不提前分配资源,把连接信息编码进 SYN+ACK 的 seq,靠合法 ACK 才真正建连。
扩展知识
- 半连接队列与全连接队列(accept queue)是两个不同队列;还可增大 backlog、减少重传次数、限流清洗。
- 详细讲解:03-Resources/cpp/C++ 网络编程
18. TCP 协议是如何保证可靠传输的?
📋 回答重点
- 序号 seq:给字节编号,保证有序、去重;确认 ack:告知已按序收到。
- 校验和:检测传输错误;重传:超时重传(RTO)+ 快速重传(3 个重复 ACK)。
- 流量控制:滑动窗口 rwnd 防止压垮接收方;拥塞控制:慢启动/拥塞避免/快重传/快恢复防止压垮网络。
扩展知识
- 区分「超时重传 vs 快速重传」「流量控制(对端)vs 拥塞控制(网络)」两对概念。
- 详细讲解:03-Resources/cpp/C++ 网络编程
19. 说说 TCP 的四次挥手?
📋 回答重点
- TCP 全双工,两个方向独立关闭,所以「双方各一次 FIN + 各一次 ACK」共四次。
- ① 主动方 FIN → ② 被动方 ACK → ③ 被动方 FIN → ④ 主动方 ACK。
- 为什么四次:FIN 只关「自己→对方」一个方向,被动方可能还有数据要发,ACK 和 FIN 通常无法合并。
- 主动方最后进入 TIME_WAIT,被动方经历 CLOSE_WAIT → LAST_ACK → CLOSED。
扩展知识
- 若被动方无数据要发,可把 ACK+FIN 合并,退化为「三次挥手」。
- 详细讲解:03-Resources/cpp/C++ 网络编程
20. 为什么 TCP 挥手需要有 TIME_WAIT 状态?
📋 回答重点
- 出现在主动关闭方,持续 2MSL(Linux MSL=30s,即 60s)。
- 原因一:保证最后一个 ACK 可靠送达,若 ACK 丢失能再次回应对方重传的 FIN。
- 原因二:让旧连接的迟到报文在网络中消亡,防止串到复用同四元组的新连接。
扩展知识
- 代价是占资源,处理:
SO_REUSEADDR、tcp_tw_reuse;tcp_tw_recycle因 NAT 问题已废弃。 - 详细讲解:03-Resources/cpp/C++ 网络编程
21. 除了四次挥手,还有什么方法断开连接?
📋 回答重点
- RST 异常终止:单报文、立即断开,丢弃收发缓冲中未处理数据,不进入 TIME_WAIT。
- RST 触发场景:收到不存在连接的报文、连接错误、
SO_LINGER(linger=0)、keepalive 探测失败。 - 对比:FIN 是优雅关闭(四次挥手、可靠交付、进入 TIME_WAIT),RST 是强制复位。
扩展知识
- 半关闭
shutdown(SHUT_WR)只关发送方向仍可收;keepalive 保活探测对端存活。 - 详细讲解:03-Resources/cpp/C++ 网络编程
22. TCP 超时重传机制是为了解决什么问题?
📋 回答重点
- 解决 TCP 可靠传输里的丢包发现与补救:IP 网络是尽力而为的,数据可能丢、乱序、重复。
- 发送方每发一个段就启动定时器,超时未收到 ACK 就重发。
- 超时时间 RTO 不是固定的,而是由 RTT 动态估算:
RTO = SRTT + 4·RTTVAR。 - Karn 算法:重传的段不参与 RTT 采样,避免污染估计值。
- 连续超时做指数退避(RTO 翻倍),多次仍无响应则放弃连接。
扩展知识
- RTO 通常有下限(约 200ms),设太短会误判重发、太长则延迟高。
- 与 03-Resources/cpp/C++ 网络编程 关联:超时重传是兜底,快速重传补速度。
- 详细讲解:03-Resources/cpp/C++ 网络编程
23. TCP 中何时会出现 RST(reset)报文?
📋 回答重点
- RST 是 TCP 首部标志位之一,作用是异常/暴力终止连接,不需要四次挥手、也不回 ACK。
- 常见触发:请求不存在的端口、半开连接(一方崩溃重启后收到不认识的包)、
SO_LINGER=0时 close。 - 收到 RST 后,接收方立即丢弃缓冲区未读数据并关闭 socket。
- 对比 FIN:FIN 是优雅关闭(四次挥手),RST 是异常重置(立即断、不确认)。
扩展知识
- 其他场景:SYN 请求到已建立连接的端口、多次重传放弃、NAT/防火墙拦截。
- 详细讲解:03-Resources/cpp/C++ 网络编程
24. TCP 有超时重传为什么还需要快速重传机制?
📋 回答重点
- 因为超时重传太慢:RTO 有下限(约 200ms),丢包后要等一个 RTO,高带宽低延迟下卡顿明显。
- 快速重传利用累计确认:接收方收到乱序段就重发上一个 ACK,形成重复 ACK。
- 发送方收到 3 个重复 ACK,就判断该 ACK 后面的段丢了,不等超时、立即重传。
- 超时回慢启动(cwnd 降到 1),3 个重复 ACK 只走快速恢复(cwnd 减半),代价更小。
扩展知识
- 为什么是「3 个」:1~2 个可能是乱序/抖动,3 个才足够可靠判断确实丢段。
- 两者互补:超时是兜底(整个窗口丢光、无 ACK 时仍靠它),快速重传解决速度。
- 详细讲解:03-Resources/cpp/C++ 网络编程
25. TCP 的 SACK 的引入是为了解决什么问题?
📋 回答重点
- 解决重传粒度太粗的问题:传统累计 ACK 只知道「丢段了」,不知道具体丢哪几个。
- 没有 SACK 时,快速重传可能重复重传已收到的段、或只重传一个段导致恢复慢。
- SACK 在 TCP 选项里携带已收到的块的左右边界,明确告诉发送方「只缺中间的洞」。
- 效果:从「重传整个窗口」变为「只重传丢失的洞」,精准且省带宽。
扩展知识
- 配套 DSACK:接收方上报重复收到的段,用于区分「真丢」还是「ACK 丢/乱序」。
- 需双方握手时协商
TCP_SACK选项才生效,常与快速重传的 3 个重复 ACK 配合。 - 详细讲解:03-Resources/cpp/C++ 网络编程
26. TCP 滑动窗口的作用是什么?
📋 回答重点
- 滑动窗口是 TCP 实现流量控制的核心机制,避免发送过快撑爆接收方缓冲区。
- 接收方在 ACK 里通告 rwnd(接收窗口),发送方未确认数据量不能超过窗口。
- 发送窗口 = min(rwnd, cwnd):rwnd 管接收方能力(流量控制),cwnd 管网络拥塞(拥塞控制)。
- 窗口随 ACK 到达右移、随 rwnd 大小伸缩,实现「边确认边滑动」。
扩展知识
- 零窗口问题:rwnd=0 时发送方靠零窗口探测定时探询,防止窗口恢复通知丢失导致死锁。
- 窗口只调节发送节奏,不切分消息边界——粘包问题仍需应用层处理,见 03-Resources/cpp/C++ 网络编程。
- 详细讲解:03-Resources/cpp/C++ 网络编程
27. 说说 TCP 拥塞控制的步骤?
📋 回答重点
- 拥塞控制解决网络本身拥塞,由发送方维护拥塞窗口 cwnd。
- 慢启动:cwnd 从 1 MSS 指数翻倍,直到达阈值 ssthresh。
- 拥塞避免:cwnd 每 RTT 线性 +1(加法增大),温和探测容量。
- 超时:ssthresh = cwnd/2,cwnd 回 1 重新慢启动。
- 快速重传/快速恢复:3 个重复 ACK 立即重传,cwnd 减半而非归零。
扩展知识
- 核心是 AIMD(加法增大、乘法减小);超时比 3 个重复 ACK 更严重,所以处理更狠。
- 现代算法有 NewReno、BIC、CUBIC(Linux 默认)。
- 详细讲解:03-Resources/cpp/C++ 网络编程
28. ARP 和 RARP 分别是什么?有什么区别?
📋 回答重点
- 都是地址解析协议,解决「逻辑地址 ↔ 物理地址」映射,方向相反。
- ARP:由 IP 查 MAC,主机发送数据前需要下一跳 MAC 才能组帧。
- RARP:由 MAC 查 IP,早期无盘工作站开机查自己的 IP。
- 关键区别:方向相反、用途不同;RARP 已被 DHCP/BOOTP 取代,现在几乎不部署。
扩展知识
- ARP 广播请求、单播应答,并把 IP-MAC 映射写入 ARP 缓存。
- ARP 无认证,存在 ARP 欺骗/中间人攻击风险。
- 详细讲解:03-Resources/cpp/C++ 网络编程
29. TCP/IP 四层模型是什么?
📋 回答重点
- 实际互联网采用的分层模型,自下而上四层。
- 网络接口层:物理传输、MAC 地址、帧封装(以太网/WiFi)。
- 网络层:IP 寻址与路由(IP、ICMP、ARP)。
- 传输层:端到端进程通信(TCP/UDP,端口)。
- 应用层:HTTP/DNS/FTP 等应用协议。
扩展知识
- 发送自上而下层层加头(数据→段→包→帧),接收自下而上层层拆头。
- 比 OSI 七层更贴近实现,是「合并版」:应用层合并了 OSI 5/6/7 层。
- 详细讲解:03-Resources/cpp/C++ 网络编程
30. OSI 七层模型是什么?
📋 回答重点
- ISO 提出的理论参考模型,自上而下七层:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。
- 传输层做端到端(TCP/UDP)、网络层做 IP 路由、链路层做 MAC 帧、物理层传比特。
- 口诀:「物 数 网 传 会 表 应」(从下往上)。
- 是「先定标准再实现」的理想模型,实际落地失败但教学价值高。
扩展知识
- 与 TCP/IP 对应:OSI 5/6/7 层 ≈ TCP/IP 应用层;链路层+物理层 ≈ 网络接口层。
- 典型例子:TLS 在 OSI 归表示层,在 TCP/IP 归应用层。
- 详细讲解:03-Resources/cpp/C++ 网络编程
31. Cookie、Session、Token 之间有什么区别?
📋 回答重点
- 三者都是解决「HTTP 无状态」下如何维持状态/身份的手段。
- Cookie:浏览器本地的小块存储,是载体,不一定是身份凭证。
- Session:服务端保存的用户会话数据,有状态,靠 Cookie 里的 session_id 关联。
- Token:客户端自持的凭证(如 JWT),服务端验签即可,无状态。
- 分工:Session 是数据、Cookie 是存放 session_id 的载体、Token 是自持凭证。
扩展知识
- Session 分布式要共享存储(Redis);Token 天然无状态、易扩展,但难主动吊销。
- Cookie 有 CSRF 风险(自动携带)、Token 有泄露风险、Session 有扩展性问题。
- 详细讲解:03-Resources/cpp/C++ 网络编程
32. JWT Token 能说说吗?
📋 回答重点
- JWT 是无状态、自包含的身份凭证,结构为
Header.Payload.Signature三段 base64url。 - Header:声明签名算法(HS256/RS256);Payload:claims(sub/exp/iat 等);Signature:对前两段签名。
- 签名只保证完整性/防篡改,不保证机密性——Payload 只是 base64 编码,不能放敏感信息。
- 服务端验签即可恢复身份,无需存会话,适合分布式/微服务/跨域 API。
扩展知识
- 三个坑:Payload 不加密、难主动失效(登出/改密难)、密钥/算法安全(别用 alg:none)。
- 与 Session 对比:JWT 无状态易扩展、Session 可主动失效更可控。
- 详细讲解:03-Resources/cpp/C++ 网络编程
33. 简单谈谈你对 DNS 的理解?
📋 回答重点
- DNS 是域名解析系统,把易记域名转成可路由的 IP。
- 本质是分层、分布式、带缓存的数据库:根 → 顶级域(TLD) → 权威服务器逐级查询。
- 客户端对本地 DNS 用递归查询,本地 DNS 对各级服务器用迭代查询。
- 常见记录:A(IPv4)、AAAA(IPv6)、CNAME(别名)、MX(邮件)、NS(权威服务器)、TXT。
扩展知识
- 本地缓存 + TTL 加速解析;CDN 用 DNS 做就近调度(GSLB)。
- 排查工具
dig/nslookup;注意 DNS 污染/劫持。 - 详细讲解:03-Resources/cpp/C++ 网络编程
34. 简单谈谈你对 CDN 的理解?
📋 回答重点
- CDN 是内容分发网络,在各地部署边缘缓存节点,把内容提前缓存到离用户最近处。
- 核心三件事:内容缓存、就近调度(GSLB)、回源。
- 价值:降低延迟、减轻源站压力、多节点冗余、吸收 DDoS/突发流量。
- 用户请求被调度到最近节点,命中缓存直接返回,未命中才回源站拉取。
扩展知识
- 调度常依赖 DNS 智能解析,也可用 HTTP 302 重定向、Anycast。
- 关键概念:缓存命中率、刷新/预热、TTL、回源。
- 详细讲解:03-Resources/cpp/C++ 网络编程
35. 从网络角度来看,用户从输入网址到网页显示,背后发生了什么?
📋 回答重点
- 按时间顺序串成一条链:URL 解析 → DNS 解析 → TCP 三次握手 → TLS 握手 → HTTP 请求 → 服务器响应 → 浏览器渲染。
- DNS:域名→IP,走本地缓存 + 递归查询。
- TCP:三次握手建立可靠连接;HTTPS 额外多 TLS 握手(协商加密、校验证书)。
- 浏览器解析 HTML,并行加载 CSS/JS/图片等子资源(可能走 CDN)。
扩展知识
- HTTPS 比 HTTP 多 TLS(1~2 RTT),可被 HTTP/2 多路复用、TLS 1.3(1-RTT)优化。
- 一个页面往往发起多个请求:HTML 引用的子资源继续发起新 DNS/TCP/HTTP 流程(除非 keep-alive 复用)。
- 详细讲解:03-Resources/cpp/C++ 网络编程
36. 常见的登录鉴权方式有哪些?各自的优缺点是?
📋 回答重点
- Session + Cookie:服务端存会话、客户端带 session_id,简单可主动失效,但有状态(分布式要共享存储)、有 CSRF 风险。
- Token(JWT):自持凭证、无状态易扩展、跨域友好,但难主动吊销、Payload 不加密。
- OAuth 2.0 / OIDC:第三方授权、权限粒度可控,但流程复杂。
- SSO(单点登录):一次登录多系统共享,体验好,但中心化依赖。
- 选型:单体用 Session、微服务/移动端用 JWT、接第三方用 OAuth、企业内部用 SSO。
扩展知识
- 其他变体:HTTP Basic Auth、API Key、MFA/OTP 二次认证。
- 安全要点:全站 HTTPS、Cookie 设 HttpOnly/Secure/SameSite、口令加盐哈希、防 CSRF/XSS/重放。
- 详细讲解:03-Resources/cpp/C++ 网络编程
37. HTTP 1.0 和 2.0 有什么区别?
📋 回答重点
- 连接模型:HTTP/1.0 默认短连接(一个请求一条 TCP,复用需手动 keep-alive);HTTP/2.0 单连接多路复用。
- 传输格式:1.0 是文本;2.0 是二进制分帧(Frame + Stream)。
- 头部压缩:1.0 无;2.0 用 HPACK 压缩头部,减少重复传输。
- 队头阻塞:1.0 串行一个请求堵全局;2.0 多路复用在应用层解决队头阻塞。
- 2.0 还支持服务器推送(Server Push)、流优先级、流控制。
扩展知识
- 中间态 HTTP/1.1 引入了长连接(默认 keep-alive)、管道化、
Host头,但管道化仍有队头阻塞。 - HTTP/2 只解决应用层队头阻塞,TCP 层队头阻塞要 HTTP/3 才解决。
- 详细讲解:03-Resources/cpp/C++ 网络编程
38. HTTP 2.0 和 3.0 有什么区别?
📋 回答重点
- 传输层:HTTP/2 基于 TCP;HTTP/3 基于 UDP 上的 QUIC。
- 加密:2.0 用 TLS(多握手);3.0 将 TLS 1.3 内建于 QUIC,强制加密。
- 连接建立:2.0 需 TCP 三次握手 + TLS 握手(2~3 RTT);3.0 支持 0-RTT / 1-RTT。
- 队头阻塞:2.0 仍受 TCP 丢包重传的队头阻塞;3.0 流独立,彻底消除。
- 连接迁移:3.0 用 Connection ID 标识连接,切网不断连。
扩展知识
- QUIC 的代价:可靠传输、拥塞控制、TLS 全要自己在 UDP 上实现(用户态)。
- HTTP/3 语义不变,只换传输层,上层 API 几乎无感。
- 详细讲解:03-Resources/cpp/C++ 网络编程
39. 常见的 HTTP 状态码有哪些?
📋 回答重点
- 状态码三位数字,首位代表类别:1xx 信息、2xx 成功、3xx 重定向、4xx 客户端错误、5xx 服务端错误。
- 常见成功:200 OK、201 Created、204 No Content、206 Partial Content(断点续传)。
- 常见重定向:301 永久、302 临时、304 未修改(走缓存)。
- 常见客户端错误:400 语法错误、401 未认证、403 无权限、404 不存在、429 限流。
- 常见服务端错误:500 内部错误、502 网关坏响应、503 不可用、504 网关超时。
扩展知识
- 区分 401(没登录)vs 403(没权限)、301(永久)vs 302(临时)、502(上游无效响应)vs 504(上游超时)。
- 304 与缓存协商(ETag / Last-Modified)相关。
- 详细讲解:03-Resources/cpp/C++ 网络编程
40. HTTP 请求包含哪些内容,请求头和请求体有哪些类型?
📋 回答重点
- 请求报文四部分:请求行 → 请求头 → 空行(
\r\n\r\n)→ 请求体。 - 请求行 = 方法 + 目标路径 + HTTP 版本(如
POST /api/user HTTP/1.1)。 - 请求头类型:通用头(Cache-Control/Connection)、请求头(Host/User-Agent/Cookie/Authorization)、实体头(Content-Type/Content-Length)、自定义头。
- 请求体类型由
Content-Type决定:x-www-form-urlencoded、multipart/form-data、application/json、text/plain、application/octet-stream。 - body 长度由 **
Content-Length(定长)或Transfer-Encoding: chunked(分块)**决定。
扩展知识
- 空行是「头 / 体」的分界;body 长度不能靠「读到连接关闭」判断。
- 详细讲解:03-Resources/cpp/C++ 网络编程
41. HTTP 和 HTTPS 有什么区别?
📋 回答重点
- HTTPS = HTTP over TLS/SSL,在 HTTP 与 TCP 之间加一层 TLS 加密。
- 三大保障:机密性(加密)、完整性(防篡改)、身份认证(防冒充,靠 CA 证书)。
- 端口不同:HTTP 80,HTTPS 443。
- 加密方式:混合加密——非对称(RSA/ECDHE)协商会话密钥 + 对称(AES)加密数据 + 哈希保证完整性。
- 代价:握手与加解密带来额外 CPU / 时延开销。
扩展知识
- HTTPS 只保证传输途中安全,防不了应用层漏洞与端点被攻破。
- 证书链由 CA 逐级签发,防中间人伪造。
- 详细讲解:03-Resources/cpp/C++ 网络编程
42. HTTP 中 GET 和 POST 的区别是什么?
📋 回答重点
- 语义:GET 获取资源(幂等、可缓存、无副作用);POST 提交/创建数据(非幂等、改状态)。
- 参数位置:GET 放 URL 查询串;POST 放请求体。
- 幂等性:GET 幂等;POST 非幂等(重复提交可能重复创建)。
- 缓存:GET 可缓存、可收藏书签;POST 一般不缓存。
- 可见性/长度:GET 参数暴露在 URL、长度受限;POST 在 body、基本无上限、相对不易泄漏。
扩展知识
- 「GET 不安全、POST 安全」是误区:两者都不安全,要安全得上 HTTPS。
- RESTful 建议:GET 不应有副作用,创建/更新用 POST/PUT。
- 详细讲解:03-Resources/cpp/C++ 网络编程
43. WebSocket 与 HTTP 有什么区别?
📋 回答重点
- 通信方向:HTTP 是单向请求-响应(服务端不能主动发);WebSocket 是全双工双向实时通信。
- 连接生命周期:HTTP 短连接(一问一答);WebSocket 一次握手后长连接保持。
- 消息格式:HTTP 文本报文、每次带完整头;WebSocket 二进制帧、帧头极小(2~14 字节)。
- 建立方式:WebSocket 靠 HTTP
Upgrade握手升级(101 Switching Protocols)。 - 适用场景:HTTP 适合普通 API/页面;WebSocket 适合聊天、游戏、行情推送等实时场景。
扩展知识
- 相比「轮询/长轮询」,WebSocket 无重复头部开销、推送即时。
- 工程上要处理**心跳保活(Ping/Pong)**与断线重连。
- 详细讲解:03-Resources/cpp/C++ 网络编程
44. 服务端是如何解析 HTTP 请求的数据?
📋 回答重点
- 本质:在 TCP 字节流上用「累积缓冲区 + 状态机」按 HTTP 文法切出「请求行/头/体」。
- 流程:accept → epoll 可读 → read 追加进缓冲区 → 找
\r\n\r\n定界头部 → 解析请求行与头 → 按Content-Length/chunked 读 body → 交给业务。 - 必须处理半包(数据没到齐先缓存等下次)与粘包(缓冲区可能含多条请求)。
- body 长度靠
Content-Length或Transfer-Encoding: chunked,不能靠「读到连接关闭」。 - 生产级用状态机(如 http-parser / llhttp),并限制头/体大小、设读超时防慢速攻击。
扩展知识
- 防止 Slowloris 慢速攻击与超大 header/body 耗尽内存。
- 详细讲解:03-Resources/cpp/C++ 网络编程