HTML5 Полная Справка

Все теги с точными визуальными примерами

Структура Документа Base

Корневые элементы, метаданные и подключение ресурсов.

CODE
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Заголовок</title>
</head>
<body>Контент</body>
</html>
🖥️ PREVIEW
🌐 Браузер
📑 Вкладка: "Заголовок"
Контент страницы
Атрибут Значения Описание
lang "ru" "en" Язык документа
charset "UTF-8" Кодировка символов
Заголовки h1-h6 Typography

Иерархия заголовков от самого важного к наименее важному.

CODE
<h1>Главный заголовок</h1>
<h2>Подзаголовок</h2>
<h3>Раздел</h3>
<h4>Подраздел</h4>
<h5>Мелкий</h5>
<h6>Минимальный</h6>
🖥️ PREVIEW

h1 Главный заголовок

h2 Подзаголовок

h3 Раздел

h4 Подраздел

h5 Мелкий
h6 Минимальный
Текст и Форматирование Typography

Параграфы, переносы строк, линии и выделение текста.

CODE
<p>Обычный текст.<br>Новая строка.</p>
<p><strong>Жирный важный</strong></p>
<p><em>Курсив акцент</em></p>
<p><mark>Выделение</mark></p>
<p><code>console.log()</code></p>
<hr>
🖥️ PREVIEW

Обычный текст.
Новая строка.

Жирный важный

Курсив акцент

Выделение

console.log()


Списки Content

Маркированные, нумерованные списки и списки определений.

CODE
<!-- Маркированный -->
<ul>
    <li>Пункт 1</li>
    <li>Пункт 2</li>
</ul>
<!-- Нумерованный -->
<ol>
    <li>Шаг 1</li>
    <li>Шаг 2</li>
</ol>
<!-- Определений -->
<dl>
    <dt>HTML</dt>
    <dd>Язык разметки</dd>
</dl>
🖥️ PREVIEW

UL (Маркированный)

  • Пункт 1
  • Пункт 2

OL (Нумерованный)

  1. Шаг 1
  2. Шаг 2

DL (Определений)

HTML
Язык разметки
CSS
Таблицы стилей
Ссылки <a> Navigation

Гиперссылки на страницы, email, телефоны и якоря.

CODE
<!-- Обычная -->
<a href="https://apple.com">Apple</a>
<!-- Новая вкладка -->
<a href="..." target="_blank">Новая</a>
<!-- Email -->
<a href="mailto:test@mail.com">Email</a>
<!-- Телефон -->
<a href="tel:+79990000000">Телефон</a>
<!-- Якорь -->
<a href="#section">Якорь</a>
Атрибут Значения Описание
href "URL" "#id" "mailto:..." URL назначения (обязательно)
target "_blank" "_self" Где открыть ссылку
download "filename" Скачать файл
Изображения <img> Media

Вставка картинок с альтернативным текстом и размерами.

CODE
<img
    src="https://via.placeholder.com/150"
    alt="Описание"
    width="150"
    height="150"
    loading="lazy"
    style="border-radius:12px;"
>
🖥️ PREVIEW Пример
Атрибут Значения Описание
src "URL" Путь к файлу (обязательно)
alt "Текст" Альтернативный текст
loading "lazy" "eager" Ленивая загрузка
width/height pixels Размеры в пикселях
Видео & YouTube Media

Вставка видео файлов и роликов с YouTube.

CODE
<!-- Свое видео -->
<video
    width="320"
    height="240"
    controls
    autoplay
    loop
    muted
    poster="thumb.jpg"
>
    <source src="movie.mp4">
</video>
<!-- YouTube -->
<iframe
    width="320"
    height="200"
    src="https://youtube.com/embed/ID"
    allowfullscreen
></iframe>
🖥️ PREVIEW
▶ ⏸ 🔊 ⚙️
YouTube Iframe
Атрибут Значения Описание
controls controls Показать кнопки плеера
autoplay autoplay Автозапуск (требует muted)
loop loop Зациклить видео
poster "image.jpg" Обложка до загрузки
Аудио <audio> Media

Вставка аудио файлов с элементами управления воспроизведением.

CODE
<!-- Аудио плеер -->
<audio
    controls
    autoplay
    loop
    muted
    preload="auto"
>
    <source src="audio.mp3" type="audio/mpeg">
    <source src="audio.ogg" type="audio/ogg">
    <source src="audio.wav" type="audio/wav">
    Ваш браузер не поддерживает аудио.
</audio>
<!-- С субтитрами -->
<audio controls>
    <source src="podcast.mp3">
    <track kind="captions" src="subs.vtt" srclang="ru">
</audio>
🖥️ PREVIEW
audio.mp3
2:34
🎵
Podcast Episode
3:45 / 45:00
Атрибут Значения Описание
controls controls Показать кнопки плеера
autoplay autoplay Автозапуск (требует muted)
loop loop Зациклить воспроизведение
muted muted Без звука
preload "auto" "metadata" "none" Предзагрузка аудио
src "URL" Путь к аудиофайлу
type "audio/mpeg" "audio/ogg" "audio/wav" MIME тип файла
Форматы Браузеры Описание
MP3 Все браузеры Наиболее совместимый формат
OGG Firefox, Chrome, Opera Открытый формат без лицензий
WAV Все браузеры Без сжатия, большой размер
AAC Safari, Chrome Формат Apple/iTunes
Таблицы <table> Data

Структурирование данных в строки и столбцы.

CODE
<table>
    <thead>
        <tr>
            <th>Имя</th>
            <th>Возраст</th>
            <th>Город</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Влад</td>
            <td>25</td>
            <td>Купертино</td>
        </tr>
        <tr>
            <td>Надя</td>
            <td>20</td>
            <td>Лос-Анджелес</td>
        </tr>
    </tbody>
</table>
🖥️ PREVIEW
Имя Возраст Город
Влад 25 Купертино
Надя 20 Лос-Анджелес
Атрибут Значения Описание
colspan number Объединить столбцы
rowspan number Объединить строки
scope "col" "row" Связь заголовка с ячейками
Формы <form> — Все типы Input

Все 22 типа полей ввода с атрибутами и визуальными примерами.

CODE
<form
    action="/submit"
    method="POST"
    enctype="multipart/form-data"
    autocomplete="on"
    novalidate
>
    <!-- Текстовые поля -->
    <input type="text" name="username" placeholder="Имя" required>
    <input type="email" name="email" placeholder="Email">
    <input type="password" name="pass" minlength="6">
    <input type="tel" name="phone" pattern="[0-9]{10}">
    <input type="url" name="website">
    <input type="search" name="query">
    <!-- Числовые поля -->
    <input type="number" name="age" min="0" max="100">
    <input type="range" name="volume" min="0" max="100">
    <!-- Дата и время -->
    <input type="date" name="birthdate">
    <input type="time" name="meeting">
    <input type="datetime-local" name="event">
    <input type="month" name="billing">
    <input type="week" name="delivery">
    <!-- Выбор -->
    <input type="color" name="favorite">
    <input type="file" name="document" accept=".pdf,.doc">
    <input type="checkbox" name="subscribe">
    <input type="radio" name="gender" value="male">
    <!-- Скрытые и кнопки -->
    <input type="hidden" name="token" value="abc123">
    <input type="submit" value="Отправить">
    <input type="reset" value="Сброс">
    <input type="button" value="Кнопка">
    <input type="image" src="submit.png">
    <!-- Другие элементы -->
    <select name="city">
        <option value="msk">Москва</option>
    </select>
    <textarea name="message" rows="4"></textarea>
    <button type="submit">Отправить</button>
    <datalist id="browsers">
        <option value="Chrome">
    </datalist>
    <output name="result">0</output>
    <progress value="70" max="100"></progress>
    <meter value="0.6" min="0" max="1"></meter>
    <fieldset>
        <legend>Группа полей</legend>
    </fieldset>
</form>
🖥️ PREVIEW
0
Fieldset + Legend
Атрибут Значения Описание
action "URL" URL для отправки данных
method "GET" "POST" "PUT" "DELETE" HTTP метод отправки
enctype "application/x-www-form-urlencoded" "multipart/form-data" Тип кодирования данных
autocomplete "on" "off" Автозаполнение полей
novalidate novalidate Отключить валидацию формы
target "_self" "_blank" Где открыть ответ
type Описание
text Текстовое поле (однострочное)
email Email с валидацией формата
password Пароль (символы скрыты)
tel Номер телефона
url URL с валидацией
search Поле поиска
number Числовое поле (min, max, step)
range Ползунок (слайдер)
date Выбор даты
time Выбор времени
datetime-local Дата и время
month Выбор месяца
week Выбор недели
color Выбор цвета
file Загрузка файла
checkbox Флажок (множественный выбор)
radio Переключатель (один из многих)
hidden Скрытое поле (не видно пользователю)
submit Кнопка отправки формы
reset Кнопка сброса формы
button Обычная кнопка (для JS)
image Кнопка-изображение
Семантика HTML5 Structure

Логическая структура страницы для SEO и доступности.

CODE
<header>Шапка сайта</header>
<nav>Меню навигации</nav>
<main>
    <article>
        <section>Раздел статьи</section>
    </article>
    <aside>Боковая панель</aside>
</main>
<footer>Подвал сайта</footer>
🖥️ PREVIEW
🏁 HEADER
🧭 NAV
📄 MAIN (Article + Section)
📌 ASIDE
🔚 FOOTER
Интерактив Interactive

Раскрывающиеся блоки и модальные окна без JavaScript.

CODE
<!-- Аккордеон -->
<details open>
    <summary>Нажмите чтобы раскрыть</summary>
    <p>Скрытый контент здесь...</p>
</details>
<!-- Диалоговое окно -->
<dialog open>
    <p>Пример встроенного диалога HTML5</p>
</dialog>
🖥️ PREVIEW
📌 Нажмите чтобы раскрыть
✅ Скрытый контент теперь виден! Это работает без JavaScript.
Нативный <dialog> (поддержка зависит от браузера)
Дополнительная Семантика Structure

Фигуры, цитаты, время, адреса и другие семантические элементы.

CODE
<!-- Фигура с подписью -->
<figure>
    <img src="photo.jpg" alt="Фото">
    <figcaption>Подпись к фото</figcaption>
</figure>
<!-- Цитаты -->
<blockquote cite="url">Цитата</blockquote>
<q>Короткая цитата</q>
<!-- Время и адрес -->
<time datetime="2024-01-01">1 января</time>
<address>Контакты автора</address>
<!-- Код и преформатирование -->
<pre>Сохраняет пробелы</pre>
<kbd>Ctrl+C</kbd>
<samp>Вывод программы</samp>
🖥️ PREVIEW
IMG
Подпись к фото
"Цитата с blockquote"
🕐 ⌨️ Ctrl+C 📍
Москва
Встраивание Контента Media

Встраивание внешнего контента, карт и объектов.

CODE
<!-- Iframe -->
<iframe
    src="https://example.com"
    width="600"
    height="400"
    title="Описание"
    loading="lazy"
    sandbox="allow-scripts"
></iframe>
<!-- Карта изображения -->
<img src="map.png" usemap="#map">
<map name="map">
    <area shape="rect" coords="0,0,100,100">
</map>
<!-- Canvas -->
<canvas id="myCanvas" width="200" height="100"></canvas>
<!-- SVG -->
<svg width="100" height="100">
    <circle cx="50" cy="50" r="40"/>
</svg>
🖥️ PREVIEW
🖼️ Iframe Placeholder
SVG Circle
Canvas
...
Атрибут Значения Описание
sandbox "allow-scripts" "allow-same-origin" Ограничения для iframe
loading "lazy" "eager" Ленивая загрузка
shape "rect" "circle" "poly" Форма области карты
SEO & Meta теги SEO

Ключевые метатеги для SEO, соцсетей и правильного отображения сайта.

CODE
<head>
    <title>Заголовок страницы</title>
    <meta name="description" content="Краткое описание страницы">
    <meta name="keywords" content="html, css, js, python">
    <meta name="robots" content="index,follow">
    <!-- Open Graph -->
    <meta property="og:title" content="Заголовок для соцсетей">
    <meta property="og:description" content="Описание для соцсетей">
    <meta property="og:image" content="https://site.com/preview.png">
    <!-- Canonical URL -->
    <link rel="canonical" href="https://site.com/page">
</head>
🖥️ PREVIEW
Заголовок страницы — site.com
https://site.com/page
Краткое описание страницы…
Заголовок для соцсетей
Описание для соцсетей
Canvas для рисования Graphics

HTML5 элемент для программного рисования графики, анимаций и игр.

HTML + JS
<canvas id="myCanvas" width="200" height="100"></canvas>

const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// Рисуем прямоугольник
ctx.fillStyle = '#0071e3';
ctx.fillRect(10, 10, 50, 50);

// Рисуем круг
ctx.beginPath();
ctx.arc(100, 50, 30, 0, 2 * Math.PI);
ctx.fill();
🖥️ PREVIEW
Метод Описание
fillRect(x,y,w,h) Заливка прямоугольника
arc(x,y,r,start,end) Рисование дуги/круга
getContext('2d') Получение 2D контекста
Адаптивные изображения Responsive

Picture, srcset и lazy loading для мобильной, планшетной и десктопной графики.

