HCL RealTimeInterview
HCL RealTimeInterview
=======================
Design patterns are reusable solutions to common problems in software design. They
can be categorized into three main types: Creational, Structural, and Behavioral
patterns. Here’s an overview of each category, along with examples in Java.
These patterns deal with object creation mechanisms, trying to create objects in a
manner suitable to the situation.
```java
public class Singleton {
private static Singleton instance;
```java
interface Product {
void create();
}
These patterns deal with object composition, ensuring that if one part of a system
changes, the entire system doesn’t need to change.
```java
interface Target {
void request();
}
class Adaptee {
void specificRequest() {
System.out.println("Specific request.");
}
}
```java
interface Coffee {
String getDescription();
double cost();
}
These patterns focus on communication between objects, what goes on between objects
and how they operate together.
```java
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class Subject {
private List<Observer> observers = new ArrayList<>();
```java
interface Strategy {
int execute(int a, int b);
}
class Context {
private Strategy strategy;
### Summary
### 1. Purpose
- **@Component**:
- It is a generic stereotype annotation that indicates that the class is a Spring
component.
- It can be used for any Spring-managed component that doesn't fall into more
specific categories like service, repository, or controller.
- **@Service**:
- It is a specialization of `@Component`.
- It is used specifically for service layer components, indicating that the class
contains business logic.
### 2. Semantics
- **@Component**:
- It does not provide any additional semantics beyond defining the class as a
Spring bean.
- It is generally used when there is no better-suited stereotype annotation.
- **@Service**:
- It provides clearer semantics that the class is part of the service layer.
- This can be beneficial for readability and maintainability of the code.
- **@Component**:
- Use this when creating generic Spring beans that do not specifically belong to
the service, repository, or controller layers.
- **@Service**:
- Use this for classes that implement business logic and service-related
functions.
### Example
```java
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Component
public class Utility {
public void performUtilityTask() {
// Some utility logic
}
}
@Service
public class UserService {
private final Utility utility;
### Summary
- Use `@Component` for general-purpose Spring beans.
- Use `@Service` for classes that contain business logic and belong to the service
layer.
Choosing the appropriate annotation can improve code clarity and organization,
making it easier for other developers to understand the role of each class in the
application.
==========================
Difference Between @Component, @Repository, @Service, and @Controller Annotations
in Spring
===============
Spring Annotations are a form of metadata that provides data about a program.
Annotations are used to provide supplemental information about a program. It does
not have a direct effect on the operation of the code they annotate. It does not
change the action of the compiled program. Here, we are going to discuss the
difference between the 4 most important annotations in Spring, @Component,
@Repository, @Service, and @Controller.
@Component Annotation
@Component is a class-level annotation. It is used to denote a class as a
Component. We can use @Component across the application to mark the beans as
Spring’s managed components. A component is responsible for some operations. Spring
framework provides three other specific annotations to be used when marking a class
as a Component.
@Service
@Repository
@Controller
Types Of Component Annotation
To read more about @Component Annotation refer to the article Spring @Component
Annotation
A. @Service Annotation
In an application, the business logic resides within the service layer so we use
the @Service Annotation to indicate that a class belongs to that layer. It is a
specialization of @Component Annotation. One most important thing about the
@Service Annotation is it can be applied only to classes. It is used to mark the
class as a service provider. So overall @Service annotation is used with classes
that provide some business functionalities. Spring context will autodetect these
classes when annotation-based configuration and classpath scanning is used.
To read more about @Service Annotation refer to the article Spring @Service
Annotation
B. @Repository Annotation
@Repository Annotation is also a specialization of @Component annotation which is
used to indicate that the class provides the mechanism for storage, retrieval,
update, delete and search operation on objects. Though it is a specialization of
@Component annotation, so Spring Repository classes are autodetected by the spring
framework through classpath scanning. This annotation is a general-purpose
stereotype annotation which very close to the DAO pattern where DAO classes are
responsible for providing CRUD operations on database tables.
To read more about @Repository Annotation refer to the article Spring @Repository
Annotation
C. @Controller Annotation
Spring @Controller annotation is also a specialization of @Component annotation.
The @Controller annotation indicates that a particular class serves the role of a
controller. Spring Controller annotation is typically used in combination with
annotated handler methods based on the @RequestMapping annotation. It can be
applied to classes only. It’s used to mark a class as a web request handler. It’s
mostly used with Spring MVC applications. This annotation acts as a stereotype for
the annotated class, indicating its role. The dispatcher scans such annotated
classes for mapped methods and detects @RequestMapping annotations.
To read more about @Controller Annotation refer to the article Spring @Controller
Annotation
Similarity
One of the interesting queries that arise in front of a developer is, can
@Component, @Repository, @Service, and @Controller annotations be used
interchangeably in Spring or do they provide any particular functionality? In other
words, if we have a Service class and we change the annotation from @Service to
@Component, will it still behave the same way?
| **Annotation** | **Purpose**
| **Specialization** | **Role** |
**Layer** | **Switching** |
**Type** |
|---------------------|------------------------------------------------------------
---|--------------------------- |----------------------------------
------|------------------------|---------------------------------------------------
|-----------------------|
| `@Service` | Indicates a class that provides business functionalities
| Specialization of `@Component` | Marks class as a service provider |
Service Layer | Possible but not recommended |
Stereotype Annotation |
| `@Repository` | Indicates a class that handles data access operations
| Specialization of `@Component` | Marks class as DAO (Data Access Object) | DAO
Layer | Possible but not recommended | Stereotype
Annotation |
| `@Controller` | Indicates a class that handles web requests
| Specialization of `@Component` | Marks class as a web request handler |
Presentation Layer | Not possible to switch with `@Service` or `@Repository` |
Stereotype Annotation |
This table concisely captures the key aspects of each annotation in a clear format.
================================
A **ConcurrentModificationException** occurs in Java when an object is modified
concurrently while it is being iterated over in a way that is not allowed. This
typically happens with collections like `ArrayList`, `HashMap`, etc., when they are
structurally modified during iteration (e.g., adding or removing elements).
```java
import java.util.ArrayList;
import java.util.Iterator;
```java
import java.util.ArrayList;
```java
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer num = iterator.next();
if (num.equals(2)) {
iterator.remove(); // Safe removal
}
}
```
```java
ArrayList<Integer> toRemove = new ArrayList<>();
for (Integer num : list) {
if (num.equals(2)) {
toRemove.add(num);
}
}
list.removeAll(toRemove);
```
A deadlock occurs when two or more threads are blocked forever, each waiting on the
other. Here's a simple example of a deadlock situation:
```java
class A {
synchronized void methodA(B b) {
System.out.println("Thread 1: Holding lock A...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock B...");
b.last();
}
class B {
synchronized void methodB(A a) {
System.out.println("Thread 2: Holding lock B...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock A...");
a.last();
}
// Thread 1
new Thread(() -> a.methodA(b)).start();
// Thread 2
new Thread(() -> b.methodB(a)).start();
}
}
```
### Explanation:
- **Thread 1** acquires a lock on `A` and tries to call `B`'s method.
- **Thread 2** acquires a lock on `B` and tries to call `A`'s method.
- This creates a deadlock as each thread is waiting for the other to release its
lock.
3. **Avoid Nested Locks**: Try not to acquire more than one lock at a time.
```java
class A {
void methodA(B b) {
synchronized (this) {
System.out.println("Thread 1: Holding lock A...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock B...");
synchronized (b) {
b.last();
}
}
}
void last() {
System.out.println("In A.last");
}
}
class B {
void methodB(A a) {
synchronized (this) {
System.out.println("Thread 2: Holding lock B...");
try { Thread.sleep(100); } catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock A...");
synchronized (a) {
a.last();
}
}
}
void last() {
System.out.println("In B.last");
}
}
// Thread 1
new Thread(() -> a.methodA(b)).start();
// Thread 2
new Thread(() -> b.methodB(a)).start();
}
}
```
### Example
```java
// Define two functional interfaces
@FunctionalInterface
interface InterfaceA {
default void greet() {
System.out.println("Hello from InterfaceA");
}
}
@FunctionalInterface
interface InterfaceB {
default void greet() {
System.out.println("Hello from InterfaceB");
}
}
// Class implementing both interfaces
class MyClass implements InterfaceA, InterfaceB {
// If you want to use a specific default method from an interface
public void useGreet() {
// Call the default method from InterfaceA
InterfaceA.super.greet();
### Explanation
1. **Functional Interfaces**: `InterfaceA` and `InterfaceB` both have a default
method `greet()`.
2. **Implementation**: `MyClass` implements both interfaces.
3. **Calling Default Methods**: Inside `useGreet()`, you can call the default
methods explicitly using `InterfaceA.super.greet()` and `InterfaceB.super.greet()`.
This disambiguates which default method you are calling.
### Output
When you run the `Main` class, the output will be:
```
Hello from InterfaceA
Hello from InterfaceB
```
This shows that both default methods were successfully called from their respective
interfaces.
==========================
`@EnableAutoConfiguration` is a key annotation in Spring Boot that enables the
automatic configuration of Spring application context. When you add this annotation
to your main application class, it tells Spring Boot to automatically configure
your application based on the dependencies present on the classpath.
### Example
```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
### Summary
4. **Schema Migration**:
- Create the schema in the target database. This includes tables, indexes,
constraints, and relationships.
- You can generate SQL scripts from the source database schema and adapt them to
the target database.
5. **Data Migration**:
- Use the chosen tool or write scripts to extract data from the source database
and load it into the target database.
- Ensure that data types are compatible. You may need to transform data during
this process.
6. **Testing**:
- Validate the migration by comparing the source and target databases.
- Check for data integrity, relationships, and application functionality.
7. **Switch Over**:
- If applicable, plan a downtime or a cutover strategy to switch applications to
the new database.
- Update configuration settings in your application to point to the new
database.
9. **Documentation**:
- Document the migration process, issues encountered, and how they were resolved
for future reference.
- **MySQL**: Use `mysqldump` for exporting data and `mysql` command to import.
- **PostgreSQL**: Use `pg_dump` and `pg_restore`.
- **Oracle**: Use Oracle Data Pump.
- **SQL Server**: Use SQL Server Management Studio (SSMS) for data export/import.
### Considerations
By following these steps, you can systematically migrate your data from one
database to another while minimizing risks.
============================
`@Transactional` is an annotation in Spring that provides declarative transaction
management. It is used to manage transactions in a Spring application, making it
easier to handle complex transaction scenarios without having to deal with low-
level transaction management code.
3. **Rollback Management**:
- You can specify which exceptions should trigger a rollback of the transaction.
By default, only unchecked exceptions (subclasses of `RuntimeException`) will cause
a rollback.
4. **Method-Level Granularity**:
- You can apply `@Transactional` at the class level or the method level. If
applied at the class level, all public methods in that class will inherit the
transaction configuration.
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
### Configuration
```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@SpringBootApplication
@EnableTransactionManagement
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
```
### Summary
**Example**:
```java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
**Correct Example**:
```java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
### Summary
- **Cause**: Modifying a collection while iterating over it using a standard loop
or iterator.
- **Solution**: Use the iterator’s `remove()` method to safely remove elements or
avoid modifying the collection during iteration.
================
Yes, you're correct! `CopyOnWriteArrayList` is a thread-safe variant of `ArrayList`
that can be used to avoid `ConcurrentModificationException` (CME) in situations
where you need to modify the list while iterating over it.
### Trade-offs:
- **Memory Overhead**: Due to copying the entire array on each modification, it can
be memory-intensive.
- **Performance on Writes**: Write operations are slower compared to regular
`ArrayList` because of the copying mechanism.
### Example:
Here’s an example of a functional interface with a single abstract method, a
default method, a static method, and a static variable:
```java
@FunctionalInterface
public interface MyFunctionalInterface {
void performAction(); // SAM
```java
public class Main {
public static void main(String[] args) {
MyFunctionalInterface myFunc = () -> System.out.println("Performing
action!");
myFunc.performAction(); // Calls the SAM
myFunc.defaultMethod(); // Calls the default method
MyFunctionalInterface.staticMethod(); // Calls the static method
System.out.println(MyFunctionalInterface.CONSTANT); // Accessing the
constant
}
}
```
### Summary:
- A functional interface can contain a single abstract method, multiple default
methods, and static methods.
- You can declare static variables, which are constants in the context of the
interface.
- The main requirement is that it maintains the SAM property to be considered a
functional interface.
============================
In Java, a functional interface cannot have instance variables. However, you can
have local variables in the methods defined within the functional interface. Here's
a breakdown:
### Example
Here’s an example to illustrate this:
```java
@FunctionalInterface
public interface MyFunctionalInterface {
void performAction(); // SAM
### Summary
- **Instance Variables**: Not allowed in functional interfaces.
- **Local Variables**: Allowed within methods (default or static) but scoped to
those methods.
```java
@RestController
public class MyController {
@GetMapping("/example")
public MyPojo getExample() {
return new MyPojo("example", 123);
}
}
```
### Summary
- **Automatic JSON Conversion**: Yes, Spring Boot automatically converts POJOs to
JSON using Jackson, configured through `@EnableAutoConfiguration`.
- **No Extra Configuration Needed**: As long as you include the right dependencies
and annotations, Spring handles the conversion seamlessly.
This means you can focus on your application logic without worrying about the
underlying serialization mechanisms!
====================
***Accenture***
===========================
Optimistic locking is a concurrency control method used to ensure that multiple
transactions can operate on the same data without conflicts. Instead of locking the
database rows for the duration of a transaction (as in pessimistic locking),
optimistic locking allows transactions to proceed without locking, checking for
conflicts only at the time of committing the transaction.
4. **Conflict Handling**:
- If the version numbers match, the update is applied, and the version number is
incremented.
- If they do not match, it means another transaction has modified the entity
since it was read, and the current transaction is aborted (or an exception is
thrown).
Here's a simple example using JPA (Java Persistence API) in a Spring Boot
application.
```java
import javax.persistence.*;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
```java
import org.springframework.data.jpa.repository.JpaRepository;
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
product.setName(newName);
product.setPrice(newPrice);
### Summary
Optimistic locking is a powerful way to manage concurrent updates in applications,
allowing for better performance and resource utilization when conflicts are
infrequent. By using versioning, it ensures data integrity without the drawbacks of
locking.
====================
Optimistic and pessimistic locking are two strategies for handling concurrent
access to data in database systems. Each approach has its advantages and
disadvantages, depending on the use case and expected contention.
**How It Works**:
1. A transaction reads data and its associated version (or timestamp).
2. The transaction performs operations on the data.
3. When committing, it checks if the version in the database matches the version
read earlier.
4. If they match, the transaction is committed, and the version is incremented. If
not, a conflict occurred, and the transaction may be retried or aborted.
```java
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
product.setName(newName);
product.setPrice(newPrice);
try {
productRepository.save(product);
} catch (OptimisticLockingFailureException e) {
// Handle conflict
System.out.println("Conflict occurred. Please retry.");
}
}
}
```
**How It Works**:
1. A transaction requests a lock on the data it needs to access.
2. Other transactions that try to access the same data are blocked until the lock
is released.
3. Once the transaction completes, the lock is released, allowing other
transactions to proceed.
```java
import javax.persistence.LockModeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@Service
public class ProductService {
@PersistenceContext
private EntityManager entityManager;
product.setName(newName);
product.setPrice(newPrice);
### Summary
Choosing between the two strategies depends on the specific requirements of your
application and the expected patterns of data access.
=================================
To connect a PostgreSQL database from a Spring Boot application, you need to
fulfill several requirements:
### 1. Dependencies
Add the PostgreSQL JDBC driver dependency in your `pom.xml` (for Maven) or
`build.gradle` (for Gradle).
**For Maven:**
```xml
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.5.0</version> <!-- Check for the latest version -->
</dependency>
```
**For Gradle:**
```groovy
implementation 'org.postgresql:postgresql:42.5.0' // Check for the latest version
```
### 2. Configuration
**For `application.properties`:**
```properties
spring.datasource.url=jdbc:postgresql://localhost:5432/your_database_name
spring.datasource.username=your_username
spring.datasource.password=your_password
spring.datasource.driver-class-name=org.postgresql.Driver
**For `application.yml`:**
```yaml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/your_database_name
username: your_username
password: your_password
driver-class-name: org.postgresql.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.PostgreSQLDialect
```
Ensure that:
- PostgreSQL is installed and running.
- You have created the database you want to connect to.
- You have the correct username and password with the necessary permissions to
access that database.
- **Connection Pooling**: You might want to use a connection pool for better
performance. Spring Boot provides support for HikariCP by default.
- **Testing the Connection**: You can create a simple REST controller or a command-
line runner to test the connection to the database once your application starts.
```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
```
### Conclusion
```properties
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
```
is used to specify the SQL dialect that Hibernate should use when interacting with
the PostgreSQL database. Here’s a breakdown of its significance:
### Purpose of Hibernate Dialect
When you use the dialect, Hibernate will generate appropriate SQL statements for
CRUD operations that align with PostgreSQL’s capabilities. For instance, if you
have an entity with a field that uses a PostgreSQL-specific data type, the dialect
ensures the correct SQL is generated for that type.
### Conclusion
The `CrudRepository` interface is the base interface for CRUD operations and
provides the following default methods:
- **`getOne(ID id)`**: Returns a reference to the entity with the given ID. The
entity is not fetched from the database until it is accessed (lazy loading).
```java
import org.springframework.data.jpa.repository.JpaRepository;
### 4. Benefits
- **Custom Queries**: You can also define custom query methods by simply declaring
their names according to Spring Data conventions.
### Conclusion
To use `@Scheduled`, you need to enable scheduling in your Spring Boot application
by adding the `@EnableScheduling` annotation to a configuration class.
```java
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@EnableScheduling
public class SchedulerConfig {
// This class can be empty, just needs to be annotated
}
```
You can then create a method in any Spring-managed bean (like a service) and
annotate it with `@Scheduled`. Here are a few examples of how to use it:
```java
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
public class MyScheduledTask {
This method runs with a fixed delay after the completion of the previous execution:
```java
@Scheduled(fixedDelay = 5000) // 5 seconds after the last execution finishes
public void performTaskWithDelay() {
System.out.println("Task executed with delay at: " +
System.currentTimeMillis());
}
```
You can also use a cron expression to specify more complex schedules. For example,
to run the task every minute at the start of the minute:
```java
@Scheduled(cron = "0 * * * * ?") // At every minute
public void performTaskWithCron() {
System.out.println("Cron task executed at: " + System.currentTimeMillis());
}
```
```java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class SchedulerApplication {
public static void main(String[] args) {
SpringApplication.run(SchedulerApplication.class, args);
}
}
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
@Service
class MyScheduledTask {
@Scheduled(fixedRate = 5000)
public void performTask() {
System.out.println("Task executed at: " + System.currentTimeMillis());
}
}
```
### 4. Conclusion
```java
package com.InterviewPrep;
import java.util.LinkedList;
import java.util.ListIterator;
### Explanation:
1. **Calculate the midpoint**: Determine the size of the list and compute the
midpoint. This is done using `size / 2`.
3. **Iterate in reverse**: Use a loop to iterate from the midpoint backwards. The
`hasPrevious()` method checks if there is a previous element, and `previous()`
retrieves that element.
### Output:
This code will print the first half of the linked list in reverse order based on
the input values.
===========================
The `@Query` annotation in Spring Boot is used to define custom queries for Spring
Data JPA repositories. It allows you to write queries directly in your repository
interface, giving you more control over the database operations.
4. **Named Parameters**:
Instead of using positional parameters, you can use named parameters for better
readability:
```java
@Query("SELECT e FROM Employee e WHERE e.department = :dept")
List<Employee> findByDepartmentNamed(@Param("dept") String department);
```
### Example
Here's a complete example using `@Query` in a Spring Boot application:
```java
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
@Modifying
@Query("UPDATE Employee e SET e.salary = ?1 WHERE e.id = ?2")
int updateEmployeeSalary(double salary, Long id);
}
```
### Summary
- **Flexibility**: Use `@Query` for complex queries that can't be easily expressed
using method naming conventions.
- **Performance**: Fine-tune your queries for performance as needed.
- **Maintainability**: Keeping queries in the repository interface makes it easier
to manage and understand.
Using `@Query` helps you leverage the power of JPA while maintaining clean and
readable code in your Spring Boot application.
============================
Here's a concise comparison between web services and microservices:
### Summary
- **Web Services** are a way to enable communication between applications, often
using standardized protocols and formats.
- **Microservices** are an architectural approach that structures an application
into small, independent services that communicate over a network.
In essence, while all microservices can be considered web services, not all web
services qualify as microservices.
================================
A **lambda expression** in Java is a concise way to represent an anonymous function
(a function without a name). It allows you to create instances of functional
interfaces (interfaces with a single abstract method) in a more compact and
readable way.
### Example:
Here's a simple example demonstrating the use of a lambda expression:
```java
import java.util.Arrays;
import java.util.List;
### Advantages:
- **Simplifies Code**: Makes code cleaner and easier to read.
- **Facilitates Functional Programming**: Enables the use of functional programming
techniques in Java, such as passing behavior as parameters.
### Conclusion:
Lambda expressions enhance the expressiveness of Java by allowing you to write more
concise and flexible code, particularly when working with collections and streams.
===========================
### Functional Interfaces in Java
1. **Runnable**
2. **Callable**
3. **Comparator**
4. **Consumer**
5. **Supplier**
6. **Function**
### Examples
#### 1. Runnable
The `Runnable` interface is used to define a task that can be executed by a thread.
```java
public class RunnableExample {
public static void main(String[] args) {
// Using lambda expression to implement Runnable
Runnable task = () -> System.out.println("Running in a separate thread!");
#### 2. Callable
The `Callable` interface is similar to `Runnable`, but it can return a result and
throw a checked exception.
```java
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
try {
System.out.println(futureTask.get()); // Retrieves the result
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
```
#### 3. Comparator
```java
import java.util.Arrays;
import java.util.Comparator;
#### 4. Consumer
The `Consumer` interface represents an operation that takes a single input and
returns no result.
```java
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
#### 5. Supplier
The `Supplier` interface represents a supplier of results. It does not take any
arguments but returns a result.
```java
import java.util.function.Supplier;
#### 6. Function
The `Function` interface represents a function that takes one argument and produces
a result.
```java
import java.util.function.Function;
System.out.println(stringLength.apply("Hello")); // Output: 5
}
}
```
### Conclusion
Functional interfaces allow for more concise and readable code in Java by enabling
the use of lambda expressions. They are a fundamental part of functional
programming in Java and can be used in various contexts, such as threading,
collection processing, and more.
======================================
The `@CrossOrigin` annotation in Spring allows you to enable Cross-Origin Resource
Sharing (CORS) on your RESTful APIs. CORS is a security feature implemented in web
browsers that prevents web pages from making requests to a different domain than
the one that served the web page.
2. **Specifying Allowed Origins**: You can specify which origins are allowed to
access your API, providing more security by limiting access.
Here's how you can use the `@CrossOrigin` annotation in a Spring Boot application:
```java
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin // Allows all origins
public class MyController {
@GetMapping("/api/data")
public String getData() {
return "Hello from the backend!";
}
}
```
```java
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = "http://localhost:3000") // Allows only this origin
public class MyController {
@GetMapping("/api/data")
public String getData() {
return "Hello from the backend!";
}
}
```
You can also configure CORS globally for your entire application using a
configuration class:
```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");
}
}
```
### Summary
2. **Swagger UI**: This is a visual interface that allows users to view and
interact with the API. It provides a web page where you can see all the endpoints,
their parameters, and responses, making it easy to understand how to use the API.
4. **Code Generation**: Swagger can generate client SDKs and server stubs in
various programming languages, streamlining the development process.
5. **Support for Multiple Formats**: It supports both JSON and YAML formats for
defining APIs, giving developers flexibility in how they document their APIs.
In a Spring Boot application, you can integrate Swagger using the `springfox-
swagger2` and `springfox-swagger-ui` libraries. Here's a simple setup:
```xml
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
```
```java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
```
3. **Access Swagger UI**: Once your application is running, you can access the
Swagger UI at `http://localhost:8080/swagger-ui.html`.
### Summary
2. **Spring MVC**: When you create a RESTful web service in Spring Boot using
Spring MVC, it automatically configures Jackson as the default JSON processor.
```xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
```
```java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@GetMapping("/api/data")
public MyData getData() {
return new MyData("Example", 123);
}
}
class MyData {
private String name;
private int value;
3. **Automatic Conversion**: When you hit the endpoint `/api/data`, Spring Boot
uses Jackson to convert the `MyData` object into JSON. The response will look like
this:
```json
{
"name": "Example",
"value": 123
}
```
### Summary
Spring Boot leverages the Jackson library to automatically convert Java objects to
JSON format when returning responses from RESTful endpoints. This is done
seamlessly, allowing developers to focus on business logic without worrying about
the serialization process.
============================
You can customize Jackson's behavior in Spring Boot in several ways, including
application properties and by defining custom `ObjectMapper` beans. Here’s how you
can do both:
```properties
# Disable serialization of null values
spring.jackson.default-property-inclusion=non_null
If you need more control over the serialization/deserialization process, you can
create a custom `ObjectMapper` bean. Here’s how:
```java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JacksonConfig {
@Bean
public ObjectMapper objectMapper() {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper;
}
}
```
You can also use annotations to customize how individual fields are serialized:
#### Example Class with Annotations
```java
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
### Summary
These methods allow you to tailor how Jackson serializes and deserializes your Java
objects to suit your application’s needs.
==========================