Mastering the Code Pair Interview
Tags: coding, interview
Published: 2020-04-30 05:00:13

Many companies incorporate a code pair exercise where the applicant must solve a coding riddle. I gave 50+ of these as the interviewer before myself needing to enter the job market where I interviewed with more than a dozen companies and completed many code pair exercises as part of the interview process. In this article I attempt to demystify this process, explain what interviewers want to see as well as provide some strategies for mastering the code pair interview.

## The Process

An applicant will typically go through one or more screening calls before being assigned a code pair exercise. Sometimes the applicant will receive a takehome assignment before the code pair exercise. If the applicant passes these initial screenings then the next step may be a code pairing exercise. 

Code pairing exercises range from super simple to devilishly complex. Typically the level of the role you are applying for will largely dictate the complexity of the problem, but some companies prefer to give difficult problems to see how candidates perform under pressure. However, even easy questions can be a strong source of stress for the nervous applicant. 

After meeting the interviewers the applicant will typically be asked to log into a code pairing website where everyone can see the code as it is being typed and run the code to receive a result. Some requirements and often times some data is provided to the applicant and some, _but not all_, requirements for a correct solution listed. Usually standard input and output functions of the language (e.g. printf or console.log) are used to output results. The applicant is given a set amount of time to complete the exercise and achieve the correct output.

Sometimes there will be follow up requirements if the applicant solves the exercise early.

## The Anatomy of a Code Pair Exercise

There are many pre-existing repositories of coding problems to choose from but also common for individual interviewers or companies to have their own set exercises. Fear not because of the format of code pairing exercises there tends to be a limited set of problems companies can reasonable expect applicants to finish assuming a 30-60 minute window. 

The most common exercise will involve the applicant working with some data (lists, objects, strings, numbers etc..)-- either to generate data, transform data or both. The goal of the applicant will typically be to map requirements into code that is generating and/or consuming some kind of data and to achieve the expected output.

The traditional code pair exercise revolved around core CS data structure concepts, e.g. all the kinds of trees and lists. My experience is that these sort of questions are not used much anymore. 

In the end the applicant is being asked to implement an algorithm to carry out a task. There will usually be preferred algorithms (solutions) that are kept hidden from the applicant. It is task of the applicant to create a solution within the time period but also the applicant is being judged on much more than their code! 

Interviewers want to see how the applicant approaches problems, listen to their thought process and be able to discuss multiple solutions. Knowing what interviewers are looking for will help the applicant pass the interview even if the exercise was not completed.

## Preparation

Understand the language you will need to use for the exercise. Sometimes there is a choice and other times the preferred language of the role is used. Be able to write code in the chosen language without needing to lookup language features and syntax during the exercise. The goal should be to spend the majority of the time on the problem, not fighting the language. 

Understand algorithms and data structures. Interviewers are often looking for certain key phrases and these key phrases will all be found in the wonderful world of algorithms and data structures. If you feel like you need a refresher or need to know more, check out these free courses online:

 - https://www.coursera.org/specializations/algorithms
 - https://www.coursera.org/learn/data-structures

Because of the open nature of code pairing exercises one can never really be fully prepared, but there are many things one can do to be ready. It shouldn't need mentioning but obviously be well rested. Try to schedule the interview at a time that is convenient. Have water and/or coffee at the ready. Expect to do a fair amount of talking during the interview.

## Understanding Requirements

The applicant is often given incomplete requirements. Ask questions! Asking the right questions to clarify the requirements is often part of the excercise. 

If your exercise involves transforming data, a good first questions is to ask, "can I assume that the data is always correctly formatted or do I need to account for bad data". This is a great question because usually the answer is to assume that the incoming data is always correct. This will save a bunch of time. A good response is "Thanks! I'll assume that the data is coming from a well tested module."

## Finding Solutions

The quickest way to find a solution to a given code pairing exercise is to google the requirements. Chances are the question being asked has already been documented and solved in multiple languages. But let's assume you are not going to be able to do so. After all the applicant is being watched. Don't assume that just because you are remote that no one will notice the darting of eyes or the reflection of another screen at the ready. 

Have a plan! First off do a systems check. Make sure code can be run and results returned. Next, start clarifying requirements.  Document any changes to requirements. Next, write stub function/class which to create a general outline that needs finishing. Try to keep talking. Discuss naming. Otherwise just talk through what you are doing. Next, write some failing tests. TTD (Test Driven Development) is not nearly as popular as it once was so the test is not to show that you know TDD (but feel free to mention it if you want!) but to _make sure there is a test written_ in case you run out of time. Having a test, like code comments, is part of writing good clean code which is the end goal.

After thinking through the requirements and asking questions, hopefully a plan is forming. A standard question of the interviewer will be to question the applicant on their solution's time and memory complexity (big O notation-- see algorithms). Get in front of those questions and declare the complexity of different approaches. At this time, don't about follow up requirements. The first goal is always to achieve a working solution for the presented exercise. 

Write down your plan as rough pseudo code as code comments. It's OK to be a little vague if some part of the plan is unknown. Mark it as such and move on. 

Now the real challenge begins.

Most solutions will involve some amount of iteration-- either a for loop, do...while loop or some kind of recursion. Look for a solution in that order. A for loop is safest because they tend have defined entry and exit parameters. do...while loops are common in these exercises but caution is needed when using them both in a code pairing exercise and in real life! Be sure to really think about how to exit a do...while loop else spend extra time dealing with a locked/crashed program. Recursion is usually a trap both in a code pairing exercise and the real world. When reaching for a recursive solution, additional requirement clarification is needed. The problem with a recursive solution is that they depend on the execution stack which tends to have much smaller memory footprint than the heap which is where general memory allocations come from. Fret not! Recursive solutions can typically be converted into a loop and a stack allocated on the heap to maintain the state stored in the execution stack of a recursive algorithm. 

If the current solution involves iterating over the same data over and over then this is a sign that the solution is not going to be time and/or memory efficient. At this point take a step back and consider how fix it. The question will come. If this problem is identified early enough and there is enough time, switch to the a more efficient solution. If you are already well through your existing solution then I recommend completing the assignment as-is but first document the limitation and if possible, the solution as code comments.

By far, the most common solution to resolving time complexity is through the use of a hash map. Be on the lookout for ways to use a hash map to avoid having to re-iterate over data by looking up data in the hash map by key. Often times the solution involves specific methods for generating those keys for the hash map. Another other common solution to resolving complexity is through use of an up-front sort. Always look to see if the problem can be solved efficiently if the data was in a certain order. Sometimes the answer involves both! In my last set of interviews I had a couple of solutions that involved using a hash map and sorting a small data set (2 or 3 variables) to use as a key. 

## What To Do When Stuck?

We'd all like to ace these problems effortlessly with a correct and efficient solution. If that happens then great! If not, then don't panic! Getting stuck is completely normal and often expected. 

I think the most important thing to do, and this takes practice, is to talk out loud as much as possible. Avoid "dead space" where there is no typing and no talking. Always be doing one or both! Usually when I'm stuck I start by talking out loud what the code I have so far does. Hopefully at this point you already have a general plan and some pseudo code. If I don't know what to do I will often simply compare my own code to the psuedo code. The questions I will ask myself are "Does my code implement the pseudo code?" and "What am I missing?". Maybe the pseudo code was incomplete. Add more detail if possible.

There is no shame in admitting you are stuck. Simple say or type "I am stuck _here_" where _here_ is a specific spot in the code. I would try to avoid asking for a hint too early on. Often times you can get hints without asking simply be talking through the problem. Listen and watch the interviewers. Look and listen for confirmation that an idea is correct or incorrect. If there are no "free" hints then ask for a hint. While it will be noted it is not necessarily a bad thing. After all no one wants software developers that spin their wheels and don't ask for help.

If no actionable hints are forthcoming and there is still more to implement-- then finish what parts of the solution you can. If you can create smaller tests for some part of the solution then that is better than providing no solution at all.

## Final Touches

No matter if the exercise is solved or not there are certain attributes a final solution to have. Usually the final code will be saved to be reviewed later. There should be tests and their should be code comments. My experience is that most applicants write code with zero code comments or with little testing. Having participated in many of the discussions that applicants are not privy to I can state unequivocally that good code carries more weight than a correct solution. Think of it this way... If there are multiple applicants with the correct solution, then the applicant with better code wins. In addition, I would be more interested in an applicant that wrote clean, well commented code over someone who quickly banged out a solution. There is always an assumption that the applicant might already know the solution in which chase a bare bones solution might look like a solution that was from rote memory rather than a creative enterprise.