千年问题:害虫多多,时间少少_互动科普

使用社交账号登录

购买价格:
付款方式:

互动科普

主页 > 科普纵览 > 生物 • 医学

千年问题:害虫多多,时间少少

admin  发表于 2017年09月24日

解决千年问题似乎很容易:将所有两位数年份变为四位数就行了。然而,这一漫长烦人和意想不到的困难过程所费的时间超过了留给我们的时间。

隐含于计算机千年问题后面的心理学解释也许能在不存在的地方找到:Lewis Carroll的《艾丽丝漫游奇境记>在这本普及的儿童经典著作中,Mad Hatter问,“你的手表能告诉你今年是哪年吗?”爱丽丝回答,“当然不能.因为这么长时间它都停留在同一年里。”

有很多理由来说明程序设计人员(包括我在内)为什么只用两位数来代表年份,例如95表示1995年.10/23/76或23/10/76表示1976年10月23日几十年前数字资源是稀缺的,计算机存储器十分昂贵,典型的穿孔卡只有80列宽。人们也用减少键击次数提高效率来证明这种省略的合理性,当然,缺乏标准起了推波助澜的作用我们许多人的确坚信(并不正确),在新的千年到来之前我们编写的软件早就弃而不用了。由于纯粹的惯性和冗长的茶会逻辑(一个世纪这么长的时间内都保持一致,那为什么要存贮两位以上的数字呢?)在计算机存贮器和成本限制的合理关注之后很久,这种做法依然继续实行着。

千年问题 1.png

最终效果如何?计算机正被可能引起巨大混乱的日期表示法困惑着。简而言之,数字机器怎么知道00表示1900还是2000?这种混淆已造成了种种麻烦早在1993年,波音公司就在处理提前7年订单的应用程序中发现了错误,肥皂和其它个人保健用品全球制造商Amway公司的—个系统因为错误地认为化学品几乎是一个世纪的陈年旧货而拒绝它们。某些计算机控制的现金出纳机在顾客试图使用以00为截止期的信用卡时就失灵了。事实上,根据一年前进行的一项工业界调查,所调查机构40%以上都遭遇过某种形式的千年问题事故。

千年问题的实质

准确地说,什么东西导致了这类问题?最明显的例子就是在1999年存款,而在2000年取款,如果银行计算利息的帐户程序先从00减去99,计算机就会错误地认为存款期是负99年.

考虑一个更令人头疼的千年陷井:某保险公司必须例行检查己失效5年的保险单.以便将其从数据库中删除为确定这些失效保险单,公司运行依赖名为LAST-ACCESS贮存数据的程序,而LAST-ACCESS包含了客户进行交易的最新日期的时间标记。

当程序检查一个LAST-ACCESS值时,它将5加到两位数的年份上去,如果结果小于当前年份,它就删除记录因此,当LAST—ACCESS为93时,则93+5<99此保险单就被正确地确认无效。然而,如果LAST—ACCESS为96时,处理就陷入了困境。如果只允许两位数且多余的信息被去除,96就变成01,这小于99结果导致该保险单被错误地终止(尽管这个例子描述的程序是不完美的,人们可能不在意它,但此类麻烦已发生)。

在另一个例子中,千年问题错误可能确确实实地导致致命后果。医生利一个开出某些药品剂量的医学程序,他打入03—16-00表示婴儿的出生日期.然而,计算机却推定患者是世纪老人,由此开出的剂量对上了年纪的成年人来说可能是恰当的,而对娇小的新生儿来说却是致命的。这就是2000年问题的实质。人们模糊的存储年份,现在这种混乱开始造成灾难。许多机构已经完全用解决了千年问题的新软件取代会出错的程序:对于嵌入系统,这种策略有时是唯一可行的选择,但要取代已投入使用的金字塔式计算机程序则可能代价太高并且破费时间。因此公司就要试着修补它们已有的软件。

日期究竟是什么?

当人们初次意识到千年问题时,他们很快就提出了合理的甚至是最优的修正策略:如果省去了两位数,只要把它们补上就行了现在撇开涉及修正多国公司的无数字节数据的逻辑复杂性不说,这种方案提出了关键的然而似乎是滑稽的问题,日期是什么。毕竟,人们在将两位数加到每个年份之前,必须先找处日期。计算机并不知道它们引用的任何信息实际代表什么意思,注意这点是重要的,数据的意义是人类赋预予的,或者更中肯地说,是留给人类的。并且程序员在给日期规定标记名时,也没有一套标准可循。例如,日期可以具有令人头疼的标签(例如,SNARK的WUMPUS)也可以采取更明了的方式(例如BIRTH-DATE和EMP-START-DT)。

人们也不能完全依赖数字信息本身。一种方法是筛选数据,选出从1到12,从1-3l和从0到99的数字列、然后假定最后一类数字表示年份尽管这种假设是合理的、但并非总是正确的lI到99的数据可能代表某种量的百分比,并目,位数的年份常常深深地隐藏于其它数据一一例如长长的产品序列号一的内部已开发出了自动软件工具来确定年份某些更先进的工具利用演绎推理取得了惊人的成功率但是,还没有任何工具取得从不出错的成绩。

