FizzBuzz: One Simple Interview Question

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Ten years ago, a friend of mine called Imran wrote about hiring programmers. He said that he was seeing people being interviewed with good computer science degrees who, while they knew all the theory, had no idea about how to actually code in the real world. And he proposed a simple test. Now, hiring programmers is a tricky job. I don't think that asking complicated lateral thinking questions is a good way to hire people, and neither is picking folks who you think will "just fit in". But a simple test to make sure that someone can actually code: yeah, that makes sense. So here is the test that Imran proposed: code something that'll play the children's game of FizzBuzz. FizzBuzz is really simple. Traditionally, it is played between two people, and you count up in turn, 1, 2, 3, 4, except every time there's a multiple of 3, you say "Fizz" instead of the number. And every time there's a multiple of 5, you say "Buzz". So: 1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, and so on and so on! And when it's a multiple of both, at 15, you say "FizzBuzz". Right, so anyone who's going in for a job in computer programming should be able to pass this test: write a program that outputs FizzBuzz for the numbers 1 to 100. And it's a clever test for a number of reasons. First, there are many possible approaches. I'll run through a couple of them here, but you folks will be able to come up with loads more. If you want, pause the video now and have a go at it. The approach that people choose, and how they work through the problems, will also give you a good insight into the style of programmer they are. Do they quickly just bodge things together to make it work and fix immediate problems, like I do, or do they start out planning for the future and try to figure out what might change later? As well as that, FizzBuzz includes something that's a little tricky to express well while programming: If it's a multiple of 3, you do something. If it's a multiple of 5, you do something else. If it's a multiple of both, you do a third thing. And if it's neither, you do a fourth thing. That’s not instantly translatable into code. So I'm going to show you how I would do it, the quick bodge-it-together approach, and then we'll see how we can start to push it a little bit further. I'm writing in JavaScript: it's not the best language in the world, but it is one of the easiest to get started with. First and most obvious step: create a loop. We're going to want to run through the numbers 1 to 100, so we create a for loop. A for loop works like this: first, run that bit of code. It creates a variable, i, and it starts it out with the number 1. Then every time it reaches the bottom of the loop, where the bracket is, it goes back to the top and runs that bit of code, increasing i by 1, and then checks it against that bit of code. If i is less than or equal to 100, it runs this code again. If not, it exits the loop. So whatever's inside here? We are doing it 100 times, and in each loop i is going to be increased by 1. Programmers use the letter i for variables like this because... er, actually, I have no idea, it's just tradition. Okay. Next up. We need something to output the results. In JavaScript, the sort that's in a plain text window, you use console.log() for this. If you were putting it in a web page you'd use something else. So: console.log(i); Output whatever is in the i variable. Test it, and sure enough, you get 1 through 100. Sometimes, though, we want it to output 'Fizz' or 'Buzz' instead. So let's put that in an if statement. If… If what? If i is a multiple of 3, we need to write 'Fizz'. So: code. That % sign is the modulo operator. It returns the remainder after you divide something. So here, it's saying, divide i by 3 and return the remainder. If the remainder is zero, then we know i is a multiple of 3, and we run that code. And if the remainder's anything else, then i is not a multiple of 3, and we skip it. So now again for 5. Now what about FizzBuzz, if it's a multiple of both 3 and 5? Well, that's already been done for us, right? If it's a multiple of both, then both these tests are going to return true, and we get 'Fizz' and 'Buzz'. So the last bit: if neither of thode are true, just output the number. In this case, we want that: Okay, it doesn't look simple, but I promise it is. That means "not equal to". And that means "and". So this whole section will only return true if both the bits in brackets are true. Cool. Let's run it. And that's... well, it's OK, I guess. It does the job. Except... what's going on at 15? That doesn't say FizzBuzz. That says "Fizz" and then "Buzz". Two separate lines. Two separate answers. That is not technically correct, 'cos it needs to say 'FizzBuzz' there. One line. So we can add a few more tests. Let's add a separate one for FizzBuzz there, using what we've learned already. If both of those tests return true, print "FizzBuzz". And then let's add some more tests in there, so they don't fire twice. This is getting quite ugly. Repeating yourself like this is a sign of dodgy code. It's clumsy, it's difficult to read and difficult to maintain. So let’s change it around a bit. Let’s test for both being true first. Now we can use an ‘else’ statement: if it’s not a multiple of both, is it just a multiple of 3? And if it’s not, if is just a multiple of 5? And if it’s still not, then we know to just output the number. But to me, this is still dodgy. Because if someone says, 'okay, now we want it to work on multiples of 7, not 5', and that's a common sort of follow-up question for something like this, you have to remember to change all the 5s. Not a big problem in a section of code this small, but once you start working on something big, this is really bad practice. Ideally, you shouldn't run the same test twice. But how else can it be done? Well, here's how I wrote this the first time I tried it. Create a variable called "output" that's just an empty string. A blank bit of text, nothing in it. If i is a multiple of 3, you add "Fizz" to that line of text. You don't output anything yet, you just store that for the future. If i is a multiple of 5, you add "Buzz" to that line of text. Don't replace it: just add it. And then, don't test the number again -- test that string of text. If it's empty, we know none of these tests were true, so you just make the text the value of i. Now at the end of the loop, you output… well, the output. So now, if whoever's running the interview says 'make it work on 7s, not 5s', you only have to change one thing in an obvious place. If they say 'make it work on 3s, 5s, 7s, 11s and 13s', you just copy and paste that line and it just does. Programming that with else statements would be a nightmare. Now I think there are still better ways to code this, particularly if you wanted to plan long into the future. After all, those lines there... I'm technically repeating myself. But I'll leave fixing that as a problem for someone else. This is good enough for me. Now there are still some companies who use this particular test for hiring, particularly because, y'know, some interviewers can’t think of anything better. But there are also many problems like it: things that a lot of computer science degrees don't teach because they're all about the theory. Me? I'm more in favour of bodging things together and making them work well enough. Just don't leave too much of a mess for whoever comes along to maintain your code once you're done with it. Thank you to everyone here at the Centre for Computing History in Cambridge for letting me film and thank you to all the proofreading team who helped make sure I got my script right.
Info
Channel: Tom Scott
Views: 3,545,772
Rating: undefined out of 5
Keywords:
Id: QPZ0pIK_wsc
Channel Id: undefined
Length: 7min 18sec (438 seconds)
Published: Mon Jul 31 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.