Python вопросы с собеседований
Вопросы с собеседований по Python @workakkk - админ @machinelearning_interview - вопросы с собесдований по Ml @pro_python_code - Python @data_analysis_ml - анализ данных на Python @itchannels_telegram - 🔥 главное в ит РКН: clck.ru/3FmrFd
Mostrar más📈 Análisis del canal de Telegram Python вопросы с собеседований
El canal Python вопросы с собеседований (@python_job_interview) en el segmento lingüístico de Ruso es un actor destacado. Actualmente la comunidad reúne a 24 822 suscriptores, ocupando la posición 5 258 en la categoría Tecnologías y Aplicaciones y el puesto 26 472 en la región Rusia.
📊 Métricas de audiencia y dinámica
Desde su creación el невідомо, el proyecto ha mostrado un crecimiento acelerado, reuniendo a 24 822 suscriptores.
Según los últimos datos del 25 agosto, 2026, el canal mantiene una actividad estable. En los últimos 30 días la variación de miembros fue de -44, y en las últimas 24 horas de 0, conservando un alto alcance.
- Estado de verificación: No verificado
- Tasa de interacción (ER): El promedio de interacción de la audiencia es 6.01%. Durante las primeras 24 horas tras publicar, el contenido suele obtener 2.76% de reacciones respecto al total de suscriptores.
- Alcance de las publicaciones: Cada publicación recibe en promedio 1 492 visualizaciones. En el primer día suele acumular 684 visualizaciones.
- Reacciones e interacción: La audiencia responde de forma activa: el promedio de reacciones por publicación es 6.
- Intereses temáticos: El contenido se centra en temas clave como github, api, собеседование, git, docker.
📝 Descripción y política de contenido
El autor describe el recurso como un espacio para expresar opiniones subjetivas:
“Вопросы с собеседований по Python
@workakkk - админ
@machinelearning_interview - вопросы с собесдований по Ml
@pro_python_code - Python
@data_analysis_ml - анализ данных на Python
@itchannels_telegram - 🔥 главное в ит
РКН: clck.ru/3FmrFd”
Gracias a la alta frecuencia de actualizaciones (últimos datos recibidos el 28 agosto, 2026), el canal mantiene la vigencia y un amplio alcance. La analítica demuestra que la audiencia interactúa activamente con el contenido, lo que lo convierte en un punto de referencia dentro de la categoría Tecnologías y Aplicaciones.
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В первой строке заданы два натуральных числа N и M (0 < N, M ≤ 100 000). Во второй строке перечислены N элементов первого множества (целые числа через пробел). В третьей строке — M элементов второго множества (целые числа через пробел). Все числа по модулю не превышают 10<sup>9</sup>.— Выходные данные
Для каждого из M чисел выведите в отдельной строке: - "IN", если число присутствует в обоих множествах - "OUT", если число есть только в одном из множеств - "MISS", если числа нет ни в одном множестве— Примеры: Входные данные:
5 4 10 20 30 40 50 20 25 40 60Выходные данные:
IN OUT IN MISSЖду ваших вариантов решений 📝 @python_job_interview
name = "Alice"
greeting = t"Hello, {name}!" # t-строка
Вместо немедленной подстановки, как в f"...", t"..." создает шаблон с выражениями как параметрами.
🔐 Зачем это нужно?
✅ Безопасность при генерации SQL, HTML, JSON
✅ Улучшение инструментов и проверки типов (через static analysis)
✅ Контроль над контекстом исполнения (больше нельзя просто вставить переменную как есть — нужно передать её явно)
📦 Использование:
t-строки — это первый шаг к "template string literals" как в TypeScript.
Можно использовать с функциями:
def html(template: T[str]) -> SafeHTML:
...
html(t"<div>{user_input}</div>")
💡 Почему это важно?
Старый код:
f"SELECT * FROM users WHERE name = '{user_name}'"
может привести к SQL-инъекциям и XSS.
t-строки — безопасная альтернатива с встроенной защитой.
🛡 Пример: безопасный HTML
template = t"<p>{user_input}</p>"
html_output = html(template)
# <p><script>alert('bad')</script></p>
Функция html() может вернуть не просто строку, а полноценный HTMLElement.
Больше никакой "грязи" — всё чисто и типобезопасно.
🔍 Работа с шаблоном
t-строки позволяют получить доступ к содержимому:
template = t"Hello {name}!"
template.strings # ("Hello ", "!")
template.values # (name,)
template.interpolations[0].format_spec # ">8"
Можно и вручную собрать шаблон:
Template("Hello ", Interpolation(value="World", expression="name"), "!")
🚀 Вывод:
t"..." — шаг к безопасным шаблонам и типизации строк в Python.
Готовься к будущему Python — безопасному по умолчанию.
📌 Подробнее здесь
@pythonlВ первой строке входных данных содержатся натуральные числа N и К ( 0 < N, K ≤ 100 000). Во второй строке задаются N элементов первого массива, отсортированного по возрастанию, а в третьей строке - К элементов второго массива. Элементы обоих массивов - целые числа, каждое из которых по модулю не превосходит 109— Выходные данные
Требуется для каждого из К чисел вывести в отдельную строку "YES", если это число встречается в первом массиве, и "NO" в противном случае.— Примеры: входные данные
10 5 123 4 5 6 7 8 9 10 -2 0 4 9 12выходные данные
NO NO YES YES NOСкидывайте свои решения в комментарии🧐 @python_job_interview
mydaemon), который запускается через systemd unit и, согласно логам, должен работать постоянно.
❓ Но вот странность:
systemctl status mydaemon показывает, что сервис активен.
Однако при выполнении ps aux | grep mydaemon — процесса в списке нет.
top, htop, pgrep, pidof — тоже ничего не показывают.
Но при перезапуске systemd-сервиса (systemctl restart mydaemon) — в логах появляется запись о запуске, ошибок нет, а поведение не меняется.
Вопрос:
что происходит и как найти реальный процесс?Подсказки: Попробуйте посмотреть, какой тип сервиса указан в systemd unit-файле. Изучите, куда уходит stdout/stderr
.
Подумайте, может ли ExecStart запускать shell-обёртку, а не сам процесс.
Что покажет systemctl show -p MainPID mydaemon?
Подвох и решение:
Часто в unit-файле могут писать:
```ini
Type=simple
ExecStart=/bin/bash -c 'sleep 9999'```
Systemd считает, что bash — это основной процесс (MainPID), но он сразу завершается, передав выполнение sleep. Однако поскольку Type=simple, systemd не отслеживает дочерние процессы, и MainPID исчезает — ps и pgrep по имени mydaemon ничего не покажут, а дочерний процесс (sleep 9999) работает, но под другим именем.
Решение:
Либо указать Type=forking и использовать PIDFile.
Либо не использовать bash -c, а запускать нужный бинарь напрямую.
Либо использовать Type=exec (в systemd >240) или Type=notify с proper daemon tools.user, login/logout).
Найди тех, кто зашел, но не вышел.
📜 Пример:
logs = [
("alice", "login"),
("bob", "login"),
("alice", "logout"),
("dave", "login"),
("bob", "logout"),
("carol", "login"),
("dave", "logout")
]
________
💻 Решение:
from collections import defaultdict
def find_stuck_users(logs):
counter = defaultdict(int)
for user, action in logs:
if action == "login":
counter[user] += 1
elif action == "logout":
counter[user] -= 1
return sorted([user for user, count in counter.items() if count > 0])
🛠Ответ: "carol"
#Python #Challenge #DevPuzzle
@python_job_interview
def extendList(val, list=[]):
list.append(val)
return list
list1 = extendList(10)
list2 = extendList(123, [])
list3 = extendList('a')
print("list1 =", list1)
print("list2 =", list2)
print("list3 =", list3)
Варианты ответа:
A.
list2 = [123]
list3 = ['a']
B.
list2 = [123]
list3 = [10, 'a']
C.
list2 = [123]
list3 = [10, 'a']
D.
list2 = [123]
list3 = ['a']
❓ Как думаешь, какой ответ правильный и почему?
Подвох: аргументы по умолчанию в Python вычисляются один раз — при определении функции.
🔸 В extendList(val, list=[]) — этот list=[] сохраняется один и тот же объект списка для всех вызовов функции, где не передаётся list.
Что происходит:
list1 = extendList(10)
→ list=[] по умолчанию
→ list = [10]
→ list1 → [10]
list2 = extendList(123, [])
→ передали новый список
→ list = [123]
→ list2 → [123]
list3 = extendList('a')
→ снова использован тот же список, что и в list1
→ list = [10, 'a']
→ list3 → [10, 'a']
→ и list1 тоже теперь [10, 'a'], потому что это один и тот же объект
Вывод будет:
list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']
x = [1, 2, 3]
y = x
x += [4]
print(x)
print(y)
🔢 Варианты ответа:
A)
[1, 2, 3]
B)
[1, 2, 3, 4]
C)
[1, 2, 3, 4]
D)
[1, 2, 3]
✅ Правильный ответ: B
💡 Почему?
- x = [1, 2, 3] и y = x — ссылка на один и тот же список.
- x += [4] модифицирует список на месте.
- Поэтому y тоже видит изменение.
🧠 Подвох — в +=, который работает не как x = x + [...].
def append_to(element, to=[]):
to.append(element)
return to
print(append_to(1))
print(append_to(2))
print(append_to(3, []))
print(append_to(4))
🔢 Варианты ответа:
A)
[2]
[3]
[4]
B)
[1, 2]
[3]
[1, 2, 4]
C)
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
D)
[1, 2]
[3]
[4]
✅ Правильный ответ: B
💡 Почему?
В Python дефолтные аргументы вычисляются один раз — при определении функции.
Список to=[] сохраняется и используется повторно, если явно не передан другой.
Поэтому append_to(1), append_to(2) и append_to(4) работают с одним и тем же списком.
def func(a, L=[]):
L.append(a)
return L
print(func(1))
print(func(2))
print(func(3))
Варианты ответа:
A)
[2]
[3]
B)
[1, 2]
[1, 2, 3]
C)
[1]
[1]
D)
[2]
[3]
---
✅ Правильный ответ: B
Почему:
Списки по умолчанию (L=[]) в Python инициализируются один раз при определении функции, а не каждый раз при вызове. Поэтому изменения сохраняются между вызовами func. Это классическая "ловушка" со значениями по умолчанию!
@python_job_interview