1. 程式人生 > >c++面試總結(騰訊公司)

c++面試總結(騰訊公司)

今天上午面試完騰訊,感覺專案部分被洗的不輕啊,實習專案被追問,網路爬蟲專案被逼問,一個問題結一個問題的深入,剛介紹完專案,就開始問為什麼用epoll一步步深入了;理論基礎部分個人感覺回答感覺不錯,都回答上了,很基礎,下面針對基礎部分總結一下,分享給大家,希望對大家有一些幫助。

1、malloc和new的區別

(1)操作物件不同:malloc/free是C++/C語言的標準庫函式,new/delete是C++的運算子。對於非內部資料類的物件而言,光用malloc/free無法滿足動態物件的要求。

(2)返回型別安全new操作符記憶體分配成功時,返回的是物件型別的指標,型別嚴格與物件匹配,無須進行型別轉換,故new是符合

型別安全性的操作符。而malloc記憶體分配成功則是返回void * ,需要通過強制型別轉換將void*指標轉換成我們需要的型別。(int *)malloc(sizeof(int))
型別安全很大程度上可以等價於記憶體安全,型別安全的程式碼不會試圖方法自己沒被授權的記憶體區域。關於C++的型別安全性可說的又有很多了。

(3)記憶體分配失敗時的返回值:new記憶體分配失敗時,會丟擲bac_alloc異常,比如反饋客戶請求處理記憶體分配不足;malloc分配記憶體失敗時返回NULL。

(4)是否需要指定記憶體大小:使用new操作符申請記憶體分配時無須指定記憶體塊的大小,編譯器會根據型別資訊自行計算,而malloc則需要顯式地指出所需記憶體的尺寸。

例子:(int *)malloc(sizeof(int)),new int;

(5)是否呼叫構造/解構函式:使用new操作符來分配物件記憶體時會經歷三個步驟:呼叫operator new 函式(對於陣列是operator new[])分配一塊足夠大原始的未命名的記憶體空間以便儲存特定型別的物件編譯器執行相應的建構函式以構造物件,併為其傳入初值編譯器執行相應的建構函式以構造物件,併為其傳入初值。使用delete操作符來釋放物件記憶體時會經歷兩個步驟:呼叫物件的解構函式編譯器呼叫operator delete(或operator delete[])函式釋放記憶體空間。

(6)對陣列的處理

C++提供了new[]與delete[]來專門處理陣列型別: A*ptr=new A[10];//分配10個A物件,使用new[]分配的記憶體必須使用delete[]進行釋放:delete [] ptrnew對陣列的支援體現在它會分別呼叫建構函式函式初始化每一個數組元素,釋放物件時為每個物件呼叫解構函式。注意delete[]要與new[]配套使用,不然會找出陣列物件部分釋放的現象,造成記憶體洩漏。至於malloc,它並知道你在這塊記憶體上要放的陣列還是啥別的東西,反正它就給你一塊原始的記憶體,在給你個記憶體的地址就完事。所以如果要動態分配一個數組的記憶體,還需要我們手動自定陣列的大小:int*ptr=(int*)malloc(sizeof(int));//分配一個10個int元素的陣列。

(7)New/malloc是否可以互相呼叫operator new /operator delete的實現可以基於malloc,而malloc的實現不可以去呼叫new。

(8)opeartor new /operator delete可以被過載(前提是自定義版本必須位於全域性作用域或者類作用域中),而malloc/free並不允許過載

(9)malloc能直觀的重新分配記憶體:使用malloc分配的記憶體後,如果在使用過程中發現記憶體不足,可以使用realloc函式進行記憶體重新分配實現記憶體的擴充。realloc先判斷當前的指標所指記憶體是否有足夠的連續空間,如果有,原地擴大可分配的記憶體地址,並且返回原來的地址指標;如果空間不夠,先 按照新指定的大小分配空間,將原有資料從頭到尾拷貝到新分配的記憶體區域,而後釋放原來的記憶體區 域。new沒有這樣直觀的配套設施來擴充記憶體。

2、執行緒和程序的區別

      主要差別在於它們是不同的作業系統資源管理方式。程序有獨立的地址空間,一個程序崩潰後,在保護模式下不會對其它程序產生影響,而執行緒只是一個程序中的不同執行路徑。執行緒有自己的堆疊和區域性變數,但執行緒之間沒有單獨的地址空間,是共享地址空間,一個執行緒死掉就等於整個程序死掉,所以多程序的程式要比多執行緒的程式健壯,但在程序切換時,耗費資源較大,效率要差一些。但對於一些要求同時進行並且又要共享某些變數的併發操作,只能用執行緒,不能用程序。

      每個獨立的執行緒有一個程式執行的入口、順序執行序列和程式的出口。但是執行緒不能夠獨立執行,必須依存在應用程式中,由應用程式提供多個執行緒執行控制。從邏輯角度來看,多執行緒的意義在於一個應用程式中,有多個執行部分可以同時執行。但作業系統並沒有將多個執行緒看做多個獨立的應用,來實現程序的排程和管理以及資源分配。這就是程序和執行緒的重要區別。

3、殭屍程序

       一個程序使用fork建立子程序,如果子程序退出,而父程序並沒有呼叫wait或waitpid獲取子程序的狀態資訊,那麼子程序的程序描述符仍然儲存在系統中。這種程序稱之為僵死程序。

      危害:如果程序不呼叫wait / waitpid的話, 那麼保留的那段資訊就不會釋放,其程序號就會一直被佔用,但是系統所能使用的程序號是有限的,如果大量的產生僵死程序,將因為沒有可用的程序號而導致系統不能產生新的程序. 此即為殭屍程序的危害,應當避免。

     處理方法:當我們尋求如何消滅系統中大量的僵死程序時,答案就是把產生大 量僵死程序的那個元凶槍斃掉(也就是通過kill傳送SIGTERM或者SIGKILL訊號啦)。槍斃了元凶程序之後,它產生的僵死程序就變成了孤兒進 程,這些孤兒程序會被init程序接管,init程序會wait()這些孤兒程序,釋放它們佔用的系統程序表中的資源,這樣,這些已經僵死的孤兒程序 就能瞑目而去了。

     孤兒程序:一個父程序退出,而它的一個或多個子程序還在執行,那麼那些子程序將成為孤兒程序。孤兒程序將被init程序(程序號為1)所收養,並由init程序對它們完成狀態收集工作。

4、過載與多型的區別

(1)過載是同名引數不同,通過引數來確定呼叫那個函式;但是多型是同名同參數,通過函式的實際型別決定呼叫那個函式;

(2)過載而言,在方法呼叫之前,編譯器就已經確定了所要呼叫的方法,這稱為“早繫結”或“靜態繫結”;

多型而言,只有等到方法呼叫的那一刻,編譯器才會確定所要呼叫的具體方法,這稱為“晚繫結”或“動態繫結”。