【原创】打磨 ——《软件随想录》的随想,以及墙裂推荐


叶材质的手串在台灯下散发着莹润如玉的光泽。虽然凑近了,还能看到许多细小的沟状纹理,但几个月的软布、手掌摩挲之下,已经初见光泽了。

打住,我又跑题了。我要谈的是软件的打磨,而不是手串。

像往常一样,“打磨”这个词是从书里抄来的,郑重地作为这篇的题目。


一、《五个世界》——软件的打磨


《软件随想录》是一个随笔集(由博客整理而来),《五个世界》是其中的一篇。

乔尔(书的作者,软件行业前辈)在2002年,将软件领域分为五个世界:盒装软件、内部软件、嵌入式软件、游戏、用过既抛的代码。这个分类到现在也基本适用。

盒装软件是精品软件,特点是受众广,要经过千千万万的用户检验。(这里的盒装,意为“精美、精品”,不是狭义的盒装。例如,网站也被认为是盒装软件的一种,因为它通过浏览器将服务传递给了千万个用户)。

内部软件只需要在一家公司的电脑上运行,使用范围小、人员比较确定和单一。这大大降低了其开发难度,因为它有许多运行环境的假定。再加上Bug容忍度高,不产生利润,持续改进的边际效用低等原因,其开发完善经常被认为是一种得不偿失的行为。管理者经常以“以经够好了”为原因阻止开发者继续完善,而为其安排其他的任务。这有时会让追求完美的那部分开发者觉得沮丧。(但我们需要正视这种现实)。

嵌入式软件和游戏被作者认为是非常特别的两个领域。前者更新升级难度非常大,对质量要求高,因为没有改正的机会。后者特点是赢家通吃,以及不能频繁地发布升级版。作者认为游戏开发“更像拍电影而不像开发软件”,用一个大卖游戏的收益弥补其他未能火爆的游戏的损失。

用过即抛的代码(没有将它称为软件),不言自明,它是为了某种临时目的,一次性使用的。

冗长地复述作者的“五个世界”划分,是为了引出“打磨”的概念。盒装、嵌入式、游戏三种软件,是最需要打磨的,也最有机会打磨。不打磨就要失败。内部软件通常因为边际效用低、投入预算小,没有机会被打磨(这或者是好事,或者是成为精品机会的丧失,谁知道呢);用过即抛的代码不需要打磨。

从业者务必要了解自己在哪个世界。

好的软件,一定是精心打磨出来的,不论它表面看起来有多么的简单。将“代码”变为“产品”,再将“产品”做成“艺术品”,都不容易(做成艺术品在哪个领域都不容易)。

如何打磨?就是持续提高软件各方面的质量,就是精心设计与实现后,持续地投入时间和精力优化它,逐渐将软件改进得更漂亮、更艺术、更好用、更强大。

但要注意,“消灭软件代码中的错误是一件边际报酬递减的事情”——随着软件中的错误越来越少,消灭一个错误所带来的收益也在变小。所以,即使位于值得打磨的软件世界,也要掌握好度。

打磨旧代码VS推倒重来。有时候一个项目的代码过于混乱,常常让人有重新开发的冲动。在《永远不要做的事情》里,作者郑重提醒读者谨慎对待重写全部代码的冲动,建议在没有充分的、压倒性的理由时,以保守的态度,继续打磨、改进原有的项目。旧代码有时候并不是不好,而是“读代码比写代码还要难”;旧代码有时候不能乱动,比如它里面可能有许多前人解决一些微妙bug的内容。旧代码重写或不重写,有时候甚至是一个战略性的问题,作者举了两个例子,网景和Borland,因为重写整个项目而耗时太长,将市场拱手让与他人。

书中还有大量工程实践中的宝贵经验,比如《揭开冰山之谜》,认真地讨论了Demo离正式产品有多远的问题。不再剧透,有兴趣看原文吧。


二、《帕默斯顿勋爵谈编程》《抽象必漏定律》——技能的打磨


在技能学习的路上,兴奋与沮丧随时交替的心情变化,实在是太刺激了。

“如今的编程学习曲线是呈指数形态的:日常编程知识的90%可以在一周内学会,但是剩下的10%的知识欠缺可能要花几年的时间才能弥补。这10%的知识决定了经验丰富的程序员的价值。一支开发团队需要很多经验不足但能产出大量代码的程序员,更需要几个经验丰富的程序员去处理真正困难的问题,否则团队无法完成任何项目。”

10%就是技能的打磨。

“计算机编程领域可以细分为许多个小领域,每个领域都需要巨大的知识储备才能称得上精通。”

“很少有人能精通超过两个领域的编程知识,因为不下几年的苦功去学习,是很难在某个编程领域登堂入室的。”

所以,当一个万金油(伪全栈工程师之类的),还是领域专家,自己决定吧。

