Zheng Hao Tan

Ace That Technical Interview - An Interviewer's Perspective

Ace That Technical Interview - An Interviewer's Perspective

Date published: January 15, 2020

There are lots of articles on the Internet on how to best prepare for software engineering interviews, but none of them communicate the expected actions, as well as how and why they are important from an interviewer's perspective.

"Ask questions and speak out loud" is sound advice but what does that really mean? I've been on both sides and have conducted several myself ranging from startups to larger engineering organizations, and I can tell you the questions and expectations vary widely based on company size and project requirements.

Let's dive right in.

Questions

When you're first given a coding problem, we want to know if the candidate is asking questions. After I give you a couple examples on how the program should behave, here are examples of what runs through my head:

  1. Does the candidate test his/her understanding of the question by presenting his/her own toy example with the right outputs?
  2. Is the candidate thinking about edge cases? Did he/she ask for them?
  3. Are the inputs always valid? Examples include "does the given array index won't have values greater than the given array size?". Does a solution always exist, so we won't have to account for it? If that's not the case, how should we handle it? Should we throw an exception? What about a return value of -1?
  4. How large do we expect the inputs to be? Can you assume it fits in memory? What data types do you need? Are all input values non-negative?
  5. Can the input container(s) be modified?
  6. How should you represent the outputs? A 2D array of ints? What about a set of results? Should they be in some uncommon, serialized format like it being encoded in a string?

The rationale for question asking is going through this stupid role play to know you're an engineer who knows how to ask for the right details. We can't have you take on a huge project, you dive right into implementation without flushing out requirements beforehand, only to realize it's wrong and have to redo work that already cost months of engineering resources.

First Stab Solution and Refinement

Interviewers don't generally expect the best solution immediately after asking it. Heck, if you do it too fast, we'll be suspicious that you've already solved the question before, and some might even insist on giving you a different problem to solve. There's an iterative component to the technical interview process as we work together in pursuit of tackling the problem itself.

We want to know how you're like working in a team. Is the candidate open to new approaches to solve the problem? Is the candidate able to articulate his/her approach clearly?

Explain your "first" solution by "drawing" out how the algorithm works on the whiteboard or type it out for phone interviews. Do this before writing any code. We'll work together if there's a better solution. Once we've converged on something, then we can proceed with writing some code.

Divide and Conquer

For questions with several steps like precomputation or validity checks, for example, coordinate out-of-bounds checks to do in a nested loop, we want to see if you can break the problem up into smaller chunks. Break down the functions/routines and give these function signatures good and explicit names. Make it as granular as possible. It's more readable and better for production code.

Quick tip: I generally prefer to handle error handling cases later on. I like to stick a // TODO: error handle there while I implement the core logic. Once I'm done with the first pass, I'll go over it the 2nd time to implement error handling. Some problems also have lots of verbose steps and are generally trivial to implement, so you may get lucky as the interviewer might tell you to skip implementing them.

Code Hygiene

I talked briefly about having good, explicit function names above, but you should definitely do the same for variable names as well. Avoid heavily nested conditionals and loops as well. It's no fun trying to follow what the program is supposed to do. You wouldn't write such code in production too, so don't do it in an interview.

Too many candidates fail to keep their implementation together not because they don't know how their algorithm should work, but their poor variable names and functions that do "too much". Their implementation often confuses interviewers and themselves in the process, and that makes it hard for us to even jump in and help.

Depending on which software engineering role you're interviewed for, don't be surprised to get some domain specific stuff nitpicking. An interviewer might question your use of dynamic memory allocation for a firmware engineering role, or why you're not moving some variables with std::move for C++11 roles.

Don't Forget to Test!

Once you're done with the implementation, remember to test it!

Start your first test case with small or invalid inputs. Some problems, especially tree and graph traversal problems, can get quite complicated to do by hand with large inputs. Small inputs are easier to use to walk through your implementation. Once you've verified it works, try out edge case tests as well. We're not expecting your code to be bug free on your first attempt. Most candidates don't get a correct implementation the first pass, but we want to know you're able to troubleshoot and resolve issues from your own work if it's buggy.

Remember how I mentioned that I like candidates who break functions and practice good code separation? It's easier to debug just in case you introduced some bugs here. In other words, you can "gate" some functions/methods to be correct, think of them as invariants and narrow down the issue a lot faster than if you wrote messy code.

Tips and Tricks

Having interviewed a couple times over my career, here's a couple more tricks I've learned.

Bring your own whiteboard markers to onsite interviews. You'll be surprised how lucky you are to get a marker that's operating at full ink. The last thing you want to do during a coding whiteboard exercise is to fight a whiteboard marker by drawing over the lines several times than actually solving the problem! Don't forget the high costs of mental context switching needed here. Just buy some off Amazon. Use a thinner tip, so you'll naturally have smaller handwriting, and that in turn will fit more code on the whiteboard.

Given a choice between a laptop and a whiteboard, I generally prefer the whiteboard. It's easier to draw and illustrate concepts like linked lists, trees or graphs. It's also easier to edit code by erasing and drawing arrows etc.

Closing Thoughts

There's a few things I left out from this piece such as data structure choices, "algorithms you should know" and space + runtime complexities. I don't have much to add aside from asking you to consult several other guides and actually brush up on your data structures and algorithms.

At the end of the day, the interviewer wants to know if you're a careful and reliable software engineer. We ask ourselves: "Can the candidate scope out the problem successfully? Can the candidate seek truths amidst some unknowns? Can the candidate figure out good enough solutions or workarounds to keep him/herself unblocked, then execute on it until completion?". It boils down to this, but there's a minimum skill level needed to get there, and technical interviews are meant to evaluate just that.

I know it's a noisy process. It's unfair to evaluate one's technical skills in these one hour sessions. That said, I think it's still the least worst way to do so (I plan to cover this with a separate blog post at another time).

I hope the questions above will help you think in our shoes. If you can close the gap between your interview performance level and what interviewers want out of you, there's a higher chance you'll get a Hire decision from him/her. Good luck!