编译/Anna
原作者/antirez
对于一般的程序员来说,能把自己的工作做好就很不错了。但如果想让一个程序员做十个程序员的工作,那实在是难以想象。而我们所谓的“10x(十倍效率)程序员”,就是指的那些可以以一当十的神级人物。实际上,“一般的程序员”这个叫法可能还有些不准确,应该说成“编程产出量处于平均水平的人”更合适些。相较于更专业的编程人员,他们可能略逊一筹。
关于这样的神级程序员是否真的存在,编程界的观点可谓是两极分化:有的人认为根本不可能;有的人却认为世界上不仅有10x程序员,甚至你真的会找的话,还能找到100x程序员。
如果我们把编程看成是一门“线性的”学问的话,10x程序员的存在的确不太合逻辑。想想看,怎么可能会有田径运动员跑得比其他人快10倍呢?或者说,一个建筑工人怎么可能在相同的时间里完成一般人十倍的工作量呢?但是我们不能以同样的眼光看待编程,因为从某种特殊的角度来说,编程靠的是“设计”。尽管表面上看,程序员们并没有实施什么切实的设计程序,但实际上他们还得在潜意识里先设计好编程的策略,然后才能付诸实践、进入编写的过程。
你也可以这样成为10X程序员
如上所述,我认为程序的设计和编写都并非是“线性”的能力。同样的,我认为诸如经验、编程能力、知识积累,以及辨别“有用”和“无用”能力,都属于“非线性”的优势。把它们放在一起,就能成倍地提高编程的效率。当然,如果你能同时掌握好设计和编写的能力,这种倍增的效果将会更好。
除了这些主观因素之外,还有一些客观的因素,比如程序员的任务本身是否是“目标导向”的。任务越是“目标导向”,那么他们发掘自己能力的可能性就越大,也就更接近实现10x程序员那种四两拨千斤的境界。但是,如果任务非常严格,并且还要求程序员以特定的工具、规定的方法来编程,那么“四两拨千斤”的技能就很难触发了。因为尽管程序员还能在某些地方走捷径,但却无法对编程方法做大幅度创新。在这种所谓的大幅度创新中,程序员甚至可能把项目的一部分彻底删掉,大大减少了工作量,却能达成同样的目标。
我做程序员这行已经二十年了。在这二十年中,我观察了很多一起共事的程序员,也作为团队的领头人带领其他程序员完成过许多指定目标——比如为Redis或者其他项目提供补丁。正是在这一过程中,许多人对我编程的速度表示了肯定。承蒙谬赞,在此我就以自己为例,向大家分享一下快速编程的经验。毕竟我自己不是个工作狂,所以相信我的方法应该也是有参考价值的。
antirez与Redis
以下我列出了一些在我看来,提高程序员工作效率所最为重要的特质。
纯编程能力:完成子任务
“完成子任务”的能力大概是最容易观察到的一项。要想写好一个程序,首先你得掌握好每一个基础函数、算法的写法,这就是所谓的“完成子任务”。掌握得好,它会成为突出的优势;掌握的不好,则会成为工作上的绊脚石。
然而让我颇感惊讶的是,这样一个对于程序员来说最为基础的能力,能掌握的人却着实有限——至少根据我个人的经验来看是这样的。我有时能在我的团队里能观察到两类程序员。一类能力有限,甚至连简单的分类算法都没听说过;另一类是刚从学校毕业的学生,拥有极为完备的理论知识,但真要让他实践起来去编程,表现却很糟糕。然而就完成的工作量来说,前者却往往比后者更胜一筹。
经验:模式匹配
我所说的经验,是指那些你已经掌握了的解决方案。当你掌握了一套既定的模式,你就可以将其应用于大量相似的情境中。在不断开发解决方案的过程中,你会不断积累经验,并最终学会如何处理各种子任务。有了经验,你就能省掉大量耗费在设计上的时间。但更为可贵的是,经验是能帮你过滤掉设计中容易产生的错误。错误可谓是编程简洁化的大敌。过滤了错误,也就更容易提高工作效率。
注意力集中:实际时间VS假定时间
如果要算我们花了多少时间写编码,只看表面的时间是没有意义的(因为你只是假定了在那段时间里你都在全神贯注地工作,而实际上并非如此)。我们必须要看所谓的quality time(实际有效的工作时间)才行
注意力不集中的原因有两方面:主观原因和客观原因。主观原因包括拖延症、对手头上的项目缺乏兴趣、缺乏锻炼导致的身体状况不佳、缺乏睡眠等等。而客观原因可能是会务繁忙、工作环境不佳、同事的频繁打扰等等。集中注意、减少干扰能够大幅提高一个人的工作效率——这似乎算是个不言自明的道理。有的时候为了集中注意力,你得采取一些极端的办法。拿我来说,电子邮箱我只会偶尔地看一看而非天天查收,甚至其中大部分的邮件我都是不会回复的。
设计过程中的牺牲:学会避轻就重
有的时候我们会发现,某些不重要的任务反倒最为繁琐、或者会反过来阻碍首要任务的达成(因为首要任务和非首要任务在设计时是存在冲突的)。这种时候,设计的复杂性就涌现出来了。
作为一名程序设计师,你必须意识到设计的方方面面都不是轻而易举的;也就是说,花费的精力和带来的好处是不成正比的。一个旨在产出最大化的项目必然会把精力放在那些既重要又可以在合理时间内实现的事情上,所以你得学会“避轻就重”,牺牲掉不重要的那5%来换取90%的完成度
举个例子,当我在设计一个叫Disque的消息代理时,我突然就在某一刻意识到,只要为消息提供尽可能最好的排序,项目的其他方面就都能得到大幅提升:包括可用性、查询语言以及客户端交互、简洁性和性能等等。
简洁性
显而易见,简洁性这一点至关重要。但是首先,为了理解什么是简洁性,我们不如先看看复杂性是如何产生的。复杂性有两个主要成因。一是程序员不愿意进行我上面所说的设计牺牲,二是在设计过程中积累了太多的错误。
如果你仔细思考一下的话,你会发现每出一次错,你就离最佳解决方案更远了一步。一项初步设计错误,如果落到了错误的人手中的话,即便被发现了也是不会被更正的。经手人不会重新编写系统,而会为解决这一初始错误设计出另一套复杂的解决方案。因而项目在每一步错误中都会朝更复杂、更低效的方向越走越远。
要想实现简洁性,我们可以将任务拆分成小部分,然后通过推论对其进行“概念验证”。这样一来,程序员可以在脑海中进行大量简单的设计,然后从中挑选最可行、最直接的解决方案。再之后,程序员的经验和设计能力将进一步帮他提升设计成果,并找出“子设计”任务的合理解决方案。
但是,每当你需要一项复杂的解决方案时,务必要花足够长的时间思考如何避免复杂性的产生。只有在你已找不到更好方法的时候,才可继续发展下去。只要能避免复杂性,即便是大相径庭的方法也务必要考虑。
别再完美主义:你是在牺牲生产力
完美主义的源头有两种:一是出于习惯了工程行业的职业习惯,总是想要在工作中呈现出尽可能好的表现;二是自己本身性格就是如此。无论哪种情形,完美主义都可能成为程序员快速编程的最大阻碍。碍于完美主义或者外界的指摘,他们在设计上会产生偏倚,导致做出糟糕的决定。比如出于心理上的原因、或者无关紧要的可衡量参数去对设计做极精细的修缮。但实质上这种小修小改对程序的健壮性、简洁性、及时交付的能力往往毫无帮助
知识:储备些理论会对你有所帮助
当处理复杂的任务时,相关的知识储备对你寻找合适设计方案的能力是有重大影响的。这些知识可能包括数据结构、计算的根本性限制、适合对特定任务建模的算法等等。你不一定要无所不知、无所不晓,但至少遇到一个问题时要能对应出多个潜在的解决方法。比方说,将我前面说的“设计牺牲”(学会接受一定百分比的误差)与基数估计概率算法的知识相结合,就可以帮你避免掉复杂、低速、内存使用率低下的解决方案。
从底层开始:理解机器
我们编程时出现的许多问题,往往都是因为误解了计算机执行特定任务的方式而导致的。即便是使用高级语言的时候也是如此。就因为使用的工具或者算法存在根本问题,甚至会导致需要从头开始对项目进行重新设计和重新实现。掌握好C语言、理解CPU的工作方式、了解清楚内核如何运作以及系统调用如何实现,就可以避免到最后阶段遭遇突如其来的“惊喜”
调试技能
我们往往很容易在找bug上花掉大量的精力。但是,如果你擅长逐步获取bug的状态、可以在合理的步骤内修补好问题,并且懂得有意识地编写不大可能导致太多bug的代码的话,你的编程效率将会有很大的提高。
在我看来,如果一位程序员具备上述特质的话,能够取得10倍于平均水平的产出并不奇怪。有了这些特质,你就可以先从可行模型着手、逐步实现你的设计,而且做出来的东西往往要比替代方案简单好几倍。为了强调简洁性,我愿意称之为“机会主义编程”。为了实现简洁,基本上在开发的每一步我们都要对使用的功能集进行挑选,才能以最少的精力对程序的客户群产生最大的影响。


继续阅读
阅读原文