c/c++筆試題
微軟亞洲技術中心的面試題!!!
1.程序和執行緒的差別。
執行緒是指程序內的一個執行單元,也是程序內的可排程實體.與程序的區別:(1)排程:執行緒作為排程和分配的基本單位,程序作為擁有資源的基本單位(2)併發性:不僅程序之間可以併發執行,同一個程序的多個執行緒之間也可併發執行(3)擁有資源:程序是擁有資源的獨立單位,執行緒不擁有系統資源,但可以訪問隸屬於程序的資源.(4)系統開銷:在建立或撤消程序時,由於系統都要為之分配和回收資源,導致系統的開銷明顯大於建立或撤消執行緒時的開銷。
2.測試方法
人工測試:個人複查、抽查和會審機器測試:黑盒測試和白盒測試
2.Heap與stack的差別
Heap是堆,stack是棧。
3.Windows下的記憶體是如何管理的?
4.介紹.Net和.Net的安全性。
5.客戶端如何訪問.Net元件實現Web Service?
6.C/C++編譯器中虛表是如何完成的?
7.談談COM的執行緒模型。然後討論程序內/外元件的差別。
8.談談IA32下的分頁機制
小頁(4K)兩級分頁模式,大頁(4M)一級
9.給兩個變數,如何找出一個帶環單鏈表中是什麼地方出現環的?
一個遞增一,一個遞增二,他們指向同一個接點時就是環出現的地方 ??
10.在IA32中一共有多少種辦法從使用者態跳到核心態?
通過呼叫門,從ring3到ring0,中斷從ring3到ring0,進入vm86等等
11.如果只想讓程式有一個例項執行,不能執行兩個。像winamp一樣,只能開一個視窗,怎樣實現?
用記憶體對映或全域性原子(互斥變數)、查詢視窗控制代碼..FindWindow,互斥,寫標誌到檔案或登錄檔,共享記憶體。.
12.如何擷取鍵盤的響應,讓所有的‘a’變成‘b’?
鍵盤鉤子SetWindowsHookEx
13.Apartment在COM中有什麼用?為什麼要引入?
14.儲存過程是什麼?有什麼用?有什麼優點?
儲存過程(Stored Procedure)是一組為了完成特定功能的SQL 語句集,經編譯後儲存在資料庫。中使用者通過指定儲存過程的名字並給出引數(如果該儲存過程帶有引數)來執行它。
儲存過程用於實現頻繁使用的查詢、業務規則、被其他過程使用的公共例行程式
儲存過程在建立時即在伺服器上進行編譯,所以執行起來比單個 SQL 語句快
15.Template有什麼特點?什麼時候用?
16.談談Windows DNA結構的特點和優點。
17.網路程式設計中設計併發伺服器,使用多程序與多執行緒 ,請問有什麼區別?
1,程序:子程序是父程序的複製品。子程序獲得父程序資料空間、堆和棧的複製品。2,執行緒:相對與程序而言,執行緒是一個更加接近與執行體的概念,它可以與同進程的其他執行緒共享資料,但擁有自己的棧空間,擁有獨立的執行序列。區別:兩者都可以提高程式的併發度,提高程式執行效率和響應時間。執行緒和程序在使用上各有優缺點:執行緒執行開銷小,但不利於資源管理和保護;而程序正相反。同時,執行緒適合於在SMP機器上執行,而程序則可以跨機器遷移。
MSRA Interview Written Exam(December 2003,Time:2.5 Hours)
1寫出下列演算法的時間複雜度。
(1)氣泡排序; (2)選擇排序;(3)插入排序;(4)快速排序;(5)堆排序;(6)歸併排序;
2寫出下列程式在X86上的執行結果。
struct mybitfields { unsigned short a : 4; unsigned short b : 5; unsigned short c : 7; }test
void main(void) { int i; test.a=2; test.b=3; test.c=0;
i=*((short *)&test); printf("%d/n",i); }
3寫出下列程式的執行結果。
unsigned int i=3; cout<<i * -1;
4寫出下列程式所有可能的執行結果。
int a; int b; int c;
void F1() { b=a*2; a=b; }
void F2() { c=a+1; a=c; }
main() { a=5; //Start F1,F2 in parallel F1(); F2(); printf("a=%d/n",a); }
5考察了一個CharPrev()函式的作用。
6對 16 Bits colors的處理,要求:
(1)Byte轉換為RGB時,保留高5、6bits; (2)RGB轉換為Byte時,第2、3位置零。
7一個連結串列的操作,注意程式碼的健壯和安全性。要求:
(1)增加一個元素; (2)獲得頭元素; (3)彈出頭元素(獲得值並刪除)。
8一個給定的數值由左邊開始升位到右邊第N位,如 0010<<1 == 0100 或者0001 0011<<4 == 0011 0000 請用C或者C++或者其他X86上能執行的程式實現。
附加題(只有在完成以上題目後,才獲准回答)
1。In C++, what does "explicit" mean? what does "protected" mean?
c++中的explicit關鍵字用來修飾類的建構函式,表明該建構函式是顯式的,在某些情況下,我們要求類的使用者必須顯示呼叫類的建構函式時就需要使用explicit,反之預設型別轉換可能會造成無法預期的問題。
protected控制的是一個函式對一個類的成員(包括成員變數及成員方法)的訪問許可權。protected成員只有該類的成員函式及其派生類的成員函式可以訪問
1. 在C++中有沒有純虛建構函式?
建構函式不能是虛的。只能有虛的解構函式
2. 在c++的一個類中宣告一個static成員變數有沒有用?
在C++類的成員變數被宣告為static(稱為靜態成員變數),意味著它為該類的所有例項所共享,也就是說當某個類的例項修改了該靜態成員變數,也就是說不管建立多少物件,static修飾的變數只佔有一塊記憶體。其修改值為該類的其它所有例項所見;而類的靜態成員函式也只能訪問靜態成員(變數或函式)。
static是加了訪問控制的全域性變數,不被繼承。
3。在C++的一個類中宣告一個靜態成員函式有沒有用? (同上?)
4。如何實現一個非阻塞的socket?
5。setsockopt, ioctl都可以對socket的屬性進行設定,他們有什麼不同? (linux)
6。解釋一下程序和執行緒的區別? (重複,參見微軟亞洲技術中心筆試)7。解釋一下多播(組播)和廣播的含義?
組播:主機之間“一對一組”的通訊模式,也就是加入了同一個組的主機可以接受到此組內的所有資料,網路中的交換機和路由器只向有需求者複製並轉發其所需資料。主機可以向路由器請求加入或退出某個組,網路中的路由器和交換機有選擇的複製並傳輸資料,即只將組內資料傳輸給那些加入組的主機。
廣播:主機之間“一對所有”的通訊模式,網路對其中每一臺主機發出的訊號都進行無條件複製並轉發,所有主機都可以接收到所有資訊(不管你是否需要).
8。多播採用的協議是什麼?
9。在c++中純虛解構函式的作用是什麼?請舉例說明。
10。程式設計,請實現一個c語言中類似atoi的函式功能(輸入可能包含非數字和空格)
百度筆試題
一、選擇題:15分 共10題 1. 在排序方法中,關鍵碼比較次數與記錄地初始排列無關的是 .A. Shell排序 B. 歸併排序 C. 直接插入排序 D. 選擇排序
2. 以下多執行緒對int型變數x的操作,哪幾個需要進行同步: A. x=y; B. x++; C. ++x; D. x=1;
3. 程式碼 void func() { static int val; … } 中,變數val的記憶體地址位於: A. 已初始化資料段 B.未初始化資料段 C.堆 D.棧
4. 同一程序下的執行緒可以共享以下 A. stack B. data section C. register set D. thread ID
5. TCP和IP分別對應了 OSI中的哪幾層? A. Application layer B. Data link layer C. Presentation layer D. Physical layer E. Transport layer F. Session layer G. Network layer
6. short a[100],sizeof(a)返回? A 2 B 4 C 100 D 200 E 400
7. 以下哪種不是基於元件的開發技術_____。 A XPCOM B XP C COM D CORBA
8. 以下程式碼列印的結果是(假設執行在i386系列計算機上): struct st_t { int status; short* pdata; char errstr[32]; };
st_t st[16]; char* p = (char*)(st[2].errstr + 32); printf("%d", (p - (char*)(st)));
A 32 B 114 C 120 D 1112
9. STL中的哪種結構是連續形式的儲存 A map B set C list D vector
10. 一個棧的入棧序列是A,B,C,D,E,則棧的不可能的輸出序列是( )A、EDCBA; B、DECBA; C、DCEAB; D、ABCDE
參考答案:D /ABC/ A/ BC /EG /D /B/ C/ D/ C
二、簡答題:20分,共2題
1. (5分)重複多次fclose一個開啟過一次的FILE *fp指標會有什麼結果,並請解釋。考察點:導致檔案描述符結構中指標指向的記憶體被重複釋放,進而導致一些不可預期的異常。
2. (15分)下面一段程式碼,想在呼叫f2(1)時列印err1,呼叫f2(2)時列印err4,但是程式碼中有一些問題,請做盡可能少的修改使之正確。 1 static int f1(const char *errstr, unsigned int flag) { 2 int copy, index, len; 3 const static char **__err = {“err1”, “err2”, “err3”, “err4”}; 4 5 if(flag & 0x10000) 6 copy = 1; 7 index = (flag & 0x300000) >> 20; 8 9 if(copy) { 10 len = flag & 0xF; 11 errstr = malloc(len); 12 if(errstr = NULL) 13 return -1; 14 strncpy(errstr, __err[index], sizeof(errstr)); 15 } else 16 errstr = __err + index; 17 } 18 19 void f2(int c) { 20 char *err; 22 swtch(c) { 23 case 1: 24 if(f1(err, 0x110004) != -1) 25 printf(err); 26 case 2: 27 if(f2(err, 0x30000D) != -1) 28 printf(err); 29 } 30 }
三、程式設計題:30分 共1題 注意:要求提供完整程式碼,如果可以編譯執行酌情加分。
1. 求符合指定規則的數。 給定函式d(n) = n + n的各位之和,n為正整數,如 d(78) = 78+7+8=93。 這樣這個函式可以看成一個生成器,如93可以看成由78生成。 定義數A:數A找不到一個數B可以由d(B)=A,即A不能由其他數生成。現在要寫程式,找出1至10000裡的所有符合數A定義的數。 輸出: 1 3 …
四、設計題:35分 共1題 注意:請儘可能詳細描述你的資料結構、系統架構、設計思路等。建議多寫一些虛擬碼或者流程說明。
1. 假設一個mp3搜尋引擎收錄了2^24首歌曲,並記錄了可收聽這些歌曲的2^30條URL,但每首歌的URL不超過2^10個。系統會定期檢查這些URL,如果一個URL不可用則不出現在搜尋結果中。現在歌曲名和URL分別通過整型的SONG_ID和URL_ID唯一確定。對該系統有如下需求:1) 通過SONG_ID搜尋一首歌的URL_ID,給出URL_ID計數和列表2) 給定一個SONG_ID,為其新增一個新的URL_ID3) 新增一個新的SONG_ID 4) 給定一個URL_ID,將其置為不可用
限制條件:記憶體佔用不超過1G,單個檔案大小不超過2G,一個目錄下的檔案數不超過128個。
為獲得最佳效能,請說明設計的資料結構、搜尋演算法,以及資源消耗。如果系統資料量擴大,該如何多機分佈處理?
漢略曾考的測試題目
Q:When speaking of software products, how do you define the term“quality”.問:當說到軟體產品的時候,你如何定義術語“質量”
Meeting customer requirementsQ:What is the role of software debelopers and quality assuranle engineers in ensuring the quality of the product? How are other functional areas important to developing a quality product?問:在確定產品的質量方面,什麼是軟體開發工程師和質量保證工程師要做的?其他的功能對如何發展產品質量有什麼重要?
軟體測試是貫穿整個軟體開發生命週期、對軟體產品(包括階段性產品)進行驗證和確認的活動過程,其目的是儘快儘早地發現在軟體產品中所存在的各種問題——與使用者需求、預先定義的不一致性。Quality assuranle engineers: use a set of activities designed to ensure the development process to meet the requirements.Q:What is cyclomatic complexity?問:(這是一個複雜度模型吧)
一種程式碼複雜度的衡量標準,中文名稱叫做圈複雜度。圈複雜度“用來衡量一個模組判定結構的複雜程度,數量上表現為獨立現行路徑條數,即合理的預防錯誤所需測試的最少路徑條數,圈複雜度大說明程式程式碼可能質量低且難於測試和維護,根據經驗,程式的可能錯誤和高的圈複雜度有著很大關係”。Q:What are black-box texing and white-box texting?問:什麼是黑盒測試和白盒測試?
黑盒測試(Black-box Testing,又稱為功能測試或資料驅動測試)是把測試物件看作一個黑盒子。利用黑盒測試法進行動態測試時,需要測試軟體產品的功能,不需測試軟體產品的內部結構和處理過程。採用黑盒技術設計測試用例的方法有:等價類劃分、邊界值分析、錯誤推測、因果圖和綜合策略。黑盒測試注重於測試軟體的功能性需求,也即黑盒測試使軟體工程師派生出執行程式所有功能需求的輸入條件。黑盒測試並不是白盒測試的替代品,而是用於輔助白盒測試發現其他型別的錯誤。
白盒測試(,又稱邏輯驅動測試,結構測試)是把測試物件看作一個開啟的盒子。利用白盒測試法進行動態測試時,需要測試軟體產品的內部結構和處理過程,不需測試軟體產品的功能。白盒測試又稱為結構測試和邏輯驅動測試。白盒測試法的覆蓋標準有邏輯覆蓋、迴圈覆蓋和基本路徑測試。其中邏輯覆蓋包括語句覆蓋、判定覆蓋、條件覆蓋、判定/條件覆蓋、條件組合覆蓋和路徑覆蓋。
Black box testing: a testing without knowledge of the internal working of the item being tested.white box testing: use specific knowledge of programming code to examine outputs.
Q:The following function divides a by b and out put to c,returns -1 as error. Int divide (int a,int b,int c) List you test cases in a black-box testing.問:對 Int divide (int a,int b,int c)函式寫出黑盒測試用例
先等價,後邊界值
a b c 預期 結果 g g 5 0 6 2 0 1 -10 10 -10 -10 10.0 10.0 Q:Int a ctivity(int nage,bool bmale) {if (nage<60) return zoo; else if(bmale) return golf; else return movie; } 用cyclomatic complexity,共有多少條路徑 3Q:The following function tests whether the three numbers can be the lengths of the three sides of a triangle.Bool triangle(float a,float b,float c)List you test cases in a black-box testing.問:也是讓寫黑盒測試用例,是一個三個數是否是三角形的三條邊的測試
先等價,後邊界值
a b c 預期 結果 g j 0 -1 2 2 10 2 3 2 3 4 2 2 5 6 6 6
IQ,EQ題
然後是英文的資料結構,c/c++,資料庫,3D建模,軟體工程,軟體測試
題目幾乎都是英文的
後面還要填表格,一張中文的,一張英文的
一般有三個步驟首先會筆試。筆試題分為EQ題和專業題,EQ題沒什麼好說的,大家自由發揮就行,不過其中有一些邏輯推理題要注意。專業題目全英文,考的內容很多,資料結構,C/C++語法,COM,3D建模,軟體測試基礎知識,如黑盒,白盒測試等,題不難,每方面有三到五題左右。筆試成績達到一定分數過後才能進入第二輪人事部面試。這部分面試一般是五人一組在一房間裡,面試人員會問很多問題,然後每個人做答,問題很隨機,當時好像問了“最尊敬的人是誰,最難忘的事是什麼,有何職業規劃,如何處理與同事之間的關係矛盾等等”。這輪過後就到技術部面試,會問一些基礎知識,如資料結構常用的有哪些,如何用C/C++寫出其中的一種,面象對像有哪些特性,XML是什麼等等,可能他會用英語問你這些問題,各位練下聽力口語哈(當時俺被問的很鬱悶)
COM:
(COM),是微軟公司為了計算機工業的軟體生產更加符合人類的行為方式開發的一種新的軟體開發技術。在COM構架下,人們可以開發出各種各樣的功能專一的元件,然後將它們按照需要組合起來,構成複雜的應用系統。由此帶來的好處是多方面的:可以將系統中的元件用新的替換掉,以便隨時進行系統的升級和定製;可以在多個應用系統中重複利用同一個元件;可以方便的將應用系統擴充套件到網路環境下;COM與語言,平臺無關的特性使所有的程式設計師均可充分發揮自己的才智與專長編寫元件模組;等等。COM是開發軟體元件的一種方法。元件實際上是一些小的二進位制可執行程式,它們可以給應用程式,作業系統以及其他元件提供服務。
開發自定義的COM元件就如同開發動態的,面向物件的API。多個COM物件可以連線起來形成應用程式或元件系統。並且元件可以在執行時刻,在不被重新連結或編譯應用程式的情況下被卸下或替換掉。Microsoft的許多技術,如ActiveX, DirectX以及OLE等都是基於COM而建立起來的。並且Microsoft的開發人員也大量使用COM元件來定製他們的應用程式及作業系統。COM所含的概念並不止是在Microsoft Windows作業系統下才有效。COM並不是一個大的API,它實際上象結構化程式設計及面向物件程式設計方法那樣,也是一種程式設計方法。在任何一種作業系統中,開發人員均可以遵循“COM方法”。 有的元件必須滿足兩個條件:第一,元件必須動態連結;第二,它們必須隱藏(或封裝)其內部實現細節。動態連結對於元件而言是一個至關重要的要求,而訊息隱藏則是動態連結的一個必要條件。對於COM來講,介面是一個包含一個函式指標陣列的記憶體結構。每一個數組元素包含的是一個由元件所實現的函式地址。
1.寫出判斷ABCD四個表示式的是否正確, 若正確, 寫出經過表示式中 a的值(3分)
int a = 4;
(A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++);
a = ?
答:C錯誤,左側不是一個有效變數,不能賦值,可改為(++a) += a;
改後答案依次為9,10,10,11
2.某32位系統下, C++程式,請計算sizeof 的值(5分).
char str[] = “www.ibegroup.com”
char *p = str ;
int n = 10;
請計算
sizeof (str ) = ?(1)
sizeof ( p ) = ?(2)
sizeof ( n ) = ?(3)
void Foo ( char str[100]){
請計算
sizeof( str ) = ?(4)
}
void *p = malloc( 100 );
請計算
sizeof ( p ) = ?(5)
答:(1)17 (2)4 (3) 4 (4)4 (5)4
3. 回答下面的問題. (4分)
(1).標頭檔案中的 ifndef/define/endif 幹什麼用?預處理
答:防止標頭檔案被重複引用
(2). #include 和 #include “filename.h” 有什麼區別?
答:前者用來包含開發環境提供的庫標頭檔案,後者用來包含自己編寫的標頭檔案。
(3).在C++ 程式中呼叫被 C 編譯器編譯後的函式,為什麼要加 extern “C”宣告?
答:函式和變數被C++編譯後在符號庫中的名字與C語言的不同,被extern "C"修飾的變數和函式是按照C語言方式編譯和連線的。由於編譯後的名字不同,C++程式不能直接呼叫C 函式。C++提供了一個C 連線交換指定符號extern“C”來解決這個問題。
(4). switch()中不允許的資料型別是?
答:實型
4. 回答下面的問題(6分)
(1).Void GetMemory(char **p, int num){
*p = (char *)malloc(num);
}
void Test(void){
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}
請問執行Test 函式會有什麼樣的結果?
答:輸出“hello”
(2). void Test(void){
char *str = (char *) malloc(100);
strcpy(str, “hello”);
free(str);
if(str != NULL){
strcpy(str, “world”);
printf(str);
}
}
請問執行Test 函式會有什麼樣的結果?
答:輸出“world”
(3). char *GetMemory(void){
char p[] = "hello world";
return p;
}
void Test(void){
char *str = NULL;
str = GetMemory();
printf(str);
}
請問執行Test 函式會有什麼樣的結果?
答:無效的指標,輸出不確定
5. 編寫strcat函式(6分)
已知strcat函式的原型是char *strcat (char *strDest, const char *strSrc);
其中strDest 是目的字串,strSrc 是源字串。
(1)不呼叫C++/C 的字串庫函式,請編寫函式 strcat
答:
VC原始碼:
char * __cdecl strcat (char * dst, const char * src)
{
char * cp = dst;
while( *cp )
cp++; /* find end of dst */
while( *cp++ = *src++ ) ; /* Copy src to end of dst */
return( dst ); /* return dst */
}
(2)strcat能把strSrc 的內容連線到strDest,為什麼還要char * 型別的返回值?
答:方便賦值給其他變數
6.MFC中CString是型別安全類麼?
答:不是,其它資料型別轉換到CString可以使用CString的成員函式Format來轉換
7.C++中為什麼用模板類。
答:(1)可用來建立動態增長和減小的資料結構
(2)它是型別無關的,因此具有很高的可複用性。
(3)它在編譯時而不是執行時檢查資料型別,保證了型別安全
(4)它是平臺無關的,可移植性
(5)可用於基本資料型別
8.CSingleLock是幹什麼的。
答:同步多個執行緒對一個數據類的同時訪問
9.NEWTEXTMETRIC 是什麼。
答:物理字型結構,用來設定字型的高寬大小
10.程式什麼時候應該使用執行緒,什麼時候單執行緒效率高。
答:1.耗時的操作使用執行緒,提高應用程式響應
2.並行操作時使用執行緒,如C/S架構的伺服器端併發執行緒響應使用者的請求。
3.多CPU系統中,使用執行緒提高CPU利用率
4.改善程式結構。一個既長又複雜的程序可以考慮分為多個執行緒,成為幾個獨立或半獨立的執行部分,這樣的程式會利於理解和修改。
其他情況都使用單執行緒。
11.Windows是核心級執行緒麼。
答:見下一題
12.Linux有核心級執行緒麼。
答:執行緒通常被定義為一個程序中程式碼的不同執行路線。從實現方式上劃分,執行緒有兩種型別:“使用者級執行緒”和“核心級執行緒”。 使用者執行緒指不需要核心支援而在使用者程式中實現的執行緒,其不依賴於作業系統核心,應用程序利用執行緒庫提供建立、同步、排程和管理執行緒的函式來控制使用者執行緒。這種執行緒甚至在象 DOS 這樣的作業系統中也可實現,但執行緒的排程需要使用者程式完成,這有些類似 Windows 3.x 的協作式多工。另外一種則需要核心的參與,由核心完成執行緒的排程。其依賴於作業系統核心,由核心的內部需求進行建立和撤銷,這兩種模型各有其好處和缺點。使用者執行緒不需要額外的核心開支,並且使用者態執行緒的實現方式可以被定製或修改以適應特殊應用的要求,但是當一個執行緒因 I/O 而處於等待狀態時,整個程序就會被排程程式切換為等待狀態,其他執行緒得不到執行的機會;而核心執行緒則沒有各個限制,有利於發揮多處理器的併發優勢,但卻佔用了更多的系統開支。 Windows NT和OS/2支援核心執行緒。Linux 支援核心級的多執行緒
13.C++中什麼資料分配在棧或堆中,New分配資料是在近堆還是遠堆中?
答:棧: 存放區域性變數,函式呼叫引數,函式返回值,函式返回地址。由系統管理
堆: 程式執行時動態申請,new 和 malloc申請的記憶體就在堆上
14.使用執行緒是如何防止出現大的波峰。
答:意思是如何防止同時產生大量的執行緒,方法是使用執行緒池,執行緒池具有可以同時提高排程效率和限制資源使用的好處,執行緒池中的執行緒達到最大數時,其他執行緒就會排隊等候。
15函式模板與類模板有什麼區別?
答:函式模板的例項化是由編譯程式在處理函式呼叫時自動完成的,而類模板的例項化必須由程式設計師在程式中顯式地指定。
16一般資料庫若出現日誌滿了,會出現什麼情況,是否還能使用?
答:只能執行查詢等讀操作,不能執行更改,備份等寫操作,原因是任何寫操作都要記錄日誌。也就是說基本上處於不能使用的狀態。
17 SQL Server是否支援行級鎖,有什麼好處?
答:支援,設立封鎖機制主要是為了對併發操作進行控制,對干擾進行封鎖,保證資料的一致性和準確性,行級封鎖確保在使用者取得被更新的行到該行進行更新這段時間內不被其它使用者所修改。因而行級鎖即可保證資料的一致性又能提高資料操作的併發性。
18如果資料庫滿了會出現什麼情況,是否還能使用?
答:見16
19 關於記憶體對齊的問題以及sizeof()的輸出
答:編譯器自動對齊的原因:為了提高程式的效能,資料結構(尤其是棧)應該儘可能地在自然邊界上對齊。原因在於,為了訪問未對齊的記憶體,處理器需要作兩次記憶體訪問;然而,對齊的記憶體訪問僅需要一次訪問。
20 int i=10, j=10, k=3; k*=i+j; k最後的值是?
答:60,此題考察優先順序,實際寫成: k*=(i+j);,賦值運算子優先順序最低
21.對資料庫的一張表進行操作,同時要對另一張表進行操作,如何實現?
答:將操作多個表的操作放入到事務中進行處理
22.TCP/IP 建立連線的過程?(3-way shake)
答:在TCP/IP協議中,TCP協議提供可靠的連線服務,採用三次握手建立一個連線。第一次握手:建立連線時,客戶端傳送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。
23.ICMP是什麼協議,處於哪一層?
答:Internet控制報文協議,處於網路層(IP層)
24.觸發器怎麼工作的?
答:觸發器主要是通過事件進行觸發而被執行的,當對某一表進行諸如UPDATE、 INSERT、 DELETE 這些操作時,資料庫就會自動執行觸發器所定義的SQL 語句,從而確保對資料的處理必須符合由這些SQL 語句所定義的規則。
25.winsock建立連線的主要實現步驟?
答:伺服器端:socket()建立套接字,繫結(bind)並監聽(listen),用accept()等待客戶端連線。
客戶端:socket()建立套接字,連線(connect)伺服器,連線上後使用send()和recv(),在套接字上寫讀資料,直至資料交換完畢,closesocket()關閉套接字。
伺服器端:accept()發現有客戶端連線,建立一個新的套接字,自身重新開始等待連線。該新產生的套接字使用send()和recv()寫讀資料,直至資料交換完畢,closesocket()關閉套接字。
26.動態連線庫的兩種方式?
答:呼叫一個DLL中的函式有兩種方法:
1.載入時動態連結(load-time dynamic linking),模組非常明確呼叫某個匯出函式,使得他們就像本地函式一樣。這需要連結時連結那些函式所在DLL的匯入庫,匯入庫向系統提供了載入DLL時所需的資訊及DLL函式定位。
2.執行時動態連結(run-time dynamic linking),執行時可以通過LoadLibrary或LoadLibraryEx函式載入DLL。DLL載入後,模組可以通過呼叫GetProcAddress獲取DLL函式的出口地址,然後就可以通過返回的函式指標呼叫DLL函數了。如此即可避免匯入庫檔案了
27.IP組播有那些好處?
答:Internet上產生的許多新的應用,特別是高頻寬的多媒體應用,帶來了頻寬的急劇消耗和網路擁擠問題。組播是一種允許一個或多個傳送者(組播源)傳送單一的資料包到多個接收者(一次的,同時的)的網路技術。組播可以大大的節省網路頻寬,因為無論有多少個目標地址,在整個網路的任何一條鏈路上只傳送單一的資料包。所以說組播技術的核心就是針對如何節約網路資源的前提下保證服務質量。
託管程式碼
使用基於公共語言執行庫的語言編譯器開發的程式碼稱為託管程式碼;託管程式碼具有許多優點,例如:跨語言整合、跨語言異常處理、增強的安全性、版本控制和部署支援、簡化的元件互動模型、除錯和分析服務等。
過載
每個型別成員都有一個唯一的簽名。方法簽名由方法名稱和一個引數列表(方法的引數的順序和型別)組成。只要簽名不同,就可以在一種型別內定義具有相同名稱的多種方法。當定義兩種或多種具有相同名稱的方法時,就稱作過載。
16道C語言面試題例子
前處理器(Preprocessor)1. 用預處理指令#define 宣告一個常數,用以表明1年中有多少秒(忽略閏年問題)#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL我在這想看到幾件事情: 1). #define 語法的基本知識(例如:不能以分號結束,括號的使用,等等)2). 懂得前處理器將為你計算常數表示式的值,因此,直接寫出你是如何計算一年中有多少秒而不是計算出實際的值,是更清晰而沒有代價的。3). 意識到這個表示式將使一個16位機的整型數溢位-因此要用到長整型符號L,告訴編譯器這個常數是的長整型數。4). 如果你在你的表示式中用到UL(表示無符號長整型),那麼你有了一個好的起點。記住,第一印象很重要。
2. 寫一個“標準”巨集MIN,這個巨集輸入兩個引數並返回較小的一個。#define MIN(A,B) ((A) <= (B)?(A) : (B))這個測試是為下面的目的而設的: 1). 標識#define在巨集中應用的基本知識。這是很重要的,因為直到嵌入(inline)操作符變為標準C的一部分,巨集是方便產生嵌入程式碼的唯一方法,對於嵌入式系統來說,為了能達到要求的效能,嵌入程式碼經常是必須的方法。2). 三重條件操作符的知識。這個操作符存在C語言中的原因是它使得編譯器能產生比if-then-else更優化的程式碼,瞭解這個用法是很重要的。3). 懂得在巨集中小心地把引數用括號括起來4). 我也用這個問題開始討論巨集的副作用,例如:當你寫下面的程式碼時會發生什麼事?least = MIN(*p++, b);
3. 前處理器標識#error的目的是什麼?如果你不知道答案,請看參考文獻1。這問題對區分一個正常的夥計和一個書呆子是很有用的。只有書呆子才會讀C語言課本的附錄去找出象這種問題的答案。當然如果你不是在找一個書呆子,那麼應試者最好希望自己不要知道答案。#error 停止編譯並顯示錯誤資訊死迴圈(Infinite loops)4. 嵌入式系統中經常要用到無限迴圈,你怎麼樣用C編寫死迴圈呢?這個問題用幾個解決方案。我首選的方案是: while(1) { } 一些程式設計師更喜歡如下方案: for(;;) { } 這個實現方式讓我為難,因為這個語法沒有確切表達到底怎麼回事。如果一個應試者給出這個作為方案,我將用這個作為一個機會去探究他們這樣做的基本原理。如果他們的基本答案是:“我被教著這樣做,但從沒有想到過為什麼。”這會給我留下一個壞印象。第三個方案是用 gotoLoop: ... goto Loop; 應試者如給出上面的方案,這說明或者他是一個組合語言程式設計師(這也許是好事)或者他是一個想進入新領域的BASIC/FORTRAN程式設計師。
資料宣告(Data declarations)5. 用變數a給出下面的定義a) 一個整型數(An integer)b) 一個指向整型數的指標(A pointer to an integer)c) 一個指向指標的的指標,它指向的指標是指向一個整型數(A pointer to a pointer to an integer)d) 一個有10個整型數的陣列(An array of 10 integers)e) 一個有10個指標的陣列,該指標是指向一個整型數的(An array of 10 pointers to integers)f) 一個指向有10個整型數陣列的指標(A pointer to an array of 10 integers)g) 一個指向函式的指標,該函式有一個整型引數並返回一個整型數(A pointer to a function that takes an integer as an argument and returns an integer)h) 一個有10個指標的陣列,該指標指向一個函式,該函式有一個整型引數並返回一個整型數( An array of ten pointers to functions that take an integer argument and return an integer )答案是: a) int a; // An integer b) int *a; // A pointer to an integer c) int **a; // A pointer to a pointer to an integer d) int a[10]; // An array of 10 integers e) int *a[10]; // An array of 10 pointers to integers f) int (*a)[10]; // A pointer to an array of 10 integers g) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integerh) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer
人們經常聲稱這裡有幾個問題是那種要翻一下書才能回答的問題,我同意這種說法。當我寫這篇文章時,為了確定語法的正確性,我的確查了一下書。 但是當我被面試的時候,我期望被問到這個問題(或者相近的問題)。因為在被面試的這段時間裡,我確定我知道這個問題的答案。應試者如果不知道 所有的答案(或至少大部分答案),那麼也就沒有為這次面試做準備,如果該面試者沒有為這次面試做準備,那麼他又能為什麼出準備呢?
Static6. 關鍵字static的作用是什麼?這個簡單的問題很少有人能回答完全。在C語言中,關鍵字static有三個明顯的作用:1). 在函式體,一個被宣告為靜態的變數在這一函式被呼叫過程中維持其值不變。2). 在模組內(但在函式體外),一個被宣告為靜態的變數可以被模組內所用函式訪問,但不能被模組外其它函式訪問。它是一個本地的全域性變數。3). 在模組內,一個被宣告為靜態的函式只可被這一模組內的其它函式呼叫。那就是,這個函式被限制在宣告它的模組的本地範圍內使用。大多數應試者能正確回答第一部分,一部分能正確回答第二部分,同是很少的人能懂得第三部分。這是一個應試者的嚴重的缺點,因為他顯然不懂得本地化資料和程式碼範圍的好處和重要性。
Const 7.關鍵字const是什麼含意? 我只要一聽到被面試者說:“const意味著常數”,我就知道我正在和一個業餘者打交道。去年Dan Saks已經在他的文章裡完全概括了const的所有用法,因此ESP(譯者:Embedded Systems Programming)的每一位讀者應該非常熟悉const能做什麼和不能做什麼.如果你從沒有讀到那篇文章,只要能說出const意味著“只讀”就可以了。儘管這個答案不是完全的答案,但我接受它作為一個正確的答案。(如果你想知道更詳細的答案,仔細讀一下Saks的文章吧。)如果應試者能正確回答這個問題,我將問他一個附加的問題:下面的宣告都是什麼意思?const int a; //a是一個常整型數int const a; //a是一個常整型數const int *a; //一個指向常整型數的指標,整型數是不可修改的,但指標可以int * const a; //一個指向整型數的常指標,指標指向的整型數是可以修改的,指標不可修改int const * a const;// 一個指向常整型數的常指標,整型數不可修改,指標也是不可修改的
(主要看const靠近*還是int,不可修改的就是它)前兩個的作用是一樣,a是一個常整型數。第三個意味著a是一個指向常整型數的指標(也就是,整型數是不可修改的,但指標可以)。第四個意思a是一個指向整型數的常指標(也就是說,指標指向的整型數是可以修改的,但指標是不可修改的)。最後一個意味著a是一個指向常整型數的常指標(也就是說,指標指向的整型數是不可修改的,同時指標也是不可修改的)。如果應試者能正確回答這些問題,那麼他就給我留下了一個好印象。順帶提一句,也許你可能會問,即使不用關鍵字const,也還是能很容易寫出功能正確的程式,那麼我為什麼還要如此看重關鍵字const呢?我也如下的幾下理由:1). 關鍵字const的作用是為給讀你程式碼的人傳達非常有用的資訊,實際上,宣告一個引數為常量是為了告訴了使用者這個引數的應用目的。如果你曾花很多時間清理其它人留下的垃圾,你就會很快學會感謝這點多餘的資訊。(當然,懂得用const的程式設計師很少會留下的垃圾讓別人來清理的。)2). 通過給優化器一些附加的資訊,使用關鍵字const也許能產生更緊湊的程式碼。3). 合理地使用關鍵字const可以使編譯器很自然地保護那些不希望被改變的引數,防止其被無意的程式碼修改。簡而言之,這樣可以減少bug的出現。Volatile
8. 關鍵字volatile有什麼含意 並給出三個不同的例子。一個定義為volatile的變數是說這變數可能會被意想不到地改變,這樣,編譯器就不會去假設這個變數的值了。精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。下面是volatile變數的幾個例子:1). 並行裝置的硬體暫存器(如:狀態暫存器)2). 一箇中斷服務子程式中會訪問到的非自動變數(Non-automatic variables)3). 多執行緒應用中被幾個任務共享的變數 回答不出這個問題的人是不會被僱傭的。我認為這是區分C程式設計師和嵌入式系統程式設計師的最基本的問題。嵌入式系統程式設計師經常同硬體、中斷、RTOS等等打交道,所用這些都要求volatile變數。不懂得volatile內容將會帶來災難。假設被面試者正確地回答了這是問題(嗯,懷疑這否會是這樣),我將稍微深究一下,看一下這傢伙是不是直正懂得volatile完全的重要性。1). 一個引數既可以是const還可以是volatile嗎?解釋為什麼。2). 一個指標可以是volatile 嗎?解釋為什麼。3). 下面的函式有什麼錯誤:int square(volatile int *ptr) { return *ptr * *ptr; } 下面是答案: 1). 是的。一個例子是隻讀的狀態暫存器。它是volatile因為它可能被意想不到地改變。它是const因為程式不應該試圖去修改它。2). 是的。儘管這並不很常見。一個例子是當一箇中服務子程式修該一個指向一個buffer的指標時。3). 這段程式碼的有個惡作劇。這段程式碼的目的是用來返指標*ptr指向值的平方,但是,由於*ptr指向一個volatile型引數,編譯器將產生類似下面的程式碼:int square(volatile int *ptr) { int a,b; a = *ptr; b = *ptr; return a * b; } 由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段程式碼可能返不是你所期望的平方值!正確的程式碼如下:long square(volatile int *ptr){ int a; a = *ptr; return a * a; }位操作(Bit manipulation)9. 嵌入式系統總是要使用者對變數或暫存器進行位操作。給定一個整型變數a,寫兩段程式碼,第一個設定a的bit 3,第二個清除a 的bit 3。在以上兩個操作中,要保持其它位不變。對這個問題有三種基本的反應 1). 不知道如何下手。該被面者從沒做過任何嵌入式系統的工作。2). 用bit fields。Bit fields是被扔到C語言死角的東西,它保證你的程式碼在不同編譯器之間是不可移植的,同時也保證了的你的程式碼是不可重用的。我最近不幸看到Infineon為其較複雜的通訊晶片寫的驅動程式,它用到了bit fields因此完全對我無用,因為我的編譯器用其它的方式來實現bit fields的。從道德講:永遠不要讓一個非嵌入式的傢伙粘實際硬體的邊。3). 用 #defines 和 bit masks 操作。這是一個有極高可移植性的方法,是應該被用到的方法。最佳的解決方案如下:#define BIT3 (0x1<<3) static int a; void set_bit3(void) { a |= BIT3; } void clear_bit3(void) { a &= ~BIT3; } 一些人喜歡為設定和清除值而定義一個掩碼同時定義一些說明常數,這也是可以接受的。我希望看到幾個要點:說明常數、|=和&=~操作。
訪問固定的記憶體位置(Accessing fixed memory locations)10. 嵌入式系統經常具有要求程式設計師去訪問某特定的記憶體位置的特點。在某工程中,要求設定一絕對地址為0x67a9的整型變數的值為0xaa66。編譯器是一個純粹的ANSI編譯器。寫程式碼去完成這一任務。這一問題測試你是否知道為了訪問一絕對地址把一個整型數強制轉換(typecast)為一指標是合法的。這一問題的實現方式隨著個人風格不同而不同。典型的類似程式碼如下:int *ptr; ptr = (int *)0x67a9; *ptr = 0xaa55;一個較晦澀的方法是: *(int * const)(0x67a9) = 0xaa55;即使你的品味更接近第二種方案,但我建議你在面試時使用第一種方案。中斷(Interrupts) 11. 中斷是嵌入式系統中重要的組成部分,這導致了很多編譯開發商提供一種擴充套件—讓標準C支援中斷。具代表事實是,產生了一個新的關鍵字__interrupt。下面的程式碼就使用了__interrupt關鍵字去定義了一箇中斷服務子程式(ISR),請評論一下這段程式碼的。__interrupt double compute_area (double radius){ double area = PI * radius * radius; printf(" Area = %f", area); return area; }這個函式有太多的錯誤了,以至讓人不知從何說起了: 1). ISR 不能返回一個值。如果你不懂這個,那麼你不會被僱用的。2). ISR 不能傳遞引數。如果你沒有看到這一點,你被僱用的機會等同第一項。3). 在許多的處理器/編譯器中,浮點一般都是不可重入的。有些處理器/編譯器需要讓額處的暫存器入棧,有些處理器/編譯器就是不允許在ISR中做浮點運算。此外,ISR應該是短而有效率的,在ISR中做浮點運算是不明智的。4). 與第三點一脈相承,printf()經常有重入和效能上的問題。如果你丟掉了第三和第四點,我不會太為難你的。不用說,如果你能得到後兩點,那麼你的被僱用前景越來越光明瞭。程式碼例子(Code examples)12 . 下面的程式碼輸出是什麼,為什麼?void foo(void) { unsigned int a = 6; int b = -20; (a+b > 6) puts("> 6") : puts("<= 6"); }這個問題測試你是否懂得C語言中的整數自動轉換原則,我發現有些開發者懂得極少這些東西。不管如何,這無符號整型問題的答案是輸出是“>6”。原因是當表示式中存在有符號型別和無符號型別時所有的運算元都自動轉換為無符號型別。 因此-20變成了一個非常大的正整數,所以該表示式計算出的結果大於6。這一點對於應當頻繁用到無符號資料型別的嵌入式系統來說是豐常重要的。如果你答錯了這個問題,你也就到了得不到這份工作的邊緣。13. 評價下面的程式碼片斷:unsigned int zero = 0;unsigned int compzero = 0xFFFF; /*1's complement of zero */對於一個int型不是16位的處理器為說,上面的程式碼是不正確的。應編寫如下:unsigned int compzero = ~0;這一問題真正能揭露出應試者是否懂得處理器字長的重要性。在我的經驗裡,好的嵌入式程式設計師非常準確地明白硬體的細節和它的侷限,然而PC機程式往往把硬體作為一個無法避免的煩惱。到了這個階段,應試者或者完全垂頭喪氣了或者信心滿滿志在必得。如果顯然應試者不是很好,那麼這個測試就在這裡結束了。但如果顯然應試者做得不錯,那麼我就扔出下面的追加問題,這些問題是比較難的,我想僅僅非常優秀的應試者能做得不錯。提出這些問題,我希望更多看到應試者應付問題的方法,而不是答案。不管如何,你就當是這個娛樂吧…
動態記憶體分配(Dynamic memory allocation)14. 儘管不像非嵌入式計算機那麼常見,嵌入式系統還是有從堆(heap)中動態分配記憶體的過程的。那麼嵌入式系統中,動態分配記憶體可能發生的問題是什麼?這裡,我期望應試者能提到記憶體碎片,碎片收集的問題,變數的持行時間等等。這個主題已經在ESP雜誌中被廣泛地討論過了(主要是 P.J. Plauger, 他的解釋遠遠超過我這裡能提到的任何解釋),所有回過頭看一下這些雜誌吧!讓應試者進入一種虛假的安全感覺後,我拿出這麼一個小節目:下面的程式碼片段的輸出是什麼,為什麼?char *ptr; if ((ptr = (char *)malloc(0)) == NULL) puts("Got a null pointer"); else puts("Got a valid pointer"); 這是一個有趣的問題。最近在我的一個同事不經意把0值傳給了函式malloc,得到了一個合法的指標之後,我才想到這個問題。這就是上面的程式碼,該程式碼的輸出是“Got a valid pointer”。我用這個來開始討論這樣的一問題,看看被面試者是否想到庫例程這樣做是正確。得到正確的答案固然重要,但解決問題的方法和你做決定的基本原理更重要些。Typedef 15. Typedef 在C語言中頻繁用以宣告一個已經存在的資料型別的同義字。也可以用前處理器做類似的事。例如,思考一下下面的例子:#define dPS struct s * typedef struct s * tPS; 以上兩種情況的意圖都是要定義dPS 和 tPS 作為一個指向結構s指標。哪種方法更好呢?(如果有的話)為什麼?這是一個非常微妙的問題,任何人答對這個問題(正當的原因)是應當被恭喜的。答案是:typedef更好。思考下面的例子:dPS p1,p2; tPS p3,p4;第一個擴充套件為 struct s * p1, p2;上面的程式碼定義p1為一個指向結構的指,p2為一個實際的結構,這也許不是你想要的。第二個例子正確地定義了p3 和p4 兩個指標。晦澀的語法16. C語言同意一些令人震驚的結構,下面的結構是合法的嗎,如果是它做些什麼?int a = 5, b = 7, c; c = a+++b;這個問題將做為這個測驗的一個愉快的結尾。不管你相不相信,上面的例子是完全合乎語法的。問題是編譯器如何處理它?水平不高的編譯作者實際上會爭論這個問題,根據最處理原則,編譯器應當能處理儘可能所有合法的用法。因此,上面的程式碼被處理成:c = a++ + b; 因此, 這段程式碼持行後a = 6, b = 7, c = 12。如果你知道答案,或猜出正確答案,做得好。如果你不知道答案,我也不把這個當作問題。我發現這個問題的最大好處是:這是一個關於程式碼編寫風格,程式碼的可讀性,程式碼的可修改性的好的話題
群碩筆試:
基本概念,涉及到C++、Java、軟體測試、EJB、ASP和ASP.NET的知識。
今天群碩筆試,考了好多內容,其中Java佔很大部分!
本試卷中最有難度的程式設計題:給定一個數組,這個陣列中既有正數又有負數,找出這個陣列中的子陣列,此子陣列的和最大!
#include<stdio.h>void main(){int a[15]={2,3,-4,5,6,-5,-1,14,9,-10,1,-71,75,4,-9};int b[15]; //計算和int num=a[14];int c[15]; //最大尾數標誌陣列int n=14;int i,j=0;for(i=14;i>=0;i--) //從後計算和放入b中{ c[i]=n;b[i]=num;if(num<0){n=i-1;num=0;}num=num+a[i-1];}printf("/n");for(i=0;i<15;i++)printf("%d, ",b[i]);printf("/n");//找到最大字元子串num=b[0];n=c[0];for(i=0;i<15;i++)if(b[i]>num){num=b[i];j=i;n=c[i];}for(i=j;i<=n;i++)printf("%d, ",a[i]);printf("sum=%d",num);}
最不知道怎麼答的題:在TCP/IP中最經常使用的程式設計方法?
最簡單的題:final, finally, finalize的區別(因為經常考)
final—修飾符(關鍵字)如果一個類被宣告為final,意味著它不能再派生出新的子類,不能作為父類被繼承。因此一個類不能既被宣告為 abstract的,又被宣告為final的。將變數或方法宣告為final,可以保證它們在使用中不被改變。被宣告為final的變數必須在宣告時給定初值,而在以後的引用中只能讀取,不可修改。被宣告為final的方法也同樣只能使用,不能過載。
finally—再異常處理時提供 finally 塊來執行任何清除操作。如果丟擲一個異常,那麼相匹配的 catch 子句就會執行,然後控制就會進入 finally 塊(如果有的話)。
finalize—方法名。Java 技術允許使用 finalize() 方法在垃圾收集器將物件從記憶體中清除出去之前做必要的清理工作。這個方法是由垃圾收集器在確定這個物件沒有被引用時對這個物件呼叫的。它是在 Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或者執行其他清理工作。finalize() 方法是在垃圾收集器刪除物件之前對這個物件呼叫的。
最容易疏忽的題:main(){C c;}在前面已經定義了C的類,這個地方容易迷糊的就是,沒有new,照樣執行建構函式,沒有free,照樣執行解構函式。
最迷糊的題:一個無向圖是否能夠存到樹中?為什麼?
最然我感到有差距的題:EJB中一定包括()interface,()interface,()class
不用任何變數交換a,b兩個變數
用遞迴求最大公約數
舉一個多型的例子二叉平衡樹(特性,內插入和 外 插入)UNIX程序包括那三個部分:...(簡單)new動態分配失敗會丟擲什麼異常,C++中提供了那兩個標準函式來設定異常處理HANLDER(有點難度)EJB包含那幾種?區別(壓根沒聽過)asp和asp.net的區別(假期做專案的時候碰到過,嘿嘿)JAVA中的interface 和 abstract class區別(照著c裡面的感念隨便寫了點)logic thinking:檢測電冰箱(我用軟體工程的思想隨便寫寫)
1.內連線與外連線的區別。3.內聯的定義,什麼情況下選擇內聯。4.什麼是多型,用一段程式碼說明。5.不經過第三者變數來交換兩個整型數。6.EJB都有那些Beans.7.什麼是平衡二叉樹。8.當new出錯後怎麼處理。9.asp與asp.net的最大區別。10.如何證明一個電冰箱是否是好的
1-1000放在含有1001個元素的陣列中,只有唯