软件工程复习
1、结构化程序设计的基本方法 (Chapter 2)
-
定义
- 结构化开发方法由结构化分析、结构化设计和结构化程序设计三部分有机组合而成的。这里所说的结构是指软件系统内各个组成要素之间的相互联系、相互作用的框架。
-
主要思想
- 结构化分析使用需求建模方法,以数据流图和控制流图为基础,由系统分析员划分出流变换函数,以得到系统的软件结构,并将其映射为软件功能。其次用状态迁移图来创建行为模型,用数据词典开发成数据模型。
- 在本质上,结构化的软件开发方法是面向数据、面向过程、面向功能、面向数据流的观点来映射问题的。
-
基本要点
任何程序都可由顺序、选择、重复三种基本控制结构构造
用顺序方法对过程进行分解,确定各部分的执行顺序。 用选择方式对过程进行分解,确定某个部分的执行条件。 用循环方式对过程分解,确定某个部分进行重复的开始和结束的条件。 对处理过程仍然模糊的部分反复使用以上分解方法,最终可将所有细节确定下来。
-
以上来自Baidu,以下为群里发的
-
目的
- 提高程序可读性和易维护性、可调性和可扩充性
-
只允许三种基本程序结构形式
- 顺序结构
- 分支结构
- 循环结构(只允许一 个流动入口和一个出口)
-
自顶向下
- 先整体后细节
- 先全局后局部
- 从最上层总目标开始设计,逐步具体化
-
模块化设计
- 把一个复杂问题分成多个简单问题,把每个小目标作为一个模块
-
特点
- 不会出现死循环,在程序的静态形式与动态执行流程之间具有良好的对应关系
2、白盒测试技术的覆盖标准(Chapter 9 - p216)
- 根据覆盖程度,由低到高有:👉指定义
- 语句覆盖
- 👉设计若干个测试用例,运行被测程序,使每一可执行语句至少执行一次。
- 测试用例越少越好
- 语句覆盖率 = (被评价到的语句数量 / 可执行的语句总数)× 100%
- 判定覆盖
- aka 分支覆盖,👉使每个判定的所有可能结果至少出现一次。
- 即所设计的测试用例,使每一个分支至少经历一次
- 条件覆盖
- 在软件中一个判定往往包含多个判定条件
- 👉不仅每个判定都取得各种结果,而且判定表达式中的每个条件也都取得各种可能的结果。
- 即要求所设计的测试用例,使得所有判定条件都能取到
true
和false
- 判定/条件覆盖
- 即满足条件覆盖,又实现判定覆盖
- 👉使得每个判定条件都能取到
true
和false
,并且判定本身也能取到所有可能结果。
- 条件组合覆盖
- 👉选取足够多的测试用例,使得每个判定中的条件结果的所有可能组合都出现至少一次。
- 因此,该覆盖比判定/条件覆盖更强
- 路径测试
- 👉选取足够多的测试用例,使得流程图上的每条路径至少经过一次。
- 路径测试相当于 判定组合覆盖
- 路径覆盖是一种相当强的逻辑覆盖,但只考虑每个判定表达式的取值,而并没有考虑判定内各种条件之间的组合,因此将路径覆盖和条件组合覆盖结合,可以得到更强的覆盖
- 语句覆盖
3、软件工程的三要素(Chapter 1 - p26)
-
👉方法、工具、过程
-
关系
软件工程方法为软件开发提供了“如何做”的技术。它包括了多方面的任务,如项目计划与估算、软件系统需求分析、数据结构、系统总体结构的设计、算法过程的设计、编码、测试以及维护等。
软件工具为软件工程方法提供了自动的或半自动的软件支撑环境。目前,已经推出了许多软件工具,这些软件工具集成起来,建立起称之为计算机辅助软件工程(case)的软件开发支撑系统。case将各种软件工具、开发机器和一个存放开发过程信息的工程数据库组合起来形成一个软件工程环境。
软件工程的过程则是将软件工程的方法和工具综合起来以达到合理、及时地进行计算机软件开发的目的。过程定义了方法使用的顺序、要求交付的文档资料、为保证质量和协调变化所需要的管理、及软件开发各个阶段完成的里程碑。
软件工程是一种层次化的技术。任何工程方法(包括软件工程)必须以有组织的质量保证为基础。全面的质量管理和类似的理念刺激了不断的过程改进,正是这种改进导致了更加成熟的软件工程方法的不断出现。支持软件工程的根基就在于对质量的关注。
4、内聚、耦合(Chapter 8 - p184)
-
模块独立 是指系统汇总的模块尽可能地只涉及自己特定的子功能,并且模块接口简单,与其他模块没有过多的通信。如果系统中每个模块都有很好的独立性时,系统实现起来会更容易。
-
模块独立性分析,一般采用 耦合 和 内聚 这两个定性的技术指标来对这一模块的独立性进行衡量
- 内聚性衡量各模块内部功能的结合强度
- 耦合性显示模块与模块之间相互的依赖关系
-
为使模块有更强的独立性,要求模块有较高的内聚性和较低的耦合性。
-
耦合
- 主要形式
- 非直接耦合
- 👉两个模块被共同的模块控制和调用,而它们本身之间没有直接的联系,则称 非直接耦合。
- 这种耦合形式是最弱的
- 数据耦合
- 👉模块与模块间通过接口参数实现通信,传递的接口参数数据只用于计算,不影响内部程序执行的路径。
- 提倡使用数据耦合,这是一种较弱的耦合
- 控制耦合
- 👉在数据耦合的基础上,模块间的接口参数不仅传递数据,还传递控制信息(标志、名字、开关等),从而影响模块的内部程序执行路径。
- 耦合性比数据耦合强,属于中等程度的耦合
- 当需要通过接口传递模块内的多功能选择时,需要用到控制耦合
- 公共耦合
- 公共数据环境:有独立于模块而存在的数据文件、公共变量的软件系统
- 👉模块通过访问公共数据环境而实现通信,则为公共耦合。
- 使模块独立性下降,属于中等程度的耦合
- 内容耦合
- 👉表现形式如下:
- 模块直接访问另一个模块的内部数据;
- 模块不通过正常的入口转到另一模块内部;
- 模块之间存在一部分代码重叠;
- 某个模块有多个入口。
- 该耦合方式耦合性极强,使得模块的变动(维护和升级)变得非常困难
- 不允许出现内容耦合
- 👉表现形式如下:
- 非直接耦合
- 主要形式
-
内聚
-
主要类型
-
偶然内聚
- 👉模块内部的元素之间的联系很少或没有。
- 产生的原因,是程序员没有精心地进行软件结构设计,或设计结构随意
- 模块的功能定义模糊、内聚程度低
-
逻辑内聚
- 👉将几种相关的功能组合在一起形成一个模块。
- 模块内部的功能之间是选择关系,在调用时需要对模块传递参数来确定所选功能
- 由于模块内部各功能执行的时间是相关的,因此逻辑内聚比偶然高
- 但在调用该模块时,需要传递控制参数,因此增强了耦合强度
-
时间内聚
- 👉模块内部各功能之间的执行与时间相关。
- 例如,初始化模块:
- 变量赋初值、打开通信连接、初始化对象、打开文件
- 比逻辑内聚的内聚性更强
- 但也属于低内聚类型
-
过程内聚
- 👉模块内的各个元素是 按照一定次序来进行 的,即 对元素的处理之间是相关的。
- 例如:流程图中的循环、分支、计算,可以看做有3个过程的内聚模块
- 比时间内聚的内聚性强
- 但每个过程仅仅完成某一功能的一小部分,因此耦合程度较高
-
通信内聚
- 👉一个模块内部可能有几个功能部分,如果这些功能部分使用相同的数据输入,或产生相同的数据输出,则为 通信内聚。
- 内聚程度比 过程内聚 高
-
顺序内聚
- 👉如果某一功能元素的 输出 作为另一个功能元素的 输入,模块内功能元素顺序连接,它们之间关系紧密。
-
功能内聚
- 👉模块内的各个元素都是为了实现整体的具体功能而必需的,且这些元素需要协同工作,无法单独执行,则这样的模块为功能内聚模块。
- 功能内聚的内聚性很高,在软件设计时,应尽量实现功能内聚。
-
-
5、软件过程模型(Chapter 2 - p29)
- 人们总结出的软件开发的策略和方法,称为软件过程模型
- 软件开发过程,aka 软件生命周期
-
瀑布模型
-
aka 线性顺序模型
-
👉按照 需求,分析、设计、实现(编码)、测试和维护阶段,顺序地进行,当线性序列完成后就能交付一个完善的系统。
-
缺点:
-
-
演化模型
- 采用一种迭代的思想方法,使工程师渐进地开发逐步完善的软件版本。
- 包括 增量模型 和 螺旋模型 两种范型
-
增量模型
-
以渐进式地增加来构造软件产品,并实时对软件进行重新规定说明、或重新设计,或重新编写代码,甚至推倒重来
-
👉以一系列的增量构件的形式来设计、实现、集成和测试,每个构件由一些代码块组成,这些代码块来自多个相互作用的模型。
-
根据增量的方式和形式的不同,分为:
- 基于瀑布模型的渐增模型
- 基于原型的快速原型模型
-
增量模型和瀑布模型的不同:
- 瀑布模型属于整体开发模型,它规定在开始下一阶段的工作前,必须完成前一个阶段的所有细节
- 增量模型属于非整体开发模型,它推迟某些阶段或所有阶段的小细节,从而较早地产生工作软件
-
增量模型强调,每个增量均发布一个可操作性产品,确实地给用户提供一定的功能,并提供给用户评估最终交付软件的一个平台
-
优点
- 可以使用户有充裕时间学习和适应新产品
- 从长远看,开放结构的软件的可维护性明显好于封闭软件
-
难点
- 每个新增量构件集成到现有体系结构中时,必须不破坏原来的产品
-
-
螺旋模型
-
结合瀑布模型和增量模型,并加入风险分析
-
该模型将开发过程划分为6个活动:
- 沟通、制定计划、风险分析、实施工程、构造与发布、系统评估
-
沿着螺旋线每转一圈,表示开发出一个更完善的新的软件版本
-
-
并发模型
- 没找到,并发开发在第十七章
6、测试的关键问题(Chapter 9 - p213)
- 测试的目的是 以最少的时间和人力找出软件中潜在的各种错误和缺陷
- 关键问题是**👉如何设计测试用例**
7、E-R图(Chapter 7 - p178)
- 实体 👉 矩形
- 联系 👉 菱形
- 属性 👉 椭圆
- 数据项是基本数据单位
- 属性不可再分,即不包含其他属性
8、软件测试步骤(Chapter 9 - p225)
-
单元测试
-
👉针对软件内最小单元——模块 的内部进行的测试,aka 模块测试。
-
一般在编码后,就会紧接着进行单元测试,因此该测试的责任人主要是编码人员
-
一般采用白盒测试法
-
单元模块
- 是单元测试的主要测试对象
- 是组成系统的最小模块单位
- 如:函数,过程 等
-
单元测试步骤
- 辅助测试模块
- 驱动模块
- 是模拟被测模块的上级,相当于被测模块的主程序
- 通过 驱动模块 调用 被测模块,接收 测试数据,然后把这些 测试数据 传送给 被测模块
- 被测模块
- 桩模块
- 👉作为被测模块所调用的子模块
- 桩模块受被测模块的调用,可以检验调用参数,并且模拟被调用的 子程序模块 的功能,最后把结果传回 被测模块
- 如果,被测模块是顶层模块,则测试时不需要驱动模块
- 如果,被测模块是底层模块,则测试时不需要桩模块
-
-
集成测试
-
👉将各个模块组装在一起,进行集成测试。
-
集成测试的任务包括对系统进行组装和测试。
- 将经过测试的模块组织起来,查看模块是否能按照结构设计组装;
- 在系统装配的过程中,对每个集成到系统中的模块检测,查看模块之间是否有良好的协作性;
-
此测试通常采用黑盒测试法完成
-
组织集成测试有两种方式
-
非渐增式测试
-
渐增式测试
- 自顶向下集成
- 自底向上集成
-
-
-
确认测试
- 验证该测试软件的功能和性能及其他特性,能否达到用户的要求。
- aka 合格性测试
-
系统测试(提纲无)
9、软件生命周期(Chapter 2 - p27)
- 过程是一个生命周期,当过程涉及某种产品的建立时,则称该过程为一个生命周期。
- 软件开发过程,即软件生命周期。
- 在软件工程三要素中,软件过程将人员、方法、工具和管理有机结合,形成一个能有效控制软件开发质量的运行机制。
10、COCOMO模型(Chapter 4 - p85)
-
COCOMO II模型
-
COCOMO模型
Constructive Cost Model,构造性成本模型
-
用来估算软件成本、工作量和进度计划
-
思想与技术要点
- 软件成本和工作量估算是一种实验性方法,一定要通过大量实验和已有软件项目的数据建立实验模型。
- 软件工作量估算要区分 软件类型 和 软件的不同开发方式。
-
用3个不同层次的模型来反映项目的复杂性
-
-
COCOMO II模型的改进
- 主要变化
- 使用3个螺旋式的生命周期模型:应用组合模型,早期设计,后体系结构。
- 使用 5个规模因子 计算项目规模经济性的幂指数 B,代替了原来按基本、中间、详细模型的不同使用固定指数的方法。
- 扩展功能点测量,使用源代码行(SLOC)代替DSI(源指令条数)。
- 新增加成本驱动因子,删除部分不适应的成本驱动因子。
- 改变原有成本驱动因子的参数值,如软件再工程和代码自动转换等,以适应当前的软件测度技术。
- 3个生命周期模型
- 应用组合模型
- 早期设计模型
- 后体系结构模型
- 主要变化
-
-
计算项目NOP(p89)
-
New Object Point,NOP 新对象点数目
-
对象点数目 = 窗口、报告、3GL构件的数目
-
NOP = 对象点数目 × (100 - REUSE%) / 100
即:新对象点 = 不可复用的对象点
-
生 产 率 P R O D = N O P / 人 月 生产率PROD=NOP/人月 生产率PROD=NOP/人月
-
开发人员的经验转换 非常低 低 正常的 高 非常高 生产率(PROD) 4 7 13 25 50 -
一般取 PROD = 13
-
则 项目估计工作量
P M = N O P / P R O D ( 人 月 ) PM = NOP/PROD(人月) PM=NOP/PROD(人月)
-
-
成本 (p103)
- 概念
- 现值,aka本金,👉资金现在的价值
- 终值,aka本利和,👉资金经过若干时期后包括本金和时间价值的未来价值
- 年金,👉每隔相等时间间隔 收到或支付相同金额 的收付款项
- 如分期贷款、养老金、租金、提取折旧 等
- P : 现 值 , i : 利 率 , F : 终 值 , t : 时 间 , A : 每 年 收 付 的 金 额 P:现值,i:利率,F:终值,t:时间,A:每年收付的金额 P:现值,i:利率,F:终值,t:时间,A:每年收付的金额
- 单利终值
-
单利终值是本金和未来利息之和
-
F = P ⋅ ( 1 + i × t ) F=P\cdot(1+i\times t) F=P⋅(1+i×t)
- 单利现值
-
单利现值是确定未来资金终值的现在价值
-
P = F / ( 1 + i × t ) P=F/(1+i\times t) P=F/(1+i×t)
- 复利终值
-
项目成本计算一般采用复利计算
-
假定年利率为 i i i,现在存入 P P P元,则n年后得到的钱 F F F为
F = P ⋅ ( 1 + i ) n F=P\cdot(1+i)^n F=P⋅(1+i)n
- ( 1 + i ) n (1+i)^n (1+i)n 为复利终值系数,用符号 ( F / P , i , n ) (F/P,i,n) (F/P,i,n) 表示
- 复利现值
- 与复利终值相反
- P = F ⋅ ( 1 + i ) − n P=F\cdot(1+i)^{-n} P=F⋅(1+i)−n
- ( 1 + i ) − n (1+i)^{-n} (1+i)−n 为复利现值系数,用符号 ( P / F , i , n ) (P/F,i,n) (P/F,i,n) 表示
- 年金终值
-
按复利终值的计算方式,计算每年的本利和,最后求和
-
F = A ⋅ ( 1 + i ) 0 + A ⋅ ( 1 + i ) 1 + . . . + A ⋅ ( 1 + i ) n − 1 F=A\cdot(1+i)^0+A\cdot(1+i)^1+...+A\cdot(1+i)^n-1 F=A⋅(1+i)0+A⋅(1+i)1+...+A⋅(1+i)n−1
F = A × ( 1 + i ) n − 1 i F=A\times\frac{(1+i)^n-1}{i} F=A×i(1+i)n−1
- ( 1 + i ) n − 1 i \frac{(1+i)^n-1}{i} i(1+i)n−1 为年金终值系数,用符号 ( F / A , i , n ) (F/A,i,n) (F/A,i,n) 表示
- 年金现值
-
按复利现值的计算方式,计算每年的复利现值,最后求和
-
P = A ⋅ 1 ( 1 + i ) + A ⋅ 1 ( 1 + i ) 2 + . . . + A ⋅ 1 ( 1 + i ) n P=A\cdot\frac{1}{(1+i)}+A\cdot\frac{1}{(1+i)^{2}}+...+A\cdot\frac{1}{(1+i)^{n}} P=A⋅(1+i)1+A⋅(1+i)21+...+A⋅(1+i)n1
P = A × 1 − ( 1 + i ) − n i P=A\times\frac{1-(1+i)^{-n}}{i} P=A×i1−(1+i)−n
- 1 − ( 1 + i ) − n i \frac{1-(1+i)^{-n}}{i} i1−(1+i)−n 为年金现值系数,用符号 ( P / A , i , n ) (P/A,i,n) (P/A,i,n) 表示
- 概念
-
工作量估算(p83)
-
工作量的单位是 人月(Person Month, PM),每人每月
-
生产率 = 产品数 ÷ (人数 × 工作小时)
实际生产率 = 潜在额生成率 - 不完善的过程带来的损失
-
代码行估算
-
功能点估算
-
项目总生产人力典型计算公式:项目总生产人力 = 项目功能点数 × 生产率
-
生产效率典型计算公式:生产效率 = 项目总生产人力 ÷ 项目功能点数
-
-
11、决策树法(Chapter 6 - p141)
- 例题
- 标准离差率 例
12、项目进度获取值分析(Chapter 4 - p99)
- BCWS
- Budgeted Cost of Work Scheduled,计划完成工作的预算成本
- 根据项目计划计算的,“到目前为止的总预算成本”,或 “到目前为止原来计划成本是多少”
- BCWP
- Budgeted Cost of Work Performed,已完成工作的预算成本
- 是“到目前为止已经完成的工作的原来的预算成本”,表示“到该日期为止完成了多少工作”
- ACWP
- Actual Cost of Work Performed,已完成工作的实际成本
- 由项目组统计的,“到目前为止所完成工作的实际成本”,说明了“到该日期为止实际花了多少钱”
- BAC
- Budgeted At Completion,工作全部完成的预算成本
- 是“项目计划中的成本估算结果”,是“项目完成的预计总成本”
13、模块独立性的标准及其定义(Chapter 8 - p184)
- 定义
- 👉尽可能地只涉及自己特定的子功能,且接口简单,与其他模块没有过多的通信。
- 模块独立性 是 衡量软件中模块质量 最重要的指标。
- 采用 耦合 和 内聚,这两个定性的技术指标来对模块的独立性进行衡量。
- 内聚 衡量模块内部功能的结合强度
- 耦合 显示模块与模块之间的依赖关系
14、体系结构(Chapter 10 - p240)
-
深度
- 根节点到叶结点的最长路径长度
-
宽度
- 体系结构中最宽那层的结点数
-
扇入
- 👉直接调用该模块的上级模块的个数
- 扇入大 表示模块的复用程序高
-
扇出
-
👉该模块直接调用的下级模块的个数
-
扇出大表示模块的复杂度高,需要控制和协调过多的下级模块
-
但扇出过小(例如总是1)也不好
-
扇出过大一般是因为缺乏中间层次,应该适当增加中间层次的模块;
-
扇出太小时可以把下级模块进一步分解成若干个子功能模块,或者合并到它的上级模块中去。
-
设计良好的软件结构,通常顶层扇出比较大,中间扇出小,底层模块则有大扇入
-
15、MIF(Chapter 15 - p353)
-
方法继承因子 Method Inheritance Factor,MIF
-
M I F = ∑ i = 1 T C M i ( C i ) ∑ i = 1 T C M a ( C i ) MIF=\frac{\sum\limits_{i=1}^{TC}{M_i(C_i)}}{\sum\limits_{i=1}^{TC}{M_a(C_i)}} MIF=i=1∑TCMa(Ci)i=1∑TCMi(Ci)
16、软件结构图(Chapter 8 - p186)
- 模块:用方框标识
- 调用:用箭头,前者是调用模块,后者是被调用模块
- 通信:用小箭头,一般在调用箭头的边上,指明从模块之间的数据或标志以及传送的方向
- 判断调用:用菱形
- 循环调用:用弧形箭头
17、技术度量(Chapter 10 - p235)
- 程序流程图表示算法(p198)
-
基本符号
-
举例
-
流图
-
结构化组件在流图中的表示
-
流程图 到 流图 的转换
-
-
流图的区域
- 看下面👇
- 计算环形复杂度 V(G)
- aka 环复杂度
- 有三种方法计算:
- V(G) = 流图中区域的数量
- 区域👉结点和边限定的区域,分为闭合区域和外部区域
- 上图有4个闭合区域( R 1 , R 2 , R 3 , R 5 R_1,R_2,R_3,R_5 R1,R2,R3,R5),再加外部区域( R 4 R_4 R4),所以V(G)=4+1=5
- V(G) = E-N+2
- E是流图中边的数目,N是流图中节点的数目
- 上图有10条边,7个节点,所以V(G)=10-7+2=5
- V(G) = P+1
- P是流图中的判定节点的数目
- 上图中的流图中节点1、2、4、5是判定节点,所以V(G)=4+1=5
- V(G) = 流图中区域的数量
-
设计路径覆盖的测试用例(p219)
测试数据 覆盖的判定组合 所走的路径 A=2,B=0,X=3 A>1 and B=0为真,并且A=2 or X>1为真 (a)(b)©(d)(e)(f) A=2,B=0,X=0 A>1 and B=0为真,并且A=2 or X>1为假 (a)(b)©(d)(f) A=0,B=0,X=3 A>1 and B=0为假,并且A=2 or X>1为真 (a)(b)(d)(e)(f) A=0,B=0,X=0 A>1 and B=0为假,并且A=2 or X>1为假 (a)(b)(d)(f)
18、LOC(Chapter 4 - p78)
- 源代码行数,Line of Code,LOC
- 指所有 可执行的源代码行数
- 包括:
- 可交付的工作控制语言语句
- 数据定义
- 数据类型声明
- 等价声明
- 输入/输出格式声明
- 等
19、需求分析的定义(Chapter 7 - p157)
- 需求分析👉为了建立一个新的或改变一个现存的计算机系统 而描写新系统的目的、范围、定义、功能时所需要做的所有工作
- 在此过程中,系统分析员和软件工程师确定顾客的需要
- 特点
- 用户与开发人员很难进行交流
- 用户的需求是动态变化的
- 系统变更的代价呈非线性增长
- 过程
- 问题识别
- 分析与综合
- 编制需求分析阶段的文档
- 需求分析评审
20、面对对象程序设计的特性(Chapter 11 - p260)
21、软件的可维护性(Chapter 10 - p248)
- 👉为了满足用户的新要求、或当环境发生了变化、或运行中发现了新的错误时,对软件进行相应诊断和修改的容易程度。
- 目前没有手段进行直接度量,只能 间接度量
- 平均变更时间 MTTC
- 一种简单的面向时间的度量
- 变更时间包括:
- 分析变更请求、设计合适的修改方案、实现变更并进行测试,以及将变更发布给用户所花的时间。
- 一般情况,MTTC值越低,可维护性越好
22、绘制某应用系统的用例图(Chapter 11 - p269)
23、分析UML类及建立相应的类图
-
UML
24、顺序图描述法(Chapter 12 - p300)
-
活动图👇
课后习题
第四章(p109)
-19
生 产 率 P = L / E = 12.1 × 1 0 3 L O C 24 P M = 504 ( L O C / p m ) 平 均 成 本 C = S / L = 168000 12.1 ∗ 1000 = 13.9 ( 美 元 / L O C ) 生产率P=L/E=\frac{12.1\times 10^3 LOC}{24PM}=504(LOC/pm) \\ 平均成本C=S/L=\frac{168000}{12.1*1000}=13.9(美元/LOC) 生产率P=L/E=24PM12.1×103LOC=504(LOC/pm)平均成本C=S/L=12.1∗1000168000=13.9(美元/LOC)
-20
-
对象类型\权重 简单 中等 复杂 屏幕 1 2 3 报表 2 5 8 3GL构件 10 -
“正常开发者环境”—— P R O D = 13 PROD=13 PROD=13
-
新 对 象 点 数 目 N O P = 对 象 点 数 目 × ( 100 − R E U S E % ) / 100 = ( 12 × 2 + 10 × 5 + 80 × 10 ) × ( 100 − 40 ) / 100 = 524.4 新对象点数目NOP=对象点数目\times(100-REUSE\%)/100=(12\times2+10\times5+80\times10)\times(100-40)/100=524.4 新对象点数目NOP=对象点数目×(100−REUSE%)/100=(12×2+10×5+80×10)×(100−40)/100=524.4
-
生 产 率 P R O D 的 单 位 : N O P / 人 月 ( 工 作 完 成 需 要 的 多 少 人 × 多 少 月 ) 生产率PROD的单位:NOP/人月(工作完成需要的多少人\times多少月) 生产率PROD的单位:NOP/人月(工作完成需要的多少人×多少月)
工 作 量 = N O P / P R O D = 524.4 / 13 = 40.34 ( 人 月 ) 工作量=NOP/PROD=524.4/13=40.34(人月) 工作量=NOP/PROD=524.4/13=40.34(人月)
-
每 个 N O P 的 成 本 = 5000 / P R O D = 5000 / 13 = 384.62 ( 元 ) 每个NOP的成本=5000/PROD=5000/13=384.62(元) 每个NOP的成本=5000/PROD=5000/13=384.62(元)
-21
功 能 点 数 F P = 总 计 数 值 × ( 0.65 + 0.01 × ∑ F i ) 功能点数FP=总计数值\times(0.65+0.01\times\sum{F_i}) 功能点数FP=总计数值×(0.65+0.01×∑Fi)
-
F P = ( 10 + 12 + 15 + 8 + 8 ) ∗ 5 × 0.65 = 172.25 FP=(10+12+15+8+8)*5\times0.65=172.25 FP=(10+12+15+8+8)∗5×0.65=172.25
-
5000 的 单 位 是 元 / p m 5000的单位是 元/pm 5000的单位是元/pm
- 每 个 F P 的 成 本 = 5000 / P R O D = 5000 / 10 = 500 ( 元 / F P ) 每个FP的成本=5000/PROD=5000/10=500(元/FP) 每个FP的成本=5000/PROD=5000/10=500(元/FP)
-
总 成 本 = F P ⋅ 每 个 F P 的 成 本 = 172.25 × 500 = 86125 ( 元 ) 总成本=FP\cdot每个FP的成本=172.25\times500=86125(元) 总成本=FP⋅每个FP的成本=172.25×500=86125(元)
工 作 量 = F P / P R O D = 172.25 / 10 = 17.2 P M 工作量=FP/PROD=172.25/10=17.2PM 工作量=FP/PROD=172.25/10=17.2PM
-23
- B C W S = 5 + 20 = 25 BCWS=5+20=25 BCWS=5+20=25
- B C W P = 5 + 20 + 40 = 65 BCWP=5+20+40=65 BCWP=5+20+40=65
- B A C = 5 + 20 + 50 + 40 + 60 + 80 = 255 BAC=5+20+50+40+60+80=255 BAC=5+20+50+40+60+80=255
- A C W P = 10 + 15 + 50 = 75 ACWP=10+15+50=75 ACWP=10+15+50=75
-24
现 在 投 资 30000 , 而 之 后 每 年 的 收 回 的 钱 应 是 按 利 率 升 值 后 的 钱 , 相 当 于 每 年 的 终 值 , 则 按 照 年 金 现 值 公 式 求 解 P = A ⋅ ( P / A , 10 % , 10 ) = A ⋅ 1 − ( 1 + 0.1 ) − 10 0.1 = 30 , 000 现在投资30000,而之后每年的收回的钱应是按利率升值后的钱,相当于每年的终值,则按照年金现值公式求解 \\ P=A\cdot (P/A,10\%,10)=A\cdot\frac{1-(1+0.1)^{-10}}{0.1}=30,000 现在投资30000,而之后每年的收回的钱应是按利率升值后的钱,相当于每年的终值,则按照年金现值公式求解P=A⋅(P/A,10%,10)=A⋅0.11−(1+0.1)−10=30,000
解方程得 A = 4882.36 A=4882.36 A=4882.36
-27
计
算
每
年
节
省
600
元
的
年
金
现
值
,
再
和
当
前
高
出
的
5030
元
进
行
比
较
P
=
A
⋅
(
P
/
A
,
6
%
,
10
)
=
A
⋅
1
−
(
1
+
6
%
)
−
10
6
%
=
4416.05
<
5030
计算每年节省600元的年金现值,再和当前高出的5030元进行比较 \\ P=A\cdot(P/A,6\%,10)=A\cdot\frac{1-(1+6\%)^{-10}}{6\%}=4416.05<5030\\
计算每年节省600元的年金现值,再和当前高出的5030元进行比较P=A⋅(P/A,6%,10)=A⋅6%1−(1+6%)−10=4416.05<5030
选乙
第六章(p149)
-19
风 险 揭 露 ( 风 险 曝 光 度 ) R E = P ⋅ C 风险揭露(风险曝光度)RE=P\cdot C 风险揭露(风险曝光度)RE=P⋅C
P − 风 险 发 生 的 概 率 , C − 风 险 发 生 带 来 的 损 失 ( 如 成 本 ) P-风险发生的概率,C-风险发生带来的损失(如成本) P−风险发生的概率,C−风险发生带来的损失(如成本)
主 要 计 算 损 失 , 不 能 复 用 的 有 25 个 , 则 C = 25 × 100 × 13 = 32500 主要计算损失,不能复用的有25个,则C=25\times100\times13=32500 主要计算损失,不能复用的有25个,则C=25×100×13=32500
R E = 60 % × C = 19500 ( 元 ) RE=60\%\times C=19500(元) RE=60%×C=19500(元)
-21
R E = 80 % × ( 60 × 40 % × 100 × 50 ) = 96000 ( 元 ) RE=80\%\times(60\times40\%\times100\times50)=96000(元) RE=80%×(60×40%×100×50)=96000(元)
-22
- 需要采用标准离差率。因为 标准离差 仅适用于期望值相同的情况,在期望值相同的情况
下,标准离差越大,风险越大;标准离差率适用于期望值相同或不同的情况,在期望值不同
的情况下,标准离差率越大,风险越大。
第七章(p181)
-7
-8
第九章(p232)
-5
- 不能被4整除——不是闰年,1823
- 可以被4整除,不能被100整除——闰年,2004
- 可以被100整除,也可以被400整除——是闰年,2000
- “leap=0” 连到 “leap是否等于1”
- “year是否被100整除?” 的否应该连到 “leap=1”
- “year是否被4整除”的否连到“leap=0”
-7
- 2,2,4 —— 不能组成三角形
- 2,3,4 —— 一般三角形
- 4,4,3 —— 等腰三角形
- 4,4,4 —— 等边三角形
第十章(p252)
-2
功 能 点 数 F P = 总 计 数 值 × ( 0.65 + 0.01 × ∑ F i ) 功能点数FP=总计数值\times(0.65+0.01\times\sum{F_i}) 功能点数FP=总计数值×(0.65+0.01×∑Fi)
测量参数 | 计数 | 平均(加权因子) | 计数值 |
---|---|---|---|
外部输入数 | 3 | 4 | 12 |
外部输出数 | 2 | 5 | 10 |
用户查询数 | 2 | 4 | 8 |
文件数 | 1 | 10 | 10 |
外部接口数 | 4 | 7 | 28 |
总计数值 | 68 |
F P = 68 × ( 0.65 + 0.01 × ( 平 均 复 杂 度 ? ) ) FP=68\times(0.65+0.01\times (平均复杂度?)) FP=68×(0.65+0.01×(平均复杂度?))
- 不清楚复杂度调整值 ∑ F i \sum F_i ∑Fi 的值
-3
操作符: = , ; , i f , > = , ∗ , − , e l s e i f , p r i n t , ( ) =,;,if,>=,*,-,else if,print,() =,;,if,>=,∗,−,elseif,print,()
操作数: x , 4 , y , 10 , 3 , 11 , 1 , 2 x,4,y,10,3,11,1,2 x,4,y,10,3,11,1,2
n 1 = 9 , n 2 = 8 n_1=9,n_2=8 n1=9,n2=8,n1、n2 是不同的个数(即多个只算一次)
长度: N = n 1 log 2 n 1 + n 2 log 2 n 2 = 9 log 2 9 + 8 log 2 8 = 52.53 N=n_1\log_2{n_1}+n_2\log_2{n_2}=9\log_29+8\log_28=52.53 N=n1log2n1+n2log2n2=9log29+8log28=52.53
体积: V = N log 2 ( n 1 + n 2 ) = 214.71 V=N\log_2{(n_1+n_2)}=214.71 V=Nlog2(n1+n2)=214.71
-4
- 区域:3+1=4
- 边和结点:13-11+2=4
- 分支:3+1=4
- 公式看第17点
-5
- 这题听说不考
-6
F
(
1
)
=
10
/
200
R
(
1
)
=
1
−
F
(
1
)
=
0.95
R
(
n
)
=
R
n
(
1
)
=
0.9
5
n
F(1)=10/200 \\ R(1)=1-F(1)=0.95 \\ R(n)=R^n(1)=0.95^n
F(1)=10/200R(1)=1−F(1)=0.95R(n)=Rn(1)=0.95n
-7
d
e
p
t
h
=
5
w
i
d
t
h
=
7
m
的
扇
出
(
出
度
)
=
4
r
的
扇
入
(
入
度
)
=
3
depth=5 \\ width=7 \\ m的扇出(出度)=4 \\ r的扇入(入度)=3
depth=5width=7m的扇出(出度)=4r的扇入(入度)=3
-8
$$ L为行数(KLOC),E为开发软件需要的工作量(人月PM,或人年PY),S为软件成本(元,或美元) \\ N_d为缺陷数,N_e为错误个数,P_d为软件文档页数 \\ \\Alpha: \
平均每人每月开发的代码行数——生产率P_l=L/E=12.1/24\times1000=504(LOC/PM) \
总成本/总行数——平均成本C_l=S/L=\frac{16.8\times10000}{12.1\times1000}=13.9(美元/LOC) \
平均每千行错误数——错误率EQR_l=N_e/L=29/12.1=2.4(个/KLOC) \
平均每千行文档数——文档率D_l=P_d/L=365/12.1=30(页/KLOC)
$$
第十一章(p277)
-10
- UML有5种(p268):
- 用例图
- 静态图
- 行为图
- 交互图
- 实现图
- 用例图,因为需要从用户的角度来模拟电脑下棋的模式
- 静态图,用来描述了系统中类图、对象图、包图直接的联系,以设计整个系统
- 行为图,需要考虑用户的各种操作所触发的各类状态,来设计对应的系统行为
- 交互图,系统需要设计一个图形界面来实现与用户的交互,让用户更直观易懂地操作系统
-13
第十三章(p333)
-8
-9
-13
第十五章(p359)
-3
-
CK度量套件(p349)
-
每个类的加权方法(Weighted Methods per Class, WMC)
-
类 的 W M C = ∑ C i , C i 为 该 类 中 第 i 个 方 法 ( 或 服 务 、 操 作 ) 的 复 杂 度 , 相 当 于 一 个 权 值 类的WMC=\sum C_i,C_i为该类中第i个方法(或服务、操作)的复杂度,相当于一个权值 类的WMC=∑Ci,Ci为该类中第i个方法(或服务、操作)的复杂度,相当于一个权值
-
对于一个有 m m m个类的系统而言,其 W M C WMC WMC是 m m m个类的加权方法的平均值,即
系 统 的 W M C = ∑ j = 1 m W M C j m 系统的WMC=\frac{\sum\limits _{j=1}^{m}WMC_j}{m} 系统的WMC=mj=1∑mWMCj -
X 的 W M C = 2 + 5 + 8 + 11 + 4 = 30 X的WMC=2+5+8+11+4=30 X的WMC=2+5+8+11+4=30
-4
-
继承树的深度(Depth of the Inheritance Tree,DIT)
-
DIT即为树的深度
-
子女的数量(Number of Children,NOC)
-
直接从属于某类的子类 称为该类的子女
-
D I T 1 = 3 D I T 2 = 4 DIT_1=3\\DIT_2=4 DIT1=3DIT2=4
-
两 棵 树 都 为 N O C X 2 = 2 两棵树都为NOC_{X2}=2 两棵树都为NOCX2=2
-5
-
由子类通过加入私有操作或属性实现实例化而增加的操作数量(Number of Operating Added by a subclass,NOA)(p353)
-
NOA增大时,子类飘离超类所隐含的抽象(书上这话才最抽象)
我的理解是,子类越发具体和面向实际的实现过程
-
当类层次的深度增大,低层的类的NOA值将下降
我的理解是,深度已经很大时,此时留给低层还没实现的抽象方法已经不多了
-
对 于 左 树 : { N O A X 3 = 1 N O A X 4 = 1 对于左树:\begin{cases} NOA_{X3}=1 \\ NOA_{X4}=1 \end{cases} 对于左树:{NOAX3=1NOAX4=1 对 于 右 树 : { N O A X 3 = 1 N O A X 4 = 1 对于右树:\begin{cases}NOA_{X3}=1 \\ NOA_{X4}=1 \end{cases} 对于右树:{NOAX3=1NOAX4=1
-6
- 类的加权方法 (p351)
类名 | 方法 |
---|---|
Reader | 4 |
Book | 2 |
Book-copy | 3 |
-
W M C = ( 4 + 2 + 3 ) / 3 = 3 ( 方 法 / 类 ) WMC = (4+2+3)/3 = 3 (方法/类) WMC=(4+2+3)/3=3(方法/类)
-
对象类间的耦合(Coupling Between Object Classes,CBO)
-
指 类之间合作的数量
类 | 耦合类 | CBO |
---|---|---|
Reader | Book-copy | 1 |
Book | Book-copy | 1 |
Book-copy | Reader,Book | 2 |
-7
- 对类的响应(Response For a Class,RFC)
- 响应集合👉 用来度量类的复杂度,是所有可能被该类调用的方法的集合(即必定包含自己和自己的方法)
- RFC 为响应集中方法的数量
- 当RFC增大时,测试序列增大,测试的工作量增大,类的总设计复杂度随之增大
类 | 响应集合 | RFC |
---|---|---|
Reader | Reader,borrow,return,subscribe,modify_OID,Book-copy,borrow_state,return_state,subscribe_state | 9 |
Book-copy | Book-copy,borrow_state,return_state,subscribe_state | 4 |
Book | Book,add_book,delete_book,Book-copy,borrow_state,return_state | 6 |
-8
- MOOD度量套件(p353)
- MIF
类 |
M
i
(
C
i
)
M_i(C_i)
Mi(Ci) Ci类中继承的(没被覆盖的)方法的数目 |
M
d
(
C
i
)
M_d(C_i)
Md(Ci) Ci类中声明的方法数 |
M
a
(
C
i
)
=
M
i
(
C
i
)
+
M
d
(
C
i
)
M_a(C_i)=M_i(C_i)+M_d(C_i)
Ma(Ci)=Mi(Ci)+Md(Ci) 与Ci类相关联的 被引用的方法数 和 继承的方法数 |
---|---|---|---|
A | 无 | x(),y() | 2 |
B | A:x() | w(),y(),z() | 4 |
C | A:x(),B:w(),y(),z() | v() | 5 |
M I F = ( 0 + 1 + 4 ) / ( 2 + 4 + 5 ) = 5 / 11 MIF=(0+1+4)/(2+4+5)=5/11 MIF=(0+1+4)/(2+4+5)=5/11
-
通俗理解:所有类中,每个类中继承而来的方法数量之和 占 每个类实际含有的方法数总和 的比值
- 实际含有即包括 继承来的+自己声明的(重写的也算自己声明的)
-
PF
类 | M n ( C i ) M_n(C_i) Mn(Ci) Ci类中的新方法 | M o ( C i ) M_o(C_i) Mo(Ci) Ci类中覆盖的方法 | D C ( C i ) D_C(C_i) DC(Ci) 基类Ci的后代类的数量 |
---|---|---|---|
A | x(),y() | 无 | 2 |
z() | y() | 1 | |
C | v() | 无 | 0 |
P F = ∑ i = 1 T C M o ( C i ) ∑ i = 1 T C [ M n ( C i ) × D C ( C i ) ] PF=\frac{\sum\limits_{i=1}^{TC}M_o(C_i)}{\sum\limits_{i=1}^{TC}[M_n(C_i)\times D_C(C_i)]} PF=i=1∑TC[Mn(Ci)×DC(Ci)]i=1∑TCMo(Ci)
P F = 1 / ( 2 × 2 + 2 × 1 + 1 × 0 ) = 1 / 6 PF=1/(2\times2+2\times1+1\times0)=1/6 PF=1/(2×2+2×1+1×0)=1/6
- 通俗理解:评价多态程度的方法,即看所有类中重写(即覆盖)的方法占新方法的比值。
- 基类的新方法必定被子类继承,则乘以后代类数量
- 由于能覆盖方法的只能是子类,因此评价多态程度的对象只是子类,因此
- 新方法乘子类数量,就是统计子类的新方法总数
- 若子类已无后代类,则乘以0 是因为它已经作为子类被父类算过了
-9
序号 | 类 | i s _ c l i e n t is\_client is_client 类 |
---|---|---|
1 | 旅店管理 | 日历,客房,顾客,结算 |
2 | 日历 | 旅店管理,预约 |
3 | 客房 | 旅店管理,预约 |
4 | 顾客 | 旅店管理,预约 |
5 | 预约 | 日历,客房,顾客 |
6 | 结算 | 旅店管理 |
- 若是单向箭头,则算某类的关联数时,只有从该类指出的箭头 才算该类的关联 (书上例题p355)
- TC包括子类,计算is_client时则不包括子类
C F = ∑ i = 1 T C ∑ j = 1 T C i s _ c l i e n t ( C i , C j ) T C 2 − T C CF=\frac{\sum\limits_{i=1}^{TC}\sum\limits_{j=1}^{TC}is\_client(C_i,C_j)}{{TC}^2-TC} CF=TC2−TCi=1∑TCj=1∑TCis_client(Ci,Cj)
C F = 4 + 2 + 2 + 2 + 3 + 1 8 2 − 8 = 1 / 4 CF=\frac{4+2+2+2+3+1}{8^2-8}=1/4 CF=82−84+2+2+2+3+1=1/4
README
v1.2.2
2022.05.09
- 修改部分错别字
- 更正第九章5题
v1.2.1
2022.05.08
- 更正第十五章8题
- 更正第十五章9题
- 更正第四章3题
- 更正第十章3题
- 更新第十一章13题、第十三章8题(不一定是正确答案)
v1.2
2022.05.28
- 补完第十五章8、9题
- 经过询问经济学大佬,更正第四章24、27题答案
- 后几章答案基本为自己做的,无标准答案对照,出现纰漏请及时通知修改
v1.1
2022.05.27
- 补充了课后习题(除作图以外)
- 课后习题和知识点中有可以跳转的超链接(下划线标识,Ctrl+左键跳转)
v1.0
2022.05.26
- 启用腾讯云COS作为图床仓库,sm.ms弃用