试题一:学生跟踪系统数据流图分析
阅读下列说明和数据流图,回答问题 1 至问题 4。
【说明】
某学校欲开发一学生跟踪系统,以便更自动化、更全面地对学生在校情况(到课情况和健康状态等)进行管理和追踪,使家长能及时了解子女的到课情况和健康状态,并在有健康问题时及时与医护机构对接。该系统的主要功能是:
(1) 采集学生状态。通过学生卡传感器,采集学生心率、体温(摄氏度)等健康指标及其所在位置等信息并记录。每张学生卡有唯一的标识(ID)与一个学生对应。
(2) 健康状态告警。在学生健康状态出问题时,系统向班主任、家长和医护机构健康服务系统发出健康状态警告,由医护机构健康服务系统通知相关医生进行处理。
(3) 到课检查。综合比对学生状态、课表以及所处校园场所之间的信息对学生到课情况进行判定。对旷课学生,向其家长和班主任发送旷课警告。
(4) 汇总在校情况。定期汇总在校情况,并将报告发送给家长和班主任。
(5) 家长注册。家长注册使用该系统,指定自己子女,存入家长信息,待审核。
(6) 基础信息管理。学校管理人员对学生及其所用学生卡和班主任、课表(班级、上课时间及场所等)、校园场所(名称和所在位置区域)等基础信息进行管理;对家长注册申请进行审核,更新家长状态,将家长ID加入学生信息记录中使家长与其子女进行关联,向家长发送注册结果。一个学生至少有一个家长,可以有多个家长。课表信息包括班级、班主任、时间和位置等。
现采用结构化方法对学生跟踪系统进行分析与设计,获得如图1-1所示的上下文数据流图和图1-2所示的0层数据流图。


【问题 1】(5分)
使用说明中的词语,给出图 1-1 中的实体 E1~E5 的名称。
【问题 2】(4分)
使用说明中的词语,给出图 1-2 中的数据存储 D1~D4 的名称。
【问题 3】(3分)
根据说明和图中术语,补充图 1-2 中缺失的数据流及其起点和终点(三条即可)。
【问题 4】(3分)
根据说明中的术语,说明图 1-1 中数据流“学生状态”和“学生信息”的组成。
【答案解析】
【问题 1】
- E1:学生卡传感器
- E2:管理人员
- E3:班主任
- E4:家长
- E5:医护机构健康服务系统
解析:根据功能描述定位数据源和接收者。E1是采集学生状态的数据源,对应“学生卡传感器”;E2提交家长注册申请,对应“管理人员”;E3接收旷课警告、在校情况报告,对应“班主任”;E4接收注册结果、旷课警告、在校情况,对应“家长”;E5接收健康状态警告,对应“医护机构健康服务系统”。
【问题 2】
- D1:学生状态记录
- D2:学生基础信息
- D3:校园场所信息
- D4:课表信息
解析:根据数据存储的内容判断。D1存储采集到的学生状态数据;D2存储学生基础信息;D3存储校园场所数据;D4存储课表相关数据。
| 【问题 3】 |
起点 |
终点 |
数据流 |
| D4(课表) |
P3(到课检查) |
课表信息 |
| D3(校园场所) |
P3(到课检查) |
场所信息 |
| D5(家长) |
P4(汇总在校情况) |
家长信息 |
解析:考查数据流图的完整性和一致性。对照上下文图和0层图,发现内部数据流缺失。
- 加工P3“到课检查”需要综合课表、校园场所信息,因此缺失从D4、D3流向P3的数据流。
- 加工P4“汇总在校情况”需要生成报告给家长,因此需要获取家长信息,缺失从D5流向P4的数据流。
【问题 4】
- 学生状态:学生ID、心率、体温、所在位置、采集时间
- 学生信息:学生ID、姓名、班级、班主任、关联的家长ID列表
解析:根据说明进行归纳。
- 学生状态:来自功能(1),包含学生卡ID(对应学生ID)、健康指标(心率、体温)、位置信息,可补充采集时间。
- 学生信息:来自功能(6),包含学生基础身份信息、关联的班级班主任,以及关联的家长ID(一个学生可关联多个家长)。
试题二:创业孵化基地数据库设计
阅读下列说明,回答问题 1 至问题 3。
【说明】
某创业孵化基地管理若干孵化公司和创业公司,为规范管理创业项目投资业务,需要开发一个信息系统。请根据下述需求描述完成该系统的数据库设计。
【需求分析结果】
(1) 记录孵化公司和创业公司的信息。孵化公司信息包括公司代码、公司名称、法人代表名称、注册地址和一个电话;创业公司信息包括公司代码、公司名称和一个电话。孵化公司和创业公司的公司代码编码不同。
(2) 统一管理孵化公司和创业公司的员工。员工信息包括工号、身份证号、姓名、性别、所属公司代码和一个手机号,工号唯一标识每位员工。
(3) 记录投资方信息。投资方信息包括投资方编号、投资方名称和一个电话。
(4) 投资方和创业公司之间依靠孵化公司牵线建立创业项目合作关系,具体实施由孵化公司的一位员工负责协调投资方和创业公司的一个创业项目。一个创业项目只属于一个创业公司,但可以接受若干投资方的投资。创业项目信息包括项目编号、创业公司代码、投资方编号和孵化公司员工工号。
【概念模型设计】
根据需求阶段收集的信息,设计的实体联系图(不完整)如图 2-1 所示。

【逻辑结构设计】
根据概念模型设计阶段完成的实体联系图,得出如下关系模式(不完整):
- 孵化公司(公司代码,公司名称,法人代表名称,注册地址,电话)
- 创业公司(公司代码,公司名称,电话)
- 员 工(工号,身份证号,姓名,性别,(a),手机号)
- 投资方(投资方编号、投资方名称,电话)
- 项 目(项目编号,创业公司代码,(b),孵化公司员工工号)
【问题 1】(5分)
根据问题描述,补充图 2-1 的实体联系图。
【问题 2】(4分)
补充逻辑结构设计结果中的 (a)、(b) 两处空缺及完整性约束关系。
【问题 3】(6分)
若创业项目的信息还需要包括投资额和投资时间,那么:
(1) 是否需要增加新的实体来存储投资额和投资时间?
(2) 如果增加新的实体,请给出新实体的关系模式,并对图 2-1 进行补充。如果不需要增加新的实体,请将“投资额”和“投资时间”两个属性补充连线到图 2-1 合适的对象上,并对变化的关系模式进行修改。
【答案解析】
【问题 1】
补充后的实体联系图如下:

解析:根据需求(4)分析实体间联系。
- 创业公司与员工:存在管理联系(1:*)。
- 创业公司与项目:拥有联系(1:1)。
- 投资方与项目:投资联系(:)。一个项目可被多个投资方投资,一个投资方可投资多个项目。
- 孵化公司员工与项目:协调联系(1:*)。一位员工可协调多个项目。
【问题 2】
- (a):所属公司代码
完整性约束:外键,参照孵化公司.公司代码或创业公司.公司代码。工号为主键。
- (b):投资方编号
完整性约束:外键,参照投资方.投资方编号。项目编号为主键。同时,创业公司代码参照创业公司.公司代码,孵化公司员工工号参照员工.工号。
解析:
- (a) 员工需归属到某个公司,因此需要“所属公司代码”属性,并作为外键。
- (b) 项目需要关联投资方,因此需要“投资方编号”属性,并作为外键。这里体现了计算机基础中关于数据库完整性约束的重要概念。
【问题 3】
(1) 不需要增加新实体。
(2) 投资额和投资时间是投资方对某个项目投资的属性,属于多对多联系(投资方-项目)的属性。应将其作为属性添加到“项目”关系中,并修改关系模式。
修改后的ER图和关系模式如下:

- 项 目(项目编号,创业公司代码,投资方编号,孵化公司员工工号,投资额,投资时间)
解析:当一个属性由多个实体共同决定时,应将其放在联系中。本题中,投资额和投资时间由具体的投资方和具体的项目共同决定,是“投资”联系的属性。在转换为关系模式时,多对多联系通常需要独立成一个关系,其属性自然包含该联系的属性。
试题三:书籍销售系统UML建模
阅读下列说明和 UML 图,回答问题 1 至问题 3。
【说明】
某图书公司欲开发一个基于 Web 的书籍销售系统,为顾客 (Customer) 提供在线购买书籍 (Books) 的功能,同时对公司书籍的库存及销售情况进行管理。系统的主要功能描述如下:
(1) 首次使用系统时,顾客需要在系统中注册 (Register detail)。顾客填写注册信息表要求的信息,包括姓名 (name)、收货地址 (address)、电子邮箱 (email) 等,系统将为其生成一个注册码。
(2) 注册成功的顾客可以登录系统在线购买书籍 (Buy books)。购买时可以浏览书籍信息,包括书名 (title)、作者 (author)、内容简介 (introduction) 等。如果某种书籍的库存量为 0,那么顾客无法查询到该书籍的信息。顾客选择所需购买的书籍及购买数量 (quantities),若购买数量超过库存量,提示库存不足;若购买数量小于库存量,系统将显示验证界面,要求顾客输入注册码。注册码验证正确后,自动生成订单 (Order),否则,提示验证码错误。如果顾客需要,可以选择打印订单 (Print order)。
(3) 派送人员 (Dispatcher) 每天早晨从系统中获取当日的派送列表信息 (Produce picklist),按照收货地址派送顾客订购的书籍。
(4) 用于销售的书籍由公司的采购人员 (Buyer) 进行采购 (Reorder books)。采购人员每天从系统中获取库存量低于再次订购量的书籍信息,对这些书籍进行再次购买,以保证充足的库存量。新书籍到货时,采购人员向在线销售目录 (Catalog) 中添加新的书籍信息 (Add books)。
(5) 采购人员根据书籍的销售情况,对销量较低的书籍设置折扣或促销活动 (Promote books)。
(6) 当新书籍到货时,仓库管理员 (Warehouseman) 接收书籍,更新库存 (Update stock)。
现采用面向对象方法开发书籍销售系统,得到如图 3-1 所示的用例图和图 3-2 所示的初始类图(部分)。


