面试题答案
一键面试结合方式及关键技术点
- 理解异步编程:asyncio 是 Python 用于编写异步代码的库,基于事件循环(event loop)。关键在于理解如何将 SocketServer 的同步操作转换为异步操作。
- 重写处理逻辑:使用
async
和await
关键字将传统的同步处理函数(如handle
方法)转换为异步函数。await
用于暂停异步函数的执行,直到等待的Future
或coroutine
完成。 - 事件循环管理:获取并使用 asyncio 的事件循环来调度异步任务。
可能遇到的问题
- 兼容性问题:SocketServer 最初设计为同步编程模型,部分功能可能与 asyncio 不兼容,需要小心重写。
- 资源管理:在异步环境下,资源(如文件描述符、连接等)的管理需要更谨慎,避免资源泄漏。
- 调试困难:异步代码的调试相对复杂,因为执行顺序不直观,需要借助合适的调试工具和日志记录。
示例代码
import asyncio
import socket
class AsyncTCPServer(asyncio.Protocol):
def connection_made(self, transport):
peername = transport.get_extra_info('peername')
print('Connection from {}'.format(peername))
self.transport = transport
async def handle(self, data):
# 模拟一些异步操作
await asyncio.sleep(1)
message = 'You sent: {!r}'.format(data.decode())
self.transport.write(message.encode())
def data_received(self, data):
asyncio.create_task(self.handle(data))
async def main():
loop = asyncio.get_running_loop()
server = await loop.create_server(
lambda: AsyncTCPServer(),
'127.0.0.1', 8888)
async with server:
await server.serve_forever()
if __name__ == "__main__":
asyncio.run(main())
上述代码创建了一个基于 asyncio 的简单 TCP 服务器。AsyncTCPServer
类继承自 asyncio.Protocol
,并重写了 connection_made
和 data_received
方法。handle
方法模拟了一个异步处理逻辑,data_received
方法将处理逻辑封装成异步任务。main
函数负责创建并启动服务器,asyncio.run
用于运行异步主函数。