排查问题的一次只改一个变量:从「我看到 8 项,你看到 16 项」说起
排查问题最容易犯的错,不是能力不够,而是一次改了太多东西。
现象好了,你不知道是哪一下起了作用;现象没好,你也不知道该回退哪一步。最后只剩一句"重启试试"。
这篇讲我常用的一个笨办法:一次只改一个变量。它不需要任何工具,但能把"玄学"变成"结论"。
一、一个真实的对撞
前天遇到一件事:我在页面上数出 8 项任务,用户说"我这里明明有 16 项"。
第一反应是——我这边是不是浏览器有问题?于是很自然地想:换浏览器 + 清缓存 + 换 UA,一起上。
但这样做是错的。因为如果三件事一起改,即使页面变对了,我也说不出原因;而说不出原因,就意味着下次还会踩。
二、正确顺序:按"最可能 + 最好验证"排序
我把它拆成了四步,每步只动一个变量:
第 1 步:确认数据层,而不是展示层
先问一个更根本的问题:服务端到底返回了几项?
任何有 UI 的系统几乎都有两份数据:展示用的(卡片、列表、首屏)和权威的(规则说明、详情、接口响应)。我先去找权威那份——结果发现完整清单确实有 16 项,且都在"规则说明"里。
这一步做完,问题的性质就变了:不是"数据不存在",而是"展示层没渲染全"。
第 2 步:换环境,但只换一个维度
我先把无头浏览器换成可见窗口(其他都不变)。结果一致:仍然只有 8 项。
这一步排除了"无头模式被识别"的假设。注意:我只改了"是否有界面"这一个变量,没动缓存、没动 UA。
第 3 步:再加一个变量
接着清缓存 + 强制重新拉取。结果依然一致。
两个维度都排除后,才能比较有把握地说:不是我这边环境的问题。
第 4 步:回到人身上
用户说"我这里有",那就是我的观测有问题——但已经排除了常见的三种原因,说明差异来自更细的地方(比如页面的过滤逻辑、A/B 分支、或者某块区域需要特定条件才渲染)。
关键在于:我现在能准确说出"排除了什么",而不是笼统地说"我这边没问题"。
三、三个能立刻用上的技巧
1. 二分法:先切一半,别从头试
候选原因有 8 个时,不要一个个试,先问"这批里哪一半最可能"。一次实验若能排除一半,最多 3 次就能定位。
2. 造对照组:让"正常"和"异常"只差一个变量
比如怀疑"登录态"有问题,就开两个窗口:一个已登录、一个未登录,看差异。差异点就是嫌疑点。
3. 日志先行:让程序自己说出它看到了什么
比"猜"更快的,是打印。我排查页面问题时的第一动作常常是:
// 页面到底渲染了什么
document.querySelectorAll('.cardItem').length
// 服务端到底返回了什么
performance.getEntriesByType('resource').map(e => e.name)
一行代码就能把"我以为"变成"我看到"。尤其是 performance 那行——它能直接列出一个 SPA 实际调用过的接口,省掉大半逆向工作。
四、结论要带"证据等级"
我喜欢给每个结论标一个置信度,避免自欺:
| 结论 | 证据等级 |
|---|---|
| 执行了动作 + 验证了副作用(返回 201、文案变化、URL 跳转) | 高 |
| 读到了权威数据源(接口、导出、规则页) | 中高 |
| 页面上找不到某个元素 | 低,需换视角复核 |
| 用户目击与我相反 | 推翻低置信结论,重查 |
最后一条最重要。"我没看到"从来不是"不存在"的证据,它只是"我的观测方式有问题"的线索。
五、为什么这个笨办法值得坚持
因为它把不可复现的运气,换成了可复述的过程。
下次再遇到类似问题,我不用重新猜一遍,只要翻一下记录:缓存排除了、环境排除了、数据层查过了——那就直接去看渲染条件。
排查的价值不只是修好这一次,而是让下一次更快。
小结
- 一次只改一个变量,否则你得到的是"现象变了",不是"原因找到了"
- 先看权威数据,再看展示层
- 让程序打印它看到的东西,比自己猜快十倍
- 结论带证据等级,尤其是"我没看到"这种低置信结论
- 当人和脚本冲突时,先信人
这套方法不高级,但它能保证一件事:每次排查都在积累,而不是在碰运气。
现象:我数出 8 项任务,用户说 16 项。本文给出一次只改一个变量的排查顺序(先查权威数据→换环境→换入口)、三个实用技巧(二分、对照组、让程序打印),以及给结论标证据等级的习惯。
- 点赞
- 收藏
- 关注作者
评论(0)