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.
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?
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.
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
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
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
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
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.
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
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.
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
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
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.
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
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
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
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
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.
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
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
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
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?
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
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.
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
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.
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
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
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
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
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.