一个容器内存 limit 为 12GB 的服务,在 QPS 稳定的情况下,内存 8 小时内从 2GB 涨到接近 12GB 后被 OOMKilled 重启,重启后再次重复这个过程。请说明:你怎么判断这是内存泄漏、缓存膨胀,还是“正常增长但没设上限”?你会看哪些指标、用什么工具定位到具体对象?你会在线上直接 dump 堆吗,这个动作的代价是什么、有没有代价更小的替代路径?
面试官在考什么
判断候选人能否区分 RSS、堆内、堆外与缓存等不同内存口径,是否理解容器 OOMKilled 的触发条件,以及能否在线上用低开销手段做内存取证。
回答框架 · 前两步
- 先对齐口径:容器 OOMKilled 由 cgroup 的 RSS 触发,堆内没涨也可能是堆外内存、direct buffer、mmap、线程栈或未归还给 OS 的内存;要分 RSS、堆 in use/committed、缓存分别观察。
- 判断泄漏还是缓存:看 GC 后的基线是否持续抬升;稳定 QPS 下正常的 LRU 缓存应趋于收敛,命中率和条目数也应该稳定。
还有 3 条答案要点、 3 层追问、 4 个常见坑, 以及针对你简历的追问路径,在定制报告里。
同一能力域的其他题
- 生产环境某接口每天偶发几笔“参数校验失败”,现有日志只有一行“invalid param”,没有请求上下文,也无法在测试环境复现。约束:不能重启服务、不能停流量、不能改业务逻辑。你如何在不影响线上稳定的前提下补日志或使用断点定位?请给出操作顺序、日志字段和级别、断点使用条件,以及日志量过大时的控制手段。
- 线上一个服务 QPS 约 5000,某核心接口 P99 约 200ms。存在一个约万分之一概率的数据不一致问题,平均每天出现 3~5 次,本地和压测环境都复现不出来,下一次上线窗口在一周后。现在要在生产现场抓这个问题的证据。请具体说明:你会用日志还是断点(或动态追踪)?日志打在哪一层、打哪些字段、如何控制采样?如果在 5000 QPS 的进程上挂一个阻塞式断点,会造成什么后果,你用什么手段规避?
- 你们的在线推理服务跑在 60 个 Pod 上,高峰 8k QPS,每个请求平均打 12 行 INFO 日志,日志平台按写入量计费。现在日增 30TB、保留 30 天,日志成本已经接近计算成本的一半,但 SRE 依然抱怨出事时日志不够用。请给出你的日志治理方案:分级和采样怎么定、哪些日志必须 100% 保留、如何在量降下来的同时不丢排查能力,以及你打算怎么推动各业务方配合。另外说清楚:生产环境需要看某个 Pod 的详细执行过程时,你会用断点还是动态日志,为什么。
- 一个 Flask 接口线上每天有几次返回 500,日志里只有一行 "handle request failed",没有堆栈;本地用同样的参数打了几千次都复现不了。请说出你接下来会怎么改日志让下一次失败能自证原因:加哪些字段、用什么级别?另外有人提议直接在线上挂断点单步调试,你怎么看?
- 某接口 P99 从 200ms 涨到 1.2s,平均耗时只涨了约 100ms,CPU 使用率没有明显变化,入口 QPS 基本不变。你手上只有该服务的性能剖析工具(CPU profiler、锁分析、GC 日志、链路追踪)和少量机器权限。请说明你会先看什么、再看什么,如何逐步区分是 CPU、锁、GC、IO、下游依赖还是排队导致的长尾。
- 线上服务 QPS 稳定在 2000,业务量没有变化,但接口 P99 从 50ms 恶化到 300ms。机器 CPU 使用率只有 60%,内存指标正常,下游依赖的 RT 监控也没变化。团队第一反应是“扩容加副本”。请说明你的排查路径:你会先看哪些指标,选择哪种 profiling(CPU sampling、wall-clock、off-CPU、锁/GC/IO 等待分析),为什么?在这个场景下扩容能不能解决问题?