三年前端寒冬入大廠,收穫螞蟻P6+、字節2-1 offer 面經分享

最近因爲一些原因想要換份工作,通過獵頭幫我投遞了幾家公司,收到了螞蟻、字節和拼多多的面試邀約,先來說下面試的結果

  • 螞蟻:收到 offer,定級 P6+
  • 字節:收到 offer,定級 2-1
  • 拼多多:1 面之後未繼續流程

拼多多

先來說說拼多多,本來投的是 C 端,結果鬼使神差簡歷去到了 A 端(管理後臺),一面簡單瞭解之後並不願意去做 A 端,之後也就沒有繼續後續的流程了。

一面

合併兩個數組

concat、for 循環、擴展運算法、push.apply 這些方法都可以

合併兩個對象

Object.assign、擴展運算法、手寫深淺拷貝 都可以

interface 和 type 的區別

常規題,網上資料很多了,還是看官網的說明比較好

  • An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot.
  • An interface can have multiple merged declarations, but a type alias for an object type literal cannot.

flex: 0 1 auto 表示什麼意思

flex: 0 1 auto 其實就是彈性盒子的默認值,表示 flex-grow, flex-shrinkflex-basis 的簡寫,分別表示放大比例、縮小比例、分配多餘空間之前佔據的主軸空間。

詳細的可以看下 第 154 題:彈性盒子中 flex: 0 1 auto 表示什麼意思

求字符串數組的最長公共前綴

比如輸入: [“flower”,“flow”,“flight”],輸出: “fl”

解題思路是先獲取數組中的最大值及最小值字符串,最小字符串與最大字符串的最長公共前綴也爲其他字符串的公共前綴,即爲字符串數組的最長公共前綴

var longestCommonPrefix = function(strs) {
    if (strs === null || strs.length === 0) return "";
    if(strs.length === 1) return strs[0]
    let min = 0, max = 0
    for(let i = 1; i < strs.length; i++) {
        if(strs[min] > strs[i]) min = i
        if(strs[max] < strs[i]) max = i
    }
    for(let j = 0; j < strs[min].length; j++) {
        if(strs[min].charAt(j) !== strs[max].charAt(j)) {
            return strs[min].substring(0, j)
        }
    }
    return strs[min]
};

當然還有其他解法,可以看下這篇,圖解拼多多&leetcode14:最長公共前綴

手寫 Koa 的 compose 方法

這裏實現一個簡化版,如果問你異步如何處理的話,dispatch 函數裏面 return promise 就好了

function compose(middleware) {
  return function() {
    return dispatch(0)
    function dispatch(i) {
      let fn = middleware[i]
      if (!fn) return
      return fn(function next() {
        return dispatch(i + 1)
      })
    }
  }
}

獲取精度更高的時間

  • 瀏覽器使用 performance.now() 可以獲取到 performance.timing.navigationStart 到當前時間之間的微秒數

  • Node.js 使用 process.hrtime 返回一個數組,其中第一個元素的時間以秒爲單位,第二個元素爲剩餘的納秒

獲取首屏時間

  • H5 如果頁面首屏有圖片
首屏時間 = 首屏圖片全部加載完畢的時刻 - performance.timing.navigationStart
  • 如果頁面首屏沒有圖片
首屏時間 = performance.timing.domContentLoadedEventStart - performance.timing.navigationStart
  • 小程序通過攔截 setData 調用方式計算

git rebase 和 merge 的區別

常規題了,主要的區別在於是否保留分支的 commit 提交節點,rebase 會給你一個簡潔的線性歷史樹

螞蟻

螞蟻一共是 4 輪技術面 + 1 輪 HR 面,耗時 10 天,流程相對來說還算快了。4 輪技術面都是電話面,最後的終面(HR 面)是視頻面。螞蟻的面試主要還是根據簡歷提問,所以簡歷上寫的點都需要好好準備下。

其中比較難的是第 4 面和 HR 面,因爲這兩面纔是最終決定是否錄用你以及確定錄用之後的職級,4 面的面試官一般是 P8 或者 P9,Level 比較高,會從聊天的過程中考察你,另外 HR 面擁有一票否決權,如果被 HR 否決,前面面的再好也沒用,這兩面都需要好好準備下。

一面

一面又叫簡歷評估面,主要對簡歷上的東西進行提問,一面結束之後會通過郵件發幾道編程題,難度比字節大,但是不限定時間,最好當天做完發過去

有沒有做過 node 端

介紹了下我的「高級前端面試」小程序和寫過的幾個 node 腳本,聊了下整體的架構、數據庫(mysql + redis)、部署、監控這些方面

大型複雜項目開發協作經驗、遇到的問題和解決方案

主要介紹下 git 協作流程

