阿里P7:你瞭解路由嗎?

好學習吧丶發表於2020-04-03

交代背景

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

跳槽心得:小廠出來的,除了基本功要紮實之外,投簡歷一定要先頭小廠在投你想去的公司,遵循先易後難,先拿到一些offer,有了底氣,才能有信心,才能有大概率去你想去的公司,雖然本人比較遺憾(也是能力不夠)沒有去到想去的公司,但是還是祝願大家都能如願去到想去的單位(個人感覺面試時信心非常重要,畢竟寫程式碼的能力和麵試中的表達那是兩碼事)

懵逼經歷

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

首先大佬讓介紹自己:.......胡說八道了一堆

然後大佬讓說一下自己的優點:......又胡說八道了一堆

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

再然後,噩夢開始..... 覆盤總結如下:

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

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

真題模擬

大佬:你瞭解路由嗎?

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

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

我:後端路由又可稱之為伺服器端路由,因為對於伺服器來說,當接收到客戶端發來的HTTP請求,就會根據所請求的相應URL,來找到相應的對映函式,然後執行該函式,並將函式的返回值傳送給客戶端。對於最簡單的靜態資源伺服器,可以認為,所有URL的對映函式就是一個檔案讀取操作。對於動態資源,對映函式可能是一個資料庫讀取操作,也可能是進行一些資料的處理,等等。然後根據這些讀取的資料,在伺服器端就使用相應的模板來對頁面進行渲染後,再返回渲染完畢的頁面。這種方式在早期的前端開發中非常普遍,比如京東頁面就是個後端路由,他請求的就是一個頁面

阿里P7:你瞭解路由嗎?

對於前端路由來說,路由的對映函式通常是進行一些DOM的顯示和隱藏操作

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

我:後端路由優點是:安全性好,SEO好,缺點是:加大伺服器的壓力,不利於使用者體驗,程式碼冗合 ,前端的路由就是優點是:前端路由在訪問一個新頁面的時候僅僅是變換了一下路徑而已,沒有了網路延遲,對於使用者體驗來說會有相當大的提升缺點是:使用瀏覽器的前進,後退鍵的時候會重新傳送請求,沒有合理地利用快取,同樣的不利於seo

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

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

  • 1、hash
  • 2、history Api

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

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

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

1、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的變化

相關文章