前言
背景:一年半經驗前端,今年三月初提了離職,想著趁著金三銀四期間尋覓好的工作機會。不幸的是,三月初全國各地包括上海爆發疫情,直接導致許多公司開始縮招和鎖 HC,金三銀四變成了銅三鐵四。四月份上海疫情越發嚴重,最終導致全城封控,只能在家準備線上面試。(寄!)
疫情開始的階段,整個社會的氛圍都很消極。沒有辦法,只能邊投簡歷,邊準備面試題,邊調整心情。疫情封控期間只能在家閒著,所以利用這段時間,鞏固了一下 JS 基礎,在 Leetcode 上刷了一些演演算法題。萬幸的是,在這期間收到了攜程和位元組跳動的面試邀請(感謝萬分)。那麼廢話不多說了,以下是具體的面試過程:
攜程(旅遊研發部)
技術一面
常見的 React Hooks 有哪些?
- useMemo 是怎麼實現效能最佳化的?
- useRef 的應用場景?
- 該怎麼實現【一套程式碼,多端執行】,說出你的想法?
- Taro 實現跨端的底層機制?
- 能說說你會怎樣進行前端效能最佳化嗎?
- Chrome Devtools 的 Lighthouse 中的 LCP 是什麼意思?該怎麼減少 LCP 時間?
技術二面
- 前端效能最佳化方案?
- React.memo 和 shouldComponentUpdate 的作用?
- ReactDOM.render 的流程?
- 演演算法題:實現陣列去重(要求最佳時間複雜度)
function unique(arr) {
const map = new Map();
for (let i = arr.length - 1; i >= 0; i--) {
if (map.has(arr[i])) {
arr.splice(i, 1);
} else {
map.set(arr[i], true);
}
}
return arr;
}
- 演演算法題:實現獲取陣列第二大的數(要求時間複雜度 O(n))
function getSecond(arr) {
if (arr.length < 2) return null;
let max = arr[0];
let second = arr[0];
for (let i = 0; i < arr.length; i++) {
if (arr[i] > max) {
second = max;
max = arr[i];
} else if (arr[i] > second) {
second = arr[i];
}
}
return second;
}
業務三面
- 介紹專案及主要的使用場景。
- 做過哪些前端效能最佳化,你認為專案中最主要的效能瓶頸是什麼?
- 你做的專案的推進流程是怎麼樣的?你是怎樣進行專案的時間管理和規劃?
- 你是如何跟專案經理、後端等同事對接專案的?
位元組跳動(抖音電商)
技術一面
- 專案介紹
你實現了哪些自定義 Hooks?
- 實現自定義 Hooks:useLocalStorage
- TypeScript 泛型中 extends 關鍵字的作用
CSS position 屬性有哪些值?
- relative 和 absolute 相對於誰而言的?
- 怎麼實現 Header 固定在網頁頂端?
- 使用 fixed 造成內容塌陷怎麼辦?
實現一個擁有以下功能的 request 函式:
- 功能一:支援快取
- 功能二:支援非同步(返回 Promise)
- 功能三:支援併發請求
技術二面
有一個列表,然後為列表的每一項新增一個響應事件,你會怎麼做?
- 描述一下 DOM 事件流
- e.target 是指向哪一個元素?
- 怎麼阻止事件冒泡,怎麼阻止事件捕獲?
- React 事件機制
聊一聊使用者登入流程
- token 和 cookie + session 有什麼區別?
- 聊一聊掃描二維碼,並透過微信登入的流程
聊一聊虛擬列表實現
- 虛擬列表的列表項可以不固定高度嗎?
- 手寫 useMyState
const useMyState = (initial) => {
const [state, setState] = useState(initial);
const callbackRef = useRef(null);
const _setState = (_state, callback) => {
setState(_state);
callbackRef.current = callback;
};
useEffect(() => {
callbackRef.current(state);
}, [state]);
return [state, _setState];
};
- this 指向問題
const obj = {
a: 10,
add(x) {
return this.a + x;
},
reduce: (x) => this.a - x,
};
console.log(obj.add(2));
console.log(obj.reduce(2));
- 實現
sum(1)(2,3)(4,5,6)...()
const sum = (...args) => {
const result = args.reduce((pre, cur) => pre + cur);
return (...args) => {
if (args.length === 0) return result;
return sum(result, ...args);
};
};
console.log(sum(1)(2, 3)(4, 5, 6)());
技術三面
- 選一個你認為複雜度比較高的專案,描述一下它的難點。
- 在 TCP 建立連線後,HTTP 傳輸資料前,這之間發生了什麼?
- 我看你文章有些關於 TypeScript 和集合論之間的關係,簡單講述一下。
- 聊一聊 React Fiber ,如果讓你實現 Scheduler 你會怎麼實現?
- 演演算法題:買股票的最佳時機(Leetcode 121)
- 演演算法題:買股票的最佳時機 Ⅱ(Leetcode 122)
總結
幾輪面試下來最大的感觸是,面試官會針對你的專案去延伸,進而廣泛地考察你的基礎知識。攜程更加註重效能最佳化方面的考察,在透過三面過後還會有一個綜合測評和英語測評(綜合測評考察基本邏輯不是很難,英語測評過了六級可以免試)。位元組更加側重於一些原理和演演算法的考察,不過位元組的演演算法題並沒有想想中那麼難,Leetcode 前 200 簡單和中單難度的題準備一下問題應該不大。
最終順利的拿到了攜程的 offer ,位元組則是倒在三面。位元組面試官的反饋說是:【選一個你認為複雜度比較高的專案,描述一下它的難點】這個問題答得太簡單了,需要再加深一下技術深度,挖掘一下專案難點。以上就是此次面經分享的全部內容了,希望對你有所幫助。
本文參與了SegmentFault 思否面試闖關挑戰賽,歡迎正在閱讀的你也加入。