3

Linus曾说过,Read The Fucking Source Code!
但是个人感觉读源代码是一个很痛苦的过程,最近在看Java多线程,看到JUC,涉及到不少源代码,有些单单一个类就有数百上千行(虽然说有很多是注释),有时看看就看不下去了……如何克服看源代码的急躁(急于求成),培养阅读源代码的耐心(遇到不懂的英文或难理解的地方,容易放弃)……

大家是有什么阅读源代码的好方法,都读过什么源代码,花了多少时间?求分享经历!

之后打算,了解下Android的源码,有相关经验的也可以分享……

11个回答

8

已采纳

laravel(队列部分)。

一个很深切的感受就是:laravel框架是典型的对基础应用友好,对高级开发苛刻。入门指南很清楚明白,但是开发框架本身的指南就完全没有了,甚至于部分注释自动生成的API都不完全的。想给laravel写一个扩展,必须深入到框架源码中做一番研究,没有商量。

以上的话虽然不好听,可意外的是,这些话还真的不是黑laravel。因为laravel迭代速度快,并且使用方式的自由度实在是过大。在这种情况下,与其抽出精力写一个半生不熟的文档,反而是干脆不写,省出时间来优化代码,允许开发者方便的深入框架,在工程上更加合理。

这件事有一个反例就是WordPress Codex。开发WordPress时看着Codex上那些陈旧和信息不充分的页面,有时颇有“还不如没有更好”的感受。

而laravel的代码本身:

  • 深度依赖composer,包、命名空间和文件结构分割严格。具体到一个功能上的代码基本上没有太多。
  • 接口完备,扩展容易。一般多种方式做同一件事的时候,都提供一个统一接口和数个参考实现。就算必须自己写新实现,也可以方便的从原来的实现copy代码。

在开发者识读和扩展的便利性上,laravel的代码是可圈可点的。


我对读的建议就是:代码只读最优秀的。不优秀的代码,要么原样使用,要么小修小补使用,要么干脆重写。

读最优秀的代码犹如与最顶尖的人才共事。这会让自己写代码的时候,都不好意思写的没有档次。这种逼迫对自己水平的提高极有用处。

代码,要读就读laravel这样的。

什么时候读、怎么读呢?最好是逼到有什么非读不可的需求的时候再读,读的时候一切以完成需求为目标,效率杠杠的。没有需求就去用别人的代码做点什么有意义的事情,需求迟早会冒出来的。


参阅:我扩展laravel的一个github项目《献给虚拟主机 Laravel 用户:全功能 MySQL 队列驱动器 L4mysqlqueue

6

python 的读过 tornado、requests,其他的用到什么读什么,C++ 的读过 xpdf,不开源的就更多了。。

第零步 —— 准备好你本次的阅读目的
一个项目,特别是上万行的代码,你是不可能一次读完的。带着目的读代码,而不是翻代码。
如果你是要修改一个功能,这样明确的目的就非常好。
如果不是,也请列一个提纲,比如今天读懂代码组织方式,明天读懂架构,后天读懂功能A 等等。
你可以用剥洋葱的方式一层层往里读,也可以直接切一刀。但是请不要翻代码,这样永远都读不懂。

第一步 —— 把代码运行起来
读代码之前请一定要让代码能运行起来,读 usage,读 API 文档,把握代码的主要功能和功能入口。如果你连程序是干嘛的都不知道,怎么读代码?

第二步 —— 找入口点
根据上一步你了解到的功能,选一个最简单的(比如 xpdf 有 GUI,有 pdftopng, pdftohtml, pdftotext,显然难度是下降的)程序,或者 API。找到它的源码位置,从它开始读。而像 tornado 的文档直接就有 API 到代码的链接,就简直太完美了!
不过,像 tornado 这样的异步架构,你可能找不到它的主循环,这时候找一个主事件处理 callback 就可以。

第三步 —— 观察数据流
好,假设你在第二步选好了要读的 main 函数或者主循环。不要着急读代码,首先看看 argv 在 main 函数中是怎么解析的,传递给了谁,谁输出了结果。主函数是怎么拿到请求的,谁处理了请求,最后输出的是哪个变量。

第四步 —— 只看函数,不看逻辑
跟着数据流,看它经过的函数,不要看逻辑,只看函数。猜,它是干嘛的。如果猜不出,跳到函数定义,看函数头注释,看接受的参数。但是记住只跳一层,不要看代码逻辑。
如果你是在剥洋葱,找个小本本记下每个函数的功能,明天请从最主要的那个函数开始看。如果你有着明确的目的,猜哪个函数和你需求相关的,进入那个函数继续看。
GOTO 3

因为很重要,再说一次,在认识所有的函数之前,不要读代码逻辑!除非:一、你已经找到你需要修改的地方;二、它是这个程序的最主要的功能算法。而这样的代码,整个程序往往只会有一处。

1

带着问题去读……(以前有个英语老师就是很喜欢说这句话,以至于现在我回想起这句话还是会响起她的声音)

就是,假如是有issue的项目,那么带着其中的一个或几个issue来阅读,看看到底是怎么一回事。说不定还能帮忙fix一下呢。
如果没有,你可以去找一下相关功能的是在哪里实现的,是如何实现的。

1

足兆叉虫已经说的很好了,这里补充一些自己有时候会用的方法:
1. 看项目的概要文档(API文档最好不要一开始就看,除非必要)搞清楚代码的目录结构和模块功能;
2. 看项目的测试案例,了解各模块的用法;
3. 看不懂的地方,google查找相关的文章,或许已经有人分析过相同的模块;
4. 如果是c++, 快速画类图和时序图(不求完备,只为了再次看的时候用来查询);

0

咩,还没到这么高级的程度。只看到开发中常用框架的源码,比如CI、Thinkphp(这个算不算?)
向楼主学习。

0

PHP框架就那样,边看边写吧

0

先关注目前你要用到的部分,尤其是当其实现遇到问题后,可以用一个具体的例子debug看变量。
然后不要忘记扩散开去。
最后在github等网站关注其动态变化。

0

楼主忽略了一个最根本的问题,那就是做任何事情,都是需要花费时间的。尤其是要做好一点,更是需要投入更多的时间。

0

对代码的功能和技术原型完全陌生的情况下,直接读源码肯定是举步维艰的。
我在刚开始读C源码的时候也是异常痛苦,不过读了小半之后就很顺畅了。

0

我是做Android驱动的,说说我读vold源码的历程吧。
其实刚开始我是拒绝的,后面SD卡遇到了一个获取卷标乱码的问题,虽然可以在上层规避,但是我还是想弄清楚到底哪儿出了问题,于是毅然啃起来源代码。主要是Android中用于获取磁盘分区信息的可执行文件——blkid的源代码。
跟很多答案一样,我发现带着问题去阅读源代码效率要高得多,边看边打log调试,很快就弄清楚了整个模块的工作流程,也定位到了问题,并修复了这个bug。还是蛮有成就感的。
总结就是:
最好是带着问题去看源代码,这样效率真的很高,否则的话,容易变成翻代码。

0

找到痛点,然后去阅读

该答案已被忽略,原因:不符合答题规范:内容不是答案,可用评论、投票替代,与已有答案重复:相同答案,请使用投票功能,无意义的内容:赞、顶、同问等毫无意义的内容

撰写答案