软考-软件工程基础知识

一、软件的生命周期

软件的生命周期是指 从软件产品的设想开始到软件不再使用而结束的时间。
软件的生命周期分为6个阶段,即 需求分析、计划、设计、编码、测试、运行维护。

1.软件工程包括三个要素

工具:软件工程支撑环境
方法:怎么做
过程:工作步骤

二、软件开发模型

在这里插入图片描述

1.瀑布模型

瀑布模型是将软件生存周期中的各个活动规定为依线性顺序连接的若干阶段的模型,包括:需求分析、设计、编码、测试、运行与维护。它规定了由前至后、相互衔接的固定次序,如同瀑布流水逐级下落,如图所示:
在这里插入图片描述
瀑布模型为软件的开发和维护提供了一和有效的管理模式,根据这一模式制定开发计划,进行成本预算,组织开发力量,以项目的阶段评审和文档控制为手段有效地对整个开发过程进行指导,所以它是以文档作为驱动、适合于软件需求很明确的软件项目的模型。每个阶段都有一个文档。文档上级评审,评审通过,开始下一个模型。
瀑布模型的优点
容易理解,管理成本低;
强调开发的阶段性早期计划及需求调查和产品测试。
瀑布模型的缺点
1.客户必须能够完整、正确和清晰地表达他们的需要;
2.在瀑布模型中,需求或设计中的错误往往只有到了项目后期才能够被发现,对于项目风险的控制能力较弱,从而导致项目常常延期完成,开发费用超出预算。
适用于 需求明确/二次开发 或者 对交付时间有严格要求的项目。
1.某项目组拟开发一个大规模系统,且具备了相关领域及类似规模系统的开发经验
2.若全面采用新技术开发一个系统,以替换原有的系统
3.系统功能有清晰的定义,需求明确
4.瀑布模型难以适应变化的需求,不断变化的系统不宜使用瀑布模型。

2.V模型-测试

瀑布模型的一个变体是V模型。
它将测试模块细化分解,把测试看作与开发同等重要的过程,每一测试阶段的前提和要求是对应开发阶段的文档。
在这里插入图片描述

3.演化模型

在开发过程中,常常会面临以下情形:商业和产品需求经常发生变化,直接导致最终产品难以实现;严格的交付时间使得开发团队不可能圆满地完成软件产品,但是必须交付功能有限的版本以应对竞争或商业压力;很好地理解了核心产品和系统需求,但是产品或系统扩展的细节问题却没有定义。在上述情况和类似情况下,软件开发人员需要一种专门应对不断演变的软件产品的过程模型。

演化模型是迭代的过程模型,使得软件开发人员能够逐步开发出更完整的软件版本。
适用于需求不清、开发周期短的中小型系统。
演化模型特别适用于对软件需求缺乏准确认识的情况。

适用
1.尽快交付使用、使用过程中不断完善

典型的演化模型有:原型模型和螺旋模型等。

4.螺旋模型

对于复杂的大型软件,开发一个原型往往达不到要求。螺旋模型将瀑布模型和演化模型结合起来,加入了两种模型均忽略的风险分析,弥补了这两种模型的不足。
螺旋模型将开发过程分为几个螺旋周期,采用周期性方法进行开发,每个螺旋周期大致和瀑布模型相符合。
在这里插入图片描述
每个螺旋周期分为如下 4 个工作步骤:
(1) 制订计划。确定软件的目标,选定实施方案,明确项目开发的限制条件。
(2) 风险分析。分析所选的方案,识别风险,消除风险。
(3) 实施工程。实施软件开发,验证阶段性产品。
(4) 用户评估。评价开发工作,提出修正建议,建立下一个周期的开发计划。

螺旋模型强调风险分析,使得开发人员和用户对每个演化层出现的风险有所了解,从而做出应有的反应。因此,该模型特别适用于庞大、复杂并且具有高风险的系统。

与瀑布模型相比,螺旋模型支持用户需求的动态变化,为用户参与软件开发的所有关键决策提供了方便,有助于提高软件的适应能力,并且为项目管理人员及时调整管理决策提供了便利,从而降低了软件开发的风险。在使用螺旋模型进行软件开发时,需要开发人员具有相当丰富的风险评估经验和专门知识。

另外,过多的迭代次数会增加开发成本,延迟提本时间。

适用于风险较高、开发周期较长的大型软件项目

5.原型模型

并非所有的需求都能够预先定义,大量的实践表明,在开发初期很难得到一个完整的、准确的需求规格说明。这主要是由于客户往往不能准确地表达对未来系统的全面要求,开发者对要解决的应用问题模糊不清,以至于形成的需求规格说明常常是不完整的、不准确的,有时甚至是有歧义的。
此外,在整个开发过程中,用户可能会产生新的要求,导致需求的变更

原型是预期系统的一个可执行版本,反映了系统性质的一个选定的子集。
一个原型不必满足目标软件的所有约束,其目的是能快速、低成本地构建原型。
当然,能够采用原型方法是因为开发工具的快速发展,使得能够迅速地开发出一个让用户看得见、摸得着的系统框架。这样,对于计算机不是很悉的用户就可以根据这个框架提出自己的需求。开发原型系统首先确定用户需求,开发初始原型,然后求用户对初始原型的改进意见,并根据意见修改原型。
在这里插入图片描述
原型模型开始于沟通,其目的是定义软件的总体目标,标识需求,然后快速制订原型开发的计划,确定原型的目标和范围,采用快速射击的方式对其进行建模,并构建原型。被开发的原型应交付给客户使用,并收集客户的反馈意见,这些反馈意见可在下一轮中对原型进行改进。在前一个原型需要改进,或者需要扩展其范围的时候,进入下一轮原型的迭代开发。
原型方法比较适合于用户需求不清、需求经常变化的情况。当系统规模不是很大也不太复杂时,采用该方法比较好。

适用于
1.有效捕获系统需求
2.主要用于需求不明确,需求动态变化(例如界面开发)的项目。
3.超大规模不适用原型模型,尽快投入使用也不合适,成本也不低

6.喷泉模型

喷泉模型是一种以用户需求为动力,以对象作为驱动的模型,适合于面向对象的开发方法。
它克服了瀑布模型不支持软件重用和多项开发活动集成的局限性。

喷泉模型使开发过程具有迭代性和无间隙性,无间隙指开发活动之间不存在明显的边界。
又称迭代模型,每个阶段是相互重叠、多次反复的。每个开发阶段没有次序要求,可以并发进行,在某个阶段随时补充其他阶段中遗漏的需求。
在这里插入图片描述 选代意味着模型中的开发活动常常需要重复多次,在迭代过程中不断地完善软件系统。

无间隙是指在开发活动(如分析、设计、编码) 之间不存在明显的边界,也就是说,它不像瀑布模型那样,在需求分析活动结束后才开始设计活动,在设计活动结束后才开始编码活动,而是允许各开发活动交叉、迭代地进行

喷泉模型的各个阶段没有明显的界线,开发人员可以同步进行。其优点是可以提高软件项目的开发效率,节省开发时间。由于喷泉模型在各个开发阶段是重叠的,在开发过程中需要大量的开发人员,不利于项目的管理。此外,这种模型要求严格管理文档,使得审核的难度加大。

主要用于采用对象技术的软件开发项目。

7.增量模型

结合瀑布模型和演化模型的优点,它假设可以将需求分段为系列增量产品,每一增量可以分别开发。
当使用增量模型时,第1个增量往往是核心的产品。客户对每个增量的使用和评估都作为下一个增量发布的新特征和功能,这个过程在每一个增量发布后不断重复,直到产生了最终的完善产品。
增量模型强调每个增量均发布一个可操作的产品。
在这里插入图片描述
优点
1.增量模型作为瀑布模型的一个变体,具有瀑布模型的所有优点。
2.第一个可交付版本所需要的成本和时间很少;
3.开发由增量表示的小系统所承担的风险不大;
4.由于很快发布了第一个版本,因此可以减少用户需求的变更;核心产品往往首次开发,可以经过多次测试
5.运行增量投资,即在项目开始时,可以仅对一个或两个增量投资。
6.不必等到整个系统开发完成才可以使用;
缺点
1.如果没有对用户的变更要求进行规划,那么产生的初始增量可能会造成后来增量的不稳定;
2.如果需求不像早期思考的那样稳定和完整,那么一些增量就可能需要重新开发,重新发布;
3.管理发生的成本、进度和配置的复杂性可能会超出组织的能力。

利用增量模型进行开发时,如何进行模块的划分往往是难点所在。

适用于
1.是一种能够快速构造可运行产品的方法

8.统一过程模型

定义
统一过程模型是一种“用例和风险驱动,以架构为中心,迭代并且增量”的开发过程,由UML 方法和工具支持。

迭代的意思是将整个软件开发项目划分为许多个小的“袖珍项目”,每个“袖珍项目”都包含正常软件项目的所有元素:计划、分析和设计、构造、集成和测试,以及内部和外部发布。

统一过程定义了 4 个技术阶段及其制品:
1)起始阶段
起始阶段专注于项目的初创活动。
2)精化阶段
精华阶段在理解了最初的领域范围之后进行需求分析和架构演进。
3)构建阶段
构建阶段关注系统的构建,产生实现模型。
4)移交阶段
移交阶段关注于软件提交方面的工作,产生软件增量。

在每个迭代中有 5 个核心工作流:捕获系统应该做什么的需求工作流,精化和结构化需求的分析工作流,在系统构架内实现需求的设计工作流,构造软件的实现工作流,验证实现是否如期望那样工作的测试工作流。

随着 UP 的阶段进展,每个核心工作流的工作量发生了变化。4 个技术阶段由主要里程碑所终止。
初始阶段:生命周期目标
精化阶段:生命周期架构
构建阶段:初始运作功能
移交阶段:产品发布。

RUP

统一过程的典型代表是 RUP。RUP 是 UP 的商业扩展,完全兼容 UP,但比 UP 更完整、更详细。
在这里插入图片描述
在这里插入图片描述

AUP(敏捷统一过程)

在大任务上连续,在小任务上迭代

解题速通

瀑布:需求明确,变更少;
原型:用户需求不是很明确,变更多;(系统规模不是很大,也不复杂)
增量:短时间内快速的开发一个可以直接运行的产品。
螺旋模型:风险分析。(复杂的大型软件)

三、开发方法

1.结构化法

即面向 过程 的开发方法。
其基本思想是 “自上而下,逐步求精”
其讲究的是用户至上,系统开发过程工程化、文档化、以及标准化。严格的区分来工作阶段,每个阶段都有明确的任务和应得额成果。
处理数据领域不太复杂的软件

2.Jackson方法

面向数据结构 的开发方法。以数据结构为驱动,适合于小规模的项目。当输入数据结构与输出数据结构之间没有对应关系时,难以应用此方法。

3.原型化方法

比较适合于用户需求不清、业务理论不确定、需求经常变化的情况。
当系统规模不是很大也不太复杂时,适合使用。

4.面向对象方法

自底而上
包括面向对象分析、面向对象设计和面向对象实现,采用统一建模语言(UML)。

5.敏捷方法

敏捷方法的定义

敏捷开发的总体目标是通过“尽可能早地、持续地对有价值的软件的交付”使客户满意。通过在软件开发过程中加入灵活性,敏捷方法使用户能够在开发周期的后期增加或改变需求。
敏捷过程的典型方法有很多,每一种方法基于一套原则,这些原则实现了敏捷方法所宣称的理念(敏捷宣言)。
它强调快速开发和有效适应需求变化。这种方法不要求严格遵循传统的软件开发流程,而是更加注重人的作用,强调开发团队与用户之间的紧密协作和面对面沟通。
敏捷方法适用于一开始并没有或不能完整地确定出需求和范围的项目,或者需要应对快速变化的环境。

1.极限编程(XP)

XP 是一种轻量级(敏捷)、高效、低风险、柔性、可预测的、科学的软件开发方式。它由价值观、原则、实践和行为 4个部分组成,彼此相互依赖、关联,并通过行为贯穿于整个生存周期。
4 大价值观:
沟通、简单性、反馈和勇气。
5 个原则:
快速反馈、简单性假设、逐步修改、提倡更改和优质工作。
12 个最佳实践:
1.计划游戏:快速制定计划、随着细节的不断变化而完善
2.小型发布:系统的设计要能够尽可能早地交付
3.隐喻:找到合适的比喻传达信息
4.简单设计:只处理当前的需求,使设计保持简单
5.测试先行:先写测试代码,然后再编写程序
6.重构:重新审视需求和设计,重新明确地描述它们以符合新的和现有的需求
7.持续集成:可以按日甚至按小时为客户提供可运行的版本
8.现场客户:系统最终用户代表应该全程配合XP团队
9.结对编程
10.集体代码所有制
11.每周工作 40 个小时
12.编码标准
XP主要解决代码质量问题,编码速度不能改变

2.水晶法

水晶法认为每一个不同的项目都需要一套不同的策略、约定和方法论。

3.并列争求法

并列争求法使用迭代的方法,其中,把每 30 天一次的迭代称为一个“冲刺”,并按需求的优先级别来实现产品。

4.自适应软件开发

自适应软件开发有6个基本的原则:
1.有一个使命作为指导;
2.特征被视为客户价值的关键点;
3.过程中的等待是很重要的,因此“重做”与“做”同样关键;
4.变化不被视为改正,而是被视为对软件开发实际情况的调整;
5.确定的交付时间迫使开发人员认真考虑每一个生产的版本的关键需求;
6.风险也包含其中。

5.敏捷统一过程

敏捷统一过程采用“在大型上连续”以及在“在小型上迭代”的原理来构建软件系统。采用经典的 UP 阶段性活动(初始、精化、构建和转换),提供了一系列活动,能够使团队为软件项目构想出一个全面的过程流。在每个活动里,一个团队迭代使用敏捷,并将有意义的软件增量尽可能快地交付给最终用户。

每个 AUP 迭代执行以下活动:
建模
建立对商业和问题域的模型表述,这些模型“足够好”即可,以便团队继续前进。
实现
将模型翻译成源代码。
测试
像 XP 一样,团队设计和执行一系列的测试来发现错误以保证源代码满足需求。
部署
对软件增量的交付以及获取最终用户的反馈。
配置及项目管理
着眼于变更管理、风险管理以及对团队的任一制品的控制。项目管理追踪和控制开发团队的工作进展并协调团队活动。
环境管理
协调标准、工具以及适用于开发团队的支持技术等过程基础设施。

四、需求分析

需求分析的定义及分类

软件需求是指用户对目标软件系统在功能、行为、性能、设计约束等方面的期望。具体内容如下:

1)功能需求。
考虑系统要做什么,在何时做,在何时以及如何修改或升级。
某系统实现每个月特定时间发工资
2)性能需求。
考虑软件开发的技术性指标。
例如,存储容量限制、执行速度、响应时间及吞吐量。
3)用户或人的因素。
考虑用户的类型。
例如,各种用户对使用计算机的熟练程度,需要接受的训练,用户理解、使用系统的难度,用户错误操作系统的可能性等。
4)环境需求。
考虑未来软件应用的环境,包括硬件和软件。对硬件设备的需求包括机型外设、接口、地点、分布、湿度、磁场干扰等,对软件的需求包括操作系统、网络、数据库等
5)界面需求。
考虑来自其他系统的输入,到其他系统的输出,对数据格式的特殊规定,对数据存储介质的规定。
6)文档需求。
考虑需要哪些文档,文档针对哪些读者。
7)数据需求。
考虑输入、输出数据的格式,接收、发送数据的频率,数据的准确性和精度,数据流量,数据需保持的时间。
8)资源使用需求。
考虑软件运行时所需要的数据、其他软件、内存空间等资源,软件开发、维护所需的人力、支撑软件、开发设备等。
9)安全保密要求。
考虑是否需要对访问系统或系统信息加以控制,隔离用户数据的方法用户程序如何与其他程序和操作系统隔离以及系统备份要求等。
10)可靠性要求。
考虑系统的可靠性要求,系统是否必须检测和隔离错误: 出错后,重启系统允许的时间等。
11)软件成本消耗与开发进度需求。
考虑开发是否有规定的时间表,软/硬件投资有无限制等;
12)其他非功能性要求。
如采用某种开发模式,确定质量控制标准、里程碑和评审、验收标准、各种质量要求的优先级等,以及可维护性方面的要求。

结构化方法的分析结果(产出)

一套分层的数据流图、一本数据字典、一组小说明(加工逻辑说明)、补充资料

需求分析阶段的产物

数据流图、数据字典、一组小说明(加工逻辑说明)、ER图(实体联系图)

五、系统设计

(一) 软件设计的两个阶段

概要设计和详细设计
对总体进行按功能划分模块是概要设计
对模块进行算法设计就是详细设计

1.概要设计

(1) 设计软件系统总体结构

基本任务是采用某种设计方法,将一个复杂的系统按功能划分成模块;

确定每个模块的功能;确定模块之间的调用关系;确定模块之间的接口(即模块之间传递的信息);评价模块结构的质量。

软件系统总体结构的设计是概要设计关键的一步,直接影响到下一个阶段详细设计与编码的工作。软件系统的质量及一些整体特性都在软件系统总体结构的设计中决定。
概要设计包括 系统框架、模块划分、系统接口、数据设计四个主要方面。

