发布于 2026-01-06 8 阅读
0

从源代码中学习

从源代码中学习

这篇文章《从源代码中学习》最初发表于CodersCat 网站

前言

上周我和一位年轻的程序员聊天时,他问我:

“我该如何读懂代码?”

我们讨论了一段时间,我介绍了一些更高效地阅读源代码的方法。

“你应该就此写篇文章,”他当时建议道。

“这对初学者很有帮助。这种技能不是你能从书本或教程里学到的。”

好了,以下是我从源代码学习的一些技巧。

为什么我们需要阅读代码

作为程序员,我们每天都要接触源代码。经过多年的学习,大多数程序员都能“编写”代码,或者至少能够复制和修改代码。

读取代码光盘

然而,我们教授编程的方式强调的是编写代码的技巧,而不是如何阅读代码。我所说的“阅读代码”,指的是有意识地阅读源代码的实践

众所周知,编程和写作有很多共同之处。唐纳德·克努特甚至提出了文学编程的编程范式。编码和写作都拥有相同的共同目标:表达我们的想法

你还记得在学校是怎么学写作的吗?我们的写作能力源于阅读大量的文本,从小学开始就如此。多年来,我们阅读不同难度的伟大作家的作品,并练习各种写作技巧。

“如果你没有时间阅读,你就没有时间(或工具)写作。”

就这么简单。

——斯蒂芬·金在他的回忆录《写作之道》中写道。

正如斯蒂芬·金所观察到的那样,作家必须广泛而频繁地阅读,才能发展出自己的写作风格,并学习如何写句子和构建故事结构,从而吸引读者拿起他们的作品阅读。

就像读书一样,有意识地阅读代码能帮助程序员更快地成长,尤其对中级程序员而言更是如此。点击分享到推特

有意识地阅读代码有三个好处。

站在巨人的肩膀上

我们有机会向他人学习。优秀的源代码就像文学杰作,它不仅提供信息和知识,更能启迪人心。

通过浏览 Linux 内核、Redis、Nginx、Rails 或任何其他著名项目的源代码,您可以汲取世界各地成千上万顶级程序员的智慧。

这些项目中蕴藏着无数优秀的编程、范式选择、设计和架构范例。向他人学习的另一个好处是能够避免常见的陷阱。大多数错误都已被他人犯过。

读取代码光盘

解决难题

在你的编程生涯中,你最终会遇到一些无法通过谷歌搜索解决的问题。如果你还没遇到过这类问题,那只能说明你的编程经验还不够丰富。阅读源代码是解决这类问题的有效方法,也是学习新知识的绝佳机会。

读取代码光盘

拓展你的局限

大多数程序员只专注于少数几个特定领域。一般来说,如果你不不断挑战自我,你的编程技能最终只会停留在同事的平均水平。不要满足于仅仅修复一些bug或为现有系统添加一些无关紧要的功能。相反,你应该尝试拓展到新的领域,不断寻找你日常工作中未曾涉足但又感兴趣的新领域。这将拓宽你对编程的整体理解。

要阅读哪种类型的源代码

好的,所以阅读源代码是有好处的。接下来的问题是,面对如此多的优秀作品,我们应该阅读哪种源代码呢?

首先,你必须选择一个目标。如果没有这个焦点,你试图了解问题的根源的努力就会收效甚微。

以下是一些典型场景:

  1. 当你想学习一门新的编程语言时,学习它不仅仅意味着学习语法。然而,在学习一门新语言时,阅读源代码是一种非常高效的学习方法。我从rust-rosetta项目中学到了很多关于 Rust 的知识。Rosetta Code是一个收集了各种编程语言中常见任务解决方案的项目,对于学习一门新的编程语言来说,它是一个非常有用的资源。

读取代码光盘

  1. 当你想了解某个特定的算法或实现时,例如,我们都使用过标准库中的排序函数。你是否曾经好奇过它是如何实现的?或者假设你需要使用 Redis 中的 Set 数据结构,那么它的实现中使用了哪些数据结构呢?为此,你只需要查看项目中与实现相关的部分,通常只有几个文件或函数。

  2. 当你使用某个特定的框架进行编码时,这意味着你已经对该框架有一定的了解,因此,阅读该框架的部分源代码是一个不错的选择。显然,了解其源代码将有助于你更好地理解框架。

读取代码光盘

  1. 当你想涉足一个新领域时,不妨阅读该领域的经典知名项目。例如,既然你在做 Web 开发,分布式系统是否让你感兴趣?如果是,并且你了解 Go 语言,那么etcd或许是个不错的选择。你想深入了解操作系统内部机制吗?那么xv6或许是个不错的起点。如今 GitHub 上有很多优秀的开源项目,我们正处于一个充满机遇的时代。不妨找几个来了解一下。

记住,选择项目时要根据你当前的编程技能和知识水平来定。如果选择的项目远远超出你的能力范围,最终只会让你感到沮丧。先阅读一些较小的项目,然后再尝试更大的项目。

如果你一时无法理解某段代码,说明你存在知识盲区。先把代码放在一边,尝试阅读一些书籍、论文或其他相关资料,等你更有信心后再回来继续研究。

