延迟/吞吐建模与故障定位

共 57 题
📑 题目列表 57 题
#
★★★

1. Bimodal latency(双峰延迟)的成因,GC pause、CPU steal、I/O readahead 的模式识别。

Bimodal latency(双峰延迟)的成因有哪些?如何通过 GC pause、CPU steal、I/O readahead 等模式识别来定位?

  • 双峰延迟的定义与典型成因
  • 如何区分 GC pause、CPU steal、I/O readahead 三类模式
  • 可观测工具与信号识别

双峰延迟指延迟分布呈现两个明显峰值(一个低延迟主峰和一个高延迟次峰),而非单一近似正态分布。常见成因包括:GC pause——JVM/Go 等托管运行时在 GC 时 STW(Stop-The-World)暂停,导致请求延迟瞬间飙升;CPU steal——在虚拟化/云环境下宿主机抢占导致 vCPU 被偷走,表现为 guest 侧 CPU 时间被静默扣除;I/O readahead——顺序读时内核预读(readahead)触发,冷数据首次访问需等待磁盘扇区读取导致延迟突增。识别方法:GC pause 可用 GC 日志或运行时 metrics 观察,暂停时间与 GC 事件对齐;CPU steal 可用 /proc/stat 的 steal 字段或 vmstat 的 st 列观察;I/O readahead 可用 iostat 观察 await 指标与 blk 相关 tracepoint。

双峰延迟本质是"叠加的慢路径"——多数请求走快速路径,少数请求触发某种"偶发慢事件"。定位的关键是把延迟分布与基础设施事件(GC 日志、CPU steal、I/O 队列)做时间对齐,找出哪类事件与高延迟峰强相关。

#
★★★

2. HdrHistogram(高动态范围直方图)相比固定桶直方图的内存优势与 P99.9 精度。

HdrHistogram(高动态范围直方图)相比固定桶直方图在内存占用和 P99.9 精度上有何优势?

  • HdrHistogram 的编码原理(对数/指数桶)
  • 与固定桶直方图的内存对比
  • P99.9 精度的保证方式

HdrHistogram 以"两个二进制幂之间的桶再细分"的编码方式记录数值,即每个十进制数量级内的桶数固定,从而在几 KB 到几十 KB 内存内覆盖从纳秒到小时的巨大动态范围,且对任意数量级的分位数精度一致(例如 P99.9 误差在 1% 以内)。固定桶直方图若桶宽足够小则精度高,但要么桶数爆炸(内存大),要么动态范围小;若桶宽大则分位数精度差。HdrHistogram 用固定精度(如 3 位有效数字)换取恒定内存,适合在服务端聚合长尾分布。

核心是"相对精度"而非"绝对精度"——HdrHistogram 对 1ms 与 1s 的 P99.9 都保持相同的相对误差,而绝对误差随数值增长,这正好匹配延迟分析中"关注数量级"的需求。

#
★★★

3. Warmup 阶段的延迟劣化(cold cache、cold JIT)与 warmup curve 的工程治理。

Warmup 阶段的延迟劣化(如 cold cache、cold JIT)由什么引起?如何工程治理 warmup curve?

  • cold cache 与 cold JIT 的成因
  • warmup curve 的形状与影响
  • 治理手段(预热、压测、JIT 预热)

服务刚启动时延迟偏高,是因为 CPU 缓存(L1/L2/LLC)与操作系统 page cache 均为空,首次访问需冷加载;JIT 编译器(JVM、V8)尚未完成方法编译,解释执行或轻度优化路径慢,且热点数据与 GC 结构也未就绪。warmup curve 即延迟随时间从高位下降并趋于稳定的曲线。治理手段:启动时主动预热(回放请求、预热连接池、预热缓存);在压测/容量评估中排除 warmup 期数据,以稳定段为基线;对 JIT 应用可提前触发关键路径编译或使用 AOT(如 GraalVM Native Image)消除 JIT 冷启动;对 CPU cache 可预热常驻工作集。

warmup 的本质是"状态尚未达到稳态"。工程上要区分"冷启动延迟"与"稳态延迟",避免将 warmup 噪声误判为回归,并主动缩短 warmup 期。

#
★★★

4. t-digest 算法在流式分位数估计的精度-内存权衡与 P99.9 误差边界。

t-digest 算法在流式分位数估计中如何权衡精度与内存?其 P99.9 误差边界如何?

  • t-digest 的核心思想(centroid 聚类,尾部更细)
  • 流式处理的能力
  • 与 HdrHistogram 的对比

t-digest 用一组质心(centroid,即带权重的均值簇)来近似分布,且自适应地让分布在尾部的质心更密、中心更稀,从而在不牺牲分位数精度的前提下用很少的内存(KB 级)表示海量样本。它支持流式(在线)更新,可自然合并多个 t-digest 实现集群聚合。P99.9 等尾部分位数误差通常控制在 1% 以内,因为尾部质心密度高;相比之下 HdrHistogram 是固定精度的保真近似,t-digest 在动态范围与内存上都更灵活,但需要更多调参。

t-digest 的关键是"分位数精度优先于整体分布",牺牲中心区域的精度换取尾部分位数(P99/P99.9)的高精度,正好匹配长尾延迟分析场景。

#
★★★

5. CPI(cycles per instruction)从 1.0 升至 2.5,按 CPU 流水线停顿分类占比识别 cache miss、branch miss、依赖等待。

CPI(cycles per instruction)从 1.0 升至 2.5,如何按 CPU 流水线停顿分类占比识别 cache miss、branch miss、依赖等待?

  • CPI 的定义与含义
  • 流水线停顿的分类(cache miss、branch miss、依赖等待)
  • 用 perf 等工具定位

CPI 是平均每条指令所需时钟周期数,CPI 从 1.0 升到 2.5 说明平均每指令多花 1.5 个周期,通常由流水线停顿(stall)导致。停顿可分三类:cache miss——数据/指令不在缓存,需等待内存访问;branch miss——分支预测错误,需冲刷流水线重新取指;依赖等待——指令等待前序指令结果(数据冒险),无法乱序执行绕过。定位方法:用 perf stat 看 cache-misses、branch-misses;用 perf record 看 stalled-cycles-frontend/backend 或 Top-Down 分析(TMAM)区分 front-end 与 backend bound;用 perf annotate 看热点指令的停顿来源。

CPI 上升是结果,需定位"停顿在哪"才能对症下药。cache miss 指向数据布局/访存局部性,branch miss 指向分支预测模式,依赖等待指向长依赖链与 ILP(指令级并行)不足。

#
★★★

6. CPU governor(performance、schedutil、ondemand、powersave)的工程取舍。

CPU governor(performance、schedutil、ondemand、powersave)各有何工程取舍?

  • 各 governor 的频率调节策略
  • 性能与功耗的权衡
  • 云/容器场景的选型

CPU governor 决定 CPU 频率如何随负载变化。performance 将 CPU 固定在最高频率,省去调频延迟,延迟最低但功耗最大;powersave 固定在最低频率,省电但延迟高;ondemand 按负载阈值在高频和低频间跳变,响应快但可能频繁切换、调频抖动;schedutil 基于调度器负载(utilization)平滑调频,可预测且能感知 per-task 需求,多核/云环境更友好。工程取舍:延迟敏感服务用 performance 或 schedutil 保证稳态;节能场景用 powersave;容器/云上注意 CPU quota 与 governor 的交互,避免调频延迟放大尾部延迟。

频率切换本身有延迟(DVFS 开销),在低延迟场景可能放大 jitter。schedutil 由于其调度感知特性,在 Linux 4.7+ 成为现代默认,兼顾性能与功耗。

#
★★★

7. Cache line(64 字节)对齐对 struct 的影响,false sharing 的 perf c2c 验证。

Cache line(64 字节)对齐对 struct 有何影响?如何用 perf c2c 验证 false sharing?

  • cache line 与缓存一致性协议
  • false sharing 的成因与危害
  • perf c2c 的使用

缓存以 64 字节 cache line 为最小一致性单元。当两个线程各自修改位于同一 cache line 上但不相关的字段时,会触发缓存一致性协议(如 MESI)的缓存行失效与所有权转移,导致性能下降,即 false sharing。Struct 可通过对齐/填充(padding)让热点字段落在不同 cache line 上缓解。验证手段:perf c2c 专门检测 cache-to-cache 传输,可定位产生 false sharing 的地址与指令;观察高 cache miss 且命中同一 cache line 的读写指令。

