來源:陳皓
筆者以前寫過一篇“我是怎麼招聘程式設計師的”的文章。今天,想再談談關於招聘和麵試這方面的東西,主要是以下這些原因:
* 近半年來我在進行了大量的招聘工作,對面試有一些新的體會。
* 酷殼最近釋出了幾篇趣味面試題(面試題一,面試題二,面試題三),從回覆中讓我有一些思考。
* 我有一個同事最近面試了一家公司,他和我分享了一個博士專家對他的面試,也讓我思考了一些。
* 在豆瓣上看到“知乎上某人寫面試豆瓣產品經理的經歷,很歡樂”(亮點是面試官現身知乎親自作答)
所以,我很想把自己的這些新的想法再次寫下來的。還是和以前一樣,這篇文章同樣是獻給面試官的。我認為,面試的好壞完全在面試官而不是面試的人。下面是我對“我是怎麼招聘程式設計師的”一文中的一些加強性的觀點。
為了讓我的文章有連續性,請允許我重申一下前文的幾個重要觀點。
* 只有應聘者真實和自然的表現,才能瞭解到最真實的東西
* 重要的不是知識,重要的是其查詢知識的能力
* 重要的不是那個解題的答案,而是解題的思路和方法
操作,知識,經驗,能力
我們有很多的面試官似乎分不清,什麼是操作能力,什麼是知識,什麼是經驗,什麼是能力,這導致了我們的面試官經常錯誤地對面試者下結論,我認為分不清這些事的人是沒有資格做面試官的。所以,我有必要在這裡把這個問題先講清楚。
* 操作。我們的面試官分不清楚什麼是操作技能,什麼是知識,他們甚至認為操作技能就是知識甚至經驗。比如他們會 問如下的問題,請問Java中的 final是什麼意思?怎麼檢視程式的CPU利用率?怎麼編寫一個管道程式?怎麼檢視程式的程式路徑?VI中的拷貝貼上命令是什麼?包括物件導向的XX模 式是什麼。等等。我以為,這些能夠通過查況相關操作手冊或是能夠google到的東西只能說明這個人的操作技術,並不能說明他有知識或有經驗。
* 知識。知識是一個人認知和學習的體現,可能會是一些基礎概念和知識。比如這些問題:TCP和UDP的優缺點比 較,連結串列和雜湊表的優缺點的比較。什麼是堆什麼是棧?程式間是怎麼通訊的?程式和執行緒的優缺點?同步和非同步的優缺點?物件導向的XX設計模式的主要原則是 什麼,等等。我以為,“知其然”只是操作技術,“知其所以然”才是真正的知識。知識不夠並不代表他不能工作,會操作技能就可以應付工作,但是知識的欠缺一定會限制你的經驗和能力,同樣會影響你的開發質量。
* 經驗。經驗通常跟一個人的經歷有關係。一個人的知識範圍,一個人經歷過的事,通常會成為一個人經驗的體現。面 試中,我們會問這些問題:你解決過最難的問題是什麼?你是怎麼設計這個系統的?你是怎麼除錯和測試你的程式的?你是怎麼做效能調優的?什麼樣的程式碼是好的 程式碼?等等。對於工作年限不長的人來說,經歷和做過的事的確會成為其經驗的主要因素,尤其是業務上的有行業背景的東西。但是,我更以為,經驗可能更多的是你對知識的運用和駕馭,是你對做過事情的反思和總結,是你對他人的學習,觀察和交流。
* 能力。一個人的能力並不會因為知道東西少而不行,也不會因為沒有經驗而沒有能力。一個人的能力是他做事情的一種態度,性格,想法,思路,行為,方法和風格。只要有熱情,有想法,有好的行為方法,以及好的行事風格,那麼知識和經驗對他來說只是一個時間問題。 比如:學習能力,專研精神,分析能力,溝通能力,組織能力,問題調查能力,合作能力等等。所以,對於一個新手來說,也許他的知識和經驗有限,但並不代表他 能力上有問題,但是對於一個老手來說,如果其存在知識和經驗欠缺的問題,那麼通常都是其能力的問題。你可能暫時懷才不遇,但我不相信你會長期懷才不遇。如 果是的話,那麼你必然些問題其讓你的能力發揮不出來。而此時,“沒有經歷過”只會是你“沒有能力”的一個藉口。
我不否認這四樣東西對於一個優秀的程式設計師來說都很重要。但是,通過上述的分析,我們可以知道,能力和經驗和知識需要分開對待。當然,這些東西是相輔相成的,你的能力可以讓你獲得知識,你的知識可以讓你更有經驗,你的經驗又會改變你的想法和思路,從而改善你的能力。在面試中,我們需要清楚的認識到,應聘者的操作技能,知識和經驗只是其能力的必要條件,並不是充要條件,而我們更應該關注於應聘者的能力。
* 如果面試只是考查這個人的操作技能的話,那麼這個面試完全失敗。這是一個沒有資格的面試官。
* 如果面試只是在考查這個人的知識和經驗的話,那麼成功了一半。因為你瞭解了基礎知和做過的事,但這並不代表你完全瞭解他的真正能力。
* 如果你能夠在瞭解這個人的知識和經驗的過程中重點關注其能力(態度、性格、想法,思路,行為,方法和風格),並能正確地評估這個人的能力,那麼你的面試算是非常成功的。
也許用這四個詞來描述定套東西並不太合適,但我相信你明白我想表達的。
不要膚淺地認識演算法題和智力題
很多公司都會在面試的時候給一些演算法題或是一些智力題或是一些設計題,我相信演算法題或是智力題是程式設計師們在面試過程中最反感的事了。很多人都很BS面試官問的演算法題,因為他們認為面試官問的這些演算法題或智力題在實際工作當中用不到。但我想在這裡說,問難的演算法智力題並沒有錯,錯的很多面試官只是在膚淺甚至錯誤地理解著面試中的難題的目的。他們認為,能做出演算法題和智力題的人就是聰明的人就是有能力的人,這種想法實在是相當的膚淺。
其實,能解難題並不意味著這個人就有能力就能在工作中解決問題,你可以想想,小學奧數題可能比這些題更難,但並不意味著那些奧數能手就有實際工作能力。你可 以想一想你們班考試得高分的同學並不一定就是聰明的人,也不一定就是有能力的人,相反,這樣的人往往者是在應試教育下培養出來的書呆子。
所以,我認為解難題的過程更重要,你要主要是通過解題檢視這個應聘者的思路,方法,運用到的知識,有沒有一些經驗,和你一起互動時和溝通得是否順暢,等等,這些才是你重點要去觀察的。當然,最終是要找到答案的。
我想,讓面試者解決一個難題的真正思路是:
* 看看他對知識的應用和理解。比如,他是否會用一些基礎的資料結構和演算法來解決演算法題?
* 看看他的整個解題思路和想法。答案是次要的,他的想法和行為才是重要的。
* 看看他是如何和你討論交流的。把面試者當成你未來的同事,當成你的工作夥伴,一起解題,一起討論,這樣可以看看大家是否可以在一起工作。
這些方面才是考查應聘者的能力(思路,方法、態度,性格等),並順帶著考查面試者的經驗和知識。下面是一些面試的點:
* 應聘者在解演算法題時會不會分解或簡化這個難題。這是分析能力。
* 應聘者在解演算法題 時會不會使用一些基礎知識,如資料結構和基礎演算法。這是知識。
* 應聘者在解題 時和你討論的過程中你有沒有感到應聘者的專研精神和良好的溝通。
* 應聘者在對待這個演算法題的心態和態度。如,面試面是否有畏難情緒。
* 應聘者在解題時的思路和方法是否得當,是否是比較科學的方法?
* 等等。
在解難題 的過程中考查應聘者的能力才是最終目的,而不是為難應聘者,不然,你只是一個傲慢而無知的面試官。
模擬實際中的挑戰和能力
作為面試官的你,你應該多想想你的工作,以及你的成長經歷。這會對你的面試很有幫助。你在工作中解決問題的實際情況是什麼?你寫程式碼的實際情況是什麼?你的成長經歷是什麼?你是怎麼獲得知識和能力的?你喜歡和什麼樣的人工作?相信你不難會發現你工作中的實際情況和麵試的情況完全是兩碼事,那麼,你怎麼可以用這種與實際情況差別那麼大的面試來評估一個人的能力呢?
所以,最為理想的面試是一起工作一段時間。當然,這個在招聘過程中,操作起來幾乎不可能,因此,這就要求我們的面試官儘可能地把面試的過程模擬成平時工作的 過程。大家一些討論來解決一個難題,和應聘者一起回顧一下他已經做過的事情,並在回礎的過程中相互討論相互學習。下面舉一個例子。
我們知道,對於軟體開發來說,開發軟體不難,難是的下面是這些挑戰:
1. 軟體的維護成本遠遠大於軟體的開發成本。
2. 軟體的質量變得越來越重要,所以,測試工作也變得越來越重要。
3. 軟體的需求總是在變的,軟體的需求總是一點一點往上加的。
4. 程式中大量的程式碼都是在處理一些錯誤的或是不正常的流程。
所以,當我們在考查應聘者的程式碼能力時候,我們為什麼不能模擬這樣的過程呢?比如,讓應聘者實現一個atoi()的函式,實現起來應該很簡單,然後 不斷地往上加新的需求或新的案例,比如:處理符號,處理非數字的字母的情況,處理有空格的情況,處理十六進位制,處理二進位制,處理“逗號”,等等,我們要看 應聘者是怎麼修改他的程式碼的,怎麼寫測試案例的,怎麼重構的,隨著要處理的東西越來越多,他的程式碼是否還是那麼易讀和清晰。如果只是考查編碼能力,一個小時,就問這一個問題,足矣。真正的程式設計師每天都在和這樣的事打交道的。
如果要考查應聘者的設計能力,同樣可以如法泡製。不斷地加新的功 能,新的需求。看看面試者的思路,想法,分 析的方法,和你的討論是否流暢,說沒說在 點上,思想清不清晰,會應用什麼樣的知識,他在設計這個系統時的經驗是會是什麼樣的,面對不斷的修改和越來越複雜的需求,他的設計是否還是那麼好?
當然,因為時間比較短,所以,你不能出太複雜的問題,這需要你精心設計一些精製的有代表性的問題。