Skip to content

Java Full Stack with React Interview Questions for 5 Years Experience

40 questions with answers for candidates with 5 years of experience — 27 medium, 13 hard.

What interviewers expect: 5 years experience

At five years, you are evaluated as a senior engineer. Expect system design rounds covering service boundaries, data consistency with sagas, messaging with Kafka, caching strategies, security and observability. Coding rounds still happen but focus on clean, testable code. Behavioural questions explore ownership, handling incidents, mentoring juniors and pushing back on unrealistic timelines with data.

This set is weighted towards REST APIs, Security and Microservices (8), JPA and Hibernate (6), Spring Boot (6), JavaScript, HTML and CSS (6).

System design Distributed data consistency Observability and incidents Mentoring and ownership
Solved at this levelStart practicing
3 QUESTIONS FREESign up to unlock the full question bank and track your progress.Unlock every question and answer, then continue practising company-wise and package-wise.
3 questions free Unlock the rest in seconds
01

A search query that used to take milliseconds now takes 10 seconds as data grew. How do you troubleshoot?

Save to ▾
Show answer
Get the exact SQL from logs or the slow query log and run EXPLAIN ANALYZE to see whether it does a full scan, a bad join order or a big sort. Check for missing or unused indexes, functions on indexed columns, implicit type conversions and outdated statistics. Add the right composite index, rewrite the query, select fewer columns and paginate. For text search, use a full-text index or a search engine instead of LIKE '%term%'.
02

What is the difference between persist and merge, and between save and saveAndFlush?

Save to ▾
Show answer
persist makes a new entity managed and assigns its ID; it fails for detached entities. merge copies the state of a detached entity onto a managed copy and returns that copy. Spring Data save calls persist for new entities and merge otherwise. saveAndFlush also calls flush, pushing pending SQL to the database immediately, which helps when you need a constraint error or trigger result now. The commit still happens at the end of the transaction.
03

What is CORS and how do you configure it for a React frontend?

Save to ▾
Show answer
CORS is a browser rule that blocks JavaScript from calling a different origin unless the server allows it with response headers like Access-Control-Allow-Origin. A React app on localhost:5173 calling an API on localhost:8080 is cross-origin. In Spring, define a CorsConfigurationSource bean with the allowed origins, methods and headers, and enable http.cors() in the security chain so preflight OPTIONS requests pass. Never use a wildcard origin together with credentials.
04

Add request validation to a registration API.

Save to ▾
Show answer
public record RegisterRequest( @NotBlank @Size(max = 60) String name, @NotBlank @Email String email, @Pattern(regexp = "^[6-9]\\d{9}$", message = "Invalid mobile") String mobile, @Size(min = 8, max = 64) String password) {} @PostMapping("/api/auth/register") public ResponseEntity<Void> register(@Valid @RequestBody RegisterRequest req) { authService.register(req); return ResponseEntity.status(HttpStatus.CREATED).build(); } // Needs spring-boot-starter-validation. Errors raise // MethodArgumentNotValidException, mapped to 400 by the advice.
05

Use CompletableFuture to call two services in parallel and combine the results.

Save to ▾
Show answer
CompletableFuture<User> userF = CompletableFuture.supplyAsync(() -> userClient.get(id), executor); CompletableFuture<List<Order>> ordersF = CompletableFuture.supplyAsync(() -> orderClient.byUser(id), executor); Profile profile = userF .thenCombine(ordersF, Profile::new) .orTimeout(2, TimeUnit.SECONDS) .exceptionally(ex -> Profile.empty()) .join(); // Pass a dedicated executor instead of the common pool for blocking I/O.
06

Your @Transactional method threw an exception but the data was still saved. Why?

Save to ▾
Show answer
By default Spring rolls back only on unchecked exceptions and Errors, so a checked exception such as IOException commits the transaction. Use @Transactional(rollbackFor = Exception.class) or wrap it in a runtime exception. Other causes are catching the exception inside the method, calling the method from the same class so the proxy is bypassed, a non-public method, or a table engine that does not support transactions such as MyISAM.
07

In a bidirectional @OneToMany relationship, what does mappedBy mean?

