此生有幸我跑到了程序员这个赛道上,说有幸因为自己还算热爱这份职业。自从2013年,我从一个工科生转入到程序员这个行业,我听过不少人把我们叫码农,最开始我也跟风自嘲,可当我后来看到程序员与程序员实际上存在巨大的差别的时候,渐渐地我心里放下了码农这个看似自嘲却值得深思的标签。

跨行业总是不那么一帆风顺,通过速成班长出来的我接收到了第二次冲击波 — 很难找到合适的工作。经受着“戴维斯双击”(生活压力和精神压力),唯有比别人付出更多的努力,才能勉强跟别人站在同一起跑线上,而且在跑道上时刻要保持多几分的努力。

至今,我在这个赛道上跑了8年有余,有些人一开始在我视线范围内,跑着跑着不见踪影。有的人跑着跑着就停下来了,还有的人干脆跑出了赛道,更多的人虽然人在赛道上,但一直在痛苦的挣扎着向前。我敬重那些通过超常人的努力跑到前头成为领航者的人,珍惜那些按自己的步伐仍在努力稳步前行的人,同情那些在痛苦挣扎却又长时间无法完成自我突破的人。

作为一个半路杀进来的程序袁,没有科班生天然的优势,一开始我成为了自己同情的那类人。在一家公司挣扎者开发着一款大数据分析的软件产品,用落后的软件开发方式修修补补。幸运的是,天然的危机感促使我不断去填补自己的知识和技能的空缺,逐渐扩大了视野,结识了行业的优秀伙伴(Thoughtworkers),便义无反顾的跳出了原来的码农圈。

在Thoughtworks,我很幸运能亲身实践诸多业界优秀的工程实践,并觉知真正是在用正确的方式做事情,这是其一。倘若用正确方式做事情就足够了,有可能出现“以最高的效率做了一件错误的事情”的,所以还需要确保自己是在做正确的事情,这是其二,甚至两相居上。唯有“以正确的方式做正确的事情”,程序员的价值就不再是简单的码农所能替代的。

在ThoughtWorks,我学到了对我的职业生涯来说很宝贵的东西 — 用正确的方式做正确的事情,持续改进,追求卓越。在一个这样充满同侪压力的学习氛围中,即便胸无大志的我也不会被潮流抛弃,顺流缓进是一贯的主旋律。流的越久,认识的程序员种类越多。总得来说,在这里大部分人在做正确的事情,同样也用正确的方式做事情。

阴差阳错,我从历时5年的交付项目上跳出来,成了一名技术讲师和技术教练。视角的切换方才后知后觉 — 原来之前我是 不识庐山真面目,只缘身在此山中。接触到的程序员多了,发现虽同为程序员,彼此有大别。有的人喜欢沉浸在技术的乐园,唯业界先进或炫酷的技术尝鲜为快。有的人忽视枯燥反复的基本功修炼,一心追逐热点,深怕被时代遗弃。有的人则在这里谋得一相对高薪的差事,心猿意马,采用蹩脚的方式应付着各种软件的需求亦或要求,生活在水深火热中却不自知。

我也遇到了我欣赏的一类程序员,他们始终孜孜不倦地修炼自己的基本功,始终在思考什么是正确的事情,不断地尝试跳跃出自身的局限性,能够耐下性子,跟时间做朋友,不断遇见更好的自己,最终脱颖而出。要成为这样的程序员,与之对应的三种思维误区是你应当尽量避免的。

误区1:不思考业务价值

在我看来,一名应用软件程序员,“做正确的事情”最显著的表现是思考软件功能背后的业务价值,可能没有之一了。

我在做敏捷软件技术教练的期间,听到过一名学员这样的声音:“用户故事即便写了这么一段话,我也压根不用看,因为我不看都能把代码写出来。”这里所说的这么一段话是指用户故事的三要素描述:Who-What-Why。如果你有过一些用户故事的使用经验,应该已经回忆起来是那段:As a… I want… So that…

言外之意是我对系统长什么样,每个功能点怎么实现了然于心了,不用再去在意是为了解决谁的什么问题。的确,不否认资深的程序员基于前期编码的积累,对系统有足够了解。只是了解和了解是不一样的,正如前文所提到的程序员和程序员是不一样的。如果一名项目开发骨干对系统的了解大多关注在How层面,而很少理解背后的Why,这种了解缺了一点生机和灵气。如何诊断这种了解呢 — 你问他系统是怎么工作,他能很流利地讲出来,你再问他系统为什么要这样工作,答案便知晓了。

只知其然而不知其所以然的程序员其实不少见,很多时候这也是大环境的产物。因为项目的开发协作模式,在业务人员和开发团队缺乏沟通的协作模式下,业务需求往往通过重量级的需求文档来传递,里面长篇大论在讲软件应该如何工作,甚至给出了详细的界面设计、数据设计的方案,而对为什么要这样工作?这样是为了解决谁的问题?解决了什么问题?却是轻描淡写,亦或是写了也被埋没在文字大海里了。(我在一次Code Review中听到某个学员在实现了某个需求文档描述的接口功能后来了一句:其实我不知道这个请求返回的字段跟这个需求有什么关系)

