Contents

Approaching Take Home Coding Assignments

If you are preparing for your next role in the software engineering world, then you know that many companies have take-home coding challenges in their interview process. It is overwhelming because of the long list of requirements and sometimes ambiguous criteria for the candidate to justify if they manage to reach the technical feedback round.

In this blog post, I am sharing the process that has worked best for me and received positive feedback. It also helped me stand out from the rest of the candidates. I always opted for backend-related tasks even if I was interviewing for full-stack positions

Understanding the problem statement

Usually, the provided document has too much information. As a candidate, we can only wish for thoroughly detailed requirements. But in the real world, it isn’t possible, and things are vague. So as a developer, we must remove the noise and focus on the things which matter the most.

https://i.imgflip.com/1itoun.jpg
imgflip.com

I pick things out from the document and put them into two buckets. There could be more buckets based on the task, but I never needed a third bucket.

  1. Required
  2. Optional

By recognising the high-level requirements and placing them into two buckets, I now have the targets I need to achieve. The next step is whiteboarding or drawing a diagram of how things will work.

Sketch the moving parts

It is necessary to understand how things will work. Writing the code shouldn’t be on your mind right now, as that’s the easy part. I use the C4 model, sometimes random boxes & arrows between different services. Here the service means an imaginative class, a database or a message bus etc. The diagram is to understand the flow of the data and actions.

Tools I have used are:

Timebox!!!

https://i.imgflip.com/x9qhp.jpg
imgflip.com

It is critical to complete the above things in a fixed time, especially the required tasks. I make sure I discuss how I would implement the optional requirements in my documentation if I didn’t have a chance to implement them. Initially, I used to spend almost 4 hours conceiving the idea and then the remaining time coding. It wasn’t the best use of time because I could either try to be perfect or deliver a working code. I learned to balance this as I gave more interviews.

Setup

I hope you’ve decided on the programming language, framework, and things like MySQL or Postgres needed for your task. I have always made sure the project base has the below items:

  1. Git
  2. Test
  3. Linting & Logging
  4. README.md
  5. Environment variable (Optional)

Git

In most cases, changes are committed to a remote git server. Ensure you have the .gitignore file to prevent pushing unnecessary files. You can get a template from here.

Test

When you’re factoring the amount of time needed to complete the assignment, always include the time to write tests. I prefer adding unit tests because they don’t need external services, and I don’t have to maintain containers and fixtures.

Linting & Logging

In my code feedback rounds, the interviewer would highlight the importance of logging with appropriate information and linting. The goal is to write clean, extensible, efficient code for the requirement. But the unsaid requirement is that it should be easy to read and debug. So adding these can give you a bonus point. It also shows that you’re focusing on making it production ready.

README.md

I create this file at the start and write code snippets to run the project locally. Nothing more is written as I’m still developing the code.

Environment variable

I have always used environment variables to make things configurable, for example, the refresh interval rate, external database credentials etc.

Smaller Commits

It is wise to break your code changes into smaller commits and follow a commit style guide. You can read about conventional-commits for more information. It shows the interviewer how you approach writing code to solve the problem. Also, it’s easier to revert when I’ve messed things up 😅.

Raw code, Refactoring & Unit Tests - Repeat

Writing modular, extensible code from the get-go needs experience. Until you can get there, the best approach I found is to write the working code first. Then manually test this code with different input data. I try to catch any unintended bugs in the codebase.

The next step is to write test cases which must include happy path, failure and edge cases. I prefer the AAA pattern when writing the tests. You can read more here [1], [2].

Now the process of refactoring the code is started. I try to refactor the code and see how to use dependency injection so that I can mock the services and instances in my unit tests. Any configuration needed will be passed either into the constructor or function parameters instead of directly consuming the environment variables. I have not discussed patterns, inheritance etc., because content on them already exists. You can pick them as you work.

As most things are ready, I prepare my tests and mock the dependency for the method/class belonging to this test. The test coverage shows no signal of failure. I repeat this process as I try to complete the items from the required bucket.

Documentation

In the end, I complete the README.md, which includes the following things

  1. Pre-requisites
  2. How to run the code, tests
  3. Explain the project with visuals, if possible.

Bonus

If you plan to go beyond following things could also be done:

  1. CI/CD Pipeline on Github/ Gitlab or similar tooling
  2. Dockerize - Allowing developers to use images to run the project or tests.
  3. Deploying your project on a server in the case of API and netlify / vercel if it’s a frontend project.

Below are a few of my repositories where you can see the above in-action.