软件工程

1. 软件工程概述

1.1 软件工程基本概念

软件定义:软件是计算机系统中与硬件相互依存的另一部分,包括程序、数据及其相关文档的完整集合。

软件的特点

  • 软件是一种逻辑实体,具有抽象性
  • 软件的生产与硬件不同,没有明显的制造过程
  • 软件在运行、使用期间不存在磨损、老化问题
  • 软件的开发、运行对计算机系统具有依赖性
  • 软件本身复杂,成本昂贵
  • 软件开发涉及诸多的社会因素

软件危机:是指在计算机软件的开发和维护过程中所遇到的一系列严重问题。

软件危机的表现

  • 软件开发进度难以预测
  • 软件开发成本难以控制
  • 软件产品质量无法保证
  • 软件产品难以维护
  • 软件开发生产率提高的速度跟不上计算机应用普及深入的趋势

软件工程定义:是指导计算机软件开发和维护的工程学科。采用工程的概念、原理、技术和方法来开发与维护软件,把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来,以经济地开发出高质量的软件并有效地维护它。

软件工程的三要素

要素说明
方法完成软件开发任务的技术方法
工具为软件工程方法提供自动或半自动的软件支撑环境
过程为了获得高质量的软件所需要完成的一系列任务的框架

1.2 软件生命周期

软件生命周期:是指软件产品从考虑其概念开始,到该软件产品不再使用为止的整个时期。

软件生命周期的阶段

阶段主要任务产出物
可行性分析确定软件的开发目标及其可行性可行性研究报告
需求分析确定软件系统的功能需求和非功能需求需求规格说明书
概要设计设计软件系统的总体结构概要设计说明书
详细设计对每个模块进行详细设计详细设计说明书
编码编写程序代码源程序代码
测试发现并纠正软件中的错误测试报告
维护对软件进行修改和完善维护文档

2. 软件过程模型

2.1 瀑布模型

瀑布模型:是将软件生命周期的各项活动规定为按照线性顺序连接的若干阶段工作,形如瀑布流水,最终得到软件产品。

瀑布模型的阶段

  1. 问题定义
  2. 可行性研究
  3. 需求分析
  4. 总体设计
  5. 详细设计
  6. 编码和单元测试
  7. 综合测试
  8. 软件维护

瀑布模型的特点

  • 阶段间具有顺序性和依赖性
  • 推迟实现的观点
  • 质量保证的观点

瀑布模型的优点

  • 强迫开发人员采用规范的方法
  • 严格地规定了每个阶段必须提交的文档
  • 要求每个阶段交出的所有产品都必须经过质量保证小组的仔细验证

瀑布模型的缺点

  • 缺乏灵活性。
  • 无法解决软件需求不明确或不准确的问题。
  • 用户只能通过文档了解产品,难以全面正确认识产品。

适用场景:需求明确、技术成熟、风险较低的项目。

2.2 原型模型

原型模型:是快速建立起来的可以在计算机上运行的程序,它所能完成的功能往往是最终产品能完成的功能的一个子集。

原型模型的类型

类型说明
探索型原型弄清用户对目标系统的要求,确定所期望的特性
实验型原型验证方案或算法的合理性,是在大规模开发和实现前,用于考查方案是否合适
演化型原型将原型作为目标系统的一部分,通过对原型的多次改进,逐步将原型演化成最终的目标系统

原型模型的优点

  • 有助于满足用户的真实需求
  • 减少由于软件需求不明确带来的开发风险
  • 用户参与软件开发过程,提高用户满意度

原型模型的缺点

  • 可能导致系统设计差、难以维护
  • 可能忽略非功能性需求
  • 可能诱导用户提出更多需求

适用场景:需求不明确、需要快速验证的项目。

2.3 增量模型

增量模型:是把待开发的软件系统模块化,将每个模块作为一个增量组件,从而分批次地分析、设计、编码和测试这些增量组件。

增量模型的特点

  • 系统被分解成多个增量构件
  • 每个增量构件都实现一定的功能
  • 增量构件逐步集成到系统中

增量模型的优点

  • 能在较短时间内向用户提交可完成部分工作的产品
  • 逐步增加产品功能可以使用户有较充裕的时间学习和适应新产品
  • 降低开发风险

增量模型的缺点

  • 要求系统架构具有良好的开放性
  • 增量构件的划分需要精心设计
  • 容易退化为边做边改模型

适用场景:需求基本明确,但希望分阶段交付的项目。

2.4 螺旋模型

螺旋模型:将瀑布模型和快速原型模型结合起来,强调了其他模型所忽视的风险分析,特别适合于大型复杂的系统。

螺旋模型的四个象限

  1. 制定计划:确定软件目标,选定实施方案,弄清项目开发的限制条件
  2. 风险分析:分析评估所选方案,考虑如何识别和消除风险
  3. 实施工程:实施软件开发和验证
  4. 客户评估:评价开发工作,提出修正建议,制定下一步计划

螺旋模型的优点

  • 强调风险分析,降低开发风险
  • 支持用户需求的动态变化
  • 结合了瀑布模型和原型模型的优点

螺旋模型的缺点

  • 风险分析需要专业的知识和经验
  • 过多的迭代次数会增加开发成本
  • 可能难以控制项目进度

适用场景:大型、复杂、高风险的项目。

2.5 喷泉模型

喷泉模型:是一种以用户需求为动力,以对象为驱动的模型,主要用于描述面向对象的软件开发过程。

喷泉模型的特点

  • 迭代性:各阶段之间可以反复迭代
  • 无间隙性:各阶段之间没有明显的界限
  • 增量性:系统功能逐步增加

适用场景:面向对象的软件开发。

2.6 统一过程(RUP)

RUP定义:Rational Unified Process,统一软件开发过程,是一个面向对象且基于网络的程序开发方法论。

RUP的四个阶段

阶段主要活动里程碑
初始阶段建立业务模型,定义项目范围生命周期目标里程碑
细化阶段分析问题领域,建立架构基础生命周期架构里程碑
构造阶段开发剩余构件,完成产品初始运作能力里程碑
移交阶段将产品移交给用户产品发布里程碑

RUP的核心工作流

  • 业务建模
  • 需求
  • 分析与设计
  • 实现
  • 测试
  • 部署
  • 配置与变更管理
  • 项目管理
  • 环境

RUP的特点

  • 用例驱动
  • 以架构为中心
  • 迭代和增量

2.7 敏捷开发方法

敏捷宣言的四个价值观

  1. 个体和交互胜过过程和工具
  2. 可以工作的软件胜过面面俱到的文档
  3. 客户合作胜过合同谈判
  4. 响应变化胜过遵循计划

敏捷开发的12条原则

  1. 最优先要做的是通过尽早的、持续的交付有价值的软件来使客户满意
  2. 即使到了开发的后期,也欢迎改变需求
  3. 经常性地交付可以工作的软件
  4. 业务人员和开发人员必须天天在一起工作
  5. 围绕被激励起来的个体来构建项目
  6. 在团队内部,最具有效果并且富有效率的传递信息的方法,就是面对面的交谈
  7. 工作的软件是首要的进度度量标准
  8. 敏捷过程提倡可持续的开发速度
  9. 不断地关注优秀的技能和好的设计会增强敏捷能力
  10. 简单——使未完成的工作最大化的艺术——是根本的
  11. 最好的架构、需求和设计出自于自组织的团队
  12. 每隔一定时间,团队会在如何才能更有效地工作方面进行反省

常见的敏捷方法

方法说明
Scrum迭代式增量软件开发过程,包括Sprint、每日站会、评审会等
XP(极限编程)强调测试先行、结对编程、持续集成等实践
精益开发消除浪费、延迟决策、快速交付
水晶方法根据项目规模和关键性选择适合的方法
特性驱动开发(FDD)以特性为驱动进行开发
动态系统开发方法(DSDM)强调时间和资源的固定
Scrum框架
元素说明
产品待办列表产品需求的优先级列表
Sprint固定时长的迭代周期(通常2-4周)
Sprint待办列表当前Sprint要完成的任务
每日站会每天15分钟的团队同步会议
Sprint评审向利益相关者展示成果
Sprint回顾团队反思改进
产品负责人负责产品需求和优先级
Scrum Master负责流程和移除障碍
开发团队自组织的跨职能团队

3. 需求工程

3.1 需求工程概述

需求工程定义:是应用已证实有效的技术、方法进行需求分析,确定客户需求,帮助分析人员理解问题,并定义目标系统的所有外部特征的一门学科。

需求工程的组成

活动说明
需求获取收集用户需求
需求分析分析和建模需求
需求定义编写需求规格说明书
需求验证验证需求的正确性
需求管理管理需求变更

3.2 需求分类

软件需求的分类

类型说明示例
功能需求系统必须完成的功能用户登录、数据查询
非功能需求系统的质量属性性能、安全性、可用性
业务需求高层次的目标要求提高业务效率
用户需求用户的目标和任务快速查询订单
系统需求系统的详细需求响应时间小于1秒
非功能需求的分类
类型说明
性能需求响应时间、吞吐量、并发用户数
安全需求身份认证、访问控制、数据加密
可用性需求系统可用时间、故障恢复时间
可靠性需求平均无故障时间、故障率
可维护性需求代码可读性、模块化程度
可移植性需求跨平台能力
易用性需求用户界面友好性、学习曲线

3.3 需求获取方法

方法说明适用场景
访谈与用户面对面交流获取用户的详细需求
问卷调查通过问卷收集需求用户分布广泛
观察观察用户的工作过程用户难以表达需求
原型通过原型获取反馈需求不明确
头脑风暴集体讨论产生需求创新需求
文档分析分析现有文档有现有系统或流程
用例分析通过用例描述需求面向对象开发

3.4 需求分析技术

结构化分析方法

  • 数据流图(DFD):描述数据在系统中的流动和处理过程
  • 数据字典:定义数据流图中的数据元素
  • 实体-关系图(E-R图):描述数据之间的关系
  • 状态转换图:描述系统的状态变化

面向对象分析方法

  • 用例图:描述系统功能和用户交互
  • 类图:描述系统的静态结构
  • 序列图:描述对象之间的交互
  • 活动图:描述业务流程
  • 状态图:描述对象的状态变化

3.5 需求规格说明书

需求规格说明书(SRS)的内容

  1. 引言
  2. 总体描述
  3. 系统特性
  4. 外部接口需求
  5. 非功能需求
  6. 其他需求

好的需求特征

  • 完整性
  • 一致性
  • 可修改性
  • 可追踪性
  • 可验证性

3.6 需求验证

需求验证的方法

  • 需求评审
  • 原型验证
  • 测试用例生成
  • 模型验证

需求验证的准则

  • 正确性
  • 无二义性
  • 完整性
  • 一致性
  • 可验证性
  • 可追踪性

3.7 需求变更管理

需求变更的原因

  • 业务环境变化
  • 对需求的理解加深
  • 技术变化
  • 利益相关者的要求

需求变更控制流程

  1. 提出变更请求
  2. 评估变更影响
  3. 审批变更请求
  4. 实施变更
  5. 验证变更

4. 软件设计

4.1 软件设计概述

软件设计定义:是将需求规格说明转化为软件实现方案的过程。

软件设计的阶段

  • 概要设计(总体设计):确定软件系统的总体结构
  • 详细设计:对每个模块进行详细设计

软件设计的原则

原则说明
模块化将系统分解为独立的模块
高内聚模块内部元素紧密联系
低耦合模块之间依赖程度低
信息隐藏隐藏模块的内部实现细节
抽象提取本质特征,忽略细节

4.2 内聚与耦合

内聚类型(从高到低)

类型说明
功能内聚模块完成单一功能
顺序内聚模块内元素顺序执行,前一元素的输出是后一元素的输入
通信内聚模块内元素操作相同的数据
过程内聚模块内元素按特定顺序执行
时间内聚模块内元素在同一时间段执行
逻辑内聚模块内元素执行相似的功能
偶然内聚模块内元素无关联

耦合类型(从低到高)

类型说明
无直接耦合模块之间无直接关系
数据耦合模块之间通过参数传递数据
标记耦合模块之间通过数据结构传递数据
控制耦合一个模块控制另一个模块的内部逻辑
外部耦合模块与外部硬件环境交互
公共耦合多个模块共享全局数据
内容耦合一个模块直接访问另一个模块的内部数据

4.3 结构化设计

结构化设计方法

  • 面向数据流的设计方法
  • 基于数据流图进行设计

数据流的类型

  • 变换流:数据经过一系列变换处理
  • 事务流:数据根据类型选择不同的处理路径

结构化设计的步骤

  1. 复查并精化数据流图
  2. 确定数据流图的类型
  3. 确定输入流和输出流的边界
  4. 完成”第一级分解”
  5. 完成”第二级分解”
  6. 优化

4.4 面向对象设计

面向对象设计原则(SOLID)

原则说明
单一职责原则(SRP)一个类只负责一个职责
开闭原则(OCP)对扩展开放,对修改关闭
里氏替换原则(LSP)子类可以替换父类
接口隔离原则(ISP)客户端不应该依赖它不需要的接口
依赖倒置原则(DIP)依赖抽象,不依赖具体

设计模式

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

4.5 软件架构设计

软件架构风格

风格说明
分层架构系统分为多个层次,每层为上层提供服务
客户端-服务器架构客户端请求服务,服务器提供服务
MVC架构模型-视图-控制器分离
微服务架构系统由多个独立的服务组成
事件驱动架构通过事件进行组件通信
管道-过滤器架构数据通过一系列处理步骤

软件架构评估

  • 场景-based评估方法(SAAM、ATAM)
  • 质量属性:性能、可用性、安全性、可修改性、可测试性、易用性

5. 软件测试

5.1 软件测试概述

软件测试定义:是为了发现错误而执行程序的过程。

软件测试的目的

  • 发现软件中的错误
  • 验证软件是否满足需求
  • 提供软件质量信息

软件测试的原则

  • 测试是为了发现错误,而不是证明没有错误
  • 不可能进行完全的测试
  • 测试应该尽早进行
  • 缺陷具有集群性
  • 杀虫剂悖论
  • 测试应该由独立的第三方进行

5.2 测试类型

按测试阶段分类

类型说明
单元测试测试单个模块或组件
集成测试测试模块之间的接口和交互
系统测试测试整个系统的功能和非功能需求
验收测试用户确认系统是否满足需求

按测试技术分类

类型说明
黑盒测试不考虑内部结构,基于需求规格进行测试
白盒测试考虑内部结构,基于代码进行测试
灰盒测试结合黑盒和白盒测试

按测试目的分类

类型说明
功能测试验证系统功能
性能测试测试系统性能
安全测试测试系统安全性
兼容性测试测试系统兼容性
可用性测试测试系统易用性
可靠性测试测试系统可靠性

5.3 黑盒测试方法

等价类划分

  • 将输入数据划分为若干个等价类
  • 从每个等价类中选取代表性数据作为测试用例

边界值分析

  • 选取边界值及其附近的值作为测试用例
  • 边界值往往是错误的高发区

决策表

  • 用于描述多个条件组合的情况
  • 列出所有条件组合及其对应的动作

因果图

  • 分析输入条件之间的因果关系
  • 生成判定表

错误推测

  • 基于经验推测可能出现的错误
  • 有针对性地设计测试用例

场景法

  • 基于用户场景设计测试用例
  • 适用于业务流程测试

5.4 白盒测试方法

语句覆盖

  • 使程序中的每条语句至少执行一次
  • 最弱的覆盖标准

判定覆盖(分支覆盖)

  • 使程序中的每个判定的取真分支和取假分支至少执行一次

条件覆盖

  • 使程序中每个判定的每个条件的可能取值至少执行一次

判定-条件覆盖

  • 同时满足判定覆盖和条件覆盖

条件组合覆盖

  • 使每个判定中条件的各种可能组合都至少出现一次
  • 最强的覆盖标准

路径覆盖

  • 使程序中的每条可能路径都至少执行一次

基本路径测试

  • 根据程序的控制流图计算环路复杂度
  • 确定基本路径集
  • 设计测试用例覆盖基本路径

McCabe环路复杂度

  • V(G) = E - N + 2(E为边数,N为节点数)
  • V(G) = P + 1(P为判定节点数)
  • V(G) = 区域数

5.5 测试用例设计

测试用例的组成

  • 测试用例ID
  • 测试目的
  • 前置条件
  • 输入数据
  • 预期结果
  • 实际结果
  • 测试状态

测试用例设计原则

  • 代表性
  • 可判定性
  • 可重复性
  • 独立性
  • 完整性

5.6 软件调试

软件调试的目的:确定错误的原因和位置,并改正错误。

调试方法

方法说明
蛮力法通过内存转储、打印语句等方式查找错误
回溯法从发现错误的地方开始,人工沿控制流往回追踪
原因排除法通过演绎或归纳,列出可能的原因,逐一排除

6. 软件维护

6.1 软件维护概述

软件维护定义:是在软件已经交付使用后,为了改正错误或满足新的需要而修改软件的过程。

软件维护的类型

类型说明占比
改正性维护诊断和改正软件中的错误20%
适应性维护使软件适应环境变化25%
完善性维护根据用户要求扩充功能和改进性能50%
预防性维护为了提高软件的可维护性和可靠性5%

6.2 软件可维护性

软件可维护性的定义:是指维护人员理解、改正、改动和改进该软件的难易程度。

影响可维护性的因素

因素说明
可理解性理解软件的难易程度
可测试性测试软件的难易程度
可修改性修改软件的难易程度
可移植性将软件移植到不同环境的难易程度
可重用性软件组件被重复使用的难易程度

提高可维护性的方法

  • 建立明确的软件质量目标
  • 使用先进的软件开发技术和工具
  • 建立明确的质量保证审查
  • 选择可维护的程序设计语言
  • 改进文档

6.3 软件再工程

软件再工程定义:是一类软件工程活动,它能够使人们:

  • 增进对软件的理解
  • 准备或直接提高软件的可维护性、可复用性或演化性

软件再工程的过程

  1. 库存目录分析
  2. 文档重构
  3. 逆向工程
  4. 代码重构
  5. 数据重构
  6. 正向工程

7. 软件项目管理

7.1 软件项目管理概述

软件项目管理的定义:是为了使软件项目能够按照预定的成本、进度、质量顺利完成,而对人员(People)、产品(Product)、过程(Process)和项目(Project)进行分析和管理的活动。

软件项目管理的4P

要素说明
人员(People)项目团队成员
产品(Product)要开发的软件产品
过程(Process)软件开发过程
项目(Project)项目的计划、跟踪和控制

7.2 项目估算

软件规模估算方法

方法说明
代码行(LOC)估算源代码行数
功能点(FP)基于软件功能进行估算
用例点(UCP)基于用例进行估算
故事点敏捷开发中的估算方法

功能点分析

组件类型复杂度权重
外部输入(EI)低:3, 中:4, 高:6
外部输出(EO)低:4, 中:5, 高:7
外部查询(EQ)低:3, 中:4, 高:6
内部逻辑文件(ILF)低:7, 中:10, 高:15
外部接口文件(EIF)低:5, 中:7, 高:10

成本估算方法

方法说明
专家判断基于专家经验进行估算
类比估算基于类似项目的历史数据进行估算
参数估算使用统计关系进行估算
三点估算使用最乐观、最可能、最悲观三个值进行估算
COCOMO模型构造性成本模型

COCOMO模型

  • 基本COCOMO:基于代码行数的粗略估算
  • 中级COCOMO:考虑成本驱动因素
  • 详细COCOMO:考虑各阶段的成本驱动因素

7.3 项目计划

项目计划的内容

  • 项目范围
  • 项目进度
  • 项目资源
  • 项目成本
  • 项目质量
  • 项目风险
  • 项目沟通

进度计划工具

工具说明
甘特图条形图,显示任务的开始、结束时间和持续时间
PERT图网络图,显示任务之间的依赖关系
关键路径法(CPM)确定项目的关键路径

关键路径

  • 网络图中最长的路径
  • 决定了项目的最短完成时间
  • 关键路径上的活动没有浮动时间

7.4 项目风险管理

风险的定义:是可能发生的事件,会对项目目标产生积极或消极的影响。

风险管理过程

过程说明
风险识别识别可能影响项目的风险
风险分析评估风险的概率和影响
风险应对制定风险应对策略
风险监控监控已识别的风险和新风险

风险应对策略

策略说明
规避消除风险或保护项目免受风险影响
转移将风险的影响和责任转移给第三方
减轻降低风险发生的概率或影响
接受接受风险,不采取任何措施

7.5 项目质量管理

软件质量定义:是软件满足规定或潜在用户需求的能力的特征和特性的总和。

软件质量模型(ISO/IEC 25010)

特性说明
功能性软件满足明确和隐含需求的能力
可靠性软件维持性能水平的能力
易用性软件被理解、学习、使用和吸引用户的能力
效率软件在指定条件下提供适当性能的能力
可维护性软件可被修改的能力
可移植性软件可从一种环境迁移到另一种环境的能力
兼容性软件与其他系统协同工作的能力
安全性软件保护信息和数据的能力

质量保证活动

  • 技术评审
  • 软件测试
  • 过程审计
  • 标准遵循

7.6 配置管理

软件配置管理(SCM)定义:是标识和确定系统中配置项的过程,在系统整个生命周期内控制这些配置项的投放和更动,记录并报告配置的状态和更动要求,验证配置项的完整性和正确性。

配置项

  • 需求文档
  • 设计文档
  • 源代码
  • 测试用例
  • 用户手册

配置管理活动

活动说明
配置项标识识别和命名配置项
版本控制管理配置项的不同版本
变更控制管理配置项的变更
配置审计验证配置项的完整性
配置状态报告报告配置项的状态

版本控制工具

  • Git
  • SVN
  • CVS
  • ClearCase

8. 软件过程改进

8.1 软件能力成熟度模型

CMM定义:Capability Maturity Model,能力成熟度模型,是用于评价软件机构的软件过程能力成熟度的模型。

CMM的五个成熟度等级

等级名称特征
1级初始级过程无序,成功依赖个人努力
2级可重复级建立了基本的项目管理过程
3级已定义级软件过程已文档化、标准化
4级已管理级软件过程可度量和控制
5级优化级持续过程改进

关键过程域(KPA)

等级关键过程域
2级需求管理、软件项目计划、软件项目跟踪与监控、软件子合同管理、软件质量保证、软件配置管理
3级组织过程焦点、组织过程定义、培训程序、集成软件管理、软件产品工程、组间协调、同行评审
4级定量过程管理、软件质量管理
5级缺陷预防、技术变更管理、过程变更管理

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

  • 集成了多个CMM模型
  • 提供了连续式和阶段式两种表示法
  • 增加了工程、采购等过程域

8.2 软件过程改进方法

PDCA循环

  • Plan(计划):制定改进计划
  • Do(执行):实施改进措施
  • Check(检查):评估改进效果
  • Act(处理):标准化或继续改进

IDEAL模型

  • Initiating(初始化):确定改进范围
  • Diagnosing(诊断):评估当前过程
  • Establishing(建立):制定改进计划
  • Acting(实施):执行改进措施
  • Learning(学习):总结经验教训

9. 考试真题精选

真题1:软件生命周期

软件生命周期中,确定软件系统的功能需求和非功能需求是在(需求分析)阶段完成的。

真题2:软件过程模型

瀑布模型)适用于需求明确、技术成熟的项目;(原型模型)适用于需求不明确的项目;(螺旋模型)适用于大型、复杂、高风险的项目。

真题3:敏捷开发

敏捷宣言强调:(个体和交互)胜过过程和工具;(可以工作的软件)胜过面面俱到的文档;(客户合作)胜过合同谈判;(响应变化)胜过遵循计划。

真题4:内聚与耦合

在软件设计中,应该追求(高内聚)、(低耦合)的模块结构。

真题5:测试覆盖

白盒测试中,(语句覆盖)是最弱的覆盖标准;(条件组合覆盖)是最强的覆盖标准。

真题6:McCabe复杂度

某程序的控制流图有10条边,8个节点,则其环路复杂度V(G) = (4)。

解析:V(G) = E - N + 2 = 10 - 8 + 2 = 4

真题7:软件维护

软件维护中,占比最大的是(完善性维护),约占(50%)。

真题8:CMM等级

CMM的五个成熟度等级从低到高依次为:(初始级)、(可重复级)、(已定义级)、(已管理级)、(优化级)。

真题9:功能点

功能点分析中,内部逻辑文件的复杂度权重为:低(7)、中(10)、高(15)。

真题10:项目管理

项目进度管理中,(关键路径)决定了项目的最短完成时间,关键路径上的活动浮动时间为(0)。