image

编辑人: 长安花落尽

calendar2025-06-06

message9

visits201

2014年5月 软件设计师 下午题答案及解析

一、问答题

1、试题一(15分)

阅读下列说明和图,回答问题,将解答填入答题纸的对应栏内。

【说明】

 某巴士维修连锁公司欲开发巴士维修系统,以维护与维修相关的信息,该系统的主要能如下:

1记录巴士ID和维修问题。巴士到车库进行维修,系统将巴士基本信息和ID记录在巴士列表文件中,将待维修机械问题记录在维修记录文件中,并生成维修订单。

2确定所需部件,根据维修订单确定维修所需部件,并在部件清单中进行标记。

3完成维修,机械师根据维修记录文件中的待维修机械问题,完成对巴士的维修,登记维修情况;将机械问题维修情况记录在维修记录文件中,将所用部件记录在部件清单中,并将所用部件清单发送绘库存管理系统以对部件使用情况进行监控,巴士司机可查看已维修机械问题。

4记录维修工时,将机械师提供的维修工时记录在人事档案中,将维修总结发送给主管进行绩效考核。

5计算维修总成本。计算部件清单中实际所用部件、人事档案中所用维修工时的总成本;将维修工时和所用部件成本详细信息给会计进行计费。

现采用结构化方法对巴士维修系统进行分析与设计,获得如图1所示的上下文数据流图1和图2所示的0层数据流图。

【问题1】(5分)

使用说明中的词语,给出图1中的实体E1E5的名称。

【问题2】(4分)

使用说明中的词语,给出图2中的数据存储D1D4的名称

【问题3】(4分)

说明图2中所存在的问题。

【问题4】(2分)

根据说明和图中术语,采用补充数据流的方式,改正图2中的问题。要求给出所补充数据流的名称、起点和终点。


参考答案:见解析

2、阅读下列说明和图,回答问题1至问题3,将解答填入答题纸的对应栏内。

【说明】

某家电销售电子商务公司拟开发一套信息管理系统,以方便对公司的员工、家电销售、家电厂商和客户等进行管理。

【需求分析】

(1)系统需要维护电子商务公司的员工信息、客户信息、家电信息和家电厂商信息等。员工信息主要包括:工号、姓名、性别、岗位、身份证号、电话、住址,其中岗位包括部门经理和客服等。客户信息主要包括:客户ID、姓名、身份证号、电话,住址、账户余额。家电信息主要包括:家电条码、家电名称、价格、出厂日期、所属厂商。家电厂商信息包括:厂商ID、厂商名称、电话、法人代表信息、厂址。

(2)电子商务公司根据销售情况,由部门经理向家电厂商订购各类家电。每个家电厂商只能由一名部门经理负责。

(3)客户通过浏览电子商务公司网站查询家电信息,与客服沟通获得优惠后,在线购买。

【概念模型设计】

根据需求阶段收集的信息,设计的实体联系图(不完整)如图所示。

 

【逻辑结构设计】

根据概念模型设计阶段完成的实体联系图,得出如下关系模式〔不完整)

客户(客户ID、姓名、身份证号、电话、住址、账户余额)

员工(工号、姓名、性别、岗位、身份证号、电话、住址)

家电(家电条码、家电名称、价格、出厂日期、 (1) )

家电厂商(厂商ID、厂商名称、电话、法人代表信息、厂址、 (2) )

购买(订购单号、 (3) 、金额)

 【问题1】 

补充实体联系图中的联系和联系的类型。

【问题2】

根据图,将逻辑结构设计阶段生成的关系模式中的空(1)~(3)补充完整。 用下划线指出"家电"、"家电厂商"和"购买"关系模式的主键。

【问题3】

电子商务公司的主营业务是销售各类家电,对账户有佘额的客户,还可以联合第二方基金公司提供理财服务,为此设立客户经理岗位。客户通过电子商务公司的客户经理和基金公司的基金经理进行理财。每名客户只有一名客户经理和一名基金经理负责'客户经理和基金经理均可负责多名客户。请根据该要求,对图进行修改,画出修改后 的实体间联系和联系的类型。

参考答案:

【问题1】

【问题2】

【参考答案】

(1)厂商ID

(2)部门经理工号 或 经理工号 或 员工工号

(3)客户ID、客服工号、家电条码


【问题3】


解析:

问题1中对于实体联系图中的联系和联系类型的描述基本正确,但表述可以更具体一些。“供应”联系的描述可以明确为一对多的关系,即一个家电厂商可以供应多台家电,但一台家电只能由一个家电厂商供应。问题2中的空(1)~(3)补充完整部分正确,主键的指出也准确。问题3中的修改建议基本符合题目要求,需要新增“基金经理”实体,并明确客户与客户经理、基金经理之间的多对一理财联系。同时,根据实际需求考虑是否保留或调整与购买相关的实体联系。最后,根据描述绘制修改后的实体间联系图。

3、 


试题三(15分)

阅读下列说明和图,回答问题,将解答填入答题纸的对应栏内。

【说明】

某高校图书馆欲建设一个图书馆管理系统,目前已经完成了需求分析阶段的工作,功能需求均使用用例进行描述,其中用例“借书(Check Out 800ks)”的详细描述如下。

    参与者:读者<Patron>

    典型事件流:

    1.输入读者ID:

    2.确认该读者能够借阅图书,并记录读者ID;

    3.输入所要借阅的图书ID;

    4.根据图书目录中的图书ID确认该书可以借阅,计算归还时间,生成借阅记录;

    5.通知读者图书归还时间;

    重复步骤3~5,直到读者结束借阅图书。

    备选事件流:

    2a.若读者不能借阅图书,说明读者违反了图书馆的借书制度(例如,没有支付借书费用等)。

    ①告知读者不能借阅,并说明拒绝借阅的原因;

    ②本用例结束。

    4a.读者要借阅的书无法外借。

    ①告知读者本书无法借阅;

    ②回到步骤3。

说明:图书的归还时间与读者身份有关。如果读者是教师,图书可以借阅一年:如果是学生,则只能借阅3个月,读者ID中包含读者身份信息,现采用面向对象方法开发该系统,得到如图1所示的系统类模型(部分);以及如图2所示的系统操作。“CheckOut(bookID).(借书)“通信图”(或协作图)。


【问题1】(5分)

根据说明中的描述,以及图1和图2,给出图1中C1-C4处所对应的类名(类名使用图1和图2中给出的英文词汇)。

【问题2】(5分)

根据说明中的描述,以及图1和图2,给出图2中M1-M4处所对应的方法名(方法名使用图1和图2中给出的英文词汇)。

【问题3】(5分)

用例“借书”的备选事件流4a中,根据借书制度来判定读者能否借阅图书,随着图书馆的借书制度会不断地扩充,并需要根据图书馆的实际运行情况来调整具体使用哪些制度,为满足这一要求,在原有类设计的基础上,可以采用何种设计模式?简要说明原因。

参考答案:见解析

解析:

第一题根据系统类模型以及类之间的关联关系,可以确定各个类的名称。第二题根据系统操作以及典型事件流,可以确定各个方法名。第三题为了满足借书制度不断变化的需求,应采用策略模式进行设计。策略模式可以在不修改原有代码的基础上,通过添加新的策略类来处理新的借书制度,从而提高系统的灵活性和可扩展性。

4、

试题四

阅读下列说明和C代码,回答下列问题。

[说明]

    采用归并排序对n个元素进行递增排序时,首先将n个元素的数组分成各含n/2个元素的两个子数组,然后用归并排序对两个子数组进行递归排序,最后合并两个已经排序的子数组得到排序结果。

    下面的C代码是对上述归并算法的实现,其中的常量和变量说明如下:

    arr:待排序数组

    P,q,r:一个子数组的位置从P到q,另一个子数组的位置从q+1到r

    begin,end:待排序数组的起止位量

    left,right:临时存放待合并的两个子数组

    n1,n2:两个子数组的长度

    i,j,k:循环变量

    mid:临耐变量

    [C代码]

    #inciude<stdio, h>

    #include<stdlib, h>

    Define MAX 65536

    void merge(int arr [ ],int p,int q,int r) {

    int * left,* right;

    int n1,n2,I,j,k;

    n1=q-p+1;

    n2=r-q;

    If(left=(int *)malloc((n1+1) * sizeof(int)))=NULL) {

    Perror( "malloc error" );

    exit11

    }

    If((right = (int *)malloc((n2+1) * sizeof(int)))=NULL)

    Perror("malloc error");

    exit 11;

    }

    for(i=0;i<n1;i++){

    left[i]=arr [p+i];

    }

    left[i]=MAX;

    for(i=0;i<n2;i++){

    right[i]=arr[q+i+1]

    }

    right[i]=MAX;

    i=0;j=0;

    For(k=p;______;k++){

    If(left[i]>right[j] {

    ______

    j++;

    }else{

    arr[k1]=left[i];

    i++;

    }

    }

    }

    Void merge Sort(int arr[ ], int begin, int end) {

    int mid;

    if(______){

    mid=(begin + end)/2;

    merge Sort(arr,begin,mid);

    ______;

    Merge(arr,begin,mid,end);

    }

    }


参考答案:见解析

解析:

根据题目描述和参考解析,以下是关于C代码部分的解析:

在函数void merge(int arr[], int p, int q, int r)中:

  1. 第一个空需要填写的是循环条件,保证合并操作能够遍历到整个数组arr。由于是在合并两个子数组,所以循环应该遍历到子数组的结束位置,即k <= q。

  2. 第二个空是关于合并操作的实现。由于题目要求的是递增排序,所以当left[i]大于right[j]时,应该将较小的值right[j]放入arr中,即arr[k]=right[j]。同时更新k和j的值进行下一轮比较。

在函数void mergeSort(int arr[], int begin, int end)中:

  1. 第三个空是递归条件。归并排序是基于分治思想的算法,当数组长度大于1时,需要继续递归分割数组并排序。所以条件应该是begin < end。当数组长度为1时,该数组已经有序,无需再递归。

  2. 第四个空是关于递归调用的部分。在合并了begin到mid之间的元素后,还需要继续合并mid+1到end之间的元素。因此这里应该调用mergeSort函数对后半部分数组进行排序,即mergeSort(arr,mid+1,end)。同时,这里还需要调用merge函数进行实际的合并操作。

关于问题补充部分的解析:
归并算法的时间复杂度分析:归并算法的时间复杂度是O(nlogn)。这是因为归并算法首先将数组分割成更小的子数组,然后合并这些子数组以得到排序结果。这个过程涉及到了递归和分治的思想。在合并过程中,需要进行n次元素的比较和交换操作,每次比较和交换都需要O(logn)的时间(因为每次都将数组分割成两半)。所以总的时间复杂度为O(nlogn)。空间复杂度为O(n),因为使用了额外的空间来存储临时数组。

5、 

试题五(15分)


阅读下列说明和C++代码,回答问题,将答案填入相应横线处。

【说明】

某实验室欲建立一个实验室环境监测系统,能够显示实验室的温度、湿度以及洁净度等环境数据。当获取到最新的环境测量数据时,显示的环境数据能够更新现在采用观察者(observer)模式来开发该系统,观察者模式的类图如下图所示。

 【C++代码】

#include <iostream>

#include <vector>

using namespace std;

class Observer {

public:

    virtual void update(float temp, float humidity, float cleanness)=0;

};

class Subject {

public:

    virtual void registerObserver(Observer* o) = 0; //注册对主题感兴趣的观察者

    virtual void removeObserver(Observer* o) = 0; //删除观察者

    virtual void notifyObservers() = 0;//当主题发生变化时通知观察者

};

class EnvironmentData : public     (1)     {

private:

vector<Observer*> observers;

float temperature, humidity, cleanness;

public:

    void registerObserver(Observer* o) { observers.push_back(o); }

    void removeObserver(Observer* o) { /* 代码省略 */ }

    void notifyObservers() {

for(vector<Observer*>::const_iterator it = observers.begin();            it != observers.end(); it++)

{       (2)    ; }

}

Void measurementsChanged() {     (3)    ; }

void setMeasurements(float temperature, float humidity, float cleanness) {

    this->temperature = temperature;

    this->humidity = humidity;

    this->cleanness = cleanness;

        (4)    ;

    }

};

class CurrentConditionsDisplay : public     (5)    {

private:  

    float temperature, humidity, cleanness;

    Subject* envData;

public:

    CurrentConditionsDisplay(Subject* envData) {

        this->envData = envData;

           (6)   ;       

}

void update(float temperature, float humidity, float cleanness)  {this->temperature = temperature;

    this->humidity = humidity;

    this->cleanness = cleanness;

    display();

}

void display() { /* 代码省略 */ }

};

int main() {

    EnvironmentData* envData = new EnvironmentData();

    CurrentConditionsDisplay* currentDisplay = new CurrentConditionsDisplay(envData);

    envData->setMeasurements(80, 65, 30.4f);

    return 0;

}

参考答案:见解析

解析:

  1. 根据题目描述和代码,EnvironmentData类作为主题(Subject),需要继承Subject类以实现注册、删除观察者和通知观察者的功能。所以答案为Subject。

  2. 在notifyObservers()方法中,需要遍历所有已注册的观察者,并调用其update方法以更新环境数据。因此,此处应填写(*it)->update(temperature, humidity, cleanness)。

  3. 当环境数据发生变化时,需要通知所有已注册的观察者。在EnvironmentData类中,这个操作是通过调用notifyObservers()方法实现的。因此答案为notifyObservers()。

  4. 当环境数据(温度、湿度和洁净度)被设置时,应该触发一次通知观察者的操作。在EnvironmentData类中,这个操作是通过调用measurementsChanged()方法实现的。因此答案为measurementsChanged()。

  5. CurrentConditionsDisplay类作为观察者(Observer),需要继承Observer类以实现update方法。所以答案为Observer。

  6. 在CurrentConditionsDisplay类的构造函数中,需要将当前对象(作为观察者)注册到环境数据主题上。所以此处应填写this->envData->registerObserver(this)。

喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!

创作类型:
原创

本文链接:2014年5月 软件设计师 下午题答案及解析

版权声明:本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。
分享文章
share