购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.5 错误、故障和风险

从消费软件到控制通信网络的系统,大多数计算机应用都是如此的复杂,以至于几乎不可能生产出没有错误的程序。某些错误并不严重,而有些事件可能会造成较大的经济损失,甚至会造成悲剧。由于计算机系统的复杂性,有时候,即使所有人都遵守了职业规范,并没有人犯任何错误,但还是会有意外发生。不过,研究这些失败、造成失败的原因以及由此带来的风险,有助于防止未来的失败情形。

3.5.1 个人遇到的问题

人们遇到的因为计算机系统的故障而造成负面影响的事件并不少见,例如收费账单错误、系统(数据库)中数据不准确或者被曲解等。

我们来看一个例子。在美国纽约州,麦格劳-希尔为学校开发了标准化测试软件CTB并用其打分,每年会有数百万名学生参加它的测试。但是,CTB软件中出现了一个问题,导致它在好几个地区都错误地报告了大大低于正确分数的测试结果,一些老师因此遭受了职业生涯危机。由于分数错误,近9000名学生不得不参加暑期学校以补习功课。当然,最终CTB纠正了错误:测试成绩实际上提高了5个百分点。

为什么这个问题没有被及早发现,从而避免严重的后果呢?几个州的学校测试官员都对分数结果持怀疑态度,因为这次分数出现了突然的、意外的下降。他们向CTB提出质疑,但CTB告诉他们说一切正常。即使在CTB发现软件错误后,公司也没有及时告知学校,而是拖了好几个星期。

当然,软件错误是很难完全避免的。人们通常会注意到显著的错误,就像这个事件中一样。但该公司没有对有关结果的准确性问题采取足够的重视,也不愿承认出错的可能性。如果发现错误并能迅速纠正,那么该错误造成的损害是可以控制在小范围的。

CTB其实也建议学校等部门不要使用其标准化测试的分数作为决定重要事项的唯一因素。但很多学校这样做了。单纯依靠一个因素或一个数据库中的数据是如此容易,特别是考虑到额外的审查或验证带来的开销时,这对人们是一种简单的诱惑。在许多情况下,负责关键决策的人都无法抵制住这种诱惑。

在2001年恐怖袭击后,美国联邦调查局向很多机构提供了一个“观察名单”,收到该名单的机构包括警察部门和一些企业,例如汽车租赁公司、银行、赌场以及货运和化工企业。收到名单的单位又把信息通过邮件发给了其他人,最终有成千上万的警察局和公司都收到了这个名单。许多人把该名单添加到了他们的数据库和系统中,用来筛选客户或求职者。虽然该名单包括的人不全是犯罪嫌疑人,还包括警察需要质问的一些人,但是一些公司把列表中的人都标记为“恐怖分子嫌疑人”。其中许多表项不包含出生日期、地址或其他识别信息,使得很容易出现错误识别。有些公司通过传真收到这个名单,依照模糊的副本把错误的名字输入到他们的数据库中。在联邦调查局停止更新列表之后,并没有告诉所有收到列表的人,因此许多条目的信息都过时了。即使有人在原始数据库中更正了错误,但对受影响的人来说,麻烦并不会就此结束。在其他系统中,还会包含不正确或错误标记的数据副本。

因为数据库中的错误以及对内容的误解,导致人们遭遇问题的频率和严重程度取决于几个因素:

(1)人口众多(很多人都有相同或相似的名字,而且与之交往的大部分人都是陌生人)。

(2)自动处理系统不具备人类的常识,或者没有识别特殊情形的能力。

(3)对在计算机上存储的数据准确性的过度自信。

(4)在数据录入时出现的错误(有时候因为粗心)。

(5)未能及时更新信息和纠正错误。

(6)缺乏对错误的问责。

第一个因素是不可能改变的,它是我们生活的环境。我们可以通过规范系统和培训用户来减少第二个负面影响,其他因素其实都在个人、专业人士和政策制定者的控制范围之内。

3.5.2 系统故障

现代通信、电力、医疗、金融、零售、交通系统都严重依赖于计算机系统,这些系统如果不能按照计划运行,就会导致失败。我们要看到故障的严重影响,以及要努力避免的事情。充分的规划和测试,在出现错误的时候采取备份,以及在应对错误时以诚相待,这些教训同样适用于各种项目。以下是一些故障示例。

