In this article, I will answer the following question: Why would two companies pass up on hiring a talented programmer based on personality insights gleaned from a coding project?
The short answer: Both companies determined that the programmer would be rather unruly.
We will expand on this answer by examining two variants of the coding interview project through the lens of my personal experience.
- Implement a feature and fix pre-planted bugs on an existing codebase
- Build a project from scratch, given guidelines
Please note that I have removed the names of the companies involved (you’ve heard of them both)
Picture a juniorish developer, obsessed with iOS, design patterns, and functional programming.
My days at this point consisted of experimenting with various iOS architectures, devouring lecture after lecture on Swift design patterns, and submitting my resume to just about every company with an open mobile developer role.
Variant 1: Implement a feature and fix bugs in an existing project
I managed to secure an interview for a Staff Mobile Developer position at a large financial services company.
As a start up fan, joining a workforce of 20,000 khaki-laden employees spread across offices in San Francisco and Austin was not my cup of tea, but the pay was fantastic and having a company like that on my resume would surely open doors in the future.
The interview process was fairly standard: a quick phone screen, some technical questions, and then the test project.
The test project had an interesting format: Instead of building a project from scratch, I was given an existing codebase and told to add a new feature, fix a few bugs, and make sure all of the unit tests passed.
After cloning the codebase and the README containing the instructions from Github, two things jumped out:
- The directions for the new feature were fairly vague
- The codebase was object-oriented without a single functional design pattern in sight (sacrilege!)
My strategy for the project was two-fold and completely doomed from the start — I’d submit two versions of the project:
- Build out the new feature and fix the bugs using the existing code, as per the instructions
- Refactor the codebase to be ultra-functional (I wanted to show off)
The bug fixes were easy, but the new requirements for the new feature were very vague (almost intentionally so) — I’d later find out that the vagueness was in fact purposeful.
Despite being unclear about the exact requirements of the feature, I asked zero questions. I thought questions would be viewed as a sign of stupidity and weakness.
I implemented the feature, made sure all of the tests passed, and submitted my code.
Then I got to work refactoring.
I rewrote the entire codebase to be ultra-functional — creating custom operators, squashing state, and writing code so terse as to dazzle the sharpest of NSA cryptographers.
And I thought it was genius. I submitted my Mona Lisa and awaited the applause.
A week later I found myself seated in a conference room in the company’s Austin headquarters wearing khakis with a tucked-in button down shirt (a far cry from my usual coffee combo)
The entire mobile leadership team entered the room: 6 or 7 senior-looking devs, several donning rather intimidating facial hair.
They opened my functional rewrite on a giant screen, and one of the bearded ones said something to the effect of, “This is super interesting, you are clearly a talented programmer. That being said, half of our team loved what you did, the other half hated it.”
Polarizing to say the least.
I explained to them all of the cool functional stuff I implemented and how they could implement these practices in their production code.
Boom. Nailed it. I descended from my soapbox, feeling rather satisfied.
A bearded member of the dissenting half then said the following: “We have hundreds of thousands of lines of object-oriented code spread across dozens of apps with established guidelines and you expect us to switch programming paradigms completely? We are not interested in that. We are interested in code that passes unit tests.”
“Passes tests???”, I thought to myself — Surely that wouldn’t be an issue.
Until it was.
The team iOS lead then ran the entire testing suite. Live. On the spot. And it took all of 20 seconds to see that I passed exactly 0% of them.
My heart sunk. I almost laughed. In my desire to show off, I neglected to run the test suite prior to submitting my Mona Lisa. This surely spelled failure.
They let me know that this wasn’t an out-right deal breaker and that the team actually took a substantial intellectual interest in my code and they’d let me know their decision in a few days.
3 days later, sitting in an Austin coffee shop the bad news wedged its way to the top of my inbox
After much discussion with the team, we have determined that we need to move forward with another candidate. While we are impressed with your functional abilities, this is ultimately not what we are looking for. We are looking for someone to join the team and follow instructions. We fear that you would be too unruly of a programmer. And while we encourage experimentation and pushing the boundaries, you seem pretty dead-set on making everything functional while ignoring the larger needs of the organization.
Also, you asked zero questions about the new feature we were looking for. We made the instructions intentionally ambiguous. We want developers to ask questions. Lots of questions.
We wish you the best of luck moving forward
Variant 2: Build a project from scratch
Same summer. 2016.
I came across an opening for a Lead Mobile Developer position at a growing start up with a completely distributed global team building a suite of productivity apps.
The position, a developer’s dream: Work when you want, where you want with annual company meetups in amazing locations — Iceland, Greece, Thailand, anyone?
While I was likely a bit too junior for the listed position, I bucked up and sent in my resume.
After passing the initial phone interview, I was given a test project and 2 weeks to complete.
The requirements of the project were actually fairly involved: Build a mini iOS version of their popular productivity app from scratch. I’d have to create and manage application state, build out networking infrastructure, add some fancy animations, and run the business logic through a custom testing suite — They estimated it would take a good developer 2–3 full days to complete.
I had yet to learn the dont-show-off-just-write-solid-code-lesson from my previous interview failure, and as I got to work, my functional programming mind started humming.
I completed the project, sent the CTO an invite to my private Github repo, and awaited the response.
While interested in the code, the CTO ultimately informed me that they were moving forward with another candidate.
The primary reason: The code. It was ridiculous.
I invented a series of custom operators, pulled in arcane third-party networking libraries, and even wrote a function that spit out ViewControllers (wut?).
The CTO was ultimately looking for a developer who could lead a growing mobile team.
While my use of function currying and custom operators was “a nice party trick”, how was another developer supposed to join the team and immediately begin hacking on such an abstruse codebase?
The team was already taking on the risk of writing their iOS app in Swift, which was barely two years old at the time, and here I was pushing the compiler into overdrive.
Neither company ended up hiring me because of the way I wrote code. Despite my clear technical ability, the coding projects captured my coding style in a way that an algorithm test or white-boarding could not have teased out.
- Could I have passed an algorithm test? Probably.
- Could I have passed an onslaught of arcane mobile os questions? I did.
Would either of those tests fished out that I was likely an unruly and dogmatic programmer? Not likely.
If you are looking for someone who will be contributing to an established codebase, give them an existing project. Ask them to add a feature and fix bugs using a set of coding guidelines. Candidates fear that asking questions denotes weakness. Make the feature requirements vague and encourage them to ask questions.
If you are a startup or in the early stages of a project, and are looking for someone who will be making large architectural decisions, building something from scratch is more applicable.