This article was written in collaboration with interview coach Suman Bukka. A former software development manager with Amazon, Suman has interviewed 500+ engineers over the course of his career. He now works as a senior engineering manager in the connected car space.
Coding interview questions are intentionally ambiguous and highly technical. Interviewers at companies like Amazon, Facebook, and Google use them to find out if you can break down a problem and find its optimal solution.
That’s why we’ve put together a minute-by-minute breakdown of how to answer one of these questions, from start to finish.
Consider this your complete guide on answering coding interview questions. Here you’ll find an approach that will help you ace your interview as a software engineer, engineering manager, data scientist, or another technical candidate.
- Coding interview framework
- Example coding interview answer
- Good vs. great technical candidates
- Coding interview preparation
Click here to practice coding interviews 1-on-1 with ex-FAANG interviewers
1. Coding interview framework
To learn how to answer coding interview questions, you must first be able to approach them systematically. You might solve a coding question in different ways, but at the end of the day, you need an approach that will consistently:
- Show your interviewer that you have the knowledge they need
- Break the problem down into manageable steps
With that in mind, one of our favorite approaches is summarized in the following video from Amazon:
The approach shown in the video above can be boiled down into 4 main steps:
- Clarify
- Plan
- Implement
- Test & optimize
Next, we’ll dig into each of these steps in more detail, with a minute-by-minute interview flow, provided to us by Suman B. Let's get started!
1.1 Clarify (minutes 0-10)
Don’t jump straight into the question without consulting your interviewer. Instead, start by asking questions to remove any ambiguity and to explore the edges of the problem.
This is a good time to set up a dialogue with your interviewer. They are not just looking for a candidate who can solve a problem, but one who can work effectively in a team of other engineers.
Let’s jump into how this will look during the interview.
Minutes 0-3: Understand the question
If the question has been written down for you, take the time to read it thoroughly at least twice, to be sure that you’ve picked up on all the details. Repeat the question back to the interviewer in your own words, so that they can flag anything that you may have initially misunderstood.
Minutes 3-8: Ask clarifying questions
Once you’re sure that you understand the basic question, clarify the unwritten details. For example, ask for constraints (e.g. 0<= N < 1000), consider edge cases, identify corner cases, specify what language you’ll be coding in, etc.
Minutes 8-10: Specify assumptions
Finally, before starting work on the solution, consider any assumptions you’re making (e.g. input format, range, sorted or unsorted list, etc). Specify those to the interviewer, so that they can tell you if that is a correct assumption to make, given the problem.
1.2 Plan (minutes 10-20)
Now that you have a complete understanding of the coding question, it’s time to start making your plan. Here is where you can discuss potential approaches with the interviewer, pick the one that is the most appropriate, and lay out the high level steps to get there.
Let’s take a look at how this will play out in the interview:
Minutes 10-15: Find a solution
Take five minutes to think through a solution to the problem. It does not need to be optimal at this stage. Map out your solution on the whiteboard or its virtual equivalent, making sure that what you add is comprehensible to both you and the interviewer. The goal is to find any solution (at least brute-force) and then find improvements. Keep walking through your steps out loud so that the interviewer can guide you.
Minutes 15-20: Explain your solution
Before you implement your plan, make sure that you’ve brought your interviewer up to speed. If you’ve identified multiple approaches to the problem, go over each and explain why you’ve chosen the one you decide to move forward with. Ensure that the interviewer is aligned with your solution before you start coding, in order to save time down the road and to allow the interviewer to capture the right data points during your coding.
1.3 Implement (minutes 20-35)
Now it’s time for the main event. Write legible, clean code rather than pseudocode, and comment out loud on what you’re doing. Alternatively, if you have a hard time talking and writing, you can spend a few minutes coding quietly, then stop periodically to explain what you’ve done.
Here’s how much time you should spend on these steps:
Minutes 20-25: Optimize the solution
Once you’ve talked through your solution with the interviewer, optimize it. Consider any points you may have missed when you first thought of the solution, and what you can do to make it better. Explain your reasoning thoroughly and keep an eye out for the cues of the interviewer, which will let you know whether or not you’re on the right track. You can prompt them by asking, “how does that sound?” before moving on to coding.
Minutes 25-35: Write the code
Now, write that code! Explain what you’re doing, and make an effort to write clearly—don’t use shorthand variables. Include descriptive variable names, structure the code well, consider boundary conditions or empty inputs, etc. Make your code modular and eliminate duplicate code. If you realize you’ve forgotten an important function, simply go back and insert it, while clarifying what you’re doing out loud.
1.4 Test and optimize (minutes 35-50)
Once you have your code on the board, you’ve got to take the time to run through and test it, then optimize it given what you’ve found in testing. Start by testing with a simple example, then try breaking your code with edge and corner cases.
Don’t forget to calculate the time and space complexity of your code, and discuss how you can possibly improve it. If you find any better solutions while testing and evaluating your code’s complexity, ask the interviewer if they’d like you to implement it.
Here’s how that will play out:
Minutes 35-40: Test run your code
When testing your code, run it through multiple cases, starting with the basic use case, moving into a more complex case, and finally test for failure and edge cases. Consider anything that might break your code, and what you can do to address it [e.g. test cases like asserrEquals(findMax(10,20), 20)].
Minutes 40-50: Optimize your code
Finally, work out the time and space complexity of your code. Explain it in simple terms to your interviewer, and use it as a jumping off point to consider ways you can optimize your code. If time permits, write out the optimal code and discuss it.
Minutes 50-60: Q & A
These last few minutes of the interview are a good time to ask any questions you might have about the company and what your experience would be like working there. The interviewer may have additional questions for you as well. If the interviewer has clearly moved on from the coding problem, consider it finished and do not try to rehash any of its finer points.
Now that you’ve seen a breakdown of a coding interview flow, let’s take a look at a full example answer.
2. Example coding interview answer
To illustrate the framework discussed above, we’ve laid out an example answer to a real coding question that was asked in a Facebook software engineer interview, according to data from Glassdoor.
Try this question:
"Find out if two given strings are anagrams."
Coding sample answer:
Step 1: Clarify
Understand the question ↑
Candidate: “Okay great. So the problem requires two strings to be compared to establish whether they are anagrams, right?”
Interviewer: “That’s right.”
Ask clarifying questions ↑
Candidate: “May I ask a few clarifying questions?”
Interviewer: “Sure, go ahead.”
Candidate: “I understand an anagram as being two words made up of exactly the same characters, but in a different order, correct?”
Interviewer: “Yes, that's correct. If you can make one of the words by rearranging the order of characters in the other, they are anagrams.”
Candidate: “Can we assume that case does not matter? And if the two strings are exactly the same, do we consider those anagrams?”
Interviewer: “Yes, it can be case insensitive, and the same word can be considered an anagram.”
Candidate: “Great, thanks. I'm just thinking about what else could be relevant to know...”
Interviewer: “No problem, take some time.”
Candidate: “Oh—one more edge case: are two empty or null strings considered anagrams?”
Interviewer: “For the purposes of this question, yes they can be considered anagrams.”
Specify assumptions ↑
Candidate: “Okay. One last question, can I assume that there will be no whitespace or punctuation in either string?”
Interviewer: “Yes, you can make that assumption.”
Step 2: Plan
Find a solution ↑
Candidate: “Okay, so I can think of one way off the top of my head to solve this.”
Interviewer: “Let's go ahead and walk through it.”
Candidate: “I'm thinking that since the characters are the same in each string, but the order is not, we could sort both strings and then compare them to see if they are equal.”
Explain your solution ↑
Interviewer: “Cool, sounds like a quick win. What would the time complexity of that approach be?”
Candidate: “Hmm, so for the compare part, it would be O(n) as we need to run through each index of the strings. For the sort part, if we assume a fast sort is implemented, it would be O(nlogn). So in total O(nlogn) time.”
Interviewer: “Sounds about right. That is a quick win programmatically, but is there another way to get better time complexity?”
Candidate: “Well, since the most significant part of the time comes from the sorting part, we'd need to find a solution that eliminates that part.”
Interviewer: “Sounds reasonable.”
Candidate: “So I'm thinking that I can create a kind of ‘scoreboard’, where I have a list of all possible characters, and keep count of the number of times a particular character occurs in each string. Something like this, where string1 is ‘note’ and string2 is ‘tone.'”
Candidate: “Then, I just need to check if the score of each character is the same for each string. The scoreboard can be implemented as an array, with the indices of the array representing each possible character, and the value at each index the difference between that character's count in each string. Although, in this solution, I’m assuming that only the characters in the set ‘A-Z and a-z’ are used in the words. Is that reasonable?”
Interviewer: “Okay, interesting. Yes, let's assume the character set is limited. What is the time complexity now?”
Candidate: “Well, we can loop through both strings once to add to the character score on their scoreboards. So it is O(n) to loop through the strings, and constant time to loop through the scoreboards. The constant time will dominate for strings less than the length of the scoreboard, but for longer strings it will be O(n) dominated.”
Interviewer: “Okay. Do you want to code it up now, and see how it works?”
Candidate: “Sure!”
Step 3: Implement
Optimize the solution ↑
Candidate: “Looking at the solution again, I think I can optimize the scoreboards a little.”
Interviewer: “What improvement do you see there?”
Candidate: “Well, we can combine the two scoreboards into one. For string1 we can add 1 to the score, and for string2, we can add -1 to the score. That way, it's just one loop through the strings, then one loop through the scoreboard array, to see if the score is 0 for each character. A 0 score for all the characters means that the strings are the same. So we save making a scoreboard array for each of the strings by combining them.”
Interviewer: “Sounds good.”
Write the code ↑
Candidate: “Okay, I'm going to implement this in Node.js flavor JavaScript. I'm going to start with a function declaration and some check and edge case handlers:”
Interviewer: “Okay.”
Candidate: “I'm going to create the array for the scoreboard and initialize all the values to 0.”
Candidate: “Now I'm going to loop through the strings, and add or subtract a score for the corresponding character in the scoreboard. To get the correct index to use, I'll get the character code for the current character in the loop. The codes for alphabetical characters start at some non-zero number, I forgot what number exactly, but we'll need to subtract this starting code number so that our character codes translate to a zero-based index.”
Interviewer: “Great, let's see what that looks like.”
Candidate: “I'm just going to look up what the JavaScript function is for getting a character code, it's something like ‘charCode()’.”
Interviewer: “‘charCodeAt()’, I think.”
Candidate: “Yeah, thanks. Okay, here is the code to loop through the strings and increment or decrement the score for a particular character:”
Candidate: “Since I can't remember the character code that ‘a’ starts at, I'm just getting it at runtime and storing it in the constant ‘charOffset’.”
Interviewer: “Good plan.”
Candidate: “Okay, now I just need to check that all the values in the scoreboard are 0. I guess there are a few ways to do this. One is to use a for loop to check each value. Another would be to sum all the elements using the array reduce function and check that the sum is 0. Another would be to use the array find method to find any non-zero values.”
Interviewer: “Yeah, that's a few options. Which are you going for?”
Candidate: “I'm going with the for loop option. It has a slight advantage in that we can return early if a non-zero element is found.”
Interviewer: “Cool. If that's the full code, let's run some test cases.”
Step 4: Test & optimize
Test run your code ↑
Candidate: “Great, let me add some test code.”
Interviewer: “Looks good. What's the output?”
Candidate: “Here it is:”
Interviewer: “Fantastic! Earlier, we made the assumption that the character set was limited. What would the implications be if that were not the case? Let's say all Unicode characters are allowed.”
Optimize your code ↑
Candidate: “All of Unicode is very large, in the region of 150 000 characters I think. That would make the scoreboard array pretty big. It would negatively affect the space complexity of our solution, because it requires a lot of constant space. It would also increase the runtime, as the whole scoreboard array would need to be checked, even though it's unlikely any strings would be anywhere close to the size of the scoreboard array.”
Interviewer: “Yeah, it would bog this down substantially. Is there an optimization for this solution that could mitigate those issues?”
Candidate: “We'd need a way to cut down the size of the scoreboard array, since it will be so sparsely populated with scores. Perhaps if we tried replacing it with a hashmap?”
Interviewer: “Sounds interesting. Can you explain more?”
Candidate: “With a hashmap, we would only need to store scores against characters that actually appear in the strings. The characters found can be the keys, and the score can be the value.”
Interviewer: “Great. Will that change the time complexity?”
Candidate: “Hashmaps are O(1) for lookup, insert and update operations, so it should be on par with the array solution.”
Interviewer: “Great. Can you code the changes in?”
Candidate: “Sure! I'm going to replace the array initialization with an empty object literal, which will serve as the hashmap. We can also remove the ‘charOffset’ constant, as our keys can now be the characters themselves.”
Candidate: “Then I'll need to replace the inside of the for loop to increment or decrement the key value. I'm first going to add a helper function for the cases where the map does not yet have the key, and it needs to be initialized:”
Candidate: “Now I can call that from inside the for loop.”
Candidate: “Then I can update the scoreboard check code. This will need the for loop to change to checking each key in the scoreboard hashmap:”
Q&A ↑
Interviewer: “What's the ‘hasOwnProperty’ line for?”
Candidate: “That's so keys from the default, or base object, are not included in the count check.”
Interviewer: “Good. Ready to test it again?”
Candidate: “Yeah! Let me run it quickly. Okay, here's the output:”
Interviewer: “Looks good! I think we can move on from this problem.”
Candidate: “Great, thanks!”
3. Good versus great technical candidates
In order to make the cut when interviewing at a company like Google, Facebook, or Amazon, you have to distinguish yourself from other candidates. Giving a good answer won’t be enough to get an offer. You’ll need to give a great answer if you want to make an impact.
So here are some details that make the difference between an interview that is just ok, and one that will impress your interviewer:
- Completely answers the coding questions, but doesn’t interact with the interviewer
- Interacts with their interviewer, but struggles to take hints or change direction when prompted to do so
- Is able to finish the coding problem, but stumbled through their behavioral questions at the start of the interview
- Gets stuck once or twice during the interview and struggles quietly until they are able to move past it
- Offers a complete solution that is difficult to follow
- Comes up with a workable solution after coming to quick conclusions that they haven't verified with the interviewer
- Follows one approach that works, but neglects to examine its tradeoffs or other possible approaches
- Tests the code after being prompted by the interviewer to do so
- Finishes and tests the code by the end of the session, but does not leave time to consider space and time complexity
A “great” technical candidate:
- Is able to change direction and dive deeper on specific aspects when asked
- Has prepared responses to common behavioral questions and can transition smoothly into the coding portion
- Is able to talk through the problem when they get stuck, attack it from multiple angles, and take hints from their interviewer
- Points out the common pitfalls of the programming language they’ve chosen
- Offers a complete solution that is easy to follow, with clearly defined variables and space for corrections
- Considers multiple approaches to the problem and clearly explains why the one they choose is the most efficient
- Works steadily and methodically, only coming to conclusions after having thought and worked through certain aspects
- Proactively tests the code and identifies bugs before the interviewer points them out
- Examines the space and time complexity of the code, offering to optimize certain aspects where applicable
Ultimately, being a great candidate boils down to having the right mix of technical knowledge and communication skills to both work out the problem and dialogue with the interviewer. For extra tips on coding interviews, take a look at our list of 21 coding tips from ex-interviewers.
So you’ll need to prepare for your interview by brushing up on technical concepts and soft skills like communication. We’ve got a preparation plan to help you do that in our next section.
4. Coding interview preparation
As you can see from the information above, there is a lot of ground to cover when it comes to coding interview preparation. So, it’s best to take a systematic approach to make the most of your practice time. We recommend the two steps below.
4.1 Practice with coding questions
Before you start practicing interviews, you’ll want to make sure you have a strong understanding of the relevant algorithms and data structures. Once you’re confident in all of these, practice your skills by working through lots of coding problems.
We recommend using our coding interview prep article as your one-stop-shop to guide your prep process. It has a 7-step preparation plan and links to the best resources.
If you want to skip straight to solving questions, you can get started with our coding interview examples article which has links to high quality answers to each problem and is broken down by coding language.
One of the main challenges of coding interviews is that you have to communicate what you are doing as you are doing it. Having to think, code, and communicate your thoughts to the interviewer all at the same time is not easy.
With that in mind, don't let the first interview you do be the real thing. Instead, we highly recommend getting some mock interviews under your belt.
4.2 Practice with peers
If you have friends or peers who can do coding mock interviews with you, that's an option worth trying. It’s free, but be warned, you may come up against the following problems:
- It’s hard to know if the feedback you get is accurate
- They’re unlikely to have insider knowledge of interviews at your target company
- On peer platforms, people often waste your time by not showing up
For those reasons, many candidates skip peer mock interviews and go straight to mock interviews with an expert.
4.3 Practice with experienced coding interviewers
In our experience, practicing real coding interviews with experts who can give you company-specific feedback makes a huge difference.
Find a coding interview coach so you can:
- Test yourself under real interview conditions
- Get accurate feedback from a real expert
- Build your confidence
- Get company-specific insights
- Save time by focusing your preparation
Mocks are also extremely useful for the other types of interview rounds you’ll be facing, such as system design and behavioral.
Landing a job at a big tech company often results in a $50,000 per year or more increase in total compensation. In our experience, three or four coaching sessions worth ~$500 make a significant difference in your ability to land the job. That’s an ROI of 100x!