false sharing 的本质是"假共享"——数据无逻辑共享,但因物理相邻而被迫一致性同步。用 aligned(64) 或 padding 让每个线程独占 cache line 是常见解法。

struct __attribute__((aligned(64))) counter_t {
    long a;   // 线程0 只写 a
    long b;   // 线程1 只写 b
};  // 若无对齐,a 与 b 可能同处一个 cache line 造成 false sharing
#
★★★

8. Hyper-Threading(SMT)下的资源竞争,port、cache line 的兄弟核争用如何发生。

Hyper-Threading(SMT)下,兄弟核(sibling core)在 port、cache line 等资源上如何竞争?

  • SMT 的物理实现(两个逻辑核共享执行单元)
  • 资源竞争类型(port、cache、前端)
  • 对性能隔离的影响

SMT 让一个物理核的两个逻辑线程共享执行单元(port、ALU、load/store 等)、L1/L2 缓存与前端取指。因此两个兄弟线程竞争:执行端口(port)——一个线程占用端口会延迟另一个线程的指令发射;cache line 与 TLB——共享 L1/L2 意味着缓存容量与带宽被平分,可能相互驱逐;前端与分支——共享解码与分支预测。这导致单线程时 SMT 提升吞吐(约 20-30%),但两个线程同时忙时单线程延迟可能劣化。工程上:对延迟敏感的关键任务可禁 SMT(nosmt)或用 CPU 亲和性隔离,或用 cpuset 保证独占。

SMT 是"吞吐换延迟"的权衡——提升物理核利用率的同时牺牲单线程确定性与隔离性。在混部/多租户场景,SMT 兄弟核的竞争可能放大尾部延迟。

#
★★★

9. IPC 降低但 CPU 占用率未满,可能瓶颈在 memory-bound(DRAM stall)还是 front-end bound(i-cache miss)。

IPC 降低但 CPU 占用率未满时,如何判断瓶颈在 memory-bound(DRAM stall)还是 front-end bound(i-cache miss)?

  • IPC 与 CPU 占用率的关系
  • DRAM stall 与 i-cache miss 的区别
  • Top-Down 分析的应用

IPC 降低意味着每周期完成的指令变少,而 CPU 占用率未满说明核心在等待而非忙于计算。瓶颈若是 memory-bound,则访存等待(DRAM stall)占主导,表现为 cache-misses 高、memory 带宽饱和、backend bound 占比高;若是 front-end bound,则取指/解码跟不上(i-cache miss、分支预测不佳),表现为 frontend bound 占比高、i-cache 缺失率高。用 perf stat 或 Top-Down(TMAM)四象限——Retiring、Bad Speculation、Frontend Bound、Backend Bound——可区分:Backend Bound 指向 memory/ALU,Frontend Bound 指向取指。

两者都是"CPU 空转"但对症不同:memory-bound 优化数据布局与访存局部性,front-end bound 优化代码体积、减少 i-cache miss(如内联、分支预测)。

#
★★★

10. L1/L2/LLC cache miss rate 的工程基线,典型业务的 hit rate 期望值与优化方向。

L1/L2/LLC cache miss rate 的工程基线是什么?典型业务的 hit rate 期望值与优化方向如何?

  • 各级缓存的典型 miss rate 基线
  • hit rate 的期望值
  • 优化方向

典型基线:L1 miss rate 约 5-10%(未命中会去 L2),L2 命中率约 90-95%,LLC(L3)命中率约 80-95%,涉及大量顺序/随机数据访问时 LLC miss 会升高。工程上,若 L1 miss 高说明热点数据频繁被替换,可优化数据布局(结构体 SoA、缓存友好遍历);若 LLC miss 高(working set 超出 LLC 容量)说明访问集大于缓存,需考虑分块、减少冷数据访问或加大工作集局部性。优化方向:数据对齐、减少间接访问、提高空间局部性、使用预取。

hit rate 是相对值,取决于业务 working set 大小与访问模式。关键是"命中率 + 访问总量"共同决定实际内存带宽压力,不能只看比率。

#
★★★

11. SIMD 指令(AVX2、AVX-512、NEON)的吞吐收益与频率下降的功耗墙。

SIMD 指令(AVX2、AVX-512、NEON)的吞吐收益与频率下降的功耗墙如何权衡?

  • SIMD 的并行吞吐收益
  • AVX-512 的频率下降(功耗墙/Throttling)
  • 工程取舍

SIMD 通过单指令多数据提升吞吐——AVX2 一次处理 256 位(4 个 64 位或 8 个 32 位),AVX-512 一次 512 位,NEON 128 位。但 AVX-512 等宽指令会显著提高功耗与温度,导致 CPU 因功耗墙(power wall)自动降频(DVFS throttling),尤其在全核 AVX-512 负载时频率下降明显,可能使串行部分反而变慢。工程取舍:在计算密集型且可向量化的场景(矩阵、编解码、加密)用 AVX-512 收益大;但要注意重负载下频率下降,需评估"每核吞吐×并发"的净收益,必要时限制 AVX-512 频率或仅在关键路径启用。

这是"峰值吞吐 vs 持续功耗"的权衡。降频是 CPU 保护机制,可能抵消 SIMD 并行收益,因此要实测实际吞吐而非只看指令宽度。

#
★★★

12. perf stat 的关键计数器,cycles、instructions、cache-misses、branch-misses、page-faults 的协同解读。

perf stat 的关键计数器(cycles、instructions、cache-misses、branch-misses、page-faults)如何协同解读?

  • 各计数器的含义
  • 相互推算(CPI、IPC、miss 率)
  • 综合诊断

各计数器含义:cycles 为总周期数,instructions 为执行指令数,二者之比即 CPI(或倒数为 IPC);cache-misses 为缓存未命中次数,可结合 cache-references 算 miss 率;branch-misses 为分支预测错误次数,结合 branch 算误预测率;page-faults 为缺页次数(区分 major/minor)。协同解读:CPI 高时看 cache-misses 判断是否 memory-bound;branch-misses 高说明分支预测差,可用无分支优化;page-faults 高说明内存/工作集问题,可能触发 swap 或冷加载。IPC 偏低 + cache-misses 高 → 内存瓶颈;IPC 低 + branch-misses 高 → 分支预测问题。

单一计数器意义有限,需多指标联动。perf stat 提供的是"静态快照",综合 IPC、miss 率、fault 数可快速缩小问题范围,再配合 perf record 深入。

#
★★★

13. Linux page cache 的回收策略,LRU、2Q、ARC 的工程取舍。

Linux page cache 的回收策略(LRU、2Q、ARC)有何工程取舍?

  • page cache 回收机制
  • LRU 的缺陷与 2Q/ARC 的改进
  • Linux 实际使用的策略

Linux page cache 采用基于 LRU 的双链表(active + inactive 两个列表)近似实现,并区分 file 与 anonymous 页。纯 LRU 有扫描污染(scan pollution)问题:一次性顺序读会污染 LRU 把热页挤出。2Q(Two Queue)通过一个小的 A1in 入队队列 + 较大的 A1out 淘汰队列 + Am 主队列区分"仅访问一次"与"频繁访问"列表;ARC(Adaptive Replacement Cache)自适应地在最近访问与频繁访问两段间分配容量,兼顾扫描与复用。Linux 实际使用可调参数(vm.swappiness、vmscan 的 inactive/active 比例)近似 2Q/ARC 思想。

核心是"区分热页与冷扫描页"。Linux 用双链表 + 比例调节实现类似效果,但不如 ARC 精确自适应;生产上常通过调 active/inactive 比例与 swappiness 优化。

#
★★★

14. OOM killer 的 oom_score 计算与进程选择,MySQL 容器被杀的常见原因。

OOM killer 的 oom_score 如何计算?如何选择被杀的进程?MySQL 容器被杀的常见原因是什么?

  • oom_score / oom_score_adj
  • 进程选择逻辑
  • MySQL 容器被 OOM 的常见原因与对策

