How to Prepare for the Silicon Valley Interview - Part 2
Welcome to the second part of the Interviewing Series! It’s time to cover the thing that terrifies most candidates1: the technical questions. We’ll see what different types of questions there are, and how we can prepare for them. We have a lot of ground to cover so let’s jump right into it.
Programming questions are the heart of the technical interview and thus what you’ll spend more time preparing.
Some people believe that the technical interview model is completely broken2. I don’t really know if technical interviews work or not, I just know that they’re part of the game, so you’d better prepare for it. Having said that, if you are really against “whiteboard interviews” check this list of companies that don’t rely on these kind of questions. Just keep in mind that you might be limiting your options.
Regardless the type of interview, one thing is certain: you’re better off preparing for it in advance. So let’s start by talking about some of the resources I used to practice.
Cracking the coding interview (6th edition)
I like it because it’s remarkably complete. It includes a description of the different interview processes at some of the big companies (Apple, Google, Facebook, etc.), it provides tips on how to set up a good resume, it covers the basics on Big O notation and much, much more…
The technical exercises are organized by topic. Each chapter includes a brief introduction of the topic at hand (around 3 pages) and a list of problems sorted from easy to hard. This organization is nice because if you don’t have much time or don’t want to focus on a particular area you can simply skip that chapter altogether. I, for example, glossed over the ”Java” and ”Databases” chapters (Chapters 13 and 14 respectively) and skipped the “C and C++” chapter (Chapter 12).
One of the best things about this book is that each exercise comes with a series of hints in case you get stuck. I love this because it mimics what would happen in a real interview, where the interviewer nudges you in the right direction to unblock you. Also in some of the more complex problems the book presents multiple solutions and compares the different approaches. Again, something that would probably come up in a real interview.
Pro-tip: If you live in the Bay Area your local library might have a copy of the CTCI. Having said that, if you have the money this is one of the best investments you can make for your career.
The other thing I used to practice daily was LeetCode. There are a number of sites you can use to practice (here’s a video comparing the most well-known); I went with LeetCode because it was explicitly designed for technical interviews and it has support for Kotlin.
One thing I like about LeetCode is that it provides tests results after submission so you can figure out what you did wrong. Another useful feature is that it ranks your submission based on performance so you can see how well you did, compared to other solutions.
Where it falls short is in the solution explanation. Only a small fraction of the problems have official articles covering the solution and the different alternative implementations. For the rest of them, you’ll have to resort to the discussion forum, in the hopes that somebody there posted his/her answer, and the code is readable.
I didn’t pay for the premium account and didn’t try the System Design questions, so can’t comment on that.
Use a whiteboard
You want your practice to be as close to the real thing as possible. That means you’ll have to resist the temptation of using your favorite IDE and go full whiteboard. It will be weird at first. Everything will take more time, you’ll run out of space and end up using * and arrows all over the place to add extra variables. But guess what? That’s going to happen in the real interview too. So you’d better get some practice on whiteboard coding before going in.
Don’t worry, nobody expects you to memorize all Java Collectors. It’s OK to ask the interviewer for the details of a particular method signature.
Having no IDE also prevents you from writing automated tests for your problems. Which (for once) is a good thing! You won’t have the luxury of unit testing your code during the interview either. Having said that you should still THINK about the tests you’d write, and even whiteboard-debug some of them (see below 👇).
Build the habit
Sometimes you’ll find it hard to sit down and practice. Here are some things that helped me:
- Find a time of the day that works for you and stick to it. For example, I’m a morning person. I’d wake up one hour earlier each day and practice before breakfast.
- Avoid distractions. Apart from waking up before everyone else I made sure my phone stayed in airplane mode at least until I’d finished one full problem.
- Prepare things beforehand. Before going to bed I’d set things up so that everything was ready in the morning. Waking up to a clean whiteboard, the computer charged and CTCI opened in the right page gives you fewer chances to slack or make excuses.
- Set yourself achievable goals. I found that not finishing my morning practice goal made me anxious during the day 😰. So I figured it was best to set realistic goals, so that after completing the morning exercise I could feel good about myself for the rest of the day.
- Know when to stop. Don’t get too caught up on one problem. If you get stuck, just drop it for the time being, or move to another exercise. ”The best debugger ever made is a good night’s sleep.”
Problems might seem hard at first, but I promise that once you get the knack of it they’ll flow more easily. To the point where you can eyeball a problem and have a pretty good idea of how you’d solve it.
While solving the exercise
The best advice I could find on how to tackle a problem is from Cracking the coding interview. Luckily, they’ve put together this amazing cheat-sheet with a step by step guide:
(It’s also a great example on how NOT to lay out an ordered list of items)
Talk through the problem
The whole point of having you solve an exercise during an interview is to provide the chance for the interviewer to evaluate how you approach a problem. So the best thing you can do to help your interviewer’s job is to speak through your thought process.
It’ll probably feel odd at first because usually, this happens as an internal monologue in your head, so make sure you practice this even when you’re solving problems on your own.
On the real interview, start by listening to the problem carefully and asking clarifying questions (does the input fit into memory? how often is this code going to be executed? etc.). Then walk your interviewer through each of the steps you take to arrive at the solution. If you’re going to start by trying an example say it so, if you’re coming up with a brute force solution first make that explicit, if you think the code could be refactored to be more legible express it. You’ll get extra points for mentioning these things, and in some cases, you might be told not to focus on that, and you’ll benefit from not wasting your time in a detail that was not meaningful to the interviewer.
It is ok to be in silence only when you’re thinking. The rest of the time you should be explaining what you’re doing. Especially while coding.
There are a number of things you should consider on every problem you face:
- Are you handling nulls properly?
- Have you handled border cases? (empty collections, empty strings, negative integers, etc.)
- Have you considered overflow on arithmetic operations?
- Is the input sorted?
- If it is a collection: can it have duplicates?
- Does the input fit in memory?
- Can a better solution be found or have you achieved the best possible runtime?
- Can you trade space for time? (Think: HashMaps and memoization)
- Can you pre-calculate something to speed things up?
- Can you split the problem in smaller parts?
- Is your solution thread safe? If not, how can you make it?
- Is there any state you can save to make future runs faster?
On CTCI cheat-sheet step #7 is Test. What I like to do for testing my solutions is what I call “whiteboard-debugging”. This is how it goes:
- Choose a good input example to work with (not too big, not trivial, not a corner case, etc.).
- Now step through the code step by step as if you were debugging it.
- Use a color marker to write down the variable values as comments just like your IDE would do.
It should look something like this:
For this technique to work the only trick is to suppress your instinct to jump ahead. With the interviewer watching you’ll get anxious and will want to speed things up by skipping a “trivial loop” or just jumping to the result. DON’T DO IT! Step through the code one line at a time just like the compiler would do. This is the only way you’ll find 🐞 in your code.
And of course pay extra attention to hot spots like arithmetic expressions, null nodes and loop conditions (always check for off-by-one errors!).
Stick to one language
It’s no secret that I’m super hooked with Kotlin (some of my friends would even say I’m a fanboy), so I figured I’d practice the programming questions in Kotlin too. The problem was that Kotlin is not that widespread (yet), so most of my interviews required me to write code in Java. Kotlin and Java are fairly similar languages and yet I noticed that writing solutions in Java was taking me longer because of small things like having to look up the exact method I wanted to use. In one of my on-sites, for example, I mixed up the Java
switch syntax with Kotlin’s
when. And while this isn’t a huge mistake, it did raise a valid flag for the interviewer.
That’s why my advice is to pick one mainstream language and stick with it for both: practice and interviews.
In my experience, open problems are not that common. When you’re presented with one of these questions your main focus should be on clarifying the goal. Ask as many followup questions as you can and don’t make any assumptions (or if you do validate them with the interviewer). Don’t just jump to the answer! Usually, this kind of exercises are more about seeing how the candidate approaches the problem rather than getting an actual solution.
As you can tell, these are knowledge-based questions, so either you know the answer or you don’t. If you don’t just be frank about it, trying to guess the answer might backfire and make you look like a fraud.
If you’re proficient with the language you’ll have no problems answering these kind questions. If you want some practice CTCI has one chapter on Java and another one on C and C++.
System design questions
The system design interview is an open-ended conversation. You are expected to lead it.
The best resource I know to prepare for the System Design interview is The System Design Primer (thanks Pablius for the tip!). Additionally, you should regularly read engineering blogs to learn how different challenges are solved in different companies. Some of the best ones are: Netflix Tech Blog, highscalability.com and Github engineering. You can find a full list of company blogs here.
That’s all I’ve got to say about practicing for the technical interview. On the third and final part of the series I’ll talk about the on-site and what happens afterwards (a job offer or rejection). See you next time!