Skip to main content

Quiz: Advanced Techniques

Test your knowledge on WebFlux, Redis, RabbitMQ, Scheduling, and WebSockets.

30 questions - Click on each question to reveal the answer.


Questions 1-10: Reactive Programming (WebFlux)​

Question 1: What is the difference between Spring MVC and WebFlux?

Answer:

Spring MVCWebFlux
BlockingNon-blocking
1 thread/requestEvent loop
Servlet APIReactive Streams
Tomcat, JettyNetty
Vertical scalabilityHorizontal scalability

Question 2: What is the difference between Mono and Flux?

Answer:

  • Mono: 0 or 1 element
  • Flux: 0 to N elements
Mono<User> user = userRepository.findById(1L);
Flux<User> users = userRepository.findAll();

Question 3: What are common Mono/Flux operators?

Answer:

OperatorDescription
mapSynchronous transformation
flatMapAsync transformation
filterFiltering
zipCombine
onErrorReturnError fallback
switchIfEmptyEmpty fallback
timeoutTime limit
retryRetry

Question 4: How to write a reactive controller?

Answer:

@RestController
@RequestMapping("/api/users")
public class UserController {

private final UserRepository repository;

@GetMapping
public Flux<User> getAll() {
return repository.findAll();
}

@GetMapping("/{id}")
public Mono<ResponseEntity<User>> getById(@PathVariable Long id) {
return repository.findById(id)
.map(ResponseEntity::ok)
.defaultIfEmpty(ResponseEntity.notFound().build());
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Mono<User> create(@RequestBody User user) {
return repository.save(user);
}
}

Question 5: What is R2DBC?

Answer: Reactive Relational Database Connectivity - non-blocking access to relational databases.

public interface UserRepository extends ReactiveCrudRepository<User, Long> {
Flux<User> findByEmail(String email);
}

Replaces blocking JPA/JDBC in reactive applications.


Question 6: How to use WebClient?

Answer:

@Service
public class ExternalApiService {

private final WebClient webClient;

public Mono<Data> fetchData(String id) {
return webClient.get()
.uri("/data/{id}", id)
.retrieve()
.bodyToMono(Data.class)
.timeout(Duration.ofSeconds(5))
.retry(3);
}
}

Question 7: Why never call block() in production?

Answer: block() blocks the thread, negating the benefits of reactive:

  • Blocks the event loop
  • Reduces throughput
  • Can cause deadlocks

Use only in tests.


Question 8: How to test reactive code?

Answer:

@Test
void shouldFindUser() {
Mono<User> userMono = userService.findById(1L);

StepVerifier.create(userMono)
.assertNext(user -> {
assertThat(user.getName()).isEqualTo("John");
})
.verifyComplete();
}

@Test
void shouldHandleError() {
Mono<User> userMono = userService.findById(999L);

StepVerifier.create(userMono)
.expectError(NotFoundException.class)
.verify();
}

Question 9: When to use WebFlux?

Answer:

  • High concurrency (thousands of connections)
  • Data streaming
  • Real-time applications
  • Integrations with many external calls

Avoid if: untrained team, blocking libraries, simple CRUD.


Question 10: How to handle errors reactively?

Answer:

return userRepository.findById(id)
.switchIfEmpty(Mono.error(new NotFoundException("User not found")))
.onErrorReturn(new User("Fallback"))
.onErrorResume(e -> {
log.error("Error: {}", e.getMessage());
return Mono.empty();
});

Questions 11-17: Caching with Redis​

Question 11: How to configure Spring Cache with Redis?

Answer:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
@Configuration
@EnableCaching
public class CacheConfig { }

Question 12: How to use @Cacheable?

Answer:

@Cacheable(value = "users", key = "#id")
public User findById(Long id) {
log.info("Fetching from DB");
return userRepository.findById(id).orElseThrow();
}

// First call: DB
// Subsequent calls: cache

Question 13: What is the difference between @Cacheable, @CachePut, and @CacheEvict?

Answer:

AnnotationBehavior
@CacheableReads from cache or executes and caches
@CachePutAlways executes and updates the cache
@CacheEvictRemoves from cache
@CachePut(value = "users", key = "#user.id")
public User update(User user) { }

@CacheEvict(value = "users", key = "#id")
public void delete(Long id) { }

@CacheEvict(value = "users", allEntries = true)
public void clearCache() { }

Question 14: How to configure cache TTL?

Answer:

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(30))
.disableCachingNullValues();

return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
}

Question 15: How to use RedisTemplate directly?

Answer:

@Service
public class SessionService {

private final RedisTemplate<String, Object> redisTemplate;

public void saveSession(String token, UserSession session) {
redisTemplate.opsForValue().set(
"session:" + token,
session,
Duration.ofHours(1)
);
}

public UserSession getSession(String token) {
return (UserSession) redisTemplate.opsForValue()
.get("session:" + token);
}
}

