程序员职业路径回顾

144 阅读12分钟

工作之后逐渐发现,技术的累积是渐进的,职业生涯的进步却总是阶梯式的,而且每一个阶梯都是有不同要求的关卡,克服过去,保三四年安稳,过不去,后面做能原地踏步都是极限了。

程序员生涯一路过来,我也是过35岁的一线开发人员了,对于职业生涯的突破经验就是:通过向后看,从过去的经历中梳理前进的道路。

阶段一 - 起步

要成为程序开发,入门第一件事,自然是先学会一门编程语言。
新人上手学习时,往往需要花一定时间去适应计算机语言的表达方式。编程中技术中有大量抽象概念,比如指针、递归、闭包、到继承、重载等等,都是需要多次反复练习,才能适应思维方式。不过编程概念在不同语言间是共通的,掌握了一门语言,后面学起其他语言就事半功倍了。
在入门语言的选择上,有两个问题需要特别考虑:

  1. 编程语言的难度曲线
    不同语言的复杂度差异很大,过于复杂的,对无基础的人来说并不合适入门学习,尤其是自学人士。这里最具代表性的应该就是 C++了。C++发展了几十年,标准不断更新补充,各种语言特性应有尽有,问题也出在“应有尽有”上: 摊子铺得太大,每个技术要点都得长篇深入细节,虽然技术上推崇深入原理,把握细节,但初学阶段,很难控制学习界限,语言特性的学习和实践就不容易平衡。具体表现到日常来说,就是搞不清,学了这些语言特性,具体有啥用,比如指向指针的指针,或者高度抽象的模板类型实现,都要放到非常具体的项目(一般是复杂度较高的成熟商业项目)去解读,单纯的死记硬背非常枯燥。
  2. 先选择职业技术路线,再选择编程语言
    新手在里面往往会有一个疑问:“我该选什么开发语言入门?”,这个问题,其实更应该换成“我准备成为哪个技术场景下的开发?”
    按公司研发岗位类型来说,程序员可以区分业务岗和基础开发岗。
    业务岗需要直接对接市场环境,工作的波动程度更大。业务上升期的时候,市场不等人,开发节奏也必然慢不下来,996的恶名怕是难以避免(幸运的话,如果产品成功回报也丰厚)。另一方面,因为市场资本热点的原因,岗位薪资会有技术之外的增益。这里最典型的就是iOS开发了,13~15年时,iOS开发作为市场热点,岗位供不应求,薪资属于程序岗里面的佼佼者,到了18年,市场热点已从移动端转移至Web了,业务岗容量也随之回落,现今完全是个饱和市场了。业务岗门槛相对基础开发岗也更低,培训班几乎全以业务岗技术栈为目标设置课程。
    基础开发岗是为公司开发一些能在多个项目中复用模块的团队,比如游戏引擎、数据库、后端中间件等等,一般在中大型公司才会设置,正因为基础岗的产品是面向的同样是开发人员,而且代码要求高度复用,而且会稳定迭代扩展,对开发人员的要求门槛也更高,成员一般都是科班出身,进去后技术成长路线相对业务岗也更为稳定清晰。毕竟业务岗一旦产品表现不佳,被砍也是难免的,这对技术开发来说影响也是非常巨大的,因为换个项目工程,哪怕市场人员变动不大,技术积累的形态都会受到很大影响。基础开发岗基础薪资和公司平台规模的关系大,但和市场热点反而隔了一层业务团队,因此生活平衡度往往比焦头烂额的业务岗更高,技术话语权一般也更大,后期也可以降维到业务层面。很多时候,有些人会被业务岗暂时的薪资增益影响举棋不定,直到三五年潮水退去,才慢慢察觉到技术路线的选择问题,可这个时候,再从业务岗跳去基础开发,难度就大多了。

总结下来,编程开发的技能训练成本其实都不高,一台电脑,一根网线足矣,但是入行时,技能素质的条件对今后发展影响很大。

阶段二 - 初级

初级程序员除了编码工作,也需要了解工作环境。这里说的"环境"有两层:工作流程(例:程团队里面开发的分工与协同),以及流程配套的工程软件(例: 包括版本管理工具和项目跟踪工具等)的使用。

软件开发工种也发展半个多世纪了,工作效率的配套软件数不胜数:

为了跟踪切换不同时期的代码,协同多位程序员的开发成果,出现了 SVN/Hg/Git 这些代码资源管理工具。
为了统一团队开发步调,使团队对任务日期等保持清晰的感知,又可能引入瀑布模式、敏捷开发。
为衡量和管理产出,公司又可能引入KPI、OKR的机制。
总而言之,实践规则都是在商业验证中逐步建立起来的,新人也需要一段时间去和这些规则磨合。

对初级程序员来说,当下开发任务一般都来源于其直属上级,对方拆分开发任务,初级程序员从复杂度低的开发任务起步,之后难度再阶梯式提高。

程序员的基础工作流程。

初级程序员的工作,主要还是在代码编写和功能实现上。这个阶段的问题,主要还是出在职业环境的适应上,如果已过了职业面试,后面技术上的瓶颈概率也很低。对程序员来说,这个时期技术速度成长是最快的,就像海绵一样,能看多少代码就看多少,能练多少就练多少。

阶段三 - 资深

