PYTHON_JOB_INTERVIEW Telegram 1089
🖥Задача: "Динамическое кэширование с ограничением памяти и частотой запросов"

🔖 Условие:

Реализуйте класс SmartCache, который работает следующим образом:

- Метод put(key: str, value: Any):
- Сохраняет значение по ключу.
- Если суммарный объем памяти, занимаемый всеми элементами, превышает лимит (например, 10 MB), автоматически удаляются наименее "ценные" элементы.

- Метод get(key: str) -> Any:
- Возвращает значение по ключу.
- Увеличивает счётчик использования элемента.
- Если элемент отсутствует — возвращает None.

Что значит "ценность" элемента:
- Ценность = количество обращений (`hit count`) к элементу.
- При очистке кэша сначала удаляются элементы с наименьшим количеством обращений.

Ограничения:
- Класс должен корректно считать объём памяти, занимаемый элементами.
- Нужно учитывать, что элементы могут быть сложными структурами (`dict`, list, вложенные объекты).
- Решение должно быть эффективным: операции должны быть быстрыми даже при большом количестве элементов.

---

▪️ Подсказки:

- Для оценки размера объектов можно использовать модуль sys.getsizeof, но для сложных вложенных структур нужен рекурсивный подсчет.
- Для хранения частоты обращений стоит использовать дополнительную структуру данных (`collections.Counter` или `dict`).
- При очистке лучше сначала группировать элементы по "ценности", а затем удалять самые "дешевые".

---

▪️ Что оценивается:

- Умение работать с ограничениями по памяти.
- Аккуратная обработка ссылок и размеров объектов.
- Эффективность очистки кэша.
- Чистота и читаемость кода.

---

▪️ Разбор возможного решения:

Идея архитектуры:

- Храним:
- storage: словарь {key: value}.
- hits: счётчик {key: hit_count}.
- size: общий размер всех объектов.
- При put():
- Добавляем элемент.
- Пересчитываем суммарный размер.
- Если размер превышает лимит:
- Удаляем наименее популярные элементы до тех пор, пока не уложимся в лимит.
- При get():
- Увеличиваем hit_count элемента.
- Возвращаем значение или None.

Оценка размера объектов:

- Простого sys.getsizeof недостаточно для коллекций.
- Нужна функция, рекурсивно подсчитывающая размер всех вложенных объектов.

Мини-пример функции подсчета размера:


import sys

def deep_getsizeof(obj, seen=None):
"""Рекурсивно считает память объекта и его вложенных объектов"""
size = sys.getsizeof(obj)
if seen is None:
seen = set()
obj_id = id(obj)
if obj_id in seen:
return 0
seen.add(obj_id)

if isinstance(obj, dict):
size += sum([deep_getsizeof(v, seen) + deep_getsizeof(k, seen) for k, v in obj.items()])
elif isinstance(obj, (list, tuple, set, frozenset)):
size += sum(deep_getsizeof(i, seen) for i in obj)
return size


Мини-пример интерфейса `SmartCache`:


class SmartCache:
def __init__(self, max_size_bytes):
self.max_size = max_size_bytes
self.storage = {}
self.hits = {}
self.total_size = 0

def put(self, key, value):
# добавить логику добавления и очистки при переполнении
pass

def get(self, key):
# увеличить hit_count и вернуть значение
pass


🔖 Дополнительные вопросы:

- Как ускорить очистку кэша без полного перебора всех элементов?
- Как сделать потокобезопасную версию кэша?
- Как адаптировать SmartCache для распределённой архитектуры (кэш между несколькими машинами)?

@python_job_interview
Please open Telegram to view this post
VIEW IN TELEGRAM
👍72🔥2🤡2



tgoop.com/python_job_interview/1089
Create:
Last Update:

🖥Задача: "Динамическое кэширование с ограничением памяти и частотой запросов"

🔖 Условие:

Реализуйте класс SmartCache, который работает следующим образом:

