阿里P7:你瞭解路由嗎?

交代背景

年後被迫跳槽,其中種種一言難盡,因而投遞簡歷,雖然有了年前嘗試積累,但年前畢竟不是真正的跳槽。因爲沒有遵循大佬們的跳槽心得,面試時,先投小廠,再投大廠,致使,隨機面試,上來就碰見了個阿里的P7,被問的啞口無言。時隔半月,覆盤總結html

跳槽心得:小廠出來的,除了基本功要紮實以外,投簡歷必定要先頭小廠在投你想去的公司,遵循先易後難,先拿到一些offer,有了底氣,纔能有信心,纔能有大機率去你想去的公司,雖然本人比較遺憾(也是能力不夠)沒有去到想去的公司,可是仍是祝願你們都能如願去到想去的單位(我的感受面試時信心很是重要,畢竟寫代碼的能力和麪試中的表達那是兩碼事) 前端

懵逼經歷

面試頭一遭,給了阿里,總結以下:面試

首先大佬讓介紹本身:.......胡說八道了一堆數據庫

而後大佬讓說一下本身的優勢:......又胡說八道了一堆後端

接着大佬讓分別說一下這些優勢有都時怎麼體現的:.....再次胡說八道一大堆(因爲沒有準備,即興真的很糟糕)api

再而後,噩夢開始..... 覆盤總結以下:瀏覽器

  • 圍繞一個知識點連續發問,直到無言以對(反映出面試大廠準備必定要深刻,切忌知道皮毛)
  • 問的知識點都是你以前在優勢中提到的技術積累(反映出在介紹本身時必定要慎重,不太深刻的知識必定不要放在介紹裏)
  • 問的問題考察還都是以基礎爲主,只不過深刻挖掘這些基礎知識了(反映出基礎必定要紮實再去阿里)

以上都是三點總結爲血淚教訓,接下來我以題目的例子爲例,模擬大佬面試問的一個問題(假設我都能回答上來),幫助後來人在遇見想去的公司以前,杜撰面試場景,增長成功的機會!緩存

真題模擬

大佬:你瞭解路由嗎?

我:瞭解,這種spa應用,都是用的前端路由,其餘的都是後端路由安全

大佬:哪能分別解釋一下嗎?

我:後端路由又可稱之爲服務器端路由,由於對於服務器來講,當接收到客戶端發來的HTTP請求,就會根據所請求的相應URL,來找到相應的映射函數,而後執行該函數,並將函數的返回值發送給客戶端。對於最簡單的靜態資源服務器,能夠認爲,全部URL的映射函數就是一個文件讀取操做。對於動態資源,映射函數多是一個數據庫讀取操做,也多是進行一些數據的處理,等等。而後根據這些讀取的數據,在服務器端就使用相應的模板來對頁面進行渲染後,再返回渲染完畢的頁面。這種方式在早期的前端開發中很是廣泛,好比京東頁面就是個後端路由,他請求的就是一個頁面bash

對於前端路由來講,路由的映射函數一般是進行一些DOM的顯示和隱藏操做

大佬:那他們分別有什麼優缺點呢?

我:後端路由優勢是:安全性好,SEO好,缺點是:加大服務器的壓力,不利於用戶體驗,代碼冗合 ,前端的路由就是優勢是:前端路由在訪問一個新頁面的時候僅僅是變換了一下路徑而已,沒有了網絡延遲,對於用戶體驗來講會有至關大的提高缺點是:使用瀏覽器的前進,後退鍵的時候會從新發送請求,沒有合理地利用緩存,一樣的不利於seo

大佬:那前端路由有幾種方案呢?

我: 前端路由主要有如下兩種實現方案:

  • 一、hash
  • 二、history Api

大佬:那他們有什麼區別呢?

我:hash在地址欄中的表現有一個# 而history並無(這是我當時的答案,比較草率)

大佬:那你分別說說他們的實現原理

一、hash

我:hash實現就是基於location.hash來實現的。其實現原理也很簡單,location.hash的值就是URL中#後面的內容。好比百度網站,設置它的location.hash='#abcsdf',那麼他的網址就是:

https://www.baidu.com/#abcsdf
複製代碼

咱們可使用hashchange事件來監聽hash的變化。而且經過history.length能看到路由總數

大佬:你能不能用hash的方案實現一個路由切換

