9.2 软件可靠性模型
软件可靠性模型(Software Reliability Model) 是指为估算软件的可靠性所建立的数学模型。
9.2.1 影响软件可靠性的因素
影响软件可靠性的因素多种多样,包括软件产品的特性、开发过程、运行环境和投入等。识别和优化这些关键因素,可以显著提升软件的可靠性。
- 运行剖面(环境):运行环境和用户的使用方式。
- 软件规模:规模越大更容易有bug
- 软件内部结构:结构越复杂越容易有bug
- 开发方法和开发环境:结构化开发方法能显著减少软件缺陷。
- 软件的可靠性投入:早期投入更多资源在可靠性方面的设计和测试上更可靠。
9.2.2 软件可靠性的建模方法
一个软件可靠性模型通常由以下几部分组成
- 模型假设:
- 代表性假设:选取的测试用例可以代表软件在实际运行时的环境和情况
- 独立性假设:软件失效是独立事件,bug彼此之间没有因果关系或影响
- 相同性假设:所有软件失效的影响或严重程度是相同的
- 性能度量:模型的输出
- 参数估计方法:某些度量的实际值无法直接获取,就需要估计参数的值。模型的参数通常由估计或预测两种方法来确定。
- 数据要求:
9.2.3软件的可靠性模型分类
1、种子法模型:在软件里故意加一点错误(种子),再测试看能找到几个。(比如种10个,找到5个,那就根据真实测试的bug数按比例推算系统的故障数)
2、失效率类模型:在一定时间内出错的次数。
3、曲线拟合类模型:使用统计方法来分析软件的复杂性和出错情况。
4、可靠性增长模型:记录下修复问题后,软件逐渐变好、失效减少的过程
5、程序结构分析模型:把软件看成一个包含不同部分(子程序、模块)的网络,分析它们之间的关系和每部分的可靠性,就像分析一个多车道公路系统中每条路的通畅度,来评估整体的可靠性。
6、输入域分类模型:根据软件在不同输入条件下运行时的表现来判断其可靠性。
7、执行路径分析方法模型:分析软件中不同路径的执行概率,看哪些路径有问题,哪些没有。
9.3 软件可靠性管理
将可靠性目标、计划、任务、进度、修正措施等融入每个开发阶段,确保软件在各阶段的可靠性要求得到满足。以下是各阶段的主要活动:
- 需求分析阶段:确定可靠性目标、影响因素、验收标准,制定管理框架和初步计划。
- 概要设计阶段:确定可靠性度量,制定验收方案,进行可靠性设计和数据收集。
- 详细设计阶段:继续设计、预测和调整可靠性活动,编制相关文档。
- 编码阶段:进行可靠性测试和排错,收集数据并调整计划。
- 测试阶段:进行集成和系统测试,评价可靠性,调整计划并编制报告。
- 实施阶段:验收测试,排错,收集数据,调整可靠性模型并进行最终评价。
尽管目前的可靠性管理仍多停留在定性描述上,难以量化,如何在有限资源下实现预期的可靠性目标仍是软件项目管理的挑战。
9.4 软件可靠性设计
软件可靠性设计是在设计阶段将可靠性要求融入软件中,以从根本上提高软件的可靠性并降低后期修改的成本和难度。
9.4.1 容错设计技术
将程序划分为多个快(模块、子程序或程序段),他们具有相同的功能,但实现逻辑不同。每个时刻只有一个块在运行,若当前块发生故障,则实时切换到备份块继续运行
2、N版本程序设计:
同一个功能由不同的团队独立设计(团队差异化越大越好),当输入相同时,例如有3个版本的实现,若有2个版本结果相同,则使用此结果为输出。优点是高可靠性,缺点是实现成本高。
3、冗余设计
设计开发完成同样功能但实现方法完全不同的两套软件系统,一套用于主系统,一套用于备份系统。备用系统处于待命状态,在主系统故障时切换到备用系统继续运行。
9.4.2 检错技术
通过在系统运行中监控并发现故障来提高软件可靠性的方法,但不能自动解决故障。其成功主要依赖于以下四大因素:
1、检测对象:
- 检测点:选择容易出错或影响较大的位置。例如:数据输入/输出接口、临界资源访问点、复杂算法的关键步骤。
- 检测内容:选取具有代表性且易于判定的软件行为或指标,例如:数据的合法性、系统状态的正确性、模块的执行结果。
2、检测延时:
检测延时是指从故障发生到检测出故障的时间间隔,对故障处理的及时性至关重要。需要优化检测机制,减少检测延时。若延时过长,应更换检测点或采用更高效的检测方法。
3. 实现方式
- 结果范围检查:判断模块返回结果是否超出预期范围,超出即触发异常处理。
- 运行时间监控:检查模块或函数是否在规定时间内完成,超时视为可能故障。
- 状态标志位:为模块设置标志位,检测标志位的正确性来判断模块状态是否异常。
- 异常检测工具:利用现成的监控工具,自动捕获异常(如系统日志、断言机制)。
- 冗余结果比对:运行多个模块并比较其输出是否一致。
4. 处理方式
故障检测后的处理方式取决于系统的实时性要求和故障的严重程度:
- 完全停止:故障发生后立即停止软件运行并报警,常见于高安全性系统(如核电控制、医疗设备)。
- 部分停止:系统运行部分功能,减少故障对整体的影响。适用于容错设计较好的系统。
- 不停止:在故障点隔离后,继续运行其余模块。常见于高可靠性系统(如分布式系统)。
9.4.3 降低复杂度设计
软件复杂度过高会显著增加开发、维护和测试的难度,当软件复杂度超出一定界限时,缺陷数目呈指数增长,可靠性降低。因此我们可以通过降低软件的复杂性来提高软件的可靠性。
1、复杂度
软件复杂性是指软件系统的内部结构和行为复杂程度,主要包括:
模块复杂性:模块内部的复杂程度,包括:数据流的路径和分布、代码的长度及逻辑嵌套深度
结构复杂性:模块之间的关系,包括:模块间交互程度、数据共享的方式和频率、系统层次的深广。
2. 降低复杂度设计的措施
- 简化结构:通过模块化设计,将复杂的系统分解为功能单一、独立的模块。优化模块间的调用关系。
- 缩短代码长度:避免不必要的冗长代码,采用简洁、可读性高的编程风格。使用函数、方法等技术实现代码复用。
- 优化数据流:减少全局变量,使用局部变量或参数传递。合理设计输入/输出接口,确保数据流向清晰且高效。
- 限制嵌套深度:避免过深的嵌套循环或递归调用。
- 采用标准化设计:使用通用的设计模式和编程规范。