Here's a concise explanation of **Inversion of Control (IoC)** and **Dependency
Injection (DI)**:
### **Inversion of Control (IoC)**:
- **Definition**: IoC is a design principle where the control of object creation
and the flow of the program is transferred to an external framework or container,
rather than the application controlling it itself.
- **Purpose**: It decouples the application logic from the object creation and
management.
- **Example**: In Spring, the IoC container creates and manages objects instead of
the application using `new`.
### **Dependency Injection (DI)**:
- **Definition**: DI is a pattern that implements IoC by injecting an object’s
dependencies (services, collaborators) into it, rather than the object creating
them itself.
- **Types**:
1. **Constructor Injection**: Dependencies are passed through the constructor.
2. **Setter Injection**: Dependencies are provided via setter methods.
3. **Field Injection**: Dependencies are injected directly into fields (commonly
used in Spring with `@Autowired`).
- **Purpose**: It improves loose coupling, flexibility, and testability by
externalizing object creation.
### Key Difference:
- **IoC** is the broader concept of transferring control over object creation and
flow to an external framework.
- **DI** is a specific implementation of IoC, focused on injecting dependencies
into an object.
**In summary**: IoC is the overarching principle, and DI is one way to achieve IoC
by injecting dependencies into objects.
=============================
### **Why and Where to Use `@Qualifier` in Spring:**
In Spring, the `@Qualifier` annotation is used to **resolve ambiguity** when
multiple beans of the same type exist in the **Spring Application Context**. It
helps Spring know which specific bean to inject when there are multiple candidates
for injection.
#### **Why Use `@Qualifier`:**
1. **To Avoid Ambiguity**:
- When multiple beans of the same type exist (e.g., multiple implementations of
an interface), Spring won't know which one to inject, and it will throw an
exception.
- `@Qualifier` tells Spring which bean to inject by specifying the **bean name**
or identifier.
2. **Control Over Dependency Injection**:
- If you have multiple implementations of an interface or class, you may want to
explicitly control which implementation gets injected into the dependent class.
- `@Qualifier` ensures that the correct bean is chosen based on its name or
identifier.
#### **Where to Use `@Qualifier`:**
`@Qualifier` is used in **combination** with **`@Autowired`** when there are
multiple beans of the same type in the Spring container.
#### **Example 1: Multiple Implementations of an Interface**
Imagine you have two different implementations of the same interface:
```java
public interface PaymentService {
void processPayment();
}
@Service("creditCardPayment")
public class CreditCardPaymentService implements PaymentService {
@Override
public void processPayment() {
[Link]("Processing payment through Credit Card.");
}
}
@Service("paypalPayment")
public class PayPalPaymentService implements PaymentService {
@Override
public void processPayment() {
[Link]("Processing payment through PayPal.");
}
}
```
In this case, Spring would not know which `PaymentService` to inject if you use
`@Autowired` alone. To resolve this ambiguity, you can use `@Qualifier`:
```java
@Service
public class OrderService {
private final PaymentService paymentService;
@Autowired
public OrderService(@Qualifier("paypalPayment") PaymentService paymentService)
{
[Link] = paymentService;
}
public void completeOrder() {
[Link]();
}
}
```
In the above example:
- **`@Qualifier("paypalPayment")`** tells Spring to inject the
`PayPalPaymentService` into `OrderService`, resolving the ambiguity between
`CreditCardPaymentService` and `PayPalPaymentService`.
#### **Example 2: Multiple Beans of the Same Type**
Consider a case where you have multiple beans of the same type but want to inject a
specific one:
```java
@Configuration
public class AppConfig {
@Bean
public PaymentService creditCardPayment() {
return new CreditCardPaymentService();
}
@Bean
public PaymentService paypalPayment() {
return new PayPalPaymentService();
}
}
```
If you have a class where you want to inject a specific `PaymentService`, you use
`@Qualifier`:
```java
@Service
public class OrderService {
private final PaymentService paymentService;
@Autowired
public OrderService(@Qualifier("paypalPayment") PaymentService paymentService)
{
[Link] = paymentService;
}
public void completeOrder() {
[Link]();
}
}
```
#### **When to Use `@Qualifier`**:
- **When multiple beans of the same type exist** in your Spring context and Spring
cannot decide which one to inject.
- **To inject a specific bean** when there are several candidates for the same
dependency (like multiple implementations of an interface or class).
#### **Key Points to Remember**:
- `@Qualifier` is typically used in combination with `@Autowired`.
- It’s used to resolve ambiguity when there are multiple beans of the same type in
the Spring container.
- You specify the **bean name** or **ID** inside the `@Qualifier` annotation to
explicitly indicate which bean to inject.
### **Conclusion**:
- Use `@Qualifier` to resolve ambiguity when there are multiple beans of the same
type and you need Spring to inject a specific one.
- It is used in places where `@Autowired` alone would cause ambiguity, such as when
there are multiple implementations of an interface or multiple beans of the same
class type in the application context.
=======================
### **Use of `@ControllerAdvice` in Spring:**
`@ControllerAdvice` is a powerful feature in **Spring MVC** that is used to handle
**global exceptions** and **shared model attributes** across multiple controllers.
It provides a centralized way to handle certain concerns such as error handling,
binding issues, and global model attributes for all controllers.
#### **Main Use Cases of `@ControllerAdvice`:**
1. **Global Exception Handling**:
- `@ControllerAdvice` can be used to define **global exception handlers** for
specific exceptions or all exceptions across the entire application. This
eliminates the need to define exception handling code in each individual
controller.
2. **Global Model Attributes**:
- It can be used to add shared attributes to the model for all controllers. For
example, if you need to add some common data (like user info, site configuration,
etc.) to all views rendered by controllers.
3. **Binding Results**:
- It can be used to handle model binding exceptions across all controllers. For
example, handling validation errors.
#### **Key Features of `@ControllerAdvice`:**
1. **Global Exception Handling**: You can define `@ExceptionHandler` methods inside
`@ControllerAdvice` to handle exceptions globally.
2. **Global Model Attributes**: You can use `@ModelAttribute` methods inside
`@ControllerAdvice` to add common attributes to all controllers' models.
3. **Global Binding**: You can manage data binding issues globally with the
`@InitBinder` annotation inside `@ControllerAdvice`.
---
### **Example of `@ControllerAdvice` for Global Exception Handling:**
In a typical Spring application, you may want to handle exceptions in a central
place rather than repeating the same exception-handling logic in each controller.
You can achieve this using `@ControllerAdvice`.
#### 1. **Define the Global Exception Handler:**
```java
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@ControllerAdvice
public class GlobalExceptionHandler {
// Handle specific exception
@ExceptionHandler([Link])
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleResourceNotFound(ResourceNotFoundException ex, Model model)
{
[Link]("error", [Link]());
return "error/resource-not-found";
}
// Handle all other exceptions
@ExceptionHandler([Link])
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public String handleGeneralException(Exception ex, Model model) {
[Link]("error", [Link]());
return "error/general-error";
}
}
```
In this example:
- `@ControllerAdvice` is used to define global exception handling.
- `@ExceptionHandler` is used to specify how specific exceptions (like
`ResourceNotFoundException`) or general exceptions (`[Link]`) should be
handled.
- `@ResponseStatus` sets the HTTP status code that should be returned (e.g.,
`NOT_FOUND`, `INTERNAL_SERVER_ERROR`).
This approach ensures that if a `ResourceNotFoundException` is thrown anywhere in
the application, the user will be shown a custom error page (`resource-not-
[Link]`).
#### 2. **Custom Exception:**
```java
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
```
#### 3. **Error Page Views:**
The `GlobalExceptionHandler` will return view names for error pages, such as
`error/resource-not-found` or `error/general-error`. These views should exist in
your resources (like `src/main/resources/templates` if using Thymeleaf).
---
### **Example of `@ControllerAdvice` for Global Model Attributes:**
In many applications, you may want to add common attributes to the model in all
controllers (e.g., site-wide user information or configurations).
`@ControllerAdvice` allows you to add these attributes globally.
```java
import [Link];
import [Link];
@ControllerAdvice
public class GlobalModelAttributes {
@ModelAttribute("appName")
public String addAppName() {
return "My Amazing App";
}
@ModelAttribute("currentUser")
public String addCurrentUser() {
// Assume a method that fetches the current user
return "John Doe";
}
}
```
In this example:
- `@ModelAttribute` is used to define attributes (`appName` and `currentUser`) that
will be available in the model of **all** controllers.
- The attributes can be accessed in any controller or view (e.g., in Thymeleaf
templates or JSP pages).
#### **In a View (e.g., Thymeleaf Template):**
```html
<p>Welcome to {{ appName }}!</p>
<p>Current User: {{ currentUser }}</p>
```
No need to explicitly add these attributes in every controller; they will be
automatically available.
---
### **Example of `@ControllerAdvice` for Global Data Binding with `@InitBinder`:**
If you want to customize how Spring binds incoming HTTP request data to model
objects globally, you can use `@InitBinder` in a `@ControllerAdvice` class.
```java
import [Link];
import [Link];
import [Link];
@ControllerAdvice
public class GlobalDataBinder {
@InitBinder
public void initBinder(WebDataBinder binder) {
// Customize the binder (e.g., register custom editors)
[Link]("password"); // Disallow binding to 'password'
field
}
}
```
In this example:
- `@InitBinder` is used to set global data binding customizations for all
controllers.
- For example, the field `password` is disallowed from binding to any model object,
globally.
---
### **Summary of `@ControllerAdvice` Use Cases:**
1. **Global Exception Handling**: Use `@ControllerAdvice` to handle exceptions
across multiple controllers in a central place.
- Define methods with `@ExceptionHandler` to handle specific exceptions
globally.
2. **Global Model Attributes**: Use `@ControllerAdvice` to add common attributes to
the model in all controllers using `@ModelAttribute`.
3. **Global Data Binding Configuration**: Use `@ControllerAdvice` with
`@InitBinder` to configure global data binding behavior for model attributes.
---
### **Advantages of Using `@ControllerAdvice`:**
- **Centralized Exception Handling**: Avoid repetitive code for exception handling
in each controller.
- **Consistency**: Ensures uniform handling of exceptions and common model
attributes across the application.
- **Separation of Concerns**: Helps keep the controller logic clean and focused on
business logic while separating concerns like error handling and global attributes.
In conclusion, `@ControllerAdvice` in Spring provides a centralized mechanism for
handling exceptions, adding shared model attributes, and configuring data binding,
improving maintainability and consistency across your web application.
==============================
Correct, the **String Constant Pool (SCP)** is **not subject to garbage
collection** in the same way that objects on the **heap** are. Here's why:
### **String Constant Pool (SCP) and Garbage Collection**
- **String literals** and **interned strings** (strings that are stored in the SCP)
are managed by the JVM's **String Pool**, which is a special memory area.
- The **String Pool** is designed to optimize memory usage by ensuring that
**identical strings** are stored only once in memory (interned strings).
- **Interned strings** are **not eligible for garbage collection** because:
1. They are stored in a special area of memory that is managed by the JVM and is
not subject to the same garbage collection process as heap objects.
2. The **JVM keeps a reference** to every interned string in the String Pool for
as long as the application runs. As long as the application is running, these
interned strings are kept alive.
### **Why String Pool Strings Aren't GC'd:**
- The JVM internally manages the **String Constant Pool**, and its purpose is to
store unique instances of string literals.
- Since the **String Pool** is part of the JVM's internal memory structure, and the
JVM keeps references to these string literals for the lifetime of the application,
**they are not eligible for garbage collection** unless the JVM itself decides to
**clear the String Pool**, which typically happens during **JVM shutdown**.
### **Key Points:**
1. **String literals** (e.g., `"abc"`, `"def"`) are **interned** and stored in the
**String Pool**.
2. The **String Pool** is generally **not subject to garbage collection**.
3. These interned strings remain in memory as long as the application is running,
which is the reason why they are not eligible for garbage collection.
4. **Heap objects** (e.g., objects created with `new String("abc")`) are different.
These are subject to normal garbage collection rules, and if they are no longer
referenced, they can be GC'd.
### **Example with Interned Strings in SCP:**
```java
String s1 = "abc"; // String "abc" is interned in SCP
String s2 = "abc"; // Refers to the same object in SCP
// Both s1 and s2 point to the same interned string in SCP
s1 = "def"; // Now s1 points to a new interned string "def"
// "abc" remains in the SCP and is not eligible for GC
// "abc" remains in the String Pool, even though s1 now points to "def".
```
- In the example above, even though `s1` no longer points to `"abc"`, the string
`"abc"` remains in the **String Constant Pool** and will **not be garbage
collected**. The string `"abc"` will remain in the pool for the lifetime of the
application.
### **Are String Literals Eligible for GC?**
No, string literals in the **String Constant Pool** are **not eligible for garbage
collection** for the following reasons:
- **String Pool Management**: The **String Pool** is specifically managed by the
JVM to avoid redundant string objects. The JVM keeps a reference to all interned
strings, meaning they are effectively **permanent** for the duration of the
program.
- **Purpose of the String Pool**: Its goal is to **reuse** string objects
efficiently, which is why the JVM holds onto them.
### **Exceptions:**
- In **Java 7 and later**, the **String Pool** is stored in the **Heap** (in the
`[Link]` class), so technically, it could be GC'd in some very specific
circumstances (like if the JVM is running out of memory), but **this is highly
unusual**. The default behavior is that interned strings are not GC'd.
- **String literals** are safe from GC as long as the JVM is running. They stay
in the String Pool for the entire lifetime of the application.
### **Conclusion:**
- **No**, the **String Constant Pool (SCP)** is not subject to garbage collection
in typical scenarios.
- **Interned strings** (such as string literals) are managed by the JVM and will
remain in memory for the duration of the application, **not eligible for garbage
collection**.
- **Heap objects**, however, are subject to the normal garbage collection process
if they become unreachable.
===================================
In Java, the **Garbage Collector (GC)** is designed to manage memory by reclaiming
space used by objects that are no longer reachable. To optimize garbage collection
and improve performance, Java's garbage collector is divided into **different
generations** based on the lifecycle and age of objects. The **Generational Garbage
Collection** model is based on the observation that most objects have a short
lifespan, so managing them differently improves performance.
### **Java Garbage Collection Generations:**
The Java heap is divided into three generations:
1. **Young Generation (Young Gen)**
2. **Old Generation (Old Gen)**
3. **Permanent Generation (Perm Gen) / Metaspace** (This has been replaced with
Metaspace in Java 8 and later.)
Let’s look at each generation in more detail:
---
### 1. **Young Generation (Young Gen)**
- **Description**: The **Young Generation** is where **newly created objects** are
allocated. This generation is designed to handle short-lived objects efficiently.
- **Subdivisions**:
- **Eden Space**: This is where **new objects** are initially allocated. When the
Eden space fills up, a **Minor GC** is triggered to clean up unreachable objects in
the Young Generation and move surviving objects to survivor spaces.
- **Survivor Spaces (S0 and S1)**: The Young Generation is further divided into
two survivor spaces, **S0** (Survivor 0) and **S1** (Survivor 1). After a Minor GC,
the surviving objects from Eden and one survivor space are moved to the other
survivor space. Objects that survive several Minor GCs are eventually promoted to
the Old Generation.
- **GC Type**:
- **Minor GC**: A **Minor GC** is triggered when the Eden space gets full, and it
only collects garbage in the **Young Generation**. This collection is relatively
fast because only a small portion of the heap is involved.
- **Purpose**: The Young Generation is designed for objects with **short
lifetimes** (e.g., temporary objects like local variables). These objects are
typically discarded quickly after their use.
---
### 2. **Old Generation (Old Gen)**
- **Description**: The **Old Generation** is where **long-lived objects** (objects
that survive multiple garbage collection cycles in the Young Generation) are
eventually promoted to. These objects are typically the ones that outlive the Young
Generation’s space.
- **GC Type**:
- **Major GC / Full GC**: A **Major GC** (also known as **Full GC**) is triggered
when the **Old Generation** is full. This involves collecting objects in the Old
Generation as well as cleaning up the Young Generation. **Full GC** is usually
slower and more expensive than a Minor GC.
- **Purpose**: The Old Generation is for **long-lived objects**, such as objects
that are used throughout the application lifecycle (e.g., caches, data structures
that persist).
- **Promotion Process**: Objects in the Young Generation that survive multiple
Minor GCs (typically a few cycles) are **promoted** to the Old Generation. This
process happens when the object is considered to be long-lived.
---
### 3. **Permanent Generation (Perm Gen) / Metaspace (Java 8 and later)**
- **Permanent Generation (Perm Gen)** (Java 7 and earlier):
- The **Permanent Generation** used to store **metadata** related to **classes**
and **method data** (e.g., class definitions, method information, static
variables).
- **Classloader**-related data, interned strings, and other JVM-level class data
were stored in the Perm Gen.
- **GC Type**: A **Full GC** would also involve the Permanent Generation. Issues
like **`OutOfMemoryError: PermGen space`** could occur when the Perm Gen ran out of
space (usually caused by loading too many classes).
- **Metaspace** (Java 8 and later):
- Starting with **Java 8**, the **Permanent Generation** was replaced with
**Metaspace**.
- **Metaspace** is used for storing **class metadata** and **JVM internal
structures**, but unlike Perm Gen, it is now stored outside the Java heap, in
native memory. This reduces the likelihood of running out of space in the heap.
- **Dynamic Sizing**: Metaspace grows automatically as needed, and you can
control the maximum size using the `-XX:MaxMetaspaceSize` flag.
- **GC Type**: The **GC** behavior for Metaspace is similar to the Permanent
Generation, but **Metaspace** is garbage collected differently because it is now
part of **native memory**, not Java heap.
---
### **Garbage Collection Algorithms:**
The Garbage Collection process in each generation is managed using different
algorithms depending on the type of generation. The most common GC algorithms are:
1. **Minor GC (Young Generation)**:
- Focuses on cleaning up the **Young Generation**.
- **Eden** is cleared, and surviving objects are moved to **Survivor spaces** or
promoted to the **Old Generation**.
2. **Major GC (Old Generation)**:
- This is a **Full GC** where both the **Old Generation** and **Young
Generation** are collected.
- This process is slower and more expensive because it involves a larger portion
of the heap.
3. **Full GC**:
- Involves a complete collection of all generations, including the Young
Generation, Old Generation, and the **Permanent Generation** or **Metaspace**.
- Full GC is much slower and can cause application pauses, so minimizing Full GC
events is important for performance.
---
### **GC in Different Generations:**
#### **Young Generation**:
- **GC Trigger**: Minor GC
- **Frequency**: Frequent (because objects are short-lived)
- **Objects**: New objects, temporary objects
- **Behavior**: Fast, collects only young objects
#### **Old Generation**:
- **GC Trigger**: Major GC (Full GC)
- **Frequency**: Less frequent (because objects here are long-lived)
- **Objects**: Long-lived objects that survived multiple minor GCs
- **Behavior**: Slower, collects long-lived objects
#### **Metaspace (or PermGen in older Java versions)**:
- **GC Trigger**: Full GC (affects both Old Gen and Metaspace)
- **Frequency**: Rare (only happens if the Metaspace is full)
- **Objects**: Class metadata, method metadata, and related structures
- **Behavior**: Affects class loading/unloading but less frequent than heap GC
---
### **Summary:**
| **Generation** | **Contents** | **GC
Type** | **Frequency** |
|----------------------|-------------------------------------------------|---------
--------|-----------------------|
| **Young Generation** | New objects, short-lived objects (Eden + Survivor Spaces)
| Minor GC | Frequent (due to short-lived objects) |
| **Old Generation** | Long-lived objects (promoted from Young Gen) | Major
GC (Full GC) | Less frequent (for long-lived objects) |
| **Metaspace / PermGen**| Class metadata, method data, interned strings | Full
GC | Rare (affects class loading/unloading) |
- **Minor GC** is fast but only affects the Young Generation.
- **Major GC** or **Full GC** is slower and involves the Old Generation, which can
lead to application pauses.
By having multiple generations, Java optimizes memory management and GC
performance, minimizing the impact of garbage collection on application
performance.
=========================
You can achieve this task in a few lines of code using Java 8's **Streams API** to
rearrange the array such that all zeros come first and the remaining numbers retain
their order.
Here’s how you can do it:
### **Java 8 Solution:**
```java
import [Link].*;
import [Link].*;
public class RearrangeArray {
public static void main(String[] args) {
int[] arr = {1, 3, 0, 4, 3, 0, 0, 7};
// Create a stream from the array, sort zeros to the front, and retain the
order of other numbers
int[] result = [Link](
[Link](arr).filter(x -> x == 0), // All zeros
[Link](arr).filter(x -> x != 0)) // All non-
zeros
.toArray();
// Print the rearranged array
[Link]([Link](result));
}
}
```
### **Explanation:**
1. **[Link](arr)**: Converts the array into a stream.
2. **filter(x -> x == 0)**: Filters out all `0` elements from the array.
3. **filter(x -> x != 0)**: Filters out all non-zero elements.
4. **[Link](...)**: Concatenates the two streams—first the zeros and then
the non-zero numbers, preserving their order.
5. **toArray()**: Collects the result back into an array.
### **Output:**
```
[0, 0, 0, 1, 3, 4, 3, 7]
```
This code keeps all the zeros at the start and preserves the relative order of the
other elements.
========================