如何快速有效地阅读别人的代码

终极教程:如何快速有效地阅读别人的代码

有一天,一名自学编程的程序员问了我一个问题:

“你是如何理解别人的代码?我现在看自己的代码感觉很舒服,但每当试着看别人写的东西时,都觉得自己完全晕菜了。我知道读别人的代码不容易,特别是如果一些代码只有很少(或根本没有)文档的话。但我现在根本就一点头绪也没有。能不能给我一点点提示?非常感谢!”

我很喜欢这个问题,这主要有以下两个原因:

  1. 更好地阅读和理解别人代码的方法,也能帮助你更好地理解自己的代码,并帮助你更快速更容易地理解你遇到的各种新代码。
  2. 它揭示了学习一门新技能(如编程)的最重要方面之一:你需要大量接触高质量的专业实例。

这需要很多克服许多不同的阻碍。让我们从头开始吧。

阅读并理解其他人的代码,最好的方法是什么?

在我看来,阅读并理解他人的代码,最好的方式就是:

1. 在代码中选一个你已知的结果(功能),然后从结尾开始,逐步反推出代码中每一步的操作

举个栗子,你知道你看的这段代码,最后会生成一个包含许多影片清单的文件。于是,你得首先在代码里找到生成那个文件的具体代码,定位这个生成操作在代码中的哪几行。

接着往回找,看看代码是如何把数据写入文件的。

再接着看上一步,这些数据是哪里来的。

就这样一步一步,直到你把整个来龙去脉都弄懂为止。

这类彼此相连的代码,我们称之为“操作链”。

使用这种方法,你必然会循着“操作链”浏览代码的各种不同部分。这将会让你了解有关代码的这些信息:

  • 代码的本体是如何组织的(在哪里声明/定义变量,不同的函数在什么位置,等等)
  • 作者的代码风格如何
  • 代码作者是如何思考并解决问题的(这部分比较难以描述,但当你看得多了,你就能从直观上察觉出来)

在这么做之后,你将会逐渐熟悉代码的全貌,理解它的构成。也就是说,你刚开始可能面对的是:

1
[ 满屏幕花花绿绿的代码,完全看不出有什么意义 ]

而之后你面对的将是:

1
[ 还是满屏幕花花绿绿的代码,但这其中的几段我知道它们是干什么的 ]

这就像是你站在一间伸手不见五指的漆黑房间里,接着,有一盏一盏的小灯在房间的各处亮了起来,让你能看清一小块一小块的细节。

img

使用“操作链”的方式梳理代码,能让你逐步了解之前难以读懂的代码片段

2. 重复、重复再重复

多次重复这样的过程,你就会快速地理解整个代码库中的各个部分。

就像上面漆黑房间里的灯一样,随着你对代码功能的理解,代码的各个部分也会逐渐在你面前“点亮”,在这些光亮的照耀下,房间的全貌就将渐渐显露在你眼前。

这个办法为什么能生效?原因是,不管在什么情况下,代码体系都被设计为解决一个(或多个)复杂问题。 因此,只要你抓牢那些“操作链”,整个逻辑关系就不会散开。

况且,随着你对代码的理解加深,你会更明白代码之间的不同部分是如何链接的,也就越能从整体上理解整个代码库

最后,随着时间的推移,你看到的(好)代码越多,你就越容易阅读并理解所有的代码,所需的时间也越少

……而这就把我们带到了我喜欢这个问题的第二个原因:它指出了接触大量、高质量的实际案例,在个人学习中的重要性。

在编程领域,“高质量的实际案例” = 好的代码。

接触大量、高质量的实际案例,在个人学习中的重要性

O’Reilly “深入浅出”系列书籍的合著者之一,凯西·赛拉(Kathy Sierra)在她的新书《用户思维+好产品让用户为自己尖叫》(Badass: Making Users Awesome)中提到,接触大量、高质量的专业实例,是决定人们能否快速有效地学习新技能的两个主要因素之一(另一个因素是坚持练习)。

