進階語言保研面試準備
- C++的特點是什麼?
- 封裝:将資料或函數集合在一個類中
- 繼承:派生類可以繼承父類的一些資料和函數
- 多态:同一個行為具有多個不同表現形式或形态的能力。運作時,可以通過指向基類的指針,調用派生類中的方法
-
C++的異常處理機制?
抛出異常和捕捉異常進行處理。
-
c和c++,java的差別?
c是純過程,c++是對象加過程,java是純面向對象的
-
純虛函數?
被virtual修飾的成員函數,基類不實作,放到派生類中實作。
-
什麼是記憶體洩漏?
記憶體洩漏(Memory Leak)是指程式中已動态配置設定的堆記憶體由于某種原因程式未釋放或無法釋放,造成系統記憶體的浪費,導緻程式運作速度減慢甚至系統崩潰等嚴重後果。沒有delete。
-
java怎麼處理對象配置設定和釋放的?
java把記憶體分為堆棧空間存儲,在堆中new的空間不用自己收回,自動垃圾收回。
-
java的特點?
一次編譯到處運作,沒有指針,完全對象化。
-
c++和c中字元串差別?
c++是類,c中是基本類型函數。
-
c++模闆
模闆就是實作代碼重用機制的一種工具,它可以實作類型參數化,即把類型定義為參數, 進而實作了真正的代碼可重用性。模版可以分為兩類,一個是函數模版,另外一個是類模版。
-
智能指針
智能指針的作用是管理一個指針,因為普通指針申請的空間在函數結束時常常忘記釋放,進而造成記憶體洩漏。使用智能指針可以很大程度上的避免這個問題,因為智能指針就是一個類,當超出了類的作用域時,類會自動調用析構函數,析構函數會自動釋放資源。智能指針的作用原理就是在函數結束時自動釋放記憶體空間,不需要手動釋放記憶體空間。
-
野指針
野指針就是指向一個已删除的對象或者所指向的空間是通路受限的空間的指針。
産生原因:(1)指針變量未初始化
(2)指針釋放後之後未置空
(3)指針操作超越變量作用域
-
new與malloc的差別
(1)new配置設定記憶體按照資料類型進行配置設定,malloc配置設定記憶體按照指定的大小配置設定;
(2)new傳回的是指定對象的指針,而malloc傳回的是void*,是以malloc的傳回值一般都需要進行類型轉化。
(3)new配置設定的記憶體要用delete銷毀,malloc要用free來銷毀;delete銷毀的時候會調用對象的析構函數,而free則不會。
(4)new是一個運算符,malloc是一個庫函數。
(5)new如果配置設定失敗了會抛出異常,而malloc失敗了會傳回NULL。
-
虛函數與純虛函數
虛函數:不代表該函數沒有被實作,而是為了允許用基類的指針來調用派生類的這個函數。
純虛函數:代表函數沒有被實作。定義純虛函數是為了實作一個接口,起到一個規範的作用,繼承這個類必須實作這個函數。
-
虛函數表
虛函數(Virtual Function)是通過一張虛函數表(Virtual Table)來實作的,簡稱為 V-Table。在這個表中,主要是一個類的虛函數的位址表,這張表解決了繼承、覆寫的問題,保證其真實反應實際的函數。這樣,在有虛函數的類的執行個體中這個表被配置設定在了這個執行個體的記憶體中,是以,當我們用父類的指針來操作一個派生類的時候,這張虛函數表就顯得由為重要了,它就像一個地圖一樣,指明了實際所應該調用的函數。
C++ 的編譯器應該是保證虛函數表的指針存在于對象執行個體中最前面的位置(這是為了保證取到虛函數表有最高的性能 —— 如果有多層繼承或是多重繼承的情況下)。 這意味着我們通過對象執行個體的位址得到這張虛函數表,然後就可以周遊其中函數指針,并調用相應的函數。
-
為什麼析構函數必須是虛函數?為什麼C++預設的析構函數不是虛函數?
析構函數設定為虛函數可以保證我們new一個派生類時,可以使用基類指針指向該派生類對象,釋放基類指針時可以釋放掉派生類的空間,防止記憶體洩漏。
C++預設的析構函數不是虛函數是因為虛函數需要額外的虛函數表和虛表指針,占用額外的記憶體。而對于不會被繼承的類來說,其析構函數如果是虛函數,就會浪費記憶體。是以C++預設的析構函數不是虛函數,而是隻有當需要當作父類時,設定為虛函數。
-
fork函數
用途:建立一個和目前程序映像一樣的程序
fork可能有三種不同的傳回值:
(1)fork向父程序傳回最新建立的派生程序的程序ID;
(2)fork向新建立的派生程序傳回0,以告知它已經被成功建立;
(3)如果出現錯誤,fork傳回一個負值;
建立新程序成功後,系統中出現兩個基本完全相同的程序,這兩個程序執行沒有固定的先後順序,哪個程序先執行要看系統的程序排程政策。
-
類構造和析構順序
構造: 析構:
基類成員對象的構造函數 派生類的析構函數
基類的構造函數 兩者相反 派生類成員對象的析構函數
派生類成員對象的構造函數 基類的析構函數
派生類的構造函數 基類成員對象的析構函數
-
靜态多态與動态多态
靜态多态有兩種實作方式:函數重載與函數模闆的使用。
靜态多态:也稱為編譯期間的多态,編譯器根據函數實參的類型,可推斷出要調用哪個函數,如果沒有對應函數則出現編譯錯誤。
動态多态主要是調用虛函數時,根據虛函數表确定具體調用的子產品。
動态多态:即運作時的多态,在程式執行期間判斷所引用對象的實際類型,根據其實際類型調用相應的方法。
-
const修飾普通函數與成員函數的目的
const修飾函數在類中将成員函數修飾為const表明在該函數體内,不能修改對象的資料成員而且不能調用非const函數
-
C語言參數壓棧順序
從右到左
-
STL六大元件
容器,算法,疊代器,仿函數,配接器(擴充卡),配置設定器
-
C++源檔案從文本到可執行檔案經曆的過程
預處理階段:對源代碼檔案中頭檔案、宏定義進行分析和替換,生成.i檔案。
編譯階段:将預編譯檔案轉換成特定彙編代碼,生成.s檔案。
彙編階段:将彙編檔案轉化成機器碼,生成.o或者.obj檔案。
連結階段:連接配接所需要的庫,形成最終的可執行目标檔案,即.out或者.exe檔案。
- 引用與指針的差別?
- 引用必須被初始化,指針不必
- 引用初始化以後不能被改變,指針可以改變所指的對象
- 不存在指向空值的引用,但是存在指向空值的指針
- 指針是一個實體,而引用僅是個别名
-
struct和class的差別
共同點:struct和class都可以定義成員和函數,都具有繼承、多态。
不同點:
- class預設權限是private,struct預設權限是public。
- class可以聲明類模闆,而struct不可以。
-
堆與棧
stack棧區主要是存儲函數的局部變量,然後程式結束後作業系統自行回收但是棧區容量比較小。一級緩存。從高位址向低位址移動。
heap堆區是程式裡動态配置設定的内容,堆區的記憶體容量大,使用靈活,使用後要自行回收。容易産生記憶體碎片。二級緩存,速度比一級緩存慢。從低位址向高位址移動。
- const 與 #define 的比較,const 有什麼優點?
- const 常量有資料類型,而宏常量沒有資料類型。編譯器可以對前者進行類型安全檢查。而對後者隻進行字元替換,沒有類型安全檢查,并且在字元替換可能會産生意料不到的錯誤(邊際效應) 。
- 有些內建化的調試工具可以對 const 常量進行調試,但是不能對宏常量進行調試。