Agile interview preparation. Agile interviewing structures…
By: S. G.
Tags: Leetcode, Interview Tips, Software Development, Programming, Software Interview

In the fall of 2019, I took a sabbatical from Software Engineering and spent a semester teaching interview preparation at the University of Puerto Rico. I co-taught and co-trail-blazed the course with a well loved and competent Professor.

I remember looking into the warm, curious eyes of the 30 students who had taken the elective. In their eyes, I saw excitement and expectation. Surely, there was no instructor better equipped to lead the course than a Software Engineer from Google?

In my first class, I made a mistake. I played this video. Then I told them that the only thing that stood between them and a juicy tech job offer was practice. “Let’s see how many of you can solve over 150 problems on LeetCode by the end of this semester”, I challenged them.

I do love the energy and delivery from the video. The crux of it is in this single line — “when you want to succeed, as bad as you want to breathe, then you’ll be successful”. When I was practicing for a half marathon, and struggling for motivation, the video inspired me. Showing this to a class of students who were already motivated to get better at interview preparation was a mistake. I was telling them to do a million push-ups.

Some students from my class did offers from big tech (Microsoft, Google etc) but many were unsuccessful in spite of having solved over a hundred questions on LeetCode. Friends and colleagues have share similar experiences- they just aren’t seeing success in interviews in spite of having solved hundreds of questions.

I was raised to believe in hard work. My parents worked long hours, and as a kid I saw cause and effect in action. I studied harder than my class-mates and so I did better than them academically. I’ve had a simple mantra — to master something, you need to practice till you are perfect. Do it over and over till it becomes a part of your muscle memory. 10,000 hours was the magic number proposed by Malcom Gladwell in his book ‘Outliers’. Do something for 10,000 hours and you’ll become great at it.

Let’s say that you give me a large log of wood and an axe to chop some firewood. If I don’t know anything about chopping wood, and start chopping the wood against the grain, I’m not going to get you any firewood. I can spend 10,000 hours wielding my axe against the grain, but I’m going to be a lousy woodcutter.

Practice makes perfect is incomplete advice. Practice needs to be done intentionally. Only through reflection will I realize that I need to chop with the grain, and not against it.

So what if you’ve solved 250 questions on LeetCode, and still can’t get an offer? Does that make you stupid? No, it just makes you bad at reflection.

Of course, given infinite time and infinite patience, you can brute force your way through the process by solving hundreds, or thousands of problems on LeetCode. But it’s inefficient. In reality, you’re probably studying or working full-time, and time spent on learning esoteric problems on LeetCode is time that you spend away from other things that are important.

The traditional approach to interview preparation is like this: you practice problems on LeetCode till you decide that you are interview ready. Then you line up as many interviews as you can and start interviewing. Perhaps you’ll take 2 weeks off from work and schedule the interview loops back to back. I call this the waterfall approach.

Rather than going with the traditional waterfall approach to interview preparation, make your interview preparation agile.

Agile interviewing structures preparation in sprints, with reflection at the core. Your objective is to iterate and fail fast. Each sprint should incorporate reflection, intentional practice, mock interviews and real interviews. Repeat this till you get a job that you want. The agile approach is optimal because you end up spending no more effort on preparation than is required to actually get the job that you want.

Not all sprints will be equal. Your first sprint will be the longest, especially if you haven’t interviewed in a while or are out of touch with data structures. Don’t wait to solve a hundred problems on LeetCode before you start interviewing. Don’t line up 10 interview loops over 2 weeks. You’re depriving yourself of a chance to reflect and course correct. You’re probably going to fail your first interview. Heck, you’re probably going to fail several interviews. Stagger interviews over sprints so that you have time to reflect on how you can get better.

Reflection

The objective is to identify gaps in your preparation.

In your first sprint, you’ll need to spend time to understand what you don’t know. When I started interviewing this year, I quickly realized that I needed to brush up on heaps and backtracking.

Second sprint onwards, it’s about looking back at your interviews and identifying areas of improvement. Replay the interviews in your head and write down your insights. Do this soon after the interview when it’s fresh in your head. What could you have done better? Were you too nervous? Did you make some unwarranted assumptions or ignore a large part of the problem? Or maybe you really need to brush up on fundamentals of Graph theory.

Be shameless in asking for feedback.

Most companies will decline your request, but some will be kind enough to offer constructive feedback. For example, Shopify told me that I didn’t spend enough time discussing failure/edge cases during my System Design rounds. Square told me that my coding seemed more reactive than proactive. Feedback is gold, and you should internalize it through intentional practice.

Intentional practice

The objective is to work on your weaknesses and get incrementally better.

How/what you need to spend time on will depend on your reflection but here are some general tips:

Don’t shoot for solving a certain number of problems on LeetCode.

Instead, go for breadth and solve different categories of problems (backtracking, merging intervals, sorting via heaps, maze traversals etc). Try to solve problems in several different ways. Focus on understanding the various techniques. Look at a couple of top-voted submissions. You’re bound to learn a thing or two.

The coding problem you’ll be asked will be of a medium difficulty.

Exceptions aside, interviewers aren’t going to expect you to know esoteric algorithms/data structures (e.g. Segment Trees, KMP etc). You won’t be asked to solve LeetCode hard problems in 30 minutes. When interviewing for Google, I used to like asking a very simple problem on making range replacements on a string.

Skip dynamic programming.

It’s not worth the time and most interviews will be perfectly fine if you use recursion rather than dynamic programming to solve the problem. My friends at Facebook tell me that they are explicitly asked to avoid asking problems on dynamic programming since they aren’t a good representation of work you’d be doing. The number of times I’ve used dynamic programming at work over the last 10 years is a big fat zero.

Don’t rush, and incorporate “spaced-repetition”

If you aren’t able to solve a problem, don’t just read the solution and move on. At my interview prep course, I gave my students a list of 40 questions in advance and told them that their midterm quiz would be one of the 40 questions. Students who had simply “read” through the solutions didn’t fare well.

Whenever you do end up looking at a solution, or discover a new interesting way to solve a problem, you need to revise it at frequent intervals in order to internalize it. You can keep track of what and when you need to revise by simply using a spreadsheet, or by adding events to your Google Calendar. You can use a fibonacci pattern (e.g. revise on day 3, 5, 8, 13, 21 etc). Alternatively, you can use apps like Anki that have spaced repetition built in.

Practice being proactive and thinking through failure cases.

This is a part of the rubric used to assess your coding. When LeetCoding, think through the edge cases and do a dry run before hitting Submit. Develop the habit of minimizing the tweaks you need to make to your code to get a passing submission.

Mock interviews

The objective is to practice in a simulated but real interview environment. Think of this stage like releasing your feature to a staging/sandbox environment.

Talking out loud or being observed during coding isn’t natural. You need to normalize this so that you can give your best performance and avoid the dreaded “brain-freeze”.

There are plenty of free resources that will let you simulate real interviews. Sign up for pramp which lets you practice 1:1 with peers. It’s also a great resource for those who want to follow the sprint model but aren’t able to get many real interviews.

If you are privileged enough to easily get interview calls, you can skip this and go straight to the real interviews.

Real Interviews

The objective is to give it your best shot and collect data for your next sprint. Schedule 2–3 interviews at a time to understand where you stand.

Find the time of day that you’re most in flow. Find what works best for you. Maybe a run or a workout before the interview helps put you at ease.

Once you get an offer that you’re ready to sign, you can try to blitz your way through several more with the goal of obtaining some counter offers. Once you mention to a recruiter that you have an offer and deadline, companies will rush to finish your interview loop.

Build a routine that works for you.

Don’t be rigid with your sprints- the goal is to build the preparation model that works best for you. You might find that it’s best to skip mock interview entirely or you might find yourself jumping from intentional practice to reflection several times within a sprint:

The interview process is a marathon. Depending on where your skill levels are at, the process can take anywhere between 1 month to 2 years. Be patient and learn from your mistakes. At the risk of sounding cheesy, I’ll quote Confucius:

Our greatest glory is not in never falling, but in rising every time we fall.

This article was focused on coding interviews. The system design interview is an entirely different beast altogether, and I plan to cover that next. Follow me on Medium to be notified whenever I publish it.