(1)一个软件错误曾经迫使成千上万的星巴克门店关闭,原因是一次日常软件更新导致门店无法处理订单、接受付款或继续开展正常业务。

(2)瑞士银行合作社的一个软件错误导致其客户不仅收到了他们自己的年终报表,还收到了其他几家银行客户的报表。这个事件侵犯了数千名客户的财务隐私,并使账户安全性受到威胁。

(3)在一个有两百万行代码的电信交换程序中,因为修改了三行代码,而造成几个主要城市的电话网络故障。虽然该方案此前经过了13周的测试,但是在修改之后没有重新测试,其中包含了一个简单的拼写错误。

(4)一个软件升级的错误关闭了东京证券交易所的所有交易。在纳税年度的最后一天,伦敦证券交易所的计算机故障导致其业务停顿了几乎8个小时,影响了很多人的税单。

在某些系统中,由于出现极端的缺陷,以至于该系统在浪费了数百万美元,甚至是数十亿美元之后,最终被废弃。例如;

(1)英国的一个大型食品零售商花费超过5亿美元开发了一个自动化供应管理系统,却导致货物被丢在仓库和转运站。他们又额外雇佣3000个工人来把这些物品搬回到货架上。

(2)一个酒店和汽车租赁业务的财团斥资1.25亿美元开发了一个综合旅游产业的预订系统,然后因为它无法工作又取消了该项目。

(3)经过9年的开发,英国国家健康服务中心放弃了一项费用超过100亿英镑的患者记录系统。这个项目的失败原因包括:项目规模太大、需要说明的变化、卫生部管理不善、技术问题以及与供应商的纠纷。

(4)在原定开发周期为4年的一个项目干了7年后,宾夕法尼亚州放弃了这个管理失业补偿金的系统。在项目取消的时候,该系统比其原先的1.07亿美元预算已经多花了6000万美元,并且依然无法正常运行。

软件专家罗伯特·夏雷特估计,在所有信息化项目中,大约有5%到15%会在交付之前或之后不久被当作“无可救药的缺陷系统”而被抛弃。他列举的一些原因包括:

(1)缺乏清晰的、深思熟虑的目标和需求说明。

(2)客户、设计师、程序员之间的管理不善和缺乏沟通。

(3)由于机构或政治压力,鼓励了不切实际的低价投标、不切实际的低预算要求,以及对时间需求的严重低估。

(4)使用了非常新的技术,其中可能包含未知的可靠性和问题,而且它的软件开发者也没有足够的经验和专业知识。

(5)拒绝承认和接受一个项目已经出现了问题。

多达六分之一的大型软件项目的进展是如此糟糕,以至于它们会对公司的生存带来威胁。这样大规模的损失涉及很多人,包括计算机专业人员、信息技术管理人员、企业管理人员和为大型项目设置预算和进度的政府官员。

3.5.3 遗留系统重用

在全美航空公司和美国西部航空公司合并之后,他们把彼此的预订系统合并到了一起,结果却造成自助值机服务机器无法工作,人们都到登记手续办理柜台区排队,导致数千名乘客和航班的延误。把不同的计算机系统进行合并是非常棘手的,而且问题也很普遍。但是,这起事件说明了另一个因素。根据全美航空公司副总裁的说法,大多数航空公司的系统开发时间都是在20世纪60年代和70年代。它们是专为那个时代的大型计算机设计的。航空公司高管说,这些旧系统“是非常可靠的,但是非常不灵活”。这些都是“遗留系统”的例子,即依然在使用中的过时系统(硬件、软件或外围设备都已经过时了),它们通常会配备特殊的接口、转换软件或其他适应性改变,使它们可以与更现代的系统进行交互。遗留系统的问题多如牛毛,如旧的硬件会发生故障,而需要更换的部件则很难找到。

与现代系统的连接是另一个频繁的故障点。旧软件通常运行在新的硬件之上,但它如果是使用程序员不再学习的老的编程语言编写的,那么维护或者修改这些软件就会非常困难。旧程序往往文档很少或根本没有说明文档,编写软件或操作该系统的程序员可能都已经离开公司了。即使有好的设计文档和手册,它们也可能不再存在或无法找到了。编程风格和标准在这些年也发生了大的变化。例如20世纪80年代的机场用来和飞行员通信的系统,在设计时没有考虑现在的网络威胁,因此包含安全漏洞。

