计算机历史——软件的发展

软件从未变得如此重要。当年赴摩尔学院听计算机讲座的先驱们万万没有想到,他们所学的知识竟然催生了一个新的行业,一个由计算机指令支撑起来的虚拟行业。软件分为多个层次,涉及到微代码、机器代码、汇编语言、高级语言的转换。数据库、软件开发过程,乃至整个企业结构都与之息息相关。计算机无所不在,它们的思想统领着整个世界。软件的重要性已变得无以复加,无怪乎世界上财力最雄厚的富豪当中,有好几个人是靠经营软件公司而积累了大笔的财富。
“优化软件就相当于优化一切。”

数据库

随着编程语言的功能日渐强大,计算机的速度日益加快,容量日益扩大,可靠性日益增强。很快,计算机科学家就意识到,除了计算方程式的结果,计算机还可以在更广阔的领域大有可为。它们可以快速存储和处理大量的数据。
如果只是单纯存储一系列数字,那倒不是什么难事,但是,如果存储的是病历记录或者财会记录,那么情况就会复杂许多。这就要求计算机必须能在短时间内迅速找到特定的信息条目——比如某一份病例中记述的病因,或者某一天产生的支付记录。怎样编排数据才能帮助我们轻松地找到所需信息呢?
这些都不是什么新的问题——自从第一部词典问世以来,人们就面临着快速查找词条的问题。其解决办法,就是按照字母表的顺序编排词语。以某个单词为参照,词典中的其他词语中要么在它之前,要么在它之后。因此,我们在查找单词时,可以翻开词典的任何一页,然后根据上面的词语决定应该往前翻还是往后翻,直到将我们想查的单词查找出来。

第一代

第一代数据库都是按照非常类似的原则编排的,它们于20世纪60年代问世,被称为导航式数据库管理系统(navigational database management system)。数据库第一次打开时,就会自动出现一个指针,指向第一条存储记录(好比翻开词典正文的第一页,就会看到第一个词条是以a开头的单词)。这些存储记录按照链表或网状结构编排,每一条记录当中都存有一个指针,指向相邻的记录。为了检索信息,计算机需要访问每一条记录,并通过其中的链接跳转到下一个记录,以此类推,直到找到用户所需的信息。如果用户想从一个庞大的数据库中检索出所有心脏病患者的病例,那么计算机就需要把每一条记录都访问一遍,才能将心脏病患者的病例筛选出来。这显然是一个非常缓慢而低效的信息检索方式,而且在那个年代,计算机和存储设备的运转速度都慢得可怜,要执行这样的检索是难以想象的。或许这种事情在今天的人看来有些匪夷所思,不过第一代数据库的确是不能用来查找信息。
随着计算机和存储器的性能日渐提升,导航式数据库的局限性也愈发凸显。20世纪70年代,IBM的一名英国研究人员埃德加·弗兰克·科德(Edgar Frank “Ted” Codd)认为,数据库的模型亟待改进。科德与开发硬盘存储系统的IBM员工一道,设计了一个新的数据库模型,科德称之为关系模型。这种数据库结构比较智能化。数据的编排方式并不是像词典那样列出一长串条目,而是采用一系列数据库表,不同的数据库表通过关系键联系起来。
为了便于大家理解关系数据库,我们用词典来打个比方。关系数据库就好比一系列分类词典,比如动词词典、名词词典、副词词典等等。如果你想查找某个单词——比如动词“bow”,那就只需要翻阅动词词典。如果你想找“bow”的名词词义,那就只需要翻阅名词词典。这比从头到尾地翻阅一本超厚的大词典要高效多了。
关系数据库也是同样的道理,它采用关系键,将不同的记录联系起来。比方说,一个员工信息数据库可能会以员工编号作为关系键。知道了工号,你就可以在各个数据库表(好比各个分类词典)中分别查询员工的工资信息、家庭住址、计算机登录情况等等。每个数据库表中的值都可以作为关系键,用于在其他数据库表中查找相应的信息。也就是说,员工的职位描述也可作为关系键,用来查询员工是否具备参与机密工作的资格。

SEQUEL的出现

