{ JavaTechNote's }
  • Linkedin
  • Github
  • Facebook
  • Twitter
  • Instagram

About me

Let me introduce myself


A bit about me

I am Dhananjaya Naidu and I’m just like you; a java lover. I feel proud to say that I am a Java Developer and currently located in Bangalore, India.

I enjoy coding in full Java/J2ee stack (Spring, JSF, Hibernate, Struts, Servlets, JSP) and Web Technologies (HTML, CSS, JavaScript, JQuery).


I love to play Cricket, Kabaddi, Valley Ball and any Outdoor Sports. I love the nature and like to travel new places.

Profile

Dhananjaya Naidu

Personal info

Dhananjaya Naidu Reddi

Be good, Do good !!!

Birthday: 19 Jun 1988
Website: www.rdnaidu.com
E-mail: hello@rdnaidu.com

RESUME

Know more about my past


Employment

  • 2023-2024

    Planview India Pvt. Ltd. @ Deployment Architect

  • 2021-2023

    Wipro Technologies @ Technical Lead

  • 2020-2021

    Persistent Systems @ Senior Engineering Lead

  • 2018-2020

    Quest Global / Exilant Technologies @ Lead Engineer

  • 2015-2018

    HCL Technologies @ Lead Engineer

  • 2013-2015

    URS Systems @ Consultant

Education

  • 2008-2011

    Osmania University, Hyderabad @ Masters

  • 2005-2008

    Andhra University, Visakhapatnam @ Graduated

  • 2003-2005

    BOE, Andhra Pradesh @ Intermediate

  • 2002-2003

    BSE, Andhra Pradesh @ SSC

Skills & Interests

Productive
90%
Java & J2ee
Creative
70%
HTML & CSS
Progressive
50%
Blogger

Notes

My latest writings


Wednesday, July 31, 2024

Complete Guide to IntelliJ IDEA Shortcuts

IntelliJ IDEA is a powerful integrated development environment (IDE) used by many developers. Mastering its shortcuts can significantly boost your productivity. This guide covers essential shortcuts and provides examples of how to use them effectively.

Table of Contents

  1. Navigation Shortcuts
  2. Editing Shortcuts
  3. Code Completion and Generation
  4. Refactoring Shortcuts
  5. Search and Replace
  6. Running and Debugging
  7. Version Control
  8. Miscellaneous
Shortcut Function Example
Ctrl+N / Cmd+O Go to Class Type "MainA" to find MainActivity.java
Ctrl+Shift+N / Cmd+Shift+O Go to File Type "style" to find styles.xml
Ctrl+E / Cmd+E Recent Files
Ctrl+Alt+Left/Right / Cmd+Option+Left/Right Navigate Back/Forward
Ctrl+B / Cmd+B Go to Declaration Place cursor on 'name' and use the shortcut to jump to its declaration
Ctrl+Alt+B / Cmd+Option+B Go to Implementation
Ctrl+F12 / Cmd+F12 File Structure
Ctrl+G / Cmd+L Navigate to Line
Alt+Down/Up / Control+Down/Up Next/Previous Method

2. Editing Shortcuts

Shortcut Function Example
Ctrl+Space Basic Code Completion Press Ctrl+Space to see methods like toLowerCase()
Ctrl+Shift+Space Smart Code Completion
Ctrl+W / Option+Up Extend Selection
Ctrl+Shift+W / Option+Down Shrink Selection
Ctrl+/ / Cmd+/ Comment/Uncomment Lines
Ctrl+D / Cmd+D Duplicate Line or Selection
Ctrl+Y / Cmd+Backspace Delete Line
Alt+Shift+Up/Down / Option+Shift+Up/Down Move Line Up/Down
Alt+Click / Option+Click Multiple Cursors
Alt+Shift+Insert / Cmd+Shift+8 Column Selection Mode

3. Code Completion and Generation

Shortcut Function Example
Alt+Insert / Cmd+N Generate Code Use this shortcut to generate a constructor in a Java class
Ctrl+Shift+Enter Complete Statement Press Ctrl+Shift+Enter to complete with braces
Ctrl+Alt+T / Cmd+Option+T Surround With Select a block of code and use this shortcut to surround it with a try-catch block
Ctrl+J / Cmd+J Insert Live Template Type "sout" and use this shortcut to insert System.out.println()
Ctrl+J / Cmd+J Postfix Completion Expands "someString.notnull" to "if(someString != null) { ... }"

4. Refactoring Shortcuts

Shortcut Function Example
Shift+F6 Rename
Ctrl+Alt+M / Cmd+Option+M Extract Method
Ctrl+Alt+N / Cmd+Option+N Inline
Ctrl+Alt+V / Cmd+Option+V Extract Variable
Ctrl+F6 / Cmd+F6 Change Method Signature
Ctrl+Alt+E / Cmd+Option+E Extract Interface
F6 Move Class
Shortcut Function Example
Ctrl+F / Cmd+F Find Search for a text string within the current file
Ctrl+R / Cmd+R Replace
Ctrl+Shift+F / Cmd+Shift+F Find in Path Search across the entire project
Ctrl+Shift+R / Cmd+Shift+R Replace in Path

6. Running and Debugging

Shortcut Function Example
Shift+F10 Run Execute the application or test
Shift+F9 Debug
Ctrl+F8 / Cmd+F8 Toggle Breakpoint
F8 Step Over
F7 Step Into
Shift+F8 Step Out
Alt+F9 / Option+F9 Run to Cursor

7. Version Control

Shortcut Function Example
Ctrl+K / Cmd+K Commit Changes
Ctrl+T / Cmd+T Update Project
Alt+` / Option+` VCS Operations Popup
Ctrl+Alt+Z / Cmd+Option+Z Revert Changes

8. Miscellaneous

Shortcut Function Example
Ctrl+Shift+A / Cmd+Shift+A Find Action
Ctrl+Shift+F12 / Cmd+Shift+F12 Toggle Maximize Editor
Ctrl+Shift+S / Cmd+Shift+S Save All
Ctrl+Shift+Alt+T / Cmd+Shift+Option+T Surround With

Conclusion

This guide covers a wide range of shortcuts available in IntelliJ IDEA. Remember, these shortcuts may vary slightly depending on your operating system and IntelliJ IDEA version. You can always check and customize shortcuts in IntelliJ IDEA by going to File > Settings > Keymap (on Windows/Linux) or IntelliJ IDEA > Preferences > Keymap (on macOS).

Practice these shortcuts regularly, and you'll find your productivity increasing significantly as you become more proficient with IntelliJ IDEA. As you become comfortable with these shortcuts, you may want to explore even more advanced features and customizations available in IntelliJ IDEA.

Happy coding!

Wednesday, July 10, 2024

A Java Programmer's Journey from Java 7 to Java 11

As Java has evolved, it has introduced numerous features and enhancements that have significantly improved the language. This article highlights the key differences and improvements from Java 7 to Java 11 with examples and explanations.

1. Lambda Expressions and Functional Interfaces (Java 8)

Lambda expressions provide a concise way to represent anonymous functions. They are particularly useful for implementing simple event listeners or callbacks.
// Java 7: Anonymous inner class
Runnable runnable = new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello, World!");
    }
};
new Thread(runnable).start();

// Java 11: Lambda expression
Runnable runnable = () -> System.out.println("Hello, World!");
new Thread(runnable).start();

2. Stream API (Java 8)

The Stream API allows for functional-style operations on collections of objects, such as map, filter, and reduce operations.
// Java 7
List<String> list = Arrays.asList("a", "b", "c", "d");
for (String s : list) {
    System.out.println(s.toUpperCase());
}

// Java 11
List<String> list = Arrays.asList("a", "b", "c", "d");
list.stream()
    .map(String::toUpperCase)
    .forEach(System.out::println);