【问题 1】(6分)
根据说明中的描述,给出图 3-1 中 A1~A3 所对应的参与者名称和 U1~U3 处所对应的用例名称。
【问题 2】(6分)
根据说明中的描述,给出图 3-1 中用例 U3 的用例描述。(用例描述中必须包括基本事件流和所有的备选事件流)。
【问题 3】(3分)
根据说明中的描述,给出图 3-2 中 C1~C3 所对应的类名。
【答案解析】
【问题 1】
- A1:Buyer(采购人员)
- A2:Warehouseman(仓库管理员)
- A3:Dispatcher(派送人员)
- U1:Register detail(顾客注册)
- U2:Print Order(打印订单)
- U3:Buy books(在线购书)
解析:识别参与者和用例。
- 参与者:与系统交互的角色。根据说明(3)(4)(6),A1是采购人员,A2是仓库管理员,A3是派送人员。
- 用例:顾客发起的业务。U1是首次使用的“注册”;U3是核心业务“在线购书”;U2是U3中的一个可选步骤“打印订单”,二者是扩展关系(
<<extend>>)。
【问题 2】
用例 U3:Buy books(在线购书)
- 基本事件流:
- 顾客登录系统。
- 顾客浏览书籍信息。
- 顾客选择所需购买的书籍及数量。
- 系统检查库存,若数量充足,进入验证界面。
- 顾客输入注册码。
- 系统验证注册码正确。
- 系统生成订单。
- 备选事件流:
- 备选流A(库存不足):在基本流步骤4,若购买数量超过库存量,系统提示库存不足,用例结束。
- 备选流B(验证码错误):在基本流步骤6,若注册码验证错误,系统提示验证码错误,返回步骤5让顾客重新输入。
- 备选流C(打印订单):在基本流步骤7后,顾客可以选择打印订单,系统执行打印操作。
解析:用例描述需覆盖主要成功场景(基本事件流)和所有异常或可选场景(备选事件流)。依据说明(2)进行梳理。
【问题 3】
- C1:Customer(顾客)
- C2:Order(订单)
- C3:Book(书籍)
解析:分析UML类图中的类名和属性。
- C1具有name、address、email属性,对应顾客信息。
- C2与OrderedBook(已订购书籍)是聚合关系,且OrderedBook中有quantity属性,显然C2代表订单。
- C3具有title、author、introduction属性,并且与Catalog(销售目录)是聚合关系,对应书籍。理解这些面向对象设计的建模技巧,对于提升编程能力很有帮助。
试题四:n皇后问题C语言算法
阅读下列说明和 C 代码,回答问题 1 至问题 3。
【说明】
n皇后问题描述为:在一个 n×n 的棋盘上摆放 n 个皇后,要求任意两个皇后不能冲突,即任意两个皇后不在同一行、同一列或者同一斜线上。
算法的基本思想如下:将第 i 个皇后摆放在第 i 行,i 从 1 开始,每个皇后都从第 1 列开始尝试。尝试时判断在该列摆放皇后是否与前面的皇后有冲突,如果没有冲突,则在该列摆放皇后,并考虑摆放下一个皇后;如果有冲突,则考虑下一列。如果该行没有合适的位置,回溯到上一个皇后,考虑在原来位置的下一个位置上继续尝试摆放皇后……直到找到所有合理摆放方案。
【C 代码】
下面是算法的 C 语言实现。
(1) 常量和变量说明
- n:皇后数,棋盘规模为 n×n
- queen[]:皇后的摆放位置数组,queen[i] 表示第 i 个皇后的位置,1 ≤ queen[i] ≤ n
(2) C 程序
#include<stdio.h>
#define n 4
int queen[n+1];
void Show(){ /* 输出所有皇后摆放方案 */
int i;
printf("(");
for(i= 1; i <= n; i++){
printf("%d",queen[i]);
}
printf(")\n");
}
int Place(int j){ /*检查当前列能否放置皇后,不能放返回0,能放返回1*/
int i;
for(i=1;i<j;i++){ /*检查与已摆放的皇后是否在同一列或者同一斜线上 */
if( (1) || abs(queen[i] - queen[j])==(j-i)){
return 0;
}
}
return (2) ;
}
void Nqueen(int j){
int i;
for(i= 1; i <= n; i++){
queen[j]= i;
if( (3) ){
if(j== n){ /* 如果所有皇后都摆放好,则输出当前摆放方案*/
Show();
} else { /* 否则继续摆放下一个皇后 */
(4) ;
}
}
}
}
int main(){
Nqueen (1);
return 0;
}
【问题 1】(8分)
根据题干说明,填充 C 代码中的空 (1)~(4)。
【问题 2】(3分)
根据题干说明和 C 代码,算法采用的设计策略为 (5)。
【问题 3】(4分)
当 n=4 时,有 (6) 种摆放方式,分别为 (7)。
【答案解析】
【问题 1】
(1) queen[i] == queen[j]
(2) 1
(3) Place(j) == 1 或 Place(j)
(4) Nqueen(j+1)
解析:填补算法关键步骤。
- (1):检查是否在同一列,即比较列号是否相等。
- (2):所有已检查的皇后都不冲突,则返回1表示可以放置。
- (3):调用
Place函数检查第j个皇后当前位置是否合法。
- (4):当前位置合法且不是最后一个皇后,则递归摆放下一个皇后(第j+1个)。
【问题 2】
(5) 回溯法
解析:算法尝试放置皇后,遇到冲突时回退(回溯)到上一步尝试其他可能,这是典型的回溯法策略。掌握这类算法设计策略是解决复杂问题的关键。
【问题 3】
(6) 2
(7) (2413)、(3142)
解析:4皇后问题共有2个解。queen[1]=2, queen[2]=4, queen[3]=1, queen[4]=3 表示第一行皇后放第2列,第二行放第4列,第三行放第1列,第四行放第3列。另一个解同理。
试题五:汽车游戏刹车策略模式(C++实现)
阅读下列说明和 C++ 代码,将应填入 (n) 处的字句写在答题纸的对应栏内。
【说明】
某软件公司欲开发一款汽车竞速类游戏,需要模拟长轮胎和短轮胎急刹车时在路面上留下的不同痕迹,并考虑后续能模拟更多种轮胎急刹车时的痕迹。现采用策略 (Strategy) 设计模式来实现该需求,所设计的类图如图 5-1 所示。

【C++ 代码】
#include <iostream>
using namespace std;
class BrakeBehavior {
public:
(1) ;
/* 其余代码省略 */
};
class LongWheelBrake : public BrakeBehavior {
public:
void stop(){ cout <<“模拟长轮胎刹车痕迹!”<< endl; }
/* 其余代码省略 */
};
class ShortWheelBrake : public BrakeBehavior {
public:
void stop(){ cout <<"模拟短轮胎刹车痕迹!"<< endl;}
/* 其余代码省略 */
};
class Car {
protected:
(2) wheel;
public:
void brake(){ (3) ; }
/* 其余代码省略 */
};
class ShortWheelCar : public Car {
public:
ShortWheelCar(BrakeBehavior* behavior){
(4) ;
}
/* 其余代码省略*/
};
int main(){
BrakeBehavior* brake = new ShortWheelBrake();
ShortWheelCar car1(brake);
car1. (5) ;
return 0;
}
【答案解析】
(1) virtual void stop () = 0;
(2) BrakeBehavior*
(3) wheel->stop ();
(4) wheel = behavior;
(5) brake ();
解析:根据策略模式填充代码。
- (1):抽象策略类
BrakeBehavior需要定义所有具体策略的公共接口stop,应为纯虚函数。
- (2):环境类
Car需要持有一个策略对象的指针。
- (3):环境类的
brake方法委托给所持有的策略对象执行。
- (4):具体汽车类(上下文子类)的构造函数,接收一个策略对象并赋值给继承自父类的成员变量。
- (5):主函数中,调用汽车对象的
brake方法来触发策略执行。
试题六:汽车游戏刹车策略模式(Java实现)
阅读下列说明和 Java 代码,将应填入 (n) 处的字句写在答题纸的对应栏内。
【说明】
(同试题五说明)现采用策略 (Strategy) 设计模式来实现该需求,所设计的类图如图 6-1 所示。

【Java 代码】
import java.util.*;
interface BrakeBehavior {
public (1) ;
/* 其余代码省略 */
};
class LongWheelBrake implements BrakeBehavior {
public void stop() { System.out.println("模拟长轮胎刹车痕迹!");}
/* 其余代码省略 */
};
class ShortWheelBrake implements BrakeBehavior {
public void stop(){ System.out.println("模拟短轮胎刹车痕迹!");}
/* 其余代码省略 */
};
abstract class Car {
protected (2) wheel;
public void brake(){ (3) ; }
/* 其余代码省略 */
};
class ShortWheelCar extends Car {
public ShortWheelCar(BrakeBehavior behavior){
(4) ;
}
/* 其余代码省略 */
};
class StrategyTest{
public static void main(String[] args) {
BrakeBehavior brake = new ShortWheelBrake();
ShortWheelCar car1 = new ShortWheelCar (brake);
car1. (5) ;
}
}
【答案解析】
(1) void stop ();
(2) BrakeBehavior
(3) wheel.stop ();
(4) this.wheel = behavior;
(5) brake ();
解析:Java版本的策略模式实现。
- (1):接口中声明方法
void stop();。
- (2):抽象类
Car持有策略接口的引用。
- (3):
brake方法调用策略对象的stop方法。
- (4):子类构造函数将传入的策略对象赋给父类成员。
- (5):调用对象的
brake方法。
知识点总结
试题一知识点:数据流图(DFD)的基本元素(外部实体、加工、数据存储、数据流)、上下文图与0层图的对应关系、数据流平衡与一致性检查规则、结构化分析方法。
试题二知识点:实体联系图(ER图)设计、关系模式转换、数据库完整性约束(主键、外键)、多对多联系的属性处理。
试题三知识点:UML用例图(参与者、用例、扩展关系)、用例描述规范(基本/备选事件流)、UML类图识别(类、属性、聚合关系)、面向对象分析。
试题四知识点:回溯法算法设计思想、递归函数实现、n皇后问题约束条件、算法策略识别。
试题五/六知识点:策略模式设计思想与应用、C++纯虚函数与多态、Java接口与实现、面向对象的多态性应用。
通过以上六道真题的详细解析,我们系统回顾了软件设计师考试下午案例分析部分的核心考点。从结构化分析到面向对象设计,从数据库建模到算法实现,这些题目全面考察了软件工程师的建模与设计能力。备考时,除了理解概念,更要多动手练习,可以参考云栈社区上的相关资源进行巩固。希望这份解析能对你的面试求职与技能提升有所帮助。