<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <language>ru</language>
    <title>SQL</title>
    <description/>
    <link>https://tproger.ru/tag/sql</link>
    <atom:link href="https://tproger.ru/tag/sql/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Sat, 03 Oct 2026 14:15:03 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>SQL</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Эволюция архитектуры страниц данных в СУБД: от NSM до FastLanes</title>
      <link>https://tproger.ru/articles/evolyuciya-arhitektury-stranic-dannyh-v-subd-ot-nsm-do-fastlanes</link>
      <comments>https://tproger.ru/articles/evolyuciya-arhitektury-stranic-dannyh-v-subd-ot-nsm-do-fastlanes?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Виталий При]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/evolyuciya-arhitektury-stranic-dannyh-v-subd-ot-nsm-do-fastlanes</guid>
      <description><![CDATA[<p>Эволюция файлов данных в СУБД. Хотя NSM уже больше 15 лет, это архитектура продолжает использоваться ведущими  СУБД. Рассмотрим какие задачи решает модель PAX и ее оптимизированный вариант FastLanes.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/evolyuciya-arhitektury-stranic-dannyh-v-subd-ot-nsm-do-fastlanes">Эволюция архитектуры страниц данных в СУБД: от NSM до FastLanes</a>»</p>]]></description>
      <category><![CDATA[Big Data]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 10 Sep 2026 17:27:01 GMT</pubDate>
      <content:encoded><![CDATA[<p>Когда вы пишете SELECT * FROM users WHERE age &gt; 30, вы
редко задумываетесь о том, как именно СУБД физически хранит эти данные на
диске. А между тем, от архитектуры страницы данных зависит, сколько лишних байт
будет прочитано, насколько эффективно используется кэш
процессора, и во что обойдутся обновления и удаления. В этой статье разберём
три классические модели — NSM, DSM и PAX, а также заглянем в будущее — формат
FastLanes, созданный специально под SIMD и GPU.<b></b></p><h3>1. Классика всех времен: страница NSM</h3><p>Традиционная и самая распространённая архитектура
в OLTP-СУБД (PostgreSQL, Oracle) — слотированная страница,
относящаяся к семейству NSM (N-ary Storage Model). Страница, как правило, имеет
фиксированный размер, чаще всего 8 или 16 КБ (может настраиваться параметром
БД), и делится на три логические области:</p><p>·      
<b>Заголовок страницы</b> — содержит
метаданные: размер страницы, количество слотов, смещение до свободного
пространства и флаги.</p><p>·      
<b>Таблица слотов</b> — массив записей
фиксированной длины, каждая из которых хранит смещение (offset) до начала
соответствующей строки. Слоты упорядочены по позиции строки в таблице.</p><p>·      
<b>Область данных</b> — сами кортежи,
расположенные последовательно, но в обратном порядке относительно таблицы
слотов (данные растут с конца страницы в начало, а слоты — с начала в конец).
Это позволяет эффективно управлять фрагментацией.</p><p><br /></p><figure><img src="https://media.tproger.ru/user-uploads/140096/2026-09-10/393863ea-b164-4e8d-8cdd-1ed31ffbac59.webp" alt="Пример таблицы" /><figcaption>1.1 Пример таблицы</figcaption></figure><figure><img src="https://media.tproger.ru/user-uploads/140096/2026-09-10/1523098a-dbbb-469e-a550-f3d7f8e23ee2.webp" alt="Пример файла данных для таблицы" /><figcaption>Рисунок 1.1 – Пример файла данных для таблицы</figcaption></figure><p><br /></p><h4>Особенности
работы с изменениями на уровне страницы:</h4><p>При обновлении строки, если её новый размер превышает старый,
на старом месте сохраняется указатель (forwarding pointer), а обновлённая
запись перемещается в свободную область страницы (или даже на другую страницу,
если свободного места недостаточно). Это порождает цепочки переадресации,
которые могут замедлять чтение.</p><p>При удалении строки соответствующий слот помечается как
недействительный (например, устанавливается флаг deleted или смещение
становится отрицательным). Физическое освобождение места происходит позже — при
сборке мусора (VACUUM в PostgreSQL) или при перестройке страницы.</p><h4>Главный недостаток:</h4><p>Для запросов, которые читают миллионы строк, но выбирают лишь 2–3 атрибута из 20, NSM необходимо просканировать всю страницу целиком. В результате в кэш CPU загружаются все атрибуты, включая ненужные. Это не только увеличивает время I/O, но и порождает промахи кэша (cache misses), поскольку полезные данные перемешиваются с не нужными.</p><h3>2. Колоночная страница DSM:</h3><p>Научная работа Джорджа П. Коупленда и Сетрага Н. Хошафяна «A
Decomposition Storage Model» (ACM SIGMOD) [1] предложила кардинально иной
подход к организации данных на странице, получивший название DSM (Decomposition
Storage Model).</p><p>В классической реализации DSM каждый атрибут таблицы хранится в
отдельном наборе страниц. При этом страницы внутри одного атрибута содержат
только значения этого столбца, расположенные в порядке строк. Для
восстановления полной записи используется либо позиционный идентификатор
(порядковый номер строки в странице), либо служебные битовые маски.</p><h4>Преимущества на уровне страниц:</h4><p>·      
Страница заполняется данными одного типа — это
даёт значительный прирост в сжатии (RLE, дельта-кодирование, битовые карты) по
сравнению с NSM-архитектурой.</p><p>·      
При сканировании одного-двух столбцов читается
ровно столько страниц, сколько нужно для этих атрибутов, без загрузки не используемых в запросе колонок.</p><h4>Обратная сторона:</h4><p>Вставка или обновление строки требуют записи в страницы всех
атрибутов, что превращается в доступ к множеству файлов и их соединение.
Запрос SELECT * для ограниченного числа строк также вынужден
выполнять дорогостоящее соединение страниц разных столбцов, что делает DSM
неэффективной для OLTP.</p><p>Первоначально модель не получила широкого распространения
именно из-за высокой стоимости сборки строк. Однако с ростом мощностей
процессоров и объёмов оперативной памяти она стала основой для колоночных СУБД
(Vertica, Greenplum, ClickHouse), где основная нагрузка — аналитические
запросы.</p><figure><img src="https://media.tproger.ru/user-uploads/140096/2026-09-10/31e86521-072e-4d3b-9983-21312d34a61b.webp" alt="Пример файла DSM" /><figcaption>Рисунок 2.1 – Пример файла DSM</figcaption></figure><p><br /></p><h3>3. PAX: гибридная модель данных</h3><p>В 2001 году на конференции VLDB была представлена работа
Анастасии Аламаки, Дэвида ДеВитта, Марка Хилла и Муниратнама Сивакумара
«Weaving Relations for Cache Performance» [2], в которой авторы предложили
комбинированный подход — PAX (Partition Attributes Crosswise).</p><h4>Ключевая идея модели:</h4><p>Страница остаётся целостной (содержит все атрибуты таблицы, как в
NSM), что позволяет избавиться от дорогостоящих соединений файлов данных. Но
внутри страницы данные разбиты по атрибутам: все значения первого атрибута
собираются в непрерывный мини-блок. Следом идёт мини-блок второго атрибута,
затем третьего, и так далее. В начале страницы располагается каталог
(directory), указывающий смещение и размер каждого мини-блока.</p><h4>Как происходит выборка данных:</h4><p>Для запроса, выбирающего два столбца, СУБД обращается к странице и читает только те два мини-блока — остальные не попадают в кэш
процессора, что снижает количество промахов.</p><p>Обновление
всей строки не требует записи в отдельные файлы (как в DSM) — достаточно
перезаписать соответствующие мини-блоки внутри одной страницы.</p><figure><img src="https://media.tproger.ru/user-uploads/140096/2026-09-10/09a94b94-0c05-469a-84ee-ff350607bddb.webp" alt="Схема страницы PAX" /><figcaption>Рисунок 3.1 – Схема страницы PAX</figcaption></figure><p><br /></p><h3>4. Современные реализации на основе PAX</h3><h4>Apache Parquet</h4><p>Прямой наследник PAX. Файл разбивается на Row Groups (группы строк,
типично 128 МБ – 1 ГБ), каждая из которых действует как крупная «страница» PAX.
Внутри Row Group данные организованы по Column Chunks — это и есть мини-блоки
разных атрибутов, только теперь они могут быть сжаты независимо друг от друга.
Parquet также добавляет индексы и статистику на уровне Column Chunk (min, max,
null count), что позволяет при сканировании пропускать целые блоки без
разжатия.</p><h4>Apache ORC (Optimized Row Columnar)</h4><p>Аналог Parquet, используемый в Hive, Presto и Trino. Внутри
ORC-файла выделяются Stripes (полосы), которые выполняют ту же роль, что и Row
Groups в Parquet. Внутри Stripe данные хранятся по колонкам с добавлением
индексов и словарей. По сути, это тоже PAX, но с более агрессивным сжатием и
встроенной фильтрацией.</p><h3>5. FastLanes — PAX, оптимизированный под SIMD и GPU</h3><p>PAX-архитектура значительно улучшила предыдущие модели
хранения данных, но она не учитывала характеристики процессора. Именно в этом
направлении происходит дальнейшее развитие архитектуры хранения данных. Петер
Бонч, учёный из исследовательского центра CWI (Нидерланды), предложил новый
формат FastLanes, который оптимизирует хранение данных под возможности
современных процессоров.</p><p>Файл FastLanes состоит из двух главных компонентов: Footer
(футер) и Data (данные). Футер содержит метаданные, описание данных и их
местонахождение в файле и может храниться отдельно от блока «Данные».</p><p>На верхнем уровне блок «Данные» повторяет архитектуру PAX:
данные делятся на группы строк и атрибуты. В отличие от существующих типов
файлов, в FastLanes группы строк содержат количество записей, кратное 1024. Это
позволяет избежать материализации данных в основной памяти и выполнять всю
работу на уровне процессора. Следующим важным нововведением является
использование сжатия LWC (Light-Weight-Compression).
Вместо тяжеловесных алгоритмов по типу Zstd, которые не позволяют
распараллелить обработку данных, применяются FSST, DICT, ALP при каскадном
(рекурсивном) применении которых достигается уровень сжатия Snappy за более
короткий промежуток времени [3]. Кроме этого, для каждой колонки данных могут
применяться разные операторы кодирования. Сжатые данные хранятся в сегментах, в
которых кроме самих данных хранятся смещения на отдельные вектора, что
позволяет читать данные на уровне одного вектора вместо целого блока, как в
старых форматах.</p><p>Когда данные читаются из
оперативной памяти в процессор, закодированный вектор, содержащий 1024
значения, разжимается и полностью помещается в кэш процессора. Напротив, старые
форматы файлов не только используют непараллельные алгоритмы сжатия, но и применяют
их к целым Row Group, что влечёт за собой использование основной памяти и
уменьшение скорости обработки [3].</p><figure><img src="https://media.tproger.ru/user-uploads/140096/2026-09-10/38442764-e882-48bd-abc8-e2389e2fbf91.webp" alt="Пример таблицы[3]" /><figcaption>Рисунок 5.1 – Пример таблицы[3]</figcaption></figure><p><br /></p><figure><img src="https://media.tproger.ru/user-uploads/140096/2026-09-10/53f16e51-def6-48b1-b0a6-3282b28622d7.webp" alt="Файл FastLane[3]" /><figcaption>Рисунок 5.2 – Файл FastLane[3]</figcaption></figure><p><br /></p><figure><img src="https://media.tproger.ru/user-uploads/140096/2026-09-10/b9a51ae2-6319-490c-bd67-4028b1b35e49.webp" alt="Футер файла FastLane[3]" /><figcaption>Рисунок 5.3 – Футер файла FastLane[3]</figcaption></figure><p><br /></p><figure><img src="https://media.tproger.ru/user-uploads/140096/2026-09-10/e52e3ea5-17fa-44d2-bc85-2f418e39150e.webp" alt="Операторы кодирования FastLane[3]" /><figcaption>Рисунок 5.4 – Операторы кодирования FastLane[3]</figcaption></figure><p><br /></p><h4>Использованные источники:</h4><ol><li>Copeland G.P., Khoshafian
     S.N. A Decomposition Storage Model. Proceedings of ACM
     SIGMOD, 1985.</li><li>Ailamaki A., DeWitt D., Hill
     M., Sivakumar M. Weaving Relations for Cache Performance. Proceedings
     of VLDB, 2001.</li><li>Boncz P., Afroozech A., et
     al. The FastLanes File Format: specification.</li></ol>]]></content:encoded>
    </item>
    <item>
      <title>NULL в SQL: почему запрос отрабатывает и молча отдаёт неверное число</title>
      <link>https://tproger.ru/articles/null-v-sql-pochemu-zapros-otrabatyvaet-i-molcha-otdayot-nevernoe-ch</link>
      <comments>https://tproger.ru/articles/null-v-sql-pochemu-zapros-otrabatyvaet-i-molcha-otdayot-nevernoe-ch?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/null-v-sql-pochemu-zapros-otrabatyvaet-i-molcha-otdayot-nevernoe-ch</guid>
      <description><![CDATA[<p>Почему WHERE x = NULL не находит строки, как одно пустое значение обнуляет весь NOT IN и на что делится среднее. Разбираем на примерах Postgres.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/null-v-sql-pochemu-zapros-otrabatyvaet-i-molcha-otdayot-nevernoe-ch">NULL в SQL: почему запрос отрабатывает и молча отдаёт неверное число</a>»</p>]]></description>
      <category><![CDATA[Лучшая практика]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Анализ данных]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 08 Sep 2026 06:08:25 GMT</pubDate>
      <content:encoded><![CDATA[<p>В SQL деление на ноль Postgres остановит с ошибкой. Приведение строки «abc» к числу тоже. А деление на NULL пройдёт, и запрос вернёт результат. Просто не тот, которого вы ждали.</p><p>Это главная особенность работы с отсутствующими значениями: ошибок нет, есть тихо неправильные числа. Разбираем, откуда они берутся в фильтрах, в арифметике, в агрегатах и в соединениях, и какими операторами это лечится.</p><p>Отправная точка одна: NULL — не значение, а отметка «неизвестно». Неизвестность распространяется дальше по всему выражению: через сравнения, арифметику, склейку строк, агрегаты, оконные функции и условия отбора. Результат при этом строго определён правилами языка, он просто может не совпасть с тем, что вы имели в виду.</p><p>В SQL три логических исхода, а не два: истина, ложь и неизвестность. Условие отбора оставляет только строки с истиной, поэтому неизвестность отбрасывается наравне с ложью.</p><p>Сравнение = NULL не почти верно, а отвечает на другой вопрос. Для проверки на отсутствие есть отдельные операторы, которые сравнением не являются.</p><p>Одно значение NULL в списке для NOT IN обнуляет всю выдачу целиком, а не сужает её.</p><p>Соединение по равенству отбрасывает строки, где ключ отсутствует с обеих сторон, и то же самое делает проверка уникальности.</p><p>Запрос, который отработал, прошёл только проверку грамматики. Число становится верным, когда с вопросом совпали строки, фильтры и знаменатель.</p><h2>Три логических исхода вместо двух</h2><p>Начнём с простого случая. В таблице клиентов у одного из них не заполнен телефон, и это прямо видно глазами. Запрос находит ноль строк:</p><p>Условие phone = NULL спрашивает: «равно ли это неизвестное значение тому неизвестному значению?» Ответить на такое нельзя, поэтому <a href="https://dev.to/systemcraftdev/why-where-x-null-never-works-in-sql-and-what-to-use-instead-3p4h">для каждой строки возвращается неизвестность</a>, включая ту самую строку с пустым телефоном. А отбор оставляет только строки, где условие истинно. Неизвестность не проходит ровно так же, как не прошла бы ложь.</p><p>Правило действует единообразно: NULL = NULL тоже не истина, а неизвестность. Отсюда и главный вывод — оператор равенства нельзя «подправить», чтобы он здесь заработал. Он не почти прав, он отвечает на другой вопрос.</p><p>В Postgres это проверяется одной строкой. Что вернёт такое выражение?</p><p>Оба внутренних сравнения неизвестны, поэтому внешнее сравнивает неизвестность с неизвестностью и тоже даёт неизвестность. Операторы сравнения возвращают NULL, если хотя бы одна сторона неизвестна. Именно поэтому в языке есть отдельный оператор проверки на отсутствие: узнать, равны ли две неизвестности, нельзя, а узнать, является ли значение неизвестным, можно.</p><h3>Как ведут себя И, ИЛИ и НЕ</h3><p>Логические связки тоже работают в трёх значениях, и запомнить стоит два исключения:</p><p>То есть ИЛИ всё ещё истинно, если истинна вторая сторона, а И всё ещё ложно, если ложна вторая сторона. Всё остальное с участием неизвестности схлопывается в неизвестность.</p><p>Последствия неочевидны. Вот запрос, который отбрасывает строку, которую вы почти наверняка хотели оставить:</p><p>В обычной двузначной логике «активно или не активно» — тавтология, утверждение, истинное при любом значении. В SQL это не так.</p><h3>Операторы, которые никогда не возвращают неизвестность</h3><p>Лечится это выходом из трёхзначной логики. Сначала решите, что NULL означает в вашей предметной области, а потом скажите это явно:</p><p>Проверки IS TRUE, IS NOT TRUE, IS FALSE, IS NOT FALSE и IS UNKNOWN никогда не возвращают неизвестность, поэтому строку не потеряют.</p><p>Аналог того же для равенства — IS NOT DISTINCT FROM. Обычное равенство спрашивает, известно ли, что значения совпадают. Этот оператор спрашивает, одно ли это значение, обращаясь с отсутствием как с полноценным состоянием. Две неизвестности неразличимы, поэтому предикат истинен.</p><p><b>Где это пригодится:</b><br />Соединение по условию равенства отбрасывает строки, где ключ отсутствует с обеих сторон. Если два отсутствующих ключа должны считаться совпадением, замените равенство на IS NOT DISTINCT FROM. То же касается проверок уникальности и условий отбора, где «отсутствует» должно означать «отсутствует», а не «неизвестно».</p><h2>Ловушка NOT IN, из-за которой пропадает вся выдача</h2><p>Это самый дорогой из всех эффектов, потому что он не сужает результат, а стирает его целиком. Операторы IN и NOT IN разворачиваются в цепочки сравнений, а NOT IN — в цепочку через И:</p><p>Разберём оба исхода. Если значение совпало с одним из перечисленных, срабатывает то самое правило «И спасает ложь справа», и выражение честно ложно. Если не совпало ни с одним, множитель со сравнением с пустым значением делает всё выражение неизвестным.</p><p>Для условия отбора разницы между этими исходами нет: оно оставляет только истину, а ложь и неизвестность отбрасывает одинаково. Поэтому итог один — если в списке или в подзапросе есть хотя бы одно отсутствующее значение, NOT IN не вернёт ни одной строки. Никакой ошибки при этом не будет.</p><p>Обычный IN ведёт себя мягче, поскольку разворачивается в цепочку через ИЛИ: совпадение остаётся истиной независимо от того, что ещё есть в списке. В простом условии отбора пустое значение в списке вообще ничего не меняет: несовпавшая строка отсеется что при неизвестности, что при лжи. Разница вылезает там, где результат сравнения используется дальше: под отрицанием, в выражении CASE или в ограничении целостности.</p><p>Надёжная замена — NOT EXISTS, который работает через равенство внутри условия отбора и потому никогда не трактует сравнение с отсутствующим значением как совпадение. Тот же смысл выражает антисоединение, которое вдобавок часто даёт лучший план:</p><p>Вычистить отсутствующие значения из подзапроса тоже можно, но это помогает, только если вы уверены, что их следует игнорировать. Вариант с NOT EXISTS делает это намерение явным, а не подразумеваемым.</p><h2>Арифметика: одно значение NULL обнуляет строку</h2><p>Любая арифметическая операция с участием отсутствующего значения даёт отсутствующее значение. Сложение, умножение, деление, модуль, возведение в степень — результат один.</p><p>В отчётах это выглядит как пустые ячейки, а в обновлениях данных как стёртые колонки. Классический пример, который каждый когда-нибудь писал:</p><p>Подставлять значение по умолчанию нужно в той точке, где вам известно правило предметной области, а не механически везде. В разборе Кристофера Уинслетта из Crunchy Data приводится удачная иллюстрация: <a href="https://www.crunchydata.com/blog/postgres-calculations-and-the-ambiguity-of-null">отсутствующее количество почти всегда означает ноль, отсутствующая ставка налога тоже, а вот отсутствующая цена нулём не является</a> и должна оставаться неизвестной, пока её кто-нибудь не заполнит.</p><h2>Агрегаты и оконные функции считают не то, что кажется</h2><p>Здесь отсутствующие значения ведут себя иначе, чем везде: агрегаты их пропускают. Функция COUNT(*) считает строки, а COUNT(колонка) — только непустые значения; SUM, AVG, MIN и MAX пропускают пустые входы.</p><p>У товара с двумя незаполненными оценками среднее и сумма пусты, а число строк равно двум. Отсюда практическое правило, которое экономит часы разбирательств с аналитикой: среднее — это сумма, делённая на количество непустых значений, а не на количество строк. Смешивать SUM(x) / COUNT(*) и ожидать совпадения со средним нельзя.</p><p>Оговорка про типы тоже важна: если сумма и счётчик целочисленные, деление усечёт дробную часть. Шесть, делённое на два, случайно даст ровно три, а оценки 5, 1 и 2 дадут при целочисленном делении двойку вместо 2,67.</p><h3>Где ломаются оконные функции</h3><p>Суммирование и усреднение в окне пропускают отсутствующие значения так же, как при группировке, а ROW_NUMBER считает строку в любом случае. Расхождение начинается у функций, которые смотрят в конкретную позицию окна: LAG, LEAD, FIRST_VALUE, LAST_VALUE и NTH_VALUE.</p><p>Такая функция возвращает то, что лежит в запрошенной позиции. Если там пусто, результат пуст. Ближайшее реальное значение она не ищет, и на рядах измерений с пропущенным отсчётом это даёт разрывы там, где ожидалась непрерывность.</p><h2>Проверка чужого запроса, включая сгенерированный</h2><p>Всё описанное складывается в одну проблему: запрос, который отработал, прошёл только проверку грамматики. База ловит опечатку в имени таблицы. Она не ловит суммирование не той колонки, соединение, задваивающее строки, и фильтр, поставленный не на том этапе. Каждая из этих ошибок — синтаксически корректный SQL.</p><p>Со сгенерированными запросами есть <a href="https://dev.to/michaelnocito/how-to-review-ai-generated-sql-before-you-trust-the-number-19ek">отдельная сложность</a>: они беглые. Псевдонимы аккуратные, форматирование чистое, форма выглядит как работа внимательного человека. Беглость читается как правильность, хотя это разные вещи.</p><h3>Проверка первая: посчитайте строки до того, как поверите сумме</h3><p>Задача звучала как «чистая выручка по завершённым заказам». Полученный запрос:</p><p>Он отрабатывает и возвращает 1830. Правильный ответ 1330, и это легко проверить руками: валовая сумма одиннадцати завершённых заказов равна 1605, возвраты составляют 275.</p><p>Виновато соединение. Два заказа возвращались частями, по две записи на каждый, поэтому одиннадцать строк превращаются в тринадцать, а сумма по заказам считает эти два заказа дважды: 2105 вместо 1605. Лишние 500 — это ровно стоимость задвоенных заказов. Явление называется размножением строк: соединение множит строки всякий раз, когда ключ на другой стороне встречается больше одного раза.</p><p>Проверка стоит двух запросов:</p><p>Одно это сравнение всё решает. Второе число выросло, значит, соединение размножило строки, и любая сумма или среднее по колонкам левой таблицы под подозрением. Число совпало — соединение безопасно, идём дальше.</p><h3>Проверка вторая: ищите отсутствующие значения в каждом фильтре</h3><p>Следующая просьба звучала как «та же выручка, но без служебных аккаунтов», и запрос получился такой:</p><p>Он возвращает пустоту, полученную из нуля строк. Не меньшее число, а вообще ничего. Механизм вы уже знаете: в справочнике служебных аккаунтов есть одна строка с незаполненным идентификатором, а справочники в реальной жизни такими и бывают. Одна такая строка бесшумно опустошает результат целиком.</p><h2>Что забрать с собой</h2><p>Правила про отсутствующие значения не сложны, они просто действуют не там, где их ждут. Из фильтра строка пропадает молча, арифметика превращает результат в пустоту, соединение по равенству теряет пары без ключа, а среднее делит на другой знаменатель. Ошибки при этом нигде не возникает, и потому такие дефекты живут в отчётах годами.</p><p>Самый надёжный способ не разбираться со всем этим каждый раз — не хранить отсутствующие значения там, где они не нужны. Если колонка обязана иметь значение, скажите это в схеме. Ограничение NOT NULL выглядит формальностью ровно до первого расследования, почему выручка в отчёте оказалась на пятьсот единиц больше настоящей.</p><p>Материалы разбора: <a href="https://dev.to/systemcraftdev/why-where-x-null-never-works-in-sql-and-what-to-use-instead-3p4h">почему сравнение с NULL никогда не срабатывает</a>, <a href="https://www.crunchydata.com/blog/postgres-calculations-and-the-ambiguity-of-null">поведение NULL в вычислениях Postgres</a> и <a href="https://dev.to/michaelnocito/how-to-review-ai-generated-sql-before-you-trust-the-number-19ek">проверка сгенерированного SQL до того, как поверить числу</a>.</p><p>Откройте последний отчёт, который вы отдавали наружу, и сравните в нём количество строк до и после соединений. Проверка занимает пять минут и иногда меняет цифру, на которую уже сослались в переписке.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как я написал AI-бота на aiogram 3 с помощью нейросетей, выжил при 2500+ пользователей и почему SQLite "всё ещё торт"</title>
      <link>https://tproger.ru/articles/kak-ya-napisal-ai-bota-na-aiogram-3-s-pomoshhyu-nejrosetej-vyzhil-p</link>
      <comments>https://tproger.ru/articles/kak-ya-napisal-ai-bota-na-aiogram-3-s-pomoshhyu-nejrosetej-vyzhil-p?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Нуя]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ya-napisal-ai-bota-na-aiogram-3-s-pomoshhyu-nejrosetej-vyzhil-p</guid>
      <description><![CDATA[<p>Технический кейс создания Telegram-бота Щёлк-ГДЗ (ИИ-репетитор по фото). Разбор архитектуры на Python (aiogram 3, aiosqlite), работы с API Gemini и решения проблем под нагрузкой 2500+ пользователей. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ya-napisal-ai-bota-na-aiogram-3-s-pomoshhyu-nejrosetej-vyzhil-p">Как я написал AI-бота на aiogram 3 с помощью нейросетей, выжил при 2500+ пользователей и почему SQLite "всё ещё торт"</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Flash]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Пет-проект]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[Hardware]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 26 Jul 2026 15:47:08 GMT</pubDate>
      <content:encoded><![CDATA[<p>На дворе 2026 год. Очередной постмортем микро-SaaS'а в Телеге.</p><p>Без маркетинга и успешного успеха. Только боль, костыли и суровый прод! Мой пет-проект - бот «Щёлк-ГДЗ». Это ИИ-помощник, который решает школьные задачки по фоткам, видео, гс, тг-кружкам и PDF. Под капотом <b>Python 3.12.3</b>, <b>aiogram 3</b>, <b>aiosqlite</b>,<b> апи OpenRouter </b>(модель Gemini 3.0 Flash) и <b>Робокасса</b>. Крутится всё это на дешёвом VPS в Нидерландах. Держит 2500+ пользователей и не падает.</p><p>В этой статье расскажу, как за 9 месяцев построил логичную архитектуру, победил ошибку FloodWait при стриминге ответа ИИ и почему в условиях 1 гига RAM обычная SQLite - отличное решение.</p><h2>Нейронка вместо джуна и Уроборос багов</h2><p>Сразу признаюсь... С нуля я это не писал :) Синтаксис мне генерили LLM-ки. Начинал с Gemini 2.5 Pro, затем перешел на 3.0 Pro, а сейчас использую 3.1 Pro.</p><p>Многие думают, что нейронка сама напишет проект "под ключ", но это миф. Я <b>никогда </b>не доверял ИИ проектирование архитектуры и использовал его как продвинутый<i> StackOverflow</i> (скармливал конкретную задачу (например, написать SQL-миграцию) и получал кусок кода).</p><p><i>ИИ — это не архитектор, а джун на спидах. </i></p><p>Как только логика усложнялась - гемини ловил <b>«Уроборос багов»</b>. Кидаешь баг <b>А</b> - он его фиксит, но появляется ошибка <b>Б</b>. Скармливаешь и её - фиксит, но возвращается баг <b>А</b>. Цикл замкнулся. Лечилось только созданием новых чатов, в которые я кидал код и писал запросы типа "Найди критические ошибки, логические дыры и баги".</p><p>Про продуктовую логику нейронка вообще не слышала. В первой версии рефералки был баг, где любой(если его аккаунта ещё нет в БД) мог написать в конце ссылки что любые 9 цифр (<i>?start=1234567890</i>) и получить бонусы.</p><p>Также были ошибки с гонкой состояний при оплатах и активациях промокодов, которые тоже фиксил запросами в новые чаты с ИИ. Так я исправил около 20 архитектурных дыр.</p><h2>Немного про архитектуру.</h2><p>Чтобы код не превратился в нечитаемую лапшу на 5000 строк, я жестко разбил всё на модули. Архитектура бота выглядит так:</p><figure><img src="https://media.tproger.ru/user-uploads/139416/2026-07-08/dfc8dd70-365f-4f70-bbbf-2b00b503bef4.webp" alt="" /></figure><p><b>main.py</b> - это точка входа с настройкой логгеров, коннетами aiohttp и запуском APScheduler</p><p><b>database.py</b> - вся работа с БД</p><p><b>neiro.py</b> - логика общения с апи OpenRouter (стриминг, сжатие фоток через Pillow, JSON-контекст)</p><p><b>states.py</b> - классы состояний aiogram.fsm.state (например, PaymentProcess, GdzMode)</p><p><b>utils.py</b> - легковесные утилиты. Например лок пользователей (защита от спама запросами):</p><p>Хэндлеры вынесены в отдельную папку handlers/:</p><p><b>handlers/common_handlers.py</b> - главное меню с обработкой /start (рефералки, utm-метки).</p><p><b>handlers/gdz_handlers.py</b> - сам процесс ИИ-решения (вход в GdzMode, прием фото, видео, кружочков).</p><p><b>handlers/pay_handlers.py</b> - это логика платежей (Robokassa) и "Умная корзина".</p><p><b>handlers/tasks_handlers.py</b> - квесты (выдача премиума за подписку на каналы спонсоров).</p><p>Сборку интерфейсов вынес в <b>all_def.py</b>. Не люблю, когда в хэндлерах генерится полотно текста с кнопками. Там же лежат функции склонения слов (1 запрос, 2 запроса, 5 запросов). А в <b>settings.py </b>лежат списки с рандомными ответами бота, чтоб казался живым.</p><p>Так же в <b>settings.py</b> я сделал кэширование картинок, тоесть при первом запуске бот грузит фото меню как <b>BufferedInputFile</b>, сохраняет <b>file_id</b> от Телеграма и дальше шлет картинки моментально по ID. Сервак говорит спасибо за сэкономленный трафик)</p><p>В <b>handlers/common_handlers.py</b> находится первичная маршрутизация. Вот так обрабатываются рефералки, переходы с сайта, с рекламы и другое при старте:</p><h2>Диета по токенам</h2><p>Хранить бесконечную историю диалогов дорого и бессмысленно. В бесплатной версии храню <b>10 последних сообщений</b> (5 пар вопрос-ответ), а в преме — <b>30. </b></p><p>Но фотки весят большое кол-во токенов. Если премиум-юзер закинет 30 фоток, OpenRouter выставит мне огромный счет. В итоге я прикрутил ограничение: Из <b>30 сообщений</b> ИИ видит только <b>10 последних картинок. </b></p><p>Старые фотки тупо вырезаю из JSON. Подменяю на системный промпт:</p><p>С довольно неплохой моделью (gemini 3.0 flash) это работает как часы (она честно признается, что забыла картинку, а не выдумывает что-то из воздуха).</p><h2>Стриминг, FloodWait и защита баланса</h2><p>Чтобы бот не выглядел тормозом, я сделал стриминг ответа от ИИ в <b>neiro.py</b>. Я обновляю сообщение в Телеграме чанками по мере получения их от ОпенРоутера.</p><p>Но если делать <b>message.edit_text </b>слишком часто, ловишь <b>FloodWait</b>. В итоге я выставил интервал в 0.7 секунд и обернул всё в жесткий<b> try/except</b>:</p><p>Стрим при этом не прерывается. Поспали и погнали дальше :) Если на этапе обработки файла или стриминга падает критическая ошибка - честно возвращаю юзеру запрос на баланс.</p><p>В <b>handlers/gdz_handlers.py</b> это выглядит так:</p><h2>SQLite тащит</h2><p>Почему не <b>Postgre</b>? Потому что для микро-SaaS с 2,5к пользователей<b> SQLite</b> хватает за глаза. Но в асинхронной среде она любит кидать ошибку <b>database is locked</b>.</p><p>Чтобы этого избежать, я включил <b>WAL-режим</b> при инициализации пула, разделил коннекты на <b>db_writer</b> и <b>db_reader</b>, а сложные операции доверил самому <b>SQL</b>.</p><p>Например, 00:00 запускается крон-таска, которая собирает огромную аналитику, начисляет всем активным юзерам +1 ежедневный запрос и сбрасывает просроченные подписки. И это всё это работает атомарно внутри <b>database.py</b>:</p><h2>Умная корзина на APScheduler</h2><p>Когда дело дошло до монетизации, всплыли две проблемы:</p><p>Первая: юзер оплатил, но забыл нажать кнопку <b>«✅ Я оплатил»</b> в боте. Бот ждет, юзер ждет, товар не выдается, поддержка кипит.</p><p>Вторая: юзер сформировал счёт и передумал ("брошенная корзина").</p><p>Вместе с LLM я с нуля изучил <b>apscheduler </b>и убил двух зайцев фоновыми задачами. Теперь в <b>handlers/pay_handlers.py </b>при генерации ссылки на оплату я создаю две отложенные таски:</p><h4>Как это работает?</h4><p>Через 5 минут срабатывает <b>async def auto_check_payment()</b>, которая тихо стучится в робокассу. Если статус<b> success</b> - бот сам начисляет запросы на баланс и радует клиента. Если статус <b>pending</b> - таска умирает, и в дело вступает 30-минутная таска.</p><p>Но она не шлёт спам вслепую, а лезит в БД и проверяет 3 бизнес-правила:</p><p>1. <b>await db.has_successful_payment_recently</b> - Не купил ли он другой товар за последние 3 часа?</p><p>2. <b>await db.get_latest_invoice_id</b> - А это точно самый последний сгенерированный им счет?</p><p>3. <b>await db.can_send_agitation</b> - Не присылали ли мы ему агитацию недавно?</p><p>Если проверки пройдены, то юзер получает сообщение: <i>"⏳ Домашка сама себя не решит! Ты начал оформлять покупку, но оплата так и не прошла..."</i>. Это поднимает конверсию оплат.</p><h2>Финал</h2><p>Почему я не использую <b>Redis </b>для стейтов? Ответ банален: мой дешевый VPS имеет всего 1 гб оперативки. Пул <b>aiohttp</b>, In-Memory стейты и асинхронные таски и так жрут 70% RAM. Редис тупо не влезет.</p><p>Как говорится, <i>работает — не трогай.</i></p><p>Сейчас проект обзавелся сайтом-витриной и продолжает развиваться. В планах - искать и чинить новые баги. Перееду на более мощное железо, когда сервак начнет физически задыхаться.</p><p>Готов ответить на вопросы по архитектуре и послушать советы в комментариях \(^^)/</p><p><i>P.s. вот ссылка на первую статью о моём проекте: </i></p><p>P.s. Если кто-то хочет потестить вживую(не реклама), то юз бота в тг <a>@gdzshchelk_bot</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Git в Telegram: как я избавился от JSON, победил Markdown и получил security by design</title>
      <link>https://tproger.ru/articles/git-v-telegram--kak-ya-izbavilsya-ot-json--pobedil-markdown-i-polu</link>
      <comments>https://tproger.ru/articles/git-v-telegram--kak-ya-izbavilsya-ot-json--pobedil-markdown-i-polu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Robin Gad]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/git-v-telegram--kak-ya-izbavilsya-ot-json--pobedil-markdown-i-polu</guid>
      <description><![CDATA[<p>Git в Telegram? Без JSON, с SQLite, победой над Markdown и security by design. Код, схема БД, факапы и ссылка на бота.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/git-v-telegram--kak-ya-izbavilsya-ot-json--pobedil-markdown-i-polu">Git в Telegram: как я избавился от JSON, победил Markdown и получил security by design</a>»</p>]]></description>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[IBM]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Markdown]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 02 Jul 2026 06:39:38 GMT</pubDate>
      <content:encoded><![CDATA[<p>В своём Telegram-канале я время от времени предлагаю подписчикам выбрать очередную «бредовую» идею для реализации. На этот раз победил Git в Telegram: чтобы можно было инитить проекты, пушить файлы, коммитить — и всё это прямо в мессенджере.</p><p>С практической точки зрения проект на**й не нужен. Есть GitHub, GitLab и куча нормальных инструментов. Но как эксперимент — почему бы и нет? Чисто посмотреть, можно ли заставить Telegram работать как VCS.</p><h2>Почему не JSON</h2><p>На старте я думал: «Положу всё в JSON, на кой мне база данных?» Проектов мало, пользователей немного, файлы текстовые — чего заморачиваться?</p><p>Подергал JSON туда-сюда пару дней и понял: не варик.</p><ol><li>Конкурентный доступ. Два юзера одновременно коммитят — один перезаписывает файл другого.</li><li>Целостность данных. Если бот упал в середине записи — JSON остаётся в невалидном состоянии.</li><li>Версионность. Хранить историю изменений в JSON — это просто перенести проблему из кода в структуру файла.</li></ol><p>Вывод: JSON — для конфигов, а не для данных, которые меняются каждую секунду.</p><h2>Выбор SQLite и схема БД</h2><p>Выбрал SQLite, потому что:</p><ul><li>Не надо поднимать отдельный сервер</li><li>Целостность данных на уровне движка (транзакции, foreign keys, rollback)</li><li>Всё в одном файле — скопировал и унёс</li></ul><p>Сущности:</p><ul><li>users — telegram_id, username, current_project_id</li><li>projects — owner_id, name, thread_id (каждый проект живёт в своём треде канала)</li><li>files — filename, current_version, флаг modified (файл изменился и готов к коммиту)</li><li>file_versions — мясо. Каждая версия файла с полным содержимым. Привязана к file_id и опционально к commit_id</li><li>commits — сообщение, время, ссылка на проект</li><li>commit_files — связка коммитов с версиями файлов (many-to-many, чтобы поддержать ветки)</li></ul><p>Почему так: я хотел иметь возможность откатиться к любой версии любого файла. Да, база распухнет, но текстовые файлы — это не гигабайты видео. Плюс наличие file_versions и commit_files позволяет делать diff между версиями и смотреть историю изменений.</p><p>В коде вместо голых кортежей из SQL — датаклассы:</p><h2>Маркдауновый ад</h2><p>Казалось бы: взял код, обернул в тройные апострофы, кинул в Telegram. Telegram сам подсветит синтаксис, если указать язык. Красота. В теории.</p><p>На практике Telegram использует свой диалект Markdown, где куча служебных символов: _ * [ ] ( ) ~ &gt; # + - = | { } . !</p><p>Попытка 1: заэкранировать всё подряд. Результат: код превращается в кашу. Вместо<b> </b><i>def  __init__- </i> получается <i>def |_|_init|_|_ </i> — уже не запустишь, и в канале выглядит как говно.</p><p>Попытка 2: не экранировать вообще. Telegram шлёт на**й с ошибкой «can't parse entities».</p><p>Попытка 3: экранировать только то, что реально ломает разметку. Выяснилось, что порядок важен. Сначала экранируем точки и подчеркивания, потом обратную косую черту. Но и это не панацея — последовательности типа \*</p><p>после экранирования превращаются в \\*, и Telegram снова недоволен.</p><p>Попытка 4: разбивать на части. Для больших файлов делаю превью (первые 50 строк), экранирую их, отправляю как код, а полную версию — файлом. И тут начался ад: Telegram находил ошибки в тех частях кода, которых в превью вообще не было. Оказывается, он всё равно парсил полный код, даже если отправлялась только его часть.</p><p>Попытка 5 (финал): забил на Markdown и перешёл на HTML. Telegram умеет его принимать. Да, он не такой красивый, но зато предсказуемый:</p><p>Никаких точек, подчеркиваний, обратных слешей. Просто экранируем три символа — и код летит как надо.</p><h2>Security by design</h2><p>Когда бот начал обрастать функциями, я задумался о безопасности. Чтобы никто не мог коммитить или удалять чужие файлы, начал писать проверки в каждую команду:</p><p>Добавил в /commit. Потом решил с другого аккаунта потестировать команды на чужих файлах. И тут бот на каждую команду стал выдавать «файл не найден» или «проект не найден». И я понял: безопасность уже работает. С самого начала. Из коробки. Без единой строчки кода.</p><p>Как так вышло? В таблице projects с самого начала было поле owner_id. При создании проекта я писал туда telegram_id  владельца. Все запросы к БД фильтруются по этому полю:</p><p>Показать проекты — только свои. Найти файл — только в своих проектах. Выбрать проект — только из своих. Никаких лишних проверок. Просто SQL-запросы, которые с самого начала учитывали владельца.</p><h2>Команды: от семи до двух десятков</h2><p>Изначально казалось, что команд будет немного. Но...</p><p>Жизнь рассудила иначе.</p><ul><li>База: /start, /init, /use, /list, /ls, /commit, /log, /status</li><li>Удаление: /rm, /rmproject + подтверждение</li><li>Игнор: /ignore, /ignored, /unignore</li><li>Ветки: /branch, /branches, /checkout</li><li>Диффы и просмотр: /diff, /cat</li></ul><p>Итого — уже под два десятка. И это не предел.</p><h2>Простота &gt; абстракции</h2><p>В моём коде нет абстрактных базовых классов. Совсем. Потому что они нужны только когда у тебя есть минимум две разные реализации одного и того же. В GitGram всё проще: один способ работать с БД, один способ шифровать, один способ парсить .gitignore.</p><p>Если завтра появится вторая реализация — тогда и буду делать интерфейс. А пока это просто оверхед.</p><p>В GitGram:</p><ul><li>Хочешь понять, как работает add_file — идёшь в database.py и читаешь 10 строк кода.</li><li>Хочешь увидеть обработчик /commit — открываешь bot.py и смотришь.</li></ul><p>Никаких AbstractMinerShieldEventProcessor, BaseGitGramManager, InterfaceProviderFactory.</p><p>Код должен быть тупым. Чем тупее — тем проще его читать и отлаживать.</p><h2>Что дальше</h2><p>В планах:</p><ul><li>Докрутить коллаборацию (несколько человек над одним проектом)</li><li>Приватные репозитории</li><li>Кодспейс прямо в боте (да да знаю я сошёл с ума и бла бла бла..)</li></ul><h2>Итог</h2><p>GitGram принимает файлы, режет их на куски если надо, постит в канал с подсветкой. Коммиты ходят, ветки переключаются, диффы показываются. Всё это в тредах, каждый проект отдельно.</p><p>На практике GitGram ни к чему. Но сама задумка — Git в Telegram — это же так прикольно. Просто посмотреть, можно ли такое вообще запилить.</p><h2>Если хочешь поучаствовать</h2><ul><li><a href="https://t.me/Git_Gram/314" rel="nofollow">GitGram</a></li><li>Чат для хардкорных: <a href="http://t.me/sandbox_hardcore" rel="nofollow">@sandbox_hardcore</a> — вся сырая разработка, факапы и обсуждения (без цензуры)</li></ul><p>Подписывайся на мой <a href="https://t.me/+q0NBWy428y1hODEy" rel="nofollow">TГ-канал</a> — там я публикую все свои эксперименты, код и приглашаю к обсуждению. Только факты, мат и никакой политоты.</p>]]></content:encoded>
    </item>
    <item>
      <title>Бесплатный WAF инструмент кибербезопасности, который я использую</title>
      <link>https://tproger.ru/articles/besplatnyj-waf-instrument-kiberbezopasnosti-kotoryj-ya-ispolzuyu</link>
      <comments>https://tproger.ru/articles/besplatnyj-waf-instrument-kiberbezopasnosti-kotoryj-ya-ispolzuyu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Неопознанный программист]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/besplatnyj-waf-instrument-kiberbezopasnosti-kotoryj-ya-ispolzuyu</guid>
      <description><![CDATA[<p>Разбор бесплатного open-source WAF SafeLine для защиты от OWASP Top 10, DDoS и ботов. Сравнение с ModSecurity и Cloudflare по точности обнаружения атак, минимальные ложные срабатывания, простая установка одной командой Docker.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/besplatnyj-waf-instrument-kiberbezopasnosti-kotoryj-ya-ispolzuyu">Бесплатный WAF инструмент кибербезопасности, который я использую</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Unity]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[IBM]]></category>
      <category><![CDATA[Cloudflare]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[CSR]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Jul 2026 05:55:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Решения с открытым исходным кодом достигли такого уровня зрелости, что сегодня они действительно могут конкурировать с коммерческими продуктами — не только по функциональности, но и по удобству использования и поддержке сообщества. Если вы управляете собственной инфраструктурой, больше нет оправдания тому, чтобы оставлять дверь открытой для угроз.</p><p>SafeLine WAF — это бесплатный инструмент, который я лично тестировал.</p><p>Это полностью open-source решения, продукт с действительно бесплатной Community Edition, где ключевые функции не урезаны.</p><p><b>SafeLine WAF — веб-приложенийный межсетевой экран, который действительно поставляется с разумными настройками по умолчанию</b></p><p><b>Что он делает:</b></p><p>Защищает веб-приложения от SQL-инъекций, XSS-атак, командных инъекций, CSRF, SSRF, атак включения файлов и других угроз из списка OWASP Top 10. Также поддерживает защиту от CC/DDoS-атак, управление ботами и может работать как шлюз аутентификации.</p><p><b>Почему он:</b></p><p>Большинство WAF с открытым исходным кодом достаточно сложно настроить. Можно потратить часы на настройку правил, пытаясь остановить ложные срабатывания, из-за которых легитимные пользователи блокируются.</p><p>SafeLine использует другой подход — вместо того чтобы полностью полагаться на сигнатурное обнаружение, он применяет движок семантического анализа, который фактически анализирует и понимает входящие HTTP-запросы. Это позволяет добиться более высокого уровня обнаружения при значительно меньшем количестве ложных срабатываний по умолчанию.</p><p>Некоторые показатели, которые стоит учитыват</p><ol><li>Уровень обнаружения - SafeLine (Balanced) (71.65%), ModSecurity (Level 1) (69.74%), Cloudflare (Free) (10.7%)</li><li>Уровень ложных срабатываний - SafeLine (Balanced) (0.07%), ModSecurity (Level 1) (17.58%), Cloudflare (Free) (0.07%)</li><li>Точность - SafeLine (Balanced) (99.45%), ModSecurity (Level 1) (82.20%), Cloudflare (Free) (98.40%)</li></ol><p>Сбалансированный профиль SafeLine обнаруживает более 70% атак, при этом блокируя легитимный трафик ошибочно всего в 0.07% случаев. Это именно тот уровень настроек по умолчанию, который можно использовать в промышленной среде без постоянного ручного контроля.</p><p>Установка выполняется одной командой</p><p>После запуска он разворачивается как набор Docker-контейнеров: Tengine (форк Nginx) используется в качестве reverse proxy, отдельный сервис отвечает за семантический анализ, PostgreSQL хранит конфигурации и логи, а удобная веб-панель администратора работает на порту 9443.Community Edition поддерживает до 10 сайтов, чего достаточно для большинства личных проектов и небольших бизнес-сценариев.</p><p>Сайт: <a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fcodeby.net%2Fgoto%2Flink-confirmation%3Furl%3DaHR0cHM6Ly9jeWJlcnNlcnZhbC50ZWNoL2xhbmRpbmcvc2FmZWxpbmXvv7xHaXRIdWI%253D%26s%3D7008b60d8a0849ba0be350fe25edfa72&amp;postId=3005263" rel="nofollow noopener">https://cyberserval.tech/landing/safeline</a></p><p>GitHub:<a href="https://api.vc.ru/v2.8/redirect?to=http%3A%2F%2Fgithub.com%2Fchaitin%2FSafeLine&amp;postId=3005263" rel="nofollow noopener"> github.com/chaitin/SafeLine</a> (более 21 тыс. звёзд)</p><p>Лицензия: GPL-3.0 / MIT (Community Edition)</p>]]></content:encoded>
    </item>
    <item>
      <title>Как приручить legacy-код: безопасная модернизация без заморозки фич</title>
      <link>https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki</link>
      <comments>https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[KODE]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki</guid>
      <description><![CDATA[<p>Как модернизировать legacy-код без остановки продукта: Strangler Fig Pattern, feature flags, shadow testing и безопасная миграция данных. Практика и антипаттерны.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-priruchit-legacy-kod-bezopasnaya-modernizaciya-bez-zamorozki">Как приручить legacy-код: безопасная модернизация без заморозки фич</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Twitter]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[OpenTelemetry]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Legacy]]></category>
      <category><![CDATA[Техника]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 23 Jun 2026 06:16:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Legacy-код — одна из самых болезненных тем в инженерных командах. Обычно все понимают, что система устарела: архитектура мешает быстро выпускать изменения, новые фичи приходится встраивать через обходные пути, тесты либо неполные, либо отсутствуют, а любое изменение в одном модуле неожиданно ломает другой.</p><p>Но при этом к такому коду часто боятся прикасаться. И не без причины. В старых системах редко бывает понятная карта зависимостей. Документация устарела, часть знаний живет только в головах нескольких разработчиков, а бизнес при этом продолжает ждать новых релизов, интеграций и продуктовых экспериментов.</p><p>Так появляется классическая ловушка legacy: систему надо модернизировать, но остановить развитие нельзя. Переписать всё с нуля страшно, поддерживать как есть — всё дороже. В результате продукт обрастает временными решениями, скорость разработки падает, а стоимость каждого следующего изменения растет.</p><p>Хорошая новость в том, что модернизация legacy-кода не обязана быть большим взрывом. Старую систему можно менять постепенно, сохраняя рабочий продукт, не замораживая фичи и не устраивая один критический релиз, от которого зависит всё.</p><h2>Почему Big Bang-переписывание чаще всего заканчивается плохо</h2><p>Когда команда долго живет с устаревшей системой, идея переписать всё с нуля выглядит очень соблазнительно. Кажется, что можно наконец избавиться от технического долга, выбрать нормальную архитектуру, перепроектировать модули, покрыть всё тестами и начать «правильно».</p><p>На старте такой план часто звучит логично. Особенно если текущая система действительно мешает развитию. Например, мобильное приложение растет, у него уже миллионы пользователей, бэкенд написан несколько лет назад как монолит, а каждая новая фича требует изменений в десятке мест. Команда устала чинить регрессии, бизнес устал ждать, и всем хочется «один раз нормально переписать».</p><p>Проблема не в самой идее переписывания, а в условиях, при которых оно проваливается. Большой риск возникает, когда совпадают четыре фактора: переписывание занимает много месяцев, в это время бизнес продолжает развивать старую систему, новая версия покрывает сразу большую часть функциональности, а откат связан с миграцией данных. Если все четыре пункта присутствуют, Big Bang почти гарантированно превратится в долгий и дорогой проект.</p><p>Допустим, команда решила переписать модуль заказов в e-commerce-продукте. В старой версии есть корзина, промокоды, доставка и оплата. Команда планирует за полгода сделать новый сервис заказов. Но за эти полгода бизнес добавляет подписки, подарочные сертификаты, частичную оплату бонусами и новую логику возвратов. В итоге новая система, которую проектировали под старые требования, к моменту релиза уже нуждается в доработке.</p><p>Есть и другая проблема: большой релиз почти всегда несет максимальный риск. Если вы заменяете крупный кусок системы целиком, ошибка влияет сразу на большую часть пользователей. Откат тоже становится сложным, потому что новая логика уже связана с новыми данными, контрактами и интеграциями.</p><p>Big Bang всё-таки бывает оправдан — но в узких условиях. Если кодовая база молодая (год-два), пользователей мало, у системы нет критичного состояния в БД и продукт можно временно заморозить или вести в обоих контурах параллельно, полное переписывание может оказаться дешевле постепенной миграции. Это редкая ситуация, и она быстро исчезает по мере роста продукта. В зрелых системах безопаснее работает другой подход — постепенная архитектурная эволюция.</p><h2>Пример: как команда переписала сервис документов и потеряла полгода</h2><p>Команда сопровождала сервис — старый модуль на aiohttp с Pydantic v1, через который проходила вся обработка путевых листов и актов осмотра транспорта. Сервис существовал шесть лет, был покрыт тестами фрагментарно, а его API использовали мобильное приложение водителей, диспетчерская веб-панель и пакетный импорт.</p><p>Команда решила переписать сервис целиком: перейти на FastAPI, обновить Pydantic до v2, заодно почистить контракты и заменить внутреннее хранилище документов с MongoDB на PostgreSQL. План был рассчитан на четыре месяца.</p><p>Через восемь месяцев проект всё ещё не был готов к выкатке, а к десятому месяцу команда откатила миграцию полностью. Причин было несколько.</p><p>Во-первых, переписывание шло параллельно с продуктовой разработкой. За время миграции бизнес добавил два новых типа документов и изменил правила подписи актов. Новая система проектировалась под старые требования и к моменту готовности уже не соответствовала продукту.</p><p>Во-вторых, команда не написала характеристических тестов. Поведение «как есть» нигде не было зафиксировано, и расхождения находились только в продакшене после переключения.</p><p>В-третьих, у старого сервиса были скрытые побочные эффекты, о которых никто не помнил. При смене статуса документа публиковал событие в Kafka, которое читал биллинг и сервис аналитики. В новой реализации это поведение не было воспроизведено, потому что в коде оно выглядело как «лишний» вызов. После переключения биллинг перестал получать события, и расхождение обнаружили только через две недели — по жалобе финансового отдела.</p><p>В-четвёртых, переключение было сделано «в лоб»: маршрут в API Gateway просто перенаправили на новый сервис. Фича-флага не было, теневого запуска не было, плана отката не было. Когда выяснилось, что новый сервис строже валидирует исторические форматы документов и отклоняет часть старых записей, быстро вернуться на старую реализацию не получилось — её к тому моменту уже отключили на стенде, а в БД успели уйти записи в новом формате.</p><p>В итоге миграцию свернули, потратив около десяти человеко-месяцев и потеряв доверие бизнеса. Сервис до сих пор работает в исходной реализации, а команда переходит к плану, описанному ниже.</p><h2>Strangler Fig Pattern: как заменить систему по частям</h2><p>Один из самых практичных подходов к модернизации legacy-кода — Strangler Fig Pattern. В софтверном виде паттерн был сформулирован Мартином Фаулером в 2004 году под названием StranglerFigApplication. Идея проста: не переписывать систему целиком, а постепенно выносить отдельные части в новую реализацию.</p><p>Название пришло из биологии. Фикус-душитель растет вокруг дерева-хозяина и постепенно вытесняет его. В архитектуре принцип похожий: старая система продолжает работать, новая функциональность появляется рядом, а затем отдельные потоки постепенно переводятся на новую реализацию.</p><p>Представим старый монолит интернет-магазина. Внутри него есть каталог, корзина, заказы, платежи, скидки, личный кабинет и уведомления. Переписать всё сразу — рискованно. Но можно начать с относительно изолированного участка, например с уведомлений.</p><p>Сначала команда описывает текущий контракт: какие события приходят в модуль уведомлений, какие каналы используются, какие шаблоны отправляются, какие ошибки считаются допустимыми. Затем рядом создается новый сервис уведомлений, который реализует тот же контракт. На первом этапе он может даже не отправлять реальные сообщения, а только принимать события и логировать результат. После проверки часть трафика переводится на новую реализацию. Когда сервис стабилизируется, старый код уведомлений удаляется из монолита.</p><p>Strangler Fig хорошо работает там, где между старым и новым кодом есть сетевая граница: HTTP, message bus, RPC. Если такой границы нет — например, нужно постепенно заменить функцию или класс внутри одного процесса — используется родственный паттерн Branch by Abstraction: над старой реализацией создается абстракция, рядом пишется новая реализация, переключение происходит через конфигурацию или фича-флаг, после стабилизации старая ветка удаляется. Снаружи это выглядит как Strangler Fig, но без сетевого прокси.</p><p>Такой подход снижает риск. В системе нет одного большого релиза, где всё меняется сразу. Есть серия небольших контролируемых изменений. Каждое можно протестировать, измерить и откатить.</p><h2>Главное правило: сначала повторить поведение, потом улучшать</h2><p>Одна из частых ошибок при модернизации legacy-кода — попытка одновременно переписать систему и улучшить бизнес-логику. Команда смотрит на старый модуль и думает: «Раз уж мы его трогаем, давайте сразу сделаем нормальную архитектуру, изменим контракты, уберем странные кейсы и перепишем поведение».</p><p>Это опасный путь. В legacy-системах странное поведение часто существует не случайно. За ним может стоять неочевидное бизнес-правило, старый клиент, интеграция с внешней системой или исторический баг, на который уже кто-то завязался.</p><p>Например, в системе расчета налогов может быть правило: для контрактов, заключенных до 2018 года, НДС округляется в меньшую сторону до целого рубля, а для всех остальных — по математическим правилам. Новый разработчик может решить, что это ошибка, и «исправить» округление. Но потом выяснится, что часть крупных клиентов держит это поведение в своих сверках, а смена правила приведет к расхождениям в актах и претензиям.</p><p>Прежде чем менять поведение, его нужно зафиксировать. Для этого пишут характеристические тесты (characterization tests, иногда называемые golden master или approval tests). Идея простая: на реальных данных или их обезличенных копиях прогоняется старая реализация, её ответы сохраняются как эталон, и любые будущие изменения, отклоняющиеся от эталона, отлавливаются автоматически. Тесты пишутся не для красоты, а для того, чтобы зафиксировать существующее поведение — даже странное — перед тем, как его трогать. Подробно эта техника описана у Майкла Физерса в книге Working Effectively with Legacy Code; на практике её удобно реализовать через библиотеки семейства approval-tests (approvaltests-python, approvaltests-java и аналоги).</p><p>Поэтому первый этап модернизации — не улучшение, а воспроизведение текущего поведения. Новая реализация должна вести себя так же, как старая. Даже если старое поведение кажется странным. Только после стабилизации можно отдельно обсуждать, что именно стоит менять.</p><h2>Feature toggles: как включать новую логику без риска</h2><p>Feature toggles, или фича-флаги, — один из главных инструментов безопасной миграции. Они позволяют включать и выключать новую логику без деплоя.</p><p>В обычной разработке релиз часто выглядит бинарно: код либо выкатили, либо нет. При миграции legacy это неудобно. Гораздо безопаснее иметь возможность включить новую реализацию для 1% пользователей, затем для 10%, потом для половины аудитории и только после этого для всех.</p><p>Например, команда переносит расчет стоимости доставки из монолита в новый сервис. С помощью фича-флага это выглядит так:</p><p>user_id передается явно, чтобы решение «попал ли пользователь в новый сегмент» было стабильным от запроса к запросу. Иначе один и тот же клиент будет получать разные ответы при обновлении страницы, и поведение системы станет непредсказуемым.</p><p>На первом этапе флаг включают только для внутренней команды. Потом для тестового сегмента пользователей. Затем для небольшой доли реального трафика. Если метрики стабильны, долю увеличивают. Если появляются ошибки, флаг выключают, и пользователи снова идут в старую реализацию.</p><p>Важно различать два разных типа флагов. Флаг постепенной выкатки (rollout flag) меняется редко и контролирует, какой процент пользователей видит новую логику. Kill switch — отдельный флаг, единственная задача которого — мгновенно выключить новую реализацию при инциденте. Kill switch должен опрашиваться на каждом запросе, его кэширование должно жить секунды, а не минуты, и он принципиально не должен зависеть от той системы, которую он выключает. Иначе в момент аварии может оказаться, что выключатель сам недоступен.</p><p>В качестве инфраструктуры для флагов команды обычно берут одну из платформ: LaunchDarkly, Unleash, Flagsmith, GrowthBook, либо собирают собственную поверх Redis или конфигурационного сервиса. Для миграции важны три свойства: быстрое распространение изменений (секунды, а не минуты), поддержка таргетинга по пользователю/сегменту и аудит — кто и когда менял флаг.</p><p>Важно, что фича-флаг — это не просто if в коде. Для серьезной миграции нужны правила: кто может включать флаг, как быстро его можно отключить, какие метрики отслеживаются, когда флаг должен быть удален.</p><p>Последний пункт особенно важен. Если флаги не удалять, система быстро превращается в набор ветвлений, где никто уже не понимает, какая логика актуальна.</p><h2>Shadow testing: как проверить новую систему на реальном трафике</h2><p>Feature toggles помогают безопасно переключать пользователей. Но перед этим хорошо бы понять, совпадает ли новая логика со старой. Для этого используют shadow testing.</p><p>Shadow testing — это запуск новой реализации параллельно старой, но без влияния на пользователя. Пользовательский запрос по-прежнему обрабатывает старая система, а новая получает копию запроса и считает результат «в тени». Пользователю этот результат не показывается. Команда только сравнивает ответы.</p><p>Например, есть старый модуль расчета скидок. Он учитывает промокоды, сегмент пользователя, историю покупок, регион и партнерские условия. Команда пишет новый сервис скидок. Чтобы не переключать пользователей сразу, можно запустить теневой режим:</p><p>Два момента, на которые стоит обратить внимание в этом коде. Теневой вызов запускается через asyncio.create_task — корутина сразу планируется в event loop и начнёт выполняться, как только функция вернёт управление. И весь блок завернут в try/except: исключение в новой логике не должно ронять основной запрос. Без этих двух свойств shadow testing рискует ухудшить продакшен вместо того, чтобы безопасно его проверить.</p><p>Небольшая оговорка для продакшена: event loop держит на task только слабую ссылку, и без сохранённой ссылки задача может быть собрана сборщиком мусора прямо во время выполнения. В реальном коде Task имеет смысл класть в set фоновых задач и удалять оттуда через add_done_callback. В примере выше эта обвязка опущена для читаемости.</p><p>Для критичной доменной логики — платежей, биллинга, расчета тарифов — допустимый уровень расхождения должен быть около нуля: цель в shadow-режиме не «как можно меньше различий», а «понимаем каждое расхождение». Для менее чувствительных доменов (рекомендации, ранжирование результатов поиска) можно жить с расхождением в долях процента, но и там расхождения нужно классифицировать, а не игнорировать. Возможно, это баги новой реализации. А возможно, старая система содержит устаревшую логику, которую нужно отдельно обсудить с бизнесом.</p><p>Shadow testing особенно полезен для критичных доменных частей: платежей, биллинга, расчета тарифов, персональных предложений, транзакций. Там нельзя просто «попробовать на пользователях» и посмотреть, что будет.</p><p>При этом важно отличать теневую проверку чтения от теневой проверки записи. Чтение проверить относительно дёшево: запрос идёт в обе системы, ответы сравниваются, никаких внешних эффектов нет. С записью всё сложнее. Если новая реализация в shadow-режиме действительно создаст заказ, спишет деньги или отправит письмо, у пользователя возникнут двойные эффекты. Поэтому для writes либо вводят идемпотентные ключи и shadow-режим без реальных побочных действий (внешние вызовы заменены no-op-стабами, БД — отдельной shadow-копией), либо вообще отказываются от теневой проверки записи в пользу постепенной выкатки за фича-флагом.</p><p>Сравнение ответов в реальной системе тоже не сводится к одной функции compare. Нужно отдельно решать, как игнорировать «нормальный» шум (метки времени, идентификаторы, порядок коллекций), как сэмплировать трафик, чтобы не утопить хранилище расхождений, и как организовать триаж — кто и в каком ритме разбирает накопившиеся диффы. Готовые решения этого класса — GitHub Scientist (Ruby и его порты в другие языки), Twitter Diffy, либо собственный лёгкий регистратор поверх Kafka и таблицы расхождений.</p><h2>С чего начинать модернизацию</h2><p>Начинать лучше не с самого больного и не с самого центрального модуля. Это звучит контринтуитивно, потому что обычно хочется сразу взяться за главный источник проблем. Но если начать с ядра системы, команда быстро упрется в максимальное количество зависимостей и рисков.</p><p>Удобный способ выбрать первый кусок — оценить кандидатов по двум осям: насколько модуль критичен для бизнеса (low / high) и насколько сильно он связан с остальной системой (low / high). Начинать стоит с квадранта low-criticality + low-coupling: ошибки в нем не уронят бизнес-показатели, а малое количество зависимостей позволит провести миграцию полностью, не утянув за собой смежные модули. Высоко-критичные и сильно связанные части (платежи, ядро авторизации) трогают в последнюю очередь — на этот момент команда уже наберёт опыт безопасной миграции.</p><p>Хорошие точки входа обычно: уведомления, генерация отчетов, поиск, история операций, профиль пользователя, отдельная часть каталога. Важно, чтобы у команды была возможность описать контракт: какие данные входят, какие выходят, какие ошибки возможны, какие внешние системы участвуют.</p><p>Допустим, в банковском приложении есть старый модуль истории операций. Он медленный, сложно расширяется, но при этом не выполняет сами транзакции. Это хороший кандидат для первой миграции. Ошибка в истории операций неприятна, но обычно менее критична, чем ошибка в списании денег.</p><p>Команда может вынести чтение истории в отдельный сервис, сначала запустить его в shadow-режиме, потом включить для части пользователей, затем полностью перевести чтение на новую реализацию. При этом критичная транзакционная логика останется в старой системе до тех пор, пока команда не наберет опыт безопасной миграции.</p><h2>Миграция данных: самая сложная часть</h2><p>Большая часть статьи говорит о маршрутизации запросов и переключении трафика. Но в реальных проектах основная сложность лежит ниже — в данных. Старая и новая реализации почти всегда работают с общим состоянием: одной БД, одним хранилищем документов, одним набором очередей. Переехать туда «одним коммитом» нельзя.</p><p>Базовый рабочий приём — Expand-Contract (он же Parallel Change). Изменение схемы делается в три такта. На этапе expand в БД добавляются новые поля, таблицы или индексы, при этом старое поведение полностью сохраняется. Затем — migrate: обе реализации начинают писать и в старое, и в новое место (dual writes), а отдельный фоновый процесс делает backfill — заполняет новые поля историческими данными. После этого читатели по одному переключаются на новую схему. Только когда никто из читателей не использует старую структуру, наступает contract — удаление лишних колонок и таблиц.</p><p>Несколько практических деталей, которые часто упускают:</p><p>·         Dual writes — это не бесплатная операция. Две записи означают две точки отказа. Если одна из них упала, нужно решать, что делать: продолжать ли работу, ставить ли событие в очередь на повтор, помечать ли запись как несогласованную. Простое «сначала пишем туда, потом сюда» в продакшене на нагрузке приводит к расхождениям.</p><p>·         Backfill часто длиннее, чем кажется. На большой таблице миграция в одном UPDATE блокирует продакшен. Поэтому backfill делают батчами по N тысяч строк с паузами, отслеживают прогресс и предусматривают возможность остановить и продолжить.</p><p>·         Онлайн-изменения схемы на крупных таблицах делаются не штатным ALTER TABLE, а специализированными инструментами: gh-ost или pt-online-schema-change для MySQL, встроенные онлайн-механизмы PostgreSQL для индексов и колонок, Liquibase/Flyway — для управления версионированием изменений в репозитории.</p><p>·         Shadow testing данные не покрывает. Можно сравнить, что новая реализация возвращает то же, что и старая, но если за этим стоит другая схема в БД, проверка корректности самой миграции данных — это отдельная работа: сверки, контрольные суммы, выборочный аудит исторических записей.</p><p>Без этих шагов любая красивая фасадная архитектура наталкивается на разъезжающиеся данные — и тогда даже идеальный Strangler Fig снаружи не спасает.</p><h2>Прокси-слой как точка контроля</h2><p>Чтобы постепенно заменять legacy-код, нужно управлять маршрутизацией запросов. Для этого часто создают прокси-слой, API Gateway или фасад, через который проходит обращение к старой и новой логике. В терминах Domain-Driven Design такой слой часто называют Anti-Corruption Layer: он защищает новую реализацию от старых контрактов и наоборот, позволяя двум моделям сосуществовать без взаимного «загрязнения».</p><p>Без такой точки контроля миграция становится хаотичной. Часть клиентов ходит напрямую в старый модуль, часть — в новый, часть использует обходные пути, а команда теряет возможность централизованно переключать трафик.</p><p>Прокси-слой решает несколько задач. Он скрывает детали реализации от клиентов, позволяет направлять часть запросов в новую систему, поддерживает фича-флаги, собирает метрики и упрощает откат.</p><p>В качестве технической основы команды обычно берут один из трех вариантов: классический API gateway (Kong, AWS API Gateway), service mesh (Envoy, Istio) или более простой reverse proxy (NGINX, HAProxy). Service mesh особенно удобен, когда трафик уже идёт внутри Kubernetes-кластера: маршрутизацию можно менять конфигурацией, без правок кода клиентов и сервисов.</p><p>Например, мобильное приложение обращается к endpoint /orders/history. Раньше этот endpoint напрямую обслуживал монолит. После введения API Gateway приложение продолжает ходить по тому же контракту, но внутри gateway может решать, куда направить запрос: в legacy-модуль или новый сервис истории заказов.</p><p>Управление маршрутизацией обычно делается не «всё или ничего», а на основании атрибутов запроса: значения заголовка (X-Migration-Cohort: new), куки, хэша от user-id (стабильное разбиение пользователей на сегменты) или географического региона. Это позволяет выкатывать новую реализацию сначала на одну страну, на сотрудников самой компании или на тестовый сегмент — и только потом расширять охват.</p><p>Для клиента ничего не меняется. Для команды появляется управляемость.</p><h2>Наблюдаемость: без метрик миграция превращается в гадание</h2><p>Постепенная модернизация невозможна без нормальной наблюдаемости. Если команда не видит, что происходит внутри системы, она не сможет безопасно переключать трафик.</p><p>Минимальный набор — это логи, метрики и распределенная трассировка (distributed tracing). Нужно понимать, сколько запросов идет в старую и новую реализацию, сколько ошибок возникает, как меняется latency, где появляются таймауты, какие статусы возвращаются, какие бизнес-метрики проседают.</p><p>Технические метрики стоит формулировать не как «средний ответ» и «процент ошибок», а в терминах SLI и SLO: целевые показатели вида «99.9% запросов на /orders/history отвечают быстрее 300 ms за 30 дней» с явным error budget. Latency измеряется по перцентилям (p50, p95, p99) — среднее значение почти всегда обманчиво, а хвосты распределения говорят о реальном опыте пользователя. На время миграции имеет смысл выставить отдельные SLO для нового и старого пути и сравнивать их.</p><p>В качестве инструментов де-факто стандартом стал OpenTelemetry для трассировок, метрик и логов — единый протокол, который пишет в практически любое хранилище. Дальше — Prometheus и Grafana для метрик, Jaeger или Tempo для traces, Sentry или аналог для ошибок. Для миграции важна возможность фильтровать метрики по «варианту» — отдельно по старому и новому пути — иначе все цифры смешаются и реальную динамику будет не видно.</p><p>Технических метрик недостаточно. Если команда переносит оформление заказа, важно смотреть не только на 500 ошибки и время ответа, но и на конверсию в оплату, количество брошенных корзин, повторы запросов, обращения в поддержку.</p><p>Пример: новая система формально отвечает быстрее старой и не дает ошибок. Но после включения на 10% пользователей падает конверсия в оплату. Причина может быть не в серверной ошибке, а в изменении порядка полей, другом тексте сообщения или потере какого-то edge-case. Без бизнес-метрик команда может решить, что миграция успешна, хотя для продукта она уже создает проблему.</p><h2>Практическая последовательность миграции</h2><p>Рабочая последовательность обычно выглядит так.</p><p>Сначала команда выбирает ограниченный участок системы. На этом этапе важно не просто назвать модуль, а описать его границы. Какие сценарии он закрывает? Кто его вызывает? Какие данные он читает и пишет? Какие внешние интеграции использует? Какие неочевидные бизнес-правила в нем есть?</p><p>Затем поверх legacy-логики создается стабильный контракт. Это может быть API, фасад, gateway или отдельный слой внутри приложения. Главная задача — сделать так, чтобы клиенты зависели не от внутренней реализации, а от понятного интерфейса. На этом этапе полезно вспомнить про contract testing (Pact, Spring Cloud Contract): автотесты со стороны потребителей фиксируют, что именно они ожидают от API, и предупреждают о ломающих изменениях до того, как они доедут до продакшена.</p><p>После этого рядом пишется новая реализация. Она должна повторять текущее поведение, а не сразу становиться «идеальной версией будущего». На этом этапе полезно фиксировать все расхождения: где старая система работает странно, где требования не описаны, где бизнес-правила требуют уточнения.</p><p>Следующий этап — shadow testing. Новая система получает копии реальных запросов, считает результат, но пользователю по-прежнему возвращается ответ legacy. Команда сравнивает результаты и устраняет расхождения.</p><p>Когда новая реализация достаточно стабильна, начинается постепенное переключение через feature toggles. Сначала внутренние пользователи, потом 1% реального трафика, затем 5–10%, затем 50% и только после этого 100%.</p><p>На каждом этапе команда смотрит на метрики. Если всё стабильно, движение продолжается. Если появляются проблемы, флаг выключается, трафик возвращается в legacy, а команда разбирает причины.</p><p>Последний этап — удаление старого кода. Это не формальность, а обязательная часть миграции. И «удалить старый код» — это не один коммит, а явный Definition of Done: вырезана старая ветка кода, удалён фича-флаг, обновлена документация и схемы архитектуры, переименованы или удалены устаревшие дашборды и алерты, обновлены runbook’и для on-call и проведено короткое внутреннее обучение. Если этого не сделать, через полгода никто уже не вспомнит, какой путь актуален, и легаси-ветвление останется в коде навсегда.</p><h2>Откат миграций: дешёвый только пока не пошли записи</h2><p>Откатить миграцию, в которой ещё не было записи в БД, легко: достаточно переключить фича-флаг, и трафик снова идёт через старую реализацию. Откатить миграцию, в которой новая система уже неделю писала данные в новые таблицы, — отдельный, гораздо более тяжёлый разговор.</p><p>Поэтому ещё на этапе проектирования каждое изменение должно сопровождаться явным планом отката. Удобно различать три типа шагов.</p><p>Полностью обратимые шаги. Чтение через новый сервис, расчёт «в тени», новые метрики. Откат — выключить флаг. Это самый комфортный режим, и в нём стоит держать миграцию как можно дольше.</p><p>Обратимые с компенсацией. Новая реализация пишет дополнительные данные (например, дублирует операции в новую таблицу), но старый источник тоже обновляется. Откат возможен, но требует решить, что делать с уже записанными данными: оставить, очистить, синхронизировать. План этих действий должен быть написан до выкатки, не во время инцидента.</p><p>Forward-only. После некоторой точки откат становится невозможен — например, после того, как старая схема удалена или внешние интеграции перенастроены на новый сервис. Такие шаги допустимы, но к ним нужно приходить отдельно, осознанно, с особенно строгими SLO в предыдущем этапе. До forward-only-перехода имеет смысл подержать систему в режиме параллельной работы дольше, чем по графику.</p><p>Базовое правило: ни один шаг миграции не должен уходить в продакшен, если у команды нет письменного ответа на вопрос «как мы откатываемся в случае проблемы». Иначе при инциденте откатываться будут на ходу — и не факт, что успешно.</p><h2>Пример: как тот же сервис мигрировали со второй попытки</h2><p>После неудачного опыта команда взялась за тот же сервис заново, но изменила подход.</p><p>На первом шаге они зафиксировали поведение существующего сервиса. На самые часто используемые сценарии (создание путевого листа, подпись акта осмотра, выгрузка пакета документов за период) написали характеристические тесты на реальных продакшен-данных, обезличенных и сохранённых как фикстуры. Любое будущее изменение поведения теперь падало в CI как явное расхождение.</p><p>Параллельно команда провела инвентаризацию побочных эффектов. Из исходного кода и логов выяснилось, что сервис не только хранит документы, но и: публикует событие в Kafka при смене статуса, инкрементирует счётчик в Redis для рейтинга водителей, отправляет webhook во внешнюю систему партнёра, пишет в таблицу аудита. Каждый из этих эффектов попал в отдельный пункт чек-листа «что должно остаться» в новой реализации.</p><p>Затем команда выбрала первый кусок для выноса — не весь сервис, а только чтение документов (GET /documents/{id} и GET /documents/by-driver/{driver_id}). Это была наименее рискованная часть: ошибки в чтении неприятны, но не ломают финансовые потоки.</p><p>Новый сервис написали на FastAPI рядом со старым. На уровне API Gateway появилось правило маршрутизации: запросы на чтение шли в старый сервис, но в фоне дублировались в новый. Ответ пользователю всегда возвращал legacy, а ответ нового сервиса сравнивался с эталоном и записывался в отдельную таблицу для разбора. Использовали обёртку поверх asyncio.create_task — на ответ пользователя теневой вызов не влиял.</p><p>За три недели shadow-режима команда нашла четыре расхождения. Два оказались багами новой реализации (округление времени, неправильная сортировка вложений). Два — давно забытыми особенностями старого сервиса (одно поле возвращалось в UTC, другое — в локальной зоне; так было исторически, бизнес не возражал, но в новой реализации захотели единый формат). Все четыре зафиксировали явно: баги — починили, особенности — согласовали с продуктовой командой как осознанное изменение.</p><p>Когда расхождений не осталось, включили фича-флаг на сотрудников самой компании. Через неделю — на 1% реальных водителей. Дальше шаг по 5%, 25%, 50%, 100% с паузой в несколько дней между этапами. На каждом шаге следили не только за HTTP-ошибками и latency, но и за продуктовыми метриками: количество подписанных актов, время от открытия документа до подписи, доля повторных запросов. Один раз пришлось откатиться с 25% на 5% — в одном из регионов выросло время отклика из-за неэффективного запроса. Исправили, выкатили снова.</p><p>Через два месяца чтение полностью перешло в новый сервис. Старый код чтения и фича-флаг удалили в том же релизе. После этого по той же схеме мигрировали запись документов, потом публикацию событий, потом импорт из внешних систем. Полная миграция заняла девять месяцев — почти столько же, сколько провалившийся Big Bang, — но продукт всё это время продолжал развиваться, инцидентов не было, и в конце команда осталась с системой, которую понимает.</p><h2>Типичные ошибки при работе с legacy</h2><p>Первая ошибка — пытаться улучшить всё сразу. Команда одновременно меняет архитектуру, бизнес-логику, контракты и инфраструктуру. В результате становится невозможно понять, какая именно часть вызвала проблему. Правильнее сначала воспроизвести поведение, стабилизировать новую реализацию и только потом улучшать.</p><p>Вторая ошибка — недооценивать скрытые зависимости и побочные эффекты. Legacy-код часто делает больше, чем кажется. На один и тот же вызов могут быть навешаны: запись в таблицу аудита, инкремент счётчика в кэше, публикация события в очередь, обновление статуса связанной сущности, инвалидация кэша, дёрганье webhook’а во внешнюю систему. Если в новой реализации воспроизвести только явный путь, скрытые потребители молча перестанут получать данные — и узнают об этом через жалобу бизнеса, а не через ошибку в логах. Поэтому перед выносом любого модуля имеет смысл составить инвентаризацию побочных эффектов: пройтись по коду и логам и выписать каждое нелогичное действие отдельным пунктом чек-листа.</p><p>Третья ошибка — отсутствие наблюдаемости. Без логов, метрик и трассировки команда не управляет миграцией, а угадывает. Особенно опасно смотреть только на технические ошибки и игнорировать бизнес-показатели.</p><p>Четвертая ошибка — не договариваться с бизнесом. Модернизация не должна быть невидимой «инженерной активностью в стол». Её нужно встраивать в roadmap, объяснять эффект и договариваться о приоритетах. Если бизнес не понимает, зачем команда тратит время на миграцию, работа будет постоянно проигрывать новым фичам.</p><p>Пятая ошибка — не удалять старый код. Временное сосуществование старой и новой логики нормально. Вечное сосуществование — нет. Если legacy не удаляется, технический долг не уменьшается, а просто меняет форму.</p><p>Шестая ошибка — не удалять фича-флаги после миграции. Флаг, который сыграл свою роль и больше никогда не выключается, превращается в постоянное ветвление в коде. Через год команда не помнит, можно ли удалить такую ветку или там сидит важный edge-case. Через два — кода с такими «мёртвыми» флагами становится больше, чем основной логики. Поэтому каждый флаг должен заводиться с условием удаления («после полной выкатки и двух недель стабильной работы») и иметь ответственного, кто этим удалением займётся.</p><p>Отдельно стоит упомянуть организационную сторону. Закон Конвея работает и в обратную сторону: если новый и старый код владеются разными командами с разными приоритетами, миграция будет тормозиться независимо от выбранного паттерна. На время миграции имеет смысл явно проговорить, кто отвечает за переход, и не разделять старую и новую реализации между несовместимыми roadmap’ами.</p><h2>Компромиссы, к которым нужно быть готовыми</h2><p>Постепенная модернизация безопаснее Big Bang-переписывания, но она не бесплатна. Некоторое время система будет сложнее, чем раньше. В ней появятся старый и новый код, прокси-слой, фича-флаги, дублирование логики, дополнительные метрики.</p><p>Shadow testing увеличит нагрузку на инфраструктуру, потому что часть запросов будет обрабатываться дважды. Команде придется поддерживать дисциплину: документировать контракты, отслеживать флаги, удалять старую реализацию после миграции, поддерживать contract-тесты в актуальном состоянии.</p><p>Но это контролируемая сложность. Она распределена во времени и управляется инженерными практиками. В отличие от Big Bang-риска, где команда долго работает с минимальной обратной связью, а потом выкатывает один большой релиз с максимальной неопределенностью.</p><h2>Когда Strangler Fig особенно оправдан</h2><p>Постепенная миграция особенно хорошо подходит для систем, где downtime невозможен или слишком дорог. Это финтех, e-commerce, биллинг, мобильные бэкенды с большой аудиторией, высоконагруженные продукты, старые монолиты и системы с большим количеством интеграций.</p><p>Если продуктом ежедневно пользуются сотни тысяч или миллионы людей, нельзя позволить себе «переписать и посмотреть, что будет». Нужно менять архитектуру так, чтобы пользователь не замечал процесса миграции.</p><p>Этот подход также полезен там, где бизнес продолжает активно развивать продукт. Если фичи нельзя заморозить на полгода, модернизация должна идти параллельно с продуктовой разработкой.</p><h2>Когда модернизацию лучше не делать</h2><p>Постепенная миграция — мощный инструмент, но у неё тоже есть стоимость, и иногда правильный ответ — оставить систему как есть. Несколько сценариев, в которых модернизация плохо окупается.</p><p>Продукт, который уходит из эксплуатации. Если через год сервис будет выключен или заменён на покупное решение, тратить квартал на его рефакторинг бессмысленно. Достаточно стабилизировать то, что есть.</p><p>Модуль, который никто не трогает. Если код десятилетней давности продолжает работать, не падает, не требует изменений и не вызывает инцидентов, его «уродливость» — не повод его переписывать. Цель модернизации — упростить будущие изменения; если будущих изменений нет, цели тоже нет.</p><p>Регулируемые системы с тяжёлой ресертификацией. В банковских, медицинских и государственных контурах любое изменение в критичной системе может потребовать повторной сертификации, перепрохождения аудитов, обновления договорной обвязки. В таких условиях стоимость модернизации может на порядок превышать стоимость поддержки текущей реализации, и решение нужно принимать вместе с владельцем продукта и юристами, а не только инженерным составом.</p><p>Простой тест: если на вопрос «какой бизнес-сценарий мы откроем после миграции» нет внятного ответа — модернизацию имеет смысл отложить и заняться чем-то другим.</p><h2>Что получает команда</h2><p>Главный результат постепенной модернизации — управляемость. Команда начинает лучше понимать систему, контролировать изменения и снижать риск инцидентов.</p><p>Появляются понятные контракты, наблюдаемость, практика безопасных релизов, культура удаления старого кода. Разработчики перестают бояться legacy, потому что у них появляется метод, а не только желание «когда-нибудь всё переписать».</p><p>Для бизнеса это тоже выгодно. Продукт продолжает развиваться, сроки становятся более прогнозируемыми, риски крупных сбоев снижаются, а технический долг постепенно уменьшается.</p><h2>Модернизация — это процесс, а не проект</h2><p>Legacy нельзя «починить за квартал». Если система развивалась годами, она не станет простой после одного рефакторинга. Но её можно системно улучшать.</p><p>Strangler Fig Pattern, Branch by Abstraction, feature toggles, shadow testing и аккуратная миграция данных дают рабочую модель: выбрать ограниченный участок, описать контракт, реализовать новую версию, проверить её на реальном трафике, постепенно переключить пользователей и удалить старый код.</p><p>Это не самый быстрый путь. Зато он управляемый. А в зрелых продуктах управляемость важнее скорости.</p><p>Потому что цель модернизации — не написать красивую новую систему. Цель — сделать так, чтобы продукт продолжал развиваться, команда могла безопасно вносить изменения, а пользователи не становились участниками инженерного эксперимента.</p>]]></content:encoded>
    </item>
    <item>
      <title>Семь ошибок индексации БД, которые убивают производительность SaaS на корню</title>
      <link>https://tproger.ru/articles/sem-owibok-indeksacii-bd-kotorye-ubivayut-proizvoditelnost-sa</link>
      <comments>https://tproger.ru/articles/sem-owibok-indeksacii-bd-kotorye-ubivayut-proizvoditelnost-sa?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sem-owibok-indeksacii-bd-kotorye-ubivayut-proizvoditelnost-sa</guid>
      <description><![CDATA[<p>Разбираем 7 типичных ошибок индексации в PostgreSQL и MySQL: переиндексация, низкая селективность, раздутие индексов, мультитенантность и внешние ключи. Проверьте свою БД перед релизом.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sem-owibok-indeksacii-bd-kotorye-ubivayut-proizvoditelnost-sa">Семь ошибок индексации БД, которые убивают производительность SaaS на корню</a>»</p>]]></description>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[Масштабируемость и ограничения памяти]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 03 Jun 2026 05:30:09 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ваш код чист, архитектура продумана, а запросы на staging укладываются в 12 мс. Но при 500 000 записей всё встаёт: панели мониторинга тормозят, пользователи жалуются, а дежурный инженер в полночь разглядывает план выполнения запроса и не понимает, что пошло не так. В девяти случаях из десяти причина — не отсутствие индексов, а <b>неправильные индексы</b>.</p><p><b>Индекс в базе данных</b> — это вспомогательная структура (чаще всего B-дерево; хеш-индексы, GiST, GIN и другие типы применяются в узких специфических сценариях), которая ускоряет выборку строк по заданным колонкам. По аналогии с оглавлением книги: вместо перелистывания всех страниц СУБД сразу переходит к нужной главе. Но если оглавление построено плохо, пользы от него нет — а вот накладные расходы на поддержку остаются.</p><p>В этой статье разберём семь самых разрушительных ошибок индексации в production-SaaS: от параноидального создания индексов «на всякий случай» до игнорирования раздутия и особенностей мультитенантных схем. Каждая ошибка — с примерами SQL, метриками и конкретным фиксом.</p><p>Индексы — это налог на запись: каждый INSERT, UPDATE и DELETE обновляет все индексы таблицы.</p><p>Индекс на колонке с низкой селективностью (boolean, статус) почти бесполезен — используйте частичные (partial) индексы.</p><p>В составном индексе порядок колонок критичен: PostgreSQL может использовать (a, b, c) только если условие начинается с a.</p><p>Раздутые индексы на высокоизменяемых таблицах могут занимать в 8 раз больше места, чем нужно — планируйте REINDEX CONCURRENTLY.</p><p>В мультитенантных системах индекс по tenant_id один часто недостаточен: добавляйте диапазон времени или тип события.</p><p>Внешние ключи в PostgreSQL не индексируются автоматически — после каждого FOREIGN KEY создавайте индекс вручную.</p><p>Без EXPLAIN ANALYZE индексы создаются вслепую. Проверяйте реальный план выполнения перед деплоем.</p><h2>Ошибка 1. Индексировать всё подряд «на всякий случай»</h2><p>Самая распространённая ошибка — не недостаток индексов, а их избыток из тревожности. Особенно часто в неё попадают junior-разработчики: добавляют индекс на каждую колонку, которая встречается в WHERE, «на всякий случай». Кажется ответственным, но на самом деле вредно.</p><p>Каждый индекс — это налог на запись. При INSERT, UPDATE и DELETE PostgreSQL (или MySQL) вынуждена обновлять <b>все</b> индексы таблицы. На таблице с 8 индексами каждая запись трогает 8 структур данных. При низкой нагрузке это невидимо, но при 10 000 записей в минуту это становится узким местом.</p><p><b>Аудит неиспользуемых индексов в PostgreSQL:</b><br />Запрос к pg_stat_user_indexes покажет, сколько раз каждый индекс применялся с момента сброса статистики. Если idx_scan = 0 — индекс кандидат на удаление.</p><p>Не удаляйте индекс сразу — сначала убедитесь, что он не нужен для редких, но критичных отчётов. Но если он месяцами не используется, смело избавляйтесь.</p><h2>Ошибка 2. Не понимать селективность</h2><p>Индекс на булеву колонку — почти всегда бесполезен. <b>Селективность</b> измеряет, сколько различных значений содержится относительно общего числа строк. У boolean всего два значения. Если 95% строк имеют is_active = true, планировщик запросов проигнорирует индекс и сделает Seq Scan — и будет прав.</p><p>Правило большого пальца: если у колонки меньше 10–20 уникальных значений относительно размера таблицы, простой индекс по ней один не справится. Используйте частичные или составные индексы.</p><h2>Ошибка 3. Неверный порядок колонок в составном индексе</h2><p>Составные индексы мощны, но часто неправильно понимаются. PostgreSQL может использовать индекс (a, b, c) для фильтрации по a, a и b, a, b и c. Но <b>не может</b> эффективно использовать его, если запрос фильтрует только по b или c — ведущая колонка пропущена.</p><p>Решение: первыми ставьте колонки с equality-условиями, затем — по селективности, и проектируйте индексы вокруг <b>реальных паттернов запросов</b>, а не вокруг схемы таблицы. Также учитывайте ORDER BY и необходимость покрывающего индекса. Перед созданием обязательно запускайте EXPLAIN ANALYZE.</p><h2>Ошибка 4. Игнорировать раздутие индексов</h2><p>Индексы деградируют со временем. Многие инженеры воспринимают их как «поставил и забыл», но это заблуждение. В PostgreSQL при обновлении или удалении строки старые записи в индексе устаревают и накапливаются как <b>раздутие</b> (bloat); их физическое удаление происходит при выполнении VACUUM. На высокоизменяемых таблицах (заказы, события, логи, сессии) раздутие накапливается стремительно.</p><p>Таблица с 1 млн живых строк может иметь индекс, раздутый до размеров 8 млн записей. Каждый запрос через такой индекс делает в 8 раз больше работы, чем должен.</p><p><b>REINDEX CONCURRENTLY</b> — ключевое слово. Обычный REINDEX блокирует таблицу, а в production-SaaS это прямой путь к инциденту. CONCURRENTLY перестраивает индекс без блокировок, хотя и медленнее.</p><p>Также убедитесь, что autovacuum настроен под вашу реальную нагрузку на запись. Значения по умолчанию в PostgreSQL консервативны и часто недостаточны для SaaS с высокой интенсивностью записи.</p><h2>Ошибка 5. Индексы на колонках с малым числом уникальных значений в мультитенантных системах</h2><p>В мультитенантной архитектуре почти каждый запрос фильтрует по tenant_id. Естественное желание — проиндексировать эту колонку. Но для крупных тенантов индекс по tenant_id вернёт слишком много строк, и планировщик предпочтёт Seq Scan. Для маленьких тенантов отдельный индекс по tenant_id может быть полезен.</p><p>На серьёзном масштабе правильное решение — партиционирование таблиц по tenant_id, но это архитектурное решение. Практический первый шаг — составные индексы с временными диапазонами.</p><h2>Ошибка 6. Не индексировать внешние ключи</h2><p>В PostgreSQL внешние ключи <b>не индексируются автоматически</b>. При удалении родительской строки СУБД должна проверить все дочерние таблицы на наличие ссылающихся записей — и без индекса на внешнем ключе это Seq Scan по каждой дочерней таблице. На таблице orders с 50 млн строк удаление пользователя вызывает полное сканирование.</p><p>Сделайте это командным соглашением: в чек-листе миграций обязательный пункт «после каждого FOREIGN KEY — CREATE INDEX».</p><h2>Ошибка 7. Не использовать EXPLAIN ANALYZE перед деплоем</h2><p>Большинство решений об индексах принимаются интуитивно. Интуиция ошибается достаточно часто, чтобы это стало проблемой. EXPLAIN ANALYZE показывает, что именно делает планировщик: какие индексы использует, какие игнорирует, сколько строк реально прочитал против оценки, где тратится время.</p><p>На что обращать внимание:<br />• <b>Seq Scan</b> на большой таблице при выборке малой доли строк — возможно, пропущен индекс или планировщик не может использовать существующий индекс.<br />• <b>Rows Removed by Filter</b> в десятки тысяч — индекс есть, но неправильные колонки или низкая селективность.<br />• <b>Buffers: shared hit=0 read=45000</b> — данные не закэшированы (cold cache), страницы читаются с диска. Для диагностики раздутия смотрите общее число буферов и сравнивайте размер индекса с ожидаемым.<br />• Высокое <b>actual time</b> — проверьте раздутие, актуальность статистики, количество буферов, дисковую подсистему и наличие блокировок. Запустите ANALYZE tablename, чтобы обновить статистику планировщика.</p><h2>Чек-лист индексации для SaaS</h2><ul><li>У каждой колонки внешнего ключа есть индекс?</li><li>Составные индексы упорядочены по селективности, а не по удобству?</li><li>Булевы и низкокардинальные фильтры используют частичные индексы вместо полных?</li><li>Вы запускали EXPLAIN ANALYZE на 10 самых медленных запросов за неделю?</li><li>Есть процесс поиска и удаления неиспользуемых индексов?</li><li>Высокоизменяемые таблицы регулярно проходят REINDEX CONCURRENTLY?</li><li>Autovacuum настроен под реальный объём записи, а не под значения по умолчанию PostgreSQL?</li><li>В мультитенантных таблицах индексы начинаются с tenant_id и включают диапазон времени?</li></ul><h2>Выводы</h2><p>Индексы — не фича производительности, которую добавляют, когда всё начинает тормозить. Это проектное решение, которое принимается вместе со схемой, и пересматривается по мере эволюции паттернов запросов. Команды, которые уверенно масштабируются, — не те, у кого больше всего индексов, а те, кто понимает, что каждый индекс стоит, что даёт и когда его пора убирать.</p><blockquote>База данных, которая быстра на 10 000 строках и быстра на 50 миллионах, — не случайность. Это результат того, что кто-то считал планирование запросов первоклассной инженерной задачей, а не рутинным дополнением.</blockquote><p>Проверьте свои самые медленные запросы этой недели — возможно, одна из этих семи ошибок уже сидит в вашей production-базе.</p><p><b>Источник и материалы:</b><br />• <a href="https://dev.to/outworktech/database-indexing-mistakes-that-kill-saas-performance-at-scale-4j8e">Database Indexing Mistakes That Kill SaaS Performance at Scale</a> — оригинальная статья OutworkTech<br />• <a href="https://www.postgresql.org/docs/current/indexes.html">PostgreSQL Index Types</a> — официальная документация<br />• <a href="https://www.postgresql.org/docs/current/sql-reindex.html">REINDEX</a> — документация по перестроению индексов</p>]]></content:encoded>
    </item>
    <item>
      <title>OwnCloud – аналог Nextcloud: для чего использовать и как настроить облачное хранилище</title>
      <link>https://tproger.ru/articles/owncloud-analog-nextcloud-dlya-chego-ispolzovat-i-kak-nastroi</link>
      <comments>https://tproger.ru/articles/owncloud-analog-nextcloud-dlya-chego-ispolzovat-i-kak-nastroi?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Oksana Karelina]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/owncloud-analog-nextcloud-dlya-chego-ispolzovat-i-kak-nastroi</guid>
      <description><![CDATA[<p>ownCloud vs Nextcloud, что лучше? Какое облачное хранилище выбрать? Как может помочь связка S3 с ownCloud?
</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/owncloud-analog-nextcloud-dlya-chego-ispolzovat-i-kak-nastroi">OwnCloud – аналог Nextcloud: для чего использовать и как настроить облачное хранилище</a>»</p>]]></description>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Конференции]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[macOS]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Персональные данные]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 07 May 2026 08:40:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Вы когда-нибудь задумывались, сколько информации производит человечество?</p><p>Если верить статистике, сейчас ежедневно создается около <a href="https://explodingtopics.com/blog/data-generated-per-day">402,74</a> миллионов терабайт данных.</p><p>Согласитесь, довольно внушительная цифра.</p><p>В этих реалиях, когда объем данных постоянно растет, у каждого из нас рано или поздно может возникнуть вопрос – где хранить рабочие и личные файлы, да еще и так, чтобы сохранить абсолютный контроль над ними.</p><p>Меня зовут Оксана, я маркетолог в Beget и в этой статье хочу поделиться решением, которое мы выбрали у себя в отделе для хранения файлов, когда заметили, что их стало слишком много.</p><p>Мы решили перейти на гибкое объектное хранилище S3 – чтобы централизовано хранить и управлять текстами, креативами, отчетами и другими маркетинговыми материалами с удобным доступом внутри команды, ведь S3 позволяет хранить файлы любого типа и объема и масштабируется автоматически. Осталось только выбрать ПО для хранения файлов в облаке, к которому можно подключить S3.</p><p>Ранее у нас был опыт использования Nextcloud, однако его функционал, подобный швейцарскому ножу (встроенные календарь, конференции, таск-трекер и т. д.), оказался слишком объемен для нашей, по сути, скромной задачи – удобного и стабильного хранения файлов.</p><p>Вот почему мы подыскали аналог Nextcloud – ownCloud. В отличие от более функционального <a href="https://beget.com/ru/cloud/marketplace/nextcloud">Nextcloud</a>, ownCloud заточен исключительно на работу с файлами. И при этом он поддерживает подключение облачного объектного хранилища S3. Поэтому для нас в сравнении Nextcloud vs ownCloud выбор был очевиден.</p><p>В этой статье я расскажу, какие возможности есть у ownCloud, почему это ПО может быть полезно и как настроить связку ownCloud и S3. Если вы хотите организовать безопасное, контролируемое хранение и обмен данными на работе или дома, то этот материал будет для вас полезен.</p><h2>Что может ownCloud</h2><p>Для начала – буквально несколько слов об ownCloud и его возможностях.</p><p>Это программное обеспечение с открытым исходным кодом для хранения, синхронизации и обмена файлами появилось в 2010 году благодаря усилиям разработчика KDE Франка Карличека, который <a href="https://ru.wikipedia.org/wiki/OwnCloud">стремился</a> создать бесплатную альтернативу коммерческим облачным сервисам хранения данных.</p><h3>OwnCloud позволяет:</h3><ol><li>получать доступ к данным из любой точки мира и хранить файлы на собственном сервере – под вашим полным контролем;</li><li>синхронизировать данные между устройствами – доступ к файлам возможен с компьютеров (Windows, macOS, Linux), смартфонов (iOS, Android) и через браузер, изменения на одном устройстве мгновенно появляются на всех остальных;</li><li>делиться файлами и папками по ссылке, настраивая права доступа, пароли и срок действия ссылок;</li><li>совместно работать с документами, отслеживать историю изменений и возвращаться к любой предыдущей версии файла.</li></ol><blockquote>Только ownCloud сочетает в себе полный контроль над данными с простыми в использовании функциями обмена файлами, делая совместную работу более эффективной и безопасной.</blockquote><p>Сегодня ownCloud используют <a href="https://owncloud.com/customers/">компании</a> (Philips, Nationwide, Zeppelin и др.) в самых разных сферах (IT, машиностроение, медицина и т. д.).</p><p>При этом решение подходит не только для работы, но и для личных целей, когда нужно обменяться фото и видео с родственниками и друзьями, ведь, по мнению пользователей, среди преимуществ ownCloud – <a href="https://www.capterra.com/p/176602/ownCloud/reviews/">простота настройки</a> и <a href="https://www.temjournal.com/content/102/TEMJournalMay2021_954_960.pdf">удобная синхронизация с различными гаджетами</a>.</p><blockquote>С ownCloud мне не нужно слепо доверять какой-то неопределенной организации. Я контролирую, как происходит обмен файлами, и ownCloud помогает мне на каждом этапе.</blockquote><p>OwnCloud позволяет решать самые разные задачи, связанные с работой с файлами, – расскажем на примере трех кейсов, как это облачное хранилище помогает нам в отделе маркетинга.</p><h2>Для каких задач мы используем ownCloud и S3</h2><h3>1. Централизованное управление материалами</h3><p>Мы часто работаем с текстами, изображениями и презентациями. Дизайнеры и авторы загружают эти материалы в ownCloud, файлы автоматически сохраняются в S3, а для удобства поиска у нас настроены теги.</p><p>В итоге каждый член команды может видеть версии файлов (это важно для правок), нет хаоса в почте и мессенджерах.</p><h3>2. Безопасное взаимодействие с подрядчиками</h3><p>Связка ownCloud и S3 позволяет выгружать внешним специалистам материалы и получать результаты работ без прямого доступа к внутренней сети компании. Мы создали папку с публичной ссылкой, но жесткими ограничениями – паролем, сроком жизни ссылки в течение нескольких дней и разрешением на загрузку файлов без права просмотра папки.</p><p>На практике это работает так: менеджер создает ссылку и отправляет подрядчику, подрядчик переходит по ссылке и загружает архив с готовыми материалами, файл попадает в ownCloud, а его содержимое сохраняется в S3. Таким образом, подрядчик не видит, какие еще файлы лежат в папке, а мы контролируем, кто, что и когда загрузил.</p><h3>3. Долгосрочный архив креативов и отчетов</h3><p>По закону (152-ФЗ в РФ или GDPR в Европе) компания обязана хранить персональные данные клиентов, а также отчеты о рассылках и рекламных акциях на протяжении определенного времени.</p><p>Для решения этой задачи мы настроили правило: файлы старше 90 дней автоматически перемещаются в S3 Glacier (холодное хранилище) – этот класс снижает стоимость хранения, а если, например, юристу понадобится скачать какой-нибудь отчет спустя 2–3 года, он просто выгрузит его из ownCloud буквально за 5–10 минут.</p><p>Теперь – в деталях и по шагам о том, как начать использовать ownCloud в связке с S3.</p><h2>Как развернуть ownCloud и подключить S3</h2><p>OwnCloud удобно использовать с объектным хранилищем S3 – таким образом можно:</p><ol><li>масштабировать систему – S3 расширяется автоматически и не имеет ограничений по объему и количеству размещаемых данных и файлов;</li><li>оптимизировать затраты – можно платить не за дорогую конфигурацию виртуального сервера с большим объемом диска, а лишь за фактически занимаемое место, по модели pay as you go (оплата по мере потребления);</li><li>повысить надежность хранения – за счет встроенной в S3 тройной репликации данных (файлы хранятся в 3 копиях и размещаются на независимых серверах в разных стойках для абсолютной сохранности данных).</li></ol><h3>Итак, разберем, как настроить связку ownCloud и S3.</h3><p>Разработчики ownCloud предлагают два варианта установки. Можно скачать ownCloud и установить его вручную или использовать Docker-контейнеры. Мы выберем второй вариант.</p><p>Для размещения ownCloud в нашем примере создадим виртуальный сервер на базе <a href="https://beget.com/ru/cloud/marketplace/docker">готового решения Docker</a>.</p><p>Можно подключиться к серверу по SSH или с помощью терминала в панели управления.</p><p>Для размещения файлов создайте бакет объектного хранилища S3. Реквизиты доступа к нему будут в карточке бакета в панели:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/ee49d00b-7e32-4b8d-8ad4-bbbaeb0c3bb0.webp" alt="" /></figure><p>Создайте директорию для размещения конфигурационных файлов проекта и перейдите в нее:</p><p>Затем вставьте в файл docker-compose.yml следующее содержимое с помощью любого текстового редактора:</p><p>После этого создайте файл .env, в котором будут храниться значения переменных. Шаблон файла следующий:</p><p>Теперь необходимо отредактировать эти строки:</p><ol><li>ownCloud_DOMAIN и ownCloud_TRUSTED_DOMAINS – укажите домен (так как ownCloud будет размещен за обратным прокси, указывать рабочий порт здесь не требуется);</li><li>ADMIN_USERNAME – логин администратора;</li><li>ADMIN_PASSWORD – пароль администратора.</li></ol><p><i>Обратите внимание! Изменение ADMIN_USERNAME и ADMIN_PASSWORD уже после развертывания контейнеров не возымеет эффекта. Изменить пароль администратора вы можете в настройках пользователя в веб-интерфейсе.</i></p><p>Далее необходимо указать параметры подключения к S3.</p><ul><li>ownCloud_OBJECTSTORE_BUCKET – имя бакета S3;</li><li>ownCloud_OBJECTSTORE_ENDPOINT – эндпоинт хранилища (например, https://s3.ru1.storage.beget.cloud);</li><li>ownCloud_OBJECTSTORE_REGION – регион (ru1 для Beget);</li><li>ownCloud_OBJECTSTORE_KEY – Access key бакета;</li><li>ownCloud_OBJECTSTORE_SECRET – Secret key бакета.</li></ul><p>Сохраните файл.</p><p>Остается лишь добавить файл конфигурации для Caddy – обратного прокси, через который пользователи будут получать доступ к ownCloud.</p><p>Создайте директорию config:</p><p>После чего создайте в ней файл конфигурации Caddyfile. Добавьте в него следующее содержимое, указав вместо ownCloud.betutorial.ru ваш домен ownCloud:</p><p><i>Обратите внимание! Caddy выпустит SSL-сертификат на домен автоматически.</i></p><p>Все запросы к домену будут проксироваться в контейнер ownCloud_server.</p><p>На этом настройка конфигурационных файлов завершена, можно запускать контейнеры:</p><p>Потребуется несколько минут, чтобы docker загрузил образ и развернул контейнеры.</p><p>После запуска перейдите по домену, чтобы проверить работу хранилища:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/934faf67-2939-40f3-840e-88af18ebfde3.webp" alt="" /></figure><p>Выполните вход со стандартными доступами.</p><p><i>Обратите внимание! Если ownCloud недоступен или вы получаете ошибку при входе со стандартными доступами, проверьте корректность конфигурационных файлов. После внесения изменений перезапустите контейнеры.</i></p><p>После входа вы попадете на главную страницу ownCloud. Перед началом работы мы крайне рекомендуем сменить стандартный пароль администратора. Сделать это можно, нажав на кнопку с именем пользователя в верхней правой части страницы и открыв раздел настроек.</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/9f93c25a-3922-4223-b3bd-b45aaaf61edf.webp" alt="" /></figure><p>Теперь проверим работу объектного хранилища – перейдем на главную страницу и загрузим файлы:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/51a6e16f-ee9b-4e96-9a5c-7ef765f62286.webp" alt="" /></figure><p>Файлы также появились и в объектном хранилище:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/16e65ad7-28f9-462c-9af6-990d2cf3c878.webp" alt="" /></figure><p><i>Обратите внимание! Файлы, которые вы удалите в ownCloud, будут перемещены в корзину и останутся в S3. Для их полного удаления очистите корзину ownCloud.</i></p><p>Чтобы делиться паролями с новыми пользователями, необходимо настроить отправку почты в ownCloud, сделать это можно в разделе Settings&gt;General.</p><p>В нашем примере мы настроим отправку через SMTP:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/45e39a41-4bb1-4d19-9bfe-1e1db3afc4a6.webp" alt="" /></figure><p>После указания данных введите тестовый email и нажмите “Send email”. Если отправка успешна, вы получите уведомление об этом:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/5a22786d-3995-4e86-9b48-0a17363c8a18.webp" alt="" /></figure><p>А на почтовый ящик поступит письмо:</p><figure><img src="https://media.tproger.ru/user-uploads/105012/2026-04-29/f4043b49-9a17-42ed-a627-34502c2a16e8.webp" alt="" /></figure><p>На этом настройка завершена – можно начинать работать с файлами, используя связку ownCloud и S3.</p><h2>Заключение</h2><p>Если вы ловите себя на мысли, что данных стало настолько много, что поиск нужного файла порой происходит дольше, чем работа с ним (особенно если одни файлы хранятся на почте или в мессенджере, а другие – на ноутбуке или флешке), облачное хранилище может вам помочь.</p><p>Подобное ПО пригодится как для личных целей, так и для бизнеса – недаром в 2025 году в нашей стране был <a href="https://www.kommersant.ru/doc/8178724">зафиксирован</a> рост интереса крупного и среднего бизнеса к технологии облачного хранилища.</p><p>Надеюсь, эта статья была для вас полезна, а облачные хранилища помогут сделать ежедневную работу комфортнее.</p>]]></content:encoded>
    </item>
    <item>
      <title>Миграция 40-летней Clipper ERP: orphan-строки как способ выжить</title>
      <link>https://tproger.ru/articles/migraciya-40-letnej-clipper-erp-orphan-stroki-okazalis-ne-bagom</link>
      <comments>https://tproger.ru/articles/migraciya-40-letnej-clipper-erp-orphan-stroki-okazalis-ne-bagom?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/migraciya-40-letnej-clipper-erp-orphan-stroki-okazalis-ne-bagom</guid>
      <description><![CDATA[<p>Joseph Sprei мигрировал 40-летний Clipper ERP на PostgreSQL: 41К orphan-строк оказались не багом, а паттерном выживания. Разбираем три фазы расследования.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/migraciya-40-letnej-clipper-erp-orphan-stroki-okazalis-ne-bagom">Миграция 40-летней Clipper ERP: orphan-строки как способ выжить</a>»</p>]]></description>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 06 May 2026 15:45:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вам предстоит вытащить данные из старой системы и в новой схеме появятся orphan-строки (записи в дочерней таблице без родителя), не торопитесь чинить — возможно, это и есть нормальное состояние, к которому система пришла за десятилетия работы. Ровно с такой ситуацией столкнулся Joseph Sprei, мигрируя 40-летнюю Clipper ERP (Clipper — диалект xBase для DOS-приложений 80-90-х, использует .PRG-файлы исходников и .DBF-файлы данных) на Delphi и PostgreSQL. После первого прохода — 41 095 осиротевших строк деталей счетов и 4 160 платежей, у которых не было соответствующего заголовка, на общую сумму $872 609. Три фазы расследования показали: это не баг миграции и не косяк старого вендора, а сознательное поведение ERP, благодаря которому система прожила 40 лет на железе из 90-х.</p><p>Joseph Sprei, основатель Ask the Ledger (on-premise ERP для wholesale-дистрибьюторов), выложил подробный разбор кейса в блоге компании. Это редкая статья, где legacy-миграция раскрывается с архитектурной, а не «вот сколько строк мы переписали»-стороны: что в старом коде казалось багом, и почему это в реальности было механизмом выживания.</p><ul><li>Clipper ERP — 570 .PRG-файлов, четыре десятилетия .DBF-файлов, миллионы строк. После миграции на Delphi и PostgreSQL — 41 095 orphan-строк деталей счетов (1,36%) и 4 160 orphan-платежей (1,19%), $872 тысячи.</li><li>Расследование прошло три фазы: «это мы виноваты», «это старый вендор», и финал — «это и есть способ, которым система выжила 40 лет». Старый ERP периодически чистил заголовки счетов, но не каскадировал чистку в детали и платежи — и продолжал работать.</li><li>Из 570 .PRG-файлов реальный бизнес делают всего семь. Остальные — устаревшие отчёты, разовые утилиты, мёртвые эксперименты. Mapping использования по меню переломил план миграции куда сильнее, чем код-анализ.</li><li>AI ускорил «археологию» — сканирование 570 файлов, mapping программ к меню и DBF, выделение бизнес-правил, генерацию reconciliation-запросов. Но не заменил verification loop: каждый вывод подтверждался повторяемым SQL и cross-check архивов.</li><li>Финальный результат: PASS-with-known-exceptions. Orphan-данные приняли как permanent legacy condition с нулевым операционным влиянием на текущий бизнес. И перестали делать вид, что можно «починить» данные, которых больше нет.</li></ul><h2>Что такое orphan-строки и откуда взялись числа</h2><p>Orphan-строка — это запись в дочерней таблице (детали счёта, платёж), у которой нет соответствующего родителя в headers-таблице. Самый банальный SQL-запрос для проверки в PostgreSQL:</p><p>В цифрах кейса Sprei это 41 095 orphan-строк деталей из 3 012 516 (1,36%) и 4 160 orphan-платежей из 350 957 (1,19%). В деньгах: $530 833,66 «осиротевших» сумм по строкам ($124,5 млн оборота — 0,42%) и $341 775,36 по платежам ($115,4 млн — 0,30%). В процентах звучит мелко. В абсолютных числах — это «нам надо как-то объяснить почти миллион долларов несведёнки».</p><h2>Фаза 1: «мы виноваты»</h2><p>Команда исходила из того, что это дефект миграции. Прошлись по всему пайплайну:</p><ul><li>Trim и pad ключей (Clipper-индексы чувствительны к trailing-пробелам).</li><li>Порядок импорта — строки до заголовков? Заголовки до строк?</li><li>Маппинг файлов: не пропустили ли молча целую колонку?</li><li>Удалённые DBF-записи (Clipper помечает удаление флагом, не настоящим delete).</li><li>Перезапуск reconciliation после каждой правки.</li></ul><p>К третьему дню в таблице записей были «мёртвые гипотезы», и ни одна не объясняла orphan-числа. Pipeline жил.</p><h2>Фаза 2: «это старый вендор накосячил»</h2><p>Когда собственный пайплайн прошёл проверку, естественный шаг — посмотреть на тех, кто построил систему. Clipper использует двузначный год в именах таблиц, а сами имена — telegraph-style сокращения: AR — accounts receivable, дебиторка; MAST — master (заголовки), TRAN — transactions (строки), CASH — платежи. ARMAST99 — текущие заголовки счетов, ARTRAN99 — строки, ARCASH99 — платежи. Команда ожидала найти десятилетние архивы — ARMAST70, ARMAST80, ARMAST88, ARMAST98 — и в них найти orphan-headers.</p><p>Архивы оказались практически пустыми: ARMAST70 и ARMAST80 не существовали вообще, в ARMAST88 — три заголовка, в ARMAST98 — один. После импорта всех найденных архивов orphan-числа сдвинулись на жалкие +4 заголовка, +24 строки, +10 платежей. 41 095 и 4 160 остались на местах.</p><p>В этот момент картина перевернулась: команда не «не нашла историю», история была <b>сознательно отсечена</b>. Это и было следующей стадией расследования.</p><h2>Фаза 3: «это и есть способ выжить 40 лет»</h2><p>Sprei смотрит на диапазон номеров счетов в активной ARMAST99. MIN = 298 417, MAX = 3 462 381. Orphan-строки ссылаются на номера счетов <i>ниже 298 417</i> — без следа в архивах — и до 3 045 913. Получается, система периодически вычищала старые заголовки счетов из активной таблицы (видимо, чтобы держать .DBF-файл управляемого размера), но <b>не каскадировала чистку</b> в файлы строк и платежей. Транзакционные записи переживали свои заголовки.</p><p><i>Не чисто. Не современно. Но согласованно с системой, которая сорок лет продолжала отгружать товар, выставлять счета и собирать оплату на железе, начавшем жизнь в 90-х.</i></p><p>Sprei формулирует переход в одной фразе: «Я виноват. Старый вендор виноват. Нет. Это то, как система прожила 40 лет».</p><h2>Странности оказались не случайными</h2><p>С позиции современного greenfield-проекта вся Clipper ERP выглядит как набор анти-паттернов:</p><ul><li>VOIDED MM/DD/YY в operational-полях (например, в поле cust_no могла лежать пометка void).</li><li>Смешанные форматы дат в одной колонке (MM/DD/YY и YYYYMMDD одновременно — в зависимости от эпохи).</li><li>Referential integrity на уровне приложения, без foreign-key constraints в БД.</li><li>Денормализованные балансы, которые транзакционно поддерживаются в карточке клиента.</li><li>Periodic header purges — те самые, что и оставили orphan-строки.</li></ul><p>Sprei делает важный поворот: с точки зрения долгожительства это не анти-паттерны, а <b>адаптация</b>. Каждый из них был обходом ограничения, которого в современных системах нет — лимиты на размер файла, single-user lock индекса, дорогие диски, отсутствие нормальных бэкапов. Ограничения исчезли, обходы остались — потому что система продолжала работать.</p><h2>570 файлов, 7 значимых</h2><p>Кодовая база выглядела как 570-файловая гора. Команда грепнула исходники по menu-hooks (Clipper-меню вызывают .PRG-файлы по имени), отследила, какая программа из какого пункта меню вызывается, сверила с last-modified датами и паттернами обращения к DBF. Получилось, что за 570-файловым «костюмом» прячется бизнес из семи процессов:</p><ul><li>Ведение клиентов</li><li>Заведение заказов</li><li>Выставление счетов: route (счета по маршруту развоза, у дистрибьютора это типичный паттерн) и standard (обычные счета по заявкам)</li><li>Применение платежей</li><li>Корректировки склада</li><li>Приёмка по PO</li><li>End-of-day постинг</li></ul><p>Это перевернуло стратегию миграции: приоритет получили процессы с поведенческой массой, а не объём исходников. Остальные 563 файла — устаревшие отчёты, разовые утилиты вроде «отменить счёт», недоделанные фичи, эксперименты вендора. Тащить их в новую систему значило портировать код, к которому никто не прикасался последние пятнадцать лет.</p><h2>Чем помог AI и чем не помог</h2><p>Sprei отдельно выносит роль AI-инструментов в проекте — спокойно, без хайпа. AI ускорил <b>археологию</b>:</p><ul><li>Сканирование и обзор всех 570 файлов Clipper-исходника.</li><li>Маппинг программа / меню / DBF.</li><li>Выделение «кандидатов» на бизнес-правила из императивного процедурного кода — для верификации против современной реализации.</li><li>Скаффолдинг reconciliation-запросов и progress-документов.</li></ul><p>Чего AI <i>не</i> сделал — не заменил верификацию. Каждый вывод грунтовался повторяемым SQL, count-parity, range-проверками и доказательствами в архивах. Гипотезу о purge-паттерне нашли не потому что AI «увидел» это в коде, а потому что один и тот же запрос прогнали сорок раз с разными разрезами и в архивах увидели пустоту там, где ждали историю.</p><blockquote>AI был множителем на этапе генерации гипотез, но не оракулом. Дорогая часть legacy-миграции — это не чтение кода, а дисциплинированный verification loop, который ловит случаи, где поведение кода расходится с твоими предположениями.</blockquote><h2>Точка принятия решения</h2><p>У команды было два пути:</p><ul><li>Делать вид, что данные, которых больше нет, можно восстановить.</li><li>Квантифицировать ущерб, задокументировать риск и явно классифицировать ситуацию.</li></ul><p>Выбрали второй. Reconciliation отгружен с пометкой <b>PASS-with-known-exceptions</b>: 41 095 orphan-строк (1,36%, $530 тысяч) и 4 160 orphan-платежей (1,19%, $342 тысячи) приняты как постоянное legacy-условие с нулевым операционным влиянием на текущий бизнес. Активные клиенты, открытая дебиторская задолженность, текущие платежи — всё, что касается сегодняшней операционной деятельности — сходится идеально. Sprei формулирует развязку коротко: «мы перестали пытаться чинить данные, которых нет».</p><h2>Выводы</h2><p>Кейс Sprei показывает то, что редко звучит в отчётах о legacy-миграциях: данные, которые в новой схеме выглядят поломанными, в старой системе могут оказаться частью <b>дизайна выживания</b>. То, что снаружи похоже на anti-pattern, внутри 40-летней системы было экономически обусловленной адаптацией под несуществующие сегодня ограничения.</p><p>Главный методический вывод: миграция legacy ERP — не «переписать код», а <b>аудит того, как этот код прожил столько лет</b>. Перепись — последний шаг. Перед ним — usage mapping (на чём бизнес реально держится), forensics архивов (где история, а где её нет) и принятие того, что часть данных не восстанавливается даже теоретически.</p><p>Полный разбор и SQL-цифры — на <a href="https://asktheledger.com/blog/clipper-erp-migration-orphan-rows.html" rel="noopener">asktheledger.com</a>. Joseph Sprei — основатель <a href="https://asktheledger.com/" rel="noopener">Ask the Ledger</a>, on-premise ERP для wholesale-дистрибьюторов; за плечами — 30+ лет работы с line-of-business-софтом.</p>]]></content:encoded>
    </item>
    <item>
      <title>Denwer SE: Возрождение легендарного локального веб-сервера на современном стеке</title>
      <link>https://tproger.ru/articles/denwer-se-vozrozhdenie-legendarnogo-lokalnogo-veb-servera-na-so</link>
      <comments>https://tproger.ru/articles/denwer-se-vozrozhdenie-legendarnogo-lokalnogo-veb-servera-na-so?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Тишов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/denwer-se-vozrozhdenie-legendarnogo-lokalnogo-veb-servera-na-so</guid>
      <description><![CDATA[<p>Помните диск Z:, иконку джентльмена и магию Run.exe? Денвер вернулся. Denwer SE: Python вместо Perl, HTTPS без красных экранов, свежий PHP и портативность. И да, он всё ещё помещается на флешку.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/denwer-se-vozrozhdenie-legendarnogo-lokalnogo-veb-servera-na-so">Denwer SE: Возрождение легендарного локального веб-сервера на современном стеке</a>»</p>]]></description>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Для продвинутых]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[CMS]]></category>
      <category><![CDATA[Laravel]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 05 May 2026 10:11:34 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы начинали веб-разработку в середине 2000-х, то наверняка помните Denwer — «джентльменский набор веб-разработчика». Иконка в виде человека в шляпе, виртуальный диск Z:, папка <i>home/localhost/www</i> — всё это было ритуалом, который упрощал жизнь тысячам разработчиков. Но оригинальный Denwer безнадёжно устарел: Perl-скрипты, 32-битные сборки, поддержка только древних версий PHP и MySQL. Ему на смену пришли громоздкие комбайны вроде Open Server или сложные для новичков Docker-контейнеры.</p><p>Однако недавно проект получил второе дыхание. Разработчик Александр Тишов (Amro) — создатель <a href="https://seditio.org" rel="nofollow">CMS Seditio</a> и основатель веб-студии <a href="https://avego.org" rel="nofollow">«Авего»</a>  — выпустил <a href="https://seditio.org/dev/denwer-se-lokalnyj-veb-stek-dlya-windows-apache-php-mysql-mariadb" rel="nofollow">Denwer SE (Second Edition)</a>. Это не просто обновление, а полный реинжиниринг с сохранением классической философии: портативность, скорость работы и привычная структура каталогов.</p><p>В этой статье разберём, что изменилось под капотом, почему панель управления переехала с Perl на Python, как работает автоматический HTTPS с собственным корневым сертификатом и зачем нужен зоопарк версий PHP от 5.6 до 8.5.</p><h2>Краткий экскурс: от Denwer 3 до Denwer SE</h2><p>Оригинальный Denwer (сокращение от Джентельменский Набор Веб-разработчика) появился в начале 2000-х. Он представлял собой связку Apache + PHP + MySQL, упакованную в самораспаковывающийся архив. Главные фишки:</p><ul><li>Виртуальный диск (по умолчанию Z:), который монтировался через subst.</li><li>Автоматическое создание виртуальных хостов по именам папок в home.</li><li>Консольные exe-файлы (Run, Stop, Restart) без графического окна.</li></ul><p>Проблемы оригинала:</p><ul><li>Управление на Perl — медленно, тяжело поддерживать в Windows.</li><li>Только 32-битные компоненты.</li><li>Невозможно быстро переключать версии PHP или БД.</li><li>Отсутствие нормального HTTPS (только самоподписанные сертификаты с ошибками в браузере).</li><li>Поддержка прекратилась в 2016 году.</li></ul><p>Denwer SE решает все эти проблемы, оставаясь при этом таким же портативным — достаточно скопировать папку на флешку или в облачный каталог.</p><h2>Архитектура: Python вместо Perl</h2><p>Denwer SE — панель управления написана на Python и скомпилирована в один EXE-файл (через PyInstaller).</p><p>Внутри служебной папки <b>denwer\</b> лежат:</p><ul><li>DLL-версия Python — интерпретатор, который использует основной исполняемый файл.</li><li>Скомпилированные модули .pyd — в том числе GUI на базе Tcl/Tk для оконного интерфейса и системного трея.</li><li>Минимальный набор библиотек для управления службами, правки hosts и генерации сертификатов.</li></ul><p>Это даёт несколько преимуществ:</p><ul><li>Портативность — панель ищет соседние папки home и usr, поэтому каталог со стеком можно переносить куда угодно без переустановки.</li><li>Скорость — Python-скрипты запускаются быстрее, чем Perl, особенно на холодном старте.</li><li>Читаемость кода — разработчику проще поддерживать и расширять функционал.</li></ul><h2>Полный переход на x64</h2><p>Оригинальный Denwer навсегда остался 32-битным, что в современных реалиях просто неприемлемо. Denwer SE собирается исключительно под x64:</p><ul><li>Apache (версия 2.4.x) — 64-битный.</li><li>Все модули PHP (от 5.6 до 8.5) — Thread Safe x64.</li><li>MySQL / MariaDB — 64-битные сборки.</li></ul><p>Системные требования — Windows 7/8/10/11 (x64). Для работы компонентов потребуются Microsoft Visual C++ Redistributable (VC11, VC12, VC14, VC15). Разработчик положил установщики этих пакетов в папку <b>vcredist\</b> — при необходимости можно доустановить вручную.</p><h2>Структура каталогов: преемственность и гибкость</h2><p>Denwer SE сохранил классическую структуру, чтобы старые пользователи не ломали голову:</p><p>Главный конфиг — usr\configuration.txt. В нём задаются пути без жёсткой привязки к букве диска, например:</p><p>При старте панель монтирует виртуальный диск (по умолчанию Z:) и динамически подставляет путь через переменную <b>subst_drive</b>.</p><h2>Управление версиями PHP и БД без танцев с бубном</h2><p>В Denwer SE встроен менеджер версий. Вы просто выбираете из выпадающего списка нужную версию PHP (например, 8.3 или 5.6) — панель сама правит конфигурацию Apache.</p><p>Как это работает под капотом:</p><p>В папке usr/local/apache/php лежат подкаталоги php5.6, php7.4, php8.3 и т.д..</p><p>В каждом из них есть файл php-denwer.conf— шаблон для подключения модуля к Apache. При выборе версии этот файл копируется в <b>conf/extra/httpd-denwer.conf</b>, который затем включается в основной httpd.conf.</p><p>Если вы хотите добавить свою сборку PHP (например, PHP 8.4-rc), достаточно:</p><ul><li>Распаковать x64 Thread Safe версию в отдельный каталог внутри php\.</li><li>Создать php-denwer.conf по образцу.</li><li>Убедиться, что все DLL от VC++ установлены.</li></ul><p>Аналогично для баз данных: переключение между MySQL 5.7 и MariaDB 11.8 происходит через тот же интерфейс. В каталоге СУБД может лежать файл <b>db-denwer.conf</b>, который при старте копируется в <b>my.ini</b>.</p><h2>HTTPS, который не бесит: локальный Root CA</h2><p>Самое болезненное место при локальной разработке это самоподписанные сертификаты. Браузеры постоянно ругаются, приходится кликать «Принять риск». Для командной разработки это вообще катастрофа: каждый участник должен сгенерировать свой сертификат и добавить в исключения.</p><p>Denwer SE решает проблему элегантно — он создаёт собственный корневой центр сертификации (CA) и подписывает им сертификаты для всех ваших локальных доменов.</p><p>Как это работает:</p><ol><li>При первом запуске (если найден OpenSSL) панель генерирует ключи denwer-ca.key и сертификат denwer-ca.crt в папку usr/local/apache/conf/cert/denwer-ca/.</li><li>Для каждого виртуального хоста (папки в home/) автоматически создаётся сертификат в conf/cert/&lt;domain&gt;/.</li><li>Все сертификаты хостов подписаны локальным CA.</li></ol><p>Чтобы браузер доверял им, нужно один раз установить <b>denwer-ca.crt</b> в хранилище «Доверенные корневые центры сертификации» Windows. Для этого в панели есть специальная кнопка (требует прав администратора).</p><p>После этого любые HTTPS-запросы к локальным хостам работают без единого предупреждения.</p><h2>Удобства для разработчика (DX)</h2><p>В версии 1.2.4 добавили несколько фич, которые экономят время каждый день:</p><ul><li>Лог с таймштампами — каждая строка в окне панели имеет префикс [чч:мм:сс]. Теперь видно, сколько секунд сервер поднимается и где возможны задержки.</li><li>Прямой доступ к php.ini и my.cnf — рядом со списками версий появились кнопки, открывающие конфигурацию именно активной версии.</li><li>Автоматическое ведение hosts — панель в реальном времени сканирует home/, находит новые домены и прописывает их в C:\Windows\System32\drivers\etc\hosts. Журнал добавляемых записей сохраняется в usr\AddedHosts.txt. При остановке стека лишние строки удаляются.</li><li>Для смены версии PHP или базы данных панель требует полной остановки всех служб. Вы нажимаете «Стоп», меняете версию в списке, затем «Старт» — и стек поднимается уже с новыми настройками. Автоматический перезапуск без вашего участия работает только для Apache: когда вы добавляете новый домен в папку home/, панель сама переписывает vhosts.conf и перезапускает веб-сервер, не трогая БД.</li></ul><h2>Почему не Open Server или Docker?</h2><p>Этот вопрос закономерно возникает у всех, кто видит очередной локальный веб-сервер. Ведь есть уже давно Open Server Panel, Laragon, XAMPP, а для продвинутых — Docker. Зачем ещё один?</p><p><b>Open Server</b> — мощный и удобный комбайн с десятками версий PHP и настройками «на века». Но он разворачивается в системе не портативно: создаёт папки в ProgramData, пишет в реестр, а запуск может занимать 5–10 секунд. Denwer SE, напротив, полностью переносим: скопировал папку на флешку или в облачный каталог — и всё работает. Запуск стека — буквально 1–2 секунды, что критично, когда вы десятки раз за день перезапускаете сервер для тестов.</p><p><b>Docker</b> — индустриальный стандарт для изоляции и воспроизводимости окружений. Но для локальной разработки простого сайта он часто избыточен. Вам нужно разобраться в образах, контейнерах, пробросе портов, volume’ах и docker-compose.yml. А в Denwer SE вы просто создали папку в home/ — и готово. Никакой работы с командной строкой, никакого потребления гигабайт ОЗУ на фоновую службу Docker Desktop.</p><p><b>Laragon</b> — быстрый, портативный, поддерживает не только PHP, но и Node.js, Python, Go. Но он ориентирован на современные фреймворки, особенно Laravel. Denwer SE же сделан для тех, кто вырос на классическом Денвере: виртуальный диск Z:, папка home/имя_домена/www, минимум настроек. Не нужно переучиваться — просто распаковал и работаешь как 10 лет назад, но с новыми версиями PHP и HTTPS.</p><h2>Как начать пользоваться Denwer SE</h2><ol><li>Скачать архив с <a href="https://seditio.org/dev/denwer-se-lokalnyj-veb-stek-dlya-windows-apache-php-mysql-mariadb" rel="nofollow">официального сайта автора</a>.</li><li>Распаковать в любое место, например C:\web\DenwerSE\.</li><li>Запустить DenwerSE.exe — если нет прав администратора, попросит их для монтирования диска и правки hosts.</li><li>Нажать «Запустить» — появится виртуальный диск Z:, а в системном трее иконка.</li><li>Создать папку сайта — например, home\myproject.local и положить туда index.php.</li><li>Открыть в браузере http://myproject.local/ (или https://myproject.local/). HTTPS будет работать сразу после установки корневого сертификата (кнопка в панели).</li></ol><p>По умолчанию пароль к MySQL/MariaDB — пустая строка (пользователь <b>root</b>). При желании его можно сменить через phpMyAdmin.</p><h2>Заключение</h2><p>Denwer SE — это не просто ностальгический проект. Это действительно современный инструмент, который доказывает, что концепция «локального сервера в одну папку» всё ещё актуальна. Отказ от Perl в пользу Python, менеджер версий PHP/БД, нормальный HTTPS, портативность и мгновенный запуск — всё это делает его отличным выбором для быстрого прототипирования, тестирования легаси-кода или обучения веб-разработке.</p><p>Если вы устали ждать, пока Open Server применит настройки, или не хотите разбираться в Docker Compose — попробуйте <b>Denwer SE</b>. Вероятно, он напомнит вам старые добрые времена, но уже без боли устаревших технологий.</p><ul><li>Автор проекта: Александр Тишов
	(Amro), разработчик CMS Seditio.</li><li>Лицензия: Freeware.</li><li>Совместимость: Windows 7/8/10/11 x64.</li></ul><p>Исходники панели управления не открыты (распространяется скомпилированный EXE), но архитектура и конфиги полностью прозрачны. В планах — добавить поддержку Nginx в качестве альтернативы. Следите за обновлениями.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как я написал E2EE-мессенджер на Spring Boot и WebCrypto — и почему сервер не видит сообщения</title>
      <link>https://tproger.ru/articles/kak-ya-napisal-e2ee-messendzher-na-spring-boot-i-webcrypto-i-poch</link>
      <comments>https://tproger.ru/articles/kak-ya-napisal-e2ee-messendzher-na-spring-boot-i-webcrypto-i-poch?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Василенков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-ya-napisal-e2ee-messendzher-na-spring-boot-i-webcrypto-i-poch</guid>
      <description><![CDATA[<p>Разбор архитектуры E2EE-мессенджера на Spring Boot 3, React и WebCrypto: X3DH, symmetric ratchet, AES-GCM, WebSocket, multi-device и ограничения реализации.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-ya-napisal-e2ee-messendzher-na-spring-boot-i-webcrypto-i-poch">Как я написал E2EE-мессенджер на Spring Boot и WebCrypto — и почему сервер не видит сообщения</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Stack Overflow]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Алиса]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[5g]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Взлом]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 05 May 2026 05:35:02 GMT</pubDate>
      <content:encoded><![CDATA[<figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/240e412b-4307-49f9-b24f-bde7e0a7fd9a.webp" alt="" /></figure><p>Я Java-разработчик и в основном работаю с backend: Spring Boot, базы данных, интеграции, авторизация, WebSocket — всё то, что обычно находится за интерфейсом.</p><p>В какой-то момент я поймал себя на мысли: я каждый день пользуюсь мессенджерами, но плохо понимаю, как они устроены внутри. Окей, JWT, WebSocket, PostgreSQL, Redis — это понятно. Но что технически означает фраза "end-to-end encryption"? Как сервер доставляет сообщения, если он не должен их читать? Где живут ключи? Что хранится в базе? Что происходит, если у пользователя два устройства?</p><p>Решил разобраться через практику. Написал мессенджер с нуля. Назвал Chaos Messenger.</p><p>Сразу честно: криптографическую часть я изучал вместе с Claude и ChatGPT — читал спецификации X3DH и Double Ratchet, разбирал примеры, задавал вопросы, пока не сложилась цельная картина. Frontend тоже делался с активной помощью ChatGPT: я backend-разработчик, React для меня не основная среда. Но архитектура, backend, интеграция WebCrypto, модель конвертов, хранение сообщений и принципиальные решения — мои.</p><p>Для меня AI здесь был не заменой понимания, а инструментом — примерно как документация, Stack Overflow и ревью коллег. Без понимания threat model и архитектуры такой проект всё равно не собрать.</p><p>В статье расскажу, как работает E2EE изнутри: как устанавливается сессия через X3DH, как каждое сообщение получает отдельный ключ через Symmetric Ratchet, почему сервер хранит только зашифрованные конверты, и какие ошибки я допустил по дороге.</p><p>Стек: Spring Boot 3, React 18, WebCrypto API, PostgreSQL, Redis, WebSocket/STOMP, Prometheus, Grafana.</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/4b028f37-2de1-46ea-a247-567f74fb3081.webp" alt="" /></figure><h2>Важная оговорка про web-E2EE</h2><p>Когда я говорю, что сервер не может прочитать сообщения, я имею в виду backend, базу данных, WebSocket-слой и уже сохранённые ciphertext-конверты. У них нет ключей и plaintext.</p><p>Но у web-E2EE есть отдельная проблема: frontend-код тоже приходит с сервера. Теоретически скомпрометированный сервер может отдать изменённый JavaScript, который украдёт ключи или plaintext до шифрования. Это ограничение не конкретно моего проекта, а браузерной модели в целом.</p><p>Поэтому корректная формулировка такая: backend не получает ключи и не может расшифровать уже переданные или сохранённые сообщения. Защита от подмены клиентского кода — отдельный слой безопасности: подпись сборок, независимая верификация клиента, desktop/mobile-приложения, reproducible builds.</p><h2>Почему обычный подход не работает</h2><p>Большинство "мессенджеров" на GitHub выглядят примерно так:</p><p>Сервер знает всё. Видит каждое сообщение. Если БД утекла — утекла вся переписка. Если сервер взломали — читай что хочешь. Если завтра компания решит продать данные — технически ничего не мешает.</p><p>E2EE решает это радикально: backend не получает ключи и не хранит plaintext. Сообщение шифруется на устройстве отправителя до отправки в сеть, а расшифровывается только на устройстве получателя.</p><p>Это уже не вопрос политики конфиденциальности в стиле "мы обещаем не читать". Это архитектурное ограничение: если у сервера нет ключа, он не может превратить ciphertext обратно в текст.</p><p>Звучит как магия. На самом деле — два протокола и немного WebCrypto.</p><h2>Главная идея: конверты</h2><p>Представь что Алиса хочет написать Бобу. Вместо того чтобы положить письмо на стол и надеяться что никто не прочитает — она кладёт его в запечатанный конверт. Конверт может открыть только Боб своим ключом. Сервер просто передаёт конверт не заглядывая внутрь.</p><p>Именно так это работает в коде. В базе данных у меня это выглядит так:</p><p>Когда я впервые увидел</p><p>в своей БД вместо текста — стало понятно, что модель наконец работает правильно: сервер создал сообщение, доставил его, сохранил метаданные, но так и не узнал содержимое.</p><p>А вот что сервер возвращает при запросе списка чатов через API:</p><p>Не</p><p>. Не</p><p>. Буквально</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/b466ad91-20da-4e64-8b78-f6e08d2851d5.webp" alt="" /></figure><p>(DevTools → Network → ответ API с</p><p>)</p><h2>Откуда берутся ключи: X3DH</h2><p>Главный вопрос: как Алиса и Боб получают общий секрет, если они никогда раньше не общались? И как сделать это так, чтобы сервер только помог передать публичные данные, но сам не смог вычислить итоговый ключ?</p><p>Для этого используется X3DH — Extended Triple Diffie-Hellman, протокол из экосистемы Signal. Его задача — установить общий секрет между двумя устройствами, используя долгосрочные и временные ключи.</p><h2>Что хранится на сервере</h2><p>Когда пользователь регистрирует устройство, он загружает на сервер пакет публичных ключей:</p><p>На сервер уходят только публичные части. Приватные ключи сериализуются и хранятся локально в браузере — и никогда не покидают устройство в сеть.</p><p>Здесь важно сказать честно: хранение приватных ключей в</p><p>Более строгий вариант — использовать Web Crypto API с</p><p>, чтобы приватный ключ жил внутри браузерного crypto runtime и его нельзя было экспортировать в байты. Но у этого подхода есть практическая сложность: ключи нужно переживать между перезагрузками страницы, синхронизировать с IndexedDB, аккуратно восстанавливать состояние устройства и не сломать UX.</p><p>В браузерных E2EE-приложениях обычно приходится выбирать между несколькими вариантами:</p><ul><li>Сериализуемые ключи в localStorage или IndexedDB — проще реализовать, но нужно очень серьёзно относиться к XSS и целостности frontend-кода.</li><li>extractable: false + IndexedDB — безопаснее, но сложнее в реализации и восстановлении состояния.</li><li>Нативное secure storage вроде Android Keystore или iOS Secure Enclave — лучший вариант для мобильных клиентов, но он недоступен обычному web-приложению.</li></ul><p>В текущей версии Chaos Messenger используется первый вариант. Это осознанный компромисс для pet/open-source проекта и удобного запуска в браузере. Переход на non-extractable ключи и более строгую модель хранения стоит в roadmap.</p><p>Ключевой момент: backend всё равно не получает приватные ключи и не может расшифровать сохранённые ciphertext-конверты. Но защита ключей на клиенте — отдельная задача, и её нельзя честно замалчивать.</p><h2>Установка сессии</h2><p>Когда Алиса открывает переписку с Бобом впервые, происходит следующее:</p><p>В классическом X3DH четвёртая DH-операция с one-time prekey опциональна: она выполняется, если сервер выдал доступный OPK получателя. В моей реализации устройство публикует набор one-time prekeys при регистрации, поэтому первое сообщение обычно использует DH4. Если OPK закончились, сессию всё равно можно установить через остальные DH-компоненты, но это уже менее сильный вариант.</p><p>Боб, получив конверт с эфемерным публичным ключом Алисы, повторяет те же операции со своими приватными ключами и получает тот же самый</p><p>. Математика симметрична.</p><p>Сервер в этот момент видит только публичные ключи и зашифрованный конверт. Он помогает устройствам найти друг друга, но не участвует в вычислении секрета.</p><p>Получить</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/e7bbacf3-4fd2-4710-863a-2c710b1f6759.webp" alt="" /></figure><h2>Как шифруется каждое сообщение: Symmetric Ratchet</h2><p>X3DH даёт нам стартовый</p><p>. Но использовать один и тот же ключ для всех сообщений — плохая идея. Если использовать один ключ для всей переписки, компрометация этого ключа сразу открывает весь поток сообщений.</p><p>Решение — симметричный ratchet. После каждого сообщения цепочка ключей продвигается вперёд:</p><p>Визуально это выглядит так:</p><p>используется для шифрования одного сообщения через AES-GCM, после чего уничтожается. Если атакующий компрометирует</p><p>— он прочитает только второе сообщение.</p><p>В рамках такой симметричной цепочки это даёт forward secrecy назад по цепочке: зная текущий или отдельный</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/939a74f7-60c5-4816-85f0-05b5afdc9845.webp" alt="" /><figcaption>(диаграмма схемы chainKey → messageKey)</figcaption></figure><p>Само шифрование сообщения:</p><p>А вот что уходит на сервер — живой пример из DevTools:</p><p>Сервер получает</p><p>и</p><p>. Расшифровать без</p><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/b5e24cda-6fd9-4b15-9f27-3eb9b4f843b0.webp" alt="" /></figure><h2>Важная оговорка: это ещё не полный Double Ratchet</h2><p>В этом проекте реализован Symmetric Ratchet — цепочка, где из</p><p>для каждого сообщения выводится отдельный</p><p>Это защищает прошлые сообщения: если атакующий узнает текущий ключ или отдельный</p><p>, он не сможет откатить HMAC назад и получить старые ключи.</p><p>Но это не полный Double Ratchet из Signal Protocol.</p><p>В полном Double Ratchet есть ещё DH ratchet step: стороны периодически выполняют новый Diffie-Hellman обмен и обновляют root key. Это даёт break-in recovery — возможность восстановить безопасность будущих сообщений после компрометации части состояния.</p><p>В моей реализации DH ratchet step пока нет. Если атакующий получит актуальное состояние сессии на устройстве и сможет продолжать его читать, он сможет расшифровывать будущие сообщения до переустановки сессии. Это честное ограничение текущей версии, и оно стоит первым пунктом в roadmap.</p><h2>Мультиустройство: один пользователь, несколько конвертов</h2><p>Первый неочевидный момент: в E2EE сообщение адресуется не просто пользователю, а конкретным устройствам пользователя.</p><p>Если у Боба два устройства — телефон и ноутбук — нужен отдельный encrypted envelope для каждого устройства. Сервер не может взять один конверт, расшифровать его и "переупаковать" для второго устройства: у него нет ключей и он не знает plaintext.</p><p>Значит при отправке сообщения нужно зашифровать его отдельно для каждого устройства каждого участника чата.</p><p>Для чата где у каждого по 2 устройства — 4 конверта на одно сообщение. Для группы из 10 человек — потенциально 20 конвертов. Это нормально, это цена безопасности.</p><h2>Сервер: хранение и доставка конвертов</h2><p>На сервере сообщение создаётся с контентом</p><p>, а конверты сохраняются отдельно:</p><p>После сохранения — fanout по WebSocket. Каждое устройство получает свой конверт и только его:</p><p>Это важное отличие от обычного WebSocket-чата. В обычном чате сервер рассылает одно и то же событие всем участникам. В E2EE-чате сервер рассылает разные события разным устройствам: payload для каждого устройства содержит свой</p><p>Топик</p><p>— строго персональный. Устройство А не получает конверт устройства Б. Никакого broadcast — только адресная доставка.</p><h2>Архитектура целиком</h2><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/de0e3257-d893-459f-86ed-7ed8eace5d56.webp" alt="" /></figure><h2>Баг который долго не замечал</h2><p>В панели чатов показывается превью последнего сообщения. Я реализовал это через</p><p>Запускаю — в списке чатов у всех написано</p><p>.</p><p>Конечно. Сервер же не знает что там написано.</p><p>Я полчаса думал как решить это на сервере. Потом дошло: нельзя решить это на сервере — у него нет ключей. Решение только на клиенте.</p><p>После того как пользователь открыл чат и сообщения расшифровались — кешируем последнее в памяти:</p><p>Это хороший пример того, как E2EE меняет привычное мышление backend-разработчика. В обычном приложении preview — это поле в SQL-запросе. В E2EE-приложении preview — это локальное клиентское состояние, потому что только клиент видел plaintext.</p><p>Простое решение. Но чтобы к нему прийти нужно было полностью принять идею что сервер здесь просто не при делах — и перестать пытаться решить задачу на его стороне.</p><h2>Rate limiting: дыра которую легко не заметить</h2><p>Эндпоинт</p><p>отправляет SMS с кодом. Без защиты любой скрипт может дёргать его тысячи раз — это называется SMS pumping fraud, SMS стоят реальных денег.</p><p>Redis у нас уже был для хранения онлайн-статусов. Добавил rate limiting поверх него:</p><p>При превышении — HTTP 429 с заголовком</p><p>. Клиент знает через сколько секунд можно повторить.</p><p>Важный нюанс: в текущей реализации, если Redis недоступен, сервис не блокирует авторизацию полностью. Для pet-проекта это приемлемый компромисс: лучше рискнуть одним лишним SMS, чем положить вход в приложение.</p><p>В production я бы сделал строже: fallback in-memory лимит на инстанс, отдельные лимиты по IP и телефону, антифрод-логику и алерты на всплески отправки кодов.</p><h2>Авторизация WebSocket</h2><p>Отдельная история — авторизация WebSocket соединений. HTTP-эндпоинты защищены Spring Security автоматически, но WebSocket — другое дело. STOMP-соединение устанавливается один раз, и нужно проверять JWT при каждом подключении.</p><p>Отдельно важно не только проверить JWT, но и связать WebSocket-соединение с конкретным устройством. Пользователь может быть один, но устройств у него несколько, а encrypted envelope адресован именно</p><p>Поэтому при подключении я проверяю не только токен, но и</p><p>: устройство должно быть зарегистрировано и принадлежать текущему пользователю. Иначе легко случайно превратить per-device E2EE-доставку обратно в обычный broadcast по пользователю.</p><h2>Что получилось — живые скрины</h2><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/1fdfa006-f5c6-4731-a40f-50559be8832d.webp" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/137649/2026-04-29/c99164a5-021c-49ac-bcc4-3e38f9cd1c31.webp" alt="" /></figure><p>Что реализовано:</p><ul><li>E2EE-модель с per-device encrypted envelopes</li><li>X3DH session setup + Symmetric Ratchet + AES-GCM</li><li>Мультиустройство</li><li>Личные и групповые чаты</li><li>Realtime доставка через WebSocket/STOMP</li><li>Статусы SENT → DELIVERED → READ</li><li>Редактирование и soft delete сообщений</li><li>Online presence, typing indicator</li><li>Фото-вложения</li><li>Поиск пользователей</li><li>Rate limiting на SMS через Redis</li><li>Prometheus метрики + Grafana дашборд</li><li>Swagger UI с JWT авторизацией</li><li>24 backend-теста на Testcontainers, 12 frontend на Vitest, E2E на Playwright</li><li>GitHub Actions CI</li></ul><p>Что ещё не сделано:</p><ul><li>Полный Double Ratchet с DH ratchet step и break-in recovery</li><li>Ротация signed prekey и аккуратное пополнение one-time prekeys</li><li>Более строгая модель хранения приватных ключей на клиенте: non-extractable CryptoKey + IndexedDB</li><li>Защита от подмены frontend-кода: подпись сборок, независимая верификация клиента, reproducible builds</li><li>Android-клиент с Android Keystore</li><li>Реальный SMS-провайдер вместо кода в backend-логах</li><li>Push-уведомления без утечки содержимого сообщений</li><li>Более строгая metadata-модель для групповых чатов</li></ul><h2>Главный инсайт</h2><p>E2EE — это архитектурное решение, а не библиотека.</p><p>Нельзя взять обычный Spring Boot чат и просто "включить шифрование". Нужно с самого начала проектировать систему так, чтобы backend не был участником доверенной зоны: он не должен получать plaintext, не должен иметь ключи и не должен уметь пересобирать сообщение из данных в базе.</p><p>Это меняет почти всё:</p><ul><li>структуру БД — вместо текста появляются encrypted envelopes</li><li>API — сервер отдаёт [encrypted], а не preview сообщения</li><li>WebSocket — доставка идёт не по пользователю, а по конкретному устройству</li><li>мультиустройство — одно сообщение превращается в несколько ciphertext-конвертов</li><li>frontend — становится полноценной криптографической частью системы, а не просто UI</li></ul><p>Второй инсайт: мессенджер — это не "чат с WebSocket". В E2EE-модели это система доставки зашифрованных конвертов с адресацией по устройствам. Как только это принимаешь, многие странные на первый взгляд решения становятся логичными.</p><h2>Репозиторий</h2><p>Код открыт: <a href="https://github.com/vaazhen/chaos-messenger">github.com/vaazhen/chaos-messenger</a></p><p>В репозитории есть README на русском и английском, диаграммы, скриншоты, security audit, Docker Compose и запуск одной командой.</p><p>Проект не претендует на уровень production-криптомессенджера вроде Signal. Это учебный и инженерный open-source прототип, цель которого — показать, как E2EE меняет архитектуру backend, frontend и realtime-доставки.</p><p>Если вы делали что-то похожее — особенно интересно сравнить подходы к ротации prekey-ов, хранению non-extractable ключей в браузере и реализации DH ratchet step. Вопросы и критика приветствуются.</p>]]></content:encoded>
    </item>
    <item>
      <title>Posit выпустили ggsql — грамматику графики прямо в SQL-запросе</title>
      <link>https://tproger.ru/translations/posit-vypustili-ggsql-grammatiku-grafiki-pryamo-v-sql-zaprose</link>
      <comments>https://tproger.ru/translations/posit-vypustili-ggsql-grammatiku-grafiki-pryamo-v-sql-zaprose?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/posit-vypustili-ggsql-grammatiku-grafiki-pryamo-v-sql-zaprose</guid>
      <description><![CDATA[<p>Перевод анонса ggsql от Posit: синтаксис VISUALIZE/DRAW прямо в SQL, без R и Python. Разбираем scatter, histogram и boxplot одним запросом. Бэкенд — DuckDB.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/posit-vypustili-ggsql-grammatiku-grafiki-pryamo-v-sql-zaprose">Posit выпустили ggsql — грамматику графики прямо в SQL-запросе</a>»</p>]]></description>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 21 Apr 2026 15:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы визуализируете данные из SQL-запроса и каждый раз упираетесь в «экспортировать таблицу — открыть Python — подключить matplotlib», у вас есть повод попробовать другое. <a href="https://ggsql.org/" rel="noopener">ggsql</a> — расширение SQL от Posit, которое позволяет описывать график прямо в запросе: ключевые слова VISUALIZE и DRAW превращают таблицу в scatter, гистограмму или boxplot без промежуточного материализованного датафрейма.</p><p>20 апреля 2026 года <a href="https://posit.co" rel="noopener">Posit</a> (бывшая RStudio; компания поддерживает <a href="https://ggplot2.tidyverse.org/" rel="noopener">ggplot2</a> и <a href="https://www.tidyverse.org/" rel="noopener">tidyverse</a> — набор R-пакетов для анализа данных, созданный Хэдли Уикхемом) <a href="https://opensource.posit.co/blog/2026-04-20_ggsql_alpha_release/" rel="noopener">анонсировала</a> альфа-релиз ggsql. Внутри — почему SQL и «грамматика графики» хорошо сочетаются, разбор синтаксиса на примерах с пингвинами и астронавтами и планы на Rust-рендерер, интерактивность и LSP (Language Server Protocol — стандарт автодополнения и подсказок для IDE).</p><p><i>Грамматика графики (grammar of graphics) — теоретическая система, в которой любой график собирается из модульных частей: данные, аэстетические маппинги (что и на какую ось), геометрические слои (scatter, bar, line), шкалы и подписи. Подход описан в книге Лиланда Уилкинсона и доведён до практики в пакете ggplot2 Хэдли Уикхема.</i></p><ul><li>ggsql — SQL-расширение для визуализации: VISUALIZE + DRAW вместо отдельного пакета графики. Альфа-релиз, бэкенд — <a href="https://duckdb.org/" rel="noopener">DuckDB</a>.</li><li>Полный пайплайн от данных до слоя графика выполняется одним SQL-запросом на бэкенде: для bar-чарта из 10 миллиардов транзакций клиент получает только количество точек для каждого бара, а не сами 10 миллиардов строк.</li><li>Синтаксис — декларативный и композиционный: весь накопленный опыт ggplot2 перенесён в SQL-совместимую форму. Заменяете слой или маппинг — меняется график, без переписывания кода.</li><li>Не требует R или Python-рантайма: отдельный исполняемый файл проще встраивать в BI-инструменты и ИИ-агенты, проще изолировать от недоверенного кода.</li><li>Работает в Quarto, Jupyter-ноутбуках, Positron и VS Code. Документация и туториал — на <a href="https://ggsql.org/" rel="noopener">ggsql.org</a>.</li></ul><h2>Знакомство с ggsql</h2><p>Начнём с «hello world» визуализаций — обычной диаграммы рассеяния (scatterplot) на встроенном датасете penguins:</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-04-21/8a50e5b9-45c8-4038-a12f-571b16b22dc2.webp" alt="Scatterplot зависимости глубины клюва от его длины у пингвинов" /><figcaption>Первая визуализация на ggsql: scatter-чарт bill_len × bill_dep на встроенном датасете penguins (источник — Posit)</figcaption></figure><p>Запрос можно прочитать вслух и понять, что он делает. <i>Маппинг</i> — это связь столбца с визуальным свойством (в грамматике графики такие свойства называют <i>эстетиками</i>): x-координата, цвет, размер. Построчно:</p><ul><li>VISUALIZE открывает визуальный запрос и задаёт маппинги: x берётся из столбца bill_len, y — из bill_dep, данные — из встроенного датасета ggsql:penguins.</li><li>DRAW point добавляет слой с точками, который по умолчанию использует маппинг, заданный выше.</li></ul><p>Теперь начнём наращивать график. Добавим цвет по виду пингвина:</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-04-21/b0971a22-059e-4a1c-b944-041eaf874473.webp" alt="Scatterplot пингвинов с цветовой разбивкой по виду" /><figcaption>Один дополнительный маппинг — и точки окрашены по категории species</figcaption></figure><p>Одно изменение в маппингах добавило цветовую категоризацию. Эта постепенная эволюция кода графика — одна из главных сильных сторон грамматики графики: нет предопределённых типов графиков, есть модульные части, которые можно комбинировать, добавлять и убирать. Добавим сглаженную линию регрессии поверх точек:</p><p>Новый слой поверх точек наследует тот же маппинг. Так как цвет разбит по видам, сглаживание тоже посчитается отдельно для каждого вида.</p><p>Можно продолжать дальше — добавлять маппинги, менять слои местами, управлять шкалами, пока не получится нужный график. Например, если нас интересует распределение видов по трём островам, с которых собирали данные, код меняется минимально:</p><p>Совсем другой график — а большая часть кода осталась прежней.</p><h2>Полный пример</h2><p>С первыми графиками разобрались — переходим к полному примеру. Там будут новые элементы синтаксиса, но с ними тоже разберёмся. Пример адаптирован из <a href="https://www.jack-davison.com/" rel="noopener">визуализации Jack Davison для TidyTuesday</a>.</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-04-21/439352a9-f510-4621-93e9-a7251bb4f8af.webp" alt="Гистограмма возраста астронавтов при отборе и в момент миссии с аннотациями" /><figcaption>Полный пример: гистограмма возраста астронавтов + пунктирные линии средних + текстовые аннотации. Источник — блог Posit</figcaption></figure><p>Кода много, но он покрывает почти весь ключевой синтаксис сразу.</p><p>На верхнем уровне у запроса две части: SQL-запрос и визуальный запрос. SQL-запрос — всё, что идёт до ключевого слова VISUALIZE. Это обычный SQL (в примере есть CTE — общее табличное выражение в секции WITH, и DuckDB-специфичное QUALIFY, которое фильтрует оконные функции): ggsql принимает всё, что принимает ваш бэкенд. Результирующая таблица не возвращается как обычно, а уходит прямо в визуализацию. Любая CTE, созданная здесь, доступна в визуальном запросе.</p><p>SQL-часть необязательна. Если данные уже в нужной форме, можно указать источник прямо в VISUALIZE:</p><p>Теперь по визуальному запросу — всё, что идёт после VISUALIZE. Ключевое слово VISUALIZE отделяет SQL от визуального запроса (или VISUALISE для тех, кто предпочитает британское написание). Оно может стоять само по себе или задавать маппинги по умолчанию для всех последующих слоёв. Маппинг — это как SELECT, где вы привязываете столбцы к абстрактным визуальным свойствам (в грамматике графики они называются <i>аэстетики</i>).</p><p>В примере выше мы указали: столбец age хранит значения, которые пойдут в x (позиция по оси), а столбец category — значения, которые пойдут в fill (цвет заливки). Ничего про то, как это отрисовать, ещё не сказано.</p><h3>DRAW и PLACE: слои графика</h3><p>После VISUALIZE идёт DRAW — способ добавить слой. Типов слоёв в ggsql много. Одни простые — point для scatter. Другие сложнее — histogram (как в примере) требует посчитать производные статистики: биннинг и подсчёт количества в бинах. У визуализации может быть сколько угодно слоёв, они рендерятся в порядке объявления.</p><p>У DRAW есть родственная конструкция — PLACE. Работает так же, но данные берёт не из таблицы, а из заданных буквально значений. Это нужно для аннотаций. В примере выше три слоя: гистограмма с данными из таблицы, rule-аннотация с заранее рассчитанными средними для каждой категории и text-аннотация с поясняющими подписями.</p><p>Слой — это не обязательно одна графическая сущность. В text-слое выше рендерятся три отдельные подписи. То есть не нужно класть три отдельных line-слоя, чтобы нарисовать три линии разных категорий.</p><h3>SCALE: преобразование данных в визуальные значения</h3><p>После DRAW и PLACE идёт SCALE. Эта конструкция управляет тем, как значения данных переводятся в значения, осмысленные для аэстетики. В примере столбец category хранит строки Age at selection и Age at mission, которые сами по себе не являются цветом. Запись SCALE fill TO accent говорит ggsql взять палитру accent и сопоставить значения fill с цветами.</p><p>SCALE умеет больше: применять преобразования к непрерывным данным, задавать точки разбиения, выставлять тип шкалы (например, ординальную или бинную).</p><h3>LABEL: подписи осей и легенд</h3><p>Последняя конструкция визуального запроса — LABEL. Она добавляет или меняет текстовые подписи: заголовок, подзаголовок, подписи осей и легенд.</p><h2>Шаг назад: короткий синтаксис</h2><p>Два хороших известия. Во-первых, вы уже знаете основные элементы синтаксиса (есть ещё нюансы, но в них легко вырасти). Во-вторых, многие визуальные запросы будут гораздо короче полного примера. Например, <i>boxplot</i> (диаграмма-ящик с усами: показывает медиану, квартили и выбросы) года рождения астронавтов, разбитый по полу:</p><p>Коротко, но если вы приходите из другой системы построения графиков, может показаться, что это многословно. Скажем, по сравнению с условным boxplot(x, y) в других библиотеках. Да, длиннее — но также структурированнее, композиционнее и самодокументируемее. Эти свойства — прямое следствие грамматики графики, и они означают, что и вам, и вашему ИИ-ассистенту по коду будет проще понимать, как строятся графики любого типа. 18 лет доминирования ggplot2 в R-экосистеме — это свидетельство в пользу такого подхода.</p><p>Например, тот же график можно переделать в jitter-scatter (scatter со случайным смещением точек, чтобы они не слипались в одну категорию):</p><p>Или так, чтобы jitter следовал распределению данных и работал как violin-плот:</p><p>Синтаксис и композиционная природа делают итерации над визуализацией очень эргономичными — это важно и в разведочном анализе, и в дизайне графиков.</p><h2>Зачем ещё один инструмент визуализации</h2><p>Писать библиотеку визуализации с нуля — большая задача. Причин, почему Posit взялись за это снова, несколько:</p><ul><li>Хочется работать с аналитиками и data-сайентистами, которые живут в SQL.</li><li>SQL и грамматика графики хорошо подходят друг другу.</li><li>Хочется мощный code-based инструмент визуализации, который не требует целого языка программирования (R или Python).</li><li>LLM хорошо говорят на SQL — значит, и на ggsql заговорят.</li><li>18 лет разработки ggplot2 дали много опыта, который приятно применить к чистому листу.</li></ul><h3>Привет, SQL-пользователь!</h3><p>Пока R и потом Python забирали внимание в data-science-революции, SQL шёл своим ходом как надёжный рабочий инструмент. Есть много людей, которые работают с данными преимущественно или только через SQL. Варианты визуализации для них, по мнению Posit, субоптимальны:</p><ul><li>Экспортировать данные и перейти в R или Python, что может быть за пределами зоны комфорта.</li><li>Использовать GUI-ориентированный BI-инструмент, у которого плохо с воспроизводимостью.</li><li>Полагаться на немногочисленные инструменты для графики прямо в запросе — но они недостаточно мощные или эргономичные.</li></ul><p>Цель ggsql — чтобы синтаксис сразу был понятен SQL-пользователю, опирался на ожидания композиционных, декларативных конструкций.</p><h3>Декларативная обработка, декларативная визуализация</h3><p>Если читаете без знания SQL, краткое резюме: SQL — язык для манипуляции реляционными данными, хранящимися в одной или нескольких таблицах. Синтаксис опирается на концепцию реляционной алгебры — структурированного подхода к операциям над данными. Семантика описывает набор модульных операций, декларативных, а не функциональных, что даёт собирать мощные манипуляции из небольшого набора операций.</p><p>Если читаете без знания грамматики графики, краткое резюме: грамматика графики — теоретическая декомпозиция концепций визуализации на модульные части. Теория реализована в таких инструментах, как ggplot2. Семантика описывает набор модульных операций, декларативных, а не функциональных, что даёт собирать мощные и кастомные визуализации из хорошо определённого набора операций.</p><p>Из сравнения понятно: SQL и грамматика графики похожи в подходе к своим предметным областям. Вместе они дают естественное и мощное решение для полного конвейера от сырых данных до финальной визуализации.</p><h3>Без рантайма — не беда</h3><p>Почему важно, что ggplot2 требует R, а plotnine — Python? Отдельный исполняемый файл для визуализации удобнее:</p><ul><li>Встраивать небольшой бинарник в другие инструменты проще, чем таскать с собой R или Python.</li><li>Меньший scope проще изолировать и защищать от запуска вредоносного кода — случайного или намеренного.</li></ul><p>Оба пункта делают ggsql хорошим кандидатом на интеграцию с ИИ-ассистентами и code-based инструментами для отчётов, которые выполняют код в разных окружениях.</p><p>Отказ от интерпретируемого языка звучит как ограничение, но даёт выигрыш. Самое главное — жёсткая структура даёт выполнять весь пайплайн данных как один SQL-запрос на слой на бэкенде. То есть для bar-чарта на 10 миллиардов транзакций вы получаете с хранилища только количество для каждого бара, а не все 10 миллиардов строк. То же для boxplot и density-плотов. Это отличает ggsql от большинства инструментов, которые сначала материализуют все данные, потом считают на них, потом рисуют.</p><h3>LLM и ggsql: код без R и Python-рантайма</h3><p>LLM хорошо переводят естественный язык в SQL, и Posit уверены, что с ggsql будет так же. Свидетельство этому уже есть в <a href="https://posit-dev.github.io/querychat/" rel="noopener">querychat</a>, где данные можно исследовать визуально через естественный язык — как раз через ggsql. А так как ggsql — более лёгкий и безопасный рантайм, чем R или Python, с ним спокойнее отправлять код-агентов в продакшен.</p><h3>18 лет знаний о визуализации</h3><p>18 лет разработки и поддержки ggplot2 — это 18 лет размышлений про синтаксис визуализации, сценарии использования и дизайн. Posit считают, что это даёт им экспертизу в теме. При этом не весь накопленный опыт можно вернуть в ggplot2: там есть решения, принятые много лет назад, которые нужно поддерживать или менять очень постепенно.</p><p>ggsql — чистый лист. Не только в смысле «строим с нуля», но и в смысле «нет сложившихся ожиданий к инструменту визуализации». Для разработчиков это даёт свободу — и, как надеются в Posit, пользователю это тоже чувствуется.</p><h2>Планы: что будет дальше</h2><p>Альфа-релиз — значит, работа далеко не закончена. Вот короткий список того, что хотят добавить:</p><ul><li>Новый высокопроизводительный рендерер, написанный с нуля на Rust.</li><li>Инфраструктура тем.</li><li>Интерактивность.</li><li>Сквозной деплой-флоу от Posit Workbench/Positron до Connect.</li><li>Полноценный language server и форматтер для ggsql.</li><li>Поддержка геоданных.</li></ul><h3>Что это значит для ggplot2</h3><p>Если вы пользователь ggplot2, возможно, вы прочли всё это со смесью страха и радости. Значит ли это, что Posit бросают ggplot2 ради новой игрушки? Нет. ggplot2 сейчас зрелый и стабильный, его продолжат поддерживать и развивать. И надеются, что ggsql сможет вернуть часть накопленного опыта обратно в ggplot2, подсказывая новые возможности.</p><h2>FAQ</h2><h2>Выводы</h2><p>ggsql — попытка перенести 18 лет опыта ggplot2 на SQL-территорию и при этом снять привязку к рантайму R или Python. Для аналитика, который живёт в SQL, это шанс строить сложные визуализации, не выходя из запроса и не материализуя миллиарды строк ради bar-чарта. Для разработчика ИИ-ассистентов — повод ожидать, что LLM будут генерировать не только SQL, но и готовые визуализации прямо в нём.</p><blockquote>ggsql — чистый лист. Не только в смысле «строим с нуля», но и в смысле окружения, в котором нет сложившихся ожиданий к инструменту визуализации. Это даёт свободу, и, мы надеемся, это чувствуется в том, как ggsql работает в руках.</blockquote><p><b>Как попробовать.</b> На <a href="https://ggsql.org/" rel="noopener">ggsql.org</a> есть <a href="https://ggsql.org/docs/getting-started/" rel="noopener">Getting Started</a> с инструкцией по установке и первыми примерами. В Quarto и Jupyter ggsql подключается как отдельное ядро; в Positron и VS Code есть интеграция через расширение. DuckDB ставится отдельно, если у вас его ещё нет. Ограничений по географии для Posit Open Source нет — пакеты доступны через открытые репозитории.</p><p>Оригинал статьи: <a href="https://opensource.posit.co/blog/2026-04-20_ggsql_alpha_release/" rel="noopener">opensource.posit.co/blog/2026-04-20_ggsql_alpha_release</a>. Обсуждение на Hacker News — <a href="https://news.ycombinator.com/item?id=47833558" rel="noopener">news.ycombinator.com/item?id=47833558</a>. Попробовать и прочитать документацию — на <a href="https://ggsql.org/" rel="noopener">ggsql.org</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Индексы в Postgres: почему ваш индекс не работает и что такое INCLUDE</title>
      <link>https://tproger.ru/translations/indeksy-v-postgres-pochemu-vaw-indeks-ne-rabotaet-i-chto-takoe-in</link>
      <comments>https://tproger.ru/translations/indeksy-v-postgres-pochemu-vaw-indeks-ne-rabotaet-i-chto-takoe-in?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/indeksy-v-postgres-pochemu-vaw-indeks-ne-rabotaet-i-chto-takoe-in</guid>
      <description><![CDATA[<p>B-tree, композитные, функциональные, частичные, покрывающие индексы Postgres — разбираем на примерах, где lower() убивает индекс и когда реально нужен INCLUDE.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/indeksy-v-postgres-pochemu-vaw-indeks-ne-rabotaet-i-chto-takoe-in">Индексы в Postgres: почему ваш индекс не работает и что такое INCLUDE</a>»</p>]]></description>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 16 Apr 2026 15:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Ваш SELECT всё ещё тормозит, хотя вы добавили индекс? Вот три главные причины, почему Postgres его не использует: вы обернули колонку в lower(), перепутали порядок колонок в композитном индексе или полагаетесь на INCLUDE ради скорости записи. Индекс — это отсортированная структура, по которой база делает бинарный поиск вместо чтения всей таблицы. Но даже правильно созданный индекс легко выключить одной лишней функцией.</p><p>Джон Чартер в статье <a href="https://jon.chrt.dev/2026/04/15/things-you-didnt-know-about-indexes.html" rel="noopener">«Things you didn't know about indexes»</a> разбирает не только базовые принципы B-tree, но и три типа индексов, о которых новичкам не рассказывают: функциональные, частичные и покрывающие. Переводим полностью, с примерами на таблице покемонов и объяснением, почему EXPLAIN — ваш лучший друг.</p><p>Индексы ускоряют чтение, но замедляют запись. INSERT, UPDATE и DELETE обновляют каждый индекс — восемь индексов на таблице значат восемь дополнительных обновлений.</p><p>Композитный индекс (type_1, type_2) работает для запросов на type_1 и на обе колонки вместе, но не для запросов только на type_2. Порядок колонок важен.</p><p>Функция над индексированной колонкой убивает индекс. WHERE lower(name) = 'pikachu' не использует индекс на name — нужен функциональный индекс на lower(name).</p><p>Частичный индекс с WHERE покрывает только нужные строки. Для soft-delete или редких флагов экономит место и ускоряет запись.</p><p>Покрывающий индекс с INCLUDE отвечает на запрос без похода в таблицу — в EXPLAIN это Index Only Scan.</p><p>Не угадывайте — используйте EXPLAIN ANALYZE. Он показывает реальный план запроса и реальное время выполнения.</p><h2>Начнём с того, что вы, вероятно, уже знаете</h2><p>Индекс в базе данных похож на алфавитный указатель в конце учебника. Хотите найти страницы про фосфор? Идёте в конец, находите тему и номера страниц рядом с ней:</p><p>Представим таблицу покемонов:</p><p>Без индекса поиск Пикачу означает, что база прочитает каждую строку, проверяя колонку name. На четырёх строках это мгновенно. На десяти миллионах — уже проблема. Такое чтение называется full table scan, и оно не медленное само по себе: современные базы легко прошивают миллионы строк в секунду. Проблема в линейной сложности — удваиваете число строк, удваиваете время. Индексный поиск этой разницы почти не замечает.</p><p>Но если добавить индекс на name, получится примерно то же, что указатель в учебнике:</p><p>Данные отсортированы, поэтому база может сделать бинарный поиск по имени и найти нужную строку, а не сканировать всю таблицу. Под капотом Postgres хранит это как B-tree (сбалансированное дерево), но идея такая же, как в учебнике: отсортированные данные, по которым можно быстро искать.</p><p>Итак, индексируем всё подряд, верно? Не так быстро.</p><h2>Цена индексации</h2><p>Как бы ни хотелось проиндексировать всё, у индексов есть компромиссы. Главное правило:</p><blockquote>Чтение ускоряется, запись замедляется.</blockquote><p>С новым блестящим индексом каждый INSERT, UPDATE и DELETE должен обновить и индекс тоже. Когда мы добавляем нового покемона, база находит правильное место в отсортированном индексе имён и вставляет его туда. А индексов может быть несколько — умножайте эту работу на каждый из них.</p><p>Плюс индексы — это реальные структуры данных, и их нужно хранить. Они живут на диске и подгружаются в память: в Postgres это shared_buffers. У таблицы с восемью индексами девять объектов, которые конкурируют за буфер, а не один.</p><p>И не забываем про планировщик (query planner) — компонент, который перед каждым запросом оценивает варианты доступа к данным и выбирает самый дешёвый. Чем больше индексов, тем больше вариантов он взвешивает, так что время планирования растёт и на быстрых выборках может даже превысить время выполнения.</p><p><b>Отдельный риск на проде.</b> Обычный CREATE INDEX блокирует таблицу на запись до конца построения. На таблице в десятки миллионов строк это минуты недоступности. В production используйте CREATE INDEX CONCURRENTLY — он строит индекс без эксклюзивной блокировки, ценой чуть большего времени и того, что операция может быть прервана и оставить индекс в состоянии INVALID (который надо пересобрать).</p><h2>Почему ваш индекс не работает</h2><p>Вы взвесили компромиссы, решили, что индекс уместен. Отлично. Но он не работает как ожидалось: улучшения нет или, хуже того, скорость падает. Разберём типичные грабли.</p><h3>Композитные индексы и порядок колонок</h3><p>Возвращаясь к таблице покемонов: вы могли решить, что хороший индекс — это индекс на type_1 и type_2. «Покажи всех покемонов типа Water и Flying» — вполне разумный запрос.</p><p>Этот индекс определённо поможет запросам вроде:</p><p>Но вот этому — уже нет:</p><p>Удивлены? Когда вы создаёте композитный индекс (type_1, type_2), вы просите базу построить структуру примерно такого вида:</p><p>Сначала сортировка по type_1, затем по type_2 внутри каждой группы. Для запросов по type_1 индекс отличный, для запросов по type_1 AND type_2 — ещё лучше, но для запросов только по type_2 он не будет использован так, как вы надеетесь. Посмотрите на Flying: он разбросан под Bug, Electric, Fire и Water — базе некуда прыгнуть.</p><p>Задайте себе вопрос: какие запросы будут частыми? Если по type_2 вы будете искать так же часто, как по type_1, создайте второй индекс на type_2.</p><h3>Функции убивают индекс</h3><p>Поиск без учёта регистра — частая фича. Пользователям всё равно, пишут ли они «Pikachu», «pikachu» или «PiKaChU» — они просто хотят результат. Поэтому можно написать так:</p><p>Я бы не обратил на такой запрос особого внимания. Выглядит нормально. У нас есть индекс на name, запрос должен летать. Но, конечно, он не летает.</p><p>Почему? Индекс на name, а не на lower(name). Для базы это две совершенно разные вещи. Ваш индекс — это отсортированный список значений вида Bulbasaur, Charmander, Squirtle, Pikachu, а не bulbasaur, charmander, squirtle, pikachu. Так что когда вы просите строки, где lower(name) = 'pikachu', у базы нет отсортированной структуры для этого — и она откатывается к сканированию всей таблицы, приводя каждое имя к нижнему регистру по ходу дела.</p><p>Это касается любой функции, оборачивающей колонку. Если база не видит индексированную колонку слева от сравнения, индекс выбывает из игры.</p><p>И вот настоящие грабли: неявные преобразования тоже считаются. Классический пример — колонка user_id типа bigint сравнивается со строкой (WHERE user_id = '42') или timestamp сравнивается со строковой датой. Postgres тихо добавит приведение типа — и индекс работать перестанет с тем же эффектом, что и явная обёртка функцией.</p><p>Как обойти это? К счастью, можно построить индекс на выражении. Индекс на lower(name) абсолютно валиден, и запрос выше будет использовать его без проблем. К этому мы ещё вернёмся.</p><h3>Как избежать этих ловушек</h3><p>Короткий ответ: не гадайте. Измеряйте. Как? Спросите базу.</p><p>В Postgres есть инструмент EXPLAIN, который показывает, как именно база собирается выполнить запрос. Поставьте его перед любым SELECT — и получите отчёт:</p><p>Index Scan — это то, что вы хотите видеть. Значит, база использует индекс. Сравните с проблемным запросом:</p><p>Seq Scan значит, что читается каждая строка. Никаких индексов.</p><p>Если хотите реальные тайминги вместо оценок планировщика, используйте EXPLAIN ANALYZE. Он действительно запускает запрос и сообщает, что произошло. Попробуйте на запросе, который, как вам кажется, вы понимаете — результаты часто удивляют. А если Postgres тормозит не из-за индексов — у нас есть <a href="https://tproger.ru/articles/tormozit-postgres--12-wagov-diagnostiki" rel="noopener">12 шагов диагностики</a>, от pg_stat_activity до auto_explain.</p><h2>Чего вам не рассказывали</h2><p>Мы разобрали базовый индекс на одной колонке и его композитного брата. Вместе они покрывают большинство случаев. Но есть ещё несколько видов индексов, которые иногда оказываются именно тем, что нужно.</p><p><b>Сначала оговоримся про типы индексов в целом.</b> Всё, о чём мы пока говорили, — это B-tree, тип по умолчанию в Postgres. Но для нестандартных задач есть другие: GIN для jsonb и полнотекстового поиска, GiST для геоданных и диапазонов, BRIN для огромных таблиц с физически упорядоченными данными (логи, временные ряды), Hash для точного равенства. Ниже речь идёт именно о B-tree — но идеи функциональных, частичных и покрывающих индексов применимы и к другим типам.</p><h3>Функциональные индексы</h3><p>Мы затрагивали это в разделе про функции. Проблемный запрос был такой:</p><p>Индекс на name не помогает, потому что база ищет строки с lower(name) = ..., а отсортированной структуры для lower(name) у неё нет. Исправление — дать ей такую структуру:</p><p>Это функциональный индекс (его ещё называют индексом на выражении). Вместо того, чтобы индексировать сырую колонку, вы индексируете результат выражения, применённого к ней. Конечно, это не ограничивается lower(). Можно индексировать любое детерминированное выражение:</p><p>Годится любая функция с меткой IMMUTABLE — в Postgres это означает, что она возвращает одинаковый результат для одинаковых аргументов при любых условиях (в отличие от STABLE, которая детерминирована только в рамках одной транзакции, и VOLATILE).</p><p>Но осторожно. Если тянуться к функциональному индексу при первом же случае, это часто плохой запах. Если мы так часто ищем по имени в нижнем регистре, почему мы вообще не храним имя в нижнем регистре? Альтернативы: отдельная колонка name_lower, которую заполняете на вставке; тип citext (case-insensitive text) из одноимённого расширения; или COLLATE с регистронезависимой коллацией. Функциональный индекс — когда изменить хранение уже нельзя.</p><h3>Частичные индексы</h3><p>Большинство индексов покрывает каждую строку таблицы. Но иногда вы запрашиваете только её небольшой срез — и индексировать всё подряд расточительно. Напомню: индексы не бесплатны.</p><p>В нашей таблице покемонов есть колонка is_legendary. На момент написания существует около 1000 видов покемонов, из которых легендарными считаются всего 80 — меньше 10%.</p><p>Представьте приложение с опцией «показать всех легендарных». Изначально так и хочется создать составной индекс:</p><p>Это работает, но это перебор. Индекс теперь содержит запись для каждого покемона, а подавляющее большинство — не легендарные. Мы будем платить за хранение и запись 1000 строк, чтобы обслуживать запросы, которым интересны только 80. Более того, поскольку is_legendary — булево, получается структура, где сначала идёт разделение на False и True, и первая группа — это 920 записей мёртвого груза, оплачивающих свою долю каждой записи в таблицу ради запросов, которые их игнорируют.</p><p>Частичный индекс покрывает только строки, которые подходят под условие:</p><p>Теперь в индексе 80 записей вместо 1000. Он меньше, быстрее в запросах; а запросы вида WHERE is_legendary = true используют его без вопросов. Запросы, которые не подходят под условие (WHERE is_legendary = false), откатываются к full table scan — что вам и нужно. Эти запросы и так матчат почти каждую строку, так что индекс им не особо помог бы.</p><p>Любая колонка, где вы почти всегда запрашиваете одно значение, — кандидат на частичный индекс. Представьте индекс на колонке email в таблице users, где у вас реализован soft-delete:</p><p>Soft-deleted строки почти никогда не запрашиваются, но без фильтра всё равно раздували бы ваши индексы.</p><h3>Покрывающие индексы</h3><p>Когда база использует индекс, чтобы найти строку, это только половина работы. Индекс указывает, где строка лежит, но потом база должна сходить в саму таблицу и забрать остальные колонки, которые запросил запрос. Две поездки.</p><p>А что, если я скажу, что так делать необязательно?</p><p>Если в индексе уже есть все колонки, которые нужны запросу, база может ответить на запрос из одного только индекса. Это покрывающий индекс. В EXPLAIN вы увидите его как Index Only Scan — три самых сладких слова из возможного вывода EXPLAIN.</p><p><b>Одна важная оговорка.</b> Даже при Index Only Scan Postgres всё же заглядывает в visibility map — битовую карту, которая для каждой страницы таблицы отмечает, видимы ли все её строки всем активным транзакциям. Если страница «грязная» (были недавние UPDATE/DELETE), Postgres всё равно пойдёт в heap за проверкой MVCC. Так что на интенсивно пишущих таблицах регулярный VACUUM (автовакуум обычно справляется) критичен для того, чтобы Index Only Scan оставался «онли».</p><p>Вот запрос:</p><p>Наш частичный индекс из предыдущего раздела идеально покрывает этот запрос. Индекс на name, отфильтрованный по легендарным, — и запрос просит name легендарных. Всё, что нужно запросу, уже в индексе. Поход в таблицу не нужен.</p><p>Покрывающие индексы можно строить и специально. Postgres позволяет добавить к индексу дополнительные колонки через INCLUDE:</p><p>Теперь на такой запрос можно ответить прямо из индекса:</p><p>Почему не положить base_attack прямо в индексируемые колонки? Потому что база считает индексируемые колонки тем, по чему нужно сортировать и искать. Если добавить base_attack в ключевые колонки индекса, вы скажете базе сортировать индекс сначала по name, потом по base_attack — дополнительная работа, которая не нужна, если вы ищете только по name. INCLUDE говорит: «тащи эту колонку с собой, но не морочься сортировкой».</p><h3>Правка автора: когда на самом деле нужен INCLUDE</h3><p>В комментариях на Reddit автор получил поправку от <a href="https://www.reddit.com/user/therealgaxbo/" rel="noopener">u/therealgaxbo</a> и обновил статью. Скорость записи — не главная причина использовать INCLUDE для покрывающих индексов: в обоих случаях (колонка в ключе или в INCLUDE) индекс обновляется при каждой записи, разница по нагрузке скромная.</p><p>Реальные причины использовать INCLUDE:</p><p>Можно включать колонки, у которых типы данных не имеют подходящего operator class для типа индекса (operator class — набор функций сравнения, по которым Postgres строит индекс для конкретного типа; для некоторых типов он просто не определён). Например, колонку box (геометрический прямоугольник) нельзя добавить в B-tree индекс как ключевую — нет оператора «меньше/больше». А через INCLUDE можно.</p><p>Можно добавить колонки в уникальный индекс без изменения его семантики уникальности:</p><p>Это обеспечивает уникальность только по email, но при этом покрывает запросы, которым нужен user_id.</p><h2>Выводы</h2><p>Индексы могут казаться новичку чем-то второстепенным. Даже опытные инженеры часто создают их не задумываясь или не создают вовсе. Но грамотная индексация делает или ломает производительность вашей базы.</p><p>Хотите глубже? Сайт <a href="https://use-the-index-luke.com/" rel="noopener">Use The Index, Luke</a> научит вас всему, что только можно знать про индексы в разных СУБД. А если вы только начинаете с Postgres — загляните в наши <a href="https://tproger.ru/articles/osnovy-postgresql-dlya-nachinayushhih--ot-ustanovki-do-pervyh-zaprosov-250851" rel="noopener">основы PostgreSQL</a>: от установки до первых запросов.</p><p>И не забудьте запустить EXPLAIN ANALYZE хотя бы на одном запросе сегодня — результаты могут вас удивить.</p><p>Источник: <a href="https://jon.chrt.dev/2026/04/15/things-you-didnt-know-about-indexes.html" rel="noopener">jon.chrt.dev — Things you didn't know about indexes</a></p>]]></content:encoded>
    </item>
    <item>
      <title>SQL: полный путеводитель — от первых запросов до оконных функций</title>
      <link>https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij</link>
      <comments>https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Картофельный Повелитель]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij</guid>
      <description><![CDATA[<p>Полный гайд по SQL: команды, транзакции ACID, нормализация, оконные функции, PostgreSQL, защита от инъекций. Разберитесь в SQL от нуля до уверенного уровня.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sql--polnyj-putevoditel---ot-pervyh-zaprosov-do-okonnyh-funkcij">SQL: полный путеводитель — от первых запросов до оконных функций</a>»</p>]]></description>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 03 Apr 2026 03:12:28 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>SQL</b> (Structured Query Language) — язык запросов для работы с реляционными базами данных, который появился больше 50 лет назад и остаётся одним из самых востребованных навыков в IT. По данным <a href="https://survey.stackoverflow.co/2024/technology/">Stack Overflow Developer Survey 2024</a>, SQL стабильно входит в тройку самых используемых языков — его применяют бэкендеры, аналитики данных, дата-инженеры и тестировщики.</p><p>Этот путеводитель — не просто список ссылок. Каждая секция содержит самостоятельный разбор темы: от истории SQL и принципов работы реляционных баз до транзакций, нормализации и защиты от инъекций. Там, где тема заслуживает глубокого погружения, мы даём ссылку на отдельную статью. Цель — дать полную карту знаний, по которой можно выстроить обучение от нуля до уверенного уровня.</p><p>— SQL — фундаментальный навык для любого, кто работает с данными: от джуна до архитектора</p><p>— Основные команды (SELECT, JOIN, GROUP BY) покрывают 80% повседневных задач</p><p>— Порядок выполнения запроса (FROM → WHERE → GROUP BY → SELECT) — ключ к пониманию SQL</p><p>— Транзакции, ACID и уровни изоляции гарантируют надёжность данных</p><p>— Оконные функции, CTE и хранимые процедуры — продвинутый уровень для карьерного роста</p><p>— PostgreSQL — СУБД №1 в 2024 по Stack Overflow Survey, обогнавшая MySQL</p><p>— SQL не устареет: стандарт развивается, появляются JSON-запросы и графовый SQL</p><h2>Что такое SQL и зачем его учить</h2><p><b>SQL</b> (Structured Query Language) — декларативный язык для работы с реляционными базами данных. «Декларативный» означает, что вы описываете <i>что</i> хотите получить, а не <i>как</i> это сделать. Вы пишете «дай мне все заказы за март», а СУБД сама решает, в каком порядке обходить таблицы и какие индексы использовать.</p><p>Краткая история: в 1970 году Эдгар Кодд из IBM опубликовал реляционную модель данных. В 1974 Дональд Чемберлин и Рэймонд Бойс создали язык SEQUEL (Structured English Query Language) для работы с этой моделью. Позже его переименовали в SQL из-за торговой марки. В 1986 году ANSI принял SQL как стандарт, а последняя версия — SQL:2023 — добавила поддержку JSON и графовых запросов.</p><p>Его используют бэкендеры, аналитики, дата-инженеры и даже тестировщики. И в обозримом будущем SQL никуда не денется — язык продолжает развиваться вместе со стандартом.</p><h2>Как работает SQL: от запроса до результата</h2><p>Когда вы отправляете SQL-запрос, внутри СУБД происходит цепочка шагов:</p><ol><li><b>Парсинг</b> — СУБД разбирает текст запроса, проверяет синтаксис и строит дерево разбора</li><li><b>Анализ</b> — проверяет, существуют ли таблицы и столбцы, есть ли у пользователя права доступа</li><li><b>Оптимизация</b> — самый важный этап. Оптимизатор строит несколько вариантов плана выполнения и выбирает самый дешёвый по стоимости (I/O, CPU, память)</li><li><b>Выполнение</b> — движок исполняет выбранный план: сканирует таблицы, применяет фильтры, объединяет результаты</li><li><b>Возврат результата</b> — СУБД формирует набор строк и отправляет клиенту</li></ol><h3>Логический порядок выполнения запроса</h3><p>SQL-запрос пишется в одном порядке, а выполняется в другом. Вот реальная последовательность обработки:</p><ol><li>FROM / JOIN — определяется источник данных, выполняются соединения</li><li>WHERE — фильтрация строк (до группировки)</li><li>GROUP BY — группировка</li><li>HAVING — фильтрация групп (после группировки)</li><li>WINDOW — вычисление оконных функций</li><li>SELECT — выбор столбцов, вычисление выражений и алиасов</li><li>DISTINCT — удаление дублей</li><li>ORDER BY — сортировка (по стандарту SQL единственное место, где гарантированно работает алиас из SELECT (в PostgreSQL и MySQL алиасы также работают в GROUP BY))</li><li>LIMIT / OFFSET — ограничение количества строк</li></ol><p>Из-за этого порядка нельзя использовать алиас из SELECT в WHERE — на момент фильтрации SELECT ещё не выполнен. А HAVING работает после GROUP BY, поэтому в нём доступны агрегатные функции.</p><p>Именно благодаря оптимизатору SQL остаётся эффективным: вы пишете простой запрос, а СУБД сама выбирает, использовать ли индекс, в каком порядке объединять таблицы, нужна ли сортировка. Увидеть план выполнения можно командой EXPLAIN ANALYZE — это один из главных инструментов оптимизации.</p><h2>Основные команды SQL</h2><p>Любое знакомство с SQL начинается с четвёрки CRUD: SELECT (чтение), INSERT (создание), UPDATE (изменение), DELETE (удаление). К ним добавляются DDL-команды для управления структурой: CREATE TABLE, ALTER TABLE, DROP TABLE, TRUNCATE TABLE (быстрое удаление всех строк без логирования каждой).</p><p>Реальная мощь SQL раскрывается в объединениях через JOIN (INNER, LEFT, RIGHT, FULL), группировке с GROUP BY и фильтрации агрегатов через HAVING. Пример: найти средний чек по городам, где было больше 100 заказов: А также CROSS JOIN (декартово произведение всех строк) и SELF JOIN (соединение таблицы с собой — например, для поиска сотрудников и их руководителей).</p><p>На практике эти команды покрывают примерно 80% задач. Полный разбор с примерами — в нашем <a href="https://tproger.ru/translations/sql-recap">гайде по основным командам SQL</a>. Статью прочитали полтора миллиона раз.</p><h2>Типы данных и ограничения SQL</h2><p>Правильный выбор типов данных — основа производительной и надёжной базы. Базовые типы SQL:</p><ul><li><b>Числовые:</b> INTEGER, BIGINT, DECIMAL(10,2), FLOAT</li><li><b>Строковые:</b> VARCHAR(255), TEXT, CHAR(10)</li><li><b>Дата и время:</b> DATE, TIMESTAMP, INTERVAL</li><li><b>Логический:</b> BOOLEAN</li><li><b>JSON:</b> JSON / JSONB (PostgreSQL) — для полуструктурированных данных</li></ul><p>Ограничения (constraints) — это правила, которые СУБД проверяет автоматически при каждой вставке и обновлении:</p><p>PRIMARY KEY гарантирует уникальность строки. FOREIGN KEY связывает таблицы и не даёт создать «висячие» ссылки. NOT NULL запрещает пустые значения. CHECK валидирует данные по условию. Вместе эти ограничения защищают целостность данных на уровне структуры — СУБД не позволит вставить строку, нарушающую правила.</p><h2>Операторы и выражения</h2><p>За базовыми командами идут операторы, которые делают запросы по-настоящему гибкими. WHERE фильтрует строки, LIKE ищет по шаблону с подстановочными знаками (% — любая подстрока, _ — один символ), IN проверяет вхождение в список, BETWEEN задаёт диапазон.</p><p>Отдельного внимания заслуживает CASE WHEN — условная логика прямо внутри запроса:</p><p>Подробный разбор LIKE с примерами — в <a href="https://tproger.ru/articles/like-sql">отдельной статье</a>.</p><h3>NULL: подводные камни</h3><p>NULL — не значение, а отсутствие значения. NULL = NULL возвращает не TRUE, а NULL. Единственный способ проверки — IS NULL / IS NOT NULL.</p><h3>Функции даты и времени</h3><p>Работа с датами — повседневная задача аналитика:</p><ul><li>NOW() / CURRENT_DATE — текущий момент / дата</li><li>DATE_TRUNC('month', ts) — округление до начала периода</li><li>EXTRACT(YEAR FROM ts) — извлечение части даты</li><li>ts + INTERVAL '7 days' — арифметика с датами</li></ul><h3>Строковые и математические функции</h3><p>Помимо дат и агрегатов, SQL предоставляет богатый набор функций для работы со строками и числами. Строковые функции: CONCAT — склейка строк, SUBSTRING — извлечение подстроки, LENGTH — длина строки, UPPER / LOWER — смена регистра, REPLACE — замена подстроки, TRIM — удаление пробелов по краям. Математические: ROUND — округление, ABS — модуль числа, CEIL / FLOOR — округление вверх и вниз. Эти функции работают одинаково в PostgreSQL, MySQL и других СУБД (с минимальными различиями в именах).</p><h3>Операторы множеств: UNION, INTERSECT, EXCEPT</h3><p>Эти операторы объединяют результаты нескольких запросов:</p><ul><li>UNION — объединение с удалением дубликатов. UNION ALL — без удаления (быстрее)</li><li>INTERSECT — пересечение (строки из обоих запросов)</li><li>EXCEPT — разность (строки из первого, которых нет во втором)</li></ul><h2>Агрегатные функции SQL</h2><p>Агрегатные функции вычисляют одно значение по набору строк: COUNT, SUM, AVG, MIN, MAX. Работают в связке с GROUP BY.</p><p>Нюансы, которые часто путают:</p><ul><li>COUNT(*) считает все строки (включая NULL). COUNT(column) — только строки, где column не NULL</li><li>COUNT(DISTINCT column) — количество уникальных значений</li><li>AVG игнорирует NULL — если NULL означает «0», результат будет завышен</li></ul><h2>Подзапросы, CTE и представления</h2><p>Когда запрос становится сложным, его нужно декомпозировать. Для этого есть три инструмента.</p><h3>Подзапросы</h3><p>Запрос внутри запроса. Бывают скалярные (возвращают одно значение), табличные (набор строк) и коррелированные (ссылаются на внешний запрос):</p><h3>CTE (Common Table Expressions)</h3><p>Конструкция WITH позволяет дать имя подзапросу и переиспользовать его. CTE делают сложные запросы читаемыми, а рекурсивные CTE позволяют обходить деревья и графы:</p><h3>Рекурсивные CTE</h3><p>Рекурсивные CTE обходят деревья и графы — например, оргструктуру компании или вложенные категории:</p><h3>Представления (Views)</h3><p>CREATE VIEW создаёт «виртуальную таблицу» — именованный запрос, к которому можно обращаться как к обычной таблице. Это удобно для инкапсуляции сложной логики и разграничения доступа. Материализованные представления (MATERIALIZED VIEW в PostgreSQL) хранят результат физически и обновляются по команде — полезно для тяжёлых аналитических запросов.</p><h2>Хранимые процедуры и функции</h2><p>Хранимые процедуры и функции — SQL-код, сохранённый на сервере СУБД. Функция возвращает значение и вызывается в SELECT, процедура выполняет действия и вызывается через CALL.</p><p>Когда использовать:</p><ul><li>Инкапсуляция бизнес-логики на уровне базы (расчёт скидок, начисление бонусов)</li><li>Повторяющиеся многошаговые операции (ежемесячные отчёты, архивация)</li><li>Безопасность: SECURITY DEFINER позволяет давать доступ к функции, не давая доступ к таблицам</li></ul><p>Когда <b>не</b> использовать:</p><ul><li>Логику приложения лучше держать в коде — её проще тестировать и деплоить</li><li>Тяжёлые вычисления: масштабировать сервер СУБД дороже, чем сервер приложения</li><li>Бизнес-логика, которая часто меняется — миграции хранимых процедур болезненнее, чем код</li></ul><p>Триггеры — особый тип: они срабатывают автоматически при INSERT/UPDATE/DELETE. Полезны для аудита (логировать все изменения) и автоматических вычислений, но злоупотреблять не стоит — скрытая логика усложняет отладку.</p><h2>Оконные функции SQL</h2><p>Оконные функции — это то, что отделяет новичка от уверенного SQL-разработчика. Они выполняют вычисления по «окну» строк, не сворачивая результат как GROUP BY. Вы получаете и агрегат, и исходные строки одновременно.</p><p>Ключевые функции: ROW_NUMBER() для нумерации, RANK() / DENSE_RANK() для ранжирования, LAG() / LEAD() для сравнения с соседними строками, агрегатные функции с OVER() для скользящих средних и нарастающих итогов.</p><p>Типичные задачи: топ-N в каждой группе, рост метрики месяц к месяцу, скользящее среднее за 7 дней. Без оконных функций эти задачи требуют громоздких подзапросов.</p><p>RANK() пропускает позиции после одинаковых значений (1, 2, 2, 4), а DENSE_RANK() — нет (1, 2, 2, 3). Для скользящих агрегатов используется конструкция ROWS BETWEEN — например, ROWS BETWEEN 6 PRECEDING AND CURRENT ROW для скользящего среднего за 7 дней.</p><p>Детальный разбор с визуальными примерами — в нашей <a href="https://tproger.ru/translations/sql-window-functions">статье об оконных функциях SQL</a>.</p><h2>Транзакции и ACID в SQL</h2><p>Транзакция — группа операций, которые выполняются как единое целое: либо всё, либо ни одна. Классический пример — перевод денег:</p><p>Если между двумя UPDATE произойдёт сбой, ROLLBACK откатит обе операции — деньги не потеряются и не удвоятся. Для частичного отката используется SAVEPOINT: можно откатить транзакцию не целиком, а до определённой точки (ROLLBACK TO SAVEPOINT имя).</p><p>Свойства ACID гарантируют надёжность транзакций:</p><ul><li><b>Atomicity</b> (атомарность) — транзакция неделима: либо выполнена полностью, либо отменена целиком</li><li><b>Consistency</b> (согласованность) — после транзакции база остаётся в корректном состоянии, все ограничения соблюдены</li><li><b>Isolation</b> (изоляция) — параллельные транзакции не мешают друг другу. Уровни: от READ UNCOMMITTED (быстро, но грязные чтения) до SERIALIZABLE (безопасно, но медленно)</li><li><b>Durability</b> (долговечность) — после COMMIT данные сохранены даже при аварии сервера</li></ul><p>ACID — фундамент надёжности реляционных баз данных. Именно эти свойства гарантируют, что данные не потеряются и не «рассинхронятся» даже при сбоях и параллельных запросах.</p><h3>Уровни изоляции</h3><p>Свойство Isolation на практике настраивается через уровни изоляции. Каждый уровень — компромисс между корректностью и производительностью:</p><ul><li><b>READ UNCOMMITTED</b> — самый слабый: видны незакоммиченные изменения других транзакций (dirty reads). Практически не используется</li><li><b>READ COMMITTED</b> — видны только закоммиченные данные. <b>По умолчанию в PostgreSQL</b>. Достаточно для большинства приложений</li><li><b>REPEATABLE READ</b> — повторное чтение строки всегда даёт тот же результат. <b>По умолчанию в MySQL</b>. Защищает от non-repeatable reads</li><li><b>SERIALIZABLE</b> — максимальная изоляция, транзакции ведут себя как последовательные. Нужен для финансовых операций и бронирований</li></ul><h2>Нормализация и проектирование схем</h2><p>Нормализация — процесс организации таблиц так, чтобы минимизировать дублирование данных и аномалии при вставке, обновлении и удалении.</p><p>Три ключевые нормальные формы:</p><ol><li><b>1NF</b> — каждая ячейка содержит одно атомарное значение. Никаких «Москва, Питер» в одном поле — разносим по строкам или связанным таблицам</li><li><b>2NF</b> — все неключевые столбцы зависят от всего первичного ключа, а не от его части. Актуально для составных ключей</li><li><b>3NF</b> — неключевые столбцы не зависят друг от друга. Если город определяет страну, нужна отдельная таблица городов</li></ol><p>Пример: таблица заказов до и после нормализации до 3NF:</p><p>В этом примере мы устранили дублирование данных клиента (2NF). Для полной 3NF нужно было бы вынести и города в отдельную таблицу, если город определяет дополнительные атрибуты (страну, регион).</p><p>На практике большинство баз проектируют в 3NF. Но иногда данные намеренно денормализуют — например, в аналитических хранилищах (OLAP), где скорость чтения важнее экономии места. Схемы «звезда» и «снежинка» в data warehouse — это контролируемая денормализация.</p><h2>Производительность и оптимизация</h2><p>Когда таблица вырастает до миллионов строк, наивные запросы начинают тормозить. Первый инструмент диагностики — EXPLAIN ANALYZE: он показывает, какой план выбрал оптимизатор, сколько строк просканировал и где узкое место.</p><p>Типичные антипаттерны:</p><ul><li>SELECT * вместо конкретных столбцов — читает больше данных, чем нужно</li><li>Отсутствие индекса на столбцах в WHERE и JOIN — приводит к полному сканированию таблицы (Seq Scan)</li><li>Функции на индексированных столбцах: WHERE UPPER(email) = ... — индекс не используется</li><li>N+1 запросы из ORM — 1 запрос за список + N запросов за детали каждой записи</li></ul><p>Индексы — главный способ ускорения. B-tree индекс (по умолчанию) подходит для большинства задач: точные совпадения, диапазоны, сортировка. PostgreSQL также поддерживает GiST (геоданные), GIN (полнотекстовый поиск, JSONB) и BRIN (временные ряды).</p><p>Глубокий разбор типов индексов и их применения — в <a href="https://tproger.ru/articles/indeksy-v-postgresql">нашей статье об индексах PostgreSQL</a>.</p><h2>Безопасность: SQL-инъекции</h2><p>SQL-инъекция — одна из самых опасных уязвимостей веб-приложений, стабильно входящая в <a href="https://owasp.org/Top10/">OWASP Top 10</a>. Суть: если пользовательский ввод подставляется в запрос без обработки, злоумышленник может изменить логику запроса.</p><p>Классический пример — форма логина:</p><p>Защита проста и надёжна — <b>параметризованные запросы</b> (prepared statements):</p><p>Пароли в реальных приложениях никогда не хранят и не сравнивают в открытом виде — их хешируют (bcrypt, argon2), а проверку выполняет код приложения, не SQL-запрос.</p><p>При использовании ORM (SQLAlchemy, Django ORM, Prisma) параметризация происходит автоматически. Если пишете raw SQL — никогда не вставляйте пользовательский ввод через конкатенацию строк или f-строки.</p><h3>Управление доступом: GRANT и REVOKE</h3><p>Вторая линия защиты — принцип минимальных привилегий. Приложению не нужен суперпользователь базы данных:</p><p>REVOKE отзывает права. В PostgreSQL также доступна Row-Level Security (RLS) — ограничение видимости строк в зависимости от роли: каждый менеджер видит только своих клиентов.</p><h2>Современный SQL: JSON, диалекты и стандарт SQL:2023</h2><p>SQL — не замороженный язык из 80-х. Стандарт активно развивается, и последняя версия SQL:2023 (опубликована в июне 2023) принесла два крупных нововведения:</p><ul><li><b>SQL/JSON</b> — стандартизированные функции для работы с JSON прямо в SQL-запросах. PostgreSQL поддерживает JSONB с 2014 года, а теперь аналогичные возможности появляются и в других СУБД</li><li><b>SQL/PGQ</b> (Property Graph Queries) — графовые запросы внутри SQL. Можно искать пути и паттерны в связанных данных без отдельной графовой базы</li></ul><p>На практике каждая СУБД имеет свой диалект:</p><ul><li><b>PostgreSQL</b> — PL/pgSQL, JSONB, массивы, расширения (PostGIS, pg_trgm). Ближе всего к стандарту</li><li><b>MySQL</b> — оконные функции появились поздно — только в версии 8.0 (2018), LIMIT вместо FETCH FIRST</li><li><b>T-SQL</b> (Microsoft SQL Server) — TOP вместо LIMIT, IDENTITY вместо SERIAL, мощные CTE</li><li><b>PL/SQL</b> (Oracle) — ROWNUM, CONNECT BY для иерархий, пакеты (packages)</li><li><b>Cloud SQL</b> — BigQuery, Redshift, Snowflake имеют свои расширения, но базовый SQL везде одинаков</li></ul><p>Хорошая новость: базовый синтаксис (SELECT, JOIN, GROUP BY, оконные функции) одинаков во всех диалектах. Освоив стандартный SQL на PostgreSQL, вы легко перейдёте на любую другую СУБД.</p><h2>PostgreSQL и MySQL</h2><h3>PostgreSQL</h3><p>PostgreSQL — самая популярная реляционная СУБД для новых проектов. Полная поддержка SQL-стандарта, JSONB для полуструктурированных данных, расширения (PostGIS для геоданных, pg_trgm для нечёткого поиска), продвинутая система типов и отличная производительность.</p><p>15 самых полезных команд PostgreSQL — от размера базы до профилирования запросов — в нашей <a href="https://tproger.ru/translations/useful-postgresql-commands">подборке</a>. А для оптимизации больших таблиц — <a href="https://tproger.ru/articles/indeksy-v-postgresql">разбор индексов PostgreSQL</a>.</p><h3>MySQL</h3><p>MySQL — одна из старейших популярных open-source СУБД, движок WordPress и множества legacy-систем. Проще в настройке, но имеет подводные камни: неявное приведение типов, особенности GROUP BY, различия между InnoDB и MyISAM.</p><p>Самые частые ошибки — от кодировок до потери данных — в нашей <a href="https://tproger.ru/translations/troubleshoot-common-errors-in-mysql">статье о типичных ошибках MySQL</a>.</p><h2>Выбор СУБД: SQL vs NoSQL</h2><p>SQLite — для встраиваемых сценариев: мобильные приложения, Electron, edge computing, прототипы (вся база в одном файле). MySQL — проверенный выбор для веб-приложений, на нём работают GitHub и Booking.com. PostgreSQL — универсальный вариант для новых проектов, от стартапов до enterprise. Детальное сравнение с бенчмарками — в <a href="https://tproger.ru/translations/sqlite-mysql-postgresql-comparison">нашем обзоре трёх СУБД</a>.</p><p>Когда данные неструктурированные или нужна горизонтальная масштабируемость, рассмотрите NoSQL: MongoDB (документы), Redis (ключ-значение), Cassandra (колонки), Neo4j (графы). Подробнее — в <a href="https://tproger.ru/translations/sql-nosql-database-models">статье о моделях баз данных</a>.</p><h2>SQL на собеседованиях</h2><p>SQL-вопросы — обязательная часть собеседований для бэкенд-разработчиков, аналитиков и дата-инженеров. Типичный формат: дают схему из 2–3 таблиц и просят написать запрос. Темы: JOIN-ы, GROUP BY, оконные функции, подзапросы, нормализация.</p><p>Ключ к успеху — практика на реальных задачах. Интервьюеры оценивают умение декомпозировать задачу, выбрать правильный тип JOIN и грамотно обработать NULL.</p><p>27 самых распространённых вопросов с ответами — в <a href="https://tproger.ru/articles/sql-interview-questions">нашей подборке</a>. Для практики — <a href="https://tproger.ru/articles/5-zadanij-po-sql-s-realnyh-sobesedovanij">5 заданий с реальных собеседований</a> с разбором решений.</p><h2>Куда двигаться дальше</h2><p>SQL — это фундамент, но не потолок. Направления для роста:</p><ol><li><b>Администрирование БД</b> — репликация, бэкапы, мониторинг, настройка производительности</li><li><b>Дата-инженерия</b> — ETL-пайплайны, dbt, Airflow, data warehouse (BigQuery, Snowflake)</li><li><b>Аналитика данных</b> — SQL + Python (pandas), визуализация, A/B-тесты</li><li><b>Бэкенд-разработка</b> — ORM (SQLAlchemy, Prisma, GORM), миграции, проектирование схем</li><li><b>Data Science</b> — feature engineering, работа с большими датасетами</li></ol><p>Главный совет: практикуйтесь на реальных данных. Поднимите PostgreSQL локально, загрузите публичный датасет и решайте задачи. Ресурсы для старта:</p><ul><li><b><a href="https://sqlbolt.com/">SQLBolt</a></b> — интерактивные уроки SQL в браузере, от нуля</li><li><b><a href="https://pgexercises.com/">PostgreSQL Exercises</a></b> — задачи на реальной схеме (клуб, бронирования)</li><li><b>LeetCode / HackerRank</b> — SQL-задачи для подготовки к собеседованиям</li><li><b><a href="https://www.kaggle.com/datasets">Kaggle Datasets</a></b> — открытые датасеты для импорта в PostgreSQL и экспериментов</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>JOIN — не дорогая операция: бенчмарк на миллиарде строк это доказывает</title>
      <link>https://tproger.ru/translations/join---ne-dorogaya-operaciya--benchmark-na-milliarde-strok-eto-doka</link>
      <comments>https://tproger.ru/translations/join---ne-dorogaya-operaciya--benchmark-na-milliarde-strok-eto-doka?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/translations/join---ne-dorogaya-operaciya--benchmark-na-milliarde-strok-eto-doka</guid>
      <description><![CDATA[<p>Тесты на DuckDB и PostgreSQL показали: JOIN на 1 млрд строк быстрее и дешевле по CPU, чем One Big Table. Смотрите графики и SQL-код бенчмарка.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/translations/join---ne-dorogaya-operaciya--benchmark-na-milliarde-strok-eto-doka">JOIN — не дорогая операция: бенчмарк на миллиарде строк это доказывает</a>»</p>]]></description>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Переводы]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 31 Mar 2026 12:49:20 GMT</pubDate>
      <content:encoded><![CDATA[<p>Вы наверняка слышали: «JOIN — это дорого, сделайте одну большую таблицу». Это заблуждение — одно из самых живучих в мире баз данных. Особенно часто его повторяют те, кто продвигает Data Lake и подход «One Big Table» (OBT). Но так ли это на самом деле?</p><p>Автор блога <a href="https://www.database-doctor.com/">Database Doctor</a> провёл серию бенчмарков на <a href="https://duckdb.org/">DuckDB</a> и <a href="https://www.postgresql.org/">PostgreSQL</a> (подробнее о нём — в нашем <a href="https://tproger.ru/articles/postgresql-basics">гайде по PostgreSQL</a>), сравнив классическую размерную модель (dimensional model) с подходом «One Big Table». Результаты оказались неожиданными для многих — JOIN не просто «не дорогой», он зачастую <b>быстрее</b> плоской таблицы.</p><p>— JOIN в колоночных СУБД (DuckDB) обходится дешевле, чем сканирование широкой OBT-таблицы, уже начиная с 4–6 колонок</p><p>— Стоимость сканирования OBT растёт нелинейно (примерно O(n log n)) с увеличением числа колонок</p><p>— В строковых хранилищах (PostgreSQL) JOIN тоже выигрывает на большинстве сценариев</p><p>— Ральф Кимбалл описал эти закономерности ещё в 1996 году в своей классической книге о размерном моделировании</p><p>— Даже при «бесконечном I/O» денормализация не экономит CPU — она его тратит</p><h2>Постановка эксперимента</h2><p>Рассмотрим два конкурирующих подхода к моделированию данных:</p><ul><li><b>Размерная модель (dimensional model)</b> — атрибуты продуктов хранятся в отдельной таблице product, и мы делаем JOIN с таблицей sales каждый раз при чтении</li><li><b>One Big Table (OBT)</b> — все атрибуты продуктов заранее «вклеены» в таблицу sales_obt, и мы читаем данные через SELECT без JOIN</li></ul><p>Очевидно, что вторую таблицу дороже строить в ETL-пайплайне. Но какая из них потребляет <b>меньше CPU при чтении</b>?</p><h3>Размерная модель</h3><p>Схема данных:</p><p>Здесь c01 ... c20 — строковые колонки с атрибутами продуктов. Кардинальности:</p><ul><li>product — 100 000 строк; каждая из колонок c01–c20 содержит ~100 уникальных значений (MD5-хеши)</li><li>sales — <b>1 миллиард строк</b> со случайным v и равномерно распределённым id_product</li></ul><p>Эта модель, где сущность (product) хранится отдельно от фактов (sales), называется <b>размерной моделью</b> (dimensional model). Подробнее о ней — в конце статьи.</p><h3>Генерация тестовых данных</h3><p>Сначала создаём seed-таблицу — универсальный способ генерации последовательности чисел, который работает практически на всех SQL-платформах:</p><p><i>Примечание: да, можно было бы использовать INSERT ... VALUES с несколькими кортежами, но не каждая аналитическая БД поддерживает этот синтаксис. Зато UNION ALL работает, кажется, вообще везде.</i></p><p>С помощью seed-таблицы генерируем миллиард строк для sales:</p><p>Таблицу product заполняем MD5-хешами для получения строковых значений с контролируемой кардинальностью:</p><p><i>Примечание: да, можно было бы взять ровно 100 различных значений вместо ~101 для c01–c20, но с приведённым выше кодом проще.</i></p><h3>Модель «One Big Table»</h3><p>На другой стороне ринга — заранее объединённая широкая таблица:</p><h3>Гипотеза: JOIN медленнее, чем плоская таблица</h3><p>Итак, вопрос: что быстрее?</p><p>Размерная модель с JOIN:</p><p>Или OBT без JOIN:</p><p>Если «JOIN — это дорого», то размерная модель должна быть медленнее. Мы также должны увидеть более высокое потребление CPU.</p><p>Чтобы быть <i>максимально нечестным</i> по отношению к размерной модели, автор запускает тесты на системе, где <b>вся база помещается в оперативную память</b>. Так мы моделируем «бесконечный I/O» и не платим за дисковые операции.</p><h2>Результаты DuckDB</h2><p>Тестовая машина: ноутбук с 14 ядрами, 32 ГБ RAM, SSD на 3 ГБ/с. Размер базы — 45 ГБ, из которых sales_obt занимает ~40 ГБ. DuckDB отлично утилизирует ядра: CPU загружен на 100% во время выполнения запросов.</p><p>Для тестов автор использовал серию запросов с нарастающим числом колонок:</p><p><i>Примечание: DuckDB использует написание EXPLAIN ANALYZE (а не ANALYSE). В оригинале автор шутит, что DuckDB «правильно» использует британское написание — но на самом деле в DuckDB работает американский вариант.</i></p><p>Базовый замер (measurement 0) — просто чтение v: мы платим за JOIN, но не запрашиваем колонки из product. Читатели, которых интересует эта крайняя ситуация и способы оптимизации, могут изучить тему <a href="https://www.databasedoctor.co/posts/join-elimination">join elimination в планировщиках запросов</a>. Каждый запрос выполняется трижды, берётся лучшее время.</p><h3>Время выполнения (wall clock)</h3><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-03-31/2511523a-e4c0-4871-a3c5-0b0e772d1c07.webp" alt="График: Wall Clock Dim vs OBT в DuckDB" /><figcaption>Время выполнения: размерная модель (Dim) vs One Big Table (OBT) в DuckDB</figcaption></figure><p>Выводы из графика:</p><ul><li>При запросе 1–2 колонок OBT <i>незначительно</i> быстрее</li><li>С ростом числа колонок стоимость OBT <b>взлетает</b> — до 15 секунд при 20 колонках</li><li>JOIN остаётся <b>практически константным</b> по времени (~1 секунда) независимо от числа колонок</li><li>Рост OBT напоминает O(n log n) — нелинейная зависимость</li></ul><h3>Потребление CPU</h3><p>DuckDB позволяет замерить CPU-время по каждому оператору в запросе:</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-03-31/3eac03af-20e8-4c61-8eef-f31b8965a9c9.webp" alt="График: CPU usage OBT vs Dim в DuckDB" /><figcaption>Потребление CPU: OBT vs Dim (CPU по всем ядрам суммарно). Для размерной модели показаны stacked-значения: scan + join</figcaption></figure><p>Та же закономерность: OBT при 20 колонках потребляет <b>~200 секунд CPU</b>, тогда как размерная модель — всего <b>~15 секунд</b> (scan + join). Разница — на <b>порядок</b>.</p><h3>Почему JOIN быстрее при масштабировании?</h3><p>Казалось бы, мы читаем каждую строку. Почему не быстрее просто отдать её из плоской таблицы?</p><p>Ответ кроется в том, как работают <b>колоночные хранилища</b> (DuckDB, Parquet и другие):</p><ol><li><b>Декомпрессия колонок.</b> Сжатые строки хранятся в словаре (dictionary encoding). Чтобы получить данные, движок «соединяет» указатели в сегментах сжатия со словарём. Это по сути тоже своего рода JOIN — но уже внутри Storage Engine. В размерной модели строки уже «материализованы» в таблице product, и эта «декомпрессия» фактически заранее выполнена</li><li><b>Сборка строк из колонок.</b> В колоночном формате данные каждой колонки хранятся отдельно. Чтобы собрать строку, нужно пройти по метаданным, найти местоположение каждой колонки и скопировать данные в финальный результат. Каждая колонка — это отдельная аллокация (и деаллокация) памяти. Именно этот механизм, вероятно, и даёт <b>нелинейный рост</b> стоимости сканирования широкой OBT-таблицы</li></ol><h2>А что насчёт строковых хранилищ?</h2><p>Не все базы данных используют колоночное сжатие. Строковые хранилища (row stores) хранят данные в формате строк (аналогично AVRO в мире Data Lake).</p><p>У строковых хранилищ есть интересное свойство: им <b>не нужно «собирать» строку</b> из отдельных колонок — строка уже хранится целиком. Правда, они занимают больше места на диске и хуже работают при чтении отдельных колонок.</p><p>Вопрос: может быть, для OBT лучше использовать строковое хранилище? Давайте проверим.</p><h3>Гипотеза автора</h3><p><b>В пользу OBT в строковом хранилище:</b></p><ul><li>Данные можно отдать напрямую, без «сборки» строк из колонок</li><li>Не нужна «неявная декомпрессия» сжатых строк</li><li>JOIN на строковых форматах медленнее, чем на колоночных — нельзя векторизовать хеширование</li></ul><p><b>В пользу JOIN:</b></p><ul><li>Если нужна часть колонок, проекция (отбрасывание ненужных) стоит CPU — это неявный memcpy</li><li>Больший объём данных при сканировании — больше работы с буферами</li><li>У JOIN лучше кеш-локальность для строк — меньше TLB-промахов</li></ul><p>Интуиция автора подсказывает, что строковые хранилища могут сдвинуть «точку пересечения» дальше от одной колонки и дать больше преимуществ OBT — хотя бы потому, что не нужна «сборка» строки. Давайте проверим.</p><h3>Тест на PostgreSQL 17</h3><p>Для теста автор выбрал PostgreSQL 17 — классическое строковое хранилище. Датасет уменьшен до 1% (10 млн строк в sales, 10 000 строк в product), но и так sales_obt занимает 7 ГБ.</p><p>Чтобы убрать стоимость сериализации результата для клиента, вместо SELECT * используется:</p><p><i>Примечание: PostgreSQL сериализует результат в клиентский формат даже при EXPLAIN ANALYZE. Это дополнительная работа, которой лишены системы, использующие Arrow-буферы, — там промежуточная сериализация не нужна.</i></p><p>Чтобы убедиться, что PostgreSQL не «хитрит» с NULL-проверкой в COUNT, автор проверил план выполнения. Видно, что агрегат действительно работает со строкой, ширина которой пропорциональна числу входных колонок:</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-03-31/c2bb9fe1-f7f0-46f5-a79a-12b37d21aae4.webp" alt="График: Wall Time Row Store PostgreSQL" /><figcaption>Время выполнения: PostgreSQL OBT vs JOIN (строковое хранилище)</figcaption></figure><p>Выводы:</p><ul><li>Как и предполагалось, стоимость «проекции» (отбрасывания ненужных колонок) доминирует при малом числе колонок — OBT проигрывает</li><li><b>Вопреки ожиданиям</b>, даже в базовом случае (0 колонок из JOIN) размерная модель оказывается быстрее</li><li>Красивая <b>линейная</b> зависимость: строковое хранилище масштабируется предсказуемо в обоих случаях</li><li>JOIN выигрывает или проигрывает OBT <b>с минимальной разницей</b> — но тренд в пользу JOIN</li></ul><h3>Глубокое погружение: что именно тормозит PostgreSQL?</h3><p>С помощью EXPLAIN (ANALYZE, BUFFERS) автор убедился, что запрос работает полностью в памяти:</p><p>shared hit=909120 означает, что все буферы были прочитаны из памяти (shared buffers), без обращения к диску. PostgreSQL форкает процесс на каждое соединение, поэтому профилировать конкретный запрос можно через SELECT pg_backend_pid().</p><p>Автор использовал Windows Performance Recorder для профилирования PostgreSQL на 16-колоночном запросе:</p><figure><img src="https://media.tproger.ru/user-uploads/133946/2026-03-31/9e988bc4-1aee-40f1-9a2f-8c9434939fc4.webp" alt="Скриншот: PostgreSQL trace в Windows Performance Recorder" /><figcaption>Трассировка PostgreSQL: горячие функции при сканировании OBT</figcaption></figure><p>Два самых горячих вызова:</p><ol><li><b>tts_buffer_heap_getsomeattrs</b> (файл execTuples.c) — по сути, неоптимальный memcpy. Эта функция копирует данные из буферного пула в представление кортежа. Именно та «проекция», которую автор предсказывал — но реализованная неэффективно</li><li><b>ExecInterpExpr</b> (файл execExprInterp.c) — интерпретатор выражений. Современные БД используют векторизованное или компилированное выполнение; PostgreSQL по умолчанию интерпретирует через гигантский switch-блок (JIT-компиляция через LLVM доступна с PG 11, но не используется на дефолтных настройках для дешёвых запросов). Основной вызывающий — ExecAgg: подсчёт COUNT обходится почти так же дорого, как само чтение данных</li></ol><p>Важная оговорка: PostgreSQL — <b>не идеальный представитель строковых хранилищ</b>. Базы данных с компилируемыми запросами могут быть значительно быстрее при «сыром сканировании». Тем не менее, строковые хранилища, похоже, почти всегда выигрывают от использования JOIN — если только вы не планируете выбирать практически все колонки из OBT в каждом запросе. Даже денормализация одной колонки ради экономии CPU может оказаться ошибочной.</p><h3>Как автор собирал PostgreSQL с отладочными символами</h3><p>Для профилирования PostgreSQL нужны debug-символы. Ни пакет Chocolatey, ни установщик EnterpriseDB их не включают — пришлось собирать из исходников на Windows.</p><p>Необходимые пакеты:</p><p>Файл msvc.ini в корне репозитория PostgreSQL:</p><p>Сборка:</p><h2>Размерная модель: уроки прошлого</h2><p>Всё, что мы наблюдаем, не ново. Ещё в 1996 году <b>Ральф Кимбалл</b> опубликовал книгу <a href="https://www.kimballgroup.com/data-warehouse-business-intelligence-resources/books/data-warehouse-dw-toolkit/">«The Data Warehouse Toolkit»</a>, которая до сих пор переиздаётся и считается классикой.</p><p>Кимбалл аргументировал:</p><ul><li>Большие аналитические таблицы (<b>факты</b>) должны содержать только метрики (то, что агрегируется) и <b>целочисленные ключи измерений</b> (то, по чему делается JOIN)</li><li>Все атрибуты сущностей хранятся в отдельных <b>таблицах измерений</b> (dimension tables), к которым присоединяются через foreign key</li><li>Колонки с высокой кардинальностью и единственным значением лучше хранить прямо в таблице фактов — <b>«вырожденные измерения»</b> (degenerate dimensions). Это идеально соответствует нашему наблюдению: чтение одной колонки через JOIN действительно немного медленнее</li></ul><p>Кимбалл также рекомендовал объединять связанные таблицы <i>внутри</i> самого измерения (делая таблицу измерения шире) — но только для измерений, <b>не для фактов</b>. И делал он это не ради производительности, а для упрощения работы оптимизатора запросов.</p><h2>Итоги</h2><p>Главный вывод:</p><blockquote>«JOIN — НЕ дорогая операция по сравнению с альтернативами»</blockquote><p>Что мы выяснили:</p><ul><li>Даже при чтении <b>всех</b> строк JOIN зачастую дешевле, чем сканирование One Big Table</li><li>В колоночных хранилищах (DuckDB) преимущество JOIN проявляется начиная с 4–6 колонок и растёт <b>нелинейно</b></li><li>В строковых хранилищах (PostgreSQL) JOIN тоже выигрывает на большинстве сценариев</li><li>«Жертвовать диском ради экономии CPU на JOIN» — это миф, который противоречит измерениям</li><li>Размерное моделирование (Кимбалл, 1996) — не устаревшая методология, а эффективный инженерный подход</li></ul><p>Важно помнить: мы тестировали JOIN большой таблицы (1 млрд строк) с маленькой (100 000 строк). Что произойдёт при JOIN двух больших таблиц — вопрос для отдельного исследования.</p><p>В следующей статье автор обещает разобрать, что происходит с производительностью при добавлении <b>фильтров</b>. Спойлер: разрыв между OBT и JOIN становится ещё больше в пользу JOIN — благодаря bloom-фильтрам и pushdown-оптимизациям.</p><p><i>Перевод и адаптация статьи <a href="https://www.database-doctor.com/posts/joins-are-not-expensive">«Joins are NOT Expensive!»</a> из блога Database Doctor. Если вы хотите глубже разобраться в SQL — рекомендуем нашу <a href="https://tproger.ru/articles/sql-cheat-sheet">шпаргалку по SQL</a>.</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Что такое SQL: основы языка запросов для начинающих</title>
      <link>https://tproger.ru/articles/chto-takoe-sql--osnovy-yazyka-zaprosov-dlya-nachinayushhih</link>
      <comments>https://tproger.ru/articles/chto-takoe-sql--osnovy-yazyka-zaprosov-dlya-nachinayushhih?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Алексей Михайлишин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-takoe-sql--osnovy-yazyka-zaprosov-dlya-nachinayushhih</guid>
      <description><![CDATA[<p>SQL — язык запросов к базам данных. Разбираем SELECT, INSERT, JOIN, WHERE с примерами, типы данных, сравнение СУБД. Начните писать запросы уже сегодня.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-takoe-sql--osnovy-yazyka-zaprosov-dlya-nachinayushhih">Что такое SQL: основы языка запросов для начинающих</a>»</p>]]></description>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 29 Mar 2026 05:09:29 GMT</pubDate>
      <content:encoded><![CDATA[<p>Каждый разработчик рано или поздно сталкивается с базами данных. Неважно, пишете ли вы веб-приложение, мобильный сервис или скрипт для анализа данных — в основе почти всегда лежит реляционная база данных, а значит, SQL. Этот язык не устаревает десятилетиями: он появился в 1970-х годах и до сих пор остаётся стандартом де-факто для работы с данными. По данным опроса Stack Overflow Developer Survey 2023, SQL занимает третье место среди профессиональных разработчиков — его используют 51,5% из них (Stack Overflow Developer Survey 2023).</p><p><b>SQL (Structured Query Language)</b> — это декларативный язык запросов для управления реляционными базами данных. С его помощью можно создавать таблицы, добавлять, изменять и удалять данные, а также делать выборки по заданным условиям. SQL стандартизирован организацией ISO и поддерживается всеми основными СУБД: PostgreSQL, MySQL, SQLite, Microsoft SQL Server и Oracle.</p><p>- SQL расшифровывается как Structured Query Language — язык структурированных запросов.</p><p>- Язык создан в 1973 году в IBM, стандарт ISO принят в 1987 году.</p><p>- SQL используют 51,5% профессиональных разработчиков по всему миру (Stack Overflow, 2023).</p><p>- Основные операции: SELECT, INSERT, UPDATE, DELETE — охватывают 90% повседневных задач.</p><p>- SQL работает с реляционными базами данных, где данные хранятся в связанных таблицах.</p><p>- Один SQL-запрос может обработать миллионы строк за доли секунды.</p><h2>Зачем нужен SQL — где используется и кому пригодится</h2><p>SQL нужен везде, где есть структурированные данные. Вот лишь несколько примеров из реальной практики:</p><ul><li><b>Веб-разработка</b> — интернет-магазины, блоги, социальные сети хранят пользователей, товары и записи в реляционных БД.</li><li><b>Аналитика данных</b> — аналитики используют SQL для агрегации, фильтрации и построения отчётов.</li><li><b>Backend-разработка</b> — серверные приложения взаимодействуют с PostgreSQL или MySQL через SQL-запросы.</li><li><b>Data Science</b> — учёные по данным выгружают датасеты из хранилищ (Redshift, BigQuery) с помощью SQL.</li><li><b>DevOps и администрирование</b> — DBA оптимизируют запросы, настраивают индексы, следят за производительностью.</li></ul><p>SQL востребован как у начинающих разработчиков, так и у опытных инженеров. По данным Glassdoor, знание SQL входит в топ-3 навыков для вакансий Data Analyst и Backend Developer в 2024 году. Даже фронтендеры, которые редко работают напрямую с БД, рано или поздно сталкиваются с SQL при отладке или настройке.</p><h2>Основные команды SQL</h2><p>Все команды SQL делятся на группы. Самые важные — это DDL (Data Definition Language) для создания структур и DML (Data Manipulation Language) для работы с данными. Рассмотрим ключевые команды подробнее.</p><h3>SELECT — выборка данных</h3><p>SELECT — самая используемая команда SQL. Она позволяет извлекать данные из одной или нескольких таблиц. Базовый синтаксис:</p><p>Звёздочка * означает «все столбцы», но на практике лучше перечислять нужные явно — это ускоряет запрос и делает код читаемым. Чтобы отфильтровать дубликаты, используют SELECT DISTINCT.</p><p>Можно также ограничить количество строк в результате:</p><h3>INSERT, UPDATE, DELETE — изменение данных</h3><p>Три команды, отвечающие за создание, изменение и удаление записей:</p><p><b>Важно:</b>
Всегда используйте WHERE в командах UPDATE и DELETE. Без условия изменения применятся ко всем строкам таблицы, и восстановить данные без бэкапа не получится.</p><h3>CREATE TABLE — создание таблиц</h3><p>Прежде чем работать с данными, нужно создать таблицу. Команда CREATE TABLE задаёт структуру: имена столбцов, их типы и ограничения:</p><p>SERIAL (или AUTO_INCREMENT в MySQL) автоматически генерирует уникальный числовой идентификатор. PRIMARY KEY — уникальный ключ строки. REFERENCES создаёт внешний ключ — связь между таблицами.</p><h3>JOIN — объединение таблиц</h3><p>Реляционные базы данных хранят информацию в нескольких связанных таблицах. Чтобы получить данные из нескольких таблиц одним запросом, используется JOIN. Существует несколько видов объединений:</p><ul><li>INNER JOIN — только совпадающие строки из обеих таблиц.</li><li>LEFT JOIN — все строки из левой таблицы, совпадения из правой (или NULL).</li><li>RIGHT JOIN — все строки из правой таблицы, совпадения из левой (или NULL).</li><li>FULL OUTER JOIN — все строки из обеих таблиц, NULL там, где нет совпадений.</li></ul><h3>WHERE, ORDER BY, GROUP BY — фильтрация и сортировка</h3><p>Три важнейших инструмента для управления результатом выборки. Подробный разбор ORDER BY с примерами читайте в нашем <a href="https://tproger.ru/articles/sortirovka-v-sql--order-by--asc-i-desc-s-primerami">гайде по сортировке в SQL</a>.</p><p>Ключевое отличие: WHERE фильтрует строки <i>до</i> группировки, HAVING — <i>после</i>. Агрегатные функции (COUNT, SUM, AVG, MIN, MAX) работают с группами строк.</p><h2>Типы данных в SQL</h2><p>При создании таблицы каждому столбцу нужно указать тип данных. Правильный выбор типа экономит место на диске и ускоряет запросы. Основные типы:</p><ul><li><b>Числовые:</b> INT / INTEGER — целые числа; BIGINT — большие целые; DECIMAL(p,s) — дробные с фиксированной точностью; FLOAT — числа с плавающей запятой.</li><li><b>Строковые:</b> VARCHAR(n) — строка до n символов; TEXT — строка без ограничений; CHAR(n) — строка фиксированной длины.</li><li><b>Дата и время:</b> DATE — дата (YYYY-MM-DD); TIME — время; TIMESTAMP — дата и время; INTERVAL — интервал.</li><li><b>Логический:</b> BOOLEAN — значения TRUE / FALSE / NULL.</li><li><b>Специальные:</b> UUID — уникальный идентификатор; JSON / JSONB — JSON-данные (PostgreSQL); ARRAY — массив значений.</li></ul><p>Практическое правило: используйте наименьший подходящий тип. Для возраста достаточно SMALLINT, для идентификатора пользователя — INT, для финансовых сумм — DECIMAL, а не FLOAT (чтобы избежать ошибок округления).</p><h2>SQL vs NoSQL — когда что использовать</h2><p>SQL-базы данных хранят данные в таблицах с фиксированной схемой. NoSQL-базы (MongoDB, Redis, Cassandra) используют другие модели: документы, ключ-значение, графы, колонки. Вот когда выбирать каждый подход:</p><ul><li><b>SQL подходит, когда:</b> данные структурированы и схема стабильна; важна целостность и транзакции (банки, интернет-магазины); нужны сложные запросы с JOIN и агрегацией; команда умеет работать с реляционными БД.</li><li><b>NoSQL подходит, когда:</b> структура данных гибкая или меняется часто; нужна горизонтальная масштабируемость под огромные объёмы; данные неструктурированы (логи, события, JSON); требуется сверхнизкая латентность (кэш в Redis).</li></ul><blockquote>SQL и NoSQL — не конкуренты, а инструменты для разных задач. В одном проекте вполне можно использовать PostgreSQL для бизнес-данных и Redis для кэша.</blockquote><h2>Популярные СУБД: PostgreSQL, MySQL, SQLite, MS SQL</h2><p>SQL-синтаксис стандартизирован, но каждая СУБД добавляет свои расширения. Вот краткое сравнение четырёх самых популярных:</p><ul><li><b>PostgreSQL</b> — мощная open-source СУБД с богатым набором типов данных, поддержкой JSON, полнотекстового поиска и оконных функций. Лучший выбор для серьёзных проектов. Подробнее читайте в нашем <a href="https://tproger.ru/articles/osnovy-postgresql-dlya-nachinayuschih--rukovodstvo-s-primerami">руководстве по PostgreSQL для начинающих</a>.</li><li><b>MySQL / MariaDB</b> — самая распространённая СУБД для веб-приложений, особенно в связке с PHP (WordPress, Drupal). Простая в настройке, быстрая для чтения.</li><li><b>SQLite</b> — встроенная база данных в одном файле, без сервера. Идеально подходит для мобильных приложений, тестирования и небольших проектов. Используется в Android, iOS, браузерах.</li><li><b>Microsoft SQL Server</b> — корпоративная СУБД от Microsoft, тесно интегрированная с экосистемой .NET и Azure. Популярна в крупных компаниях.</li></ul><p>Если вы только начинаете, рекомендуем PostgreSQL или SQLite. PostgreSQL — для полноценной разработки, SQLite — для обучения без установки сервера.</p><h2>Как начать учить SQL — ресурсы, песочницы, советы</h2><p>SQL — один из самых практичных языков для изучения. Базовые команды можно освоить за неделю, а первые реальные запросы писать уже через несколько часов практики.</p><p>Подробную дорожную карту с последовательностью тем и рекомендуемыми ресурсами смотрите в нашей <a href="https://tproger.ru/articles/dorozhnaya-karta-sql-dlya-nachinayuschih-v-2024-godu">дорожной карте SQL для начинающих</a>.</p><ul><li><b>SQLiteOnline.com</b> — онлайн-песочница без регистрации. Запустите первый запрос прямо в браузере за 30 секунд.</li><li><b>SQLBolt.com</b> — интерактивный курс с упражнениями от SELECT до сложных JOIN. Полностью бесплатный, на английском.</li><li><b>Stepik.org</b> — бесплатный курс «Введение в базы данных» на русском языке с практическими заданиями.</li><li><b>LeetCode / HackerRank</b> — задачи на SQL для подготовки к техническим собеседованиям.</li><li><b>Официальная документация PostgreSQL</b> — самый полный и точный источник по возможностям СУБД.</li></ul><p>Советы для эффективного обучения: практикуйтесь на реальных данных (импортируйте CSV-файл в SQLite), сразу изучайте индексы — они кардинально влияют на производительность. Читайте наш материал об <a href="https://tproger.ru/articles/sql-indeksy-za-10-minut--kak-uskorit-zaprosy-v-baze-dannyh">SQL-индексах за 10 минут</a> и <a href="https://tproger.ru/articles/optimizaciya-sql-zaprosov--10-sovetov-dlya-nachinayushhih">10 советов по оптимизации запросов</a>.</p><h2>Выводы</h2><p>SQL — фундаментальный навык для любого, кто работает с данными. За полвека существования язык не только не устарел, но и стал ещё более востребованным: облачные хранилища BigQuery и Redshift, аналитические инструменты, современные ORM — всё это работает поверх SQL или совместимо с ним.</p><p>Что делать дальше:</p><ol><li>Установите PostgreSQL или откройте SQLiteOnline.com и напишите первый SELECT.</li><li>Пройдите интерактивный курс на SQLBolt.com — займёт 3–5 часов.</li><li>Попрактикуйтесь на реальных данных: загрузите любой CSV-датасет с Kaggle.</li><li>Изучите индексы — это самый быстрый способ ускорить запросы.</li><li>Посмотрите нашу дорожную карту SQL и двигайтесь по ней системно.</li></ol><p>SQL знают и продолжают учить потому, что он действительно работает. Сотни миллионов строк в банках, маркетплейсах и SaaS-сервисах каждый день обрабатываются именно с помощью SQL-запросов. Это инвестиция в навык, который окупится независимо от выбранного стека.</p>]]></content:encoded>
    </item>
    <item>
      <title>10 подходов по работе с данными, которые должен знать каждый data-инженер</title>
      <link>https://tproger.ru/articles/10-podhodov-po-rabote-s-dannymi--kotorye-dolzhen-znat-kazhdyj-dat</link>
      <comments>https://tproger.ru/articles/10-podhodov-po-rabote-s-dannymi--kotorye-dolzhen-znat-kazhdyj-dat?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Неопознанный программист]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/10-podhodov-po-rabote-s-dannymi--kotorye-dolzhen-znat-kazhdyj-dat</guid>
      <description><![CDATA[<p>10 подходов по работе с данными для data-инженера</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/10-podhodov-po-rabote-s-dannymi--kotorye-dolzhen-znat-kazhdyj-dat">10 подходов по работе с данными, которые должен знать каждый data-инженер</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 24 Mar 2026 08:55:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>В статье рассматриваем 10 подходов по работе с данными, которые должен знать любой уважающий себя data-инженер.</p><h2>10. Star Schema —
старая рабочая лошадка (которая разваливается на больших данных)</h2><p>Наша любимая звездочка — это самая базовая модель для аналитики. Таблица фактов
(с метриками, напр. продажи) окружена таблицами измерений.</p><p>К примеру, таблица
фактов «Продажи», а вокруг нее таблицы измерения: «Клиент» (кому продали), «Продукт»
(что продали), «Заказ» и т.д. Но на больших объемах, а также при увеличении
объектов в хранилище данных, она может начать подводить. Особенно сложно в нее
вносить какие-либо изменения, так как таблицы зависят друг от друга. Звездочка
это такой неэластичный монолит.</p><p><b>Проблемы на практике:</b></p><p>Когда таблица fact_sales растёт до сотен миллионов или
     миллиардов строк, запросы начинают жёстко тормозить. JOIN-ы с несколькими измерениями и GROUP BY приводят к долгим
     сканированиям. сложно вносить изменения, все может посыпаться</p><p>Типичный запрос может выглядеть так:</p><p>И чем больше строк в fact_sales, тем медленнее выполняется такой
запрос.</p><p>Проще говоря: звёздочка удобна и понятна, но <b>не очень масштабируется</b>.</p><h2>9. Snowflake Schema — слишком усложнённая и медлительная</h2><p>Снежинка — это “нормализованная” версия звездочки: таблицы измерений
разбиваются на ещё более мелкие части, как ветви снежинки. В результате каждая
иерархия измерений (например продукт → категория → бренд) живёт в своей
таблице.</p><p>Это улучшает хранение (меньше дублирования данных и меньше места на диске),
но делает запросы <b>еще более тяжёлыми</b>, потому что для простого отчёта
нужно больше JOIN-ов между таблицами. Зато теперь чуточку легче поддерживать и
это уже мене похоже на монолит, хотя все равно таковым является.</p><p><b>Короче говоря:</b></p><ul><li>Плюсы: меньше избыточности, данные лучше
     структурированы, нормализовано (хорошо для поддержки целостности).</li><li>Минусы: запросы становятся сложнее и медленнее (много
     JOIN-ов), сложнее для понимания тем, кто пишет SQL-аналитику. И все равно
     монолит, который сложно поддерживать.</li></ul><p>п=</p><h2>8. Data Vault — гибко,
масштабируемо… и очень сложно</h2><p>Эта модель появилась, чтобы строить очень
масштабируемые DWH, где можно спокойно переживать постоянные изменения
источников данных.</p><p>Вместо привычных «фактов и измерений» тут три типа таблиц:</p><p>·        
<b>Hubs
</b>— бизнес-сущности (клиент, заказ, продукт).</p><p>·        
<b>Links
</b>— связи между ними.</p><p>·        
<b>Satellites
</b>— атрибуты и история изменений (фио клиента, наименование товара, стоимость
товара).</p><p>Можно добавлять новые источники почти без боли и хранить полную историю изменений.</p><p>Но где
подвох?</p><p>Во-первых, схема получается гигантской — десятки и сотни таблиц.</p><p>И во-вторых, даже простой отчёт превращается в цепочку JOIN-ов на пол-экрана SQL.</p><p>А в-третьих, новым людям в команде разобраться в этом всём,
как отдельный квест.</p><p>Data Vault отлично подходит для
enterprise-DWH, где важны аудит, история и масштаб. Но для обычной аналитики это как резать колбасу бензопилой.</p><p>Пример запроса:</p><h2>7. Wide Tables / One Big Table (OBT) — для time-series</h2><p>Это противоположность сложным моделям вроде Data Vault.</p><p>Идея максимально простая - берём данные из
разных таблиц и склеиваем всё в одну огромную таблицу.</p><p>·        
Запросы супербыстрые, почти без
JOIN-ов.</p><p>·        
Очень удобно для BI и дашбордов.</p><p>·        
Понятная структура: «одна строка = один
бизнес-объект».</p><p>Но за скорость нужно платить следующими недостатками:</p><p>·        
Дублирование данных на каждом шаге,</p><p>·        
Таблица быстро разрастается до сотен колонок,</p><p>·        
Любое изменение логики требует пересборки всей
таблицы,</p><p>·        
Легко поймать несогласованность данных.</p><p>Короче:</p><p>OBT — это как кеш. Но все это добро
практически невозможно поддерживать.</p><p>Часто применяется в рамках time-seriesанализа:
IoT, анализ метрик, логов, clickstream.</p><p>Пример запроса:</p><h2>6. Graph Models (Neo4j, TigerGraph) — для связей</h2><p>Когда ценность данных именно <b>в связях</b> (например,
в мошеннических схемах, социальном влиянии или цепочках переходов по сети). В таком случае куча
join-ов просто
перестают работать, особенно при всякого рода рекурсиях.</p><p>С этим помогают графовые базы.</p><p>Вот к примеру, нужно нам найти всех
друзей наших друзей:</p><ul><li>Количество JOIN-ов растёт экспоненциально
     с каждым уровнем.</li><li>Уже на 3+ переходах запрос
     становится почти нечитаемым.</li><li>Кратно падает
     производительность</li></ul><p>Теперь посмотрим, как в графовой
базе это будет реализовано:</p><p>Отлично
подходит для антифрода, соцграфов и рекомендательных систем.</p><p>И совершенно
не подходит для OLAP-аналитики.</p><h2>5. Streaming Event
Sourcing (Kafka + CDC)</h2><p>Классический batch-ETL плохо сочетается с системами реального времени. Для real-time аналитики более
всего подходит CDC.</p><p>CDC превращает изменения в базе данных в события, которые отправляются потребителю
(DWH).</p><p>Данные становятся не снимком, а временной линией.</p><p><b>Как все это работает</b></p><p>·        
Базы данных → источники событий</p><p>·        
Kafka → надёжный журнал событий</p><p>·        
Потребители → могут пересобрать состояние в
любой момент</p><p>Пример (из debezium):</p><h2>Плюсы</h2><p>·        данные в реальном времени</p><p>·        
встроенное восстановление после сбоев</p><p>·        
слабая зависимость между продюсерами и
консьюмерами</p><h2>Минусы</h2><p>·        
высокая сложность реализации</p><p>·        
порядок событий и идемпотентность реализовать
непросто</p><p>·        
отладка требует видимости на уровне событий</p><h2>4. Columnar Storage (Parquet, Delta Lake) для дешёвой и быстрой аналитики</h2><p>Row
oriented базы
(данные стандартно лежат в виде строк в таблицах) оптимизированы под точечные
запросы, а не под аналитику. Если вы выбираете из таблицы всего два столбца из
ста, все равно будет считываться весь файл, так как все столбы хранятся в одном
файле.</p><p>Колоночный же формат подразумевает, что значения столбцов лежат в разных
местах.</p><h2>Ключевые преимущества</h2><p>·        
читаются только нужные колонки</p><p>·        
сильное сжатие (RLE, словарное кодирование)</p><p>·        
векторизованное выполнение</p><p>Меньше I/O → быстрее запросы.</p><p>Структура таблицы:</p><h2>3. Мульти-модельные (когда SQL и NoSQL одновременно)</h2><p>В реальной жизни данные редко бывают одного типа.</p><p>Современные приложения одновременно работают с:</p><p>·        
реляционными фактами</p><p>·        
полуструктурированным JSON</p><p>·        
связями между сущностями</p><p>Мульти-модельные базы позволяют запрашивать всё это в одном месте.</p><p>Вот типичный сценарий, когда один из столбцов хранит данные в jsonb:</p><p>И вот пример запроса к такой таблице:</p><p>Как видно для аналитика это не совсем удобно. Поэтому (как в
сценарии с data vault),
для аналитиков лучше делать отдельные витрины, где данный json уже разложен на нужные столбцы.</p><h2>Плюсы</h2><p>·        
одна система для разных типов данных</p><p>·        
мощный SQL при гибкой схеме</p><p>·        
меньше ETL и копирования данных</p><h2>Минусы</h2><p>·        
сложнее управлять схемой</p><p>·        
планы запросов могут усложняться</p><p>·        
медленнее специализированных движков</p><h2>2. Reverse ETL (операционная аналитика, возвращающая данные в приложения)</h2><p>Классическая аналитика заканчивается дашбордами и отчетами.</p><p>Reverse ETL замыкает цикл: данные из хранилища отправляются обратно в
операционные системы. Будь то скорректированные данные или какие-то посчитанные
в DWH метрики,
которые должны также храниться в информационной системе, что отображаться на
сайте или еще где-нибудь.</p><p>Вот частые примеры использования:</p><p>·        
почти-реальная персонализация</p><p>·        
актуальные метрики здоровья клиента и оттока</p><p>·        
автоматизация продаж и маркетинга (CRM, ESP и
т.д.)</p><h2>1. Единый слой данных (наше будущее)</h2><p>Вот обычная картина в средней компании: операционные данные
хранятся в PostgreSQL, аналитические
данные в Greenplum, стриминговые
данные в Clickhouse, данные
для поиска в Elasticsearch.
Четыре системы, между которыми данные нужно синхронизировать и реплицировать.</p><p>Unified Serving Layer использует единый логический слой таблиц</p><p>Например, Iceberg / Hudi / Delta с разными способами доступа.</p><p>То есть, один
набор данных, много движков, без ETL.</p><p>Данные лежат в одном месте, но читаются разными движками,
предназначенными для разных задач.</p><h2>Что это заменяет</h2><p>·        
нет ETL (warehouse → lake → feature store)</p><p>·        
рассинхронизацию данных между системами</p><p>·        
повторную реализацию логики в SQL, Spark и
приложениях</p><p>Пример таблицы в Iceberg</p><p>OLAP-запрос (Trino / Spark SQL)</p><h2>Плюсы</h2><p>·        
единый источник истины</p><p>·        
доступ из разных движков (SQL, ML, стриминг)</p><p>·        
ACID, time-travel, эволюция схемы</p><p>·        
отсутствие vendor lock-in</p><h2>Минусы</h2><p>·        
более сложная платформа</p><p>·        
требуется сильное управление метаданными и
governance</p><p>·        
не является прямой заменой OLTP-БД (потому что с
нагрузкой может не справиться).</p>]]></content:encoded>
    </item>
    <item>
      <title>Кривая забывания Эббингауза в пользовательских приложениях</title>
      <link>https://tproger.ru/articles/krivaya-zabyvaniya-ebbingauza-v-polzovatelskih-prilozheniyah</link>
      <comments>https://tproger.ru/articles/krivaya-zabyvaniya-ebbingauza-v-polzovatelskih-prilozheniyah?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Ivan Kornaukhov]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/krivaya-zabyvaniya-ebbingauza-v-polzovatelskih-prilozheniyah</guid>
      <description><![CDATA[<p>Кривая забывания Эббингауза часто упоминается в теории обучения, но редко в прикладном контексте. В статье разбираю саму модель и показываю, как её можно реализовать на SQL и Python для управления повторениями в пользовательском приложении.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/krivaya-zabyvaniya-ebbingauza-v-polzovatelskih-prilozheniyah">Кривая забывания Эббингауза в пользовательских приложениях</a>»</p>]]></description>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 04 Jan 2026 12:20:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Привет, Tproger! Сегодня многие учат иностранные языки с помощью приложений - от популярных до простых Telegram-ботов. Но сталкивались ли вы с тем, что вроде бы выученное слово через пару дней вдруг исчезает из памяти? Спойлер: это не ваша проблема, а особенность человеческого мозга.</p><p>В этой статье я хочу познакомить вас с системой забывания, которую исследовал немецкий психолог <b>Германн Эббингауз.</b> Мы разберём, как перевести её в формулы, понятные программисту, как эту теорию я применил в своём Telegram-боте для изучения английских слов. Мы разберём практическую сторону, посмотрим на SQL-реализацию и наглядно сравним её с кодом на Python.</p><h2>Кривая забывания Эббингауза</h2><p>Суть теории проста, если выучить определённый объём несвязанных данных (в оригинальных экспериментах это были случайные слоги), то уже через 20 минут в памяти останется около 56%, через час - 47%, через 8 часов - 35%, и дальше спад идёт по экспоненте.</p><p>Эббингауз впервые экспериментально описал <b>кривую забывания </b>как зависимость сохранности материала от времени.</p><figure><img src="https://media.tproger.ru/user-uploads/135250/2025-12-30/9d62b1c7-0b88-4bca-8c86-3ab780e7efd0.png" alt="" /><figcaption>Кривая забывания Эббингауза</figcaption></figure><p>Согласно его фундаментальной работы "Memory: A Contribution to Experimental Psychology" формула выглядит так:</p><figure><img src="https://media.tproger.ru/user-uploads/135250/2025-12-30/503272e7-0df1-40be-b0b8-173401a97412.png" alt="" /><figcaption>Формула забывания Эббингауза</figcaption></figure><p>Коэффициенты <i>k</i> и <i>c</i> были получены опытным путём, чтобы расчёты совпадали с реальными наблюдениями.</p><p>Давайте попробуем поиграть параметрами формулы и посмотреть как изменяется график. Если увеличить коэффициент <i>k</i>, кривая вытягивается вправо: <b>всё забывается медленнее по всему диапазону</b>. Вот график при коэффициенте <i>k</i> = 5. Пунктирной линией график с коэффициентом <i>k</i> = 1.84.</p><figure><img src="https://media.tproger.ru/user-uploads/135250/2025-12-30/b276fb16-232b-47d2-b48d-2298b5a33e1e.png" alt="" /><figcaption>График при коэффициенте k = 5. Пунктирной линией график с коэффициентом k = 1.84.</figcaption></figure><p>C психологической точки зрения этот коэффициент можно трактовать как стабильность повторения ну или легкость элемента повторения.</p><p>Коэффициент "<i>с</i>" - кривизна забывания. Он управляет тем, насколько быстро растёт вклад времени в знаменатель.</p><figure><img src="https://media.tproger.ru/user-uploads/135250/2025-12-30/f4eb21af-180e-4414-922b-5d2597041cda.png" alt="" /><figcaption>График при коэффициенте c &lt; 1.25, c = 1.25, c &gt; 1.25.</figcaption></figure><p>При <i>c</i> &gt; 1.25 спад ускоряется сильнее, то есть весь изученный материал забывается <b>раньше</b>, а при <i>c</i> &lt; 1.25 - резче падает сразу, но хвост длиннее (дольше «тянется» память на больших временах). Коэффициент будто «перераспределяет» забывание между ранней и поздней фазами.</p><h2>Как перенести теорию в код</h2><p>Теорию мы разобрали, теперь самое интересное применить её на практике.  Представим, что у нас есть приложение для изучения английских слов. В моём случае это Telegram-бот, который ищет переводы, сохраняет их в «альбомы» и помогает учить через задания и тесты. Пользователь повторяет слова небольшими порциями, а приложение подсказывает, что стоит повторить прямо сейчас, а что можно оставить на потом.</p><p>И вот здесь мне понадобится кривая забывания. Алгоритм на её основе помогает автоматически решать: какое слово пора освежить в памяти, а какое можно отложить. Чем лучше ты справляешься с тестами, тем дольше приложение не будет тревожить тебя этим словом. Если же ошибок много, то слово будет попадаться чаще, пока не закрепится.</p><p>Если учесть, что коэффициент <i>k</i> поднимает и вытягивает кривую на графике, логично предположить, что при каждом правильном прохождении теста, этот коэффициент должен увеличиваться, а при неправильном снижаться. Назовем его <i>коэффициент прочности</i>, а описать его можно так:</p><p>Каждый правильный ответ (correct_count) повышает коэффициент прочности на <b>0.8</b>, а каждый неправильный (wrong_count) снижает его на 0.5. Эти значения можно регулировать под конкретные задачи: сделать повторения чаще или реже, в зависимости от того, какой баланс между скоростью и качеством обучения вам нужен.</p><p>minutes - сколько прошло минут с момента повторения,</p><p>strength<i> </i>- коэффициент прочности, который мы описали выше.</p><p>max(minutes, 1)<i></i> - используется, если между повторениями материала прошло меньше минуты, чтобы исключить отрицательно значение логарифма.</p><p>Для хранения параметров обучения в базе данных нам потребуется простая таблица words, которая состоит из 4 столбцов:</p><ul><li>text - само слово,</li><li>last_review - время последнего повторения,<br /></li><li>correct_count и wrong_count - статистика ответов пользователя.<br /></li></ul><p>Если слов в обучении немного, мы можем просто выгрузить все данные из таблицы и выполнить расчёты прямо в приложении. Но по мере увеличения словаря такой подход становится неэффективным, потому что передача и обработка больших объёмов данных на стороне клиента сильно замедляет работу. Поэтому оптимальнее переносить вычисления на сторону базы данных. В этом случае сервер сразу возвращает только нужные слова, уже отсортированные по приоритету.</p><p>Например, в PostgreSQL это можно выразить напрямую в SQL-запросе:</p><p>priority - итоговый коэффициент по формуле Эббингауза, показывающий, какие слова стоит повторять в первую очередь.</p><p>Хочу поподробнее остановится на запросе и разобрать эту строчку:</p><ul><li>NOW() - возвращает текущее время базы данных (в PostgreSQL это timestamp with time zone),</li><li>NOW() - last_review - разность двух времён, это объект типа interval<br /></li><li>EXTRACT(EPOCH FROM ...) - функция берёт определённое поле из даты или интервала,<br /></li><li>EPOCH - это количество секунд.</li></ul><p>То есть EXTRACT(EPOCH FROM interval) преобразует интервал времени в число секунд, прошедших с момента последнего повторения.</p><p>Хочу обратить внимание на синтаксис функции логарифма в SQL и Python. В оригинальной формуле используется десятичный логарифм (common logarithm, основание 10). В PostgreSQL он записывается как <i>LOG(x)</i>, тогда как в python <i>math.log(x)</i> или <i>numpy.log(x)</i> это натуральный логарифм по основанию <i>e</i>, а десятичный записывается как <i>math.log10(x)</i> или <i>numpy.log10(x)</i>.</p><h2>Визуализация забывания</h2><p>Для наглядности рассмотрим пять слов с разным временем последнего повторения и количеством правильных/неправильных ответов:</p><figure><img src="https://media.tproger.ru/user-uploads/135250/2025-12-30/802f30bc-f8b6-4435-85dd-af35a77bf2e4.png" alt="" /><figcaption>Таблица содержит пять слов с разным временем последнего повторения и количеством правильных/неправильных ответов.</figcaption></figure><p>Эта таблица демонстрирует, что чем раньше мы начали учить слово, тем больше правильных ответов оно накапливает. Например, у <i>take</i> или <i>see</i> число успешных повторений значительно выше, чем у свежих слов <i>go</i> или <i>come</i>. В то же время слово <i>circumstances</i> выбивается из общей картины, хотя оно училось раньше других и должно было бы демонстрировать высокий уровень запоминания, большое количество ошибок (40 против 42 правильных) сильно снижает его «силу удержания» в памяти.</p><figure><img src="https://media.tproger.ru/user-uploads/135250/2025-12-30/1bd8fe56-0af5-4f53-a18d-0a43ff0ce846.png" alt="" /><figcaption>Построение кривых забывания для представленных слов</figcaption></figure><p>На графике хорошо заметно как кривая <i>circumstances</i> резко идёт вниз и оказывается ниже даже у более «молодых» слов. Этот пример наглядно показывает, что важен не только фактор времени последнего повторения, но и качество усвоения. Если слово систематически даётся с ошибками, его приоритет для повторения возрастает, и система будет предлагать его чаще.</p><p>Таким образом, сочетание параметров времени последнего повторения и статистики правильных/неправильных ответов позволяет адаптивно выстраивать план повторений. Это даёт более реалистичную модель памяти по сравнению с простой зависимостью только от времени, как у Эббингауза в классической формуле.</p><p>Подробный пример реализации с извлечением слов из базы данных по приоритету и построения графиков можно посмотреть в моём <a href="https://github.com/ivakorn/Ebbinghaus_curve">репозитории на GitHub</a>.</p><h2>Заключение</h2><p>Формула Эббингауза - это лишь один из возможных подходов к решению задачи повторения, который я реализовал на SQL и Python. Очевидно, что в сети существуют более сложные и продвинутые решения, особенно с учётом развития машинного обучения и ИИ. Однако целью этой статьи было показать, как подобную модель можно реализовать просто без усложнения архитектуры. Коэффициенты и сама формула легко модифицируются. Их можно адаптировать под сложность материала, частоту ошибок или даже контекст использования знаний. Если у вас есть идеи, как улучшить модель или расширить её применение, буду рад обратной связи и обсуждению.</p><p><br /></p>]]></content:encoded>
    </item>
    <item>
      <title>Сжать государственную VIN-базу с 1,5 ГБ до 21 МБ? Реально! Разработчик рассказал как</title>
      <link>https://tproger.ru/news/szhat-gosudarstvennuyu-vin-bazu-s-1-5-gb-do-21-mb--realno--razrabotchik-rasskazal-kak</link>
      <comments>https://tproger.ru/news/szhat-gosudarstvennuyu-vin-bazu-s-1-5-gb-do-21-mb--realno--razrabotchik-rasskazal-kak?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/szhat-gosudarstvennuyu-vin-bazu-s-1-5-gb-do-21-mb--realno--razrabotchik-rasskazal-kak</guid>
      <description><![CDATA[<p>Разработчик показал, как сократить государственную VIN-базу с 1,5 ГБ до 21 МБ: анализ данных, удаление лишних таблиц, индексов и грамотная оптимизация под чтение</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/szhat-gosudarstvennuyu-vin-bazu-s-1-5-gb-do-21-mb--realno--razrabotchik-rasskazal-kak">Сжать государственную VIN-базу с 1,5 ГБ до 21 МБ? Реально! Разработчик рассказал как</a>»</p>]]></description>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 25 Dec 2025 09:27:38 GMT</pubDate>
      <content:encoded><![CDATA[<p>Команда разработчиков офлайн-декодера VIN — <b>Corgi</b> — столкнулась с типичной проблемой государственных данных.</p><p>База VPIC от National Highway Traffic Safety Administration <b>весила 1,5 ГБ</b>. Для серверов это нормально, но для браузеров, edge-платформ и мобильных устройств — <b>почти приговор</b>.</p><p>У такой базы целый ворох проблем. От долгого скачивания и съедания чрезмерной памяти, до поломки serverless-запусков и невозможности работать с приложениями, которые должны запускаться «везде».</p><p>При этом именно VPIC считается официальным и самым полным источником данных для расшифровки VIN в США.</p><h2>Анализ вместо «магической оптимизации»</h2><p>Первое, что сделали разработчики — это <b>разобрали базу по частям</b>. С помощью SQLite-инструментов они посмотрели, какие таблицы реально занимают место.</p><p>Оказалось, что <b>почти 850 МБ</b> приходилось на одну таблицу, которая хранила соответствие кодов производителей и модельных годов.</p><p>Ключевой вывод: <b>эти данные можно вычислять на лету из других таблиц</b>. Таблицу удалили и база сразу похудела больше чем наполовину.</p><p>Дальше команда пошла по тому же пути: <b>не сжимать, а выкидывать лишнее</b>. Из базы убрали шаблоны и справочники, которые нужны регуляторам, но почти никогда не используются в прикладных VIN-декодерах.</p><h2>Оптимизация под реальное использование</h2><p>Следующий шаг — чистка «мертвых» данных. После удаления части таблиц, <b>в базе остались записи, на которые больше никто не ссылался</b>. Их тоже убрали.</p><p>Затем команда пересобрала индексы. Оригинальная база оптимизирована под регулярные обновления — ведь государство ее постоянно дополняет. Corgi же использует базу только для чтения.</p><p>Это позволило удалить лишние индексы и создать новые, заточенные под самые частые запросы при декодировании VIN.</p><p>И финальный штрих — VACUUM, чтобы SQLite физически пересобрал файл без мусора.</p><h2>Результат: минус гигабайты, плюс скорость</h2><p>В итоге <b>размер базы сократился с 1,5 ГБ до 64 МБ</b> в несжатом виде. <b>После gzip — всего 21 МБ</b>. При этом декодирование стало даже быстрее: таблицы меньше, индексы точнее, а лишних данных нет.</p><p>Оптимизированную базу упаковали в open-source библиотеку Corgi, которая работает офлайн и одинаково подходит для сервера, браузера и edge-окружений.</p>]]></content:encoded>
    </item>
    <item>
      <title>Создание простой поисковой системы, которая действительно работает</title>
      <link>https://tproger.ru/articles/sozdanie-prostoj-poiskovoj-sistemy--kotoraya-dejstvitelno-rabotaet</link>
      <comments>https://tproger.ru/articles/sozdanie-prostoj-poiskovoj-sistemy--kotoraya-dejstvitelno-rabotaet?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Иван]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sozdanie-prostoj-poiskovoj-sistemy--kotoraya-dejstvitelno-rabotaet</guid>
      <description><![CDATA[<p>Создайте свою собственную поисковую систему на PHP без внешних сервисов. Используйте токенизацию, веса и реляционные базы данных для точного и быстрого поиска по тексту. Полное руководство по реализации, индексированию и поиску.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sozdanie-prostoj-poiskovoj-sistemy--kotoraya-dejstvitelno-rabotaet">Создание простой поисковой системы, которая действительно работает</a>»</p>]]></description>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Рекомендательные системы]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 21 Nov 2025 09:12:42 GMT</pubDate>
      <content:encoded><![CDATA[<h2>Зачем строить свой собственный?</h2><p>Зачем вообще делать что-то своё?</p><p>Я знаю, что вы можете подумать: «Почему бы просто не использовать Elasticsearch?» или «А что насчёт Algolia?» Это вполне рабочие решения, но у них есть нюансы. Нужно разбираться с их API, поддерживать инфраструктуру под них и учитывать все тонкости их работы.</p><p>Но иногда хочется чего-то более простого — такого, что:</p><ul><li>работает прямо с вашей текущей базой данных;</li><li>не требует сторонних сервисов;</li><li>легко понять и отладить;</li><li>действительно выдаёт релевантные результаты.</li></ul><p>Поэтому я и сделал свою систему поиска — такую, которая использует вашу существующую БД, вписывается в архитектуру проекта и даёт полный контроль над тем, как она работает.</p><h2>Основная идея</h2><p>Концепция проста: разбить текст на токены, сохранить их, а затем при поиске сопоставлять токены запроса с токенами в индексе.</p><p>Процесс выглядит так:</p><ul><li>Индексация. Когда вы добавляете или обновляете данные, система разбивает текст на токены (слова, префиксы, n-граммы) и сохраняет их вместе с весами.</li><li>Поиск. Когда пользователь вводит запрос, он проходит такую же токенизацию. Затем система ищет совпадающие токены и подбирает подходящие документы.</li><li>Оценка. Сохранённые веса используются для расчёта итоговой релевантности.</li></ul><p>Вся суть — в том, как выполняется токенизация и как рассчитываются веса. Сейчас я покажу, что именно имеется в виду.</p><h2>Строительный блок 1: схема базы данных</h2><p>Для начала нам нужны всего две таблицы: index_tokens и index_entries.</p><h2>index_tokens</h2><p>В этой таблице хранятся все уникальные токены вместе с их весами, полученными от разных токенизаторов.</p><p>Важно: один и тот же токен может встречаться несколько раз с разными весами — по одному для каждого токенизатора.</p><figure><img src="https://media.tproger.ru/user-uploads/134517/2025-11-19/9429ca06-ac31-48ea-857e-70fab73c92e8.png" alt="" /></figure><h2>Почему так?</h2><p>Потому что разные токенизаторы создают один и тот же токен, но с разным весом.</p><p>Например, токен parser:</p><ul><li>WordTokenizer → вес 20</li><li>PrefixTokenizer → вес 5</li></ul><p>Чтобы итоговый механизм оценки релевантности работал правильно, нужны отдельные записи.</p><p>Ограничение уникальности в этой таблице — (name, weight).</p><p>То есть имя токена может повторяться, но вес — нет.</p><h2>index_entries</h2><p>Эта таблица связывает:</p><ul><li>токен</li><li>документ</li><li>конкретное поле документа</li></ul><p>…и хранит итоговый вес, который нужен для процедуры ранжирования.</p><h2>Структура таблицы index_entries</h2><figure><img src="https://media.tproger.ru/user-uploads/134517/2025-11-19/3cd82554-37a8-4530-90a6-173ef6613753.png" alt="" /></figure><h2>Что такое weight?</h2><p>Это итоговый вычисленный вес токена для конкретного поля конкретного документа.</p><p>Формула:</p><p>Он уже включает всё, что понадобится позже при начислении очков.</p><h2>Какие индексы добавляем?</h2><p>Чтобы поиск работал быстро:</p><ul><li>(document_type, document_id) — для быстрого получения документов</li><li>token_id — чтобы быстро находить все документы по токену</li><li>(document_type, field_id) — для поиска по конкретному полю</li><li>weight — для фильтрации по весам</li></ul><h2>Почему именно такая схема?</h2><p>Потому что она:</p><ul><li>простая</li><li>эффективно ложится на реляционные БД</li><li>использует сильные стороны SQL</li><li>позволяет масштабировать алгоритм без усложнений</li></ul><h2>Блок 2: токенизация</h2><h2>Что такое токенизация?</h2><p>Это процесс разбивки текста на более мелкие части — токены, удобные для поиска.</p><p>Например, слово «parser» можно разбить разными способами:</p><ul><li>Как одно целое: ["parser"]</li><li>На префиксы: ["par", "pars", "parse", "parser"]</li><li>На n-граммы (последовательности символов): ["par", "ars", "rse", "ser"]</li></ul><h2>Зачем несколько токенизаторов?</h2><p>Разные задачи требуют разных подходов к поиску:</p><ul><li>Один токенизатор для точных совпадений</li><li>Другой — для частичных совпадений</li><li>Третий — для учёта опечаток</li></ul><p>Каждый из них играет свою роль в итоговом ранжировании.</p><h2>Общий интерфейс токенизатора</h2><p>Все токенизаторы реализуют простой интерфейс:</p><p>Простой и расширяемый контракт.</p><h2>Токенизатор слов (WordTokenizer)</h2><p>Разбивает текст на отдельные слова. Слово «parser» превращается в</p><p>Этот метод отлично подходит для точных совпадений.</p><p>Вес: 20 — высокий, для точных совпадений.</p><h2>Префиксный токенизатор (PrefixTokenizer)</h2><p>Создаёт префиксы слов, например:</p><p>→</p><p>(минимальная длина префикса — 4).</p><p>Это полезно для поиска по частям слова и автодополнения.</p><p>Вес: 5 — средний, для частичных совпадений.</p><p>Зачем минимальная длина?</p><p>Чтобы избежать слишком большого количества коротких токенов — префиксы короче 4 символов обычно слишком распространены и малоэффективны.</p><h2>Токенизатор n-грамм (NGramsTokenizer)</h2><p>Создаёт последовательности символов фиксированной длины (обычно 3).</p><p>Например,</p><p>→</p><p>.</p><p>Это помогает улавливать опечатки и частичные совпадения.</p><p>Вес: 1 — низкий, но улавливает редкие случаи и опечатки.</p><p>Почему длина 3?</p><p>Это компромисс между слишком большим количеством совпадений и пропущенными вариантами из-за опечаток.</p><h2>Блок 3: Система весов</h2><p>В нашей системе есть три уровня весов, которые работают вместе, чтобы определить важность каждого токена при поиске:</p><ol><li>Вес поля — например, заголовок, основное содержание или ключевые слова. Разные части документа могут иметь разный приоритет.</li><li>Вес токенизатора — каждый тип токенизатора (слово, префикс, n-грамма) имеет свой вес. Эти веса хранятся в таблице index_tokens.</li><li>Вес документа — итоговый вес для конкретного токена в конкретном документе. Хранится в index_entries и рассчитывается по формуле:</li></ol><h2>Как рассчитывается итоговый вес?</h2><p>Во время индексации для каждого токена мы считаем вес так:</p><p>Например:</p><ul><li>Вес поля заголовка: 10</li><li>Вес токенизатора слов: 20</li><li>Длина токена «parser»: 6</li></ul><p>Тогда итоговый вес:</p><h2>Почему используется ceil(sqrt())?</h2><ul><li>Более длинные токены обычно более специфичны и важны — например, «parser» конкретнее, чем «par».</li><li>Но мы не хотим, чтобы очень длинные токены имели слишком большой вес — 100-символьный токен не должен давать вес в 100 раз больше, чем короткий.</li><li>Функция квадратного корня даёт убывающую доходность — вес растёт с длиной, но не линейно.</li><li>ceil() округляет результат вверх, чтобы сохранить веса целыми числами.</li></ul><h2>Настройка весов под свои задачи</h2><p>Вы можете гибко настраивать веса под свои нужды:</p><ul><li>Увеличить вес поля — например, если заголовки для вас важнее всего.</li><li>Изменить вес токенизатора — повысить для точных совпадений (слов), понизить для менее важных (n-граммы).</li><li>Изменить формулу для длины токена — вместо ceil(sqrt()) можно использовать логарифм или линейную функцию, чтобы по-другому влиять на вес длинных токенов.</li></ul><p>Таким образом, вы можете точно контролировать, какие части текста и какие типы совпадений важнее при поиске, и подстроить систему под свои требования.</p><h2>Блок 4: Служба индексирования</h2><p>Служба индексирования отвечает за обработку документов и сохранение всех их токенов в базе данных для последующего быстрого поиска.</p><h2>Интерфейс для документов</h2><p>Чтобы документ мог индексироваться, он должен реализовать интерфейс</p><p>с тремя методами:</p><ul><li>getDocumentId() — возвращает уникальный идентификатор документа.</li><li>getDocumentType() — возвращает тип документа (например, статья, пост, комментарий).</li><li>getIndexableFields() — возвращает поля документа, которые нужно индексировать, вместе с их весами.</li></ul><p>Пример реализации для статьи:</p><h2>Когда индексируем?</h2><ul><li>При создании или обновлении документа (например, через события).</li><li>По командам в консоли — например, app:index-document или app:reindex-documents.</li><li>Через задачи cron для массовой переиндексации.</li></ul><h2>Как работает индексирование — шаг за шагом</h2><ol><li>Получаем данные документа: его тип, ID и поля с весами.</li><li>Удаляем старый индекс для этого документа. Это важно, чтобы избежать дублирования данных.</li><li>Для каждого поля запускаем все токенизаторы, которые разбивают текст на токены.</li><li>Для каждого токена:Находим или создаём его в таблице токенов (чтобы не хранить одинаковые токены несколько раз).Рассчитываем итоговый вес по формуле:вес_поля × вес_токенизатора × ceil(квадратный_корень_из_длины_токена) Добавляем информацию в пакет для массовой вставки.Вставляем все новые записи в базу данных одним запросом — так быстрее и эффективнее.</li><li>Находим или создаём его в таблице токенов (чтобы не хранить одинаковые токены несколько раз).</li><li>Рассчитываем итоговый вес по формуле:вес_поля × вес_токенизатора × ceil(квадратный_корень_из_длины_токена) Добавляем информацию в пакет для массовой вставки.Вставляем все новые записи в базу данных одним запросом — так быстрее и эффективнее.</li></ol><h2>Зачем искать или создавать токены?</h2><p>Токены — это общие элементы для всех документов. Если токен уже есть, используем его повторно, чтобы не хранить дубли и сэкономить место и время.</p><ol><li>Ключевые моментыСтарый индекс удаляется перед созданием нового — это упрощает обновление.Используется пакетная вставка для производительности.Токены ищутся или создаются, чтобы избежать дубликатов.Итоговый вес считается динамически при индексации.</li><li>Ключевые моментыСтарый индекс удаляется перед созданием нового — это упрощает обновление.Используется пакетная вставка для производительности.Токены ищутся или создаются, чтобы избежать дубликатов.Итоговый вес считается динамически при индексации.</li><li>Старый индекс удаляется перед созданием нового — это упрощает обновление.</li><li>Используется пакетная вставка для производительности.</li><li>Токены ищутся или создаются, чтобы избежать дубликатов.</li><li>Итоговый вес считается динамически при индексации.</li></ol><h2>Блок 5: Служба поиска</h2><p>Поисковый сервис принимает строку запроса, разбивает её на токены, ищет эти токены в индексах и возвращает список документов, отсортированных по релевантности.</p><h2>Как это работает — шаг за шагом</h2><ol><li>Токенизация запроса</li></ol><p>Запрос разбивается на токены с помощью того же набора токенизаторов, который использовался при индексации документов. Это важно, чтобы поиск и индексирование были синхронизированы.</p><p>Пример:</p><ul><li>Индексация создала токены: par, pars, parse, parser (префиксный токенизатор).</li><li>Поиск тоже использует префиксный и обычный токенизатор — так мы найдём не только точное слово parser, но и все его варианты.</li></ul><p>Если запрос пустой (нет токенов), возвращаем пустой результат.</p><ol><li>Уникальные токены</li></ol><p>Из всех токенов берём только уникальные значения, чтобы не искать одинаковые токены по несколько раз.</p><ol><li>Сортировка токенов</li></ol><p>Токены сортируются по длине — сначала самые длинные. Это важно, потому что более длинные токены — более конкретные и дают более точные совпадения.</p><ol><li>Ограничение количества токенов</li></ol><p>Если пользователь отправит очень длинный запрос, мы ограничиваем число токенов (например, максимум 300), чтобы избежать нагрузок на систему.</p><ol><li>Выполнение поискового SQL-запроса</li></ol><p>Далее строится и выполняется оптимизированный SQL-запрос, который:</p><ul><li>Ищет документы, где встречаются эти токены.</li><li>Считает оценку релевантности для каждого документа.</li><li>Сортирует результаты по убыванию оценки.</li><li>Возвращает ограниченное число результатов (например, топ-10).</li></ul><h2>Как считается оценка релевантности?</h2><p>Оценка складывается из нескольких факторов:</p><ul><li>Базовый балл — сумма весов всех найденных токенов в документе.</li><li>Разнообразие токенов — документы с большим количеством разных токенов получают бонус (логарифмическая шкала, чтобы не давать слишком большой перевес).</li><li>Качество совпадений — чем выше средний вес токенов, тем лучше (например, совпадение в заголовке важнее, чем в теле текста).</li><li>Штраф за длину документа — чтобы длинные документы не имели слишком большое преимущество.</li></ul><p>В итоге оценка нормализуется на максимальное значение, чтобы можно было сравнивать разные поисковые запросы.</p><h2>Почему нужен подзапрос с весом токенов?</h2><p>В подзапросе проверяется, что документ содержит хотя бы один токен с весом выше порогового. Это исключает из результатов документы, которые совпадают только по «шумным» токенам с очень маленьким весом (например, незначительным n-граммам), что улучшает качество поиска.</p><h2>Пример возвращаемого результата</h2><p>Поиск возвращает список таких объектов — ID документа и его релевантность.</p><h2>Как получить сами документы?</h2><p>Мы берём ID из результатов поиска, и через репозиторий загружаем реальные объекты документов, сохраняя порядок релевантности.</p><p>Репозиторий гарантирует, что документы вернутся в том же порядке, что и результаты поиска (используется SQL-функция</p><h2>Итог</h2><p>В результате вы получаете мощную и гибкую поисковую систему, которая:</p><ul><li>Быстро находит релевантные документы через индексы в базе данных.</li><li>Обрабатывает опечатки и частичные совпадения с помощью n-грамм и префиксных токенизаторов.</li><li>Придаёт больше веса точным совпадениям (например, полным словам).</li><li>Работает без внешних сервисов — только с базой данных.</li><li>Легко отлаживается и настраивается за счёт прозрачного SQL и гибких весов.</li></ul><h2>Расширение системы</h2><h2>Добавление нового токенизатора</h2><p>Чтобы добавить новый способ разбиения текста на токены (например, стемминг, лемматизацию, синонимы и т.д.), нужно:</p><ul><li>Реализовать интерфейс TokenizerInterface, например:</li></ul><p>Зарегистрировать этот токенизатор в конфигурации сервиса — и он автоматически будет использоваться и для индексации, и для поиска.</p><h2>Добавление нового типа документа</h2><p>Чтобы индексировать новый тип документов (например, комментарии, статьи, профили), реализуйте интерфейс:</p><h2>Изменение весов и формул</h2><ul><li>Вес токенизаторов и полей легко настраивается через конфигурацию.</li><li>Формулы подсчёта релевантности находятся в SQL-запросе — вы можете его изменить, чтобы подстроить оценивание под свои задачи.</li></ul><h2>Заключение</h2><ul><li>Это простая и понятная поисковая система — нет сложных «черных ящиков» и магии.</li><li>Она легко контролируется, настраивается и отлаживается.</li><li>Подходит для большинства приложений, где не нужна гигантская инфраструктура типа Elasticsearch.</li><li>Главное — вы полностью управляете системой, понимаете каждый её шаг и можете улучшать её под свои нужды.</li></ul><p>Берите и делайте под себя — это ваш поиск, и он должен работать так, как вам нужно.</p>]]></content:encoded>
    </item>
    <item>
      <title>Разработчик Yandex Cloud вошел в топ-50 контрибьюторов PostgreSQL в мире</title>
      <link>https://tproger.ru/news/razrabotchik-yandex-cloud-vowel-v-top-50-kontribyutorov-postgresql-v-mire</link>
      <comments>https://tproger.ru/news/razrabotchik-yandex-cloud-vowel-v-top-50-kontribyutorov-postgresql-v-mire?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/razrabotchik-yandex-cloud-vowel-v-top-50-kontribyutorov-postgresql-v-mire</guid>
      <description><![CDATA[<p>Разработчик Yandex Cloud Андрей Бородин вошел в топ-50 контрибьюторов PostgreSQL — 10 лет в проекте и сотни апстрим-патчей в ядро</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/razrabotchik-yandex-cloud-vowel-v-top-50-kontribyutorov-postgresql-v-mire">Разработчик Yandex Cloud вошел в топ-50 контрибьюторов PostgreSQL в мире</a>»</p>]]></description>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Яндекс]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 10 Nov 2025 06:35:33 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>Андрей Бородин</b>, руководитель разработки СУБД с открытым исходным кодом в <b>Yandex Cloud</b>, <a href="https://www.cnews.ru/news/line/2025-11-10_razrabotchik_yandeksa_voshel">вошел</a> в список <b>топ-50 крупнейших контрибьюторов PostgreSQL</b>.</p><h2>10 лет в развитии PostgreSQL</h2><p>Бородин получил статус топ-контрибьютора спустя <b>10 лет активного участия</b> в развитии сообщества и кодовой базы PostgreSQL.</p><p>При этом и команда Yandex Cloud активно сотрудничает с сообществом PostgreSQL. Каждый год в релизы СУБД попадает множество доработок от инженеров компании.</p><p>Процесс принятия изменений в ядро PostgreSQL считается одним из самых строгих в мире open-source, поэтому успешный апстрим-патч — <b>знак качества и зрелости кода</b>.</p><p>Кроме ядра, команда Яндекса развивает собственные опенсорс-решения. Например, <b>SPQR</b> — на его основе в сентябре 2025 года был запущен сервис <b>Managed Service for Shared PostgreSQL</b>.</p><p>Он обеспечивает <b>горизонтальное масштабирование</b> баз данных через шардирование — разделение данных между разными серверами.</p><h2>Кто такой Андрей Бородин</h2><p>До работы в Yandex Cloud, Бородин был инженером в <b>AWS</b>, а сейчас совмещает разработку с преподаванием в <b>ШАД «Яндекса»</b> и <b>Уральском федеральном университете</b>.</p><p>Первый патч в PostgreSQL он закоммитил еще в <b>2016 году</b>. С тех пор он уже <b>четырежды попадал в годовой топ-50 контрибьюторов проекта</b>.</p>]]></content:encoded>
    </item>
    <item>
      <title>SQL-оптимизация: 5 запросов, которые ломают базу</title>
      <link>https://tproger.ru/articles/sql-optimizaciya--5-zaprosov--kotorye-lomayut-bazu</link>
      <comments>https://tproger.ru/articles/sql-optimizaciya--5-zaprosov--kotorye-lomayut-bazu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/sql-optimizaciya--5-zaprosov--kotorye-lomayut-bazu</guid>
      <description><![CDATA[<p>Типовые SQL-запросы, которые тормозят базу: от JOIN без условий до DISTINCT в лоб. Почему они опасны и как их переписать правильно, чтобы база работала быстро и стабильно.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/sql-optimizaciya--5-zaprosov--kotorye-lomayut-bazu">SQL-оптимизация: 5 запросов, которые ломают базу</a>»</p>]]></description>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 15 Oct 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Оптимизация SQL-запросов — это набор вполне конкретных правил, нарушение которых может положить любую базу. Даже один неудачный JOIN или ORDER BY без индекса способны превратить быструю систему в тормозящую. Мы собрали типовые запросы, которые чаще всего убивают производительность, объяснили, почему они опасны, и показали, как переписать их правильно.</p><h2>1. Запросы без ограничений</h2><p>Запрос:</p><h3>Почему он опасен</h3><p>Такие запросы тянут абсолютно все данные из таблицы, даже если нужны 2–3 поля. На больших таблицах это превращается в тяжелую нагрузку на сервер: растет объём передаваемых данных, замедляется отклик, падает производительность. Если запрос используют в проде (например, при каждом открытии страницы), он легко может «задушить» базу под пиковыми нагрузками.</p><h3>Как переписать правильно</h3><p>или</p><p>Важно явно указывать необходимые поля и добавлять LIMIT, если не нужны все строки сразу. Это снижает нагрузку и ускоряет ответ.</p><h2>2. WHERE без индексов</h2><p>Запрос:</p><h3>Почему он опасен</h3><p>Если по полю status нет индекса, база будет проходить всю таблицу построчно (full table scan), чтобы найти нужные строки. На таблицах с миллионами записей это приводит к заметной деградации производительности, особенно при частых запросах. Если таких фильтров несколько, нагрузка на сервер растет лавинообразно.</p><h3>Как переписать правильно</h3><p>Добавить индекс по фильтруемому полю:</p><p>Переписать запрос, чтобы он использовал индекс:</p><p>Если поле часто используется в фильтрах или джоинах — индексировать его почти всегда оправдано. Это резко ускоряет поиск и снижает нагрузку.</p><h2>3. GROUP BY и агрегаты по большим таблицам</h2><p>Запрос:</p><h3>Почему он опасен</h3><p>GROUP BY заставляет базу данных сначала обработать все строки, а потом сгруппировать их в памяти или на диске. Если таблица содержит миллионы записей и нет подходящих индексов, такой запрос приводит к сортировке или хэшированию огромных объёмов данных. Итог — долгие выполнения, рост потребления оперативной памяти и, в худшем случае, временные таблицы на диске (disk spill). Дополнительную нагрузку дают агрегаты (COUNT, SUM, AVG и др.) без фильтров — база пересчитывает их для всех строк, даже если вам нужна малая часть.</p><h3>Как переписать правильно</h3><p>Ограничить выборку с помощью фильтров до агрегации:</p><p>Добавить индекс по ключу группировки:</p><p>Если данные статичны — использовать материализованные представления или промежуточные агрегации, чтобы не пересчитывать заново каждый раз.</p><p>GROUP BY хорошо работает на подготовленных и отфильтрованных данных. Если он упирается в «сырые» миллионы строк — это сигнал к пересмотру логики запроса.</p><h2>4. Подзапросы в WHERE (особенно некоррелированные)</h2><p>Запрос</p><h3>Почему он опасен</h3><p>Подзапрос в WHERE нередко превращается в лишний проход по таблице. Если оптимизатор не умеет эффективно преобразовать подзапрос в JOIN, он будет сначала выполнять подзапрос (часто без индексов), а потом сверять результаты с основной таблицей. При больших объёмах это означает десятки тысяч сравнений и скачки производительности. Особенно опасны некоррелированные подзапросы, которые не зависят от внешнего запроса — они могут выполняться повторно или создавать временные таблицы.</p><h3>Как переписать правильно</h3><p>Заменить подзапрос на JOIN:</p><p>Убедиться, что по ключам соединения и фильтрации (customer_id, country) есть индексы:</p><p>Если подзапрос всё же нужен — использовать EXISTS, а не IN, чтобы оптимизатор мог «коротко замыкать» проверку:</p><p>Подзапросы — удобный синтаксис, но не всегда эффективный. JOIN и индексы почти всегда работают быстрее, особенно на больших таблицах.</p><h2>5. ORDER BY без индекса</h2><p>Запрос</p><h3>Почему он опасен</h3><p>Когда вы используете ORDER BY по колонке без индекса, база вынуждена сортировать всю выборку в памяти или на диске. Это означает дополнительную нагрузку на CPU, а при больших объёмах данных — полную деградацию производительности. Часто такие запросы встречаются в продакшене в виде пагинации по миллионам строк. В итоге простой «листинг заказов» превращается в многосекундный или даже минутный ответ.</p><h3>Как переписать правильно</h3><p>Добавить индекс по полю сортировки:</p><p>Ограничить выборку с помощью LIMIT и пагинации:</p><p>Использовать составные индексы, если сортировка идёт вместе с фильтром:</p><p>А какие запросы убивают вашу базу? пишите в комментариях!</p>]]></content:encoded>
    </item>
    <item>
      <title>Вышел Bun 1.3: full-stack рантайм, поддержка Redis и новый SQL API. Разобрались, что еще нового</title>
      <link>https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo</link>
      <comments>https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo</guid>
      <description><![CDATA[<p>Bun 1.3 стал full-stack рантаймом с Redis, SQL API, поддержкой MySQL и PostgreSQL, новым тест-раннером и ускорением сборки до 2,5 раз</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/vywel-bun-1-3--full-stack-rantajm--podderzhka-redis-i-novyj-sql-api--razobralis--chto-eshhe-novogo">Вышел Bun 1.3: full-stack рантайм, поддержка Redis и новый SQL API. Разобрались, что еще нового</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 13 Oct 2025 04:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Команда <b>Oven</b> <a href="https://bun.com/blog/bun-v1.3">представила</a> <b>Bun 1.3</b> — крупнейший релиз в истории JavaScript-рантайма.</p><p>Теперь Bun официально позиционируется как <b>full-stack платформа</b> для фронтенда и бэкенда. И она объединяет сервер, сборщик, менеджер пакетов вместе с тест-раннером в одном инструменте.</p><p>В новую версию добавлены десятки ключевых функций: встроенные клиенты для <b>Redis</b>, <b>MySQL</b>, <b>PostgreSQL</b> и <b>SQLite</b>, единый <b>SQL API</b>, улучшенные <b>WebSocket-модули</b>, переработанный <b>тест-раннер</b> и поддержка <b>VSCode Test Explorer</b>.</p><h2>Full-stack по-умному</h2><p>Главное новшество — режим <b>full-stack Bun.serve()</b> с поддержкой роутинга, cookies и WebSockets.</p><p>Теперь фронтенд и бэкенд можно запускать в одном процессе без проблем с CORS, а приложение собрать в <b>единый исполняемый файл</b> с помощью bun build --compile.</p><p>Разработчики могут напрямую импортировать HTML, запускать React-приложения с хот-перезагрузкой и собирать проект одной командой bun init --react. По данным команды, скомпилированные React-приложения в Bun работают <b>до 1,8 раза быстрее, чем через nginx</b>.</p><h2>Новый SQL и встроенный Redis</h2><p>Bun 1.3 представил унифицированный <b>Bun.SQL API</b> — теперь один и тот же код работает с MySQL, PostgreSQL, SQLite и MariaDB. Добавлен хелпер sql.array() для работы с массивами в PostgreSQL, улучшена поддержка JSON и Unix-сокетов.</p><p>Кроме того, в рантайм встроен <b>Redis-клиент</b>, который поддерживает 66 команд, автоматическое переподключение, очереди сообщений и Pub/Sub. По данным разработчиков, он <b>значительно быстрее ioredis</b>, а поддержка кластеров и Lua-скриптов появится в будущих релизах.</p><h2>Новые возможности</h2><p>Среди прочих улучшений — <b>Zstandard-сжатие</b>, нативная поддержка <b>YAML</b>, API для безопасного хранения секретов (<b>Bun.secrets</b>), и серьезный прирост производительности: операции с криптографией ускорены <b>до 400х</b>, установка пакетов — <b>до 2,5х</b>.</p><p>Также обновлен менеджер пакетов с <b>интерактивным bun update</b>, изолированными установками и API для проверки безопасности зависимостей.</p><h2>Почему это важно</h2><p>Bun 1.3 превращает экспериментальный рантайм в <b>полноценную платформу для веб-разработки</b>, способную заменить Node.js, Vite и Redis-CLI одновременно.</p><p>Разработчики называют релиз «началом новой эпохи», цель которой — сделать Bun лучшим способом писать и развертывать JavaScript-приложения.</p>]]></content:encoded>
    </item>
    <item>
      <title>Post-GraphQL мир: стоит ли переходить на gRPC и tRPC</title>
      <link>https://tproger.ru/articles/post-graphql-mir--stoit-li-perehodit-na-grpc-i-trpc</link>
      <comments>https://tproger.ru/articles/post-graphql-mir--stoit-li-perehodit-na-grpc-i-trpc?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/post-graphql-mir--stoit-li-perehodit-na-grpc-i-trpc</guid>
      <description><![CDATA[<p>Подробное сравнение технологий API для разработчиков. Разбираем сильные и слабые стороны GraphQL, gRPC и tRPC на реальных кейсах. Практические рекомендации по выбору технологии для вашего проекта.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/post-graphql-mir--stoit-li-perehodit-na-grpc-i-trpc">Post-GraphQL мир: стоит ли переходить на gRPC и tRPC</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Post-GraphQL]]></category>
      <category><![CDATA[gRPC]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Oct 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Архитектура API постоянно меняется. Несколько лет назад GraphQL казался панацеей от всех болезней REST. Сегодня всё чаще говорят о двух других технологиях — gRPC и tRPC. Это не означает, что GraphQL уже не актуален — он нашёл свою нишу и продолжает развиваться, но это уже не универсальное решение для любых задач. Фреймворки gRPC и tRPC открывают принципиально иные подходы к построению API. Они решают конкретные проблемы в конкретных контекстах.</p><p>Узнаем, что предлагает Post-GraphQL мир, в чём плюсы и минусы фреймворков gRPC и tRPC и в каких ситуациях стоит пользоваться новыми инструментами.</p><h2>От монолитов к микросервисам: как мы здесь оказались</h2><p>Чтобы понять современный ландшафт API, вернёмся на несколько лет назад. REST доминировал десятилетиями. Этот подход прост для понимания, но имеет фундаментальные проблемы.</p><p>Типичный сценарий разработки под REST выглядел так: фронтендеры постоянно просили бэкендеров добавить новые поля в ответы API или создать новые эндпоинты. Возникала тесная связь между командами, что замедляло разработку.</p><p>GraphQL решил эти проблемы, предоставив клиентам возможность запрашивать именно те данные, которые им нужны. Один запрос вместо десятков, строгая типизация, интроспекция — всё это сделало GraphQL популярным.</p><p>Но идеальных технологий не существует. GraphQL принёс свои сложности:</p><ul><li>кэширование на клиенте стало нетривиальной задачей;</li><li>сложные запросы создавали нагрузку на сервер;</li><li>необходимость изучать новый язык запросов отпугивала разработчиков.</li></ul><p>Эволюция продолжилась. Сегодня мы видим, как экосистема разделилась на два основных направления: высокопроизводительные межсервисные коммуникации (gRPC) и бесшовную разработку полного стека на TypeScript (tRPC).</p><h2>gRPC: высокопроизводительная связность для микросервисов</h2><p>gRPC — не просто ещё один протокол, а полноценная экосистема для построения эффективных распределённых систем. Технология создана Google для внутренних нужд, где критически важны производительность и надёжность.</p><p>gRPC использует Protocol Buffers (protobuf) в качестве языка описания интерфейсов и формата сериализации. Это бинарный формат, который значительно эффективнее текстового JSON. Сообщения занимают меньше места и быстрее обрабатываются.</p><p>HTTP/2 — ещё один козырь gRPC. Этот протокол поддерживает мультиплексирование запросов, server push и двунаправленные потоки. В отличие от традиционных HTTP-запросов, gRPC может работать с постоянными соединениями и потоковой передачей данных в реальном времени.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/ca6ce939-89ec-4b24-b4e4-dbccf40845cd.png" alt="" /></figure><h2>Когда gRPC действительно сияет</h2><p>gRPC идеально подходит для микросервисных архитектур, где сервисы общаются друг с другом внутри защищенной сети. Финансовые системы, телекоммуникационные платформы, игровые серверы — везде, где важны эффективность и минимальное время отклика.</p><p>Сильная сторона gRPC — потоковая передача данных. Представьте систему мониторинга, где сервер постоянно отправляет метрики, или чат-приложение с тысячами одновременных соединений. gRPC справляется с такими задачами лучше REST или GraphQL благодаря встроенной поддержке потоков на уровне протокола HTTP/2.</p><p>В отличие от REST, который требует постоянного установления новых HTTP-соединений, gRPC поддерживает двунаправленные потоки в рамках одного соединения, что снижает накладные расходы и позволяет эффективнее использовать сетевые ресурсы.</p><p>Межъязыковое взаимодействие — ещё одно преимущество. У вас могут быть сервисы на Go, Python, Java и C++, которые легко общаются между собой благодаря сгенерированному коду из protobuf-файлов.</p><h2>Ограничения gRPC</h2><p>Браузерная поддержка требует дополнительных усилий. Нативные gRPC-клиенты в браузерах не работают, нужен прокси gRPC-Web. Это добавляет сложности в настройке.</p><p>Человекочитаемость сообщений оставляет желать лучшего. Бинарный формат protobuf неудобен для отладки без специальных инструментов. Разработчики часто используют JSON-эквиваленты для разработки, жертвуя производительностью.</p><p>gRPC требует кодогенерации. При каждом изменении API нужно обновлять protobuf-файлы и перегенерировать код для всех языков. Это добавляет лишний шаг в процесс разработки.</p><h2>tRPC: типобезопасность без схем и кодогенерации</h2><p>tRPC занимает противоположную нишу. Это технология для полного стека на TypeScript, где важны скорость разработки и типобезопасность.</p><p>Философия tRPC — минимализм. Не нужны схемы, кодогенерация, сложные настройки. Вы определяете процедуры (запросы и мутации) на TypeScript, а клиент автоматически получает информацию о типах.</p><p>tRPC использует обычный HTTP поверх HTTP/1.x, что делает его совместимым с любым браузером. Транспортный формат — JSON, который легко отлаживать с помощью стандартных инструментов разработчика.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/f029279a-d51f-4666-bb04-1f409c22b18f.jpg" alt="" /></figure><h2>Сильные стороны tRPC</h2><p>Скорость разработки — главный плюс tRPC. Изменения на сервере сразу отражаются в типах на клиенте. Не нужно ждать кодогенерации или вручную синхронизировать типы.</p><p>Идеальная интеграция с экосистемой TypeScript. Если ваш стек — Next.js, React, Prisma и TypeScript, то tRPC станет естественным выбором. Разработка напоминает работу с монолитом, но с распределённой архитектурой.</p><p>tRPC отлично работает в монорепозиториях. Один репозиторий содержит и клиент, и сервер, что упрощает синхронизацию версий и рефакторинг.</p><h2>Когда tRPC не подходит</h2><p>tRPC привязан к экосистеме TypeScript. Если у вас мультиязычная архитектура или вы планируете публичное API для клиентов на разных языках, tRPC — не лучший выбор.</p><p>Отсутствие схемы может быть ограничением. GraphQL-схема служит документацией и основой для инструментов вроде Apollo Studio. tRPC не предоставляет аналогичных возможностей для интроспекции API.</p><p>tRPC не решает проблему over-fetching на том же уровне, что GraphQL. Клиент не может точно указать, какие поля нужны в ответе — он получает всю структуру данных, определённую процедурой.</p><h2>Сравнительная таблица: gRPC vs GraphQL vs tRPC</h2><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/94988143-b27a-40e5-a33a-f84a3c5a8013.png" alt="" /></figure><h2>GraphQL рано списывать со счетов</h2><p>Несмотря на рост популярности gRPC и tRPC, GraphQL остаётся сильным игроком на рынке API. Технология развивается, появляются новые инструменты и практики:</p><ul><li><b>GraphiQL 2.0.</b> Не просто обновление, а полный редизайн официального инструмента для разработки запросов. Новая версия, разрабатываемая GraphQL Foundation, предлагает модульную архитектуру с поддержкой плагинов для расширения функциональности.</li><li><b>Apollo MCP Server.</b> Адаптация GraphQL к новейшим технологическим трендам, в частности — к интеграции с искусственным интеллектом. Apollo MCP Server позволяет подключать большие языковые модели (LLM) и AI-системы к вашим API через GraphQL, выступая для них стандартизированным и безопасным интерфейсом. Это решает такие проблемы AI, как необходимость детерминированного выполнения запросов и контроля политик доступа.</li><li><b>Автоматические постоянные запросы</b> (Automatic Persisted Queries, APQ). Клиент может отправлять на сервер не текст запроса, а его хэш. Сервер, заранее получивший полный запрос, выполняет его, найдя по хэшу. Это значительно сокращает объем передаваемых данных и ускоряет работу, особенно в мобильных сетях.</li></ul><p>GraphQL незаменим, когда у вас множество клиентов с разными требованиями к данным. Мобильное приложение, веб-интерфейс, партнерские интеграции — каждый может запросить именно те данные, которые нужны, без изменения серверной логики.</p><p>Эволюция GraphQL продолжается. Подходы вроде GraphQL Federation позволяют распределить схему между разными командами, что решает проблему монолитной схемы в больших организациях.</p><p>Инструменты вроде graphql-tada и Grats улучшают процесс разработки с GraphQL, приближая его к удобству tRPC. Они обеспечивают типобезопасность без потерь в гибкости.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/05238f17-ec27-4483-90d6-4340e984d173.png" alt="" /></figure><h2>Как выбрать: практические рекомендации</h2><p>Выбор технологии зависит от конкретного контекста. Не следуйте трендам вслепую — это приводит к архитектурным ошибкам. Вместо вопроса «Что сейчас модно?» спросите: «Какую проблему я решаю?».</p><p>Проанализируйте свой проект по нескольким ключевым параметрам. Ответы помогут принять взвешенное решение.</p><h2>Вопрос первый: какую проблему вы решаете?</h2><p>Разные технологии созданы для разных сценариев. Определите основную боль вашего проекта:</p><ul><li>Нужна высокая производительность для внутренней коммуникации микросервисов → gRPC. Бинарный протокол и HTTP/2 дают преимущество в скорости при частых вызовах между сервисами.</li><li>Хотите дать клиентам гибкость в запросах данных → GraphQL. Разные потребители API могут запрашивать только нужные поля без изменения серверной логики.</li><li>Разрабатываете full-stack приложение на TypeScript и хотите максимальной типобезопасности → tRPC. Единая типовая система от бэкенда до фронтенда ускоряет разработку и снижает количество ошибок.</li></ul><h2>Вопрос второй: какая у продукта архитектура?</h2><p>Технологический стек определяет доступные опции. Оцените текущую и планируемую инфраструктуру:</p><ul><li>Один язык программирования по всему стеку (TypeScript) → tRPC. Тесная интеграция с экосистемой TypeScript становится приоритетом.</li><li>Несколько языков (Go, Python, Java, etc.) → gRPC или GraphQL. gRPC обеспечивает эффективную коммуникацию между разнородными сервисами, а GraphQL подходит для публичного API.</li><li>Планируете масштабирование на разные платформы → GraphQL. Единая схема API работает с любым клиентом, независимо от языка или платформы.</li></ul><h2>Вопрос третий: кто потребители вашего API?</h2><p>Проанализируйте, кто будет использовать ваш API:</p><ul><li>Внутренние сервисы → gRPC. Высокая производительность и эффективность важнее человекочитаемости.</li><li>Внешние клиенты (мобильные приложения, партнеры) → GraphQL. Возможность точного запроса данных снижает нагрузку на сеть и упрощает интеграцию.</li><li>Собственный фронтенд на TypeScript → tRPC. Максимальная скорость разработки и типобезопасность окупают ограничения по браузерной поддержке.</li></ul><h2>Вопрос четвертый: каковы требования к инструментарию?</h2><p>Разработка не заканчивается на написании кода. Оцените важность сопутствующих инструментов:</p><ul><li>Важна интроспекция API и полноценная экосистема инструментов → GraphQL. Встроенная интроспекция и инструменты вроде Apollo Studio предоставляют мощные возможности для отладки и мониторинга.</li><li>Нужна максимальная производительность и минимальные накладные расходы → gRPC. Бинарный формат и HTTP/2 обеспечивают эффективную передачу данных.</li><li>Приоритет — скорость разработки и минимальная конфигурация → tRPC. Отсутствие схем и кодогенерации ускоряет итерации.</li></ul><h2>Дополнительные практические соображения</h2><p>Командная экспертиза играет важную роль. Любая новая технология требует времени на освоение. Оцените готовность команды изучать новые инструменты.</p><p>Операционные расходы — ещё один фактор. gRPC требует инфраструктуры для мониторинга бинарных протоколов. GraphQL нуждается в инструментах для анализа запросов и защиты от перегрузки.</p><p>Рассмотрите возможность гибридного подхода. Крупные проекты часто используют разные технологии для разных задач. Внутренняя коммуникация — gRPC, публичное API — GraphQL, админ-панель — tRPC.</p><p>Проведите пилотные испытания. Реальные нагрузки могут преподнести сюрпризы. Протестируйте выбранную технологию на критически важных сценариях перед полным внедрением.</p><h2>Почему гибридные подходы набирают популярность</h2><p>Современные приложения редко бывают простыми. Один продукт может включать мобильное приложение, веб-интерфейс, админ-панель и интеграции с партнерами. Каждый компонент имеет уникальные требования к API.</p><p>Монолитная архитектура API часто не справляется с разнородными нагрузками. Один протокол пытается угодить всем, но в итоге не идеален ни для кого. Гибридный подход признает это разнообразие и предлагает адресные решения.</p><p>Технологическая зрелость инструментов позволяет легко комбинировать разные подходы. Контейнеризация, сервисная сетка и API-гейтвеи упрощают интеграцию разнородных компонентов.</p><h2>Реальные сценарии комбинирования технологий</h2><p>Рассмотрим типичный пример e-commerce платформы. Система состоит из нескольких логических частей, каждая со своими требованиями.</p><p>Микросервисы инвентаризации и платежей общаются через gRPC. Здесь важна низкая задержка и эффективность сети. Бинарный протокол и HTTP/2 идеально подходят для частых внутренних вызовов.</p><p>Публичное API для мобильных приложений и партнеров использует GraphQL. Разные клиенты могут запрашивать только нужные данные без переразработки серверной логики. Это снижает нагрузку на сеть и упрощает поддержку API.</p><p>Админ-панель и внутренние инструменты построены на tRPC. Разработчики работают в единой TypeScript-экосистеме, что ускоряет итерации. Типобезопасность от backend до frontend снижает количество ошибок.</p><h2>Техническая реализация гибридной архитектуры</h2><p>Ключевой элемент гибридной системы — API-шлюз. Он маршрутизирует запросы к соответствующим бэкендам, преобразует форматы данных и обеспечивает единую точку входа.</p><p>Шлюз принимает HTTP-запросы и определяет, куда их направить. GraphQL-запросы идут к GraphQL-серверу, gRPC-вызовы — к микросервисам, а tRPC-запросы — к соответствующим процедурам.</p><p>Преобразование протоколов происходит прозрачно для клиента. Например, мобильное приложение отправляет GraphQL-запрос, который шлюз может преобразовать в gRPC-вызов к внутренним сервисам.</p><p>Сервисная сеть (service mesh) упрощает управление гибридной инфраструктурой. Она обеспечивает обнаружение сервисов, балансировку нагрузки и мониторинг независимо от используемых протоколов.</p><h2>Организационные аспекты смешанного подхода</h2><p>Гибридная архитектура влияет на структуру команд. Вместо единой бэкенд-команды появляются специализированные группы:</p><ul><li>Команда платформы отвечает за базовую инфраструктуру: API-шлюз, сервисную сеть, мониторинг. Они обеспечивают совместимость различных технологий и единые стандарты качества.</li><li>Команды продукта фокусируются на конкретных функциональных областях. Они выбирают оптимальные технологии для своих задач в рамках установленных стандартов.</li></ul><p>Такое разделение требует чётких интерфейсов между командами. Контракты API становятся критически важными — они определяют точки взаимодействия между различными частями системы.</p><h2>Проблемы и решения при внедрении</h2><p>Гибридный подход не лишён сложностей. Основная проблема — высокая операционная нагрузка. Каждая технология требует специфических знаний и инструментов мониторинга.</p><p>Единая система мониторинга обязательна. Нельзя иметь отдельные дашборды для gRPC, GraphQL и tRPC. Нужен агрегированный взгляд на всю систему, который показывает взаимосвязи между компонентами.</p><p>Стандартизация практик разработки становится критически важной. Разные команды должны следовать единым принципам документирования, версионирования и тестирования API.</p><p>Обучение разработчиков — еще один вызов. Программисты должны понимать несколько технологий, а не специализироваться на одной. Это требует инвестиций в обучение и обмен знаниями.</p><h2>Когда гибридный подход оправдан</h2><p>Переход к смешанной архитектуре требует дополнительных ресурсов. Он не всегда целесообразен для небольших проектов или стартапов на ранней стадии.</p><p>Проекты с явно выраженными разнородными требованиями к API получают максимальную выгоду. Если у вас есть и высоконагруженные внутренние сервисы, и публичное API с разнообразными клиентами — гибридный подход может быть оптимальным.</p><p>Системы, которые эволюционируют из монолита в микросервисы, часто естественным образом приходят к гибридной архитектуре. Постепенное внедрение новых технологий менее рискованно, чем полный рефакторинг.</p><p>Команды с сильной DevOps-культурой лучше справляются со сложностью гибридных систем. Автоматизация развёртывания, мониторинга и масштабирования снижает операционную нагрузку.</p><h2>Эволюция вместо революции</h2><p>Гибридный подход — не про выбор одной технологии, а про использование сильных сторон каждой. Это признание того, что современные системы слишком сложны для универсальных решений.</p><p><b>Начинайте с простого.</b> Если ваш проект небольшой, одной технологии API может быть достаточно. По мере роста вы сможете постепенно вводить дополнительные протоколы там, где они дают максимальный эффект.</p><p><b>Измеряйте результаты.</b> Внедрение новой технологии должно решать конкретные проблемы: снижать задержки, ускорять разработку или улучшать пользовательский опыт. Без измеримых целей гибридная архитектура превращается в ненужное усложнение.</p><p>Главное — сохранять архитектурную гибкость. Технологии продолжат меняться, и ваша система должна быть готова адаптироваться к новым вызовам.</p><h2>Итоги: не следуйте трендам, решайте задачи</h2><p>GraphQL не умер — он занял свою нишу в мире API. gRPC и tRPC не заменят его полностью, а дополнят экосистему, предлагая решения для конкретных сценариев.</p><p>Выбирайте технологию исходя из потребностей проекта, а не модных трендов. Иногда простое REST API может оказаться лучшим решением, если ваши требования минимальны.</p><p>Технологии продолжат развиваться. Важно сохранять архитектурную гибкость и не замыкаться на одном стеке. Умение выбрать правильный инструмент для задачи — навык, который останется актуальным независимо от появления новых технологий.</p><p>Главное — решать реальные проблемы, а не создавать себе новые в погоне за модными фреймворками.</p>]]></content:encoded>
    </item>
    <item>
      <title>PostgreSQL 18 вышел: новый асинхронный I/O ускоряет запросы в 3 раза</title>
      <link>https://tproger.ru/news/--postgresql-18-vywel--novyj-asinhronnyj-i-o-uskoryaet-zaprosy-v-3-raza</link>
      <comments>https://tproger.ru/news/--postgresql-18-vywel--novyj-asinhronnyj-i-o-uskoryaet-zaprosy-v-3-raza?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/--postgresql-18-vywel--novyj-asinhronnyj-i-o-uskoryaet-zaprosy-v-3-raza</guid>
      <description><![CDATA[<p>PostgreSQL 18 вышел с асинхронным I/O, ускоряющим запросы в 3 раза, быстрее pg_upgrade, новыми индексами, OAuth 2.0 и улучшенным текстовым поиском</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/--postgresql-18-vywel--novyj-asinhronnyj-i-o-uskoryaet-zaprosy-v-3-raza">PostgreSQL 18 вышел: новый асинхронный I/O ускоряет запросы в 3 раза</a>»</p>]]></description>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 26 Sep 2025 04:43:56 GMT</pubDate>
      <content:encoded><![CDATA[<p>Вышла финальная версия <b>PostgreSQL 18</b> — одного из самых популярных СУБД с открытым исходным кодом.</p><p>Главное нововведение — <b>асинхронный ввод-вывод</b>, который в ряде сценариев ускоряет работу с диском <b>до трех раз</b>.</p><p>Но на этом список улучшений не заканчивается: PostgreSQL 18 ускорил обновления между версиями, добавил удобства разработчикам, улучшил текстовые операции и получил поддержку OAuth 2.0.</p><h2>До трех раз быстрее благодаря новому вводу-выводу</h2><p>До этого момента PostgreSQL полагался на механизм операционной системы под названием readahead, чтобы предсказывать, какие данные будут востребованы.</p><p>В PostgreSQL 18 появилась полноценная <b>поддержка асинхронного I/O</b>, благодаря которой база может отправлять сразу несколько I/O-запросов — и не ждать завершения каждого по отдельности.</p><p>Это позволяет достичь <b>серьезного прироста производительности </b>при последовательном чтении, bitmap heap scan и даже во время VACUUM.</p><p>В зависимости от настроек (io_method) можно выбрать подходящий механизм — от worker до io_uring, или оставить синхронный режим (sync). Подробные параметры конфигурации описаны в официальной документации.</p><h2>Обновления между версиями больше не обнуляют производительность</h2><p>Одной из болезненных сторон мажорных обновлений PostgreSQL всегда было то, что после pg_upgrade приходилось заново собирать статистику — иначе планировщик начинал выбирать неоптимальные запросы.</p><p>В PostgreSQL 18 это <b>исправлено</b>: теперь можно сохранять собранную статистику между версиями, чтобы после обновления система сразу показывала ожидаемую производительность.</p><p>Помимо этого, утилита pg_upgrade теперь работает быстрее на базах с большим количеством таблиц, может выполнять параллельные проверки (через --jobs) и поддерживает флаг --swap — для моментальной замены директорий без копирования файлов.</p><h2>Что еще улучшили</h2><p>В PostgreSQL 18 появилось множество изменений, не связанных напрямую с I/O, но делающих жизнь разработчиков и администраторов проще. Среди них:</p><ul><li><b>Новые методы индексирования</b> (вроде skip scan), которые позволяют задействовать индексы даже без фильтрации по первым столбцам.</li><li>Улучшения в JOIN: быстрее работают hash join, merge join и incremental sort.</li><li>Поддержка <b>виртуальных вычисляемых колонок</b>, которые вычисляются на лету и не хранятся на диске.</li><li>Новый генератор uuidv7() — UUID с временной сортировкой, который лучше индексируется и ускоряет выборки.</li><li>Возможность использовать оба значения (OLD и NEW) в RETURNING при INSERT, UPDATE, DELETE и MERGE.</li><li>Улучшения в полнотекстовом поиске и обработке текста, включая новый casefold() и быструю сортировку PG_UNICODE_FAST.</li></ul><p>Также PostgreSQL теперь проще интегрировать с <b>OAuth 2.0</b>, появилась валидация для FIPS-режима, улучшено логгирование репликации и по умолчанию включены <b>контрольные суммы страниц</b> (page checksums), что может повлиять на стратегию обновления через pg_upgrade.</p><p><b>PostgreSQL 18</b> уже доступен для загрузки. Полный список изменений можно найти в<a href="https://www.postgresql.org/docs/18/release-18.html"> официальных release note</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Redis против Postgres в роли кэша: неожиданные итоги бенчмарка</title>
      <link>https://tproger.ru/news/redis-protiv-postgres-v-roli-kewa--neozhidannye-itogi-benchmarka</link>
      <comments>https://tproger.ru/news/redis-protiv-postgres-v-roli-kewa--neozhidannye-itogi-benchmarka?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/redis-protiv-postgres-v-roli-kewa--neozhidannye-itogi-benchmarka</guid>
      <description><![CDATA[<p>Бенчмарк показал: Redis быстрее в роли кэша, но PostgreSQL с unlogged-таблицами выдаёт до 7400 rps и подходит для многих проектов</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/redis-protiv-postgres-v-roli-kewa--neozhidannye-itogi-benchmarka">Redis против Postgres в роли кэша: неожиданные итоги бенчмарка</a>»</p>]]></description>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 25 Sep 2025 10:00:51 GMT</pubDate>
      <content:encoded><![CDATA[<p>Разработчик <a href="https://dizzy.zone/2025/09/24/Redis-is-fast-Ill-cache-in-Postgres/">провел</a> собственное исследование, сравнив производительность Redis и PostgreSQL в роли кэша.</p><p>Он ожидал увидеть очевидное превосходство Redis, но результаты оказались не такими однозначными — особенно с учетом unlogged-таблиц в Postgres.</p><h2>Как проводили тест</h2><ul><li>Был написан простой HTTP-сервер на Go с двумя эндпоинтами: GET и SET.</li><li>В качестве кэша использовались: Redis (через go-redis) и PostgreSQL с unlogged-таблицей (через pgx).</li><li>Оба сервиса запускались в k8s с лимитами: 2 CPU и 8 ГБ ОЗУ.</li><li>Генерация нагрузки — с помощью k6, с предзаполнением кэша 30 млн записей.</li><li>Тестировались три типа нагрузки: только чтение, только запись, смешанная (80% чтения и 20% записи).</li></ul><h2>Что показали тесты</h2><h3>1. Redis быстрее почти по всем метрикам</h3><ul><li>При чтении Redis обработал более 11 000 запросов в секунду против 7400 у PostgreSQL.</li><li>Задержки в Redis в среднем были на 20–30 мс ниже.</li><li>При записи разрыв еще больше: Redis справлялся с ~10 700. запросов в секунду, а PostgreSQL — с ~6000.</li></ul><h3>2. Unlogged-таблицы действительно ускоряют PostgreSQL</h3><ul><li>При использовании обычных таблиц производительность записи в Postgres падала почти в 3 раза.</li><li>На смешанной нагрузке unlogged-таблицы дали прирост примерно в 25%.</li></ul><h3>3. Redis стабильно использовал меньше ресурсов</h3><ul><li>Redis не превышал 1.3 CPU и держал стабильное потребление памяти (~4–4.5 ГБ).</li><li>PostgreSQL упирался в лимит CPU и требовал до 6 ГБ ОЗУ при нагрузке.</li></ul><h2>Когда стоит выбрать Postgres</h2><p>Автор поста подчеркивает: несмотря на более высокую производительность Redis, он лично предпочитает Postgres в небольших и средних проектах:</p><ul><li>База данных все равно уже используется в проекте.</li><li>Нет нужды в сложных TTL или автоудалении.</li><li>Не хочется тянуть в проект еще одну зависимость.</li><li>От 7000 до 8000 запросов в секунду — более чем достаточно для большинства задач.</li></ul><p>7425 запросов в секунду — это больше полумиллиарда в день. Все на 10-летнем железе и обычном PostgreSQL. Мало кто работает на таких нагрузках.</p>]]></content:encoded>
    </item>
    <item>
      <title>«SQL хорош для данных, но плох для логики» — почему все больше разработчиков выносят бизнес-логику из базы</title>
      <link>https://tproger.ru/news/-sql-horow-dlya-dannyh--no-ploh-dlya-logiki----pochemu-vse-bolwe-razrabotchikov-vynosyat-biznes-logiku-iz-bazy</link>
      <comments>https://tproger.ru/news/-sql-horow-dlya-dannyh--no-ploh-dlya-logiki----pochemu-vse-bolwe-razrabotchikov-vynosyat-biznes-logiku-iz-bazy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/-sql-horow-dlya-dannyh--no-ploh-dlya-logiki----pochemu-vse-bolwe-razrabotchikov-vynosyat-biznes-logiku-iz-bazy</guid>
      <description><![CDATA[<p>SQL отлично справляется с данными, но неудобен для бизнес-логики: разработчики выносят её в код ради гибкости, скорости и независимости</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/-sql-horow-dlya-dannyh--no-ploh-dlya-logiki----pochemu-vse-bolwe-razrabotchikov-vynosyat-biznes-logiku-iz-bazy">«SQL хорош для данных, но плох для логики» — почему все больше разработчиков выносят бизнес-логику из базы</a>»</p>]]></description>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Oracle]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 24 Sep 2025 11:06:25 GMT</pubDate>
      <content:encoded><![CDATA[<p>Современные приложения все чаще используют базы данных исключительно как «хранилище», а не как движок для бизнес-логики. <i>Почему? </i></p><p>Потому что SQL, несмотря на свое превосходство в работе с данными, неудобен, ограничен и рискован в роли полноценного языка программирования.</p><h2>Логика не по адресу</h2><p>Как <a href="https://ewaldbenes.com/en/blog/why-i-keep-business-logic-out-of-sql">отмечает</a> Эвальд Бенс, фуллстек разработчик и авторов популярного блога об IT, он <b>предпочитает держать как можно больше логики в приложении</b>, а не в SQL-хранилищах, представлениях и процедурах:</p><blockquote>Я отношусь к базе как к тупому хранилищу данных. Вся логика — в коде. SQL просто не предназначен для сложных сценариев.</blockquote><p>И дело не в том, что SQL чего-то «не умеет». Умеет — особенно с расширениями вроде PL/pgSQL или Oracle PL/SQL.</p><p><b>Но выразительность этих языков — далека от Python, TypeScript, Rust или C#</b>, особенно когда речь идет о бизнес-логике, объектной модели или сложных расчетах.</p><h2>Зачем выносить логику из базы?</h2><h2>1. SQL невыразителен</h2><p>Для манипуляций с табличками и JOIN — он король. Но как только начинается рекурсия, классы, вложенные состояния или обработка ошибок — SQL превращается в монстра с BEGIN, IF, LOOP, EXCEPTION, RAISE, CURSOR, FETCH, WHILE и т.д...</p><h2>2. Развертывание — боль</h2><p>Обновить приложение можно за минуту, откатить — за две. А вот миграции на проде — это:</p><ul><li>повышенные права доступа;</li><li>согласование с DBA;</li><li>боязнь сломать что-то «наживую»;</li><li>ручной откат схем.</li></ul><h2>3. Лочит на вендора</h2><p>Логика, написанная на PL/SQL — это билет в один конец к Oracle. Переезд на PostgreSQL или SQL Server становится в 5 раз сложнее.</p><h2>4. Меньше инструментов</h2><p>Вокруг SQL есть утилиты, но полноценной среды с юнит-тестами, статическим анализом, форматтерами, профайлерами, линтерами и отладчиками — почти нет.</p><h2>А что с производительностью?</h2><p>Да, есть нюанс: <b>иногда лучше обработать данные прямо в базе</b>, чтобы не гонять десятки тысяч строк по сети. Это особенно актуально, если не хочется получить классическую проблему N+1-запросов.</p><p>Но даже в этом случае большинство специалистов советует <b>сначала делать «просто и понятно», а не «оптимально заранее»</b>. До тех пор, пока не уперлись в реальные метрики, выносить логику в базу — преждевременная оптимизация.</p><h2>Что делать?</h2><p>Подход <i>«база — хранилище, логика — в коде»</i> стал де-факто стандартом во многих командах. Но это не догма:</p><ul><li>Для отчетности или простых ETL сценариев логика в SQL может быть уместной.</li><li>Для монолитных решений без CI/CD и DevOps — процедурный SQL вполне оправдан.</li><li>Но в современной разработке с частыми релизами, микросервисами и отказоустойчивостью <b>бизнес-логика в приложении — просто удобнее и безопаснее</b>.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Как сеньоры документируют проекты: протокол архитектурных решений</title>
      <link>https://tproger.ru/articles/kak-senory-dokumentiruyut-proekty--protokol-arhitekturnyh-rewenij</link>
      <comments>https://tproger.ru/articles/kak-senory-dokumentiruyut-proekty--protokol-arhitekturnyh-rewenij?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Даровская Маша]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-senory-dokumentiruyut-proekty--protokol-arhitekturnyh-rewenij</guid>
      <description><![CDATA[<p>Как сеньоры документируют архитектуру без боли. Обзор подхода ADR: шаблоны, примеры из практики и комментарии экспертов. Ускорьте онбординг и перестаньте объяснять одно и то же.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-senory-dokumentiruyut-proekty--protokol-arhitekturnyh-rewenij">Как сеньоры документируют проекты: протокол архитектурных решений</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Unity]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Scala]]></category>
      <category><![CDATA[Amazon]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Lua]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 09 Sep 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Это перевод <a href="https://dev.to/koladev/how-senior-software-engineers-document-their-project-1nf4">статьи</a> автора <a href="https://dev.to/koladev">Мангабо Колаволе</a> с портала DevTo с комментариями экспертов.</i></p><p>Есть одна задача, которую программисты терпеть не могут — но именно она отличает хорошего инженера от посредственного: как они документируют свой проект? Несколько лет назад я отвечал за запуск финтех-проекта. Мы выбрали стратегию быстрого старта, поэтому масштабируемость не стала для нас приоритетом. Главной целью было проверить гипотезу — и мы двигались вперёд, разрабатывая API, архитектуру и системы —  с упором на простоту, не особенно задумываясь о будущем.</p><p>Но я отвечал за бэкенд и инфраструктуру — и понимал: как бы хороша ни была моя память, через шесть месяцев я не смогу вспомнить все технические детали.</p><p>Во время работы я наткнулся на подход, который мне очень понравился: ADR — Architectural Decision Record, или «протокол архитектурных решений».</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-09-05/7d1206a7-6729-4bcb-ab55-63d59240df12.png" alt="" /></figure><p>По сути, это документ, в котором
фиксируются все изменения, внесённые в архитектуру: само решение, его влияние и
полученные уроки.</p><p>Проще говоря, это как личный дневник —
только для всей команды.</p><h2>Почему это важно?</h2><p><b>Память
— ненадёжна.</b> Мы часто забываем, почему выбрали одну
архитектурную модель, а не другую. Документирование изменений помогает
восстановить ход мыслей и избежать повторения одних и тех же ошибок.</p><p><b>Это
усиливает команду.</b> Представьте, что вы перепробовали
несколько вариантов решения проблемы и зафиксировали как удачные, так и
неудачные попытки. Это не просто ваш личный опыт — это знание, которым могут
воспользоваться все, включая тех, кто придёт после вас.</p><p><b>Будущие
разработчики скажут вам спасибо.</b> Подумайте о человеке,
который через пять лет будет разбираться в вашем коде. Если вы не оставили
объяснений, он, скорее всего, будет мучиться, пытаясь понять, зачем было
сделано то или иное изменение. А теперь представьте другого разработчика в
другой компании, который находит ADR-документ с чётким объяснением принятого
решения. Он, без сомнения, будет вам благодарен.</p><p>Синьор-фронтендер из ВК Маргарита Лукина, автор телеграм-канала <a href="https://t.me/frontend_kitchen">«Фронтенд кухня»</a>:</p><blockquote>Ценность ADR я впервые осознала в 2019 году. В команду, где работала, активно набирали новых ребят, и приблизительно раз в неделю кто-нибудь из новых разработчиков спрашивал "а почему это сделано так, а не иначе?" Приходилось постоянно давать ответы на одни и те же вопросы, и тогда-то я и поняла, насколько будет удобно записывать ответы где-нибудь в документацию в confluence и просто кидать ссылку новичкам. <br /><br />В 2019 году я еще не знала сам термин ADR и говорила "документация". С термином я познакомилась совсем недавно — этим летом, на курсе по архитектуре монолитных приложений. Тогда я поняла, насколько эффективно можно использовать ADR для ускорения разработки и уменьшения TTM. Дело в том, что начиная разрабатывать новый проект, разработчик первое время (от месяца до полугода! всё зависит от размера проекта) погружается в проект — разбирается, как всё устроено, чтобы вносить изменения соответственно архитектуре. В этот период разработчик, по сути, составляет собственные adr —  обычно в виде мыслеобразов в своей голове :) Если записать основные решения, разработчик сможет намного быстрее погрузиться в проект.</blockquote><h2>Как писать ADR?</h2><p>Существует несколько общепринятых правил, но
вы всегда можете адаптировать их под себя.</p><p>Вдохновившее меня соглашение можно найти на <a href="https://adr.github.io/madr/">GitHub</a>
. Вы также можете ознакомиться с процессом <a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/architectural-decision-records/adr-process.html">ADR на Amazon</a>.</p><p>Вот пример шаблона, который вы можете
использовать.</p><p>Такой тип документа может находиться прямо в репозитории проекта, в Confluence или, например, в JIRA.</p><p>В моей последней компании, где я работал фронтенд-разработчиком, не существовало одного централизованного документа, фиксирующего все архитектурные изменения. Вместо этого мы использовали задачи GitLab и привязывали каждое архитектурное изменение к соответствующей ветке. Это позволяло отслеживать причины изменений даже спустя месяцы после их внедрения.</p><p>Практика спасала нас бесчисленное количество раз. Как я всегда говорю: не важно, насколько вы или ваши коллеги умны — будь то технический директор, менеджер или любой другой участник команды — никто не помнит каждое техническое решение, принятое два года назад.</p><p>Синьор-фронтендер из ВК Маргарита Лукина, автор телеграм-канала <a href="https://t.me/frontend_kitchen">«Фронтенд кухня»</a>:</p><blockquote>Многие руководители хотят видеть на своём проекте разработчиков, которые "сразу, без раскачки" начнут перформить. Совсем избежать периода погружения невозможно, но можно ускорить его в десятки раз за счёт ADR</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>Многофакторное сравнение пяти популярных вычислительных движков для больших данных</title>
      <link>https://tproger.ru/articles/mnogofaktornoe-sravnenie-pyati-populyarnyh-vychislitelnyh-dvizhkov-dlya-bolwih-dannyh</link>
      <comments>https://tproger.ru/articles/mnogofaktornoe-sravnenie-pyati-populyarnyh-vychislitelnyh-dvizhkov-dlya-bolwih-dannyh?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[StarRocks]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/mnogofaktornoe-sravnenie-pyati-populyarnyh-vychislitelnyh-dvizhkov-dlya-bolwih-dannyh</guid>
      <description><![CDATA[<p>Эволюция от Hadoop к cloud‑native и ИИ‑архитектурам. Многомерное сравнение Spark, Presto, Trino, ClickHouse и StarRocks по скорости, масштабируемости, кэшам, SQL/Python, HA и др.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/mnogofaktornoe-sravnenie-pyati-populyarnyh-vychislitelnyh-dvizhkov-dlya-bolwih-dannyh">Многофакторное сравнение пяти популярных вычислительных движков для больших данных</a>»</p>]]></description>
      <category><![CDATA[Big Data]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 20 Aug 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Скорость итераций в области Big Data вновь вернулась к стремительному темпу 2015–2016 годов. Область анализа данных — самая близкая к бизнесу, часто используемая и ценная, с жёсткими требованиями к стоимости и эффективности.</p><p>Разработчики на передовой всё реже запускают новые сервисы на «тяжёлой в эксплуатации» связке сервисов Hadoop и предпочитают формат «всё в одном» — унифицированный подход, объединяющий хранение и аналитику. Если раньше архитектуру больших данных приходилось «собирать из кубиков», то теперь она всё чаще становится более монолитной архитектурой (all‑in‑one).</p><p>Кроме того, с быстрым развитием ИИ изменились и объёмы, и типы данных, поэтому на стороне вычислительных движков были проведены соответствующие оптимизации и обновления: например, для OLAP‑аналитики векторизация де‑факто стала стандартной возможностью, а форматы озёр данных эволюционируют к поддержке мультимодальности (о мультимодальном хранении — ниже).</p><p>В этой статье разберём архитектуры популярных сегодня распределённых вычислительных движков и их плюсы/минусы. Проанализировав их, мы лучше поймём, какой движок уместнее использовать в тех или иных бизнес‑сценариях.</p><p>Реализации распределённых вычислительных движков обычно состоят из компонентов «Server» и «Worker». Узлы Worker, как правило, распределяются по множеству хостов и под координацией Server выполняют параллельные вычисления. Хотя логика вычислений и оптимизации у разных движков реализована по‑разному, базовые этапы похожи.</p><figure><img src="https://media.tproger.ru/user-uploads/116700/2025-08-15/587b10ca-1dff-4464-86df-9ee5f0956735.png" alt="" /></figure><h2>Базовые этапы выполнения запроса</h2><ol><li>Parsing — разбор: SQL‑запрос разбирается в синтаксическое дерево для валидации структуры и выявления задействованных таблиц.</li><li>Planning — планирование: формируется логический план, описывающий необходимые операции (например, фильтры, соединения) и их порядок.</li><li>Optimization — оптимизация: логический план преобразуется в эффективный физический план с помощью стоимостной (CBO) или правил‑ориентированной оптимизации.</li><li>Compilation — компиляция: физический план компилируется в низкоуровневые операции, байт‑код или аппаратно‑специфичные инструкции, подготавливаясь к исполнению.</li><li>Execution — исполнение: план распределяется узлам Worker, которые параллельно сканируют данные, применяют преобразования и обмениваются данными; промежуточные данные/метаданные возвращаются в главный процесс.</li><li>Result Serving — формирование и отдача результатов: результаты агрегируются, форматируются и возвращаются пользователю или нижестоящим системам (downstream).</li></ol><h2>Классификация движков по назначению</h2><ul><li>Универсальные вычислительные движки: например, Spark, Flink, MR (MapReduce), поддерживающие пакетные и сложные вычислительные задачи, различные типы данных и множество источников.</li><li>Интерактивные движки запросов: например, Presto, Trino — для ad hoc‑запросов, где важно быстро получать результаты и применять оптимизации, обеспечивая высокую скорость выполнения и интерактивность анализа.</li><li>OLAP‑движки: например, ClickHouse, StarRocks, Doris и др. — для быстрого анализа постоянно меняющихся данных. Поддерживают аналитику в реальном времени, субсекундную латентность запросов и серьёзные оптимизации в оптимизаторе выполнения.</li></ul><h3>Универсальные вычислительные движки</h3><p>Среди универсальных движков наиболее широко используется Apache Spark: он поддерживает офлайн‑вычисления, обработку, близкую к реальному времени (near real time), и интеграцию с фреймворками машинного обучения. Spark изначально создавался для преодоления ограничений Hadoop MapReduce. Spark Driver — центральный координатор Spark‑приложения: он управляет использованием CPU и памяти, широковещательными переменными (broadcast variables, для эффективного совместного использования данных между узлами Worker) и создаёт наборы данных RDD.</p><p>Ниже — схема архитектуры Apache Spark.</p><figure><img src="https://media.tproger.ru/user-uploads/116700/2025-08-15/108c7e1b-ca28-48aa-9eb9-d1c3e0ef8898.png" alt="Схема технической архитектуры Apache Spark" /><figcaption>Техническая архитектура Apache Spark</figcaption></figure><h3>Интерактивные движки запросов</h3><p>PrestoDB был создан в 2012 году в Facebook (Meta)* для предоставления быстрых распределённых возможностей SQL поверх различных источников (включая HDFS, S3, MySQL и Cassandra) без перемещения или преобразования данных. Trino появился в 2019 году как форк Presto, созданный его оригинальными авторами, с фокусом на улучшении производительности и добавлении поддержки облачных и современных Lakehouse‑архитектур. Эти движки остаются очень похожими и после форка различаются лишь в деталях.</p><p>*<i>Компания Meta признана экстремистской на территории РФ и запрещена</i></p><p>На следующей схеме показана архитектура Presto/Trino. В Presto и Trino координатор парсит и планирует запрос, затем создаёт набор задач и сплитов (splits) базовых внешних хранилищ; каждый сплит передаётся рабочим узлам для чтения соответствующих данных.</p><figure><img src="https://media.tproger.ru/user-uploads/116700/2025-08-15/ba93830b-dd17-4aac-a3a4-4675f70f642d.png" alt="Схема архитектуры Presto/Trino" /><figcaption>Архитектура Presto/Trino</figcaption></figure><h3>OLAP‑движки для работы в реальном времени</h3><p>StarRocks — высокопроизводительное аналитическое хранилище данных (DWH), реализующее многомерную аналитику, аналитику в реальном времени и высокую конкурентность за счёт векторизации, MPP‑архитектуры, CBO, умных материализованных представлений и колоночного движка с возможностью оперативных обновлений.</p><p>Архитектура StarRocks поддерживает две модели: Shared‑nothing и Shared‑Data. В Shared‑nothing данные загружаются в формат StarRocks и хранятся непосредственно в локальном хранилище узлов StarRocks Backend. Shared‑Data позволяет напрямую запрашивать внешние источники данных без копирования их в кластер StarRocks — аналогично Presto/Trino/Spark.</p><figure><img src="https://media.tproger.ru/user-uploads/116700/2025-08-15/86fc796c-72c0-4a6d-865c-1dc2bb802738.png" alt="Схема архитектуры StarRocks" /><figcaption>Архитектура StarRocks</figcaption></figure><p>Используются два типа узлов: Frontend (FE) и Backend (BE)/Compute (CN). Узлы FE отвечают за управление метаданными и построение плана выполнения. Узлы BE исполняют план и хранят данные, ускоряя запросы за счёт локального хранения и обеспечивая высокую доступность посредством репликации. В конфигурации с общими данными (Shared‑Data) вместо BE используются вычислительные узлы (CN), которые выполняют те же функции, но не хранят данные.</p><p>ClickHouse был разработан в 2009 году, изначально для сервиса Yandex.Metrica — высоконагруженной веб‑аналитической платформы, обрабатывающей миллиарды событий в день с низкой задержкой. Существующие базы данных не справлялись с таким масштабом для аналитики в реальном времени с высокой конкурентностью, особенно на сложных фильтрах, агрегациях и соединениях. В ответ появился ClickHouse — быстрая OLAP‑СУБД для решения этих задач.</p><figure><img src="https://media.tproger.ru/user-uploads/116700/2025-08-15/983e7058-86cb-4e2a-9eef-713eeed575d1.png" alt="Схема архитектуры ClickHouse" /><figcaption>Архитектура ClickHouse</figcaption></figure><p>Архитектура ClickHouse использует колоночное хранение; операции выполняются над векторами (колоночными блоками), а данные векторов размещаются в реплицируемых шардах ClickHouse, что обеспечивает быстрое выполнение запросов и отказоустойчивость. Кроме того, ClickHouse позволяет запрашивать данные из облачных хранилищ, аналогично внешним таблицам в традиционных DWH.</p><p>Каждый распределённый исполнительный движок имеет свои сильные стороны: хотя почти все исполняют один и тот же SQL, детали реализации заметно различаются — исполнительные подсистемы, подходы к оптимизациям, обработка shuffle, кэширование, уровни векторизации и т. п.</p><p>В сводной таблице ниже (по мотивам сравнения на сайте Onehouse и описанных в тексте критериев) каждому движку присваивается оценка: A = лучший вариант; B = хороший вариант; C = ниже среднего. Каждой оценке соответствует балл: A = 3, B = 2, C = 1. metascore — нормализованная сумма баллов по всем категориям.</p><h2>Сводная таблица сравнения (оценки A/B/C и metascore)</h2><p>Примечания:</p><ul><li>A = 3 балла, B = 2 балла, C = 1 балл.</li><li>metascore рассчитан как сумма баллов по 5 категориям, нормализованная к максимуму 15 (деление на 15 и умножение на 100%).</li><li>Таблица отражает выводы текста: «лучший/худший» в классе по каждой категории и качественные комментарии по архитектуре.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/116700/2025-08-15/9aeaa77a-b35f-4a37-a239-d8bbb7887046.png" alt="Analytics Engines Metascore" /></figure><h3>Рейтинг по metascore</h3><ol><li>StarRocks — 73%</li><li>ClickHouse — 73%</li><li>Presto — 67%</li><li>Apache Spark — 60%</li><li>Trino — 60%</li></ol><h3>Сравнение по ключевым критериям</h3><p><b>Скорость выполнения.</b> Одним из ключевых критериев качества вычислительного движка выступает время ответа на запрос; также важны пропускная способность, отказоустойчивость и ресурсоёмкость.</p><p>Оптимизации на базе SIMD (Single Instruction, Multiple Data), позволяющие одной инструкции CPU обрабатывать сразу несколько элементов данных, дают заметное преимущество над поэлементной обработкой.</p><p>— 🏆 Лучший в классе: StarRocks, ClickHouse</p><p>— ❌ Худший в классе: Spark</p><p><b>Масштабируемость.</b> Способность масштабировать кластер вверх/вниз на старте и по завершении запроса — важная составляющая отличной производительности и оптимизации затрат. Архитектуры с разделением хранения и вычислений упрощают масштабирование. Presto обеспечивает наиболее простую операционную модель на больших масштабах. Локальное хранение у StarRocks/ClickHouse усложняет масштабирование. Spark чаще используется для крупномасштабных ETL‑заданий и менее удобен для эластики интерактивных нагрузок.</p><p>— 🏆 Лучший в классе: Presto</p><p>— ❌ Худший в классе: Apache Spark</p><p><b>Конкурентное чтение/запись. </b>Нужна эффективная обработка больших объёмов одновременных запросов с приоритизацией, чтобы важные запросы не блокировались. ClickHouse предоставляет самый тонкий и гибкий контроль над исполнением запросов. В отношении транзакций большинство движков ориентированы на OLAP и уступают типичным OLTP/онлайн‑БД.</p><p>— 🏆 Лучший в классе: ClickHouse</p><p>— ❌ Худший в классе: Apache Spark</p><p><b>Поддержка хранения</b>. В эпоху открытых табличных форматов (Data Lake) по стратегии Lakehouse важно уметь читать/писать множество форматов. Spark поддерживает самый широкий спектр: через источники данных — Parquet, JSON, ORC, Avro, CSV и др.</p><p>— 🏆 Лучший в классе: Apache Spark</p><p>— ❌ Худший в классе: ClickHouse</p><p><b>Поддержка языков запросов.</b> В эпоху ИИ и аналитики главные способы работы — SQL и Python. Apache Spark с PySpark обеспечивает лучший опыт работы с Python и позволяет выражать бизнес‑логику в Python‑функциях; другие движки обычно требуют определять логику на SQL через клиентские обёртки. Spark можно бесшовно использовать как Python‑библиотеку и как распределённый SQL‑движок.</p><p>— 🏆 Лучший в классе: Apache Spark</p><p>— ❌ Худший в классе: Trino, Presto</p><h2>Выводы</h2><p>Выбор оптимального движка для решения бизнес‑задач не ограничивается желаемыми техническими целями — он должен учитывать будущие потребности бизнеса и направление эволюции архитектуры.</p><p>Каждый движок имеет свои сильные стороны:</p><ol><li>Apache Spark обладает самой широкой поддержкой хранилищ и языков; он может подключаться к практически любым типам данных и работать с ними.</li><li>Trino — отличный интерактивный SQL‑движок для ad hoc‑аналитики.</li><li>Presto имеет общую историю с Trino, предоставляет превосходный интерактивный SQL и эффективно масштабируется.</li><li>StarRocks предлагает сверхбыстрый векторизованный движок, но поддержка форматов файлов у него не так широка.</li><li>ClickHouse также даёт сверхбыстрый векторизованный движок для ускорения OLAP, но ему не хватает эластичности масштабирования.</li></ol><p>Независимо от выбора движка, настоящая сила — в умении комбинировать движки, масштабировать их и интегрировать с другими компонентами экосистемы под задачи бизнеса, не заковываясь в единственную архитектурную парадигму.</p>]]></content:encoded>
    </item>
    <item>
      <title>Куда двигаться после изучения Django: советы для Python-разработчиков</title>
      <link>https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299</link>
      <comments>https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгения Епихина]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299</guid>
      <description><![CDATA[<p>В статье разбираемся, почему Django — далеко не финиш в карьере, и в каких направлениях можно двигаться Python-разработчику.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kuda-dvigatsya-posle-izucheniya-django--sovety-dlya-python-razrabotchikov-257299">Куда двигаться после изучения Django: советы для Python-разработчиков</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Raspberry Pi]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Асинхронное программирование]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[NoSQL]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Neo4j]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 12 Aug 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Django — это веб-фреймворк на языке Python, который позволяет быстро создавать сложные веб-приложения. Он включает в себя готовые компоненты для работы с базами данных, маршрутизацией URL, обработкой форм, аутентификацией пользователей и админ-панелями, что значительно ускоряет разработку и упрощает поддержку проектов.</p><p>Владение Django — это старт, а не финиш. Чтобы оставаться востребованным, нужно постоянно расширять знания и навыки. В этой статье разберем пути и направления для улучшения своих компетенций.</p><h2>Почему владение Django — не предел для разработчика</h2><h2>Особенности Django</h2><p>Django используют для разработки веб-приложений разной сложности: при работе с большими базами данных, для создания сервисов, способных обслуживать большое количество пользователей. На нём создают соцсети, новостные сайты, веб-версии приложений, онлайн-магазины.</p><p>Основные плюсы:</p><ul><li><b>Полноценный стек</b>: ORM для работы с базой, мощная система маршрутизации URL, шаблоны для рендеринга, встроенная админка, формы, система аутентификации и авторизации.</li><li><b>Архитектура MTV (Model-Template-View)</b>: похожа на классический MVC, но с особенностями, которые упрощают разделение логики, представления и данных.</li><li><b>Безопасность</b>: Django автоматически защищает от CSRF, XSS, SQL-инъекций и других распространенных атак. Не нужно писать много дополнительного кода.</li><li><b>Активное сообщество и экосистема</b>: тысячи сторонних пакетов, расширений и готовых решений.</li><li><b>Поддержка нескольких баз данны</b>х: PostgreSQL, MySQL, SQLite, Oracle и др.</li></ul><p>Ограничения:</p><ul><li><b>Синхронная природа Django</b>.</li><li><b>Монолитность</b>: архитектура фреймворка ориентирована на создание крупных приложений, но в микросервисах может быть избыточна.</li><li><b>Ограниченная гибкость ORM</b>: нестандартные SQL-запросы иногда сложно выразить средствами ORM, приходится использовать raw SQL или сторонние библиотеки для запросов.</li><li><b>Строгие правила организации кода</b>: требуют дисциплины и могут ограничивать свободу в архитектурных решениях.</li><li><b>Недостаточная производительность</b>: уступает лёгким асинхронным фреймворкам (например, FastAPI), особенно под высокими нагрузками. Но для большинства проектов пока это не критично.</li></ul><h2>В каком направлении двигаться после изучения Django</h2><blockquote>Задача — создавать продукт, который будет нужен конечному потребителю.</blockquote><h3>Первое направление для развития — расширить инструментарий для решения разных задач в веб-разработке</h3><p>Возможные пути:</p><ul><li>Изучить другие веб-фреймворки (Flask, FastAPI)</li><li>Углубиться в асинхронное программирование (asyncio, aiohttp)</li><li>Работать с API и микросервисами</li></ul><h4>Flask и FastAPI</h4><p>Flask — минималистичный микрофреймворк, даёт полную свободу в выборе компонентов. Используют для небольших приложений и микросервисов.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-12/bbe7c040-14de-426d-9a10-c556f7319bee.png" alt="" /><figcaption>Пример простой команды на Flask</figcaption></figure><p>FastAPI — современный асинхронный фреймворк, ориентирован на создание высокопроизводительных API. Поддерживает стандарт OpenAPI и автоматическую генерацию документации. Он быстрее Flask и Django благодаря asyncio и Pydantic.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-12/33a27277-5136-4a03-8af2-f436db42fa99.png" alt="" /><figcaption>Пример простого API на FastAPI</figcaption></figure><h4>Асинхронное программирование</h4><p>Веб-разработка всё активнее использует асинхронные технологии. Django не всегда справляется с задачами высокой конкурентной нагрузки.</p><p>Поэтому изучение asyncio — стандартной библиотеки Python для асинхронного программирования — откроет перед вами новые возможности. Вместе с aiohttp или тем же FastAPI вы сможете создавать приложения, которые обрабатывают тысячи одновременных соединений. Это особенно важно для real-time сервисов, чат-приложений и систем с интенсивным обменом данными.</p><h3>Второе направление — расширить навыки в смежных областях</h3><p>Можно пойти по пути расширения компетенций за пределы основной специализации. Важно не только уметь писать код, но и понимать, как приложения разворачиваются и работают в продакшене. Знание DevOps-практик помогает наладить эффективное взаимодействие между разработкой и эксплуатацией.</p><h4>Изучение DevOps и контейнеризации</h4><p>Контейнеры позволяют запускать приложения в изолированной среде, это упрощает настройку и развертывание. Например, Docker помогает упаковать приложение с зависимостями в один контейнер, а Kubernetes — управлять такими контейнерами в продакшене. Знание этих технологий улучшит взаимодействие с операционной командой и ускорит выпуск новых версий приложений.</p><h4>CI/CD и автоматизация процессов</h4><p>Непрерывная интеграция (Continuous Integration) и непрерывное развертывание (Continuous Deployment) — ключевые практики современной разработки ПО. Они позволяют автоматизировать сборку, тестирование и доставку приложений, масштабировать процессы.</p><p>Инструменты CI/CD (например, Jenkins, GitLab CI/CD, GitHub Actions) помогают настроить автоматические пайплайны, которые обеспечивают быструю обратную связь и минимизируют человеческий фактор в релизах. Автоматизация процессов снижает количество ошибок и позволяет сосредоточиться на разработке новых функций.</p><p>Настройка непрерывной интеграции и доставки (Continuous Integration / Continuous Delivery) снижает поток ошибок при релизах и экономит время. Пример: GitHub Actions для автоматического запуска тестов и сборки проекта при каждом коммите.</p><h4>Больше знаний в области баз данных</h4><p>Помимо классических реляционных баз данных (PostgreSQL, MySQL), современные приложения часто используют NoSQL для специфичных задач. MongoDB, Redis, Cassandra обеспечивают гибкость в хранении данных, горизонтальное масштабирование и высокую производительность при работе с большими объемами информации.</p><p>Графовые базы данных (Neo4j, ArangoDB) предназначены для эффективного хранения и анализа связей между объектами, что важно для социальных сетей, рекомендательных систем и других приложений с богатой структурой.</p><p>Так, Redis хорошо подходит для кэширования данных, а Neo4j — для сложных связей между объектами.</p><h3>Третье направление — переход к другим аспектам Python-разработки</h3><p>Рассмотрим четыре варианта карьерного развития для Python-программиста: Data Science и машинное обучение, автоматизация бизнес-процессов, разработка десктопных приложений и встраиваемые системы (IoT).</p><p>Почему стоит попробовать?</p><ul><li>Высокий спрос на специалистов. Они востребованы в банках и инвестиционных компаниях, в сфере медицины и биотехнологии, в консалтинге,  автомобильной промышленности и т.д..</li><li>Широкий набор библиотек: pandas, NumPy, scikit-learn, TensorFlow, PyTorch.</li><li>Возможность работать с реальными задачами: от бизнеса до науки.</li></ul><h4>Автоматизация и скрипты для бизнеса</h4><p>Python часто используется для автоматизации рутинных задач: парсинга данных, обработки файлов, интеграции систем, генерации отчетов. Создание скриптов для автоматизации бизнес-процессов помогает повысить эффективность работы и снизить количество ошибок.</p><p>Знание таких библиотек, как openpyxl (работа с Excel), requests (HTTP-запросы), BeautifulSoup и Scrapy (парсинг веб-страниц), а также умение писать скрипты под конкретные задачи, делают разработчика ценным специалистом в корпоративной среде.</p><p>Примеры задач:</p><ul><li>Автоматическая загрузка данных из Excel и их преобразование</li><li>Скрипты для отправки email-рассылок</li><li>Интеграция с CRM и другими сервисами через API</li></ul><h4>Разработка десктопных приложений (PyQt, Kivy)</h4><p>Хотя сейчас популярность уходит к вебу и мобильным платформам, десктопные приложения на Python востребованы в таких сферах: инструменты для анализа, редакторы, утилиты.</p><p>Инструменты для создания:</p><ul><li>PyQt — мощный фреймворк для создания кроссплатформенных GUI.</li><li>Kivy — библиотека для разработки приложений с поддержкой сенсорных экранов.</li></ul><p>Этот путь подходит тем, кто хочет создавать удобные инструменты с графическим интерфейсом для пользователей на Windows, macOS или Linux.</p><h4>Встраиваемые системы и IoT</h4><p>В области IoT и встроенных систем Python набирает популярность благодаря легкости освоения и поддержке на маломощных устройствах. Помогают в этом  платформы по типу Raspberry Pi и MicroPython.</p><p>Изучение этого направления открывает возможности работы с аппаратным обеспечением, созданием прототипов и внедрением инновационных решений в промышленности и бытовой технике.</p><p>Например, с помощью Python на Raspberry Pi можно  разрабатывать датчики для мониторинга состояния оборудования на производстве и разрабатывать прототипы носимых устройств для сбора данных о здоровье.</p><blockquote>Если рассматривать профессию “Python-разработчик на Django”, то сразу получится сужение до конкретной библиотеки на конкретном языке. Если же в резюме у специалиста стоит, что он “разработчик Python”, возможностей сильно больше. Если написать про себя “разработчик”, будет не понятно, разработчик чего. Но изменив резюме на “DevOps инженера”, становится понятен карьерный трек.</blockquote>]]></content:encoded>
    </item>
    <item>
      <title>Вредные советы по работе с базами данных, или как расстроить DBA</title>
      <link>https://tproger.ru/articles/vrednye-sovety-po-rabote-s-bazami-dannyh--ili-kak-rasstroit-dba</link>
      <comments>https://tproger.ru/articles/vrednye-sovety-po-rabote-s-bazami-dannyh--ili-kak-rasstroit-dba?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/vrednye-sovety-po-rabote-s-bazami-dannyh--ili-kak-rasstroit-dba</guid>
      <description><![CDATA[<p>Сборник самых раздражающих ошибок в работе с базами данных — с примерами и советами, как делать правильно. По выпуску подкаста «Техно.Логично».</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/vrednye-sovety-po-rabote-s-bazami-dannyh--ili-kak-rasstroit-dba">Вредные советы по работе с базами данных, или как расстроить DBA</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Oracle]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Инновации]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 08 Aug 2025 08:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Когда разработчик говорит «база упала», администратор баз данных вздыхает и открывает логи. Снова кто-то решил, что временные файлы бесконечны. Или создал 47 индексов на одной таблице. Или оставил транзакцию висеть на выходные.</p><p>Классические ошибки повторяются с завидным постоянством. В недавнем выпуске подкаста «Техно.Логично» наши коллеги Владимир Герциков и Николай Волынкин как раз обсуждали типичные проблемы с базами данных — от выбора инструментов до падений в продакшне. Послушав коллег, мы решили не пересказывать их беседу целиком, а на основе их беседы сделать практический список вредных советов.</p><p>Получился антигайд: как гарантированно завалить базу данных — и что делать правильно. Если узнаете себя в этих советах, не расстраивайтесь. Через подобное проходят все. А если хотите услышать полную дискуссию о современных СУБД, инструментах и миграции на open source — послушайте <a href="https://vk.com/video-145457488_456239847?access_key=b17a8de1d4db2dde5d">оригинальный выпуск</a>.</p><h2>1. Временные файлы бесконечны — лейте терабайты джойнов</h2><p>Берите две таблицы по миллиону записей каждая, смело делайте JOIN без WHERE, сортируйте результат — и удивляйтесь, почему закончилось место под временные данные.</p><p><b>Что происходит</b>: PostgreSQL создает временные файлы в pg_tmp для обработки больших запросов. Когда места не хватает, падают конкретные запросы с ошибкой <i>No space left on device</i>, а не весь сервер. Особенно болезненно там, где несколько таких запросов запускаются параллельно — временное пространство переполняется быстрее, чем успевает сработать мониторинг.</p><p><b>Как делать правильно</b>: Планируйте размер временных данных заранее. Добавляйте фильтры перед джойнами, разбивайте сложные запросы на этапы. Настройте temp_file_limit для ограничения временных файлов на запрос и мониторинг заполнения. Если ваш запрос генерирует терабайты промежуточных результатов, скорее всего, есть способ сделать это эффективнее.</p><h2>2. Суперпользователь для всех задач — что может пойти не так</h2><p>Создайте пользователя с правами суперадминистратора, используйте его для всех подключений и смело устанавливайте любые расширения, найденные в интернете.</p><p><b>Реальная история:</b> Разработчик развернул постгрес на виртуалке с дефолтными настройками — порт 5432 открыт, пользователь <i>postgres/postgres</i> с правами суперпользователя. Через семь (!) секунд в базу начали ломиться боты. Боты сканируют интернет на стандартные порты СУБД постоянно и превращают сервер в майнинг-ферму быстрее, чем вы успеете допить кофе. Диск переполнился от созданных таблиц, установились неизвестные расширения, начались HTTP-вызовы из базы наружу. Сервер превратился в часть ботнета.</p><p><b>И так все понятно, но еще раз напомним</b>: Суперпользователь может подключить postgres_fdw, dblink и читать/писать любые базы кластера, создавая запросы, которые переполнят временное пространство за минуты. Неподписанные расширения могут содержать что угодно — от бэкдоров до майнеров. А если расширение вызовет <i>segmentation fault</i>, упадет вообще все.</p><p><b>Принцип минимальных прав:</b> Создавайте отдельных пользователей с минимально необходимыми правами. Устанавливайте только официально поддерживаемые расширения. Закрывайте базу от внешнего доступа файрволом, настройте TLS для шифрования трафика, используйте fail2ban против брутфорса и уникальные пароли. Это кажется очевидным, но количество баз с дефолтными паролями в интернете говорит об обратном.</p><h2>3. Держите транзакции открытыми — счетчик XID все стерпит</h2><p>Открывайте длинные транзакции и держите их днями. Постгерс умный, сам разберется.</p><p><b>Что сломается:</b> У PostgreSQL есть счетчик транзакций (XID), который может переполниться. Когда возраст транзакций становится критическим, сервер блокирует обычные подключения и пускает только суперпользователя для выполнения <i>VACUUM FULL</i>. Все приложения встают, начинается паника.</p><p><b>Как избежать:</b> Настройте timeout для idle in transaction состояний. Разбивайте большие батчи на маленькие операции. Мониторьте возраст самых старых транзакций. И запомните: транзакция, которая висит неделю, — это не фича, это бомба замедленного действия.</p><h2>4. На каждый SELECT — свой индекс</h2><p>Создавайте индекс под каждый запрос. Чем больше индексов, тем быстрее будет работать.</p><p><b>Почему это убивает PostgreSQL: </b>В отличие от других СУБД, PostgreSQL при UPDATE создает новую версию записи, а старую помечает как мертвую. Если у таблицы 30 индексов, каждый UPDATE генерирует 30 мертвых ссылок в индексах. VACUUM начинает работать постоянно, производительность рушится.</p><p><b>Правило 20/80: </b>Покройте индексами 20% самых частых запросов, которые дают 80% нагрузки. Остальную аналитику выносите на реплику для чтения. Регулярно анализируйте статистику использования индексов — неиспользуемые безжалостно удаляйте .</p><h2>5. Сайзинг не нужен</h2><p>Ресурсы бесконечны. А DBA разберутся, как бэкапить ваши 100 терабайт.</p><p><b>Физические ограничения:</b> Таблица в PostgreSQL не может быть больше 32 терабайт при дефолтном размере блока. Ограничение можно обойти партиционированием или пересборкой с увеличенным размером блока, но лучше планировать заранее.</p><p><b>Экономика:</b> «Эта функция будет стоить как два сервера, потому что нам нужно оборудование для бэкапа 50-терабайтной базы». В этот момент «бизнес» делает большие глаза и внезапно появляется мотивация оптимизировать архитектуру.</p><p><b>Планирование:</b> Считайте размер данных на год-два вперед. Внедряйте партиционирование с первого дня, если ожидаете рост. Архивируйте старые данные. Удалить лишнее проще, чем добыть дополнительные терабайты дискового пространства в пятницу вечером.</p><h2>6. Пихайте СУБД в контейнеры</h2><p>Kubernetes решает все проблемы! Поэтому переносим в контейнеры все, базы данных тоже. Если что-то работает на виртуалках, то в контейнерах точно будет работать лучше.</p><p><b>Проблемы слоеного пирога:</b> Мы слышали, тебе нравится виртуализация, поэтому мы добавили виртуализацию в твою виртуализацию. В результате кратное усложнение отладки. Где тормозит база: железо, гипервизор, менеджер контейнеров?</p><p><b>Где контейнер оправдан?</b>  В CI/CD, локальной разработке, тестовых средах. В продакшне контейнеры тоже работают, если использовать Kubernetes-операторы (Patroni, CloudNativePG), правильно настроить Persistent Volumes и протестировать поведение при рестартах. База должна жить в памяти, прогревать кэши, работать стабильно. Но это требует серьезной экспертизы в Kubernetes и готовности разбираться с проблемами на стыке технологий. Если команда не готова изучать все тонкости — лучше не начинать.</p><p><b>Компромисс:</b> Если выбираете контейнеры для продакшна, используйте StatefulSet, настройте правильные storage-классы и OOM-политики. Для stateless-сервисов контейнеры — отличный выбор.</p><h2>7. Всю бизнес-логику держим в хранимках — так быстрее</h2><p>Переносите всю логику в базу. Зачем нужны сервисы приложений?</p><p><b>Пример из практики:</b> Система с хранимыми процедурами Oracle обыграла Java-реализацию в тестах производительности. Логика выполнялась рядом с данными, без сетевых задержек. Но когда нагрузка выросла в разы, уперлись в лимит CPU на сервере баз данных. Добавить ресурсы оказалось сложнее, чем масштабировать stateless-сервисы.</p><p><b>Компромисс:</b> Тяжелые агрегации и отчеты делайте в функциях базы. CRUD-операции выносите в сервисы приложений. Следите за загрузкой CPU на сервере БД — когда она приближается к пределу, начинайте выносить логику наружу.</p><h2>8. Коммерческая СУБД — единственный путь</h2><p>Только коммерческие решения подходят для серьезных задач. Oracle и SQL Server проверены временем, а всякие open source базы — это для студентов и стартапов.</p><p><b>Что изменилось:</b> События последних лет заставили многие компании пересмотреть подход к выбору СУБД. Компании массово переходят на PostgreSQL Pro и другие open source решения. Тренд только усиливается — игнорировать open source значит отстать от рынка и пропустить инновации, которые часто появляются именно в открытых проектах.</p><p><b>НО:</b> Vanilla PostgreSQL без поддержки — это действительно риск. Когда расширение Oracle FDW падает с разными структурами таблиц, а автор из коммьюнити отвечает «мне в голову не приходило, что кто-то будет так делать», понимаешь ценность платной поддержки. Поэтому open source, но с поддержкой от надежных вендоров.</p><h2>Заключение</h2><p>Продовые пожары в базах данных всегда случаются в самый неподходящий момент. Но большинство из них можно предотвратить, следуя простым правилам: планировать ресурсы, ограничивать права, мониторить метрики.</p><p>Выберите один совет из этой статьи и примените его сегодня. Возможно, это сэкономит вам несколько часов сна в будущем. А коллеги-DBA скажут спасибо.</p>]]></content:encoded>
    </item>
    <item>
      <title>5 VPS-хостингов в 2025, которые держат нагрузку: кейсы, стоимость, метрики</title>
      <link>https://tproger.ru/articles/5-vps-hostingov-v-2025--kotorye-derzhat-nagruzku--kejsy--stoimost--metriki</link>
      <comments>https://tproger.ru/articles/5-vps-hostingov-v-2025--kotorye-derzhat-nagruzku--kejsy--stoimost--metriki?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Валерия Турчак]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/5-vps-hostingov-v-2025--kotorye-derzhat-nagruzku--kejsy--stoimost--metriki</guid>
      <description><![CDATA[<p>Сравниваем 5 VPS-провайдеров, которые стабильно работают под нагрузкой в 2025 году. Разбираем стоимость, примеры использования, производительность и uptime. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/5-vps-hostingov-v-2025--kotorye-derzhat-nagruzku--kejsy--stoimost--metriki">5 VPS-хостингов в 2025, которые держат нагрузку: кейсы, стоимость, метрики</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Быстрый старт]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[ВКонтакте]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[VPN]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[Windows Server]]></category>
      <category><![CDATA[Образование]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Техподдержка]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[AMD]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 05 Aug 2025 06:10:17 GMT</pubDate>
      <content:encoded><![CDATA[<p>В 2025 году выбирать VPS по принципу дешево и сердито уже не работает. Любой рабочий или MVP-проект — от API для мобильного приложения до интернет-магазина  сталкивается с пиками нагрузки, которые нужно выдержать. Ошибки на старте обходятся дороже простоя в продакшне.</p><p>Собрали пять VPS-хостингов, которые показывают, как должны выглядеть выжившие серверы под нагрузкой: современное железо, каналы без счётчиков трафика, живая поддержка инженеров и опыт клиентов. Ниже — конфигурации, цены и метрики, чтобы вы подобрали сервер под свой сценарий.</p><h2>1. ИХЦ (Интернет ХостингЦентр): конфигурации под нагрузку с NVMe, CPU до 5 ГГц и трафиком без ограничений</h2><p>Один из самых гибких по конфигурациям хостеров в обзоре. Работает с 2009 года. Поддерживает разные типы виртуализации (KVM и Virtuozzo), предлагает линейки с SSD и NVMe, российские и европейские площадки, разные уровни мощности — от базовых до высоконагруженных.</p><h3>Линейки VPS и конфигурации</h3><ol><li>ssdVPS — базовая линейка для России. Позволяет собирать конфигурации от 1 до 32 ГБ оперативной памяти, от 1 до 10 виртуальных CPU и от 20 до 300 ГБ SSD-диска.</li><li>NVMe/ — линейка на базе KVM с более высокой производительностью ввода-вывода. Доступны конфигурации от 1 до 24 ГБ RAM, от 1 до 12 vCPU, SSD от 15 до 300 ГБ.</li><li>EU-NVMe/ — аналог NVMe-линейки, но размещённый в Амстердаме. Конфигурации расширены: от 1 до 64 ГБ оперативной памяти, от 1 до 18 CPU, от 15 до 1000 ГБ SSD, скорость порта — от 200 до 500 Мбит/с.</li><li>VPS 5 ГГц — отдельная линейка на KVM, ориентированная на проекты с высокой частотной нагрузкой, до 5 ГГц на ядро, порт до 1000 Мбит/с.</li></ol><p>VPS Windows — выделенная категория для задач на Windows.</p><h3>Особенности и инфраструктура</h3><p>В <a href="https://www.ihc.ru/vps.html">ИХЦ</a> можно выбрать между двумя видами виртуализации: <b>KVM</b> и <b>Virtuozzo</b>. Виртуализация KVM подходит для задач, где нужна изоляция ресурсов, стабильность под нагрузкой и совместимость с Linux и Windows. Virtuozzo — более экономный вариант с быстрой настройкой, но с возможной перераспределённой нагрузкой между соседними VPS.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/d8f9548f-7bd8-4eef-a4aa-6d50b0e424a2.png" alt="" /><figcaption>Дата-центры провайдера есть в Москве и Амстердаме.</figcaption></figure><p>Связь с поддержкой доступна через тикеты, онлайн-чат на сайте, телеграм-бота, телефон и сообщения ВКонтакте. Поддержка работает 24/7. На всех тарифах включена базовая <b>DDoS-защита</b>.</p><h3>Примеры использования VPS от IHC</h3><p>Компания предоставляет конкретные кейсы. Примеры:</p><ul><li>Проект 1: VPS NVMe/24 (24 ГБ RAM, ~200 ГБ SSD) используется под бэкенд iOS-приложения. Стек: nginx, PHP, MySQL. Нагрузка: 12 000 уникальных пользователей в сутки. Утилизация CPU — 25%.</li><li>Проект 2: VPS NVMe/12 (12 ГБ RAM, ~120 ГБ SSD) для развлекательного сайта. Стек: nginx, Docker, Node.js. Нагрузка: 7 000 уникальных пользователей в сутки, загрузка CPU — около 20%.</li></ul><p>Серверы стабильно держат среднюю и высокую нагрузку — даже с трафиком в 10–12 тысяч пользователей в сутки остаётся запас по ресурсам.</p><h3>Дополнительные опции</h3><p>ИХЦ предлагает <b>тестовый период в 3 дня</b>, <b>безлимитный трафик</b>, <b>бесплатный первый месяц ispmanager 6</b> в подарок, а также предустановку панелей управления (ispmanager, FastPanel) или VPN-шаблонов по выбору при заказе. Также доступны бэкапы, SLA и автоснапшоты.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/e5730a1c-375b-4b91-a238-6a52a51df67a.png" alt="" /></figure><h3>Цены</h3><p>Что касается ценовой политики, стоимость VPS в России (линейка «ssdVPS») начинается <b>от 380 руб/мес</b> или 3800 руб/год (12 месяцев по цене 10). Европейские VPS («EU-NVMe/») и VPS на KVM («NVMe/») стартуют <b>от 440 руб/мес</b> или 4400 руб/год, а каждый дополнительный гигабайт памяти стоит 6 рублей.</p><h2>2. FirstVDS: мощные VDS на AMD EPYC и Ryzen</h2><p><a href="https://firstvds.ru/">FirstVDS</a> — хостинг-провайдер с опытом на рынке более 20 лет. Предлагают VPS и VDS с виртуализацией KVM для проектов любого размера. Все серверы работают на современном оборудовании. Трижды победитель в номинации «Хостер года» Национальной премии «ЦОДы.РФ».</p><p>Есть VPS для разных сценариев нагрузки — от стандартных сайтов до тяжёлых веб-приложений и проектов с высокими требованиями к CPU и отказоустойчивости. Отдельные решения для Битрикс, установка ОС семейства Linux, FreeBSD и Windows Server.</p><h3>Линейки VPS: от базовой мощности до кластера Ceph</h3><p>FirstVDS предлагает три основные линейки, которые отличаются архитектурой и назначением:</p><ol><li>VDS Форсаж — гибкая конфигурация сервера на базе AMD EPYC, до 128 ядер (до 3,7 ГГц), до 512 Гб оперативной памяти и до 4 000 Гб быстрого NVMe-накопителя. Локации Москва и Амстердам. Стартовая стоимость такой конфигурации составляет от 749 руб/мес.</li><li>Для нагруженных проектов — CPU.Турбо — гибкая конфигурация сервера на базе AMD Ryzen с частотой до 5,7 ГГц, DDR5 и с быстрыми NVMe-накопителями. Идеально для Битрикс. Локация Москва. Начальная цена CPU.Турбо — от 624 руб/мес. При покупке лицензии Битрикс (1С-Битрикс: Управление сайтом или Битрикс24) есть дополнительная скидка 30% на 3 месяца аренды этого тарифа.</li><li>Отказоустойчивый VDS Атлант — гибкая конфигурация сервера на базе AMD EPYC — до 192 ядер (до 3,5 ГГц), до 768 Гб оперативной памяти и до 8 Тб быстрого NVMe-накопителя. Репликация данных между узлами кластера Ceph и дублирование сетевого оборудования. Локация Москва. Его стартовая стоимость от 1619 руб/мес, при этом бесплатные автобэкапы уже включены.</li></ol><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/3490237d-3e99-49c5-9d90-10e3849765ed.png" alt="" /></figure><p>Компания использует два центра обработки данных в <b>Москве</b>: <b>IXcellerate (уровень Tier III)</b> и Web DC. Для тарифа Форсаж и готовых тарифов также доступен ЦОД <b>euNetworks (уровень Tier III) в Амстердаме</b>.</p><h3>Сетевые возможности, трафик и безопасность</h3><p>В стоимость каждого сервера входит бесплатный выделенный IP-адрес. Клиенты могут выбрать между 100 Мбит/с с безлимитным трафиком или портом 1 Гбит/с с включёнными 32 Тб трафика.</p><p>Защита от DDoS-атак и система безопасности BitNinja для сервера и сайта доступны как подключаемые опции. Также предоставляются объектное хранилище S3, автобэкапы и Кибер-бэкап. Для безопасности коммуникаций используются SSL-сертификаты GlobalSign.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/7d36ac0d-4832-402b-b0b0-9d7955963916.png" alt="" /></figure><h3>Управление, ПО и поддержка</h3><p>При заказе сервера клиент получает лицензию ispmanager 6  lite: первый месяц панель предоставляется бесплатно, дальше оплачивается по тарифу самой панели. Предлагается гибкий выбор операционных систем, включая Linux, FreeBSD и Windows Server. Под разовые задачи доступны готовые рецепты установки — от Битрикс и GitLab до TeamSpeak, LAMP‑стека и других популярных наборов ПО.</p><p>Для установки и решения любых вопросов — доступна живая круглосуточная техническая поддержка 24/7 через чат на сайте, в личном кабинете и по телефону, без использования чат-ботов. Для самостоятельного решения вопросов предусмотрена обширная база знаний.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/7fc897fc-5d2d-4f28-9047-834a8b0202b1.png" alt="" /></figure><h3>Клиентские бонусы и программы</h3><p>Есть тестовый период до 3 дней. Регулярно проводятся акции и предоставляются скидки, в том числе на тарифы для нагруженных проектов.</p><p>1) При переходе от другого хостера FirstVDS бесплатно переносит до 10 сайтов. Дополнительно предоставляется скидка 40% на первый месяц аренды VPS при оплате сервера на 1, 3 или 6 месяцев, либо 3 месяца бесплатной аренды VPS при оплате на год.</p><p>2) Клиенты с возрастом аккаунта от 5 лет получают постоянную скидку на аренду VPS, начиная от 5% и увеличиваясь ежегодно до 20%.</p><p>3) Действует реферальная программа, по которой партнёр получает 10% от расходов привлечённых клиентов, а привлечённый пользователь — скидку 25% на первый месяц аренды VPS.</p><p>4) Стоимость продления домена у FirstVDS равна актуальной стоимости его регистрации.</p><h2>3. InCloud: VPS‑площадки для бизнеса, где важен SLA</h2><p><a href="https://incloud.ru/">InCloud</a> продаёт виртуальные серверы, работающие в отказоустойчивом кластере на базе enterprise хранилищ NetApp и HPE 3PAR. Позиционируется как решение для 1С, малого/среднего бизнеса и аутсорс компаний, которым нужны предсказуемые ресурсы и техподдержка профессиональных инженеров, а не чат‑ботов.</p><h3>Тарифные планы и ценообразование</h3><p>InCloud предлагает две основные линейки тарифов:</p><ol><li>Стандартный тариф: внутри процессоры Intel Xeon 2600v4 2ГГц и оперативная память DDR4 2400 МГц.Стоимость: 1 CPU – 200 рублей, 1 Гб RAM – 200 рублей.</li><li>Производительный тариф: использует процессоры AMD EPYC до 3.8 ГГц и оперативной памяти DDR5 4800 МГц. Стоимость: 1 CPU – 250 рублей, 1 Гб RAM – 250 рублей.</li></ol><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/c484688e-fd3f-48ca-b743-616c21699ac4.png" alt="" /></figure><p><b>Стоимость дискового пространства</b>: SATA диски: <b>3 рубля за 1 Гб</b>. SSD и NVMe диски: <b>13 рублей за 1 Гб</b>.</p><h3>Архитектура и поддержка</h3><p>Теперь про то, что упрощает жизнь и добавляет надежности нашим развернутым сервисам:</p><ul><li>Ежедневные бэкапы: данные ваших серверов будут копироваться каждый день, и храниться они могут до 30 дней.</li><li>Удобная панель управления: через нее можно делать снапшоты  и клонировать серверы. Для разработчиков это просто золото – быстро накатить тестовую среду, попробовать новую фичу, а потом откатиться или создать идентичные рабочие среды.</li><li>SLA-договор: есть возможность заключить SLA-договор, чтобы получить гарантированный уровень доступности услуг.</li><li>Новейшие мощные серверы — на базе AMD EPYC 4 поколения.</li></ul><p>Одна из фишек – это возможность напрямую проконсультироваться с сертифицированными инженерами InCloud по сложным проектам.</p><h3>А что с клиентскими кейсами</h3><ol><li><b>Кейс Vamkamin</b>: производственная компания, которая ускорила работу своей системы 1С и сократила IT-расходы на 35%. У них была проблема с медленной работой 1С при одновременном доступе бухгалтерии, склада и отдела продаж, а также с частыми простоями на локальных серверах. InCloud предложил перенести все сервисы в облако, используя серверы на базе AMD EPYC 9554, что обеспечило прирост производительности более 40% по сравнению с предыдущими решениями. Также были внедрены гибкое масштабирование ресурсов и ежедневное резервное копирование.</li><li><b>Кейс Веб-студии 100UP</b>: компания занимается разработкой и поддержкой сайтов для крупных торговых сетей и e-commerce проектов. 100UP переехала к облачному провайдеру InCloud, выбрав тарифы на базе AMD EPYC 9554 с высокой тактовой частотой и большим количеством ядер. Благодаря разнообразию тарифов команда легко распределила проекты по нужным по производительности виртуальным серверам. После переезда 100UP смогла сократить время отклика клиентских сайтов в среднем на 45%, обеспечить бесперебойную работу даже в периоды высокой сезонной нагрузки, ускорить запуск новых проектов, фокусироваться на разработке и маркетинге и улучшить качество предоставляемых услуг.</li></ol><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/c0b63a9f-bb39-4b44-9363-45cefd4c2f62.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/9f98fda8-0b7a-408a-9a82-00f063ee0d88.png" alt="" /></figure><h2>4. SmartApe: быстрые VPS на NVMe‑SSD</h2><p><a href="https://www.smartape.ru/ssd-vps">SmartApe</a> подойдет проектам, где дисковая подсистема и CPU работают без простоя: интернет‑магазины, порталы с большим количеством контента, внутренние корпоративные системы, высоконагруженные API. Если нужен быстрый старт — сервер создаётся за одну‑две минуты; если понадобится масштабирование, тариф можно увеличить без миграции.</p><h3>Преимущества этих VPS</h3><p>Используются современные серверные NVMe SSD диски в RAID массиве, которые в 600 раз быстрее обычных HDD. Скорость чтения достигает 8000 Мбайт/с, а записи — 2000 Мбайт/с.</p><p>Серверы работают на мощных процессорах Intel Xeon Gold или AMD EPYC (до 3.7 ГГц) и быстрой памятью DDR4. Используется полноценная виртуализация KVM с выделенными ресурсами для гарантии их предоставление. Дата-центры уровня TIER-III и TIER-IV обеспечивают Uptime 99.982%. Данные хранятся в хранилище RAID-10.</p><p>Дополнительно клиенты получают полный root-доступ (по SSH для Linux и RDP для Windows), возможность установки любых операционных систем (более 20, включая Ubuntu, CentOS, Debian, Windows Server) и ПО, а также полную изоляцию от других клиентов.</p><h3>Удобство и поддержка</h3><ul><li>Бесплатная панель управления (Hestia) или платная ISPmanager для простого управления сервером.</li><li>Бесплатное базовое администрирование и помощь в переносе сайтов.</li><li>Круглосуточная квалифицированная поддержка 24/7.</li><li>Бесплатный тестовый период 10 дней без оплаты и ввода карты.</li><li>Защита от DDoS-атак включена в стоимость.</li><li>Выделенный внешний IP-адрес (возможность купить до 10 IP).</li></ul><p>Перед покупкой дают десять дней теста без привязки карты; если сервис не подойдёт, в течение тридцати дней можно вернуть деньги за неиспользованный период.</p><h4>Пример использования: интернет‑магазин</h4><p>VPS c 2 vCPU, 4 ГБ RAM, 80 ГБ SSD и портом 100 Мбит/с; при обычном трафике сайт обслуживает 300–500 уникальных посетителей в день, одновременно на страницах бывает 10–20 человек, а в пиковую распродажу до 50; средняя нагрузка 5–10 запросов в секунду, короткими всплесками до 20; заявленный аптайм 99,982 %, реальные замеры отклика после кэширования — 200–300 мс; счёт за такой сервер выходит около 1 300 рублей в месяц.</p><h4>Пример использования: API на Node.js</h4><p>4 vCPU, 8 ГБ RAM, 160 ГБ NVMe и канал 200 Мбит/с; сервис стабильно обрабатывает 50–100 запросов в секунду, на пике достигает 200, одновременно подключены 500–1 000 клиентов, максимум 2 500; трафик близок к 200 ГБ в месяц; при том же аптайме 99,982 % средняя задержка ответа укладывается в 50–100 мс; ежемесячная стоимость в зависимости от опций колеблется в диапазоне 2 600–3 000 рублей.</p><p>SmartApe имеет смысл брать, когда дисковая скорость и гарантированные ресурсы важнее высокого GUI и почасовой тарификации, для расчёта стоимости есть калькулятор конфигураций на сайте и оперативная техподдержка.</p><h2>5. PSB Hosting: что даёт их VPS‑платформа</h2><p><a href="https://psb.hosting/vps">PSB Hosting</a> продвигает VPS-хостинг как решение для сайтов, приложений и SaaS-сервисов, которым нужна предсказуемая мощность и высокий SLA. Провайдер делает упор на новое оборудование, пропускную способность без ограничений и инфраструктуру уровня Tier III+.</p><h3>Локации и тарификация</h3><p>Серверы разворачиваются в четырёх точках: Нидерланды, США, Германия и Финляндия. Для каждой площадки доступен одинаковый конструктор конфигураций. Базовый план NL‑100, который включает 1 vCPU, 2 ГБ RAM и 30 ГБ SSD, стоит 6 долларов в месяц. Линейка поднимается ступенчато:</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/62dfc578-ede9-4533-bfb8-bca1a1a26688.png" alt="" /></figure><p>Слайдеры позволяют довести параметры до 32 ядер, 64 ГБ RAM и 510 ГБ SSD; верхняя планка оплаты — 220 $ в месяц.</p><p>Трафик безлимитный на любых конфигурациях — дополнительной оплаты за гигабайты нет.</p><h3>Аппаратная платформа, ОС и предустановки</h3><p>В хост-узлах применяются процессоры последних линеек AMD и Intel. Оперативная память — DDR5, что снижает задержки при обращении к ОЗУ. Дисковая подсистема полностью на NVMe, объединена в RAID 10: чтение и запись выше, чем у классических SSD, а отказ одного накопителя не выводит хранилище из строя. К каждому VPS подключён выделенный канал с пропускной способностью до 10 Гбит/с.</p><p>Сервер можно поднять сразу с Windows Server, Ubuntu, Debian, CentOS или FreeBSD. Для быстрого старта доступны готовые образы: Bitrix, Django-стек, Docker, FastPanel, Hestia CP, Keitaro, LAMP, Node, OpenVPN, Outline, Portainer, Vesta CP и другие.</p><h3>Управление и поддержка</h3><p>Провайдер обещает круглосуточную техническую поддержку, резервные копии (бэкапы) и автоснапшоты. Для автоматизации предусмотрен API; в панели управления можно масштабировать ресурсы, перезагружать сервер и следить за статистикой.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-31/fabfe43d-7891-4129-8ad5-e87f45b087ef.png" alt="" /></figure><h2>Как выбрать VPS под свой проект</h2><p>Для сайта с пиковыми нагрузками подойдёт SmartApe, где дисковая подсистема на NVMe-SSD в RAID-10 обеспечивает скорость чтения до 8000 Мбайт/с и записи до 2000 Мбайт/с, а сайт на конфигурации с 2 vCPU, 4 ГБ RAM и 80 ГБ SSD выдерживает 300–500 уникальных посетителей в день с пиком до 50 одновременных пользователей и нагрузкой 5–10 запросов в секунду (короткими всплесками до 20).</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/bc98805d-7f7f-471d-a2a2-1df68139c637.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/204e63be-985f-449d-a37c-37ca9993d335.png" alt="" /></figure><p>Если проект включает высоконагруженный API, например, на Node.js, то оптимален SmartApe с конфигурацией 4 vCPU, 8 ГБ RAM и 160 ГБ NVMe, которая стабильно обрабатывает 50–100 запросов в секунду (пики до 200) при 500–1000 одновременных подключениях (максимум 2500) и трафике до 200 ГБ в месяц.</p><p>Для задач с 1С, где важна стабильность и сокращение IT-расходов, выбирайте InCloud на базе AMD EPYC 9554: в кейсе Vamkamin это ускорило работу системы на 40%, сократило расходы на 35% и минимизировало простои, с ежедневными бэкапами до 30 дней и SLA-договором.</p><p>Если нужен VPS для Битрикс с высокой частотой CPU, подойдёт FirstVDS на AMD Ryzen (CPU.Турбо) с частотой до 5,7 ГГц и DDR5: скидка 30% на 3 месяца при покупке лицензии Битрикс, плюс отказоустойчивость на кластере Ceph с репликацией данных.</p><p>Для веб-студий с разработкой и поддержкой сайтов для e-commerce, где требуется распределение проектов по производительности и бесперебойная работа в сезонные пики, подойдёт InCloud на AMD EPYC 9554: в кейсе 100UP это сократило время отклика на 45% и обеспечило стабильность под высокой нагрузкой.</p><p>Если проект ориентирован на международный трафик с предсказуемыми ресурсами и высоким SLA, выбирайте PSB Hosting с локациями в Нидерландах, США, Германии или Финляндии, безлимитным трафиком и каналом до 10 Гбит/с на DDR5 и NVMe в RAID 10.</p><p>Для бэкенда мобильного приложения с нагрузкой до 12 000 уникальных пользователей в сутки (утилизация CPU 25%) подойдёт ИХЦ на NVMe/24 с 24 ГБ RAM и ~200 ГБ SSD, стеком nginx, PHP, MySQL.</p><p>Если развлекательный сайт с более чем 5000 уникальных пользователей в сутки (загрузка CPU ~20%), то подходит ИХЦ на NVMe/12 с 12 ГБ RAM и ~120 ГБ SSD, стеком nginx, Docker, Node.js. Он обеспечит стабильность с безлимитным трафиком и DDoS-защитой.</p><p>Выбор сводится к трём вопросам: где ваши<br />пользователи, какую пиковую нагрузку вы ждёте и нужен ли формальный SLA.<br />Сформулируйте эти требования заранее — и любой из пяти хостингов закроет задачу<br />без проблем в продакшне. Добавить свои рекомендации VPS хостингов — вы всегда<br />можете в комментариях, желательно описывать короткие кейсы.</p>]]></content:encoded>
    </item>
    <item>
      <title>Энтузиаст замедлил PostgreSQL в 42 000 раз с помощью 32 параметров — и ни одной строчки кода</title>
      <link>https://tproger.ru/news/--entuziast-zamedlil-postgresql-v-42-000-raz-s-pomoshhyu-32-parametrov---i-ni-odnoj-strochki-koda</link>
      <comments>https://tproger.ru/news/--entuziast-zamedlil-postgresql-v-42-000-raz-s-pomoshhyu-32-parametrov---i-ni-odnoj-strochki-koda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/--entuziast-zamedlil-postgresql-v-42-000-raz-s-pomoshhyu-32-parametrov---i-ni-odnoj-strochki-koda</guid>
      <description><![CDATA[<p>Энтузиаст замедлил PostgreSQL в 42 000 раз без кода — только с помощью 32 настроек в конфиге. От 7000 TPS до 0,016 за 2 минуты</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/--entuziast-zamedlil-postgresql-v-42-000-raz-s-pomoshhyu-32-parametrov---i-ni-odnoj-strochki-koda">Энтузиаст замедлил PostgreSQL в 42 000 раз с помощью 32 параметров — и ни одной строчки кода</a>»</p>]]></description>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 28 Jul 2025 03:58:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Один энтузиаст решил выяснить не <b>как ускорить</b>, а <b>как максимально замедлить PostgreSQL</b>.</p><p>И ему это <a href="https://byteofdev.com/posts/making-postgres-slow/">удалось</a>: производительность упала с <b>7082 транзакций в секунду до 0,016 TPS</b>, то есть более чем в <b>42 000 раз</b>.</p><p>Причем он не трогал железо, не удалял индексы и не вмешивался в код — все только через postgresql.conf.</p><h2>Минимальный кэш и перегруженный autovacuum</h2><p>Первый шаг — почти отключить кэш: shared_buffers = 2MB. Это резко снижает буферизацию страниц и увеличивает обращения к диску.</p><p>Затем — заставить Postgres непрерывно запускать autovacuum и analyze после каждой вставки. В итоге в логи будут падать десятки операций в секунду. Почти без пользы, но с большим I/O.</p><h2>WAL, как у Брэндона Сандерсона</h2><p>Потом автор усложнил систему логов WAL: настроил частые чекпоинты (checkpoint_timeout = 30, max_wal_size = 32MB) и принудил Postgres писать каждый байт максимально медленно (wal_sync_method = open_datasync, wal_level = logical).</p><p>Производительность упала до <b>менее 1 TPS</b>.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-07-28/3df2f851-d3ea-40df-b64b-7447af3bbb93.jpeg" alt="" /></figure><h2>Отключение индексов и однопоточный I/O</h2><p>Без удаления самих индексов автор просто сделал их бессмысленными для планировщика запросов: random_page_cost и cpu_index_tuple_cost были задраны до 1e300.</p><p>Вдобавок, Postgres был переведен на io_method = worker с io_workers = 1, чтобы все дисковое I/O выполнялось одним потоком.</p><h2>Финал</h2><p>В итоге Postgres смог обработать <b>всего 11 транзакций за 2 минуты</b> со 100 подключениями.</p><p>Эксперимент не только впечатляющий, но и полезный: он показывает, насколько надежно Postgres защищен от «случайного самоуничтожения». Но если очень захотеть — можно все.</p>]]></content:encoded>
    </item>
    <item>
      <title>Что еще есть в терминале Linux: 7 команд, которые экономят кучу времени</title>
      <link>https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni</link>
      <comments>https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni</guid>
      <description><![CDATA[<p>Семь советов для ускорения работы в терминале Linux. Как быстро обработать файлы, отладить Bash-скрипт и редактировать длинные пути в Линукс.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-eshhe-est-v-terminale-linux--7-komand--kotorye-ekonomyat-kuchu-vremeni">Что еще есть в терминале Linux: 7 команд, которые экономят кучу времени</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Регулярные выражения]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 22 Jul 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>Сколько статей про «полезные команды Linux» вы уже прочитали?</b> Алиасы, history, базовые горячие клавиши — факты для джунов, которые опытным админам уже снятся. Если свободно пользуетесь grep и awk, создаете циклы, применяете регулярные выражения — эта статья для вас.</p><p>Рассказываем про 7 команд, влияющие на скорость работы в терминале. Вы узнаете:</p><ul><li>про встроенные bash-операции, которые заменяют пайплайны,</li><li>про способы работы с файловыми дескрипторами,</li><li>про wildcards, которые избавляют от сложных конструкций с find.</li></ul><p>Каждая команда в подборке решает конкретную проблему:</p><ul><li>массовая обработка файлов,</li><li>отладка скриптов,</li><li>работа с длинными путями.</li></ul><h2>1. Bash variable expansions</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/b5f2b475-b18e-49cb-a00c-9197ab87b9f4.jpg" alt="" /></figure><p>Вместо <i>basename</i>, <i>cut </i>для простых операций со строками можно использовать встроенные возможности Bash:</p><p><b>%</b> режет справа до первого совпадения, <b>%%</b> — до последнего. Символ <b>#</b> работает слева направо.</p><p>В реальной работе это помогает при массовой обработке файлов. Например, есть 1000 логов, и нужно каждый переименовать.</p><p>Если использовать <i>basename</i>, запустится 1000 отдельных процессов. <b>Variable expansions</b> работают без <i>fork/exec</i>, без задержек на создание процессов.</p><p>Bash variable expansions используют в циклах с файлами и при работе с массивами. Когда скрипт обрабатывает сотни файлов, разница в скорости становится заметной. Еще и код выглядит чище.</p><h2>2. Here-string (&lt;&lt;&lt;)</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/ef72e05d-6f80-49aa-842b-32c209d8b724.jpg" alt="" /></figure><p>Here-string упрощает передачу строковых данных в команды без создания временных файлов или использования echo с пайпом.</p><p>Реальная экономия времени проявляется при отладке и модификации скриптов. Например, когда SQL-запрос или конфигурация зашиты в <i>here-документ</i>. С <b>here-string </b>данные собраны в одном месте, легко редактируются и переиспользуются.</p><p>Работает не только с базами данных. Отправка в API, конфигурирование сетевых устройств через expect, передача команд в Docker — через &lt;&lt;&lt; код будет понятнее, а сопровождение проще.</p><h2>3. /proc/$$/fd</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/f314de69-9459-4ecb-ab62-2c7b5c7b54f3.jpg" alt="" /></figure><p>Каждый процесс имеет стандартные дескрипторы <b>0</b> (stdin), <b>1</b> (stdout), <b>2</b> (stderr), которые представлены как символические ссылки. Директория <b>/proc/$$/fd </b>предоставляет доступ к файловым дескрипторам текущего процесса:</p><p>Переменная <b>$$</b> содержит PID текущего процесса, поэтому /proc/$$/fd ведет к дескрипторам именно вашего шелла.</p><p>Практическое применение — отладка перенаправлений и работа с дескрипторами в сложных скриптах:</p><h2>4. Wildcards с диапазонами</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/08dbc2a0-5e2e-49a3-9486-a042a0480369.jpg" alt="" /></figure><p>Про <b>*</b> и <b>?</b> говорят чаще, чем про диапазоны в квадратных скобках. Такие маски используют реже, а зря — они решают массу задач по отбору файлов.</p><p>Wildcards автоматически раскрываются шеллом в список подходящих файлов — это их основная функция. Кавычки нужны только когда передаете символы [, ] как литеральные:</p><p>Экономия времени заметна при работе с логами, бэкапами и в скриптах автоматизации. Например, для архивации файлов с определенными номерами, очистки временных файлов с нужными паттернами.</p><h2>5. sudo !!</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/9434c945-925f-40b3-9062-994fce2091c6.jpg" alt="" /></figure><p>Набрали длинную команду, нажали Enter, получили «<b>Permission denied</b>». Рука на рефлексе тянется к стрелке вверх и Home, чтобы добавить sudo в начало.</p><p>Вот способ в разы быстрее:</p><p>Двойное восклицание <b>!!</b> — это ссылка на предыдущую команду целиком. Bash подставит всю строку со всеми аргументами и ключами. Кажется мелочью, но для админа, который 10 раз в день забывает sudo, это серьезная оптимизация.</p><p>Двойное восклицание универсально и работает не только с sudo:</p><ul><li><b>time !!</b> для замера времени выполнения,</li><li><b>nohup !! &amp;</b> для запуска в фоне,</li><li><b>strace !!</b> для отладки.</li></ul><p>Если между командой и sudo !! выполнялись другие команды, восклицание сработает для последней из них. Для поиска конкретной команды в истории используйте <b>!строка</b>.</p><h2>6. ^старое^новое</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/1888b625-8ae5-4d0e-a73d-25260ff7d893.jpg" alt="" /></figure><p>Основной способ исправления опечатки — стрелка вверх, поиск ошибки, исправление. Смотрите, как можно сделать это побыстрее:</p><p>Символ <b>^</b> ищет первое вхождение слова и заменяет его. Работает с последней командой.</p><p>Заменяется только первое вхождение. Если ошибочное слово встречается несколько раз, способ не сработает. В таких случаях придется использовать классическое редактирование или <i>history expansion</i>.</p><h2>7. Alt+.</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-07-10/4d1c03bb-66b2-4cb0-8c3e-ce80c3406ec5.jpg" alt="" /></figure><p>Создали файл с длинным именем — теперь его нужно отредактировать, переместить, изменить права. Каждый раз перепечатывать путь утомительно и чревато ошибками.</p><p>Комбинация <b>Alt+.</b> (Alt + точка) вставляет последний аргумент предыдущей команды в текущую позицию курсора. Повторное нажатие перебирает аргументы из более ранних команд.</p><p>Экономия времени проявляется при работе с файлами и директориями. Например: распаковали архив, теперь нужно зайти в созданную папку, затем посмотреть содержимое, потом изменить права. Вместо того, чтобы 3 раза печатать один путь, можно 3 раза нажать Alt+.</p><p>Еще этой комбинацией вставляются:</p><ul><li>имена пользователей,</li><li>IP-адреса,</li><li>названия сервисов,</li><li>параметры конфигурации.</li></ul><p>Alt + точка работает в большинстве шеллов. Привыкнув к ней, начинаешь использовать на автомате.</p><h2>Что запомнить</h2><ul><li><b>${filename%.*} </b>и встроенные операции со строками работают быстрее внешних утилит. % режет справа, # — слева. Полезно при работе с циклами для массовой обработки файлов.</li><li><b>&lt;&lt;&lt;</b> — here-string удобен для передачи коротких строковых данных в команды. С многострочными данными лучше использовать here-document или переменные.</li><li><b>/proc/$$/fd</b> — доступ к файловым дескрипторам текущего процесса. Ускоряет отладку перенаправлений и работу с дескрипторами.</li><li><b>file[1-5] и [^b]* </b>— диапазоны в wildcards для точного отбора файлов. Кавычки нужны только для передачи литеральных символов.</li><li><b>sudo !!</b> — повторяет последнюю команду с sudo. Также работает с time !!, nohup !! &amp;. Если между нужной командой и !! выполнялись другие операции, используйте !строка для поиска конкретной команды в истории.</li><li><b>^старое^новое</b> — заменяет первое вхождение в предыдущей команде. Работает только с последней командой и заменяет первое совпадение.</li><li><b>Alt+. </b>— вставляет последний аргумент предыдущей команды. Повторное нажатие перебирает аргументы из истории команд. Экономит время при работе с длинными путями.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Выбираем российский хостинг в 2025: подборка на любой запрос</title>
      <link>https://tproger.ru/articles/vybiraem-rossijskij-hosting-v-2025--podborka-na-lyuboj-zapros</link>
      <comments>https://tproger.ru/articles/vybiraem-rossijskij-hosting-v-2025--podborka-na-lyuboj-zapros?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/vybiraem-rossijskij-hosting-v-2025--podborka-na-lyuboj-zapros</guid>
      <description><![CDATA[<p>В этом материале — семь проверенных российских хостингов для разных задач: от стартапа до корпоративного проекта. Каждый прошел тестирование на аптайм (время бесперебойной работы), безопасность и доступность поддержки.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/vybiraem-rossijskij-hosting-v-2025--podborka-na-lyuboj-zapros">Выбираем российский хостинг в 2025: подборка на любой запрос</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Ruby on Rails]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[Windows Server]]></category>
      <category><![CDATA[Техподдержка]]></category>
      <category><![CDATA[Россия]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[CMS]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 22 Jul 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В 2025 году российский хостинг переживает новый виток развития. После того как законодательство изменилось и добавились новые технологии, локальные провайдеры усилили инфраструктуру.</p><p>Теперь они предлагают решения, которые не хуже, а где-то даже и лучше международных аналогов и по надёжности, и по цене.</p><p>Посмотрим, кто из них есть в этом списке, и определим особенности хостингов для сайта.</p><h2>1. FirstVDS: профессиональные решения для любых проектов</h2><p><a href="https://firstvds.ru/">FirstVDS</a><a href="https://firstvds.ru/" rel="noopener noreferrer nofollow"></a> — хостинг-провайдер с опытом на рынке более 20 лет. Предлагают VPS и VDS с виртуализацией KVM для проектов любого размера. Все серверы работают на современном оборудовании. Трижды победитель в номинации «Хостер года» Национальной премии «ЦОДы.РФ».</p><p>Хостинг подойдет бизнесу любого масштаба: для любых сайтов — от визиток до высоконагруженных интернет-магазинов, для разработки и тестирования, для сервисов и других проектов. Отдельные решения для Битрикс, установка ОС семейства Linux и Windows Server.</p><h3>Особенности хостинга</h3><h4>Надёжность</h4><p>FirstVDS обеспечивает аптайм 99,97–99,99% в 2025 году, подтверждённый замерами (например, отклик из Москвы — 27 мс в апреле 2025). Серверы размещены в трёх дата-центрах уровня Tier III: два в Москве (IXcellerate и Web DC) и один в Амстердаме (euNetworks). Отказоустойчивый кластер Ceph гарантирует работу даже при сбоях точки или канала.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/80547603-f63a-4f2e-9bc1-332c9e061bf9.png" alt="" /></figure><h4>Инфраструктура</h4><p>Серверы работают на процессорах Intel Xeon и AMD EPYC (до 5,7 ГГц в линейке CPU.Турбо), с быстрыми NVMe-дисками объёмом до 8 ТБ и оперативной памятью DDR5 (до 768 ГБ в VDS Атлант). Это обеспечивает высокую производительность для ресурсоёмких задач, таких как Битрикс или высоконагруженные приложения.</p><h4>Гибкость</h4><p>Тарифы масштабируются: от базовых конфигураций (1 CPU, 1 ГБ RAM, 40 ГБ SSD) до мощных серверов (192 ядра, 768 ГБ RAM, 8 ТБ NVMe). Линейки:</p><ul><li>VDS Форсаж: AMD EPYC, до 128 ядер, 512 ГБ RAM, 4 ТБ NVMe, от 749 ₽/мес (Москва/Амстердам).</li><li>CPU.Турбо: AMD Ryzen до 5,7 ГГц, DDR5, от 624 ₽/мес (Москва).</li><li>VDS Атлант: отказоустойчивый, до 192 ядер, 8 ТБ NVMe, от 1619 ₽/мес (Москва).</li><li>VDS Storage: хранилище, от 704 ₽/мес (Москва).Горячее масштабирование (hot-resize) позволяет добавлять CPU, RAM или диск без перезагрузки.</li></ul><h4>Автоматизация</h4><p>Шаблоны для быстрого развёртывания: Django, Redmine, Tomcat, Teamspeak, Nextcloud, LAMP, LEMP, Forgejo Git, GitLab, Битрикс. Поддерживаются ОС Linux (Ubuntu, Alma, Debian, Rocky, CentOS, Oracle), FreeBSD, Windows Server. API и панель ispmanager 6 lite (бесплатно на месяц) упрощают управление.</p><h4>Безопасность</h4><p>Включена защита от DDoS-атак на сетевом уровне, BitNinja для защиты сервера и сайта, SSL-сертификаты GlobalSign. Доступны автобэкапы, снапшоты, Кибер-бэкап и объектное хранилище S3 для больших данных.</p><h4>Поддержка</h4><p>Круглосуточная поддержка 24/7 без чат-ботов, ответ до 15 минут через чат, личный кабинет или телефон. Бесплатно: помощь с активацией и первичной настройкой. Платно: установка ПО, администрирование. Экспертная линия для мониторинга и устранения сбоев.</p><h4>Бонусы</h4><ul><li>Тестовый период 3 дня.</li><li>Бесплатный перенос до 10 сайтов с другого хостера.</li><li>Скидки: 40% на первый месяц при оплате на 1/3/6 месяцев или 3 месяца бесплатно при оплате за год.</li><li>Лояльность: скидка 5–20% для клиентов от 5 лет.</li><li>Реферальная программа: 10% от расходов привлечённых клиентов для партнёра, 25% скидка для нового пользователя на первый месяц.</li><li>Домены: продление по цене регистрации.</li></ul><h3>Тарифы и условия</h3><p>Тестовый период 3 дня, после него подключаете один из основных тарифов:</p><ul><li>Линейка готовых конфигураций от 1 CPU, 1 Гб RAM, 40 Гб SSD-накопителя и от 219 руб/мес. до сервера с 8 CPU, 12 Гб RAM, 150 Гб NVMe-накопителя. Локация в РФ и Нидерландах.</li><li>VDS Форсаж: на AMD Epyc от 749 ₽/мес. Локации: РФ и Нидерланды.</li><li>CPU.Турбо: гибкая конфигурация на базе высокочастотных AMD Ryzen 9 от 624 ₽/мес. При покупке лицензии Битрикс дополнительная скидка 30% на 3 месяца аренды CPU.Турбо. Локация в РФ.</li><li>VDS Атлант: отказоустойчивый с автобэкапами от 1 619 ₽/мес. Локация: РФ.</li><li>VDS Storage: сервис как хранилище с гибкой конфигурацией от 704 ₽/мес. Локация: РФ</li></ul><p>Все тарифы доступны для тестирования по согласованию с отделом продаж. Для точного подбора конфигурации используйте гибкую настройку.</p><h2>2. UltraVDS: для малого бизнеса и стартапов</h2><p>Компания <a href="https://ultravds.com/">UltraVDS</a>, провайдер услуг виртуальных серверов (VPS/VDS), работает на рынке с 2014 года — предлагает решения для разных операционных потребностей. Сервисы UltraVDS можно использовать для развертывания торговых роботов, запуска чат-ботов, хостинга веб-сайтов, а также для создания FTP-хранилищ данных. Есть предложения для фрилансеров, цифровых агентств, корпоративных пользователей и стартапов, которым требуются функциональные инфраструктурные решения.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/edef3abb-6f77-4c69-be56-e22d90f379db.png" alt="" /></figure><h3>Технические особенности</h3><p>Серверы UltraVDS размещены в современном дата-центре, расположенном в Москве. Доступность сервиса (аптайм) составляет 99,98%, что обеспечивает высокую стабильность работы. Сетевая пропускная способность превышает 200 Мбит/с, при этом трафик предоставляется без ограничений.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-07-17/56ccb605-b64b-44f3-94b7-10e960541dda.png" alt="" /></figure><p>Система защиты от DDoS-атак способна обрабатывать трафик до 1,5 Тбит/с и поддерживает стабильность работы сервера даже при интенсивном внешнем воздействии. Лицензия на Windows Server входит в стоимость обслуживания в данном предложении. Это упрощает развертывание сервера: вам не нужно отдельно покупать и устанавливать лицензию. Плюс снижает общие операционные расходы для пользователей этой операционной системы.</p><h3>Тарифные планы</h3><p>Для новых пользователей UltraVDS предусмотрена возможность 3-дневного тестового периода, позволяющего оценить функциональность и производительность сервиса.</p><p>После тестового периода стоимость тарифов начинается от 119 рублей в месяц. На сайте доступен онлайн-калькулятор, позволяющий подобрать конфигурацию сервера и рассчитать итоговую стоимость.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-07-17/932d0cca-9f20-4723-8ae9-8d9c3218a08a.png" alt="" /></figure><p>Клиентам доступны различные варианты оплаты, включая ежемесячную систему без предоплаты. При авансовой оплате на период от 3 до 12 месяцев предоставляются скидки до 20%, размер которых зависит от выбранного срока. В случае досрочного прекращения использования сервиса, неиспользованный остаток средств возвращается на баланс пользователя.</p><h3>Поддержка и обслуживание</h3><p>Техническая поддержка UltraVDS работает круглосуточно, 7 дней в неделю. Среднее время ответа на запросы составляет до 15 минут. Связь со службой поддержки возможна по электронной почте и телефону, указанным на официальном сайте.</p><h2>3. RUVDS: 10 лет на рынке облачных решений</h2><p><a href="https://ruvds.com/ru-rub">RUVDS</a> — облачный провайдер, имеющий десятилетний опыт работы на рынке услуг виртуальных серверов (VPS/VDS). Является официальным партнером Huawei в России, работает по SLA. Компания предоставляет инфраструктурные решения, которые могут быть применены для широкого спектра задач, включая хостинг высоконагруженных интернет-магазинов, корпоративных порталов, игровых серверов, сложных backend-систем и чат-ботов.</p><p>Платформа RUVDS спроектирована для оптимизации процесса развертывания ресурсов. Одной из ее особенностей является маркетплейс, который позволяет быстро запускать серверы с предустановленным программным обеспечением. Это способствует ускорению старта проектов, снижая потребность в ручной настройке распространенных CMS, игровых серверов и сред разработки.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-07-17/aed25b96-b39b-4be9-b875-dc695645ef24.png" alt="" /></figure><h3>Тарифная политика и варианты оплаты</h3><p>RUVDS предлагает различные тарифные планы. Например, стоимость конфигурации Linux-сервера (1 CPU, 512 МБ RAM, 10 ГБ HDD, 1 IPv4) начинается от 139 ₽/месяц. Это может быть рассмотрено как экономичное решение для запуска небольших проектов и проведения тестирования.</p><p>Клиентам доступны разные опции оплаты:</p><ol><li>Ежемесячные платежи или предоплата на срок от 3 до 12 месяцев, при которой предоставляются скидки до 20%, зависящие от продолжительности периода.</li><li>Для проектов с динамической нагрузкой предусмотрена посекундная тарификация, оплата по которой взимается только за фактически использованные ресурсы. Неиспользованный остаток средств в рамках этой модели возвращается на баланс пользователя</li></ol><p>Дополнительно, до конца 2025 года панель управления ISP Manager для сервера и сайта предоставляется без дополнительной платы при создании любого VPS.</p><h3>Глобальная инфраструктура и стабильность</h3><p>Инфраструктура включает 17 дата-центров уровня Tier III, расположенных по всему миру. Это один из самых больших показателей по количеству геолокаций среди российских провайдеров. Для работы используются корпоративное оборудование и накопители (HDD, SSD, NVMe), чтобы обеспечить стабильную работу и производительность размещенных проектов.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/3f3c970e-820f-4f0e-9b53-f227950e298b.png" alt="" /></figure><h3>Поддержка клиентов и доступные ресурсы</h3><p>Техническая поддержка RUVDS доступна круглосуточно, 7 дней в неделю. Среднее время ответа на запросы через тикет-систему или онлайн-чат составляет 15 минут. Клиентам предоставляются полные административные права и консультации по вопросам запуска и настройки серверов. Для самостоятельного изучения доступна база знаний, включающая инструкции и руководства.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-07-17/c086a963-2d51-4ada-86c8-0c1704cf8230.png" alt="" /></figure><h3>Безопасность и масштабирования</h3><p>В контексте безопасности данных, RUVDS предлагает несколько решений:</p><p>- Встроенная защита от DDoS-атак, способствующая поддержанию бесперебойной работы серверов при внешнем воздействии.</p><p>- Стандартный IPv4-адрес включен в стоимость каждой виртуальной машины, с опцией аренды дополнительных IP-адресов.</p><p>- API, соответствующий OpenAPI 3.0.0, предоставляет возможности для интеграции и автоматического масштабирования серверных ресурсов в зависимости от нагрузки.</p><p>- Компания официально подтверждает соответствие требованиям ФСТЭК и ФЗ-152 по защите персональных данных, что обеспечивает соблюдение соответствующих законодательных норм.</p><h2>4. McHost: решения для бизнеса разного масштаба</h2><p><a href="https://mchost.ru/"> McHost</a> предоставляет комплексные хостинговые решения, включая виртуальный хостинг и VPS/VDS с NVMe-накопителями. Сервис поддерживает популярные CMS (WordPress, Joomla, 1С-Битрикс) с оптимизированными настройками и автоматической установкой через панель управления.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/2ccc459a-8df5-41b6-bbf9-b751bed2e757.png" alt="" /></figure><p>McHost ориентирован на широкий круг клиентов:</p><ul><li>владельцы сайтов-визиток, блогов и лендингов — благодаря низким тарифам и полному набору опций;</li><li>интернет-магазины с небольшой нагрузкой — тарифы с SSD-накопителями и автоматическим резервным копированием обеспечивают стабильную работу;</li><li>разработчики, которым нужны<br />VPS/VDS с root-доступом — работают серверы на KVM-виртуализации с ОС Linux и Windows;</li><li>госучреждения и компании,<br />работающие с персональными данными — соответствие 152-ФЗ и размещение в дата-центрах Tier III в Москве.</li></ul><h3>Особенности сервиса</h3><p>McHost поддерживает стабильную работу с аптаймом 99.9% за счет размещения оборудования в дата-центрах уровня Tier III — в Москве и Нидерландах.</p><p>Сервис предоставляет защиту от DDoS-атак, автоматическое резервное копирование раз в два дня с хранением данных в течение 30 дней для виртуального хостинга и 14 дней для VPS, а также поддержку российских криптографических стандартов. Клиентам доступны различные варианты размещения: от виртуального хостинга с SSD (от 157.5 ₽/мес) до выделенных серверов с NVMe-накопителями.</p><h3>Технические параметры и условия</h3><p>Инфраструктура McHost базируется на серверах Dell с NVMe-накопителями и процессорами Intel Xeon (частота ядер от 2.35 ГГц). Для виртуального хостинга используется CloudLinux с технологией CageFS, обеспечивающей изоляцию аккаунтов. Поддержка российских ОС («Альт») подтверждена для VPS-тарифов.</p><p>В техподдержку можно обратиться по телефону, через тикет или в Telegram-боте. Время ответа — до 10 минут.</p><p>Текущие тарифы:</p><ul><li>Виртуальный хостинг: от 157 ₽/мес<br />(3 ГБ SSD, 1 сайт).</li><li>VPS: от 396 ₽/мес (15 ГБ SSD, 1<br />ядро CPU).</li><li>Выделенные серверы: от 3 000 ₽/мес<br />(32 ГБ RAM, 2×1 ТБ HDD).</li></ul><h2>5. UFO Hosting: VPS/VDS и выделенные серверы с портом до 10 Гбит/с и безлимитным трафиком</h2><p><a href="https://ufo.hosting/">UFO Hosting </a>предлагает VPS/VDS и выделенные серверы на партнёрской инфраструктуре IXcellerate (Tier III). В портфолио — недорогие виртуальные машины и серверы с портом 10 Gbps для проектов, которым нужна стабильность без завышенных цен.</p><p>Сервис подходит для пользователей разных масштабов: от фрилансеров и веб‑студий до средних и крупных компаний. Для DevOps‑специалистов доступны API и инструменты автоматизации.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-19/3cfc6e79-bab0-48ab-862b-f523c0ad24e8.png" alt="" /></figure><h3>Основные сценарии использования</h3><ul><li>корпоративные сайты, CRM‑системы и веб‑приложения;</li><li>аналитические сервисы и SaaS‑продукты;</li><li>инфраструктура для разработки и тестирования;</li><li>задачи фрилансеров, агентств и digital‑команд.</li></ul><h3>Формат работы, особенности и интеграции</h3><p>Серверы установлены в российском дата‑центре Tier III (IXcellerate), что означает резервирование по питанию и каналам связи. Заявленный аптайм — 99,98 %. Поддержка работает круглосуточно в тикетах, чате и по телефону; среднее время ответа 5–10 минут.</p><p>Сервис UFO Hosting делает акцент на безопасности и гибкости. Есть сеть с защитой от DDoS, возможность горячего расширения ресурсов, автоматическое развёртывание из шаблонов и API для интеграции. Поддерживаются популярные фреймворки и CMS, есть интеграции с GitLab, Telegram и DockerHub. Бэкапы, снапшоты и резервирование входят в стандартный набор, так что восстанавливать тестовую среду не придётся вручную.</p><p>В панели управления можно автоматически установить популярные CMS, панели управления, хранилища и DevOps‑инструменты. Это экономит время на настройку и подходит тем, кто не хочет поднимать всё с нуля.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-08-06/e4433ae3-898b-4c14-90c1-2a4bbb8b13a1.png" alt="" /></figure><h3>Условия использования и тарифы</h3><p>Базовые конфигурации начинаются от 577 руб./месяц. Заявленная скорость порта — до 10 Gbps, что подходит для проектов, где много трафика.</p><p>Есть возможность бесплатно попробовать сервис присутствует, но предоставляется по запросу в поддержку, а при оплате на срок от трёх месяцев действуют скидки, а также регулярно проводятся акции: это поможет оптимизировать бюджет.</p><figure><img src="https://media.tproger.ru/user-uploads/99854/2025-08-06/1e2e0191-1194-4a60-a612-fcac5d8cf76d.png" alt="" /></figure><p>В целом, UFO Hosting выглядит как практичное решение для тех, кому нужны производительные VPS/VDS и выделенные серверы в России. При выборе стоит оценить, насколько конфигурации подходят под конкретные нагрузки и есть ли необходимость в интеграциях из коробки.</p><h2>6. Timeweb: хостинг для веб-проектов</h2><p><a href="https://timeweb.com/">Timeweb </a>предоставляет услуги хостинга для различных типов веб-проектов. Сервис поддерживает популярные CMS, включая WordPress, 1C-Битрикс и Joomla, что делает его подходящим как для личных блогов, так и для корпоративных сайтов.</p><p>Платформа использует собственную панель управления с инструментами для работы с сайтами, базами данных и резервными копиями. Ежедневное автоматическое резервное копирование с хранением данных до 30 дней включено во все тарифные планы. Базовая защита от DDoS-атак доступна для всех клиентов без дополнительной платы.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/b443bfef-bccb-4672-bd55-cb67a1146bc3.png" alt="" /></figure><p>Инфраструктура Timeweb размещена в дата-центрах уровня Tier III в России (Санкт-Петербург) и Казахстане (Алматы). Гарантированный показатель uptime составляет 99.98%. Поддерживаются современные технологии: PHP версий от 5.3 до 8.4, MySQL от 5.6 до 8.0, а также Perl, Python, SSH, FTP и Cron.</p><p>Тарифные планы:</p><ul><li>Year+: от 164 ₽/мес (2 сайта, 15<br />ГБ NVMe, 2 БД);</li><li>Optimo+: от 248 ₽/мес (15 сайтов,<br />40 ГБ NVMe, безлимитные БД);</li><li>Century+: от 347 ₽/мес (35 сайтов,<br />50 ГБ NVMe, безлимитные БД);</li><li>Millennium+: от 482 ₽/мес (60<br />сайтов, 60 ГБ NVMe, безлимитные БД).</li></ul><p>Все тарифы включают бесплатный SSL-сертификат, 10 ГБ почтовой квоты с неограниченным количеством ящиков и DNS-хостинг. При оплате годового тарифа предоставляется домен в зонах .RU/.РФ в подарок.</p><p>Техническая поддержка доступна круглосуточно через онлайн-чат, тикет-систему и по телефону. Среднее время ответа не превышает 15 минут. Новые клиенты могут протестировать сервис бесплатно в течение пробного периода.</p><h2>7. Reg.ru: комплексные решения для сайтов и доменов</h2><p><a href="https://www.reg.ru/">Reg.ru </a>сочетает услуги хостинга и регистрации доменов, что упрощает управление веб-проектами. Компания работает с 2005 года, имеет статус аккредитованного регистратора доменных имён в зонах .RU и .РФ.</p><h3>Функциональные возможности</h3><p>Платформа предоставляет доступ к трём панелям управления: ISPmanager, cPanel и Plesk. Это позволяет выбрать наиболее удобный интерфейс для работы с сайтами. Все тарифы включают бесплатный SSL-сертификат от Let’s Encrypt, который автоматически устанавливается при создании сайта.</p><p>Начинающим пользователям доступен конструктор сайтов с готовыми шаблонами. Поддерживаются популярные CMS, включая WordPress, Joomla и 1С-Битрикс. Ежедневное резервное копирование данных с хранением копий в течение 30 дней входит в стандартный набор услуг.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/c1ac0c6a-51ae-4ae5-8875-f18a01ffdc2c.png" alt="" /></figure><h3>Техническая инфраструктура</h3><p>Серверы размещены в дата-центрах уровня Tier III в Москве. Средний показатель uptime составляет 99.9%, что подтверждается ежемесячной статистикой. Подключение к сети осуществляется по выделенным каналам со скоростью до 1 Гбит/с на выделенных серверах.</p><h3>Поддержка и тарифы</h3><p>Техническая поддержка доступна 24/7 через онлайн-чат и тикет-систему. Среднее время ответа составляет 15-20 минут. Для срочных вопросов можно обратиться по телефону.</p><p>Тарифы — от 151 ₽/мес (7 ГБ SSD, 15 сайтов). При регистрации домена в зонах .RU или .РФ предоставляется скидка на другие доменные имена.</p><h2>8. Спринтхост: хостинг с персональным подходом</h2><p><a href="https://sprinthost.ru/">Sprinthost</a> предлагает услуги хостинга с акцентом на индивидуальную поддержку клиентов. Сервис работает с 2011 года и специализируется на VPS-решениях для различных веб-проектов.</p><h2>Особенности сервиса</h2><p>Компания предоставляет персонального менеджера для каждого клиента, который помогает с настройкой сервера и решением технических вопросов. А если вы остались недовольны услугами, то в течение 30 дней сервис вернёт деньги. Sprinthost проводит бесплатные обучающие вебинары по DevOps и администрированию серверов.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-16/7acc90d0-655a-4cda-906f-a7e5ad4f9a8e.png" alt="" /></figure><h3>Технические характеристики и тарифы</h3><p>Инфраструктура размещена в дата-центрах Москвы и Санкт-Петербурга с аптаймом 99.9%. Поддерживаются современные технологии разработки, включая Ruby on Rails, Node.js, Python и Docker. Все серверы используют SSD-накопители с гарантированной скоростью чтения/записи.</p><p>Тарифные планы:</p><ul><li>Start: 290 ₽/мес (1 ядро, 1 ГБ<br />RAM, 15 ГБ SSD);</li><li>Turbo: 1 900 ₽/мес (4 ядра, 8 ГБ<br />RAM, 100 ГБ NVMe).</li></ul><h3>Поддержка</h3><p>Техническая помощь доступна 24/7 через тикет-систему и онлайн-чат. Среднее время ответа составляет 10-15 минут. Для корпоративных клиентов предусмотрена приоритетная поддержка по телефону.</p><h2>Как выбрать хостинг в 2025 году</h2><p>Выбор хостинга зависит от типа проекта и его требований. Для небольших сайтов и блогов подойдет виртуальный хостинг с поддержкой популярных CMS — важно проверить наличие автоматических бэкапов и базовой защиты от DDoS. Если проект связан с обработкой персональных данных, убедитесь, что провайдер соответствует 152-ФЗ и использует сертифицированное оборудование.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/3a0b1d01-c4e0-424d-86b2-8988d43bcdb1.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/b3c26558-3a50-4eb3-a9f3-89c899fd9e59.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-20/3408c453-b5db-44ce-b6ab-f1b3bcb5abd1.png" alt="" /></figure><p>Для высоконагруженных сервисов и интернет-магазинов лучше рассматривать VPS или выделенные серверы. Обратите внимание на тип накопителей (SSD/NVMe), возможность масштабирования ресурсов и аптайм дата-центров (рекомендуется от 99.9%).</p><p>Перед покупкой протестируйте сервис — большинство провайдеров предлагают пробный период. Проверьте скорость работы панели управления и отзывчивость поддержки. Не забывайте о резервном копировании: даже если хостинг предоставляет эту услугу, дублируйте критически важные данные самостоятельно.</p><p>Главное правило — выбирайте решение, которое покрывает текущие потребности проекта. Важно, чтобы конфигурацию можно было оперативно менять по мере роста запросов и масштабирования бизнеса. Технологии меняются быстро, и гибкость конфигурации часто важнее сиюминутной экономии.</p><h2>FAQ</h2><h3>Что такое виртуальный хостинг и когда его выбирать?</h3><p>Виртуальный хостинг — это экономичное решение, где один физический сервер делит ресурсы между множеством сайтов. Подходит для небольших проектов с низкой нагрузкой: личных блогов, лендингов или стартовых страниц.</p><p>Преимущества: низкая стоимость, простота управления через панели, автоматические обновления и базовая защита. Минусы: ограниченные ресурсы; производительность зависит от соседних сайтов; минимальный контроль над настройками.</p><h3>Что такое VPS/VDS и для каких проектов он подходит?</h3><p>VPS (Virtual Private Server) или VDS — это виртуальный сервер с выделенными ресурсами (процессор, память, диск), предоставляющий доступ для полной настройки. Идеален для проектов среднего масштаба: интернет-магазинов, API, SaaS, чат-ботов, корпоративных порталов или приложений с умеренным трафиком.</p><p>Преимущества: гибкость конфигураций, выбор ОС, изоляция ресурсов. Минусы: требует базовых навыков администрирования, стоимость выше, чем у виртуального хостинга.</p><h3>Что такое выделенный сервер и когда его использовать?</h3><p>Выделенный сервер — это физический сервер, полностью зарезервированный под ваш проект. Подходит для высоконагруженных систем: крупных интернет-магазинов, игровых платформ, корпоративных ERP или аналитических сервисов с большим трафиком.</p><p>Преимущества: максимальная производительность, полный контроль, высокая отказоустойчивость. Минусы: высокая цена, сложность настройки и обслуживания.</p><h3>В чём основные различия между виртуальным хостингом, VPS и выделенным сервером?</h3><p>Виртуальный хостинг — самый дешёвый и простой, но ресурсы делятся между пользователями, что ограничивает производительность (до 1000–2000 посетителей в сутки).</p><p>VPS обеспечивает выделенные ресурсы и гибкость, справляясь с нагрузкой до 5000–10 000 пользователей в сутки.</p><p>Выделенный сервер — максимум мощности для пиков свыше 10 000 пользователей, но требует значительных затрат и технических знаний.</p><p>Выбор зависит от масштаба: виртуальный для старта, VPS для роста, выделенный для enterprise.</p><h3>Нужны ли навыки администрирования для хостинга?</h3><p>Для виртуального хостинга навыки не нужны — управление идёт через интуитивные панели, а провайдеры обеспечивают обновления и базовую поддержку. Для VPS желательны базовые знания (настройка ОС, установка ПО), хотя многие провайдеры предлагают помощь. Для выделенного сервера навыки администрирования необходимы, так как вы полностью отвечаете за сервер, хотя провайдеры могут предлагать платное администрирование.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как найти работу в IT за границей в 2025 году: ответы на часто задаваемые вопросы и рекомендации экспертов</title>
      <link>https://tproger.ru/articles/kak-najti-rabotu-v-it-za-granicej-v-2025-godu--otvety-na-chasto-zadavaemye-voprosy-i-rekomendacii-ekspertov</link>
      <comments>https://tproger.ru/articles/kak-najti-rabotu-v-it-za-granicej-v-2025-godu--otvety-na-chasto-zadavaemye-voprosy-i-rekomendacii-ekspertov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Мария Грищенко]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-najti-rabotu-v-it-za-granicej-v-2025-godu--otvety-na-chasto-zadavaemye-voprosy-i-rekomendacii-ekspertov</guid>
      <description><![CDATA[<p>Свежая статистика, исследования и советы экспертов: как российским IT-специалистам найти работу за границей в 2025 году.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-najti-rabotu-v-it-za-granicej-v-2025-godu--otvety-na-chasto-zadavaemye-voprosy-i-rekomendacii-ekspertov">Как найти работу в IT за границей в 2025 году: ответы на часто задаваемые вопросы и рекомендации экспертов</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Статистика]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Amazon]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[VPN]]></category>
      <category><![CDATA[На английском языке]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Data Science]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[Стартапы]]></category>
      <category><![CDATA[Английский]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[GTK]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Кибербезопасность]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 18 Jul 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Российские IT-специалисты востребованы не только у себя на родине, но и за рубежом. В 2024 году иностранные технологические компании наняли <a href="https://www.kommersant.ru/doc/7675878">более 5 тыс. сотрудников</a> из России — это в два раза больше, чем годом ранее. Чаще всего наших айтишников приглашают работать китайские IT-гиганты Huawei, Alibaba и Tencent, также активизировались европейские работодатели SAP, Delivery Hero и американские Amazon, OpenAI. </i></p><p>Если вы хотите стать одним из них и расширить свои горизонты, сделать первые шаги вам поможет наш материал. Здесь мы собрали ответы на часто задаваемые вопросы по поиску работы в IT за рубежом: наиболее перспективные направления, вспомогательные сервисы, особенности виз, рекомендации, как адаптировать резюме для иностранного рынка и получить оффер мечты.</p><p>Бонус — комментарии экспертов с многолетним опытом работы за границей и глубоким пониманием международного рынка труда.</p><h2>Какие IT-профессии наиболее востребованы за рубежом</h2><p>По данным <a href="https://www.rbc.ru/business/29/01/2025/6799966d9a794709c7932279">сервиса по поиску работы HeadHunter</a>, в 2024 году наибольшим спросом за границей пользовались российские:</p><ul><li>менеджеры по продажам и работе с клиентами (13%),</li><li>операторы колл-центров (5%),</li><li>дизайнеры, менеджеры по маркетингу, интернет-маркетологи, художники (по 4%),</li><li>учителя, SMM- и контент-менеджеры (по 3%),</li><li>секретари, помощники руководителя, ассистенты (по 2%).</li></ul><p>Программисты и разработчики заняли почётное второе место (10%). А специалисты технической поддержки и тестировщики набрали всего по 2%.</p><p>Но в исследовании <a href="https://netology.ru/blog/news/03-07-2023-europe-it">образовательной онлайн-платформы «Нетология» и международного коммуникационного агентства Zecomms Agency</a> специалист технической поддержки — наоборот, наиболее востребованная профессия за рубежом. С ним связано 17% от общего массива IT‑вакансий, что делает специалиста техподдержки абсолютным лидером по количеству открытых вакансий.</p><figure><img src="https://media.tproger.ru/user-uploads/114863/2025-06-30/dd2413cd-3aac-48e1-a29c-30620bdccf1d.png" alt="" /><figcaption>Самые востребованные за рубежом IT-специальности, данные исследования «Нетологии» и Zecomms Agency</figcaption></figure><p>На втором месте расположился программный инженер (16%), на третьем — бизнес-аналитик (6%) и IT-консультант (6%).</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting:</b></p><blockquote>Российские IT-специалисты всё ещё остаются востребованными за рубежом, но по сравнению с 2022 годом ситуация изменилась. Международные компании уже не так охотно берут в штат сотрудников из России, известны случаи сокращений из-за гражданства. Причина — политика компаний, особенно тех, которые решили покинуть российский рынок. Зато за последние три года многие отечественные стартапы релоцировались в другие страны, и они отдают предпочтение сотрудникам из России.</blockquote><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>В 2022 году интерес к российским IT-специалистам был выше, но в 2025 ситуация изменилась из-за экономической нестабильности, роста процентных ставок и замедления найма во многих странах. Вакансий стало меньше, особенно без разрешения на работу. Однако IT по-прежнему остаётся одной из самых высокооплачиваемых и востребованных сфер.</blockquote><h2>Языки программирования, актуальные для иностранных компаний</h2><p>Согласно <a href="https://netology.ru/blog/news/04-07-2023-top-programming-languages">исследованию «Нетологии» и Zecomms Agency</a>, Java признан самым популярным языком программирования — его активно используют компании по всему миру. На Java приходится более четверти всех открытых вакансий (26%) в сфере IT в Европе, США, Латинской Америке, Азии и на Ближнем Востоке.</p><p>Java — это универсальный язык программирования, который отличаются стабильностью, масштабируемостью и кроссплатформенностью. На нём пишут крупные корпоративные приложения в банках, промышленных, страховых и телеком-компаниях, облачные, распределённые и IoT- системы, микросервисы. Также Java считается неотъемлемой частью бэкенд-разработки.</p><p>На втором месте по популярности находится язык SQL, который используют для разработки баз данных и систем аналитики. На него пришлось 24% всех вакансий, бóльшая часть из них в Европе, Азии и на Ближнем Востоке.</p><p>Замыкает тройку лидеров Python (23%) — более половины открытых вакансий в Азии и на Ближнем Востоке связано именно с этим языком. Оно и неудивительно: на Python пишут модели для машинного обучения, анализа данных и автоматизации.</p><figure><img src="https://media.tproger.ru/user-uploads/114863/2025-06-30/6a35cec4-e5d1-4991-a1a8-ef49722d59ea.png" alt="" /><figcaption>Самые востребованные за рубежом языки программирования, данные исследования «Нетологии» и Zecomms Agency</figcaption></figure><h2>Сколько айтишникам платят за границей</h2><p>Более высокая зарплата — <a href="https://www.cnews.ru/news/top/2023-10-27_polovinu_rossijskih_it-shnikov">одна из главных причин</a>, почему российские IT-специалисты хотят работать за границей.</p><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей:</b></p><blockquote>Трудоустройство за границей открывает доступ к международным командам, передовым технологиям и крупным проектам мирового уровня с лучшими практиками разработки, высокими стандартами качества кода и современными архитектурными подходами. Всё это способствует быстрому профессиональному росту. Мне переезд позволил быть ближе к центру IT-индустрии и дал возможность развиваться в высококонкурентной среде.</blockquote><p>В большинстве европейских стран зарплаты индексируются и официально растут вслед за инфляцией. За счёт этого доходы, пусть и медленно, но увеличиваются. К сожалению, не все отечественные компании могут такое гарантировать — практика индексации зарплат в России пока не так распространена.</p><p>Но ключевое — размер оклада. По данным <a href="https://ruitunion.org/posts/2024-04-24-market-and-wages-state/">«Профсоюза работников ИТ»</a>, медианная зарплата специалистов уровня senior в России составляет 276 362 рубля в месяц, в то время как за рубежом она равна 386 730 рублей в месяц. Российские миддлы получают 170 000 рублей, а работающие за границей — 205 142 рубля. Зарплата джунов несильно отличается, хотя «за бугром» она всё-таки немного больше: 85 000 рублей против 80 000 рублей в России.</p><p>Таким образом, зарплата IT-специалистов за рубежом как минимум в 1,5 раза больше, чем в России.</p><p>Дополнительное преимущество — оплата в валюте: долларах, евро или фунтах. После пересчёта на рубли итоговая сумма все равно будет выше средней зарплаты в России — и это без учёта премий и бонусов.</p><figure><img src="https://media.tproger.ru/user-uploads/114863/2025-06-30/caf0a60b-53e5-4468-9c37-44101399c92c.png" alt="" /><figcaption>Медианная зарплата IT-специалистов в России и за рубежом, статистика «Профсоюза работников ИТ»</figcaption></figure><h2>Где IT-кадры пользуются спросом</h2><p>Найти работу в IT сейчас везде нелегко, но чуть проще это сделать там, где активно развивается IT-сектор и требуется много кадров соответствующего профиля:</p><p><b>Германия. </b>Наибольший дефицит IT-специалистов наблюдается в Германии — в 2023 году было опубликовано <a href="https://netology.ru/blog/news/03-07-2023-europe-it">103 089 вакансий</a>. Особенно остро нехватка кадров ощущается в таких областях, как разработка программного обеспечения, Data Science, кибербезопасность и DevOps. А в 2025 году страна планирует выдать <a href="https://prian.ru/news/germaniya-vydast-200-000-viz-kvalificirovannym-kadram-iz-za-nehvatki-rabochey-sily.html">на 10%</a> больше рабочих виз, чем годом ранее.</p><p><b>Нидерланды.</b> В стране большое внимание уделяется IT-стартапам. Так, в 2024 году голландские технологические компании привлекли <a href="https://tech.eu/2025/06/12/the-growth-and-opportunities-of-the-netherlands-tech-ecosystem/">€3,7 млрд венчурных инвестиций</a> — это около 5% от общего объёма капитала, вложенного в европейскую экосистему. Благодаря этому Нидерланды вошли в топ‑10 стран Европы по объёму инвестиций в технологии. Особенно быстро растёт сектор DeepTech («глубоких технологий») — полупроводники, искусственный интеллект и квантовые технологии.</p><p><b>Канада.</b> Такие канадские города как Торонто, Ванкувер и Монреаль считаются настоящей IT-меккой. Здесь активно развиваются стартапы и работают подразделения крупнейших технологических компаний — Google, Microsoft, Amazon. Кроме того, для IT-специалистов есть много иммиграционных программ, например, <a href="https://www.canadacareersite.com/blog/global-talent-stream-canada-work-permit-application">Global Talent Stream</a>, которая позволяет получить разрешение на работу в течение двух недель.</p><p><b>США.</b> В 2023 году объём IТ-рынка США достиг <a href="https://www.comnews.ru/content/233424/2024-05-29/2024-w22/1008/rossiyskiy-it-rynok-ustupil-obemu-rynkam-stran-briks">$1,3 трлн</a> и продолжает развиваться <a href="https://www.mordorintelligence.com/industry-reports/united-states-it-services-market">высокими темпами</a>. В Европейском союзе он составил <a href="https://www.comnews.ru/content/233424/2024-05-29/2024-w22/1008/rossiyskiy-it-rynok-ustupil-obemu-rynkam-stran-briks">$1,05 трлн</a>, в Китае — <a href="https://www.comnews.ru/content/233424/2024-05-29/2024-w22/1008/rossiyskiy-it-rynok-ustupil-obemu-rynkam-stran-briks">$348 млрд</a>, в России — <a href="https://www.comnews.ru/content/233424/2024-05-29/2024-w22/1008/rossiyskiy-it-rynok-ustupil-obemu-rynkam-stran-briks">$36,1 млрд</a>. Таким образом, американский технологический рынок в 36 раз больше российского, в 1,24 раза больше европейского и почти в четыре раза превосходит китайский. Это подтверждает его статус мирового лидера. Соответственно, IT-специалистов нужно много.</p><h2>Куда уехать проще всего</h2><p>По данным <a href="https://www.rbc.ru/business/29/01/2025/6799966d9a794709c7932279">HeadHunter</a>, активнее всего российских специалистов приглашают на работу компании из:</p><ul><li>Белоруссии — 172,3 тыс. приглашений,</li><li>Казахстана — 150,9 тыс. приглашений,</li><li>Грузии и Турции — 69,7 тыс. и 67,8 тыс. приглашений соответственно,</li><li>Узбекистана — 57,2 тыс. приглашений.</li></ul><p>Самый большой рост интереса продемонстрировали китайские работодатели — он увеличился почти в шесть раз. В 2023 году количество предложений для жителей России о работе в Китае составляло всего 4,8 тыс., тогда как в 2024 году цифра достигла 27,6 тыс. предложений.</p><p>Кроме того, за год потребность в российских специалистах выросла в Сербии с 5,8 тыс. до 26,3 тыс. (+356,3%), в Турции — с 23,5 тыс. до 67,8 тыс. (+188,6%), на Кипре — с 4,6 тыс. до 12 тыс. (+160,9%), в Польше — с 4,1 тыс. до 9,0 тыс. (+119,6%) и в ОАЭ — с 19,2 тыс. до 41,7 тыс. (+117,2%).</p><p>А Европа стала лидером по количеству предложений для IT-специалистов со знанием русского языка — <a href="https://netology.ru/blog/news/03-07-2023-europe-it">3%</a> всех IT-вакансий в регионе. На других рынках доля таких предложений не превышает 1%. Чаще всего русскоязычных специалистов ищут <a href="https://netology.ru/blog/news/03-07-2023-europe-it">в Польше — 2 200 вакансий, Венгрии — 752 вакансии, Австрии — 178 вакансий, Греции — 152 вакансии</a>.</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting: </b></p><blockquote>Не все страны охотно принимают специалистов из других стран. Если раньше одними из самых популярных направлений для релокации были Канада и США, то сейчас переехать туда стало значительно сложнее. Больше шансов на трудоустройство в компании Испании, Португалии, Кипра, ОАЭ.</blockquote><h2>Как IT-специалисту найти работу за границей: четыре шага</h2><h3>1. Зарегистрируйтесь на международных платформах</h3><p>Принцип поиска работы за рубежом такой же, как и в России. Нужно зарегистрироваться на платформах по типу HeadHunter и откликаться на понравившиеся вакансии. Чем больше откликов, тем лучше.</p><p>Вот подборка сайтов для поиска работы за границей:</p><ul><li><a href="https://ru.linkedin.com/">LinkedIn</a> — профессиональная социальная сеть, где можно искать вакансии и налаживать контакты;</li><li><a href="https://www.indeed.com/">Indeed</a> — международный агрегатор вакансий, позволяющий фильтровать их по странам, городам и отраслям;</li><li><a href="http://relocate.me">Relocate.me</a> — платформа для вакансий с релокацией;</li><li><a href="https://remoteok.com/">Remote OK</a> — площадка для поиска удалённой работы;</li><li><a href="https://weworkremotely.com/">WWR</a> — сервис, где публикуют вакансии крупные зарубежные компании, например, Amazon или Google.</li><li><a href="https://www.angellist.com/careers">AngelList Talent</a> — каталог вакансий в иностранных стартапах.</li></ul><p>Некоторые из них открываются только с VPN.</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting: </b></p><blockquote>Удобнее всего искать вакансии зарубежных компаний через LinkedIn. По моему опыту, большинство специалистов находят работу за границей именно через эту площадку. Но есть и альтернативные варианты — например, телеграм-каналы с профильными вакансиями. Будьте готовы к тому, что придётся отправлять много откликов. В среднем на 100 откликов приходится не более 5 ответов.</blockquote><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>В основном я искал работу через LinkedIn. Это самая эффективная платформа: я обновил профиль, загрузил резюме и активно взаимодействовал с рекрутерами. Также полезно размещать резюме на популярных job-порталах и быть открытым к предложениям — тогда многие специалисты по подбору персонала сами выходят на связь.</blockquote><h3>2. Адаптируйте резюме для иностранного рынка</h3><p>Если вы собираетесь искать работу на европейском или американском рынке, разумеется, резюме должно быть составлено на английском языке. В англоязычных странах резюме называют Curriculum Vitae или CV.</p><p>Эксперты компании EP Advisory, которая помогает российским специалистам строить карьеру за рубежом, <a href="https://ep-advisory.com/ru/statii/rabotayushhee-rezyume-na-anglijskom-na-osnove-30-000-proverennyh-rezyume/">рекомендуют</a> включать в CV разделы Name, Profile, Education, Experience, Skills &amp; Other. Названия предыдущих компаний и занимаемые должности следует выделять, а каждый блок —  разграничить чертой.</p><figure><img src="https://media.tproger.ru/user-uploads/114863/2025-06-30/2f6d7e8d-fa4e-4d6c-8925-e3c2228fc0cb.png" alt="" /><figcaption>Пример грамотно составленного резюме на английском языке от экспертов EP Advisory</figcaption></figure><p>Кроме того, в некоторых странах, например, Великобритании, США и Канаде не принято добавлять фото в резюме. Такое правило стало следствием законов против дискриминации в этих странах, поэтому его несоблюдение может вызвать негативную реакцию и привести к мгновенному отказу.</p><p>Дополнительно к резюме стоит приложить мотивационное письмо (Cover Letter), подготовленное специально под конкретную вакансию. В мотивационном письме уже не пишут об образовании и навыках — эти сведения указывают только в резюме. А в Cover Letter особый упор делается на кейсах и объяснении, чем для вас интересна компания и почему вы для неё — самый подходящий кандидат.</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting: </b></p><blockquote>Необходим большой и подтверждённый опыт работы. Придётся конкурировать со специалистами уровня senior со всех концов света. Особенно много кандидатов из Индии, Ирана, Пакистана.</blockquote><h3>3. Обратитесь в агентство по трудоустройству</h3><p>Самостоятельно найти работу за границей и разобраться во всех сопутствующих вопросах, связанных с написанием резюме, оформлением виз и переездом, может быть сложно. Поэтому стоит обратиться в агентства по трудоустройству, которые все эти моменты возьмут на себя.</p><p>Вот список наиболее известных рекрутинговых агентств:</p><ul><li><a href="https://www.adecco.com/">Adecco </a>— крупнейшее агентство с вакансиями по всему миру;</li><li><a href="https://manpower.ru/">Manpower</a> — международная стаффинговая, аутсорсинговая и HR-консалтинговая компания из России;</li><li><a href="https://www.michaelpage.com/">Michael Page</a> — международная компания, которая специализируется на подборе персонала среднего и высшего звена;</li><li><a href="https://www.hays.com/">Hays</a> — британская рекрутинговая компания, которая предоставляет услуги по подбору персонала в 33 странах мира;</li><li><a href="https://www.harveynash.com/">Harvey Nash</a> — международная компания, которая специализируется на IT-аутсорсинге;</li><li><a href="https://www.randstad.pl/ru/">Randstad</a> — голландская консалтинговая компания, которая сотрудничает с ведущими зарубежными работодателями.</li></ul><p>Агентства также консультируют по вопросам адаптации и помогают с поиском жилья.</p><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>Чтобы найти работу в Лондоне, я сотрудничал с международными и британскими рекрутинговыми агентствами — Hays, Harvey Nash и Michael Page. Примерно 50% предложений приходили именно от них. Эти агентства играют важную роль на IT-рынке и обладают широкой сетью контактов с работодателями по всей Европе. Они помогали мне в поиске подходящих позиций и сопровождали на всех этапах — от первичного отклика до собеседования и подписания оффера.</blockquote><h3>4. Получите визу и разрешение на работу</h3><p>Без визы и разрешения приступить к работе за границей не получится. Здесь доступны два варианта — Digital Nomad Visa или обычные рабочие визы.</p><p><b>Digital Nomad Visa.</b> Digital Nomad Visa или «виза цифрового кочевника» позволяет легально жить за рубежом, но при этом продолжать удалённо работать на родину. В отличие от туристической визы, Digital Nomad Visa даёт право длительно находиться в определённой стране, а в сравнении с рабочей визой — не требует трудоустройства на местном рынке.</p><p>Это не классическая рабочая виза. Она разрешает трудиться из разных частей мира, но с ней нельзя работать на компании из страны пребывания. Также не всегда можно перевести семью.</p><p>Чтобы получить визу цифрового кочевника, нужно подтвердить минимальный доход (чаще всего <a href="https://ep-advisory.com/ru/statii/digital-nomad-visa-zit-v-evrope-i-rabotat-udalenno/?ref=journal.zarplata.ru">не ниже 2000 евро в месяц</a>) и наличие медицинской страховки. Также может понадобиться трудовой договор или договор подряда, доказывающие, что вы работаете удалённо. Сейчас Digital Nomad Visa оформляют в<a href="https://www.globalcitizensolutions.com/digital-nomad-visa/"> 66 странах</a>, включая Португалию, Испанию, Эстонию, ОАЭ и Южную Корею.</p><p><b>Классические рабочие визы.</b> Это визы EU Blue Card или виза H‑1B.</p><ul><li>Голубая карта (EU Blue card) — виза для работы в Европе. Чтобы получить её, нужен диплом о высшем образовании (не ниже бакалавра) и оффер с зарплатой от 48 300 евро год (43 760 евро для IT‑специалистов) на срок минимум шесть месяцев. В случае одобрения выдаётся вид на жительство, действующий до четырёх лет с возможностью продления.</li></ul><ul><li>Виза H‑1B — виза для работы в США. Она также требует наличия высшего образования и оффера от местной компании. Но американское законодательство устанавливает лимит на выдачу H‑1B — 65 000 базовых и 20 000 дополнительных виз для специалистов с магистерской степенью из США. Всего 85 000 виз в год. Виза предоставляется максимум на три года с возможностью продления до шесть лет.</li></ul><p>Рабочие визы позволяют получить полноценный правовой статус резидента страны, в которую вы планируете переезжать, а вместе ним — все социальные гарантии: медстраховку, оплачиваемый отпуск, пенсионные отчисления.</p><h2>Официальное трудоустройство или фриланс</h2><h3>Удалённая работа на фрилансе</h3><p>Фриланс — самый простой способ начать работать с зарубежными компаниями без лишней бюрократии и сложностей с оформлением. Достаточно зарегистрироваться на зарубежную фриланс-платформах <a href="https://www.upwork.com/">Upwork</a> или <a href="https://www.fiverr.com/">Fiverr</a>, и можно сразу браться за международные проекты. Единственное, могут возникнуть трудности с оплатой, поэтому стоит завести себе иностранную банковскую карту.</p><p>Главные минусы фриланса — нет оплачиваемого отпуска и больничных, а доход крайне нестабилен.</p><h3>Официальное трудоустройство с релокацией</h3><p>Официальное трудоустройство гарантирует стабильную зарплату и полный соцпакет, а при релокации — помощь с переездом и адаптацией в новой стране.</p><p>Однако получить оффер с переводом в местный офис не так просто. Иностранные компании редко берут на себя расходы, связанные с релокацией российских специалистов и их семей. Чаще всего они нанимают тех, кто уже легально живёт за границей — например, по рабочей визе или с видом на жительство. В таком случае проще оформить перевод в местный офис или принять человека на работу через филиал в этой стране.</p><p>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting:<b></b></p><blockquote>Найти работу будет проще, если вы уже находитесь в стране, и компании не придётся заниматься вашей релокацией. Поэтому хороший вариант — попробовать переехать самостоятельно, продолжая работать удалённо в российской компании или на фрилансе. У вас будет время присмотреться к стране, понять, подходит ли она вам. А если вы достаточно активны и коммуникабельны, можно будет попробовать найти вакансию через местные сообщества российских эмигрантов.</blockquote><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>В первую очередь, нужно убедиться, что у вас есть правовой статус или разрешение на работу в стране, где вы планируете трудоустроиться. Это значительно повышает ваши шансы на успех.</blockquote><h2>Какой уровень владения английским языком нужен</h2><p>Для оценки владения иностранными языками, включая английский, в Европе используют систему CEFR (Common European Framework of Reference). CEFR выделяет шесть уровней знания языка: A1, A2, B1, B2, C1, C2.</p><p>Чтобы успешно строить карьеру за границей, рекомендуется уровень не ниже B1-B2, который позволит понимать профессиональные тексты, участвовать во встречах и вести рабочую переписку.</p><p><b>Максим Оганов, ментор, бизнес-консультант, автор проекта Oganov.Consulting:</b></p><blockquote>Обязательное требование — свободное владение английским: например, в Португалии большинство сотрудников IT-компаний общаются на нём. Но иногда кандидату необходимо знание местных языков — так, если вы хотите переехать во Францию, шансы на трудоустройство без владения французским минимальны.</blockquote><p><b>Евгений Козак, senior фронтенд-разработчик компании With Intelligence, живёт в Лондоне, более 10 лет опыта работы за границей: </b></p><blockquote>Главной трудностью для меня был язык. Технический английский у меня на хорошем уровне, особенно когда речь идёт о собеседованиях, терминах и обсуждении архитектуры — в этом я чувствую себя уверенно. Однако повседневный английский, особенно неформальное общение, давался сложнее. Кроме того, структура интервью в других странах немного отличается, но к ней я быстро адаптировался. Повысить уровень языка и стать увереннее в повседневном общении мне помогли постоянная практика, разговоры с носителями языками и участие в командных митингах.</blockquote><h2>Коротко о главном</h2><ul><li>Иностранные компании активно используют Java, Python, SQL и нуждаются в программистах, умеющих писать на этих языках.</li><li>IT-специалисты особенно востребованы в Германии, Нидерландах, Канаде и США — странах с наиболее интенсивным ростом технологического сектора.</li><li>Проще всего уехать в Белоруссию, Казахстан, Турцию, Грузию и Китай.</li><li>Работать за границей можно официально или на фрилансе.</li><li>Чтобы получить оффер, следует зарегистрироваться на международных платформах для поиска работы, адаптировать резюме, оформить визу и, при необходимости, обратиться в агентство.</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>10 библиотек Python, которые меняют карьеру</title>
      <link>https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru</link>
      <comments>https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru</guid>
      <description><![CDATA[<p>10 библиотек Python, которые помогут прокачаться в аналитике, ML и разработке. Как они работают и почему меняют карьеру.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/10-bibliotek-python--kotorye-menyayut-kareru">10 библиотек Python, которые меняют карьеру</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[Нейронные сети]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Django]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Jupyter Notebook]]></category>
      <category><![CDATA[Визуализация]]></category>
      <category><![CDATA[Образование]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Анализ данных]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 17 Jul 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>У Python тысячи библиотек, но лишь немногие действительно меняют карьеру. Они помогают не просто решать задачи, а ускорять проекты, прокачивать навыки и выходить на следующий уровень в аналитике, машинном обучении и разработке. В этом материале мы собрали 10 библиотек, которые помогут зарабатывать на Python и развивать навыки.</p><h2>1. Pandas</h2><p>Pandas — библиотека для работы с данными в Python, позволяющая легко загружать, анализировать, очищать и преобразовывать числовую информацию в удобной табличной форме. По сути, это Excel, который смог, и позволяет делать всё автоматизировано и на порядки быстрее.</p><p>Библиотека строится вокруг двух ключевых структур: <b>Series</b> (одномерный массив с индексами); <b>DataFrame </b>(таблица с индексами и колонками).</p><h3>Какие задачи решает библиотека</h3><p>Pandas полезна для следующих задач:</p><ul><li>Сам анализ данных: можно быстро фильтровать, группировать, агрегировать и строить сводные таблицы.</li><li>Очистка данных: удаляем пустые строки, заменяем значения, приводим типы.</li><li>Загрузка данных из CSV, Excel, SQL.</li><li>Визуальная разведка данных (EDA) перед построением моделей.</li><li>Подготовка данных для ML и отчётов.</li><li>Автоматизация отчётов и ETL-пайплайнов.</li></ul><p>Благодаря Pandas аналитик превращается в инженера данных, а ML-специалист может сосредоточиться на моделях, а не на ручной подготовке датасетов.</p><h3>Как пользоваться</h3><p>Ниже разберём простейший кейс: нужно загрузить данные о зарплатах разработчиков из CSV, посчитать среднюю зарплату по языкам программирования и отобрать топ-5.</p><h3>Почему это меняет карьеру</h3><p>Работа с Pandas становится границей между знанием Python и умением решать задачи бизнеса. Для <b>джуна </b>это шанс сразу показать практическую пользу: выгрузки, отчёты и базовый анализ можно делать в десятки раз быстрее и аккуратнее, чем вручную в эксельке.</p><p>Для <b>аналитика</b> Pandas превращается в главный рабочий инструмент, позволяя не просто проверять гипотезы и делать сводные таблицы, а строить полноценные отчётные пайплайны, автоматизировать рутинные выгрузки и концентрироваться на сути данных, а не на правках ручками.</p><p>Для <b>ML-инженера</b> владеть Pandas — значит уметь готовить датасеты качественно; быстро очищать и приводить данные к нужному виду, что напрямую влияет на результат моделей. Без этого работа над проектами машинного обучения часто превращается в бесконечную возню с данными.</p><p>Наконец, даже для <b>разработчиков</b> Pandas может стать неожиданным бустом в карьере. Например, когда нужно автоматизировать отчёты для бизнеса или быстро анализировать логи и данные из БД без поднятия дашбордов — Pandas даёт гибкость и скорость, которые редко даёт что-то ещё в экосистеме Python.</p><h2>2. Django</h2><p>Django — фреймворк для веб-разработки на Python, который позволяет быстро создавать надежные и масштабируемые веб-приложения. Он следует принципам DRY (Don’t Repeat Yourself — не повторяй себя), предоставляя разработчику ORM, роутинг, систему авторизации, админку, работу с формами, шаблонами и инструментами безопасности из коробки.</p><p>Django подходит как стартапам, которым нужно быстро выйти на рынок, так и крупным проектам с миллионами пользователей. Это не просто библиотека, а полноценный каркас для построения и сопровождения веб-сервисов.</p><h3>Какие задачи решает библиотека</h3><p>Каркас, действительно, каркасный. Задачи следующие:</p><ul><li>Создание веб-приложений и API любой сложности.</li><li>Быстрая разработка MVP, прототипов и коммерческих проектов.</li><li>Упрощение работы с базами данных через ORM, без написания сырого SQL.</li><li>Построение административных панелей для управления данными без ручной разработки.</li><li>Гибкая маршрутизация и работа с формами, валидацией и шаблонами.</li><li>Реализация аутентификации, авторизации и защиты приложений.</li></ul><p>Django позволяет сосредоточиться на бизнес-логике и продукте, не тратить недели на настройку инфраструктуры.</p><h3>Как пользоваться</h3><p>Устанавливаем:</p><p>Создаем проект и приложение:</p><p>Пример модели:</p><p>Миграция базы данных:</p><p>Создание админки:</p><p>После этого можно запустить сервер:</p><p>И перейти по адресу http://127.0.0.1:8000/admin для управления записями через готовую админ-панель.</p><h2>3. PyTorch</h2><p>PyTorch — мощная библиотека Python. Она позволяет строить и обучать нейронные сети, проводить вычисления с автоматическим дифференцированием и работать с GPU для ускорения самих вычислений.</p><p>Главное отличие PyTorch от других ML-фреймворков — динамическая вычислительная графика (define-by-run): модель строится и изменяется во время выполнения кода, что даёт гибкость при создании и отладке сложных моделей.</p><p>Сегодня PyTorch используется в продакшен системах, научных исследованиях, компьютерном зрении, NLP и генеративных моделях, занимая ведущее место в индустрии.</p><h3>Какие задачи решает библиотека</h3><p>В функционал PyTorch входят:</p><ul><li>Построение нейронных сетей любой сложности (CNN, RNN, трансформеры);</li><li>Обучение и тестирование моделей на CPU и GPU;</li><li>Реализация кастомных слоёв и loss-функций;</li><li>Разработка и деплой ML/AI моделей в продакшен;</li><li>Быстрая итерация гипотез с удобной отладкой.</li></ul><p>С PyTorch можно начать с простых нейронных сетей, а затем перейти к реализации современных архитектур.</p><h3>Как пользоваться</h3><p>Установим PyTorch (на CPU, для GPU потребуется версия с CUDA):</p><p>Рассмотрим кейс обучения простой нейронной сети для классификации рукописных цифр MNIST.</p><p>После обучения можно использовать torch.save() для сохранения модели и torch.load() для загрузки в продакшн.</p><h3>Почему это меняет карьеру</h3><p>PyTorch — билет в мир современной разработки AI и машинного обучения. Владение инструментом даёт <b>разработчику</b> возможность уверенно войти в области, которые продолжают оставаться топовыми на рынке: искусственный интеллект, компьютерное зрение, NLP, генерация изображений и видео и т.д.</p><p>Для <b>начинающего ML/AI-специалиста </b>PyTorch помогает лучше понять, как устроены нейронные сети, и под капотом увидеть, как происходят вычисления. Это ускоряет рост навыков и делает разработчика востребованным в исследованиях и R&amp;D-проектах.</p><p>Для <b>дата-сайентистов</b> PyTorch позволяет превратить исследовательские ноутбуки в готовые к деплою модели, благодаря PyTorch Lightning, TorchScript и ONNX.</p><p>Для<b> разработчиков, которые хотят выйти на рынок AI</b>, PyTorch — это мастхев: проекты в стартапах и крупных компаниях всё чаще строятся вокруг него. Умение писать кастомные loss-функции, проектировать сложные пайплайны обучения, настраивать обучение на кластерах и GPU — компетенции, которые существенно бустят зарплату.</p><p>PyTorch в целом помогает расширять портфолио: с ним можно создавать генеративные модели, строить LLM, участвовать в соревнованиях и работать с самыми современными подходами в машинном обучении.</p><h2>4. Polars</h2><p>Polars — современная библиотека для обработки данных в Python, созданная как альтернатива Pandas. Она использует колоночную архитектуру и многопоточность, что позволяет работать с большими объёмами данных значительно быстрее и с меньшим потреблением памяти.</p><p>Polars вдохновлена Pandas, но её API оптимизировано для производительности и удобства, а также даёт разработчику возможность писать цепочки ленивых вычислений, которые оптимизируются перед выполнением. Это делает её отличным инструментом для аналитиков, дата-инженеров и дата-сайентистов, которым нужно обрабатывать данные быстро.</p><h3>Какие задачи решает библиотека</h3><p>Polars явно есть, чем гордиться:</p><ul><li>Загрузка, очистка и преобразование больших датасетов;</li><li>Анализ данных с использованием цепочек преобразований;</li><li>Быстрая агрегация и группировка данных;</li><li>Ленивые вычисления: построение пайплайнов преобразования данных, которые выполняются только при вызове collect().</li><li>Обработка данных, которые не помещаются в память, за счёт эффективности и колоночной архитектуры.</li></ul><p>Если Pandas начинает притормаживаться на данных в несколько гигабайт, Polars обычно продолжает работать быстро, позволяя без боли обрабатывать большие CSV.</p><h3>Как пользоваться</h3><p>Установка:</p><p>Давайте загрузим данные и проведем базовые трансформации:</p><p>А вот и пример ленивых вычислений:</p><p>В чем особенность:</p><ul><li>pl.read_csv загружает данные сразу.</li><li>pl.scan_csv создаёт план вычислений для последующей оптимизации.</li><li>Используются выражения (pl.col, .with_columns, .agg), которые композируются без создания промежуточных копий, это ускоряет процесс.</li></ul><h3>Почему это меняет карьеру</h3><p>Polars меняет карьеру, потому что даёт преимущество в скорости и эффективности при работе с данными. Там, где Pandas уже не справляется, полярный медведь приходит на помощь.</p><p>Для <b>дата-инженеров</b> Polars полезен при построении ETL и пайплайнов обработки данных, где важна скорость и предсказуемое потребление ресурсов. Его можно использовать в продакшен-скриптах, для подготовки данных к ML и для автоматизации отчётности.</p><p>Для <b>дата-сайентистов </b>Polars даёт возможность анализировать больше данных за меньшее время, быстро итерировать гипотезы и ускорять исследования. Его API достаточно близок к Pandas, поэтому переход не требует месяцев переучивания.</p><p>Освоение Polars показывает работодателям, что ты не просто знаешь стандартные инструменты, но умеешь выбирать оптимальные решения для реальных задач, повышая эффективность работы команды. В эпоху роста данных это критично для любого Python-разработчика, работающего с аналитикой и машинным обучением.</p><h2>5. FastAPI</h2><p>FastAPI — современный фреймворк для создания API на Python, заточенный под скорость, асинхронность и валидацию данных из коробки. Он построен на Starlette и Pydantic, автоматически создаёт OpenAPI-документацию, поддерживает асинхронное программирование и позволяет писать производительные REST и WebSocket API с минимальным количеством кода.</p><p>Вместо долгой настройки, как у Flask или Django, в FastAPI многое готово изначально: удобная работа с запросами и ответами, декларативная валидация, документация Swagger, асинхронность и высокая производительность без лишних усилий.</p><h3>Какие задачи решает</h3><p>Задач, действительно, много:</p><ul><li>Быстрая разработка REST API для мобильных и веб-приложений;</li><li>Создание бэкенда для ML/DS моделей (деплой моделей в виде API);</li><li>Построение микросервисов с хорошей производительностью;</li><li>Реализация websocket-серверов и асинхронных API;</li><li>Подготовка внутренних инструментов или бэкендов для MVP.</li></ul><p>FastAPI помогает быстро запускать API и уверенно масштабировать его в полевых условиях. Это один из немногих фреймворков Python, который по скорости работы сопоставим с Node.js и Go.</p><h3>Как пользоваться</h3><p>Во-первых, нужно установить FastAPI и Uvicorn (используем ASGI-сервер для запуска):</p><p>Простейший API-пример с эндпоинтом GET /:</p><p>Запускаем сам сервер:</p><p>После запуска API будет доступен по адресу http://127.0.0.1:8000/. Автоматически доступна интерактивная документация Swagger по адресу http://127.0.0.1:8000/docs.</p><p>FastAPI поддерживает валидацию параметров запроса, тел запросов и путей прямо через типы Python. Например, простой эндпоинт с параметром:</p><p>При вызове http://127.0.0.1:8000/items/10?q=test FastAPI автоматически проверит, что item_id — это число, и распарсит q как строку.</p><h3>Почему это меняет карьеру</h3><p>FastAPI — билет в мир бэкенда, где скорость и чистота кода имеют довольно высокое значение. Для <b>Python-разработчика </b>это возможность быстро освоить создание API и микросервисов, не увязнув в громоздкой настройке, как в Django, и при этом получить систему, готовую к продакшену.</p><p>Для <b>ML-специалиста</b> FastAPI становится инструментом для деплоя моделей: можно обернуть пайплайн предсказаний в API, подключить авторизацию или логирование и получить работающий сервис за считанные дни.</p><p>Вообще умение быстро поднимать и поддерживать API — навык, который ценят в бигтехе и стартапах. На разработчиков, которые владеют FastAPI, часто равняются: они умеют превращать идеи бизнеса в работающие сервисы за минимальное время.</p><h2>6. Typer</h2><p>Typer — современная библиотека для создания CLI-приложений на Python с минимальным количеством кода и автоматической генерацией документации. Автор библиотеки — Себастьян Рамирес, создатель FastAPI.</p><p>Главная особенность Typer — использование type hints для автоматического парсинга аргументов командной строки. Вы получаете удобную и читаемую CLI с поддержкой автодополнения и цветного вывода за считанные минуты.</p><h3>Какие задачи решает библиотека</h3><p>Список задач такой:</p><ul><li>Создание CLI-утилит любого уровня сложности.</li><li>Быстрое прототипирование и упаковка Python-скриптов в удобные инструменты для продакшена.</li><li>Генерация подробной справки (--help) и автодополнения команд.</li><li>Облегченная поддержка и масштабирование CLI за счёт структуры и читаемого кода.</li><li>Организация CLI с подкомандами, вложенными аргументами и обработкой ошибок.</li></ul><p>Typer использует аннотацию типов и минимум шаблонного кода.</p><h3>Как пользоваться</h3><p>Установка:</p><p>Пример минимальной CLI:</p><p>Теперь можно запустить из консоли:</p><p>Результат будет такой: Привет, Алиса! Тебе 25 лет.</p><h3>Почему это меняет карьеру</h3><p>Typer меняет карьеру тем, что открывает путь к созданию удобных CLI-инструментов, которые автоматизируют рутину и повышают продуктивность.</p><p>С Typer можно быстро превращать свои Python-скрипты в надежные утилиты, которыми удобно пользоваться и другим разработчикам, и сотрудникам из других отделов. CLI-приложения часто становятся клеем инфраструктуры: они позволяют автоматизировать деплой, миграции БД, сбор данных, интеграцию с внешними API и локальную разработку.</p><p>Если вы <b>Data Scientist или ML-инженер</b>, Typer позволяет оборачивать пайплайны в CLI, которые легко запускать из Jenkins, Airflow или вручную. Если вы <b>DevOps или Backend-инженер</b>, можете создавать CLI для работы с инфраструктурой и сервисами без сложных зависимостей.</p><p>Кроме того, работа с Typer улучшает навык структурирования кода, понимание CLI, использования type hints и разработки инструментов, которые делают работу проще для других. А это, очевидно, ценится в любой команде и повышает востребованность специалиста.</p><h2>7. Rich</h2><p>Rich — библиотека Python для красивого форматирования и интерактивного отображения информации в терминале. С её помощью можно выводить цветные таблицы, маркдаун, прогресс-бары, подсвеченный синтаксис кода, деревья каталогов и логирование в понятной и привлекательной форме.</p><p>Rich создана для того, чтобы «оживить» консоль Python, сделать логи удобными для восприятия, а CLI-инструменты — профессионально выглядящими без лишних усилий. Это библиотека, которая улучшает и UX, и DX.</p><h3>Какие задачи решает</h3><p>Про красоту не забываем! Задачи следующие:</p><ul><li>Цветное и структурированное логирование, понятное при чтении логов в реальном времени.</li><li>Отображение прогресс-баров для долгих операций.</li><li>Вывод таблиц, деревьев каталогов, JSON прямо в терминале.</li><li>Подсветка синтаксиса кода для CLI-инструментов.</li><li>Создание CLI-интерфейсов, которые выглядят профессионально и современно.</li><li>Улучшение читаемости при отладке скриптов.</li></ul><p>С помощью Rich можно быстро сделать понятными даже сложные данные при отладке или демонстрации.</p><h3>Как пользоваться</h3><p>Установка Rich:</p><p>Для примера выведем таблицу с подсветкой в консоли:</p><p>В результате в терминале получится цветная таблица, которая выглядит понятно и презентабельно.</p><h3>Почему это меняет карьеру</h3><p>Rich — это библиотека, которая помогает быстро повысить качество любого CLI-инструмента или дев-опыт в команде. <b>Разработчик</b>, который использует Rich, делает свои инструменты удобными не только для себя, но и для коллег: логирование становится понятным, а отладка скриптов — наглядной.</p><p>Во многих стартапах и продвинутых командах важна скорость обратной связи при тестировании пайплайнов и автоматизаций, и Rich помогает выводить ключевую информацию максимально читаемо.</p><p>Кроме того, Rich позволяет быстро создавать CLI-интерфейсы, которые выглядят как продакшен-продукты, даже если это внутренние инструменты. Руководство будет радоваться и думать о вас как о крутом разрабе.</p><p>Для <b>дата-инженеров и разработчиков DevOps</b> Rich полезна при создании админ-утилит и при мониторинге пайплайнов, для <b>Python-разработчиков</b> — при создании библиотек и фреймворков с CLI.</p><h2>8. LangChain</h2><p>LangChain — фреймворк для создания приложений на базе LLM, например, GPT, Claude, Mistral, Gemini. Он позволяет строить цепочки обработки запросов, интегрировать LLM с данными и инструментами, добавлять память и управление состояниями, а также связывать работу модели с внешними API и базами знаний.</p><p>LangChain предоставляет удобный слой абстракции над вызовами LLM и ускоряет разработку чат-ботов, RAG-приложений, агентов с инструментами, систем анализа документов и других AI-сервисов.</p><h3>Какие задачи решает</h3><p>Список внушительный:</p><ul><li>Интеграция LLM в Python-приложения без необходимости писать тот самый клеевой код вручную.</li><li>Построение цепочек с последовательной обработкой сообщений, включая преобразования и вызовы внешних функций.</li><li>Добавление памяти в чат-боты для сохранения истории общения и контекста.</li><li>Использование агентов для динамического вызова инструментов (веб-поиск, базы данных, API).</li><li>Создание RAG-систем с интеграцией LLM и векторных БД.</li><li>Быстрая сборка прототипов LLM-приложений, которые можно развернуть в продакшен.</li></ul><h3>Как пользоваться</h3><p>Установка:</p><p>Создадим простую цепочку с чатом GPT:</p><p>Благодаря единым абстракциям, можно гибко комбинировать цепочки, память и вызов внешних инструментов, не усложняя код.</p><h3>Почему это меняет карьеру</h3><p>LangChain меняет карьеру, потому что открывает новый пласт Python-разработки в AI и LLM-инженерии, быстро превращая пользователя GPT в создателя полноценных AI-приложений. Вместо того чтобы писать хаотичный клеевой код, вы начинаете системно проектировать цепочки запросов, учитесь строить продуманные промпты и объединять их с инструментами, памятью и внешними API.</p><p>Работа с LangChain погружает в практическую LLM-инженерию: вы начинаете создавать RAG-приложения, которые умеют искать и анализировать данные перед генерацией ответа и строить агентов. Это востребовано в продуктах, где нужно подключать ИИ к базам знаний, автоматизировать задачи и разрабатывать интерактивные системы, которые реально используют модели в продакшене.</p><p>LangChain позволяет быстро собирать и запускать MVP AI-продуктов, что дает конкурентное преимущество при создании стартапов или внутренних сервисов. А ещё учит мыслить структурами и проектировать масштабируемую архитектуру LLM-приложений и видеть, как генеративный ИИ можно превратить в рабочий инструмент.</p><h2>9. SQLAlchemy</h2><p>SQLAlchemy — это мощная ORM и toolkit для работы с базами данных в Python, позволяющая писать SQL-запросы декларативно, создавать модели таблиц и управлять транзакциями в Python-коде без ручного написания SQL.</p><p>Библиотека даёт разработчику два уровня контроля:</p><ul><li>Core: низкоуровневая работа с SQL выражениями и соединениями;</li><li>ORM: высокоуровневая декларативная работа с моделями, классами и связями между таблицами.</li></ul><p>SQLAlchemy поддерживает PostgreSQL, MySQL, SQLite, Oracle и другие СУБД, давая единую абстракцию, без привязки к конкретному движку.</p><h3>Какие задачи решает</h3><p>Пул задач следующий:</p><ul><li>Описание таблиц в виде Python-классов и управление ими через сессии;</li><li>Создание, чтение, обновление и удаление данных;</li><li>Миграция SQL на декларативный стиль без потери гибкости;</li><li>Полный контроль над транзакциями и выполнением запросов;</li><li>Работа с асинхронными приложениями при создании FastAPI/Django-приложений;</li><li>Экранирование параметров, которое снижает вероятность SQL-инъекций и ошибок.</li></ul><h3>Как пользоваться</h3><p>Создадим минимальный пример для SQLite с таблицей пользователей:</p><p>Этот код создаёт базу example.db, таблицу users, добавляет туда одного пользователя и выводит всех пользователей в базе. При необходимости можно использовать SQLAlchemy Core для написания гибких запросов вручную, если нужно работать ближе к SQL.</p><h3>Почему это меняет карьеру</h3><p>SQLAlchemy меняет карьеру <b>Python-разработчика</b> тем, что даёт понимание системной работы с данными, архитектуры приложений и взаимодействия с реальными базами данных. Вы учитесь строить продуманные бэкенды, которые работают с транзакциями, миграциями, связями между таблицами и сложными выборками.</p><p>Знание SQLAlchemy открывает дорогу в мир API, микросервисов и продуктов, где требуется качественное управление данными и гибкая логика работы с БД. Работа с SQL теперь совсем не страшная.</p><h2>10. Seaborn</h2><p>Seaborn — библиотека для визуализации данных на Python, построенная поверх Matplotlib и упрощающая создание информативных и стильных графиков с минимальным количеством кода.</p><p>Она автоматически заботится о красивых стилях, цветах, разметке графиков, легендах и позволяет легко строить распределения, линейные графики, тепловые карты и другие визуализации.</p><p>Библиотека тесно интегрируется с Pandas DataFrame, позволяя использовать колонки данных напрямую для построения графиков, что делает её идеальной для EDA (разведочного анализа данных) и подготовки визуализаций для отчётов и презентаций.</p><h2>Какие задачи решает</h2><p>Визуализация безумно важна, особенно в контексте дата-аналитики. Seaborn отвечает за:</p><ul><li>Быстрое построение информативных графиков для анализа данных и поиска инсайтов;</li><li>Автоматическую обработку ошибок отображения и масштабирования, что экономит время;</li><li>Поддержку сложных визуализаций по типу ящиков с усами или тепловых карт без десятков строк кода;</li><li>Стилизацию графиков без ручных настроек Matplotlib;</li><li>Возможность добавлять статистические элементы (линию регрессии, KDE, распределение);</li><li>Интеграцию с Jupyter Notebook для интерактивного анализа данных.</li></ul><h3>Как пользоваться</h3><p>Допустим, у нас есть датасет с данными о чаевых:</p><p>В три строки мы получаем чистый и читаемый ящик с усами, показывающий, как счет за ужин распределяется по дням недели.</p><p>Для построения более сложных графиков можно использовать диаграмму рассеяния:</p><p>Тут мы добавляем цветовую кодировку по полу, чтобы увидеть зависимости между переменными.</p><h3>Почему это меняет карьеру</h3><p>Seaborn меняет карьеру, потому что даёт навык визуального анализа данных, что критично в современной аналитике и дата-инженерии. Умение быстро строить графики и видеть аномалии, распределения и взаимосвязи между переменными превращает работу с данными из слепого копания в числах в структурный анализ.</p><p>Использование Seaborn в Python-стеке помогает выделиться среди разработчиков, которые ограничиваются Pandas и текстовыми логами, ведь визуализация часто позволяет быстрее заметить закономерности и убедить команду или заказчика в правильности гипотезы.</p><p>Seaborn также учит пониманию данных через визуальные паттерны, что улучшает навыки построения моделей машинного обучения (так понятнее, какие признаки важны), и помогает создавать наглядные отчёты для продуктовых решений, где результат анализа нужно доносить до людей не из айти-индустрии.</p><p><i>А какими библиотеками пользуетесь вы? Делитесь в комментариях!</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Где в 2025 учат на продакта и проджекта в IT: лучшие курсы для начинающих</title>
      <link>https://tproger.ru/articles/gde-v-2025-uchat-na-prodakta-i-prodzhekta-v-it--luchwie-kursy-dlya-nachinayushhih</link>
      <comments>https://tproger.ru/articles/gde-v-2025-uchat-na-prodakta-i-prodzhekta-v-it--luchwie-kursy-dlya-nachinayushhih?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/gde-v-2025-uchat-na-prodakta-i-prodzhekta-v-it--luchwie-kursy-dlya-nachinayushhih</guid>
      <description><![CDATA[<p>Где учиться на продакт- и проджект-менеджера в 2025 году? В статье — проверенные курсы от Softline, TOP Academy, Нетологии и других школ с реальными отзывами, ценами и гарантией трудоустройства. Подробный разбор программ, форматов обучения и карьерных перспектив для начинающих. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/gde-v-2025-uchat-na-prodakta-i-prodzhekta-v-it--luchwie-kursy-dlya-nachinayushhih">Где в 2025 учат на продакта и проджекта в IT: лучшие курсы для начинающих</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Ретро]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Agile]]></category>
      <category><![CDATA[Управление проектами]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Стажировка]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Яндекс]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Стартапы]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[5g]]></category>
      <category><![CDATA[Сбер]]></category>
      <category><![CDATA[Waterfall]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Figma]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Вебинар]]></category>
      <category><![CDATA[VPS]]></category>
      <category><![CDATA[Обучающие курсы]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 14 Jul 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Современная IT-индустрия нуждается не только в технических специалистах, но и в тех, кто умеет превращать идеи в работающие продукты. Продакт- и проджект-менеджеры стали главными фигурами в этом процессе. Первые решают, что и зачем создавать, задача вторых — как и когда это сделать. В IT-компаниях оба специалиста часто работают в паре, дополняя друг друга.</p><p>Спрос на таких специалистов продолжает расти. Средняя зарплата проджект-менеджера в России в 2025 году составляет около 147 000 руб., при этом сеньоры могут получать до 240 тыс. Для продактов цифры еще выше — опытные специалисты в крупных IT-компаниях зарабатывают от 300 000 руб.</p><p>Обучение этим профессиям стало доступнее благодаря онлайн-курсам. Мы проанализировали десятки программ и выбрали семь лучших, которые действительно дают нужные навыки и помогают начать карьеру.</p><h2>1. Академия Softline: «Управление проектами в области ИТ»</h2><p>Академия Softline предлагает<a href="https://academyit.ru/courses/pmit/"> актуальный курс</a> в рамках обширной обучающей программы для повышения квалификации. Программа разработана практиками из крупных IT-компаний и охватывает все аспекты работы с проектом.</p><p>Курс длится 40 академических часов и проводится полностью в онлайн-формате. Программа сочетает теоретические модули с интенсивной практической отработкой навыков через индивидуальные и групповые упражнения.</p><p>Каждый участник работает над реальным проектом, применяя инструменты управления на всех этапах — от запуска до завершения. Наставники-практики сопровождают студентов на протяжении всего обучения, помогая разобрать нюансы применения методик в реальных ИТ-проектах.</p><h3>Уникальность программы</h3><p>Курс отличается синтезом мировых стандартов: PMBoK и ITIL интегрированы с гибкими методологиями (Agile, Scrum, Kanban). Такой подход учит адаптировать инструменты под специфику конкретных задач, а не просто следовать шаблонам.</p><p>Акцент на ИТ-проекты делает программу полезной для компаний, внедряющих цифровые продукты или модернизирующих инфраструктуру, поскольку здесь разбираются кейсы по управлению релизами ПО и масштабированию облачных решений.</p><p>Преимущества:</p><ul><li><b>практическая направленность:</b> 70% времени посвящено работе с реальными кейсами;</li><li><b>гибкие методики для ИТ-среды: </b>от классического Waterfall до гибридных моделей;</li><li><b>поддержка наставников</b> с опытом в Сбере, Яндексе и других топовых компаниях.</li></ul><h3>Что получают выпускники</h3><p>После защиты итогового проекта участники получают удостоверение повышении квалификации государственного образца и готовое портфолио с реализованным кейсом. Карьерный центр помогает с трудоустройством: студенты 2024 года получили офферы от партнеров (Сбер, МТС, VK) в течение 3 месяцев после завершения курса.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-07-11/a5b98557-d4e3-4ded-a93d-f5138b0b9388.png" alt="" /></figure><h3>Стоимость и условия</h3><p>Полная цена программы — 80 000 рублей. Доступна рассрочка на 4 месяца (20 000 руб./мес). Для корпоративных клиентов действуют скидки до 15% при обучении групп от 3 человек.</p><h2>2. Компьютерная Академия ТОП: «Проджект-менеджер в IT»</h2><p>Компьютерная Академия ТОП уже несколько лет готовит сильных проджектов для IT-индустрии. <a href="https://msk.top-academy.ru/education/project-management?utm_source=article&amp;utm_medium=paidorganic&amp;utm_campaign=adults&amp;utm_content=projectmanagement&amp;utm_term=tproger">Курс</a> подходит тем, кто хочет научиться управлять проектами в условиях неопределенности — именно с этим сталкивается большинство новичков.</p><p>Курс длится 10 месяцев и доступен в двух форматах: очном (в 200+ филиалах по России) или онлайн с живыми вебинарами. В отличие от многих программ, здесь нет записанных уроков — все занятия проходят в режиме реального времени с преподавателями-практиками. Каждую группу курирует действующий проджект из IT-индустрии, который дает каждому участнику обратную связь и разбирает ошибки на практике.</p><h3>Уникальность программы</h3><p>Живое обучение в малых группах (до 15 человек), где студенты отрабатывают навыки на 12 реальных кейсах — от запуска мобильных приложений до управления релизами SaaS. Например, один из проектов имитирует работу с заказчиком из банковского сектора, где нужно согласовать требования и сроки под жесткими ограничениями бюджета.</p><p>Программа обновляется каждые 6 месяцев с учетом запросов работодателей. В 2025 году добавлен модуль по гибридным методологиям (Agile-Waterfall) для госпроектов и FinTech.</p><p>Помимо Jira и Trello, студенты осваивают специализированные решения для IT-команд — Axure RP для прототипирования и MS Project для сложных диаграмм Ганта.</p><p>Преимущества:</p><ul><li>стажировка у партнеров (VK, Сбер, Тинькофф) после успешной защиты дипломного проекта;</li><li>доступ к закрытому чату выпускников с вакансиями от 500+ компаний;</li><li>сертификация PMI CAPM® включена в стоимость.</li></ul><h3>Что получают выпускники</h3><p>По данным академии, до 80%студентов трудоустраиваются в течение нескольких месяцев после выпуска.</p><p>В портфолио входят:</p><ul><li>4 завершенных учебных проекта с метриками эффективности (например, сокращение сроков на 15-20% в симуляциях);</li><li>готовые артефакты: устав проекта, реестр рисков, отчеты по Scrum-спринтам;</li><li>государственный диплом о профессиональной переподготовке и международный сертификат.</li></ul><h3>Стоимость и условия</h3><ul><li>онлайн: 4 590 руб./мес (рассрочка на 10 месяцев);</li><li>очно: 17 910 руб./мес (скидка 15% при оплате за год);</li><li>корпоративное обучение: индивидуальный расчет для групп от 5 человек.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-07-10/2d2b29dc-b845-491b-a8f2-48d3aeb2fa15.png" alt="" /></figure><h2>3. ProductStar: «Профессия Продакт-менеджер»</h2><p><a href="https://new.productstar.ru/product-manager">Курс</a> от ProductStar подойдет как новичкам, так и тем, кто уже работает в IT, но хочет перейти в продукт.</p><p>Особенности программы:</p><ul><li>8 месяцев обучения с упором на практику;</li><li>3 специализации на выбор: B2C, B2B или стартапы;</li><li>работа с Figma, Miro, Amplitude, SQL;</li><li>кейсы от партнеров: Яндекс, МТС;</li><li>подготовка к реальным собеседованиям.</li></ul><p>Один из плюсов ProductStar — сообщество. Студенты получают доступ к закрытому чату, где общаются выпускники и преподаватели. Там можно получить совет, найти напарника для проекта или даже предложение о работе.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-07-10/3ed91164-9cbb-458e-97ba-7ddc83186a2b.png" alt="" /></figure><p>Каждый модуль курса завершается защитой проекта перед экспертами из индустрии. Это не только возможность получить обратную связь, но и шанс заявить о себе потенциальным работодателям.</p><h2>4. Академия Softline: «Управление проектами по разработке программных продуктов»</h2><p><a href="https://academyit.ru/courses/pp_project/">Курс от Академии Softline</a> создан для тех, кто хочет научиться выводить проекты на финишную прямую без переработок и конфликтов.</p><h3>Формат обучения и особенности курса</h3><p>Курс длится 252 академических часа и реализуется в мультиформатном режиме:</p><ul><li><b>Живые вебинары</b> с разбором кейсов и домашних заданий от экспертов-практиков.</li><li><b>Самостоятельная работа</b> на обучающей платформе с доступом к записям и шаблонам документов.</li><li><b>80% практики.</b> Симуляции переговоров с заказчиками, разработка проектной документации (устав проекта, реестр рисков, отчеты), защита итогового проекта перед комиссией с обратной связью.</li></ul><p>У курса Академии Softline гибкий подход к методологиям управления проектами. В отличие от стандартных программ, здесь учат не просто следовать шаблонам Waterfall или Agile, а адаптировать их под специфику российского IT-рынка.</p><p>Особое внимание уделяется работе в сложных условиях — например, управлению изменениями требований, частыми релизами и MVP. Студенты разбирают полный цикл разработки ПО: от архитектурных решений до интеграции с устаревшими системами (legacy), что особенно актуально для разработки новых программных продуктов.</p><p>Практическая направленность — еще одна особенность программы. Все теоретические знания сразу применяются в реальных кейсах от партнеров (Сбер, VK, МТС), включая разработку мобильных приложений и SaaS-платформ. Участники осваивают профессиональные инструменты: Jira для трекинга задач, MS Project для построения сложных диаграмм Ганта и Confluence для ведения проектной документации.</p><p>Преподаватели курса — действующие проджект-менеджеры с опытом в международных компаниях. Они делают акцент на технических аспектах управления: понимании жизненного цикла разработки ПО (SDLC), базовых принципах DevOps и особенностях работы с API. Это позволяет выпускникам говорить на одном языке с разработчиками и грамотно ставить технические задачи.</p><h3>Результаты выпускников</h3><p>По окончании обучения студенты получают диплом о профессиональной переподготовке государственного образца и готовое портфолио. В него входят: устав проекта для финтех-стартапа, реестр рисков с mitigation-стратегиями и отчеты по Scrum-спринтам с метриками эффективности.</p><p>Выпускники также получают доступ к вакансиям партнеров через карьерный центр Softline, что существенно повышает шансы на трудоустройство.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-07-11/df95d413-6573-46e2-b530-55088d550a5c.png" alt="" /></figure><h3>Стоимость и условия</h3><ul><li>полная цена: 156 000 руб.;</li><li>рассрочка: 13 000 руб./мес × 12 месяцев;</li><li>корпоративное обучение: индивидуальный расчет для групп от 5 человек.</li></ul><h2>5. Нетология: «Продуктовый менеджер»</h2><p><a href="https://netology.ru/programs/profession-product#/">Курс «Продуктовый менеджер»</a> от Нетологии предназначен для тех, кто хочет освоить управление продуктом на всех этапах его жизненного цикла — от исследования рынка до масштабирования. Программа подходит как новичкам, так и специалистам, которые хотят углубить свои знания в продуктовой аналитике и стратегическом планировании.</p><h3>Формат обучения и особенности</h3><p>Обучение длится 8 месяцев и включает 104 урока в формате видеолекций, практических заданий и живых вебинаров. Студенты работают над собственным продуктом, проходя все стадии разработки: от формирования гипотез до запуска MVP и анализа первых метрик. Каждый модуль завершается практическим заданием, которое проверяют кураторы — действующие продакт-менеджеры из Mail.ru Group, Avito и других компаний.</p><p>Основные темы:</p><ul><li>Анализ рынка и целевой аудитории — методы CustDev, построение CJM (Customer Journey Map), выявление Jobs To Be Done (JTBD).</li><li>Продуктовая аналитика — работа с метриками AARRR и HEART, настройка дашбордов, проведение A/B-тестов.</li><li>Финансовое моделирование — расчет юнит-экономики, стратегии монетизации, оценка рентабельности продукта.</li><li>Управление продуктом — создание роадмапа, приоритизация фич, работа с бэклогом и командой разработки.</li></ul><p>Что отличает курс:</p><ul><li>Практическая направленность. 70% времени посвящено работе с реальными кейсами, включая задачи от партнеров Нетологии.</li><li>Карьерный модуль. Помощь в составлении резюме, подготовка к собеседованиям, разбор переговоров о зарплате.</li><li>Гибкий график. Возможность изучать материалы в удобное время, совмещая обучение с работой.</li></ul><h3>Что получают выпускники</h3><p>По окончании курса выпускники получают диплом о профессиональной переподготовке государственного образца, подтверждающий квалификацию в области управления проектами.</p><p>В портфолио добавляются реальные кейсы — от проработанных гипотез и расчетов метрик до готовых дорожных карт продуктов, что существенно повышает шансы при трудоустройстве.</p><p>Карьерная поддержка включает доступ к вакансиям компаний-партнеров (VK, Тинькофф), персональные консультации по составлению резюме и подготовку к собеседованиям с HR-специалистами. Для лучших студентов предусмотрены стажировки с возможностью дальнейшего трудоустройства.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-07-10/79ec5a5a-0f72-440a-ab3e-914f73af1fa2.png" alt="" /></figure><h3>Стоимость</h3><p>Полная цена: 158 160 руб. (доступна рассрочка — 4 393 руб./мес). В рамках корпоративного обучения площадка предлагает индивидуальный расчет для групп.</p><h2>6. SkillFactory: «Проджект-менеджер в IT»</h2><p>SkillFactory предлагает подробный <a href="https://skillfactory.ru/project-manager">курс по управлению проектами</a>. За 9 месяцев студенты полностью погружаются в профессию и выходят готовыми к реальным задачам.</p><p>Курс SkillFactory предназначен для тех, кто хочет освоить управление IT-проектами с нуля или систематизировать имеющийся опыт. Программа сочетает теорию с практикой: студенты изучают методологии (Agile, Scrum, Waterfall) и сразу применяют их в реальных кейсах, таких как разработка мобильного приложения или внедрение CRM-системы.</p><h3>Формат обучения</h3><ul><li>Онлайн-вебинары с разбором кейсов от преподавателей-практиков (например, Павла Максимова, который руководил запуском eSIM в России).</li><li>3 проекта в портфолио: планирование приложения по Agile, внедрение софта для call-центра по Waterfall, дипломная работа — сервис для видео-найма персонала.</li><li>Поддержка наставников, включая персональные консультации и проверку заданий.</li></ul><h3>Ключевые навыки</h3><p>Курс фокусируется на практических инструментах:</p><ul><li>работа с Jira, Trello, MS Project для планирования;</li><li>управление бюджетом и рисками;</li><li>проведение ретроспектив и дэйли-митингов (коротких ежедневных собраний команды);</li><li>подготовка документации (уставы проектов, реестры рисков).</li></ul><h3>Трудоустройство</h3><p>Выпускники получают доступ к вакансиям партнеров SkillFactory и помощь в составлении резюме. По данным портала hh.ru, средняя зарплата junior-проджекта после курса составляет 95 000–120 000 руб.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-07-10/cf5081f8-58d2-473e-91df-b6e4d2e3608e.png" alt="" /></figure><h3>Стоимость</h3><p>Полная цена: 87 000 руб. (доступна рассрочка — 7 250 руб./мес). Включен бонусный курс по нейросетям.</p><h2>7. GoPractice: «Профессия: Продакт-менеджер»</h2><p><a href="https://gopractice.ru/switchers/">Программа</a> длится 11 месяцев и предназначена для специалистов, планирующих переход в продакт-менеджмент из смежных ролей (аналитики, маркетологи, проджекты).</p><p>Обучение включает пять ступеней:</p><ol><li>Анализ траекторий перехода в профессию.</li><li>Освоение основ продакт-менеджмента через кейсы.</li><li>Работа с симулятором управления продуктом.</li><li>Дипломный проект.</li><li>Подготовка к трудоустройству.</li></ol><p>Занятия проходят онлайн с гибким графиком. Каждую группу курируют менторы из компаний (Яндекс, Avito, Ozon), которые проводят приветственные звонки и консультируют по заданиям.</p><h3>Программа</h3><p>Курс охватывает:</p><ul><li>построение продуктовой стратегии;</li><li>проведение качественных и количественных исследований;</li><li>управление бэклогом и приоритизация фич;</li><li>расчет юнит-экономики;</li><li>взаимодействие со стейкхолдерами.</li></ul><p>Практическая часть включает три кейса и дипломный проект, которые формируют портфолио. Для выполнения заданий используются шаблоны и фреймворки, применяемые в MAANG-компаниях.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-07-10/6b1624c4-1b29-41f6-98a4-e80ad96b5574.png" alt="" /></figure><h3>Результаты</h3><p>По завершении программы выпускники получают сертификат GoPractice, подтверждающий освоение ключевых навыков продакт-менеджера. В портфолио добавляются три практических кейса и дипломный проект, выполненные на основе реальных бизнес-задач. Дополнительно предоставляется доступ к закрытому чату выпускников, где можно поддерживать профессиональные связи и обсуждать актуальные вакансии.</p><h3>Стоимость</h3><p>Полная цена: 219 900 руб., рассрочка: 18 325 руб./мес × 12 мес.</p><h2>Как выбрать курс и начать карьеру</h2><p>Выбор программы зависит от ваших целей и стартовых условий. Тем, кто только начинает, лучше выбрать курсы с упором на практику и помощью в трудоустройстве. Опытным специалистам подойдут программы с углублением в конкретные области — аналитику, управление командами или работу с данными.</p><p>Важно помнить, что ни один курс не даст всего сразу. После обучения придется доучиваться на практике, однако хорошая программа обеспечит базу, которая ускорит этот процесс. И главное — доступ к сообществу профессионалов, которое поможет на старте карьеры.</p>]]></content:encoded>
    </item>
    <item>
      <title>PostgreSQL: что нужно знать о счётчике транзакций</title>
      <link>https://tproger.ru/articles/postgresql--chto-nuzhno-znat-o-schyotchike-tranzakcij</link>
      <comments>https://tproger.ru/articles/postgresql--chto-nuzhno-znat-o-schyotchike-tranzakcij?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Postgres Professional]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/postgresql--chto-nuzhno-znat-o-schyotchike-tranzakcij</guid>
      <description><![CDATA[<p>Статья погружает в сложности счетчика транзакций PostgreSQL и MVCC в условиях высокой нагрузки. Разберитесь, почему 32-битные xid создают проблемы и как 64-битные идентификаторы транзакций решают их.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/postgresql--chto-nuzhno-znat-o-schyotchike-tranzakcij">PostgreSQL: что нужно знать о счётчике транзакций</a>»</p>]]></description>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 13 Jul 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Многие годы считалось, что PostgreSQL не подходит для систем с высокой нагрузкой. Но на практике всё чаще встречаются ситуации, когда даже крупные компании выбирают именно эту СУБД. В результате, всё больше внимания уделяется вопросам производительности и масштабируемости PostgreSQL. Один из таких вопросов — счётчик транзакций, о котором мы сегодня и поговорим.</p><h2>Что такое счётчик транзакций и зачем он нужен?</h2><p>PostgreSQL использует механизм многоверсионности (MVCC) благодаря которому читающие транзакции не блокируют пишущие, и наоборот. Каждая транзакция работает со своей версией данных, а доступ регулируется правилами видимости.</p><p>Чтобы понять, как функционирует MVCC, представьте, что у каждого пользователя базы есть свой «моментальный снимок» данных. Когда вы начинаете работать, вы видите состояние данных на этот конкретный момент времени. Изменения, которые делают другие пользователи, не влияют на ваш снимок, пока вы не завершите свою операцию и не начнете новую. Это позволяет нескольким пользователям одновременно читать и изменять данные, не мешая друг другу.</p><p>MVCC в PostgreSQL работает похожим образом:</p><ul><li>Каждая транзакция — это как отдельный пользователь, работающий с документом. Транзакция видит «снимок» базы данных на момент своего начала.</li><li>Когда транзакция изменяет данные, она не перезаписывает старые. Вместо этого создаётся новая версия изменённых строк.</li></ul><p>Каждая версия строки имеет специальные метки:</p><ul><li>xmin — идентификатор транзакции, которая создала версию.</li><li>xmax — идентификатор транзакции, которая удалила (или обновила) версию. Если строка ещё не удалена, xmax пустой.</li></ul><p>Когда транзакция читает данные, PostgreSQL определяет, какую версию строки ей показывать, на основе правил видимости:</p><ul><li>транзакция видит строки, созданные до её начала (xmin меньше её идентификатора), и не помеченные как удалённые (xmax пустой или больше её идентификатора);</li><li>транзакция видит строки, созданные ею самой;</li><li>транзакция не видит строки, созданные транзакциями, которые начались позже неё (xmin больше её идентификатора).</li></ul><p>Пример:</p><p>Допустим, у нас есть таблица users с данными:</p><p>1. Транзакция 1 (xid=100) начинается и читает таблицу  Она видит обе строки, потому что они были созданы до её начала, и xmax у них пустой.</p><p>2. Транзакция 2 (xid=105) начинается и обновляет возраст Alice на 31. PostgreSQL не перезаписывает строку Alice, а создаёт новую версию:</p><p>3. Обратите внимание, что у старой версии Alice xmax теперь равен 105 (идентификатор транзакции 2), а у новой версии xmin равен 105.</p><p>4. Транзакция 1 снова читает таблицу.  Она по-прежнему видит старую версию Alice (возраст 30), потому что новая версия была создана транзакцией, которая началась позже (105 &gt; 100), а старая помечена как удалённая транзакцией с большим номером.</p><p>5. Транзакция 2 фиксируется.</p><p>6. Транзакция 3 (xid=110) начинается и читает таблицу  Теперь она видит новую версию Alice (возраст 31), потому что транзакция 2, которая её создала, уже зафиксирована, и её xid меньше чем у транзакции 3.</p><p>Важно: номера транзакций (xid) не стоит сравнивать как обычные числа («больше» или «меньше»). Корректнее говорить «старше» или «младше». Дело в том, что номера транзакций сравниваются по модулю 232, образуя кольцо. Транзакции, отстающие от текущей на 231 назад, считаются «старше» («в прошлом»), а на 231 вперёд — «младше» («в будущем»).</p><p>Представьте себе круг:</p><ul><li>текущая транзакция — это точка на круге;</li><li>«прошлые» транзакции — это точки слева от текущей, если двигаться против часовой стрелки;</li><li>«будущие» транзакции — точки справа.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/115310/2025-07-04/f547fb58-a54c-404c-8852-6d91fd4a8aed.png" alt="" /></figure><p>Каждая запись в базе данных имеет служебные поля xmin и xmax. В xmin записывается номер транзакции, создавшей запись, а в xmax — номер транзакции, удалившей её. Учетом этих номеров и занимается счетчик транзакций.</p><h2>Как развивался счётчик транзакций</h2><p>До версии PostgreSQL 8.2 при достижении максимального значения счётчика транзакций (примерно 4 миллиарда) PostgreSQL просто «падал». Чтобы продолжить работу, нужно было сделать дамп базы данных и создать её заново.</p><p>В версии 8.2 появился механизм циклического перезапуска счётчика. Для этого в фоновом режиме запускается процесс очистки (VACUUM).</p><p>Как это работает:</p><ol><li><b>«Заморозка» старых транзакций</b>: Когда на VACUUM передаётся значение, что счётчик транзакций скоро переполнится, он начинает помечать старые транзакции специальным идентификатором FrozenTransactionId. По сути, VACUUM говорит: «Эти транзакции настолько старые, что мы считаем их замороженными. Мы всегда будем считать их старше любых других транзакций.»</li><li><b>Счётчик эпох</b>: Чтобы PostgreSQL знал, сколько раз счётчик уже «перезапускался», используется счётчик эпох. Каждый раз, когда счётчик транзакций доходит до конца и начинает заново, счётчик эпох увеличивается на единицу.</li><li><b>Циклический перезапуск:</b> После того как VACUUM «заморозит» старые транзакции, счётчик транзакций может безопасно начать считать заново с трёх. PostgreSQL теперь знает, что все транзакции с идентификатором FrozenTransactionId старше любых других транзакций, даже если их номера меньше.</li></ol><p>Это решило проблему «падения», но возникла новая: если VACUUM не успевает отработать вовремя, сервер может остановиться и потребовать запуска в монопольном режиме для очистки, что ведёт к простою.</p><h3>В чём же проблема?</h3><p>Сам по себе механизм счётчика транзакций работает хорошо. Проблема в том, что он создавался, когда 32-битное число (более 4 миллиардов) казалось огромным. Сейчас же, в системах с высокой нагрузкой (ретейл, крупные заводы, госучреждения), счётчик может оборачиваться раз в сутки.</p><p>Дополнительные сложности:</p><p>Среди служебных данных записи есть поле флагов. Для старых записей нужно периодически запускать VACUUM FREEZE, который помечает их как «замороженные» (FrozenTransactionId).</p><p>Для стабильной работы нужно, чтобы:</p><ul><li>разница между номером текущей транзакции и номером самой старой записи не превышала 2^32;</li><li>VACUUM FREEZE выполнялся до нарушения первого условия.</li></ul><p>В реальном мире это сложно:</p><ul><li>«долгие» транзакции мешают VACUUM FREEZE;</li><li>сложно определить, когда транзакция «долгая», а когда «зависшая»;</li><li>непонятно, когда бить тревогу из-за исчерпания идентификаторов;</li><li>администратор БД несёт ответственность за потери бизнеса из-за своих действий.</li></ul><p>Если вы можете остановить кластер БД, запустить его в монопольном режиме и подождать несколько часов, эта проблема вас не касается. Но в системах с высокими требованиями к доступности простой — недопустим.</p><p>Отдельно стоит упомянуть базы данных, в которые данные только добавляются (insert-only). В них VACUUM всё равно запускается для «заморозки» старых записей.</p><h2>Решение: 64-битные идентификаторы транзакций</h2><p>Казалось бы, простое решение — увеличить размер счётчика до 64 бит. Но это сложно:</p><ul><li>весь код PostgreSQL ожидает «видеть» 32-битные числа;</li><li>в каждом кортеже (записи) хранятся xmin и xmax. Увеличение их размера с 8 до 16 байт значительно увеличит размер базы.</li></ul><p>Мы в Postgres Professional разработали реализацию 64-битных идентификаторов транзакций (xid), увеличив их количество до 18 446 744 073 709 551 615 (264). Это решение используется во многих форках PostgreSQL. Проблема переполнения счётчика становится гипотетической (при высокой нагрузке 64-битный счётчик исчерпается примерно через 400 лет).</p><p>Патч с реализацией был предложен сообществу PostgreSQL, но пока не принят из-за его сложности. Однако многие разработчики форков PostgreSQL уже заявили о поддержке 64-битных xid в своих дистрибутивах.</p><p>Цель Postgres Professional  — не продвигать свой вариант как единственно верный, а привлечь внимание к проблеме и стимулировать сообщество к поиску оптимального решения. Первая часть удалась: идея получила внимание. Но внедрение таких изменений — долгий процесс. Рост нагрузок на СУБД во всём мире показывает важность этой проблемы.</p><p>Мы надеемся, что PostgreSQL сможет адаптироваться к растущим нагрузкам и укрепить свои позиции на рынке.</p>]]></content:encoded>
    </item>
    <item>
      <title>Что по экологии? Сколько углеродного следа оставляет ваш код</title>
      <link>https://tproger.ru/articles/chto-po-ekologii--skolko-uglerodnogo-sleda-ostavlyaet-vaw-kod</link>
      <comments>https://tproger.ru/articles/chto-po-ekologii--skolko-uglerodnogo-sleda-ostavlyaet-vaw-kod?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-po-ekologii--skolko-uglerodnogo-sleda-ostavlyaet-vaw-kod</guid>
      <description><![CDATA[<p>Узнайте, сколько CO₂ генерирует ваш код в 2025 году и как снизить углеродный след в IT. Практические советы по оптимизации архитектуры, выбору «зеленых» технологий и реальные кейсы компаний. Экологичное программирование — новый тренд для разработчиков и бизнеса.
</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-po-ekologii--skolko-uglerodnogo-sleda-ostavlyaet-vaw-kod">Что по экологии? Сколько углеродного следа оставляет ваш код</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Языки программирования]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Конференции]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Amazon]]></category>
      <category><![CDATA[IBM]]></category>
      <category><![CDATA[Cloudflare]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[NVIDIA]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Стартапы]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Сбер]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 10 Jul 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В 2025 году IT-индустрия потребляет больше энергии, чем крупная европейская страна  в 2010. <a href="https://www.iea.org/">По данным IEA</a> (International Energy Agency), дата-центры и телекоммуникационные сети уже отвечают за 3,7% глобальных выбросов CO₂ — это больше, чем производит авиация.</p><p>Казалось бы, код — это просто текст. Но каждый запрос к API, каждая компиляция и даже холостой цикл требуют энергии. Например, обучение GPT-4 в 2023 году «съело» столько же электричества, сколько 120 домохозяйств за год. А теперь представьте, что таких моделей тысячи, а серверов — миллионы.</p><p>Почему это важно? Во-первых, <a href="https://digital-strategy.ec.europa.eu/">регуляторы ужесточают требования</a>: в ЕС с 2025 года IT-компании обязаны раскрывать углеродный след своих продуктов. Во-вторых, инвесторы все чаще смотрят на ESG-рейтинги — показатели экологического и ответственного производства. В-третьих, оптимизация кода снижает затраты на инфраструктуру.</p><p>Эта статья — не манифест экоактивистов, а руководство для разработчиков, архитекторов и технических директоров компаний (СТО), которые стремятся более эффективные и экологичные проекты.</p><h2>Углеродный след кода: что скрывается за строчками</h2><p>Программное обеспечение — не виртуальный конструктор. Каждая операция требует электричества, а серверы, на которых работает код, часто питаются от невозобновимых источников энергии — например, угля и газа.</p><h3>Откуда берутся выбросы</h3><p>Когда мы говорим об углеродном следе ПО, важно понимать: код не существует в вакууме. Каждая строка, каждый запрос и каждая операция требуют физических ресурсов — электричества, серверного оборудования, систем охлаждения. В 2025 году эта цепочка стала еще сложнее из-за взрывного роста облачных вычислений и ИИ.</p><p>Прямые выбросы — это энергия, которую потребляют серверы при выполнении вашего кода. Например, один средний веб-сервер на AWS EC2 (тип t3.large) в год вырабатывает около 400 кг CO₂ — как небольшой автомобиль, проехавший 2000 км. При этом нагрузка на серверы постоянно растет: с 2020 по 2025 год энергопотребление дата-центров увеличилось на 35%.</p><p>Косвенные выбросы часто упускают из виду. Производство серверного оборудования — процесс крайне энергоемкий. Для создания одной только микросхемы памяти DDR5 требуется около 200 кВт⋅ч энергии — столько же, сколько средний холодильник потребляет за год. А после выхода оборудования из строя лишь 20% компонентов перерабатывается должным образом (<a href="https://globalewaste.org/">Global E-Waste Monitor 2024</a>).</p><p>Системы охлаждения — еще один скрытый источник выбросов. Современные дата-центры работают 24/7, и даже с использованием жидкостного охлаждения на поддержание температуры уходит до 40% всей потребляемой энергии. В жарких странах, ОАЭ или Сингапуре, этот показатель может достигать 50%.</p><p>Яркий пример — крупные языковые модели. Если в 2023 году обучение GPT-4 потребовало ~10 ГВт⋅ч (эквивалент годового потребления 120 домохозяйств), то к 2025 году из-за увеличения размеров моделей этот показатель вырос в 1,5 раза. Один запрос к такому ИИ теперь генерирует около 2 г CO₂ — как если бы вы проехали 10 метров на бензиновом автомобиле.</p><p>Но проблема не только в ИИ. Обычное веб-приложение с посещаемостью 100 000 пользователей в месяц может производить до 1 тонны CO₂ в год — и это без учета мобильных клиентов и API. При этом <a href="https://www.webpagetest.org/eco/">30% этой нагрузки приходится на неоптимизированный фронтенд</a>: тяжелые изображения, избыточные JavaScript-библиотеки и частые запросы к серверу.</p><p>Ситуацию усугубляет географический фактор. Дата-центр в Норвегии, где 98% энергии поступает от ГЭС, будет «чище», чем такой же центр в Польше, где угольные электростанции дают 70% энергии. <a href="https://app.electricitymaps.com/">Разница</a> в углеродном следе может быть 20-кратной для идентичных операций.</p><p>При этом стандарты измерения все еще остаются разрозненными. PUE (Power Usage Effectiveness), который используют Google и Microsoft, учитывает только эффективность инфраструктуры, но не источник энергии. Новый стандарт CUE (Carbon Usage Effectiveness), разработанный в 2024 году, уже включает эти данные, но его поддерживают менее 30% провайдеров.</p><h2>Где код тратит энергию впустую</h2><p>Некоторые части систем особенно вредны для экологии. Главные «пожиратели» ресурсов:</p><ul><li>Неоптимизированные алгоритмы. Сортировка пузырьком (O(n²)) на большом массиве данных может потреблять в 100 раз больше энергии, чем быстрая сортировка (O(n log n)).</li><li>Микросервисный хаос. Архитектура из сотен микросервисов увеличивает нагрузку на сеть. Каждый вызов API между сервисами — это дополнительные 0,5–1 Вт⋅ч.</li><li>Облачные провайдеры. Не все одинаково зеленые. AWS и Google используют 60–70% ВИЭ (возобновляемых источников энергии), но в Азии и Африке их дата-центры часто работают на угле.</li></ul><h3>Как измерить углеродный след</h3><p>В 2025 году появились инструменты, которые помогают оценить влияние кода:</p><ul><li>Cloud Carbon Footprint — анализирует выбросы AWS, GCP и Azure.</li><li>Scaphandre — мониторит энергопотребление серверов в реальном времени.</li><li>Greenframe.io — симулирует нагрузку на веб-приложение и считает CO₂.</li></ul><p>Климатические инициативы в IT больше не просто красивые слова в корпоративных отчетах. В 2025 году за неэффективный код можно получить не только порицание сообщества, но и вполне реальный штраф.</p><p>Европейский союз уже ввел санкции против пяти крупных SaaS-компаний за превышение углеродных квот, а Amazon Web Services выплатила 2,7 млн евро штрафа за неоптимизированные алгоритмы в своих сервисах.</p><h2>Как изменились подходы к разработке</h2><p>Эти тренды нацелены на долгосрочное действие и в перспективе должны полностью изменить текущую концепцию в разработке.</p><h3>Экологичный DevOps — новая реальность</h3><p>Современные системы автоматического масштабирования стали умнее. Kubernetes Horizontal Pod Autoscaler теперь учитывает не только нагрузку на CPU, но и текущий углеродный след дата-центра. Если в регионе пиковое потребление энергии и работают угольные электростанции, система сознательно ограничивает масштабирование.</p><p><a href="https://cloud.google.com/blog">Технология, разработанная Google</a> в партнерстве с WattTime, уже снижает выбросы CO₂ на 27-33% по сравнению с традиционным подходом.</p><p>CI/CD-цепочки тоже стали «зеленее». Вместо запуска полного набора тестов при каждом коммите, современные системы определяют, какие именно модули затронуты изменениями.</p><p><a href="https://carbonrunner.io/features/github-action-runners">GitHub Actions представил Carbon-Aware Runner</a>, который планирует выполнение задач на время максимальной доступности возобновляемой энергии в регионе. По данным Microsoft, это сокращает углеродный след тестирования на 40%.</p><h3>Языки программирования: война за эффективность</h3><p>Rust продолжает набирать популярность не только из-за безопасности, но и благодаря энергоэффективности. Тесты Benchmarks Game показывают, что один и тот же алгоритм обработки данных на Rust потребляет на 38-42% меньше энергии, чем на Python. В 2025 году Rust вошел в топ-5 языков для enterprise-решений, вытеснив Java в 17% крупных проектов.</p><p>Но настоящим открытием стал <a href="https://ziglang.org/documentation/master/">Zig </a>— язык, который сочетает производительность C с простотой синтаксиса. Его компилятор потребляет в 3 раза меньше ресурсов, чем LLVM-бэкенд Rust, что делает его идеальным выбором для встраиваемых систем.</p><h3>ИИ на грани: когда меньше значит лучше</h3><p>TinyML-революция набирает обороты. Современные нейросети для микроконтроллеров занимают менее 256 КБ памяти, но справляются с задачами, которые раньше требовали облачных вычислений.</p><p>Например, новые датчики Nest анализируют звук прямо на устройстве, определяя не только дым, но и тип возгорания. Это экономит до 150 МБ трафика в месяц на одно устройство.</p><p>На фронте больших языковых моделей тоже произошли изменения. Meta* выпустила LLaMA-3 Nano — модель с 500 млн параметров, которая работает на смартфоне и по качеству ответов не уступает GPT-3.5. Ее углеродный след при обучении в 1200 раз меньше, чем у GPT-4.</p><p><i>(*Компания запрещена в РФ)</i></p><h3>Новые правила игры: регуляторы и бизнес</h3><p>С января 2025 года в Евросоюзе действует Углеродный налог на цифровые продукты (Digital Carbon Border Tax). Теперь любое ПО, продающееся в ЕС, должно иметь сертификат углеродной эффективности.</p><p>Для крупных enterprise-решений максимально допустимый углеродный след составляет 500 г CO₂ на 1000 пользователей в месяц. Нарушители платят 7% от оборота продукта в регионе.</p><p>Венчурные фонды радикально изменили подход к инвестициям. <a href="https://www.pwc.com/gx/en/services/sustainability/publications.html">Согласно отчету PwC</a>, 43% фондов требуют ESG-отчетность перед заключением сделки, а 28% вообще не рассматривают стартапы без «зеленой» стратегии. В Кремниевой долине появился первый акселератор Carbon Neutral Startups, который дает бонусы в $50 000 проектам с нулевым углеродным следом.</p><p>Корпорации тоже не остались в стороне. <a href="https://www.microsoft.com/sustainability">Microsoft ввела внутренний углеродный налог</a> — теперь каждое подразделение платит $100 за каждую тонну CO₂, связанную с его продуктами. Эти деньги идут на развитие возобновляемой энергетики.</p><p>Но самое интересное происходит на рынке труда. Разработчики с навыками «зеленого» программирования получают на 15-20% больше предложений. Появилась появилась новая категория навыков — «Устойчивая разработка ПО», а спрос на таких специалистов вырос на 300% за последний год.</p><h2>Как писать «зеленый» код</h2><p>Каждая лишняя операция в коде — это не только миллисекунды процессорного времени, но и реальные граммы CO₂. В 2025 году энергоэффективность кода перестала быть теоретической концепцией и превратилась в конкретный навык, который влияет на карьеру разработчика. Рассмотрим три ключевых направления оптимизации.</p><h3>Оптимизация запросов к базе данных</h3><p>Типичный пример — использование SELECT * вместо явного перечисления полей. Когда приложение запрашивает все поля таблицы users (включая редко используемые avatar_blob или metadata_json), сервер БД тратит дополнительные ресурсы на чтение и передачу этих данных. В крупных системах с миллионами запросов в день это приводит к значительному перерасходу вычислительных ресурсов.</p><p>Современные ORM типа Prisma и Drizzle добавили автоматическую оптимизацию запросов. Теперь при использовании select() они анализируют, какие поля действительно нужны на клиенте, и генерируют оптимальный SQL. В тестах это снижает нагрузку на БД на 12-18%.</p><h3>Работа с циклами и алгоритмами</h3><p>Классическая ошибка — продолжать перебор массива после нахождения нужного элемента. В 2025 году статический анализатор кода в WebStorm и VS Code автоматически предупреждает о таких ситуациях. Особенно критично это для мобильных приложений: лишние итерации цикла на слабых устройствах увеличивают энергопотребление на 5-7%.</p><p>Новые версии JavaScript и TypeScript ввели оптимизированные методы для массивов. Например, array.findLast() работает в 1,5 раза эффективнее ручной реализации с циклом. Для сложных алгоритмов появились «зеленые» библиотеки вроде EcoCollections для Java, которые минимизируют энергопотребление при работе с структурами данных.</p><h3>Сжатие и передача данных</h3><p>Формат Brotli стал новым стандартом для API: он обеспечивает лучшее сжатие, чем gzip, особенно для JSON-ответов. Компания Cloudflare провела эксперимент: после перехода на новую версию Brotli нагрузка на их серверы снизилась на 18%, что эквивалентно годовому потреблению энергии 2000 домохозяйств.</p><p>Но сжатие — не панацея. Грамотное проектирование API может дать больший эффект. GraphQL-подход, где клиент запрашивает только нужные данные, в среднем почти вдвое уменьшает объем передаваемой информации по сравнению с REST. А технология Server-Sent Events (SSE) для реального времени потребляет в 3 раза меньше ресурсов, чем WebSockets, когда не нужна двусторонняя связь.</p><p>Современные фреймворки начали учитывать энергоэффективность. Next.js 15 <a href="https://nextjs.org/blog">представил «зеленый» режим компиляции</a>, который оптимизирует сборку под минимальное энергопотребление. В тестах это дало 8% экономии на процессоре при работе приложения. А Deno 2.0 автоматически кэширует зависимости на уровне ОС, сокращая число повторных загрузок.</p><p>Эти изменения кажутся мелкими, но в масштабах индустрии они имеют огромное значение. Если бы все репозитории на платформе применили базовые оптимизации, глобальное энергопотребление дата-центров сократилось бы на несколько процентов. Для отрасли, которая потребляет 700 ТВт⋅ч в год, это десятки миллионов долларов и тысячи тонн CO₂.</p><h2>Выбор технологий</h2><p>В 2025 году выбор стека технологий влияет не только на производительность, но и на экологичность проекта. Разберем ключевые аспекты, которые помогут снизить углеродный след вашего приложения.</p><h3>Языки программирования: баланс между скоростью и эффективностью</h3><p>Rust и Go продолжают доминировать в высоконагруженных системах. Тесты показывают, что веб-сервер на Rust потребляет на 35-40% меньше энергии при одинаковой нагрузке по сравнению с Node.js. Особенно заметна разница в облачных средах, где каждый ватт на счету.</p><p>C++ остается выбором для задач, где важна предсказуемая производительность. Новый стандарт C++26 добавил энергоэффективные режимы работы алгоритмов STL, что особенно важно для встраиваемых систем.</p><p>Python по-прежнему хорош для прототипирования, но в продакшене его лучше заменять на компилируемые языки. PyPy 8.0 сократил энергопотребление интерпретатора на 25%, но даже с этими улучшениями Python проигрывает Rust в 3-4 раза по эффективности.</p><h3>Базы данных: от малого к большему</h3><p>SQLite — идеальный выбор для небольших проектов и edge-устройств. Его новая версия 3.45 добавила режим «энергосбережения», который снижает потребление на 15% при фоновых операциях.</p><p><a href="https://www.postgresql.org/docs/17/release-17.html">PostgreSQL 17</a> сделал большой шаг в энергоэффективности. Функция автоматического партиционирования теперь учитывает не только производительность, но и энергопотребление. В тестах это дало 20% экономии на крупных аналитических запросах.</p><p>Для высоконагруженных систем появилась альтернатива — ScyllaDB 5.0. Эта Cassandra-совместимая СУБД потребляет втрое раза меньше энергии при аналогичной нагрузке, благодаря полному переписыванию на Rust.</p><h2>Кейсы: что работает, а что нет</h2><p>Российские компании тоже внедряют экологичные IT-решения. МТС разработала мобильное приложение, где пользователи получают бонусы за раздельный сбор мусора — их можно обменять на подписки или скидки. За первый год проект привлек 500 тысяч участников и сократил количество непереработанных отходов в регионах присутствия.</p><p>НИУ ВШЭ, совместно с Росприроднадзором, автоматизировал сбор экологической отчетности с помощью ИИ. Нейросеть анализирует данные с датчиков и заполняет формы вместо специалистов. Это сократило время обработки с 100 до 10 часов в месяц и уменьшило количество ошибок.</p><p>Некоторые архитектурные решения приносят больше вреда, чем пользы. Один московский стартап без необходимости разбил монолитную систему на 50 микросервисов — в результате затраты на инфраструктуру выросли в 3 раза, а углеродный след увеличился на 180%.</p><p>Проблемы возникают и на уровне зависимостей. История с left-pad повторилась в 2024 году, когда один npm-пакет потянул за собой 80 МБ ненужных библиотек. Теперь крупные компании проверяют каждую зависимость через Bundlephobia и устанавливают лимит на размер node_modules.</p><h2>Что нас ждет</h2><p>В 2025 году отрасль стоит на пороге радикальных изменений, которые перевернут наши представления о «зеленом» программировании.</p><p>Супероблака — следующий этап эволюции распределенных вычислений. В отличие от традиционных облачных провайдеров, эти системы автоматически переносят нагрузку между дата-центрами в зависимости от доступности возобновляемой энергии.</p><p><a href="https://cloud.google.com/sustainability">Google уже тестирует эту технологию</a> в Северной Европе: когда в Норвегии дует сильный ветер и ветряные электростанции работают на пике, система переносит вычисления именно туда. По предварительным оценкам, это снижает углеродный след на 18-22% по сравнению со статичным распределением.</p><p>Но настоящий прорыв ожидается в сегменте квантовых вычислений. Хотя современные квантовые компьютеры потребляют колоссальное количество энергии (система IBM Quantum System One требует около 25 кВт⋅ч для работы одного кубита), их потенциал для оптимизации классических алгоритмов огромен.</p><p>В 2024 году исследователи из ЦЕРНа <a href="https://www.nature.com/articles/s41534-024-00859-0">предложили квантовый алгоритм</a>, который сокращает время сложных расчетов в 1000 раз при той же точности. Когда такие решения станут массовыми (прогноз — 2028-2030 годы), энергопотребление дата-центров может сократиться на 30-40%.</p><p>Государственное регулирование становится строже. В 2025 году в силу вступает EU Digital Product Passport — требование указывать углеродный след для всего ПО, продающегося в Европе.</p><p>Компании, которые не смогут предоставить эти данные, столкнутся с дополнительными налогами до 7% от оборота. В ответ на это крупнейшие IT-корпорации создали Carbon Neutral Software Alliance — консорциум по разработке единых стандартов измерения.</p><p>Не отстает и аппаратная часть. Производители чипов переходят на новые техпроцессы: TSMC анонсировала 2-нм процесс, который на 30% энергоэффективнее предыдущего поколения. А стартапы вроде британской ZeroPoint Technologies разрабатывают память с нулевым энергопотреблением в режиме ожидания — технология может сократить энергопотребление серверов на 15%.</p><p><b>Но главный тренд </b>— децентрализация вычислений. Edge-устройства (от смартфонов до промышленных датчиков) становятся мощнее и берут на себя часть нагрузки. Например, новый алгоритм Apple для обработки фото на iPhone 16 выполняет 90% операций локально, а не в облаке. По оценкам компании, это экономит сотни тысяч тонн CO₂ в год только для пользователей в США.</p><p>Однако остаются и <b>проблемы</b>. Бум генеративного ИИ привел к взрывному росту энергопотребления: одна тренировка модели Gemini Ultra потребляет столько же энергии, сколько небольшой город за месяц. OpenAI и Anthropic уже работают над более эффективными архитектурами, но прорыва пока не случилось.</p><p>В ближайшие 3-5 лет нас ждет:</p><ul><li>массовый переход на углеродно-нейтральные дата-центры — к 2027 году их доля превысит 60%;</li><li>внедрение AI-оптимизаторов кода, которые автоматически сокращают энергопотребление;</li><li>появление «зеленых» рейтингов для приложений — аналог энергоэффективности для бытовой техники.</li></ul><p>Компании, внедрившие принципы устойчивого развития в IT, уже в 2025 году получают на больше инвестиций и быстрее проходят аудит регуляторов. Экологичность перестала быть затратой — теперь это конкурентное преимущество.</p><p>Технологии будущего уже здесь. Вопрос в том, насколько быстро мы сможем их адаптировать. Как сказал Дженсен Хуанг из NVIDIA на последней конференции GTC:</p><blockquote>«Следующее десятилетие определит, станет ли IT частью климатического решения или останется проблемой. Выбор за нами».</blockquote><h2>Итоги</h2><p>Экологичность в IT — не благотворительность и не актуальная повестка, а реальная экономия. Плюс работа на перспективу. Оптимизация кода снижает счета за облака и повышает производительность.</p><p>С чего начать? Начните с малого:</p><ol><li>Запустите аудит через Cloud Carbon Footprint.</li><li>Уберите «мусор» из зависимостей.</li><li>Выберите хостинг с ВИЭ.</li></ol><p>Как говорил Дональд Кнут, автор книги «Искусство программирования»:</p><blockquote>«Преждевременная оптимизация — корень всех зол. Но и запоздалая — тоже».</blockquote><p>В 2025 году это актуально как никогда.</p>]]></content:encoded>
    </item>
    <item>
      <title>Что скрывает ChatGPT: тайные символы в ответах нейросети</title>
      <link>https://tproger.ru/articles/chto-skryvaet-chatgpt--tajnye-simvoly-v-otvetah-nejroseti</link>
      <comments>https://tproger.ru/articles/chto-skryvaet-chatgpt--tajnye-simvoly-v-otvetah-nejroseti?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Михаил Сахаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/chto-skryvaet-chatgpt--tajnye-simvoly-v-otvetah-nejroseti</guid>
      <description><![CDATA[<p>В статье расскажем о невидимых метках, которые оставляет ChatGPT во время работы, а также о «мировом заговоре», который возник из-за этого, и как удалось его раскрыть.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/chto-skryvaet-chatgpt--tajnye-simvoly-v-otvetah-nejroseti">Что скрывает ChatGPT: тайные символы в ответах нейросети</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Hardware]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Unicode]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[MIT]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Оружие]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 04 Jul 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>ChatGPT оставляет в текстах невидимые метки. Звучит как начало фильма про ИИ-заговор, но это реальность. Когда эта история впервые появилась в новостях, люди подумали о том, что нейросети шпионят за ними.</p><p>Представьте: студент пишет эссе в ChatGPT, сдает работу, а через неделю преподаватель находит странные символы в его тексте. Это не мистика, а обычная техническая особенность, которая превратилась в детектив в духе Дэна Брауна.</p><p>Пора узнать о том, как обычные пользователи случайно раскрыли «заговор» искусственного интеллекта, почему в интернете началась паника о скрытых водяных знаках, и что на самом деле происходит с новыми моделями OpenAI.</p><h2>Первые улики</h2><p>Все началось в апреле 2025 года. Студенты университетов стали <a href="https://trashbox.ru/link/2025-04-21-chatgpt-vstraivaet-vodyanye-znaki">жаловаться</a> на странные проблемы с текстами ChatGPT. Текстовый редактор Word вел себя странно при копировании эссе. Некоторые символы странно выглядели и в редакторах кода.</p><p>Первыми в теме начали <a href="https://www.rumidocs.com/newsroom/new-chatgpt-models-seem-to-leave-watermarks-on-text">разбираться</a> специалисты из Rumi. Они создавали инструменты для поиска ИИ в курсовых и контрольных, поэтому привыкли анализировать тексты. При тестировании новых моделей GPT o3 и o4-mini команда обнаружила, что нейросеть встраивает в сгенерированные ответы Unicode-символы.</p><p>При этом OpenAI как раз запустила бесплатный доступ к ChatGPT для студентов до конца учебного года, как раз во время сессии. Неразрывные пробелы <a href="https://t-j.ru/news/are-chatgpt-watermarks-real/">появлялись</a> только в длинных ответах — например, если ввести запрос «Напиши эссе о министерстве образования». Хотя некоторые пользователи заметили, что невидимые символы встраиваются и в короткие ответы.</p><p>Разработчики начали <a href="https://itc.ua/en/news/the-new-chatgpt-models-leave-extra-characters-in-the-text-they-can-be-detected-through-word/">обсуждать</a> тему на форумах. Пользователи делились скриншотами из Sublime Text и VS Code, где обычные пробелы подсвечивались как спецсимволы. Кто-то понял, что в Word можно нажать Ctrl+Shift+8 — сочетание клавиш сразу находит водяные знаки ChatGPT и отображает их как кружочки.</p><p>Такие символы не видно в чате с нейросетью и при копировании текста в Word, гугл-документы, мессенджеры или браузер. OpenAI нигде <a href="https://news.finance.ua/ru/chatgpt-stal-tayno-markirovat-svoi-teksty">не сообщала</a> об этом нововведении — вероятно, специально.</p><figure><img src="https://media.tproger.ru/user-uploads/115386/2025-06-19/5d095e83-7ece-4283-ba97-e93a4409b24c.jpg" alt="" /><figcaption>Непечатные символы, которые обнаружила команда Rumi в одном из текстов ChatGPT</figcaption></figure><h2>Охота на невидимку</h2><p>Команда Rumi тестировала новые модели и <a href="https://www.rumidocs.com/newsroom/new-chatgpt-models-seem-to-leave-watermarks-on-text">заметила</a> странность — длинные эссе выглядели нормально, но что-то было не так. Когда разработчики скопировали текст в редактор Sublime, то увидели россыпь странных символов на месте обычных пробелов.</p><p>Виновником <a href="https://gadgetstouse.com/blog/2025/04/25/detect-hidden-watermark-in-chatgpt-generated-text/">оказался</a> Unicode-символ U+202F — узкий неразрывный пробел. Он практически неотличим от обычного пробела, но имеет совершенно другой код. Для программистов это как найти подделку с помощью ультрафиолета.</p><p>Энтузиасты быстро создали инструменты для охоты на невидимку. SoSciSurvey научился находить 34 типа скрытых Unicode-символов — от пробела нулевой ширины до длинных тире.</p><p>Самым простым способом отыскать «партизан» стала комбинация клавиш. В Word нужно нажать Ctrl+Shift+8 — обычные пробелы превращаются в точки, а водяные знаки ChatGPT отображаются кружочками. Sublime Text <a href="https://gadgetstouse.com/blog/2025/04/25/detect-hidden-watermark-in-chatgpt-generated-text/">показывает</a> символы еще нагляднее — можно искать конкретно \u202F через функцию поиска.</p><p>Удалить символы оказалось еще проще. Любой может открыть VS Code или Sublime Text, найти U+202F через поиск и заменить на обычные пробелы. Водяные знаки исчезают за секунды.</p><p>Однако удаление скрытых символов не влияет на обнаружение ИИ-контента детекторами. Текст все равно определяется как сгенерированный. Получается, водяные знаки — это дополнительная, а не основная защита от мухлежа при создании работ.</p><h2>Заговор разрастается</h2><p>В соцсетях началась паника. Пользователи обвиняли OpenAI в том, что она специально выявляет студентов-читеров. Совпадение с бесплатным доступом для учащихся добавило масла в огонь.</p><p>Блогеры рисовали мрачные картины тотальной слежки. Якобы компания тайно <a href="https://mitsloan.mit.edu/ideas-made-to-matter/mit-study-ai-chatbot-can-reduce-belief-conspiracy-theories">помечает</a> каждого пользователя через невидимые символы. Кто-то даже предполагал, что OpenAI готовит массовые облавы на студентов перед защитой дипломов.</p><p>Особенно <a href="https://dl.acm.org/doi/10.1145/3614419.3644014">бурлили</a> студенческие форумы на Reddit. Учащиеся делились страшилками о том, как преподаватели внезапно начали проверять работы через редакторы кода. Появились гайды по обходу любых ИИ-детекторов.</p><p>Конспирологи забыли об одной детали — водяные знаки удаляются за пару кликов через поиск в документе.</p><p>Второй прокол теоретиков заговора — техническая реальность. OpenAI уже несколько лет разрабатывает технологию водяных знаков, но так и не выпустила ее.</p><p>К тому же компания открыто заявляла о работе над детекторами ИИ-контента. «Заговор» рассыпался при первом же фактчекинге.</p><p>Но паника уже распространилась. Студенты массово <a href="https://www.tomshardware.com/tech-industry/artificial-intelligence/openai-has-built-a-text-watermarking-method-to-detect-chatgpt-written-content-company-has-mulled-its-release-over-the-past-year">скачивали</a> инструменты для «очистки текстов», а преподаватели начали подозревать каждую работу. История с невидимыми символами превратилась из мелкого бага в огромный снежный ком из паники и домыслов.</p><h2>Прозаичная реальность</h2><p>OpenAI наконец прокомментировала ситуацию. Официальный ответ звучал предельно скучно: «Это не водяные знаки, а просто особенность масштабного обучения с подкреплением». Никакого заговора, никакой слежки — банальный артефакт.</p><p>При обучении нейросети с подкреплением модель <a href="https://openai.com/index/learning-to-reason-with-llms/">получает </a>«награды» за правильные ответы и «штрафы» за неправильные. В процессе миллионов таких циклов система случайно научилась вставлять специальные символы. Не потому, что так задумывали разработчики. Просто в данных эти символы встречались и улучшали результат.</p><p>Нейросеть приобрела «привычку». Никто ее этому не учил, но действие «отложилось в подсознании».</p><p>В обучении с подкреплением множество таких сюрпризов. Например, алгоритмы учатся играть в видеоигры и внезапно <a href="https://news.ycombinator.com/item?id=41600179">находят</a> баги, которые не замечали разработчики. Или начинают использовать физику игрового движка нестандартными способами. ChatGPT просто продолжил традицию — научился ставить невидимые символы там, где человек поставил бы пробел.</p><p>Конспирологам пришлось сворачиваться. Вместо эпического противостояния студентов и корпораций получился рассказ о том, как нейросеть случайно освоила цифровую каллиграфию.</p><h2>Дело раскрыто</h2><p>Парадокс в том, что разоблачить «заговор» оказалось проще, чем его придумать. Один официальный комментарий OpenAI — и вся конструкция рухнула.</p><p>Урок простой: перед тем как кричать о заговоре, стоит <a href="https://www.wissenschaftskommunikation.de/why-we-shouldnt-panic-about-the-rise-of-conspiracy-theories-75843/">потратить</a> пять минут на фактчекинг. Google по запросу «reinforcement learning side effects» выдаст тонны статей о побочках машинного обучения. Но кто же будет искать скучные объяснения, когда есть яркие теории?</p><p>В следующий раз, когда увидите пост про «тайное оружие техногигантов», вспомните про символы U+202F.</p><p>Над теориями заговора можно только смеяться. Больше — в нашем <a href="https://t.me/+JWynXkY6aXcxZGNi">тг-канале</a>!</p>]]></content:encoded>
    </item>
    <item>
      <title>Петабайты каждый день: как хранить и использовать данные с умом</title>
      <link>https://tproger.ru/articles/petabajty-kazhdyj-den--kak-hranit-i-ispolzovat-dannye-s-umom</link>
      <comments>https://tproger.ru/articles/petabajty-kazhdyj-den--kak-hranit-i-ispolzovat-dannye-s-umom?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/petabajty-kazhdyj-den--kak-hranit-i-ispolzovat-dannye-s-umom</guid>
      <description><![CDATA[<p> Как компаниям эффективно хранить и масштабировать big data? Разбираем решения с экспертом VK Cloud. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/petabajty-kazhdyj-den--kak-hranit-i-ispolzovat-dannye-s-umom">Петабайты каждый день: как хранить и использовать данные с умом</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[AMD]]></category>
      <category><![CDATA[CSR]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 02 Jul 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Каждый день в мире генерируется более <a href="https://www.techbusinessnews.com.au/blog/402-74-million-terrabytes-of-data-is-created-every-day/">400 миллионов</a> терабайт данных. Возможно, стоило бы отпраздновать эту цифру, но компаниям все сложнее хранить такие объемы. С одной стороны, — это вопрос оптимизации стоимости. С другой, — удобства использования и масштабирования.</p><p>В этом материале вместе со Станиславом Погоржельским, технологическим евангелистом платформы VK Cloud, разберем особенности решений для хранения и работы с большими данными.</p><h2>Особенности локальных хранилищ</h2><p>Стоит держать в уме, что выбор таких решений не всегда зависит от архитектурных принципов и лучших практик, а чаще всего от наличия определенной экспертизы в компании. Проведем очную ставку трех основных моделей построения хранилищ.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-02/7eece396-17d8-49b4-8aca-522d466b3c85.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-02/5c60f581-5f7e-40e2-ac17-65eb3ad59714.png" alt="" /></figure><h3>Семь «грехов» локальных кластеров</h3><p>Теперь поговорим о том, какие неприятные особенности встречаются во время эксплуатации локальных кластеров.</p><h4>Структура данных и хаос</h4><p>В реальных системах данные редко бывают аккуратными. Вместо красивых таблиц разработчик часто сталкивается с миллионами мелких файлов по 1-2 Кб и, например, видео по несколько Гб. Такие крайности требуют противоположных стратегий хранения и кэширования.</p><p>Файловая система, не оптимизированная для работы с малыми файлами, быстро забивается inode'ами (переполнение файловых дескрипторов). Системы хранения начинают задыхаться не от общего объема, а от количества объектов, что критически влияет на производительность. Например, <a href="https://web.archive.org/web/20161101132116/http://engineering.spilgames.com/openstack-swift-lots-small-files/">известны случаи</a>, когда после миллиона объектов OpenStack Swift начинал терять метаданные, а в хранилищах висели призраки удаленных объектов.</p><h4>RAID — не универсальное спасение</h4><p>Настройка RAID-массивов кажется очевидным решением, но не все так однозначно:</p><ul><li>RAID 5 и 6 плохо переносят большие объемы из-за длительного времени восстановления.</li><li>RAID 10 требует удвоения или утроения объема хранения ради скорости и отказоустойчивости.</li><li>На петабайтных объемах пересборка массива после сбоя может занимать больше недели.</li></ul><h4>Поддержка архивов и ZIP-файлов</h4><p>Архивирование данных (например, с помощью ZIP) спасает место, но приводит к другим проблемам: невозможность выборочного доступа к отдельным файлам без полной распаковки, рост времени обработки запросов, сложность мониторинга целостности данных.</p><p>Массовая работа с архивами требует настройки кэширования и часто вынуждает строить параллельные системы для индексации содержимого архивов.</p><h4>Автоматизация мониторинга и ремонта</h4><p>Любая система хранения живет с постоянным риском деградации: умирают диски, выходят из строя контроллеры, падают сети. На уровне сотен и тысяч узлов мониторинг «вручную» невозможен: требуется автоматизированная оркестрация алертов, самовосстановление, динамическая миграция данных на здоровые узлы. Иначе разрастание локальных отказов перерастает в потерю данных.</p><h4>Шардирование данных: неизбежность и боль</h4><p>На больших объемах данных (более 250 Тб) приходится шардировать — разбивать на независимые логические части, чтобы сохранить производительность. Но с шардированием есть проблемы:</p><ul><li>усложняет маршрутизацию запросов;</li><li>увеличивает сложность восстановления данных при сбоях;</li><li>требует отдельных механизмов ребалансировки шардов при добавлении новых узлов.</li></ul><p>Более того, встроенные механизмы шардирования некоторых популярных СУБД (MongoDB, PostgreSQL с партиционированием) не рассчитаны на миллиарды записей и начинают деградировать.</p><h4>Проблемы метаданных</h4><p>Каждый файл и объект требуют метаданных: даты создания, размера, доступа, хеш-суммы. При росте числа объектов метаданные сами по себе становятся огромными: терабайты информации, требующие отдельного хранения, индексирования и защиты.</p><h4>Резервное копирование на практике</h4><p>Бэкап петабайта данных требует продуманной стратегии инкрементальных копий, дедупликации, постоянного тестирования восстановления. Локальное хранение больших объемов данных — это не про покупку железа и развертывание файлового сервера. Это бесконечная инженерная работа по балансировке между скоростью, надежностью, стоимостью и сложностью системы.</p><p>Хранение больших объемов обостряет вопросы производительности, резервного копирования и автоматизации мониторинга, где каждый аспект требует балансировки между скоростью, надежностью и сложностью ИТ-инфраструктуры.</p><h2>Облачные хранилища</h2><p>С локальными хранилищами разобрались, теперь рассмотрим технические особенности альтернативного решения.</p><h3>Гибкость и масштабируемость без ограничений</h3><p>В облаке увеличение объемов хранения происходит мгновенно:</p><ul><li>без ожидания закупки нового оборудования;</li><li>без сложного планирования миграций;</li><li>без перебоев в обслуживании приложений.</li></ul><p>Эксплуатация и разработчики могут динамически добавлять терабайты и петабайты данных в рамках одного API-запроса. Облачное хранилище предлагает готовое решение для масштабирования от стартапов до международного уровня компаний.</p><h3>Финансовая прозрачность и удобная модель оплаты</h3><p>Модель Pay-As-You-Go (оплата по факту использования) дает бизнесу и разработчикам:</p><ul><li>предсказуемость расходов;</li><li>возможность мгновенно адаптировать инфраструктуру под изменяющиеся требования;</li><li>отсутствие необходимости капитальных затрат на старте;</li><li>гибкость в выборе тарифов хранения (горячие, холодные, архивные данные).</li></ul><p>Такая прозрачная модель помогает экономить бюджет без потери качества сервиса.</p><h3>Надежность и отказоустойчивость «из коробки»</h3><p>S3-совместимый Object Storage обеспечивает высокую доступность данных благодаря:</p><ul><li>автоматической репликации данных в нескольких географических регионах;</li><li>встроенным механизмам самовосстановления данных;</li><li>резервированию оборудования на уровне дата-центров;</li><li>постоянному мониторингу целостности объектов.</li></ul><h3>Оптимизация работы с любыми типами данных</h3><p>Хранилище позволяет одинаково эффективно работать:</p><ul><li>с миллионами мелких файлов (фото, документы, логи);</li><li>с тяжелыми объектами (видео или архивами).</li></ul><p>Облачная платформа автоматически оптимизирует хранение и доступ, снижая латентность и ускоряя обработку даже при экстремальных нагрузках.</p><h3>Высокий уровень безопасности данных</h3><p>В облаке предоставляется комплексная защита данных с помощью:</p><ul><li>шифрования на стороне клиента и сервера;</li><li>гибкого управления правами доступа (ACL, IAM);</li><li>соответствия требованиям хранения ПДН и прочих стандартов безопасности;</li><li>автоматического обнаружения потенциальных уязвимостей.</li></ul><p>Безопасность данных обеспечивается на каждом уровне инфраструктуры и подтверждается регулярными внешними аудитами.</p><h3>Инструменты для разработчиков и автоматизации</h3><p>Хранение данных в облаке ориентировано на удобство интеграции и масштабирование за счет:</p><ul><li>полного набора API и SDK для популярных языков программирования;</li><li>готовых модулей для работы с данными в распределенных системах;</li><li>продвинутых средств мониторинга, алертинга и автоскейлинга;</li><li>поддержки DevOps практик через IaC-инструменты.</li></ul><p>Автоматизация всех процессов упрощает разработку и сопровождение проектов, значительно снижая риски человеческих ошибок.</p><h2>Опыт хранения больших данных</h2><p>Когда речь идет о масштабных системах хранения — таких как S3-совместимый сервис Object Storage на платформе VK Cloud, — производительность определяется не только скоростью сети и дисков. Ключевую роль играют архитектурные особенности приложений: как именно данные распределяются, обрабатываются и индексируются.</p><p>Особенно важно это в системах с огромным количеством объектов, где миллионы или миллиарды файлов разного размера постоянно создаются, обновляются и удаляются.</p><h3>Как измеряется производительность облачного хранилища</h3><p>Для реальной оценки производительности облачного хранилища важно замерять:</p><ul><li>Количество операций в секунду (RPS): сколько запросов на чтение/запись способна обработать система.</li><li>Среднюю и 99-ю персентиль задержек: критично для оценки качества обслуживания конечных пользователей.</li><li>Производительность на больших объемах объектов: важно не просто тестировать один файл, а моделировать реальную работу приложений с множеством параллельных операций.</li><li>Влияние мелких и крупных файлов: системы по-разному работают при миллионах маленьких объектов и гигабайтных видео.</li></ul><p>Практические сценарии измерений:</p><ul><li>многопоточная загрузка 100 миллионов объектов размером 1–10 КБ;</li><li>массовое чтение миллионов объектов через S3 API;</li><li>удаление больших объемов объектов для оценки работы сборки мусора;</li><li>сценарии с версионированием объектов, чтобы проверить нагрузку на метаданные.</li></ul><h3>Почему шардирование критически важно для облачного хранилища</h3><p>Правильная организация шардирования данных — один из ключевых факторов производительности больших хранилищ.</p><p><b>Что происходит без правильного шардирования:</b></p><ul><li>«Горячие» бакеты (S3-бакеты) с высокой нагрузкой становятся узким местом.</li><li>Распределение нагрузки по серверам становится неравномерным.</li><li>Метаданные начинают тормозить операции доступа.</li><li>Снижается общая масштабируемость системы.</li></ul><p><b>Реальная практика VK Cloud:</b></p><ul><li>Метаданные объектов распределяются по кластерам через шардирование по диапазонам ключей.</li><li>При превышении нагрузки шард автоматически расщепляется (split) для перераспределения нагрузки между нодами.</li><li>Для хранения метаданных используется Tarantool как высокоскоростная in-memory база данных, способная выдерживать сотни тысяч операций в секунду на один шард.</li></ul><p><b>Такой подход позволяет обеспечить:</b></p><ul><li>низкие задержки доступа даже при миллиардах объектов;</li><li>линейное масштабирование — добавление новых серверов дает реальный прирост пропускной способности;</li><li>быструю обработку как мелких, так и больших файлов без перегрузки одной ноды.</li></ul><p>С увеличением объема метаданных нагрузка на отдельные узлы или компоненты системы возрастает, что ограничивает масштабируемость и может снижать производительность при высоких требованиях к обработке данных.</p><h2>За что мы любим Tarantool</h2><p>Принцип работы СУБД Tarantool кардинально отличается от классических SQL-баз (PostgreSQL, MySQL) в хранилищах:</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-07-02/15133b4d-c1bc-4d7d-a09f-e86554a1d249.png" alt="" /></figure><p>Tarantool позволяет работать с облачным хранилищем на скорости, которую классические базы не способны обеспечить без радикальных усилий по оптимизации.</p><h2>Как правильно проектировать нагрузку на S3-совместимое облако</h2><p>Если вы проектируете высоконагруженную систему, важно:</p><ul><li>Использовать естественное шардирование ключей (например, вставлять случайные префиксы в имена объектов).</li><li>Ожидать миллионы объектов в бакете и строить приложения так, чтобы они не зависели от скорости листинга всех файлов.</li><li>Минимизировать количество операций массового удаления объектов — использовать batch-удаление через S3 API.</li><li>Понимать, что работа с метаданными так же важна, как и сама передача данных.</li></ul><p>Производительность облачного хранилища определяется не только сетью и железом, но и архитектурой работы с данными. Правильное шардирование, оптимизация структуры ключей и использование быстрых конечных СУБД — основа эффективных и масштабируемых сервисов.</p><h2>Заключение</h2><p>Работа с петабайтными объемами данных требует серьезного подхода к проектированию инфраструктуры. На этом пути локальные решения сталкиваются с проблемами масштабирования, отказоустойчивости, обновления оборудования и обеспечения безопасности. Управление инфраструктурой превращается в отдельный проект со своими ресурсами.</p><p>Облачное хранилище обеспечивает:</p><ul><li>автоматическое масштабирование объема хранения без потерь в производительности;</li><li>высокую доступность данных благодаря распределению по зонам отказа;</li><li>прозрачную модель оплаты — вы платите только за реально используемые ресурсы;</li><li>эффективную работу как с миллионами мелких файлов, так и с крупными объектами;</li><li>безопасность данных с помощью встроенного шифрования и управления доступом через IAM;</li><li>богатый инструментарий API для полной интеграции в любые архитектуры приложений.</li></ul><p>Облачные хранилища предоставляют возможность компаниям сосредоточиться на развитии своих продуктов и бизнес-логики, передав инфраструктурные задачи профессиональной облачной платформе.</p>]]></content:encoded>
    </item>
    <item>
      <title>Микросервисная архитектура: от монолита к гибкой системе</title>
      <link>https://tproger.ru/articles/mikroservisnaya-arhitektura--ot-monolita-k-gibkoj-sisteme</link>
      <comments>https://tproger.ru/articles/mikroservisnaya-arhitektura--ot-monolita-k-gibkoj-sisteme?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/mikroservisnaya-arhitektura--ot-monolita-k-gibkoj-sisteme</guid>
      <description><![CDATA[<p>«Монолит или микросервисы» — вопрос, который до сих пор вызывает споры в IT. СТО Сервисной цифровой платформы в Газпромбанке делится личным опытом перехода к микросервисной архитектуре, разбирает реальные кейсы и объясняет, почему однозначного ответа не существует.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/mikroservisnaya-arhitektura--ot-monolita-k-gibkoj-sisteme">Микросервисная архитектура: от монолита к гибкой системе</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Ретро]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 27 Jun 2025 08:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Привет! Меня зовут Андрей Бирюков, я СTO Сервисной цифровой платформы в Газпромбанке. За свою карьеру поработал в нескольких компаниях — от стартапов до крупных корпораций — и видел разные архитектурные подходы.</p><p>И вот начала копиться усталость от обсуждения, что использовать — монолиты или микросервисы. Этот вопрос стал преследовать меня на конференциях, в офисе, в личных сообщениях. Я потратил столько времени на обсуждение этой темы, что иногда хочется просто распечатать какой-нибудь емкий ответ на футболке и ходить в ней на все митапы.</p><p>Шутки шутками, но тема действительно важная. Я прошел путь от классических монолитных приложений до сложных микросервисных, проектировал системы, которые работают под большой нагрузкой, и пришел к выводу, что однозначного ответа здесь не существует. И вообще, «монолит или микросервисы» — это неправильная постановка вопроса.</p><p>Недавно сходил с Витей на запись <a href="https://vkvideo.ru/video-145457488_456239831">подкаста</a> на эту тему и настолько преисполнился, что решил в текстовом виде формализировать свое отношение к теме (я гнался за вами три дня, чтобы сказать, как вы мне безразличны, ага), обобщить то, о чем говорили, и попытаться дать ответ на вопрос «когда микросервисы действительно помогают и как не сойти с ума, если вы с ними работаете». Порассуждаю о проектировании, поддержке, DevOps-культуре и попробую немного заглянуть в микросервисную архитектуру.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-27/98a19000-c584-440e-bf7a-af36d4409a2a.png" alt="" /><figcaption>Подкаст «Техно.Логично»</figcaption></figure><h2>Микросервисы: зачем они нужны и в чем их плюсы</h2><h3>Архитектура приложений: немного базы</h3><p>Под капотом современных приложений обычно скрываются три основные части:</p><ul><li>множество библиотек и зависимостей;</li><li>единый store, в котором живут состояние и данные;</li><li>компоненты, которые нужно собрать, чтобы сделать из них приложение.</li></ul><p>Собрать это все можно по-разному. Можно сложить в монолит, а можно попробовать модульный подход.</p><p>Монолитное приложение — старое доброе приложение, которое, как правило, создают один или несколько разработчиков, потом его дорабатывает армия джунов, синьоров и всех, кто оказался рядом. Каждый «чуть-чуть поправил», и вот уже никто не понимает, почему оно работает, — но трогать страшно. Монолиты пишут и сейчас — все зависит от бизнеса. Если нужно приложение для небольшого проекта, микросервисы могут и не понадобиться.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-27/02011912-2de9-4c86-9de2-44865eb93fab.png" alt="" /><figcaption>Как выглядит монолит</figcaption></figure><p>Однако наступает момент, когда бизнес расширяется, аудитория растет, нагрузка увеличивается — а масштабировать монолит становится все сложнее. Тогда и приходят на помощь микросервисы.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-27/739de2ec-05c4-4f68-bf1a-356380611028.png" alt="" /><figcaption>А вот приложение с микросервисной архитектурой</figcaption></figure><p>Масштабировать можно и монолиты, но у них всегда остается какая-то единая точка отказа — например, база данных. Особенно если это реляционная СУБД, завязанная на Oracle или PostgreSQL. Когда база достигает сотен гигабайт или даже терабайт, масштабировать такую штуку становится дорого, больно и ненадежно.</p><h3>Микросервисы — панацея? Не совсем</h3><p>Тренд на микросервисный подход появился в начале 2010-х годов, вместе с проникновением интернета в широкие слои населения. Первый iPhone вышел в 2007 году, люди стали гораздо ближе к интернету, к данным, к информации. Бизнес захотел дотянуться до этой аудитории, и тогда началась диджитализация, сложность систем стала повышаться. Особенно остро это почувствовали крупные организации вроде банков: функциональность увеличивалась, и монолит начал «трещать» не только технически по инфраструктуре, но и по возможностям команд разработки, которые с ним работали.</p><p>Плюсы микросервисов очевидны: масштабируемость, независимая разработка, изоляция компонентов. Но вместе с этим пришли новые проблемы — усложнились мониторинг и поддержка, стали требоваться все новые инструменты, чтобы обеспечивать работу огромной инфраструктуры. Так появился DevOps.</p><h2>Распространение DevOps-культуры и инструменты оркестрации</h2><p>Раньше разработчик писал код, собирал артефакт и перекидывал его через забор в поддержку. Коллеги за забором его деплоили, запускали — и разработчику можно было больше не думать про плоды своей работы.</p><p>В новой реальности количество артефактов, которые нужно перекидывать через забор, кратно выросло. Вместе с этим появилась и стала распространяться DevOps-культура: понимание, что за качественную раскатку в проде отвечает не только команда поддержки, но и разработчики.</p><p>Важно учитывать еще и то, что сложность поддержки кратно увеличилась. Если монолит можно было отдебажить, просто заглянув в логи, то с сотней микросервисов так не получится. Поэтому появились такие инструменты, как централизованное логирование, распределенный трейсинг — и сотни, если не тысячи других, связанных в первую очередь с observability. В таких обстоятельствах DevOps-культура стала особенно важна.</p><h2>Проектируем микросервисы без боли: от стандартов до DDD</h2><h3>Стандартизация — наше все</h3><p>Если каждый микросервис пишет логи в своем формате и использует свои библиотеки, получается зоопарк. Нужно, чтобы были выровнены стек и CI/CD pipeline, существовали одинаковые библиотеки логирования и формат.Микросервисы дают свободу писать на разных языках, но с ней приходит и ответственность: под каждый язык придется придумывать и поддерживать разные инструменты. А это приведет к еще большему увеличению сложности. Так что с языком тоже лучше соблюдать стандартизацию: если пишете на Java, то и решать все проблемы стоит с помощью этого языка.</p><p>При этом иногда другой язык вполне оправдан. Например, просто потому, что Java не может работать с такой высокой скоростью, какая нужна. В некоторых случаях даже на Java приходится писать особым образом, либо можно использовать C++, Go или Rust. Но это скорее исключение из правила.</p><p>Инженеры — натуры увлекающиеся и любят паттерн CV driven development, когда хочется новую технологию потрогать и внедрить у себя. А потом похвастаться этим на каком-нибудь ивенте по принципу «just because I can» («просто потому что могу»). При этом может оказаться, что бизнесу технология особо и не была нужна. Чтобы избегать таких ситуаций, необходим технологический радар — список того, что можно использовать в компании, а что нет. И исключения из такого радара должны приниматься и допускаться очень взвешенно.</p><h2>DDD: как правильно нарезать сервисы</h2><p>Одна из опасностей при проектировании микросервисов — скатиться в очень мелкую гранулярность, когда логика нарезается чуть ли не по отдельной функции на микросервис (на отдельный deployment unit). Это может привести к такой сложности, которой потом будет очень трудно управлять. Такая проблема была, например, у Uber в начале их пути, и им пришлось пересматривать свою архитектуру. Избежать этого помогает Domain-driven design (DDD) — предметно-ориентированное проектирование.</p><p>Вместо того чтобы пилить отдельные сервисы для авторизации, логирования и уведомлений, команда может подумать вот над чем: все это части одного бизнес-контекста — пользовательского доступа. И целесообразно оставить их в одном сервисе. Это и есть DDD в действии.</p><p>Существует и еще одна проблема, с которой DDD помогает справиться, — неправильная нарезка сервисов с точки зрения бизнесовой функциональности. Если не понимать бизнес-контекста, можно получить «распределенный монолит»: будет много отдельно стоящих сервисов, но профита никакого, только все сложности микросервисов плюс проблемы монолита с масштабируемой базой данных. Особенно остро это проявляется, когда изменения в одной части бизнес-процесса (в одном сервисе) влекут за собой изменения еще в трех-четырех-пяти других сервисах.</p><p>DDD помогает выделить bounded context — согласованные по бизнесу участки. Они позволяют более или менее правильно нарезать большой бизнес-функционал на отдельные части.</p><p>Еще один важный принцип правильной архитектуры микросервисов — у каждого микросервиса должна быть своя независимая маленькая база данных (если она вообще нужна).</p><p><b>Два эмпирических правила, которые касаются размера сервисов и помогают понять, правильно ли они спроектированы:</b></p><ul><li>Если вы не можете переписать сервис за две недели, значит, возможно, он неправильно нарезан, и его нужно декомпозировать.</li><li>Если вам страшно браться за переписывание сервиса, значит, он точно кандидат на декомпозицию.</li></ul><p>Внедрение микросервисов: с чего начать?</p><p>С микросервисным подходом есть проблема — нет четкого ответа, куда идти и что делать, чтобы научиться его создавать. Это одна из главных сложностей микросервисной архитектуры, особенно когда только начинаешь с ней работать. Если хочется изучить Spring или Oracle, можно почитать официальную документацию. А к такой большой и необъятной теме, как микросервисы, даже и непонятно, с какой стороны подступиться. Туториала к ней нет, есть только куча статей, подходов и практик. Причем одни практики подойдут конкретной команде, а другие — нет.</p><p>И вот тут возникает реальная сложность, особенно когда вы только начинаете, — глаза разбегаются. Здесь Kubernetes, здесь ELK, здесь Grafana, здесь observability, здесь всякие паттерны отказоустойчивости, CAP-теорема и прочее. Непонятно, куда бежать. И каждый день появляются новые инструменты, которые так или иначе упрощают жизнь.</p><p>Совет: задавайте себе вопрос о каждом инструменте, который вы хотите внедрить (будь то Kubernetes, OpenTelemetry с Jaeger или любой другой) — какую проблему мы решаем, втаскивая его в свою инфраструктуру? Ответ на этот простой вопрос может дать много инсайтов и просветлений.</p><p>Чтобы в первом приближении ознакомиться с темой, можно почитать материалы <a href="https://sre.google/books/">SRE</a> от Google, также будут полезны статьи и книги в<a href="https://martinfowler.com/"> блоге</a> Мартина Фаулера, в том числе <a href="https://martinfowler.com/microservices/">Microservices Guide</a>. Если вам нужна практика, можно попробовать пойти на тот же Udemy, где есть множество курсов по микросервисной архитектуре с хорошими рейтингами и отзывами.</p><p>И вот что важно: при проектировании и внедрении микросервисов лучше избегать «велосипедостроения». Если индустрия уже решила проблему, нет смысла изобретать новое логирование или оркестрацию. Собственное решение вряд ли будет работать лучше, а сил, времени ресурсов на него можно потратить очень много.</p><h2>Поддержка микросервисной архитектуры</h2><p>Мы каждый день используем разные приложения — например, мобильный банк. Если в магазине длинная очередь, а на кассе у вас вдруг вылетает ошибка, — это раздражает. Поэтому у бизнеса нет права на ошибку: мониторинг должен срабатывать раньше, чем клиент успеет заметить, а инциденты необходимо устранять за минуты.</p><p>В крупных организациях микросервисов могут быть сотни: например, в некоторых системах насчитывается почти 700 микросервисов на продакшене. Каждый инстанс еще масштабирован — это тысячи подов, которые постоянно обрабатывают клиентский трафик. И при этом в современных условиях нужно стремиться к доступности системы на уровне четырех девяток (99,99%), то есть к простою всего в несколько минут в год.</p><p>Если вы хотите достичь того, чтобы простой вашего приложения был минимальным, приходится продумывать много разных подходов, приемов и инструментов.</p><h3>Паттерны отказоустойчивости</h3><p>Микросервисы — это не про «разбили монолит», это про то, что сбой одного сервиса не должен валить весь продукт. Поэтому если какой-то важный сервис упал, то максимум, который нужно сделать, — чтобы клиент не увидел упавший кусочек функционала приложения.</p><p>Еще один хороший вопрос: как мониторить аварии? Необходимо очень быстро находить точку отказа. Для этого, собственно, и нужен observability-подход, трейсинг. Нужно смотреть, где какой RPS (число запросов в секунду), не произошло ли резкого скачка трафика, важно следить за latency (задержками).</p><p>Бывали случаи, когда из-за бага в мобильном приложении трафик внезапно удваивался, и системы не выдерживали такой нагрузки. Любая малейшая задержка в самом незначительном компоненте может привести к тому, что по цепочке пойдет отказ, — будут копиться потоки, соединения, и рано или поздно упадет вообще все. Чтобы подготовиться к таким ситуациям, важно изучить хотя бы <a href="https://sre.google/sre-book/monitoring-distributed-systems/">четыре «золотых сигнала» мониторинга</a> из SRE от Google.</p><p>Совет: возьмите на вооружение парадигму проектирования на отказ. Исходите из того, что в любой момент что угодно может пойти не так. Сеть будет нестабильной, железо начнет падать, интеграции станут работать неправильно. Если изначально придерживаться этого принципа, вы здорово подстрахуете себя завтрашнего. Это всегда спасает, особенно когда получаешь по наследству что-то, что не было спроектировано с учетом этого принципа.</p><p>Сейчас часто используют паттерны, которые помогают поддерживать отказоустойчивость системы:</p><ul><li><b>Circuit Breaker</b> — если сервис спамит ошибками, лучше временно прекратить попытки до него достучаться. Для клиента ничего не изменится, он как получал ошибки, так и будет получать. Но, по крайней мере, можно дать системе возможность восстановиться. А еще лучше — позволить ей переключиться на какой-то резервный канал, например сходить в кэш с неактуальными данными.</li><li><b>Rate Limiter</b> — абсолютно банальная, но необходимая вещь. Нужно ограничивать входящий поток на примерно максимальном уровне от того, который ожидается. Чтобы все не развалилось, если произойдет резкий скачок трафика.</li><li><b>Blue-Green Deployment</b> — значительно снижают на продакшене количество аварий и проблем, связанных с кривыми релизами. Можно не раскатывать новую фичу сразу на все 100 подов, а выкатить ее только на 1% трафика и проверить.</li></ul><p>И это только малая часть паттернов.</p><p>Все это must have для абсолютно любой системы. Даже если у вас низкая нагрузка, она когда-нибудь увеличится. Лучше вовремя предусмотреть это, заранее потратив чуть больше времени и реализовав эти паттерны.</p><h3>Как эффективно работать с инцидентами</h3><p>Начало всех начал в траблшутинге — мониторинг. Здорово, когда разработчики понимают, как устроена их система, и уже вложились в мониторинг: есть дашборд, где можно посмотреть по уровням абстракций основные точки отказа.</p><p>Первый уровень — это application-слой, сами сервисы, которые в подах крутятся в Kubernetes. Нужно проверить, все ли у них хорошо по точкам интеграции — нет ли тайм-аутов. Все ли в порядке у них по железу — по CPU, по памяти, по дискам.</p><p>Если на первом уровне все нормально, нужно опуститься на уровень ниже — либо на виртуалки, на которых Kubernetes развернут, либо на железки, если он развернут на Bare-metal. Недавно мы столкнулись с интересным случаем: виртуалка показывала нормальную загрузку CPU, но физический гипервизор, на котором она крутилась, был загружен на 99%. Естественно, виртуалка страдала, но уровнем выше этого не было видно.</p><p>Совет: если вы вдруг нашли что-то, что еще не мониторится, — это повод поскорее добавить эту метрику, начать ее мониторить и ретроспективно отслеживать.</p><p>Еще одна важная вещь в работе с инцидентами — культура постмортемов. Ретроспективы по каждой аварии пишутся не просто так — их можно свести по категориям и понять, из-за чего чаще всего происходят аварии: например, из-за протухших сертификатов либо человеческого фактора в конфигурации. Категорий причин отказа обычно не так много. С постмортемами проще выработать стратегию технического инженерного развития.</p><p>Вообще, человеческий фактор — это отдельная боль. Все привыкли менять что-нибудь руками: заходить в виртуалки, поправлять конфиг. Чтобы такого было как можно меньше, важно вкладываться в infrastructure as a code и даже everything as a code. В идеале следует стремиться к zero access production — нулевому доступу к продакшену — и все раскатывать через Git, через конфигурации, включая политики безопасности.</p><h2>Культура ответственности и изменение ролей в команде</h2><p>Представим, что происходит инцидент — падают 15 микросервисов. Как должна быть устроена система, которая позволит оперативно справляться с авариями?</p><p>Организационно все достаточно просто — хотя не так просто на земле, при устранении инцидента. Все сервисы должны быть каталогизированы, сгруппированы по командам или продуктовым стримам. Необходима матрица эскалации, позволяющая найти по зоне ответственности человека, которому можно позвонить и попросить подключить необходимых инженеров.</p><p>Подобную конструкцию важно поддерживать в актуальном состоянии. Это часть процесса непрерывности, и в нее надо вкладываться. В крупных компаниях этим занимаются целые отделы, в небольших организациях — отдельный человек, но такая информация всегда должна быть в общем доступе. Иначе время «отскока» после инцидента увеличится кратно.</p><p>Желательно, чтобы в компании был специальный ситуационный центр, в котором сразу можно создать конференцию, если случилась авария, и поделиться информацией, чтобы все подключились к решению проблемы.</p><p>Однако эти организационные моменты еще не гарантируют быстрого решения проблемы. Ключевой фактор — культура компании. На людей часто нападает отстраненность — авария случилась, и все думают: «Кто-нибудь другой разрулит. Я разработчик, ну, что я там сделаю?»</p><p>Многие привыкли жить по старой парадигме: написали код, потестировали, отдали поддержке и забыли. Но культура в команде должна дорасти до такого уровня, когда каждый понимает: я не только разрабатываю или тестирую код, но еще и отвечаю за него на продакшене.</p><p>Из-за этого разрыва в осознании между командами поддержки и разработки возникают конфликты. У каждой разные цели, и зачастую одна команда не понимает, чего хочет другая. Чтобы лучше понять природу этих конфликтов, важно вспомнить про DevOps-культуру и SRE. В их парадигме разработчики не только пишут код, но и деплоят в продакшен.</p><p>Проще говоря, есть два варианта взаимодействия с поддержкой: классический, когда она административно отделена, и SRE-подобный, когда сотрудники «второй линии» прямо интегрированы в команду разработки. Могу сказать, что второй эффективнее.</p><p>При этом не обязательно сливать всех в одну плоскую структуру на уровне административного деления. Достаточно, чтобы люди, даже находясь в разных административных юнитах, работали как команда и коммуницировали постоянно, а не от случая к случаю. Важно, чтобы все были проактивными — если что-то случилось, сразу подрывались и по инструкции пытались устранить проблему.</p><p>Это то самое SRE, о котором пишет Google. Но людей нужно долго обучать такой культуре — это не дело одного месяца. Благодаря такому подходу инженеры, которые раньше были просто разработчиками или аналитиками, глубже осознают свою ответственность за стабильность продакшена. И это действительно правильное направление развития. Потому что и DevOps, и SRE — это в первую очередь культура, а уже во вторую — набор инструментов.</p><h3>Будущее микросервисов: тренд на AI Ops</h3><p>Разработчики уже используют AI как copilot — и это очень мощный инструмент в умелых руках. Он не заменяет инженера, но сильно экономит ему время. Эту помощь от нейросетей очень хочется растянуть и на инфраструктуру, и на эксплуатацию, чтобы получить крутой AI Ops.</p><p>Нейросеть будет находить протухшие сертификаты внутри инфраструктуры, работать инструментом для early warning, подсвечивать риски.Кажется, что все инструменты для этого есть уже сейчас. Надо только, чтобы кто-то сложил этот пазл в рабочее решение.</p><p>Есть прототипы — например, Big Panda или Moocsoft (который был недавно куплен Dell), но пока это точечные решения. Возможно, на горизонте 5–7 лет (скорее 5, чем 10) они станут серьезной частью индустрии и очень мощным прорывом, который упростит разработчикам жизнь.Кроме того, важно, чтобы развивались и более «приземленные» технологии: инструменты контейнеризации, оркестрации, observability, а также APM — Application Performance Monitoring.</p><h3>Инженер остается в центре всего</h3><p>Никакие микросервисы, Kubernetes и AI Ops не спасут, если за системой не стоит инженер, который думает головой, правильно работает руками и отвечает за результат. Важны его навыки, кругозор и культура работы. Именно такие люди превращают набор сервисов в работающий продукт. Все остальное — только инструменты.</p><p>P. S. Если интересно, как мы решаем эти задачи на практике, <a href="https://technologichno.mave.digital/">слушайте </a>(и <a href="https://api.vc.ru/v2.8/redirect?to=https%3A%2F%2Fvkvideo.ru%2Fvideo-145457488_456239831&amp;postId=1982175">смотрите</a>) наш подкаст «Техно.Логично» — там регулярно обсуждаем самое актуальное в IT-сфере.</p>]]></content:encoded>
    </item>
    <item>
      <title>5 инструментов, которые используют айтишные команды</title>
      <link>https://tproger.ru/articles/5-instrumentov--kotorye-ispolzuyut-ajtiwnye-komandy</link>
      <comments>https://tproger.ru/articles/5-instrumentov--kotorye-ispolzuyut-ajtiwnye-komandy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анна Ельцова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/5-instrumentov--kotorye-ispolzuyut-ajtiwnye-komandy</guid>
      <description><![CDATA[<p>Показываем, какими инструментами пользуются внутри айтишных команд и какие можно использовать для себя здесь и сейчас или внедрить в свою команду.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/5-instrumentov--kotorye-ispolzuyut-ajtiwnye-komandy">5 инструментов, которые используют айтишные команды</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Статистика]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[Отладка]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Ruby on Rails]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Adobe]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Маркетинг]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 26 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В статье собрали 5 решений — от трекеров задач и онлайн-досок до комплексных платформ для управления проектами. Инструменты помогут закрывать горящие дедлайны, ускорять разработку и четко распределять задачи — все то, что используют в больших командах. Рассказываем, что делать с этими фичами и как их использовать.</p><h2>1. МояДоска</h2><p><a href="https://moyadoska.com/">«МояДоска»</a> — это российский SaaS-сервис для совместной работы и визуализации идей. У онлайн-доски бесконечный размер: это значит, что вы можете размещать сколько угодно элементов и никогда не упретесь в границу. Так, команды, преподаватели и креативные специалисты могут проводить брейнштормы, планирования, презентации и обучение в одном пространстве.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/4fe2215f-6b29-4d0c-a490-281b2d045ddc.jpeg" alt="" /></figure><h3>Что под капотом</h3><p>Фронт написан на React + PixiJS, а бэк — Node.js + PostgreSQL. Это обеспечивает быстрый и понятный интерфейс и стабильную работу даже при большом объёме объектов на доске. Команда выпускает обновления несколько раз в месяц, а о новинках можно узнать в <a href="https://t.me/moyadoska">Telegram-канале</a> сервиса. Например, в недавнем апдейте появилась возможность превратить фрейм в таблицу или тетрадь за пару кликов, а еще задать нужное число столбцов, колонок, толщину границ и цвет.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/0f1a8489-ffe3-4003-8ecc-09d25bbba3b3.png" alt="" /></figure><p><b>Из главных функций:</b></p><ul><li>Понятный интерфейс</li><li>Совместная работа в реальном времени</li><li>Привычные инструменты: фигуры, стрелки, стикеры, текст, загрузка файлов, маркер, карандаш</li><li>Обрезка фото прямо на доске, воспроизведение аудио, поддержка PDF</li><li>Гибкое управление доступом</li><li>Возможность повторного использования шаблонов</li><li>Поддержка фреймов и создание логичных пространств для разных задач</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/21a6ecbd-a6b5-40c9-ae19-71a85b919c46.png" alt="" /></figure><h3>Переезд на сервис</h3><p>«МояДоска» интегрируется в процессы на разных этапах, упрощая жизнь команде. Например, сама команда сервиса перешла с Miro на свою доску для стратегического планирования. С помощью стикеров и стрелок они построили дерево решений, чтобы лучше расставить приоритеты. А одно маркетинговое агентство перевело все документы и сессии планирования на доску, отказавшись от Google Docs и таблиц. Это ускорило принятие решений: сотрудники работали с данными в одном формате, точно собрались в одном кабинете перед маркерной доской.</p><h2>2. METEOR</h2><p><a href="https://u-meteor.ru">METEOR</a> — инструмент управления проектами. Это трекер задач с дашбордами, досками канбан, диаграммами Ганта и API, который работает в виде веб-приложения как в облаке, так и на своих серверах. Продукт создавался как универсальный центр управления задачами: он объединяет в себе все — от разработки и тестирования до маркетинга и поддержки. Сейчас его используют более 250 команд и свыше 2000 пользователей ежедневно.</p><h3>Что под капотом</h3><p>В основе — стек Ruby on Rails, React и TypeScript, PostgreSQL и Redis, плюс современная инфраструктура на Docker и Kubernetes.</p><p>Система разбита на микросервисы — за фоновую обработку, нотификации и работу с файлами отвечает отдельный функционал. Авторизация построена через OAuth 2.0 (Google, Yandex), а для аналитики используется Posthog и ELK-стек. Мониторинг реализован на Prometheus + Grafana. Обновления выходят каждую неделю, а обратная связь приходит разработчикам METEOR через Telegram-бот.</p><p><b>Вот главные функции:</b></p><ul><li>Гибкие доски задач (Kanban, Scrum) — 6 видов.</li><li>Списки задач с группировками и иерархией.</li><li>Автоматические отчеты (ежедневные/еженедельные сводки).</li><li>Умные напоминания (Telegram-бот, email).</li><li>Глубокая аналитика (время выполнения задач, загрузка команды).</li><li>Потоковая автоматизация процессов</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/60e0eb0a-c1b1-473b-b343-1c4fb1b3fbd6.png" alt="" /><figcaption>Упрощенная схема сущностей системы</figcaption></figure><p>METEOR — мощный инструмент для автоматизации процессов, с триггерами, серверными функциями и ИИ-аналитикой. Он позволяет гибко настраивать сложные операции.</p><p>Все данные анализируются, и внутри самого сервиса можно понять, как работает команда: кто загружен, сколько времени уходит на задачи, где стопперы в процессе.</p><p>Разработчики используют METEOR для линковки задач с pull-requests и контроля бэклога. Менеджеры получают отчеты автоматически и не тратят часы, чтобы собрать всю информацию вручную. QA ведут тест-кейсы и баги в удобных досках, а DevOps отслеживают инциденты и шаги деплоя. Даже HR подключаются — через систему проходят кандидаты и стажеры.</p><h3>Переезд на сервис</h3><p>После внедрения METEOR команды замечают, что продуктивность их работы сильно повышается:</p><ul><li>скорость выполнения задач увеличивается в среднем на 25% — благодаря автоматическим напоминаниям и чётким процессам;</li><li>количество потерянных задач снижается на 70% — исчезают хаотичные чаты и забытые письма;</li><li>на составление отчетов и сбор метрик уходит не 5 часов, а всего 30 минут в неделю;</li><li>а экономия времени — около 75 часов в месяц на команду из 10 человек.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/f3f086f0-5846-4a35-adba-dc4fbe17f1c0.png" alt="" /><figcaption>Карточка задачи</figcaption></figure><p>METEOR не просто помогает контролировать задачи — он становится частью операционного «ядра» команды, избавляя от хаоса, ускоряя работу и делая все немного спокойнее.</p><h2>3. Gitlife</h2><p><a href="https://gitlife.ru">GitLife</a> — это универсальная платформа для хостинга репозиториев и построения полного DevOps-процесса внутри компании. Разработана с прицелом на закрытые контуры, импортозамещение и гибкость — подходит как для современных Git-проектов, так и для инфраструктур, где все еще используется SVN.</p><p>Помимо самого Gitlife, разработчики делают Gitlife AI, в котором есть доступ к топовым ИИ-моделям и инструментам, чтобы разрабатывать ИИ-решения.</p><h3>Что под капотом</h3><p>Внутри Gitlife собраны модули для:</p><ul><li>Кода — репозитории, ветвление.</li><li>Задач — бэклоги, спринты, дашборды.</li><li>Документации — совместное редактирование документов, управление правами.</li><li>Аналитики — карты потока ценности, качество кода, метрики по инженерам.</li><li>Пайплайны — модуль «Конвейер» управляет сборками и CI/CD.</li></ul><p>Gitlife используется ИТ-отделами и R&amp;D-подразделениями в компаниях с высокими требованиями к информационной безопасности. Подходит как для небольших команд, так и для распределённых корпораций с десятками проектов.</p><p>Что решает:</p><ul><li>Безопасный и полностью локальный хостинг исходного кода (Git + SVN)</li><li>Управление задачами и CI/CD в одном месте</li><li>Централизованный доступ, права, аудиты и история изменений</li><li>Полная поддержка DevOps-процессов на российском ПО</li><li>Альтернатива GitHub, GitLab и Bitbucket в условиях ограниченного доступа и санкционных рисков</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/bb3f815f-ce07-4c9d-9243-7ace4b14d5ba.png" alt="" /><figcaption>Создание пайплайна</figcaption></figure><h3>Переезд на сервис</h3><p>Инструмент подходит практически всем командам — от инди-разработчиков до крупных проектов с множеством ролей. Например, гейм-девелопер может разрабатывать персональный проект и хранить код бесплатно, стартап — разрабатывать MVP, а крупный бизнес — управлять большими командами и проектами максимально безопасно.</p><h2>4. Cerebro</h2><p><a href="https://cerebrohq.com/ru/">Cerebro</a> — профессиональная система для совместной работы и управления проектами. Она помогает ставить задачи, планировать этапы, следить за выполнением, обмениваться файлами и комментировать их прямо в системе. Особенно полезна для команд, которые делают VFX, 3D, анимацию или дизайн — но при этом легко адаптируется и под другие команды.</p><p>Платформа охватывает полный цикл — от первых идей и планирования до комментирования финальных шотов (отдельных сцен или кадров в видео/анимации) и соблюдения дедлайнов. Такой подход помогает команде ускорить работу на 20%, сократить время на правки и держать весь процесс под контролем — от начала до сдачи проекта.</p><p>Cerebro подходит для команд от 1 до 1000+ человек с задачами на проекте от 1 до 10000+. Сервис работает с 2009 года, сейчас им пользуются более 400 команд в России и СНГ.</p><h3>Что под капотом</h3><p>Cerebro поддерживает десктоп (Windows, Mac и Linux), веб-версию и мобильное приложение, локальное, облачное и гибридное развертывание. Инструмент построен на клиент-серверной архитектуре — она гибкая, поэтому можно настраивать конфиги исходя из потребностей бизнеса.</p><p>Из технологий:</p><ul><li><b>Backend:</b> C, C++, Python, SQL</li><li><b>Frontend:</b> JS, TypeScript, ReactJS, Qt, PyQt</li><li><b>Мобильные клиенты:</b> React Native</li><li><b>БД: </b>PostgreSQL с проприетарными расширениями + SQLite</li><li><b>Файловое хранилище:</b> Cargador</li><li><b>Плагины: </b>Tentaculo (встраивается в производственные программы)</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/d51c709f-2b9c-4e0b-95c0-2b78d61f5c1e.png" alt="" /></figure><p>Cerebro покрывает весь пайплайн — от идеи до финала. Вот основные возможности сервиса:</p><ul><li>Множественные уровни вложенности задач — подходит для сложных иерархий продакшена</li><li>Планирование с помощью диаграммы Ганта и специального инструмента «План»</li><li>Канбан-доска для визуального контроля задач</li><li>Инструмент «Моё пространство» — для персонализированной фильтрации и отбора задач</li><li>Уровни доступа и ролевое управление</li><li>Расширенная статистика по проектам, командам, сотрудникам</li><li>Совместная работа над большими файлами (видео, изображения, 3D) — Mirada позволяет комментировать, делать подрисовки, оставлять голосовые заметки</li><li>Интеграция с пакетами Adobe, Autodesk и мессенджерами, возможность встраивать в любые пайплайны</li><li>Удобное подключение фрилансеров</li></ul><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/5411ad9d-a74b-46ed-9774-61d60ff69885.png" alt="" /><figcaption>Навигатор и форум</figcaption></figure><h3>Переезд на сервис</h3><p>Обычно внедрение начинается еще на этапе препродакшена — во время разработки концепции и четкого плана действий. Затем система сопровождает проект на всех стадиях, вплоть до постпродакшена (финального тестирования и релиза), где она закрывает 80-100% задач. Cerebro позволяет собирать всё в одном месте: задачи, правки, сроки, бюджеты, загрузку сотрудников и статус проекта в целом.</p><p>После переезда снимается много рутинных задач: больше не нужно вручную назначать исполнителей, комментировать медиаконтент, передавать файлы между программами и так далее. В среднем проекты выполняются на 20% быстрее, без потери качества. В больших студиях объем выпускаемых шотов может вырасти до 20+ тысяч — это уже работает у других клиентов, среди которых СберМаркетинг, Sinners, Black Point и другие. Cerebro также помогает переехать с других такс-трекеров и систем для управления проектами.</p><h2>5. Replit Teams</h2><p><a href="https://replit.com/teams">Replit Teams</a> — это платформа для совместной разработки в реальном времени. По сути, это интегрированная IDE + git-репозиторий + система управления задачами — и все доступно через браузер. Подходит как для командной работы в стартапах, так и для образовательных проектов, хакатонов и небольших продуктовых команд.</p><p>А главная фишка — встроенный ИИ, к которому можно обращаться прямо во время написания кода. Инструмент разработан с акцентом на простоту входа, командную работу и быстрое прототипирование. Поддерживает более 50 языков программирования и позволяет запускать полноценные веб-приложения в облаке.</p><figure><img src="https://media.tproger.ru/user-uploads/101078/2025-06-26/70b00e25-9ec7-4858-911c-b2d7a181104e.png" alt="" /></figure><h3>Что под капотом</h3><p>Внутри Replit Teams есть интерфейсы для:</p><ul><li>Кода — редактор с автокомплитом, подсветкой синтаксиса, терминалом и интеграцией с Git.</li><li>Задач — встроенный таск-менеджер с распределением задач по участникам.</li><li>Общения — встроенные комментарии в коде, возможность ревью и обсуждений.</li><li>CI/DevOps — запуск и отладка приложений без настройки окружения.</li><li>Доступа — гибкие роли, приглашения по ссылке, настройки приватности.</li></ul><h3>Переезд на сервис</h3><p>Replit Teams позволяет моментально начать работу: не нужно ставить зависимости, конфигурировать CI или закупать сервера. Подходит как для быстрой прокачки навыков, так и для реальных командных проектов в продакшене.</p><p>Сейчас инструмент активно используют в стартапах — для быстрого MVP, парного программирования, хакатонов и удаленных командах — как замена локальным IDE и конфигурациям.</p><p>Рассказывайте в комментариях, какими сервисами пользуетесь вы.</p>]]></content:encoded>
    </item>
    <item>
      <title>Эволюция программиста 2005–2025: от CRT-мониторов до квантовых алгоритмов</title>
      <link>https://tproger.ru/articles/evolyuciya-programmista-2005-2025--ot-crt-monitorov-do-kvantovyh-algoritmov</link>
      <comments>https://tproger.ru/articles/evolyuciya-programmista-2005-2025--ot-crt-monitorov-do-kvantovyh-algoritmov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/evolyuciya-programmista-2005-2025--ot-crt-monitorov-do-kvantovyh-algoritmov</guid>
      <description><![CDATA[<p>Эпохи развития программирования в России и в мире. Какие стадии прошли разработчики и к чему пришли в настоящий момент. Прогнозы на будущее. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/evolyuciya-programmista-2005-2025--ot-crt-monitorov-do-kvantovyh-algoritmov">Эволюция программиста 2005–2025: от CRT-мониторов до квантовых алгоритмов</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Обучение программированию]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Stack Overflow]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Ruby]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[jQuery]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Ruby on Rails]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Облачные технологии]]></category>
      <category><![CDATA[macOS]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[Mozilla]]></category>
      <category><![CDATA[WebAssembly]]></category>
      <category><![CDATA[Образование]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Soft Skills]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Обучающие курсы]]></category>
      <category><![CDATA[Дата-центр]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Fullstack]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 25 Jun 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>За последние 20 лет программирование изменилось до неузнаваемости. Если в 2005 году разработчики писали код на PHP 4.0 под мерцание CRT-экранов, то в 2025-м нейросети помогают им генерировать целые модули, а квантовые компьютеры становятся частью исследовательских проектов.</p><p>Эта статья — подробная хроника эволюции программистов: какие языки и технологии они осваивали, как менялись их рабочие места, методы обучения и даже само восприятие профессии. Мы разберем ключевые этапы, от первых веб-гигантов до эпохи совместного программирования с ИИ, и попробуем представить, что ждет нас дальше.</p><h2>2005-2009: Эпоха авторских решений и первых веб-фреймворков</h2><p>В середине 2000-х типичный рабочий инструмент программиста — это громоздкий системный блок с процессором Intel Pentium 4 или новеньким Core 2 Duo. Мониторы с ЭЛТ-трубкой постепенно уступали место LCD-экранам с разрешением 1024×768 — именно на таких дисплеях создавались первые версии Wikipedia и набирающих популярность соцсетей. Оперативная память в 1-2 ГБ считалась нормой, а жесткие диски на 80-160 ГБ часто заполнялись до отказа — проекты редко весили меньше нескольких гигабайт.</p><p>Серьезная разработка велась преимущественно на стационарных компьютерах. Ноутбуки только начинали входить в обиход — их брали в офис, но для реальной работы предпочитали мощные десктопы. Операционная система Windows XP доминировала на рабочих станциях, в то время как серверы чаще всего крутили на Linux — Red Hat Enterprise или Debian.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-13/d5fca723-5450-4b72-8e8d-4cd57627fb99.jpg" alt="" /></figure><p>Среды разработки того времени сегодня кажутся архаичными. Eclipse и NetBeans потребляли гигабайты памяти, Visual Studio 2005 требовала серьезных ресурсов. Многие разработчики предпочитали простые текстовые редакторы вроде Notepad++, а для отладки использовали примитивные методы вроде вывода значений переменных через print. Контроль версий только начинал входить в практику — Git появился в 2005 году, но большинство команд продолжали использовать SVN или вообще заливали файлы по FTP напрямую на продакшен.</p><p>Языковая экосистема этого периода вращалась вокруг трех основных технологий. PHP версий 4 и 4.3 доминировал в веб-разработке — на нем работало около 80% всех сайтов в интернете. Однако его объектно-ориентированные возможности были крайне ограничены до выхода PHP 5 в 2004 году.</p><p>Java в лице J2EE оставалась стандартом для корпоративных решений — банковских систем, крупных порталов и ERP-комплексов. Spring Framework только начинал набирать популярность, а Hibernate упрощал работу с реляционными базами данных. C++ сохранял свои позиции в разработке игр (особенно с использованием Unreal Engine), драйверов и высоконагруженных сервисов.</p><p>Фронтенд-разработка в те годы была невероятно простой по современным меркам. Верстали преимущественно таблицами, а всю динамику реализовывали через jQuery, который появился в 2006 году и быстро вытеснил нативный JavaScript из повседневной практики. AJAX-запросы казались революционной технологией, позволяющей обновлять части страницы без ее полной перезагрузки.</p><p>Обучение программированию в этот период кардинально отличалось от современных подходов. Онлайн-курсы практически отсутствовали. Основными источниками знаний служили бумажные книги:</p><ul><li>«Философия Java» Брюса Эккеля;</li><li>«Совершенный код» Стива Макконнелла;</li><li>«PHP и MySQL. Разработка веб-приложений» Люка Веллинга.</li></ul><p>Русскоязычное сообщество активно обсуждало вопросы разработки на форумах RSDN.ru и CyberForum.ru. В 2008 году появился Stack Overflow, который постепенно стал главной площадкой для профессиональных обсуждений.</p><p>Университетское образование давало хорошую теоретическую базу — алгоритмы, структуры данных, принципы ООП. Однако практическим навыкам приходилось учиться самостоятельно, методом проб и ошибок. Документацию часто скачивали в формате CHM-файлов или читали непосредственно на сайтах вроде php.net и MSDN.</p><p>Типичный стек начинающего разработчика в 2009 году:</p><ul><li>HTML/CSS с jQuery для фронтенда;</li><li>PHP или Ruby on Rails для бэкенда;</li><li>MySQL в качестве базы данных.</li></ul><p>ORM-технологии еще не получили широкого распространения, поэтому SQL-запросы писали вручную. Многие проекты представляли собой монолитные приложения, где весь код хранился в единой кодовой базе без четкого разделения на модули.</p><p><b>Показательный кейс</b>:</p><p>В 2007 году разработчик PHP-приложений из МЭСИ (Москва) столкнулся с типичной для того времени проблемой — SQL-инъекциями. Вместо стандартных решений он создал DLAC (Data Logic Access Component) — обертку для работы с базой данных, которая автоматически экранировала параметры запросов. Это выглядело революционно на фоне типичного кода того периода, где строки запросов часто собирали через конкатенацию с пользовательским вводом.</p><p>Компонент использовал новую для 2005 года технологию Generics в C#. Он генерировал параметризованные запросы, что резко снижало риски взлома.</p><p><i>Разработчики в университетской среде тогда редко задумывались о безопасности — многие проекты содержали уязвимости вроде  </i>SELECT * FROM users WHERE name = ‘.$_POST[‘name’]<i>. </i></p><p><i>DLAC стал локальным спасением для внутренних систем МЭСИ, пока в 2009 году не появился NHibernate — порт популярного Java-фреймворка Hibernate.</i></p><p>Этот кейс хорошо иллюстрирует дух эпохи: отсутствие готовых безопасных решений заставляло программистов изобретать велосипеды. Многие подобные наработки позже легли в основу ORM-библиотек, но тогда они рождались в муках — через пробелы в безопасности и километры самописного кода.</p><h2>2010-2014: Мобильная революция и рассвет JavaScript</h2><p>Начало нового десятилетия ознаменовалось стремительным ростом мобильных технологий. Выход iPhone 4 в 2010 году и Android 2.3 Gingerbread задал новые стандарты мобильной разработки.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-13/7b640694-b2cd-4f03-a68f-51ed138557b2.jpg" alt="" /></figure><p>Программисты массово переходили на MacBook Pro — не столько из-за преимуществ macOS, сколько благодаря появлению Retina-дисплеев в 2012 году, которые кардинально улучшили качество отображения кода.</p><p>Железо продолжало стремительно эволюционировать. Твердотельные накопители (SSD) начали вытеснять традиционные жесткие диски в рабочих станциях. Облачные платформы вроде AWS и Heroku стали реальной альтернативой локальным серверам, которые раньше часто стояли прямо под рабочими столами в офисах. Оперативная память в 8 ГБ стала стандартом для комфортной разработки, а четырехъядерные процессоры ускорили сборку крупных проектов.</p><p>Языковая палитра этого периода значительно расширилась. Objective-C стал основным языком для iOS-разработки и оставался таковым до появления Swift в 2014 году. Python 3 начал набирать популярность благодаря веб-фреймворку Django и научным библиотекам NumPy и Pandas, которые открыли дорогу для анализа данных в массовом сегменте.</p><p>JavaScript пережил настоящий ренессанс — после выхода AngularJS в 2010 и Node.js в 2009 году он перестал быть просто «языком для анимаций на сайте», превратившись в полноценную платформу для fullstack-разработки.</p><p><b>Важный факт</b>. В 2011 году разработчик из Сан-Франциско Райан Даль представил Node.js — среду выполнения JavaScript на стороне сервера. За первые 24 часа после релиза проект собрал 10 000 звезд на GitHub, что для того времени стало рекордом. Многие скептически относились к идее использовать JavaScript вне браузера, но уже через год такие компании как LinkedIn и Walmart перевели части своего бэкенда на Node.js, получив прирост производительности в 2-3 раза по сравнению с традиционными решениями на Java и Ruby.</p><p>Образовательная сфера претерпела значительные изменения. В 2011 году запустилась Coursera с первым массовым курсом по программированию — Machine Learning от Эндрю Ына. В 2012 году в Кремниевой долине открылся Hack Reactor, ставший прототипом современных coding bootcamps (интенсивов по программированию). Эти форматы предложили альтернативу традиционному университетскому образованию, сделав акцент на практических навыках.</p><p>Параллельно в России:</p><ul><li>В 2012 году появился Hexlet — одна из первых русскоязычных платформ с практико-ориентированными курсами по программированию. Особенность: выполнение заданий в реальной среде разработки через браузер. Платформа до сих пор работает: на текущий момент 80% выпускников трудоустраиваются в IT, <a href="https://ru.hexlet.io/blog/posts/hse-research">согласно исследованию ВШЭ</a>. В 2012 этот показатель был еще выше.</li><li>«Нетология» (основана в 2011) к 2013 году запустила курсы по веб-разработке с акцентом на JavaScript и Python, сотрудничая с российскими tech-компаниями. Их модель включала менторство и проектные работы.</li><li>В 2013 году стартовал Stepik — платформа с открытыми курсами от ведущих вузов (ИТМО, МФТИ). Особенность: интерактивные задачи с автоматической проверкой кода, что было прорывом для местного рынка.</li></ul><p>Курс «Введение в Linux» от Stepik (2014) за полгода собрал 50 тыс. студентов — рекорд для Рунета. Задания включали настройку виртуальных серверов, что сразу применялось в работе.</p><p>Эти проекты заложили основу для бума EdTech в России после 2015 года, доказав, что онлайн-формат может давать актуальные навыки быстрее вузов.</p><p>Типичный разработчик среднего уровня в 2014 году:</p><ul><li>понимал принципы REST API;</li><li>начинал осваивать основы DevOps с появлением Docker в 2013;</li><li>экспериментировал с микроконтроллерами вроде Arduino или Raspberry Pi, создавая собственные IoT-устройства.</li></ul><p>В профессиональной среде начал формироваться консенсус о том, что PHP устаревает для сложных коммерческих проектов.</p><h2>2015-2019: Эра больших данных и облачных технологий</h2><p>Аппаратные возможности сделали очередной рывок вперед. Многоядерные процессоры Intel i7 и AMD Ryzen стали стандартом для рабочих станций. 16 ГБ оперативной памяти перестали быть роскошью, а мониторы с разрешением 4К стали доступны широкому кругу разработчиков. В 2015 году появился Visual Studio Code, который быстро обогнал по популярности Sublime Text и Atom благодаря удачному сочетанию функциональности и производительности.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-13/c92b70be-b3eb-4924-a40a-587ed3d43592.png" alt="" /></figure><p>Языковая экосистема продолжила развитие. TypeScript, представленный в 2014 году, предложил решение проблемы масштабируемости JavaScript-кода в крупных проектах. Go от Google, созданный еще в 2009, нашел свою нишу в разработке микросервисов и инструментов оркестрации вроде Kubernetes (2015). Rust от Mozilla начал завоевывать доверие системных программистов благодаря уникальной системе владения памятью.</p><p>JavaScript-сообщество столкнулось с первыми серьезными проблемами. В 2016 году инцидент с пакетом left-pad показал уязвимость экосистемы npm — удаление одного небольшого модуля привело к сбоям в работе тысяч проектов по всему миру. Это заставило разработчиков задуматься о зависимости от сторонних библиотек.</p><p>Типичный senior-разработчик в 2019:</p><ul><li>разбирался в микросервисной архитектуре и понимал, как избежать vendor lock-in (привязки к поставщику) при работе с облачными провайдерами;</li><li>имел опыт работы с React или <a href="http://vue.js">Vue.js</a>;</li><li>знал, что понимание принципов работы алгоритмов становится менее важным, чем развитие soft skills для работы в команде.</li></ul><p>Ключевые технологии этого периода включали Kubernetes, который стал стандартом де-факто для оркестрации контейнеров, а также TensorFlow (2015) и PyTorch (2016), открывшие эру машинного обучения для широкого круга разработчиков. Появились первые серьезные инструменты для работы с большими данными — Apache Spark, Hadoop.</p><p><i>Ключевой момент. В 2016 году Netflix раскрыл детали своего перехода на облачную инфраструктуру AWS. Компания полностью перенесла все сервисы — от рекомендательной системы до биллинга — в облако за семь лет. Главным триггером стала катастрофа 2008 года, когда три дня простоя дата-центра оставили 8,4 млн подписчиков без доступа к сервису. Миграция потребовала перепроектирования архитектуры: инженеры разбили монолит на 500 микросервисов и внедрили Chaos Monkey — инструмент для тестирования отказоустойчивости, который случайно отключал серверы в продакшене.</i></p><p>Этот кейс стал хрестоматийным примером cloud-native подхода. Облачные технологии стали активно использоваться в разработке, а обращение с ними — обязательным навыком для прогеров.</p><h2>2020-2024: AI-assisted разработка и новые парадигмы</h2><p>Пандемия COVID-19 ускорила переход на удаленную работу. Программисты по достоинству оценили макбуки на чипах M1 (2020) за их энергоэффективность и производительность. Домашние офисы оснащались 32-дюймовыми 4К-мониторами и механическими клавиатурами, ставшими своеобразным профессиональным стандартом.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-06-13/65ba41e0-844c-419f-8656-e78905e93540.jpg" alt="" /></figure><p>Языковая палитра продолжала обогащаться. Rust официально вошел в ядро Linux в 2022 году, подтвердив свой статус системного языка нового поколения. Zig появился как современная альтернатива «C» с акцентом на безопасность. WebAssembly (Wasm) позволил запускать ресурсоемкие приложения прямо в браузере, открыв новые возможности для веб-разработки.</p><p>Искусственный интеллект начал проникать в повседневную работу программистов. GitHub Copilot на базе GPT-3, представленный в 2021, изменил сам процесс написания кода, предлагая контекстные подсказки. Low-code платформы вроде Retool упростили создание внутренних инструментов для бизнеса.</p><p>Типичный lead-разработчик в 2024 году:</p><ul><li>умел эффективно работать в гибридных командах (офис + удаленка);</li><li>автоматизировал рутинные задачи через ChatGPT API;</li><li>следил за развитием квантовых вычислений, хотя практическое применение пока оставалось ограниченным.</li></ul><p><i>Ключевой момент. В 2023 году GitHub Copilot, разработанный совместно с OpenAI, стал катализатором перемен в индустрии. За первый год после релиза инструмент использовали более 1,3 млн разработчиков — каждый десятый подписчик GitHub. Система анализировала контекст кода и предлагала целые функции: например, при написании SQL-запроса она автоматически генерировала соответствующую модель данных на Python. Amazon внедрил аналогичный инструмент Amazon Q Developer для внутренних команд — по заявлению CEO Энди Джесси, это сэкономило компании 4,500 человеко-лет работы и $260 млн ежегодно.</i></p><p><i>Но были и курьезы. В 2024 году разработчик из Берлина случайно отправил в продакшен код, полностью сгенерированный Copilot. Система использовала фрагмент из GPL-лицензированной библиотеки, что нарушило политику компании по открытому ПО. Инцидент заставил пересмотреть процессы ревью: теперь 78% команд требуют ручной проверки AI-кода перед мержем (слиянием).</i></p><p><i>Параллельно выяснилось, что Copilot в 40% случаев предлагает уязвимый код при работе с СУБД — это привело к взлому API стартапа через SQL-инъекцию. Такие кейсы показали, что ИИ пока не заменяет программистов, а требует от них новых навыков — критического анализа машинных предложений и понимания юридических аспектов кода.</i></p><h2>2025: Современное состояние профессии</h2><p>Современные рабочие станции программистов оснащены ноутбуками с процессорами Apple M4 (3 нм) или Windows-машинами на Snapdragon X Elite. Мониторы с разрешением 8К используются для разработки AR-приложений, а OLED-экраны с HDR стали стандартом для работы с графикой. Появляются первые экспериментальные IDE с нейроинтерфейсами, способные предсказывать код на основе анализа мозговой активности.</p><p>Среди языков программирования выделяется Mojo (2023) — «Python для GPU», набирающий популярность в сфере машинного обучения. Carbon как потенциальный наследник C++ пока остается в тени Rust. Квантовые языки вроде Q# и Cirq интересуют в основном энтузиастов и исследователей.</p><p>Профессия претерпела значительные изменения. ИИ стал не конкурентом, а помощником — по некоторым оценкам, около 60% рутинного кода в 2025 году (тесты, документация) генерируется автоматически. Знание английского языка стало важнее знания сложных алгоритмов — без него невозможно эффективно работать с современными AI-инструментами. Понятие «fullstack-разработчик» трансформировалось — теперь оно подразумевает владение фронтендом, одним бэкенд-языком и основами машинного обучения.</p><p>За два десятилетия программисты прошли путь от одиночек за CRT-мониторами до участников глобальных распределенных команд. Если в 2005 ключевым навыком было умение написать работающий код, то в 2025 главное — способность эффективно взаимодействовать с ИИ-ассистентами. Однако основы профессии остались неизменными — логическое мышление, способность к абстракции и желание автоматизировать рутинные задачи.</p><p>Будущее обещает новые трансформации. К 2030 году нейроинтерфейсы смогут заменить традиционные устройства ввода, а квантовые компьютеры — перевернуть основы криптографии. Но пока актуальными остаются проверенные временем принципы: изучать перспективные технологии (вроде Rust и Mojo), осваивать работу с ИИ и, конечно, совершенствовать главный навык любого программиста — умение быстро и грамотно гуглить.</p><p>Ты уже программист, если читаешь это! Больше о кодинге <a href="https://t.me/+ezugB7gnIEsxNGMy">тут</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как сделать свой первый сайт на HTML и CSS: пошаговая инструкция</title>
      <link>https://tproger.ru/articles/kak-sdelat-svoj-pervyj-sajt-na-html-i-css--powagovaya-instrukciya</link>
      <comments>https://tproger.ru/articles/kak-sdelat-svoj-pervyj-sajt-na-html-i-css--powagovaya-instrukciya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-sdelat-svoj-pervyj-sajt-na-html-i-css--powagovaya-instrukciya</guid>
      <description><![CDATA[<p>Как сделать на HTML и CSS. Показываем, какими навыками нужно обладать для создания сайтов. Рассматриваем пошаговую инструкцию и основные нюансы ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-sdelat-svoj-pervyj-sajt-na-html-i-css--powagovaya-instrukciya">Как сделать свой первый сайт на HTML и CSS: пошаговая инструкция</a>»</p>]]></description>
      <category><![CDATA[Интернет]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Веб-разработка]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[MySQL]]></category>
      <category><![CDATA[Google]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[WordPress]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 23 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Tilda, Wix, WordPress — конструкторы сайтов кажутся простым решением. Согласны, на готовых блоках можно сделать интернет-магазин за 1 час. Но учтите, что в конструкторе непонятно, как всё работает изнутри. Вы не поймёте, почему сайт долго грузится, как увеличить кнопку для смартфонов и т. д.</p><p><b>Выбрали путь программиста</b>? Значит навсегда запомните, когда опубликовали первый самописный сайт. Откосить не получится: мы сразу перейдём к практике — к концу статьи у вас будет ссылка на сайт-визитку.</p><p><b>Мало времени</b>? Выделите 10 минут — мы используем только HTML и CSS.</p><p>Вы узнаете:</p><ul><li>как подключать стили,</li><li>как верстать блоки,</li><li>как опубликовать сайт.</li></ul><p>Возможно сейчас вы убедитесь, что веб-разработка — это ваше призвание, и захотите продолжить обучение профессии.</p><h2>Шаг 1. Подготовим инструменты и папку проекта</h2><p>Сайт можно писать и в блокноте. Это как забивать гвозди камнем – работает, но зачем мучиться? <b>Редактор кода подсвечивает синтаксис, подсказывает команды и сразу указывает на ошибки</b>.</p><p>Новичкам рекомендуем ставить <b>Visual Studio Code (VS Code)</b>. Он бесплатный, не тормозит и понимает любой код. Плюс у него огромное сообщество — если нужно установить плагин или увеличить шрифт, ответ на вопрос уже есть в интернете.</p><p><a href="https://code.visualstudio.com/download">Скачайте VS Code с официального сайта</a>.</p><h2>Как устроен веб-проект</h2><p><b>Сайт</b> — это папка с файлами для браузера.</p><p>HTML-файл содержит текст и разметку страницы, CSS-файл — правила оформления. Браузер берёт эти два файла и показывает веб-страницу.</p><p>Основной файл сайта обычно называют <i>index.html</i>. Стили хранятся в <i>style.css</i>.</p><p>Кроме файлов HTML и CSS, в нашем проекте будут папки:</p><ul><li><i>img </i>— для картинок.</li><li><i>fonts </i>— для шрифтов.</li></ul><p><b>Создайте на рабочем столе папку с названием сайта</b>, например <i>first-site</i>, и соберите начальную структуру — это займёт 1 минуту.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/5ba1fa76-6d96-4b7b-aac4-633a4d251a7e.jpg" alt="" /><figcaption>Типичная структура веб-проекта</figcaption></figure><h2>Шаг 2. Создадим базовую HTML-страницу</h2><p>В VS Code есть удобная фишка: наберите символ «!» и нажмите Tab. Редактор <b>автоматически </b>создаст базовую структуру HTML-документа.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/3fbcd34e-cf7c-473c-b0cf-84260e9aa42c.jpg" alt="" /><figcaption>Структура HTML-документа в VS Code</figcaption></figure><p>Как читать структуру:</p><ul><li><i></i><b>&lt;!DOCTYPE html&gt; </b>—<b> </b>сообщает браузеру, что это HTML-документ.</li><li><i></i><b>&lt;html&gt; </b>—<b> </b>корневой элемент, внутри которого живёт страница.</li><li><i></i><b>&lt;head&gt; </b>—<b> </b>служебная информация, которую не видно на странице.</li><li><i></i><b>&lt;body&gt; </b>—<b> </b>то, что увидят пользователи на странице.</li></ul><p><b>Измените Document на название вашего сайта</b> — это текст, который появится во вкладке браузера.</p><p>Добавим контент в &lt;body&gt;:</p><p>Мы не комментируем каждый тег и атрибут, потому что это тема для отдельной статьи. Наша задача — показать, как быстро собрать сайт и выложить его в интернет.</p><p><b>Сохраните HTML-файл и откройте его в браузере</b>. Поздравляем, ваша первая веб-страница готова! Она недоступна другим пользователям, но мы это исправим.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/c3588fae-fe59-447a-9045-d7f7ada0161c.jpg" alt="" /><figcaption>HTML-страница без стилей</figcaption></figure><h2>Шаг 3. Подключим стили CSS</h2><p>Сейчас сайт выглядит странно — чёрный текст на белом фоне. Так не пойдёт, добавим стилей в файле <i>style.css</i>.</p><p>CSS можно писать внутри HTML или в отдельном файле. Мы выберем второй вариант, потому что это удобнее.</p><p>Подключим CSS к HTML. В секции <i></i> вашего <i>index.html</i> добавьте строчку:</p><p>Тег <i> </i>говорит браузеру: «Возьми файл <i>style.css</i> из той же папки и примени все стили к этой странице».</p><p>Добавьте в <i>style.css </i>первое правило:</p><p><b>Сохраните оба файла </b>—<b> HTML и CSS</b>. Обновите страницу в браузере.</p><p>Фон поменял цвет? Значит, CSS подключён правильно. Можете вернуть белый фон или оставить голубой — далее мы добавим более интересные стили.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/95a0bd53-c4a5-4139-92c5-1c1fdda3916b.jpg" alt="" /><figcaption>Применили стиль к фону страницы</figcaption></figure><h2>Шаг 4. Подключим шрифты</h2><p>Есть три способа избавиться от дефолтного Times New Roman:</p><ul><li>Google Fonts — бесплатная библиотека шрифтов от Google.</li><li>Локальные файлы — загружаете шрифт на свой сервер.</li><li>Системные шрифты — используете то, что уже есть на компьютере пользователя.</li></ul><p><b>Для первого сайта на HTML и CSS рекомендуем Google Fonts</b> — это просто, быстро и надёжно.</p><p>Перейдите на <a href="http://fonts.google.com">fonts.google.com</a> и выберите шрифт. Популярные варианты: Roboto, Open Sans, Lato, Montserrat. Нажмите на понравившийся шрифт, выберите начертания (тонкий, обычный или жирный), скопируйте код подключения и вставьте в <i>head</i>.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/19c3409f-ea46-42fb-a56d-2680820d1fb3.jpg" alt="" /><figcaption>Подключение всех начертаний Montserrat в Google Fonts</figcaption></figure><p>На Google Font собраны популярные шрифты. Если этого мало, нужно скачать шрифт (.woff, .woff2, .ttf) и поместить в папку fonts.</p><p>Путь к файлу указывается относительно CSS-файла. Подключаем начертания через <i>@font-face:</i></p><p>Теперь используйте шрифт в CSS:</p><p>Для каждого начертания (обычный, жирный, курсив) нужно отдельное правило <i>@font-face</i>.</p><h2>Шаг 5. Сверстаем блоки</h2><p>Замените содержимое вашего <i>style.css</i> на этот код:</p><p>Что мы делаем:</p><ul><li>Убираем стандартные отступы браузера и задаём голубой фон.</li><li>Центрируем карточку по всей странице с помощью flexbox.</li><li>Создаём белую карточку с тенью и скруглёнными углами.</li><li>Делаем круглый аватар с рамкой.</li><li>Стилизуем текст и кнопку.</li><li>Добавляем эффект при наведении на кнопку.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/d89d9cf8-b178-4794-bd56-00997cf45750.jpg" alt="" /><figcaption>Простая визитка на HTML и CSS с анимированной кнопкой и ссылкой на Телеграм</figcaption></figure><h2>Шаг 6. Загрузим сайт на хостинг</h2><p>Чтобы визиткой можно было поделиться, нужно загрузить файлы на <b>хостинг</b>. Это сервер, который работает круглосуточно и показывает ваш сайт всем желающим. Посмотреть, как это работает, можно на бесплатном тарифе.</p><p>Заходим на сайт хостинга (Beget, Hostiman, InfinityFree) и регистрируемся. После подтверждения email вы попадёте в панель управления. Система предложит выбрать домен — берите бесплатный типа название.<b>fwh.is</b>.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/26a6c762-28f6-4c16-9db2-9963b1468a14.jpg" alt="" /><figcaption>Выбор бесплатного поддомена на InfinityFree</figcaption></figure><h2>Загружаем файлы на сервер</h2><p>После создания аккаунта появится доступ к файловому менеджеру. Через веб-интерфейс можно управлять файлами на сервере прямо из браузера. Перейдите в папку <i>htdocs </i>— это корневая директория вашего сайта, куда нужно загружать структуру.</p><p>Удалите лишние файлы по типу <i>default.php</i> и загрузите ваши файлы: <i>index.html</i>, <i>style.css</i>,  <i>папки img и fonts</i>. Основной <i>index.html </i>должен лежать прямо в <i>htdocs</i>, а не во вложенной папке — иначе сайт не откроется.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/142fed8d-33ff-4d1a-bc2c-0bb97effdbb8.jpg" alt="" /><figcaption>Менеджер файлов InfinityFree</figcaption></figure><p>Более продвинутый способ — использовать FTP-клиент <a href="https://filezilla-project.org/">FileZilla</a>. В панели хостинга найдите FTP-данные и подключитесь через программу. Это удобнее для больших проектов, но для первого сайта веб-менеджера будет достаточно.</p><h2>Проверяем результат</h2><p>Через несколько минут после загрузки ваш сайт будет доступен по адресу. Откройте его в браузере — если всё сделано правильно, увидите свою страницу. Если что-то не работает, проверьте, что <i>index.html</i> лежит в корне <i>htdocs</i>, а <i>style.css</i> загружен в ту же папку.</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/28368cd4-887b-41fe-8930-37b51e3875e2.jpg" alt="" /><figcaption>Опубликованная визитка на HTML и CSS</figcaption></figure><h2>Реальность бесплатного хостинга</h2><p>Для изучения основ и создания первых проектов на HTML и CSS это отличный вариант. Регистрация занимает 1 минуту, никаких настроек, можно сразу экспериментировать и видеть результат.</p><p><b>Помните про обратную сторону медали</b>. Бесплатные хостинги жёстко ограничивают ресурсы — трафик, место на диске, нагрузку на сервер. Иногда вставляют рекламу на ваш сайт. Серверы часто «падают» — страница может быть недоступна по несколько часов.</p><p>Самая большая проблема — нестабильность бизнеса. Бесплатные хостинги закрываются без предупреждения. Сегодня ваш сайт работает, а завтра компания решила, что бесплатные услуги больше не окупаются.</p><p>Скрытые ограничения:</p><ul><li>В рекламе бесплатные хостинги обещают безлимитный трафик и неограниченное место, но вынуждают переходить на платный тариф после 100 посетителей в день.</li><li>Про индексацию можно забыть — поисковые системы не пропустят бесплатные поддомены на первые страницы выдачи.</li><li>На бесплатных хостингах слабая защита. Ваш сайт могут использовать для размещения вредоносного кода, а вы об этом даже не узнаете.</li></ul><h2>Когда стоит переходить на платный хостинг</h2><p>Бесплатный хостинг — это тренировочная площадка, а не постоянное решение. Если планируете заниматься веб-разработкой, создавать портфолио или коммерческие проекты, лучше сразу инвестировать в качественный хостинг и собственный домен.</p><p>Самый простой домен стоит 200-1000 рублей/год, а базовый хостинг — 100-300 рублей/месяц. Плюс получите доступ к технологиям (PHP, MySQL), более стабильную работу и нормальную техподдержку. <b>Начните с минимального тарифа </b>— <b>его хватит на тренировочные проекты, а потом можно масштабироваться</b>.</p><h2>Куда двигаться дальше?</h2><p>Мы создали первый сайт и опубликовали его в интернете. Если повторяли за нами то поздравляем — многие останавливаются на теории, а вы дошли до результата. Теперь у вас есть понимание основ:</p><ul><li>как работает HTML,</li><li>зачем нужен CSS,</li><li>что такое хостинг и домен.</li></ul><p><b>Следующий шаг</b> — подробнее изучить CSS. Сайт-визитка из примера нормально отображается только на больших экранах. Однако 60% пользователей <a href="https://gs.statcounter.com/platform-market-share/desktop-mobile-tablet">заходит</a> с телефонов. Изучите медиазапросы, они применяются только на определённых размерах дисплея.</p><p>Подробнее про адаптив рассказал старший фронтенд-разработчик Никита Кушнарёв: <a href="https://tproger.ru/articles/esli-vy-umeete-pokrasit-knopochku-no-hotite-uznat-bolshe-o-vjorstke-veb-prilozhenij">Если вы умеете покрасить кнопочку, но хотите узнать больше о вёрстке веб-приложений</a>.</p><p>Попробуйте переделать карточку так, чтобы она нормально выглядела на телефоне. Уменьшите размеры, измените отступы, сделайте кнопку на всю ширину. Потом изучите <a href="https://tproger.ru/articles/css-grid-i-flexbox--evolyuciya-maketov-v-veb-dizajne">Flexbox и CSS Grid</a> — современные способы вёрстки макетов.</p><p>Когда почувствуете уверенность в CSS, пора знакомиться с <b>JavaScript</b>. Это язык программирования, который делает сайты интерактивными. Сложные анимации, всплывающие окна, динамическое изменение контента — это JS. Предупреждаем, он сложнее HTML и CSS. В нём есть функции, условия, циклы — всё то, что пугает новичков.</p><p>Подробнее про JavaScript: <a href="https://tproger.ru/articles/javascript-s-nulja-dorozhnaja-karta">Разработка на JavaScript с нуля: дорожная карта</a>.</p><p><b>Изучайте инструменты разработчика</b> в браузере. Нажмите F12 на любом сайте — откроется интерфейс для просмотра структуры сайта, отладки JS, тестирования адаптива. Смотрите, как устроены другие сайты, изучайте чужой код.</p><p>Самое время узнать о большем количестве инструментов программиста. Читайте в нашем <a href="https://t.me/+N9AAs1a82VA1MDMy">тг-канале!</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Как мы строим агрегатор финансовых продуктов в Казахстане: история Finance.kz</title>
      <link>https://tproger.ru/articles/kak-my-stroim-agregator-finansovyh-produktov-v-kazahstane--istoriya-finance-kz</link>
      <comments>https://tproger.ru/articles/kak-my-stroim-agregator-finansovyh-produktov-v-kazahstane--istoriya-finance-kz?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Жандос Байдильденов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-my-stroim-agregator-finansovyh-produktov-v-kazahstane--istoriya-finance-kz</guid>
      <description><![CDATA[<p>Как из обычного сайта-витрины вырастить финтех-продукт? Расскажу, как строится агрегатор финансовых продуктов в Казахстане.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-my-stroim-agregator-finansovyh-produktov-v-kazahstane--istoriya-finance-kz">Как мы строим агрегатор финансовых продуктов в Казахстане: история Finance.kz</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[SEO]]></category>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Финтех]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Техподдержка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 22 Jun 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Я — Жандос, руководитель проекта <a href="https://finance.kz">Finance.kz</a>. Последний год активно развиваем агрегатор финансовых продуктов в Казахстане, и за это время рынок изменился кардинально. Хочу поделиться опытом создания финтех-решения с нуля и рассказать, как мы конкурируем с зарубежными игроками за счёт глубокой локализации.</p><h2>Откуда началось: мой путь в финтех</h2><p>До Finance.kz я работал в казахстанских финтех-проектах — bai.kz и finbee.kz. Там понял, что рынок агрегаторов в Казахстане находится в зачаточном состоянии. Пользователи мучились, сравнивая предложения банков вручную, а сами финансовые организации не умели эффективно работать с цифровыми каналами привлечения клиентов.</p><p>Finance.kz существовал уже более 3 лет, но работал как классический сайт-витрина. Когда я пришёл в проект год назад, стало ясно: нужно полностью переосмыслить подход и создать технологическое решение нового поколения.</p><h2>Состояние рынка: от монополии к жёсткой конкуренции</h2><p>Казахстанский рынок агрегаторов финансовых продуктов переживает бум. Ещё два года назад здесь было 2-3 локальных игрока с простейшим функционалом. Сегодня ситуация кардинально изменилась — зашли зарубежные команды: vbr.kz, fintree.kz, moneypanda.com и другие.</p><p>Эти компании привозят готовые решения, которые хорошо работали в России или других рынках. На первый взгляд их продукты выглядят более зрелыми — красивые интерфейсы, отработанные воронки конверсии. Но у импортных решений есть критический недостаток: они плохо адаптированы под специфику казахстанского рынка.</p><h2>Технологические вызовы: интеграция с госсервисами и банками</h2><p>Главная боль при разработке агрегатора в Казахстане — это интеграции. В отличие от рынков СНГ, здесь нельзя обойтись простым партнёрским трафиком. Пользователи хотят получить продукт онлайн, полностью, без походов в офисы.</p><h3>API-интеграции с банками и МФО</h3><p>За год мы реализовали прямые API-интеграции с крупнейшими игроками рынка. Это означает, что пользователь может не просто сравнить условия кредитов, но и подать заявку, пройти скоринг и получить одобрение, не покидая наш сайт.</p><p>Техническая сложность — в разнородности API. Каждый банк использует собственные протоколы, форматы данных и методы аутентификации. Пришлось создать унифицированный слой-адаптер, который «переводит» наши запросы в формат, понятный конкретной финансовой организации.</p><h3>Интеграция с госорганами</h3><p>Finance.kz интегрируется с государственными сервисами eGov и Палаты предпринимателей (ПКБ). Это позволяет автоматически подтягивать справки о доходах, данные о трудоустройстве и другие документы, необходимые для получения кредита.</p><p>Работа с госAPI — отдельная история. Протоколы меняются, документация часто устаревает, а техподдержка работает в режиме «как получится». Но результат того стоит: время оформления кредита сокращается с нескольких дней до 15-30 минут.</p><h2>Архитектура продукта: ставка на микросервисы</h2><p>При проектировании архитектуры Finance.kz мы отказались от монолитного подхода в пользу микросервисов. Это решение диктовалось спецификой агрегатора — нам нужно было обеспечить высокую доступность при интеграции с десятками внешних систем.</p><h3>Backend</h3><p>Основные сервисы написаны на Node.js с использованием Express.js. Для работы с базами данных используем PostgreSQL для транзакционных данных и Redis для кэширования. Очереди сообщений реализованы через RabbitMQ — это критично для обработки заявок пользователей.</p><p>Отдельно выделили сервис интеграций, который отвечает за взаимодействие с внешними API. Он построен по принципу circuit breaker — если один из банков не отвечает, это не ломает работу всего агрегатора.</p><h3>Frontend</h3><p>Фронтенд построен на React с использованием Next.js для серверной отрисовки. Это важно для SEO — львиная доля трафика приходит из поисковых систем по запросам типа «кредит онлайн».</p><h2>Стратегия «единого окна»: от поиска до получения</h2><p>Наша главная идея — превратить агрегатор из витрины в полноценный финтех-сервис. Пользователь должен получить продукт полностью онлайн: от сравнения условий до перечисления денег на карту.</p><p>Для этого мы реализовали несколько ключевых функций:</p><ul><li>Умный подбор продуктов на основе данных пользователя и машинного обучения</li><li>Предварительный скоринг для оценки вероятности одобрения ещё до подачи заявки</li><li>Автоматическое заполнение анкет с подтягиванием данных из госсервисов</li><li>Отслеживание статуса заявки в реальном времени</li></ul><h2>Монетизация: CPS как основа устойчивого бизнеса</h2><p>Мы работаем по модели CPS (Cost Per Sale) — получаем комиссию только за успешно выданные продукты. Для кредитов это 2% от суммы, для микрозаймов — фиксированная сумма от 7 до 15 тысяч тенге.</p><p>Такая модель выгодна всем участникам: банки платят только за результат, пользователи получают продукт бесплатно, а мы мотивированы повышать качество трафика и конверсию.</p><h2>Конкурентные преимущества: локализация против красивых интерфейсов</h2><p>Главное отличие Finance.kz от зарубежных конкурентов — интеграция в казахстанскую финтех-экосистему. Пока они тратят месяцы на адаптацию готовых решений, мы изначально строили продукт под местную специфику.</p><h3>Что даёт локальный подход:</h3><ul><li>Знание рынка: мы понимаем особенности работы казахстанских банков и МФО</li><li>Связи с регуляторами: легче договариваться об интеграциях с госорганами</li><li>Техническая экспертиза: наша команда уже прошла путь интеграции с местными API</li><li>Гибкая настройка продукта под изменения законодательства и требований ЦБ</li></ul><h3>Результаты и метрики</h3><p>За год активного развития мы достигли:</p><ul><li>150 000 уникальных пользователей в месяц</li><li>Интеграция с 15+ финансовыми организациями</li><li>Конверсия заявка-выдача на уровне 35-40% (против 15-20% у конкурентов)</li><li>Средний чек по кредитам — 1,2 млн тенге, по микрозаймам — 85 тысяч</li></ul><h2>Планы на будущее: от агрегатора к экосистеме</h2><p>Ближайшие 1-2 года будут критичными для всего рынка. Мы видим несколько ключевых направлений развития:</p><h3>Расширение продуктовой линейки</h3><p>Планируем добавить страхование, депозиты и инвестиционные продукты. Цель — стать единой точкой входа для всех финансовых потребностей пользователя.</p><h3>Внедрение ИИ и машинного обучения</h3><p>Работаем над персонализацией предложений и предиктивной аналитикой. Хотим научиться предлагать продукты до того, как пользователь их осознанно найдет.</p><h3>Международная экспансия</h3><p>Рассматриваем возможность выхода на рынки Узбекистана и Кыргызстана. Наша технологическая платформа легко масштабируется на соседние рынки.</p><h3>Собственные финансовые продукты</h3><p>В долгосрочной перспективе планируем получить лицензию МФО и предлагать собственные займы наиболее качественным клиентам.</p><h2>Уроки и выводы</h2><p>Главный урок последнего года: в финтехе побеждает не тот, у кого красивее интерфейс, а тот, кто лучше решает реальные проблемы пользователей. Красивый дизайн можно скопировать за месяц, а на создание качественной технологической интеграции уходят годы.</p><p>Второй важный момент — команда решает всё. Мы собрали людей, которые понимают как технологии, так и специфику финансового рынка. Это даёт нам фору перед конкурентами, которые пытаются адаптировать готовые решения силами удалённых команд.</p><p>Рынок агрегаторов в Казахстане только формируется, и впереди ещё много интересных вызовов. Уверен, что следующие два года покажут, кто готов строить долгосрочный бизнес, а кто просто пытается заработать на хайпе.</p>]]></content:encoded>
    </item>
    <item>
      <title>Как защитить pet-проект почти бесплатно, но эффективно</title>
      <link>https://tproger.ru/articles/kak-zashhitit-pet-proekt-pochti-besplatno--no-effektivno</link>
      <comments>https://tproger.ru/articles/kak-zashhitit-pet-proekt-pochti-besplatno--no-effektivno?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Светлана Гринь]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-zashhitit-pet-proekt-pochti-besplatno--no-effektivno</guid>
      <description><![CDATA[<p>Как эффективно защитить pet-проект: управление секретами, логирование, бэкапы, локальные туннели и другие базовые правила безопасности
</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-zashhitit-pet-proekt-pochti-besplatno--no-effektivno">Как защитить pet-проект почти бесплатно, но эффективно</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Slack]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Pet-проекты]]></category>
      <category><![CDATA[Мессенджер]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Взлом]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Grafana]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 17 Jun 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Pet-проекты помогают развивать профессиональные навыки и воплощать собственные идеи, но не стоит забывать об их информационной безопасности. Делать сервис и не думать об инфобезе — всё равно что строить дом без фундамента: выглядит добротно, но всё может рухнуть в самый неожиданный момент. Разберём, как недорого и эффективно защитить проект.</p><h2>Что такое pet-проект и зачем его защищать</h2><p><b>Pet-проект</b> (от английского pet — «домашний питомец») — тренировочный проект, который разработчик создаёт в свободное время по собственному желанию. Обычно их делают, чтобы освоить новую технологию, пополнить портфолио или поучаствовать в хакатонах.</p><p>Такие проекты часто воспринимают как что-то «несерьёзное», но пренебрежение информационной безопасностью может привести к неприятным последствиям. Злоумышленники используют уязвимости pet-проектов для получения доступа к ресурсам разработчика, кражи данных и будущих атак на более крупные цели.</p><p>Кроме того, защита pet-проекта — важный навык, который высоко ценится работодателями.</p><p>Рассмотрим основные правила кибербезопасности, которые нужно учитывать при работе над pet-проектом.</p><h2>Безопасное управление секретами</h2><p><b>Секреты</b> — это чувствительные данные, такие как пароли, токены доступа, ключи API, SSH-ключи, сертификаты и другие данные, которые обеспечивают аутентификацию и шифрование. Если добавить секреты в код, злоумышленники могут получить полный контроль над вашей инфраструктурой.</p><h3>Какие правила нужно соблюдать</h3><ul><li>Не храните секреты в коде. Храните секреты в отдельных файлах env. и добавьте эти файлы в .gitignore, чтобы они не попадали в репозиторий.</li><li>Придерживайтесь принципа минимальных привилегий. Каждый сервис должен иметь только те права, которые необходимы для выполнения своих задач.</li><li>Регулярно обновляйте секреты. Меняйте токены и пароли периодически, особенно после обнаружения утечек или изменений в проекте.</li><li>Используйте менеджеры секретов. Популярные сервисы: Doppler, HashiCorp Vault, AWS Secrets Manager, 1Password Developer Tools.</li><li>Мониторьте утечки. Можно использовать такие инструменты, как GitGuardian, TruffleHog, Gitleaks.</li><li>Шифруйте секреты. Используйте библиотеки типа cryptography в Python и подключайте шифрование на уровне операционной системы.</li></ul><h2>Безопасность CI/CD</h2><p><b>Пайплайн CI/CD</b> (Continuous Integration / Continuous Delivery) — автоматизированный процесс сборки, тестирования и развёртывания приложений. Он помогает автоматически интегрировать код и деплоить его на различные среды.</p><p>Если злоумышленник получит доступ к пайплайну, он может внедрить вредоносный код в ваше приложение, остановить весь процесс разработки или развёртывания, украсть данные пользователей и т.д.</p><h3>Способы защиты пайплайна</h3><ul><li>Моделируйте угрозы. Оцените, какие угрозы наиболее вероятны на каждом этапе пайплайна: от коммита кода до деплоя на сервер.</li><li>Проверяйте зафиксированный код. Используйте статический анализ кода для автоматического поиска уязвимостей.</li><li>Защитите Git-репозитории. Настройте двухфакторную аутентификацию (2FA), ограничьте доступ к репозиториям, используйте обязательную проверку пул-реквестов двумя разработчиками.</li><li>Изолируйте пайплайн. Не запускайте его на том же сервере, где крутится ваше продакшн-приложение.</li></ul><p>Дополнительно стоит шифровать секреты в пайплайне и минимизировать их передачу между этапами сборки.</p><h2>Сервисы мониторинга и логирования</h2><p><b>Логирование</b> — запись событий, ошибок и других данных о работе приложения в специальные файлы или базы данных. По сути, это дневник.</p><p><b>Мониторинг</b> — наблюдение за состоянием приложения, инфраструктуры или сервисов в реальном времени для своевременного выявления падения сервера, роста ошибок и других проблем.</p><p>Анализ логов помогает выявлять баги, попытки несанкционированного доступа, долгие запросы, ошибки базы данных. Мониторинг позволяет мгновенно реагировать на сбои, а также с его помощью вы узнаете, хватает ли приложению серверных мощностей.</p><h3>Примеры популярных сервисов</h3><p><a href="https://logtail.ru/">Logtail </a>— простой инструмент для сбора и анализа логов, есть бесплатный тариф.</p><p><a href="https://github.com/paper-trail-gem/paper_trail">Papertrail</a> — удобный сервис для быстрого поиска по логам, бесплатный план для небольших проектов (10 Мб в день).</p><p><a href="https://docs.sentry.io/">Sentry</a> —  хорош для отслеживания ошибок в приложениях на клиентской стороне и сервере.</p><p><a href="https://betterstack.com/">BetterStack</a> — мониторинг доступности сайтов и серверов с бесплатными уведомлениями об инцидентах по почте, через SMS и Slack.</p><p><a href="https://grafana.com/pricing/">Grafana Cloud Free</a> — мониторинг с красивыми дашбордами, бесплатный лимит ресурсов до 10 тыс. серий данных, 50 ГБ трафика.</p><p><a href="https://prometheus.io/">Prometheus</a> и <a href="https://grafana.com/">Grafana</a> — Prometheus собирает метрики, Grafana их визуализирует.</p><p><a href="https://uptimerobot.com/">UptimeRobot</a> — проверка доступности вашего проекта каждые 5 минут, бесплатный тариф на 50 мониторингов.</p><h2>Бэкап и восстановление данных</h2><p><b>Бэкап</b> — это создание резервной копии данных, которую можно использовать для восстановления в случае утраты или повреждения оригиналов. Может показаться, что для pet-проекта это излишне, однако от случайных удалений данных, взломов серверов, утечек данных никто не застрахован. А ещё можно откатиться к рабочей версии, если будут ошибки в коде и деплойменте.</p><h3>Как сделать бэкап пошагово</h3><ol><li>Определите данные, которые необходимо бэкапить: какие данные критически важны, какие можно восстановить вручную.</li><li>Выберите место хранения: облачные сервисы, собственные серверы, внешние носители, Git-репозиторий.</li><li>Выберите тип бэкапа: при полном копируются все данные целиком, при инкрементном — изменения с момента последнего копирования, при дифференциальном — изменения с момента последнего полного бэкапа.</li><li>Настройте автоматизацию, чтобы не забывать делать бэкапы вручную. Можно использовать скрипты, планировщики задач или бэкап-сервисы.</li><li>Проверьте бэкап. Проведите тестовое восстановление.</li><li>Определите частоту бэкапа. Например, можно проводить полный бэкап раз в неделю и инкрементные бэкапы каждый день.</li><li>Защитите чувствительные данные.</li></ol><h2>Локальные туннели</h2><p>При разработке pet-проекта может возникнуть необходимость показать результат внешнему миру. Кроме того, многие внешние сервисы, такие как платёжные системы и мессенджеры, тоже требуют «боевые» URL для отправки запросов. Однако открывать порты на своём устройстве напрямую небезопасно. Локальные туннели создают временный внешний URL-адрес без развертывания на реальном сервере.</p><p>Когда вы запускаете туннель через специальный инструмент, он:</p><ul><li>устанавливает зашифрованное соединение между вашим компьютером и своим публичным сервером;</li><li>создаёт внешний адрес;</li><li>пересылает все запросы, которые приходят на этот адрес, вашему локальному приложению.</li></ul><p>Трафик при этом шифруется и проходит через защищённый канал.</p><h3>Примеры инструментов</h3><p><a href="https://ngrok.com/?ref=gobigger">Ngrok </a>— самый известный инструмент для быстрого создания туннелей. Есть бесплатный тариф.</p><p>Порты от<b> VSCode</b> — отличное решение для пользователей Visual Studio Code, удобно для быстрой демонстрации.</p><p><a href="https://dev.vk.com/ru/libraries/tunnel">VK Tunnel</a> — российская альтернатива, подходит для работы через VK Cloud.</p><p><b>Tuna</b> и <a href="https://xtunnel.ru/">xTunnel </a>— простые в использовании решения, есть бесплатные тарифы.</p><h2>Чек-лист по инфобезу для тех, кто делает pet-проект</h2><ol><li>Регулярно обновляйте зависимости. Используйте автоматические инструменты, например, Dependabot или npm audit.</li><li>Настройте базовые HTTP-заголовки безопасности. Добавьте заголовки Content-Security-Policy, X-Frame-Options, Strict-Transport-Security, чтобы минимизировать риск XSS, Clickjacking и других атак.</li><li>Используйте бесплатные SSL-сертификаты. Подключите HTTPS через бесплатные сервисы, например, Let's Encrypt.</li><li>Очищайте и валидируйте ввод данных. Фильтрация и валидация данных защитит от SQL-инъекций и XSS.</li><li>Создайте отдельные учётные записи для разных сервисов. Не используйте одну и ту же учётную запись везде.</li><li>Минимизируйте доступы к базе данных. Если сервису нужно только читать, не давайте права на запись или удаление.</li><li>Используйте бесплатные инструменты для сканирования уязвимостей. Проверьте код через такие сканеры, как SonarQube Community Edition, Snyk, OWASP ZAP.</li><li>Делайте резервные копии. Настройте автоматические бэкапы базы данных и важных файлов.</li><li>Не храните секреты в коде. Используйте .env файлы и убедитесь, что они добавлены в .gitignore.</li><li>Включите двухфакторную аутентификацию (2FA). На всех сервисах, где это возможно, включите 2FA для дополнительной защиты.<br /></li></ol><p>А больше про разработку и все, что с ней связано, в нашем<a href="https://t.me/tproger_web"> тг-канале</a>!</p>]]></content:encoded>
    </item>
    <item>
      <title>Как сделать код-ревью, чтобы тебя не возненавидели?</title>
      <link>https://tproger.ru/articles/kak-sdelat-kod-revyu--chtoby-tebya-ne-voznenavideli-</link>
      <comments>https://tproger.ru/articles/kak-sdelat-kod-revyu--chtoby-tebya-ne-voznenavideli-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-sdelat-kod-revyu--chtoby-tebya-ne-voznenavideli-</guid>
      <description><![CDATA[<p>Как делать код-ревью без токсичности: что говорить, как формулировать замечания и не разрушать отношения в команде. </p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-sdelat-kod-revyu--chtoby-tebya-ne-voznenavideli-">Как сделать код-ревью, чтобы тебя не возненавидели?</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Тимлид]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 16 Jun 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>«Почему ты так написал?» — если ваш комментарий в код-ревью начинается с таких слов, будьте готовы к тому, что коллеги разочаруются. Жёсткая критика без контекста, замечания о стиле вместо архитектуры и тон преподавателя, а не ментора, превращают ревью в стресс. Но можно иначе: находить реальные баги, а не придираться к неймингу; объяснять, а не указывать; замечать хорошие решения. Рассказываем, как делать код-ревью так, чтобы ваш фидбек ждали, а не проклинали.</p><h2>Почему код-ревью — не про власть, а про заботу</h2><p>Код-ревью — процесс, который помогает проекту и команде расти. И подходить к нему стоит не с позиции «сейчас найду ошибку», а с установки «сделать вместе с разработчиком лучше». На зачем он вообще нужен?</p><ul><li>чтобы заметить ошибки до продакшена, а не после;</li><li>чтобы синхронизировать стиль и подходы в команде;</li><li>чтобы разработчик не оставался наедине с кодом и сомнениями.</li></ul><p>Хорошее ревью по сути — это дополнительная пара глаз. Но часто оно воспринимается как экзамен, особенно у джунов. Почему? Комментарии звучат категорично, без объяснений, а ревью превращается в поиск опечаток, а не обсуждение архитектуры. В итоге весь процесс теряет смысл: вместо совместной работы над улучшением кода получается конфликт интересов. В таком случае оптику нужно менять.</p><h3>Что на самом деле проверяется</h3><p>В код-ревью обычно проверяется:</p><ul><li>Понятность и читаемость — сможет ли через месяц любой член команды понять, что происходит.</li><li>Надёжность — не развалится ли всё, если пойти по нестандартному сценарию.</li><li>Согласованность — насколько код вписывается в архитектуру и договорённости команды.</li><li>Перспектива — насколько удобно будет этот код поддерживать, масштабировать или переписывать через год.</li></ul><p>Задача здесь — дать взгляд со стороны, нащупать правильные вопросы, увидеть то, что автор кода мог не заметить. Но как это сделать правильно?</p><h2>Чек-лист для ревьюера: что смотреть в коде, чтобы все прошло гладко</h2><p>Хороший ревьюер не выискивает опечатки, а помогает сделать код лучше. Рассмотрим, что необходимо проверять.</p><h3>Логика: всё ли понятно и предсказуемо?</h3><p>Проверка логики — про то, чтобы прочитать код и сразу понять, зачем он написан именно так. Без нужды лезть в историю коммитов или в личные сообщения к программисту. Вот на что стоит обратить внимание:</p><h4>Код решает задачу или обходит её?</h4><p>Иногда разработчик может использовать запутанные конструкции, прибегать к костылям и лишним условиям. Здесь стоит спрашивать самого себя:</p><ul><li>«А зачем тут это условие?»</li><li>«Можно ли решить задачу проще?»</li><li>«Это бизнес-логика или побочный эффект бага?»</li></ul><h4>Всё ли предсказуемо?</h4><p>Хорошая логика — это ожидаемое поведение. Когда видишь функцию getUserRoles, и она действительно возвращает роли пользователя, а не делает лишний лог (или хуже, мутирует глобальное состояние).</p><p>Нужно проверить:</p><ul><li>Есть ли неожиданные побочные эффекты?</li><li>Не делает ли функция всё подряд?</li><li>Можно ли использовать этот код повторно?</li></ul><h4>Учитываются ли граничные случаи?</h4><p>Тестировать happy path — это приятно. Но ревью — момент, когда нужно быть немного параноиком и задавать себе вопросы:</p><ul><li>«А что, если в массиве будет null?»</li><li>«Что вернётся, если база пустая?»</li><li>«Что произойдёт, если API не ответит?»</li></ul><p>Если логика ломается при первой же нестандартной ситуации — это нерабочая логика.</p><h4>Видна ли связь между частями?</h4><p>Чем сложнее фича, тем важнее понимать, как всё взаимодействует. Хороший код складывается в историю: ты читаешь файл, и у тебя в голове выстраивается картинка. Если же приходится постоянно прыгать между файлами и держать всё в голове — это тревожный сигнал.</p><h3>Архитектура: насколько код ложится в общую картину?</h3><p>Ревью — про то, как новая часть кода вписывается в уже существующую систему. Даже идеально написанное решение может быть неуместно, если оно идёт вразрез с архитектурой проекта. На что обращать внимание:</p><h4>Живёт ли код в вакууме</h4><p>Каждый новый модуль, компонент или класс должен:</p><ul><li>быть в нужном слое архитектуры (не пишем, например, SQL-запросы в React-компоненте),</li><li>располагаться там, где его логически ожидаешь (не прячем бизнес-логику в утилитах),</li><li>использовать существующие механизмы, а не дублировать их.</li></ul><h4>Следует ли код соглашениям команды</h4><p>Хорошая архитектура держится на дисциплине. Если вы договорились, что у каждого эндпоинта есть слой сервисов — не нужно вызывать репозиторий напрямую из контроллера. Иначе проект превращается в сборную солянку: один разработчик пишет по паттернам, другой — по наитию.</p><p>Нужно проверить:</p><ul><li>используются ли принятые в команде подходы;</li><li>поддерживаются ли слои;</li><li>повторяет ли структура проекта предыдущие решения.</li></ul><h3>Безопасность: нет ли уязвимосей?</h3><p>Код должен не только работать корректно, но и быть защищённым. Даже в небольших задачах могут скрываться уязвимости — особенно там, где данные приходят извне или есть доступ к чувствительной информации. На что обращать внимание:</p><h4>Пользовательский ввод</h4><p>Всё, что приходит от пользователя (формы, параметры URL, тело запроса), требует внимания. Здесь могут возникнуть SQL-инъекции, XSS и т.д. Поэтому стоит проверить:</p><ul><li>Есть ли валидация данных на стороне сервера?</li><li>Используются ли подготовленные запросы или ORM?</li><li>Обрабатываются ли потенциально опасные символы?</li><li>Предусмотрена ли защита от исполнения произвольного кода?</li></ul><h4>Доступ к данным и авторизация</h4><p>Если код взаимодействует с базой, файлами или персональными данными, важно удостовериться, что доступ предоставляется только тем, кому он положен. Проверяем:</p><ul><li>Есть ли проверка прав пользователя перед выполнением запроса?</li><li>Реализована ли проверка не только на фронте, но и на сервере?</li><li>Используются ли идентификаторы, которые нельзя легко перебрать?</li></ul><h3>Тесты: можно ли быть уверенным, что всё работает?</h3><p>Хороший тест — реальная гарантия, что при следующем изменении код не сломается. Здесь важно понять, действительно ли тесты покрывают важные сценарии и защищают от регрессий:</p><h4>Есть ли вообще тесты?</h4><p>Начнём с очевидного. Прежде чем обсуждать качество, стоит выяснить: тесты вообще написаны? Если в задаче меняется логика или добавляется новая функциональность — это почти всегда повод что-то протестировать.</p><p>Проверяем:</p><ul><li>Есть ли новые юнит- или интеграционные тесты?</li><li>Актуальны ли существующие — не остались ли висящими после изменений?</li><li>Упали ли какие-нибудь тесты в CI — и если да, то почему?</li></ul><h4>Тестируется ли то, что нужно?</h4><p>Иногда тесты есть, но проверяют слишком очевидное или не покрывают рисковые места. На что обратить внимание:</p><ul><li>Проверяются ли граничные случаи (например, пустой ввод, null, некорректные данные)?</li><li>Есть ли тесты на негативные сценарии — когда функция должна вернуть ошибку?</li><li>Покрыта ли новая логика?</li></ul><h4>Понятны ли сами тесты?</h4><p>Тесты тоже часть кода, и их читают люди. Если логика проверок неочевидна, тесты будут мешать. При ревью задаем вопросы:</p><ul><li>Говорят ли названия тестов, что именно они проверяют?</li><li>Можно ли по коду теста быстро понять, зачем он нужен?</li><li>Нет ли странных чисел или непонятных моков?</li></ul><p>Так, хороший код-ревьюер фокусируется на смысловых точках риска. Но как указывать на эти точки? Рассмотрим стратегии взаимодейтсвия с разработчиком во время код-ревью (чтобы последний не возненавидел любую возможность писать код и самого ревьюера).</p><h2>Как давать комментарии и не звучать резко</h2><p>Хорошее ревью — это про диалог, в котором оба участника заинтересованы в улучшении кода. Чтобы комментарии воспринимались конструктивно, а не как придирки, важно держать тон и структуру. Разберем четыре простых ориентира.</p><h3>Начните с положительного: что в этом коде уже хорошо</h3><p>Хорошее ревью начинается с признания сильных сторон. Это легальный способ показать, что вы оцениваете работу комплексно. Когда автор видит, что вы заметили не только недочеты, но и удачные решения, он/она с большей вероятностью воспримет все конструктивно.</p><p>К тому же, положительные комментарии помогают закрепить результат: человек будет знать, что именно сработало — и использовать это снова.</p><p>Что можно хвалить:</p><ul><li>чистую и понятную структуру;</li><li>удачные названия переменных или функций;</li><li>хорошую обработку исключений или пограничных случаев;</li><li>то, что код хорошо ложится в текущую архитектуру.</li></ul><p>Примеры фраз:</p><ul><li>«Здорово, что ты вынес логику в отдельный хелпер — теперь это читается в разы легче».</li><li>«Классная идея использовать (вставьте код),а не (вставьте код)— так гораздо понятнее».</li><li>«Круто, что добавил тест на этот кейс — про него часто забывают».</li></ul><h3>Замечания: только по делу и с предложением, как исправить</h3><p>Чтобы код-ревью было конструктивным, нужно не просто указывать на проблему, а помогать найти решение. Комментарии без объяснения или контекста могут звучать как придирки, особенно если ревью получает менее опытный разработчик. А вот если вы объясняете, почему что-то не так, и что можно сделать по-другому — это уже наставничество, а не критика.</p><p>Так НЕ надо:</p><ul><li>«Плохо читается».</li><li>«Переделай»</li><li>«Зачем???»</li></ul><p>Так лучше:</p><ul><li>«Можно упростить, если разделить условие на два блока — сейчас выглядит довольно сложно».</li><li>«Тут, кажется, можно обойтись без цикла: достаточно метода (вставьте метод)— он короче и лучше читается»..</li><li>«В этом месте можно потенциально получить undefined. Может, стоит добавить проверку?»</li></ul><h3>Говорите прямо, без намёков и иронии</h3><p>Код-ревью — не место для недосказанностей и полутонов. Комментарии вроде «Ну, если так РЕАЛЬНО работает — ок» звучат пассивно-агрессивно и только создают напряжение. Получивший такое замечание будет гадать: это одобрение, сарказм или тонкий намёк, что я всё сделал не так?</p><p>Вместо этого — формулируйте замечания ясно и по существу:</p><ul><li>«В этом месте поведение функции может быть неочевидным — можешь уточнить название или добавить комментарий?»</li><li>«Пока непонятно, почему именно такое условие — можешь пояснить, пожалуйста?»</li><li>«Похоже, тут можно упростить: если заменить на (вставьте код) логика станет короче».</li></ul><p>Если вы не уверены, как ваша реплика будет воспринята — переформулируйте. В ревью лучше не пошутить, чем задеть человека, особенно если вы не на 100% уверены в уровне вашей взаимной иронии.</p><h3>Делайте фокус на код, а не на человека</h3><p>Хорошее ревью — это не про то, чтобы указать, что человек сделал плохо, скорее про то, что в этом месте можно улучшить. Разница тонкая, но критически важная. Комментарии не должны звучать как обвинения, даже если баг очевидный.</p><p>Так НЕ надо:</p><ul><li>«Ты опять забыл обработать ошибку».</li><li>«Почему ты так сделал?!»</li><li>«Это неправильно».</li></ul><p>Лучше так:</p><ul><li>«Похоже, здесь не хватает обработки ошибки — может быть сбой».</li><li>«Можешь, пожалуйста, уточнить логику? Кажется, тут может возникнуть исключение».</li><li>«Вот так решение будет стабильнее: предлагаю…»</li></ul><p>Когда мы говорим о коде, а не о человеке, снижается напряжение. Человек не чувствует, что его «проверяют», он чувствует, что с ним вместе улучшают результат.</p><h2>Как сделать код-ревью полезным и для себя</h2><p>Код-ревью часто воспринимается как обязанность: проверил pull request, поставил галочку, пошел дальше. Но на самом деле это отличная возможность прокачиваться не только тому, чью работу вы смотрите, но и вам самим. Даже если задача кажется простой, внимательно просмотрев чужой код, можно узнать что-то новое и лучше понять архитектуру проекта. Рассмотрим, как превратить свой ревьюерский труд в пользу.</p><h3>Учитесь новому: чужой код — тоже учебник</h3><p>Читая чужие решения, можно заметить многое: библиотеку или инструмент, который вы раньше не использовали; необычную структуру функции или способ организации логики; паттерн, который вы обычно не применяете, но он к месту и т.д. Это особенно полезно, если вы работаете в мультистековой команде. Кто-то пишет на Python, вы — на C++, но идеи и архитектурные подходы легко переносятся между языками. Подмечайте, как другие подходят к задачам, даже если в целом всё вам понятно — детали часто дают самые интересные инсайты.</p><p>Заведите привычку задаваться вопросом: «Что здесь сделано хорошо и почему я сам так не пишу?». Или наоборот — «Почему мне этот кусок кажется странным и как бы я сделал иначе?». Такие наблюдения дают гораздо больше, чем кажется на первый взгляд.</p><h3>Задавайте вопросы, даже если всё понятно</h3><p>Иногда вы смотрите код — и вроде всё чисто, логично. Но это как раз повод не просто молча одобрить, а пообщаться с проггером. Почему? Потому что вопросы — не всегда сигнал о проблеме: иногда это инструмент обучения.</p><p>Например:</p><ul><li>«А почему решили использовать именно этот метод?»</li><li>«Это кастомное решение или такой подход у нас принят в проекте?»</li><li>«Я раньше делал по-другому — есть ли причины, почему здесь выбрали такой путь?»</li></ul><p>Такие вопросы помогают вам лучше понять чужой ход мыслей; показывают автору, что вы включены в процесс, а не просто пробежались глазами; создают пространство для обсуждения и обмена опытом.</p><p>Важно: вопросы должны звучать как приглашение к диалогу, а не как скрытая критика. Если вы спрашиваете «Зачем это вообще нужно?», лучше замените на «Помоги разобраться, почему выбрали такой подход — интересно сравнить с тем, как делал раньше».</p><h3>Прокачивайте навык объяснять</h3><p>Хороший разработчик умеет не только писать код, но и объяснять, почему он написал именно так. Код-ревью — отличная тренировка этого навыка.</p><p>Когда вы оставляете комментарий — попробуйте объяснить, в чём именно суть проблемы и почему стоит внести изменения. Это заставит вас сформулировать мысль чётко, логично и по делу — а это критически важный навык для тимлида, ментора и любого разработчика, который находится в команде.</p><p>Например, вместо «Это плохой способ», напишите: «Такой подход может усложнить отладку, потому что данные не логируются. Предлагаю использовать вот такой паттерн (укажите паттерн), он делает поведение функции более прозрачным».</p><p>Почему это работает:</p><ul><li>вы тренируете навык аргументации — полезно и в коммуникации, и на технических собеседованиях;</li><li>автор кода быстрее понимает, что именно стоит изменить, и почему;</li><li>вы сами начинаете глубже понимать, почему какой-то код не совсем правильно написан.</li></ul><p>И ещё один плюс: если ваш комментарий требует объяснения — это повод задуматься, действительно ли замечание по делу. Иногда, пока формулируешь аргументы, понимаешь, что лучше промолчать. И это тоже рост.</p><p>Код-ревью — не ритуал и не повод самоутверждаться. Это способ сделать код лучше, команду сильнее, а продукт стабильнее. Хорошее ревью помогает не только найти баги, но и передать знания, улучшать архитектуру, учиться объяснять мысли и замечать собственные пробелы.</p>]]></content:encoded>
    </item>
    <item>
      <title>7 курсов, с которых реально стартуют в IT в 2025</title>
      <link>https://tproger.ru/articles/7-kursov--s-kotoryh-realno-startuyut-v-it-v-2025</link>
      <comments>https://tproger.ru/articles/7-kursov--s-kotoryh-realno-startuyut-v-it-v-2025?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/7-kursov--s-kotoryh-realno-startuyut-v-it-v-2025</guid>
      <description><![CDATA[<p> Хотите начать карьеру в IT с нуля? Рассказываем, какие курсы в 2025 реально помогают попасть в IT, даже без опыта и тех.образования.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/7-kursov--s-kotoryh-realno-startuyut-v-it-v-2025">7 курсов, с которых реально стартуют в IT в 2025</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[SQL]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Базы данных]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[Образование]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Английский]]></category>
      <category><![CDATA[Аналитика]]></category>
      <category><![CDATA[Обучающие курсы]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Вебинар]]></category>
      <category><![CDATA[Кибербезопасность]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 11 Jun 2025 15:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>В 2025 году старт карьеры в IT намного сложнее, чем несколько лет назад. Работодатели больше не берут новичков только за диплом или сертификат — теперь всем нужны реальные практические навыки, которые можно сравнить с опытом работы.</p><p>В этой подборке — 7 курсов, после которых реально получить первую работу в IT за 3–6 месяцев.</p><h2>Почему в 2025 попасть в IT и легче, и сложнее одновременно</h2><p>Войти в IT в 2025 реально, но рынок сильно изменился. С одной стороны, спрос на junior-специалистов вернулся: компании снова набирают новичков, открывают стажировки и гибридные программы. Но конкуренция стала выше, а фильтры — жёстче.</p><h3>Что легче</h3><ul><li>После карьерного спада 2022–2023 спрос на junior-специалистов начал восстанавливаться. Появилось больше стажировок и вакансий для начинающих. Согласно отчёту<a href="https://www.roberthalf.com/us/en/insights/research/data-reveals-which-technology-roles-are-in-highest-demand"> Robert Half</a>, начать успешную карьеру могут инженеры по данным, DevOps-инженеры и разработчики ПО. Однако конкуренция остаётся высокой, и работодатели ожидают от кандидатов не только базовых знаний, но и быстрой адаптации к новым инструментам.</li><li>Образование и работа в IT всё чаще переходят в <a href="https://trends.rbc.ru/trends/social/63a374dd9a794731007f44da">гибридный </a>формат: можно совмещать онлайн- и офлайн-обучение, работать удалённо и периодически встречаться в офисе.</li></ul><h3>Что сложнее</h3><ul><li>Конкуренция выше, чем раньше. Даже на стартовые позиции часто подаётся по сотне кандидатов.</li><li>Работодатели ждут не просто знаний или диплома, а быстрой адаптации.</li></ul><h3>Что изменилось в 2025 по сравнению с 2020–2024</h3><p>Во-первых, образование стало прагматичнее. С 2020 по 2022 год рынок был наводнен короткими курсами «на джуна». В 2025-м большинство таких школ либо закрылись, либо переформатировались: люди устали платить за теорию без практики. Сейчас ценятся программы, в которых есть командные проекты, ревью от наставников, работа с Git и проектный пайплайн, близкий к реальному.</p><p>Во-вторых, работодатели всё чаще оценивают кандидатов по их реальным навыкам и опыту, а не по формальному образованию. Согласно <a href="https://dzen.ru/a/aB4XGcZqiXGuE2wI">прогнозам</a>, 39% текущих навыков работников устареют к 2030 году, что подчеркивает необходимость постоянного обновления и адаптации.</p><p>Так, расширяются границы образования. А вместе с ними – появляются онлайн-курсы.</p><h2>7 курсов, с которых начинают карьеру в IT</h2><h3>1. Kata Academy — GO-разработчик</h3><p><a href="https://kata.academy/courses/go-backend-developer?utm_source=web&amp;utm_medium=article&amp;utm_campaign=go&amp;utm_content=tproger_11_06_25">Ссылка на курс</a></p><p>Go (Golang) — это билет в backend-разработку, где в 2025 году крутятся большие деньги и хардовые задачи. Язык, созданный Google, ценят за скорость и простоту, а компании от стартапов до гигантов вроде Яндекса выстраиваются в очередь за Go-разработчиками. Курс от Kata Academy учит писать серверный код, работать с SQL, Git, Linux и Docker, чтобы выпускники могли строить масштабируемые приложения.</p><h4>📚Что получают выпускники</h4><p>На курсе студент осваивает Go и смежные технологии, создает портфолио из практических проектов, готовится к собеседованиям с поддержкой школы и приходит к главной цели — устраивается на работу по новой специальности. Кроме этого:</p><ul><li>Есть карьерная поддержка: резюме, собеседования, вакансии;</li><li>В договоре — гарантированная зарплата от 120 000 ₽ (может быть выше).</li></ul><h4>🎓Длительность и формат</h4><p>Курс проводится полностью онлайн. Длительность обучения — 9 месяцев, включая подготовку к собеседованиям. Нагрузка: от 25 часов обучения в неделю (3-4 часа в день), есть дедлайны. Выпускник устраивается на работу после курса, в течение 1-2 месяцев (в среднем).</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/8eb864d0-b80e-40a4-9de5-df9ee68d9c5d.png" alt="" /><figcaption>Скриншот траектории обучения с сайта программы</figcaption></figure><h4>👥Кому подойдет</h4><ul><li>Новичкам без опыта в программировании;</li><li>Студентам и начинающим разработчикам, которые хотят освоить Go;</li><li>Может быть интересен тем, кто работает во фронтенде или техподдержке и хочет сменить направление.</li></ul><p>Не требует знаний математики и программирования — рассчитан на обучение с нуля.</p><h4>🏆Возможности после курса</h4><p>На сайте указано, что выпускники устраиваются в компании, такие как Яндекс, Альфа-Банк и Kaspersky, часто в течение первого месяца после завершения основной программы курса. Если выпускник не найдет работу с зарплатой от 120.000 рублей, то оплачивать обучение не придется.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/1a7f9220-659a-4942-b49a-f4cfd1c06651.png" alt="" /><figcaption>Отзывы с сайта программы</figcaption></figure><h4>💸 Стоимость и условия участия</h4><p>Есть два варианта обучения:</p><ul><li>Интенсивное (стоимость — 110 000 рублей во время учебы плюс 20% от зарплаты в первый год работы). Для тех, кто живет в Москве или Санкт-Петербурге, или готов туда переехать.</li><li>Асинхронное (стоимость — 262 000 рублей). Обучение в своем темпе, нет дедлайнов. Можно искать работу в любом городе-миллионнике, если не получится устроиться — есть гарантия возврата денег.</li></ul><h3>2. CyberEd — Пентестер</h3><p><a href="https://cyber-ed.ru/b2c-courses/pentester/?utm_medium=tproger&amp;utm_campaign=7kursov">Ссылка на курс</a></p><p>Пентест (тестирование на проникновение) — это процесс поиска уязвимостей в IT-системах путем имитации атак хакеров.</p><p>Курс обучает анализу защищенности веб-приложений, сетей и инфраструктуры, а также использованию инструментов вроде Nessus и Nmap.</p><p>В программе будут техники атак, методы их обнаружения и составление отчетов. Курс готовит специалистов к реальным задачам в области кибербезопасности для работы в топовых компаниях.</p><h4>📚Что получают выпускники</h4><ul><li>Выпускники получают диплом о профессиональной переподготовке или удостоверение о повышении квалификации (зависит от формата).</li><li>Студенты формируют цифровое резюме и портфолио на основе практических заданий.</li><li>Все студенты проходят карьерную подготовку — от тренировки прохождения собеседований до подбора стажировок и вакансий.</li></ul><h4>🎓Длительность и формат</h4><p>Обучение длится 24 недели (365 академических часов) и проходит полностью онлайн. Есть два формата:</p><ul><li>Синхронный формат — с расписанием и онлайн-занятиями в группе. Включает 24 онлайн-семинара по 4 часа, регулярную обратную связь от наставников и карьерные консультации.</li><li>Асинхронный формат — без привязки ко времени: обучение проходит в удобном для студента темпе. Доступ ко всем материалам курса, заданиям и модулям открыт сразу.</li></ul><p>Оба формата включают более 100 практических заданий, поддержку менторов и итоговый проект.</p><h4>👥Кому подойдет</h4><ul><li>Айтишникам, которые хотят научиться пентесту или прокачаться в кибербезопасности.</li><li>Системным администраторам, веб-разработчикам, специалистам по ИБ, а также джунам и миддлам из пентеста, Blue Team или AppSec.</li></ul><p>В общем, полезно будет тем, у кого уже есть хотя бы год опыта и кто хочет перейти на следующий уровень.</p><h4>🏆Возможности стажировки и трудоустройства</h4><p>Выпускники устраиваются на позиции инженеров по безопасности или пентестеров, в том числе в крупные IT-компании. По отзывам студентов, некоторые находят стажировку уже на 4 месяц обучения, а часть получает постоянные позиции в течение 1 года после финала курса.</p><h4>💸 Стоимость и условия участия</h4><p>138 000 рублей за синхронный формат, 74 000 рублей за асинхронный. Доступна рассрочка на 2 года — 6 900 рублей в месяц.</p><p>Для поступления необходимо подать заявку через сайт. Точные требования к участникам не указаны, но курс предполагает наличие базовых знаний IT.</p><h3>3. Яндекс Практикум — Инженер по тестированию</h3><p><a href="https://practicum.yandex.ru/qa-engineer/?utm_source=partners&amp;utm_medium=cpc&amp;utm_campaign=tproger_cpc_RF_Prog_qaEn_b2c_Article_None_None">Ссылка на курс</a></p><p>Инженер по тестированию (QA-инженер) проверяет качество программных продуктов: ищет ошибки  в веб-приложениях, мобильных приложениях и API.</p><p>В программе курса Яндекс Практикума будут основы ручного тестирования, работа с тестовой документацией и инструментами, базовые навыки автоматизации, а также отдельные модули по информационной безопасности, Figma, Python и SQL.</p><p>Из интересного: обучение построено по принципу симуляции стажировки: студенты работают над проектами, которые похожи на реальные рабочие задачи.</p><h4>📚Что получают выпускники</h4><ul><li>В финале курса Практикум выдаёт диплом о профессиональной переподготовке.</li><li>Также у выпускников остаётся портфолио из 7 учебных проектов (в расширенной версии курса — из 9). Среди них, например, — итоговая работа над сервисом Яндекса (тестирование Яндекс.Маршрутов и т.д.).</li><li>Дополнительно открывается доступ к модулю по YandexGPT и YandexART.</li><li>В течение семи месяцев после окончания обучения доступна карьерная поддержка. При желании можно набираться опыта в Мастерской Практикума — это агентство внутри Практикума, где выпускники работают над задачами реальных заказчиков.</li></ul><h4>🎓Длительность и формат</h4><ul><li>Курс рассчитан на пять месяцев — это 318 академических часов, в среднем около 20 часов в неделю. Обучение проходит онлайн.</li><li>Теоретическая часть будет в виде интерактивного учебника, а практические задачи выполняются по спринтам: каждые три недели — новый проект.</li><li>Воркшопы и консультации с наставниками проходят по расписанию. У студентов есть дедлайны по проектным заданиям.</li></ul><h4>👥Кому подойдет</h4><ul><li>Новичкам без опыта в IT — студентам, тем, кто хочет сменить профессию, и специалистам из смежных областей.</li><li>Техническое образование и навыки программирования не требуются, но базовый английский будет плюсом, особенно если планируете развиваться в сторону автоматизации.</li></ul><h4>🏆Возможности стажировки и трудоустройства</h4><p>После завершения программы карьерный центр помогает в трудоустройстве (доступны карьерная поддержка в течение 6+ месяцев после обучения, фриланс-трек для тех, кто хочет работать на себя, вакансии и стажировки от партнёров и мастерская проектов). В среднем, стажёры зарабатывают около 52 000 рублей, джуниоры — 76 000, мидлы — 142 000 рублей.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/20143499-8f64-456d-84d7-a9fb2f205b5f.png" alt="" /><figcaption>Отзывы студентов. Скриншот с сайта программы</figcaption></figure><h4>💸 Стоимость и условия участия</h4><ul><li>Junior-трек. Подходит для старта в тестировании. 77 000 ₽ — при полной оплате; 16 500 ₽/мес. × 5 месяцев — при рассрочке.</li><li>Расширенный трек. Тут больше практики и навыков, чтобы быстрее вырасти до мидла. 148 000 ₽ — при полной оплате; 18 500 ₽/мес. × 9 месяцев — при рассрочке.</li><li>От новичка до автоматизатора. Сразу две профессии: ручное и автоматизированное тестирование. 156 000 ₽ — при полной оплате. 20 000 ₽/мес. × 9 месяцев — при рассрочке.</li></ul><p>Перед стартом можно пройти бесплатный вводный модуль на всех треках. Также получить налоговый вычет или частично вернуть деньги, если не понравится.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/c167cf4d-f1f8-4308-ad0d-75931e3b8048.png" alt="" /><figcaption>Как выглядит вводный бесплатный модуль. Скриншот с сайта программы</figcaption></figure><h3>4. Rebrain — Мини-практикум Golang с нуля</h3><p><a href="https://rebrainme.com/golang-s-nulya/?utm_source=tproger&amp;utm_medium=post&amp;utm_campaign=devops_mako&amp;utm_content=27052025">Ссылка на курс</a></p><p>Мини-практикум от Rebrain знакомит с основами Go, включая синтаксис, работу с каналами, контекстами и микросервисами. Программа ориентирована на практическое освоение языка через выполнение задач, моделирующих реальные сценарии backend-разработки.</p><h4>📚Что получают выпускники</h4><p>Выпускники получают сертификат Rebrain, подтверждающий освоение основ Go. В программу входят более 10 практических задач, демонстрирующих навыки работы с языком и современными подходами к разработке.</p><p>Доступ к комьюнити и онлайн-мероприятиям Rebrain позволяет продолжать обучение и налаживать профессиональные связи. Теоретические материалы остаются доступными навсегда.</p><h4>🎓Длительность и формат</h4><ul><li>Курс длится около 2 недель, но продолжительность зависит от темпа студента.</li><li>Программа полностью онлайн и асинхронная, что позволяет учиться в удобное время без привязки к расписанию.</li><li>Формат текстовый, без видеолекций, с акцентом на практику (90% времени).</li></ul><p>Студенты выполняют более 10 задач, а менторы на связи для обратной связь и поддержки.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/2fcb2893-3d65-4211-a18a-2adde491fc05.png" alt="" /><figcaption>Скриншот программы практикума с сайта Rebrain</figcaption></figure><h4>👥Кому подойдет</h4><ul><li>Студентам с потенциалом для Go;</li><li>Начинающим разработчикам без практического опыта;</li><li>Специалистам из смежных IT-направлений.</li></ul><p>Здесь нужны минимальные навыки работы с системами контроля версий (GitHub/GitLab), но глубокие знания программирования не требуются.</p><h4>🏆Возможности стажировки и трудоустройства</h4><p>HR-центр Rebrain помогает выпускникам с поиском работы, предоставляя консультации по резюме и подготовке к собеседованиям.  Участники комьюнити Rebrain могут попробовать себя в хакатонах и профессиональных событиях, где легче найти работу.</p><h4>💸 Стоимость и условия участия</h4><p>Стоимость курса — 14 990 рублей при полной оплате или 1 249 рублей в месяц при рассрочке на 12 месяцев. Для поступления достаточно подать заявку через сайт; специальных требований, кроме базового понимания IT, нет. Курс подходит для самостоятельного обучения, но требует дисциплины из-за асинхронного формата.</p><h3>5. Systems.Education — Системный аналитик / Проектировщик корпоративных информационных систем</h3><p><a href="https://systems.education/systems-analyst-bootcamp?utm_source=social&amp;utm_medium=tproger&amp;utm_campaign=rp">Ссылка на курс</a></p><p>Цель программы — получить профессию системного аналитика, которая соответствует актуальным требованиям вакансий на рынке.</p><p>На курсе от Systems.Education вы за 3 месяца пройдёте реальный кейс за счёт работы с:</p><ul><li>Формальным моделированием бизнеса и бизнес-проблемы: Event Storming, BPMN, Opportunity canvas.</li><li>Разработкой пользовательских требований: Impact map, User story map, Use case diagram, Use case scenario.</li><li>Концептуальным проектированием ИТ-решений: моделирование предметной области, UML диаграмма состояний, Контекстная диаграмма, Концептуальная модель данных, Макеты приложений.</li><li>Спецификацией требований к системе: Функциональные требования к системе, Нефункциональные требования к системе, Требования к информационной безопасности, Системные алгоритмы.</li><li>Техническим проектированием ИТ-решений: Диаграмма взаимосвязи объектов, диаграммы в нотации С4, Требования к интеграции, UML диаграмма последовательности, Data flow diagram.</li></ul><h4>📚Что получают выпускники</h4><ul><li>Сертификат на основании лицензии об образовательной деятельности, подтверждающий квалификацию системного аналитика уровней 4 и 5 по российскому профстандарту.</li><li>Портфолио, включающее результаты их учебного проекта.</li><li>Демонстрацию финальных результатов кейса перед приглашенными HR и техническими специалистами из компаний-потенциальных работодателей.</li></ul><h4>🎓Длительность и формат</h4><p>Курс длится 3 месяца (200+ академических часов) и проводится полностью онлайн: 8 часов в неделю — занятия с преподавателем в Zoom, дополнительно — командные и индивидуальные созвоны с ментором. Процесс обучения осуществляется в командах, в которых участники работают над реальным кейсом.</p><p>Каждую неделю студенты взаимодействуют с заказчиком, роль которого выполняет ведущий специалист школы SE: команды проводят с ним интервью, собирают требования, выявляют проблемы бизнеса, формируют цель разработки, определяют границы проекта и утверждают концепцию решения. Под руководством ментора переходят от системного анализа к проектированию информационной системы: выбирают подходящий архитектурный паттерн и тип базы данных, проектируют поток информации через интеграции API и брокеров. Каждую неделю студенты получают обратную связь от менторов.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/fba4356b-cef4-4b24-b693-1800ca41b24e.png" alt="" /><figcaption>Скриншот отзывов с сайта программы</figcaption></figure><h4>👥Кому подойдет</h4><ul><li>Не системным аналитикам, которые хотят освоить практики проектирования информационных систем и/или стать системными аналитиками.</li><li>Системным аналитикам, которые хотят получить поддержку старших коллег при отработке практик проектирования, а также систематизировать знания в области проектирования ИС.</li></ul><h4>🏆Возможности стажировки и трудоустройства</h4><ul><li>Защитите итоговый проект прямо перед HR и техспецами из компаний.</li><li>Получите портфолио из настоящих проектных документов (артефактов) — всё, что требуют работодатели на позиции младшего системного аналитика.</li><li>В течение всего обучения вас будут сопровождать менторы-практики: помогут с проектом, дадут фидбек, подготовят к собеседованиям.</li></ul><p>По статистике школы, выпускники за год могут дорасти до уровня Middle-аналитика.</p><h4>💸 Стоимость и условия участия</h4><ul><li>205 000 рублей для физических лиц</li><li>255 000 рублей для юридических лиц.</li></ul><p>Действует скидка на раннее бронирование. Потоки стартуют раз в три месяца. Для поступления требуется подать заявку через сайт. Базовые знания IT-процессов желательны, но специальных тестов нет. Гарантируется 100% возврат средств при отказе до начала обучения.</p><h3>6. Karpov.Courses — Аналитик данных</h3><p><a href="https://karpov.courses/analytics?utm_source=tproger&amp;utm_medium=partners&amp;utm_campaign=1_dscoursestartda_tproger_partners_article_course_all_ds_kc">Ссылка на курс</a></p><p>Курс от karpov.courses учит работать с Python, SQL, Power BI и другими нужными инструментами для анализа, визуализации и автоматизации. В программе много практики: решаете реальные задачи — A/B-тесты, расчёт метрик, анализ больших данных, работа с хранилищами.</p><h4>📚Что получают выпускники</h4><ul><li>Сертификат, подтверждающий освоение программы, и портфолио из более чем 10 учебных проектов, включая работу с реальными бизнес-кейсами.</li><li>Доступ к рабочей инфраструктуре и более 490 заданиям, моделирующим задачи аналитиков.</li><li>Карьерную поддержку.</li></ul><p>Материалы курса остаются доступны бессрочно.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/3c48685a-bca9-47ac-9375-9fc377a3f790.png" alt="" /><figcaption>Что предлагает программа. Скриншот с сайта Karpov.courses</figcaption></figure><h4>🎓Длительность и формат</h4><p>Курс длится 5 месяцев и проводится полностью онлайн на LMS-платформе. Студенты проходят уроки и выполняют домашние задания в удобном темпе, с ежедневной поддержкой кураторов и экспертов.</p><h4>👥Кому подойдет</h4><ul><li>Новичкам без опыта в IT, студентам, чтобы освоить аналитику данных.</li><li>Маркетологам и менеджерам, чтобы рассчитывать метрики бизнеса и их эффективность.</li><li>Специалистам с релевантным опытом (джуниорам и выше).</li></ul><p>Базовые навыки работы с данными (например, Excel или SQL) полезны, но не обязательны.</p><p>По итогу — будете уметь вытаскивать инсайты из данных, делать понятные дашборды и находить ответы для решения бизнес-задач.</p><h4>🏆Возможности стажировки и трудоустройства</h4><p>Karpov.Courses предлагает карьерную поддержку по поиску работы, чат с консультантами и доступ к вакансиям от партнеров.</p><p>Выпускники могут стать младшими аналитиками данных или Data Scientist с медианной зарплатой на старте 100–120 000 рублей, а если уровень мидл — от 180 000 рублей. По данным школы, 3 месяца — средний срок успешного трудоустройства.</p><h4>💸 Стоимость и условия участия</h4><p>Стоимость базового тарифа — 80 000 рублей при единовременной оплате. Доступна беспроцентная рассрочка на 24 месяца (платёж примерно 4 408 рублей в месяц).</p><p>Для поступления достаточно подать заявку через сайт, специальных требований или вступительных тестов нет.</p><h3>7. Нетология — Инженер по тестированию</h3><p><a href="https://netology.ru/programs/qa-middle#/program_variants">Ссылка на курс</a></p><p>Инженер по тестированию (QA-инженер) отвечает за проверку качества программного обеспечения, выявляя ошибки в веб-приложениях, мобильных сервисах и API. Курс от Нетологии обучает ручному и автоматизированному тестированию, включая работу с инструментами и языками программирования (Python, Java, JavaScript).</p><p>Программа предлагает три трека:</p><ul><li>«Ручное тестирование» для новичков;</li><li>«QA-инженер уровня Junior» с основами автоматизации;</li><li>«QA-инженер уровня Middle» с углубленным изучением JavaScript, мобильного и нагрузочного тестирования.</li></ul><p>Студенты работают над реальными кейсами от партнеров — Dragons, OneTwoTrip и GOD.</p><h4>📚Что получают выпускники</h4><ul><li>Диплом о профессиональной переподготовке и портфолио из 5 крупных проектов, включая тестирование сайтов, веб-сервисов, приложений и командный дипломный проект.</li><li>Программа включает до 74 практических заданий, моделирующих реальные задачи тестировщиков.</li><li>Карьерная поддержка предусматривает тестовые собеседования, помощь в составлении резюме и возможность стажировки у партнеров.</li><li>Дополнительно студенты проходят воркшоп по применению нейросетей для автоматизации задач.</li></ul><p>Материалы курса доступны в личном кабинете навсегда.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/0c758546-2119-4983-b661-2b66ba079d76.png" alt="" /><figcaption>Обещают официальный диплом. Скриншот с сайта курса</figcaption></figure><h4>🎓Длительность и формат</h4><ul><li>Курс проводится полностью онлайн, длительность зависит от трека: в среднем, 4–6 месяцев.</li></ul><ul><li>Занятия включают вебинары по расписанию (не чаще 2 раз в неделю после 19:00 МСК), видеолекции, тесты и практические задания.</li></ul><ul><li>На обучение требуется 8–10 часов в неделю. Формат сочетает синхронные вебинары с асинхронной работой через личный кабинет.</li></ul><h4>👥Кому подойдет</h4><ul><li>Новичкам без опыта, студентам и специалистам из смежных сфер.</li></ul><ul><li>Трек Junior подходит для начинающих, интересующихся автоматизацией, а трек Middle — для тех, кто хочет углубить навыки и претендовать на более высокие позиции. Базовый английский полезен, но программирование не обязательно для старта.</li></ul><h4>🏆Возможности стажировки и трудоустройства</h4><p>Программа позволяет начать карьеру в ручном тестировании уже через 2 месяца обучения, на фрилансе или в найме.</p><p>Выпускники трека Junior могут начать карьеру младших QA-инженеров (медианная зарплата около 76 000 рублей), а трека Middle — на более сложные роли с зарплатой от 142 000 рублей.</p><h4>💸 Стоимость и условия участия</h4><p>Стоимость зависит от трека (цены указаны с учетом скидки 40%):</p><ul><li>Ручное тестирование: 56 700 рублей (или 2 487 рублей/мес. на 24 месяца)</li><li>QA-инженер уровня Junior: 105 000 рублей (или 3 070 рублей/мес. на 36 месяцев).</li><li>QA-инженер уровня Middle: 130 500 рублей (или 3 816 рублей/мес. на 36 месяцев).</li></ul><p>Для поступления нужно подать заявку через сайт, вступительных тестов нет. Возможен возврат средств в течение 7 дней, если курс не подошел.</p><h2>Как выбрать правильный курс под себя?</h2><p>Выбор IT-курса в 2025 году зависит от ваших интересов, доступного времени и бюджета. Собрали таблицу, чтобы помочь сориентироваться среди представленных программ.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/0b69693c-0870-4afb-ae44-921e6856ade6.png" alt="" /></figure><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-06-11/4a01e788-550b-4e34-adba-e1ff701d9527.png" alt="" /></figure><h2>FAQ: частые вопросы от новичков</h2><h3>Можно ли войти в IT без высшего образования?</h3><p>Да, можно. Но в некоторых крупных компаниях или госструктурах формальное образование может быть требованием. Если нет профильного образования, стоит выбирать курсы с сильной практической базой и поддержкой трудоустройства.</p><h3>Реально ли устроиться после курсов?</h3><p>Да, но результат зависит от трёх факторов: качества курса, вашей активности и текущего спроса на рынке труда.</p><h3>Что выбрать: универсальный курс или узкую специализацию?</h3><p>Зависит от вашей подготовки:</p><ul><li>Универсальный курс: подходит новичкам. Дает обзор направлений, помогая выбрать специализацию. Минус — знания менее глубокие.</li><li>Узкая специализация: для тех, кто знает, чего хочет. Дает глубокие навыки для конкретной роли, но требует начальной базы или четкой цели.</li></ul><p>Так НЕ надо:</p><ul><li>Брать узкую специализацию «потому что все советуют», без анализа своих склонностей (например, идти в кибербезопасность, хотя нравится работа с данными).</li><li>Выбирать универсальный курс в надежде потом определиться — это растягивает сроки выхода на рынок.</li></ul><p>Новичкам лучше начать с универсального курса, чтобы понять рынок, а затем углубиться в нишу.</p>]]></content:encoded>
    </item>
  </channel>
</rss>