3. Optional (Java 8)

Optional is a container object that may or may not contain a non-null value. It helps avoid null checks and potential NullPointerException.
// Java 7
public String getName(Person person) {
    if (person != null) {
        return person.getName();
    } else {
        return "Unknown";
    }
}

// Java 11
public String getName(Person person) {
    return Optional.ofNullable(person)
                   .map(Person::getName)
                   .orElse("Unknown");
}

4. Local-Variable Type Inference (Java 10)

The var keyword allows local variables to have their types inferred by the compiler, making code less verbose.
// Java 7
List<String> list = new ArrayList<>();
list.add("Hello");

// Java 11
var list = new ArrayList<String>();
list.add("Hello");

5. Module System (Java 9)

The module system introduced in Java 9 allows for better encapsulation and separation of code, improving maintainability and security.
// Java 7: No module system
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

// Java 11: With module system
// module-info.java
module mymodule {
    exports com.example;
}

// Main.java
package com.example;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

6. API Changes and Enhancements

Standard libraries have been enhanced with new methods to make common tasks easier and more efficient.
// Java 7: String.join not available
List<String> list = Arrays.asList("a", "b", "c");
String result = "";
for (String s : list) {
    result += s + ",";
}
result = result.substring(0, result.length() - 1);

// Java 11
List<String> list = Arrays.asList("a", "b", "c");
String result = String.join(",", list);

7. New Methods in java.util.Collection (Java 8)

Java 8 introduced new methods like forEach, removeIf, and replaceAll to simplify collection operations.
// Java 7
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    if ("b".equals(iterator.next())) {
        iterator.remove();
    }
}

// Java 11
List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
list.removeIf("b"::equals);

8. HTTP Client (Java 11)

Java 11 introduced a new HttpClient API to replace the old HttpURLConnection and third-party libraries for HTTP requests.
// Java 7: Using third-party libraries like Apache HttpClient
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet("https://api.example.com/data");
HttpResponse response = client.execute(request);

// Java 11
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/data"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

9. Default and Static Methods in Interfaces (Java 8)

Java 8 allows interfaces to have default and static methods, enabling interfaces to provide method implementations.
// Java 7
public interface MyInterface {
    void abstractMethod();
}

public class MyClass implements MyInterface {
    @Override
    public void abstractMethod() {
        System.out.println("Abstract method implementation");
    }
}

// Java 11
public interface MyInterface {
    void abstractMethod();
    
    default void defaultMethod() {
        System.out.println("Default method implementation");
    }

    static void staticMethod() {
        System.out.println("Static method implementation");
    }
}

public class MyClass implements MyInterface {
    @Override
    public void abstractMethod() {
        System.out.println("Abstract method implementation");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.abstractMethod();
        myClass.defaultMethod();
        MyInterface.staticMethod();
    }
}

10. New Date and Time API (Java 8)

The new date and time API introduced in Java 8 (in the java.time package) provides a more modern and comprehensive way to handle dates and times.
// Java 7
import java.util.Date;
import java.text.SimpleDateFormat;

public class Main {
    public static void main(String[] args) {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println(sdf.format(date));
    }
}

// Java 11
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        System.out.println(date.format(formatter));
    }
}

11. CompletableFuture (Java 8)

CompletableFuture is part of the java.util.concurrent package and provides a way to handle asynchronous computations more effectively.
// Java 7
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        Future<String> future = executor.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "Hello, World!";
            }
        });
        System.out.println(future.get());
        executor.shutdown();
    }
}

// Java 11
import java.util.concurrent.CompletableFuture;

public class Main {
    public static void main(String[] args) {
        CompletableFuture.supplyAsync(() -> "Hello, World!")
                         .thenAccept(System.out::println);
    }
}

12. VarHandle and VarHandles (Java 9)

VarHandle is a flexible mechanism for variable manipulation, providing a safer alternative to the sun.misc.Unsafe class.
// Java 7: No direct equivalent, often Unsafe was used with reflection

// Java 11
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;

public class Main {
    private static int value;

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        VarHandle handle = MethodHandles.lookup().findStaticVarHandle(Main.class, "value", int.class);
        handle.set(42);
        System.out.println(value);
    }
}

13. Private Methods in Interfaces (Java 9)

Java 9 introduced private methods in interfaces to share code between default methods.
// Java 7: No direct equivalent

// Java 11
public interface MyInterface {
    default void method1() {
        common();
    }

    default void method2() {
        common();
    }

    private void common() {
        System.out.println("Common method implementation");
    }
}

public class MyClass implements MyInterface {}

public class Main {
    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        myClass.method1();
        myClass.method2();
    }
}

14. Collection Factory Methods (Java 9)

Java 9 introduced factory methods for creating immutable collections, making it easier to create and initialize collections.
// Java 7
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");

Set<String> set = new HashSet<>();
set.add("a");
set.add("b");
set.add("c");

Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);

// Java 11
List<String> list = List.of("a", "b", "c");
Set<String> set = Set.of("a", "b", "c");
Map<String, Integer> map = Map.of("a", 1, "b", 2, "c", 3);

15. String API Enhancements (Java 11)

Java 11 introduced several new methods in the String class to simplify common operations.
// Java 7
String str = " ";
boolean isBlank = str.trim().isEmpty();
String stripped = str.replaceAll("^\\s+|\\s+$", "");
String repeated = new String(new char[3]).replace("\0", "abc");

// Java 11
String str = " ";
boolean isBlank = str.isBlank(); // true
String stripped = str.strip();   // ""
String repeated = "abc".repeat(3); // "abcabcabc"

16. Files API Enhancements (Java 11)

Java 11 introduced new methods in the Files class to make file operations more straightforward.
// Java 7
Path path = Paths.get("test.txt");
List<String> lines = Files.readAllLines(path);
String content = "";
for (String line : lines) {
    content += line + System.lineSeparator();
}
Files.write(path, content.getBytes());

// Java 11
Path path = Paths.get("test.txt");
String content = Files.readString(path);
Files.writeString(path, content);
By leveraging these features introduced from Java 8 to Java 11, you can make your Java code more concise, readable, maintainable, and efficient. Moving from Java 7 to Java 11 involves adopting new paradigms and best practices that modernize your development process and take advantage of the latest improvements in the Java language and libraries.

Sunday, July 7, 2024

Twelve-Factor App methodology applying the Developing a Microservice with Spring Boot


12-Factor App Methodology

The 12-Factor App methodology is a set of best practices for building modern web-based applications. It provides guidelines for creating scalable, maintainable, and portable applications that can be deployed across various environments. Here are the twelve factors with examples:

1. Codebase

One codebase tracked in revision control, many deploys. Example: A single Git repository for your e-commerce application that includes all code for various environments (development, staging, production). Branches can be used for feature development and bug fixes.
git clone https://github.com/username/ecommerce-app.git

2. Dependencies

Explicitly declare and isolate dependencies. Example: Using pom.xml in a Maven-based Java project to declare dependencies.
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.5.4</version>
</dependency>

3. Config

Store config in the environment. Example: Using environment variables to manage configuration.
# application.properties
spring.datasource.url=${DATABASE_URL}
spring.datasource.username=${DATABASE_USERNAME}
spring.datasource.password=${DATABASE_PASSWORD}
Setting environment variables:
export DATABASE_URL=jdbc:mysql://localhost:3306/mydb
export DATABASE_USERNAME=root
export DATABASE_PASSWORD=secret

4. Backing Services

Treat backing services as attached resources. Example: Configuring a database connection in Spring Boot.
spring.datasource.url=${DATABASE_URL}
This allows you to switch databases easily without changing the code.

5. Build, Release, Run

