一个 7x24 常驻的服务,容器 limit 4GiB。内存曲线呈『锯齿状缓慢抬升』:每次回收后的低点比上一次高大约 50MB,约 5 天后被 OOMKilled,重启立刻恢复正常。请给出你的定位方案:怎么区分是真泄漏、缓存无界、还是内存碎片;在容器里你用什么工具拿到能站得住脚的证据;以及最后你依据什么决定是『改代码』还是『调 limit / 换策略』。
面试官在考什么
判断候选人能否把内存问题拆成堆内泄漏、堆外分配、缓存无界、碎片几类不同成因,并具备在受限的线上容器里取证、以及做修代码与调策略之间工程取舍的能力。
回答框架 · 前两步
- 先做二分:回收后低点持续抬升,指向对象被长期持有(疑似泄漏);低点稳定但峰值贴着 limit,更像是瞬时峰值、无界缓存或碎片——这两类修法完全不同。
- 工具链要对得上:语言级堆快照比对象类型和引用链、allocator 统计看 arena 与碎片、/proc/<pid>/smaps 看匿名页与文件页、cgroup memory.stat 确认涨的是哪一类内存。
还有 3 条答案要点、 3 层追问、 5 个常见坑, 以及针对你简历的追问路径,在定制报告里。
同一能力域的其他题
- 生产环境某接口每天偶发几笔“参数校验失败”,现有日志只有一行“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 等待分析),为什么?在这个场景下扩容能不能解决问题?