注意:每道題前面出現(xiàn)的 (xx) 數(shù)字代表這道題出現(xiàn)的頻次,此 計(jì)算機(jī)網(wǎng)絡(luò) 基礎(chǔ)是基于 30+ 篇前端面經(jīng)整理出的問(wèn)題和對(duì)應(yīng)的回答、參考鏈接等。文章內(nèi)容為拿到 Offer 的本人整理。
(3)問(wèn):HTTP 緩存
HTTP 緩存又分為強(qiáng)緩存和協(xié)商緩存:
- 首先通過(guò) Cache-Control 驗(yàn)證強(qiáng)緩存是否可用,如果強(qiáng)緩存可用,那么直接讀取緩存
- 如果不可以,那么進(jìn)入?yún)f(xié)商緩存階段,發(fā)起 HTTP 請(qǐng)求,服務(wù)器通過(guò)請(qǐng)求頭中是否帶上 If-Modified-Since 和 If-None-Match 這些條件請(qǐng)求字段檢查資源是否更新:
- 若資源更新,那么返回資源和 200 狀態(tài)碼
- 如果資源未更新,那么告訴瀏覽器直接使用緩存獲取資源
(5)問(wèn):HTTP 常用的狀態(tài)碼及使用場(chǎng)景?
- 1xx:表示目前是協(xié)議的中間狀態(tài),還需要后續(xù)請(qǐng)求
- 2xx:表示請(qǐng)求成功
- 3xx:表示重定向狀態(tài),需要重新請(qǐng)求
- 4xx:表示請(qǐng)求報(bào)文錯(cuò)誤
- 5xx:服務(wù)器端錯(cuò)誤
常用狀態(tài)碼:
- 101 切換請(qǐng)求協(xié)議,從 HTTP 切換到 WebSocket
- 200 請(qǐng)求成功,有響應(yīng)體
- 301 永久重定向:會(huì)緩存
- 302 臨時(shí)重定向:不會(huì)緩存
- 304 協(xié)商緩存命中
- 403 服務(wù)器禁止訪問(wèn)
- 404 資源未找到
- 400 請(qǐng)求錯(cuò)誤
- 500 服務(wù)器端錯(cuò)誤
- 503 服務(wù)器繁忙
你知道 302 狀態(tài)碼是什么嘛?你平時(shí)瀏覽網(wǎng)頁(yè)的過(guò)程中遇到過(guò)哪些 302 的場(chǎng)景?
而 302 表示臨時(shí)重定向,這個(gè)資源只是暫時(shí)不能被訪問(wèn)了,但是之后過(guò)一段時(shí)間還是可以繼續(xù)訪問(wèn),一般是訪問(wèn)某個(gè)網(wǎng)站的資源需要權(quán)限時(shí),會(huì)需要用戶去登錄,跳轉(zhuǎn)到登錄頁(yè)面之后登錄之后,還可以繼續(xù)訪問(wèn)。
301 類似,都會(huì)跳轉(zhuǎn)到一個(gè)新的網(wǎng)站,但是 301 代表訪問(wèn)的地址的資源被永久移除了,以后都不應(yīng)該訪問(wèn)這個(gè)地址,搜索引擎抓取的時(shí)候也會(huì)用新的地址替換這個(gè)老的。可以在返回的響應(yīng)的 location 首部去獲取到返回的地址。301 的場(chǎng)景如下:
- 比如從 http://baidu.com,跳轉(zhuǎn)到 https://baidu.com
- 域名換了
(2)問(wèn):HTTP 常用的請(qǐng)求方式,區(qū)別和用途?
http/1.1 規(guī)定如下請(qǐng)求方法:
- GET:通用獲取數(shù)據(jù)
- HEAD:獲取資源的元信息
- POST:提交數(shù)據(jù)
- PUT:修改數(shù)據(jù)
- DELETE:刪除數(shù)據(jù)
- CONNECT:建立連接隧道,用于代理服務(wù)器
- OPTIONS:列出可對(duì)資源實(shí)行的請(qǐng)求方法,常用于跨域
- TRACE:追蹤請(qǐng)求-響應(yīng)的傳輸路徑
()問(wèn):你對(duì)計(jì)算機(jī)網(wǎng)絡(luò)的認(rèn)識(shí)怎么樣
應(yīng)用層、表示層、會(huì)話層、傳輸層、網(wǎng)絡(luò)層、數(shù)據(jù)鏈路層、物理層
(3)問(wèn):HTTPS 是什么?具體流程
HTTPS 是在 HTTP 和 TCP 之間建立了一個(gè)安全層,HTTP 與 TCP 通信的時(shí)候,必須先進(jìn)過(guò)一個(gè)安全層,對(duì)數(shù)據(jù)包進(jìn)行加密,然后將加密后的數(shù)據(jù)包傳送給 TCP,相應(yīng)的 TCP 必須將數(shù)據(jù)包解密,才能傳給上面的 HTTP。
瀏覽器傳輸一個(gè) client_random 和加密方法列表,服務(wù)器收到后,傳給瀏覽器一個(gè) server_random、加密方法列表和數(shù)字證書(包含了公鑰),然后瀏覽器對(duì)數(shù)字證書進(jìn)行合法驗(yàn)證,如果驗(yàn)證通過(guò),則生成一個(gè) pre_random,然后用公鑰加密傳給服務(wù)器,服務(wù)器用 client_random、server_random 和 pre_random ,使用公鑰加密生成 secret,然后之后的傳輸使用這個(gè) secret 作為秘鑰來(lái)進(jìn)行數(shù)據(jù)的加解密。
(4)問(wèn):三次握手和四次揮手
為什么要進(jìn)行三次握手:為了確認(rèn)對(duì)方的發(fā)送和接收能力。
三次握手
三次握手主要流程:
- 一開始雙方處于 CLOSED 狀態(tài),然后服務(wù)端開始監(jiān)聽某個(gè)端口進(jìn)入 LISTEN 狀態(tài)
- 然后客戶端主動(dòng)發(fā)起連接,發(fā)送 SYN,然后自己變?yōu)?SYN-SENT,seq = x
- 服務(wù)端收到之后,返回 SYN seq = y 和 ACK ack = x + 1(對(duì)于客戶端發(fā)來(lái)的 SYN),自己變成 SYN-REVD
- 之后客戶端再次發(fā)送 ACK seq = x + 1, ack = y + 1給服務(wù)端,自己變成 EASTABLISHED 狀態(tài),服務(wù)端收到 ACK,也進(jìn)入 ESTABLISHED
SYN 需要對(duì)端確認(rèn),所以 ACK 的序列化要加一,凡是需要對(duì)端確認(rèn)的,一點(diǎn)要消耗 TCP 報(bào)文的序列化
為什么不是兩次?
無(wú)法確認(rèn)客戶端的接收能力。
如果首先客戶端發(fā)送了 SYN 報(bào)文,但是滯留在網(wǎng)絡(luò)中,TCP 以為丟包了,然后重傳,兩次握手建立了連接。
等到客戶端關(guān)閉連接了。但是之后這個(gè)包如果到達(dá)了服務(wù)端,那么服務(wù)端接收到了,然后發(fā)送相應(yīng)的數(shù)據(jù)表,就建立了鏈接,但是此時(shí)客戶端已經(jīng)關(guān)閉連接了,所以帶來(lái)了鏈接資源的浪費(fèi)。
為什么不是四次?
四次以上都可以,只不過(guò) 三次就夠了
四次揮手
- 一開始都處于 ESTABLISH 狀態(tài),然后客戶端發(fā)送 FIN 報(bào)文,帶上 seq = p,狀態(tài)變?yōu)?FIN-WAIT-1
- 服務(wù)端收到之后,發(fā)送 ACK 確認(rèn),ack = p + 1,然后進(jìn)入 CLOSE-WAIT 狀態(tài)
- 客戶端收到之后進(jìn)入 FIN-WAIT-2 狀態(tài)
- 過(guò)了一會(huì)等數(shù)據(jù)處理完,再次發(fā)送 FIN、ACK,seq = q,ack = p + 1,進(jìn)入 LAST-ACK 階段
- 客戶端收到 FIN 之后,客戶端收到之后進(jìn)入 TIME_WAIT(等待 2MSL),然后發(fā)送 ACK 給服務(wù)端 ack = 1 + 1
- 服務(wù)端收到之后進(jìn)入 CLOSED 狀態(tài)
客戶端這個(gè)時(shí)候還需要等待兩次 MSL 之后,如果沒(méi)有收到服務(wù)端的重發(fā)請(qǐng)求,就表明 ACK 成功到達(dá),揮手結(jié)束,客戶端變?yōu)?CLOSED 狀態(tài),否則進(jìn)行 ACK 重發(fā)
為什么需要等待 2MSL(Maximum Segement Lifetime):
因?yàn)槿绻坏却脑挘绻?wù)端還有很多數(shù)據(jù)包要給客戶端發(fā),且此時(shí)客戶端端口被新應(yīng)用占據(jù),那么就會(huì)接收到無(wú)用的數(shù)據(jù)包,造成數(shù)據(jù)包混亂,所以說(shuō)最保險(xiǎn)的方法就是等服務(wù)器發(fā)來(lái)的數(shù)據(jù)包都死翹翹了再啟動(dòng)新應(yīng)用。
- 1個(gè) MSL 保證四次揮手中主動(dòng)關(guān)閉方最后的 ACK 報(bào)文能最終到達(dá)對(duì)端
- 1個(gè) MSL 保證對(duì)端沒(méi)有收到 ACK 那么進(jìn)行重傳的 FIN 報(bào)文能夠到達(dá)
為什么是四次而不是三次?
** 如果是三次的話,那么服務(wù)端的 ACK 和 FIN 合成一個(gè)揮手,那么長(zhǎng)時(shí)間的延遲可能讓 TCP 一位 FIN 沒(méi)有達(dá)到服務(wù)器端,然后讓客戶的不斷的重發(fā) FIN
參考資料
https://zhuanlan.zhihu.com/p/86426969
問(wèn):在交互過(guò)程中如果數(shù)據(jù)傳送完了,還不想斷開連接怎么辦,怎么維持?
在 HTTP 中響應(yīng)體的 Connection 字段指定為 keep-alive
你對(duì) TCP 滑動(dòng)窗口有了解嗎?
在 TCP 鏈接中,對(duì)于發(fā)送端和接收端而言,TCP 需要把發(fā)送的數(shù)據(jù)放到發(fā)送緩存區(qū), 將接收的數(shù)據(jù)放到接收緩存區(qū)。而經(jīng)常會(huì)存在發(fā)送端發(fā)送過(guò)多,而接收端無(wú)法消化的情況,所以就需要流量控制,就是在通過(guò)接收緩存區(qū)的大小,控制發(fā)送端的發(fā)送。如果對(duì)方的接收緩存區(qū)滿了,就不能再繼續(xù)發(fā)送了。而這種流量控制的過(guò)程就需要在發(fā)送端維護(hù)一個(gè)發(fā)送窗口,在接收端維持一個(gè)接收窗口。
TCP 滑動(dòng)窗口分為兩種: 發(fā)送窗口和接收窗口。
參考資料
https://juejin.im/post/5e527c58e51d4526c654bf41#heading-38
問(wèn):WebSocket與Ajax的區(qū)別
本質(zhì)不同
Ajax 即異步 JavaScript 和 XML,是一種創(chuàng)建交互式網(wǎng)頁(yè)的應(yīng)用的網(wǎng)頁(yè)開發(fā)技術(shù)
websocket 是 HTML5 的一種新協(xié)議,實(shí)現(xiàn)了瀏覽器和服務(wù)器的實(shí)時(shí)通信
生命周期不同:
- websocket 是長(zhǎng)連接,會(huì)話一直保持
- ajax 發(fā)送接收之后就會(huì)斷開
適用范圍:
- websocket 用于前后端實(shí)時(shí)交互數(shù)據(jù)
- ajax 非實(shí)時(shí)
發(fā)起人:
- AJAX 客戶端發(fā)起
- WebSocket 服務(wù)器端和客戶端相互推送
了解 WebSocket嗎?
長(zhǎng)輪詢和短輪詢,WebSocket 是長(zhǎng)輪詢。
具體比如在一個(gè)電商場(chǎng)景,商品的庫(kù)存可能會(huì)變化,所以需要及時(shí)反映給用戶,所以客戶端會(huì)不停的發(fā)請(qǐng)求,然后服務(wù)器端會(huì)不停的去查變化,不管變不變,都返回,這個(gè)是短輪詢。
而長(zhǎng)輪詢則表現(xiàn)為如果沒(méi)有變,就不返回,而是等待變或者超時(shí)(一般是十幾秒)才返回,如果沒(méi)有返回,客戶端也不需要一直發(fā)請(qǐng)求,所以減少了雙方的壓力。
參考鏈接
https://www.jianshu.com/p/3fc3646fad80
HTTP 如何實(shí)現(xiàn)長(zhǎng)連接?在什么時(shí)候會(huì)超時(shí)?
通過(guò)在頭部(請(qǐng)求和響應(yīng)頭)設(shè)置 Connection: keep-alive,HTTP1.0協(xié)議支持,但是默認(rèn)關(guān)閉,從HTTP1.1協(xié)議以后,連接默認(rèn)都是長(zhǎng)連接
- HTTP 一般會(huì)有 httpd 守護(hù)進(jìn)程,里面可以設(shè)置 keep-alive timeout,當(dāng) tcp 鏈接閑置超過(guò)這個(gè)時(shí)間就會(huì)關(guān)閉,也可以在 HTTP 的 header 里面設(shè)置超時(shí)時(shí)間
- TCP 的 keep-alive 包含三個(gè)參數(shù),支持在系統(tǒng)內(nèi)核的 net.ipv4 里面設(shè)置:當(dāng) TCP 鏈接之后,閑置了 tcp_keepalive_time,則會(huì)發(fā)生偵測(cè)包,如果沒(méi)有收到對(duì)方的 ACK,那么會(huì)每隔 tcp_keepalive_intvl 再發(fā)一次,直到發(fā)送了 tcp_keepalive_probes,就會(huì)丟棄該鏈接。
- tcp_keepalive_intvl = 15
- tcp_keepalive_probes = 5
- tcp_keepalive_time = 1800
實(shí)際上 HTTP 沒(méi)有長(zhǎng)短鏈接,只有 TCP 有,TCP 長(zhǎng)連接可以復(fù)用一個(gè) TCP 鏈接來(lái)發(fā)起多次 HTTP 請(qǐng)求,這樣可以減少資源消耗,比如一次請(qǐng)求 HTML,可能還需要請(qǐng)求后續(xù)的 JS/CSS/圖片等
參考鏈接
https://blog.csdn.net/weixin_37672169/article/details/80283935
https://www.jianshu.com/p/3fc3646fad80
問(wèn):Fetch API與傳統(tǒng)Request的區(qū)別
- fetch 符合關(guān)注點(diǎn)分離,使用 Promise,API 更加豐富,支持 Async/Await
- 語(yǔ)意簡(jiǎn)單,更加語(yǔ)意化
- 可以使用 isomorphic-fetch ,同構(gòu)方便
參考資源
https://github.com/camsong/blog/issues/2
(2)問(wèn):POST一般可以發(fā)送什么類型的文件,數(shù)據(jù)處理的問(wèn)題
- 文本、圖片、視頻、音頻等都可以
- text/image/audio/ 或 application/json 等
問(wèn):TCP 如何保證有效傳輸及擁塞控制原理。
- tcp 是面向連接的、可靠的、傳輸層通信協(xié)議
- 可靠體現(xiàn)在:有狀態(tài)、可控制
- 有狀態(tài)是指 TCP 會(huì)確認(rèn)發(fā)送了哪些報(bào)文,接收方受到了哪些報(bào)文,哪些沒(méi)有收到,保證數(shù)據(jù)包按序到達(dá),不允許有差錯(cuò)
- 可控制的是指,如果出現(xiàn)丟包或者網(wǎng)絡(luò)狀況不佳,則會(huì)跳轉(zhuǎn)自己的行為,減少發(fā)送的速度或者重發(fā)
所以上面能保證數(shù)據(jù)包的有效傳輸。
擁塞控制原理
原因是有可能整個(gè)網(wǎng)絡(luò)環(huán)境特別差,容易丟包,那么發(fā)送端就應(yīng)該注意了。
主要用三種方法:
- 慢啟動(dòng)閾值 + 擁塞避免
- 快速重傳
- 快速回復(fù)
慢啟動(dòng)閾值 + 擁塞避免
對(duì)于擁塞控制來(lái)說(shuō),TCP 主要維護(hù)兩個(gè)核心狀態(tài):
- 擁塞窗口(cwnd)
- 慢啟動(dòng)閾值(ssthresh)
在發(fā)送端使用擁塞窗口來(lái)控制發(fā)送窗口的大小。
然后采用一種比較保守的慢啟動(dòng)算法來(lái)慢慢適應(yīng)這個(gè)網(wǎng)絡(luò),在開始傳輸?shù)囊欢螘r(shí)間,發(fā)送端和接收端會(huì)首先通過(guò)三次握手建立連接,確定各自接收窗口大小,然后初始化雙方的擁塞窗口,接著每經(jīng)過(guò)一輪 RTT(收發(fā)時(shí)延),擁塞窗口大小翻倍,直到達(dá)到慢啟動(dòng)閾值。
然后開始進(jìn)行擁塞避免,擁塞避免具體的做法就是之前每一輪 RTT,擁塞窗口翻倍,現(xiàn)在每一輪就加一個(gè)。
快速重傳
在 TCP 傳輸過(guò)程中,如果發(fā)生了丟包,接收端就會(huì)發(fā)送之前重復(fù) ACK,比如 第 5 個(gè)包丟了,6、7 達(dá)到,然后接收端會(huì)為 5,6,7 都發(fā)送第四個(gè)包的 ACK,這個(gè)時(shí)候發(fā)送端受到了 3 個(gè)重復(fù)的 ACK,意識(shí)到丟包了,就會(huì)馬上進(jìn)行重傳,而不用等到 RTO (超時(shí)重傳的時(shí)間)
選擇性重傳:報(bào)文首部可選性中加入 SACK 屬性,通過(guò) left edge 和 right edge 標(biāo)志那些包到了,然后重傳沒(méi)到的包
快速恢復(fù)
如果發(fā)送端收到了 3 個(gè)重復(fù)的 ACK,發(fā)現(xiàn)了丟包,覺得現(xiàn)在的網(wǎng)絡(luò)狀況已經(jīng)進(jìn)入擁塞狀態(tài)了,那么就會(huì)進(jìn)入快速恢復(fù)階段:
- 會(huì)將擁塞閾值降低為 擁塞窗口的一半
- 然后擁塞窗口大小變?yōu)閾砣撝?/li>
- 接著 擁塞窗口再進(jìn)行線性增加,以適應(yīng)網(wǎng)絡(luò)狀況
問(wèn):OPTION是干啥的?舉個(gè)用到OPTION的例子?
旨在發(fā)送一種探測(cè)請(qǐng)求,以確定針對(duì)某個(gè)目標(biāo)地址的請(qǐng)求必須具有怎么樣的約束,然后根據(jù)約束發(fā)送真正的請(qǐng)求。
比如針對(duì)跨域資源的預(yù)檢,就是采用 HTTP 的 OPTIONS 方法先發(fā)送的。用來(lái)處理跨域請(qǐng)求
問(wèn):http知道嘛?哪一層的協(xié)議?(應(yīng)用層)
- 靈活可擴(kuò)展,除了規(guī)定空格分隔單詞,換行分隔字段以外,其他都沒(méi)有限制,不僅僅可以傳輸文本,還可以傳輸圖片、視頻等任意資源
- 可靠傳輸,基于 TCP/IP 所以繼承了這一特性
- 請(qǐng)求-應(yīng)答,有來(lái)有回
- 無(wú)狀態(tài),每次 HTTP 請(qǐng)求都是獨(dú)立的,無(wú)關(guān)的、默認(rèn)不需要保存上下文信息
缺點(diǎn):
- 明文傳輸不安全
- 復(fù)用一個(gè) TCP 鏈接,會(huì)發(fā)生對(duì)頭擁塞
- 無(wú)狀態(tài)在長(zhǎng)連接場(chǎng)景中,需要保存大量上下文,以避免傳輸大量重復(fù)的信息
問(wèn):OSI七層模型和TCP/IP四層模型
- 應(yīng)用層
- 表示層
- 會(huì)話層
- 傳輸層
- 網(wǎng)絡(luò)層
- 數(shù)據(jù)鏈路層
- 物理層
TCP/IP 四層概念:
- 應(yīng)用層:應(yīng)用層、表示層、會(huì)話層:HTTP
- 傳輸層:傳輸層:TCP/UDP
- 網(wǎng)絡(luò)層:網(wǎng)絡(luò)層:IP
- 數(shù)據(jù)鏈路層:數(shù)據(jù)鏈路層、物理層
(3)問(wèn):TCP 協(xié)議怎么保證可靠的,UDP 為什么不可靠?
- TCP 是面向連接的、可靠的、傳輸層通信協(xié)議
- UDP 是無(wú)連接的傳輸層通信協(xié)議,繼承 IP 特性,基于數(shù)據(jù)報(bào)
為什么 TCP 可靠?TCP 的可靠性體現(xiàn)在有狀態(tài)和控制
- 會(huì)精準(zhǔn)記錄那些數(shù)據(jù)發(fā)送了,那些數(shù)據(jù)被對(duì)方接收了,那些沒(méi)有被接收,而且保證數(shù)據(jù)包按序到達(dá),不允許半點(diǎn)差錯(cuò),這就是有狀態(tài)
- 當(dāng)意識(shí)到丟包了或者網(wǎng)絡(luò)環(huán)境不佳,TCP 會(huì)根據(jù)具體情況調(diào)整自己的行為,控制自己的發(fā)送速度或者重發(fā),這是可控制的
反之 UDP 就是無(wú)狀態(tài)的和不可控制的
HTTP 2 改進(jìn)
改進(jìn)性能:
- 頭部壓縮
- 多路信道復(fù)用
- Server Push
參考資料https://juejin.im/post/5d032b77e51d45777a126183
原文地址:https://mp.weixin.qq.com/s/Wa4iWshvmILUlfYhFCMr7A