码路指南:程序员的几个职场发展方向

清代著名学者曾对知识地图的必要性做过非常精确的表述:

凡读书最切要者,目录之学也。目录明,方可读书,不明,终是乱读。

—— 王鸣盛,《十七史商榷》

目录即是地图。

对于软件开发的知识,我更愿意使用下面的的“地图”,这不一定是最合理的,但确实对归纳各种软件开发知识有所帮助。

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、面向对象、性能确保等)。这时和一般所说的设计的一个关键区别是,那就是架构设计要分心思去考虑那些东西用别人的就好了,而那些东西要自己开发。而一般所说的设计技术中,比较侧重自己应该怎么干(面向对象、测试驱动等)。为达成这一目的,就需要对现有技术的优劣有相对比较清晰的认识,比如要能分清楚那些是成熟稳定的技术,那些是处在实验阶段的技术。Pinterest网站就曾经进行过下列这样的架构改进,在这样的改进过程中,不知道各种技术的优劣是代价很大的:

Pinterest 早期阶段:

Rackspace

1 small web engine

1 small MySQL DB

2011/1:

Amazon EC2 + S3 + CloudFront

1 NGinX, 4 Web Engines (for redundancy, not really for load)

1 MySQL DB + 1 Read Slave (in case master goes down)

1 Task Queue + 2 Task Processors

1 MongoDB (for counters)

2 Engineers

2011/9:

Amazon EC2 + S3 + CloudFront

2NGinX, 16 Web Engines + 2 API Engines

5 Functionally sharded MySQL DB + 9 read slaves

4 Cassandra Nodes

15 Membase Nodes (3 separate clusters)

8 Memcache Nodes

10 Redis Nodes

3 Task Routers + 4 Task Processors

4 Elastic Search Nodes

3 Mongo Clusters

3 Engineers

2012/1:

Amazon EC2 + S3 + Akamai, ELB

90 Web Engines + 50 API Engines

66 MySQL DBs (m1.xlarge) + 1 slave each

59 Redis Instances

51 Memcache Instances

1 Redis Task Manager + 25 Task Processors

Sharded Solr

6 Engineers

2012/10:

Amazon EC2 + S3 + Edge Cast,Akamai, Level 3

180 Web Engines + 240 API Engines

88 MySQL DBs (cc2.8xlarge) + 1 slave each

110 Redis Instances

200 Memcache Instances

4 Redis Task Manager + 80 Task Processors

Sharded Solr

40 Engineers (and growing)

摘自:http://highscalability.com/blog/2013/4/15/scaling-pinterest-from-0-to-10s-of-billions-of-page-views-a.html

这个过程比较真实,大家可以参照着想想如果自己来主导,那还欠缺什么。

最后一点要说的是,做架构设计已经相对于在做技术管理工作,至少要适当涉猎估算并能做出合适的任务分解,这样一旦日程紧张,则可以通过增加人手等手段来在质量、成本和进度之间进行均衡。

由于知识面已经扩的比较大,架构师在具体某个专业领域上的深度可能会有所欠缺,比如:在做一款电子消费产品时用到了TTS,但架构师不一定能很好的了解TTS的算法—这是CodeGuru的领域。

架构师所需要达成的最终目标可以形象的描述为:产品经理考虑用户和市场建立了一个模型,那么架构师要能把这东西映射到技术的世界里来。如果是在互联网行业,那么在你的主导设计下要可以做出高并发的网站。换到其他行业也与此类似,从产品的的角度往回看,架构师要能解决和技术相关的所有问题,主导完成商业上有价值的产品或项目的开发工作。实现手段上倒并无限制,可以是购买,可以是组织人员进行开发,只要能平衡短期和长期利益,解决特定的问题即可。

路径二:由程序员而CodeGuru

与架构师相对应,在某些智力密集型的程序中,也需要技能高超的程序员,这种程序员往往被称为Guru。

这条路线里,程序员并不把自己擅长的领域扩的太宽,但在指定领域上会挖掘的很深。驱动、字库、图形库、算法库、OCR等都偏向于这一领域。

假如说,一个程序员在掌握基本语言之后,想往这个方向发展,那么需要的技能和架构师差别很大。比如:一个人如果想往驱动方向发展,那么就需要了解CPU的基本结构、内核调试方式、操作系统中与相应驱动所对应的机制、硬件侧的规格、通讯协议等。

这时候很可能由于程序规模并不十分庞大,面向对象、设计模式这类东西没有太大发挥空间,而是需要处理的是大量或麻烦或艰深的细节。

2013年1月,ITeye发布了一条信息说:Intel面向学生免费提供 C++ 开发工具,并简单的介绍了一下是那些工具免费向学生提供:

Intel C++ Composer XE,其中包括:

Intel C++编译器(高度优化的编译器) 

Intel数学核心函数库(高性能数学库) 

Intel线程构建模块(C++任务模型、最流行的C++并行方法) 

 Intel集成性能基元(多媒体基元库) 

Intel Advisor XE(推荐的并行开发建模方法)

Intel VTune Amplifier XE(非侵入性的性能分析工具)

Intel Inspector XE(先进的线程和内存调试工具)

看到这张列表,我们可以思考下要开发这类工具需要什么样的程序员。上面这些工具的开发都属于高难度的工作,和开发大规模的MIS系统完全不同,如果不是某方面的专家,基本不太可能负担起相应的责任。而这类领域则正是Guru的天下。

路径三:由程序员而纯管理