HTML
<picture>
    <source srcset="img-small.jpg 480w, img-medium.jpg 768w, img-large.jpg 1200w" sizes="(max-width: 600px) 100vw, 50vw" type="image/jpeg">
    <img src="img-large.jpg" alt="Адаптивное изображение" loading="lazy" decoding="async" width="1200" height="800">
</picture>
🖥️ PREVIEW
Responsive preview
srcset: разные размеры для разных экранов
loading: lazy для экономии трафика
Атрибут Значения Описание
srcset "url 480w" "url 2x" Набор изображений для разных размеров/плотностей
sizes "100vw" "50vw" Ширина изображения в макете
loading lazy eager Отложенная загрузка
decoding async sync Асинхронная декодировка изображения

CSS3 Справочник

Все свойства с точными визуальными примерами

Селекторы Basics
CSS
element { } /* По тегу */
.class { } /* По классу */
#id { } /* По ID */
:hover { } /* При наведении */
::before { content: "★"; }
[attr] { } /* По атрибуту */
:nth-child(n) { }
:first-child { }
:last-child { }
:not(.class) { }
::after { }
:focus { }
:active { }
:disabled { }
:checked { }
:empty { }
:target { }
::first-letter { }
::first-line { }
::selection { }
:is(.btn, a) { } /* Современная группировка */
:where(.card .title) { } /* Без влияния специфичности */
:has(img) { } /* Родитель, содержащий img (поддержка зависит от браузера) */
🖥️ PREVIEW element .class #id :hover ::before ★ [attr] :nth-child :focus
Тип Пример Описание
Универсальный * Все элементы
Дочерний parent > child Прямые потомки
Потомок ancestor descendant Все потомки
Сосед elem + elem Следующий сосед
Общий сосед elem ~ elem Все следующие соседи
Современные :is() :where() :has() Гибкая работа со сложными селекторами
Box Model Layout
CSS
.box {
    width: 200px;
    height: 100px;
    padding: 20px;
    margin: 10px;
    border: 3px solid #0071e3;
    border-radius: 12px;
    box-sizing: border-box;
}
🖥️ PREVIEW
margin
10px
padding
20px
Content
200×100px
Свойство Значения Описание
box-sizing content-box border-box Модель расчета размеров
display block inline inline-block Тип отображения
visibility visible hidden Видимость элемента
overflow auto scroll hidden Обработка переполнения
Flexbox Layout
CSS
.container {
    display: flex;
    flex-direction: row; /* row, column */
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 16px;
}
.item {
    flex: 1;
    order: 0;
    align-self: stretch;
}
🖥️ PREVIEW
1
2
3
justify-content: center | align-items: center | gap: 16px
Свойство Значения Описание
flex-direction row column row-reverse Направление оси
justify-content flex-start center space-between Выравнивание по главной оси
align-items stretch center baseline Выравнивание по поперечной оси
flex-wrap nowrap wrap Перенос элементов
Grid Layout
CSS
.grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: auto;
    gap: 12px;
    grid-auto-flow: dense;
}
.item {
    grid-column: 1 / 3;
    grid-row: 1;
}
🖥️ PREVIEW
1fr
1fr
1fr
grid-template-columns: 1fr 1fr 1fr | gap: 12px
Свойство Значения Описание
grid-template-columns 1fr 1fr repeat(3, 1fr) Колонки сетки
grid-template-rows auto 100px Строки сетки
grid-column 1 / 3 span 2 Объединение колонок
grid-row 1 1 / 3 Объединение строк
Typography Text
CSS
.text {
    font-size: 16px;
    font-weight: 700;
    font-family: sans-serif;
    color: var(--accent);
    text-align: center;
    text-decoration: underline;
    text-transform: uppercase;
    letter-spacing: 1px;
    line-height: 1.5;
    text-shadow: 1px 1px 2px rgba(0,0,0,0.2);
}
🖥️ PREVIEW

font-size: 14px

font-weight: 600

color: var(--accent)

font-style: italic

text-transform: uppercase

Background & Effects Visual
CSS
.box {
    background: linear-gradient(135deg, #0071e3, #bf5af2);
    background-size: cover;
    background-position: center;
    border-radius: 16px;
    box-shadow: 0 8px 24px rgba(0,113,227,0.3);
    transform: rotate(-3deg);
    opacity: 0.9;
    filter: blur(0px);
}
🖥️ PREVIEW
Gradient
border-radius
box-shadow
transform
Свойство Значения Описание
background color url() gradient Фон элемента
transform rotate() scale() translate() Трансформация
filter blur() grayscale() brightness() Визуальные фильтры
opacity 0 - 1 Прозрачность
Position Layout
CSS
.relative { position: relative; }
.absolute { position: absolute; top: 10px; }
.fixed { position: fixed; bottom: 0; }
.sticky { position: sticky; top: 0; }
.static { position: static; }
🖥️ PREVIEW
absolute
fixed
relative center
Значение Описание
static Позиция по умолчанию
relative Относительно своего места
absolute Относительно родителя с position
fixed Относительно окна браузера
sticky Липкое позиционирование
Анимации и Транзиции Animation
CSS
@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}
.box {
    animation: fadeIn 1s ease-in-out;
    animation-delay: 0.5s;
    animation-iteration-count: infinite;
    transition: all 0.3s ease;
}
🖥️ PREVIEW
Pulse
Hover
Spin
Свойство Значения Описание
animation name duration timing Настройка анимации
@keyframes from/to 0%-100% Ключевые кадры
transition property duration Плавный переход
transform rotate scale translate Изменение формы
Media Queries Responsive
CSS
/* Мобильные */
@media (max-width: 600px) { ... }
/* Планшеты */
@media (min-width: 601px) and (max-width: 1024px) { ... }
/* Десктоп */
@media (min-width: 1025px) { ... }
/* Темная тема */
@media (prefers-color-scheme: dark) { ... }
/* Печать */
@media print { ... }
/* Ориентация */
@media (orientation: landscape) { ... }
🖥️ PREVIEW
📱
max-width: 600px
📟
601-1024px
💻
min-width: 1025px
🌙
prefers-color-scheme: dark
🖨️
print
🔄
orientation
CSS Переменные и Функции Advanced
CSS
:root {
    --primary: #0071e3;
    --spacing: 16px;
}
.box {
    color: var(--primary);
    padding: var(--spacing);
    width: calc(100% - 40px);
    background: linear-gradient(to right, red, blue);
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}
🖥️ PREVIEW
CSS Variables
--primary: #0071e3
calc()
100% - 40px
gradient()
Linear Gradient
Функция Описание
var() Использование CSS переменной
calc() Математические вычисления
linear-gradient() Линейный градиент
radial-gradient() Радиальный градиент
rgb()/rgba() Цвет с прозрачностью
hsl()/hsla() Цвет в формате HSL
Переменные и @media Advanced

CSS-переменные в :root и адаптивность через @media.

CSS
:root {
    --primary: #0071e3;
    --radius: 12px;
}
.card {
    background: var(--bg-card);
    border-radius: var(--radius);
}
/* Адаптивность */
@media (max-width: 768px) {
    .grid {
        grid-template-columns: 1fr;
        gap: 16px;
    }
    header {
        position: sticky;
        top: 0;
    }
}
🖥️ PREVIEW
Desktop
Mobile @media
Анимация, Transition и Transform Motion

Плавные переходы, 2D‑трансформации и ключевые кадры.

CSS
.btn {
    background: #0071e3;
    color: #fff;
    padding: 10px 18px;
    border-radius: 999px;
    transition: transform .2s ease, box-shadow .2s ease;
}
.btn:hover {
    transform: translateY(-2px) scale(1.02);
    box-shadow: 0 8px 20px rgba(0,0,0,.25);
}
@keyframes pulse {
    0%   { transform: scale(1); }
    50%  { transform: scale(1.05); opacity: .85; }
    100% { transform: scale(1); }
}
.badge-anim {
    animation: pulse 1.5s infinite;
}
🖥️ PREVIEW
transform + transition
pulse animation
CSS Grid Advanced Grid

Продвинутые возможности CSS Grid: именованные области, адаптивные сетки.

CSS
.container {
    display: grid;
    grid-template-areas:
        "header header header"
        "sidebar main main"
        "sidebar footer footer";
    grid-template-columns: 200px 1fr 1fr;
    grid-template-rows: auto 1fr auto;
    gap: 20px;
}

.header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
.main   { grid-area: main; }
.footer { grid-area: footer; }

/* Адаптивная сетка */
.responsive-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 20px;
}
🖥️ PREVIEW
grid-template-areas позволяет создавать семантические макеты без лишних классов.
Комментарий: auto-fit minmax создает адаптивные колонки без медиа-запросов.
Свойство Описание
grid-template-areas Определяет именованные области сетки
grid-area Присваивает элемент к именованной области
auto-fit Автоматически подстраивает количество колонок
Современные CSS инструменты Modern

aspect-ratio, clamp(), min(), max() и @supports для гибких макетов.

CSS
:root {
    --card-width: clamp(260px, 35vw, 420px);
    --card-radius: 18px;
}

.card {
    width: var(--card-width);
    aspect-ratio: 4 / 3;
    padding: 24px;
    border-radius: var(--card-radius);
    background: #fff;
    box-shadow: 0 14px 28px rgba(0,0,0,0.08);
}

.text {
    font-size: clamp(14px, 1.2vw, 18px);
    margin: max(16px, 2vw);
}

/* Проверка поддержки */
@supports (aspect-ratio: 1 / 1) {
    .card {
        border: 1px solid #dce0e8;
    }
}
🖥️ PREVIEW
aspect-ratio 4/3
Функция Описание
aspect-ratio Фиксирует соотношение ширины и высоты
clamp() Ограничивает значение между min и max
min() / max() Выбирает минимальное или максимальное значение
@supports Условная стилизация по поддержке браузера

JavaScript Справочник

Синтаксис, DOM, События, Асинхронность

Переменные и Типы Данных Base
JS
"use strict"; // Строгий режим
let name = "Alex"; // String
const age = 25; // Number
var old = "Legacy";
let arr = [1, 2, 3]; // Array
let obj = { key: "val" }; // Object
let isTrue = true; // Boolean
let nothing = null; // Null
let undef = undefined; // Undefined
let big = 123n; // BigInt
let sym = Symbol("id"); // Symbol
🖥️ CONSOLE
typeof name = "string"
typeof age = "number"
typeof isTrue = "boolean"
typeof arr = "object"
typeof null = "object"
Тип Описание
string Строка текста
number Число (целое или дробное)
boolean true или false
null Пустое значение
undefined Не определено
object Объект или массив
symbol Уникальный идентификатор
bigint Большие целые числа
Функции Base
JS
// Обычная функция
function sum(a, b) {
    return a + b;
}
// Стрелочная функция
const mult = (a, b) => a * b;
// С параметрами по умолчанию
function greet(name = "Guest") {
    return `Hello, ${name}!`;
}
// Замыкание
function counter() {
    let count = 0;
    return () => count++;
}
sum(2, 3); // 5
greet(); // Hello, Guest!
🖥️ OUTPUT
function sum(a, b) { return a + b; }
sum(2, 3) = 5
greet() = "Hello, Guest!"
Методы Массивов Array
JS
const arr = [1, 2, 3, 4, 5];
// forEach - перебор
arr.forEach((item) => console.log(item));
// map - преобразование
const doubled = arr.map(x => x * 2);
// filter - фильтрация
const evens = arr.filter(x => x % 2 === 0);
// reduce - свертка
const total = arr.reduce((sum, x) => sum + x, 0);
// find - поиск элемента
const found = arr.find(x => x > 3);
// some/every - проверка
const hasEven = arr.some(x => x % 2 === 0);
const allPositive = arr.every(x => x > 0);
// sort - сортировка
arr.sort((a, b) => a - b);
// slice/splice - вырезка/изменение
const part = arr.slice(0, 3);
arr.splice(1, 1, 99);
// push/pop/shift/unshift
arr.push(6); arr.pop();
arr.unshift(0); arr.shift();
// flat / flatMap - работа с вложенностями
const nested = [[1], [2, 3]];
const flat = nested.flat();          // [1,2,3]
const flatMapped = arr.flatMap(x => [x, x * 2]);
🖥️ OUTPUT
map: [2, 4, 6, 8, 10]
filter: [2, 4]
reduce: 15
find: 4
Метод Возвращает Описание
forEach undefined Выполняет функцию для каждого
map new array Преобразует каждый элемент
filter new array Фильтрует по условию
reduce accumulator Сворачивает в одно значение
find element Находит первый подходящий
some boolean Проверяет наличие хотя бы одного
every boolean Проверяет все элементы
flat / flatMap new array Разворачивает и/или трансформирует вложенные массивы
Методы Строк String
JS
const str = "Hello, World!";
// Длина
str.length; // 13
// Регистр
str.toUpperCase(); // HELLO, WORLD!
str.toLowerCase(); // hello, world!
// Поиск
str.indexOf("World"); // 7
str.includes("Hello"); // true
str.startsWith("Hello"); // true
str.endsWith("!"); // true
// Извлечение
str.slice(0, 5); // Hello
str.substring(0, 5);
str.substr(0, 5);
// Замена
str.replace("World", "JS");
str.replaceAll("l", "L");
// Разделение
str.split(", "); // ["Hello", "World!"]
// Обрезка
"  text  ".trim(); // "text"
str.padStart(20, "0");
str.repeat(3);
🖥️ OUTPUT
toUpperCase: "HELLO, WORLD!"
slice(0,5): "Hello"
split: ["Hello", "World!"]
trim: "text"
Числа и Математика Number
JS
// Math объект
Math.round(4.7); // 5
Math.floor(4.7); // 4
Math.ceil(4.2); // 5
Math.random(); // 0-1
Math.pow(2, 3); // 8
Math.sqrt(16); // 4
Math.abs(-5); // 5
Math.max(1, 5, 3); // 5
Math.min(1, 5, 3); // 1
// Number методы
Number.parseInt("42px"); // 42
Number.parseFloat("3.14"); // 3.14
Number.isNaN(NaN); // true
Number.isFinite(10); // true
// Форматирование
(1234.567).toFixed(2); // "1234.57"
(1234).toLocaleString(); // "1,234"
🖥️ OUTPUT
Math.round(4.7) = 5
Math.random() = 0.123...
(1234.567).toFixed(2) = "1234.57"
Объекты Object
JS
const obj = {
    name: "Alice",
    age: 25,
    city: "Moscow"
};
// Доступ
obj.name; // "Alice"
obj["age"]; // 25
// Деструктуризация
const { name, age } = obj;
// Spread/Rest
const copy = { ...obj };
const merged = { ...obj, country: "RU" };
function sum(...args) { }
// Методы объекта
Object.keys(obj); // ["name", "age", "city"]
Object.values(obj); // ["Alice", 25, "Moscow"]
Object.entries(obj); // [["name", "Alice"], ...]
Object.assign({}, obj); // Копия
Object.freeze(obj); // Заморозка
Object.fromEntries([ ["a", 1], ["b", 2] ]); // Обратное к entries
🖥️ OUTPUT
Object.keys: ["name", "age", "city"]
Destructuring: name="Alice", age=25
Spread: { ...obj, country: "RU" }
Классы OOP

