Top 100+ Java Interview Questions and Answers (2026)

Preparing for a 2026 Java developer interview? Top tech companies expect more than basic OOP definitions, they want deep expertise in Java 21, Virtual Threads, Stream APIs, and JVM memory management. Whether you’re a fresher or a senior architect, master these top 100+ highly scannable, scenario-based Java interview questions to secure your next offer.

Java’s popularity lies in the features it offers. Here are the top features provided by Java:

  • Platform Independent: Code can run on any platform.
  • Object Oriented: Follows the principles of OOPS.
  • Simple and Easy to Learn: Doesn’t include complex features such as pointers, operator overloading etc.
  • Secure: Explicit access to pointers is unavailable, making it less vulnerable.
  • Multi-threaded: Supports parallel computing.
  • Distributed Computing: Built-in support for remote method invocation and protocols like HTTP and FTP.

Q2. Explain the internal working of HashMap in Java. [Asked in Amazon]

Internally, a HashMap uses an array of buckets (Nodes) to store key-value pairs. When you call put(key, value), it calculates the key’s hashCode() to determine the bucket index. If multiple keys hash to the exact same index (a collision), they are stored together as a Linked List.

Q3. What are the differences between StringBuffer and StringBuilder in Java programming?[Asked in Oracle]

StringBufferStringBuilder
StringBuffer methods are synchronized.StringBuilder is non-synchronized.
StringBuffer is thread-safe.StringBuilder is not thread-safe.
The performance is very slow.The performance is very fast.

Table of Contents

Module 1: JVM, Core Fundamentals and Memory

Q4. What makes the Java platform independent?

Java’s ‘Write Once, Run Anywhere’ feature allows it to be platform-independent. Once a Java program is written, it can run on any machine or operating system with Java installed.

When the code is compiled, it is compiled into an intermediate language called Bytecode. Bytecode is not dependent on any operating system or hardware. Once the code is compiled into Bytecode, it is then executed by the Java Virtual Machine (JVM).

JVM is platform-dependent and needs to be installed on the platform where you want the code to run. Therefore, as long as the target platform has a JVM installed, it can run any code that is written in Java, making it platform-independent.

Q5. What is the difference between JDK, JRE, and JVM in Java? 

JDKJREJVM
It includes the full suite of tools required for developing Java applications.It is a software layer that provides the necessary environment to run Java programs.JVM converts Java Code into Bytecode.
Includes JRE, JVM, Java compiler, java debugger, and javadoc.It consists of the JVM, java libraries like .util and .lang, and runtime tools like java collector.It is platform dependent i.e., it has different versions of Mac, Linux, and Windows.

Q6. How does the JVM work? 

Java Virtual Machine is a Java Runtime Environment (JRE) component. It loads, verifies, and executes the bytecode. Although JVM is platform-dependent, it enables Java code to be platform-independent.

Q7. Which memory areas are allocated by JVM?

To execute programs, the JVM divides its memory into five specific, purpose-built areas:

  • Method Area (Metaspace): Stores class metadata, method details, and static variables.
  • Heap: The largest memory space, allocating memory for objects and their instance variables.
  • Java Stacks: Created per thread to strictly store local variables and handle method execution.
  • PC Registers: Points to the exact current instruction being executed by the thread.
  • Native Method Stacks: Reserved exclusively for executing native methods written in languages like C/C++.

Q8. Explain the differences between Java and C++ 

FeatureJavaC++
Design PhilosophyMore focus on portability and simplicity.It is a software layer that provides the necessary environment to run Java programs. (Note: This point seems misplaced; see correction below)
Platform IndependencePlatform independent, just needs the target platform’s JVM installed.Consists of JVM, Java libraries like .util and .lang, and runtime tools like garbage collector. (Note: This also seems Java-specific; see correction below)
Memory ManagementAutomatic Memory Management.Manual memory management.
Execution SpeedIt is slower since the code is first converted to bytecode and then interpreted/compiled by the JVM.Faster due to direct compilation to machine code.
Syntax ComplexitySimpler Syntax.Complex Syntax compared to Java.
Application DomainsUsed in enterprise applications, web development, Android apps, etc.Used in system software, game development, embedded systems, etc.

Q9. Explain the following syntax: public static void main(String args[]) in java

Every Java program needs a main method. When you compile a Java program, the JVM looks for the main method with the exact same syntax. Let’s break down the syntax to understand it better.

  • Public: The access specifier ‘public’ helps JVM access the method from outside the class.
  • Static: The static keyword helps to make a method or variable belong to a class, and not to an instance of a class, which is its object. 
  • Void: This is a return type, and means the main method is not returning any value to the caller. In this case, it’s the JVM.
  • main(String args[]): This is the main method, with parameters of args[]. args[] helps to catch any command line arguments passed while launching the program.

Q10. What is the difference between int and Integer in Java?

  • int is a primitive data type that stores a 32-bit signed integer.
  • Integer is a wrapper class for an int type and is a part of Java Collections Framework.

Key Differences:

FeatureintInteger
TypePrimitiveObject (Wrapper class)
NullabilityCannot be nullCan be null
Use in CollectionsNot allowedAllowed (e.g., in ArrayList<Integer>)
MethodsNo methodsProvides utility methods (e.g., parseInt())

Example:

int a = 10;
Integer b = Integer.valueOf(a);  // Autoboxing

Q11. Explain the working of JIT. 

JIT (Just-in-Time) is a runtime component of the Java Virtual Machine (JVM) that converts bytecode into machine code. Its main purpose is to speed up code execution, thereby improving the performance and efficiency of Java applications.

It does so by recognizing code blocks that are executed frequently and converting them into machine code. This compiled machine code is then saved in memory and whenever the same code block needs to run again, JVM can use the already compiled version instead of recompiling it..

By avoiding repeated compilation of the same code, the JIT compiler improves execution speed and rQ13. educes the workload on the JVM.

Q12. What is the Java Memory Model and how is memory allocated?

The Java Memory Model (JMM) specifies the semantics of cooperation between threads via memory and the acceptable behaviors in concurrent programming. It is a standard that specifies reading and writing of variables by different threads within a Java Virtual Machine (JVM).

In memory allocation, this is how it usually happens in Java:

  1. Heap memory: Holds objects and class instances. It is shared by all threads.
  2. Stack memory: Holds function calls and local variables. It is thread-local.
  3. MetaSpace: Holds class metadata, static data, and method code.
  4. PC (Program Counter) Register: Identifies the current JVM instruction being processed.
  5. Native Method Stack: Manages the native (non-Java) methods.

Q13. Explain memory management and garbage collection in Java.

Garbage collection is Java’s automatic memory management system. It runs as a process that recovers memory from objects that will never be used again. Garbage collection is done by JVM, and it does tasks like allocating memory for objects, garbage collecting unused objects, and optimizing memory usage for performance enhancement. Various types of memory areas are used by JVM such as heap, stack, method area, and native method stacks to manage memory efficiently.

Q14. Explain the differences between minor, major, and full garbage collections in Java. 

Type of GCAffected AreaFrequencyPause DurationDescription
Minor GCYoung GenerationFrequentShortClears short-lived objects from the Eden space and moves survivors to Survivor/Old gen.
Major GC (Old GC)Old GenerationLess frequentLongerCleans up long-lived objects. May involve compaction.
Full GCEntire Heap (Young + Old)RareLongestCleans all memory areas, including PermGen / Metaspace. Most disruptive to application performance.

