这门是厦门大学计科大四上的专业课,一学期一点都没学,全在玩了(保研完了是这样的)。
下面是本人用时一天的速通笔记。(基本上直接面向做题)
2 项目管理
在估算软件项目规模的适合,直接方法是代码行数LOC,间接方法是功能点FP。
LOC
LOC,Lines of Code,代码行数,用来估计软件项目的规模大小。
一般每个模块有三个估计值:
- 乐观值(最理想情况):4,600行
- 可能值(最可能情况):6,900行
- 悲观值(最坏情况):8,600行
估算期望值的公式
FP
FP,Funcition Point,功能点。这里有几个概念:FP, UFP, AFP
FP是功能点,包括UFP(未调整功能点,Unadjusted Function Point)和AFP(调整后功能点,Adjusted Function Point)
UFP,考虑功能数量、功能本身的复杂度(简单还是复杂):
一般来说,会考虑外部输入EI、外部输出EO、外部查询EQ、内部逻辑文件ILF、外部接口文件EIF,这五个部分。
通常的权重表如下:

AFP,加上了系统技术难度的考虑。
如何加上技术难度的考虑呢?引入一个 作为技术复杂度调整系数公式
TCF一般考虑14个复杂度因子:

然后最后调整后的AFP
一般还要计算一个人月,生产率一般是 10~20 FP/人月
**题1:**假设某个项目的功能点统计如下。

且技术复杂度因子评分综合为30,团队的生产率为 15FP/人月。
计算项目的人月。
解答:
挣值分析
定量估算项目进度。
BAC,Buget At Completion,总预算。(比如,总预算,582人日)
BCWS,Budgeted Cost of Work Scheduled,预算工作成本。也就是说,到今天为止,应该完成的工作量,按预算价格算。(比如,预计完成15个任务,“计划工作量”之和 = 156.5人日)
BCWP,Budgeted Cost of Work Performed, 实际工作值的成本,也就是说,到今天为止,实际上完成的工作量,也是按预期算。(实际值完成12个任务,用计划工作量,完成了126.5人日)
ACWP,Actual Cost of Work Performed,实际工作花的钱。也就是说,实际上我们花了多少时间。(实际完成12个任务,实际上花了127.5人日)
NOTE我的理解就是,BCWS,大饼,意思是,我计划要干多少工作量。
BCWP,实绩,我实际干完的活,按照原先的预算,值多少钱。
ACWP,实际成本,我实际上花了多少钱。
由此衍生出来
SPI,Schedule Performance Index,计划表执行指标
如果SPI=1.0,刚好符合计划。SPI>1.0,卧槽超额完成!SPI<1.0,有点垃圾了慢吞吞的。
SV,Schedule Variance,进度表偏差
同理,SV=0,刚好。SV>0,很牛逼了很快。SV<0,很慢了。
CPI,Cost Performance Index,成本执行指标。
同理同理。
CV,Cost Variance,成本偏差
同理。
题1: 假设你是一个软件项目管理者,受命为一个小型软件项目进行挣值统计。这个项目共计划了56个工作任务,估计需要582人日才能完成,但是,按照项目进度,现在应该完成15个任务,下面给出相关进度安排数据(单位:人日)
请你做出挣值分析,计算该项目的进度表执行指标SPI、进度偏差SV、预定完成百分比、完成百分比、成本执行指标CPI和成本偏差CV。
| 任务 | 计划工作量 | 实际工作量 |
|---|---|---|
| 1 | 12.0 | 12.5 |
| 2 | 15.0 | 11.0 |
| 3 | 13.0 | 17.0 |
| 4 | 8.0 | 9.5 |
| 5 | 9.5 | 9.0 |
| 6 | 18.0 | 19.0 |
| 7 | 10.0 | 10.0 |
| 8 | 4.0 | 4.5 |
| 9 | 12.0 | 10.0 |
| 10 | 6.0 | 6.5 |
| 11 | 5.0 | 4.0 |
| 12 | 14.0 | 14.5 |
| 13 | 16.0 | - |
| 14 | 6.0 | - |
| 15 | 8.0 | - |
解答:
Budget Cost of Work Scheduled, BCWS
Budget Cost of Work Performed, BCWP
Acutal Cost of Work Performed, ACWP
所以SPI,Scheduled Performance Index
进度偏差,Scheduled Variance
预定完成百分比
完成百分比
成本执行指标CPI,Cost Performance Index
成本偏差CV, Cost Variance
缺陷放大和消除
缺陷放大模型

