12 道騰訊前端面試真題及答案整理

ajavascript

年末了,又到了跳槽季啦,該刷題走起了。這裏總結了一些被問到可能會懵逼的面試真題,有須要的能夠看下~css

1. 談談你對 dns-prefetch 的理解

DNS 是什麼-- Domain Name System,域名系統,做爲域名和IP地址相互映射的一個分佈式數據庫。前端

DNS Prefetching

瀏覽器根據自定義的規則,提早去解析後面可能用到的域名,來加速網站的訪問速度。簡單來說就是提早解析域名,以避免延遲。java

使用方式

<link rel="dns-prefetch" href="//wq.test.com">

這個功能有個默認加載條件,全部的a標籤的href都會自動去啓用DNS Prefetching,也就是說,你網頁的a標籤href帶的域名,是不須要在head裏面加上link手動設置的。但a標籤的默認啓動在HTTPS不起做用。git

這時要使用 meta裏面http-equiv來強制啓動功能。程序員

<meta http-equiv="x-dns-prefetch-control" content="on">

總結一下

  1. DNS Prefetching是提早加載域名解析的,省去了解析時間。a標籤的href是能夠在chrome。firefox包括高版本的IE,可是在HTTPS下面不起做用,須要meta來強制開啓功能
  2. 這是DNS的提早解析,並非css,js之類的文件緩存,你們不要混淆了兩個不一樣的概念。
  3. 若是直接作了js的重定向,或者在服務端作了重定向,沒有在link裏面手動設置,是不起做用的。
  4. 這個對於什麼樣的網站更有做用呢,相似taobao這種網站,你的網頁引用了大量不少其餘域名的資源,若是你的網站,基本全部的資源都在你本域名下,那麼這個基本沒有什麼做用。由於DNS Chrome在訪問你的網站就幫你緩存了。

拓展知識學習

  • web下的性能優化1(網絡方向)

2. get/post請求傳參長度有什麼特色

咱們常常說get請求參數的大小存在限制,而post請求的參數大小是無限制的。這是一個錯誤的說法,實際上HTTP 協議從未規定 GET/POST 的請求長度限制是多少。對get請求參數的限制是來源與瀏覽器或web服務器,瀏覽器或web服務器限制了url的長度。爲了明確這個概念,咱們必須再次強調下面幾點:github

  1. HTTP 協議 未規定 GET 和POST的長度限制
  2. GET的最大長度顯示是由於 瀏覽器和 web服務器限制了 URI的長度
  3. 不一樣的瀏覽器和WEB服務器,限制的最大長度不同
  4. 要支持IE,則最大長度爲2083byte,若只支持Chrome,則最大長度 8182byte

3. 前端須要注意哪些 SEO

  1. 合理的 title、description、keywords:搜索對着三項的權重逐個減少,title 值強調重點便可,重要關鍵詞出現不要超過 2 次,並且要靠前,不一樣頁面 title 要有所不一樣;description 把頁面內容高度歸納,長度合適,不可過度堆砌關鍵詞,不一樣頁面 description 有所不一樣;keywords 列舉出重要關鍵詞便可
  2. 語義化的 HTML 代碼,符合 W3C 規範:語義化代碼讓搜索引擎容易理解網頁
  3. 重要內容 HTML 代碼放在最前:搜索引擎抓取 HTML 順序是從上到下,有的搜索引擎對抓取長度有限制,保證重要內容必定會被抓取
  4. 重要內容不要用 js 輸出:爬蟲不會執行 js 獲取內容
  5. 少用 iframe(搜索引擎不會抓取 iframe 中的內容)
  6. 非裝飾性圖片必須加 alt
  7. 提升網站速度(網站速度是搜索引擎排序的一個重要指標)

4. 實現一個頁面操做不會整頁刷新的網站,而且能在瀏覽器前進、後 退時正確響應。給出你的技術實現方案?

