What are intermediate and terminal operators in the Java Stream API?
Intermediate operators:
* Return a new stream; can be chained.
* Do not trigger processing.
* Examples: filter, map, flatMap, sorted, distinct.
Terminal operators:
* Produce a result or side effect; trigger stream processing.
* Examples: collect, forEach, reduce, count, anyMatch.
Can you mention some terminal operators that end stream processing without going through all elements?
Short-circuiting terminal operators:
* May finish processing before all elements are examined.
Examples:
* anyMatch()
* allMatch()
* noneMatch()
* findFirst()
* findAny()
How do parallel streams work, and what are their advantages and pitfalls?
How they work:
* Split data into multiple parts and process them concurrently using multiple threads (ForkJoinPool).
* Use .parallelStream() or .parallel() on a stream.
Advantages:
* Can improve performance for large, CPU-intensive tasks.
* Simplifies parallel processing code.
Pitfalls:
* Overhead may outweigh benefits for small datasets.
* Not always thread-safe if operations have side effects.
* Order may not be preserved (unless using ordered streams).
* Shared mutable state can cause bugs.
How do you handle exceptions during Java Stream processing?
Checked exceptions:
* Streams don’t handle checked exceptions directly; wrap code in try-catch blocks inside lambdas or use custom wrapper methods.
Unchecked exceptions:
* Can be caught outside the stream or inside lambdas.
Common approaches:
* Use try-catch inside the lambda:
list.stream().map(item -> {
try { return riskyMethod(item); }
catch (Exception e) { /* handle or rethrow */ }
})How can you debug streams?
stream.filter(x -> x > 0)
.peek(System.out::println)
.map(x -> x * 2)What is the Executors framework?
How is LinkedHashMap implemented?
What is the Java Memory Model? How does it work?
Java Memory Model (JMM):
* Defines how threads interact through memory and what behaviors are allowed in concurrent code.
* Specifies rules for visibility, ordering, and atomicity of variable reads/writes.
* Ensures that changes made by one thread to shared variables are visible to others (with proper synchronization).
* Guarantees provided by volatile, synchronized, and final fields.
How would you identify and troubleshoot a memory leak?
Identification:
* Monitor memory usage (e.g., with VisualVM, JConsole, or profilers).
* Look for increasing heap usage and frequent garbage collection.
* Analyze heap dumps for unreachable but referenced objects.
Troubleshooting:
* Check for static collections or caches holding references.
* Review code for listeners, threads, or resources not released.
* Use profiling tools to find reference chains and root causes.
What are the different phases of garbage collection?
Mark: Identify all reachable (live) objects.
Sweep: Remove unreferenced (dead) objects from memory.
Compact (optional): Rearrange remaining objects to eliminate fragmentation.
Copy (in some collectors): Move live objects to a new memory area, leaving dead objects behind.
What is garbage collection?
What is throughput and latency in terms of garbage collection?
Throughput:
* The percentage of total time the application spends doing useful work (not garbage collection).
* Higher throughput means less time spent in GC.
Latency:
* The pause time experienced by the application during garbage collection.
* Lower latency means shorter or less frequent GC pauses.
What is the subtype of Set that supports sorted order?
Can we have a default method in a functional interface?
How would you decide which GC algorithm to use in certain situations?
Throughput-focused applications:
Use collectors like Parallel GC (default in many JVMs); best for batch processing or server-side apps where pause times are less critical.
Low-latency applications:
Use G1 GC or ZGC/Shenandoah GC; suitable for real-time systems or user-facing apps where short pause times are important.
Small applications or limited resources:
Serial GC is simple and has low overhead; good for single-threaded or small footprint apps.
Large heaps or high scalability:
G1 GC, ZGC, or Shenandoah GC handle large memory sizes and minimize pause times.
What problems could arise if a mutable object is used as a key in a HashMap?
If the key’s fields (used in hashCode() or equals()) change after insertion, the map may not find the key.
Retrieval, update, or removal operations can fail or behave unpredictably.
Can lead to memory leaks (unreachable entries remain in the map).
What are virtual threads?
Lightweight threads introduced in Java (Project Loom) to simplify concurrent programming.
Managed by the JVM, allowing thousands of threads with minimal resource usage.
Each virtual thread is scheduled by the JVM, not directly mapped to OS threads.
Makes it easier to write scalable, blocking code without complex thread management.
What’s the difference between ExecutorService and ForkJoinPool?
ExecutorService:
* General-purpose interface for managing and executing tasks asynchronously.
* Supports fixed, cached, single-threaded, and scheduled thread pools.
* Tasks are independent; no built-in support for task splitting or joining.
ForkJoinPool:
* Specialized implementation of ExecutorService for parallelism.
* Designed for tasks that can be recursively split into subtasks (fork/join framework).
* Efficiently handles divide-and-conquer algorithms.
What are atomic variables?
Special classes in java.util.concurrent.atomic package.
Provide thread-safe, lock-free operations on single variables (e.g., AtomicInteger, AtomicLong).
Support atomic operations like increment, decrement, compare-and-set.
Useful for counters, flags, and other shared variables in concurrent code.
What do wait(), notify(), and notifyAll() do in regards to threads?
wait():
Causes the current thread to release the monitor and wait until another thread calls notify() or notifyAll() on the same object.
notify():
Wakes up one waiting thread on the same object’s monitor.
notifyAll():
Wakes up all waiting threads on the same object’s monitor.
All must be called from synchronized context (inside a synchronized block or method).
What makes a class or method thread-safe?
Thread-safe means the class or method works correctly when accessed by multiple threads at the same time.
Achieved by:
* Synchronizing access to shared data (synchronized keyword, locks).
* Using immutable objects.
* Using thread-safe classes (e.g., ConcurrentHashMap, AtomicInteger).
Can you explain how inconsistent state can happen in multithreaded applications?
Inconsistent state occurs when multiple threads access and modify shared data without proper synchronization.
This can lead to:
* Partial updates (one thread sees data in the middle of being changed).
* Lost updates (changes from one thread overwrite another’s).
* Unexpected results or program errors.
Example:
If two threads increment the same counter without synchronization, both may read the same value and write back the same result, losing one increment.
Can you explain how Java’s memory model works with respect to cache and heap memory, particularly in multithreaded contexts?
Heap memory:
Shared area where all objects and class variables are stored.
All threads can access the heap, but changes may not be immediately visible to other threads due to caching.
CPU caches:
Each thread may run on a different CPU core with its own cache.
Threads may see stale values if changes in one cache are not flushed to main memory (heap).
Java Memory Model (JMM):
Defines rules for visibility and ordering of variable reads/writes between threads.
Synchronization (synchronized, volatile, etc.) ensures changes in one thread are visible to others by flushing caches to main memory.
What is a race condition? How do you detect it?
Race condition:
* Occurs when two or more threads access shared data at the same time, and the result depends on the timing of their execution.
* Can lead to unpredictable or incorrect results.
Detection:
* Look for inconsistent or unexpected behavior in multithreaded code.
* Use code reviews to spot unsynchronized access to shared variables.
* Employ tools like thread analyzers, profilers, or static analysis tools (e.g., FindBugs, VisualVM, Java Flight Recorder).