【前端面試分享】- 寒冬求職上篇

前言

在這互聯網的寒冬臘月時期,雖然說過了金三銀四,但依舊在招人不斷。更偏向於招聘高級開發工程師。本人在這期間求職,去了幾家創業,小廠,大廠廝殺了一番,也獲得了本身滿意的offer。javascript

整理一下本身還記得的面試題,但願能幫助到還在求職的你。大佬略過,不喜勿噴。css

記錄下我遇到的面試題,都有大佬分享過,附上各個大佬的文章,總結出其中的主要思想便可。html

基礎算法篇

【前端面試分享】- 寒冬求職下篇前端

css篇

1. 盒模型

概念就不介紹了,請看一個例題,若你能立馬反應過來,就說明掌握的不錯了。vue

/* 紅色區域的大小是多少? */
.box {
    width: 200px;
    height: 200px;
    padding: 20px;
    margin: 20px;
    background: red;
    border: 20px solid black;
    box-sizing: border-box;
}
複製代碼

2. 水平垂直居中

貼上一位騰訊大佬總結的文章java

16種方法實現水平居中垂直居中node

按照固定寬高和不固定寬高分類各說幾個方法就能夠了。react

3. 頁面佈局

3.1 高度已知,三欄佈局,左右寬度300,中間自適應

/* 浮動佈局 */
  .layout.float .left{
    float:left;
    width:300px;
    background: red;
  }
  .layout.float .center{
    background: yellow;
  }
  .layout.float .right{
    float:right;
    width:300px;
    background: blue;
  }
 /* 決定定位佈局 */
 .layout.absolute .left-center-right>div{
  position: absolute;
 }
.layout.absolute .left{
  left:0;
  width: 300px;
  background: red;
}
.layout.absolute .center{
  left: 300px;
  right: 300px;
  background: yellow;
}
.layout.absolute .right{
  right:0;
  width: 300px;
  background: blue;
}
 /* flex佈局 */
  .layout.flexbox{
      margin-top: 110px;
    }
    .layout.flexbox .left-center-right{
      display: flex;
    }
    .layout.flexbox .left{
      width: 300px;
      background: red;
    }
    .layout.flexbox .center{
      flex:1;
      background: yellow;
    }
    .layout.flexbox .right{
      width: 300px;
      background: blue;
    }
複製代碼

固然還有 table 佈局 和 grid 佈局。webpack

當你回答出來之後,面試官還可能會追問你,這幾種佈局有什麼優缺點,兼容性?git

若是把高度已知換成未知,又該怎麼作?

這些都是咱們要考慮總結的。

3.2 高度已知,兩欄佈局,左邊固定,右邊自適應

基本思路和三欄佈局同樣

3.3 如何實現左右等高佈局

table 佈局就登場了

section {
    width:100%;
  display: table;
}
article  {
    display: table-cell;
}
.left {
    height: 100px;
    background: red;
}
.right {
    background: black;
}
複製代碼

4. 如何實現一個最大的正方形

padding-bottom 撐開邊距就能夠了。

section {
    width:100%;
    padding-bottom: 100%;
    background: #333;
}
複製代碼

5. css 的解析順序

css 選擇器匹配元素是逆向解析

  • 由於全部樣式規則可能數量很大,並且絕大多數不會匹配到當前的 DOM 元素(由於數量很大因此通常會創建規則索引樹),因此有一個快速的方法來判斷「這個 selector 不匹配當前元素」就是極其重要的。
  • 若是正向解析,例如「div div p em」,咱們首先就要檢查當前元素到 html 的整條路徑,找到最上層的 div,再往下找,若是遇到不匹配就必須回到最上層那個 div,往下再去匹配選擇器中的第一個 div,回溯若干次才能肯定匹配與否,效率很低。
  • 逆向匹配則不一樣,若是當前的 DOM 元素是 div,而不是 selector 最後的 em,那隻要一步就能排除。只有在匹配時,纔會不斷向上找父節點進行驗證。

因此爲了減小查找時間,儘可能不要直接使用標籤選擇器。

6. css 如何開啓 gpu 加速

請參考網易雲社區的文章CSS動畫的性能分析和瀏覽器GPU加速

js篇

1. 不借助第三者交換 a,b兩個值。

/* 方法一 */
a = a + b;
b = a - b;
a = a - b;

/* 方法二 */
a = a - b;
b = a + b;
a = b - a;

