Many techies are daunted at the prospect of doing programming interviews. There are so many unknowns: Will you be able to solve the problems they give you? Will you be asked to solve them on a whiteboard instead of a screen? What if there’s something you don’t understand?
A great way to prepare for your programming interview is by doing practice questions ahead of time. But don’t spend all your prep time doing this without taking the time to really understand what your interviewers are looking for while assessing you.
In this guest post, Clément Mihailescu, a software engineer at Google and the co-founder and CEO of AlgoExpert, explains what interviewers are looking for in the technical interview.
If you’re likely to be job hunting any time soon, pay close attention to his tips so you can crush your interview and land a job in tech!
Big tech companies and startups are notorious for their difficult, timed, algorithm-intensive software engineering interviews. Because of this, many developers fear and hate programming interviews.
However, with the right amount of knowledge and preparation, you can alleviate these negative feelings and ace those interviews. Here are six key things that tech interviewers aim to assess in the interview room.
Please note that these are a combination of my own thoughts and publicly available information! I am not representing my employer.
#1 Algorithms and Data Structures
Algorithms and data structures are the bread and butter of programming interviews; at the core of the interviews, they are what you’re being tested on.
It’s therefore very important to understand what they are.
Let’s start by defining algorithms within the scope of a programming interview. An algorithm, in its most basic form, is the solution to a self-contained problem. In the context of an interview, these problems generally take roughly 45 minutes to solve both conceptually and programmatically.
For instance, in an interview, you might be asked to develop an algorithm that solves the following problem:
Given a list of integers and an integer k, write a function that returns the kth largest integer in the list.
There are various kinds of algorithms, including sorting algorithms, searching algorithms, recursive algorithms, divide-and-conquer algorithms, ones that make use of dynamic programming, etc. It’s important to be well-versed in all of them.
If an algorithm is a solution to a problem that you’re given in an interview, data structures are (some of) the tools at your disposal to implement and optimize that algorithm.
It’s supremely important to be intimately familiar with all of the popular data structures. These include arrays, strings, binary trees, binary search trees, linked lists, heaps, graphs, tries, hash tables, queues, and stacks.
In some ways, data structures constitute the theoretical “knowledge” portion of the interviews. They are the baseline amount of knowledge–aside from knowing how to code–that you simply need to have in order to succeed in an algorithm interview.
So how do you prepare for algorithms and data structures?
Well, the first step is to actually learn about the many data structures and types of algorithms that exist and to understand them. The second step is to develop the ability to recognize patterns in problems and quickly identify the data structure(s) and type(s) of algorithms necessary to construct an optimal solution.
How do you do that?
Smart practice. As with many things in life, practice really does make perfect in the world of algorithm interviews. The more algorithm problems you do, the better you will get at the pattern-recognition step described above.
However, I prefix “practice” with “smart” because it’s crucial to truly understand the best way(s) to solve the problems that you practice with. Mindlessly coding out solutions without knowing if they’re actually working, let alone optimal, is a recipe for disaster. That’s where good preparatory resources come into play.
Cracking the Coding Interview and Elements of Programming Interviews are two fairly popular options. They’re pretty good (albeit dense) books with a lot of practice questions.
I would recommend AlgoExpert as one of your main resources (disclaimer: I am the co-founder and CEO of AlgoExpert). AlgoExpert is a website that offers an organized platform with 60 curated practice interview questions, with more being added periodically. Each question is accompanied by:
- an in-depth two-part video explanation consisting of:
- a conceptual “whiteboard” overview of the algorithm at hand, covering its inner workings and its space-time complexity analysis
- an entire coding walkthrough of the solution
- a full-fledged coding workspace where you can type out and run your code against premade test cases and look at hints if you need help
Use the promo code l2code for a $10 discount on AlgoExpert.
I would then suggest approaching each question on AlgoExpert as follows:
- Attempt to solve the question by yourself. Don’t set any time limits at first; then, as you improve, give yourself 45 to 60 minutes per question.
- Look at hints sparingly, only when you need them; try to imitate an interview setting.
- Only look at test cases if you’re really stuck or if you really can’t find why one or two test cases are failing.
- Analyze the time and space complexities of your algorithm (more on that in the section below), compare them against the optimal ones next to the hints, and see if they match.
- Watch the video explanation at 1.5x or 2x speed, then go through the written solutions and see if they now make sense. Make sure you understand the complexity analysis portion of the video.
- Do the question again a few days later.
#2 Complexity Analysis
Many algorithm problems won’t be limited to only one solution; in fact, it’s safe to say that most will have multiple solutions relying on different data structures and approaches.
What differentiates the better solutions from the worse ones are their time and space complexities (i.e., how fast they run and how much additional memory they use up), which are typically denoted using Big O notation (e.g., O(n), O(n!), O(log(n)), etc.).
You’ll often come up with a working solution during an interview, and your interviewer will ask you the infamous question:
Can you do better?
This is essentially a facade for:
What are the time and space complexities of your solution? Can you come up with a solution that’s better in one or both of these regards?
Just as it’s important to be familiar with the many data structures that exist, it’s important to know their space-time-complexity tradeoffs.
You should know how fast it is to look up a string in a trie. You should know how much time it takes to print integers in an array using a double for-loop. You should know the space-complexity ramifications of a recursive algorithm. These are but a few examples of what you need to know.
So, how do you prepare for this?
You go through a thorough complexity analysis for every single practice problem you do–no exceptions. And you make sure that you truly understand it for every algorithm you implement; you should be able to derive it from logic, not just from memory.
See the section above for more detailed information on what resources to use to prepare for this.
#3 Coding Skills
As you might expect, coding interviews also aim to test a candidate’s coding skills. After all, your job will likely primarily consist of coding. But how can coding skills be tested in a 45-minute interview, half of which is spent jotting ideas down on a whiteboard?
The truth is, they can’t be fully assessed. However, interviewers can pick up quite a few signals that can tell them a lot about your coding style.
Here are some simple yet important things you can focus on to really accentuate your coding skills:
- DRY (don’t repeat yourself): any piece of repeated logic in your code should most likely be abstracted out into a helper method
- YAGNI (you aren’t gonna need it): don’t implement anything that isn’t necessary for your algorithm to work properly and optimally
- Readability: your code should be as readable as possible; the closer it is to production-grade code, the better
- Variable naming: favor clear, self-explanatory variable names like “longStrings” and “getEvenFactors” over ambiguous ones like “a” or “gef”
- Documentation: if you’re given the opportunity to type up your code, consider adding a few lines of documentation in the form of comments where they might be helpful
- Self-explanatory code: capture long and confusing bits of code into logical variables; e.g. “if (error.status !== SOME_STATUS && error.code === SOME_CODE)” can be turned into “if (canHandleError)” where “canHandleError” is set to the complicated condition
A good way to work on your coding skills is to treat the code you write for every practice problem as if it were going to be pushed to production as part of an open-source project.
Another way is to have a (programmer) friend or two read your solutions; if they can quickly grasp what your code is doing, you’re likely in good shape.
Download the LinkedIn profile checklist
Created with aspiring techies in mind.
#4 Problem-Solving Ability
A popular misconception amongst software engineers is that big tech companies and startups are purely assessing candidates’ abilities to solve puzzle-like algorithm problems.
This couldn’t be further from the truth.
While it is true that tech companies test candidates using puzzle-like algorithm problems, what they are really assessing under the hood is problem-solving ability.
Is this candidate a great problem solver? How does this candidate tackle a difficult and ambiguous problem?
And it so happens that many interviewers think puzzle-like algorithm problems are great tools to assess problem-solving ability (this is highly debatable but the subject of an entirely different article).
So how do you convey that you’re a great problem solver?
You start by asking questions. Anything that isn’t clear about the prompt, anything that could warrant more information–and there’s always room for clarification–you ask it. Can we be given invalid input? How do we handle an empty input? Do these strings only consist of alphanumeric characters? Are these numbers always integers? Are the dimensions of this array always equal to each other?
Then, you come up with a strategy to solve the problem (or try to). Can this problem be divided into simpler subproblems? Does this problem ask two different questions that can be addressed separately? Is there an obvious naive solution that we can crank out before trying to come up with something better or optimal? Vocalizing your thoughts is really important to help convey your problem-solving ability here (more on that in the next section).
You then proceed to implement your algorithm in an organized manner; for instance, if you’ve managed to separate the problem into two separate questions, tackle them one at a time, explaining why you pick one of them first.
Finally, you test your algorithm with various inputs and try to come up with edge cases to see if they’re handled properly.
The key takeaway is that you should really show that you’re a great problem solver; don’t think that simply finding the optimal solution to the problem will demonstrate that.
In my opinion, communication is the most underestimated aspect of a coding interview, and it’s one that can sometimes make or break you.
As software engineers, we tend to think that coding is all that matters for our job, and we forget that communicating effectively is instrumental to succeeding as part of a collaborative software development team.
In an interview, you will be assessed on your communication. Would you work well as part of a team? Could you explain a complex design or piece of code clearly and unambiguously? Could you convey engineering-specific information to non-engineers?
These are some of the interviewers’ questions that are directly and indirectly getting answered throughout the interview.
So how do you communicate effectively in an interview?
First and foremost, you speak. You vocalize your thoughts. Any approach that you’re considering, any data structure that you’re analyzing, any complicated code that you’re writing–you think it through and explain it out loud.
This is extremely important. You want to give your interviewer as much information about your thought process as possible. Never assume that your interviewer knows why you’re doing something; they don’t.
For example, if you’re taking a few minutes to decide between a recursive and an iterative algorithm, tell your interviewer and explain the tradeoffs. Doing so will help convey your critical-thinking skills and will keep your interviewer in the loop. If you don’t speak up, the interviewer might just think that you’re stuck.
Communicating can also help you in situations where you truly are stuck. Instead of staying silent, consider explaining to your interviewer why you’re stuck:
So we’ve tried solving this problem with a max heap. That didn’t work because of X. We also tried using a simple array, but that led to some problems with Y. I’m not really sure if I’m missing something here. Do you have any ideas?
This summarizes your thought process and shows your interviewer that you have considered a few seemingly valid options. Perhaps you’ve just been missing a tiny yet crucial detail, and now your interviewer knows not to penalize you for some larger logic flaws. This can also prompt your interviewer to give you a more targeted and helpful hint, which is a good thing.
As you may have guessed by now, communicating goes hand in hand with demonstrating that you’re a great problem solver. Therefore, it’s really important to communicate as much as possible.
One last point I’d like to make is that I am not implying that tech companies are biased towards hiring extroverts. Not at all–you can be a fantastic communicator as an introvert. Don’t mistake sociability and a loud voice with clear communication; the former won’t really do much for you in these interviews.
#6 Culture Fit
Culture fit is a tricky and intangible one; it means different things at different companies. It’s nonetheless very important.
My advice is as follows:
For small startups
- Being genuinely interested in the company’s domain is crucial. Demonstrate this interest by actually being interested in the company and its field, by doing your research on the company and its field, and by expressing this interest during your interview via well-prepared questions and answers.
- Getting along with employees (and interviewers) is quite important because you’ll likely be working with them very closely, all the time (this is amplified the smaller the company is). Try to get a sense of the company’s culture from their “Meet the Team” page and see if it even fits your personality and style.
For big companies
- Being interested in the company’s core product isn’t enough – saying you like Facebook’s mission isn’t very unique. Demonstrate intellectual curiosity and vitality by doing research on more distinct features of the company, like a new product area or tangential mission, and mention it at the start or end of your interviews.
- Show that you are a collaborative, friendly, and smart person who would make a great co-worker. Nailing the five sections above will help!
That’s it. Now you know how to ace those scary coding interviews! And if you decide to purchase AlgoExpert to sharpen your algorithm skills, remember to use the promo code l2code to get a $10 discount!
About the author
Clément Mihailescu is a software engineer at Google and the co-founder and CEO of AlgoExpert. After graduating with a degree in Mathematics from the University of Pennsylvania in May 2016, he decided to learn programming and enrolled in Fullstack Academy, an immersive coding bootcamp in New York City. Upon completion of the program, he dove into the field of algorithms and aced the Google interviews. The frustration that he felt during his interview prep led him to create AlgoExpert.