Why do software engineers struggle to write “chunks” function?


In the last couple of years, I took close to two hundred interviews. These interviews range from Java engineers with two years of experience to architects holding more than fifteen years of experience. The first round of our interview process, irrespective of the candidate experience, involves solving a small problem in a Google document. 

I prefer Google docs because it removes the unnecessary fluff and most candidates are familiar with it. I understand that you may feel awkward and conscious when someone watches you while you are writing code. At the same time, it does give some understanding on how candidates keep calm under pressure, recover from their mistakes, and explain things.

I don’t expect people to write completely syntactically correct formatted code in Google docs. I give them 20 minutes of peaceful time to write the program. I once read that in other tech organizations, it is expected that you explain your approach and your thinking as you write code on a whiteboard (virtual or physical), but I prefer to give people an uninterrupted time so that they don’t have to do two things at a time. I try to make sure that they have understood the problem by giving them a couple of inputs and their expected output. 

One question that I have used in most of our L1 interview rounds is shown below. Since 2021 I have stopped using this question so I thought it can be useful to share my analysis on how people performed in attempting this problem.

You have to write a function that chunks an array into smaller arrays of specified size. For example, chunks([1,2,3,4,5] , 2) should return [[1,2],[3,4], [5]].

Coming up with your own “Fizz Buzz Test”[1] is not easy. I came up with the following requirements on which I evaluate such coding questions [2].

  1. It should be a real problem. The kind of problem you solve in a real-world scenario.
  2. It should feel simple and give confidence to the developer that they can solve it.
  3. The solution should not require more than 20 lines of code.
  4. The problem should not be domain specific that it gives advantage to some candidates.
  5. It should not require any special data structure, which you don’t use in your day to day work.
  6. Problem should not have a long text. Anyone should be able to read the problem text in less than a minute.
  7. It should not require knowledge of a special library function.
  8. A reasonable developer should be able to write the first version in 15-20 minutes. Candidates do tend to miss a few aspects of the problem, so it can involve more than one iteration.

I have used this question for evaluating Java candidates only. It is possible that it is not a good question for your specific programming language. So, please keep this point in your mind.

There are three skills that I am trying to evaluate about the candidate.

  1. Can they code?
  2. Can they explain the code they have written?
  3. Can they explain how they will test the code they have written?

Coming back to the chunks problem, one possible Java solution is shown below.

public static int[][] chunks(int[] numbers, int chunkSize) {
   int length = numbers.length;
   int resultArraySize = (length % chunkSize == 0) ? length / chunkSize : length / chunkSize + 1;
   int[][] result = new int[resultArraySize][];
 
   int numberArrIndex = 0;
   for (int i = 0; i < resultArraySize; i++) {
       int chunkArraySize = i == resultArraySize - 1 && (length % chunkSize != 0)
               ? length % chunkSize
               : chunkSize;
 
       int[] chunk = new int[chunkArraySize];
 
       for (int j = 0; j < chunkArraySize; j++) {
           chunk[j] = numbers[numberArrIndex++];
       }
       result[i] = chunk;
   }
   return result;
}

Java 8 solution using the Stream API is shown below. I don’t expect candidates to write this version.

public static int[][] chunk(int[] numbers, int size) {
   return IntStream.iterate(0, i -> i + size)
           .limit((long) Math.ceil((double) numbers.length / size))
           .mapToObj(cur -> Arrays.copyOfRange(numbers, cur, cur + size > numbers.length ? numbers.length : cur + size))
           .toArray(int[][]::new);
}

My analysis is that only 10% of the total candidates solved the problem correctly in the first attempt. 30-40% missed a few scenarios and while explaining the solution they figured out the gaps and suggested improvements to fix their first version. And, remaining 50% failed to write even the partially correct first version. 

Following are my observations on the attempts made by people:

  • Candidates for some reason choose a function name different from chunks. I fail to understand why they don’t use function name as chunks. Some of the names used by candidates getSmallArray, getChunksArray, getMeArray, getRefactorArray, getChunks, splitArrayInChunks, convertArray, splitArray, chunkInputArray, etc.
  • Candidates who did well in the attempt first wrote chunks algorithm in plain English and then attempted to write code.
  • Candidates struggled to come up with the correct function declaration in the first go. They directly wrote the first version of the problem and then came up with the correct declaration.
  • Many candidates struggled with multi-dimensional array syntax. 
  • The first solution written by most candidates didn’t handle the last chunk correctly. They created all chunks with equal size. So, the answer returned by their solution is [[1,2], [3,4], [5,0]]. Some candidates while explaining the solution with the example input figured out the problem and explained how they will handle this scenario.
  • Candidates struggled with the size of the result array. They need to consider whether the array is fully divisible by chunkSize or leaves a remainder.
  • Some candidates at times used String. They failed to make much progress.
  • Candidates make chunks an instance method of some class. They don’t think whether they should make the method static. For some reason, they think static is bad.
  • Some candidates prefer to convert an array to a List and then only they can write code. 
  • Java developers still struggle with Generics. Only a handful of them were able to convert the program to a version that uses generics.
  • Only a handful of developers can eloquently explain the code they have written. 

By no means I am underestimating the pressure of giving an interview. Both taking a good interview and giving an interview are difficult. I know it is hard for most of us to write code when someone is watching us in an interview. But, given that this is the kind of code we write everyday and we do have to pair with others. I think it is still a better and scalable way to filter good candidates from average candidates. 

References

  1. Fizz Buzz Test – Link
  2. Picking problems for programming interviews – Link

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s