Java interview task that actually makes sense

My experience as a candidate and interviewer

I have worked for 10 companies so far. The longest period was about 2 years, while the shortest was only 3 days. On average, I participated in 3 recruitment processes when looking for a job. Each process had an average of 2 technical stages, with most having 4 stages (code refactoring, coding task, discussion about the coding task, and system design), and the least having only 1 stage. Simple math tells us that I participated in about 60 technical recruitment meetings as a candidate. (I suspect there were slightly more, but let’s stick to the average).

Over the past years, I have also participated in technical interviews as an interviewer. In some companies we recruited very heavily, so there were about 8 interviews per week, in others 4 per month. Sometimes I had complete freedom in the way I conducted these interviews, other times we had a pre-prepared list of issues I should have covered.
I have a lot of trouble estimating how many such interviews I had, but let’s assume another 60.
(Here again I have the impression that there were more).
In the end, I can conclude that I took part in more than a hundred recruitment meetings, but rather less than two hundred.

How to quickly and effectively distinguish candidates with potential from those without?

Over time, attending many recruitment meetings can become tiresome. As a candidate, you may want to get them over quickly, and as an interviewer it can be challenging to stay focused during each meeting. Based on my recruitment experience, I recommend a valuable solution for both parties. As a first technical step in recruiting for Java/Kotlin programming positions, I suggest using a code refactoring task:

import java.io.*;
import java.util.Optional;

/**
 * This class is thread safe.
 */
public class ParserFacade {

    private static ParserFacade instance;

    public static ParserFacade getInstance() {
        if (instance == null) {
            instance = new ParserFacade();
        }
        return instance;
    }

    private File file;

    public synchronized void setFile(File f) {
        file = f;
    }

    public synchronized Optional<File> getFile() {
        if (file != null) {
            return Optional.of(file);
        } else {
            return null;
        }
    }

    public String getContent() throws IOException {
        FileInputStream i = new FileInputStream(file);
        String output = "";
        int data;
        while ((data = i.read()) > 0) output += (char) data;
        return output;
    }
    public String getContentWithoutUnicode() throws IOException {
        FileInputStream i = new FileInputStream(file);
        String output = "";
        int data;
        while ((data = i.read()) > 0) if (data < 0x80) {
            output += (char) data;
        }
        return output;
    }
    public void saveContent(String content) throws IOException {
        FileOutputStream o = new FileOutputStream(file);
        for (int i = 0; i < content.length(); i += 1) {
            o.write(content.charAt(i));
        }
    }
}

You only need to refactor the code and provide a document with comments explaining the changes you made. This will allow others to understand your thought process. It’s also recommended to add a note similar to: Usually, only a few things are truly valuable in terms of traits like maintainability or ease of change, even though there may be a million technically feasible options.

Why the task actually makes sense?

If the following task is placed in the hands of a candidate who knows the basics of language features and object-oriented programming paradigms (which is not that obvious at all), he will know how to approach it within 10 minutes.
The reviewer upon receiving the solution within 10 minutes will know who he is dealing with.
A huge saving of time, money, health- simply life, for each party.

What exactly are we checking in this task?

The above task is designed to test several skills in one go:

  • Basics of multithreading and thread safety. The first comment says: This class is thread safe which is obviously not true. However, it is up to the candidate to explain why he thinks so and what obvious mistakes were made.
  • Basics of design patterns. Name of the class suggests Facade design pattern. Yet the code not necessarily reflect the usage of the pattern. If the candidate is familiar with design patterns, should be able to understand the author’s intentions after the first 10 lines of code.
  • Basics of Java language. In the original code we can see famous getter and setter. Even at first glance, we can see that something is wrong with them…
  • Basics of how String works internally in JVM. For someone who does not have a clue about the subject, the code will seem fine. For someone who knows the basics, the solution using StringBuilder will seem obvious. Someone with extensive knowledge of the JVM could tell here a bit about the innovations introduced in JDK9 and invokeDynamic.

    The implementation

    The source code, as well as my solution recommendation, can be found here

    Summary

    I want to be clear that this task is not the best recruitment task, nor am I suggesting that it should be used. I am simply sharing my experience from the many recruitment’s I have participated in. The task serves as an invitation to the interview and a warm-up for the next stages. In my opinion, this is a valuable warm-up exercise. It helps us quickly identify candidates’ current knowledge level in various areas.In addition, by giving feedback to the candidate, we are able to very clearly and explicitly point out to him the places that we think need improvement (if any, of course).

    Leave a Comment