從輸入U(xiǎn)RL到頁面加載的過程
- 瀏覽器接收URL開啟網(wǎng)絡(luò)請(qǐng)求線程
- DNS查詢
- TCP/IP請(qǐng)求
- 服務(wù)器接收到請(qǐng)求、對(duì)應(yīng)后臺(tái)處理請(qǐng)求
- 后臺(tái)和前臺(tái)的HTTP交互
- 瀏覽器接收到HTTP數(shù)據(jù)包并解析
- 頁面渲染
- JS引擎解析
進(jìn)程和線程
進(jìn)程是CPU資源分配的最小單位师溅,線程是CPU調(diào)度的最小單位
瀏覽器的進(jìn)程
- Browser進(jìn)程:瀏覽器的主進(jìn)程赶诊,負(fù)責(zé)協(xié)調(diào)主到、主控,只有一個(gè)。負(fù)責(zé)界面顯示、用戶交互拒迅、頁面管理、繪制她倘、下載等
- 第三方插件進(jìn)程:每個(gè)插件對(duì)應(yīng)一個(gè)線程璧微,使用時(shí)創(chuàng)建
- GPU線程,用于3D繪制
- 瀏覽器渲染進(jìn)程:默認(rèn)每個(gè)Tab頁一個(gè)進(jìn)程
瀏覽器多進(jìn)程的優(yōu)勢(shì)
- 避免單個(gè)page crash影響整個(gè)瀏覽器
- 避免第三方插件crash影響整個(gè)瀏覽器
- 多進(jìn)程充分利用多核優(yōu)勢(shì)
瀏覽器內(nèi)核進(jìn)程(tab頁面)的線程
- GUI線程(渲染界面)
- JS引擎線程
- 事件觸發(fā)線程(事件循環(huán))
- 定時(shí)器線程
- 網(wǎng)絡(luò)請(qǐng)求線程
其中GUI渲染線程和JS引擎是無法同時(shí)工作的
DNS查詢
- 瀏覽器緩存
- hosts
- 路由器緩存
- ISP(網(wǎng)絡(luò)服務(wù)提供商)
- 遞歸查詢
五層因特網(wǎng)協(xié)議棧
- 應(yīng)用層(HTTP)
- 傳輸層(TCP硬梁、UDP)
- 網(wǎng)絡(luò)層(IP)
- 數(shù)據(jù)鏈路層
- 物理層
TCP的三次握手
- 第一次握手(SYN=1, seq=x):
客戶端發(fā)送一個(gè) TCP 的 SYN 標(biāo)志位置1的包前硫,指明客戶端打算連接的服務(wù)器的端口,以及初始序號(hào) X,保存在包頭的序列號(hào)(Sequence Number)字段里荧止。
發(fā)送完畢后屹电,客戶端進(jìn)入 SYN_SEND 狀態(tài)。 - 第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服務(wù)器發(fā)回確認(rèn)包(ACK)應(yīng)答跃巡。即 SYN 標(biāo)志位和 ACK 標(biāo)志位均為1危号。服務(wù)器端選擇自己 ISN 序列號(hào),放到 Seq 域里瓷炮,同時(shí)將確認(rèn)序號(hào)(Acknowledgement Number)設(shè)置為客戶的 ISN 加1,即X+1递宅。 發(fā)送完畢后娘香,服務(wù)器端進(jìn)入 SYN_RCVD 狀態(tài)。 - 第三次握手(ACK=1办龄,ACKnum=y+1)
客戶端再次發(fā)送確認(rèn)包(ACK)烘绽,SYN 標(biāo)志位為0,ACK 標(biāo)志位為1俐填,并且把服務(wù)器發(fā)來 ACK 的序號(hào)字段+1安接,放在確定字段中發(fā)送給對(duì)方,并且在數(shù)據(jù)段放寫ISN的+1
發(fā)送完畢后英融,客戶端進(jìn)入 ESTABLISHED 狀態(tài)盏檐,當(dāng)服務(wù)器端接收到這個(gè)包時(shí),也進(jìn)入 ESTABLISHED 狀態(tài)驶悟,TCP 握手結(jié)束胡野。
TCP的四次揮手
- 第一次揮手(FIN=1,seq=x)
假設(shè)客戶端想要關(guān)閉連接痕鳍,客戶端發(fā)送一個(gè) FIN 標(biāo)志位置為1的包硫豆,表示自己已經(jīng)沒有數(shù)據(jù)可以發(fā)送了龙巨,但是仍然可以接受數(shù)據(jù)。
發(fā)送完畢后熊响,客戶端進(jìn)入 FIN_WAIT_1 狀態(tài)旨别。 - 第二次揮手(ACK=1,ACKnum=x+1)
服務(wù)器端確認(rèn)客戶端的 FIN 包汗茄,發(fā)送一個(gè)確認(rèn)包秸弛,表明自己接受到了客戶端關(guān)閉連接的請(qǐng)求,但還沒有準(zhǔn)備好關(guān)閉連接剔难。
發(fā)送完畢后胆屿,服務(wù)器端進(jìn)入 CLOSE_WAIT 狀態(tài),客戶端接收到這個(gè)確認(rèn)包之后偶宫,進(jìn)入 FIN_WAIT_2 狀態(tài)非迹,等待服務(wù)器端關(guān)閉連接。 - 第三次揮手(FIN=1纯趋,seq=y)
服務(wù)器端準(zhǔn)備好關(guān)閉連接時(shí)憎兽,向客戶端發(fā)送結(jié)束連接請(qǐng)求,F(xiàn)IN 置為1吵冒。
發(fā)送完畢后纯命,服務(wù)器端進(jìn)入 LAST_ACK 狀態(tài),等待來自客戶端的最后一個(gè)ACK痹栖。 - 第四次揮手(ACK=1亿汞,ACKnum=y+1)
客戶端接收到來自服務(wù)器端的關(guān)閉請(qǐng)求,發(fā)送一個(gè)確認(rèn)包揪阿,并進(jìn)入 TIME_WAIT狀態(tài)疗我,等待可能出現(xiàn)的要求重傳的 ACK 包。
服務(wù)器端接收到這個(gè)確認(rèn)包之后南捂,關(guān)閉連接吴裤,進(jìn)入 CLOSED 狀態(tài)。
客戶端等待了某個(gè)固定時(shí)間(兩個(gè)最大段生命周期溺健,2MSL麦牺,2 Maximum Segment Lifetime)之后,沒有收到服務(wù)器端的 ACK 鞭缭,認(rèn)為服務(wù)器端已經(jīng)正常關(guān)閉連接剖膳,于是自己也關(guān)閉連接,進(jìn)入 CLOSED 狀態(tài)岭辣。
TCP和UDP的區(qū)別
粘包
默認(rèn)情況下, TCP 連接會(huì)啟用延遲傳送算法 (Nagle 算法), 在數(shù)據(jù)發(fā)送之前緩存他們. 如果短時(shí)間有多個(gè)數(shù)據(jù)發(fā)送, 會(huì)緩沖到一起作一次發(fā)送 (緩沖大小見 socket.bufferSize), 這樣可以減少 IO 消耗提高性能.
如果是傳輸文件的話, 那么根本不用處理粘包的問題, 來一個(gè)包拼一個(gè)包就好了. 但是如果是多條消息, 或者是別的用途的數(shù)據(jù)那么就需要處理粘包.
可以參見網(wǎng)上流傳比較廣的一個(gè)例子, 連續(xù)調(diào)用兩次 send 分別發(fā)送兩段數(shù)據(jù) data1 和 data2, 在接收端有以下幾種常見的情況:
A. 先接收到 data1, 然后接收到 data2 .
B. 先接收到 data1 的部分?jǐn)?shù)據(jù), 然后接收到 data1 余下的部分以及 data2 的全部.
C. 先接收到了 data1 的全部數(shù)據(jù)和 data2 的部分?jǐn)?shù)據(jù), 然后接收到了 data2 的余下的數(shù)據(jù).
D. 一次性接收到了 data1 和 data2 的全部數(shù)據(jù).
其中的 BCD 就是我們常見的粘包的情況. 而對(duì)于處理粘包的問題, 常見的解決方案有:
多次發(fā)送之前間隔一個(gè)等待時(shí)間
關(guān)閉 Nagle 算法
進(jìn)行封包/拆包
TCP流量控制
通過滑動(dòng)窗口協(xié)議(連續(xù)ARQ協(xié)議)實(shí)現(xiàn)潮秘,保證了分組無差錯(cuò)、有序接收易结、流量控制枕荞。接收方返回的ACK中會(huì)包含自己的接收窗口的大小柜候,并且利用大小來控制發(fā)送方的數(shù)據(jù)發(fā)送。
TCP流量控制中的死鎖
當(dāng)發(fā)送者收到了一個(gè)窗口為0的應(yīng)答躏精,發(fā)送者便停止發(fā)送渣刷,等待接收者的下一個(gè)應(yīng)答。如果這個(gè)窗口不為0的應(yīng)答在傳輸過程中丟失矗烛,發(fā)送者一直等待辅柴,接收者以為發(fā)送者收到該應(yīng)答,等待接收新數(shù)據(jù)瞭吃,這樣雙方就相互等待碌嘀,從而產(chǎn)生死鎖
TCP流量控制中的死鎖的解決
TCP使用了持續(xù)計(jì)時(shí)器。每當(dāng)發(fā)送者收到一個(gè)0窗口的應(yīng)答后就啟動(dòng)該計(jì)時(shí)器歪架。計(jì)時(shí)器到時(shí)便主動(dòng)發(fā)送報(bào)文詢問接收者的窗口大小股冗。若接收者仍然返回0窗口,則重置該計(jì)時(shí)器繼續(xù)等待和蚪;若窗口不為0止状,則標(biāo)識(shí)應(yīng)答報(bào)文丟失了,此時(shí)重置發(fā)送窗口開始發(fā)送攒霹,這樣就避免了死鎖的產(chǎn)生
擁塞控制和流量控制的區(qū)別
擁塞控制是作用于網(wǎng)絡(luò)的怯疤,防止網(wǎng)絡(luò)負(fù)載過大,常用的方法:1.慢啟動(dòng)催束、擁塞避免 2.快重傳集峦、快恢復(fù)。流量控制是作用于接收者的抠刺,控制發(fā)送者的發(fā)送速度使接收者來得及接收塔淤,防止分組丟失
慢啟動(dòng)算法
發(fā)送方維持一個(gè)叫做擁塞窗口CWnd的狀態(tài)變量,控制著傳輸速度矫付,TCP開始發(fā)送報(bào)文時(shí)CWnd=1凯沪。一個(gè)傳輸輪次所經(jīng)歷的時(shí)間就是往返時(shí)間RTT第焰,每經(jīng)過一個(gè)RTT并且按時(shí)收到確認(rèn)买优,就將擁塞窗口CWnd加倍。還有一個(gè)叫慢啟動(dòng)門限ssthresh的狀態(tài)變量挺举,當(dāng)CWnd<ssthresh時(shí)杀赢,使用慢啟動(dòng),當(dāng)CWnd>=ssthresh改用擁塞避免算法
擁塞避免算法
每經(jīng)過一個(gè)往返時(shí)間RTT就把發(fā)送方的擁塞窗口cwnd加1而不是加倍湘纵。無論在慢啟動(dòng)階段還是擁塞避免階段脂崔,只要發(fā)送方?jīng)]有按時(shí)收到確認(rèn),就把慢啟動(dòng)門限設(shè)置為出現(xiàn)擁塞時(shí)的擁塞窗口cwnd的一半(但不小于2)梧喷。然后把擁塞窗口cwnd重置為1砌左,執(zhí)行慢啟動(dòng)算法
快重傳算法
接收方收到一個(gè)失序的報(bào)文段后就立刻發(fā)出重復(fù)確認(rèn)而不是等到自己發(fā)送數(shù)據(jù)時(shí)捎帶確認(rèn)脖咐。只要發(fā)送方一連收到三個(gè)重復(fù)確認(rèn)就立即重傳對(duì)方尚未收到的報(bào)文段,而不是等待重傳計(jì)時(shí)器到期
快恢復(fù)算法
當(dāng)發(fā)送方連續(xù)收到三個(gè)重復(fù)確認(rèn)時(shí)汇歹,把慢啟動(dòng)門限ssthresh減半屁擅,但是并不執(zhí)行慢開始算法,而是將擁塞窗口cwnd設(shè)置為ssthresh減半后的值产弹,直接執(zhí)行擁塞避免算法派歌。快重傳配合快恢復(fù)的TCP Reno版本是目前使用最廣的版本痰哨。
HTTP報(bào)文結(jié)構(gòu)
- 通用頭部
- 請(qǐng)求/響應(yīng)頭部
- 請(qǐng)求/響應(yīng)體
常見請(qǐng)求頭部
Accept: 接收類型胶果,表示瀏覽器支持的MIME類型(對(duì)標(biāo)服務(wù)端返回的Content-Type)
Accept-Encoding:瀏覽器支持的壓縮類型,如gzip等,超出類型不能接收
Content-Type:客戶端發(fā)送出去實(shí)體內(nèi)容的類型
Cache-Control: 指定請(qǐng)求和響應(yīng)遵循的緩存機(jī)制,如no-cache
If-Modified-Since:對(duì)應(yīng)服務(wù)端的Last-Modified斤斧,用來匹配看文件是否變動(dòng)早抠,只能精確到1s之內(nèi),http1.0中
Expires:緩存控制折欠,在這個(gè)時(shí)間內(nèi)不會(huì)請(qǐng)求贝或,直接使用緩存,http1.0锐秦,而且是服務(wù)端時(shí)間
Max-age:代表資源在本地緩存多少秒咪奖,有效時(shí)間內(nèi)不會(huì)請(qǐng)求,而是使用緩存酱床,http1.1中
If-None-Match:對(duì)應(yīng)服務(wù)端的ETag羊赵,用來匹配文件內(nèi)容是否改變(非常精確)契耿,http1.1中
Cookie: 有cookie并且同域訪問時(shí)會(huì)自動(dòng)帶上
Connection: 當(dāng)瀏覽器與服務(wù)器通信時(shí)對(duì)于長(zhǎng)連接如何進(jìn)行處理,如keep-alive
Host:請(qǐng)求的服務(wù)器URL
Origin:最初的請(qǐng)求是從哪里發(fā)起的(只會(huì)精確到端口),Origin比Referer更尊重隱私
Referer:該頁面的來源URL(適用于所有類型的請(qǐng)求游添,會(huì)精確到詳細(xì)頁面地址,csrf攔截常用到這個(gè)字段)
User-Agent:用戶客戶端的一些必要信息堤框,如UA頭部等
常見響應(yīng)頭部
Access-Control-Allow-Headers: 服務(wù)器端允許的請(qǐng)求Headers
Access-Control-Allow-Methods: 服務(wù)器端允許的請(qǐng)求方法
Access-Control-Allow-Origin: 服務(wù)器端允許的請(qǐng)求Origin頭部(譬如為*)
Content-Type:服務(wù)端返回的實(shí)體內(nèi)容的類型
Date:數(shù)據(jù)從服務(wù)器發(fā)送的時(shí)間
Cache-Control:告訴瀏覽器或其他客戶罐寨,什么環(huán)境可以安全的緩存文檔
Last-Modified:請(qǐng)求資源的最后修改時(shí)間
Expires:應(yīng)該在什么時(shí)候認(rèn)為文檔已經(jīng)過期,從而不再緩存它
Max-age:客戶端的本地資源應(yīng)該緩存多少秒靡挥,開啟了Cache-Control后有效
ETag:請(qǐng)求變量的實(shí)體標(biāo)簽的當(dāng)前值
Set-Cookie:設(shè)置和頁面關(guān)聯(lián)的cookie,服務(wù)器通過這個(gè)頭部把cookie傳給客戶端
Keep-Alive:如果客戶端有keep-alive鸯绿,服務(wù)端也會(huì)有響應(yīng)(如timeout=38)
Server:服務(wù)器的一些相關(guān)信息
HTTP2.0相對(duì)于HTTP1.x有什么優(yōu)勢(shì)和特點(diǎn)
二進(jìn)制分幀
幀:HTTP/2 數(shù)據(jù)通信的最小單位消息:指 HTTP/2 中邏輯上的 HTTP 消息跋破。例如請(qǐng)求和響應(yīng)等,消息由一個(gè)或多個(gè)幀組成瓶蝴。
流:存在于連接中的一個(gè)虛擬通道毒返。流可以承載雙向消息,每個(gè)流都有一個(gè)唯一的整數(shù)ID
頭部壓縮
HTTP/1.x會(huì)在請(qǐng)求和響應(yīng)中中重復(fù)地?cái)y帶不常改變的舷手、冗長(zhǎng)的頭部數(shù)據(jù)拧簸,給網(wǎng)絡(luò)帶來額外的負(fù)擔(dān)。
- HTTP/2在客戶端和服務(wù)器端使用“首部表”來跟蹤和存儲(chǔ)之前發(fā)送的鍵-值對(duì)男窟,對(duì)于相同的數(shù)據(jù)盆赤,不再通過每次請(qǐng)求和響應(yīng)發(fā)送
- 首部表在HTTP/2的連接存續(xù)期內(nèi)始終存在贾富,由客戶端和服務(wù)器共同漸進(jìn)地更新
- 每個(gè)新的首部鍵-值對(duì)要么被追加到當(dāng)前表的末尾,要么替換表中之前的值
服務(wù)器推送
服務(wù)端可以在發(fā)送頁面HTML時(shí)主動(dòng)推送其它資源牺六,而不用等到瀏覽器解析到相應(yīng)位置祷安,發(fā)起請(qǐng)求再響應(yīng)。例如服務(wù)端可以主動(dòng)把JS和CSS文件推送給客戶端兔乞,而不需要客戶端解析HTML時(shí)再發(fā)送這些請(qǐng)求汇鞭。
服務(wù)端可以主動(dòng)推送,客戶端也有權(quán)利選擇是否接收庸追。如果服務(wù)端推送的資源已經(jīng)被瀏覽器緩存過霍骄,瀏覽器可以通過發(fā)送RST_STREAM幀來拒收。主動(dòng)推送也遵守同源策略淡溯,服務(wù)器不會(huì)隨便推送第三方資源給客戶端读整。
多路復(fù)用
HTTP 1.x 中,如果想并發(fā)多個(gè)請(qǐng)求咱娶,必須使用多個(gè) TCP 鏈接米间,且瀏覽器為了控制資源,還會(huì)對(duì)單個(gè)域名有 6-8個(gè)的TCP鏈接請(qǐng)求限制膘侮。
HTTP2中:
同域名下所有通信都在單個(gè)連接上完成屈糊。
單個(gè)連接可以承載任意數(shù)量的雙向數(shù)據(jù)流。
數(shù)據(jù)流以消息的形式發(fā)送琼了,而消息又由一個(gè)或多個(gè)幀組成逻锐,多個(gè)幀之間可以亂序發(fā)送,因?yàn)楦鶕?jù)幀首部的流標(biāo)識(shí)可以重新組裝
HTTP的緩存過程
- 客戶端向服務(wù)器發(fā)出請(qǐng)求雕薪,請(qǐng)求資源
- 服務(wù)器返回資源昧诱,并通過響應(yīng)頭決定緩存策略
- 客戶端根據(jù)響應(yīng)頭的策略決定是否緩存資源(這里假設(shè)是),并將響應(yīng)頭與資源緩存下來
- 在客戶端再次請(qǐng)求且命中資源的時(shí)候所袁,此時(shí)客戶端去檢查上次緩存的緩存策略盏档,根據(jù)策略的不同、是否過期等判斷是直接讀取本地緩存還是與服務(wù)器協(xié)商緩存
原文章
前端面試與進(jìn)階指南
從輸入U(xiǎn)RL到頁面加載的過程燥爷?如何由一道題完善自己的前端知識(shí)體系蜈亩!