How to approach a technical interview question

Matt Gruber
8 min readMay 3, 2020

--

During the past two years of conducting interviews, I’ve often seen candidates struggle with breaking a question into solvable pieces. Breaking down problems is a necessary skill for interviewing and essential for everyday work as a Software Engineer.

Photo by Chris Ried on Unsplash

Problems in the Real World

Part of software engineering is refining requirements and understanding the use case you are solving for. The real world is not like a class where you are told what to do in detailed steps. You must learn to take a high-level problem and convert that into requirements otherwise you will be challenged to move beyond a junior role as a software engineer.

When I first started work out of school I was overwhelmed by a task like “Create a user profile page.” Where do I put the files in the codebase? What should the UI look like? What information should be on this page? How long should this take me? Who do I go to for help?

My biggest mistake was trying to solve every question at once. I would try to figure out the questions, answer them all, and then hold all of the answers in my head at the same time. The best way I’ve found to solve a complex task like this is to first break it down.

Writing is your friend for outlining a problem and solution. An interviewee who writes 15 comments before a line of code is more impressive to me than someone who tries to solve the whole thing in their head before writing anything.

Trying to figure out the entire problem in your head before starting makes it hard to… well, start. When every piece of the problem seems important you may end up picking a midpoint of the problem and attempt to work forwards and backward at the same time, only to realize you were solving the wrong problem from the start.

My first step when I’m breaking down a problem is to find the start and end first. If you understand the input and the output it’ll be a lot easier to understand the whole problem than it would be if you started throwing spaghetti at the wall to see what sticks.

Now if I was asked to “Create a user profile page” I would break the task into a list of requirements with an outline before writing a single line of code. Something like (most likely with sublists below each point to break down how I would accomplish those steps as well):

1. A user should be able to click a link in the sidebar to go to the profile page

2. A user should be able to configure their name, photo, and t-shirt size on the profile page

3. A user should be able to save the information and be directed to the home page

Problems in Technical Interviews

I know the above task isn’t something you would commonly find in an interview but I think it demonstrates a couple of important concepts to use when breaking down an interview question before writing a single line of code.

1. Start with the beginning and the end, or input and output.

2. Clarify your questions and assumptions.

Now let’s apply these same ideas to a question that is more likely to be asked in a technical interview. Suppose you’re asked the question: “Create a ranked list of words contained in a given string.”

The first thing you should do is write down the expected input and the expected output. If it isn’t clear to you what either of these are then you should ask the interviewer questions. Questions are a good thing because they help the interviewer determine if you work from assumptions or a shared understanding. It can give the interviewer an understanding of how you pair through problems and work with others. Some questions may be intentionally framed vaguely to test this very skill.

In this case, the input should be a string. But what kind of string? Is the string parsed in a format that you can use to find the expected output? Do you need to parse the string to remove special characters before you can move onto the next step?

You may have a question about the output such as “How should I rank the words?” In this case, let’s pretend the interviewer said they wanted to rank them by the number of uses of a word.

This may generate a follow-up question such as: “Should a word with some kind of punctuation be treated as a word without punctuation?” I.e. Should “car” == “car!”?

Sometimes candidates will assume how this should be based on their mental model of the problem. But it’s important to verify your mental model aligns with that of the interviewer. I’ve never interviewed someone and suggested not hiring someone because they asked a question. However, I have suggested not hiring people because they assumed and didn’t ask.

You build a foundational understanding of the problem by asking questions and working from the start towards the end. You may write something like this at the top of your editor after an initial discussion with the interviewer:

# Input = String of words("car" == "car!")
# Output = Hash of word counts

If the interviewer hasn’t given me a test case as part of the problem than I will ask for one. Suppose the interviewer gives me the example “The old car was faster than the new car!” If for some reason the interviewer won’t, or can’t, give you a test case then come up with your own and ask the interviewer if that test case is sufficient.

I would confirm the expected output with them in this use case, i.e. {"the": 2, "car": 2, "old": 1, "was": 1, "faster": 1, "than": 1, "new": 1}.

Two things to note about this example is that “The” and “the” are treated the same. Similarly “car” and “car!” are treated the same. If you hadn’t previously asked if the input should be sanitized this example output should clarify that for you. If you still aren’t sure, ask.

Now that you have an example and understand the input and output you can begin to break down the problem into a pseudo-coded list of instructions that can be converted into lines of code. As you pseudo-code the implementation you should continue to ask the interviewer questions to clarify your assumptions.

A first iteration may look something like:

# Input = String of words
# Output = Hash of word counts
# Take input string and normalize each word
# Return hash of words with count
## Tests
rankWords("The old car was faster than the new car!") == {"the": 2, "car": 2, "old": 1, "was": 1, "faster": 1, "than": 1, "minivan": 1}

While the problem is beginning to become a bit clearer in your mind you’ll want to break down each section further to make each piece as simple as possible.

# Input = String of words
# Output = Hash of word counts
# Take input string and normalize each word
# split input string into array on spaces
# loop over each word in array
# normalize word
# Return hash of words with count
# loop over list of normalized words
# add to hash
## Tests
word_count("The old car was faster than the new car!") == {"the": 2, "car": 2, "old": 1, "was": 1, "faster": 1, "than": 1, "minivan": 1}

This is getting closer to code but you still need to define what normalizing a word means. From the example, you know The and the should be equivalent and car! and car should be equivalent.

Therefore to normalize a word based on the given input, you’ll need to lowercase the word and remove any non-alphabetic characters. At this point, you may ask “Are there any other variations of words I should be normalizing?”. Let’s assume in this case the interviewer replies that your current normalization is sufficient.

# Input = String of words
# Output = Hash of word counts
# Take input string and normalize each word
# split input string into array on spaces
# loop over each word in array
# lowercase word
# remove non-alphabetic characters
# Return hash of words with count
# loop over list of normalized words
# add to hash
## Tests
word_count("The old car was faster than the new car!") == {"the": 2, "car": 2, "old": 1, "was": 1, "faster": 1, "than": 1, "minivan": 1}

From the pseudo-code, you may see that it would be easier to break this problem into two methods. One method to take the input string and return an array of normalized words and one to take a list of normalized words and return a hash of word counts. Similarly, you could combine this into one large function or smaller ones that have less responsibility such as a function whose sole purpose is to normalize each word.

Implementing this with two functions may look something like:

# Input = String of words
# Output = Hash of word counts
# Take input string and normalize each word
def normalize(string)
# split input string into array on spaces
word_list = string.split(" ")
normalized_word_list = []
# loop over each word in array
word_list.each do |word|
# lowercase word
lowercase_word = word.downcase
# remove non-alphabetic characters
normalized_word = word.gsub(/[a-z]/i, "")
normalized_word_list << normalized_word
end

return normalized_word_list
end
# Return hash of words with count
def word_count(word_list)
word_count_hash = {}
# loop over list of normalized words
word_list.each do |word|
# add to hash
if word_count_hash[word].present?
word_count_hash[word] = word_count_hash[word] + 1
else
word_count_hash[word] = 1
end
end

return word_count_hash
end
## Tests
word_count("The old car was faster than the new car!") == {"the": 2, "car": 2, "old": 1, "was": 1, "faster": 1, "than": 1, "minivan": 1}

You’ll notice my pseudo-code doesn’t map 1–1 with lines of code. That’s alright, the pseudo-code is meant to be a framework to build off of. I will commonly make deviations from my pseudo-code as I gain a better understanding of the problem I’m solving for.

Additionally, you’ll notice I used regex and a gsub to remove non-alphabetic characters in my first function. If you don’t know how to do this offhand ask your interviewer if it is alright to use google. Most likely they’ll say you can as using google to solve software problems is something most engineers do every day. (Just don’t google “How do I count the normalized word counts of a string using ruby.”)

Key Takeaways

The key takeaways that I hope you implement in your next coding challenge are the following:

1. Determine the input and output.

2. Clarify your questions and assumptions.

3. Ask for examples and confirm the results.

4. Continue to break the problem down into an outline you can work through before you start coding anything.

If you’ve found this article helpful or lacking in any way please leave a comment! Any feedback, especially pointing out the flaws in my thinking, would be super helpful!

If you want me to help you break down any other problems feel free to leave a comment as well and I’ll do my best to walk you through how I would go about tackling the problem.

--

--