面試官不講武德,一上來就問我Chrome底層原理和HTTP協議(萬字長文)

程式設計師哆啦A夢發表於2020-11-30

已釋出到 程式設計師小灰 公號

前言

有人說,如果你懂得瀏覽器的工作原理,你就能解決80%的前端難題。

是的,瞭解瀏覽器的工作原理,有助於你的工作;而瞭解TCP/IP 、HTTP等網路協議,更是對你未來的職業發展大有裨益。

下面,我總結了4個面試常考的關於瀏覽器和網路通訊的問題,為你重新梳理瀏覽器,網路通訊、頁面渲染、JavaScript、瀏覽器安全等知識,從而讓你對整個前端後端體系有全新的認識。

第一問:Chrome為什麼開啟一個頁面,會有4個程式?

學習掌握:瀏覽器中的網路流程,頁面渲染過程,JavaScript執行流程,以及Web安全理論。下面展開問題了解多程式架構:

多程式架構的學習

程式和執行緒的概念混淆

如計算來說,單執行緒就是一個接一個的計算,多執行緒就是同時處理多個計算。多執行緒是指程式中包含多個執行流,即在一個程式中可以同時執行多個不同的執行緒來執行不同的任務,就是說允許單個程式建立多個並行執行。

單執行緒是程式中的一個執行流,每個執行緒都有自己的專有暫存器(棧指標、程式計數器等),但程式碼區是共享的,即不同的執行緒可以執行同樣的函式。

多執行緒也是程式,所以執行緒需要佔用記憶體,執行緒越多佔用記憶體也越多,多執行緒需要協調和管理,所以需要CPU時間跟蹤執行緒;執行緒之間對共享資源的訪問會相互影響,必須解決競用共享資源的問題;執行緒太多會導致控制太複雜。

單執行緒在程式執行時,所走的程式都是按照連續順序下來的,前面的必須處理好,才會執行後面的。多執行緒執行就是一個程式內有多個相對獨立的並且實現特定的任務以競爭CPU的方式執行,巨集觀上是併發,實際上是分時執行,只是執行的時間片較短。

每個正在執行的程式即是程式,至少包含一個執行緒,這個執行緒叫主執行緒,它在程式啟動時被建立,用於執行main函式。只有一個主執行緒的程式,稱為單執行緒程式。擁有多個執行緒的程式,稱為多執行緒程式。

程式是當一個程式開始執行時,它就是一個程式,程式包括執行中的程式和程式所使用到的記憶體和系統資源(一個程式又是由多個執行緒所組成的)

多執行緒的好處就是可以提高CPU的利用率,在多執行緒程式中,如果一個執行緒必須等待的時候,CPU可以執行其它的執行緒而不是等待,這樣可以大大地提高程式的效率。

所以,執行緒是不能單獨存在的,它是由程式來啟動和管理的,一個程式就是一個程式的執行例項。執行緒是依附於程式的,而程式中使用多執行緒並行處理能提升運算效率。執行緒之間共享程式中的資料。當一個程式關閉後,作業系統會回收程式所佔用的記憶體。

目前的多程式架構瀏覽器Chrome包括,1個瀏覽器主程式,1個GPU程式,1個網路程式,多個渲染程式和多個外掛程式。

so,開啟一個頁面,為啥有4個程式?因為開啟1個頁面:至少需要1個網路程式1個瀏覽器程式1個GPU程式以及1個渲染程式

雖然多程式模型提升了瀏覽器的穩定性、流暢性和安全性,但是帶來了更高的資源佔用,更復雜的體系架構。so,Chrome官方要構建一個更內聚,鬆耦合,易於維護和擴充套件的系統。

第二問:TCP協議是如何保證頁面檔案能被完整送達瀏覽器的?

對於在網路中,我們知道一個檔案通常會被拆分為很多資料包來進行傳輸,而資料包在傳輸過程中又有很大的可能會丟失或者出錯,保證頁面檔案完整地送達瀏覽器是有必要的。

下面就這三方面展開描述:

  1. 資料包如何送達到主機
  2. 主機如何將資料包轉交給應用
  3. 資料是如何被完整地送達到應用程式

資料包從主機A送到主機B,資料包上會附加上主機B的IP地址資訊,主機A本身的IP地址,這些附加的資訊會被裝進一個IP頭的資料結構裡(包含IP版本,源IP地址,目標IP地址,生存時間等)

這些一般我們都瞭解,下面主要說明TCP(Transmission Control Protocol),傳輸控制協議是一種面向連線的可靠的,基於位元組流的傳輸層通訊協議,在簡化的計算機網路OSI模型中,它完成第四層傳輸層所指定的功能。