Современный синтаксис классов, наследование и статические методы.

JS
class User {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    get info() {
        return `${this.name}, ${this.age} years`;
    }

    set nickname(value) {
        this.name = value;
    }

    static createGuest() {
        return new User("Guest", 18);
    }
}

class Admin extends User {
    constructor(name, age, role) {
        super(name, age);
        this.role = role;
    }

    get details() {
        return `${this.info} - ${this.role}`;
    }
}

const user = new Admin("Ivan", 30, "admin");
user.nickname = "Ivanov";
user.details;
🖥️ OUTPUT
Admin: Ivanov, 30 years - admin
static createGuest() → Guest, 18 years
Ключ Описание
constructor Инициализация нового объекта
extends Наследование от базового класса
super Вызов конструктора родителя
static Метод, доступный на самом классе
get / set Свойства для чтения и записи
DOM Web
JS
// Поиск элементов
document.getElementById("main");
document.querySelector(".class");
document.querySelectorAll("div");
document.getElementsByClassName("item");
// Создание
const el = document.createElement("div");
el.textContent = "Новый текст";
el.innerHTML = "<b>HTML</b>";
// Атрибуты
el.setAttribute("data-id", "123");
el.getAttribute("data-id");
el.removeAttribute("data-id");
// Классы
el.classList.add("active");
el.classList.remove("hidden");
el.classList.toggle("visible");
// Вставка/Удаление
parent.appendChild(el);
parent.insertBefore(el, ref);
parent.removeChild(el);
el.remove();
🖥️ RESULT
До:
<div id="main">Старый текст</div>
После:
<div id="main" class="active">Новый текст</div>
События Interact
JS
// Добавление слушателя
btn.addEventListener("click", (e) => {
    e.preventDefault();
    console.log("Click!");
});
// Удаление
btn.removeEventListener("click", handler);
// Типы событий
// Мышь: click, dblclick, mousedown, mouseup
//        mouseover, mouseout, mousemove
// Клавиатура: keydown, keyup, keypress
// Форма: submit, change, input, focus, blur
// Документ: DOMContentLoaded, load, scroll
// Drag-n-Drop: dragstart, drag, drop
// Всплытие и погружение
element.addEventListener("click", handler, true);
🖥️ EVENTS
mouseover
Промисы и Асинхронность Async
JS
// Promise
const promise = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Успех!");
        // reject("Ошибка!");
    }, 1000);
});
promise
    .then(data => console.log(data))
    .catch(err => console.error(err))
    .finally(() => console.log("Завершено"));
// Async/Await
async function fetchData() {
    try {
        const response = await fetch("/api/data");
        const data = await response.json();
        return data;
    } catch (error) {
        console.error(error);
    }
}
// Fetch API
fetch("https://api.example.com/data")
    .then(res => res.json())
    .then(data => console.log(data));
🖥️ OUTPUT
Promise resolved: "Успех!"
async/await: ожидание fetch...
finally: Завершено
Состояние Описание
pending Ожидание
fulfilled Успешно завершено
rejected Ошибка выполнения
Обработка Ошибок Error
JS
// try/catch/finally
try {
    const result = riskyOperation();
    if (!result) {
        throw new Error("Что-то пошло не так");
    }
} catch (error) {
    console.error(error.message);
} finally {
    console.log("Всегда выполняется");
}
// Типы ошибок
throw new Error("Базовая ошибка");
throw new TypeError("Неверный тип");
throw new ReferenceError("Переменная не найдена");
throw new SyntaxError("Ошибка синтаксиса");
// Своя ошибка
class CustomError extends Error {
    constructor(message) {
        super(message);
        this.name = "CustomError";
    }
}
🖥️ OUTPUT
Error: Что-то пошло не так
finally: Всегда выполняется
Async/Await & Fetch API Async

Асинхронное программирование и HTTP-запросы в современном JavaScript.

JAVASCRIPT
// async function: объявляет функцию, которая может использовать await и ВСЕГДА возвращает Promise
async function fetchUserData(userId) {
    // try: блок для кода, который может выбросить исключение
    try {
        // await: ОСТАНАВЛИВАЕТ выполнение, пока fetch не вернёт ответ (без блокировки остального потока)
        const response = await fetch(`https://api.example.com/users/${userId}`);
        // response.ok: проверяем что статус 2xx (200-299), иначе ошибка на сервере
        if (!response.ok) {
            // throw выбросит ошибку, которую поймает catch блок ниже
            throw new Error(`HTTP error! status: ${response.status}`);
        }
        // response.json(): парсит тело ответа как JSON, возвращает Promise
        const userData = await response.json();
        return userData;
    } // catch: ловит ошибки из try (либо сетевые, либо выброшенные нами через throw)
    catch (error) {
        console.error('Ошибка загрузки:', error);
        throw error;
    }
}

// Использование async функции: вызов должен быть внутри async функции или использовать .catch()
async function loadUser() {
    try {
        // await: ждём результата fetchUserData (функция вернёт Promise, await распаковывает значение)
        const user = await fetchUserData(123);
        console.log('Пользователь:', user);
    } catch (error) {
        console.error('Не удалось загрузить пользователя');
    }
}

// Fetch с опциями: POST запрос с headers и body
const postData = await fetch('/api/posts', {
    method: 'POST',  // HTTP метод (по умолчанию GET)
    headers: {
        'Content-Type': 'application/json'  // сервер, содержимое - JSON
    },
    body: JSON.stringify({ title: 'Новый пост', content: 'Текст' })  // конвертируем объект в JSON строку
});
🖥️ PREVIEW
async/await делает асинхронный код читаемым, как синхронный.
Комментарий: Fetch API заменил XMLHttpRequest для HTTP-запросов.
Метод Описание
async function Объявляет асинхронную функцию
await Ждет выполнения Promise
fetch() Выполняет HTTP-запрос

Python Полная Справка

Синтаксис, ООП, методы, структуры данных

Базовый синтаксис Base
PYTHON
# Переменные
name = "Alice"
age = 25
height = 1.75
is_student = True
# Вывод
print(f"Привет, {name}!")
print(f"Возраст: {age}")
# Ввод
user_input = input("Введите имя: ")
# Типы данных
type(name)  # <class 'str'>
type(age)   # <class 'int'>
type(height) # <class 'float'>
type(is_student) # <class 'bool'>
# None
nothing = None
🖥️ OUTPUT
Привет, Alice!
Возраст: 25
<class 'str'>
<class 'int'>
Тип Пример Описание
int 42 Целое число
float 3.14 Число с плавающей точкой
str "text" Строка
bool True/False Булево значение
None None Пустое значение
complex 3+4j Комплексное число
bytes b"data" Байтовая строка
Структуры данных Data
PYTHON
# Список (List)
fruits = ["apple", "banana", "cherry"]
fruits.append("orange")
fruits.extend(["grape"])
fruits.insert(0, "mango")
fruits.remove("banana")
fruits.pop()  # Удаляет последний
fruits.pop(0)  # Удаляет по индексу
fruits.index("apple")
fruits.count("apple")
fruits.sort()
fruits.reverse()
fruits.copy()
print(fruits[0])  # apple
print(fruits[-1]) # Последний
print(fruits[1:3]) # Срез
# Кортеж (Tuple)
coordinates = (10, 20)
x, y = coordinates
# Словарь (Dict)
person = {
    "name": "Alice",
    "age": 25,
    "city": "Moscow"
}
person.keys()
person.values()
person.items()
person.get("name", "Default")
person.update({"country": "RU"})
person.pop("age")
print(person["name"])  # Alice
# Множество (Set)
unique_nums = {1, 2, 3, 3, 2}  # {1, 2, 3}
unique_nums.add(4)
unique_nums.remove(1)
unique_nums.discard(5) # Без ошибки
unique_nums.union({5, 6})
unique_nums.intersection({2, 3})
unique_nums.difference({3})
Структура Изменяемая Синтаксис
list ✅ Да [1, 2, 3]
tuple ❌ Нет (1, 2, 3)
dict ✅ Да {"key": "value"}
set ✅ Да {1, 2, 3}
frozenset ❌ Нет frozenset([1,2,3])
Метод списка Описание
append() Добавить элемент в конец
extend() Добавить несколько элементов
insert() Вставить по индексу
remove() Удалить по значению
pop() Удалить и вернуть элемент
index() Найти индекс элемента
count() Посчитать вхождения
sort() Отсортировать
reverse() Развернуть список
copy() Создать копию
Метод словаря Описание
keys() Все ключи
values() Все значения
items() Пары ключ-значение
get() Получить значение (без ошибки)
update() Обновить словарь
pop() Удалить и вернуть значение
clear() Очистить словарь
Управляющие конструкции Flow
PYTHON
# if-elif-else
age = 18
if age < 13:
    print("Ребенок")
elif age < 18:
    print("Подросток")
else:
    print("Взрослый")
# for цикл
for i in range(5):
    print(i)  # 0, 1, 2, 3, 4
for i, val in enumerate(fruits):
    print(i, val)
# while цикл
count = 0
while count < 5:
    print(count)
    count += 1
# break/continue/pass
for i in range(10):
    if i == 5:
        break
    if i % 2 == 0:
        continue
    pass  # Пустая операция
# List comprehension
squares = [x**2 for x in range(10)]
evens = [x for x in range(10) if x % 2 == 0]
# Dict comprehension
squares_dict = {x: x**2 for x in range(5)}
🖥️ OUTPUT
range(5): 0, 1, 2, 3, 4
squares: [0, 1, 4, 9, 16, ...]
evens: [0, 2, 4, 6, 8]
Функции и методы Functions
PYTHON
# Обычная функция
def greet(name):
    return f"Hello, {name}!"
# Функция с параметрами по умолчанию
def power(base, exp=2):
    return base ** exp
# Lambda функция
add = lambda x, y: x + y
# *args и **kwargs
def sum_all(*args):
    return sum(args)