找出日期仅仅是第一步,将所有年份变成4位数的一个问题是,程序员必须重新设计某些报告的格式,形式和屏幕显示容纳额外的数字一更大的复杂性是引用扩充了的数据的软件应用程序也必须修改。

千年问题 2.png

考虑一个人事数据库,其中雇员的姓名由1-30列存贮,生日期由31-36列存贮,薪水由37—42列存贮,等等如果出生日期扩展成容纳4位数年份,则薪水信息和所有随后的数据也都必须向右挤移两列。结果,所有检索这些信息的程序都必须调整以从正确的位置获取数据,

这类变化一般都牵涉到改变“源代码”。源代码由程序用COBOL和C语言等编写。然后软件被转换成称为目标模块的形式即计算机能够理解的形式此翻译过程由编译序执行固为编译程序不断升级,就会出问题在某些情况下,早期编译程序认为合法而接受的程序技术现在可能被禁止:同样的道理,字处理软件程序的版本l生成的文件可能被同一产品的版本V拒绝。因此,最近才正确处理千年问题的老源代码可能不再被恰当地编译成新的目标模块,除非进行额外修改。

更糟糕的是,许多公司已失掉了部分源代码尽管丢失软件的数量一般低于3—4%;但就是这少量的东西就会引起极大的麻烦,因为程序员不能轻易地直接修改目标模块他们必须重新创造源代码,方法是擦除(这是困难的事情因为相应的文件也极有可能已丢失)或者取自目标模块本身(这是极端困难的过程,就象从腊肠中去重新再出一头猪一样)。

一旦源代码被修正和重新编译它还必须经过测试因为软件的修改几乎总是引出新虫,所修正后程序的测试现在已成了任何千年问题项目最繁重的部分工作。

90年代初期,许多专家断言,日期增位是解决千年问题的最佳途径。但是,他们没有料到必须重新编译引用了任何文件中的日期的一程序(甚至在应用程序不进行日期计算时也是如此),而此种必要性使这一方法对大多数公司而言,代价太高而且又费时(当然,扩到4位数在公元9999年与公元10000年之交时、同样会导致万年问题,这是另一篇文章的主题)。

曙光初露

一种选择方案是教计算机将00认作2000年程序员已将这种简明的思想应用于称为打开窗户”的策略之中、他们选出所有从00到99的年份并根据精心挑选的元素(例如45)将这些年份分为两组、大于或等于此数的位数年份就保留在当前世纪(68变成1968)其它的年份则进入21世纪(13变成2013).

使用这种概念,程序员能挖掘源代码技出所有日期的数据并根据相关信息修正计算因为不需要更改实际的两位数年份本身(只是调整涉及这些年份的计算从而将年份置于适当的世纪):所“打开窗户”所需工作量比日期扩展少得多:是目前用于解决千年问题最普遍的技术然而,这种方法也有缺点它显然不能适用于分布范围任何超过l00年的数据,例如出生13期和长期租赁当信息必须在使用不同元素点的系统间转移时也会出现一些有趣的问题。例如,25对成立于l928年的公司处理发票的程序来说可能是适当的,但同家公司处理期销售计划的另一种应用程序则可能选用70。当然,问题只在信息必须于种系统间转移时(2031年变成1931、或者1931年变成2131年)才引起有害的计算。

对于复杂的问题,程序员还使用了滑动窗户策略,在这种策略中元素随时间变化这种策略对某些类型的程序(例如处理30年期的住宅抵押货款程序)是有效的对这种应用程序,元素可能设定为从当前年起的40年。显然,关键的事情是要记录变动的元素以避免与其它系统可能的冲突。此外,程序员必须认识到,在一个以70为元素的程序中表示年份1968年将需要额外的软件策略.

时间变动

在另一种方法中,基本的算术用来巧妙地解决千年问题考虑计算00-99=99如果想要进行的计算是2000-1999,则答案一99明显是错误的。但注意00-99等价于(00+5)一(99+5),如果此式在两位数范,围计算,其结果是5—4=l。如果将5加到00和99上去,结果两个日期都变到一个世纪中去了,这样运算2000-1999只用两位数就能正确执行了。

不过日期并非仅仅是数字问题。2000年1月1日是星期六,2005年1月1日却不是星期六这样,将所有年份加5的方法不适于需要区分星期几的程序。但并非毫无办法从根本上讲+两个循环控制着某一天是星期几:一个是不同天日的以7为周期的循环一个是闰年的以4为周期的循环将两个循环乘起来就得到一个周期为28的大循环。2009年1月1日,1972年1月1日和2028年1月1日都是星期六利用这种规律,“囊括(encapulation)”技术在做进一步计算之前将“28”加到两位数年份上去;计算结束后。又将“28”从日期中减去。

尽管囊括技术可用来对付大量千年问题,但它对复杂的计算却不方便。一个例子就是一个应用程序与另一个或多个程序并行运行的时候:在它自身运算的时候,该应用程序可能向以自身方式运行的其它系统输送信息。结果就会以不同的时间间隔被反复地融合程序员将难于决定和保持什么时候加“28”,什么时候减“28“的时机。