如果讓你負責一個新項目,如何選擇技術棧,如何避免多端合作可能遇到的問題

腳手架開發、約定團隊開發規範、Lint 等;根據團隊的技術棧、成員能力等去選擇

TSLint、ESLint 的區別

TS 已經建議使用 ESLint 了

對 TS 的認識,項目中是否使用

那必須使用了

介紹一些開源框架的原理

Koa、Axios、Vue、React、Taro 等

對開源框架的一些貢獻

先吹下我的前端 100 問,再虛心的表示下後續對開源框架做些貢獻

介紹我開發的性能監控 SDK、行爲埋點 SDK 的工作、背景、遇到的問題等

我的業務問題,介紹了下整體的架構、遇到的一些難點、解決方案等

性能監控的一些實現原理,包括異常、網絡請求、加載時間等

業務問題,吹就完事了

介紹下灰度功能

聊了下業務場景,實現原理,迭代優化的過程

對於後端的數據收集落庫、web 搭建等的認識

不是主要開發,但是還是有些參與和了解

其他的項目難點

聊了下 SDK 的緩存優化

介紹下寫博客和公衆號的初衷、運營、推廣等

主要還是提升自己,聊了下運營模式

二面

和一面一樣都是聊項目,但是換了一個方向切入,主要還是根據簡歷上的點去深入提問

小程序的技術架構和方案、小程序的出現主要解決什麼問題?

包含小程序容器、渲染引擎和 JavaScript 引擎。UI 層運行在 WebView 中,而邏輯層運行在獨立的 JS 引擎中。

降低獲客成本、打通跨端

view 層、js 層分別在哪裏、怎麼通信 ?

業務邏輯的 JS 在獨立的 JavaScript 引擎(ServiceWorker)中,每個頁面的 view 和 css 運行在各自獨立的 webview 裏面,頁面之間是通過函數 navigateTo 進行頁面的切換;

JS 層和 view 層通過消息服務 MessageChannel 進行通信

Taro 和其他小程序框架的橫向對比,如何選型

Taro、uni-app、kbone、WePY、mpvue

Taro 的一些好用的點和不好用的點,聊下想法

一些特性不支持,不過隨着 Taro 的升級也在解決

Taro 本身的限制

對 React 的語法支持有限,比如不能使用 Array#map 之外的方法操作 JSX 數組

React 代碼轉成小程序代碼的原理

編譯器修改和運行時修改,同時配合 babel 做編譯、轉譯

Babel 的轉換過程,比如把 JSX 的 map 轉成 wxml

根據 AST 中的 JSXElement 生成對應的數據結構,比如

oddNumbers.map(number => <Text onClick={this.handleClick}>{number}</Text>)

生成的數據結構是

{
  type: 'element',
  tagName: 'text',
  attributes: [
    { bindtap: 'handleClick' },
    { 'wx:for': '{{oddNumbers}}' },
    { 'wx:for-item': 'number' }
  ],
  children: [
    { type: 'text', content: '{{number}}' }
  ]
}

再根據這個結構轉成 wxml 就好了,可以參考 himalaya 的代碼

真實數據和緩存的競爭如何處理,第一次如何處理,第二次有更新如何處理

優先使用緩存、真實數據替換緩存等

npm 版本號 ^ ~ 的區別

  • 脫字符(^)來限定所安裝模塊的主版本號

    • ^1.2.1 代表的更新版本範圍爲 >=1.2.1 && < 2.0.0,即 1.x

    • ^0.2.1 代表的更新版本範圍爲 >=0.2.1 && < 0.3.0,即 0.2.x

    • ^0.0.2 代表的更新版本範圍爲 0.0.2(相當於鎖定爲了0.0.2版本),即 0.0.2

  • 波浪號(~)是限定模塊的次要版本

    • ~1.5.1允許安裝版本號大於1.5.1但小於1.6.0版本的模塊,即 1.5.x

    • ~0.5.1允許安裝版本號爲0.6.0,即0.5.x

怎麼發 beta 版本

npm publish --tag beta

埋點數據上報的方案

Ajax 請求、img、script

圖片方案的原理和優勢

img 天然支持跨域;跨域友好、不佔用 Ajax 請求、執行無阻塞

埋點上報數據的設計

介紹了下抽象數據模板,如何對不同業務場景進行拆分

介紹下曝光埋點

埋點數據服務端相關的邏輯

異常數據的排查

是否做過 SQL 表查詢

寫過的最複雜 SQL 查詢

介紹下技術運營

最近在看的書

三面、四面

這兩輪面試聊得比較輕鬆,主要聊些項目、規劃、思考這些方面

有亮點的項目

寫的 SDK 對比同類產品的優勢

遇到的問題以及有哪些反思

技術規劃

技術的優勢和不足

個性、協作方面的優點和缺點

工作地點選擇

