`asyncio`: quando ajuda e quando não
Pergunta
Como `async`/`await` do Python (asyncio) difere de threads, e em que tipo de carga ele ajuda?
Resposta esperada
asyncio roda um event loop single-thread: `await` num ponto de I/O (rede, disco assíncrono) cede o controle pro loop, que roda outra corrotina enquanto aquela espera — concorrência cooperativa, sem o custo de threads nem as races de memória compartilhada (dentro da mesma thread). Ajuda MUITO em carga I/O-bound com alta concorrência: milhares de conexões, chamadas a várias APIs em paralelo, websockets. NÃO ajuda em CPU-bound — uma corrotina que faz um loop pesado sem `await` bloqueia o loop inteiro (igual bloquear o event loop do Node); pra isso, `run_in_executor` (thread/process pool). Pegadinha: não dá pra misturar livremente — chamar uma função bloqueante síncrona (um driver de banco não-async, `requests`, `time.sleep`) dentro de uma corrotina trava tudo; o ecossistema precisa ser async de ponta a ponta (`asyncpg`, `httpx`, `aiofiles`).
Por que perguntam isso
Pergunta pleno/sênior de Python. Paralelo direto com o event loop do Node. Sinal de experiência: 'não misture bloqueante síncrono' e `run_in_executor` pra CPU.