Библиотека Pydantic валидирует и преобразует данные согласно типам:
- Примитивы (str, int, float, bool)
- Коллекции (List, Dict, Tuple, Set)
- Даты и UUID
- Вложенные модели
Pydantic полезен при создании API (например, с FastAPI), где входящие данные из запросов должны быть проверены и типизированы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
CRUD — это аббревиатура из четырех основных операций с данными:
C (Create) – создание
R (Read) – чтение
U (Update) – обновление
D (Delete) – удаление
Добавление новой записи в базу данных.
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()
Получение данных из базы.
conn = sqlite3.connect("example.db")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
users = cursor.fetchall() # Получаем все записи
for user in users:
print(user)
conn.close()
Изменение существующей записи.
conn = sqlite3.connect("example.db")
cursor = conn.cursor()
cursor.execute("UPDATE users SET name = ? WHERE id = ?", ("Боб", 1))
conn.commit()
conn.close()
Удаление записи из базы.
conn = sqlite3.connect("example.db")
cursor = conn.cursor()
cursor.execute("DELETE FROM users WHERE id = ?", (1,))
conn.commit()
conn.close()
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
- REST — архитектурный стиль. Использует HTTP-методы (GET, POST, PUT, DELETE), ресурсы представлены как URL (например, /users/1).
- RPC (Remote Procedure Call) — модель, в которой клиент вызывает конкретную функцию или метод на сервере, как будто она локальная (getUserData, saveOrder).
REST работает с ресурсами, RPC — с действиями. REST проще кэшировать, а RPC может быть более гибким в функциональности.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍4
Блокировка (lock) — это механизм, который предотвращает одновременный доступ к данным разными транзакциями, чтобы избежать конфликтов, повреждения данных или "гонки" процессов.
Представь, что два человека редактируют один и тот же документ. Если они начнут менять его одновременно, файл может испортиться. Блокировки в БД работают так же — если один процесс изменяет данные, другой должен подождать, пока первый закончит.
предотвращает одновременные изменения одних и тех же строк.
когда два запроса пытаются изменить одно и то же значение.
разные операции не мешают друг другу.
Строчная (Row Lock) – блокирует только одну строку таблицы.
Табличная (Table Lock) – блокирует всю таблицу целиком.
Блокировка всей базы (Database Lock) – редко используется, но блокирует всю БД.
BEGIN;
SELECT * FROM users WHERE id = 1 FOR UPDATE; -- Блокирует строку, пока транзакция не завершится
Эксклюзивная (Exclusive, X-Lock) – блокирует запись для всех (никакие другие операции её не изменят).
Разделяемая (Shared, S-Lock) – блокирует только на запись (чтение возможно).
BEGIN;
UPDATE users SET balance = balance - 100 WHERE id = 1;
-- Пока транзакция не завершится, другая транзакция не сможет изменить balance пользователя 1.
Явные (ручные) – задаются программистом (
SELECT ... FOR UPDATE
). Неявные (автоматические) – создаются СУБД при
INSERT
, UPDATE
, DELETE
. Если два запроса ждут друг друга, система "зависает". Решение: правильный порядок выполнения транзакций.
Если транзакция не закрывается (
COMMIT
/ROLLBACK
), другие запросы ждут бесконечно. Решение: короткие транзакции, автоматическое завершение. Чем больше блокировок, тем медленнее работа БД.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥1
Host (хост) — это устройство или сервер, подключённый к сети, который может предоставлять или запрашивать данные.
GET /index.html HTTP/1.1
Host: example.com
Когда браузер запрашивает сайт, он отправляет заголовок
Host
, чтобы сервер знал, какой сайт нужно отдать. GET / HTTP/1.1
Host: google.com
User-Agent: Mozilla/5.0
Host — это доменное имя, привязанное к IP-адресу.
-
example.com
→ 192.168.1.100
-
mail.example.com
→ 192.168.1.101
127.0.0.1 mysite.local
Внутри сети устройства тоже считаются хостами (
192.168.1.10
, 192.168.1.20
). localhost
(127.0.0.1
) — это всегда локальный компьютер.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Динамическая типизация означает, что тип переменной определяется автоматически в момент её инициализации.
Это упрощает код, но может привести к ошибкам в случае некорректного использования типов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥1🤔1
Сортировка слиянием (
Merge Sort
) — это алгоритм, который использует разделяй и властвуй (divide & conquer). В худшем случае сложность O(n log n).
до тех пор, пока не останутся отдельные элементы.
полученные подмассивы.
def merge_sort(arr):
if len(arr) <= 1:
return arr
mid = len(arr) // 2
left = merge_sort(arr[:mid])
right = merge_sort(arr[mid:])
return merge(left, right)
def merge(left, right):
sorted_arr = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
sorted_arr.append(left[i])
i += 1
else:
sorted_arr.append(right[j])
j += 1
sorted_arr.extend(left[i:])
sorted_arr.extend(right[j:])
return sorted_arr
arr = [5, 2, 9, 1, 5, 6]
print(merge_sort(arr))
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
2. Объектно-ориентированная: работа с классами и объектами.
3. Функциональная: поддержка высших функций, замыканий и итераторов.
4. Процедурная: выполнение программ как последовательности процедур.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥1
Это такие типы данных, которые имеют постоянное (неизменяемое) хеш-значение на протяжении всего времени их существования. Это означает, что их можно использовать в качестве ключей в словарях (
dict
) и элементов в множествах (set
), так как они поддерживают вычисление хеша с помощью функции hash()
.если объект можно изменить после создания, его хеш тоже изменится, что нарушает работу структур данных (словари, множества).
который возвращает уникальный идентификатор объекта.
Числа (
int
, float
, complex
)print(hash(42)) # 42
print(hash(3.14)) # 322818021289917443
print(hash(1 + 2j)) # 8389048192121911274
Строки (
str
)print(hash("hello")) # Например, 5320385861927423548
Кортежи (
tuple
), если все их элементы тоже хешируемые:print(hash((1, 2, 3))) # 529344067295497451
Булевы значения (
bool
):print(hash(True)) # 1
print(hash(False)) # 0
Списки (
list
)hash([1, 2, 3]) # TypeError: unhashable type: 'list'
Множества (
set
)hash({1, 2, 3}) # TypeError: unhashable type: 'set'
Словари (
dict
)hash({"a": 1}) # TypeError: unhashable type: 'dict'
Хешируемые типы используются в словари (
dict
) и множества (set
), так как они используют хеш-функцию для быстрого поиска данных.my_dict = { (1, 2, 3): "tuple_key" } # Работает, потому что кортеж неизменяемый
my_set = { 42, "hello", (1, 2) } # Все элементы хешируемые
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Python ищет переменные по правилу LEGB:
- Local — локальная область внутри функции.
- Enclosing — области вложенных функций (для замыканий).
- Global — глобальная область модуля.
- Built-in — встроенные объекты Python.
Поиск идёт сверху вниз, и как только переменная найдена — поиск останавливается.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Хвостовая рекурсия (tail recursion) — это особый вид рекурсии, когда рекурсивный вызов является последней операцией в функции. В языках, поддерживающих оптимизацию хвостовой рекурсии (TCO – Tail Call Optimization), такие вызовы не создают новый стек вызовов, а переиспользуют текущий, что предотвращает переполнение стека.
Но в Python хвостовая рекурсия НЕ оптимизируется из-за особенностей интерпретатора (Python хранит полную историю вызовов для отладки).
Лучший способ избежать проблем с глубокой рекурсией — заменить её циклом.
def factorial(n, acc=1):
if n == 0:
return acc
return factorial(n - 1, acc * n) # Хвостовая рекурсия (но Python не оптимизирует!)
Решение: заменить на цикл (итеративный подход)
def factorial_iter(n):
acc = 1
while n > 0:
acc *= n
n -= 1
return acc
print(factorial_iter(10000)) # Работает без ошибок
Python имеет ограничение на глубину рекурсии (обычно около
1000
). Можно его увеличитьimport sys
sys.setrecursionlimit(20000) # Увеличение лимита
Если рекурсивная функция пересчитывает одни и те же значения, можно кешировать результаты.
from functools import lru_cache
@lru_cache(None) # Кеширует все вызовы функции
def fibonacci(n):
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(100)) # Работает быстро, без переполнения стека
Если алгоритм требует рекурсии, но стек ограничен, можно использовать список как стек.
def factorial_stack(n):
stack = [(n, 1)]
while stack:
n, acc = stack.pop()
if n == 0:
return acc
stack.append((n - 1, acc * n))
print(factorial_stack(10000)) # Работает без ошибок
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Генераторы позволяют создавать значения "по требованию", без необходимости хранить их все в памяти. Они экономят ресурсы при работе с большими объёмами данных. Генераторы удобны для ленивых вычислений, бесконечных последовательностей и обработки потоков данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6💊2👍1
Кэширование в HTTP позволяет уменьшить нагрузку на сервер и ускорить загрузку страниц за счёт сохранения копий ресурсов.
Управление кэшем происходит через HTTP-заголовки, которые указывают, как долго хранить данные и когда обновлять их.
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: "abc123"
При следующем запросе браузер отправляет
If-None-Match
: If-None-Match: "abc123"
Если ресурс не изменился, сервер отвечает
304 Not Modified
(клиент использует кэш). Если ресурс изменился — сервер отправляет новую версию.
HTTP/1.1 304 Not 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
Если ресурс зависит от заголовков (
User-Agent
, Accept-Encoding
), используем Vary
.Vary: User-Agent
Если сервер отправил старый кэш, можно обновить ресурс с новым URL.
Способы
Добавить версию в URL
/style.css?v=2
Использовать хеш в имени файла:
/style.abc123.css
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1🔥1
Да, декораторы можно накладывать друг на друга. Они применяются сверху вниз, но выполняются в обратном порядке.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Паттерн "Мост" (Bridge) является структурным паттерном проектирования, который предназначен для разделения абстракции и реализации так, чтобы они могли изменяться независимо друг от друга. Этот паттерн полезен, когда класс должен работать с различными платформами или когда нужно избежать жесткой связки между абстракцией и ее реализацией.
Он позволяет отделить абстракцию от ее реализации, что упрощает поддержку и расширение системы.
Без применения этого паттерна, если у нас есть несколько вариантов абстракции и несколько вариантов реализации, то нам пришлось бы создавать классы для всех возможных комбинаций, что приводит к взрывному росту количества классов.
Это позволяет изменять и абстракцию, и реализацию независимо друг от друга.
Определяет интерфейс и хранит ссылку на объект Implementor.
Наследует Abstraction и расширяет интерфейс.
Определяет интерфейс для всех реализаций.
Реализует интерфейс Implementor.
Допустим, у нас есть программа для управления различными типами устройств (например, телевизор и радио), которые можно включать и выключать. Мы хотим, чтобы способ управления устройствами мог изменяться независимо от типов устройств.
# Implementor
class Device:
def is_enabled(self):
pass
def enable(self):
pass
def disable(self):
pass
# ConcreteImplementor
class TV(Device):
def __init__(self):
self._on = False
def is_enabled(self):
return self._on
def enable(self):
self._on = True
def disable(self):
self._on = False
class Radio(Device):
def __init__(self):
self._on = False
def is_enabled(self):
return self._on
def enable(self):
self._on = True
def disable(self):
self._on = False
# Abstraction
class RemoteControl:
def __init__(self, device):
self._device = device
def toggle_power(self):
if self._device.is_enabled():
self._device.disable()
else:
self._device.enable()
# RefinedAbstraction
class AdvancedRemoteControl(RemoteControl):
def mute(self):
print("Device is muted.")
# Клиентский код
tv = TV()
remote = RemoteControl(tv)
remote.toggle_power() # Включает TV
radio = Radio()
advanced_remote = AdvancedRemoteControl(radio)
advanced_remote.toggle_power() # Включает Radio
advanced_remote.mute() # Заглушает Radio
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🤔1
Типы данных в Python делятся на:
- Неизменяемые (immutable): int, float, str, tuple, frozenset.
- Изменяемые (mutable): list, dict, set, bytearray.
Изменяемые объекты могут быть модифицированы без изменения их идентификатора (id()), в то время как неизменяемые создают новый объект при любом изменении. Это влияет на поведение в функциях, при копировании, в кэшировании и в хешировании.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6