20世纪70年代末出现了一种特殊的编程语言,用户可以通过它查询数据库中的复杂信息。这种语言脱胎于关系代数和微积分,全称为结构化英语查询语言(SEQUEL,即Structured English Query Language),后来又很快简称为结构化查询语言(SQL)。SQL支持查询、表达式、从句等多种编程元素。有了它,用户就可以在数据库中查询高度复杂的信息。
数据库管理系统负责接收和翻译SQL表达式,并尽快返回结果(如果情况理想的话)。SQL中包含好几种语言,其中数据操纵语言(data manipulation language,简称DML)和数据定义语言(data definition language,简称DDL)能让用户运用简单易用的表达式在数据库中修改或添加数据。
此后,数据库在原有的基础上继续改进,开始向面向对象的趋势发展,并进一步得到优化。索引的概念得到引进,经常查询的信息存储在高速的临时数据库中,临时数据库则与主数据库相连。正如图书目录一样,索引可以使用户查找所需信息的速度大幅加快。如今,数据库的设计特点表现为高度模块化,可访问性强。可扩展标记语言(Extensible Markup Language,简称XML)、超级文本预处理语言(Hypertext Preprocessor,简称PHP)等基于网页的语言可以使用SQL,连接在线数据库。(有了网页服务器,当你浏览的网页中包含这些高级语言写成的命令时,网页浏览器就会对它们进行翻译。)可以想见,未来数据库的分布将日趋广泛,可访问性日益增强,访问速度日益加快。

我们已经对数据库领域的巨大飞跃感同身受。就在几年前,家家户户的抽屉里还塞满了老照片,书架上堆满了书本、文件、录像带和CD,但是如今,我们查找、创建、购买的所有信息都是以数字形式保存下来的。大多数照片都已实现数字化,电子书正日渐占据图书市场的主流。大多数公司都喜欢给客户邮寄电子账单,而非纸质账单。视频和音乐已大多实现数字化。多年来,我们的财富不过是存储在银行计算机中的数字。政府以数字化的形式发布信息;医院在计算机上保存病例。越来越多的商店开始实行网上交易。我们只需要轻轻点击几次鼠标,就可以购买食品、汽车乃至任何种类的商品。
所有这些海量的数据都存储在数据库中。它们的界面可以是一个赏心悦目的网页,供人随意浏览各种美观的照片;可以是一家网上商店,供人随心挑选品类丰富的商品;可以是一款功能强大的音乐播放程序,能让人徜徉于音乐的海洋;甚至可以是一款会计应用程序,能让人随时监测开支情况。但是,在多姿多彩的界面背后,让这一切成为可能的,便是精巧的数据库技术。

软件危机

如今,软件业可谓风生水起,蔚为大观,仿佛这个行业的发展向来一帆风顺,毫无波澜。但是,正如电子业历经了“数字暴政”的阵痛,才有了集成电路的诞生,新生的软件业也经历了危机的考验,这场危机还推动了一门全新学科的诞生。

编写大型程序的巨大困难

程序员遇到的问题从一开始就很明晰。虽然有了新的高级编程语言的帮助,开发人员在编写代码的过程中可谓得心应手,但是,前所未有的重大问题依然在不断涌现。20世纪60年代,随着集成电路的发明和摩尔定律的问世,计算机的性能每年都在突飞猛进。与此同时,软件应用也在以类似的速度不断飞跃。然而,就在这个过程中,程序员日益强烈地意识到,他们的程序正变得越来越难以掌控。程序当中的错误太多,软件并没有发挥应有的效果,而且开发系统的过程似乎正变得意料之外地漫长。

这些问题在1968年达到了顶点。在有史以来的第一次软件工程大会上,世界各地的计算机科学家齐聚一堂,共同讨论他们关切的问题。他们忧心忡忡,这一点从会上的讨论中就可以看出来:

麻省理工学院的罗伯特·格雷厄姆(Robert Graham)表示:“我们投入了长年累月的研究,耗费了巨大的投资,到头来却发现,我们从一开始就没有把系统研究透彻,软件根本没有取得预期的效果。我们就像莱特兄弟制造飞机一样,辛辛苦苦地把飞机造好,将它推下悬崖,任凭它轻而易举地坠毁,然后再从头开始。”
密歇根大学计算中心(University of Michigan Computing Center)的伯纳德·加勒(Bernard Galler)表示:“我想举几个在IBM碰到的不好的例子。有一次,用户提出,希望能够增强PL/1语言可扩展性。对此,IBM经过一周的内部讨论,最终下结论称,这种事情不可能做到。因为语言设计师不打算告诉用户怎样实现所需的扩展。还有一个例子:OS/360操作系统的作业控制语言(job control language,简称JCL)开发出来以后,用户在设计阶段根本无法事先看到任何选项。为什么会出现这种情况呢?”
丹麦第一家计算机公司A/S Regnecentralen的员工彼得·诺尔(Peter Naur)表示:“……软件设计师的角色类似于建筑师和土木工程师,尤其是规划城市、工厂等复杂建筑的设计师。因此我们应该学会从这些领域吸取灵感,攻克我们遇到的设计问题。”

此次大会落幕后,另一场大会很快召开,其宗旨是讨论技术和管理思想。从这一刻开始,软件工程学作为一门新的学科登上了历史的舞台。伊恩·萨默维尔是现代软件工程师、英国圣安德鲁斯大学(St. Andrews University)教授,他撰写了很多业内的权威教科书。他表示,新学科的命名颇有内涵,意在表明,人们从此将采取系统的、有组织的方式来编写软件。不过,大会的主办方给出了不同的说法,“他们声称之所以发明这个术语,只是出于调侃的心态,没想到这种叫法就传播开了”。当然,这样命名是为了“故意制造煽动的效果”,以激发研究人员行动起来。
还别说,这样做真的起到了效果。没过多久,许多关键性的技术革新开始涌现,它们专门针对的是软件工程学领域,旨在辅助程序开发人员提高编程能力,写出高效的软件。在这一理念的指导下,新的编程语言得到开发。戴维·帕纳斯(David Parnas)等研究人员提出了信息隐藏的概念,这一概念在模块化编程和面向对象的编程领域举足轻重,它可以确保数据及相关函数封装在对象内,与其他的数据和函数分隔开来。这就好比采用标准化模块制造汽车——车载收音机等部件的更换不会影响到其他部件。同理,如果你设计好程序之后,突然想对某个地方进行改写(比方说将某个函数或数据结构更换),那么程序中的其他函数和数据完全不会受到影响。
集成开发环境(Integrated development environment,简称IDE)的发明,就是为了让编程变得更加轻松。它们的作用就好比文字处理器——程序开发人员可以在不同的窗口编写代码,并对其进行编译和调试。正如文字处理器可以检查拼写和语法错误,集成开发环境也可以帮助编程人员找出程序中的错误,并提供大量实用的工具进行除错。现代的集成开发环境通常包括一系列工具,比如:手持设备模拟器;用于设计图形用户界面(Graphical User Interface,简称GUI)的工具;全方位的帮助系统,用于辅助编程人员从已有的库——即程序编程接口(application programming interface,简称API)中寻找合适的函数。

如何面向用户

除了发明实用的编程工具,研究人员很快意识到,还有更好的软件设计方法亟待开发。这就好比汽车制造商不能把仅仅把目光放在硬件上,还应着眼于汽车的用途、目标客户的定位、成本开销的大小,从而将生产问题化整为零,分解成一个个具体的问题,比如:应该采用什么样的发动机、传动部件、转向系统、制动系统、车轮系统和座椅系统?车内需要容纳多少人?生产一台汽车需要多少时间?编写软件也是同样的道理。一个大型软件项目可能会比制造汽车复杂得多,怎样设计才能确保项目的高效运转?
研究人员很快意识到,要做到这一点,必须确立一个明确的软件生命周期。首先,你必须合理定位产品和项目需求。接下来要做的,就是设计、运行和测试软件,并将其运行情况清晰地记录下来。最后要做的,就是发布软件,或许在这个阶段,你还需要指导用户如何高效地使用软件、如何进行必要的维护工作。

