Monday, 30 June 2025

10 years Java8 SpringBoot Interview questions

 

 

Interview Questions

Self Introduction

 

Hi Name,

Good Morning!

My name is Prabhu Prasad, and I am a Tech Lead with over  10 years of experience in software development. I specialize in designing and developing robust business applications using Java, SpringBoot Microservices, and REST APIs. My expertise extends to requirement analaysis, testing, deployment and leveraging AI tools like GitHub Copiot and LLM.

 

DSA 




https://dev.to/iuliagroza/complete-introduction-to-the-30-most-essential-data-structures-algorithms-43kd

 

I. Data Structures

1.     Arrays

2.     Linked Lists

3.     Stacks

4.     Queues

5.     Maps & Hash Tables

6.     Graphs

7.     Trees

8.     Binary Trees & Binary Search Trees

9.     Self-balancing Trees (AVL Trees, Red-Black Trees, Splay Trees)

10. Heaps

11. Tries

12. Segment Trees

13. Fenwick Trees

14. Disjoint Set Union

15. Minimum Spanning Trees

II. Algorithms

16. Divide and Conquer

17. Sorting Algorithms (Bubble Sort, Counting Sort, Quick Sort, Merge Sort, Radix Sort)

18. Searching Algorithms (Linear Search, Binary Search)

 

·        Hash table internal

·        equals and hashcode

 

 

 

 

 

Java 8 features

Streams

Lamda -> anonymous method->NO name,access modifie, return type

to implment functioninternace

 

@FunctionalINteface to avoid to add muiltple mehtods

single abstarct method contains is Finctoin interface.

 In addition to single abstract method, we can have any number of

 default & static methods and even public methods of java.lang.Object class inside a Functional Interface.

Object class methods-> equlas, hashcode, toStirng, wait, notify, notifyall, getClass()

 

 

Default and static methods in interface introduced.

default-> to avoid changing all implemented classes if new functionality added using default method implementation in interface.

 

Abstract classes

still lambda expressions are not for abstract classes

can create instance variables and create construers and static and instance blocks but not in interface.

 

Method reference and lambda expressions are to implement Functional Interfaces

Method Reference is the process of refering pre-exisng method using :: reference is called Method reference ex:

System.out::println

 

Optional

java.Util package

Optional<Object> emptyOptional = Optional.empty()

Optional<String> emailOoptianal = Optional.of(custome.getEmail());

Optional.ofNullable(customer.getEmail());

It check (if (customer.getEmail==null?empty (): of(custm.getEmail())));

To get the Otional value  use get() method.

If(emailOptiaon.isPresent()){

emialOpgioan.get()

}

emialOptiona.orElse(“default value”)

emailOptional.orElseThrow(()->new NoSuchElementError(“email not fouldn”))->Supplier Functional interface

emialOptiona.orElseGet(()->“default value”)

filter()->accepts Predicate Function interface

forEach()-> accepts Consumer Functioal interface

->Function Functional Interface.

 

 

 

Memory allocation.

 



 


 

 


 

 

 

And Permanent Generation-> JVM metadata-. Class structure,Class metadata and all part of heap memroy and fixed one.

Meta space is out of HEAP and can increase based on situation. To avoid outofmemeory issues.

==================

Springboot Autocofiguration

 Java Desing Patterns

Creational Patterns:

·         Factory, Abstract Factory, Builder, Prototype, Singleton

Structural Patterns:

·         Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy

Behavioral Patterns:

·         Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor

 

 

SOLID Design principles

S -> Single Responsibility Principle

·         Every Java class must have single functionality ex: for ptinting passbook sepearet class, for loans seperate class, for sending otp notifications seperate class.

O -> Open & Close Principle

·         Open for extension & Closed for modification

·         Create interface with notification otp an report

·         implement in EmailNOtificatin, Whatsappnotification and MobileMessageNotification classes and implement Notification interface and its methods. sendOtp,sendRepots.

L -> Leskov's Substitution Priciple

·         Derived class must be completely substitutable for their base classes. In other words, if Class A is a subtype of class B, then we should be able to replace B with A without interrupting behavior of the program. For this can create multiple interfaces with related abstract methods and related Calsses can implement only those related interfaces. so can subclass substitues with baseclass or interface.

·         ex: chat, share phots, video call, publishpost

·         Interface1 chat and share methods

