Раздел 19 · 28 вопросов

CompletableFuture и асинхронность

28 вопросов и ответов в разделе CompletableFuture и асинхронность.

Russian CompletableFuture и асинхронность Исходный Markdown
Версии по языкам: English Russian Ukrainian

Вопросы этого раздела

  1. Что такое CompletableFuture и чем он отличается от Future
  2. Какие основные преимущества CompletableFuture перед Future
  3. Как создать CompletableFuture, который уже завершён с результатом?
  4. В чём разница между thenApply() и thenCompose()
  5. Что делают методы thenAccept() и thenRun()
  6. Как обрабатывать исключения в цепочке CompletableFuture
  7. В чём разница между handle(), exceptionally() и whenComplete()?
  8. Как комбинировать результаты нескольких CompletableFuture
  9. Что делает метод allOf() и когда его использовать
  10. Что делает метод anyOf() и в каких случаях он полезен
  11. В чём разница между thenApply() и thenApplyAsync()
  12. Какой пул потоков используется по умолчанию для async методов?
  13. Как указать свой Executor для CompletableFuture?
  14. Что такое блокирующий код и как его отличить от неблокирующего
  15. Почему важно избегать блокирующих операций в CompletableFuture
  16. Как правильно выполнить несколько параллельных запросов к микросервисам
  17. Что делает метод supplyAsync() и когда его использовать
  18. Как отменить выполнение CompletableFuture
  19. Что произойдёт, если в цепочке CompletableFuture возникнет исключение?
  20. Можно ли повторно использовать один CompletableFuture в нескольких цепочках?
  21. Как реализовать timeout для CompletableFuture
  22. Что делает метод orTimeout() в Java 9+
  23. В чём разница между thenCombine() и thenCompose()
  24. Как тестировать код с CompletableFuture
  25. В каких случаях лучше использовать CompletableFuture, а в каких — реактивное программирование?
  26. Что делает метод join() и чем он отличается от get()
  27. Можно ли вручную завершить CompletableFuture результатом
  28. Как реализовать retry логику с помощью CompletableFuture

Навигатор по разделу

28 вопросов для подготовки к собеседованию на Middle/Senior Java Developer.


📋 Все вопросы

# Вопрос Уровень сложности
1 Что такое CompletableFuture и чем он отличается от Future ⭐⭐
2 Какие основные преимущества CompletableFuture перед Future ⭐⭐
3 Как создать CompletableFuture, который уже завершён
4 В чём разница между thenApply() и thenCompose() ⭐⭐
5 Что делают методы thenAccept() и thenRun()
6 Как обрабатывать исключения в цепочке CompletableFuture ⭐⭐
7 В чём разница между handle(), exceptionally() и whenComplete() ⭐⭐
8 Как комбинировать результаты нескольких CompletableFuture ⭐⭐
9 Что делает метод allOf() и когда его использовать ⭐⭐
10 Что делает метод anyOf() и в каких случаях он полезен ⭐⭐
11 В чём разница между thenApply() и thenApplyAsync() ⭐⭐
12 Какой пул потоков используется по умолчанию для async методов ⭐⭐⭐
13 Как указать свой Executor для CompletableFuture ⭐⭐⭐
14 Что такое блокирующий код и как его отличить от неблокирующего ⭐⭐
15 Почему важно избегать блокирующих операций ⭐⭐⭐
16 Как правильно выполнить несколько параллельных запросов ⭐⭐⭐
17 Что делает метод supplyAsync() и когда его использовать ⭐⭐
18 Как отменить выполнение CompletableFuture ⭐⭐
19 Что произойдёт, если возникнет исключение ⭐⭐
20 Можно ли повторно использовать CompletableFuture ⭐⭐⭐
21 Как реализовать timeout для CompletableFuture ⭐⭐
22 Что делает метод orTimeout() в Java 9+ ⭐⭐
23 В чём разница между thenCombine() и thenCompose() ⭐⭐
24 Как тестировать код с CompletableFuture ⭐⭐
25 CompletableFuture vs реактивное программирование ⭐⭐⭐
26 Что делает метод join() и чем он отличается от get() ⭐⭐
27 Можно ли вручную завершить CompletableFuture результатом ⭐⭐⭐
28 Как реализовать retry логику с помощью CompletableFuture ⭐⭐⭐

