前幾天看到一個題目,問在瀏覽器中輸入一個URL會發生神馬,這好像是網上比較流行的面試題,並且也被回答爛了,仔細想下來,要是本身遇到這個題目能不能答上來,後來一想,這個題目要徹底答出來能夠把大學開始的幾乎全部知識都用上。呵呵,爲了模擬面試,因此都憑印象說的,沒有查網絡資料,因此估計不少地方都不對,歡迎來拍。
後續能夠總結一個很是很是詳細的版本,我的感受真的能夠把大學開始的全部的東西都用上,包括連數電模電(所有流程都跑不掉),信息論(gzip壓縮),密碼學(HTTPS),通信原理(網絡基帶傳輸)這種均可以,本文仍是以軟件處理過程爲主。html
輸入網址嘛,那就是鍵盤輸入了,鍵盤通常用usb或者PS/2口鏈接電腦,如今見過PS/2口的人很少了吧,咱們就看看usb吧,usb分爲主從模式,通常的鍵盤自己的usb是一個從設備,相應的還有u盤啊,鼠標啊都是從設備,對應的主機端的USBcontroller是一個主設備,這個主設備掛在CPU上,在X86結構的機器上是掛在主板的南橋(好像是的,反正是低速的那個)芯片上,若是是ARM這類嵌入式設備的話,那麼就是掛在APB總線上,對這個我熟悉一些,就按ARM這種SoC來講吧,當是在手機上輸入URL吧,呵呵。nginx
鍵盤輸入字符之後,經過USB協議(USB協議簡單的來講就是一個串行協議,靠一個時鐘電信號和一個數據電信號傳輸數據)將數據傳輸到APB總線上的USB控制器上。而後這個控制器開始搶總線,總線的APB橋
接收到信號之後也開始經過APB總線上的時鐘和數據線發送一個中斷信號
到APB橋
中,APB橋
同時鏈接在AHP
高速總線上,接收完數據之後,它開始搶高速總線,高速總線上有個Arbiter(總線仲裁器)
,由於高速總線上接的都是內存啊這種傢伙,你一個小小的USB不見得搶得過他們,等仲裁器給你時間之後,APB橋
開始把中斷信號發給CPU。web
CPU接收到這個中斷之後,要是沒有其餘更高級的中斷須要處理的話就會調用內核中的中斷處理函數開始處理中斷,中斷處理函數又分爲底半部和頂半部,首先會是底半部處理,把中斷放處處理隊列中就返回了,而後頂半部從隊列根據註冊的的中斷號拿到本身對應的中斷號進行處理,這時候中斷處理函數就算收到這個信號了,至關於硬件的電信號已經傳遞到軟件層了,中斷處理函數會調用USB的驅動程序去USB控制器上讀取這個輸入的字符,這個字符仍是經過兩條總線(APB和AHB)以獨佔的方式傳遞到軟件層上,其實呢,是軟件控制這個信號寫到了內存的某個空間上。面試
整個流程是這樣的算法
發出中斷 :鍵盤--->usb控制器 ---> APB橋 ---> CPU硬件中斷 ---> 中斷處理底部 ---> 中斷處理函數頂部 ---> 驅動程序 ---> 讀取數據 ---> CPU尋址 ---> 寫入內存後端
假設咱們輸入的url以C語言的scanf
函數爲例,scanf函數會一直在內核態阻塞着,直到中斷處理函數接收到了全部的字符而且接受到了一個回車符,這時scanf語句會經過操做系統的read調用把緩衝區的全部字符從內核態拷貝到用戶態,這時這些個字符就從電信號傳遞到了應用程序(瀏覽器)的軟件層了。瀏覽器
整個流程是服務器
scanf ---> 系統調用read ---> 內核態阻塞等待 ---> 讀取拷貝數據 ---> 用戶態接收數據微信
由於軟件層也不是一個實體層次,其實全部的操做最後都變成了硬件的電信號,全部沒辦法把流程寫得很明白,大概就是這麼個意思吧。網絡
應用程序(瀏覽器)接收到這個URL之後,就開始走網絡層來獲取數據了,這裏咱們就不深刻到底層的電信號了,就按網絡這一套來講吧。
首先就要解析域名了,瀏覽器會先看一下本地的host文件,看有沒有url域名對應的ip地址,若是沒有的話,會經過DNS協議發送數據包給DNS服務器詢問域名的ip地址,DNS服務本身沒有對應的ip的話會繼續往上尋找,而後把ip地址發回給瀏覽器。DNS協議是UDP的,但好像有特殊狀況是TCP鏈接,好像是各個DNS服務器之間傳輸用的TCP吧,無論了,反正經過UDP這個傳輸層協議之上的DNS應用層協議把url對應的ip地址獲得了。
拿到ip地址之後,假設咱們輸入的網址是https://www.baidu.com/
,百度的服務器在北京,而咱們在上海,瀏覽器就經過connect開始鏈接這個這個北京的ip地址了,鏈接跑到tcp/ip協議棧之後,協議棧一看這個IP和本地IP根本就不在一個段上啊,那ARP也不發了,直接把數據包轉發到網關上,也就是家裏的路由器上了,路由器拿到地址,查一下本地的路由表,呀,我這小路由表上沒這個網段的啊,那我無論了,給個人上級路由吧(也許是小區的大路由器了),小區路由一看,我這也沒有啊,這樣一級一級傳遞到了上海的城際路由上,而後到了北京的城際路由,這麼一層一層下來終於傳到了百度的服務器上。
在這裏看上去簡單,可是路由的算法是很複雜的,這一塊我也不太懂沒弄過,可是Dijkstra
選路算法仍是明白的,別問我爲何記得這個單詞,大學計算機網絡課的課程做業啊,就是實現這個Dijkstra
啊,經過路由算法,終於把第一個數據包發送給百度的服務器了。
這個數據包是神馬呢,就是咱們熟悉的TCP三次握手的第一握了,SYN=1的那個數據包,關於三次握手就很少說了,你們都知道,關鍵是我不記得細節了,反正就是你們都懂的,握手完了鏈接就創建完了。爲何創建鏈接須要三次握手,關閉鏈接須要四次握手,呵呵,寫不動了。
同時,在百度服務器這邊,有個web服務器的應用程序(好比Nginx),一直在監聽着80端口,收到這個數據包之後也同時和客戶端創建起了鏈接了。
鏈接創建好之後,是TCP鏈接創建了,這時經過更上層的HTTP協議開始傳輸數據,HTTP協議自己很複雜,這裏咱們簡單的來講,就是瀏覽器發送了一個GET / HTTP/1.1 \n\r
字符串給了服務器,服務器接受到這個字符串之後,經過協議棧傳遞給了上層的Nginx應用程序。
應用程序一看這個地址是/
,而後對照一下本身的配置文件nginx.conf
,有個配置告訴他碰到這種請求,直接把本地的index.html
吐出去,因而Nginx讀取index.html
並把數據經過這條TCP鏈接回覆給了客戶端。
因爲http協議是無狀態的,因此本次傳輸完數據之後,這個連接就關閉了。
好了,後面的就是接受到數據的顯示了,關於webkit內核的細節就真不清楚了,就是解DOM樹,執行JS代碼,從新請求CSS和圖片,而後把頁面畫出來吧。
哦了,題目作完了,其實還有不少細節沒有說的,好比網絡尋址的時候的ARP協議啊,路由器尋路的其餘不少算法啊,Nginx處理請求的時候的幾個階段解讀啊,是否須要反向代理到後端的服務器上啊,最後顯示的時候還須要操做顯卡進行顯存的操做,若是頁面中有複雜的圖形效果還須要GPU參與運算之類的,要寫就寫不完了。
若是你以爲不錯,歡迎轉發給更多人看到,也歡迎關注個人公衆號,主要聊聊搜索,推薦,廣告技術,還有瞎扯。。文章會在這裏首先發出來:)掃描或者搜索微信號XJJ267或者搜索西加加語言就行