题目2:现象收集与分析

缺陷定位的第一步,就是把现象搞清楚。

我见过太多人,一上来就翻代码、打日志,结果折腾半天发现——原来问题描述本身就是错的。说白了,现象没搞明白,后面全是白费功夫。

如何准确描述缺陷现象

一个准确的缺陷描述,应该像一份“现场报告”。

我个人习惯用这个模板:

要素 说明 示例
前置条件 问题发生前做了什么 用户登录后,点击“订单详情”
实际结果 系统实际表现 页面白屏,控制台报 500 错误
期望结果 应该是什么样 正常显示订单列表
环境信息 浏览器、系统、版本等 Chrome 120, Windows 11
复现概率 必现/偶现/概率 必现,每次操作都触发

核心原则:现象描述要可验证、可复现。别用“好像”、“可能”、“偶尔”这类模糊词。

我在项目中遇到过这样一个案例:测试同学报了个“页面加载慢”,结果我一看,他用的是一台 4G 内存的虚拟机,还开着十几个标签页。你想想看,这到底是代码问题还是环境问题?

日志分析技巧

日志是缺陷定位的“黑匣子”。但很多人不会看。

技巧一:先看时间线

别一上来就搜“error”。先按时间排序,看看异常发生前后都发生了什么。我习惯用 grep 配合 tail 来截取关键时间段:

# 截取 2025-01-15 10:00:00 到 10:05:00 之间的日志
grep "2025-01-15 10:0[0-5]" app.log | less

技巧二:关注“第一次”异常

很多时候,第一个错误才是根因。后面的异常都是连锁反应。举个例子:

10:00:01 ERROR - 数据库连接超时
10:00:02 ERROR - 查询用户信息失败
10:00:03 ERROR - 返回空数据给前端

你看,根因是数据库连接超时,后面两个只是“受害者”。

我的小习惯:日志里如果出现“timeout”、“null pointer”、“out of memory”这类词,我会优先排查。它们往往是根因的“代言人”。

技巧三:善用日志级别

别把所有日志都打成 INFO。我建议这样分级:

  • ERROR:系统无法自动恢复的异常,比如数据库连不上
  • WARN:不影响主流程,但值得关注,比如重试了一次
  • INFO:关键业务节点,比如“用户下单成功”
  • DEBUG:开发调试用,上线后建议关闭

注意:别把敏感信息(密码、身份证号)打到日志里。我曾经见过一个项目,日志里明文打印了用户密码……嗯,那场面,你懂的。

复现步骤的规范化

复现步骤写得好不好,直接决定别人能不能看懂。

我推荐用“三步法”:

  1. 准备阶段:需要什么数据、什么环境
  2. 操作阶段:按顺序列出每一步操作
  3. 验证阶段:如何确认问题出现了

举个例子,一个“购物车无法删除商品”的缺陷:

【复现步骤】
1. 准备:登录一个已有商品的账号(账号:test01,密码:123456)
2. 操作:
   a. 进入“我的购物车”页面
   b. 点击商品 A 右侧的“删除”按钮
   c. 在弹出的确认框中点击“确定”
3. 验证:页面刷新后,商品 A 仍然存在,未从购物车移除

你看,这样写,任何人照着做都能复现。我在项目中遇到过最离谱的复现步骤是:“随便点点,然后就崩了”。你想想看,这谁能复现?

避坑指南:我曾经因为复现步骤里漏写了一个“先清空缓存”的步骤,导致开发花了三天没复现出来。后来发现,是因为开发的环境有缓存,而测试环境没有。从那以后,我写复现步骤一定会把“前置条件”写清楚。

知识体系图

下面这张图,帮你理清本章的核心逻辑:

现象收集与分析 准确描述现象 前置条件 + 实际结果 期望结果 + 环境信息 复现概率(必现/偶现) 日志分析技巧 先看时间线,按序排查 关注“第一次”异常 善用日志级别分级 复现步骤规范化 准备阶段(数据/环境) 操作阶段(按顺序) 验证阶段(确认问题) 三者结合,才能从现象快速定位到根因

好了,这一章的内容就这些。记住:现象描述要准,日志要会看,复现步骤要规范。这三板斧练好了,缺陷定位就成功了一半。

可可精品资料库