Exam Drill #21 · 5 Oct 2026 · 19 to fix · 66 drills

Twenty-first attempt — 41/60, and Spring Core lost 13 marks

41/60 = 68%, against a 76% pass mark. Five marks short. After two passes in a row this is a big drop, but it is a narrow one: 13 of the 19 misses are Spring Core, and Core was half the paper (about 30 questions). Data Management went the other way, from 75% to 100%.
Most of the Core misses are basics: @Autowired, stereotypes, @Bean attributes, @PostConstruct. And five of the 19 were questions you've already missed on an earlier paper. Getting just those five right would have scored exactly 46, which is a pass.

68%
Pass mark 76% ✗
−9
Marks on #20 (50 → 41)
19
Misses — was 10
13
Of them in Spring Core
5
Word-for-word repeats
Progress · every attempt

Twenty-one papers, out of 60

Hover a bar for the date and score. The dashed line is 46/60, the lowest pass.

Passed (46+) Below the pass

The first fourteen papers averaged 40.3. The last seven average 47.1, even with today's 41. Today puts you back at the level of the first fourteen papers, but the misses are concentrated in one section, which is easier to fix than a broad slump.

Official result · practice exam

68% — not passed

76% required to pass · 60/60 answered · 41 correct · time used 57m 57s of 2h 10m
Data Management 100%▲ 250 misses / 9 Spring Boot 80%▼ 22 misses / 10 Testing 75%▼ 252 misses / 8 Spring Core 57%▼ 2213 misses / 30 Spring MVC 33%▼ 532 misses / 3

How the sizes come out. There was no Security section this time. MVC at 33% with two misses can only be 1/3. Testing at 75% is 6/8, and Boot at 80% is 8/10. That leaves 13 misses for Core, and 57% with 13 misses only works as 17/30. Data takes the remaining 9 questions, all correct. MVC's 33% looks alarming, but it's three questions. Core's 57% is the real story: half the paper, and 13 of the 19 lost marks.

Where the next marks are

If you had…ScoreResult
Not repeated the five questions you'd already missed, word for word, on an earlier paper4677% — pass
…and got the three that repeat a topic you've missed before (BPP timing, Environment, proxy types)4982%
…and the five @Autowired / stereotype / @Bean basics5490%
What actually happened4168% — not passed

The pass needed no new knowledge. The five repeats on their own cover the gap. That's why the repeats block comes first on this page, and why it's worth redoing on a different day.

What moved between #20 and #21

Attempt #20Attempt #21Result
Score50/60 (83%)41/60 (68%)−9 · not passed
Misses1019+9
Questions with a false tick916+7
Stopped short (no false tick)13+2 · all three were "3 of 4 true"
Left blank00Held — ninth paper running
Spring Core misses413+9 — the whole drop
Data Management misses30−3 · the #20 Data drills held
Word-for-word repeats5 of 105 of 19Same count, different questions
Time39m 46s57m 57s+18 min

The +9 in Core matches the −9 in the score. Every other section moved by a mark or two. You also took 18 minutes longer than on #20, so this doesn't look like rushing. More likely, more of Core's questions felt uncertain this time.

Five questions were word-for-word repeats, and three repeated a topic

QTopicAlready on this siteThen → now
Q57@PostConstruct / @PreDestroy constraints#7 Q27, word for word, and #18 Q23, rewordedTicked "must be public" all three times
Q20When Load-Time Weaving changes bytecode#13 Q60, rewordedTicked "at runtime through JDK/CGLIB proxies" both times
Q5Customising the embedded server#8 Q23, word for wordTicked "exclude Tomcat, add Jetty = external server" both times, plus server.timeout this time
Q33The class that applies @Transactional advice#15, word for wordThen: invented TransactionStatusAdvice. Now: invented PlatformTransactionManagerAdvisor
Q39What @MockBean does#11 Q11, same optionsStopped short of the three true options both times
Q43When a BeanPostProcessor runs#14 Q29 and #19 Q2, same topicThird paper on BPP timing. Then "only once"; now "before instantiation"
Q45What Environment exposes#14 Q27, the non-web twinThen gave JNDI + servlet params to a non-web app. Now: invented "System Registry"
Q12CGLIB vs JDK proxy limits#13 Q24, same topicThen gave JDK proxies CGLIB's limits. Now gave CGLIB the JDK's interface rule