(2) 数据结构及数据库设计

1.数据结构的设计;
2.数据库的设计。
①概念设计;
②逻辑设计;
③物理设计;

(3) 编写概要设计文档

文档主要有:概要设计说明书、数据库设计说明书、用户手册、修订测试计划。

(4) 评审

对设计部分是否完整地实现了需求中规定的功能、性能等要求,设计方法的可行性,关键的处理及内外部接口定义的正确性、有效性、各部分之间的一致性等都一一进行评审。

2.详细设计

(1) 对每个模块进行详细的算法设计,用某种图形、表格和语言等工具将每个模块处理过程的详细算法描述出来。
(2) 对模块内的数据结构进行设计。
(3) 对数据库进行物理设计,即确定数据库的物理结构。
(4) 其他设计。

根据软件系统的类型,还可能要进行以下设计。
①代码设计;
②输入/输出格式设计;
③用户界面设计。

(5) 编写详细设计说明书。
(6) 评审。
对处理过程的算法和数据库的物理结构都要评审。

系统设计的结果是一系列的系统设计文件,这些文件是物理实现一个信息系统(包括硬件设备和编制软件程序) 的重要基础。

(二) 设计内容

在这里插入图片描述
体系结构设计(模块设计):体系结构设计定义软件模块及其之间的关系
接口设计:包括外部接口设计和内部接口设计
外部接口设计:分析模型中顶层数据流图,完成包括用户界面、目标系统与其它硬件设备、软件系统的外部接口的设计
内部接口设计:系统内部各种元素之间的接口
数据设计:根据需求阶段所建立的实体-关系图(E-R图)来确定软件涉及的文件系统的结构及数据库的表结构
过程设计:确定软件各个组成部分内的算法及内部数据结构,并选定某种表达形式来描述各种算法
在这里插入图片描述

(三) 软件设计原则

软件设计原则始终强调高内聚、低耦合的设计原则。
具体包括:
1.保持模块的大小适中
每个模块都应该专注于执行一个明确的功能。模块不应过大,以免难以理解和维护;也不应过小,以避免系统过于碎片化。适中的模块大小有助于提高代码的可读性和可维护性。

2.尽可能减少调用的深度
调用深度过深会使得系统难以跟踪和理解。减少调用深度有助于简化系统结构,使其更加清晰,也便于调试和维护。

3.多扇入,少扇出
扇入是指多个模块调用一个模块,扇出是指一个模块调用多个模块。多扇入说明模块被广泛使用,增强了模块的重用性少扇出有助于减少模块间的依赖,使系统结构更稳定。

4.单入口,多出口
这原则指的是模块的调用应该有一个明确的入口点,但可以有多个出口点。这有助于提高模块的可控性和可预测性。

5.模块的作用域应该在模块之内
模块应该是自包含的,它的内部实现应该对外部隐藏。这有助于降低模块间的耦合度,增强系统的模块化。

6.功能应该是可预测的
模块的行为应该是可预测的,不应该有意外的副作用。这有助于提高系统的可靠性和可维护性。

(四) 模块设计原则

模块的作用范围应在控制范围之内
模块的作用范围是指模块内某个判定语句对其他模块的影响范围,而控制范围则是指一个模块能够直接影响或控制的其他模块的集合。

六、系统测试

(一) 系统测试概述

1.系统测试的意义

系统测试是为了发现错误而执行程序的过程成功的测试是发现了至今尚未发现的错误的测试。

2.系统测试的目的

目的:希望能以最少的人力和时间发现潜在的各种错误和缺陷
用户应根据开发各阶段的需求、设计等文档或程序的内部结构精心设计测试实例,并利用这些实例来运行程序,以便发现错误的过程。

信息系统测试应包括软件测试、硬件测试和网络测试。
硬件测试、网络测试可以根据具体的性能指标进行,此处所说的测试更多的是指软件测试。

系统测试是保证系统质量和可靠性关键步骤,是对系统开发过程中的系统分析、系统设计和实施的最后复查。

3.系统测试的原则

根据测试的概念和目的,在进行信息系统测试时应遵循以下基本原则:

1)应尽早并不断地进行测试。
测试不是在应用系统开发完之后才进行的。由于原始问题的复杂性、开发各阶段的多样性以及参加人员之间的协调等因素,使得在开发的各个阶段都有可能出现错误。因此,测试应贯穿在开发的各个阶段,应尽早纠正错误,消除隐患。

2)测试工作应该避免由原开发软件的人或小组承担。
一方面,开发人员往往不愿否认自己的工作,总认为自己开发的软件没有错误:另一方面,开发人员的错误很难由本人测试出来很容易根据自己编程的思路来制定测试思路,具有局限性。测试工作应由专门人员来进行,这样会更客观、更有效。

3)在设计测试方案时,不仅要确定输入数据,而且要根据系统功能确定预期输出结果将实际输出结果与预期结果相比较就能发现测试对象是否正确。

4)在设计测试用例时,不仅要设计有效、合理的输入条件,也要包含不合理、失效的输入条件。 在测试的时候,人们往往习惯按照合理的、正常的情况进行测试,而忽略了对异常、不合理、意想不到的情况进行测试,而这可能就是隐患。

5)在测试程序时,不仅要检验程序是否做了该做的事,还要检验程序是否做了不该做的事。 多余的工作会带来副作用,影响程序的效率,有时会带来潜在的危害或错误。

6)严格按照测试计划来进行,避免测试的随意性。
测试计划应包括测试内容、进度安排、人员安排、测试环境、测试工具和测试资料等。严格地按照测试计划可以保证进度,使各方面都得以协调进行。

7)妥善保存测试计划、测试用例,作为软件文档的组成部分,为维护提供方便。

8)测试例子都是精心设计出来的,可以为重新测试或追加测试提供方便。
当纠正错误系统功能扩充后,都需要重新开始测试,而这些工作的重复性很高,可以利用以前的测试用例或在其基础上修改,然后进行测试。

9)系统测试阶段的测试目标来自于需求分析阶段

(二) 传统软件的测试策略

有效的软件测试分为4步:单元测试、集成测试、确认测试、系统测试。

1.单元测试(模块测试)

单元测试也称为模块测试,在模块编写完成且无编译错误后就可以进行。

单元测试侧重模块中的内部处理逻辑和数据结构。如果选用机器测试,般用白盒测试法。这类测试可以对多个模块同时进行。

(1) 单元测试的测试内容

单元测试的主要检测模块的以下5个特征:

① 模块的接口

模块的接口保证了测试模块的数据流可以正确地流入、流出。
在测试中应检查以下要点:
①测试模块的输入参数和形式参数在个数、属性、单位上是否一致。
②调用其他模块时,所给出的实际参数和被调用模块的形式参数在个数、属性、单位上是否一致。
③调用标准函数时,所用的参数在属性、数目和顺序上是否正确
④全局变量在各模块中的定义和用法是否一致。
⑤输入是否仅改变了形式参数。
⑥开/关的语句是否正确。
⑦规定的 IO 格式是否与输入/输出语句一致。
⑧在使用文件之前是否已经打开文件或使用文件之后是否已经关闭文件。

② 局部数据结构

在单元测试中,局部数据结构出错是比较常见的错误,在测试时应重点考虑以下因素。
①变量的说明是否合适
②是否使用了尚未赋值或尚未初始化的变量。
③变量的初始值或默认值是否正确。
④变量名是否有错(例如拼写错)

③ 重要的执行路径

④ 出错处理

⑤ 边界条件

(2) 单元测试的过程

由于模块不是独立运行的程序,各模块之间存在调用与被调用的关系。在对每个模块进行测试时,需要开发两种模块。单元测试环境如图所示。
在这里插入图片描述

① 驱动模块

相当于一个主程序,接收测试例子的数据,将这些数据送到测试模块,输出测试结果。

② 桩模块(存根模块)

桩模块用来代替测试模块中所调用的子模块,其内部可进行少量的数据处理,目的是为了检验入口,输出调用和返回的信息

提高模块的内聚度可以简化单元测试。如果每个模块只完成一种功能,对于具体模块来讲。所需的测试方案数据会显著减少,而且更容易发现和预测模块中的错误。
高内聚、低耦合

2.集成测试

集成测试就是把模块系统设计说明书的要求组合起来进行测试。

即使所有的模块都通过了测试,在集成之后,仍然可能出现问题。

通常,集成测试有两种方法:非增量集成和增量集成。

(1) 非增量集成

分别测试各个模块,再把这些模块组合起来进行整体测试。
非增量式集成可以对模块进行并行测试,能充分利用人力,并加快工程进度。但这种方法容易混乱,出现错误不容易查找和定位。

(2) 增量集成