- Метод put(key: str, value: Any):
- Сохраняет значение по ключу.
- Если суммарный объем памяти, занимаемый всеми элементами, превышает лимит (например, 10 MB), автоматически удаляются наименее "ценные" элементы.

- Метод get(key: str) -> Any:
- Возвращает значение по ключу.
- Увеличивает счётчик использования элемента.
- Если элемент отсутствует — возвращает None.

Что значит "ценность" элемента:
- Ценность = количество обращений (`hit count`) к элементу.
- При очистке кэша сначала удаляются элементы с наименьшим количеством обращений.

Ограничения:
- Класс должен корректно считать объём памяти, занимаемый элементами.
- Нужно учитывать, что элементы могут быть сложными структурами (`dict`, list, вложенные объекты).
- Решение должно быть эффективным: операции должны быть быстрыми даже при большом количестве элементов.

---

▪️ Подсказки:

- Для оценки размера объектов можно использовать модуль sys.getsizeof, но для сложных вложенных структур нужен рекурсивный подсчет.
- Для хранения частоты обращений стоит использовать дополнительную структуру данных (`collections.Counter` или `dict`).
- При очистке лучше сначала группировать элементы по "ценности", а затем удалять самые "дешевые".

---

▪️ Что оценивается:

- Умение работать с ограничениями по памяти.
- Аккуратная обработка ссылок и размеров объектов.
- Эффективность очистки кэша.
- Чистота и читаемость кода.

---

▪️ Разбор возможного решения:

Идея архитектуры:

- Храним:
- storage: словарь {key: value}.
- hits: счётчик {key: hit_count}.
- size: общий размер всех объектов.
- При put():
- Добавляем элемент.
- Пересчитываем суммарный размер.
- Если размер превышает лимит:
- Удаляем наименее популярные элементы до тех пор, пока не уложимся в лимит.
- При get():
- Увеличиваем hit_count элемента.
- Возвращаем значение или None.

Оценка размера объектов:

- Простого sys.getsizeof недостаточно для коллекций.
- Нужна функция, рекурсивно подсчитывающая размер всех вложенных объектов.

Мини-пример функции подсчета размера:


import sys

def deep_getsizeof(obj, seen=None):
"""Рекурсивно считает память объекта и его вложенных объектов"""
size = sys.getsizeof(obj)
if seen is None:
seen = set()
obj_id = id(obj)
if obj_id in seen:
return 0
seen.add(obj_id)

if isinstance(obj, dict):
size += sum([deep_getsizeof(v, seen) + deep_getsizeof(k, seen) for k, v in obj.items()])
elif isinstance(obj, (list, tuple, set, frozenset)):
size += sum(deep_getsizeof(i, seen) for i in obj)
return size


Мини-пример интерфейса `SmartCache`:


class SmartCache:
def __init__(self, max_size_bytes):
self.max_size = max_size_bytes
self.storage = {}
self.hits = {}
self.total_size = 0

def put(self, key, value):
# добавить логику добавления и очистки при переполнении
pass

def get(self, key):
# увеличить hit_count и вернуть значение
pass


🔖 Дополнительные вопросы:

- Как ускорить очистку кэша без полного перебора всех элементов?
- Как сделать потокобезопасную версию кэша?
- Как адаптировать SmartCache для распределённой архитектуры (кэш между несколькими машинами)?

@python_job_interview

BY Python вопросы с собеседований


Share with your friend now:
tgoop.com/python_job_interview/1089

View MORE
Open in Telegram


Telegram News

Date: |

Hui said the time period and nature of some offences “overlapped” and thus their prison terms could be served concurrently. The judge ordered Ng to be jailed for a total of six years and six months. You can invite up to 200 people from your contacts to join your channel as the next step. Select the users you want to add and click “Invite.” You can skip this step altogether. 1What is Telegram Channels? The optimal dimension of the avatar on Telegram is 512px by 512px, and it’s recommended to use PNG format to deliver an unpixelated avatar. Add up to 50 administrators
from us


Telegram Python вопросы с собеседований
FROM American