Saltar a contenido

Prelude - The Philosophy Behind the Syllabus

Sit with this document for an evening before week 1. The rest of the curriculum is mechanically dense; this is the only chapter where we step back and define the shape of the discipline.


1. Java Is a Platform, Not a Language

The most damaging misconception a Java engineer can hold is that "Java is just C++ with garbage collection." A working master-level practitioner thinks the inverse:

Java is a platform - a sophisticated bytecode VM with a tiered JIT, a concurrent garbage collector, a class-loading model with security boundaries, and a 30-year-old standard library - that ships with a deliberately conservative language attached.

Almost every interesting performance bug in production Java has its root in the JVM (JIT deoptimization, GC pause, classloader leak, allocation-rate spike, false-shared cache lines), not in the language semantics. Almost every elegant high-throughput Java architecture is a thin layer over JVM primitives: MethodHandle, VarHandle, ForkJoinPool, VirtualThread, MemorySegment, JFR.

Internalize this and the rest of the curriculum makes sense.


2. The Five-Axis Cost Model

A working Java engineer reasons about every line of code along five axes simultaneously:

Axis Question to ask
Allocation Does this allocate? On TLAB or outside? Can the JIT scalar-replace it via escape analysis?
JIT shape Will C2 inline this? Is the call site monomorphic, bimorphic, or megamorphic? Will a profile pollution force a deopt?
GC pressure How much live data does this add? Young-gen churn or tenured? Pointer-heavy or primitive-packed?
Concurrency safety Is this safely published? Visible across threads? Synchronized, volatile, VarHandle, or accidentally lock-free-and-wrong?
Failure What happens on InterruptedException? On OutOfMemoryError? On a classloader leak? On a StackOverflowError deep in a virtual thread?

Beginner courses teach axis 4 only (and incompletely, via synchronized). This curriculum forces all five into your hands by week 12.


3. The "Java Way" - Aesthetic as Engineering Constraint

Java's design ethic, post-Java-8, is "readable, refactorable, profileable." That phrase is doing more work than newcomers think. Specifically:

  • Composition over inheritance, finally. Sealed hierarchies + records + pattern matching deliver algebraic data types. Reach for extends only when truly modeling an "is-a" with shared state; reach for sealed interface + record for everything else.
  • Exceptions are control flow you reluctantly accept. Checked exceptions remain controversial; the modern stance is "checked exceptions for recoverable I/O at boundaries, runtime exceptions inside business logic, never throws Exception."
  • Concurrency by structure, not by threads. "Don't spawn threads; submit tasks; and prefer structured concurrency to free-floating CompletableFutures." Virtual threads (Loom) make this affordable.
  • The JDK is the framework - until it isn't. java.net.http, java.time, java.util.concurrent, java.lang.foreign, java.util.stream, System.Logger cover ~70% of any service. Spring/Quarkus exist because dependency injection, configuration, and HTTP routing are not in the JDK - not because the JDK is weak.
  • Tooling is part of the platform. javac, jcmd, jfr, jstack, jmap, JMH, async-profiler, jlink, jpackage, jdeps. A Java engineer who does not know these is half-trained.

If you fight these defaults, you will fight the platform. If you internalize them, you will write code that any other Java engineer can pick up in under a day, and you will know which knob to turn when a service goes sideways at 3 AM. That is the actual deliverable Java optimizes for.


4. The Reading List

These are referenced throughout the curriculum. They are pinned tabs, not pre-requisites.

Primary - Effective Java, 3rd ed. (Bloch). The canonical text. Re-read items 1–17 quarterly. - Java Concurrency in Practice (Goetz et al.). Pre-Loom but the JMM chapter is timeless. Pair with the JEPs on virtual threads (425, 444, 491) and structured concurrency (462/480/505). - Optimizing Java (Evans, Gough, Newland). The book on JIT, GC, and JFR for practitioners. - The Well-Grounded Java Developer, 2nd ed. (Evans, Verburg) - modern (post-17) idioms. - Java Language Specification (JLS) and Java Virtual Machine Specification (JVMS) - normative; read the chapters relevant to whatever bug is in front of you.

JVM & internals - The HotSpot source itself: src/hotspot/share/runtime/, src/hotspot/share/gc/, src/hotspot/share/opto/ (C2), src/hotspot/share/c1/ (C1). Treat as primary literature. - OpenJDK JEP archive (openjdk.org/jeps/). Read every JEP that ships in the LTS you target. JEPs are the design docs of the platform. - Aleksey Shipilëv's blog (shipilev.net) - the JMM, GC, microbenchmarking. JMH is his. - Cliff Click's A JVM Does That? talks; Gil Tene's Understanding Latency (the GC-pause-as-coordinated-omission talk). - The Garbage Collection Handbook (Jones, Hosking, Moss).

Distributed systems canon (not Java-specific, but mandatory) - Lamport, Time, Clocks, and the Ordering of Events. - Ongaro, In Search of an Understandable Consensus Algorithm (Raft). Read in week 21. - Brewer, CAP Twelve Years Later. - Kleppmann, Designing Data-Intensive Applications. Chapters 5–9 in the back half.

Adjacent canon - Drepper, What Every Programmer Should Know About Memory (re-read in week 9 for cache effects on object headers and false sharing). - Herlihy & Shavit, The Art of Multiprocessor Programming, chapters 7, 9, 13.


5. Curriculum Philosophy: "Read the JEP, Profile the Lab"

Three rules govern every module:

  1. JEP first, blog second. When the curriculum says "study virtual threads," it means read JEP 444 (final spec), then java.lang.VirtualThread source, then the blog post. Blogs go stale; JEPs are dated and tracked.
  2. One lab per concept, one artifact per phase. By the end of each month, the reader has produced one open-source-quality artifact (library, JMH benchmark suite, JFR analysis, or upstream OpenJDK contribution) - not a notebook of toy snippets.
  3. JFR and async-profiler are the teachers. When you do not understand why a program misbehaves, the first response is jcmd <pid> JFR.start, the second is async-profiler -e cpu,alloc, and only the third is to ask another human. System.out.println is not in the top three.

6. What Java Is Not For

A graduate of this curriculum should be able to argue these points in a design review without sounding ideological:

  • Cold-start-sensitive serverless. A JVM start is ~100ms+ minimum; a Spring Boot start is seconds. GraalVM native-image (or Leyden once stable) closes the gap but trades peak throughput and reflection ergonomics. If your p99 cold-start budget is <50ms, look at Go or Rust before fighting native-image.
  • Hard-real-time systems. Even ZGC's sub-millisecond pauses are not real-time guarantees. Audio DSP, motor control, kernel paths - wrong tool. Azul Zing pushes the envelope but is a commercial appliance.
  • Tiny CLIs. A 30MB java -jar for a tool that runs for 200ms is silly. jlink + jpackage help; native-image helps more; but if it's a one-shot tool, Go and Rust win on ergonomics.
  • Code where the team will demand pointer arithmetic. Panama (Foreign Memory API) gives controlled off-heap access, but it is not C. If your problem is "I need SIMD-tight numerical kernels and full control of layout," call into Rust via Panama or use the Vector API (still incubating) and accept the constraints.

The signal that Java is the right tool: you have a long-running-service, large-team, observability-rich, library-ecosystem-leveraging constraint, and the workload is throughput-shaped, not cold-start-shaped.


7. A Note on AI-Assisted Workflows

Modern Java authors use LLM tooling. Four rules:

  1. Never accept generated concurrent code without the JMM in mind. The most common failure mode of generated Java is plausible-looking but unsafe publication: a non-final field read across threads, a "double-checked locking" without volatile, an ArrayList mutated from a parallelStream. Read the JMM, then audit.
  2. Verify imports and JDK version. Models conflate Java 8, 11, 17, 21, and 25 freely. They will suggest Stream.toList() on Java 8, or var in an interface, or virtual threads on Java 17. Pin the target JDK in your prompt and verify.
  3. Watch for deprecated/removed APIs. Models still suggest new Date(), Vector, Hashtable, Thread.stop, SecurityManager, finalize(), sun.misc.Unsafe, raw types, and JNI when Panama is appropriate. APPENDIX_B_LEGACY_JAVA.md is the antidote.
  4. Treat generated exception handling skeptically. The most common Java anti-pattern in generated code is catch (Exception e) { e.printStackTrace(); }. Make a habit of replacing it with deliberate, narrow, logged handling at boundaries, and propagation everywhere else.

You are now ready for Week 1. Open 01_MONTH_LANGUAGE_AND_TOOLCHAIN.md.

Comments