Save to ▾
Show answer
mappedBy marks the inverse side and names the field on the other entity that owns the relationship. The owning side, usually the @ManyToOne with the foreign key column, is the one Hibernate uses to write the join column. For example, Order has @OneToMany(mappedBy = "order") and OrderItem has @ManyToOne @JoinColumn(name = "order_id"). Always update both sides in helper methods such as addItem to keep the object graph consistent.
08

How do you handle a requirement that is unclear or keeps changing?

Save to ▾
Show answer
Situation: a product manager asked for a discount feature with vague rules. Task: build it without wasting effort. Action: I wrote down my understanding with examples, asked specific questions about edge cases like stacking coupons, and built the rules as configurable data instead of hard-coded logic. I shared a small demo early for feedback. Result: two rule changes later in the sprint needed only configuration updates, not code changes.
09

Configure Spring Security 6 for a stateless JWT-secured REST API.

Save to ▾
Show answer
@Configuration @EnableMethodSecurity public class SecurityConfig { @Bean SecurityFilterChain api(HttpSecurity http) throws Exception { http .csrf(csrf -> csrf.disable()) .cors(Customizer.withDefaults()) .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(auth -> auth .requestMatchers("/api/auth/**", "/actuator/health").permitAll() .requestMatchers(HttpMethod.DELETE, "/api/**").hasRole("ADMIN") .anyRequest().authenticated()) .oauth2ResourceServer(o -> o.jwt(Customizer.withDefaults())); return http.build(); } }
10

You are designing a new feature. When would you choose a relational database and when a NoSQL database?

Save to ▾
Show answer
Choose a relational database like PostgreSQL or MySQL when data is structured, relationships matter and you need transactions and joins, such as orders, payments and inventory. Choose NoSQL when you need a flexible schema or huge horizontal scale for simple access patterns: MongoDB for documents, Redis for caching and sessions, Cassandra for high-write time series and Elasticsearch for search. Many systems use both, with SQL as the source of truth.
11

When should you use parallel streams and when should you avoid them?

Save to ▾
Show answer
Parallel streams split work across the common ForkJoinPool. They help for CPU-heavy, stateless operations on large in-memory data with cheap splitting, such as ArrayList or arrays. Avoid them for small lists, I/O or database calls, operations with shared mutable state, or inside web servers where the common pool is shared by all requests. Always measure with JMH or real load before and after, because overhead often makes them slower.
12

Find the top 3 highest-paid employees in each department.

Save to ▾
Show answer
SELECT department_id, name, salary FROM ( SELECT department_id, name, salary, DENSE_RANK() OVER ( PARTITION BY department_id ORDER BY salary DESC) AS rnk FROM employees ) ranked WHERE rnk <= 3 ORDER BY department_id, rnk; -- DENSE_RANK keeps ties; use ROW_NUMBER for exactly 3 rows.
13

Write global exception handling for a REST API in Spring Boot.

Save to ▾
Show answer
@RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(ResourceNotFoundException.class) public ProblemDetail handleNotFound(ResourceNotFoundException ex) { return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getMessage()); } @ExceptionHandler(MethodArgumentNotValidException.class) public ProblemDetail handleValidation(MethodArgumentNotValidException ex) { ProblemDetail pd = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST); pd.setProperty("errors", ex.getBindingResult().getFieldErrors() .stream().map(e -> e.getField() + ": " + e.getDefaultMessage()).toList()); return pd; } }
14

What is the circuit breaker pattern and how is it implemented in Spring?

Save to ▾
Show answer
A circuit breaker stops calling a failing downstream service so failures do not cascade. It is closed during normal operation, opens when the failure rate crosses a threshold, returns a fallback immediately while open, and moves to half-open after a wait to test recovery. In Spring Boot it is implemented with Resilience4j using @CircuitBreaker(name = "payment", fallbackMethod = "fallback"), usually combined with timeouts, retries with backoff and bulkheads.
15

Describe the main JVM memory areas.

Core JavaMedium
Save to ▾
Show answer
The heap stores objects and is shared by all threads; it is managed by the garbage collector and split into young and old generations. Each thread has its own stack holding method frames, local variables and references. Metaspace, in native memory since Java 8, stores class metadata. There is also the program counter per thread and the code cache for JIT-compiled code. Stack overflow comes from deep recursion, while OutOfMemoryError usually means heap or metaspace is full.
16

