A little while ago while writing this post, I came across the post by Jeff Atwood where he talks about the FizzBuzz test (originally found here). I remember seeing that post for the first time a couple of years ago and thinking that I would be a little insulted if someone asked me to write something that trivial in an interview. Seeing it again the other day I realized that my feelings hadn't changed. It IS an insulting question. Sure you may quickly weed out complete incompetents by asking it, by you will also alienate just about every competent developer. There is really no reason to ask a question that simple. You might as well ask something more complex, that could really test a programmer's skills. The incompetent will still have no chance, and you won't make the decent developers feel like you're making fun of them. If you can't think of any interesting programming questions to ask (and you don't like my quine question :)), I will try and cover a few decent, straight forward coding questions at some point in the future. But, that's not what this post is about.
You see, when I was reminded of the "FizzBuzz" question, what I actually thought to myself was something along the lines of:
What an insulting question, I could do that in 10 seconds or less!
Of course having thought that, I immediately had to prove to myself that I actually could do it (curse you developer personality :)). So, I took the subsequent 10 seconds to come up with this (in Ruby, of course):
(1..100).each do |index| if index % 3 == 0 puts "fizz" elsif index % 5 == 0 puts "buzz" elsif index % 3 == 0 && index % 5 == 0 puts "fizzbuzz" else puts index end end
Did you spot it yet? What I gigantic fail on my part. Here is a snippet of the output:
... fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizz 16 ...
Everything is fine until we get to 15 and – no "fizzbuzz". Of course, there is no way we could ever get a "fizzbuzz" with the above code. If a number is divisible by 3 AND 5 it must be divisible by 3 OR 5 and so the first two conditions of the if..else block would match before we ever get to the third one. It should have been this:
(1..100).each do |index| if index % 3 == 0 && index % 5 == 0 puts "fizzbuzz" elsif index % 3 == 0 puts "fizz" elsif index % 5 == 0 puts "buzz" else puts index end end
Now everything is fine:
... fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 ...
The lesson here is this. It is never a good idea to write code mindlessly. No matter how trivial you consider a problem to be, don't just switch off and write it on autopilot. Even if it was only going to take 10 seconds, take a few seconds more to think, before you jump in and then take another 10 seconds to make sure you didn't miss anything once you've finished. Not only will you write better, less buggy code, but you will also never end up in one of those embarrassing situations where you feel insulted by a "fizzbuzz"-type question and get it wrong anyway :). It just doesn't pay to mentally switch off in our line of work. I thought that little snippet of wisdom was worth sharing and even if you already consider it common sense, it never hurts to be reminded.
Image by Vidiot