Python | Вопросы собесов
13.9K subscribers
36 photos
1 file
926 links
Cайт: easyoffer.ru
Реклама: @easyoffer_adv
ВП: @easyoffer_vp

Тесты t.me/+20tRfhrwPpM4NDQy
Задачи t.me/+nsl4meWmhfQwNDVi
Вакансии t.me/+cXGKkrOY2-w3ZTky
Download Telegram
🤔 Что такое деструктор класса?

Это специальный метод, который вызывается автоматически, когда объект класса уничтожается. В Python этот метод называется __del__(). Деструктор используется для выполнения операций очистки, таких как освобождение ресурсов или выполнение завершающих действий перед тем, как объект будет удален из памяти.

🚩Определение и использование деструктора

Определяется внутри класса с помощью метода __del__().
class FileManager:
def __init__(self, filename):
self.file = open(filename, 'w')
print(f"Файл {filename} открыт для записи.")

def write_data(self, data):
self.file.write(data)

def __del__(self):
self.file.close()
print("Файл закрыт.")


🟠Класс FileManager имеет конструктор __init__(), который открывает файл для записи.
🟠Метод write_data() записывает данные в файл.
🟠Деструктор __del__() закрывает файл, когда объект FileManager уничтожается.

🚩Создание и уничтожение объекта

Когда объект класса создается, вызывается конструктор. Когда объект больше не нужен, вызывается деструктор:
manager = FileManager('example.txt')
manager.write_data('Hello, world!')
# Когда объект manager больше не нужен, вызывается деструктор и файл закрывается


🚩Важные замечания

🟠Сборка мусора
Python использует механизм сборки мусора для автоматического управления памятью. Когда объект больше не используется (например, нет активных ссылок на него), сборщик мусора удаляет объект и вызывает его деструктор.

🟠Неопределенное время вызова
Точное время вызова деструктора зависит от работы сборщика мусора. Это означает, что нельзя гарантировать момент вызова деструктора. Поэтому для критических операций лучше использовать явное управление ресурсами, например, с помощью контекстных менеджеров (with).

🟠Контекстные менеджеры
Для явного управления ресурсами и их освобождения в предсказуемый момент лучше использовать контекстные менеджеры.
with open('example.txt', 'w') as file:
file.write('Hello, world!')
# Файл автоматически закрывается после выхода из блока with


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍112
🤔 На что влияет атрибут slots?

1. Атрибут slots ограничивает набор свойств, которые можно добавлять объекту, улучшая использование памяти.
2. Убирает динамический словарь атрибутов (dict), что снижает накладные расходы.
3. Подходит для классов с большим количеством объектов, где оптимизация памяти критична.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥4
🤔 Что такое хранитель (Memento)?

Это поведенческий паттерн проектирования, который позволяет сохранять и восстанавливать предыдущее состояние объекта без нарушения инкапсуляции. Этот паттерн особенно полезен для реализации операций отмены и повтора, так как он позволяет хранить состояния объектов и возвращать их к этим состояниям по необходимости.

🚩Зачем нужен?

🟠Сохранение состояния:
Позволяет сохранять текущее состояние объекта и восстанавливать его позже.
🟠Инкапсуляция:
Обеспечивает сохранение состояния объекта без нарушения его инкапсуляции. Внутренние детали объекта остаются скрытыми от других объектов.
🟠Отмена и повтор операций:
Поддерживает функциональность отмены и повтора операций, так как позволяет возвращать объект к предыдущим состояниям.
Пример реализации
class Memento:
def __init__(self, state: str):
self._state = state

def get_state(self) -> str:
return self._state

class TextEditor:
def __init__(self):
self._state = ""
self._history = []

def type(self, text: str):
self._save_state()
self._state += text

def _save_state(self):
self._history.append(Memento(self._state))

def undo(self):
if not self._history:
return
memento = self._history.pop()
self._state = memento.get_state()

def get_content(self) -> str:
return self._state

# Клиентский код для использования паттерна Хранитель
def main():
editor = TextEditor()

editor.type("Hello, ")
editor.type("world!")
print(editor.get_content()) # Hello, world!

editor.undo()
print(editor.get_content()) # Hello,

