梦断代码(Dreaming in Code)

https://book.douban.com/subject/3142280/

20世纪90年代科技行业的兴盛,给我们带来了”互联网时间”的概念。该短语含义的理解见仁见智,但多指”快速”之意。数字时代的新时间机制下,一切皆有可能发生,技术生产,公司创立,创造财富,而且速度惊人。这意味着你没有时间做到尽善尽美,无须担心因为别人也一样。

和摩天大楼,水坝等等永久性建筑一样,桥梁体现了人类对于物理世界的技术的把握。在过去半个世纪里面,软件成为构建这个世界的虽不可见却深入渗透的人造物。“人类文明运行于软件之上”,广为应用的计算机语言C++发明人说。这里我觉得软件似乎更加反映人类的逻辑,人类所有的软件都是人类的逻辑的结晶。人类的逻辑没有办法考虑周全,所以软件也永远没有完美,也不可能完美。

让托伊害怕的并非44号缺陷本身,而是无法确定需要多长时间才能修正缺陷。依此类推,历数Chandler中类似的不可知因素,加起来就变成了开发经理的噩梦。日程中的黑洞充满了不确定甚至是不可知的因素的时间陷阱。

在2002年10月Chandler首次官方声明之后的9个月里面,他们经历了布鲁克斯在人月神话描画的种种困境。尽管他们采用了诸如邮件列表,blog,缺陷追踪,原代码控制等工具,但和他人保持一致仍然极其困难。每次延误,总让人想要雇用更多人力,但是新增的人力似乎根本无法助于推动进度. 在大型团队中,保持一致性是最难办的事情,组织是关键。

六月份迈克尔托伊开设了blog,讲述他作为OSFA的开发经理的工作状况。在第一篇帖子中他反思了为什么Chandler的进度如此慢如龟行。他比较了他在OSAF和网景公司的工作经历,把部分原因归咎于OSAF更为民主化,缺少等级式结构。无论是大教堂还是集市,都认为等级式结构是将顽固的程序员组织起来的有效手段。我们尊重集体意见,很慢才能作出决定,最重要的是做出好决定。在网景公司写代码是重中之重,所以只要是有助于解放人力,有助于开始写代码的决定就是好决定。OSAF问题在于,真的很难为编写代码清除障碍。

Linus说“在科学领域里面,人们互相察看引用各自的成果,整个系统建立与这个基础上面。而在魔法界则有人暗藏秘技,也不会让别人真正理解乃至使用。传统软件就像是魔法。历史上魔法最终消亡了。历史将在软件开发中重演。当问题趋于严重的时候,就不能够允许个人或者是个别公司抱有秘密。应当让所有人分享知识。

计算机是用来延展人类智慧的,恩格巴特希望它强大而多用。他可不愿削足适履,满足人们在几天或几个星期内学会使用的需要。恩格巴特关于人类适应机器的想法,在后来几十年里得到了一些人的响应。如计算机先驱Alan Kay所言:“不论好坏,恩格巴特都是在致力于打造一把小提琴。”但是大多数人并不想学小提琴。简易与强大,方便与精细之间的拉锯战,贯穿了后来软件发展史的每一阶段。关于可用性原则,我们中的多数人一开始都有一种可以理解的成见:计算机应该让工作变得更容易,为什么不让他们干重活呢?但是将恩格巴特的程序视为“对抗人类”并不公平,因为其全部目的就是找出如何让技术帮助大幅提高人类思考效率的办法。

回到IT产业喜用的关于做软件和建桥梁之间的类比,1995年那份报告认为软件的问题不只与中途纠正和后期设计更改有关,这些情况都是桥梁建筑师所不能忍受的;它还存在无法从失败中吸取教训的问题:“如果桥塌了,就要做调查,写报告说明失败的原因。而在计算机产业中失败案例总是被遮盖,被忽视,并且或者被说成是合理的,结果我们不断重复同样的错误。”

把生活的某些方面融入到软件代码中之后,就很容易被各种新奇诱人的可能性所迷惑,看不到自己放弃了什么。设计良好的程序在提供大多数新特性的同时,并不试图对抗进化过程留给我们的物理世界倾向。(我从昨天就记得这个按钮在哪儿,因为大脑能记忆空间中的位置,所以明天最好还能在同一个地方找到它。)

选项太多,往往导致软件项目在选择编程语言是随性所谓-根据个人品味,习惯或者是心血来潮。