“编程领域之间的巨大差异导致人们经常对于哪个领域更好而发生无谓的争执”,另外,“只熟悉一个编程领域的人就像井底之蛙,每当听见别人抱怨另一个领域的艰难,就越发觉得待在自己的领域里无比轻松愉快。其实根本没有这回事,你只是太熟悉自己的领域,早就习惯了其中的艰难。这些编程领域经过多年的发展,已经过于庞大和复杂,无法进行比较了。就像帕默斯顿勋爵说的‘施勒斯维格.霍斯坦因问题太复杂了,整个欧洲只有三个人懂。其中一个是普林斯.阿尔伯特,死了。另一个是一名德国的教授,疯了。我曾经是第三个懂得这个问题的人,但现在全忘了。’”

为什么这么难?“抽象必漏定律”可以部分回答这个问题。

计算机行业有许多抽象,抽象为我们隐藏了复杂性,让我们可以在抽象之上愉快地玩耍。比如TCP协议,它抽象出了一种可靠的消息传递方式,而屏蔽了下层IP协议的不可靠。但作者说了,“当你养的宠物蛇咬断了网线,导致所有IP包无法通过,那么TCP再厉害,消息也绝对发不出去。或者你得罪了网管,他为了报复你,把你的数据链接放在一个过载的网络集线器上,那么你发出的IP包有很多都无法通过。虽然TCP能够工作,但一切都将变得异常缓慢。”

这就是“抽象必漏定律”,作者以他独特的幽默命名的一个概念,含义为:“所有重要的抽象,都具有某种程度的不严密性”。简言之,一切抽象总有例外。

以前我经常感到,在工作中觉得困难的一个重要原因就是程序相关的细节太多。但为什么有这么多细节,我没有过多的思考。我所欠缺考虑的这第二个问题,这条定律替我解决了。

抽象难免会失效。有时候轻,有时候重。这种情况下,我们就需要揭开这种抽象,探究平时掩盖在抽象后面的细节。我觉得这就好比一个只会开自动挡的司机——他可能连玻璃水都没有加过——却突然要打开引擎盖或猫在车下修车时面临的困境。

“我们可以用抽象节省工作的时间,但无法节省学习的时间”。这就是为什么我们会Java编程还不够,还要了解Java虚拟机,会用函数库还不够,还要去读源码。这一个个“还要、还要”,就构成那困难的10%

“随着我们拥有的编程工具越来越先进,抽象层次越来越高,成为一名熟练的程序员也变得越来越难了。”呃,这真是一个坏消息。


好消息是,我们都早早自发感受到了这个坏消息,并且在现在被作者明确了。那么,大胆前进吧。

三、《给计算机系学生的建议》《学校只教Java的危险性》——人的打磨


国外的作者很少谈人生谈理想啊,(这一点绝对是因为我读的国外译著大部分是技术类的,想必国外的网上也会像国内一样有许多鸡汤帖子),所以读到这部分内容时感觉比较新奇。

作者谈了为什么我们在学校时要学习一些困难的课程,很有共鸣。

我印象非常深刻的是在学校时上的一门《程序设计语言理论》,一门要命的理论课程(内容有λ演算等等)。这门课程引发的痛苦,现在还记忆犹新。当时不理解为什么要学习如此复杂的课程,毕竟大部分人即将从事的工作,工程性更强,而不是研究性和理论性。

作者的回答是:提高你的抗击打能力。作者谈论这个问题时,着眼点比较具体。在《学校只教Java的危险性》里,作者说:“函数式编程……指针、递归……是重要的。除了那些直接就能想到的重要性,指针和递归的真正价值在于那种你在学习它们的过程中所得到的思维深度,以及你因为害怕在这些课程中被淘汰所产生的心理抗压能力,它们都是在建造大型系统的过程中必不可少的。指针和递归要求一定水平的推理能力、抽象思考能力,以及最重要的,在若干不同的抽象层次上同时审视同一个问题的能力。”

作者的看法和我们以往的认识是一致的,因为重要所以再重复一遍:你以为学高数没有用吗?当然有。它不能用在菜市场中,但是能提高处理复杂问题的能力、锻炼耐心和探索能力。这些在编程实践中是万分宝贵的。

作者在书中也提到一些软技能的内容,比如建议练习好写作——大量的写,直到越写越好——但这部分内容少之又少。


四、后记


一些题外话。

《软件随想录》一共两卷,都不厚。卷2是我特别推崇的一位译者阮一峰翻译的,购买之前我就对书的质量非常的放心(不论是原书的选择,还是译的水平。这位译者有个人博客,推荐阅读)。卷1是一位年轻译者,我并不熟悉,网上也查不到资料,出于收套装的完美情结,与卷2一并购入。出乎我意料的是翻译质量相当地高,一翻看作者介绍,一个年轻的毕业没多久的学生。后生可畏。

这套书基本可以归为“道”一类,其对面是“术”一类的书(比如经常见到的关于语言、框架、工具、API的书)。可同归为“道”一类的书中,还有《黑客与画家》《人月神话》等经典,但它们又是如此地风格和内容迥异。《软件随想录》润物细无声,它的装逼属性可能差一些,但真的,有用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值