当前位置:首页>python>python开发工程师解答(1)

python开发工程师解答(1)

  • 2026-09-10 21:01:17
python开发工程师解答(1)

题 1:实现一个LRU缓存机制

实现一个类 LRUCache,支持以下操作:

cache = LRUCache(2)# 容量为2cache.put(1, 1)cache.put(2, 2)print(cache.get(1))# 返回 1cache.put(3, 3)    # 移除键 2print(cache.get(2))# 返回 -1(未找到)

要求:

用 OrderedDict 或双向链表 + 字典 实现;

get 和 put 都必须是 O(1) 时间复杂度。

要求:实现 get / put 操作,时间复杂度 O(1)

示例:

cache=LRUCache(2)cache.put(1, 1)cache.put(2, 2)print(cache.get(1))  # 输出 1cache.put(3, 3)      # 删除键 2print(cache.get(2))  # 输出 -1
ifkeyinself.cache:self.cache.move_to_end(key)self.cache[key] =valueiflen(self.cache) >self.capacity:self.cache.popitem(last=False)

from collections import OrderedDictclass LRUCache:    def __init__(self, capacity: int):        self.cache = OrderedDict()        self.capacity = capacity    def get(self, key: int) -> int:        if key not in self.cache:            return -1  # 如果key不存在,返回-1        else:            # 将访问的key移动到字典的末尾,表示最近使用过            self.cache.move_to_end(key)            return self.cache[key]    def put(self, key: int, value: int) -> None:        if key in self.cache:            # 如果key已存在,先删除旧的键值对,然后再添加新的,这样可以保持顺序正确            del self.cache[key]            self.cache[key] = value            self.cache.move_to_end(key)  # 移动到末尾表示最近使用过        else:            if len(self.cache) >= self.capacity:                # 如果缓存已满,则删除最久未使用的项(OrderedDict的第一个元素)                self.cache.popitem(last=False)            self.cache[key] = value            self.cache.move_to_end(key)  # 移动到末尾表示最近使用过# 使用示例:cache = LRUCache(2)cache.put(1, 1)cache.put(2, 2)print(cache.get(1))       # 返回  1cache.put(3, 3)          # 该操作会使关键字 2 作废print(cache.get(2))       # 返回 -1 (未找到)cache.put(4, 4)          # 该操作会使关键字 1 作废print(cache.get(1))       # 返回 -1 (未找到)print(cache.get(3))       # 返回  3print(cache.get(4))       # 返回  4

在这个实现中:

__init__ 方法初始化缓存的容量。

get 方法检查键是否存在于缓存中,如果存在,则将其移到字典的末尾(表示最近使用),然后返回其值。如果不存在,则返回-1。

put 方法首先检查键是否已存在,如果存在则更新其值并将其移到末尾。如果不存在,则先检查缓存是否已满,如果已满,则删除最久未使用的项(即字典中的第一个项),然后添加新的键值对并将其移到末尾。

这样,我们就实现了LRU缓存机制。

关键点总结

‌O(1) 时间复杂度‌:通过哈希表实现快速查找,双向链表实现快速插入/删除;

‌访问顺序维护‌:每次 get 或 put(新键)都将对应节点移至链表头部;

‌淘汰策略‌:链表尾部始终为最久未使用节点,容量超限时删除它。

如需完整 LeetCode 题目练习,可访问:LeetCode 146. LRU 缓存

https://leetcode.cn/problems/lru-cache/description/ ‌

题 2:实现一个简单的并发爬取

编写程序,使用 asyncio + aiohttp 并发请求以下 URL 列表:

urls = ["https://example.com/a", "https://example.com/b", "https://example.com/c"]

要求:

输出每个请求的响应状态码;

限制同时并发数量不超过 3;

加入超时与异常捕获逻辑。

import asyncioimport aiohttpasync def fetch(session, url):    async with session.get(url) as response:        return await response.text()async def main():    urls = [        'https://www.example.com',        'https://www.google.com',        'https://www.python.org',        'https://www.github.com'    ]    async with aiohttp.ClientSession() as session:        tasks = [fetch(session, url) for url in urls]        responses = await asyncio.gather(*tasks)        for i, response in enumerate(responses):            print(f"Response from {urls[i]}:")            print(response[:100])  # 打印前100个字符作为示例            print("..." * 5)  # 添加省略号以简化输出# 运行主函数if __name__ == '__main__':    asyncio.run(main())

程序解释:

‌导入库‌:导入 asyncio 和 aiohttp。

‌定义 fetch 函数‌:这是一个异步函数,它使用 aiohttp 的 ClientSession 来发起 GET 请求,并返回响应的文本内容。

‌定义 main 函数‌:这是主函数,它定义了一个 URL 列表,并使用 aiohttp.ClientSession 来管理会话。它创建了一个任务列表,每个任务对应一个 URL 的请求,然后使用 asyncio.gather 来并发执行这些任务。

‌打印响应‌:对于每个响应,程序打印出该 URL 的响应内容的前100个字符,并添加省略号以简化输出。

‌运行主函数‌:使用 asyncio.run(main()) 来运行主函数。

这个程序展示了如何使用 asyncio 和 aiohttp 进行并发 HTTP 请求,非常适合于网络爬虫和数据抓取任务。你可以根据需要修改 URL 列表和响应处理逻辑

最新文章

随机文章