Linux OOM killer 在内存耗尽时按 oom_score 选择被杀进程,oom_score 基于进程内存占用(RSS + swap 等)与 oom_score_adj(可调,范围 -1000 到 1000,越大越先被杀)。系统优先杀掉占用内存大、优先级低(adj 高)的进程。MySQL 容器被杀的常见原因:容器内存配额过小,innodb_buffer_pool_size 设置过大超过容器内存上限,导致 cgroup 内存耗尽触发 OOM;或 page cache 与进程内存争抢导致内存压力。对策:合理设置 buffer pool 与容器配额、设置 oom_score_adj 保护关键进程、预留内存余量、监控 cgroup 内存使用。

容器内 OOM 是"限额内内存耗尽"而非整机耗尽,MySQL 的 buffer pool 常占内存大头,若与 cgroup 上限不匹配极易 OOM。可通过 memory.max 监控与 buffer pool 调优预防。

#
★★★

15. major page fault 与 minor page fault 的工程差异,磁盘 I/O vs 仅页表分配如何对比。

major page fault 与 minor page fault 的工程差异是什么?

  • 两者定义与触发条件
  • 磁盘 I/O vs 页表分配的开销差异
  • 观测与优化

minor page fault 指页已在内存(如 page cache 或共享页),但当前进程页表未映射,只需分配页表项建立映射,无需磁盘 I/O,开销很小(μs 级);major page fault 指页不在内存,需从磁盘/swap 读入,涉及磁盘 I/O(ms 级),开销大。工程上:major fault 高说明冷加载或 swap 频繁,会显著放大延迟;minor fault 高多为内存映射(mmap)页表首次访问,相对无害。可用 perf stat 的 page-faults 与 major/minor 区分,/proc/pid/status 的 VmPeak 等观察。

关键区别是"是否触发磁盘 I/O"。major fault 是性能杀手,应通过预热、加大内存、避免 swap 缓解;minor fault 是页表管理的正常成本。

#
★★★

16. 吞吐未饱和但延迟升高,可能瓶颈在 working set 超出 cache、memory pressure、swap 还是 NUMA remote。

吞吐未饱和但延迟升高,最可能的瓶颈是什么?如何区分 working set 超出 cache、memory pressure、swap 还是 NUMA remote?

  • 吞吐正常但延迟升高的原因
  • 各类内存瓶颈的特征
  • 定位手段

吞吐未饱和(CPU/IO 未满)但延迟升高,说明瓶颈在"等待"而非"忙碌",常见于内存相关:working set 超出 cache——LLC miss 升高,访问落入主存;memory pressure——内存紧张触发回收/压缩(compaction)与更频繁分配;swap——内存不足导致页换出,访问触发 major fault;NUMA remote——访问本地 NUMA 节点的远端内存,跨 NUMA 访问延迟远高于本地。区分方法:用 perf stat 看 LLC miss 与 major/minor fault;用 numastat 看跨 NUMA 访问;用 vmstat 看 si/so(swap in/out)与 memory pressure;用 cgroup 内存指标看压力。

"吞吐未满但延迟升"典型是"等待资源"而非"计算饱和"。需逐项排查 cache 容量、内存压力、swap 与 NUMA 拓扑,定位等待来源。

#
★★★

17. DNS 解析慢的工程定位,resolver 配置、TTL、DoH/DoT 的安全与性能。

DNS 解析慢的工程定位思路是什么?resolver 配置、TTL、DoH/DoT 的安全与性能如何权衡?

  • DNS 解析慢的定位步骤
  • resolver 配置与 TTL 的影响
  • DoH/DoT 的安全与性能

DNS 解析慢定位:先看解析耗时(dig 或 nslookup 计时),再看 resolver 配置(/etc/resolv.conf 的 nameserver 顺序、超时、重试),检查是否频繁全量查询(TTL 过短导致缓存失效)、上游递归服务器慢、UDP 被丢弃、或解析了过多的域名层次。TTL 决定缓存时长,过短增加上游查询,过长则更新不实时。DoH/DoT 加密 DNS 查询(防劫持/窥探),但增加 TLS 握手与加密开销,且 DoH 因走 HTTP 有额外解码开销;工程上对内网 DNS 常用明文缓存,对外敏感场景用 DoT/DoH 并缓存。

慢定位的关键是"内网解析 vs 外网解析"与"缓存命中率"。TTL 与 resolver 超时是最大可调因素,DoH/DoT 以安全换性能,需按场景取舍。

#
★★★

18. HTTP 慢请求拆解,DNS(5-50ms)→ TCP connect(10-100ms)→ TLS 握手(50-200ms)→ TTFB(50-500ms)→ content download 的耗时定位。

HTTP 慢请求如何拆解定位?每阶段(DNS、TCP connect、TLS 握手、TTFB、content download)的典型耗时范围是多少?

  • 各阶段耗时范围
  • 拆解工具(浏览器 DevTools、curl、Wireshark)
  • 阶段定位与优化

一个 HTTP 请求可拆分为:DNS 解析(5-50ms,若缓存命中则近 0)、TCP connect(10-100ms,含 RTT)、TLS 握手(50-200ms,1-2 个 RTT + 加密)、TTFB(50-500ms,服务端处理 + 首字节返回)、content download(取决于带宽与文件大小)。定位:用 curl -w 查看各阶段计时(time_namelookup、time_connect、time_appconnect、time_starttransfer)、浏览器 DevTools 的 Timing 面板、Wireshark 抓包。优化:DNS 用缓存/预解析、TCP 用 keep-alive 复用、TLS 用 session resumption 与 HTTP/2 多路复用、TTFB 用服务端优化与 CDN。

"慢请求"不是单一问题,而是多阶段叠加。分别量化各阶段耗时,才能定位瓶颈在客户端、网络还是服务端。

#
★★★

19. QUIC(HTTP/3)的连接建立,0-RTT、1-RTT 与 TCP+TLS 1.3 的对比。

QUIC(HTTP/3)的连接建立中,0-RTT、1-RTT 与 TCP+TLS 1.3 有何对比?

  • QUIC 的握手模式
  • 与 TCP+TLS 1.3 的 RTT 对比
  • 0-RTT 的重放风险

QUIC 基于 UDP 把传输与加密合并在用户态,握手用 TLS 1.3:首次连接 1-RTT 完成握手(1 个往返建立连接+加密),对已握手过的客户端可用 0-RTT 恢复(发送首包即可携带数据,减少 1 个 RTT)。对比 TCP+TLS 1.3:TCP 握手 1-RTT + TLS 1.3 握手 1-RTT = 至少 2-RTT 才能发首字节,QUIC 最低 1-RTT(首次)或 0-RTT(恢复)。且 QUIC 无队头阻塞、连接迁移(网络切换不断连)。0-RTT 存在重放攻击风险(重放已加密的早期数据),需服务端幂等处理。

QUIC 的收益是减少握手 RTT 与消除队头阻塞,尤其适合弱网/移动网络。0-RTT 用安全性(重放)换延迟,需权衡。

#
★★★

20. TCP slow start 与 cwnd(congestion window)的初始拥塞,cwnd=10 vs IW10 的对比。

TCP slow start 与 cwnd(congestion window)的初始拥塞如何理解?cwnd=10 与 IW10 有何区别?

  • slow start 机制
  • 初始拥塞窗口(IW)
  • cwnd=10 与 IW10 的对比

TCP slow start 在连接初期以指数增长 cwnd(每 RTT 翻倍),避免一开始就注入过量数据导致拥塞。初始拥塞窗口(IW)决定首轮可发送的报文数,RFC 6928 建议 IW=10(约 10 个 MSS,约 14KB),即"cwnd=10"通常指初始窗口为 10 个 MSS。较小的 IW 在长 RTT 高带宽路径上会拖慢启动(需更多 RTT 才达到满带宽),较大的 IW 加速启动但可能加剧网络拥塞。工程上:现代内核默认 IW10,CDN/边缘可适度加大 IW 提升短连接性能,但需考虑拥塞风险。

cwnd 从初始值按 slow start 增长,直到检测到丢包/达到 ssthresh 进入拥塞避免。IW 大小是"启动速度 vs 拥塞风险"的权衡。

#
★★★

21. mTLS 握手延迟,证书链大小(KB 级)、OCSP stapling、session resumption 的工程优化。

mTLS 握手延迟如何优化?证书链大小、OCSP stapling、session resumption 各有哪些工程手段?

  • mTLS 握手延迟的组成
  • 证书链大小的优化
  • OCSP stapling 与 session resumption