Q15. How can you identify major and minor garbage collections in Java? 

You can identify various garbage collection modes by simply applying JVM flags and garbage collection monitoring tools.

1. Enable GC Logs:

-XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log

This will help log minor GC (e.g., “ParNew”) and major/full GC (e.g., “Tenured”, “Full GC”) events.

2. Use Java Monitoring Tools:

  • JVisualVM
  • JConsole
  • GCViewer
  • GCEasy.io (log analyzer)

3. Look at GC Log Patterns:

  • Minor GC: Identified by logs like GC (Allocation Failure), Young Gen, PS Scavenge, etc.
  • Major/Full GC: Appears as Full GC, CMS, or G1 Old Generation.

Q16. What is a memory leak in Java, and how does it affect garbage collection?

In Java, a memory leak happens when objects that are no longer needed remain referenced and thus are not garbage collected. Even with automatic garbage collection in Java, memory leaks are possible if objects are kept accessible by virtue of poor programming practices.

Impact on Garbage Collection:

  • Avoids memory reclaiming by the GC.
  • Slowly increases usage of the heap, causing OutOfMemoryError.
  • Triggers degradation in performance, prolonged GC pauses, and system instability.

Q17. What are the drawbacks of Java’s garbage collection? 

Although garbage collection makes memory management easier, it has a few disadvantages:

  1. Irregular Pause Durations: GC can suspend application threads (Stop-the-world events) that affect latency-sensitive applications.
  2. CPU Overhead: Garbage collection takes CPU time, notably full GC cycles.
  3. Less Control: A developer cannot exactly control when or where an object gets deallocated.
  4. Performance tuning is needed: JVM flags need to be carefully tuned to let GC behave appropriately by adjusting -Xms, -Xmx, and -XX:+UseG1GC.

Q18. What are the differences between Serial, Parallel, CMS, and G1 garbage collectors in Java? 

In Java, Garbage Collectors, or GCs, are tasked with automatic memory management. Each is optimized to serve particular cases like minimal pause times or maximal throughput.

Garbage CollectorCharacteristicsBest Use Case
Serial GCSingle-threaded; stops all application threads during GC (Stop-the-World).Small applications or environments with single CPUs.
Parallel GC (Throughput Collector)Multi-threaded GC; focuses on maximizing throughput.Applications where high throughput is more important than low pause times.
CMS (Concurrent Mark-Sweep)Minimizes pause times by doing most of the work concurrently with the application.Low-latency applications requiring shorter GC pauses.
G1 (Garbage First)Region-based, concurrent collector; balances throughput and pause time with predictable performance.Large heap, server-side applications needing predictable pause times.

G1 GC has become the default collector in more recent versions of Java (Java 9+) and replaced CMS in this role, and ZGC and Shenandoah are recent low-pause collectors in subsequent releases of Java.

Module 2: OOPs Concepts and Exception Handling

Q19. What are Classes and Objects in Java? 

In Java, a Class is a logical blueprint or template that defines the state (variables) and behavior (methods) of an entity. An Object is a physical, runtime instance of that class that occupies memory.

  • Class (The Blueprint): Defines the general concept of a “Car” with attributes like wheels and an engine.
  • Object (The Instance): The actual physical “BMW” or “Audi” built from that exact blueprint.
Java

Get 100% Hike!

Master Most in Demand Skills Now!

Q20. Explain the concept of Inheritance in Java. 

Inheritance enables a new class (subclass) to automatically inherit the properties and methods of another class (superclass). This basic OOP principle significantly cuts down on redundancy and strongly emphasizes code reusability.

In Java, inheritance is implemented through the extends keyword. For example, a NewCar automatically inherits common behaviors (such as engine()) from a generic Vehicles parent class, so developers need to implement new, specific functionalities (such as fuel()) only.

Java

Q21. What is data encapsulation in java? 

Encapsulation in Java is the process of bundling data and methods within a class while restricting direct access to the class’s internal state. The reason behind this approach is to ensure data integrity and promote abstraction by exposing only essential details of the class’s behavior through public methods.

Q22. What is a constructor in Java? Explain the different types.

In Java, a constructor is a special type of method used to initialize objects. Constructors are automatically called when an object of a class is created. They must have the same name as the class and do not have any return type, not even void – unlike regular methods.

There are two types of constructors in the Java:

  1. Parameterized Constructor: A constructor that accepts arguments or parameters is known as the parameterized constructor. It initializes the instance variables and the values passed while creating an object.

Below is an example of the parameterized constructor:

Java
  1. Non-parameterized/Default constructor: The constructors with no parameters or arguments are known and non-parameterized constructors. In case you don’t define a constructor of any type, the compiler itself creates a default constructor which will be called when the object is created.

Below is an example of a non-parameterized constructor:

Java

Q23. Explain the differences between method overriding and method overloading. 

The following is the difference between Method Overloading and Method Overriding in Java:

FeatureMethod Overriding
DefinitionRedefining a method in a subclassDefining multiple methods with same name but different parameters
Class RelationshipRequires inheritance (subclass & superclass)Happens within the same class
Method SignatureMust be the same (name, parameters)Must differ (parameters type, number, or order)
Runtime or Compile TimeResolved at runtime (dynamic binding)Resolved at compile time (static binding)
Access ModifiersCannot reduce visibilityNo such restriction
Use CaseTo provide specific implementation in subclassTo perform different tasks with same method name

Code Example:

Java

Q24. Explain the meaning of the ‘final’ keyword in Java. Give an example. 

Java uses the final keyword to declare constants, prevent method overriding, and create immutable classes.

For example, final int MAX_SIZE = 100; declares a constant MAX_SIZE whose value is 100.

Q25. Explain the use of the ‘super’ keyword in Java? 

Super is used in the Java programming language to refer to the superclass of the current object. It can also be used as a bridge between superclass methods/constructors and subclass methods/constructors. For instance, super.methodName() invokes the method defined by the superclass.

Q26. List the differences between this() and super() keywords in Java.

this()super()
Represents the present instance of a classRepresents the current instance of the parent class.
Calls the default constructor.Calls the base class constructor.
Used to point to the current class instance.Used to point to the instance of the superclass.

Q27. Explain the use of access modifiers in Java.

Public, protected, default (no modifier), and private are four access modifiers in Java.

  • Public: access from anywhere.
  • Protected: access to the same package or other packages (subclasses).
  • Default (no modifier): Only access in the created package.
  • Private: No one else but the declaring class will be able to obtain it.

Use public if you want your member to be accessed from anywhere, protected when you wish to restrict access to subclasses and classes within the same package, default when you want access at the package level, and private when you only want access within the declaring class.

Q28. What is the difference between static loading and dynamic class loading?

In Java, class loading determines exactly when the JVM brings a compiled .class file into memory.

FeatureStatic LoadingDynamic Class Loading
When it happensAt compile-time / application startup.strictly at runtime.
How it’s invokedUsing the standard new keyword.Using Class.forName() or loadClass().
Primary Use CaseWhen all class dependencies are known beforehand.When the class name is determined dynamically at runtime (e.g., loading a JDBC driver).
Failure ErrorThrows NoClassDefFoundError.Throws ClassNotFoundException.

