软件工程

Software Engineering

Posted by kaws-y on July 20, 2026

本文整理自《芝士架构公共知识红宝书》系统架构设计师公共基础知识,涵盖软件工程概述、需求工程、系统设计、软件测试、系统运行与维护、项目管理六大核心领域。


一、软件工程概述

1.1 软件工程相关定义

软件工程由方法、工具和过程三个部分组成,包含以下 4 个方面(PDCA 循环):

阶段 含义
P (Plan) 软件规格说明——规定软件的功能及其运行时的限制
D (Do) 软件开发——开发出满足规格说明的软件
C (Check) 软件确认——确认开发的软件能够满足用户的需求
A (Action) 软件演进——软件在运行过程中不断改进以满足客户新的需求

1.2 软件开发方法

1.2.1 方法分类

分类方法 具体方法 描述
开发风格 自顶向下 系统整体结构首先被定义,然后逐步细化为更具体的模块
自底向上 从具体模块开始逐步构建整个系统
性质 形式化方法 具有坚实数学基础的开发方法
非形式化方法 不把严格性作为主要着眼点
适应范围 整体性方法 适用于软件开发全过程
局部性方法 适用于开发过程某个具体阶段

1.2.2 形式化方法

使用严格的数学模型和形式化语言来描述系统的需求、设计和行为,通过逻辑推理或模型检测等手段证明软件正确性。

特点:

  • 正确性验证难且耗时,数学模型和证明困难
  • 仍需要和传统测试相结合(形式化方法提供理论保证,测试负责发现运行时错误)

1.2.3 净室软件工程(CSE)

净室软件工程是一种形式化方法,强调用数学与统计理论在设计和规约阶段消除错误。

理论基础 描述
函数理论 将程序定义为从输入集合到输出集合的严格映射,关注完备性、一致性、正确性
抽样理论 基于软件输入空间的无限性,通过科学抽样选取代表性测试用例推断系统可靠性

开发步骤: 统计过程控制下的增量式开发 → 基于函数的规约+盒子结构方法 → 正确性验证 → 统计测试与软件认证

局限性: 正确性验证依赖严格数学基础,对工程师要求极高;不依赖传统单元测试但仍需模块测试;未突破传统软件工程体系边界。

1.2.4 逆向工程

概念 通俗解释 定义
逆向工程 从低层(代码)推回高层设计 分析程序,在比源代码更高抽象层次上建立程序表示
重构 同一抽象层改结构 在同一抽象级别上转换系统描述形式
设计恢复 借助工具抽取设计信息 从已有程序中抽象出数据设计、总体结构设计和过程设计
再工程 逆向工程+新需求+正向工程 在逆向工程信息基础上,修改或重构已有系统产生新版本
正向工程 从设计到代码 从现有系统恢复设计信息,用此信息改变或重构系统

关键区分: 看到”分析程序、恢复设计”选逆向工程;看到”修改、重构、升级、产生新版本”选再工程

逆向工程抽象层次(从低到高):

层次 包含信息
实现级 程序的抽象语法树、符号表等信息
结构级 反映程序分量相互依赖关系信息(调用图、结构图等)
功能级 反映程序段功能及程序段之间关系的信息
领域级 反映程序分量或实体与应用领域概念对应关系的信息

记忆口诀:世仇结分工龄(实现→结构→功能→领域)

1.2.5 基于构件的软件工程(CBSE)

CBSE 旨在通过复用可重用的软件构件来构造高质量、高效率的应用软件系统。

构件特性:

特性 描述
可组装性 所有外部交互必须通过公开定义的接口进行
可部署性 构件必须是自包含的,能作为独立实体运行(二进制形式)
文档化 构件必须完全文档化,所有接口语法和语义应被定义
独立性 可以在无其他特殊构件的情况下进行组装和部署
标准化 构件必须符合某种标准化的构件模型
可见性 没有(外部的)可见状态

记忆口诀:竹鼠挡毒标(组装→部署→文档→独立→标准)

构件分类:

名称 特点 例子
独立而成熟的构件 完全隐藏接口,通过命令使用 数据库管理系统、操作系统
有限制的构件 提供接口并指出使用条件 面向对象基础类库
适应性构件 处理了不兼容性,可直接使用 ActiveX 组件
装配的构件 已装配在不同层次上,用胶水代码连接 成品软件产品
可修改的构件 可修改错误、增加新功能 常用功能模块

记忆口诀:独显时装秀(独立→限制→适应→装配→修改)

CBSE 过程: 系统需求概览 → 识别候选构件 → 根据发现的构件修改需求 → 体系结构设计 → 构件定制与适配 → 组装构件创建系统

构件组装方式:

组装类型 描述 特点
顺序组装 按顺序调用已有构件创造新构件 构件间不相互调用,需胶水代码
层次组装 一个构件直接调用另一个构件的服务 接口匹配无需额外代码,不匹配需转换代码
叠加组装 两个或以上构件叠加创建新构件 A 和 B 不相互依赖和调用

接口不兼容类型:

类型 描述
参数不兼容 接口两侧操作名相同,但参数类型或数目不同
操作不兼容 “提供”接口和”请求”接口操作名不同
操作不完备 一个构件的”提供”接口是另一个构件”请求”接口的子集

1.3 软件过程/生命周期模型

软件过程 = 软件开发生命周期模型(同义词)

前提条件 具体模型
软件需求完全确定 瀑布模型
开发初始阶段仅能提供基本需求 喷泉模型、螺旋模型、统一开发过程、敏捷方法
以形式化开发方法为基础 变换模型

1.3.1 瀑布模型

将软件开发分为 6 个阶段:需求分析和定义 → 系统和软件设计 → 实现和单元测试 → 集成和系统测试 → 运行维护。

缺点: 依赖于早期需求调查,不能适应需求的变化。

1.3.2 原型模型/演化模型

适用于需求难完整定义的软件开发,基于快速开发的原型,依据用户反馈改进,不断迭代直至形成最终产品。特点是迭代。

1.3.3 螺旋模型

螺旋模型 = 快速原型 + 风险分析

适用于庞大、复杂并具有高风险的系统,支持用户需求的动态变化。过多迭代会增加开发成本,延迟提交时间。

1.3.4 喷泉模型

以用户需求为动力,以对象为驱动,主要用于面向对象的软件开发。各阶段可以交互进行,没有特定次序要求。

1.3.5 V 模型

测试类型 测试依据(文档)
单元测试 软件详细设计说明书
集成测试 软件概要设计文档
系统测试 需求分析文档或开发合同
验收测试 用户需求

1.3.6 统一过程(RUP)

RUP 是用例驱动的、以体系结构为中心的、迭代和增量的软件开发过程。

9 大核心工作流: 业务建模、需求、分析与设计、实现、测试、部署、配置与变更管理、项目管理、环境

记忆口诀:建需分食测(建模→需求→分析→实现→测试),部配变项环(部署→配置变更→项目管理→环境)

1.3.7 敏捷方法

敏捷宣言:

  • 个体和交互 胜过 过程和工具
  • 可工作的软件 胜过 大量的文档
  • 客户合作 胜过 合同谈判
  • 响应变化 胜过 遵循计划

适用场景: 规模较小的项目;需求快速改变的情况。不适用于高关键性、可靠性、安全性要求的系统。

记忆口诀:小变(规模小、快速改变)

主要敏捷方法:

方法 简介 核心价值观
极限编程(XP) 短开发周期和频繁发布 交流、朴素、反馈、勇气
水晶系列方法 具有共性核心元素 以人为中心
Scrum 迭代式增量软件开发 团队协作、响应变化、关注商业价值
特征驱动开发(FDD) 强调人、过程和技术三要素 迭代开发模型

Scrum 框架:

角色 职责
Product Owner 业务价值代言人,管理产品需求列表
Scrum Master 推动框架落地,清除团队障碍
Development Team 跨功能自组织团队,执行 Sprint 任务
活动 目的
Sprint Planning 定义冲刺工作,制定执行计划
Daily Scrum 每日同步进展,暴露障碍
Sprint Review 展示成果,收集反馈
工件 定义
Product Backlog 按业务价值优先级排序的功能需求清单
Sprint Backlog 冲刺规划阶段筛选出的工作项集合
Increment 满足”完成定义”的可交付产品改进

1.3.8 增量模型

将系统分为多个模块,逐步实现。每次增量版本都可以作为独立可操作的作品。

迭代 vs 增量: 迭代是功能深度优化的螺旋上升(逐步完善同一功能);增量是模块叠加的线性扩展(逐个添加新功能模块)。

1.4 软件过程管理

1.4.1 CMM(软件能力成熟度模型)

等级 描述
初始级 过程没有明确规定,成功依赖个别高手和运气
可重复级 已建立基本项目管理过程,能跟踪成本、进度、功能
已定义级 软件过程已文档化、标准化,形成组织级标准过程
已管理级 对过程和产品质量有详细度量标准,能定量分析
优化级 基于量化分析不断持续改进过程

记忆口诀:初重定管优(除虫顶管用)

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

CMMI 是 CMM 的升级版本,理论基础源于四大知识体系:系统工程(SE)、软件工程(SW)、集成产品与流程开发(IPPD)、供应商采购(SS)。

记忆口诀:细软开工(系统工程→软件工程→开发→供应商采购)

等级 描述
初始级 过程通常是随意且混乱的
已管理级 确保策划、文档化、执行、监督和控制项目级过程
已定义级 根据自身情况定义标准流程并制度化
量化管理级 建立产品质量、服务质量和过程性能的定量目标
优化级 动态调整软件过程以适应不同项目需求

记忆口诀:储罐定粮油(初始→管理→定义→量化→优化)


二、需求工程

需求工程 = 需求开发 + 需求管理

需求开发包括:需求获取 → 需求分析 → 需求定义(SRS) → 需求验证

需求管理包括:需求基线、需求变更、需求跟踪

2.1 需求获取

方法 描述 优缺点
用户访谈 结构化和非结构化两种形式 灵活性强;对沟通能力要求高
问卷调查 制作调查表确定问题类型 高效低成本;缺乏灵活性
采样 从种群中选出代表性样本 加快收集、减少偏差;依赖设计师经验
情节串联板 通过图片辅助讲故事叙述需求 生动友好;花费时间多
联合需求计划(JRP) 开发者与顾客深入合作的集会 对需求不清晰领域有用;组织和人员是难点
收集资料 查阅已有文档、报告、标准 -
获取文档 索取项目相关文档 -
参加业务实践 体验和观察业务活动 -

记忆口诀:访问踩窗帘,合收十文

2.2 结构化分析(SA)

基本思想:自顶向下,逐层分解

分析模型核心是数据字典,围绕三个层次的模型:

模型 表示工具
数据模型 ER 图
功能模型 DFD 图(数据流图)
行为模型 状态转换图

2.2.1 数据流图(DFD)

基本符号:

符号 表示内容 图形
数据流 具有名字和流向的数据 标有名字的箭头
加工 对数据流的变换 圆圈
数据存储 可访问的存储信息 直线段
外部实体 数据源及数据终点 标有名字的方框

补充:数据存储要被外部实体使用必须经过加工。

DFD 层次: 顶层图(整个系统表示为一个加工) → 逐层分解

数据流图平衡原则:

原则 描述
父图与子图平衡 数据流个数一致、方向一致
黑洞 加工只有输入没有输出
奇迹 加工只有输出没有输入
灰洞 加工中输入不足以产生输出

2.3 面向对象分析(OOA)

2.3.1 用例模型

构建用例模型 4 个阶段:识别参与者 → 合并需求获得用例 → 细化用例描述 → 调整用例模型

记忆口诀:人合细条

用例之间的关系:

关系 描述 构造型 箭头指向
包含 从多个用例提取公共行为 <<include>> 指向抽象用例
扩展 一个用例混合多种场景分为基本+扩展 <<extend>> 指向基本用例
泛化 多个用例有类似结构,抽象为父用例 - 指向父用例

2.3.2 分析模型(类图)

类之间的 6 大关系(强弱排序):

泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖

记忆口诀:饭食组聚关羽(泛化→实现→组合→聚合→关联→依赖)

关系 定义 特点
关联 两个事物间存在明确稳定的语义联系 强语义、结构稳定
依赖 B 的变化可能引起 A 的变化 临时使用关系
泛化 父类与子类的关系(is-a) 子类继承父类属性和方法
聚合 整体与部分,部分可属于多个整体 部分能单独存在,生命周期可不同
组合 整体与部分,部分只能属于一个整体 部分唯一归属,生命周期同步
实现 接口定义行为,类实现接口 接口定行为,类负责实现

2.4 建模语言(UML)

UML 结构包括:构造块、规则和公共机制。

UML 4+1 视图:

视图 关注点 关注角色
逻辑视图 系统功能模块及相互关系 最终用户
进程视图 系统运行时的进程和线程 系统集成人员
实现视图 软件构件在开发环境中的组织 程序员
部署视图 软件到硬件的映射和分布 系统工程师
用例视图 系统功能需求(+1,核心) 分析人员和测试人员

UML 图分类:

  • 结构图: 类图、对象图、包图、组合结构图、构件图、部署图、轮廓图
  • 行为图: 用例图、活动图、状态机图、顺序图、通信图、时间图、交互概览图

UML 4 种基本关系: 依赖、关联、泛化、实现

用例图中的包含和扩展属于依赖关系;类图中的组合和聚合属于关联关系

2.5 需求管理

2.5.1 需求基线

已经通过正式评审和批准的规约或产品,作为进一步开发的基础,只能通过正式的变更控制系统进行变化。

2.5.2 需求变更

变更管理流程:变更申请 → 变更评估 → 通告评估结果 → 变更实施 → 变更验证与确认 → 变更发布

2.5.3 需求跟踪

跟踪类型 概念
正向跟踪 检查 SRS 中的每个需求是否在后继工作成果中找到对应点
反向跟踪 检查设计文档、代码、测试用例等是否都能在 SRS 中找到出处

三、系统设计

3.1 系统设计概述

系统设计包括概要设计和详细设计:

  • 概要设计: 对系统进行高层次规划,确定系统的基本结构、组成要素及其关系
  • 详细设计: 在概要设计基础上,确定各个模块的具体实现方式、接口定义、算法实现

系统设计 7 类: 网络设计、代码设计(面向对象设计+结构化设计)、输入设计、输出设计、处理流程设计、数据存储设计、用户界面设计、安全性和可靠性设计

用户界面设计黄金三原则:置于用户控制之下、减轻用户记忆负担、保持界面一致性

3.2 处理流程设计

流程 6 要素: 输入资源、活动、活动的相互作用(结构)、输出结果、用户、价值

流程设计工具:

类别 工具 描述
图形工具 程序流程图(PFD) 用图框表示各种操作,独立于程序设计语言
图形工具 N-S 图(盒图) 以方框代替传统 PFD,具有强烈结构化特征
图形工具 IPO 图 描述模块的输入、输出和数据加工
图形工具 问题分析图(PAD) 支持结构化程序设计,适合嵌套和层次关系
图形工具 判定树 用树形结构表示逻辑判断
表格工具 判定表 用表格形式表示逻辑判断问题
语言工具 过程设计语言(PDL) 混合自然语言和结构化程序设计语法(伪代码)

工作流管理系统(WFMS): 通过软件定义、创建工作流并管理其执行。

基本功能:工作流建模 → 工作流执行 → 业务过程管理 → 业务过程分析

记忆口诀:简直过分(建模→执行→过程→分析)

3.3 面向对象设计(OOD)

3.3.1 设计类分类

类别 定义 命名规则 生命周期
实体类 映射需求中的实体,保存永久存储信息 业务领域术语(名词) 具有永久性
控制类 控制用例工作,对控制行为建模 动宾结构短语转化的名词 用例执行时产生,完毕后消亡
边界类 封装系统与外界交互的信息流 与系统接口相关 随系统运行一直存在

判断方法:先看是否是窗口、通信协议、打印机接口、报表等(边界类),再用命名规则判断(名词→实体类,动名词→控制类)。

3.3.2 面向对象设计原则(SOLID)

原则 描述
S - 单一职责原则 类应该只有一个设计目的
O - 开闭原则 对扩展开放,对修改封闭(是其他原则的基础)
L - 里氏替换原则 子类对象必须能替换父类对象
I - 接口隔离原则 客户端不应依赖它不需要的接口
D - 依赖倒置原则 抽象不依赖于细节,针对接口编程
组合/聚合复用原则 通过组合或聚合复用已有对象,比继承更灵活
最少知识原则(迪米特法则) 软件实体应尽量少与其他实体相互作用

3.4 结构化设计(SD)

结构化设计是一种面向数据流的方法,以 SRS、数据流图和数据字典为基础,是自顶向下、逐步求精和模块化的过程。

软件设计模型包括 4 个活动:数据设计、软件结构设计、人机界面设计(接口设计)、过程设计

3.4.1 模块划分原则

  • 模块大小适中(1-2 页纸或 50-200 行)
  • 模块扇入扇出合理(平均 3 或 4,不超过 7)
  • 深度和宽度适当
  • 信息隐蔽(封装技术隐藏实现细节)

3.4.2 耦合(从低到高)

耦合类型 描述
非直接耦合 两个模块之间没有直接关系
数据耦合 借助参数表传递简单数据值
标记耦合 通过参数表传递记录信息(数据结构)
控制耦合 传递的信息中包含控制模块内部逻辑的信息
外部耦合 都访问同一全局简单变量
公共耦合 都访问同一个公共数据环境
内容耦合 一个模块直接访问另一个模块的内部数据

记忆口诀:非鼠标控制外公嘞(非直接→数据→标记→控制→外部→公共→内容)

3.4.3 内聚(从高到低)

内聚类型 描述
功能内聚 完成一个单一功能,各部分协同工作,缺一不可
顺序内聚 处理元素相关且必须顺序执行(存在数据传递)
通信内聚 所有处理元素集中在一个数据结构的区域上
过程内聚 处理元素相关且必须按特定次序执行(不存在数据传递)
瞬时内聚 所包含的任务必须在同一时间间隔内执行
逻辑内聚 完成逻辑上相关的一组任务
偶然内聚 完成一组没有关系或松散关系的任务

记忆口诀:公孙铜锅涮罗欧(功能→顺序→通信→过程→瞬时→逻辑→偶然)

3.5 设计模式

模式大类 包含模式
创建模式 工厂方法、抽象工厂、生成器、原型、单例
结构模式 适配器、桥接、组合、装饰、外观、享元、代理
行为模式 职责链、命令、解释器、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者

四、软件测试

4.1 测试分类

分类维度 类别 描述
按程序可见性 黑盒测试 不考虑内部结构,从用户角度基于输入输出测试
按程序可见性 白盒测试 需了解程序内部逻辑结构,对所有逻辑路径测试
按程序可见性 灰盒测试 介于白盒与黑盒之间,多用于集成测试
按是否执行 静态测试 不运行程序,通过分析源程序检查正确性
按是否执行 动态测试 运行被测程序,检查运行结果与预期差异
按测试阶段 单元测试 对最小可测试单元检查,以白盒为主
按测试阶段 集成测试 将软件集成后测试,针对模块间接口
按测试阶段 系统测试 对整个系统测试,检验是否符合系统说明书
按测试对象 功能测试 验证程序按预期方式运行
按测试对象 性能测试 测试响应时间,包括负载、压力、并发等
按测试对象 安全测试 验证应用程序安全等级

4.2 白盒测试覆盖标准(从弱到强)

覆盖标准 描述 发现错误能力
语句覆盖 每条语句至少执行一次 1(最弱)
判定覆盖 每个判定的每个分支至少执行一次 2.5
条件覆盖 每个条件的每个可能值取到 2.5
判定条件覆盖 同时满足判定覆盖和条件覆盖 4
条件组合覆盖 每个判定中各条件的每一种组合至少出现一次 5
路径覆盖 所有可能的执行路径都执行过 6(最强)

记忆口诀:路条组判|条条判语(从高到低)

4.3 性能测试辨析

类别 描述
负载测试 在已达到瓶颈的情况下继续运行,测试各项性能指标
压力测试 不断给系统加压,直到某些性能指标达到瓶颈
并发测试 负载测试和压力测试的结合,确定系统并发性能
容量测试 预先分析出某项指标的极限值,测试极限状态下系统表现
强度测试 检查程序对异常情况的抵抗能力(超负荷或最差环境)

强度测试 vs 压力测试: 强度测试侧重制造极限状态(超负荷或环境);压力测试是慢慢加压、渐增负载的过程。

4.4 测试模型

模型 定义 测试与开发关系
W 模型 在 V 模型基础上发展而来 同步
H 模型 测试活动独立 独立
X 模型 针对单独程序片段进行编码和测试 交错

五、系统运行与维护

5.1 运维技术指标

指标 含义 计算方式
MTTR 平均故障修复时间 总修复时间 / 维修次数
MTBF 平均故障间隔时间 总运行时间 / 故障总数
MTTF 平均无故障时间 正常运行总时间 / 故障总数
MTTA 平均应答时间 告警到确认累计时间 / 事件总数

5.2 软件系统维护

维护类型 维护原因 定义
改正性维护 纠正软件错误、性能缺陷 诊断和改正错误的过程(修 Bug)
适应性维护 外部环境或数据环境发生变化 为适应环境变化而修改软件
完善性维护 用户提出新的功能与性能要求 修改或再开发软件以扩充功能、增强性能
预防性维护 预先提高可维护性和可靠性 采用先进方法对软件进行重新设计、编码和测试

适应性 vs 完善性: 外部环境改变导致的维护→适应性维护;用户想要更多/更好导致的维护→完善性维护。

5.3 遗留系统处置

根据技术水平和业务价值两个维度,分四象限选择演化策略:

象限 技术与业务价值 策略
第一象限 高技术、高价值 改造策略(功能增强+数据模型改造)
第二象限 高技术、低价值 集成策略(对遗留系统进行集成)
第三象限 低技术、低价值 淘汰策略(重新开发新系统)
第四象限 低技术、高价值 继承策略(新系统完全兼容旧系统功能)

记忆口诀:该记陶吉(改造→集成→淘汰→继承,按逆时针顺序)

5.4 新旧系统转换

系统转换策略:直接转换、并行转换、分段转换。


六、项目管理

6.1 范围管理

5 个管理过程:编制范围管理计划 → 定义范围 → 创建工作分解结构(WBS) → 确认范围 → 范围控制

6.2 进度管理

关键概念:

  • AOV 网(单代号网络图): 顶点表示活动,弧表示活动之间的先后关系
  • AOE 网(双代号网络图): 顶点表示事件,弧表示活动

三点估算法:

\[期望时间 = \frac{乐观时间 + 4 \times 最可能时间 + 悲观时间}{6}\]

关键路径: 项目中耗时最长的路径,决定了项目的最短完工时间。

6.3 成本管理

3 个过程:成本估算 → 成本预算 → 成本控制

成本估算方法:自顶向下估算、自底向上估算、差别估算法

6.4 配置管理

过程 描述
编制配置管理计划 制订整个项目开发计划的一部分
配置标识 确定配置项,明确命名方式及描述信息
变更管理和配置控制 对配置项变更加以控制和管理
配置状态报告 记录、报告管理配置所需信息
配置审核 验证配置项对配置标识的一致性

6.5 风险管理

6 大过程:风险管理计划编制 → 风险识别 → 风险定性分析 → 风险定量分析 → 风险应对计划编制 → 风险监控

重点关注:风险管理计划编制、风险识别(选择题考察概率较高)


总结

领域 核心要点
软件工程概述 PDCA 循环、开发方法分类、生命周期模型、CMM/CMMI
需求工程 需求获取方法、结构化分析(DFD)、面向对象分析(用例图+类图)、UML
系统设计 面向对象设计原则(SOLID)、结构化设计(耦合+内聚)、设计模式
软件测试 黑/白盒测试、覆盖标准、性能测试辨析、测试模型
系统运行与维护 运维指标(MTTR/MTBF/MTTF)、维护四分类、遗留系统四象限
项目管理 范围管理(WBS)、进度管理(关键路径)、成本管理、配置管理、风险管理