面试题答案
一键面试Python 的 asyncio 库
- 协程定义:
- 使用
async def
关键字定义协程函数。例如:
async def fetch_data(): await asyncio.sleep(1) return "Data fetched"
- 这里
await
用于暂停协程,等待asyncio.sleep(1)
这个异步操作完成,在等待期间,事件循环可以调度其他协程执行,从而避免线程阻塞。
- 使用
- 事件循环:
- 通过
asyncio.get_event_loop()
获取事件循环对象,然后使用loop.run_until_complete(coro)
来运行协程。例如:
import asyncio async def fetch_data(): await asyncio.sleep(1) return "Data fetched" loop = asyncio.get_event_loop() result = loop.run_until_complete(fetch_data()) print(result)
- 在现代 Python 中,也可以使用
asyncio.run()
来简化操作,asyncio.run()
内部会创建和管理事件循环。例如:
import asyncio async def fetch_data(): await asyncio.sleep(1) return "Data fetched" result = asyncio.run(fetch_data()) print(result)
- 通过
- 并发执行多个协程:
- 使用
asyncio.gather(*coros)
来并发运行多个协程。例如:
import asyncio async def task1(): await asyncio.sleep(1) return "Task 1 done" async def task2(): await asyncio.sleep(2) return "Task 2 done" async def main(): results = await asyncio.gather(task1(), task2()) print(results) asyncio.run(main())
- 这里
asyncio.gather
会同时启动task1
和task2
两个协程,在task1
和task2
等待asyncio.sleep
的过程中,事件循环可以调度其他可运行的协程,大大提升了并发处理能力。
- 使用
Node.js 的异步机制
- 回调函数:
- 早期在 Node.js 中,广泛使用回调函数来处理异步操作。例如读取文件:
const fs = require('fs'); fs.readFile('example.txt', 'utf8', (err, data) => { if (err) { console.error(err); return; } console.log(data); });
- 但是这种方式容易导致回调地狱,当异步操作嵌套层次过多时,代码可读性和维护性变差。
- Promise:
- Promise 是一种更优雅的处理异步操作的方式。例如使用
fs.promises
来读取文件:
const fs = require('fs').promises; fs.readFile('example.txt', 'utf8') .then(data => { console.log(data); }) .catch(err => { console.error(err); });
- 多个 Promise 可以通过
.then()
链式调用,避免了回调地狱。而且Promise.all([...promises])
可以并行执行多个 Promise,并在所有 Promise 都完成后返回结果,提升并发处理能力。例如:
const fs = require('fs').promises; const promise1 = fs.readFile('file1.txt', 'utf8'); const promise2 = fs.readFile('file2.txt', 'utf8'); Promise.all([promise1, promise2]) .then(([data1, data2]) => { console.log(data1, data2); }) .catch(err => { console.error(err); });
- Promise 是一种更优雅的处理异步操作的方式。例如使用
- async/await:
- 基于 Promise,
async/await
语法糖让异步代码看起来更像同步代码。例如:
const fs = require('fs').promises; async function readFiles() { try { const data1 = await fs.readFile('file1.txt', 'utf8'); const data2 = await fs.readFile('file2.txt', 'utf8'); console.log(data1, data2); } catch (err) { console.error(err); } } readFiles();
await
只能在async
函数内部使用,它暂停函数执行,直到 Promise 被解决(resolved)或被拒绝(rejected),在等待期间,Node.js 事件循环可以处理其他任务,提升了系统的并发处理能力。
- 基于 Promise,