Strictly separate build and run stages. Example: Using Jenkins to manage build and release pipelines. Build stage: Compile the code, run tests, and package the application.
mvn clean package
Release stage: Combine the build with environment-specific configuration.
java -jar target/myapp.jar --spring.config.location=/path/to/config/
Run stage: Execute the application.
java -jar target/myapp.jar

6. Processes

Execute the app as one or more stateless processes. Example: Running a Spring Boot application as a stateless process.
java -jar target/myapp.jar
State (like session data) is stored in external services like Redis.

7. Port Binding

Export services via port binding. Example: Configuring a Spring Boot application to run on a specific port.
server.port=8080
Accessing the application:
curl http://localhost:8080

8. Concurrency

Scale out via the process model. Example: Running multiple instances of a Spring Boot application using Docker.
docker run -d -p 8080:8080 myapp:latest
docker run -d -p 8081:8080 myapp:latest
Load balancing these instances using Nginx or another load balancer.

9. Disposability

Maximize robustness with fast startup and graceful shutdown. Example: Implementing graceful shutdown in Spring Boot.
@Bean
public ServletWebServerFactory servletContainer() {
    TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
    tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
        connector.setProperty("server.shutdown.graceful", "true");
    });
    return tomcat;
}

10. Dev/Prod Parity

Keep development, staging, and production as similar as possible. Example: Using Docker to ensure the same environment in all stages.
docker build -t myapp:latest .
docker run -e DATABASE_URL=jdbc:mysql://localhost:3306/mydb myapp:latest

11. Logs

Treat logs as event streams. Example: Using a logging framework like Logback to write logs to stdout.
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="info">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

12. Admin Processes

Run admin/management tasks as one-off processes. Example: Running a database migration using Flyway in a Spring Boot application.
java -cp myapp.jar org.flywaydb.core.Flyway migrate


Developing a Microservice with Spring Boot: Applying the Twelve-Factor Methodology

Developing a microservice using Spring Boot involves several steps, from setting up your development environment to implementing features and ensuring the application adheres to best practices, including the twelve-factor methodology. Here's a step-by-step guide:

Step 1: Set Up Your Development Environment

  1. Install JDK: Ensure you have Java Development Kit (JDK) installed. Spring Boot typically requires JDK 8 or later.
  2. Install an IDE: Use an Integrated Development Environment (IDE) like IntelliJ IDEA, Eclipse, or Visual Studio Code.
  3. Install Maven/Gradle: These build tools help manage project dependencies and build lifecycle. Maven is commonly used with Spring Boot.

Step 2: Create a Spring Boot Application

  1. Initialize the Project:
    • Use Spring Initializr (https://start.spring.io/) to generate a basic Spring Boot project. Select dependencies such as Spring Web, Spring Data JPA, and any database connector (e.g., H2, MySQL).
    • Download the generated project and import it into your IDE.
  2. Structure Your Project: A typical Spring Boot project follows the Maven structure:
    ├── src
    │   ├── main
    │   │   ├── java
    │   │   │   └── com
    │   │   │       └── example
    │   │   │           └── mymicroservice
    │   │   │               ├── MyMicroserviceApplication.java
    │   │   │               ├── controller
    │   │   │               ├── service
    │   │   │               └── repository
    │   │   ├── resources
    │   │       └── application.properties
    │   └── test

Step 3: Develop Your Microservice

  1. Define Models: Create Java classes representing your data model.
    package com.example.mymicroservice.model;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    @Entity
    public class Product {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
        private String name;
        private Double price;
    
        // getters and setters
    }
  2. Create Repositories: Use Spring Data JPA to handle database interactions.
    package com.example.mymicroservice.repository;
    
    import com.example.mymicroservice.model.Product;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    public interface ProductRepository extends JpaRepository<Product, Long> {
    }
  3. Implement Services: Write business logic in service classes.
    package com.example.mymicroservice.service;
    
    import com.example.mymicroservice.model.Product;
    import com.example.mymicroservice.repository.ProductRepository;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    @Service
    public class ProductService {
    
        @Autowired
        private ProductRepository productRepository;
    
        public List getAllProducts() {
            return productRepository.findAll();
        }
    
        public Product getProductById(Long id) {
            return productRepository.findById(id).orElse(null);
        }
    
        public Product saveProduct(Product product) {
            return productRepository.save(product);
        }
    
        public void deleteProduct(Long id) {
            productRepository.deleteById(id);
        }
    }
  4. Create Controllers: Define REST endpoints to handle HTTP requests.
    package com.example.mymicroservice.controller;
    
    import com.example.mymicroservice.model.Product;
    import com.example.mymicroservice.service.ProductService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    @RestController
    @RequestMapping("/products")
    public class ProductController {
    
        @Autowired
        private ProductService productService;
    
        @GetMapping
        public List getAllProducts() {
            return productService.getAllProducts();
        }
    
        @GetMapping("/{id}")
        public Product getProductById(@PathVariable Long id) {
            return productService.getProductById(id);
        }
    
        @PostMapping
        public Product createProduct(@RequestBody Product product) {
            return productService.saveProduct(product);
        }
    
        @DeleteMapping("/{id}")
        public void deleteProduct(@PathVariable Long id) {
            productService.deleteProduct(id);
        }
    }

Step 4: Apply the Twelve-Factor Methodology

  1. Codebase: One codebase tracked in version control, many deploys. Use a version control system like Git.
  2. Dependencies: Explicitly declare and isolate dependencies. Manage dependencies using Maven or Gradle.
  3. Config: Store config in the environment.
    server.port=8080
    spring.datasource.url=jdbc:mysql://localhost:3306/mydb
    spring.datasource.username=root
    spring.datasource.password=secret
  4. Backing Services: Treat backing services as attached resources. Configure external resources (e.g., databases, message brokers) using environment variables.
  5. Build, Release, Run: Strictly separate build and run stages. Use CI/CD pipelines to automate the build and deployment process.
  6. Processes: Execute the app as one or more stateless processes. Ensure the application is stateless, storing any needed state in a database or external service.
  7. Port Binding: Export services via port binding. Spring Boot applications bind to a port and serve requests.
  8. Concurrency: Scale out via the process model. Scale the application horizontally by running multiple instances.
  9. Disposability: Maximize robustness with fast startup and graceful shutdown. Implement graceful shutdown and ensure the application can handle interruptions.
  10. Dev/Prod Parity: Keep development, staging, and production as similar as possible. Use Docker or similar technologies to ensure consistency across environments.
  11. Logs: Treat logs as event streams. Use a logging framework like Logback and externalize logs to a centralized logging system.
  12. Admin Processes: Run admin/management tasks as one-off processes. Use tools like Spring Boot Actuator for management and monitoring.

Step 5: Testing and Deployment

  1. Write Tests: Implement unit tests, integration tests, and end-to-end tests.
    package com.example.mymicroservice;
    
    import com.example.mymicroservice.model.Product;
    import com.example.mymicroservice.service.ProductService;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import static org.junit.jupiter.api.Assertions.assertNotNull;
    
    @SpringBootTest
    class MyMicroserviceApplicationTests {
    
        @Autowired
        private ProductService productService;
    
        @Test
        void testGetAllProducts() {
            assertNotNull(productService.getAllProducts());
        }
    }
  2. Package and Deploy: Package the application as a JAR or WAR file and deploy it to your server or cloud platform.
    mvn clean package

Step 6: Monitoring and Maintenance

  1. Monitoring: Use tools like Prometheus and Grafana for monitoring application performance.
  2. Logging: Implement centralized logging using tools like ELK Stack (Elasticsearch, Logstash, Kibana).
  3. Security: Regularly update dependencies and use security practices like OAuth2 for authentication and authorization.
By following these steps and adhering to the twelve-factor methodology, you can develop a robust, scalable, and maintainable microservice using Spring Boot.

Friday, July 5, 2024

Building a E-commerce Microservices Architecture with Spring Boot and Spring Cloud


In this article, we will walk through the creation of a scalable microservices architecture for an e-commerce application using Java Spring Boot and Spring Cloud. The architecture includes several services such as Config Server, Eureka Server, API Gateway, Auth Service, Order Service, Inventory Service, and Notification Service with Kafka.

Project Structure

The project is organized into the following structure:
ecommerce-microservices
├── config-server
├── eureka-server
├── api-gateway
├── auth-service
├── order-service
├── inventory-service
├── notification-service
├── docker-compose.yml (optional)
└── README.md
        

Config Server

The Config Server manages external configurations for all microservices.
config-server/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>config-server</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
        
config-server/src/main/resources/application.yml
server:
  port: 8888

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/your-repo/config-repo
        
config-server/src/main/java/com/example/configserver/ConfigServerApplication.java
package com.example.configserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;

@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }
}
        