在这样的注重流程的工作模式下,程序员被培养成编程工具的可能性会高出许多。假如你也身处在这样的环境,要跳出这样的思维模式需要付出更多的努力。有时候,即便自己去思考业务,挑战需求方,凭一己之力也难以撬动大盘,加上身负开发重任,还得拉拢团队其他人,种种阻力的叠加下,你可能坚持一段时间就放弃了,而一旦放弃,这种模式就会越发合理的存在,开发体验也将持续恶化下去。

好在敏捷转型和数字化转型在中国也不再是新鲜词汇了,一些传统的IT组织也开始寻求变化,他们邀请外部教练来帮助解决这些问题,如果你恰恰碰到了这种机会,当珍惜这样的机会。跳出原来的思维模式,对分派到自己手上的需求多停下来去想一想下面的三个问题:

  1. 解决谁的问题?
  2. 解决了什么问题?
  3. 有没有更好的方案?

重文档的需求管理方式多少扼杀程序员参与业务需求讨论的机会,这样一来就给业务价值之思添上了一堵墙。如若程序员有机会参与到业务讨论过程中,理解了业务本质问题,相信能够给出更具程序员独特智慧的技术解决方案,不但充分发挥了主观创造力,还可能赢得业务人员更多的信任。

从被动等待丢过来一份缺乏生机的需求文档,积极主动起来吧,积极思考三个问题,积极跟业务人员建立链接,即使努力了最终无法撬动大盘,美好的未来也会在向你伸出橄榄枝。

对于过重的需求文档,不妨以钱钟书钱老的话为借鉴 — 不受教育的人,因为不识字,上人的当;受教育的人,因为识了字,上印刷品的当。做一个不容易上当的程序员,需要比别人多一些额外的思考。

误区2:不注重基本功修炼

互联网便捷性的提升,软件行业诞生了越来越多的GBS程序员(Google + Baidu + Sougou)和栈溢出程序员(Stack Overflow),有了这些搜索工具,似乎问题再也不是问题了。渐渐地跟抽大烟一样,越抽越上瘾,越上瘾越搜。

搜索引擎提供了信息检索的便利性,使用起来就几分像嗑瓜子或玩王者一样能够很快获得反馈(很快帮助我们解决眼前的问题)。而体系的阅读和钻研的过程是漫长的,加上不能每次快速有效吸收的话,还无法立即用在工作上去解决燃眉之急,很容易半途而废。

如果给这两种方式取个名字,前者是假借外力,后者则是修炼内功,一个可能知其然而不知其所以然,一个是知其然且知其所以然。

举个身边经常发生的例子:一个Java后端程序员小A正在采用MVC架构,他看了篇别人写的文章,认识了Model、View和Controller这些新生的概念,并且也能画出它的结构图,并且很快依葫芦画瓢,照着网上Demo慢慢把代码写出来。后来,小A上了个Andorid项目,使用了MVP架构,他采取了一样的方式快速从别人的博客中取得真经,超度了了项目。TL说要把MVP改成MVVM架构,陌生的概念,你又去搜索了几篇文章,改吧改吧变成自己的。再后来,做了个Ruby On Rails, 依然是MVC架构,还是不会,于是原来的拿来主义又派上用场了……

这些年,各种架构模式的概念层出不穷,从名字上似曾相似,又似是而非,然而这些架构模式的底层原理有什么不同吗?MVC、MVP、MVVM说得不都是展示和逻辑分离吗?为什么要将它们分离,你曾思考过吗?如何分离,你有去从0到1实现过吗?这些模式背后的原理若理解透了,你还会焦虑今天Struts2还没焐热,明天切到SpingMVC,后天又换成Ruby on Rails吗?掌握了底层的原理,任凭川普变脸如何耍,你也可以做到新中有数,处码不惊。

洋葱架构、六边形架构、端口适配架构、整洁架构、DDD分层架构,这些词没一个重音同名的,每个都够消化一阵子,它们真的有那么多的不同吗?细究之后,无非是通过引入分层来分离关注点,保持职责单一和清晰,隔离变化与不变,并通过依赖倒置来控制简单的依赖关系。为什么要这么做?怎么做到?这些都是值得程序员应该去思考的底层问题,搞清楚了背后的原理,恐怕不用担心哪天业务复杂到超出当前架构所能驾驭的范围了吧。

又比如依赖注入(DI:Dependency Injection),很多开发人员为了速成完成项目交付,一直照猫画虎使用Dagger、Spring DI、Guice这些开箱即用的框架,而很少去探究DI的原理,思考DI的价值和优劣,更别提手动实现一个简易的DI框架,以至于多年的软件开发经验其实更像1年的多次重复,下一次换了个别的框架,依然需要按图索骥般从0开始,而随着年纪的增大,身体体力恐怕有点吃不消了。