Question 16: How to handle Redis unavailability?

Answer:

@Configuration
public class CacheConfig extends CachingConfigurerSupport {

@Override
public CacheErrorHandler errorHandler() {
return new SimpleCacheErrorHandler() {
@Override
public void handleCacheGetError(RuntimeException ex, Cache cache, Object key) {
log.warn("Cache error: {}", ex.getMessage());
// Continue without cache
}
};
}
}

Question 17: When to cache?

Answer:

  • Frequently read, rarely modified data
  • Expensive computations
  • External API calls
  • Reference data (countries, categories)

Avoid: real-time data, sensitive personal data.


Questions 18-23: Messaging with RabbitMQ​

Question 18: How to configure RabbitMQ with Spring?

Answer:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest

Question 19: What are the types of RabbitMQ exchanges?

Answer:

TypeRouting
DirectExact routing key
FanoutBroadcast to all queues
TopicPattern matching (*.error, order.#)
HeadersBased on headers

Question 20: How to send a message?

Answer:

@Service
public class OrderProducer {

private final RabbitTemplate rabbitTemplate;

public void sendOrderEvent(OrderEvent event) {
rabbitTemplate.convertAndSend(
"order.exchange", // exchange
"order.created", // routing key
event // message
);
}
}

Question 21: How to receive a message?

Answer:

@Component
public class OrderListener {

@RabbitListener(queues = "order.queue")
public void handleOrder(OrderEvent event) {
log.info("Received: {}", event);
processOrder(event);
}
}

Question 22: What is a Dead Letter Queue?

Answer: Queue that receives failed messages (rejected, expired, max retries):

@Bean
public Queue orderQueue() {
return QueueBuilder.durable("order.queue")
.withArgument("x-dead-letter-exchange", "dlx.exchange")
.withArgument("x-dead-letter-routing-key", "dlq")
.build();
}

Allows analyzing and reprocessing errors.


Question 23: How to ensure message delivery?

Answer:

  1. Publisher confirms: exchange confirmation
  2. Consumer acks: processing confirmation
  3. Persistent messages: survives restart
  4. Durable queues: persistent queues
@RabbitListener(queues = "order.queue", ackMode = "MANUAL")
public void handle(OrderEvent event, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) {
try {
process(event);
channel.basicAck(tag, false);
} catch (Exception e) {
channel.basicNack(tag, false, false);
}
}

Questions 24-27: Scheduled Tasks​

Question 24: How to enable scheduling?

Answer:

@SpringBootApplication
@EnableScheduling
public class Application { }

Question 25: What are the options for @Scheduled?

Answer:

// Every 5 seconds
@Scheduled(fixedRate = 5000)

// 5 seconds after completion
@Scheduled(fixedDelay = 5000)

// Cron expression
@Scheduled(cron = "0 0 6 * * *") // Every day at 6 AM

// With initial delay
@Scheduled(fixedRate = 5000, initialDelay = 10000)

Question 26: How to write a Cron expression?

Answer:

┌───────────── second (0-59)
│ ┌───────────── minute (0-59)
│ │ ┌───────────── hour (0-23)
│ │ │ ┌───────────── day of month (1-31)
│ │ │ │ ┌───────────── month (1-12)
│ │ │ │ │ ┌───────────── day of week (0-7)
* * * * * *

Examples:

  • 0 0 * * * *: every hour
  • 0 0 9 * * MON-FRI: 9 AM on weekdays
  • 0 */15 * * * *: every 15 minutes

Question 27: How to run a method asynchronously?

Answer:

@EnableAsync
@Configuration
public class AsyncConfig { }

@Service
public class EmailService {

@Async
public CompletableFuture<Boolean> sendEmail(String to) {
// Executed in another thread
return CompletableFuture.completedFuture(true);
}
}

Questions 28-30: WebSockets​

Question 28: How to configure WebSocket with STOMP?

Answer:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic", "/queue");
registry.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}

Question 29: How to send and receive WebSocket messages?

Answer:

@Controller
public class ChatController {

@MessageMapping("/chat.send")
@SendTo("/topic/messages")
public ChatMessage send(ChatMessage message) {
return message;
}
}

// Programmatic sending
@Service
public class NotificationService {

private final SimpMessagingTemplate template;

public void notifyUser(String userId, Notification notif) {
template.convertAndSendToUser(userId, "/queue/notifications", notif);
}
}

Question 30: When to use WebSocket vs REST?

Answer:

WebSocketREST
Bidirectional communicationRequest-Response
Real-timeStatic data
Chat, notificationsCRUD, API
Persistent connectionShort connections
Games, tradingTraditional applications

Score​

ScoreLevel
27-30Excellent - Mastered advanced techniques
21-26Good - Some revisions needed
15-20Average - Review the chapters
Less than 15Needs improvement

Back to Module 14