Exam Drill #17 · 19 Sep 2026 · 9 to fix · 59 drills

Seventeenth attempt — third pass in a row, and the best yet

51/60 = 85%, against a 76% pass mark. Your best score in seventeen papers, and +2 on #16. Spring Core 71% → 96%. Spring Boot 75% → 89%. Those were the two sections the last page told you to drill. Finished in 44m 22s, your fastest pass.
The margin is now five questions (46/60 is the lowest pass), up from three. This page is about the three sections that slipped while you worked on the other two, Data (70%), MVC (71%) and Testing (75%), and about the seven misses that were already answered on this site.

85%
Pass mark 76% ✓
+2
Marks on #16 (49 → 51)
9
Misses — was 11
7
Of the 9 already answered on this site
Official result · practice exam

85% — congratulations, you passed

76% required to pass · 60/60 answered · 51 correct · time used 44m 22s of 2h 10m
Spring Security 100%▬ 00 misses / 1–2 Spring Core 96%▲ 251 miss / 24–25 Spring Boot 89%▲ 141 miss / 9 Testing 75%▼ 142 misses / 8 Spring MVC 71%▼ 182 misses / 7 Data Management 70%▼ 213 misses / 10

Section sizes: Data 7/10 = 70%, MVC 5/7 = 71.4%, Testing 6/8 = 75% and Boot 8/9 = 88.9% are the only sizes that give those percentages with those miss counts. That leaves 26 questions for Core and Security. Core is 24 or 25 (23/24 and 24/25 both round to 96%), so Security is 2 or 1.
Small sections swing hard. MVC had seven questions, so each miss costs it 14 points. Its drop from 89% to 71% is one extra miss. Data's drop is two.

What moved between #16 and #17

Attempt #16Attempt #17Result
Score49/60 (82%)51/60 (85%)Best of seventeen
Misses119−2
Questions with a false tick87−1
Stopped short (no false tick)32−1
Left blank00Held
Spring Core misses61−5
Margin over the pass mark3 questions5 questions+2
Time51m 32s44m 22s86 minutes unused

Spring Core went from six misses to one. It was the biggest section on #16 and the one the page spent most time on. Across the nine questions you missed there were 23 false options, and you rejected 16 of them. No question had more than one false tick.

The sections you drilled went up. The ones you didn't went down.

The 30-minute routine on #16 pointed at Core and Boot. Here's what each section did next:

SectionIn #16's routine?#16 → #17Misses
Spring CoreYes — 15 minutes71% → 96%6 → 1
Spring BootYes — 5 minutes75% → 89%2 → 1
Data ManagementNo91% → 70%1 → 3
Spring MVCNo89% → 71%1 → 2
TestingNo89% → 75%1 → 2

This is the same pattern as the mixed practice set: a section goes up after its clinic and slides back within a week or two. You gained six marks in Core and Boot and gave four back in the other three. So the routine below covers all five sections, weighted to the three that fell.

Seven of the nine were already answered on this site

Two are the same question word for word. One was a drill on the last page, four days before this paper. These seven marks need no new study, only recall.

QTopicAlready on this siteThen → now
Q41@RequestMapping statementsReview #10 Q37 — same questionStopped short → ticked a false option
Q35matchIfMissingReview #16, a drill: "property not set → does not match"Four days later, ticked "still loaded"
Q33execute(String) returns voidData clinic §5 — "caught you twice"Third time, ticked Map
Q52Commit a test transactionReview #10 Q5@NoRollback → @Transactional(commit=true)
Q43Prototypes get no destroy callbackReview #9 Q57Ticked "All of the above"
Q19Using a SpecificationReview #8 Q1Ticked @Query
Q2Controller parameter annotationsMVC round 3 §2 — lists all fiveStopped short — all five were true

Q35 is the one to learn from. The drill on #16 was "@ConditionalOnProperty(name = "enable.x", havingValue = "true") — the property is not set at all. What happens?" Four days later the same fact came back in a longer question and went the other way. A fact you've drilled once isn't reliable yet. That's why every repeat here has drills that ask it from a different angle.

