深色模式
01 · 高频追问链 40 条
面试不是"问答",是"追问"。能扛住第三层追问,才算真懂。 用法:盖住右边,只看问题链,自己往下答。答不出来的回到对应篇目。
怎么用
每条链的格式:
Q1 > Q2 > Q3 > Q4
关键答点:一句话说清这条链的"命门"在哪自测方法:只看 Q1,然后一路往下自问自答。卡在第几层,就说明那层没懂。
一、操作系统(1-12)
1. 进程和线程的区别
线程共享什么?(栈私有、堆共享) 为什么栈私有?(每个线程要有独立的函数调用链) 那局部变量一定线程安全吗?(不一定,引用可能指向堆上共享对象) 怎么保证共享数据安全?(锁 > 链 5) 关键答点:别停在"资源分配单位 vs 调度单位",要落到"隔离与开销"。
2. 进程切换比线程切换贵在哪
要保存什么?(寄存器现场) 最贵的一步是什么?(切换页表 CR3) 为什么切页表贵?(TLB 失效,之后每次访存都要重新查页表) 那协程为什么更轻?(用户态切换,不换页表不进内核) 关键答点:贵在页表和 TLB,不是"要保存的东西多"。
3. 进程状态转换
有哪几个状态?(新建/就绪/运行/阻塞/终止) 阻塞能直接到运行吗?(不能,必须先到就绪,因为 CPU 可能被占) 运行到就绪是谁触发的?(时间片用完,被动) 运行到阻塞呢?(自己发起 IO,主动) 关键答点:阻塞 > 就绪 > 运行,中间必须排队。
4. 虚拟内存解决了什么
不这么做会怎样?(地址冲突、无法隔离、必须连续) 怎么翻译地址?(页表 + MMU) 页表太大怎么办?(多级页表,按需分配) 多级页表多了访存怎么办?(TLB) 关键答点:三个价值——隔离、超卖、免连续。
5. 缺页中断的流程
怎么知道缺页?(页表项存在位为 0) 先做什么?(找空闲页框,没有就选牺牲页) 牺牲页脏了怎么办?(先写回磁盘) 处理完怎么继续?(更新页表,重新执行那条指令) 关键答点:"重新执行指令"这一步不能漏。
6. 页面置换算法
有哪几种?(OPT / FIFO / LRU / Clock) 为什么不用 LRU?(精确实现太贵,每次访存都要记录) Clock 怎么近似?(访问位 + 环形扫描) 抖动是什么?(进程太多,页框不够,频繁换页) 关键答点:工程上选 Clock,是"效果换成本"。
7. 死锁的四个条件
分别是什么?(互斥/持有并等待/不可剥夺/循环等待) 破坏哪个最实用?(循环等待 > 全局顺序申请) 数据库怎么处理?(等待图检测 + 回滚代价最小的事务) 死锁检测有什么问题?(O(n²),高并发 CPU 打满) 关键答点:说清"破坏哪个"比背四条更重要。
8. 自旋锁和互斥锁
区别?(抢不到时:自旋 vs 睡眠) 怎么选?(临界区极短 + 多核 > 自旋) 单核为什么不能用自旋?(占着唯一的核,持有者没法释放) 读写锁呢?(读读并行,写写互斥,适合读多写少) 关键答点:判断依据是"临界区长度 + 是否可能阻塞 + 是否多核"。
9. CAS 的问题
CAS 是什么?(比较并交换,一条原子指令) 有什么坑?(ABA / 自旋开销 / 只能保护单变量) ABA 怎么解决?(加版本号) 冲突激烈时怎么办?(退回锁,或者用 LongAdder 分段) 关键答点:ABA 必须能举出具体场景。
10. 五种 IO 模型
哪五种?(阻塞/非阻塞/多路复用/信号驱动/异步) 为什么前四种是同步的?(第二阶段拷贝仍要自己等) 只有谁是异步?(AIO,第二阶段也不阻塞) Linux 的 AIO 成熟吗?(io_uring 之前不成熟) 关键答点:用"两个阶段"讲,不要罗列名字。
11. epoll 为什么比 select 快
select 有什么问题?(1024 上限 + 每次全量拷贝 + O(n) 遍历) epoll 怎么解决?(注册一次 + 回调挂就绪链表 + 只返回就绪) epoll 永远更快吗?(不是,fd 少且全活跃时不一定) LT 和 ET 的区别?(通知时机不同) 关键答点:三个原因 + 一句"什么时候不占优"。
12. 零拷贝
普通方式拷贝几次?(4 次拷贝,4 次切换) sendfile 省了哪几次?(省掉用户态那两次 CPU 拷贝) 真的零拷贝吗?(零 CPU 拷贝,DMA 拷贝还在) 什么场景不能用?(需要修改数据时,比如加密压缩) 关键答点:"零"指的是零 CPU 拷贝。
二、计算机网络(13-24)
13. 三次握手
过程?(SYN > SYN+ACK > ACK) 为什么不是两次?(历史 SYN 会让服务器白建连接、占资源) 第三次能带数据吗?(能,前两次不能) 序号为什么随机?(防历史报文误接收 + 安全) 关键答点:两次握手的问题要能讲成一个完整场景。
14. 四次挥手
过程?(FIN > ACK > FIN > ACK) 为什么不是三次?(全双工,服务器可能还有数据要发) 什么情况会变成三次?(服务器没数据了,ACK+FIN 合并) TIME_WAIT 在哪一方?(主动关闭方) 关键答点:全双工是根本原因。
15. TIME_WAIT 为什么等 2MSL
两个理由?(保证最后 ACK 可达 + 残留报文消亡) 为什么是 2 不是 1?(覆盖一个完整往返) 大量 TIME_WAIT 怎么办?(长连接 / tcp_tw_reuse) CLOSE_WAIT 呢?(代码没关连接,是 bug) 关键答点:两个理由都要说,缺一个就扣分。
16. TCP 怎么保证可靠
三根支柱?(序号 / 确认 / 重传) 什么时候重传?(超时 / 3 个重复 ACK) 为什么是 3 个重复 ACK?(乱序也会产生重复 ACK,3 个才够确定) 只重传丢失那段吗?(SACK 可以做到) 关键答点:"可靠"不是"不丢",是"丢了能补"。
17. 流量控制 vs 拥塞控制
区别?(一个怕对方收不下,一个怕路上堵) 分别用什么实现?(滑动窗口 / cwnd) 实际发送窗口?(min(两者)) 慢启动为什么叫慢?(起点低,不是增长慢) 关键答点:一句话区分两者,是这题的命门。
18. 超时重传 vs 快速重传
触发条件?(超时 / 3 dup ACK) 处理差异?(cwnd 降到 1 / cwnd 减半) 为什么区别对待?(一个是"路断了",一个是"掉了个包裹") 快速恢复是什么?(减半后不回到慢启动,直接从 ssthresh 线性增长) 关键答点:区别对待的"为什么"比"是什么"重要。
19. TCP 队头阻塞
是什么?(前面的段丢了,后面的必须等) HTTP/2 解决了吗?(只解决了应用层的,TCP 层没解决) 为什么 HTTP/2 反而更糟?(所有流共享一个连接,一个丢包卡住全部) HTTP/3 怎么解决?(QUIC 基于 UDP,每流独立排序) 关键答点:区分"应用层 HOL"和"TCP 层 HOL"。
20. HTTP 版本演进
1.1 加了什么?(keep-alive、管道化、Host、分块传输) 2.0 加了什么?(二进制分帧、多路复用、头部压缩) 3.0 改了什么?(换 QUIC/UDP) 主线是什么?(都在减少往返、消除队头阻塞) 关键答点:用一条主线串,不要罗列特性。
21. 强缓存 vs 协商缓存
强缓存看什么?(Cache-Control: max-age) 协商缓存看什么?(If-None-Match / If-Modified-Since) 顺序?(先强缓存,过期了才协商) no-cache 和 no-store 区别?(缓存但校验 vs 完全不缓存) 关键答点:no-cache 的坑必须能说清。
22. HTTPS 的握手
解决哪三件事?(机密性、完整性、身份认证) 为什么非对称 + 对称混用?(非对称慢,只用来协商密钥) 怎么确认公钥是对方的?(证书 + CA 签名 + 证书链) 能防中间人吗?(能,除非用户信任了恶意根证书) 关键答点:证书解决的是"公钥归属"问题。
23. DNS 查询过程
缓存链?(浏览器 > 系统 > hosts > 本地 DNS > 迭代) 递归和迭代分别是谁对谁?(客户端对本地 DNS 递归,本地对上级迭代) 为什么用 UDP?(小、快) 什么时候用 TCP?(响应超 512 字节、区域传送、DoT) 关键答点:"谁对谁是递归"这题很多人答反。
24. ARP 的作用
干什么?(IP > MAC) 请求和响应方式?(广播请求,单播响应) 为什么只能局域网?(广播域限制) 跨网段怎么办?(ARP 网关,网关再 ARP 下一跳) 查的是目标的 MAC 吗?(不是,是下一跳的) 关键答点:"下一跳"这个点最容易答错。
三、数据结构与算法(25-33)
25. 数组 vs 链表
随机访问?(O(1) vs O(n)) 插入删除?(数组 O(n),链表定位仍 O(n)) 为什么实测差 10 倍?(缓存局部性、预取器、指针开销) 什么时候真该用链表?(频繁在已知位置增删,如 LRU) 关键答点:能说出"实测差距来自缓存"。
26. 哈希表
查找为什么 O(1)?(哈希直接算下标) 冲突怎么解决?(拉链 / 开放寻址) 装太满会怎样?(冲突变多,退化成 O(n)) 怎么避免?(负载因子 + 扩容) 容量为什么是 2 的幂?(位运算 + 扩容只需判断一位) 关键答点:O(1) 是平均,不是最坏。
27. 为什么用 B+ 树做索引
为什么不用哈希?(不支持范围查询、排序、最左前缀) 为什么不用红黑树?(树高 24 层 = 24 次磁盘 IO) 为什么不用 B 树?(数据占空间,节点存键少,树高更高) B+ 树强在哪?(数据全在叶子、叶子有链表、IO 次数稳定) 关键答点:所有比较都要落到"磁盘 IO 次数 = 树高"。
28. 二叉搜索树退化
BST 查找多快?(O(树高)) 什么情况退化?(有序插入 > 变成链表) 怎么解决?(平衡树:AVL / 红黑树) 红黑树和 AVL 怎么选?(写多用红黑,读多用 AVL) 关键答点:平衡树的目的是"保证最坏情况"。
29. 堆
是什么?(完全二叉树 + 局部有序) 为什么用数组存?(下标可算父子,无指针,缓存友好) 插入删除?(上浮/下沉,O(log n)) 建堆为什么是 O(n)?(大部分节点在底层,下沉距离短) 关键答点:建堆 O(n) 是高频陷阱。
30. BFS vs DFS
数据结构?(队列 vs 栈) 用途?(BFS 找无权最短路/层序,DFS 找连通性/拓扑/回溯) 空间?(O(宽度) vs O(深度)) 为什么 BFS 能找到最短路?(按层扩展,第一次到达就是最短) 关键答点:无权图最短路用 BFS,这是应用判断。
31. Dijkstra 为什么不能有负权
基于什么假设?(已确定的最短距离不会再变短) 负权怎么破坏它?(绕远路可能更短) 那用什么?(Bellman-Ford) Bellman-Ford 还能干什么?(检测负环) 关键答点:能举出一个具体的三节点反例。
32. 并查集
两个操作?(find / union) 两个优化?(路径压缩 + 按秩合并) 复杂度?(O(α(n)),接近 O(1)) 能处理有向图吗?(不能,丢失方向信息) 关键答点:为什么接近 O(1) 要能说清。
33. 快排
思路?(分区 + 递归) 最坏为什么 O(n²)?(pivot 每次都是极值) 什么时候会发生?(有序输入 + 固定选首元素) 怎么优化?(随机 pivot / 三数取中 / 三路快排) 和归并比?(快排原地不稳定,归并稳定需额外空间) 关键答点:"已排序的数组最慢"是反直觉但必答的点。
四、数据库(34-40)
34. 为什么用 B+ 树(已在 27,这里是数据库视角)
2000 万行几层?(3 层,因为非叶子能存 1170 个键) 一次查询几次 IO?(最多 3 次) 叶子节点存什么?(聚簇索引存整行,二级索引存主键) 二级索引查到主键后还要做什么?(回表) 关键答点:能算出"3 层"这个数字。
35. 索引失效
常见原因?(函数、类型转换、前导模糊、OR、区分度低) 为什么类型转换会失效?(等于对列做函数) 前导模糊为什么不行?(不知道从哪开始二分) 什么时候不该建索引?(小表、写多、区分度低) 关键答点:每种失效原因都要能说出"为什么"。
36. 最左前缀
联合索引 (a,b,c) 怎么排?(先 a 再 b 再 c) 能用 b 单独查吗?(不能,不知道 a 无法定位) a 用了范围查询后 b 能用吗?(不能用于定位,只能索引下推过滤) 怎么设计联合索引?(把等值查询的列放前面,范围查询放最后) 关键答点:"范围查询后面失效"是高频考点。
37. ACID 怎么实现
A?(undo log) D?(redo log,WAL) I?(锁 + MVCC) C?(不是单独实现的,是 AID + 业务约束的结果) 关键答点:"C 不是数据库实现的"是加分点。
38. MVCC
三件套?(隐藏字段 / undo 版本链 / ReadView) 怎么判断可见?(四个分支) RC 和 RR 的唯一区别?(ReadView 生成时机) 能解决幻读吗?(只解决快照读的,当前读要靠间隙锁) 关键答点:RC/RR 只差一处,说清这一处。
39. 间隙锁
干什么?(阻止在间隙插入,防幻读) 什么时候有?(RR 及以上,RC 没有) 代价?(锁范围大,死锁多) 为什么"没走索引会锁全表"?(行锁加在索引上,全表扫描时每行都访问到) 关键答点:行锁加在索引上,这是理解一切锁问题的前提。
40. 慢 SQL 排查
第一步?(EXPLAIN 看 type / rows / Extra) type=ALL 说明什么?(没走索引) 有索引为什么不用?(失效原因) 走了索引还慢?(回表太多 > 覆盖索引;数据量大 > 分表) 不是 SQL 的问题?(锁等待 / Buffer Pool / 硬件) 关键答点:不要一上来就说"加索引"。
跨模块连环追问(面试官最爱)
A. 从"输入 URL"开始,一路追问到磁盘
输入 URL 后发生了什么?
> DNS 怎么解析?(网络 05)
> 建连接为什么是三次握手?(网络 02)
> 数据怎么封装?(网络 01)
> 服务端怎么知道有数据来了?(OS 04 epoll)
> 应用读数据要几次拷贝?(OS 04)
> 查数据库怎么找到数据?(数据库 01 B+树)
> 内存里没有那页怎么办?(OS 02 缺页)
> 事务怎么保证不读到脏数据?(数据库 03 MVCC)B. 从"系统变慢"开始,一路追问到根因
系统变慢了,怎么排查?
> 先看什么?(CPU、内存、IO、网络)
> CPU 高?(计算密集 / 自旋锁 / GC)
> CPU 低但慢?(在等:锁 / IO / 网络)
> 在等锁?(OS 锁 / 数据库锁,看是不是没走索引锁全表)
> 在等 IO?(磁盘慢 / 网络 RTT 大 / 丢包重传)C. 从"高并发"开始,一路追问到瓶颈
怎么支撑 10 万并发?
> 连接怎么管?(epoll,一个线程管上万连接)
> 线程模型?(Reactor / 多线程 / 协程)
> 数据库扛得住吗?(连接池 + 索引 + 缓存)
> 缓存怎么防击穿?(互斥重建 / 逻辑过期)
> 缓存和数据库怎么一致?(先更新库再删缓存 / 延迟双删)✅ 验收清单
- 40 条链里,能完整答出 30 条以上(每条的最后一层也要答得上)
- 能说出每条链的"关键答点"是什么(不是背链,是知道命门在哪)
- 三条跨模块连环追问,能连续答 5 层以上不卡壳
- 任意抽 3 条链,能在 2 分钟内讲完(语速正常,不背稿)
- 能指出自己最弱的 5 条链,并回到对应篇目重读
- 合上书,挑一条链讲给别人听,对方能听懂