記錄一套新鮮的前端筆試題

前言

本套筆試題來自某半知名遊戲公司,作題時間要求:四十分鐘。css

可供自測(初級前端),按需取用。html

正文

第一題

CSS 有幾種方法實現垂直水平居中?請寫出來。前端

第二題

var a='a123',b='b234',請在不調用其餘變量的狀況下,互換 a,b 的值。vue

第三題

請寫出匹配郵箱帳號的正則表達式,郵箱可包含下劃線「_」,但不能如下劃線開頭。css3

第四題

定義兩個類A、B,其中A類有屬性 type 值爲'a',使用 ES5 規範實現 B 類繼承 A 類。web

第五題

有 3 個基於 Promise 的異步函數,A、B、C;寫出按順序 A-B-C 調用的代碼(前一個函數完成後,才能執行後一個函數)。正則表達式

第六題

有一個元素長度超過 10000 且類型都會 Number 的數組 args,如何求其最大值的方法。數組

第七題

說說你對 HTTP 協議的理解,HTTP協議的底層實現。promise

第八題

分別寫出下面兩段代碼的輸出結果瀏覽器

for(var i=0;i<5;i++){
    (function(){
        setTimeout(function(){
            console.log(i)
        },i*1000)
    })(i)
}
複製代碼
for(var i=0;i<5;i++){
    (function(i){
        setTimeout(function(){
            console.log(i)
        },i*1000)
    })(i)
}
複製代碼

第九題

根據下列代碼,寫出結果,並說明緣由。

setTimeout(()=>{
    console.log(1)
},0)
new Promise((resolve,reject)=>{
    console.log(2)
    setTimeout(()=>{
        console.log(3)
        resolve(4)
    },0)
}).then((val)=>{
    console.log(val)
})
setTimeout(()=>{
    console.log(5)
},0)
console.log(6)
複製代碼

第十題

除了壓縮代碼、合併文件外,列舉出你所知道的優化網站首屏顯示速度的方法?

第十一題

vue 數據雙向綁定原理是什麼,依賴收集是如何實現的?

第十二題

請用原生 js實現一個前端路由。

解答

僅供參考,期待交流

第一題解答

CSS 有幾種方法實現垂直水平居中?請寫出來。

答:

  1. 用inline-block和vertical-align來實現居中;( 參考- Centering in the Unknown
  2. 用相對絕對定位和負邊距實現上下左右居中;(經常使用)
  3. 用Flexbox來實現水平垂直居中,注意兼容;(經常使用)
  4. 利用絕對定位來實現居中;(參考
  5. 使用css3中的transform;(參考
  6. 使用table-cell,inline-block實現水平垂直居中;

小結:儘量寫全,關鍵是要分清在不一樣的場景用不一樣的方法!

第二題解答

var a='a123',b='b234',請在不調用其餘變量的狀況下,互換 a,b 的值。

答:

var a='a123';
var b='b234';
a={a:b,b:a}
b=a.b
a=a.a
console.log(a)
console.log(b)
複製代碼

第三題解答

請寫出匹配郵箱帳號的正則表達式,郵箱可包含下劃線「_」,但不能如下劃線開頭。

答:

/^(?!_)[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
複製代碼

第四題解答

定義兩個類A、B,其中A類有屬性 type 值爲'a',使用 ES5 規範實現 B 類繼承 A 類。

答:

  1. 原型鏈繼承:即B.prototype-new A();
  2. 借用構造函數(call 或者 apply 的方式繼承);
  3. 組合繼承;

參考:六種常見繼承模式

第五題解答

有 3 個基於 Promise 的異步函數,A、B、C;寫出按順序 A-B-C 調用的代碼(前一個函數完成後,才能執行後一個函數)。

答:

function A(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log("1");
            resolve();
        },3000);
    });
}
function B(){
    return new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log("2");
            resolve();
        },1000);
    });
}
function C(){
    return  new Promise(function(resolve,reject){
        setTimeout(function(){
            console.log("3");
        },1000);
    });
}

A().then(B).then(C)

或:

A().then(()=>{
    return B();
}).then(()=>{
    return C();
})
複製代碼

第六題解答

有一個元素長度超過 10000 且類型都是 Number 的數組 args,如何求其最大值的方法。

答:選擇快速排序(是對冒泡排序的一種優化)

時間複雜度:O(nlogn)

function quickSort(arr){
    if(arr.length<=1){return arr;}    //若是數組<=1,則直接返回
    let pivotIndex = Math.floor(arr.length/2);   
    let pivot = arr.splice(pivotIndex,1)[0]; //找基準,並把基準從原數組刪除
    let left=[], right=[];    //定義左右數組
    for(let i=0; i<arr.length; i++){//比基準小的放在left,比基準大的放在right
        if(arr[i] <= pivot){
            left.push(arr[i]);   
        } else { 
        right.push(arr[i]);
        }
    }
    return quickSort(left).concat([pivot],quickSort(right));    //遞歸
}
複製代碼

