Java Backend Interview: The 15 Questions That Come Up

JVM memory model, GC algorithms, concurrency primitives, collections and Spring — the questions asked in nearly every round, with the answer depth interviewers want.

IntermediateUpdated 2026-10-2976K views

JVM & Garbage Collection

Q1: Describe the JVM runtime memory areas.

  • Heap: objects (young gen Eden + 2 survivors, old gen)
  • Metaspace: class metadata, method constants (replaced pre-8 PermGen)
  • Stack: per-thread frames, local variables, operand stack
  • Native stack + PC register: JNI calls and per-thread instruction pointer

Q2: How does GC find garbage?

Root set (GC Roots) + reachability traversal: objects unreachable from roots (stack locals, statics, active thread references, JNI handles) are garbage. Reference counting fails on cycles — the classic demonstration is two objects referencing each other but nothing else.

Q3: CMS vs G1 vs ZGC.

CollectorPause feelChoose when
Parallel/ParallelOld全堆 STW,吞吐高批处理、无低延迟要求
CMS老年代并发,碎片多,已废弃(JDK14)历史项目兼容
G1Region 化、可预测停顿目标(-XX:MaxGCPauseMillis)堆 6GB 以上,JDK9+ 默认
ZGC/Shenandoah亚毫秒级停顿,堆到 TB低延迟服务,JDK15+(ZGC)
Interviewers love the follow-up 'what does -XX:MaxGCPauseMillis actually guarantee?' — G1 does Soft Real-Time: it plans region collection to MEET the target, and if it misses repeatedly it degrades rather than corrupting anything.

Concurrency

Q4: volatile — what two things does it guarantee?

Visibility (writes flush to main memory, reads invalidate cache) and happens-before ordering; NOT atomicity (i++ still races). DCL singleton needs volatile because of instruction reordering: an object can be 'published' before its constructor finishes.

public class Singleton {
    private static volatile Singleton instance;   // ← volatile 不可省
    public static Singleton get() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) instance = new Singleton();
                // 分配内存 → 调构造 → 赋引用,重排后可能先赋引用
            }
        }
        return instance;
    }
}

Q5: synchronized vs ReentrantLock vs CAS/atomic.

ToolUnlock conditionInterruptible?
synchronized自动(异常/退出)否(不响应 interrupt)
ReentrantLock必须 unlock()(finally!)是,支持 tryLock 超时
AtomicXxx / CAS无锁,竞争失败自旋无阻塞,适合低-中竞争

Q6: Thread pool — what happens when you submit to a full pool?

corePoolSize → queue → maxPoolSize → rejection policy. The trap: Executors.newFixedThreadPool uses an unbounded LinkedBlockingQueue, so maxPoolSize is never reached and memory grows until OOM. Always construct ThreadPoolExecutor explicitly with a bounded queue.
ThreadPoolExecutor pool = new ThreadPoolExecutor(
    8, 32,
    60L, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(2000),        // 有界!
    new ThreadFactoryBuilder().setNameFormat("order-%d").build(),
    new ThreadPoolExecutor.CallerRunsPolicy());  // 队列满→让提交者自己跑(反压)

Collections & Spring

Q7: HashMap internals after Java 8.

Array of buckets + linked lists that convert to red-black trees when a bucket exceeds 8 entries (and shrink back below 6). Capacity is always a power of two so hash % capacity is a cheap bit mask. Not thread-safe — concurrent put can lose data or resize-loop; the JDK8 resize fixes the JDK7 infinite-loop bug but put still races.

Q8: Spring Bean lifecycle in one breath.

Instantiate → populate properties → BeanNameAware/BeanFactoryAware/ApplicationContextAware → BeanPostProcessor.before → @PostConstruct / InitializingBean.afterPropertiesSet / init-method → BeanPostProcessor.after (AOP proxy wraps here) → ready → (destroy) @PreDestroy / DisposableBean.destroy.

Q9: How does @Transactional actually fail?

  • Self-invocation: same-class call bypasses the proxy (no proxy in the call chain)
  • Method not public: JDK proxies only intercept public methods
  • Exception swallowed: catch it without rethrowing → no rollback
  • Checked exception by default does NOT roll back — specify rollbackFor = Exception.class
Rolling back on checked exceptions is the #1 silent data-consistency bug in Spring services. Make it a review checklist item: every @Transactional that can throw a checked exception must declare rollbackFor.

Friends & Partners