最重要的話寫在前面:本文不允許任何公眾號、論壇社群、微博轉載。原因請見上一篇開頭。
(上)篇說過我的面試方法經過三個階段的變化,下面說說最後一個階段。
第三階段:現場寫程式碼
面試的歷程開始之初,請面試者現場寫程式碼這個想法就不時在我的腦海裡浮現。畢竟同樣是程式設計師,水平如何,看一眼程式碼是最快了解的方法(所以所有附 github 連結的簡歷我都給過了,總共只有兩人)。但一直比較猶豫,開始沒有采用這個方法,最主要的原因是怕面試者會累。因為寫程式碼總歸是比較累的,尤其是在短時間內高度集中精力寫程式碼。之前我自己去下家公司面的時候,幾輪面試總共讓我寫了三個小時的程式碼,緊張到我懷疑人生。候選人當天可能還會有別家公司的面試,我實在怕累著人家。還有一個原因是寫程式碼耗時長,而面試者太多,老大讓我 40 分鐘過一個;40 分鐘夠寫什麼呢?
但有一位先生讓我下定決心要請後面的面試者現場寫寫程式碼,哪怕只寫兩三行。當時我還在採取第二階段的問題,我問:“您在開發方面感覺遇到過什麼難點?” 他回答:“平常主要工作是畫畫介面,感覺沒什麼難點。有一次做橫屏的時候感覺挺麻煩,因為總體要求豎屏,只有一個介面橫屏,然後鍵盤會有問題……”
我覺得這個回答挺靠譜的,因為單個介面橫屏確實有點麻煩。另外一個問題:“您做過哪些重構?” 對方回答,上家公司把外包程式碼直接拿回來用,mvc 分層不清,一個 viewController 好幾千行,裡面大量繪製程式碼;他把 UI 的繪製都儘量分出去到單獨 view 裡做了。我一邊聽一邊點頭,剛畢業的時候領導也帶著我做過類似的事。到這裡為止,我對面試者的印象很好。然後後面聊到自己封裝過的控制元件,我隨口問了一句:“一般什麼時候用 weak?”
對方回答:“weak 啊…… weak 一般就是用來修飾 int 那些的吧。”
這個回答出乎意料。我覺得可能是個小口誤,正好電腦就在面前,我說:“weak 修飾 int 肯定會報錯的呀。”一邊順手敲出來,果然那一行紅了。
然而對方只是呆住了。1 分鐘面面相覷的沉默。
送走這位先生,我對自己的面試水平再次產生了深深的懷疑。一個工作三年,重構過幾千行 viewController 的工程師,為何會不知道 weak 不能用來修飾 int 呢。這次經歷給我敲響了警鐘:第二階段採用的諸如“工作中遇到什麼難點”這類一般性問題,雖然比知識性問題聊起來開心很多,但它有一個弱點,就是這些問題都是可以提前準備的。也許這位面試者,先去向開發經驗豐富的朋友請教,把他們的回答一一背下來,準備出一套天衣無縫的說辭。如果去面一個沒人會 iOS 的公司,他可能會被認定為很優秀、很有經驗;如果我沒隨口問這個問題,我可能也會把他放過去了。
於是我決定,對於後面的每個面試者,都儘量讓他/她現場敲幾行程式碼;保證一下招聘的下限,起碼要招一個會寫程式碼的人……
既然決定要寫程式碼,出個什麼題目呢?我想的是封裝一個簡單的小控制元件會比較好,最後選定的是公告欄,就是文字上下自動滾動的輪播。類似螞蟻金服首頁“聚寶頭條”後面那樣的文字滾動,內容做一行 label 即可,停 2s 滾動一次。只需要向一個方向滾動,不需要用手指能拖。點選時觸發點選事件,打個 log 即可。
我對自己選定的這道題還是比較滿意的,難度不大,同時可考察的點卻不少。出題的時候,我都會先給面試者看我在自家 app 實現的這個小控制元件,一方面是為了更清晰地說明題目,讓對方可以一邊看著例子一邊想,有助於想到怎麼實現;另一方面也是為了防止人家誤會我們用面試騙程式碼,騙他們幫我幹活><
雖然功能很簡單,但程式碼寫起來也需要時間。我跟面試者說的是,30 分鐘隨便寫,電腦已翻牆,允許上網查任何資料,寫多少算多少,寫不完也沒關係,我們們看看程式碼。最終做過這道題的 8 位面試者有兩位能實現到 90%,有一半直到時間過完對於怎麼實現效果還是沒有頭緒。實際上只要能寫出雛形、能口述出後面準備怎麼寫的,我這邊都給過了。
真的讓面試者做現場寫程式碼這麼辛苦的事,我心裡還是比較愧疚。所以對於每一個寫了程式碼的面試者,我都會一行行幫他們 review,但願他們費了這些時間精力的同時也能得到一點點收穫,這是我唯一能補償他們的了 >< 從大家的程式碼來看,出現的問題還是比較集中的,主要如下:
速度與編碼規範
速度方面,因為給的時間實在不夠,所以只要思路可以,並不要求程式碼量多大。手快的工程師 30 分鐘一氣呵成寫了一百多行程式碼,我非常欽佩膜拜。也存在略為過慢的工程師,30 分鐘只寫了不到 10 行程式碼,就畫了兩個 label,也沒來得及想後面的思路。這種情況會讓人不免擔心他以後的開發速度,所以就直接不能通過了。
有一位面試者比較特殊。一上來我會先自我介紹,然後請對方也簡單自我介紹下,其實一兩句話即可,3~5 分鐘都比較正常。但這位說了足足 20 分鐘,都是前公司如何做業務、如何運營這些跟技術無關的事,而且沒有空隙,我都找不到打斷的機會。請他做這道題,他一聽就說肯定有第三方的實現。我說別找第三方的,嘗試自己寫一下吧。過了半小時回來,發現他還是從 Github 上下了一個第三方的實現,放進工程裡交差。我不太開心,進去第三方的原始碼問了他幾個細節,果然他也沒有太深入的考慮。如果在工程開發中,找開源的實現當然沒有問題,雖然個人覺得這種簡單的控制元件自己寫反而問題少一些。但是在面試中,我都明確說自己寫,還堅持用第三方庫,難免讓人認為是對開發能力不夠自信。
編碼規範方面,看看大家的不同習慣還是挺有意思的。有些朋友不愛空格,等號、加減號兩邊一概不空格;有些命名時駝峰與下劃線混用;還有幾位只用 instance variable 的方法存變數,不用 property。當然無論有什麼個人習慣,我覺得都可以用寬容的眼光看待,避免橫加批判。但是編碼比較符合大眾化的規範,命名比較好讀,看的時候肯定是更有好感的~
UI 上如何實現輪播效果
其實最簡單的實現就是兩個 label 迴圈,一上一下,上面滾出螢幕之後再重回到底部即可。不過實際上大家想到的方案五花八門:有好幾位想用 UITableView、 UICollectionView 的,有用 UIScrollView,把每一個 label 排上去的。我覺得選用哪種方案都沒關係,用 scrollView 的不重用也不是什麼大事,只要能實現效果就行。但是這些思路基本都是把每行文字先從上到下排好,然後再第一行開始,一行行往下滾。這就帶來一個共同問題:到最後一行怎麼辦呢?
有一位工程師想到把第一行文字複製到最後一行;滾動到最後一行之後,不帶動畫重回開頭,我覺得是非常聰明的做法。不過其他人要麼沒有想法,要麼說只能從最後一行嘩啦啦 scroll 回第一行了。這樣看起來效果是不夠好的,我覺得是一個在設計之初就應該考慮到的問題。
傳值方式
因為要求在 label 上加點選事件,就會涉及到開發中最基本的問題之一:怎麼把點選事件傳出去。寫到這裡的人不多,主要是提問+口述,發現現在大家還是喜歡用 block 的多。有一位很認真地寫了一個 delegate:
@protocol ScrollLabelDelegate <NSObject>
- (void)scrollLabel:(ScrollLabel *)scrollLabel didSelectIndex:(NSUInteger)index;
@end
@interface ScrollLabel : UIView
@property (nonatomic, weak) id <ScrollLabelDelegate> delegate;複製程式碼
寫得很規範,一下就把我征服了~
在這裡我會順便問一個問題:“如果要用 delegate,一般用什麼關鍵字來修飾 delegate 屬性?” 有 3 位面試者都很乾脆地回答:“用 assign 呀。”我跟他們講了為何用 weak 比 assign 好一些,猜測他們可能是看了同一個過時的教學視訊,所以留下了相同的錯誤印象。雖然現在開發中 delegate 用得相對少一些,但這些比較基礎的內容還是要知道的~
防止 timer 造成的記憶體洩漏
像 timer 這種東西,大家肯定覺得都是很簡單,雖然 API 記不住,用到的時候現查就好了。這次出的題,我是允許上網查任何資料的。實際上同樣是上網現查,開發經驗豐富的工程師速度就要快很多,而經驗不足的工程師還是免不了踩坑 >< 有一位不知道怎麼,30分鐘全都用在試圖開一個 dispatch 的 timer 上,還把自己帶的電腦的程式碼拿出來抄,到最後這個 timer 還是沒調出來……
有好幾位用的 NSTimer,把 timer 儲存成一個 strong 的屬性,然後 timer 的 target 設為 self。當我問到 timer 有些 API 會 retain 它的 target,會不會造成迴圈引用,這樣是不是有記憶體洩漏的風險?大部分工程師都表示沒聽說過,還有一位回答:“沒關係,只要在 dealloc 方法裡把 timer 置為 nil 釋放掉就可以了。” 但如果真的形成了迴圈引用,就不會自然走到 dealloc 方法。
回想上一篇文章,一些評論噴我問的問題是裝X,平常開發反正也用不到,用到時候再查不行嗎,有什麼百度解決不了的問題嗎?我個人也不喜歡那種很底層、很偏的面試題,也同意網上很多面試題是平常開發用不到的;但就這個細節來看,開發工程師瞭解一些記憶體管理的知識還是有一定必要。這裡如果考慮到了記憶體洩漏,只需 google “NSTimer retain cycle” 就有一堆一堆的結果,很容易就能找到解決方法。但如果對這些沒概念,可能都不會意識到有這個問題的存在;或者像回答“在 dealloc 方法裡打破迴圈引用”的那位朋友,想當然地以為問題已經解決。對於這些工程師來說,他們會想到去 google 一下嗎?最終結果就是一個隱患埋進工程裡。
面對“有什麼百度解決不了的問題嗎?”,常見的問題確實沒有解決不了的,但前提是要大概有個概念。所以雖然上篇文章被噴,過段時間我還是準備學一點底層的知識,就算細節看完了就忘,能補充下知識框架也是有好處的~
印象深刻的面試者
關於面試的經驗,我能想到的都毫無保留地跟大家分享了。最後一點篇幅,跟大家閒聊一下印象深刻的面試者吧~
關於史上最短面試
給我印象最深刻的面試者非這位莫屬。
雙方剛坐下,我說:“您好,很高興認識您,我先自我介紹一下:我是這公司的 iOS 開發,在這公司快兩年了,一直是我一個人做……” 跟每個人我都先說這同一句開場白。
對方打斷我:“那我們們公司是獨立開發嗎?”
我:“是的,不過公司6月會再招1~2個人。”
一段沉默。
我:“您換工作是想找一個不是獨立開發的嗎?”
對方:“是的。”
一段沉默。
對方:“那要不我們們今天就先這樣?”
然後起身走了。留下目瞪口呆的我。
大概是史上最短面試了,哈哈哈。對方非常爽快,也節約了雙方的時間,我很感激。從此以後我的開場白多了一句:“這個職位是獨立開發的,能接受嗎?”
關於培訓
做 iOS 的,對培訓機構的厲害都或多或少有所耳聞。有些朋友對培訓出來的工程師一票否決,我倒是對培訓機構沒有反感,我們這個級別的公司也無法要求太多。培訓本身不是問題,簡歷造假才是問題。所以對於幾位坦承自己是培訓出來的面試者,感謝他們的誠實,我都願意額外多給一些機會。遺憾的是,這幾位技術確實也都不過關,不知道是不是一個巧合。
有一些簡歷明顯能看出有偽造的痕跡,比如 95 年的孩子說三年工作經驗。我們篩簡歷篩掉了,不知為何 HR 還是幫忙約來了。自己解釋是有個親戚如何超生云云,最後造成自己身份證年齡小;兩年前那時候雖然培訓班還不是特別火,他出去面試,人家都不相信,說他是編的…… 一套話說得很熟練。簡單問兩個技術問題,不知 delegate 為何物。我覺得並不意外,主要是前面的解釋過於流利了,有種銷售的感覺,感覺就不像真的了。
有一位大哥讓我印象很深。他拿出自己帶的簡歷,把自己的學歷、學位、四級證照全列印出來附到簡歷上了,厚厚一大疊。最後竟然還有離職證明,上面還蓋著紅章…… 面試時,他兩手平放在膝蓋上,並不看我,直視前方,像背書一樣地說:“我叫某某某,5年工作經驗,於某某年至某某年在某某科技有限公司工作,某某年至某某年在某某網路公司工作……” 技術問題完全聊不通,問他重構過什麼程式碼,他說每次新建一個 view 都會重構系統的 initWithFrame。我把他送走,覺得心裡很難過:大哥年紀比較大,至少 30 多了,一看就是個很實在的人,完全不會騙人的樣子;這樣去面試,估計沒有公司會看不出來。要放棄的話,又不知道他在培訓上投了多少積蓄和時間。這件事讓我對培訓機構產生了很多惡感,為了多賺幾個錢,把這些根本不適合入行的人花言巧語騙了進來,讓他們陷入這樣困難的境地,去做這些不得以的事。
關於妹子
本次招聘共有兩位面試者是妹子,只佔了不到 1/10。不過她們的表現都不錯,技術上都是過關的。一個共同特點是溝通很優秀,聊起來很輕鬆愉快。雖然最後結果比較遺憾,一位妹子長期嚴重加班,沒什麼時間學習,在老大一關沒有通過;另一位技術優秀,經驗也比較豐富,可惜自己希望轉管理,可能感覺在我們這個規模的公司沒有發展空間吧。
所以就本次個例來看,感覺妹子普遍技術還不錯,溝通也很有優勢。但願她們都能順利找到理想的工作,也希望業界能少一些偏見,給妹子同等的機會,相信她們也能為公司帶來相匹配的貢獻。
關於優秀的面試者
上一篇文章被噴了,雖然我很難過,其實想想也能理解。反覆列舉面試者各種表現欠佳的地方,行文確實容易給人一種盛氣凌人、居高臨下的感覺,比較招噴。
但真正招聘的過程遠沒有這些表面風光。尤其是偶爾遇到一位優秀的面試者,聊得很舒服,真是心裡深受感動,幾乎是乞求的心態求人家來吧 >< 但結果人家可能並看不上我們,絕塵而去。這麼來看,突然覺得招聘跟相親差不多,就是一個反覆失望、互相傷害的過程;不僅求職方可能會高不成、低不就,招聘方也容易如此。
公司被拒絕的最主要原因大概是獨立開發。上面說過有一位工程師聽說是獨立開發,扭頭就走了。還有兩三位優秀的工程師,雖然客氣一點,走完了面試的流程,但後面也明確提出不傾向於獨立開發。這種想法是很可以理解的,因為他們技術都非常不錯,都提到日常級別的開發已經沒有任何能難住他們的問題了,可能到了一個獨立開發的瓶頸階段;這時候希望能有技術複雜一點的專案,或者大神帶帶自己,是一個很正常的想法。小公司招人、留人最大的困難,可能就在於此吧。
即使有幸人家能看得上我們,還可能有各種其他原因導致談不成。比如 HR 可能會有一些自己的考慮,有位非常熟練的工程師,老大也很滿意,HR 以跳槽太頻繁、興趣愛好過多的理由否決了。雖然不知道何為“興趣愛好過多” >< 但半年一次跳槽,引起 HR 擔心也是沒辦法的事。
再比如一位工程師,我請他自我介紹,他一副垂頭喪氣、不想說話的樣子,不介紹自己,只是發呆望著空氣、又反問我工作時間、加班情況。雖然對方不大客氣,我還是提醒自己盡最大努力保持耐心和微笑,認真跟他聊。沒想到就這樣遇上了整個招聘中技術最優秀的面試者:各種底層問題我盡力往深裡問都能答出來,能看出水平在我之上;小控制元件看一眼就說出清晰思路,我一聽就不用讓他寫了,直接過。
雖然技術非常優秀,但面試過程遠談不上輕鬆,他聽到每個問題基本都是皺著眉、一臉不開心,沉默一會才說出答案,不時夾雜著嘆息。他坦言上家公司嚴重壓榨過度、連軸加班,自己現在已經非常疲憊、精力完全耗盡了。結果不出意料掛在了老大一關,老大說,他只聊了兩句話就把人送走了,說感覺不到任何工作的激情,不適合公司現階段發展。當然,可能人家也沒看上我們公司。唉,還是真心祝福這個哥們換個輕鬆點的工作吧,或者休個假放鬆一下也好,這樣下去真怕他抑鬱了…… 以他的技術找個大廠完全沒問題,不過精神狀態不調整一下的話,找任何工作都會比較困難吧…… 也提醒廣大碼農,照顧好自己,小心職業倦怠;如果感覺工作已經耗盡了自己的全部活力,還是多為自己考慮吧,犧牲了健康不值得。
最後說說我們最終招到入職的小夥伴。其實看到他的簡歷,有不錯的公司經驗,我內心就踏實一半了;聊了聊果然溝通很輕鬆、技術很優秀。然後我就開始暗自祈禱,老大給過吧 HR 給過吧老闆給過吧讓他來吧拜託了…… 所幸後面一路綠燈,三天後就入職了。目前工作了兩週,幹活超快,各種給力:)一再感謝上天,能遇見一個對的人,會明白前面的所有辛苦都是值得的。
篇幅寫到跟(上)篇差不多,也寫得很累了 >< 就到這裡吧。感謝閱讀,要噴的話求輕噴,還有不要轉載哈,怕被噴~ 最後還是祝大家都能招到滿意的人才,找到理想的工作:)