寫這篇文章主要是由於偶然看到一篇關於stackoverflow公司的面經中提到了一個有趣的面試編程問題,如題所述:FizzBuzz問題。原文引用以下:html
「在一些公平的考驗以後,我發現那些由於代碼而抓狂的人不是爲了龐大的項目,而是在細小的地方就纏不休。因此我開始研究這些問題,收集這些編程人員的特色 和歸結成一類問題,取名爲「FizzBuzz 問題」。 FizzBuzz問題是一種英國學校學生常常玩的遊戲。舉個「FizzBuzz 問題」的例子:python
寫一個程序打印1到100這些數字。可是遇到數字爲3的倍數的時候,打印「Fizz」替代數字,5的倍數用「Buzz」代替,既是3的倍數又是5的倍數打印「FizzBuzz」。程序員
大部分優秀的程序員都應該能在紙上輕易地把這個程序寫出來,也就幾分鐘的事情。但你想知道一個使人震驚的事實嗎?多數計算機科學專業的畢業生不會作這道題。我還見過一個自稱是高級程序員的人作這道題,他竟然花了10~15分鐘。
Dan Kegel在招聘初級程序員的時候,也經歷了相似的事情:使人驚訝的是,有至關一部分的應聘者(包括那些得到計算機科學專業的碩士或博士學位的人),當他們被要求完成一個基本的編程任務時,他們都通不過,所以面試失敗。舉例來講,我曾經碰到過一些畢業生,他們竟然回答不出"寫一個從1數到10的循環"或者"在16進制裏F後面的數是什麼"之類的問題。若是務實一點,我在面試中也碰到過不少應聘者,他們不會用遞歸去解決一個實際的問題。但這些都是基本的技能。若是他們不會,只能說明他們極可能根本就沒寫過程序。web
乍看這個問題的時候感受題目敘述很清楚啊,思路也很簡單啊,比如今不少公司用的字符串逆序,字符串空格替換啥的簡單多了啊,爲何還會如此火地做爲一個面試編程題?本身動手寫了個,1分鐘搞定,沒毛病。而後懷着疑問就去百度了下,還真有各類論壇、博客等網站都在討論怎麼寫。而後看了下那些不屑一顧的編程愛好者們貼出來的代碼,看完你們的代碼後,個人心裏是崩潰的,終於知道爲何這也能做爲程序員們的面試編程題目了面試
(看到這裏的你不妨也去寫一寫吧,說不定寫的過程當中也會發現聯想起來不少有趣的事呢)。編程
不知道爲何常逛CSDN的那些技術宅們,爲什麼會給出這樣奇葩的答案,再次刷新了我對CSDN的用戶平均技術水平,下面把幾種CSDN論壇裏網友給出的答案而且在真實面試中不少人都容易犯的毛病提出來吧,但願即將面試中要手寫代碼的親多留意下這些問題:編程語言
大哥你這是用python嗎,給個語言提示啊。並且這是要手動從1打印到100?說好的3和5的控制呢?再說python是不須要分號的啊,你開頭加後面又不加是什麼編碼風格?函數
真不知道這哥們兒又是什麼心態?(注:這兩個答案是最早回覆的,並且還獲得了分數!)從代碼風格來看,我感受是徹底從上面那答案複製,而後把print改爲了cout>>了,對,你沒有看錯!是>>而不是<<,我真想問問這哥們兒,你真學過C++沒?並且先不說大家倆都沒有實現題目的需求,別人python不寫分號沒毛病,你這最後一句不寫就有點尷尬了啊。網站
好吧,終於算是一個看起來比較正常的代碼了,眼前一亮,好欣慰。但是!我隨便帶一個數15進去,發現輸出徹底不對啊?這個代碼會輸出Fizz-Buzz \n Fizz \n Fizz-Buzz \n Buzz啊?這隻有if沒有else的代碼看起來仍是不靠譜,好吧,這我的估計到了面試也會倒下... 編碼
嗯哼,這個代碼還算不錯,驗證結果也是正確的。不過啊,難道沒有代碼規範意識?三目運算符「?:」在一條一句裏用了三次也是蠻佩服的,可是若是是公司的線上代碼寫成這樣會被人嫌棄得要死吧!真是印證了那句「***的裹腳布,又臭又長」
一眼看過去,第一:不符合題意要求,明明要求的是若是是*的倍數,只輸出單詞便可,爲什麼要自做主張輸出數字加冒號?這是面試中的大忌諱,切記不可自覺得是的修改了「用戶需求」。第二:這明顯是把特殊case處理了,普通case給直接漏掉了啊?結果天然就不對了
哇,好工整,好想來句贊,但是......爲何是range(1,100)?你是對題意沒理解清楚仍是不知道range的具體用法呢?另外,其中三處continue實乃多此一舉!
看到第一句,就有點心累,又是範圍問題,題目中明確說了是1~100的數字,怎麼變成[0,100)區間了呢?並且中間有明顯的冗餘判斷:若是進了else if(i%5--0)這個條件裏,就不可能進入裏面一層的if(i%3==0)好吧?
我勒個去?我都開始懷疑這我的爲什麼要加入CSDN了,若是題目忽然換成1000,100000了,你也手算?
哇,居然看到了有人用js來提交,仔細一看。。頓時失望了。第一,仍是範圍問題。第二,思路卻是沒問題啊,對倍數進行從新賦值,但是,那個len=15那裏,爲何仍是賦值爲Fizz?題目沒看清仍是手抖了?另外,效率較低。
經驗證,這個代碼能夠知足需求,終於算是看到了一個能pass的代碼了。不過,這個須要半個小時?有點接受不了。並且這代碼格式,看了讓人落淚,聽了讓人瘋狂
最後貼一個,這個實在是膽小精悍,乍一看還覺得沒實現,不過看起來不明覺厲,就去驗證了下,發現!!!除了0也被包含進來(範圍問題)以外,居然徹底正確,實在是python大法好啊!仔細看了下,若是真的面試中就寫了這一句給面試官,而且搭配上準確的解釋那也將是完美的經過面試節奏。這一句裏面涉及到的知識點有:for in語法、range函數(另外,爲何不用xrange呢豈不更好)、[::]。將本身對這三個語法知識點的理解和延伸說說,將讓面試官心服口服!
固然,上面不少代碼是很直接的硬傷,連基本需求都過不了,做爲要去面試的人來講,這道題若是寫不出知足基本需求的代碼,感受有點過度啊!
不過我以爲若是想做爲一個合格的工程師(好吧,若是你想稱呼本身爲程序員...開心就好),這個基本需求還遠遠不夠,由於工做中的實際需求比這個不知道要複雜多少倍!
從這題來講的話,須要說的點還有:拓展性,效率問題。
也許只從這100個數來看,對效率問題可能不會有什麼要求,老是要遍歷的嘛,並且就100個數,效率影響因子基本可忽略。可是若是把這個問題拓展到實際環境,這個100可能被瞬間變爲100億,一樣這個過程也可能重複運行上億次,這個時候,咱們就不得不考慮效率問題了。
對於拓展性,這裏很簡單,就是把那個magic number(100)拿出來當作函數的參數(面試中給的編程題都最好寫成函數的形式,哪怕只是一段簡短的代碼!既然是個函數,就要注意函數參數和返回值問題等等),這樣就能夠根據實際狀況來肯定數據範圍。
效率的話,固然是冗餘判斷次數越少越好,充分利用已有條件來減小判斷次數。 下面是以C語言爲例的示例代碼:
1 void printFizzBuzz(int n=100) 2 { 3 for (int i = 1; i <= n; ++i) 4 { 5 if (i % 3 == 0) 6 { 7 if(i % 5 == 0) 8 printf("FizzBuzz\n"); 9 else
10 printf("Fizz\n"); 11 } 12 else if (i % 5 == 0) 13 { 14 printf("Buzz\n"); 15 } 16 else
17 { 18 printf("%d\n", i); 19 } 20 } 21 }
對於效率問題,這個代碼中,每一個數進來都只會判斷兩次並打印出結果。而對比上面貼出的CSDN網頁們的答案,不少答案將會有更屢次判斷。
其實問題能夠再嚴肅一點:每一個輸出之間的間隔符題目中沒有明確規定,可是不表明沒有,上面有些答案中並無輸出分隔符,這也算是一個問題吧,上面我提供的這個代碼中是以換行做爲分隔的,若是是要以空格分隔,而且最後一個結果後面不加分隔呢?若是要每k個數用\n分隔,k個數之間用空格分隔呢?這些就變得稍微複雜了,更能考驗面試者的嚴謹性、編碼能力、編碼風格和思惟方式了。
另外,對於擅長不一樣編程語言的人來講,可能會用不一樣的語言來實現,那麼若是是你,你會用多少種較主流的語言來完整且正確的寫出這個問題的答案呢?
最後,我不得不認可,這真的是一個考驗面試者的編程能力的好問題!
本文通過分析CSDN相應帖子後整理得出,轉載請註明出處-「聞波 博客園」:http://www.cnblogs.com/webary/p/6507413.html