五、软件工程基础知识

1 软件工程概述

软件工程的起源与发展

  • 软件危机:早期软件开发面临成本超支、进度延迟、质量不保证等问题。
  • 软件工程提出:1968 年北约会议上提出,旨在用工程化方法解决软件问题。

软件工程的定义:应用计算机科学、数学及管理科学等原理,以工程化的原则和方法解决软件问题,提高软件生产率、质量和降低成本。

软件工程学的范畴

  • 软件开发技术
    • 软件开发方法学
    • 软件工具
    • 软件工程环境
  • 软件工程管理
    • 软件工程管理学
    • 软件经济学

1.1 计算机软件的分类

  1. 系统软件
  • 服务于其他程序的整套程序。
  • 特点:与硬件交互多、多用户使用、资源管理复杂。
  1. 应用软件
  • 解决特定业务需求的独立应用程序。
  • 应用领域广泛,包括实时控制等。
  1. 工程/科学软件
  • 特征:数值计算算法。
  • 应用领域:天文、火山学、航天等。
  • 现代发展:交互性应用如 CAD、仿真。
  1. 嵌入式软件
  • 内置于产品或系统中,控制特定功能。
  • 应用:微波炉控制、汽车电子系统。
  1. 产品线软件
  • 为多个用户提供更多的功能用户使用提供特定功能。
  • 针对专业市场或大众消费品市场。
  1. Web 应用
  • 以网络为中心的软件。
  • 特点:网络密集性、并发性、性能要求高。
  1. 人工智能软件
  • 使用非数值算法解决复杂问题。
  • 应用:机器人、专家系统、模式识别等。
  1. 开放计算
  • 普适计算和分布式计算。
  • 挑战:开发适配多种网络设施的软件。
  1. 网络资源
  • 万维网作为计算引擎和内容平台。
  • 软件工程师任务:构建智能应用程序服务全球用户。
  1. 开源软件
  • 开放代码,允许多人贡献开发。
  • 挑战:开发自我描述代码和技术,便于跟踪改动。

1.2 软件工程基本原理

  1. 用分阶段的生命周期计划严格管理:将软件生命周期划分为多个阶段,制定并严格执行计划,包括项目概要计划、里程碑计划、项目控制计划等。
  2. 坚持进行阶段评审:在每个开发阶段进行严格评审,以便尽早发现并修正错误,减少后期修改成本。
  3. 实现严格的产品控制:不随意更改需求,采用基准配置管理,确保软件各部分的一致性。
  4. 采用现代程序设计技术:使用先进技术提高开发效率,降低维护成本。
  5. 结果应能清楚地审查:明确开发小组的责任和产品标准,提高管理透明度。
  6. 开发小组的人员应少而精:注重开发人员素质,减少沟通开销,提高效率。
  7. 承认不断改进软件工程实践的必要性:持续改进开发技术,总结经验,收集数据进行分析。

1.3 软件生存周期

软件生存周期包括多个阶段,每个阶段有明确任务,便于控制和管理:

  1. 可行性分析与项目开发计划:确定开发目标及可行性,制定项目计划,输出可行性分析报告和项目开发计划
  2. 需求分析:确定系统功能、性能、数据和界面要求,输出软件需求说明书
  3. 概要设计:设计软件结构、模块层次、调用关系及数据结构,输出概要设计说明书
  4. 详细设计:对每个模块功能进行具体描述,输出详细设计文档
  5. 编码:将模块控制结构转换为程序代码。
  6. 测试:验证软件质量,输出测试计划、测试用例和测试报告。
  7. 维护:修复错误、适应环境变化、扩充功能等。

1.4 软件过程

1.4.1 能力成熟度模型(CMM)

CMM 用于评估和改进软件组织的过程能力,分为 5 个成熟度等级:

  1. 初始级:过程无序,项目成功依赖个人努力。
  2. 可重复级:项目管理过程标准化,可重复以往成功经验。
  3. 已定义级:软件过程文档化、标准化,项目基于标准过程开发。
  4. 已管理级:过程和产品质量被量化和控制。
  5. 优化级:持续改进过程,通过反馈和新技术提升质量。

1.4.2 能力成熟度模型集成(CMMI)

CMMI 是 CMM 的集成和扩展,提供阶段式和连续式两种模型:

  1. 阶段式模型:关注组织成熟度,分为 5 个等级:
    • 初始的:过程不可预测且缺乏控制。
    • 已管理的:过程为项目服务。
    • 已定义的:过程为组织服务。
    • 定量管理的:过程已度量和控制。
    • 优化的:集中于过程改进。
  2. 连续式模型:关注每个过程域能力,分为6个等级(0~5):
    • CL0(未完成的):过程未执行或未达到 CL1 目标。
    • CL1(已执行的):过程将输入转换为输出,支持过程域目标。
    • CL2(已管理的):过程运作制度化,遵循文档化计划。
    • CL3(已定义的):过程按组织标准剪裁,收集过程资产。
    • CL4(定量管理的):过程量化管理,使用测量和质量保证。
    • CL5(优化的):过程持续优化,满足客户和改进计划需求。

2 软件过程模型

