成功入職位元組跳動,分享我的八面面經心得!
今天正式入職了位元組跳動。辦公環境也很好,這邊一棟樓都是辦公區域。公司內部配備各種小零食、飲料,還有免費的咖啡。15樓還有健身房。而且公司包三餐來著。下午三點半左右還會有阿姨推著小車給大家送下午茶。聽說入職以後很容易長胖來著。不過如果想要保持身材的話,公司二樓還提供專門的健身餐。週二週四還可以預約專業的按摩服務,有效調理頸椎和腰椎。生活服務得這麼貼心,感覺在這裡就只需要好好工作就好了吧,哈哈
為什麼想去位元組跳動
實際上,這次的工作變動並不在我計劃中。只是在四月份的時候偶然得知位元組跳動上海要搬到合川路地鐵站附近,我就忽然心動了。為什麼呢,因為我家距離合川路地鐵站步行只要十分鐘。本身宇宙條待遇高名聲在外,也就是說,只要我能來這裡的話,人生最美滿的錢多事少離家近的不可能三角我能拿倆。所以在五月份的時候我就開始悄摸摸地準備面試頭條了。為的就是以後可以過上早上八點半起床,然後慢慢悠悠走到公司還不遲到(可能還是很早來的人之一)的生活。
當然,這是我為什麼想去位元組跳動的原因。換算到你們自己的時候,你們也要想一想是因為什麼想要換一份工作、想要去某個公司。為了薪資?環境?平臺?還是大公司的名頭?記住,不管是為了哪一個,都OK的。談錢不傷感情,目標明確,心智堅定以後,才好圍繞著這個目標做一系列的準備。面試的過程中每次面試官問我為什麼想來位元組跳動,我都是直截了當地說離家近,還說假如這次面不上,準備準備,過段時間再面試好了。反正你們公司就在我家旁邊,三年五載的可能都跑不掉,哈哈。
因為這種面上OK,面不上也沒事的心態,所以感覺面試的時候我的發揮也好一些。本身就是一個互相選擇的過程,而且這個過程中,公司方相對來說固定一些,因為他的招人標準不太可能會有太大的變化。拿我經常用來懟人的一個例子來打比方:我常常和別人說,搞技術開發,英語很重要。你需要英語來看最新的技術文件,並且有些翻譯並不準確,你可能需要看原文才能理解什麼意思。有的人當時就會和我說,哎,可惜我英語不太好。這個時候我會回,沒事,你現在英語不好不是你的錯,但是如果我一年以後,甚至兩年三年以後再來問你英語怎麼樣,要是你還和我說你英文不好的話,那你就得查一下自己的問題了。你根本就不想著學英語,英語怎麼可能會好?
類比下來,如果你根本不想去這個公司,那你怎麼可能來到這個公司?如果你真的想去一個公司,可能現在這個時候你暫時不滿足要求,但是沒事,只要咱知道別人是啥要求,咱認真學習,好好準備,一年以後再面試,兩年以後再面試,甚至三年、五年以後再來試試,都可以的。人最怕的不是沒有達成目標,而是沒有一個真正的目標。所以,換工作之前,你要想清楚為什麼,並且提前開始準備。
我準備了些啥?
其實我有好長一段時間沒有正規地面試過了。三年前從數雲換到GIO的時候,因為簡歷上的相關技術太過於匹配,所以基本上就和CTO聊了聊就確定過去了;後來再回數雲的時候,也就和總監喝了一下咖啡就回來了。也就是大約5年的時間裡面,我沒有正規地接受過面試。所以在準備投位元組跳動之前,我投了幾個公司做了一下熱身活動。記住,這個時候其實不需要有啥心理包袱。因為本身候選人面試成功的可能性比較低,一個合適的可以面試的人選他們也很樂意看看,而且萬一你確實想換工作,但是心儀的公司面不上,而熱身活動的公司拿到了offer,你也可以考慮考慮去看下。並且這個時候你沒有任何的心理包袱,因為反正你也就是來面試看看的,所以面試時候的發揮可能也會更好點,因此說不定最終拿的offer會比最後想去的那家更好呢?
當然這裡面不包括我。我第一次面試的時候就被血虐了T-T。參加中介軟體比賽的時候,我用的netty做的實現。個人感覺對netty還算有所瞭解的,結果面試官讓我直接寫出netty的原始碼結構,包括哪幾個主要的類以及名稱還有互相之間的關係……工作的專案裡面我使用了kafka來做訊息佇列,來緩衝流量,保護系統,結果直接讓我描述kafka的儲存結構……比賽的時候我通過各種手段讓程式無GC,結果直接就要我說出各種GC演算法的原理和應用場景……PolarDB比賽我們自己寫了KV,對標的是RocksDB,結果讓我描述RocksDB的索引結構……
當然,雖然基本上他問的東西我都有所瞭解,並且清楚應用場景在哪裡,但是到了細節裡面的時候,就稍微有點蒙圈了。雖然每個細節我確認我稍微看一下就能搞定的,但是架不住面試的時候無法張口就來呀。這個時候,感覺彷彿我變成了年輕時候的楊過,忽然身邊出現了一個金輪法王對我說:"楊兄弟,你的武功花樣甚多,不過我倚老賣老說一句,博採眾家固然甚妙,但也不免駁而不純。你最擅長的到底是哪一門功夫?要用什麼武功去對付郭靖夫婦?"。對呀,我的知識面很廣,各種應用框架新技術可能都有所耳聞,但是我最擅長的是哪一個呢?雖然我深深地知道我最擅長的是Scala和Akka、Play、Lagom等,但是架不住沒有人會問呀T-T。
事已至此,雖然我帥如楊過,但是此時也不得不考慮一下整理一下平生所學,找出強點和弱點,然後在面試的時候有的放矢。所以第一次熱身面試之後的一個星期,我基本就在整理我的知識結構了。我大致按照如下結構做了一份思維導圖:
1、JVM相關
執行時結構 GC演算法 JVM調優
2、程式語言
Scala Java
3、資料結構與演算法
表、棧、佇列 樹 雜湊 優先佇列 排序 高階資料結構
4、併發程式設計
Java記憶體模型 基本工具 無鎖併發 反應式工具
5、微服務
微服務設計 服務治理
6、中介軟體
分散式快取 訊息佇列 RPC
7、資料庫
關係型資料庫 NoSQL NewSQL
8、機器學習演算法
推薦演算法
其中JVM、Scala相關、併發程式設計、訊息佇列什麼的,我都仔細寫了一下;Java語言太簡單就沒弄,資料結構稍微看了一下感覺腦海裡面塵封很久的記憶忽然就被喚醒了,所以也沒咋做筆記,微服務相關的太熟沒弄,推薦演算法太難了也沒有弄;資料庫相關的內容太多了,也沒弄。但是大體來說索引結構在這裡,拿到xmind之後,你可以按照自己的知識結構體系將其補全或者修改,然後學而時習之,甚至在面試之前也可以稍微看看加深一下記憶。
這之後我就進行了第二次面試。第二次面試技術相關的問題其實就沒啥太大的問題了,主要考驗我的是說話技巧相關的事情。我這人有點毛病,想的太多,想要做的事情太多。這些其實沒啥大問題,但是我不確定的事情我也喜歡和人說,還不分場合地就和人說了。比如,我面的是中介軟體團隊,但是我終面面試的時候卻說我因為之前搞推薦演算法對深度學習產生了興趣,想要今年考個在職研究生學一下深度學習。可其實,這個時候我說這個幹嘛呢?腦袋有點抽抽的嗎?並且他問了我一個手寫程式碼的題,我想了半天沒有想出來。問題是如何去算根號2的值。我的第一反應很快,牛頓迭代法嘛!但是他說讓我在紙上把程式碼寫出來的時候,我就一直在想辦法回憶牛頓迭代法是個什麼鬼,應該怎麼用來算根號2。然後一直在紙上推演導數啊什麼鬼的……直到他提示我這個不是一個數學問題,二分查詢就能算出來的時候,我才心不甘情不願地開始弄二分查詢的寫法(內心OS:牛頓迭代法肯定比二分查詢好的呀!為什麼不給我時間回憶一下牛頓迭代!)。這個時候又暴露了我一個問題,我好久沒有手寫程式碼了。沒有IDE的時候,我基本上啥都不是……寫了半天勉勉強強地弄了個版本出來,估計也不是bug free的。所以,最終這個公司的offer也沒拿到。辛苦為我推薦的普架了。
這之後我又知道了我出來面試的幾個缺點。首先就是要合適地說話,與面試無關的話題不要扯;其次就是我得練習一下手寫程式碼了。不至於要刷題,但是問到什麼必須能至少寫出個大概吧
位元組跳動面試體驗
位元組其實我面試了兩個職位。第一個職位的一面感覺挺好的,面試官很親和,問的問題也蠻到位的,然後留給我的發揮空間也蠻大的,所以順利過了。二面的時候就有點聊不來了,而且越聊越感覺職位不合適。所以後來朋友幫我重新推了一個職位,就是我現在所在的資料平臺部門。一面的面試官又年輕又高大又帥氣,而且基本上是針對我的簡歷問的問題。當然,第一個問題讓我講Akka的時候,我是真的呆了。完全不按套路出牌呀!我從來沒有遇到過有人會問我Akka的!!!怎麼會有人問我Akka!!!內心一陣狂喜和激動之後,我先收拾了一下心情,慢慢整理了一下自己腦海中一直在跳著舉手喊著"講我講我"的Akka特性。於是先從執行緒模型開始講起,講了它的M:N實質,Actor模型依賴的訊息傳遞模式,層級結構劃分的監督職責,讓它垮的失敗處理,Akka叢集支撐起的橫向擴充套件,等等等等。然後圍繞著Akka又問了一些小問題,基本很順利的過去了。後來又問了一下快取相關的內容,其中講了一個快取雪崩的問題我一時半會兒沒有反應過來。問題其實很簡單,就是忽然有一堆請求訪問同一個key,而這個key在快取中不存在。如此所有請求就會同時去訪問資料庫然後又同時去更新快取。這樣的快取雪崩效應應該如何解決?這個問題聽起來其實很熟很熟很熟的,但是當時我腦袋短路了沒有想起來。後來想起來原來Akka-Http-Caching(以前的Spray-Caching)就是專門為這種情況服務的。老外給的說法是這種問題叫做驚群效應,講的是很多請求在第一個請求完成之前,一起訪問同一個鍵(This approach has the advantage of taking care of the thundering herds problem where many requests to a particular cache key (e.g. a resource URI) arrive before the first one could be completed.)。文件上說的This approach指的是快取的時候,不要快取一個值,而是一個Future[T]。這樣,第一個請求獲取值的過程也被快取下了。後續的請求就會訪問到這個Future,然後可以向其註冊回撥,等待快取動作完成再完成回撥。當然,這個沒有答得特別好也沒事,後續又問了我一下關於JVM相關的一些東西,最後手寫了一個演算法題。然後一面順利地就過了。
之後二面的話基本也是圍繞我的簡歷來問的,講了一下當時做的推薦演算法的原理,講了一下Spark的基本原理,然後最後做了一個演算法題,然後也順利過了(其實還有一些其他問題,但是我忘了問的是什麼了……)。當然這個演算法題的實現並不是最好的。題目內容是26進位制的加法,其實要涉及單個字元的加減和進位的處理的,這樣實現下來細節就要處理好多東西,還很有可能出錯。所以我取了個巧,我先把字元數字都轉化成了整型,然後整型加減得到結果,然後再把結果轉化成了26進位制字元。雖然結果不是最優的,因為數字大了肯定會溢位的嘛。但是起碼還是做出來了,所以二面也順利過了。
三面的時候也是先圍繞著我的專案問了一些相關的問題,所以答得蠻平淡的,但是也還行。然後他問了一下我如何做流量控制。問我流量控制哎!!!然後,我又強行按捺下了內心的喜悅,將《反應式設計模式》的第十六章流量控制的內容大致講了一遍。也許就是給了這樣一個我發揮的空間,所以我第三面也很順利地過了。沒多久就是HR面試大致談了一些技術之外的問題。
HR面我就中規中矩了。當時面完感覺就穩了,但是等了好久好久還沒有跟我溝通offer的事情,等的我有點難受了……之後HR聯絡我說,還要給我加面試,說團隊老大要面我一下。原本位元組面試一般3+1就OK了,然後突如其來地加面試讓我感覺有點忐忑,所以後面的面試發揮沒有前面好了。其實後來回想一下,我可能是以為前面面試表現不好,不能給我確定offer,才會有後來多的面試的。所以當時心態不好,答的感覺也沒有之前果斷。後來第五面完了以後,團隊老大還是不確定,還要加一面交叉面試,這個時候我就豁出去了。無所謂,面上面不上沒關係,反正位元組跳動在我家旁邊,只要廟不搬,我就進得去。所以最後一面跟隔壁leader聊的時候相對來說還好一些。問題沒有問啥特別的,就是仔細問了下我最近做的一個專案,優點在哪裡,缺點在哪裡,難點在哪裡。然後順著難點來進行擴充套件,為什麼是難點,怎麼解決,有哪些方案,這些方案有哪些優缺點。幸好我平時工作還是有思考的,所以最終答的還不錯。於是終於到了6月10號左右,HR和我確定要發offer了。
經驗總結
整個面試過程,如果加上之前不合適的職位的話,總共8面,前後跨度一個多月。然後到了今天的時候,最終入職成功。說起來還是有點漫長的。如果再加上前面的兩次熱身面試,可能跨度就有接近兩個月的時間了。說實話我並不是那種別人一看就很喜歡的工程師,因為一直在小公司做個小架構,而且主力程式語言比較偏門,所以適合我的職位範圍相對來說很窄。實際上我今天看了一下和我工作相關的兩個專案,一個go,一個python,我的scala技能可能在後面相當長一段時間要荒廢了……不過沒關係,離家近就行,而且跳出舒適區看一下其他風景,我感覺對我來說也是一件好事。
最終總結為什麼能成功面上位元組跳動,首先我的基礎實際上還可以的,雖然第二次面試的面試官覺得我基礎不好,但是其實很多內容在我深入的時候我就把思路、結構、來龍去脈整的明明白白的,所以就算忘了,回憶起來也能很快塞進體系裡重新理解透徹;其次我有自己的拳頭產品,面試不問就罷了,一旦問到Scala、Akka、Play、Lagom或者能扯上反應式架構的時候,只要嘉和和品神不在這條街,我就是這條街最靚滴仔!!!最後,我知道我為什麼想去這家公司,並且就算不去也沒啥大的損失,所以面試的時候可以不卑不亢,心平氣和,於是發揮的就也還行。而且,反正公司就在我家旁邊,這次沒面上沒事,過段時間再面唄。
這些經驗換算到你這邊:如果你說你現在基礎不好,我會說沒關係;但是如果一年、兩年、三年以後你還和我說你基礎不好,那是不是要自我反思一下呢?如果你說你現在沒有拳頭產品,我會說沒關係;如果一年、兩年、三年以後,你還是沒有拳頭產品,那你看我這篇文章有啥用呢?然後心態的問題可能就需要自己調整了。只要有基礎,有拔高,然後心平氣和地來面試,我相信你肯定