DJI Java Backend Interview Experience, Salary Insights, and Core Concurrency Knowledge
The article shares DJI's impressive compensation data, details a 50‑minute Java backend interview covering concurrency tools, locks, CountDownLatch, ConcurrentHashMap, Kafka ordering, zero‑copy, Spring AOP, filters vs. interceptors, and provides code examples and explanations for each concept.
Hello everyone, I am Xiao Lin.
Although DJI is not a Fortune 500 company nor a listed firm, it dominates the drone market with over 80% share and consistently reports strong profits, prompting many to wonder about its year‑end bonuses.
According to leaked information, the R&D department’s median year‑end bonus is about 180,000 CNY (some exceeding 250,000 CNY), while the Embedded department’s median is close to 200,000 CNY, with a few receiving more than five months of salary.
DJI’s overall salary packages for new graduates range from 350,000 to 500,000 CNY annually, comparable to major internet companies.
Other benefits include a monthly housing allowance of 1,500 CNY (first year) and 1,000 CNY (second year), a monthly internal e‑coin of 500 CNY, a 10 am–10 pm work schedule, and double weekends.
DJI Java Backend First‑Round Interview (50 minutes)
Opening Three Questions
Self‑introduction (focus on technology stack and projects).
What do you know about DJI? (demonstrate prior research).
Why this position? (match between role and personal interests).
Java Concurrency Tools
Tool
Applicable Scenario
Characteristics
synchronizedSimple synchronization or low‑contention environments
Simple syntax, JVM‑optimized (biased lock, lightweight lock)
ReentrantLockHigh concurrency, need flexible control
Supports timeout, interrupt, fairness
ReadWriteLockRead‑heavy shared‑resource access
Maximises read concurrency
StampedLockVery high read‑performance requirements
Optimistic read lock reduces contention
SemaphoreRate‑limiting or resource‑pool management
Configurable number of permits
Example of synchronized usage:
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
}
}Example of ReentrantLock with a fair lock:
private final ReentrantLock lock = new ReentrantLock(true);
public void doWork() {
lock.lock();
try {
// critical section
} finally {
lock.unlock();
}
}Example of ReentrantReadWriteLock :
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();
}
}Example of StampedLock with optimistic read:
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);
}
}Example of Semaphore (single‑permit mutex):
Semaphore semaphore = new Semaphore(1);
semaphore.acquire();
try {
// critical section
} finally {
semaphore.release();
}CountDownLatch
CountDownLatch (java.util.concurrent) allows one or more threads to wait until a set of operations performed by other threads completes.
Initialize with a count.
Threads call await() to block.
Other threads call countDown() to decrement the count.
When the count reaches zero, waiting threads are released.
Example:
public class MainThreadWaitExample {
public static void main(String[] args) throws InterruptedException {
int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " executing task");
Thread.sleep(1000);
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "Worker-" + i).start();
}
latch.await();
System.out.println("All tasks completed");
}
}Common Concurrent Classes
Thread‑safe containers: ConcurrentHashMap , CopyOnWriteArrayList , CopyOnWriteArraySet , ConcurrentLinkedQueue , ConcurrentLinkedDeque .
Coordination utilities: CountDownLatch , CyclicBarrier , Semaphore .
Atomic classes: AtomicInteger , AtomicLong , AtomicBoolean .
Other utilities: ThreadLocal , lock interfaces ( ReentrantLock , ReentrantReadWriteLock , StampedLock ).
How ConcurrentHashMap Supports Concurrency
JDK 1.7 uses a segmented lock architecture: the map consists of an array of Segment objects (each a ReentrantLock ) and each segment holds an array of HashEntry linked‑list buckets. Only the segment containing the target bucket is locked, allowing other segments to be accessed concurrently.
JDK 1.8 replaces segments with a single array of bins that can be either a linked list or a red‑black tree. It uses volatile fields, CAS for lock‑free insertion when the bin is empty, and falls back to synchronized on the bin’s head node when contention occurs. This reduces lock granularity and improves performance, especially for large maps where the tree structure gives O(log n) lookup.
CAS Problems and Java’s Solution
CAS suffers from the ABA problem: a value may change from A→B→A, and a CAS check sees A again and assumes no change. Java mitigates this by attaching a version stamp or tag, e.g., AtomicStampedReference , which records both the value and a stamp.
AtomicStampedReference
ref = new AtomicStampedReference<>(100, 0);
// try to change value and stamp atomically
boolean success = ref.compareAndSet(100, 200, 0, 1); // succeeds only if value=100 and stamp=0Java Lock Types
synchronized : built‑in keyword, simple syntax, no manual release.
ReentrantLock : implements Lock , supports re‑entrancy, interruptible lock acquisition, timeout, fairness.
ReentrantReadWriteLock : separate read and write locks; multiple readers can hold the read lock simultaneously.
Spin lock (implemented via CAS) – low‑level busy‑wait lock.
Frequently Used Locks
For simple synchronization, synchronized is convenient:
public class Counter {
private int count = 0;
public synchronized void increment() { count++; }
public synchronized int getCount() { return count; }
}When more control is needed, ReentrantLock offers interruptible and timed lock acquisition:
public class InterruptibleLockExample {
private final ReentrantLock lock = new ReentrantLock();
public void doWork() {
try {
lock.lockInterruptibly();
// critical work
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
}In read‑heavy scenarios, ReentrantReadWriteLock improves throughput:
public class Cache {
private final Map
cache = new HashMap<>();
private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
public Object get(String key) {
readLock.lock();
try { return cache.get(key); }
finally { readLock.unlock(); }
}
public void put(String key, Object value) {
writeLock.lock();
try { cache.put(key, value); }
finally { writeLock.unlock(); }
}
}For simple counters, atomic classes based on CAS are ideal:
public class VisitorCounter {
private AtomicInteger count = new AtomicInteger(0);
public void increment() { count.incrementAndGet(); }
public int getCount() { return count.get(); }
}Spring AOP Overview
Spring AOP enables aspect‑oriented programming, separating cross‑cutting concerns (e.g., transactions, logging) from core business logic. Core concepts include AspectJ (aspect), Join point (method execution point), Advice (before/after/around), Pointcut (matching join points), Introduction, Weaving, and AOP proxy (JDK dynamic proxy or CGLIB).
Filter vs. Interceptor in Spring Boot
Feature
Filter
Interceptor
Specification
Servlet spec (
javax.servlet.Filter)
Spring MVC (
org.springframework.web.servlet.HandlerInterceptor)
Scope
Global – all requests and static resources
Controller layer – only Spring‑managed requests
Execution Order
Before Servlet processing
After DispatcherServlet, before/after controller method
DI Support
Cannot inject Spring beans directly
Can autowire Spring beans
Typical Use Cases
Global tasks – encoding, logging, security
Business‑level tasks – permission checks, parameter validation
Kafka Message Ordering
Kafka guarantees order only within a single partition. Producers achieve ordering by sending messages with the same key to the same partition (custom partitioner). Consumers must process a partition with a single thread to preserve order. Global ordering requires either a single partition (reducing parallelism) or business‑level sequencing.
Why Kafka Is Fast
Sequential disk writes minimise seek time.
Batching reduces network and I/O overhead.
Zero‑copy transfers data directly from kernel buffers to the network socket.
Optional compression reduces payload size.
Zero‑Copy in Java
Zero‑copy avoids copying data between user space (Java heap) and kernel space. Java’s FileChannel.transferTo / transferFrom invoke OS‑level mechanisms such as Linux’s sendfile , moving data directly from file buffers to socket buffers.
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);
}Zero‑copy results in “zero‑CPU copy”: data moves from disk → kernel buffer → socket buffer → NIC via DMA without touching the Java heap.
Project‑Related Questions
What is the main role of Redis in the project?
What does Kafka handle in the project?
Issues encountered with Redis and their solutions.
Issues encountered with Kafka and their solutions.
Known point‑cloud formats.
Experience using DJI products for SLAM (visual, LiDAR, or fusion).
Key difficulties in the project.
Algorithm Exercises
Determine if two singly linked lists intersect.
Count the number of 1 bits in an integer.
Interview Impression
The interview felt well‑matched to my experience; the Java questions were deep, and I need to review some topics over the weekend. Unfortunately, I did not advance to the second round.
IT Services Circle
Delivering cutting-edge internet insights and practical learning resources. We're a passionate and principled IT media platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.