mTLS 双向 TLS 要求双方都验证证书,握手延迟由证书链大小(传输 + 验证)、OCSP 检查、椭圆曲线运算等决定。优化手段:证书链瘦身——精简中间证书、避免巨型链,减少握手传输字节;OCSP stapling——服务器把 OCSP 响应缓存进握手扩展,避免客户端在线查询 OCSP 服务器(额外 RTT);session resumption——用 TLS session ticket 或 session ID 复用已建立的会话,跳过完整握手,降低到 1-RTT 甚至 0-RTT。工程上常配合连接复用(keep-alive)与连接池减少握手频率。

mTLS 高频握手是服务间调用的延迟大头。核心是"减少握手次数"(复用)与"减少单次握手成本"(证书瘦身、OCSP stapling、resumption)。

#
★★★

22. tcpdump 与 Wireshark 的 HTTP/2、gRPC 解析,header compression、HPACK 索引如何处理。

tcpdump 与 Wireshark 如何解析 HTTP/2、gRPC?header compression 与 HPACK 索引如何影响抓包?

  • Wireshark 对 HTTP/2、gRPC 的解析
  • HPACK 头部压缩原理
  • 抓包时如何正确解码

Wireshark 能识别 HTTP/2 帧(DATA、HEADERS、SETTINGS 等)与 gRPC(基于 HTTP/2 的二进制协议,可解析其 message 与 status)。HTTP/2 用 HPACK 压缩头部:静态表(预定义常用头)+ 动态表(连接内维护的索引)+ 霍夫曼编码。抓包时若使用 TLS 需配置解密密钥(key log file)才能看到明文 HTTP/2;动态表依赖连接上下文,若从连接中途开始抓包,可能无法解码依赖动态表索引的头部(需完整连接或禁用动态表)。gRPC 解析依赖 HTTP/2 正确解码,PROTOBUF 消息可能需要 proto 定义才能反序列化。

抓包层面的难点是"加密 + 头部压缩的有状态性"。理解 HPACK 动态表与 TLS 解密是正确解码 HTTP/2/gRPC 的前提。

#
★★★

23. Off-CPU 分析,阻塞在锁、I/O、调度上的时间占比。

Off-CPU 分析如何量化线程阻塞在锁、I/O、调度上的时间占比?

  • Off-CPU 分析的概念
  • 阻塞类型(锁、I/O、调度)
  • 工具(offcputime、bpftrace)

On-CPU 分析看线程在 CPU 上执行的时间,Off-CPU 分析看线程被阻塞(不在 CPU)的时间,二者互补。线程阻塞主要有:锁等待(mutex/condvar 争用)、I/O 等待(磁盘、网络、同步 I/O)、调度延迟(runqueue 排队、被抢占)。工具:bcc 的 offcputime 用 tracepoint 记录线程睡眠点与时长,bpftrace 的 offcputime 脚本可聚合出各阻塞点(如 futex、block_rq)的累计时间与占比。通过 off-CPU 分布可定位"线程卡在哪"——是不是锁竞争、I/O 慢还是排队。

吞吐未满但 CPU 占用低时,off-CPU 分析是核心手段——它定位"等待"而非"执行"。区分锁、I/O、调度三类阻塞,对症优化(减少锁、异步 I/O、调优调度)。

#
★★★

24. 火焰图(Flame Graph)的解读,宽度=CPU 时间、深度=调用栈。

火焰图(Flame Graph)如何解读?宽度与深度分别代表什么?

  • 火焰图的结构(x 轴宽度、y 轴深度)
  • 读取方法(找宽平顶、看栈深)
  • 与 off-CPU 火焰图的区别

火焰图 x 轴表示采样的累积时间(宽度=CPU 时间占比),y 轴表示调用栈深度(自底向上为调用顺序,自顶向下为当前函数)。顶部是采样时正在执行的函数,越宽说明占用 CPU 越多。读取方法:找顶部"宽平顶"(hot function)——即 CPU 热点;看栈——热点函数所属的调用链,判断瓶颈来源。注意火焰图是"当前执行"采样,栈浅的宽函数说明该函数自身重,栈深且每层都宽说明整条链开销大。另有 off-CPU 火焰图展示阻塞时间分布。

火焰图是 on-CPU 时间分布的可视化,"宽"是热点信号,"深"是调用链信息。正确解读需结合"顶部宽度"与"调用链"定位真正开销。

#
★★★

25. Bimodal latency 业务的告警策略,双窗口监控与告警分级。

Bimodal latency 业务如何设计告警策略?双窗口监控与告警分级如何实现?

  • 双峰延迟对告警的挑战
  • 双窗口监控的思路
  • 告警分级

双峰延迟业务中,平均值/整体 P99 可能被次峰掩盖,单一阈值告警易误报或漏报。双窗口监控:用"短窗口"(如 1 分钟)捕捉瞬时尖峰(次峰),用"长窗口"(如 10 分钟)评估趋势与基线,二者结合可区分"偶发尖峰(可接受)"与"持续劣化(需告警)"。告警分级:按严重程度分级——P1(服务不可用,P99 长时间超线)、P2(性能劣化,次峰占比上升)、P3(轻微抖动,无需立即处理)。结合 baselining(相对历史基线而非固定阈值)与多分位数(P50/P99/P99.9)联合监控,避免单点误判。

双峰延迟最大的坑是"平均值掩盖 tail"。双窗口 + 分级 + 多分位数 + 基线,才能既捕捉真实劣化又不被偶发抖动淹没。

#
★★★

26. P99 与平均值的差异成因,尾延迟放大(tail latency amplification)在多服务调用链的传递规律。

P99 与平均值为何差异大?尾延迟放大(tail latency amplification)在多服务调用链中如何传递?

  • 平均值与 P99 的差异成因
  • 尾延迟放大机制
  • 长尾抑制策略

平均值对偶发大延迟不敏感,P99 反映了 1% 最慢请求的延迟,当分布右偏(存在长尾)时二者差异显著。尾延迟放大指在多服务串行调用链上,若每跳的 P99 延迟为 L,则整链 P99 会显著大于各跳 P99 之和——因为各跳的极端延迟会叠加(尾概率相乘)。例如 5 跳、每跳 P99=100ms,整链 P99 可能达到数百 ms。抑制策略:Hedged requests(向多个副本发冗余请求取最快)、超时与重试控制、请求压缩、把慢路径降级、用短路/缓存剔除慢调用。

尾延迟放大是"概率相乘"的数学结果——串行链上多个分位数的极端值叠加。这也是为什么分布式系统要控制每跳的 P99 与调用链深度。

#
★★

27. 对数正态分布(log-normal)拟合响应时间的工程方法,μ、σ 参数估计与 P95/P99/P99.9 计算。

如何用对数正态分布(log-normal)拟合响应时间?μ、σ 参数如何估计?P95/P99/P99.9 如何计算?

  • 对数正态分布模型
  • μ、σ 参数估计
  • P95/P99/P99.9 计算

对数正态分布(log-normal)适合拟合响应时间(右偏、非负、长尾)。若 X 服从对数正态,则 ln X 服从正态分布 N(μ, σ²)。参数估计:对采样值取对数后求均值(μ = E[ln X])与标准差(σ = std[ln X])。分位数计算:P_p = exp(μ + σ·z_p),其中 z_p 是标准正态分位(P95 对应 z≈1.645,P99 对应 z≈2.326,P99.9 对应 z≈3.09)。工程上:用对数正态拟合响应时间分布,可外推高尾分位数(P99.9)评估 SLO,比直接经验分位数更平滑、抗噪。注意:样本量需足够,且实际分布可能混合(多峰),需结合直方图验证拟合质量。

对数正态取对数后变正态,用 μ、σ 描述形状。分位数用 exp(μ+σz) 计算,z 取标准正态分位,故 P99.9 明显高于 P99 反映长尾。

#
★★

28. 平均响应时间不变但 P99 突然飙升,最可能的三种根因与各自的可观测信号。

平均响应时间不变但 P99 突然飙升,最可能的三种根因是什么?各自的可观测信号是什么?

  • 平均不变但 tail 恶化的根因
  • 各类根因的观测信号
  • 用时长直方图/分位数而非平均值暴露少数极端请求