第一步,經過使用 pushState + ajax 實現瀏覽器無刷新前進後退,當一次 ajax 調用成功後咱們將一 條 state 記錄加入到 history 對象中。web

第二步,一條 state 記錄包含了 url、title 和 content 屬性,在 popstate 事件中能夠 獲取到這個 state 對象,咱們可 以使用 content 來傳遞數據。第三步,咱們經過對 window.onpopstate 事件監聽來響應瀏覽器 的前進後退操做。面試

使用 pushState 來實現有兩個問題,一個是打開首頁時沒有記錄,咱們可使用 replaceState 來將首頁的記錄替換,另外一個問 題是當一個頁面刷新的時候,仍然會向服務器端請求數據,所以若是請求的 url 須要後端的配 合將其重定向到一個頁面。ajax

更多參考:http://blog.chenxu.me/post/detail?id=ed4f0732-897f-48e4-9d4f-821e82f17fad

5. 如何優化SPA應用的首屏加載速度慢的問題?

  • 將公用的JS庫經過script標籤外部引入,減少app.bundel的大小,讓瀏覽器並行下載資源文件,提升下載速度;
  • 在配置 路由時,頁面和組件使用懶加載的方式引入,進一步縮小 app.bundel 的體積,在調用某個組件時再加載對應的js文件;
  • root中插入loading 或者 骨架屏 prerender-spa-plugin,提高用戶體驗;
  • 若是在webview中的頁面,能夠進行頁面預加載
  • 獨立打包異步組件公共 Bundle,以提升複用性&緩存命中率
  • 靜態文件本地緩存,有兩種方式分別爲HTTP緩存,設置Cache-Control,Last-Modified,Etag等響應頭和Service Worker離線緩存
  • 配合 PWA 使用
  • ***
  • root中插入loading 或者 骨架屏 prerender-spa-plugin
  • 使用 Tree Shaking 減小業務代碼體積 更多參考:https://github.com/LuckyWinty/fe-weekly-questions/issues/69

6. Reflect 對象建立目的?

  1. 將 Object 對 象 的 一 些 明 顯 屬 於 語 言 內 部 的 方 法 ( 比 如 Object.defineProperty,放到 Reflect 對象上。
  2. 修改某些 Object 方法的返回結果,讓其變得更合理。
  3. 讓 Object 操做都變成函數行爲。
  4. Reflect 對象的方法與 Proxy 對象的方法一一對應,只要是 Proxy 對象 的方法,就能在 Reflect 對象上找到對應的方法。這就讓 Proxy 對象可 以方便地調用對應的 Reflect 方法,完成默認行爲,做爲修改行爲的基礎。

也就是說,無論 Proxy 怎麼修改默認行爲,你總能夠在 Reflect 上獲取 默認行爲。

7. 內部屬性 [[Class]] 是什麼?

全部 typeof 返回值爲 "object" 的對象(如數組)都包含一個內部屬性 [[Class]](我 們能夠把它看做一個內部的分類,而非傳統的面向對象意義上的類)。這個屬性沒法直接訪問, 通常經過 Object.prototype.toString(..) 來查看。例如:

Object.prototype.toString.call( [1,2,3] );  // "[object Array]" 
Object.prototype.toString.call( /regex-literal/i ); //"[object RegExp]"

多數狀況下,對象的內部[[class]]屬性和建立該對象的內建原生構造函數相對應,不過也不老是這樣。2.基本類型值的[[class]]屬性

雖然Null()和Undefined()這樣的原生構造函數並不存在,可是內部[[class]]屬性仍然是「Null」和「Undefined」。

console.log(Object.prototype.toString.call(null)); //[object Null]

console.log(Object.prototype.toString.call(undefined)); //[object Undefined]

其餘基本類型值的狀況有所不一樣:

console.log(Object.prototype.toString.call("abc")); //[object String]

console.log(Object.prototype.toString.call(42));  //[object Number]

console.log(Object.prototype.toString.call(true)); //[object Boolean]

基本類型值被各自的封裝對象自動包裝,因此他們的內部[[class]]屬性分別爲「String」,「Number」和「Boolean」。3.封裝對象

因爲基本類型值沒有.length和.toString()這樣的屬性和方法,須要經過封裝對象才能訪問,此時Javascript引擎會自動爲基本類型值包裝一個封裝對象。

//封裝對象包裝

var b = 'abc';
console.log(b.length);
console.log(b.toUpperCase());
```js
通常不直接使用封裝對象(即經過new操做建立基本類型值),優先考慮使用「abc」和「42」這樣的基本類型值,而不是new String("abc") 和 new Number(42)。4.拆封

若是想要獲得封裝對象中的基本類型值,可使用valueOf()函數。 
`
``js
//封裝對象的拆封
var s = new String"abc" );
var n = new Number42 );
var b = new Booleantrue );