2.1 瀑布模型

  • 定义:将软件生存周期划分为线性顺序的阶段,包括需求分析、设计、编码、测试、运行与维护。
  • 特点:强调阶段性早期计划和文档控制,适合需求明确的项目。
  • 优点:易于理解和管理。
  • 缺点:需求变更能力弱,项目风险控制能力差,可能导致延期和超预算。
  • 适用场景:需求明确且稳定的软件项目。

2.2 增量模型

  • 定义:将软件开发分解为多个增量,每个增量独立开发并交付。
  • 特点:融合瀑布模型和原型实现的迭代特征,强调每个增量发布可操作产品。
  • 优点:快速发布初始版本,降低风险,减少需求变更影响。
  • 缺点:需求不稳定可能导致增量重新开发,管理复杂度高。
  • 适用场景:需求不确定或需要快速交付的项目。

2.3 演化模型

演化模型适用于需求不确定、经常变化的软件开发场景,通过迭代逐步完善软件版本。常见的演化模型包括原型模型和螺旋模型。

2.3.1 原型模型

  • 目的:快速构建原型,澄清需求,验证方案。
  • 步骤
    1. 沟通需求。
    2. 快速设计原型。
    3. 用户评估与反馈。
    4. 迭代改进。
  • 分类
    • 探索型:澄清目标。
    • 实验型:验证方案。
    • 演化型:逐步完善。

2.3.2 螺旋模型

  • 特点:结合瀑布模型和原型模型,强调风险分析。
  • 步骤:
    1. 制订计划。
    2. 风险分析。
    3. 实施工程。
    4. 用户评估。
  • 优势:支持需求动态变化,降低开发风险。
  • 挑战:需要丰富风险评估经验,避免过多迭代。

2.4 喷泉模型

  • 定义:以用户需求为动力,以对象为驱动,适合面向对象开发。
  • 特点
    • 迭代性:开发活动可重复多次。
    • 无缝性:开发活动无明显边界,可交叉进行。
  • 优点:提高开发效率,节省时间。
  • 缺点:需大量开发人员,不利于项目管理,要求严格文档管理。

2.5 基于构件的开发模型

  • 定义:利用预先包装的构件构造应用系统。
  • 过程
    • 领域工程:构建领域模型、可复用构件库。
    • 应用系统工程:使用可复用构件组装应用系统。
  • 优点:促进软件重用、提高开发效率。

2.6 形式化方法模型

  • 定义:基于严格数学基础的软件开发方法。
  • 活动:生成计算机软件形式化的数学规格说明。
  • 特点:使用严格数学语言描述功能规约和设计规约。

2.7 统一过程(UP)模型

  • 核心特点:用例和风险驱动,以架构为中心,迭代和增量开发。
  • 四个阶段:
    1. 起始阶段:项目初创,产出构想文档和初始用例模型等。
    2. 精化阶段:需求分析和架构演进,产出用例模型和分析模型等。
    3. 构建阶段:系统构建,产出设计模型和软件构件等。
    4. 移交阶段:软件提交,产出软件增量和β测试报告等。
  • 典型代表:Rational Unified Process (RUP),比 UP 更完整详细。

2.8 敏捷方法

  • 目标:快速、持续交付有价值的软件,使客户满意。
  • 典型方法:
    1. 极限编程(XP):
      • 特点:轻量级、高效、低风险。
      • 组成:价值观(沟通、简单性、反馈、勇气)、原则、实践和行为。
      • 最佳实践:计划游戏、小型发布、隐喻、简单设计、测试先行、重构、结队编程、集体代码所有制、持续集成、每周 40 小时工作制、现场客户、编码标准。
    2. 水晶法(Crystal):强调项目策略、约定和方法论的多样性,注重人员素质对软件质量的影响。
    3. 并列争求法(Scrum):使用迭代方法,每 30 天一个“冲刺”,多个小组并行递增实现产品。
    4. 自适应软件开发(ASD):以使命为指导,强调变化的重要性,注重风险管理和交付时间。
    5. 敏捷统一过程(AUP):结合 UP 阶段性和敏捷迭代,快速交付软件增量。

3 需求分析

3.1 软件需求

软件需求涵盖功能、性能、用户因素、环境、界面、文档、数据、资源使用、安全、可靠性、成本与进度及其他非功能性需求。具体内容如下:

  1. 功能需求:系统应具备的功能及修改升级能力。
  2. 性能需求:技术指标如存储容量、速度、响应时间等。
  3. 用户因素:用户类型、熟练程度、培训需求及操作难度。
  4. 环境需求:硬件(机型、外设等)和软件环境(操作系统等)。
  5. 界面需求:输入输出格式及数据存储规定。
  6. 文档需求:文档类型及目标读者。
  7. 数据需求:数据格式、频率、准确性、流量及存储时间。
  8. 资源使用需求:运行资源及开发、维护资源。
  9. 安全保密需求:访问控制、数据隔离及用户程序隔离。
  10. 可靠性需求:错误检测、隔离及重启时间。
  11. 软件成本与进度:开发时间表及资源限制。
  12. 其他非功能性需求:开发模式、质量标准、优先级及可维护性。

