How To Ace the Coding Interview, by an Ex-Facebook Interviewer
Land the software engineering job of your dreams
Last year, I spent countless hours interviewing engineering candidates for positions at Facebook.
Having now been on both sides of the interview process, I’d like to help you.
Maybe you’re a college student looking for your first software engineering internship. Maybe you’re already a software engineer looking to jump to a new company.
Or maybe you’re none of the above and are trying to break into the software engineering world from a completely different industry.
This post highlights the top lessons I learned during my time as a software engineering interviewer at Facebook.
I hope they will provide some enlightenment for a process that is frustrating for so many people.
Coding interviews are typically 45-minute long conversations meant to test your knowledge of data structures and algorithms.
Intern candidates at most companies will only be required to do coding interviews. Senior candidates, however, will likely be required to do two to three coding interviews, one to two system design interviews, and a behavioral interview.
This article solely covers advice for the coding interview.
I was recently asked, “What should I do if I don’t know how to approach the problem right off the bat?”
My response: “Well, you won’t know what to do if it’s a good interview question. ”
If you did, what would be the point? The goal of a coding interview is to get a grasp of your coding abilities. At Facebook, we referred to this as signal.
Our goal as the interviewer is always to extract as much signal as possible. This means if we detect that you’ve heard the problem before, it’s our job to switch questions.
We want to know how you handle adversity.
If you happen to recite a solution that you memorized from “Cracking the Coding interview,” we’ve learned nothing about your problem-solving skills.
Coding Interview Best Practices
The absolute best candidates lead interviews. They require very little guidance from the interviewer. They’re the ones who drive the conversation, not the interviewer.
These candidates will usually go through these steps by themselves with little to no prompting from the interviewer:
- Ask clarifying questions.
- Analyze various solutions and tradeoffs.
- Plan solution with pseudocode.
- Implement solution.
Leading ≠ Rushing
Leading doesn’t mean that you rush into writing code. In fact, starting to write code within the first five minutes of an interview can often be a very bad sign.
The first step in leading a great interview is to ask great clarifying questions.
Ask great clarifying questions
Before you can start to tackle the problem, you need to understand the problem.
Asking a few clarifying questions can go a long way in setting you up for success.
Here are some great clarifying questions to ask:
- Should this be done be in place? (No additional memory)
- Can we make any assumptions about the input?
- Do we care more about performance or saving memory?
This will allow you to focus on what’s important and ignore the rest. Knowing what to ignore is equally as important as knowing what to focus on.
Don’t make assumptions
Too often, candidates make assumptions about the problem (i.e., all integers are positive, arrays are not empty, all input is safe) … big red flag.
Never assume that the conditions of the problem are aligned as is convenient for you to solve the problem. Instead, just ask.
“Are the integers passed into this problem all positive?”
It’s that simple. If yes, then great. You don’t have to check for that. If not, then a simple if-statement is all you need to make your code safe.
Often, asking these questions can provide you great hints as to which direction to move in.
Talk about tradeoffs
We interviewers love to see when candidates discuss various approaches to a problem.
It shows that you understand that there are always multiple approaches to a problem but, more importantly, pressures the interviewer into giving you a hint without you explicitly asking for it. Booyah!
We can’t just give you the right answer, but if you propose two options, A and B, and ask, “Which approach do you think I should take?” we’ll sure as hell pick the one that’s closer to the answer we want to see.
Plan your solution with pseudocode
Usually, during these interviews, you’ll be working off a whiteboard. This means you can’t easily insert statements wherever you want. You have to know what you’re going to do before writing code.
Take a deep breath and plan out your code. It could be pseudocode, or it could be a simple drawing, but make sure you know what data structures you’ll be using and what variables you’ll need to keep track of.
I’m sure that you don’t want your final solution to look something like this:
Implement your solution
This is the step that everyone gets hung up on but really shouldn’t.
Implementing your solution should be the easy part. You’ve asked great clarifying questions, you’ve considered various different approaches, you’ve planned out your algorithm; now all you have to do is code it up.
But while you are doing this, remember to …
Talk out loud. It’s hard to help steer you in the right direction if I can’t tell what you’re thinking.
If you’re going in the wrong direction, I can interject. If you’re in the right direction, I’ll most likely let you keep going.
Small note: This is where interviewer style can be a factor. Some interviewers are more proactive than others when it comes to interjecting.
For some reason, this is the most overlooked step. I’d say 98% of the candidates that I interviewed could have benefited from better testing.
At the start of an interview, candidates are often given their interview problem alongside a sample test case.
When candidates finish writing their solution, they will run through the given test case. The only problem? We give you the simplest possible test case. Likely a test case with no edge cases nor with the capability to properly test your code.
Just because your algorithm can provide the correct output for this test case does not mean it can provide the correct output for every case.
The easiest way to stand out in a coding interview is to … write more tests. Write harder tests. Write comprehensive tests.
More often than not, this will help you catch the bugs without needing me to interject. And that looks very good for you.
What to Do When You Don’t Know What to Do
So what should you do when you’re asked a question that you don’t know right off the bat?
Take it one step at a time.
Think back and see if this question reminds you of another one you’ve heard before. Many of the coding interview questions I asked were basic algorithm questions that are taught in most data structures and algorithms classes with a twist.
If nothing comes to mind, don’t panic. This is perfectly normal.
Don’t overwhelm yourself trying to come up with the most efficient solution right off the bat. Start with the simplest solution.
From there, think about what’s the bottleneck? What aspect of the algorithm is the most inefficient? What can you do to minimize those inefficiencies?
Align the weakness of a solution to the strength of a data structure
When trying to improve an algorithm’s efficiency, you can sometimes (not always) use data structures to help you.
Each data structure has its strengths and weaknesses (i.e., Hashmaps—lookup speed, BST—ordering, etc.).
Some of the best problem solving happens when you can align the strength of a specific data structure to a problem’s bottleneck.
Given a sentence, return the number of occurrences for each letter in the alphabet.
A brute force solution would have you count the occurrences of each letter at a time, then output the result. Here, the bottleneck is storing/looking up information. We need to store the occurrences of each letter in the sentence and look up the final result at the end.
If we then take a look at all the data structures we have available to us, there is one that stands out:
- Binary Search Tree
- AVL Tree
The data structure that most efficiently stores and retrieve data is a hash table.
So if we use a hash table for this problem, we wouldn’t need to run through the sentence 26 times. We’d just need to run through it once.
Look for the twist
Often, interview questions have a twist that allows you to solve them more efficiently.
Something subtle that creates a unique condition that allows you to do something more efficiently than normally. Look for these.
Here’s an example:
Given two sorted integer arrays A and B, merge B into A as one sorted array.
You may assume that A has enough space to hold additional elements from B. The number of elements initialized in A and B are m and n respectively.
This is a question pulled straight from Cracking the Coding Interview.
Notice the twist here?
We could have been given this problem such that we are required to merge two sorted arrays, but no.
We’re given two arrays where one can fit entirely in the other.
That’s the twist I’m talking about. And when you see something like this, notice that it is there for a reason.
Those empty slots actually provide you an opportunity to solve this problem more efficiently than if they weren’t there.
You can read the full solution here.
Ask for help
Sometimes even after going through all these steps, you’ll have no idea where to go. In that case, you should just ask for help.
Standing in silence for ten minutes doesn’t do either of us any good. If you truly don’t know what to do, asking for a hint is the right step.
Everyone needs a hint every once in a while. It’s what you do with that hint that really matters.
The technical interview is a standardized test, just like the ACT, SAT, GRE, and so many others. While the details of a question may vary, the main concepts and strategies used to solve them are quite standardized.
Many candidates shoot themselves in the foot by slipping up on the simple things. Making assumptions. Not communicating their thoughts. Writing poor tests.
These are mistakes that can be fixed and ultimately make the difference between a no-hire and a hire decision.
Follow the framework that I’ve outlined in this post and you’ll be in pretty good shape.