这里通过的错误,意思是传递下去了
假设设计阶段有10个错误传给编码阶段:
| 错误类型 | 数量 | 说明 |
|---|---|---|
| 通过的错误 | 5个 | 设计的错,编码时没发现,原样保留 |
| 放大的错误 | 3个→9个 | 设计的3个错,导致编码时产生9个bug(放大3倍) |
| 新产生的错误 | 6个 | 编码自己犯的新错(比如语法错误) |
| 传到下一步 | 20个 | 5+9+6 = 20个错误传给测试阶段 |
比如:


4 软件设计
这一部分重点是结构化程序设计。
比如一个判断三角形类型的代码,可以写成这样:
(写成这样也是神人了,总之意思就是写得乱七八糟的,goto乱飞。)

然后如果改成结构化写法,就改成这样:

老师的PPT这样的:

我的理解如下。
病形程序就是有死路的程序,烂代码。比如死循环什么的。反正就是史,有BUG,永远达不到结束。
好形程序就是正常写,没有死路,但是可能有多出口,具体表现就是,可能有不止一个return。
适形程序,就是单出口,只有一个return。
我们希望的最好的程序,被称为适形程序(单入单出的好形程序)
**结构程序定理:**任何一个适形程序都可以转换为一个等价的结构程序, 使用原来功能框和判定框及赋值和测试一个附加的变量。
TIP(PPT上叽里咕噜说了那么多,我的理解是,简单来说,就是任何程序,都可以去掉
goto,改成全部使用if和while这样的。)
数据流图、程序结构图
这里一个经典考题是数据流图转程序结构图。
**题1:**请将以下图书销售系统数据流图转换为程序结构图。

解答:
在数据流图中:
- 蓝色方框,是外部实体。系统外的人或组织。
- 黄色圆圈是处理过程。
- 然后那些底部带线方框,是数据表。
怎么把数据流图转成程序结构图?核心是变换分析。

然后再看前面的图

画出来