Q29. What are abstract classes in Java? Give an example.

Java Abstraction refers to showing only the function ability and behavior of methods while hiding their implementation details to the user. It focuses on what an object does rather than how it does it.

For instance, the List interface in Java represents abstraction because it describes common operations for lists without defining how those operations are carried out. Classes like LinkedList and ArrayList implement these operations differently but still follow the same interface.

Q30. When should you use an abstract class in Java?

Use an abstract class in Java when:

  • You would like to have default behaviour (method implementations) that your child classes will inherit.
  • Your class hierarchy has shared state (fields).
  • You must define the constructors.
  • You expect subclasses to follow a template pattern.

Abstract classes are suitable when constructing a base class with partial implementation. Abstract classes have both concrete and abstract methods, in contrast to interfaces.

Q31. What are the differences between abstract class and interface?

Below are the major differences between the abstract class and an interface:

Abstract ClassInterface
Can provide complete, default, or only the details in method overriding.Doesn’t provide any code, the user can only have the signature of the interface.
Have instance variables.No instance variables.
An abstract class can be public, private, or protected.The interface must be public.
An abstract class can have constructors.No constructors are available in the interface.
A class can inherit only a single abstract class.A class can implement one or more interfaces.
Abstract classes are fast.Interfaces are slower as they have to locate the corresponding methods in the class.

Q32. Can a superclass reference variable hold an object of a subclass in Java?

Yes, in Java, a reference variable of a superclass can point to a subclass object. This is known as polymorphism, and dynamic method dispatch occurs at runtime.

Java

Java supports calling overridden methods at runtime, enabling runtime polymorphism, which promotes flexible and scalable program design.

Q33. How can we restrict a class from being inherited?

There are various ways to restrict inheritance for a class in Java. They are listed below:

  1. By using final keyword: if you mark a class as final, it cannot be extended, below is the code for the same.
Java

Here, you will get an error. Since the ‘Base’ class is ‘final’, and hence it cannot be inherited. Here, if you remove the ‘final’ keyword from the ‘Base’ class, the code will work as intended.

  1. By using private constructors: if we make the constructor private of the class, then it cannot be inherited by another class. This way it cannot be instantiated outside the class.

Example

Java

Here, you will get an error since the display method in the Base class is private, hence it cannot be instantiated. If we remove the keyword ‘private’ from the method, the code will work as expected.

  1. By sealing the class: By using the seal keyword, we can restrict which classes can inherit the base class. Let’s understand it using an example:
Java

A class that wants to inherit properties from a sealed class must be declared with one of the following access specifiers: final, non-sealed, or sealed.

Q34. Why doesn’t Java support multiple inheritance?

Java doesn’t support multiple inheritance because of two reasons:

  1. Ambiguity
  2. Simplicity

Example:

Java

Both Intellipaat1 and Intellipaat2 classes have their own test() methods, and class C is inheriting from both. In this case, there is ambiguity because the compiler cannot determine which test() method to inherit.

To resolve this, class C must override the test() method and provide its own implementation. This way, the ambiguity is explicitly handled.

Q35. Explain Aggregation in Java. 

Aggregation in Java represents a relationship where one class contains the reference of another class. In other words, it refers to a one-way relationship between two objects where the aggregate class has the instance of another class it owns. The aim is to have classes which are loosely coupled with each other.

Q36. What is composition in Java? 

Composition refers to a relationship between two classes or objects where they are tightly coupled. In this relationship, the lifetime of the contained object depends on the lifetime of the container object. This concept is known as composition.

In simple words, the composition is a kind of aggregation that represents a strong relationship between two classes using the reference variable.

Q37. What is the purpose of the toString() method in Java? 

The toString() method in Java returns a string describing an object. It is part of the Object class and is usually overridden to provide a more meaningful result.

By default, it returns the class name of the object and the hash code, such as:

Car@1a2b3c

But when overridden:

@Override
public String toString()
return "Car model: " + this.model;
}

The method is generally very helpful in debugging, logging, and object printouts. This enhances maintainability and readability.

Q38. Explain the try-catch block in Java. 

A try-catch block in Java is used to implement exceptional handling. The code that may throw exceptions has to be written inside the try block, and if any exception occurs, it is caught and handled in the corresponding catch block.

Q39. What are the different types of Exceptions in Java. 

There are two types of Exceptions in Java Programming:

  • Built-in Exception: These exceptions are the exceptions available in the standard package of java lang. They are used for certain errors with specific exceptions as mentioned below:
    • ArithmeticException: thrown for the errors related to the arithmetic operations.
    • IOException: thrown for failed input-output operations.
    • FileNotFoundException: raised when the file is not accessible or does not exist.
    • ClassNotFoundException: exception is raised when the compiler is unable to find the class definition.
    • InterruptedException: raised when a thread is interrupted.
    • NoSuchFieldException: raised when a class or method doesn’t have a variable specified.
    • NullPointerException: thrown while referring to the variable or values of a null object.
    • RuntimeException: raised for the errors occurring during the runtime. For example, performing invalid type conversion.
    • IndexOutOfBoundsException: raised when the index of the collection like an array, string, or vector is out of the range or invalid.
  • User-defined Exceptions: User-defined exceptions are the exceptions thrown by the user with custom messages. These are used for cases where the in-built Exception might not be able to define the error.

Q40. Differentiate between checked and unchecked exceptions in Java. 

FeatureChecked ExceptionsUnchecked Exceptions
Verification PhaseChecked at compile-time.Checked strictly at runtime.
Handling RequirementMust be explicitly handled (try-catch) or declared (throws).Handling is completely optional (usually indicates bad logic).
HierarchyDirectly extends the Exception class.Extends the RuntimeException class.
Common ExamplesIOException, SQLException.NullPointerException, ArithmeticException.

Q41. What is the difference between throw and throws keyword? 

throwthrows
The throw keyword is used to explicitly throw an exception inside a program or a block of code.Throws keyword is used to declare an exception in the method signature that might occur during the compilation or execution of a program.
Can throw only unchecked exceptions.Can be used for both checked and unchecked exceptions.
throw keyword followed by an instance variable.throws keyword followed by the exception class names.
throw keyword is used to throw only a single exception.throws can be used to throw multiple exceptions.

Q42. How do you create a custom exception in Java? 

You can create a custom exception by subclassing the Exception or RuntimeException class.

Checked Exception:

Java

Unchecked Exception:

Java

Usage:

Java

Custom exceptions assist in offering descriptive context to error handling, particularly for domain-specific projects.

Q43. Can we write multiple try-catch blocks in java? If yes, how? 

In Java, we can include multiple catch statements for a single try block. This approach allows multiple exceptions to be handled separately within a single try block.

Below is the program for multiple catch statements:

Java

Q44. What happens if an exception is thrown inside a finally block? 

If an exception is explicitly thrown inside a finally block, it violently aborts the block and entirely masks or overrides any unhandled exception previously thrown in the try or catch blocks. The original exception is permanently lost, making debugging incredibly difficult.

To prevent this, you should always wrap cleanup code inside its own nested try-catch block within the finally block, or preferably, use Java 7’s Try-With-Resources statement for automatic, exception-safe resource management.

