跳槽週期跨度
什麼時候動了想法
大概在去年11月份的時候,我負責的業務線一直做不出成績。而且整個公司的前端技術設施,都是我一手搭建出來的,再待在公司,沒什麼可成長的空間,就想跳槽了,期間考慮了幾個可能性:
- 出國工作:這個想法來源,主要是看了某位網友肉身出國到新加坡的蝦皮到新加坡打工兩個月的經歷分享,覺得挺有意思,也想嘗試下,後面投了一些跨國企業,沒啥反饋,估計是卡學歷,所以就放棄了,後面再想想彌補外語的可能性
- 進入大廠:很多大廠都卡學歷,即使是內推,也會被卡面試流程,我被小紅書、京東、騰訊、美團,拼多多、蝦皮、攜程、喜馬拉雅卡學歷和卡面試程式,所以,能選擇的大廠很少,最終入職了 B站
面了哪些公司
熱身階段(11月下旬 - 12月中旬)
- 彩雲科技,offer
- 天壤智慧,offer
- 掌門一對一,offer
- 帷幄匠心,offer
- 馳騖科技,offer
- 堅果雲,二面掛
- 樂言科技,二面掛
正式階段(12月下旬 - 2月下旬)
- 微盟(海外電商),一面掛
- 位元組(廣告商業化),一面掛
- 位元組(線索中臺),二面掛
- 位元組(抖音生活服務),二面掛
- 網易(嚴選),四面完,最終評審掛
- 七牛雲(低程式碼平臺),三面完,後續無反饋
- B站,offer
- 中通快遞,offer
複習備戰花了多久,面試到入職,花了多久
11月 - 2月 一直在陸陸續續準備,持續了 3 個月,主要是準備複習、覆盤、刷演算法
從開始面試,到入職,差不多 3 個月時間
做了哪些準備
主要準備了以下幾個方面:
- 簡歷,仔細梳理了最近的工作經歷,專案上做的事情,用到哪些技術
- 筆試,主要是演算法和程式設計題
- 技術知識點查漏補缺
複習了哪些內容,刷了哪些題
- 八股文
- 程式設計題,手寫各種方法
- 演算法題
- React/Mobx/Vite && Webpack
- 自己寫的部落格
八股文
這塊沒啥好說的,把各大社群各位大神經常分享的一些文章看了下,再就是針對計算機基礎知識和網路基礎知識,做了一些總結,大概看了下面這些文章:
程式設計
刷了下基本會手寫的面試題以及再把面試過程中遇到的手寫題總結下,基本上都還好
演算法
演算法這塊不是我的長項,基本沒接觸,主要是把 LeetCode 熱題 HOT 100,Easy 難度簡單刷了下,針對大廠頻出的演算法題,看不懂的,就背答案,比如經典的反轉二叉樹、任意兩個數的和等於 Target、反轉單向連結串列等
後面根據一些面經和文件,比如:前端年後面試真題,會80%直接進大廠副本,做了一些針對性地練習和鞏固
框架
React 部分複習了 setState原理、 diff 原理,深入了 hooks 和 fiber 原理,當然這裡的深入不是去讀原始碼,因為時間來不及,而是參考了比較多的文章:
Mobx 由於我日常使用比較多的,也被面試官深入問過,就自己搭建過前端腳手架和看了下 React 進階實踐指南里面有一篇講了 Mobx。主要了解框架的主體邏輯、響應式原理、依賴收集的實現
此外也總結了一下 Redux 和 Mobx 的特點,因為面試官大概率會問:Redux 和 Mobx 的區別?
部落格
由於本人經常會寫播客,這點在投遞簡歷的時候,是非常大的一個加分項,在多個技術社群有同名賬號,經常發表一些文章,會受到面試官的青睞,我最近的面試,都有被面試官提到,你的部落格寫的不錯,而且面試官也會從你的部落格中來提問你,我就被問到以下問題:
- Webpack 如何實現熱更新的?
- React 和 Vue 的選型?
- Redux 和 Mobx 的區別?
這些問題,我都在部落格上記錄了,所以都是信手拈來
重點補了哪些能力和短板
- 技術部分:演算法、程式設計題、對框架的細節思考(不僅僅是停留在使用層面)
- 業務部分:將自己對業務的理解和思考進行了總結
- 管理部分:歸納和提煉
面試中暴露了哪些問題,怎麼應對的
思考和表達的連續性
前期熱身的時候,準備內容的結構化不足,遇到有些沒有準備到的問題,臨場思考和組織,或者一遍表述一遍思考,導致表達的結構性和連續性較差,表現上就是重點不夠、囉嗦、回答不上
解決:針對幾大類問題梳理了整體的思維導圖,表達的時候,跟進面試官的側重點,挑選關鍵點進行結構
化表達
過往經歷的思考不足
當面試官聊到過往短板問題或者低谷經歷時,一開始的回答有點浮於表面,並且有一些規避的回答,受到了面試官的質疑
解決:認真、客觀地重新梳理了對應的問題,從主觀、客觀層面進行重新組織語言進行回答
印象深刻的事情
每個公司面下來的感受
- 位元組:我自己的意向是位元組跳動,連續面了三個部門,後面位元組掛了兩個部門,又被其他部門撈起來,,面到後面,越來越沒底氣,一方面自己的技術深度不夠,另一方面,感覺面試官都很年輕,不會往你的優勢方面去進行引導(面試經驗不足),有的部門,面的感覺還可以,都掛了,很煩
- 網易嚴選:網易嚴選的流程最長,我面了一個多月,當位元組跳動掛了之後,網易嚴選是我最意向的部門,技術棧和業務方向匹配,該部門接下來一年要做的一些事情,也跟我的職業發展比較匹配,但是,四面完之後,就給我掛了,很遺憾,估計是被其他候選人給 PK 下去了
- 七牛雲:一面問八股文,手寫程式碼,比如實現一個 call/apply 方法等,二面很常規,問問簡歷上的事,三面由部門負責人來面試(產品經理),感覺還可以,還讓我加了微信,但後面流程一直沒有推動,我問了 HR 多次,HR 給我的反饋是對我的印象挺好,希望保持聯絡,但後面流程就推動不下去了,再聯絡 HR ,就沒回復
- B站:全程聊的都還可以,比較順利
- 堅果雲:印象最深的就是二面了,要開始二面前, HR 先聯絡我,說是一個開放性的題目,讓我二選一,我選擇了其中一個,讓我做整體的思考,我做了大量的後端知識、服務端知識,但面試官只問前端方面的知識,溝通的不是很順利,整體面下來,感覺雙方的理解都是有問題
哪些經歷讓自己很難熬
位元組和七牛雲的 offer 一個都沒拿到
位元組面的感覺還可以,第二天就掛了,很難受,心態有點蹦
七牛雲三面完之後,我等了一週左右,沒給我反饋,我一直在推進,包括聯絡三面的面試官,詢問結果,就是不給反饋,掛了也沒任何反饋
最終抉擇
當時手頭上只有掌門一對一的 offer ,掌門一對一,HR 在催我入職, B站和網易嚴選還沒有面完,無法拒絕,很糾結,當時做的選擇就是,先入職掌門一對一,哪會兒中通聯絡上我,我就再面了一箇中通,拿到了中通的 offer,然後再等B站和嚴選的流程了,自己對嚴選是非常意向的,但嚴選終面完還是被掛,就很頭疼,在面嚴選的過程,B站正式 offer 發了,只能選擇B站
如何克服了過程中的困難
- 定好策略,穩住心態
跳槽的過程中不是來一家公司就面一家公司的,而是要根據自己的情況循序漸進。像我這樣後面 offer 還比較少的時候,雖然心裡也慌,但還是準備了一些兜底的策略,這點非常重要,而且本人是裸辭的情況下,面了很長的時間,心態一定要穩住,特別是網際網路寒冬時期 - 與人交流,開拓思路
我會和學長、靠譜同事、靠譜獵頭進行交流,一方面可以從他們的角度看出自己的不足,另一方面也可以從他們那裡得到幫助和思路
其他的心得體會和經驗
面試的 4 個環節:簡歷準備 - 投遞策略 - 面試和覆盤 - offer 談判和選擇
- 簡歷準備
簡歷準備不是要跳槽的時候才準備的,而是日常工作中要經常做總結,跳槽前對這些總結進行梳理歸納提煉為簡歷 - 投遞策略
職業生涯中每個階段的跳槽,可能會有不同的策略,常規好用的策略是先找幾家公司熱身,然後再開始投遞自己的目標公司,在投遞過程中,時間節點也需要有一定的關注 面試和覆盤
- 面試可以通過一些公司熱身試錯,同時,在面試中要快速捕捉到面試官想挖掘的點,用簡煉地話表達出來回應給面試官。如果面試官沒有挖到你長項的部分,還需要考慮引導面試官,讓自己展現出自己的長項
- 在表達方面,如果直接表達不夠結構化和清晰,可以先使用筆記或者思維導圖梳理,然後自己預演熟練
- 覆盤很重要,要儘可能讓自己犯過的錯不再犯第二次,並且,覆盤的內容是可以長期積累的
offer 談判和選擇
- 首先,要大概瞭解自己的市場價(對於大廠要了解自己的定級,對於中小廠要按市場水平),雖然這個比較難,但還是可能的
- 如果有了解自己的市場價,那麼在期望薪資這塊,就可以報得有底氣一些,也比較容易得到較高的漲幅。
- 多拿 offer,通過技巧去讓廠家自己在 offer 之間互相競爭,是相對容易的。雖然每個公司有自己的薪資體系,但招聘本質上是一個市場行為,廠家也要遵循客觀規律
總結
跳槽是一項心力、體力、腦力都必須線上的活動
資料參考和分享
最後
也歡迎大家關注我的部落格
高頻面試題整理
CSS
- css 重繪和重排如何理解
- 下面寬高各是多少
<style>
.box {
width: 100px;
height: 100px;
padding: 10px;
margin: 10px;
background-color: #f00;
box-sizing: content-box;
}
</style>
<body>
<div class="box">12312312</div>
</body>
- span 標籤在瀏覽器中偏移量是多少
<style>
.test {
margin: 20px;
}
</style>
<body>
<div>
<span class="test"></span>
</div>
</body>
- 為什麼
marign 0 auto
無法垂直居中 - 控制 z-index 的規則有哪些
- 元素替換概念有了解嗎?
- 移動端 1px 畫素如何解決?
- 一個元素隱藏有幾種方式?
- 講講 BFC
- css 選擇器
- display 有哪些屬性
- 三列布局如何實現
- css 柵格佈局
- flex: 0 1 auto 的含義
- css 如何實現一個正方形盒子(隨父元素)自適應
JS
- js 有哪些基本資料型別
- 講講閉包是什麼?
- var、let、const 的區別
es5 如何實現繼承
- 原型繼承方式(這裡要注意下,很有可能讓你手寫)
- 寄生組合繼承
- 引申到 es6 的 Class 語法糖
- es6 有哪些新的特性
- map 和 waekMap 的區別
- js 中 this 指向
- 講講 setTimeout 和 setInterval 的差異
- 用過函式節流和防抖嗎?
- localStorage, sessionStorage, Cookie 之間的區別
- 下面輸出結果是什麼?
var count = 100;
var obj = {
count: 200,
getCount: function() {
console.log(this.count);
}
}
const c = obj.getCount;
obj.getCount();
c();
- 下面輸出結果是什麼?
var obj1 = { a: 100 };
var obj2 = Object.assign({}, obj1);
var obj3 = obj2;
obj3.a = 200;
console.log(obj1);
console.log(obj2);
- 下面列印結果是多少
var p1 = new Promise((resolve) => {
resolve(1);
});
var p2 = new Promise((resolve) => {
setTimeout(() => {
resolve(2);
}, 0);
});
var p3 = new Promise((resolve) => {
resolve(3);
});
Promise.all([p1, p2, p3]).then((res) => {
console.log(res);
});
- 下面列印結果是多少
async function promise2() {
function p1() {
return new Promise((resolve) => {
resolve(1);
});
}
function p2() {
return new Promise((resolve, reject) => {
reject(2);
});
}
function p3() {
return new Promise((resolve, reject) => {
resolve(3);
});
}
try {
var p11 = await p1();
var p22 = await p2();
var p33 = await p3();
console.log(p11);
console.log(p22);
console.log(p33);
} catch(e) {};
}
- 請描述下 new 的執行原理
- 為什麼 Object.prototype.toString.call 可以判斷出變數,而不是通過 Object.toString.call ?
- 講講 gc 原理
- js 如何解決數值精度問題
- 講講事件迴圈
瀏覽器
- 瀏覽器快取原理
- 單頁應用如何提高載入速度?
React
- 講講 fiber 架構
- 講講對 diff 的理解
- 講講對 hooks 的理解
- 講講 class 生命週期
- setState 原理
- hooks 為何有一些規則使用條件
- 聊聊 react 事件機制原理
- 講講 useCallBack 和 useMemo 的區別
- 講講 useRef 和 ref 的區別
- react 元件傳遞狀態有哪幾種方式
狀態管理
- mobx 原理
- redux 原理
- mobx 和 redux 的區別
- 函式式元件特點,和 hoc 區別
- 講講 redux 中介軟體
微信小程式
- taro 原始碼如何實現的?
- taro 2.x 和 taro 3 最大區別是什麼?
- 微信小程式原理是什麼?
打包工具
- 聊聊 vite 和 webpack 的區別
- 模組化有了解嗎,講講 import 和 require 的區別?
- webpack 的原理
- 談談搖樹的概念
- webpack 熱更新機制原理
- vite 原理是什麼?
設計模式
- 訂閱釋出和觀察者模式和什麼之間的區別,實現一個訂閱釋出者模式
程式設計題
- 如何實現一個深 copy
- 實現一個 new
- 柯里話函式的實現
- 實現一個函式 calc
function calc() {
}
- 對於任意引數,實現累乘功能
- 對於兩次同樣的引數,結果快取,比如 (1, 2, 3)、(3, 1, 2)
- 對快取優化
- 實現一個 apply
- 針對深 Copy,變種的題目
- 實現一個 ajax
function ajax(options) { }
- 在實現的 ajax 基礎上實現呼叫所有請求,等到所有請求結果成功之後,再返回結果
- 在實現的 ajax 基礎上實現請求順序呼叫,第一個呼叫成功之後,再呼叫第二個,以此類推
- 實現一個 repeat 函式,根據傳入的引數,間隔時間,列印次數,來輸出 log
repeat(func, inteval, times){ … }
const r = repeat(repeatPrint, 10, 10);
- 用最精煉的程式碼實現陣列非零非負最小值的索引 index
// 例如:[10,21,0,-7,35,7,9,23,18] 輸出索引 5, 數值 7 最小
function getIndex(arr) {
let index = null;
...
return index;
}
- 該程式碼輸出結果是什麼?
const list = [1, 2, 5]
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()
- 手寫一唯陣列轉換樹節點
var array = [
{pid: 4, id: 6617, name: "a",subNode:[]},
{pid: 5, id: 666, name: "a",subNode:[]},
{pid: 4, id: 6616, name: "a",subNode:[]},
{pid: 6616, id: 66161, name: "a",subNode:[]},
{pid: -1, id: 0, name: "a",subNode:[]},
{pid: 0, id: 4, name: "a",subNode:[]},
{pid: 0, id: 5, name: "a",subNode:[]},
{pid: 4, id: 10, name: "a",subNode:[]},
{pid: 10, id: 451, name: "a",subNode:[]},
{pid: 0, id: 98, name: "a",subNode:[]},
{pid: 98, id: 23, name: "a",subNode:[]},
{pid: 98, id: 523, name: "a",subNode:[]}
];
var toTree = function(tarArray) { }
toTree(array);
演算法題
- 實現一個反轉二叉樹
- 一個迷宮,最短路徑生成
- 實現單向連結串列反轉
- 實際場景演算法題
- twoSum 得到兩個數的之後等於 target
其他
- 聊聊業務上的事
- 聊聊最複雜的業務如何處理的
- 如何做效能優化
- 聊聊前端腳手架
- 帶團隊中有哪些難點
- 聊聊迭代流程
- Git 如何覆蓋某次 commit
- 長列表滾動,你怎麼優化的
- 印象中最深的一件事
本文參與了 SegmentFault 思否徵文「如何“反殺”面試官?」,歡迎正在閱讀的你也加入。