editor.undo()
print(editor.get_content()) #

if __name__ == "__main__":
main()


1⃣`Memento`:
Сохраняет состояние объекта. Он предоставляет методы для получения сохраненного состояния, но не предоставляет методов для изменения состояния, что обеспечивает неизменность.

2⃣`TextEditor`:
Создает и использует объекты Memento для сохранения и восстановления своего состояния. Методы type и undo позволяют редактировать текст и отменять изменения.

3⃣`_save_state`:
Сохраняет текущее состояние редактора в истории перед каждым изменением.

4⃣`undo`:
Восстанавливает предыдущее состояние редактора из истории.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
🤔 Какая проблема связана с множественным наследованием?

1. Проблема алмаза наследования: порядок вызовов методов становится неоднозначным, если класс наследует от двух классов, имеющих общий предок.
2. Решает это через алгоритм MRO (Method Resolution Order), но это может усложнить проектирование.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1
🤔 Для чего нужны dunder методы?

1. Dunder (double underscore) методы предоставляют интерфейсы для встроенных операций, таких как арифметика, сравнение, представление объекта.
2. Например, str для строкового представления, add для перегрузки оператора +.
3. Они делают классы более гибкими и интегрируемыми с Python-экосистемой.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2
🤔 Как реализовать метод new через singleton?

1. Переопределить new так, чтобы он сохранял единственный экземпляр класса в атрибуте класса.
2. Если экземпляр уже создан, возвращать сохранённый объект, а не создавать новый.
3. Это позволяет гарантировать, что все обращения к классу используют один и тот же экземпляр.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🤔 Какие бывают виды тестов?

Существует несколько видов тестов, каждый из которых имеет свою цель и особенности.

🚩Виды

🟠Юнит-тесты (Unit Tests)
Проверка работы отдельных модулей или функций в изоляции от других частей системы.
Ориентированы на минимальные части кода (функции, методы, классы).
Высокая скорость выполнения.
Простота написания и отладки.
Обычно пишутся разработчиками.
def add(a, b):
return a + b

def test_add():
assert add(1, 2) == 3


🟠Интеграционные тесты (Integration Tests)
Проверка взаимодействия между различными модулями или компонентами системы.
Тестируют комбинации модулей и их взаимодействие.
Более сложные и медленные по сравнению с юнит-тестами.
Могут выявить проблемы в интерфейсах между модулями.
def fetch_data_from_api():
response = requests.get('https://api.example.com/data')
return response.json()

def test_fetch_data_from_api():
data = fetch_data_from_api()
assert 'key' in data


🟠Системные тесты (System Tests)
Проверка всей системы целиком на соответствие требованиям.
Тестируют систему в рабочей среде.
Включают проверку всех функциональных и нефункциональных требований.
Могут включать пользовательские сценарии.
Тестирование веб-приложения на основе реальных пользовательских сценариев, включая проверку интерфейса, баз данных и API.

🟠Приемочные тесты (Acceptance Tests)
Проверка соответствия системы требованиям и ожиданиям заказчика или конечного пользователя.
Часто выполняются вместе с заказчиком или пользователем.
Фокусируются на бизнес-требованиях и пользовательских сценариях.
Успешное прохождение приемочных тестов является критерием готовности системы к выпуску.
Тестирование нового функционала с участием конечных пользователей для проверки его удобства и соответствия их ожиданиям.

🟠Регрессионные тесты (Regression Tests)
Убедиться, что изменения в коде не вызвали новых ошибок в уже работающем функционале.
Выполняются после внесения изменений в код.
Обычно автоматизируются и включают повторное выполнение всех или части существующих тестов.
Повторное выполнение всех юнит-тестов и интеграционных тестов после рефакторинга кода.

🟠Нефункциональные тесты (Non-functional Tests)
Проверка нефункциональных аспектов системы, таких как производительность, безопасность, удобство использования и др.

🚩Основные виды:

🟠Тесты производительности
Измеряют скорость выполнения, пропускную способность и время отклика системы.
🟠Тесты безопасности
Оценивают защищенность системы от угроз и атак.
🟠Тесты удобства использования
Проверяют удобство и интуитивность пользовательского интерфейса.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍62
🤔 Как выражена инкапсуляция?

1. Инкапсуляция выражена через модификаторы доступа: public, protected и private.
2. Используется соглашение: _ для защищённых и __ для приватных атрибутов.
3. Обеспечивает управление доступом к данным и методам, скрывая детали реализации.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥4
🤔 Что такое обработка исключений?

Обработка исключений — это механизм в программировании, который позволяет предотвращать аварийное завершение программы, если во время выполнения возникает ошибка. Вместо того чтобы программа просто "упала", обработка исключений дает возможность перехватить ошибку и обработать её безопасным способом.

🚩Почему это нужно?

В реальном коде ошибки неизбежны:
деление на ноль (ZeroDivisionError),
обращение к несуществующему индексу (IndexError),
работа с несуществующим файлом (FileNotFoundError) и т. д.

🚩Как это работает?

В Python для обработки исключений используется конструкция try-except.
Обработка деления на ноль
try:
x = 10 / 0 # Ошибка: деление на ноль
except ZeroDivisionError:
print("Ошибка! Деление на ноль невозможно.")

Результат: вместо аварийного завершения программы мы получаем сообщение
Ошибка! Деление на ноль невозможно.


Обработка нескольких типов исключений
try:
num = int(input("Введите число: ")) # Возможна ошибка ValueError
result = 10 / num # Возможна ошибка ZeroDivisionError
except ZeroDivisionError:
print("Ошибка! Деление на ноль.")
except ValueError:
print("Ошибка! Введите число.")


Если пользователь введет "abc", программа не завершится с ошибкой, а выведет
Ошибка! Введите число.


Использование finally (код, который выполняется всегда)
try:
file = open("data.txt", "r") # Возможна ошибка FileNotFoundError
content = file.read()
except FileNotFoundError:
print("Файл не найден!")
finally:
print("Программа завершена.") # Выполнится в любом случае


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍1
🤔 Чем отличается микросервисная архитектура от монолитной?

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


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥5
🤔 Чем отличаются методы сокрытия?

Методы и атрибуты класса могут быть скрыты от внешнего использования с помощью различных уровней сокрытия. Сокрытие реализуется с помощью соглашений об именах, а не с помощью жесткой инкапсуляции, как в некоторых других языках программирования. Основные уровни сокрытия включают публичные, защищенные и приватные методы и атрибуты.

🚩Публичные методы и атрибуты

Доступны из любого места, как внутри класса, так и за его пределами. Их имена не начинаются с подчеркиваний.
class MyClass:
def __init__(self):
self.public_attribute = "I am public"

def public_method(self):
return "This is a public method"

obj = MyClass()
print(obj.public_attribute) # Вывод: I am public
print(obj.public_method()) # Вывод: This is a public method


🚩Защищенные методы и атрибуты

Не предназначены для использования за пределами класса и его подклассов. Они обозначаются одним подчеркиванием в начале имени. Это всего лишь соглашение, сигнализирующее другим разработчикам, что такие методы и атрибуты не следует использовать вне класса или его подклассов.
class MyClass:
def __init__(self):
self._protected_attribute = "I am protected"

def _protected_method(self):
return "This is a protected method"

class SubClass(MyClass):
def access_protected(self):
return self._protected_method()

obj = MyClass()
sub_obj = SubClass()

print(sub_obj.access_protected()) # Вывод: This is a protected method


🚩Приватные методы и атрибуты

Скрыты от внешнего доступа и доступны только внутри самого класса. Они обозначаются двумя подчеркиваниями в начале имени. Python реализует это с помощью механизма именования, который изменяет имя метода или атрибута, добавляя к нему имя класса, чтобы затруднить доступ извне.
class MyClass:
def __init__(self):
self.__private_attribute = "I am private"

def __private_method(self):
return "This is a private method"

def access_private(self):
return self.__private_method()

obj = MyClass()

try:
print(obj.__private_attribute)
except AttributeError as e:
print(e) # Вывод: 'MyClass' object has no attribute '__private_attribute'

try:
print(obj.__private_method())
except AttributeError as e:
print(e) # Вывод: 'MyClass' object has no attribute '__private_method'

