原文转载于:https://my.oschina.net/editorial-story/blog/3133210
我们的中国文化,对“面子”看得特别重,所以你会发现身边到处都是高级 XXX,听着倍儿有面子,程序员也不例外。
但是你真要问每个人,你认为的高级 XXX 是什么样子的,估计每个人都有不同的回答。
我还记得在我刚开始从事编程工作的时候,对坐在边上不远的那位我心目中的高级程序员的印象是:
工作至少有 6、7 年以上,能写一个用起来很方便、看起来很牛逼、但是不太容易让初级人员看懂的框架。
前两天,我把这个问题丢到群里,大家给出的答案中,占比最高的是以下几个。
你看,这件事对大家来说就是常说的,“一千个人眼中有一千个哈姆雷特”。
不过这也正常,毕竟像初级、中级、高级这种高度抽象的词汇,想要得到一个可描述的定义与人交流,必然需要夹杂着个人的主观因素。
但是很多行业都在这么进行分类,自然有它的道理和好处。
我觉得其中最大的一个好处恰好是“主观”的附属品——弹性。
比如,我现在想招一位高级程序员,面试的时候不管是通过还是不通过,我都有理由来解释我对“高级”的定义。如此一来,我对陌生人的判断就有了更大的“弹性”。
这其实是面试官的一种权利,也是长期以来面试者总在面试中处于下峰的原因之一。
事物总是有两面性的,我们在对陌生人弹性的同时,间接地也对内部的人弹性了,会导致内部的一些人才培养出现问题。
比如,你觉得内部的高级程序员不够,希望能在外部招聘的同时,从内部也培养一些出来。但是此时,你又面临了需要定义什么是“高级”的问题。
如果没法定义一个能够达成共识的标准,又如何指导培养的方向呢?只能是一句空话。
长此以往会导致更严重的问题:真正的高级程序员不够,只能让中级程序员顶上。顶替的时间长了,会让一些中级程序员误以为自己已经达到了高级水平。
在我平时的面试中,这样的案例屡见不鲜,网上流传的工作 10 年 = 1 年重复 10 次的段子是真实存在的。
下面我来聊聊我对“什么是高级程序员”的个人看法,欢迎你和我一起探讨。
不管是什么行业,什么岗位,在这个高度分工协作的现代社会,所需的能力主要分为三个维度,我的理解大概是这样的:
先卖个关子,文章的最后我会将这三个维度组合起来,你会发现一片新的天地。
根据这三个维度的水平差异,我们对初级程序员、中级程序员、高级程序员做一个简要的描述。
处在初级阶段的时候,我们的精力大多只会专注在专业能力的提升上。这个时候“领导能力”和“连接能力”是很弱的。
所以,这个时候哪怕你有强烈的好奇心也无法很好地表达出来,大多只能被动的接受工作安排。
在这个时期做事情需要依赖一些教程、文档,只能“依样画葫芦”,几乎不能在不借助外部信息的情况下解决之前从未遇到过的新问题,所以百度、google 就成了他们唯一的选择。
你可以在你的身边观察一下,如果经常有以下这些场景出现,大多是初级程序员的表现。
很遗憾,看似很初级的阶段,并不只是刚踏入工作的程序员所属,在实际工作中,也有不少工作多年的人还处在这个阶段。
对人群按照单一维度进行划分,大多数时候都是符合正态分布的,这里也不例外。中级程序员是我们身边最多的,包括那些不得不穿上高级程序员马甲的中级程序员。
在这个阶段,有些中级程序员开始具备了一定的“连接能力”,但并不是所有人,主要看是不是拥有了“共同体意识”。
在专业能力上,中级程序员已经明白了一定的“整体与局部”的概念,但仍然看不到整个“森林”,大多局限在某个模块、流程上。比如,他们会想“这是做敏捷的正确方式吗?”,但不会考虑“这对整个团队、整个公司会产生什么实际的影响?”。
他们开始注重代码质量,因为担心低质量的代码会影响他们视野中的“整体”。
但是对于质量的理解还是比较单一。比如,这个时候你会经常听到他们把“性能”挂在嘴边,在他们心目中“性能”的地位是至高无上的,总是想着你这个方案和我的方案哪个性能更好。
同样可以观察一下周围,中级的开发大多数会这样做事:
其实这个阶段是最危险的阶段,因为最可怕的不是无知,而是一知半解。心理学中的邓宁-克鲁格效应(The Dunning-Kruger Effect)讲述的就是这个问题。
两位社会心理学家在 1999 年做的 4 项研究,证实了下面的这个曲线的存在。
在这种状态下,人最容易高估自己,这也是很多导致产生很多“假高级程序员”的原因所在。
高级程序员在“专业能力”、“连接能力”与“领导能力”这三个维度都有所建树。因为他们不但可以把从 1 到 100 的事情做得很好,也有能力带领其它人完成 0 到 1 的事情。
根据我身边所接触的程序员群体来看,我所认为的高级程序员,他们明白没有什么是完美的,相反,问题、缺点和风险总是存在的。
他们的决策总是站在为了整体的“平衡”角度去考虑,而不是技术的酷炫或者外界流传的所谓“正确的”技术。
他们会更多地关心那些不显而易见的东西,如可维护性、可扩展性、易阅读、易调试等等。
高级程序员就好比社会中的成年人,他们踩过足够多的坑,也填过足够多的坑,已经认清了现实的残酷,寻求适合而不是完美。周到、务实、简单,是他们做事的时候强烈散发出的“味道”。
可以根据下面的这些场景来看看你身边有多少“有味道”的高级程序员?
那么,怎么做有助于我们成为高级程序员呢?
为什么把它放第一点,因为我觉得这点最重要,是其它项的基础,也最容易做到,但是很多程序员不愿意去做。
一定要搞清楚业务目标,不搞清楚不开工。相信我,只要是一位合格的 leader,一定会不厌其烦地和你说清楚的。
然后要习惯基于业务目标去分析可能会面临的技术挑战。比如,多少流量,涉及哪些用户角色和功能,复杂度有多大等等。
再带着下面的“不可能三角”去寻找合适的技术框架、解决方案。尽可能地寻求最优的平衡,而不是走极端。
如果拿捏不准,可以将多个方案各自的优缺点罗列出来,向 leader 寻求建议。
一般人可能拿到需求,就开始写代码了,写着写着由于页面功能越来越多,感觉代码越来越复杂,自己都会觉得难以维护了。
虽说要做好设计离不开大量的实战经验的积累,但还是有些方法可以让塑造这个能力的过程更快一些。比如:
要做这点还得依赖于第一点,否则,你提出的“砍”需求建议大多是不会被采纳的。
很多人在听需求讲解的时候,思考的是,这个功能能不能实现、怎么实现、难不难。大多数的提问也是基于这个思路展开的。
可能也会提出“砍”需求的问题,但是理由大多是这个实现起来太麻烦了,这个没法实现之类。
其实只要你时刻保持着“做这个需求的目的是什么”这个问题去思考,“砍”需求会变成一件更容易成功,而且自然而然的事情。
很多人觉得,每天看到 bug 清完就万事大吉了,哪怕同一个问题在生产环境出现多次,最多也就说一句“不会吧,怎么又出问题了”。
这种对待问题的方式只会让你越来越忙,因为你的解决问题效率与投入的时间多少是成同比变化的。
我们要习惯于解决掉一个 bug 之后,想一下能否通过什么方式找到现有代码中的同类问题,并把它们处理掉。
甚至是考虑有没有什么办法能够一劳永逸地避免此类问题再次发生,比如封装一个 SDK 或者写一个组件,尽可能用一种低侵入的通用方式将问题扼杀在摇篮里。不但让自己轻松了,也造福了大家。
KISS 原则:保持简单,愚蠢(Keep it simple, stupid)。
不单单是程序员,任何化繁为简的能力才是一个人功力深厚的体现,没有之一。
越简单,越接近本质。就好比,有的人要用长篇大论才能讲明白一件事,而有的人只要做一个形象的比喻你就懂了。
这个“简单”指的是整体的简单,而不是通过局部的复杂让另一个局部简单。比如,为了上层的使用更加傻瓜化,底层封装的代码错综复杂、晦涩难懂,这并不是真正的“简单”。
如果你自认为已经是一个中级或者高级程序员了,那么你回头去看看自己还是初级程序员那会写的代码,就会很容易发现一些显得冗余的代码。
第二点提到的——“设计代码而不是写代码”对做好这点有很大的帮助。
在人工智能还不能代替我们 coding 之前,我们永远要亲自面对无穷无尽的、这样那样的问题。
然而,任何事物都有两面性的,一个方案在解决一个老问题的同时,总会带来新的问题。所以,我们一定要意识到,忍受某些问题是必然的。
那些你现在看起来很傻逼的设计,可能就是当时的人做出的妥协。
所以,既然如此,你更应该考虑的是,当前的这个问题现在到底有没有必要解决?值不值得,为什么之前没去解决?它是不是你当前所有待解决问题列表中优先级最高的?
可能很多人都听过“T型人才”的概念,我们程序员在专业技能的打造上也适合用这种模型。
但是对于“先竖再横”还是“先横再竖”可能不同的人有不同的看法。
我的观点是,大多数情况下,先竖再横。特别是某个技术、领域发展得越成熟,越应该如此。
因为很多事物的本质是一样的,所以对某一个领域达到非常深入,洞察到一些本质的东西之后,对其它相邻的领域有触类旁通的效果。可以加速自己在“广度”上的扩展。
不过,“广度”也不是说蜻蜓点水,只知道最表象的“它是什么”。我认为比较合适的程度是,可以不用清楚某个技术具体的使用方式,但得知道它可以解决哪些问题,以及使用成本和潜在的风险,我将这些信息概括为“它怎么样”。
很多人都知道闭环的概念,但是它的重要性和价值往往被低估。因为人总是短视的,“聚沙成塔”之类的方式总是不受待见。
常规的搭建一个闭环的过程大多是这样的。
这里所说的自驱动的“闭环”是这样的。
如何才能变成这样呢?只要做一件事,尽可能多地对外输出自己的知识。
举个我自己的例子,我在 2015 年那会在项目中开始引入领域驱动设计,并且不断地在内部进行分享它的好处,慢慢地越来越多的项目开始往这个方向走。
因为前期的不断分享,所以在组织内部,别人对我的人设多了一个“DDD专家”的标签,那么大家遇到有关 DDD 的问题就会来和我一起探讨。
越到后面,我已经不用自己主动去寻找这个领域的知识去学习了,因为接收到的外部反馈已经足够多了,它们能够倒逼我往前走。并且这些反馈都是实际的真实场景,此时的信息获取和学习自然能达到“学以致用”的效果。
说实话,有不少人并不是这么想的,他们想的恰恰相反:“为什么每个人都在问我问题!你自己去学习吧!”。
所以,当你遇到其他人来请教你的时候,如果恰巧这是你所关注的领域,那么应该去拥抱这个问题而不是排斥它。因为你是团队里最权威的人,这是你构建自驱动“闭环”的好机会。错过这一回,下一回不知道得等多久。
前面文章里说到,我会将“专业技能”、“连接外部的能力”、“领导力”三个维度组合起来给你看。就是下面这个样子。
你会发现这里面包含了程序员在进阶后的几个常见岗位。
可以对号入座一下:D
好了,我们总结一下。
这篇我先和你聊了一下在大家眼中高级程序员是什么样子,发现没有特别统一的标准,都是模糊的。这也体现在了几个现实的场景中,比如招聘高级程序员、培养高级程序员上。
其次,我对初级、中级、高级程序员的特点分别阐述了自己的观点。
然后,给出了一些帮助大家往高级程序员靠拢的实践思路。
希望对你有所启发。
最后,用Martin Fowler 的一句话作为结尾:“任何傻瓜都能写计算机能理解的代码,优秀的程序员编写人类能够理解的代码。”
Any fool can write code that a computer can understand. Good programmers write code that humans can understand
Martin Fowler