Параллелизм — это способ выполнения программ, при котором несколько задач выполняются одновременно (реально параллельно). Он используется для ускорения работы программ, особенно на многоядерных процессорах.
Пример без параллелизма (последовательное выполнение)
Допустим, у нас есть две задачи:
1. Скачать файл (3 секунды).
2. Обработать данные (2 секунды).
Если выполнять их последовательно
[1] Скачать файл... (3 сек)
[2] Обработать файл... (2 сек)
[Готово за 5 секунд]
Пример с параллелизмом (оба процесса выполняются одновременно)
Если у нас 2 ядра процессора, можно выполнить задачи одновременно.
[1] Скачать файл... (3 сек) ──► Готово!
[2] Обработать файл... (2 сек) ──► Готово!
[Готово за 3 секунды] ✅ Быстрее!
В Python
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("Все процессы завершены")
Python не может выполнять потоки параллельно из-за GIL, но
threading
всё же полезен для задач ввода-вывода.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("Все потоки завершены")
Асинхронность позволяет не ждать выполнения операции, а переключаться на другие задачи.
import asyncio
async def task(name):
print(f"Начал {name}")
await asyncio.sleep(2) # НЕ блокирует другие задачи
print(f"Закончил {name}")
async def main():
await asyncio.gather(task("Задача 1"), task("Задача 2"))
asyncio.run(main())
Процессор выполняет несколько инструкций одновременно. Например, в современных процессорах есть конвейер (pipeline), который выполняет несколько операций параллельно.
Одна операция применяется к разным данным одновременно (используется в нейросетях, GPU).
import numpy as np
arr = np.array([1, 2, 3, 4])
result = arr * 2 # Все элементы умножаются одновременно (векторизация)
print(result) # [2 4 6 8]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Forwarded from easyoffer
⏳ Осталось всего 14 дней до завершения краудфандинга
Сейчас самое подходящее время подключиться, если вы ждали или откладывали:
Все, кто поддержат проект сейчас, до релиза, получат:
🚀 PRO-доступ на 1 год по цене месячной подписки
➕ Бета-доступ к EasyOffer 2.0 (конец мая)
👉 Поддержать: https://planeta.ru/campaigns/easyoffer
Сейчас самое подходящее время подключиться, если вы ждали или откладывали:
Все, кто поддержат проект сейчас, до релиза, получат:
🚀 PRO-доступ на 1 год по цене месячной подписки
➕ Бета-доступ к EasyOffer 2.0 (конец мая)
👉 Поддержать: https://planeta.ru/campaigns/easyoffer
❤1
Плюсы:
- проще масштабировать;
- можно использовать разные технологии в разных сервисах;
- команды могут работать независимо.
Минусы:
- выше сложность инфраструктуры;
- нужно организовать стабильную коммуникацию между сервисами;
- сложнее отлаживать и следить за всей системой.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥1
Оконные функции (window functions) — это специальные функции в SQL, которые выполняют вычисления по строкам внутри "окна" (группы строк), но не агрегируют их.
SELECT
id,
месяц,
продавец,
сумма,
SUM(сумма) OVER (PARTITION BY месяц) AS общий_доход_в_месяц
FROM sales;
Пронумеруем продажи каждого продавца в порядке убывания суммы.
SELECT
id,
продавец,
сумма,
ROW_NUMBER() OVER (PARTITION BY продавец ORDER BY сумма DESC) AS номер
FROM sales;
Если два продавца получили одинаковую сумму,
RANK()
пропустит следующий номер, а DENSE_RANK()
– нет. SELECT
продавец,
сумма,
RANK() OVER (ORDER BY сумма DESC) AS ранг_1,
DENSE_RANK() OVER (ORDER BY сумма DESC) AS ранг_2
FROM sales;
LAG() даёт предыдущее значение, LEAD() – следующее.
SELECT
месяц,
продавец,
сумма,
LAG(сумма) OVER (PARTITION BY продавец ORDER BY месяц) AS предыдущий_месяц,
LEAD(сумма) OVER (PARTITION BY продавец ORDER BY месяц) AS следующий_месяц
FROM sales;
Иногда нужно анализировать не всю группу, а только несколько соседних строк.
SELECT
месяц,
продавец,
сумма,
AVG(сумма) OVER (PARTITION BY продавец ORDER BY месяц ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS скользящее_среднее
FROM sales;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
Некоторые полезные функции:
- lru_cache — кэширование результатов.
- partial — частичное применение аргументов.
- wraps — сохранение метаданных при создании декораторов.
- cmp_to_key — преобразование функции сравнения в ключ.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍2
Словарь (
dict
) — это структура данных, которая хранит пары "ключ → значение". Через
{}
(фигурные скобки)my_dict = {"name": "Alice", "age": 25, "city": "New York"}
Изменение значения
my_dict["age"] = 26 # Меняем возраст
del
— удаление по ключуdel my_dict["city"]
Перебор ключей (
for key in dict
)for key in my_dict:
print(key, my_dict[key])
Проверка наличия ключа
if "name" in my_dict:
print("Ключ существует!")
Создадим словарь квадратов чисел
squares = {x: x**2 for x in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Нельзя использовать
list
как ключ! my_dict[[1, 2, 3]] = "Ошибка" # TypeError: unhashable type: 'list'
Можно использовать
tuple
, int
, str
, frozenset
my_dict[(1, 2, 3)] = "OK"
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Ключевое слово as позволяет задать псевдоним импортируемому модулю или объекту. Это удобно, когда имя слишком длинное или возникает конфликт имён. Псевдоним упрощает использование и делает код более лаконичным.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
Forwarded from easyoffer
🎉 Easyoffer 2.0 — самый успешный краудфандинг в истории рунета в категории "Технологии"!
Мы это сделали! За считанные часы после старта, благодаря вашей поддержке, проект не просто стартовал — он взлетел.
💸 Собрано: 2 276 840 рублей
Это не просто цифра — это ваше доверие, ваша вера в идею, и ваша инвестиция в будущее карьеры сотен (а скоро — тысяч) специалистов.
💼 Благодаря этой сумме мы уже:
— Наняли ещё пару разработчиков и аналитиков
— Запустили активный сбор и разметку новых данных
— Ускорили разработку и подняли планку качества
Спасибо каждому, кто поверил в нас на старте! Дальше — только масштабирование и развитие. Мы строим сервис, который станет must-have для всех, кто ищет работу в IT.
👉 Присоединяйтесь сейчас — это только начало.
Мы это сделали! За считанные часы после старта, благодаря вашей поддержке, проект не просто стартовал — он взлетел.
💸 Собрано: 2 276 840 рублей
Это не просто цифра — это ваше доверие, ваша вера в идею, и ваша инвестиция в будущее карьеры сотен (а скоро — тысяч) специалистов.
💼 Благодаря этой сумме мы уже:
— Наняли ещё пару разработчиков и аналитиков
— Запустили активный сбор и разметку новых данных
— Ускорили разработку и подняли планку качества
Спасибо каждому, кто поверил в нас на старте! Дальше — только масштабирование и развитие. Мы строим сервис, который станет must-have для всех, кто ищет работу в IT.
👉 Присоединяйтесь сейчас — это только начало.
Ограничения (constraints) в SQL используются для контроля целостности данных в таблицах. Они помогают предотвратить некорректные значения и обеспечить согласованность данных.
Используется, если поле обязательно для заполнения
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL -- Поле name обязательно
);
Нельзя вставить
NULL
в name
INSERT INTO users (id, name) VALUES (1, NULL); -- Ошибка!
Запрещает дубликаты в столбце
CREATE TABLE users (
id INT PRIMARY KEY,
email VARCHAR(100) UNIQUE -- Email должен быть уникальным
);
Попытка вставить одинаковый email вызовет ошибку
INSERT INTO users (id, email) VALUES (1, 'test@example.com');
INSERT INTO users (id, email) VALUES (2, 'test@example.com'); -- Ошибка!
Создание
UNIQUE
на нескольких колонках CREATE TABLE orders (
user_id INT,
product_id INT,
UNIQUE (user_id, product_id) -- Запрещает заказывать один товар дважды
);
Объединяет
NOT NULL + UNIQUE
и гарантирует, что строка уникальна. CREATE TABLE users (
id INT PRIMARY KEY, -- Уникальный идентификатор
name VARCHAR(50)
);
Можно создать
PRIMARY KEY
на нескольких колонках CREATE TABLE enrollments (
student_id INT,
course_id INT,
PRIMARY KEY (student_id, course_id) -- Один студент не может записаться дважды на один курс
);
Создаёт связь между таблицами и поддерживает ссылочную целостность.
Есть таблица пользователей (
users
) и таблица заказов (orders
), где user_id
в orders
должен ссылаться на id
в users
. CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
FOREIGN KEY (user_id) REFERENCES users(id) -- Связь с таблицей users
);
Что делать при удалении пользователя?
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥4
В Python все данные делятся на изменяемые (mutable) и неизменяемые (immutable)
После создания их нельзя изменить!
x = 10
print(id(x)) # 140735598722544 (адрес в памяти)
x = x + 5 # Создаётся новый объект!
print(id(x)) # 140735598722704 (новый адрес)
Пример:
str
неизменяемая s = "hello"
print(id(s)) # 140735598723664
s = s + " world" # Создаётся новая строка!
print(id(s)) # 140735598724240 (новый адрес)
Можно менять их содержимое без создания нового объекта.
lst = [1, 2, 3]
print(id(lst)) # 140735598722544
lst.append(4) # Изменяем список
print(id(lst)) # 140735598722544 (адрес остался тот же!)
Пример:
dict
изменяемый d = {"name": "Alice"}
print(id(d)) # 140735598723664
d["age"] = 25 # Добавляем ключ
print(id(d)) # 140735598723664 (адрес не изменился!)
Неизменяемые объекты безопаснее для ключей
dict
и set
d = {}
d[[1, 2, 3]] = "Ошибка!" # ❌ TypeError: unhashable type: 'list'
Используем
tuple
вместо list
(он неизменяемый) d[(1, 2, 3)] = "OK"
Ошибки с изменяемыми значениями по умолчанию
def add_item(lst=[]): # ❌ Опасный код!
lst.append(1)
return lst
print(add_item()) # [1]
print(add_item()) # [1, 1] ❌ Список не создаётся заново!
Используем
None
вместо списка def add_item(lst=None):
if lst is None:
lst = []
lst.append(1)
return lst
copy()
делает поверхностную копию (новый объект, но старые вложенные элементы). deepcopy()
делает глубокую копию (всё новое). import copy
lst1 = [[1, 2, 3], [4, 5, 6]]
lst2 = copy.copy(lst1) # Поверхностная копия
lst2[0][0] = 99
print(lst1) # [[99, 2, 3], [4, 5, 6]] ❌ Исходный список изменился!
Используем
deepcopy()
для полной независимой копии lst3 = copy.deepcopy(lst1)
lst3[0][0] = 100
print(lst1) # [[99, 2, 3], [4, 5, 6]] ✅ Не изменился!
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥1💊1
Forwarded from easyoffer
Что такое PRO-подписка на easyoffer 2.0?
easyoffer PRO — это не просто доступ к базе, а полноценный инструмент для получения оффера.
🧠 База вопросов с собеседований
+ Анализ на основе 4,000 собеседований
+ Вероятность встречи каждого вопроса
+ Фильтрация по грейдам, компаниям, типам интервью
+ Примеры ответов: текстовые и видео
+ Готовьтесь к собеседованию в конкретную компанию
🛠 Тренажер "Проработка вопросов"
+ Флеш-карточки + интервальные повторения
+ Персональная система показа карточек в зависимости от ваших ответов
+ Упор на наиболее частые вопросы
+ Фокус на слабые места и быстрый прогресс
🎭 Тренажер "Реальное собеседование"
+ Сценарии на основе реальных интервью
+ Подготовка к конкретным компаниям
+ Итоговая статистика: прошёл/не прошёл
🧩 База задач с собеседований
+ Live-coding и System Design задачи
+ Оценка вероятности встречи задачи
+ Подготовка к задачам по конкретным компаниям
📋 База тестовых заданий
+ Задания из реальных вакансий
+ Фильтрация по технологиям и грейдам
+ Лучшие решения в доступе
📈 Тренды технологий в вакансиях
+ Топ-100 навыков, которые требуют компании
+ Динамика популярности технологий
+ Фильтрация по грейдам
🎁 Специальная цена до релиза:
3200 руб. за целый год
Сейчас PRO на 1 год стоит как будет стоить 1 месяц после релиза. Покупка также открывает доступ к закрытому бета-тестированию.
+ Вы можете активировать подписку в любой момент, например, когда начнете искать работу.
Предзаказ здесь: https://planeta.ru/campaigns/easyoffer
📌 Цена поднимется сразу после запуска.
Если вы хотите перестать угадывать, что спросят на собеседовании, и начать точечно готовиться на основе реальных данных — easyoffer PRO именно для вас.
Экономьте время. Получайте оффер легко.
easyoffer PRO — это не просто доступ к базе, а полноценный инструмент для получения оффера.
🧠 База вопросов с собеседований
+ Анализ на основе 4,000 собеседований
+ Вероятность встречи каждого вопроса
+ Фильтрация по грейдам, компаниям, типам интервью
+ Примеры ответов: текстовые и видео
+ Готовьтесь к собеседованию в конкретную компанию
🛠 Тренажер "Проработка вопросов"
+ Флеш-карточки + интервальные повторения
+ Персональная система показа карточек в зависимости от ваших ответов
+ Упор на наиболее частые вопросы
+ Фокус на слабые места и быстрый прогресс
🎭 Тренажер "Реальное собеседование"
+ Сценарии на основе реальных интервью
+ Подготовка к конкретным компаниям
+ Итоговая статистика: прошёл/не прошёл
🧩 База задач с собеседований
+ Live-coding и System Design задачи
+ Оценка вероятности встречи задачи
+ Подготовка к задачам по конкретным компаниям
📋 База тестовых заданий
+ Задания из реальных вакансий
+ Фильтрация по технологиям и грейдам
+ Лучшие решения в доступе
📈 Тренды технологий в вакансиях
+ Топ-100 навыков, которые требуют компании
+ Динамика популярности технологий
+ Фильтрация по грейдам
🎁 Специальная цена до релиза:
3200 руб. за целый год
Сейчас PRO на 1 год стоит как будет стоить 1 месяц после релиза. Покупка также открывает доступ к закрытому бета-тестированию.
+ Вы можете активировать подписку в любой момент, например, когда начнете искать работу.
Предзаказ здесь: https://planeta.ru/campaigns/easyoffer
📌 Цена поднимется сразу после запуска.
Если вы хотите перестать угадывать, что спросят на собеседовании, и начать точечно готовиться на основе реальных данных — easyoffer PRO именно для вас.
Экономьте время. Получайте оффер легко.
Это правило описывает порядок поиска переменных: сначала в локальной области, потом во вложенных функциях (если есть), затем в глобальной области текущего модуля, и в конце — среди встроенных объектов языка. Если переменная не найдена на этих этапах, возникает ошибка.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🤔3🔥2
В Python поиск переменной происходит по правилу LEGB, которое определяет порядок поиска в четырёх областях видимости:
Пример работы LEGB
x = "глобальная" # Global
def outer():
x = "охватывающая" # Enclosing
def inner():
x = "локальная" # Local
print(x) # Поиск начинается отсюда (L)
inner()
outer()
Вывод
локальная
Если нужно изменить глобальную переменную внутри функции, используем
global
x = 10 # Глобальная переменная
def modify_global():
global x
x = 20 # Меняем глобальную переменную
modify_global()
print(x) # 20
Если в вложенной функции нужно изменить переменную из enclosing-области, используем
nonlocal
def outer():
x = 10 # Переменная из enclosing-области
def inner():
nonlocal x
x = 20 # Меняем `x` в `outer()`
inner()
print(x) # 20
outer()
Если переменная не найдена в LEGB, Python выдаст
NameError
def func():
print(y) # Ошибка: y не объявлена!
func()
Ошибка
NameError: name 'y' is not defined
Python в последнюю очереде проверяет встроенные функции (
print()
, len()
, sum()
и т. д.). print = "Ошибка!" # Переопределили встроенную функцию
print("Hello") # TypeError: 'str' object is not callable
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
Блок finally в конструкции обработки исключений выполняется всегда — независимо от того, произошло исключение или нет. Его задача — гарантировать выполнение завершающего кода: освобождение ресурсов, закрытие файлов, завершение соединений. Это полезно для корректного завершения работы программы.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥1
Да, в Django ORM можно указать конкретные поля для сохранения, используя параметр
update_fields
в методе .save()
. Пример модели
from django.db import models
class UserProfile(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
age = models.IntegerField()
Обновляем только поле
name
, не трогая email
и age
user = UserProfile.objects.get(id=1)
user.name = "Новый пользователь"
user.save(update_fields=["name"]) # Обновит только поле `name`
Генерирует SQL-запрос только для указанных полей, например:
UPDATE user_profile SET name = 'Новый пользователь' WHERE id = 1;
Уменьшает нагрузку на БД, так как обновляет только нужные поля.
Полезен, если нужно изменить одно поле, а не всю запись.
Избегает ненужных изменений в
auto_now
и auto_now_add
полях (DateTimeField
). Нельзя использовать при создании объекта (
save()
с update_fields
не работает для .create()
). user = UserProfile(name="Alice", email="alice@example.com")
user.save(update_fields=["name"]) # ❌ Ошибка, объект ещё не в базе!
Не обновляет
auto_now
-поля (DateTimeField
) автоматически! updated_at = models.DateTimeField(auto_now=True) # Не обновится с `update_fields`
Решение: обновить вручную:
user.updated_at = timezone.now()
user.save(update_fields=["name", "updated_at"])
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Есть два механизма управления памятью:
1. Счётчик ссылок (reference counting) — каждый объект отслеживает, сколько ссылок на него существует. Как только счётчик становится 0, объект немедленно удаляется.
2. Сборщик циклов (garbage collector) — предназначен для очистки циклических ссылок (объекты, ссылающиеся друг на друга, но более недоступные извне). Работает фоново и периодически сканирует объекты по поколениям (generation 0, 1, 2), удаляя неиспользуемые.
Python позволяет вручную управлять GC через модуль gc, где можно вызывать gc.collect() или отключать сборку.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍3
Циклы — это конструкции, которые позволяют многократно выполнять код, пока выполняется определённое условие.
В Python есть два типа циклов:
for
— перебирает элементы последовательности (list
, tuple
, dict
, range()
и т. д.). while
— выполняется, пока условие True
. Простой пример
for
for i in range(5):
print(i)
Вывод
0
1
2
3
4
Перебор списка
names = ["Alice", "Bob", "Charlie"]
for name in names:
print(name)
Вывод
Alice
Bob
Charlie
Перебор словаря (
dict
) user = {"name": "Alice", "age": 25}
for key, value in user.items():
print(f"{key}: {value}")
Вывод
name: Alice
age: 25
Пример
while
x = 0
while x < 5:
print(x)
x += 1
Вывод
0
1
2
3
4
*
while
с input()
(бесконечный цикл) while True:
command = input("Введите команду: ")
if command == "exit":
break # Выход из цикла
print(f"Вы ввели: {command}")
break
— выход из цикла for i in range(10):
if i == 5:
break # Прерывает цикл, если i == 5
print(i)
Вывод
0
1
2
3
4
continue
— пропуск итерации for i in range(5):
if i == 2:
continue # Пропускаем 2
print(i)
Вывод
0
1
3
4
else
выполняется, если цикл завершился без break
for i in range(5):
print(i)
else:
print("Цикл завершён!")
Вывод
0
1
2
3
4
Цикл завершён!
Но если сработает
break
, else
не выполняется for i in range(5):
if i == 3:
break
print(i)
else:
print("Цикл завершён!") # Не выполнится!
Вывод
0
1
2
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10💊1
Forwarded from easyoffer
📅 Осталось 7 дней до конца краудфандинга
Мы на финишной прямой!
Если ты планировал присоединиться, но ещё не успел, сейчас идеальный момент.
Вознаграждения за поддержку:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу.
➕ Приглашение на закрытое бета-тестирование
👉 Поддержать easyoffer 2.0
Не откладывай на последний момент
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Мы на финишной прямой!
Если ты планировал присоединиться, но ещё не успел, сейчас идеальный момент.
Вознаграждения за поддержку:
🚀 PRO подписка к easyoffer 2.0 на 1 год по цене месячной подписки. Активировать подписку можно в любой момент, например, когда начнешь искать работу.
➕ Приглашение на закрытое бета-тестирование
👉 Поддержать easyoffer 2.0
Не откладывай на последний момент
📌 Если не получается оплатить через карту РФ — напишите мне @kivaiko, и мы найдём удобный способ
Порт — это числовой идентификатор, который определяет, какое приложение на устройстве должно обработать входящий сетевой трафик.
Например:
- Порт 80 — для HTTP
- Порт 443 — для HTTPS
- Порт 22 — для SSH
Сочетание IP-адреса и порта позволяет доставить данные точно до нужного сервиса.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16💊6🔥2