简单却又复杂的FizzBuzz面试编程问题

     写这篇文章主要是由于偶然看到一篇关于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

相关文章
相关标签/搜索