in

14 Frequently Asked Java Interview Questions and Answers [2023]

default image

Getting ready for a Java developer job interview? You‘ve come to the right place! Acing the interview requires being prepared to intelligently discuss both core Java concepts and programming best practices.

In this comprehensive guide, we‘ll explore some of the most common Java interview questions and provide the details you need to master thoughtful answers.

Why Reviewing Java Interview Questions Matters

Java remains one of the most in-demand programming languages sought after by companies big and small. With enterprises relying on Java for critical systems and apps, it‘s no surprise that Java developer interviews require demonstrating deep knowledge.

The good news is that many Java interview questions focus on the same fundamental topics. By reviewing explanations and examples for the most frequently asked questions, you can walk into the interview room with confidence.

Let‘s get started!

Core Java Interview Questions and Answers

Q: What is the difference between an abstract class and interface in Java?

While both abstract classes and interfaces cannot be instantiated directly, they differ in their implementation contracts.

An abstract class allows defining concrete and abstract methods. Concrete methods have method bodies, while abstract methods only have signatures and must be implemented by subclasses. Abstract classes can have fields and constructors.

An interface only allows method signatures and constant variables. The implementing class must define all interface methods. Interfaces cannot have constructors.

So in summary:

  • Abstract classes provide a partial implementation, whereas interfaces are blank contracts.
  • A class can only extend one abstract class but can implement multiple interfaces.
  • Abstract classes are extended using "extends", while interfaces are implemented using "implements".

Here‘s an example abstract class:

public abstract class Animal {

  private int age;

  public Animal(int age) {
    this.age = age; 
  }

  public abstract void makeSound();

  public void sleep() {
    System.out.println("Sleeping"); 
  }

}

And an interface example:

public interface Herbivore {

  public void eatPlants();

}

Using abstract classes and interfaces together allows flexibility in providing skeletal implementations while enforcing contracts through interfaces.

Q: Explain immutable objects in Java. How are they used?

An immutable object is an object whose state cannot be modified after creation. Immutable objects are inherently thread-safe since no mutation takes place.

Some ways to create immutable objects:

  • Declare class and fields as final
  • Make fields private and without setters
  • Return defensive copies from getter methods
  • Do not provide methods that modify state

Java String objects are immutable. The String class has no methods that allow changing the object‘s state.

Immutability has advantages like:

  • Thread safety – can be shared without synchronization
  • Class instances can be cached and reused safely
  • Useful as Map keys or Set elements since hashcode won‘t change
  • Simpler programming model with no possibility of side-effects

Immutable objects should be the default choice for object design unless mutability is absolutely needed.

Q: What is the significance of the finalize() method in Java?

The finalize() method is called by the JVM garbage collector when an object is being removed from memory. This method can be overridden by classes to perform cleanup activities before final garbage collection.

For example, you may want to close file or network resources associated with the object being finalized.

However, there are some caveats with finalize():

  • There is no guarantee when finalize() will be called, or even if it will be called.
  • It can significantly slowdown garbage collection.
  • Objects become eligible for finalize() when no longer referenced, but may still be reachable through autres before collection.

So in most cases, try to cleanup resources with finally blocks or implementing AutoClosable instead of relying on finalize().

Q: What is string interning in Java?

String interning refers to storing only one copy of each distinct string value in a pool of reusable String objects.

The JVM maintains a String pool to minimize memory usage for String objects. When the intern() method is invoked on a String, the JVM will return the same object reference if it already exists in the pool.

For example:

String s1 = new String("Test"); 
String s2 = new String("Test");

s1 == s2; //false, different objects

s1 = s1.intern();
s2 = s2.intern();

s1 == s2; //true, same object reference

String interning is helpful because:

  • It reduces duplicate String objects, saving memory
  • Checking string equality is faster with == instead of equals() method
  • Useful for caching distinct values like enum constants

But it can also complicate string equality checking in some cases.

Q: Explain deadlock and livelock concepts in multithreading.

Deadlock occurs when two or more threads get blocked waiting on locks held by each other.

For example:

Thread1 acquires lock A 
Thread2 acquires lock B

Thread1 waits for lock B
Thread2 waits for lock A

Now both threads wait indefinitely causing a deadlock.

Deadlock can be avoided by careful locking order and avoiding nested locks in threads.

Livelock is similar to deadlock but threads in livelock continuously try to acquire locks but fail.

For example:

Thread1 acquires lock A
Thread2 needs lock A, so releases lock B
Thread1 needs lock B now which Thread2 has released
Thread2 again needs lock A released by Thread1 

