今天正式入職了字節(jié)跳動(dòng)。辦公環(huán)境也很好,這邊一棟樓都是辦公區(qū)域。公司內(nèi)部配備各種小零食、飲料,還有免費(fèi)的咖啡。15樓還有健身房。而且公司包三餐來(lái)著。下午三點(diǎn)半左右還會(huì)有阿姨推著小車給大家送下午茶。聽說(shuō)入職以后很容易長(zhǎng)胖來(lái)著。不過(guò)如果想要保持身材的話,公司二樓還提供專門的健身餐。周二周四還可以預(yù)約專業(yè)的按摩服務(wù),有效調(diào)理頸椎和腰椎。生活服務(wù)得這么貼心,感覺在這里就只需要好好工作就好了吧,哈哈

為什么想去字節(jié)跳動(dòng)
實(shí)際上,這次的工作變動(dòng)并不在我計(jì)劃中。只是在四月份的時(shí)候偶然得知字節(jié)跳動(dòng)上海要搬到合川路地鐵站附近,我就忽然心動(dòng)了。為什么呢,因?yàn)槲壹揖嚯x合川路地鐵站步行只要十分鐘。本身宇宙條待遇高名聲在外,也就是說(shuō),只要我能來(lái)這里的話,人生最美滿的錢多事少離家近的不可能三角我能拿倆。所以在五月份的時(shí)候我就開始悄摸摸地準(zhǔn)備面試頭條了。為的就是以后可以過(guò)上早上八點(diǎn)半起床,然后慢慢悠悠走到公司還不遲到(可能還是很早來(lái)的人之一)的生活。
當(dāng)然,這是我為什么想去字節(jié)跳動(dòng)的原因。換算到你們自己的時(shí)候,你們也要想一想是因?yàn)槭裁聪胍獡Q一份工作、想要去某個(gè)公司。為了薪資?環(huán)境?平臺(tái)?還是大公司的名頭?記住,不管是為了哪一個(gè),都OK的。談錢不傷感情,目標(biāo)明確,心智堅(jiān)定以后,才好圍繞著這個(gè)目標(biāo)做一系列的準(zhǔn)備。面試的過(guò)程中每次面試官問(wèn)我為什么想來(lái)字節(jié)跳動(dòng),我都是直截了當(dāng)?shù)卣f(shuō)離家近,還說(shuō)假如這次面不上,準(zhǔn)備準(zhǔn)備,過(guò)段時(shí)間再面試好了。反正你們公司就在我家旁邊,三年五載的可能都跑不掉,哈哈。
因?yàn)檫@種面上OK,面不上也沒(méi)事的心態(tài),所以感覺面試的時(shí)候我的發(fā)揮也好一些。本身就是一個(gè)互相選擇的過(guò)程,而且這個(gè)過(guò)程中,公司方相對(duì)來(lái)說(shuō)固定一些,因?yàn)樗恼腥藰?biāo)準(zhǔn)不太可能會(huì)有太大的變化。拿我經(jīng)常用來(lái)懟人的一個(gè)例子來(lái)打比方:我常常和別人說(shuō),搞技術(shù)開發(fā),英語(yǔ)很重要。你需要英語(yǔ)來(lái)看最新的技術(shù)文檔,并且有些翻譯并不準(zhǔn)確,你可能需要看原文才能理解什么意思。有的人當(dāng)時(shí)就會(huì)和我說(shuō),哎,可惜我英語(yǔ)不太好。這個(gè)時(shí)候我會(huì)回,沒(méi)事,你現(xiàn)在英語(yǔ)不好不是你的錯(cuò),但是如果我一年以后,甚至兩年三年以后再來(lái)問(wèn)你英語(yǔ)怎么樣,要是你還和我說(shuō)你英文不好的話,那你就得查一下自己的問(wèn)題了。你根本就不想著學(xué)英語(yǔ),英語(yǔ)怎么可能會(huì)好?
類比下來(lái),如果你根本不想去這個(gè)公司,那你怎么可能來(lái)到這個(gè)公司?如果你真的想去一個(gè)公司,可能現(xiàn)在這個(gè)時(shí)候你暫時(shí)不滿足要求,但是沒(méi)事,只要咱知道別人是啥要求,咱認(rèn)真學(xué)習(xí),好好準(zhǔn)備,一年以后再面試,兩年以后再面試,甚至三年、五年以后再來(lái)試試,都可以的。人最怕的不是沒(méi)有達(dá)成目標(biāo),而是沒(méi)有一個(gè)真正的目標(biāo)。所以,換工作之前,你要想清楚為什么,并且提前開始準(zhǔn)備。

