# 02|面試題筆記系列

“本文大約有 2794 字。

面試筆記系列的第 2 篇文章。

01面試題來源

  • 老虎二面

  • BIGO 一面

 

02概念題

1. C++ 的內存管理?

在 C++ 中,內存分爲 5 個區:堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。

 

堆/棧、malloc/new

 

2. TCP 和 UDP 的區別?

TCP 是面向連接的,UDP 是面向無連接的。

 

  • TCP 提供可靠交付。UDP 繼承了 IP 包的特性,不保證不丟失,不保證按順序到達。

  • TCP 是面向字節流的,發送的時候發的是一個流,沒頭沒尾。UDP 是基於數據報的,一個一個的發,一個一個的收。

  • TCP 是可以有擁塞控制的。它意識到包丟棄了或者網絡的環境不好了,就會根據情況調整自己的行爲,看看是不是發快了,要不要發慢點。UDP 就不回,應用讓他發,它就發,可不管網絡情況怎麼樣。

  • TCP 是一個有狀態服務,精確地記着發送了沒有,接收到沒有,發送到哪個了,應該接收哪個了,錯一點兒都不行。UDP 則是無狀態服務,沒有什麼保證機制,一個包發出去就發出去了。

 

3. TCP 怎麼確定可靠傳輸?

  • 順序問題,穩重不亂;

每一個包都有一個 ID。在建立連接的時候,會商定起始的 ID 是什麼,然後按照 ID 一個個發送。

 

  • 丟包問題,承諾靠譜;

對於發送的包都要進行應答,有高效的累計確認。

 

  • 連接維護,有始有終;

 

  • 流量控制,把握分寸;

接收窗口控制發送窗口。當發送端的窗口爲 0 時(接收方一直不處理數據),發送方會定時發送窗口探測數據包,看看是否有機會調整窗口大小。

 

  • 擁塞控制,知進知退。

避免包丟失和超時重傳,指數式增長、線性增長,快速重傳算法:cwnd 減半爲 cwnd/2,然後 sshthresh = cwnd。

 

4. 流量控制與擁塞控制

流量控制機制,在對於包的確認中,同時會攜帶一個窗口的大小。包的確認到達的時候,窗口滑動,纔有更多的包可以發送。

如果接收方處理的太慢,導致緩存中沒有空間了,可以通過確認信息修改窗口大小,降低發送方發送速度或者發送方暫停發送。

 

發送方會定時發送窗口探測數據包,看是否有機會調整窗口的大小。又要防止低能窗口綜合徵,別空出一個字節來就告訴發送方,有馬上填滿了,具備一定的鬆弛操作,直到到達一定的大小,才更新窗口。

 

“粘包”其實是應用程序中沒有處理好數據包分割,兩個應用層的數據包粘在一塊了,這不關 TCP 的事,在大學學習網絡的時候,書本上就沒有這個名詞。

 

擁塞控制:TCP 的擁塞控制主要來避免兩種現象,即包丟失和超時重傳。一旦出現了這些現象就說明,發送的速度太快了,要慢一些。

 

一條 TCP 連接開始,cwnd 設置爲一個報文段,一次只能發送一個;當收到這一個確認的時候,cwnd 加一,於是一次能夠發送兩個;當這兩個的確認到來的時候,每個確認 cwnd 加一,兩個確認 cwnd 加二,於是一次能夠發送四個;當這四個的確認到來的時候,每個確認 cwnd 加一,四個確認 cwnd 加四,於是一次能夠發送八個。可以看出這是指數性的增長。

 

漲到什麼時候是個頭呢?有一個值叫做門限(ssthresh)爲 65535 個字節,當超過這個值的時候,就要小心一點了,就不能增長那麼快了。

 

於是,每收到一個確認後,cwnd 增加 1/cwnd,我們接着上面的過程來,一次發送八個,當八個確認到來的時候,每個確認增加 1/8,八個確認一共 cwnd 增加 1,於是一次能夠發送九個,變成了線性增長。

 

但是線性增長還是增長,還是越來越多,直到發送擁塞。擁塞的一種表現形式是丟包,需要超時重傳。

 

有一種方式是,將 sshresh 設爲 cwnd/2,將 cwnd 設爲 1,重新開始慢啓動。。但是這種方式太激進了,將一個高速的傳輸速度一下子停了下來,會造成網絡卡頓。

 

快速重傳算法。當接收端發現丟了一箇中間包的時候,發送三次前一個包的 ACK,於是發送端就會快速的重傳,不必等待超時再重傳。TCP 認爲這種情況不嚴重,因爲大部分沒丟,只丟了一小部分,cwnd 減半爲 cwnd/2,然後 sshthresh = cwnd,呈線性增長。

 