🗺️ Карта зависимостей тем

                    ┌──────────────────────────────────────────┐
                    │   ОСНОВЫ (1-5)                           │
                    │   1. CompletableFuture vs Future          │
                    │   2. Преимущества                         │
                    │   3. completedFuture                      │
                    │   4. thenApply vs thenCompose             │
                    │   5. thenAccept vs thenRun                │
                    └──────────────────┬───────────────────────┘
                                       │
            ┌──────────────────────────┼──────────────────────────┐
            ▼                          ▼                          ▼
    ┌───────────────┐        ┌───────────────┐        ┌────────────────────┐
    │ ИСКЛЮЧЕНИЯ     │        │ КОМБИНИРОВАНИЕ │        │ EXECUTORS          │
    │ (6-7, 19)      │        │ (8-11, 23)     │        │ (12-13, 17)        │
    │ 6. Обработка   │        │ 8. Комбинир.   │        │ 12. Common Pool    │
    │ 7. handle/     │        │ 9. allOf       │        │ 13. Custom Exec.   │
    │    exceptionally│       │ 10. anyOf      │        │ 17. supplyAsync    │
    │ 19. Исключ.    │        │ 11. *Async     │        │                    │
    │    в цепочке   │        │ 23. thenCombine│        │                    │
    └───────┬───────┘        └───────┬───────┘        └────────┬───────────┘
            │                        │                        │
            └────────────────────────┼────────────────────────┘
                                     ▼
                    ┌──────────────────────────────────────────┐
                    │   BLOCKING И TIMEOUT (14-16, 20-22)      │
                    │   14. Blocking vs Non-blocking           │
                    │   15. Почему избегать blocking           │
                    │   16. Параллельные запросы               │
                    │   20. Timeout                            │
                    │   21. orTimeout (Java 9+)                │
                    └──────────────────────────────────────────┘
                                     │
            ┌────────────────────────┼────────────────────────┐
            ▼                        ▼                        ▼
    ┌───────────────┐        ┌───────────────┐        ┌────────────────────┐
    │ ADVANCED       │        │ TESTING        │        │ PATTERNS           │
    │ (18, 25-28)    │        │ (24)           │        │ (27)               │
    │ 18. Cancel     │        │ 24. Тестир.    │        │ 27. Retry          │
    │ 25. join vs get│        │                │        │                    │
    │ 26. obtrude    │        │                │        │                    │
    │ 25. CF vs      │        │                │        │                    │
    │    Reactive    │        │                │        │                    │
    └───────────────┘        └───────────────┘        └────────────────────┘

🎯 Рекомендуемый порядок изучения

🟢 Уровень Junior (недели 1-2)

Шаг Тема Файлы Цель
1 Основы Q1, Q2, Q3 Чем отличается от Future, completedFuture
2 Цепочки Q4, Q5 thenApply, thenCompose, thenAccept, thenRun
3 Исключения Q6, Q7 exceptionally, handle, whenComplete
4 join vs get Q25 Чем отличаются, почему join предпочтительнее

🟡 Уровень Middle (недели 3-4)

Шаг Тема Файлы Цель
1 Комбинирование Q8, Q9, Q10, Q23 allOf, anyOf, thenCombine, thenCompose
2 Async методы Q11, Q17 thenApply vs thenApplyAsync, supplyAsync
3 Blocking Q14, Q15 Что такое blocking, почему опасен в commonPool
4 Timeout Q20, Q21 Ручной timeout, orTimeout (Java 9+)
5 Testing Q24 Awaitility, Testcontainers, Virtual Threads

