it turns out

3 coding interview tests I failed

It's no fun to fail an interview. But reading about failure is usually more fun than reading about success. And probably more educational.

I flunked three coding interview tests over the years.

The first two stories are set in March 2000, right at the peak of the dot-com era. The bubble was getting ready to burst and erase more than three quarters of NASDAQ valuation, a loss that would only be recovered 15 years later.

I was graduating from University of Waterloo's prestigious Computer Science program in April 2000, just in time to enjoy the last bit of the madness. During my final semester prospective employers were flying us around the continent, and wining-and-dining us to impress us into joining them. Without even trying to game the system, I got flown from Toronto to high tech hubs of Ottawa, New York, and Boston.

CarOrder.com · Austin, 2000

But the trip to Texas to interview with CarOrder.com, a start-up by vaunted Trilogy, was by far the most impressive. They even had my girlfriend come along. They flew us to Austin where they had a car rental and a hotel arranged for us. Over the next couple of days, we socialized with Trilogy employees - during the day on their gorgeous suburban campus (whose parking lot resembled a Porsche dealership), and in the evening on downtown Austin's Sixth Street.

It worked. I was thoroughly impressed with the company and with the city.

The price I paid for interviewing with a genuine high-flying IT company was a typical tough programming interview that can sometimes feel like a hazing.

Recursion, often a very difficult concept for programming students, absolutely shines in binary tree traversals. They are literally textbook examples of recursion, right after factorials and Fibonacci numbers. Just compare recursive and iterative algorithms from Wikipedia article on tree traversals:

preorder(node)
	if node == null then return
	visit(node)
	preorder(node.left)
	preorder(node.right)
iterativePreorder(node)
	parentStack = empty stack
	while (not parentStack.isEmpty() or node ≠ null)
		if (node ≠ null)
			visit(node)
			if (node.right ≠ null) parentStack.push(node.right)
			node = node.left
		else
			node = parentStack.pop()
inorder(node)
	if node == null then return
	inorder(node.left)
	visit(node)
	inorder(node.right)
iterativeInorder(node)
	parentStack = empty stack
	while (not parentStack.isEmpty() or node ≠ null)
		if (node ≠ null)
			parentStack.push(node)
			node = node.left
		else
			node = parentStack.pop()
			visit(node)
			node = node.right
postorder(node)
	if node == null then return
	postorder(node.left)
	postorder(node.right)
	visit(node)
iterativePostorder(node)
	parentStack = empty stack	
	lastnodevisited = null 
	while (not parentStack.isEmpty() or node ≠ null)
		if (node ≠ null)
			parentStack.push(node)
			node = node.left
		else
			peeknode = parentStack.peek()
			if (peeknode.right ≠ null and lastnodevisited ≠ peeknode.right) 
				/* if right child exists AND traversing node from left child, move right */
				node = peeknode.right
			else
				visit(peeknode)
				lastnodevisited = parentStack.pop() 
				node = null
Binary tree traversal algorithms - recursive and iterative

I was familiar with these algorithms before the interview. A professor hand-wrote them on the blackboard for a second-year computer science class. I marvelled at the contrast between succinct recursive algorithms and their unwieldy iterative counterparts: "Wow, am I happy that I will never have to recreate this ugliness from scratch."

And then I found myself at a white board in a conference room, with two interviewers telling me: "Write a post-order binary tree traversal without using recursion."

I couldn't believe it. Of all the things they could have asked me. I couldn't believe it.

No amount of explaining and pleading would help. I had to stumble my way through my programming nightmare, while an audience of my peers prodded, helped, and judged me. And ultimately gave me a failing grade.

In preparation for writing this post, I tried writing the algorithms from scratch again. I was failing miserably, even without pressure and with decades of programming experience. As I was giving up, I realized that I had somehow misremembered the lesson from my university class. For some reason I thought the iterative solution had to use two stacks, not just one. Once I disabused myself of that notion, I got the algorithms done within a few minutes. I don't know whether the same misconception also stymied me in that wretched interview 15 years ago.

If there is any good that came out of this fiasco, it's that the next interviewee didn't get subjected to the same grilling. Instead his coding test was to look at my code on the white board and determine what it did. He nailed it.

I would later find out that my all-expenses-paid three-day guided trip to Austin for two wasn't even the royal treatment. A colleague's interview process with CarOrder included a skiing retreat, the details of which were so lavish that he was embarrassed to share them. Five months later, the company would lay off two thirds of its staff.

Descartes Systems Group · New York, 2000

In this climate of irrational exuberance the phone call from Descartes Systems Group * seemed completely out of place:

"Before we start the interview process, I need you to write a QuickSort in C++, and email it to me for review."

I was taken aback. No other employer dared ask me for any favours prior to wooing me.

And why would they, I thought. I busted my ass through an extremely difficult university program, where mandatory assignments included writing an operating system. I earned the trust to sort a damn array.

This was long before the discovery of Fizz Buzz. I had no idea that some programmers couldn't program. In fact, I still find that hard to believe, at least for those who managed to graduate from my class.

With all due respect to my interviewer, I hadn't even heard of his company previously. I had heard of Goldman Sachs, and they were about to fly me to that same New York City, sight unseen.

It's no surprise then that I was not too eager to put in an effort in the pre-interview process.

And an effort it was. Believe it or not, at the time, despite being about to graduate with a Computer Science degree, my home computer had neither email access nor a C++ compiler. I would bike over to the campus lab and get on a Unix terminal in order to get any real work done. And I thought the only C++ compiler they had was μC++, a specialized flavour written by one of my profs. Of course, had I put in the work, I would have found a solution - μC++ itself would have sufficed - but I was half-assing it.

