[toc]
软件设计师笔记_科目二_精简考点
科目二:软件设计(应用题,包括填空,问答,画图,补全程序代码等)。共6道大题,满分75分,需要达到45分才能合格。前4道题目必答,后2道题目二选一。
科目二知识点分布
| 题号 | 题目类型 | 章节 | 知识点 | 内容 |
|---|---|---|---|---|
| 第1题 | 必答题 | 第5章 软件工程基础知识 和 第6章 结构化开发方法 | 数据流图 DFD | 补充数据流图的缺失部分 |
| 第2题 | 必答题 | 第7章 面向对象 和 第 9 章 数据库系统 | 数据库设计 | E-R模型,关系模式,增加实体等 |
| 第3题 | 必答题 | 第7章 面向对象 | UML建模 | 类图,用例图,活动图,状态图等 |
| 第4题 | 必答题 | 第8章 算法设计 | C语言算法 | 分治法,谈心法,动态规划法,回溯法等 |
| 第5题 | 选答题 | 第 7 章 面向对象 | C++程序设计 | C++语法,设计模式 |
| 第6题 | 选答题 | 第 7 章 面向对象 | Java程序设计 | Java语法,设计模式 |
第一题 数据流图DFD
题型分析
给文字说明 + 不完整数据流图DFD,要求:
- 补外部实体
- 补数据流(最常考)
- 补数据存储
- 简答 DFD 平衡、父图子图等概念问题
基本概念
数据流图用于描述数据在系统中如何被传送或变换,以及如何对数据流进行变换的功能或子功能,主要用于对功能建模。
数据流图建模应遵循( 自顶向下、从抽象到具体 )的原则。

数据流图中的基本图形元素包括数据流、加工、数据存储和外部实体。 
- 外部实体: 是指存在于软件系统之外的人员、组织或其他系统;
- 数据流: 是由一组固定成分的数据组成,表示数据的流向;
- 加工: 是指输入数据流到输出数据流之间的变换;
- 数据存储: 用来表示存储数据。
数据字典(DD)
数据流图描述了系统的分解,但没有对图中各成分进行说明。
数据字典就是为数据流图中的每个数据流、文件、加工,以及组成数据流或文件的数据项做出说明。
数据流图的三大元素
外部实体
外部实体是指在当前系统之外的实体。例如人,物品,其他系统等。
图像用矩形表示。 英文一般用E1,E2表示。
举例的外部实体:
- 人:学生,老师,医生,客户等
- 物品:传感器,车辆。
- 其他系统:支付系统,订单系统等
数据加工
数据加工表示数据的处理。
加工描述了输入数据流到输出数据流之间的变换,也就是输入数据流经过什么处理后变成了输出数据流。
圆矩形表示数据加工。英文一般用P1,P2来表示。
注意:一个加工可以有多个输入数据流和多个输出数据流,但至少有一个输入数据流和一个输出数据流。
加工错误的情况
- 黑洞:是指只有输入没有输出的数据加工。
- 白洞:是指只有输出没有输入的数据加工。
- 灰洞:加工的输入数据不足以产生输出数据
数据存储
数据存储表示存储数据的介质。其中流入的表示写数据,流出的表示读数据。
图像用缺口矩形表示。英文一般用D1 D2 表示。
例子:客户表,学生表,订单文件等
数据流
数据流是指数据在系统中流动的路径。数据流用箭头表示。
数据流的流向:
- 数据流可以从 一个加工 流向 另一个加工。
- 数据流可以从 一个外部实体 流向 一个加工。表示实体输入数据给加工。
- 数据流可以从 一个加工 流向 一个外部实体。表示加工输出数据给实体。
- 数据流可以从 一个加工 流向 一个数据存储。表示写入数据到数据存储。
- 数据流可以从 一个数据存储 流向 一个加工。表示从数据存储读取数据。
注意:数据流与加工有关,且必须经过加工。即数据流的起点或终点必须有一个是加工。
数据流图基本设计原则
- 数据守恒原则:对任何一个加工来说,其所有输出数据流中的数据必须能从该加工的输入数据流中直接获得,或者说是通过该加工能产生的数据
- 守恒加工原则:对同一个加工来说,输入与输出的名字必须不相同,即使它们的组成成分相同。
- 对于每个加工,必须既有输入数据流,又有输出数据流
- 外部实体与外部实体之间不存在数据流
- 外部实体与数据存储之间不存在数据流
- 数据存储与数据存储之间不存在数据流
- 父图与子图的平衡原则:子图的输入输出数据流同父图相应加工的输入输出数据流必须一致,此即父图与子图的平衡。父图与子图之间的平衡原则不存在于单张图
- 数据流与加工有关,且必须经过加工。即数据流的起点或终点必须有一个是加工。
做题总结
第一题:找出图中的实体名称。
做题步骤:
- 参考图2和题目说明。根据说明中的词语,找出实体名称。所有的实体名称都会在题目说明中出现过。
- 若发现图中有多个E1,E2,E3 那是为了方便设计数据流图而导致的。
第二题:给出图中数据存储的名称
做题步骤:
- 推荐参考 图2和题目说明,找到数据存储的名称。
第三题:补充缺失的数据流起点终点
做题步骤:
- 一般是一条数据流对应1-2分。根据分数补充多少条数据流。
- 缺失数据流的名称和起点终点都可以从说明中获取.
- 推荐的书写格式或机考格式如图所示