This cycle repeats preventing progress. Handling livelock requires mechanisms like backing off requests or randomizing wait times.

Unlike deadlock though, threads in livelock remain active.

Q: What is synchronization and why is it important in multithreading?

Synchronization refers to controlling access to shared resources like objects and variables by threads. Without synchronization, threads may access inconsistent state leading to conditions like race conditions.

Java provides synchronized blocks and methods to prevent such shared state issues.

For example:

class Counter {
   private int count = 0;

   public synchronized void increment() {
      count++ 
   }

   public synchronized int getCount() {
      return count;
   }
}

synchronized ensures only one thread can execute the increment or getCount methods on a Counter instance.

Synchronization has a performance cost so should be applied judiciously based on need. Other mechanisms like atomics and locks can also be used.

Q: Explain the Java Memory Model. How is it different from stack and heap?

The Java Memory Model defines how threads in Java interact through memory during execution. It specifies guarantees threads must adhere to while accessing shared state.

Some key highlights:

  • Threads interact through shared memory by acting on the same variables/objects.
  • The sequence of operations done within a thread is preserved. But operation sequence between threads may not be orderly.
  • Synchronization establishes happens-before relationships between operations in different threads. This provides ordering guarantees.

The stack and heap are separate memory segments used by Java:

  • Stack holds primitive variables and object references for method invocation stack in threads. Stack helps track state during method calls.
  • Heap contains application objects like strings, lists, etc. and is shared across threads.

So the Memory Model governs shared heap access by threads while stack is unique per thread.

Q: Explain how generics work in Java.

Java generics allow defining classes, interfaces, and methods that can operate on different types while providing compile-time type safety.

For example, a generic class:

public class Box<T> {

  private T obj;

  public void set(T obj) {
    this.obj = obj;
  }

  public T get() {
    return obj;
  }
}

Using generics enforces type-checking at compile time without explicit casts:

Box<Integer> intBox = new Box<>();
intBox.set(10); 

Integer value = intBox.get(); // No casting needed

The compiler handles inserting necessary casts based on the generic type.

Generics allow:

  • Reusable class/method code for multiple types
  • Elimination of run-time casting errors
  • Better code readability with intent capture through typing

Target types specify bounds like <T extends Number> or <T extends Runnable & Closeable> to restrict generic arguments.

Q: What is the difference between method overloading and overriding in Java?

Method overloading refers to defining multiple methods with the same name within a class but different parameters. Overloading is resolved at compile-time.

For example:

class MathUtils {
  public int add(int a, int b) {
    return a + b;
  }

  public double add(double a, double b) {
    return a + b;
  } 
}

MathUtils m = new MathUtils();
m.add(1, 2); //calls first version
m.add(1.0, 2.0); //calls second 

This allows semantic method name reuse for different scenarios.

Method overriding means providing a different implementation for a method inherited from a parent class. The signature must remain the same. Overriding happens at runtime based on actual object type.

For example:

class Animal {
  public void makeSound() {
    //generic animal sound 
  }
}

class Lion extends Animal {
  public void makeSound() {
    //roar, overriding animal sound
  }
}

Animal a = new Lion();  
a.makeSound(); //calls overridden version

Overriding allows polymorphic behavior based on implementations.

Q: What are the differences between ArrayList and LinkedList classes in Java?

ArrayList and LinkedList both implement the List interface but have the following differences:

  • Backing data structure: ArrayLists use arrays whereas LinkedLists use doubly linked nodes.

  • Performance:

    • ArrayLists have O(1) access by index. LinkedLists require O(n) time to traverse to an index.

    • LinkedList add/remove from head/tail is O(1) while ArrayLists take O(n) time to shift elements.

  • Memory usage: ArrayList has lower overhead than LinkedList node storage.

  • Common operations:

    • ArrayList suits random access of elements

    • LinkedList suits frequent additions/deletions from ends of the list

So ArrayLists work well when index-based retrieval is frequent. LinkedLists suit contexts where data manipulation outweighs random access.

Q: Explain how HashMap works in Java.

The HashMap provides key-value map functionality in Java. Some key characteristics:

  • HashMap stores entries as key-value pairs.
  • It uses hashing to insert/retrieve elements, providing constant time operations.
  • Under the hood, a HashMap uses an array of buckets, with linked list chaining to handle collisions.
  • The capacity (bucket array size) dynamically scales up as elements get added. Default capacity is 16.
  • Load factor determines when the map will resize, default is 0.75 (75% filled).
  • Hashcode is used to determine bucket location for a key. Hashcode collisions are handled via separate chaining.
  • HashMap is non-synchronized making it thread unsafe in multithreaded context.

Let‘s look at an example flow:

  • Create a HashMap object with default capacity 16.
  • Add key-value entry (key1, val1).
  • Key1.hashCode() % 16 determines bucket location where this entry gets stored.
  • More entries added, different keys may collide to the same bucket due to hashcode result.
  • These entries get stored as linked nodes in the bucket‘s linked list handling collisions.
  • Load factor reached, capacity doubles to 32 and entries redistributed.
  • Get value for a key just involves – compute hashcode again, determine bucket location, search linked list.

This provides an efficient insert/retrieve time while handling collisions gracefully.

Q: How does Garbage Collection work in Java?

Garbage collection (GC) automatically manages memory in Java by clearing objects no longer reachable or in use by the application. Some key aspects:

  • The JVM periodically runs the garbage collector to free up unused memory.
  • Any object no longer reachable by the application can be reclaimed.
  • Reachability analysis algorithmically determines unused objects.
  • Two common GC algorithms used are Mark-Sweep and Stop-The-World.
  • GC can be tuned via JVM options based on app behavior.
  • Java developers mainly focus on object allocation/de-allocation while the GC handles actual memory reclamation seamlessly.

Understanding GC helps debug issues like memory leaks when objects are unintentionally maintained preventing cleanup.

Profiling tools can provide insights into GC behavior in the JVM.

Java Coding and Design Principles

Let‘s move on to some other common Java interview questions you may encounter:

Q: What are some standard Java coding best practices?

Some recommended Java coding best practices are:

  • Follow standard naming conventions like lowerCamelCase for variables/methods, UpperCamelCase for classes, ALL_CAPS for constants etc.

  • Use access modifiers like private, protected, public to encapsulate class behavior.

  • Implement behaviours via interfaces by composition over heavy inheritance.

  • Add javadoc comments for classes, methods to document intention and usage.

  • Follow standard formatting rules for spacing, indentation, brackets etc. for readability.

  • Keep methods small and focused on single responsibilities (SRP principle).

  • Handle errors/exceptions early and properly using try-catch-finally blocks.

  • Use logging libraries like log4j2 to add debug/info/error level logs to trace execution flow.

  • Follow standard package naming like com.company.module and organize directory structure accordingly.

Adhering to these coding best practices ensures maintainable and well-written Java code.

Q: Explain different software design patterns used in Java with examples.

Some popular design patterns used in Java include:

Singleton – Ensures only one instance of a class is created. Example:

class DataSource {

  private static DataSource instance;

  private DataSource() {}

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

}

Factory – Creates objects without specifying exact class. Example:

interface Food {
  public void consume();
}

class FoodFactory {

  public Food getFood(String foodType) {
   if (foodType == "banana") {
      return new Banana();
    } else if (foodType == "pizza") {
      return new Pizza();
    }
  }

}

MVC – Separates data (model), presentation (view) and logic (controller).

Observer – Allows notifying other objects about state changes. Useful for event handling.

Learning common design patterns gives guidance on flexible object-oriented design and coupling in Java.

Q: What is a Java annotation? What are some common predefined annotations?

Java annotations provide metadata about code that has no direct effect on execution. JVM tools, libraries and frameworks can inspect annotations for useful information.

Some common annotations in Java:

  • @Override – Indicates a method declaration intends to override a superclass method.

  • @Deprecated – Marks a class, method as obsolete and discouraged from usage.

  • @SuppressWarnings – Instructs compiler to ignore specific warnings.

  • @Test – Used by JUnit to identify methods as test cases for suite execution.

  • @Inject – Used by dependency injection frameworks like Guice for DI configuration.

  • @Entity – Used by JPA/Hibernate to mark a class as a database entity.

Annotations help embed extra details without cluttering the code with comments. Java defines many standard annotations but also allows custom ones.

Summary

We‘ve explored a variety of commonly asked Java interview questions ranging from language fundamentals like abstract classes and immutability to design principles and coding best practices.

You can expect the interviewer to ask several questions to probe your knowledge across these different concept areas.

Preparing explanations for these common questions using examples is one of the best ways to walk into an interview assured and ready to demonstrate your Java skills.

We‘ve only scratched the surface of possible Java interview questions. Be sure to also review multithreading concepts like volatile, atomic, synchronized and JVM topics like bytecode, classloaders.

Best of luck with the Java job hunt! Let me know in the comments about any other helpful interview question topics to cover.

Written by