Top 10 Core Java 8+ Interview Questions – Part I

Lately, I have been thinking why shouldn't I complie set of questions that I generally include in interviews for mid-senior level Java Developers. Though I am a big fan of algorithm questions in interviews for developer, I believe including these questions either in screening or half of time in second round interview would give chance to hear about candidate's understanding on core concepts of Java 8+. I like these these questions since they include core concepts in Java that developers use in day to day jobs. 

 

1. How try-with-resource works?

The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

For example, the following snippet writes data to csv file. It uses an instance of BufferedWriter to write data into the file. BufferedWriter is a resource that must be closed after the program is finished with it.

try (Writer writer = Files.newBufferedWriter(Paths.get(RESULT_FILE_NAME))) {
    StatefulBeanToCsv<RecordStat> beanToCsv = new StatefulBeanToCsvBuilder(writer)
            .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
            .build();

    beanToCsv.write(recordStats);
} catch (CsvDataTypeMismatchException | CsvRequiredFieldEmptyException | IOException e) {
    LOGGER.warn("Error while writing csv . . .", e);
}

In this example, because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method StatefulBeanToCsv.write throwing an IOException).

The complete example is available on Github and more info about try-with-resource on Oracle Java Docs.

 

2.  What is memory improvement in Java 8?

In Java 8, PermGen has been renamed to Metaspace – with subtle changes.  PermGen from Java 7 and earlier has a default maximum size of 64 MB on 32-bit JVM and 82 MB on the 64-bit version i.e. PermGen always has a fixed maximum size. However, Metaspace has an unlimited default maximum size i.e. Metaspace by default auto increases its size up to what the underlying OS provides.

Prior to JDK 8, it didn't used to possible to auto increase the size of PermGem. That caused some serious problems with the infamous:

java.lang.OutOfMemoryError: PermGen space

After JDK 8, with Metaspace default settings, since it auto increases as much as it can, you may not see this issue so easily or it takes longer until you notice the symptoms. This is not much improvement since this just push the problem further away without solving it. However, the introduction of Metaspace makes more sense for dynamic class loading and unloading in JEE applications.

More info on java.lang.OutOfMemoryError

 

3. What is immutable object? How can you make object immutable with DateTime API in after JDK 8?

An object is considered immutable if its state cannot change after it is constructed. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state making them useful in concurrent applications. For example String objects in Java are immutables. 

Defining Immutable Objects

The following rules define a simple strategy for creating immutable objects:

  1. Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
  2. Make all fields final and private.
  3. Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
  4. If the instance fields include references to mutable objects, don't allow those objects to be changed:

    • Don't provide methods that modify the mutable objects.
    • Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.

It is good news that new java.time.* api after JDK 8 has Date objects as immutable objects. For example, the Student object in example below is immutable even if the property dateJoined is date object.

import java.time.LocalDate;

final class Student {
    private final String name;
    private final int age;
    private final LocalDate dateJoined;

    public Student(String name, int age, LocalDate dateJoined) {
        this.name = name;
        this.age = age;
        this.dateJoined = dateJoined;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public LocalDate getDateJoined() {
        return dateJoined;
    }
}

public class TestImmutable {
    @Test
    public void testImmutableObject() {
        Student original = new Student("Yogen", 23, LocalDate.of(2016, 5, 1));

        LocalDate modifiedLocalDate = original.getDateJoined().plusYears(2);

        Student expected = new Student("Yogen", 23, LocalDate.of(2016, 5, 1));
        assertEquals(expected, original);
    }
}

The code from above example is available on Github.

 

4. How HashMap works internally?

This has been very popular question for all level of experienced Java developer. In short, HashMap has array of a linked lists.

To insert an element, a key and value, we do the following:

  1. First, compute the key's hash code, which will usually be an int. The two different objects could have the same hash code, as there may be an infinite number of elements and a finite number of ints.
  2. Then, calculate the index in the array using hash code using modulo as hashCode (key) % array_length. Here, two different hash codes could map to the same index.
  3. Get the linked list at this index calculated above. Store the element in this index. The use of a linked list is important because of collisions: you could have two different keys with the same hash code or two different hash codes that map to the same index.

Please checkout this article for the detail explanation with example implementation.

 

5. What is daemon thread? How to make a thread as daemon? What is difference that comes with worker thread?

Daemon threads are service providers for user threads running in the same process. So, when all of the user threads complete, daemon threads terminates automatically. A daemon is simply a thread that has no other role in life than to serve others. Examples are timer threads that send regular "timer ticks" to other threads or threads that clean up stale cache entries.

You can turn a thread into a daemon thread by calling setDaemon(boolean) method on your normal thread object as:

thread.setDaemon(true); // Call this method before starting the thread

The difference that daemon thread comes with worker thread is JVM gives preference to worker threads that is created by us and doesn't wait for daemon threads in order to exit. Hence, a daemon thread should never be used to access a persistent resource such as file or database since it can terminate at any time, even in the middle of an operation.

 

Conclusion

This compilation is on the basis of my experience. I will come with part II for rest of 5 questions. Meanwhile, please add what you think is important to include in Java Core interview questions.