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

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

Это структурный шаблон проектирования, который предоставляет объект, управляющий доступом к другому объекту. Этот паттерн создаёт суррогат или заместителя для другого объекта и контролирует доступ к нему.

🚩Зачем нужен паттерн Заместитель

🟠Управление доступом
Когда необходимо контролировать доступ к ресурсу.
🟠Отложенная инициализация
Когда необходимо отложить создание ресурсоёмких объектов до момента их первого использования.
🟠Управление ресурсами
Для управления ресурсами, такими как память или сетевые соединения.
🟠Логирование и кэширование
Для добавления дополнительной функциональности, такой как логирование или кэширование, без изменения кода основного объекта.

🚩Типы заместителей

🟠Управляющий заместитель (Virtual Proxy):
Контролирует доступ к объекту, создавая его по требованию.
🟠Защитный заместитель (Protection Proxy):
Контролирует доступ к объекту, ограничивая права пользователей.
🟠Удалённый заместитель (Remote Proxy)
Управляет доступом к объекту, находящемуся в другом адресном пространстве.
🟠Кэш-прокси (Cache Proxy)
Кэширует результаты запросов к объекту для повышения производительности.

🚩Как используется паттерн Заместитель

Заместитель реализует интерфейс основного объекта и перенаправляет вызовы к реальному объекту, добавляя при этом дополнительную функциональность. В этом примере класс Proxy контролирует доступ к классу RealSubject, добавляя проверку доступа и логирование.
from abc import ABC, abstractmethod

class Subject(ABC):
@abstractmethod
def request(self):
pass

class RealSubject(Subject):
def request(self):
print("Реальный объект: Обработка запроса.")

class Proxy(Subject):
def __init__(self, real_subject):
self._real_subject = real_subject

def request(self):
if self.check_access():
self._real_subject.request()
self.log_access()

def check_access(self):
print("Заместитель: Проверка доступа перед выполнением запроса.")
return True

def log_access(self):
print("Заместитель: Логирование времени запроса.")

# Клиентский код
real_subject = RealSubject()
proxy = Proxy(real_subject)

proxy.request()


Ставь 👍 и забирай 📚 Базу знаний
👍3
🤔 Что означает %s?

%s — это форматная строка, placeholder для вставки строки. Применяется при форматировании строк через оператор %. Используется для подстановки значений в строку определённого типа (в данном случае — строка).


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍5🔥5
🤔 Что такое объект первого класса?

Объект первого класса (или сущность первого класса) — это концепция из программирования, которая означает, что объект обладает всеми следующими свойствами:

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

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

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

🚩Пример на Python

Присваивание функции переменной
def say_hello():
return "Hello!"

# Функция присваивается переменной
greet = say_hello
print(greet()) # Вывод: Hello!


Передача функции как аргумента
def apply_function(func, value):
return func(value)

def square(x):
return x * x

result = apply_function(square, 5)
print(result) # Вывод: 25


Возврат функции из функции
def multiplier(n):
def multiply(x):
return x * n
return multiply

double = multiplier(2)
print(double(10)) # Вывод: 20


Ставь 👍 и забирай 📚 Базу знаний
👍6
🤔 Как связаны for и next?

Цикл for в Python работает на основе итераторов. Он неявно вызывает метод next, чтобы получить следующий элемент из последовательности. Когда элементы заканчиваются, вызывается исключение, которое завершает цикл. Таким образом, for — это более удобная и безопасная обёртка над вызовами next.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍7🔥2
🤔 Какие нюансы есть в использовании чисел как ключей?

Использование чисел в качестве ключей в словарях Python – это достаточно распространённый случай. Однако у этого подхода есть несколько нюансов, которые нужно учитывать для избежания ошибок.

🚩Хешируемость чисел

Ключи в словаре должны быть хешируемыми, поскольку словари в Python основаны на хеш-таблицах. Хешируемость означает, что объект имеет неизменное значение хеша в течение его жизни. Числа (как int, так и float) являются хешируемыми, поэтому их можно использовать в качестве ключей.
d = {1: "один", 2: "два"}
print(d[1]) # "один"


🚩Взаимодействие `int` и `float`

Python не делает различий между int и float, если их значения равны. Это связано с тем, что у них одинаковое хеш-значение при равенстве.
d = {1: "один", 1.0: "float один", 2: "два"}
print(d) # {1: 'float один', 2: 'два'}


🚩Непредсказуемое поведение при работе с `float`

Числа с плавающей запятой (float) иногда ведут себя непредсказуемо из-за ошибок округления, которые возникают из-за особенностей представления чисел в памяти компьютера.
d = {0.1 + 0.2: "значение"}  # 0.1 + 0.2 не равно точно 0.3 из-за округления
print(d.get(0.3)) # None, ключ не найден!


