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?
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?
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?
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.
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?
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?
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.
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?
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.
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.
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.
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?
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.
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.
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.
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.
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?
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.
-- 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?
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?
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.
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.
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.
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?
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?
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?
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?
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?
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.
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?
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.
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.