学会“投机取巧”——Redis之父九条忠告,如何成为“一打十”的程序员
japn1580
8年前
<p>据维基百科记载:“ <strong>Redis</strong> 是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。根据 月度排行网站DB-Engines.com的数据 显示,Redis是最流行的键值对存储数据库。”</p> <p>Redis 之父 Salvatore Sanfilippo,一名意大利程序员,大家更习惯称呼他 Antirez。本文为Salvatore所写,CSDN编译,具体讲述了其心目中成就一名“野兽级”程序员的可贵品质。</p> <p>坊间流传着“十倍程序员”的传说,所谓“十倍程序员”是指在同样时间内可以做“普通”程序员十倍的工作的程序员,而所谓“普通”是指那些擅长自己的领域,但不具有“十倍程序员”那样特殊魔力的程序员。更准确地说,普通程序员就是指那些具有平均编程效率的专业程序员。</p> <p>在程序员群体中,对于“十倍程序员”的存在持有极度分化的观点:一些人认为这样的人绝不存在,另一些人则认为不仅存在,而且甚至存在“百倍程序员”。</p> <p>如果你认为编程是一项线性工作(产出与劳动时间成正比的工作),那么显然“十倍程序员”是一种不合理的存在。一个跑步运动员不可能比对手跑得快十倍,一个建筑工人也不可能在同等时间建造十倍于别人的东西。然而,编程实际上是一项特殊的“设计”工作。此处设计不单指架构师的工作。即便不是项目的整体设计,当工程师具体实现它的时候,依然需要低层的实现策略的设计。</p> <p>在我看来,程序的设计和实现不是一项线性工作。经验、代码能力、知识、对不重要事项的辨识能力都是不易量化的能力,这些能力的结合在程序开发中发挥重要作用,使程序员更高效。特别是当一个程序员需要全程参与到项目的设计与实现时,这些能力的优势更加明显。</p> <p>越是以结果为导向的任务越能激发高效程序员的能力。因为在结果导向的任务中,高效的程序员能够找到自己的方式,用更少的投入达到同样的效果。他们可以从顶层改变目标的实现路径,有时甚至直接去掉不必要的模块,来减少工作量而不影响目标的达成。而相对要求严格的项目,则会使这种效应减弱,因为程序员不得不受到诸如“使用某某工具”,“通过某某算法”的限制。虽然如此,高效程序员在这种多限制的情况下仍有其优势:他们可以发掘细节处优化实现的办法。</p> <p>在我二十年的编程生涯中,始终观察我身边的程序员,无论我的同事、学徒,还是Redis或者其他项目的贡献者,以指导他们高效地达到既定目标。很多人说我是个很“快”的程序员。鉴于我不是个工作狂,所以我想以我为例来说明如何高效编程。</p> <p>以下是我认为影响程序员工作效率的最主要因素:</p> <p><strong>纯编程能力:不写一行多余代码</strong></p> <p>程序员的纯编程能力是程序员水平的最直接表现。在解决实际问题时候,程序员经常会被要求实现项目的某一个子模块,一个函数或者一个算法等等。令人惊讶的是,我发现在这个过程中,很少有人能够做到用最少的命令高效地完成任务。我甚至发现在很多团队中,竟然存在会忘记使用排序算法的不称职的程序员,这让他们甚至无法胜过虽然缺乏实践经验但理论完备的毕业生。</p> <p><strong>经验:踩在前人的肩膀上</strong></p> <p>所谓经验,我指的是重复出现的任务的成熟解决方案。一个有经验的程序员知道如何处理各种任务。这可以避免重复设计,更重要的是可以避免设计错误,设计错误是程序员效率的最大敌人。</p> <p><strong>专注:高效利用时间</strong></p> <p>对于任何事情,时间的有效利用都至关重要,许多内在和外在的因素都会导致程序员丧失专注度。内在因素包括拖延症、没有兴趣、缺乏经验、睡眠短缺等。外在因素包括频繁的会议、工作环境、同事的干扰等。提高专注度、避免打扰能够提高编程效率,这很好理解。有时,为了专注,需要狠下心来,采取较为极端的措施。比如邮件,虽然都会看,但只回复很少的一部分。</p> <p><strong>不要吝惜时间设计:防止推倒重来</strong></p> <p>很多时候,程序员非常不情愿看到的一种情况是,需要在一些无关紧要的功能上浪费大量的时间,但你又不得不去将这个无关紧要的功能实现,因为它牵扯着这个项目的主要功能。这种时候,就需要反思,在顶层设计的时候是否考虑周全。详细而缜密的顶层设计能够减少上述情况的发生,即降低模块间的耦合性。对于项目的设计者来说,意识到每一个细小的模块都有可能成为项目的瓶颈,这很重要。对于项目而言,最终的目标是合理的时间做最大的产出,那么实施重点就应该放在项目最主要的模块上。拿我设计Disque(一个开源的分布式消息队列)为例,我意识到只要提供最优的消息排列方式,至于项目其他锦上添花的方面都可以后续慢慢补充,例如,可用性、查询语言、客户端交互、简易性及系统性能。</p> <p><strong>简洁性:避免细节错误才是程序简洁的根本</strong></p> <p>简洁性意味着很多。为了理解什么是简洁性,首先来看看究竟可以多复杂?我相信导致复杂性有两个罪魁祸首,除了上面所说的不愿意花费过多的时间在设计上,还有一个是在设计过程中错误的累积。</p> <p>思考一下程序实施的过程,所谓失之毫厘,谬以千里。一个初始的设计错误可能不会导致所在功能的重新设计,但可能会导致开发者需要在其他功能上做大量的工作来应对这个错误。因此,项目一步一步走向复杂和低效。</p> <p>简洁性需要一步一步实现。程序员可以从最直接可靠的解决方式开始入手,用尽可能简单的方式实现功能,之后随着经验和编程能力的提高,程序员就有能力去优化设计了。</p> <p>每次遇到不得不采取复杂的解决的方案的情况,开发者都应该花些时间想想如何避免这种情况的发生。只有在考虑了各种不同的方式,发现不得不走这条道路的时候,才继续在这个方向上前进。</p> <p><strong>完美主义:高效产出的最大阻碍</strong></p> <p>完美主义有两种类型,一种是追求至高性能的工程师文化,一种要符合个人趣向的执拗。两种情况都妨碍到程序员快速发布项目。完美主义和对外界评价的在乎会使程序员过多地将关注点放在一些细枝末节上,进而主观忽视项目的关键特性,例如程序的稳健性、简洁性、及是否能够按时交付。</p> <p><strong>知识:某些关键问题还是要依靠理论解决</strong></p> <p>当处理复杂的任务时:数据结构知识、对计算能力的极限的了解、对针对某个任务最行之有效的小众算法的了解,会帮助我们解决这些任务。对于开发者而言,对所有问题的所有解决方案都了如指掌这不现实,但对于某类问题的多数潜在解决方案都有所了解是必须的。例如,容许一定错误率,考虑概率集合基数估计量,可以设计一个优化的流的元素计数算法,避免复杂,缓慢,空间效率低下的缺点。</p> <p><strong>底层:熟悉计算机的脾性</strong></p> <p>即便我们使用的是高级语言,但不了解计算机的内部运行机制仍然会导致一些问题。有时系统会出现涉及到底层问题的工具或算法错误,导致整个系统的重新设计实施。深入理解C语言、CPU运算机理和操作系统内核会避免我们遇到在项目后期“推倒重来”的情况。</p> <p><strong>Debug能力:无需多言</strong></p> <p>寻找Bug总是非常耗费时间的。擅长发现、定位并合理地解决Bug,以及在编程过程中尽可能简化程序以减少Bug,这些素质将极大地提高程序员的编程效率</p> <p><strong>总结</strong></p> <p>对于我来说,一个拥有以上素质的程序员,能表现出“十倍”于平庸程序员的效率是绝不意外的。往往,他们在项目开始的可行性研究阶段就能做出正确的决策,这样一来,数倍于常人的效率是很容易实现的。这种方式我称之为“取巧编程”,意思是在开发过程中的每一步都选择最优化的解决方案,花费最少的努力获得最大的用户体验。</p> <p> </p> <p>来自:http://www.iteye.com/news/32180</p> <p> </p>