Code Challenge Review — What Most Reviewers Prefer
Opinionated tips on how to make your code challenge submissions pleasant to review during the hiring process
Over the past couple of months, I have written and reviewed a ton of code. My Github contributions chart says that code reviews amount to 65%+ of my contributions in the past year. I agree with this because I recall deciding to partake in a lot of code reviews at the beginning of this year.
It is unsurprising that I eventually found myself volunteering to review the code submissions of android engineering candidates who would like to work with us. A decision which I would say turned out to be a really good one.
In this post, I intend to share some tips on how to increase the likelihood that a reviewer would find your code delightful to review. Most of what I will say are based on my experience reviewing the code submissions and would likely contain some biases, so do not see this as a fixed rule. Let us begin.
Have a seamless setup
A pet peeve of mine as a reviewer is having to jump through hoops to get someone else’s code to build and run successfully on my device. A reviewer’s first impression of a candidate’s codebase begins at this very first step.
In some cases, I would advise that only stable releases of libraries and tools should be used when writing the project. This way, you are sure that the chances of this step going bad would be low.
I should point out that experimental or unstable releases should only be used in a case where it is absolutely necessary. I would personally understand seeing the usage of experimental stuff in Jetpack Compose and Kotlin Coroutines.
Finally, the project structure should be familiar. It should be easy for anyone to know where to find dependency injection, view models, or UI classes. I also appreciate it greatly whenever the project is split into meaningful submodules that are linked through modular dependencies.
Write documentation
There should be a README
file in your project. Ideally, every project needs one. Even if you do not have any documentation to write in this file, I would still advise one to create it and then put the the description of the task in this file and then put a checkmark next to each objective of the task.
If there is an additional setup that needs to be done before the project is able to build successfully, this should be mentioned in the README
. For example, if you expect to read the value of aTHIRD_PARTY_LIBRARY_API_KEY
in a file called local_config.properties
, this should be mentioned in the README
file.
Other forms of documentation should also be present where necessary. For example, if a deprecation warning is intentionally suppressed, I expect to see a comment that explains why the recommended approach was ignored.
A lot has been written on writing code comments already, in order not to inflate this post more than necessary I’ll refer you to this post about the best practices for writing code comments.
Keep it simple, stupid
Trying to understand a complicated code snippet breaks a reviewer’s flow. There are already some established architectural patterns which software engineers are familiar with. Violating this principle, by introducing an unnecessary complexity, rather than breaking down the complex code into simpler steps doesn’t help anyone.
A common occurrence of a transgression to this principle is visible when one’s codebase has god classes. For example, having stuff like:abstract BaseActivity
, abstract BaseFragment
, abstract BaseViewModel
, etc, should be avoided.
The reason is that there’s an extra mental effort that is required to understand what happens in BaseFooBar
before I can continue with the class that inherits from it. A tip to avoid this would be to favour composition over inheritance when adding behaviour to your classes.
Showcase your knowledge of modern tools
Utilising modern stable programming tools is one of the best ways to prove that you know your beans. What better way does one have to impress a reviewer than to have the reviewer review a project that shows that they are up to date with the techosystem?
For instance, newer android projects should use the Gradle Kotlin DSL
+ buildSrc
rather than the Groovy DSL
to declare the gradle configurations. Also, extension functions should be used instead of Utility Classes.
Speaking of extension functions, knowledge of existing extension functions in the androidx
libraries is a huge plus. A final tip is that delegated properties like the View Binding delegates could be used to reduce boilerplate code.
Perform code quality checks
Before you submit your code for review, it is important to ensure that ALL lint errors are resolved. An easy way to ensure that there are no lint errors is to set the abortOnError
flag to true
in the lintOptions
configuration.
If you are able to ./gradlew clean build
your project without errors after this is configured then your project is lint/dust free. You could even go the extra mile of setting up detekt & ktlint to check your Kotlin files more thoroughly.
Finally, I cannot overstate how important it is to ensure that your code is properly formatted. As a rule of thumb, you could default to using the kotlin style guide provided by Google. If you have decided to use ktlint
, it comes with a ktlintFormat
task which you could use to quickly format the entire kotlin files in your project.
Write tests
Ideally, every project should have tests. There are differing opinions about this and I strongly feel that senior & mid-level engineers should have tests in their codebase.
What to test is another topic. A hint is to look at the objectives of the task and write test cases for these objectives. I have discovered that writing tests can make one to discover some unhandled edge case scenarios.
It feels quicker to write unit tests and leave out UI tests, however I would advise that some UI tests be present in the project.
If you decide to not include tests in the project, please delete the src/androidTest
& src/test
folders from your project. There’s no greater disappointment than expecting to see actual tests in those folders only to see the auto-generated ExampleInstrumentedTest
and ExampleUnitTest
classes.
These are not hard rules, coding challenges are usually written under some time pressure and I will understand if the entire codebase is not perfect.
The code submitted to a coding challenge is NOT the developer’s best code. It is their code that was done within the pressure of the hiring process. We could review the code, see if it works, see if the design matches our idea of the design and then decide based on that if they are any good. — Andy Davis
I hope that these tips provide some help that would nudge you towards writing code that is easier for reviewers to review. If you feel like there’s something I missed out, please let me know in the comments.
Bis später ✌🏽.