網(wǎng)絡(luò)篇:朋友面試之TCP/IP,回去等通知吧
本文轉(zhuǎn)載自微信公眾號(hào)「潛行前行」,作者cscw。轉(zhuǎn)載本文請(qǐng)聯(lián)系潛行前行公眾號(hào)。
前言
最近和一同學(xué)聊天,他想換工作,然后去面了一家大廠。當(dāng)時(shí),他在簡歷上寫著精通TCP/IP,本著對(duì)TCP協(xié)議稍有了解,面試官也不會(huì)深問的想法,就寫了精通二字。沒想到,大意了
開場(chǎng)
朋友約的是十點(diǎn)半的面試,提前了十分鐘到,然后安靜地坐在沙發(fā)等待,順便回憶下之前看的資料??斓绞c(diǎn)半時(shí),一個(gè)高瘦,穿著格子衫的男子推開門而進(jìn),說了句“你好,我們來開始面試吧!”,朋友不失禮貌地笑著回了句“行”
面試官:看你簡歷說精通TCP和IP,那我們來討論下網(wǎng)絡(luò)模型和TCP、IP協(xié)議,講下你的理解先
- 朋友(怎么一上來就問TCP,不按套路出牌啊,不該問問java基礎(chǔ)嗎?不過常規(guī)題,我還行)
- 朋友:網(wǎng)絡(luò)模型一般分七層:應(yīng)用層、表示層、會(huì)話層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層、物理層。應(yīng)用層的協(xié)議包括HTTP、FTP、SMTP,而TCP屬于傳輸層,IP協(xié)議則屬于網(wǎng)絡(luò)層
- 朋友:TCP/IP網(wǎng)絡(luò)模型層次由上到下,層層包裝,每一層都對(duì)應(yīng)不同的協(xié)議解析,我來畫個(gè)圖
面試官:看你畫的圖,TCP有自己的首部結(jié)構(gòu),這都有哪些字段,最好說說它們的作用
- 朋友(什么鬼!當(dāng)我百度詞典,這怎么記得住?等等,昨天晚上好像看過,有印象)
- 朋友:繼續(xù)畫個(gè)圖,直觀點(diǎn)
- 朋友:TCP首部結(jié)構(gòu)先是16位的源端口號(hào)和目標(biāo)端口號(hào)、接著是32位的序列號(hào)和確認(rèn)號(hào)。再下面就是4bit的頭部長度和6個(gè)bit的保留位及6bit的標(biāo)志位
- 朋友:16位的屬性則有窗口大小(控制發(fā)送窗口),檢驗(yàn)和(校驗(yàn)數(shù)據(jù)段是否未被修改)及緊急指針。最后是選項(xiàng),其長度由頭部長度決定
- 朋友:詳細(xì)說下序列號(hào),它是TCP報(bào)文段的一數(shù)字編號(hào),為保證TCP可靠連接,每一個(gè)發(fā)送的數(shù)據(jù)段都要加上序列號(hào)。建立連接時(shí),兩端都會(huì)隨機(jī)生成一個(gè)初始序列號(hào)。而確認(rèn)號(hào)是和序列號(hào)配合使用的,應(yīng)答某次請(qǐng)求時(shí),則返回一個(gè)確認(rèn)號(hào),它的值等于對(duì)方請(qǐng)求序列號(hào)加1
- 朋友:而6個(gè)標(biāo)志位分別是,URG:這是條緊急信息,ACK:應(yīng)答消息,PSH:緩沖區(qū)尚未填滿,RST:重置連接,SYN:建立連接消息標(biāo)志,F(xiàn)IN:連接關(guān)閉通知信息
- 朋友:窗口大小是接收端用來控制發(fā)送端的滑動(dòng)窗口大小
面試官:那TCP和UDP有什么區(qū)別
- 朋友(松了一口氣)
- 朋友:1)連接方面:TCP面向連接。UDP是無連接的,發(fā)送數(shù)據(jù)之前不需要建立連接
- 朋友:2)安全方面:TCP提供可靠的服務(wù),保證傳送的數(shù)據(jù),無差錯(cuò),不丟失,不重復(fù),且按序到達(dá)。UDP則是盡最大努力交付,不保證可靠交付
- 朋友:3)傳輸效率:TCP傳輸效率相對(duì)較低,UDP傳輸效率高
面試官:剛才你說TCP是可靠的連接,它是怎么實(shí)現(xiàn)的
- 朋友:TCP的連接是基于三次握手,而斷開則是四次揮手
- 朋友:為了保障數(shù)據(jù)不丟失及錯(cuò)誤(可靠性),它有報(bào)文校驗(yàn)、ACK應(yīng)答、超時(shí)重傳(發(fā)送方)、失序數(shù)據(jù)重傳(接收方)、丟棄重復(fù)數(shù)據(jù)、流量控制(滑動(dòng)窗口)和擁塞控制等機(jī)制
面試官:具體說一說三次握手和四次揮手機(jī)制
- 朋友(又是常規(guī)題,曬曬水啦)
- 朋友:TCP是可靠的雙向通道,所以需要三次握手和四次揮手,我來畫個(gè)圖
- 三次握手
- 四次揮手
- 朋友:提前搶答下,關(guān)閉連接時(shí)需要四次揮手,比建立時(shí)多一次,是因?yàn)楸粍?dòng)關(guān)閉端或許還有數(shù)據(jù)沒被送出去,不能像握手時(shí)一樣,第二次握手既是發(fā)起握手也是響應(yīng)握手
面試官:如果沒有三次握手會(huì)有什么問題呢
- 朋友:如果只有兩次握手,client發(fā)連接請(qǐng)求后不會(huì)再ACK服務(wù)端的SYN
- 朋友:此時(shí)若客戶端因?yàn)樽陨碓蚺袛嘟⑦B接失敗,可能會(huì)重復(fù)建立TCP連接,而服務(wù)端卻會(huì)認(rèn)為那些被client丟棄的TCP還是有效,會(huì)白白浪費(fèi)資源
面試官:TIME_WAIT和CLOSE_WAIT的區(qū)別在哪
- 朋友:CLOSE_WAIT是被動(dòng)關(guān)閉形成的;當(dāng)對(duì)方close socket而發(fā)送FIN報(bào)文過來時(shí),回應(yīng)ACK之后進(jìn)入CLOSE_WAIT狀態(tài)。隨后檢查是否存在未傳輸數(shù)據(jù),如果沒有則發(fā)起第三次揮手,發(fā)送FIN報(bào)文給對(duì)方,進(jìn)入LAST_ACK狀態(tài)并等待對(duì)方ACK報(bào)文到來
- 朋友:TIME_WAIT是主動(dòng)關(guān)閉連接方式形成的;處于FIN_WAIT_2狀態(tài)時(shí),收到對(duì)方FIN報(bào)文后進(jìn)入TIME_WAIT狀態(tài);之后再等待兩個(gè)MSL(Maximum Segment Lifetime:報(bào)文最大生存時(shí)間)
面試官:TIME_WAIT的作用呢,還有為啥狀態(tài)時(shí)間要保持兩個(gè)MSL
- 朋友(這問得太深了吧,老哥。還好昨天偷偷補(bǔ)課了)
- 朋友:1)TIME_WAIT的作用是為了保證最后一次揮手的ACK報(bào)文能送達(dá)給對(duì)方,如果ACK丟失,對(duì)方會(huì)超時(shí)重傳FIN,主動(dòng)關(guān)閉端會(huì)再次響應(yīng)ACK過去;如果沒有TIME_WAIT狀態(tài),直接關(guān)閉,對(duì)方重傳的FIN報(bào)文則被響應(yīng)一個(gè)RST報(bào)文,此RST會(huì)被動(dòng)關(guān)閉端被解析成錯(cuò)誤
- 朋友:2)存在兩個(gè)連接,第一個(gè)連接正常關(guān)閉,第二相同的連接緊接著建立;如果第一個(gè)連接的迷路報(bào)文到來,則會(huì)干擾第二連接,等待兩個(gè)MSL則可以讓上次連接的報(bào)文數(shù)據(jù)消逝在網(wǎng)絡(luò)
面試官:剛才你還有提到擁塞控制,TCP協(xié)議用什么方式去解決擁塞的
- 朋友:第一方式是慢啟動(dòng)和擁塞避免
- 朋友:1)慢啟動(dòng),TCP發(fā)送端會(huì)維護(hù)一個(gè)擁塞窗口(congestionwindow),簡稱為cwnd。擁塞窗口初始為1個(gè)報(bào)文段,每經(jīng)過一次RTT(數(shù)據(jù)完全發(fā)送完到確認(rèn)的時(shí)間),窗口大小翻倍(指數(shù)增長,只是前期慢)
- 朋友:2)擁塞避免,它思路是讓擁塞窗口cwnd緩慢增大,發(fā)送方的cwnd達(dá)到閥值ssthresh(初始值由系統(tǒng)決定的)之后,每經(jīng)過一個(gè)RTT就把擁塞窗口加一,而不是加倍(收到兩個(gè)或四個(gè)確認(rèn),都是cwnd+1),cwnd呈線性增加(加法增大)
- 朋友:(畫個(gè)圖好解析)
- 朋友:如果遇到網(wǎng)絡(luò)擁塞,擁塞窗口閥值ssthresh減半,cwnd設(shè)置為1,重新進(jìn)入慢啟動(dòng)階段
面試官:那擁塞控制還有其他什么方式呢
- 朋友:快重傳和快恢復(fù)
- 朋友:1)快重傳是當(dāng)接收方收到了一個(gè)失序的報(bào)文,則立馬報(bào)告給發(fā)送方,趕緊重傳
- 朋友:假如接收方M1收到了,M2沒有收到,之后的M3、M4、M5又發(fā)送了,此時(shí)接收方一共連續(xù)給發(fā)送方反饋了3個(gè)M1確認(rèn)報(bào)文。那么快重傳規(guī)定,發(fā)送方只要連續(xù)收到3個(gè)重復(fù)確認(rèn),立即重傳對(duì)方發(fā)來的M2(重復(fù)確認(rèn)報(bào)文的后一個(gè)報(bào)文)
- 朋友:2)快恢復(fù)
- 朋友:當(dāng)發(fā)送方連續(xù)收到三個(gè)重復(fù)確認(rèn),ssthresh減半;由于發(fā)送方可能認(rèn)為網(wǎng)絡(luò)現(xiàn)在沒有擁塞,因此與慢啟動(dòng)不同,把cwnd值設(shè)置為ssthresh減半之后的值,然后執(zhí)行擁塞避免算法,cwnd線性增大
- 朋友:(再來一圖)
面試官:知道滑動(dòng)窗口不,客戶端和服務(wù)端控制滑動(dòng)窗口的過程是怎樣的
- 朋友:接收端將自己可以接收的緩沖區(qū)大小放入TCP首部中的“窗口大小”字段,通過ACK報(bào)文來通知發(fā)送端,滑動(dòng)窗口是接收端用來控制發(fā)送端發(fā)送數(shù)據(jù)的大小,從而達(dá)到流量控制
- 朋友:其實(shí)發(fā)送方的窗口上限,是取值擁塞窗口和滑動(dòng)窗口兩者的最小值
面試官:那你知道滑動(dòng)窗口和擁塞窗口有什么區(qū)別不
- 朋友:相同點(diǎn)都是控制丟包現(xiàn)象,實(shí)現(xiàn)機(jī)制都是讓發(fā)送方發(fā)得慢一點(diǎn)
- 朋友:不同點(diǎn)在于控制的對(duì)象不同
- 朋友:1)流量控制的對(duì)象是接收方,怕發(fā)送方發(fā)的太快,使得接收方來不及處理
- 朋友:2)擁塞控制的對(duì)象是網(wǎng)絡(luò),怕發(fā)送方發(fā)的太快,造成網(wǎng)絡(luò)擁塞,使得網(wǎng)絡(luò)來不及處理
面試官:TCP的粘包和拆包問題,你怎么看
- 朋友:程序需要發(fā)送的數(shù)據(jù)大小和TCP報(bào)文段能發(fā)送MSS(Maximum Segment Size,最大報(bào)文長度)是不一樣的
- 朋友:大于MSS時(shí),而需要把程序數(shù)據(jù)拆分為多個(gè)TCP報(bào)文段,稱之為拆包;小于時(shí),則會(huì)考慮合并多個(gè)程序數(shù)據(jù)為一個(gè)TCP報(bào)文段,則是粘包;其中MSS = TCP報(bào)文段長度-TCP首部長度
- 朋友:在IP協(xié)議層或者鏈路層、物理層,都存在拆包、粘包現(xiàn)象
面試官:那解決粘包和拆包的方法都有哪些?
- 朋友:1)在數(shù)據(jù)尾部增加特殊字符進(jìn)行分割
- 朋友:2)將數(shù)據(jù)定為固定大小
- 朋友:3)將數(shù)據(jù)分為兩部分,一部分是頭部,一部分是內(nèi)容體;其中頭部結(jié)構(gòu)大小固定,且有一個(gè)字段聲明內(nèi)容體的大小
面試官:SYN Flood了解嗎
- 朋友:SYN Flood 偽造 SYN 報(bào)文向服務(wù)器發(fā)起連接,服務(wù)器在收到報(bào)文后用 SYN_ACK 應(yīng)答,此應(yīng)答發(fā)出去后,不會(huì)收到 ACK 報(bào)文,造成一個(gè)半連接
- 朋友:若攻擊者發(fā)送大量這樣的報(bào)文,會(huì)在被攻擊主機(jī)上出現(xiàn)大量的半連接,耗盡其資源,使正常的用戶無法訪問,直到半連接超時(shí)
面試官:對(duì)TCP的掌握挺不錯(cuò)的,下面問下HTTP的知識(shí)。你知道一次HTTP請(qǐng)求,程序一般經(jīng)歷了哪幾個(gè)步驟?
- 朋友:1)解析域名 -> 2)發(fā)起TCP三次握手,建立連接 -> 3)基于TCP發(fā)起HTTP請(qǐng)求 -> 4)服務(wù)器響應(yīng)HTTP請(qǐng)求,并返回?cái)?shù)據(jù) -> 5)客戶端解析返回?cái)?shù)據(jù)
面試官:HTTP有哪幾種響應(yīng)狀態(tài)碼,列舉幾個(gè)你熟悉的
- 朋友:大概有以下幾種
- 200:表示成功正常請(qǐng)求
- 400:語義有誤,一般是請(qǐng)求格式不對(duì)
- 401:需求用戶驗(yàn)證權(quán)限,一般是證書token沒通過認(rèn)證
- 403:拒絕提供服務(wù)
- 404:資源不存在
- 500:服務(wù)器錯(cuò)誤
- 503:服務(wù)器臨時(shí)維護(hù),過載;可恢復(fù)
面試官:不錯(cuò),再考考你,session和cookie有什么區(qū)別
- 朋友:1)存儲(chǔ)位置不同,cookie是保存在客戶端的數(shù)據(jù);session的數(shù)據(jù)存放在服務(wù)器上
- 朋友:2)存儲(chǔ)容量不同,單個(gè)cookie保存的數(shù)據(jù)小,一個(gè)站點(diǎn)最多保存20個(gè)Cookie;對(duì)于session來說并沒有上限
- 朋友:3)存儲(chǔ)方式不同,cookie中只能保管ASCII字符串;session中能夠存儲(chǔ)任何類型的數(shù)據(jù)
- 朋友:4)隱私策略不同,cookie對(duì)客戶端是可見的;session存儲(chǔ)在服務(wù)器上,對(duì)客戶端是透明對(duì)
- 朋友:5)有效期上不同,cookie可以長期有效存在;session依賴于名為JSESSIONID的cookie,過期時(shí)間默認(rèn)為-1,只需關(guān)閉窗口該session就會(huì)失效
- 朋友:6)跨域支持上不同,cookie支持跨域名訪問;session不支持跨域名訪問
面試官:不錯(cuò),那你了解什么是HTTP分塊傳送嗎
- 朋友:分塊傳送是HTTP的一種傳輸機(jī)制,允許服務(wù)端發(fā)送給客戶端的數(shù)據(jù)分成多個(gè)部分,該協(xié)議在HTTP/1.1提供
面試官:HTTP分塊傳送有什么好處
- 朋友:HTTP分塊傳輸編碼允許服務(wù)器為動(dòng)態(tài)生成的內(nèi)容維持HTTP持久連接
- 朋友:分塊傳輸編碼允許服務(wù)器在最后發(fā)送消息頭字段。對(duì)于那些頭字段值在內(nèi)容被生成之前無法知道的情形非常重要,例如消息的內(nèi)容要使用散列進(jìn)行簽名
- 朋友:HTTP服務(wù)器有時(shí)使用壓縮 (gzip或deflate)以縮短傳輸花費(fèi)的時(shí)間。分塊傳輸編碼可以用來分隔壓縮對(duì)象的多個(gè)部分。在這種情況下,塊不是分別壓縮的,而是整個(gè)負(fù)載進(jìn)行壓縮。分塊編碼有利于一邊進(jìn)行壓縮一邊發(fā)送數(shù)據(jù)
面試官:HTTP的長連接你怎么理解
- 朋友:長連接是指客戶端和服務(wù)建立TCP連接后,它們之間的連接會(huì)持續(xù)存在,不會(huì)因?yàn)橐淮蜨TTP請(qǐng)求后關(guān)閉,后續(xù)的請(qǐng)求也是用這個(gè)連接
- 朋友:長連接可以省去TCP的建立和關(guān)閉操作,對(duì)于頻繁請(qǐng)求的客戶端適合使用長連接,但是注意惡意的長連接導(dǎo)致服務(wù)受損(建議內(nèi)部服務(wù)之間使用)
面試官:HTTP是安全的嗎?怎么做到安全的HTTP協(xié)議傳輸
- 朋友:并非安全,HTTP傳輸?shù)臄?shù)據(jù)都是明文的,容易被第三方截取;要做安全傳輸數(shù)據(jù),可以使用HTTP的升級(jí)版HTTPS協(xié)議
面試官:HTTPS和HTTP的區(qū)別,你是怎么理解的
- 朋友:1)http協(xié)議的連接是無狀態(tài)的,明文傳輸
- 朋友:2)HTTPS則是由SSL/TLS+HTTP協(xié)議構(gòu)建的有加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議
面試官:SSL/TLS是什么,HTTPS的安全性是怎樣實(shí)現(xiàn)的?
- 朋友:SSL(Secure Socket Layer 安全套接層)是基于HTTPS下的一個(gè)協(xié)議加密層,保障數(shù)據(jù)私密性。TLS(Transport Layer Security)則是升級(jí)版的SSL
- 朋友:https在http基礎(chǔ)加了一層安全認(rèn)證及加密層TLS或者SSL,它首先會(huì)通過安全層進(jìn)行ca證書認(rèn)證,正確獲取服務(wù)端的公鑰
- 朋友:接著客戶端會(huì)通過公鑰和服務(wù)端確認(rèn)一種加密算法,后面的數(shù)據(jù)則可以使用該加密算法對(duì)數(shù)據(jù)進(jìn)行加密