作为一名程序员,有几种获取知识的渠道,比如本文将要讨论的技术书籍、开源代码、学术论文。这些可能都不是什么秘密,但每个人都有不同的方式和习惯,也就对应有不同的效果和效率。本文就分享下自己这些年来的一些经验,不一定适用每个人,但也许每个人能有些小的触动和收获。
1.技术书籍
可能程序员都很少读书,因为这个时代就是这样的特点,读书的人在减少。大家更多地从工作日常获得知识,对于程序员来说比如CSDN、StackOverflow、Quora等。但这种获取知识的方式就好比上厕所时看手机,获取的都是所谓的“碎片化”的知识。你不会因为知道一堆“冷知识”而比别人出色,相信大部分高手大牛也不是这样炼成的。之前在《高效程序员的狂暴之路》中曾提到过:“李小龙说过:我不害怕把一万种踢法都练一次的人,但我害怕把一种踢法练一万次的人。”,牛人都是形成了自己的知识体系,深刻、完整、自洽,这才是你的竞争力。
想要有自己的体系就需要系统化地学习,而系统化学习最直接的方式就是读书,读好书。然而技术书籍汗牛充栋,即便是有口皆碑的好书也足够我们读一辈子了。这时就需要正确的学习策略,对不同类型的书用不同的阅读方法,才能最大程度地发挥其价值。这一部分就简单谈谈,技术书籍的几种常见读法和适用的情况。
1.1 精读与回看
从头到尾一气呵成地精读,这种方式适用于章节间有着较强逻辑关系的经典好书。因为有顺序关系,所以从头到尾,因为是经典,所以要精读。比如,《Introduction to Algorithms》(CLRS)、SICP等,不仅正文要读,甚至习题也要认真去做,这样才会有最大收获。这一类书都是慢工出细活,着急不得,适合有一段完整的时间,比如这段工作不忙,那就每天下班固定一两个小时投入进去。
前面以CLRS举例可以不是十分准确,因为毕竟这是一部大部头的巨作,第一次接触的话几乎不可能顺利地从头到尾一字不落地读完的。但书非常经典,我们还是很想仔细揣摩学习的,这时可以采取反复阅读的策略。切记:千万不要让任何东西打消你的兴趣。尽量坚持读完每一章,但如果发现有一处就是看不懂,千万不要卡住甚至就此把书丢到一边。这时可以毫不犹豫地跳过,先尽力读完全书,从作者的动机、背景知识、重要章节、最终结论等各方面,在整体上有一个了解。之后在回头去看当时没太看懂的部分,这样避免浪费一本好书。
1.2 对比阅读
这里所谓的对比阅读就是,同时读两三本同专题的书,从不同角度学习。这种方式适合学习一种特定的技术,而不是很大的一个方向或范围。比如笔者学习Spring、MySQL、Dynamic Programming等都用的这种策略,以DP为例,我们可以读CLRS、《Algorithm Design》、《The Algorithm Design Manual》三本经典著作的相关章节,全面学习。但比如整个算法、数据库理论或其他大的范畴,就不适合用这种方式。想要学一个主题、分支、领域的话,还是像前面“精读”部分介绍的那样,专注于一两本经典细细品味比较好。
1.3 工具类资料
还有一类书,类似词典等工具书,书名中一般有Handbook、大全、Cookbook之类的字眼。另外网上能找到的各种命令、快捷键Cheatsheet也属于这一类。这种工具书通常会放在手边,需要时随手查询一下,非常方便。比如最近发现的《Python Cookbook》就是一本不错的工具书,对Python方方面面的语法和API都有涉及,对于一名Java为主的程序员来说还是非常实用的。
2.开源代码
除了技术书籍,网上的开源软件为我们提供了另一种学习方式。虽然是免费的开源软件,但通常比较流行的开源软件都具有工业级别的标准,所以其代码量都不会太小。因此就跟看书是一个道理,如果不讲究点策略的话,一头扎进代码的海洋,后果可想而知,一定是晕头转向、铩羽而归。下面就谈谈个人的一点经验。
2.1 周边环境
一个软件当然不只包括产品的核心代码,肯定还有编译、打包、测试框架、运行环境等构建工具来支撑它。所以我们可以从这些外围周边工具入手,先整体上了解这个软件是什么语言、哪些依赖、如何构建和运行的等等。了解了这些来龙去脉后,再看源代码会非常舒服。比如近期看了一些ElasticSearch的Kibana源代码,开始看之前一无所知,于是就从外围入手,先确定开发语言是Javascript,用了AngularJS+Nodejs的技术栈。
2.2 找到入口
了解了周边环境和背景知识后,就可以开始读源码了,但首先一步是找到入口。找入口看似简单,实则不然,就像美剧《西部世界》里的剧情一样,黑衣人花了一季时间还没找到迷宫的入口。开源代码的入口应该从Shell或其他启动脚本找起,可以是明显的main函数,也可能是其他指定的位置。可能是直接的加载,也可能是由操作系统内核似的Bootloader间接的加载,达到灵活或安全的目的。
2.3 抓住主线
找到了入口,游戏才真正开始。但不要高兴得太早,就像玩游戏先玩“主线剧情”一样,看源码也要抓住个主线才不会迷失。开源代码的主线就是该开源软件的启动过程以及之后主要操作背后所对应的代码。在梳理这条主线时,一般可以采取下面几种办法:
- 调试大法好:如果有幸软件可以跑起来或者远程调试的话,那真是再好不过,这种方式能够帮你快速理解复杂的逻辑。因为在调试过程中,所有变量的值你都能看到,可以说是带着一副能直接看到变量含义的神奇眼镜,一遍不行就再来一遍,一般不需要很多次就能对流程有不错的理解了。
- 抽取代码库:边看代码边敲也是一种不错的方式,但这不是要照抄,而是梳理出核心的逻辑和结构,并且帮助自己专注地找下去,最后读完后还能形成一个该软件的Mini版本放到自己的代码库里,也算是学习的成果。大概8年前学习Spring时就采取的这种方式,最后梳理出了一个Mini容器,最后还碰巧用到了毕业设计里做成了一个OSGi的小动态内核,非常有趣。
- 调用链图+文章记录:如果不是什么要保密的东西,那么随手画一些调用关系图,再写点文字也是不错的方式。最后整理好了,甚至还能出一个系列的源码学习文章。
3.学术论文
有时要想了解最前沿领域的知识,就要读一些论文。论文一般都不简单,有背景介绍、有解决问题的创新点、设计思路、实验验证、结论总结等。不求完全读懂,但要想抓住其主要思想,也是需要些方法的。《How to Read a Paper》是念研究生修一门课时,一位教授推荐的。她当时推荐我们用这篇文章方式读论文,然后为她布置的几篇经典论文写summary。这里就简单总结一下这篇文章的主要思想——“三趟阅读法”:
- 第一趟:这一趟只要5~10分钟,仔细读title、abstract、introduction,每个section忽略所有内容只读标题,然后读conclusion部分,最后扫一眼reference部分看看哪些是读过的。这一趟过后,你应该对这篇论文的分类、上下文、贡献、清晰度和正确性有个大概了解,并决定是否继续读下去。
- 第二趟:这一趟大概要一小时,仔细看各种图表,标记reference里没读过看似比较重要的。这一趟过后,你应该对其主要的证据有所了解,但不一定有很深的了解,因为可能论文中有你不知道的术语、缩写、实验或证明技术等。
- 第三趟:这一趟对于初学者可能需要4~5小时,将自己想象成这篇论文的作者,reimplement the paper,设想自己会如何写这篇论文。然后对比当前作者的写法,对与你的想象不一致的地方都要探究其是否正确,是否有漏掉的assumption、citation,实验是否有哪些步骤有潜在的问题等。
http://blog.csdn.net/dc_726/article/details/77861715