如何招聘一個能幹活的程式設計師

發表於2013-03-24

原文連結 & 作者:侯帥英@江南奇侯),本文來自作者的投稿,也歡迎其他朋友投稿。提示:投稿時記得留下微博賬號哦 ~

寫這篇文章不是件容易的事情,因為需要舉一些例項,就會牽扯到過去現在的各種見聞,也會牽涉到業界的各種看法。既然部落格也是公開狀態,還得考慮有的話是否需要委婉一點講… 不過畢竟出來混了也有一年半載,對這方面還算略有心得,那就班門弄斧一下,還望高手不吝賜教。

關於一個程式設計師該具備怎樣的能力,這篇帖子裡面一共講了7點(伯樂線上注:經詢問文章作者,得知前文提到的帖子是在一個內部論壇,外部人員看不到,故而刪除文章連結了)。這7點本身沒錯,放之四海而皆準。但是對於程式設計師這一個特定的群體,似乎又顯得過於寬泛。有一些比如善於溝通這樣的能力更多是靠環境激發出來的。如果不幸混進一個國企,那其實鍛鍊更多的還是和領導套近乎和推卸責任的能力… 所以我認為,一個優秀的程式設計師有兩個最核心的能力是不可代替的:解決問題的能力與學習能力

先來說說“解決問題”的能力。

這個能力是相當寬泛的:debug是解決問題;設計某種架構是解決問題;提高使用者體驗是解決問題;根據需求給出整體的解決方案同樣是解決問題。概括起來就是本文表退中的“能幹活”,或者說就是“getting things done”。解決一個問題實際上分兩方面:其一需要有足夠的技術能力找到解決方案;其二需要對業務有充分的瞭解,明白到底該怎麼做才能達到使用者的預期。結合實際來說,做一個遊戲不僅要完成策劃提出的功能需求,還要考慮做出來的功能操作上是否便利,是否符合玩家的習慣和心理預期,是否可能引起玩家的誤解和不滿等等… 在技術熟練的情況下,絕大部分的功能要實現起來並不需要花很大的精力在技術上,而是需要把精力投入到使用者體驗上面,對每一個細節都斤斤計較,這樣才能做出精品。這和技術實力並沒有太大的關係,很多時候關鍵看執行者的耐心、細緻,甚至是品位。在對大部分遊戲系統有充分了解的前提下,只需要策劃給一個大致的思路,略加點撥就可以做出符合預期的實現,這才是一個合格的遊戲程式設計師應有的素質,吃過了五星級料理,雖然未必能總結出什麼理論,但直覺會讓你明白什麼是一定會被策劃打回來的狗屎,所以這就是我會去花時間玩大量不同型別遊戲的主要原因(終於成功為自己玩遊戲找到藉口,噢耶~),

熟悉業務是解決問題一方面,另一方面就是技術水平。雖然大部分情況下不需要非常高深的技術,但如果牽涉到了一些關鍵的核心演算法,或是效能調優、架構設計,技術水平就顯得尤為重要。這就一定會牽涉到學習能力的問題。不可否認的是,技術積累非常重要,但同一個方向上的積累同樣會造成思維定勢,從而不願主動走出自己的舒適區。光從解決問題的角度而言,在碰到難題時,首先需要嘗試相對穩定和成熟的解決方案,但同時也不能排斥在必要的時候使用一些比較“古怪”的方法。保持開放的心態(keep an open mind)在解決問題時同樣也很重要。

在來公司以後,我參與的第一個專案是一款和《百戰天蟲》相近的回合制射擊類遊戲。當時剛進入專案,聽了策劃介紹後我就把戰鬥場景按難度分成了四個主要部分:1. 人物移動等基本操作 2. 場景視角縮放 3. 炮彈飛行軌跡 4. 地形破壞。實際上前三個部分在技術上沒有太大的難度,主要還是跟著策劃的思路走,但第四個問題在當時確實把我給難住了,因為在這方面沒有技術積累,根本連如何解決的思路都沒有。之後用過了兩個方案,一是用物理引擎來實現炮彈飛行和破壞,這個方案確實可行,但與遊戲的整體風格不符,而且物理引擎本身也會有一定限制,在不熟悉的情況下適得其反。第二個方案是用openGL提供的一些介面,通過遮罩圖來實現破壞。這個方案在應用中發現效率太低,炮彈落地時會需要將近一秒才能重繪完成,之後發現是openGL的運算介面占用了大部分時間,這也是很難進行調優的。當時沈晟給了一個解決方案,概括起來就是自己實現一套相關演算法,然後過載材質。當然這套演算法比較hack,需要直接操作記憶體中的圖片資料,當時因為對引擎和圖片格式不熟結果我沒有看懂沈晟給的示例….後來又去調視角縮放花了很長時間,在將近一個月後某個週末的早上突然開了竅最終把這個問題搞定了。實際花了一個多星期的時間寫出了最後的解決方案,只需要0.1秒就可以完成地形破壞的運算與重繪,順便還解決了人物移動和碰撞檢測的問題。當然那套演算法在實現時很醜陋,因為使用了非常底層的方式,還存在一些溢位的bug需要調整。不過這個解決這個問題的過程給了我很大的啟示:學習能力,特別是底層的基礎知識非常非常之重要。現在想來,如果之前的一份工作不是寫C語言而是隱藏了太多底層實現的JAVA,恐怕就幾乎不可能解決這個問題。

 

