背景

本文是系列文章《用结构化思维解一切BUG》的第二篇。本系列文章主要介绍一种「无需掌握技术细节,只需结构化思维和常识即可解一切BUG的方法」。

在前序文章《用结构化思维解一切BUG(1):核心思路》中,我介绍了用结构化思维解BUG的核心思路。即,基于结构化的「假设树」,通过重复多次执行「做实验→造现象→缩范围」动作序列,逐级下钻,缩小问题范围,直到找到问题根因

但本方法是一个理论和实践相结合的方法,仅靠核心思路,无法完整表达。您真正使用时,还需一系列实践原则来指导方向,才能高效执行。

我把这些实践原则总结成「程序断案三字经」,5 条 30 个字:

  1. 先诊断,后开药。
  2. 信机器,慎信人。
  3. 做试验,缩范围。
  4. 找不同,看变化。
  5. 先脆弱,后稳定。

下文详述。

1. 先诊断,后开药

切勿在没有充分的证据时,投入大量人力去修改 BUG。如果现有的现象不足以充分支撑结论,则应该做「小成本」的试验去制造更多现象,以支撑结论。

我看过很多程序员,只了解了基本的现象,就开始靠直觉和经验来推断:「这里最有可能是这里的问题,咱们引入另一个新的工具库可以解决这个问题,我们改改试试」。当大家大动干戈地修改完后,发现问题并没有解决。然后马上改变主意:「刚刚的推断不对,我认为可以再改下这里试试」。几轮下来,极大的影响团队士气不说,更加影响业务的正常运转。

所以,这种在进行严谨的诊断之前就盲目开药的行为,是应该尽力避免的。

2. 信机器,慎信人

这里有两层意思:

一、机器不说谎

机器没有「真」随机,就算随机数也是伪随机,更不用说你观测到的 BUG 现象了。你观测到的随机BUG,一定不是随机的,一定有确定稳定的根因,只是你暂时没有发现

另外,机器不会错报任何一个现象。如果您找到的根因,解释了 10 个现象中的 9 个现象,只差 1 个解释不了,那么请相信,您还没有找到根因。

二、人会说谎。

你要相信自己「观察」到的现象,而不是别人「描述」的现象。这不是说您的同事或客户会故意骗人,而是人类大脑有自身缺陷。面对不重要的事情时,人脑经常容易遗忘;当面对信息缺失时,人脑又会自己进行无中生有的脑补。比如,有一次,我问一个运维工程师,这次发布跟上次的发布有什么区别时,他说完全没有。但最终证明,在本次发布时,他新建了一个新的文件夹来存放应用的运行包,而这个文件夹是以 root 的角色创建的。他完全忘记了这件事,而这件事就是应用无法启动的根因。

所以,我们对别人描述的现象,要自己判断其真实性,必要时做试验验证。举个例子,如果有人说,他昨天早上 9 点多登录应用失败,并且报错“Invalid Password”。你应该相信的是,他真的登录失败了;你应该保持怀疑的是,登录的时间和报错的信息,这些信息最好去后台日志去验证一下。

3. 做试验,缩范围

在「假设树」中下钻的过程中,如果当前已知现象没有提供充分的证据,来帮我们进一步缩小范围,则我们需要主动做试验,来创造更多现象,以支撑我们缩小范围

并且,试验要有针对性,针对目标的就是「假设树」中当前阶段的「可能原因列表」。你设计的「试验」,是需要能排除一个或多个可能的原因。

4. 找不同,看变化

这条原则是对上一条原则「做实验,缩范围」的补充说明。

即,在做实验时,一次验证一个原因,控制单一变量,尽量排除其他干扰。然后,寻找单一变化因子下的现象变化。

举个真实的例子,曾经有一个登录问题,我的直觉判断是浏览器版本问题。我设计的试验是:

  1. 让现在没有 BUG 的用户升级 Chrome 浏览器到有 BUG 的用户一样的版本,看是否出现 BUG。
  2. 并且,我让两个用户都打开隐私窗口,以排除 Cookie 可能造成的干扰。
  3. 同时,我让两个用户都更换浏览器到 Edge、Firefox 和 Safari,做了同样的试验。