工作節奏

抗壓能力怎麼樣

HR 面

HR 面還是需要準備下,不能在最後一步功虧一簣了

介紹最近幾年的工作經驗

換工作的原因

目前在看的工作機會

如何考慮未來發展

每家公司離職的原因

之前跳槽拿到哪些 offer

考慮工作機會的優先級(公司、團隊、技術、薪資等排序)

成長特別快的公司和經歷

生活、工作遇到的一些有挑戰的地方

面對壓力一般是怎麼應對的

之前工作的績效

團隊中的定位、排名如何

字節

字節的話比螞蟻少一輪技術面,一共是 3 輪技術面 + 1 輪 HR 面,全程是視頻面試,其中比較難的是第 1、2 面,因爲前 2 輪會有 3 道左右的筆試題,3 面就是聊聊項目比較簡單,HR 面就完全和技術無關了,純粹問些你的期望、離職原因等基本信息,沒有一票否決權。

所以如果你打算面試字節的話,一定一定一定提前準備下筆試題,包括但不限於算法題、編程題、手寫實現題等。

一面

這裏介紹下遇到的手寫題,其他的問題和項目關聯,就不再重複了

下面這幾道題目已經更新到了我的題庫中,可以去那裏查看解析,Daily-Interview-Question / 字節

彈性盒子中 flex: 0 1 auto 表示什麼意思

求最終 left、right 的寬度

<div class="container">
    <div class="left"></div>
    <div class="right"></div>
</div>

<style>
  * {
    padding: 0;
    margin: 0;
  }
  .container {
    width: 600px;
    height: 300px;
    display: flex;
  }
  .left {
    flex: 1 2 500px;
    background: red;
  }
  .right {
    flex: 2 1 400px;
    background: blue;
  }
</style>

輸出以下代碼運行結果,爲什麼

如果希望每隔 1s 輸出一個結果,應該如何改造?注意不可改動 square 方法

const list = [1, 2, 3]
const square = num => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(num * num)
    }, 1000)
  })
}

function test() {
  list.forEach(async x=> {
    const res = await square(x)
    console.log(res)
  })
}
test()

實現一個批量請求函數 multiRequest(urls, maxNum)

要求:

  1. 要求最大併發數 maxNum
  2. 每當有一個請求返回,就留下一個空位,可以增加新的請求
  3. 所有請求完成後,結果按照 urls 裏面的順序依次打出

二面

這一面主要對我之前寫過的文章進行提問,找了一些文章中可以再深入的點進行提問

介紹原型雞生蛋、蛋生雞問題

可以看我之前的文章,深入探究 Function & Object 雞蛋問題

輸出以下代碼的結果

Object instanceof Function
Function instanceof Object

Object instanceof Object
Function instanceof Function

結果都是 true

手寫深拷貝

可以看我之前的文章,面試題之如何實現一個深拷貝

如何實現正則的深拷貝

可以看我之前的文章,Lodash是如何實現深拷貝的

模擬實現 Array.prototype.splice

可以看我的題庫,已經收錄這道題了,第 158 題:如何模擬實現 Array.prototype.splice

三面

前面兩面通過之後,三面就比較簡單了,主要就是聊項目,聊我之前做過的項目,亮點,之後的規劃,以及加入團隊之後所要做的項目

HR 面

比較簡單,聊之前的經驗,還有期望薪資之類的,沒有螞蟻 HR 的一票否決,整個過程還是比較輕鬆愉快

面試感想

先來說下大環境,感覺非常不好,就一二線互聯網來說招人的沒幾家公司,裁員的、內部調整的、鎖 HC 的確是一大堆,所以大家在換工作的時候一定不要裸辭,風險太大。

今年面試和往年感受有些不同,對於項目的重難點、亮點、個人在團隊中做的貢獻、對項目的 Owner 意識等比較關注,還有就是編程能力的考察會更多一些。

對於社招小夥伴來說,除了常規的 CSS / JS / 網絡 / 瀏覽器 / 異步 / 框架 / 工程化等方面,還需要在以上說的這兩方面多加準備準備,準備越充分,拿到的面試評價越高,能拿到的薪資也將越多,加油!!!

面試小程序

最後的最後,推廣一波我寫的面試小程序,現在用戶快突破 3 萬了。小程序的功能比較多,包括了編程題、算法營、選擇題、簡答題、計劃每週還會弄一次抽獎活動等。功能寫了好幾個月,現在在擴充題庫的過程中。歡迎大家使用,歡迎提 Bug,會持續更新維護。

支持

如果你覺得這篇內容對你挺有啓發,我想邀請你幫我三個小忙:

  • 點個「贊」,讓更多的人也能看到這篇內容
  • 關注我的官網 https://muyiy.cn,讓我們成爲長期關係
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章