三种常见根因:(1) 少量请求被"慢路径"拖累——如某类大请求、冷缓存、GC pause、锁竞争,只影响少数请求,P99 飙升而平均不变;观测信号:慢请求的调用链/trace、GC 日志、锁等待统计。(2) 尾部资源(某连接、某线程、某分片)热度过载——热键/热分片延迟高,其余正常;观测信号:分片/实例级延迟分布、热点 key。(3) 偶发阻塞/抖动——如 CPU steal、网络丢包重传、磁盘 I/O 抖动,只影响短暂窗口;观测信号:CPU steal 指标、网络重传、磁盘 await 尖峰。三者共同点:影响少数请求但影响大,导致分布右尾被拉长。

"平均不变、P99 飙升"说明是"少数极端",用时长/频率分桶(histogram)比平均值更能暴露。需结合 trace 与基础设施指标定位慢路径来源。

#
★★

29. 用 Little 定律(L = λW)计算最优并发数,若 p99 服务时间从 50ms 升至 200ms 而到达率不变,最大并发如何变化。

用 Little 定律(L = λW)计算最优并发数:若 p99 服务时间从 50ms 升至 200ms 而到达率不变,最大并发如何变化?

  • Little 定律 L = λW
  • 服务时间与并发的关系
  • 容量规划

Little 定律 L = λW 表示在稳定系统中,系统内平均请求数 L = 到达率 λ × 平均服务时间 W。若到达率 λ 不变,而服务时间 W 从 50ms 升到 200ms(4 倍),则系统内平均请求数 L 也变为 4 倍。这意味着维持相同到达率所需"在途/并发"请求数变为 4 倍,若并发数(连接池/线程池)不增加,则会出现排队或超时;若想让系统不积压,需将并发容量提升到原来的 4 倍。因此"最优并发数"应随服务时间线性增长(L=λW)。

服务时间延长直接放大所需并发。容量规划时既要看吞吐(λ)也要看服务时间(W),二者乘积决定稳态并发需求。

#
★★

30. 给定平均稳定而 p99 恶化,依次追踪平均值、分位数、排队、Little 定律、服务时间与并发,找出首个失败点。

给定平均稳定而 p99 恶化,如何依次追踪平均值、分位数、排队、Little 定律、服务时间与并发,找出首个失败点?

  • 系统化诊断流程
  • 各指标的关系
  • 定位首个异常点

诊断流程:先看平均值(稳定)确认整体吞吐未劣化;再看分位数(P50/P99/P99.9)确认 tail 恶化到哪一档;看排队——队列深度/等待时间是否上升(若排队上升则是过载/服务时间延长);用 Little 定律校验——若 λ 稳定而 W 上升(服务时间延长),则 L 上升,并发需求上升;若并发已达上限(连接池/线程池满)则排队加剧,形成首个失败点。首个失败点通常是"服务时间延长导致并发耗尽→排队→tail 恶化",而排队进一步放大 tail。需从服务时间(下游慢/GC/锁)与并发上限两个方向定位。

这是"从现象到根因"的漏斗:平均值→分位数定位"tail 恶化",排队与 Little 定律定位"是否过载",服务时间与并发定位"瓶颈在哪"。首个失败点是可用性恶化发生的起点。

#
★★

31. 长尾延迟与 SLA 的差异,SLO 设定的 P99.9 vs 平均值陷阱。

长尾延迟与 SLA 有何差异?SLO 设定 P99.9 相比平均值有何陷阱?

  • SLA/SLO 的概念
  • P99.9 与平均值作为 SLO 的差异
  • 平均值陷阱

SLA(服务等级协议)是外部承诺,SLO(服务等级目标)是内部度量目标。用 P99.9 作为 SLO 反映"最慢请求也能达标",但陷阱是:P99.9 对极端长尾敏感,且单次尖峰就可能破 SLO(分位数对异常值敏感);同时 P99.9 只保证 99.9% 以内,最坏 0.1% 完全不受控,可能造成不可接受的极端延迟。平均值陷阱:平均值被大多数请求拉平,掩盖了长尾,用平均值定 SLO 会让"大面积慢请求"被掩盖,业务实际体验差。工程上常多分位数 + 预算(error budget)组合,区分"影响范围"与"严重程度"。

平均值掩盖分布,P99.9 只约束分位。好的 SLO 用多分位数 + 时间窗口(如 30 天内 P99.9 < 100ms)+ 错误预算,兼顾可知性与可操作性。

#
★★

32. Intel PT(Processor Trace)指令级追踪,相比 perf 的开销与精度差异。

Intel PT(Processor Trace)指令级追踪相比 perf 有何开销与精度差异?

  • Intel PT 的原理
  • 与 perf 采样的差异
  • 适用场景

Intel PT 是硬件级指令追踪,通过 CPU 内嵌的 Trace 单元记录每条指令的执行路径(用压缩的包流编码,含分支、时序),精度极高(指令级、周期级),可还原完整执行流。相比 perf 的事件采样(按周期采样少数点,开销低但只覆盖采到的点),Intel PT 开销相对更高(持续记录大量 trace 数据,需专门解码,内存/带宽开销大),但能给出确定性的执行轨迹,适合定位"为什么走到这条路径"、崩溃复现、安全取证等。perf 便宜(采样)但统计性,Intel PT 昂贵(全量)但确定性。

这是"采样 vs 全量追踪"的权衡。perf 统计定位热点,Intel PT 精确还原执行路径;Intel PT 数据量大,通常只对短窗口/关键路径启用。

#
★★

33. perf record -g 的调用栈采样,频率(frequency)与采样周期的工程取舍。

perf record -g 的调用栈采样中,频率(frequency)与采样周期如何取舍?

  • -g 调用栈采样
  • 采样频率与周期
  • 开销与精度权衡

perf record -g 以固定频率(默认约 1000Hz,可用 -F 调整)周期性采样调用栈,得到 CPU 时间分布。采样周期(间隔)决定精度与开销:频率高(如 -F 999)采样点密,统计更准,但开销与数据量大(尤其是热点栈深);频率低则开销小但可能漏掉短生命周期热点。取舍原则:在用中等频率(-F 999),长时间采样用更低频率;采样频率应低于事件率(避免饱和),且用 -F 指定而非依赖默认;对栈深大的应用注意停止开销。频率与采样周期互为倒数,本质是"精度 vs 开销"。

采样是统计估计,精度随样本量提升。现代 CPU 用周期采样(每 N 个周期采一次)而非固定时间,可减少频率偏差。工程上从 -F 999 起步,结合数据量调整。

#
★★

34. Dirty page 写回策略,dirty_ratio、dirty_background_ratio 与 writeback 的延迟。

Dirty page 写回策略如何影响延迟?dirty_ratio、dirty_background_ratio 与 writeback 的关系是什么?

  • dirty page 写回机制
  • dirty_ratio 与 dirty_background_ratio 的区别
  • 对延迟的影响

Linux 把脏页先缓存在内存,后台由 writeback 线程异步刷盘。dirty_background_ratio 是脏页占内存比例达到时触发后台 writeback(异步,不阻塞应用);dirty_ratio 是硬上限,达到时应用进程要同步写回(阻塞,latency 突增)。工程上:dirty_background_ratio 设小些(如 5-10%)可提前异步刷盘,避免脏页积累到 dirty_ratio 触发同步阻塞;但设太小会增加刷盘频率与 I/O 开销。持久化/延迟敏感场景要控制脏页积累,避免周期性写回尖峰。

关键是把"后台异步刷"与"前台同步阻塞"的分界控制到脏页上限。控制脏页水平能在吞吐与延迟间平衡,避免突发同步写。

#
★★

35. "已知未知"(Known-Unknowns)vs"未知未知"(Unknown-Unknowns)的可观测策略。

"已知未知"(Known-Unknowns)vs"未知未知"(Unknown-Unknowns)在可观测性上有何策略差异?

  • 两类不确定性的概念
  • 可观测性设计
  • 主动探索 vs 被动发现

Known-Unknowns 是"知道存在但不知道具体值"的问题,如"某接口延迟可能升高但不知道何时",可通过预设的指标、trace、告警来覆盖(已知需要监控的维度);Unknown-Unknowns 是"完全想不到的问题"——新型故障、未知依赖、未建模的路径,无法靠预设指标覆盖。策略:对 Known-Unknowns 用"预设可观测性"(指标采样、trace、结构化日志、告警基线),持续测量已知维度;对 Unknown-Unknowns 用"高保真采样 + 深度分析能力"(全链路 trace、on/off-CPU、profiling、审计日志),在故障时能回溯/深挖,而不是依赖预设告警。可观测性既要"已知维度的监控"也要"未知维度的可回溯资产"。

