从“猿”到“金刚”,九条建议告诉你“超级程序员”是如何思考的

 

稻花香里说丰年,听取人生经验。...


我  相  信  这  么  优秀  的  你 
 已  经  置 顶  了  我


翻译| 李瑞杰 选文| 小象

转载请联系后台

一个10×的程序员,在编程世界的神话中,是指一个程序员所做的工作量是另一个正常程序员的十倍。

对于正常的程序员,我们可以想象他擅长于做自己的工作,但是却没有10×程序员的神奇能力。

实际上,为了更好地描述“正常程序员”,可以这么认为:在专业的程序员这个阶级的人群中,他代表着平均的编程水平。

正常程序猿
10x程序猿
编程社区在关于是否存在如同“野兽”般令人吃惊的10×程序员这件事上,两极分化很严重。谁敢说世界上没有10×程序员的存在,谁又敢说世界上不仅存在10×程序员?如果你知道去哪里寻找的话,指不定还会发现100×程序员呢!

如果你看到程序设计为“线性”的学科,它是明确的,那么10倍的程序员看起来像一个理论上的可能性。一个赛跑者怎么会比其他人快十倍?或一个建筑工人可以用同样的时间做出十倍于别人的建筑?

然而,编程是一门设计学科,是一种非常特殊的方式。即使程序员不参与程序的实际体系结构设计,实现它的行为仍然需要实现策略的子设计。
因此,如果一个程序的设计和实现的工作量不是以线性增长来算的话,那么诸如经验、编码能力、知识、对无用部分的认知等,在我看来,不仅仅是基于线性的优势,它们在编程的过程中将以乘法的方式协同工作。

当然,当程序员能够同时处理程序的设计和实现时,这种现象将变得更为常见。

任务越具有“目标导向性”,一个潜在的10×程序员越有可能利用自己的能力以更小的工作量来完成这一任务。

然而当手头的任务越趋于“硬性”,具体来说就是对于这些任务该使用什么工具以及如何使用有明确的指导原则时,10×程序员在较少的时间内完成大量工作的能力将被削弱。



其实这种情况下,仍可以通过在“局部”精巧的设计来将工作做好,但是不能通过更深刻的方式来改变达成目标的路径,这其中有可能包括,通过删减项目说明书中部分的内容,以使其在很大程度上减少工作量的方式,完成与要求相同的目标。

作为程序员以来的二十多年的工作生涯中,我观察和我一起工作的其他程序员,作为同事,通过提供Redis以及其他项目的补丁包来指导他们,以期完成既定的目标。

与此同时,他们相信我是一个非常高效的程序员。考虑到我并不是一个工作狂,所以我也常把自己作为评判编码的快慢参照。

以下是一系列我认为能给程序员的工作效率带来很大提升的建议:
裸编程能力:完成子任务


一个最能凸显程序员能力的事情是处理实际执行任务部分的子任务,如:函数、算法或其他。令人惊讶的是,根据我的经验,使用基本命令式编程结构有效地实现某些东西的能力并不像人们想象的那样广泛。

在一个团队中,有时我观察到连一些很简单的排序算法都不知道的非常不称职的程序员,都比在理论上十分精通但在执行解决方案的实践中非常差的程序员能完成更多的工作。
经验:模式匹配
根据经验,我指的是一组对于一些重复出现的任务早已探索过的解决方案。一个有经验的程序员甚至知道如何处理与之相关的各种子任务。这避免了大量的设计工作,特别是,对于防止设计错误的发生是一个非常有力的武器,然而,反过来看,这却又是简单的最大敌人。

焦点:实际时间VS假想时间
在不查看所花时间质量的情况下,编写代码所花费的时间是无关紧要的。缺乏注意力可以由内外因素产生。内部因素是拖延,对手头的项目缺乏兴趣(你不能做你不喜欢做的事情),缺乏锻炼/幸福感,可怜或很少睡觉。