有三种发现缺失的数据流的方法。
- 方法1:父图子图平衡。
根据图1和图2中的数据流名称,看图2中是否有缺失的数据流。并根据图1的提示进行补充。
即父图与子图的数据流必须一致(数据流名称和数量)。
- 方式2:加工既有输入数据流,也有输出数据流。
看图2中的加工是否有输入和输出数据流。若没有则表示该加工缺失数据流,需要进行补充。
- 方式3:数据守恒
根据题目说明与图2进行详细对比,看图2的数据流是否符合题目说明。若不符合则缺少数据流,需要根据说明对图2进行补充。
==注意:数据流的起点或终点必须有一个是加工。==
真题1
2014年上半年

【问题1】 使用说明中的词语,给出图1-1中的实体E1-E5的名称。
E1:巴士司机 E2:机械师 E3:会计 E4:主管 E5:库存管理系统
【问题2】 使用说明中的词语,给出图1-2中的数据存储D1-D4的名称
D1: 巴士列表文件 D2: 维修记录文件 D3: 部件清单 D4: 人事档案
【问题3】
补充图1-2中缺失的数据流及其起点和终点
答案:
3分表示有3条缺失的数据流。

真题2
2018年11月



- 问题1(4分) 使用说明中的词语,写出图1-1中的实体E1~E4的名称。
- 问题2(4分) 使用说明中的词语,写出图1-2中的数据存储DI~D4 的名称。
- 问题3(3分) 根据说明和图中术语,补充图1-2中缺失的数据流及其起点和终点。
- 问题4(4分) 根据说明和图中术语,写出图1-1中数据流的“客户信息”和“房源信息”的组成。
答案 
第二题 数据库设计
第二题 数据库设计一般考E-R模型,关系模式,增加实体等
题型分析
给出文字需求 + 不完整E-R图,要求:
- 补实体、属性、联系(1:1/1:n/m:n)
- E-R图 → 关系模式转换(主键、外键)→ 表的设计
- 判断范式(1NF/2NF/3NF/BCNF)
- 补 SQL(查询、连接、分组、子查询)
E-R 模型图
E-R 图中的主要构件如图所示。
- 实体:用矩形表示。
- 属性:用椭圆表示。
- 联系:用菱形表示,分为一对一(1:1)、一对多(1:n)、多对多(m:n)。

