Day 15 — #100DaysJava three things in one day. Collections, DSA, and JUnit revision. ☕ Some days you just lock in. ----------------------------- Thing 1 — Collections detail I never knew I always used ArrayList without thinking. Today I learned there are actually three different ways to create a list in Java and they behave completely differently. Arrays.asList() — fixed size. You can update values but you cannot add or remove. Most people think it works like ArrayList. It does not. List.of() — completely immutable. Nothing can change. Not even the values. And it does not allow null. This is the safest option when you want data that should never change. ArrayList — fully dynamic. Add, remove, update — everything works. This is what you use when the data needs to change. One line to remember: Arrays.asList = fixed, List.of = immutable, ArrayList = flexible. Small difference. Huge impact in interviews and real code. --- Thing 2 — Queue in Java (DSA) Queue follows FIFO — First In, First Out. Like a line at a ticket counter. First person in line gets served first. Three ways to use Queue in Java: LinkedList — simple, most common PriorityQueue — automatically sorts elements, smallest comes out first ArrayDeque — fastest, preferred in interviews The method pairs every Java developer should know: offer() vs add() — offer is safe, add throws exception if it fails poll() vs remove() — poll returns null if empty, remove throws exception peek() vs element() — peek returns null if empty, element throws exception Always use the safe version — offer, poll, peek. Problems I practiced: Reverse a queue using a stack Generate binary numbers using a queue Implement queue using two stacks --- Thing 3 — JUnit 5 revision Went back through everything from Day 13 and 14. Rewrote test cases for Calculator and String utilities from scratch without looking at notes. The AAA pattern is now muscle memory — Arrange, Act, Assert. Also revised edge cases — null inputs, empty strings, boundary values. This is where real bugs hide. --- 15 days in. The concepts are connecting now. DSA problems feel less scary when you understand the data structures behind them. If you are learning Java — save this post. Arrays.asList vs List.of vs ArrayList comes up in almost every Java interview. 📌 Day 1 ........................................Day 15 ✅ What DSA topic do you find hardest to crack in interviews? Drop it below — let us discuss! 🙏 #Java #DSA #DataStructures #Queue #Collections #JUnit #100DaysOfJava #JavaDeveloper #LearningInPublic #BackendDevelopment #100DaysOfCode #InterviewPrep #CodingInterview
Java Collections, DSA, and JUnit Revision
More Relevant Posts
-
🛡️ Shipped a major upgrade to AI-MR-Reviewer — a GitHub App that reviews your Java pull requests the moment you open them. Inline comments on the diff. Three severity levels. Zero configuration. Built for teams who want fast feedback without setting up SonarQube. What lands in this release: 19 hand-tuned Java rules. 🔴 HIGH RISK — 9 rules - Empty catch blocks (silent exception swallowing) - printStackTrace() in production code - Broad catches — Exception / Throwable / RuntimeException - SQL injection in createQuery / prepareStatement (concat + String.format) - Hardcoded credentials (password / apiKey / authToken) - Thread.sleep() in non-test code - Resource leaks — FileReader / Socket without try-with-resources - String compared with == instead of .equals() - Raw generics — new ArrayList() without the diamond operator 🟡 MID RISK — 5 rules - System.out / System.err in production - Magic strings in local assignments - PascalCase class / interface / enum naming - Methods with more than 5 parameters (god-method signal) - new Date() — prefer java.time (Instant, LocalDateTime) 🔵 LOW RISK — 5 rules - Numbered method names (toResponse2, handler3) - Wildcard imports (import java.util.*) - Missing Javadoc on public API surfaces (Service / Controller / Facade) - Unresolved TODO / FIXME / HACK comments - Files left behind as "ClassName copy.java" Every rule is tuned for a low false-positive rate. JPA/Spring annotation attributes are whitelisted, so @Table(name = "user") will never show up as a "magic string". Common numeric suffixes — sha256, base64, int32, ipv4 — are excluded from the numbered-method rule. Under the hood: TypeScript · Node.js · Octokit · Express · Docker. Deployed on Hostinger. Reviews land within seconds of opening the PR. Next up: the same treatment for Python and PHP, plus a semantic layer on top of the regex foundation — equals()/hashCode() pairing, Optional misuse detection, and blocking calls inside reactive chains. If your team reviews Java PRs every day, this saves an hour per dev per week. DMs open. #Java #SpringBoot #CodeReview #DeveloperTools #StaticAnalysis #OpenSource #DevEx
To view or add a comment, sign in
-
-
I spent my first 2 years writing Java the hard way. Verbose. Fragile. Full of boilerplate I didn't need. Then I discovered these 5 features — and I've never looked back. If you're a Java developer, save this post. 🔖 --- 1. Optional — stop pretending null doesn't exist How many NullPointerExceptions have you chased at midnight? I lost count. Then I started using Optional properly. Before: String city = user.getAddress().getCity(); // NPE waiting to happen After: Optional.ofNullable(user) .map(User::getAddress) .map(Address::getCity) .orElse("Unknown"); Clean. Safe. Readable. No more defensive if-null pyramids. --- 2. Stream API — ditch the for-loops I used to write 15-line loops to filter and transform lists. Streams cut that to 2 lines — and made the intent crystal clear. Before: List<String> result = new ArrayList<>(); for (User u : users) { if (u.isActive()) result.add(u.getName()); } After: List<String> result = users.stream() .filter(User::isActive) .map(User::getName) .collect(toList()); Once you think in streams, you can't go back. --- 3. Records — goodbye boilerplate data classes How many times have you written a POJO with getters, setters, equals, hashCode, and toString? Java Records (Java 16+) killed all of that in one line. Before (~50 lines): public class User { private String name; private String email; // getters, setters, equals, hashCode, toString... 😩 } After (1 line): public record User(String name, String email) {} Your DTOs and value objects will thank you. --- 4. var — let the compiler do the obvious work I was skeptical at first. Felt "un-Java-like." But for local variables, var makes code dramatically less noisy. Before: HashMap<String, List<Order>> map = new HashMap<String, List<Order>>(); After: var map = new HashMap<String, List<Order>>(); Still strongly typed. Just less noise. Use it for local scope — not method signatures. --- 5. CompletableFuture — async without the headache Threading used to terrify me. CompletableFuture changed that. Chain async tasks, handle errors, combine results — all without callback hell. CompletableFuture.supplyAsync(() -> fetchUser(id)) .thenApply(user -> enrichWithOrders(user)) .thenAccept(result -> sendResponse(result)) .exceptionally(ex -> handleError(ex)); Readable async Java. Yes, it's possible. --- I wasted months writing verbose, fragile code because nobody told me these existed. Now you have no excuse. 😄 Which of these changed your code the most? Drop a number (1–5) in the comments 👇 — I read every one. #Java #SoftwareEngineering #FullStackDeveloper #CleanCode #SpringBoot #CodingTips
To view or add a comment, sign in
-
How the JVM Actually Runs Your Java Code After years of building Java services, one thing I’ve noticed is that most developers interact with the JVM every day, but rarely think about what actually happens between compiling code and running it in production. Behind the scenes, the JVM goes through several stages to safely and efficiently execute Java applications. Here’s the simplified flow 👇 1️⃣ Build The Java compiler (javac) converts .java source files into platform-independent bytecode stored in: • .class files • JAR archives • Java modules This layer is what allows Java applications to run on any platform with a JVM. 2️⃣ Load The Class Loader Subsystem dynamically loads classes when needed using the parent delegation model: • Bootstrap Class Loader → loads core JDK classes • Platform Class Loader → loads platform libraries • System Class Loader → loads application classes This mechanism improves security and prevents duplicate class loading. 3️⃣ Link Before execution, the JVM links the class through three steps: • Verify → ensures bytecode safety • Prepare → allocates memory for static variables • Resolve → converts symbolic references to direct memory references 4️⃣ Initialize The JVM assigns values to static variables and executes static initializer blocks. This step occurs only once when the class is first used. 5️⃣ Runtime Memory Areas Shared across threads: • Heap → object storage • Method Area → class metadata • Runtime Constant Pool Per thread: • JVM Stack → method frames & local variables • Program Counter (PC) → execution pointer • Native Method Stack The Garbage Collector continuously reclaims unused heap memory. 6️⃣ Execution Engine The JVM executes code using two mechanisms: • Interpreter → executes bytecode directly • JIT Compiler → compiles frequently used methods into optimized machine code Compiled code is stored in the Code Cache, improving performance over time. 7️⃣ Native Integration When Java needs system-level access, it uses JNI (Java Native Interface) to call C/C++ native libraries. 💡 What makes the JVM powerful is its hybrid execution model: • platform-independent bytecode • managed memory with garbage collection • secure class loading • runtime optimization with JIT This is why Java continues to power many large-scale backend systems. 🔍 Production insight If you’ve ever seen: • slow startup times • GC pauses • class loading conflicts • performance improving after warm-up those behaviors are directly tied to how the JVM executes and optimizes code at runtime. Understanding these internals makes debugging and performance tuning far easier. #Java #JVM #JavaDeveloper #BackendEngineering #SoftwareArchitecture #SystemDesign #PerformanceEngineering #DistributedSystems #JavaInternals
To view or add a comment, sign in
-
-
How the JVM Actually Runs Your Java Code After years of building Java services, one thing I’ve noticed is that most developers interact with the JVM every day, but rarely think about what actually happens between compiling code and running it in production. Behind the scenes, the JVM goes through several stages to safely and efficiently execute Java applications. Here’s the simplified flow 👇 1️⃣ Build The Java compiler (javac) converts .java source files into platform-independent bytecode stored in: • .class files • JAR archives • Java modules This layer is what allows Java applications to run on any platform with a JVM. 2️⃣ Load The Class Loader Subsystem dynamically loads classes when needed using the parent delegation model: • Bootstrap Class Loader → loads core JDK classes • Platform Class Loader → loads platform libraries • System Class Loader → loads application classes This mechanism improves security and prevents duplicate class loading. 3️⃣ Link Before execution, the JVM links the class through three steps: • Verify → ensures bytecode safety • Prepare → allocates memory for static variables • Resolve → converts symbolic references to direct memory references 4️⃣ Initialize The JVM assigns values to static variables and executes static initializer blocks. This step occurs only once when the class is first used. 5️⃣ Runtime Memory Areas Shared across threads: • Heap → object storage • Method Area → class metadata • Runtime Constant Pool Per thread: • JVM Stack → method frames & local variables • Program Counter (PC) → execution pointer • Native Method Stack The Garbage Collector continuously reclaims unused heap memory. 6️⃣ Execution Engine The JVM executes code using two mechanisms: • Interpreter → executes bytecode directly • JIT Compiler → compiles frequently used methods into optimized machine code Compiled code is stored in the Code Cache, improving performance over time. 7️⃣ Native Integration When Java needs system-level access, it uses JNI (Java Native Interface) to call C/C++ native libraries. 💡 What makes the JVM powerful is its hybrid execution model: • platform-independent bytecode • managed memory with garbage collection • secure class loading • runtime optimization with JIT This is why Java continues to power many large-scale backend systems. 🔍 Production insight If you’ve ever seen: • slow startup times • GC pauses • class loading conflicts • performance improving after warm-up those behaviors are directly tied to how the JVM executes and optimizes code at runtime. Understanding these internals makes debugging and performance tuning far easier. #Java #JVM #JavaDeveloper #BackendEngineering #SoftwareArchitecture #SystemDesign #PerformanceEngineering #DistributedSystems #JavaInternals
To view or add a comment, sign in
-
-
𝐈𝐬 𝐄𝐯𝐞𝐫𝐲𝐭𝐡𝐢𝐧𝐠 𝐚 𝐎𝐛𝐣𝐞𝐜𝐭 𝐈𝐧 𝐉𝐚𝐯𝐚? In Java, we often hear that "everything is an object"—but that’s not entirely true. We still rely on 𝐩𝐫𝐢𝐦𝐢𝐭𝐢𝐯𝐞 𝐝𝐚𝐭𝐚 𝐭𝐲𝐩𝐞𝐬 (like int, char, and boolean) for performance and simplicity. However, there are moments when these primitives aren't enough. That is where 𝐖𝐫𝐚𝐩𝐩𝐞𝐫 𝐂𝐥𝐚𝐬𝐬𝐞𝐬 come into play. 𝐖𝐡𝐚𝐭 𝐢𝐬 𝐚 𝐖𝐫𝐚𝐩𝐩𝐞𝐫 𝐂𝐥𝐚𝐬𝐬? A Wrapper class is exactly what it sounds like: a class that "wraps" or encapsulates a primitive data type into an object. This allows you to treat a simple value as a full-fledged object. 𝐖𝐡𝐲 𝐝𝐨 𝐰𝐞 𝐧𝐞𝐞𝐝 𝐭𝐡𝐞𝐦? You might wonder, "Why go through the extra effort of creating an object?" Here are the primary reasons: •𝐂𝐨𝐥𝐥𝐞𝐜𝐭𝐢𝐨𝐧𝐬 & 𝐆𝐞𝐧𝐞𝐫𝐢𝐜𝐬: Java Collections (like ArrayList or HashMap) cannot store primitives. You can’t have an ArrayList<int>, but you can have an ArrayList<Integer>. •𝐍𝐮𝐥𝐥 𝐕𝐚𝐥𝐮𝐞𝐬: Primitives must have a value (e.g., 0 for int). Wrapper objects can be null, which is essential for representing "no data" in databases or APIs. •𝐔𝐭𝐢𝐥𝐢𝐭𝐲 𝐌𝐞𝐭𝐡𝐨𝐝𝐬: Wrapper classes provide helpful tools. For example, Integer.parseInt("123") or Character.isDigit('5'). 𝐓𝐡𝐞 𝐌𝐚𝐠𝐢𝐜 𝐨𝐟 𝐀𝐮𝐭𝐨𝐛𝐨𝐱𝐢𝐧𝐠 𝐚𝐧𝐝 𝐔𝐧𝐛𝐨𝐱𝐢𝐧𝐠 Java makes the transition between primitives and objects seamless through two features: 𝟏. 𝐀𝐮𝐭𝐨𝐛𝐨𝐱𝐢𝐧𝐠 This is the automatic conversion of a primitive to its corresponding wrapper class. 𝐄𝐱𝐚𝐦𝐩𝐥𝐞: Java int b = 357; Integer a = b; // 𝐀𝐮𝐭𝐨𝐦𝐚𝐭𝐢𝐜𝐚𝐥𝐥𝐲 𝐜𝐨𝐧𝐯𝐞𝐫𝐭𝐬 𝐢𝐧𝐭 -> 𝐈𝐧𝐭𝐞𝐠𝐞𝐫 𝟐. 𝐔𝐧𝐛𝐨𝐱𝐢𝐧𝐠 The reverse process: automatically converting a wrapper object back into a primitive. 𝗘𝘅𝗮𝗺𝗽𝗹𝗲: Java Integer objectNum = 24; int primitiveNum = objectNum; // 𝐀𝐮𝐭𝐨𝐦𝐚𝐭𝐢𝐜𝐚𝐥𝐥𝐲 𝐜𝐨𝐧𝐯𝐞𝐫𝐭𝐬 𝐈𝐧𝐭𝐞𝐠𝐞𝐫 -> 𝐢𝐧𝐭 𝐅𝐢𝐧𝐚𝐥 𝐓𝐚𝐤𝐞𝐚𝐰𝐚𝐲 Wrapper classes are the "bridge" between the performance of procedural programming (primitives) and the power of Object-Oriented Programming (objects). Understanding when to use them is key to mastering Java's memory management and collection framework. A special Thank You to Syed Zabi Ulla Sir for beautifully explaining this core Java concept and making the logic so clear. #Java #Programming #CodingTips #BackendDevelopment #SoftwareEngineering #WrapperClasses #ObjectOrientedProgramming
To view or add a comment, sign in
-
Stop writing Java Switch statements like it’s 2004! If you are still writing switch statements with break; at the end of every line, you are living in the past! Java has transformed the humble switch from a clunky branching tool into a powerful, functional expression. Here is the evolution of how we control logic in Java: 1️⃣ The "Classic" Era (Java 1.0 - 6) * Syntax: case X: ... break; * Limitation: Only primitives (int, char) and Enums. * The Risk: "Fall-through" bugs. Forget one break and your logic cascades into chaos. 2️⃣ The "Modern Expression" (Java 14) Java 14 turned the Switch into an Expression. It can now return a value! * Arrow Syntax (->): No more break. It’s cleaner and safer. * Assignment: var result = switch(val) { ... }; * Yield: Use yield to return values from complex multi-line blocks. 3️⃣ The "Pattern Matching" Powerhouse (Java 21) This is the game changer. Switch is no longer just for values; it’s for Types. * Case Patterns: Switch directly on an Object. * Automatic Casting: No more instanceof followed by manual casting. * Guarded Patterns: Use the when keyword to add logic filters directly into the case. * Null Safety: Explicitly handle case null without crashing. Sample : /** * SCENARIO: Processing a result object that could be * a String, an Integer, or a custom Status record. */ // 🛑 THE OLD WAY (Java 8) - Verbose and manual public String handleResultOld(Object result) { if (result == null) { return "Unknown"; } if (result instanceof String) { String s = (String) result; // Manual casting return "Message: " + s; } else if (result instanceof Integer) { Integer i = (Integer) result; return "Code: " + i; } return "Unsupported"; } // ✅ THE MODERN WAY (Java 21) - Concise and Type-Safe public String handleResultModern(Object result) { return switch (result) { case null -> "Unknown"; case String s when s.isBlank() -> "Empty Message"; case String s -> "Message: " + s; // Automatic casting case Integer i -> "Code: " + i; default -> "Unsupported"; }; } #Java21 #ModernJava #BackendDevelopment #Coding #TechCommunity #Developers #LearningToCode
To view or add a comment, sign in
-
Mastering Java Streams: What’s Actually Happening Under the Hood? Ever wondered why Java Streams are called "Lazy"? Or why adding more intermediate operations doesn't necessarily slow down your code? The secret lies in the Internal Flow. Unlike traditional Collections, Streams don't process data step-by-step for the entire list. Instead, they use a Single-Pass Execution model. 🏗️ The 3 Stages of a Stream The Source: Where the data comes from (Lists, Sets, Arrays). Intermediate Operations: These are Lazy. Operations like .filter() or .map() don’t execute immediately. They just build a "recipe" or a pipeline of instructions. Terminal Operations: This is the Trigger. Operations like .collect(), .findFirst(), or .forEach() start the engine. Without this, nothing happens. 🧠 The "Pull" Mechanism Java Streams don't "push" every element through the entire pipeline one by one. Instead, the Terminal Operation "pulls" data from the source through the pipeline. Imagine a factory line: instead of moving every item to the next station, the worker at the very end of the line asks for one finished product. This triggers the previous stations to work only as much as needed to produce that one item. 💻 Code in Action: Lazy Evaluation & Short-Circuiting Check out this example. Even though we have a list of 1,000 items, the stream only processes what it needs. List<String> names = Arrays.asList("Java", "Spring", "Hibernate", "Microservices", "Docker"); String result = names.stream() .filter(s -> { System.out.println("Filtering: " + s); return s.length() > 4; }) .map(s -> { System.out.println("Mapping: " + s); return s.toUpperCase(); }) .findFirst() // Terminal Operation .get(); System.out.println("Result: " + result); What happens here? It checks "Java" (fails filter). It checks "Spring" (passes filter). It immediately maps "Spring" to "SPRING". findFirst() is satisfied, so it stops. It never even looks at "Hibernate" or "Docker"! 💡 Why does this matter for your LinkedIn reach? (and your code) Performance: Drastically reduces unnecessary computations. Memory Efficiency: Processes elements in a single pass rather than creating intermediate data structures. Readability: Clean, declarative code that describes what to do, not how to do it. Which do you prefer? The classic for-loop or the Stream API? Let's discuss in the comments! 👇 #Java #Programming #SoftwareDevelopment #Backend #JavaStreams #CleanCode #TechTips
To view or add a comment, sign in
-
-
𝐉𝐚𝐯𝐚 𝟏𝟑: 𝐌𝐚𝐤𝐢𝐧𝐠 𝐭𝐡𝐞 𝐒𝐰𝐢𝐭𝐜𝐡 𝐒𝐭𝐚𝐭𝐞𝐦𝐞𝐧𝐭 𝐁𝐞𝐭𝐭𝐞𝐫! If you've ever spent hours debugging a logic error only to find you missed a single break; statement, you know the pain of the traditional Java switch. Java 12 and 13 introduced major upgrades to fix these "legacy" headaches. Here is a quick breakdown of how the Enhanced Switch makes your code cleaner and safer: 𝟏. 𝐍𝐨 𝐌𝐨𝐫𝐞 "𝐅𝐚𝐥𝐥-𝐓𝐡𝐫𝐨𝐮𝐠𝐡" 𝐓𝐫𝐚𝐩𝐬 Traditional switches require a break for every case. If you forget it, the code "falls through" to the next case. The Fix: Using the new arrow (->) syntax. It executes only the code on the right side. No break required! 𝟐. 𝐒𝐰𝐢𝐭𝐜𝐡 𝐚𝐬 𝐚𝐧 𝐄𝐱𝐩𝐫𝐞𝐬𝐬𝐢𝐨𝐧 You can now assign the result of a switch directly to a variable. This makes your code much more concise. Example: 𝐉𝐚𝐯𝐚 String device = switch (itemCode) { case 001 -> "Laptop"; case 002 -> "Desktop"; default -> "Unknown"; }; System.out.println("Output: " + device); 𝐎𝐮𝐭𝐩𝐮𝐭: Output: Laptop 𝟑. 𝐌𝐮𝐥𝐭𝐢𝐩𝐥𝐞 𝐕𝐚𝐥𝐮𝐞𝐬, 𝐎𝐧𝐞 𝐂𝐚𝐬𝐞 Gone are the days of stacking cases on top of each other. You can now comma-separate multiple values in a single line: case 001, 002, 003 -> System.out.println("Electronic Gadget"); 𝟒. 𝐓𝐡𝐞 𝐲𝐢𝐞𝐥𝐝 𝐊𝐞𝐲𝐰𝐨𝐫𝐝 In Java 13, if you are using the traditional colon syntax (:) but want to return a value from a switch expression, use yield. It returns the value and exits the switch immediately. 𝟓. 𝐄𝐱𝐡𝐚𝐮𝐬𝐭𝐢𝐯𝐞𝐧𝐞𝐬𝐬 (𝐒𝐚𝐟𝐞𝐭𝐲 𝐅𝐢𝐫𝐬𝐭!) When using switch as an expression, Java forces you to cover every possible case (or provide a default). This prevents those pesky "unhandled value" bugs from reaching production. 𝟔. 𝐌𝐨𝐝𝐞𝐫𝐧 𝐋𝐨𝐠𝐢𝐜 𝐰𝐢𝐭𝐡 𝐭𝐡𝐞 𝐰𝐡𝐞𝐧 𝐊𝐞𝐲𝐰𝐨𝐫𝐝 (𝐉𝐚𝐯𝐚 𝟐𝟏+) Introduced in Java 21, the when keyword acts as a Guard. It allows you to add extra boolean conditions directly to a case label. No more nesting if statements inside your cases! Example: 𝐉𝐚𝐯𝐚 switch (obj) { case String s when s.length() > 5 -> System.out.println("Long string: " + s); case String s -> System.out.println("Short string"); default -> System.out.println("Not a string"); } Deeply grateful to Syed Zabi Ulla Sir for his expert guidance. He has a gift for making even the trickiest Java updates feel intuitive. Thank you, sir, for helping us build such a strong technical base and for always being a guiding light in our learning journey! #Java #Programming #CodingTips #SoftwareDevelopment #Java21 #CleanCode #BackendDeveloper #Mentorship #PWIOI #LearningJourney
To view or add a comment, sign in
-
-
𝗜'𝘃𝗲 𝗯𝗲𝗲𝗻 𝘄𝗿𝗶𝘁𝗶𝗻𝗴 𝗝𝗮𝘃𝗮 𝗳𝗼𝗿 𝗮 𝘄𝗵𝗶𝗹𝗲 𝗻𝗼𝘄 — 𝗮𝗻𝗱 𝗜 𝘀𝘁𝗶𝗹𝗹 𝗰𝗼𝗺𝗲 𝗮𝗰𝗿𝗼𝘀𝘀 𝗸𝗲𝘆𝘄𝗼𝗿𝗱𝘀 𝗜 𝗻𝗲𝘃𝗲𝗿 𝗳𝘂𝗹𝗹𝘆 𝘂𝗻𝗱𝗲𝗿𝘀𝘁𝗼𝗼𝗱. Turns out Java has 67 reserved keywords. Most of us use ~20 in our daily code. Here's what the rest actually do. 𝗖𝗮𝘁𝗲𝗴𝗼𝗿𝘆 𝟭 — Data Types (11) byte · short · int · long · float · double · char · boolean · void · var · enum var (Java 10) enables local type inference. enum values are full objects under the hood — not just constants. 𝗖𝗮𝘁𝗲𝗴𝗼𝗿𝘆 𝟮 — Control Flow (13) if · else · switch · case · default · yield · for · while · do · break · continue · return · when yield (Java 13) returns a value from a switch expression. when (Java 21) is a pattern matching guard — case Integer i when i > 0. 𝗖𝗮𝘁𝗲𝗴𝗼𝗿𝘆 𝟯 — Modifiers (10) public · protected · private · static · final · abstract · synchronized · transient · volatile · native volatile forces reads from main memory, not thread cache. transient skips fields during serialization. native calls JNI-based C/C++ code. 𝗖𝗮𝘁𝗲𝗴𝗼𝗿𝘆 𝟰 — Exception Handling (6) try · catch · finally · throw · throws · assert assert validates assumptions in dev. Enable with -ea JVM flag. Never use it for production logic. 𝗖𝗮𝘁𝗲𝗴𝗼𝗿𝘆 𝟱 — Class & Module (18) class · interface · extends · implements · package · import · sealed · non-sealed · permits · record · module · exports · requires · opens · uses · provides · with · to sealed (Java 17) restricts subclassing. record (Java 16) eliminates boilerplate — auto-generates constructors, getters, equals(), hashCode(). Module keywords power JPMS (Java 9). 𝗖𝗮𝘁𝗲𝗴𝗼𝗿𝘆 𝟲 — Object Reference (4) new · instanceof · super · this instanceof now supports pattern matching (Java 16) — no explicit cast needed. 𝗖𝗮𝘁𝗲𝗴𝗼𝗿𝘆 𝟳 — Literals (3) true · false · null null is not an object — it's the absence of a reference. Still a top cause of NullPointerException in production. 𝗖𝗮𝘁𝗲𝗴𝗼𝗿𝘆 𝟴 — Unused & Obsolete (4) goto · const · strictfp · _ Reserved but non-functional. strictfp is a no-op since Java 17. _ is illegal as an identifier from Java 21+. Java's keyword list grows every LTS release. yield, record, sealed, when — all added in the last few years. Not tracking Java releases = working with an incomplete language. A special thanks to Syed Zabi Ulla sir at PW Institute of Innovation for their clear explanations and continuous guidance throughout this topic. Which category is most underused in your day-to-day Java code? #Java #JavaDeveloper #CoreJava #Programming #SoftwareDevelopment #BackendDevelopment #LearnJava
To view or add a comment, sign in
-
☕ How Java Actually Works — from source code to running application. Most developers use Java daily without knowing this. After 10+ years of building enterprise Java systems, understanding what happens under the hood has made me a dramatically better engineer. Let me walk through every stage 👇 📝 Stage 1 — Source You write Java code in your editor — IntelliJ, VS Code, Eclipse. That code is saved as a .java source file. Human-readable. Platform-specific to nothing yet. This is where it all begins. ⚙️ Stage 2 — Compile The Java Compiler (javac) transforms your .java source file into Bytecode — a .class file. This is the magic of Java's "Write Once Run Anywhere" promise. The bytecode is not native machine code — it's an intermediate language that any JVM on any platform can understand. Windows, Linux, Mac — same bytecode runs everywhere. 📦 Stage 3 — Artifacts The compiled .class files are packaged into artifacts — JAR files, modules, or classpath entries. In enterprise projects I've shipped across Bank of America and United Health, Maven and Gradle manage this — producing versioned artifacts deployed to Nexus or AWS CodeArtifact repositories. 📂 Stage 4 — Load The Class Loader loads .class files, JARs, and modules into the Java Runtime Environment at runtime. Three built-in class loaders handle this — Bootstrap, Extension, and Application. Understanding class loading has helped me debug NoClassDefFoundError and ClassNotFoundException in production more times than I can count. 🔍 JVM — Verify Before executing a single instruction, the JVM Verifier checks the bytecode for correctness and security violations. No invalid memory access. No type violations. No corrupted bytecode. This is one reason Java is inherently safer than languages with direct memory management. ▶️ Stage 5 — Execute — Interpreter + JIT Compiler This is where performance gets interesting. The JVM first Interprets bytecode line by line — fast startup, moderate throughput. Simultaneously it monitors execution and identifies hot paths — code that runs frequently. Those hot paths are handed to the JIT (Just-In-Time) Compiler which compiles them to native machine code stored in the Code Cache. 🏃 Stage 6 — Run The JVM runs a mix of interpreted bytecode and JIT-compiled native code — balancing startup speed with peak performance. Standard Libraries (java.* / jdk.*) provide everything from collections to networking to I/O throughout execution. #Java #c2c #opentowork #c2h #JVM #CoreJava #JavaDeveloper #SpringBoot #JVMPerformance #FullStackDeveloper #OpenToWork #BackendDeveloper #Java17 #HiringNow #EnterpriseJava #SoftwareEngineer #JITCompiler #JavaInterview #CloudNative #Microservices #TechEducation #Programming
To view or add a comment, sign in
-
Explore related topics
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development