⚡ Play a quiz
HomeInterview questions › Java
30 questions with answers

Java Interview Questions and Answers for Freshers

30 questions, written and maintained by the JBattle team · Last updated

These are the Java questions that actually come up in fresher and campus interviews, answered the way you would say them out loud. Most carry the follow-up question an interviewer asks next — because the first answer rarely ends the exchange, and the second one is where candidates are least prepared.

🎤 Practise these in an AI mock interview
Questions
30
Basic
10
Intermediate
12
Advanced
8

Language fundamentals

The opening questions. Short answers, asked to check you are not bluffing.

Basic
Q1

What is the difference between JDK, JRE and JVM?

JVM is the runtime that executes bytecode — it is what makes Java portable, because each platform ships its own JVM. JRE is the JVM plus the standard class libraries: enough to run a Java program. JDK is the JRE plus the development tools — the compiler javac, the debugger, and so on. You need the JDK to build, only the JRE to run.
The follow-upThen: what does "write once, run anywhere" actually mean? The answer is that javac produces bytecode, not machine code, and each platform's JVM translates that bytecode for its own hardware.
Intermediate
Q2

Is Java pass-by-value or pass-by-reference?

Always pass-by-value. For objects, the value being copied is the reference — so a method can change the object's state and the caller sees it, but reassigning the parameter only points the local copy somewhere else and the caller sees nothing.
void mutate(StringBuilder sb)   { sb.append(" world"); }   // caller sees it
void reassign(StringBuilder sb) { sb = new StringBuilder("bye"); } // caller does not
The follow-upThis is the single most mis-answered Java question. Saying "pass-by-reference for objects" is the wrong answer, and interviewers are listening for it.
Basic
Q3

What is the difference between == and equals()?

== compares references — whether two variables point at the same object. equals() compares contents, as the class defines them. For strings, == appears to work for literals because they are interned in a shared pool, then fails the moment a string comes from user input or is built at runtime.
The follow-upFollowed by: if you override equals(), what else must you override? hashCode() — equal objects must produce equal hash codes, or the object breaks as a HashMap key.
Basic
Q4

What is the difference between final, finally and finalize?

They share four letters and nothing else. final is a modifier: a variable cannot be reassigned, a method cannot be overridden, a class cannot be extended. finally is a block that runs after try/catch whether or not an exception was thrown, used for cleanup. finalize() was a method called before garbage collection; it is deprecated since Java 9 — use try-with-resources.
The follow-upDoes final make an object immutable? No — it freezes the reference, not the object. A final List can still have elements added.
Intermediate
Q5

Why is String immutable in Java?

So strings can be shared freely without defensive copying: many references can point at one string with no risk of one holder changing it under another. It also lets the hash code be cached, which is what makes strings good map keys, allows identical literals to be interned into one object, and makes strings thread-safe for free.
The follow-upThen: what is the difference between String, StringBuilder and StringBuffer? String is immutable; StringBuilder is a mutable buffer for single-threaded building; StringBuffer is the same with synchronised methods, so thread-safe but slower.
Intermediate
Q6

Why is concatenating strings in a loop slow?

Because each concatenation allocates a new string and copies everything accumulated so far. Copy lengths 1, 2, 3 … n sum to n(n+1)/2, so the loop is O(n²). A StringBuilder writes into one growable buffer and copies once at the end, making it O(n).
Advanced
Q7

What is autoboxing, and where does it bite?

Autoboxing is the compiler converting between primitives and their wrapper types automatically — int to Integer and back. It bites in two places: comparing wrappers with == compares references (and passes for small values only, because -128 to 127 are cached), and unboxing a null Integer throws a NullPointerException on what looks like plain arithmetic.
Integer a = 127, b = 127;
Integer c = 128, d = 128;
System.out.println(a == b);   // true  - both from the Integer cache
System.out.println(c == d);   // false - two different objects

OOP and design

Where memorised definitions fall apart on the first follow-up.

Basic
Q8

What are the four pillars of OOP?

Encapsulation — keep state private and expose behaviour, so invariants are enforced in one place. Abstraction — hide how something works behind a contract, so callers survive change. Inheritance — a subclass is a kind of its parent and can be used wherever the parent is. Polymorphism — the same call dispatches to different implementations depending on the actual object.
The follow-upDo not stop at the definitions. Say what each one buys: encapsulation protects invariants, abstraction absorbs change, polymorphism deletes branching on type.
Intermediate
Q9