纯管理工作和技术管理工作可以用是否接触乃至编写代码来区分。纯管理工作往往需要把精力放在预算编制、人员职业路径、考评、度量、流程改善这些工作上。一定程度上讲,这等价于和编程工作说拜拜,当然前提是你得有编程经验,有一些通用领域知识和概念创建乃至逻辑优化的知识,否则的话和程序员没法沟通,进而给工作造成障碍。

从需要读的书来看,这时候可能要看过PMBOK,《项目管理修炼之道》,《管理的实践》,《基业长青》等等。

但如果一个人认为想做管理要从PMP开始,那大概是还没太明白管理这项工作的本质。管理本身是一种借势,虽然有技术性的一面,比如要理解挣值曲线这类,但这方面知识其实并没有想的那么复杂 —— 至少没有C++11复杂,只要有时间正常智商的人都可以在不太长的时间内掌握。所以如果你想做管理,并使用了和学习C++语言一样的方法,那基本上是偏离了方向。

抛开机缘这类东西不论,做好管理工作有两点很关键:

一是要把技术工作做的相对比较好。这好像有点学而优则仕的意味,但大多时候人们更愿意相信“将军起于行伍,宰相拔于州郡”,而不愿意相信单只会耍嘴皮子的人。过度务实的人容易迷失于道路,过度务虚的人则容易飘的太高而丧失根基。管理者正应该身处在这两者之间的一个平衡点。

二是要能够借势。要情商比较好,能把很多人组织在一起。这个时候要知道那些东西需要规则化,那些东西需要灵活把握。过度偏向规则是教条,过度偏向灵活则是人治,平衡点始终要根据具体人员的状况,工作特质这些不可改变的事情来把握。这有点微妙。但即使程序员这个群体相对简单,但并不能推翻先人后事这类规则。这不知道是不是东方特色,当你想做管理并想推进事情的时候,终究要理清人际上的关系,否则就和可能会欲速则不达。这点会在后面进一步展开来谈。

下面我们来看一个具体点的例子,这个例子出自郭致星老师的博客,是一个学员的真实疑问(文字上有修饰),X入职后的现状如下:

开发部现在26个人。基本组织架构是由开发组、需求组、测试组、运维部四个部门组成。需求组的人收集需求,再通过系统指派给开发组,进行开发。开发组的文档严重缺乏。

现在公司内有技术总监和开发部经理的岗位。眼下全公司就X一个项目经理,目前是跟着开发部经理,在熟悉一个核心系统,由于没有任何文档的遗留,所以现在是相当于一个开发人员在开发一些实际的功能,一边开发一边熟悉现有系统。

现在X并没有项目的实际权力,而且整个项目组也只有开发部经理,加上2个开发,再加上1个测试和X共5个人。其中X和其中一个开发都是新来的。

与此同时,业务部门在搞一些流程,但还没做完,没有在开发部进行实施。工作气氛比较沉闷。技术总监和开发部经理,都是技术型的人,比较偏向技术,平时工作也多偏向于具体执行。

在使用一个Redmine系统进行项目管理和BUG跟踪。

这里的系统大部分都类似于产品线制,属于需要长期开发维护的,需求源源不断的来,相应人员也就需要不停的做,没有版本制度,也没有计划和规划。

系统现在主要的问题是性能问题。 

问题就是在这样的一种环境下,X应该如何开始自己的管理工作?

这类问题通常并没有唯一答案,但确实有些通行的手段可供参考,最终做不做的好和个人能力乃至环境关联很紧:

了解现有系统的状况,包括规格、代码规模、代码质量、代码内部结构、工作流程、问题所在等。比如说:很可能这类系统缺乏一种整体设计,是靠单纯的增加代码的量堆积出来的,代码冗余非常厉害,数据库的表也创建的比较随意。

了解人员。包括人员的能力水平、工作意愿状况、性格。

了解公司。尤其是公司的运作风格,有的公司偏人治有的公司偏于规则。短期对这类现行秩序要考虑如何顺应,而不是如何改变。

对当前系统的状况和人的状况有所把握后,要对愿景进行描画,比如在功能上做那些改善,对速度做如何改善,目标的高低要适度,要能获得上司和下属的支持。这时候还要能平衡短期和长期目标,既不能长时间投入没有产出,也不能有产出但进步不可见。在这一步骤里最典型的忌讳是急功近利的做超出自己影响力范围的事情。比如:目标与现有人员的能力完全不匹配或者完全不顾及对销售可能产生的影响而单纯的做系统的优化。最理想的情形是,连续达成几个目标,提升自己的影响力。

搞清楚团队成员和公司的的基本诉求,在取得成绩的同时尽可能双赢的扩大自己的影响力,目标是确保团队的执行力。

逐步导入基本流程,使项目上轨道。但流程不能成为成绩的借口。

接下来进一步的规划愿景,看能否取得更大的成绩,比如:挑战是否能做出真正有特色比较优异的产品。

在不同类型的公司里,对应手段上会有不同。比如在规范性比较强的大公司,第4,5两步的权重就会比较低。在上述这样的场景下,PMP这类书籍中所提到的种种技术手段诚然是必要的,但和人打交道的部分(老板、直属上司、下属)往往会对最终的结果产生更大的影响,这是管理工作与纯粹技术工作不同的地方。

延伸阅读

此文章所在专题列表如下:

码路指南:缘起
码路指南:怎样才算是编程高手?
码路指南:程序员的几个职场发展方向
码路指南:为何你成不了编程高手?
码路指南:在博与专之间取得平衡
码路指南:别错过人生中学习的黄金时期
码路指南:物质驱动与兴趣驱动
码路指南:保持内心的青春与理想

Leave a Reply

电子邮件地址不会被公开。 必填项已用*标注