社招一年多前端微信面經(掛)

lyllovelemon發表於2020-01-07

前言

文章開始之前,先介紹下個人背景,18年普通本科信管專業畢業,到寫文章時有一年多經驗,主要使用的是vue。

年前本來不打算面試的,才剛開始複習(這個年限的hc比較少),但是恰好遇到騰訊大佬在招人,便試著投了簡歷,大概3天后收到了面試簡訊。

面試的部門是微信支付基礎架構部,早前就聽說微信面試難度很大,輪次很多,但是心裡一直有個大廠夢,這次機會不想錯過。 跟面試官約的是晚上,恰逢跨年夜。

下班就到了濱海大廈,騰訊的前臺小姐姐很好看呀,長相姣好,妝容精緻,身高170+。

咳咳,扯遠了,開始正題吧

一面(1h,過)

一面出了5道筆試題

實現斐波那契數列

我用的是最簡單的遞迴方法實現的,果不其然,面試官問我怎麼進行優化

function Fibo(n){
    if(n<=0){
        return 0
    }
    if(n===1){
        return 1
    }
    return Fibo(n-1)+Fibo(n-2)
}
複製程式碼

非遞迴迴圈實現:

function Fibo(n) {
  if (n <= 0) {
    return 0
  }
  if(n == 1) {
    return 1
  };
  let fn_2 = 0
  let fn_1 = 1
  let fn = 0;
  for (let i = 2; i <= n; i++) {
    fn = fn_1 + fn_2
    fn_2 = fn_1
    fn_1 = fn
  }
  return fn
}
複製程式碼

手寫氣泡排序

function bubbleSort(arr){
    if(!arr.length){
        return arr
    }
    for(let i=0,l=arr.length;i<l-1;i++){
        for(let j=1;j<l-1-i;j++){
            if(arr[j]>arr[j+1]){
                let temp
                temp=arr[j+1]
                arr[j]=temp
                arr[j+1]=arr[j]
            }
        }
    }
    return arr
}
複製程式碼

實現的是升序還是降序? 升序

怎麼實現降序? 將內層迴圈的if條件語句改為小於號即可

時間複雜度是多少,這個很簡單,O(n^2)

手寫二叉樹的中序遍歷

function inOrder(root,arr=[]){
    if(root){
        inOrder(root.left,arr)
        arr.push(root.val)
        inOrder(root.right,arr)
    }
    return arr
}

複製程式碼

使用的遞迴的方式解決,其實還可以考慮非遞迴的方式,網上有很多實現,不再贅述

判斷一個點是否在圓內

直接套用數學公式

function inCircle(cx,cy,x,y,r){
    return (cx-x)^2+(cy-y)^2<r^2
}
複製程式碼

其中(cx,cy)是點座標,(x,y)為圓心,r為半徑

為什麼不用開根號? 巴拉巴拉

實現_.[2,3,4].increase(1).reverse().val()

用原型鏈繼承即可實現,就不列程式碼了

自我介紹和專案介紹

每個人針對自己的情況介紹,注意介紹的專案一定要非常熟悉,面試官會往死裡問的

簡歷上寫了英語聽說讀寫流利,面試官讓我來一段英文自我介紹,這個是我的強項

二分查詢,時間複雜度和空間複雜度

function binarySearch(arr,val){
    if(!arr.length){
        return -1
    }
    let low=0,high=arr.length-1
    while(low<=high){
        let mid=Math.floor((low+high)/2)
        for(let i=0;i<arr.length;i++){
            if(arr[i]===val){
                return i
            }
            else if(arr[i]>val){
                high=mid-1
            }
            else{
                low=mid+1
            }
        }
    }
}
複製程式碼

複雜度是O(nlogn)

絕對定位和相對定位

送分題

/*
** position:relative 相對定位,相對自身定位
** position:absolute 絕對定位,相對於最近的不為static的父級元素定位
*/
複製程式碼

vue v-for裡的key作用

