Running on Java 24-ea+21-2447 (Preview)
Home of The JavaSpecialists' Newsletter

265Threading Questions in Job Interviews Part 1

Author: Dr. Heinz M. KabutzDate: 2019-01-02Java Version: 11Category: Concurrency
 

Abstract: Asking detailed threading questions during an interview is like asking a football player to prove that he can sing well. Not necessarily relevant to their job description. And yet we see this commonly for Java jobs. In this newsletter we consider more than a dozen real questions that technical interviewers have asked.

 

Welcome to the 265th edition of The Java(tm) Specialists' Newsletter, sent from the Island of Crete. Only 363.5 days left until 2020. Let's not waste a single one of them.

It is rare for a top Java programmer to stay unemployed for long, except by choice or life throwing them a curveball. Companies around the world compete for the best brains in our industry. However, a lot of capable Java programmers flunk their job interviews, sometimes on irrelevant questions. Before I go on, if you are interested to find out how the job industry works amongst programmers, I strongly recommend Best Developer Job Ever! [ISBN B07FNFG5LQ] by Bruno Souza. I read the first proof copy whilst sharing an Uber with Bruno en route to a Java Community BBQ in San Francisco. A lot of the best jobs that we see advertised are already filled. Bruno Souza explains why. He also gives tips on making sure that this awesome job has your name on it.

javaspecialists.teachable.com: Please visit our new self-study course catalog to see how you can upskill your Java knowledge.

Threading Questions in Job Interviews (1/2)

A few weeks ago, one of my readers told me that they had missed out on a great job, because he was not able to answer a rather basic, but irrelevant, concurrency question. Threading was not part of his job description, but the interviewers were using the question as a coarse filter. This happens frequently and is not really fair.

To help both those looking for jobs and those interviewing potential Java programmers, I compiled a list of actual threading questions used in interviews. We will go through each of these tomorrow the 3rd January 2019 at 16:00 UTC in Heinz's Happy Hour Webinar. Please join the webinar for free. A bit later this month I will write up the answers to these interview questions in another newsletter.

Question 1: Thread Signalling

Without further waffling, here is our first question. What is wrong with this class?

import java.util.*;

public class Threading01<E> {
  private final LinkedList<E> elements = new LinkedList<>();

  public boolean offer(E e) throws InterruptedException {
    elements.add(e);
    notify();
    return true;
  }

  public E take() throws InterruptedException {
    if (elements.isEmpty()) wait();
    return elements.removeFirst();
  }
}

A question like this gives a great opportunity to show that you know how wait/notify works. I can think of at least 5 things that are wrong. Some are more subtle than others.

Question 2: Static Locks

What is wrong with this code? Is there a way to fix it or a better approach?

public class Threading02 {
  private static final Object LOCK = new Object();
  private static Object myObj = null;

  public static Object retrieve() {
    if (myObj == null) {
      synchronized (LOCK) {
        myObj = create();
      }
    }
    return myObj;
  }

  private static Object create() {
    return new Object();
  }
}

Question 3: Fastest Way to Signal

Here is a real interview question, forwarded by one of my readers: Let T1 be the main thread, and T2 be a thread running a never ending CPU computation inside a "while(true)" loop. Assuming that both threads run code which you own and can modify, how would you send a signal from T1 to T2 to stop working and exit?

This is a very good question. There is a quick answer that you can give, which will in all likelihood satisfy the interviewer. Or if you want to show that you really know your stuff, you can show several options that have different performance. It might be best in this situation to ask questions back, such as "Is it guaranteed that there will only be two threads?" and "How quickly after the signal should T2 exit?"

Question 4: Possible Values of Shared int

Another real interview question: Assume C is a shared int (say, defined as volatile int), and assume that T1..T100 are 100 threads, each trying to increase C 1000 times (in a naive get-modify-write fashion). What will be the range of possible values of C by the time all threads terminate?

Question 5: Debounce in Java

This one is a lot harder to get right. There are a zillion ways to code it. I think the point of the question is to see how someone would answer the question. Are they going to copy and paste from an online solution, claiming it as their own? Will they use existing concurrency constructs to maximize code reuse?

Sometimes we want to invoke a method call only once per time interval. Let's start with a simple interface Callback:

public interface Callback<T> {
  void call(T t);
}

The Debouncer would extend that interface, but add the functionality to run the call only once per time interval. Thus if someone calls it 1000 times in a row, we still only call it once. The Debouncer follows the protection proxy design pattern, both in intent and in structure. Since it may start a background thread to manage the actual call, we give it a shutdown() method.

public interface Debouncer<T> extends Callback<T> {
  void shutdown();
}

Implement the Debouncer interface so that the following test passes:

