阿里面試:“說一下從 url 輸入到返回請求的過程”
閱讀本文大概需要 8.5 分鐘。
前言
問題: 從瀏覽器地址欄輸入url到請求返回發(fā)生了什么?
先說為什么url要解析(也就是編碼)
我回答大概內(nèi)容是:因為網(wǎng)絡(luò)標(biāo)準(zhǔn)規(guī)定了URL只能是字母和數(shù)字,還有一些其它特殊符號(-_.~ ! * ' ( ) ; : @ & = + $ , / ? # [ ],特殊符號是我下來查的資料,實在背不住這么多,比較常見的就是不包括百分號和雙引號),而且如果不轉(zhuǎn)義會出現(xiàn)歧義,比如 http:www.baidu.com?key=value,假如我的key本身就包括等于=符號,比如ke=y=value,就會出現(xiàn)歧義,你不知道=到底是連接key和value的符號,還是說本身key里面就有=。大佬接著毒打我說,那url編碼的規(guī)則是什么呢,我說utf-8 大佬接著窮追不舍,為啥是utf-8呢,所有瀏覽器都是這樣嗎?中文的話用gb2312編碼嗎,還有就是萬一瀏覽器不是你說的這樣統(tǒng)一用utf-8,你怎么保證都是utf-8的編碼? 我支支吾吾的說,我了解的大概是這樣,不太清楚, 應(yīng)該和html本身的編碼格式有關(guān),然后怎么保證utf-8的編碼,我覺得可以用encodeURIComponent 大佬說encodeURIComponent比encodeURI有什么區(qū)別? 區(qū)別就是encodeURIComponent編碼范圍更廣,適合給參數(shù)編碼,encodeURI適合給URL本身(locaion.origin)編碼,當(dāng)然項目里一般都是用qs庫去處理
然后說說dns解析流程,并且html如何做dns優(yōu)化
<meta http-equiv="x-dns-prefetch-control" content="on" />
<link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />
第一次握手:主機A發(fā)送位碼為SYN=1的TCP包給服務(wù)器,并且隨機產(chǎn)生一個作為確認(rèn)號(這是tcp包的一部分),主機B收到SYN碼后直到A要求建立連接; 第二次握手:主機B收到請求后,向A發(fā)送確認(rèn)號(主機A的seq+1),syn=1,seq = 隨機數(shù) 的TCP包; 主機A收到后檢查確認(rèn)號是否正確,即第一次A發(fā)送的確認(rèn)號是否+1了,以及位碼ack是否為1,若正確,主機A會再發(fā)送確認(rèn)號(主機B的seq+1),ack=1,主機B收到后確認(rèn)seq值與ack=1則連接建立成功。
接著,大佬說出個加分題,我看你不是科班出身,能答多少是多少。問題是,從網(wǎng)卡把數(shù)據(jù)包傳輸出去到服務(wù)器發(fā)生了什么,提示我OSI參考模型
我說,先從局域網(wǎng)把數(shù)據(jù)發(fā)送到公司的交換機(如果交換機沒有緩存本地mac地址和IP地址的映射,此時會通過ARP協(xié)議來獲得),交換機的好處是可以隔離沖突域(因為以太網(wǎng)用的是CSMA/CD協(xié)議,這個協(xié)議規(guī)定網(wǎng)線上同一時刻只能有一臺機器發(fā)送數(shù)據(jù)),這樣就可以不僅僅同一時刻只有一臺機器發(fā)送網(wǎng)絡(luò)包了 然后交換機再將數(shù)據(jù)發(fā)送到路由器,路由器相當(dāng)于公司網(wǎng)關(guān)(我們公司小),路由器具有轉(zhuǎn)發(fā)和分組數(shù)據(jù)包的功能(路由器通過選定的路由協(xié)議會構(gòu)造出路由表,同時不定期的跟相鄰路由器交換路由信息),然后這算是經(jīng)過了物理層,數(shù)據(jù)鏈路層(以太網(wǎng)),開始到網(wǎng)絡(luò)層進行數(shù)據(jù)轉(zhuǎn)發(fā)了 然后路由器轉(zhuǎn)發(fā)IP數(shù)據(jù)報,一般公司的IP地址都會經(jīng)過NAT轉(zhuǎn)換,讓內(nèi)網(wǎng)的ip也能夠訪問外網(wǎng),我們公司我注意了一下是192.168打頭的內(nèi)網(wǎng)ip地址。通過路由器的分組傳輸,所有數(shù)據(jù)到達服務(wù)器。 然后服務(wù)器的上層協(xié)議傳輸層協(xié)議開始發(fā)揮作用,根據(jù)tcp包里的端口號,讓服務(wù)器特定的服務(wù)來處理到來的數(shù)據(jù)包,并且tcp是面向字節(jié)流的(tcp有四大特性,可靠傳輸、流量控制、擁塞控制、連接管理),所以我們node的request對象,它的監(jiān)聽事件data事件為什么要用字符串一起拼接起來呢(buffer),就是因為tcp本身就是字節(jié)流,request對象使用的data(http層面)是tcp傳來的數(shù)據(jù)塊。 最后數(shù)據(jù)由傳輸層轉(zhuǎn)交給應(yīng)用層,也就是http服務(wù)(或者h(yuǎn)ttps),后端經(jīng)過一系列邏輯處理,返回給前端數(shù)據(jù)。
答完這里,我說大佬我只知道大概的流程,具體細(xì)節(jié)我不是很清楚,但自己后面會補上。。。
堅決不給中國人發(fā)Offer的GitLab成立中國公司!立志3-5年上市,怕是聞到了韭菜香?瀏覽器首次加載資源成功時,服務(wù)器返回200,此時瀏覽器不僅將資源下載下來,而且把response的header(里面的date屬性非常重要,用來計算第二次相同資源時當(dāng)前時間和date的時間差)一并緩存; 下一次加載資源時,首先要經(jīng)過強緩存的處理,cache-control的優(yōu)先級最高,比如cache-control:no-cache,就直接進入到協(xié)商緩存的步驟了,如果cache-control:max-age=xxx,就會先比較當(dāng)前時間和上一次返回200時的時間差,如果沒有超過max-age,命中強緩存,不發(fā)請求直接從本地緩存讀取該文件(這里需要注意,如果沒有cache-control,會取expires的值,來對比是否過期),過期的話會進入下一個階段,協(xié)商緩存 協(xié)商緩存階段,則向服務(wù)器發(fā)送header帶有If-None-Match和If-Modified-Since的請求,服務(wù)器會比較Etag,如果相同,命中協(xié)商緩存,返回304;如果不一致則有改動,直接返回新的資源文件帶上新的Etag值并返回200; 協(xié)商緩存第二個重要的字段是,If-Modified-Since,如果客戶端發(fā)送的If-Modified-Since的值跟服務(wù)器端獲取的文件最近改動的時間,一致則命中協(xié)商緩存,返回304;不一致則返回新的last-modified和文件并返回200;
我說強緩存會觸發(fā),這兩種,具體什么行為不知道,大概內(nèi)容如下:
1、先查找內(nèi)存,如果內(nèi)存中存在,從內(nèi)存中加載;
2、如果內(nèi)存中未查找到,選擇硬盤獲取,如果硬盤中有,從硬盤中加載;
3、如果硬盤中未查找到,那就進行網(wǎng)絡(luò)請求;
4、加載到的資源緩存到硬盤和內(nèi)存;
// Date 減去 Last-Modified 值的 10% 作為緩存時間。
// Date:創(chuàng)建報文的日期時間, Last-Modified 服務(wù)器聲明文檔最后被修改時間
response_is_fresh = max(0,(Date - Last-Modified)) % 10
構(gòu)建DOM樹(DOM tree):從上到下解析HTML文檔生成DOM節(jié)點樹(DOM tree),也叫內(nèi)容樹(content tree); 構(gòu)建CSSOM(CSS Object Model)樹:加載解析樣式生成CSSOM樹; 執(zhí)行JavaScript:加載并執(zhí)行JavaScript代碼(包括內(nèi)聯(lián)代碼或外聯(lián)JavaScript文件); 構(gòu)建渲染樹(render tree):根據(jù)DOM樹和CSSOM樹,生成渲染樹(render tree); 渲染樹:按順序展示在屏幕上的一系列矩形,這些矩形帶有字體,顏色和尺寸等視覺屬性。 布局(layout):根據(jù)渲染樹將節(jié)點樹的每一個節(jié)點布局在屏幕上的正確位置; 繪制(painting):遍歷渲染樹繪制所有節(jié)點,為每一個節(jié)點適用對應(yīng)的樣式,這一過程是通過UI后端模塊完成;
頁面渲染優(yōu)化
HTML文檔結(jié)構(gòu)層次盡量少,最好不深于六層; 腳本盡量后放,放在前即可; 少量首屏樣式內(nèi)聯(lián)放在標(biāo)簽內(nèi); 樣式結(jié)構(gòu)層次盡量簡單; 在腳本中盡量減少DOM操作,盡量緩存訪問DOM的樣式信息,避免過度觸發(fā)回流; 減少通過JavaScript代碼修改元素樣式,盡量使用修改class名方式操作樣式或動畫; 動畫盡量使用在絕對定位或固定定位的元素上; 隱藏在屏幕外,或在頁面滾動時,盡量停止動畫; 盡量緩存DOM查找,查找器盡量簡潔; 涉及多域名的網(wǎng)站,可以開啟域名預(yù)解析
推薦閱讀:
七個開源的 SpringBoot 前后端分離項目,Star過千,快去收藏夾吃灰吧!
最近面試BAT,整理一份面試資料《Java面試BATJ通關(guān)手冊》,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。
朕已閱 
評論
圖片
表情