def print_info(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")
# Аннотации типов
def add(a: int, b: int) -> int:
    return a + b
print(greet("Alice"))  # Hello, Alice!
print(power(2, 3))     # 8
print(add(5, 3))        # 8
print(sum_all(1, 2, 3))  # 6
Параметр Описание
*args Произвольное число позиционных
**kwargs Произвольное число именованных
default Параметр по умолчанию
: type Аннотация типа параметра
-> type Аннотация типа возврата
JSON и HTTP‑запросы Web
PYTHON
import json
import requests  # pip install requests

# Словарь → JSON‑строка
data = {"name": "Alice", "age": 25}
json_str = json.dumps(data, ensure_ascii=False, indent=2)

# JSON‑строка → словарь
parsed = json.loads(json_str)

# Простой GET‑запрос
resp = requests.get("https://api.example.com/user/1", timeout=5)
if resp.status_code == 200:
    user = resp.json()
    print(user["name"])

# POST с JSON‑телом
payload = {"title": "Hello", "body": "World"}
resp = requests.post("https://api.example.com/posts", json=payload, timeout=5)
print(resp.status_code)
🖥️ OUTPUT
json.dumps → { "name": "Alice", "age": 25 }
GET /user/1 → 200 OK, user["name"] = "Alice"
POST /posts → 201 Created
Классы и ООП OOP
PYTHON
class Person:
    # Конструктор
    def __init__(self, name, age):
        self.name = name
        self.age = age
    # Метод экземпляра
    def greet(self):
        return f"Hi, I'm {self.name}"
    # Метод класса
    @classmethod
    def from_birth_year(cls, name, year):
        age = 2024 - year
        return cls(name, age)
    # Статический метод
    @staticmethod
    def is_adult(age):
        return age >= 18
    # Строковое представление
    def __str__(self):
        return f"{self.name}, {self.age} лет"
    # Свойство через @property
    @property
    def info(self):
        return f"{self.name} ({self.age})"
# Создание объекта
person = Person("Alice", 25)
print(person.greet())  # Hi, I'm Alice
print(person)          # Alice, 25 лет
print(person.info)     # Alice (25)
Метод Описание
__init__ Конструктор класса
__str__ Строковое представление
__repr__ Официальное представление
@classmethod Метод класса (cls)
@staticmethod Статический метод
@property Геттер свойства
@abstractmethod Абстрактный метод
Наследование OOP
PYTHON
class Animal:
    def __init__(self, name):
        self.name = name
    def speak(self):
        pass
class Dog(Animal):
    def speak(self):
        return f"{self.name} говорит: Гав!"
class Cat(Animal):
    def speak(self):
        return f"{self.name} говорит: Мяу!"
# Множественное наследование
class FlyingDog(Dog, Animal):
    pass
# Проверка типа
isinstance(dog, Animal)  # True
issubclass(Dog, Animal)  # True
dog = Dog("Бобик")
cat = Cat("Мурка")
print(dog.speak())  # Бобик говорит: Гав!
print(cat.speak())  # Мурка говорит: Мяу!
Работа с файлами IO
PYTHON
# Чтение файла
with open("file.txt", "r", encoding="utf-8") as f:
    content = f.read()
    lines = f.readlines()
    line = f.readline()
# Запись в файл
with open("file.txt", "w", encoding="utf-8") as f:
    f.write("Hello, World!")
    f.writelines(["Line 1\n", "Line 2\n"])
# Добавление
with open("file.txt", "a") as f:
    f.write("\nNew line")
# Режимы открытия
# "r" - чтение (по умолчанию)
# "w" - запись (перезаписывает)
# "a" - добавление в конец
# "r+" - чтение и запись
# "b" - бинарный режим
# "x" - создание (ошибка если существует)
# Работа с путем
import os
os.path.exists("file.txt")
os.path.isfile("file.txt")
os.path.isdir("folder")
os.remove("file.txt")
os.mkdir("folder")
Режим Описание
r Чтение (файл должен существовать)
w Запись (создает или перезаписывает)
a Добавление в конец
r+ Чтение и запись
b Бинарный режим
x Создание нового файла
Обработка исключений Error
PYTHON
try:
    result = 10 / 0
except ZeroDivisionError as e:
    print(f"Ошибка: {e}")
except Exception as e:
    print(f"Другая ошибка: {e}")
else:
    print("Все хорошо")
finally:
    print("Всегда выполняется")
# Вызов исключения
raise ValueError("Неверное значение")
# Создание своего исключения
class MyError(Exception):
    pass
# Контекстный менеджер
with open("file.txt") as f:
    content = f.read()
# assert
assert x > 0, "x должен быть положительным"
Исключение Описание
ValueError Неверное значение
TypeError Неверный тип
KeyError Ключ не найден в словаре
IndexError Индекс вне диапазона
FileNotFoundError Файл не найден
ZeroDivisionError Деление на ноль
ImportError Ошибка импорта
AttributeError Атрибут не найден
Модули и импорты Modules
PYTHON
# Импорт модуля
import math
print(math.sqrt(16))  # 4.0
# Импорт конкретных функций
from datetime import datetime, date
# Импорт с алиасом
import numpy as np
# Импорт всего
from module import *
# Собственный модуль
from mymodule import my_function
# Установка пакетов
# pip install package_name
# pip install -r requirements.txt
# Популярные модули
import os      # Операционная система
import sys     # Системные параметры
import json    # Работа с JSON
import re      # Регулярные выражения
import random  # Случайные числа
import time    # Время и задержки
import pathlib # Пути к файлам
Модуль Описание
os Операционная система
sys Системные параметры
json Работа с JSON
re Регулярные выражения
datetime Дата и время
random Случайные числа
math Математические функции
collections Доп. структуры данных
itertools Итераторы
functools Функции высшего порядка
Методы Строк String
PYTHON
text = "  Hello, World!  "
# Регистр
text.upper()        # HELLO, WORLD!
text.lower()        # hello, world!
text.capitalize()   # Hello, world!
text.title()        # Hello, World!
text.swapcase()     # hELLO, wORLD!
# Обрезка
text.strip()        # "Hello, World!"
text.lstrip()       # Левая обрезка
text.rstrip()       # Правая обрезка
# Поиск
text.find("World")   # 9
text.index("World")  # 9 (ошибка если нет)
text.count("l")     # 3
text.startswith("H") # True
text.endswith("!")   # True
# Замена
text.replace("World", "Python")
# Разделение
text.split(", ")     # ["Hello", "World!"]
text.rsplit(", ")    # Справа
text.splitlines()   # По строкам
# Объединение
", ".join(["a", "b", "c"]) # "a, b, c"
# Форматирование
"{} {}".format("Hello", "World")
f"{name} is {age}"
text.center(20, "*")
text.ljust(20)
text.rjust(20)
text.zfill(10)
Метод Описание
upper()/lower() Изменение регистра
strip() Удаление пробелов
split()/join() Разделение/объединение
replace() Замена подстроки
find()/index() Поиск подстроки
format()/f"" Форматирование
Итераторы и Генераторы Advanced

Итератор — это объект, который возвращает следующий элемент по запросу через next(). Генератор — удобный способ создать итератор с помощью yield. Это полезно, когда не нужно хранить в памяти всю последовательность сразу: только текущий элемент. Используйте генераторы для больших списков, потоковой обработки, файлов и последовательностей, которые создаются по требованию.

PYTHON
# Итератор
my_list = [1, 2, 3]
my_iter = iter(my_list)
next(my_iter)  # 1
next(my_iter)  # 2
# Генератор: возвращает числа по одному, экономя память
def count_up_to(n):
    count = 1
    while count <= n:
        yield count
        count += 1
for num in count_up_to(5):
    print(num)  # 1 2 3 4 5
# Генераторное выражение: ленивый квадрат
squares = (x**2 for x in range(10))
# первое значение берётся только при необходимости
print(next(squares))  # 0
# itertools: генераторы для бесконечных и комбинированных последовательностей
from itertools import count, cycle, chain
for i in count(0, 2):
    print(i)  # 0, 2, 4...
🖥️ PREVIEW
⚡ Зачем использовать генераторы
Память: генератор не создает весь список сразу, он генерирует элементы по одному.
Когда: чтение больших файлов, работа с потоками, бесконечные последовательности и сложные вычисления.
Выгода: меньше памяти, быстрее старт, проще код для ленивых вычислений.
HTTP-запросы (requests) HTTP

Библиотека requests для простых REST‑API запросов и работы с JSON.

PYTHON
import requests
# GET-запрос
response = requests.get("https://api.example.com/users")
if response.status_code == 200:
    data = response.json()
    print(data[0]["name"])
# POST-запрос с JSON
payload = {"name": "Vlad", "role": "admin"}
response = requests.post(
    "https://api.example.com/users",
    json=payload,
    timeout=5,
)
print(response.status_code)
🖥️ PREVIEW
GET /users → 200 OK
[{ "id": 1, "name": "Vlad" }, ...]

POST /users → 201 CREATED
venv и pip Env

Создание виртуального окружения и установка сторонних пакетов.

PYTHON
# Создать виртуальное окружение
python -m venv venv
# Активация (Windows)
venv\Scripts\activate
# Активация (macOS/Linux)
source venv/bin/activate
# Установка пакетов
pip install requests flask
# Заморозить зависимости
pip freeze > requirements.txt
# Установка из файла
pip install -r requirements.txt
🖥️ PREVIEW
project/
├─ venv/
├─ app.py
└─ requirements.txt
SQLite3 база данных DB

Использование встроенной SQLite для хранения данных без отдельного сервера.

PYTHON
import sqlite3
# Подключение к файлу БД
conn = sqlite3.connect("app.db")
cursor = conn.cursor()
# Создание таблицы
cursor.execute(
    "CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)"
)
# Вставка данных
cursor.execute(
    "INSERT INTO users (name, age) VALUES (?, ?)",
    ("Vlad", 25),
)
conn.commit()
# Чтение
cursor.execute("SELECT name, age FROM users")
rows = cursor.fetchall()
for name, age in rows:
    print(name, age)
conn.close()
🖥️ PREVIEW e
id name age
1 Vlad 25
2 Nadejda23
Декораторы в Python Advanced

Функции, модифицирующие поведение других функций. Используются для логирования, кеширования, аутентификации.

PYTHON
import functools
import time

# ДЕКОРАТОР БЕЗ ПАРАМЕТРОВ: функция, которая принимает функцию и возвращает её обёртку
def timer(func):
    # @functools.wraps(func): копирует метаданные оригинальной функции (__name__, __doc__ и т.д.)
    @functools.wraps(func)
    # wrapper(*args, **kwargs): внутренняя функция, которая может принять ЛЮБЫЕ аргументы
    def wrapper(*args, **kwargs):
        start = time.time()
        # func(*args, **kwargs): вызываем оригинальную функцию с переданными аргументами
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start:.2f}s")
        return result
    # ВАЖНО: возвращаем wrapper, а не result! (wrapper становится новой функцией)
    return wrapper

# ДЕКОРАТОР С ПАРАМЕТРАМИ: вложенные функции (repeat(times) -> decorator -> wrapper)
def repeat(times):
    # times запоминается в замыкании (closure) для использования в wrapper
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            # Цикл повторяет вызов функции заданное количество раз
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

# Использование: @timer и @repeat(3) - это синтаксический сахар для slow_function = timer(slow_function)
@timer
def slow_function():
    time.sleep(1)

# @repeat(3): сначала вызывается repeat(3), потом результат (decorator) применяется к greet
@repeat(3)
def greet(name):
    print(f"Hello, {name}!")

# slow_function теперь это wrapper, который отмеряет время выполнения оригинальной функции
slow_function()  # Выведет: slow_function took 1.00s
# greet теперь это wrapper, который вызывает оригинальную greet 3 раза
greet("World")  # Выведет "Hello, World!" три раза
🖥️ OUTPUT
slow_function took 1.00s
Hello, World!
Hello, World!
Hello, World!
Декоратор Назначение
@functools.wraps Сохраняет метаданные оригинальной функции
@property Создает геттеры/сеттеры
@staticmethod Статические методы класса

SQLAlchemy Полная Справка

Объектно-реляционный менеджер SQLAlchemy: настройка, модели, сессии, CRUD и связи.

Установка и подключение SQLAlchemy Setup

Подготовка проекта, создание движка и сессии.

PYTHON
# Установка SQLAlchemy и адаптера БД
pip install sqlalchemy psycopg2-binary

# Подключение к базе и создание сессии
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

DATABASE_URL = "postgresql://user:password@localhost/dbname"
engine = create_engine(DATABASE_URL, echo=True)  # Лог SQL-запросов
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# Функция для получения сессии
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()
🖥️ PREVIEW
SQLAlchemy создает единый движок для всех моделей.
SessionLocal управляет транзакциями и жизненным циклом соединения.
Модель SQLAlchemy и таблица Models

Создание модели через Declarative Base и представление таблицы.

PYTHON
# Описание модели пользователя
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Boolean

Base = declarative_base()

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String, nullable=False)
    email = Column(String, unique=True, index=True)
    is_active = Column(Boolean, default=True)

    # Удобный метод для отображения модели
    def __repr__(self):
        return f"<User id={self.id} name={self.name}>"
🖥️ PREVIEW
Модель User становится таблицей users с колонками id, name, email, is_active.
CRUD сессии SQLAlchemy CRUD

Примеры создания, чтения, обновления и удаления через сессию.

PYTHON
# Создание нового пользователя
user = User(name="Anna", email="anna@example.com")
db.add(user)  # Добавление в транзакцию
db.commit()  # Сохранение в базе
db.refresh(user)  # Обновление объекта полями из БД

# Чтение данных
user = db.query(User).filter(User.email == "anna@example.com").first()

# Обновление записи
user.name = "Anna Ivanova"
db.commit()

# Удаление записи
db.delete(user)
db.commit()
🖥️ PREVIEW
db.commit сохраняет изменения, db.refresh обновляет объект из базы.
db.query(User) возвращает объекты модели User.
Связи и отношения Relations

Пример связи One-to-Many между Users и Articles.

PYTHON
# Связь One-to-Many
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship

class Article(Base):
    __tablename__ = "articles"
    id = Column(Integer, primary_key=True)
    title = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey("users.id"))

    user = relationship("User", back_populates="articles")

User.articles = relationship("Article", back_populates="user", cascade="all, delete-orphan")
🖥️ PREVIEW
Каждый Article связан с одним User, а User может иметь множество статей.
Back_populates обеспечивает синхронные объекты на обеих сторонах отношения.
SQLAlchemy + FastAPI FastAPI

Повтор примера интеграции SQLAlchemy в FastAPI.