🚩Производительность

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

🚩Проблемы при преобразованиях

Если ключами словаря являются числа, то при обработке данных (например, чтении из файла или API) можно случайно преобразовать их в строки, что приведёт к созданию новых ключей вместо использования существующих.
d = {1: "один", 2: "два"}
print(d.get("1")) # None, строка "1" и число 1 – это разные ключи!


🚩Пользовательские объекты с числовыми свойствами

Если вы используете пользовательские объекты как ключи и они ведут себя как числа (например, реализуют методы __hash__ и __eq__), то их поведение должно быть совместимо с ожидаемым использованием.
class MyNumber:
def __init__(self, value):
self.value = value

def __hash__(self):
return hash(self.value)

def __eq__(self, other):
return self.value == other.value

d = {MyNumber(1): "один"}
print(d[MyNumber(1)]) # "один"


Ставь 👍 и забирай 📚 Базу знаний
👍7
🤔 Что такое DNS и как он работает?

DNS (Domain Name System) — это система, которая преобразует доменное имя (например,
google.com) в IP-адрес, нужный для соединения.
Принцип работы:
1. Вводишь адрес в браузере.
2. Запрос уходит к DNS-серверу.
3. Он возвращает IP-адрес.
4. С этого момента браузер знает, куда направить HTTP-запрос.
DNS работает как телефонная книга интернета.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍8🔥1
🤔 Какие объекты можно положить в множество?

В Python множество (set) — это неупорядоченная коллекция уникальных элементов, которая работает на основе хеш-таблицы. Это значит, что только хешируемые (immutable) объекты могут быть добавлены в set.

🚩Можно добавить в `set`:

Числа (int, float, complex)
   s = {1, 2.5, 3+4j}


Строки (str)
   s = {"apple", "banana", "cherry"}


Кортежи (tuple), если они тоже содержат только неизменяемые объекты
   s = {(1, 2), ("a", "b")}


Булевые значения (bool)** (но True считается 1, а False0)
   s = {True, False, 1, 0}
print(s) # {False, True} (0 и 1 не добавятся повторно)


🚩Нельзя добавить в `set`

Изменяемые объекты (list, set, dict)
   s = { [1, 2, 3] }  #  Ошибка: TypeError: unhashable type: 'list'


   s = { {"key": "value"} }  #  Ошибка: TypeError: unhashable type: 'dict'


Кортежи с изменяемыми элементами
   s = { (1, [2, 3]) }  #  Ошибка: TypeError


Ставь 👍 и забирай 📚 Базу знаний
👍8
🤔 Строка — это последовательность или нет?

Да, в Python строка (str) — это последовательность символов, поддерживающая индексацию, срезы и итерируемость.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍8🔥1
🤔 Что такое многопоточность/многопроцессорность?

В программировании многопоточность и многопроцессорность помогают выполнять задачи параллельно, но работают по-разному.

🟠Многопоточность (Multithreading)
Многопоточность позволяет одной программе запускать несколько потоков (threads), которые работают одновременно.
import threading
import time

def task(name):
print(f"{name} начал работу")
time.sleep(2)
print(f"{name} завершил работу")

# Создаём два потока
t1 = threading.Thread(target=task, args=("Поток 1",))
t2 = threading.Thread(target=task, args=("Поток 2",))

t1.start()
t2.start()

t1.join()
t2.join()
print("Все потоки завершены")


Вывод
Поток 1 начал работу
Поток 2 начал работу
Поток 1 завершил работу
Поток 2 завершил работу
Все потоки завершены


🟠2. Многопроцессорность (Multiprocessing)
Многопроцессорность запускает отдельные процессы, которые работают полностью независимо и могут использовать разные ядра процессора.
import multiprocessing
import time

def task(name):
print(f"{name} начал работу")
time.sleep(2)
print(f"{name} завершил работу")

if __name__ == "__main__":
p1 = multiprocessing.Process(target=task, args=("Процесс 1",))
p2 = multiprocessing.Process(target=task, args=("Процесс 2",))

p1.start()
p2.start()

p1.join()
p2.join()
print("Все процессы завершены")


Вывод (процессы действительно работают параллельно)
Процесс 1 начал работу
Процесс 2 начал работу
Процесс 1 завершил работу
Процесс 2 завершил работу
Все процессы завершены


Ставь 👍 и забирай 📚 Базу знаний
👍5
🤔 Что такое self?

Это ссылка на текущий экземпляр класса, используемая для доступа к атрибутам и методам объекта.
Он всегда первым аргументом передаётся в методы экземпляра класса.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍9🔥2💊1
🤔 Что такое CRUD?

CRUD — это аббревиатура из четырех основных операций с данными:

C (Create) – создание
R (Read) – чтение
U (Update) – обновление
D (Delete) – удаление