这些事情说起来容易,做起来难。产品或项目的需求并不好确定,因为顾客往往并不知道自己真正的需求到底是什么,因此可能会举棋不定、自相矛盾,甚至改变主意。他们往往不具备编程人员的思维方式,因此不知道如何从软件开发的角度表达自己的需求。换句话说,对于哪些事情在技术上可行,而哪些不可行,他们基本上没什么概念。有的时候,编程人员连目标用户是哪些人都无法确定,因此,真正应该提要求的人反而没有这个机会。

如何规划大型项目

除此之外,不同的设计阶段应该如何开展,这也是摆在编程人员面前的一大难题。项目的开发架构是应该采用“瀑布模型”(waterfall model)——像流水下坡一样顺次开展每个阶段,还是应该采用“螺旋模型”(spiral model)——反复开展每个阶段,开发一系列原型软件,以最大限度地降低风险?软件的开发是应该遵循迭代式和增量式的过程,还是应该采用“灵活性强”的方式,以迅速适应可能发生的变化?就算你知道了开发软件的最佳顺序,怎样才能把每一个阶段的工作都做到最好?应该采用哪些设计方法和工具?怎样测试软件,才能确保万无一失?怎样维护软件,才能使之适应未来的变化?

正因为软件工程学专家孜孜不倦地攻克上述难题,软件项目的发展才得以适应硬件的发展需求和用户复杂的使用需求。软件工程学着眼于软件开发的方方面面,比如对软件体系结构进行建模,采用可视化程序设计,使用形式化方法测试软件、提高其性能的可靠性。
伊恩·萨默维尔认为,软件工程学领域已经取得了许多重大的进步,这些进步给软件开发带来了实实在在的影响。“开发不同类型的软件,需要采用不同类型的软件技术和方法,”他表示,“配置管理(Configuration Management,简称CM)就是一个非常重要的项目管理方法,它支持并行开发。信息隐藏的概念是由帕纳斯在1972年提出的,它在抽象数据类型(Abstruct Data Type,简称ADT)领域得到了进一步发展,并影响了大多数现代编程语言。在关键任务系统领域,我们不仅可以采用安全分析和可靠性分析的方法,还可以运用容错技术,为航空器、化工厂等重要设施建立安全可靠的系统。统一建模语言(Unified Modelling Language,简称UML)将多种建模概念融合在一起,如今已成为软件系统建模的标准方式。编程环境的思想于20世纪70年代问世,在20世纪80年代得到进一步发展,如今已在软件工程学界得到广泛采纳。”
安东尼·芬克尔斯坦是软件工程学教授,在伦敦大学学院担任工程学系系主任。他认为,正因为有了软件工程学的帮助,程序员才得以高效利用时间。“如果没有软件工程学,我认为硬件与软件之间的性能差距会进一步扩大。制约软件开发的主要因素就是缺少训练有素的人才,现在也是如此。如果当初没有足够的人才投身于软件工程行业,我们就无法取得今天的成就了。”

软件膨胀

不过,尽管为数众多的软件工程师竭尽全力地投身于技术攻坚,但是依然无法解决所有的问题。我们每次使用计算机时,都会对软件工程领域的一大问题感同身受:由于某种原因,软件每次升完级以后,其运转速度似乎都会变慢。计算机科学家(及众多编程语言的发明者)尼古拉斯·维尔特(Niklaus Wirth)观察到了这一现象,人们将其称为维尔特定律(Wirth’s Law)。维尔特定律的内容是:软件变慢的速度永远快过硬件变快的速度。其他科学家也发表过类似的观点。曾在英特尔担任研究人员的兰德尔·肯尼迪(Randall Kennedy)就是其中一人。他曾写道:“虽然与几年前的Office 2000相比,Vista系统上的微软的Office 2007 虽然处理能力提高了将近两倍,但是占用空间却多出了11倍以上。”造成这一现象的罪魁祸首是软件膨胀(software bloat)——新版本的软件往往只是在原版本的基础上叠加了新的代码,而并没有经过重新编写。 维尔特定律表明,纵使计算机的运行速度快得惊人,新一代的软件的运 行速度也比不上十年前的老版本。
目前,计算机科学家正在费尽心思解决这个问题。不过萨默维尔深知,这并不是软件工程学领域的唯一挑战。“软件项目面临的主要挑战在于,开发环境正变得越来越复杂。这是因为,我们在建立新系统的过程中,将不同的供应商提供的各种系统和服务整合了起来。原本,在软件工程学领域,很多理论之所以能够成立,往往是基于这样的前提,那就是,系统完全处在软件开发人员的掌控之下,软件开发人员可以做出明智的决定来开发和改变系统。当这样的前提不再成立时,软件测试等方法必须做出相应的调整,以适应新的情况。”
这一观点引起了一些计算机科学家的高度重视。伦敦大学学院教授马克·哈曼围绕搜索问题对软件工程学进行了研究。他按照遗传算法——也就是由“优胜劣汰”的生物进化规律演化而来的随机化搜索方法,利用计算机来寻找特定软件的最优测试方法。
“软件测试是衡量软件质量、寻找优化方法的关键手段之一。测试的内容之一,就是寻找特定的输入,使程序执行特定的代码片段,”哈曼表示,“人工完成这样的工作需要花费很大的心血。这就好比你得从厚厚的地址簿里大海捞针,将一个人的电话和住址找出来。但是,如果计算机能够对测试用例进行评定,我们可以轻而易举地将这个过程自动化。”