这些需求来源于用户、领域专家、技术标准等多方面。

3.2 需求分析原则

需求分析应遵循以下原则:

  1. 表示信息域:准确反映问题的信息域。
  2. 定义任务:明确软件的任务。
  3. 表示行为:描述软件对外部事件的响应。
  4. 划分模型:构建数据、功能和行为模型,分层展示细节。
  5. 从要素到细节:分析过程逐步深入,从整体到细节。

通过遵循这些原则,分析人员可以系统地处理问题,完整理解功能需求,简洁交流功能与行为特征,降低问题复杂度。

3.3 需求工程

  1. 需求获取:通过用户交流和系统观察确定需求。
  2. 需求分析与协商**:分类组织需求,解决冲突和不一致问题。
  3. 系统建模:使用工具建立模型,描述系统需求。
  4. 需求规约:编写需求文档,明确软件功能和行为。
  5. 需求验证:复查需求,确保正确性和完整性。
  6. 需求管理:跟踪和控制需求变化,维护需求一致性。

4 系统设计

4.1 概要设计

  • 软件系统总体结构设计
    • 将系统划分成模块;确定每个模块的功能;确定模块之间的调用关系;确定模块之间的接口;评价模块结构的质量。
  • 数据结构及数据库设计
    • 数据结构设计:细化数据结构。
    • 数据库设计:包括概念设计(E-R模型)、逻辑设计(结合 DBMS 特性)、物理设计(存储结构和存取方法)。
  • 编写概要设计文档:包括概要设计说明书、数据库设计说明书、用户手册、测试计划

4.2 详细设计

  • 算法设计:详细描述每个模块的算法。
  • 数据结构设计:设计模块内的数据结构。
  • 数据库物理结构设计:确定数据库的物理结构。
  • 其他设计
    • 代码设计。
    • 输入/输出格式设计。
    • 用户界面设计。
  • 编写详细设计说明书。
  • 评审:评审处理过程和数据库物理结构。

5 系统测试

5.1 系统测试与调试

5.1.1 系统测试的意义、目的及原则

系统测试是发现程序错误的过程,旨在以最少的人力和时间发现潜在错误和缺陷。测试应贯穿开发的各个阶段,遵循以下原则:

  1. 尽早并不断测试:错误发现越早,修正成本越低。
  2. 避免开发人员自测:由独立团队进行测试更客观有效。
  3. 设计有效测试方案:确定输入数据和预期输出,全面检查功能。
  4. 包含异常输入条件:测试异常和失效输入以发现隐藏错误。
  5. 检查未做之事:确保程序未执行不应做的操作。
  6. 严格按计划测试:保证测试进度和全面性。
  7. 保存测试文档:为维护和重新测试提供依据。

5.1.2 测试过程

测试过程与开发过程并行,包括以下活动:

  1. 制定测试计划:考虑项目时间和进度,确保计划可行。
  2. 编制测试大纲:明确测试项目和完成标准。
  3. 设计测试用例:涵盖被测项目、输入数据、测试过程和预期输出。
  4. 实施测试:依据测试大纲和用例执行测试。
  5. 生成测试报告:总结测试结果,指出缺陷并建议修改方案。

5.2 传统软件的测试策略

5.2.1 单元测试

  • 定义:测试单个模块的逻辑和结构。
  • 方法:使用白盒测试法。
  • 关注点:接口、数据结构、路径、错误处理、边界条件。
  • 环境
    • 驱动模块:模拟主程序传递测试数据。
    • 桩模块:代替子模块验证接口和返回信息。
  • 优点:简化测试,易于发现错误。

5.2.2 集成测试

  • 定义:将模块组合起来测试,确保集成后功能正常。
  • 方法:
    • 非增量集成:一次性组合所有模块进行测试。
    • 增量集成:逐步添加模块进行测试。
  • 关注点:数据丢失、模块间干扰、全局数据结构问题。
  • 回归测试:加入新模块后重新执行测试,确保没有引入新错误。
  • 冒烟测试:快速验证构建是否稳定,发现关键错误。

5.2.3 确认测试

确认测试用于验证软件是否满足用户可见的动作和系统输出。

  • 准则:确保功能和性能符合需求规格说明。
  • 配置评审:检查软件、文档和数据的完整性和正确性。
  • α 测试与 β 测试:
    • α 测试:在开发者场所由最终用户进行。
    • β 测试:在用户场所进行,开发者不在场。

5.2.4 系统测试

将软件与硬件、外设和网络结合,进行全面测试。

  1. 恢复测试:验证系统从故障中恢复的能力。
  2. 安全性测试:验证保护机制防止非法入侵的有效性。
  3. 压力测试:评估系统在极端条件下的表现。
  4. 性能测试:测量系统运行性能。
  5. 部署测试:确保软件在多种平台和环境中兼容。

5.3 测试面向对象软件

5.3.1 单元测试

  • 类的封装:重点测试类的属性和操作。
  • 最小测试单元:类中的单个操作。

5.3.2 集成测试

  • 基于线程的测试:集成和测试响应系统输入或事件所需的类。
  • 基于使用的测试:从少服务类开始构建系统。

5.4 测试 Web 应用