软件界有太多势不两立的标准,举目之处,四顾皆是。计算机系统中的每一点差异(你用什么中央处理器芯片?什么操作系统的哪个版本?什么编程语言?什么数据格式?)如此等等,都能惊醒乐高之梦。如多部软件工程著作的作者罗伯特格拉斯所言,程序员们很久前就解决了“小复用”问题,通过构建子程序库来为自己减负的,一直悬而未决的问题则是“大复用”,创造并使用真正有用的软件大型可复用组件。“无关乎志向格,亦无关乎技能”格拉斯写道,只因为难题源自软件的多样性,根深蒂固且难以解决。

对于Chandler的前台,卡普尔比较清楚自己想要什么,以及它如何体现Agenda之魂。不管Chandler的后台做成什么样子,都要满足卡普尔关于前台的想法,但到底该做成什么样子呢?OSAF的程序员们努力开始编写程序,他们总会撞上没解决的问题。Chandler的资料库,程序的数据存储仓库,是否应该采用RDF三元格式?就像萨奇在Shimmer原型系统中那样?如何保存用来构造Chandler的Python对象,也在资料库中放置可行吗?如果Chandler要支持P2P,数据共享资料库如何管理这些数据?如果Chandler资料库保存在家里的计算机中,而你又想要在办公室用到这些数据,该怎么办呢?怎么办?程序员们明白,如果没有得到回答,就无法进行下去。他们停步不前,用软件行业的惯用语来说,他们被锁定了。

安德森的“我发现了最佳方案”和托蒂克的“我们自己也能轻松做一个”,再次体现了软件复用天生的两难选择。创建还是借用,每个软件项目迟早都会到达这个岔路口。世界上到处都是别人写好的代码,拿到新项目中使用难道不是很容易吗?那为什么还有许多程序员扫了一眼现有的代码,就不容置疑地宣称,他们自己也能写出具有相同功能,而且更快更容易更好的代码呢?

想要走向这种编程乌托邦之路的程序员,大多都发现此路不通。诺博尔和利多的研究指出了最大的障碍。他们同另外两名同事一起研究了,采用面向对象技术的真实程序中的大量软件对象,发现这些构建块完全不像是乐高积木。如果软件组件像乐高积木块,那么它们就应该细小,不能再分,可被替代;它们之间应该更为相像;它们应该只能与有限的几种相邻组件拼合。然而当诺博尔和毕多观察真实程序时,他们却发现,真实程序中的组件在尺寸上,功能上,以及与其他组件的可拼合数量上差异甚大。它们大小不定,就像不规则的形体,不像乐高积木。诺博尔和毕多发现他们称之为“普遍多样性”的现象,目力所及之处,有常者惟无常。想想看一套乐高积木,其中一些积木块只有半英寸长,而其他积木块则长达半英里,有些用硬塑料制成,有些则是液态或气态,有些积木块借由大家熟悉的凹凸结构相互连接,而另一些则用上了焊接胶水或绳索。

大多数程序员喜欢写程序,甚至胜过沐浴和饮食。他们中的大多数宁肯写代码,也不愿意详细察看文档或者是目录,或者是去找其他笨蛋程序员写的蠢代码。在同等条件下,程序员会选择从头设计构建,而不是重复利用。有时候软件开发者深受”此处尚未创造”综合症的折磨,偏信于自己的技术和所在的研究机构的力量,以至于不相信他人创造的东西。有时他们不肯花时间研究其他人的工作,甚至不肯瞥一眼别人的东西是否符合自己的需求。对于典型的程序员,即使要花2分27秒去找一样的东西,他们就会认为这个东西不存在,就会去重新创造它。

在卡普尔和OSAF所有人的想法中,Chandler的资料库应该支持那种灵活适应,自由变换和非地窖式的存储,体现出Agenda之魂。而且它还该支持P2P架构设计所需的在线同步功能。ZODB够用了吗?谁也说不准,除非是自己写的代码,否则很难确定一段代码是否真的管用。程序员们一旦发现可复用软件之梦,有一个悖论,几乎总能找到一段满足大部分需要的代码,但这些拿来的代码,所不能做到的部分,恰恰是项目与众不同的创新之处,也是创建这个项目的出发点。