Q45. Can you catch an OutOfMemoryError in a try-catch block? Should you?[Asked in IBM]

Technically, yes, you can catch an OutOfMemoryError because it inherits from the java.lang.Throwable base class. However, you absolutely should not catch it in a production application.

Errors in Java represent catastrophic JVM-level failures, not recoverable application logic bugs. By the time an OOMError is thrown, the JVM is entirely starved of memory, and simply catching it will likely just cause another crash milliseconds later. Instead, properly profile your application using heap dumps to fix the underlying memory leak.

Q46. What is the difference between a String and a StringBuilder?

The main distinction between String and StringBuilder in Java is related to immutability and efficiency.

  • A String is immutable, meaning its value cannot be altered once it is created. Operations like concatenation produce a new String object, which can be memory-inefficient.
  • A StringBuilder is mutable, or able to change its value without the creation of a new object. It is much more efficient to use in loops.

Example:

Java
Java

Therefore, whenever you are performing heavy string manipulations, always use StringBuilder or StringBuffer instead of a regular String to improve performance and reduce memory overhead.

Module 3: Java Collections Framework

Q47. Explain the use of collections in Java.

A collection is a framework that provides a set of classes and interfaces, which are used to manage, store and manipulate data for a group of objects in Java.

Java Collections can be used for performing a variety of operations such as:

  • Search
  • Sort
  • Manipulate
  • Delete

Q48. List the differences between an ArrayList and a Vector.

FeatureArrayListVector
SynchronizationAn ArrayList is not synchronized.A vector is synchronized.
PerformanceAn ArrayList is fast.A vector is slow as it is thread-safe.
Growth PolicyIf an element is inserted into an ArrayList, it increases its array size by 50 percent.A vector defaults to doubling the size of its array.
Capacity IncrementAn ArrayList does not define the increment size.A vector defines the increment size.
Traversal MechanismAn ArrayList uses an Iterator for traversing.Except for the hashtable, a vector is the only other class using Enumeration and Iterator.

Q49. List the differences between ArrayList and LinkedList in Java? 

Both implement the List interface but are structurally optimized for entirely different data operations.

FeatureArrayListLinkedList
Internal StructureDynamic Array (contiguous memory).Doubly Linked List (nodes with pointers).
Memory OverheadLow (only stores actual data).High (stores data plus two node pointers).
Search PerformanceO(1) (extremely fast index-based access).O(n) (must traverse nodes sequentially).
Insertion/DeletionSlow O(n) (requires shifting array elements).Fast O(1) (just instantly updates node pointers).

Q50. What is the Difference Between List and Set in Java?

The main difference between List and Set in Java is ordering and duplicates.

FeatureListSet
DuplicatesAllows duplicatesDoes not allow duplicates
OrderingMaintains insertion orderMay not maintain order (depends on implementation)
AccessIndexed access via get(int)No index-based access
ImplementationsArrayList, LinkedList, VectorHashSet, LinkedHashSet, TreeSet

Q51. What are the differences between HashSet and TreeSet in Java? 

Both TreeSet and HashSet are implementations of the Set interface but vary based upon ordering and efficiency.

FeatureHashSetTreeSet
OrderingNo specific orderSorted order based on natural or custom comparator
PerformanceO(1) for basic operations (average)O(log n) for all operations
Null ElementsAllows one null elementDoes not allow null elements
Use CaseFast access, unordered setSorted set with range query support

Use a HashSet where there are requirements of performance and no ordering. Use TreeSet for sorted entries and navigation methods such as headSet() or tailSet().

Q52. How does HashSet internally store elements?

Internally, HashSet uses a HashMap to store its elements. When an element is added to a HashSet, it is added as a key in the underlying HashMap with a constant dummy value (PRESENT) associated with it.

Internal Representation:

private transient HashMap<E, Object> map;

private static final Object PRESENT = new Object();

Working:

  • It relies on hashCode() and equals() methods to provide uniqueness.
  • Even when two objects share identical hash codes but are not equal through equals(), both can still be cached.

Example:

HashSet set = new HashSet<>();
set.add("Java"); // Stored as map.put("Java", PRESENT)

Q53. How Does List Differ from Map in Java?

List and Map serve entirely different purposes in Java Collections Framework.

FeatureListMap
Data TypeCollection of elementsCollection of key-value pairs
AccessAccessed by indexAccessed by key
DuplicatesAllows duplicate elementsKeys must be unique; values can duplicate
ImplementationsArrayList, LinkedListHashMap, LinkedHashMap, TreeMap

List is a linear data collection, and Map is a key-value mapping. Use a Map whenever data lookup by a distinct key is needed, like in caching or lookup applications.

Q54. List the differences between HashMap and HashTable in Java?

Both store mapped key-value pairs, but they handle multithreaded environments very differently.

FeatureHashMapHashTable
Thread SafetyNon-synchronized (Not thread-safe).Synchronized (Thread-safe).
Null AcceptanceAllows exactly one null key and multiple null values.Absolutely does not allow any null keys or values.
PerformanceVery fast (no internal locking overhead).Very slow (locks the entire map for every operation).
Modern StatusModern industry standard.Legacy class (use ConcurrentHashMap instead for multithreading).

Q55. How Does HashMap Differ from TreeMap in Java? 

HashMap and TreeMap are both implementations of the Map interface but are very different in behaviour, performance and ordering.

FeatureHashMapTreeMap
OrderingNo guaranteed orderSorted based on keys (natural/comparator)
PerformanceO(1) average for get/putO(log n) for get/put
Null KeysAllows one null keyDoes not allow null keys
Use CaseFast lookup, unordered dataSorted map for range queries or ordered traversal

Use HashMap for better performance. Use TreeMap if a sorted key-value map is desired.

Q56. Compare Queue and Stack in Java

Queue and Stack are both linear data structures but follow different ordering principles.

FeatureQueueStack
OrderingFIFO (First-In-First-Out)LIFO (Last-In-First-Out)
InsertionVia add() or offer() at tailVia push()
RemovalVia poll() or remove() at headVia pop()
Use CasesTask scheduling, resource sharingRecursion, backtracking, parsing

Q57. Compare Queue and Deque in Java.

Queue and Deque both belong to the java.util package but Deque is more versatile.

FeatureQueueDeque (Double-Ended Queue)
DirectionElements added at rear, removed from front.Elements can be added/removed from both ends.
Typical UsageFIFO (First-In-First-Out)FIFO and LIFO (supports both)
Methodsadd(), poll(), peek()addFirst(), addLast(), removeFirst()
ImplementationsLinkedList, PriorityQueueArrayDeque, LinkedList

Use Queue when performing simple FIFO operations. Use Deque if you need both ends to be flexible, like when implementing a stack or a sliding window.

Q58. What is the difference between poll() and remove() in a Queue? 

MethodDescription
Throws Exception if Queue is Empty
poll()Retrieves and removes the head, or returns null if emptyNo (Returns null)
remove()Retrieves and removes the head, or throws NoSuchElementException if emptyYes

Example:

Java

When to Use:

  • Use poll() when you wish to safely search for an element.
  • Use remove() when you are certain that the queue is not empty.

Q59. What distinguishes PriorityQueue from TreeSet in Java?

While both PriorityQueue and TreeSet maintain sorted elements, they differ in structure, usage, and uniqueness constraints.