使用者資料包協議(UDP)是同一層內另一個重要的傳輸協議。

在因特網協議族中,TCP層是位於IP層之上的,TCP->IP,應用層之下的中間層,應用層->中間層。不同主機的應用層之間經常需要可靠的,像管道一樣的連線,但是IP層不提供這樣的流機制,而是提供不可靠的包進行交換。

TCP為了保證不發生丟包的情況,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。接收端實體對已成功收到的包發回一個相應的確認資訊(ACK),如果傳送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的資料包就被假設為已丟失並進行重傳。

  • 資料在TCP層稱為流
  • 資料分組稱為分段
TCP協議的運作:連線建立,資料傳送,連線終止。

那你瞭解什麼是TCP嗎?這一點大部分人應該只會說它是一種協議。

TCP傳輸控制協議是TCP/IP,傳輸控制協議Internet協議中的主要協議之一,TCP/IP是一套通訊協議,用於連線Internet以及大多數其他計算機網路上的主機。

協議是一種共同商定的用於執行某件事的格式。對於計算機,最常用於指一組規則,使計算機能夠相互連線並傳輸資料,稱為通訊協議。

TCP是一種面向連線的協議,它在主機之間建立並維護虛擬連線,直到交換了一條訊息或要在其上執行的應用程式交換的訊息為止。資料包是TCP/IP網路上資料傳輸的最基本單位。

TCP在傳輸層上執行,負責維護整個網路上可靠的端到端通訊,IP是網路層協議,它是傳輸層正下方的層,在傳輸層執行的有:UDP(使用者資料包協議),RTP(實時傳輸協議),SCTP(流控制傳輸協議)。

連線建立

  1. TCP用三次握手過程建立一個連線

三次握手協議的過程:

a.客戶端 向 伺服器端 傳送一個 SYN 包,請求一個主動開啟。該包攜帶客戶端為這個連線請求設定的隨機數A作為訊息列號。

b.伺服器端接收到一個SYN包後,把該包放入SYN佇列中;回送一個SYN/ACK。ACK的確認碼應為A+1,SYN/ACK包本身攜帶一個隨機產生的序號B。

c.客戶端收到SYN/ACK包後,傳送一個ACK的包,該包的序號被設定為A+1,而ACK的確認碼為B+1。 當伺服器端收到這個ACK包的時候,把請求幀從SYN佇列中移出,放置ACCEPT佇列中。

場景:當伺服器端接收到客戶端傳送過來的SYN後, 回了SYN-ACK後,客戶端掉線了,伺服器端沒有收到客戶端回來的ACK,那這個連線 就 處於 一箇中間狀態,沒成功也沒失敗。

但是,伺服器端如果在一定時間內沒有收到TCP會重新發SYN-ACK。

  • 主機收到一個TCP包時,用兩端的IP地址與埠號來標識這個TCP包屬於哪個session。
  • 使用一張表來儲存所有的session,表中的每條稱作TCB。
  • tcb結構的定義含: 連線使用的源埠, 目的埠,目的ip, 序號, 應答序號, 對方視窗大小, 已方視窗大小, tcp狀態, tcp輸入/輸出佇列, 應用層輸出佇列, tcp的重傳有關變數等。
  • 伺服器端的連線數量是無限的,只受記憶體的限制。
資料傳送

在每個TCP報文段中都有一對序號和確認號

TCP報文傳送者稱自己的位元組流的編號為序號,稱接收到對方的位元組流編號為確認號。通過使用序號和確認號,TCP層可以把收到的報文段中的位元組按正確的順序交付給應用層。

TCP協議使用序號標識每端發出的位元組順序,從另一端接收資料可以重建順序,無懼傳輸的包的亂序交付或丟包。

傳送確認包acks,攜帶接收對方發來的位元組流的編號(確認號),告訴對方已經成功接收的資料流的位元組位置。

上圖描述資料傳輸的過程圖

資料包結構

下面讓我們來看看資料包結構圖:

包含:偏移位元組,來源連線埠,目的連線埠,序列號碼,確認號碼,校驗和,緊急指標等。

  • 來源連線埠,16位長,識別傳送連線埠
  • 目的連線埠,16位長,識別接收連線埠
  • 序列號(seq,32位長)
  • 確認號(ack,32位長),期望收到的資料的開始序列號,也即已經收到的資料的位元組長度加1
  • 資料偏移(4位長),以4位元組為單位計算出的資料段開始地址的偏移值。
  • 保留,須置0
  • ACK—為1表示確認號欄位有效
  • SYN—為1表示這是連線請求或是連線接受請求,用於建立連線和使順序號同步
  • FIN—為1表示傳送方沒有資料要傳輸了,要求釋放連線
  • RST—為1表示出現嚴重差錯。可能需要重新建立TCP連線。還可以用於拒絕非法的報文段和拒絕連線請求
  • 緊急指標(16位長)—本報文段中的緊急資料的最後一個位元組的序號
  • 視窗(WIN,16位長)—表示從確認號開始,本報文的傳送方可以接收的位元組數,即接收視窗大小。用於流量控制
  • 校驗和(Checksum,16位長)—對整個的TCP報文段,包括TCP頭部和TCP資料,以16位字進行計算所得。這是一個強制性的欄位

記住其中IP是把資料包送達目的主機的,資料包送達到主機。那麼如何將資料包轉交給應用的呢?

UDP是把資料包送達應用程式的。

UDP是基於IP之上開發能和應用打交道的協議,使用者資料包協議,是決定把資料包交給哪個程式的,IP只負責把資料包傳送到對方電腦

下面看一下UDP協議和TCP協議在TCP/IP體系中的位置:

看完位置,那麼下面我們來簡單對比一下UDP和TCP:

UDP: 無連線;支援一對一,一對多,多對一和多對多互動通訊;對應用層交付的報文直接打包;盡最大努力交付,也就是不可靠;不使用流量控制和擁塞控制;首部開銷小,僅8位元組。

TCP:面向連線;每一條TCP連線只能有兩個端點EP,只能是一對一通訊;面向位元組流;可靠傳輸,使用流量控制和擁塞控制;首部最小20位元組,最大60位元組。

讓我們看看UDP和TCP首部對比開銷:

UDP最重要的一點就是埠號,因為UDP是通過埠號把資料包分發給正確的程式,UDP不能保證資料的可靠性,但傳輸速度快。

重要的講解是:資料是如何被完整地送達到應用程式?

TCP就是把資料完整地送達應用程式。

TCP是一種面向連線的,可靠的,基於位元組流的傳輸層通訊協議,提供重傳機制,引入了資料包排序機制(TCP頭,提供了排序的序列號,用來通過序號重排資料包)。

說到TCP連線,就要說說常面試的TCP/IP的三次握手,建立連線;四次揮手,斷開連線

三次握手圖:

完成了三次TCP握手:

女朋友發給男朋友:“在嗎?”
男朋友回覆女朋友:“我在!”
女朋友回覆男朋友:“我知道了!”

此時男朋友知道了。

四次揮手圖:

完成四次揮手:

女朋友發給男朋友:“分手吧!”
男朋友回覆女朋友:“額?”
男朋友回覆女朋友:“認真的嗎?”
女朋友回覆男朋友:“認真的!”

此時女朋友刪除了男朋友的微信。

按照我描述的三次握手和四次揮手,我相信你懂了,哈哈!

第三問:HTTP請求流程,為什麼很多站點第二次開啟速度會很快呢?

說到HTTP協議,它是建立在TCP連線基礎之上的,超文字傳輸協議,HTTP是一種用於分散式,協作式和超媒體資訊系統的應用層協議,HTTP是全球資訊網的資料通訊的基礎。

某人說:要想學好瀏覽器,就要深入瞭解HTTP。

瀏覽器是使用HTTP協議作為應用層協議,用來封裝請求的文字資訊,使用TCP/IP作傳輸層協議將它發到網路上(http的內容是通過TCP的傳輸資料階段來實現的)。

  • 域名和IP地址-對映關係,域名對映為IP的系統叫作“域名系統”,簡稱DNS

域名系統DNS是網際網路的一項服務。它作為將域名和IP地址相互對映的一個分散式資料庫,能夠使人更方便地訪問網際網路。

域名如:dadaqianduan.cn (URL地址)

IP地址為:xx.233.xxs.12 (訪問)

首先,第一步瀏覽器會請求DNS返回域名對應的IP,瀏覽器還提供了DNS資料快取服務,如果某個域名已經被解析過了,瀏覽器就會快取解析的結構,下次查詢時直接使用,減少一次網路請求。拿到IP後,就需要獲取埠號,如果url沒有明確指出埠號,HTTP協議預設是80埠。

到這一步明白的清清楚楚了,IP和埠號。那麼讓我說說HTTP協議的描述,這裡補充是為了更好的瞭解:

HTTP是一個客戶端和伺服器端之間請求和應答的標準,通常使用TCP協議,通過使用網頁瀏覽器,網咯爬蟲或者其它的工具,客戶端發起一個HTTP請求到伺服器上指定埠,預設埠為80。

應答的伺服器上儲存著一些資源,如HTML檔案和影像等,源伺服器;(客戶端稱為使用者代理程式),使用者代理和源伺服器中間可能存在多個"中間層",比如代理伺服器,閘道器,隧道等。

so,HTTP伺服器在埠監聽客戶端的請求,一旦收到請求,伺服器會向客戶端返回一個狀態,如:"HTTP/1.1 200 OK",以及返回的內容,如請求的檔案,錯誤訊息,或者其它訊息。

到這裡我先回答一下:瀏覽器發起HTTP請求流程:1.構建請求(構建請求行資訊);2.查詢快取(瀏覽器快取是一種在本地儲存資源副本,以供下次請求時直接使用的技術);3.準備IP地址和埠;4.等待TCP佇列;5.建立TCP連線;6.傳送HTTP請求。

然後伺服器處理請求,伺服器返回請求,斷開連線。

其實埠和IP地址準備好後,不一定直接建立TCP連線的,因為在Chrome中有個機制,就是同一個域名同時最多隻能建立6個TCP連線,如果在同一個域名下同時有10個請求發生,那麼其中就有4個請求進入排隊等待狀態。

如果請求數量少於6個,就直接進入建立TCP連線。

傳送HTTP請求

上面都講好了初步,那麼瀏覽器是如何傳送請求資訊給伺服器的呢?

來一張post請求抓包圖:

來張瀏覽器傳送請求到伺服器端接收返回的過程:

描述:使用者在瀏覽器輸入請求的url地址,瀏覽器內部的核心程式碼會將這個url進行拆分解析,最終將domain傳送到DNS伺服器上,DNS伺服器會根據domain去查詢相關的對應的ip地址,從而將IP地址返回給瀏覽器。

瀏覽器有了ip地址後就會知道這個請求是傳送到哪裡的。經過(區域網,交換機,路由器,主幹網咯)到達伺服器。

對於經常瞭解HTTP的朋友應該瞭解上述表達,那接下來看看HTTP請求資料格式(可看上圖->來一張post請求抓包圖):

HTTP請求資料格式

瀏覽器首先向伺服器傳送請求行(請求方法;請求URI;HTTP協議版本)-來告訴伺服器瀏覽器需要什麼資源,常用請求方法為GET,請求頭(用來告訴一些瀏覽器的基礎資訊-瀏覽器所使用的作業系統、瀏覽器核心等資訊,以及當前請求的域名資訊、瀏覽器端的Cookie資訊等),請求體(如常用的POST,用於傳送一些資料給伺服器,準備的資料是通過請求體來傳送的)。

伺服器處理HTTP請求流程

  1. 返回請求;
  2. 斷開連線;
  3. 重定向。

檢視返回請求資料,-i,獲取返回響應行(包含協議版本和狀態碼),響應頭,響應體資料。

一般情況下,伺服器向客戶端返回了請求資料,就要關閉TCP連線。但其頭資訊中加入了該欄位: Connection: Keep-Alive,讓TCP連線仍然保持連線,可以繼續同一個TCP連線傳送請求,可以省下次請求時需要建立連線的時間。

其實一般返回請求,斷開連線就沒了,但有一種就是你在瀏覽器中開啟的url,發現最終的頁面地址不一樣,那是因為有一個重定向操作。

如圖:-I表示只需要獲取響應頭和響應行資料

  • location欄位時重定向的地址;

狀態碼301和302的區別

301 Moved Permanently 被請求的資源已永久移動到新位置,並且將來任何對此資源的引用都應該使用本響應返回的若干個URI之一。如果可能,擁有連結編輯功能的客戶端應當自動把請求的地址修改為從伺服器反饋回來的地址。除非額外指定,否則這個響應也是可快取的。

302 Found 請求的資源現在臨時從不同的URI響應請求。由於這樣的重定向是臨時的,客戶端應當繼續向原有地址傳送以後的請求。只有在Cache-Control或Expires中進行了指定的情況下,這個響應才是可快取的。

字面上的區別:301是永久重定向,而302是臨時重定向

302重定向是暫時的重定向,搜尋引擎會抓取新的內容而保留舊的地址,因為伺服器返回302,所以搜尋搜尋引擎認為新的網址是暫時的。

301重定向是永久的重定向,搜尋引擎在抓取新的內容的同時也將舊的網址替換為了重定向之後的網址。

接下來,讓我們梳理一下HTTP版本號,這一點,我相信在學習的過程中,大家也是想知道的。
HTTP/0.9:

