본문으로 건너뛰기

취업 면접을 위한 Sayli

내 경험을 명확하게 전하세요.

내 프로젝트를 바탕으로, 어려운 질문에도 생각을 명확히 설명하세요.

제품 예시는 영어로 표시됩니다.

Technical interview: Senior engineer. Daniel Novak asks: Implement an async map with a concurrency limit. Preserve input order, stop scheduling on failure, and support cancellation. Sayli: Use a shared index and a fixed pool of workers. Each worker claims its index before awaiting, so two workers cannot claim the same item.

```ts
async function mapLimit<T, R>(
  items: readonly T[],
  limit: number,
  run: (item: T, signal?: AbortSignal) => Promise<R>,
  signal?: AbortSignal,
): Promise<R[]> {
  if (!Number.isInteger(limit) || limit < 1)
    throw new RangeError('limit must be a positive integer');
  signal?.throwIfAborted();

  const results = new Array<R>(items.length);
  let next = 0;
  let failed = false;

  async function worker() {
    while (!failed) {
      signal?.throwIfAborted();
      const i = next++;
      if (i >= items.length) return;
      try {
        results[i] = await run(items[i], signal);
      } catch (error) {
        failed = true;
        throw error;
      }
    }
  }

  await Promise.all(Array.from(
    { length: Math.min(limit, items.length) }, worker,
  ));
  return results;
}
```

**Why it works:** results are written by input index, not completion order. At most `limit` calls are in flight. A rejection stops new work; already-running tasks finish unless their implementation honours the abort signal.

**Edge cases:** empty input, a limit larger than the input, out-of-order completion, a rejected task, and cancellation before or during the call. Time is O(n) bookkeeping plus the async work; result storage is O(n).
Sayli의 답변 읽기

Use a shared index and a fixed pool of workers. Each worker claims its index before awaiting, so two workers cannot claim the same item.

ts
async function mapLimit<T, R>(
  items: readonly T[],
  limit: number,
  run: (item: T, signal?: AbortSignal) => Promise<R>,
  signal?: AbortSignal,
): Promise<R[]> {
  if (!Number.isInteger(limit) || limit < 1)
    throw new RangeError('limit must be a positive integer');
  signal?.throwIfAborted();

  const results = new Array<R>(items.length);
  let next = 0;
  let failed = false;

  async function worker() {
    while (!failed) {
      signal?.throwIfAborted();
      const i = next++;
      if (i >= items.length) return;
      try {
        results[i] = await run(items[i], signal);
      } catch (error) {
        failed = true;
        throw error;
      }
    }
  }

  await Promise.all(Array.from(
    { length: Math.min(limit, items.length) }, worker,
  ));
  return results;
}

Why it works: results are written by input index, not completion order. At most limit calls are in flight. A rejection stops new work; already-running tasks finish unless their implementation honours the abort signal.

Edge cases: empty input, a limit larger than the input, out-of-order completion, a rejected task, and cancellation before or during the call. Time is O(n) bookkeeping plus the async work; result storage is O(n).

다음 면접도 준비된 상태로.

질문, 내 답변, 다음에 준비할 내용까지 남겨두세요.

예시 1/3

결정은 남기고, 약속은 기억하세요.

Technical interview: Senior engineer. Daniel asked for an async map with a concurrency limit. You discussed keeping results in input order, stopping new work on failure and passing cancellation to each operation. Next steps: Practise the failure and cancellation walkthrough, You, Thu. Prepare tests for out-of-order results, You, Thu.

통화 예시 · Technical interview: Senior engineer

다음 면접에서 내 실력을 보여주세요.

무료로 시작하세요. 필요한 순간에 내 맥락을 바로.