第0章 软件时间
作者迷恋于一个开放代码并可以由游戏玩家更改程序的一个游戏,并为在它的基础上创新和增添一些功能而乐此不疲。
0代表程序员的思维方式,因为计算机从0开始计数。
“Hello World “ 程序能够唤醒每个程序员心中乐观的一面。既然能叫它说话,就能让它做任何事!
计算机器协会(The Association for Computing Machinery ), 维护了一张网页,上面列出将近两百种编程语言版本的”Hello World” 程序。简直就是程序代码的罗塞塔石碑。
网页地址:http://www2.latech.edu/~acm/HelloWorld.html
为什么就是不能像造桥那样造软件?
人类文明运行于软件之上。软件创建艺术却隐于暗处,即便对于专家们也是如此。互联网时间带来了快速发展的技术产生、公司创立、创造财富等也同时带来了程序的缺陷问题。而对软件开发者来说,则过的是时快时慢:如果灵感到了,一切顺利,则全然忘记时间,全心投入高速的开发之中。反之遇到瓶颈,则举步维艰的软件时间。软件不能像建造桥梁那样一劳永逸可以造福上百年。反而漏洞百出,麻烦不断,错误不停。带来无穷尽的改进和苦恼。
在现代软件研究领域多有建树的专家弗里德里克·布鲁克斯(Frederick Brooks) 在1987 年写了一篇题为( 没有银弹(No Silver Bullet )〉的著名论文。布鲁克斯在论文中称,无论编写计算机程序是如何地令我们倍感挫败,也永远无法找到一种魔法般的突破-我们只能期待渐次前行。1/4个世纪过去了,银弹仍然没有发现。
第1章 死定了
一个错误就可能让一个项目“死定了”。往往带来不可知因素的时间陷阱。
记录于Bugzilla 中的第44 个缺陷,最初于2003 年1 月19 日登记,描述信息是“ 当修改窗体大小时出现闪烁”。。安德森认为这是个小问题,不过还是应该查实和修正。可直到将近六个月之后的今天,他仍然没能修正。问题不在自己和同事编写的代码上,出错的根源在于一个称作wxWidgets 的软件里面,Chandler 小组采用该软件作为项目的构造块。安德森要么等着wxWidgets的开发者修正代码,要么就得绕过问题所在。
软件项目难以按进度安排实现,这种情况极为常见。在软件开发的世界里,进度延误普遍到人们特意生造出—个委婉词来描述它:slippage(失速)。
软件时间自我扭曲再头尾相接,如同莫比乌斯环。一般令人费解。进度忽而突飞猛进,忽而不知何故驻足道中。在你以为大功即将告成之时,却又山穷水尽, 花上整半年时间,一无所得。
IBM System/360 主机操作系统是当时规模最大的软件项目。那台巨大而昂贵的大型计算机,本应是后来二十年中生意场上的中流砾柱,但它的孕育和诞生却饱受延误和成本超支之苦。正如布鲁克斯所言,它变成了一个“沥青坑”, 一个能粘住大企业的陷阱,哪怕对于IBM这样“孔武有力”的公司也不例外。
布鲁克斯法则:
向已延误的项目中补充人力,只会使其继续延误。
布鲁克斯写道,软件开发者通常都是乐天派,他们认定每个缺陷都可以被迅速修正,且修正旧缺陷必能减少新缺陷的数量。
布鲁克斯发现,在实际开发中,编码只占软件项目开发时间的1/6, 有一半时间用于测试和修正缺陷。但只有少数项目经理会真正按照这种思路来安排开发人员的工作时间。
所谓“人月”, 是一种科学管理概念,它假定生产力可被拆分为不连续、无差异、可替换的单元。
布鲁克斯观察到,“只有在任务能分派给许多互相之间无须沟通的工作者时,人和月才是可互换品。
“对于软件而言,项目各有差异、工具不断升级,每当团队中加入一个新组员,老组员就得放下手边的工作,帮助新组员进入角色,每位组员都要等待重新分派任务,好让新组员有事可做。在你意识到这一切之前,已经远远落后于进度了。也就是说,每次重新安排进度计划,都导致雇用更多人力,于是又不得不重新安排进度。
制作软件的大量工作受困于“序列约束",它限制了任务分解的程度:完成某项任务是处理其他任务的先决条件,这与人力投入多少无关。
布鲁克斯法则暗示最理想的开发组规模是一个人——无须停下工作与同事沟通的单个开发者。
一切均顺序进行,确保项目维持布鲁克斯所谓“概念上完整”的状态· 项目中所有环节目标一致,且按计划完美结合。
但是对于庞大且涉及面极广的一个程序来说几乎不可能。从理论上团队开发就是不得不被认可的,何况实践上它几乎必不可少。
开放源代码软件开发(open source software development),它能彻底改变软件开发的具体过程——将其从少数隐士手里拿出来,散播到广大人群中。在它之前,软件开发都采用大教堂模式。即“最重要的软件……需要像建教堂一般,由独立的巫师或一队相互隔离的魔法师精心打造,在面世之前绝不发布beta 版本。”
开发源码开发方式(又叫开源集市)在一方面,低成本、广泛地接入像互联网那样的网络, 让开发者之间能建立迅速、可信的沟通渠道,存储可被开放访问的共享知识和代码池;另一方面,围绕一种领导方式——如托瓦茨那样的方式——形成合作团队的良好风气,欢迎新人进入、鼓励成员做出贡献,同时尽可能增加合格成员。
开源运动的新集市模式在很多方面改变了计算世界,但说到能比大教堂模式更快地让新产品面世,却并无显著建树。
"愉悦是金,“艾瑞克· 瑞蒙德写道。“开源的成功告诉我们,对于创造性工作,玩耍是最经济有效的模式。”
第2章 Agenda之魂
Chandler 项目并没有真的“正在“改变世界(至少尚未开始)。但Chandler 项目正是为改变世界之梦所驱动。
卡普尔自己以及他的莲花公司还有更多开发者对项目的执着与对灾难的坚持。正是某种意义上的开发者的精神。
卡普尔(Mitchell Kapor)在接受戴维·甘斯的采访时说过的一段话:
“在变成数字资本家之前,我曾教人超觉静坐。,还在一家社区医院的精神科做过心理咨询师,这些经历对我影响极深。我拥有心理咨询的硕士学位。所以,我另有志趣。我只是误入计算机领域,无意成为比尔·盖茨——只有比尔·盖茨才能做比尔·盖茨。我向来不求做大公司、赚大钱。我只是办了家叫做莲花的小公司, 做了个几百万人争相购买的软件产品,结果这家小公司陡然暴长,员工数千,每年收入数亿美元。很不爽。至少对我个人来说,很不爽。所以我离开了。在某一天,我离开了。”
莲花公司有个叫做Agenda 的项目,为了解决卡普尔的小纸片问题而设立。即采用计算机人工智能来管理记录信息的小纸片——名片、随手贴、笔记页等。莲花公司于1988 年发布了Agenda 软件。
Agenda的“自动分派”特性一一在意义模糊的短语里面,如“ 下周五与约翰共进午餐”‘找出“下周五”这个曰子——如同魔法一般,没有其他软件能与之媲美。它还引入了一种管理数据的新手段——介于传统计算机数据库的严格结构和字处理软件的自由格式之间。
Agenda的创建者们认定这样一些超乎常规的原则:
用户不用关心软件的存储结构,只管输入数据就好,用户应该能够容易地扩展和修改数据结构、添加新分类, 且不会导致数据丢失,用户应该能够用自己创建的新方式查看数据——也可以在自己创建的视图中操作和修改数据。
在当时,程序或网站总是要你按它设定的方式而不是你自己的方式填空——社会保险号码里面不得包括连字符!信用卡号中不得包括空格!——而Agenda 早有独门秘技让用户随意输入。
卡普尔离开莲花公司后,投身于开创开放网络的工作。但他放不下Agenda。他珍视的并非Agenda 的“特性列表”——软件的种种特殊功能一一而是动态适应性的程序精髓,即“先扔进去,延后处理”。于是,Chandler项目诞生了。
关于Chandler,米奇.卡普尔只知道三个要素:它应当开源,它应当挠到Exchange 的痒处,它应当承继Agenda 之精髓。
鼠标之父道格拉斯·恩格巴特( Douglas Engelhart ) 的”OnLine System (在线系统, NLS)” 就是—种PIM(personal information manager) 。NLS 的目标是让用户能够“保存并研究想法,使之相互关联,并能交叉引用”。
现在的计算机用户大概会把这叫做outliner (大纲工具)——以可折叠和展开的节点对信息行进行层级结构化组织的程序。但NLS 可以在网络上共享,而不仅限于单机使用。
在1962 年关于增进人类智慧研究计划的论文中,恩格巴特阐述了程序员最有可能成为初期目标用户的原因。“成果也可用千智慧增进研究项目自身,改进研究和开发智慧增进系统编程活动的效能。设计、实现和修改程序的能力,在衡量研究进展时颇为重要。”
若NLS 能帮助程序员更好地编程,则程序员就能更快地改进NLS。这就出现了正向循环。这就是“提靴带(bootstrapping)” 。
在恩格巴特看来,提靴带(bootstrapping)的意思是“让改进的过程得到改进”。提靴带(bootstrapping)并不改进过程——如让人更快地解决问题。它改进的是改进过程的速率一一如怎样才能快速教会他人更快地解决问题。
初次启动计算机时,内存是空的。这就造成了鸡与蛋的悖论:计算机硬件需要操作系统软件来装载程序——包括操作系统本身。计算机系统发明者们通过一个叫做”bootstrap loader (靴带装载者,引导程序)”的小程序让机器具备刚好足够把大操作系统装入内存的能力,开始正常运行。
米奇· 卡普尔总把恩格巴特作为自己的灵感之源,而Agenda 在某种意义上则是NLS的传承者。
之后,本章介绍了很多个失败的项目,这些项目失败的原因都是因为项目需求不断地变化。用一句话来概括就是:标靶移来移去。目的忽上忽下。计划不切实际。期限一拖再拖。预算膨胀超支。绝望已极。混乱不堪。
第3章 原型与Python
卡普尔的团队开始问自己一个看似简单的问题:我们如何组织信息?如何对这种信息组织法建模——需要怎样的数据结构才能让计算机也能回答这个问题?
软件没有磁芯。它就像洋葱般层层叠叠,每一层都辛辛苦苦地建立于前一层基础之上。程序员把这种结构叫做“抽象层叠",每当新添一层时,就要把一些复杂而特殊的东西转换为简单而通用的东西。
在抽象层叠的最底端, 正好在核心内存之上的部分就是汇编语言。
语言的选择可能都是一个项目在前期选择时必须要经历的痛苦抉择。文中谈到了汇编、Fortran、C、Perl,谈到了编译型语言和解释型语言,最后项目用Python语言来实现。
Python 是一种“解释型语言(interpreted language)” 。“编译型语言(compiled language)” 通过编译器先将程序员的源代码翻译为机器可读的二进制代码后再运行,而解释型语言则是在运行时做类似的工作——解释器逐行翻译源代码,再喂给处理器运行。解释型语言效率较差,因为你要同时运行自己的程序和解释器。但这也使得解释型语言较为敏捷。
Python是解释型语言,但是简单易懂的语言,很明显在修改错误和拓展程序上事半功倍。这恰恰说明了,解释型语言这种往往被忽略的“脚本语言”是至关重要的。
很多语言都用括号或其他符号来划分代码块,而Python 却只简单地用缩进表示。它的另一个优点是变量类型设定宽松。
Python 的信条,范·罗萨姆说,是TOOWTDI: There’s only way to do it. (仅此一途。)
Python和Java语言一样提供了“垃圾回收(garbage collection)”机制。
当程序不再需要先前申请的内存空间, Python 就会负责清理。
面向对象技术不是围绕一系列命令行来组织程序,而是基于一些叫做对象的代码片段来组织程序。当接收到其他对象的呼叫时,对象就会做出操作。对象之间通过严格定义的输入输出彼此相关。软件对象通过互相之间发“消息(message)” 来触发”事件(event)”,达到交互的目的。共享特性对象可以组建为“类(class)”, 还可以从“父类(parent)” 继承特性。
语义网时基于一种名为RDF(Resource Description Framework , 资源描述框架)的技术。RDF 以“ 三元组(triples)” ——包括三个部分的语句——存储所有信息,描述事物之间的关系。
电梯游说:就是当你有幸在电梯间遇到某位权钱人士时,能脱口而出,在短时间内说服他。
第4章 乐高王国
这一章主要描述乐高积木式的软件制作方式,如果这一块块积木是程序代码,则很难做到尽善尽美,完全适用且精简的代码。最终这个方式是卡塞尔团队在这方面的一个尝试探索,值得我们钦佩和敬仰。
乐高假设指未来程序将由可复用的部件组合而成。部件将在全球范围内提供。虽然实际上这种假设不太容易实现,甚至不能实现。做好项目的关键在于复用,而不是重复发明。
把前人的成功经验集成进来,少写新代码。软件复用的两难选择:创建还是借用?
可复用软件之梦有一个悖论:几乎总能找到一段满足大部分需要的代码。但这些拿来的代码所不能做到的部分,恰恰是项目与众不同的创新之处—-也是创建这个项目的出发点。
模块化和组件化是软件人员的梦想,谁都想把几个模块插到一起就可以完美的运行并完成任务,但现实却相当残酷,可以运行的模块通常不能与自己想写的程序配合工作。程序员们很久前就解决了“小复用”问题,即通过构建子程序库来为自己减负。但一直悬而未决的间题则是“大复用”——创造并使用真正有用的软件大型可复用组件。
书中提到一个叫考克斯的人,他创办了一家叫做Stepstone的公司,致力于向C语言系统搭造者提供插入式芯片级软件组件,最后的结论是:即便采用最新的技术,要想设计和制造既有用又真能复用的组件、为组件写文档以便于客户理解、移植组件到潮水般不断涌现的新硬件平台上、确保最新的改进或发布版本不与现存接口冲突、将组件销售到类似威廉姆斯堡枪械行业那种鼓励从头做起的价值体系,都是极其困难的。
美国西海岸时间2003 年4月21 日下午3:07, 第一个公众版Chandler0.1上载到OSAF 服务器。24 小时内,就被下载15000 次。卡普尔在blog 上写道“我把Chandler0.1叫做‘B超’版本:胎儿只能在母腹中存活,但如果仔细查看,就能看到小小的手臂和腿脚在划动,你会相信最终它将诞生。”
团队讨论后认为Chandler数据模型的核心应该是“条目( item)”。
什么都可以是条目——对用户来说,可能是一封电子邮件、一条随笔记录或者一次约会事件,但它也要体现程序自身的一些机制,例如某”类”条目的定义(“电子邮件”或“随笔记录”或“约会事件”)。
条目采用面向对象方式加以组织,构成一种继承层级结构。如果一组中的每一条目都被定义为某一”类”——例如,都是电子邮件一一则它们将继承“电子邮件类”条目的所有特性。所有条目都应该保存在资料库中。
这种方案让Chandler 具有“以条目为中心”的特点,它还引申出几个要点。其中之一是程序彻底从RDF 的世界中转移出来,回到摩根·萨奇编写第一个资料库时Chandler 的出生地。
在RDF 中,数据存储的基本单位是“属性(attribute)” ; Chandler 条目可以包含许多不同属性(对于一封电子邮件,典型的属性可能是“日期”、“发件人”、“ 主题”、“正文”等等)。
现在,Chandler 团队终于回到有所进展的世界。
第5章 管束奇客和狗
从狗的需要管束引论到程序员需要管束。工程的质量、进度、成本也需要进行策划决策。
质量三角,既好、又快、还便宜,同时满足的事情不太可能发生。
软件经理非常重要,他制定进度、推动程序员按进度工作、决定先干什么后干什么,需要沟通能力、决策能力、市场感知能力、粘合团队能力、程序掌控能力等等。
用代码行数做判断标准只会鼓励程序员写臃肿、蹩脚的代码。
闲逛式管理MBWA(Management by wandering around):这种严密的方法要求经理们走出办公室,遍访坐在隔间里的下属,和他们谈话。“做得怎样了?”它鼓励人们观察和接触他人。
但在软件领域开发进度是闲逛的管理人员看不到的,因此不能移植到软件领域中。
多数开发者都乐意告诉经理自己的进度,问题是,就目前的软件实践而言,开发者们对于自己的进度也不比经理知道得多。
奇客的2种定义:
以(计算机)程序缺陷为食—-不善社交、身有恶臭、面色苍白的偏执狂,具有奶酪刨丝器一般的人格特点。
专注于己事的人;追求技术(特别是专业技术)和梦想、不融入主流社会的人。
群件(Groupware):即时通信、聊天室、缺陷跟踪、源借故传统的邮件列表等工具,个人感觉要慎用这些工具,否则你的工作时间会被这些工具吃得一干二净。
Wiki在chandler项目中也建立了起来,感觉这个chandler项目用到的工具太多,如果程序员不能合理地安排自己的时间,估计会被这些工具所淹没。
对于程序员来说,确实有一种制造工具的冲动。磨刀不误砍柴功本身没错,但程序员在磨刀的过程中会想弄到一块最好的石头,并花了大把的时间去把刀磨得吹毛断发,却忘了还要砍柴。
第6章 搞掂设计方案
卡普尔认为, 软件设计不仅只是在程序员代码之上覆盖一层诱人的图形。它是一种设想用户需求并在软件结构中满足这些需求的创造性基础工作。
良好设计的原则:
坚固–良好的结构、没有缺陷;适用–程序应符合其设定目标之所需;愉悦–使用程序的体验应令人愉快。设计方案与实际过程没有先后,而是相辅相成,同期发展。
在软件世界中,集成(integration ) 的意思就是把一段运行正常的代码连接到某个程序中另一段运行正常的代码上。
集成往往是软件项目遇到大麻烦的环节。分开来运行相当正常的代码, 在合起来时就闹罢工:不能正确挂接、发送不可解释的消息、或者顽固地拒绝启动或停止。
现今的多数项目都接纳了“持续集成”的观念:程序员不断向主干代码中签入最新的代码,每个人负责确保自己加进去的代码不会导致问题发生。持续集成应该更利于产品的定期发布。
戴维·艾伦是一位生产力教练,其著作《GettingThings Done》一书在程序员人群中近乎圣典。
GTD 的核心原则之一是建议有规律地安排定量时间处理收件箱:
查看胡乱塞进系统的每个比特填料并做出决定,“下一步怎么处理这东西?"艾伦建议,如果在两分钟之内就能处理好, 马上就开始做。否则, 决定是存档、丢弃、推迟, 或者分类到某个有下一步操作建议的具体项目中。
关于Linux的作者李纳斯托瓦茨的话:
别做大项目。从小项目开始,而且永远不要期望它变大。如果这么想(指做大型软件),就会做过度设计,把它想象行过于重要。更坏的情况是,你可能会被自己想象中的艰难工作所吓倒。所以要从小处起步,着力考虑细节。别去想大图景和好设计。如果项目没解决某些需求,多半就是被过度设计了。
别指望在短时间内达到大成就,我致力于Linux达13年之久,我想后面还得花上好些时间。如果一早就妄想做个大东西,可能现在还没动手呢。
第7章 细节视图
程序员和机器、程序员和程序员、程序员和用户之间往往达不到某种共识。
程序员们对于信息的需求显而易见。他们需要细节。他们需要蓝图。他们需要规格说明(specifications)。
规格说明是程序员的圣经,而且,通常程序员也会是忠诚信徒:规格说明就是法律。
需求搞错的严重后果,18英尺的巨石拱门变成了18英寸的石桩子。
最著名也最声名狼藉的匈牙利命名法:在匈牙利语标记法中,程序员给每个变量名加上前缀, 好让代码阅读者了解变量的类型。
匈牙利命名法可能在用C++写Windows程序的时代是需要,因为各种类型、结构、枚举、控件等等让人眼花缭乱,让人容易出错,而在Java和C#等这种强类型的语言中,这类命名法完全是对程序员审美观的践踏。
第8章 白板上的即时贴
获得更好进展的关键是将软件改进到程序员自己可以使用的程度。
白板上的即时贴:用贴纸,每张纸表示大致同等的工作量。每张即时贴代表各开发者一个月或两个月的工作时间。先在墙上循“点号版本”的顺序贴上,然后就能对每一轮计划的工作和自己是否脱离显示一目了然。用贴纸法来讨论项目各个小版本应该具有的功能特性,也是敏捷开发里重点推广的。
“吃你自己的狗食”的意思是开发者必须使用自己正在做的产品。
在传奇般的施乐帕罗· 阿尔托研究中心(20 世纪70 年代发明了现代个人计算技术),研究队伍领导人鲍勃· 泰勒提出了这种说法:
“吃狗食则是迫使开发者把鼻子伸到产品的问题中、加速发现和修正缺陷的低调且实用的方法。”
WebDAV 的工作机制是扩展HTTP——Web 服务器和浏览器之间赖以互相通讯的协议——增加了让用户在远端服务器上编辑文件的新命令。
Chandler一直具有两面性——一方面,它是用户管理信息的软件应用;另一方面,它是—种“应用框架”或“平台”一开发者可在上面添加新酷特性的一种基础。由于卡普尔和OSAF 团队逐渐勉强接受了不能两者得兼的事实,他们首先选择做应用程序。
第9章 方法
从Chandler 项目的最早期开始,卡普尔就坚持要做诚实、现实的计划和进度安排。但项目在满足进度方面却拥有不佳的记录:平均6个月能发布一个版本,但计划却总假设应在3 、4 个月内完成一个版本。部分原因或许是在软件开发和其他领域中计划总是超出了能预见的范围。
Chandler项目的软件开发者很少成组地共同开发一系列项目:他们不太像运动队或是军队单位,也不太像合唱团,而更像是专才们为制作一部电影而临时组合然后解散,再重新为下一部电影组合起来。每次到新团队中开始做新项目时,他们大概还是会按下”重置”按钮, 根据某些首要原则设计出一套新的工作流程。
结构化编程的主要规则:“程序的每一层都该自成一体。”
为了摆脱软件制作的焦油坑,无数软件实行者在不断探索。只有个体开发者为个人工作制定计划并遵循,项目才有控制和管理的基础。想法是好的,但往往很少有人将之付诸于行动。软件的速度和质量造成人月神话的恶性循环,但是质量是保证软件继续发展的前提。
汉弗里在IBM 执行强制进度纪律的成功基于两条原则:
计划是强制性的;
计划必须符合现实情况——“从底向上”,依据那些负责按计划执行的程序员的经验和知识而来,而不是“从顶至下”,靠管理者拍脑袋或对市场的期望而来。
在SEI,汉弗里和同事们创建了软件成熟度模型(Capability Maturity Model, CMM ), 作为一种衡量软件开发组织品质的准绳。
CMM 原则的简单的概述
位于第一级的组织基本上什么都没做。
第二级组织做一些计划、跟踪、配置管理工作,也讨论质量保证之类的话题。
第三级组织开始定义过程——如何工作、如何完成任务、可训练的事项等。
第四级,他们采用衡量准绳。他们有一套真正跟踪和管理自己所做工作的框架, 一种可统计跟踪的系统。
第五级组织拥有持续改进的过程。
CMM主要目的是帮助规模庞大的组织改进软件进度和质量。
模式运动让个体程序员有了一条解决问题的新路子,并且提炼经验、供同事所用。但它并不太有助于找到在更大项目中协调工作的方法。
瀑布模型
将项目切分为依序进行的多个独立阶段,比如需求定义、设计、实现、集成、测试和发布。每个阶段需在下一阶段开始前完成。
这套做法在纸上看似合乎逻辑,但实践起来却总是导致延误、混乱和灾难。每个阶段都耗时无算,但没一个工作正常的。“大设计优先”引发大延误,“大爆炸式集成“一一单独编写代码的各个主要部分,在项目将近结束时拼到一起——导致系统崩溃。
螺旋模型
将开发切割为六个月到两年的“迭代周期”——更快生产出可工作代码的小瀑布,从部分完成的产品使用中得到反馈、指导下一步迭代。
快速应用开发(Rapid Application Development)
RAD承诺通过快速原型设计和更紧迫的迭代周期,依靠新工具让计算机处理一些繁重的编程工作,加速完成软件的交付。RAD 帮助软件公司更敏捷地工作。
敏捷软件开发(Agile Software Development)
个体和交互胜于过程和工具
可工作的软件胜于面面俱到的文档
客户协作胜于合同谈判
响应需求胜于遵循计划
尽管右栏条目有其价值,但我们更看重左栏条目。
争球式开发(Scrum)
将项目分解为30 天一轮的“竞跑”‘强调每天开例会、维持项目在正轨上运转。
极限编程
采用了一系列广为接受的方法,并将这些方法的使用推至极限。
祖尔测试
索伯斯基提出了祖尔测试( Joel Test),基于他自己的经验和“集体智慧",给出一套快餐式原则, 判断开发组织是否符合这条原则—— “不会叫人头疼的CMM”。
祖尔测试询问以下十二个问题:
1)Do you use source control? 你们使用源代码控制吗?
2)Can you make a build in one step? 你们一步就能完成构建吗?
3)Do you make daily builds? 你们做每日构建吗?
4)Do you have a bug database? 你们有缺陷数据库吗?
5)Do you fix bugs before writing new code? 你们会在写新代码之前修复缺陷吗?
6)Do you have an up-to-date schedule? 你们有与当前工作吻合的进度安排吗?
7)Do you have a spec? 你们有规约吗?
8)Do programmers have quiet working conditions? 程序员工作环境安静吗?
9)Do you use the best tools money can buy? 你们采用了市面上最好工具吗?
10)Do you have testers? 你们有测试人员吗?
11)Do new candidates write code during their interview? 你们会要求应聘者在面试时写代码吗?
12)Do you do hallway usability testing? 你们做走廊可用性测试吗?
“得12分为最佳,“索伯斯基写道, “11分还可以接受,得10分或更低就说明你们问题大了。其实多数软件组织只能得2、3分,他们迫切需要帮助,因为微软等公司一直都得12 分。”
第10章 工程师和艺术家
软件设计有两个意思:“其一是我们要打造的产品。其二是让产品得以实现的软件工程。我相信有两种不同的角色一一主题专家和软件工程师。”
延后绑定是计算机科学中的—个术语,表示编程语言提供给程序员以更多灵活性的能力。
兴趣决定了编程是工程师的工作还是艺术家热爱的作品,为之创新和废寝忘食的魔力。培养兴趣对学习者很重要,而坚持兴趣对工程师很重要。
在计算领域中,变化不可避免,我们设计的系统应该让我们从变化中学习、并且反过来影响变化。
在PARC 时,我们的理念就是,既然你永远不会踏入同一条河流,用户界面的第一要素是一种学习环境——可以从不同途径探索,随用户使用该环境的时间进程不断改变。“换言之,用户从计算机处学到新东西后,就能自己修改系统,以期发挥所学。
高德纳写的书名叫《计算机程序设计艺术》,他在1984年获得图灵奖时发表感言说,“计算机编程是门艺术”。写《计算机程序设计艺术》这本书他花了十年,写TeX和metafont程序没想到也花了近10年。他宣称,写软件要比写书“难多了”。
第11章 通往狗食版之路
“吃你自己的狗食”的意思是开发者必须使用自己正在做的产品。
在传奇般的施乐帕罗· 阿尔托研究中心(20 世纪70 年代发明了现代个人计算技术),研究队伍领导人鲍勃· 泰勒提出了这种说法:
“吃狗食则是迫使开发者把鼻子伸到产品的问题中、加速发现和修正缺陷的低调且实用的方法。”
吃自己的狗粮,这种思路确实有助于提升软件质量和用户体验,想想连自己都不屑一用的软件凭什么去折磨用户呢?
软件中的递归很危险,因为它必须要有出口。否则,奇异循环就会变作无限循环,而计算机就会堆栈溢出。终结条件是递归定义中最重要的部分。