此外,囊括技术不能解决隐藏于其它使用了某些数来进行验证的信息中的日期同题例如,某产品贮存号是728947995,其中99表示期满年,而最后一个数字5则用于验证整个序列在这个例子中5是将7289,17和99加在一起,然后取总和7453的最后一位数而得到的。所谓校验数字经常用于验信用卡、条形代码和社会保障号码显然,随便将28加位数年份上将搞乱这种验证计算日期扩展打开窗户和囊括这3种技术如今占了解决千年问题现存软件的95%以上。许多拥有数以千计计算机程序的大公司已以采州了混和方法已有软件工具自动地实施3种解决方案,但还没有取得任何不出错的成功事例。

不正常的情况是某些软件已经考虑了世纪更选这个因素这种情况重妨碍了千年问题的解决原来的程序员已用他们自己的打开窗户或冀括方案预防千年问题但这些预防措施并没有彻底用于整个程序中从而使系统处于解决的两可之间这种尴尬境地=对于这类软件,采用其它补救措施可能引起数据混乱一一使用不同关键年份的双重开窗或者对同一数据进行开窗和囊括。

确定一个软件应用程序是否预存了解决方法是件困难的事情,特别是在代码写得很差,文件组织得很糟时更是如此作为一名程序员我不得不坐下来数小时面对少量代码(只有10一l5行),艰难地确定这些软件究竟想完成什么事情自动工具的危险是,它们盲目地应用点心切割(cookie—Cutter)这种囫囤吞枣的办法,而并不了解代码实际上在做些什么事情。

还有另外的麻烦一种常见的编程习惯是赋予快要接近2001年的日期或年份特殊的含义特别地,程序员经常利用“9999”或简单的99”来表示应当删去或归档的文件或记录的结柬当然,现在这种措施导致了混乱,因为两个数字可能被合理地分别认作1999年9月9日和1999年。例如一个销售应用程序可能提示职员键入99作为年份,如果他们想删除相应的客户订单的话。现在此程序必须以另外的方式重写以完成相同的请求。

另一个复杂问题涉及到闰年。因为地球以略小36525天(更准确的数字是365242199天)的时间围绕太阳公转闰年不会严格地遵循4年一个循环例外的是世纪年一一例如170(1年和1800年,它们不闰年,但这一例外的例外是能被4整除的世纪。因此2100年将有2月29目(尽管1900年没有这样一天,)没有利用这种知识进行适当编程的计算机将被这种情形进一步弄糊涂。

数字灾难?

上述各种因素加上种种其它理由,已导致人们对千年问题的前景普遍没有把握,并引发了对这个问题的热烈争论争论的一个极端是一种极为悲观的看法一一我们有可能永远失去电力……”(一位发言者在最近一次千年问题会议上就是这么说的)争论的另一个极端则是盲目乐观——“千年问题是一日之事。人们在周末就能解决所有的问题。”)

在我看来,两个极端都无异于无知前者忽视了人类社会战胜灾难的能力认为人们将永远失去生产电力的智能这种观点不值得仔细推敲。事实上,许多组织(例如金融机构)已提供了必要的资源,在对付千处问题方面已取得了重大进展。去年夏天华尔街模拟了2000年1月313股票交易的情形,只暴露了了极小的日期敏感问题。另外的测试计划于今年春天进行。

另一方面,轻视千年问题则忽视了现代社会的技术脆弱性,现代社会由一环扣一环的相互依存的复杂基础支撑着。特别是,一处故障很快就能波及全系统,从而造成灾难性后果银河4号一一许多通信卫星中的仅仅一颗一一去年春天出了毛病,数百万传呼机突然死机。在新西兰奥克兰市,仅仅一根电缆出事,就使整个系统过载,全城停电6个星期。

上述事情偶然发生了,无一被预见过。当然,千年问题就不一样了一一它已被预见到。今天世界各地的计算机专业人员都在修正他们众多的现存软件加拿大帝国商业银行预算耗资1亿8千万美元,动用1000名工作人员一攻克这个项目。美国电报电话公司已经耗去5亿美元,纽约花旗银行将开支6亿5千万美元左右,国内收入署大约斥资10亿美元。

这是巨大的投入,但是如果人们对大型软件项目稍有了解,就应当知道许多项目都不会按期完成,而能够如期完成的项目也很少会正常运行否认这一点就是忘记以前的软件灾祸,包括亚特兰大奥运会计算机事故和丹佛国际机场的计算机故障实际上,及时的不出错的复杂计算机系统设备是少见的。千年问题项目极其艰难的一面就是晟后期限是不可更改的基于上述分析并考虑其它因素(包括已经完成的工作,临近世纪之交人们必须采取的已预计的应急措施和妥协)、我相信,严重的混乱状况将会发生并持续一个月左右其它的问题一一从烦恼到更严重的问题一一将持续整个2000年这一预测还是乐观的:它假定人们将完成把可能发生的单个问题专的数目减少到最低限度所必需的工作在剩下的时间里单是完成这些工作就需要作出在计算机历史上前所未有的艰苦努力。

 

 


全部评论

你的评论