Skip to content

Commit ed0cea2

Browse files
committed
revert_miss_ci
1 parent 3976acf commit ed0cea2

File tree

43 files changed

+445
-442
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+445
-442
lines changed
Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1-
# Learn to Debug
1+
# 学会 Debug
22

3-
Debugging is the cornerstone of being a programmer. The first meaning of the verb "debug" is to remove errors, but the meaning that really matters is to see into the execution of a program by examining it. A programmer that cannot debug effectively is blind.
3+
调试(Debug)是成为一个程序员的基石。调试这个词第一个含义即是移除错误,但真正有意义的含义是,通过检查来观察程序的运行。一个不会调试的程序员等同于瞎子。
44

5-
Idealists, those who think design, analysis, complexity theory, and the like are more fundamental than debugging, are not working programmers. The working programmer does not live in an ideal world. Even if you are perfect, you are surrounded by and must interact with code written by major software companies, organizations like GNU, and your colleagues. Most of this code is imperfect and imperfectly documented. Without the ability to gain visibility into the execution of this code, the slightest bump will throw you permanently. Often this visibility can be gained only by experimentation: that is, debugging.
5+
理想主义者认为设计、分析、复杂的理论或其他东西,是更基本的东西,他们不是现实的程序员。现实的程序员不会活在理想的世界里。即使你是完美的,你也需要与在你周围的主要软件公司或组织 (比如 GNU ) 的代码,和你同事写的代码打交道。这里面大部分的代码以及它们的文档是不完美的。如果不能看透代码的具体执行过程,最轻微的颠簸都会把你永远地抛出去。通常这种可见性只能从实验获得,也就是,调试。
66

7-
Debugging is about the running of programs, not programs themselves. If you buy something from a major software company, you usually don't get to see the program. But there will still arise places where the code does not conform to the documentation (crashing your entire machine is a common and spectacular example), or where the documentation is mute. More commonly, you create an error, examine the code you wrote, and have no clue how the error can be occurring. Inevitably, this means some assumption you are making is not quite correct or some condition arises that you did not anticipate. Sometimes, the magic trick of staring into the source code works. When it doesn't, you must debug.
7+
调试是一件与程序运行相关的事情,而非与程序本身相关。你从主要的软件公司购买一些产品,你通常不会看到(产品背后的)程序本身。但代码不遵循文档的情况(让你整台机器崩掉是一个常见又特殊的例子)或者文档没有说明的情况仍然会出现。更常见的是,你的程序出现了一个错误,当你检查你写的代码的时候,却不知道这个错误是怎么发生的。不可避免的,这意味着你做的一些假设并不对,或者一些你没有预料到的情况发生了。有时候,神奇的修改源代码的技巧可能会生效。当它无效时,你必须调试了。
88

9-
To get visibility into the execution of a program you must be able to execute the code and observe something about it. Sometimes this is visible, like what is being displayed on a screen, or the delay between two events. In many other cases, it involves things that are not meant to be visible, like the state of some variables inside the code, which lines of code are actually being executed, or whether certain assertions hold across a complicated data structure. These hidden things must be revealed.
9+
为了获得一个程序执行过程的可见性,你必须能够执行代码并且从这个过程中观察到什么。有时候这是显而易见的,比如一些正在呈现在屏幕上的东西,或者两个事件之间的延迟。在许多其他的案例中,调试与一些不一定可见的东西相关,比如代码中一些变量的状态,哪一行代码正在被执行,或者一些断言是否持有了一个复杂的数据结构。这些隐藏的细节必须被显露出来。
1010

11-
The common ways of looking into the ‘innards’ of an executing program can be categorized as:
1211

13-
- Using a debugging tool,
14-
- Printlining - Making a temporary modification to the program, typically adding lines that print information out, and
15-
- Logging - Creating a permanent window into the programs execution in the form of a log.
12+
观察一个正在执行程序的内部的方法通常可按如下分类:
1613

17-
Debugging tools are wonderful when they are stable and available, but the printlining and logging are even more important. Debugging tools often lag behind language development, so at any point in time they may not be available. In addition, because the debugging tool may subtly change the way the program executes it may not always be practical. Finally, there are some kinds of debugging, such as checking an assertion against a large data structure, that require writing code and changing the execution of the program. It is good to know how to use debugging tools when they are stable, but it is critical to be able to employ the other two methods.
14+
- 使用一个调试工具;
15+
- Printlining[(戳这里看释义)](../../4-Glossary.md) - 对程序做一个临时的修改,通常是加一些行去打印一些信息;
16+
- 日志 - 用日志的形式为在程序的运行中创建一个永久的视窗。
1817

