写这篇文章主要是因为偶然看到一篇关于stackoverflow公司的面经中提到了一个有趣的面试编程问题,如题所述:FizzBuzz问题。原文引用如下:

“在一些公平的考验之后,我发现那些因为代码而抓狂的人不是为了庞大的项目,而是在细小的地方就缠不休。所以我开始研究这些问题,收集这些编程人员的特点 和归结成一类问题,取名为“FizzBuzz 问题”。 FizzBuzz问题是一种英国学校学生经常玩的游戏。举个“FizzBuzz 问题”的例子:

写一个程序打印1到100这些数字。但是遇到数字为3的倍数的时候,打印“Fizz”替代数字,5的倍数用“Buzz”代替,既是3的倍数又是5的倍数打印“FizzBuzz”。

大部分优秀的程序员都应该能在纸上轻易地把这个程序写出来,也就几分钟的事情。但你想知道一个令人震惊的事实吗?多数计算机科学专业的毕业生不会做这道题。我还见过一个自称是高级程序员的人做这道题,他居然花了10~15分钟。

Dan Kegel在招聘初级程序员的时候,也经历了类似的事情:令人惊讶的是,有相当一部分的应聘者(包括那些获得计算机科学专业的硕士或博士学位的人),当他们被要求完成一个基本的编程任务时,他们都通不过,因此面试失败。举例来说,我曾经碰到过一些毕业生,他们居然回答不出"写一个从1数到10的循环"或者"在16进制里F后面的数是什么"之类的问题。如果务实一点,我在面试中也碰到过很多应聘者,他们不会用递归去解决一个实际的问题。但这些都是基本的技能。如果他们不会,只能说明他们很可能根本就没写过程序。

乍看这个问题的时候感觉题目叙述很清楚啊,思路也很简单啊,比现在很多公司用的字符串逆序,字符串空格替换啥的简单多了啊,为什么还会如此火地作为一个面试编程题?自己动手写了个,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语言为例的示例代码:

 void printFizzBuzz(int n=)
{
for (int i = ; i <= n; ++i)
{
if (i % == )
{
if(i % == )
printf("FizzBuzz\n");
else
printf("Fizz\n");
}
else if (i % == )
{
printf("Buzz\n");
}
else
{
printf("%d\n", i);
}
}
}

  对于效率问题,这个代码中,每个数进来都只会判断两次并打印出结果。而对比上面贴出的CSDN网页们的答案,很多答案将会有更多次判断。

  其实问题可以再严肃一点:每个输出之间的间隔符题目中没有明确规定,但是不代表没有,上面有些答案中并没有输出分隔符,这也算是一个问题吧,上面我提供的这个代码中是以换行作为分隔的,如果是要以空格分隔,并且最后一个结果后面不加分隔呢?如果要每k个数用\n分隔,k个数之间用空格分隔呢?这些就变得稍微复杂了,更能考验面试者的严谨性、编码能力、编码风格和思维方式了。

  另外,对于擅长不同编程语言的人来说,可能会用不同的语言来实现,那么如果是你,你会用多少种较主流的语言来完整且正确的写出这个问题的答案呢?

  最后,我不得不承认,这真的是一个考验面试者的编程能力的好问题!


  本文经过分析CSDN相应帖子后整理得出,转载请注明出处-“闻波 博客园”:http://www.cnblogs.com/webary/p/6507413.html