我得到的现象是:Edge 和 Chrome 升级后都会报错,其它两个浏览器都不报错。

得到的结论是:此 BUG 必然跟 Chrome 最新内核的更新有关,因为 Chrome 和 Edge 都是同一个内核。

5. 先脆弱,后稳定

现代应用有非常多模块,不同的模块有不同的“置信度”或“可靠度”。要从更脆弱的、更有可能出错的地方入手。就像警察断案,先找有犯罪前科的,工作不稳定的,是一个道理。有些人对自己的代码过于自信,经常从 MySQL、Nginx 这样的模块入手去查找问题。不是说这两个组件绝对不会出问题,而是说 100 次有 99 次都会失败,严重影响效率。

一般置信度从高到低的排列如下:

  1. 操作系统。
  2. 行业通用组件。这类系统经过大量验证,比如 MySQL、Nginx、Memcached、RabitMQ 等。
  3. 组织内通用组件。比如被企业内多个项目使用过的 SSO 模块。
  4. 自己写的最上层的业务代码。

除了代码提供者这个维度以外,还有一个更新时间维度。越是有新的更新的代码,越没有经过时间验证的代码,越有可能有问题。

总结

至此,《用结构化思维解一切BUG》的方法的理论部分已经讲完。

为了更好的帮助大家掌握此方法,我准备了多个实际案例,将在后续系列文章中细致讲解,请关注我的公众号接收更新。

关于作者

您好,朋友。我现就职于西门子工业软件,担任高级咨询顾问。成功领导 10 多个世界 500 强企业的数字化转型项目,跨越政府、零售、金融、汽车制造、生物医药等多个行业,创造巨大商业价值。

如有任何与「数字化转型」有关的问题,欢迎用以下方式与我交流:

  1. 添加我的个人微信「zjh1943」。添加时请注明姓名、行业、交流的问题。

  2. 关注我的微信公众号「知明所以」。

  3. 关注我的知乎专栏:https://www.zhihu.com/people/zhu-jin-heng