我们总是按照某种模式取得进步:阅读(代码、书籍、论文)、写作、阅读更多、写作更多。

如何阅读源代码

《如何阅读一本书》是一本指导如何进行高效阅读的指南。对于初学者来说,如何阅读代码也是一门值得投入时间和精力学习的课程。阅读代码并非易事,仅仅阅读源代码是不够的,你还需要尝试理解他人的设计和思路。

读取代码光盘

前提条件

为了高效阅读代码,你需要准备好以下几样东西:

  1. 选择一款你能高效使用的编辑器。你需要能够快速搜索关键词或变量。有时你还需要查找引用或函数定义。熟悉你的编辑器至关重要。为了更高效地使用编辑器,学习只用键盘操作。这样你就能专注于代码,不受干扰。
  2. 具备 Git 或类似版本控制工具的基本技能,以便能够比较不同版本之间的差异。
  3. 与源代码相关的文档。这些文档将作为您阅读的参考资料,特别是设计文档、代码规范等等。
  4. 对所使用的编程语言和设计模式有一定的了解和经验。这对于大型项目来说至关重要。如果你精通一门编程语言,你就会知道源代码的组织结构,以及相关的范式和最佳实践。当然,这需要时间积累。请耐心等待。

流程和技巧

阅读过程并非线性过程。你不能逐个阅读源文件。相反,大多数情况下,我们都是自上而下地阅读代码。以下是一些提高代码阅读效率的技巧:

1. 结合上下文阅读代码

读取代码光盘

开始阅读代码时,一定要不断提出问题。

例如,如果一个应用程序有缓存策略,那么一个好问题是,如果某个键失效了,缓存中的值是如何更新的?

这类问题让你在上下文中阅读代码,或者说带着明确的目标去阅读代码,这使得阅读过程充满乐趣。你甚至可以自己做出一些假设。然后,有了代码,我们就需要验证这些假设。

这有点像间谍活动:你想发现代码的真相、代码的逻辑,以及它如何像故事一样流畅地运行

2. 运行并与代码交互

源代码就像一个乐高积木,只不过已经组装好了。如果你想了解它是如何构建的,就需要与之交互,甚至有时需要拆解它。对于代码来说,阅读同一源代码的旧版本很有帮助。查看 Git 中的差异,尝试弄清楚某个特定功能是如何实现的(变更日志对此很有用)。例如,我发现 Lua 的第一个版本要简洁得多,这帮助我理解了其作者最初的设计理念。

读取代码光盘

调试是另一种玩转代码的方式。尝试在代码中添加一些断点(或打印点),并理解控制台输出的任何内容。

如果你对代码有足够的了解,可以尝试进行一些修改,然后重新编译并运行。最简单的方法是尝试调整配置,观察不同配置的运行结果。之后,你可以尝试添加一些简单的功能。如果结果对其他人有用,你应该向上游项目贡献代码。

3. 数据结构之间的关系

“糟糕的程序员只关心代码,优秀的程序员只关心数据结构及其相互关系。”

——林纳斯·托瓦尔兹

数据结构是程序中最重要的组成部分。用笔或其他你喜欢的工具绘制数据结构之间的关系图。这样就能得到一张源代码关系图。在阅读过程中,你需要经常参考这张关系图。一些工具,例如scitools,可以用来生成 UML 类图。

4. 模块依赖关系和边界

大型项目包含多个模块,通常每个模块只负责一个职责。这有助于我们降低代码复杂性,并实现适当层次的抽象。模块的接口就是抽象边界,我们可以阅读一个模块后再阅读另一个模块。如果您正在阅读使用 Make 构建的 C/C++ 项目,那么 Makefile 文件将是理解模块组织方式的一个很好的切入点。

边界本身也很有用。优秀的代码组织良好,变量和函数的命名风格易于阅读。你不需要阅读所有源文件,可以忽略不重要或熟悉的部分。如果你已经确认某个模块仅用于解析,那么你已经大致了解了它的功能;这时就可以跳过阅读该模块。这当然会大大节省时间。

5. 使用测试用例

测试用例也是理解代码的绝佳补充。测试用例本身就是文档。如果你阅读了一个类,不妨也阅读一下相关的测试代码。这能帮助你了解类的接口以及它的典型用法。集成测试用例对于使用特定输入调试代码也很有用,它能帮助你把握程序的整体流程。

6. 复习

长时间阅读完一个项目后,何不写一篇代码审查呢?这就像读一本书的评论一样。你可以记录下这段源代码的优点和缺点,以及你从阅读中学到的东西。撰写这类文章不仅能加深你对代码的理解,还能帮助其他人更好地阅读源代码。

一些好书

读取代码光盘

我发现代码阅读比我想象的要复杂得多。这项技能并没有真正系统的训练方法。总之,要不断练习,找到适合自己的方法。以下是一些有助于提高代码阅读能力的书籍:

设计模式:可重用面向对象软件的要素

整洁架构:软件结构与设计的工匠指南

如何阅读一本书:经典的智慧阅读指南

啊哈,这本书对程序员也很有用。

文章来源:https://dev.to/snj/learn-from-source-code-4d1o