Why Use Config Server?

Config Server provides a centralized place to manage external properties for applications across all environments. It uses a Git repository to store configuration files, making it easy to version and manage configurations.

How to Deploy and Run Config Server

To deploy the Config Server, ensure you have a Git repository with configuration files. Then, run the application using:
mvn spring-boot:run
This will start the Config Server on port 8888.

Eureka Server

The Eureka Server is a service registry for locating services.
eureka-server/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>eureka-server</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
        
eureka-server/src/main/resources/application.yml
server:
  port: 8761

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
  instance:
    hostname: localhost
        
eureka-server/src/main/java/com/example/eurekaserver/EurekaServerApplication.java
package com.example.eurekaserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
        

Why Use Eureka Server?

Eureka Server acts as a discovery server for registering and locating microservices. This helps in load balancing and makes it easier to scale services dynamically.

How to Deploy and Run Eureka Server

To deploy the Eureka Server, run the application using:
mvn spring-boot:run
This will start the Eureka Server on port 8761.

API Gateway

The API Gateway routes requests to appropriate services.
api-gateway/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>api-gateway</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.2.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
        
api-gateway/src/main/resources/application.yml
server:
  port: 8080

spring:
  application:
    name: api-gateway

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

spring:
  security:
    oauth2:
      resourceserver:
        jwt:
          jwk-set-uri: http://localhost:9000/oauth2/default/.well-known/jwks.json
        
api-gateway/src/main/java/com/example/apigateway/ApiGatewayApplication.java
package com.example.apigateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@SpringBootApplication
@EnableEurekaClient
@EnableResourceServer
public class ApiGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }
}
        
api-gateway/src/main/java/com/example/apigateway/config/SecurityConfig.java
package com.example.apigateway.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;

@Configuration
@EnableResourceServer
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .antMatchers("/h2-console/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .csrf().disable()
            .headers().frameOptions().disable();
    }
}
        

Why Use API Gateway?

The API Gateway handles requests by routing them to the appropriate microservice. It provides a single entry point for the client and helps in securing and managing requests efficiently.

How to Deploy and Run API Gateway

To deploy the API Gateway, run the application using:
mvn spring-boot:run
This will start the API Gateway on port 8080.

Auth Service

The Auth Service handles authentication and authorization using OAuth2.
auth-service/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>auth-service</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
        
auth-service/src/main/resources/application.yml
server:
  port: 9000

spring:
  application:
    name: auth-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driverClassName: org.h2.Driver
    username: sa
    password: password

spring:
  h2:
    console:
      enabled: true

spring:
  jpa:
    hibernate:
      ddl-auto: update
    database-platform: org.hibernate.dialect.H2Dialect
        
auth-service/src/main/java/com/example/authservice/AuthServiceApplication.java
package com.example.authservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;

@SpringBootApplication
@EnableEurekaClient
@EnableAuthorizationServer
public class AuthServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(AuthServiceApplication.class, args);
    }
}
        
auth-service/src/main/java/com/example/authservice/config/AuthorizationServerConfig.java
package com.example.authservice.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;

@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("client-id")
                .secret("{noop}client-secret")
                .authorizedGrantTypes("password", "authorization_code", "refresh_token")
                .scopes("read", "write")
                .accessTokenValiditySeconds(3600)
                .refreshTokenValiditySeconds(36000);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
    }
}
        
auth-service/src/main/java/com/example/authservice/config/WebSecurityConfig.java
package com.example.authservice.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    protected AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    @Bean
    @Override
    protected UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withDefaultPasswordEncoder()
                .username("user")
                .password("password")
                .roles("USER")
                .build());
        return manager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .formLogin()
            .permitAll();
    }
}
        

Why Use Auth Service?

The Auth Service handles user authentication and authorization using OAuth2. It provides secure access to resources by issuing JWT tokens.

How to Deploy and Run Auth Service

To deploy the Auth Service, run the application using:
mvn spring-boot:run
This will start the Auth Service on port 9000.

Order Service

The Order Service manages orders within the e-commerce application.
order-service/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>order-service</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
        
order-service/src/main/resources/application.yml
server:
  port: 9001

spring:
  application:
    name: order-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driverClassName: org.h2.Driver
    username: sa
    password: password

spring:
  h2:
    console:
      enabled: true

spring:
  jpa:
    hibernate:
      ddl-auto: update
    database-platform: org.hibernate.dialect.H2Dialect

spring:
  kafka:
    bootstrap-servers: localhost:9092
    consumer:
      group-id: order-group
        
order-service/src/main/java/com/example/orderservice/OrderServiceApplication.java
package com.example.orderservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class OrderServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderServiceApplication.class, args);
    }
}
        
order-service/src/main/java/com/example/orderservice/model/Order.java
package com.example.orderservice.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String product;
    private int quantity;
    private double price;

    // Getters and setters
}
        
order-service/src/main/java/com/example/orderservice/repository/OrderRepository.java
package com.example.orderservice.repository;

import com.example.orderservice.model.Order;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
}
        
order-service/src/main/java/com/example/orderservice/controller/OrderController.java
package com.example.orderservice.controller;

import com.example.orderservice.model.Order;
import com.example.orderservice.repository.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/orders")
public class OrderController {

    @Autowired
    private OrderRepository orderRepository;

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    private static final String TOPIC = "order-topic";

    @PostMapping
    public Order createOrder(@RequestBody Order order) {
        Order savedOrder = orderRepository.save(order);
        kafkaTemplate.send(TOPIC, "Order created: " + savedOrder.getId());
        return savedOrder;
    }

    @GetMapping("/{id}")
    public Order getOrder(@PathVariable Long id) {
        return orderRepository.findById(id).orElse(null);
    }
}
        

Why Use Order Service?

The Order Service manages all operations related to orders. It uses Kafka to send notifications whenever an order is created.

How to Deploy and Run Order Service

To deploy the Order Service, run the application using:
mvn spring-boot:run
This will start the Order Service on port 9001.

Inventory Service

The Inventory Service manages product inventory within the e-commerce application.
inventory-service/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>inventory-service</artifactId>
    <version>1.0.0</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.kafka</groupId>
            <artifactId>spring-kafka</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
        
inventory-service/src/main/resources/application.yml
server:
  port: 9002

spring:
  application:
    name: inventory-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true

spring:
  datasource:
    url: jdbc:h2:mem:testdb
    driverClassName: org.h2.Driver
    username: sa
    password: password

spring:
  h2:
    console:
      enabled: true

spring:
  jpa:
    hibernate:
      ddl-auto: update
    database-platform: org.hibernate.dialect.H2Dialect

spring:
  kafka:
    bootstrap-servers: localhost:9092
    consumer:
      group-id: inventory-group
        
inventory-service/src/main/java/com/example/inventoryservice/InventoryServiceApplication.java
package com.example.inventoryservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
public class InventoryServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(InventoryServiceApplication.class, args);
    }
}
        
