В SQL можно объединять данные из двух таблиц без использования
JOIN
, используя альтернативные методы. Подзапрос (
subquery
) позволяет выбрать данные из одной таблицы, используя данные из другой. Допустим, у нас есть две таблицы:
employees (id, name, department_id)
departments (id, name)
SELECT name,
(SELECT name FROM departments WHERE id = employees.department_id) AS department_name
FROM employees;
Можно фильтровать данные из одной таблицы, проверяя наличие значений в другой.
SELECT name
FROM employees
WHERE department_id IN (SELECT id FROM departments);
Если таблицы имеют схожие колонки, можно объединить их с
UNION
. SELECT id, name, email FROM users_old
UNION
SELECT id, name, email FROM users_new;
Хотя
CROSS JOIN
делает декартово произведение, его можно фильтровать WHERE
, имитируя INNER JOIN
. SELECT e.name, d.name AS department
FROM employees e, departments d
WHERE e.department_id = d.id;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Forwarded from Идущий к IT
Привет ребята, мне на easyoffer.ru нужен:
🐍 Middle/Senior Python Developer
Стек:
DRF, PostgreSQL, Redis, Celery, Docker, Sentry
Задачи:
🟠 Разработка и поддержка REST API для новых фичей
🟠 Интеграция с веб-сервисами и внешними API
🟠 Подключение и поддержка платежных систем
🟠 Написание юнит- и интеграционных тестов
🟠 Оптимизация производительности и масштабирование
🟠 Взаимодействие с ML-моделями — будет плюсом
Ожидания:
🟠 2+ лет опыта DRF
🟠 Опыт интеграций платежных систем
🟠 Опыт работы с PostgreSQL, Celery, Redis, Docker
🟠 Умение проектировать архитектуру REST-API
🟠 Ответственный подход к качеству кода и тестированию
Опыт в стартапах и небольших командах будет плюсом
Условия:
– Частичная занятость (2-3 часа в день)
– Удаленная работа
– Свободный график
– Почасовая оплата
✈ Если вас заинтересовала вакансия, напишите мне @kivaiko
1. Резюме
2. Ссылку на github
3. Комфортную ставку за час
🐍 Middle/Senior Python Developer
Стек:
DRF, PostgreSQL, Redis, Celery, Docker, Sentry
Задачи:
Ожидания:
Опыт в стартапах и небольших командах будет плюсом
Условия:
– Частичная занятость (2-3 часа в день)
– Удаленная работа
– Свободный график
– Почасовая оплата
1. Резюме
2. Ссылку на github
3. Комфортную ставку за час
Please open Telegram to view this post
VIEW IN TELEGRAM
💊2
Схема (schema) в базе данных — это логическая группировка объектов (таблиц, индексов, представлений и т. д.) внутри одной БД.
Схема — это контейнер для объектов БД (таблиц, индексов, процедур).
База данных (company_db)
├── Схема: public (по умолчанию)
│ ├── Таблица: employees
│ ├── Таблица: departments
├── Схема: hr
│ ├── Таблица: employees
│ ├── Таблица: salaries
├── Схема: sales
│ ├── Таблица: customers
│ ├── Таблица: orders
Создание схемы (
CREATE SCHEMA
) CREATE SCHEMA hr; -- Создаём схему "hr"
Создание таблицы внутри схемы
CREATE TABLE hr.employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
position VARCHAR(50)
);
Выбор схемы по умолчанию
SET search_path TO hr;
Если в БД хранятся разные области бизнеса (кадры, продажи, финансы), их можно разделить по схемам:
-
hr.employees
, hr.salaries
-
sales.orders
, sales.customers
Например, в PostgreSQL можно создать схему
dev
для тестов: -
dev.users
— тестовая версия таблицы -
prod.users
— продакшен-версия Можно дать доступ к разным схемам разным пользователям:
GRANT USAGE ON SCHEMA hr TO hr_manager;
GRANT SELECT ON ALL TABLES IN SCHEMA hr TO hr_manager;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9💊1
- PUT — идемпотентный: повторный вызов приводит к одному и тому же состоянию ресурса.
- PATCH — условно идемпотентный, если изменения одинаковы.
- POST — не идемпотентный, каждый запрос может создать новый объект или изменить данные.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥7❤1💊1
Пузырьковая сортировка (Bubble Sort) — это один из самых простых, но неэффективных алгоритмов сортировки.
1. Проходим по массиву несколько раз.
2. На каждой итерации сравниваем соседние элементы и меняем их местами, если они идут не в том порядке.
3. После первого прохода наибольший элемент оказывается в конце массива.
4. Повторяем процесс, пока массив не отсортируется.
Количество сравнений в худшем случае:
- На первой итерации:
n-1
сравнений - На второй:
n-2
сравнений - На третьей:
n-3
сравнений - …
- Всего:
(n-1) + (n-2) + ... + 1 = O(n²)
Количество обменов (swap) в худшем случае:
- Если массив полностью перевёрнут, на каждой итерации будет максимальное количество перестановок →
O(n²)
. Если на проходе по массиву не было перестановок, значит массив уже отсортирован.
def bubble_sort(arr):
n = len(arr)
for i in range(n):
swapped = False # Флаг, отслеживающий перестановки
for j in range(n - i - 1):
if arr[j] > arr[j + 1]: # Если элементы в неправильном порядке, меняем местами
arr[j], arr[j + 1] = arr[j + 1], arr[j]
swapped = True
if not swapped:
break # Если перестановок не было, завершаем сортировку
arr = [1, 2, 3, 4, 5] # Уже отсортированный массив
bubble_sort(arr)
print(arr) # [1, 2, 3, 4, 5]
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤2
Согласно правилу LEGB:
- Локальная (внутри текущей функции).
- Замыкающая (внутри внешней функции, если функция вложена).
- Глобальная (на уровне модуля).
- Встроенная (встроенные функции и константы вроде print, len, None).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍8❤1
В Python список (
list
) — это массив указателей. Элементы списка не хранятся внутри него, а находятся в других местах памяти, а сам список содержит ссылки (указатели) на них. Допустим, у нас есть список:
my_list = [10, "hello", 3.14, [1, 2, 3]]
+-----------------+
| Указатель → 10 | (int)
| Указатель → "hello" | (str)
| Указатель → 3.14 | (float)
| Указатель → [1, 2, 3] | (list)
+-----------------+
Мы можем увидеть размер пустого списка и списка с элементами с помощью
sys.getsizeof()
:import sys
empty_list = []
print(sys.getsizeof(empty_list)) # 56 байт (сам список)
filled_list = [10, "hello", 3.14, [1, 2, 3]]
print(sys.getsizeof(filled_list)) # 88 байт (список + 4 указателя)
Каждая ячейка списка занимает фиксированное количество памяти, равное размеру указателя (8 байт на 64-битной системе).
import ctypes
my_list = [10, "hello", 3.14, [1, 2, 3]]
for i in range(len(my_list)):
print(ctypes.cast(id(my_list[i]), ctypes.py_object).value)
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
Ключевое слово global используется для объявления переменной глобальной внутри функции. Без него любое присваивание переменной внутри функции создаёт новую локальную переменную. Если нужно изменить переменную, определённую вне функции — следует явно указать global.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14💊8
Для создания и управления виртуальными окружениями существует несколько инструментов. Вот некоторые из наиболее распространенных:
Это один из самых популярных инструментов для создания виртуальных окружений. Он позволяет создавать изолированные среды, в которых можно устанавливать и использовать зависимости для конкретных проектов.
Это встроенный инструмент для создания виртуальных окружений, доступный начиная с Python 3.3. Он предоставляет функциональность, аналогичную virtualenv, но является частью стандартной библиотеки.
Это инструмент для управления зависимостями и виртуальными окружениями. Он комбинирует возможности управления зависимостями с помощью
pip
и создания виртуальных окружений с помощью virtualenv
или venv
. Pipenv также автоматически создает и активирует виртуальное окружение для каждого проекта.Это современный инструмент для управления зависимостями и виртуальными окружениями. Он предоставляет возможности для управления зависимостями, создания виртуальных окружений, управления сценариями (scripts) и публикации пакетов. Poetry использует файл pyproject.toml для определения зависимостей и настроек проекта.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8😁2
Forwarded from easyoffer
Я боялся, что провалю собеседование. Так появился easyoffer
Когда я только начинал искать первую работу программистом, меня пугала мысль, что я просто не смогу ответить на вопросы на собеседовании.
Типа… ты потратил месяцы на то, чтобы учиться, писал pet-проекты, собирал резюме, рассылаешь отклики — и всё может закончиться на одном-единственном вопросе, на который ты не знаешь ответ.
Я реально боялся.
Я смотрел видео mock-собеседований на YouTube, останавливал каждое, выписывал вопросы в Notion. Потом вручную писал к ним ответы. И потом ещё по нескольку раз перечитывал. Такой вот "тренажёр" на коленке.
📎 (там на картинке — один из моих реальных списков в Notion, ставь 🔥 если тоже так делал)
В какой-то момент я посчитал — у меня уже было выписано больше 500 вопросов. Я почувствовал ужас.
Потому что невозможно всё это зазубрить. А что, если спросят как раз тот, к которому я не успел подготовиться?..
Тогда и пришла идея
А что если понять, какие из вопросов встречаются чаще всего? Чтобы не учить всё подряд, а сфокусироваться на главном.
Так родился easyoffer.
Сначала — просто как пет-проект, чтобы показать в резюме и подготовиться к собесам. А потом оказалось, что он реально помогает людям. За первые месяцы его посетили сотни тысяч человек. И я понял: это больше, чем просто пет-проект.
Сейчас я делаю EasyOffer 2.0
И уже не один, а вместе с вами.
В новой версии будут:
– вопросы из реальных собесов, с фильтрацией по грейду, компании, типу интервью
– тренажёр с карточками (по принципу интервальных повторений — как в Anki)
– база задач с интервью
– тренажёр «реальное собеседование», чтобы отрепетировать как в жизни
Каждая фича упрощает и сокращает время на подготовку. Все эти штуки я бы мечтал иметь, когда сам готовился к собеседованиям.
Я делаю всё на свои деньги. Никаких инвесторов. Только вы и я.
Если вы хотите помочь — сейчас самое важное время.
Краудфандинг уже стартовал. Благодаря нему я смогу привлечь больше людей для разработки, сбору и обработки собеседований.
Все, кто поддержат проект до релиза, получат:
🚀 1 год PRO-доступа по цене месячной подписки. Его можно активировать в любое время, например когда начнете готовится к собесам.
➕ Доступ к закрытому бета-тесту
Поддержать 👉 https://planeta.ru/campaigns/easyoffer
Спасибо, что верите в этот проект 🙌
Когда я только начинал искать первую работу программистом, меня пугала мысль, что я просто не смогу ответить на вопросы на собеседовании.
Типа… ты потратил месяцы на то, чтобы учиться, писал pet-проекты, собирал резюме, рассылаешь отклики — и всё может закончиться на одном-единственном вопросе, на который ты не знаешь ответ.
Я реально боялся.
Я смотрел видео mock-собеседований на YouTube, останавливал каждое, выписывал вопросы в Notion. Потом вручную писал к ним ответы. И потом ещё по нескольку раз перечитывал. Такой вот "тренажёр" на коленке.
📎 (там на картинке — один из моих реальных списков в Notion, ставь 🔥 если тоже так делал)
В какой-то момент я посчитал — у меня уже было выписано больше 500 вопросов. Я почувствовал ужас.
Потому что невозможно всё это зазубрить. А что, если спросят как раз тот, к которому я не успел подготовиться?..
Тогда и пришла идея
А что если понять, какие из вопросов встречаются чаще всего? Чтобы не учить всё подряд, а сфокусироваться на главном.
Так родился easyoffer.
Сначала — просто как пет-проект, чтобы показать в резюме и подготовиться к собесам. А потом оказалось, что он реально помогает людям. За первые месяцы его посетили сотни тысяч человек. И я понял: это больше, чем просто пет-проект.
Сейчас я делаю EasyOffer 2.0
И уже не один, а вместе с вами.
В новой версии будут:
– вопросы из реальных собесов, с фильтрацией по грейду, компании, типу интервью
– тренажёр с карточками (по принципу интервальных повторений — как в Anki)
– база задач с интервью
– тренажёр «реальное собеседование», чтобы отрепетировать как в жизни
Каждая фича упрощает и сокращает время на подготовку. Все эти штуки я бы мечтал иметь, когда сам готовился к собеседованиям.
Я делаю всё на свои деньги. Никаких инвесторов. Только вы и я.
Если вы хотите помочь — сейчас самое важное время.
Краудфандинг уже стартовал. Благодаря нему я смогу привлечь больше людей для разработки, сбору и обработки собеседований.
Все, кто поддержат проект до релиза, получат:
🚀 1 год PRO-доступа по цене месячной подписки. Его можно активировать в любое время, например когда начнете готовится к собесам.
➕ Доступ к закрытому бета-тесту
Поддержать 👉 https://planeta.ru/campaigns/easyoffer
Спасибо, что верите в этот проект 🙌
👍6
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Кэширование в 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
👍6🔥3
Ретрай (повтор запроса) возможен при:
- 429 (Too Many Requests) — если сервер просит подождать.
- 503 (Service Unavailable) — сервер временно недоступен.
- 502/504 — сбои на уровне прокси/шлюзов, возможно временные.
Ретрай не имеет смысла при ошибках клиента (например, 400 или 404).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥3💊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
👍7
2.
3.
4.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥1
Middleware (промежуточное ПО) — это специальные классы, которые обрабатывают запросы и ответы, проходящие через Django. Они позволяют изменять данные, проверять доступ, логировать действия и многое другое.
Добавляет важные HTTP-заголовки для защиты сайта:
-
Strict-Transport-Security
(HTTPS) -
X-Content-Type-Options: nosniff
-
X-Frame-Options: DENY
Отвечает за:
Перенаправление с
APPEND_SLASH=True
(если /about
→ перенаправит на /about/
). Удаление
www.
(www.example.com
→ example.com
). Обработка кодировки и контента.
Позволяет Django хранить данные пользователя между запросами (например, авторизацию).
request.session["user_id"] = 42 # Сохраняем ID пользователя в сессии
Позволяет работать с
request.user
, автоматически определяя пользователя. if request.user.is_authenticated:
print(f"Пользователь: {request.user.username}")
Защищает от атак межсайтовой подделки запросов (CSRF).
При обработке форм Django требует специальный CSRF-токен:
<form method="POST">
{% csrf_token %}
<input type="text" name="name">
</form>
Запрещает встраивать сайт в
<iframe>
, предотвращая атаку Clickjacking. X-Frame-Options: DENY
Позволяет передавать временные сообщения (
django.contrib.messages
). from django.contrib import messages
messages.success(request, "Вы успешно вошли!")
messages.error(request, "Ошибка авторизации!")
Мидлвари хранятся в
settings.py
: MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
]
Допустим, хотим логировать все запросы.
Создаём
middleware.py
import datetime
class LogMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print(f"[{datetime.datetime.now()}] Запрос: {request.path}")
response = self.get_response(request)
return response
Добавляем в
settings.py
MIDDLEWARE.append("myapp.middleware.LogMiddleware")
Теперь в консоли будем видеть все запросы!
[2024-02-28 12:00:00] Запрос: /
[2024-02-28 12:01:00] Запрос: /login/
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍2🤯1
2. Иммутабельные (immutable): данные, которые нельзя изменить после создания, например, строки (str), числа (int, float), кортежи (tuple).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10💊3