// pass in Debouncer with interval of 1 second
public void test(Debouncer<Runnable> db) throws InterruptedException {
  AtomicInteger rx_count = new AtomicInteger();
  AtomicInteger ry_count = new AtomicInteger();

  Runnable rx = () -> {
    System.out.println("x");
    rx_count.incrementAndGet();
  };
  Runnable ry = () -> {
    System.out.println("y");
    ry_count.incrementAndGet();
  };

  for (int i = 0; i < 8; i++) {
    Thread.sleep(50);
    db.call(rx);
    Thread.sleep(50);
    db.call(ry);
  }
  Thread.sleep(200); // expecting x and y
  assertEquals(1, rx_count.get());
  assertEquals(1, ry_count.get());

  for (int i = 0; i < 10000; i++) {
    db.call(rx);
  }
  Thread.sleep(2_400); // expecting only x
  assertEquals(2, rx_count.get());
  assertEquals(1, ry_count.get());

  db.call(ry);
  Thread.sleep(1_100); // expecting only y
  assertEquals(2, rx_count.get());
  assertEquals(2, ry_count.get());
  db.shutdown();
}

The journey is more important than the correct answer. We should be more interested in how they derived their solution than whether they pass the test. Someone prepared to cheat on their interview question will likely continue that behaviour once hired.

Question 6: Deadlocks

What is the minimum number of threads that you need for a Java thread deadlock?

I heard this question once whilst teaching a course. The students were using it as an interview question.

Question 7: ConcurrentHashMap

Here is a nasty one that another reader sent me: Explain the internal synchronization details of ConcurrentHashMap.

What they are looking for is an understanding of under what scenarios put() and get() don't actually lock the map and similarly what are the scenarios when locking is required. For this question, it is appropriate to ask what version of the JDK we are talking about. We could then expound on the many changes of that versus the other versions. Even if you don't know the exact answer (I certainly don't) we can still give a great response by focusing on the parts we do know.

Question 8: Check Then Act

A question that was recently asked during a real job interview: Explain 5 different check then act scenarios you have implemented in your projects.

Question 9: Possible Outcomes

This question is quite hard and the Dr who sent it to me told me he only uses it when people claim that they know threading well. It's like when someone say on their CV that they like chess (after all, that's the smart person's game), we haul out the chess board and call Yuri to play a game with them.

public class Threading09 {
  static class Foo {
    public int x, y;
    public boolean f;

    public void bar() {
      x = 5;
      y = 10;
      f = true;
    }
  }

  public static void main(String... args) throws InterruptedException {
    Foo f = new Foo();

    Thread t1 = new Thread(f::bar);
    Thread t2 = new Thread(() -> {
      while (!f.f) { }
      assert (f.x == 5);
    });

    t2.start();
    Thread.sleep(10_000L);

    t1.start();

    t1.join();
    t2.join();
  }
}

In the interview, my Dr friend sometimes offers the following possibilities to choose from:

  1. runs and exits with return code of zero;
  2. assertion error;
  3. runs forever, always
  4. runs forever, sometimes
  5. something else

Question 10: wait/notify/join/yield

I like this question: Why do wait and notify methods have to be in Object class whereas join and yield have to be in the Thread class?

It is an open-ended question that allows the interviewee to expound as much as they want to. They could continue talking about signal and await, and explain what yield actually does in Thread.

Question 11: Deadlock Sample

What is a deadlock? Please provide the code sample for deadlock creation.

Interesting question, with a myriad of possible code samples that would demonstrate deadlock. I would start with the simplest case and then show another 3-4 ways to deadlock, or until the interviewer stops me.

Question 12: Deadlock Detection

How do you detect a deadlock?

Again, I would start with the most obvious deadlock, and then move on to those that are really hard to detect.

Question 13: Deadlock Avoidance

How can you prevent a deadlock?

Lots of possibilities here too. I would list them all and then explain the various advantages of each approach.

Question 14: Plain Java Thread vs Managed Application Server Thread

What is the difference between executing code in "plain" Java thread and application server container managed thread?

I think this is another fine question and allows us to talk about architecture and design, maybe even go into what daemon threads are and how they differ from ordinary threads.

Summary

We will go through the questions and discuss them in Heinz's Happy Hour on Thursday the 3rd January 2019 at 16:00 UTC. We will chat in the Happy Hour Slack Channel (Get an invite here). As always, the recording will be made available to paid subscribers of Happy Hour 3 Recordings. However, this time I will also write out the answers in the next newsletter. I am expecting this to be a lively discussion, so try to make the webinar if you can and have time.

Kind regards from Crete

Heinz

 

Comments

We are always happy to receive comments from our readers. Feel free to send me a comment via email or discuss the newsletter in our JavaSpecialists Slack Channel (Get an invite here)

When you load these comments, you'll be connected to Disqus. Privacy Statement.

Related Articles

Browse the Newsletter Archive

About the Author

Heinz Kabutz Java Conference Speaker

Java Champion, author of the Javaspecialists Newsletter, conference speaking regular... About Heinz

Superpack '23

Superpack '23 Our entire Java Specialists Training in one huge bundle more...

Free Java Book

Dynamic Proxies in Java Book
Java Training

We deliver relevant courses, by top Java developers to produce more resourceful and efficient programmers within their organisations.

Java Consulting

We can help make your Java application run faster and trouble-shoot concurrency and performance bugs...