Java Full Stack Developer Top 100 Interview Questions
100 Java full stack developer interview questions with structured answers, comparison tables, flow diagrams and runnable examples. Covers core Java, concurrency, backend architecture, REST APIs, SQL, persistence, HTML, CSS, JavaScript, security, testing, deployment and system design.
Questions 81-100 of 100
Q81.How do client-side rendering, server-side rendering, and prerendering differ?
The approaches differ in when and where initial page markup is produced. They can be combined, and interactive behavior may still require client-side code after the initial content appears.
Client-side rendering Server-side rendering Prerendering Markup produced in the browser after code runs Markup produced during a server request Markup produced before the user requests it Concern: initial script and data dependency Concern: server work and hydration coordination Concern: freshness and the number of generated variants When to use which:
- Use client-side rendering when rich interaction and navigation fit the application, while measuring the initial download, execution, and data-fetch cost.
- Use server-side rendering when request-specific initial content is valuable, and ensure client hydration starts from compatible data and markup.
- Use prerendering when content can be generated ahead of time and served efficiently, with a clear refresh policy for changed information.
No rendering mode guarantees fast interaction or discoverability by itself. Authentication, caching, script size, network waterfalls, and content correctness still determine the user experience.
Q82.How would you improve a frontend that loads slowly or responds poorly to input?
I would measure the actual user journey and identify whether delay comes from loading, execution, rendering, or backend dependencies. Smaller bundles help only when download or script execution is a meaningful bottleneck.
- Reproduce the issue on representative devices and networks, measuring usable content, interaction delay, layout movement, and the relevant request waterfall.
- Inspect transferred assets, main-thread work, rendering and layout activity, image dimensions, and repeated or serial data requests.
- Apply targeted changes such as route-level code splitting, appropriate images, reduced unnecessary renders, bounded lists, or consolidated independent requests.
- Retest the complete interaction, including accessibility and failure states, and compare user-facing metrics rather than relying only on a local development impression.
flowchart TD A["Measure representative user journey"] B{"Dominant delay?"} C["Inspect network and assets"] D["Inspect script and render work"] E["Inspect backend request chain"] F["Apply targeted change"] G["Retest user experience"] A --> B B -->|loading| C B -->|execution| D B -->|dependency| E C --> F D --> F E --> F F --> GTrade-offs:
- Aggressive lazy loading reduces initial work but can introduce visible delays when newly needed code or content is requested later.
- Virtualizing large lists can reduce DOM work while requiring deliberate handling of keyboard navigation and accessibility.
Example
A page waits for three independent API requests one after another before showing its main content.
- Verify that the requests truly have no dependency on each other.
- Start them concurrently and display meaningful partial loading states.
- Preserve independent failure handling so one optional result does not block everything.
- Measure the improved content-ready time under a realistic network profile.
Q83.What is the difference between authentication and authorization?
Authentication establishes an identity or verifies credentials. Authorization decides whether that identity may perform a particular action on a particular resource under the current conditions.
Authentication Authorization Asks: who is making the request? Asks: may this request act on this resource? Evidence: validated credentials or session Evidence: roles, ownership, tenant and policy When to use which:
- Authenticate requests through a trusted mechanism and validate the resulting identity context before treating client-supplied identity claims as authoritative.
- Authorize each protected operation using relevant resource and action context, rather than assuming that a logged-in user may access every record.
- Apply checks on the server even when the interface hides unavailable actions, because direct requests do not need to pass through the intended UI.
A role check can be one input to authorization but is not always sufficient. Account status, resource ownership, tenant boundaries, and changes in permission may also affect the decision.
Q84.How do server-side sessions and self-contained signed access tokens differ?
A server-side session usually maps an opaque identifier to server-held state. A self-contained signed token carries claims that a verifier can validate, with important differences in revocation and freshness.
Server-side session Signed access token Identity resolved from a session store or server context Identity resolved from validated token claims Concern: shared access and expiry of session state Concern: expiry, revocation and stale permissions When to use which:
- Use a server-side session when centralized invalidation and a browser-oriented session lifecycle fit the application, securing the identifier and session store.
- Use signed access tokens when their verification and distribution properties fit the architecture, validating trusted algorithms, issuer, audience, expiry, and other required claims.
- Choose token transport and storage separately: either model can involve cookies, and script-readable storage exposes credentials to successful script injection.
A signed JWT is not automatically encrypted, and its claims are not trustworthy merely because they can be decoded. Logout and permission changes need an explicit policy for already-issued tokens.
Q85.How do CORS and CSRF protection solve different browser security problems?
CORS controls permitted cross-origin browser access to responses and gates some requests through preflight. CSRF protection prevents an attacker’s site from causing an unwanted authenticated action using credentials the browser sends automatically.
CORS CSRF protection Controls cross-origin browser access to responses Stops unwanted credentialed state changes Does not replace server authorization or CSRF controls Does not replace XSS prevention or authentication When to use which:
- Configure CORS with approved origins, methods, and headers when a legitimate frontend must call another origin, handling credentialed requests according to browser rules.
- Protect state-changing cookie-authenticated requests with an appropriate anti-CSRF mechanism, origin validation, and suitable cookie policy as complementary controls.
- Test both accepted and rejected origins and credential paths; a request may reach the server even when browser code cannot read its response.
CORS is not enforced by every non-browser client and does not prove who the caller is. Avoid reflecting arbitrary origins while allowing credentials, and do not treat a missing preflight as proof that a request is safe.
Q86.How would you prevent cross-site scripting in a web application?
Cross-site scripting occurs when untrusted content is interpreted as executable browser code in a trusted application context. Prevention requires safe rendering and context-appropriate treatment of untrusted values.
- Output context: encode values appropriately for their destination, such as HTML text, attributes, or JavaScript, rather than applying one universal string replacement.
- Safe APIs: prefer text insertion and safe templating behavior over constructing executable markup from untrusted strings, and review escape hatches that bypass normal protections.
- Rich content: when users may supply HTML, use a maintained allowlist sanitizer appropriate for that content instead of attempting to block a few suspicious substrings.
- Defense in depth: configure a suitable content security policy and protect credentials, while recognizing that these controls do not replace correct input-to-output handling.
Stored, reflected, and DOM-based injection can enter through different paths. Test realistic rendering contexts and avoid embedding secrets in browser-accessible content.
Q87.How would you store passwords and design a secure login flow?
I would verify passwords using a suitable adaptive password hash and issue a controlled authenticated session after successful verification. Password storage, abuse prevention, and recovery all belong to the same account lifecycle.
- Store a unique salt and an approved password hash, using an appropriate memory-hard algorithm such as Argon2id with parameters chosen for the deployment and current guidance.
- Verify through a trusted implementation, apply bounded abuse controls, and avoid responses that unnecessarily disclose whether an account exists.
- After successful authentication, rotate or establish the session identifier, protect its transport and storage, and apply additional verification when the risk model requires it.
- Design reset, logout, credential change, and session revocation behavior, while keeping passwords and reusable credentials out of logs and diagnostic output.
flowchart TD A["Receive credentials over protected transport"] B["Apply abuse controls"] C["Verify stored password hash"] D{"Authentication accepted?"} E["Create or rotate protected session"] F["Return controlled failure"] G["Record safe security event"] A --> B B --> C C --> D D -->|yes| E D -->|no| F E --> G F --> GTrade-offs:
- A more expensive password hash increases offline attack cost but also affects login capacity, so measure and rate-limit appropriately.
- Account recovery can undermine strong login checks if its identity and session-revocation rules are weaker.
Example
A user successfully changes their password after a verified recovery process.
- Generate a new salt and store the new password hash.
- Invalidate existing sessions according to the account policy.
- Require a fresh authenticated session rather than reusing an untrusted earlier identifier.
- Record the security event without storing the supplied password.
Q88.How would you implement a secure file-upload endpoint?
I would treat uploaded bytes, names, and declared content types as untrusted. A successful upload should mean the file passed the application’s required checks and was stored under controlled access.
- Authenticate and authorize the operation, enforce request and file-size limits, and allow only the file categories the business actually needs.
- Validate content using suitable inspection or decoding rather than trusting extension or supplied MIME type, with limits for compressed or expanded content.
- Generate a safe storage identity, keep files outside executable application paths, and apply scanning or quarantine appropriate to the supported content.
- Serve accepted files through access-controlled delivery with safe content headers, and define lifecycle, rejection cleanup, and audit behavior.
flowchart TD A["Authenticate and limit upload"] B["Validate allowed content"] C{"Required checks pass?"} D["Store under generated identity"] E["Reject or quarantine"] F["Deliver through controlled access"] A --> B B --> C C -->|yes| D C -->|no| E D --> FTrade-offs:
- Deep inspection improves assurance but consumes resources and may require asynchronous quarantine rather than immediate publication.
- Preserving the original filename as display metadata can be useful, but it should not determine a trusted filesystem path.
Example
A profile-photo upload has an allowed extension but its contents do not decode as an allowed image.
- Reject it before exposing it as a profile image.
- Remove temporary upload data according to the failure policy.
- Return a safe validation error and retain only necessary diagnostic metadata.
- Test oversized images and excessive decoded dimensions as separate resource limits.
Q89.How would you enforce resource-level authorization in a multi-tenant API?
I would authorize each operation using trusted identity, tenant context, resource ownership, and the requested action. An identifier supplied in a URL or request body is not evidence of permission.
- Establish the caller and applicable tenant from verified context, and resolve the requested action through a deny-by-default policy.
- Load or query the resource within the allowed scope, checking object-level and field-level permissions where the operation requires them.
- Validate related resource identifiers and state transitions as well, preventing an allowed object from being linked to an unauthorized object elsewhere.
- Apply the same policy to reads, writes, exports, caches, and background work, and test cross-user and cross-tenant requests directly.
flowchart TD A["Verify caller and tenant context"] B["Resolve scoped resource and action"] C{"Policy permits operation?"} D["Check related fields and resources"] E["Apply authorized operation"] F["Return policy appropriate rejection"] A --> B B --> C C -->|yes| D C -->|no| F D --> ETrade-offs:
- Centralized policy logic improves consistency, but each entry point must supply accurate resource and action context.
- Caching authorization-sensitive results improves latency only when keys and invalidation preserve the relevant user and tenant boundaries.
Example
A signed-in user requests an invoice identifier belonging to another tenant.
- Derive the permitted tenant from trusted identity context.
- Query or authorize the invoice within that tenant’s scope.
- Return the documented denied or not-found response without exposing the other tenant’s data.
- Verify that exports and cached responses enforce the same boundary.
Q90.How do a container image and a running container differ?
A container image is a packaged filesystem and execution configuration. A running container is an instance created from an image, with runtime process state and configured isolation and resources.
- Image: build a reproducible artifact containing the application and required runtime components, minimizing unnecessary content and avoiding embedded secrets.
- Instance: supply environment-specific configuration and appropriate identity, resource limits, network access, and filesystem permissions when starting the container.
- Storage: treat the instance’s writable layer as disposable unless persistence is intentionally provided through a suitable mounted or external storage mechanism.
- Operations: define readiness, health, graceful shutdown, logging, and version identification so instances can be replaced predictably during deployment and recovery.
Containers commonly share the host kernel and are not simply small virtual machines. Packaging the application does not by itself solve orchestration, data persistence, credential management, or application-level security.
Q91.How do unit, integration, and end-to-end tests differ?
These tests examine behavior at different boundaries. A useful strategy combines focused feedback with enough real integration coverage to catch defects that isolated components cannot reveal.
Unit Integration End-to-end Tests a focused function or component Tests collaborating real components Tests a complete user or system journey Gives precise, fast behavior feedback Verifies contracts and infrastructure behavior Validates the assembled experience When to use which:
- Use unit tests for business rules, transformations, and edge cases that can be checked clearly without relying on a full application environment.
- Use integration tests for persistence, transactions, serialization, authentication boundaries, and dependency contracts where mocked behavior can hide important differences.
- Use a focused set of end-to-end tests for critical journeys, including failures and permissions, while controlling data, timing, and environmental causes of flakiness.
Mocking every collaborator can make tests fast but disconnected from reality. Conversely, checking every small rule only through a browser makes failures slow and difficult to localize.
Q92.How would you test a REST endpoint beyond its happy path?
I would test the observable contract and business invariants across valid, invalid, unauthorized, and concurrent requests. A response status alone does not prove that stored state or side effects are correct.
- Create representative fixtures and verify request validation, response structure, status codes, headers, and the exact authorized data returned.
- Exercise missing authentication, insufficient permissions, cross-resource access, invalid fields, absent records, and conflicting state transitions.
- Test repeated requests and simultaneous updates where duplicate effects or race conditions could violate the business invariant.
- Inject relevant dependency failures and verify rollback, durable outcomes, safe error mapping, and recoverability rather than merely checking that an exception occurred.
flowchart TD A["Define API contract and invariant"] B["Test valid and invalid inputs"] C["Test authorization boundaries"] D["Test concurrency and retries"] E["Inject dependency failures"] F{"Stored outcome remains correct?"} G["Accept tested behavior"] H["Repair boundary or recovery logic"] A --> B B --> C C --> D D --> E E --> F F -->|yes| G F -->|no| HTrade-offs:
- Real dependency tests provide stronger integration evidence but require controlled data and dependable environment cleanup.
- Excessive implementation-specific assertions make refactoring expensive without necessarily protecting user-visible behavior.
Example
An order endpoint promises one order per accepted idempotency key.
- Send the same valid request concurrently with the same key.
- Verify both responses resolve to one accepted order outcome.
- Confirm only one order and one logical downstream event exist.
- Repeat with a changed payload under the same key and verify the documented conflict behavior.
Q93.How would you structure CI/CD for a Java backend and browser frontend?
I would build reproducible versioned artifacts, verify their contracts together, and promote a reviewed release through controlled environments. Deployment must account for active older clients as well as running backend instances.
- Validate source changes with focused backend and frontend checks, dependency review, and tests for important API and persistence behavior.
- Build immutable application artifacts once, recording their versions and supplying environment-specific configuration without embedding production credentials.
- Apply compatible schema changes and deploy through a bounded rollout, verifying readiness before routing ordinary traffic to new instances.
- Monitor user-facing errors, latency, and critical business outcomes, then complete the rollout or execute a defined code and data recovery plan.
Retain required older frontend assets and API compatibility during the transition. Reverting an executable artifact does not automatically reverse a destructive schema change or repair data already written incorrectly.
flowchart TD A["Review source and contracts"] B["Run focused checks"] C["Build versioned artifacts"] D["Apply compatible migration and rollout"] E{"Readiness and service checks pass?"} F["Complete promotion"] G["Stop rollout and recover"] A --> B B --> C C --> D D --> E E -->|yes| F E -->|no| GExample
A new frontend begins sending an optional profile field.
- Deploy a backend version that accepts the new field while preserving the old contract.
- Release the frontend after compatibility checks succeed.
- Monitor both new and still-active older clients.
- Remove obsolete behavior only after its consumers and rollback window are retired.
Q94.How would you design a reliable checkout flow across frontend, Java services, and a database?
I would model checkout as a recoverable business workflow with authoritative server validation and clear states. A browser success message must correspond to a known durable outcome, not merely a completed click handler.
- Define order and reservation states, authoritative pricing, inventory rules, authentication, acceptable payment delay, and the client’s retry and status-check behavior.
- Validate the request and idempotency key, then atomically create appropriate local order and inventory state without trusting client-supplied totals.
- Coordinate payment and other external effects through durable steps, verifying callbacks and deduplicating repeated messages before changing the order state.
- Expose a stable order-status contract, reconcile uncertain external outcomes, release expired reservations, and monitor the entire path from request to final result.
flowchart TD A["Frontend submits identified checkout"] B["Validate access price and stock"] C["Commit pending order and reservation"] D["Request external payment safely"] E{"Payment outcome known?"} F["Finalize or cancel order"] G["Reconcile pending outcome"] H["Frontend displays authoritative status"] A --> B B --> C C --> D D --> E E -->|yes| F E -->|no| G F --> H G --> HTrade-offs:
- Reservations support a multi-step workflow but require expiry and compensation policies to avoid indefinitely holding stock.
- Immediate user feedback can show a pending state honestly while recovery establishes whether the external action succeeded.
Example
A payment request times out after the order reservation is committed.
- Keep the order in a defined pending state rather than guessing success or failure.
- Query or reconcile the external operation using its stable identity.
- Finalize the order once success is confirmed, or release the reservation after a confirmed failure or expiry.
- Let the frontend retrieve the same authoritative order status after a reload.
Q95.When should a frontend use polling, server-sent events, or WebSockets?
The choice depends on update direction, frequency, latency, and operational requirements. A persistent connection adds lifecycle concerns that an occasional status request may not need.
Polling Server-sent events WebSockets Repeated client requests A server-to-client event stream Persistent two-way messages Fits occasional status updates Fits notifications or progress feeds Fits interactive two-way communication When to use which:
- Use polling when updates are infrequent enough that simple requests meet freshness requirements without excessive traffic or overlapping calls.
- Use server-sent events when the server mainly pushes text events and the application can define reconnection, event identity, and replay behavior.
- Use WebSockets when frequent bidirectional messages justify a persistent protocol, with explicit authentication, message validation, heartbeat, and backpressure policies.
Automatic reconnection does not guarantee that no updates are missed or duplicated. Preserve resumable event positions or provide a fresh-state reconciliation path when correctness requires it.
Q96.How would you estimate average database connection demand from request rate?
I would estimate steady-state connection occupancy from throughput and the average total time each request holds a connection. This is a starting measurement model, not a complete pool-sizing rule.
- Formula:
average occupied connections = requests per second × average connection-hold seconds per request, assuming stable flow and consistently measured work. - Scope: include the total connection time across all relevant database operations, and distinguish one application instance from the combined deployment.
- Variability: bursts, slow queries, long transactions, background jobs, and tail latency can require capacity beyond the average, but the database still sets a sustainable limit.
- Verification: load-test a bounded pool while measuring queueing, acquisition timeouts, database utilization, and end-to-end latency before choosing the operating configuration.
Increasing the pool can increase contention rather than improve throughput. Reduce unnecessary connection hold time when it is the source of demand.
Example
One application instance handles 200 requests per second, and each request holds a connection for an average total of 0.04 seconds.
- Average occupancy is
200 × 0.04 = 8 connections. - Eight is the mean demand under the stated assumptions, not automatically a safe maximum.
- Measure bursts, tail hold times, and other users of the same database.
- Validate a bounded configuration and check the sum of pool limits across all deployed instances.
- Formula:
Q97.How do Cache-Control and ETag support HTTP caching?
Cache-Control defines how a representation may be stored and reused. An ETag identifies a version of a representation so a client can ask whether its stored copy is still valid.
- Freshness: directives such as max-age define permitted fresh reuse, while private and related rules affect which caches may store a response.
- Revalidation: no-cache allows storage but requires validation before reuse; it does not mean the same thing as no-store, which instructs caches not to store the response.
- Conditional requests: a client can send If-None-Match with an ETag, and a matching authorized retrieval can receive a 304 response instead of another complete representation.
- Correct variants: vary cache entries by the relevant representation inputs and avoid sharing personalized responses across users or tenants.
Caching does not replace authorization. Validate access and use appropriate policies for sensitive content even when the representation has not changed.
Example
A client stores a permitted resource representation with ETag "version-2".
- When revalidation is required, it sends If-None-Match with that tag.
- The server verifies the request and finds the representation unchanged.
- It returns 304 with applicable caching metadata and no new representation body.
- The client reuses its stored representation according to the updated cache rules.
Q98.An API works in direct tests but fails from the browser. How would you debug it?
I would compare the actual browser request and response with the successful direct request. Browser security, credentials, routing, and response handling can differ even when the backend business logic is correct.
- Inspect the network request, final target, method, headers, credentials, redirect chain, status, and response content rather than relying only on the UI error message.
- Check browser enforcement such as cross-origin rules, mixed-content restrictions, cookie policy, and content security policy, including any failed preflight.
- Compare proxy paths, environment configuration, authentication, payload shape, and content type with the working request, tracing the same correlation identifier on the server.
- Fix the precise contract or configuration issue and test allowed and denied cases, preserving the intended security boundary instead of disabling it broadly.
flowchart TD A["Capture browser network evidence"] B{"Request reaches intended endpoint?"} C["Inspect response and credentials"] D["Inspect routing and browser restrictions"] E["Compare with successful direct request"] F["Correct specific mismatch"] G["Test allowed and rejected behavior"] A --> B B -->|yes| C B -->|no| D C --> E D --> E E --> F F --> GTrade-offs:
- Permissive security settings can hide the symptom while exposing data or actions to unintended origins.
- A frontend parsing error may come from a proxy’s HTML login page rather than malformed JSON produced by the intended API.
Example
The frontend reports a JSON parsing error, while a direct authenticated API request succeeds.
- The browser network response contains an HTML login page after a redirect.
- Compare its credential and proxy configuration with the successful request.
- Correct the authentication flow and check status and content type before parsing.
- Verify unauthenticated requests produce the documented client behavior.
Q99.How should you explain a Java full stack project you personally delivered?
Use a real feature or project to show how you connected user needs, backend behavior, data, and operational delivery. Clearly distinguish your contribution from the work of the wider team.
- State the user problem, major requirements, constraints, and your responsibility, using measured scale or performance figures only when you can explain their source.
- Trace one important user action through the frontend, API, business service, and database, identifying validation, permissions, and transaction boundaries.
- Explain a meaningful design trade-off and the evidence that influenced it, such as responsiveness, consistency, maintainability, or deployment risk.
- Describe how you tested the feature and resolved a real failure, including what happened at integration boundaries rather than only within one class.
- Report the actual outcome and a specific improvement you would make next, acknowledging limitations honestly.
What the interviewer is listening for: ownership, cross-layer reasoning, practical judgment, clear communication, and credible evidence of delivered behavior.
Q100.How should you discuss a production incident or technical disagreement?
Describe a real situation in terms of impact, evidence, decisions, and learning. The goal is to demonstrate accountable problem-solving rather than to assign blame or present every decision as perfect.
- Explain the context, affected users, and initial uncertainty, separating confirmed observations from the hypotheses the team first considered.
- State your responsibility and how you helped contain the impact, communicate progress, or frame the competing technical options fairly.
- Describe the logs, tests, experiments, or measurements used to decide what was happening and which correction or design choice was justified.
- Explain the outcome and its validation, including any rollback, data repair, unresolved limitation, or conclusion that changed your original view.
- Describe the follow-up improvement and how the team assessed whether it reduced the chance or impact of a similar problem.
What the interviewer is listening for: calm investigation, collaboration, honest ownership, willingness to revise assumptions, and follow-through after the immediate issue is resolved.