你最近面试被问到的最难的题是什么? 评论区交流,我来解答)
突然发现自己欠了一屁股 技术债 ? 别薅头发了 —— 关注本专栏,带你清债~
一、口诀:
一问二止三看志,四监五网六查库。
七码八具九复现,十找根因十一解。
十二盯紧十三记。
一问:问清楚问题情况
二止:及时止损,采取应急措施
三看志:查看各种日志
四监:分析监控数据
五网:检查网络状况
六查库:排查数据库问题
七码:查看代码情况
八具:使用工具辅助
九复现:尝试复现问题
十找根因:找到问题根源
十一解:制定解决方案
十二盯紧:持续监控
十三记:总结记录经验
二、答案:
对照着一个人摔伤看病过程来说。
1、先搞明白 “到底出了啥幺蛾子”。(问题确认) 1、问诊
发现问题别急着动手,先把情况摸清楚。就像医生看病得先问症状,你得搞清楚这几个事儿:
具体啥毛病?(如响应慢、服务不可用、数据异常等)。 骨折了还是流血?
确定影响范围(受影响的用户、模块、服务)。 哪里疼?
记录问题发生的时间点,是持续还是间歇性。 啥时候开始的?
收集环境信息(服务器配置、JDK/应用版本等)。 咋受伤的?
2、先给系统 “止止血”(快速响应) 2、止血包扎。
要是问题特别严重,比如支付系统崩了,可不能慢悠悠分析。先掂量掂量事儿有多大:
- 要是影响核心业务,赶紧上应急措施。比如暂时关掉非关键功能(服务降级)、不让太多人同时访问(流量限制),或者把程序退回到上一个稳定版本(回滚)。先把损失控制住,再慢慢找病根。
3、从日志里找 “蛛丝马迹”。 3、看验血报告,从数据里找问题。
系统出问题,日志里多半藏着线索。就像汽车坏了,故障灯亮了会提示哪里不对,程序也一样:
- 先看程序自己的日志,里面有没有 “报错”“异常” 之类的字眼,这些都是明晃晃的线索。
- 服务器本身也会记日志,比如 Linux 系统的 /var/log/messages 文件,说不定能找到服务器层面的问题。
- 数据库、缓存这些 “中间件” 也得看看,它们的日志里可能藏着和程序互动时出的岔子。
4、看看系统 “身体指标” 正常不 4、看血压、心率
- 服务器的 CPU 是不是跑满了?内存是不是快用完了?磁盘和网络忙不忙?
- Java 程序的 JVM 有没有 “消化不良”?内存堆是不是快撑爆了?垃圾回收是不是太频繁?
- 应用本身的表现咋样?请求响应时间是不是突然变长了?报错的请求多不多?
5、查查网络 “通不通畅” 5、血液循环 是否顺畅
有时候系统卡,不是程序的锅,是网络在捣乱:
- 看看防火墙是不是挡了关键连接,该开的端口有没有打开。
- 测测网络速度,是不是延迟特别高,或者数据总丢包。就像打电话总断,说话再清楚也没用。
6、给数据库 “把把脉” 6、检查 内脏器官
很多问题最后都能追到数据库头上:
- 有没有特别慢的 SQL?就像堵车时总有几辆慢吞吞的车挡路。
- 数据库连接够不够用?是不是太多人同时抢连接,导致大家都得等着。
- 那些关键的 SQL 语句写得合理不?有没有绕远路查数据。
7、扒开代码看看 “内部情况” 7、检查 细胞
要是前面几步还没找到原因,就得往代码深处挖了:
- 看看程序里的线程都在干啥,是不是有一堆线程堵在那儿不动了(线程转储)。
- 内存里有没有堆积如山的无用数据(堆转储),就像家里杂物太多走路都费劲。
- 最近改了啥代码?新上线的功能说不定藏着小 bug。
8、善用工具 “当助手” 8、CT、核磁共振
排查问题不能光靠眼睛看,得靠工具帮忙:
- 用 Arthas、JProfiler 这类工具,能精准找到 CPU 和内存的 “耗电大户”。
- 用 Prometheus、Grafana 这些监控工具,把系统状态画成图表,哪里不对劲一眼就能看出来。
9、试着 “再犯一次错”。再按一下痛处。 9、模拟受伤场景
在测试环境里,尽量模仿线上出问题的场景,看看能不能把问题复现出来。就像警察还原案发现场,复现出来了,解决起来就容易多了。
10、找到 “罪魁祸首”。 10、找到病因。
把前面收集的所有信息汇总起来,一步步倒推:到底是哪个环节先出问题,又引发了后面的连锁反应?比如数据库连接不够用,可能是代码没释放连接;内存不够用,可能是数据没及时清理。
11、开出 “药方”。 11、打针、吃药、手术。
找到原因后,先想个快速解决的办法,让系统先正常运转起来。然后再琢磨长期方案,比如优化代码、调整配置,防止以后再出同样的问题。
12、盯着点 “别再出岔子”。 12、术后观察,防止复发。
改完之后别大意,先在测试环境试试好不好使,没问题了再放到线上。上线后也得盯着,确保问题真的解决了,没留下后遗症。
13、记下来 “下次别踩坑”。 13、病例总结。
最后一定要写个总结:这次问题是咋回事、怎么解决的、以后该注意啥。把经验记下来,团队里的人都能学到,下次遇到类似问题就不用从头摸索了。
三、举个例子:
Java 程序变慢了咋办?
比如用户说 “页面点一下要等 2 秒,以前才 0.2 秒”。按上面的步骤走:
- 看日志发现好多 “内存不够” 的警告。
- 监控里显示内存快满了,频繁清理内存(Full GC)。
- 查线程状态,发现好多线程都在等数据库连接。
- 数据库里连接池都用完了,还有一堆慢 SQL 在拖后腿。
- 最后发现,最近改的代码里,数据库连接用完没关!
找到原因就好办了:把连接释放的代码修了,优化一下慢 SQL,再把连接池调大点儿,问题就解决了。
(点个赞,算法会给你推荐更多类似干货 ~ 持续更新中,点关注,看下篇文章)
一、口诀:
CPU 高看栈堆,内存泄漏快照追;
超时链路查节点,线程阻塞锁定位。
二、思路:
(1)定位故障类型。
CPU 过高:系统响应慢,服务器 CPU 使用率超 95%;
内存泄漏:JVM 内存持续增长,频繁 Full GC,最终 OOM;
线程阻塞:接口超时,线程状态多为BLOCKED或WAITING;
接口超时:调用链路中某环节耗时突增(如 DB 查询、RPC 调用)。
(2)用工具深查根因。
(3)针对性优化。
三、解决方案:
1. CPU 过高
- 排查工具:JProfiler、Yourkit(可视化 CPU 耗时函数)、jstack(定时打印线程栈)。
- 步骤:
- 用
top命令定位 CPU 使用率超 95% 的 Java 进程; - 用
jstack <进程ID>打印线程栈,分析频繁出现的函数(采样法识别耗时操作); - 结合 JProfiler 查看函数调用耗时,重点优化 CPU 密集型操作(如序列化、复杂计算)。
- 用
2. 内存泄漏
- 排查工具:jmap(导出堆快照)、MAT(内存分析工具)。
- 步骤:
- 用
jmap -dump:format=b,file=heap.hprof <进程ID>导出堆快照; - 通过 MAT 分析快照,定位频繁创建却未释放的对象(如静态集合未清理、长生命周期对象引用短对象);
- 检查代码中是否存在资源未关闭(如 IO 流、连接池未回收)。
- 用
3. 接口超时
- 排查工具:SkyWalking(链路追踪)、Grafana(监控 QPS/RT)、tcpdump(网络抓包)。
- 步骤:
- 用 SkyWalking 查看接口调用链路,定位超时节点(如 RPC 调用、DB 查询);
- 若 DB 超时,用
explain分析 SQL 执行计划,优化索引或拆分查询; - 若网络超时,用 tcpdump 抓包分析是否存在网络抖动或连接池耗尽。
4. 线程阻塞
- 排查工具:jstack(线程栈分析)、jconsole(线程状态监控)。
- 步骤:
- 用
jstack打印线程栈,统计BLOCKED状态线程,定位锁竞争源头(如 synchronized 块、Lock 锁); - 检查是否存在死锁(线程互相等待资源),通过线程 ID 关联等待关系;
- 优化锁粒度(如拆分锁、使用并发容器)。
- 用
四、STAR 法则回答
- 情境(S):某电商支付接口突发超时,99% 响应时间从 50ms 增至 500ms,影响下单流程。
- 任务(T):1 小时内定位故障原因并修复,恢复接口性能。
- 行动(A):
- 用 Grafana 发现接口 QPS 未变但 RT 飙升,SkyWalking 追踪到 DB 查询耗时占比 80%;
- 用
explain分析 SQL,发现订单表未建索引,导致全表扫描; - 紧急添加索引后,用 jstack 确认无锁竞争,接口 RT 恢复至 40ms。
- 结果(R):故障 15 分钟内修复,支付成功率从 80% 回升至 99.9%,未影响用户下单。
五、生活例子
类比 “医院急诊诊断”:
- CPU 过高像 “病人持续高烧”,用体温计(JProfiler)测体温,CT(jstack)查病因(哪个器官异常);
- 内存泄漏像 “水肿”,用 B 超(MAT)看哪里积水(未释放对象);
- 接口超时像 “供血不足”,用血管造影(SkyWalking)查堵塞位置(哪个环节延迟)。
13万+

被折叠的 条评论
为什么被折叠?