计算机在初期的主要用户包括银行、航空公司、政府机构和像电力公司这样提供基础设施服务的公司。这些系统是逐步成长的,因此完全重新设计和开发一个新的现代系统当然是非常昂贵的。转换到新的系统可能需要一些停机时间,这也可能是破坏性的,并且需要对员工进行大规模重新培训,因此,遗留系统的问题仍然存在。

人们将继续发明新的编程语言、范型和协议,还会把它们添加到以前开发的系统中,在遗留系统给计算机专业人员提供的经验教训中,有一点是:需要意识到有30或40年后还有人可能会使用你的软件,因此,为你的工作准备文档是非常重要的。它对于设计的灵活性、可扩展性和升级都非常重要。当鼓励软件开发团队为代码写文档,并使用良好的编程风格时,一些管理人员会提醒开发人员“想想那些不得不维护你的代码的可怜的程序员。想办法让他们的生活愉快点吧,他们会感激你的善良”。

3.5.4 案例:停滞的丹佛机场建设

耗费32亿美元巨资修建的丹佛国际机场在原定启用时间延迟10个月之后,仍然没有启用。这个机场占地53平方英里[1平方英里(mile 2 )=2.589平方公里(km 2 )],大约是曼哈顿面积的两倍左右,它的启用时间至少推迟了四次。花在债券利息和运营成本上的延迟支出每月超过3000万美元。造成严重延迟的主要原因是耗资1.93亿美元开发的计算机控制的行李处理系统(见图3-5)。

图3-5 机场行李处理系统

该行李系统的规划相当雄心勃勃。通过自动化的行李车系统,行李车可以在长达22英里的地下轨道上,以高达19英里/小时的时速穿梭,从而在登记柜台或路边柜台托运的出发行李可以在10分钟以内到达该机场的任何角落。同样,到达的行李也可以自动传送到登机口或直接转送到机场任何地方的转机航班。该系统中的激光扫描仪会追踪4000辆小车,并把它们的位置信息发送到计算机。计算机使用包含航班、登机口和路线信息的数据库来控制小车的发动机与转向开关,以将行李车送到目的地。

该系统未能按计划正常工作。在测试过程中,小车会在轨道交叉点处相撞。该系统会出现错误路径、丢弃和乱放行李的情况,如本应该去搬运行李的小车却被错误地送到等待区。

这个案例中的具体问题都是很有启发性的:

(1)现实世界的问题。有些扫描仪被弄脏了或者被撞歪了,因此无法检测到路过的小车。在有些小车上出现了插销故障,导致行李会落在轨道上。

(2)在其他系统中的问题。该机场的电气系统无法处理与行李系统有关的电源峰值。在第一次全面测试时,许多电路被烧坏,因此测试不得不中止。

(3)软件错误。因为软件错误导致真正需要的小车被导向了等待区。

没有人期望如此复杂的软件和硬件能够在首次测试时就可以完美地工作,会存在设计人员可能没有预料到的无数的相互作用和状况。如果在早期测试时发现行李会被送错,并且错误被及时修复的话,那么并不会让人觉得尴尬。但是如果问题是在系统运行之后才被发现,或者它需要花长达一年时间来修复的话,这才是令人尴尬的。是什么导致了在丹佛行李系统出现的这种令人惊讶的拖延呢?有两个主要的原因:

(1)留给开发和系统测试的时间是不够的。唯一一个同等规模的行李处理系统是在德国法兰克福机场。开发该系统的公司花了六年时间进行开发,并用了两年进行测试和调试。而负责建造丹佛机场行李系统的BAE自动系统公司则总共只给了两年时间。一些报告表明,因为机场的电气问题,实际上只有六个星期的测试时间。

(2)在项目开始之后,丹佛机场对项目需求做了大量修改。最初,该自动化系统只是为了服务美国联合航空公司,但是丹佛官员决定将它扩大到包括整个机场,使得该系统的规模比BAE公司曾在旧金山国际机场为联合航空公司安装的自动行李系统的规模扩大了14倍。

《PC周刊》的一名记者表示:“该事件的主要教训是,当把成熟的技术扩展到一个更复杂的环境中的时候,设计师需要预留大量的测试和调试时间。”有观察家批评BAE公司,它们在知道没有足够的时间来完成它的时候,就不应该接手这个任务。其他人指责市政府管理不善,决策带有政治动机,以及试图推动一个虽然宏大却不切实际的计划。