即以小增量的方式逐步进行构造和测试。
增量式测试的范围一步步扩大,错误容易定位,更易于对接口进行彻底测试,并且可以运用系统化的测试方法。下面讨论一些增量集成策略:

1)自顶向下集成测试

自顶向下集成测试是一种构造软件体系结构的增量方法。模块的集成顺序为从主控模块(主程序)开始,沿着控制层次逐步向下,以深度优先或广度优先的方式将从属于(或间接从属于)主控模块的模块集成到结构中。
不用编写驱动模块,需要编写桩模块。
在这里插入图片描述

实现自顶向下测试方法(广度优先)
总结特点:从上到下(分层),从左到右(排序)
这句话可以这样理解先从整体上从上到下排列
第一层有:M1
第二层有:M3,M4,M2
第三层有:M6,M5
第四层有:M7
然后再从每层进行细分,从左到右排列
第一层排序后:M1
第二层排序后:M2,M3,M4
第三层排序后:M5,M6
第四层排序后:M7
整合起来,自顶向下测试方法(广度优先):M1,M2,M3,M4,M5,M6,M7

实现自顶向下测试方法(深度优先)
总结特点:从左到右(分支),从上到下(排序)
这句话可以这样理解,整体分支上是从左到右排序
(从左到右)
一分支:M1 - M2分支
二分支:M1 - M3 - M5分支
三分支:M1 - M3 - M6 - M7分支
四分支:M1 - M4分支
各分支具体编号从上到下排序
一分支排序后:M1,M2
二分支排序后:M1,M3,M5
三分支排序后:M1,M3,M6,M7
四分支排序后:M1,M4
整合起来,第一分支M1,M2,第二分支(M1在第一分支上已有)M3,M5,
第三分支(跟前面同理,M3之前分支已有)M6,M7,,第四分支(同理)M4
最终排序结果:M1,M2,M3,M5,M6,M7,M4

集成过程可以通过下列5个步骤完成:
(1)主控模块用作测试驱动模块,用从属于主控模块的所有模块代替桩模块。
(2)依靠所选择的集成方法(深度优先、广度优先),每次用实际模块替换一个桩模块。
(3)在集成每个模块后都进行测试。
(4)在完成每个测试集之后,用实际模块替换另一个桩模块。
(5)可以执行回归测试,以确保没有引入新的错误。

2)自底向上集成测试

自底向上集成测试就是从原子模块(程序结构的最底层构件,桩模块)开始进行构造和测试。由于构件是自底向上集成的,在处理时所需要的从属于给定层次的模块总是存在的,因此,没有必要使用桩模块。
不需要编写桩模块,需要编写驱动模块
在这里插入图片描述

连接相应的构件形成簇 1、簇2和簇 3,利用驱动模块(图中的虚线框)对每个进行测试。簇1和簇2中的构件从属于模块 Ma,去掉驱动模块D1和 D2,将这两个簇直接与 M1相连。与之相类似,在簇3与 Mb,连接之前去掉驱动模块 D3,最后将 Ma和Mb与构件 Mc连接在一起。

在这里插入图片描述
第一步,依次从左到右,d1,d2,d3,d4,d5,d6称为桩模块
在这里插入图片描述
第二步,整合在一起
在这里插入图片描述

自底向上集成策略可以利用以下步骤来实现:
(1)连接低层构件以构成完成特定子功能的簇。
(2)编写驱动模块(测试的控制程序)以协调测试用例的输入和输出。
(3)测试簇。
(4)去掉驱动程序,沿着程序结构向上逐步连接簇。遵循这种模式的集成。

3.回归测试

每当加入一个新模块作为集成测试的一部分时,软件发生变更,建立了新的数据流路径,可能出现新的IO,以及调用新的控制逻辑。这些变更可能会使原来可以正常工作的功能产生问题。改正当前故障的同时有可能会引进新的故障。

在集成测试策略的环境下,回归测试是重新执行已测试过的某些子集,以确保变更没有传播不期望的副作用。

回归测试有助于保证变更不引入无意识行为或额外的错误。回归测试可以手工进行,方法是重新执行所有测试用例的子集,或者利用捕捉/回放工具自动执行。捕捉/回放工具使软件工程师能够为后续的回放与比较捕捉测试用例和测试结果。

回归测试要执行的测试子集包含以下3 种测试用例:
能够测试软件所有功能的具有代表性的测试样本。
额外测试,侧重于可能会受变更影响的软件功能。
侧重于已发生变更的软件构件测试。

随着集成测试的进行,回归测试的数量可能变得相当庞大,因此,应将回归测试用例设计成只包括设计每个主要程序功能的一个或多个错误类的测试。一旦发生变更,对每个软件功能重新执行所有的测试是不切实际的,而且效率很低。

4.冒烟测试

当开发软件产品时,冒烟测试是一种常用的集成测试方法,是时间关键项目的决定性机制,它让软件团队频繁地对项目进行评估。

(三) 测试方法

在软件测试过程中,应该为定义软件测试模板,即将特定的测试方法和测试用例设计放在一系列的测试步骤中。

软件测试方法分为:静态测试和动态测试。

1.静态测试

静态测试是指被测试程序不在机器上运行,而是采用人工检测和计算机辅助静态分析的手段对程序进行检测。

1) 人工检测

人工检测不依靠计算机而是依靠人工审查程序或评审软件,包括代码检查静态结构分析和代码质量度量等。

2) 计算机辅助静态分析

利用静态分析工具对被测试程序进行特性分析,从程序中提取一些信息,以便检查程序逻辑的各种缺陷和可疑的程序构造。

2.动态测试

动态测试是指通过运行程序发现错误。在对软件产品进行动态测试时可以采用黑盒测试法和白盒测试法

测试用例由测试输入数据和与之对应的预期输出结果组成。在设计测试用例时,应当包括合理的输入条件和不合理的输入条件。

黑盒测试(功能测试)

完全不考虑软件的内部结构和特性的情况下,测试软件的外部特性

进行黑盒测试主要是为了发现以下几类错误:
(1) 是否有错误的功能或遗漏的功能?
(2) 界面是否有误?输入是否正确接收?输出是否正确?
(3) 是否有数据结构或外部数据库访问错误?
(4) 性能是否能够接受?
(5) 是否有初始化或终止性错误?

黑盒测试技术

常用的黑盒测试技术有:
等价类划分、边界值分析、错误推测和因果图等。

(1) 等价类划分

等价类划分法将程序的输入域划分为若干等价类,然后从每个等价类中选取一个代表性数据作为测试用例。每一类的代表性数据在测试中的作用等价于这一类中的其他值,这样就可以用少量代表性的测试用例取得较好的测试效果。

等价类划分有两种不同的情况:有效等价类和无效等价类。在设计测试用例时,要同时考虑这两种等价类。

示例:要求x在0~100之内
x<0,x>100:无效等价类
0<= x <= 100,有效等价类

考等价类划分的测试用例是否正确时,2项或者超过2项的用例是错误的。

(2) 边界值分析

输入的边界比中间更加容易发生错误,因此用边界值分析来补充等价类划分的测试用例设计技术。

边界值划分选择等价类边界的测试用例,既注重于输入条件边界,又适用于输出域测试用例

(3) 错误推测

错误推测是基于经验和直觉推测程序中所有可能存在的各种错误,从而有针对性地设计测试用例的方法。其基本思想是列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据它们选择测试用例。

(4) 因果图

因果图法是从自然语言描述的程序规格说明中找出因(输入条件)和果(输出或程序状态的改变),通过因果图转换为判定表。

白盒测试(结构测试)

1) McCabe度量法

软件复杂度
软件复杂度是指理解和处理软件的难易程度。
程序复杂度是软件度量的重要组成部分。
度量方法: McCabe 度量法(环路度量)

(1)McCabe度量法的定义

McCabe 度量法是通过定义环路复杂度,建立程序复杂性的度量。用于评估程序的控制结构复杂性
它基于一个程序模块的程序图中环路的个数。计算有向图G的环路复杂性的公式为:V(G) = m - n + 2 = 闭合区域 + 1
其中V(G)是有向图 G 中的环路个数,m 是 G 中的有向弧数,n 是 G 中的节点数。
在这里插入图片描述

2)白盒测试的定义

根据程序的内部结构和逻辑来设计测试用例,对程序的路径和过程进行测试,检查是否满足设计的需要。

白盒测试常用的技术是:逻辑覆盖、循环覆盖和基本路径测试

(1) 逻辑测试

逻辑覆盖考察用测试数据运行被测程序时对程序逻辑的覆盖程度
在这里插入图片描述

① 语句覆盖