What is the difference between abstraction and encapsulation?

Encapsulation hides data so invalid states cannot be created from outside — private fields, public operations. Abstraction hides implementation behind a contract, so the thing behind it can be swapped. One protects the object's invariants; the other protects the caller from change.
Basic
Q10

What is the difference between overloading and overriding?

Overloading is several methods with the same name and different parameter lists, resolved by the compiler from the declared types — compile-time polymorphism. Overriding is a subclass replacing a parent method with the same signature, resolved at runtime from the actual object — runtime polymorphism.
The follow-upCan you override a static method? No — statics are resolved from the declared type. Redeclaring one in a subclass is hiding, not overriding, and it behaves differently.
Intermediate
Q11

Abstract class or interface — which do you choose?

An abstract class can hold instance fields, a constructor and shared implementation, and a class can extend only one. An interface defines a capability, holds no instance state, and a class can implement many. Reach for an interface first: it keeps the single inheritance slot free. Move to an abstract class only when subclasses genuinely share state.
The follow-upSince Java 8 interfaces can have default methods, so "interfaces can't have bodies" is out of date — say so, it shows you have kept up.
Advanced
Q12

Why is composition preferred over inheritance?

Inheritance is permanent compile-time coupling to a parent's internals: change the base class and every subclass shifts under it, you get one parent only, and orthogonal traits force a class per combination. Composition holds an object behind a contract instead — swappable at runtime, easy to fake in tests, and capabilities combine freely. Use inheritance only when the subclass is genuinely substitutable for the parent everywhere.
The follow-upThe classic example: Penguin extends Bird has to throw from fly(). A class that must refuse an inherited method is a sign the hierarchy is wrong — that is a Liskov violation.
Advanced
Q13

What is a marker interface?

An interface with no methods, used purely to tag a class so that some other code can check the type — Serializable and Cloneable are the standard examples. Annotations have largely replaced the pattern, because they carry data and do not consume an interface slot.

Collections

The most-asked area after OOP. Every answer should name a cost.

Basic
Q14

What is the difference between ArrayList and LinkedList?

ArrayList is backed by a resizable array: O(1) access by index, O(n) insertion at the front, and excellent cache behaviour because the elements sit together in memory. LinkedList is a doubly linked list: O(1) insertion at the ends, O(n) access by index, and more memory per element for the node pointers.
The follow-upWhich do you actually use? ArrayList, nearly always — LinkedList wins on paper and loses in practice because pointer chasing defeats the CPU cache. For cheap operations at both ends, use ArrayDeque, not LinkedList.
Intermediate
Q15

How does HashMap work internally?

The key's hashCode() is computed and reduced into the table's range to pick a bucket, and the entry is stored there. Lookup repeats the same computation and goes straight to that bucket, which is why it is O(1) on average. Keys that collide share a bucket as a linked list; since Java 8, a bucket that grows past eight entries in a large enough table converts to a balanced tree, so the worst case per bucket is O(log n) rather than O(n).
The follow-upThen: what is the load factor? Entries divided by buckets. Past 0.75, the table doubles and every entry is rehashed.
Advanced
Q16

What happens if you use a mutable object as a HashMap key?

The bucket was chosen from the key's hash at insertion time. Change a field the hash depends on, and the entry becomes unreachable — get() computes a different bucket and finds nothing, while the entry still sits in memory. Map keys should be immutable.
Intermediate
Q17

When would you use a TreeMap instead of a HashMap?

When you need keys in sorted order, or range operations — firstKey(), floorKey(), headMap(), subMap(). You pay O(log n) per operation instead of O(1) average, and that is the trade. "Give me the largest key not exceeding x" is the signal.
Advanced
Q18

HashMap or ConcurrentHashMap for a map several threads write to?

ConcurrentHashMap. A plain HashMap under concurrent writes can corrupt its internal structure — historically it could even spin forever during a resize. Hashtable and Collections.synchronizedMap are safe but lock the whole map per operation, so threads queue; ConcurrentHashMap locks far more narrowly and scales.
Intermediate
Q19

What causes a ConcurrentModificationException?

Structurally modifying a collection while iterating it with a for-each loop. The iterator notices the modification count changed and fails fast, deliberately, so you get an exception rather than silently skipped elements. Use Iterator.remove(), or removeIf(), or iterate over a copy.
for (String s : list) { if (s.isEmpty()) list.remove(s); }  // throws
list.removeIf(String::isEmpty);                            // correct
Intermediate
Q20

Why does Arrays.asList() throw on add()?

It returns a fixed-size view backed by the original array, not a new list — so writes to existing positions pass through, but adding or removing has nowhere to go and throws UnsupportedOperationException. Wrap it when you need a real list: new ArrayList<>(Arrays.asList(...)).

Exceptions

Asked to see whether you have debugged real code or only written it.

Basic
Q21

What is the difference between a checked and an unchecked exception?

Checked exceptions extend Exception and must be caught or declared — they represent conditions a correct program should anticipate, like a missing file. Unchecked exceptions extend RuntimeException and need neither — they usually signal a programming bug, like dereferencing null or indexing past the end.
Basic
Q22

What is the difference between throw and throws?

throw is a statement that raises an exception right now. throws is part of a method signature, declaring what the method may propagate to its caller.
Advanced
Q23

Can a finally block stop an exception from propagating?

Yes, and that is exactly why you should not let it. A return or a throw inside finally replaces whatever was in flight, so the original exception disappears and the real cause of a failure is silently swallowed. Keep finally to cleanup, or better, use try-with-resources.
Intermediate
Q24

What is try-with-resources?

A try block that declares resources implementing AutoCloseable and closes them automatically, in reverse order, even if the body throws. It replaces the nested try/finally close pattern, and it also handles the case where both the body and close() throw — the close exception is attached as suppressed rather than replacing the real one.
Basic
Q25

What actually causes a NullPointerException, and how do you avoid it?

Calling a method or reading a field on a reference that is null. Avoid it by not returning null from your own methods — return an empty collection or an Optional — by validating arguments at the boundary, and by comparing constants first ("ADMIN".equals(role) rather than the other way round). From Java 14, helpful NullPointerException messages name the exact expression that was null, which usually ends the debugging in one read.

JVM and memory

The area that separates candidates who understand the runtime from those who know the syntax.

Intermediate
Q26

What is the difference between stack and heap memory?

The stack holds local variables, parameters and references, one per thread, and unwinds automatically when a method returns — which is why locals are thread-safe for free. The heap holds every object and array, is shared across all threads, and is reclaimed by the garbage collector. Exhausting them gives you StackOverflowError and OutOfMemoryError respectively.
Advanced
Q27

How does garbage collection decide what to remove?

By reachability, not reference counting. An object is collectable when no live root — a running thread's stack, a static field — can reach it. That is why two objects referring only to each other are both collected correctly. The heap is split by age because most objects die young: new objects go in the young generation, collected often and cheaply; survivors are promoted to the old generation, collected rarely and expensively.
The follow-upThen: can a Java program leak memory? Yes — a growing static map, a listener never unregistered, a cache with no eviction. Those objects are still reachable, so the collector correctly keeps them forever.
Intermediate
Q28

Should you ever call System.gc()?

No. It is a suggestion the JVM may ignore, and when it does not, it usually forces an expensive full collection at a moment the collector had good reason to avoid. If you are calling it to fix a memory problem, the problem is a retained reference, not the collector's timing.
Advanced
Q29

What does the volatile keyword do?

It guarantees visibility: a write by one thread is seen by every other thread, because reads and writes go to main memory instead of a per-CPU cache, and the compiler may not reorder around it. It does not give atomicity — count++ on a volatile field is still a read, an add and a write, and two threads can still interleave and lose an update. For that you need AtomicInteger or a lock.
Basic
Q30

What is the difference between a process and a thread?

A process has its own memory space; threads live inside one process and share its heap. That sharing is what makes threads cheap to create and communicate between, and it is also the entire reason synchronisation exists.

Reading answers is not the same as giving them

Most candidates know the material and still stumble when asked out loud. Take a Java mock interview where the AI follows up on what you actually say.

🎤 Start a Java mock interview

Learn it properly first

If any answer above needed more than a paragraph, the structured lessons go deeper: Java on JBattle Learn.

Other interview question sets

JavaScript
JavaScript interview questions with real answers
26 questions
Python
Python interview questions with real answers
25 questions
SQL
SQL interview questions with real answers and queries
25 questions
React
React interview questions with real answers
23 questions
Spring Boot
Spring Boot interview questions with real answers
24 questions
DSA
DSA interview questions with real answers
24 questions
System Design
System design interview questions with real answers
23 questions