學習能力:重視基礎,不糾結於細節

在上一篇文章中,我提到了程式設計師能力的兩方面——解決問題的能力與學習能力。這兩點可以說是相輔相成的。而在學習能力中,基礎又是必不可少的一條。下面就來說說我對基礎的理解。

當我還在大學的時候,我的數學成績一直不太好。有一個同學在其他方面毫不出眾,但他所有和數學相關的學科都學得非常好,考試前也只是翻翻書,並沒有付出相當大的精力和時間。我始終以為他天賦異稟,但後來才發現,無論學到什麼新的東西,他總是能用非常簡潔的語言解釋這個概念的本質。換而言之,在絕大多數人還在死記硬背的時候,他已經瞭解到了一些本質性的東西——這些東西可以把所有和數學這門學科相關的知識串聯到一起,對他而言,看問題的視角也和絕大多數人不同了。

什麼是“基礎”?我認為這是對一門學科本質的理解。什麼是電腦科學的基礎?計算機架構,計算機程式的構造,編譯原理。幾乎所有的現代計算機都基於馮諾伊曼架構,為何這一架構會成為現代計算機的主流?它又是如何設計出來的?我們都知道一個程式的地址空間包含堆區、靜態區和棧區,那麼為何要將其分開設計?為何在預編譯時需要進行詞法和語義分析?能回答出這些問題中哪怕一個,就說明對這些本質性的問題已經有了較深的瞭解。

最近我一直在看王垠的部落格 ,其中提到了很多關於程式設計方面的知識。此人讀過三個博士學位均未畢業,但不可否認的確是個大牛。他在文章中提到的很多東西,感覺就讓人上升到了一個新的層次。雖然計算機語言層出不窮,但是歸根結底,其本源都是相同的。有經驗的程式設計師可以很快地學習一門新語言,更多地是因為對程式語言本身的瞭解,所以一通百通;至於一些技術細節,大部分時候通過查資料就可以解決問題。遺憾的是,在中國很多招聘者與應聘者都沒有意識到這一點,於是就出現了“程式設計師幹到30歲就得轉行”這種錯誤的趨勢。很多人並不明白他們應該用什麼方法來積累經驗,程式設計本身對他們而言也許只是種維生手段。而僱主也用應試教育的思維去挑選應聘者,在這樣的前提下挑選出來的往往只是一些程式碼機器。當然程式碼機器在外包公司這種勞動力密集的地方還是大有用處的,誰叫我們國家人口眾多,勞動力從來不缺呢,呵呵。

 

廢話講了一大段,接下來還是講講關於如何招聘吧。

首先需要宣告的一點是,以下這些建議,不適合外包公司、國有企事業單位,只適合100人以下,團隊和人事關係相對簡單的中小型公司及創業型團隊。當然,如果是大公司下,團隊leader比較強勢和開明,有較大的資源調配及話語權,也是可以一試的。

 

在我看來,要招聘到一個“能幹活”的程式設計師,有以下幾條原則:

1. 此人是否和團隊有著相近的價值觀,作為一個團隊的leader,是否願意能夠留住這名員工?

之所以把這一條放在第一位,是因為國內現在IT行業人員的流動性實在是太離譜了,幹個一年拿了年終獎就跳槽的事情比比皆是。在IT這個行業,新員工加入任何公司都至少需要半年左右的磨合期才能發揮出其應有的水準,相當於一半的時間都在磨合中渡過,對於自己和整個團隊都不是件好事。

尋找價值觀相近的人共事,首先就可以確保這個人對團隊所從事的事業和目標有著相當的興趣和動力。這些興趣和動力,可以轉化成額外的工作成果,這也是優秀程式設計師和碼農之間最本質的區別。

 

2. 注重細節,但不拘泥於細節

把這一條放在第二位,是因為我看到了這麼一道題:

int a=2; a+=a-=a*a; a=?

首先我要宣告的是,如果在任何面試中面試官給我出類似的題目,即便我沒有立刻走人,這家公司在我心目中的地位也會一落千丈。在實際程式設計中,最重要的是程式碼的可讀性和非二義性。在 不同環境 下,由於編譯器的實現不同,這道題的答案是不唯一的。何況這樣的寫法在實際工程中除了造成其他同事的困惑和可移植性降低之外,一無是處。

前兩天我還碰到了一個類似的問題(寫得不太嚴謹,各位包涵):

問 textC 的值是多少?

