0% found this document useful (0 votes)
2 views6 pages

Java Book

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views6 pages

Java Book

Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

novasistek.

com
Mastering Java: From Syntax to
Scalability
Table of Contents
●​ Chapter 1: The Java Virtual Machine & Memory Model
●​ Chapter 2: Object-Oriented Integrity & Modern Types
●​ Chapter 3: The Functional Paradigm in Java
●​ Chapter 4: Concurrency & The Virtual Thread Revolution
Chapter 1: The Java Virtual Machine & Memory Model
To write high-performance Java, you must understand that you are not writing code for the
hardware; you are writing code for the Java Virtual Machine (JVM).
The Runtime Data Areas

When a Java application runs, the JVM allocates memory into specific regions. Understanding
the distinction between the Stack and the Heap is fundamental to managing performance and
avoiding OutOfMemoryError exceptions.

+-------------------------------------------------------------------+​
| JVM Memory Layout |​
+-------------------------------------------------------------------+​
| [ Thread Stack 1 ] [ Thread Stack 2 ] [ Metaspace ] |​
| - Local variables - Local variables - Class metadata |​
| - Primitive types - Primitive types - Method structures |​
| - Object references - Object references |​
+-------------------------------------------------------------------+​
| |​
| [ Heap Memory ] |​
| - All objects survive here |​
| - Shared across all threads |​
| |​
+-------------------------------------------------------------------+​

●​ The Stack: Each thread has its own private stack. It stores primitive local variables and
references to objects stored in the heap. Memory allocation here is incredibly fast and
adheres to a Strict LIFO (Last-In, First-Out) structure.
●​ The Heap: A common memory pool shared by all threads. This is where all Java objects
reside. Managing this space is the job of the Garbage Collector (GC).
Reference Types and Behavior

Java passes everything by value. However, when passing an object, the "value" is the memory
address pointer to the heap.

Java
public class MemoryDemo {​
public static void main(String[] args) {​
int primitiveAge = 25; // Stored directly on the Stack​
User user = new User("Alex"); // 'user' reference on Stack, Object on Heap​

modify(primitiveAge, user);​

[Link](primitiveAge); // Prints 25 (unchanged)​
[Link]([Link]()); // Prints "Sophia" (mutated via reference)​
}​

private static void modify(int age, User u) {​
age = 30; ​
[Link]("Sophia"); ​
}​
}​

Chapter 2: Object-Oriented Integrity & Modern Types


Java has evolved beyond verbose boilerplates. Modern Java provides powerful constructs to
enforce domain modeling constraints cleanly.
Encapsulation with Records

Introduced to eliminate the endless scroll of getters, setters, equals(), hashCode(), and
toString(), a Record is an immutable data carrier.
Java
// A complete, immutable data class in one line​
public record Point(int x, int y) {​
// Optional: Compact constructor for validation​
public Point {​
if (x < 0 || y < 0) {​
throw new IllegalArgumentException("Coordinates cannot be negative");​
}​
}​
}​

Algebraic Data Types with Sealed Classes

Historically, Java inheritance was wide open unless marked final. Sealed classes allow you to
restrict exactly which classes or interfaces can extend or implement them, enabling predictable
domain design.

Java
public sealed interface PaymentMethod ​
permits CreditCard, PayPal, Crypto {}​

public final class CreditCard implements PaymentMethod { String cardNumber; }​
public final class PayPal implements PaymentMethod { String email; }​
public final class Crypto implements PaymentMethod { String walletAddress; }​

By sealing the interface, you can leverage exhaustive Pattern Matching in modern switch
expressions:
Java
public String getPaymentDetails(PaymentMethod method) {​
return switch (method) {​
case CreditCard cc -> "Card ending in: " + [Link](12);​
case PayPal pp -> "PayPal account: " + [Link];​
case Crypto crypto -> "Crypto wallet: " + [Link];​
// No default block needed! The compiler knows all subtypes are covered.​
};​
}​

Chapter 3: The Functional Paradigm in Java


Java integrated functional programming paradigms via Lambda Expressions and the Streams
API. This shifted code bases from imperative (how to do something) to declarative (what to
achieve).
Stream Pipelines

A stream pipeline consists of a source, zero or more intermediate operations (lazy evaluation),
and a terminal operation (eager evaluation).

Java
import [Link];​

public class StreamProcessor {​
public static void main(String[] args) {​
List<String> names = [Link]("anna", "bob", "alexander", "brian", "charlie");​

List<String> processedNames = [Link]()​
.filter(name -> [Link]("b")) // Intermediate operation​
.map(String::toUpperCase) // Intermediate operation​
.sorted() // Intermediate operation​
.toList(); // Terminal operation​

[Link](processedNames); // [BOB, BRIAN]​
}​
}​

Warning on Streams: Do not modify external state within a stream pipeline (side effects).
Streams are designed for pure transformations. If your mapping logic mutates data outside the
pipeline, it breaks thread safety and readability.
Chapter 4: Concurrency & The Virtual Thread
Revolution
For decades, Java threads ([Link]) were direct wrappers around operating system
(OS) kernel threads. This model crashed when hitting massive scale because OS threads are
memory-expensive (~1MB each) and context switching between them kills CPU cycles.
Project Loom & Virtual Threads

Modern Java introduces Virtual Threads. They are lightweight threads managed by the JVM
runtime, not the OS. They share a small pool of carrier OS threads.
When a virtual thread performs a blocking I/O operation (like waiting for a database response),
the JVM automatically unmounts it from the OS carrier thread, letting other virtual threads run.

[Traditional Thread-per-Request Model]​


Request 1 ----> [ OS Thread A (1MB) ] (Blocked on DB)​
Request 2 ----> [ OS Thread B (1MB) ] (Blocked on I/O) -> Hard Limit around ~5,000
threads​

[Modern Virtual Thread Model]​
Virtual Thread 1 (Few KB) --\​
Virtual Thread 2 (Few KB) ----> [ JVM Scheduler ] ===> [ Carrier OS Thread 1 ]​
Virtual Thread 3 (Few KB) --/​

Implementing Virtual Threads

You can instantly spin up millions of virtual threads without running out of memory.

Java
import [Link];​
import [Link];​
import [Link];​
import [Link];​
import [Link];​
import [Link];​

public class VirtualThreadServer {​
public static void main(String[] args) {​
// Creates an ExecutorService that starts a new virtual thread for each task​
try (var executor = [Link]()) {​

for (int i = 0; i < 10_000; i++) {​
[Link](() -> {​
return fetchRemoteData();​
});​
}​

} // Executor automatically closes, waiting for all virtual tasks to finish​
}​

private static String fetchRemoteData() {​
try {​
var client = [Link]();​
var request = [Link]()​
.uri([Link]("[Link]
.build();​
return [Link](request, [Link]()).body();​
} catch (Exception e) {​
return "Fallback Data";​
}​
}​
}​

By utilizing virtual threads, your blocking microservice architectures achieve the same structural
simplicity as synchronous code while outputting the massive throughput of reactive,
asynchronous engines.

You might also like