我準(zhǔn)備了些啥?
其實(shí)我有好長(zhǎng)一段時(shí)間沒(méi)有正規(guī)地面試過(guò)了。三年前從數(shù)云換到GIO的時(shí)候,因?yàn)楹?jiǎn)歷上的相關(guān)技術(shù)太過(guò)于匹配,所以基本上就和CTO聊了聊就確定過(guò)去了;后來(lái)再回?cái)?shù)云的時(shí)候,也就和總監(jiān)喝了一下咖啡就回來(lái)了。也就是大約5年的時(shí)間里面,我沒(méi)有正規(guī)地接受過(guò)面試。所以在準(zhǔn)備投字節(jié)跳動(dòng)之前,我投了幾個(gè)公司做了一下熱身活動(dòng)。記住,這個(gè)時(shí)候其實(shí)不需要有啥心理包袱。因?yàn)楸旧砗蜻x人面試成功的可能性比較低,一個(gè)合適的可以面試的人選他們也很樂(lè)意看看,而且萬(wàn)一你確實(shí)想換工作,但是心儀的公司面不上,而熱身活動(dòng)的公司拿到了offer,你也可以考慮考慮去看下。并且這個(gè)時(shí)候你沒(méi)有任何的心理包袱,因?yàn)榉凑阋簿褪莵?lái)面試看看的,所以面試時(shí)候的發(fā)揮可能也會(huì)更好點(diǎn),因此說(shuō)不定最終拿的offer會(huì)比最后想去的那家更好呢?
當(dāng)然這里面不包括我。我第一次面試的時(shí)候就被血虐了T-T。參加中間件比賽的時(shí)候,我用的netty做的實(shí)現(xiàn)。個(gè)人感覺對(duì)netty還算有所了解的,結(jié)果面試官讓我直接寫出netty的源碼結(jié)構(gòu),包括哪幾個(gè)主要的類以及名稱還有互相之間的關(guān)系……工作的項(xiàng)目里面我使用了kafka來(lái)做消息隊(duì)列,來(lái)緩沖流量,保護(hù)系統(tǒng),結(jié)果直接讓我描述kafka的存儲(chǔ)結(jié)構(gòu)……比賽的時(shí)候我通過(guò)各種手段讓程序無(wú)GC,結(jié)果直接就要我說(shuō)出各種GC算法的原理和應(yīng)用場(chǎng)景……PolarDB比賽我們自己寫了KV,對(duì)標(biāo)的是RocksDB,結(jié)果讓我描述RocksDB的索引結(jié)構(gòu)……
當(dāng)然,雖然基本上他問(wèn)的東西我都有所了解,并且清楚應(yīng)用場(chǎng)景在哪里,但是到了細(xì)節(jié)里面的時(shí)候,就稍微有點(diǎn)蒙圈了。雖然每個(gè)細(xì)節(jié)我確認(rèn)我稍微看一下就能搞定的,但是架不住面試的時(shí)候無(wú)法張口就來(lái)呀。這個(gè)時(shí)候,感覺仿佛我變成了年輕時(shí)候的楊過(guò),忽然身邊出現(xiàn)了一個(gè)金輪法王對(duì)我說(shuō):"楊兄弟,你的武功花樣甚多,不過(guò)我倚老賣老說(shuō)一句,博采眾家固然甚妙,但也不免駁而不純。你最擅長(zhǎng)的到底是哪一門功夫?要用什么武功去對(duì)付郭靖夫婦?"。對(duì)呀,我的知識(shí)面很廣,各種應(yīng)用框架新技術(shù)可能都有所耳聞,但是我最擅長(zhǎng)的是哪一個(gè)呢?雖然我深深地知道我最擅長(zhǎng)的是Scala和Akka、Play、Lagom等,但是架不住沒(méi)有人會(huì)問(wèn)呀T-T。
事已至此,雖然我?guī)浫鐥钸^(guò),但是此時(shí)也不得不考慮一下整理一下平生所學(xué),找出強(qiáng)點(diǎn)和弱點(diǎn),然后在面試的時(shí)候有的放矢。所以第一次熱身面試之后的一個(gè)星期,我基本就在整理我的知識(shí)結(jié)構(gòu)了。我大致按照如下結(jié)構(gòu)做了一份思維導(dǎo)圖:
1、JVM相關(guān)
運(yùn)行時(shí)結(jié)構(gòu)
GC算法
JVM調(diào)優(yōu)
2、編程語(yǔ)言
Scala
Java
3、數(shù)據(jù)結(jié)構(gòu)與算法
表、棧、隊(duì)列
樹
散列
優(yōu)先隊(duì)列
排序
高級(jí)數(shù)據(jù)結(jié)構(gòu)
4、并發(fā)編程
Java內(nèi)存模型
基本工具
無(wú)鎖并發(fā)
反應(yīng)式工具
5、微服務(wù)
微服務(wù)設(shè)計(jì)
服務(wù)治理
6、中間件
分布式緩存
消息隊(duì)列
RPC
7、數(shù)據(jù)庫(kù)
關(guān)系型數(shù)據(jù)庫(kù)
NoSQL
NewSQL
8、機(jī)器學(xué)習(xí)算法
推薦算法
其中JVM、Scala相關(guān)、并發(fā)編程、消息隊(duì)列什么的,我都仔細(xì)寫了一下;Java語(yǔ)言太簡(jiǎn)單就沒(méi)弄,數(shù)據(jù)結(jié)構(gòu)稍微看了一下感覺腦海里面塵封很久的記憶忽然就被喚醒了,所以也沒(méi)咋做筆記,微服務(wù)相關(guān)的太熟沒(méi)弄,推薦算法太難了也沒(méi)有弄;數(shù)據(jù)庫(kù)相關(guān)的內(nèi)容太多了,也沒(méi)弄。但是大體來(lái)說(shuō)索引結(jié)構(gòu)在這里,拿到xmind之后,你可以按照自己的知識(shí)結(jié)構(gòu)體系將其補(bǔ)全或者修改,然后學(xué)而時(shí)習(xí)之,甚至在面試之前也可以稍微看看加深一下記憶。
這之后我就進(jìn)行了第二次面試。第二次面試技術(shù)相關(guān)的問(wèn)題其實(shí)就沒(méi)啥太大的問(wèn)題了,主要考驗(yàn)我的是說(shuō)話技巧相關(guān)的事情。我這人有點(diǎn)毛病,想的太多,想要做的事情太多。這些其實(shí)沒(méi)啥大問(wèn)題,但是我不確定的事情我也喜歡和人說(shuō),還不分場(chǎng)合地就和人說(shuō)了。比如,我面的是中間件團(tuán)隊(duì),但是我終面面試的時(shí)候卻說(shuō)我因?yàn)橹案阃扑]算法對(duì)深度學(xué)習(xí)產(chǎn)生了興趣,想要今年考個(gè)在職研究生學(xué)一下深度學(xué)習(xí)??善鋵?shí),這個(gè)時(shí)候我說(shuō)這個(gè)干嘛呢?腦袋有點(diǎn)抽抽的嗎?并且他問(wèn)了我一個(gè)手寫代碼的題,我想了半天沒(méi)有想出來(lái)。問(wèn)題是如何去算根號(hào)2的值。我的第一反應(yīng)很快,牛頓迭代法嘛!但是他說(shuō)讓我在紙上把代碼寫出來(lái)的時(shí)候,我就一直在想辦法回憶牛頓迭代法是個(gè)什么鬼,應(yīng)該怎么用來(lái)算根號(hào)2。然后一直在紙上推演導(dǎo)數(shù)啊什么鬼的……直到他提示我這個(gè)不是一個(gè)數(shù)學(xué)問(wèn)題,二分查找就能算出來(lái)的時(shí)候,我才心不甘情不愿地開始弄二分查找的寫法(內(nèi)心OS:牛頓迭代法肯定比二分查找好的呀!為什么不給我時(shí)間回憶一下牛頓迭代!)。這個(gè)時(shí)候又暴露了我一個(gè)問(wèn)題,我好久沒(méi)有手寫代碼了。沒(méi)有IDE的時(shí)候,我基本上啥都不是……寫了半天勉勉強(qiáng)強(qiáng)地弄了個(gè)版本出來(lái),估計(jì)也不是bug free的。所以,最終這個(gè)公司的offer也沒(méi)拿到。辛苦為我推薦的普架了。
這之后我又知道了我出來(lái)面試的幾個(gè)缺點(diǎn)。首先就是要合適地說(shuō)話,與面試無(wú)關(guān)的話題不要扯;其次就是我得練習(xí)一下手寫代碼了。不至于要刷題,但是問(wèn)到什么必須能至少寫出個(gè)大概吧

