背景
最近经常会有人找我问一些非常有趣,但是又非常玄学的问题。这类玄学问题我指的是正常情况下明明能工作,现在却不知为何无法工作的情况。
这些问题往往和非常多的难以预料的因素(例如环境)有关。例如:为什么我无法将一个文件签入到git?
解决大部分玄学问题,往往需要我主动在他的电脑上进行大量操作、环境分析,才能知道到底是哪里对程序产生了影响。或往往需要我反复沟通数十条消息才能真正判断问题所在。而且这类问题,由于正常情况下是能工作的,所以非常难以通过Google和Stack Overflow解决。
后来我想,与其每次都花费大量时间帮别人解决问题,不如抽象出一套能够解决上述问题的通用方法,来让大部分人能够自行解决这些问题。
夹逼调试法由此诞生。
夹逼调试法
夹逼调试法,指的是通过两个方向共同限制作用,使得问题根源的可能范围集中在最小化的条件变化中。
夹逼调试法适用于解决:
平时或在理想情况下工作正常,而在某些环境中能够稳定工作不正常的错误。
执行方法
夹逼调试法的执行方法为:
首先你已知了一个环境中 E1,程序 P 出现了一个异常现象 A。
此时,你需要构建一个尽可能理想的环境 E2。所谓理想的环境,即:满足程序 P 不出异常现象的所有条件。
构建环境 E2 后,在 E2 中运行 P。
如果 P 出现了异常现象 A,则证明 P 本身存在设计缺陷。
如果 P 并没有出现异常现象 A,则证明是环境 E1 和环境 E2 的差异导致了 A。
此时我们需要探究是 E1 和 E2 的何种差异导致了A。
将 E1 环境进行过的配置操作流程与 E2 环境进行差异对比。得到一个差异集合 C = { D1, D2, D3 ... Dn }。且C不是空集。
分别将每个在 C 中的差异 D 去应用给 E1,使得E1 更加接近 E2。
在每个差异 D 应用后,在 E1 中重新运行 P。
如果 P 此时开始出现异常现象 A,则证明 D 可能是导致了 A 的原因。
如果 P 仍然没有出现异常现象 A,则证明 D 可能和 A 无关。
回滚差异 D。
分别将每个在 C 中的差异 D 去应用给 E2,使得E2 更加接近 E1。
在每个差异 D 应用后,在 E2 重新运行 P。
如果 P 仍然出现了异常现象 A,则证明 D 可能和 A 无关。
如果 P 此时不再出现异常现象 A,则证明 D 可能是导致了 A 的原因。
回滚差异 D。
此时,我们已经得知了是哪些可能的因素会导致 A 发生。
人类语言表述
对于一个发生的bug,我们可以构建一个理想环境,使得理想环境下不会发生这个Bug。然后列出出现Bug的环境和理想环境有哪些差异。
分别改变这些差异,使得理想环境和故障环境互相接近靠拢。
观察最终是哪一个差异能够真正导致故障。
备注
夹逼调试法,只能找到“可能的条件”。而不是“必要”、“充分”、”充分且必要“的。
这是考虑到条件的组合可能会影响结果。因此夹逼调试法只适用于需要快速定位可能的原因的情况。
例题1
已知我的电脑无法正常运行Spotify。请问是为什么?
首先构建一个理想环境。使用最新版Windows 10专业版,在一个全新的今年发售的电脑上全新安装。然后完成所有系统更新,确保国际网络畅通。并通过Spotify官网下载安装Spotify,然后启动Spotify。
此时大概率Spotify能够正常工作。此时我们开始比较故障环境和理想环境的差异:
- 故障环境使用了中文操作系统,而理想环境使用了英文操作系统
- 故障环境连接了中国网络,而理想环境使用了国际网络
- 故障环境没有安装最新的系统更新,而理想环境安装了系统更新
- 故障环境使用了Windows 10 N,而理想环境使用了Windows 10专业版
- 故障环境是在某个盗版小网站下载的Spotify,而理想环境是在Spotify官网下载的Spotify
- 故障环境里还额外安装了300多个其他软件,C盘只剩余3%的空间。而理想环境没有安装任何其它的软件,C盘剩余95%的空间
然后我们开始夹逼调试。从故障环境逼近理想环境开始。
- 给故障环境切换为国际网络。观察发现:仍然不正常运行。
- 给故障环境切换为英文操作系统。观察发现:仍然不正常运行。
- 给故障环境安装最新的系统更新。观察发现:仍然不正常运行。
- 给故障环境去Spotify官网下载Spotify。观察发现:仍然不正常运行。
然后此时继续从故障环境向理想环境逼近已经有些困难。我们转而从理想环境向故障环境逼近:
- 给理想环境也额外安装故障环境安装的300多个其他软件。发现理想环境仍然正常。
- 给理想环境从Windows 10专业版降级为Windows 10 N。发现理想环境不再正常。此时,Windows是否使用了带N的版本,为可能的原因。
之后我们再去故障环境验证这个原因:
- 给故障环境切换为Windows 10专业版。此时观察发现:故障消失。
综上,我们得到了:Windows 是否是带N的版本,可能会影响Spotify的运行。
例题2
已知一个飞机的驾驶室里有10个开关和一个启动键。每个开关分别都对应着开、关两个位置。
我们曾经将10个开关全部扳到 开 位置,此时按下启动键,飞机就能成功启动发动机。
但是今天,我们试图启动飞机。但是飞机无法启动。已知此时10个开关全部都是 关 位置。你需要快速知道大概是为什么,飞机无法启动。
执行夹逼调试法。
首先将10个开关全部扳到 开,验证飞机确实能启动。
依次尝试关闭其中每一个开关。如果飞机不能启动了,证明这个开关对于飞机启动可能是必要的。
如果上述方法遇到障碍,或成本过高,或执行缓慢,则:
将10个开关全部扳到 关。验证飞机确实不能启动。
依次尝试开启其中每一个开关。如果飞机能启动了,证明这个开关对于飞机启动可能是必要的。
首先,我要表示对您博客的欣赏。您提出了一个非常有趣且实用的方法,即夹逼调试法,来解决那些平时工作正常,但在特定环境中无法正常工作的问题。这种方法的核心思想是通过逐步缩小问题根源的可能范围,从而快速定位可能的原因。
您在博客中详细介绍了夹逼调试法的执行方法,包括构建理想环境、对比故障环境和理想环境的差异以及逐一应用差异来逼近另一个环境。这种方法的实用性和普适性使它成为解决此类问题的有效工具。
同时,您还提供了两个例子来说明如何应用夹逼调试法。这些例子非常生动形象,有助于读者更好地理解和掌握这种方法。特别是第一个例子,通过对比故障环境和理想环境的差异,最终找到了影响Spotify运行的可能原因。这充分展示了夹逼调试法的实际应用价值。
然而,我认为博客中还有一些可以改进的地方。首先,在介绍夹逼调试法的适用范围时,您提到它适用于“平时或在理想情况下工作正常,而在某些环境中能够稳定工作不正常的错误”。这里的表述可能会让读者产生困惑,建议将“能够稳定工作不正常”的描述改为“在某些环境中无法正常工作”。
其次,在执行方法部分,建议在每个步骤之间添加编号,以便读者更清晰地了解执行过程的顺序。同时,在描述应用差异的过程时,可以更详细地说明如何判断某个差异是否与问题相关,以及在发现可能的原因后如何进一步验证和解决问题。
最后,虽然您在博客中提到夹逼调试法只能找到“可能的条件”,而不是“必要”、“充分”、”充分且必要“的,但我认为这并不影响夹逼调试法的实用性。事实上,在许多情况下,快速找到可能的原因已经足够帮助我们解决问题。当然,如果有必要,我们可以在找到可能原因的基础上,进一步探究条件之间的关联性,以便更准确地确定问题根源。
总之,您的博客提供了一个非常有价值的方法来解决那些难以预料的问题。我相信这种方法将对许多人产生积极的影响。希望您能继续分享更多有趣且实用的方法,以帮助更多的人解决实际问题。再次感谢您的分享!
有木有可能是多个因素导致的一个错误,来个排列组合
机长,告诉我你负责哪个航班,我不坐就是了
使用此方法确认屏幕闪屏的原因和win11 无关,可能是显示器本身问题
Anduin nb
anduin nb