往期系列: 《由阅读源码想到》 《由阅读源码想到 | 下篇》 《阅读源码(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. Tomcat集群应用部署的实现机制

    集群应用部署是一个很重要的应用场景,设想一下如果没有集群应用部署功能,每当我们发布应用时都要登陆每台机器对每个tomcat实例进行部署,这些工作量都是繁杂且重复的,而对于进步青年的程序员来说是不能容忍 ...

  2. Java基础---集合框架---迭代器、ListIterator、Vector中枚举、LinkedList、ArrayList、HashSet、TreeSet、二叉树、Comparator

    为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式. 数组和集合类同是容器,有何不同? 数组虽然也可以存储对 ...

  3. (九十六)借助APNS实现远程通知、后台任务

    APNS全称为Apple Push Notification Service,可以实现在app不启动时也能通过服务器推送到iOS端特定设备的功能. APNS的实现原理为先发送设备的UDID和应用的Bu ...

  4. 【unix网络编程第三版】阅读笔记(五):I/O复用:select和poll函数

    本博文主要针对UNP一书中的第六章内容来聊聊I/O复用技术以及其在网络编程中的实现 1. I/O复用技术 I/O多路复用是指内核一旦发现进程指定的一个或者多个I/O条件准备就绪,它就通知该进程.I/O ...

  5. UE4帧动画Matineed

    发一句牢骚,ue4除了渲染好一点,其他操作都没有unity便利,最近需要在项目中,调几个简单的动画使用到了Matineed,相当不好用.也可能是unity转ue4,有先入为主的观念,哈哈,never ...

  6. Tomcat如何检测内存泄漏

    一般情况下,如果我们重启web应用是通过重启tomcat的话,则不存在内存泄漏问题.但如果不重启tomcat而对web应用进行重加载则可能会导致内存泄漏,因为重加载后有可能会导致原来的某些内存无法让G ...

  7. MyBatis主键生成器KeyGenerator(一)

    Mybatis提供了主键生成器接口KeyGenerator,insert语句默认是不返回记录的主键值,而是返回插入的记录条数:如果业务层需要得到记录的主键时,可以通过配置的方式来完成这个功能 . 由于 ...

  8. 根据CSS的class选择DOM

    // 网上参考的,自己修改了一部分 // 代码如下,纯JS,要求浏览器支持 getElementsByClassName 方法 <script type="text/javascrip ...

  9. Android官方命令深入分析之虚拟机

    Android SDK包含了一个运行在计算机上的移动设备虚拟机.这个虚拟机可以允许你在没有物理设备的情况下开发和测试Android应用. 键盘命令 虚拟设备按键 对应键盘按键 Home HOME 菜单 ...

  10. Uva - 506 - System Dependencies

    模拟题,注意显示安装和隐式安装,显示安装的必须显示显示删除.把名字转化为整数维护.其他注意都注释了.输入稍微多一下,题目不是很麻烦. AC代码: #include <iostream> # ...