//首先咱們要有個html
  <ul>
      <li><a href="#luyou1">路由1</a></li>
      <li><a href="#luyou2">路由2</a></li>
      <li><a href="#luyou3">路由3</a></li>
    </ul>
    <div id="luyouid"></div>
複製代碼
//ts邏輯
      class router {
        //存貯當前路由
        hashStr: String;
        constructor(hash: String) {
          //初始化賦值
          this.hashStr = hash;
          //初始化
          this.watchHash();
          //綁定監聽改變事件,因爲this被換了,必須用bind綁定
          this.watch = this.watchHash.bind(this);
          window.addEventListener("hashchange", this.watch);
        }
        //監聽方法
        watchHash() {
          console.log();
          let hash: String = window.location.hash.slice(1);
          this.hashStr = hash;
          console.log(hashStr);
          if (hashStr) {
            if (hashStr == "luyou1") {
              document.querySelector("#luyouid").innerHTML = "好好學習每天向上";
            } else if (hashStr == "luyou2") {
              document.querySelector("#luyouid").innerHTML = "每天向上好好學習";
            } else {
              document.querySelector("#luyouid").innerHTML = "學習向上";
            }
          }
        }
      }
複製代碼

大佬:那history Api 的原理呢?

history

我:history 這個對象在html的時候新加入兩個api history.pushState() 和 history.repalceState() 這兩個 API能夠在不進行刷新的狀況下,操做瀏覽器的歷史紀錄。惟一不一樣的是,前者是新增一個歷史記錄,後者是直接替換當前的歷史記錄,

大佬:那這個兩個api怎麼用?

window.history.pushState(state,title,url)
//state:須要保存的數據,這個數據在觸發popstate事件時,能夠在event.state裏獲取
//title:標題,基本沒用,通常傳null
//url:設定新的歷史紀錄的url。新的url與當前url的origin必須是同樣的,不然會拋出錯誤。url能夠時絕對路徑,也能夠是相對路徑。
//如 當前url是 https://www.baidu.com/a/,執行history.pushState(null, null, './qq/'),則變成 https://www.baidu.com/a/qq/,
//執行history.pushState(null, null, '/qq/'),則變成 https://www.baidu.com/qq/

window.history.replaceState(state,title,url)
//與pushState 基本相同,但她是修改當前歷史紀錄,而 pushState 是建立新的歷史紀錄
複製代碼

大佬:除了這兩個api history還有其餘的啥api呢?

window.history.back()//後退
window.history.forward()//前進
window.history.go(1)//前進一部,-2回退兩不,window.history.length能夠查看當前歷史堆棧中頁面的數量
複製代碼

大佬:這些操做執行了怎麼監聽呢?

我:每當同一個文檔的瀏覽歷史(即history)出現變化時,就會觸發popState事件,只要咱們監聽事件便可

window.addEventListener('popstate', function(event) {
});
複製代碼

大佬:全部的都能監聽,你肯定嗎?

我:僅僅調用pushState方法或replaceState方法,並不會觸發該事件,只有用戶點擊瀏覽器後退和前進按鈕時,或者使用js調用back、forward、go方法時纔會觸發。

大佬:那麼如何監聽 pushState 和 replaceState 的變化呢?

我:咱們能夠建立2個全新的事件,事件名爲pushState和replaceState,咱們就能夠在全局監聽

//建立全局事件
var _wr = function(type) {
   var orig = history[type];
   return function() {
       var rv = orig.apply(this, arguments);
      var e = new Event(type);
       e.arguments = arguments;
       window.dispatchEvent(e);
       return rv;
   };
};
//重寫方法
 history.pushState = _wr('pushState');
 history.replaceState = _wr('replaceState');
//實現監聽
window.addEventListener('replaceState', function(e) {
  console.log('THEY DID IT AGAIN! replaceState 111111');
});
window.addEventListener('pushState', function(e) {
  console.log('THEY DID IT AGAIN! pushState 2222222');
});
複製代碼

最後

至此,一個問題算是圓滿結束了。其實我在真實的面試中只回答到了,問我history有哪些api,而後實在是不會了,這種連續刨根問底的發文方式,我以爲好像是阿里面試官的廣泛面試方式,因此,請切記,若是簡歷上寫的東西必定確保很是瞭解,否則千萬別寫,否則這種刨根問底的問法,你在不是很瞭解的知識點上早晚要露餡的。

而後,祝你們跳槽都能去滿意的單位!

參考:如何監聽URL的變化

相關文章
相關標籤/搜索