软件水平考试(中级)软件设计师下午(应用技术)试题模拟试卷5
(题后含答案及解析)
题型有:1. 必答题 2. 选答题
必答题(共4道大题,每道大题15分)
【说明】 某考务处理系统主要功能是考生管理和成绩管理: 1.对考生送来的报名表进行检查。 2.对合格的报名表编好准考证号码后将准考证送给考生,将汇总后的考生名单送给阅卷站。 3.对阅卷站送来的成绩表进行检查,并根据考试中心指定的合格标准审定合格者。 4.填写考生通知单(内容包含该考生的准考证号、姓名、各课程成绩及最终合格/不合格标志),送给考生。 5.根据考生信息及考试成绩,按地区、年龄、文化程度和职业进行成绩分类统计及试题难度分析,产生统计分析表。 考务处理系统的顶层图如图1-1所示,第0层图如图1—2所示,加工2子图如图1-3所示。
1. 指出哪张图的哪些文件可以不必画出。
正确答案:0层图中的“试卷得分表”是局部文件,可不必画出。 解析:“不必画出”是指在某层数据流图中,只画流程图中各加工之间的公共数据文件,隐藏某加工的局部数据文件,这个规则只是为了使整个数据流图的层次结构更科学、更清晰,不过画出“不必画山的数据文件”对数据流图不会造成理解错误。在。层图中有文件“考生名册”和“试卷得分表”,其中“试卷得分表”是加工2“统计成绩”的局部数据文件,所以不必画出。
2. 数据流图1—3中缺少3条数据流,请直接在图中添加。
正确答案:(1)分类统计成绩中需要读入考生成绩,缺少从“考生名册”到“2.4分类统计成绩”的数据流。(2)“2.1检查成绩表”缺少输出数据流“错误成绩表”。(3)“2.2审定合格者”缺少输入数据流“合格标准”。
解析:本题是要指出哪些图中遗漏了哪些数据流,这需要从两个方面进行考虑: 一是父图与子图的平衡,即子图的输入、输出数据流与父图相应的加工的输入、输出数据必须一致。 二是针对每个加工至少要有一个输入和输出,反映次加工的数据来源和结果。 数据流图1—3是加工2“统计成绩”的子图,为了发现图中遗漏的数据流,首先要观察 0层图中加工2的输入、输出流。在0层图中,加工2“统计成绩”有2个输入流“合格标准”和“成绩表”,4个输出流“考生通知单”、“统计分析表”、“难度分析表”和“错误成绩表”。 再看加工2子图中只有一个输入流“成绩表”,可见必然遗漏了一个输入流“合格标准”。根据题目说明提到的“对阅卷站送来的成绩表进行检查,并根据考试中心指定的合格标准审定合格者”,所以输入流“合格标准”应该是输入到加工2.2“审定合格者”。 加工2子图中只有3个输出流“考尘通知单”、“统计分析表”和“难度分析表”,缺少数据流“错误成绩表”。加工2.1“检查成绩表”的功能是检查成绩表是否合格,其中一个输出流是“正确成绩表”, 自然另一个是输出是“错
误成绩表”。因此,第二个遗漏的数据流是“2.1检查成绩表”的输出数据流“错误成绩表”。 根据题目中提到的“根据考生信息及考试成绩,按地区、年龄、文化程度和职业进行成绩分类统计及试题难度分析,产生统计分析表”这一说明,可以判断出加工2.4“分类统计成绩”除了需要“试卷得分表”的输入流外,还需要考生信息,需要从文件“考生名册”中输入。
3. 根据系统功能和数据流图填充下列数据字典条目中的(1)和(2): 试题得分表二准考证号+{课程名+成绩} 考生名册=报名号+准考证号+姓名+通信地址+出生年份+文化程度+职业 考生通知单=(1) 报名表=(2)
正确答案:(1)准考证号+姓名+{课程名+成绩}+合格/不合格标志(2)报名号+姓名+通信地址+出生年份+文化程度+职业
解析:根据题目说明中提到的“填写考生通知单(内容包含该考生的准考证号、姓名、各课程成绩及最终合格/不合格标志),送给考生”,所以考生通知单应该包括考生的准考证号、姓名和最终合格/不合格标志,这种共同组成的含义由符号“+”来表示。同时因为考试可能有多门课程共同组成,所以,课程号和该课程的成绩也是必须的。其中的多门课程山符号“{...}”来表示重复。因此,考生通知单;准考证号+姓名+{课程名+成绩}+合格/不合格标志。 根据题目说明中提到的“对合格的报名表编好准考证号码后将准考证送给考生”,在0层图中可以看到,加工1“登记报名表”把考生信息写入文件“考生名册”中,可见“考生名册”中的数据除“准考证号”外均从合格的报名表中得到。因此“报名表”至少需要山报名号、姓名、通信地址、出生年份、文化程度和职业组成。由数据字典定义式表示为:报名表=报名号+姓名+通信地址+出生年份+文化程度和职业。
【说明】 设有关于银行借贷管理系统的E-R图。图中矩形表示实体,圆表示属性,双圆表示关键字属性,菱形表示实体间的联系。为了答题的方便,图中的实体和属性同时给出了中英文说明,回答问题时只需写出英文名即可。
4. 根据E-R图中给出的词汇,按照“有关模式名(属性1,属性2,…)”的格式,将此E-R图转换为关系模式,并指出每个关系模式中的主码和外码,其中模式名根据需要取实体名或联系名。要求其中的关系模式至少属于第三范式。
正确答案:Customer(idno, name, address, phone) Account(Ano. balance, Bname) Bname reference Branch(Bname) Deposit(idno, Ano)idno reference Customer(idno) Ano reference Account(Ano) Branch(Bname. city) Loan(Lno, Bname, amount)
解析:将E-R模型转换为关系模型时,需要遵循的转换规则如下: 1.每个实体集转换为一个关系。 2.一个一对一的联系可转换为一个关系模式,将两端关系的码及联系的属性均作为该关系的属性,任意一端的码作为该关系的码;也可将任意一端的码及联系的属性合并到另一端实体集所转换的关系模式中。 3.一个一对多联系可转换为一个关系模式,将两端关系的码及联系的属性均作为该关系的属性,“多”端的码作为该关系的码:也可将“一”端的码及联系的属性合并到“多”端实体集所转换的关系模式中。 4.一个多对多联系
应转换为一个关系模式,两端的码及联系的属性为关系的属性,两端的码共同组合为该关系的码。 3个或3个以上多对多的联系应转换为一个关系,各关系的码及联系的属性为关系的属性,各端的码共同组合为该关系的码。 本题中的E-R图中有4个实体集、2个多对多联系和2个一对多联系,根据上述E-R图转换关系模型的规则可以转换成6个关系。 4个实体集转换的4个关系(Customer、Account、Branch和Loan),对于一对多联系B-L和B-A则是将“一”端(关系Branch)的码Bname加入到“多”端所转换的关系(Account和Loan)。此4个关系分别为: Customer(idno,name,address,phone) Account(Ano,balance,Bname) Branch(Bname,city,assets) Loan(Lno,Bname,amount) 4个关系中,Account和Loan的属性Bname均参照Branch的码Bname,为外码。 2个多对多联系转换为2个关系,两端的码及联系的属性为关系的属性,两端的码共同组合为该关系的码。此2个关系分别为: Deposit(idno.Ano) Borrow(idno,Lno) 其中的idno、Ano和Lno分别参照Customer的idno、Account的Ano和Loan的Lno。
5. 如下的SQL语言用于查询“在该银行中一笔贷款贷给多个(至少2个)客户的所有贷款号和发放贷款的支行名称”的不完整语句,请在空缺处填A.正确的内容。 SELECT Borrow. Lno, Bname FROM Borrow, Loan WHERE(1) GROUP BY Borrow. Lno HAVING(2)
正确答案:(1)Borrow. Lno =Loan.Lno(2) COUNT(distinct idno)>=2
解析:本题是要查询在该银行中一笔贷款贷给多个(至少2个)客户的所有贷款号和发放贷款的支行名称。Borrow表中记录着各贷款号和该贷款的客户,Loan表中记录着各贷款号和发放该贷款的支行,要完成题目查询必须将Borrow和Loan联系起来,即需要两者的贷款号相等。所以填空(1)应该为Borrow. Lno=Loan. Lno。 “一笔贷款贷给多个客户”则需要按贷款号进行分组,只有客户个数至少两个的组才是满足查询要求的分组。对于分组的条件应该添加在HAVING子句中,个数的统计需利用 COUNT(idno)函数,因此填申(2)为COUNT(idno)>=2。
6. 假设这个银行有若干个节点,每个节点运行一个数据库系统。假设这些节点之间惟一的交互式用电子方式相互传送款项,这样的系统是分布式数据库系统吗?为什么?
正确答案:这样的系统算不上分布式数据库系统。分布式数据库系统并不是简单地把集中式数据库系统安装在不同场地,用网络连接起来实现的(这是分散的数据库系统),它是具有自己的性质和特征。 分布式数据库系统具有以下特点: 1.数据的物理分布性。 2.数据的逻辑整体性。 3.数据的分布独立性。 4.场地的自治和协调。 5.数据的冗余及冗余透明性。 虽然上述银行的数据库系统具有性质1、3以及4和5的一部分,但关键是没有数据的逻辑整体性和不同场地之间的协调性等,这恰恰是分布式数据库系统的关
解析:本题主要考查分布式数据库系统的必备条件。
7. 阅读下列说明、流程图和算法,将应填入(n)处的字句写在答题纸的对
应栏内。 【说明】 下面的流程图1—5用N-S盒图形式描述了数组A中的元素被划分的过程。其划分方法是:以数组中的第一个元素作为基准数,将小于基准数的元素向低下标端移动,而大于基准数的元素向高下标端移动。当划分结束时,基准数定位于A[i],并且数组中下标小于i的元素的值均小于基准数,下标大于i的元素的值均大于基准数。设数组A的下界为low,上界为high,数组中的元素互不相同。例如,对数组(4,2,8,3,6),以4为基准数的划分过程如下:【算法说明】 将上述划分的思想进一步用于被划分出的数组的两部分,就可以对整个数组实现递增排序。设函数血p(int A[],int low,int high)实现了上述流程图的划分过程并返回基准数在数组A中的下标。递归函数void sort(int A[],iht L;int H)的功能是实现数组A中元素的递增排序。 【算法】 void sort(int A[],int1,int H) {if (L<H) { k=p(A, L, R): //p( )返回基准
数在数组A中的下标 sort((4)); //小于基准数的元素排序 sort((5)); //大于基准数的元素排序 } }
正确答案:(1)j--(2) i++(3)A[i]←pivot或[j]←pivot(4)A,L,k-1或A,L,k(5)A,k+I,H或A,k,H
解析:题目考查快速排序算法。快速排序采用了一种分治的策略,通常称为分治法,其基本思想足:将原问题分解为若干个规模更小,但结构与原问题相似的子问题。递归地解这些子问题,然后将这些子问题的解组合为原问题的解。 快速排序的具体过程为:第一步,在待排序的n个记录中任取一个记录,以该记录的排序码为基准,将所有记录分成2组,第一组各记录的排序码都小于等于该排序码,第二组各记录的排序码都大十该排序码,并把该记录排在这2组中间,这个过程称为一次划分。第二步,采用同样的方法,对划分出来的2组元素分别进行快速排序,直到所有记录都排到相应的位置为止。 在进行一次划分时,若选定以第一个元素为基准,就可将第一个元素备份在变量pivot中,如图中的第①步所示。这样基准元素在数组中占据的位置就空闲出来了,因此下一步就从后向前扫描。如图中的第②步所示,找到一个比基准元素小的元素时为止,将其前移,如图中的第③步所示。然后再从前向后扫描,如图中的第④步所示,找到一个比基准元素大的元素时为止,将其后移,如图中的第⑤步所示。这样,从后向前扫描和从前向后扫描交替进行,直到扫描到同一个位置为止,如图中的第⑥步所示。 由题目中给出的流程图可知,以第一个元素作为基准数,并将A[low]备份至pivot,i用于从前向后扫描的位置指示器,其初值为low,j用于从后往前扫描的位置指示器,其初值为high。当i<j时进行循环: 1.从后向前扫描数组A,在i<j的情况下,如果被扫描的元素A刚>pivot,就继续向前扫描(j--);如果被扫描的元素A[j]<pivot就停止扫描,并将此元素的值赋给目前空闲着的A[i]。 2.这时,再从前向后扫描,在i<j的情况下,如果被扫描的元素A刚<pivot,就继续向后扫描(i++);如果被扫描的元素A[j]>pivot就停止扫描,并将此元素的值赋给目前空闲着的A[j]。 3.这时又接第(1)步,直到i>j时退出循环。退出循环时,将pivot赋给当前的A[i] (A[i]←pivot)。 递归函数的目的是执行一系列调用,直到到达某一点时递归终止。为了保证递归函数正常执行,应该遵守下面的规则: 1.每当一个递归函数被调用时,程序首先应该检查基本的条件是否满足,例如,某个参数的值等于0,如果是这种情形,函数应停止递归。 2.每次当函数被递归调用时,传递给函数一个或多个参数,应该以某种方式变得“更简单”,即这些参数应该逐渐靠近上述基本条件。例如,一个正
整数在每次递归调用时会逐渐变小,以至最终其值到达0。 本题中,递归函数sort(iht A[],int L int H)有3个参数,分别表示数组A及其下界和上界。根据流程图可知,这里的L相当于流程图中的i,这里的H相当于流程图中的j。因为p( )返回基准数所在数组A中的下标,也就是流程图中最后的“A[i]←pivot”中的i。根据快速排序算法,在第一趟排序后找出了基准数所在数组A中的下标,然后以该基准数为界 <基准数在数组中的下标为k),把数组A分成2组,分别是A[L,…,k-1]和A[k+l,…, H],最后对这2组中的元素再使用同样的方法进行快速排序。
【说明】 一个图书馆信息管理系统的分析与建模。下面是某图书馆的有关介绍。 图书馆雇有若干管理员,各自具有编码、姓名等属性。管理员可上岗,也可下岗。 图书馆中备有若干图书,每本图书有书号、书名、出版社、价格等属性。图书馆不定期地购买并注册新图书供读者借阅,也可将报废的旧书注销以停止借阅。 图书馆可为众多读者提供服务。每个读者在借阅之前需注册姓名、性别、地址、Email等内容。读者可在终端上查询。每个读者最多可同时借阅5本书。每本图书借期为30天;若有一本书超期,则不可再借其他图书。一本书超期一天罚款0.1元。若一本书超期3个月不归还,则发布通告。若读者的图书丢失,在罚款处理之前不能借书,每本报失的图书罚款该书价的2倍。注册新读者不受限制;在注销读者之前,该读者必须归还所有借阅的图书,或者报失并接受罚款。
8. 在需求分析阶段,采用UML的用例图描述系统功能需求,如图1-6所示。指出图1-6中(1)(2)、(3)、(4)分别是哪个用例?
正确答案:(1)return(还书)(2)outdate(超期)(3)Reader Register(读者注册)(4)Book Cancel ReSister(图书注销)
解析:仔细阅读题目,可以发现“图书馆不定期地购买并注册新图书供读者借阅,也可将报废的旧书注销以停止借阅”,这句需求前半部分已经在用例图中显示出来,后半部分没有用例图说明,同时(4)处的前件是“图书登记”,可以得出(4)是Book Cancel Register (图书注销)。同样道理,从题目说明中“每个读者在借阅之前需注册姓名、性别、地址、Email等内容”,得到(3)处是Reader Register(读者注册);从题目说明中“一本书超期一天罚款 0.1元。若一本书超期三个月不归还,则发布通告”,得到(2)处是outdate(超期),(1)处是return(还书)。
9. 图1-7采用协作图描述借书和还书两个动态过程的交互关系。在UML中,重复度(multiplicity)定义了某个实体的一个实例可以与另一个类的多个实例相关联。指出图1-7中(5)、(6)处的重复度分别是多少?
正确答案:(5)0…1、(6)0…1
解析:在UML中重复度表示为一个整数范围n…m,整数n定义所连接的最少对象的数目,而m则为最多对象的数(当不知道确切的最大数时,最大数用*号表示)。例如, 0…1 表示0~1个对象 0…*或者* 表示0~多个对象 5…17 表示5~17个对象 2 表示2个对象
10. 指出UML中全局、局部、参数、自我、投票、广播、创建、注销和
临时9个约束对于链接角色、消息和对象的作用。
正确答案:1.全局的约束应用于一个链接角色,指定相应的实例是可见的,因为它是一个全局量。2.局部的约束应用于一个链接角色,指定相应的实例是可见的,因为它是操作的局部变量。3.参数应用于一个链接角色,指定相应的实例是可见的,因为它是某个操作的参数。4.自我应用于一个链接角色,指定对象可以向它自己发送消息。5.投票应用于消息,限制一组返回的消息。投票约束指定从这组消息中以大多数投票的方式选出返回的值。6.广播应用于消息,指定不能以某种顺序发出该消息。7.创建影响对象生命,将在交互的执行中创建对象。8.注
解析:题目中的9个约束应用于交互。可以用顺序图从时间的角度来看交耳,也可以用协作图从空间的角度来看交互,或者还可以用活动图从工作的角度来看交互。在所有类型的交互图(顺序图、协作图和活动图)中,消息、对象和链接是最重要的概念。对象是通过链接连接起来的(而不是关联),每个链接都有两个链接角色。当对象进行交互时,它们扮演角色(链接的角色),并且通过链接相互发送消息。
11. 【程序说明】 定义一个多边形结构:struct polygon实现以下内容:(1)建立该结构的链表:create函数是创建链表,每输入一个结点的数据,就把该结点加入到链表当中,它返回创建的链表的头指针。(2)显示链表的各个结点数据:结点数据包括:多边形顶点数、各顶点的纵横坐标、当多边形顶点数为0时,链表创建结束。(3)编写一个函数disp,删除链表中的所有结点。需要注意的是:要先释放结点数据内存,再删除结点,如果在释放结点数据内存单元之前删除结点,则无法找到结点数据内存单元的地址,也就无法释放数据的内存单元。 【程序】 #include “iostxeam. h” #include “iomanip. h” stmct polygon { int n; int *x; int *y; polygon *next; }; void Push(polygon*& head, int n) { polygon* newNode = new polygon; newNode = new polygon; newNode->
next=(1); newNode->x = new int[n]; newNode->y = new int[n]; newNode->n=(2); for(int i=0; i<=(3); i++) { cout<<”请输入多边形各顶点x、y坐标, 坐标值之间用空格分隔: “; cin>>newNode->x[i]>>newNode->y[i]; }(4)= head; //在head前不需要额外的* head = newNode; } polygon *create( ) { polygon* head = NULL; polygon* tail; int n; cout<<”请输入多边形顶点的
个数(顶点个数为0时结束): “; cin>>n; if(n==O) return (5); Push(head,(6)); tail = head; cout<<”请输入多边形顶点的个数(顶点个数为0时结束): “; cin>>n; while(n!=0) {Push(tail->next,(7));// 在tail->next增加结点tail = tail->next; //advance tail to point to last nodecout<<”请输入多边形顶点的个数(顶点个数为0时结束): “;cin>>
n; } remm head; } void disp(polygon *head) { inti, No=l; eout<<setw( 10)<<”x”<<setw(6)<<”y”<<endl; while(head !=NULL) {cout<<”第”<<No<<”结点: “<<endl;for(i=0;i<=head->n-1;i++)cout<<setw(10)<<head->x [i] <<setw(6)
<<head->y[i]<<endl;(8);he ad=(9); }//Match while statement }
void del(polygon *head) { polygon *p; while(head!=NIILL {p=(10);head=head->next; delete p->x; delete p->y; delete p;}//Match
while statement void main( ) { polygon *head; head=create( ); disp(head); del(head); }
正确答案:(1)NULL(2) n(3)n-1(4)newNode->next(5)head(6) n(7) h(8)NO++(9)head->next(10)head
解析:如果掌握了链表的创建、遍历和删除的方法,解决本题应该并不困难。要显示链表各结点的数据,就是要把各结点找到,然后把该结点的的每一个x、y坐标打印出来。不过,与普通的链表也有不同的地方:就是该链表的结点数据是指针。要在链表结点中存入数据,必须先动态分配存储数据的内存单元;要删除链表中的各个结点,必须先释放结点数据的内存单元,否则会造成内存泄露。
选答题(共3道大题,每道大题15分)从下列3道试题中任选1道解答,如果解答的试题数超过1道,则仅题号小的1道题解答有效。
12. 从下列的3道式题(试题五至试题七)中任选1道解答。 如果解答的试题数超过1道,则题号小的1道解答有效。 阅读以下说明和C++码,将应填入(n)处的字名写在的对应栏内。[说明] 利用c++的各种控制语句编写一个万年历程序,要求:显示任何年份的日历,日历以月份顺序排列,每月以星期顺序排列,类似于一般挂历上的格式。本程序包含如下两个函数:Leap ( )用于判定指定的年份是闰年,Week ( )用于计算year年份的1月1日是星期几,其判定规则为:(1) 如果year 年份为1994年,则为星期六。(2) 如果year 年份大于1994年,则星期值weekno 按下列公式计算:differ=(year-1994)*(365%6)+(year-1993)/4-(year-2001)/100+(year-2001)/400
date=6+differ%7weekno=(date6)? date-7:date(3) 如果year 年份小于1994年,则星期值weekno 按下列公式计算:differ=(1994-year)*(365%7)+(1996-year)/4-(2001-year)/100+(2000-year)/400
weekno=6-dder%7 # include “iostream. h” # include “iomanip. h” int leap(int n) { if( (1) )return 0 elsereturn 1; } int week( int
year ) { int a1, differ, date, weekno; if (year = = 1994)a1 =0; else if (year > 1994) a1=1; else a1= -1; switch(a1){ case 0: return 6; break; case 1: { (2) date = 6 + differ% 7; weekno = ( date > 6) ? date - 7 date; } return weekno; break;case - 1: { differ = ( 1994 - year) * (365%7) + (1996 - year)/4 - (2001 - year)/100 + (2000 - year)/400; weekno =6-differ%7; } return weekno; break; }} void main( ) } int i,year,m2,n,j; cout
< < “Please input 某年数:”; cin> >year; if ( ! leap(year) )(3); elsem2 =28; int month [12]: {31 ,m2,31,30,31,30,31,31,30,31,30,31 };(4)for ( i=0; i<12; i+ + ) { cout< < < <end1< <setw(4*n) < <”; for(j=1 ;j< =month [i] ;j+ +) { cout< <setw(4) < <j; n+ +; if(n> =7) { (5) cout < < end1; } } } }
正确答案:(n%100 = =0) ||(n%400 = =0)differ=(year - 1994) *(365%6) +(year - 1993)/4 -(year-2001)/100 +(year-2001 )/400;m2 =29n = week( year );n=0;
13. 阅读以下说明和Java 码,将应填入(n)处的字名写在的对应栏内。 [说明] 打印输出10行杨晖三角形。形式如下:杨晖三角形:11 11 2 11 3 3 11 4 6 4 11 5 10 10 5 11 6 15 20 15 6 11 7 21 35 35 21 7 11 8 28 56 70 56 28 8 11 9 36 84 126
126 84 36 9 1 class yanghui { public static void main (String args [] ) {int i, j; (1) int yanghui [] [];System. out. println( “杨晖三角形:” );yanghui = new int [ yhleve1] [];for(i =0;i < yanghui, length; i + + ) yanghui[i] = new int [i + 1]; (2) for((3)){yanghui [i] [0] = 1;for(j = 1 ;j < yanghui[i], length - 1 ;j + + ) yanghui[i] [j] = yanghui[i - 1] [j - 1] + yanghui[i - 1] [j]; yanghui[i] [yanghui[i]. length - 1 ] = 1;}for ( i=0; i < yanghui. length; i + + ){ for(j =0;j < yanghui[i]. length; j + + ) (4) System. out. println( );} } }
正确答案:int yhleve1 = 10;yanghui [0] [0] = 1;i=1; i < yanghui, length; i + +System. out. print( yanghui [i] [j] +” “);
14. 阅读以下说明和Visual Basic 码,将应填入(n)处的字名写在的对应栏内 [说明] 编写一工资调整程序。若基本工资大于等于800元,工资增加20%,若小于800元大于 600元,则工资增加15%,若小于600元则工资增加10%。要求在文本框Text1 中增加某职工的基本工资,单击“计算”按钮,在标签框Label1中输出增加后的工资。 Private Sub Command1_ Click( ) Dim x
As Integer, y As Single(1)Select Case x Case Is > = 800 y=x*1.2 Case Is > = 600 y=x, 1.5(2) y=x*1.1(3)Label1. Caption = y (4) Private Sub Command2_ Click( ) Unload Me End Sub
正确答案:x=Val(Text1, Text)Case ElseEnd SelectEnd Sub
因篇幅问题不能全部显示,请点此查看更多更全内容