Skip to content

DAY 4 — Concurrency, Scheduling & Consistency (SDE-2 Critical)

Excellent. ​Day 4 is where many SDE-2 candidates break — because now concurrency + correctness are tested together.
Interviewers expect:
You know Java concurrency primitives
You protect invariants under race conditions
You don’t over-engineer, but you also don’t hand-wave
You’ll feel this day is harder than previous ones — that’s intentional.

🔵 DAY 4 — Concurrency, Scheduling & Consistency (SDE-2 Critical)

Concepts Introduced Today (Short + Interview-Relevant)

1️⃣ Concurrency ≠ Multithreading

Concurrency is about:
Correctness under race
Atomicity
Visibility
A solution that “works in single thread” is ❌ today.

2️⃣ Time + Threads = Tricky

Schedulers, delays, cancellation — interviewers check:
Do tasks execute at the right time?
Do canceled tasks really stop?
Does the system leak threads?

3️⃣ Consistency Over Performance

Overselling inventory or executing a task twice is instant rejection.

✅ Problem 1: Concurrent Task Scheduler

📌 Problem Statement

Design an in-memory task scheduler that:
Executes tasks at a future timestamp
Supports cancellation
Is thread-safe

Functional Requirements

schedule(taskId, runnable, executeAtMillis)
cancel(taskId)
Task should run once
Cancelled tasks must never execute

Example

schedule("t1", task, now + 2 sec)
cancel("t1")
→ task never runs

🧩 Java Interfaces (DO NOT MODIFY)

public interface TaskScheduler {
void schedule(String taskId, Runnable task, long executeAtMillis);
boolean cancel(String taskId);
}

🧪 Driver Code (Auto Tests + Edge Cases)

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class TaskSchedulerTest {

public static void main(String[] args) throws Exception {
TaskScheduler scheduler = new InMemoryTaskScheduler();

AtomicInteger counter = new AtomicInteger(0);

scheduler.schedule("task1", counter::incrementAndGet,
System.currentTimeMillis() + 1000);

Thread.sleep(1500);
assert counter.get() == 1;

// Cancellation test
scheduler.schedule("task2", counter::incrementAndGet,
System.currentTimeMillis() + 1000);
boolean cancelled = scheduler.cancel("task2");
assert cancelled;

Thread.sleep(1500);
assert counter.get() == 1;

// Cancel non-existent
assert !scheduler.cancel("missing");

System.out.println("✅ TaskScheduler tests passed");
}
}

🎯 What Interviewer Evaluates

Correct scheduling
Thread safety
No double execution
Clean shutdown strategy (if asked)

✅ Problem 2: Inventory Management System (Oversell Prevention)

📌 Problem Statement

Design an inventory system that supports:
Adding stock
Reserving stock
Releasing stock
Preventing oversell under concurrency

Functional Requirements

addStock(productId, quantity)
reserve(productId, quantity) → fails if insufficient
release(productId, quantity)
getAvailableStock(productId)

Rules

Stock can never go negative
Concurrent reservations must be safe
Release restores availability

Example

addStock("P1", 10)

Thread A: reserve 6 → success
Thread B: reserve 6 → fail

available = 4

🧩 Java Interfaces (DO NOT MODIFY)

public interface InventoryManager {
void addStock(String productId, int quantity);
boolean reserve(String productId, int quantity);
void release(String productId, int quantity);
int getAvailableStock(String productId);
}

🧪 Driver Code (Auto Tests + Concurrency)

import java.util.concurrent.*;

public class InventoryTest {

public static void main(String[] args) throws Exception {
InventoryManager inventory = new InMemoryInventoryManager();
inventory.addStock("P1", 10);

ExecutorService executor = Executors.newFixedThreadPool(2);

Callable<Boolean> t1 = () -> inventory.reserve("P1", 6);
Callable<Boolean> t2 = () -> inventory.reserve("P1", 6);

Future<Boolean> f1 = executor.submit(t1);
Future<Boolean> f2 = executor.submit(t2);

boolean r1 = f1.get();
boolean r2 = f2.get();

assert r1 ^ r2; // only one should succeed
assert inventory.getAvailableStock("P1") == 4;

// Release test
inventory.release("P1", 2);
assert inventory.getAvailableStock("P1") == 6;

executor.shutdown();
System.out.println("✅ Inventory tests passed");
}
}

🎯 What Interviewer Evaluates

Atomicity of operations
Lock granularity
Correctness under race
No oversell, ever

🧠 Day 4 Takeaways

After Day 4, you should be able to:
Write thread-safe production code
Defend your locking strategy
Avoid race conditions confidently
Handle time + concurrency together
This is where strong SDE-2s separate from average ones.
 
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.