Hero Image
- Mihai Surdeanu

(#2) Tricky Java Questions for Interviews

Motto: Play a bit with code and with functional interfaces!

Q1: Take your time to study the given code. After you managed to figure out what’s his purpose, you have to think about possible improvements in terms of performance. What happens if tomorrow stream() is replaced with parallelStream()?

public class Main {

    public static void main(String[] args) {
        List<Double> sqrtValues = new ArrayList<>();

        Arrays.asList(2.0d, -1.0d, 4.0d).stream()
                .map(Main::safeSqrt)
                .forEach(computedValue -> computedValue.ifPresent(sqrtValues::add));

        System.out.println(sqrtValues);
    }

    public static Optional<Double> safeSqrt(double value) {
        if (value < 0) {
            return Optional.empty();
        }

        return Optional.of(Math.sqrt(value));
    }

}

Q2: Look at the source code illustrated below. Can you decide if there is any difference from performance perspective between choosing option 1 or 2 to implement a simple mechanism to count the number of requests made by the clients? As a hint, think about the volume of calls and how synchronized keyword behaves when two threads are trying to update in the same time the total number of requests.

Bonus: Do you know another alternative for implementing a simple counter? (Hint: new class introduced in Java 8)

public class Main {

    private Object lock = new Object();

    private int requestsMadeOpt1 = 0;
    private AtomicInteger requestsMadeOpt2 = new AtomicInteger(0);

    public static void main(String[] args) {
        // Multithreaded environment where number of requests are incremented for each request
    }

    // Option 1: Increment number of requests made by the client using synchronized keyword
    public void incrementRequestsMadeThroughSynchronized() {
        synchronized (lock) {
            requestsMadeOpt1++;
        }
    }

    // Option 2: Increment number of requests made by the client using Atomic variable
    public void incrementRequestsMadeThroughAtomic() {
        requestsMadeOpt2.incrementAndGet();
    }

}

Q3: To mark an interface as a functional interface, is well known the fact that annotation @FunctionalInterface should be added to your interface. But if you deep dive into JDK documentation, you will see that @FunctionalInterface is not mandatory at all. Having this in mind, can you present all benefits of putting the annotation even if its not mandatory? Moreover, do you know the reason why the annotation is optional?

Other Related Posts:

Microbenchmarking with Java

Microbenchmarking with Java

Hello guys,

Today, we are going to continue the series of articles about Java ecosystem. More specific, today, we are going to talk about JMH (Java Microbenchmark Harness).

2nd Apr 2022 - Mihai Surdeanu