🚩Разберем CRUD на примере работы с базой данных в Python

🟠Create (Создание)
Добавление новой записи в базу данных.
import sqlite3

conn = sqlite3.connect("example.db")
cursor = conn.cursor()

# Создаем таблицу, если её нет
cursor.execute("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT)")

# Добавляем пользователя
cursor.execute("INSERT INTO users (name) VALUES (?)", ("Алиса",))

conn.commit() # Сохраняем изменения
conn.close()


🟠Read (Чтение)
Получение данных из базы.
conn = sqlite3.connect("example.db")
cursor = conn.cursor()

cursor.execute("SELECT * FROM users")
users = cursor.fetchall() # Получаем все записи

for user in users:
print(user)

conn.close()


🟠Update (Обновление)
Изменение существующей записи.
conn = sqlite3.connect("example.db")
cursor = conn.cursor()

cursor.execute("UPDATE users SET name = ? WHERE id = ?", ("Боб", 1))

conn.commit()
conn.close()


🟠Delete (Удаление)
Удаление записи из базы.
conn = sqlite3.connect("example.db")
cursor = conn.cursor()

cursor.execute("DELETE FROM users WHERE id = ?", (1,))

conn.commit()
conn.close()


Ставь 👍 и забирай 📚 Базу знаний
👍9
🤔 Какие типы HTTP запросов знаешь? В чем их отличия?

Типы: GET (получение данных), POST (отправка данных), PUT (обновление ресурса), DELETE (удаление ресурса), PATCH (частичное обновление). GET передаёт параметры в URL, а POST отправляет данные в теле запроса. PUT и DELETE изменяют состояние сервера, а PATCH обновляет только указанные части ресурса.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍7
🤔 В чем отличия pytz от datetime?

🟠`datetime` – встроенный модуль Python
Модуль datetime позволяет работать с датами и временем, но по умолчанию он не поддерживает часовые пояса.
from datetime import datetime

dt = datetime.now() # Получаем текущую дату и время
print(dt) # Например: 2024-02-28 14:30:00.123456
print(dt.tzinfo) # None (нет информации о часовом поясе)


🟠`pytz` – внешний модуль для работы с часовыми поясами
Библиотека pytz добавляет поддержку часовых поясов и позволяет работать с разными временными зонами.
from datetime import datetime
import pytz

tz = pytz.timezone("Europe/Moscow") # Часовой пояс Москвы
dt = datetime.now(tz) # Получаем текущее время с учетом часового пояса

print(dt) # Например: 2024-02-28 17:30:00+03:00
print(dt.tzinfo) # Europe/Moscow


🚩Как работать с часовыми поясами правильно?

Создание datetime с часовым поясом pytz
dt = datetime(2024, 2, 28, 15, 0)  # Наивная дата
tz = pytz.timezone("Europe/Moscow")
dt = tz.localize(dt) # Присваиваем часовой пояс
print(dt) # 2024-02-28 15:00:00+03:00


Конвертация времени между часовыми поясами
ny_tz = pytz.timezone("America/New_York")
ny_time = dt.astimezone(ny_tz)
print(ny_time) # Конвертированное время в Нью-Йорке


Использование UTC (лучший подход для серверов)
utc_now = datetime.now(pytz.UTC)  # Текущее время в UTC
print(utc_now) # Например: 2024-02-28 14:30:00+00:00


Ставь 👍 и забирай 📚 Базу знаний
👍6🤔1💊1
🤔 Что такое Docker image?

Docker image — это шаблон неизменяемой файловой системы, содержащий всё необходимое для запуска приложения: ОС, библиотеки, зависимости, файлы. Из образа можно запускать один или несколько контейнеров.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍4
🤔 Для чего можно использовать celery?

Celery - это очередь задач (task queue), которая позволяет выполнять задачи асинхронно и распределять их между различными рабочими процессами или узлами. Она обычно используется для выполнения долгих и трудоемких операций в фоновом режиме, таких как обработка задач веб-приложений, отправка электронных писем, генерация отчетов, обработка изображений, а также многие другие.

🚩Вот некоторые типичные сценарии использования Celery:

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

🟠Отправка электронных писем
Может использоваться для отправки электронных писем асинхронно. Это позволяет вашему приложению отправлять уведомления и письма пользователям без блокировки основного потока выполнения.

🟠Обработка изображений
Может использоваться для обработки изображений асинхронно. Например, вы можете использовать его для изменения размера изображений, преобразования форматов или применения фильтров без задержки ответа вашего приложения.

🟠Периодические задачи
Поддерживает периодические задачи, которые могут выполняться автоматически по расписанию. Это позволяет вам запускать задачи на основе времени, что особенно полезно для выполнения регулярных обновлений и обслуживания.

