| Mechanism | Detail |
|---|---|
| Spring Boot 2.x | META-INF/spring.factories lists all EnableAutoConfiguration candidate classes. |
| Spring Boot 3.x | META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports replaces spring.factories for auto-configuration (faster startup, no per-class instantiation to check conditions). |
| @ConditionalOnClass | Bean is registered only if the given class is present on the classpath. |
| @ConditionalOnMissingBean | Backs off if the developer already defined a bean of that type — this is exactly how you override an auto-configured bean. |
| @ConditionalOnProperty | Bean created only if a property matches (e.g. management.endpoint.health.enabled=true). |
| @AutoConfigureAfter/Before | Orders auto-configuration classes relative to each other. |
spring-boot-devtools) adds: automatic restart on classpath change, LiveReload browser refresh, and disables template caching — excluded automatically from production repackaged JARs.@SpringBootApplication annotation?@SpringBootApplication annotation will it work ?@SpringBootApplication ?used on the main class to bootstrap and start a Spring Boot application, combining @Configuration, @EnableAutoConfiguration, and @ComponentScan into a single annotation.
if No @SpringBootApplication β Application may not work properly if Add: @Configuration, @EnableAutoConfiguration, @ComponentScan β Works exactly the same
@Configuration β Marks the class as a source of Spring bean definitions.@EnableAutoConfiguration β enables the Auto-Configuration mechanism & Auto-configures the Spring Boot based on the dependencies/libraries available in the classpath.@ComponentScan β Scans packages for Spring components (@Component, @Service, @Repository, @Controller) and registers them as Spring beans.Internal Flow:
@SpringBootApplication.@EnableAutoConfiguration is triggered.@ConditionalOnClass - @ConditionalOnMissingBean - @ConditionalOnPropertyStartup Flow:
Both CommandLineRunner and ApplicationRunner execute code once after the Spring Boot application context is initialized. The difference is that : CommandLineRunner uses raw String... args, whereas ApplicationRunner uses the ApplicationArguments API for structured access to command-line arguments.
Reduce Spring Boot startup time by enabling lazy initialization (spring.main.lazy-initialization=true), minimizing component scanning scope, avoiding unnecessary auto-configurations, excluding unneeded starters, and considering AOT/native compilation (Spring Native/GraalVM) for the most significant improvement.
Specific Auto-Configurations can be excluded using the exclude attribute of @SpringBootApplication or the spring.autoconfigure.exclude property in application.properties. This is commonly done when the default auto-configuration is not needed or a custom implementation is being used. @SpringBootApplication( exclude = {DataSourceAutoConfiguration.class} )
We can override an auto-configured bean by defining our own bean of the same type using @Bean method in a @Configuration class. Spring will use the custom bean instead of the auto-configured one (provided the auto-configuration is conditional).
Starter dependencies are predefined dependency packages that contains required libraries for a specific functionality : spring-boot-starter-web manual dependency management requires developers to add and maintain each dependency and its version individually. : jjwt-api
spring-boot-starter-parent is the parent POM provided by Spring Boot. It manages dependency versions, plugin configurations, and default build settings, so we don't have to specify compatible versions manually.
We can disable the embedded web server by configuring the application as non-web. Using application.properties: spring.main.web-application-type=none
Yes. Spring Boot can be used to create a non-web application by disabling the web server using spring.main.web-application-type=none or WebApplicationType.NONE. This is commonly used for batch jobs, scheduled tasks, CLI applications, or Kafka consumers.
Spring Boot uses Tomcat as the default embedded server. To replace it, we exclude spring-boot-starter-tomcat and add another embedded server dependency such as spring-boot-starter-jetty or spring-boot-starter-undertow.
If I don't want to use an embedded server, I can package the application as a WAR file, exclude the embedded Tomcat dependency, and deploy it to an external application server such as Apache Tomcat, JBoss/WildFly, or WebLogic.
Spring Boot supports multiple embedded servers. The default is Tomcat, and it also supports Jetty and Undertow. It can also be deployed as a WAR file to external application servers.
JAR (Java ARchive) is a standalone executable package that contains an embedded server like Tomcat. WAR (Web ARchive) is deployed to an external application server such as Tomcat, JBoss, or WebLogic.
Dependency Injection (DI) is a design pattern where Spring creates and injects dependent objects (beans) into a class instead of the class creating them itself, reducing tight coupling and improving maintainability.
Internally :
@ComponentScan to scan classes annotated with @Component, @Service, @Controller, and @Repository.@Autowired or Constructor Injection.@Component, @Controller, @Service, and @Repository?@Component β Generic bean. Create an bean of this class and manage its lifecycle in the Spring IoC Container.@Controller β Handles HTTP requests in Spring MVC and returns a view (or works with @ResponseBody).@Service β Business logic layer.@Repository β Database layer and provides exception translation for persistence exceptions.A Spring Bean is an object that is created, managed, and maintained by the Spring IoC Container.
@Autowired or Constructor Injection.@PostConstruct, init-method).@PreDestroy, destroy-method).singleton β One object/bean for Spring container (Default) - ApplicationContext prototype β New object/bean every request to Spring container - ApplicationContext request β One object/bean per HTTP request session β One object/bean per user session applicationβ One object/bean per web application - ServletContext websocket β One object/bean per WebSocket session
@Resource Annotation?β’ @Resource is a Jakarta dependency injection annotation used to inject beans into a Spring-managed class. It performs dependency injection by bean name first and falls back to type-based resolution if no matching bean name is found.
@Configuration and @Component?a @Component creates a Spring-managed bean a @Configuration is used to define and manage other beans through @Bean methods.
Spring stores all managed beans in the ApplicationContext. We can retrieve all bean names using applicationContext.getBeanDefinitionNames() and the total number of beans using getBeanDefinitionCount(). For runtime inspection, Spring Boot Actuator also provides the /actuator/beans endpoint.
@Component -> Generic Spring bean@Service -> Business logic layer@Repository -> Data access layer@Controller -> MVC controller@RestController -> REST API controller (@Controller + @ResponseBody )@Autowired -> Inject dependency@Qualifier -> Select a specific bean when multiple exists@Primary -> Default bean among multiple candidates@Bean -> Creates a bean manually@Configuration -> Configuration class containing @Bean methods@ComponentScan -> Scans packages for Spring components@Value -> Inject property values@Scope -> Defines bean scope (Singleton, Prototype, etc.)@PostConstruct -> Executes after bean initialization@PreDestroy -> Executes before bean destructionWithout stereotype annotations (@Component, @Service, @Repository, @Controller), Spring's component scanning won't detect the class as a bean, so it won't be registered in the application context, and any attempt to @Autowire it elsewhere will fail with a NoSuchBeanDefinitionException.
Common Spring Boot annotations include @SpringBootApplication (entry point), @RestController/@Controller, @Service, @Repository, @Component, @Autowired, @RequestMapping/@GetMapping/@PostMapping, @Transactional, and @Configuration/@Bean - each marks a class's role or wires behavior for Spring to manage automatically.
These annotations let Spring auto-detect, instantiate, and wire components without manual configuration - they declare intent (this is a service, this is a REST endpoint) so Spring's component scanning and dependency injection can manage the object lifecycle and relationships automatically, reducing boilerplate.
The IoC Container is the core of Spring that manages the lifecycle and configuration of application objects (beans) - it creates, wires (injects dependencies into), and manages beans based on configuration (XML, annotations, or Java config), implemented via BeanFactory (basic) or ApplicationContext (advanced, most commonly used).
Spring bean scopes control how many instances of a bean are created: singleton (one instance per container, default), prototype (new instance every time it's requested), and web-aware scopes like request, session, and application for web applications.
A circular dependency occurs when two or more beans depend on each other (directly or through a chain). Spring can usually resolve this for singleton beans via setter injection (partially constructed beans exposed early), but constructor injection circular dependencies fail at startup - resolved by refactoring the design, using @Lazy, or switching to setter injection.
--server.port=8081)SPRING_APPLICATION_JSON / JNDI attributesapplication-{profile}.properties / .yml (profile-specific, outside jar > inside jar)application.properties / .yml (outside jar > inside jar)@PropertySource on @Configuration classesSpringApplication.setDefaultProperties@Value?Values from application.properties or application.yml can be accessed using @Value, @ConfigurationProperties, or the Environment interface. Single Property β @Value("${app.name}") Multiple Properties β @ConfigurationProperties(prefix = "app") Dynamic Access β Environment (String appName = environment.getProperty("app.name"); )
Spring Profiles are used to manage environment-specific configurations and beans for different environments such as Development, Testing, STQA, and Production. Example : application-dev.properties, application-stqa.properties, and application-prod.properties Activate a profile: spring.profiles.active=dev
A specific Spring Profile can be activated using the spring.profiles.active property, which tells Spring Boot which environment configuration to load.
application-dev.properties is used to store environment-specific configuration settings for the Development environment.
REST (REpresentational State Transfer) is an architectural style for web services that enables communication between client and server using HTTP methods such as GET, POST, PUT, and DELETE. GET β Retrieve data POST β Create data PUT β Update entire resource PATCH β Partial update DELETE β Delete data
@RequestParam?β’ @RequestParam is used to extract query parameter values from the request URL path and bind them to method parameters. eg: /employee?id=101 UseCase: filter, search, sort, paginate, or pass optional data
Pagination is a technique used to retrieve data in smaller chunks (pages) instead of loading all records at once, improving performance and reducing memory consumption. Pagination is implemented using Spring Data JPA's Pageable interface and Page<T> response.
Sorting is the process of retrieving data in a specific order based on one or more fields, such as ascending or descending order. Sorting is implemented using Spring Data JPA's Sort class OR by combining Pageable with sorting parameters.
Spring MVC is a web framework that follows the Model-View-Controller pattern to build server-side web applications by returning views like JSP or Thymeleaf. REST is an architectural style used to build stateless web services that return data, typically in JSON or XML format.
In Spring Boot, JSON conversion is handled automatically by HttpMessageConverter. By default, Spring Boot uses the Jackson library to convertJava objects to JSON and JSON to Java objects.
A POST API is created using the @PostMapping annotation. It is typically used to create new resources in the database. The request data is typically received using @RequestBody, processed in the Service layer, saved through the Repository layer, and a response is returned to the client.
Inject a RestTemplate or WebClient bean into the service class and use it to make the HTTP call (e.g., restTemplate.getForObject(url, ResponseType.class)), keeping the call encapsulated within the service layer rather than the controller so business logic and external integration stay separated.
HandlerInterceptor is a Spring MVC interface used to intercept HTTP requests before, after, or once a controller handler completes (preHandle, postHandle, afterCompletion) - commonly used for cross-cutting concerns like logging, authentication checks, or request timing without modifying controller code.
Global exception handling is implemented using @ControllerAdvice and @ExceptionHandler. It centralizes exception handling across the application and returns consistent error responses to clients.
@ControllerAdvice?β’ @ControllerAdvice β Handles exceptions globally across all controllers. It works with @ExceptionHandler to catch exceptions from all controllers and return a common error response.
@Valid vs @Validateda @Valid is used for basic bean validation a @Validated extends it by supporting validation groups and method-level validation.
Custom exceptions are handled by creating a custom exception class that extends RuntimeException and implementing global exception handling using @ControllerAdvice and @ExceptionHandler, which returncustomerrorresponses.
| Propagation | Behavior |
|---|---|
| REQUIRED ⭐ | Join existing transaction, or create a new one if none exists (default). |
| REQUIRES_NEW | Always suspends the current transaction and starts a brand-new one — used for audit-logging that must persist even if the outer transaction rolls back. |
| SUPPORTS | Joins if a transaction exists, otherwise runs non-transactionally. |
| MANDATORY | Must run inside an existing transaction, else throws an exception. |
| NOT_SUPPORTED | Suspends any existing transaction and runs non-transactionally. |
| NEVER | Throws an exception if a transaction already exists. |
| NESTED | Runs within a savepoint of the outer transaction — a failure here can roll back to the savepoint without rolling back the whole outer transaction. |
| Isolation Level | Prevents |
|---|---|
| READ_UNCOMMITTED | Nothing — allows dirty reads. |
| READ_COMMITTED ⭐ | Dirty reads (DB default for most engines, incl. PostgreSQL/Oracle). |
| REPEATABLE_READ | Dirty reads + non-repeatable reads (MySQL InnoDB default). |
| SERIALIZABLE | Dirty, non-repeatable & phantom reads — safest, slowest, transactions effectively run one at a time. |
@Version)OptimisticLockException. Best for low-contention, high-read scenarios (no DB lock held).SELECT ... FOR UPDATE)UPDATE at flush time — no explicit save() call needed inside a transaction. Flush vs Commit: flush synchronizes the persistence context with the DB (sends SQL) but doesn't end the transaction; commit ends the transaction (making changes durable) and triggers a flush first. save() just schedules the entity for persistence at next flush; saveAndFlush() forces an immediate flush — useful when you need the DB-generated ID or a trigger-computed value right away.CrudRepository provides basic CRUD operations JpaRepository provides CRUD operations along with advanced JPA features such as pagination and sorting.
@Query annotation?β’ @Query is used to write custom JPQL or native SQL queries in a repository when derived query methods are not sufficient.
JPQL is an object-oriented query language that works with JPA entities and their fields. SQL works directly with database tables and columns.
The N+1 query problem occurs when Hibernate executes one query to fetch the parent entities and then executes one additional query for each parent entity to fetch its related child entities, resulting in a total of N+1 queries. causes performance issues due to excessive database calls.
Example: Suppose we have a Department entity, and each department has multiple Employee entities. When we fetch all departments, Hibernate executes one query to fetch the departments and then one additionalquery for the employees of eachdepartment. If there are N departments, a total of N+1 queries are executed. This performance issue is called the N+1 Query Problem.
@Transactional work internally?@Transaction needed?.β’ @Transactional is used to ensure data consistency by treating multiple database operations as a single unit of work. If alloperations succeed, the transaction is committed; if anyoperation fails, all changes are rolled back.
Internally, Spring uses AOP to create a proxy for methods annotated with @Transactional. Every call first goes to the proxy, which starts the transaction, executes the business method, and then commits the transaction if everything succeeds or rolls it back if an exception occurs.
Spring's @Transactional (and @Async, @Cacheable, etc.) works via proxies - when a method calls another method on 'this' within the same class, the call bypasses the proxy entirely and goes directly to the target object, so the transactional advice never gets applied. Fix by calling through a self-injected proxy, or moving the method to a separate bean.
@Transactional is present but rollback did not happen. Why?If @Transactional doesn't roll back, I check the exception type(it should be unchecked exception), ensure the exception isn't swallowed, verify proxy-based transaction behavior (such as self-invocation), and configure rollbackFor when handling checked exceptions.
This is usually caused by a LazyInitializationException. It happens when a lazily loaded entity is accessed after the Hibernate session has been closed. It may work locally because of different configurations (such as Open Session in View enabled), but fail in production where the session is closed before the lazy association is accessed.
JPA is a specification that defines standards for ORM in Java, while Hibernate is the most popular implementation of JPA. In Spring Boot, we usually write code using JPA APIs, and Hibernateperforms the actual database operationsbehind the scenes.
Data is retrieved from the database using the Repository layer. The Controller calls the Service layer, the Service calls the Repository, and the Repository fetches the data from the database using JPA/Hibernate.
Database connectivity in Spring Boot is configured using datasource properties. During startup, Spring Boot reads these properties, creates a DataSource bean, configures a connection pool (HikariCP by default), and provides databaseconnections to JPA or JDBC components.
In Spring Boot, multiple data sources are configured by defining separate DataSource beans for each database and, when using JPA, separate EntityManagerFactory and transaction manager configurations. @Primary defines the default data source and @Qualifier allows explicit selection. Each repository package can then be associated with the appropriate EntityManager. Common use cases include multiple databases, read/write separation, legacy database integration, and reporting databases. In microservices, however, the preferred approach is usually database-per-service rather than having one service directly access multiple service-owned databases.
Spring integrates with JDBC through JdbcTemplate, which handles boilerplate like opening/closing connections, exception translation into Spring's DataAccessException hierarchy, and resource cleanup, letting you focus on writing SQL and mapping results via RowMapper instead of manual JDBC plumbing.
| Mechanism | Use |
|---|---|
| hasRole() / hasAuthority() | URL-level authorization inside SecurityFilterChain config. |
| @PreAuthorize | Method-level, evaluated before invocation — supports SpEL, e.g. @PreAuthorize("hasRole('ADMIN')"). |
| @PostAuthorize | Evaluated after method execution — can inspect the return value. |
| @Secured | Simpler, legacy role-based method security (no SpEL). |
| @EnableMethodSecurity | Enables method-level annotations (Spring Security 6+). |
Spring Security is a framework that provides authentication, authorization, and protection against common security vulnerabilities for Spring applications.
Authentication is the process of verifying the identity of a user before granting access to an application, ensuring that the user is who they claim to be. User enters username and password -> System validates the credentials -> If valid, the user is authenticated.
For example, in the Candidate Registration Portal, when a candidate enters a username and password, the Authentication Service verifies the credentials. If they are valid, the user is authenticated and allowed to access the portal.
Authentications Different Methods:
Authorization is the process of determining what resources or actions an authenticated user is allowed to access/perform.
For example, in the Candidate Registration Portal, after a user logs in, the system checks their role. An Admin can manage users, while a Candidate can only register for exams and view certificates. If a Candidate tries to access an Admin-only feature, the system denies access.
In JWT authentication, a user logs in with valid credentials, and the server generates a signed JWT token. The client sends this token in the Authorization header with each request. Spring Security validates the token, extracts user details and roles, and authenticates the request withoutmaintaining server-side sessions.
User Login β Validate Credentials β Generate Signed JWT β Client sends "Authorization: Bearer <JWT>" β Validates Token β Extract User & Roles β Authorize Request
To implement JWT in Spring Boot, I authenticate the user using Spring Security, generate a JWT token upon successful login, create a JWT filter to validate tokens for incoming requests, and configure Spring Security to use stateless authentication with JWT tokens instead of sessions.
Spring Security intercepts every request through the SecurityFilterChainbefore it reaches the Controller. The request passes through multiple filters that perform authentication, authorization, token validation, session management, and exception handling. If authentication and authorization succeed, the request proceeds to the Controller; otherwise, an error response is returned.
I store sensitive data in encrypted form using algorithms like AES-256, keep encryption keys in a secure key management system, and decrypt the data only when it is required.
Caching is a technique used to store frequently accessed data in memory to reduce database calls and improve application performance. On the first request, data is fetched from the database and stored in the cache. Subsequentrequests are served directly from the cache until the cache is updated or invalidated.
@EnableCaching annotation. After enabling caching, below annotations used to manage cached data.@EnableCaching β Enablescaching in the Spring Boot application.@Cacheable β Reads from cache; on Cache Miss, executes the method and stores the result in the cache.@CachePut β Always executes the method and updates the cache.@CacheEvict βRemoves specific cache data or clears the entire cache.@Caching β Combines multiple cache operations on a single method.@Async annotation?β’ @Async is used to execute methods asynchronously in a separate thread. It is commonly used for long-running tasks such as sending emails, file processing, and external API calls to improve application responsiveness. Save User in DB β Return Response β Send Email in Background
Spring's scheduling is enabled via @EnableScheduling on a configuration class, then methods annotated with @Scheduled (using fixedRate, fixedDelay, or a cron expression) run automatically on a background thread pool at the specified interval, useful for periodic tasks like cleanup jobs or batch processing.
| Pattern | Purpose |
|---|---|
| Circuit Breaker | Stops calling a repeatedly failing downstream service for a cool-down period, failing fast instead of piling up threads. |
| Retry | Re-attempts a failed call a bounded number of times, usually with backoff, for transient failures. |
| Bulkhead | Caps concurrent calls to a dependency so one slow downstream can't exhaust the whole thread pool. |
| Rate Limiter | Restricts number of calls in a time window. |
| Time Limiter | Bounds how long a call is allowed to take before it's treated as a failure. |
| Fallback | Alternate response/logic executed when the primary call ultimately fails. |
@KafkaListener subscribes a method to a topic.Implement rate limiting using a token-bucket or sliding-window algorithm, either in application code (e.g., Bucket4j) or at the gateway/infrastructure level (API Gateway, Nginx, Redis-backed distributed limiter for multi-instance deployments) - track request counts per client/API key within a time window and reject or throttle once the limit is exceeded.
Resilience4j works by decorating application calls with fault-tolerance mechanisms. For example, when Booking Service calls Payment Service, Resilience4j can apply a timeout to prevent indefinite waiting, retry temporary failures, use a circuit breaker to stop calls after repeated failures, limit concurrent calls using a bulkhead, restrict request rates with a rate limiter, and execute a fallback when the call ultimately fails. These mechanisms prevent cascading failures and improve the resilience and availability of microservices.
A different service can be called using HTTP clients such as RestTemplate, WebClient, or Feign Client. RestTemplate is typically used in legacy applications. WebClient is preferred for new applications because it supports non-blocking communication. Feign Client is commonly used In microservices architectures, because it simplifiesservice-to-service communication and reduces boilerplate code.
| Annotation | Loads |
|---|---|
| @WebMvcTest | Only the web/MVC layer (controllers, filters, converters) — services/repos mocked with @MockBean. |
| @DataJpaTest ⭐ | Only the JPA layer against an in-memory H2 DB by default; each test runs in a transaction that's rolled back afterward. |
| @SpringBootTest | Full application context — real end-to-end integration test, slower. |
| @Mock / @InjectMocks | Pure Mockito unit tests with no Spring context at all — fastest, ideal for service-layer logic. |
| MockMvc | Tests controllers/REST endpoints without starting a real HTTP server. |
Service-layer logic is tested using JUnit and Mockito. Dependencies such as repositories and external services are mocked, allowing the test to focus only on business logic, validations, calculations, and exception handling within the service layer.
JUnit improves code quality by catching bugs early through automated regression testing, encouraging modular/testable design, enabling safe refactoring (tests confirm behavior didn't break), and serving as executable documentation of expected behavior.
If SonarQube reports that a class exceeds the line limit, I would first analyze the class and identify different responsibilities inside it. Instead of simply increasing or suppressing the SonarQube limit, I would refactor the class into smaller, focused classes following Single Responsibility Principle. For example, if a service class handles validation, payment processing, notification, reporting, and database operations, I would extract those responsibilities into separate services or components.
| Property | Meaning |
|---|---|
| maximum-pool-size | Hard cap on total connections — size it to ((core_count * 2) + effective_spindle_count) as a starting heuristic, then load-test; bigger isn't always faster because of DB-side contention. |
| minimum-idle | Connections kept ready even when idle. |
| connection-timeout | Max wait for a connection from the pool before throwing an exception. |
| idle-timeout | How long a connection can sit idle before being retired. |
| max-lifetime | Max connection age before it's recycled (should be a few minutes less than any DB/firewall imposed connection timeout). |
| leak-detection-threshold | Logs a warning if a connection is checked out longer than this, which usually points to a leak (not returned to the pool). |
| Endpoint | Shows |
|---|---|
| /actuator/health | Liveness/readiness, DB & downstream health indicators. |
| /actuator/metrics | JVM, HTTP, DataSource metrics (usually scraped by Prometheus). |
| /actuator/env | Resolved environment properties (sensitive values sanitized). |
| /actuator/beans | All beans in the ApplicationContext. |
| /actuator/loggers | View/change log levels at runtime without a redeploy. |
| /actuator/threaddump & /heapdump | Live diagnostics for stuck threads / memory investigations. |
@Endpoint(id="myendpoint") and expose read operations with @ReadOperation. JVM triage checklist for "memory keeps growing": capture a heap dump, compare object histograms across two snapshots, check for unbounded caches/static collections/unclosed streams, and watch GC logs for rising old-gen occupancy after full GCs (a real leak, vs. sawtooth pattern which is normal).Actuator endpoints are production-ready REST endpoints provided by Spring Boot Actuator for monitoring and managing application health, metrics, and runtime status/actuator/health β Shows application health status. /actuator/info β Displays application information. /actuator/metrics β Provides application metrics. /actuator/env β Shows environment properties. /actuator/beans β Lists all Spring beans.
Spring Boot Actuators provides the health endpoint to check the health & availability status of an application and its dependentservices.
Custom Actuator endpoints can be exposed by creating a class annotated with @Endpoint and exposing it through Spring Boot Actuator.
In production, I monitor application, JVM, database, infrastructure, and businessmetrics to ensure system health, performance, and availability.
We can enable debugging logs by setting debug=true or configuring the logging level in application.properties. DEBUG is mainly used during development to troubleshoot issues. In production, we usually enable DEBUG only for specific packages.
If the application's memory usage keeps increasing, I would first determine whether it's a memory leak or normal memory growth. I would monitor JVM heap usage, analyze GC logs, capture a heap dump, and identify objects consuming memory. Then I would fix issues such as memory leaks, unclosed resources, large caches, or excessive object creation.
If a REST API returns data but the response time is inconsistent, I would investigate whether the latency is caused by slow database queries, external API calls, thread or connection pool contention,garbage collection pauses, network latency, or varying server load. I would use application logs, APM tools, SQL execution plans, and JVM metrics to identify the bottleneck.
I isolate background jobs by moving them to dedicated thread pools, asynchronous workers, or message queues so they do not compete with REST APIs for CPU, threads, or database connections.
APIs can be optimized by optimizing database queries, using pagination and caching, returning DTOs, tuning connection pools, optimizing external API calls, using asynchronous processing, and continuously monitoring application performance.
@Async processing when appropriate.@Async, Kafka, or message queues for long-running operations such as email sending, notifications, and report generation.If a Spring Boot application works locally but fails in production, I start by checking the logs, then verify the environment configuration, database connectivity, dependencies, external services, and server resources to identify and resolve the root cause.
If changes to application.properties are not reflected in production, I would check whether the application was restarted, whether the correct configuration file is being used, if environment variables are overriding the properties, whether the correct Spring profile is active, and if the latest build was actually deployed.
Low CPU usage doesn't necessarily mean the application is healthy. The service may crash due to database connection pool exhaustion, thread pool exhaustion, memory issues, blocked threads, external API delays, or resource limits. I would analyze logs, thread dumps, heap usage, connection pools, and external dependencies to identify the bottleneck.
When multiple beans of the same type exist, Spring cannot determine which bean to inject and throws a NoUniqueBeanDefinitionException. I can resolve this by using @Qualifier, marking one bean as @Primary, or injecting a specific bean by its name.
I would first determine whether it's a 401 (Authentication) or 403 (Authorization) issue. Then I would verify the JWT token, user roles/permissions, Spring Security configuration, token expiration, request Authorization headers, and application logs to identify the root cause.
I would first check the application logs and monitor the connection pool metrics to confirm that all database connections are in use. Then I would identify the root cause, such as connection leaks, slow SQL queries, long-running transactions, or increased traffic. Finally, I would optimize queries, ensure connections are properly released, tune the HikariCP pool configuration, and scale the application if necessary.
If users still see the old behavior after deployment, I would verify that the new version was actually deployed, the application was restarted successfully, caches were refreshed, the correct configuration/profile is beingused, and the load balancer or reverse proxy is routing traffic to the updatedinstances.
If logs are missing in production, I would verify the logging configuration, log level, log file path, application permissions, active Spring profile, log rotation settings, and whether logs are being forwarded correctly to the centralized logging system.
Zero Downtime Deployment is a deployment strategy where a new application version is released without interrupting service or causing downtime for users. This is achieved by deploying the new version alongside the existing one and switching user traffic only after the new version is verified to be healthy.
If an application behaves differently in Docker than locally, I compare the runtime environments. Common causes include different environment variables, Spring profiles, Java versions, Docker networking, mounted volumes, file paths, resource limits, or missing dependencies. I verify the container configuration, inspect logs, and compare both environments to identify the difference.
Most production issues are caused by configuration mistakes, inefficient database access, poor exception handling, resource leaks, security misconfigurations, and inadequate monitoring. Preventing these issues requires proper testing, monitoring, logging, and following Spring Boot best practices.
Idempotency-Key header checked against a DB unique constraint before processing.deleted/is_active flag instead of a physical DELETE; Hibernate's @SQLDelete rewrites the delete into an update, and @Where transparently filters deleted rows out of every query.@CreatedBy/@LastModifiedBy/@CreatedDate), an AOP aspect around service methods, or a dedicated audit-event table/service.I would handle duplicate API requests using idempotency keys, unique database constraints, and validation checks. Beforeprocessing a request, the system verifies whether the request has already been processed. If it has, the previouslystored response is returned instead of executing the operation again.
I would start by identifying whether the delay is coming from the database, application code, external services, or infrastructure. I would analyze logs, SQL queries, CPU and memory usage, connectionpools, and downstream servicecalls. Once the bottleneck is identified, I would optimize the relevant component and measure the improvement.
DB Sequernce I would use UUIDs because they are globally unique and avoid collisions, even when thousands or millions of images are uploaded concurrently across multiple servers. (Universally Unique IDentifier)
Data can be encrypted using encryption algorithms that convertplain text into ciphertext, ensuring that only authorized users can read the data. Symmetric Encryption β Same key for encryption and decryption. (AES , DES , 3DES) Asymmetric Encryption β Different keys for encryption and decryption. (RSA, ECC) (Encrypt -> Public Key) (Decrypt -> Private Key)
In our Candidate Registration Portal:
To handle large datasets, I use pagination, query optimization, indexing, DTO projections, streaming, batch processing, caching, and asynchronous processing. The goal is to avoid loading all data into memory and minimize database and network overhead.
Issue: Candidates reported that payment and seat booking were successful, but admit cards were not being generated. Investigation: Traced the flow of Payment Success β Seat Confirmation β Admit Card Generation. Found that the admit card generation service was failingdue to a missing configuration. Fix:Fixed the configuration and regenerated pending admit cards through a batch job. Result: All affected candidates received their admit cards successfully.
Issue: Admin reports were loading very slowly. Investigation: Analyzed SQL queries and found missingindexes and unnecessary joins. Fix: Added indexes, optimized queries, and implemented pagination. Result: Response time reduced from 30 seconds to 2 seconds.
Issue: Admins complained that the candidate approval screens were slow. Investigation: Enabled Hibernate SQL logs and found an N+1 query issue while loading candidate documents. Fix: Used Join Fetch/ Entity Graph and optimized data retrieval. Result: The approval screen became significantly faster.
Issue: Candidates complained that the payment was deducted, but the seat was not booked. Investigation: Checked the transaction flow. The payment service succeeded, but the seat booking servicefailed due to a timeout. Fix: Added a retry mechanism, implemented a reconciliation job, and added compensation handling. Result: Payment and seat booking remained synchronized.
Issue: The exam center showed available seats even though all seats were booked. Investigation: Checked the booking and seat allocation tables. Found that concurrent bookings were updating seat counts incorrectly. Fix: Added transaction management and implemented optimistic locking. Result: Seat counts remained consistent.
Spring Boot internally uses several design patterns such as Singleton, Factory, Dependency Injection (IoC), Proxy, Template, Observer, and MVC patterns to provide loose coupling, maintainability, and scalability.
DAO (Data Access Object) encapsulates database access logic (queries, persistence) behind a clean interface, isolating the rest of the app from persistence details. DTO (Data Transfer Object) is a simple object used to carry data between layers (e.g., API request/response) without exposing internal entity structure.
Spring itself is built on several design patterns - Singleton (default bean scope), Factory (BeanFactory creates beans), Proxy (AOP and transactional/security proxies), Template Method (JdbcTemplate, RestTemplate), Observer (ApplicationEvent/ApplicationListener), and Dependency Injection/Inversion of Control as its foundational pattern.
@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScanAutoConfiguration.imports (Boot 3) / spring.factories (Boot 2) → filters via @Conditional* → registers beans