網路篇:朋友面試之TCP/IP,回去等通知吧

cscw發表於2020-11-29

前言

最近和一同學聊天,他想換工作,然後去面了一家大廠。當時,他在簡歷上寫著精通TCP/IP,本著對TCP協議稍有了解,面試官也不會深問的想法,就寫了精通二字。沒想到,大意了

關注公眾號,一起交流,微信搜一搜: 潛行前行

開場

朋友約的是十點半的面試,提前了十分鐘到,然後安靜地坐在沙發等待,順便回憶下之前看的資料。快到十點半時,一個高瘦,穿著格子衫的男子推開門而進,說了句“你好,我們來開始面試吧!”,朋友不失禮貌地笑著回了句“行”

面試官:看你簡歷說精通TCP和IP,那我們來討論下網路模型和TCP、IP協議,講下你的理解先

  • 朋友(怎麼一上來就問TCP,不按套路出牌啊,不該問問java基礎嗎?不過常規題,我還行)
  • 朋友:網路模型一般分七層:應用層、表示層、會話層、傳輸層、網路層、資料鏈路層、物理層。應用層的協議包括HTTP、FTP、SMTP,而TCP屬於傳輸層,IP協議則屬於網路層
  • 朋友:TCP/IP網路模型層次由上到下,層層包裝,每一層都對應不同的協議解析,我來畫個圖

面試官:看你畫的圖,TCP有自己的首部結構,這都有哪些欄位,最好說說它們的作用

  • 朋友(什麼鬼!當我百度詞典,這怎麼記得住?等等,昨天晚上好像看過,有印象)
  • 朋友:繼續畫個圖,直觀點
  • 朋友:TCP首部結構先是16位的源埠號和目標埠號、接著是32位的序列號和確認號。再下面就是4bit的頭部長度和6個bit的保留位及6bit的標誌位
  • 朋友:16位的屬性則有視窗大小(控制傳送視窗),檢驗和(校驗資料段是否未被修改)及緊急指標。最後是選項,其長度由頭部長度決定
  • 朋友:詳細說下序列號,它是TCP報文段的一數字編號,為保證TCP可靠連線,每一個傳送的資料段都要加上序列號。建立連線時,兩端都會隨機生成一個初始序列號。而確認號而是和序列號配合使用的,應答某次請求時,則返回一個確認號,它的值等於對方請求序列號加1
  • 朋友:而6個標誌位分別是,URG:這是條緊急資訊,ACK:應答訊息,PSH:緩衝區尚未填滿,RST:重置連線,SYN:建立連線訊息標誌,FIN:連線關閉通知資訊
  • 朋友:視窗大小是接收端用來控制傳送端的滑動視窗大小

面試官:那TCP和UDP有什麼區別

  • 朋友(鬆了一口氣)
  • 朋友:1)連線方面:TCP面向連線。UDP是無連線的,傳送資料之前不需要建立連線
  • 朋友:2)安全方面:TCP提供可靠的服務,保證傳送的資料,無差錯,不丟失,不重複,且按序到達。UDP則是盡最大努力交付,不保證可靠交付
  • 朋友:3)傳輸效率:TCP傳輸效率相對較低,UDP傳輸效率高

面試官:剛才你說TCP是可靠的連線,它是怎麼實現的

  • 朋友:TCP的連線是基於三次握手,而斷開則是四次揮手
  • 朋友:為了保障資料不丟失及錯誤(可靠性),它有報文校驗、ACK應答、超時重傳(傳送方)、失序資料重傳(接收方)、丟棄重複資料、流量控制(滑動視窗)和擁塞控制等機制

面試官:具體說一說三次握手和四次揮手機制

  • 朋友(又是常規題,曬曬水啦)
  • 朋友:TCP是可靠的雙向通道,所以需要三次握手和四次揮手,我來畫個圖
  • 三次握手
  • 四次揮手
  • 朋友:提前搶答下,關閉連線時需要四次揮手,比建立時多一次,是因為被動關閉端或許還有資料沒被送出去,不能像握手時一樣,第二次握手既是發起握手也是響應握手

面試官:如果沒有三次握手會有什麼問題呢

  • 朋友:如果只有兩次握手,client發連線請求後不會再ACK服務端的SYN
  • 朋友:此時若客戶端因為自身原因判斷建立連線失敗,可能會重複建立TCP連線,而服務端卻會認為那些被client丟棄的TCP還是有效,會白白浪費資源

面試官:TIME_WAIT和CLOSE_WAIT的區別在哪

  • 朋友:CLOSE_WAIT是被動關閉形成的;當對方close socket而傳送FIN報文過來時,回應ACK之後進入CLOSE_WAIT狀態。隨後檢查是否存在未傳輸資料,如果沒有則發起第三次揮手,傳送FIN報文給對方,進入LAST_ACK狀態並等待對方ACK報文到來
  • 朋友:TIME_WAIT是主動關閉連線方式形成的;處於FIN_WAIT_2狀態時,收到對方FIN報文後進入TIME_WAIT狀態;之後再等待兩個MSL(Maximum Segment Lifetime:報文最大生存時間)

