This is the second article I’ve written on the ThoughtWorks recruitment process (for developers) and today I’ll shed some light on how I approach reviewing a candidate’s submitted code problem and what that means for how candidates should approach these problems.
It’s important to note that what follows is largely my opinion. My opinion is considered and experienced, but it’s opinion nonetheless. Try as we might, no two ThoughtWorkers will agree on an exact standard to which coding problems are reviewed. We round off some of the edges of this risk by having two ThoughtWorkers review almost all our code submissions.
If a developer candidate has already had a conversation with one of our recruiters and both parties are happy to proceed, then the next step is that they are sent a menu of coding problems and asked to submit a solution to one of them within 72 hours in a language of their choice.
Hint #1. Yes, there are solutions to these problems online and easily searchable via Google. There’s nothing stopping you submitting one of those solutions as your own, however if you’re considering this approach then let me save you the time: ThoughtWorks is definitely not the company for you.
Hint #2. There are no right or wrong choices when it comes to the coding problems. Different people will gravitate towards different problems because;
– they concern a problem domain that appeals to them, or
– they seem easy/hard, or
– they are similar/different to problems they’ve solved before
– they think they’ll give them the best chance to shine in a particular language
If I’m doing an interview with a candidate to review their coding problem (typically the next step in the dev recruitment process), I’ll ask why they chose that particular problem, but I don’t attach any further significance to the choice of problem itself.
Hint #3. It doesn’t matter which language you choose. We all have preferences to reading and writing different languages and there’s a lot of language snobbery that goes on inside TW, but there’s no point trying to game this to your advantage. Some languages are more problematic to review from a practical perspective (e.g., we almost all use Mac laptops, but still need to review .Net solutions), but beyond that we can always find reviewers with enough depth in most common languages. Some languages naturally fit some types of problem better, but you don’t gain any automatic benefit from choosing language X for problem Y.
Hint #4. Usually, all people need to hang themselves is enough rope. As with production code, you should be striving to write as little of it as possible. More code gives a bigger surface area for problems in terms of implementation, style or just plain defects. Our coding questions, like all requirements, are incomplete. What you choose to assume around the missing/ambiguous requirements could mean a lot more or a lot less code to write. If it were me, I’d err on the latter. This is the coding equivalent of http://quotes.lifehack.org/quote/mark-twain/it-is-better-to-keep-your-mouth/. So how do you impress us with your mad chops while heeding my advice to write less code? Balancing these tensions well is where gifted developers will shine.
Hint #5. Make sure you get the basics right. What version of the language is needed? What version of any libraries? How do I build? Test? Run? Answers to these questions should be mind-bogglingly obvious to me when I have my reviewing hat on. Once I get past all this bootstrap-y stuff, I can start to get comfy with your code, which is what I really want to do. I aim to spend 30 minutes on average looking at the code and the less hoops I need to jump through to get to that point, the better. Try not to annoy me before that 30 minutes has started by having to use trial-and-error to work out which version of JUnit you’ve coded against.
Hint #6. Like most reviewers, I start from a hypothesis of “this candidate should continue through the recruitment process” and look to disprove this theory through examination of the code. I don’t have any single thing that will automatically “fail” a solution in my mind, but I do look for consistency in design and naming, an even distribution of responsibility, simplicity in construction and decomposition and lack of duplication in/between code and comments as baseline for a good solution.
Hint #7. And automated tests. Doesn’t everyone do them now? TDD is not a necessity but I’d need a lot of persuasion that a lack of any form of automated testing in a submission is a good thing. It would make me start to consider what sort of development culture has the candidate come from, which leads to the biggest form of stress I have in this part of TW recruitment…
How do you reverse engineer a feeling for “potential” out of a static snapshot of code? Like all good employers, ThoughtWorks hires for potential, not current skills, yet a code review plainly focusses on the latter rather than the former. I can excuse a lot of coding evils with a bit of background knowledge about the candidate, but that is information that’s normally not available or too subjective to use.
Really high quality code submissions can be spotted a mile away and are quick and boring to do.
Truly poor submissions are similarly quick to spot but far less quick and boring because writing up feedback for our recruitment team takes a lot more time.
Between those two extremes are the majority of submissions which are generally good but with some really interesting issues to be picked up on if the candidate comes into our office for the next step in the process.
But a largish minority of submissions fall into the “not too bad, assuming the candidate [insert assumption about degree of past experience/exposure to strong dev culture here]” bucket. These are the ones that take a lot more time to conclude on. I’m sure I’ve missed the mark on some of these submissions. hopefully to the side of being inclusive rather than exclusive.
And if you’ve ended up being included as a result of a code review, the next step in recruitment is to get you physically into one of our offices to pair with some developers on further development of your solution. This is the step I’ll be talking about next.