5.4.1 质量维度

  1. 内容:评估语法和语义层的内容。
  2. 功能:测试功能的正确性和标准符合性。
  3. 结构:确保结构正确表示内容和功能。
  4. 可用性:保证接口支持多种用户。
  5. 导航性:检查导航错误。
  6. 性能:确保系统响应和处理性能。
  7. 兼容性:测试不同配置下的兼容性。
  8. 安全性:识别和修复安全漏洞。

5.4.2 WebApp 测试策略

  1. 评审内容模型。
  2. 评审接口模型。
  3. 评审设计模型。
  4. 测试用户界面。
  5. 对功能组件进行单元测试。
  6. 测试导航结构。
  7. 在不同环境中测试兼容性。
  8. 进行安全测试。
  9. 进行性能测试。
  10. 用户评估。

5.5 测试方法

5.5.1 静态测试

  • 人工检测:代码检查、静态结构分析、代码质量度量。
  • 计算机辅助静态分析:使用工具分析程序逻辑缺陷。

5.5.2 动态测试

  • 黑盒测试(功能测试):不考虑内部结构,测试外部特性。
    • 等价类划分:将输入域分为有效和无效等价类,选择代表性数据。
    • 边界值分析:选择边界值作为测试用例。
    • 错误推测:基于经验设计测试用例。
    • 因果图:从规格说明中找出因果关系,设计测试用例。
  • 白盒测试(结构测试):基于程序内部结构和逻辑设计测试用例。
    • 逻辑覆盖标准(6种):
      1. 语句覆盖:确保程序每条语句至少执行一次,覆盖程度低。
      2. 判定覆盖(分支覆盖):确保每个判定分支(真/假)至少执行一次,比语句覆盖强。
      3. 条件覆盖:确保每个逻辑条件的各种可能值至少满足一次。
      4. 判定/条件覆盖:确保每个条件的所有可能取值及每个判定结果都出现。
      5. 条件组合覆盖:确保每个判定中条件值的各种组合都出现至少一次。
      6. 路径覆盖:覆盖程序中所有可能的路径。
    • 循环覆盖:确保循环中的每个条件都得到验证。
    • 基本路径测试:基于控制流图设计测试用例。

5.6 调试

5.6.1 调试过程

调试在测试后进行,旨在根据测试发现的错误找出原因和位置进行修正。主要由程序开发人员负责。

5.6.2 调试步骤

  1. 执行测试用例:运行测试用例,评估测试结果。
  2. 评估结果:比较实际输出与预期输出,确定错误。
  3. 开始调试:当实际与预期不符时,开始调试过程。
  4. 结果:可能找到并修正错误,或未能找到原因,需重复假设和验证。

5.6.3 调试难点

  • 症状与原因可能相隔甚远。
  • 症状可能在错误修正后暂时消失。
  • 可能由非错误因素(如舍入误差)引起。
  • 可能由人为错误引起。
  • 可能涉及计时问题。
  • 重现相同输入条件困难。
  • 症状可能时有时无。
  • 可能由分布式系统中的多个任务引起。

5.6.4 调试方法

  1. 试探法:分析症状,猜测错误位置,逐步试探。
  2. 回溯法:从错误症状位置开始,沿控制流程回溯。
  3. 对分查找法:通过设置变量正确值缩小错误范围。
  4. 归纳法:分析测试数据之间的关系,找出错误原因。
  5. 演绎法:列出可能原因,排除不可能原因,验证假设。

6 运行和维护知识

6.1 系统转换

系统试运行是对新系统进行全面检验的关键阶段,主要工作包括:

  1. 初始化与数据输入:输入原始数据记录。
  2. 数据与状态记录:记录系统运行数据和状态。
  3. 输出核对:对比新旧系统输出结果。
  4. 输入方式评估:检查新系统输入的便捷性、效率和安全性。
  5. 性能测试:实际测试系统的响应速度和处理能力。

新旧系统转换有以下三种转换方式

  1. 直接转换
    • 定义:新系统运行稳定后立即替代旧系统。
    • 特点:节省资源,适用于简单系统。
  2. 并行转换
    • 定义:新旧系统同时运行,验证新系统后替换旧系统。
    • 特点:安全可靠,但成本和工作量大,适用于复杂系统。
  3. 分段转换
    • 定义:逐步替换旧系统,部分新系统先运行,其余在模拟环境中继续测试。
    • 特点:兼顾可靠性和成本,要求系统具有独立性。

6.2 系统维护概述

系统可维护性

  • 定义:衡量维护人员理解、改正、改进软件的难易程度。
  • 评价指标
    • 可理解性:模块化、详细设计文档、结构化设计、良好的编程语言。
    • 可测试性:好的文档、程序结构、测试工具、测试工序。
    • 可修改性:模块的耦合、内聚、作用范围与控制范围。

维护与软件文档

  • 用户文档:描述系统功能和使用方法。
  • 系统文档:描述系统设计、实现和测试内容。
  • 文档修改:维护时需同步更新设计文档和用户手册。

