Розділ 19 · 28 питань

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

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

Ukrainian 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. Що робить метод supplyAsync() і коли його використовувати
  17. Як правильно виконати декілька паралельних запитів до мікросервісів
  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
  • 🎯 Шпаргалка для співбесіди — ключові тези, часті питання, червоні прапорці, пов’язані теми