Backend Development 13 min read

Mastering Java Interviews: HashMap, ConcurrentHashMap, JVM GC, and SQL Tricks

This article shares a real HSBC interview experience and provides in‑depth explanations of Java HashMap internals, ConcurrentHashMap locking mechanisms, differences between synchronized and ReentrantLock, JVM garbage‑collection nuances, memory‑overflow causes, and practical SQL queries for extracting top scores.

Java Tech Enthusiast
Java Tech Enthusiast
Java Tech Enthusiast
Mastering Java Interviews: HashMap, ConcurrentHashMap, JVM GC, and SQL Tricks

HSBC, as a foreign bank, offers comfortable work conditions and a two‑part interview: a Chinese technical round focusing on Java collections, concurrency, and JVM, followed by an English discussion.

HashMap Internal Implementation

HashMap underlying implementation

Before JDK 1.7, HashMap used an array of buckets with linked lists for collisions, leading to O(n) lookup when a bucket became long. In JDK 1.8, when a bucket’s list exceeds 8 entries, it is transformed into a red‑black tree, giving O(log n) lookup, while short lists remain as linked lists.

How HashMap retrieves elements

HashMap computes the key’s hash, then determines the bucket index with

(n - 1) & hash

, where

n

is the array length.

If the bucket holds a single node, the key is compared directly and the value returned.

If the bucket holds a linked list or red‑black tree, the structure is traversed and

equals()

is used to find a matching key; if none is found,

null

is returned.

Since JDK 8, when a list exceeds 8 elements and the array length is at least 64, it is converted to a red‑black tree, keeping worst‑case lookup at O(log n). Average lookup remains O(1).

ConcurrentHashMap Locking

JDK 1.7 ConcurrentHashMap

Uses a segmented lock architecture: a large

Segment

array (each a ReentrantLock) and a smaller

HashEntry

array for key‑value pairs. Each segment can be locked independently, allowing concurrent access to different segments.

JDK 1.8 ConcurrentHashMap

Combines volatile variables, CAS operations, and

synchronized

blocks. When adding an element, if the table is empty it is initialized with volatile + CAS. If not empty, the bucket is examined; a CAS sets a new node when the slot is empty, otherwise a synchronized block traverses the bucket, inserts or updates the node, and may convert the bucket to a red‑black tree.

Thus, ConcurrentHashMap achieves finer‑grained locking than the original segment lock, reducing contention and improving concurrency.

Difference Between synchronized and ReentrantLock

Usage :

synchronized

can decorate methods, static methods, and blocks;

ReentrantLock

works only in code blocks.

Lock acquisition :

synchronized

acquires and releases automatically;

ReentrantLock

requires explicit

lock()

and

unlock()

.

Lock type :

synchronized

is always non‑fair;

ReentrantLock

can be configured as fair or non‑fair.

Interruptibility :

ReentrantLock

supports interruption while waiting for the lock;

synchronized

does not.

Implementation :

synchronized

is implemented by the JVM monitor;

ReentrantLock

is built on AQS (AbstractQueuedSynchronizer).

JVM Garbage Collection: Minor vs Full

Scope : Minor GC cleans only the young generation (Eden and Survivor); Full GC cleans the entire heap, including old generation and metaspace.

Trigger : Minor GC occurs when young generation is full; Full GC triggers when old generation or metaspace is insufficient, or when

System.gc()

or CMS fails.

Pause time : Minor GC pauses are usually milliseconds; Full GC pauses can reach seconds.

Algorithm : Minor GC typically uses copying; Full GC uses mark‑sweep or mark‑compact.

Frequency : Minor GC happens frequently; Full GC is rarer.

Memory Leak vs Memory Overflow

Memory leak : Objects that are no longer needed remain referenced (e.g., static collections, unremoved listeners, lingering threads), preventing garbage collection and gradually exhausting heap space.

Memory overflow (OutOfMemoryError) : The JVM cannot allocate the requested memory. Common causes include heap space exhaustion, metaspace exhaustion (too many loaded classes), direct buffer overuse, or inability to create native threads.

Typical OOM scenarios

Heap space OOM:

Java heap space

– caused by excessive live objects or large

-Xmx

limits.

Metaspace OOM:

Metaspace

– caused by loading many classes or generating dynamic proxies.

Direct buffer OOM:

Direct buffer memory

or

allocate native memory

– caused by unreleased NIO direct buffers.

Native thread OOM:

unable to create new native thread

– caused by OS limits or insufficient virtual memory (

-Xss

).

Diagnosing OOM requires examining the specific error message, heap dumps, configuration, and monitoring tools.

SQL Queries for Top Scores

Overall top three scores

SELECT *
FROM students
ORDER BY score DESC
LIMIT 3;

Top three scores per class

SELECT s1.*
FROM students s1
WHERE (
  SELECT COUNT(*)
  FROM students s2
  WHERE s2.class = s1.class
    AND s2.score > s1.score
) < 3
ORDER BY s1.class, s1.score DESC;
JavaJVMmemory-managementSQLHashMapConcurrentHashMap
Java Tech Enthusiast
Written by

Java Tech Enthusiast

Sharing computer programming language knowledge, focusing on Java fundamentals, data structures, related tools, Spring Cloud, IntelliJ IDEA... Book giveaways, red‑packet rewards and other perks await!

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.