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

已發佈到 程序員小灰 公號前端

前言

有人說,若是你懂得瀏覽器的工做原理,你就能解決80%的前端難題。git

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

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

第一問:Chrome爲何打開一個頁面,會有4個進程?

學習掌握:瀏覽器中的網絡流程,頁面渲染過程,JavaScript執行流程,以及Web安全理論。下面展開問題了解多進程架構: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協議,瞭解三次握手,四次揮手流程,感謝閱讀,若是你以爲這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友。

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

相關文章
相關標籤/搜索