用结构化思维解一切BUG(1):核心思路
面对万“卷”世界,有人选择拼命学习新技术,解决眼前的、点状问题;有人提升思维层级,解决未来的、系统问题。您选择什么?
背景
我有10多年编程经验和研发管理经历,虽很久不写代码,但有很多人找我咨询技术问题,解决程序 BUG。因为不管多么千奇百怪的技术栈,我都能帮到他们,或直接给出解题思路,或帮他们精准定位问题。
在很多具体的技术点上(比如SQLServer、Kubernetes上),我都算不上资深专家,但我总能帮这些资深专家快速解决 BUG。为什么呢?
回答这个问题之前,我们要分清「诊断」和「治疗」。「诊断」需要的是结构化思维,只要您理解计算机运行原理,对现代应用的组成有基本认知,您就可以用「假设树」和「主动试验」来逐步缩小范围,最终确定「病因」。但「治疗」,需要把想法实现,需要具体的技术知识。
很多程序员在具体技术上很精通,但在需要平移或扩展到其它类似技术时,往往捉襟见肘。这导致,为了自己的维持竞争力,需要拼命的学习新的技术栈。很累,却效果不好。
本系列文章不介绍具体的技术,而介绍一种「程序诊断」的思维框架,是「性价比」更高的「通项公式」,可以跨场景解决任何问题,可以终生受益!
核心思路:做实验→造现象→缩范围
本「程序诊断」的核心思路就是依赖于「假设树」,通过重复多次执行「做实验→造现象→缩范围」动作序列,逐级下钻,缩小问题范围,直到「执行者」可以接管的程度(通常是一个服务/模块/函数)。如下图所示:
其基本逻辑是:
- 面对现象,先从宏观去判断第一层级的「可能的原因」,即原因所在的大类。当我们判断了第一层级的原因,我们就把问题范围缩小了。
- 假设确定原因大类为「可能的原因2」,接下来在更小的范围中,我们需要进一步确定更具体的原因,是 2-1 还是 2-2 还是 2-3。
- 如果当前现象没有提供充分的证据来帮我们进一步缩小范围,则我们需要主动做试验,来创造更多现象,以支撑我们缩小范围。
- 重复上面三个步骤,直到把范围缩小到执行者可以解决的程度。
在软件领域,前几层的「假设树」一般有大致的套路。以一个 Web 应用为例,其前几层「假设树」通常可参考下图制作。
我们面对一个现象时,通常先判断是前端原因还是后端原因。
假设是前端原因,我们再判断,是运行问题(代码问题)、数据问题、网络问题、还是运行环境问题。展开来说:
- 如果近期发布过新版本,则有很大概率是运行问题(代码问题)。
- 如果排除了代码问题,并且 BUG 只有某些固定用户出现,或只跟某些固定的实体(比如商品、流程)相关,那么大概率是数据问题。
- 如果排除了以上两者,并且 BUG 只有某些固定用户出现,则可以检查一下这些用户的浏览器(品牌和版本)是否一样,以确定是否浏览器问题。
- 如果排除了以上三者,并且 BUG 跟用户所在的网络环境有很大关系,则可以检查下网络。
再往后,以此类推。
请注意,「假设树」没有标准答案,以上只是 Web 应用的「假设树」的「一种」拆分方法。面对不同的软件应用场景、不同的现象,你可能需要绘制自己的「假设树」。这个绘制不难,只要懂得计算机的基本运行原理和现代应用的基本组成部分,利用机构化拆解问题的基本方法,即可绘制。
从第一性原理来讲,一个应用本质就是「处理」「数据」的程序。出现问题,要么是处理逻辑发生了改变(一般是代码导致),要么是数据发生了改变。如果我们能保证代码没改变(通过发布的版本号或者 Git 提交号来判断),那么一定是数据发生了改变。假设确定了是数据的问题,我们可以继续列举原因,可能是环境配置的数据、数据库的数据、缓存的数据、其它微服务传递过来的数据、前端传递过来的数据、时间等。这样,就可以继续往下钻。
实践原则:程序断案三字经
通过上面的介绍,您大概已经知道了核心思路。但到实际使用,还需要一些操作原则来帮助。我把他们总结成「程序断案三字经」:
- 先诊断,后开药。
- 信机器,慎信人。
- 做试验,缩范围。
- 先脆弱,后稳定。
- 找不同,看变化。
篇幅原因,本文不展开介绍这些实践原则,请关注本系列后续文章,我将深度讲解实践原则和典型案例。
总结
面对万“卷”世界,有人选择拼命学习新技术,解决眼前的、点状问题;有人提升思维层级,解决未来的、面状问题。您选择什么?
关于作者
您好,朋友。我现就职于西门子工业软件,担任高级咨询顾问。成功领导 10 多个世界 500 强企业的数字化转型项目,跨越政府、零售、金融、汽车制造、生物医药等多个行业,创造巨大商业价值。
如有任何与「数字化转型」有关的问题,欢迎用以下方式与我交流:
-
添加我的个人微信「zjh1943」。添加时请注明姓名、行业、交流的问题。
-
关注我的微信公众号「知明所以」。
-
关注我的知乎专栏:https://www.zhihu.com/people/zhu-jin-heng 。