Build an Employee Management System (In-Memory)
Difficulty: Easy · Category: Management System · Languages: Java 17, Python 3.11, Go 1.22, Node.js 20, TypeScript 5.x
Employee Management System (In-Memory)
Background
Every enterprise application needs an employee management layer. In this challenge you will build one that runs entirely in memory — no database, no Redis, no file system. This forces you to pick the right Java data structures, maintain multiple indexes for efficient lookups, and guarantee thread safety under concurrent access.
This is the kind of component that backs real-world admin dashboards, HR tools, and microservice caches where latency must stay sub-millisecond.
Your Task
Implement the EmployeeManagementMemoryContract interface. Your implementation must:
- CRUD — Add, retrieve, update (partial), and remove employees.
- Multi-Index Search — Query by department, role, or partial name (case-insensitive).
- Aggregation — Compute per-department statistics (count, average, min, max, total salary).
- Promotion — Atomically update an employee's role and salary.
- Thread Safety — All operations must be safe for concurrent access from multiple threads without data corruption.
- No External Storage — Everything must live in JVM heap memory. No database drivers, no Redis clients, no file I/O.
Recommended infrastructure:
kv-store— in-memory KV store matches the requirement for sub-millisecond latency.
How It Works
The platform injects your chosen infrastructure SDK(s) via constructor. For example, if you select KV Store:
public class MyEmployeeManagement implements EmployeeManagementMemoryContract {
private final KVStoreClient store;
public MyEmployeeManagement(KVStoreClient store) {
this.store = store;
}
// ... implement methods using store.*
}
See the SDK Docs tab for the full API reference of your chosen system.
Interface
public interface EmployeeManagementMemoryContract {
String addEmployee(String name, String department, String role, double salary);
Map<String, Object> getEmployee(String employeeId);
boolean updateEmployee(String employeeId, String department, String role, Double salary);
boolean removeEmployee(String employeeId);
List<Map<String, Object>> getByDepartment(String department);
List<Map<String, Object>> getByRole(String role);
List<Map<String, Object>> getAllEmployees();
Map<String, Object> getDepartmentStats(String department);
boolean promoteEmployee(String employeeId, String newRole, double salaryIncrease);
int getEmployeeCount();
List<Map<String, Object>> searchByName(String nameQuery);
}
Employee Map Format
Every method that returns an employee must produce a Map<String, Object> with:
| Key | Type | Description |
|---|---|---|
id | String | The unique employee ID |
name | String | Full name |
department | String | Department name |
role | String | Job role / title |
salary | Double | Current salary |
Department Statistics Format
getDepartmentStats returns a map with:
| Key | Type | Description |
|---|---|---|
count | Integer | Number of employees in department |
avgSalary | Double | Average salary (0.0 if empty) |
minSalary | Double | Minimum salary (0.0 if empty) |
maxSalary | Double | Maximum salary (0.0 if empty) |
totalSalary | Double | Sum of salaries (0.0 if empty) |
Example
id1 = addEmployee("Alice", "Engineering", "SDE-1", 75000)
id2 = addEmployee("Bob", "Engineering", "SDE-2", 95000)
getEmployee(id1)
→ {id: id1, name: "Alice", department: "Engineering", role: "SDE-1", salary: 75000.0}
getDepartmentStats("Engineering")
→ {count: 2, avgSalary: 85000.0, minSalary: 75000.0, maxSalary: 95000.0, totalSalary: 170000.0}
promoteEmployee(id1, "SDE-2", 10000)
getEmployee(id1).get("salary") → 85000.0
getEmployee(id1).get("role") → "SDE-2"
searchByName("ali") → [{...Alice's data...}]
removeEmployee(id1)
getEmployee(id1) → null
Constraints
name,department,roleare non-null, non-empty stringssalaryis always > 0getEmployeereturnsnullfor non-existent IDs- Search/list methods return empty lists, never
null updateEmployeeapplies only non-null parameters (partial update)searchByNameis case-insensitive and supports partial matches
Design Hints
- Primary index:
ConcurrentHashMap<String, Employee>keyed by ID for O(1) lookups. - Secondary indexes: Consider
ConcurrentHashMap<String, Set<String>>for department→IDs and role→IDs mappings to avoid full scans. - ID generation:
UUID.randomUUID().toString()or anAtomicLongcounter. - Thread safety:
ConcurrentHashMap+synchronizedblocks for compound operations (promote = read + write), or useConcurrentHashMap.compute()for atomic updates. - Name search: For small-to-medium datasets, a linear scan with
String.toLowerCase().contains()is acceptable. For large datasets, consider a trie or inverted index.
Performance Expectations
Since everything is in-memory, the bar is high:
- Throughput: 50,000 ops/sec
- p99 Latency: < 1 ms
- Use lock-free or fine-grained locking — avoid global
synchronizedblocks.
Infrastructure your code runs against
- Key-Value Store
How your solution is graded
Your score combines functional correctness (40%), performance (40%) and code quality (20%).
- Target throughput: 50,000 operations/second
- Target p99 latency: 1 ms
- Load test concurrency: 8 concurrent clients
- Load test duration: 10 seconds
- Maximum error rate: 0.5%