PYTHON
# Настройка движка и сессии
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Float
from fastapi import Depends

DATABASE_URL = "postgresql://user:pass@localhost/dbname"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

# Модель SQLAlchemy
class Product(Base):
    __tablename__ = "products"
    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)
    price = Column(Float)

# Функция зависимости для FastAPI
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/products")
async def get_products(db: Session = Depends(get_db)):
    return db.query(Product).all()

@app.post("/products")
async def create_product(name: str, price: float, db: Session = Depends(get_db)):
    product = Product(name=name, price=price)
    db.add(product)
    db.commit()
    db.refresh(product)
    return product
🖥️ PREVIEW
FastAPI использует Depends для получения SQLAlchemy-сессии в роуте.
db.commit сохраняет объект, db.refresh заполняет поля из БД.
SQLAlchemy + Flask Flask

Повтор примера работы с Flask-SQLAlchemy и моделями.

PYTHON
from flask import Flask, jsonify
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:pass@localhost/db'
db = SQLAlchemy(app)

# Определение моделей
class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)

class Post(db.Model):
    __tablename__ = 'posts'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(120), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)

# Операции с БД
@app.route('/create-user', methods=['POST'])
def create_user():
    user = User(username='john', email='john@example.com')
    db.session.add(user)
    db.session.commit()
    return jsonify({'id': user.id})

@app.route('/users')
def get_users():
    users = User.query.all()
    return jsonify([{'id': u.id, 'username': u.username} for u in users])

@app.route('/user/<int:user_id>')
def get_user(user_id):
    user = User.query.get_or_404(user_id)
    return jsonify({'id': user.id, 'username': user.username})
🖥️ PREVIEW
Flask-SQLAlchemy использует db.session для транзакций.
User.query и db.session упрощают запросы к данным.

SQL Полная Справка

Полный путь от базовых запросов до аналитики, транзакций, оптимизации и практик проектирования БД

CREATE TABLE и связи DDL
SQL
CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    city TEXT
);
CREATE TABLE orders (
    id INTEGER PRIMARY KEY,
    user_id INTEGER NOT NULL,
    total DECIMAL(10,2),
    created_at DATE,
    FOREIGN KEY (user_id) REFERENCES users(id)
);
🖥️ PREVIEW
Таблица Колонки Ключи
users id, name, city PK: id
orders id, user_id, total, created_at PK: id, FK: user_id → users.id
INSERT / UPDATE / DELETE DML
SQL
INSERT INTO users (id, name, city) VALUES
(1, 'Vlad', 'Moscow'),
(2, 'Nadia', 'Kazan');

UPDATE users
SET city = 'Saint Petersburg'
WHERE id = 2;

DELETE FROM users
WHERE id = 99;
🖥️ PREVIEW
Изменение данных в таблице без изменения структуры.
Rows affected: 2 INSERT, 1 UPDATE, 0 DELETE
JOIN: объединение таблиц JOIN
SQL
SELECT u.name, o.total, o.created_at
FROM users u
INNER JOIN orders o ON u.id = o.user_id
WHERE o.total >= 1000
ORDER BY o.created_at DESC;
🖥️ PREVIEW
name total created_at
Vlad 1990.00 2026-04-10
Nadia 1250.00 2026-04-11
Агрегации и GROUP BY Analytics
SQL
SELECT user_id,
       COUNT(*) AS orders_count,
       SUM(total) AS total_sum,
       AVG(total) AS avg_total
FROM orders
GROUP BY user_id
HAVING SUM(total) > 1500;
🖥️ PREVIEW
user_id orders_count total_sum avg_total
1 3 4200.00 1400.00
Индексы и производительность Perf
SQL
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_orders_created_at ON orders(created_at);

EXPLAIN QUERY PLAN
SELECT * FROM orders WHERE user_id = 1;
🖥️ PREVIEW
SEARCH orders USING INDEX idx_orders_user_id (user_id=?)
Индекс сокращает полный скан таблицы и ускоряет фильтрацию по `user_id`.
Типы JOIN (полная карта) JOIN
SQL
-- INNER JOIN
SELECT u.name, o.total
FROM users u
INNER JOIN orders o ON u.id = o.user_id;

-- LEFT JOIN
SELECT u.name, o.total
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

-- CROSS JOIN
SELECT u.name, p.period
FROM users u
CROSS JOIN (SELECT 'Q1' AS period UNION ALL SELECT 'Q2') p;
🖥️ PREVIEW
INNER: пересечение, LEFT: все из левой, CROSS: декартово произведение.
CTE и рекурсия Advanced
SQL
WITH RECURSIVE nums(n) AS (
    -- БАЗОВЫЙ CASE (anchor): начальное условие рекурсии - генерируем первую строку
    SELECT 1
    -- UNION ALL: объединяем базовый case с рекурсивным (ВАЖНО: ALL, а не UNION - иначе дубли удалятся!)
    UNION ALL
    -- РЕКУРСИВНЫЙ CASE: берём предыдущий результат и добавляем 1, ПОКА n < 5 (условие выхода)
    SELECT n + 1 FROM nums WHERE n < 5
)
SELECT * FROM nums;

-- NON-RECURSIVE CTE (просто сохраняем подзапрос для переиспользования):
WITH top_orders AS (
    SELECT * FROM orders WHERE total >= 1000
)
SELECT * FROM top_orders;
🖥️ PREVIEW
n
1
2
3
4
5
Оконные функции Window
SQL
-- Оконные функции: вычисления над группами строк БЕЗ коллапса (в отличие от GROUP BY)
SELECT
    user_id,
    total,
    -- ROW_NUMBER(): порядковый номер в окне (1,2,3...) даже если значения одинаковые
    ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY total DESC) AS rn,
    -- LAG(): получить значение из предыдущей строки в окне (для трендов, сравнения с предыдущим заказом)
    LAG(total) OVER (PARTITION BY user_id ORDER BY created_at) AS prev_total
-- PARTITION BY: разделить результаты на группы по user_id (отдельное окно для каждого юзера)
FROM orders;
🖥️ PREVIEW
user_id=1, total=1990, rn=1, prev_total=960
Подзапросы и EXISTS Subquery
SQL
SELECT name
FROM users u
WHERE EXISTS (
    SELECT 1
    FROM orders o
    WHERE o.user_id = u.id AND o.total > 1000
);

SELECT name
FROM users
WHERE id IN (
    SELECT user_id FROM orders
);
🖥️ PREVIEW
name
Vlad
Nadia
Транзакции и ACID TCL
SQL
BEGIN TRANSACTION;

UPDATE accounts SET balance = balance - 500 WHERE id = 1;
UPDATE accounts SET balance = balance + 500 WHERE id = 2;

COMMIT;
-- при ошибке:
ROLLBACK;
🖥️ PREVIEW
Atomicity: обе операции применяются вместе или откатываются вместе.
VIEW, TRIGGER, PROCEDURE DB Objects
SQL
CREATE VIEW active_users AS
SELECT id, name FROM users WHERE id > 0;

CREATE TRIGGER trg_orders_ai
AFTER INSERT ON orders
BEGIN
    INSERT INTO logs(message) VALUES ('order inserted');
END;
🖥️ PREVIEW
VIEW упрощает сложные SELECT, TRIGGER автоматизирует бизнес-логику.
Нормализация (1NF / 2NF / 3NF) Design
🖥️ PREVIEW
Форма Суть Результат
1NF Атомарные значения, без повторяющихся групп Чистые строки/столбцы
2NF Нет частичных зависимостей от составного PK Меньше дублирования
3NF Нет транзитивных зависимостей Стабильная модель
Денормализация допустима для аналитики и ускорения чтения.
Операции над наборами Set Ops
SQL
SELECT name FROM users_moscow
UNION
SELECT name FROM users_kazan;

SELECT name FROM active_users
INTERSECT
SELECT name FROM paid_users;

SELECT name FROM all_users
EXCEPT
SELECT name FROM blocked_users;
🖥️ PREVIEW
`UNION` объединяет уникальные строки, `INTERSECT` возвращает пересечение, `EXCEPT` показывает разницу наборов.
CASE и работа с NULL Logic
SQL
SELECT
  name,
  CASE
    WHEN age < 18 THEN 'minor'
    WHEN age >= 18 THEN 'adult'
    ELSE 'unknown'
  END AS age_group,
  COALESCE(city, 'N/A') AS city_safe
FROM users;
🖥️ PREVIEW
`CASE` добавляет условные категории прямо в выборке, `COALESCE` подставляет значение вместо `NULL`.
UPSERT (INSERT OR UPDATE) DML
SQL
INSERT INTO users (id, name, city)
VALUES (1, 'Vlad', 'Moscow')
ON CONFLICT (id)
DO UPDATE SET
  name = EXCLUDED.name,
  city = EXCLUDED.city;
🖥️ PREVIEW
UPSERT полезен для синхронизации: если строка есть — обновляем, если нет — создаем.
Изменение схемы без потерь Migration
SQL
ALTER TABLE users ADD COLUMN phone TEXT;
UPDATE users SET phone = 'unknown' WHERE phone IS NULL;
ALTER TABLE users ALTER COLUMN phone SET NOT NULL;

-- безопасное переименование
ALTER TABLE users RENAME COLUMN city TO location;
🖥️ PREVIEW
Правильная миграция: добавить колонку, заполнить данные, затем усиливать ограничения.
SQL Cheat Sheet Reference
QUICK REFERENCE
-- 1) DDL: сначала создаем структуру
CREATE TABLE table_name (
    id INTEGER PRIMARY KEY,
    col1 TEXT NOT NULL,
    col2 INTEGER,
    UNIQUE (col1),
    CHECK (col2 >= 0),
    DEFAULT 0
);
ALTER TABLE table_name ADD COLUMN created_at DATE;
CREATE INDEX idx_table_col1 ON table_name(col1);

-- 2) DML: заполняем и изменяем данные
INSERT INTO table_name (col1, col2) VALUES ('A', 10);
UPDATE table_name SET col2 = 20 WHERE col1 = 'A';
DELETE FROM table_name WHERE col1 = 'B';

-- 3) DQL: правильный порядок SELECT
SELECT col1, SUM(col2) AS total
FROM table_name
WHERE col2 > 0
GROUP BY col1
HAVING SUM(col2) >= 10
ORDER BY total DESC
LIMIT 10;

-- 4) TCL: оборачиваем критичные изменения в транзакцию
BEGIN;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- или ROLLBACK;

-- 5) DCL: права доступа
GRANT SELECT, INSERT ON table_name TO analyst_user;
REVOKE INSERT ON table_name FROM analyst_user;
🖥️ PREVIEW
Как писать SQL по шагам: DDL (структура) → DML (данные) → DQL (чтение) → TCL (безопасность изменений) → DCL (доступы).
Комментарий: блок SELECT в шпаргалке расположен в корректном синтаксическом порядке: SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT.
Комментарий: транзакции (BEGIN/COMMIT/ROLLBACK) используйте для денежных и критичных операций, чтобы избежать частично примененных изменений.
Оконные функции Advanced

Функции, работающие с окнами строк. Позволяют вычислять агрегаты без группировки.

SQL
SELECT
    name,
    salary,
    department,
    -- ROW_NUMBER(): простой порядковый номер (1,2,3,4) - каждой строке свой номер
    ROW_NUMBER() OVER (ORDER BY salary DESC) AS overall_rank,
    -- RANK(): пропускает номера при одинаковых значениях (1,2,2,4 - скачок через 3)
    RANK() OVER (ORDER BY salary DESC) AS rank_with_ties,
    -- DENSE_RANK(): не пропускает номера (1,2,2,3 - нет скачков)
    DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank,
    -- AVG(salary) OVER (PARTITION BY department): средняя зарплата ПО ОТДЕЛУ (разное значение для каждого отдела)
    AVG(salary) OVER (PARTITION BY department) AS dept_avg,
    -- LAG(salary, 1): берёт значение из предыдущей строки (полезно для сравнения с предыдущим рядом)
    LAG(salary) OVER (ORDER BY hire_date) AS prev_salary
FROM employees;
🖥️ PREVIEW
name salary dept_avg overall_rank
Alice 100000 95000 1
Bob 95000 95000 2
Charlie 95000 95000 2
Комментарий: ROW_NUMBER уникален, RANK пропускает позиции при равенстве, DENSE_RANK нет.
Функция Описание
ROW_NUMBER() Уникальный номер строки
RANK() Ранг с пропусками
LAG()/LEAD() Доступ к предыдущим/следующим строкам

PostgreSQL Полная Справка

От установки до production: типы, индексы, JSONB, транзакции, администрирование, мониторинг и оптимизация

Установка и подключение Setup
PSQL
-- Подключение к серверу
psql -h localhost -p 5432 -U postgres -d app_db

-- Проверка версии и текущей БД
SELECT version();
SELECT current_database();