當 Vue 正在更新使用 v-for 渲染的元素列表時,它預設使用“就地更新”的策略。如果資料項的順序被改變,Vue 將不會移動 DOM 元素來匹配資料項的順序,而是就地更新每個元素,並且確保它們在每個索引位置正確渲染

這個預設的模式是高效的,但是隻適用於不依賴子元件狀態或臨時 DOM 狀態的列表渲染輸出。

key 的特殊屬性主要用在 Vue 的虛擬 DOM 演算法,在新舊 nodes 對比時辨識 VNodes。如果不使用 key,Vue 會使用一種最大限度減少動態元素並且儘可能的嘗試修復/再利用相同型別元素的演算法。使用 key,它會基於 key 的變化重新排列元素順序,並且會移除 key 不存在的元素。

有相同父元素的子元素必須有獨特的 key。重複的 key 會造成渲染錯誤。

sql分頁查詢

假設是從使用者表裡查詢前10條資訊

select * from user limit 0,10
複製程式碼

nodejs的應用

  • restful api
  • 中介軟體
  • 命令列工具
  • api代理
  • 反向代理
  • 前端構建工具
  • 平臺打包工具
  • 作業系統

nodejs的優缺點

優點:

  • 非同步
  • 非阻塞

缺點:

  • 不適合CPU密集型應用

但是有了serveless,我們就可以把存在安全風險的,消耗大量CPU計算的任務都遷移到函式計算上

nodejs非同步非阻塞的理解

非同步是相對於同步而言的,是指不等請求完成就執行下一個動作的行為。同步是指要等待一個操作完成才能執行下一個操作的行為。

非阻塞是執行緒/程式相關的,它是相對IO而言的,如果執行一個函式後,當前執行緒仍處於執行狀態,就意味當前執行緒是可以的繼續處理其他任務,但要時不時的去看是否返回結果,這就是非阻塞。

一個執行緒/程式經歷的5個狀態,建立,就緒,執行,阻塞,終止。其中有個阻塞狀態,就是說當執行緒中呼叫某個函式,需要IO請求,或者暫時得不到競爭資源,作業系統會把該執行緒阻塞起來,避免浪費CPU資源,等得到了資源,再變成就緒狀態,等待CPU排程執行。 非阻塞相反,在不能得到結果前,函式不會阻塞執行緒,而會立即返回

難道面試官看我長得可愛,問題變簡單了?

是否參加過校招,當時為什麼不校招

沒,渣本沒有信心

二面(接近2h,掛)

大概在兩天後,收到了二面通知簡訊,約在晚上面(心疼扣錢,真是個貧窮的小女孩了)

有兩個面試官交替面試,其中有一個說是團隊的老大

流程圖的功能設計

可以從封裝,繼承,多型的角度考慮,主要考察的是需求理解能力和程式碼設計能力,開放性問題,答案有很多,我就不再贅述了

閉包

這個是前端必會的問題。如果有不懂的可以看<<你不知道的JavaScript(上卷)>>,講解的很詳細。

如果一個函式可以訪問其他函式作用域的變數,那這個函式就形成了閉包。

function f(){
    var a=1
    function closure(){
        return a
    }
    return closure
}
複製程式碼

閉包優點

  1. 可以讓一個變數儲存在記憶體中,不被垃圾回收機制清除
  2. 可以避免變數的全域性汙染
  3. 可以定義模組,將操作函式暴露到外部,細節隱藏在模組內部

閉包缺點

  1. 容易造成記憶體洩漏
  2. 閉包對效能會產生負面影響,包括處理速度和記憶體消耗

記憶體洩漏

如果一個變數長期存在記憶體裡,沒有被垃圾回收機制清除,就會產生記憶體洩漏。

執行上下文

執行上下文可以簡單理解為一個物件,它包含三個部分:

  • 變數物件
  • 作用域鏈(詞法作用域)
  • this指向

型別可分為:

  • 全域性執行上下文
  • 函式執行上下文
  • eval執行上下文