Q57 is now a three-time miss with the same wrong click. Two review pages have explained it, so reading isn't fixing it. What should help is answering the question again, correctly, on a different day. The first drill block has all eight, as they appeared on the paper.

My drill progress on this page

Each time you finish a drill block (every question answered), it's recorded here in this browser. Reload the page to retake a block. Questions and options reshuffle every time. Aim for a full score on every block before the next paper. Do the three Core blocks first, and redo the repeats block on a different day from the first try.

Drill blockQsLastBestRunsLast done
Loading…

All 19, at a glance

QTopicWhat went wrongThe answer
Q5Customising the embedded server+ server.timeout · + Jetty = "external" · same as #8WebServerFactoryCustomizer · server.port
Q10Valid @Autowired forms+ searchBy="type"Setter (Map) · constructor · array field
Q12CGLIB limitations+ "must implement an interface"Self-invocation · final class · final methods
Q20When LTW changes bytecode+ "via JDK/CGLIB proxies" · same as #13When a classloader loads the class
Q28@Autowired on a private field+ "by type, setter methods only"Injects by type, private fields too
Q29Properties of REST+ ResilienceStatelessness · scalability
Q30BFPP — which is incorrect?+ "applies transformations to bean definitions" (a true statement)"Its only method is postProcess()"
Q32Which is not a stereotype?+ @Configuration@Autowired
Q33Class in the tx AOP proxy+ PlatformTransactionManagerAdvisor · repeat of #15TransactionInterceptor
Q34Circular setter injection+ "always throws"Early reference to a partly built bean
Q37Controller argument annotationsStopped short — 3 were true@RequestParam · @PathVariable · @RequestBody
Q39@MockBeanStopped short — 3 were true · same as #11Class or field · adds mocks · can define a new bean
Q43When BPP modifies beans+ "before instantiation" · 3rd BPP paperBefore (and after) initialisation
Q45Environment in a web app+ "System Registry Properties"Servlet context · servlet config · JNDI
Q47Adding auto-config to a test+ @ContextConfiguration@ImportAutoConfiguration
Q50Why not field injection+ "harder to read"Breaks encapsulation · harder to test
Q56Excluding auto-configuration+ @ComponentScan(excludeFilters)exclude · excludeName · spring.autoconfigure.exclude
Q57@PostConstruct constraints+ "must be public" · 3rd timeReturns void · no parameters
Q60What @Bean can setStopped short — 3 were trueName · init method · destroy method

A note on what you ticked

The exported results show an icon instead of a letter for any option that was correct or ticked. So a no-letter option marked "Incorrect" is a definite false tick. Sixteen of the nineteen misses have at least one of those (Q5 has two). Q37, Q39 and Q60 have none, so they can only be under-selection. Each of those three had three true options, and you stopped before the third. On a single-answer question I can't tell whether you ticked the right option as well, because it looks the same either way.

Jump to a section

⓪ The repeats + the shape of the misses — 8 drills ①a Core: proxies, AOP, weaving — 4 misses · 10 drills ①b Core: DI and @Autowired — 6 misses · 12 drills ①c Core: lifecycle + container hooks — 4 misses · 9 drills ② Spring Boot — 2 misses (80%) · 6 drills ③ Testing — 2 misses (75%) · 6 drills ④ Spring MVC — 2 misses (33%) · 5 drills Every hook on one screen Mixed drill — all sections, no headings · 10 drills

⓪ The repeats, and the shape of the misses all 19 misses

Shape 1 · Q57, Q20, Q5, Q33, Q39 already missed on an earlier paper

Five repeats, and on three of them the same wrong click

