凡读书最切要者,目录之学也。目录明,方可读书,不明,终是乱读。
—— 王鸣盛,《十七史商榷》
目录即是地图。
对于软件开发的知识,我更愿意使用下面的的“地图”,这不一定是最合理的,但确实对归纳各种软件开发知识有所帮助。
1. 通用的领域知识
- 编程语言(C/C++,Java,C#,Python,Perl,PHP等)
- 框架和类库(Struts,Spring,OSGi的某个具体实现,MFC,Boost等)
- 平台(Windows API,POSIX,.Net Framework※1,Java API,C/C++ Runtime Library等)。恰如Jeffry Richter所说,大多时候可以从内存机制、线程机制、错误处理、异常处理、组件构建、组件组合等方面来进一步考察一个平台。
- 计算机体系结构(CPU指令,虚拟存储等)
- 数据库
- 实用技巧(调试方法,代码生成器等 )
- ... ...
※1 有的时候子类别间的界限并不是很容易界定,其中一个主要原因就是存在着像.Net Framework这样涵盖了过多内容的概念。
2. 概念和逻辑创建和优化
- 面向对象分析和设计/结构化分析和设计
- 设计模式
- 重构
- 契约式编程
- UML ※2
- ... ...
※2 从形式上来看UML更近似于一种编程语言,但从其目的上来看也许归在这里是更合适的一种选择。
3. 专业领域知识
- 图形图像算法
- 网络协议
- 人工智能
- 数值/非数值类算法
- 财务知识
- 负载均衡
- ... ...
4. 关于软件的间接知识:
- 需求开发和描述
- 估算
- 估算法。比如,COCOMO, FP等。
- 估算术。比如,使用计数等原始办法。
- 软件工程和方法论
- 轻量型方法论。比如敏捷。
- 大方法论。比如CMMI
- 综合分析。比如,《人月神话》,《人件》所做的工作。
随着待解决问题越来越复杂,通用的领域知识中,几种技术往往会组成一种技术Stack,他们更需要被看做一组必须一起掌握的知识,比如:LAMP(Linux+Apache+MySQL+Python/PHP)。
当然上面罗列的远不是全部,这种罗列更多的是展示一种分类的方法。通过对这种分类方法的补充和完善,大多可接触到知识都可以被归入特定的类别,比如说:WinRT可以看做一种新的平台,HTML5则可以看做是一种语言等。
每个人可以根据自己的情形,参照上面的分类建立属于自己的地图,有点问题没关系,有就比没有要好很多。接下来依据这样的地图就可以选一条自己的线路,持续累积,寻求实践机会,最终就很可能会成为真正的高手。
而关于增值所需的动力,所要避开的陷阱,将下面陆续提到。
增值、读书与大局观
单纯从达成某一目的而言,读书往往非是绝对必要条件。
秦始皇把书一把火烧了,刘邦项羽一样造反并取得胜利。但读书无疑的可以加速一个人增值的过程,记不得是谁说过:实践无疑是人类最好的老师,但只靠实践来认知世界无疑也是愚蠢的。这是非常精辟的。除此之外,要想培养大局观,那就非读书不可。
每个人的亲身经历,在大的时空背景中往往只是一个简单的截面,这一截面中绝不会包含可以归纳出所有真理的事实,因此只依赖于自身的实践也就必然限定了一个人的视野。 这一点随着一个人的责任范围变大往往会体现为一种制约和限制。所以培根讲:有实际经验的人虽能够处理个别性的事务,但若要综观整体,运筹全局,却唯有学识方能办到。
即使从实践来看也是如此,要想培养出一种大局观,那就非读书不可。而大局观往往是成为将帅之才的必要条件。
具体到软件而言,有一本很有名的书对培养技术的大局观有帮助:《代码大全》。至于专业性较强的书,反倒是可以根据自己的情景比较容易的选择,这里就不提了。
基于上面这样的一张地图,我们就可以具体的去考虑几条进阶路径。
路径一:由程序员而架构师
架构师是一个很火的职位名字,但你很难给它下精确的定义。
下面所陈述的一切是我个人的理解和体会,我无法保证它和其他人的解释完全吻合。因为架构师,乃至架构设计实在是一种非常模糊的概念,如果你用心去找,可以找到各种定义(甚至IEEE和SEI的定义也不一致),这就导致你只能参照别人,相信自己。
本质来讲架构设计也是设计,所以凡是做设计的都可以称自己为架构师。
当一个系统的规模变大的时候,设计上的决策就具有了特别的价值,并且也越来越需要专门的人来做,架构设计也就越来越像是一种特别的设计。比如说:考虑架构设计的时候,可能需要考虑选用什么样的数据库、选用那个开源框架、选用什么样的硬件平台,这些东西在小规模程序中往往是居于次要地位的。
假设说一个人已经掌握了一门或几门编程语言、面向对象、设计模式、能够很熟练的写出质量较高的代码,接下来他想成为架构师,这个时候他需要做什么?
我个人认为,这时候这个人首先要有一个“专业”。这个专业可以是“金融”,“财务”,“电商”,“管理”等等。这是一种属于某一专业的领域知识,而不是编程技术。如果把需求和最终的代码,看成描述同一事物的一体两面,那么设计始终是要架起这两者间的桥梁。而架桥的时候,怎么可能只知道一端而不知道另一端。
接下来是深化设计所需要的各种通用领域知识(UML、