1、掌握读代码的方法和技巧
不管最终想成为什么,刚入行之后,一定离不开的是读代码和写代码。这里将介绍一些读代码的方法和技巧。
读代码这事,先要分是精读还是泛读。从学习的目的来看,一定要精读一定量的经典代码。而精读是指每行都读懂,不看代码脑子里就能勾画出程序的基本结构。要想判断是不是精读了有个很形象的判断方法:精读代码时会满脑子都是代码,放不下,甚至睡觉前脑子里也是代码。达到这个程度就是精读了,否则应该就还不是。精读代码要控制规模(初始阶段一万行以下即可)并用心,不太需要什么特别的方法。这节里主要关注的是如何泛读较大规模代码,不是精读。现存的很多系统往往很大,几十万行的可能也只算普通。这时候一旦加入了这样一个项目,应该如何去读代码?读规模较大的程序前,先得把规格说明书大致弄清楚,而不能上来就读。比如:对于应用程序,要先大致整清楚它的使用方法、使用场景;对于库则要弄清楚它对外接口的定义。如果其中有涉及到某些专门的领域知识,比如:流程、财会等,那也最好预先有些认识。这类东西彻底的从代码里反推回来是不太可能的。如果弄不清这类东西,很多时候对读程序是个很大的障碍。你不知道代码做的是什么,却去读对应的程序,那就只能看到调用来调用去,最终会云里雾里。
接下来从大往小,从面到点来看,一旦开始接触代码,那要先弄清楚代码的基本静态结构。如:包构成、类构成等。这里几乎一定会涉及一个层次问题。一下子把层次探的太深,就容易盯在细节上出不来。把层次拔得太高,又容易流于表面。从数目上看,一个层次最好不要超过10个关键概念,超过了真记不住。在静态结构这步,要弄清楚每个部分的核心职责,可以是很简单的概括,最好能记住。接下来选择出最常用的典型场景,然后在典型场景下考察上面的静态结构是如何发挥作用的。典型场景下用到的接口往往就是关键的接口,要弄清楚他们的定义和作用。也要整清楚典型场景下数据流的变迁。通过这两个步骤等价于脑子里可以生成一份比较高层次的静态和动态结构图,很像UML里的Sequence图和类图。牵涉到数据库的时候,一般需要对相应的数据规格有所了解。接下来要关注进程、线程的结构。比如:都是什么时候开始、什么时候结束的,在上述典型场景下都负责干什么。
上述四步(规格、静态结构、典型场景、进程线程)完成后,对程序的第一次泛读完成。检验是否达成目标的方法可以很简单,如果真的基本读懂了,这时应该能够单靠纸笔描述出程序典型场景的Sequence图。
做第一次泛读的时候,要抑制自己的求知欲,因为总是很想在调试器里通过call stack把一个功能的实现细节整清楚。至少在第一个次泛读里,可以先不要这样。第一次泛读后,就要进入深掘的过程,一般来讲需要针对自己会负责的部分进行深入挖掘。这部分功能往往会隐藏在某个接口之下。
这时候一般来讲可以把功能型的模块优先级降低,比如:XML解析的模块等。其他部分可以认为是需要把之前所说的四个步骤再重复一下。但这时候要关注细节和调用堆栈了。
不管是在那个读代码的层次,有两个基本技巧总是需要的,一个是要掌握具体程序里内嵌的Log机制,要能看Log,必要时可能还得加Log;一个是基本调试方法。同时一个合适的代码阅读工具会对提升代码阅读速度有所帮助,比如:一款名叫SourceInsight的小工具中可以把窗口分拆为几个部分,点击任何方法的时候,这个方法的实现以及CallsGraph都可以被自动展开,这样的小功能无疑的对阅读代码是有帮助的。
2、从哪门编程语言开始学习好些?
学习编程至少要掌握一门编程语言,但从那门编程语言开始是一个极其容易引起争议的问题。为使结论经得起推敲,这里需要做一点系统的分析。
纯从未来应用的角度看,结果是不确定的,在学习的时候,其实没人能够知道未来会主要使用那门语言。因为最终工作中使用那门编程语言往往取决于一些很偶然的因素,比如现有产品的开发语言,待解决问题的领域等。比如说如果命运安排你去做和Hadoop相关的工作,那很可能会用到Java,如果安排你去做驱动开发,那就很可能会用到C/C++。
如果上述这点成立,并且被预设为前提,那么在学习阶段应该学什么就可以有个相对确定的答案:学习阶段学习语言的目的是为了掌握编程的基础概念并能更快速的学好另一门语言。显然这仍然是打基础的范畴。
从这个角度看,只有一门语言是必须学的,那就是C。因为不了解这门语言会造成一定视野上的限制,使基础薄弱,比如不掌握C语言的人,很可能无法了解《深入理解计算机系统》这样的书,进一步也就不理解什么是指针,什么Stack,什么是StackOverflow,什么是写超界,做性能优化的时候可能也就想不到一些系统级的手段。Joel在《软件随想录》里专门有一章叫“学校只教Java的危险性”,其中所表达的观点与这里的观点类似。
作为结果,尽管很可能在工作中用不上C语言,在学习的时候还是要把它掌握,除非在最初阶段就已经下定决心只把技术当做敲门砖,而不想走的更远。要不然根基就过于薄弱了。
至于其他一些比较主流的语言比如C++,Java,C#等可以完全按照兴趣来进行选择,唯一关键的是不管选择那个都要累积一定代码量并把它学透。这样依此扩展到将来要用的编程语言,学习曲线往往就会很平,大致2~3周就可以用新的语言做一些基本的开发工作。
选择编程语言的另一种思路是从脚本语言入手,比如PHP,Python,Javascript等。这就和赵匡胤当年要下决策是先搞定弱的南唐还是先搞定强的辽国一样,是个两难的话题。从入手容易,培养兴趣的角度看,显然脚本更好些,并且脚本语言也是互联网的显学,未来用到的机会很高;但如果想多积累,厚积薄发那么就还是从C入手会好些。我个人的建议是如果在大学里那就先难后易好些,因为人生里不总是有这么大块的时间;但如果是后想转入这个行业,那就直接找脚本开始吧。
3、小结
写程序、读程序、学好学习曲线陡的知识、避免IDE依赖这些事情的根本目的都是为了打好基础。这个环节里最忌讳的是急功近利,比如:学习一堆IDE的操作方法、每个编程语言都掌握一点。很多人可能误以为这对找工作有帮助,所以把但凡接触过的技术都列到简历里是很常见的做法。但其实这个认识是不对的,但凡有点规模的公司招聘毕业生或者刚毕业不久的开发人员的时候都更看重他的基础和发展潜力。而基础和潜力这两样东西很难精确度量,但并不难判断,通过简单的面试既可以判断出来。只关注当下这个人能干什么的公司很可能是看不到明天的公司。