简单却又复杂的FizzBuzz面试编程问题的更多相关文章

  1. 简单介绍Javascript匿名函数和面向对象编程

    忙里偷闲,简单介绍一下Javascript中匿名函数和闭包函数以及面向对象编程.首先简单介绍一下Javascript中的密名函数. 在Javascript中函数有以下3中定义方式: 1.最常用的定义方 ...

  2. 经典面试编程题--atoi()函数的实现(就是模拟手算,核心代码就一句total = 10 * total + (c - '0'); 但是要注意正负号、溢出等问题)

    一.功能简介 把一个字符串转换成整数 二.linux c库函数实现 /*** *long atol(char *nptr) - Convert string to long * *Purpose: * ...

  3. 面向面试编程——javascript对象的几种创建方式

    javascript对象的几种创建方式 总共有以下几个模式: 1.工厂模式 2.构造函数模式 3.原型模式 4.混合构造函数和原型模式 5.动态原型模式 6.寄生构造函数模式 7.稳妥构造函数模式 1 ...

  4. java面试编程题

      [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?   //这是一个菲波拉契数列问 ...

  5. 【剑指Offer面试编程题】题目1360:乐透之猜数游戏--九度OJ

    题目描述: 六一儿童节到了,YZ买了很多丰厚的礼品,准备奖励给JOBDU里辛劳的员工.为了增添一点趣味性,他还准备了一些不同类型的骰子,打算以掷骰子猜数字的方式发放奖品.例如,有的骰子有6个点数(点数 ...

  6. 【剑指Offer面试编程题】题目1362:左旋转字符串--九度OJ

    题目描述: 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S=&qu ...

  7. 【剑指Offer面试编程题】题目1504:把数组排成最小的数--九度OJ

    题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 输入: 输 ...

  8. 【剑指Offer面试编程题】题目1524:复杂链表的复制--九度OJ

    题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点). 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第 ...

  9. 【剑指Offer面试编程题】题目1521:二叉树的镜像--九度OJ

    题目描述: 输入一个二叉树,输出其镜像. 输入: 输入可能包含多个测试样例,输入以EOF结束. 对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000,n代表将要输入的二叉树节点 ...

随机推荐

  1. webstorm常用快捷键及插件

    子曰:工欲善其事,必先利其器.那么问题来了,前端开发用什么比较好? 我反正用的是webstorm,之前也花了一些时间看看别人的使用方式.下面分类介绍一下. 常用快捷键: double shift : ...

  2. iOS 之 ARC 的内存泄露

    循环引用导致内存泄露,如block容易内存泄露

  3. Jq对象与dom对象的互相转换!

    JQ对象转化成dom对象 var a=$('div'); var b=a[0];//dom对象 转化成dom对象以后就可以使用dom方法了 dom对象转化成jq对象 var a=document.ge ...

  4. Activity的生命周期与加载模式——Activity的4种加载模式

    配置Activity时可指定android:launchMode属性,该属性用于配置该Activity的加载模式,该属性支持如下4个属性值. standard:标准模式,这是默认的加载模式. sing ...

  5. JSP EL表达式 获得 request的GET/POST方法

    JSP EL表达式 获得 request的GET/POST方法: 不在requestScopse中: <p>得到request的方法</p> <p>pageCont ...

  6. DNS没有生效的几个原因

    1.记录没有正确添加 请确认你的域名记录是否完全正确的添加.线路类型正确,记录类型正确 2.域名还没有生效 这个情况还会有另外一个现象,就是域名有时候可以ping,有时候不能ping. 这是因为你当地 ...

  7. Libcurl细说

    libcurl教程   原文地址:http://curl.haxx.se/libcurl/c/libcurl-tutorial.html 译者:JGood(http://blog.csdn.net/J ...

  8. 纯CSS3实现不错的表单验证效果

    这是补充HTML5基础知识的系列内容,其他为: 一.HTML5-- 新的结构元素 二.HTML5-- figure.time.details.mark 三.HTML5-- details活学活用 四. ...

  9. 第一篇:CUDA 6.0 安装及配置( WIN7 64位 / 英伟达G卡 / VS2010 )

    前言 本文讲解如何在VS 2010开发平台中搭建CUDA开发环境. 当前配置: 系统:WIN7 64位 开发平台:VS 2010 显卡:英伟达G卡 CUDA版本:6.0 若配置不同,请谨慎参考本文. ...

  10. CodeForces758D

    D. Ability To Convert time limit per test:1 second memory limit per test:256 megabytes input:standar ...