Surviving Software Engineering Interviews

A few years ago, as a brand-new apprentice developer, I was doing an AMA session on campus with current students of the bootcamp I had attended when a student asked me about the job search. Without missing a beat, I said, "It sucks." They all laughed, betraying the horror on their faces at the blunt confirmation of their worst fears. Some people in the back might have cried.

Afterward, my manager advised me to maybe not say that. But it was true then, and it's definitely true now.

So, basically, if anyone tells you that interviewing for a new job as a software engineer is easy and fun, they're lying.

Tech interviewing is an overall unpleasant process that makes you question even after many years of professional experience your validity as a software engineer as well as your own self-worth and intelligence.

I've been programming professionally for four start-up years, which is something like eight regular years (I'm making up my own multiplier). I code; therefore, I am a developer. I have built features from end-to-end. I have designed systems, completed massive migrations in a legacy codebase, and also dipped my toes into the world of ops. I have done lots of complex things and done them well. But never have I doubted my abilities more than when I was interviewing.

But it's okay. I survived, and so will you. You'll bomb a couple interviews, make some good impressions. You'll learn a lot about yourself in the process. You might learn some new stuff about coding. You'll meet some weirdos as well as some really awesome people, and at the end, you'll probably make more money in the process. So overall, I suppose it's worth the suffering.

If you are looking for tips on how to survive interviewing mixed in with some fun anecdotes, you've come to the right place! Because I am starting a job in about a month and I have some stories to share.

Make a Plan and Prep

I'm a planner. It is just in my nature. To that effect, I started plotting an interview strategy and timeline a year ago.

Especially when you are starting to interview after a few years on the job, I think it's really useful to come up with a general plan of attack. Interviewing is, unfortunately, an entirely different skill set. You need to remember to talk out loud and communicate your thought process. You need to know obscure details about frameworks and be able to articulate them. You need to be able to stomach stress and not throw up during onsites as you stand, panicking and sweaty, at a whiteboard as your mind blanks. Sometimes you even need to know the meal to choose during the lunch interview that will require the least amount of chewing and slurping. It's a lot, and you need to practice.

(Maybe it's easier to always be interviewing? I'm sure there are pros and con to that.)

Working backward from my target new job start date, I estimated how long it would take me to study and network and interview. For the most part, I found that each company's process takes about one month from start to end, since the interview process typically has three or four steps and it takes about a week in between for team's to gather feedback and schedule next steps.

The Typical Interview Process

  1. Recruiter screen in response to referral or application (15-30 min)
  2. One or more technical phone/video screens with software engineer or manager (1 hour each)
  3. Onsite interview (3-4 hours)

Knowing that I would probably bomb a couple interviews in the beginning, I set aside time for simultaneous studying and interviews with companies that I didn't really care about. And then, since I wanted to take a crack at some of the bigger tech companies, I knew I needed a lot of time to actually learn algorithms and data structures. (For what it's worth, my experience with companies who ask about algorithms and data structures has been mixed. Many want to know if you understand time and space complexity. Fewer are interested in whether you know how to implement and use a heap.)

Factoring in all of these knowns, I was left with this rough timeline:

Month 1: Identify companies that seem cool and interesting. Start chatting up friends and ask them what they're working on and if they know anyone else who is working on cool stuff. Update resume and LinkedIn with latest job experience.

Month 2: Start responding to random recruiter requests that you don't really care about. Do the tech screens. Begin studying in earnest.

Month 3: Do a couple onsite practices. Get some referrals for companies and apply for real.

Month 4: Do the real deals, phone screens, onsites, the whole thing.

Month 5: Accept offer and revel in glory.

###Tools to Help You Organize I used a Trello board to help me keep track of the statues of each of my opportunities. It was a pretty low-lift solution. I didn't do anything crazy with reminders or statuses or anything, just a couple swimlanes.

I also kept notes on each opportunity in my actual email inbox. Whenever a recruiter would reach out to me, I'd just keep the notes in a draft in the same thread. Previously I've used note-taking software, but I found that it was much easier to have all the information about an opportunity in one place.

Networking and Applying

So, generally, I am not a big fan of networking in the traditional sense, but I am pretty good at connecting with people and maintaining friendships. I go to the occasional Meetup, but I have been far more successful just catching up with old colleagues and friends and seeing what they're working on. If you are an introvert like me, maybe the same will work for you.

As far as applying to companies, from my own experience and based on the advice I've received from coaches, it is practically useless to apply blindly online. Occasionally I do it just to see what'll happen, but I'm never counting on a response from those. For any place I actually want to work at, I get a referral.

Studying

Just from this round of interviewing, I found that studying was actually a good idea. In the past when I'd interviewed, my primary focus was building side projects that I could talk about in an interview setting. And don't get me wrong, for some people, a job opportunity might fall into your lap, you'll ace the interviews, and get the new job. But actually putting in the time to study can't really hurt. Some people just get lucky. The rest of us need to study.

When I was interviewing this time around, with tools like CoderPad and CodeSandbox or whatever else is out there, it seemed like a lot of companies actually wanted to do some real code challenges (some problem-solving, algorithm-y questions and some pair programming in a codebase challenges) with me in real time. Other companies did those same challenges in a Google Doc because they didn't want to pay for those services, which says something (not sure what) about their company's stability... Anyway. Many companies are really into this live coding thing.

With that in mind, and knowing that I wanted to interview at a large tech company, I did a lot of studying. In general, I wanted to get exposed to as many types of problems as possible.

First, I took a couple classes online about algorithms.

  1. [The Coding Interview Bootcamp: Algorithms + Data Structures by Steven

Grider](https://www.udemy.com/share/101WU0AkIbeFdWTXQ=/) 2) JavaScript Algorithms and Data Structures Masterclass with Colt Steele

I read a couple books, well, parts of some books. I didn't read them from end to end.

  1. [Cracking the Coding

Interview](http://www.crackingthecodinginterview.com/) by Gayle Laakman McDowell 2) The Algorithm Design Manual by Steven Skiena

I practiced on Leetcode every day. If I hadn't been angling for Big Tech, I wouldn't have done this, but I figured I would give it my best shot.

Some people will tell you to do mock interviews. You can, I guess, but I find them really awkward, so I didn't.

The Phone Screen

Generally, after I applied, a recruiter would reach out to me and schedule a phone screen. We'd cover topics like my background, interests, and salary expectations. And then they would tell me about next steps. In most cases, the next step was either scheduling a technical phone screen or a take-home challenge.

For technical phone screens, I got a lot of Leetcode-like problems, but some involved pairing on a real app. Most were conducted over Zoom. Usually I was allowed to pick whatever language I wanted, which for interviews is always Ruby.

Yes, you should pick a language you're familiar with, and I'm familiar with a handful, but I'm the most proficient and efficient in Ruby. I find that Ruby lets you express exactly what you want to code with as little friction as possible, which means that you'll end up writing more correct code and be able to debug it faster. In general, demonstrating your ability to think and code live is way more valuable than your ability to configure an app from memory. But that's just me and what I look for when I'm interviewing candidates.

I bombed the first technical interview phone screen I had. A startup founder had reached out to me via email and he seemed like a reasonable person so we set up a time to chat. Via Code Sandbox, we set up a code pairing session and he wanted me to build the game Set.

Minor aside: I hate building games for code challenges. I think they bias toward people who have heard of the game or who have studied combinations or permutations recently, and you never get very far into building a game with just an hour.

I had never played or heard of the game Set, so as he explained the rules, it pretty much went over my head. I could not for the life of me figure out what he was trying to explain. The cards had shapes and colors? You had to match some but not all of the attributes? What the heck was a Set?

I was able to build a deck of cards, but after that we got almost nowhere. Needless to say, that interview was a bust. After that botched interview, I seriously questioned whether I had the capacity to code at all.

A couple companies had me do some domain modeling and system design as part of the screen. But overall, a lot of the questions were very similar to those you would find on Leetcode.

The Take-Home Challenge

Another somewhat popular technical screen is the take-home challenge. These can take anywhere between a few hours to a few days depending on the company.

A few companies have had me build out a link shortening app in whatever framework I wanted. For app-building take-homes, the greatest advice I can offer is to read the directions, write tests, and add a readme describing the app and includes setup instructions. Also, unless you're interviewing for a front-end role, you can probably get away with using very minimal styling or a framework like Bootstrap.

Others had me critique a design document. I thought this was a pretty great idea actually because it was reflective of how the team works and gives a good indication of your thought process and ability to communicate. It helped that my team was real big into design docs recently, so this was basically just like doing my normal job. For a different company. On a contrived problem.

The Onsite

Most of the onsites I did lasted between three and four hours and consisted of two or three technical screens, a couple behavioral sessions, and perhaps a cultural fit interview.

##The Technical Portion Many included pairing together on a loaner computer on some sort of challenge. Some were Leetcode-like problems on a whiteboard. Others were system design on a whiteboard.

People tend to dislike whiteboarding. With enough practice, I think you get used to it. That isn't to say I'm good at it necessarily.

For one of the first interviews I did at a pharmacy startup, the recruiter informed me that the interviews would not involve any type of "algorithm-y" questions. And that was true of the phone screen -- I ended up pairing on building out some new features in an app that mimicked some of the basic functionality of the startup's core platform, which was totally fine. Flash forward to the onsite, and suddenly three managers come in one after the other and want me to whiteboard algorithm-like problems.

The first question I should have been able to do. It was to split an array into chunks of a given size. A couple things went wrong, though. First, I was confused and shocked that there was going to be whiteboarding at all. Second, I chose to do it in JavaScript to practice (another interview I was preparing for was going to be entirely in JavaScript). And third, the whiteboard markers were almost out of ink. Plus the interviewer kept trying to rush me and stood very confrontationally a few feet away from me by the board.

Pro tip: Bring your own set of whiteboard markers.

In the next question, another manager gave me a question about calculating the median of a stream of numbers. Medians and streams are the stuff of my nightmares. I asked some follow-up questions and then wrote a really naive solution on the board that sorted an array of numbers after each addition. She asked me about the runtime, and then she asked me if there was a better solution. Of course there was! But I didn't know what it was. Turns out, the optimal solution leveraged heaps. Which I had only just learned about.

The final question was to build spellcheck, which sounds intimidating, but I broke it down and built really naive solutions and then built on them. That's basically what you should always do. Get something working. Then build on it. The worst thing you can do is to sit or stand silently and not write any sort of code.

So that was one interview in a nutshell. I did not get the job, which was fine because that was just a warm-up anyway.

##Some Other Experiences

A fintech startup: Three pairing sessions with software engineers on building well-defined features in a Rails app and a behavioral interview with a manager over an afternoon. It was very friendly and collaborative. That company decided that they were no longer going to hiring full-stack software engineers though, so it fell through.

An infrastructure as a service company: This was a remote interview consisting of two behavioral / cultural screens and two technical screens, one of which was to review a pull request and the other of which was to implement database transactions in Ruby.

An edtech startup: Three tech lead / manager types asking me one Leetcode-like question and two system design questions, all coded on a whiteboard. The first question was to build autosuggest. One of the system design questions was essentially to build Datadog. It's lucky that I have been paying the vaguest of attention to my team's integration of Datadog into our systems. Otherwise, it would have gone way worse. Fortunately, I ended up with some boxes and lines on the board and the semblance of something that made sense. I've blanked on what the third question was. Anyway, the company decided to go with another candidate in spite of generally positive feedback.

##The Behavioral Interview For these types of interviews, you are asked to point to specific experiences and examples that demonstrate particular behaviors. "Tell me a time when you..." questions.

Before I interviewed, I reflected on my jobs and tried to pick good examples of leadership, teamwork, and negotiation. These aren't always stories that made me look good. To answer some questions, I deliberately picked stories that I learned from, like when I stayed up too late shipping on a tight deadline. Or when I failed to catch a rather large edge case, that kind of thing. For me, the most important thing in finding stories was finding meaty examples that I could talk about, analyze, and discuss in detail. Truthfully, the stories got better the more I practiced, which is another reason I planned on doing a ton of practice interviews with real companies.

If you don't have any of those types of stories, perhaps trying to create opportunities for yourself at your current role could help. Ask your manager for guidance. Come up with a proposal. Show some initiative and makes a good story.

##Big Tech And then I did an onsite with Google, which was truly mentally exhausting. It was actually the most challenging interview I've done to date because it is just so long and because there's so much time spent under duress at a whiteboard. Four technical, algorithm-y problems and a behavioral session. I ended up getting through most of the problems with some prompting and hints, but by the end of the day, I was so drained that I walked to the nearest Ample Hills and bought myself an ice cream cone. I didn't end up getting the job, but I'm proud to say that I survived.

Self-Care and Dealing with Disappointment

As you might have discerned, my job search process had its ups and downs, but a lot of the factors were out of my control.

For some companies, their hiring needs changed. Others decided it wasn't a good fit or the interviewers didn't provide "enough positive feedback" to move forward.

For yet another company, the recruiter promised to follow up with next steps the following day and then I didn't hear from them again for months, despite my follow-ups.

So things happen. You can't really get upset about failure and disappointments when you really gave it your best shot. Failing to get a job doesn't make you any less of a good person or programmer. Maybe you had an unfair question or a particularly nasty interviewer. Don't beat yourself up about it. Just assess if there's something you can improve, work on it, and move on.

But I did want to note that you can and should take some time to process your feelings and reward yourself. I love ginger beer and ice cream and I definitely indulged myself if I had a particularly rough experience. I also made sure I reserved time to have fun and see friends. I read a ton of fiction and also watched a bunch of TV to unwind because job searching is just plain stressful and you shouldn't burn yourself out on it.

Dealing with Offers

Getting offers is great! Just from my experience, it pays to be super straightforward about your timeline and your salary expectations. If I end up declining an offer, I always express my gratitude and try to keep the door open in case something changes in the future.

If I end up accepting an offer, I of course try to negotiate. Whether that's on salary, bonus, PTO, or a later start date, it pays off to negotiate.

After being burned out at my current role, I decided that I needed to take some extra time off between jobs, and my new gig was super accommodating and respectful of that. So figure out what you need and ask for it. The worst thing I did to myself was to jump into a new job immediately without taking any time.

tl;dr tips without context

Okay, so you've reached the end of this very long post! Congratulations. Here's a summary to take with you on your next job search journey.

  1. Make some sort of plan and rough timeline.
  2. Catch up with your friends and former colleagues as a form of networking.
  3. Do some studying, even if it's just a little.
  4. Review your job experiences and projects and look for meaty stories that you can talk about in a behavioral interview. If you don't have any, see if you can angle your way into those types of opportunities at your current role.
  5. Buy your own whiteboard markers and carry them with you to interviews.
  6. Make sure you take breaks and treat yourself and see friends. Interviewing is stressful.

And that's about it. That's what it takes to survive the software engineering interview in 2020.