Context
This article simulates a senior Java backend interview.
The format is simple: each question gives a direct answer, then the senior-level angle interviewers usually expect. The goal is not to memorize definitions. The goal is to show clear reasoning, current technical knowledge, and awareness of trade-offs.
| Area | Questions |
|---|---|
| Java platform | Q1, Q2 |
| Quarkus | Q3, Q4, Q5, Q6 |
| MicroProfile | Q7 |
| Operations and architecture | Q8, Q9, Q10 |
Q1. What are the important features in Java 21 and Java 25?
Important Java 21 features:
- Virtual threads: lightweight JVM threads for high-throughput blocking I/O.
- Pattern matching for
switch: cleaner type-based branching. - Record patterns: easier deconstruction of records.
- Sequenced collections: common APIs such as
getFirst(),getLast(), andreversed(). - Generational ZGC: improved low-latency garbage collection.
Important Java 25 features:
- Scoped values: immutable contextual data across a call flow, useful with virtual threads.
- Flexible constructor bodies: validation and preparation before constructor delegation.
- Module import declarations: simpler imports from modules.
- Compact source files and instance main methods: simpler entry points for small programs.
- Compact object headers: lower object header overhead in selected workloads.
- JFR and AOT improvements: better profiling and startup-oriented tooling.
Some Java 25 features are still preview, incubator, or experimental. Examples include structured concurrency, primitive types in patterns, and the Vector API.
Q2. What are virtual threads, and when should you use them?
A virtual thread is a JVM-managed thread that is cheap to create. The JVM schedules many virtual threads over a smaller number of platform threads.
void runOnVirtualThread(Runnable task) throws InterruptedException {
Thread virtualThread = Thread.startVirtualThread(task);
virtualThread.join();
}
Use virtual threads for I/O-heavy workloads:
- HTTP calls
- database queries
- file I/O
- message processing
- request-per-task server workloads
They are not a replacement for capacity management. Database pools, HTTP timeouts, bulkheads, and back-pressure still matter.
Q3. What makes Quarkus different from traditional runtime-oriented Java frameworks?
Quarkus is optimized for containerized Java services. It moves a lot of work from runtime to build time:
- annotation scanning
- dependency injection metadata
- configuration processing
- reflection metadata
- native image preparation
This gives Quarkus practical advantages:
- fast startup
- low memory usage
- strong fit for containers and autoscaling
Quarkus supports imperative and reactive styles. Teams can keep simple REST code for common cases and use reactive APIs where non-blocking flows add value.
Q4. When would you choose JVM mode instead of native image?
Choose JVM mode when peak throughput, simpler debugging, shorter builds, or library compatibility matter more than minimal startup time and memory.
| Topic | JVM mode | Native image |
|---|---|---|
| Startup | Fast | Very fast |
| Memory | Low | Usually lower |
| Build time | Normal | Longer and more expensive |
| Debugging | Familiar JVM tooling | More constraints |
| Peak throughput | Strong after warm-up | Workload-dependent |
| Compatibility | Easier with dynamic runtime | Needs more validation |
Native image is useful for short-lived processes, scale-to-zero workloads, and services where cold start matters. JVM mode is often better for long-running services with hot code paths.
Q5. What standards does Quarkus support?
Quarkus builds on familiar Java standards, including:
- Jakarta REST
- CDI through Arc
- Jakarta Persistence with Hibernate ORM
- Bean Validation
- Jakarta Transactions
- JSON-B and JSON-P
It also supports MicroProfile specifications through SmallRye implementations, including:
- Config
- Fault Tolerance
- Health
- JWT
- OpenAPI
- REST Client
- Telemetry
Q6. How would you use virtual threads in Quarkus REST?
In Quarkus REST, @RunOnVirtualThread tells Quarkus to invoke the endpoint handler on a virtual thread.
import io.smallrye.common.annotation.RunOnVirtualThread;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
@Path("/orders")
public class OrderResource {
private final OrderService orderService;
public OrderResource(OrderService orderService) {
this.orderService = orderService;
}
@GET
@Path("/{id}")
@RunOnVirtualThread
public OrderResponse findById(@PathParam("id") Long id) {
return orderService.findById(id);
}
}
This keeps a synchronous programming model while improving scalability for blocking I/O workloads.
It still needs explicit limits:
- database connection pool size
- HTTP client timeouts
- retries and circuit breakers
- load testing at realistic concurrency
| Model | Good fit | Main risk |
|---|---|---|
| Worker thread | Traditional blocking endpoints | Limited worker pool |
| Event loop and reactive APIs | High-concurrency non-blocking flows | More complex code |
| Virtual thread | Blocking I/O with simple code | External resource saturation |
Q7. What is MicroProfile?
MicroProfile is a set of specifications for Java microservices. It defines APIs for common service needs:
- external configuration
- health checks
- fault tolerance
- type-safe REST clients
- OpenAPI documentation
- JWT security
- telemetry integration
Common runtimes with MicroProfile support include:
- Quarkus
- Open Liberty
- Helidon
- Payara Micro
- WildFly
Q8. What are the advantages and disadvantages of microservices?
Microservices help when a system needs independent ownership, deployment, and scaling.
Advantages:
- independent deployments
- clearer ownership boundaries
- independent scaling
- better fault isolation
- technology flexibility where justified
Disadvantages:
- distributed system complexity
- network latency and partial failures
- harder testing and debugging
- data consistency challenges
- more operational overhead
Production prerequisites:
- mature CI/CD
- strong observability
- clear domain boundaries
- service ownership
- automated infrastructure
- reliable incident response
For a small team or simple domain, a modular monolith is often the better starting point.
Q9. What are good monitoring and observability practices?
A backend service should expose three main signals:
- Metrics: numeric measurements over time.
- Logs: structured events.
- Traces: request flow across services.
| Signal | Common tools |
|---|---|
| Metrics | Prometheus, Grafana |
| Logs | Fluent Bit, Elasticsearch, Loki |
| Traces | Jaeger, Grafana Tempo |
| Alerts | Alertmanager, Grafana Alerting, incident tools |
For services, the RED method is useful:
- Rate: requests per second.
- Errors: failed requests.
- Duration: latency distribution.
For infrastructure, the USE method is useful:
- Utilization
- Saturation
- Errors
Q10. What is OpenTelemetry, and why does it matter?
OpenTelemetry is a vendor-neutral standard for generating, collecting, and exporting telemetry data. It covers metrics, logs, traces, and context propagation.
It is not a dashboard, database, or alerting system. It helps applications produce consistent telemetry that can be sent to different backends.
Teams use OpenTelemetry to:
- instrument services consistently
- propagate trace context across service calls
- correlate logs, metrics, and traces
- reduce vendor lock-in
- send telemetry through a collector before storage or analysis
Final Takeaway
For a senior Java backend interview, definitions are not enough.
- Java virtual threads simplify scalable blocking I/O.
- Quarkus optimizes startup and memory through build-time processing.
- JVM mode and native image are deployment trade-offs.
- Quarkus REST can use virtual threads for selected blocking endpoints.
- MicroProfile provides standard APIs for service concerns.
- Microservices require organizational maturity.
- Observability must support debugging, alerting, and incident response.
- OpenTelemetry standardizes instrumentation and telemetry export.
The expected answer is clear trade-off thinking backed by production awareness.