QThe tempting optionWhy it feels rightWhat rules it out
Q57@PostConstruct must be publicThe container has to call it from outsideThe container calls it by reflection, which ignores visibility. Same reason @Autowired works on a private field
Q20LTW happens "at runtime through proxies"Load time is runtime, and Spring AOP is runtimeA proxy is a separate object. Weaving changes the class's own bytes, which happens as the classloader reads them
Q5Swap Tomcat for Jetty = external server"Exclude Tomcat" sounds like "remove the embedded server"Jetty is also embedded. External = WAR + SpringBootServletInitializer
Q33A …Advisor / …Advice classAOP vocabulary is all advice and advisorsThe class is an interceptor: TransactionInterceptor, a MethodInterceptor
Q39Stopping at two"Defines a new bean" sounds wrong for a mockIf no bean of that type exists, @MockBean adds one. Mocks are beans in that context
Memory hook: If an option feels familiar, ask whether you've seen it as the right answer or as the one you ticked last time.
Shape 2 · Q10, Q33, Q45, Q5, Q47, Q56 a name that doesn't exist, or the wrong tool

Six false ticks named something that isn't real, or a real thing that does a different job

QWhat you tickedWhat's actually true
Q10@Autowired(searchBy="type")@Autowired has one attribute: required
Q33PlatformTransactionManagerAdvisorNo such class. It's TransactionInterceptor
Q45"System Registry Properties"Spring reads JVM system properties and OS env vars, never the Windows registry
Q5server.timeoutNo generic property. It's server-specific: server.tomcat.connection-timeout
Q47@ContextConfiguration for auto-configReal, but it loads plain config classes. Auto-config needs @ImportAutoConfiguration
Q56@ComponentScan(excludeFilters)Real, but auto-config classes are imported, not scanned
Memory hook: Before ticking, name the class, method or property that would do it. If you can't name one, don't tick it. If you can, ask whether it does this job.
Shape 3 · Q37, Q39, Q60 stopped short

All three stopped-short misses were "three of four are true"

#20 got the stopped-short count down to one. Today it's three, and they're the same kind of question: four options, three true, and you stopped at two. On a "select all" question, check each option on its own. Don't stop because two already feel like enough. Ruling an option out needs a reason, such as a name that doesn't exist or a job it doesn't do, so if you can't give one, tick it.

Memory hook: On "select all", judge each option on its own. Three of four true is common.

① Spring Core 13 misses · 30 questions · 57%, down from 79%

Thirteen misses is too many for one block, so they're split into three groups by what they test. Each group has its own drill.

①a Proxies, AOP and weaving — Q12, Q20, Q33

Q12 · CGLIB limitations ticked a false option

CGLIB is a subclass. Every limit comes from what a subclass can't do