/* 方法三 */
a = {a:b,b:a};
b = a.b;
a = a.a;

/* 方法四 */
a = [a,b];
b = a[0];
a = a[1];

/* 方法五 */
[a,b] = [b,a];
複製代碼

2. new 的過程和實現

/* 選自 yck 文章 */
function create(Con, ...args) {
  let obj = {}
  Object.setPrototypeOf(obj, Con.prototype)
  let result = Con.apply(obj, args)
  return result instanceof Object ? result : obj
}

複製代碼

若是你能清楚的瞭解上邊代碼的原理,請忽略。

否則的話建議閱讀下邊大佬的文章。

推薦 yck 的文章 重學 JS 系列:聊聊 new 操做符

3. Eventloop

不管是筆試仍是面試,高頻出現,要知其然還要知其因此然。

/* 選自 小美娜娜 文章 */
async function async1() {
    console.log("async1 start");
    await  async2();
    console.log("async1 end");
}

async  function async2() {
    console.log( 'async2');
}

console.log("script start");

setTimeout(function () {
    console.log("settimeout");
},0);

async1();

new Promise(function (resolve) {
    console.log("promise1");
    resolve();
}).then(function () {
    console.log("promise2");
});
console.log('script end'); 

複製代碼

若是你能很清楚的知道每一步的輸出,能夠忽略。

否則的話建議閱讀下邊大佬的文章,解釋的很詳細。

推薦 小美娜娜 的文章 Eventloop不可怕,可怕的是趕上Promise

4. 繼承優缺點

function inherits(childCtor, parentCtor) {
    function tempCtor() {};
    tempCtor.prototype = parentCtor.prototype;
    childCtor.prototype = new tempCtor();
    childCtor.prototype.constructor = childCtor;
};
複製代碼

好比說 原型繼承,構造函數繼承,組合繼承等。

向面試官從簡到難介紹每一個繼承的優缺點,一步步的寫出最完美的繼承。

絕對能加好多分。

推薦一篇 路易斯 的文章 JS原型鏈與繼承別再被問倒了

5. 實現一個 promise

首先你須要對 promise 有一個清晰的認識,封裝過請求,使用過它的 api 等。

請參考 前端勸退師 的文章 「中高級前端面試」JavaScript手寫代碼無敵祕籍

6. 實現一個按順序加載的 promise

當你說出 promise.all 和 promise.race 的區別後,面試官可能就會接着考察此題。

/* 使用 async await */
async function queue(tasks) {
  const res = []
  for (let promise of tasks) {
    res.push(await promise(res));
  }
  return await res
}
queue([a, b, c])
  .then(data => {
    console.log(data)
  })
複製代碼

固然也可使用 reduce 方法。

7. 對 import 和 module.exports的理解

考察對模塊化的理解。 區分 Es6 和 commonJs 規範。

能夠參考 有贊 2dunn 的 文章 import、require、export、module.exports 混合使用詳解

8. 實現一個 EventEmitter 方法

當你回答出 vue 中用 emit 通訊的時候,就要當心了。

EventEmitter 方法主要包含了 on,emit,once,off方法。

class Event {
    constructor() {
          this.events = Object.create(null);
      }
      on(name, fn) {
        if (!this.events[name]) {
            this.events[name] = []
          }
          this.events[name].push(fn);
          return this;
      }
      emit(name, ...args) {
        if (!this.events[name]) {
            return this;
        }
        const fns = this.events[name]
        fns.forEach(fn => fn.call(this, ...args))
        return this;
      }
      off(name,fn) {
        if (!this.events[name]) {
            return this;
        }
          if (!fn) {
            this.events[name] = null
            return this
          }
          const index = this.events[name].indexOf(fn);
          this.events[name].splice(index, 1);
        return this;
      }
      once(name,fn) {
        const only = () => {
          fn.apply(this, arguments);
          this.off(name, only);
        };
        this.on(name, only);
        return this;
      }
  }
複製代碼

能夠參考 尤大大的 vue 源碼 vue-event

9. this 指向

若是你能清楚的知道每一個this的指向,能夠忽略。

好比說 默認綁定,隱式綁定,顯示綁定,new 綁定。

/* 節選自 京東小姐姐 文章 */
var obj = {
    hi: function(){
        console.log(this);
        return ()=>{
            console.log(this);
        }
    },
    sayHi: function(){
        return function() {
            console.log(this);
            return ()=>{
                console.log(this);
            }
        }
    },
    see: function() {
        console.log(this);
        (function(){
            console.log(this)
        })()
    },
    say: ()=>{
        console.log(this);
    }
}
let hi = obj.hi(); 
hi();            
let sayHi = obj.sayHi();
let fun1 = sayHi(); 
fun1();             
obj.say();
obj.see();
複製代碼

