1. 程式人生 > >某上市公司的前端面試

某上市公司的前端面試

2018已步入尾聲,苦苦奮鬥了一年的各位程式猿(媛)們估計早已蠢蠢欲動,憧憬著新的一輪漲薪,話不多說,直接上程式碼,一切沒有答案和解說的面試題都是耍牛氓,各位看官如果有收穫,請務必記得點贊給餘支援

一面就不多說了,簡單的問了一下基本情況

1.目前用的什麼框架?
2.正在做什麼專案?
3.有沒有做過xxx?(這裡很可能就是你即將去貴公司要參與的專案,這時候就知道自己改對症下藥了)
4.有了解過xxx? (比如es6,nodejs,webpack)

基礎面試

每一次console.log輸出多少,將 var 改成 let,每一次的console.log輸出又是多少
var a = 10; // 全域性變數掛載在 window 物件上
 (function () {
        // 匿名函式的回撥形成獨立的作用域,函式內部無法獲取外部的 a
        // 變數宣告提升 var a;
        console.log(a); // 輸出 undefined
        a = 5; //  沒有用 var 進行宣告,會在該作用域內部形成全域性變數,而且會變數宣告提升
        console.log(a); //  5
        console.log(window.a); // 輸出 10
        var a = 20; // 重新賦值
        console.log(a) // 輸出20
  })()

嗯嗯,看完感覺一搬搬,沒有是麼特殊的難點,唯一的坑就是第一個 console.log(a) 也許你會以為返回 10,只要你牢記作用域,任憑在花哨的出題也無法擾亂我們堅守的道心,那就是 作用域、作用域、作用域

如果將 外部 var 改成let
let a = 10; // let 宣告的變數不會掛載到全域性window物件上
(function () {
    // 匿名函式的回會形成獨立的作用域,函式內部無法獲取外部的 a
    // 變數宣告提升 var a;
    console.log(a); // 輸出 undefined
    a = 5; // 沒有用 var 進行宣告,會在該作用域內部形成全域性變數,而且會變數宣告提升
    console.log(a); //  5
    console.log(window.a); // 輸出 undefined
    var a = 20; // 重新賦值
    console.log(a) // 輸出20
})()

既然都已經無法訪問了,隨你怎麼改,俺就是不為所動,你愛誰誰啊,這就是純粹的忽悠,不要面試官一問你瑟瑟發抖,堅守本心最重要

如果將 回撥函式內部的 var 改成 let
var a = 10; // let 宣告的變數不會掛載到全域性window物件上
(function () {
    console.log(a); // 用let進行宣告,就存在了內部的塊級作用域,  a is not undefined
    a = 5; //  看起來有了內部的全域性變數,但是操作依然在 let 之前,所以然並卵  a is not defined
    console.log(a);
    console.log(window.a); // 10
    let a = 20; // 重新賦值
    console.log(a) // 輸出20
})()

關於 let 塊級作用域的學習,請參見 阮大大的es6教程

是不是很簡單,其實也沒有考啥,就是一個作用域的問題,我說過,萬變不離其中,不要被各種各樣的用法所迷惑

原生js封裝一個事件代理

eg: proxy(document.querySelector(‘ul’), ‘li’, ‘click’, function () { console.log(this.innerHTML) })

// 面向物件的程式設計小小的秀一下
const proxyUtil = {
  // 獲取目標物件
  getTarget: function (event) {
    return event.target || event.srcElement;
  },
  proxy: function (element, targetEle, handleType, handle) {
    let _that = this
    element["on" + handleType] = function (e) {
      let target = _that.getTarget(e); // 獲取目標節點
      if (target.nodeName.toLocaleLowerCase() === targetEle) {
        handle.call(target, null)
      }
    }
  }
}

proxyUtil.proxy(document.querySelector('ul'), 'li', 'click', function () {
  console.log(this.innerHTML)
})

考察的知識點很簡單,就是對原生js的理解,大廠嘛,就是喜歡自己造輪子,你懂得,Ta 們並不喜歡不可控的輪子,當然自己早的輪子肯定就是最安全的毋庸置疑

