文章出处:http://blogread.cn/it/article/4349?f=wb#originalphp
1. 前言java
不少人问我如何看源代码?是否是我在看源代码这方面特别有天赋?mysql
其实不是的,我也只是个普通人,跟大伙没啥分别,sql
只不过我没有别的特别爱好,一有空时,不是写本身的代码就是看别人的代码,服务器
我在看源代码时比较有耐心,纯粹就是兴趣驱动,或者说是一种好奇心。数据结构
固然,我不会随随便便拿起一个开源项目就看,而是通过必定了解后才决定看它的源代码的,架构
一旦决定要看了,我至少要把这个开源项目80%以上的代码看完,并非那种肤浅的看,eclipse
而是仔细研究每一行代码。布局
2. 我看过这些开源项目post
按时间前后顺序:
2007:
OpenJDK Javac1.7
2008:
Erlang编译器 (看得最少的一个,只看了一半源代码)
2009:
Tomcat6
Junit4
Ibatis2.3
OSCache2.4
Ehcache1.6
Mongodb-mongo-java-driver1.2
Velocity1.6
2010:
MySQL JDBC Driver (mysql-connector-java-5.1.13)
PostgreSQL JDBC Driver (postgresql-jdbc-8.4-701)
Netty3.2
Tomcat7
2011:
Jetty8
目前主要关注这4个:
OpenJDK Javac1.7
Netty4.0
Tomcat7
Jetty8
我如今每隔1到7天就会看这4个开源项目的源代码库中有没有更新,
我装了TortoiseHg, TortoiseGit, TortoiseSVN,
由于看Javac1.7的源代码更新用TortoiseHg比较方便,
而看Netty4.0要用TortoiseGit,最后二者用TortoiseSVN。
3. 我对看源代码的人进行了分类
分5种人:
1) 解决问题型
这种类型的人一般是在工做学习中碰到了一个很费解或很棘手的问题,
文档也看了,google也找了,同事、同窗也问过了,
可是问题仍是没法解决,因而不得不把源代码下下来,而后一边看一边debug,直到问题解决。
2) 三分钟热度型
多是看到别人也在看或者在论坛上看到某些人说XXX设计得很好,性能也不错,或者看到某些人在论坛上发了些分析源代码的文章,
再加上本身一开始也兴趣满满,而后也跟风了,看了10来个类的代码,啊,发现太痛苦,方法之间调来调去的,太绕了,头快炸了,
给本身找个理由,这代码写得太垃圾了,妈的,不看了。
3) 只知其一;不知其二型
网上常常看到有人在写分析源代码的文章,一上来就是一陀陀的源代码,而后告诉你这作了什么,那作了什么,
就加了点中文注释,有时这中文注释还不如源代码中的英文注释好理解,而后过了一段时间,发现文章不更新了,也没有后续了。
4) 真才实学型
像原做者同样思考,能轻松说出此开源项目的核心架构,精确理解80%以上的源代码,能找出bug并能提交相应patch,
5) 创新型
对此开源项目的优缺点了然于心,可以提取其精华为我所用,想出更好的方案解决现有问题,超越原做者。
4. 我看源代码的经验
仅供参考,不要随意模仿,每一个人都应该找到适合本身的方式,
惟一重要的是如下3点:
1) 时间
最好能有一大段时间集中精力去看,好比你要看Tomcat7,要有3个月的时间天天花3到8小时去不停的看,
时间拖拉得越久,会看了前面忘了后面。
2) 兴趣
看代码不要有任何功利性,你要对它有兴趣,充满好奇心,去理解它作了什么,怎么作的。
3) 耐心
这一点提及来容易,真正要作到是极其困难的,好比当你某些类连看了三次时还看不懂,不要先想别人写的代码是否垃圾,
先想一想你在这方面的背景知识是否足够,好比在看Tomcat实现http协议相关的代码时,一边看代码一边看http协议是最有效的方式,
再好比你想看编译器相关的代码,最起码在看以前,你要对<<编译原理>>这门课中的内容有基本的了解。
若是背景知识有了还看不懂怎么办,看不懂的代码先放下,有些if分支只有你把整个项目都大体了解了一下后才能理解的,
要反复的看,看三次仅仅是个入门级别。
先简单说一下个人经历:
小学到初中我还算是个好学生,在班里常常拿第一,
可是从小学6年级到初三这4年比较特殊,遇到了一个很垃圾很垃圾很垃圾的数学老师,
因此这4年个人数学基本上就是自学的了,个人自学能力从小到如今都是很是的强。
固然,这不能归功于这位垃圾老师,我自小就很叛逆,不喜欢这禽兽的教学方式,没有此垃圾,也许个人生活会是另外一番景色。
我不像正常人那样上完初中上高中,而后再上大学,
而是上完初中后就直接到一所师范大学上中专+自考大专,2001年就毕业了。
中专是学会计统计类的,自考大专是计算机应用,大专注共才12门课,没有英语,数学方面只有高数,并且仍是第一册,
核心专业课方面只有pascal、c、8086汇编语言、FoxPro、模拟电路、数据结构、操做系统、软件工程、计算机接口与技术。
只要不是硬件类的专业课程我就学得很是好,硬件类课程就只是听老师讲,当时连硬盘长什么样都不知道。
我2001年毕业时才19岁,而后就出来找工做了,说这些只是想说我从学校获得的教育并很少,
如今回想起来从学校学的C语言、汇编语言、数据结构、操做系统为我之后的自学提供了一些帮助。
直到2006年,我辞职了,以前我己经工做了4年,都只是作应用软件项目,
因此数学基本上没用过,英语也用得少之又少,英语其实比如今的高中生水平还差,
因此要看英文的技术文章也是看不懂的。
2006年我原本是要复习考研究生的,我从3月份开始连背了三个月的英语,天天花4到8小时背新概念英语的课文,
1、二册所有背完,第三册背了前42课,第四册背了前10课,我觉得这样的水平足够应付考研英语了,结果拿试卷一作,
阅读理解至少有2/5的单词认不得,不得不去背考研英语的单词。
数学基本上忘光了,到网上下初中和高中的新课标课本下来看,
高数、线性代数、概论全都自学,还买了相关的数学书来看(像几何、离散数学等等)。
每天作那些垃圾数学题,还要背马哲、毛概,专业课却是小儿科。
一直到10月份,各校出来招生简章了,想报10大高校,结果别人不鸟你专科生,你专科生没有报名资格,
好吧,换二线的能够了吧,结果仍是差很少,不是要本科,就是要发表啥论文才能报,
最后,很不情愿的报了个很平庸的所谓211大学。
此后愈加以为每天作题背单词背书实在是件极其无聊的事,再加上报考这件事,严重打击积极性,一直想放弃考研可是又一直坚持着,
直到11月23日,那天去书店看书,翻到一本讲编译器实现的书,
也就是所谓的"虎书",当时并不知道编译器是什么,由于我在学校时没学过编译原理,在书店连看了一小时,以为颇有趣,
就买了回来,接着就把考研的书全丢到一个角落里了。
接下来你应该懂的,我疯狂的买书,"龙书","鲸书"啥的我都买了,只要是有关编译器的,无论是国内仍是国外我都买,
由于我并非一看就全懂的,也是由于"虎书"刚开始一两章还好理解,后面的我当时就看不懂了,
我有个习惯,就是实在看不懂的书,我就会换一本,确认一下是我本身的缘由仍是书自己的问题,
如今我只会说"虎书"翻译得并很差,"龙书"更好理解,固然一开始就看"龙书"也并非那么好理解,
因此我当时甚至连形式语言和自动机相关的书我都买来看了。
我连看了3个多月,当时以为看书不过瘾,就想找个实际的编译器来玩,
我下了GCC和LCC,当时恰好sun公司又把javac开源了。
由于工做中只用到php和java,c语言已经4年没用过了,加上javac比前二者要小不少,
因此从2007年二月份开始第一次看javac的源代码,也是第一次看别人的源代码。
javac的源代码很少,8万行都不到,花了我3个月的时间,平均天天至少花7小时看代码。
由于我当时只会java1.4,java1.5以后出来的不少东西都不懂,因此也是一边看javac的源代码一边学新语法。
2007年5月份时我还在JavaEye上发了第一篇有关javac的文章,得了个精华,引发了一点小轰动,
这里有证据: http://www.iteye.com/topic/84833
内容貌似当年被我删除了,想不起来是什么缘由了,zhh2007就是我本人之前的id。
当时看代码的方法是很是原始的,可是直到如今我还在用这种方法,只不过如今有时会用eclipse来看,
我是这么作的:
看原代码用 EditPlus,
找到第一个入口类: com\\sun\\tools\\javac\\Main
本身再写一个Debug类,按执行流程看到一个方法时,就加入相似下面的代码块:
public static int compile(String[] args) { try {//我加上的 DEBUG.P(Main.class,"compile(1)"); DEBUG.PA("args", args); com.sun.tools.javac.main.Main compiler = new com.sun.tools.javac.main.Main("javac"); return compiler.compile(args); }finally{//我加上的 DEBUG.P(0,Main.class,"compile(1)"); } }
而后必定要重编译源代码,再运行,保证本身加的代码被执行到了,我会把输出的debug结果重定向到一个文件中,
而后一边看源代码一边看输出结果,一些变量或表达式本身想看结果也会加DEBUG.P(...),
碰到一些代码行数不少的类,我甚至会把每一个方法copy出来放到一个新的java文件中,
而后打开多个EditPlus,每一个EditPlus看一个方法,并且是按照方法的调用顺序打开EditPlus看的。
可能看到这不少人会以为这种方式好土,我也不能说好很差,从今年开始,由于个人电脑装了Eclipse了,
因此Jetty8的源代码我是用Eclipse看的,也再也不打DEBUG输出,也再也不copy方法,而是直接用eclipse的debug跟踪功能,
可是我如今提出质疑了,Jetty8的代码量只是Tomcat6的1/3,我用Eclipse这种方式来研究源代码并不能节省个人总时间,
我用最原始的方式研究Tomcat6也只花了3个月,如今研究Jetty8已经用了我两个月的时间,并且看Tomcat6和Jetty8是两个相似的东西,
按理说先看Tomcat6后看Jetty8应该花的时间更少才对。
我总结了一下,为何最初的方式好,那是由于我那样不断折腾源代码的过程当中已经间接让我记住了代码的布局,
我在敲那些重复的DEBUG.P代码时我把局部变量、表达式、字段都输出了一次,这有助于个人记忆。
而Eclipse的debug功能只是在不停的按F5-F6-F7-F8,打断点,方法调用太深时很难理清先后关系,
有时看了一星期,连哪一个类在哪一个目录都不知道,由于debug时,跟到相关的类eclipse会自动打开那个类,不用你从目录中找。
Eclipse的代码折叠粒度又不能折叠到块级别,不能折叠if、while,一旦方法的行数不少,看起来会很累,分不清这个方法的层次结构,
而EditPlus在看方法时就看得很舒服,由于他能折叠if、while,看完了一个while我能够把他折叠起来,
有多个if-else时只要折叠一下就不会超过一屏。
你能打开20个EditPlus,可是你不能同时打开10个Eclipse,除非你电脑的内存牛X到不行。
有一点很重要,无论是哪种方式,必定要把环境搭建好,你自已要可以编译源代码,而且多写些例子去验证源代码中的执行流程,
我通常不会去看源有代码中的例子或测试用例的,只有想不出时才去看(特别是看编译器时,一些用例你很难想到)。
我为何要看这么多源代码?
除了我的兴趣以外,如今想起来其实还有个很可笑的缘由:
2007下半年和2008一全年,这段时间不少人说Java快死了,Ruby/Rails、Erlang很火,
我常常上JavaEye,免不了也受影响,因此在2008年时还学习了Ruby/Rails、Erlang,连Erlang的编译器都玩了一下,
以后发现并非那样滴,只不过是一些大佬在鼓吹而已,再加上2008年家里出了点事,因此过得很郁闷,
一有闲情就跟JavaEye的大佬们"打架",想来也是种乐趣,算是种排解压力的方式。
固然,与此同时,也会从技术的角度思考Java出了什么问题,因此从2009年开始就专心研究技术了,还把douyu的原型鼓捣出来了。
2009年研究的那些开源项目其实都是很顺其天然的事,我要作一个http服务器,Tomcat已经作好了,我想知道他怎么作的,
我就去看,看这些项目就是为了想知道他们作了什么,怎么作的,哪里作得很差,我能不能比他们作得更好。
如今,看代码已是个人一种习惯了,从毕业那年到2008年我买了几万块钱的书,以致于我来杭州后都没有把桂林的房子退了,
由于书多,桂林那房子除了回去能住个几天外,如今是租给书住的了。
从2009年到如今,两年多时间我没有再买书,都是看源代码学新东西,
若是是一个全新的领域,最多也就是在网上找点入门资料,而后再看源代码,
包括下半年我准备研究HotSpot,已是C/C++的领域了,我没有任何学习压力,只是一个时间问题。
一我的的自我学习能力很是的重要,Java相关的和Java以外的全部东西我都是自学的,
我没有特别问过什么人,也没参加过培训,实在不懂的地方就查资料买书看。
若是看代码看不懂,这几点必定要明白:
1) 相关背景知识是否具有
2) 要有耐心,多看几遍
3) 不要期望别人告诉你答案,别人没跟你说也不要说别人高高在上不理你,由于这不是别人的义务
4) 通过对比以后再说别人的代码烂