FeaturePriorityQueueTreeSet
DuplicatesAllows duplicatesDoes not allow duplicates
OrderingNatural or comparator-based priorityNatural or custom order
AccessNo random access; only peek/poll headCan navigate using methods like first(), last()
Underlying StructureBinary heapRed-Black tree (self-balancing BST)

Q60. What is the difference between Fail-Fast and Fail-Safe iterators in Java?

Fail-Fast and Fail-Safe are terms that describe how iterators will react if the collection is structurally changed while iterating.

FeatureFail-FastFail-Safe
Behavior on ModificationThrows ConcurrentModificationExceptionWorks safely without exception
ExamplesArrayList, HashSet, HashMap (normal)CopyOnWriteArrayList, ConcurrentHashMap
Underlying CopyWorks on the same collectionWorks on a cloned copy of the collection
PerformanceFasterSlightly slower due to cloning

Q61. Explain Iterator vs Enumeration

IteratorEnumeration
Iterator is an interface found in the java.util package.Enumeration is a special data type that allows you to define a fixed set of constants.
Uses three methods to interface:hasNext()next()remove()Uses two methods:hasMoreElements()nextElement()
Iterator method names have been improved.The traversing of elements can only be done once per creation.
Become an Java Expert with Our Free Course
Achieve Your Goals with this Free Training
quiz-icon

Q62. How does the Comparator interface differ from Comparable? 

FeatureComparableComparator
Packagejava.langjava.util
MethodcompareTo(T o)compare(T o1, T o2)
Defined InSame class being comparedSeparate or anonymous class
Sorting LogicNatural/default orderCustom or multiple orderings
FlexibilityOne comparison strategy onlyMultiple strategies possible

Comparable Example:

public class Student implements Comparable {

    public int compareTo(Student s) {

        return this.id - s.id;

    }

}

Comparator Example:

Comparator byName = (s1, s2) -> s1.name.compareTo(s2.name);

Q63. What are the differences between ConcurrentHashMap and Collections.synchronizedMap()? 

Both Collections.synchronizedMap() and ConcurrentHashMap are employed to make a Map thread-safe, but with vastly different performance, granularity, and concurrency.

FeatureConcurrentHashMapCollections.synchronizedMap()
Thread SafetyFine-grained (segment-level locking)Entire map is locked (coarse-grained)
ConcurrencyHigh concurrencyLow concurrency
Null Keys/ValuesNot allowedAllows one null key and multiple null values
PerformanceBetter under high thread contentionPoor performance under load
IterationWeakly consistentMust use external synchronization
Introduced InJava 5 (java.util.concurrent)Legacy approach using Collections

Use ConcurrentHashMap in contemporary concurrent applications. It supports non-blocking reads, lock striping, and increased scalability.

Q64. Explain the internal workings of LinkedHashMaps.

A LinkedHashMap is a subclass of HashMap that has a doubly-linked list that goes through all of its entries. This feature causes it to retain insertion order or access order, depending upon the way it is set.

Constructors:

LinkedHashMap<K, V> map = new LinkedHashMap<>(16, 0.75f, true);

  • The third parameter, accessOrder, controls whether iteration order is by insertion (false) or by access (true).

LinkedHashMap with LRU Cache Example:

Java

Internal Working of LinkedHashMap

  • Internally extends HashMap.
  • Maintains a doubly-linked list connecting all entries in insertion or access order.
  • When accessOrder = true, every access (get or put) moves the accessed entry to the end of the list.
  • Has a customizable method removeEldestEntry() that helps control eviction – ideal for implementing caches like Least Recently Used (LRU).

Q65. What considerations should be made when implementing the equals() method in Java?

When overriding the equals() method in Java, a few key rules have to be followed to make it function appropriately and consistently:

  1. Reflexive: a.equals(a) must return true.
  2. Symmetric: b.equals(a) should be true if and only if a.equals(b) is true
  3. Transitive: If a.equals(b) and b.equals(c), then a.equals(c) must be true.
  4. Consistent: Identical calls should give the same response unless there are object property updates.
  5. Non-nullity: a.equals(null) must return false.

Also, whenever overriding equals(), you should override hashCode() to ensure the contracts are consistent, particularly if the object is employed in hash-based collections such as HashMap or HashSet.

Explore the key issues to consider when overriding equals and hashCode in Java through this blog.

Q66. What is the purpose of the hashCode() method in Java?

Java’s hashCode() method returns an integer hash code that denotes the object’s memory location or, more practically, its location within a hash-based collection.

It is essential for both performance and accuracy in data structures such as:

  • HashMap
  • HashSet
  • Hashtable

Q67. What is the hashCode() and equals() contract? 

The hashCode() and equals() contract is a fundamental rule for ensuring objects behave correctly in hash-based collections like HashSet or HashMap. The strict contract states:

  • If two objects are physically equal according to equals(), they must return the exact same integer hashCode().
  • If two objects have the same hashCode(), they are not required to be equal (this is a standard hash collision).

If you override equals(), you are strictly mandated to override hashCode(). Failing to do so completely breaks collection lookups.

Q68. What happens if you override equals() but not hashCode()?[Asked in Google]

If you override equals() without overriding hashCode(), you completely break the fundamental Java contract for hash-based collections like HashMap and HashSet. Because the default hashCode() algorithm relies on internal memory addresses, two logically identical objects will produce entirely different hash codes. Consequently, they will be dropped into different memory buckets. When you attempt to retrieve the object using .get(), the collection will look in the wrong bucket and return null, causing silent data loss and unexplainable duplicate entries.

Module 4: Java 8+ and Modern Features

Q69. What is a lambda expression, and how is it used in Java? 

A Java lambda expression is a concise block of code that can be passed around and executed. Introduced in Java 8, it is mainly used to implement  functional interfaces, interfaces with a single abstract method.

The syntax:

(parameter) -> { body }

For example:

Runnable r = () -> System.out.println(“Hello from Lambda!”);

Lambda expressions are widely employed in functional programming, particularly with Java Stream API, to perform operations such as filtering, mapping, and iterating. They make the code more readable, concise, and highly expressive, particularly when dealing with collections and concurrency APIs.

Q70. What are method references in Java?

Java method references are a concise syntax for lambda expressions that call a pre-existing method. They make the code more readable and concise.

Syntax Types:

Java

Example:

Java

Q71. What is a Predicate in Java?

Predicate is a functional interface added in Java as part of the package java.util.function. It is a representation of a one-argument boolean-valued function.

Method Signature:

@FunctionalInterface

public interface Predicate {

    boolean test(T t);

}

Example Usage:

Predicate startsWithA = str -> str.startsWith("A");

System.out.println(startsWithA.test("Apple")); // true

System.out.println(startsWithA.test("Banana")); // false

Q72. What is a BiFunction in Java?

BiFunction<T, U, R> is a functional interface in package java.util.function that defines a function that accepts two parameters of types T and U and has an output of type R.

Syntax:

Java

Example:

Java

Q73. What are streams in Java, and how are they used?

Java Streams are a sequence of elements that can support functional-style operations like filter, map, reduce, and collect. The Java Stream API improves collection processing by enabling declarative, pipelined operations on data structures like  List and Set.

Here is a sample code:

Java

The streams are either parallel or sequential and enable parallel processing to optimize the execution. Both are extremely useful when combined with method references and lambda expressions and encourage clean, functional style programming in Java.

Q74. How does the flatMap() method work in streams?

The Java Streams flatMap() method is utilized to flatten hierarchical structures, often by transforming a stream of collections (e.g., lists) into a single stream of their individual elements.

Behavior:

  • Maps every element to a Stream.
  • Flattens the outcome into one Stream.

Example:

Java

Q75. Write a Java 8 Stream API code to find the highest paid employee in each department from a List<Employee>. [FAANG Level]

This classic FAANG interview question tests your ability to chain advanced Stream operations. It requires combining groupingBy to partition the dataset and maxBy to extract the top earner per partition.

Map<String, Optional<Employee>> topEarners = employees.stream()

    .collect(Collectors.groupingBy(

        Employee::getDepartment,

        Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary))

    ));

This pipeline groups the stream by the department field and utilizes maxBy as a downstream collector. It safely wraps the highest salary in an Optional to completely prevent NullPointerExceptions if a department is unexpectedly empty.

Q76. What is the purpose of the java.util.Optional class?

Optional<T> is a container class that can or cannot have a non-null value. It prevents null pointer exceptions and promotes better practices for handling null values.

Use Case:

Rather than returning null, return an Optional<T>.

Example:

Java

Q77. How does the Optional class help in avoiding null checks?

The Optional<T> class in Java is a container object to prevent explicit null checks and avoid NullPointerException.

How It Helps:

Methods now return Optional<T> rather than null to indicate that a value could be present or not.

Java

Q78. What are its best practices of using Optional Class?

  • Use Optional as return types, in particular where a method may not yield a value.
  • Avoid the use of Optional as a field or parameter type (according to Oracle recommendations).
  • Use .orElse(), .orElseGet(), or .orElseThrow() to gracefully deal with empty values.
  • Chain operations securely with .map() or .flatMap().

Q79. What are Generics in Java?

Java generics are a very useful feature that permits you to write reusable, type-safe code. Generics help classes, interfaces, and methods perform operations on objects of different types without knowing at compile time.

Java 5 introduced generics to avoid explicit type casting and to minimize the possibility of ClassCastException at runtime.

Example:

Java

Without generics, objects would need to be cast by hand, raising the threat of runtime errors.

Q80. What is the diamond operator (<>) in generics?

The diamond operator (<>), added in Java 7, has made instantiation of generic types easier by enabling the compiler to deduce the type arguments.

Before Java 7:

List list = new ArrayList();

With Diamond Operator (Java 7+):

List list = new ArrayList<>();

Benefits:

  • Minimizes boilerplate.
  • Enhances readability.
  • Prevents duplicate declarations of types.

Q81. Explain the concept of autoboxing and unboxing.

Autoboxing and unboxing are significant additions made to Java 5 to connect primitive data types and their corresponding wrapper classes.

  • Autoboxing is the process where a primitive type like int is automatically converted to its equivalent wrapper class such as Integer.
  • Unboxing is converting an Integer back to an int.

Example:

Integer x = 10;  // autoboxing

int y = x;       // unboxing

These conversions are useful with collections like ArrayList, where objects are needed instead of primitives. They make your code more readable and less cluttered with boilerplate, although be mindful of the performance ramifications when in a tight loop.

Q82. What is the purpose of the transient keyword in serialization?

In Java, if a class implements Serializable, all of its fields are eligible to be serialized by default. However, if you want to prevent a particular field from getting serialized, you make that field transient.

For instance:

private transient String password;

This instructs the Java Serialization API to skip this field while converting the object to a byte stream. It is usually employed to shield sensitive information (like a password, a session token) or to skip non-serializable objects like Thread, Socket, etc.

Q83. What are Records in Java (introduced in Java 14/16)?[Asked in Meta]

Introduced in Java 14, Records act as transparent, deeply immutable data carriers that completely eliminate boilerplate code. By simply declaring a record, the Java compiler automatically generates the private final fields, constructors, getters, equals(), hashCode(), and toString() methods entirely under the hood.

// Replaces 50 lines of POJO code

public record Employee(int id, String name) {}

They are perfectly engineered for Data Transfer Objects (DTOs) and API responses, ensuring absolute immutability and dramatically cleaner architecture compared to legacy POJOs.

Q84. What is the difference between Jakarta EE and legacy Java EE?

Jakarta EE is a new Java EE that is more current. Java EE was initially developed by Oracle, but Jakarta EE has been transferred to the Eclipse Foundation, which is more open, innovative at a faster pace, and is better suited to cloud-native architectures.

Key Differences:

FeatureJava EEJakarta EE
GovernanceOracleEclipse Foundation
Package Namesjavax.*jakarta.* (from Jakarta EE 9 onwards)
Community InvolvementLimitedOpen, community-driven
Cloud & MicroservicesLess emphasisStrong microservices and cloud focus
Innovation PaceSlowerMore agile and modular
CompatibilityStable, but less future-proofBackward-compatible and forward-looking

Module 5: Multithreading, Concurrency and Project Loom

Q85. Can we able do multithreading in Java?

Yes, multithreading is part of Java. It provides built-in support for creating and managing threads, thereby enabling multiple tasks to be executed concurrently within one program.

Q86. What is a thread lifecycle in Java?

There are 5 states in a thread lifecycle, let’s understand each one of them:

  • New: The thread lies in the new state after it has been created. It remains in the new state until you start the execution process.
  • Runnable: At runnable state, the thread is ready to run at any point in time or it might have started running already.
  • Running: The scheduler picks up the thread and changes its state to running, the CPU starts executing the thread in the running state.
  • Waiting: While being ready to execute, another thread might be running in the system. So, the thread goes to the waiting state.
  • Dead: Once the execution of the thread is finished, its state is changed to the dead state, which means it’s not considered active anymore.

Q87. What are the different thread priorities in Java, and what is the default priority assigned by the JVM? 

In Java, every thread has a priority value ranging from 1 (MIN_PRIORITY) to 10 (MAX_PRIORITY). The default priority that the JVM gives to every thread is 5 (NORM_PRIORITY).

Thread Priority Constants:

  • MIN_PRIORITY = 1
  • NORM_PRIORITY = 5 (default)
  • MAX_PRIORITY = 10

Significance: Priority of the thread will affect the thread scheduler to select the thread to be executed, but not necessarily-governed by the JVM’s underlying operating system level thread scheduling mechanism. It is a suggestion, not a requirement.

Q88. Explain the volatile keyword and its use cases.

The volatile keyword in Java ensures that updates to a variable are visible to all threads. By declaring a variable as volatile, every read loads the most recent value directly from the main memory, and every write immediately updates the main memory.

Why it is Important in Multithreading:

In a multithreaded environment, threads can cache variables locally. Without the volatile keyword, updates made by one thread may not be immediately visible to other threads, leading to inconsistent data access.

Q89. How does the synchronized keyword work in methods? 

The synchronized keyword in Java is utilized to manage the multiple threads’ access to a method or section of code to provide mutual exclusion and visibility.

Synchronized Instance Method:

public synchronized void method() {

// thread-safe logic

}
  • Acquires a lock on this current object.
  • At most, a single thread can invoke any synchronized method on an object.

Synchronized Static Method:

public static synchronized void method() {

    // logic

}
  • Obtains a lock on the class object (ClassName.class) rather than on an instance.

Use Cases:

  • Avoid race conditions.
  • Maintain data consistency in concurrent situations.

Q90. What is the use of synchronized blocks?

The synchronized block in Java is used to provide exclusive access to shared resources by locking a specific object. It helps prevent thread interference and ensures thread safety when multiple threads access the same resource. Unlike synchronized methods, the scope of a synchronized block is limited to a specific section of code, offering more fine-grained control over synchronization.

Q91. What is the difference between synchronized blocks and ReentrantLock in Java? 

Both synchronized block and ReentrantLock in Java are employed in thread synchronization, but vary in terms of flexibility, functionality, and control:

FeaturesynchronizedReentrantLock
SyntaxImplicit monitor lock (synchronized(obj))Explicit lock acquisition (lock.lock())
FlexibilityLess flexibleMore flexible
Try-LockNot availabletryLock() with timeout support
InterruptibilityNot interruptibleCan interrupt a waiting thread
FairnessNo fairness policyCan enforce fairness
Condition VariablesUses wait() / notify()Supports multiple Condition objects

Q92. What is a ConcurrentModificationException, and how can it be avoided? 

ConcurrentModificationException is raised when a thread is modifying a collection while iterating over its elements with fail-fast iterators like ArrayList, HashMap, etc.

Common Cause:

How to Avoid It:

for (String s : list) {

    list.remove(s); // Unsafe!

}

1. Use Iterator’s remove() method:

Iterator it = list.iterator();

while (it.hasNext()) {

    if (condition) it.remove();

}

2. Use concurrent collections like CopyOnWriteArrayList, ConcurrentHashMap when working in multithreaded environments.

Collect and remove later:

List toRemove = new ArrayList<>();

for (String s : list) {

    if (condition) toRemove.add(s);

}

list.removeAll(toRemove);

Q93. How does the Java Memory Model (JMM) ensure visibility and ordering of variables in multithreaded environments?

The Java Memory Model (JMM) provides ordering, atomicity, and visibility guarantees between threads by describing the memory interaction between threads (in the sense of shared variables). 

Important concepts:

  • Visibility: Modifications done by a single thread to shared variables are not visible to others until appropriate synchronization.
  • Happens-before relationship: Guarantees memory operations to be viewed in the appropriate order.
    • start() occurs before the thread’s run.
    • Synchronized and volatile fields define happens-before relationships.
  • Volatile variables: Provide visibility without locking but not atomicity.
  • Locks: Both mutual exclusion and visibility guarantees are enforced.

The JMM renders concurrent program execution predictable and thread-safe by controlling instruction reordering and caching effects.

Q94. Explain the concept of false sharing in multithreaded applications and how it affects performance. 

False sharing is a performance-degrading occurrence where several threads write to variables that happen to be stored near together in memory (on the same CPU cache line) even if the threads are operating on entirely different variables.

Although logically unrelated, all the variables are allocated in a cache line, and when a thread updates a variable, the entire cache line is invalidated with:

  • Constant cache invalidation
  • Excessive memory traffic
  • Decreased CPU efficiency
  • Increased contention

Example Scenario:

Java

If x and y are in the same cache line, updates by both threads cause false sharing.

Q95. How does the ForkJoinPool work in Java’s concurrency framework? 

The ForkJoinPool is an extended implementation of Java’s ExecutorService that is particularly suited for running tasks in parallel and for efficiently handling parallelizable, recursive tasks. It is part of the package java.util.concurrent and is particularly tuned to operate with work-stealing algorithms, enhancing utilization in multi-processor environments.

Usage Example:

Java

Q96. How do CompletableFuture and Future differ in handling asynchronous computations? 

The Future and CompletableFuture both describe the result of a computation that happens asynchronously, but in terms of features and versatility, both are very different.

Key Differences:

FeatureFutureCompletableFuture
Non-blocking APINo (requires .get() which blocks)Yes (supports non-blocking callbacks with .thenApply(), .thenAccept() etc.)
ChainingNot possibleSupports functional-style chaining of tasks
Exception HandlingLimitedBuilt-in exception handling with .exceptionally(), .handle()
Manual CompletionNot supportedSupports manual completion via .complete()
Combining FuturesNot supportedCombine multiple async results with .thenCombine(), .allOf()

Q97. What is a CountDownLatch vs CyclicBarrier? [Asked in Netflix]

Both are advanced concurrency utilities found in the java.util.concurrent package, but they resolve entirely different thread synchronization problems.

FeatureCountDownLatchCyclicBarrier
ReusabilityCannot be reused once the internal count reaches zero.Can be cleanly .reset() and reused multiple times.
Trigger MechanismOne or more threads wait for a fixed counter to decrement to 0.Multiple threads wait for each other to reach a common barrier point.
Primary Use CaseWaiting for multiple background services (like API calls) to boot up.Synchronizing parallel worker threads at distinct mathematical phase boundaries.

Q98. How can you prevent deadlocks in a multithreaded Java application? 

Deadlock happens when two or more threads await each other to free a lock, and neither moves.

Strategies to Prevent Deadlock:

  1. Consistent Lock Ordering: Always lock in the same order.
Java
  1. Try-Lock with Timeout: Use ReentrantLock.tryLock() with a timeout to prevent waiting indefinitely.
Java
  1. Use Lock Timeout or Deadlock Detection Tools: Deadlocks can be detected at runtime by monitoring tools such as VisualVM or jstack.
  2. Minimize Lock Scope: Decrease the amount of code within synchronized regions to reduce lock contention..
  3. Avoid Nested Locks: Organize logic to prevent nested or cyclic lock acquisition.

Q99. What are Sealed Classes in Java (introduced in Java 15/17)? 

Introduced in Java 15, Sealed Classes grant architects absolute control over object-oriented inheritance hierarchies. By using the sealed modifier alongside the permits keyword, you strictly define exactly which subclasses are legally allowed to extend your base class or implement your interface.

public sealed class Shape permits Circle, Square {}

This actively prevents unauthorized third-party extensions, heavily fortifies domain models, and enables exhaustive switch pattern matching without ever needing to write a generic, error-prone default case.

Module 6: Scenario-Based and System Design (For Seniors)

Q100. How would you detect and resolve a Deadlock in a production Java application?

To immediately detect a production deadlock without crashing the server, trigger a thread dump using CLI tools like jstack <PID>, or visual profilers like JVisualVM. The dump will explicitly highlight the blocked threads waiting on exact memory monitors.

To permanently resolve it, you must refactor the architecture to guarantee a consistent global lock acquisition order across all threads. Alternatively, replace rigid synchronized blocks with ReentrantLock.tryLock() to introduce safe timeouts, effectively shattering the circular waiting condition.

Q101. How does structured concurrency simplify error handling?

Structured concurrency is a structured approach that enables threads and tasks to be managed efficiently by specifying the manner in which they are started, supervised, and finished within a clearly defined scope. This model makes it easy to deal with errors and manage tasks in concurrent programs.

In what way it makes error handling easy:

  • In case one task goes wrong, the system will be able to cancel all other tasks which are running at the same time without the user being involved.
  • The exceptions might be handled at a central point by the parent task or scope.
  • It is not going to allow thread leaks and tasks without owners to exist.

Example using StructuredTaskScope (Java 21+):

Java

Note: This requires Java 21+ with –enable-preview for Structured Concurrency.

Q102. What are Project Loom and virtual threads in Java?

Project Loom is an active Java platform project whose objective is to make Java concurrency easier by adding support for virtual threads. Virtual threads provide better management of concurrency, particularly in use cases involving very concurrent applications that have a high need for many threads with low memory use.

Q103. What is the Open/Closed Principle? 

The Open/Closed Principle (OCP) is a part of the SOLID design principles of object-oriented design. It states:

“Software entities should be open for extension but closed for modification.”

In Java, this means:

  • You can extend a class or interface without having to change its source code.
  • Interfaces and abstractions provide this by means of polymorphism.

Q104. How does Open/Closed Principle apply to Java interfaces and abstract classes? 

  • Interfaces permit various implementations without a change in the interface itself.
  • Abstract classes can specify a general framework yet let subclasses extend function.

Example:

Java

Here, introducing a new payment method doesn’t require modifying current code. You simply create a new class that implements the PaymentStrategy interface.

Q105. How does the Strategy pattern promote flexibility in algorithm selection?

The Strategy pattern encapsulates a family of algorithms, allowing them to be defined independently and made interchangeable at runtime. It permits a client to change an algorithm’s behavior at runtime without actually modifying the implementation.

Structure:

  • Context: Uses a Strategy
  • Strategy interface: Specifies a contract
  • Concrete Strategies: Various implementations of the algorithm

Q106. Can you implement the Singleton pattern in a thread-safe manner without using synchronization?

Yes, a thread-safe Java Singleton without explicit synchronization can be created with the Bill Pugh Singleton Design Pattern that utilizes Java Memory Model’s guarantees around class loading to ensure safe and efficient lazy initialization.

Implementation Using Static Inner Class:

Java

How it works:

  • The inner class is only loaded when the call to getInstance() occurs.
  • Class loading is guaranteed to occur only once by the JVM and is thread-safe.
  • No synchronized or double-checked locking is necessary.

Q107. Explain the double-check locking idiom for Singleton classes. 

Double-checked locking is a method utilized for safe lazy initialization of a Singleton class, without synchronization overhead on every access to the Singleton.

Steps:

  1. Verify that the Singleton instance is already created (initial check).
  2. Otherwise, synchronize only that block of code that instantiates an instance, once to prevent performance premiums.
  3. Double-check that the instance is not null in the synchronized section (second check). This guarantees only a single thread may construct the instance.

Code Example:

Java

Q108. What tools and techniques can be used to diagnose and resolve OutOfMemoryError in Java?

When a Java application experiences memory depletion, the JVM throws an OutOfMemoryError. It takes a mixture of monitoring, profiling, and analysis tools to correct this.

Common Tools:

  • Heap Dumps: Examine memory snapshots with tools such as:
    • Eclipse MAT (Memory Analyzer Tool)
    • JVisualVM
    • YourKit
  • Garbage Collection Logs:
    Enable with -XX:+PrintGCDetails, -Xlog:gc (Java 9+)
    • Use GCViewer or GCEasy to analyze logs.
  • Profiling Tools:
    • JProfiler, Flight Recorder, VisualVM, JConsole to monitor memory trends and object allocations.

Techniques:

  • Identify memory leaks: Find objects with a long retention in heap dumps.
  • Tune GC: Tune the heap size (-Xms, -Xmx) and GC algorithm depending upon the application.
  • Use soft/weak references: Assists in the development of memory-sensitive caches.
  • Fix code issues: Remove unused references, clean up static fields, close resources.

Q109. How can memory leaks occur in Java applications despite automatic garbage collection? 

Java’s Garbage Collector recovers memory that’s not accessible. But memory leaks are still possible where references to unused objects are held unintentionally, precluding GC to recover memory.

Common Causes:

  • Static references: Static fields retaining objects outside their lifespan.
  • Listeners & callbacks: Failing to deregister event listeners will retain objects alive.
  • Incorrect caching: Caches that are not properly managed (such as Map without eviction) cause leaks.
  • ThreadLocal misuse: Not removing values can cause leaks, especially in thread pools.
  • Inner class references: Non-static inner classes have implicit outer class instance references.

Q110. You have a 10GB log file but only 2GB of RAM. How do you read and parse this file in Java without getting an OutOfMemoryError? [FAANG Level]

You absolutely cannot use Files.readAllLines() as it attempts to load the entire 10GB payload into the JVM heap, instantly triggering an OutOfMemoryError.

Instead, you must process the file sequentially, loading only a single line into memory at a time. The most modern, memory-efficient approach utilizes the Java 8 Files.lines(Path) method, which returns a lazily-evaluated Stream<String>. Alternatively, wrapping a standard FileReader inside a BufferedReader and iterating with .readLine() achieves the exact same O(1) memory footprint.

Q111. What is the output of System.out.println(0.1 + 0.2 == 0.3); in Java? 

The output is exactly false. This is a classic FAANG trap regarding the universal IEEE 754 standard for floating-point arithmetic.

In Java (and most languages), primitive doubles and floats cannot precisely represent base-10 fractions like 0.1, leading to minor rounding errors in binary memory (the actual engine result is 0.30000000000000004). For any financial calculations, precise engineering formulas, or strict equality checks, you must entirely abandon primitive floats and strictly utilize the BigDecimal class instead.

Conclusion

Cracking a modern Java interview demands a deep understanding of internal workings, multithreading, and architectural design. By mastering these 100+ questions, from core JVM memory models to FAANG-level coding scenarios, you are fully equipped for 2026. Bookmark this page, practice the code snippets, and step into your interview with absolute confidence.

Frequently Asked Questions

Frequently Asked Questions
Q1. What job roles can you get after learning Java?

You can apply for roles like Java Developer, Backend Developer, Software Engineer, Android Developer, and Full Stack Developer. Many freshers also start as Associate Software Engineer or Application Developer.

Q2. What kind of Java interview questions are commonly asked?

Interviewers ask about OOP concepts, Collections, JVM, memory management, exceptions, and multithreading. They also ask coding questions like HashMap working, String vs StringBuilder, and problem solving programs.

Q3. What is the usual interview process for a Java developer role?

Most companies have an online test with coding and MCQs, followed by technical interviews. The final round is usually HR, where they discuss salary, projects, and communication skills.

Q4. Which companies hire Java developers?

Top IT companies like TCS, Infosys, Wipro, Accenture, Capgemini, Amazon, IBM, and Oracle hire Java developers. Many startups and product based companies also use Java for backend systems.

Q5. What is the average salary of a Java developer in India?

For freshers, salary usually ranges between 3 to 6 LPA. With 3 to 5 years of experience, it can go up to 8 to 15 LPA depending on skills and company.

About the Author

Software Developer | Technical Research Analyst Lead | Full Stack & Cloud Systems

Ayaan Alam is a skilled Software Developer and Technical Research Analyst Lead with 2 years of professional experience in Java, Python, and C++. With expertise in full-stack development, system design, and cloud computing, he consistently delivers high-quality, scalable solutions. Known for producing accurate and insightful technical content, Ayaan contributes valuable knowledge to the developer community.