14 gotchas around coding challenges for Frontend Engineers
For two years I have been involved into our hiring process. I am checking code challenges and I am conducting technical interviews from Junior to Lead seniority. Here are 14 things I am looking at as a reviewer when assessing a candidates coding challenge and how a candidate can avoid mistakes.
I do not write this article to make it easier for candidates to pass our coding challenges and I will not go into detail on them. I will share my personal point of view which might not reflect other reviewers perspective. Some parts that I mention are most probably also applicable to backend engineers but I am focusing on frontend engineering as this is my domain.
1. Read the instructions carefully
My first tip might sound obvious but I urge every candidate to take the time and read the given instructions in detail. Making oneself aware of what is asked is crucial. Reading the instructions should give clarity and confidence to tackle the challenge. A head jump into coding is the first big mistake. If in doubt, I propose to follow my second tip.
2. Ask for clarification
We are all humans and it is not a weakness to ask for further clarification when something is unclear. In fact I am actually welcoming questions as it shows me that the candidate thinks before starting. This is also something crucial when working on the real product. It is better to align twice on the acceptance criteria than wasting time on the wrong thing.
The next point is something that candidates tend to forget. Think about the reviewer. Keep in mind that the reviewer most likely does not have a lot of time so the candidates should want to make their assessment as easy as possible. For this I suggest the following.
3. Work on a branch
If your coding challenge is provided using a git based version-control tool:
Do not commit directly into the main branch as this makes reviewing harder. Open a branch and create a pull request. This might sound obvious but you would be surprised how many candidates simply start working on the main branch. Even when applying for higher seniority roles.
4. Add meaningful commit messages
Assuming that git is used:
The commit history is also an indication of how structured a candidate works. Adding meaningful commit messages helps the reviewer to follow your thoughts and working progress. A lot of commits with messages like fix, try, another try, please work, … or equivalents does not paint a picture of professionalism.
5. Add code comments
I am also happy if the candidate adds some short (!) comments in the code that shows me why the candidate did certain things or why some things were left out. This helps assessing the candidates experience and way of thinking. This is especially helpful when the given time was too short for you to complete the tasks. Focus on finishing the actual task within the given time frame and use comments as a shortcut to show your intentions.
// TODO: add debounce logic to search input
// TODO: move to service worker for increased performance
// TODO: add test case also for condition ABC
// TODO: move into context to enable cross component access to state
// TODO: split into sub components
// TODO: move logic into shared utils function file
Clean code patterns
The next thing I am always looking at are clean code standards and code structure. (check out Robert C. Martin’s work on Clean Code) The code you write needs to be understood in the future to stay maintainable hence it is important to follow some patterns and conventions. Showing this in the coding challenge also gives me confidence that the candidate will apply this in the real code base.
Choose names for your functions and variables that make sense. Do not use random characters or abbreviations. Naming is hard and can take time which you might not have in a coding challenge but it is important that the reviewer understands what your intentions are and a good chosen name helps a lot.
Do not add multiple functions or functional components into a single file. Think about a good structure and split your logic. Also think about the folder tree. A good structure proves seniority and professionalism. For more I suggest to have a look at the single-responsibility principle.
Also code formatting is giving me a lot of insights about the candidate. Is the candidate sticking to what we propose in the bare bone structure of the coding challenge? This point is not as important as the other ones as in the real code base we are using a pretty strict linter. (ESLint) But a deviation here makes the code suspicious which leads to the next point.
Whatever naming, structure or formatting the candidate comes up with the most important thing is not the individual decision but an overall consistency. Whenever I find something unusual which appears suspicious to me I will surely question it in a following technical interview. This could be an indicator that the candidate copied code instead of writing it by herself/himself.
Another advantage of following the upper points is that the candidate can explain the handed in solution in the technical interview better as navigating and orientating is way easier for herself/himself.
Syntax & coding style
When looking at the code I am obviously also paying attention to the used syntax and coding style. Here are the points that are most important for me.
10. Keep it simple
The latest ECMAScript versions have added a lot of useful syntax which allows to write more logic with less code. But this also adds the risk for code to become unmaintainable. I have observed that especially junior and intermediate candidates try to proof their experience by writing complex solutions. My tip is to keep it simple. The more complex and nested the solution is the harder it is for oneself to explain it. This does not mean that you should avoid using new ECMAScript syntax but try to keep an eye on simplicity and avoid nesting conditions.
11. Do’s and Don’ts
12. Styling (CSS)
A big part of frontend engineering is around styling components. I am not in particular interested in the used CSS as our coding challenge is not CSS heavy. I am looking more into the how CSS was used. Did the candidate use inline styling, simple css classes, CSS Modules, styled components, SASS, JSS or something similar? If the candidate decided for simple css classes was BEM used? The most important part here is structure, reusability and (repeated the third time) consistency. I am also in favour of keeping it simple for the coding challenge.
In my opinion:
If the coding challenge did not explicitly ask you to extend on your styling skills this is something that could easily be discussed in the technical interview.
One of the topics that candidates tend to handle with low priority is testing. This is where the wheat separates from the chaff. (directly translated a german saying) I can tell that a candidate with a lot of experience is focusing on this topic while more junior developers see testing as a burden. When I am talking about testing I mean unit testing as this is what I would expect from a coding challenge. But I also have seen candidates adding E2E tests using Cypress. However I think the most important thing is not coverage but that the tests make sense.
See this example:
Once I had a candidate who was using a Redux store to handle data in a shared state. The candidate tested the redux store and its reducers by initialising the store with mock data and dispatching actions to invoke the reducer functions. However the candidate only tested that these reducers were called and did not fail but did not test what the reducers actually should do.
13. Write meaningful tests
So my tip here is to focus on meaningful tests instead of trying to reach 100% coverage. This is especially important when short in time. In my opinion it is more about quality than quantity which also applies to coding challenges. If you run out of time but you still have some test cases in mind add some TODO comments like explained above. I think that no one will doubt your ability to write the tests if the few you wrote are good.
14. Manual test
Test your solution manually if possible. Make sure it builds and that the server is running without issues. Also check if what you expect from your solution works when used in the browser. Do not rely on unit tests alone. That might sound ridiculous but I have seen solutions which instantly crashed or where filter and sorting didn’t work properly. A manual test has a high chance of revealing these issues before handing in a broken solution. In most cases these issues were a slip or oversight by the candidate which could be resolved in the technical interview but in some cases this led to the rejection of the candidate.
With increasing seniority also the importance of the mentioned points are increasing. While it is ok for Juniors to fail or ignore most of the mentioned points this would be a show stopper for a Senior or Lead position.
Keep in mind that the coding challenge is an entrance card for the next phase in the hiring process. Which means that even if you follow all my mentioned points it is just one factor in a variety of other factors for a successful hire.
While a good coding challenge does not guarantee you to be hired a bad one results in a higher chance of being rejected.
I really hope this gave you some insights and you feel better prepared for your next coding challenge. Thank you for reading!