已過時。僅支援請求方式GET,並且僅能請求訪問HTML格式的資源,沒有在通訊中指定版本號,且不支援請求頭。

HTTP/1.0:

這是第一個在通訊中指定版本號的HTTP協議版本,增加了請求方式POST和HEAD;不再侷限於0.9版本的HTML格式,根據Content-Type可以支援多種資料格式;包括狀態碼(status code)、多字符集支援、多部分傳送(multi-part type)、許可權(authorization)、快取(cache)、內容編碼(content encoding)等。

1.0版本:每次TCP連線只能傳送一個請求,當伺服器響應後就會關閉這次連線,下一個請求需要再次建立TCP連線.
HTTP/1.1:

預設採用持續連線(TCP連線預設不關閉,可以被多個請求複用,不用宣告Connection: keep-alive),能很好地配合代理伺服器工作。

一個TCP連線可以允許多個HTTP請求

增加了管道機制,在同一個TCP連線裡,允許多個請求同時傳送,增加了併發性,進一步改善了HTTP協議的效率

1.1版規定可以不使用Content-Length欄位,而使用"分塊傳輸編碼"-只要請求或回應的頭資訊有Transfer-Encoding欄位,就表明回應將由數量未定的資料塊組成。Transfer-Encoding: chunked

新增了請求方式PUT、PATCH、OPTIONS、DELETE

  • 分塊傳輸編碼:是超文字傳輸協議中的一種資料傳輸機制,允許HTTP由網頁伺服器傳送給客戶端應用的資料可以分成多個部分,分塊傳輸編碼只在HTTP協議1.1版本(HTTP/1.1)中提供。

同一個TCP連線裡,所有的資料通訊是按次序進行的。回應慢,會有許多請求排隊,造成"隊頭堵塞"。

HTTP/2:

於2015年5月作為網際網路標準正式釋出。加了雙工模式,即不僅客戶端能夠同時傳送多個請求,服務端也能同時處理多個請求,解決了隊頭堵塞的問題。

使用了多路複用的技術,做到同一個連線併發處理多個請求,而且併發請求的數量比HTTP1.1大了好幾個數量級。

增加伺服器推送的功能,不經請求服務端主動向客戶端傳送資料。

HTTP1.1相較於HTTP1.0協議區別:

  1. 快取處理
  2. 頻寬優化及網路連線的使用
  3. 錯誤通知的管理
  4. 訊息在網路中的傳送
  5. 網際網路地址的維護
  6. 安全性及完整性

最後的最後,說第二次站點的開啟為啥速度快?

原因是第一次載入頁面過程中,快取了一些耗時的資料,主要快取有 DNS快取 和 頁面資源快取 兩個方面。
  • 瀏覽器快取

當第一次傳送請求,伺服器返回HTTP響應頭給瀏覽器時,瀏覽器會通過響應頭中CacheControl欄位來設定是否快取資源。通常還需設定一個快取時間,Cache-Control:Max-age=2000,在快取沒有過期的情況下,在傳送請求請求該資源,會直接返回快取中的資源給瀏覽器。如果快取過期,瀏覽器則會繼續發起網路請求。

盲點:

第四問:輸入URL到頁面展示發生了什麼?

簡單地說一下就是:

  • 瀏覽器主程式提交url給網路程式
  • 網路程式請求伺服器,返回響應頭行體,判斷是否需要重定向
  • 網路程式將頁面型別的響應資源提交給渲染程式
  • 渲染程式渲染結束,載入完畢

分步驟簡單說一下就是:

  1. 首先是域名解析
  2. 建立TCP連結
  3. 建立Http請求
  4. 伺服器處理Http請求
  5. 關閉TCP連線
  6. 瀏覽器解析資源
  7. 瀏覽器渲染頁面

在我的GitHub上也講過:
從瀏覽器位址列輸入url到顯示頁面的步驟
https://github.com/webVueBlog...

本篇文章的最後,留給你一個面試題,就是上面說到的:“從輸入URL到頁面展示,這中間傳送了什麼?”這個問題,如果面試你,你又如何回答呢?

如果你作為面試官,又該考哪些點呢?

閱讀資料

瀏覽器工作原理與實踐
https://time.geekbang.org/col...

總結

以上就是今天要講的內容,本文簡單介紹了Chrome流程,梳理了TCP與HTTP協議,瞭解三次握手,四次揮手流程,感謝閱讀,如果你覺得這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友。

喜歡本文的朋友,歡迎關注,收看更多精彩內容

相關文章