skip to content

Asyncio Core

One event loop on one thread interleaving thousands of coroutines that yield at every await. Interviewers spend the most time here, because this is where candidates block the loop or forget to await.

part ofPythonoverview, primer and where to startread it →
on this pageshow

questions

page 2 of 2

How does asyncio.run() finalize async generators that are left suspended at shutdown?

level: seniorimportance: nice to knowfreq 22%

basics

~10 s

After cancelling the remaining tasks, asyncio.run() awaits loop.shutdown_asyncgens(), which calls aclose() on every async generator still suspended at a yield inside that loop, so their finally blocks run before the loop is closed.

open as a page

What does python -m asyncio ps <pid> print, and when would you reach for it?

level: seniorimportance: nice to knowfreq 15%

basics

~20 s

New in Python 3.14, it attaches to a running Python process by PID and prints a table of its pending asyncio tasks — id, name, coroutine stack and awaiter — with no restart and no change to the program.

open as a page

What is asyncio's transport and protocol layer, and when would you use it instead of streams?

level: seniorimportance: nice to knowfreq 24%

basics

~20 s

Transports own the socket and its write buffer; protocols are your callback object, receiving connection_made, data_received, eof_received and connection_lost. Streams are a coroutine-friendly façade built on that pair. Drop to protocols for lower per-connection overhead and zero-copy reads.

open as a page

When would you use asyncio.wait with FIRST_COMPLETED instead of asyncio.gather, and what must you clean up afterwards?

level: seniorimportance: nice to knowfreq 28%

basics

~20 s

Use asyncio.wait with return_when=asyncio.FIRST_COMPLETED when you only need the earliest answer, such as racing a cache against an authoritative source. It returns done and pending sets, raises nothing itself, and leaves the pending tasks running for you to cancel.

open as a page

showing 31–34 of 34