Where the next marks are

BucketMarksWhat it costs you
The seven repeats7No new material. Q2, Q19, Q33, Q35, Q41, Q43, Q52
Real annotation, invented job3Q19, Q41, Q52 — the trap drill below
Take them all when all check out2Q2 (five of five), Q56 (three of four)
"All of the above" needs every option1Q43 — one false option kills it
Genuinely new2Q51 (keyword order), Q56 (@SpringBootTest's Javadoc list)

The rows overlap, so don't add them up. Only two of the nine were new to you. Aim for 54+ next time, which is 90%.

All 9, at a glance

QTopicWhat went wrongThe answer
Q2Controller parameter annotationsStopped short — all 5 were true@MatrixVariable · @RequestParam · @PathVariable · @RequestHeader · @CookieValue
Q19Using a Specification+ "use @Query"findAll(spec) from JpaSpecificationExecutor
Q33JdbcTemplate.execute(String) return type+ Mapvoid
Q35matchIfMissing = false+ "property not defined → still loaded"Set matchIfMissing = true to load it when missing
Q41@RequestMapping statements+ "redundant with @RestController"All HTTP methods by default · path takes an array
Q43Which one is true about scopes+ "All of the above"Prototypes get no destroy callbacks
Q51Derived query name order+ ordering before comparisonfind(First[n])By + property + comparison + ordering
Q52Commit a test transaction+ @Transactional(commit=true) — invented@Commit · @Rollback(false)
Q56What @SpringBootTest configuresStopped short — 3 were trueFinds @SpringBootConfiguration · TestRestTemplate/WebTestClient · default context loader

Jump to a section

⓪ Three trap shapes — 12 statements ① Data Management — 3 misses (70%) ② Spring MVC — 2 misses (71%) ③ Testing — 2 misses (75%) ④ Spring Boot — 1 miss (89%) ⑤ Spring Core — 1 miss (96%) Mixed drill — all sections, no headings

⓪ Three trap shapes 6 of the 9 misses

Six of the nine misses were one of three shapes of question. The other three (Q33, Q35, Q51) are plain facts.

Shape 1 · Q19, Q41, Q52 real part, invented job

A real annotation given an attribute or a job it doesn't have

On #15 and #16 the fakes were invented names: TransactionStatusAdvice, BeanFactoryApplicationContext. You now reject those. This paper hid the fakes inside real annotations instead, and you ticked all three:

QReal partInvented jobThe test that exposes it
Q52@Transactionala commit attributeList its attributes: propagation, isolation, timeout, readOnly, rollbackFor, noRollbackFor. No commit
Q19@Queryholds a Specification@Query takes a JPQL string. A Specification is a Java object, so it can only be passed in as an argument
Q41@RestControllermaps URLs from method namesName one controller you've written with no @GetMapping. There isn't one
Memory hook: A real annotation doesn't make the sentence true. Ask: "Could I write that line of code?" @Transactional(commit = true) doesn't compile.
Shape 2 · Q2, Q56 stopped short

When every option checks out, take them all

Q2 had five options and all five were true. Q56 had four and three were true. You ticked no false option on either question, so you stopped before you'd taken every true one. It's the third paper in a row with this shape: #16 had Q30 (four of four), Q4 and Q55.

The routine: go through the options one by one and mark each true or false on its own. Then tick every one you marked true, even if that's all of them. Don't decide in advance how many answers there "should" be.

Memory hook: Judge each option alone, then tick every true one. Five out of five is a real answer.
Shape 3 · Q43 ticked a false option

"All of the above" is only true if every other option is true

Q43 asked for one true statement, and "All of the above" was one of the options. Ticking it says A and B and C are all true. Find one false option and "All of the above" is out. Here there were two: singletons are created at startup, not lazily (A), and the stateless/stateful advice is the wrong way round (C).

Memory hook: "All of the above" = an AND of every other option. One counterexample kills it.

① Data Management 3 misses · 10 questions · 70%

Q33 · JdbcTemplate.execute(String sql) ticked a false option 3rd time · data clinic §5

execute(String sql) returns void. It's for DDL.

You ticked Map. You correctly rejected "an entity" and int. The Data clinic says of this exact distinction: "it caught you twice". This is the third.
MethodReturnsFor
execute(String sql)voidDDL: CREATE, ALTER, DROP
update(sql, args…)int — rows affectedINSERT, UPDATE, DELETE
batchUpdate(…)int[]Many updates
queryForObject(sql, Class)TOne value or one row
queryForMap(sql)Map<String, Object>One row as a map
queryForList(sql)List<Map<String, Object>>Many rows as maps
query(sql, RowMapper)List<T>Many rows as objects

Why Map was tempting: queryForMap is a real method. But only the query… methods return data. The name tells you the return type: query returns rows, update returns a count, execute returns nothing. (The execute overloads that take a callback return whatever the callback returns. The one that takes a plain String returns void.)

Memory hook: execute = DDL = void. update = DML = int. query… = SELECT = data.
Q19 · Using a Specification real part, invented job review #8 Q1

Pass the Specification to findAll(spec). @Query has nothing to do with it.

You ticked "Use @Query to define a specification-based query". You correctly rejected "annotate specifications with @Query" and "a custom repository implementation".
public interface ProductRepository
        extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {}

// the Specification is an ARGUMENT, built at runtime
List<Product> cheap = repo.findAll(hasPriceGreaterThan(new BigDecimal("50")));
List<Product> both  = repo.findAll(
        hasPriceGreaterThan(new BigDecimal("50")).and(hasCategory("Electronics")));
Way to queryWhere the query lives
Derived queryThe method name — findByPriceGreaterThan
@QueryA JPQL or SQL string on the method
SpecificationA Criteria API object passed to findAll / findOne / count
Query by ExampleAn Example<T> object passed to findAll (QueryByExampleExecutor)

JpaSpecificationExecutor<T> gives you: findOne(spec) → Optional<T> · findAll(spec) → List<T> · findAll(spec, Pageable) → Page<T> · findAll(spec, Sort) → List<T> · count(spec) → long. Specifications combine with and(), or() and Specification.not().

Memory hook: A Specification is an argument, not an annotation. Extend JpaSpecificationExecutor, then call findAll(spec).
Q51 · Derived query name order ticked a false option

By → property → comparison → OrderBy. It's the same order as SQL: WHERE, then ORDER BY.

You ticked find(First[count]) By[Property] [ordering] [comparison], with ordering and comparison swapped. You correctly rejected both options that put operators before By.
List<User> findFirst3ByAgeGreaterThanOrderByLastNameAsc(int age);
//          ^^^^^^ ^^ ^^^ ^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^
//          limit  By prop comparison  ordering

// select u from User u where u.age > ?1 order by u.lastName asc   (limit 3)

Why the order can't be swapped: the comparison keyword belongs to its property. AgeGreaterThan is one piece, the same as age > ?1 in SQL. OrderBy starts a new clause and always comes last, as in SQL. Put OrderBy between Age and GreaterThan and Spring would try to sort by a property called AgeGreaterThan.

Memory hook: Read the name as SQL: SELECT (find, First3) … WHERE (By Age GreaterThan) … ORDER BY (OrderBy LastName Asc).

② Spring MVC 2 misses · 7 questions · 71%

Q41 · @RequestMapping statements real part, invented job same question · review #10 Q37

Two true: it maps every HTTP method by default, and path takes an array

You ticked "redundant if a class is annotated with @RestController, as such classes create mappings by their method names". You correctly rejected "method-level only". On #10 you stopped short on this same question; this time you ticked a false option.
OptionVerdictWhy
Method-level onlyFalseClass level sets a base path for every method
Maps all HTTP methods unless you say otherwiseTrueAdd method = RequestMethod.GET to restrict it
Redundant with @RestController; methods map by nameFalse@RestController = @Controller + @ResponseBody. That's all it adds
path takes an array of StringsTrue@RequestMapping({"/users", "/members"})

Where "mapped by method name" comes from: method names do mean something in Spring Data. findByLastName becomes a query. In Spring MVC a method name means nothing. A URL exists only if an annotation declares it. Also note that @GetMapping and its siblings can only go on methods. @RequestMapping is the only one that also works on a class.

Memory hook: Method names build queries in Spring Data, and nothing in MVC. Bare @RequestMapping = every verb; path = an array.
Q2 · Controller parameter annotations stopped short MVC round 3 §2

All five were true — each one names a part of the request

No option was false, so you left out at least one. The export can't show which. MVC round 3 lists all five, and its rule covers them: "anything naming a part of the request binds a parameter".
AnnotationBinds fromExample
@PathVariableA URI template variable/orders/{id}
@RequestParamQuery string or form field?page=2
@MatrixVariableName-value pairs inside a path segment/cars;color=red;year=2012
@RequestHeaderAn HTTP headerAccept-Language
@CookieValueA cookieJSESSIONID
@RequestBodyThe body, through an HttpMessageConverterJSON
@ModelAttributeSeveral parameters bound onto one objectA form
@SessionAttribute · @RequestAttributeSession / request attributes—

Fakes you might meet: @QueryParam, @PathParam, @HeaderParam, @CookieParam and @FormParam are real, but they're JAX-RS, not Spring MVC. @MatrixVariable only works if semicolon content isn't stripped from the URL. Set that with configurePathMatch() in a WebMvcConfigurer.

Memory hook: Path, Param, Matrix, Header, Cookie, Body — each names a part of the request. @QueryParam, @PathParam and @HeaderParam are JAX-RS, not Spring.

③ Testing 2 misses · 8 questions · 75%

Q52 · Commit a test transaction real part, invented job review #10 Q5

@Commit and @Rollback(false). @Transactional has no commit attribute.

You ticked @Transactional(commit=true). You correctly rejected @Sql(alwaysCommit=true) and @SqlMergeMode(false). On #10 the fakes were @NoRollback and @NoRollback(true), invented annotations. This time the fake was an invented attribute on a real annotation.
@SpringBootTest
@Transactional                 // tests roll back by default
class OrderRepositoryTest {

    @Test @Commit              // commit this one
    void savesForReal() { … }

    @Test @Rollback(false)     // same effect
    void alsoSavesForReal() { … }
}
AnnotationMain attributes
@TransactionaltransactionManager · propagation · isolation · timeout · readOnly · rollbackFor · noRollbackFor
@Rollbackvalue — true by default
@Commitnone. It's meta-annotated with @Rollback(false)
@Sqlscripts/value · statements · executionPhase · config
@SqlMergeModeMergeMode.MERGE or OVERRIDE — an enum, not a boolean
Memory hook: Tests roll back by default. Two ways to commit: @Commit and @Rollback(false). @Transactional's attributes control how the transaction runs, not how a test ends.
Q56 · What @SpringBootTest configures stopped short

Three of four were true. This question is lifted from @SpringBootTest's Javadoc.

No false option ticked, so you left out at least one of the three true ones. You correctly rejected PropertySourcesPlaceholderConfigurer.
@SpringBootTest's Javadoc says it…Detail
Uses SpringBootContextLoader as the default context loaderUnless you set @ContextConfiguration(loader = …)
Searches for a @SpringBootConfigurationUnless there's a nested @Configuration or you pass classes
Registers a TestRestTemplate and/or WebTestClientOnly when a real server runs: RANDOM_PORT or DEFINED_PORT
Lets you set Environment propertiesproperties = "app.x=1"
Lets you pass application argumentsargs = "--debug"
Supports the webEnvironment modesMOCK (default) · RANDOM_PORT · DEFINED_PORT · NONE

What it does not give you: MockMvc. That needs @AutoConfigureMockMvc as well (@WebMvcTest includes it). And there's no TestRestTemplate in the default MOCK mode, because no server is running.

Memory hook: @SpringBootTest = finds the Boot config, uses SpringBootContextLoader, adds TestRestTemplate/WebTestClient when a real server runs. MockMvc needs @AutoConfigureMockMvc.

④ Spring Boot 1 miss · 9 questions · 89%, up from 75%

Q35 · matchIfMissing = false ticked a false option a drill on review #16, 4 days earlier

Property missing + matchIfMissing = false → not loaded

You ticked "If custom.feature.enabled is not defined in the properties file, CustomFeatureAutoConfiguration will still be loaded." You correctly rejected "YAML only", "loaded only when set to false" and "always loaded".
havingValue = "true" and…Property = trueProperty = falseProperty absent
matchIfMissing = false (default)LoadedNot loadedNot loaded
matchIfMissing = trueLoadedNot loadedLoaded

What may be leaking in: without havingValue, any value except false matches. That rule is about which values match. Whether a missing property matches is decided by matchIfMissing alone, and it defaults to false. So a feature is off unless you turn it on.

The bank's answer is loosely worded: "to ensure the configuration always loads, set matchIfMissing = true". It doesn't make it load every time: with the property set to false it still won't load. It's the best of the five options, not a precise statement.

Memory hook: Missing = not loaded, unless matchIfMissing = true. Features are opt-in by default.

⑤ Spring Core 1 miss · 24–25 questions · 96%, up from 71%

Q43 · Which one is true about scopes ticked a false option review #9 Q57

Only one is true: prototypes don't get destroy callbacks. "All of the above" fails because A and C are false.

You ticked "All of the above". That claims A and C are true as well, and both are false. The fact itself, no @PreDestroy for prototypes, is from review #9.
OptionVerdictCounterexample
A. A singleton is created lazily, on first requestFalseThe ApplicationContext creates every non-@Lazy singleton at startup, in refresh()
B. Destroy callbacks aren't called on prototypesTrueThe container hands a prototype over and stops tracking it
C. Prototype for stateless, singleton for statefulFalseThe wrong way round. A shared singleton must hold no per-user state
D. All of the aboveFalseA is false, so "all" is false

Why eager is the default: a missing dependency or a bad config value should fail at startup, not on the first request an hour later. A plain BeanFactory is lazy. The ApplicationContext isn't, unless a bean is @Lazy. Prototypes are always created on demand, and Spring calls @PostConstruct on them but never @PreDestroy.

Memory hook: Singleton: eager, shared, stateless, full lifecycle. Prototype: on demand, stateful, init yes, destroy never.

The 9 facts, one line each

Drill these, don't read them

Mixed drill — all sections, no headings

Ten questions with no topic label to prime you. Judge each option on its own, then tick every true one. For each annotation, ask whether you could actually write that line of code.

The change to make before the next attempt (1) Keep the routine. Three passes in a row, 60/60 answered every time, and the score has gone 46 → 49 → 51. (2) Drill every section, not just the weakest. Core and Boot went up after you drilled them; Data, MVC and Testing went down when you didn't. Five minutes per section beats thirty on one. (3) Ask whether you could write the line. @Transactional(commit = true), @Query holding a Specification, URLs mapped by method name: all three were real annotations with an invented job. (4) Judge each option on its own, then tick every true one. Q2 was five of five. (5) Aim for 54+. Seven of the nine misses were already on this site.
A 30-minute routine before the next paper 5 min — the trap drill. Twelve statements, three shapes. 10 min — Data Management. Eleven drills: JdbcTemplate return types, Specifications, method-name order. 5 min — Spring MVC. Parameter annotations and @RequestMapping. 5 min — Testing. Committing tests and @SpringBootTest. 5 min — the mixed drill. Every section, so Core and Boot stay warm.
I'm your teacher — ask me anything. Say "drill the repeats" for a set built from every question you've missed more than once across all seventeen papers (Q33, Q35 and Q41 all qualify now), or "quiz me on the 9" for this attempt. Data Management is the lowest section again, so say "refresh the Data clinic" and I'll add this paper's three misses to it.
← Dashboard ← Review #16 Data clinic Testing clinic MVC round 3