·         Interface2 video call, publishpost

·         Insta class implents both interafaces

·         Whatsapp class implemnts Interface1

·         Facebook class implemts both intrfaces

 

I -< Interface Segregation Principle

·         Split larger Interface into smaller  ones. We should not force the client to use the methods that they dont want to use.-> similar to single responsibility.

·         ex: UpiPaymentInterace, CashBackInterface

·         Gpay implemtns both-> sendmOny, scarchcard, cashback

·         PhonPe only UpiPaymentsINteraec->No cash back not forcing. to implment CashBackintefae by splitting it into different interface.

D-> Dependency Inversion Principle

Don't tightly couple with the concrete classes, instead create interface and make it loosely coupled

ex: public class ShoppingMall{

private Debitcatd debitcatrd;

ShoppingMall(Debitcard debitcare){

this.debitcard = debitcard

} doPurchagetn(debitcard){

creditcard.DoTransaction()

main(){

creaet Debit instance or Creditcard instance and call doTrancaitno 

but when we write intefce and implemnt in Debitcasll and Creditcat and imoment DoTransactinmethod and in ShoppingMall class invoke what ever want.

 

Microservices design patterns 

·         Decomposition

·         Strangler

·         API Gateway pattern

 




Outh2->JWT token

 

https://www.autodraw.com/share/0NGELIR3UDHB

 

SpringBootSecurity

 

Till 2.7

public Class SecurityConfig extends WebSecurityConfigurerAdapter{

 

@Override

public void configure(AuthenticationManagerBuilder  auth)thrws Exception{

auth.inMemoryAuthentication()

    .withUser()

    .password()

.roles();

 

auth.inMemoryAuthentication()

    .withUser()

    .password()

.roles();

}

 

public void configure(HttpSecurity  http)thrws Exception{

http.csrf().disable()

.authoriseRequests().antMatchers("/products/welcome").permitAll()

.and

.authoriseRequests().antMatchers("/products/getAllProducts").authenticated()

.and.httpBasic();

}

 

Microservices Design pattern

Aggregator pattern

Database per service

Shared database per service

CommandQueryResponsiblitySegregation(CQRS)

Keep Read and Write Opeations(Mircro services in different or seggregated)

to get the high throught put or out come. can be flexible for scaling.

ex: Flipkart or amazon sale offer-> search(read opreations are more)->Write operations are less(buy product)-> to keep both servies in sync use Messaging system(Kafka).

Saga Pattern-> Choreography Saga pattern -> introduces Kafka in between microservices instead of using multiple Http requests.

Microservices:

Log Aggregation

Externalized configuration

Service Registry & Service Discovery

Circuit Breaker

Loose coupling

High Cohesion

Side car pattern

 

Micro services Fallout Scenarios handling

 

For system or data faliure reqeusts 

Can maintain Dead letter queue and Fallout queue so that can reprocess them after few retries and to unblock other requests.

Understand scope of the problem

    Health checks: actuator /health, /status

    @Component

    public class MyCustomHealthIndicator implements HealthIndicator {

 

        @Override

        public Health health() {

1. Understand the Scope of the Problem:

·         Detection: The first step is to detect that a microservice is down. This requires robust monitoring and alerting.

    • Health Checks: Implement health check endpoints in each microservice (e.g., /health, /status). These endpoints should return a 200 OK status if the service is healthy and an error status if it's not.
    • Monitoring Tools: Use monitoring tools (e.g., Prometheus, Grafana, Datadog, New Relic) to periodically check the health check endpoints of each service.
    • Alerting: Configure alerts to notify you when a service's health check fails or when other metrics (e.g., CPU usage, memory usage, error rate) exceed a certain threshold.
  • Isolation: Ensure that the failure of one microservice doesn't cascade and bring down other services.

2. Implement Fault Tolerance Patterns:

·         Circuit Breaker:

    • Purpose: To prevent a client from repeatedly trying to call a failing service, which can waste resources and potentially overload the failing service.
    • How it Works: The circuit breaker monitors the number of failures. If the failure rate exceeds a certain threshold, the circuit breaker "opens," and subsequent calls to the service are immediately failed without even attempting to connect. After a certain amount of time, the circuit breaker enters a "half-open" state, where it allows a limited number of calls to the service to see if it has recovered. If the calls succeed, the circuit breaker "closes" and normal operation resumes.
    • Libraries: Hystrix (Netflix, now in maintenance mode), Resilience4j (more actively maintained).
  • Retry:
    • Purpose: To automatically retry failed requests to a service, in case the failure was transient (e.g., a temporary network glitch).
    • How it Works: When a request fails, the client automatically retries the request after a certain delay. The delay can be fixed or exponential (increasing with each retry).
    • Considerations: Be careful about retrying requests that are not idempotent (i.e., requests that have side effects). Retrying a non-idempotent request could lead to unintended consequences (e.g., creating duplicate orders).
  • Fallback:
    • Purpose: To provide an alternative response when a service is unavailable.
    • How it Works: When a request fails, the client executes a fallback function that provides a default value, retrieves data from a cache, or performs some other action.
    • Example: If a product catalog service is down, the client could display a cached version of the catalog or a default set of products.
  • Bulkhead:
    • Purpose: To isolate different parts of your application so that a failure in one part doesn't affect other parts.
    • How it Works: The bulkhead pattern limits the number of concurrent calls to a service. This prevents a single failing service from consuming all of the resources of the calling service.
  • Rate Limiting:
    • Purpose: To prevent a client from overwhelming a service with too many requests.
    • How it Works: The rate limiting pattern limits the number of requests that a client can make to a service within a certain time period. This can help to protect services from denial-of-service attacks and prevent them from becoming overloaded.

3. Design for Idempotency:

  • Definition: An operation is idempotent if it can be executed multiple times without changing the result beyond the initial application.
  • Importance: Designing your services to be idempotent makes it much easier to handle failures and retries. If an operation is idempotent, you can safely retry it without worrying about unintended side effects.
  • Example: An operation to set the quantity of an item in a shopping cart to 5 is idempotent. An operation to increment the quantity of an item in a shopping cart is not idempotent.

4. Implement Asynchronous Communication:

  • Message Queues: Use message queues (e.g., RabbitMQ, Kafka, ActiveMQ) to decouple services and enable asynchronous communication.
    • Benefits: If a service is down, the messages will be queued and delivered when the service comes back online. This improves the resilience of the system and prevents data loss.
  • Eventual Consistency: Embrace eventual consistency, which means that data might not be immediately consistent across all services, but it will eventually become consistent.

5. Use Service Discovery and Load Balancing:

  • Service Discovery: Use a service discovery mechanism (e.g., Consul, etcd, ZooKeeper, Kubernetes DNS) to allow services to dynamically locate each other.
  • Load Balancing: Use a load balancer (e.g., Nginx, HAProxy, Kubernetes Service) to distribute traffic across multiple instances of a service.
    • Benefits: If one instance of a service goes down, the load balancer will automatically redirect traffic to the remaining instances.

6. Implement Proper Monitoring and Logging:

  • Centralized Logging: Use a centralized logging system (e.g., ELK stack, Splunk) to collect and analyze logs from all services.
  • Distributed Tracing: Use distributed tracing (e.g., Jaeger, Zipkin) to track requests as they flow through the system.
    • Benefits: This makes it easier to identify the root cause of failures and to monitor the performance of the system.

7. Use Container Orchestration (e.g., Kubernetes):

  • Self-Healing: Container orchestration platforms like Kubernetes provide self-healing capabilities, such as automatically restarting failed containers.
  • Scaling: They also make it easy to scale services up or down based on demand.
  • Service Discovery: Kubernetes provides built-in service discovery and load balancing.

8. Consider a Service Mesh (e.g., Istio, Linkerd):

  • Traffic Management: Service meshes provide advanced traffic management capabilities, such as traffic shaping, canary deployments, and A/B testing.
  • Security: They also provide security features, such as mutual TLS authentication and authorization policies.
  • Observability: Service meshes enhance observability by providing detailed metrics and traces.

Example Scenario (Order Service Depends on Payment Service):

  1. Payment Service Down: The Payment Service becomes unavailable.
  2. Order Service Detects Failure: The Order Service's health checks to the Payment Service start failing.
  3. Circuit Breaker Opens: The Circuit Breaker in the Order Service opens, preventing further calls to the Payment Service.
  4. Fallback Mechanism: The Order Service uses a fallback mechanism:
    • If the payment was already attempted and failed, the Order Service displays an error message to the user, suggesting they try again later.
    • If the payment hasn't been attempted yet, the Order Service queues the order for later processing (using a message queue) and notifies the user that their order is pending.
  1. Monitoring and Alerting: The monitoring system alerts the operations team about the Payment Service failure.
  2. Payment Service Recovery: The operations team fixes the Payment Service issue, and it comes back online.
  3. Circuit Breaker Closes: The Circuit Breaker in the Order Service closes, and normal communication with the Payment Service resumes.
  4. Queued Orders Processed: The Order Service processes the queued orders.

Key Takeaways:

  • Proactive Monitoring: Invest in robust monitoring and alerting to detect failures quickly.
  • Embrace Fault Tolerance: Implement fault tolerance patterns to prevent failures from cascading and to provide a good user experience.
  • Design for Resilience: Design your services to be resilient to failures. This includes using asynchronous communication, service discovery, and load balancing.
  • Automate Recovery: Automate as much of the recovery process as possible to reduce downtime.
  • Continuous Improvement: Continuously monitor and improve your failure handling strategies.

 

 

 

normalization basics

 JWT TOCKEN SpringSecurity-> GCP cloud run

GCP apigee gatway

document db basics

install docment db and nosql

 

check for AWS serices

ECS, S3, TERRFORM, LAMDA

k8 kubeclt commands

to create build and push and pull commands

deploy

get

scale

replica

logs

all kubectl commands

service,

deply file

pods files and all.

configmap files.

 

Hibernate caches

    • Client-> 1time queried DB
    •             ->Same session 2 time quired DB-> fetch data it from 1st level cache.->HIbernate provides it by default.
    • Same User or Another user in different or 2nd session-> same query-> it doest not have data in first level cache of session2 so it agian hits db.-> need to go for 2nd level cache.
    • ->All the sessions can use 2nd level cache-> thirdparty caches ehcache, OS, swam
    • Jpa save and persist methods and all..

@Persistance context by EntityManager

    • creates or saves new reocrd, if any already record exist with id-> thorows exception, doesn't update it.
    • doesn't not return any entity
    • Standard JPA 

 

 

 

 

 

Reactive programming->

Event looping

Unsynchronous and Nonblocking.

Can accept multiple request for a thread -> and subscribe to db  for respposne

DataFlow as eveng driven stream

Subscribe to db-> if any udpates happened to DB also we can get the all update data. Ex: Live Cricket score board.

Back pressure on data streams-> app can tell to db wait for some time until I process existing records.

PubSub Mono

 

Kafka: Distributed messaging system.

·         acks=0

·         acks=all or acks=-1

·         Properties props = new Properties();

·         props.put("bootstrap.servers", "kafka1:9092,kafka2:9092,kafka3:9092");

·         props.put("acks", "all");

·         props.put("retries", 3);

·         props.put("enable.idempotence", "true");

·         props.put("max.in.flight.requests.per.connection", "1");

·         props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");

·         props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

·         props.put("delivery.timeout.ms", "120000");

 

·         ProducerRecord<String, String> record = new ProducerRecord<>("my-topic", "key", "value");

·         producer.send(record, (metadata, exception) -> {

Checklist for Ensuring Message Delivery:

·         Set acks=all (or acks=-1) on the producer.

·         Set retries to a reasonable value (e.g., 3-10) on the producer.

·         Enable enable.idempotence=true on the producer (Kafka >= 0.11).

·         Set max.in.flight.requests.per.connection=1 on the producer (in combination with idempotence and acks=all).

·         Set delivery.timeout.ms to a sufficiently high value on the producer.

·         Set replication.factor to 3 (or higher) on the topic.

·         Set min.insync.replicas to 2 (or higher) on the topic.

Spring Boot Optimization

Optimize Configuration

1.      Use Profiles-> for env speicific config

2.     Avoid over config-> Use auto configuration feature

3.     Lazy initialization(spring.main.lazy-initialization=true)

Improve Database Performance

1.     Use connection pooling

2.     Indexing

3.     Use cache

4.     Batch Operations

Optimize JVM & Garbage collection

JMV tuning-> approprate heap size -Xmx - Xms

Garbage collector algorithem ->ZGC

 

Reduce start up time

Remove unused starters

@Component scan liimt to package

Customer Banner

 

Optimize application logic

Avoid heavy logic in Controllers ->Logic shouldbe in service layer instead of controller layer.

Efficient data structures

Use nAysnc or Reactive or  parlell processing-> non blocking operations.

 

Optiimze API Performance

GZIP compression-> Enable compression to reduce response time(server.compresssion.enable=true)

Pagination and filtering

Timeouts and Retries

 

Optimize Security

Disable unused Features-> deisbale unused actuators endpoints in production

Use stateliess sission

Toien based authentication

 

Use Monitoring and Profiling tools

ELK, Actuator, 

Jprofiler

 

Optimse Deployment

 -> use Docker, K8

Scale Horizantally by deploying multiple instances

Use  Cloud native 

 

 

Regular cdoe and dependcney updates-> remvoe dead code

 

----------------------------------------------------------------------------

 



Advantages of Microservices

1.      Scalability->independently.

2.      Flexibility in tech stack-> different services can use different programming language

3.      Faster Development & Deployment->Teams can work parlally independtly on different services, independent deployment.

4.      Improved fault Isolation-> one service fail -> less impact in entire system.

5.      Easier Maintance and Debugging-> Debugging and testing individual services are easier, simpler compared to Monolithic.

6.      Agility & Faster time to Market->Supports shorter deployment cycles  due to decoupled components.

7.      Team Autonomy-> Team can own speicific services-> increase productivity.

Challenges of using Microservices

 

1.      Increased complexity->  managing mulitple services introduing complexity in communication, deployment and monitoring

2.      Network latency & Reliability-> communication  in network latency and failures disrupt system.

3.      Data Management-> Managing distributed data across multipe services is challendgin-> event or SagaPattern

4.      DevOps overhead-> complex in configuring and managing containiration and orchestration tools

5.      Security-> more services  means more surface for attackers.

6.      Cost-> additioanl infra for cont, orche and logging

7.      Team Coordination

 

K8 Features

1.      Container Orchestration->Automatically schedules and manages deployments of containers accross cluster of machines

2.      Scalbility

3.      Load Balancing, High availability

4.      Self Healing-> Restarts contianer-> kills container that donot respond fto health checks.

5.      Declarative configuration-> Cofigmap, secret map, YML

6.      Service Discovery->DNS nanes with out IP address, with service names finds other services.

7.      Automated rollout and rollbaceks

8.      Monitoring and logging

9.      Extensiblity

10.  HIgh availabilty

11.  Resource ooptimization-> Uses quitosa nd liimts to contorl the resuorceon pod and namespace level.

12.  CICD integration

13.  cli(command line interface)

14.  Faoult tolrance-> redistributes load from falied nodes to healthy ones.



Micro services 12 factors

1.      OneCodebase-> one code base for service and deployble to multiple envs.

2.      Dependencies-> Explicitlyl declare and Isolate dependencies to enseure consistency

3.      Configuraiton-> Speerate from code base-> env variables

4.      Backing services-> DBs & message brokcers as attached resources->flexiblity replace.

5.      Build,Relsae, Run-> CI/CD automates

6.      Processes-> exceute app in stateless proces and persiste data in exteranl  backing servies.

7.      Port Binidg->Export services via prot to enable external comminiation.

8.      Concurrncy-> k8 scaling of mulitple serices.

9.      Disposiblity-> Maximize roubustness with  fast startups and graceful shutdownd.

10.  Dev/Prod Parity-> all envs shuld be similar configuration

11.  Logs->event streaming-> ELK

12.   Admin processes-> Use job scheduler to run backgrouknd tasks->seperate process.




HttpHeaders headers = new HttpHeaders();

headers.set("Authorization", "Bearer " + jwt);

HttpEntity<String> request = new HttpEntity<>(headers);

String response = restTemplate.exchange(userServiceUrl, HttpMethod.GET, request, String.class).getBody();



spring.security.oauth2.resourceserver.jwt.issuer-uri=https://auth.example.com

spring.security.oauth2.resourceserver.jwt.audience=service-name


@Configuration

public class SecurityConfig extends WebSecurityConfigurerAdapter {


    @Override

    protected void configure(HttpSecurity http) throws Exception {

        http

            .csrf().disable()

            .authorizeRequests()

                .antMatchers("/public/**").permitAll()

                .anyRequest().authenticated()

            .and()

            .oauth2ResourceServer()

                .jwt();

    }

}