C++面試總結
阿新 • • 發佈:2019-01-05
1、C++中的類和C的struct的區別:
C++中的類封裝了資料以及對資料進行的操作,而struct僅僅是封裝了資料,同時struct的資料外界是可以直接訪問的,這與封裝是衝突的,不安全,而在類中資料對外界一般是不可見的,對外提供能操作資料的介面。同時類是可以繼承,struct不能繼承;
值得注意的是:C++中的類與C++中的struct差別是不大的。
2、解構函式和虛擬函式的用法與作用:
解構函式是名為“~<類名>”、沒有引數和返回型別的一個特殊的成員函式。當物件消亡時,在系統收回它所佔的記憶體空間之前,物件類的解構函式會被自動呼叫。 虛擬函式:為了實現動態繫結,必須把相應的函式宣告為虛擬函式,就是在函式的宣告前面加上virtual關鍵字。虛擬函式的動態繫結隱含著:基類中的一個成員函式如果被定義為虛擬函式,則在派生類中定義的與之具有相同型構的成員函式是對基類該成員函式的重定義(或稱覆蓋,override)。如果基類的一個成員函式沒有被定義成虛擬函式,則在派生類中定義的與之同名(包括同型構)的所有成員函式都不是對基類該成員函式的重定義,它們只是隱藏了基類的同名成員函式。
值得注意的是:建構函式不能是虛擬函式;類的靜態成員函式不能是虛擬函式;(基類的)解構函式往往可以是虛擬函式,只有類的成員函式才能是虛擬函式。
3、全域性變數與區域性變數的區別:
全域性變數儲存在記憶體空間的靜態資料區,具有靜態生存期,從程式編譯開始就一直存在著,直到程式執行結束,作用域是全域性作用域;
區域性變數的預設儲存類為auto,除此之外還有static、register。作用域是區域性作用域,只能定義它們的複合語句內使用。auto類區域性變數具有自動生存期,存放在棧區;register類區域性變數具有動態生存期,建議編譯程式把其空間分配在CPU暫存器中(有時候也會存放在記憶體中);static類具有靜態生存期,存放在記憶體的靜態資料區。
編譯器根據變數定義的位置區分全域性變數與區域性變數,作業系統通過變數的分配地址就可以判斷出是區域性變數和全域性變數。
區域性變數在編譯階段不分配空間,全域性變數在編譯是就分配空間。 4、程序與執行緒的區別:
程序是系統資源分配和排程的基本單元,擁有獨立的記憶體空間,不同的程序間相互獨立,一個程序死亡不影響其他程序;程序是程式在計算機中的一次執行活動;
執行緒擁有堆疊和區域性變數,但是不用獨立的記憶體空間,而是和同一程序下的其他執行緒共享該程序的記憶體資源;
一個執行緒終止不影響其他執行緒執行,但是如果一個執行緒執行exit()系統呼叫,則全部執行緒終止;父執行緒終止,則所有子執行緒也終止;在Windows下,執行緒是CPU資源分配與排程的基本單位;
與程序相比,執行緒的開銷更小,但是不利於資源的管理與保護
引入執行緒帶來的主要好處:
(1) 在程序內建立、終止執行緒比建立、終止程序要快;
(2) 同一程序內的執行緒間切換比程序間的切換要快,尤其是使用者級執行緒間的切換。
程序間通訊IPC,執行緒間可以直接讀寫程序資料段(如全域性變數)來進行通訊——需要程序同步和互斥手段的輔助,以保證資料的一致性。
而棧則是向下生長的,從高地址向低地址增長,是連續的記憶體空間,大小固定,一般為2M;如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。
堆上存放著程式執行過程中產生的動態變數,棧上存放的是auto區域性變數以及函式的形參、函式的呼叫資訊(返回地址等)
答:因為當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連線時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能傳送FIN報文,因此不能一起傳送。故需要四步握手。
【問題2】為什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網路是不可靠的,有可以最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。
C++中的類封裝了資料以及對資料進行的操作,而struct僅僅是封裝了資料,同時struct的資料外界是可以直接訪問的,這與封裝是衝突的,不安全,而在類中資料對外界一般是不可見的,對外提供能操作資料的介面。同時類是可以繼承,struct不能繼承;
值得注意的是:C++中的類與C++中的struct差別是不大的。
2、解構函式和虛擬函式的用法與作用:
解構函式是名為“~<類名>”、沒有引數和返回型別的一個特殊的成員函式。當物件消亡時,在系統收回它所佔的記憶體空間之前,物件類的解構函式會被自動呼叫。 虛擬函式:為了實現動態繫結,必須把相應的函式宣告為虛擬函式,就是在函式的宣告前面加上virtual關鍵字。虛擬函式的動態繫結隱含著:基類中的一個成員函式如果被定義為虛擬函式,則在派生類中定義的與之具有相同型構的成員函式是對基類該成員函式的重定義(或稱覆蓋,override)。如果基類的一個成員函式沒有被定義成虛擬函式,則在派生類中定義的與之同名(包括同型構)的所有成員函式都不是對基類該成員函式的重定義,它們只是隱藏了基類的同名成員函式。
值得注意的是:建構函式不能是虛擬函式;類的靜態成員函式不能是虛擬函式;(基類的)解構函式往往可以是虛擬函式,只有類的成員函式才能是虛擬函式。
3、全域性變數與區域性變數的區別:
全域性變數儲存在記憶體空間的靜態資料區,具有靜態生存期,從程式編譯開始就一直存在著,直到程式執行結束,作用域是全域性作用域;
區域性變數的預設儲存類為auto,除此之外還有static、register。作用域是區域性作用域,只能定義它們的複合語句內使用。auto類區域性變數具有自動生存期,存放在棧區;register類區域性變數具有動態生存期,建議編譯程式把其空間分配在CPU暫存器中(有時候也會存放在記憶體中);static類具有靜態生存期,存放在記憶體的靜態資料區。
編譯器根據變數定義的位置區分全域性變數與區域性變數,作業系統通過變數的分配地址就可以判斷出是區域性變數和全域性變數。
區域性變數在編譯階段不分配空間,全域性變數在編譯是就分配空間。 4、程序與執行緒的區別:
程序是系統資源分配和排程的基本單元,擁有獨立的記憶體空間,不同的程序間相互獨立,一個程序死亡不影響其他程序;程序是程式在計算機中的一次執行活動;
執行緒擁有堆疊和區域性變數,但是不用獨立的記憶體空間,而是和同一程序下的其他執行緒共享該程序的記憶體資源;
一個執行緒終止不影響其他執行緒執行,但是如果一個執行緒執行exit()系統呼叫,則全部執行緒終止;父執行緒終止,則所有子執行緒也終止;在Windows下,執行緒是CPU資源分配與排程的基本單位;
與程序相比,執行緒的開銷更小,但是不利於資源的管理與保護
引入執行緒帶來的主要好處:
(1) 在程序內建立、終止執行緒比建立、終止程序要快;
(2) 同一程序內的執行緒間切換比程序間的切換要快,尤其是使用者級執行緒間的切換。
程序間通訊IPC,執行緒間可以直接讀寫程序資料段(如全域性變數)來進行通訊——需要程序同步和互斥手段的輔助,以保證資料的一致性。
程序間通訊(IPC,InterProcess Communication)是指在不同程序之間傳播或交換資訊。IPC的方式通常有管道(包括無名管道和命名管道)、訊息佇列、訊號量、共享儲存、Socket、Streams等。其中Socket和Streams支援不同主機上的兩個程序IPC。
5、堆(heap)與棧(stack)的區別:
堆向上生長,從低地址向高地址生長,是一段不連續的記憶體空間;系統是用連結串列來儲存的空閒記憶體地址的;堆的大小受限於計算機系統中有效的虛擬記憶體。由此可見,堆獲得的空間比較靈活,也比較大。而棧則是向下生長的,從高地址向低地址增長,是連續的記憶體空間,大小固定,一般為2M;如果申請的空間超過棧的剩餘空間時,將提示overflow。因此,能從棧獲得的空間較小。
堆上存放著程式執行過程中產生的動態變數,棧上存放的是auto區域性變數以及函式的形參、函式的呼叫資訊(返回地址等)
重點:TCP三次握手和四次揮手的過程。
答:因為當Server端收到Client端的SYN連線請求報文後,可以直接傳送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連線時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能傳送FIN報文,因此不能一起傳送。故需要四步握手。
【問題2】為什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網路是不可靠的,有可以最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。