Backend Development 26 min read

Master Java Concurrency & SpringBoot: DJI Interview Insights & Advanced Locks

This article combines a DJI interview experience—including salary and bonus details—with an in‑depth guide to Java concurrency tools, lock implementations, SpringBoot AOP, filters vs. interceptors, Kafka ordering, zero‑copy techniques, and related backend development best practices.

macrozheng
macrozheng
macrozheng
Master Java Concurrency & SpringBoot: DJI Interview Insights & Advanced Locks

Although DJI is not a Fortune‑500 company, it dominates the drone market with over 80% share and consistently strong financials, prompting curiosity about its employee bonuses. Reported data shows the R&D department’s median year‑end bonus around 180k CNY, with some exceeding 250k CNY, while the embedded team’s median approaches 200k CNY. Recent campus offers for embedded developers range from 260k CNY to 430k CNY, and backend positions can exceed 520k CNY annually.

DJI Java Backend Interview Overview

The interview lasted about 50 minutes and covered three main parts: an opening round of three questions (self‑introduction, knowledge of DJI, and motivation for the role), a deep dive into Java fundamentals (concurrency, Spring, Kafka), a project discussion, and two algorithm challenges.

Java Concurrency Tools

synchronized

– simple monitor lock, suitable for low‑contention scenarios.

ReentrantLock

– explicit lock supporting timeout, interruptibility, and fairness.

ReadWriteLock

– separates read (shared) and write (exclusive) locks for read‑heavy workloads.

StampedLock

– combines optimistic read with fallback to pessimistic lock for high‑performance reads.

Semaphore

– counting semaphore for rate‑limiting or resource‑pool control.

<code>public synchronized void method() {
    // critical section
}

public static synchronized void staticMethod() {
    // critical section
}

private final Object lock = new Object();
public void someMethod() {
    synchronized (lock) {
        // critical section
    }
}
</code>
<code>private final ReentrantLock lock = new ReentrantLock(true); // fair lock
public void doWork() {
    lock.lock();
    try {
        // critical section
    } finally {
        lock.unlock();
    }
}
</code>
<code>private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
public void readData() {
    rwLock.readLock().lock();
    try {
        // read shared data
    } finally {
        rwLock.readLock().unlock();
    }
}
public void writeData() {
    rwLock.writeLock().lock();
    try {
        // modify shared data
    } finally {
        rwLock.writeLock().unlock();
    }
}
</code>
<code>private final StampedLock stampedLock = new StampedLock();
public double readOptimistic() {
    long stamp = stampedLock.tryOptimisticRead();
    double value = sharedValue;
    if (!stampedLock.validate(stamp)) {
        stamp = stampedLock.readLock();
        try { value = sharedValue; } finally { stampedLock.unlockRead(stamp); }
    }
    return value;
}
public void write() {
    long stamp = stampedLock.writeLock();
    try {
        // modify shared value
    } finally {
        stampedLock.unlockWrite(stamp);
    }
}
</code>
<code>Semaphore semaphore = new Semaphore(1); // binary semaphore
semaphore.acquire();
try {
    // critical section
} finally {
    semaphore.release();
}
</code>

CountDownLatch

CountDownLatch allows one or more threads to wait until a set of operations performed by other threads completes. Threads call

await()

to block, and other threads invoke

countDown()

to decrement the counter. When the counter reaches zero, all waiting threads are released.

<code>int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
    new Thread(() -> {
        try {
            System.out.println(Thread.currentThread().getName() + " doing work");
            Thread.sleep(1000);
            latch.countDown();
        } catch (InterruptedException e) { e.printStackTrace(); }
    }, "Worker-" + i).start();
}
latch.await();
System.out.println("All tasks completed");
</code>

Concurrent Collections and Utilities

Thread‑safe containers:

ConcurrentHashMap

,

CopyOnWriteArrayList

,

ConcurrentLinkedQueue

.

Synchronization utilities:

CountDownLatch

,

CyclicBarrier

,

Semaphore

.

Atomic classes:

