Java has been one of the most widely used programming languages since 1995, and it still ranks among the top languages recruiters look for. Whether you are preparing for your first job as a fresher or switching roles as an experienced developer, walking into an interview with a strong grip on Java fundamentals, OOP, collections, multithreading, Java 8+ features, and Spring Boot/Hibernate can make the difference between a callback and a rejection.
This guide covers the most commonly asked Java interview questions, organized the way interviewers usually structure their rounds, from basics to coding and scenario-based problems. If you want structured, mentor-led practice on these concepts along with real projects, you can check out Codegnan’s Java training programs or the detailed Java course syllabus.
Java basic interview questions and answers
1. What is Java?
Java is a class-based, object-oriented programming language designed to be platform-independent. Code written in Java is compiled into bytecode, which can run on any device that has a Java Virtual Machine, following the “write once, run anywhere” principle.
2. What is the JVM, JDK, and JRE?
The JVM (Java Virtual Machine) is the engine that runs Java bytecode. The JRE (Java Runtime Environment) bundles the JVM with core libraries needed to run Java applications. The JDK (Java Development Kit) includes the JRE plus development tools like the compiler, so you can write, compile, and run Java programs.
3. What is bytecode and how does it enable platform independence?
Bytecode is the intermediate, platform-neutral code produced when the Java compiler (javac) compiles source code. Any machine with a compatible JVM can interpret or JIT-compile this bytecode into native instructions, which is why Java programs can run unchanged across operating systems.
4. What is the classpath in Java?
The classpath is the parameter, either an environment variable or a command-line flag, that tells the JVM and Java compiler where to look for user-defined classes, packages, and third-party libraries needed to run or compile a program.
5. What are packages and imports used for?
A package is a namespace that groups related classes and interfaces together, helping avoid naming conflicts and keeping code organized. The import statement lets you use classes from another package without typing their fully qualified names every time.
6. What are Java’s primitive data types?
Java has eight primitive types: byte, short, int, long, float, double, char, and boolean. Unlike objects, primitives store actual values directly in memory rather than references, which makes them faster and more memory-efficient for simple computations.
7. What is the difference between == and .equals() in Java?
The == operator compares references for objects (whether two variables point to the same memory location) and values for primitives. The .equals() method, when properly overridden, compares the actual content or logical equality of two objects, which is why String comparisons should almost always use .equals().
8. What are operators and loops in Java?
Operators (arithmetic, relational, logical, bitwise, assignment) let you perform computations and comparisons on variables. Loops such as for, while, and do-while let you repeat a block of code, and Java 5 added the enhanced for-each loop for cleaner iteration over arrays and collections.
9. What is an array in Java, and how does it differ from a collection?
An array is a fixed-size, index-based container that holds elements of the same type in contiguous memory. Unlike collections such as ArrayList, arrays cannot grow or shrink dynamically, though they generally offer faster access for a known, fixed number of elements.
10. Why are Strings immutable in Java, and what is the String pool?
Once created, a String object’s value cannot be changed; any modification creates a new object. This immutability makes Strings safe to share across threads and enables the String pool, a memory-saving area where identical string literals are reused instead of duplicated.
11. What is the difference between a method and a constructor?
A method defines behavior and can be called any number of times, while a constructor initializes an object and runs automatically when the object is created using the new keyword. Constructors share the class name and have no return type, not even void.
12. What are access modifiers in Java?
Access modifiers, public, private, protected, and default (package-private), control the visibility of classes, methods, and fields. They are central to encapsulation, since they let you expose only what other classes genuinely need to use.
13. What is the “this” keyword used for?
The this keyword refers to the current object instance. It is commonly used to distinguish instance variables from parameters with the same name, or to pass the current object as an argument to another method or constructor.
14. What is the “super” keyword used for?
The super keyword refers to the immediate parent class. It is used to call a superclass’s constructor, access a superclass’s fields, or invoke a superclass’s overridden method from within a subclass.
15. What is the difference between static and final?
The static keyword ties a member to the class rather than any specific instance, so it is shared across all objects. The final keyword prevents further modification, a final variable cannot be reassigned, a final method cannot be overridden, and a final class cannot be extended.
OOP interview questions and answers
16. What are the four pillars of Object-Oriented Programming?
They are encapsulation (bundling data and methods and restricting direct access), abstraction (hiding implementation details and exposing only essential features), inheritance (reusing and extending behavior from a parent class), and polymorphism (allowing one interface to take multiple forms).
17. What is inheritance and what types does Java support?
Inheritance lets a subclass acquire the fields and methods of a parent class using the extends keyword. Java supports single, multilevel, and hierarchical inheritance for classes, but it does not support multiple inheritance of classes directly, since that would create ambiguity; multiple inheritance of type is instead achieved through interfaces.
18. What is polymorphism, and what are its two types?
Polymorphism allows the same method name to behave differently depending on context. Compile-time polymorphism is achieved through method overloading, while runtime polymorphism is achieved through method overriding, resolved dynamically based on the actual object type.
19. What is encapsulation?
Encapsulation means bundling an object’s data (fields) with the methods that operate on it, and restricting direct access to that data using access modifiers. Getters and setters are a common way to expose controlled access to private fields.
20. What is abstraction, and how is it achieved in Java?
Abstraction focuses on what an object does rather than how it does it. In Java, this is achieved using abstract classes and interfaces, which define a contract of behavior without necessarily specifying implementation details.
21. What is the difference between an interface and an abstract class?
An abstract class can have both abstract and concrete methods, constructors, and instance variables, and a class can extend only one abstract class. An interface traditionally defines method contracts (though it can now include default and static methods since Java 8), and a class can implement multiple interfaces, which is how Java achieves multiple inheritance of type.
22. What is method overloading?
Method overloading occurs when multiple methods in the same class share a name but differ in the number, type, or order of parameters. It is resolved at compile time based on the method signature.
23. What is method overriding?
Method overriding occurs when a subclass provides its own implementation of a method already defined in its parent class, with the same signature. It is resolved at runtime based on the actual object type, which is what enables dynamic (runtime) polymorphism.
24. Can you override a static method in Java?
No. Static methods belong to the class, not an instance, so they are resolved at compile time based on the reference type, a behavior called method hiding rather than overriding. Only instance methods can be truly overridden.
25. What is constructor chaining?
Constructor chaining is the practice of calling one constructor from another, either within the same class using this(), or from a subclass to a parent class using super(). It helps avoid duplicating initialization logic.
Core Java interview questions and answers
26. What are Java Streams?
Introduced in Java 8, Streams provide a declarative way to process sequences of elements from collections, arrays, or I/O sources using operations like filter, map, sorted, and collect, often combined with lambda expressions for concise, functional-style code.
27. What is a Lambda expression?
A lambda expression is a compact way to represent an anonymous function, most often used to implement a functional interface (an interface with a single abstract method) without writing a full anonymous class.
28. What is Optional, and why use it?
Optional is a container object introduced in Java 8 that may or may not hold a non-null value. It encourages developers to handle the possible absence of a value explicitly, reducing the risk of NullPointerException.
29. What are Generics, and why do we need them?
Generics allow classes, interfaces, and methods to operate on typed parameters specified at compile time, such as List<String>. They provide type safety and eliminate the need for explicit casting, catching type mismatches at compile time instead of runtime.
30. What are Annotations in Java?
Annotations are metadata attached to code elements like classes, methods, or fields, using an @ symbol. Common examples include @Override, @Deprecated, and framework-specific annotations like @Autowired or @Entity, which tools and frameworks read at compile time or runtime to alter behavior.
31. What is Reflection in Java?
Reflection is the ability of a Java program to inspect and manipulate classes, methods, and fields at runtime, even ones it did not know about at compile time. It powers many frameworks (like Spring and Hibernate) but comes with a performance cost and should be used carefully.
32. What is Serialization, and what does “transient” do?
Serialization is the process of converting an object into a byte stream so it can be saved to a file or sent over a network, and deserialization reverses the process. Marking a field as transient excludes it from serialization, useful for sensitive or non-serializable data like passwords or file handles.
33. What is Garbage Collection, and how does it work?
Garbage Collection is the JVM’s automatic process of reclaiming memory occupied by objects that are no longer reachable from any live reference. Modern collectors (like G1 or ZGC) typically work generationally, cleaning up short-lived objects in the young generation more frequently than long-lived objects in the old generation.
34. What is JIT compilation?
The Just-In-Time (JIT) compiler is part of the JVM that translates frequently executed bytecode into native machine code at runtime, improving performance compared to pure interpretation while still keeping the platform independence benefits of bytecode.
35. What is the difference between Comparable and Comparator?
Comparable is implemented by the class itself to define a single natural ordering through the compareTo() method. Comparator is a separate class used to define one or more custom orderings through the compare() method, useful when you need multiple sorting strategies for the same type.
Collections framework interview questions and answers
36. What is the Collections framework in Java?
It is a unified architecture of interfaces (List, Set, Map, Queue) and their implementations (ArrayList, HashSet, HashMap, LinkedList, and more) that provide ready-made data structures and algorithms for storing, retrieving, and manipulating groups of objects.
37. What is the difference between ArrayList and LinkedList?
ArrayList is backed by a dynamic array, so it offers fast random access (O(1)) but slower insertions or deletions in the middle (O(n)) because elements need to shift. LinkedList is a doubly-linked list, so insertions and deletions are faster at known positions, but random access is slower since it requires traversal.
38. What is the difference between HashMap, HashSet, TreeMap, and TreeSet?
HashMap stores key-value pairs with no guaranteed order and average O(1) access. HashSet is built on top of a HashMap and stores unique elements with no order. TreeMap and TreeSet maintain elements in sorted order using a Red-Black tree, offering O(log n) operations at the cost of losing the constant-time average performance of their hash-based counterparts.
39. What is the difference between Queue and Stack?
A Queue follows First-In-First-Out (FIFO) ordering, elements are removed in the order they were added. A Stack follows Last-In-First-Out (LIFO) ordering, the most recently added element is removed first. Java’s Deque interface can actually be used to implement both behaviors efficiently.
40. How does HashMap work internally?
A HashMap stores entries in an array of buckets, using the key’s hashCode() to determine which bucket an entry belongs to. When multiple keys hash to the same bucket (a collision), Java 8+ handles it with a linked list, or a balanced tree once a bucket grows large enough, to keep lookups efficient.
41. What is the difference between fail-fast and fail-safe iterators?
Fail-fast iterators (used by ArrayList, HashMap) throw a ConcurrentModificationException if the underlying collection is structurally modified while iterating. Fail-safe iterators (used by CopyOnWriteArrayList, ConcurrentHashMap) work on a cloned or snapshot version of the collection, so they tolerate concurrent modification but may not reflect the latest changes.
42. What is the difference between ConcurrentHashMap and a synchronized HashMap?
A synchronized HashMap (via Collections.synchronizedMap) locks the entire map for every operation, which limits concurrency. ConcurrentHashMap divides data into segments or buckets and locks only the relevant portion, allowing much higher throughput for concurrent reads and writes in multithreaded applications.
43. What is the difference between Collection and Collections?
Collection is a root interface representing a group of objects, the parent of List, Set, and Queue. Collections is a utility class with static helper methods for operating on collections, such as sorting, searching, or making them unmodifiable or synchronized.
44. How do you sort a List or a Map in Java?
A List can be sorted using Collections.sort() or List.sort() with a Comparator. A Map does not maintain order by default, so to sort it, you typically convert its entries into a List and sort that, or use a TreeMap for natural key ordering, or a LinkedHashMap combined with sorted insertion for custom order.
45. What is the load factor in HashMap, and what triggers rehashing?
The load factor (default 0.75) determines how full the HashMap can get before its internal array is resized. When the number of entries exceeds capacity multiplied by the load factor, the map rehashes, doubling its capacity and redistributing entries to keep lookup performance close to constant time.
Exception handling and multithreading interview questions and answers
46. What is the difference between checked and unchecked exceptions?
Checked exceptions (like IOException) are checked at compile time, and the compiler forces you to either catch them or declare them with throws. Unchecked exceptions (like NullPointerException or ArithmeticException) extend RuntimeException and are not enforced at compile time, usually indicating programming errors.
47. How does try-catch-finally work, and what is try-with-resources?
The try block contains code that might throw an exception, catch handles specific exception types, and finally always executes regardless of whether an exception occurred, commonly used for cleanup. try-with-resources (Java 7+) automatically closes any resource implementing AutoCloseable, removing the need for manual cleanup in a finally block.
48. How do you create a custom exception in Java?
You create a custom exception by extending Exception (for a checked exception) or RuntimeException (for an unchecked one), typically adding a constructor that passes a message to the superclass. Custom exceptions make error handling more descriptive and specific to your application’s domain.
49. What is the difference between Thread and Runnable?
Extending the Thread class means your class cannot extend any other class, since Java doesn’t support multiple inheritance. Implementing Runnable is generally preferred because it separates the task from the thread mechanism and still lets your class extend something else if needed.
50. What are the stages in a thread’s lifecycle?
A thread moves through New (created but not started), Runnable (ready to run or running), Blocked/Waiting (paused for a resource or signal), Timed Waiting (paused for a specific duration), and Terminated (finished execution).
51. What does the synchronized keyword do?
The synchronized keyword ensures that only one thread can execute a block of code or method on a given object at a time, preventing race conditions when multiple threads access shared, mutable data.
52. What is a deadlock, and how do you avoid it?
A deadlock happens when two or more threads wait on each other to release locks, so none of them can proceed. It can be reduced by always acquiring locks in a consistent order, using timeouts, or preferring higher-level concurrency utilities like those in java.util.concurrent instead of manual locking.
53. What is the difference between wait/notify and sleep?
wait() releases the object’s lock and pauses a thread until another thread calls notify() or notifyAll(), and it must be called inside a synchronized block. sleep() simply pauses the current thread for a fixed time without releasing any lock it holds.
54. What is the Executor framework?
The Executor framework, part of java.util.concurrent, manages a pool of worker threads so you can submit tasks without manually creating and managing Thread objects. ExecutorService and thread pools like FixedThreadPool help control resource usage and improve performance in concurrent applications.
55. What does the volatile keyword do?
The volatile keyword ensures that reads and writes to a variable go directly to main memory rather than a thread’s local cache, so changes made by one thread are immediately visible to others. It provides visibility but not atomicity, so it is not a substitute for synchronization on compound operations.
Java 8+ interview questions and answers
56. What are the major features introduced in Java 8?
Java 8 introduced lambda expressions, the Stream API, functional interfaces, default and static methods in interfaces, the new java.time date and time API, and Optional, a significant shift toward functional-style programming alongside Java’s object-oriented roots.
57. What is a functional interface?
A functional interface is an interface with exactly one abstract method, though it can have multiple default or static methods. Common examples include Runnable, Comparator, and the java.util.function interfaces like Function, Predicate, and Supplier, which are commonly implemented with lambdas.
58. What are method references, and how do they relate to lambdas?
A method reference (using the :: syntax) is shorthand for a lambda expression that simply calls an existing method, such as System.out::println. They make code more readable when a lambda would just delegate to a method that already exists.
59. What are default and static methods in interfaces?
Default methods let you add a method with a body to an interface without breaking existing implementing classes, since implementers automatically inherit the default behavior. Static methods in interfaces belong to the interface itself and are called directly on it, similar to static methods in a class.
60. What are common Stream operations like map, filter, and reduce?
filter() selects elements matching a condition, map() transforms each element into another form, and reduce() combines all elements into a single result, like a sum or a concatenated string. These operations are lazy and only execute when a terminal operation like collect() or forEach() is called.
61. What is the java.time API, and why did it replace Date and Calendar?
Introduced in Java 8, java.time provides immutable, thread-safe classes like LocalDate, LocalTime, and LocalDateTime for handling dates and times. It replaced the old, mutable, and notoriously error-prone java.util.Date and Calendar classes.
62. What are some notable features added after Java 8?
Java 10 added the var keyword for local variable type inference, Java 14 introduced switch expressions, Java 16 added records for concise immutable data classes, Java 17 introduced sealed classes to restrict which classes can extend a type, and Java 21 added pattern matching for switch and virtual threads for lightweight concurrency.
63. What is the difference between a Stream and a Collection?
A Collection is a data structure that stores elements in memory. A Stream does not store data; it is a pipeline that processes elements from a source (like a Collection) on demand, and it can only be consumed once before it needs to be recreated.
JVM and performance interview questions and answers
64. What are the main memory areas inside the JVM?
The Heap stores objects and is shared across threads, managed by the garbage collector. The Stack stores method frames, local variables, and is per-thread. Metaspace (which replaced PermGen in Java 8) stores class metadata, and the Program Counter register tracks the current instruction per thread.
65. What types of garbage collectors does the JVM offer?
Common collectors include Serial GC (single-threaded, good for small applications), Parallel GC (multi-threaded, throughput-focused), G1 GC (the default since Java 9, balancing throughput and pause times), and ZGC or Shenandoah (designed for very low pause times on large heaps).
66. How does the static keyword affect memory usage?
Static members are stored once per class rather than once per instance, in an area tied to the class’s metadata rather than the heap-based object memory. This can reduce memory footprint when data genuinely needs to be shared, but overusing static fields can also create hidden shared state that is hard to test and can hurt concurrency.
67. How does String immutability affect performance and memory?
Because Strings are immutable, identical literals can be safely shared through the String pool, reducing memory usage. However, heavy string concatenation in a loop using + creates many intermediate objects, which is why StringBuilder is recommended for building strings incrementally.
68. Can Java applications still have memory leaks despite automatic garbage collection?
Yes. Memory leaks happen when objects are still reachable through references, like static collections that keep growing, unclosed resources, or listeners that are never deregistered, so the garbage collector cannot reclaim them even though they are no longer actually needed.
69. What are class loaders in the JVM?
Class loaders are responsible for locating and loading class files into the JVM at runtime. Java uses a hierarchical model: the Bootstrap loader loads core Java classes, the Platform (Extension) loader loads extension libraries, and the Application (System) loader loads classes from the application’s classpath.
70. How does the choice of collection type affect application performance?
Choosing ArrayList over LinkedList for read-heavy workloads, or a HashMap over a TreeMap when ordering doesn’t matter, can noticeably change an application’s speed and memory profile. Interviewers often ask this to see whether a candidate understands time complexity trade-offs rather than defaulting to one collection everywhere.
Spring Boot and Hibernate interview questions and answers
71. What is Spring Boot, and how is it different from the Spring Framework?
Spring Boot is built on top of the Spring Framework and simplifies application setup with auto-configuration, embedded servers (like Tomcat), and starter dependencies, so you can build production-ready applications with minimal boilerplate configuration compared to traditional Spring.
72. What is Dependency Injection, and what is Inversion of Control?
Inversion of Control (IoC) is a design principle where the framework, rather than your code, controls the creation and lifecycle of objects. Dependency Injection is how Spring implements IoC, automatically providing (injecting) an object’s dependencies through constructors, setters, or field annotations like @Autowired.
73. What is Spring Boot auto-configuration?
Auto-configuration automatically configures beans based on the dependencies present on the classpath and properties defined in the application, reducing the need for manual XML or Java-based configuration for common setups like a data source or a web server.
74. How do you build a REST API in Spring Boot?
You typically annotate a class with @RestController, map HTTP methods to handler methods using annotations like @GetMapping or @PostMapping, and let Spring handle request routing, JSON serialization, and response building automatically. For structured learning on building full REST APIs with Spring Boot, Codegnan’s Java Full Stack Developer course covers this hands-on.
75. What is Hibernate, and what problem does ORM solve?
Hibernate is an Object-Relational Mapping (ORM) framework that maps Java objects to database tables, letting developers work with objects instead of writing raw SQL for most operations. This reduces boilerplate JDBC code and helps keep data access logic more maintainable.
76. What is the difference between Session and SessionFactory in Hibernate?
SessionFactory is a heavyweight, thread-safe object created once per application (or per database) that produces Session instances. A Session represents a single unit of work with the database, is not thread-safe, and is typically short-lived, created and closed per request or transaction.
77. What is the difference between lazy and eager loading in Hibernate?
Lazy loading fetches related data only when it is actually accessed, which improves performance by avoiding unnecessary queries. Eager loading fetches related data immediately along with the parent entity, which can simplify code but may load more data than needed.
78. What is the N+1 select problem in Hibernate?
It occurs when fetching a list of N parent entities triggers one query for the parents and then one additional query per parent to fetch related child data, resulting in N+1 queries instead of a single optimized join, which can severely hurt performance on large datasets.
79. What are some commonly used Spring Boot annotations?
@RestController and @Controller define web layer components, @Service marks business logic classes, @Repository marks data access classes, @Autowired injects dependencies, @Entity maps a class to a database table, and @SpringBootApplication bootstraps the entire application.
Coding and scenario-based interview questions
80. How do you check if a string is a palindrome in Java?
Reverse the string (using StringBuilder’s reverse() method, for example) and compare it to the original, ignoring case and spaces if needed. This is a common warm-up question to check basic string manipulation skills.
81. How do you remove duplicate elements from an ArrayList?
The simplest way is to add the ArrayList’s elements into a LinkedHashSet (which preserves insertion order while removing duplicates) and then convert it back into a List, since Set implementations by definition do not allow duplicate values.
82. How would you find duplicate elements in an array using a HashSet?
Iterate through the array, and for each element, try adding it to a HashSet. If the add() method returns false, that element is already in the set, meaning it is a duplicate, which you can then collect into a result list.
83. How do you sort a HashMap by its values instead of its keys?
Convert the map’s entry set into a List of Map.Entry objects, then sort that list using a Comparator that compares Map.Entry::getValue, and optionally collect the sorted entries back into a LinkedHashMap to preserve the new order.
84. How would you implement the producer-consumer problem in Java?
A common approach uses a BlockingQueue, where producer threads add items with put() and consumer threads remove items with take(). The BlockingQueue internally handles waiting and signaling, so you get thread-safe coordination without manually managing wait() and notify().
85. How do you implement the Singleton design pattern in Java?
A common thread-safe approach declares a private static instance, a private constructor to prevent external instantiation, and a public static getInstance() method using double-checked locking or, more simply, an enum-based singleton, which is inherently thread-safe and protects against reflection-based attacks.
86. How do you find the second largest number in an array without sorting?
Track two variables, largest and secondLargest, while iterating through the array once. Whenever you find a value greater than the current largest, shift largest into secondLargest before updating largest, giving you an O(n) solution instead of the O(n log n) cost of sorting.
87. How would you solve FizzBuzz using Java Streams?
You can use IntStream.rangeClosed(1, n) combined with a mapToObj() call that checks divisibility by 3 and 5 and returns “Fizz”, “Buzz”, “FizzBuzz”, or the number as a string, then collect the results, showing you can apply functional-style thinking to a classic problem.
88. How do you design an immutable class in Java?
Declare the class as final, make all fields private and final, avoid setters, initialize all fields through the constructor, and if a field holds a mutable object (like a List or Date), return a defensive copy from any getter instead of the original reference.
89. How would you handle a scenario where multiple threads update a shared counter?
Wrapping the increment logic in a synchronized block, using an AtomicInteger from java.util.concurrent.atomic, or using a dedicated lock like ReentrantLock all prevent race conditions. AtomicInteger is generally preferred for simple counters since it uses lock-free, compare-and-swap operations for better performance.
90. How would you detect and fix a memory leak scenario in a Java application?
Look for objects that stay referenced longer than needed, such as static collections that keep growing, caches without eviction policies, or unclosed streams and connections. Tools like the JVM’s heap dump analyzers or profilers help identify which objects are accumulating, and the fix usually involves removing unnecessary references, closing resources properly (ideally with try-with-resources), or introducing a bounded cache.
Final tips for your Java interview
Interviewers rarely expect textbook definitions word for word; they are usually testing whether you understand the “why” behind a concept and can apply it to real code. Practice explaining these answers out loud, write small code snippets for the coding questions instead of just reading about them, and be ready to discuss trade-offs (like ArrayList vs LinkedList, or checked vs unchecked exceptions) rather than just definitions.
If you are preparing for interviews and want hands-on practice with mock interviews, live projects, and placement support, Codegnan’s Java Full Stack Developer program and Java course syllabus are built around exactly these fundamentals. You can also explore Java career paths and Java project ideas to strengthen your resume before your next interview.