若要做到任凭它技术日新月异,稳坐乾坤不乱。相比于追逐技术热点,更重要的是夯实基本功。培养出整洁代码的洁癖,吃透基础的面向对象设计理念,吃透架构设计的底层原则和理念,养成持续重构的意识,磨练自己的编码手速。深究技术框架的背后原理 — 学会造轮子,用原生的方式实现框架,从而深入理念。

软件开发从来不是一个人的事情,程序员除了一些软件开发相关的基本功,不容忽视的是团队协作方面的一些软性基本功。培养自己团队协作的意识和责任感,培养开放合作的心态以及磨炼结构化思考和表达的能力,力求在与他人合作的过程中不至于因为这些短板将闪光的技术硬实力遮掩住。

重要不紧急的事情要提前做,而且要经常做,因为很多重要紧急的事情是由重要不紧急的事情演变而来。好比健身,平时花点时间去健身,不至于哪天身体出问题了,健康就变成了重要紧急的事情了。程序员平时除了完成本职的开发工作,基本的夯实需要更多忍耐和坚持,而这恰恰又是违背人的天性的(人天性喜欢安逸),所以需要能够多保持一份清醒和克制。另外,如果你的工作忙到不允许你有时间去学习成长,而这种忙本身却带来不了成长,不妨站在现在、不久的将来、以及未来去思考这种状况是否你想要的,人无远虑,必有近忧,成长越早开始越好。

误区3:不愿跳出自我局限

我在做软件教练的时候,曾听到过学员一些这样的声音:

  • 我没事干嘛给自己找事,早点下班不好吗
  • 这不是我的工作呀,况且只有我去这么做也没什么用啊,干嘛费这劲

我第一反应有点惊讶,因为我自己是一个那种“路上有个石头即使没把我绊倒,我也会把它搬开,因为我觉得这次即使没把我绊倒,下次可能会绊倒其他的路人。” 跳出自我这个小圈子,很多事情就不再是“事不关己,高高挂起”的心态了。

在工作上,如果每天仅仅想着如何快速让自己的任务交差,跟自己眼前没关系的事情一概挂起,多付出点精力和时间生怕吃亏,这其实是一种小格局的表现。暂且不说出于为他人着想,什么拯救世界的崇高理想,哪怕是让自己工作的环境变好一点,工作体验也会更舒适。这让我想起来几年前我刚加入ThoughtWorks的时候,一些小伙伴总是喜欢“爱管闲事”般地给我反馈,多年后我想清楚了原因之一 — 他们希望我变得更好,以至于后面再跟我合作的时候更高效。

其实不管是否身为程序员,为人处世也要尝试跳出这种小我的局限性,因为这种小我会大概率地限制自己未来的发展,时间久了,发现身边跟自己一起奔跑的人越来越比自己年轻,而此时自己已经各方面不具备优势。这种小我局限性给人带来的影响让我想起了十点读书经常听到的一个故事:

一天,一位记者到建筑工地采访时,看到工地现场,大家都在忙碌工作,不方便接受他的采访,他就近采访几个正在忙碌施工的建筑工人,问他们正在做什么?第一个建筑工人头也不抬地回答道:“我正在砌一堵墙。”,第二个建筑工人习以为常地回答道:“我正在盖一所房子。”,第三个建筑工人则干劲十足、神采飞扬地说道:“我正在为建设一座美丽的城市而努力。”

若干年后,当这位记者找到这三个建筑工人的时候,现在这三个人的境遇令他大吃一惊:当年头也不抬回答的建筑工人现在还是一个普通工地的建筑工人,仍然像以前一样砌着他的墙,没有任何变化。而习以为常自己工作的第二个建筑工人,现在是在施工现场拿着图纸的设计师。那个干劲十足、神采飞扬的建筑工人,现在已经是一家房地产公司的老板,手下拥有几十号人,正在运营大的建设工程。

同样是在写代码,平庸的程序员在堆砌功能,优秀的程序员在构建系统,伟大的程序员在改变世界。而这种区别源于程序员心中的小我和大我。如果仅仅是想完成每日工作,按时下班,软件开发可能不是一份好差事,因为这种事不关己高高挂起的做法大概率会给自己挖坑,迟早会坑了自己,自己编(挖)码(坑)把自己埋了的案例不少见。

在传统的代码非集体所有的责任田式的开发模式下,很多程序员可能吃过改别人代码的亏,出了问题还得自己来背锅,在这种环境下,克服内心的小我需要付出更多的努力。 即便如此,也希望你为之努力,尽力了也没能如意也没关系,你若盛开,舞台自来。

写在最后

如果你是一名程序员,并且愿意让自己更优秀,这三个误区值得去尝试避开。如果你有幸融入了一个不错的环境,当珍惜,努力成长,顺势而进。如果你身处在一个不那么理想的环境,跟环境做抗争需要你付出更多的努力,避开这三个误区可能需要尝试从外部汲取更多营养。

我心中的程序员不再是我之前跟风调侃的码农,他们是一群 用正确的方式做正确的事情,追求卓越,持续改进 的人,愿你我都能成为这样的人。