Disclaimer: This article is based solely on my personal interactions and experiences and those of my batchmates and seniors and in no way reflect official opinions of any company or organisation.
Coding interviews are not just about solving the question correctly. Interviewers are looking for a number of indicators other than good coding skills that make you suitable for the position. This article aims to list important points and explain their importance for technical interviews.
Introduction, Motivation and Objective
I sat for the recruiting season last year for summer internships at BITS Pilani. I gave interviews for Google, Goldman Sachs, Microsoft and Arcesium. I completed my 2-month internship at Arcesium in a software development role recently. I had a steep learning curve at Arcesium in terms of technological skills. But perhaps the most important thing that I learnt and that would stay with me throughout my career is how an idea is converted into software at an industrial scale and the importance of good coding practices.
As a candidate I was always daunted by the questions: Why is competitive programming so important when it comes to interviews? Why does being able to solve those algorithmic question in those 45–60 mins matter even after I have cleared the coding test? What it is that the interviewers are really looking for and why is it important?
I read a number of blogs on interviewing and attended seminars by recruiters at companies like Google and Facebook. Finally, working at Arcesium and interacting with senior employees is what helped me make sense of all the tips given to a candidate. This is my attempt to correlate what interviewers look for in a candidate with its relevance when working as a software developer.
Here is the list of some of the most important points one should keep in mind and the reasons as to why they are important:
A project life-cycle — Building your code.
A typical project/product lifecycle has multiple stages. These are ideation, prototyping, and iterations development, testing, bug-fixing and optimisations. Adaptation is important during this cycle as user requirements or ideas or constraints can change along the way.
Similarly, in an interview, one is not expected to come up with the most optimal solution instantly. A good cycle to follow would be to first, ideate, come up with an intuitive solution without worrying about implementation and optimisations. After this, build a prototype — think about how you will implement the solution — what data structures you can use and what kind of algorithms can you leverage. Next, start writing the code and enter into the iterations. As you write code, you will realise there are edge cases you need to handle, there might be some aspect of the problem that you did not think about initially etc. Go back to the drawing board and inculcate everything you can think of. At this point, you should also realise the time complexity of your solution and think about optimisations to reduce time and space complexity. Finally, running test cases on the algorithm you have built will further help you ensure that the algorithm is correct and robust. In the middle of this process, if you realise that maybe you could have taken an entirely different path, that is fine as well. Explain this to your interviewer and change your course.
Understanding the needs and constraints of the project — Asking clarifications for ambiguous problems.
As a developer, one needs to clearly understand these requirements and constraints of a project. This can depend on the purpose, the resources available, the intended users among other things. When an idea is first described, it may be vague. It is up to you to ask relevant questions, before starting to implement the solution.
Your interviewer wants to know whether you have the knack for identifying gaps in the problem presented to you. Often, unlike coding tests, interview questions are intentionally ambiguous. Never jump to solving them. Ask your interviewers to clarify any gaps you see. If they leave it up to you to fill in the blanks, clearly state and explain your assumptions. Examples of some questions one can ask are:
- Does the input fit in memory?
- What do I return in case of NULL input, should I throw an error/exception or return some default value, what to do with other edge cases (if you can think of any at the time)?
- Are there repeating elements or are elements unique, can there be negative elements?
- Ask for some specific example, or if the interviewer has given an example, try tweaking it a bit and then asking what kind of output is expected for a different test case.
- Is there any constraint on buffer space or the number of passes/time complexity etc? (This may not be answered by the interviewer directly, but if they do, you will know your target).
If you can’t see any gaps (or there are no gaps), the least you can do is to repeat the question in your own words and confirm with the interviewer whether you understood all aspects correctly. This can often lead you to identify some aspect or gap that you missed initially.
Clearly conveying ideas and ability to listen — Talking to your interviewer and being receptive to feedback.
When working in a team being able to express yourself to your colleagues or superiors is very important. You may have brilliant ideas and immense knowledge but if you can’t convey them, your teammates/managers might never realise your true potential. One also needs to be receptive to feedback.
This is true, and even more so, during the interview process. You have roughly 45–60 mins to make a positive impression on your interviewer and staying silent won’t really help. At each step, clearly explain your thought process and the reasons for various design decisions you are making. If you think better silently remember to summarise everything you have thought after every couple of minutes so that the interviewer keeps up with you. Take a test case to convey your idea. Someone who is able to explain their solution (even if they don’t reach the best solution) may be preferred over someone who coded the perfect solution but is unable to explain how and why it works or how they reached it. They also want to see if you listened to the question properly and considered all aspects that they mentioned. Often, during the discussion of the problem, they may throw at you subtle hints or nudge you in the correct direction. They may also give suggestions or put up questions. Don’t just disregard those, instead try to address their concerns while you solve the problem. Even if you decide not to use their suggestion, explain why you think going another way is a better option.
Knowledge and Analytical Skills — Knowing what to use and how it will behave.
“You are paid not for your ability to write correct syntax, but for your ability to understand the semantics of it” — this is what my manager told me when I asked her why do firms put so many efforts into hiring people when anyone can learn to code in Java in a matter of few weeks. As an engineer, you need to know your tools and as a software developer, you need to know your data structures inside out.
Interviewers are looking for the proper usage of data structures in problems.
- Are you using a stack or queue appropriately or do you always keep using an array?
- Can you leverage heaps, maps and sets appropriately?
- Are you aware of the time complexities of basic operations like insert, delete and lookup in these data structures?
- Can you model a problem as a graph or a tree when needed? Are you aware of complex data structures like disjoint sets, segment trees or tries.
It is very important that you learn to identify the best data structure for a particular problem. Often one question can be solved with different data structures. The pros and cons of using the different data structures is a great discussion you can have with your interviewer. At the same time, forcing a problem into a (fancy) data structure it does not belong to can leave a negative impression.
Your interviewer is also looking for your ability to understand the semantics of the code. You don’t just need to flawless code, you need to analyse the behaviour of that code. Time and Space complexity are the first steps. Always mention them, and how you derived them, even if the interviewer does not specifically ask for it. Analysing your solution, poking holes in it, identifying gaps and trying to fill them is an important indicator of the depth of your understanding in DSA interviews.
Understanding tradeoffs and scalability — Most optimal solution is not always the priority.
The best solution is not always the fastest one. One has to consider multiple other factors or tradeoffs. Designing software that will be used by 100 students versus designing one that will be used potentially by millions of people completely changes the landscape you are on. This is why some of the most common follow up questions on algorithm design are based on scalability issues and tradeoffs. “What is the goal of optimisation — time, space or something else” or “How will you design the same algorithm if the input did not fit in memory?” or “What components do you need to modify if the number of users for an application increases?”
An interviewer wants to know whether you understand these tradeoffs. For eg — reducing time complexity can lead to increased space complexity. Pointing out and discussing these tradeoffs is a good practice. Sometimes, they may be looking for specific optimisations like those for big inputs or for space rather than speed. Another possibility is that you know a more optimal solution, but it is very complicated to translate it into code within a short time. That’s fine too, tell this to your interviewer and go for coding a less complex solution. They also want to know if you can model the real world into your solutions and take appropriate design decisions. Can you identify potential issues while scaling? Can you come up with intuitions to address those issues, if not perfect solutions to solve them? Can you think of algorithm design from perspectives other than just time and space complexity, such as online and offline algorithms or concurrency issues? Read up a bit in advance about such potential questions. Make it a habit of asking such questions to yourself once you have solved the problem and try to look for its solution.
Hands-on experience — Being comfortable with and knowledgeable about at least one programming language.
When working at a firm, you will have to get your hands dirty. For the first time, I would have written 1000+ lines of code roughly every 3–4 weeks. And it is not about the language or the framework you are working with that is important, it is having the agility to write a good amount of code that matters.
Thus, being comfortable in writing code in at least one programming language is a must. You have to be comfortable with the syntax without the benefits of having an IDE or autocomplete prompts. Pseudocode is NOT good enough. You need to write working code with correct syntax. This shows that you are actually familiar with the language and can use it comfortably without having to look up every small thing about it. It shows that you have, in the past, coded enough in the language and that you cross the threshold of the required coding aptitude. It is also good to know some of the key conceptual questions about the language you are planning to use in your interview. Stuff like “How does garbage collection happen in this language?” or “How do the heap and stack memories work” or “what is the underlying implementation of some data structure or algorithm in the standard library”. These questions don’t necessarily show up. But if they do, having a good understanding of such conceptual questions can go a long way in showing that your knowledge is not limited to coding DS&A.
Diversity in problems and tech stack — CS foundations and Approach.
When working in the industry, the technologies you will use will be different from what you use in college. Thus companies (especially when hiring interns or entry-level grads) don’t look for the perfect match in terms of tech stack. I used languages and frameworks that were completely new to me in my project. When working, you always have to keep picking up new technologies, frameworks or intricacies of technologies you are currently using. Often, the problems you face will not have a direct solution (if they did, you wouldn’t be trying to solve them). Thus it is your approach and foundation that matters.
Interviewers are thus looking for indicators that you are smart at solving new problems. You have to be prepared (mentally) to come across problems you have never seen before or have no clue on how to start. They also want to check your core concepts of computer science. Things like DSA, database concepts and OOP concepts. The latter two may not be necessarily asked, but it's good to be brushed up on the basics. The idea behind these questions is: “if you have good core concepts, picking up a new language or framework would just require some effort”.
Good coding practices — Writing clean, readable and modular code.
Here is the difference between coding in college projects and coding in the industry: someone else is going to read, test, review and maintain your code. Thus, there are extensive review processes to ensure that your code meets high standards. Modularisation and Reusability are probably the most important characteristics of good code. Some of the reasons behind this are: allowing someone reviewing/testing your code understand the meat of your implementation without having to understand the internal working of some sub-task, allowing other developers to reuse some methods you might have written for an unrelated task, ease of testing etc.
While most of these practices can be learnt, having them at the interview stage shows your meticulousness. Many companies like google also evaluate you for your coding style. Some of the “good coding practices” include:
- Proper variable and function names: The names you use should represent the purpose of the variable. Avoid using names like myvar, foo(), x etc.
- Coding style: write with a consistent coding style (eg: casing — either using ‘_’ or camel casing). Proper indentation throughout the code.
- Comments: You should not have to write comments to explain every line. Comments should explain why the code is in a particular way rather than what it is doing and how.
- Writing modular code: writing reusable functions for tasks that are repetitive and abstracting unnecessary details. You should simultaneously discuss with your interviewer how these functions are expected to work. Sometimes, they may ask you to actually skip the implementation of trivial functions like initialisations, finding max/min in an array etc. And this will also save you time and allow you to focus on more important aspects of the implementation.
Dev testing and potential problems — Dry runs with examples and edge cases.
For any project/product to go into production, an extensive amount of testing is required. Most companies (including mine) have multiple stages of testing and reviews. As a developer, one must also understand the possible use cases and be able to identify when the program can fail. Robustness is the most important feature of a real-world solution.
This is why the interviewers are looking for indicators of your ability to test your own code. Once you have implemented an algorithm, spend a few minutes on running a test case. You should select a sufficiently complex test case and not test cases that are very small and/or trivial or are special cases (For eg — if it’s not mentioned that the tree is a BST, you shouldn’t take a BST as an example). Dry runs on a test case can also help you to identify potential bugs in the correctness of your solution. This is also when you can think about more edge cases. An interviewer wants to test whether you can identify the gaps in your solution. Edge cases are often tricky and can be missed. So, it is important that you practise identifying edge cases in problems during your preparation and do the same in the interview. If you can point out an edge case that the interviewer themselves did not think of you will surely get some brownie points.
Time management — Speed and efficiency
Time is money, in work and interviews. If your interviewer plans to ask you 2 questions and you spend the whole one hour solving just one, it may not be very good. Roughly, one should spend 20–25 mins on one question. This time should be properly divided into time for asking questions, ideating, implementing and optimising your solution. (Some questions ARE harder and in that case, the time constraints can change). Time management is also very important, you don’t want to spend too much time on the brute force algorithm if you know you can do better. You also don’t want to use up your entire time in simply ideating and not leaving any time to code the implementation. Roughly you can divide your time as follows:
- 2–3 mins — discussing the question and asking for clarifications
- 4–5 mins — ideating, talking about your intuitions and a simple brute force solution.
- 6–8 mins — optimising, identifying edge cases and coming up with a final algorithm
- 4–5 mins — coding your solution
- 4–5 mins — dry run of the test case, bug fixes etc.
Independence — Being confident about your solution.
Even as an intern, I was given a fair amount of independence in working. I was not expected to ask about every detail of the implementation once I had understood what had to be done.
To evaluate this aspect, the interviewer is looking for the following indicators: once you have discussed a solution, can you implement it by yourself without looking for validation at each step? During the discussion of the solution, are you confident about what you think would work and can you justify it? How many hints do you need to reach the solution expected, could you do it on your own or did you take up a lot of help? Can you drive and lead the technical discussion without too many inputs?
Who are you — Behavioural questions, attitude and personality beyond coding
The person who is interviewing you is probably looking at you from the perspective of how you would fit in while working with/under them or their colleagues.
One may think that behavioural or personality questions are only asked in HR interviews but that’s not true. One of the worst questions I faced in an interview was “Why do you use C++ for competitive programming, instead of say, Java in which you are also proficient enough?”. Knowing ‘why’ you do certain things in a certain way indicates competence. Technical interviews often start with ice-breaker questions like “tell me about yourself” or “what is the most interesting project you worked on and why”. Such questions may not have a direct impact on your evaluation, but they are a great way to show your interviewer that you have more potential than just writing code. So it is important to rehearse them as they leave a lasting first impression.
- Go through the book ‘Cracking the Coding Interview’. It has some amazing content that you should look at both while preparing and in the days leading to interviews. I cannot stress enough on the importance of this, go through it and you will know why I am emphasising so much on it.
- Avoiding hassle in virtual interviews — if you are given access to a google doc beforehand, you may want to switch off spell check, auto-correct and auto-capitalisation from the preferences so that you are not troubled with the idiosyncrasies of coding in a doc.
- Brush up anything and everything you have mentioned on your resumes.
- Do a few mock interviews with friends or seniors because this will help to reduce the anxiety in actual interviews and help you practise communication.
- Interviewers generally allow you to ask some questions at the end, don’t get intimidated by this. In fact, this is a great time to know more about the company, people work culture etc. So ask!
- While preparing for technical interviews, do not forget about the HR/behavioural rounds. Read up interview experiences and be prepared with some talking points.
- Read up a bit about the company, you don’t want to be clueless if you are asked questions like “Why do you want to work with us?” or “Do you know what our company does?”.
- Don’t lose hope, give your best and keep trying :)
References and Further Reading:
- Cracking the Coding Interview. Link
- What no-one tells about interviews(why leetcode doesn’t work). Link
- How to work at google — an example interview. Link
- Six things you absolutely need to do when interviewing. Link
- Coding standards and Guidelines. Link
- Tips to crack interviews at Big companies. Link
- Google Solve.Code workshop 2020.
- A session with a FB recruiter and intern turned data scientist organised by Scholarship Track. Link
Original Post: tiny.cc/beyond-coding