HomeBytesheetsRoadmapsUI TemplatesUI ToolsStack Discussion
75 Topics
Chapter•390 Minutes

Java Progressive Master Question Bank

75 progressive Java interview questions complete with technical explanations, key takeaways, diagrams, code examples, and interactive knowledge check quizzes.

Q51: What are the differences between CountDownLatch and CyclicBarrier?

  • CountDownLatch: One or more threads wait until a set of operations in other threads complete (count decrements to zero via countDown()). One-time use; count cannot be reset.
  • CyclicBarrier: A set of threads wait for each other to reach a common barrier point (await()). Reusable; resets automatically after threads are released.
Key Takeaways
  • CountDownLatch = One-time count decrementer. CyclicBarrier = Reusable thread synchronization barrier.
Knowledge Check

Which synchronization utility can be reset and reused repeatedly across processing cycles?

Q52: How does ThreadLocal work internally and what causes ThreadLocal Memory Leaks?

ThreadLocal stores thread-confined state. Each Thread instance contains a private ThreadLocalMap where keys are WeakReference<ThreadLocal<?>> and values are strong object references.

  • Memory Leak in Thread Pools: Thread pool worker threads are reused indefinitely. If a ThreadLocal value is not explicitly removed via threadLocal.remove(), the strong value reference persists inside the thread's ThreadLocalMap, leaking memory across executions.
Safe ThreadLocal Cleanup Pattern
public class UserContext {
    private static final ThreadLocal<User> context = new ThreadLocal<>();

    public static void set(User user) { context.set(user); }
    public static User get() { return context.get(); }
    public static void clear() { context.remove(); } // Mandatory cleanup
}

// Usage in web filter
try {
    UserContext.set(authenticatedUser);
    chain.doFilter(request, response);
} finally {
    UserContext.clear(); // Prevents thread pool memory leak
}
💡 Clearing ThreadLocal inside finally blocks prevents thread pool worker reference leaks.
Key Takeaways
  • ThreadLocal isolates state per thread.
  • ALWAYS call threadLocal.remove() in finally blocks when using thread pools.
Knowledge Check

Why must threadLocal.remove() be invoked when executing inside web application thread pools?

Q53: What are Lambda Expressions and Functional Interfaces in Java 8?

  • Functional Interface: An interface containing exactly one abstract method (annotated with @FunctionalInterface). Examples: Runnable, Callable, Comparator.
  • Lambda Expression: Concise anonymous method implementation ($(text{params}) to {text{body}}$). Invoked via bytecode instruction invokedynamic.
Key Takeaways
  • Functional Interfaces hold exactly one abstract method.
  • Lambdas compile to invokedynamic call sites instead of anonymous class allocations.
Knowledge Check

Can an interface annotated with @FunctionalInterface contain default and static methods?

Q54: What are the primary built-in Functional Interfaces in java.util.function?

  1. Predicate<T>: boolean test(T t) — Accepts input, returns boolean.
  2. Function<T, R>: R apply(T t) — Accepts input $T$, transforms and returns result $R$.
  3. Consumer<T>: void accept(T t) — Accepts input, returns void (side-effects).
  4. Supplier<T>: T get() — Accepts no input, produces result $T$.
  5. UnaryOperator<T>: T apply(T t) — Function where input and output types match.
Key Takeaways
  • Predicate: Test condition ($T o ext{boolean}$). Function: Transform data ($T o R$). Consumer: Execute action ($T o ext{void}$). Supplier: Supply value ($emptyset o T$).
Knowledge Check

Which functional interface signature accepts an argument and returns NO output result (void)?

Q55: How does the Java Stream API distinguish between Intermediate and Terminal Operations?

  • Intermediate Operations (filter, map, flatMap, sorted):
    • Return a new Stream.
    • Lazy evaluation: No element processing occurs until a terminal operation is invoked.
  • Terminal Operations (collect, forEach, reduce, findFirst):
    • Trigger element processing pipeline execution.
    • Produce a non-Stream result or side-effect, closing the Stream pipeline.
Stream Pipeline Execution
List<String> names = List.of("Alice", "Bob", "Charlie");

// Intermediate operations evaluated ONLY when count() terminal operation fires
long count = names.stream()
    .filter(name -> name.length() > 3) // Intermediate
    .map(String::toUpperCase)          // Intermediate
    .count();                          // Terminal (triggers execution)
💡 Filter and map steps execute lazily during the final count() processing pass.
Key Takeaways
  • Intermediate operations are lazy and return a new Stream.
  • Terminal operations trigger pipeline evaluation and close the stream.
Knowledge Check

What happens if a Stream pipeline contains multiple intermediate operations but NO terminal operation?

Q56: What is the difference between map() and flatMap() in Java Streams?

  • map(): $1 o 1$ transformation. Applies a mapping function to each element, returning Stream<T>.
  • flatMap(): $1 o N$ transformation. Applies a function that returns a Stream for each element, flattening nested streams (Stream<Stream<T>>) into a single unified Stream<T>.
flatMap Example
List<List<String>> nestedList = List.of(
    List.of("A", "B"),
    List.of("C", "D")
);

List<String> flatList = nestedList.stream()
    .flatMap(Collection::stream) // Flattens nested streams into one stream
    .toList(); // [A, B, C, D]
💡 flatMap extracts elements from inner collections and merges them into a single linear stream.
Key Takeaways
  • map() transforms values 1-to-1 (List<String> -> List<Integer>). flatMap() flattens nested structures (List<List<String>> -> List<String>).
Knowledge Check

Which operation should be used to transform a List<Order> (where each Order contains a List<Item>) into a single flat List<Item>?

Q57: What is Optional<T> and what are its anti-patterns?

Optional<T> is a single-value container introduced in Java 8 to represent present or absent values explicitly without returning null.

  • Good Practices: Use as method return type to signal potential missing values explicitly. Use orElseGet() for lazy default generation.
  • Anti-Patterns: Avoid using Optional as class instance fields, method parameters, or collection wrapper items (List<Optional<T>>). Avoid calling .get() without isPresent() verification.
Key Takeaways
  • Use Optional for method return types.
  • Avoid using Optional for class instance fields or method parameter parameters.
Knowledge Check

Why is opt.orElseGet(() -> defaultValue) preferred over opt.orElse(defaultValue)?

Q58: What are Method References and what are the four syntax variants?

Method References are shorthand lambda syntaxes (Class::method).

  1. Static Method: ContainingClass::staticMethodName (Math::max)
  2. Instance Method of Particular Object: containingObject::instanceMethodName (System.out::println)
  3. Instance Method of Arbitrary Object of Type: ContainingType::methodName (String::toUpperCase)
  4. Constructor Reference: ClassName::new (ArrayList::new)
Key Takeaways
  • Method references provide clean syntax shortcuts for lambda methods.
Knowledge Check

Which method reference syntax corresponds to the lambda expression (String s) -> s.toLowerCase()?

Q59: How do Parallel Streams work and what pitfalls do they present?

Parallel Streams (list.parallelStream()) partition stream workloads into sub-tasks executed concurrently on the shared ForkJoinPool.commonPool().

  • Pitfalls:
    1. Sharing commonPool() with blocking I/O operations starves other application tasks.
    2. Operations with stateful or non-thread-safe accumulators produce race conditions.
    3. Overhead for small collections makes parallel processing slower than sequential iterations.
Key Takeaways
  • Parallel streams use the shared ForkJoinPool.commonPool().
  • Avoid using parallel streams for blocking I/O tasks or small collections.
Knowledge Check

Which shared thread pool executes parallel stream operations by default?

Q60: What is a Spliterator in Java 8?

Spliterator (Splittable Iterator) traverses and splits elements of a data source. It powers the Stream API.

  • Key Methods: tryAdvance() (processes next single element), trySplit() (splits prefix portion into a new Spliterator for parallel thread execution), estimateSize(), characteristics().
Key Takeaways
  • Spliterator splits streams for parallel thread processing via trySplit().
Knowledge Check

Which method in Spliterator splits off a subset of elements to enable parallel stream processing?