inventory-service/src/main/java/com/example/inventoryservice/model/Inventory.java
package com.example.inventoryservice.model;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Inventory {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String product;
    private int quantity;

    // Getters and setters
}
        
inventory-service/src/main/java/com/example/inventoryservice/repository/InventoryRepository.java
package com.example.inventoryservice.repository;

import com.example.inventoryservice.model.Inventory;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface InventoryRepository extends JpaRepository<Inventory, Long> {
}
        
inventory-service/src/main/java/com/example/inventoryservice/controller/InventoryController.java
package com.example.inventoryservice.controller;

import com.example.inventoryservice.model.Inventory;
import com.example.inventoryservice.repository.InventoryRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/inventory")
public class InventoryController {

    @Autowired
    private InventoryRepository inventoryRepository;

    @Autowired
    private KafkaTemplate<String, String> kafkaTemplate;

    private static final String TOPIC = "inventory-topic";

    @PostMapping
    public Inventory addInventory(@RequestBody Inventory inventory) {
        Inventory savedInventory = inventoryRepository.save(inventory);
        kafkaTemplate.send(TOPIC, "Inventory added: " + savedInventory.getId());
        return savedInventory;
    }

    @GetMapping("/{id}")
    public Inventory getInventory(@PathVariable Long id) {
        return inventoryRepository.findById(id).orElse(null);
    }
}
        

Why Use Inventory Service?

The Inventory Service manages all operations related to inventory. It uses Kafka to send notifications whenever inventory is updated.

How to Deploy and Run Inventory Service

To deploy the Inventory Service, run the application using:
mvn spring-boot:run
This will start the Inventory Service on port 9002.

Communication Between Services

Microservices communicate using REST APIs and Apache Kafka for asynchronous messaging. Services are registered with Eureka and communicate via Eureka Server.

Testing

Unit and integration tests are implemented using Spring Boot Test.
Example test class:
order-service/src/test/java/com/example/orderservice/OrderServiceApplicationTests.java
package com.example.orderservice;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class OrderServiceApplicationTests {

    @Test
    void contextLoads() {
    }

}
        

Directory Structure

Here's the complete directory structure for the project:
ecommerce-microservices/
├── api-gateway/
│   ├── src/main/java/com/example/apigateway/ApiGatewayApplication.java
│   ├── src/main/resources/application.yml
│   └── pom.xml
├── auth-service/
│   ├── src/main/java/com/example/authservice/AuthController.java
│   ├── src/main/java/com/example/authservice/AuthServiceApplication.java
│   ├── src/main/java/com/example/authservice/SecurityConfig.java
│   ├── src/main/java/com/example/authservice/User.java
│   ├── src/main/java/com/example/authservice/UserRepository.java
│   ├── src/main/resources/application.yml
│   └── pom.xml
├── config-server/
│   ├── src/main/java/com/example/configserver/ConfigServerApplication.java
│   ├── src/main/resources/application.yml
│   └── pom.xml
├── eureka-server/
│   ├── src/main/java/com/example/eurekaserver/EurekaServerApplication.java
│   ├── src/main/resources/application.yml
│   └── pom.xml
├── inventory-service/
│   ├── src/main/java/com/example/inventoryservice/InventoryController.java
│   ├── src/main/java/com/example/inventoryservice/Inventory.java
│   ├── src/main/java/com/example/inventoryservice/InventoryRepository.java
│   ├── src/main/java/com/example/inventoryservice/InventoryServiceApplication.java
│   ├── src/main/resources/application.yml
│   └── pom.xml
├── notification-service/
│   ├── src/main/java/com/example/notificationservice/KafkaConsumerConfig.java
│   ├── src/main/java/com/example/notificationservice/KafkaListenerService.java
│   ├── src/main/java/com/example/notificationservice/NotificationServiceApplication.java
│   ├── src/main/resources/application.yml
│   └── pom.xml
├── order-service/
│   ├── src/main/java/com/example/orderservice/OrderController.java
│   ├── src/main/java/com/example/orderservice/Order.java
│   ├── src/main/java/com/example/orderservice/OrderRepository.java
│   ├── src/main/java/com/example/orderservice/OrderServiceApplication.java
│   ├── src/main/resources/application.yml
│   └── pom.xml
├── docker-compose.yml (optional)
└── README.md

Tuesday, July 2, 2024

System Design Concepts and Interview FAQs


System Design involves creating the architecture of a system, considering aspects like scalability, reliability, performance, and maintainability. Here are some core concepts and industry-standard architectures:

Core Concepts in System Design

  • Scalability: The ability of a system to handle increased load by adding resources.
    • Vertical Scaling: Adding more power (CPU, RAM) to an existing machine.
    • Horizontal Scaling: Adding more machines to handle the load.
  • Reliability: Ensuring the system operates correctly even in case of failures.
    • Redundancy: Duplicate critical components or functions to increase system reliability.
    • Failover: Automatic switching to a backup system if the primary system fails.
  • Performance: The system’s ability to handle requests within acceptable time limits.
    • Caching: Storing frequently accessed data in a temporary storage for quick retrieval.
    • Load Balancing: Distributing incoming network traffic across multiple servers.
  • Maintainability: Ease of making changes and extending the system.
    • Modular Design: Dividing a system into smaller, manageable modules.
    • Documentation: Keeping detailed and up-to-date documentation of the system.
  • Security: Protecting the system and data from unauthorized access and breaches.
    • Authentication: Verifying the identity of users or systems.
    • Authorization: Granting permission to resources based on user roles.

Industry-Standard System Design Architectures

  • Monolithic Architecture: All components of the system are packaged together.
    • Easy to develop and deploy initially but can become difficult to manage and scale as the system grows.
  • Microservices Architecture: Breaks down a system into smaller, independent services that communicate via APIs.
    • Facilitates scalability, maintainability, and allows teams to work independently.
  • Event-Driven Architecture: System components communicate through events, enabling asynchronous processing.
    • Useful for applications with complex workflows and real-time updates.
  • Service-Oriented Architecture (SOA): Similar to microservices but with more emphasis on service reusability and communication via an enterprise service bus (ESB).
    • Common in large enterprises with complex IT landscapes.
  • Serverless Architecture: Applications are deployed on third-party servers and managed by cloud providers.
    • Simplifies operations, reduces costs, and allows developers to focus on code without worrying about infrastructure.
  • Layered (N-Tier) Architecture: Organizes the system into layers (presentation, business logic, data access).
    • Promotes separation of concerns and ease of maintenance.
  • Peer-to-Peer (P2P) Architecture: Decentralized architecture where each node (peer) can act as both a client and server.
    • Common in file-sharing and blockchain technologies.
  • Client-Server Architecture: Divides the system into two parts: client (frontend) and server (backend).
    • The server provides services to client requests, commonly used in web applications.

Popular System Designs

  • URL Shortener (e.g., bit.ly)
    • Generate a short, unique alias for a long URL.
    • Handle redirects efficiently.
  • Designing a Web Crawler
    • Traverse the web to collect information for indexing.
    • Handle distributed crawling and data storage.
  • Social Media Feed (e.g., Twitter, Facebook)
    • Display posts from friends/followed users.
    • Efficiently update and retrieve feed content.
  • Messaging System (e.g., WhatsApp, Facebook Messenger)
    • Real-time messaging between users.
    • Manage message delivery, read receipts, and offline storage.
  • Distributed File Storage (e.g., Google Drive, Dropbox)
    • Store and retrieve large amounts of data.
    • Handle replication, consistency, and data retrieval.
  • Ride Sharing Service (e.g., Uber, Lyft)
    • Match riders with drivers in real-time.
    • Handle location tracking, ride pricing, and user management.
  • Video Streaming Service (e.g., YouTube, Netflix)
    • Stream video content to users.
    • Handle video storage, encoding, CDN distribution, and playback.
  • E-commerce Platform (e.g., Amazon, eBay)
    • Manage product listings, shopping carts, and orders.
    • Handle search, recommendation, and payment processing.
  • Search Engine (e.g., Google)
    • Index and search the web for relevant information.
    • Handle ranking algorithms, crawling, and query processing.
  • Notification System (e.g., Email , SMS notifications)
    • Send notifications to users.
    • Handle user preferences, delivery guarantees, and scaling.