🟠Распределенные вычисления
Позволяет распределенно выполнять задачи на различных узлах или рабочих процессах, что позволяет обрабатывать большие объемы данных и операций параллельно.

Ставь 👍 и забирай 📚 Базу знаний
👍4
🤔 pickle.dumps / pickle.dump, pickle.loads / pickle.load?

Эти функции сериализуют и десериализуют Python-объекты в бинарном формате. В отличие от JSON, pickle поддерживает больше типов, но может быть небезопасен для недоверенных данных.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍1
🤔 Какие есть особенности исключения в Python?

В Python исключения (exceptions) — это специальные объекты, которые возникают при ошибках и прерывают выполнение программы, если их не обработать.

Все исключения в Python — это объекты, унаследованные от BaseException.
try:
1 / 0
except ZeroDivisionError as e:
print(type(e)) # <class 'ZeroDivisionError'>
print(e) # division by zero


Все исключения унаследованы от BaseException:
BaseException
├── Exception
│ ├── ArithmeticError
│ │ ├── ZeroDivisionError
│ │ ├── OverflowError
│ ├── ValueError
│ ├── IndexError
│ ├── KeyError
│ ├── TypeError
├── SystemExit
├── KeyboardInterrupt


Можно перехватывать несколько исключений
try:
x = int("abc") # Ошибка ValueError
except (ValueError, TypeError) as e:
print(f"Ошибка: {e}")


Если не знаем, какая ошибка может произойти:
try:
x = 1 / 0
except Exception as e:
print(f"Ошибка: {e}") # division by zero


finally выполняется всегда
try:
1 / 0
except ZeroDivisionError:
print("Ошибка!")
finally:
print("Этот код выполнится всегда")


raise позволяет выбрасывать исключения вручную
raise ValueError("Ошибка: неверное значение!")


Можно создать свой класс ошибки, унаследованный от Exception:
class MyError(Exception):
pass

raise MyError("Это моя ошибка!")


Ставь 👍 и забирай 📚 Базу знаний
👍2
🤔 Threading что это?

Threading в Python — это использование потоков для выполнения множества задач одновременно в рамках одного процесса. Это полезно для выполнения I/O-задержанных задач и повышения реактивности программы. Однако из-за глобальной блокировки интерпретатора (GIL) в CPython, потоки не всегда могут эффективно использоваться для задач, требующих интенсивных вычислений.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍2🔥1
🤔 Как управлять кешированием в HTTP?

Кэширование в HTTP позволяет уменьшить нагрузку на сервер и ускорить загрузку страниц за счёт сохранения копий ресурсов.
Управление кэшем происходит через HTTP-заголовки, которые указывают, как долго хранить данные и когда обновлять их.

🟠Управление кэшированием через `Cache-Control`
Cache-Control — основной заголовок для кэширования, который указывает, как долго хранить ресурс и когда обновлять его.
Cache-Control: no-cache            # Браузер всегда запрашивает ресурс заново
Cache-Control: no-store # Запрещает кэширование вообще
Cache-Control: public, max-age=3600 # Кэшировать 1 час (3600 секунд)
Cache-Control: private, max-age=600 # Кэш только для одного пользователя (например, личный кабинет)
Cache-Control: must-revalidate # Клиент должен проверять, истёк ли срок кэша перед загрузкой


🟠Управление кэшем с `ETag` (оптимизированное обновление)
ETag — это уникальный идентификатор версии файла.
Сервер отправляет ресурс с ETag:
ETag: "abc123"

При следующем запросе браузер отправляет If-None-Match:
If-None-Match: "abc123"


Если ресурс не изменился, сервер отвечает 304 Not Modified (клиент использует кэш).
Если ресурс изменился — сервер отправляет новую версию.
HTTP/1.1 304 Not Modified


🟠Кэширование через `Last-Modified`
Работает аналогично ETag, но вместо идентификатора используется дата последнего изменения.
Сервер отправляет заголовок
Last-Modified: Wed, 21 Feb 2024 10:00:00 GMT


Браузер запрашивает ресурс с If-Modified-Since
If-Modified-Since: Wed, 21 Feb 2024 10:00:00 GMT


🟠Полное отключение кэша
Если нужно всегда загружать свежие данные, используем:
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache # Устарел, но нужен для старых браузеров
Expires: 0


🟠Управление кэшем через `Vary`
Если ресурс зависит от заголовков (User-Agent, Accept-Encoding), используем Vary.
Vary: User-Agent


🟠Принудительное обновление кэша (Cache Busting)
Если сервер отправил старый кэш, можно обновить ресурс с новым URL.
Способы
Добавить версию в URL
/style.css?v=2


Использовать хеш в имени файла:
/style.abc123.css


Ставь 👍 и забирай 📚 Базу знаний
👍3
🤔 Что такое полиморфизм?

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

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍5