試題四
閱讀下列函數(shù)說明、圖和C代碼,將應(yīng)填入 (n) 處的字句。
[說明]
散列文件的存儲(chǔ)單位稱為桶(BUCKET)。假如一個(gè)桶能存放m個(gè)記錄,當(dāng)桶中已有 m個(gè)同義詞(散列函數(shù)值相同)的記錄時(shí),存放第m+1個(gè)同義詞會(huì)發(fā)生“溢出”。此時(shí)需要將第m+1個(gè)同義詞存放到另一個(gè)稱為“溢出桶”的桶中。相對(duì)地,稱存放前m個(gè)同義詞的桶為“基桶”。溢出桶和基桶大小相同,用指針鏈接。查找指定元素記錄時(shí),首先在基桶中查找。若找到,則成功返回,否則沿指針到溢出桶中進(jìn)行查找。
例如:設(shè)散列函數(shù)為Hash(Key)=Key mod 7,記錄的關(guān)鍵字序列為15,14,21,87,97,293,35,24,149,19,63,16,103,77,5,153,145,356,51,68,705,453,建立的散列文件內(nèi)容如圖4-1所示。
[圖4-1]
為簡化起見,散列文件的存儲(chǔ)單位以內(nèi)存單元表示。
函數(shù)InsertToHashTable(int NewElemKey)的功能是:將元素NewEIemKey插入散列桶中,若插入成功則返回0,否則返回-1。
采用的散列函數(shù)為Hash(NewElemKey)=NewElemKey % P,其中P為設(shè)定的基桶數(shù)目。
函數(shù)中使用的預(yù)定義符號(hào)如下:
#define NULLKEY -1 /*散列桶的空閑單元標(biāo)識(shí)*/
#define P 7 /*散列文件中基桶的數(shù)目*/
#define ITEMS 3 /*基桶和溢出桶的容量*/
typedef struct BucketNode{ /*基桶和溢出桶的類型定義*/
int KcyData[ITEMS];
struct BucketNode *Link;
}BUCKET;
BUCKET Bucket[P]; /*基桶空間定義*/
[函數(shù)]
int lnsertToHashTable(int NewElemKey){
/*將元素NewElemKey插入散列桶中,若插入成功則返回0,否則返回-1*/
/*設(shè)插入第一個(gè)元素前基桶的所有KeyData[]、Link域已分別初始化為NULLKEY、
NULL*/
int Index; /*基桶編號(hào)*/
int i,k;
BUCKET *s,*front,*t;
(1) ;
for(i=0; i<ITEMS;i++)/*在基桶查找空閑單元,若找到則將元素存入*/
if(Bucket[Index].KeyData[i]=NULLKEY){
Bucket[Index].KeyData[i]=NewElemKey; break;
}
if( (2) ) return 0;
/*若基桶已滿,則在溢出桶中查找空閑單元,若找不到則申請(qǐng)新的溢出桶*/
(3) ; t=Bucket[Index].Link;
if(t!=NULL) {/*有溢出桶*/
while (t!=NULL){
for(k=0; k<ITEMS; k++)
if(t->KeyData[k]=NULLKEY){/*在溢出桶鏈表中找到空閑單元*/
t->KeyData[k]=NewElemKey; break;
}/*if*/
front=t;
if( (4) )t=t->Link;
else break;
}/*while*/
}/*if*/
if( (5) ) {/*申請(qǐng)新溢出桶并將元素存入*/
s=(BUCKET*)malloe(sizeof(BUCKET));
if(!s) return-1;
s->Link=NULL;
for(k=0; k<ITEMS; k++)
s->KeyData[k]=NULLKEY;
s->KeyData[0]=NewElemKey;
(6) ;
}/*if*/
return 0;
}/*InsertToHashTable*/
試題一
閱讀下列說明和圖,回答問題1~問題3。
[說明]
某公司的主要業(yè)務(wù)是出租圖書和唱碟。由于業(yè)務(wù)需求,該公司委托軟件開發(fā)公司A開發(fā)一套信息管理系統(tǒng)。該系統(tǒng)將記錄所有的圖書信息、唱碟信息、用戶信息、用戶租借信息等。A公司決定采用面向?qū)ο蟮姆治龊驮O(shè)計(jì)方法開發(fā)此系統(tǒng)。圖1-1所示為某類圖書或唱碟被借閱時(shí)應(yīng)記錄的信息,圖1-2描述了系統(tǒng)定義的兩個(gè)類Book和CD,分別表示圖書和唱碟的信息。
[問題1]
經(jīng)過進(jìn)一步分析,設(shè)計(jì)人員決定定義一個(gè)類Items on loan,以表示類Book和CD的共有屬性和方法。請(qǐng)采用圖1-2中屬性和方法的名稱給出類Items_on_loan應(yīng)該具有的屬性和方法(注意:不同名稱的屬性和方法表示不同的含義,如CD中的composer與 Book甲的author無任何關(guān)系)。
[問題2]
為了記錄每種圖書或唱碟租借的歷史記錄,引入類CirculationHistory,類中存儲(chǔ)的信息是圖1-1中所表示的內(nèi)容。請(qǐng)采用UML表示法將下列四個(gè)類間的關(guān)系表示出來。
[問題3]
現(xiàn)需了解十大最暢銷(借出次數(shù)最多)圖書或唱碟。為此,引入TenPopulate類以存儲(chǔ)所有十大暢銷圖書或CD的名稱及其被借出的次數(shù)。下列順序圖描述了某類圖書或唱碟被借出后成為十大暢銷圖書或唱碟時(shí)對(duì)象間的消息交互。系統(tǒng)在一次運(yùn)行過程中,應(yīng)有 (1) 個(gè)TenPopulate實(shí)例對(duì)象最合適,一個(gè)TenPopulate類實(shí)例對(duì)象最多需要和 (2) 個(gè)Items_on_loan實(shí)例對(duì)象交互。
試題二
閱讀下列說明和圖,回答問題1至問題3。
[說明]
某企業(yè)決定開發(fā)一個(gè)企業(yè)倉儲(chǔ)管理系統(tǒng),山李工承擔(dān)系統(tǒng)的設(shè)計(jì)工作。該系統(tǒng)的網(wǎng)絡(luò)連接如圖2-1所示。
[圖2-1]
該企業(yè)有多個(gè)倉庫,圖2-1所示的中心數(shù)據(jù)庫存儲(chǔ)了各個(gè)倉庫中每種貨物的庫存信息。每個(gè)倉庫配備一臺(tái)前端機(jī),進(jìn)出貨物均由前端機(jī)輔助實(shí)現(xiàn)。管理員每天上班時(shí),通過前端機(jī)從中心數(shù)據(jù)庫的庫存表中讀取本倉庫各種貨物的庫存數(shù),每個(gè)倉庫的當(dāng)日業(yè)務(wù)數(shù)據(jù)也都暫存在前端機(jī),當(dāng)天業(yè)務(wù)結(jié)束后,再將前端機(jī)中存儲(chǔ)的數(shù)據(jù)傳輸?shù)街鳈C(jī)進(jìn)行存儲(chǔ)與匯總。
每個(gè)倉庫可以存放多種貨物,但同一種貨物不能存放在不同的倉庫中。每個(gè)倉庫有多個(gè)管理員,但每個(gè)管理員只管理一個(gè)倉庫。貨物出庫/入庫時(shí),由倉庫管理員將貨物的條碼通過閱讀器輸入前端機(jī)中,貨物數(shù)量的默認(rèn)值為1,可以由管理員修改。前端機(jī)根據(jù)輸入的貨物信息,打印“出庫/入庫”清單。出庫/入庫單中同一種貨物最多只出現(xiàn)一次,每份出庫/入庫單由流水號(hào)唯一標(biāo)識(shí)。圖2-2是一個(gè)出庫單的實(shí)例。
[圖2-2] 流水號(hào);200408080001300101 時(shí)間:2005-10-01 13:22
該系統(tǒng)處理業(yè)務(wù)的過程如下。
1.初始化:前端機(jī)根據(jù)倉庫號(hào)從貨物表中讀取本倉庫中每種貨物的貨物編碼、庫存量、貨物名稱和單價(jià);
2.登記出庫/入庫信息:由前端機(jī)存儲(chǔ)每一筆“出庫從庫”記錄:
3.匯總:在每個(gè)工作日結(jié)束前匯總當(dāng)日各種貨物的“出庫/入庫”量至日匯總表;
4.更新庫存表:根據(jù)當(dāng)日的匯總信息更新貨物的庫存。
李工經(jīng)過分析,設(shè)計(jì)出如圖2-3所示的關(guān)系模式。
[圖2-3]
出入庫單(流水號(hào),出入庫標(biāo)志,管理員號(hào),時(shí)間)
出入庫記錄(貨物編碼,數(shù)量,流水號(hào))
日匯總表(日期,貨物編碼,數(shù)量,出入庫標(biāo)志)
倉庫(倉庫號(hào),倉庫名,倉庫電話)
管理員(管理員號(hào),姓名,倉庫號(hào))
貨物( (a) )
注:時(shí)間格式為年-月-日時(shí):分;日期格式為年-月-日。
賣體聯(lián)系圖的表示方法如圖2-4所示,其中方框表示實(shí)體,菱形表示聯(lián)系,聯(lián)系的類型在實(shí)體與聯(lián)系的邊上標(biāo)出。圖2-5為與該系統(tǒng)對(duì)應(yīng)的實(shí)體聯(lián)系圖。
[問題1]
根據(jù)題意,補(bǔ)充圖2-3中(a)處的空缺,即貨物關(guān)系模式的屬性。
[問題2]
根據(jù)題意,補(bǔ)充圖2-5中缺失的聯(lián)系和聯(lián)系的類型,使其成為完善的實(shí)體聯(lián)系圖。其中,聯(lián)系名分別取名為聯(lián)系1,聯(lián)系2,聯(lián)系3,……。
[問題3]
寫出每種關(guān)系模式的主鍵。
試題三
閱讀下列說明和圖,回答問題1至問題4,將解答填入答題紙的對(duì)應(yīng)欄內(nèi)。
[說明]
某公司計(jì)劃與客戶通過Internet交換電子郵件和數(shù)據(jù)(以下統(tǒng)一稱為“消息”)。為保障安全,在對(duì)傳輸?shù)臄?shù)據(jù)進(jìn)行加密的同時(shí),還要對(duì)參與通信的實(shí)體進(jìn)行身份認(rèn)證。因此,需同時(shí)使用對(duì)稱與非對(duì)稱密鑰體系。圖3-1描述了接收者B使用非對(duì)稱密鑰體系對(duì)發(fā)送者A進(jìn)行認(rèn)證的過程。
[圖3-1]
圖3-2描述了發(fā)送和接收消息的過程,其中的認(rèn)證過程使用了圖3-1中的方法。圖3—1中的方框a和方框b與圖3-2中的方框a和方框b相同。
[圖3-2]
圖3-2中發(fā)送和接收消息的過程是:
1)發(fā)送者A使用與接收者B共享的對(duì)稱密鑰體系的密鑰加密將要發(fā)送的消息。
2)為了實(shí)現(xiàn)身份認(rèn)證,A使用與B共享的摘要算法生成消息摘要,并使用公鑰密碼體系把生成的消息摘要加密后發(fā)送給B(這里假設(shè)A和B都能通過安全的方法獲得對(duì)方的公鑰)。
3)B使用非對(duì)稱密鑰體系解密收到的消息摘要,使用與A共享的對(duì)稱密鑰體系的密鑰解密加密后的消息,再使用與A共享的摘要算法針對(duì)解密后的消息生成消息摘要。
4)B對(duì)比自己生成的消息摘要與接收到的A發(fā)送的消息摘要是否相同,從而驗(yàn)證發(fā)送者A的身份。
[問題1]
請(qǐng)?jiān)谙铝羞x項(xiàng)中選擇合適的答案,填入圖3-1、圖3-2的方框a和方框b。
B的公鑰,B的私鑰,摘要算法,A的私鑰,A的公鑰,會(huì)話密鑰
[問題2]
請(qǐng)?jiān)谙铝羞x項(xiàng)中選擇合適的答案,填入圖3-2的方框c至方框f。
B的公鑰,B的私鑰,摘要算法,A的私鑰,A的公鑰,會(huì)話密鑰
[問題3]
按照?qǐng)D3-2中的方法發(fā)送郵件時(shí),使用不同的密碼體制加密消息和消息摘要,請(qǐng)用 150字以內(nèi)文字簡要說明這樣做的理由。
[問題4]
請(qǐng)從下面關(guān)于摘要函數(shù)的說法中選出所有正確的描述。
[a]很容易使不同的輸入數(shù)據(jù)生成相同的輸出數(shù)據(jù)。
[b]根據(jù)輸入數(shù)據(jù)獲取輸出數(shù)據(jù)的時(shí)間非常短。
[c]根據(jù)輸入數(shù)據(jù)獲取輸出數(shù)據(jù)的時(shí)間非常長。
[d]輸出數(shù)據(jù)的長度比輸入數(shù)據(jù)的長度要長。
[e]根據(jù)輸出數(shù)據(jù)無法還原出輸入數(shù)據(jù)。
試題五
閱讀以下說明和C++代碼,將應(yīng)填入 (n) 處。
[說明]
在一公文處理系統(tǒng)中,開發(fā)者定義了一個(gè)公文類OfficeDoc,其中定義了公文具有的屬性和處理公文的相應(yīng)方法。當(dāng)公文的內(nèi)容或狀態(tài)發(fā)生變化時(shí),關(guān)注此OfficeDoc類對(duì)象的相應(yīng)的DocExplorer對(duì)象都要更新其自身的狀態(tài)。一個(gè)OfficeDoc對(duì)象能夠關(guān)聯(lián)一組 DocExplorer對(duì)象。當(dāng)OfficeDoc對(duì)象的內(nèi)容或狀態(tài)發(fā)生變化時(shí),所有與之相關(guān)聯(lián)的 DocExplorcr對(duì)象都將得到通知,這種應(yīng)用被稱為觀察者模式。以下代碼寫在一個(gè)C++源文件中,能夠正確編譯通過。
[C++代碼]
#include <iostream>
const OBS_MAXNUM=20;//最多與OfficeDoc對(duì)象相關(guān)聯(lián)的DocExplorer對(duì)象的個(gè)數(shù)
(1) ;
class DocExplorer{ //關(guān)注OfficeDoc公文對(duì)象的類
public:
DocExplorer( (2) *doc); //構(gòu)造函數(shù)
(3) void update(OfficeDoc *doc)=0;//更新自身狀態(tài)的函數(shù)
//其他相關(guān)屬性和方法省略
};
class OfficeDoc{ //公文類
private:
DocExplorer *myObs[OBS_MAXNUM];
//關(guān)注此公文類的DocExplorer類對(duì)象指針數(shù)組
int index; //與OfficeDoc對(duì)象關(guān)聯(lián)的DocExplorer對(duì)象的個(gè)數(shù)
public:
OfficeDoe()
index=0;
}
void attach(DocExplorer *o){
//將一DoeExplorer對(duì)象與OfficeDoe對(duì)象相關(guān)聯(lián)
if(index >=OBS_MAXNUM ||o=NULL)return;
for(int loop=0; loop<index; loop++)
if(myObs[loop]==o) return;
myObs[index]=o;
index++;
}
void detaeh(DocExplorer *o){
//接觸某DoeExplorer對(duì)象與OfficeDoc對(duì)象的關(guān)聯(lián)
if(0==NULL) return;
for(int loop=0; loop<index; loop++){
if(myObs[loop]==o){
if(loop<=index-2)myObs[loop]=myObs[index-1];
myObs[index-1]=NULL;
index--;
break;
}
}
}
private:
void notifyObs(){ //通知所有的DocExplorer對(duì)象更改自身狀態(tài)
for(int loop=0; loop<index; loop++){
myObs[loop]-> (4) ; //DocExplorer對(duì)象更新自身狀態(tài)
}
}
//其他公文類的相關(guān)屬性和方法
};
DocExplorer::DocExplorer(OfficeDoc *doc){//DocExplorer 類對(duì)象的構(gòu)造函數(shù)
doc-> (5) ; //將此DocExplorer對(duì)象與doc對(duì)象相關(guān)聯(lián)
}
試題六
閱讀以下說明和Java代碼,將應(yīng)填入 (n) 處。
[說明]
在一公文處理系統(tǒng)中,開發(fā)者定義了一個(gè)公文類OfficeDoc,其中定義了公文具有的屬性和處理公文的相應(yīng)方法。當(dāng)公文的內(nèi)容或狀態(tài)發(fā)生變化時(shí),關(guān)注此OfficeDoc類對(duì)象的相應(yīng)的DocExplorer對(duì)象都要更新其自身的狀態(tài)。一個(gè)OfficeDoc對(duì)象能夠關(guān)聯(lián)一組 DocExplorer對(duì)象。當(dāng)OfficeDoc對(duì)象的內(nèi)容或狀態(tài)發(fā)生變化時(shí),所有與之相關(guān)聯(lián)的 DocExplorer對(duì)象都將得到通知,這種應(yīng)用被稱為觀察者模式。以下代碼采用Java語言實(shí)現(xiàn),能夠正確編譯通過。
[Java代碼]
//Subject.java 文件
public interface Subject {
public void attach(Observer DocExplorer);
public void detach(Observer DocExplorer);
void notifyObservers();
}
//Observer.java 文件
public interface Observer{
void update( (1) );
}
//OfficeDoc.java 文件
import java.util.*;
public class OfficeDoc implements Subject(//OfficeDoc 類實(shí)現(xiàn) Subject 接口
private Vector ObserverVeetor=new java.util.Vector();
//存儲(chǔ)與OfficeDoc相關(guān)聯(lián)的DocExplorer 對(duì)象
public void attach(Observer observer){
//將某 DocExplorer 對(duì)象與OfficeDoc 相關(guān)聯(lián)
ObserverVector.addElement(observer);
}
public void detach(Observer observer){
//解除某DocExplorer 對(duì)象與OfficeDoc的關(guān)聯(lián)關(guān)系
ObserverVector.removeElement(observer);
}
public void notifyObservers(){
//當(dāng)OfficeDoc對(duì)象狀態(tài)已發(fā)生變化時(shí),通知所有的DocExplorer對(duì)象
Enumeration enumeration= (2) ;
while (enumeration.hasMoreElements()){
((Observer)enumeration.nextElement()). (3) ;
}
}
public Enumeration Observers(){
return ObserverVector.elements();
}
//其他公文類的屬性和方法省略
}
//DoeExplorer.java 文件
public class DocExplorer implements (4) {
public void update( (5) ){
//更新DocExplorer自身的狀態(tài),代碼省略
}
}
試題七
閱讀以下說明和C代碼,將應(yīng)填入 (n) 處。
[說明]
在一公文處理系統(tǒng)中,開發(fā)者定義了一個(gè)公文結(jié)構(gòu)OfficeDoc,其中定義了公文應(yīng)該具有的屬性(字段)。當(dāng)公文的內(nèi)容或狀態(tài)發(fā)生變化時(shí),與之相關(guān)聯(lián)的DocExplorer結(jié)構(gòu)的值都需要發(fā)生改變。一個(gè)OfficeDoc結(jié)構(gòu)能夠關(guān)聯(lián)一組DocExplorer結(jié)構(gòu)。當(dāng)OfficeDoc結(jié)構(gòu)的內(nèi)容或狀態(tài)發(fā)生變化時(shí),所有與之相關(guān)聯(lián)的DocExplorer結(jié)構(gòu)都將被更新,這種應(yīng)用被稱為觀察者模式。以下代碼采用C語言實(shí)現(xiàn),能夠正確編譯通過。
[C代碼]
#include <stdio.h>
#define OBS_MAXNUM 20 /*一個(gè)OfficeDoc變量最多能夠關(guān)聯(lián)的*/
/*DoeExplorer變量的個(gè)數(shù)*/
typedef void( (1) )(struct OfficeDoc*,street DocExplorer*);
struct DocExplorer{
func update;/* DocExplorer結(jié)構(gòu)采用的更新函數(shù)*/
/*其他的結(jié)構(gòu)字段省略*/
};
struct OfficeDoc{
(2) myObs[OBS_MAXNUM];
/*存儲(chǔ)所有與OfficeDoc相關(guān)聯(lián)的DoeExplorer結(jié)構(gòu)指針*/
int index;/*與OfficeDoc結(jié)構(gòu)變量相關(guān)聯(lián)的DocExplorer結(jié)構(gòu)變量的個(gè)數(shù)*/
};
void attach(struet OfficeDoc *doc, struet DocExplorer *ob){
/*關(guān)聯(lián)Obersver結(jié)構(gòu)ob與OfficeDoe結(jié)構(gòu)doc*/
int loop=0;
if(doc->index >=OBS_MAXNUM || ob==NULL) return;
for(loop=0; loop <doc->index; loop++)
if(doc->myObs[loop]==ob)return;
doc->myObs[doe->index]=ob;
doc->index++;
)
void detach(struct OfficeDoc *doc, struct DocExplorer *ob){
/*解除doc結(jié)構(gòu)與ob結(jié)構(gòu)間的關(guān)系*/
int loop;
if(ob==NULL)return;
for(loop=0; loop <doc->index; loop6++){
if(doc->myObs[loop]==ob){
if(loop<=doc->index-2)
doe->myObs[loop]=doc->myObs[ (3) ];
doc->myObs[doe->indox-1]=NULL;
doe->index--;
break;
}
}
}
void updatel(struct OfficeDoc *doc,struct DocExplorer *ob){
/*更新ob結(jié)構(gòu)的值,更新代碼省略*/
}
void update2(stmct OfficeDoc *doc, struct DocExplorer *ob){
/*更新ob結(jié)構(gòu)的值,更新代碼省略*/
}
void notifyObs(struet OfficeDoc *doc){
/*當(dāng)doc結(jié)構(gòu)的值發(fā)生變化時(shí),通知與之關(guān)聯(lián)的所有DocExplorer結(jié)構(gòu)變量*/
int loop;
for(loop=0; loop <doc->index; loop++){
(doc->myObs[loop])->update( (4) );
}
}
void main(){
stmct OfficeDoc doc;/*定義一OfficeDoc變量*/
struct DocExplorer explorer1, explorer2;/*定義兩個(gè)DocExplorer變量*/
/*初始化與OfficeDoc變量相關(guān)的DocExplorer變量個(gè)數(shù)為0*/
doc.index=0;
explorer1.update=update1;/*設(shè)置explorer1變量的更新函數(shù)*/
explorer2.update=update2;/*設(shè)置explorer2變量的更新函數(shù)*/
attaeh(&doc,&explorer1);/*關(guān)聯(lián)explorer1與doc對(duì)象*/
attach(&doc,&explorer2);/*關(guān)聯(lián)explorer2與doc對(duì)象*/
/*其他代碼省略*/
(5) ;/*通知與OfficeDoc相關(guān)的所有DocExplorer變量*/
return;
}