系统维护的内容及类型

  1. 硬件维护:定期保养和突发故障维护。
  2. 软件维护:
    • 正确性维护:修正测试阶段未发现的错误。
    • 适应性维护:适应信息技术变化和管理需求变化。
    • 完善性维护:扩充功能和改善性能。举例:某开发人员修改了其中的索引方法,使得用户可以更快地得到搜索结果。
    • 预防性维护:增加预防性功能,适应未来环境变化。
  3. 数据维护:数据库管理员负责数据的安全性、完整性和并发性控制。

系统维护的管理和步骤

  1. 提出维护或修改要求:用书面形式向系统维护主管人员提出。
  2. 领导审批并答复:根据调查决定是否修改,制定维护计划。
  3. 领导分配任务,维护人员执行修改:维护人员了解原系统后进行修改。
  4. 验收维护成果并登记修改信息:测试和验收修改部分,更新文档。

6.3 系统评价

5.6.3 系统评价概述

5.6.3.1 信息系统评价

  • 广义评价:贯穿系统开发的全过程。
  • 狭义评价:系统运行后的全面综合评价。

按时间与阶段关系分为:

  1. 立项评价:系统开发前的可行性研究。
  2. 中期评价:项目实施过程中的阶段性评估。
  3. 结项评价:项目结束时的综合评价。

注意事项

  1. 数据准确性:数据采集的准确性至关重要,管理问题可能导致数据不一致。
  2. 系统能力边界:信息系统适合处理常规任务,不适合处理特殊、非规范的管理内容。

5.6.3.2 系统评价指标

  1. 用户需求和运行质量:从运行效果和用户需求角度出发。
  2. 系统质量和技术创新:关注系统质量和技术水平。
  3. 经济效益和社会效益:考虑系统成本、效益和财务指标。

7 软件项目管理

7.1 软件项目管理涉及的范围

7.1.1 人员

  • 项目管理人员:负责项目全面管理工作,其负责人通常称为项目经理。项目包括目标制定、计划、监控、团队组建等。
  • 高级管理人员:领域专家,负责项目目标和业务问题定义。
  • 开发人*:掌握专门技术,负责需求分析、设计、编码、测试等。
  • 客户:需求提出者和风险承担者。
  • 最终用户:产品交互者。

7.1.2 产品

  • 项目定义:明确项目范围、目标、约束等。
  • 软件范围:通过回答项目环境、信息目标、功能性能等问题定义。

7.1.3 过程

  • 过程模型选择:基于客户需求、产品特性、团队环境选择合适模型。
  • 过程控制:基于选定模型制定计划并分解任务。

7.1.4 项目

  • 明确目标及过程:理解问题,定义目标和范围。
  • 保持动力:提供激励,确保任务质量。
  • 跟踪进展:通过质量保证活动跟踪进展并测量。
  • 明智决策:使用商用软件和标准方法降低风险。
  • 事后机制分析:评估计划,收集反馈,记录发现。

7.2 软件项目估算

估算方法

  1. 基于类似项目估算:参考已完成的类似项目进行推断。
  2. 分解技术估算:
    • 问题分解:将复杂问题分解为多个小问题分别估算。
    • 过程分解:按软件开发活动(分析、设计、编码、测试)进行估算。
  3. 经验模型估算:使用IBM、COCOMO、Putnam等模型。

成本估算方法

  1. 自顶向下估算:根据历史项目总成本推断新项目成本,按阶段分配。
  2. 自底向上估算:估算每个子任务工作量后汇总。
  3. 差异估算:比较新项目与类似项目的差异,调整成本。
  4. 其他方法:专家估算法、类推估算法、算式估算法。

COCOMO 估算模型

  • 基本 COCOMO:静态单变量模型,公式为 E=a(L)bE = a(L)^bD=cEdD = cE^d
  • 中级 COCOMO:考虑 15 种成本驱动因素,引入工作量调节因子(EAF)。
  • 详细 COCOMO:分为系统、子系统、模块三层,考虑更多成本驱动因素。

COCOMOII 模型

  • 应用组装模型:用于软件工程前期,关注原型开发和用户界面。
  • 早期设计阶段模型:在需求稳定后使用,基于功能点。
  • 体系结构阶段模型:在软件构造过程中使用。

Putnam 估算模型

  • 动态多变量模型:基于工作量在软件生命周期中的分布。
  • 公式:L=CkE1/3td4/3L = C_k E^{1/3} t_d^{4/3},其中 CkC_k 为技术状态常数。

7.3 进度管理

7.3.1 进度管理基本原则

  1. 划分任务:将项目分解为可管理的活动和任务。
  2. 明确依赖关系:确定任务间的依赖关系,有些任务需按序进行,有些可并行。
  3. 时间分配:为每个任务分配工作量和时间,考虑资源限制。
  4. 责任到人:指定团队成员负责具体任务。
  5. 明确输出:每个任务应有明确的输出结果。
  6. 设定里程碑:与项目里程碑关联,标记重要阶段的完成。

7.3.2 进度安排

  1. Gantt 图(甘特图):
    • 水平条形图,展示任务的时间安排。
    • 显示任务的开始、结束时间和持续时间。
    • 优点:直观展示任务进度和并行性。
    • 缺点:无法清晰反映任务间的依赖关系和关键路径。
  2. PERT 图(项目计划评审技术图):
    • 有向图,箭头表示任务,结点表示事件。
    • 显示任务间的依赖关系和关键路径。
    • 优点:明确关键路径和任务的最早、最迟时间。
    • 缺点:无法反映任务间的并行关系。