FAQs in System Design Interviews

  • What is the difference between vertical and horizontal scaling?
    • Vertical scaling involves adding more resources (CPU, RAM) to an existing machine.
    • Horizontal scaling involves adding more machines to handle the load.
  • How would you design a system to handle a large number of read/write operations?
    • Use caching to reduce read load.
    • Implement sharding to distribute the write load.
    • Consider using a NoSQL database for high write throughput.
  • How do you ensure high availability in a distributed system?
    • Implement redundancy and failover mechanisms.
    • Use load balancers to distribute traffic.
    • Design for fault tolerance by replicating data across multiple nodes.
  • What is eventual consistency?
    • Eventual consistency means that, given enough time, all replicas of a distributed system will converge to the same state.
  • How would you design a rate limiter?
    • Use techniques like token bucket or leaky bucket.
    • Store rate limiting information in a distributed cache (e.g., Redis).
  • What are the trade-offs between consistency and availability in a distributed system?
    • According to the CAP theorem, you can only achieve two out of three: consistency, availability, and partition tolerance.
    • Choosing consistency means you may sacrifice availability during network partitions.
    • Choosing availability means you may have eventual consistency.
  • How would you design a scalable search engine?
    • Use inverted indexes for fast search lookups.
    • Implement distributed crawling and indexing.
    • Use ranking algorithms to provide relevant search results.
  • What is a CDN and how does it work?
    • A Content Delivery Network (CDN) caches content at various edge locations to reduce latency and load on the origin server.
    • It helps in faster content delivery by serving content from a location closer to the user.
  • How do you handle database replication?
    • Use master-slave replication or master-master replication.
    • Ensure data consistency with techniques like two-phase commit or conflict resolution strategies.
  • What are the considerations for designing a caching system?
    • Decide what data to cache based on access patterns.
    • Choose an appropriate eviction policy (e.g., LRU, LFU).
    • Handle cache invalidation strategies to maintain data consistency.

These examples and questions should give you a good foundation for understanding system design and preparing for interviews.

Friday, June 28, 2024

50 Java 8 Interview Programs with Solutions

This blog post presents 50 Java 8 interview programs along with their solutions. These examples demonstrate various features and concepts introduced in Java 8, particularly focusing on streams, lambdas, and functional programming.

1. Find the sum of all numbers in a list using streams

import java.util.Arrays;
import java.util.List;

public class SumOfNumbers {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5);
        int sum = numbers.stream().mapToInt(Integer::intValue).sum();
        System.out.println("Sum: " + sum);
    }
}
    

2. Find the average of numbers in a list using streams

import java.util.Arrays;
import java.util.List;

public class AverageOfNumbers {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5);
        double average = numbers.stream().mapToInt(Integer::intValue).average().orElse(0.0);
        System.out.println("Average: " + average);
    }
}
    

3. Count the number of strings in a list with length greater than 3

import java.util.Arrays;
import java.util.List;

public class CountStrings {
    public static void main(String[] args) {
        List strings = Arrays.asList("a", "ab", "abc", "abcd", "abcde");
        long count = strings.stream().filter(s -> s.length() > 3).count();
        System.out.println("Count: " + count);
    }
}
    

4. Remove all empty strings from a list

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class RemoveEmptyStrings {
    public static void main(String[] args) {
        List strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
        List filtered = strings.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
        System.out.println("Filtered List: " + filtered);
    }
}
    

5. Convert a list of strings to uppercase

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class UppercaseStrings {
    public static void main(String[] args) {
        List strings = Arrays.asList("a", "b", "c", "d", "e");
        List uppercase = strings.stream().map(String::toUpperCase).collect(Collectors.toList());
        System.out.println("Uppercase: " + uppercase);
    }
}
    

6. Find the maximum value in a list of integers

import java.util.Arrays;
import java.util.List;

public class MaxValue {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 5, 3, 8, 2);
        int max = numbers.stream().max(Integer::compare).orElse(0);
        System.out.println("Max value: " + max);
    }
}
    

7. Sort a list of strings in alphabetical order

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class SortStrings {
    public static void main(String[] args) {
        List strings = Arrays.asList("d", "b", "a", "c", "e");
        List sorted = strings.stream().sorted().collect(Collectors.toList());
        System.out.println("Sorted: " + sorted);
    }
}
    

8. Find the first non-repeated character in a string

import java.util.LinkedHashMap;
import java.util.function.Function;
import java.util.stream.Collectors;

public class FirstNonRepeatedChar {
    public static void main(String[] args) {
        String input = "aabbcdeeff";
        Character result = input.chars()
                .mapToObj(ch -> Character.toLowerCase((char) ch))
                .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
                .entrySet()
                .stream()
                .filter(entry -> entry.getValue() == 1L)
                .map(entry -> entry.getKey())
                .findFirst()
                .orElse(null);
        System.out.println("First non-repeated character: " + result);
    }
}
    

9. Check if a number is prime

import java.util.stream.IntStream;

public class PrimeNumber {
    public static void main(String[] args) {
        int number = 17;
        boolean isPrime = number > 1 && IntStream.rangeClosed(2, (int) Math.sqrt(number)).noneMatch(i -> number % i == 0);
        System.out.println(number + " is prime: " + isPrime);
    }
}
    

10. Generate Fibonacci series up to n terms

import java.util.stream.Stream;

public class FibonacciSeries {
    public static void main(String[] args) {
        int n = 10;
        Stream.iterate(new int[]{0, 1}, f -> new int[]{f[1], f[0] + f[1]})
              .limit(n)
              .map(f -> f[0])
              .forEach(i -> System.out.print(i + " "));
    }
}
    

11. Find all pairs of elements in an array whose sum is equal to a given number

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class PairSum {
    public static void main(String[] args) {
        int[] numbers = {2, 4, 3, 5, 7, 8, 9};
        int targetSum = 7;
        
        List pairs = Arrays.stream(numbers)
            .boxed()
            .flatMap(i -> Arrays.stream(numbers)
                .filter(j -> i + j == targetSum && i <= j)
                .mapToObj(j -> i + "," + j))
            .collect(Collectors.toList());
        
        System.out.println("Pairs with sum " + targetSum + ": " + pairs);
    }
}
    

12. Check if a string is a palindrome

import java.util.stream.IntStream;

public class Palindrome {
    public static void main(String[] args) {
        String str = "racecar";
        boolean isPalindrome = IntStream.range(0, str.length() / 2)
            .allMatch(i -> str.charAt(i) == str.charAt(str.length() - 1 - i));
        
        System.out.println(str + " is palindrome: " + isPalindrome);
    }
}
    

13. Find the factorial of a number using streams

import java.util.stream.LongStream;

public class Factorial {
    public static void main(String[] args) {
        int n = 5;
        long factorial = LongStream.rangeClosed(1, n)
            .reduce(1, (long x, long y) -> x * y);
        
        System.out.println("Factorial of " + n + " is: " + factorial);
    }
}
    

14. Find the second largest number in an array

import java.util.Arrays;

public class SecondLargest {
    public static void main(String[] args) {
        int[] numbers = {5, 9, 11, 2, 8, 21, 1};
        
        int secondLargest = Arrays.stream(numbers)
            .boxed()
            .sorted((a, b) -> b.compareTo(a))
            .skip(1)
            .findFirst()
            .orElse(-1);
        
        System.out.println("Second largest number: " + secondLargest);
    }
}
    

