Senior
A senior answer names the tradeoff, the failure, and what to measure.
What does a service author need from the Java memory model?
Without a happens-before relationship, a thread can keep seeing a stale value written by another thread. volatile, locks, and the concurrent collections create that relationship. Final fields are visible after the constructor finishes, as long as this does not escape during construction. A plain write is not enough.
How do you investigate a long garbage-collection pause?
Read the collector log. Note the pause, how full the heap was before and after, and the allocation rate. A pause that tracks a growing old generation points at a leak or an unbounded cache. A pause where the heap recovers, with a high allocation rate, points at short-lived garbage. Change one thing and compare the same log.
How do you publish an object so other threads never see it half-built?
Finish the object, then publish one reference. Final fields are safely published when the constructor returns, if this does not escape while the constructor is still running. Handing out the reference and then calling setters lets another thread observe defaults.
When is ConcurrentHashMap a better choice than wrapping a HashMap with synchronizedMap?
ConcurrentHashMap allows concurrent reads and updates without locking the whole map, and a retrieval sees the most recently completed update. synchronizedMap locks the entire map, and a compound action such as check-then-act still needs an external lock. Use compute for a compound update on the concurrent map.
What do virtual threads change about blocking calls, and what do they leave unchanged?
Virtual threads, since Java 21, make a blocking I/O call cheap in operating-system threads, so a thread per request can wait on many calls. They do not make CPU-bound work faster. A scarce resource, such as a database, still needs a limit. On Java 21–23, avoid blocking inside synchronized, which pins the carrier thread; JDK 24 removed that limit (JEP 491).
Why is catching Exception and returning null a bug?
The caller cannot tell "not found" from "the database failed," and null then spreads. Catch the failure you can handle. Log an unexpected failure with its stack and let it surface as an error. Returning null deletes the cause.