level 4 - Expert (Concurrency, Scheduling, System Patterns) Flashcards
Focus: data structures, scheduling, parallelism (5 cards)
TaskScheduler with Concurrency Limit
Description
Implement a TaskScheduler class that allows you to schedule asynchronous tasks with a concurrency limit. The scheduler should ensure that no more than limit tasks run at the same time.
Each task is a function that returns a Promise. Tasks can complete at different times, and the scheduler should ensure new tasks start only after one of the current ones completes, while preserving order of task insertion.
๐ Example Usage
const scheduler = new TaskScheduler(2); const delay = (ms, val) => () => new Promise(res => setTimeout(() => res(val), ms)); scheduler.add(delay(1000, "A")).then(console.log); // resolves at t=1000ms scheduler.add(delay(500, "B")).then(console.log); // resolves at t=1000ms scheduler.add(delay(300, "C")).then(console.log); // resolves at t=1300ms scheduler.add(delay(400, "D")).then(console.log); // resolves at t=1500ms // Expected order of output // A // B // C // D
Code
// ๐ง Stubbed Implementation class TaskScheduler { constructor(limit) { this.limit = limit; // TODO: Initialize necessary queues and state variables } add(taskFn) { // TODO: Return a Promise and schedule task respecting concurrency } }
๐งช Test Suite
// ๐ Enforcement: Disallow forbidden patterns (function enforceSchedulerConstraints() { const source = TaskScheduler?.toString?.() || ""; const forbidden = ["eval", "Function", ".toString", "window", "globalThis"]; forbidden.forEach(term => { if (source.includes(term)) { throw new Error(`โ Forbidden pattern used in TaskScheduler(): "${term}" is not allowed.`); } }); })(); function runTaskSchedulerTests() { console.log("๐ Running TaskScheduler Tests..."); const delay = (ms, val) => () => new Promise((res) => setTimeout(() => { results.push(val); res(val); }, ms)); const results = []; const scheduler = new TaskScheduler(2); const start = Date.now(); const logTime = () => Math.round(Date.now() - start); const tasks = [ scheduler.add(delay(100, "A")), scheduler.add(delay(100, "B")), scheduler.add(delay(50, "C")), scheduler.add(delay(30, "D")), ]; Promise.all(tasks).then((values) => { console.log("โ All tasks completed"); console.log("๐งพ Results Order:", results.join(", ")); if (results.join("") !== "ABCD") { console.error("โ Task order incorrect."); } console.log("โฑ๏ธ Total Time:", logTime(), "ms"); }); } // โ Run Tests runTaskSchedulerTests();
class TaskScheduler { constructor(limit) { this.limit = limit; this.running = 0; this.queue = []; } add(taskFn) { return new Promise((resolve, reject) => { const run = () => { this.running++; taskFn() .then(resolve) .catch(reject) .finally(() => { this.running--; if (this.queue.length) { const next = this.queue.shift(); next(); } }); }; if (this.running < this.limit) { run(); } else { this.queue.push(run); } }); } }
LazyEvaluator โ Chainable Utility for Deferred Evaluation
Description
Implement a utility called LazyEvaluator that supports chained method calls like map, filter, and take, but defers execution until .evaluate() is explicitly called.
Requirements:
Initialize with an array: new LazyEvaluator([1, 2, 3, 4])
Chain operations:
* map(fn)
* .filter(fn)
* .take(n) โ takes first n results from the processed stream
Call .evaluate() to execute all queued operations and return the final array.
Example:
const lazy = new LazyEvaluator([1, 2, 3, 4, 5]) .map(x => x * 2) .filter(x => x > 5) .take(2) .evaluate(); // โ [6, 8]
๐ Constraints:
The implementation must not use any of the following:
* eval
* Function constructor
* .toString()
* Global variables (window, globalThis)
* Built-in utility libraries (like Lodash, etc.)
Code
// ๐งฑ Stubbed Implementation class LazyEvaluator { constructor(array) { this.array = array; // TODO: Store chain of operations without executing them } map(fn) { // TODO: Queue a map operation return this; } filter(fn) { // TODO: Queue a filter operation return this; } take(n) { // TODO: Queue a take operation return this; } evaluate() { // TODO: Apply queued operations in order, return final array } }
๐งช Test Suite
// ๐ Enforcement for forbidden patterns (function enforceLazyEvaluatorConstraints() { const source = LazyEvaluator?.toString?.(); const forbidden = ["eval", "Function", ".toString", "window", "globalThis"]; forbidden.forEach(term => { if (source?.includes(term)) { throw new Error(`โ Forbidden pattern used in LazyEvaluator: "${term}"`); } }); })(); function runLazyEvaluatorTests() { const assertDeepEqual = (desc, actual, expected) => { const pass = JSON.stringify(actual) === JSON.stringify(expected); console.log(`${pass ? "โ " : "โ"} ${desc}`); if (!pass) { console.log(` Expected: ${JSON.stringify(expected)}, but got: ${JSON.stringify(actual)}`); } }; const lazy1 = new LazyEvaluator([1, 2, 3, 4, 5]) .map(x => x * 2) .filter(x => x > 5) .take(2) .evaluate(); assertDeepEqual("Chained lazy evaluation works", lazy1, [6, 8]); const lazy2 = new LazyEvaluator([10, 20, 30, 40]) .filter(x => x >= 20) .map(x => x / 10) .evaluate(); assertDeepEqual("Filter before map", lazy2, [2, 3, 4]); const lazy3 = new LazyEvaluator([1, 2, 3, 4]) .take(2) .map(x => x * 3) .evaluate(); assertDeepEqual("Take before map", lazy3, [3, 6]); const lazy4 = new LazyEvaluator([]) .map(x => x + 1) .filter(x => x > 0) .evaluate(); assertDeepEqual("Empty array returns empty", lazy4, []); } runLazyEvaluatorTests();
class LazyEvaluator { constructor(array) { this.array = array; this.operations = []; } map(fn) { this.operations.push(arr => arr.map(fn)); return this; } filter(fn) { this.operations.push(arr => arr.filter(fn)); return this; } take(n) { this.operations.push(arr => arr.slice(0, n)); return this; } evaluate() { return this.operations.reduce((acc, op) => op(acc), this.array); } }
Safe JSON.parse
Description
Implement a function safeJsonParse(jsonString, fallback) that attempts to parse a given JSON string. If parsing fails due to invalid JSON, it must return the provided fallback value instead of throwing an error.
Requirements
Accept two arguments:
* jsonString: a string that might represent a JSON value.
* fallback: a fallback value to return in case parsing fails.
Must not throw an error for invalid JSON input.
Must return parsed object on success, or fallback on failure.
Examples
safeJsonParse('{"name":"Alice"}', {}); // โ { name: "Alice" } safeJsonParse('invalid JSON', { error: true }); // โ { error: true } safeJsonParse('[1,2,3]', []) // โ [1, 2, 3] safeJsonParse('42', 0) // โ 42
๐ Constraints
You must not use:
* eval
* Function constructor
* .toString()
* Global variables (window, globalThis)
* Third-party libraries (e.g., Lodash)
Code:
// ๐งฑ Stubbed Implementation function safeJsonParse(jsonString, fallback) { // TODO: Try parsing jsonString using JSON.parse // If parsing fails, return the fallback value }
// ๐ Constraint Enforcement (function enforceSafeJsonParseConstraints() { const source = safeJsonParse?.toString?.(); const forbidden = ["eval", "Function", ".toString", "window", "globalThis"]; forbidden.forEach(term => { if (source?.includes(term)) { throw new Error(`โ Forbidden pattern used in safeJsonParse(): "${term}" is not allowed.`); } }); })(); function runSafeJsonParseTests() { const assertDeepEqual = (desc, actual, expected) => { const pass = JSON.stringify(actual) === JSON.stringify(expected); console.log(`${pass ? "โ " : "โ"} ${desc}`); if (!pass) { console.log(` Expected: ${JSON.stringify(expected)}, but got: ${JSON.stringify(actual)}`); } }; assertDeepEqual( "Parses valid JSON object", safeJsonParse('{"x":10}', {}), { x: 10 } ); assertDeepEqual( "Parses valid JSON array", safeJsonParse('[1,2,3]', []), [1, 2, 3] ); assertDeepEqual( "Returns fallback for invalid JSON", safeJsonParse('not-json', { error: true }), { error: true } ); assertDeepEqual( "Returns number if valid JSON number", safeJsonParse('42', 0), 42 ); assertDeepEqual( "Returns null for JSON 'null'", safeJsonParse('null', 'default'), null ); } runSafeJsonParseTests();
function safeJsonParse(jsonString, fallback) { try { return JSON.parse(jsonString); } catch (e) { return fallback; } }
Reimplement setTimeout and setInterval
Description:
Your task is to implement:
* customSetTimeout(callback, delay) using only setInterval.
* customSetInterval(callback, delay) using only setTimeout.
You must not use setTimeout when implementing customSetTimeout, and likewise must not use setInterval when implementing customSetInterval.
โ ๏ธ Constraints:
Your implementation must not use any of the following:
* eval, Function, or .toString
* Any global/shared state across invocations
Code
// ๐ Reimplement setTimeout using setInterval function customSetTimeout(callback, delay) { // TODO: Use setInterval to trigger the callback only once after the delay } // ๐ Reimplement setInterval using setTimeout function customSetInterval(callback, delay) { // TODO: Use setTimeout to call the callback repeatedly every delay ms }
๐งช Test Suite
// ๐ Enforcements (function enforceConstraints() { const forbidden = ["eval", "Function", ".toString"]; const timeoutSource = customSetTimeout.toString(); const intervalSource = customSetInterval.toString(); forbidden.forEach(term => { if (timeoutSource.includes(term)) { throw new Error(`โ Forbidden pattern in customSetTimeout(): "${term}"`); } if (intervalSource.includes(term)) { throw new Error(`โ Forbidden pattern in customSetInterval(): "${term}"`); } }); if (timeoutSource.includes("setTimeout")) { throw new Error(`โ Do not use setTimeout inside customSetTimeout`); } if (intervalSource.includes("setInterval")) { throw new Error(`โ Do not use setInterval inside customSetInterval`); } })(); // โ Tests function runTests() { console.log("โถ๏ธ Running timing tests..."); const assertApproximately = (desc, actual, expected, threshold = 50) => { const diff = Math.abs(actual - expected); const passed = diff <= threshold; console.log(`${passed ? "โ " : "โ"} ${desc}`); if (!passed) { console.log(` Expected ~${expected}ms, but got ${actual}ms`); } }; // Test customSetTimeout const t1Start = Date.now(); customSetTimeout(() => { const elapsed = Date.now() - t1Start; assertApproximately("customSetTimeout executes after ~1000ms", elapsed, 1000); }, 1000); // Test customSetInterval let counter = 0; const t2Start = Date.now(); const cancel = customSetInterval(() => { counter++; const elapsed = Date.now() - t2Start; if (counter === 3) { assertApproximately("customSetInterval 3rd tick ~2000ms", elapsed, 2000); cancel(); // stop future intervals } }, 1000); } runTests();
function customSetTimeout(callback, delay) { const id = setInterval(() => { clearInterval(id); callback(); }, delay); } function customSetInterval(callback, delay) { let active = true; function loop() { if (!active) return; callback(); timeoutId = setTimeout(loop, delay); } let timeoutId = setTimeout(loop, delay); return () => { active = false; clearTimeout(timeoutId); }; }
FileSystem Simulation
Description
Design and implement a FileSystem class that simulates a simplified file system with a hierarchical directory structure.
๐ ๏ธ Your FileSystem should support:
* mkdir(path: string)
Create directories based on an absolute or relative path.
Intermediate directories should be created if they do not exist.
* ls(path?: string)
List contents of the given path, sorted lexicographically. If path is a file, return just the filename. If not provided, list contents of current directory.
* cd(path: string)
Change the current working directory to the target path. Paths can be absolute (start with /) or relative (like .., ., folder).
๐ Constraints
You must not use:
* eval
* Function constructor
* .toString (on functions or objects)
* You must simulate file system behavior in memory.
* Treat all entries as directories (no file content handling required for now).
* The root directory is โ/โ.
Code
class FileSystem { constructor() { // TODO: Initialize root and current directory } mkdir(path) { // TODO: Create directory at given path } ls(path = ".") { // TODO: Return sorted list of items in path } cd(path) { // TODO: Change current working directory } }
๐งช Test Suite
(function enforceConstraints() { const source = FileSystem.toString(); const forbidden = ["eval", "Function", ".toString"]; forbidden.forEach(term => { if (source.includes(term)) { throw new Error(`โ Forbidden pattern detected: "${term}" is not allowed.`); } }); })(); function runFileSystemTests() { const assert = (desc, actual, expected) => { const pass = JSON.stringify(actual) === JSON.stringify(expected); console.log(`${pass ? "โ " : "โ"} ${desc}`); if (!pass) { console.log(` Expected: ${JSON.stringify(expected)}`); console.log(` Got : ${JSON.stringify(actual)}`); } }; const fs = new FileSystem(); fs.mkdir('/a/b/c'); assert("mkdir should create nested directories", fs.ls('/a/b'), ['c']); fs.cd('/a/b/c'); fs.mkdir('x'); fs.mkdir('y'); assert("ls in current path shows created dirs", fs.ls(), ['x', 'y']); fs.cd('..'); assert("cd('..') moves up one level", fs.ls(), ['c']); fs.cd('/'); assert("cd('/') returns to root", fs.ls(), ['a']); fs.cd('a/b'); assert("cd supports relative paths", fs.ls(), ['c']); fs.cd('../../a'); assert("cd supports '../' navigation", fs.ls(), ['b']); fs.cd('/'); fs.mkdir('z'); assert("mkdir creates directories at root", fs.ls('/'), ['a', 'z']); } runFileSystemTests();
class FileSystem { constructor() { this.root = {}; this.cwd = this.root; this.cwdPath = ['/']; } _resolve(path) { const parts = path.split('/').filter(Boolean); const absolute = path.startsWith('/'); let node = absolute ? this.root : this.cwd; const trail = absolute ? ['/'] : [...this.cwdPath]; for (const part of parts) { if (part === '.') continue; else if (part === '..') { if (trail.length > 1) { trail.pop(); node = this._getNodeFromPath(trail); } } else { if (!node[part]) { node[part] = {}; } node = node[part]; trail.push(part); } } return { node, trail }; } _getNodeFromPath(pathArray) { let node = this.root; for (let i = 1; i < pathArray.length; i++) { node = node[pathArray[i]]; } return node; } mkdir(path) { this._resolve(path); // Just resolve and create intermediate directories } ls(path = '.') { const { node } = this._resolve(path); return Object.keys(node).sort(); } cd(path) { const { node, trail } = this._resolve(path); this.cwd = node; this.cwdPath = trail; } }