I was considering the whole exercise ludicrous and I treated it as such. Instead of getting a C++ compiler, I just dusted off my book to refresh my memory on its syntax, and wrote a QuickSort from memory. I could have just copied the code straight from the web, but I figured I would be honest. I looked over my solution a couple of times, determined that it would probably compile and run, and sent it in.

Apparently not plagiarizing all the way was a mistake. The interviewer called back and told me that the code that I had sent "contained at least three errors". So I came clean about the situation I was in, and about how I had put together the code. I was hoping he'd cut me some slack, and trust me enough to test my skills in person. He didn't.

In fairness, he was right. But part of me still hopes that he ended up hiring some incompetent who had no qualms about just copy-and-pasting QuickSort straight from StackOverflow of the day. What can I say, I hate getting rejected.

But in a way, it was me who rejected him. It was an employee's market in early 2000, and I was looking for reasons to reject prospective employers. I didn't have the heart or the guts to simply say: "No, I don't want to continue this interview process, I am busy with other prospects," so I instead half-assed my way into a rejection.

Just a year later I would hardly be able to get any job interview at all, let alone get flown across the continent. Such was the contrast between the boom and the bust.

The Globe and Mail · Toronto, 2012

I thought this would be a dream job. The Globe and Mail is a company that I had long admired. Their head office is within a 10-minute walk. And they needed my exact skill set - a very experienced front-end guy with an emphasis on user interface and visualization skills. I worked hard to get the interview, and when I did, I was so exhilarated, I had to deliberately temper my expectations. Maybe the position would not be what I thought, maybe they would not see the value modern JavaScript visualizations could add to their content, or maybe we would not be able to agree on the terms of the contract.

It never occurred to me that I could flunk the interview.

It started out well enough. An hour-long talk with two interviewers. The guy was technical, seemed to know his stuff, and we had great rapport. I have no clue what the lady's role was, because she said absolutely nothing during the entire hour. I think she took some notes, but I got the feeling that she really didn't want to be there, and was annoyed that the guy and I were hitting it off and prolonging the process.

I was a little uneasy about this Good Cop / Bored Cop routine, but I have seen variations of it before, and knew not to read too much into it.

At the end of the face-to-face interview, all that remained was the test. My interviewers politely bid me bye-bye and directed me outside of the employees-only area, where an impartial third party from the HR department would administer a 15-minute quiz on my way out.

The quiz was a flashback to high school. It was a piece of paper with about a dozen questions, a few of them multiple-choice. It was a closed-book closed-internet test.

One of the questions I remember was: "List five tags that were introduced with HTML5." This really struck me as a question that would be written by a high school humanities teacher putting together a programming test. Was it really crucial to know tags like <summary> and <details> which IE and Firefox still don't support in 2015, three years later? Still, I may have managed to get marks for that question thanks to <canvas>, <video>, and <input type="tel">, or whatever it is I wrote.

What really killed me were the many jQuery questions. I know it's preposterous that I claim to be a front-end guru who didn't know jQuery in 2012, but I have a bit of a weird background. The foundation of my DOM knowledge came from working at a dream job at ComponentArt (since renamed to Datazen) from 2002 to 2009. Datazen was always a Microsoft shop, and has since even been acquired by it, so incorporating open source libraries into our code was not high on the priority list in those days. Besides, when we started, there was no jQuery. By the time it came out in 2006, we had long written our own internal jQuery-like implementations for the many DOM manipulations that we needed.

I admit it's really odd that it took me until 2012-2013 to learn jQuery, but I knew DOM, and vanilla JavaScript manipulations served me just fine. When I finally ran into a codebase that used jQuery, it took me no time to get a good working knowledge of it. Two hours tops. That's not a brag, it's a credit to jQuery. jQuery is an abstraction over DOM and CSS. I knew DOM and CSS. Because the abstraction is brilliantly written, of course I could pick it up on the run.

But I surely couldn't pick it up in a 15-minute test without internet access. I was dead in the water. Globe and Mail never called back.

I felt bad for letting down the Good Cop. If only I was able to explain myself to him, like I did here. But he was gone before I got to the test, and I figured I had no leverage to call back and explain myself, after having flunked it. I didn't have the foresight to learn jQuery specifically for the interview, and was too optimistic in thinking that if the questions about it came up, I could explain why it is missing from my background.

The Common Thread

All of these coding tests either didn't resemble coding work or introduced unnecessary barriers to communication - or both.

  1. The first one was an unnecessarily complicated algorithm, written on a whiteboard in front of a live audience of judges. Many companies conduct programming interviews like that, but nobody programs like that. Thankfully this kind of interview seems to be going out of style at last.

  2. The second one would have been appropriate had it been done in person. Doing it remotely made obtaining the tools - in this case a responsibility of the employer - the most complicated part of the test for an honest candidate. It simultaneously did absolutely nothing to guard against a dishonest one.

  3. The third one was like one of those high school quizzes that you could cram for and nail, only to forget it all by next week. It was so far removed from actual programming that I doubt it served any purpose. It also introduced an artificial barrier between the interviewer and the interviewee, having the test administered by a blinded third party. They do that for SATs only because they have to. You don't.

A good coding test closely resembles the work environment that it is testing for:

  • It features the kind of task that the candidate will perform on the job.

  • It uses the equipment that will be used on the job.

  • It provides for communication between interviewer and interviewee, but it doesn't turn programming into a performance art.

None of these coding tests were good.

See, it couldn't be me, it was the tests. No way was it me.

comments on Disqus