Screen 1 of 5

Futures — "I'll Get Back to You"

A Future is like ordering takeout. You place the order (start the computation), get a receipt (the Future object), and continue your day. When the food arrives, you eat (use the result).

import scala.concurrent.Future import scala.concurrent.ExecutionContext .Implicits.global // Start an async computation val futurePrice = Future { // This runs on a background thread Thread.sleep(1000) 42.99 } // Don't wait — react when it's done futurePrice.map(price => println(s"Price is $$price") ) // Chain multiple async steps val result = futurePrice .map(_ * 2) // double it .map(_ + 5) // add shipping
Import Future and an ExecutionContext (the thread pool that runs async tasks).
Future { ... } = "Run this code in the background." Returns immediately.
.map on a Future = "When the result arrives, transform it." Non-blocking!
Chain transformations: each .map runs only after the previous Future completes.
Screen 2 of 5

Future vs Await — Non-Blocking vs Blocking

This is a classic interview question. Know the difference cold.

import scala.concurrent.Await import scala.concurrent.duration._ val f = Future { 42 } // NON-BLOCKING: keep going, react later f.map(v => println(s"Got $v")) // BLOCKING: freeze this thread until done val result = Await.result(f, 2.seconds) // result = 42 (but thread was frozen!)
Future.map: "When you're done, call me." Your thread is free to do other work.
Await.result: "I'm going to SIT HERE and WAIT until you're done." Blocks the thread.
Await takes a timeout (2 seconds). If the Future isn't done by then, it throws an exception.
🎯 Interview Answer
Avoid Await in production code. It blocks threads, which defeats the purpose of async programming. Use it only in tests or main methods. In production, use .map, .flatMap, .recover, and for-comprehensions to work with Futures.
Screen 3 of 5

Akka Actors — Message Passing in Action

Watch actors communicate like coworkers sending Slack messages:

👤 Main App
Hey OrderActor, process order #42!
📦 OrderActor
Got it! Let me validate... ✅ Valid. Forwarding to PaymentActor.
📦 OrderActor → 💳 PaymentActor
Charge $99.99 for order #42.
💳 PaymentActor
Payment processed! Telling NotificationActor.
💳 PaymentActor → 📧 NotificationActor
Send confirmation email for order #42.
📧 NotificationActor
Email sent! ✉️ Each of us worked independently, no shared state, no locks!

🎭 What's an Actor?

A lightweight object that processes messages one at a time from its mailbox. No shared memory between actors — all communication via messages.

🛡️ Why Actors?

No locks, no race conditions, no deadlocks. Each actor is an island. If one crashes, its supervisor restarts it. Fault-tolerant by design.

Screen 4 of 5

The Concurrency Toolkit

Scala has multiple tools for different concurrency needs. Know which to pick.

⏳ scala.concurrent.Future

Built-in. Good for simple async tasks. "Fire and forget" or chain with map/flatMap. Part of the standard library.

🎭 Akka (Classic & Typed)

Actor-based. For complex distributed systems, clustering, event sourcing. Industry standard for high-concurrency Scala.

🐱 Cats Effect

Functional approach. Pure FP, referential transparency, IO monad. Popular with FP-heavy teams.

⚡ ZIO

Modern FP runtime. Built-in error handling, fiber-based concurrency, resource management. Growing fast.

🎯 Interview Tip
If asked "How does Scala handle concurrency?", mention the progression: Futures for simple async → Akka for distributed systems → Cats Effect / ZIO for pure functional approaches. Show you know the landscape.
Screen 5 of 5

Test Yourself 🧠

Q1: You need to fetch data from 3 APIs simultaneously without blocking. What do you use?
Thread.sleep after each call
Create 3 Futures and combine them with Future.sequence or for-comprehension
Await.result on each one sequentially
Use var to track completion
Q2: Why are Akka actors safer than traditional threads for concurrency?
Actors are faster than threads
Actors use less memory
Actors don't share mutable state — they communicate via immutable messages, eliminating race conditions
Actors automatically scale to multiple machines
Q3: When is Await.result acceptable to use?
Always — it's the standard way to get Future results
In web request handlers for API responses
Only in tests or main methods — never in production request paths
Only with Akka actors