最近面試的一些總結

前言

發表一下本身對面試的見解。首先面試跟實際水平是有誤差的,與工做經驗是有關係的,但也不是正比關係。html

手寫代碼跟手敲代碼區別挺大的,手敲代碼能進行調試,可是手寫代碼,會犯不少的低級錯誤,由於脫離了IDE帶來的提示。不過手寫代碼是可以看出面試者的思路的,大部分的面試官基本只是看看思路以及邏輯嚴謹性。前端

另外,其實面試就是公司讓你去造飛機,其實工做頂多擰擰螺絲釘。不過每一個人知識的深度和廣度,以及這我的的潛力,有經驗的面試官是可以看出來的。這也是面試的時候offer到手的籌碼,別覺得背背面試題就能夠了。平時多嚴格要求本身,多多得研究和總結。vue

進入正題

公司名字我都不寫了基本都是大廠,有些公司的面試題我沒有貼出來,都是爛大街的前端面試題,你們看看這篇文章就夠了。es6

題目我也只是挑一些本身以爲比較經典的,分享給你們!面試

一、寫一個函數fn(10),獲取0-100之內的隨機數傳入一個數組,數組內不能重複出現想同的數字,數組長度爲10(下面寫的代碼進行了一部分改造原題);
function getRandomNum(num,[min,max]){
    let arr = [];
    if(typeof num === "number" && typeof min === "number" && typeof max === "number"){
        // console.log(num,min,max);
        while(true){
            let isExit = false;
            let randomNum = parseInt(min + (max-min) * Math.random());
            //方法一:
            // for(let i = 0;i<arr.length;i++){
            //     if(arr[i]===randomNum){
            //         console.log(arr[i]);
            //         isExit = true;
            //         break;
            //     }
            // }
            
            //方法二:
            let set = new Set(arr)
            if(!set.has(randomNum)){
                arr.push(randomNum);
            }


            if(arr.length === num) break;
        }
    }else{
        throw Error("請傳入Number類型!")
    }
    return arr;
}

let randomArr = getRandomNum(10,[10,100]);
console.log(randomArr);

二、給定這麼一個數據:
let data = [{
    id:1,
    name:"北京"
},{
    id:1,
    name:"天津",
    children:[{
        id:1,
        name:"西青"
    },{
        id:1,
        name:"和平",
        children:[{
            id:1,
            name:"和平一"
        },{
            id:1,
            name:"和平二"
        }]
    }]
}]
寫一個函數將數據內的key值namechildren相應的替換成lablecity
function dealData(arr){
    if(arr instanceof Array){
        let dealedArr = JSON.parse(JSON.stringify(arr));
        let new_arr = changeKey(dealedArr);
        return new_arr;
    }else{
        throw Error("請傳入數組!")
    }
}

function changeKey(arr){
    let new_arr = arr.map((item,index)=>{
        if(item.hasOwnProperty("name")){
            item["lable"]=item["name"];
            delete item.name;
        }
        if(item.children && item.children.length > 0){
            item['city'] = changeKey(item.children);
            delete item.children;
        }
        return item;
    })
    return new_arr;
}
let arr = dealData(data);
console.log(arr);

三、給一個數組以下
const tree = [ '1', ['2', '3'], [4, ["5",6]]];
須要改形成
let new_tree = ["1", "2", "3", 4, "5", 6];

這道題面試的時候,一眼看過去真的會懵逼,反正我是懵逼了。不過只要懂一些iterator的知識,其實並不難;segmentfault

const tree = [ '1', ['2', '3'], [4, ["5",6]]];

function* iteratorTree(tree){
    if(typeof tree === "string" || typeof tree === "number"){
        yield tree;
    }else if(tree instanceof Array){
        for (const i of tree) {
            yield* iteratorTree(i)
        }
    }
}


// for(const i of iteratorTree(tree)){
//     console.log(i);
// }
console.log([...iteratorTree(tree)]);
四、說一說promise的實現原理

so,我也是比較懵逼的,只是會用而已,惡補了下這篇文章設計模式


五、js類型檢測的各類方法及其對比

轉移現場,看看這篇文章數組


六、vue雙向綁定的基本原理

這個題我估計只要考到vue,基本都會考到吧!promise

vue.js 是採用數據劫持結合發佈者-訂閱者模式的方式,經過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。
具體步驟:

第一步:須要observe的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上 setter和getter
這樣的話,給這個對象的某個值賦值,就會觸發setter,那麼就能監聽到了數據變化服務器

第二步:compile解析模板指令,將模板中的變量替換成數據,而後初始化渲染頁面視圖,並將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變更,收到通知,更新視圖

第三步:Watcher訂閱者是Observer和Compile之間通訊的橋樑,主要作的事情是:
一、在自身實例化時往屬性訂閱器(dep)裏面添加本身
二、自身必須有一個update()方法
三、待屬性變更dep.notice()通知時,能調用自身的update()方法,並觸發Compile中綁定的回調,則功成身退。

第四步:MVVM做爲數據綁定的入口,整合Observer、Compile和Watcher三者,經過Observer來監聽本身的model數據變化,經過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通訊橋樑,達到數據變化 -> 視圖更新;視圖交互變化(input) -> 數據model變動的雙向綁定效果。