console.log(s.valueOf());
console.log(n.valueOf());
console.log(b.valueOf());

8. 什麼是堆?什麼是棧?它們之間有什麼區別和聯繫?

堆和棧的概念存在於數據結構中和操做系統內存中。在數據結構中,棧中數據的存取方式爲 先進後出。而堆是一個優先隊列,是按優先級來進行排序的,優先級能夠按照大小來規定。徹底 二叉樹是堆的一種實現方式。在操做系統中,內存被分爲棧區和堆區。棧區內存由編譯器自動分 配釋放,存放函數的參數值,局部變量的值等。其操做方式相似於數據結構中的棧。堆區內存一 般由程序員分配釋放,若程序員不釋放,程序結束時可能由垃圾回收機制回收。

詳細資料能夠參考:《什麼是堆?什麼是棧?他們之間有什麼區別和聯繫?》

9. isNaN 和 Number.isNaN 函數的區別?

函數 isNaN 接收參數後,會嘗試將這個參數轉換爲數值,任何不能被轉換爲數值的的值都會返 回 true,所以非數字值傳入也會返回 true ,會影響 NaN 的判斷。

函數 Number.isNaN 會首先判斷傳入參數是否爲數字,若是是數字再繼續判斷是否爲 NaN ,這種方法對於 NaN 的判斷更爲準確。

10. 什麼狀況下會發生布爾值的隱式強制類型轉換?

(1) if (..) 語句中的條件判斷表達式。(2) for ( .. ; .. ; .. ) 語句中的條件判斷表達式(第二個)。(3) while (..) 和 do..while(..) 循環中的條件判斷表達式。(4) ? : 中的條件判斷表達式。(5) 邏輯運算符 ||(邏輯或)和 &&(邏輯與)左邊的操做數(做爲條件判斷表達式)。

11. undefined 與 undeclared 的區別?

已在做用域中聲明但尚未賦值的變量,是 undefined 的。相反,尚未在做用域中聲明 過的變量,是 undeclared 的。對於 undeclared 變量的引用,瀏覽器會報引用錯誤,如 ReferenceError: b is not defined 。可是咱們可使用 typeof 的安全防範機制來避免 報錯,由於對於 undeclared(或者 not defined )變量,typeof 會返回 "undefined"。

12. 如何封裝一個 javascript 的類型判斷函數?

function getType(value
  // 判斷數據是 null 的狀況 
  if (value === null) { 
      return value + ""
  }
  // 判斷數據是引用類型的狀況 
  if (typeof value === "object") { 
    let valueClass = Object.prototype.toString.call(value), 
    type = valueClass.split(" ")[1].split(""); 
    type.pop(); 
    return type.join("").toLowerCase();
  } else { 
    // 判斷數據是基本數據類型的狀況和函數的狀況 
    return typeof value
  }
}



最後

  • 歡迎加我微信(winty230),拉你進技術羣,長期交流學習...

  • 歡迎關注「前端Q」,認真學前端,作個專業的技術人...

image.png

相關文章
相關標籤/搜索