Ask HN: Why do so many software developers fail the FizzBuzz test?
I've been in the interview loop for my company for just over a year now, and one of the most surprising experiences so far has been the high proportion of developers who fail the most basic programming questions.
We use FizzBuzz as one of our easy challenges and I would say that around 80% to 85% of interviewees simply cannot solve this. It's bizarre. Some even refuse to answer and try to turn their lack of ability around onto us for asking the question, as if we're the ones doing something wrong.
What could be causing this? Is this a generation of AI-reliant copy-and-paste code-jockeys who've never developed the ability to think? Is our hiring process perhaps not screening sufficiently for incompetent bullshitters?
These are candidates who come to us with a solid employment history, often having worked for big name tech giants. But they can't figure out this most basic coding puzzle. What's going on? Has anyone else noticed this phenomenon?
I've definitely seen my share of coders who can sling decent code to maintain and extend an app, but not write anything from scratch. It is quite possible to have a solid career without ever having started with a blank slate. Even starting a new project these days, people often grab a framework that starts them with boilerplate.
So it is not really that they cannot code. It is that they cannot go from zero. If you handed them a bad implementation of FizzBuzz and asked them to improve it, they could. But they cannot write the very first line of code because while the code is trivial, the utter lack of context is a new experience.
Whether or not you want that to be a deal-killer for a hiring process is a much deeper question.
agree mostly, although i'd quibble at saying: "So it is not really that they cannot code". i'd certainly say that being able to open an editor and pound out a functioning 20 line program from scratch is a requisite skill for saying you can code.
"Whether or not you want that to be a deal-killer" - exactly. as annoying as these stupid tests are, at least they tell you something. it's surprising how much so.
Fizzbuzz is a stupid test not representative of anything useful. And I say that as a high school dropout, self-taught programmer who easily passed it, but only because I happened to learn about the modulus operator in some online tutorial years and years ago, purely by chance.
After that, in twenty years of professional dev work, I don't think I used the modulus operator or anything like Fizzbuzz again.
Why test candidates on something completely irrelevant to their work? There are much better questions to ask, or potential take-homes to assign.
As a web dev, for example, I'd much rather get a sense of someone's UX sense or their approach to optimizing async calls or how they deal with framework rot etc. There are a ton of interesting everyday problems candidates actually encounter and struggle with, but that have basically nothing to do with math or contrived loops like that.
Fizzbuzz was never meant to represent anything useful; it's an intentionally trivial problem used to quickly filter out unqualified candidates. In the words of its inventor, "this sort of question won’t identify great programmers, but it will identify the weak ones":
https://archive.is/Ybnm
It filters out a specific kind of programmer, but not necessarily the right kind. Somebody might be great at their job but have no domain knowledge of this sort of problem. It's kinda like how Advent of Code is totally irrelevant to a lot of day to day work.
Like maybe back in the 80s and 90s programming was primarily about logic and math, but that hasn't been the case for a long time now. A lot of business apps are just declarative markup plus client-server networking, not necessarily condition cascades like this (beyond super simple switch statements).
I'd much rather have teammates who, say, pay attention to UX details or write good documentation or are just easy to work with, rather than someone who's good at abstract logic puzzles that don't reflect most day to day work.
The problem with Fizzbuzz is not that it's too hard, but that it's not really representative. If you wanted to test conditionals, for example, basic HTTP success / error handling in a try/catch would be more useful and common.
Fizzbuzz is easy if you have an intuitive sense that some numbers are evenly divisible by 5 and/or 3, and either know modulus or can test it manually, but if you don't have that sort of math background, it tests the completely wrong things (mathematical reasoning rather than business app ability). In the US, especially, math education gets worse every year, but that's not necessarily a good reason to filter out coders who would otherwise be perfectly fine writing standard consumer apps.
I can accept that in extreme cases people just don't run across the trivia of what a modulo operator does by more or less random coincidence (while learning programming that is. I get that most people in general would have no idea).
But for conditionals and related logic in whatever nested form they may appear, I'm afraid my ability to disbelief is stretched a little too thin. It seems too basic an operation that is involved in any kind of program I could possibly imagine.
I get how some boilerplate API glue code that a lot of people write does it via stacked layers of dynamic dispatches instead, but I could not expect a person to write such code at sufficient quality without being able to reason through a bunch of next to trivial conditionals (since that's what these dispatches still are, under the hood).
At some level I feel like we are talking about such an extremely low level of basic ability, even if it's not technically constantly necessary for a specific job, that it's highly worthwhile to disqualify lacking applicants anyways. But I can also see how that might be some form of privileged or elitist thinking. Open to hear counterpoints.
Keep in mind that I work in the web world, with small to medium businesses outside of FAANG, so that colors my perspective. But in my career, it's often been a stylistic choice (from me and others) to deliberately emphasize readability and maintainability over than what you might call "efficiency" of code and logic.
That means eschewing things like currying, nested ternaries, deep recursions, etc. in favor of simple, flat switch statements whenever possible, maybe broken out into small pure functions (e.g. isDivisibleBy5() and isDivisibleBy(3)) such that each switch condition could be modularly disabled or swapped in and out, etc. Makes for easier reasoning, unit tests, A/B tests (for users), etc. I think the overall goal is to make each paragraph of code pretty obvious and easy to reason about, without having to click through layers and layers of nested/recursive functions, mutable variables, inherited state, etc.
It's a very deliberate shift away from OOP and huge classes that do everything, in favor of a bunch of micro functions written alongside UI code that looks like declarative PHP. Most often conditionals are used to decide whether to show or hide some UI component based on a var, so that var's lifecycle needs to be simple to reason about. I think a lot of old-school programmers would find that kind of code frankly shitty and terrifying, but it's the normal practice on the web these days, partially as a reflection of how the web frontend world typically works (favoring rapid changes not just in UI code but in underlying frameworks, company priorities, product owners, team makeup, etc... it's all high-churn, low-permanence).
Perhaps that is an idiosyncrasy of the web world, especially in the frontend, where teams are usually made up of less experienced and less formally trained programmers. So the code style adapts to match, becoming more verbose, redundant, and memory-intensive (e.g. rarely do we ever directly mutate something in memory directly, instead copying it to a new var that runs it through a function)... but hopefully more readable, maintainable, and understandable by the next dev to join the team in 6 months. It's a very high turnover field, so being able to quickly get a new member up to speed is more important than writing super efficient code.
Anyway, all that is to say... "programming ability" is not the only consideration. They don't have to be some elite coder to write your basic CRUD app or dashboard UI. Yes, they have to be able to code, but it's easier to teach someone what a modulus is than to try to shape an elite lone-wolf coder into a good team player.
I've spent far more time and energy trying to read, understand, troubleshoot... and then ultimately debug... some mad genius coder's "I am very smart" reimplementation of some common semi-complex pattern, like maybe a hashing function or color conversion system or whatever.
As an admittedly mediocre, self-taught coder (but one with decades of experience), I would typically reach for some popular, well-tested and documented lib for such a use case. But the really good coders that I've met see those situations as a fun challenge and like to write their own implementations that have 90% of the functionality, 3x the performance in quarter of the lines of code... but zero testing and often some edge case bugs. I've had to fix and rewrite a lot of that in my career, usually as the guy who picks up these codebases after the superstar who wrote it has left and moved on to the next startup. So I'm biased against this sort of thinking, instead opting for KISS (keep it simple, stupid) to make my own life and my replacement's life easier.
That's just my perspective though. There are definitely teams and managers who prefer the mad genius lone wolves over run-of-the-mill devs like myself, I just don't particularly like working with them :)
Thank you for sharing your point of view. You have given me a glimpse into a surprising and unfamiliar way of thinking about programming. I'll have to think about this for a while.
Thanks for listening and considering. That's already more than most people do :)
I used a variation of rot13, discovering much the same thing.
I try to put myself in the other’s perspective. Firstly, many (myself included) do not respond predictably on “on the spot”. Going cold into a problem is like doing some responsive physical activity, it often takes some mental warm up. The obstruction of “mental tooling” makes a unit of effort in the span of two hours, two weeks, or two month frames.
Solving the problem in “pseudo code”, in which you don’t actually intend to run it for instance reduces the anxiety of the dev environment not working in exactly the way you require for your iterative dev round trip. Even if it isn’t actually a problem, our mindsets are actually slower switching intellectual frames, where those frames may be compartmentalized competence.
Is that compartmentalized competence in there, and can I get it out? Is it wrapped in a tolerable character? So many dimensions set us apart.
I'm sorry, but I never ask developers about things like FizzBuzz.
When you get a developer, they are joining a project that they know little about, and the value they bring is how quickly they can adapt to the problem space and solution space that your project sits in.
I'm going to call them 'trick questions' when you start asking about things like FizzBuzz, as if the smartest of them all will get the role.
In reality, their ability to learn and thrive in the space your project works is the really valuable thing.
Explain the problem space your product sits in, ask them what they think some challenges could be in that niche, see how insightful they are, or how far off the mark they are. Walk them through developing some of their ideas, leaning on your experience in that space. See what evolves, see if they have some insights you haven't thought of.
There are much better ways to evaluate candidates.