An order service and a payment service have separate databases. How do you keep data consistent when placing an order?

Save to ▾
Show answer
Avoid distributed two-phase commit. Use the saga pattern: each service performs a local transaction and publishes an event, and failures trigger compensating actions, such as cancelling the order if payment fails. Use the transactional outbox pattern so the database write and the event are saved atomically, then a relay publishes to Kafka or RabbitMQ. Make consumers idempotent because events can be delivered more than once.
17

Build a dynamic search with optional filters using JPA Specifications.

Save to ▾
Show answer
public class ProductSpecs { public static Specification<Product> hasCategory(String c) { return (root, q, cb) -> c == null ? null : cb.equal(root.get("category").get("name"), c); } public static Specification<Product> priceBetween(BigDecimal min, BigDecimal max) { return (root, q, cb) -> (min == null || max == null) ? null : cb.between(root.get("price"), min, max); } } // Repository extends JpaSpecificationExecutor<Product> repo.findAll(Specification.where(hasCategory(cat)) .and(priceBetween(min, max)), pageable);
18

How does the useEffect dependency array work?

Save to ▾
Show answer
useEffect runs after the component renders. With no dependency array it runs after every render, with an empty array it runs once after mount, and with values like [userId] it runs again whenever those values change. Return a cleanup function to cancel subscriptions, timers or requests before the next run or on unmount. Missing dependencies cause stale data, so follow the exhaustive-deps lint rule. Effects are for syncing with external systems, not for computing derived values.
19

Write a unit test for a service method using JUnit 5 and Mockito.

Save to ▾
Show answer
@ExtendWith(MockitoExtension.class) class ProductServiceTest { @Mock ProductRepository repo; @InjectMocks ProductService service; @Test void throwsWhenProductMissing() { when(repo.findById(1L)).thenReturn(Optional.empty()); assertThrows(ResourceNotFoundException.class, () -> service.getProduct(1L)); verify(repo).findById(1L); } }
20

How do you deep clone an object in JavaScript?

Save to ▾
Show answer
const original = { user: { name: 'Asha' }, tags: ['a'], joined: new Date() }; // Modern built-in (handles Date, Map, Set, cycles): const copy = structuredClone(original); // Spread is only a shallow copy: const shallow = { ...original }; shallow.user.name = 'Ravi'; // also changes original.user.name // JSON.parse(JSON.stringify(obj)) loses Dates, functions, // undefined and fails on circular references.
21

A security test shows a stored XSS vulnerability in a comments feature. How do you fix it?

Save to ▾
Show answer
Stored XSS happens when user input containing script is saved and later rendered as HTML. React escapes text by default, so look for dangerouslySetInnerHTML, direct innerHTML or unsafe URL attributes like javascript: links. If rich text is required, sanitise it with a library like DOMPurify, and validate on the server too. Add a Content Security Policy header and keep tokens out of JavaScript-readable storage to limit damage.
22

Write a debounce function in JavaScript.

Save to ▾
Show answer
function debounce(fn, delay = 300) { let timer; return function (...args) { clearTimeout(timer); timer = setTimeout(() => fn.apply(this, args), delay); }; } const search = debounce(term => { fetch(`/api/products?q=${encodeURIComponent(term)}`); }, 400); input.addEventListener('input', e => search(e.target.value)); // Only the last call within 400 ms actually runs.
23

Explain the JavaScript event loop, including microtasks and macrotasks.

Save to ▾
Show answer
JavaScript runs on a single thread with a call stack. Asynchronous work is handled by the browser or Node, and callbacks wait in queues. After the stack empties, the event loop runs all microtasks first, such as promise callbacks and queueMicrotask, then one macrotask, such as setTimeout or an I/O callback, then renders if needed. So Promise.resolve().then(a) runs before setTimeout(b, 0). Long synchronous code blocks everything, including UI updates.
24

What is the N+1 select problem and how do you solve it?

