面试题答案
一键面试原理
- 协程基础:协程是一种轻量级的线程,与操作系统线程不同,它由用户态调度。在Python中,
asyncio
库实现了协程式编程。async def
定义的函数是一个协程函数,调用它不会立即执行函数体,而是返回一个协程对象。 async/await
机制:await
只能在async def
定义的函数内部使用,它用于暂停协程的执行,等待一个可等待对象(如另一个协程)完成。这样可以在一个线程内实现多个任务的协作式调度,避免阻塞主线程,提高了I/O密集型任务(如网络请求)的效率。在高并发网络请求场景下,当一个网络请求在等待响应时,协程可以暂停并切换到其他请求任务,从而充分利用CPU资源,提升整体性能。
代码示例
以下是使用Python的asyncio
库结合async/await
处理多个并发网络请求的示例代码:
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.json()
async def main():
urls = [
'https://jsonplaceholder.typicode.com/todos/1',
'https://jsonplaceholder.typicode.com/todos/2',
'https://jsonplaceholder.typicode.com/todos/3'
]
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
results = await asyncio.gather(*tasks)
print(results)
if __name__ == "__main__":
asyncio.run(main())
在上述代码中:
fetch
函数是一个协程函数,用于发起一个HTTP GET请求并返回JSON格式的响应。async with
语句用于管理aiohttp
的会话资源,await response.json()
暂停fetch
协程,直到响应数据可用。main
函数也是一个协程函数,它定义了要请求的URL列表,并为每个URL创建一个fetch
任务。asyncio.gather
函数用于并发运行这些任务,并等待所有任务完成。await asyncio.gather(*tasks)
会暂停main
协程,直到所有fetch
任务完成,然后将所有任务的结果收集到results
列表中。asyncio.run(main())
用于运行整个异步程序,启动事件循环并执行main
协程。