c++一些面試題目
1、What is achieved by prefixing the 'static' keyword to a file-level function or file-level variable declaration?
使用static關鍵字修飾文件級的函數和變量起到什么作用?
key:對變量來說,不允許文件外的程序訪問;對函數來說,該函數的實現必須在這個文件內完成,并且不允許文件外的程序調用。
2、Describe the difference between the “IS A” and “HAS A” object relationships. Which is the stronger relationship and why?
IS A在編譯期就決定了對象的行為,但是HAS A可以在運行的時候改變"A"所指向的對象,從而可以在運行時改變其行為;
HAS A可以有IS A提供的所有特性(至于訪問權限,如果需要,可以賦予friend的關系)
3、Java & C# support interfaces directly with the “interface” keyword.
C++ does not have an “interface” keyword.
How do you create an interface in C++?
Where/when is the use of interfaces especially helpful?
C++ uses pure virtual class to emulate interfaces.
4、If a program requires a large number of execution contexts, what can be done to minimise thread scheduling overhead?
題目意思是:如果一個程序需要巨大的運行上下文,怎樣來最小化線程調度的開銷?
我不知道怎么回答,如果你知道,能告訴我么?
5、What does it mean to say that a function is reentrant?
What are some of the ways of achieving re-entrancy?
函數可重入是指無論什么時候,對于輸入相同的參數,得到的結果都一致。
要使函數可重入,就要避免在函數中使用靜態變量,全局變量(在這里是廣義的全局變量,包括全局變量,類的靜態變量,以及類的數據成員)
如果要在多線程環境下也保證re-entrancy的話,還需要安裝互斥鎖。
6、拋出異常和返回錯誤值有什么不同?什么時候得處理拋出異常?
有些情況下必須作異常處理,如程序出現除0的情況,如果不作異常處理的話程序就出現運行時錯誤。
7、函數參數聲明為引用的好處
不需要創建臨時變量,創建一個臨時變量會增加開銷。
8、異常處理的catch里邊能不能再拋出異常?
能,這種拋出稱為“重拋出”(rethrow),異常將由更外邊一層異常處理程序來處理。
9、析構函數是否允許拋出異常?
允許,但這樣的話析構函數的執行就在throw處結束,這樣析構可能就不完整。
如果實在要使用throw(),那么在析構函數內用catch()處理所有的異常可認為是安全的。
10、構造函數是否允許為虛函數?析構函數呢?
構造函數不允許為虛函數,析構函數可以。
看這種情況:
BaseClass *p = new DerivedClass();
delete p;
如果基類析構函數不為virtual,那么只會調用基類的析構函數,子類的析構函數是不被調用的,所以一般來說我們要把基類的析構函數聲明為virtual。
11、什么是多態,如何實現?
經常問的問題,但有時候太緊張思維受阻,還真回答不出來……
其實如果要咬文嚼字的話:“多態(polymorphism)是一種將不同的特殊行為和單個泛化記號相關聯的能力”。
回答:
通過虛函數和模版來實現,前者是動態多態,后者是靜態多態。
12、什么是虛基類?
其實不應該這樣問的,不過我也是碰到這個問題之后才了解到“虛繼承”,回答:
被子類虛繼承的基類稱為虛基類。(e……虛基類和一般的類毫無分別,只是被別人“虛繼承”就稱為虛基類了,可惡,哪有這樣定義的?但他硬是這么問)
虛繼承所能達到的目的是:無論繼承了多少個基類的實例,只存在一份基類的共享實例,通常用于多重繼承(又是很少用的東西,我只建過接口的實現用多重繼承,接口接口,該死的Java,該死的面向對象),它可以避免基類實例重復出現而引起的沖突。
13、闡述一下iostream
對“iostream”來說:
cin 是 istream類的對象,istream類 來自 basic_istream模版
cout 是 ostream類的對象,ostream類 來自 basic_ostream模版
cerr 同 cout
對“iostream.h”來說:
沒有使用模版,
cin 是 ostream_withassign類的對象,ostream_withassign是istream的子類,istream虛繼承于ios類(ios類就是根了)
cout 是 ostream_withassign類的對象,ostream_withassign是ostream的子類,ostream虛繼承于ios類
cerr 同 cout
14、闡述STL(復習下STL)
……
15、用聚合還是繼承
和第二題差不多
16、函數指針的聲明
typedef int (*FUN)(int, int);
FUN fp;
也可以直接定義一個叫fp的函數指針:
int (*fp)(int, int);
typedef int (*FUN)(int, int);
FUN fp[10]; //函數指針數組
或
int (*fp[10])(int, int);
17、關于const
const int a = 10; //a恒為10
int const a = 10; //(同上)
const int *a = &b; //a指向的數為恒值,但a可變
int * const a = &b; //a的值不可變,a指向的值可變
//可能你已經想到了,要使得a及*a的值都不可變:
int const * const a = &b;
18、關于volatile
這個問題我還真的遇到了,并且我幾乎答不出,我只說了,這是跟硬件比較相關的一個概念……
如果沒做過嵌入式開發的話是不會使用到這個關鍵字的。當一個變量被定義為volatile的時候,這個關鍵字告訴優化器,改變量的值可能會不經意地改變,每次使用到該變量的值,都必須重新獲取。
19、++的細節
(A)a += (a++); (B) a += (++a) ;(C) (a++) += a;(D) (++a) += (a++);
C是錯誤的表達式,因為“=”左邊不是一個有效值。
20、extern "C"的作用
一般都能回答,但標準的答案是:
函數和變量被C++編譯后在符號庫中的名字與C語言的不同,被extern "C"修飾的變量和函數是按照C語言方式編譯和連接的。由于編譯后的名字不同,C++程序不能直接調用C 函數。C++提供了一個C 連接交換指定符號extern“C”來解決這個問題。
21、關于類型安全
……
22、簡述Windows線程同步的幾個方法
1)關鍵代碼段,InitializeCriticalSection(),EnterCriticalSection(),LeaveCriticalSection(),不能跨越進程,速度很快,又稱為用戶方式同步。
2)除了用戶方式同步就是內核對象同步了。WaitForSingleObject(),WaitForMultiObject()……
注意:如果是一個線程對象,它處于“有信號”的時候說明它“可調度”,比如它結束了。
2-1)事件Event:CreateEvent(),SetEvent(),ResetEvent(),注意:Event對象可以設置為自動,那么Wait之后它會自動轉變為無信號。
2-2)信標Semaphore:CreateSemaphore(),ReleaseSemaphore(),WaitForSingleObject(smph)的時候Count--,ReleaseSemaphore(smph)的時候Count++。
2-3)互斥體Mutex:CreateMutex(),ReleaseMutex(),和信標類似,但沒有“資源計數”這一概念。
23、進程間通信
1)Windows消息
2)共享內存,用CreateFileMapping()或者dll
3)網絡
4)命名管道
5)郵槽
24、函數參數傳遞中,數組參數將退化為指針
這點經常考,千萬注意
25、程序分析
void getmemory(char *p)
{
p=(char *)malloc(100);
strcpy(p,"hello world");
}
int main( )
{
char *str=NULL;
getmemory(str);
printf("%s/n",str);
free(str);
return 0;
}
這段程序是不能正常打印出“hello world”的,因為指針的值不能正常返回,如果要正確返回指針的值,那么請使用指針的指針,或者引用。
void getmemory(char* & p)
{
p=(char *)malloc(100);
strcpy(p,"hello world");
}
這樣就OK了。
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成