往期系列: 《由阅读源码想到》 《由阅读源码想到 | 下篇》 《阅读源码(III)


Eric S.Raymond的写于2014年的《How to learn hacking》是一篇出色的谈论如何阅读源码的文章。(Eric这里的hacking技术,指的是开源项目里的一种 an effective way to acquire general-purpose programming skills,即获取通用编程技艺的有效方法。)

这篇文字里,Eric创造性地提出了incremental-hacking cycle的概念。在他看来,建立起坚实的技术实力,需要经过这么一个循环过程:

  1. 选择一个你感兴趣的开源项目。

  2. 如果你不是太了解这个项目,通过阅读文档,去学习如何使用这个项目。

  3. 为这个项目增添/修改一个小的feature。

  4. 不断在代码库中做搜索,直至找到增添这个小feature的正确位置。

  5. 为你的改动,生成一个build,对这个build做测试、调式。并为这个改动撰写文档。

  6. 将你的改动作为这个项目的patch,发送给这个项目的维护者。

  7. 继续询问自己:我现在理解了整个项目吗?如果不是,返回到第三步,选择另外一个更复杂的feature来重复上述操作。

短短7个步骤,蕴含了开源社区如何滋养技术人的合作方式(之后另写文章阐述),及自我技术修炼的精髓。

在这里,我想展开论述第三条。从技术角度讲,第三条是阅读源码的必要衍生——不仅仅是阅读代码,而是要和代码发生作用与反应。

但对于一个newbie来说,第三条充满了陷阱和不知晓的误导。特别是,当第三条的工作,是由你的上司或者同事指派下来,你往往会因为feature功能过于简单,更加无法领会第三条的精髓。

例如,如果这个项目本身有one click的功能,而你被指派的任务是实现一个double click的功能,估计很多newbie会为此抓狂,并深深地感觉受到了伤害和智商上的侮辱。

但实际情况是什么呢?

这里的重点,其实不是写一个简单的feature, 而是以这个小的feature做引子,去带动你找到能够正确添加这个feature的准确位置。

换言之,这是在训练你对代码的搜寻能力和对代码整体脉络的把握能力。当你能够自如地找寻到每一段代码正确的添加位置时,你也就基本掌握了这个项目的代码架构。

另一方面,“添加一段代码”这句话,其实隐含了很多老兵默认但newbie却不一定知道的东西:

  • 如何证明你的添加是正确的?

  • 这段代码会对整个项目产生哪些影响?

  • 如何证明只会产生你认为的这些影响?

  • 支撑这段代码的test case有哪些?

  • 你撰写的test case能否覆盖、囊括了对项目产生的所有影响?

这些默认的隐藏思考点,对newbie是极其残酷的。老兵们没有义务去做过多的解释,往往就是一句“你要多写啊”,然后不断地给你“reject”,不断地重复“你要认真一点啊”这样粗糙的指导。

而如何认真呢?你从来不知道。其实就是这些默认的规则、规范和细致考虑。这些东西是开源社区的默认规则,你得通过不断地阅读其他人的邮件列表和提交工作,来一步步归纳总结:应该在每个看似简单的改动背后,做足、做踏实哪些相应的辅助工作。

如此,你更加可以理解:为什么不能够只是通过阅读代码,而必须通过“写代码”的方式来理解一个项目。所谓的“牵一发而动全身”,如果没有一个明确的操作目标和实际作用,你很难知道这个小小的位置,会造成那么可观的连锁反应。而添加代码,就如同往河里扔进去一颗石子,能够通过切切实实的作用,让那些隐藏在背后的连锁反应逐一显现,从而让你更深刻地去掌握项目背后的实质和逻辑关系。

这样,你也可以理解为什么需要添加一些功能上无足轻重的代码了。因为,如果你对本身的代码架构不够熟悉,而feature本身的技术细节又极端复杂,你将会陷入到一个double difficulty的处境。你的debug,不仅要解决feature的技术细节,还得考虑在代码构架中所引发的影响,这对一个newbie来说就太过困难了。

总结起来,对于newbie来说,一个很矛盾的困境、但却很少有人愿意为你解释清楚的是:你很可能因为这个feature自身的简陋甚至幼稚而轻视这项“添加feature”的任务。但你的轻视,源自于你将这项任务的“用意”弄错了。

这项任务的主菜,不在于feature的高技术含量,而在于让你去探索、评估、理解“即便是这么简单的一个feature添加,它到底会对这个项目本身产生哪些影响?又该如何去验证、测试这些影响?从而去加深你对项目的理解,提高自身吸收代码的技艺。”

近期回顾

阅读源码(III)
2018年03月写字总结
再探羊、猪、狗

