Skip to content

DAY 6 — Eventing & Usage-Based Systems (Advanced SDE-2)

You’re doing great. ​Day 6 is advanced SDE-2 / early SDE-3 territory — interviewers use these problems to test whether you can design internal frameworks, not just features.
Today you’ll work on:
Asynchronous systems
Decoupling producers & consumers
Accurate aggregation logic
Clean extensibility

🔴 DAY 6 — Eventing & Usage-Based Systems (Advanced SDE-2)

Concepts Introduced Today (Short & Practical)

1️⃣ Event-Driven Design (In-Memory)

Instead of calling methods directly:
You publish events
Subscribers react independently
This improves:
Decoupling
Extensibility
Testability

2️⃣ Accurate Aggregation

Billing systems fail when:
Counts are wrong
Double counting happens
Aggregates reset incorrectly
Interviewers focus on correctness over cleverness.

✅ Problem 1: In-Memory Event Bus (Pub-Sub)

📌 Problem Statement

Design an in-memory event bus that supports:
Multiple event types
Multiple subscribers per event
Asynchronous delivery

Functional Requirements

subscribe(eventType, handler)
publish(event)
Each subscriber receives the event exactly once
Publishing must not block

Example

subscribe("ORDER_CREATED", handler1)
subscribe("ORDER_CREATED", handler2)

publish(ORDER_CREATED)

→ handler1 called
→ handler2 called

🧩 Java Interfaces (DO NOT MODIFY)

public interface Event {
String getType();
}
public interface EventHandler {
void handle(Event event);
}
public interface EventBus {
void subscribe(String eventType, EventHandler handler);
void publish(Event event);
}

🧪 Driver Code (Auto Tests + Async Verification)

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

public class EventBusTest {

public static void main(String[] args) throws Exception {
EventBus bus = new InMemoryEventBus();

AtomicInteger counter = new AtomicInteger(0);

bus.subscribe("TEST_EVENT", e -> counter.incrementAndGet());
bus.subscribe("TEST_EVENT", e -> counter.incrementAndGet());

bus.publish(() -> "TEST_EVENT");

// async delivery
Thread.sleep(500);

assert counter.get() == 2;

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

🎯 What Interviewer Evaluates

Decoupling
Async execution
Thread safety
Clean handler management

✅ Problem 2: API Usage-Based Billing System

📌 Problem Statement

Design a billing system that:
Tracks API usage per customer
Supports pricing tiers
Aggregates monthly usage

Pricing Rules

Tier
Price per call
FREE
₹0
BASIC
₹1
PREMIUM
₹0.5
There are no rows in this table

Functional Requirements

recordUsage(customerId)
getMonthlyBill(customerId)
Tier is fixed per customer

Rules

Billing is usage × price
Usage resets every month (simulate via reset method)
Accurate counting (no double count)

Example

Customer: C1 (BASIC)
recordUsage() x 3

bill → ₹3

🧩 Java Interfaces (DO NOT MODIFY)

public enum PricingTier {
FREE,
BASIC,
PREMIUM
}
public interface BillingService {
void addCustomer(String customerId, PricingTier tier);
void recordUsage(String customerId);
double getMonthlyBill(String customerId);
void resetMonthlyUsage();
}

🧪 Driver Code (Auto Tests + Edge Cases)

public class BillingTest {

public static void main(String[] args) {
BillingService billing = new InMemoryBillingService();

billing.addCustomer("C1", PricingTier.BASIC);
billing.addCustomer("C2", PricingTier.PREMIUM);

billing.recordUsage("C1");
billing.recordUsage("C1");
billing.recordUsage("C1");

billing.recordUsage("C2");
billing.recordUsage("C2");

assert billing.getMonthlyBill("C1") == 3.0;
assert billing.getMonthlyBill("C2") == 1.0;

billing.resetMonthlyUsage();
assert billing.getMonthlyBill("C1") == 0.0;

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

🎯 What Interviewer Evaluates

Clean aggregation
Tier-based extensibility
Correct resets
Defensive coding (unknown customers?)

🧠 Day 6 Takeaways

After today, you should:
Design internal frameworks (event bus)
Handle async behavior confidently
Build correct billing logic
Think like a backend platform engineer
This is strong SDE-2+ signal.

⏭️ Final Step

If you say:
“Continue with Day 7”
You’ll do a full interview-simulation day:
Payment Rule Engine (rolling windows, rule chaining)
Retry Queue with DLQ (backoff, failure handling)
Day 7 is intentionally hard — exactly like real interviews.
Say the word 💪
 
Want to print your doc?
This is not the way.
Try clicking the ··· in the right corner or using a keyboard shortcut (
CtrlP
) instead.