The greatest resource of any company are the people who work for it. Therefore the process by which you hire the people who work for or with you, is extremely important. At REA Tech we have always been keen on trialling new ways of hiring people. We have played around for years with utilities such as codility.com, sample algorithm questions, and even the one hour pairing session with tech leads and other software developers for a substantial amount of time on a business feature. We in the Media and Developer team decided to try and use Git as a means of sorting out the initial set of candidates before bringing them in for the face to face interview. Git is a wonderful version control system designed by Linus Torvalds and one of its features is the history of changes it keeps. This is the most critical feature of Git we chose to use as a candidate sieve.
The purpose of the initial test is to ensure that the person who has applied is indeed a skilled software developer. Previously we have used Codility for that, but in my opinion, the information that it conveys is limited. You only see a very narrow window of the persons technical expertise and whats worse you are limiting them in terms of time. You want the person to perform to the best of his/her abilities and for that reason, you need to give a bit of leeway in terms of what time can they have to do the test and also, the format of the question. To that regard, we decided to reorder our interview test.
We looked at the set of applications that the candidate would work on in the future if we hired and identified the common themes in all of them. Majority of our applications are web based, responsive in nature and use maps extensively. We use persistence of some sort for a lot of our features and we test the living daylights out of our features. This being the core of our applications, we decided to get the applicant to some how demonstrate their competence with these technologies.
This is how one of our interview tests reads
As you can see, this is fairly simple test. We leave most of the implementation details up-to the applicant themselves and simply state our expectations of their submission. The most important detail however is that we send them an empty Git repository and expect one back in return. The reason ? We want to know the way the applicant thinks. And this is where the Git history comes in.
Take a simple Git repository and check its history using
[~:] $ git log
and we see something like the following:
Have a look at the above output.
The first thing to notice is the commit messages and how descriptive or otherwise they are. The first message reads “Ensured that the API is 7” … What API ? And what is 7 ? Version ? Build number ? The fact that you only see a short summary and no long/explanatory summary could suggest that the person is either erring on the side of brevity or is not bothered with explaining their changes in a succinct manner.
Next have a look at the time gap between commits. Usually, for the sample question above, we like to give the applicant anywhere about 3 to 7 days to work out the problem and send us back the solution. If we look at the difference in time between the second latest and the third latest commits. June 6, 2011 and then Nov 3, 2011. Why such a gap? You choose then the Nov 6 commit using
[~:] $ git show COMMIT_ID
and have a look at the changes.
Then you discuss those changes with the applicant. Why such a long gap between those commits? If the change set contains some algorithm changes, you ask about his knowledge of algorithms. Did he find them hard? What resources did he consult in order to arrive at this solution and how many algorithms did he try in order to arrive at this one? How did the candidate go about the asset generation pipeline?
Another aspect you definitely want to look at is how well tested the solution is. By well tested, I do not mean coverage. I mean actual tests that cover and ensure that your core business functionality is working as expected. Once again you should be to go through the Git log and have a look at the output using:
[~:] $ git log --stat
A simple example as shown above. You have two commits on May 6. You don’t want ten commits spaced out that change and alter the functionality and the one commit at the every end testing out that change. What you want is the test first, to map out what you are thinking the functionality should do, then the implementation as best as it should be, and then any alteration to the testing strategy to better optimise it. Some of my coworkers are very insistent on a TDD strategy while some, me included like it but do not insist upon it. But I do insist upon sensible tests that cover the functionality.
Then there is refactoring. How many times after a business feature and its associated test has been written, has the applicant gone back and tweaked his solution, and his test. Check the history of a file that you think has the important logic in it using
[~:] $ git log --stat PATH_TO_FILE
and that should show you something like:
That should show you very clearly how often a file is changed. The commits that reflect the notion of refactoring and you start having a conversation about the reasons behind it. Why the refactor ? Why that particular refactor ? What led to it and was there any reason why he didn’t think of that originally?
As you can see, from just examining the history of a project you can get a view of how the applicant has gone about developing, testing, and refactoring the solution. You can get an idea of his time management, his ability to enunciate his code in a commit message and his ability to sum up his changes in a succinct manner. And the sum of all this is how the applicant thinks, which is what all these ways of testing the applicant strive to figure out.
The Media and Developer team in REA Tech only use this for the initial screening. We still have the applicant come in and pair with someone very experienced on a core feature to see how that person is actually like to work with and how well or otherwise he can communicate his ideas when pairing. But you want to get to that point having had a fair understanding of how that person thinks and distributes his time. These insights are invaluable and contribute greatly to us finding out the best person for the job.