15. Remove duplicates from a list

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class RemoveDuplicates {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 2, 4, 3, 5);
        
        List distinctNumbers = numbers.stream()
            .distinct()
            .collect(Collectors.toList());
        
        System.out.println("List without duplicates: " + distinctNumbers);
    }
}
    

16. Find the longest string in a list

import java.util.Arrays;
import java.util.List;

public class LongestString {
    public static void main(String[] args) {
        List strings = Arrays.asList("Java", "Python", "JavaScript", "C++", "Ruby");
        
        String longest = strings.stream()
            .reduce((s1, s2) -> s1.length() > s2.length() ? s1 : s2)
            .orElse("");
        
        System.out.println("Longest string: " + longest);
    }
}
    

17. Count occurrences of each character in a string

import java.util.Map;
import java.util.stream.Collectors;

public class CharacterCount {
    public static void main(String[] args) {
        String str = "programming";
        
        Map charCount = str.chars()
            .mapToObj(ch -> (char) ch)
            .collect(Collectors.groupingBy(ch -> ch, Collectors.counting()));
        
        System.out.println("Character count: " + charCount);
    }
}
    

18. Join a list of strings with a delimiter

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class JoinStrings {
    public static void main(String[] args) {
        List fruits = Arrays.asList("apple", "banana", "cherry", "date");
        
        String joined = fruits.stream()
            .collect(Collectors.joining(", "));
        
        System.out.println("Joined string: " + joined);
    }
}
    

19. Check if all elements in a list are even

import java.util.Arrays;
import java.util.List;

public class AllEven {
    public static void main(String[] args) {
        List numbers = Arrays.asList(2, 4, 6, 8, 10);
        
        boolean allEven = numbers.stream()
            .allMatch(n -> n % 2 == 0);
        
        System.out.println("All numbers are even: " + allEven);
    }
}
    

20. Find the sum of squares of all odd numbers in a list

import java.util.Arrays;
import java.util.List;

public class SumOfSquaresOfOdd {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        
        int sumOfSquaresOfOdd = numbers.stream()
            .filter(n -> n % 2 != 0)
            .mapToInt(n -> n * n)
            .sum();
        
        System.out.println("Sum of squares of odd numbers: " + sumOfSquaresOfOdd);
    }
}
    

21. Convert a list of integers to an array

import java.util.Arrays;
import java.util.List;

public class ListToArray {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5);
        
        int[] array = numbers.stream()
            .mapToInt(Integer::intValue)
            .toArray();
        
        System.out.println("Array: " + Arrays.toString(array));
    }
}
    

22. Find the most frequent element in an array

import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class MostFrequentElement {
    public static void main(String[] args) {
        Integer[] numbers = {1, 2, 3, 2, 4, 2, 5, 3};
        
        Map.Entry mostFrequent = Arrays.stream(numbers)
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
            .entrySet()
            .stream()
            .max(Map.Entry.comparingByValue())
            .orElse(null);
        
        System.out.println("Most frequent element: " + (mostFrequent != null ? mostFrequent.getKey() : "None"));
    }
}
    

23. Check if a string contains only digits

public class OnlyDigits {
    public static void main(String[] args) {
        String str = "12345";
        
        boolean onlyDigits = str.chars()
            .allMatch(Character::isDigit);
        
        System.out.println("String contains only digits: " + onlyDigits);
    }
}
    

24. Find the sum of all even numbers in a range

import java.util.stream.IntStream;

public class SumOfEvenInRange {
    public static void main(String[] args) {
        int start = 1;
        int end = 100;
        
        int sum = IntStream.rangeClosed(start, end)
            .filter(n -> n % 2 == 0)
            .sum();
        
        System.out.println("Sum of even numbers from " + start + " to " + end + ": " + sum);
    }
}
    

25. Reverse the order of words in a sentence

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class ReverseSentence {
    public static void main(String[] args) {
        String sentence = "Hello World Java Programming";
        
        List words = Arrays.asList(sentence.split("\\s+"));
        Collections.reverse(words);
        
        String reversed = words.stream()
            .collect(Collectors.joining(" "));
        
        System.out.println("Reversed sentence: " + reversed);
    }
}
    

26. Find the intersection of two lists

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class ListIntersection {
    public static void main(String[] args) {
        List list1 = Arrays.asList(1, 2, 3, 4, 5);
        List list2 = Arrays.asList(4, 5, 6, 7, 8);
        
        List intersection = list1.stream()
            .filter(list2::contains)
            .collect(Collectors.toList());
        
        System.out.println("Intersection: " + intersection);
    }
}
    

27. Calculate the product of all numbers in a list

import java.util.Arrays;
import java.util.List;

public class ProductOfList {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5);
        
        int product = numbers.stream()
            .reduce(1, (a, b) -> a * b);
        
        System.out.println("Product: " + product);
    }
}
    

28. Find all strings that start with a specific letter

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class StringsStartingWith {
    public static void main(String[] args) {
        List words = Arrays.asList("apple", "banana", "avocado", "cherry", "apricot");
        char startLetter = 'a';
        
        List filteredWords = words.stream()
            .filter(w -> w.toLowerCase().startsWith(String.valueOf(startLetter).toLowerCase()))
            .collect(Collectors.toList());
        
        System.out.println("Words starting with '" + startLetter + "': " + filteredWords);
    }
}
    

29. Calculate the average length of strings in a list

import java.util.Arrays;
import java.util.List;

public class AverageStringLength {
    public static void main(String[] args) {
        List words = Arrays.asList("Java", "Python", "C++", "JavaScript", "Ruby");
        
        double averageLength = words.stream()
            .mapToInt(String::length)
            .average()
            .orElse(0.0);
        
        System.out.println("Average length: " + averageLength);
    }
}
    

30. Find the smallest number in a list that is greater than a given number

import java.util.Arrays;
import java.util.List;

public class SmallestGreaterThan {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 3, 5, 7, 9, 11, 13);
        int target = 6;
        
        int result = numbers.stream()
            .filter(n -> n > target)
            .min(Integer::compare)
            .orElse(-1);
        
        System.out.println("Smallest number greater than " + target + ": " + result);
    }
}
    

31. Group a list of objects by a property

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class Person {
    String name;
    int age;
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class GroupByAge {
    public static void main(String[] args) {
        List people = Arrays.asList(
            new Person("Alice", 25),
            new Person("Bob", 30),
            new Person("Charlie", 25),
            new Person("David", 30)
        );
        
        Map> groupedByAge = people.stream()
            .collect(Collectors.groupingBy(p -> p.age));
        
        System.out.println("Grouped by age: " + groupedByAge);
    }
}
    

32. Find the length of the longest word in a sentence

public class LongestWordLength {
    public static void main(String[] args) {
        String sentence = "The quick brown fox jumps over the lazy dog";
        
        int maxLength = sentence.split("\\s+").length > 0 ?
            sentence.split("\\s+")
                .stream()
                .mapToInt(String::length)
                .max()
                .orElse(0) : 0;
        
        System.out.println("Length of longest word: " + maxLength);
    }
}
    

33. Check if a list contains any element starting with a specific prefix

import java.util.Arrays;
import java.util.List;

public class ContainsPrefix {
    public static void main(String[] args) {
        List words = Arrays.asList("apple", "banana", "cherry", "date");
        String prefix = "ba";
        
        boolean containsPrefix = words.stream()
            .anyMatch(w -> w.startsWith(prefix));
        
        System.out.println("Contains word with prefix '" + prefix + "': " + containsPrefix);
    }
}
    

34. Convert a list of strings to lowercase

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class ToLowerCase {
    public static void main(String[] args) {
        List words = Arrays.asList("HELLO", "World", "JAVA", "Programming");
        
        List lowercaseWords = words.stream()
            .map(String::toLowerCase)
            .collect(Collectors.toList());
        
        System.out.println("Lowercase words: " + lowercaseWords);
    }
}
    

35. Find the sum of digits of a number

public class SumOfDigits {
    public static void main(String[] args) {
        int number = 12345;
        
        int sum = String.valueOf(number)
            .chars()
            .map(Character::getNumericValue)
            .sum();
        
        System.out.println("Sum of digits: " + sum);
    }
}
    

36. Check if a list is sorted

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class IsSorted {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5);
        
        boolean isSorted = numbers.stream()
            .sorted()
            .collect(Collectors.toList())
            .equals(numbers);
        
        System.out.println("Is list sorted: " + isSorted);
    }
}
    