用结构化思维解一切BUG(2):实践原则的更多相关文章

  1. 工作中的Buff加成-结构化思考力:第一章:认识结构化思维及其作用

    一:引言 为了更好的说明结构思考力,我们先来做几个小测试. PS:如果你能做到,请留言,因为我要和你交好友,因为你是人才啊,可以挖一挖,挖到我的公司中. 第一个测试:请在三秒内记住下列数字.数字顺序不 ...

  2. 有效的结构化思维训练,MECE分析法

    MECE原则,表达精准分类与全面性的有效利器 结构化思维的本质就是逻辑,其目的在于对问题的思考更完整.更有条理,它帮助我们一个一个找到线头,理清思路,探求事物之间的相互联系.MECE分析法是一种结构化 ...

  3. 你真的了解字典(Dictionary)吗? C# Memory Cache 踩坑记录 .net 泛型 结构化CSS设计思维 WinForm POST上传与后台接收 高效实用的.NET开源项目 .net 笔试面试总结(3) .net 笔试面试总结(2) 依赖注入 C# RSA 加密 C#与Java AES 加密解密

    你真的了解字典(Dictionary)吗?   从一道亲身经历的面试题说起 半年前,我参加我现在所在公司的面试,面试官给了一道题,说有一个Y形的链表,知道起始节点,找出交叉节点.为了便于描述,我把上面 ...

  4. 结构化CSS设计思维

    LESS.SASS等预处理器给CSS开发带来了语法的灵活和便利,其本身却没有给我们带来结构化设计思维.很少有人讨论CSS的架构设计,而很多框架本身,如Bootstrap确实有架构设计思维作为根基. 要 ...

  5. 详解Google-ProtoBuf中结构化数据的编码

    本文的主要内容是google protobuf中序列化数据时用到的编码规则,但是,介绍具体的编码规则之前,我觉得有必要先简单介绍一下google protobuf.因此,本文首先会介绍一些google ...

  6. NumPy之:结构化数组详解

    目录 简介 结构化数组中的字段field 结构化数据类型 创建结构化数据类型 从元组创建 从逗号分割的dtype创建 从字典创建 操作结构化数据类型 Offsets 和Alignment Field ...

  7. Bigtable:一个分布式的结构化数据存储系统

    Bigtable:一个分布式的结构化数据存储系统 摘要 Bigtable是一个管理结构化数据的分布式存储系统,它被设计用来处理海量数据:分布在数千台通用服务器上的PB级的数据.Google的很多项目将 ...

  8. 视频结构化 AI 推理流程

    「视频结构化」是一种 AI 落地的工程化实现,目的是把 AI 模型推理流程能够一般化.它输入视频,输出结构化数据,将结果给到业务系统去形成某些行业的解决方案. 换个角度,如果你想用摄像头来实现某些智能 ...

  9. Shell 语法之结构化命令(流程控制)

    许多程序在脚本命令之间需要某种逻辑流控制,允许脚本根据变量值的条件或者其他命令的结果路过一些命令或者循环执行这些命令.这些命令通常被称为结构化命令.和其他高级程序设计语言一样,shell提供了用来控制 ...

  10. 第25章 SEH结构化异常处理_未处理异常及向量化异常

    25.1 UnhandledExceptionFilter函数详解 25.1.1 BaseProcessStart伪代码(Kernel32内部) void BaseProcessStart(PVOID ...

随机推荐

  1. CMU15-445 Project4 Concurrency Control心得

    一.概述 过瘾!过瘾!过瘾!P4 真过瘾!写 P3 的博客时我说过"感觉自己在数据库方面真正成长了",但写完 P4 之后最大的感受就是,我终于理解了 andy 在第一课说过的&qu ...

  2. Kerberos、黄金票据与白银票据

    kerberos Kerberos是一个网络认证协议,用于验证用户和服务之间的身份,解决分布式计算环境中的身份验证问题.它使用加密技术来提供安全的身份验证,并防止网络中的身份欺骗攻击.Kerberos ...

  3. git报错:SSL certificate problem: unable to get local issuer certificate

    原因:在windows系统中git没有获取到ssl证书 解决方案 输入以下命令: git config --global http.sslBackend schannel 之后再执行操作就可以啦 另: ...

  4. 8 最全的零基础Flask教程

    最全的零基础Flask教程 1 Flask介绍 1.1 为什么要使用Flask Django和Flask是Python使用最多的两个框架 1.2 Flask是什么 Flask诞生于2010年,是Arm ...

  5. [nginx]lua读取请求体

    前言 nginx默认不读取请求体的数据,但可以通过$request_body内置变量来获取.$request_body存在内存中,如果它的字节大小超过nginx配置的client_body_buffe ...

  6. 3.你不知道的go语言控制语句

    目录 本篇前瞻 Leetcode习题9 题目描述 题目分析 代码编写 知识点归纳 控制结构 顺序结构(Sequence) 声明和赋值 算术运算符 位运算符 逻辑运算 分支结构 if 语句 switch ...

  7. 现代 CSS 解决方案:数学函数 Round

    在 CSS 中,存在许多数学函数,这些函数能够通过简单的计算操作来生成某些属性值,例如在现代 CSS 解决方案:CSS 数学函数一文中,我们详细介绍了 calc():用于计算任意长度.百分比或数值型数 ...

  8. 2.7 PE结构:重定位表详细解析

    重定位表(Relocation Table)是Windows PE可执行文件中的一部分,主要记录了与地址相关的信息,它在程序加载和运行时被用来修改程序代码中的地址的值,因为程序在不同的内存地址中加载时 ...

  9. 全网最详细Java-JVM

    Java-JVM ①JVM概述 ❶基本介绍 JVM:全称 Java Virtual Machine,一个虚拟计算机,Java 程序的运行环境(Java二进制字节码的运行环境) 特点: Java 虚拟机 ...

  10. Modbus转profinet网关连接位移计在1200程序控制案例

    Modbus转profinet网关连接位移计在1200程序控制案例 本案例讲述了兴达易控Modbus转profinet网关(XD-MDPN100)连接现场用台达LD-E镭射位移计检测控制在1200PL ...