這種題通常考到以後,先問你瞭解發佈者訂閱者模式(觀察者模式)的實現,再問你是否瞭解其餘的js的設計模式;

其實,只要咱們曾經在DOM節點上綁定過事件函數,那咱們曾經就使用過發佈-訂閱模式;好比click事件,給某個dom節點添加click事件,其實就是訂閱了這個dom節點的click事件,當這個dom被點擊的時候,就會像訂閱者click事件發佈這個消息。

發佈訂閱者模式我用得也不多,用得比較多的也就是單例模式代理模式,遇到這種狀況的瞭解哪種說哪種吧,別瞎比比就行。畢竟面試要求你什麼都會,而實際工做須要用什麼。js設計模式建議你們仍是多看看,畢竟前人總結出來的好東西,不用一用,你還好意思說本身是站在巨人的肩膀上麼?


七、vue生命週期鉤子的理解(vue2.0+)
  • beforeCreate:在實例初始化以後,數據觀測(data observer)event/watcher事件配置以前被調用。
  • created :實例已經建立完成以後被調用。在這一步,實例已完成如下的配置:數據觀測(data observer),屬性和方法的運算,watch/event事件回調。然而,掛載階段還沒開始,$el屬性目前不可見。
  • beforeMount:在掛載開始以前被調用:相關的 render 函數首次被調用,也就是說,render函數此時會生成虛擬的dom節點,即vm.$el
  • mountedel被新建立的vm.$el替換,並掛載到實例上去以後調用該鉤子。若是root實例掛載了一個文檔內元素,當mounted被調用時vm.$el也在文檔內。
  • beforeUpdate:數據更新時調用,發生在虛擬DOM從新渲染和打補丁以前。 你能夠在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。
  • updated:因爲數據更改致使的虛擬DOM從新渲染和打補丁,在這以後會調用該鉤子。當這個鉤子被調用時,組件DOM已經更新,因此你如今能夠執行依賴於DOM的操做。然而在大多數狀況下,你應該避免在此期間更改狀態,由於這可能會致使更新無限循環。
  • beforeDestroy:實例銷燬以前調用。在這一步,實例仍然徹底可用。
  • destroyed:Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。 該鉤子在服務器端渲染期間不被調用。該鉤子在服務器端渲染期間不被調用。

八、http狀態碼有哪些?

大概說說就行,這種狀態碼,其實工做中遇到了直接就給後臺說一聲就行,反正我歷來不記,面試的時候,大體看看記了一下

100-199 用於指定客戶端應相應的某些動做。
200-299 用於表示請求成功。
300-399 用於已經移動的文件而且常被包含在定位頭信息中指定新的地址信息。
400-499 用於指出客戶端的錯誤。400 一、語義有誤,當前請求沒法被服務器理解。
401 當前請求須要用戶驗證 403 服務器已經理解請求,可是拒絕執行它。
500-599 用於支持服務器錯誤。 503 – 服務不可用

九、談一談let
  • 與var的不一樣在於,用let聲明的變量只在 { } 內有效。這使得咱們能夠很方便的實現塊級做用域,再也不使用當即實行函數。
{  
  let a=1;  
  var b=2;  
}  
console.log(a); //undefined  
console.log(b); //2
  • let不會變量提高。也就是說,若是你使用var ,能夠先使用變量再定義變量(注意:變量提高只提高聲明不提高賦值操做),可是若是你使用let定義變量則必須先定義後使用,不然會報錯。
console.log(a);//報錯:Uncaught ReferenceError: a is not defined  
console.log(b); //undefined  
let a=1;  
var b=2;
  • 暫時性死區(Temporal Dead Zone),只要塊級做用域內有let,let 聲明的變量不受全局同名變量的影響,若是想要在塊級做用域內使用let 聲明的變量,只能爲其賦值。
var a=1;  
if(true){  
  a=2;  
  let a; //Uncaught ReferenceError: a is not defined  
}
  • 不容許在一個塊級做用域內重複聲明一個變量

不論是var與let重複聲明,仍是let與let重複聲明,都會報錯。

爲了方便你們看,把原文複製了一遍給你們看,懶得去本身敲栗子了!


十、promise的一個題
console.log('1');
    setTimeout(function() {
      console.log('2');
    }, 0);
    Promise.resolve().then(function() {
      console.log('3');
    }).then(function() {
      console.log('4');
    });
    console.log('5');

順序是:15342

console.log(1)

setTimeout(() => {
    console.log(2)
}, 0)

new Promise(resolve => {
    console.log(3)
    resolve()
}).then(() => {
    console.log(4)
})

console.log(5)

順序是:13542

這個題也比較簡單,注意一個是有new關鍵字的,另外一個是直接在then方法中輸出的,當心這個陷阱就OK了!


十一、簡單寫一下數組中求差集的方法

考過這道題以後,本身回來總結了一下數組中的求交集、差集、並集的方法,包括es5es6兩種方式,你們能夠去看看


暫時先寫到這兒吧!最近手頭事兒比較多,還有面試,有經典的題再跟你們分享!

後續

持續更新
若是有更好的方法,請及時交流。
可加微信 YOYO_ZCC
最近在面試,多多交流;

[...面試題]

相關文章
相關標籤/搜索