语句覆盖是指选择足够的测试数据,使被测试程序中的每条语句至少执行1次。语句覆盖对程序执行逻辑的覆盖很低,因此一般认为它是很弱的逻辑覆盖。
在这里插入图片描述
输入: x=4 , y=2 , z=0
执行路径为:sacbed

语句覆盖虽然可以测试执行语句是否被执行到,但却无法测试程序中存在的逻辑错误

例如,如果上述程序中的第一个逻辑判断符号 “&&” 误写了 “||” ,使用测试用例同样可以覆盖 sacbed 路径上的全部执行语句,但却无法发现错误。同样,如果第二个逻辑判断符号 “||” 误写了 “&&” ,使用同样的测试用例也可以执行 sacbed 路径上的全部执行语句,但却无法发现上述逻辑错误。

语句覆盖的目的:
语句覆盖的目的是测试程序中的代码是否被执行,它只测试代码中的执行语句,这里的执行语句不包括头文件、注释、空行等。

语句覆盖在多分支的程序中,只能覆盖某一条路径,使得该路径中的每一个语句至少被执行一次,但不会考虑各种分支组合情况。

② 判定覆盖(分支覆盖)

判定覆盖是指设计足够的测试用例,使得被测程序中的每个判定表达式至少获得一次“真”值和“假”值,或者说是程序中的每一个取“真”分支和取“假”分支至少都通过一次,因此判定覆盖也称为分支覆盖。

判定覆盖要比语句覆盖更强一些。
在这里插入图片描述
以上述代码为例,构造以下测试用例即可实现判定覆盖标准:

输入:① x=1,y=3,z=0 ,执行路径为 sacbd
(判断的结果分别为T,F)
输入:② x=3,y=1,z=1 ,执行路径为 sabed
(判断的结果分别为F,T)

上述两组测试用例不仅满足了判定覆盖,而且满足了语句覆盖,从这一点可以看出判定覆盖比语句覆盖更强一些。所以只要满足了判定覆盖就一定满足语句覆盖,反之则不然。

判定覆盖仍然具有和语句覆盖一样无法发现逻辑判断符号 “&&” 误写了 “||” 的逻辑错误。

判定覆盖仅仅判断判定语句执行的最终结果而忽略每个条件的取值,所以也属于弱覆盖。

③ 条件覆盖

条件覆盖指的是设计足够的测试用例,使判定语句中的每个逻辑条件取真值与取假值至少出现一次。

例如,对于判定语句 if(a>1 OR c<0) 中存在 a>1、c<0 两个逻辑条件,设计条件覆盖测试用例时,要保证 a>1、c<0 的“真”、“假”值至少出现一次。

在这里插入图片描述
要使程序中每个判断的每个条件都至少取真值、假值一次,测试用例:

输入:① x=1,y=2,z=0 ,执行路径为 sacbed
(条件的结果分别为T T T F)
y>1 T;z=0 T; y=2 T;x=1 F;

输入:② x=2,y=1,z=1 ,执行路径为 sabed
(条件的结果分别为F F F T)

从条件覆盖的测试用例可知,使用2个测试用例就达到了使每个逻辑条件取真值与取假值都至少出现了一次,但从测试用例的执行路径来看,条件覆盖的状态下仍旧不能满足判定覆盖,即没有覆盖 bd 这条路径。相比于语句覆盖与判定覆盖,条件覆盖达到了逻辑条件的最大覆盖率,但却不能保证判定覆盖

④ 判定-条件覆盖

要求设计足够的测试用例,使得判定语句中所有条件的可能取值至少出现一次,同时,所有判定语句的可能结果也至少出现一次

例如,对于判定语句 if(a>1 AND c<1) ,该判定语句有 a>1、c<1 两个条件,则在设计测试用例时,要保证 a>1、c<1 两个条件取“真”、“假”值至少一次,同时,判定语句 if(a>1 AND c<1) 取“真”、“假”也至少出现一次。

在这里插入图片描述
为满足判定-条件覆盖原则,我们可以构造以下测试用例:

输入:① x=4,y=2,z=0 ,覆盖路径:sacbed
(判断的结果分别为TT,条件的结果分别为:TTTT )

输入:② x=1,y=1,z=1 ,覆盖路径:sabd
(判断的结果分别为FF,条件的结果分别为:FFFF )

判定-条件覆盖满足了判定覆盖准则和条件覆盖准则,弥补了二者的不足。但是判定-条件覆盖不一定比条件覆盖的逻辑更强。

判定-条件覆盖的缺点: 没有考虑条件的组合情况。

⑤ 条件组合覆盖

条件组合指的是设计足够的测试用例,使得每个判定中条件的各种可能组合都至少执行一次。满足了判定覆盖、条件覆盖、判定-条件覆盖准则
在这里插入图片描述
为满足条件组合覆盖原则,我们可以构造以下测试用例:

输入① x=4,y=2,z=0 ,覆盖路径: sacbed (条件的结果分别为:TTTT )
输入 ② x=1,y=2,z=1,覆盖路径: sabed (条件的结果分别为:TFTF )
输入③ x=2,y=1,z=0 ,覆盖路径: sabed (条件的结果分别为:FTFT )
输入 ④ x=1,y=1,z=1,覆盖路径: sabd (条件的结果分别为:FFFF )
由于这4个条件每个条件都有取“真”、“假”两个值,因此所有条件结果的组合有2^4=16种。但是,当一个程序中判定语句较多时,其条件取值的组合数目也较多。需要设计的测试用例也会增加,这样反而会使测试效率降低。

⑥ 路径覆盖

路径覆盖指的是设计足够的测试用例,使得程序中的每一条可能组合的路径都至少执行一次
在这里插入图片描述
为满足路径覆盖原则,我们可以构造以下测试用例:
输入:① x=4,y=2,z=0 ,覆盖路径:sacbed
(判定的结果分别为:TT )

输入:② x=1,y=2,z=1,覆盖路径: sabed
(判定的结果分别为:FT )

输入:③ x=1,y=3,z=0 ,覆盖路径: sacbd
(判定的结果分别为:TF )

输入:④ x=1,y=1,z=1 ,覆盖路径: sabd
(判定的结果分别为:FF )

(2) 循环覆盖

执行足够的测试用例,使得循环中的每个条件都得到验证。
循环的分支,一般真、假都执行。
在这里插入图片描述

(3) 基本路径测试

基本路径测试法是在程序控制流图的基础上,通过分析控制流图的环路复杂性,导出基本可执行路径集合,从而设计测试用例。

(4) 白盒测试的原则

(1)、程序模块中的所有独立路径至少执行一次。
(2)、在所有的逻辑判断中,取“真”和取“假”的两种情况至少都能执行一次。
(3)、每个循环都应在边界条件和一般条件下各执行一次。
(4)、测试程序内部数据结构的有效性等。

3)伪代码+McCabe度量法+白盒测试

(1) 伪代码的程序流程图

选择结构 顺序结构
在这里插入图片描述
if else if
在这里插入图片描述

循环结构
for循环
在这里插入图片描述
在这里插入图片描述
while循环
在这里插入图片描述
do-while循环
在这里插入图片描述

七、软件维护

1.软件维护的概念

软件维护软件生命周期中的最后一个阶段,处于系统投入生产性运行以后的时期中,因此不属于系统开发过程
软件维护是在软件已经交付使用之后为了改正错误或满足新的需求而修改软件的过程,即软件在交付使用后对软件所做的一切改动。

2.系统可维护性的评价指标

1) 可理解性

指别人能理解系统的结构、界面、功能和内部过程的难易程度。
模块化、详细设计文档、结构化设计和良好的高级程序设计语言等都有助于提高可理解性。

2) 可测试性

诊断和测试的容易程度取决于易理解的程度。
好的文档资料有利于诊断和测试,同时,程序的结构、高性能的测试工具以及周密计划的测试工序也是至关重要的。为此,开发人员在系统设计和编程阶段就应尽力把程序设计成易诊断和测试的。此外,在进行系统维护时,应该充分利用在系统测试阶段保存下来的测试用例。

3) 可修改性

诊断和测试的容易程度与系统设计所制定的设计原则有直接关系。
模块的耦合、内聚、作用范围与控制范围的关系等都对可修改性有影响。

3.软件维护和软件文档

文档是软件可维护性的决定因素
软件系统的文档可以分为:用户文档、系统文档
软件维护时期比软件开发周期都要长
可维护性是所有软件都应具有的基本特点,必须在开发阶段保证软件具有可维护的特点。在软件工程的 每一个阶段 都应考虑并提高软件的可维护性,在每个阶段结束前的技术审查和管理复查中应该着重对可维护性进行复审。

4.软件维护的内容

(1) 正确性维护

正确性维护是,指改正系统开发阶段已发生系统测试阶段尚未发现错误

(2) 适应性维护

适应性维护是指使应用软件适应信息技术变化和管理需求变化而进行的修改。

