软件工程期末复习
重要PPT截图
耦合与内聚



软件维护







软件开发生命周期

软件过程模型

| 过程模型 | 驱动力 | 核心思想 | 适用场景 | 主要优点 | 主要缺点 |
|---|---|---|---|---|---|
| 瀑布模型 Waterfall | 文档驱动、阶段驱动 | 按照需求分析、设计、编码、测试、维护等阶段顺序推进,前一阶段完成后再进入下一阶段 | 需求明确、变更少、规模中等或偏小的项目 | 阶段清晰,文档规范,便于计划和管理 | 灵活性差,难以适应需求变化,问题往往到后期才暴露 |
| 快速原型模型 Rapid Prototyping | 用户反馈驱动、需求驱动 | 先快速构造一个可运行原型,让用户试用和反馈,再逐步明确需求 | 用户需求不清晰、需要反复确认界面或功能的项目 | 有助于澄清需求,降低需求理解偏差,用户参与度高 | 原型可能被误当成最终系统,容易忽视整体架构和质量 |
| 增量模型 Incremental | 功能交付驱动、增量驱动 | 将系统划分为多个增量,每次交付一部分可运行功能,逐步形成完整系统 | 需求可以分批实现、希望尽早交付部分功能的项目 | 可早期交付,风险分散,便于根据反馈调整后续功能 | 需要良好的总体架构设计,否则后续增量集成困难 |
| 螺旋式模型 Spiral | 风险驱动 | 将开发过程分成多轮循环,每轮都包含计划、风险分析、工程实现和客户评估 | 大型、复杂、高风险、需求可能变化的项目 | 强调风险分析,适合处理不确定性和高风险问题 | 管理复杂,成本较高,对风险分析能力要求高 |
| 喷泉模型 Fountain | 对象驱动、迭代驱动 | 面向对象开发中常用,强调各阶段之间可以迭代、重叠和回溯 | 面向对象系统、需求和设计需要反复调整的项目 | 支持迭代和复用,能体现面向对象开发的连续性 | 过程边界不如瀑布模型清晰,管理和控制难度较大 |
| Rational 统一开发过程 RUP | 用例驱动、架构驱动、风险驱动 | 以用例驱动、架构为中心、迭代增量式开发,通常分为初始、细化、构造、移交四个阶段 | 中大型软件项目,尤其是需要规范过程和架构控制的项目 | 过程完整,重视架构和风险控制,支持迭代开发 | 流程较重,文档和管理成本较高,小项目使用可能过于复杂 |
| 敏捷过程 Agile Process | 价值驱动、变化驱动、客户反馈驱动 | 通过短周期迭代、持续交付、客户协作和快速反馈来适应变化 | 需求变化快、交付节奏快、团队沟通顺畅的项目 | 响应变化快,客户参与度高,能持续交付可用软件 | 对团队自组织能力和客户参与要求高,不适合高度固定且强文档约束的场景 |
| 微软开发过程 Microsoft Process | 版本驱动、构建驱动、质量稳定驱动 | 强调小团队、并行开发、每日构建、持续集成和快速稳定产品 | 商业软件、版本迭代快、需要频繁构建和测试的项目 | 交付节奏快,重视构建和测试,便于快速发现集成问题 | 对工具链、配置管理和团队协作要求较高 |
快速原型和瀑布模型


| 对比维度 | 瀑布模型 | 快速原型模型 |
|---|---|---|
| 基本思想 | 按照需求分析、规格说明、设计、编码测试、综合测试、维护等阶段顺序推进,各阶段完成后进入下一阶段 | 先快速建立一个可运行的原型系统,让用户试用和验证,再根据反馈形成或修正规格说明 |
| 过程特点 | 实际瀑布模型并不是完全不能回退,而是带有反馈环;当后续阶段发现前面阶段的问题时,需要返回前面阶段修正产品,再继续后续任务 | 通过“快速原型—用户验证—规格说明—设计—编码测试—综合测试—维护”的过程,使需求在早期得到验证 |
| 反馈机制 | 图中实线箭头表示开发过程,虚线箭头表示维护过程;左侧反馈线表示发现错误后回到前面阶段修改 | 原型系统已经和用户交互并得到验证,因此可减少因需求规格说明错误造成的大量返工;开发人员也能通过原型学习系统特点 |
| 驱动方式 | 文档驱动、阶段驱动 | 用户反馈驱动、需求澄清驱动、快速验证驱动 |
| 文档要求 | 严格规定每个阶段必须提交文档,强调通过书面规格说明约束开发过程 | 前期更重视快速构造和验证原型,最终仍需要把经过验证的需求整理为规格说明文档 |
| 质量保证 | 要求每个阶段交出的产品都必须经过质量保证小组的仔细验证 | 原型可以帮助提前发现需求理解偏差,但若原型实现过于粗糙,可能带来质量隐患 |
| 对用户的要求 | 用户通常在早期提出需求,之后主要通过文档了解产品;要求用户一开始就提出完整、准确的需求 | 用户需要参与原型试用和反馈,用户与设计人员都是关键角色 |
| 对需求变化的处理 | 不适合需求频繁变化;如果用户使用软件后需求发生变化,最初的需求可能不再完全适用 | 适合项目开始前需求不明确、需要减少需求不确定性的情况 |
| 优点 | 迫使开发人员采用规范方法;每个阶段都有明确文档;阶段产品经过质量保证验证;遵守文档约束,便于后期维护 | 能尽早让用户看到可运行系统;有助于澄清需求;减少规格说明错误导致的大返工;设计和编码阶段出错可能性较小 |
| 缺点 | 交付可运行软件前,用户只能通过文档了解产品;静态规格说明难以准确描述动态软件;过度依赖书面说明可能导致最终产品不能真正满足用户需求 | 为了快而省,原型常采用折衷实现方案,质量问题较多;需要快速原型开发技术和工具;需要足够人力资源 |
| 适用条件 | 开发期间需求没有或很少变化;分析设计人员熟悉应用领域;项目风险低;目标和环境熟悉;用户使用环境稳定;用户除提出需求外很少参与开发 | 项目需求在开始前不明确;需要减少需求不确定性;需要通过用户试用来确认界面、交互或关键功能 |
| 适合项目 | 条件虽然严格,但软件企业开发新产品或新项目时仍常使用;系统软件和工具软件开发也常采用瀑布模型 | 小型或中等规模的交互式系统;大型系统的某些部分,例如用户界面;开发周期较短的系统 |
| 主要风险 | 需求错误发现较晚,后期返工成本高;文档正确不代表用户真实满意 | 原型可能被误认为最终产品;原型质量不足可能影响后续系统;团队需要掌握快速构造原型的能力 |
| 记忆要点 | “规范、文档、阶段、反馈环” | “快速、原型、用户验证、需求澄清” |
结构化分析

ER图





状态转换图



数据规范化的范式

数据库规范化的目的,是按照属性之间的依赖关系,把关系模式逐步分解得更合理,减少数据冗余,避免插入异常、删除异常和修改异常。常见考点主要是一范式、二范式、三范式。
| 范式 | 核心要求 | 主要解决的问题 | 判断重点 | 简单记忆 |
|---|---|---|---|---|
| 第一范式 1NF | 每个属性值都必须是原子值,不可再分 | 消除重复组和多值属性 | 表中每个单元格是否只存一个值 | 字段不可再拆 |
| 第二范式 2NF | 在满足 1NF 的基础上,每个非主属性必须完全依赖整个主键 | 消除非主属性对组合主键的部分依赖 | 如果主键由多个属性组成,非主属性是否只依赖其中一部分 | 非主属性必须依赖整个主键 |
| 第三范式 3NF | 在满足 2NF 的基础上,非主属性不能依赖其他非主属性 | 消除传递依赖 | 是否存在“主键 → 非主属性 A → 非主属性 B” | 非主属性不能依赖非主属性 |
第一范式强调“属性不可分”。例如有一个学生表:
| 学号 | 姓名 | 联系方式 |
|---|---|---|
| 001 | 张三 | 电话:13800000000,邮箱:zhang@example.com |
这个表不满足第一范式,因为“联系方式”里同时存了电话和邮箱,字段值不是原子的。可以改为:
| 学号 | 姓名 | 电话 | 邮箱 |
|---|---|---|---|
| 001 | 张三 | 13800000000 | zhang@example.com |
这样每个字段都只表示一个明确含义,电话和邮箱不能再作为一个混合字段存放,就满足了第一范式。
第二范式强调“完全依赖主键”,主要出现在组合主键的情况下。例如有一个选课表:
| 学号 | 课程号 | 姓名 | 课程名 | 成绩 |
|---|---|---|---|---|
| 001 | C01 | 张三 | 软件工程 | 90 |
| 001 | C02 | 张三 | 数据库 | 85 |
这个表的主键可以是“学号 + 课程号”。其中:
- 成绩依赖于“学号 + 课程号”,因为某个学生选某门课才有一个成绩。
- 姓名只依赖于学号,不依赖课程号。
- 课程名只依赖于课程号,不依赖学号。
因此,“姓名”和“课程名”只依赖组合主键的一部分,存在部分依赖,不满足第二范式。可以分解为:
| 学号 | 姓名 |
|---|---|
| 001 | 张三 |
| 课程号 | 课程名 |
|---|---|
| C01 | 软件工程 |
| C02 | 数据库 |
| 学号 | 课程号 | 成绩 |
|---|---|---|
| 001 | C01 | 90 |
| 001 | C02 | 85 |
分解后,学生姓名只放在学生表,课程名只放在课程表,选课表中只保留真正依赖“学号 + 课程号”的成绩,就满足第二范式。
第三范式强调“不能传递依赖”。例如有一个学生表:
| 学号 | 姓名 | 班级号 | 班主任 |
|---|---|---|---|
| 001 | 张三 | B01 | 李老师 |
| 002 | 李四 | B01 | 李老师 |
这个表中:
- 学号可以决定学生姓名和班级号。
- 班级号可以决定班主任。
- 因此存在“学号 → 班级号 → 班主任”的传递依赖。
“班主任”不是直接描述学生本身,而是由“班级号”决定的,所以它依赖了另一个非主属性“班级号”,不满足第三范式。可以分解为:
| 学号 | 姓名 | 班级号 |
|---|---|---|
| 001 | 张三 | B01 |
| 002 | 李四 | B01 |
| 班级号 | 班主任 |
|---|---|
| B01 | 李老师 |
分解后,学生表只保存学生自身信息和所属班级,班级表保存班级与班主任的关系,就消除了传递依赖。
三种范式的区别可以抓住这一条主线:
- 第一范式:看字段内部,一个字段不能存多个值。
- 第二范式:看组合主键,非主属性不能只依赖组合主键的一部分。
- 第三范式:看非主属性之间,非主属性不能再决定其他非主属性。
考试中判断范式时,可以按顺序检查:先看属性是否原子;再看是否有组合主键和部分依赖;最后看是否有传递依赖。
IPO图
- INPUT/PROCESS/OUTPUT(输入/处理/输出图)的简称。
- 能够方便地描述输入数据、输出数据和对数据的处理之间的关系。(适用任何系统)
- 需求分析阶段可以使用IPO图来简要地描述系统的主要算法。
- 符号即少又简单

软件需求的验证


重点作业题
COCOMO模型

答案:C。基本 COCOMO 模型计算得到的是“项目所需要的人月”,也就是软件开发工作量(Effort, PM)。
COCOMO(Constructive Cost Model,构造性成本模型)是一种用于估算软件项目工作量、开发时间和人员需求的经验模型。它的核心思想是:先根据软件规模估算开发所需工作量,再由工作量进一步推算开发周期和平均人员数。
基本 COCOMO 模型主要根据代码规模 KLOC(千行代码)和项目类型来估算工作量,常见形式为:
其中,$E$ 表示开发工作量,单位是人月;$KLOC$ 表示千行代码;$a$ 和 $b$ 是由项目类型决定的经验系数。
COCOMO 中常见的项目类型有三类:
- 组织型:项目规模较小,开发人员经验丰富,需求比较稳定。
- 半独立型:项目规模和复杂度中等,团队经验和约束条件也处于中等水平。
- 嵌入型:项目复杂度高,受硬件、实时性、安全性等强约束影响较大。
基本 COCOMO 模型先求出的是工作量,即“需要多少人月”。例如 10 人月可以理解为 1 个人做 10 个月,或者 5 个人做 2 个月,但实际项目中还要考虑沟通、管理和任务划分,所以不能简单认为增加人数就一定能等比例缩短时间。
本题中,A 选项“最多设备数量”和 D 选项“交通成本”都不是 COCOMO 的估算对象;B 选项“最长时间”也不准确,因为开发时间通常是在估算出人月之后再进一步推导出来的。因此,基本 COCOMO 模型计算得到的是项目所需要的人月,选 C。
CMM等级

答案:B。该公司最可能处于 CMM 2 级,即可重复级。
CMM(Capability Maturity Model,能力成熟度模型)用于评价软件组织的软件过程成熟度。它关注的不是某一个程序写得好不好,而是整个组织在软件开发、项目管理、质量控制等方面是否形成了稳定、可管理、可改进的过程。
CMM 通常分为五个等级:
- 1 级,初始级:软件过程混乱,项目成功主要依赖个人能力和临时发挥,缺乏稳定的管理方法。
- 2 级,可重复级:组织能够借鉴以往类似项目的经验,对新项目进行基本的计划、跟踪和管理,因此在相似项目中可以重复以前的成功经验。
- 3 级,已定义级:组织已经建立并文档化了标准的软件过程,各项目按照统一的软件过程进行开发和管理。
- 4 级,已管理级:能够使用定量数据度量和控制软件过程,例如用统计方法管理质量和进度。
- 5 级,优化级:能够持续改进软件过程,通过缺陷预防、技术创新和过程优化不断提高开发能力。
题干中的关键信息是“能够利用以往项目上的经验对新项目进行策划和管理”,这说明公司已经具备一定的项目管理能力,不是完全依赖个人发挥的初始级;但题干又说“尚未定义软件过程”,说明它还没有形成组织级、标准化、文档化的软件过程,因此没有达到 CMM 3 级。符合这一特征的是 CMM 2 级可重复级,所以选 B。
估算单位

答案:B。功能点、用例点都是常用的软件规模估算单位。
功能点(Function Point, FP)和用例点(Use Case Point, UCP)都是用来描述软件“有多大”的规模度量方法。它们关注的是软件需要实现多少功能、系统边界内外有多少交互、业务复杂度有多高,而不是直接计算需要多少人、花多少钱或做多久。
功能点通常根据输入、输出、查询、内部逻辑文件、外部接口文件等功能数量来估算软件规模;用例点则主要根据用例数量、参与者复杂度、技术因素和环境因素来估算软件规模。二者都常用于项目早期,因为此时可能还没有代码行数,但已经能够根据需求或用例初步判断软件规模。
常见估算对象与单位如下:
| 估算对象 | 常用单位 | 含义 |
|---|---|---|
| 软件规模估算 | 功能点 FP、用例点 UCP、代码行 KLOC | 衡量软件系统的大小或功能数量 |
| 工作量估算 | 人月 PM、人日、人时 | 衡量完成项目需要投入多少人力 |
| 进度估算 | 月、周、天 | 衡量项目开发需要持续多长时间 |
| 成本估算 | 元、万元、美元等货币单位 | 衡量项目需要投入多少经费 |
本题中,功能点和用例点都不是工作量单位,因为工作量通常用人月、人日表示;也不是进度单位,进度通常用时间表示;更不是成本单位,成本通常用金额表示。因此功能点、用例点属于软件规模估算单位,选 B。
动态多变量模型与静态单变量模型

答案:B。动态多变量模型比静态单变量模型增加了“开发时间”这个变量对工作量的影响。
静态单变量模型和动态多变量模型都可以用于软件项目工作量估算,但二者考虑的因素不同:
静态单变量模型:
- 主要根据一个变量估算工作量,最常见的是软件规模。
- 典型形式可以理解为:软件规模越大,所需工作量越大。
- 它没有重点考虑开发时间对工作量的影响。
动态多变量模型:
- 不只考虑软件规模,还考虑多个因素对工作量的影响。
- 其中一个重要变量是开发时间。
- 开发时间会影响工作量,因为项目周期过短时,需要更多人员并行开发,沟通、协调和管理成本也会上升;项目周期较合理时,工作量安排会更加平稳。
各选项分析如下:
- A 软件规模:软件规模本来就是工作量估算中最基本、最常见的因素,静态单变量模型通常已经考虑它,所以不是“增加”的变量。
- B 开发时间:动态多变量模型会考虑开发时间对工作量的影响,这是相对于静态单变量模型新增的重要因素,所以正确。
- C 开发语言:开发语言可能影响开发效率,但不是本题强调的动态多变量模型相对静态单变量模型增加的核心变量。
- D 开发环境:开发环境也可能影响效率,但不是该模型区别中的关键变量。
因此,本题应选 B。
Brooks定律

答案:D。根据 Brooks 定律,随着开发小组规模扩大,个人生产率将下降。
Brooks 定律常见表述是:“向已经延期的软件项目中增加人手,只会使项目更加延期。”它强调的是软件开发不是简单的人力叠加问题,团队人数增加以后,沟通、协调、培训和管理成本都会上升,因此每个人的平均生产率可能下降。
可以从以下几个方面理解:
沟通成本增加:
- 团队人数越多,成员之间需要沟通和协调的关系越多。
- 沟通关系数量大致会随人数平方级增长,而不是线性增长。
- 因此,更多时间会被用于会议、同步、接口协调,而不是直接开发。
新成员需要培训:
- 新加入的开发人员需要熟悉需求、设计、代码结构和开发规范。
- 原有成员需要花时间指导新人,这会占用原本的开发时间。
- 短期内增加人手不一定能提高产出,甚至会降低整体效率。
任务不可完全并行:
- 软件开发中有些任务存在先后依赖,不能简单拆给更多人同时完成。
- 如果任务之间接口复杂,人数增加还可能带来更多集成问题。
各选项分析如下:
- A 不确定是否会变化:Brooks 定律明确指出团队规模扩大可能导致个人生产率下降,因此不选。
- B 保持不变:忽略了沟通和管理成本增加的影响,因此不选。
- C 提高:这只适合可以高度并行、沟通成本很低的工作,不符合 Brooks 定律对软件项目的判断。
- D 下降:团队规模扩大后,协调成本和培训成本上升,个人平均生产率下降,正确。
因此,本题应选 D。
软件可靠性度量指标

答案:A。系统平均无故障时间属于软件可靠性度量指标。
软件可靠性是指软件在规定条件下、规定时间内完成规定功能的能力。可靠性度量关注的是软件运行过程中是否容易发生故障、故障间隔有多长、发生故障后能否快速恢复。
常见的软件可靠性相关指标如下:
MTTF(Mean Time To Failure,平均无故障时间):
- 表示系统从开始正常运行到发生故障之前的平均时间。
- MTTF 越长,说明系统平均能稳定运行的时间越久,可靠性越高。
- 本题中的“系统平均无故障时间”就是 MTTF,因此属于软件可靠性度量指标。
MTTR(Mean Time To Repair,平均修复时间):
- 表示系统发生故障后,从开始维修到恢复正常所需的平均时间。
- MTTR 越短,说明系统故障恢复越快,可维护性越好。
- 它常与可靠性、可用性一起分析。
MTBF(Mean Time Between Failures,平均故障间隔时间):
- 表示两次相邻故障之间的平均时间。
- 对可修复系统来说,通常有:MTBF = MTTF + MTTR。
- MTBF 越大,说明系统发生故障的频率越低。
故障率:
- 表示单位时间内系统发生故障的概率或次数。
- 故障率越低,软件运行越稳定,可靠性越高。
可用性:
- 表示系统在需要使用时处于可正常运行状态的概率。
- 常见公式为:可用性 = MTTF / (MTTF + MTTR)。
- 它不仅与无故障运行时间有关,也与故障后的修复速度有关。
各选项分析如下:
- A 系统平均无故障时间:衡量系统平均能无故障运行多久,属于可靠性度量指标,正确。
- B 软件代码行数:衡量软件规模,不是可靠性指标。
- C 软件年销售量:属于市场或经营指标,不是软件质量或可靠性指标。
- D 系统稳定运行的天数:可以反映运行情况,但它不是常见的标准可靠性度量指标;标准说法通常是平均无故障时间、平均故障间隔时间、故障率等。
因此,本题应选 A。
软件维护类型占比