Save to ▾
Show answer
It happens when one query loads N parent rows and then each lazy association fires a separate query, giving N+1 queries. For example, listing 100 orders and calling getCustomer on each. Solve it with JOIN FETCH in JPQL, @EntityGraph on the repository method, batch fetching with hibernate.default_batch_fetch_size, or DTO projections that select only the needed columns. Enable SQL logging or a statistics tool in development to catch it early.
25

Write a Flyway migration to add a column and index to an existing table.

Save to ▾
Show answer
-- src/main/resources/db/migration/V3__add_sku_to_products.sql ALTER TABLE products ADD COLUMN sku VARCHAR(40); UPDATE products SET sku = CONCAT('SKU-', id) WHERE sku IS NULL; ALTER TABLE products ALTER COLUMN sku SET NOT NULL; CREATE UNIQUE INDEX ux_products_sku ON products (sku); # application.yml # spring.jpa.hibernate.ddl-auto: validate # Flyway runs pending V-scripts in order at startup.
26

Your team is starting a new React project. Would you use Create React App or something else?

Save to ▾
Show answer
Create React App is deprecated and no longer recommended. For a single-page app backed by a Spring Boot API, Vite is the usual choice because of its fast dev server and optimised builds. If you need server-side rendering, SEO or file-based routing, a framework like Next.js or React Router in framework mode is recommended by the React team. Choose based on SEO needs, hosting and the team's experience.
27

Memory usage of a single-page app keeps growing the longer it stays open. What could cause this?

Save to ▾
Show answer
Common causes are event listeners, intervals or WebSocket subscriptions that are never removed when a component unmounts, growing global caches or arrays, and detached DOM nodes still referenced by JavaScript. In React, return cleanup functions from useEffect to remove listeners and clear timers. Use the Chrome DevTools Memory tab with heap snapshots to compare before and after navigation and find retained objects.
28

Write a record and use pattern matching in a switch expression.

Core JavaMedium
Save to ▾
Show answer
sealed interface Payment permits Card, Upi {} record Card(String number, double amount) implements Payment {} record Upi(String vpa, double amount) implements Payment {} static String describe(Payment p) { return switch (p) { case Card c when c.amount() > 50000 -> "High value card"; case Card c -> "Card ending " + c.number().substring(12); case Upi u -> "UPI to " + u.vpa(); }; } // Sealed types make the switch exhaustive without a default branch (Java 21).
29

A downstream service is slow, and your API threads are all stuck waiting. What do you do?

Save to ▾
Show answer
Set connection and read timeouts on every client call, because the defaults can wait far too long. Add a Resilience4j circuit breaker with a fallback and a bulkhead to limit concurrent calls to that service, plus retries only with backoff and only for idempotent requests. Consider caching the downstream data or making the call asynchronous through a queue. Monitor latency percentiles and thread pool usage with Micrometer to confirm the fix.
30

Write a repository query that loads orders with their items in one query.

Save to ▾
Show answer
public interface OrderRepository extends JpaRepository<Order, Long> { @Query(""" select distinct o from Order o join fetch o.items i where o.customer.id = :customerId """) List<Order> findWithItems(@Param("customerId") Long customerId); @EntityGraph(attributePaths = {"items", "customer"}) Optional<Order> findWithGraphById(Long id); }
31

Using streams, group employees by department and count them.

Save to ▾
Show answer
Map<String, Long> countByDept = employees.stream() .collect(Collectors.groupingBy( Employee::getDepartment, Collectors.counting())); // Average salary per department: Map<String, Double> avgSalary = employees.stream() .collect(Collectors.groupingBy( Employee::getDepartment, Collectors.averagingDouble(Employee::getSalary))); // Use TreeMap::new as the second argument to get sorted keys.
32

What changed when moving from Spring Boot 2 to Spring Boot 3?

Save to ▾
Show answer
Spring Boot 3 requires Java 17 or later and is built on Spring Framework 6. The biggest migration task is the switch from javax.* to jakarta.* packages for persistence, validation and servlet APIs. Spring Security 6 removed WebSecurityConfigurerAdapter in favour of SecurityFilterChain beans. Boot 3 also supports GraalVM native images, Micrometer observation and tracing, and from 3.2 the RestClient and virtual thread support.
33

A user's JWT is stolen and you need to invalidate it before expiry. How would you design for this?