人们质疑在确定机场启用的预计时间时,是否考虑了政治上的需要,而不仅仅是项目的需要。

3.5.5 哪里出了毛病

计算机系统故障一般有两个原因:它们正在做的工作本来就很难,以及有时候它们没有把工作做好。之所以它们的任务很困难,是因为有几个因素交织在一起造成的。计算机系统需要与现实世界(包括机械设备和不可预测的人类)进行交互,包含复杂的通信网络,它们拥有众多相互连接的子系统,拥有需要满足许多类型用户的功能,而且它们的规模是非常大的。从智能手机到汽车、客运飞机和喷气式战斗机,它们的设备和机器上都包含数百万行计算机代码。机械系统中的一个小错误可能会导致一个小的性能下降,而在计算机程序中一个地方敲错就可能会导致行为上的巨大差异。

在构建和使用一个系统的工作中,任何一个阶段都可能出现问题:从系统设计和实现,到系统的管理和使用。当然,这个特性不是计算机系统独有的。我们可以用相同的方式来描述建造桥梁、楼房、汽车或其他任何复杂的系统。

出现问题的原因如下:

(1) 过度自信 。或者说对一个复杂系统中的风险拥有不切实际的或不足的认识,是软件故障的一个核心问题。当系统开发人员和用户能够理解风险的时候,他们有更多的动力来利用现有的“最佳实践”以构建更可靠和更安全的系统。

发生故障的一些安全关键系统都拥有所谓的“故障保护”的软件控制。在某些情况下,程序的基本逻辑是好的,而出现故障是因为没有考虑到系统与实际用户或现实世界进行交互的问题(如线缆变松、火车轨道上的落叶、一杯咖啡洒落到飞机驾驶舱内等)。

对可靠性和安全性的不切实际的估计,可能来自真正缺乏了解、粗心大意,或故意的不实陈述。对诚信不是很重视的人,或者在缺乏诚信文化和没有专注于安全的组织中工作的人,有时候会为了商业或政治压力而夸大安全或隐藏缺陷,其目的是避免不利的宣传,或避免因为改正错误或诉讼而产生费用。

(2) 软件复用 。前面我们说过,在法国阿丽亚娜5型火箭首次发射后不到40秒,火箭就偏离了轨道。火箭和它携带的卫星的成本约为5亿美元。这起事故是软件复用时造成的软件错误所致。

再看一例。一个叫作杨·亚当斯的人,和姓亚当斯并且名字的首字母是J的许多其他人一样,都被标记为可能是恐怖分子,从而在试图登机时会受到阻拦。事实上,在航空安全局发给航空公司的可疑恐怖分子(或其他被认为有安全威胁的人)的“禁飞”名单上的名字是“JosephAdams(亚当斯)”。为了与在“禁飞”名单上的乘客名字进行比较,一些航空公司使用的是比较老的软件和策略,其目的是帮助机票代理商迅速找到乘客的机票预订记录(例如,如果乘客打电话咨询或要做出修改的时候)。该软件会执行快速搜索,并且会“广撒网”。也就是说,它会找到所有可能的匹配,然后由销售代理执行进一步的验证。在预期应用场景中,如果该程序给代理提供具有类似名称的多个匹配,并不会给大家带来不便。然而,在把乘客标记为可能的恐怖分子的情况下,一个人如果被错误“匹配”,就可能会不得不接受安全人员的质询以及对行李和身体的额外检查。

面向对象的代码这类编程范型的一个重要目标是开发可以广泛使用的软件构件,从而可以节省我们的时间和精力。复用运行良好的软件还可以提高安全性和可靠性。毕竟,它经历过在真实的运行环境下的现场测试,我们也知道它可以正常工作。关键的一点是,它需要可以在不同的环境下正常工作。因此,必须重新审视该软件的需求说明、假设和设计,考虑在新环境下的影响和风险,并对该软件的新用途进行重新测试。 A/DMOuBX+qIC/+ZbdBRoaprOX9hre3YWkFbQOayYTC9v4ClLNklWNby//0SmGtfS

点击中间区域
呼出菜单
上一章
目录
下一章
×