7.4 软件项目组织

组织原则

  1. 尽早落实责任:明确专人负责,赋予管理权限。
  2. 减少交流接口:优化沟通路径,提高生产率。
  3. 责权均衡:确保责任与权利匹配。

组织结构模式

  1. 按项目划分:成员共同完成项目所有任务。
  2. 按职能划分:成员按专业职能组织成组。
  3. 矩阵模式:结合项目和职能组织,成员双重隶属。

程序设计小组组织方式

  1. 主程序员制:主程序员领导,分工明确。
  2. 民主制:成员平等决策,合作氛围好。
  3. 层次式:分层管理,适合层次结构项目。

7.5 软件配置管理

软件配置管理(SCM)用于整个软件工程过程,目标包括标识变更、控制变更、确保变更正确实现、报告变更。SCM是管理软件生存周期各阶段变更的活动集。

7.5.1 基线

基线是软件生存周期中各开发阶段的特定点,用于明确工作划分,便于检查与肯定阶段成果。当基线出错时,可返回到最近和最恰当的基线上。

7.5.2 软件配置项(SCI)

SCI 是软件工程中产生的信息项,是配置管理的基本单位。常见的 SCI 包括:系统规格说明书、软件项目实施计划、软件需求规格说明书、设计规格说明书、源代码清单、测试计划和过程、测试用例和测试结果记录、操作和安装手册、可执行程序、数据库描述、用户手册、维护文档、软件工程标准、项目开发小结等。

7.5.3 版本控制

软件配置随软件生存周期推进而变化,形成新版本。可用版本演变图表示系统不同版本。

7.5.4 变更控制

软件工程过程中的变更必须严格控制和管理,保持修改信息并传递到下一步骤。变更控制是重要的软件配置任务,需借助配置数据库和基线。配置数据库分为开发库、受控库和产品库三类。

7.6 风险管理

软件风险包含不确定性损失两个特性。在风险分析时,需量化每个风险的不确定程度和损失程度,并考虑不同类型的风险,包括项目风险、技术风险和商业风险。

  • 项目风险 威胁到项目计划,可能导致进度延误和成本增加,如预算、进度、人员、资源和需求等方面的问题。
  • 技术风险 威胁软件质量和交付时间,如设计、实现、接口、验证和维护等方面的问题,以及技术的不确定性和陈旧性。
  • 商业风险 威胁软件的生存能力,包括市场风险、策略风险、销售风险、管理风险和预算风险。

风险识别是系统化地指出对项目计划的威胁,包括:

  • 产品规模:与软件总体规模相关的风险
  • 商业影响:与市场和管理约束相关的风险
  • 客户特性:与客户素质及沟通能力相关的风险
  • 过程定义:与软件过程定义及遵守程度相关的风险
  • 开发环境:与开发工具的可得性和质量相关的风险
  • 开发技术:与软件复杂性和技术新奇性相关的风险
  • 人员才干及经验:与开发人员技术水平和项目经验相关的风险

风险预测又称风险估计,试图从两个方面评估一个风险:概率和后果。

风险评估预测活动:

  1. 建立评估标准:反映风险发生的可能性
  2. 描述后果:风险发生后的影响
  3. 估算影响:风险对项目和产品的潜在影响
  4. 标注精度:避免误解

风险影响评估考虑风险的本质、范围和时间。风险显露度(RE)由公式 RE=P×CRE = P \times C 确定,其中 P 是风险发生的概率,C 是风险带来的成本。

风险评估建立三元组 (ri,li,xi)(r_i, l_i, x_i),其中 rir_i 表示风险,lil_i 表示风险发生的概率,xix_i 表示风险产生的影响。评估步骤包括定义风险参考水平值、建立关系、预测临界点和评估风险组合影响。

风险控制策略包括:

  1. 风险避免:分析风险原因并采取措施避免风险发生
  2. 风险监控:监控风险相关因素,评估风险变化
  3. RMMM 计划:文档化风险分析工作,包含风险缓解、监控和管理计划,用于项目管理和跟踪

8 软件质量

软件质量是指软件系统或产品满足规定或隐含需求的能力的特征和特性全体。软件质量管理由质量保证、质量规划和质量控制三个活动构成,旨在生产高质量的软件。

8.1 软件质量特性

8.1.1 ISO/IEC 9126 软件质量模型