Save to ▾
Show answer
Pure JWTs cannot be revoked, so keep access tokens short-lived, around 10 to 15 minutes, and use refresh tokens stored server-side and rotated on each use. On logout or theft, revoke the refresh token. For immediate blocking, keep a denylist of token IDs or a per-user token version in Redis and check it in the filter. Send refresh tokens in HttpOnly, Secure, SameSite cookies to reduce theft through XSS.
34

Your application fails at startup with a circular dependency error between two services. What do you do?

Save to ▾
Show answer
Spring Boot 2.6 and later forbid circular references by default. The real fix is design: two services depending on each other usually means a responsibility is in the wrong place. Extract the shared logic into a third bean, or use an application event so one service notifies the other without a direct reference. Using @Lazy or allowing circular references in properties hides the problem and should only be a temporary workaround.
35

In a search box, older API responses sometimes overwrite newer results. How do you fix this race condition?

Save to ▾
Show answer
Each keystroke starts a request, and responses can arrive out of order. Debounce the input by about 300 milliseconds so fewer requests are sent. In the effect, cancel the previous request with AbortController in the cleanup function, or keep an ignore flag so stale responses are discarded. Libraries like TanStack Query handle this automatically by keying queries on the search term and ignoring outdated results.
36

What are intermediate and terminal operations in Java Streams?

Save to ▾
Show answer
Intermediate operations such as filter, map, sorted and distinct return a new stream and are lazy; nothing runs until a terminal operation is called. Terminal operations such as collect, forEach, count, reduce and findFirst trigger processing and produce a result. Laziness allows short-circuiting: with findFirst, elements are processed one by one only until a match is found. A stream can be consumed only once.
37

How does garbage collection work in modern Java?

Core JavaMedium
Save to ▾
Show answer
The GC frees objects that are no longer reachable from GC roots such as thread stacks and static fields. Most objects die young, so the heap is generational: minor collections clean the young generation often and survivors are promoted. G1 is the default collector since Java 9 and targets predictable pause times by collecting regions. ZGC and Shenandoah offer sub-millisecond pauses for large heaps. Tuning usually starts with -Xmx and choosing the collector, not dozens of flags.
38

What is the difference between controlled and uncontrolled components?

Save to ▾
Show answer
In a controlled component, form input values live in React state and change through onChange, so React is the single source of truth, which makes validation and conditional UI easy. In an uncontrolled component, the DOM keeps the value and you read it through a ref when needed, which needs less code and suits simple forms or file inputs. Libraries like React Hook Form use uncontrolled inputs for better performance in large forms.
39

Sort a list of products by category, then by price descending, then by name.

Save to ▾
Show answer
products.sort( Comparator.comparing(Product::getCategory) .thenComparing(Product::getPrice, Comparator.reverseOrder()) .thenComparing(Product::getName)); // Null-safe variant for an optional field: Comparator<Product> byBrand = Comparator.comparing( Product::getBrand, Comparator.nullsLast(Comparator.naturalOrder()));
40

What is Spring Boot Actuator used for?

Save to ▾
Show answer
Actuator adds production-ready endpoints for monitoring and management, such as /actuator/health, /actuator/info, /actuator/metrics and /actuator/prometheus. Kubernetes uses health liveness and readiness groups for probes. Metrics are collected through Micrometer and can be exported to Prometheus, Datadog or other systems. Only expose the endpoints you need with management.endpoints.web.exposure.include and secure them, because endpoints like env or heapdump can leak sensitive data.

Frequently asked questions

What is asked in Java Full Stack with React interviews for 5 years of experience?

At five years, you are evaluated as a senior engineer. Expect system design rounds covering service boundaries, data consistency with sagas, messaging with Kafka, caching strategies, security and observability. Coding rounds still happen but focus on clean, testable code. Behavioural questions explore ownership, handling incidents, mentoring juniors and pushing back on unrealistic timelines with data.

How many questions should I practise before a Java Full Stack with React interview?

Work through all 40 questions here, then the company-wise sets for the employers you are targeting. Quality matters more than count: be able to explain why each answer is right.

Which topics matter most for 5 years of experience?

Focus first on System design, Distributed data consistency, Observability and incidents, Mentoring and ownership.