弱实体
弱实体用双边矩形表示。弱实体的存在必须以另一个实体为前提。例如实体A,B。只有当实体A存在的时候,实体B才会存在。那么实体B相对于实体A是弱实体。
如图只有当职工实体存在时,家属实体才存在。则家属实体为弱实体。 
父子实体
若实体A,B是父子关系。则实体A是实体B的父实体。
如图所示。职员实体和其他三个实体的关系是父子关系。 
==父子实体的联系需要加上小圆圈表示。子实体是用类似橡皮擦的图案表示。==
关系模式和指出主键外键 ⭐️
- 关系模式格式:关系名(属性1,属性2,属性3,...)
- 主键(PK):唯一标识元组的属性或属性组,用下划线标注
- 外键(FK):引用其他关系主键的属性,用于建立表间联系
==构建关系模式,可以理解为设计表==
E-R图转换为关系模式的规则 ⭐️⭐️
一对一关系(1:1)
方式1:合并法(常用)
- 先将两个实体转换为关系
- 任意选择其中一个实体的主键,作为外键加入另一个实体的属性中。
方式2:独立法
- 两个实体分别转换为关系
- 创建联系关系,包含两个实体的主键
如图所示 
一对多关系(1:n)⭐️
方式1:外键法(推荐)
- 两个实体分别转换为关系
- 将"1"方实体的主键加入"n"方关系作为外键
方式2:联系关系法
- 两个实体分别转换为关系
- 创建联系关系,包含双方主键,"n"方主键作为主键

多对多关系(m:n)⭐️
必须创建中间表:
- 两个实体分别转换为关系
- 将联系作为第三个实体,也转换为关系(中间表),包含两个实体的主键,共同作为联合主键

三个实体关系的转换 ⭐️
必须创建中间表:
- 三个实体分别转换为关系
- 将联系作为第四个实体,也转换为关系(中间表),包含三个实体的主键,共同作为联合主键
场景 1 : m : n(实体A:实体B:实体C = 1 : m : n)
- 实体 A (主键 Aid, 其他属性)
- 实体 B (主键 Bid, 其他属性)
- 实体 C (主键 Cid, 其他属性)
- 联系 R (Aid, Bid, Cid, 联系属性)
由于一个B、C 只能对应唯一一个 A,因此中间表的联合主键是(Bid, Cid)
场景 m:n:p(实体A:实体B:实体C = m : n : p)
- 实体 A (主键 Aid, 其他属性)
- 实体 B (主键 Bid, 其他属性)
- 实体 C (主键 Cid, 其他属性)
- 联系 R (Aid, Bid, Cid, 联系属性)
由于任意两方的关系都是多对多,因此中间表的联合主键是(Aid, Bid, Cid)
弱实体转换 ⭐️
弱实体(双边矩形)的转换:
- 先转换强实体
- 然后转换弱实体时,必须包含强实体的主键作为外键
- 弱实体的主键通常是自身属性+强实体主键
子类实体转换 ⭐️
泛化关系(父子实体)的转换:
- 方式1:单表法:父类和所有子类合并为一个表
- 方式2:多表法:父类一个表,每个子类一个表,子类包含父类主键作为外键
如图所示 
第一问:补充E-R图
如图是18年下半年的真题例子 
一般根据需求分析结果将E-R图进行补充。注意联系的名称如果没要求可以从需求分析结果中摘取。
答案如图所示 
第二问:补充关系模式,指出主键和外键
即根据问题一的E-R图转换为对应的关系模式。
如图所示,将关系模式中的a-c补充完整。 
==注意一个空可能要填多个属性。不光要从文字说明中找到对应属性,也要从E-R图中根据对应关系添加对应属性。==
答案

第三问:补充属性
假如问题是要你补充某个实体的属性。
- 从文字说明中找到对应属性。
- 可以根据其他问题中给出的关系模式来补充属性。
- 还需要根据实体之间的关系来补充属性。需要根据1:1、1:n、m:n的关系转换来对实体的属性进行加减。
例如实体A与实体B的关系是1:n。那么关系模式中实体B的属性中,需要把实体B的主键作为实体A的外键。但是E-R图中的实体B的属性中,不需要显示实体A的主键属性名称。
2018年下半年真题
问题


答案

2021年上半年真题
问题


题目中的完整性约束关系就是主键,外键的意思。
参考答案
问题1,问题2的答案图 
问题3的答案图: 
注意:图中答题的时候不光需要参考文字说明,还需要参考E-R图。或者参考其他问题中的描述信息。来答题。
例如需要参考若两个实体之间的m:n的关系。那么关系模式中的有的属性,就可以不需要直接显示在E-R图中。即补充E-R图的时候,要考虑到实体之间的关系。从而对E-R图的属性进行加减。
2021年下半年真题
问题


参考答案

第三题 UML建模(以类图 / 用例图 / 时序图为主)
题型分析
给文字说明 + 不完整UML类图,需要补充:
- 用例图:参与者、用例、关系(包含 / 扩展 / 泛化)
- 类图:类、属性、方法、关系(关联 / 聚合 / 组合 / 继承 / 依赖)
- 时序图:对象、消息顺序、调用关系
UML图类型汇总 ⭐️⭐️
| 图类型 | 用途 | 核心元素 |
|---|---|---|
| 类图 | 描述系统的静态结构 | 类、接口、关系 |
| 用例图 | 描述系统功能 | 参与者、用例、关系 |
| 活动图 | 描述业务流程 | 活动、决策节点、泳道 |
| 状态图 | 描述对象状态变化 | 状态、转换、事件 |
| 顺序图 | 描述对象交互 | 对象、生命线、消息 |
| 协作图 | 描述对象协作 | 对象、链接、消息 |
类图 ⭐️⭐️⭐️
类图展现一组对象、接口、协作和它们之间的关系。
类的组成:
- 类名(上部)
- 属性(中部):可见性 + 名称 : 类型
- 方法(下部):可见性 + 名称(参数) : 返回类型
可见性符号:
+public(公有)-private(私有)#protected(保护)~package(包)

示例

图中聚集有聚合和组合的意思。主要是根据图案来确定到底是聚合还是组合。
- Company 与 Department/Office 的实心菱形表示组合关系。
- 整体:Company(公司)。1:多个Department(部门)、Office(办公室)
- 部分:Department(部门)、Office(办公室)
- 图中 Department 和 Office 的实线表示关联关系。表示存在业务关联。
- 图中Department 与 Person 之间有两个实线。表示如下
- member:表示“成员” 的关联,多重度 1..* → 一个部门有 1 名以上成员
- manager:表示“管理者” 的关联,多重度 1 → 一个部门有且仅有 1 名管理者
- Office 与 Headquarters 的空心三角箭头。是泛化关系。
- 表示Office是Headquarters的父类。
- 从 Person 指向 PersonRecord 的虚线箭头。
- 表示Person 指向 PersonRecord 有依赖关系。即Person依赖于PersonRecord。
UML类图中的关系总结(依赖/关联/聚合/组合/泛化/实现) ⭐️⭐️⭐️
UML 中有四种关系:依赖,关联,泛化,实现。
关系按耦合强度从弱到强排序: 依赖 < 关联 < 聚合 < 组合 < 泛化 < 实现
- 依赖关系:一个事物发生变化影响另一个事物。若类A的方法中仅仅使用了类B的对象,那么类A依赖于类B。若A依赖于B,则A在箭头起点,B在箭头终点。用实现箭头表示。
- 关联关系:(分为普通关联、聚合关联和组合关联)
- 普通关联:类与类之间,对象与对象之间的一种结构关系。可以表示1:1或者1:n或m:n。用实线表示。
- 聚合关系:整体与部分的生命周期不同。整体消失了,部分任然可以存在。双方是独立的。类似学校和学生。用空心菱形表示。指向整体。
- 组合关系:整体与部分的生命周期相同。整体消失了,部分也会消失。双方不是独立的。类似汽车和零件。用实心菱形表示。指向整体。
- 泛化关系:泛化是一个类与它的一个或多个细化类之间的关系,类似父类和子类。一般/特殊关系。用空心三角箭头表示。指向父类。
- 实现关系(很少考):类似接口与类之间的关系。用虚线空心三角箭头表示。指向接口类。
如图所示各个关系的画图 
普通关联关系上的0..1表示0个或1个。0..*表示0个或多个。
记忆点:
- 依赖关系:类A依赖于类B,那么类A的方法中使用了类B的对象。一个事物发生变化影响另一个事物。
- 关联关系:(分为普通关联、聚合关联和组合关联)
- 普通关联:类与类之间,对象与对象之间的一种结构关系。表示双方有1:1或者1:n或m:n的关系。
- 聚合关系:整体与部分的生命周期不同,是聚合在一起的。可分离。整体没了,部分还能活。
- 组合关系:整体与部分的生命周期相同,是组合在一起的。不可分离。整体没了,部分也没了。
- 泛化关系:类似父类,子类。特殊/一般关系。
- 实现关系:类似接口和实现类。
用例图 ⭐️⭐️⭐️
用例图展现了一组用例、参与者和它们之间的关系。
- 参与者:人、硬件或其他系统扮演的角色,用小人表示
- 用例:参与者完成的一系列操作,用椭圆表示
- 关系:包含(必须要做)、扩展(可做可不做)、泛化等。用各种箭头表示。
示例

- 参与者(Actor)
- Student(学生):普通学生参与者
- International Student(国际学生):通过泛化关系继承自Student
- 椭圆符号代表用例,即系统提供的功能或操作:
- Enroll Student in University(大学入学注册):核心主用例
- Enroll in Seminar(注册研讨会):被包含的子用例
- Perform Security Check(执行安全检查):扩展用例
- Enroll Family Member(注册家庭成员):泛化用例
用例就是一些功能。或者说是一些操作。补充用例就是补充操作。用例是动词,而不是名词。
注意:用例图的包含,扩展,泛化关系。和 类图中的各个关系。是不同的。
用例图中的关系总结(包含/扩展/泛化) ⭐️
关联关系
- 实线。一般是用户 和 用例之间的实线。表示用户触发了该用例。
- 例如:用户A —————— 用例B。表示用户A使用了用例B
包含关系(<<
include>>)
- 箭头指向被包含用例。主用例必须执行被包含的用例(必选步骤)
- 例如:A --include --> B。就是A包含B的意思。相当于执行A则必须执行B。
- include的逻辑是:若A包含B。则调用A的时候必须会调用B。例如购物功能必须包含支付功能。
扩展关系(<<
extend>>)
- 箭头指向被扩展用例。主用例可以不执行被扩展的用例(可选步骤)
- 例如:A --extend --> B。就是A扩展B的意思。相当于执行A则可选执行B。
- extend的逻辑是:若A扩展B。则调用A时,可以可选的调用B。例如购物功能可选的使用优惠卷功能。
泛化关系(<<
generalization>>)
- 箭头指向被泛化的用例。空心三角箭头表示。表示子用例 / 子参与者 → 父用例 / 父参与者
- 例如:A --generalization --> B。就是A是B的父类的意思。相当于B是A的一个子类。
- generalization的逻辑是:若A是B的父类。则调用A时,会调用B。例如购物功能是支付功能的父类。
注意:用例图的包含,扩展,泛化关系。和 类图中的各个关系。是不同的。
第一问 补充用例图
一般是补充用例图中的用例(用椭圆表示)。用例是指参与者完成的一些操作。
用例就是一些功能。或者说是一些操作。补充用例就是补充操作。用例是动词,而不是名词。
一般根据说明来猜出用例图中缺失的部分。
第二问 补充类图
一般来说是补充类图。可以根据说明中用英文标注的单词。推测出每个单词表示一个类。
- 先找出类图中的具有父类子类关系和接口实现类的关系。
- 然后根据说明中描述的数量关系,来与类图中的类进行一一比对。
- 从而将类图中的类与说明中的名词进行绑定。
例如文字说明中机器人有两种类型,表示机器人这个类有两个子类。机器人有两个传感器功能,表示机器人有一个传感器接口,该接口有两个实现类。
也有可能通过第三问的题干,推出第二题的答案。
真题
21年下


真题
21年上


真题
19年下


真题
2018年11月


答案 
第四题 算法设计 ⭐️⭐️
题型分析
给出经典算法 + 不完整 C 代码,填 5~6 个空
必考算法(按频率排序)
- 动态规划(DP)★★★★★(几乎每年)
- 0/1 背包、最长公共子序列 LCS、最长递增子序列、矩阵连乘
- 填空:状态初始化、转移方程、边界条件、结果输出
- 贪心算法
- 活动安排、哈夫曼编码、最小生成树(Prim/Kruskal)
- 分治法
- 二分查找、归并排序、快速排序
- 回溯 / 递归
- 全排列、子集和、树的遍历
解题套路
- 先看问题类型 → 确定 动态规划(DP) / 贪心 / 分治
- 找状态定义(DP 核心)
- 补转移方程(最常空)
- 补初始化 / 边界
- 补结果返回 / 打印
答题技巧
- 理解题目要求:明确输入输出格式和约束条件
- 选择合适算法:根据问题特征选择分治、动态规划等
- 编写伪代码:先设计算法框架
- 注意边界条件:空输入、边界值、特殊情况
- 测试用例验证:用简单例子验证算法正确性
- 优化空间时间:考虑时间复杂度和空间复杂度
第五题 C++程序设计 或 第六题 java程序设计 (二选一)
主要考补全代码,程序填空题,重点考察面向对象概念和设计模式。
题型分析
先给场景,识别设计模式。然后根据设计模式,补全代码(接口、继承、多态、方法实现)。
高频设计模式(6 个必考)
- 单例模式:全局唯一实例(私有构造、静态 getInstance)
- 工厂模式(简单 / 工厂方法 / 抽象工厂):对象创建解耦
- 策略模式:封装不同算法,可互换
- 观察者模式:一对多,状态变化通知所有观察者
- 装饰器模式:动态给对象加功能
- 适配器模式:接口不兼容,需要做转换
程序填空答题技巧 ⭐️
- 分析类图关系:根据箭头判断继承、实现、关联等关系
- 理解代码结构:通读代码,理解整体框架
- 关注语法细节:注意分号、括号、访问修饰符
- 结合上下文:根据前后代码推断缺失内容
- 使用题目术语:变量名、方法名要与题目一致
Java程序设计 ⭐️⭐️
关键字汇总
| 关键字 | 用途 | 示例 |
|---|---|---|
| extends | 类继承 | class B extends A |
| implements | 实现接口 | class D implements C |
| abstract | 抽象类/方法 | abstract class A |
| interface | 定义接口 | interface C |
| final | 常量/不可继承 | final int MAX=100 |
| static | 静态成员 | static int count |
| this | 当前对象引用 | this.name = name |
| super | 父类引用 | super.show() |
类继承
class A{
String name;
}
class B extends A{
int age;
}抽象类和抽象方法
abstract class A{
public abstract int show(); //抽象方法
}接口
//用interface关键字声明接口
interface C{
void show(); //抽象方法,默认为public abstract
}
//用implements关键字实现接口C
class D implements C{
public void show() { //对接口的实现
System.out.println("show");
}
}根据类图中的箭头图案,推测出类之间的关系。并推测出对应的代码 
异常处理
try {
// 可能抛出异常的代码
} catch (Exception e) {
// 异常处理
} finally {
// 无论是否异常都会执行
}集合框架
| 接口 | 实现类 | 特点 |
|---|---|---|
| List | ArrayList | 动态数组,随机访问快 |
| List | LinkedList | 链表,插入删除快 |
| Set | HashSet | 无序,不重复 |
| Set | TreeSet | 有序,不重复 |
| Map | HashMap | 键值对,无序 |
| Map | TreeMap | 键值对,有序 |
C++程序设计
关键字汇总
| 关键字 | 用途 | 示例 |
|---|---|---|
| class | 定义类 | class A |
| public/private/protected | 访问控制 | public: |
| virtual | 虚函数 | virtual void show() |
| override | 重写虚函数 | void show() override |
| extends | 继承 | class B : public A |
| const | 常量 | const int MAX=100 |
| static | 静态成员 | static int count |
| this | 当前对象指针 | this->name = name |
类继承
class A {
public:
string name;
};
class B : public A {
public:
int age;
};虚函数和多态
class Shape {
public:
virtual double area() = 0; // 纯虚函数
};
class Circle : public Shape {
public:
double area() override {
// 实现
}
};