可观测性设计要覆盖"已知"用预设指标,覆盖"未知"用可回溯的原始数据(trace、日志、profile)。只有预设告警无法应对未知故障。

#
★★

36. Continuous Profiling(持续剖析)的工程价值,Always-on vs Sampled 的取舍。

Continuous Profiling(持续剖析)的工程价值是什么?Always-on 与 Sampled 如何取舍?

  • 持续剖析的概念
  • Always-on 与 Sampled 的差异
  • 工程取舍

Continuous Profiling(持续剖析)在生产环境持续运行 profiling,采集 CPU、内存、锁等画像,形成时间序列,可回溯到过去任意时刻的调用栈热点,用于"事后定位"(如发布后性能回归、偶发尖峰)而无需现场复现。Always-on 持续全量/高频采样,覆盖最全、时间分辨率高,但开销(CPU、存储、带宽)大;Sampled 按周期性/概率抽样(如每 N 秒采一次),开销可控但可能漏掉短窗口热点。取舍:对关键服务用较高采样率(Always-on 但降频),对非关键服务用低频采样;结合"按需开大"(故障时临时提高采样率)平衡成本与覆盖。

持续剖析的价值在于"时间维度"——能回溯历史,这是传统按需 profiling 无法做到的。Always-on 与 Sampled 是"覆盖度 vs 开销"的权衡。

#
★★

37. 三种可观测支柱的工程价值,Logs(debug)、Metrics(趋势)、Traces(链路)的协同。

三种可观测支柱(Logs、Metrics、Traces)各自的工程价值是什么?如何协同?

  • 三支柱的定义与价值
  • 各自适用场景
  • 协同(correlation)

可观测性三支柱:Logs(日志)——结构化事件记录,用于 debug 具体请求的执行细节(错误、参数、状态),粒度最细但量大、无统一维度;Metrics(指标)——数值聚合(计数、直方图、速率),用于趋势、告警、容量,量化但不是逐请求;Traces(链路)——单请求跨服务/跨调用的完整路径与耗时,用于分布式定位,有 traceID 关联。协同:用 Metrics 发现异常(告警)→ 用 Traces 定位到具体请求/调用链 → 用 Logs 深挖该请求细节。三者通过 traceID/requestID 关联,形成"指标发现→链路定位→日志深挖"的闭环。

三支柱各有粒度与用途,协同才能高效排障。现代实践也强调"trace 驱动的日志关联"与高基数 trace 补全 metric 的不足。

#
★★

38. 指标 cardinality(基数)的爆炸,tag 过多导致的存储压力。

指标 cardinality(基数)的爆炸如何产生?tag 过多导致哪些存储压力?

  • cardinality 的概念
  • tag 高基数的影响
  • 治理手段

指标 cardinality 指一个指标(metric)的取值空间,由 tag/label 组合决定。例如一个指标带 user_id、request_id、instance 等 tag 各上百取值,组合爆炸导致形成海量时间序列。存储压力:每个唯一标签组合对应一条时间序列,高基数使时序数据库(Prometheus 等)内存与磁盘占用指数增长,查询变慢,成本飙升。治理:限制 tag 数量、对高基数 tag(如 request_id)改放 trace 而非 metric、用降采样聚合、合理设置 retention 与采集频率。

高基数是大忌——把"每个唯一值"当指标序列存储会爆炸。应把高基数维度(请求级)放 trace/logs,指标只保留低基数聚合维度。

#
★★

39. "client-perceived latency"与"server-side latency"的差异,网络 RTT 的贡献拆分。

"client-perceived latency"与"server-side latency"有何差异?网络 RTT 的贡献如何拆分?

  • 两种延迟口径
  • 网络 RTT 的组成
  • 定位客户端 vs 服务端

client-perceived latency 是客户端从发请求到收到完整响应的总时长,server-side latency 是服务端处理请求的时间(从收到请求到返回响应)。二者差即网络往返与传输开销(RTT + 序列化 + 排队)。网络 RTT 由传输延迟、传播延迟、处理延迟、排队延迟组成;客户端感知延迟 = 上行 RTT + 服务端处理 + 下行传输 + 应用层处理。拆分方法:用 curl -w 计时(time_namelookup/connect/appconnect/starttransfer/total)、服务端日志记录处理时间、抓包对比。若 client-perceived 远大于 server-side,说明网络/RTT 或中间链路是瓶颈;若 server-side 本身就大,则服务端优化。

关键是把"口径差异"拆开——把总延迟分成"客户端开销 + 网络 + 服务端",才能定位到底是网络还是服务端。网络 RTT 在跨地域/弱网下占比大。

#
★★

40. CoDel(Controlled Delay)算法如何用 sojourn time 反推队列长度并触发 drop,与传统尾部丢弃的差异。

CoDel(Controlled Delay)算法如何用 sojourn time 反推队列长度并触发 drop?与传统尾部丢弃有何差异?

  • CoDel 的核心思想
  • sojourn time 与队列长度
  • 与 tail drop 的对比

CoDel 用"sojourn time"(数据包在缓冲区停留的时间,即排队延迟)作为队列拥塞的代理指标,而非直接看队列长度。它维护最小 sojourn time(在窗口内),若 min sojourn 超过目标延迟(如 5ms)且持续超过一个周期,则判定队列拥塞,开始丢弃/标记包,使发送端(TCP)感知拥塞削减速。与传统 tail drop(队尾丢弃)相比:tail drop 在队列满时丢弃,会造成"global synchronization"(所有 TCP 同时丢包退避,吞吐波动)与 buffer bloat(队列长期积压,延迟高);CoDel 主动基于延迟而非缓冲长度丢包,保持队列短、延迟低,且用 ECN 可标记而非丢包。

CoDel 的价值是"延迟感知而非队列长度感知"——它尽早控制队列,避免 buffer bloat 与同步退避。fq_codel 结合公平排队是其主流实现。

#
★★

41. Throughput-latency curve 的"膝盖点"(knee point)识别,服务端容量规划的拐点定位。

Throughput-latency curve 的"膝盖点"(knee point)如何识别?它对服务端容量规划有何意义?

  • throughput-latency 曲线
  • knee point 的物理意义
  • 容量规划应用

Throughput-latency curve 显示随并发/负载上升,吞吐先升、到某点后增平缓,而延迟在附近开始急剧上升,该拐点即"膝盖点"(knee point)。膝盖点之前系统接近线性、延迟低;越过膝盖点,系统进入饱和(排队加剧),延迟急剧恶化而吞吐几乎不再增长。容量规划:应以膝盖点作为工作上限,留出余量——即"工作在膝盖点左侧但尽量接近",兼顾吞吐与延迟。识别方法:压测(load test)逐步加压,绘制吞吐-延迟曲线,找延迟开始陡增/吞吐增长停滞的拐点。

膝盖点是"吞吐-延迟平衡"的临界,容量规划应避免进入膝盖点右侧的饱和区,否则延迟爆炸而吞吐不增。用压测找拐点,设安全余量。

#
★★

42. tail latency 抖动(jitter)在音视频通话的影响与 FEC/ARQ 的工程补偿。

tail latency 抖动(jitter)在音视频通话中有何影响?FEC/ARQ 如何工程补偿?

  • jitter 对实时媒体的影响
  • FEC(前向纠错)与 ARQ(自动重传)
  • 补偿策略

音视频通话对延迟极其敏感,jitter(抖动,即延迟的波动)会导致抖动缓冲(jitter buffer)涨跌、播放卡顿、音画不同步、往返延迟增大。补偿手段:FEC(前向纠错)——发送端附加冗余数据,接收端无需重传即可恢复损失的包,牺牲带宽换即时恢复,适合丢包率低但要求低延迟的场景;ARQ(自动重传)——接收端检测丢包后请求重传,节省带宽但引入额外 RTT,适合丢包偶发、延迟容忍稍高的场景。工程上常结合:丢包率高时用 FEC,加上 jitter buffer 自适应、码率自适应与丢包隐掩藏(PLC),权衡延迟与画质。

实时媒体是"延迟与丢包"的权衡。FEC 用带宽换延迟,ARQ 用延迟换带宽,jitter buffer 吸收抖动,需按实际丢包率与 RTT 自适应。

#
★★