(3) 完善性维护

这是为扩充功能和改善性能而进行的修改,主要是指对已有的软件系统增加一些在系统分析和设计阶段中没有规定的功能与性能特征。
因为 … 修改 … 使得用户得到好的体验

(4) 预防性维护

为了改进应用软件的可靠性和可维护性,为了适应未来的软/硬件环境的变化,应主动增加预防性的新的功能,以使应用系统适应各类变化而不被淘汰。

八、软件的质量属性

可靠性、可用性和可维护性是软件的质量属性,软件工程中用 0-1 之间的数来度量

1.可靠性

可靠性是指一个系统对于给定的时间间隔内、在给定条件下无失效运作的概率。
可以用 MTTF/ (1+MTTF) 来度量,其中 MTTF 为平均无故障时间。
mean time to failure

2.可用性

可用性是在给定的时间点上,一个系统能够按照规格说明正确运作的概率。
可以用MTBF/ (1+MTBF) 来度量,其中 MTBF 为平均失效间隔时间。

3.可维护性

可维护性是在给定的使用条件下,在规定的时间间隔内,使用规定的过程和资源完成维护活动的概率。
可以用 1/ (1+MTTR) 来度量,其中 MTTR 为平均修复时间。
Mean Time To Repair

九、软件工具

用来辅助软件开发、运行、维护、管理和支持等过程中的活动的软件称为软件工具。

1.软件开发工具

对应于软件开发过程的各种活动,软件开发工具通常有:需求分析工具、设计工具、编码与排错工具、测试工具等。

1.软件维护工具

辅助软件维护过程中活动的软件称为软件维护工具,它辅助维护人员对软件代码及其文档进行各种维护活动。软件维护工具主要有:版本控制工具、文档分析工具、开发信息库工具、逆向工程工具和再工程工具、配置管理支持。

逆向工程工具:

逆向工程工具辅助软件人员将某种形式表示的软件(源程序)转换成更高抽象形式表示的软件。这种工具力求恢复源程序的设计信息,使软件变得更容易理解。逆向工程工具分为静态的和动态的两种。

CMM
“CMM,全称为Capability Maturity Model for Software,即“软件能力成熟度模型”,是对组织软件过程的描述,核心内容是将软件开发视为一个过程,并且根据相应的原则对于软件开发进行相应的监控和研究。是一个将软件不断从混乱走向成熟的规范化过程的一个框架。

十、沟通路径

每个人都与其他n-1个人有沟通路径。
沟通路径 = 在这里插入图片描述
有一个主程序员的沟通路径。
沟通路径 = n-1

十一、软件开发项目管理

(一) 成本估算

1.成本估算方法

常见的成本估算方法有自顶向下估算方法、自底向上估算方法、差别估算方法、专家估算方法、类推估算方法、算式估算法等。

2.成本估算模型

常见的成本估算模型有Putnam模型和COCOMO模型。
Putnam模型是一种动态多变量模型,它是假设在软件开发的整个生存期中工作量有特定的分布。
结构性成本模型COCOMO是最精确、最易于使用的成本估算模型之一。COCOMO 模型按其详细程度分为:基本 COCOMO 模型、中级 COCOMO 模型、详细 COCOMO 模型。

3.COCOMO模型的分类

1)基本 COCOMO 模型

基本 COCOMO 模型是一个静态单变量模型,用于对整个软件系统进行估算。

2)中级COCOMO 模型

中级 COCOMO 模型是一个静态多变量模型,它将软件系统模型分为系统和部件两个层次,系统由部件构成,它把软件开发所需的人力(成本)看作是程序大小和一系列“成本驱动属性”的函数。

中级 COCOMO 模型以基本 COCOMO 模型为基础,并考虑了 15 种影响软件工作量的因素,通过工作量调节因子 (EAF) 修正对工作量的估算,从而使估算更合理。

3) 详细 COCOMO 模型

它将软件系统模型分为系统、子系统和模块3 个层次,除包括中级模型所考虑的因素外,还考虑了在需求分析、软件设计等每一步的成本驱动属性的影响。

4.COCOMOII模型

最初的 COCOMO 模型是得到产业界最广泛应用和讨论的软件成本估算模型之一,现在它已经演化成更全面的估算模型,称为 COCOMOII。

和其前身一样,COCOMOII 也是一种层次结构的估算模型,分为 3 个阶段性模型。
(1)应用组装模型;(对象点)
(2) 早期设计阶段模型;(功能点)
(3) 体系结构阶段模型;(代码行)

和所有的软件估算模型一样,COCOMOII 模型也需要使用规模估算信息,在模型层次结构中有3 种不同的规模估算选择:对象点、功能点和代码行。

应用组装模型使用的是对象点;早期设计阶段模型使用的是功能点,功能点可以转换为代码行。

(二) 进度管理

软件开发项目的进度安排有两种方式:系统最终交付日期已经确定,软件开发部门必须在规定期限内完成;系统最终交付日期只确定了大致的年限,最后交付日期由软件开发部门确定。
进度安排的常用图形描述方法有甘特(Gantt)图和计划评审技术(PERT)图。

1.Gantt图

Gantt图是一种简单的水平条形图,它以日历为基准描述项目任务。
水平轴表示日历时间线(如时、天、周、月和年等),每个条形表示一个任务,任务名称垂直地列在左边的列中,图中水平条的起点和终点对应水平轴上的时间,分别表示该任务的开始时间和结束时间,水平条的长度表示完成该任务所持续的时间。当日历中同一时段存在多个水平条时,表示任务之间的并发。
在这里插入图片描述

Gantt 图描述了3 个任务的进度安排:任务 1首先开始,完成它需要 6 个月时间;任务2在1个月后开始,完成它需要 9 个月时间;任务3 在6个月后开始,完成它需要5个月时间。

Gantt图能清晰地描述每个任务从何时开始,到何时结束,任务的进展情况以及各个任务之间的并行性

但是它不能清晰地反映出各任务之间的依赖关系,难以确定整个项目的关键所在,也不能反映计划中有潜力的部分。

2.PERT图

PERT图是一个有向图,用箭头表示任务,它可以表示完成该任务所需的时间
箭头指向节点表示流入节点的任务的结束,并开始流出节点的任务,这里把节点当成事件。只有当流入该节点的所有任务都结束时,节点所表示的事件才出现,流出节点的任务才可以开始。
事件本身不消耗时间和资源,它仅表示某个时间点。
在这里插入图片描述
一个事件有一个事件号和出现该事件的最早时刻和最迟时刻。
最早时刻:表示在此时刻之前从该事件出发的任务不可能开始;
最迟时刻:表示从该事件出发的任务,最迟必须在此时刻之前开始,否则整个工程就不能如期完成。
每个任务还可以有个松驰时间 (Slack Time),表示在不影响整个工期的前提下完成该任务有多少机动余地。

最早时刻

单个流入的节点,最早开始时间 = 前一个节点的最早开始时间 + 任务时间;
多个流入的节点,最早开始时间 = MAX(前一个节点的最早开始时间 + 任务时间);
注意:
开始节点的最早时刻 = 0
在这里插入图片描述

最晚时刻

单个流出节点的最迟时刻 = 后一个节点的最迟时刻 - 任务时间;
多个流出节点的最迟时刻 = MIN(后一个节点的最迟时刻 - 任务时间);
注意:
结束节点的最迟时刻 = 结束节点的最早时刻
在这里插入图片描述

松弛时间

松弛时间 = 节点的最迟时刻 - 节点的最早时刻

关键路径

松弛时间为0的路径
在这里插入图片描述
PERT 图不仅给出了每个任务的开始时间、结束时间和完成该任务所需的时间,还给出了任务之间的关系,即哪些任务完成后才能开始另外一些任务,以及如期完成整个工程的关键路径。

松弛时间反映了完成某些任务时可以推迟其开始时间延长其所需完成的时间

但是,PERT 图不能反映任务之间的并行关系
PERT 图可以表示出依赖关系

3.项目活动图

事件最早发生时间 ve(k)
ve(源点) = 0
ve(k) = max{ve(j) + cost(j, k)}

事件最迟发生时间 vl(k)
vl(汇点) = ve(汇点)
vl(k) = min{vl(j) - cost(k, j)}

活动 ai 的最早开始时间 e(i)
活动为(k, j),则 e(i) = ve(k)

活动 ai 的最迟开始时间 l(i)
活动为(k, j),则 l(i) = vl(j) - cost(k, j)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1.关键路径可能多条
2.关键路径的长度(结束顶点的开始时刻)
3.某个顶点/活动是否在关键路径上、
4.松弛时间(关键路径上的活动,松弛时间 = 0)。
5.缩短关键路径上的时间才能缩短整个项目的时间