判定表、判定树
判定表和判定树,都是用来专门处理有很多if条件的情况。
举个例子,假设要写一个程序:计算飞机托运费。
规则很复杂:
- 国内乘客和国外乘客收费不同
- 残障乘客有优惠
- 超重部分要额外收费
- 不同情况收费标准不一样
如果要直接写代码,会有大量的嵌套if-else。这样:
if (国内乘客) { if (残障) { if (超重) { // ... } else { // ... } } else { if (超重) { // ... } }} else { // ...一堆嵌套}然后判定表、判定树,就是在写代码之前,先把所有情况理清楚的,理清有多少种条件、每种组合应该做什么。
这样做完后,一目了然,写代码就不会漏情况。
判定表

如上图,红色区域是条件列表,绿色区域是处理结果。
怎么看这个表呢,右边两个区域,竖着看,比如:

这一列,意思是,如果满足
- 功率>50马力(Yes),是
- 维修记录不全(Yes),是
- 已运行>10年(Yes),是
那么,处理的结果是优先处理。
同理,下一列就是,如果满足
- 功率>50马力(Yes),是
- 维修记录不全(Yes),是
- 已运行>10年(No),否
那么,处理的结果也是优先处理。
**题1:**假设某航空公司规定,乘客可以免费托运重量不超过30kg的行李
- 当行李重量超过30kg时,对头等舱的国内乘客超重部分每公斤收费4元,对其他舱的国内乘客超重部分每公斤收费6元
- 对外国乘客超重部分每公斤收费比国内乘客多一倍;对残障乘客超重部分每公斤收费比正常乘客少一半。
解答:
条件有这些:
- 行李重量 W 小于30kg
- 国内乘客(否则外国乘客)
- 头等舱
- 残障乘客
处理方式:
- 免费
- (W-30)*4
- (W-30)*6
- (W-30)*8
- (W-30)*12
- (W-30)*2
- (W-30)*3
| 行李重量 W 小于30kg | Y | N | N | N | N | N | N | N | N |
|---|---|---|---|---|---|---|---|---|---|
| 国内乘客(否则外国乘客) | Y | Y | Y | Y | N | N | N | N | |
| 头等舱 | N | Y | N | Y | N | Y | N | Y | |
| 残障乘客 | N | N | Y | Y | N | N | Y | Y | |
| 免费 | √ | ||||||||
| (W-30)*2 | √ | ||||||||
| (W-30)*3 | √ | ||||||||
| (W-30)*4 | √ | √ | |||||||
| (W-30)*6 | √ | √ | |||||||
| (W-30)*8 | √ | ||||||||
| (W-30)*12 | √ |
(这里第一列已经是优化后的结果了,对于 行李重量 W 小于30kg 为Y的,不需要重复后面的其他元素判定。
**题2:**某银行发放贷款原则如下:
-
对于贷款未超过限额的客户,允许立即贷款。
-
对于贷款超过限额的客户,若过去还款记录好且本次贷款在2万元以下,可作出贷款安排;否则拒绝贷款。
请绘出发放贷款的判定表并优化
TODO
**题3:**某维修站对“功率大于50马力”的机器且“维修记录不全”或“已运行十年以上”的机器应给予优先维修,否则作一般处理。请绘制决策表。
TODO
判定树
判定表含义比较复杂,需要理解一下,含义不清晰,而且数据元素比较多的时候,有点复杂。
所以有判定树,作为判定表的变种,更一目了然。
前面的题1,就可以画成下面这样:

优点是形式很简单,缺点是最后一个数据元素(比如残疾乘客/正常乘客)要写好多遍。
**题1:**某图书发行公司采用下列政策优惠用户。
-
书店订购20册以上优惠25%,否则不优惠;
-
图书馆和个人订购6册以下则不优惠;6—19册则优惠5%,20—49册则优惠10%,50册以上则优惠15%。
提示:有多少种备选方案,决策树就有多少个分枝。
解答:

5 软件建模
状态图
状态图是类似下面这样子的:

这里其中的do/action意思是,里面可以嵌套其他的状态。
NOTE其中,Event(事件) = “发生了什么” → 触发器 Condition(条件) = “是否满足要求” → 检查器
想象你在家里:
- Event(事件): 门铃响了 ← 这是一个”发生的动作”
- Condition(条件): 检查猫眼看是不是快递员 ← 这是一个”判断条件”
- Action(动作): 开门 ← 这是你要执行的操作
写出来就是
门铃响了 [是快递员] / 开门Event [Condition] / Action
Condition是可以不需要的,比如:按钮按下 / 启动不需要任何条件,按下就启动。
举个例子1:

其中这种地方:

是可以嵌套的。
比如:

可以看见,往里面嵌套了Get Coffee的具体的东西。
题1: 某信用卡系统账户具有使用状态和冻结状态,其中使用状态又包括正常状态和透支状态两种子状态。
如果账户余额小于零则进入透支状态,透支状态时既可以存款又可以取款,但是透支金额不能超过5000元;
如果余额大于零则进入正常状态,正常状态时既可以存款又可以取款;
如果连续透支100天,则进入冻结状态,冻结状态下既不能存款也不能取款,必须要求银行工作人员解冻。
用户可以在使用状态或冻结状态下请求注销账户。
解答:

6 软件测试
MTTF计算题
MTTF,Mean Time To Failure,是平均无故障时间。
也就是说,程序平均能运行多久才会出错。
做题是基于一个叫“Shooman模型”的公式:
可以写成:
上面,程序总错误数 ,一般来说是题目要我们求的(也就是程序总共估计有多少个Bug,在测试过程中没测试完前,只能估计出来)
然后 是一个常数,一般也是未知数,是一个固定的系数,不需要理解含义,算出来就行。
然后MTTF与测试时间,在做题时假设是线性关系。
题1:对一个长度为100000条指令的程序进行集成测试期间记录如下面的数据:
(A) 7月1日集成测试开始没有发现错误
(B) 8月2日总共改正了100个错误,此时MTTF=0.4H
(C) 9月1日:总共改正300个错误,此时MTTF=2H.
根据上述数据完成下列各题:
(1) 估计程序中的错误总数
(2) 为使MTTF达到10H必须测试和调试这个程序多长时间?
解答:
(1)列方程
解得:
也就是总错误数
(2)
如果
得到
截止到9月1日,总共已经改正300个错误,还剩40个。
**题2: **对一个包含10000条机器指令的程序进行一个月集成测试后,总共改正了15个错误,此时MTTF= 10h;经过两个月测试后,总共改正了25个错误(第二个月改正了10个错误) ,MTTF= 15h。
要求:
(1) 根据上述数据确定MTTF与测试时间之间的函数关系,画出MTTF与测试时间τ的关系曲线。在画这条曲线时做了什么假设?
(2) 为做到MTTF= 100h,必须进行多长时间的集成测试?当集成测试结束时总共改正了多少个错误,还有多少个错误潜伏在程序中?
解答:
(1)假设MTTF与测试时间是线性关系。
一个月集成测试后,MTTF=10h,也就是说,,
两个月后,同理,,
解得
曲线:
(2)
也就是19个月。
然后要算还剩多少个错误,需要来算
解得到
当 ,剩余 3 个错误。