🔴 Уровень Senior (недели 5-6)

Шаг Тема Файлы Цель
1 Executors Q12, Q13 CommonPool internals, custom executors, ManagedBlocker
2 Parallel requests Q16 Semaphore + dedicated executor, error handling
3 Cancel & obtrude Q18, Q26 cancel() mechanics, obtrudeValue dangers
4 Reuse CF Q19 Fan-out, memory leak via reference chains
5 CF vs Reactive Q25 When to use each, Virtual Threads impact
6 Retry patterns Q28 exceptionallyCompose, exponential backoff + jitter

🔗 Ключевые связи между темами

Тема: Основы

Q1 (CF vs Future) → Q2 (Преимущества) → Q3 (completedFuture)

Тема: Цепочки

Q4 (thenApply vs thenCompose) → Q5 (thenAccept vs thenRun) → Q23 (thenCombine vs thenCompose)

Ключевые связи:

  • Q4 ↔ Q23: thenCompose = последовательно, thenCombine = параллельно
  • Q5 ↔ Q4: thenAccept = Consumer (нет результата), thenRun = Runnable (нет входа)

Тема: Исключения

Q6 (Обработка) → Q7 (handle/exceptionally/whenComplete) → Q19 (Исключение в цепочке)

Тема: Комбинирование

Q8 (Комбинирование) → Q9 (allOf) → Q10 (anyOf)

Тема: Executors и Blocking

Q12 (Common Pool) → Q13 (Custom Executor) → Q14 (Blocking) → Q15 (Почему избегать)
     ↓
Q17 (supplyAsync) → Q16 (Параллельные запросы)

Ключевые связи:

  • Q12 ↔ Q15: Blocking в commonPool → thread pool starvation
  • Q13 ↔ Q16: Параллельные запросы → dedicated executor, НЕ commonPool
  • Q14 ↔ Q15: Blocking vs non-blocking → почему blocking опасен

Тема: Timeout и Cancel

Q20 (Timeout) → Q21 (orTimeout)
Q18 (Cancel) → Q26 (obtrudeValue)

🎓 Шпаргалка: что знать для каждого уровня

🟢 Junior

  • CompletableFuture = async результат + цепочки коллбэков
  • thenApply = трансформация, thenAccept = побочный эффект, thenRun = действие без данных
  • exceptionally = fallback при ошибке, handle = обработка и успеха и ошибки
  • join() = blocking без checked exceptions, get() = blocking с checked exceptions

🟡 Middle

  • supplyAsync по умолчанию → ForkJoinPool.commonPool()
  • Blocking в commonPool → thread pool starvation для всех задач
  • allOf = ждём ВСЕ, anyOf = ждём ПЕРВЫЙ
  • orTimeout (Java 9+) = built-in timeout, в Java 8 — вручную через ScheduledExecutor
  • exceptionallyCompose (Java 12+) = неблокирующий retry

🔴 Senior

  • commonPool размер = availableProcessors - 1, меняется через System.setProperty
  • ManagedBlocker уведомляет ForkJoinPool о блокирующей операции
  • obtrudeValue нарушает контракт «однократного завершения» → race conditions
  • CF vs Reactive: CF = single result, Reactive = streams + backpressure
  • Virtual Threads (Java 21+) упрощают blocking-код → CF менее критичен
  • Retry: exponential backoff + jitter предотвращает thundering herd

📝 Формат каждого файла

Каждый файл содержит:

  • 🟢 Junior Level — базовое понимание, простые аналогии, примеры
  • 🟡 Middle Level — внутренности, типичные ошибки, практические примеры
  • 🔴 Senior Level — deep dive, edge cases, production experience, monitoring
  • 🎯 Шпаргалка для интервью — ключевые тезисы, частые вопросы, красные флаги, связанные темы