其他危机

不过,仅仅有个聪明的测试方法是不够的。我们所说的危机与20世纪60年代末的软件危机已经无法同日而语,但是从某种程度上讲,软件业依然面临着定位问题。大型软件开发项目依然经常失败,尽管软件工程师尽了最大的努力。有时候,问题只是出现在成本和时间上——我们并不擅长估算软件开发产生的耗费。“我们的软件估算水平很差,”芬克尔斯坦表示,“如果你让我‘开发一个售卖二手教科书的网页前端,’我可能一时半会儿没法告诉你需要多少时间。运气好的话,我可能之前就做过一次这样的项目,但是我在这方面的经验也就仅限于此了。’”
不过,重大的失败也有可能是由更微妙的原因造成的(而且这样的事情不在少数,造成的损失也极为惨重)。芬克尔斯坦认为,问题的症结并不在于分析师和开发者经验不足。“个人认为,这些系统之所以失败,都是一些人们很熟悉的问题造成的:比如在项目设计和开展阶段犯了低级错误,”他表示,“你必须问自己,既然人们对这些问题都很熟悉,为什么还要一次又一次地犯同样的错误?他们是傻子吗?他们没看过萨默维尔的书吗?这些问题前十页就讲了,哪怕稍微翻翻也好啊,又不一定要全读完!我觉得,问题的症结是,企业结构、管理决策结构与开发软件的技术过程存在不协调。因此,这些系统之所以会失败,问题出在管理上,而不是工程上。”
软件工程领域的挑战还表现在,怎样满足客户的信息安全需求,怎样设计软件才能使之适应互联网时代的潮流。此外,一些所谓的“非功能性需求”也越来越值得重视,比如电源或电池寿命。在这个问题上,哈曼的想法比较现实:“如果我在乘坐越洋航班时,笔记本的电量在半路上就耗光了,那么就算里面的软件再好,对我来说一点用也没有。我宁愿软件耗电量低点,让续航时间久点,就算软件里头到处都是漏洞也没有关系。”芬克尔斯坦也这么认为:“在软件工程领域,我们一直致力于开发新特性,从来没有想过省电的问题——一般都不会有人往这方面想,除非你要设计航天器。但是现在,这个问题已经变得很关键。有很多之前没有考虑过的新特性一下子变得非常重要。”

还记得以前我们讲到的编写并行软件吗?那是帕特森给整个行业的科学家提出的挑战。芬克尔斯坦确信,它会给软件工程领域带来重大的变革。“软件工程领域面临的另一大挑战就是多核技术。如果软件无法充分发挥多核技术的优势,那么一台计算机就算内核再多也于事无补。要是采用一个内核就足以运行所有软件,那么剩下15个内核留着干嘛呢?总不可能都用来运行杀毒软件吧。我们所需要的,不仅仅是编程技术的一个突破,而是整个软件工程领域的革新。这肯定会改变我们当前的游戏规则。”

谁都是要吃饭的嘛。