- The quality of a software product is closely correlated with the quality of the people who built it
- High-performance teams are typically populated by high-quality engineers usually of varying experience levels
- A high quality engineer is between 10 to around 100 times more productive than an average engineer
Most teams that I’ve worked on have an open hiring process that anyone can participate in should they wish to be involved. My interest is to find interesting people to work with, people I can learn from. This has the side effect of helping the client somewhat as the team is strengthened by a quality player: a team-player who is technically brilliant, self-motivated, charming and well dressed, who can grasp your domain quickly.
I am really looking for the top 1% of engineers. I think the rest of you should be fired. This isn’t affected by degree, experience, or training. I can give you specific skills; I’m looking for aptitude and potential. I’ve hired recent graduates and I’ve hired names. I hire smart team-players who are engaged and self managing. Any one of the people I choose to work with can be handed any task and (despite grumbling a lot) will step up and do a good job. People who could take over my job in a heartbeat should it be needed.
Given that the top 1% are likely to be subject to higher pay levels and better working conditions than everyone else there are fewer of them on the market than average engineers. And, given that they’re not on the market very long, maybe a tiny fraction of people on the market on any given day are at this level. This makes hiring very difficult — if there aren’t enough stars to go around then you’ll just have to hire average people, right? Wrong, actually. They’ll do more harm than good, and the stars you do have will want to leave for a place entirely populated by stars. If you want to attract stars then you need a culture of excellence and a culture of rewarding excellence. If you don’t have this, then you are an average employer and I don’t want to work for you (see how it works — the best people work for the best employers, because we have a choice).
There are five steps to my process:
Write job description, test candidates, interview anyone passing test, pair with anyone passing interview, hire anyone passing the pairing.
First, the job description is essential. If you’re hiring a contractor then the JD should talk about specific skills and technologies. If you’re hiring a permy then the JD should talk about architecture and technique. Another difference is that for a permy position the JD is a marketing document designed to attract talent. Don’t let a recruitment agency write your JD (in fact, don’t let them become involved in the process at all — you really don’t need them, they’re parasites).
You should ask your good people to distribute the JD through their networks. If you’ve been good to them, then this will happen and you’ll find quality candidates. If you go to an agency then you’ll spend three quarters of your time sifting through useless CVs and resumes. Linked In is great for this. If you’re not on Linked In then you’re being unprofessional.
Eventually you’ll have quality candidates; approximately one in a hundred if you’re doing this through your networks, one in a thousand if you’re using a good agency, and one in ten-thousand if you’re using an average one.
You should have a predefined coding test to send out to candidates to pre-screen them. The test should constitute a couple of hours, maybe an evening’s, work. I ask people to convert numbers to words (1234 = One Thousand, Two Hundred and Thirty Four). I give more guidance than this, of course, but that’s basically it. I use java, so I want the solution in Java. I use Maven, so I want the solution in Maven. I use junit and mockito, so I want the solution to have these dependencies.
This test is a bare minimum. It hardly tests anything really – just some basic skills that I expect everyone on my team to have. The resulting POM is about a dozen lines long. The java code could be done in a few hundred, including tests.
I’m looking for non-procedural solutions that I can load without error into IntelliJ and immediately run all tests and find that they pass. I’m looking for code that’s clear and simple and which can be understood by everyone on the team, easily (it is a very simple problem). I’m looking for evidence of a test-drive approach, with objects rather than procedures, with a simple very simple POM. I don’t want a gui, rest services, json, jquery, performance and memory profiling, or the ability to run on the Amazon cloud. I just want good code that’s easy to read, understand, and maintain. It’s surprising really how many professional engineers with excellent resumes fail this simple test — most of them.
Maybe good people won’t go through the effort of doing the test? Maybe, but I don’t know anyone good who’s really ever objected, so this seems more FUD than reality. But, I don’t really know for sure and I don’t know how to find out. This has been working for me for some years now, so I only have evidence that this isn’t really a problem.
The solutions I received are, much more often than not, hopeless. I typically interview one in ten. I’ve had people supply copies of solutions they found through google. I had one guy submit a solution with another guy’s name in the comments. I’ve had people send me failing test suites, and maven poms that can’t be read by Maven. I’ve had complete solutions written in a single method of procedural (and recursive) code.
If someone completes the test successfully then you should interview them. The interview should start with discussing the test. I like to challenge people at this stage, so I’ll ask some mean questions about garbage collection and classloaders. A mean question is one that has no right answer, it’s designed to put the candidate in a position where I can see how they react to a no-win situation (because it’s often the case that we’re juggling competing sets of requirements, or choosing technologies with no outstanding solutions).
My favorite interview question is: Given that we are in a typical modern large-enterprise environment, how do you implement the singleton pattern in Java? The answer is always wrong; and I do mean always. This question is designed to get the candidate involved in an enterprise level design discussion. The solution has to take into account the fact that my servers are all clustered with live fail-over requirements. The common implementation of the singleton pattern, using a private static final to hold the single instance of a class, fails in this environment because I have multiple copies of my code in the production environment and there will be at least one copy of the singleton on each node of the cluster, violating the singleton pattern. The correct answer is to start by asking what the scope of the intended singleton is and what the runtime deployment topology is? Follow this by talking about a single point of truth (a master instance of the singleton), to which all requests will be tunneled, and the use of the Paxos algorithm to nominate a master instance of the singleton. The discussion can even go into classloaders and the effects of loading a singleton in multiple web-apps in a single container, if you want to avoiding mention of enterprise structures.
The interview is also a chance to assess how a candidate will integrate with and survive your team culture. The culture of a successful team must be protected. That isn’t to say that it can’t evolve and improve — almost everything can be improved (except Anjeo Tequilla), but it shouldn’t be allowed to break. If your team are all atheists and make funny jokes about the beliefs of others, don’t hire a born-again-christian — I’m sure they’re a fine person, but you’re just going to start trouble with that one. If everyone on the team speaks good English, don’t hire someone who only speaks Swahili — it just isn’t going to work out. If everyone on your team is a stoner, you probably shouldn’t be hiring a teetotaler because it’s not okay to bring everyone down. If your team is full of successful, bright, women, don’t hire a misogynist — it’ll only end in tears (his, obviously).
Next is the pair-programming bit. I really like this bit. Bring the candidate in and have them join the team for a few hours, pair programming with a senior developer. They’ll know pretty soon if the candidate is a good fit for the team.
Finally, hire the candidate. This means offering them lots of money. You’re not hiring an engineer, or even a team-member, you’re hiring a talented human. An agent of and asset to the company. Pay them lots and treat them very well; they’re worth it. Empower them to make decisions and give them the authority they need to achieve the goals you set, then get out of the way.
If you do this right, you’ll have a very expensive, high-performance team, that will easily solve all the problems you throw at them. Give them a good process (XP) and they’ll excel at everything and fail at nothing.
In place of the code test you could accept a reference to a public body of work — either on an open source project, or on some sort of portfolio site in the case of a front-end developer. The aim of the code test is to simply week out the non-starters before the interview begins. The code can come from anywhere.