Skip to content

PUBLIC QUESTION PREVIEW

Java interview questions

JVM, collections, concurrency, Spring basics, generics, streams.

Showing 12 of 50 source questions. Sample answers are study material, not employer-specific hiring guidance.

How to work through this preview

Attempt each question before reading its answer. For a concept, give a definition and a concrete example. For code, state constraints, walk through a small input, and check complexity. For design, separate requirements from assumptions and explain failure handling. Use real situations for behavioral answers.

QUESTION 1 / medium / conceptual

What is the difference between HashMap and ConcurrentHashMap?

Sample answer

HashMap: not thread-safe. Concurrent modifications can cause data corruption or infinite loops. Use only in single-threaded contexts. ConcurrentHashMap: thread-safe without locking the whole map. In Java 8+, it uses CAS (Compare-And-Swap) operations and synchronized blocks only at the bucket level, allowing high concurrency. Alternatives: Collections.synchronizedMap(new HashMap<>()) — synchronizes every operation on the whole map (coarse lock, worse throughput). ConcurrentHashMap is almost always preferred for concurrent use.

Hints to guide your next attempt

  • Thread safety
  • ConcurrentHashMap uses segment-level locking

Source tags: hashmap / concurrency / thread-safety / java

QUESTION 2 / easy / conceptual

What is the difference between checked and unchecked exceptions in Java?

Sample answer

Checked exceptions: subclasses of Exception (not RuntimeException). Must be either caught (try-catch) or declared in the method signature (throws). Examples: IOException, SQLException. The compiler enforces this. Unchecked exceptions: subclasses of RuntimeException or Error. Don't need to be declared or caught. Examples: NullPointerException, ArrayIndexOutOfBoundsException, IllegalArgumentException. Design guidance: use checked for recoverable conditions (file not found — try another path), unchecked for programming errors (null dereference — fix the code).

Hints to guide your next attempt

  • Checked exceptions must be handled or declared
  • RuntimeException and its subclasses are unchecked

Source tags: exceptions / checked / unchecked / error-handling / java

QUESTION 3 / medium / conceptual

How does the Java garbage collector work? What is a memory leak in Java?

Sample answer

Java GC automatically frees objects that are no longer reachable from GC roots (local variables, static fields, active threads). Modern JVMs use generational GC: most objects die young (Eden space), survivors are promoted to older generations. Memory leak in Java: objects that are still referenced but never used again. Examples: - Static collections that grow forever - Unclosed resources (streams, DB connections) - Inner class instances holding outer class references - Caches without eviction Tools: VisualVM, Eclipse MAT for heap dump analysis.

Hints to guide your next attempt

  • GC traces reachability from GC roots
  • Memory leaks happen when objects are reachable but no longer needed

Source tags: garbage-collection / memory-leak / jvm / java

QUESTION 4 / easy / conceptual

What is the difference between == and .equals() in Java?

Supplied choices

  1. == compares content; .equals() compares references
  2. They are identical for String comparisons
  3. == compares references (memory address) for objects; .equals() compares logical content if overridden
  4. .equals() is only defined on String — other classes use == for equality

Source answer choice: C. == compares references (memory address) for objects; .equals() compares logical content if overridden

Sample answer

== : compares references for objects — "do both variables point to the same object in memory?" For primitives (int, char), == compares values. .equals(): compares content — implemented by the class. String, Integer, and most value objects override it for logical equality. String a = new String("hello"); String b = new String("hello"); a == b; // false — different objects a.equals(b); // true — same content String literals are interned, so "hello" == "hello" may be true — but never rely on this. For custom classes: always override equals() (and hashCode() together) if two objects with the same fields should be considered equal. Failing to override hashCode() when overriding equals() breaks HashMaps and Sets.

Hints to guide your next attempt

  • == compares references for objects
  • .equals() compares content (if overridden)

Source tags: equality / string / java

QUESTION 5 / easy / conceptual

What is the Java Collections Framework? When do you use List vs Set vs Map?

Sample answer

List<T>: ordered, indexed, duplicates allowed. ArrayList — O(1) random access; LinkedList — O(1) insert/delete at ends. Set<T>: unique elements, no duplicates. - HashSet: O(1) ops, no order (backed by HashMap) - LinkedHashSet: insertion order maintained - TreeSet: sorted order, O(log n) ops Map<K,V>: key-value pairs, keys unique. - HashMap: O(1) avg, no order - LinkedHashMap: insertion order - TreeMap: sorted by key Choosing: - Need order + duplicates + index access → ArrayList - Fast lookup by key → HashMap - Uniqueness constraint → HashSet - Sorted data → TreeMap / TreeSet - Thread-safe → ConcurrentHashMap, CopyOnWriteArrayList

Hints to guide your next attempt

  • List = ordered, duplicates allowed; Set = unique elements; Map = key-value pairs

Source tags: collections / list / set / map / java

QUESTION 6 / medium / conceptual

What are Java Streams? Explain lazy evaluation, intermediate vs terminal operations.

Sample answer

Streams provide a declarative pipeline to process collections. They are lazy — intermediate operations are not executed until a terminal operation triggers evaluation. List<String> result = employees.stream() .filter(e -> e.getSalary() > 50000) // intermediate — lazy .map(Employee::getName) // intermediate — lazy .sorted() // intermediate — lazy .collect(Collectors.toList()); // terminal — triggers execution Intermediate operations (return Stream): filter(), map(), flatMap(), sorted(), distinct(), limit(), skip() Terminal operations (produce result): collect(), forEach(), count(), findFirst(), anyMatch(), reduce(), toList() Parallel streams: .parallelStream() — uses ForkJoinPool for parallel processing. Good for CPU-bound, independent operations on large collections. Bad for small collections or operations with shared state. Short-circuit operations: findFirst(), anyMatch(), limit() — stop processing as soon as possible.

Hints to guide your next attempt

  • Streams are lazy — nothing executes until a terminal operation
  • Intermediate operations return Stream; terminal operations produce a result

Source tags: streams / lambda / lazy-evaluation / java-8 / java

QUESTION 7 / easy / conceptual

Why is String immutable in Java? What is the String pool?

Supplied choices

  1. String is mutable — it uses a char[] internally that can be modified
  2. String is immutable for performance only — thread safety is handled separately
  3. String is immutable to enable pool interning, thread-safety, and hashcode caching; any modification creates a new object
  4. String pool stores all String objects regardless of how they were created

Source answer choice: C. String is immutable to enable pool interning, thread-safety, and hashcode caching; any modification creates a new object

Sample answer

String is immutable in Java — once created, its characters cannot be changed. Any operation (concat, replace) returns a new String object. Why immutable: 1. Thread-safety: strings can be shared across threads without synchronization 2. String pool (interning): the JVM caches string literals — "hello" anywhere in the code points to the same pool object, saving memory 3. Hashcode caching: used constantly as HashMap keys — immutability lets the hash be computed once and cached 4. Security: class names, URLs, credentials can't be changed mid-flight String pool: String a = "hello"; // from pool String b = "hello"; // same pool object — a == b is true String c = new String("hello"); // explicit heap allocation — a == c is false String.intern() forces a string onto the pool. For frequent string building, use StringBuilder (mutable, O(1) amortized append) instead of + concatenation in loops (creates O(n) intermediate objects).

Hints to guide your next attempt

  • Immutability enables safe sharing and caching
  • String literals are interned — stored in the pool

Source tags: string / immutability / string-pool / interning / java

QUESTION 8 / easy / conceptual

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

Supplied choices

  1. Abstract classes allow multiple inheritance; interfaces allow only single inheritance
  2. Interfaces can have constructors; abstract classes cannot
  3. Abstract classes can have state and constructors; interfaces define contracts; a class can implement multiple interfaces but extend only one class
  4. There is no practical difference in Java 8+ since interfaces can have default methods

Source answer choice: C. Abstract classes can have state and constructors; interfaces define contracts; a class can implement multiple interfaces but extend only one class

Sample answer

Abstract class: can have state (fields), constructors, concrete methods, and abstract methods. A class can extend only ONE abstract class. Interface: traditionally all-abstract (pre-Java 8). A class can implement MULTIPLE interfaces. No state (only static final constants). Java 8+ blurred the line: - default methods: interfaces can now provide method implementations - static methods in interfaces - Java 9: private methods in interfaces Choose abstract class when: - Sharing state or concrete behavior among closely related classes - Defining a template method pattern (skeleton algorithm with hook methods) Choose interface when: - Defining a contract/capability unrelated to class hierarchy (Serializable, Comparable, Runnable) - Multiple inheritance of behavior - Defining APIs that many unrelated classes will implement In modern Java, prefer interfaces for most abstractions. Use abstract classes when you genuinely need shared state or constructor logic.

Hints to guide your next attempt

  • Multiple inheritance of interfaces vs single class inheritance
  • Java 8 default methods blurred the line

Source tags: interface / abstract-class / inheritance / java

QUESTION 9 / medium / conceptual

What is the synchronized keyword in Java? When would you use volatile instead?

Sample answer

synchronized: provides mutual exclusion (only one thread executes the block) AND memory visibility (changes are flushed to main memory and visible to other threads). Can apply to: method (lock on this/class), block (lock on specific object). synchronized void increment() { count++; } // one thread at a time volatile: ensures memory visibility only — every read comes directly from main memory, every write is immediately visible. Does NOT provide atomicity. private volatile boolean running = true; // safe flag for loop control void stop() { running = false; } void run() { while (running) { ... } } Use volatile when: - One thread writes, others read (no compound operations) - Simple boolean flags, status indicators Use synchronized (or Atomic classes) when: - Multiple threads write - Compound operations (check-then-act, read-modify-write like ++) For counters: prefer AtomicInteger (CAS — no lock overhead) over synchronized.

Hints to guide your next attempt

  • synchronized = mutual exclusion + memory visibility
  • volatile = memory visibility only, no atomicity

Source tags: synchronized / volatile / concurrency / thread-safety / java

QUESTION 10 / easy / conceptual

What is the difference between Comparable and Comparator in Java?

Supplied choices

  1. Comparable is for custom objects; Comparator is only for primitives
  2. Both are identical — Comparator is just a lambda-friendly version of Comparable
  3. Comparable defines natural ordering within the class (one ordering); Comparator is external and allows multiple orderings
  4. Comparator is deprecated in Java 8+ — use Comparable instead

Source answer choice: C. Comparable defines natural ordering within the class (one ordering); Comparator is external and allows multiple orderings

Sample answer

Comparable<T>: the class defines its own natural ordering by implementing compareTo(). One ordering per class. public class Employee implements Comparable<Employee> { public int compareTo(Employee other) { return this.name.compareTo(other.name); // natural order = by name } } Collections.sort(employees); // uses compareTo Comparator<T>: external ordering logic, decoupled from the class. Multiple orderings possible. Comparator<Employee> bySalary = Comparator.comparingDouble(Employee::getSalary); Comparator<Employee> byNameThenSalary = Comparator.comparing(Employee::getName) .thenComparingDouble(Employee::getSalary); employees.sort(bySalary); employees.stream().sorted(byNameThenSalary).collect(toList()); Use Comparable for the default/natural ordering (alphabetical, chronological). Use Comparator when you need multiple orderings or can't modify the class.

Hints to guide your next attempt

  • Comparable = natural order (intrinsic to the class)
  • Comparator = external, flexible ordering

Source tags: comparable / comparator / sorting / java

QUESTION 11 / medium / conceptual

What is Optional in Java 8? How does it prevent NullPointerException?

Supplied choices

  1. Optional is a replacement for null — always use it instead of returning null
  2. Optional eliminates NullPointerException by making the compiler enforce null checks
  3. Optional explicitly represents absence in a return type, forcing callers to handle the empty case through its API
  4. Optional should be used as method parameters to indicate optional arguments

Source answer choice: C. Optional explicitly represents absence in a return type, forcing callers to handle the empty case through its API

Sample answer

Optional<T> is a container that either holds a value or is empty — it makes the possibility of absence explicit in the API signature. // Without Optional — unclear if null is a valid return User findUser(int id) { ... } // returns null if not found? // With Optional — contract is clear Optional<User> findUser(int id) { ... } // Usage: Optional<User> user = repo.findUser(42); // Safe patterns: user.ifPresent(u -> System.out.println(u.getName())); String name = user.map(User::getName).orElse("Anonymous"); User u = user.orElseThrow(() -> new NotFoundException(42)); // Anti-patterns: user.get(); // NPE risk if empty — never do this without isPresent() Optional<Optional<T>> // nesting — always wrong void method(Optional<T> param) // don't use as method parameter — use overloads instead Use Optional as return types from methods that legitimately may not find a result. Don't use for fields or collections (use empty collection instead).

Hints to guide your next attempt

  • Optional wraps a potentially-null value and forces the caller to handle the empty case
  • Never use Optional.get() without isPresent() check

Source tags: optional / null-safety / java-8 / java

QUESTION 12 / easy / conceptual

What is the difference between ArrayList and LinkedList in Java?

Supplied choices

  1. LinkedList is always faster than ArrayList for all operations
  2. ArrayList uses more memory than LinkedList
  3. ArrayList is O(1) random access with O(n) middle inserts; LinkedList is O(n) random access with O(1) insert at known position
  4. They have identical performance — ArrayList is just syntactic sugar for LinkedList

Source answer choice: C. ArrayList is O(1) random access with O(n) middle inserts; LinkedList is O(n) random access with O(1) insert at known position

Sample answer

ArrayList: backed by a dynamic array. Resizes by 50% when full. - O(1) random access by index (get(i)) - O(n) insert/delete in the middle (elements shift) - O(1) amortized append at end - Good cache locality — contiguous memory LinkedList: doubly-linked list. Each node stores prev/next pointers. - O(n) random access (must traverse) - O(1) insert/delete at known position (just pointer update) - O(1) insert/delete at head or tail - More memory overhead (two pointers per node) In practice: ArrayList is almost always better due to cache-friendly access patterns. The O(1) insert/delete advantage of LinkedList rarely materializes because you still need O(n) to find the position. Use LinkedList when: implementing a queue (poll/offer at head/tail), frequent insert/delete at both ends, and you never need index access.

Hints to guide your next attempt

  • Dynamic array vs doubly-linked list
  • Random access vs insert/delete performance

Source tags: arraylist / linkedlist / collections / time-complexity / java

Check understanding, not recognition

  • Can you explain the answer without reading it?
  • Can you show when the approach fails or needs a different assumption?
  • Can you connect the concept to a real project, task, or decision you have made?
  • Can you distinguish a simplified interview example from a production requirement?

A LITTLE MORE CLARITY

Frequently asked questions

How many Java questions are shown here?

This public preview shows 12 questions with the supplied answers from the app's 50-question Java bank. Full interactive practice requires signing in.

Should I memorize the sample answers?

Use them as reference explanations, not a script or a guarantee of technical correctness for every environment. Explain your assumptions, validate code against your language and version, and discuss trade-offs. Behavioral answers should be built from your own experience.

What do hints and solution steps mean?

Hints identify ideas to consider before reading the answer. When the source question includes steps, they are shown as a separate walkthrough. Example capacities and design targets in a solution are assumptions for that exercise, not real system statistics.

BUILD YOUR NEXT OPPORTUNITY

Practice Java actively.

Sign in to use the full topic bank and interactive practice workspace.

Open Topic Practice