All posts

Java Interview Questions for Freshers: 25 Questions and the Follow-Ups Behind Them

Java Interview Questions for Freshers: 25 Questions and the Follow-Ups Behind Them

The interviewer asks how a HashMap works. You say "key-value pairs, O(1) lookup" and stop. They wait a second, then ask, "What happens when two keys land in the same bucket?" You know you read about this. You cannot find it.

That pause is where most fresher Java interviews are decided. The first question checks whether you have heard of something. The follow-up checks whether you understand it, and it comes almost every time.

The short answer

Core Java interview questions for freshers, the ones actually asked in a Java interview, come from a small, predictable pool: the JVM, OOP, Strings, equals and hashCode, keywords like final and static, collections, exceptions, generics, Java 8 features, basic threading and garbage collection. For each question below you get a model answer that explains why Java works that way, and the follow-up you are most likely to hear next. Learn the reasoning, not the wording, and say each answer out loud at least once.

If you want the wider plan around this list, our interview preparation guide for freshers covers it. This article is the Java question bank.

The JVM and the platform

1. What is the difference between the JDK, JRE and JVM?

The JVM runs bytecode: it loads classes, verifies them, interprets them and compiles hot code to machine code with the JIT compiler. The JRE is the JVM plus the standard class libraries, which is what you need to run a program. The JDK is the JRE plus development tools such as javac, jar and jdb, which is what you need to write one.

Likely follow-up: "Do you still download a separate JRE?" Not from Oracle since Java 11. You install a JDK, and if you need a slim runtime for deployment you build one with jlink.

2. Why is Java called platform independent?

Because javac compiles your code to bytecode, not to machine code for one processor. Any machine with a JVM can run that same .class file. The JVM itself is platform specific, which is the point: the platform dependence is pushed into the JVM so your code does not have to carry it.

Likely follow-up: "Is Java slow because it is interpreted?" Not for long-running code. The JIT compiler watches which methods run often and compiles them to native code, so a warmed-up Java program runs close to compiled speed.

OOP in Java

3. What are the four pillars of OOP, in Java terms?

Encapsulation is private fields with methods that control how they change. Abstraction is an interface or abstract class that lets callers use something without knowing how it works. Inheritance is extends, which reuses behaviour. Polymorphism is one call doing the right thing for different types, such as shape.area() working for both a Circle and a Square.

4. What is the difference between method overloading and overriding?

Overloading is several methods with the same name and different parameter lists in one class, and the compiler picks which one to call at compile time. Overriding is a subclass replacing a parent's method with the same signature, and the JVM picks which version runs at runtime based on the actual object. That is why overriding is runtime polymorphism and overloading is compile-time.

Likely follow-up: "Can you override a static method?" No. A static method with the same signature in a subclass hides the parent's one; which runs depends on the reference type, not the object.

5. Interface or abstract class: when would you pick each?

An abstract class can hold state (instance fields) and constructors, and a class can extend only one. An interface defines a capability, and a class can implement many. Since Java 8, interfaces can have default and static methods, and since Java 9 private methods, so the old "interfaces have no method bodies" answer is out of date. Pick an abstract class when related classes share state and code; pick an interface when unrelated classes need the same contract, like Comparable.

6. Explain the access modifiers.

private is visible only inside the class. No modifier (package-private) is visible inside the same package. protected adds subclasses in other packages. public is visible everywhere. Default to the narrowest that works.

Strings

7. Why are Strings immutable in Java?

Several reasons that reinforce each other. Immutable strings can be safely shared from the string pool. They are safe to pass between threads without locking. Their hash code can be cached, which makes them fast HashMap keys. And security-sensitive values like file paths cannot change after being checked.

8. What is the String pool, and what does == compare?

String literals are stored once in a pool and reused, so "java" == "java" is always true: the language guarantees identical literals refer to the same pooled object. new String("java") forces a new object on the heap, so == against the literal is false. == compares references; equals() compares contents. Always use equals() for strings. The pool has lived in the main heap since Java 7.

9. String, StringBuilder or StringBuffer?

Because String is immutable, concatenating in a loop creates a new object every iteration. StringBuilder is a mutable buffer you append to, so it is the right choice for building strings in a loop. StringBuffer does the same but every method is synchronized, which costs speed and is rarely needed, so StringBuilder is the default.

Core keywords and object basics

10. What is the contract between equals() and hashCode()?

If two objects are equal by equals(), they must return the same hashCode(). The reverse need not hold. Break it, and hash-based collections stop working: override equals() without hashCode(), and two "equal" objects can go into different buckets, so set.contains(x) returns false for something you just added.

Likely follow-up: "Should a HashMap key be mutable?" No. If a field used in hashCode() changes after insertion, the entry sits in the wrong bucket and cannot be found.

11. What is the difference between final, finally and finalize?

final stops change: a final variable cannot be reassigned, a final method cannot be overridden, a final class cannot be extended. finally is the block after try that runs whether or not an exception was thrown, used for cleanup. finalize() was a method the garbage collector might call before reclaiming an object. It was deprecated in Java 9 and deprecated for removal in Java 18, because nothing guaranteed when, or whether, it ran. Use try-with-resources instead.

Likely follow-up: "Does a final list mean the list cannot change?" No. The reference cannot be reassigned, but you can still add to the list.

12. What does static mean?

A static member belongs to the class, not to any object. A static field has one copy shared by every instance; a static method can be called without an object, which is why it cannot use this or instance fields directly. main is static because the JVM calls it before any object exists.

Collections

13. ArrayList or LinkedList?

ArrayList is backed by an array, so get(i) is O(1) and iteration is cache-friendly. Adding at the end is amortised O(1); inserting in the middle shifts elements. LinkedList is a doubly linked list, so get(i) is O(n). It is often said to be faster for insertion in the middle, but you have to walk to that position first, so in practice ArrayList wins in most real code.

14. How does a HashMap work internally?

It holds an array of buckets. On put, it calls the key's hashCode(), mixes the high bits into the low bits, and uses the result to pick a bucket index. If the bucket is empty, the entry goes in; if not, it walks the entries there, using equals() to find a matching key to replace, or adds a new node. When the number of entries passes capacity times the load factor (16 and 0.75 by default), the array doubles and entries are redistributed.

Likely follow-up: "What happens with lots of collisions?" Since Java 8, a bucket that grows past eight entries is converted from a linked list into a balanced tree (once the table has at least 64 buckets), so worst-case lookup in that bucket drops from O(n) to O(log n).

15. How does a HashSet ensure uniqueness?

A HashSet is backed by a HashMap. Each element is stored as a key with a dummy value, so uniqueness comes from the map's hashCode() and equals() logic. So a broken equals/hashCode contract lets duplicates in.

16. Why use ConcurrentHashMap instead of a synchronized HashMap?

Collections.synchronizedMap locks the whole map for every operation, so threads queue up. ConcurrentHashMap lets reads proceed without locking, and since Java 8 it writes using compare-and-swap on empty buckets and locks only the single bucket being changed. It also rejects null keys and values, because in a concurrent map a null from get would be ambiguous.

If collections feel shaky, go one level down: the data structures you must know covers what these classes are built on.

Exceptions and generics

17. Checked vs unchecked exceptions?

Checked exceptions (subclasses of Exception but not RuntimeException, like IOException) must be caught or declared with throws; the compiler enforces it because they describe failures a caller can reasonably recover from. Unchecked exceptions (RuntimeException and its subclasses, like NullPointerException) usually signal a bug, so forcing every caller to handle them would add noise. Error, like OutOfMemoryError, is for problems the application should not try to catch.

Likely follow-up: "What is try-with-resources?" Added in Java 7, it closes anything that implements AutoCloseable automatically when the block ends, even if an exception is thrown.

18. Why use generics, and what is type erasure?

Generics let the compiler check types, so List<String> will not accept an Integer and you do not need casts when reading. Type erasure means this checking happens only at compile time: at runtime a List<String> is just a List. That is why you cannot write new T() or check instanceof List<String>.

Java 8 features

19. What is a lambda, and what is a functional interface?

A functional interface has exactly one abstract method, like Runnable or Comparator. A lambda is a short way to provide that one method without writing an anonymous class: list.sort((a, b) -> a.length() - b.length()).

20. What are streams, and how are they different from collections?

A collection stores data. A stream describes a pipeline of operations over data: filter, map, then a terminal operation like collect or count. Intermediate operations are lazy, so nothing runs until the terminal operation, and a stream can be consumed only once.

Likely follow-up: "What is the difference between map and flatMap?" map turns each element into one result. flatMap turns each element into a stream and flattens them into one, which is what you want for a list of lists.

21. What is Optional for?

Optional makes "this might be missing" part of a method's return type, so the caller has to deal with it instead of discovering a NullPointerException later. Use orElse, orElseGet or map rather than calling get() without checking. It is meant for return values, not for fields or method parameters.

Threads and memory

22. Should you extend Thread or implement Runnable?

Implement Runnable (or Callable if you need a result). Java has single inheritance, so extending Thread uses up your one parent class, and it mixes the task with the mechanism that runs it. In real code you submit tasks to an ExecutorService. Since Java 21, virtual threads make it cheap to run very large numbers of tasks concurrently.

Likely follow-up: "What is the difference between start() and run()?" start() creates a new thread that then calls run(). Calling run() directly just executes it on the current thread.

23. What does synchronized do?

It makes a thread acquire an object's monitor lock before entering a method or block, so only one thread at a time runs code guarded by that lock. It also makes changes inside the block visible to the next thread that takes the lock. A synchronized instance method locks this; a synchronized static method locks the class object.

24. What does volatile do, and is it enough for a counter?

volatile guarantees that a write to the variable happens-before every later read of it by another thread, so readers always see the latest value, and accesses are not reordered around it. It does not make compound operations atomic. count++ is a read, an add and a write, so two threads can still lose an update. Use AtomicInteger or synchronized for counters; use volatile for simple flags like a running boolean.

25. How does garbage collection work, at a basic level?

Objects live on the heap. The garbage collector finds objects that can no longer be reached from any live reference (local variables, static fields, active threads) and reclaims their memory. Most collectors are generational, because most objects die young: new objects go in the young generation, which is collected often and cheaply, and survivors are promoted to the old generation. G1 has been the default collector on server-class machines since Java 9. You can request a collection with System.gc(), but the JVM is free to ignore it.

Likely follow-up: "Can you get a memory leak in Java?" Yes. If you keep references you no longer need, such as entries in a static map that is never cleared, the collector cannot reclaim them.

How to practise these

Reading these answers is not the same as giving them under a follow-up you did not expect; that gap is what why knowing the answer isn't enough is about. When you do hit a question you cannot answer, there is a better move than guessing: see how to handle a question you don't know.

Practise in pairs: one person asks a question, then asks "why?" twice. If you are preparing more than one language, the Python interview questions for freshers follow the same format.

To rehearse with someone who keeps asking, you can pick Java as your stack in a scored round on our Java interview practice page. Sia, the AI interviewer, asks one question at a time and follows up on what you actually said, and you get a written breakdown when you finish. When you want a person instead, a live 40-minute Zoom interview with a working engineer gives you scored, written feedback on technical depth, problem solving, communication, behaviour and code quality.