很多人第一反應,textC的值當然就是123。對函式的壓棧順序有一些瞭解的人會認為是123456,因為引數從右至左壓棧,會先執行append方法將text值擴充套件為123456。但在實際應用中,ios平臺上的執行結果是123,安卓平臺編譯後的執行結果是1230。是不是很奇怪?其實這是一道不錯的面試題,但不應該直接問面試者執行結果,而應該問這段程式中可能存在的問題,以及改進方法。最簡單的方法就是加一行string text2 = text.append(“456″),這樣就不存在壓棧順序不同導致不同平臺下結果無法預期的問題,程式碼的移植性也就更好了。如果拘泥於一個“正確”答案,那就陷入了應試教育的泥潭。我們要招的是一個能夠解決問題的人,而不是糾結於茴字有幾種寫法的書呆子。

當然,這些細節問題可以體現出一個人的功力,但不能本末倒置,以瞭解所有的細節為目標。在面試中,我還是主張這些問題儘量少問,如果面試者無法回答,可以用探討的方法給出一些提示,主要還是觀察其思路和態度為主,不宜過分糾結。我曾經經歷過國內某規模不小的公司一場很不愉快的電話面試,面試我的人聽語氣應該也不是個等閒之輩,遺憾的是他在20多分鐘的時間裡有15分鐘都在一些細節問題上面糾纏不休。他問了我在之前工作中碰到多執行緒問題的解決方案,我當時回答他在某某地方使用了讀寫鎖,之後他就開始不停詢問為什麼要用讀寫鎖等等等等。其實理由很簡單,因為在那個特定條件下讀操作次數遠遠多於寫操作,所以讀寫鎖是最優解決方案(事實上我在設計時也是這麼想的)。他可能是要問如何儘量避免加鎖達到效能優化,但是首先效能優化必須在有充足證據證明效率低下的情況下才有必要進行,而我當時並沒有碰到這種情況,所以沒有必要為了一個可能的效能問題大費周章。我當然也不能對他說“你這個臆想症患者給老子閉嘴”,於是只能在尷尬中渡過這個問題。後來他問了我一個gdb的使用問題,我想他的本意應該是看看我除錯程式的功力怎樣,沒想到他開始問我gdb的常用命令有多少多少個,條件斷點該如何設定等等等等。對於這些問題,我完全可以找一本gdb使用手冊扔在他面前。經過了這場面試,不管對方的態度如何,這家公司的技術實力在我的心中也已經打了一個大大的問號。

在面試中,一個面試官應該儘可能地去了解並引導對方解決問題的思路,而不是拿一些細節問題是否答出了“標準”答案來評判一個人水平的高下。畢竟,細節知識上的欠缺很容易彌補,良好的思維習慣卻是無法在一朝一夕養成的,這一點對於評判那些應屆畢業生尤為重要。

順便多提一句,很多公司的招聘啟事在應聘者要求中往往會不小心寫錯一些技術的名稱,或是犯一些低階錯誤,這會讓應聘者對這家公司的專業性產生懷疑,反之亦然。在簡歷和招聘啟事上,還是多注意一些細節吧~

 

3. 良好的編碼風格

在程式設計中,最困難的事情莫過於起變數和函式名。好的變數和函式名能讓人一眼就看出這段程式的功能,而糟糕的名字(沒錯!就是我上面寫的textA這種玩意,所以我也是個爛程式設計師)往往讓人摸不著頭腦。由於迄今為止還沒有任何一種主流程式語言支援英文以外的字元,所以使用標準的英語起名應該成為共識。這裡我要吐個槽,我在程式碼中發現了一個叫“Supersport”的玩意,光看這名字還以為是什麼比賽,一問才知道是“競技場”,實在想不通為什麼不用”Arena”。還有像強化裝備翻譯成“upgrade”也容易造成歧義,國外一般都用“enhance”特指裝備強化。還有像“baoxiang”,“yamede”,”yikuyiku”這種變數名真是讓我淚流滿面….(後面兩個是我杜撰出來的,LOL)。所以,要辨別一個程式設計師的水平,最好的辦法就是看看他的程式碼變數名是否清晰,換行縮排的格式是否嚴格,會不會寫一個幾百行的函式不知道把其中的功能塊進行封裝….

 

4.  是否有個人部落格網站、github、stackoverflow

是的,如果一個應聘者有以上這些內容,我一定會考慮優先面試及錄用他。

以上這些內容都需要在平時擠出業餘時間來完成。架設網站,給開源軟體和社群作出貢獻,在專業性上肯定不如嚴謹的日常工作,但同樣需要付出精力和時間。如果一個人願意在業餘時間做一些和技術相關的事,至少能說明這個人不僅僅是想混口飯吃,而是將其作為一種愛好,這樣的人假以時日必有所長。這些公開資料同樣可以檢驗應聘者的真實水平:個人網站可以看出一個人的品味及價值觀;github上的程式碼可以看出編碼風格;StackOverflow上的活動可以瞭解他的表達能力和英語水平。能做到這些的應聘者在國外較多,但在中國並不多見。當然,還是以興趣和實際能力為主,做不到也無需強求。

 

前前後後花了快一個月總算把這篇文章寫完了!我寫文章的速度的確不容樂觀啊…..總算是堅持到最後一刻了!

相關文章