部分原因在于,尽管卡普尔世间的一切事物的最终决策者,他真感觉自己没法左右关于资料库的争论,而且也不愿有所偏向。安德森虽然坚信和清楚自己的技术选择,却不够果断坚决。当别人提出问题,他总要再花时间去考虑。但最主要的问题却是,大家都在等瑞斯麦卡斯柯开始构建资料库,而麦卡斯柯却感到蒙特利和托蒂克把Chandler带入歧途,他认为他们总在重改前议,比如关于Python和ZODB的选择。后来他说如果当初没受这种个人情绪影响,他也许能找到更有力的技术观点来反驳他们,然而他只是满怀沮丧的看着对方实施“阻碍策略”。而在蒙特利和托蒂克看来,麦卡斯柯不能胜任,无法很快作出OSAF能用的东西来。蒙特利质疑对象持久化是否值得付出劳动。他认为对象持久化更像是象牙塔里做的白日梦,而不是真实有用的编程技术,。

“我压根就没看过ZODB,”维达后来回忆道,“时间紧张倒是可以复用ZODB,但是得花时间学习。我还可以复用在动态对象系统方面的经验,再做一套类似的东西,这样更快。否则我就得去拆解ZODB,找出其运行机制,再把Chandler嵌入进去。”“而且对于资料库有许多落差极大的需求,既要能共享又要能复制。当然ZODB肯定也能做到,不过如果我可以全盘控制,就能做得更快更好,更符合Chandler的要求。还有ZODB是用Python写的,如果我们以后想不用Python就会受困于此。我喜欢做灵活设计,即便需求或其他什么发生了始料未及的改变,我们也手到擒来,说这没问题。”

如果说以代码行数计算不太可靠,那么衡量软件生产力的其他通用的方法也同样不可靠。你可以更新程序特性或者是功能点,但是他们很难被整齐划分成为难度或者是尺寸相似的单元,只能以对每一个特性完成时间主观预测告终。

温格伯指出,要点是”非正式机制总是存在,而且如果没真正理解就改变它是很危险的,要避免扰乱原本运行顺畅而且你无法以同等代价替换的系统”。与此同时,程序员已经发明了自己的非正式沟通机制,他们发明了一系列技术好让彼此保持联系,他们通过各种新的团队协同工具拓展了软件领域。

在软件管理中,协作不是马后炮,也不是无足轻重的事情:它是工作的核心,决定采用何种工具和方法有可能成就或者是毁掉项目,但是同时管理这些工具容易诱使项目偏离正轨。

通常由程序员负责猜测程序该如何应对用户输入和机器状态上千种可能的组合,但是他们却不擅于站在用户的立场考虑问题,想出合理之策。他们花费大量时间纠缠于数字化细节,他们被调教得按照自己做出的系统一般运作。他们视之为理所当然的概念,对于非程序员而言纯然是怪异之举。他们多半不了解用户的想法(程序员常依赖一种称为妈妈测试的手段,以对计算机一无所知的父母家乡用例,有时候甚至请这类用户亲自体验)。

用亚历山大的术语来说,有机增长的真实城市,以及人类关系的真实结构,是以“半格点”形态存在的。半格点是比树状更松散的结构,仍有继承层级,但允许子集重叠。为什么建筑设计和规划社区总是树状结构呢?亚历山大认为半格点更为复杂和难以描述,而且我们不可避免的倾向于采用更易于把握的树状结构。但是这种“每个思维简单的人都患有的将同名物体放入同一篮子的狂躁症”却在城市设计中导致了人为的约束和隔离。“采用树状结构就是以人性和鲜活城市的丰富性为代价,去换取概念上的简单性。这只便利了设计师,规划师,行政官员和建设者。每当城市被撕开一块,用树状结构代替了原先的半格点结构,城市就向着分裂又迈进了一步。”

作为设计师,我们都需要更多用于来展示自己设计了了不起的东西。初次成功的人特别是年轻时就取得成功究竟是靠运还是靠本事?两者都有一点。如果你能够做到另外一件了不起的事情,那么就能够让世界看到你的实力。

Mozilla开发者么决定全部重写浏览器”布局引擎”,在屏幕上画出网页的代码。这一决定的结果是让项目花了好多年时间,外界对此颇有微词。但是那是一个关键性的决定,即便是一个错误的决定。然后设计出可运转的工程进展计划。

方法论的真正目的是卖书而不是解决问题。方法论的关键问题在于,那类发明方法论的聪明人实施方法论时就会有用,但是如果让那些只是知道听令行事的笨蛋来实施,即不管用了。

约束是朋友,是打造伟大产品的关键。约束产生创意,如果有人说给你全世界的财富,让你任何想做的东西,那么这个东西多半永远发布不了。给我一个月的时间就好。

罗森伯格法则:软件好做如果你只是想完成旧任务。一旦完成新的任务软件就不好做。由于软件不好做,所以只有完成新任务的软件才是值得去做的。

抽象并未真的想人们打算的那样简化我们的生活,漏洞抽象法则意味着,无论何时有人拿出一套本能够提升我们效率的所见即所得代码生成工具,你总会听到许多人说”先学会学怎么手工操作,再用所见即所得工具节省时间”。所有抽象节省了工作的时间,却没有节省学习的时间。总而言之,尽管我们拥有了越来越高级的编程工具和抽象,但要成为编程高手越来越难。

软件领域感觉特别像《土拨鼠日》,想法总是雷同没完没了。因为我们相信只有想象中的计算框架是可行之路。虽然硬件一直在加速,但是软件却毫无改进,这是计算机科学的奇耻大辱。但是程序员们却自满起来,接受了不能够令人满意的现状还视其为恒久不变之事。

软件的大问题在于,程序员起步于小程序,并且在小程序上学习原则和实践经验。但是当程序膨胀到今天的项目一般体量的时候,他们发现所有的经验都没有用了。

我们对象成为作家和诗人的学生的要求,比对那些想成为软件开发者的人要求多:他们跟随导师,他们得在讨论班上展示自己的作品并且接受他人的批评,他们反复推敲,不断精炼。我想我们应该感到羞愧,我们拿得出手的所谓计算机教育简直就是一出闹剧。

艺术是由人类智慧所作之物,相对于源自天然或者本能的行为而言。假设要在人造物和自然物之间划分界限,那么任何与计算机相关之事都会毫无疑问地落在艺术这边。

要在大型项目中保持高效,你得效忠于他。你要将它印在脑海中,我在做大型项目的时候常常睡觉也梦到代码。

如果设计师知道编程的话,那么就会固步自封。一旦知道怎么编程,那么你就会想做那样的东西太难了。

SWAG(silly wild-ass guess)盲估就是估计任务的耗时,就是要求开发者在Bugzilla填写任务完成的预计时间,不过不同的是要求任务更细。一旦任务更细粒度更小估计时间就越容易了。

Richard Stallam喜欢说”如果有人问我这个事情什么时候结束,我总是回答只要你来帮忙,就会完成得快一些”。

老程序很少拥有新潮的图形界面或者是风行一时的特性。但是它有一种不可低估的优势,以工作为取向。适当使用的程序就像是精心打理得旧花园,或者是轻柔弹奏的老吉他,其粗糙边缘已经锉去,缺陷已被发现和修正,人皆知其表现物有所值。

由于重复周期和无限期的延误,变成工作总是让人想到薛西弗斯的劳役没完没了地推石头上山,典型的无用功。我在研究过程中访问和认识的多数程序员始终如一,而且有时毫无由来地对工作持有乐观态度。如果他们是薛西弗斯的话,也会是快乐的薛西弗斯。

诚然,微软是历史上最成功的软件公司,年复一年地赚取几十亿美元利润。它的行为值得留意。另一方面,与其他竞争对手相比,或与那些编写公司内部软件的程序员相比,微软也不乏进度延误和忽视缺陷的情况。微软正处于在规程上要求万事齐备的阵痛之中,不再以一致水平制造人们愿意购买的产品。他们太过沉迷于过程,到了任何微软产品都要花6个月才能发布新版本的程度,他们真的开不了快船。在SP2上花了差不多一年的时间,出于安全考虑,他们做了件好事,不过它的作用基本上也就是清理维护和打补丁。这就是军队叫做内务的东西,在军队里内务就是保持装备在最佳工作状态的一切事情:擦鞋,刷牙,时刻准备着,子弹保持清洁,确保枪膛里没沙子。所有这些都叫做内务,步兵每天要花两个钟头做这些事,但他却不是你真正想要干的事情。微软现在到了大概百分之八九十的时间都在做内务的阶段。

当然编程领域能够也将继续改进其技术和能力和工具,程序员向来乐于自扫门前雪,他们不太可能会停止打磨算法,改进后台代码,调优开发平台。然而这就是在磨斧头,或者给牦牛剃毛,他们没触及问题的根本。实现人类世界中某个功能的任何机制,迟早都要脱壳而出,与人交流。究其根本,信息系统仅在与人接触时才有所价值。而一旦与人接触,对于完美的追求就消散于无形了。软件之本质困难,乃是强加于技术进步的人类自由意志和不确定性的通行费。尽管计算机科学的兴起,让许多科学家借其透视人类机体,例如假想人脑的功能映射到计算机结构上,而个体的人却仍旧不可被编程。人们之所为,就连最具想象力的程序员也无法预料,人们之所愿,程序员更不可预期。