如果你喜欢我的文章或分享,请长按下面的二维码关注我的微信公众号,谢谢!

更多信息交流和观点分享,可加入知识星球:

VIP赞赏专区

阅读源码(IV)的更多相关文章

  1. 【转】使用 vim + ctags + cscope + taglist 阅读源码

    原文网址:http://my.oschina.net/u/554995/blog/59927 最近,准备跟学长一起往 linux kernel 的门里瞧瞧里面的世界,虽然我们知道门就在那,但我们还得找 ...

  2. Spring源码解析——如何阅读源码(转)

    最近没什么实质性的工作,正好有点时间,就想学学别人的代码.也看过一点源码,算是有了点阅读的经验,于是下定决心看下spring这种大型的项目的源码,学学它的设计思想. 手码不易,转载请注明:xingoo ...

  3. Spring源码解析——如何阅读源码

    最近没什么实质性的工作,正好有点时间,就想学学别人的代码.也看过一点源码,算是有了点阅读的经验,于是下定决心看下spring这种大型的项目的源码,学学它的设计思想. 手码不易,转载请注明:xingoo ...

  4. 阅读源码(III)

    往期系列: <由阅读源码想到> <由阅读源码想到 | 下篇> Medium上有一篇文章Why You Don't Deserve That Dream Developer Jo ...

  5. How Tomcat works — 一、怎样阅读源码

    在编程的道路上,通过阅读优秀的代码来提升自己是很好的办法.一直想阅读一些开源项目,可是没有合适的机会开始.最近做项目的时候用到了shiro,需要做集群的session共享,经过查找发现tomcat的s ...

  6. 使用 vim + ctags + cscope + taglist 阅读源码

    转自:http://my.oschina.net/u/554995/blog/59927 最近,准备跟学长一起往 linux kernel 的门里瞧瞧里面的世界,虽然我们知道门就在那,但我们还得找到合 ...

  7. 转载~Linux 平台下阅读源码的工具

    Linux 平台下阅读源码的工具 前言 看源代码是一个程序员必须经历的事情,也是可以提升能力的一个捷径.个人认为: 要完全掌握一个软件的方法只有阅读源码在Windows下有sourceinsight这 ...

  8. Linux 平台下阅读源码的工具链

    原文:http://blog.jobbole.com/101322/ 前言 看源代码是一个程序员必须经历的事情,也是可以提升能力的一个捷径.个人认为: 要完全掌握一个软件的方法只有阅读源码. 在Win ...

  9. Zookeeper_阅读源码第一步_在 IDE 里启动 zkServer(集群版)

    上篇文章Zookeeper_阅读源码第一步_在 IDE 里启动 zkServer(单机版)讲了在 idea 里以单机的方式启动zookeeper,这篇介绍一下以集群的方式启动. 集群方式启动,才会真正 ...

随机推荐

  1. Jetty 嵌入式启动官方完整教程

    网上太多了,不如直接看官方的这个全面. http://wiki.eclipse.org/Jetty/Tutorial/Embedding_Jetty 入门地址: http://wiki.eclipse ...

  2. 择天记OL体验截图

  3. Fedora 20: How to enable SSH

    1. systemctl  enable sshd.service 2. service sshd restart

  4. [GitHub]第三讲:简单分支操作

    Git 最核心的操作对象是版本( commit ),最核心的操作技巧就是分支. 什么是分支? 仓库创建后,一旦有了新 commit,默认就会放到一个分支上,名字叫 master.前面咱们一直看到的多个 ...

  5. java设计模式---访问者模式

      Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自 己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广 泛,遵循一定的编程模式,才能使自 ...

  6. bash:chkconfig:command not found

    1尝试sudo/su rootsudo chkconfig --list2上述方法不行,请检查是否安装chkconfigrpm -qa |grep chkconfigubuntu上默认是不支持chkc ...

  7. Linux IPC实践(9) --System V共享内存

    共享内存API #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int ...

  8. 下载android5.0源码

    方法还是与之前我介绍的下载源码的方法一样,但是repo需要更新一下,否则可能会出现以下错误: type commit tag v1.12.16 tagger Conley Owens <cco3 ...

  9. Java Map 及相应的一些操作总结

    Map是我们在开发的时候经常会用到的,大致有以下几个操作,其中putAll方法是针对集合而言的操作,故不再进行说明,下面请看一下常用的知识点吧,尤其是keySet和Values两个方法及相应值的获取方 ...

  10. ISLR系列:(3)重采样方法 Cross-Validation & Bootstrap

    Resampling Methods 此博文是 An Introduction to Statistical Learning with Applications in R 的系列读书笔记,作为本人的 ...