外部因素是频繁的会议,没有实际办公室的工作环境,同事经常打断等等。试图提高注意力并减少干扰,这似乎很自然,这将对编程效率产生非边际影响。有时为了提升注意力,需要采取极端措施。例如,我只会时不时地读电子邮件,对大多数邮件都不回复。
设计牺牲:杀死5%来获得90%
经常地,当不情愿意地意识到对于项目来说,一个非基本的目标具有很大的设计复杂度,或使另一个更重要的目标变得更难实现时,复杂性便应运而生,因为在基本特征以及非基本特征之间存在着一个设计张力。

对于一个设计师来说,要识别一个设计中不容易取胜的所有部分是非常重要的,也就是说,努力与优势之间没有比例关系。

为了最大化输出而执行的项目,将集中于那些重要的方面,并且可以在合理的时间内实现。例如当设计Disque,一个消息代理时,我意识到通过在某些点提供更好的短信订购服务,该项目的其他方面都可以大幅提高:可用性、查询语言和客户的互动,简单性及性能。
简单


这是一个明显的点,意思是全部和没有。为了理解什么是简单性,通常值得对复杂度是如何产生的进行检查。值得检查复杂度是如何生成的。我认为,复杂性的两个主要驱动力是不愿意执行设计牺牲,以及设计活动中错误的累积。

如果你认为在设计过程中,每一次朝着错误的方向走下去,我们会越来越远离最优解。

一个初始设计错误,要是解决的方式不当,将不会对相同系统再次设计,而是将会导致设计出另一个复杂的解决方案,以应付最初的错误。因此,在每一个错误步骤累计过程中,项目中变得更加复杂,效率更低。

简单的方式可以实现的理由是小金属“概念的证明”,使大量的简单设计可以探索在程序员的头脑,开始工作从看起来最可行和直接的解决方案。之后,经验和个人设计能力将允许改进设计,并为需要解决的子设计找到合理的解决方案。

然而,每当需要一个复杂的解决方案时,重要的是要长远角度思考如何避免复杂性,如果没有更好的可能性,即使考虑到完全不同的选择,也只能继续朝这个方向努力。
完美主义:如何杀死你的生产力及影响你的设计
完美主义有两种变体:其一是追求在程序中达到最好的可衡量的性能的一种工程文化,其二是一种人格特质。我认为这两种情况下均会成为程序员快速交付的最大障碍之一。

为了仅根据心理或平常的测量参数改善设计,完美主义以及担心外部审判对设计的偏见将导致更少的选择, 故而诸如鲁棒性、简单性、按时完成任务的能力经常无法全部照顾到。

知识:有些理论会有所帮助
当处理复杂的任务时,有关数据结构、基本计算极限、非常适合特定任务建模的巧妙算法的知识,将对找到合适的设计方案产生影响。在每一方面都成为超级专家,不是必需的,但至少要意识到对一个确定的问题将会有许多潜在的解决方案。例如,为了在一个流程中独特的项目,将应用设计牺牲以及概率集基数估计结合起来,从而可以避免一个复杂的、缓慢的及内存低效的解决方案。
面向底层:了解机器
程序中的一些问题,甚至在使用高级语言时,都源于对计算机将如何执行给定任务的误解。这甚至可能导致重新设计及执行一个项目的需要,因为工程中使用的工具或算法有一个根本性的问题。

良好的C语言能力,了解CPU的工作原理,清楚地了解内核的运行方式以及系统调用是如何实现的,可以避免后期许多不必要的麻烦。
调试技巧
花费大量的工作去找一个程序错误是很常见的。擅长获取bug的状态,逐步地,用一组合理的步骤来修复它,以及编写不太可能包含很多bug的简单代码的能力,将会对程序员的编程效率产生很大的影响。

一个高水平的程序员有10倍的工作效率对于我来说不是个奇怪的事情,再加上他们从开始就可以实施一个可行的模型,并且设计比替代方案简单好几倍。

有一种强调简单的方式,我喜欢称之为“机会编程”。

基本上,在软件开发过程的每一步中,为了既可以以最小的精力完成项目需求,还要实现对使用该程序的用户有最好的效果,我们将会选定实施该方案的一系列必须的特性。
译者介绍




李瑞杰

大连海事大学硕士研究生在读,对智能优化算法感兴趣。


    关注 小象


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册