43. 用 M/M/1 队列模型计算利用率 ρ 与平均等待时间的关系,说明 ρ→1 时的相变(phase transition)。

用 M/M/1 队列模型,利用率 ρ 与平均等待时间的关系如何?ρ→1 时发生什么相变?

  • M/M/1 模型
  • 利用率 ρ 与等待时间
  • ρ→1 的相变

M/M/1 模型(泊松到达、指数服务、单服务台)中,利用率 ρ = λ/μ(到达率/服务率)。平均系统内请求数 L = ρ/(1-ρ),平均等待时间 W = 1/(μ(1-ρ))。当 ρ→1 时,1-ρ→0,L 和 W 都趋于无穷大——即"相变":系统从稳定(queue 有限)过渡到不稳定(队列无限增长),这是排队理论的核心临界点。工程意义:利用率达到 80-90% 以上时,等待时间开始以非线性方式急剧上升,所以容量规划应把利用率控制在较低水平(如 <80%),避免接近 ρ=1 的饱和区。

M/M/1 揭示了"接近饱和时延迟爆炸"的物理规律。ρ/(1-ρ) 的倒数在 ρ→1 时发散,说明高利用率下缓解延迟不可行,必须降负载或加容量。

#
★★

44. Branch misprediction 的工程影响,5-20 cycle 代价、5% 误预测率与代码模式(if-else、虚函数、switch)。

Branch misprediction 的工程影响是什么?5-20 cycle 代价、5% 误预测率与代码模式(if-else、虚函数、switch)如何理解?

  • 分支预测与误预测
  • 误预测的周期代价
  • 代码模式的影响

现代 CPU 用分支预测器预测分支走向,预测错误时需冲刷流水线(丢弃已取指令)重新取指,代价约 5-20 个周期(现代乱序核可能更高)。即使误预测率仅 5%,在热循环中也可能显著降低 IPC。相关代码模式:if-else 分支可预测性好(规则模式),但随机数据上的 if 会使预测器饱和;虚函数(vtable 间接跳转)与大 switch 分支表可能预测困难,导致误预测率高。优化:用查表替代分支、保持热路径分支可预测、用 __builtin_expect/likely 提示、对规律数据做排序使分支可预测。

分支预测是"预测性执行"的代价——误预测付的"流水线冲刷"周期。关键是让热路径分支可预测(规律性)或消除分支,而非一味减少分支数量。

#
★★

45. TLB miss(d-TLB、i-TLB)的工程成本与 hugepage 的收益边界。

TLB miss(d-TLB、i-TLB)的工程成本是什么?hugepage 的收益边界如何?

  • TLB 与 TLB miss
  • d-TLB/i-TLB 区别
  • hugepage 的收益

TLB(Translation Lookaside Buffer)缓存虚拟地址到物理地址的映射,miss 时需走页表遍历(多级内存访问),成本高。d-TLB 缓存数据页映射,i-TLB 缓存指令页映射,分别影响数据/指令访问。THP/hugepage(如 2MB 大页)用更大页覆盖更多内存,减少页表项数量,显著降低 TLB miss 率,提升访存性能(尤其对大数据集)。收益边界:hugepage 对按页遍历的大内存工作集收益明显,但若工作集本来就小、或访问高度局部性,收益有限;且大页分配/回收更粗粒度,可能造成内存碎片与浪费。合理配置:对大内存热数据用 hugepage,兼顾 TLB 命中与内存效率。

TLB miss 的代价是"页表遍历"——多级内存访问。hugepage 用大页减少映射项,是降低 TLB miss 的主流手段,但需权衡碎片与粒度。

#
★★

46. Top-Down Microarchitecture Analysis(TMAM)方法论,Retiring、Bad Speculation、Frontend Bound、Backend Bound 四象限。

Top-Down Microarchitecture Analysis(TMAM)方法论的四个象限(Retiring、Bad Speculation、Frontend Bound、Backend Bound)如何理解?

  • TMAM 方法论
  • 四象限定义
  • 诊断应用

TMAM(Top-Down Microarchitecture Analysis)把 CPU 周期按瓶颈归到四个象限:Retiring(退休)——指令正常完成,占比高说明 CPU 高效执行;Bad Speculation(坏推测)——因分支预测错误/推测执行被取消的浪费周期;Frontend Bound(前端瓶颈)——取指/解码跟不上,指令供给不足(i-cache miss、分支预测复杂度);Backend Bound(后端瓶颈)——执行单元/访存跟不上(ALU、load/store、cache miss、向量单元)。诊断:先看 Retiring 是否低(若低说明 CPU 未充分利用),再细分前端/后端/坏推测,定位是取指、访存还是执行问题,对症优化。

TMAM 是"按瓶颈分类"的顶层诊断,避免盲调。Retiring 低 + Backend Bound 高 → 访存/计算瓶颈;Frontend Bound 高 → 取指/代码布局问题。

#
★★

47. Swap 触发与内存压力的关系,swappiness=0、60、100 的不同策略。

Swap 触发与内存压力的关系如何?swappiness=0、60、100 分别是什么策略?

  • swap 触发机制
  • swappiness 参数含义
  • 不同取值策略

swap 是内核在内存压力下把匿名页(或 file 页)换出到磁盘的机制,触发与否取决于内存压力(回收需求)与 swappiness。swappiness 控制"回收时倾向换出匿名页 vs 丢弃 file 页(page cache)"的比例:swappiness=0 表示尽量不换出匿名页,优先回收 page cache(适合数据库等大内存应用,避免 swap 拖慢);swappiness=60 是默认,平衡两者;swappiness=100 表示激进换出匿名页,优先保留 page cache(适合缓存密集场景)。工程上:延迟敏感的大内存服务常设 swappiness 较低(如 0-10)避免 swap 抖动;但完全为 0 可能牺牲 page cache 导致磁盘读增多。

swappiness 是"匿名页 vs page cache"的回收偏好,不是开关。合理值取决于内存压力类型与工作负载(需保留 page cache 还是避免 swap)。

#
★★

48. cgroup memory.high 与 memory.max 的差异,throttle vs kill 的边界。

cgroup memory.high 与 memory.max 的差异是什么?throttle vs kill 的边界如何?

  • memory.high 与 memory.max 语义
  • throttling vs kill
  • 工程选择

cgroup v2 中:memory.high 是软上限,超过时内核对该 cgroup 的进程进行 throttle(回收抑制分配,进程可能被降速/等待,但不会被杀),触发内存回收;memory.max 是硬上限,超过时触发 OOM killer,直接杀掉进程返回错误。差异:high 是"限速"(throttle,进程慢但活着),max 是"杀"(kill,进程死亡)。工程上:用 memory.high 设"舒适上限"让进程受控降速,用 memory.max 设"硬边界"防止进程逃逸导致宿主机 OOM;为避免关键进程被杀,应把 max 设在合理值并监控 high 附近的使用。

high 与 max 是"软限速 vs 硬杀死"的边界。合理配置 high 让进程在内存压力下优雅降速,max 兜底防止失控。

#
★★

49. RED(Rate、Errors、Duration)与 USE(Utilization、Saturation、Errors)方法论。

RED(Rate、Errors、Duration)与 USE(Utilization、Saturation、Errors)方法论分别是什么?如何应用?

  • RED 与 USE 的定义
  • 各自适用场景
  • 资源与请求视角

RED(Rate、Errors、Duration)是"请求视角"的监控方法论:Rate(请求速率,如 QPS、吞吐)、Errors(错误率,如 5xx、异常)、Duration(延迟,如 P50/P99)。适合服务层监控,直接反映用户体验。USE(Utilization、Saturation、Errors)是"资源视角"的排障方法论:Utilization(利用率,如 CPU 忙/总时长)、Saturation(饱和度,如队列长度、等待时间)、Errors(错误数)。适合定位资源瓶颈(CPU、内存、磁盘、网络)。协同:用 RED 看服务表现,用 USE 看底层资源是否饱和,二者结合定位"服务慢是资源问题还是自身问题"。

RED 回答"服务表现如何",USE 回答"哪块资源吃紧"。前者面向用户可用性,后者面向资源排障,是两类互补的检查框架。

#

50. kswapd 的唤醒阈值(watermark)与直接回收(direct reclaim)的切换。