19-
Some beginners fear debugging when it requires modifying code. This is understandable - it is a little like exploratory surgery. But you have to learn to poke at the code and make it jump; you have to learn to experiment on it and understand that nothing that you temporarily do to it will make it worse. If you feel this fear, seek out a mentor - we lose a lot of good programmers at the delicate onset of their learning to this fear.
18+
当调试工具稳定可用时,它们是非常美妙的,但 [Printlining](../../4-Glossary.md) 和写日志甚至是更加重要的。调试工具通常落后于编程语言的发展,所以在某些时候它们都可能是无效的。另外,调试工具可能轻微改变程序实际执行的方式。最后,调试有许多种,比如检查一个断言和一个巨大的数据结构,这需要写代码并改变程序的运行。当调试工具可用时,知道如何使用调试工具是一件好事,但学会使用其他两种方式也是至关重要的。
2019

21-
Next [How to Debug by Splitting the Problem Space](02-How to Debug by Splitting the Problem Space.md)
20+
当调试需要修改代码的时候,一些初学者会感到害怕。这是可以理解的,这有点像探索型外科手术。但你需要学会打破代码,让它跳起来,你需要学会在它上面做实验,并且需要知道你临时对它做的任何事情都不会使它变得更糟。如果你感受到了这份恐惧,找一位导师 - 就是因为许多人在一开始面对这种恐惧的的时候表现的太脆弱,我们因此失去了很多本可以变成优秀程序员的人。
21+
22+
Next [如何通过分离问题空间来 Debug](02-How to Debug by Splitting the Problem Space.md)
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
# How to Debug by Splitting the Problem Space
1+
# 如何通过分割问题 Debug
22

3-
Debugging is fun, because it begins with a mystery. You think it should do something, but instead it does something else. It is not always quite so simple---any examples I can give will be contrived compared to what sometimes happens in practice. Debugging requires creativity and ingenuity. If there is a single key to debugging it is to use the divide and conquer technique on the mystery.
3+
调试是有趣的,因为它一开始是个迷。你认为它应该这样做,但实际上它却那样做。很多时候并不仅是这么简单---我给出的任何例子都会被设计来与一些偶尔在现实中会发生的情况相比较。调试需要创造力与智谋。如果说调试有简单之道,那就是在这个谜题上使用分治法。
44

5-
Suppose, for example, you created a program that should do ten things in a sequence. When you run it, it crashes. Since you didn't program it to crash, you now have a mystery. When you look at the output, you see that the first seven things in the sequence were run successfully. The last three are not visible from the output, so now your mystery is smaller: ‘It crashed on thing #8, #9, or #10.’
5+
假如,你创建了一个程序,它会依次执行十件事情。当你运行它的时候,它却崩溃了。但你本来的目的并不是想让它崩溃,所以现在一个谜题扔给你了。当你查看输出时,你可以看到序列里前七件事情运行成功了。最后三件事情在输出里却看不到,所以你的谜题变小了:“它是在执行第8、9、10件事的时候崩溃的”。
66

7-
Can you design an experiment to see which thing it crashed on? Sure. You can use a debugger or we can add printline statements (or the equivalent in whatever language you are working in) after #8 and #9. When we run it again, our mystery will be smaller, such as ‘It crashed on thing #9.’ I find that bearing in mind exactly what the mystery is at any point in time helps keep one focused. When several people are working together under pressure on a problem it is easy to forget what the most important mystery is.
7+
你是否可以设计一个实验来观察它是在哪件事情上崩溃呢?当然,你可以用一个调试器或者我们可以在第8第9件事后面加一些[printlining](../../4-Glossary.md)的语句(或者你正在使用的任何语言里的等价的事情),当我们重新运行它的时候,我们的谜题会变得更小,比如“它是在做第九件事的时候崩溃的”。我发现,把谜题是怎样的一直清楚地记在心里能让我们保持注意力。当几个人在一个问题的压力下一起工作时,很容易忘记最重要的谜题是什么。
88

9-
The key to divide and conquer as a debugging technique is the same as it is for algorithm design: as long as you do a good job splitting the mystery in the middle, you won't have to split it too many times, and you will be debugging quickly. But what is the middle of a mystery? There is where true creativity and experience comes in.
9+
调试技术中分治的关键和算法设计里的分治是一样的。你只要从中间开始划分,就不用划分太多次,并且能快速地调试。但问题的中点在哪里?这就是真正需要创造力和经验的地方了。
1010

11-
To a true beginner, the space of all possible errors looks like every line in the source code. You don't have the vision you will later develop to see the other dimensions of the program, such as the space of executed lines, the data structure, the memory management, the interaction with foreign code, the code that is risky, and the code that is simple. For the experienced programmer, these other dimensions form an imperfect but very useful mental model of all the things that can go wrong. Having that mental model is what helps one find the middle of the mystery effectively.
11+
对于一个真正的初学者来说,可能发生错误的地方好像在代码的每一行里都有。一开始,你看不到一些你稍后开发的时候才会看到的其它纬度,比如执行过的代码段,数据结构,内存管理,与外部代码的交互,一些有风险的代码,一些简单的代码。对于一个有经验的程序员,这些其他的维度为整个可能出错的事情展示了一个不完美但是有用的思维模型。拥有这样的思维模型能让一个人更高效地找到谜题的中点。
1212