-- Создание пользователя и БД
CREATE ROLE app_user WITH LOGIN PASSWORD 'StrongPass123';
CREATE DATABASE app_db OWNER app_user;
🖥️ PREVIEW
Сервер PostgreSQL запущен, база `app_db` и роль `app_user` готовы для приложения.
Комментарий: сначала создается отдельная роль приложения, затем база назначается владельцу — это безопаснее, чем работать под `postgres` в проде.
Типы данных PostgreSQL Types
SQL
CREATE TABLE events (
    id BIGSERIAL PRIMARY KEY,
    event_uuid UUID NOT NULL,
    title TEXT NOT NULL,
    price NUMERIC(10,2),
    tags TEXT[],
    payload JSONB,
    created_at TIMESTAMPTZ DEFAULT now()
);
🖥️ PREVIEW
Тип Где применять
UUID публичные идентификаторы
JSONB гибкая структура данных
TIMESTAMPTZ даты/время с часовым поясом
Комментарий: выбор правильных типов влияет на производительность, точность данных и корректную работу с часовыми поясами.
Ограничения и целостность Schema
SQL
CREATE TABLE users (
    id BIGSERIAL PRIMARY KEY,
    email TEXT UNIQUE NOT NULL,
    age INT CHECK (age >= 13),
    created_at TIMESTAMPTZ DEFAULT now()
);

CREATE TABLE orders (
    id BIGSERIAL PRIMARY KEY,
    user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
    total NUMERIC(10,2) CHECK (total >= 0)
);
🖥️ PREVIEW
`CHECK`, `UNIQUE` и `FK` защищают данные от некорректных значений и «висячих» связей.
Комментарий: ограничения лучше задавать в БД, а не только в коде приложения — это последняя линия защиты целостности.
Индексы и EXPLAIN ANALYZE Perf
SQL
CREATE INDEX idx_orders_user_id ON orders(user_id);
CREATE INDEX idx_events_payload_gin ON events USING GIN(payload);
CREATE INDEX idx_orders_paid_partial ON orders(id) WHERE total > 0;

EXPLAIN ANALYZE
SELECT * FROM orders WHERE user_id = 42;
🖥️ PREVIEW
Index Scan using idx_orders_user_id on orders (actual time=0.08..0.15 rows=18 loops=1)
Комментарий: `EXPLAIN ANALYZE` показывает реальный план и время — используйте его для проверки, что запрос действительно идет по индексу.
JSONB: хранение и поиск JSONB
SQL
-- JSONB: тип данных PostgreSQL для хранения JSON документов с индексацией
-- payload->>'status': извлекает значение (как text) по ключу 'status'
SELECT id, payload->>'status' AS status
FROM events
-- @>: оператор "содержит": проверяет содержит ли payload JSON объект {"priority":"high"}
-- Этот запрос очень быстр, если есть GIN индекс на payload!
WHERE payload @> '{"priority":"high"}'::jsonb;

-- jsonb_set(): безопасно обновляет конкретный путь в JSON без полной перезаписи
UPDATE events
SET payload = jsonb_set(payload, '{status}', '"processed"'::jsonb)
-- {status}: JSON путь (как в объекте: payload['status'] в коде)
-- ВАЖНО: используем jsonb_set вместо полной перезаписи! (atomicity, MVCC)
WHERE id = 1;
🖥️ PREVIEW
JSONB позволяет хранить полуструктурированные данные и быстро фильтровать их с GIN-индексами.
Комментарий: оператор `@>` проверяет вхождение JSON-объекта, а `jsonb_set` безопасно обновляет конкретный путь без полной перезаписи документа.
CTE и оконные функции Analytics
SQL
-- CTE (Common Table Expression) в PostgreSQL: вспомогательный SELECT, на который можно ссылаться
WITH monthly AS (
  -- Подзапрос CTE: вычисляем сумму заказов (revenue) за каждый месяц для каждого пользователя
  SELECT user_id, date_trunc('month', created_at) AS m, SUM(total) AS revenue
  FROM orders
  -- GROUP BY: группируем по user_id и месяцу (m), SUM - агрегирует по этим группам
  GROUP BY user_id, m
)
SELECT user_id, m, revenue,
       -- RANK() OVER (PARTITION BY user_id ORDER BY revenue DESC): ранг дохода внутри каждого user_id
       -- PARTITION BY: разделяет результаты на окна по user_id (отдельный ранг для каждого пользователя)
       -- ORDER BY revenue DESC: ранжируем в порядке убывания дохода
       RANK() OVER (PARTITION BY user_id ORDER BY revenue DESC) AS revenue_rank
-- Источник: используем CTE monthly вместо подзапроса (более читаемо!)
FROM monthly;
🖥️ PREVIEW
user_id month revenue rank
1 2026-04 2950.00 1
Комментарий: CTE делает сложный запрос читаемым, а оконная функция дает ранг без потери исходных строк.
Транзакции и уровни изоляции ACID
SQL
BEGIN;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

UPDATE accounts SET balance = balance - 500 WHERE id = 1;
UPDATE accounts SET balance = balance + 500 WHERE id = 2;

COMMIT;
-- при ошибке: ROLLBACK;
🖥️ PREVIEW
Для финансовых операций используйте транзакции и корректный уровень изоляции, чтобы избежать гонок и грязных чтений.
Комментарий: `REPEATABLE READ` фиксирует снимок данных внутри транзакции и снижает риск непредсказуемых результатов.
Роли, права, backup/restore Admin
ADMIN
CREATE ROLE readonly NOLOGIN;
GRANT CONNECT ON DATABASE app_db TO readonly;
GRANT USAGE ON SCHEMA public TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly;

-- Политика построчного доступа (RLS)
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY orders_owner_policy ON orders
USING (user_id = current_setting('app.user_id')::bigint);

-- Резервная копия и восстановление
pg_dump -Fc -U postgres -d app_db -f app_db.dump
pg_restore -U postgres -d app_db_new app_db.dump
🖥️ PREVIEW
Минимальные права по ролям + регулярный `pg_dump` — базовая стратегия безопасной эксплуатации PostgreSQL.
Комментарий: RLS ограничивает строки на уровне БД, даже если в приложении где-то пропущена проверка доступа.
Расширения PostgreSQL Extensions
SQL
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE EXTENSION IF NOT EXISTS citext;

CREATE TABLE accounts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email CITEXT UNIQUE NOT NULL
);
🖥️ PREVIEW
`pgcrypto` дает безопасный UUID, а `citext` делает email-поля регистронезависимыми.
Комментарий: расширения включаются отдельно в каждой базе и должны быть учтены в миграциях.
Партиционирование таблиц Scale
SQL
CREATE TABLE logs (
    id BIGSERIAL,
    created_at DATE NOT NULL,
    payload JSONB
) PARTITION BY RANGE (created_at);

CREATE TABLE logs_2026_04 PARTITION OF logs
FOR VALUES FROM ('2026-04-01') TO ('2026-05-01');
🖥️ PREVIEW
Данные автоматически раскладываются по партициям; старые партиции можно архивировать или удалять отдельно.
Комментарий: партиционирование особенно полезно для больших time-series таблиц и политики retention.
Materialized View Reporting
SQL
CREATE MATERIALIZED VIEW mv_monthly_revenue AS
SELECT date_trunc('month', created_at) AS month, SUM(total) AS revenue
FROM orders
GROUP BY month;

REFRESH MATERIALIZED VIEW CONCURRENTLY mv_monthly_revenue;
🖥️ PREVIEW
Материализованное представление хранит предрасчитанный результат и ускоряет аналитические дашборды.
Комментарий: `CONCURRENTLY` позволяет обновлять view без долгой блокировки чтения (при наличии уникального индекса).
VACUUM, ANALYZE, Autovacuum Maintenance
SQL
VACUUM orders;
ANALYZE orders;
VACUUM (VERBOSE, ANALYZE) orders;

-- Проверка активности autovacuum
SELECT relname, n_live_tup, n_dead_tup
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;
🖥️ PREVIEW
`VACUUM` чистит мертвые версии строк, `ANALYZE` обновляет статистику для оптимизатора.
Комментарий: без актуальной статистики планировщик может выбрать медленный план даже при наличии индексов.
Мониторинг и диагностика Observability
SQL
SELECT pid, usename, state, wait_event_type, query
FROM pg_stat_activity
WHERE state <> 'idle';

SELECT locktype, relation::regclass, mode, granted
FROM pg_locks
WHERE relation IS NOT NULL;
🖥️ PREVIEW
Через `pg_stat_activity` видно долгие запросы, через `pg_locks` — блокировки, мешающие транзакциям.
Комментарий: это первый шаг при жалобах на “тормозит БД” и “все зависло”.

Алгоритмы Полная Справка

От Big O и базовых структур до графов, динамического программирования и практики собеседований

Big O и оценка сложности Base
REFERENCE
O(1)  -- доступ по индексу
O(log n)  -- бинарный поиск
O(n)  -- линейный проход
O(n log n)  -- эффективные сортировки
O(n^2)  -- двойные циклы, bubble/selection
O(2^n)  -- полный перебор подмножеств
O(n!)  -- перестановки
🖥️ PREVIEW
Комментарий: Big O сравнивает масштабируемость алгоритмов при росте входных данных, а не абсолютное время в миллисекундах.
Массивы, HashMap, два указателя Patterns
PYTHON + JS
# Python: Two Sum (O(n))
def two_sum(nums, target):
    seen = {}
    for i, x in enumerate(nums):
        if target - x in seen:
            return [seen[target - x], i]
        seen[x] = i

// JS: max sum subarray of size k (sliding window)
function maxWindowSum(arr, k) {
  let sum = 0, best = -Infinity;
  for (let i = 0; i < arr.length; i++) {
    sum += arr[i];
    if (i >= k) sum -= arr[i - k];
    if (i >= k - 1) best = Math.max(best, sum);
  }
  return best;
}
🖥️ PREVIEW
Комментарий: HashMap помогает перейти от O(n²) к O(n), а sliding window убирает повторные вычисления в подмассивах.
Сортировки Sorting
PYTHON
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])
    out = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            out.append(left[i]); i += 1
        else:
            out.append(right[j]); j += 1
    return out + left[i:] + right[j:]
🖥️ PREVIEW
Алгоритм Сложность Стабильность
Merge Sort O(n log n) Да
Quick Sort O(n log n) avg Нет
Heap Sort O(n log n) Нет
Бинарный поиск Search
JAVASCRIPT
function binarySearch(arr, target) {
  let l = 0, r = arr.length - 1;
  while (l <= r) {
    const m = (l + r) >> 1;
    if (arr[m] === target) return m;
    if (arr[m] < target) l = m + 1;
    else r = m - 1;
  }
  return -1;
}
🖥️ PREVIEW
Комментарий: бинарный поиск работает только на отсортированных данных и делит область поиска пополам на каждом шаге.
Стек и очередь DS
PYTHON
from collections import deque

# Stack (LIFO)
stack = []
stack.append(10)
stack.append(20)
top = stack.pop()  # 20

# Queue (FIFO)
q = deque([1, 2])
q.append(3)
first = q.popleft()  # 1
🖥️ PREVIEW
Комментарий: стек часто применяют для парсинга/скобок/DFS, очередь — для BFS и задач с обработкой по порядку.
Связные списки и указатели LinkedList
PYTHON
def reverse_list(head):
    prev = None
    cur = head
    while cur:
        nxt = cur.next
        cur.next = prev
        prev = cur
        cur = nxt
    return prev

# Floyd cycle detection: slow/fast pointers
🖥️ PREVIEW
Комментарий: техника slow/fast pointers позволяет находить цикл без дополнительной памяти O(1).
Деревья и обходы Tree
JAVASCRIPT
function inorder(root, out = []) {
  if (!root) return out;
  inorder(root.left, out);
  out.push(root.val);
  inorder(root.right, out);
  return out;
}
🖥️ PREVIEW
Обход Порядок Применение
Preorder Root-Left-Right Сериализация
Inorder Left-Root-Right Отсортированный вывод BST
Postorder Left-Right-Root Удаление/сворачивание дерева
Графовые алгоритмы Graph
PYTHON
import heapq
def dijkstra(graph, start):
    dist = {v: float('inf') for v in graph}
    dist[start] = 0
    pq = [(0, start)]
    while pq:
        d, v = heapq.heappop(pq)
        if d != dist[v]:
            continue
        for to, w in graph[v]:
            nd = d + w
            if nd < dist[to]:
                dist[to] = nd
                heapq.heappush(pq, (nd, to))
    return dist
🖥️ PREVIEW
Комментарий: Дейкстра ищет кратчайшие пути в графе с неотрицательными весами через приоритетную очередь.
Рекурсия и Backtracking Search
PYTHON
def subsets(nums):
    res = []
    def dfs(i, path):
        if i == len(nums):
            res.append(path[:]); return
        dfs(i + 1, path)
        path.append(nums[i])
        dfs(i + 1, path)
        path.pop()
    dfs(0, [])
    return res
