Provyn Prep · 8 min read
How to pass the Provyn Java assessment
Java 17+ questions. The assessment focuses on concurrency, generics, streams, and the language changes that separate modern Java from what most tutorials still teach.
What you will be tested on
- Java memory model: happens-before, volatile, synchronized
- Generics: bounds, wildcards (? extends / ? super), type erasure
- Streams: lazy evaluation, terminal operations, collectors
- CompletableFuture: chaining, error handling, thenCompose vs thenApply
- Records, sealed classes, pattern matching (Java 16–21)
- Virtual threads (Project Loom, Java 21)
What the assessment tests
The Java assessment is not about Spring or Hibernate — it tests the language and standard library, specifically the modern features that have shipped since Java 11. If you have been writing Java since Java 8 and haven't revisited recent releases, the assessment will expose that gap.
The highest-weighted area is the concurrency model. Know the Java memory model happens-before relationship, when volatile is sufficient versus when synchronized is required, and how CompletableFuture chains work.
Generics: bounds and wildcards
Bounded wildcards are the most tested generics topic. ? extends T is a producer — you can read a T from it but not write. ? super T is a consumer — you can write a T to it but not safely read. Remember PECS: Producer Extends, Consumer Super. The assessment will ask which wildcard to use for a method that adds to a list versus one that reads from it.
Type erasure: generic type parameters are erased at runtime. List<String> and List<Integer> are the same class at runtime. You cannot use instanceof with a generic type parameter. The assessment will show code that does this and ask if it compiles — it does not, or it produces an unchecked warning.
Streams and lazy evaluation
Stream operations are lazy until a terminal operation is invoked. filter, map, flatMap are intermediate — they return a new Stream. collect, count, findFirst, forEach are terminal — they trigger the pipeline. A stream without a terminal operation does nothing.
Collectors: Collectors.groupingBy produces a Map<K, List<T>>. Collectors.toMap requires a key mapper and value mapper. Collectors.joining concatenates strings. The assessment will ask you to write a pipeline that groups, counts, or reduces a list — know which collector to use without looking it up.
Modern Java (16–21)
Records are immutable data classes with a compact constructor, automatically generated equals, hashCode, and toString, and accessor methods. Sealed classes restrict which classes can extend them — useful for algebraic data types. Pattern matching in switch is the synthesis: switch(shape) { case Circle c -> ...; case Rectangle r -> ... }.
Virtual threads (Java 21 / Project Loom): lightweight threads managed by the JVM runtime, not the OS. You can spin up millions without the overhead of platform threads. They block cheaply. The assessment will ask in which scenario virtual threads provide the most benefit — the answer is I/O-bound workloads with high concurrency, not CPU-bound work.
Three-day prep plan
Day one: run the practice assessment. Note the concurrency questions you got wrong. Review happens-before and volatile.
Day two: implement a merge sort using CompletableFuture — the recursive case splits work into two futures and joins them. This exercise covers thenCompose, supplyAsync, and exception handling.
Day three: write a Stream pipeline that reads a list of transactions, groups by merchant, sums the amount per merchant, and returns the top 5 by total. This is a common assessment pattern.
Ready when you are
Take the Java assessment
Sixty minutes. One credential. Free tier — no card required.
Last updated 2026-05-01.