# Доступ к приватным методам через публичный метод класса
print(obj.access_private()) # Вывод: This is a private method


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍1
🤔 Зачем может потребоваться создавать свой тип исключения?

Собственный тип исключения нужен для более точного описания ошибок в бизнес-логике или специфичных ситуаций, которые невозможно выразить стандартными исключениями. Это улучшает читаемость кода и упрощает отладку.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
🤔 Почему плохо хранить данные SQL в Docker контейнере?

Хранение данных базы данных (SQL) внутри Docker-контейнера не рекомендуется, потому что контейнеры являются временными и одноразовыми. При удалении или пересоздании контейнера все данные внутри него теряются.

🚩Данные удаляются при удалении контейнера
Контейнеры в Docker спроектированы так, чтобы их можно было легко пересоздавать. Если удалить контейнер (docker rm), все данные, хранящиеся внутри него, исчезнут навсегда.
docker run --name mydb -e MYSQL_ROOT_PASSWORD=secret -d mysql
docker stop mydb
docker rm mydb # Удаляем контейнер – все данные пропали!


🚩Проблемы с обновлением и масштабированием

Если база данных хранится внутри контейнера, обновить версию MySQL/PostgreSQL будет сложно. При пересоздании контейнера все данные потеряются, и их придется восстанавливать из резервной копии.

🚩Низкая производительность I/O

Хранение данных внутри контейнера может снизить скорость работы базы, потому что Docker использует копию на запись (Copy-on-Write, CoW).
Решение — использовать прямые тома (volumes) или монтировать каталог хоста.
docker run --name mydb -v /data/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=secret -d mysql


🚩Проблемы с резервным копированием

Если база находится внутри контейнера, то сделать бэкап или восстановить данные сложно.
Лучшее решение: использовать volumes + делать бэкапы через mysqldump или pg_dump.
docker exec mydb mysqldump -u root -psecret mydatabase > backup.sql


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8💊6
🤔 Что такое SRP?

Это принцип единственной ответственности, утверждающий, что каждый класс или модуль должен иметь только одну причину для изменения. Это повышает читаемость, тестируемость и повторное использование кода.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥5
🤔 Какие есть минусы у Monkey Patch если использовать не в тесте?

Monkey Patching — это изменение или замена кода существующих классов и функций во время выполнения программы. Хотя этот метод бывает полезен, особенно в тестировании, его использование в продакшене может привести к опасным и непредсказуемым последствиям

🚩Ломает предсказуемость кода

Когда ты изменяешь поведение встроенных библиотек или сторонних модулей на лету, программисты, читающие код, не смогут понять, почему стандартные функции ведут себя не так, как ожидалось.
import datetime

# Меняем поведение метода now()
def fake_now():
return datetime.datetime(2000, 1, 1)

datetime.datetime.now = fake_now # Monkey Patch

print(datetime.datetime.now()) # Выведет 2000-01-01 00:00:00


🚩Может вызвать неожиданные ошибки после обновления библиотек

Если библиотека обновится, и её внутренняя логика изменится, Monkey Patch может перестать работать или, что ещё хуже, привести к багам.
Ты сделал Monkey Patch метода json.dumps, а потом библиотека json обновилась и поменяла его сигнатуру. Теперь твой патч сломается или будет работать некорректно.

🚩Трудно отлаживать и поддерживать

Monkey Patching меняет поведение кода в скрытом режиме, поэтому сложно понять, почему что-то работает не так. Если баг возник из-за патча, отладка может занять часы или даже дни.
Ты исправил баг с str.split(), заменив его через Monkey Patch, но через 6 месяцев разработчик обновил код, забыл про патч, и всё сломалось.

🚩Может затронуть весь код проекта (глобальное изменение)

Monkey Patching меняет поведение для всей программы, а не только в одном модуле или файле. Это делает код хрупким и непредсказуемым.
Если ты изменишь метод dict.get(), он будет вести себя по-другому во всех модулях программы. Это может привести к критическим ошибкам.
original_get = dict.get

def patched_get(self, key, default=None):
print(f"Запрашивается ключ: {key}")
return original_get(self, key, default)