(三) 软件配置管理

1.配置数据库

配置数据库可以分为以下三类:
(1) 开发库
专供开发人员使用,其中的信息可能做频繁修改,对其控制相当宽松
(2) 受控库(软件配置库)
在生存期某一阶段工作结束时发布的阶段产品,这些是与软件开发工作相关的计算机可读信息和人工可读信息。软件配置管理正是对受控库中的各个软件项进行管理,受控库也称为软件配置库。
(3) 产品库
在开发的软件产品完成系统测试后,作为最终产品存入产品库,等待交付用户或现场安装。

2.软件配置管理

软件配置管理目标

软件配置管理其主要目标包括:变更标识、变更控制、版本控制、确保变更正确的实现、变更报告;

软件配置管理内容

软件配置管理其主要内容包括:版本管理、配置支持、变更支持、过程支持、团队支持、变化报告、审计支持。

上下为两个不同的版本

软件配置管理其主要内容包括:软件配置标识、变更管理、版本控制、系统建立、配置审核、配置状态报告。

(四) 风险管理

一般认为软件风险包含两个特性:不确定性、损失
不确定性是指:风险可能发生也可能不发生;
损失是指:如果风险发生,就会产生恶性后果。

1.风险分类

在进行风险分析时,重要的是量化每个风险的不确定程度和损失程度。为了实现这一点,必须考虑不同类型的风险。

1) 项目风险

项目风险威胁到项目计划。也就是说,如果项目风险发生,就有可能拖延项目的进度增加项目的成本。项目风险是指预算、进度、人员(聘用职员及组织)、资源、利益相关者、需求等方面的潜在问题以及它们对软件项目的影响。项目复杂度、规模及结构不确定性也属于项目风险因素。

2) 技术风险

技术风险威胁到要开发软件的质量及交付时间。如果技术风险发生,开发工作就可能变得很困难或根本不可能。技术风险是指设计、实现、接口、验证和维护等方面的潜在问题。此外,规格说明的歧义性、技术的不确定性、技术陈旧以及“前沿”技术也是技术风险因素。技术风险的发生是因为问题比我们所设想的更加难以解决。

3) 商业风险

商业风险威胁到要开发软件的生存能力,且常常会危害到项目或产品。

2.风险识别

风险识别,试图系统化地指出对项目计划(估算、进度、资源分配等)的威胁。识别出已知风险和可预测风险后,项目管理者首先要做的是在可能时回避这些风险,在必要时控制这些风险。

识别风险的一种方法是建立风险条目检查表。该检查表可用于风险识别,并且主要用来识别下列几种类型中的一些已知风险和可预测风险:

(1)产品规模。与要开发或要修改的软件的总体规模相关的风险。
(2)商业影响。与管理者或市场所施加的约束相关的风险。
(3)客户特性。与客户的素质以及开发者和客户定期沟通的能力相关的风险
(4)过程定义。与软件过程定义的程度以及该过程被开发组织遵守的程度相关的风险。
(5)开发环境。与用来开发产品的工具的可得性及质量相关的风险。
(6)开发技术。与待开发软件的复杂性及系统所包含技术的“新奇性”相关的风险。
(7)人员才干及经验。与软件工程师的总体技术水平及项目经验相关的风险。

风险条目检查表可以采用不同的方式来组织。与上述每个主题相关的问题可以针对每一个软件项目来回答。根据这些问题的答案,项目管理者就可以估计风险产生的影响。

当然,也可以采用另一种风险条目检查表格式,即仅仅列出与每一种类型有关的特性,最终给出一组风险因素和驱动因子以及它们发生的概率。风险因素包括性能、成本、支持和进度

风险因素是以如下方式定义的:
(1)性能风险。产品能够满足需求且符合其使用目的的不确定程度。
(2)成本风险。能够维持项目预算的不确定程度。
(3)支持风险。开发出的软件易于纠错、修改及升级的不确定程度
(4)进度风险。能够维持项目进度且按时交付产品的不确定程度。

有些风险可以避免,有些风险不可以避免。

3.风险预测(风险估计)

风险预测又称风险估计,它试图从两个方面评估一个风险:风险发生的可能性或概率;如果风险发生了所产生的后果。

1) 风险预测活动

通常,项目计划人员与管理人员、技术人员一起进行以下4步风险预测活动。
(1)建立一个尺度或标准,以反映风险发生的可能性。
(2)描述风险产生的后果。
(3)估算风险对项目和产品的影响。
(4)标注风险预测的整体精确度,以免产生误解。

一种简单的风险预测技术是建立风险表。风险表的第1列列出所有的风险(由风险识别活动得到),第 2~4列列出每个风险的种类、发生的概率以及所产生的影响。风险所产生的影响可用一个数字来表示:“1”表示灾难性的:“2”表示严重的:“3”表示轻微的:“4”表示可忽略的。

2)评估风险的影响

如果风险真的发生,有3个因素可能会影响风险所产生的后果:风险的本质、范围和时间

风险的本质,是指当风险发生时可能带来的问题。例如,一个定义很差的与客户硬件的外部接口(技术风险)会妨碍早期的设计和测试,也有可能导致项目后期阶段的系统集成问题。

风险的范围,包括风险的严重性(即风险有多严重)及风险的整体分布情况(即项目中有多少部分受到影响或有多少客户受到损害)。

风险的时间,是指何时能够感受到风险的影响及风险的影响会持续多长时间。在大多数情况下,项目管理者希望“坏消息”越早出现越好,但在某些情况下则是越迟越好。

3) 风险优先级

整体的风险显露度(Risk Exposure,RE)可由下面的关系确定:(风险优先级)
RE = P*C
其中,P是风险发生的概率,C是风险发生时带来的项目成本(后果)。

4.风险评估

在进行风险评估时,建立了如下形式的三元组:
在这里插入图片描述
其中,ri表示风险,li表示风险发生的概率,xi表示风险产生的影响。

一种对风险评估很有用的技术就是定义风险参照水准。对于大多数软件项目来说,成本、进度和性能就是3种典型的风险参照水准。

也就是说,对于成本超支、进度延期、性能降低(或它们的某种组合),有一个表明导致项目终止的水准。

在风险评估过程中,需要执行以下4个步骤:
(1) 定义项目的风险参考水平值。
(2) 建立每一组(ri, li, xi)与每一个参考水平值之间的关系。
(3) 预测一组临界点以定义项目终止区域,该区域由一条曲线或不确定区域所界定。
(4) 预测什么样的风险组合会影响参考水平值。

5.风险控制

风险控制的目的是辅助项目组建立处理风险的策略。一个有效的策略必须考虑以下3个问题:风险避免\风险监控\RMMM计划

1)风险避免

应对风险的最好办法是主动地避免风险,即在风险发生前分析引起风险的原因,然后采取措施,以避免风险的发生。

例如:项目风险ri“表示“频繁的人员流动”,根据历史经验可知,该风险发生的概率大约为 70%,该风险产生的影响xi是第2级(严重的)。为了避免该风险,可以采取以下策略:

(1)与现有人员一起探讨人员流动原因(如恶劣的工作条件、低报酬、竞争激烈的劳动力市场等)。
(2)在项目开始之前采取行动,设法缓解那些能够控制的起因。
(3)项目启动之后,假设会发生人员流动,当有人员离开时,找到能够保证工作连续性的方法。
(4)组织项目团队,使得每一个开发活动的信息都能被广泛传播和交流。
(5)制定工作产品标准,并建立相应机制以确保能够及时创建所有的模型和文档。
(6)同等对待所有工作的评审。
(7)给每一个关键的技术人员都指定一个后备人员。

2) 风险监控

项目管理者应监控某些因素,这些因素可以提供风险是否正在变高或变低的指示。在频繁的人员流动的例子中,应该监测团队成员对项目压力的普遍态度、团队的凝聚力、团队成员彼此之间的关系、与报酬和利益相关的潜在问题、在公司内及公司外工作的可能性。

3) RMMM计划

风险管理策略可以包含在软件项目计划中,或者风险管理步骤也可以组织成一个独立的风险缓解、监控和管理计划(RMMM 计划)。RMMM计划将所有风险分析工作文档化,并由项目管理者作为整个项目计划中的一部分来使用。

建立了 RMMM 计划,而且项目己经启动之后,风险缓解及监测步骤也就开始了。风险缓解是一种问题规避活动,而风险监测是一种项目跟踪活动,这种监测活动有3个主要目的:

评估所预测的风险是否真的发生了;
保证正确地实施了各风险的缓解步骤;
收集能够用于今后风险缝隙的信息。
在很多情况下,项目中发生的问题可以追溯到不止一个风险,所以风险监测的另一个任务就是试图找到“起源”(在整个项目中是哪些风险引起了哪些问题)。

