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

前言

有人說,如果你懂得瀏覽器的工作原理,你就能解決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(流控制傳輸協議)。

連接創建

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(Transmit Control  Block)。

  • 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:

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

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

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/interview-answe/issues/27

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

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

閱讀資料

瀏覽器工作原理與實踐

https://time.geekbang.org/column/intro/100033601

總結

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

—————END—————

喜歡本文的朋友,歡迎關注公衆號 程序員小灰,收看更多精彩內容

點個[在看],是對小灰最大的支持!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章