“你观看(或倾听)专业实例的次数越多,你就能变得更好。你接触的专家或专家的工作结果越少,你培养专业技能的可能性就越小。”

让我们来看看这个显而易见(并不)的,和本文的主题非常相关(才怪)的例子:如何区分小鸡的性别。

别笑,事实上,它是上述概念的一个很好的证明。

从区分小鸡性别中学习(是,你没看错)

什么叫区分小鸡的性别?这跟我们从大量高质量的实例中学习有什么关系?凯西是这样解释的:

“众所周知,确定新生小鸡的性别是相当难的。但对于大型商业养鸡场来说,雌性越早与雄性分开,它们就能越早地进入蛋鸡养殖生产。在 20 世纪初,日本人开发了一种特殊的小鸡性别鉴定方法,并出现了一些专家(可靠、准确的小鸡性别鉴定师)。
很好,那么我们可以让这些专家训练其他人了,对吧?这只剩一个问题:当被问到具体鉴定方式的时候,专家并不能很明确地说出他们是怎么做到的,他们就是‘就是看出来了’。”

那么他们该如何开始培训呢?好吧,假设你是一个新的小鸡性别鉴定学徒,站在一个装满小鸡的箱子前。问题是:在你看来,它们完全一样啊。但是,你被告知,随便抓起一只,猜猜它的性别。就你当前的状况而言,你只能完全随机地蒙一个。但赛拉是这样说的:

“在每次乱来、随机、完全搞不清楚状况的猜测之后,负责教你的专家都会给你一个反馈。对、错、错、对。你仍然不知道专家是如何“知道”的,但你就还是一遍又一遍地这样做。

最后,有什么事情发生了。你的正确率开始超过随机猜测的正确率。随着时间的推移,你的准确率越来越高。但你还是不知道为什么。如你所知,你仍然只是凭着直觉去猜,但现在好像有某种“神秘”的力量将你的手引向正确的答案。”

这种“魔法”是怎么出现的?赛拉的总结是:

“经过接触足够多的反馈,你的大脑开始在潜意识中检测模式和底层结构,而并不通过意识。随着经验的增加,你的大脑会对感知进行微调,并最终计算出真正重要的细节区别。即使你不能解释你为什么这样选择,你的大脑也从噪音中判断出更细微的差别,并将其区分出来。
感性认识包括我们所认为的“专家直觉”。能够立即知道棋子下一步应该怎么走,或者察觉出一幅画是伪造的,或者感觉火灾现场快要引发爆炸,或者觉得这段代码有问题——即使你并不是总能用言语表达出来。”

img

专家如何使用潜意识中的感性认识
来自《用户思维+好产品让用户为自己尖叫》第 134 页,作者 凯西·赛拉

这在编程中又起到什么作用?

最重要的是,这让我们知道,你编程的时间越长,你看到的(各种不同类型的)代码实例就越多,也就越容易理解其他人的代码,理解的速度也越快。

这是一个很棒的正反馈循环:你阅读更多的代码,就能够更快、更有效地理解它;于是你可以理解消化更多的代码……

而且,这还不算完:它也会给你自己的代码带来巨大的有益影响。 为什么会这样?

  1. 你将能够更快地理解在编程期间不可避免地会引用的代码和示例(例如,来自在线教程的代码,或是来自 StackOverflow 帖子的代码段等)。
  2. 你将能够一目了然地理解你过去编写的代码。(并且,在未来的职业生涯中,你将不可避免地同时处理许多不同的代码片段,因此这种能力可以给你带来很大的好处。)

最后,这些能力将给你带来

  1. 更少的停顿
  2. 更大的进步

也就是 => “更有趣,更愉快”。棒不棒?

试过以后,你也会爱上它的……

(译注:这怎么很像对着自己的大脑进行有监督强化学习……)