随着计算机技术的普及和发展,硬件可靠性技术日趋成熟,软件可靠性问题变得日益突出。美国军用装备中软件成本在总成本中的比重已从1955年的不到20%增加到1985年的90%以上。在软件开发的早期阶段,软件产品像是在手工业个体作坊中制造出来的工艺品,不是现代化严格科学管理下生产出来的工业品,因此,软件可靠性是当今可靠性工程研究领域中的新课题。
1.软件可靠性的概念
和硬件可靠性相似,软件可靠性的定义是:软件按规定的条件,在规定的时间内运行而不发生故障的能力。同样,软件的故障是由于它固有的缺陷导致错误,进而使系统的输出不满足预定的要求,造成系统的故障。所谓按规定的条件主要是指软件的运行(使用)环境,它涉及软件运行所需要的一切支持系统及有关的因素。如支持硬件、操作系统及其他支持软件、输入数据的规定格式和范围、操作规程等。
和硬件可靠性相似,在软件的寿命周期中,也有早期故障期和偶然故障期。早期故障率也高于偶然故障期的故障率,但软件不存在故障率呈增长趋势的耗损故障期,软件的缺陷纠正一个就减少一个,不会重复出现。
故障率也是度量软件可靠性的直观指标。一般要求:在软件交付用户的三个月内,早期故障率不大于0.01h-1;在交付用户四个月后,故障率不大于0.001h-1。
2.保证软件可靠性的工程方法
为了保证软件的可靠性,应在软件寿命周期的各个阶段千方百计地减少缺陷。软件开发周期错误和软件故障分类的百分数分别如表1和表2所示。
表1 软件开发周期各阶段错误的百分数
表1 软件开发周期各阶段错误的百分数
软件开发周期各阶段 需求分析 设 计 编码与单元试验 综合与试验 运行与维护
错误百分数(%) 55 17 13 10 5
表2 软件故障分类的百分数
软件故障分类百分数(%) 36 28 6 6 5 5 5 2 7
由表1、表2的统计数据表明,在软件寿命周期的各个阶段都可能发生软件错误或故障。而需求分析和软件设计阶段发生错误或故障的比重占多数。
同时,统计数据同样表明,软件错误的改正所需费用也是越晚越高。
为保证软件可靠性,在其寿命周期各个阶段需要采取如下的措施。
(1)需求分析阶段 本阶段主要措施是,全面理解用户的使用要求、使用条件和软件功能,在全面分析和与用户充分交换意见的基础上,制订出软件的技术规格书。该规格书要说明测试软件的方法,有完整的软件技术要求,用语要准确和规范。
(2)设计阶段 在软件设计阶段,要把软件的技术要求转换成设计方案。此时,可采取如下的方法。
1)自顶向下设计;
2)采用结构化程序设计;
3)容错设计;
4)设计评审;
5)(标准)模块化设计;
6)制订和贯彻软件可靠性设计准则。
(3)编码阶段 编码就是把设计方案变成计算机语言,也就是所谓的编程序。编码产生的缺陷也是软件缺陷的一个主要来源。常见的编码缺陷有:键入错代码、原始数据输入错误(含单位不一致等)、用了被零除这类不正确表达式等。
应在编码过程中尽可能早地查出缺陷并予以改正。
(4)检验阶段 检验阶段主要任务是发现软件中的缺陷,并加以清除。这个阶段对于保证软件的可靠性是很关键的。
为了查找缺陷,首先要对软件进行静、动态调试。此时,需检查源程序的结构、方法和过程间的接口是否有误,运行时是否存在不必要的功能,检查“要求”、“数据”、“结果”和“内部程序工作状态”对应关系是否正确。
软件的测试按模块测试、整体测试和系统测试的次序依次进行,最终确认软件的全部功能能否正确而完全地实现。
(5)维护阶段 软件交付使用后,要对使用中发现的残存缺陷进行纠正。同时,由于软件的运行环境和调试时不尽相同,也需对软件进行必要的修改、补充和完善。此时用户也可能提出一些新的要求。此外,还应经常研究出错的记录,前后对照和分析,弄清楚软件是否存在某种隐患。
3.容错设计
对于软件失效后果特别严重的场合,如飞机的飞行控制系统、空中交通管制系统、核反应堆安全控制系统等,可采用容错设计方法。此时,软件的故障率要求低于0.001h-1。常用的容错方法如下:
(1)N版本编程法 N版本编程法的核心是:通过多个模块或版本不同的设计软件,对于相同初始条件和相同输入的操作结果,实行多数表决,防止其中某一软件模块/版本的故障提供错误的服务,以实现软件容错。
为使此种容错技术具有良好的结果,必须注意:
1)使软件的需求说明具有完全性和精确性。这是保证软件设计错误不相关的前提。因为软件的需求说明是不同设计组织和人员的唯一共同出发点。
2)设计全过程的不相关性。它要求各个不同的软件设计人员彼此不交流,程序设计使用不同的算法、不同的编程语言、不同的编译程序、不同的设计工具、不同的实现方法和不同的测试方法。为了彻底保证软件设计的不相关性,甚至提出设计人员应具有不同的受教育背景,来自不同地域、不同的国家。
(2)恢复块技术 恢复块技术的设计思想是:把一些特有的故障测试和恢复特性引人单一版本软件。其目的在于:用可接收性测试(Acceptance Test)实现软件的故障测试。该测试对首先启动的模块运行结果实行。如果测试不通过,则恢复系统的原来状态,在相同的硬件上执行另一模块;若以后的可接受性测试得以通过,则被认为完成了恢复功能。
恢复块技术的要点是:可接收性测试准则,恢复点的状态保持和选择策略,以及不同算法的设计。