十二、 软件质量

1.软件质量

软件质量是指反映软件系统或软件产品满足规定或隐含需求的能力的特征和特性全体。软件质量管理是指对软件开发过程进行独立的检查活动,由质量保证、质量规划和质量控制3个主要活动构成。软件质量保证是指为保证软件系统或软件产品充分满足用户要求的质量而进行的有计划、有组织的活动,其目的是生产高质量的软件

1) 软件质量特性

讨论软件质量首先要了解软件的质量特性,目前已经有多种软件质量模型来描述软件质量特性,例如 ISO/IEC 9126 软件质量模型和 Mc Call 软件质量模型

(1) ISO/EC 9126 软件质量模型

ISO/EC 9126 软件质量模型由3个层次组成:第一层是质量特性,第二层是质量子特性,第三层是度量指标。该模型的质量特性和质量子特性如图5-15所示。
在这里插入图片描述
其中,各质量特性和质量子特性的含义如下。

(1) 功能性(Functionality)。
与一组功能及其指定的性质的存在有关的一组属性,功能是指满足规定或隐含需求的那些功能。

适应性(Suitability)。与对规定任务能否提供一组功能以及这组功能是否适合有关的软件属性。
准确性(Accurateness)。与能够得到正确或相符的结果或效果有关的软件属性。
互用性(Interoperability)。与其他指定系统进行交互操作的能力相关的软件属性。
依从性(Compliance)。使软件服从有关的标准、约定、法规及类似规定的软件属性。
安全性(Security)。与避免对程序及数据的非授权故意或意外访问的能力有关的软件属性。

(2) 可靠性(Reliability)。
与在规定的一段时间内和规定的条件下软件维持在其性能水平有关的能力。

成熟性(Matuity)。与由软件故障引起失效的频度有关的软件属性。
容错性(Fault tolerance)。与在软件错误或违反指定接口的情况下维持指定的性能水平的能力有关的软件属性。
易恢复性(Recoverability)。与在故障发生后,重新建立其性能水平并恢复直接受影响数据的能力,以及为达到此目的所需的时间和努力有关的软件属性。

(3) 易使用性(Usability)。
与为使用所需的努力和由一组规定或隐含的用户对这样使用所做的个别评价有关的一组属性。

易理解性(Understandability)。与用户为理解逻辑概念及其应用所付出的劳动有关的软件属性。
易学性(Learnability)。与用户为学习其应用(例如操作控制、输入、输出)所付出的努力相关的软件属性。
易操作性(Operability)。与用户为进行操作和操作控制所付出的努力有关的软件属性。

(4) 效率(Efciency)。
在规定条件下,与软件的性能水平与所用资源量之间的关系有关的软件属性。

时间特性(Time behavior)。与响应和处理时间以及软件执行其功能时的吞吐量有关的软件属性。
资源特性(Resource behavior)。与软件执行其功能时,所使用的资源量以及使用资源的持续时间有关的软件属性。

5) 可维护性(Maintainability)。
与进行规定的修改所需要的努力有关的一组属性。

易分析性(Analyzability)。与为诊断缺陷或失效原因,或为判定待修改的部分所需努力有关的软件属性。
易改变性(Changeability)。与进行修改、排错或适应环境变换所需努力有关的软件属性。
稳定性(Stability)。与修改造成未预料效果的风险有关的软件属性。
易测试性(Testability)。为确认经修改软件所需努力有关的软件属性。

6)可移植性(Portability)。
与软件可从某一环境转移到另一环境的能力有关的一组属性。

适应性(Adaptability)。与软件转移到不同环境时的处理或手段有关的软件属性。
易安装性(Imstallability)。与在指定环境下安装软件所需努力有关的软件属性。
一致性(Conformance)。使软件服从与可移植性有关的标准或约定的软件属性。
易替换性(Replaceability)。与一软件在该软件环境中用来替代指定的其他软件的可能和努力有关的软件属性。

(2) Mc Call 软件质量模型

Mc Call 软件质量模型从软件产品的运行、修正和转移3个方面确定了 11 个质量特性:
在这里插入图片描述
Mc Call 也给出了一个三层模型框架,第一层是质量特性,第二层是评价准则,第三层是度量指标。

十三、软件评审

通常,把“质量”理解为“用户满意程度”。为了使得用户满意,有以下两个必要条件:
(1) 设计的规格说明书符合用户的要求,这称为设计质量
(2) 程序按照设计规格说明所规定的情况正确执行,这称为程序质量

1. 设计质量的评审内容

设计质量评审的对象是在需求分析阶段产生的软件需求规格说明、数据需求规格说明,以及在软件概要设计阶段产生的软件概要设计说明书等。通常从以下几个方面进行评审。
(1) 评价软件的规格说明是否合乎用户的要求,即总体设计思想和设计方针是否明确;需求规格说明是否得到了用户或单位上级机关的批准;需求规格说明与软件的概要设计规格说明是否一致等。

(2) 评审可靠性,即是否能避免输入异常(错误或超载等)、硬件失效及软件失效所产生的失效,一旦发生应能及时采取代替手段或恢复手段。

(3) 评审保密措施实现情况,即是否对系统使用资格进行检查;

(4) 评审操作特性实施情况,即操作命令和操作信息的恰当性;输入数据与输入控制语句的恰当性;输出数据的恰当性;应答时间的恰当性等。

(5) 评审性能实现情况,即是否达到所规定性能的目标值。

(6) 评审软件是否具有可修改性、可扩充性、可互换性和可移植性。

(7) 评审软件是否具有可测试性;

(8) 评审软件是否具有复用性。

2.程序质量的评审内容

程序质量评审通常是从开发者的角度进行评审,与开发技术直接相关。它是着眼于软件本身的结构、与运行环境的接口以及变更带来的影响而进行的评审活动。

软件的结构如下:
(4)模块结构。
模块层次结构是模块的静态结构,现在要检查块的动态结构。模块分为处理模块和数据模块两类,模块间的动态结构也与这些模块分类有关。对这样的模块结构进行检查的项目如下:
控制流结构;
数据流结构;
功能结构与控制流结构的对应关系;

3.与运行环境的接口

运行环境包括硬件、其他软件和用户,主要的检查项目如下
(1) 与硬件的接口。
(2) 与用户的接口。

进行正式的技术评审。一旦形成了规格说明和设计,就要对它们进行质量评估。完成质量评估的中心活动是正式的技术评审。正式的技术评审是一种由技术人员实施的程式化会议,其唯一的目的是揭露质量问题。在多数情况下,评审能像测试一样有效地揭露软件中的缺陷。

十四、软件容错技术

提高软件质量和可靠性的技术大致可分为两类,一类是避开错误,即在开发的过程中不让差错潜入软件的技术;另一类是容错技术,即对某些无法避开的差错,使其影响减至最小的技术。

1.容错软件的定义

归纳容错软件的定义,有以下4种:
(1)规定功能的软件,在一定程度上对自身错误的作用(软件错误)具有屏蔽能力,则称该软件为具有容错功能的软件,即容错软件

(2)规定功能的软件,在一定程度上能从错误状态自动恢复到正常状态,则称该软件为容错软件。

(3)规定功能的软件,在因错误发生错误时仍然能在一定程度上完成预期的功能,则称该软件为容错软件。

(4)规定功能的软件,在一定程度上具有容错能力,则称该软件为容错软件。

2.容错的一般方法

实现容错的主要手段是冗余。冗余是指对于实现系统规定功能是多余的那部分资源,包括硬件、软件、信息和时间。由于加入了这些资源,有可能使系统的可靠性得到较大的提高。通常,冗余技术分为4类:
结构冗余;
信息冗余;
时间冗余;
冗余附加技术

冗余技术

(1)结构冗余。

结构冗余是通常采用的冗余技术,按其工作方法可以分为静态、动态和混合几余3种。

(2)信息几余。

为检测或纠正信息在运算或传输中的错误需外加一部分信息,这种现象称为信息冗余。

(3)时间冗余。

时间几余是指以重复执行指令或程序来消除瞬时错误带来的影响。

(4)冗余附加技术。

冗余附加技术是指为实现上述冗余技术所需的资源和技术,包括程序、指令、数据、存放和调动它们的空间和通道等。

3.屏蔽硬件错误的容错技术

在屏蔽硬件错误的容错技术中,冗余附加技术包括:
①关键程序和数据的冗余存储及调用。
②检测、表决、切换、重构、纠错和复算的实现。

4.屏蔽软件错误的容错系统

在屏蔽软件错误的容错系统中,冗余附加技术的构成包括:
①冗余备份程序的存储及调用。
②实现错误检测和错误恢复的程序。
③实现容错软件所需的固化程序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-C`ESTVRAI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值