往期系列: 《由阅读源码想到》 《由阅读源码想到 | 下篇》 《阅读源码(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. 发运模块中如何创建Debug 文件

     版本11.5.9到12.x A. 针对发运事务处理或者快速发运产生Debug文件 注意:如果通过发运事务处理执行发放,请参考B部分,下面这部分销售订单发放是格外的设置和日志文件. 1.   每一 ...

  2. 如何使用EasyUI显示表格界面

    还记得前面有篇博客叫---使用TT模板+mvc+wcf实现简单查询,这篇博文的末尾,小编贴了一张查询出来的结果图,那么这篇博客的中新来了,如何使用EasyUI显示出表格样式的界面,以前学习CS的时候, ...

  3. tomcat请求路由映射核心组件Mapper

    Mapper组件的核心功能是提供请求路径的路由映射,根据某个请求路径通过计算得到相应的Servlet(Wrapper).这节看下Mapper的实现细节,包括Host容器.Context容器.Wrapp ...

  4. 03 ProgressBar 进度条

    >      style="?android:attr/progressBarStyleSmall" 样式                 android:progress= ...

  5. (七十三)iOS本地推送通知的实现

    iOS的推送通知分为本地推送和网络推送两种,如果App处于挂起状态,是可以发送本地通知的,如果已经被杀掉,则只有定时通知可以被执行,而类似于QQ的那种网络消息推送就无法实现了,因为App的网络模块在被 ...

  6. Maven项目中获取classpath和资源文件的路径

     假设资源文件放在maven工程的 src/main/resources 资源文件夹下,源码文件放在 src/main/java/下, 那么java文件夹和resources文件夹在运行时就是cl ...

  7. javascript之DOM编程增加附件

    在开始这个案例之前,需要学习一下有关于根据子关系节点获取标签的几个方法.罗列如下 /*通过关系(父子关系.兄弟关系)找标签.parentNode 获取当前元素的父节点.childNodes 获取当前元 ...

  8. SQL2008数据表空间大小查询脚本

    --尽量少用触发器,否则数据库增长很快,特别是关于登陆的数据表字段不要用出发器,一周左右能使得数据库增长1G的空间. --数据库表空间大小查询脚本 IF  EXISTS (SELECT * FROM ...

  9. 通过Java进行网页抓取并生成plist创建代码

    抓取网页的方法: 抓取网页可以通过正则表达式也可以通过Java. 通过firefox浏览器,安装Firebug来查看网页的源代码. 首先将要抓取的部分保存到本地,步骤如下: 1.在要抓取的位置右键,选 ...

  10. JNI设置C++与java的结合(2)

    我们可以看到其中有四个函数声明, Java_完整类名_方法名, 完整类名包括了包名, 例如demo.Sample1是完整类名, 对应的这里就是demo_Sample1. 在注释中我们可以看到这样一个东 ...