37. Find the kth largest element in an array

import java.util.Arrays;

public class KthLargest {
    public static void main(String[] args) {
        int[] numbers = {3, 2, 1, 5, 6, 4};
        int k = 2;
        
        int kthLargest = Arrays.stream(numbers)
            .boxed()
            .sorted((a, b) -> b.compareTo(a))
            .skip(k - 1)
            .findFirst()
            .orElse(-1);
        
        System.out.println(k + "th largest element: " + kthLargest);
    }
}
    

38. Remove all vowels from a string

public class RemoveVowels {
    public static void main(String[] args) {
        String str = "Hello World";
        
        String result = str.replaceAll("[aeiouAEIOU]", "");
        
        System.out.println("String without vowels: " + result);
    }
}
    

39. Find the common elements between two arrays

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class CommonElements {
    public static void main(String[] args) {
        Integer[] arr1 = {1, 2, 3, 4, 5};
        Integer[] arr2 = {4, 5, 6, 7, 8};
        
        List common = Arrays.stream(arr1)
            .filter(Arrays.asList(arr2)::contains)
            .collect(Collectors.toList());
        
        System.out.println("Common elements: " + common);
    }
}
    

40. Calculate the factorial of a number using reduce

import java.util.stream.LongStream;

public class FactorialUsingReduce {
    public static void main(String[] args) {
        int n = 5;
        
        long factorial = LongStream.rangeClosed(1, n)
            .reduce(1, (long x, long y) -> x * y);
        
        System.out.println("Factorial of " + n + ": " + factorial);
    }
}
    

41. Find the longest palindrome in a string

import java.util.stream.IntStream;

public class LongestPalindrome {
    public static void main(String[] args) {
        String str = "babad";
        
        String longest = IntStream.range(0, str.length())
            .boxed()
            .flatMap(i -> IntStream.rangeClosed(i + 1, str.length())
                .mapToObj(j -> str.substring(i, j)))
            .filter(s -> s.equals(new StringBuilder(s).reverse().toString()))
            .max((s1, s2) -> s1.length() - s2.length())
            .orElse("");
        
        System.out.println("Longest palindrome: " + longest);
    }
}
    

42. Convert a list of integers to a comma-separated string

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class ListToString {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5);
        
        String result = numbers.stream()
            .map(String::valueOf)
            .collect(Collectors.joining(", "));
        
        System.out.println("Comma-separated string: " + result);
    }
}
    

43. Find the sum of squares of even numbers in a list

import java.util.Arrays;
import java.util.List;

public class SumOfSquaresOfEven {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        
        int sum = numbers.stream()
            .filter(n -> n % 2 == 0)
            .mapToInt(n -> n * n)
            .sum();
        
        System.out.println("Sum of squares of even numbers: " + sum);
    }
}
    

44. Check if a number is a perfect square

import java.util.stream.IntStream;

public class PerfectSquare {
    public static void main(String[] args) {
        int number = 16;
        
        boolean isPerfectSquare = IntStream.rangeClosed(1, (int) Math.sqrt(number))
            .anyMatch(i -> i * i == number);
        
        System.out.println(number + " is a perfect square: " + isPerfectSquare);
    }
}
    

45. Find the first repeating element in an array

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class FirstRepeatingElement {
    public static void main(String[] args) {
        Integer[] numbers = {1, 2, 3, 4, 2, 1, 5, 6};
        
        Integer firstRepeating = Arrays.stream(numbers)
            .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
            .entrySet()
            .stream()
            .filter(entry -> entry.getValue() > 1)
            .map(Map.Entry::getKey)
            .findFirst()
            .orElse(null);
        
        System.out.println("First repeating element: " + firstRepeating);
    }
}
    

46. Calculate the product of all odd numbers in a list

import java.util.Arrays;
import java.util.List;

public class ProductOfOdd {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        
        int product = numbers.stream()
            .filter(n -> n % 2 != 0)
            .reduce(1, (a, b) -> a * b);
        
        System.out.println("Product of odd numbers: " + product);
    }
}
    

47. Find the difference between the largest and smallest numbers in a list

import java.util.Arrays;
import java.util.List;

public class LargestSmallestDifference {
    public static void main(String[] args) {
        List numbers = Arrays.asList(5, 2, 8, 1, 9, 3);
        
        int difference = numbers.stream()
            .reduce((a, b) -> Math.max(a, b) - Math.min(a, b))
            .orElse(0);
        
        System.out.println("Difference between largest and smallest: " + difference);
    }
}
    

48. Check if a string contains only unique characters

public class UniqueCharacters {
    public static void main(String[] args) {
        String str = "abcdefg";
        
        boolean hasUniqueChars = str.chars()
            .distinct()
            .count() == str.length();
        
        System.out.println("String has only unique characters: " + hasUniqueChars);
    }
}
    

49. Find the sum of all numbers in a string

public class SumOfNumbersInString {
    public static void main(String[] args) {
        String str = "ab12c3d4ef5";
        
        int sum = str.replaceAll("\\D+", " ")
            .trim()
            .split(" ")
            .length > 0 ?
            str.replaceAll("\\D+", " ")
                .trim()
                .split(" ")
                .stream()
                .mapToInt(Integer::parseInt)
                .sum() : 0;
        
        System.out.println("Sum of numbers in string: " + sum);
    }
}
    

50. Implement a custom Collector to join strings with a delimiter

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collector;

public class CustomCollector {
    public static void main(String[] args) {
        List fruits = Arrays.asList("apple", "banana", "cherry", "date");
        
        String result = fruits.stream()
            .collect(Collector.of(
                StringBuilder::new,
                (sb, str) -> {
                    if (sb.length() > 0) sb.append(", ");
                    sb.append(str);
                },
                StringBuilder::append,
                StringBuilder::toString
            ));
        
        System.out.println("Joined string: " + result);
    }
}
    
These 50 Java 8 interview programs cover a wide range of concepts and techniques. Practice these examples to improve your understanding of Java 8 features and prepare for Java interviews.

If you need any further assistance, such as explanations of specific programs, modifications to the code, or help with implementing these examples, please don't hesitate to ask. Good luck with your Java programming endeavors!

Works

What can I do


Branding

Social media Branding is far and away the best technique a company has to boost engagement with its customer base. Even a minimum of involvement, such as making one post a day.

Web Design

Web design is the process of creating websites. It encompasses several different aspects, including webpage layout, content production, and graphic design.

Development

Web Development refers to building, creating, and an maintaining websites. It includes aspects such as web design, web publishing, web programming and database management.

Graphic Design

Graphic design is the process of visual communication and problem-solving through the use of typography, photography, and illustration. The field is considered a subset of visual communication and communication design.

Photography

Photography is the art, application and practice of creating durable images by recording light or other electromagnetic radiation, either electronically by means of an image sensor, or chemically by means of a light-sensitive material such as photographic film.

User Experience

User experience (UX) design is the process design teams use to create products that provide meaningful and relevant experiences to users. This involves the design of the entire process of acquiring and integrating the product, including aspects of branding, design.

Contact

Get in touch with me


Adress/Street

Bangalore, India