程式碼執行過程: 1.建立 全域性上下文

2.全域性執行上下文逐行自上而下執行。遇到函式時,函式執行上下文被push到執行棧頂層

3.函式執行上下文被啟用,成為 active EC, 開始執行函式中的程式碼,全域性執行上下文被掛起

4.函式執行完後,callee 被pop移除出執行棧,控制權交還全域性上下文,繼續執行

call,bind,apply

這個答上來了,比較簡單就不寫了,不瞭解的可以自行搜尋

水平垂直居中

水平居中:

  • 行內元素:text-align:center
  • 塊級元素:margin:0 auto
  • display:flex+justify-content:center
  • position:absolute+left:50%+transform: translateX(-50%)

垂直居中:

  • line-height:height
  • display:flex+align-items:center
  • position:absolute+top:50%+transform: translateY(-50%)

水平垂直居中:

  • position: absolute+top: 50%+left: 50%+transform: translate(-50%,-50%)
  • display:flex+justify-content:center+align-items:center

方法不只這些,有興趣的同學可以自己實現

vue的響應式原理

面試常見題,不會的可以搜下

virtual dom的diff原理

虛擬dom的產生是在瀏覽器的解析階段開始的,而瀏覽器的解析又可以分成以下部分:

  1. html解析形成DOM樹
  2. css解析形成css 物件模型(Css Object Model)
  3. DOM樹和css Object Model合併成render樹
  4. 頁面佈局(layout)
  5. 頁面繪製(painting)

每次操作真實DOM,瀏覽器都會從頭到尾解析一次瀏覽器,造成效能的巨大浪費。

為了解決這個問題,產生了虛擬DOM

虛擬DOM是對真實DOM的結構的抽象,它可以將vnode渲染成真實的DOM,通過和真實DOM的diff比較,對比新舊虛擬節點之間有哪些不同,然後根據對比結果找出需要更新的的節點進行更新。

Vue的diff演算法是僅在同級的vnode間做diff,遞迴地進行同級vnode的diff,最終實現整個DOM樹的更新。

父子元件傳參

  • 父傳子: prop
  • 子傳父:$emit
  • eventbus
  • 跨多層元件:provide/inject

怎麼改變一個陣列

怎麼改變一個物件

怎麼改變一個基本型別值

這三個問題過於基礎,不瞭解的可以看vue文件

效能優化

這個問題最好是結合自身專案經驗回答

公司的技術架構

這個涉及公司的問題就保密了

資料庫索引的實現原理

具體實現請參考附錄2

OSI七層模型

面試的時候有點小緊張,沒有說全

  • 應用層
  • 表示層
  • 會話層
  • 傳輸層
  • 網路層
  • 資料鏈路層
  • 物理層 每一層都可能發散往深層次問,面試官對我的回答不是很滿意,沒有繼續追問

最小堆原理

這個問題沒有答上來,面完以後看了不少關於堆的文章,感覺這篇寫的比較好 看動畫輕鬆理解「 堆 」

後記

面試是一個發現自身不足的過程,可能是年限原因,考察我的都是基礎,我的資料庫實現原理方面答得不是很好。面試官的需求是一個不限於前端的技術人員,需要你對資料結構與演算法,資料庫,編譯原理,作業系統等底層都有深層次的瞭解,並在一個方向專精。

有準備面試的小夥伴可以關注我的專案algorithm-js,涉及到很多面試知識點,包括:

  • 紅寶書js基礎
  • 設計模式
  • 資料結構和演算法
  • vue原始碼剖析
  • 你不知道的js讀書筆記
  • 計算機網路

文中如有錯誤,歡迎在評論區指正,如果這篇文章幫助到了你,歡迎點贊和關注。

有複習基礎知識準備面試的小夥伴可關注我的github部落格,你的star✨、點贊和關注是我持續創作的動力!

附錄

  1. 狼叔:如何正確的學習Node.js

  2. MySQL索引背後的資料結構及演算法原理

相關文章