kswapd 的唤醒阈值(watermark)与直接回收(direct reclaim)如何切换?

  • watermark 机制
  • kswapd(后台回收)vs direct reclaim(前台回收)
  • 切换条件

Linux 内存回收用 watermark(水位线)分层:high、low、min。当空闲内存低于 low watermark 时,唤醒 kswapd 内核线程做后台异步回收(不阻塞分配);当内存继续下降低于 min watermark 时,分配路径直接进入 direct reclaim(同步回收,阻塞进程),此时延迟显著升高。若 direct reclaim 也释放不了足够内存,可能触发 OOM。工程上:观察 direct reclaim 的频繁程度(pgscan_direct 等统计)可判断内存压力是否严重——direct reclaim 频繁说明阈值设置过低或内存不足,需加内存或调低可回收压力。

后台回收(kswapd)与前台回收(direct reclaim)的分界是"水位线"。direct reclaim 阻塞分配是内存压力的强信号,应尽量避免。

#

51. memory cgroup 的"硬限制"(memory.max)与 soft(memory.low)的策略。

memory cgroup 的硬限制(memory.max)与 soft(memory.low)的策略有何区别?

  • memory.max 硬限制
  • memory.low 软保护
  • 资源争用下的策略

cgroup v2 中:memory.max 是硬上限,超过即 OOM;memory.low 是软保护(best-effort),当父 cgroup 内内存紧张、需要回收时,尽量不回收低于 memory.low 的 cgroup 的内存(保护其正常运行),但若其他 cgroup 也高压可能会突破。memory.high 是软限速。策略:memory.max 兜底防逃逸,memory.low 保护关键服务(如数据库)在内存竞争时不被过度回收;memory.low 不是硬保证,而是"优先保留"的软语义,配合 high 与 max 组合使用。

三者的关系是:low(软保护)< high(软限速)< max(硬杀死)。low 用于在资源竞争时保护重要服务,max 用于防失控。

#

52. Buffer bloat(缓冲区膨胀),长 fat pipe 与 fq_codel 的工程治理。

Buffer bloat(缓冲区膨胀)是什么?长 fat pipe 下如何用 fq_codel 工程治理?

  • buffer bloat 的定义
  • 成因与影响
  • fq_codel 治理

Buffer bloat(缓冲区膨胀)指网络设备/中间盒缓冲区过大,导致数据包大量排队、RTT 显著增大,即使吞吐正常。成因:厂商为吸收突发配置过大的 FIFO 缓冲,TCP 会不断填满缓冲区抬高延迟却无法提升吞吐。影响:延迟(RTT)高、实时应用(游戏、VoIP)恶化。长 fat pipe(高带宽长时延)下更明显。治理:fq_codel(fair queueing + CoDel)对每个流公平排队(fq),并用 CoDel 基于 sojourn time 主动丢弃/标记包控制队列,避免一个流霸占缓冲,保持队列短、延迟低。部署在路由器/边界设备或服务端,能显著降低 buffer bloat 带来的排队延迟。

buffer bloat 的本质是"过量缓冲 + 无主动队列管理"。fq_codel 用公平队列 + 延迟感知丢弃,让队列保持短小,是 AQM(主动队列管理)的主流方案。

#

53. Connection pool 的命中与新连接,keep-alive timeout、TIME_WAIT 调优。

Connection pool 的命中与新连接如何权衡?keep-alive timeout 与 TIME_WAIT 如何调优?

  • 连接池命中 vs 新建连接
  • keep-alive timeout
  • TIME_WAIT 状态

连接池命中可复用已建立的连接,避免 TCP 握手与 TLS 等开销;新建连接成本高(握手 RTT + 资源)。keep-alive timeout 决定连接空闲多久后关闭——过长浪费连接资源(占用 fd/端口),过短导致频繁新建连接。TIME_WAIT 是主动关闭方在连接关闭后停留的状态(2*MSL),过多 TIME_WAIT 连接会耗尽本地端口/连接资源。调优:keep-alive timeout 设适中(如 60s),配合 HTTP keep-alive 复用;TIME_WAIT 过多时用 SO_REUSEADDR 允许复用、调整 tcp_tw_reuse、或避免客户端主动关闭(让服务端超时关闭)。连接池应监控"连接复用率"与"新建速率"。

连接池的价值是"复用降成本",但 Keep-Alive 生命周期与 TIME_WAIT 回收是平衡点。目标是在复用率与资源占用间取平衡。

#

54. MTU 1500 与 Jumbo Frame 9000,IP 分片与 PMTUD 的边界。

MTU 1500 与 Jumbo Frame 9000 有何差别?IP 分片与 PMTUD 的边界如何?

  • MTU 概念
  • Jumbo Frame 的收益
  • IP 分片与 PMTUD

MTU(最大传输单元)决定单帧可承载的最大载荷,标准以太网 1500 字节,Jumbo Frame 可达 9000 字节。Jumbo Frame 减少帧数量与中断/头部开销,提升大包传输效率,但要求整条链路所有设备都支持(端到端一致),否则触发分片。IP 分片:超过路径 MTU 的包被中间设备分片,增加开销且易丢;PMTUD(路径 MTU 发现)通过探测避免分片,让发送端按最小路径 MTU 发送。边界:Jumbo Frame 只在受控的局域网/数据中心内有收益且需端到端支持;跨公网/多设备普遍用 1500,依赖 PMTUD 与 DF 位避免分片。

Jumbo Frame 是"效率 vs 兼容性"的权衡。端到端支持才有效,否则要靠 PMTUD 避免分片。工程上仅在有完整控制的基础设施内启用。

#

55. Span 的成本,网络、序列化、存储、聚合的工程考量。

Span 的成本构成是什么?网络、序列化、存储、聚合各有哪些工程考量?

  • Span 的成本组成
  • 各环节开销
  • 成本控制

分布式追踪的 Span 产生成本:网络成本——每个 span 从服务端上报到 collector/后端,占带宽与 collector 负载;序列化成本——span 数据编码(如 protobuf/JSON)的 CPU 开销;存储成本——span 写入存储,占用磁盘与内存,高吞吐下 span 量巨大导致成本爆炸;聚合成本——后端聚合、索引、采样处理 span 的 CPU/内存。控制:采样(按比例/按错误全采/按尾延迟采样)、降采样、仅保留关键 span、设置 TTL 与 retention、批量上报合并。工程上要权衡"追踪覆盖度"与"成本"。

Span 是"质量 × 数量"的成本问题。生产上必须采样与限量,否则追踪成本会超过收益。核心是"该采的都采到,不该采的别浪费"。

#

56. 基线的建立,历史数据、灰度数据、对照组的工程选择。

基线(baseline)如何建立?历史数据、灰度数据、对照组各有什么工程选择?

  • baseline 的概念
  • 各类基线来源
  • 应用场景

基线(baseline)是用于对比的"参考水平",用于判断当前是否偏离正常。建立来源:历史数据——用过去一段时间(如 7 天/30 天同时间段)的指标均值/分位数作基线,能反映季节性,但受历史异常污染;灰度数据——发布时用灰度实例的真实数据作基线,与正式环境对比,最相关但需灰度流量;对照组——用未变更的实例/集群作对照,隔离变量,适合 A/B 与实验。工程上:结合历史基线(趋势)与实时对照组(隔离变量),在发布/变更时用灰度对照,日常用历史基线告警。

基线是"判断异常的参照"。不同来源适配不同场景:历史看趋势,灰度看变更影响,对照组看隔离实验。动态基线比固定阈值更鲁棒。

#

57. 日志采样(sampling)的策略,全采 vs 错误全采 vs 概率采样。

日志采样(sampling)的策略有哪些?全采、错误全采、概率采样各有什么取舍?

  • 采样策略类型
  • 各策略取舍
  • 成本与覆盖

日志采样策略:全采(head sampling)——所有日志都记录,覆盖最全但成本最高(存储、链路上报),适合低流量或关键系统;错误全采——错误级别日志全量记录,正常日志按需记录,兼顾排障(错误必留)与成本;概率采样(如 10% 采样)——按比例随机采样,成本可控,但可能漏掉错误/低频事件,需配合错误全采兜底。工程上常组合:错误全采 + 正常流量按概率采样 + 高价值业务(如支付)全采,在成本与可观测性间平衡。

采样是"成本 vs 覆盖"。错误全采是底线(排障必须),概率采样控制成本,全采用于关键路径。按业务重要性分层采样。