AtomicInteger

,

AtomicLong

,

AtomicBoolean

.

Lock hierarchy:

ReentrantLock

,

ReentrantReadWriteLock

,

StampedLock

.

How ConcurrentHashMap Works

In JDK 1.7, ConcurrentHashMap uses segment locks: the map is divided into several

Segment

objects, each protecting a subset of buckets, allowing concurrent access to different segments.

JDK 1.7 ConcurrentHashMap segment lock diagram
JDK 1.7 ConcurrentHashMap segment lock diagram

In JDK 1.8, the implementation switched to a lock‑striped design with

volatile

fields, CAS for bucket initialization, and fallback to

synchronized

for bucket updates. When a bucket’s chain grows beyond a threshold, it is transformed into a red‑black tree, reducing lookup from O(n) to O(log n).

JDK 1.8 ConcurrentHashMap bucket and tree structure
JDK 1.8 ConcurrentHashMap bucket and tree structure

CAS Pitfalls and Solutions

Compare‑And‑Swap (CAS) suffers from the ABA problem: a value may change from A to B and back to A, making the CAS operation think nothing changed. Java mitigates this with version stamps, e.g.,

AtomicStampedReference

, which stores a value together with a stamp that increments on each update.

<code>AtomicStampedReference<Integer> ref = new AtomicStampedReference<>(100, 0);
boolean success = ref.compareAndSet(100, 200, 0, 1); // succeeds only if value=100 and stamp=0
</code>

Java Lock Types

synchronized

– built‑in monitor lock, simple but non‑interruptible.

ReentrantLock

– explicit lock with interruptibility, timeout, and fairness options.

ReentrantReadWriteLock

– separate read and write locks for high read‑concurrency.

Spin‑lock style via CAS loops.

SpringBoot AOP Overview

Aspect‑Oriented Programming separates cross‑cutting concerns (logging, transactions, security) from core business logic. Key concepts include Aspect, Join point, Advice (before, after, around), Pointcut, Introduction, Weaving, AOP proxy (JDK dynamic proxy or CGLIB), and Target object.

Filters vs. Interceptors in SpringBoot

Feature

Filter

Interceptor

Specification

Servlet API (

javax.servlet.Filter

)

Spring MVC (

org.springframework.web.servlet.HandlerInterceptor

)

Scope

Global (all requests, static resources)

Controller layer only

Execution order

Before servlet processing

After DispatcherServlet, before/after controller methods

DI support

Cannot inject Spring beans directly

Can autowire beans

Typical use‑cases

Encoding, logging, security for all requests

Permission checks, parameter validation

Kafka Message Ordering

Kafka guarantees order only within a single partition. Producers must send related messages to the same partition (e.g., by using the same key). Consumers should process a partition with a single thread to preserve order. Global ordering requires a single partition or application‑level sequencing.

Ensuring Idempotent Writes

Idempotency key (UUID) stored and checked before processing.

Database transaction + optimistic lock (version field).

Unique constraints at the DB level.

Distributed lock (e.g., Redis lock) for critical sections.

Message deduplication using unique message IDs.

Why Kafka Is Fast

Sequential disk writes reduce seek time.

Batching reduces network and I/O overhead.

Zero‑copy (sendfile) moves data directly from kernel buffers to the network.

Optional compression lowers payload size.

Zero‑Copy in Java

Java achieves zero‑copy via

FileChannel.transferTo/transferFrom

, which delegates to the OS (e.g., Linux

sendfile

) to move data between file and socket buffers without copying through the Java heap.

<code>try (FileChannel source = FileChannel.open(Paths.get("input.txt"), READ);
     FileChannel target = FileChannel.open(Paths.get("output.txt"), WRITE)) {
    source.transferTo(0, source.size(), target);
}
</code>
Zero‑copy data flow diagram
Zero‑copy data flow diagram

The article concludes with the author’s interview impression—positive overall but noting gaps in some deep Java topics that need further study.

Javabackend developmentconcurrencyKafkaSpringBootLocks
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

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.