It's official: I hate programming tests.
Don't get me wrong, I understand their use and the reasons why potential employers give them out. There's enough programmers in the world who aren't really skilled enough for the job (whatever that job may be) that it becomes necessary to offer some kind of litmus test that a potential job-seeker must pass. I get that.
And it's not like all the programming tests in the world are created equal. Some are pretty useful ways to demonstrate basic programming facilities, à la the FizzBuzz problem. Other projects I've seen, à la the Robot on Mars problem ThoughtWorks handed out to candidates, are good indicators of how a candidate could/would handle a small project entirely on his/her own. (The Robot on Mars scenario, in case you're interested: A robot lands on Mars, which happens to be a cartesian grid. Assuming that we hand the robot these instructions, such as LFFFRFFFRRFFF, where "L" is a "turn 90 degrees left," "R" is a "turn 90 degrees right," and "F" is "go forward one space," please write control code for the robot such that it ends up at the appropriate and correct destination. Include unit tests.)
But the ones where the challenge is to implement some algorithmic doodad or other? Shudder.
For example, one I just took recently asks candidates to calculate the "disjoint sets" of a collection of sets; in other words, given sets of { 1, 2, 3 }
, { 1, 2, 4 }
, and { 1, 2, 5 }
, the result should be sets of {1,2}
, {3}
, {4}
, and {5}
. Do this and calculate the big-O notation for your solution in terms of time and of space/memory.
I hate to say this, but in 20 years of programming, I've never had to do this. Granted, I see the usefulness of it, and granted, it's something that, given large enough sets and large enough numbers of sets, will make a significant difference that it bears examination, but honestly, in times past when I've been confronted with this problem, I'm usually the first to ask somebody next to me how best to think about this, and start sounding out some ideas with them before writing any bit of code. Unit tests to examine input and its expected responses are next. Then I start looking for the easy cases to verify before I start attacking the algorithm in its entirety, usually with liberal help from Google and StackOverflow.
But in a programming test, you're doing this alone, which already takes away a significant part of my approach, because being an "external processor," I think by talking out loud. And if, like this one, it's timed, you're tempted to take a shortcut and forgo some of the setup (I did) in order to maximize the time spent hacking. When you end up down a wrong path (I did), you have nothing to fall back on.
Granted, I screwed up, in that I should've stuck to my process and simply said, "Here's how far I got in the hour." But when you've been writing code for 20 years, across three major platforms, for dozens of Fortune 500 companies and architected platforms that others will use to build software and services for thousands of users and customers, you feel like you should be able to hack something like this out fairly quickly.
And when you can't, you feel like a failure.
I hate programming tests.
Update: By the way, as always, I would love some suggestions on how to accomplish the disjoint-set problem. I kept thinking I was close, but was missing one key element. I particularly would love a nudge in doing it in a object-functional language, like F# or Scala (I've only attempted it in C# so far). Just a nudge, though -- I want to work through it myself, so I learn.
Postscript An analogy hit me shortly after posting this. It's almost as if, in order to test a master carpenter's skill at carpentry, you ask him to build a hammer. After all, if he's that good, he should be able to do something as simple as affix a metal head to a wooden shaft and have the result be a superior device to anything he could buy off the shelf, right?
This article, "Why I hate programming tests," was originally published at JavaWorld.com.