Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
Chaturmind
← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: 8+ Years (Senior & Lead)Expert Core Java
✓ FreeAdvanced· 16 min read

Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions

Classic questions on ArrayList vs Vector vs arrays, HashMap vs Hashtable vs ConcurrentHashMap, hashCode, Collection vs Collections, fail-fast vs fail-safe iterators, Map vs Queue, LinkedHashMap vs PriorityQueue, Comparable vs Comparator, BitSet, streams, heap vs stack, processes vs threads, context switching, multithreading benefits, wait/notify/notifyAll/sleep, BlockingQueue, CyclicBarrier, CompletableFuture, JDBC statement types, NIO and memory-mapped buffers — with senior-level depth and corrections.

Published September 25, 2026


How to use this lesson

Answer each question in one line, then add one production insight: a complexity trade-off, a concurrency hazard, or a modern replacement. Several popular answers are subtly wrong (for example, "ConcurrentHashMap allows null values", or "fail-safe iterators copy the collection"), and those errors are corrected here.

Q1. What's the difference between ArrayList and Vector?

Short answer:

  • Vector is a legacy (Java 1.0) class. Every method is synchronized, and it doubles its capacity when it grows.
  • ArrayList is unsynchronised and faster, and grows by about 50%.

Key points to cover:

  • Don't use Vector in new code. Per-method locking doesn't make compound operations safe ("check then add" still races).
  • For concurrency, use CopyOnWriteArrayList (read-mostly lists), Collections.synchronizedList plus external locking for iteration, or a concurrent queue.

Learn it in depth → List, Set, and Map

Q2. What's the difference between HashMap and ConcurrentHashMap?

Short answer:

  • HashMap isn't thread-safe. Concurrent writes can lose updates or corrupt its structure. It allows one null key and null values.

  • ConcurrentHashMap is thread-safe, with high concurrency:

    • lock-free reads;
    • CAS for empty bins, and fine-grained locking on individual bins (since Java 8, not segments);
    • weakly consistent iterators;
    • atomic compound operations (computeIfAbsent, merge, compute).

    It allows no null keys or values: null would be ambiguous with "absent" in concurrent get calls.

Common trap: saying ConcurrentHashMap only disallows null keys. Values can't be null either.

Learn it in depth → ConcurrentHashMap & CopyOnWriteArrayList

Q3. What's the difference between HashMap and Hashtable?

Short answer:

  • Hashtable is legacy: fully synchronised (one lock for the whole table), with no null keys or values. It extends the obsolete Dictionary class, and has an Enumeration API.
  • HashMap is unsynchronised and faster. It allows one null key and null values. Since Java 8, it also treeifies large buckets (red-black trees once a bin has more than 8 entries, and the table has at least 64 buckets), which protects against collision attacks.

Use HashMap for single-threaded code, and ConcurrentHashMap for concurrent code. There's no reason to use Hashtable today.

Q4. What is hashCode() for?

Short answer: It returns an int used by hash-based collections to pick a bucket. HashMap spreads the bits (h ^ (h >>> 16)), then masks with table.length - 1. A good hash distributes keys evenly, which keeps lookups at O(1) on average.

Key points to cover:

  • A hash code is not unique: collisions are normal.
  • The default Object.hashCode() isn't a memory address in modern JVMs (typically a thread-local random value, stored in the object header).
  • Equal objects must have equal hash codes.
  • String caches its hash.
  • Keys should be immutable.

Q5. What's the difference between Collection and Collections?

Short answer:

  • Collection<E> is the root interface of lists, sets and queues. Maps are separate.
  • Collections is a utility class of static helpers: sort, binarySearch, unmodifiableList, synchronizedMap, emptyList, nCopies, frequency, shuffle.

Key points to cover:

  • Modern equivalents often replace these helpers: List.of/copyOf for immutable collections, list.sort(comparator), and streams.

Q6. What's the difference between fail-fast and fail-safe iterators?

Short answer:

  • Fail-fast iterators (ArrayList, HashMap) track a modCount. If the collection is structurally modified during iteration by anything other than the iterator's own remove(), the next next() throws ConcurrentModificationException. This is a best-effort check, not a thread-safety guarantee.
  • "Fail-safe" iterators, more precisely:
    • snapshot iterators: CopyOnWriteArrayList iterates over the array as it was when the iterator was created;
    • weakly consistent iterators: ConcurrentHashMap, ConcurrentLinkedQueue traverse live data, never throw CME, and may or may not reflect concurrent updates.

Common trap: saying fail-safe iterators always work on a clone. Only copy-on-write collections snapshot. ConcurrentHashMap doesn't copy anything.

list.removeIf(item -> item.isExpired());         // the safe way to remove while "iterating"
for (Iterator<Item> it = list.iterator(); it.hasNext();) if (it.next().isExpired()) it.remove();

Learn it in depth → Iterators & Modification Semantics

Q7. What's the difference between Map and Queue?

Short answer:

  • Map<K,V> holds key → value associations, with unique keys. It's designed for lookup by key (HashMap is O(1) average, TreeMap is O(log n) and sorted).

  • Queue<E> is a Collection that holds elements for processing, in a defined order:

    • FIFO (ArrayDeque, LinkedList);
    • priority (PriorityQueue);
    • blocking, for producer-consumer (BlockingQueue).

    It has offer/poll/peek, which return special values, and add/remove/element, which throw.

Map doesn't extend Collection, and Queue does.

Q8. What's the difference between LinkedHashMap and PriorityQueue?

Short answer: They solve different problems:

  • LinkedHashMap is a map with a doubly linked list through its entries, which gives predictable insertion order, or access order (new LinkedHashMap<>(16, 0.75f, true)). With removeEldestEntry, it's the classic LRU cache. O(1) operations.
  • PriorityQueue is a binary heap of elements, ordered by natural order or a Comparator:
    • offer/poll are O(log n), and peek is O(1);
    • iteration order isn't sorted, only poll order is;
    • it isn't thread-safe (use PriorityBlockingQueue).
class LruCache<K, V> extends LinkedHashMap<K, V> {
    private final int max;
    LruCache(int max) { super(16, 0.75f, true); this.max = max; }
    @Override protected boolean removeEldestEntry(Map.Entry<K, V> e) { return size() > max; }
}

Q9. What's the difference between Comparable and Comparator?

Short answer:

  • Comparable<T>: the class defines its natural ordering itself, with compareTo(T). That's one ordering per class (String, LocalDate, BigDecimal). It's used by TreeMap/TreeSet and Collections.sort when no comparator is given.
  • Comparator<T>: an external, pluggable ordering, with compare(a, b). You can have many orderings without touching the class. Java 8's builders compose them:
orders.sort(Comparator.comparing(Order::priority)
        .thenComparing(Order::createdAt, Comparator.reverseOrder())
        .thenComparing(Order::id));

Key points to cover:

  • Keep compareTo consistent with equals, or sorted sets and maps behave surprisingly. BigDecimal("2.0") and ("2.00") compare equal, but aren't equals.
  • Never compare with subtraction (a.x - b.x): it overflows. Use Integer.compare.

Q10. What is BitSet used for?

Short answer: A growable vector of bits, backed by a long[], with fast set/clear/flip/get, bulk operations (and, or, xor, andNot), cardinality(), and nextSetBit() for iteration. It's very memory-efficient for dense flags over integer indexes: 1 bit per flag, instead of a boolean (1 byte) or a Boolean object.

It's used for sieve algorithms, feature and permission masks, visited sets in graph algorithms, simple Bloom filters, and bitmap indexes. It isn't thread-safe. For sparse, huge bitmaps, use RoaringBitmap.

Q11. What are Java 8 streams?

Short answer: A declarative pipeline for processing a sequence of elements:

  • a source: a collection, array, IntStream.range, Files.lines;
  • lazy intermediate operations: filter, map, flatMap, sorted, distinct;
  • one terminal operation: collect, reduce, forEach, findFirst, count.

A stream doesn't store data, and can be consumed only once. Laziness enables short-circuiting and operation fusion. Primitive streams (IntStream) avoid boxing, and parallel() splits the work across the common ForkJoinPool.

Key points to cover:

  • Keep lambdas side-effect free.
  • Parallel streams only pay off for large, CPU-bound, easily splittable workloads.
  • Java 16 added toList(), and Java 22+ added gatherers (Stream.gather) for custom intermediate operations.

Learn it in depth → Streams API

Q12. What's the difference between heap and stack memory?

Short answer:

  • Stack (per thread): frames for method calls, holding local variables (primitives and references), operand stacks and return addresses. It's LIFO, allocated and freed automatically on method entry and exit. It's very fast, and sized with -Xss. Overflowing it throws StackOverflowError (deep recursion).
  • Heap (shared by all threads): all objects and arrays. It's managed by the garbage collector, sized with -Xms/-Xmx, and exhausting it throws OutOfMemoryError: Java heap space.

Key points to cover:

  • A local reference lives on the stack, but the object it points to is on the heap. Escape analysis can scalar-replace non-escaping objects, so they're effectively never allocated.
  • Virtual threads store their stacks on the heap, as chunks, when they're unmounted.

Learn it in depth → JVM Memory Areas

Q13. What's the difference between an array and a Collection, and between an array and an ArrayList?

Short answer:

  • Arrays:
    • fixed length;
    • can hold primitives (int[]) or references;
    • covariant, so Object[] a = new String[1]; a[0] = 1; throws ArrayStoreException at runtime;
    • fast, with a minimal API (length, and the Arrays utilities).
  • Collections / ArrayList:
    • dynamic size;
    • hold objects only (boxing for primitives);
    • type-safe through generics (invariant, and checked at compile time);
    • rich APIs (add, remove, contains, streams), and many implementations with different trade-offs.

Common trap: saying collections "store elements of different types". With generics, a List<Order> is homogeneous, like an array. Use List<Object> only if you really want mixed types.

Q14. What's the difference between a process and a thread?

Short answer:

  • A process is an OS-level program instance with its own address space, file handles and resources. Processes are isolated from each other, communicate through IPC (sockets, pipes, shared memory), and are heavyweight to create.
  • A thread is an execution path within a process. Threads share the heap and resources, but each has its own stack and registers. They're cheaper to create and switch, but shared memory brings race conditions.

Key points to cover:

  • A JVM is one process, with many platform threads (1:1 with OS threads).
  • Virtual threads (Java 21) are JVM-managed, and scheduled M:N onto carrier threads, which makes millions of concurrent tasks cheap.

Q15. What are the advantages of multithreading?

Short answer:

  • Using multiple CPU cores for CPU-bound parallel work.
  • Overlapping I/O waits: other tasks run while one blocks on the network or disk.
  • Responsiveness: UI or request threads aren't blocked by background work.
  • Throughput for servers handling many concurrent requests.

The costs:

  • Complexity: races, deadlocks and visibility bugs.
  • Context-switch and synchronisation overhead.
  • Harder testing and debugging.
  • Memory per platform thread (around 1 MB of stack each).

Use higher-level tools (executors, CompletableFuture, virtual threads, concurrent collections), rather than raw threads.

Q16. What is context switching?

Short answer: The OS (or the JVM, for virtual threads) saves one thread's execution state (registers, program counter, stack pointer) and restores another's, so they can share a CPU core. It happens on time-slice expiry, blocking I/O, lock contention, sleep and wait. Each switch costs microseconds, plus cache and TLB pollution.

Key points to cover:

  • Too many runnable platform threads means switching overhead dominates. That's why CPU-bound pools are sized around the number of cores, and why virtual threads (cheap, user-mode switches when they block) scale I/O-bound concurrency better.

Q17. What's the difference between notify() and notifyAll()?

Short answer:

  • notify() wakes one arbitrary thread waiting on that object's monitor.
  • notifyAll() wakes all of them. They then compete for the monitor, and each re-checks its condition.

Prefer notifyAll(), unless every waiter waits for the same condition, and any one of them can proceed. With notify(), the "wrong" thread may wake up (for example a producer when a consumer was needed), and the signal is lost, which can hang the system.

Key points to cover:

  • Modern code uses java.util.concurrent (BlockingQueue, Condition with separate notFull/notEmpty conditions, CountDownLatch) instead of wait/notify.

Q18. What's the difference between wait() and notify()?

Short answer: They're two halves of the guarded-wait protocol on an object's monitor:

  • wait() releases the monitor, and suspends the current thread until it's notified (or interrupted, or times out, or wakes spuriously). It then reacquires the monitor before returning.
  • notify() signals one waiting thread. It doesn't release the lock: the woken thread proceeds only after the notifier leaves the synchronized block.

Both must be called while holding that object's monitor, or they throw IllegalMonitorStateException. Always wait in a loop, re-checking the condition:

synchronized (lock) {
    while (queue.isEmpty()) lock.wait();     // loop: spurious wakeups and competing consumers
    item = queue.remove();
}
// producer
synchronized (lock) { queue.add(item); lock.notifyAll(); }

Q19. What's the difference between sleep() and wait()?

Short answer:

Thread.sleep(ms)obj.wait()
Defined inThread (static)Object
LockKeeps every lock it holdsReleases that object's monitor
Requires a monitorNoYes (inside synchronized(obj))
Wakes onTimeout, or interruptnotify/notifyAll, timeout, interrupt, or spuriously
PurposePause executionWait for a condition signalled by another thread

Both throw InterruptedException. Restore the interrupt flag (Thread.currentThread().interrupt()) if you can't propagate it.

Q20. What is a BlockingQueue?

Short answer: A thread-safe Queue whose put() blocks when it's full, and whose take() blocks when it's empty. There are also timed offer/poll. It's the backbone of the producer-consumer pattern, and of ThreadPoolExecutor's work queue. Implementations:

  • ArrayBlockingQueue (bounded, one lock);
  • LinkedBlockingQueue (optionally bounded, separate put and take locks);
  • PriorityBlockingQueue;
  • DelayQueue (scheduling);
  • SynchronousQueue (a direct hand-off, with zero capacity);
  • LinkedTransferQueue.

Key points to cover:

  • Bounded queues give back-pressure. An unbounded LinkedBlockingQueue in an executor can grow until an OutOfMemoryError.

Q21. What is a CyclicBarrier?

Short answer: A synchroniser where a fixed number of threads wait (await()) until all of them arrive. Then they're released together, optionally after a barrier action runs. It's reusable (cyclic) for the next phase. It's used for iterative parallel algorithms and simulations, where each phase must finish before the next begins.

Key points to cover:

  • If one thread is interrupted or times out, the barrier becomes broken (BrokenBarrierException for the others).
  • For dynamic parties and phases, use Phaser.
  • For "wait until N events happen" (a one-shot, where the counting parties don't wait themselves), use CountDownLatch.

Learn it in depth → Concurrent Utilities & Coordination

Q22. Explain Java 8's CompletableFuture.

Short answer: A Future you can complete manually, and compose without blocking:

  • create one with supplyAsync/runAsync;
  • transform it with thenApply, chain async steps with thenCompose (flatMap), combine two with thenCombine, and wait for many with allOf/anyOf;
  • handle errors with exceptionally/handle/whenComplete;
  • use timeouts (orTimeout, completeOnTimeout, Java 9).

Key points to cover:

  • By default, the *Async methods run on ForkJoinPool.commonPool(). Pass your own executor for blocking I/O, or you'll starve the common pool, which parallel streams share.
  • Non-async callbacks run on whichever thread completes the future.
  • get() wraps exceptions in ExecutionException, and join() in CompletionException.

Learn it in depth → CompletableFuture

Q23. What are the types of JDBC statements?

Short answer:

  • Statement: static SQL, without parameters. It's vulnerable to SQL injection if you concatenate input, and is rarely appropriate.
  • PreparedStatement: parameterised SQL (? placeholders). It prevents injection (the values are bound, never parsed as SQL), handles types correctly, and allows statement caching. Use it with addBatch/executeBatch for bulk inserts.
  • CallableStatement: calls stored procedures, with IN/OUT parameters ({call proc(?, ?)}).

Key points to cover:

  • Always close them with try-with-resources (or use JdbcTemplate/JPA).
  • Placeholders bind values only. They can't bind table or column names, so allow-list those.

Learn it in depth → Practical SQL & JDBC for Interviews

Q24. Explain Java NIO.

Short answer: NIO (java.nio, Java 1.4, extended in NIO.2 in Java 7) provides:

  • Buffers (ByteBuffer, including direct buffers allocated outside the heap for zero-copy I/O) and channels (FileChannel, SocketChannel), for block-oriented I/O.
  • Non-blocking sockets plus Selectors: one thread multiplexes thousands of connections. That's the foundation of Netty, Tomcat's NIO connector and WebFlux.
  • NIO.2 (java.nio.file): Path, Files, directory watching (WatchService), file attributes, and asynchronous channels.
  • FileChannel.transferTo (zero-copy sendfile), and memory-mapped files.

Key points to cover:

  • Virtual threads now make plain blocking I/O scale for many use cases, reducing the need to hand-write selector loops.

Q25. What is a memory-mapped buffer?

Short answer: FileChannel.map(...) returns a MappedByteBuffer that maps a region of a file directly into the process's virtual memory. Reads and writes become memory accesses, paged in and out by the OS page cache, with no copying through the heap and no explicit read calls. It's great for large files and random access (databases, Kafka's index files, Lucene).

Key points to cover:

  • Caveats:
    • Mappings are released only when the buffer is garbage-collected (there's no explicit unmap before the FFM API).
    • Individual mappings are limited to 2 GB (int indexes).
    • Page faults cause latency.
    • It's native memory, outside the heap limits.
  • Java 22's Foreign Function & Memory API (Arena, MemorySegment, FileChannel.map(..., arena)) gives deterministic unmapping, and 64-bit sizes.

Follow-up questions this topic invites — and their answers

Q: What's the time complexity of HashMap.get, in the worst case? A: O(1) on average. With many collisions in one bucket: O(log n) since Java 8, when the bucket is treeified (keys ideally Comparable), and O(n) in older versions, or with a tiny table.

Q: ArrayDeque or LinkedList for a stack or queue? A: ArrayDeque. It's a circular array with better cache locality and no per-node allocation. Stack is legacy (it extends Vector), and LinkedList has high overhead per element.

Q: Why can't ConcurrentHashMap.size() always be exact? A: Counts are maintained in striped CounterCells (like LongAdder), and updates are concurrent, so size() or mappingCount() is an estimate while writes are in progress. Don't build logic that depends on an exact concurrent size.

Q: Is PriorityQueue iteration sorted? A: No. Only repeated poll() returns elements in priority order. The iterator traverses the underlying heap array. To get a sorted view, sort a copy.

Previous

Classic Java Language Questions, Senior-Grade Answers — Interview Questions

Next

Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

AI Tutor

Lesson: Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.