Your ultimate guide to interview preparation
11 November 2018
In this blog post I share my interview preparation process that helped me land offers from Google, Facebook, Uber and Amazon.
I describe how I prepared for different parts of the interview process, as well as share my philosophy on the interviews in general. Lastly, there are a lot of somewhat ad hoc links to some useful material throughout the article.
Text turned out to be pretty long, but reading it may be the easiest part of your preparation. So, get used :) Hope you will find it useful!
Table of Contents
Distributed computing problems
System design interviews
Applying to companies
Offers, negotiations and beyond
Your interview experience may differ greatly depending on your background. Therefore, in order for you to find this guide more useful, I think it's necessary to share my background as it was at the time of applying.
First, I am a software engineer with more focus on the backend. Non-engineers have a completely different interview process. Frontend/ML/data/systems/mobile engineers have interviews which are fundamentally similar (after all, they also need to be able to code and know algorithms), but may have some parts that are specific to their role or otherwise different.
At the moment of writing, I live in the San Francisco Bay Area, part of which is often also called Silicon Valley. I applied only to the big and well-known tech companies, and all of them have offices here. Tech market is generally booming now, engineers are in high demand and well-paid, and it's pretty easy to find a job.
I am from Kazakhstan, and I am here in the United States on the work visa. Getting a work visa is hard, and this topic is well beyond this article (for a brief overview, read this piece), but the information here should generally work for most tech companies worldwide.
I have a bachelors degree in computer science from Nazarbayev University in Kazakhstan.
Before this round of applying to the companies, I had about 1.5 years of industry experience total. I was working for a smaller company ipsy, where I had a chance to work on a lot of cool tech stuff and got exposure to big systems at scale.
I have a lot of experience participating in programming contests, and my team got to the finals of ACM ICPC twice. So, I am pretty used to solving algorithmic problems, and before my interview preparation I generally already knew all the algorithms and data structures required to pass interview rounds.
I have a lot of friends in different big tech companies and startups. Their advice, help and experience definitely have been crucial to me. Thank you, guys! :)
Before my onsite rounds, I intensively prepared for the interviews for about three months. On average, I worked on this about three hours a day, every day, so it's about 300 hours in total (I also worked fulltime during this time). In case you need to catch up on more or less material, you may need a different amount of time, but I think at least 200-400 hours during 2-4 months is a must first time you go through the hard interview process for a fulltime position.
Be also prepared that getting referrals, talking to recruiters, passing phone screens and onsite rounds, and getting and choosing offers will take some time, about 1-2 months. So you may want to plan accordingly and start contacting the companies earlier.
Of course, investing at least three hours a day for several months into something is not easy, so here are some strategies that helped me:
- Keep a log where you track how you prepare for interviews every day. I logged 98 days of my own preparation. Log not only helps you build a habit, it will also help later in reviewing the material you studied. For keeping a log I recommend Quiver - an Evernote alternative for programmers.
- Read Deep work.
- Quit social media.
- Having a friend who is also preparing or passed interviews recently to discuss your progress with him/her definitely helps.
- Make it your top priority. During my preparation, I didn't travel, rarely hung out with friends and ignored most of "important" errands.
- Also, set yourself a deadline, something like "I will prepare for three months, and then apply". Not meeting a deadline is better than having no deadlines at all.
- Read a chapter or two in Coders at Work for an inspiration.
Good news: the interview process in most big tech companies is pretty similar, and you already may know all about it. But just to refresh your memory again, check out these materials on the format and structure of the interviews:
- Read introduction chapters in Cracking the Coding Interview.
- Uber has some pretty cool videos on the topic.
Some other guides and articles that I found useful:
- Get that job at Google - this blog post by Steve Yegge is considered legendary, so you may want to read it too.
- Another coding interview preparation guide by a good friend of mine Sergey pretty much inspired at least half of this article. Read it.
- Ace the coding interview, every time - another good guide.
- What I Learned Doing 250 Interviews at Google.
If you have time, I strongly recommend reading these books to get a deeper understanding of certain software engineering topics. I've read about 60% of their total content, full books in some cases and just several interesting chapters in others, and I feel it helped me a lot.
- Effective Java – best book on Java, and I would recommend reading it even if you mostly use some other language.
- Designing Data-Intensive Applications – a very good overview of the big distributed systems, and one of the best technical books I've ever read.
- Clean Code – classic book on writing a good code.
- Building Microservices – good book on microservices (without any unnecessary hype around them) that also provides a good overview of topics of security, testing, deployment and others.
- Design Patterns by Gang of Four – classic book on design patterns. If you don't read all of it, make sure to at least know the following patterns: Singleton, Builder, Observer, Decorator, Facade.
- Cracking the Coding Interview – I've read just several interesting chapters from there, but it's still a solid book about interview preparation in particular.
- Modern Operating Systems – some chapters in this book provide a nice overview of hardware, memory management and other systems related concepts.
- Coders at Work – book of motivating interviews with great programmers.
Software engineer's interviews usually consist of coding, system design and behavioral rounds. Coding rounds, though, take at least 80% of the process, and by far are the most important. At these rounds you will typically get 1-2 algorithmic problems that you will need to solve in the language of your choice in about 45-60 minutes.
For practicing solving problems there is nothing better than Leetcode. It's so good that I feel anybody who solves 300-400 problems there will get a fair chance of clearing almost any interview round.
- Leetcode has a lot of problems that are asked at the real interviews in big companies. By my estimations, about 25-30% of the problems I was asked to solve during the real interviews I solved on Leetcode before, and about 70% of the problems I was asked have something very similar there.
- There is also a premium subscription for Leetcode that opens you more problems and features. I found it only somewhat helpful (mostly "problem frequency" feature and company problems lists), so it's up to you if you want to buy it or not. As another bonus, paying for the Leetcode subscription can be an additional motivation to solve it more ;)
- Problem difficulties are not always very accurate, so don't skip easy problems. Hard problems, on the other hand, may be too tedious and intimidating, so get to them only once you are comfortable, and mix them with easier problems as well. Before my onsite rounds, I solved 333 Leetcode problems (115 easy, 160 medium, 58 hard), including ~100 that I solved several years before.
- For choosing what to solve next, I recommend filtering problems by company tags (choose companies you want to apply to) and frequency. I also solved all problems from these collections and found them to be very helpful: top facebook questions, top google questions and top interview questions.
- I participated in nine Leetcode contests and managed to reach 24th global rank before my onsites. Contests may be helpful to train your speed, but it's important to watch out for your solutions' code quality – you should write very clean code in your real interviews.
- After solving the problem, be sure to check its discussion and some of the top solutions there. This will help you to learn about any better ways to solve the problem, and also you may find some good code examples for the language of your choice. Generally, at the interviews companies expect you to know at least one language very well, and write real code (not pseudocode) even on a whiteboard.
- Avoid using IDEs and solve the problems right in the editor on the Leetcode website or on a whiteboard. This will better simulate a real interview environment.
- Cracking the Coding Interview book has a nice collection of problems, though nowadays it's not as useful as Leetcode, where you can compile and test your solution. I mostly just checked the chapters I found interesting to me (for example, I recommend chapters about linked lists and trees).
- During phone interviews you will code in some kind of a web editor while talking with the interviewer on a phone/skype, and on onsite interviews you mostly will code on the whiteboard. Writing a code on a whiteboard is pretty different from coding on the computer, therefore it's important to actually buy a whiteboard and solve more and more problems on it closer you get to the onsites. I got this one, and recommend getting at least this size or bigger.
- This will probably be covered by 300-400 problems at Leetcode, but here is a list of algorithms and techniques you absolutely need to know: time and space complexity, sorting (quicksort, mergesort), binary search, hashmaps, trees, graphs, BFS/DFS, union find, tries, bit manipulation, stacks/queues, dynamic programming, priority queue, two pointers, recursion/backtracking, greedy solutions. Knowing this may also help: string hashing (Rabin-Karp algorithm), probability/combinatorics, segment tree, binary indexed tree (Fenwick Tree).
Note for those who are coming from competitive programming world: interview questions are a bit different than programming competitions problems. For example, in interview problems you may find restrictions that are pretty rare in CP world, like don't use division, don't use extra memory at all, or try solving the problem without using some particular algorithm. Also, code style expected in interviews is much cleaner and more structured than typical competitive programming code. Therefore even if you are pretty good with algorithms and solving competitive programming problems, I'd suggest still solving some Leetcode problems to get used to the format and prepare better.
On the other hand, interview problems are much easier :)
Distributed computing problems
Some companies, especially Google, like to ask follow up problems that involve distributed computing – basically the same algorithmic problems, but you need to try to solve them using multiple cores/machines. I still don't know any good thorough source on this (ping me if you know?), but here is some material that I used for preparation:
- Cormen has a nice chapter on parallel computing.
- Some links that discuss certain distributed algorithm problems: 1, 2.
- Learn about MapReduce paradigm and Spark framework.
System design interviews
In system design interviews, you are usually given a very vague design problem (like design Twitter), and you need to share your approach in about 45 minutes. The purpose of this interview is to test your experience working with real software systems, and how much you know about these systems in general. Usually, interns and new grads don't get this type of interviews, but otherwise you may expect it at every big tech company.
Here is a list of material you absolutely need to check:
- Intro to system design interviews with Jackson Gabbard - really helpful video on the topic. I watched it twice.
- System design course on educative.io - good collection of solutions for common system design problems. It's not free, but well worth it. Several lessons are also available for free preview.
- Harvard lecture on scalability.
- Read at least several chapters in Designing Data-Intensive Applications.
- Building Microservices has nice chapters on security, deployment and other topics you may want to review.
Here are some videos that I found helpful:
- How We've Scaled Dropbox – fascinating story of Dropbox going from one server to massive infrastructure supporting millions of users.
- What I Wish I Had Known Before Scaling Uber to 1000 Services.
- Building Software Systems At Google and Lessons Learned by Jeff Dean.
- Facebook and memcached
- Oversubscribing Apache Spark Resource Usage for Fun and $$$ featuring my good friend Sergey :)
I think one of the best ways to prepare for system design interviews is to expose yourself to as much information about designs of the real systems as possible, so here are lots of links to the blog posts, articles, videos and papers I found useful:
- Highscalability.com - a nice website with articles on the real scalable systems, though I found the quality of some of the articles to be quite mediocre.
- System design primer - huge collection of materials and links on system design.
- Nginx book on microservices.
- Gainlo has a nice blog on system design and generally interview preparation.
- Uber tech stack
- How Uber Engineers an Efficient Route
- A Look at WhatsApp: Engineering for Success at Scale
- How WhatsApp Reduced Spam for Over 1 Billion People
- One Year Designing at WhatsApp
- MySQL at Yelp
- Quizlet Tests Cloud Spanner
- Google book on SRE
- Command-line Tools can be 235x Faster than your Hadoop Cluster
- The biggest smallest website
- Why the Hell Would You Use Node.js
- How Twitter is fighting spam and malicious automation
- CAP Twelve Years Later: How the “Rules” Have Changed
- Spanner: Google’s Globally-Distributed Database
- Spanner, TrueTime & The CAP Theorem
- Big Data and Google's Three Papers I - GFS and MapReduce
- Designing Schemaless, Uber Engineering’s Scalable Datastore Using MySQL
- How does HTTPS actually work?
- Under the hood: MySQL Pool Scanner (MPS)
- (Re)Introducing Edgestore
- How We Partitioned Airbnb’s Main Database in Two Weeks
- Evernote migration to Google Cloud Platform
- Jepsen: On the perils of network partitions
- The Google Technical Interview. How to Get Your Dream Job
- Introducing "Testing on the Toilet"
- Tape Rescues Google in Lost Email Scare and Gmail back soon for everyone
- Google Project Zero
- How to Solve Google's Crazy Open-Ended Interview Questions
- Google’s Site Reliability Engineering Podcast with Todd Underwood
- The Design Interview From the Interviewer's Perspective
- Computer System Engineering MIT course
- Awesome public Google postmortem
- Java concurrent package
- What’s different about the new Google Docs: Conflict resolution
- Bunch of Wikipedia articles
- Some StackOverflow questions
In behavioral interviews, you will typically get asked questions like "What is the most challenging project you worked on?" or "What was your biggest failure during the time at the company X?", but this differs from company to company. At some companies, you may also get these questions asked during the usual coding interview rounds.
It's pretty hard to effectively prepare for this type of interview, but here are some guidelines and materials that will help:
- Start with this video by Jackson Gabbard.
- Read a related chapter in Cracking the Coding Interview.
- Good list of behavioral questions.
- Communication: how to be a better software developer.
Real interviews are a pretty unique experience: you have to solve tough algorithmic problems in a limited time with somebody looking how you do it and with you explaining every step aloud. It may be confusing even if you are already a good coder, and this skill requires practice.
The best way to practice this without the risk of failing to get to the company of your dream is doing mock interviews. In these interviews you solve real interview problems in the setting as close to the real thing as possible. Here are the ways how you can do it:
- Practice with friends. I did two mock interviews with friends and found both sessions very helpful. The downside of this approach is that you know your "interviewer" in advance, and, as a result, you are not as nervous as you may be on the real interview.
- Pramp offers free mock interviews with peers, where you interview somebody over the internet for half an hour, and then they interview you. I did four mock interviews on the website, and found some of them to be pretty useful. On the downside, session quality heavily depends on your peer and the problem website chooses for you, and often the experience can be not that good. I also didn't really want to spend the time to interview people. During my time at ipsy I interviewed dozens of people, but if you never did this, I strongly suggest you trying Pramp – taking the side of the interviewer is a valuable experience.
For best mock interview experience, I strongly suggest gainlo.co. On this website, you arrange paid mock interviews with real engineers from Google, Facebook and other companies. Mock interviews are pretty expensive, but well worth it (partially because when you pay a lot of money for a mock interview, you treat it very seriously).
I did four sessions: three with Googlers and one with Facebooker. Three interviews were coding ones, and one was system design. Mocks were awesome in three cases out of four, and these sessions really helped me to prepare better for the real interviews. One session, unfortunately, was quite mediocre.
Applying to companies
Applying to the companies is an art of its own. Remember that the whole interview process will take some time, so I suggest starting to reach out to the companies earlier. Here are some more additional points on this process:
- Since preparing for the interviews is a big investment of your time and energy, it totally makes sense to apply to many companies at the same time. This way you have more chances that you will succeed, and with multiple offers at hand you can also negotiate a better compensation.
- Best way to apply to the companies is through referrals from somebody who already works there. So reach out to your friends and friends of friends!
- I solved all of Dropbox challenges at Codesignal (former Codefights), and within two weeks got contacted by 4-5 companies, including Twitter and Evernote. You may also try this.
- Keep your LinkedIn updated. It is a good way to get contacted by the recruiters.
- Don't stress out about resume too much. Read a chapter about resume in Cracking the Coding Interview, and check out this link on Careercup. Here is a Google Docs resume template that me and several of my friends successfully used to apply to the big tech companies – you can make a copy to create your own similar one! :)
You should also research the companies you apply to. Apart from Google and Wikipedia, here are some helpful links:
- Glassdoor is a platform with employee reviews and other details for different companies.
- Blind is an app and website where employees anonymously discuss their companies and a wide variety of other topics.
I also found that applying to the companies depends on your level of experience:
- Students and new grads usually can apply only to internships and new grad positions respectively.
- People with 3-5+ years of experience usually can easily get interviews almost anywhere.
- Most of the positions require 3+ years of experience to apply for them, so with 1-2 years of experience (like in my case), the choice is somewhat limited and it may be harder to get interviews, especially with smaller companies.
Offers, negotiations and beyond
Here are some resources that will help you better navigate and negotiate different company offers. Remember that they want to hire you as much or even more as you want to get hired! :)
- Nice equity compensation guide, read it to learn more about stocks, taxes and so on.
- Salary Negotiation with Haseeb Qureshi - a podcast with some interesting ideas about salary negotiating.
- An Engineer’s guide to Stock Options.
- Levels.fyi - here you can compare levels and compensation in different companies.
- Blind post that compares offer numbers for different levels at different tech companies.
- Ten Rules for Negotiating a Job Offer and How not to bomb your offer negotiation.
- For phone screens make sure you have a reliable internet and phone connection, good headphones with a microphone, and a quiet place where you can be alone for the whole time. I also found that the best time for me to do phone screens is the first thing in the morning (after some breakfast of course). Interviews are a pretty nervous experience so you want to make yourself as comfortable and relaxed as you can.
- Onsite interviews are physically and psychologically demanding, so you should take at least one rest day before and between them. I'd suggest taking something like one-two weeks off specifically to do onsites, and not doing more than three of them per week.
- Good luck! Generally, more you prepare, more you have it :)