字節(jié)跳動(dòng)面試體驗(yàn)
字節(jié)其實(shí)我面試了兩個(gè)職位。第一個(gè)職位的一面感覺挺好的,面試官很親和,問(wèn)的問(wèn)題也蠻到位的,然后留給我的發(fā)揮空間也蠻大的,所以順利過(guò)了。二面的時(shí)候就有點(diǎn)聊不來(lái)了,而且越聊越感覺職位不合適。所以后來(lái)朋友幫我重新推了一個(gè)職位,就是我現(xiàn)在所在的數(shù)據(jù)平臺(tái)部門。一面的面試官又年輕又高大又帥氣,而且基本上是針對(duì)我的簡(jiǎn)歷問(wèn)的問(wèn)題。當(dāng)然,第一個(gè)問(wèn)題讓我講Akka的時(shí)候,我是真的呆了。完全不按套路出牌呀!我從來(lái)沒(méi)有遇到過(guò)有人會(huì)問(wèn)我Akka的?。?!怎么會(huì)有人問(wèn)我Akka?。?!內(nèi)心一陣狂喜和激動(dòng)之后,我先收拾了一下心情,慢慢整理了一下自己腦海中一直在跳著舉手喊著"講我講我"的Akka特性。于是先從線程模型開始講起,講了它的M:N實(shí)質(zhì),Actor模型依賴的消息傳遞模式,層級(jí)結(jié)構(gòu)劃分的監(jiān)督職責(zé),讓它垮的失敗處理,Akka集群支撐起的橫向擴(kuò)展,等等等等。然后圍繞著Akka又問(wèn)了一些小問(wèn)題,基本很順利的過(guò)去了。后來(lái)又問(wèn)了一下緩存相關(guān)的內(nèi)容,其中講了一個(gè)緩存雪崩的問(wèn)題我一時(shí)半會(huì)兒沒(méi)有反應(yīng)過(guò)來(lái)。問(wèn)題其實(shí)很簡(jiǎn)單,就是忽然有一堆請(qǐng)求訪問(wèn)同一個(gè)key,而這個(gè)key在緩存中不存在。如此所有請(qǐng)求就會(huì)同時(shí)去訪問(wèn)數(shù)據(jù)庫(kù)然后又同時(shí)去更新緩存。這樣的緩存雪崩效應(yīng)應(yīng)該如何解決?這個(gè)問(wèn)題聽起來(lái)其實(shí)很熟很熟很熟的,但是當(dāng)時(shí)我腦袋短路了沒(méi)有想起來(lái)。后來(lái)想起來(lái)原來(lái)Akka-Http-Caching(以前的Spray-Caching)就是專門為這種情況服務(wù)的。老外給的說(shuō)法是這種問(wèn)題叫做驚群效應(yīng),講的是很多請(qǐng)求在第一個(gè)請(qǐng)求完成之前,一起訪問(wèn)同一個(gè)鍵(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.)。文檔上說(shuō)的This approach指的是緩存的時(shí)候,不要緩存一個(gè)值,而是一個(gè)Future[T]。這樣,第一個(gè)請(qǐng)求獲取值的過(guò)程也被緩存下了。后續(xù)的請(qǐng)求就會(huì)訪問(wèn)到這個(gè)Future,然后可以向其注冊(cè)回調(diào),等待緩存動(dòng)作完成再完成回調(diào)。當(dāng)然,這個(gè)沒(méi)有答得特別好也沒(méi)事,后續(xù)又問(wèn)了我一下關(guān)于JVM相關(guān)的一些東西,最后手寫了一個(gè)算法題。然后一面順利地就過(guò)了。
之后二面的話基本也是圍繞我的簡(jiǎn)歷來(lái)問(wèn)的,講了一下當(dāng)時(shí)做的推薦算法的原理,講了一下Spark的基本原理,然后最后做了一個(gè)算法題,然后也順利過(guò)了(其實(shí)還有一些其他問(wèn)題,但是我忘了問(wèn)的是什么了……)。當(dāng)然這個(gè)算法題的實(shí)現(xiàn)并不是最好的。題目?jī)?nèi)容是26進(jìn)制的加法,其實(shí)要涉及單個(gè)字符的加減和進(jìn)位的處理的,這樣實(shí)現(xiàn)下來(lái)細(xì)節(jié)就要處理好多東西,還很有可能出錯(cuò)。所以我取了個(gè)巧,我先把字符數(shù)字都轉(zhuǎn)化成了整型,然后整型加減得到結(jié)果,然后再把結(jié)果轉(zhuǎn)化成了26進(jìn)制字符。雖然結(jié)果不是最優(yōu)的,因?yàn)閿?shù)字大了肯定會(huì)溢出的嘛。但是起碼還是做出來(lái)了,所以二面也順利過(guò)了。
三面的時(shí)候也是先圍繞著我的項(xiàng)目問(wèn)了一些相關(guān)的問(wèn)題,所以答得蠻平淡的,但是也還行。然后他問(wèn)了一下我如何做流量控制。問(wèn)我流量控制哎!??!然后,我又強(qiáng)行按捺下了內(nèi)心的喜悅,將《反應(yīng)式設(shè)計(jì)模式》的第十六章流量控制的內(nèi)容大致講了一遍。也許就是給了這樣一個(gè)我發(fā)揮的空間,所以我第三面也很順利地過(guò)了。沒(méi)多久就是HR面試大致談了一些技術(shù)之外的問(wèn)題。
HR面我就中規(guī)中矩了。當(dāng)時(shí)面完感覺就穩(wěn)了,但是等了好久好久還沒(méi)有跟我溝通offer的事情,等的我有點(diǎn)難受了……之后HR聯(lián)系我說(shuō),還要給我加面試,說(shuō)團(tuán)隊(duì)老大要面我一下。原本字節(jié)面試一般3+1就OK了,然后突如其來(lái)地加面試讓我感覺有點(diǎn)忐忑,所以后面的面試發(fā)揮沒(méi)有前面好了。其實(shí)后來(lái)回想一下,我可能是以為前面面試表現(xiàn)不好,不能給我確定offer,才會(huì)有后來(lái)多的面試的。所以當(dāng)時(shí)心態(tài)不好,答的感覺也沒(méi)有之前果斷。后來(lái)第五面完了以后,團(tuán)隊(duì)老大還是不確定,還要加一面交叉面試,這個(gè)時(shí)候我就豁出去了。無(wú)所謂,面上面不上沒(méi)關(guān)系,反正字節(jié)跳動(dòng)在我家旁邊,只要廟不搬,我就進(jìn)得去。所以最后一面跟隔壁leader聊的時(shí)候相對(duì)來(lái)說(shuō)還好一些。問(wèn)題沒(méi)有問(wèn)啥特別的,就是仔細(xì)問(wèn)了下我最近做的一個(gè)項(xiàng)目,優(yōu)點(diǎn)在哪里,缺點(diǎn)在哪里,難點(diǎn)在哪里。然后順著難點(diǎn)來(lái)進(jìn)行擴(kuò)展,為什么是難點(diǎn),怎么解決,有哪些方案,這些方案有哪些優(yōu)缺點(diǎn)。幸好我平時(shí)工作還是有思考的,所以最終答的還不錯(cuò)。于是終于到了6月10號(hào)左右,HR和我確定要發(fā)offer了。
經(jīng)驗(yàn)總結(jié)
整個(gè)面試過(guò)程,如果加上之前不合適的職位的話,總共8面,前后跨度一個(gè)多月。然后到了今天的時(shí)候,最終入職成功。說(shuō)起來(lái)還是有點(diǎn)漫長(zhǎng)的。如果再加上前面的兩次熱身面試,可能跨度就有接近兩個(gè)月的時(shí)間了。說(shuō)實(shí)話我并不是那種別人一看就很喜歡的工程師,因?yàn)橐恢痹谛」咀鰝€(gè)小架構(gòu),而且主力編程語(yǔ)言比較偏門,所以適合我的職位范圍相對(duì)來(lái)說(shuō)很窄。實(shí)際上我今天看了一下和我工作相關(guān)的兩個(gè)項(xiàng)目,一個(gè)go,一個(gè)python,我的scala技能可能在后面相當(dāng)長(zhǎng)一段時(shí)間要荒廢了……不過(guò)沒(méi)關(guān)系,離家近就行,而且跳出舒適區(qū)看一下其他風(fēng)景,我感覺對(duì)我來(lái)說(shuō)也是一件好事。
最終總結(jié)為什么能成功面上字節(jié)跳動(dòng),首先我的基礎(chǔ)實(shí)際上還可以的,雖然第二次面試的面試官覺得我基礎(chǔ)不好,但是其實(shí)很多內(nèi)容在我深入的時(shí)候我就把思路、結(jié)構(gòu)、來(lái)龍去脈整的明明白白的,所以就算忘了,回憶起來(lái)也能很快塞進(jìn)體系里重新理解透徹;其次我有自己的拳頭產(chǎn)品,面試不問(wèn)就罷了,一旦問(wèn)到Scala、Akka、Play、Lagom或者能扯上反應(yīng)式架構(gòu)的時(shí)候,只要嘉和和品神不在這條街,我就是這條街最靚滴仔?。。∽詈?,我知道我為什么想去這家公司,并且就算不去也沒(méi)啥大的損失,所以面試的時(shí)候可以不卑不亢,心平氣和,于是發(fā)揮的就也還行。而且,反正公司就在我家旁邊,這次沒(méi)面上沒(méi)事,過(guò)段時(shí)間再面唄。
這些經(jīng)驗(yàn)換算到你這邊:如果你說(shuō)你現(xiàn)在基礎(chǔ)不好,我會(huì)說(shuō)沒(méi)關(guān)系;但是如果一年、兩年、三年以后你還和我說(shuō)你基礎(chǔ)不好,那是不是要自我反思一下呢?如果你說(shuō)你現(xiàn)在沒(méi)有拳頭產(chǎn)品,我會(huì)說(shuō)沒(méi)關(guān)系;如果一年、兩年、三年以后,你還是沒(méi)有拳頭產(chǎn)品,那你看我這篇文章有啥用呢?然后心態(tài)的問(wèn)題可能就需要自己調(diào)整了。只要有基礎(chǔ),有拔高,然后心平氣和地來(lái)面試,我相信你肯定能面試成功的。