关于调试的11个真相
原文来自斯坦福 cs106a 课程的一份讲义。因为翻译能力有限,所以原文也一并贴在下面了。
- 直觉和预感很好,只是你还得去验证它们。当预感和事实冲突时,事实总是胜出。这就是生活!
-
不要寻找复杂的解释。即使是最简单的疏忽或错别字都会造成非常诡异的行为。认真地看代码,不要想着代码太简单不可能出错,就对简单语句一扫而过。
-
代码出问题的线索在你变量的值以及条件语句的流程中。尽力去看事实是怎样的。电脑不会误导你。从事实出发。
-
要有系统性,要坚持不懈。别慌张!Bug 又不会在你的代码里乱动,也不会去欺骗或者躲避你。它只是呆在那个地方,每次都以相同的方式做着错误的事情。
-
如果你的代码一分钟前还好好的,现在却出问题了,那么你最后一次改动了什么?这是条超级可靠的经验法则,也就是为什么你的小组长告诉你代码要边写边测试,而不是到最后一起测试。
-
不要为了追踪 bug 去随意地改动代码。这就好像科学家在做实验时一次性更改了不止一个变量。这会让我们更难解释观察到的行为,而且你可能会引入新的 bug。
-
如果你发现有些代码错误,但是看起来跟你要追踪的 bug 并不相关,也要顺手修复这些代码错误。许多时候错误的代码与 bug 是相关联的或者是以你没有想象到的方式掩盖了bug。
-
你应当能够像福尔摩斯一样解释一系列的事实,测试和最终引导你找到 bug 的推论。而如果有一个 bug 而你又无法定位它,你应当尝试去跟一个认真的第三方论证为什么你的每一个函数不可能有 bug。其中一份论证会有漏洞,因为你的某个函数事实上有 bug。尝试构建论证可能会帮助你发现这个漏洞。
-
对自己代码的信心要有批判心态。当你直觉某个函数是无辜的,那几乎不可能发现这个函数中的 bug。只有当事实证明毫无疑问某个函数不是问题的源头,你才可以假定它是正确的。
-
尽管你需要系统地 debug,但还是会需要信心、预感和猜测等。在你系统性地搜寻 bug 时,用你的直觉去指导搜寻的顺序。先去检查你最怀疑的函数。好的直觉从经验中获得。
-
debug 依靠客观和理性的路径。它依赖对你的代码作用的理解以及全局的合理判断。debug 比写代码还要耗费心智。当你尝试追踪 bug 而无果的时间越长,你会越不能理智判断。当你意识到无法对你的代码 debug 进行理智判断时,休息一下,睡个觉。当你思路不清时你没法 debug。很多时候一个程序员在深夜花费数个小时去定位 bug 却最终在凌晨4点放弃。第二天他们10分钟内就找到了 bug。什么让他们能够在第二天这么快地找到 bug?也许他们只是需要睡眠以及合理判断恢复的时间。或者可能他们的潜意识在他们睡觉的时候想出来了。不管怎样,「去干会别的事情,回来,然后立即找到 bug 」这样的场景太常见,不可能只是意外。
以下是原文:
-
Intuition and hunches are great—you just have to test them out. When a hunch and a fact collide, the fact wins. That’s life in the city.
-
Don’t look for complex explanations. Even the simplest omission or typo can lead to very weird behavior. Everyone is capable producing extremely simple and obvious errors from time to time. Look at code critically—don’t just sweep your eye over that series of simple statements assuming that they are too simple to be wrong.
-
The clue to what is wrong in your code is in the values of your variables and the flow of control. Try to see what the facts are pointing to. The computer is not trying to mislead you. Work from the facts.
-
Be systematic and persistent. Don’t panic. The bug is not moving around in your code, trying to trick or evade you. It is just sitting in one place, doing the wrong thing in the same way every time.
-
If you code was working a minute ago, but now it doesn’t—what was the last thing you changed? This incredibly reliable rule of thumb is the reason your section leader told you to test your code as you go rather than all at once.
-
Do not change your code haphazardly trying to track down a bug. This is sort of like a scientist who changes more than one variable in an experiment at a time. It makes the observed behavior much more difficult to interpret, and you tend to introduce new bugs.
-
If you find some wrong code that does not seem to be related to the bug you were tracking, fix the wrong code anyway. Many times the wrong code was related to or obscured the bug in a way you had not imagined.
-
You should be able to explain in Sherlock Holmes style the series of facts, tests, and deductions that led you to find a bug. Alternately, if you have a bug but can’t pinpoint it, then you should be able to give an argument to a critical third party detailing why each one of your functions cannot contain the bug. One of these arguments will contain a flaw since one of your functions does in fact contain a bug. Trying to construct the arguments may help you to see the flaw.
-
Be critical of your beliefs about your code. It’s almost impossible to see a bug in a function when your instinct is that the function is innocent. Only when the facts have proven without question that the function is not the source of the problem should you assume it to be correct.
-
Although you need to be systematic, there is still an enormous amount of room for beliefs, hunches, guesses, etc. Use your intuition about where the bug probably is to direct the order that you check things in your systematic search. Check the functions you suspect the most first. Good instincts will come with experience.
-
Debugging depends on an objective and reasoned approach. It depends on overall perspective and understanding of the workings of your code. Debugging code is more mentally demanding than writing code. The longer you try to track down a bug without success, the less perspective you tend to have. Realize when you have lost the perspective on your code to debug. Take a break. Get some sleep. You cannot debug when you are not seeing things clearly. Many times a programmer can spend hours late at night hunting for a bug only to finally give up at 4:00A.M. The next day, they find the bug in 10 minutes. What allowed them to find the bug the next day so quickly? Maybe they just needed some sleep and time for perspective. Or maybe their subconscious figured it out while they were asleep. In any case, the ―go do something else for a while, come back, and find the bug immediately‖ scenario happens too often to be an accident.
— Nick Parlante, Stanford University