Quarkus Interview Questions and Answers
22 hand-picked Quarkus interview questions with
detailed answers. Open the interactive version above to search, filter
by difficulty, run code, bookmark questions and track your progress.
What is Quarkus and how does it differ from Spring Boot?
Quarkus is a Kubernetes-native Java framework optimised for GraalVM native compilation and fast startup. Key differences from Spring Boot:
- Build-time processing — much configuration and classpath scanning happens at build time, not runtime.
- Lower memory footprint — especially in native mode (tens of MB vs hundreds).
- Faster startup — JVM mode is fast; native mode starts in milliseconds.
- Reactive-first — built on Vert.x and RESTEasy Reactive; imperative style also supported.
- Extensions — modular add-ons (like Boot starters) for Hibernate, Kafka, Redis, etc.
Both use CDI-style dependency injection; Quarkus targets cloud/serverless, Spring Boot has the larger enterprise ecosystem.
@QuarkusMain
public class App {
public static void main(String[] args) {
Quarkus.run(args);
}
}
What is Quarkus native compilation and GraalVM?
GraalVM Native Image compiles Java bytecode ahead-of-time (AOT) into a standalone native binary — no JVM needed at runtime. Benefits: ~10ms startup, ~20–50MB RSS, instant scale-up.
Tradeoffs: longer build times, no dynamic class loading at runtime, reflection must be declared (Quarkus handles most via build-time analysis). Build with ./mvnw package -Pnative.
Quarkus JVM mode is already fast — native is for extreme startup/memory requirements.
./mvnw package -Pnative -Dquarkus.native.container-build=true
How does dependency injection work in Quarkus?
Quarkus uses CDI (Contexts and Dependency Injection) — the Jakarta EE standard. Inject dependencies with @Inject on fields, constructors, or methods.
Bean scopes: @ApplicationScoped (singleton), @RequestScoped, @Dependent. Define beans with @ApplicationScoped on the class — no @Component equivalent needed.
Quarkus resolves the dependency graph at build time, eliminating runtime CDI container overhead.
@ApplicationScoped
public class OrderService {
private final OrderRepository repo;
@Inject
public OrderService(OrderRepository repo) {
this.repo = repo;
}
}
How do you create REST endpoints in Quarkus?
Use JAX-RS annotations via RESTEasy Reactive (default) or RESTEasy Classic:
@Path — base URI@GET, @POST, @PUT, @DELETE@PathParam, @QueryParam, @HeaderParam@Produces / @Consumes — content types
Return types can be synchronous or Uni<T> / Multi<T> for reactive endpoints.
@Path("/orders")
@ApplicationScoped
public class OrderResource {
@GET
@Path("/{id}")
public Order get(@PathParam("id") Long id) {
return orderService.find(id);
}
}
What are Uni and Multi in Quarkus?
Quarkus uses Mutiny for reactive programming:
Uni<T> — emits 0 or 1 item (like a Promise/Single). Use for single async results.Multi<T> — emits 0 to N items (like a Stream). Use for event streams or paginated results.
Composable with .onItem().transform(), .onFailure().recover(), .combine(). Non-blocking I/O on the Vert.x event loop.
@GET
public Uni<Order> get(@PathParam("id") Long id) {
return orderService.findAsync(id);
}
What is Hibernate Panache?
Panache is Quarkus's simplified ORM layer on top of Hibernate ORM. Two styles:
- Active Record — entity extends
PanacheEntity; call Person.findById(1) directly on the entity. - Repository — entity is a plain JPA class; repository extends
PanacheRepository<Person>.
Provides concise query methods, pagination, and integrates with reactive PostgreSQL drivers.
@Entity
public class Person extends PanacheEntity {
public String name;
public static List<Person> findByName(String name) {
return find("name", name).list();
}
}
How does configuration work in Quarkus?
Config via application.properties or application.yaml. Inject with @ConfigProperty:
Supports profiles (%dev, %prod), environment variables (automatic mapping), and type-safe config interfaces with @ConfigMapping.
External config via env vars is the standard for containers — no config baked into the image.
@ConfigProperty(name = "greeting.message")
String message;
# application.properties
%dev.greeting.message=Hello Dev
%prod.greeting.message=Hello
What is Quarkus dev mode?
Run with ./mvnw quarkus:dev for a development experience with:
- Live reload — code changes picked up without restart.
- Dev UI — browser dashboard at
/q/dev for config, extensions, continuous testing. - H2 dev services — auto-starts a test database if no datasource configured.
- Test continuous testing — tests re-run on file save.
./mvnw quarkus:dev
What are Quarkus extensions?
Extensions are modular add-ons that bring capabilities and auto-configuration — analogous to Spring Boot starters. Add via CLI or pom.xml:
quarkus extension add hibernate-orm-panache jdbc-postgresql smallrye-openapi
Each extension contributes build steps, runtime config, and dev services. Only included extensions are in the final binary — no bloat from unused features.
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache</artifactId>
</dependency>
Health checks and metrics in Quarkus.
SmallRye Health — /q/health (aggregated), /q/health/live (liveness), /q/health/ready (readiness). Implement custom checks with @Readiness / @Liveness on HealthCheck.
SmallRye Metrics — MicroProfile Metrics at /q/metrics. Annotate with @Counted, @Timed. Integrates with Prometheus via Micrometer.
@Readiness
@ApplicationScoped
public class DatabaseCheck implements HealthCheck {
public HealthCheckResponse call() {
return isDbUp() ? up("db") : down("db");
}
}
How do you secure REST endpoints in Quarkus?
Quarkus Security with extensions:
quarkus-oidc — OpenID Connect / OAuth2 integration.quarkus-smallrye-jwt — JWT bearer token validation.@RolesAllowed("admin") — restrict by role.@Authenticated — require any authenticated user.
Configure issuer, client, and JWKS URL in application.properties.
@GET
@RolesAllowed("admin")
@Path("/admin/users")
public List<User> listUsers() { ... }
How do you test Quarkus applications?
@QuarkusTest — boots the full application in test mode (fast thanks to build-time setup). Use @TestHTTPResource for injected test URLs.
RestAssured for HTTP testing. @InjectMock to replace CDI beans with mocks. Testcontainers for real PostgreSQL/Kafka in integration tests.
Dev services auto-provision databases in dev/test without manual Docker setup.
@QuarkusTest
class OrderResourceTest {
@Test
void testGet() {
given().when().get("/orders/1")
.then().statusCode(200);
}
}
Database migrations with Flyway in Quarkus.
Add quarkus-flyway extension. Place SQL scripts in src/main/resources/db/migration/ named V1__create_orders.sql, V2__add_status.sql.
Flyway runs migrations on startup automatically. Configure with quarkus.flyway.migrate-at-start=true.
# application.properties
quarkus.flyway.migrate-at-start=true
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost/orders
How do you schedule tasks in Quarkus?
Quarkus Scheduler extension — annotate methods with @Scheduled:
every = "10s" — fixed intervalcron = "0 0 1 * * ?" — cron expressiondelay = 5 — initial delay
Runs on worker threads by default — safe for blocking operations.
@Scheduled(every = "1h")
void cleanupExpiredSessions() {
sessionService.deleteExpired();
}
Caching in Quarkus.
Add quarkus-cache extension. Annotate methods with @CacheResult(cacheName = "users") to cache return values. @CacheInvalidate evicts entries.
Backends: Caffeine (in-memory, default) or Redis (quarkus-redis-cache) for distributed caching across pods.
@CacheResult(cacheName = "product-by-id")
public Product findById(Long id) {
return productRepo.findById(id);
}
How does Quarkus generate OpenAPI documentation?
Add quarkus-smallrye-openapi. Scans JAX-RS endpoints and generates an OpenAPI 3 spec automatically.
Access at /q/openapi (JSON/YAML). Swagger UI at /q/swagger-ui. Enrich with @Operation, @APIResponse, @Schema annotations.
@Operation(summary = "Get order by ID")
@APIResponse(responseCode = "200", description = "Order found")
@GET @Path("/{id}")
public Order get(@PathParam("id") Long id) { ... }
Global exception handling in Quarkus.
Implement ExceptionMapper<T extends Exception> — a JAX-RS provider that converts exceptions to HTTP responses:
Annotate with @Provider and implement toResponse(T exception). Quarkus discovers it via CDI.
For validation errors, quarkus-hibernate-validator returns 400 with constraint violation details automatically.
@Provider
public class NotFoundMapper implements ExceptionMapper<NotFoundException> {
public Response toResponse(NotFoundException e) {
return Response.status(404).entity(Map.of("error", e.getMessage())).build();
}
}
Transaction management in Quarkus.
Use @Transactional on CDI bean methods (from Narayana JTA). Default propagation: REQUIRED — joins existing transaction or creates new one.
Options: rollbackOn, dontRollbackOn, value = TxType.REQUIRES_NEW for independent transactions.
Works with Hibernate Panache — a single @Transactional method can call multiple repository operations atomically.
@Transactional
public void transfer(Long from, Long to, BigDecimal amount) {
accountRepo.debit(from, amount);
accountRepo.credit(to, amount);
}
How does Quarkus integrate with Kafka?
Add quarkus-smallrye-reactive-messaging-kafka. Use MicroProfile Reactive Messaging channels:
- Incoming —
@Incoming("orders") on a method consuming messages. - Outgoing —
@Outgoing("orders") on a method producing messages, or inject @Channel("orders") Emitter<Order>.
Configure broker, serializers, and consumer group in application.properties.
@Incoming("orders")
public CompletionStage<Void> process(Order order) {
return orderService.handle(order);
}
Blocking vs reactive endpoints — when to use which?
Reactive (Uni/Multi) — non-blocking I/O on the event loop. Best for high-concurrency I/O (many simultaneous requests, reactive DB drivers).
Blocking (imperative) — traditional synchronous code. Use @Blocking or run on a worker thread pool. Fine for most CRUD apps.
Virtual threads (Java 21+) — @RunOnVirtualThread gives blocking-style code with reactive-scale concurrency.
@GET
@RunOnVirtualThread // Java 21+
public Order get(@PathParam("id") Long id) {
return orderRepo.findById(id); // blocking JPA, but cheap on virtual thread
}
What are Quarkus profiles?
Profiles activate environment-specific configuration. Set via quarkus.profile=dev or %prod prefix in properties:
%dev.quarkus.log.level=DEBUG
%prod.quarkus.log.level=WARN
Default profiles: dev, test, prod. Custom profiles supported. Beans can be profile-specific with @IfBuildProfile("dev").
%dev.quarkus.datasource.jdbc.url=jdbc:h2:mem:test
%prod.quarkus.datasource.jdbc.url=${DATABASE_URL}
Quarkus and Kubernetes — what makes it cloud-native?
Quarkus generates Kubernetes manifests via extensions (quarkus-kubernetes, quarkus-openshift). Auto-configures:
- Health probes pointing to
/q/health/ready and /q/health/live - Resource limits based on native vs JVM mode
- Service discovery and config maps
- Container image via
quarkus-container-image-docker
Fast startup + low memory = higher pod density and faster autoscaling.
./mvnw package -Dquarkus.container-image.build=true