1、高手的定义和养成关键
我估计如果问100个人“什么样的程序员是高手?”,那答案会有100多个。因为同一个人还可能给高手下不同的定义。
在这里我们认为,在特定领域里能搞定大部分人搞不定事情的就是高手。从这样一个定义出发,我们会发现在技术人员和销售人员眼里,高手的内涵是有很大差异的。
纯技术人员更多的关注性能能不能提到极致,并发能不能处理的很好,内存溢出Bug能不能很快搞定,类库的机理熟悉不熟悉等等。而在销售人员的眼里,则在技术外还多看了些东西,比如业务流程熟不熟悉、使用性好不好、能否迅速对应变化、能否在限定工期和预算下搞定任务等。
考虑到职场和产品销售有着非常紧密的关系,我们这里使用后一个视角,而非是单纯的技术视角。
高手有很多种类型
有几类本质上很不同的人都会被视为高手,比如说:
能写出很牛的病毒的。这个不举例子,但当年读过CIH的代码,我是被其精巧给震住了。此外也许搞加密解密的也应该放在这个类别里。
能把一堆3D图形放到64K的。以前专门有个比赛是干这个的,64K大小的EXE能给你放10几分钟很酷的3D动画,第一次见绝对会很震惊。
能迅速调试出问题所在的。内存泄露、多线程同步这类问题往往让人纠缠很久也搞不定,但就是有人能很快的解决这类问题。
能仅靠几个人就架起高并发网站的。新兴Web2.0网站如:Flickr,甚至还可以包括Google,在初期往往是几个人搞起来的,这些人名声不显,但绝对是高手。
能主导开发出很牛的产品的。这个上可以想想Unix和Linux的作者等。
能主持大规模软件设计的。这个往往更有商业价值,我们常说的Martin Fowler应该可以算在这个类别。
能把一种语言研究的特别牛的。想想各个编程语言的创建者,想想C++的大牛们。当然创建某一门语言的也可以归到这个类别里。
能开辟自己方法论的。比如搞CMMI的Watts S. Humphrey。
能写出很牛的书的。比如:Windows平台下写了Windows核心编程的Jeffry Richard。
能写出很牛的算法的。比如:Donald Knuth。
……
这个表应该还可以加长很多,单以大家认可这个角度来看确实高手可以从各个方面冒出来。
不管在那一方面,要想成为上面所描述的高手总是需要学习、思考、实践这些环节,这没什么可说的。但和软件相关的知识其实多如牛毛,完全不像小说里武功秘籍那么稀缺,几乎可以讲满地都是。这就使选择和集中成为难题。
只学不用没意义
软件的三个基本特征(技术更迭快、低介入门槛、多内部分野)就像铡刀一样,一旦选择出错,就会把个人的努力切的粉碎,一点价值也留不下来。而与此相对的,则是人的黄金学习时间其实并不多 —— 不过是毕业后的10年左右的时间。
曾经有人希望自己能够从事嵌入式软件的开发,因此给自己买了ARM板,自己在家里花了很多时间来学习并实践相关知识,最终却因为其他的原因进入了一家做网络的公司。这个人等价于被软件的内部分野较多,而彼此间技能流动性较差这样的一个特质斩了一刀,被斩掉的倒不是ARM板,而是自己一年多的辛苦投入。这种情况下强调学的知识将来有用是没有太大意义的,因为还有两刀在等着:如果你三年都不做这个,你今天学到的知识可能会被更迭掉了,同时由于你年纪增长了,可能也不太适合与大批新介入这个行业的人员进行竞争。
这类事情使软件行业中的成为高手这事变得复杂了。
为了在成为高手这条路上走的顺畅,事实上有三个关键点:
一是要有一张全局性的地图,以便选好方向;
二是要知道都有那些坑,好绕开它,免得掉进去。
三是要有足够的热情和动力,能坚持走下去。下面将分别从这三个方面来说明成为高手途径和方法,而这种途径和方法会因为具体目标不同而有所微调。
2、全局性的地图
清代著名学者曾对知识地图的必要性做过非常精确的表述:
凡读书最切要者,目录之学也。目录明,方可读书,不明,终是乱读。
---王鸣盛,《十七史商榷》
目录即是地图。
对于软件开发的知识,我更愿意使用下面的的“地图”,这不一定是最合理的,但确实对归纳各种软件开发知识有所帮助。
通用的领域知识
编程语言(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指令,虚拟存储等)
数据库
实用技巧(调试方法,代码生成器等 )
... ...
有的时候子类别间的界限并不是很容易界定,其中一个主要原因就是存在着像.Net Framework这样涵盖了过多内容的概念。
概念和逻辑创建和优化
面向对象分析和设计/结构化分析和设计
设计模式
重构
契约式编程
UML
... ...从形式上来看UML更近似于一种编程语言,但从其目的上来看也许归在这里是更合适的一种选择。
专业领域知识
图形图像算法
网络协议
人工智能
数值/非数值类算法
财务知识
负载均衡
... ...
关于软件的间接知识:
需求开发和描述
估算
估算法。比如,COCOMO, FP等。
估算术。比如,使用计数等原始办法。
软件工程和方法论
轻量型方法论。比如敏捷。
大方法论。比如CMMI
综合分析。比如,《人月神话》,《人件》所做的工作。
随着待解决问题越来越复杂,通用的领域知识中,几种技术往往会组成一种技术Stack,他们更需要被看做一组必须一起掌握的知识,比如:LAMP(Linux+Apache+MySQL+Python/PHP)。
当然上面罗列的远不是全部,这种罗列更多的是展示一种分类的方法。通过对这种分类方法的补充和完善,大多可接触到知识都可以被归入特定的类别,比如说:WinRT可以看做一种新的平台,HTML5则可以看做是一种语言等。
每个人可以根据自己的情形,参照上面的分类建立属于自己的地图,有点问题没关系,有就比没有要好很多。接下来依据这样的地图就可以选一条自己的线路,持续累积,寻求实践机会,最终就很可能会成为真正的高手。
学习有困难可以以关注微信公众号:javaniuniu 进行交流得到大神的指导和帮助,获取免费的听课权限!