🐍 Задача на внимательность и глубокое понимание Python: ловушка `defaultdict` и мутабельных объектов
Представьте, что вы разрабатываете систему трекинга активностей пользователей на сайте. Вам нужно собрать словарь, где каждому пользователю соответствует список его действий.
Вы решаете использовать
🧠 Вопрос:
Что будет напечатано? Почему?
Как сделать так, чтобы copy_actions не изменился при добавлении новых действий в actions?
💥 Подвох
Метод copy() копирует только верхний уровень словаря. То есть, списки значений не копируются — это всё те же самые объекты в памяти. Поэтому при track('bob', 'logout') список actions['bob'] изменяется, и это тот же самый список, что лежит в copy_actions['bob'].
➡️ Ответ: print(copy_actions['bob']) напечатает ['view', 'logout'].
✅ Как правильно?
Чтобы избежать такой проблемы, используйте глубокое копирование:
Теперь copy_actions не изменится при дальнейшем редактировании actions.
📌 Вывод
Даже опытные разработчики иногда забывают: copy() не копирует вложенные структуры данных!
Если в значениях словаря лежат мутабельные объекты, обязательно подумайте — а не нужен ли вам deepcopy()?
🧪 Попробуйте изменить defaultdict(list) на обычный dict — и посмотрите, что изменится.
Представьте, что вы разрабатываете систему трекинга активностей пользователей на сайте. Вам нужно собрать словарь, где каждому пользователю соответствует список его действий.
Вы решаете использовать
collections.defaultdict(list)
для удобства, и пишете такой код:
from collections import defaultdict
actions = defaultdict(list)
def track(user_id, action):
actions[user_id].append(action)
track('alice', 'login')
track('bob', 'view')
track('alice', 'logout')
# Теперь вы хотите скопировать этот словарь
copy_actions = actions.copy()
# Допишем в оригинал
track('bob', 'logout')
# Посмотрим, как выглядит копия
print(copy_actions['bob']) # Что будет напечатано?
🧠 Вопрос:
Что будет напечатано? Почему?
Как сделать так, чтобы copy_actions не изменился при добавлении новых действий в actions?
💥 Подвох
➡️ Ответ: print(copy_actions['bob']) напечатает ['view', 'logout'].
✅ Как правильно?
Чтобы избежать такой проблемы, используйте глубокое копирование:
import copy
copy_actions = copy.deepcopy(actions)
Теперь copy_actions не изменится при дальнейшем редактировании actions.
📌 Вывод
Даже опытные разработчики иногда забывают: copy() не копирует вложенные структуры данных!
Если в значениях словаря лежат мутабельные объекты, обязательно подумайте — а не нужен ли вам deepcopy()?
🧪 Попробуйте изменить defaultdict(list) на обычный dict — и посмотрите, что изменится.
🐍 Хитрая задача на Python: замыкание + nonlocal
📌 Задача:
Напиши функцию
Пример:
🎯 Подвох:
- Нельзя использовать глобальные переменные
- Нужно использовать замыкание
- Без
✅ Решение:
🧠 Объяснение подвоха:
-
-
- Каждое замыкание имеет своё независимое состояние
⚠️ Без
🛠️ Применяется в:
• Реализации генераторов состояния
• Мини-хранилищах внутри функций
• Кеширующих функциях и декораторах
@python_job_interview
📌 Задача:
Напиши функцию
counter(start)
, которая возвращает функцию-счётчик. Каждый вызов этой функции увеличивает значение на 1.Пример:
c = counter(10)
print(c()) # 11
print(c()) # 12
print(c()) # 13
d = counter(100)
print(d()) # 101
print(c()) # 14 ← работает независимо
🎯 Подвох:
- Нельзя использовать глобальные переменные
- Нужно использовать замыкание
- Без
nonlocal
— не заработает✅ Решение:
def counter(start):
count = start
def inner():
nonlocal count
count += 1
return count
return inner
# Проверка
a = counter(5)
print(a()) # 6
print(a()) # 7
b = counter(100)
print(b()) # 101
print(a()) # 8
🧠 Объяснение подвоха:
-
counter
возвращает функцию, внутри которой count
сохраняется в замыкании-
nonlocal
нужен, чтобы изменить внешнюю переменную, а не просто читать её- Каждое замыкание имеет своё независимое состояние
⚠️ Без
nonlocal count
, Python создаст локальную count
внутри inner()
, и UnboundLocalError
— гарантирован🛠️ Применяется в:
• Реализации генераторов состояния
• Мини-хранилищах внутри функций
• Кеширующих функциях и декораторах
@python_job_interview
🌟 FastAPI-Limiter — простое ограничение запросов для FastAPI. Эта библиотека добавляет rate limiting буквально в несколько строк кода, используя Redis как хранилище для счетчиков.
Достаточно добавить
Интересные фишки:
— Поддержка вебсокетов через
— Кастомизация идентификаторов
— Множественные лимиты на один роут
🤖 GitHub
@python_job_interview
Достаточно добавить
Depends(RateLimiter(times=2, seconds=5))
к эндпоинту и он начнет отклонять запросы после двух обращений в пятисекундном окне. Под капотом работает Lua-скрипт, который эффективно считает запросы без лагов. Интересные фишки:
— Поддержка вебсокетов через
WebSocketRateLimiter
— Кастомизация идентификаторов
— Множественные лимиты на один роут
🤖 GitHub
@python_job_interview
Forwarded from Machinelearning
🚀 VS Code трансформируется в опенсорнсый ИИ-редактор!
Команда Visual Studio Code объявила о планах трансформировать VS Code в редактор с открытым исходным кодом для работы с ИИ.
Конкуренция - двигатели прогресса!Где-то напряглась команда Cursor 🤓
🔗 Подробности: aka.ms/open-source-ai-editor
#VSCode #OpenSource #ИИ #Разработка #Сообщество
Команда Visual Studio Code объявила о планах трансформировать VS Code в редактор с открытым исходным кодом для работы с ИИ.
Конкуренция - двигатели прогресса!
🔗 Подробности: aka.ms/open-source-ai-editor
#VSCode #OpenSource #ИИ #Разработка #Сообщество
🐍 Задача с подвохом: mutable default arguments в Python
🔹 Уровень: Advanced
🔹 Темы: изменяемые аргументы по умолчанию, функции, ловушки с
📌 Условие
Что выведет следующий код?
❓ Вопросы
1. Почему результат выглядит неожиданно?
2. Как исправить это поведение?
3. Когда стоит использовать изменяемые аргументы по умолчанию — если вообще стоит?
🔍 Разбор
✅ Ожидаемый вывод:
🔧 Почему так происходит
- Аргументы по умолчанию вычисляются один раз — во время определения функции, а не при каждом вызове.
- Значение
- Все вызовы
⚠️ Подвох
Это один из самых коварных багов в Python, особенно среди начинающих — кажется, что
🧠 Вывод
- Никогда не используй изменяемые типы (list, dict, set) как значения по умолчанию.
- Вместо этого используй
✅ Тогда вывод будет:
📌 Это правило относится ко всем изменяемым типам:
@python_job_interview
🔹 Уровень: Advanced
🔹 Темы: изменяемые аргументы по умолчанию, функции, ловушки с
list
и dict
📌 Условие
Что выведет следующий код?
def append_to_list(value, my_list=[]):
my_list.append(value)
return my_list
print(append_to_list(1))
print(append_to_list(2))
print(append_to_list(3))
❓ Вопросы
1. Почему результат выглядит неожиданно?
2. Как исправить это поведение?
3. Когда стоит использовать изменяемые аргументы по умолчанию — если вообще стоит?
🔍 Разбор
✅ Ожидаемый вывод:
[1]
[1, 2]
[1, 2, 3]
🔧 Почему так происходит
- Аргументы по умолчанию вычисляются один раз — во время определения функции, а не при каждом вызове.
- Значение
my_list=[]
создаётся один раз и затем используется повторно при всех вызовах.- Все вызовы
append_to_list
изменяют один и тот же список.⚠️ Подвох
Это один из самых коварных багов в Python, особенно среди начинающих — кажется, что
my_list
должен быть новым на каждый вызов, но это не так.🧠 Вывод
- Никогда не используй изменяемые типы (list, dict, set) как значения по умолчанию.
- Вместо этого используй
None
и создавай новый объект вручную:
def append_to_list(value, my_list=None):
if my_list is None:
my_list = []
my_list.append(value)
return my_list
✅ Тогда вывод будет:
[1]
[2]
[3]
📌 Это правило относится ко всем изменяемым типам:
[]
, {}
, set()
и кастомные классы.@python_job_interview
22 мая(в четверг) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Python-разработчика.
Собес проведет Вадим Пуштаев, ex. head of backend в
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Python-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_py_bot
Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2Vtzqvtihsa
Please open Telegram to view this post
VIEW IN TELEGRAM
🐍 Хитрая задача на замыкания в Python
🔹 Уровень: Advanced
🔹 Темы: замыкания (closures), переменные цикла,
📌 Условие
Что выведет следующий код?
❓ Вопросы
1. Почему вывод может не соответствовать ожиданиям
2. Что именно "запоминает"
3. Как переписать код, чтобы результат был
🔍 Разбор
✅ Ожидаемый (неправильный) вывод:
🔧 Почему так происходит
- Все
- К моменту выполнения
⚠️ Подвох
В итоге — все
🧠 Решение
Нужно "зафиксировать" значение
Теперь результат будет:
📌 Это один из самых частых подвохов в Python, особенно при использовании лямбда-функций в генераторах и UI-коллбеках.
🔹 Уровень: Advanced
🔹 Темы: замыкания (closures), переменные цикла,
lambda
, отложенное выполнение📌 Условие
Что выведет следующий код?
funcs = []
for i in range(5):
funcs.append(lambda: i)
results = [f() for f in funcs]
print(results)
❓ Вопросы
1. Почему вывод может не соответствовать ожиданиям
[0, 1, 2, 3, 4]
? 2. Что именно "запоминает"
lambda
внутри цикла? 3. Как переписать код, чтобы результат был
[0, 1, 2, 3, 4]
?🔍 Разбор
✅ Ожидаемый (неправильный) вывод:
[4, 4, 4, 4, 4]
🔧 Почему так происходит
- Все
lambda
внутри funcs
замыкают одну и ту же переменную `i`. - К моменту выполнения
f()
переменная i
уже равна 4 — и так для всех функций.⚠️ Подвох
lambda: i
не захватывает значение, а ссылается на переменную, которая будет изменяться при каждой итерации цикла. В итоге — все
lambda
ссылаются на одно и то же `i`, которое стало равно 4 к концу цикла.🧠 Решение
Нужно "зафиксировать" значение
i
, передав его как аргумент по умолчанию в lambda
:
for i in range(5):
funcs.append(lambda i=i: i)
Теперь результат будет:
[0, 1, 2, 3, 4]
📌 Это один из самых частых подвохов в Python, особенно при использовании лямбда-функций в генераторах и UI-коллбеках.
⚡️ Pydantic Core — Rust-ядро для валидации данных в Python. Этот низкоуровневый валидатор демонстрирует впечатляющую скорость: до 17x быстрее оригинальной реализации на чистом Python.
Хотя напрямую с ним обычно не работают (используя вместо этого основной пакет pydantic), проект интересен как пример интеграции Rust в Python-экосистему. Валидация описывается через JSON-схемы, поддерживая сложные условия вроде
🤖 GitHub
@python_interview
Хотя напрямую с ним обычно не работают (используя вместо этого основной пакет pydantic), проект интересен как пример интеграции Rust в Python-экосистему. Валидация описывается через JSON-схемы, поддерживая сложные условия вроде
ge: 18
для чисел или вложенных структур. Сборка требует Rust toolchain, но результат стоит того: например, валидация списка из 10к элементов занимает миллисекунды. 🤖 GitHub
@python_interview
🐍 lessslow.py — Python, который не тормозит
Многие считают Python медленным, но это не всегда правда.
Ash Vardanyan в рамках проекта Less Slow показывает, как писать быстрый и эффективный код даже на Python — без магии, но с пониманием.
⚡️ Что в проекте:
- pandas vs polars — что быстрее при работе с миллионами строк
- Использование Numba, Cython, PyO3, rust bindings
- Работа с нативными типами, векторизация и zero-copy
- Сериализация: MessagePack, Arrow, Parquet
- Ускорение JSON: orjson, yyjson, simdjson, ujson
- Как обойти GIL и не платить за удобство интерпретатора
📚 Репозиторий: github.com/ashvardanian/lessslow.py
💡 Даже если ты не используешь всё это каждый день — ты точно станешь писать лучший Python-код.
@python_job_interview
Многие считают Python медленным, но это не всегда правда.
Ash Vardanyan в рамках проекта Less Slow показывает, как писать быстрый и эффективный код даже на Python — без магии, но с пониманием.
⚡️ Что в проекте:
- pandas vs polars — что быстрее при работе с миллионами строк
- Использование Numba, Cython, PyO3, rust bindings
- Работа с нативными типами, векторизация и zero-copy
- Сериализация: MessagePack, Arrow, Parquet
- Ускорение JSON: orjson, yyjson, simdjson, ujson
- Как обойти GIL и не платить за удобство интерпретатора
📚 Репозиторий: github.com/ashvardanian/lessslow.py
💡 Даже если ты не используешь всё это каждый день — ты точно станешь писать лучший Python-код.
@python_job_interview
Media is too big
VIEW IN TELEGRAM
Стань частью масштабного ИТ-события от МТС
True Tech Day 2025 — третья технологическая конференция МТС для профессионалов ИТ‑индустрии. Одна из главных тем в этом году — тренды и практики искусственного интеллекта.
В программе:
— Доклады от ученых и зарубежных спикеров с индексом Хирша более 50.
— Кейсы применения современных ИИ‑решений — от AI‑агентов, тестов LLM и бенчмарков до вопросов регулирования.
— AI-интерактивы и технологические квесты.
— Пространство для нетворкинга,
…а еще after-party со звездным лайн-апом.
Когда: 6 июня
Где: Москва, МТС Live Холл и онлайн
Участие бесплатное, но мест мало. Регистрируйся по ссылке.
True Tech Day 2025 — третья технологическая конференция МТС для профессионалов ИТ‑индустрии. Одна из главных тем в этом году — тренды и практики искусственного интеллекта.
В программе:
— Доклады от ученых и зарубежных спикеров с индексом Хирша более 50.
— Кейсы применения современных ИИ‑решений — от AI‑агентов, тестов LLM и бенчмарков до вопросов регулирования.
— AI-интерактивы и технологические квесты.
— Пространство для нетворкинга,
Когда: 6 июня
Где: Москва, МТС Live Холл и онлайн
Участие бесплатное, но мест мало. Регистрируйся по ссылке.
Каким будет вывод этого кода?
Anonymous Quiz
47%
['AB', 'CD']
10%
['ab', 'cd']
15%
Ничто из перечисленного
15%
Ошибка
14%
Посмотреть ответ
🐍 **LibrePythonista — Python прямо в LibreOffice Calc**
LibrePythonista — это бесплатное и открытое расширение, которое добавляет полноценную поддержку Python прямо в LibreOffice Calc. И да, оно уже поддерживает Pandas, Matplotlib и даже собственный PIP-менеджер пакетов!
💡 Что умеет LibrePythonista:
• 📊 Создание DataFrame, Series и графиков прямо в ячейках
• 📦 Встроенный PIP для установки дополнительных библиотек
• 🔐 Локальное исполнение кода — ваши данные не покидают компьютер
• 🧰 Использует OOO Dev Tools — не требует дополнительных расширений
• 🧪 Пока в бете — можно влиять на развитие
📎 Больше не нужно колхозить скрипты или вручную подключать Pandas/Numpy — всё уже встроено.
🔗 Проект: https://extensions.libreoffice.org/en/extensions/show/99231
LibrePythonista — это бесплатное и открытое расширение, которое добавляет полноценную поддержку Python прямо в LibreOffice Calc. И да, оно уже поддерживает Pandas, Matplotlib и даже собственный PIP-менеджер пакетов!
💡 Что умеет LibrePythonista:
• 📊 Создание DataFrame, Series и графиков прямо в ячейках
• 📦 Встроенный PIP для установки дополнительных библиотек
• 🔐 Локальное исполнение кода — ваши данные не покидают компьютер
• 🧰 Использует OOO Dev Tools — не требует дополнительных расширений
• 🧪 Пока в бете — можно влиять на развитие
📎 Больше не нужно колхозить скрипты или вручную подключать Pandas/Numpy — всё уже встроено.
🔗 Проект: https://extensions.libreoffice.org/en/extensions/show/99231
🐍 Python-задача с подвохом: кто съел яблоко?
У тебя есть список действий персонажей:
Каждое действие — это кортеж:
📌 Правила:
1. Только тот, кто сначала "picked", может "ate".
2. Если кто-то "dropped", он больше не владеет объектом.
3. Нужно выяснить, кто съел яблоко, и проверить: мог ли он это сделать по правилам?
🧠 Задача:
Напиши функцию
-
-
---
✅ Решение с разбором:
```python
def who_ate(actions):
holding = set()
eater = None
for name, action in actions:
if action == "picked":
holding.add(name)
elif action == "dropped":
holding.discard(name)
elif action == "ate":
eater = name
if name in holding:
return "OK"
else:
return "CHEATER"
return "NO ONE ATE"
```
📌 **Как это работает:**
- `holding` — это множество тех, кто в данный момент "держит" объект.
- Как только кто-то `"ate"`, мы сразу проверяем: находится ли он в `holding`?
- Если нет — значит, он **съел чужое яблоко**. Подмена! 🤯
---
🔍 **Разбор на примере:**
```python
# Charlie picked → OK
# Charlie ate → всё ещё держит → OK
print(who_ate([
("Charlie", "picked"),
("Charlie", "ate")
])) # OK
# Alice picked, потом dropped, потом ate → нарушила правила
print(who_ate([
("Alice", "picked"),
("Alice", "dropped"),
("Alice", "ate")
])) # CHEATER
```
---
💡 Подвох в том, что многие решают задачу, просто считая количество действий, **не отслеживая актуальное владение** объектом.
📦 Задача хороша для собесов — проверяет внимание к деталям и мышление в терминах состояний.
У тебя есть список действий персонажей:
actions = [
("Alice", "picked"),
("Bob", "looked"),
("Charlie", "picked"),
("Bob", "dropped"),
("Alice", "dropped"),
("Charlie", "ate")
]
Каждое действие — это кортеж:
(имя персонажа, действие)
.📌 Правила:
1. Только тот, кто сначала "picked", может "ate".
2. Если кто-то "dropped", он больше не владеет объектом.
3. Нужно выяснить, кто съел яблоко, и проверить: мог ли он это сделать по правилам?
🧠 Задача:
Напиши функцию
who_ate(actions: list[tuple[str, str]]) -> str
, которая возвращает:-
"OK"
— если всё законно -
"CHEATER"
— если съевший не имел права---
✅ Решение с разбором:
```python
def who_ate(actions):
holding = set()
eater = None
for name, action in actions:
if action == "picked":
holding.add(name)
elif action == "dropped":
holding.discard(name)
elif action == "ate":
eater = name
if name in holding:
return "OK"
else:
return "CHEATER"
return "NO ONE ATE"
```
📌 **Как это работает:**
- `holding` — это множество тех, кто в данный момент "держит" объект.
- Как только кто-то `"ate"`, мы сразу проверяем: находится ли он в `holding`?
- Если нет — значит, он **съел чужое яблоко**. Подмена! 🤯
---
🔍 **Разбор на примере:**
```python
# Charlie picked → OK
# Charlie ate → всё ещё держит → OK
print(who_ate([
("Charlie", "picked"),
("Charlie", "ate")
])) # OK
# Alice picked, потом dropped, потом ate → нарушила правила
print(who_ate([
("Alice", "picked"),
("Alice", "dropped"),
("Alice", "ate")
])) # CHEATER
```
---
💡 Подвох в том, что многие решают задачу, просто считая количество действий, **не отслеживая актуальное владение** объектом.
📦 Задача хороша для собесов — проверяет внимание к деталям и мышление в терминах состояний.
Forwarded from Machinelearning
Мультимодальная модель от NVIDIA уверенно занимает первое место на OCRBench v2, показав лучшую точность парсинга документов среди всех моделей.
📄 Что это такое:
Llama Nemotron Nano VL — лёгкая vision-language модель для интеллектуальной обработки документов (IDP), которая:
• разбирает PDF
• вытаскивает таблицы
• парсит графики и диаграммы
• работает на одной GPU
– Вопрос-ответ по документам
– Извлечение таблиц
– Анализ графиков
– Понимание диаграмм и дешбордов
📊 OCRBench v2 — крупнейший двухъязычный бенчмарк для визуального анализа текста, и именно NVIDIA Nano VL показывает лучший результат.
@ai_machinelearning_big_data
#Nemotron #NVIDIA
Please open Telegram to view this post
VIEW IN TELEGRAM
🐍 Задача на внимательность и понимание области видимости в Python: «Почему список не заполняется?»
🎯 Цель: Найти, почему переменная ведёт себя не так, как ожидается
📍 Ситуация:
У тебя есть простой код, который должен собирать данные в список из файла:
Но после запуска ты получаешь:
🙃 Хотя ты уверен, что в обоих файлах есть строки с
🧩 Задача:
1. Почему список
2. Почему нет ошибки при обращении к
3. Что будет, если вместо
4. Как правильно модифицировать глобальную переменную?
5. Как сделать поведение явным и безопасным?
🛠 Решение:
🔸 Проблема в области видимости переменных:
Функция использует
Однако
Если бы внутри функции была строка
🔸 Для ясности и чистоты кода лучше делать так:
Или, если обязательно нужно использовать глобальную переменную:
🔸 Проверка:
-
-
📌 Вывод:
В Python изменение содержимого изменяемой глобальной переменной внутри функции возможно без
🎯 Цель: Найти, почему переменная ведёт себя не так, как ожидается
📍 Ситуация:
У тебя есть простой код, который должен собирать данные в список из файла:
results = []
def process_file(path):
for line in open(path):
if "error" in line:
results.append(line.strip())
# где-то в другом месте:
process_file("logs1.txt")
process_file("logs2.txt")
print(f"Total errors: {len(results)}")
Но после запуска ты получаешь:
Total errors: 0
🙃 Хотя ты уверен, что в обоих файлах есть строки с
"error"
.🧩 Задача:
1. Почему список
results
остаётся пустым? 2. Почему нет ошибки при обращении к
results.append(...)
? 3. Что будет, если вместо
append()
просто написать results = [...]
внутри функции? 4. Как правильно модифицировать глобальную переменную?
5. Как сделать поведение явным и безопасным?
🛠 Решение:
🔸 Проблема в области видимости переменных:
Функция использует
results
, определённый вне функции, но не объявляет его как global. Однако
results.append(...)
— это допустимая операция, так как она не переназначает переменную, а вызывает метод объекта.Если бы внутри функции была строка
results = [...]
, Python бы создал локальную переменную results
, и тогда append
бы вызывал UnboundLocalError
.🔸 Для ясности и чистоты кода лучше делать так:
def process_file(path, results):
for line in open(path):
if "error" in line:
results.append(line.strip())
results = []
process_file("logs1.txt", results)
process_file("logs2.txt", results)
Или, если обязательно нужно использовать глобальную переменную:
results = []
def process_file(path):
global results
for line in open(path):
if "error" in line:
results.append(line.strip())
🔸 Проверка:
-
print(locals())
— покажет локальные переменные-
print(globals())
— покажет глобальные📌 Вывод:
В Python изменение содержимого изменяемой глобальной переменной внутри функции возможно без
global
, но присваивание новой переменной требует явного global
. Это тонкое поведение, которое часто приводит к ошибкам, особенно при работе со списками и словарями.This media is not supported in your browser
VIEW IN TELEGRAM
Задача: Что делает эта странная функция teleport и почему она запускает цикл 32 раза?
🧠 Подсказка:
На первый взгляд это выглядит как хаотичная мешанина побитовых операций, но на самом деле здесь происходит реверс битов (bitwise reversal) — отражение битов справа налево.
Но вопрос — зачем делать это 32 раза подряд?
🔍 Что происходит:
Каждый шаг в теле цикла — это стандартная техника реверса битов через маски и сдвиги:
0xAAAAAAAA, 0xCCCCCCCC, и т.д. — маски по битовым паттернам
Итерация for _ in range(32) делает это снова и снова…
💣 Фишка: первый проход уже полностью отражает 32-битное число.
Остальные 31 повтор возвращают число в исходное состояние — но в побитово инвертированном порядке!
📌 То есть:
Чётное количество циклов — возвращает в исходную позицию
Нечётное — делает реверс
👉 Ответ на teleport(0x12345678) будет реверс битов этого числа.
Ожидаемое: 0x1e6a2c48 (в зависимости от реализации может отличаться).
🎯 Челлендж для продвинутых:
Упростите функцию до одного вызова (без цикла)
Напишите inverse_teleport(x), которая возвращает исходное число обратно
🧩 Эта техника используется в:
— алгоритмах FFT (быстрые преобразования Фурье)
— графике
— реверсировании хэшей
— low-level оптимизациях для SIMD
🧠 Подсказка:
На первый взгляд это выглядит как хаотичная мешанина побитовых операций, но на самом деле здесь происходит реверс битов (bitwise reversal) — отражение битов справа налево.
Но вопрос — зачем делать это 32 раза подряд?
🔍 Что происходит:
Каждый шаг в теле цикла — это стандартная техника реверса битов через маски и сдвиги:
0xAAAAAAAA, 0xCCCCCCCC, и т.д. — маски по битовым паттернам
Итерация for _ in range(32) делает это снова и снова…
💣 Фишка: первый проход уже полностью отражает 32-битное число.
Остальные 31 повтор возвращают число в исходное состояние — но в побитово инвертированном порядке!
📌 То есть:
Чётное количество циклов — возвращает в исходную позицию
Нечётное — делает реверс
👉 Ответ на teleport(0x12345678) будет реверс битов этого числа.
Ожидаемое: 0x1e6a2c48 (в зависимости от реализации может отличаться).
🎯 Челлендж для продвинутых:
Упростите функцию до одного вызова (без цикла)
Напишите inverse_teleport(x), которая возвращает исходное число обратно
🧩 Эта техника используется в:
— алгоритмах FFT (быстрые преобразования Фурье)
— графике
— реверсировании хэшей
— low-level оптимизациях для SIMD
🎓 Модульный учебник по Python для Middle-разработчиков
Этот учебник создан для тех, кто уже пишет на Python, но хочет выйти за рамки базовых конструкций. Здесь — практичные модули с упором на архитектуру, производительность, тестирование, чистый код и современные практики разработки.
🔧 Каждый модуль — это отдельный блок знаний: теория + реальные кейсы + трюки из индустрии.
🎯 Только то, что реально нужно миддлу: от дебага и профилирования до async, typing, CI/CD и LLM-интеграций.
Без воды. С кодом. По делу.
📚 Читать
@python_job_interview
Этот учебник создан для тех, кто уже пишет на Python, но хочет выйти за рамки базовых конструкций. Здесь — практичные модули с упором на архитектуру, производительность, тестирование, чистый код и современные практики разработки.
🔧 Каждый модуль — это отдельный блок знаний: теория + реальные кейсы + трюки из индустрии.
🎯 Только то, что реально нужно миддлу: от дебага и профилирования до async, typing, CI/CD и LLM-интеграций.
Без воды. С кодом. По делу.
📚 Читать
@python_job_interview
🐳 Что если вам нужно запустить чужой (возможно небезопасный) код?
Представьте: вам прислали бинарник, Python-скрипт или npm-пакет, и его надо выполнить.
Вы не знаете, что внутри — а вдруг там
🔥 Первый инстинкт: запустить в Docker. Кажется, контейнер спасёт?
⚠️ На самом деле — не всегда.
🛑 Docker ≠ песочница
Контейнеры по умолчанию не изолированы от ядра, сетей и сокетов хоста.
Даже простое
🛡️ Что делать, если код небезопасен:
Также стоит:
• Настроить AppArmor / SELinux
• Запретить монтирование Docker сокета
• Ограничить доступ к
💡 Вывод:
Docker — это удобный инструмент упаковки, но не синоним безопасной изоляции.
Если запускаете сторонний или user-generated код (плагины, CI-скрипты, sandbox-сервисы) — относитесь к нему как к потенциально опасному.
Безопасность — это не "чеклист", а постоянная практика.
#Docker #Security #Sandbox #DevOps #Isolation
Представьте: вам прислали бинарник, Python-скрипт или npm-пакет, и его надо выполнить.
Вы не знаете, что внутри — а вдруг там
rm -rf /
, попытка выйти из контейнера, майнер или установка root-доступа?🔥 Первый инстинкт: запустить в Docker. Кажется, контейнер спасёт?
⚠️ На самом деле — не всегда.
🛑 Docker ≠ песочница
Контейнеры по умолчанию не изолированы от ядра, сетей и сокетов хоста.
Даже простое
docker run -it ubuntu
запускает процесс с root-доступом внутри контейнера.🛡️ Что делать, если код небезопасен:
# Запуск без root-доступа
docker run --user 1000:1000 my-image
# Только для чтения
docker run --read-only my-image
# Удалить все cap-привилегии ядра
docker run --cap-drop=ALL my-image
# Использовать seccomp-профиль
docker run --security-opt seccomp=default.json my-image
# Отключить сеть
docker run --network=none my-image
Также стоит:
• Настроить AppArmor / SELinux
• Запретить монтирование Docker сокета
• Ограничить доступ к
/proc
, /sys
💡 Вывод:
Docker — это удобный инструмент упаковки, но не синоним безопасной изоляции.
Если запускаете сторонний или user-generated код (плагины, CI-скрипты, sandbox-сервисы) — относитесь к нему как к потенциально опасному.
Безопасность — это не "чеклист", а постоянная практика.
#Docker #Security #Sandbox #DevOps #Isolation
This media is not supported in your browser
VIEW IN TELEGRAM