🖥️ PREVIEW
Комментарий: backtracking перебирает дерево решений с откатом, что подходит для комбинаций, перестановок и constraint-задач.
Динамическое программирование DP
JAVASCRIPT
-- Динамическое программирование (DP): сохранение результатов подзадач, чтобы избежать пересчета
function fibDP(n) {
  -- Базовый случай: F(0)=0, F(1)=1
  if (n <= 1) return n;
  -- dp[i] будет хранить результат для i-го числа Фибоначчи (табуляция)
  const dp = Array(n + 1).fill(0);
  -- Инициализация: F(1) = 1
  dp[1] = 1;
  -- Итеративное заполнение: F(i) = F(i-1) + F(i-2) (строим решение снизу вверх)
  for (let i = 2; i <= n; i++) {
    -- Каждый результат вычисляется ровно один раз и хранится в dp
    dp[i] = dp[i - 1] + dp[i - 2];
  }
  -- Временная сложность: O(n) вместо O(2^n) для наивной рекурсии!
  return dp[n];
}
🖥️ PREVIEW
Комментарий: DP сокращает экспоненциальный перебор за счет хранения результатов подзадач (memoization/tabulation).
Жадные алгоритмы Greedy
PYTHON
-- Жадный алгоритм для max non-overlapping intervals (выбираем максимум не пересекающихся интервалов)
def max_non_overlap(intervals):
    -- Сортируем интервалы по конечной точке (ключевой шаг жадного выбора!)
    intervals.sort(key=lambda x: x[1])
    -- end: конец последнего выбранного интервала (инициализируем -бесконечность)
    end = -10**9
    -- cnt: количество выбранных интервалов
    cnt = 0
    -- Жадный выбор: берём интервал, если его начало >= конца последнего выбранного
    for l, r in intervals:
        if l >= end:
            -- Интервалы не пересекаются, добавляем его
            cnt += 1
            end = r
    return cnt
🖥️ PREVIEW
Комментарий: greedy берет локально лучшее решение; работает, только если задача обладает свойством жадного выбора.
Строковые алгоритмы Strings
PYTHON
-- KMP prefix function: для каждой позиции i вычисляет длину наибольшего префикса-суффикса
def prefix_function(s):
    -- pi[i] = длина наибольшего собственного префикса s[0..i], который также суффикс
    pi = [0] * len(s)
    for i in range(1, len(s)):
        -- j: текущая позиция для сравнения (начинаем с конца предыдущего совпадения)
        j = pi[i - 1]
        -- Если s[i] != s[j], откатываемся к предыдущему совпадению
        while j > 0 and s[i] != s[j]:
            -- j = pi[j-1]: переходим к следующему более короткому префиксу-суффиксу
            j = pi[j - 1]
        -- Если символы совпали, увеличиваем длину совпадения
        if s[i] == s[j]:
            j += 1
        pi[i] = j
    -- Результат: массив pi используется в KMP для поиска за O(n+m) без отката!
    return pi
🖥️ PREVIEW
Комментарий: префикс-функция — основа KMP для поиска подстроки за O(n + m) без отката по тексту.
Roadmap по алгоритмам Roadmap
🖥️ PREVIEW
Этап Темы Цель
1 Big O, массивы, hashmap, two pointers Уверенная база
2 Сортировки, бинарный поиск, стек/очередь Шаблоны задач
3 Деревья, графы, DFS/BFS, shortest path Средний+ уровень
4 DP, greedy, backtracking, string algorithms Сложные задачи
Комментарий: эффективная практика — решать 2-3 задачи в день с обязательным разбором сложности и альтернативных решений.
Сегментное дерево Data Structures

Структура данных для эффективных запросов на диапазонах и обновлений элементов.

PYTHON
class SegmentTree:
    def __init__(self, arr):
        self.n = len(arr)
        self.tree = [0] * (4 * self.n)
        self.build(arr, 0, 0, self.n - 1)

    def build(self, arr, node, start, end):
        if start == end:
            self.tree[node] = arr[start]
            return
        mid = (start + end) // 2
        self.build(arr, 2*node+1, start, mid)
        self.build(arr, 2*node+2, mid+1, end)
        self.tree[node] = self.tree[2*node+1] + self.tree[2*node+2]

    def query(self, node, start, end, l, r):
        if r < start or end < l:
            return 0
        if l <= start and end <= r:
            return self.tree[node]
        mid = (start + end) // 2
        left = self.query(2*node+1, start, mid, l, r)
        right = self.query(2*node+2, mid+1, end, l, r)
        return left + right

# Использование
arr = [1, 3, 5, 7, 9, 11]
st = SegmentTree(arr)
print(st.query(0, 0, 5, 1, 3))  # Сумма с 1 по 3: 3+5+7=15
🖥️ PREVIEW
Сегментное дерево позволяет выполнять запросы суммы/минимума на диапазоне за O(log n).
Комментарий: подходит для задач с частыми обновлениями и запросами на диапазонах.
Операция Сложность
Build O(n)
Query O(log n)
Update O(log n)

FastAPI Полная Справка

Современный асинхронный фреймворк для создания REST API с автоматической документацией

Установка и запуск Setup

Установка FastAPI и ASGI сервера Uvicorn

BASH
# Установка FastAPI и Uvicorn
pip install fastapi uvicorn[standard]

# Опционально: для работы с БД
pip install sqlalchemy psycopg2-binary pydantic

# Запуск сервера
uvicorn main:app --reload

# На production
uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
🖥️ PREVIEW
Сервер запущен на http://localhost:8000
Документация доступна на http://localhost:8000/docs (Swagger)
ReDoc доступен на http://localhost:8000/redoc
Основные методы и роуты Routing

GET, POST, PUT, DELETE запросы с параметрами пути и query

PYTHON
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

# GET - получение данных
@app.get("/items")
async def get_items(skip: int = 0, limit: int = 10):
    return {"skip": skip, "limit": limit}

# GET с параметром пути
@app.get("/items/{item_id}")
async def get_item(item_id: int):
    return {"item_id": item_id}

# Модель Pydantic
class Item(BaseModel):
    name: str
    price: float
    is_offer: bool = None

# POST - создание
@app.post("/items")
async def create_item(item: Item):
    return {"created": item}

# PUT - обновление
@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item):
    return {"updated": item_id, "item": item}

# DELETE - удаление
@app.delete("/items/{item_id}")
async def delete_item(item_id: int):
    return {"deleted": item_id}
🖥️ PREVIEW
Автоматическая валидация данных через Pydantic
Интерактивная документация в /docs
Поддержка асинхронного кода с async/await
Зависимости и Authentication Security

Внедрение зависимостей и аутентификация через JWT токены

PYTHON
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
import jwt

security = HTTPBearer()
SECRET_KEY = "your-secret-key"

# Функция зависимости
async def get_current_user(credentials: HTTPAuthorizationCredentials = Depends(security)):
    try:
        token = credentials.credentials
        payload = jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
        user_id = payload.get("sub")
        if user_id is None:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
        return user_id
    except jwt.InvalidTokenError:
        raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)

# Использование зависимости
@app.get("/me")
async def get_me(user_id: str = Depends(get_current_user)):
    return {"user_id": user_id}

# Middleware для логирования
@app.middleware("http")
async def log_requests(request, call_next):
    response = await call_next(request)
    return response
🖥️ PREVIEW
Зависимости автоматически внедряются в функции
JWT токены для безопасной передачи данных
Middleware для кроссплатформенной обработки
Работа с БД и SQLAlchemy Database

Интеграция с SQLAlchemy ORM

PYTHON
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, Session
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Float

DATABASE_URL = "postgresql://user:pass@localhost/dbname"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()

# Модель SQLAlchemy
class Product(Base):
    __tablename__ = "products"
    id = Column(Integer, primary_key=True)
    name = Column(String, unique=True)
    price = Column(Float)

# Использование в FastAPI
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@app.get("/products")
async def get_products(db: Session = Depends(get_db)):
    return db.query(Product).all()

@app.post("/products")
async def create_product(name: str, price: float, db: Session = Depends(get_db)):
    product = Product(name=name, price=price)
    db.add(product)
    db.commit()
    db.refresh(product)
    return product
🖥️ PREVIEW
Полная интеграция с реляционными БД
ORM для безопасных операций с данными
Background Tasks и Async Advanced

Фоновые задачи и асинхронная обработка

PYTHON
from fastapi import BackgroundTasks
import asyncio

# Background Task
def send_email(email: str, message: str):
    # Отправка email
    print(f"Email отправлен на {email}")

@app.post("/send-notification")
async def send_notification(email: str, background_tasks: BackgroundTasks):
    background_tasks.add_task(send_email, email, "Hello!")
    return {"message": "Notification queued"}

# Асинхронные операции
async def fetch_data_async(url: str):
    await asyncio.sleep(1)
    return {"data": "fetched"}

@app.get("/async-data")
async def get_async_data():
    data = await fetch_data_async("https://api.example.com")
    return data
🖥️ PREVIEW
Встроенная поддержка background tasks
Полная асинхронность с async/await
Для Celery используйте внешние queue системы
CORS, Exception Handling, Валидация Advanced

Настройка CORS, обработка ошибок и валидация данных

PYTHON
from fastapi.middleware.cors import CORSMiddleware
from fastapi import HTTPException
from pydantic import BaseModel, validator

# CORS конфигурация
app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://example.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Валидация с Pydantic
class User(BaseModel):
    username: str
    email: str
    age: int
    
    @validator('age')
    def age_must_be_positive(cls, v):
        if v < 0:
            raise ValueError('Age must be positive')
        return v

# Exception Handling
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
    return {"error": exc.detail}

@app.post("/users")
async def create_user(user: User):
    if not user.email.endswith("@example.com"):
        raise HTTPException(status_code=400, detail="Invalid email")
    return user
🖥️ PREVIEW
CORS для безопасной кроссдоменной коммуникации
Автоматическая валидация через Pydantic validators
Кастомная обработка исключений
WebSockets в FastAPI Real-time

Реальное время с двусторонней связью для чатов, уведомлений и live-обновлений.

PYTHON
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from typing import List

app = FastAPI()

-- ConnectionManager: класс для управления активными WebSocket подключениями
class ConnectionManager:
    def __init__(self):
        -- active_connections: список всех подключённых клиентов для broadcast сообщений
        self.active_connections: List[WebSocket] = []

    -- accept(): принимает входящее подключение (обязательно перед receive/send)
    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        -- добавляем клиента в список активных подключений
        self.active_connections.append(websocket)

    -- disconnect(): удаляет клиента при разрыве соединения
    def disconnect(self, websocket: WebSocket):
        self.active_connections.remove(websocket)

    -- send_personal_message(): отправляет сообщение ОДНОМУ конкретному клиенту
    async def send_personal_message(self, message: str, websocket: WebSocket):
        await websocket.send_text(message)

    -- broadcast(): отправляет сообщение ВСЕ подключённым клиентам (асинхронно)
    async def broadcast(self, message: str):
        for connection in self.active_connections:
            await connection.send_text(message)

manager = ConnectionManager()

-- @app.websocket("/ws/{client_id}"): WebSocket эндпоинт, path-параметр client_id
@app.websocket("/ws/{client_id}")
async def websocket_endpoint(websocket: WebSocket, client_id: int):
    -- await manager.connect(): принимаем клиента и добавляем в список
    await manager.connect(websocket)
    try:
        -- while True: бесконечный цикл, ждём сообщений от клиента
        while True:
            -- await websocket.receive_text(): БЛОКИРУЕТ, пока не придёт сообщение (async wait)
            data = await websocket.receive_text()
            -- личное подтверждение клиенту, что его сообщение получено
            await manager.send_personal_message(f"You wrote: {data}", websocket)
            -- broadcast: уведомляем всех остальных клиентов о новом сообщении
            await manager.broadcast(f"Client #{client_id} says: {data}")
    -- except: ловим разрыв соединения (клиент отключился)
    except WebSocketDisconnect:
        manager.disconnect(websocket)
        -- уведомляем остальных, что клиент ушёл
        await manager.broadcast(f"Client #{client_id} left the chat")
🖥️ PREVIEW
WebSockets позволяют двустороннюю связь без polling.
Комментарий: идеально для чатов, игр и real-time приложений.
Метод Описание
websocket.accept() Принимает соединение
websocket.receive_text() Получает текстовое сообщение
websocket.send_text() Отправляет текстовое сообщение

Flask Полная Справка

Лёгкий микрофреймворк для создания веб-приложений с полной гибкостью

Установка и первое приложение Setup

Установка Flask и создание простого приложения

BASH
# Установка Flask
pip install flask python-dotenv

# Запуск development сервера
flask run

# Или запуск скрипта напрямую
python app.py

# Для production используйте Gunicorn
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 app:app
🖥️ PREVIEW
Development сервер на http://localhost:5000
Auto-reload при изменении файлов
Отладчик Werkzeug в браузере
Роуты и обработка запросов Routing

Определение маршрутов и обработка HTTP методов

PYTHON
from flask import Flask, request, jsonify

-- Flask(__name__): создаёт приложение, __name__ для автоопределения путей
app = Flask(__name__)

-- @app.route('/'): декоратор привязывает функцию к URL пути (маршрутизация)
@app.route('/')
def hello():
    -- Простой ответ: Flask автоматически установит content-type: text/html
    return 'Hello, World!'

-- @app.route('/user/<int:user_id>'): <int:user_id> - параметр пути, тип int
@app.route('/user/<int:user_id>')
def get_user(user_id):
    -- jsonify(): преобразует Python dict в JSON с content-type: application/json
    return jsonify({'user_id': user_id})

-- @app.route('/items'): роут для получения списка (query параметры)
@app.route('/items')
def get_items():
    -- request.args.get(): получает параметры из query строки (?skip=10&limit=5)
    skip = request.args.get('skip', default=0, type=int)
    limit = request.args.get('limit', default=10, type=int)
    return jsonify({'skip': skip, 'limit': limit})

-- @app.route(..., methods=['POST']): указываем HTTP метод (GET по умолчанию)
@app.route('/items', methods=['POST'])
def create_item():
    -- request.get_json(): парсит JSON из тела запроса
    data = request.get_json()
    -- Возвращаем JSON и HTTP статус 201 (Created для POST)
    return jsonify({'created': data}), 201

-- PUT: HTTP метод для полного обновления ресурса
@app.route('/items/<int:item_id>', methods=['PUT'])
def update_item(item_id):
    data = request.get_json()
    return jsonify({'updated': item_id, 'item': data})

-- DELETE: HTTP метод для удаления ресурса
@app.route('/items/<int:item_id>', methods=['DELETE'])
def delete_item(item_id):
    -- Возвращаем информацию об удаленном ресурсе
    return jsonify({'deleted': item_id})

if __name__ == '__main__':
    app.run(debug=True)
🖥️ PREVIEW
Декоратор @app.route для связи URL с функцией
request объект для доступа к данным
jsonify() для возврата JSON
Шаблоны и Jinja2 Templates

Использование Jinja2 для динамических HTML шаблонов

PYTHON
from flask import render_template, url_for

# Файл: templates/index.html
"""
<h1>{{ title }}</h1>
<ul>
  {% for item in items %}
    <li>{{ item.name }} - ${{ item.price }}</li>
  {% endfor %}
</ul>
<a href="{{ url_for('get_item', item_id=1) }}">Товар 1</a>
"""

@app.route('/')
def index():
    items = [
        {'name': 'Product A', 'price': 100},
        {'name': 'Product B', 'price': 200}
    ]
    return render_template('index.html', title='Welcome', items=items)

# Наследование шаблонов
"""
# base.html
<!DOCTYPE html>
<html>
<head>
  <title>{% block title %}{% endblock %}</title>
</head>
<body>
  {% block content %}{% endblock %}
</body>
</html>

# page.html
{% extends "base.html" %}
{% block title %}Page Title{% endblock %}
{% block content %}<h1>Page content</h1>{% endblock %}
"""
🖥️ PREVIEW
Jinja2 - мощный язык шаблонов
Циклы, условия и наследование шаблонов
url_for() для генерации ссылок
Работа с БД и Flask-SQLAlchemy Database

Использование Flask-SQLAlchemy для работы с БД

PYTHON
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:pass@localhost/db'
db = SQLAlchemy(app)

# Определение модели
class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)

class Post(db.Model):
    __tablename__ = 'posts'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(120), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)

# Операции с БД
@app.route('/create-user', methods=['POST'])
def create_user():
    user = User(username='john', email='john@example.com')
    db.session.add(user)
    db.session.commit()
    return jsonify({'id': user.id})

@app.route('/users')
def get_users():
    users = User.query.all()
    return jsonify([{'id': u.id, 'username': u.username} for u in users])

@app.route('/user/<int:user_id>')
def get_user(user_id):
    user = User.query.get_or_404(user_id)
    return jsonify({'id': user.id, 'username': user.username})
🖥️ PREVIEW
Flask-SQLAlchemy упрощает работу с ORM
Отношения между таблицами через relationships
db.session для управления транзакциями
Аутентификация и сессии Security

Реализация login/logout с хешированием паролей

PYTHON
from flask import session, redirect, url_for
from werkzeug.security import generate_password_hash, check_password_hash

app.secret_key = 'your-secret-key'

@app.route('/register', methods=['POST'])
def register():
    username = request.form.get('username')
    password = request.form.get('password')
    hashed_pw = generate_password_hash(password)
    
    user = User(username=username, password=hashed_pw)
    db.session.add(user)
    db.session.commit()
    return redirect(url_for('login'))

@app.route('/login', methods=['POST'])
def login():
    username = request.form.get('username')
    password = request.form.get('password')
    
    user = User.query.filter_by(username=username).first()
    if user and check_password_hash(user.password, password):
        session['user_id'] = user.id
        return redirect(url_for('dashboard'))
    return 'Invalid credentials', 401

@app.route('/logout')
def logout():
    session.clear()
    return redirect(url_for('index'))
🖥️ PREVIEW
Werkzeug для хеширования паролей
Сессии для хранения данных пользователя
Никогда не сохраняйте пароли в plaintext
Blueprints для модульности Advanced

Организация кода через Blueprints

PYTHON
# Файл: auth/routes.py
from flask import Blueprint, request, jsonify

auth_bp = Blueprint('auth', __name__, url_prefix='/auth')

@auth_bp.route('/login', methods=['POST'])
def login():
    return jsonify({'message': 'Login'})

@auth_bp.route('/logout')
def logout():
    return jsonify({'message': 'Logout'})

# Файл: app.py
from flask import Flask
from auth.routes import auth_bp

app = Flask(__name__)
app.register_blueprint(auth_bp)

# Результат: /auth/login, /auth/logout
🖥️ PREVIEW
Blueprints разделяют приложение на модули
Перевосстанавливают код для больших проектов
Каждый blueprint может иметь свои templates и static
Flask-SQLAlchemy ORM

ORM для работы с базами данных в Flask-приложениях.

PYTHON
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)

    def __repr__(self):
        return f'<User {self.username}>'

# Создание таблиц
with app.app_context():
    db.create_all()

@app.route('/users')
def get_users():
    users = User.query.all()
    return {user.username: user.email for user in users}

@app.route('/add_user/<username>/<email>')
def add_user(username, email):
    user = User(username=username, email=email)
    db.session.add(user)
    db.session.commit()
    return f'User {username} added'
🖥️ PREVIEW
SQLAlchemy предоставляет высокоуровневый ORM для Flask.
Комментарий: поддерживает миграции, отношения и сложные запросы.
Метод Описание
db.Model Базовый класс для моделей
db.Column Определяет столбец таблицы
db.session Управляет транзакциями

Django Полная Справка

Полнофункциональный фреймворк для разработки масштабируемых веб-приложений

Установка и создание проекта Setup

Инициализация Django проекта и приложения

BASH
# Установка Django
pip install django

# Создание проекта
django-admin startproject myproject
cd myproject

# Создание приложения
python manage.py startapp myapp

# Миграции
python manage.py makemigrations
python manage.py migrate

# Запуск development сервера
python manage.py runserver

# Создание суперпользователя для админки
python manage.py createsuperuser
🖥️ PREVIEW
Development сервер на http://localhost:8000
Admin панель на http://localhost:8000/admin
ORM с автоматическими миграциями
Модели и ORM Database

Определение моделей и работа с ORM

PYTHON
# Файл: models.py
from django.db import models

class Category(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField(blank=True)
    
    def __str__(self):
        return self.name

class Product(models.Model):
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    is_active = models.BooleanField(default=True)
    
    class Meta:
        ordering = ['-created_at']
        verbose_name_plural = 'Products'
    
    def __str__(self):
        return self.name

# Запросы ORM
# Получить все
products = Product.objects.all()

# Фильтрация
active = Product.objects.filter(is_active=True)

# Исключение
recent = Product.objects.exclude(created_at__lt='2025-01-01')

# Получить один объект
product = Product.objects.get(id=1)

# Создание
Product.objects.create(name='New', price=99.99, category_id=1)

# Обновление
product.price = 79.99
product.save()

# Удаление
product.delete()
🖥️ PREVIEW
Django ORM с типизацией полей
Автоматические связи ForeignKey, ManyToMany
QuerySet с ленивыми вычислениями
Представления (Views) Routing

Функции и классы-представления для обработки запросов

PYTHON
# Файл: views.py
from django.shortcuts import render, get_object_or_404
from django.http import JsonResponse
from django.views import View
from django.views.generic import ListView, DetailView

# Function-based view
def product_list(request):
    products = Product.objects.all()
    return render(request, 'products/list.html', {'products': products})

# Class-based view
class ProductListView(ListView):
    model = Product
    template_name = 'products/list.html'
    context_object_name = 'products'
    paginate_by = 10

class ProductDetailView(DetailView):
    model = Product
    template_name = 'products/detail.html'

# JSON API view
def api_products(request):
    products = Product.objects.values('id', 'name', 'price')
    return JsonResponse({'products': list(products)})

# Файл: urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('products/', views.ProductListView.as_view(), name='product-list'),
    path('products/<int:pk>/', views.ProductDetailView.as_view(), name='product-detail'),
    path('api/products/', views.api_products, name='api-products'),
]
🖥️ PREVIEW
Function-based views для простых случаев
Class-based views (CBV) для переиспользования кода
Встроенная поддержка JSON и пагинации
Шаблоны Django Templates

Синтаксис шаблонов Django с фильтрами и тегами

HTML
<!-- Наследование шаблонов -->
{% extends "base.html" %}

{% block title %}Products{% endblock %}

{% block content %}
    <h1>{{ page_title }}</h1>
    
    <!-- Условия -->
    {% if products %}
        <ul>
            {% for product in products %}
                <li>
                    <a href="{% url 'product-detail' product.id %}">
                        {{ product.name }}
                    </a>
                    <!-- Фильтры -->
                    - ${{ product.price|floatformat:2 }}
                </li>
            {% endfor %}
        </ul>
    {% else %}
        <p>Нет товаров</p>
    {% endif %}
    
    <!-- Статические файлы -->
    {% load static %}
    <img src="{% static 'images/logo.png' %}" />
    
    <!-- Пагинация -->
    {% if is_paginated %}
        <a href="?page={{ page_obj.next_page_number }}">Далее</a>
    {% endif %}
{% endblock %}
🖥️ PREVIEW
{% url %} для динамических ссылок
{% load static %} для статических файлов
Встроенные фильтры (truncatewords, date, etc)
Формы Django Forms

Создание и валидация форм через Django Forms

PYTHON
# Файл: forms.py
from django import forms
from .models import Product

# ModelForm автоматически из модели
class ProductForm(forms.ModelForm):
    description = forms.CharField(
        widget=forms.Textarea(attrs={'rows': 4}),
        required=False
    )
    
    class Meta:
        model = Product
        fields = ['name', 'price', 'category']
    
    # Кастомная валидация
    def clean_price(self):
        price = self.cleaned_data.get('price')
        if price and price < 0:
            raise forms.ValidationError("Price must be positive")
        return price

# Использование в view
def create_product(request):
    if request.method == 'POST':
        form = ProductForm(request.POST)
        if form.is_valid():
            product = form.save()
            return redirect('product-detail', pk=product.id)
    else:
        form = ProductForm()
    return render(request, 'create.html', {'form': form})

# В шаблоне
# <form method="post">
#     {% csrf_token %}
#     {{ form.as_p }}
#     <button type="submit">Save</button>
# </form>
🖥️ PREVIEW
ModelForm автоматически из моделей
CSRF защита автоматически
Встроенная валидация через clean методы
Аутентификация и Admin панель Security

Встроенная система аутентификации и админки

PYTHON
# Файл: views.py
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate, login, logout

# Защита view от неавторизованных
@login_required(login_url='login')
def profile(request):
    return render(request, 'profile.html')

def login_view(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(request, username=username, password=password)
        if user:
            login(request, user)
            return redirect('home')
    return render(request, 'login.html')

def logout_view(request):
    logout(request)
    return redirect('home')

# Файл: admin.py - регистрация моделей
from django.contrib import admin
from .models import Product, Category

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ['name', 'price', 'category', 'is_active']
    list_filter = ['is_active', 'category']
    search_fields = ['name']
    ordering = ['-created_at']

admin.site.register(Category)
🖥️ PREVIEW
Встроенная система User с группами и правами
@login_required декоратор для защиты view
Auto-generated admin панель с фильтрацией
Django REST Framework API

Создание REST API с Django REST Framework

PYTHON
# Файл: serializers.py
from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ['id', 'name', 'price', 'category']

# Файл: views.py
from rest_framework import viewsets, status
from rest_framework.response import Response

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer

# Файл: urls.py
from rest_framework.routers import DefaultRouter
from .views import ProductViewSet

router = DefaultRouter()
router.register(r'products', ProductViewSet)

urlpatterns = router.urls
# Результат: GET /products/, POST /products/, GET /products/{id}/, etc
🖥️ PREVIEW
Serializers для валидации и трансформации данных
ViewSets автоматически генерируют CRUD endpoints
Роутеры для автоматической регистрации URL
Django Authentication Auth

Система аутентификации пользователей в Django.

PYTHON
# Файл: models.py
from django.db import models
from django.contrib.auth.models import AbstractUser

class CustomUser(AbstractUser):
    phone = models.CharField(max_length=15, blank=True)
    birth_date = models.DateField(null=True, blank=True)

# Файл: views.py
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect

def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            return redirect('home')
    return render(request, 'login.html')

@login_required
def profile_view(request):
    return render(request, 'profile.html', {'user': request.user})

# Файл: settings.py
AUTH_USER_MODEL = 'myapp.CustomUser'

# Проверка прав
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView

class MySecureView(LoginRequiredMixin, ListView):
    pass
🖥️ PREVIEW
Django предоставляет готовую систему аутентификации.
Комментарий: поддерживает кастомные модели пользователей и права доступа.
Функция Описание
authenticate() Проверяет учетные данные
login() Авторизует пользователя
@login_required Декоратор для защищенных views
✓ Код скопирован!