13-
Once you have evenly subdivided the space of all that can go wrong, you must try to decide in which space the error lies. In the simple case where the mystery is: ‘Which single unknown line makes my program crash?’, you can ask yourself: ‘Is the unknown line executed before or after this line that I judge to be executed in the middle of the running program?’ Usually you will not be so lucky as to know that the error exists in a single line, or even a single block. Often the mystery will be more like: ‘Either there is a pointer in that graph that points to the wrong node, or my algorithm that adds up the variables in that graph doesn't work.’ In that case you may have to write a small program to check that the pointers in the graph are all correct in order to decide which part of the subdivided mystery can be eliminated.
13+
一旦你最终划分出了所有可能出错的地方,你必须试着判断错误躲在哪个地方。比如:这样一个谜题,哪一行未知的代码让我的程序崩溃了?你可以这样问自己,出错的代码是在我刚才执行的程序中间的那行代码的前面还是后面?通常你不会那么幸运就能知道错误在哪行代码甚至是哪个代码块。通常谜题更像这个样子的:“图中的一个指针指向了错误的结点还是我的算法里变量自增的代码没有生效?”,在这种情况下你需要写一个小程序去确认图中的指针是否都是对的,来决定分治后的哪个部分可以被排除。
1414

15-
Next [How to Remove an Error](03-How to Remove an Error.md)
15+
Next [如何移除错误](03-How to Remove an Error.md)
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
# How to Remove an Error
1+
# 如何移除一个错误
22

3-
I've intentionally separated the act of examining a program's execution from the act of fixing an error. But of course, debugging does also mean removing the bug. Ideally you will have perfect understanding of the code and will reach an ‘A-Ha!’ moment where you perfectly see the error and how to fix it. But since your program will often use insufficiently documented systems into which you have no visibility, this is not always possible. In other cases the code is so complicated that your understanding cannot be perfect.
3+
我曾有意把检查程序执行和修复错误分割开来,但是当然,调试也意味着移除 bug。理想状况下,当你完美的发现了错误以及它的修复方法时,你会对代码有完美的理解,并且有一种顿悟(啊哈!)的感觉。但由于你的程序会经常使用其他不具有可视性的、没有一致性注释的系统(比如第三方库),所以完美是不可能的。在其他情况下,可能代码是如此的复杂以至于你的理解可能并不完美。
44

5-
In fixing a bug, you want to make the smallest change that fixes the bug. You may see other things that need improvement; but don't fix those at the same time. Attempt to employ the scientific method of changing one thing and only one thing at a time. The best process for this is to be able to easily reproduce the bug, then put your fix in place, and then rerun the program and observe that the bug no longer exists. Of course, sometimes more than one line must be changed, but you should still conceptually apply a single atomic change to fix the bug.
5+
在修复 bug 时,你可能想要做最小的改变来修复它。你可能看到一些其他需要改进的东西,但不会同时去改进他们。请使用科学的方法去改进一个东西,并且一次只改变一个东西。修复 bug 最好的方式是能够重现 bug,然后把你的修复替换进去,重新运行你的程序,观察,直到 bug 不再出现。当然,有时候不止一行代码需要修改,但你在逻辑上仍然需要使用一个独立原子(译者注:以前人们认为原子不可再分,所以用用原子来代表不可再分的东西)的改变来修复这个 bug
66

7-
Sometimes, there are really several bugs that look like one. It is up to you to define the bugs and fix them one at a time. Sometimes it is unclear what the program should do or what the original author intended. In this case, you must exercise your experience and judgment and assign your own meaning to the code. Decide what it should do, and comment it or clarify it in some way and then make the code conform to your meaning. This is an intermediate or advanced skill that is sometimes harder than writing the original function in the first place, but the real world is often messy. You may have to fix a system you cannot rewrite.
7+
有时候,可能实际上有几个 bug,但表现出来好像是一个。这取决于你怎么定义 bug,你需要一个一个地修复它们。有时候,程序应该做什么或者原始作者想要做什么是不清晰的。在这种情况下,你必须多加练习,增加经验,评判并为代码赋予你自己的认知。决定它应该做什么,并注释或用其他方式阐述清楚,然后修改代码以遵循你赋予的含义。这是一个进阶或高级的技能,有时甚至比一开始用原始的方式创建这些代码还难,但真实的世界经常是混乱的。你必须修复一个你不能重写的系统。
88

9-
Next [How to Debug Using a Log](04-How to Debug Using a Log.md)
9+
Next [如何使用日志调试](04-How to Debug Using a Log.md)

0 commit comments

Comments
 (0)