ISO/IEC 9126 模型包含三个层次:质量特性、质量子特性和度量指标。主要质量特性包括:

  • 功能性:与功能及其指定性质的存在有关。
    • 适应性:功能是否适合任务。
    • 准确性:结果是否正确。
    • 互用性:与其他系统交互的能力。
    • 依从性:符合标准和法规。
    • 安全性:防止非授权访问。
  • 可靠性:在规定时间和条件下维持性能的能力。
    • 成熟性:故障频度。
    • 容错性:在错误情况下维持性能。
    • 易恢复性:恢复性能和数据的能力。
  • 易使用性:与用户使用所需努力和评价有关。
    • 易理解性:理解逻辑概念所需努力。
    • 易学性:学习应用所需努力。
    • 易操作性:操作和控制所需努力。
  • 效率:性能与资源使用的关系。
    • 时间特性:响应和处理时间。
    • 资源特性:资源使用量和持续时间。
  • 可维护性:修改所需努力的属性。
    • 易分析性:诊断缺陷原因。
    • 易改变性:进行修改所需努力。
    • 稳定性:修改造成未预料效果的风险。
    • 易测试性:确认修改后软件所需努力。
  • 可移植性:转移到另一环境的能力。
    • 适应性:转移到不同环境的处理。
    • 易安装性:安装所需努力。
    • 一致性:符合移植相关的标准。
    • 易替换性:替代其他软件的可能和努力。

8.1.1.2 Mc Call 软件质量模型

Mc Call 模型从软件运行、修正和转移三个方面确定了 11 个质量特性:

产品修正:

  • 可维护性:易于修改。
  • 可靠性:在规定条件下维持性能。
  • 可测试性:易于测试。

产品转移:

  • 可移植性:易于转移到其他环境。
  • 复用性:组件可复用性。
  • 互用性:与其他系统交互的能力。

产品运行:

  • 正确性:满足需求的能力。
  • 可靠性
  • 易使用性:用户使用的容易程度。
  • 效率:资源使用效率。
  • 完整性:保护信息的能力。

8.2 软件质量保证

软件质量保证是指为保证软件系统或产品充分满足用户要求的质量而进行的有计划、有组织的活动,其目的是生产高质量的软件。强调以下3个要点:

  1. 软件必须满足用户规定的需求。
  2. 软件应遵循规定标准所定义的开发准则。
  3. 软件应满足某些隐含的需求,如可理解性和可维护性。

主要活动

  1. 应用技术方法 - 将质量设计到软件中,选择技术方法和工具。
  2. 进行正式技术评审 - 评估规格说明和设计,揭露质量问题。
  3. 测试软件 - 结合多种测试策略,检测错误。
  4. 标准的实施 - 遵循开发标准和过程,确保一致性。
  5. 控制变更 - 管理变更以防止错误引入。
  6. 度量 - 收集软件度量,跟踪质量和方法影响。
  7. 记录保存和报告 - 记录质量保证活动的结果并传播信息。

8.3 软件评审

8.3.1 设计质量的评审内容

  • 规格说明书与用户需求一致性:检查总体设计思想、需求规格说明书的批准情况以及与概要设计规格说明的一致性。
  • 可靠性:评估是否能避免输入异常、硬件失效和软件失效,并及时采取替代手段或恢复措施。
  • 保密措施:检查系统对使用资格的检查、特定数据和功能的使用资格以及数据加密功能。
  • 操作特性:评估操作命令、输入输出数据的恰当性以及应答时间。
  • 性能目标值:检查是否达到规定的性能目标值。
  • 可修改性、可扩充性、可互换性和可移植性:评估软件的可修改性和可移植性。
  • 可测试性:检查软件是否具有可测试性。
  • 复用性:评估软件是否具有复用性。

8.3.2 程序质量的评审内容

  • 功能结构:检查数据结构、功能结构以及它们之间的对应关系,确保功能结构与数据结构的一致性。
  • 功能的通用性:评估功能的通用性,并检查抽象数据结构和抽象功能结构。
  • 模块的层次:检查模块层次是否根据功能层次设计。
  • 模块结构:评估模块的动态结构,包括控制流结构、数据流结构以及模块结构与功能结构的对应关系。
  • 处理过程的结构:检查模块功能与处理过程结构的对应关系,控制流的结构化,数据结构与控制流的对应关系,以及处理过程的术语标准化。

8.3.3 与运行环境的接口

  • 与硬件的接口:检查接口约定、硬件使用规定、硬件故障处理和超载处理。
  • 与用户的接口:检查输入输出数据的结构、异常输入处理、超载输入处理以及用户存取资格检查等。

8.4 软件容错技术

8.4.1 容错软件的定义

容错软件能够在一定程度上屏蔽自身错误、从错误状态恢复、在错误发生时仍完成预期功能,或具有容错能力。

8.4.2 容错的一般方法

实现容错的主要手段是冗余,包括以下几种类型:

8.4.2.1 结构冗余
  • 静态冗余:如三模冗余(TMR)和多模冗余,通过表决和比较屏蔽错误。
  • 动态冗余:多重模块待机储备,检测到错误时切换到备用模块。
  • 混合冗余:结合静态和动态冗余的优点。
8.4.2.2 信息冗余

通过添加额外信息检测或纠正错误,如奇偶码和循环码。

8.4.2.3 时间冗余

通过重复执行指令或程序消除瞬时错误影响,如程序滚回技术。

8.4.2.4 冗余附加技术

提供实现冗余技术所需的资源和技术,包括关键程序和数据的冗余存储及调用、错误检测和恢复程序等。

9 软件度量

9.1 软件度量分类

软件度量分为以下几类:

按属性分类

  • 面向规模的度量:如代码行数(LOC)、千行代码数(KLOC)。
  • 面向功能的度量:如功能点(FP)。
  • 面向人的度量:如开发人员的工作方式和效率。

按关注点分类

  • 生产率度量:关注软件工程活动的制品。
  • 质量度量:关注软件产品的特征,如可靠性、可维护性。
  • 技术度量:关注软件产品的技术特征,如逻辑复杂性、模块化程度。

9.1.1 面向规模的度量

面向规模的度量基于代码行数(LOC)或千行代码数(KLOC)。

9.1.2 面向功能的度量

面向功能的度量主要使用功能点(FP),基于软件信息域的特性和复杂性计算。信息域包括:

  • 外部输入数(EI):来自用户或其他系统的输入。
  • 外部输出数(EO):系统导出的信息。
  • 外部查询数(EQ):在线输入产生的即时软件响应。
  • 内部逻辑文件数(ILF):应用系统边界内的数据逻辑分组。
  • 外部接口文件数(EIF):应用系统外部的数据逻辑分组。

9.2 软件复杂性度量

软件复杂性涉及多个参数,包括:

  • 规模:总指令数或源程序行数。
  • 难度:由程序操作数的数量决定。
  • 结构:与程序结构相关。
  • 智能度:算法的难易程度。

9.2.1 程序复杂性度量原则

程序复杂性度量模型应遵循以下基本原则:

  • 程序复杂性与大小的关系不是线性的。
  • 控制结构复杂、数据结构复杂的程序较复杂。
  • 转向语句使用不当、循环结构多的程序较复杂。
  • 程序中的语句、数据、子程序和模块的次序影响复杂性。

9.2.2 McCabe 度量法

McCabe 度量法基于程序控制流,使用环路复杂性度量程序的复杂性。环路复杂性通过程序图的环路数计算得出,公式为:V(G) = m - n + 2p

其中,V(G)V(G) 是环路数,m 是弧的个数,n 是结点数,p 是强连通分量的个数。程序图的环路数反映了程序控制结构的复杂性。McCabe 建议环路复杂性度量值不超过 10。

10 软件工具与软件开发环境

10.1 软件工具

软件工具用于辅助软件开发、运行、维护、管理和支持等过程,以提高效率和质量。

10.1.1 软件开发工具

  1. 需求分析工具
    • 用于生成完整、清晰、一致的功能规范。
    • 分为基于自然语言/图形描述的工具和基于形式化需求定义语言的工具。
  2. 设计工具
    • 辅助设计人员从功能规范得到设计规范。
    • 分为概要设计工具和详细设计工具。
  3. 编码与排错工具
    • 编码工具:辅助程序员编写源程序并转换为可执行代码。
    • 排错工具:辅助程序员查找源程序中的错误。
  4. 测试工具
    • 支持软件测试,包括数据获取工具、静态分析工具、动态分析工具、模拟工具和测试管理工具。

10.1.2 软件维护工具

  1. 版本控制工具
    • 用于存储、更新、恢复和管理软件的多个版本。
  2. 文档分析工具
    • 分析软件开发过程中的文档,提供维护信息。
  3. 开发信息库工具
    • 维护软件项目的开发信息,记录每个对象的修改信息和其他变形。
  4. 逆向工程工具
    • 将软件转换为更高抽象形式,恢复设计信息。
  5. 再工程工具
    • 支持重构功能和性能更完善的软件系统。

10.1.3 软件管理和支持工具

  1. 项目管理工具
    • 辅助项目管理活动,如计划、调度、通信、成本估算等。
  2. 配置管理工具
    • 辅助完成软件配置项的标识、版本控制、变化控制等任务。
  3. 软件评价工具
    • 根据质量模型对软件进行度量,生成评价报告。

10.2 软件开发环境

软件开发环境由软件工具集和环境集成机制构成,支持软件开发的相关过程、活动和任务。

集成机制

  1. 数据集成:提供统一的数据模式和接口规范,实现工具间数据交换。
  2. 界面集成:采用统一界面风格和交互方法,降低学习成本。
  3. 控制集成:支持工具和开发活动间的通信、切换、调度和协同。
  4. 其他集成:包括平台集成、方法与过程集成等。

特征

  1. 集成的服务:支持多种集成机制,如平台集成、数据集成、界面集成、控制集成和过程集成。
  2. 小组工作支持:支持小组工作方式,提供配置管理功能。
  3. 多活动支持:支持分析、设计、编程、测试、调试和文档等开发活动。

集成型开发环境将多种开发方法、模型和工具集成在一起,具有开放性和可剪裁性,可根据需求进行定制。

11 加餐和总结

模块设计原则的考查

模块控制域:这个模块本身以及所有直接或间接从属于它的模块的集合。
模块作用域:指受该模块内一个判定所影响的所有模块的集合。
模块的作用域应该在控制域范围之内。

软件文档的意义

  • 文档是软件的重要组成部分,贯穿整个软件周期,包括软件开发和软件维护阶段。
  • 软件文档的编制在软件开发工作中占有突出的地位和相当大的工作量。
  • 高质量文档对于发挥软件产品的效益有着重要的意义。