Day1

软件是什么

软件 = 程序 + 数据 + 文档

软件分类

系统软件:管理计算机资源(windows,驱动程序等等)

支撑软件:帮助开发软件的软件(IDEA等等)

应用软件:给用户使用的软件(QQ等等)

软件的特点

复杂性:模块关系复杂,业务逻辑复杂,需求复杂

不可见性:出问题难以定位

服从性:软件必须服从外部需求

易变性:随着需求不断变化

软件危机

定义:软件开发和维护过程中遇到的一系列严重问题。

出现原因:60年代硬件发展快,软件开发跟不上,导致项目越来越大

软件危机表现:

1.规模越来越大

2.复杂度越来越高

3.开发速度慢

4.成本高

5.质量差

如何解决软件危机

重视需求分析

重视文档

充分测试

加强维护和管理

使用软件工程方法

什么是软件工程

核心就是用工程化的方法开发软件

本质:将问题域映射到计算机实现域。

软件工程三要素

方法:例如面向对象,结构化开发,告诉我们怎么做

工具:例如IDEA,git,帮助我们开发

过程:规定步骤

软件工程管理三要素

成本(维护阶段占比最高,持续维护,新需求,新bug)

质量

工期

软件工程基本原理

1.推迟实现:先分析,设计再编码

2.逐步求精:从粗到细

3.分解与抽象:复杂问题拆小

4 信息隐藏:只暴露接口

5.质量保证:保证软件符合需求

两种开发方法

结构化开发

自顶向下,逐步细化,面向过程

工具:

DFD

数据字典

结构图

面向对象开发

特点:

对象=数据+行为

面向对象优点

维护容易,扩展性强,复用性高

高内聚、低耦合

内聚:一个模块内部成员之间联系有多紧密

耦合:模块与模块之间依赖有多强

模块独立性的原则是什么?

高内聚,低耦合

什么是高内聚低耦合

1
2
3
4
5
高内聚是指模块内部各元素联系紧密,共同完成单一功能。

低耦合是指模块之间联系尽量减少,通过简单接口进行交互。

采用高内聚低耦合设计能够提高软件的可维护性、可扩展性和复用性。

为什么要高内聚低耦合

1
2
3
4
5
6
7
8
提高可维护性

提高可扩展性

降低修改影响

提高复用性

内聚性最好:功能性内聚(模块中的所有处理都围绕同一个功能展开);最差:偶然性内聚

耦合度最低:非直接耦合,数据耦合(数据耦合是模块之间仅通过参数传递数据进行联系);最高:内容耦合

Day2

瀑布模型

1
2
3
4
5
6
7
8
9
10
11
需求分析

概要设计

详细设计

编码

测试

维护

前一个阶段结束后才能进入下一阶段。

特点

1 顺序执行不能跳步骤。

2 文档驱动:每阶段都要写文档。

3 强调评审:每阶段结束要检查。

优点:管理方便,文档完整,适合规范项目

缺点:需求必须明确,用户参与少(开发完才能看见产品),风险发现较晚

增量模型

核心思想:不一次开发完,分批交互

系统分多个增量开发,每次交付部分功能。

优点:用户能尽快使用,风险小,易修改

缺点:需要良好的架构

快速原型模型

1
2
3
4
5
6
7
8
9
快速分析

构造原型

用户评价

修改原型

最终系统

优点:需求明确快,用户参与度高

缺点:容易忽视设计,原型可能质量差

适用于用户需求不明确的适合

螺旋模型

瀑布:需求变了很难改。

增量:风险控制一般。

原型:容易忽视整体设计。

螺旋模型 = 瀑布模型 + 原型模型 + 风险分析

特点:风险驱动

1
2
3
4
5
6
7
8
9
制定计划

风险分析

工程开发

客户评价

然后下一圈

适合做高风险项目

Day3

需求分析要解决的:用户需要软件做什么

可行性分析

判断项目值不值得做

包括:经济可行性, 技术可行性,法律可行性,方案可行性

怎么看要画什么图

题目说法 实际要画
结构化分析方法 DFD图
UML需求分析模型 用例图
UML行为模型 状态图、顺序图
UML动态模型 状态图、顺序图
UML静态模型 类图
需求分析模型 DFD 或 用例图

DFD(Data Flow Diagram数据流图)

用于描述数据如何流动和处理

四大元素:

1.外部实体:谁使用系统

1
2
3
┌─────┐
│ 学生 │
└─────┘

2.数据流:数据怎么流动

1
────►

3 加工(处理):系统做什么

1
○ 查询成绩

4 数据存储:数据库

1
║学生库║

画出银行取款过程的 DFD 图。问题描述为:储户用存折取款,首先填写取款单,根据“ 账卡”中的信息检验取款单与存折,如有问题,将问题反馈给储户,否则,登录“储户存款数据库”,修改相应数据,并更新“账卡”,同时发出付款通知,出纳向储户付款。

顶层:只有一个加工(只看系统和外界如何交互,不管内部如何交互)

image-20260608143926503

0层:把银行取款系统拆开

image-20260608144153583

平衡原则:父图与子图的输入输出数据流保持一致

1层:

image-20260608144528230

UML

状态图

状态图 = 状态 + 状态之间的转换

通常洗衣机包括一个注水的进水管,一个装衣物的洗涤缸和一个排水管,洗衣过程是浸泡、洗涤、漂洗、脱水,依次按如下顺序执行:

(1)通过进水管向洗涤缸注水。

(2)洗涤缸保持5分钟静止状态。

(3)水注满,停止注水。

(4)洗涤缸往返旋转15分钟。

(5)通过排水管排掉洗涤后的污水。

(6)重新开始注水。

(7)洗涤缸继续往返旋转洗涤。

(8)停止向洗衣机中注水。

(9)通过排水管排掉漂洗衣物的水。

(10)洗涤缸加快速度单方向旋转5分钟。

(11)洗涤缸停止旋转,洗衣过程结束。

如果以UML描述洗衣机的工作过程,请画出以洗衣机作为对象的状态图及洗衣机执行的顺序图。

image-20260608153208821

顺序图

先画出生命线,然后按题目步骤发送消息

image-20260608154047116

用例图

描述谁使用系统,以及系统提供哪些功能

现在有一个医院病房监护系统,用户提出的系统功能要求如下:在医院病房监护系统中,病症监视器安置在每个病房,将病人的病症信号实时传送到中央监视系统进行分析处理。在中心值班室里,值班护士使用中央监视系统对病员的情况进行监控,根据医生的要求随时打印病人的病情报告,系统会定期自动更新病历。当病症出现异常时,系统会立即自动报警,通知值班医生及时进行处理,同时立即打印病人的病情报告和更新病历。

分别画出采用结构化分析方法和UML 建模语言建立的需求分析模型。

image-20260608161445486

协作图

(1)画出银行取款过程的 DFD 图。问题描述为:储户用存折取款,首先填写取款单,根据“ 账卡”中的信息检验取款单与存折,如有问题,将问题反馈给储户,否则,登录“储户存款数据库”,修改相应数据,并更新“账卡”,同时发出付款通知,出纳向储户付款。

(2)如果银行储户在ATM上取款,同样需要身份认证及授权等处理过程,请画出ATM系统协作图。

image-20260608162827611

类图

关联(Association)

最常见。

1
学生 ---- 课程

聚合(Aggregation)

整体和部分。

1
2
3
4
5
医院 ◇──── 医生

//医院有医生。

//医生离开医院还能存在。

组合(Composition)

强拥有。

1
2
3
4
5
订单 ◆──── 订单项

//订单没了。

//订单项也没了。

继承(Generalization)

1
2
3
4
医生


主任医师

1 —— 1:一对一

1 —— *:一对多

*—— *:多对多

image-20260609193312858

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
┌────────────┐
│ 病人 │
├────────────┤
│ 病人编号 │
│ 姓名 │
│ 性别 │
│ 年龄 │
│ 联系方式 │
└────────────┘
1


*
┌────────────┐
│ 就诊记录 │
├────────────┤
│ 就诊编号 │
│ 就诊时间 │
│ 症状描述 │
│ 诊断结果 │
└────────────┘
*


1
┌────────────┐
│ 医生 │
├────────────┤
│ 医生编号 │
│ 姓名 │
│ 科室 │
│ 职称 │
└────────────┘


┌────────────┐
│ 护士 │
├────────────┤
│ 护士编号 │
│ 姓名 │
│ 科室 │
└────────────┘
1


*
┌────────────┐
│ 护理记录 │
├────────────┤
│ 护理编号 │
│ 护理时间 │
│ 护理内容 │
└────────────┘


┌────────────┐
│ 处方 │
├────────────┤
│ 处方编号 │
│ 药品名称 │
│ 数量 │
│ 用法 │
└────────────┘
*


1
┌────────────┐
│ 就诊记录 │
└────────────┘


┌────────────┐
│ 发票 │
├────────────┤
│ 发票编号 │
│ 金额 │
│ 收费时间 │
│ 收费项目 │
└────────────┘
*


1
┌────────────┐
│ 病人 │
└────────────┘

Day4

黑盒

等价类划分

把输入数据划分成若干个有代表性的集合,每个集合选一个数据测试。

目标:减少测试数量

1
1~100

例如50,满足要求,属于有效等价类(E1)

例如:

1
2
3
4
5
6
7
0

101

abc


不满足要求,属于无效等价类(空,非法字符等等)

边界值分析

选择边界值进行测试

1
2
3
4
5
6
7
8
9
10
11
12
13
最小值-1

最小值