面試官:TIME_WAIT的作用呢,還有為啥狀態時間要保持兩個MSL

  • 朋友(這問得太深了吧,老哥。還好昨天偷偷補課了)
  • 朋友:1)TIME_WAIT的作用是為了保證最後一次揮手的ACK報文能送達給對方,如果ACK丟失,對方會超時重傳FIN,主動關閉端會再次響應ACK過去;如果沒有TIME_WAIT狀態,直接關閉,對方重傳的FIN報文則被響應一個RST報文,此RST會被動關閉端被解析成錯誤
  • 朋友:2)存在兩個連線,第一個連線正常關閉,第二相同的連線緊接著建立;如果第一個連線的迷路報文到來,則會干擾第二連線,等待兩個MSL則可以讓上次連線的報文資料消逝在網路後

面試官:剛才你還有提到擁塞控制,TCP協議用什麼方式去解決擁塞的

  • 朋友:第一方式是慢啟動和擁塞避免
  • 朋友:1)慢啟動,TCP傳送端會維護一個擁塞視窗(congestionwindow),簡稱為cwnd。擁塞視窗初始為1個報文段,每經過一次RTT(資料完全傳送完到確認的時間),視窗大小翻倍(指數增長,只是前期慢)
  • 朋友:2)擁塞避免,它思路是讓擁塞視窗cwnd緩慢增大,傳送方的cwnd達到閥值ssthresh(初始值由系統決定的)之後,每經過一個RTT就把擁塞視窗加一,而不是加倍(收到兩個或四個確認,都是cwnd+1),cwnd呈線性增加(加法增大)
  • 朋友:(畫個圖好解析)
  • 朋友:如果遇到網路擁塞,擁塞視窗閥值ssthresh減半,cwnd設定為1,重新進入慢啟動階段

面試官:那擁塞控制還有其他什麼方式呢

  • 朋友:快重傳和快恢復
  • 朋友:1)快重傳是當接收方收到了一個失序的報文,則立馬報告給傳送方,趕緊重傳
  • 朋友:假如接收方M1收到了,M2沒有收到,之後的M3、M4、M5又傳送了,此時接收方一共連續給傳送方反饋了3個M1確認報文。那麼快重傳規定,傳送方只要連續收到3個重複確認,立即重傳對方發來的M2(重複確認報文的後一個報文)
  • 朋友:2)快恢復
  • 朋友:當傳送方連續收到三個重複確認,ssthresh減半;由於傳送方可能認為網路現在沒有擁塞,因此與慢啟動不同,把cwnd值設定為ssthresh減半之後的值,然後執行擁塞避免演算法,cwnd線性增大
  • 朋友:(再來一圖)

面試官:知道滑動視窗不,客戶端和服務端控制滑動視窗的過程是怎樣的

  • 朋友:接收端將自己可以接收的緩衝區大小放入TCP首部中的“視窗大小”欄位,通過ACK報文來通知傳送端,滑動視窗是接收端用來控制傳送端傳送資料的大小,從而達到流量控制
  • 朋友:其實傳送方的視窗上限,是取值擁塞視窗和滑動視窗兩者的最小值

面試官:那你知道滑動視窗和擁塞視窗有什麼區別不

  • 朋友:相同點都是控制丟包現象,實現機制都是讓傳送方發得慢一點
  • 朋友:不同點在於控制的物件不同
  • 朋友:1)流量控制的物件是接收方,怕傳送方發的太快,使得接收方來不及處理
  • 朋友:2)擁塞控制的物件是網路,怕傳送方發的太快,造成網路擁塞,使得網路來不及處理

面試官:TCP的粘包和拆包問題,你怎麼看

  • 朋友:程式需要傳送的資料大小和TCP報文段能傳送MSS(Maximum Segment Size,最大報文長度)是不一樣的
  • 朋友:大於MSS時,而需要把程式資料拆分為多個TCP報文段,稱之為拆包;小於時,則會考慮合併多個程式資料為一個TCP報文段,則是粘包;其中MSS = TCP報文段長度-TCP首部長度
  • 朋友:在IP協議層或者鏈路層、物理層,都存在拆包、粘包現象

面試官:那解決粘包和拆包的方法都有哪些?

  • 朋友:1)在資料尾部增加特殊字元進行分割
  • 朋友:2)將資料定為固定大小
  • 朋友:3)將資料分為兩部分,一部分是頭部,一部分是內容體;其中頭部結構大小固定,且有一個欄位宣告內容體的大小

