Posts

Showing posts from March, 2026

JVM Memory Areas in Java (Heap, Stack, Metaspace)

Image
1. Introduction The JVM ( Java Virtual Machine) divides memory into different areas to efficiently manage program execution. The most important memory areas are: Heap Memory Stack Memory Metaspace (Method Area) Understanding these is very important for performance tuning, debugging, and interviews . 2. JVM Memory Structure Overview JVM Memory | |--- Heap |--- Stack |--- Metaspace 3. Heap Memory Explanation Heap is used to store objects and instance variables Shared among all threads Managed by Garbage Collector (GC) Key Features Stores all objects ( new keyword) Divided into: Young Generation Old Generation Slower access compared to stack Example class Student { int id; } public class HeapExample { public static void main(String[] args) { Student s = new Student(); // stored in Heap } } Explanation of Code new Student() → object created in Heap Reference s is stored in Stack GC removes unused objects from Heap 4. Stack Memory Explanation Stack is us...

Difference Between Runnable and Thread in Java

Image
1. Introduction In Java, multithreading can be achieved in two main ways: By extending the Thread class By implementing the Runnable interface Both are used to create threads, but they differ in design, flexibility, and usage . 2. Thread Class Explanation Thread is a class in Java. To create a thread, you extend this class and override the run() method. Java does not support multiple inheritance , so extending Thread limits flexibility. Example class MyThread extends Thread { public void run() { System.out.println("Thread is running..."); } } public class ThreadExample { public static void main(String[] args) { MyThread t = new MyThread(); t.start(); } } Explanation of Code MyThread extends Thread → Inheriting Thread class run() → Defines the task start() → Creates a new thread and internally calls run() 3. Runnable Interface Explanation Runnable is an interface . You implement it and pass the object to a Thread. Allows multi...

How Do You Ensure Fault Tolerance?

Image
Fault tolerance is a crucial concept in modern system design that ensures an application continues to function even when some of its components fail. In distributed systems, failures are unavoidable due to network issues, hardware problems, or software bugs. However, a well-designed fault-tolerant system minimizes downtime and ensures a seamless user experience. What is Fault Tolerance? Fault tolerance refers to the ability of a system to continue operating without interruption even when one or more components fail. Instead of crashing completely, the system detects failures and takes corrective actions automatically. For example, if one server in a distributed system goes down, traffic can be redirected to other active servers without affecting users. This ensures high availability and reliability. Why is Fault Tolerance Important? Fault tolerance is important because modern applications must be available 24/7. Any downtime can lead to financial loss, poor user experience, and damage ...

What is API versioning?

Image
API Versioning is the practice of managing changes to an API by assigning different versions, so that existing clients don’t break when updates are made. 👉 In simple terms: API Versioning = Updating APIs without breaking old applications  Why Do We Need API Versioning? In real-world applications, APIs evolve: New features are added Existing responses change Bugs are fixed  Problem: If you change an API directly: Old apps may break Mobile apps may crash Clients may fail  Solution: 👉 Use versioning to support old + new versions together  Example Without Versioning ❌ GET /users If response format changes → old clients break With Versioning ✅ GET /v1/users GET /v2/users /v1/users → old response /v2/users → new response ✔ Both clients work safely  Types of API Versioning 1. URL Versioning (Most Common) GET /v1/users GET /v2/users ✔ Easy to implement ✔ Easy to understand 2. Header Versioning GET /users Headers: API-Version: 2 ✔ Cleaner URLs ❌ Harder to test/debug...

What is a Multi-Module Project?

Image
A multi-module project is a project that is divided into multiple smaller sub-projects (called modules), where each module handles a specific functionality. 👉 Instead of one large codebase, you split it into logical units.  Example Structure In Java , using tools like Apache Maven or Gradle , a multi-module project might look like this: project-parent │ ├── user-service ├── order-service ├── payment-service └── common-utils Parent Project → Manages all modules Child Modules → Independent components  How It Works in Maven? In Maven, a parent pom.xml defines all modules: <modules> <module>user-service</module> <module>order-service</module> <module>payment-service</module> </modules> 👉 Each module has its own pom.xml , but all are controlled by the parent.  Key Features  1. Modular Development Each module focuses on a specific functionality.  2. Code Reusability Common logic (like utilities) can be...

What is JWT (JSON Web Token)?

Image
JWT (JSON Web Token) is a compact, secure way of transmitting information between two parties as a JSON object. It is commonly used for authentication and authorization in modern web applications. In simple terms, JWT allows a server to verify who you are without storing your session data. 📌 Why Do We Use JWT? Stateless authentication (no session storage) Secure data transfer Widely used in REST APIs Works well with microservices 📌 Structure of JWT A JWT consists of 3 parts , separated by dots ( . ): Header.Payload.Signature 1️⃣ Header Contains algorithm and token type Example: { "alg": "HS256", "typ": "JWT" } 2️⃣ Payload Contains user data (claims) Example: { "userId": 101, "role": "ADMIN" } 3️⃣ Signature Used to verify token integrity Created using: Header + Payload Secret key Algorithm (e.g., HS256) 🔹 Example JWT Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 . eyJ1c2VySWQiOjEwMSwicm9sZSI6IkFETUlOIn0 . ab...

Difference between FileInputStream vs BufferedInputStream

Image
Both FileInputStream and BufferedInputStream are used to read data from files in Java , but they differ significantly in performance and how they handle data internally . 🔹 1. FileInputStream FileInputStream is a low-level byte stream that reads data directly from the file . ✅ Example: FileInputStream fis = new FileInputStream("data.txt"); int data; while ((data = fis.read()) != -1) { System.out.print((char) data); } fis.close(); ✔ Key Features: Reads one byte at a time Direct interaction with the file system Slower performance for large files No buffering mechanism 🔹 2. BufferedInputStream BufferedInputStream is a wrapper class that adds buffering to improve performance. ✅ Example: FileInputStream fis = new FileInputStream("data.txt"); BufferedInputStream bis = new BufferedInputStream(fis); int data; while ((data = bis.read()) != -1) { System.out.print((char) data); } bis.close(); ✔ Key Features: Uses an internal buffer (default ~8KB) Reads chunk...

What Are SoftReference, WeakReference, and PhantomReference in Java?

Image
Java provides different types of references to manage memory efficiently and work closely with the Garbage Collector (GC). Among them, SoftReference , WeakReference , and PhantomReference are advanced concepts used in memory-sensitive applications. Let’s break them down in a simple and practical way. 🔹 Why Do We Need Special References? In Java, objects are usually referenced using strong references . String str = new String("Java"); 👉 As long as a strong reference exists, the object will not be garbage collected . But sometimes, we want objects to be removed when memory is low or not in use. That’s where special references come in. 🔹 1. SoftReference A SoftReference is used when you want to keep objects as long as memory is available . 👉 The Garbage Collector removes them only when memory is low . 💡 Example: import java.lang.ref.SoftReference; SoftReference<String> ref = new SoftReference<>(new String("Java")); String value = ref.get(); ✅ Use Ca...

SoftReference vs WeakReference vs PhantomReference in Java

Image
📌 What are Reference Types in Java ? In Java, apart from strong references , there are three special types: SoftReference WeakReference PhantomReference 👉 These are part of java.lang.ref package and are used for memory-sensitive applications . 🔹 1. SoftReference A SoftReference object is cleared only when JVM is running low on memory . ✅ Use Case: Caching Memory-sensitive data 💡 Example: import java.lang.ref.SoftReference; SoftReference<String> ref = new SoftReference<>(new String("Java")); 👉 Object stays in memory until JVM really needs memory 🔹 2. WeakReference A WeakReference object is cleared as soon as GC runs , even if memory is available. ✅ Use Case: Avoid memory leaks WeakHashMap 💡 Example: import java.lang.ref.WeakReference; WeakReference<String> ref = new WeakReference<>(new String("Java")); 👉 Object is eligible for GC immediately 🔹 3. PhantomReference A PhantomReference is the weakest reference type. 👉 Object is alr...

What is CascadeType in Hibernate/JPA?

Image
In Hibernate/JPA , CascadeType defines how operations performed on a parent entity should be automatically applied to its child entities . 👉 In simple terms, it controls how changes in one entity affect related entities . Why CascadeType is Needed Without CascadeType: You must manually save, update, or delete child entities More boilerplate code Higher chance of errors With CascadeType: Operations are automatically propagated Simplifies entity management Improves consistency Example @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) private List<Order> orders; 👉 When you perform operations on User , the same will be applied to Order . Types of CascadeType 1. PERSIST Saves child entities when parent is saved cascade = CascadeType.PERSIST 2. MERGE Updates child entities when parent is updated cascade = CascadeType.MERGE 3. REMOVE Deletes child entities when parent is deleted cascade = CascadeType.REMOVE 4. REFRESH Refreshes child entities when parent is refreshe...

What is API Gateway?

Image
In modern applications, especially microservices architecture , multiple services handle different functionalities. Managing direct communication between clients and these services can become complex. An API Gateway acts as a single entry point for all client requests. Instead of calling multiple services directly, clients send requests to the API Gateway, which then routes them to the appropriate microservice. Understanding API Gateway An API Gateway sits between the client (frontend/mobile app) and the backend services (microservices) . Flow: Client → API Gateway → Microservices → Response → Client The API Gateway handles all incoming requests and performs tasks like routing, authentication, and load balancing . Key Responsibilities of API Gateway 1. Request Routing Routes client requests to the correct microservice. 2. Authentication & Authorization Validates user identity and permissions before forwarding requests. 3. Load Balancing Distributes requests across multiple serv...

Garbage Collection in Java

Image
Memory management is one of the most powerful features of Java. Unlike many programming languages where developers must manually manage memory, Java provides an automatic mechanism called Garbage Collection (GC) . Garbage Collection helps remove unused objects from memory, improving application performance and preventing memory leaks. Understanding how garbage collection works is very important for Java developers who want to build efficient and scalable applications . What is Garbage Collection in Java? Garbage Collection is the process by which the Java Virtual Machine (JVM) automatically identifies and removes objects that are no longer being used by the program. In simple terms, when an object is no longer referenced by any part of the program, the JVM marks it as eligible for garbage collection and frees the memory occupied by that object. Example: Student s = new Student(); s = null; In this example, the object created for Student becomes eligible for garbage collection becaus...

What is @Autowired in Spring?

Image
In the Spring Framework , the @Autowired annotation is used for automatic dependency injection . It tells the Spring container to automatically find and inject the required dependency into a class . Instead of manually creating objects using the new keyword, Spring automatically provides the required object at runtime. This helps reduce tight coupling between classes and makes applications more flexible and maintainable . How @Autowired Works When Spring encounters the @Autowired annotation, it searches for a matching bean in the Spring container and injects it into the required class. Spring resolves dependencies using type-based injection by default . Example of @Autowired Service Class @Service class UserService { public void getUser() { System.out.println("Fetching user details..."); } } Controller Class @RestController class UserController { @Autowired private UserService userService; public void displayUser() { userService.get...

Builder Design Pattern in Java

Image
The Builder Design Pattern is a Creational Design Pattern used to construct complex objects step by step . It allows developers to create objects with many optional parameters while keeping the code clean, readable, and maintainable. Instead of creating large constructors with many parameters, the Builder Pattern separates the construction of an object from its representation , making object creation more flexible. Why Builder Pattern is Needed When a class has many fields, creating objects using constructors can lead to problems like: Too many constructor parameters Unreadable code Difficulty in maintaining and extending code For example: User user = new User("John", 25, "India", "john@gmail.com", "Developer"); It becomes difficult to understand what each parameter represents. The Builder Pattern solves this problem by building the object step by step. Structure of Builder Pattern The Builder Pattern usually contains: Product Class – The com...

Key Components of a Distributed System in Java

Image
Modern applications often serve millions of users across different locations. To handle this scale efficiently, organizations rely on distributed systems . A distributed system is a collection of independent computers that work together as a single system to provide better performance, scalability, and reliability. For backend developers working with Java , understanding the core components of a distributed system is essential for building scalable applications. These concepts are fundamental in System Design . What is a Distributed System? A distributed system is a network of multiple machines that communicate and coordinate with each other to achieve a common goal. Instead of relying on a single server, the workload is distributed across multiple nodes , improving performance and fault tolerance. Examples of distributed systems include large platforms such as Amazon , Netflix , and Google . Key Components of a Distributed System 1. Load Balancer A load balancer distributes incoming...

What is ForkJoinPool in Java?

Image
In modern Java applications, performing large computations efficiently is very important. When tasks can be broken into smaller independent tasks , Java provides a powerful framework called Fork/Join Framework to execute them in parallel. The core component of this framework is the ForkJoinPool . ForkJoinPool is designed to efficiently execute recursive tasks by splitting them into smaller subtasks and combining the results . What is ForkJoinPool? ForkJoinPool is a special type of thread pool introduced in Java 7 as part of the java.util.concurrent package. It is mainly used for parallel processing of large tasks using the divide-and-conquer approach . The basic idea: Fork → Break a big task into smaller subtasks Execute → Run subtasks in parallel Join → Combine results of all subtasks This approach helps in maximizing CPU utilization in multi-core systems . How ForkJoinPool Works ForkJoinPool uses a technique called Work Stealing Algorithm . Work Stealing Each worker thread m...

What is JIT Compiler in Java?

Image
Java is known for its platform independence and high performance. One of the important components that helps Java run faster is the JIT (Just-In-Time) Compiler . The JIT compiler is part of the Java Virtual Machine (JVM) and plays a crucial role in improving the performance of Java applications by converting bytecode into optimized machine code at runtime. What is JIT Compiler? The JIT (Just-In-Time) Compiler is a component of the JVM that converts Java bytecode into native machine code while the program is running . Normally, Java code goes through multiple stages before execution: Java source code is written ( .java file) The Java compiler (javac) converts it into bytecode ( .class file) The JVM interprets the bytecode The JIT compiler converts frequently used bytecode into native machine code This makes Java programs run faster after initial execution . Java Execution Process The Java execution flow looks like this: Java Source Code (.java) ↓ Java Compiler (javac) ...

What is the Difference Between Shallow Copy and Deep Copy in Java?

Image
When working with objects in Java, especially in real-time applications, understanding object copying is very important. One common interview question is: What is the difference between Shallow Copy and Deep Copy? Let’s understand this clearly with examples. 🔹 What is a Shallow Copy? A shallow copy creates a new object, but it copies the references of nested objects instead of creating new copies of them. 👉 That means both original and copied objects point to the same memory location for internal objects. 🔹 Example of Shallow Copy class Address { String city; Address(String city) { this.city = city; } } class Employee implements Cloneable { int id; Address address; Employee(int id, Address address) { this.id = id; this.address = address; } protected Object clone() throws CloneNotSupportedException { return super.clone(); // Shallow Copy } } What Happens? A new Employee object is created. But the Address o...

What is Load Factor in HashMap?

Image
The Load Factor in a HashMap defines how full the HashMap can get before its capacity is automatically increased (resized) . In simple terms: 👉 Load Factor controls when HashMap should grow to maintain good performance. 🔹 Default Load Factor The default load factor value in Java HashMap is: 0.75 (75%) This means when the HashMap becomes 75% full , it will resize automatically. 🔹 How It Works Formula: Threshold = Capacity × Load Factor Example: Initial Capacity = 16 Load Factor = 0.75 Threshold = 16 × 0.75 = 12 👉 When 12 entries are inserted, HashMap resizes (capacity becomes 32). 🔹 Why Load Factor is Important? It balances between: Default value 0.75 provides the best balance between memory and performance. 🔹 Resizing Process When threshold is reached: HashMap capacity doubles All elements are rehashed New bucket indexes are calculated This process is called Rehashing . 🔹 Custom Load Factor Example HashMap<Integer, String> map = new HashMap<>(32, 0.5f); He...