dict.get = patched_get # Monkey Patch

d = {"a": 10}
print(d.get("a")) # Работает, но теперь с побочным эффектом


🚩Нет гарантии, что это сработает во всех окружениях
Monkey Patch может работать на одной версии Python или библиотеки, но сломаться на другой. В продакшене, где есть разные серверы и окружения, это может вызвать непредсказуемые ошибки.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5💊1
🤔 Какие методы разработки есть?

Среди популярных методов разработки: Agile, Scrum, Kanban, Waterfall и Extreme Programming (XP). Каждый из них подходит для различных типов проектов в зависимости от требований и условий.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🤯4💊4
🤔 Что знаешь о идемпотентности?

Идемпотентность — это свойство операции, при котором повторное выполнение приводит к тому же результату, что и первое.

🚩Зачем нужна идемпотентность?

🟠Надёжности
если операция выполнится повторно (из-за ошибки сети), она не приведёт к неожиданному результату.
🟠Безопасности
позволяет избежать дублирования данных или неожиданных изменений.
🟠API и HTTP-запросов
гарантирует, что повторные вызовы API не создадут дубликатов.

🚩Идемпотентность в HTTP (REST API)
В веб-разработке идемпотентность важна для API-запросов, чтобы случайные повторные вызовы не привели к непредсказуемым последствиям.
Этот запрос идемпотентен — если отправить его 10 раз, пользователь "Alice" останется тем же.
POST /users { "name": "Alice" }


🚩Идемпотентность в базах данных

В SQL запросы SELECT и DELETE часто идемпотентны, а INSERT — нет.
DELETE FROM users WHERE id = 5;


Этот запрос идемпотентен — удаление пользователя с ID = 5 несколько раз не изменит систему (если он уже удалён).
INSERT INTO users (name) VALUES ('Alice');


Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍1
🤔 Какие есть 6 этапов разработки продукта?

Шесть этапов разработки продукта включают: анализ требований, проектирование, разработку, тестирование, развёртывание и поддержку. Эти этапы помогают структурировать процесс создания программного обеспечения.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥7
🤔 В чем отличие асинхронности, threading'га и мультипроцессинга?

Асинхронность, threading и мультипроцессинг - это три различных подхода к параллельному выполнению задач каждый из которых имеет свои особенности и применения:

🚩Асинхронность (Asynchronous)

Асинхронность предполагает выполнение задач без ожидания их завершения. Используется для работы с вводом-выводом (I/O), таким как чтение или запись файлов, сетевые запросы и т. д. В асинхронном коде задачи не блокируют основной поток выполнения, что позволяет эффективно использовать ресурсы процессора. Примеры асинхронных моделей включают в себя асинхронные функции и ключевые слова в Python (например, async, await).

🚩Потоки (Threading)

Потоки позволяют выполнять несколько частей кода (потоков) параллельно в пределах одного процесса. Используются для выполнения многозадачных операций, которые могут быть распределены между несколькими ядрами процессора. Потоки могут выполняться параллельно, но могут также конкурировать за общие ресурсы, что может привести к проблемам синхронизации и безопасности. В некоторых языках, таких как Python, использование потоков ограничено из-за GIL (Global Interpreter Lock), что может снижать эффективность при использовании множества потоков для CPU-интенсивных задач.

🚩Мультипроцессинг (Multiprocessing)

Мультипроцессинг также позволяет выполнять несколько частей кода параллельно, но каждая часть выполняется в отдельном процессе. Каждый процесс имеет свое собственное пространство памяти, что делает мультипроцессинг более подходящим для многозадачных вычислений на многоядерных системах. Процессы обычно имеют больший накладные расходы по сравнению с потоками, поскольку каждый из них требует своих собственных ресурсов памяти и управления. Мультипроцессинг избегает проблемы GIL, что делает его более эффективным для CPU-интенсивных задач в Python и других языках.

Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82
🤔 В чем разница между хешированием и шифрованием?

Это необратимое преобразование данных для их идентификации, тогда как шифрование предполагает обратимое преобразование для защиты данных. Хеширование используется для проверки целостности, а шифрование — для конфиденциальности.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥91