1.教材上的主要知识点 1.1 软件的概念
- 软件:计算机软件指计算机中的程序、文档及数据
- 软件工程:将
系统化的、严格约束的、可量化的
方法应用于软件的开发、运行和维护,也就是将工程化应用于软件
- 软件生存周期:软件有一个
孕育
、诞生
、成长
、成熟
、衰亡
的生存过程 - 软件生存周期大体可分为如下六个活动:
计算机系统工程
、需求分析
、设计
、编码
、测试
、运行和维护
- 能力成熟度模型:
- 初始级:无序、混乱,几乎所有的过程都没有经过妥善的定义
- 可重复级:制定了基本的项目管理过程,已做过的项目能够重复实现
- 已定义级:定义了管理和工程活动的软件过程,并将之文档化和标准化
- 已管理级:对软件过程和产品实现了量化管理和控制
- 优化级:新思想和新技术、量化反馈推动软件过程不断改进
- 最早出现的软件模型,一般不单独使用,可在演化、迭代模型中应用
- 特征:
- ①接受上一阶段的结果作为本阶段的输入
- ②利用这一输入实施本阶段应完成的任务
- ③对本阶段工作进行评审
- ④将本阶段的结果作为输出,传递给下一阶段
- 缺点:
- ①缺乏灵活性,难以适应
需求不明确
或者需求经常变化
的软件开发 - ②开发早期存在的问题往往要到交付使用时才发现,维护代价大
- 基于计算机的系统:通过处理信息来完成某些预定义目标而组织在一起的元素的集合
- 主要元素:
软件
,硬件
,人员
,数据库
,文档和规程
- 定义:用户对目标软件系统在
功能
、性能
、设计约束
等方面的期待 - 具体内定:
- 功能需求:系统要做什么、何时做,如何修改或升级等
- 性能需求:技术性指标,如存储容量、执行速度、响应时间,吞吐量等
- 用户或人的因素:用户的类型,如使用计算机的熟练程度,需要接受的培训、用户理解使用系统的难度、用户错误操作的可能性等
- 环境需求
- 界面需求
- 文档需求
- 数据需求
- 资源使用需求
- 安全保密需求
- 可靠性需求
- 成本与开发进度需求、其他非功能性需求
- 面向数据流的结构化分析方法(SA)
- 面向数据结构的分析方法
- 面向对象的分析方法(OOA)
- 软件设计的任务:使用一个设计方法,软件分析模型中通过
数据
、功能
、行为模型
所展示的软件需求信息
被传递给设计阶段,产生数据/类设计、体系结构设计、接口设计、部件级设计 - 数据/类数据
- 将分析类模型变换成
类的实现
和软件实现所需的数据结构
- 基础:类、由CRC中定义的数据对象和关系、数据字典中描述的详细数据内容
- 数据结构是数据的各个元素之间逻辑关系的一种表示,数据结构的设计应确定数据的组织、存储方式、相关程度以及信息的不同处理方法
- 无论采取什么样的设计方法,如果数据结构设计得很好,往往能产生很好的软件系统结构,具有很强的模块独立性和较低的程序复杂度。
清晰的数据结构
是软件开发成功的关键。 - 数据设计的过程
- 在为需求分析阶段所确定的数据对象选择逻辑表示,需要对不同结构进行算法分析,以便选择一个最有效的设计方案
- 确定对逻辑数据结构所必需的那些操作的程序模块,以便限制或限定各个数据设计决策的影响范围
- 将分析类模型变换成
- 体系结构设计
- 体系结构定义了
软件的整体结构
,由软件部件
、外部可见的属性
和它们之间的关系
组成 - 体系结构设计表示可以从
系统规约
、分析模型
、和分析模型中定义的子系统
交互中导出
- 体系结构定义了
- 接口设计
- 定义:接口设计描述了软件内部、软件和协作系统之间以及软件同人之间的通信方式
- 主要内容:设计
模块间的接口
、设计模块与其他非人的信息生产者和消费者(如外部实体)之间的外部接口
以及设计人(用户)与计算机间的人机接口
- 外部接口设计起始于对分析模型的每个外部实体的评估;外部实体的数据和控制需求确定下来后,就可以设计外部接口了
- 部件级设计
- 定义:将软件体系的结构的结构性元素变换为对软件部件的过程性描述
- 基础:类为基础的模型、流模型、行为模型
- 制定规范
- 体系结构和接口设计
- 数据/类设计
- 部件级(过程)设计
- 编写设计文档
- 设计评审
- 模块的定义
- 定义:在软件工程中,模块是数据说明、可执行语句等程序对象的集合,是单独命名的,并且可以通过名字来访问的。
对象类、构件、过程、函数、子程序、宏等
都可以作为模块使用 - 模块具有
名字
、参数
、功能
等外部特征,及完成功能模块的程序代码和模块内部数据等内部特征
- 定义:在软件工程中,模块是数据说明、可执行语句等程序对象的集合,是单独命名的,并且可以通过名字来访问的。
- 模块化的定义:把软件按照规定原则,划分为一个个较小的、相互独立的但又相互关联的部件,模块化实际上是
系统分解
和抽象
的过程
- 定义:每个模块的实现细节对于其他模块来说应该是隐蔽的,模块中包含的信息(包括数据和过程)不允许其他不需要这些信息的模块来使用
- 隐蔽的不是模块的所有信息而是模块的实现细节。通过信息隐藏来定义和实现对模块的过程细节和局部数据结构的存取限制
- 内聚的概念:是指同一个模块内部的各个元素彼此结合的紧密程度,是衡量功能独立的指标
- 耦合的概念:耦合度是指不同模块彼此间相互依赖的紧密程度
- 耦合与内聚都是功能独立性的
定性
标准,都反映独立性的良好程度,但耦合是直接的主导因素,内聚则辅助耦合,共同对功能独立性进行衡量
1.14 数据耦合的概念 数据耦合:指的是两个模块之间仅通过参数表传递简单数据
1.15 程序流程图、判定表
- 判定表
- 条件桩:列出各种条件的对象,每行写一个条件对象
- 条件条目:列出各件对象的取值,条件条目的每一列表示了一个可能的条件组合
- 动作桩:列出所有可能采取的动作,每行写一个动作
- 动作条目:列出各种条件组合下应采取的动作
- 结构化分析
- 数据字典:模型核心,描述软件使用和产生的全部数据
- 数据流图:功能建模,描述系统的输入数据如何经过加工,一步一步变成输出数据
- 实体-关系图(E-R图):数据建模,描述数据字典中数据的关系
- 状态转换图:行为建模,描述系统接受哪些外部数据,以及外部事件的作用下系统状态的转移
- 结构化分析的结果
- 一套分层的数据流图
- 一本数据字典(包括数E-R图)
- 一组加工规约以及其他材料补充
- 数据流图DFD
- 基本元素:
数据流
、加工
、文件
、宿
- 数据流:一组有序的(有起点和终点的)数据序列,由一组固定成分的数据组成,DFD图中的每一个数据流必须用一个定义明确的名字标识,
对于流入文件或者从文件流出的数据流,由于它们代表文件的一个记录,意义明确,不需要为它们命名
- 加工:一个变换,将输入数据流变成输出数据流,加工描述了输入数据流到输出数据流的变换
- 文件:文件用于存放数据。每个文件用一个定义明确的名字标识
- 宿:通常指存在于系统之外的人员或组织,表示系统输入数据的来源或输出数据的去向,因此也称为源点或终点
- 数据流图的扩充符号:
- 星号(*):"与"关系,即数据流必须全部到达后才能开始
- 加号(+):"或"关系,即数据流有任意一个到达后就能开始
- 异或:当且仅当其中一个到达才能开始
- 层次结构
- 顶层图:
只有一张图
且只有一个加工
,该加工代表整个软件系统
,描述系统与外界的数据流 - 0层图:顶层图中的加工经分解后的图,也只有一张图
- 底层图:处于分层数据流图最底层的图,底层图中的所有加工不再分解
- 中间层图:处于0层和底层图之间的图,至少有一个图的加工的可以继续分解
- 基本加工:在整套分层数据流图中,不再分解成子图的加工
- 顶层图:
- 每张子图只能对应一张父图
- 图和加工的编号
- 顶层图不编号,其唯一的一个加工也不编号
- 0层图不编号,图中加工依次编号为1,2,3,4,5
- 剩余图层:若某一子图由其父图中加工号为x的加工分解而成,则该子图号为x,该子图中的加工标记为x.1,x.2,…,x.n
- 记录为字典顺序+继承方法
- 基本元素:
- 分层数据流图的画法
- 画出系统的输入和输出
- 确定源和宿:系统从外部的哪些源获取输入数据流,以及系统的哪些输出数据流输出到哪些外部的宿
- 确定加工(只有一个,就是系统)
- 确定数据流
- 画出系统的内部结构
- 将顶层图中的加工分解成若干加工,并用一些
新定义的数据流
连接,使得系统的输入数据流经过一系列加工处理后,变化成输出数据流,也就是画出0层图- 确定加工:根据功能分解来确定加工(一般用于高层加工的分解),根据业务处理来确定加工(一般用于底层加工的分解)
- 确定数据流
- 确定文件
- 确定源和宿
- 画出内部结构
- 采用画第零层图方法
- 重复第三步,直到所有加工都变成基本加工
- 数据流图的审查
- 分层数据流图的一致性和完整性
- 一致性指的是不存在矛盾和冲突
- 完整性指的是本身的完整性,也就是是否有遗落的加工和数据流
- 一致性
- 父图与子图的一致性:指任何一种DFD子图边界上的输入输出流必须与其父图中对应加工的输入输出流保持一致
- 数据守恒:加工所有的输出流数据中的数据,必须能从该加工的输入流数据中直接或者经处理
- 局部文件:任何一个文件都应有写入的数据流和读取的数据流
- 数据流异名:一个加工的输入数据流不能和该加工的输出数据流同名
- 完整性
- 每个加工至少有一个输入流和一个输出流
- 在整套分层数据流图中,每个文件至少有一个加工写入,一个加工读取
- 分层数据流图中的每一个数据流和文件都必须命名(除了流入文件和流出文件的数据流),并且与数据字典一致
- 分层DFD图的每一个基本都应有一个加工规约
- 分层数据流图的一致性和完整性
- 画出系统的输入和输出
- 数据字典
- 数据字典是指对数据的数据项、数据流、文件、加工、源或宿等进行的定义和描述,其目的是对数据流程图中的各个元素做出详细的说明
- 字典条目的详细说明
- 数据流条目:数据流名=数据流组成
- 文件条目:文件名=文件组成
- 数据项条目:数据类型+计量单位+取值范围
- 加工条目:加工名、加工号、简述、加工逻辑
- 源或宿条目:源或宿的名称、简要描述
- 别名条目:别名的名称、类型、基本名、说明
- 结构化设计(SD)是将结构化分析得到的数据流图映射成软件体系结构的一种设计方法
- 结构图
- 定义:指以模块的调用关系为线索,用自上而下的连线表示调用关系并注明参数传递的方向和内容,从宏观上反映软件层次结构的图形
- 基本成分
- 模块:指具有一定功能并可以用模块名调用的一组程序语句(如函数、子程序等),它是组成程序的基本单元
- 调用:模块之间的调用关系用从一个模块指向另一个模块的箭头来表示,含义为前者调用后者
- 数据:模块调用传递的数据可以通过调用箭头旁加一个小箭头和数据名来表示,小箭头表示响应数据传递的方向
- 深度:指结构图中控制的层数
- 宽度:指结构图中同一层次上模块总数的最大值
- 扇出:指该模块直接调用的模块数目,该模块有多少出边
- 扇入:指能直接调用该模块的模块数目,该模块有多少入边
- 定义:指以模块的调用关系为线索,用自上而下的连线表示调用关系并注明参数传递的方向和内容,从宏观上反映软件层次结构的图形
- 启发式设计策略
- 降低耦合度,提升内聚度
- 避免高扇出,随着深度的增加,力求高扇入
- 模块的影响范围应该限制在该模块的控制范围内
- 降低模块接口的复杂程度和冗余程度,提高一致性
- 模块功能应该是可预测的,避免对模块施加过多的限制
- 尽可能设计单入口和单出口的模块
1.18 标识符命名需要注意的问题
- 选择含义明确的名字,使其能正确提示标识符所代表的实体
- 名字不要太长,太长会增加打字量,而且容易出错
- 必要时可使用缩写,缩写规则要一致并加注释
- 不用相似的名字,相似的名字容易混淆,不易发现错误
- 通常嵌在源程序体内,主要描述程序段的功能
- 注解要正确,错误的注解比没有注解要更坏
- 为程序段作注解,而不是为每一个语句作注解
- 用缩进和空行,使程序与注释容易区分
- 注解应提供一些从程序本身难以得到的信息,而不是语句的重复
- 一个测试用例由测试输入数据和预期结构组成,测试时通过输入数据,运行被测程序,如果运行的实际输出与预期结果不一致,则表明发现了程序中的错误
- 发现软件的错误和缺陷,并加以纠正
- 白盒测试
- 称为结构测试,把测试对象看作一个透明的盒子
- 测试人员根据程序内部的逻辑结构以及有关信息设计测试用例
- 检查程序中所有的逻辑路径是否都按照要求正确地工作
- 白盒测试方法
- 逻辑覆盖测试
- 基本路径覆盖测试
- 数据流测试
- 循环测试
- 覆盖标准
- 语句覆盖
- 判定覆盖
- 条件覆盖
- 判定-条件覆盖
- 条件组合覆盖
- 路径覆盖
- 语句覆盖:每个可执行语句都至少执行一次
- 判定覆盖(分支覆盖):每个判定的所有可能结果都至少执行一次(即判定的每个分支都至少经过一次)
- 判定覆盖将每个判定的所有可能结果都至少执行一次,程序中所有语句也必定至少执行一次
- 满足判定覆盖标准的测试用例也一定满足语句覆盖标准
- 条件覆盖:是指选择足够的测试用例,使得运行这些测试用例时,被测程序的每个判定中的每个条件的所有可能结果都至少出现一次
- 通常,
条件覆盖
比判定覆盖
强 - 有时虽然每个条件的所有可能结果都出现过,但判定表达式的某些可能结果并未出现过
- 通常,
- 判定/条件覆盖:是指选择足够的测试用例,使得运行这些测试用例时,被测程序的每个判定的所有可能结果都至少执行一次,并且,每个判定中的每个条件的所有可能结果都至少出现一次
- 满足判定/条件覆盖标准的测试用例也一定满足判定覆盖、条件覆盖、语句覆盖标准
- 条件组合覆盖:是指选择足够的测试用例,使得运行这些测试用例时,被测程序的每个判定中条件结果的所有可能组合都至少出现一次
- 满足条件组合覆盖标准的测试用例一定也满足判定覆盖、条件覆盖、判定/条件覆盖、语句覆盖标准
- 条件组合覆盖是上述五种覆盖标准中最强的一种
- 条件组合覆盖仍不能保证程序中所有可能的路径都被覆盖
- 路径覆盖是指选择足够的测试用例,使得运行这些测试用例时,被测程序的每条可能执行到的路径都至少经过一次(如果程序中包含有环路,则要求每条环路都至少经过一次)
- 路径覆盖实际上考虑了程序中各种判定结果的所有可能组合,但它未必能覆盖判定中条件结果的各种可能情况
- 路径覆盖是一种比较强的覆盖标准,但不能代替条件覆盖、判定/条件覆盖和条件组合覆盖标准
- 基本路径测试
- 测试方法
- 根据程序或者设计图画出控制流图
- 计算其区域数
- 确定一组独立的程序执行路径(称为基本路径)
- 为每一条基本路径设计一个测试用例
- 根据程序或者设计图画出控制流图
- 如果设计图的判定包含了复合条件,那么必须先将其转换成等价的简单件设计图
- 把流图中由结点和边组成的闭合部分称为一个区域,在计算区域数时,图的外部部分也作为一个区域
- 独立路径是指程序中至少引进一个新的处理语句序列或者一个新条件的任一路径
- 【华南农大习题与考试|软件工程复习提纲】独立路径的数目就是流图的区域数
- 测试方法
- 是指输入域的某个子集,该子集中的每个输入数据对揭露软件中的错误都是等效的,测试等价类的某个代表值就等价与这一类其他值的测试
- V模型
- 系统工程->系统测试
- 需求分析->确认测试
- 设计->集成测试
- 编码->单元测试
- 单元测试
- 内容:接口、局部数据结构、边界条件、所有独立路径、错误处理路径,,,,,,,,,,,,,,
- 模块接口:确保模块的输入/输出参数信息是正确的
- 局部数据结构:确保临时存储的数据在算法执行的整个过程都能维持其完整性
- 边界条件:确保程序单元在极限或严格条件的情况下仍能正确地执行
- 所有独立路径:确保模块中所有语句都至少执行一次。程序执行的路径实际上体现了计算的过程
- 错误处理路径:单元测试应该对所有的错误处理路径进行测试
- 桩模块:替代被测模块调用的模块(专注于当前测试的模块),它接受被测模块的调用,验证入口信息,把控制连同模拟结果返回被测模块
- 集成测试(组成测试、联合测试)
- 经单元测试后,每个模块都能独立工作,但把它们放在一起往往不能正确工作,推测依据:
- 数据可能在通过接口时丢失
- 一个模块可能对另一个模块产生非故意的、有害的影响
- 当子功能被组合起来时,可能不能达到期望的主功能
- 单个模块可以接受的不精确性(如误差),连接起来后可能会扩大到无法接受的程度
- 全局数据结构可能存在问题
- 任务:使得能够独立工作的模块在集成之后能够完成主功能
- 非增量式集成测试
- 将程序看做一个整体
- 增量式集成测试
- 自顶向下集成
- 从主控模块(主程序)开始,然后按照程序结构图的控制层次,将直接或间接从属于主控模块的模块按照深度优先、广度优先的方式逐个集成到整个结构中,并对其进行测试
- 自顶向下集成在测试一个模块时,它的上层模块(已测试过)可用作它的驱动模块
- 步骤
- 主控程序(主程序)被直接用作驱动程序,所有直接从属于主控模块的模块用桩模块替换,然后对主控模块进行测试
- 根据集成的实现方式(深度优先或者广度优先),下层的桩模块依次一个地替换成真正的模块,从属于该模块的模块用桩模块,然后对其进行测试
- 用回归测试来保证其没有错误
- 自底向上集成
- 从程序结构的最底层模块(即原子模块)开始,然后按照程序结构图控制层次将上层模块不断集成到整个结构中,并对其进行测试
- 自底向上测试不需要桩模块
- 步骤
- 将低层模块组合成能实现软件特定功能的簇
- 为每个簇编写驱动程序,并对簇进行测试
- 移走驱动程序,用簇的直接上层模块替换驱动程序,然后沿着程序结构层次向上组合新的簇
- 凡对新的簇测试后,都要进行回归测试,以保证没有引入新的错误
- 关键模块:
- 与多个软件需求有关
- 含有高层控制(位于程序结构的高层)
- 本身是复杂的或者是容易出错的
- 含有确定的性能需求
- 自顶向下集成
- 经单元测试后,每个模块都能独立工作,但把它们放在一起往往不能正确工作,推测依据:
- 回归测试
- 对已经进行过测试的测试用例子集的重新测试,以确保对程序的改变和修改,没有传播非故意的副作用
- 测试集
- 能测试软件所有功能的代表性测试用例
- 专门针对可能会被修改影响的软件功能的附加测试
- 注重于修改过的软件模块测试
- 确认测试
- 任务:确认测试以软件需求规约为依据,以发现软件与需求不一致的错误
- 内容:主要检查软件是否实现了规约规定的
- 全部功能要求
- 文档资料是否完整、正确、合理
- 其他的需求,如可移植性、可维护性等
- 软件配置评审
- 系统测试
- 任务:基于计算机的系统进行一系列的测试
- 内容:恢复测试、安全保密性测试、压力测试、性能测试
- 压力测试
- 强制测试,是在一种需要非正常数量、频率、容量的方式下执行系统
- 目的是检查系统对非正常情况的承受程度
- 性能测试
- 测试软件在集成的系统中的运行性能
- 对实时系统和嵌入式系统尤为重要
- 为了改正软件系统中的错误,使软件能够满足预期的正常运行状态的要求而进行的维护
- 为了使软件适应内部或外部环境变化,而去修改软件
- 满足使用过程中用户提出增加新功能或修改已有功能的建议维护
- 可维护性:指理解、改正、调整和改进软件的难易程度
- 可理解性
- 可测试性
- 可修改性
- 可移植性
- 确定质量管理目标和优先级
- 规范化程序设计风格
- 选择可维护性高的程序设计语言
- 改进程序文档
- 保证软件质量审查方法
推荐阅读
- 后端开发|ThreadPoolExecutor源码剖析
- 期末专栏|软件工程期末复习
- Python在Django中上传图片开发示例
- 华南农大习题与考试|操作系统(10)多处理器调度和实时调度
- 何时使用Django(与其他开发栈的比较)
- 如何为亚马逊软件开发工程面试做准备()
- 如何在PHP中进行重定向(代码实现)
- Java编程后端开发小书架!毛遂自荐
- 软件工程师必备Linux命令(ls cd pwd命令)