不清楚的話,建議閱讀一下

京東小姐姐的文章 嗨,你真的懂this嗎?

10. 普通函數和箭頭函數的區別

  • this指向的問題,會捕獲其所在上下文的 this 值,做爲本身的 this 值。
  • 箭頭函數不綁定 arguments,取而代之用rest參數解決。
var foo = (...args) => {
  return args[0]
}
console.log(foo(1)) 
複製代碼
  • 箭頭函數不能用做構造器,和 new 一塊兒用就會拋出錯誤。
  • 箭頭函數沒有原型屬性。
var foo = () => {};
console.log(foo.prototype) //undefined
複製代碼

11. 考察本地存儲

/* 如下代碼會輸出什麼 */
localStorage.setItem('show',false);
console.log(localStorage.show || '顯示')
複製代碼

vue篇

1. vnode的轉換過程 和 dom-diff 的過程

有的大廠面試官須要你手寫這個過程,很殘忍有木有。

請參考 360-chenhongdong大佬的文章 讓虛擬DOM和DOM-diff再也不成爲你的絆腳石

2. key值的做用

使用 v-for更新已渲染的元素列表時,默認用就地複用策略。列表數據修改的時候,他會根據key值去判斷某個值是否修改:若是修改,則從新渲染這一項;不然複用以前的dom,僅修改value值。

詳細參考 阿里-funnycoderstar 文章爲何使用v-for時必須添加惟一的key?

3. 對 v-show的理解

我猜你可能會回答 v-show 經過控制樣式的 display: nonedisplay: block 實現顯示隱藏的。 你以爲這樣合理嗎?

好比說:對一個 img 或者 span 使用 v-show,那麼當它爲 true 的時候不就把內聯元素改爲塊級元素了嘛。

出題目啦:

/* 1.此時span是顯示仍是隱藏? */
<span class="span" v-show="isShow">111</span>
<script> data() { return { isShow: false } }, </script>
<style> .span { display: block; } </style>

/* 2.此時span是顯示仍是隱藏? */
<span class="span" v-show="isShow">111</span>
<script> data() { return { isShow: true } }, </script>
<style> .span { display: none; } </style>
複製代碼

v-show 控制顯隱,是經過 js 代碼去修改元素的 element style。 若是 value 爲 false,設置 display: none; 若是 value 爲 true,清除 display 屬性。 因此 value 爲 true 時,只是將 element style 中的 display 效果清除,並不能覆蓋 css 中的 display 樣式。

4. vue的生命週期

不要直接巴拉巴拉的說出那幾個英文單詞,建議按照官網圖的執行順序來引出各個生命週期名稱,會有加分的。

react篇

1. react的自定義事件和原生事件的區別

React 並非將 click 事件綁在該 div 的真實 DOM 上,而是在 document 處監聽全部支持的事件,當事件發生並冒泡至 document 處時,React 將事件內容封裝並交由真正的處理函數運行。

詳情請參考文章 螞蟻金服-Nekron 大佬的文章 React合成事件和DOM原生事件混用須知

2. setState是異步仍是同步的

不要着急回答是異步的,再上問的基礎上 setState 也能夠是同步的。

setState 只在合成事件和鉤子函數中是「異步」的,在原生事件和 setTimeout 中都是同步的。

詳情請閱讀 餓了麼-虹晨大佬的文章 你真的理解setState嗎?

3. redux和vuex的區別

  • redux 是 flux 的一種實現,redux 不僅僅能夠用在 react 上面。
  • vuex 是 redux 的基礎上進行改變,對倉庫的管理更加明確。
  • 數據流向不同,vuex 的同異步有不一樣的流向,而 redux 的同異步是同樣的。
  • redux 使用的是不可變的數據,而 vuex 的數據是可變的,redux 每次修改更新數據,其實就是用新的數據替換舊的數據,而 vuex 是直接修改原數據。

4.react 和 vue 的 diff 過程有什麼區別

