Interview replay
Full round replay — Spring AOP
Timed verbal replay with pass/fail criteria per follow-up.
How to run this
The opener
“How does Spring AOP work, and what are its limits?”
Budget: 45 seconds. Going long here is itself a fail signal.
Follow-ups
1. “Which proxy does Spring create, and when?”
Testing: Do they know Boot changed the default, or only the textbook rule?
Scoring
Pass: Classically JDK dynamic when the bean has an interface, CGLIB when it does not. Spring Boot sets proxyTargetClass=true, so it is CGLIB either way unless you turn that off.
Fail: Says it is always CGLIB, or always JDK, with no mention of interfaces.
2. “Why does injecting the concrete class sometimes fail once an aspect is added?”
Testing: Whether they connect the proxy type to the injection point.
Scoring
Pass: A JDK proxy implements the interface and is not an instance of your class, so there is no candidate of the concrete type and the context fails to start. A CGLIB proxy is a subclass, so it still matches — which is why the same code works in one project and not another.
Fail: Blames component scanning or a missing bean.
3. “Why can a final method not be advised?”
Testing: Mechanism, not rule recitation.
Scoring
Pass: CGLIB advises by subclassing and overriding, and a final method cannot be overridden, so there is nowhere to put the advice. A final class cannot be subclassed at all, so the proxy cannot be built.
Fail: 'Spring doesn't support it' with no reason.
4. “My @Cacheable method runs every time. Where do you look?”
Testing: First instinct — proxy boundary, or configuration?
Scoring
Pass: Self-invocation first. Then public, non-final, and the caching infrastructure enabled. All of those fail silently.
Fail: Starts with cache keys or the cache manager before considering the call path.
5. “Does a method reference like this::doWork go through the proxy?”
Testing: The version of self-invocation that survives code review.
Scoring
Pass: No — it is bound to `this`, the raw bean. Same bug, with the this. removed, which is exactly why nobody catches it in review.
Fail: Thinks a method reference is dispatched differently from a normal call.
6. “Two aspects on one method. Which runs first?”
Testing: Nesting versus queueing.
Scoring
Pass: The lowest @Order is outermost: first in, last out. They nest, so an outer timing aspect measures the inner one's work and an inner one does not measure the outer's.
Fail: Describes them as running one after another, or says the order is undefined.
7. “Why does an annotation on a method called from @PostConstruct do nothing?”
Testing: Do they know when the proxy is created?
Scoring
Pass: The proxy is created by a BeanPostProcessor after initialisation. During construction and @PostConstruct there is no proxy, so the call is on the raw bean.
Fail: Assumes the proxy exists as soon as the object does.
8. “How would you prove in a test that an aspect is applied?”
Testing: Behaviour versus annotation presence.
Scoring
Pass: Assert on observable behaviour — a call count, a transaction count, a cache hit. AopUtils.isAopProxy tells you the bean is proxied; only behaviour tells you the call path was advised. Reflecting over annotations proves nothing.
Fail: Would assert the annotation is present, or check the bean's class name.
9. “When is AspectJ the right answer instead?”
Testing: Whether they can decline it.
Scoring
Pass: When you genuinely need private or final methods, constructors, field access, or objects Spring did not create. It is compile-time or load-time weaving and costs build or agent configuration. Most self-invocation problems are a class doing two jobs, and splitting it is cheaper.
Fail: Reaches for AspectJ as the fix for self-invocation.
Score yourself
← Back to How does Spring AOP work, and what are its limits?