最小值+1

最大值-1

最大值

最大值+1


白盒测试

语句覆盖

程序中每条语句至少执行一次。

例如:

1
2
3
4
5
if(a>0)
{
x++;
}
y++;

测试:

1
a=1

执行过程:

1
2
3
4
5
if成立

x++

y++

所有语句都执行到了。


所以:

1
语句覆盖率 = 100%

判定覆盖

每个判定的真假结果至少出现一次。

例如:

1
if(a>0)

需要:

1
a=1

得到:

1
True

再来:

1
a=-1

得到:

1
False

所以判定覆盖至少要两组数据。

条件覆盖

例如:

1
if(a>0 && b>0)

条件有:

1
2
3
a>0

b>0

要求:

每个条件都出现:

1
2
3
True

False

例如:

1
2
3
4
5
a=1 b=1

a=-1 b=1

a=1 b=-1

路径覆盖

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

1
2
3
4
5
6
7
if (a > 0) {
x++;
}

if (b > 0) {
y++;
}

这里有两个判断。

每个判断都有 True / False。

所以一共有 4 条路径:

1
2
3
4
路径1:a>0 真,b>0 真
路径2:a>0 真,b>0 假
路径3:a>0 假,b>0 真
路径4:a>0 假,b>0 假

对应测试用例:

路径 a b
TT 1 1
TF 1 -1
FT -1 1
FF -1 -1

这4组都测到,才叫路径覆盖。

强度大致:

1
路径覆盖 > 判定覆盖 > 语句覆盖

McCabe复杂度(圈复杂度)

McCabe复杂度就是衡量程序有多少条独立路径。

V(G) 越大

程序越复杂

V(G)=判定节点数+1

if

while

for

switch

这种会产生判断分支的语句就是判定节点

1
2
3
4
5
McCabe复杂度
=
独立路径数
=
至少需要设计的基本路径测试用例数

全都路径:

比如:

1
2
3
4
5
6
7
if(a>0)

if(b>0)

if(c>0)


三个独立判定。

每个判定:

1
2
3



两种情况。

所以:

1
2 × 2 × 2 = 8

流程图

image-20260610115417188

测试真题

黑盒

image-20260610133917656

image-20260610133937784

白盒

image-20260610120022776

1.流程图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
开始


k=0


x>0 && y>0 ?
┌───┴───┐
真 假
│ │
▼ ▼
k=x+y-10 k=x+y+10
\ /
\ /

k<0?
┌─┴─┐
真 假
│ │
▼ │
k=0 │
\ │
\ │

return k


结束


语句:

1
2
3
4
5
6
7
8
9
int k=0;

k=x+y-10;

k=x+y+10;

k=0;

return k;

判定:

1
2
3
if(x>0 && y>0)

if(k<0)

条件:

1
2
3
4
5
x>0

y>0

k<0

3.满足判定覆盖的测试用例

用例1:

1
2
3
x=1

y=1

用例2:

1
2
x=5
y=-1

4.满足条件覆盖的测试用例

用例1:

1
2
x=1
y=1

用例2:

1
2
x=-1
y=1

用例3:

1
2
x=1
y=-1
条件 True False
x>0
y>0
k<0

5.满足条件覆盖一定满足判定覆盖吗?

不一定。

举例:

1
2
3
4
5
if (A || B) {
// 走 True 分支
} else {
// 走 False 分支
}

测试:

1
2
3
用例 1:A = true,B = false (结果为 True)

用例 2:A = false,B = true (结果为 True)

Day5

UFP

项目 含义
Inp 输入数
Out 输出数
Inq 查询数
Maf 主文件数
Inf 接口文件数
项目 简单 平均 复杂
Inp 3 4 6
Out 4 5 7
Inq 3 4 6
Maf 7 10 15
Inf 5 7 10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
UFP

=

Inp×权重

+

Out×权重

+

Inq×权重

+

Maf×权重

+

Inf×权重

FP

1
FP = UFP × TCF

其中:

1
2
UFP = 未调整功能点
TCF = 技术复杂度因子

PM

1
2
3
4
5
工作量(pm)

=

FP ÷ 生产率

成本

1
2
3
4
5
成本

=

工作量 × 人月单价

真题

image-20260610144128698

image-20260610144140567

1
2
3
4
5
Inp = 5
Out = 6
Inq = 2
Maf = 1
Inf = 2

题目说简单级,查表:

1
2
3
4
5
Inp = 3
Out = 4
Inq = 3
Maf = 7
Inf = 5

所以:

1
2
3
4
UFP
= 5×3 + 6×4 + 2×3 + 1×7 + 2×5
= 15 + 24 + 6 + 7 + 10
= 62

如果没有给 TCF:

1
FP = 62

工作量:

1
62 ÷ 10 = 6.2 pm

成本:

1
6.2 × 10000 = 62000 美元