TCP BBR 擁塞算法,它佔滿帶寬,但是不佔滿緩存,時延較低。

03算法題

1. 怎麼刪除鏈表第 n 個結點?

(1)找到待刪節點的前一個節點,然後指向待刪節點的下一個節點,釋放待刪節點的空間。

(2)如果傳入的參數爲第 n 個節點,則可以直接將後一個節點值覆蓋掉當前節點,然後刪除後一節點。注:傳入的節點不是最後一個節點。

 

04理解應用題

1. STL 容器是線程安全的還是不安全的?

多線程讀取是安全的,多線程對不同的容器寫是安全的。多個線程可以讀同一個容器內的數據,讀時不允許寫操作。

 

2. Windows 出現了內存泄漏怎麼辦?

* VC++ 的 CRT 庫在 Debug 下支持內存的診斷。

* IBM 的 Purify 號稱最強大的內存檢測工具。

 

3. TCP, UDP 應用的場景

TCP 支持的應用層協議主要有:Telnet、FTP、SMTP、HTTP。

UDP 支持的應用層協議有:DNS、NFS(網絡文件系統)、SNMP(簡單的網絡管理協議)、TFTP(通用文件傳輸協議)等。

 

UDP 的三大應用場景:

第一,需要資源少,在網絡情況比較好的內網,或者對於丟包不敏感的應用。

第二,不需要一對一溝通,建立連接,而是可以廣播的應用。第三,需要處理速度快,時延低,可以容忍少數丟包,但是要求即便網絡擁塞,也毫不退縮,一往無前的時候。

 

基於 UDP 的五個例子:

(1)網頁訪問:QUIC(全稱Quick UDP Internet Connections,快速 UDP 互聯網連接)是 Google 提出的一種基於 UDP 改進的通信協議。QUIC 在應用層上,會自己實現快速連接建立、減少重傳時延,自適應擁塞控制。

 

(2)流媒體的協議

很多直播應用,都基於 UDP 實現了自己的視頻傳輸協議。直播,實時性比較比較重要,寧可丟包,也不要卡頓的。在網絡不好的情況下,應用希望選擇性的丟幀。

 

老的視頻幀丟了其實也就丟了,就算再傳過來用戶也不在意了,他們要看新的了,如果老是沒來就等着,卡頓了,新的也看不了,那就會丟失客戶。

 

(3)實時遊戲

遊戲有一個特點,就是實時性比較高。TCP 的強順序問題,如果出現一個數據包丟失,容易造成卡頓。遊戲對實時要求較爲嚴格的情況下,採用自定義的可靠 UDP 協議,自定義重傳策略,能夠把丟包產生的延遲降到最低,儘量減少網絡問題對遊戲性造成的影響。

 

(4)IoT 物聯網

物聯網領域終端資源少,很可能只是個內存非常小的嵌入式系統,而維護 TCP 協議代價太大;另一方面,物聯網對實時性要求也很高,而 TCP 還是因爲上面的那些原因導致時延大。

 

Google 推出的物聯網通信協議 Thread,就是基於 UDP 協議的。

 

在 4G 網絡裏,移動流量上網的數據面對的協議 GTP-U 是基於 UDP 的。

 

4. 紅黑樹

這裏我寫了一篇博客,講的是紅黑樹與 2-3樹的等價性,請看參考。

 

5. 穩定的排序算法

穩定性:*穩定排序算法*會讓原本有相等鍵值的記錄維持相對次序,原本在前面的還是在前面。

穩定的排序:冒泡、插入、桶子、計數、歸併、基數。

“快”“堆”“選”“希“不穩。

快:2330 ==> 切分 i 和 j 互換,3 和 0 換。

堆:222 === > 第一個出堆後,選擇後面的一個放到堆頂。

選擇:221 ==> 122 一趟排序後,第一個 2 個最後一個 1 換了位置。

希爾明顯不穩。

 

6. C++ 有哪些創建線程的方法?

(Function Pointer)函數指針

(Function Objects)函數對象

(Lambda functions)

生產者消費者,傳遞的是函數指針。

05參考

1. 數據結構 | 2-3樹與紅黑樹的等價性

https://donngdev.github.io/posts/rb-tree

2. Have Fun with LeetCode

https://github.com/donngdev/Have-Fun-with-LeetCode

 


 

PS:關注微信公衆號「藍本本」,和我一起學習、進修和放縱好奇心。

題圖:Photo by Mohamed Khaled from Pexels.


 

 

Landon

——

學習、進修和放縱好奇心!

@  藍本本  

——

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章