第七題解答

說說你對 HTTP 協議的理解,HTTP協議的底層實現。

答:HTTP是超文本傳輸協議,是一種可靠的應用層數據傳輸協議,傳輸前須要進行三次握手進行客戶端和服務端的驗證。

經常使用的方法是:GET、POST、PUT、DELETE;

常見的返回碼有:200、30二、40三、40四、500、503

底層實現: http協議的底層是在應用層裏,是一個特殊處理的socket,創建在TCP/IP協議之上的一種普遍應用:服務器先初始化一個socket,與端口綁定,對端口進行監聽,調用阻塞,等待客戶端的鏈接。而後,初始化客戶端的socket,與服務器的socket鏈接,須要通過三次握手。

第八題解答

分別寫出下面兩段代碼的輸出結果:

for(var i=0;i<5;i++){
    (function(){
        setTimeout(function(){
            console.log(i)
        },i*1000)
    })(i)
}
複製代碼
for(var i=0;i<5;i++){
    (function(i){
        setTimeout(function(){
            console.log(i)
        },i*1000)
    })(i)
}
複製代碼

答:分別是:

//5,5,5,5,5

//0,1,2,3,4

考察點:閉包:第一段代碼沒有傳遞 i 值,第二段代碼有傳遞 i 值。

第九題解答

根據下列代碼,寫出結果,並說明緣由。

setTimeout(()=>{
    console.log(1)
},0)
new Promise((resolve,reject)=>{
    console.log(2)
    setTimeout(()=>{
        console.log(3)
        resolve(4)
    },0)
}).then((val)=>{
    console.log(val)
})
setTimeout(()=>{
    console.log(5)
},0)
console.log(6)
複製代碼

答:2,6,1,3,4,5

緣由:

  1. 首先遇到setTimeout放到宏任務隊列,
  2. 而後Promise的executor是一個同步函數,執行console.log(2)
  3. 而後又是一個setTimeout,再被推入到宏任務隊列,
  4. 而後又遇到一個setTimeout,也被推到宏任務隊列中
  5. 而後看到主線程的同步任務console.log(6),隨即打印;

// 這個時候控制檯打印了2,6;(能夠在控制檯中看到已返回「undefined」)

  1. 而後執行宏任務,console.log(1)
  2. 繼續執行宏任務隊列中的,console.log(3);此時,遇到resolve,promise.then是一個微任務,則推到主線程執行,console.log(4)
  3. 再執行宏任務隊列的任務,console.log(5)
  4. 全都執行完啦!

力薦:

一次弄懂Event Loop

Eventloop不可怕,可怕的是趕上Promise

第十題解答

除了壓縮代碼、合併文件外,列舉出你所知道的優化網站首屏顯示速度的方法?

答:

  1. 使用 CDN 加速靜態資源;
  2. webapck打包,減小資源載入,按需加載;
  3. 避免 JS 執行阻塞渲染;
  4. 圖片使用懶加載,視頻或音頻禁止自動播放,用圖標代替圖片;
  5. 充分利用本地緩存;

第十一題解答

vue 數據雙向綁定原理是什麼,依賴收集是如何實現的?

答:Vue內部經過Object.defineProperty方法屬性攔截的方式,把data對象裏每一個數據的讀寫轉化成getter/setter,當數據變化時通知視圖更新。

實現數據的雙向綁定,首先要對數據進行劫持監聽,因此咱們須要設置一個監聽器Observer,用來監聽全部屬性。若是屬性發生變化了,就須要告訴訂閱者Watcher看是否須要更新。由於訂閱者Watcher是有不少個,因此咱們須要有一個消息訂閱器Dep來專門收集這些訂閱者,而後在監聽器Observer和訂閱者Watcher之間進行統一管理。

回答來源

第十二題解答

請用原生 js實現一個前端路由。

答:

原理:以 hash 形式(也可使用 History API 來處理)爲例,當 url 的 hash 發生變化時,觸發 hashchange註冊的回調,回調中去進行不一樣的操做,進行不一樣的內容的展現。

function Router() {
    this.routes = {};
    this.currentUrl = '';
}
Router.prototype.route = function(path, callback) {
    this.routes[path] = callback || function(){};
};
Router.prototype.refresh = function() {
    this.currentUrl = location.hash.slice(1) || '/';
    this.routes[this.currentUrl]();
};
Router.prototype.init = function() {
    window.addEventListener('load', this.refresh.bind(this), false);
    window.addEventListener('hashchange', this.refresh.bind(this), false);
}
window.Router = new Router();
window.Router.init();
複製代碼

上面路由系統 Router 對象實現,主要提供三個方法:

  1. init 監聽瀏覽器 url hash 更新事件;

  2. route 存儲路由更新時的回調到回調數組routes中,回調函數將負責對頁面的更新;

  3. refresh 執行當前url對應的回調函數,更新頁面;

參考連接

結語

實打實寫一哈更重要!祝須要筆試的盆友們順利!

相關文章
相關標籤/搜索