以下的輸出結果

 (function () {
    var i=0;
    var arr = [];
    for (i; i< 3;i++) {
      arr.push(function () {
        console.log(i)
      })
    }
    arr[0](); // 3
    arr[1](); // 3
    arr[2](); // 3
  })()

以上老生常談的問題就不做解釋為什麼了哈?如果時至如今,在前端江湖,這個還不懂,請恕我不能為力

將var 改成 let

  (function () {
    let i=0;
    let arr = [];
    for (i; i< 3;i++) {
      arr.push(function () {
        console.log(i)
      })
    }
    arr[0](); // 3
    arr[1](); // 3
    arr[2](); // 3
  })()

這就是一個心理戰術啊,可憐的程式設計師,曾經以為只要會敲程式碼完成任務就夠,後來發現和自己水平相當甚至稍有遜色的同事比自己的薪資拿的不止多一點的時候,才有所覺悟光會敲程式碼是不夠的,還要和人精(HR)玩兒心理戰,曾以為技術面試試最講道理的,沒想到如今也是步步驚心。重要的話就講三遍: 作用域、作用域、作用域

如何將 var 改成 let 可以達到 0、1、 2 的結果

  (function () {
    let i=0;
    let arr = [];
    for (let i=0; i< 3;i++) {
      arr.push(function () {
        console.log(i)
      })
    }
    arr[0](); // 0
    arr[1](); // 1
    arr[2](); // 2
  })()

根據跟人經驗,到此一般屬於點到為止,還沒碰到過哪位面試官要你在講講為什麼可以形成塊級作用域

可否不用 es6 實現剛才的效果

(function () {
    var i=0; // 或者 let i = 0
    let arr = [];
    for (i; i< 3;i++) {
      (function (i) {
        arr.push(function () {
          console.log(i)
        })
      })(i)
    }
    arr[0](); // 0
    arr[1](); // 1
    arr[2](); // 2
  })()

這時候,才是真的入戲了,當你寫完這段程式碼,就是和閉包相關的問題,eg: 談談你對閉包的理解,閉包的優缺點…
當你說道記憶體釋放的時候,就會帶出垃圾回收機制(自行問度娘啊),接下來就是優化相關(HTML、JS、webpack、魔模組化、H5快取、http快取……) , 更多幹貨,點我丫

房間裡有100盞電燈,編號為1,2,3……100,每盞燈上有一個按鈕,初始時燈全都是關的。編好號的100位同學由房間外依次走進去,將自己編號的倍數的燈的按鈕全部按一次,例如第一位同學把編號是1的倍數的燈的按鈕按一下(此時100盞燈全亮),第二位同學把編號是2的倍數的燈的按鈕按一下(此時只有50盞燈亮著,50盞被這個人按滅了)……第100位同學把編號是100的倍數的燈(即編號為100的燈)的按鈕按一下,請問依次走完後,還有多少盞燈亮著。

關於 100 盞燈的點選, 規律找 每個數的公約數(可以被開平方的數)

var findOpenLight = {
  arr: [],
  createArr: function () {
    for (let i = 1, l = 100; i <= l; i++) {
      this.arr.push(i)
    }
    return this.sqrt(this.arr)
  },
  sqrt: function(arr) {
    let newArr = arr.filter((item, index, arr) => {
      return Math.sqrt(item).toString().indexOf('.') === -1
    })
    return newArr
  }
}
console.log(findOpenLight.createArr())

這是一個簡單的邏輯推理題,面試官想看看你的邏輯思維能力,畢竟程式的世界裡,只有想不到沒有做不到,一個需求出來了,你都沒有任何的思路和邏輯,這麼可能寫的出來

結束語:
這是一個上市工資的面試題,招聘的崗位是高階前端,這是筆試題中的一部分,後續我會繼續更上有關更坑的面試題,今天就總結到這裡,但願各位看官來年薪資有大幅度的提升,學習是一件枯燥的事,但是沒有比學習更可以讓人充實的事,如果從這裡可以讓你有所收穫,我也感到榮幸。