React 是這麼幹的:你給我一個數據,我根據這個數據生成一個全新的 Virtual DOM,而後跟我上一次生成的 Virtual DOM 去 diff,獲得一個 Patch,而後把這個 Patch 打到瀏覽器的 DOM 上去。完事。而且這裏的 Patch 顯然不是完整的 Virtual DOM,而是新的 Virtual DOM 和上一次的 Virtual DOM 通過 diff 後的差別化的部分。

Vue 在渲染過程當中,會跟蹤每個組件的依賴關係,不須要從新渲染整個組件樹。

React 每當應用的狀態被改變時,所有子組件都會從新渲染。 這能夠經過 shouldComponentUpdate 這個生命週期方法來進行控制。

React diff的是 Dom,而 Vue diff 的是數據。

webpack篇

1. webpack 如何進行打包優化

從提取公共模塊,區分開發環境,移除重複沒必要要的 css 和 js 文件等方面說。

推薦arlendp2012的文章 Webpack打包優化

2. webpack 打包原理

  • 初始化:啓動構建,讀取與合併配置參數,加載 Plugin,實例化 Compiler。
  • 編譯:從 Entry 發出,針對每一個 Module 串行調用對應的 Loader 去翻譯文件內容,再找到該 Module 依賴的 Module,遞歸地進行編譯處理。
  • 輸出:對編譯後的 Module 組合成 Chunk,把 Chunk 轉換成文件,輸出到文件系統。

推薦whjin的文章 webpack原理

瀏覽器篇

1. 如何實現跨域

主要介紹 jsonp 和 cors 便可,其餘能夠一筆帶過。

推薦閱讀 浪裏行舟 大佬的文章 九種跨域方式實現原理(完整版)

2. 輸入url後的加載過程

簡要回答出 域名解析,返回資源,瀏覽器渲染,重排重繪概念等便可。

推薦 浪裏行舟 文章從URL輸入到頁面展示到底發生什麼?

3. 緩存

分爲 強緩存 和 協商緩存, 各自的標識要記住。

推薦 黑金團隊的文章 前端緩存最佳實踐

推薦名揚的文章 淺解強緩存和協商緩存

4. http狀態碼

重點是 301 302 304 401 等,要給面試官介紹清楚。

304 的話就會涉及到上問的緩存,能詳細介紹下會是個加分項。

推薦騎摩托馬斯文章,有圖有文字 具備表明性的 HTTP 狀態碼

5. 本地存儲

要記住 cookie 的幾個屬性值,分別是作什麼的。

好比說 cookie 設置了 express 屬性,存儲位置有什麼區別?

好比說 a.snow.com 和 b.snow.com 兩個網頁如何共享 cookie ?

推薦 Damonare的文章 Javascript 本地存儲小結

6. http請求頭有哪些

介紹幾個,而後說清楚各自的做用便可。

又會涉及到 緩存頭的知識。

推薦很是兔的文章http請求頭與響應頭的應用

7. 路由實現的原理

兩種模式 hash 和 history。

推薦尋找海藍96的文章 面試官: 你瞭解前端路由嗎?

8. 常見的內存泄露

全局變量,未清除的定時器,閉包,以及 dom 的引用等。

推薦掘金的LeviDing文章 [譯] JavaScript 工做原理:內存管理 + 處理常見的4種內存泄漏

9. 前端安全問題

主要從 XSS 和 CSRF 兩個方面回答便可。

推薦 京東小姐姐的文章 【面試篇】寒冬求職之你必需要懂的Web安全

10. GET 和 POST 的區別

這題道理很深,也有不少誤區。

推薦 WebTechGarden 微信公衆號的文章 99%的人都理解錯了HTTP中GET與POST的區別

11. 對 HTTP2 的理解

HTTP2號稱可讓咱們的應用更快、更簡單、更穩定,它完美解決了1.1版本的諸多問題。

推薦黑金團隊的文章 面試官問:你瞭解HTTP2.0嗎?

擴展篇

1. 請問你怎麼看待技術和業務的關係?

歡迎討論、、、

2. 請問你怎麼看待996或者說公司加班?

也歡迎討論,,,

總結

寫業務的同時,不要忘記提升本身的基礎知識,css,js,http 等,纔會在面試中脫穎而出。

水平有限,若是有不妥的回答,還望指出,謝謝。

下篇總結下遇到的編碼算法相關題目。

有你才完美

自認很菜,建立了一個數據結構和算法的交流羣,不限開發語言,前端後端,歡迎各位同窗入駐。

羣以超過掃碼限制人數,能夠加我好友,邀請你入羣。

請備註:掘金加羣

相關文章
相關標籤/搜索