1. c++中指針的優(yōu)缺點有哪些 答案:優(yōu)點: (1)提高程序的編譯效率和執(zhí)行速度,。 (2)通過指針可使用主調函數和被調函數之間共享變量或數據結構,,便于實現(xiàn)雙向數據通訊。 (3)可以實現(xiàn)動態(tài)的存儲分配,。 (4)便于表示各種數據結構,,編寫高質量的程序。 缺點: (1)使用未正確初始化的指針導致程序崩潰 (2)引用已釋放的指針 (3)通過指針訪問不該訪問的內存 2. 宏和函數的區(qū)別 答案:(1)宏做的是簡單的字符串替換(注意是字符串的替換,,不是其他類型參數的替換),,而函數的參數的傳遞,參數是有數據類型的,,可以是各種各樣的類型,。 (2)宏的參數替換是不經計算而直接處理的,而函數調用是將實參的值傳遞給形參,,是計算得來的,。 (3)宏在編譯之前進行,即先用宏體替換宏名,,然后再編譯的,,而函數是編譯之后,在執(zhí)行時,,才調用的,。因此,宏占用的是編譯的時間,,而函數占用的是執(zhí)行時的時間,。 (4)宏的參數是不占內存空間的,因為只是做字符串的替換,,而函數調用時的參數傳遞則是具體變量之間的信息傳遞,,形參作為函數的局部變量,是占用內存的,。 (5)函數的調用是需要付出一定的時空開銷的,,因為系統(tǒng)在調用函數時,要保留現(xiàn)場,,然后轉入被調用函數去執(zhí)行,,調用完,再返回主調函數,,此時再恢復現(xiàn)場,,這些操作,顯然在宏中是沒有的,。 3. 宏定義是什么時期處理的(預處理?編譯期?) 答案:預處理 4. 不同情況下類對象的大小(有數據成員,,無數據成員,,有虛函數等) 答案:(1)無任何數據成員和虛函數的類大小為1 (2)每個虛函數大小為4 (3)成員變量大小要考慮內存對齊,通常是4字節(jié)對齊 5. STL中vector使用的時候要注意什么 答案:(1) 如果元素是對象的指針,,當該vector超出其作用域或調用erase刪除元素時,,那么元素本身在該vector中會被刪除,但對象本身并沒有得到銷毀,。在這種情況下,,銷毀的工作要由程序員自己來做。 (2) 用erase刪除vector容器中的元素對象時,,元素對象的析構函數會被多次調用,。 6. 字符轉整型數的函數是什么? 是怎樣實現(xiàn)的? 答案: strtol、strtoul,。 #define TOLOWER(x) ((x) | 0×20) #define isxdigit(c) ((’0′ <= (c) && (c) <= ’9′) \ || (‘a’ <= (c) && (c) <= ‘f’) \ || (‘A’ <= (c) && (c) <= ‘F’)) #define isdigit(c) (’0′ <= (c) && (c) <= ’9′) unsigned long strtoul(const char *cp,char **endp,unsigned int base) { unsigned long result = 0,value; if (!base) { base = 10; if (*cp == ’0′) { base = 8; cp++; if ((TOLOWER(*cp) == ‘x’) && isxdigit(cp[1])) { cp++; base = 16; } } } else if (base == 16) { if (cp[0] == ’0′ && TOLOWER(cp[1]) == ‘x’) cp += 2; } while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-’0′ : TOLOWER(*cp)-’a'+10) < base) { result = result*base + value; cp++; } if (endp) *endp = (char *)cp; return result; } long strtol(const char *cp,char **endp,unsigned int base) { if(*cp==’-') return -strtoul(cp+1,endp,base); return strtoul(cp,endp,base); } INT32S atoi(const INT8S *nptr)// { return strtol(nptr, ( INT8S **)NULL, 10); } 7. 虛擬類和最終類能否派生出對象 答案:虛擬類可以派生對象 8. 你怎么理解虛擬類?虛擬類可以實例化一個對象嗎?為什么?它的作用和其他類的區(qū)別 答案:虛擬類可以派生對象,,純虛類不可以實例化對象。因為純虛類存在未定義的函數,,只是個概念,,不可真實存在。虛擬類用做多態(tài),,純虛類做接口,。 9. 內聯(lián)函數怎么實現(xiàn)的,什么時期處理的,,優(yōu)缺點 答案:在程序編譯時,,編譯器將程序中出現(xiàn)的內聯(lián)函數的調用表達式用內聯(lián)函數的函數體來進行替換。 優(yōu)點:不會產生函數調用的開銷 缺點:增加目標程序的代碼量,,即增加空間開銷 10. 內存分配的幾種方法與特點 答案:棧:就是那些由編譯器在需要的時候分配,,在不需要的時候自動清除的變量的存儲區(qū)。里面的變量通常是局部變量,、函數參數等,。 堆:就是那些由new分配的內存塊, 自由存儲區(qū):就是那些由malloc等分配的內存塊 全局/靜態(tài)存儲區(qū):全局變量和靜態(tài)變量被分配到同一塊內存中 常量存儲區(qū):這是一塊比較特殊的存儲區(qū),,他們里面存放的是常量,,不允許修改 11. 靜態(tài)變量、全局變量,、局部變量分別存儲于什么位置 答案:靜態(tài)變量:全局/靜態(tài)存儲區(qū) 全局變量:全局/靜態(tài)存儲區(qū) 局部變量:棧 12. static全局變量與普通全局變量的區(qū)別?static局部變量與普通變量的區(qū)別?static函數與普通函數的區(qū)別 答案: static全局變量與普通的全局變量有什么區(qū)別:static全局變量只初使化一次,并且在其他文件單元中不可被引用 static局部變量和普通局部變量有什么區(qū)別:static局部變量只被初始化一次,,值在程序生存期有效 static函數與普通函數有什么區(qū)別:static函數在內存中只有一份,,普通函數在每個被調用中維持一份拷貝 13. 虛函數的機制,怎么理解,。與其它函數的區(qū)別,,如重載 答案:虛函數在c++中的實現(xiàn)機制就是用虛表和虛指針 普通函數編譯時綁定,,虛函數運行時綁定 14. 寫一個復制字符串的方法,要求只能使用基本類型,,用char數組表示字符串 答案: char * strcpy(char * strDest,const char * strSrc) { if ((strDest==NULL)||(strsrc=”/=NULL”)) //[1] throw “Invalid argument(s)”; //[2] char * strDestCopy=strDest; //[3] while ((*strDest++=*strSrc++)!=’\0′); //[4] return strDestCopy; } [1] (A)不檢查指針的有效性,,說明答題者不注重代碼的健壯性。 (B)檢查指針的有效性時使用((!strDest)||(!strSrc))或(!(strDest&&strSrc)),,說明答題者對C語言中類型的隱式轉換沒有深刻認識,。在本例中char *轉換為bool即是類型隱式轉換,這種功能雖然靈活,,但更多的是導致出錯概率增大和維護成本升高,。所以C++專門增加了bool、true,、false三個關鍵字以提供更安全的條件表達式,。 (C)檢查指針的有效性時使用((strDest==0)||(strsrc=”/=0″)),說明答題者不知道使用常量的好處,。直接使用字面常量(如本例中的0)會減少程序的可維護性,。0雖然簡單,但程序中可能出現(xiàn)很多處對指針的檢查,,萬一出現(xiàn)筆誤,,編譯器不能發(fā)現(xiàn),生成的程序內含邏輯錯誤,,很難排除,。而使用NULL代替0,如果出現(xiàn)拼寫錯誤,,編譯器就會檢查出來,。 [2] (A)return new string(“Invalid argument(s)”);,說明答題者根本不知道返回值的用途,,并且他對內存泄漏也沒有警惕心,。從函數中返回函數體內分配的內存是十分危險的做法,他把釋放內存的義務拋給不知情的調用者,,絕大多數情況下,,調用者不會釋放內存,這導致內存泄漏,。 (B)return 0;,,說明答題者沒有掌握異常機制。調用者有可能忘記檢查返回值,,調用者還可能無法檢查返回值(見后面的鏈式表達式),。妄想讓返回值肩負返回正確值和異常值的雙重功能,其結果往往是兩種功能都失效,。應該以拋出異常來代替返回值,,這樣可以減輕調用者的負擔,、使錯誤不會被忽略、增強程序的可維護性,。 [3] (A)忘記保存原始的strDest值,,說明答題者邏輯思維不嚴密。 [4] (A)循環(huán)寫成while (*strDest++=*strSrc++);,,同[1](B),。 (B)循環(huán)寫成while (*strSrc!=’\0′) *strDest++=*strSrc++;,說明答題者對邊界條件的檢查不力,。循環(huán)體結束后,,strDest字符串的末尾沒有正確地加上’\0′。 2.返回strDest的原始值使函數能夠支持鏈式表達式,,增加了函數的“附加值”,。同樣功能的函數,如果能合理地提高的可用性,,自然就更加理想,。 鏈式表達式的形式如: int iLength=strlen(strcpy(strA,strB)); 又如: char * strA=strcpy(new char[10],strB); 返回strSrc的原始值是錯誤的。其一,,源字符串肯定是已知的,,返回它沒有意義。其二,,不能支持形如第二例的表達式,。其三,為了保護源字符串,,形參用const限定strSrc所指的內容,,把const char *作為char *返回,類型不符,,編譯報錯,。 15. 局部變量能否和全局變量重名 答案:能,局部會屏蔽全局,。要用全局變量,,需要使用”::” 局部變量可以與全局變量同名,在函數內引用這個變量時,,會用到同名的局部變量,,而不會用到全局變量。對于有些編譯器而言,,在同一個函數內可以定義多個同名的局部變量,,比如在兩個循環(huán)體內都定義一個同名的局部變量,而那個局部變量的作用域就在那個循環(huán)體內。 16. 如何引用一個已經定義過的全局變量 答案:extern 可以用引用頭文件的方式,,也可以用extern關鍵字,如果用引用頭文件方式來引用某個在頭文件中聲明的全局變理,,假定你將那個變寫錯了,,那么在編譯期間會報錯,如果你用extern方式引用時,,假定你犯了同樣的錯誤,,那么在編譯期間不會報錯,而在連接期間報錯,。 17. 全局變量可不可以定義在可被多個.C文件包含的頭文件中 為什么 答案:可以,,在不同的C文件中以static形式來聲明同名全局變量。 可以在不同的C文件中聲明同名的全局變量,,前提是其中只能有一個C文件中對此變量賦初值,,此時連接不會出錯 18. 語句for( ;1 ;)有什么問題 它是什么意思 答案:和while(1)相同。 19. do……while和while……do有什么區(qū)別 答案:前一個循環(huán)一遍再判斷,,后一個判斷以后再循環(huán) 20. static全局變量與普通的全局變量有什么區(qū)別 static局部變量和普通局部變量有什么區(qū)別 static函數與普通函數有什么區(qū)別 答案:全局變量(外部變量)的說明之前再冠以static 就構成了靜態(tài)的全局變量,。全局變量本身就是靜態(tài)存儲方式, 靜態(tài)全局變量當然也是靜態(tài)存儲方式,。 這兩者在存儲方式上并無不同,。這兩者的區(qū)別雖在于非靜態(tài)全局變量的作用域是整個源程序, 當一個源程序由多個源文件組成時,,非靜態(tài)的全局變量在各個源文件中都是有效的,。 而靜態(tài)全局變量則限制了其作用域, 即只在定義該變量的源文件內有效,, 在同一源程序的其它源文件中不能 IT人才網(it.ad0.cn) 使用它,。由于靜態(tài)全局變量的作用域局限于一個源文件內,只能為該源文件內的函數公用,, 因此可以避免在其它源文件中引起錯誤,。 從以上分析可以看出, 把局部變量改變?yōu)殪o態(tài)變量后是改變了它的存儲方式即改變了它的生存期,。把全局變量改變?yōu)殪o態(tài)變量后是改變了它的作用域,, 限制了它的使用范圍。 static函數與普通函數作用域不同,。僅在本文件,。只在當前源文件中使用的函數應該說明為內部函數(static),內部函數應該在當前源文件中說明和定義,。對于可在當前源文件以外使用的函數,,應該在一個頭文件中說明,要使用這些函數的源文件要包含這個頭文件 static全局變量與普通的全局變量有什么區(qū)別:static全局變量只初使化一次,防止在其他文件單元中被引用; static局部變量和普通局部變量有什么區(qū)別:static局部變量只被初始化一次,,下一次依據上一次結果值; static函數與普通函數有什么區(qū)別:static函數在內存中只有一份,,普通函數在每個被調用中維持一份拷貝 21. 隊列和棧有什么區(qū)別 答案:隊列先進先出,棧后進先出 22. 頭文件中的 ifndef/define/endif 干什么用?預處理 答案:防止頭文件被重復引用 23. #i nclude 和 #i nclude “filename.h”有什么區(qū)別? 答案:前者用來包含開發(fā)環(huán)境提供的庫頭文件,,后者用來包含自己編寫的頭文件,。 24. 在C++ 程序中調用被 C 編譯器編譯后的函數,為什么要加 extern “C”聲明? 答案:函數和變量被C++編譯后在符號庫中的名字與C語言的不同,,被extern “C”修飾的變 量和函數是按照C語言方式編譯和連接的,。由于編譯后的名字不同,C++程序不能直接調 用C 函數,。C++提供了一個C 連接交換指定符號extern“C”來解決這個問題,。 25. switch()中不允許的數據類型是? 答案:實型 26. C++中為什么用模板類。 答案:(1)可用來創(chuàng)建動態(tài)增長和減小的數據結構 (2)它是類型無關的,,因此具有很高的可復用性,。 (3)它在編譯時而不是運行時檢查數據類型,保證了類型安全 (4)它是平臺無關的,,可移植性 (5)可用于基本數據類型 27. C++中什么數據分配在?;蚨阎校琋ew分配數據是在近堆還是遠堆中? 答案:棧: 存放局部變量,,函數調用參數,函數返回值,,函數返回地址。由系統(tǒng)管理 堆: 程序運行時動態(tài)申請,,new 和malloc申請的內存就在堆上 28. 使用線程是如何防止出現(xiàn)大的波峰,。 答案:意思是如何防止同時產生大量的線程,方法是使用線程池,,線程池具有可以同時提 高調度效率和限制資源使用的好處,,線程池中的線程達到最大數時,其他線程就會排隊 等候,。 29. 函數模板與類模板有什么區(qū)別? 答案:函數模板的實例化是由編譯程序在處理函數調用時自動完成的,,而類模板的實例化 必須由程序員在程序中顯式地指定。 30. 一般數據庫若出現(xiàn)日志滿了,,會出現(xiàn)什么情況,,是否還能使用? 答案:只能執(zhí)行查詢等讀操作,不能執(zhí)行更改,,備份等寫操作,,原因是任何寫操作都要記 錄日志。也就是說基本上處于不能使用的狀態(tài),。 31. SQL Server是否支持行級鎖,,有什么好處? 答案:支持,,設立封鎖機制主要是為了對并發(fā)操作進行控制,對干擾進行封鎖,,保證數據 的一致性和準確性,,行級封鎖確保在用戶取得被更新的行到該行進行更新這段時間內不 被其它用戶所修改。因而行級鎖即可保證數據的一致性又能提高數據操作的迸發(fā)性,。 32. 如果數據庫滿了會出現(xiàn)什么情況,,是否還能使用? 答案:只能執(zhí)行查詢等讀操作,不能執(zhí)行更改,,備份等寫操作,原因是任何寫操作都要記 錄日志,。也就是說基本上處于不能使用的狀態(tài),。 33. 關于內存對齊的問題以及sizof()的輸出 答案:編譯器自動對齊的原因:為了提高程序的性能,數據結構(尤其是棧)應該盡可能 地在自然邊界上對齊,。原因在于,,為了訪問未對齊的內存,處理器需要作兩次內存訪問 ;然而,,對齊的內存訪問僅需要一次訪問,。 34. int i=10, j=10, k=3; k*=i+j; k最后的值是? 答案:60,此題考察優(yōu)先級,,實際寫成: k*=(i+j);,,賦值運算符優(yōu)先級最低 35. 對數據庫的一張表進行操作,同時要對另一張表進行操作,如何實現(xiàn)? 答案:將操作多個表的操作放入到事務中進行處理 36. TCP/IP 建立連接的過程?(3-way shake) 答案:在TCP/IP協(xié)議中,TCP協(xié)議提供可靠的連接服務,,采用三次握手建立一個連接,。 第一次握手:建立連接時,客戶端發(fā)送syn包(syn=j)到服務器,,并進入SYN_SEND狀 態(tài),,等待服務器確認; 第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),,同時自己也發(fā)送一個 SYN包(syn=k),,即SYN+ACK包,此時服務器進入SYN_RECV狀態(tài); 第三次握手:客戶端收到服務器的SYN+ACK包,,向服務器發(fā)送確認包ACK(ack=k+1) ,,此包發(fā)送完畢,客戶端和服務器進入ESTABLISHED狀態(tài),,完成三次握手,。 37. ICMP是什么協(xié)議,處于哪一層? 答案:Internet控制報文協(xié)議,處于網絡層(IP層) 38. 觸發(fā)器怎么工作的? 答案:觸發(fā)器主要是通過事件進行觸發(fā)而被執(zhí)行的,,當對某一表進行諸如UPDATE,、 INSERT 、 DELETE 這些操作時,數據庫就會自動執(zhí)行觸發(fā)器所定義的SQL 語句,,從而確保對數 據的處理必須符合由這些SQL 語句所定義的規(guī)則,。 39. winsock建立連接的主要實現(xiàn)步驟? 答案:服務器端:socker()建立套接字,綁定(bind)并監(jiān)聽(listen),,用accept() 等待客戶端連接,。 客戶端:socker()建立套接字,連接(connect)服務器,,連接上后使用send()和recv( ),,在套接字上寫讀數據,直至數據交換完畢,,closesocket()關閉套接字,。 服務器端:accept()發(fā)現(xiàn)有客戶端連接,建立一個新的套接字,,自身重新開始等待連 接,。該新產生的套接字使用send()和recv()寫讀數據,直至數據交換完畢,,closesock et()關閉套接字,。 40. 動態(tài)連接庫的兩種方式? 答案:調用一個DLL中的函數有兩種方法: 1.載入時動態(tài)鏈接(load-time dynamic linking),模塊非常明確調用某個導出函數 ,,使得他們就像本地函數一樣,。這需要鏈接時鏈接那些函數所在DLL的導入庫,導入庫向 系統(tǒng)提供了載入DLL時所需的信息及DLL函數定位,。 2.運行時動態(tài)鏈接(run-time dynamic linking),,運行時可以通過LoadLibrary或Loa dLibraryEx函數載入DLL。DLL載入后,,模塊可以通過調用GetProcAddress獲取DLL函數的 出口地址,,然后就可以通過返回的函數指針調用DLL函數了。如此即可避免導入庫文件了 ,。 41. 一個32位的機器,該機器的指針是多少位 答案:指針是多少位只要看地址總線的位數就行了,。80386以后的機子都是32的數據總線。所以指針的位數就是4個字節(jié)了,。 42. 關鍵字volatile有什么含意?并舉例? 答案:提示編譯器對象的值可能在編譯器未監(jiān)測到的情況下改變,。如多線程、多CPU,,變量的值可能被其它線程或運行在其它CUP的代碼更改,。 43. c和c++中的struct有什么不同? 答案:c和c++中struct的主要區(qū)別是c中的struct不可以含有成員函數,而c++中的struct可以,。c++中struct和class的主要區(qū)別在于默認的存取權限不同,,struct默認為public,,而class默認為private 44. 列舉幾種進程的同步機制,并比較其優(yōu)缺點,。 答案:原子操作 信號量機制 自旋鎖 管程,,會合,分布式系統(tǒng) 45. 進程之間通信的途徑 答案:共享存儲系統(tǒng) 消息傳遞系統(tǒng) 命名管道 46. 進程死鎖的原因 答案:資源競爭及進程推進順序非法 47. 死鎖的4個必要條件 答案:互斥,、請求保持,、不可剝奪、環(huán)路 48. 操作系統(tǒng)中進程調度策略有哪幾種? 答案:FCFS(先來先服務),,優(yōu)先級,,時間片輪轉,多級反饋 49. 類的靜態(tài)成員和非靜態(tài)成員有何區(qū)別? 答案:類的靜態(tài)成員每個類只有一個,,非靜態(tài)成員每個對象一個 50. 純虛函數如何定義?使用時應注意什么? 答案:virtual void f()=0; 是接口,,子類必須要實現(xiàn) 51. 數組和鏈表的區(qū)別 答案:數組:數據順序存儲,固定大小 鏈表:數據可以隨機存儲,,大小可動態(tài)改變 52. 線程與進程的區(qū)別和聯(lián)系? 線程是否具有相同的堆棧? dll是否有獨立的堆棧? 答案:進程是死的,只是一些資源的集合,,真正的程序執(zhí)行都是線程來完成的,,程序啟動的時候操作系統(tǒng)就幫你創(chuàng)建了一個主線程。 每個線程有自己的堆棧,。 DLL中有沒有獨立的堆棧,,這個問題不好回答,或者說這個問題本身是否有問題,。因為DLL中的代碼是被某些線程所執(zhí)行,,只有線程擁有堆棧,如果DLL中的代碼是EXE中的線程所調用,,那么這個時候是不是說這個DLL沒有自己獨立的堆棧?如果DLL中的代碼是由DLL自己創(chuàng)建的線程所執(zhí)行,,那么是不是說DLL有獨立的堆棧? 以上講的是堆棧,如果對于堆來說,,每個DLL有自己的堆,,所以如果是從DLL中動態(tài)分配的內存,最好是從DLL中刪除,,如果你從DLL中分配內存,,然后在EXE中,或者另外一個DLL中刪除,,很有可能導致程序崩潰 |
|
來自: lifei_szdz > 《待分類1》