从代码编写角度上说,三五年经验的程序员,能力已经从功能点的实现,升级到了模块级的开发。
一般项目经过三五年发展后,有些功能下线了,有些功能扩展改版,对应的的代码也是删删改改,面目全非,在频繁更新的业务场景下 ,程序员应该怎么做,才能巩固代码质量,提高开发效率?

这时候会意思到,多个具有关联性的功能点,可以打包升级成独立模块,模块除了完成基础功能,设计更讲究复用性、扩展性。就像写文章一样,起步的时候,我们关注语句表达的正确清晰,再高一层,还要理清段落逻辑结构。设计模式本身就是开发人员在多年业务场景下,总结出来的应对方案。当然,模式并不是一成不变的,程序员还是得在项目中经过千锤百炼,才能获取足够的经验去做好一个设计。另一方面,代码清晰的结构,在任务分工对接上也有很大优势,模块内部划分明确,任务拆分和验证都更轻松。
网上偶尔会有一种言论,认为代码写得太过清晰影响自身岗位安全性,当然大部分时候,这只是一种调侃。现实里,业务功能繁多,如果缺少复用性设计,开发效率是很难提升的,项目规模在不断扩大, 复杂度在不断提高,如果个体能力不随之进步,很快就会陷入重复代码编写、在仓促中排查Bug这种恶性循环。输出复用性模块,代码质量是资深程序和初级的关键分水岭。

作为资深开发,工作中的沟通也不再主限于程序员内部之间,和产品经理、交互设计人员的交流也会愈来愈频繁。这个时候,就要求去理解产品的思路,并在开发成本、周期上做权衡,开始学会列举技术方案,最后在各方磨合下,综合完成实现。

资深程序员的工作范围

阶段四 - 技术整合

相比传统制造业代码实现代码,软件开发的一大特点,就是商业验证的周期特别短。大部分情况下,很多业务功能编码和运行测试是没什么成本的,或者说它是它相比建筑、机械这些行业,项目验证特别短,节奏也尤其快,实践经验的累积速度非常快。大约到五年左右,经验累积的提高速度就会显著慢下来,而且慢下来的因素,未必是程序员本身素质不够,它更可能是:没有出现更复杂的业务场景,产品复杂度没有继续变高。

资深程序技术上想再进一步的话,一个方向是研究多模块之间的架构,或是后端将从并发十万级提升到百万级等等。
这里就要提出一个问题了:什么样的项目规模,需要有人去规划模块架构? 以我个人的经验,普遍代码规模在几十万以上,而且是三年五年持续迭代的大项目,这种类型的项目,公司也得是个稳定的平台。当下的互联网大厂自然不缺乏这种场景,但每年优秀的应届生供应源源不断,走到这一步的高手,也、需要和他们同级竞争,进入前 20% 或者更小比例,才能顺利获取下一级试炼的资格。
小公司的开发人员到这个阶段就要面临尴尬处境:除非公司这几年一直在顺利壮大,否则业务估摸是做不到架构设计层面,也没有大规模并发服务器的经历给自己实践。 公司业务没有起色的话,就算你想在这一层继续升级,现下项目吃到的新经验实在太少了。更糟糕的是,一个业务长期停滞不前,可能就进入平稳期维护,或直接砍掉下马了,换下一个项目,必然又附带特定业务技术经验的损耗。
综合之下,这个阶段更可能出现的场景的情况是,程序员几年里在不同业务之间辗转,积累业务相关的开发经验,但是技术提升速度已大大趋缓。比如前端发展几年,慢慢出现了大前端的概念,因为网页开发上,业务上限能明显感知到了,这个时候是要靠扩充技术栈的丰富度,去扩大技术触及的范围。

阶段五 - 团队影响

对公司多个业务有经验累积的人,接下来应该做什么呢?
除了人们常说的“升职做管理”,我的回答是:从技术出发,做综合解决方案。一个公司技术栈往往不是单一的,也需要有足够经验的开发人员去不同项目之间的“润滑剂”。这时候除了和代码打交道,必然还要开始思考团队工作流程的问题。程序内部,也分前后端,也有移动、Web、桌面,像医院科室一样泾渭分明。不同技术栈背景的程序员直接对接也会有沟通效率问题,作为技术栈更深厚的开发人员,了解更全面,才能做出更全面的应对方法。
比如前端开发中,为了提高开发软件的质量,减少程序员犯错概率,提高团队协作效率,微软推出了 TypeScript,现下近乎行业实践标准。那在具体自家公司的业务流程里,处于研发位置的人,又该怎么去设计工具和标准呢?

这阶段是程序,技术影响需要扩大到整个技术团队(紫色范围),保证流程顺畅,提高区块内流程的效率:

再往后 - 回归市场

如果发挥团队中的影响力,程序员职位本身就算比较稳固了,但是单纯技术面解决不了非技术问题 -- 比如:市场大环境变动。

技术只能解决技术面的风险,无法解决商业面问题。归根结底,程序员是一个商业上划分出的一个职位,市场产品需要这一项技术支撑,软件开发只是一个切入点,如果个人超越技术层面突破,那最终方案自然还是回归商业本身。
工作是一份有稳定回报的低风险业务,公司平台为职工隔离了商业世界中的各种不确定性。所以把工作当做商业技能的培养平台,理解商业流程的运作,将自己感知触角延伸到技术之外,这种认知能力的累积,是无法靠技术迭代抹消的。

脱离职业标签,把自己看成一家公司去梳理自己的技能树: