2129 words
11 minutes
15 More Java Backend Interview Questions and Answers

Java backend interviews rarely test one framework in isolation. A single conversation may move from collections and object equality to concurrency, JVM memory, Spring proxies, transactions, and database isolation.

This guide organizes 15 common questions into four themes. Each answer starts with the essential idea, then adds the implementation details and caveats that often distinguish a strong interview response from a memorized definition.

Java Collections and Core Language#

1. How does HashMap work, and what changed in JDK 8?#

A HashMap stores entries in an array of buckets. It spreads the key’s hash code, maps that hash to a bucket index, and searches the entries in that bucket. Keys that map to the same bucket form a collision chain.

Since JDK 8, a busy bucket can use either a linked list or a red-black tree. A tree changes lookup in a heavily collided bucket from linear time, O(n)O(n), to logarithmic time, O(log⁡n)O(\log n).

The important thresholds are:

  • TREEIFY_THRESHOLD = 8: a sufficiently long bucket becomes eligible for treeification.
  • MIN_TREEIFY_CAPACITY = 64: the table must have at least 64 buckets; otherwise, HashMap resizes instead.
  • UNTREEIFY_THRESHOLD = 6: a small tree bin may return to a linked list during resize operations.

In short, treeification happens when the collision chain reaches the threshold and the table capacity is at least 64. The capacity rule avoids paying for a tree when expanding the table may distribute the keys more effectively.

JDK 8 also changed resize behavior. Nodes are split between their existing index and oldIndex + oldCapacity, preserving their relative order instead of using the JDK 7 head-insertion approach. This made resizing more efficient and avoided the circular-list failure associated with unsafe concurrent resizing in older implementations. HashMap is still not thread-safe; use ConcurrentHashMap when concurrent access is required.

2. How do ArrayList and LinkedList differ?#

ArrayList uses a resizable array; LinkedList uses a doubly linked chain of nodes.

Operation or propertyArrayListLinkedList
Indexed accessO(1)O(1)O(n)O(n)
AppendAmortized O(1)O(1)O(1)O(1)
Insert/remove at a known nodeRequires shifting elementsO(1)O(1)
Find an insertion/removal positionO(1)O(1) by index, but shifting followsO(n)O(n) traversal
Memory localityGoodPoor
Per-element overheadLowHigher due to two links per node

The phrase “linked lists are faster for insertion and deletion” needs context. They avoid shifting elements only after the target node has been reached. Finding that node is usually O(n)O(n), and pointer-heavy nodes are less cache-friendly.

Use ArrayList as the general-purpose default. If the real requirement is efficient queue or deque operations at both ends, ArrayDeque is usually a better choice than LinkedList.

3. What is the difference between == and equals()?#

For primitives, == compares values. For references, it tests whether both references point to the same object.

equals() represents logical equality. The default implementation inherited from Object behaves like reference identity, but classes such as String, records, and value objects override it to compare content.

The relationship with hashCode() is essential:

  • If a.equals(b) is true, then a.hashCode() and b.hashCode() must be equal.
  • Equal hash codes do not imply that two objects are equal; collisions are allowed.
  • An object’s hash code should remain stable while it is stored in a hash-based collection.
  • Override hashCode() whenever you override equals().

Breaking this contract can make a logically equal key impossible to find in a HashMap or HashSet.

4. How do String, StringBuilder, and StringBuffer differ?#

  • String is immutable. Operations that appear to modify it produce a new string.
  • StringBuilder is mutable and unsynchronized, making it the usual choice for assembling text within one thread.
  • StringBuffer is mutable and synchronizes its operations. It exists mainly for cases where the same buffer truly must be shared across threads.

Modern JDKs store string data in an internal byte[] when possible, rather than the char[] used by older releases. The implementation keeps that storage private and exposes no operation that can mutate a String after construction.

Immutability makes strings safe to share, suitable as hash keys, cacheable, and reusable through the string pool. It also prevents security-sensitive values such as class names, file paths, and URLs from changing after validation.

Concurrency, Thread Pools, and the JVM#

5. How do synchronized and Lock differ?#

synchronized is built into the language and JVM. Lock acquisition and release are tied to a block or method, and the monitor is released automatically when control leaves that scope—even when an exception is thrown.

Lock, most commonly ReentrantLock, is an API. It supports features such as timed acquisition, interruptible acquisition, optional fairness, multiple Condition objects, and attempts that do not block. It must be released explicitly, normally in a finally block:

lock.lock();
try {
updateSharedState();
} finally {
lock.unlock();
}

The traditional interview description of monitor optimization is:

biased -> lightweight -> heavyweight

That model is version-dependent. Biased locking was disabled by default in JDK 15 and removed in JDK 18. Modern JVMs still optimize uncontended monitors and may inflate them under contention, but candidates should avoid presenting the old three-stage sequence as a universal rule for every JDK.

6. What does volatile guarantee?#

volatile provides visibility and ordering, but not general-purpose atomicity.

A write to a volatile field happens-before a later read of that field. This means the reading thread sees that write and also sees ordinary writes that happened before it in the writing thread. The JVM and CPU enforce these semantics with compiler constraints and memory barriers appropriate to the platform.

A volatile read or write of the field itself is atomic, but a read-modify-write operation is not:

volatile int count;
count++; // read, add, and write: not an atomic unit

Use synchronization or an atomic type such as AtomicInteger when multiple threads must update a value safely. volatile is well suited to state flags and safely publishing immutable snapshots.

7. What are the seven ThreadPoolExecutor parameters?#

The constructor accepts:

  1. corePoolSize: the number of core workers.
  2. maximumPoolSize: the maximum number of workers.
  3. keepAliveTime: how long excess idle workers may remain alive.
  4. unit: the time unit for the keep-alive value.
  5. workQueue: the queue holding tasks before execution.
  6. threadFactory: the strategy used to create workers.
  7. handler: the policy used when the executor cannot accept a task.

Tasks are generally handled in this order: create workers up to the core size, enqueue work, create additional workers up to the maximum when the queue cannot accept more, and finally invoke the rejection policy.

The built-in rejection policies are:

  • AbortPolicy: throw RejectedExecutionException.
  • CallerRunsPolicy: execute the task in the submitting thread, providing a simple form of backpressure.
  • DiscardPolicy: silently discard the new task.
  • DiscardOldestPolicy: remove the oldest queued task and retry submission.

In production, size the pool for the workload, prefer bounded queues, give threads useful names, expose queue and rejection metrics, and define a shutdown strategy. Convenience factories in Executors are not inherently wrong, but some create unbounded queues or an unbounded number of threads. Constructing ThreadPoolExecutor directly makes those capacity decisions explicit.

8. How is JVM memory organized, and how do CMS and G1 compare?#

The JVM runtime data areas include:

  • the program counter register;
  • one JVM stack per thread;
  • native method stacks;
  • the shared heap;
  • the shared method area, implemented as Metaspace in HotSpot since JDK 8.

CMS and G1 take different approaches to garbage collection:

CollectorCMSG1
Heap organizationTraditional generations with a contiguous old generationMany equal-sized regions forming logical generations
Main goalReduce old-generation pausesBalance throughput with a configurable pause-time goal
ReclamationPrimarily mark-sweepEvacuates live objects and compacts selected regions
Main drawbackFragmentation and concurrent-mode failuresMore complex heuristics and some overhead

CMS was deprecated in JDK 9 and removed in JDK 14. G1 became the default HotSpot collector in JDK 9 and prioritizes regions expected to yield the most reclaimable space.

Spring and Spring Boot#

9. What is Spring IoC, and what is the bean lifecycle?#

Inversion of Control means the Spring container creates objects, supplies their dependencies, configures them, and manages their lifecycle. Application code declares relationships instead of manually constructing the entire object graph.

A simplified singleton bean lifecycle is:

instantiate
-> populate dependencies and properties
-> invoke aware callbacks
-> BeanPostProcessor before initialization
-> initialization callbacks
-> BeanPostProcessor after initialization
-> bean is ready
-> destruction callbacks when the context closes

Initialization can include @PostConstruct, InitializingBean, or a configured init method. Destruction can include @PreDestroy, DisposableBean, or a configured destroy method.

Common scopes are singleton, prototype, request, session, application, and websocket. Spring does not automatically call destruction callbacks for prototype beans after handing them to the client.

10. How does Spring AOP work, and how do JDK and CGLIB proxies differ?#

Spring AOP wraps a bean in a proxy. Calls that pass through that proxy can run advice before, after, or around the target method, which supports concerns such as transactions, logging, caching, and authorization.

  • A JDK dynamic proxy implements one or more interfaces.
  • A CGLIB proxy creates a subclass of the target class.

Subclass-based proxies cannot advise final classes or override final methods. With either approach, a call from one method to another on this does not pass through the proxy, which explains many self-invocation surprises.

Spring Framework can choose a JDK proxy when interfaces are available; Spring Boot configures class-based proxying by default for AOP auto-configuration. The exact choice can be changed through configuration.

11. How does Spring Boot auto-configuration work?#

@EnableAutoConfiguration, included by @SpringBootApplication, imports candidate auto-configuration classes. Current Spring Boot releases list candidates in:

META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

Older releases commonly registered them through META-INF/spring.factories.

Each candidate uses conditions such as @ConditionalOnClass, @ConditionalOnMissingBean, and @ConditionalOnProperty. Spring evaluates those conditions against the classpath, configuration, and current application context. Auto-configuration therefore supplies sensible defaults while backing off when the application defines its own bean or disables a feature.

12. When can @Transactional fail to roll back?#

Common causes include:

  1. Self-invocation: one method calls another transactional method on the same instance, bypassing the proxy.
  2. An exception is swallowed: the method catches the failure and returns normally.
  3. The exception does not match rollback rules: by default, runtime exceptions and errors trigger rollback; checked exceptions require configuration such as rollbackFor.
  4. The method cannot be advised: this depends on proxy type and Spring version, but private or final methods are common problems.
  5. The work runs in another thread: transaction context is normally bound to the current thread.
  6. Propagation suspends or creates another transaction: settings such as NOT_SUPPORTED or REQUIRES_NEW change the expected boundary.
  7. The resource is not transactional: for example, a non-transactional database engine or an operation outside the configured transaction manager.
  8. The transaction was never activated: the class is not a managed bean, transaction management is not enabled, or the wrong transaction manager is selected.

Debug these cases by identifying the proxy boundary, the actual exception leaving the method, the propagation mode, and the resource participating in the transaction.

Security and Data#

13. What is the Spring Security authentication and authorization flow?#

A request passes through Spring Security’s filter chain. An authentication filter extracts credentials and creates an unauthenticated Authentication token. An AuthenticationManager delegates to an AuthenticationProvider, which may call UserDetailsService to load the account and a PasswordEncoder to verify the password.

On success, the resulting authenticated object is stored in the SecurityContext. Later authorization components compare that identity and its authorities with the rules for the requested resource. Authentication answers “Who are you?”; authorization answers “May you do this?”

UserDetailsService has one focused responsibility: load UserDetails by username. It does not itself authenticate the password. That comparison is normally performed by an authentication provider such as DaoAuthenticationProvider.

14. How do you integrate Spring Security with JWT?#

A typical stateless flow is:

  1. Configure the API with SessionCreationPolicy.STATELESS.
  2. Authenticate credentials at a login endpoint.
  3. Issue a short-lived, signed access token after successful authentication.
  4. Add a filter before UsernamePasswordAuthenticationFilter to read the bearer token.
  5. Validate the token’s signature, expiry, issuer, audience, and other required claims.
  6. Build an authenticated principal and store it in SecurityContextHolder for the current request.
  7. Return 401 Unauthorized when authentication is required but invalid or absent, and 403 Forbidden when an authenticated user lacks permission.

CSRF protection is often disabled for a bearer-token API whose credentials are sent explicitly in the Authorization header and not stored in cookies. If tokens are cookie-based, disabling CSRF without another defense is unsafe.

Production designs should also address key rotation, refresh-token storage and revocation, token leakage, narrow claims, and HTTPS. A JWT is a signed credential format—not encryption and not a complete session-management strategy.

15. What are InnoDB’s transaction isolation levels, and how does MVCC work?#

InnoDB supports the four SQL isolation levels:

  1. READ UNCOMMITTED
  2. READ COMMITTED
  3. REPEATABLE READ—the InnoDB default
  4. SERIALIZABLE

MVCC allows consistent, non-locking reads by combining transaction metadata, undo-log version chains, and a read view. If the latest row version is not visible to a transaction’s snapshot, InnoDB follows the undo chain to find a visible version.

Under READ COMMITTED, a new read view is generally created for each consistent read. Under REPEATABLE READ, consistent reads in a transaction normally share a snapshot, which prevents non-repeatable reads for those snapshot queries.

It is also important to distinguish two kinds of reads:

  • Consistent reads use an MVCC snapshot and normally do not lock records.
  • Locking/current reads, including SELECT ... FOR UPDATE and data modifications, inspect current versions and acquire locks.

InnoDB combines MVCC with record, gap, and next-key locking where needed. MVCC improves read/write concurrency, but it does not mean that every query is lock-free or that application-level race conditions disappear.

Final Review Checklist#

Strong interview answers connect definitions to consequences:

  • Describe complexity together with the data structure that causes it.
  • State concurrency guarantees precisely—visibility, ordering, and atomicity are different properties.
  • Explain Spring features through proxy and lifecycle boundaries.
  • Separate authentication from authorization and JWT validation from session design.
  • Distinguish database snapshot reads from locking reads.

Those connections make the material easier to remember and make follow-up questions much easier to answer.

15 More Java Backend Interview Questions and Answers
https://astro-nyc.pages.dev/posts/java-backend-interview-questions/
Author
Hari
Published at
2026-08-28
License
CC BY-NC-SA 4.0