Java & OOP Fundamentals
Re-sharpen the Java details that separate routine OOP from robust systems: equality contracts, generics, concurrency, collections, and JVM behavior.
72 concepts442 live tasks
Start practicing freeWhat's inside
Objects, Identity & Encapsulation
Identity and equality are different contracts
Encapsulation protects invariants, not fields
final freezes the reference, not the object
Records model transparent values
Optional is a boundary signal, not a field type
Sealed classes make a hierarchy closed on purpose
Enums are singleton classes with behavior
Value-based classes ask you to ignore identity
Inheritance, Polymorphism & Design
Inheritance is a substitutability promise
Composition gives behavior without exposing ancestry
Instance method calls dispatch on runtime type
Overloading is compile-time; overriding is runtime
Interfaces define capability; abstract classes share state
Default methods compose until two interfaces disagree
equals() and hashCode() are one contract
Narrow interfaces keep implementations replaceable
Collections & Generics
List, Set, and Map promise different questions
HashMap starts with hashCode() and finishes with equals()
Sorted collections trust the comparator as equality
Fail-fast iterators catch bugs, not races
List<String> is not a List<Object>
Type erasure removes most generic types at runtime
PECS: producers extend, consumers super
Raw types turn generic errors into runtime failures
Exceptions & Resource Boundaries
Checked exceptions are part of the call contract
finally runs during stack unwinding, even through returns
try-with-resources preserves cleanup failures as suppressed
Translate exceptions at architectural boundaries
Exceptions are too expensive and vague for normal branches
InterruptedException is a cancellation request
Log or throw at one layer, not every layer
Error usually means the process is unhealthy
Streams, Lambdas & Functional Style
Lambdas capture effectively final variables
A lambda's type comes from its target
Stream pipelines are lazy until a terminal operation
Terminal operations consume the stream
Parallel streams need splittable work and clean side effects
Collectors encode mutable reduction safely
Optional chains are for simple absence flow
Side effects make stream order and parallelism matter
Concurrency & Memory Model
happens-before is the visibility contract
volatile gives visibility, not compound atomicity
synchronized is both a lock and a memory barrier
Atomic classes use compare-and-set loops
ExecutorService separates task submission from threads
CompletableFuture chains work; executor choice decides where
Concurrent collections trade snapshots for progress
Virtual threads make blocking cheap, not state safe
JVM Runtime & Performance
References live in variables; objects live where the JVM decides
Class loading and initialization are separate moments
The JIT optimizes hot code after observing it
Most collectors exploit the generational hypothesis
Escape analysis can make allocation disappear
Autoboxing hides allocation and identity traps
String literals are pooled; runtime strings are not magically identical
JMH exists because JVM benchmarking is easy to fake
IO, Time & Boundary APIs
InputStream reads bytes; Reader reads characters
Path models filesystem names better than String
Java serialization bypasses normal construction
DTOs keep wire shape separate from domain shape
Instant, LocalDate, and ZonedDateTime answer different questions
BigDecimal value includes scale in equals()
ServiceLoader discovers implementations through interfaces
Defensive copies stop callers from mutating your internals
Modern Java & Architecture Boundaries
Modules make dependencies and exported packages explicit
Annotations are metadata until something reads them
Dependency injection should reveal boundaries, not hide them
Domain code should not know how it is stored or delivered
An anemic model stores data while services hold all behavior
Builders are for construction complexity, not optional validation
Pattern matching switch pays off with closed hierarchies
Preview features are for feedback, not casual production dependencies