面試官:SYN Flood瞭解嗎

  • 朋友:SYN Flood 偽造 SYN 報文向伺服器發起連線,伺服器在收到報文後用 SYN_ACK 應答,此應答發出去後,不會收到 ACK 報文,造成一個半連線
  • 朋友:若攻擊者傳送大量這樣的報文,會在被攻擊主機上出現大量的半連線,耗盡其資源,使正常的使用者無法訪問,直到半連線超時

面試官:對TCP的掌握挺不錯的,下面問下HTTP的知識。你知道一次HTTP請求,程式一般經歷了哪幾個步驟?

  • 朋友:1)解析域名 -> 2)發起TCP三次握手,建立連線 -> 3)基於TCP發起HTTP請求 -> 4)伺服器響應HTTP請求,並返回資料 -> 5)客戶端解析返回資料

面試官:HTTP有哪幾種響應狀態碼,列舉幾個你熟悉的

  • 朋友:大概有以下幾種
    • 200:表示成功正常請求
    • 400:語義有誤,一般是請求格式不對
    • 401:需求使用者驗證許可權,一般是證照token沒通過認證
    • 403:拒絕提供服務
    • 404:資源不存在
    • 500:伺服器錯誤
    • 503:伺服器臨時維護,過載;可恢復

面試官:不錯,再考考你,session和cookie有什麼區別

  • 朋友:1)儲存位置不同,cookie是儲存在客戶端的資料;session的資料存放在伺服器上
  • 朋友:2)儲存容量不同,單個cookie儲存的資料小,一個站點最多儲存20個Cookie;對於session來說並沒有上限
  • 朋友:3)儲存方式不同,cookie中只能保管ASCII字串;session中能夠儲存任何型別的資料
  • 朋友:4)隱私策略不同,cookie對客戶端是可見的;session儲存在伺服器上,對客戶端是透明對
  • 朋友:5)有效期上不同,cookie可以長期有效存在;session依賴於名為JSESSIONID的cookie,過期時間預設為-1,只需關閉視窗該session就會失效
  • 朋友:6)跨域支援上不同,cookie支援跨域名訪問;session不支援跨域名訪問

面試官:不錯,那你瞭解什麼是HTTP分塊傳送嗎

  • 朋友:分塊傳送是HTTP的一種傳輸機制,允許服務端傳送給客戶端的資料分成多個部分,該協議在HTTP/1.1提供

面試官:HTTP分塊傳送有什麼好處

  • 朋友:HTTP分塊傳輸編碼允許伺服器為動態生成的內容維持HTTP持久連線
  • 朋友:分塊傳輸編碼允許伺服器在最後傳送訊息頭欄位。對於那些頭欄位值在內容被生成之前無法知道的情形非常重要,例如訊息的內容要使用雜湊進行簽名
  • 朋友:HTTP伺服器有時使用壓縮 (gzip或deflate)以縮短傳輸花費的時間。分塊傳輸編碼可以用來分隔壓縮物件的多個部分。在這種情況下,塊不是分別壓縮的,而是整個負載進行壓縮。分塊編碼有利於一邊進行壓縮一邊傳送資料

面試官:HTTP的長連線你怎麼理解

  • 朋友:長連線是指客戶端和服務建立TCP連線後,它們之間的連線會持續存在,不會因為一次HTTP請求後關閉,後續的請求也是用這個連線
  • 朋友:長連線可以省去TCP的建立和關閉操作,對於頻繁請求的客戶端適合使用長連線,但是注意惡意的長連線導致服務受損(建議內部服務之間使用)

面試官:HTTP是安全的嗎?怎麼做到安全的HTTP協議傳輸

  • 朋友:並非安全,HTTP傳輸的資料都是明文的,容易被第三方擷取;要做安全傳輸資料,可以使用HTTP的升級版HTTPS協議

面試官:HTTPS和HTTP的區別,你是怎麼理解的

  • 朋友:1)http協議的連線是無狀態的,明文傳輸
  • 朋友:2)HTTPS則是由SSL/TLS+HTTP協議構建的有加密傳輸、身份認證的網路協議

面試官:SSL/TLS是什麼,HTTPS的安全性是怎樣實現的?

  • 朋友:SSL(Secure Socket Layer 安全套接層)是基於HTTPS下的一個協議加密層,保障資料私密性。TLS(Transport Layer Security)則是升級版的SSL
  • 朋友:https在http基礎加了一層安全認證及加密層TLS或者SSL,它首先會通過安全層進行ca證照認證,正確獲取服務端的公鑰
  • 朋友:接著客戶端會通過公鑰和服務端確認一種加密演算法,後面的資料則可以使用該加密演算法對資料進行加密

面試官:你能詳細說下TLS/SSL的認證過程不...(此時面試官放在桌面的手機震動了起來,他下意識看了看手機,停頓下)

朋友面試暫時告一段落(下回繼續)

歡迎指正文中錯誤

參考文章

相關文章