Skip to content
tezvyn:

Top 30 Async Interview Questions and Answers

30 multiple-choice questions on Async, drawn from 30 bites out of the 92 tagged Async on Tezvyn. Answer them here or read straight down. Every question carries the correct option, why it is correct, and a link to the bite it came from.

30 questions. Pick an answer, or open “Show the answer” to read it.

Answers are graded in your browser. Nothing is saved, and no XP or streak is earned here. The app keeps score.

  1. Question 1 of 30

    You write an async def FastAPI endpoint that calls requests.get. What is the main risk?

    Show the answer

    Answer: c · The event loop is blocked, freezing concurrent request handling until the call finishes.

    The correct answer is C because calling a blocking library like requests inside async def stalls the event loop, stopping all other requests. The most tempting distractor is A because beginners often assume FastAPI magically threadpools any blocking code, but only def endpoints are run in a threadpool.

    Read the full bite: What is the difference between def and async def in Python and FastAPI?

  2. Question 2 of 30

    In which event loop phase do the majority of completed I/O callbacks, such as a finished network read, actually execute?

    Show the answer

    Answer: d · The poll phase, which retrieves and runs I/O completions

    The poll phase retrieves new I/O events and executes most of their callbacks. The timers phase only handles elapsed setTimeout/setInterval, not I/O completion.

    Read the full bite: Order of the Node.js event loop phases

  3. Question 3 of 30

    When building an async execution-time decorator for FastAPI, why is omitting functools.wraps on the inner wrapper considered a red flag?

    Show the answer

    Answer: b · It strips the original function's metadata, which breaks FastAPI's OpenAPI schema generation and dependency injection.

    functools.wraps preserves the original function's name, signature, and metadata, which FastAPI relies on to generate OpenAPI docs and resolve dependencies; omitting it exposes the wrapper's metadata instead. Distractor A is wrong because wraps has no effect on whether code runs synchronously or blocks the event loop.

    Read the full bite: Write an async decorator that logs execution time for FastAPI

  4. Question 4 of 30

    What is the primary consequence of running a long-running synchronous task in a Node.js application?

    Show the answer

    Answer: a · The application's event loop will become blocked, making the server unresponsive.

    The card states that a long-running synchronous computation will 'monopolize the single main thread, blocking the event loop entirely,' leading to an unresponsive application. Synchronous tasks are not automatically offloaded to background threads; they execute directly on the main thread, unlike asynchronous I/O operations.

    Read the full bite: The Node.js Event Loop: Concurrency on a Single Thread

  5. Question 5 of 30

    What is the primary benefit of splitting a CPU-intensive synchronous operation into smaller pieces using setTimeout(fn, 0)?

    Show the answer

    Answer: b · To allow the browser to process UI updates and user input between task segments.

    The card states that splitting work with setTimeout(fn, 0) allows yielding control back to the event loop, enabling the browser to process user input and render updates, keeping the UI alive. Option A is incorrect because this technique adds overhead and does not necessarily speed up the overall execution time; its purpose is responsiveness, not raw speed.

    Read the full bite: JavaScript's Event Loop: Macrotasks & Microtasks

  6. Question 6 of 30

    Which statement accurately describes how process.nextTick() callbacks are prioritized within the Node.js event loop?

    Show the answer

    Answer: b · They execute immediately after the current JavaScript operation, before any timers or I/O.

    process.nextTick() callbacks are processed with the highest precedence, immediately after the current JavaScript operation completes and before the event loop proceeds to microtasks, timers, or I/O. Option D is incorrect because nextTick callbacks are processed *before* the microtask queue.

    Read the full bite: process.nextTick(): Cutting in Line on the Event Loop

  7. Question 7 of 30

    In FastAPI, why should an async database session dependency wrap yield in try and place await session.close() in finally?

    Show the answer

    Answer: a · It guarantees cleanup runs even if the path operation raises an exception.

    A try/finally block guarantees that await session.close() runs even when the path operation raises an exception, preventing database connection leaks. The thread pool issue in distractor C is caused by using def instead of async def, not by omitting exception handling.

    Read the full bite: Implement an async database session dependency using yield for setup and teardown

  8. Question 8 of 30

    In a Dart isolate, what is the consequence of a microtask that keeps rescheduling new microtasks recursively?

    Show the answer

    Answer: a · The event queue is starved until the recursive microtask chain ends

    The event loop always drains the entire microtask queue before processing any event queue tasks, so a self-rescheduling microtask chain blocks the event queue indefinitely. Option C is wrong because Dart does not interleave the two queues one-for-one.

    Read the full bite: Explain Dart's event loop, microtask queue, event queue, and await behavior

  9. Question 9 of 30

    You write an async generator that awaits during resource teardown, but mistakenly decorate it with @contextmanager. What is the most likely result?

    Show the answer

    Answer: b · A runtime error occurs because the synchronous decorator cannot await inside the generator

    The card explicitly warns that @contextmanager is for synchronous generators only and cannot await, causing a crash. Distractor A is tempting because blocking the event loop is discussed as a general risk of async code, but the specific mistake of using the sync decorator with async cleanup results in a runtime error rather than silent blocking.

    Read the full bite: Python Async Context Managers

  10. Question 10 of 30

    When is the Swift Result type most advantageous for handling failable operations?

    Show the answer

    Answer: d · When an asynchronous operation needs to explicitly communicate either a success value or a specific error.

    The Result type shines in asynchronous programming, providing a standard and type-safe way to pass either a success value or a specific error, especially when errors cannot be propagated with 'throws' across completion handler boundaries. Option A is incorrect because 'throws' is generally preferred for synchronous functions.

    Read the full bite: The Result Type: Modeling Success and Failure

  11. Question 11 of 30

    When is a Dart Stream the most appropriate choice for handling asynchronous data?

    Show the answer

    Answer: d · Processing a series of real-time sensor readings from an IoT device.

    Option D describes a continuous flow of data (real-time sensor readings), which is the primary use case for Dart Streams, as they handle sequences of asynchronous events over time. Options A, C, and D all represent scenarios where a single asynchronous value is expected, making a Future a more appropriate and simpler choice.

    Read the full bite: Dart Streams: Asynchronous Data Sequences

  12. Question 12 of 30

    What happens if a Kotlin Flow is created but no terminal operator like .collect() is invoked?

    Show the answer

    Answer: b · The Flow's producer code will not execute, and no values will be emitted.

    Flows are 'cold,' meaning their producer code only executes when a terminal operator like .collect() is called. Without a collector, the flow builder block never runs, so no values are emitted. Option C is incorrect because nothing is emitted to be discarded.

    Read the full bite: Kotlin Flow: Asynchronous Data Streams

  13. Question 13 of 30

    Which statement about a Promise's state transitions is correct?

    Show the answer

    Answer: a · Once settled as fulfilled or rejected, the state is permanent and cannot change

    Settling is one-way and final; a Promise transitions from pending to exactly one of fulfilled or rejected and stays there. then callbacks run later as microtasks, not synchronously.

    Read the full bite: The three states of a JavaScript Promise

  14. Question 14 of 30

    Why does the Promise callback print before the setTimeout(0) callback despite both being scheduled in the same tick?

    Show the answer

    Answer: d · The microtask queue is fully drained before the next macrotask runs

    After the synchronous stack clears, all microtasks (Promise reactions) drain before any macrotask (setTimeout) runs. The delay value is not the deciding factor here; queue priority is.

    Read the full bite: Output order of sync, microtask, and macrotask

  15. Question 15 of 30

    What happens to the remaining requests when one input to Promise.all rejects?

    Show the answer

    Answer: b · The combined Promise rejects immediately, but the other requests still run to completion

    Promise.all rejects as soon as the first input rejects, but JavaScript Promises are not cancellable, so the other in-flight requests continue running. They simply have no remaining handler.

    Read the full bite: Running independent requests with Promise.all and race

  16. Question 16 of 30

    In classic Express 4, how should an error from an awaited database call inside async middleware reach the error handler?

    Show the answer

    Answer: c · Catch it and pass it to next(err) so the error-handling middleware runs

    Express 4 does not auto-catch async throws, so you must catch and forward with next(err) to trigger the four-argument error handler. Throwing alone leaves the request hanging.

    Read the full bite: Handling async errors in Express middleware

  17. Question 17 of 30

    Which statement accurately describes how to consume a Future<String> and handle errors idiomatically in Dart?

    Show the answer

    Answer: b · Use an async function with try/catch around an await, or chain .then() with .catchError() on the Future.

    Option B correctly identifies both callback-style and async/await patterns for handling values and errors. Option A is wrong because a Future<String> is a pending object, not an actual String, so assigning it directly causes a type mismatch and synchronous try/catch cannot catch its asynchronous errors.

    Read the full bite: Define a Dart Future, return Future<String>, and handle errors with both patterns.

  18. Question 18 of 30

    What is the practical consequence of declaring an async Dart function as void instead of Future<void>?

    Show the answer

    Answer: a · The caller gets no Future handle, so they cannot await completion or catch async errors.

    A void return type hides the implicit Future from the caller, which prevents awaiting completion and catching errors with try/catch. Option C is tempting but wrong because without a Future handle, exceptions become uncaught async errors instead of propagating to the caller.

    Read the full bite: Difference between Future<void> and void from an async function

  19. Question 19 of 30

    What happens when you call listen() again on a single-subscription Dart stream after the first listener has finished?

    Show the answer

    Answer: d · It throws a StateError because only one listener is ever permitted

    A single-subscription stream allows exactly one listener over its entire lifetime, so calling listen again throws a StateError even after the first listener completes. The idea that it resumes where the first left off is a common misconception because the runtime enforces the one-listener contract strictly, treating the stream as consumed rather than pausable.

    Read the full bite: Explain single-subscription vs broadcast Streams in Dart

  20. Question 20 of 30

    When using Future.wait to fetch user profiles concurrently, how do you isolate individual failures while preserving successful results?

    Show the answer

    Answer: b · Attach catchError to each future before passing the list to Future.wait, then filter out nulls afterward

    Attaching catchError to each future guarantees every item resolves, so Future.wait yields a full list where nulls represent failures that can be filtered out. Wrapping Future.wait in try-catch is a common mistake because it catches the batch error but discards all successful profiles that had already completed.

    Read the full bite: Fetch user profiles concurrently and handle individual failures

  21. Question 21 of 30

    When managing a StreamController inside a StatefulWidget, what is the primary risk of omitting close() in the dispose method?

    Show the answer

    Answer: c · The controller retains listeners and internal resources, leaking memory and preventing graceful isolate shutdown.

    The correct answer reflects that an open controller holds references to listeners and resources, which leaks memory and can prevent an isolate from shutting down. The most tempting distractor is the first option because it reverses the actual StateError behavior—adding events after close throws, not omitting close itself.

    Read the full bite: Explain StreamController, write a broadcast stream example, and why close it?

  22. Question 22 of 30

    Why does a callback scheduled with setTimeout(callback, 0) not execute immediately in JavaScript?

    Show the answer

    Answer: b · The event loop must wait for the Call Stack to be completely empty before processing any queued callbacks.

    The event loop's fundamental rule is to move tasks from the Job Queue to the Call Stack only when the Call Stack is empty, ensuring all current synchronous code finishes first. Option A, while sometimes true due to browser optimizations, is not the core reason for the ordering behavior described by the event loop.

    Read the full bite: The JavaScript Event Loop: Asynchronicity on a Single Thread

  23. Question 23 of 30

    Why is calling fs.readFileSync inside an Express request handler a problem under concurrent load?

    Show the answer

    Answer: c · It blocks the single event loop thread, stalling all other pending requests

    The sync read blocks the one event loop thread until it finishes, so every other request waits. It is not forbidden and does not spawn threads; the async version uses the libuv pool instead.

    Read the full bite: fs.readFileSync vs fs.readFile

  24. Question 24 of 30

    Which statement best describes the primary function of the Dart event loop?

    Show the answer

    Answer: b · It manages the sequential execution of asynchronous operations and user input on a single thread, ensuring the UI remains responsive.

    The card explicitly states the event loop is a "single-threaded task manager" whose purpose is "to keep a user interface responsive" by processing events "one at a time." Option B accurately reflects this. Option C is incorrect because the event loop is single-threaded; heavy CPU tasks require spawning a new Isolate, not parallel execution by the event loop itself.

    Read the full bite: The Dart Event Loop: Your App's Task Manager

  25. Question 25 of 30

    A developer implements a CPU-intensive image resize inside an async def FastAPI endpoint. Under concurrent load, what is the most likely outcome?

    Show the answer

    Answer: b · The event loop blocks during each resize, starving other concurrent requests

    CPU-intensive work inside async def never yields control to the event loop, so it starves other requests on the same worker. FastAPI only runs regular def routes in a thread pool, and async does not create parallel multicore execution.

    Read the full bite: Async Path Operations in FastAPI

  26. Question 26 of 30

    What is the fundamental mechanism by which Promise.then() enables sequential asynchronous operations?

    Show the answer

    Answer: a · Each call to .then() returns a new promise, whose resolution depends on the preceding handler's outcome.

    The core mechanism for chaining is that every .then() call creates and returns a new promise, allowing the next step in the sequence to wait for the previous one's resolution. Option C describes the outcome but not the underlying mechanism of how this sequential execution is achieved. Option B describes a common misconception where multiple handlers attached to the *same* promise execute in parallel, not sequentially.

    Read the full bite: Promise.then(): Each Call Returns a New Promise

  27. Question 27 of 30

    Which statement accurately describes the default behavior of Future.wait when one of its constituent futures encounters an error?

    Show the answer

    Answer: a · It fails with the error from the first future that failed, discarding all other results.

    Future.wait operates on an 'all or nothing' principle by default; if any of the provided futures fail, the entire Future.wait operation fails with that error, and any results from other successful futures are discarded. It does not return partial results or indicate failure with nulls.

    Read the full bite: Future.wait: Run Concurrent Dart Operations

  28. Question 28 of 30

    What is a significant limitation of util.promisify when used with callback-based functions?

    Show the answer

    Answer: a · It only resolves with the first successful value if the callback provides multiple.

    The card states that "If a callback provides multiple success values, like (err, val1, val2), promisify will only resolve with val1." Option D is incorrect because util.promisify provides its own internal callback to check for errors, not relying on the original function's error handling implementation.

    Read the full bite: Node.js util.promisify: From Callbacks to Promises

  29. Question 29 of 30

    Which scenario best describes when a Dart Stream is the most appropriate choice?

    Show the answer

    Answer: b · When you want to process a series of data events as they become available over time.

    A Stream is specifically designed to handle a sequence of asynchronous events delivered over time, acting as a data pipeline. Option A describes the primary use case for a Future, which handles a single asynchronous result.

    Read the full bite: Dart's Stream: Asynchronous Data Pipelines

  30. Question 30 of 30

    When is it essential to use StreamController.broadcast() instead of the default StreamController() constructor?

    Show the answer

    Answer: a · When the stream is expected to have multiple independent listeners at the same time.

    The card explicitly states that the default StreamController() creates a single-subscription stream and will throw an error if multiple listeners try to subscribe. StreamController.broadcast() is specifically for scenarios requiring multiple listeners. Other options describe features not directly related to this distinction.

    Read the full bite: StreamController: The Faucet for Your Data Stream

Could you explain these out loud?

That is what an interview actually tests. Tezvyn gives you questions like these with what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon