1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        阿里面試:“說一下從 url 輸入到返回請求的過程”

        共 5418字,需瀏覽 11分鐘

         ·

        2021-04-02 11:08

        不點藍(lán)字,我們哪來故事?

        每天 11 點更新文章,餓了點外賣,點擊 ??《無門檻外賣優(yōu)惠券,每天免費領(lǐng)!》

        作者 | 孟祥_成都

        來源 | https://juejin.cn/post/6928677404332425223

        前言

        年前準(zhǔn)備換工作,總結(jié)了一波面試最頻繁的面試問題跟大家交流。此文章是關(guān)于瀏覽器的常見問題,大概面試10家遇到6家提問類似問題(主要是大廠和中廠)。(面試的部分內(nèi)容已經(jīng)忘了,為了串聯(lián)成一個完整的故事,增加可讀性,20%的內(nèi)容為虛構(gòu)),目前入職滴滴出行成都團(tuán)隊。

        問題: 從瀏覽器地址欄輸入url到請求返回發(fā)生了什么

        你一看這種爛掉牙的問題,小case,但996面試大佬由此延展的問題已經(jīng)遠(yuǎn)遠(yuǎn)超越了這個問題本身了,不信你就接著看。

        我回答了首先會進(jìn)行 url 解析,根據(jù) dns 系統(tǒng)進(jìn)行 ip 查找。

        話音剛落,此時一位喜歡修福報的公司的大佬打斷了我,說url為啥要解析,dns查詢規(guī)則是什么?我一聽就心里想,不按套路出牌啊,網(wǎng)上一般都沒問這兩個問題,心里再一想,俗話說,萬事開頭難,扛過這一波,答出來,就是陽光明媚,萬物騷動的春天!

        先說為什么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)歧義,你不知道=到底是連接keyvalue的符號,還是說本身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)化

        首先dns這個屬于很久以前在計算機(jī)網(wǎng)絡(luò)謝希仁版看到過了,有一些細(xì)節(jié)忘了,但是大致流程是記得的。比如說查詢一個網(wǎng)址為:www.baidu.com

        1、器中輸入https://www.baidu.com 域名,操作系統(tǒng)會先查hosts件是否有記錄,有的話就會把相對應(yīng)映射的IP返回。

        2、hosts文件沒有就去查本地dns解析器有沒有緩存。(這個我沒答上來)

        3、然后就去找我們計算機(jī)上配置的dns服務(wù)器上有或者有緩存,就返回

        4、還沒有的話就去找根DNS服務(wù)器(全球13臺,固定ip地址),然后判斷.com域名是哪個服務(wù)器管理,如果無法解析,就查找.baidu.com服務(wù)器是否能解析,直到查到www.baidu.com的IP地址

        注:后面查資料才發(fā)現(xiàn)dns查詢有兩種模式,一種是轉(zhuǎn)發(fā)模式,一種是非轉(zhuǎn)發(fā)模式,我上面說的4是非轉(zhuǎn)發(fā)模式。

        前端的dns優(yōu)化,可以在html頁面頭部寫入dns緩存地址,比如

        <meta http-equiv="x-dns-prefetch-control" content="on" />
        <link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />

        終于抗過了第一輪的猛問,接著我繼續(xù)說從瀏覽器地址欄輸入url到請求返回發(fā)生了什么?


        查找到IP之后,就是http協(xié)議的三次握手(以及后面會涉及到四次分手)

        我剛恢復(fù)節(jié)奏,準(zhǔn)備侃侃而談,修福報的大佬再次打斷了我,說三次握手,為啥兩次不行,順便說一下3次握手發(fā)生了什么。

        我去,大意了,沒有閃,這是不是說我每說一句都要夾雜著各種問題,太難了?。。。?/p>

        沒有辦法,繼續(xù)回答大佬,我說我先回答三次握手發(fā)生的事情吧,簡答來說:

        • 第一次握手:主機(jī)A發(fā)送位碼為SYN=1的TCP包給服務(wù)器,并且隨機(jī)產(chǎn)生一個作為確認(rèn)號(這是tcp包的一部分),主機(jī)B收到SYN碼后直到A要求建立連接;
        • 第二次握手:主機(jī)B收到請求后,向A發(fā)送確認(rèn)號(主機(jī)A的seq+1),syn=1,seq = 隨機(jī)數(shù) 的TCP包;
        • 主機(jī)A收到后檢查確認(rèn)號是否正確,即第一次A發(fā)送的確認(rèn)號是否+1了,以及位碼ack是否為1,若正確,主機(jī)A會再發(fā)送確認(rèn)號(主機(jī)B的seq+1),ack=1,主機(jī)B收到后確認(rèn)seq值與ack=1則連接建立成功。

        接著補(bǔ)上小問題為什么兩次握手不行,因為第二次握手,主機(jī)B還不能確認(rèn)主機(jī)A已經(jīng)收到確認(rèn)請求,也是說B認(rèn)為建立好連接,開始發(fā)數(shù)據(jù)了,結(jié)果發(fā)出去的包一直A都沒收到,那攻擊B就很容易了,我專門發(fā)包不接收,服務(wù)器很容易就掛了。

        接著,大佬說出個加分題,我看你不是科班出身,能答多少是多少。問題是,從網(wǎng)卡把數(shù)據(jù)包傳輸出去到服務(wù)器發(fā)生了什么,提示我OSI參考模型

        我一聽,好嘛,這不是計算機(jī)網(wǎng)絡(luò)的知識嗎,幸虧之前看過書,但也是好久以前看過了,只能憑借自己的理解解答了。

        • 我說,先從局域網(wǎng)把數(shù)據(jù)發(fā)送到公司的交換機(jī)(如果交換機(jī)沒有緩存本地mac地址和IP地址的映射,此時會通過ARP協(xié)議來獲得),交換機(jī)的好處是可以隔離沖突域(因為以太網(wǎng)用的是CSMA/CD協(xié)議,這個協(xié)議規(guī)定網(wǎng)線上同一時刻只能有一臺機(jī)器發(fā)送數(shù)據(jù)),這樣就可以不僅僅同一時刻只有一臺機(jī)器發(fā)送網(wǎng)絡(luò)包了
        • 然后交換機(jī)再將數(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ò)層進(jìn)行數(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ù)到達(dá)服務(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é)我不是很清楚,但自己后面會補(bǔ)上。。。

        大佬讓我繼續(xù),我就接著3次握手之后接著說道,建立完鏈接,就該請求html文件了,如果html文件在緩存里面瀏覽器直接返回,如果沒有,就去后臺拿

        剛說到緩存,立馬就有一種不詳?shù)念A(yù)感,果不其然大佬先讓把緩存解釋一下。緩存這種問爛的問題,本以為能輕松應(yīng)對,結(jié)果還是被問了個滿頭包。。。。

        堅決不給中國人發(fā)Offer的GitLab成立中國公司!立志3-5年上市,怕是聞到了韭菜香?

        我說的大概意思是:

        • 瀏覽器首次加載資源成功時,服務(wù)器返回200,此時瀏覽器不僅將資源下載下來,而且把response的header(里面的date屬性非常重要,用來計算第二次相同資源時當(dāng)前時間和date的時間差)一并緩存;
        • 下一次加載資源時,首先要經(jīng)過強(qiáng)緩存的處理,cache-control的優(yōu)先級最高,比如cache-control:no-cache,就直接進(jìn)入到協(xié)商緩存的步驟了,如果cache-control:max-age=xxx,就會先比較當(dāng)前時間和上一次返回200時的時間差,如果沒有超過max-age,命中強(qiáng)緩存,不發(fā)請求直接從本地緩存讀取該文件(這里需要注意,如果沒有cache-control,會取expires的值,來對比是否過期),過期的話會進(jìn)入下一個階段,協(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;

        果不其然,大佬問了一些緩存不常問的,首先就是問我知道什么是from disk cache和from memory cache嗎,什么時候會觸發(fā)?

        • 我說強(qiáng)緩存會觸發(fā),這兩種,具體什么行為不知道,大概內(nèi)容如下:
        1、先查找內(nèi)存,如果內(nèi)存中存在,從內(nèi)存中加載;
        2、如果內(nèi)存中未查找到,選擇硬盤獲取,如果硬盤中有,從硬盤中加載;
        3、如果硬盤中未查找到,那就進(jìn)行網(wǎng)絡(luò)請求;
        4、加載到的資源緩存到硬盤和內(nèi)存;

        接著大佬又問知道什么是啟發(fā)式緩存嗎,在什么條件下觸發(fā)?

        這個問題給我的感覺就兩個字,懵逼!然后如實回答不知道。(查了下資料大概如下)

        啟發(fā)式緩存:

        如果響應(yīng)中未顯示Expires,Cache-Control:max-age或Cache-Control:s-maxage,并且響應(yīng)中不包含其他有關(guān)緩存的限制,緩存可以使用啟發(fā)式方法計算新鮮度壽命。通常會根據(jù)響應(yīng)頭中的2個時間字段 Date 減去 Last-Modified 值的 10% 作為緩存時間。

        // Date 減去 Last-Modified 值的 10% 作為緩存時間。
        // Date:創(chuàng)建報文的日期時間, Last-Modified 服務(wù)器聲明文檔最后被修改時間
          response_is_fresh =  max(0,(Date -  Last-Modified)) % 10

        接著回答,我說返回html之后,會解析html,這部分知識我提前準(zhǔn)備過,但是答的不是很詳細(xì),大概意思就是cssom + domTree = html,然后布局和繪制

        • 構(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)化手段,大概如下:

        頁面渲染優(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ù)解析

        最后面試官問我,如何診斷頁面渲染時各個性能指標(biāo),我大概說了,通過chrome瀏覽器的工具,比如看網(wǎng)絡(luò)請求情況的network,還有看頁面渲染情況的perfermance,以后有機(jī)會自己總結(jié)一篇。

        往期推薦

        面試官:這貨一聽就是一個水貨。。。

        頭條二面:你們公司怎么處理 MySQL 的 Binlog 日志?

        紅包免費送!

        技術(shù)大佬們都是怎么學(xué)習(xí)的?

        下方二維碼關(guān)注我

        技術(shù)草根,堅持分享 編程,算法,架構(gòu)

        看完文章,餓了點外賣,點擊 ??《無門檻外賣優(yōu)惠券,每天免費領(lǐng)!》

        朋友,助攻一把!點個在看!


        瀏覽 27
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            性生活直播间 | 宝贝裙子内不许穿内裤打屁股 | 欧美老妇逼 | 亚洲女人在线 | 大色鬼AV| 小操逼| 丰满的熟女荫蒂高潮喷水91 | 丰满少妇理论片在线观看 | 亚洲无码在线免费观看视频 | 欧美午夜成人理论电影网站小视频 |