如何阅读代码

转自:https://www.codedump.info/post/20200605-how-to-read-code-v2020/

https://www.zhihu.com/question/21186887,https://boholder.github.io/blogs/learn-from-source-code/

1.介绍 

大多数程序员只在少数特别领域编过程。 一般而言,如果你不时常推自己一把,你的编程技能会维持在你同事间的平均水平。 不要满足于修补 bug 或在现有系统中添加琐碎特性的工作。 相反,你可以试着扩展到一个新的领域,持续尝试找到一个你在日常工作中接触不到、但你感兴趣的领域。 这将从整体上拓宽你对编程的理解。 

2.读什么

  • 当你想了解一个特殊的算法或实现。 例如,我们都会使用标准库中的 sort 函数,你有没有好奇过它是怎么实现的? 或者当你要使用 Redis 中的 Set 结构,它是用什么数据结构实现的? 为了解决这些疑惑,你只需要读源码中与之相关的实现部分通常只有很少的文件或函数

  • 选择与你当前的编程技能与知识水平相当的项目。 如果你选择了远超你当前技能水平的项目,最终你会感到沮丧。 读一些相对较小的项目,接着读更大的项目。 如果目前你不能理解某些特定的代码片段,这意味着你有个知识缺口(knowledge gap)。 把代码放到一边去,试着读一些相关的书、论文或其他文档,当你更有信心时再回来接着读代码。 我们总能在一个模式中取得进展:读(代码、书、论文),写,更多的读,更多的写。

 3.如何读

  • 掌握基本的 Git 或其他版本控制工具的技能,这样你就能比较代码在版本间的差异。阅读同一模块的老版本同样有帮助。从 Git 中阅读版本差异,试着弄清楚特定的特性是如何实现的。

  • 与源码有关的文档。文档可以为你的阅读提供参考,尤其是设计文档、编码规范等文档。

  • 开始阅读一份项目源码的第一步,是先让这个项目能够通过你自己编译通过并且顺利跑起来。
  • 尽管阅读项目源码很重要,但是并不见得所有项目都需要从头到尾看的清清楚楚。在开始展开阅读之前,需要明确自己的目的:是需要了解其中一个模块的实现,还是需要了解这个框架的大体结构,还是需要具体熟悉其中的一个算法的实现,等等。
  • 当你阅读代码时,请持续提出问题。 例如,如果一个应用有缓存策略,一个好问题就是:如果键无效了会怎样?缓存中的值如何更新? 带着这些问题阅读代码,就是结合上下文。或者说因为你有了一个目标,你会变得享受阅读的过程。 你甚至可以自己做一些假设,然后在代码中寻找验证
  • 了解模块间的依赖关系与边界。你不需要阅读全部源文件,你可以忽略不重要的或你熟悉的部分。 如果你确定一个模块是仅仅是为了被解析而设计的(just designed for parsing), 那么你已经大致了解了它的功能;那么你就可以跳过不读这个模块。
  • 程序设计=算法+数据结构。Linus说: “烂程序员关心的是代码。好程序员关心的是数据结构和它们之间的关系。”
  • 测试用例也是帮助代码理解的一个很好的补充。测试用例就是文档。 当你在阅读一个类时,试着把对应的测试代码一起读了。 测试用例能帮你弄清一个类的接口,和该类的典型用法。 集成测试用例可以让你顺着走过程序的整体流程,适合输入一些特殊值并 debug 运行。
  • 阅读代码有两种模式:top-down 和 bottom-up。每次出现函数调用的时候,把函数的执行层次纪录下来。
func1( )
   func2(  )
       func(  )
   func3(  )

有时会把重要的「实际参数」一直标下来,这样阅读深层次代码不用再回头查形式参数到底指什么。这个图的基本作用是防止在阅读深层次代码时忘记总体执行层次。Top-down 模式进行到一定层次,往往会发现虽然图画了出来,但还是无法了解程序再干什么。这时需要转入 bottom-up 模式,一直深入到最底层,给能了解作用的底层函数一个一个的写文档。当然这时的文档是完全底层的观点。

  • 针对烂代码。不要想当然的看到函数的名字一定能猜到它的作用,也不要假设一个函数只可能有1到N个作用,也有可能这个函数什么用都没有,仅仅是在代码中存在而已。不要假设注释一定是准确的,有可能注释早就没人维护了。
  • 只有更好的输出才能更好的消化知识,所谓的搭建调试环境、情景分析、多问自己问题、写代码阅读笔记等都是围绕输出来展开的。总而言之,不能像一条死鱼一样指望着光靠看代码就能完全理解它的原理,需要想办法跟它互动起来。

 

posted @ 2024-04-14 14:18  lypbendlf  阅读(10)  评论(0编辑  收藏  举报