You ticked "The target class must implement at least one interface". You correctly rejected "only interface methods can be proxied".
JDK dynamic proxyCGLIB proxy
What it isA new class implementing the target's interfacesA runtime subclass of the target class
Needs an interface?YesNo — that's why it exists
Final classFine (it never extends it)Fails at startup
Final methodFine (interface methods can't be final)Silently not advised
Private / static methodNot advisedNot advised
this.other()Bypasses proxyBypasses proxy

This is #13's question turned round. On #13 you gave JDK proxies CGLIB's "final" limits. Today you gave CGLIB the JDK's "needs an interface" limit. Keep the two columns separate: JDK = interfaces. CGLIB = subclass, so no final. Only self-invocation and private methods affect both.

Memory hook: CGLIB subclasses, so final stops it. JDK implements interfaces, so it needs one.
Q20 · Load-Time Weaving ticked a false option same as #13 Q60

Weaving changes the class itself. A proxy leaves it alone

You ticked "At runtime through JDK/CGLIB proxy generation", the same option as on #13.
ModeWhenWho does itTarget's bytecode changed?
Compile-time (CTW)CompilingajcYes
Post-compileAfter compiling, on existing jarsajc -inpathYes
Load-time (LTW)As the classloader loads the classJava agent + ClassFileTransformerYes, in memory only
Spring AOPWhen the bean is createdA BPP wraps it in a proxyNo — not weaving

The trap is that "load time" and "runtime" both happen while the app is running. The difference is what changes. LTW rewrites the class's bytes before the JVM defines it. A proxy is an extra object that sits in front of an unchanged target. No packaging step weaves anything either.

Memory hook: LTW = Loader. The transformer edits the bytes as the classloader hands them over. Proxies aren't weaving at all.
Q33 · TransactionInterceptor ticked a false option same question as #15

The proxy runs a MethodInterceptor, and for transactions it's TransactionInterceptor

You ticked PlatformTransactionManagerAdvisor. On #15 you ticked TransactionStatusAdvice. Both are invented.

The chain: @EnableTransactionManagement registers a BeanFactoryTransactionAttributeSourceAdvisor. Its advice is a TransactionInterceptor. When a proxied method is called, the interceptor reads the @Transactional attributes, asks the PlatformTransactionManager for a transaction, calls the method, then commits or rolls back. TransactionTemplate is the programmatic alternative. You call it yourself, and no proxy is involved.

Memory hook: Declarative = TransactionInterceptor (proxy). Programmatic = TransactionTemplate (you).

①b DI, @Autowired, stereotypes, @Bean — Q10, Q28, Q32, Q34, Q50, Q60

Q10 + Q28 · @Autowired ticked a false option invented attribute

@Autowired has one attribute, and it works on fields, constructors and methods

Q10: you ticked @Autowired(required=false, searchBy="type"). Q28: you ticked "injects by type, using setter methods only".
FactDetail
AttributesOnly required (default true). No searchBy, no name
WhereConstructor · field (private too) · setter or any method · parameter
How it resolvesBy type → several matches? @Primary / @Qualifier / parameter name
CollectionsList<T>, Set<T>, T[], Map<String,T> get every bean of type T
Private fieldWorks through reflection
Single constructor@Autowired is optional (since 4.3)
Memory hook: @Autowired: one attribute (required), by type, anywhere a value can go in.
Q32 · Which is NOT a stereotype? ticked a false option

@Configuration is a stereotype, because it's meta-annotated with @Component

You ticked @Configuration. The answer was @Autowired.

A stereotype marks a class as a component, so scanning picks it up. The test is simple: open the annotation's source and look for @Component on it. @Service, @Repository, @Controller, @RestController (through @Controller) and @Configuration all have it. @Autowired goes on a field, constructor or method, and it asks for a bean rather than declaring one.

Memory hook: Stereotype = "I am a bean" on a class. @Autowired = "give me a bean" on a member.
Q34 · Circular dependencies ticked a false option

Setter or field cycles between singletons resolve, but constructor cycles fail

You ticked "Spring always throws BeanCurrentlyInCreationException regardless of injection type".
CyclePlain SpringBoot 2.6+
Singletons, setter / fieldResolved: early referenceFails unless spring.main.allow-circular-references=true
Singletons, constructorBeanCurrentlyInCreationExceptionSame
PrototypesBeanCurrentlyInCreationExceptionSame

How it works: A is instantiated (constructor done, fields empty), and a factory for an "early reference" to A goes into the singletonFactories cache. A asks for B. B is created and asks for A, and gets the early reference. B finishes, then A finishes. A constructor cycle can't do this, because no instance of A exists until its constructor returns, and that constructor is waiting for B. "Always throws" is false, because of the setter case.

Memory hook: Setter cycle: an early reference fixes it. Constructor cycle: there's nothing to hand over yet.
Q50 · Field injection ticked a false option

Field injection is easier to read. The case against it is design and testing

You ticked "it makes the code harder to read and understand".

Field injection is the shortest form, so readability is the one thing in its favour. The real objections: it breaks encapsulation (the container writes private state by reflection), it hides dependencies (they aren't in the constructor), it stops fields being final, and it makes the class harder to test (you need reflection or a Spring context to set the field).

Memory hook: Field injection: short to read, hard to test, breaks encapsulation.
Q60 · What @Bean can set stopped short

@Bean can set the name, the init method and the destroy method

Three of four were true. @Bean's attributes are name/value, initMethod, destroyMethod (default "(inferred)", which calls a public close() or shutdown()) and autowireCandidate. The false option was "include the class in component scanning". @Bean registers one object from a factory method and has nothing to do with scanning.

Memory hook: @Bean(name, initMethod, destroyMethod, autowireCandidate).

①c Lifecycle and container hooks — Q30, Q43, Q45, Q57

Q57 · @PostConstruct / @PreDestroy constraints ticked a false option 3rd time: #7, #18, #21

Void, no parameters, not static, and any visibility

You ticked "Must be public", on all three papers. You correctly rejected "can take parameters" every time.
RuleRequirementWhy
Return typevoidNobody reads a return value
ParametersNoneThe container has nothing to pass
StaticNot allowedIt's called on the instance
VisibilityAny — private is fineCalled by reflection (setAccessible(true))

Link it to something you already get right: @Autowired works on a private field because Spring uses reflection. @PostConstruct is called by a BPP (CommonAnnotationBeanPostProcessor) the same way, so private works there too. "Public is recommended" isn't the same as "public is required".

Memory hook: Reflection ignores private. If @Autowired can reach a private field, a BPP can call a private @PostConstruct.
Q43 · When BPP runs ticked a false option 3rd BPP-timing paper: #14, #19

A BPP post-processes, so the bean has to exist first

You ticked "Before the bean is instantiated".
StepWhat happensHook
0Bean definitions loaded and editedBeanFactoryPostProcessor
1Instantiate (constructor)—
2Dependency injection—
3postProcessBeforeInitializationBPP (@PostConstruct runs here)
4afterPropertiesSet() → initMethod—
5postProcessAfterInitializationBPP (AOP proxies made here)

"Before instantiation" is a BFPP's territory: it works on definitions, when no instance exists. A BPP receives Object bean as its argument, so the instance must already exist. #14 and #19 asked "when is it called?" (twice per bean). Today asked "when can it modify the instance?" The table above answers both.

Memory hook: BFPP = Factory = definitions, before any bean. BPP = Post-processes a real object, around init.
Q30 · BFPP — which is incorrect? ticked a true statement

The method is postProcessBeanFactory(), not postProcess()

You ticked "It applies transformations to bean definitions", which is true, so it isn't the answer to "which is incorrect".

BFPP's whole job is transforming bean definitions, as in the table above (step 0). The incorrect statement was "Its only method is named postProcess()". It does have only one method, but it's called postProcessBeanFactory(ConfigurableListableBeanFactory). Spring's built-in ones are PropertySourcesPlaceholderConfigurer (resolves ${…}) and PropertyOverrideConfigurer.

On a "which is incorrect" question, check every option before you pick one. A statement with a slightly wrong name in it is the usual answer.

Memory hook: BFPP: one method, postProcessBeanFactory. BPP: two, postProcessBefore/AfterInitialization.
Q45 · Environment in a web app ticked a false option invented source

A web app adds three sources: servlet config, servlet context, JNDI

You ticked "System Registry Properties".
Property source (highest first)Non-web (StandardEnvironment)Web (StandardServletEnvironment)
servletConfigInitParams—✓
servletContextInitParams—✓
jndiProperties—✓
systemProperties (JVM -D)✓✓
systemEnvironment (OS env vars)✓✓
Profiles✓✓

On #14 you gave the three web sources to a non-web app. Today's question was the web version, so those three were right. "System" in Spring always means the JVM's System.getProperties() / System.getenv(), never an OS registry.

Memory hook: Web adds the servlet two + JNDI. Everyone has system properties, env vars and profiles. Nobody has a registry.

② Spring Boot 2 misses · 10 questions · 80%, down from 82%

Q5 · Embedded server two false ticks same as #8 Q23

Switching to Jetty keeps the server embedded. External means WAR

You ticked "exclude spring-boot-starter-tomcat, add spring-boot-starter-jetty" to get an external server (as on #8) and server.timeout.
GoalHow
Change port / context path / SSLserver.port, server.servlet.context-path, server.ssl.*
Anything programmaticA WebServerFactoryCustomizer<T> bean
TimeoutServer-specific: server.tomcat.connection-timeout, server.jetty.connection-idle-timeout
Different embedded serverExclude spring-boot-starter-tomcat, add …-jetty or …-undertow
External serverPackage as WAR, extend SpringBootServletInitializer, Tomcat starter provided
Memory hook: Tomcat, Jetty and Undertow starters are all embedded. "External" always means WAR.
Q56 · Excluding auto-configuration ticked a false option

Auto-configuration is imported, not scanned, so scan filters can't remove it

You ticked @ComponentScan(excludeFilters = …). You got the three real switches.

@EnableAutoConfiguration uses AutoConfigurationImportSelector, which reads candidates from spring.factories (or AutoConfiguration.imports in 2.7+). It removes only what exclude, excludeName and spring.autoconfigure.exclude list. Component scanning never sees these classes. @SpringBootApplication even adds AutoConfigurationExcludeFilter to make sure of that.

Memory hook: Three switches: exclude (class), excludeName (string), spring.autoconfigure.exclude (property). Scanning isn't one.

③ Testing 2 misses · 8 questions · 75%, down from 100%

Q39 · @MockBean stopped short same as #11 Q11

Three true: class or field, adds mocks to the context, can define a new bean

No false tick, so you left one of the three true options out, as on #11. The one most likely to look wrong is "used to define a new Spring bean in the test context". It's true: if the context has no bean of that type, @MockBean registers one. If it has one, the mock replaces it. The only false option was "same as @Mock". @Mock is plain Mockito and never touches a Spring context.

For later: Boot 3.4 deprecates @MockBean in favour of Spring Framework's @MockitoBean. The exam is on Boot 2.x, so answer with @MockBean.

Memory hook: @MockBean = replace or add, in the context. @Mock = no context.
Q47 · Adding auto-configuration to a test ticked a false option

Auto-configuration goes in with @ImportAutoConfiguration

You ticked @ContextConfiguration.
AnnotationLoadsKnows about auto-config?
@ContextConfigurationPlain @Configuration classes or XML (spring-test)No
@ImportA regular config / component classNo — skips its ordering
@ImportAutoConfigurationNamed auto-config classes, with their conditions and orderingYes
@SpringBootTestThe whole appLoads all of it; you can't add one selectively
Memory hook: Slice test missing one auto-config? @ImportAutoConfiguration(Xxx.class).

④ Spring MVC 2 misses · 3 questions · 33%, down from 86%

33% is two misses out of three questions. It looks bad, but there's much less to fix than in Core.

Q29 · Properties of REST ticked a false option

REST is a list of constraints. Resilience isn't one of them

You ticked Resilience. You correctly rejected "loose coupling between classes".

The six constraints: client-server, stateless, cacheable, uniform interface, layered system, code on demand (optional). Scalability counts because it follows directly from statelessness: any server can handle any request. Resilience is about how the system is run (retries, failover), not one of REST's constraints. Related from #9: REST is an architectural style, not a protocol, and it is interoperable.

Memory hook: Stateless → scalable. If it isn't one of the six constraints or a direct result of one, it isn't REST.
Q37 · Controller argument annotations stopped short

Three of four go on a parameter. @RequestMapping doesn't

No false tick, so you left one of @RequestParam, @PathVariable and @RequestBody out. All three bind something from the request to a parameter. Others that go on a parameter: @RequestHeader, @CookieValue, @ModelAttribute, @MatrixVariable, @RequestPart. @RequestMapping goes on a class or method, never on a parameter.

Memory hook: @RequestMapping maps the method. Every other @Request… / @PathVariable fills a parameter.

Every hook on one screen

The nineteen misses, in one pass

Mixed drill — all sections, no headings

Ten questions with no topic label to prime you. For each option, name the class, method or property that would do it, and check it does this job. If you can't, it's false.

I'm your teacher — ask me anything. Say "build the Spring Core clinic". #20 suggested it, and today Core lost 13 marks. It's half the paper and the only big section without a clinic page. Or "drill the repeats" for one page made of every question you've missed on more than one paper. After #21 that list includes the @PostConstruct constraints (three times), LTW, the embedded server, TransactionInterceptor and @MockBean.
← Dashboard ← Review #20 Review #18 (Q57 second time) Review #13 (LTW, proxy limits) Review #14 (BPP, Environment) Boot clinic Testing clinic