<?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>Java</title>
    <description>Java — статьи, обучающие материалы и новости, посвящённые одному из самых популярных языков программирования.</description>
    <link>https://tproger.ru/tag/java</link>
    <atom:link href="https://tproger.ru/tag/java/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Sun, 27 Sep 2026 08:44:44 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>Java</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Producer-Consumer на Java, Go и Rust: одна задача и три уровня решения</title>
      <link>https://tproger.ru/articles/producer-consumer-na-java-go-i-rust-odna-zadacha-i-tri-urovnya-r</link>
      <comments>https://tproger.ru/articles/producer-consumer-na-java-go-i-rust-odna-zadacha-i-tri-urovnya-r?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Tproger]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/producer-consumer-na-java-go-i-rust-odna-zadacha-i-tri-urovnya-r</guid>
      <description><![CDATA[<p>Три уровня решения задачи производителя и потребителя: BlockingQueue в Java, каналы в Go и очередь без блокировок на Rust. Разбираемся, какой уровень нужен вам.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/producer-consumer-na-java-go-i-rust-odna-zadacha-i-tri-urovnya-r">Producer-Consumer на Java, Go и Rust: одна задача и три уровня решения</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Многопоточность]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Паттерны проектирования]]></category>
      <category><![CDATA[Потоки и блокировки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 08 Sep 2026 09:00:57 GMT</pubDate>
      <content:encoded><![CDATA[<p>Задача Producer-Consumer звучит обманчиво просто: одни потоки производят элементы, другие их разбирают, а между ними стоит буфер. На собеседовании её просят решить почти всегда, и почти всегда кандидат берётся писать координацию потоков руками.</p><p>Между тем у этой задачи есть три принципиально разных уровня решения, и выбор уровня определяется не языком, а требованиями к задержке. Разбираем все три: блокирующую очередь на Java, каналы и горутины в Go и очередь без блокировок на Rust.</p><p>Producer-Consumer — это схема, в которой производители и потребители работают независимо, обмениваясь данными через общий буфер конечной ёмкости. Ёмкость здесь работает главным механизмом защиты: именно она не даёт быстрым производителям завалить медленных потребителей.</p><p>Ручная координация через wait() и notifyAll() в блоках синхронизации даёт гонки и ложные пробуждения, а активное ожидание в цикле впустую жжёт процессор.</p><p>Готовая блокирующая очередь решает задачу целиком: при переполнении она сама останавливает производителя, обеспечивая обратное давление вместо переполнения памяти.</p><p>Горутины — это не потоки операционной системы, а лёгкие единицы, которые планировщик рантайма раскладывает по потокам, поэтому создавать их можно в количествах, немыслимых для системных потоков.</p><p>Три гарантии прогресса различаются строго: obstruction-free требует отсутствия помех, lock-free гарантирует прогресс системы в целом, wait-free — завершение каждой операции за ограниченное число шагов.</p><p>Отсутствие блокировок и использование атомарных операций сами по себе не дают wait-free: цикл повторных попыток без верхней границы — это lock-free, как бы его ни называли в описании библиотеки.</p><h2>Уровень первый: блокирующая очередь Producer-Consumer</h2><p>С этого уровня начинают почти все, и здесь же <a href="https://dev.to/machinecodingmaster/mastering-the-producer-consumer-pattern-in-java-lld-the-restaurant-kitchen-khn">делают три типовые ошибки</a>:</p><ul><li>Писать собственную логику блокировок через wait() и notifyAll() внутри синхронизированных блоков. Это приносит тонкие гонки и баги ложного пробуждения, когда поток просыпается без всякого уведомления.</li><li>Крутить активное ожидание в бесконечном цикле поверх коллекции, не рассчитанной на многопоточность. Процессор загружен постоянной проверкой размера очереди, а корректности всё равно нет.</li><li>Не предусмотреть обратного давления. Когда производители быстрее потребителей, буфер растёт, пока приложение не упрётся в нехватку памяти.</li></ul><p>Правильная ментальная модель здесь кухонная: повара выкладывают блюда на раздачу фиксированной вместимости, официанты забирают их по готовности. Раздача заполнена — повар ждёт, и это нормальная работа системы, а не сбой.</p><p>В Java всё это уже реализовано в стандартной библиотеке:</p><p>Вся координация потоков спрятана внутри реализации очереди, и явных блокировок в коде не остаётся вовсе. Метод put останавливает производителя при переполнении, и это и есть обратное давление, ради которого затевалась ограниченная ёмкость.</p><h2>Уровень второй: передача сообщений вместо общей памяти</h2><p>Go подходит к задаче с другой стороны. Вместо того чтобы защищать общий буфер, язык предлагает передавать данные между независимыми исполнителями. Запускается такой исполнитель одним словом:</p><p>Ключевое слово go перед вызовом запускает функцию конкурентно. Правда, у примера выше есть подвох: когда main завершается, программа выходит целиком, и горутина может не успеть отработать. Дожидаться её нужно явно:</p><h3>Где здесь, собственно, очередь</h3><p>Горутины сами по себе задачу производителя и потребителя не решают: WaitGroup лишь дожидается завершения, буфера и обратного давления в нём нет. Роль ограниченной очереди в Go играет буферизированный канал, и это прямой аналог кухонной раздачи из предыдущего раздела:</p><p>Поведение совпадает с блокирующей очередью один в один: отправка встаёт при переполнении, приём встаёт на пустом канале. Разница в акценте. В Java вы защищаете общий буфер, в Go передаёте значение из одной горутины в другую, и владение данными переходит вместе с ним.</p><h3>Почему это не просто потоки с коротким именем</h3><p>Горутина не является потоком операционной системы. Это лёгкая единица конкурентного исполнения, которой управляет рантайм языка: он раскладывает горутины по небольшому набору системных потоков сам. Отсюда и практическое следствие — можно оперировать очень большим числом конкурентных задач, не создавая и не сопровождая отдельный системный поток под каждую.</p><p>Здесь же полезно развести два понятия, которые постоянно путают. Конкурентность — это способ структурировать программу так, чтобы несколько задач продвигались независимо. Параллелизм означает фактическое одновременное исполнение на нескольких вычислительных ресурсах. Программа может быть конкурентной, и при этом ни одна пара её задач не выполняется буквально в один момент.</p><h2>Уровень третий: очередь без блокировок</h2><p>Третий уровень нужен, когда неприемлема сама возможность того, что поток уснёт на блокировке. Это низкая задержка в торговых системах, обработка звука, ядра планировщиков. И здесь начинается терминология, в которой путаются чаще всего.</p><h3>Три гарантии прогресса</h3><p><b>Obstruction-free.</b> Операция завершится, если в какой-то момент ей дадут поработать без помех со стороны других потоков. При непрерывных помехах прогресс не гарантирован вообще. Самая слабая из трёх гарантий.</p><p><b>Lock-free.</b> Гарантирует прогресс системы в целом: даже если один поток застрял, какой-то другой обязательно завершит свою операцию. Отдельный поток при этом может голодать сколь угодно долго, но система не встаёт целиком.</p><p><b>Wait-free.</b> Каждая операция завершается за ограниченное число шагов независимо от того, что делают остальные потоки. Ключевая формулировка здесь именно «ограниченное число шагов», а не «обычно быстро», «не использует блокировок» или «работает на атомарных операциях». Это формальное свойство, а не характеристика скорости.</p><p><b>Два неравенства, которые стоит запомнить:</b><br />Отсутствие блокировок не равно wait-free. Использование атомарных операций тоже не равно wait-free.</p><h3>Почему мьютекса недостаточно</h3><p>Очередь, обёрнутая в мьютекс, — это совершенно корректный многопоточный код на Rust. Но wait-free она не является: поток, захвативший блокировку, может быть снят с процессора планировщиком, и все остальные будут ждать его возвращения неограниченно долго. Для большинства задач это приемлемо, для систем с жёсткими требованиями по задержке уже нет.</p><h3>Атомарность и упорядочивание — разные вещи</h3><p>Процессор гарантирует, что атомарная операция неделима. Этого мало: нужно ещё, чтобы потребитель увидел записи, сделанные производителем <b>до</b> публикации флага. За это отвечает модель упорядочивания памяти.</p><p>Пара «освобождение и захват» создаёт отношение синхронизации: если потребитель увидел освобождающую запись, он гарантированно видит и все предшествовавшие ей записи. Это одна из центральных идей программирования без блокировок, и именно её упускают, заменяя мьютекс на атомарную операцию без всего остального.</p><h3>Кольцевой буфер и номера последовательности</h3><p>Практическая конструкция ограниченной очереди для нескольких производителей и нескольких потребителей строится на кольцевом буфере с двумя атомарными счётчиками логических позиций. Физический слот вычисляется как остаток от деления позиции на ёмкость, а при ёмкости, равной степени двойки, деление заменяется маской по битам.</p><p>Каждый слот хранит не только значение, но и номер последовательности, по которому определяется, какому логическому поколению этот слот сейчас принадлежит:</p><p>Тип UnsafeCell здесь означает ровно то, что написано на упаковке: обращаться к значению можно только из блока unsafe, компилятор проверку прекращает, и инвариант «в конкретный момент со слотом работает один поток» держится на номере последовательности, а не на системе типов.</p><p>Тип MaybeUninit здесь не для красоты: при ёмкости в 1024 элемента нужны 1024 места под значения, а не 1024 сконструированных объекта. Производитель получает уникальную позицию одним атомарным инкрементом, и никакого соревнования за неё не возникает:</p><p>Последние три строки стоит запомнить, потому что через абзац они окажутся важны. Позиция достаётся производителю без соревнования, а вот дальше он крутится в ожидании, пока слот не перейдёт к его поколению. Верхней границы у этого ожидания нет.</p><h3>Где заканчивается честность в названиях</h3><p>Неприятная правда, которую стоит знать до выбора библиотеки: многое из того, что продаётся как wait-free очередь, на деле является lock-free. Причина в устройстве ядра алгоритма:</p><p>Операция обычно завершается быстро, но верхней границы на число неудачных попыток здесь нет, а именно она и определяет wait-free. И да, ровно такой цикл вы только что видели в нашей собственной очереди: строго говоря, на этом шаге она тоже lock-free, а не wait-free, и автор исходного разбора это прямо оговаривает. Строгая реализация требует ограниченной стратегии резервирования или механизма помощи: когда поток B встречает незавершённую операцию потока A, он не ждёт возвращения A, а доводит его операцию до конца сам. Так прогресс перестаёт зависеть от того, что планировщик сделал с конкретным потоком.</p><h2>Какой уровень выбрать</h2><p>Правило простое и почти всегда работает от обратного.</p><ul><li>Блокирующая очередь из стандартной библиотеки закрывает подавляющее большинство задач. Начинайте с неё и не пишите координацию потоков вручную.</li><li>Модель с передачей сообщений выигрывает, когда конкурентных задач много, а связи между ними хочется описать явно, а не через набор общих структур под блокировками.</li><li>Алгоритмы без блокировок берутся, когда есть измеренное требование к задержке, которое блокировка нарушает: не «хочется быстрее», а конкретная цифра в бюджете. И в продакшене их берут готовыми из библиотек вроде crossbeam, а разбирают по косточкам ради понимания механики.</li></ul><p>Ошибка почти всегда идёт в одну сторону: за атомарные операции берутся раньше, чем появилась причина, и получают код, который сложнее отлаживать, а гарантий даёт не больше.</p><h2>Что забрать с собой</h2><p>Задача Producer-Consumer решается на трёх уровнях, и уровень выбирается требованиями, а не вкусом. Ограниченный буфер с обратным давлением закрывает большинство случаев. Передача сообщений упрощает структуру, когда конкурентных задач становится много. Алгоритмы без блокировок нужны там, где блокировка нарушает измеренный бюджет задержки, и тогда важно понимать, какую именно гарантию вы покупаете.</p><p>Материалы разбора: <a href="https://dev.to/machinecodingmaster/mastering-the-producer-consumer-pattern-in-java-lld-the-restaurant-kitchen-khn">задача о ресторанной кухне на Java</a>, <a href="https://dev.to/ashitoshh01/why-does-go-have-goroutines-understanding-gos-lightweight-concurrency-341p">введение в горутины и модель конкурентности Go</a> и <a href="https://dev.to/derekmwale/building-a-wait-free-queue-in-rust-2329">построение wait-free очереди на Rust</a>.</p><p>Если в вашем коде есть класс, где потоки координируются через ручные ожидания и уведомления, у вас уже есть кандидат на замену стандартной очередью. Начните с него.</p>]]></content:encoded>
    </item>
    <item>
      <title>ИИ-агент собрал сам себя: эксперимент с LangChain4j и уроки для Java-разработчиков</title>
      <link>https://tproger.ru/articles/ii-agent-sobral-sam-sebya-eksperiment-s-langchain4j-i-uroki-dlya</link>
      <comments>https://tproger.ru/articles/ii-agent-sobral-sam-sebya-eksperiment-s-langchain4j-i-uroki-dlya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/ii-agent-sobral-sam-sebya-eksperiment-s-langchain4j-i-uroki-dlya</guid>
      <description><![CDATA[<p>LLM по документации LangChain4j собрала клона себя — мультиагентного кодера. Он починил баги, прошёл 11 тестов и показал, почему workflow быстрее supervisor.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/ii-agent-sobral-sam-sebya-eksperiment-s-langchain4j-i-uroki-dlya">ИИ-агент собрал сам себя: эксперимент с LangChain4j и уроки для Java-разработчиков</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Фреймворки и библиотеки]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 25 Jul 2026 06:50:22 GMT</pubDate>
      <content:encoded><![CDATA[<p>Если вы строите агентные системы на Java, вот факт, о котором стоит знать: LLM уже способна по одной документации фреймворка спроектировать и написать мультиагентную систему — по сути, клона самой себя. Инженеры Red Hat Кевин Дюбуа и Марио Фуско провели такой мета-эксперимент с <b>LangChain4j</b>, и получившийся «самособранный» агент не только запустился, но и починил реальные баги в коде, прогнав все 11 тестов. Заодно выяснилось, что детерминированный workflow решает ту же задачу <b>втрое быстрее</b> автономного супервизора — два минуты против шести с лишним.</p><p><b>LangChain4j</b> — это Java-фреймворк для приложений на базе больших языковых моделей, аналог LangChain из мира Python. Его модуль <b>langchain4j-agentic</b> позволяет описывать агентные системы декларативно: прямо в Java-интерфейсах, через аннотации. Эксперимент Дюбуа и Фуско проверял две вещи сразу: достаточно ли «читаем» API фреймворка, чтобы модель использовала его без подсказок, и как ведут себя два главных паттерна агентных систем — <b>supervisor</b> и <b>workflow</b> — на одной и той же задаче отладки кода.</p><p>ИИ-ассистент по документации LangChain4j сам спроектировал и реализовал мультиагентного кодера — клона самого себя: супервизор плюс четыре субагента.</p><p>Собранная система починила все баги в тестовом классе Calculator: 11 тестов из 11 зелёные, сборка Maven успешна.</p><p>Модель gpt-4o провалила задачу, уйдя в цикл вызовов инструментов (сработал лимит в 100 вызовов), а более свежая gpt-5-mini справилась.</p><p>Жёсткий workflow-паттерн выполнил ту же задачу за 2 минуты против 6+ минут у supervisor-паттерна: автономная координация через LLM стоит дорого.</p><p>Новый интерфейс MonitoredAgent (langchain4j-agentic 1.12.2-beta22) показывает топологию системы и трейс вызовов агентов.</p><h2>Вайбкодинг агента: промпт, который собрал агента</h2><p>Идея эксперимента предельно проста: отдать код-ассистенту документацию и исходники LangChain4j и попросить собрать на их основе клона самого себя. Дословно промпт звучал так: «Изучи API и возможности агентного фреймворка LangChain4j по его документации и исходному коду и спроектируй на его основе агентного кодера, который будет клоном тебя самого».</p><p>Через несколько минут размышлений ассистент выбрал <b>supervisor-паттерн</b>: главный агент-координатор, который сам решает, какого субагента вызвать и с какими аргументами. Архитектура получилась такой — обратите внимание, вся система описывается одним аннотированным интерфейсом:</p><p>Ассистент спроектировал и написал четырёх субагентов, а также инструменты для каждого из них. Если вы пользовались «взрослыми» код-ассистентами, схема покажется знакомой — это ровно те четыре роли, которые такие инструменты исполняют внутри:</p><ul><li><b>ExplorerAgent</b> — изучает кодовую базу (получил инструмент обхода файловой системы);</li><li><b>PlannerAgent</b> — составляет план изменений;</li><li><b>ImplementerAgent</b> — пишет и правит код (получил редактор кода);</li><li><b>ExecutorAgent</b> — компилирует и запускает результат.</li></ul><p>Отдельно интересно, что модель воспроизвела собственное внутреннее устройство «сходу», без объяснений: похоже, современные LLM действительно имеют высокоуровневое представление о том, как устроены они сами, и умеют переводить его в рабочий дизайн агентной системы.</p><h2>Проверка боем: агент чинит баги в Calculator</h2><p>Чтобы испытать собранную систему, авторы пошли от обратного: попросили ассистента написать класс Calculator с четырьмя методами, в каждом из которых спрятан классический баг. Набор получился показательный — такие ошибки джуны делают постоянно:</p><ul><li>в методе sum() выход за границу списка: цикл до i &lt;= size();</li><li>в average() целочисленное деление вместо дробного;</li><li>в max() стартовое значение 0 — ломается на списке из отрицательных чисел;</li><li>в factorial() цикл до i &lt; n — факториал недосчитан на один множитель.</li></ul><p>Дальше ассистент сгенерировал интеграционный тест: скопировать проект с багами во временную папку и натравить на него агентного кодера:</p><h3>Первая попытка: gpt-4o уходит в цикл</h3><p>Первый прогон делали на <b>gpt-4o</b> — это модель по умолчанию в LangChain4j, и она поддерживает вызов инструментов. Результат: через несколько минут система упала с ошибкой. LLM застряла в цикле вызовов инструментов, и фреймворк прервал её на лимите в <b>100 последовательных вызовов</b>:</p><p><b>Полезно знать:</b> лимит в 100 вызовов инструментов подряд — дефолт LangChain4j. Он настраивается методом <b>maxToolCallingRoundTrips()</b> в AiServices, но дефолт вполне разумный: здоровому агенту столько вызовов не нужно, а беззащитный цикл сожжёт бюджет на токены.</p><h3>Вторая попытка: gpt-5-mini чинит всё</h3><p>Авторы уже сталкивались с таким поведением у старых моделей, поэтому просто заменили модель на <b>gpt-5-mini</b> — и тот же самый агентный дизайн отработал чисто. Система нашла все четыре бага, переписала методы (for-each вместо индексного цикла, приведение к (double) в среднем, инициализация максимума первым элементом, включительная граница в факториале) и отчиталась:</p><ul><li><b>mvn package</b> — BUILD SUCCESS;</li><li><b>mvn test</b> — 11 тестов, 0 падений, 0 ошибок;</li><li>финальный вердикт агента: «All tests in CalculatorTest.java pass (11/11)».</li></ul><p>Это важный практический вывод, который часто недооценивают: <b>агентная архитектура неотделима от модели, на которой она работает</b>. Один и тот же дизайн на одной модели захлёбывается в tool-calling цикле, а на другой решает задачу. Прежде чем переписывать оркестрацию, попробуйте сменить модель.</p><h2>Смотрим под капот: MonitoredAgent</h2><p>Когда один ИИ собирает другого ИИ, вопрос «а что там внутри происходит» перестаёт быть риторическим. В версии <b>1.12.2-beta22</b> модуля langchain4j-agentic появился интерфейс MonitoredAgent: достаточно унаследовать от него корневой интерфейс системы, и фреймворк сам зарегистрирует монитор — можно распечатать отчёт о вызовах агентов и топологию системы:</p><p>По такому отчёту видно, какой агент когда вызывался и как система фактически связана в граф — без ручного сбора листенеров и регистрации AgentMonitor.</p><h2>Supervisor против workflow: автономия или скорость</h2><p>Автономность супервизора имеет скрытую цену: каждый шаг координации — это дополнительный вызов LLM, который «придумывает», кого вызвать дальше и с какими аргументами. Чтобы измерить эту цену, авторы попросили ассистента перепроектировать систему в детерминированном виде — только на workflow-паттернах LangChain4j.</p><p>Получилась строгая последовательность из пяти шагов: те же четыре роли плюс отдельный <b>SummarizerAgent</b>, который забрал у супервизора функцию финального отчёта. Шаги планирования и исполнения оформлены как циклы с самопроверкой:</p><p>Цикл исполнения устроен как связка «исполнитель → оценщик → рефактор»: итерации продолжаются, пока оценка качества не достигнет <b>0.8</b>, но не дольше <b>5 итераций</b> — защита от бесконечного сжигания токенов:</p><p>Та же задача с багами в Calculator — тот же результат: все тесты зелёные, финальная оценка качества 0.8. Но по времени картина разительно другая: <b>две минуты у workflow против более чем шести у supervisor</b>. Втрое быстрее — при большем числе агентов в системе. Вся разница — устранение координационных вызовов LLM: в workflow каждый следующий шаг известен заранее и «мнения» модели на этот счёт не требуется.</p><p>Это не означает, что supervisor не нужен. Выбор зависит от природы задачи:</p><ul><li><b>Workflow</b> — когда задача раскладывается на предсказуемые этапы и важны скорость, стоимость и воспроизводимость. Детерминированная последовательность, циклы самопроверки — и никаких сюрпризов.</li><li><b>Supervisor</b> — когда маршрут по шагам заранее неизвестен и важнее гибкость: главный агент на лету решает, кого вызывать. Платите за это временем и токенами.</li></ul><h2>Что это значит на практике</h2><p>Эксперимент Дюбуа и Фуско красиво подтверждает рекомендации, которые Anthropic <a href="https://www.anthropic.com/engineering/building-effective-agents">сформулировала в гайде по эффективным агентам</a>: начинайте с простейшего детерминированного пайплайна и добавляйте автономность только там, где без неё никак. Каждый «свободный» шаг координации — это лишний вызов модели: и по деньгам, и по латентности, и по шансу уйти в цикл. Замер в статье (3x на одной тривиальной задаче) — хорошая иллюстрация того, во что это превращается в проде.</p><p>Второй урок — про «вайбкодинг» агентных систем. То, что LLM собрала рабочую мультиагентную систему по документации, говорит больше о качестве API LangChain4j, чем о магии моделей: аннотации @SupervisorAgent, @SequenceAgent и @LoopAgent читаются как обычный декларативный дизайн, и модели это по зубам. Для Java-команд это практический повод присмотреться к фреймворку: порог входа в агентные системы здесь заметно ниже, чем кажется.</p><p>И третье: отлаживайте агентов как распределённую систему. Трейс вызовов и топология из MonitoredAgent — это тот же распределённый трейсинг, к которому вы привыкли в микросервисах, только спаны здесь — вызовы LLM. Без него вы не узнаете, что система половину бюджета потратила на «размышления» супервизора.</p><h2>Выводы</h2><blockquote>Выбирайте workflow, когда критичны скорость, предсказуемость и цена выполнения. Выбирайте supervisor, когда автономность и гибкость важнее скорости — но помните, что свобода координации оплачивается токенами и временем.</blockquote><p>Самособирающийся агент — пока эксперимент, а не продакшн-практика. Но три вывода из него применимы уже сегодня. Первый: хорошо спроектированный декларативный API читаем не только для людей, но и для моделей — и это становится критерием качества фреймворка. Второй: детерминированный workflow на предсказуемых задачах даёт троекратный выигрыш во времени — автономию стоит включать точечно. Третий: агентная система наследует слабости своей модели, поэтому мониторинг и лимиты вызовов — не опция, а необходимость.</p><p><b>Источники:</b> оригинальная статья — <a href="https://www.infoq.com/articles/self-building-agent-langchain4j/">The Self-Building Agent: A LangChain4j Experiment</a> (InfoQ); код эксперимента — <a href="https://github.com/mariofusco/langchain4j-agentic-coder">репозиторий langchain4j-agentic-coder</a>; документация — <a href="https://github.com/langchain4j/langchain4j/blob/main/docs/docs/tutorials/agents.md">Agentic Systems в LangChain4j</a>.</p><p>Если строите агентные системы на Java — возьмите репозиторий, прогоните тест на своей модели и сравните supervisor с workflow на своих задачах. Цифры могут удивить.</p>]]></content:encoded>
    </item>
    <item>
      <title>Один фреймворк для Android и iOS: звучит круто, работает?  Нет</title>
      <link>https://tproger.ru/articles/odin-frejmvork-dlya-android-i-ios-zvuchit-kruto-rabotaet-net</link>
      <comments>https://tproger.ru/articles/odin-frejmvork-dlya-android-i-ios-zvuchit-kruto-rabotaet-net?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Роман Новохацкий]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/odin-frejmvork-dlya-android-i-ios-zvuchit-kruto-rabotaet-net</guid>
      <description><![CDATA[<p>Почему единый кроссплатформенный фреймворк для автотестов Android и iOS не работает на практике и когда стоит разделить его на два отдельных проекта.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/odin-frejmvork-dlya-android-i-ios-zvuchit-kruto-rabotaet-net">Один фреймворк для Android и iOS: звучит круто, работает?  Нет</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Распознавание]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[GitLab]]></category>
      <category><![CDATA[Kotlin]]></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>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 23 Jul 2026 13:20:45 GMT</pubDate>
      <content:encoded><![CDATA[<p>Я сделал автотесты на Appium для Android и iOS в одном проекте. Один репозиторий, общий фреймворк, общие Page Objects, общие steps. Красота.</p><p>Потом проект вырос, в команду пришли ещё люди, и стало понятно: этот красивый монолит пора разделять.</p><p>Это было взвешенное решение. В какой-то момент общий фреймворк превратился в поле мерж-конфликтов, где ты уже не тесты пишешь, а разбираешься, кто чей page object сломал и почему Android отвалился после правки для iOS.</p><p>Appium тут ни при чём, как и скорость тестов. Проблема была в архитектуре: один общий слой для двух разных платформ начал мешать сильнее, чем помогать.</p><p>Как говорил один мой коллега, перефразируя классическое “вам шашечки или ехать”:</p><blockquote>Ты сюда страдать пришёл или тесты писать?</blockquote><p>После этого решение разделить Android и iOS на два проекта стало очевидным.</p><p>Сейчас у меня два отдельных проекта: mb-android-tests и mb-ios-tests. И знаете что? Это лучшее архитектурное решение за всё время на этом проекте. Серьёзно.</p><p><b>Контекст: что за проект и почему это важно</b></p><p>Финтех. Нативное приложение. Отдельные кодовые базы, Kotlin на Android, Swift на iOS. И UI там не «три кнопки и список», формы с десятками полей, кастомные контролы, WebView-вставки, платежи, валютные операции, бюджетные переводы. Ну вы поняли.</p><p>Стек: Java 21, TestNG, Appium 2.x, Selenide, Allure, Maven. CI на GitLab, крутится на Mac Mini. 5 Android-эмуляторов, 4 iOS-симулятора, 9 Appium-серверов — по одному на устройство.</p><p>Но это сейчас. А начиналось всё с одного жирного монолита.</p><p><b>Старый проект: 8 модулей и конструктор-монстр</b></p><figure><img src="https://media.tproger.ru/user-uploads/139426/2026-07-07/54be52bb-7e50-4e11-b624-86cc1ce0766b.webp" alt="" /></figure><p>Идея была «как в книжке»: один репозиторий, модульная структура, переиспользование. DRY во все поля. Ну а чё, красиво же.</p><p>8 модулей. Один mvn clean install. Все зависят от mobile-automation-framework, в котором живут DriverFactory, BaseTest, общие Page Objects и слой Steps.</p><p>А DriverFactory принимал <b>11 параметров</b>. Одиннадцать, Карл.</p><p>Половина нужна только Android, другая только iOS. Но метод один. Потому что так более по программистцки, как написано в каждой второй статье про архитектуру автотестов.</p><p>Когда я работал один, было норм. Ты сам знаешь, от куда что идет.</p><p>А потом пришли люди.</p><p><b>Почему с людьми всё навернулось</b></p><p><b>Мерж-конфликты каждый божий день</b></p><p>Вот конкретная ситуация. Один человек правит LoginPage в общем фреймворке, добавляет метод для iOS, меняет локатор. Второй в тот же момент рефакторит этот же LoginPage под новую версию Android-приложения.</p><p>Мерж. Конфликт.</p><p>И тут начинается самое весёлое: какой локатор правильный? Для Android? Для iOS? Для обоих? Кто будет разбираться? Тот, кто мёрджит? А он вообще контекст понимает?</p><p>Это не единичный случай. Это было <b>каждый</b> день. Потому что mobile-automation-framework получился общим модулем, от которого зависят все. И все туда лезут. Постоянно.</p><figure><img src="https://media.tproger.ru/user-uploads/139426/2026-07-07/3866002d-86c5-4894-a441-2522f48dcab1.webp" alt="" /></figure><p><b>Обновление одной библиотеки = блокировка всех</b></p><p>Решил обновить java-client с 7.x на 8.x. Нормальное желание — API поменялся, MobileElement удалили, capabilities переехали на типизированные Options.</p><p>Вот что произошло в реальности:</p><ol><li>Меняю версию в parent pom.xml</li><li>MobileElement удалён → compilation error в DriverFactory, во всех DriverManager’ах</li><li>DesiredCapabilities → UiAutomator2Options / XCUITestOptions → переписываю все менеджеры</li><li>selenide-appium 1.x несовместим с java-client 8.x → обновляю до 2.x</li><li>selenide-appium 2.x требует Selenide 6.x → обновляю Selenide</li><li>Selenide 6.x ломает API page objects → переписываю page objects во всех модулях</li><li>А Selenide 6.x ещё и Java 8 не поддерживает → обновляю Java</li></ol><p>Одна библиотека.</p><p>Задача «обновить одну библиотеку» превратилась в 50+ файлов, 4-5 каскадных обновлений, 2-3 недели работы. И всё это время develop нестабилен. Все заблокированы. Тесты не запускаются.</p><p>Две недели.</p><p>Из-за одной строчки в pom.xml.</p><p><b>Page Objects с if/else — это два page object в одном файле</b></p><p>Общие Page Objects звучат красиво на бумаге: пишем один раз, используем для обеих платформ. А на практике…</p><p>Это не page object. Это два page objects, запиханных в один файл через if/else. И так в каждом методе.</p><p>А сверху ещё слой Steps. Обёртки над page objects «для читаемости». И в steps тоже if (platform), потому что логика взаимодействия разная. На Android ты скроллишь через UiScrollable семантически, «прокрути до элемента с текстом X». На iOS координатами, «двигай палец из точки A в точку B». Один метод в steps, а внутри два разных мира.</p><p>В какой-то момент ловишь себя на мысли: я же не тесты пишу. Я подгоняю pages и steps под две платформы, чтобы фреймворк не развалился. Это уже не автоматизация тестирования, это поддержка фреймворка ради поддержки фреймворка.</p><p><b>Каждый работает в своём темпе и все друг другу мешают</b></p><p>У одного задача покрыть тестами новый экран на Android. У второго пофиксить падающие тесты на iOS. У третьего добавить тестовые данные.</p><p>Все трое лезут в mobile-automation-framework. Все трое меняют pom.xml, BaseTest, page objects. Каждый в своей ветке.</p><p>А потом мёрдж.</p><p><b>Технические причины, которые добили окончательно</b></p><p>Ладно, человеческий фактор. Но были и чисто технические штуки, которые окончательно убедили меня, что кроссплатформа тут бессмысленна.</p><p><b>Локаторы: работай с тем, что дают</b></p><p>Сразу скажу то, о чём мало кто пишет в статьях: в мобильной автоматизации ты работаешь с тем, что дают, а не с тем, что хотелось бы.</p><p>В теории есть AccessibilityID единый локатор для обеих платформ. Звучит хорошо. А на практике? Попробуй попросить мобильных разработчиков расставить одинаковые accessibility-идентификаторы на сотнях экранов. На Kotlin и Swift. Одновременно. Они тебя вежливо пошлют, но скорее всего не вежливо. И будут правы, у них свои спринты, свои дедлайны, и твои автотесты в их приоритетах где-то между «поправить тень у кнопки» и «никогда».</p><p>Так что реальный выбор:</p><p><b>XPath -</b> работает, но на iOS может быть тормозным. На Android через UiSelector быстро, нативно, надёжно. На iOS через NSPredicate тоже ок. А «универсальные» XPath типа //*[@text='Войти' or @label='Войти']  это путь к боли, потому что Page Source на двух платформах два совершенно разных XML-дерева.</p><p><b>Координаты -</b> костыль? Да. Но иногда единственный вариант. Когда у тебя кастомный контрол без accessibility-свойств, а разработчик говорит «это декоративный элемент», ты либо тыкаешь по координатам, либо не тестируешь.</p><p><b>OpenCV</b> - есть ещё вариант с распознаванием элементов по картинке. Для некоторых кейсов реально выручает. Но это отдельная тема на целую статью, может напишу потом.</p><p>Суть в том, что «напиши один локатор и работай на двух платформах» это миф. Page Source на Android это android.widget.Button с resource-id. На iOS  XCUIElementTypeButton с name и label. Разные типы элементов, разные атрибуты, разная глубина вложенности. Разные миры.</p><p><b>StaleElementReferenceException — «подарок» от iOS</b></p><p>Android рендерит UI через Choreographer синхронно с VSYNC. Элемент появился → стабилен → кликаем.</p><p>iOS рендерит через CoreAnimation с неявными анимациями. Элемент есть в дереве, но ещё анимируется. Формально кликабелен, фактически хрен.</p><p>Стандартный WebDriverWait с elementToBeClickable это не ловит. Элемент «кликабелен» по мнению Appium wait завершается. А потом click() падает, потому что DOM изменился между вызовами.</p><p>На Android этой проблемы нет вообще. Тот же тест, тот же wait, тот же код зелёный на Android, красный на iOS. Один и тот же метод, два разных результата. И это не баг это фундаментальное различие платформ.</p><p>Кастомные wait-стратегии для iOS отличаются от Android принципиально. Пихать их в один фреймворк строить leaky abstraction, которая протекает на каждом шаге.</p><p><b>Жесты — два разных мира</b></p><p>Свайп вниз на Android:</p><p>Свайп вниз на iOS:</p><p>Чувствуете разницу? И даже длительность свайпа важна: на Android 200мс это нормальный скролл. На iOS 200мс это fling, и элемент улетает за экран.</p><p>«Кроссплатформенная» обёртка для скролла функция на 40 строк с двумя ветками if (platform), внутри каждой и ещё if для performSwipeDown() vs performSwipeUp(). На 50+ экранах таких обёрток, которых десятки.</p><p>И каждая место для бага.</p><p><b>Решение: разделяй и властвуй</b></p><p>Решение было болезненным. Я реально откладывал, потому что казалось, что это шаг назад. Дублирование кода, нарушение DRY, всё такое. Мозг сопротивлялся.</p><p>А потом я просто сел и разделил.</p><p>Никаких общих page objects. Никаких общих steps. Никакого общего DriverFactory с 11 параметрами. Каждый проект со своим pom.xml, свои зависимости, свой BaseTest, свои локаторы.</p><p>Что осталось общего: подход к структуре (Maven + TestNG + Allure), CI-шаблоны, принципы организации. Но не код. Код полностью раздельный.</p><p><b>Что поменялось на практике</b></p><p>В Android-проекте DriverManager типизирован под AndroidDriver. В iOS под IOSDriver. Не AppiumDriver&lt;MobileElement&gt; с кастами и проверками, а конкретный тип для конкретной платформы. IDE подсказывает только релевантные методы. Компилятор ловит ошибки на этапе сборки, а не в рантайме.</p><p>BaseTest принимает ровно те параметры, которые нужны. Android: deviceName, platformVersion, udid, appPackage, appActivity, systemPort, serverUrl, appPath — 8 штук, все релевантные. iOS: deviceName, platformVersion, udid, appPath, serverUrl, wdaLocalPort — 6. Никаких @Optional("systemPort") со строкой “systemPort” в качестве дефолта.</p><p><b>А мерж-конфликты?</b></p><p>Когда один человек работает в mb-android-tests, а второй в mb-ios-tests то они <b>вообще</b> не пересекаются. Разные репозитории. Конфликт невозможен физически.</p><p>Обновление java-client в Android-проекте не затрагивает iOS. Хочешь обновить, обновляй. iOS продолжает работать на старой версии.</p><p>Добавить новый параметр для iOS? Меняешь BaseTest и testng.xml в iOS-проекте. Android даже не узнает.</p><p>Это прям кайф.</p><p><b>А как же дублирование кода?!</b></p><p>Конечно, конечно. Первый вопрос, который задают: «Но ведь ты пишешь тесты дважды!»</p><p>Нет.</p><p>Я пишу каждый тест один раз и без костылей. Без if (platform) в каждом методе. Да, для одного и того же экрана есть два теста, один для Android, один для iOS. Но каждый из них чистый, понятный, заточенный под свою платформу.</p><p>В старом варианте я тоже «писал один раз», а потом тратил столько же времени на поддержку if/else, мерж-конфликты и каскадные обновления. «Экономия» на создании оборачивалась переплатой на поддержке. С процентами.</p><p><b>Когда кроссплатформа всё-таки ок</b></p><p>Я не топлю за то, что кроссплатформенный фреймворк абсолютное зло. Есть ситуации, где он работает:</p><p>Приложение простое, пара экранов, стандартные контролы, минимум кастомного UI.</p><p>UI реально идентичен на обеих платформах. Бывает, наверное.</p><p>Команда из одиного человека. Сам пишешь, сам мёрджишь, сам разруливаешь. Голова справляется.</p><p>Минимум жестов. Нет сложных свайпов, drag-and-drop, pinch-to-zoom.</p><p>Если у тебя финтех, банк, enterprise-приложение с сотнями экранов, кастомными контролами и тремя+ QA, то два проекта дешевле. Не в строках кода, а во времени. В нервах. В часах, потраченных на мерж-конфликты вместо написания тестов.</p><p><b>Итого</b></p><p>Два проекта это не шаг назад и не двойная работа. Со стороны может выглядеть именно так, но на практике ты пишешь каждый тест один раз, под конкретную платформу, без лишних компромиссов. Потом поддерживаешь его без постоянных мерж конфликтов, каскадных обновлений и if/else в каждом втором методе.</p><p>Кроссплатформенный фреймворк на Appium для сложного нативного приложения часто оказывается иллюзией экономии.</p><p>В следующей статье покажу, как у нас устроена инфраструктура для 9 параллельных устройств на одном Mac Mini: порты, bash скрипты, Appium серверы и workaround’ы, которых нет в документации. Спойлер: там тоже всё не совсем как в гайдах.</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>A2A Java SDK 1.0.0: стабильный релиз для агентных приложений на Java</title>
      <link>https://tproger.ru/news/a2a-java-sdk-1-0-0-stabilnyj-reliz-dlya-agentnyh-prilozhenij-na</link>
      <comments>https://tproger.ru/news/a2a-java-sdk-1-0-0-stabilnyj-reliz-dlya-agentnyh-prilozhenij-na?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/a2a-java-sdk-1-0-0-stabilnyj-reliz-dlya-agentnyh-prilozhenij-na</guid>
      <description><![CDATA[<p>Вышел A2A Java SDK 1.0.0.Final — официальная Java-реализация протокола Agent2Agent. Разбираем ключевые изменения, как подключить SDK из Maven Central и зачем это Java-разработчикам.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/a2a-java-sdk-1-0-0-stabilnyj-reliz-dlya-agentnyh-prilozhenij-na">A2A Java SDK 1.0.0: стабильный релиз для агентных приложений на Java</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Open Source]]></category>
      <category><![CDATA[Сетевые протоколы]]></category>
      <category><![CDATA[Новости]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 16 Jun 2026 09:45:59 GMT</pubDate>
      <content:encoded><![CDATA[<p>Java-разработчики получили стабильный инструмент для создания агентных систем. <b>A2A Java SDK 1.0.0</b> вышел в релиз и доступен в Maven Central с groupId org.a2aproject.sdk. Для сборки клиента можно взять артефакт a2a-java-sdk-client или импортировать a2a-java-sdk-bom. Библиотека реализует протокол <b>Agent2Agent (A2A)</b> — открытый стандарт, управляемый Linux Foundation, для взаимодействия ИИ-агентов друг с другом.</p><p><b>Agent2Agent</b> — это протокол, управляемый Linux Foundation (изначально представленный Google), который позволяет агентам на разных фреймворках и языках находить друг друга, делегировать задачи и обмениваться результатами. Для Java-экосистемы выпуск SDK версии 1.0.0 означает переход от экспериментальных сборок к инструменту, готовому к промышленной эксплуатации.</p><p>Релиз 1.0.0 появился на прошлой неделе, как сообщает InfoQ в очередном выпуске Java News Roundup. В него вошли исправления ошибок, обновление зависимостей и несколько новых возможностей: интеграционный тестовый набор на базе Quarkus для проверки совместимости разных SDK, а также расширение интерфейса A2AHttpResponse и класса A2AClientHTTPError для доступа к HTTP-заголовкам ответов.</p><ul><li>A2A Java SDK 1.0.0 вышел в GA — первая стабильная версия для Java.</li><li>Реализует протокол Agent2Agent для взаимодействия ИИ-агентов.</li><li>Появился интеграционный тестовый набор на базе Quarkus.</li><li>Доступен в Maven Central: org.a2aproject.sdk.</li><li>Параллельно вышел A2A Jakarta 1.0.0.CR1 для Jakarta EE серверов.</li></ul><h2>Что вошло в релиз A2A Java SDK 1.0.0</h2><ul><li>Новый интеграционный тестовый набор (ITK) на базе Quarkus для проверки кросс-SDK совместимости.</li><li>Возможность получать HTTP-заголовки ответов через интерфейс A2AHttpResponse и класс A2AClientHTTPError.</li><li>Исправления ошибок и обновление зависимостей.</li><li>Готовность к использованию в production вместе с A2A Protocol Specification 1.0.</li></ul><blockquote>I am pleased to announce the release of A2A Java SDK 1.0.0.Final — our first GA release. The A2A Java SDK is the official Java implementation of the Agent2Agent (A2A) Protocol, an open standard that enables AI agents to communicate and collaborate regardless of underlying framework, language, or vendor.</blockquote><p>Параллельно команда выпустила первый релиз-кандидат <b>A2A Jakarta 1.0.0.CR1</b>. Эта интеграция помогает запускать A2A-агентов внутри Jakarta EE серверов, таких как WildFly. В CR1 переименованы пакеты и артефакты, обновлён набор TCK для работы с A2A Java SDK 1.0.0 и настроен запуск CI на Windows.</p><h2>Зачем это Java-разработчикам</h2><p>SDK позволяет строить агентные приложения на Java без привязки к Python-стеку. Агенты могут общаться с агентами на Google ADK, LangGraph, CrewAI и других фреймворках через единый протокол. Это особенно важно для команд, где основная инфраструктура уже написана на Java. Рядом с A2A развивается протокол <a href="https://tproger.ru/news/anthropic-zapustila-mcp-tunneli-i-sendboksy-dlya-korporativnyh-ai">MCP</a>: если MCP соединяет агента с инструментами, то A2A — агента с агентом.</p><p>A2A Java SDK 1.0.0 делает Java полноценной платформой для агентных приложений: теперь можно подключить SDK из Maven Central и начать строить агентов, которые работают в одной экосистеме с Python- и TypeScript-решениями.</p><p><b>Источник:</b> <a href="https://www.infoq.com/news/2026/06/java-news-roundup-jun08-2026/">InfoQ — Java News Roundup: A2A Java SDK 1.0, Jakarta EE 12, JNoSQL, GraalVM, Micrometer, OpenXava, Gradle</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Локализация через Enum, неожиданный Дзен, быстрее только телепатия</title>
      <link>https://tproger.ru/articles/lokalizaciya-cherez-enum-neozhidannyj-dzen-bystree-tolko-telepat</link>
      <comments>https://tproger.ru/articles/lokalizaciya-cherez-enum-neozhidannyj-dzen-bystree-tolko-telepat?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Самир Гёзалов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/lokalizaciya-cherez-enum-neozhidannyj-dzen-bystree-tolko-telepat</guid>
      <description><![CDATA[<p>Надоело плодить JSON/ARB файлы при локализации Flutter-приложения? Автор делился личным опытом и показал, как элегантно настроить локализацию через Enum без внешних зависимостей, генераторов кода и боли в рантайме.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/lokalizaciya-cherez-enum-neozhidannyj-dzen-bystree-tolko-telepat">Локализация через Enum, неожиданный Дзен, быстрее только телепатия</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Массивы и строки]]></category>
      <category><![CDATA[Красивый хак]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Мобильная разработка]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Flutter]]></category>
      <category><![CDATA[Dart]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 04 Jun 2026 04:45:17 GMT</pubDate>
      <content:encoded><![CDATA[<p>Решил давеча добавить локализацию в свое приложение на Flutter. Задачка-то простая: пара кнопок, пару десятков переменных. Казалось бы, делов на пять минут. Но Flutter «из коробки» сразу попытался всучить мне какую-то дичь в виде ARB и JSON файлов. Хмм, из прошлого с такими реализациями лишь печаль, так что…</p><h2>Попытка №1. Путь в лоб: Классы и интерфейсы</h2><p>Самый очевидный способ - создать родительский класс с переменными, а языки сделать его наследниками. Но это просто… фиаско. Даже если не писать from/toJson, процесс выглядит так:</p><ol><li>Объявил переменную в родителе.</li><li>Прописал её в конструкторе.</li><li>Повторил то же самое для всех дочерних классов (всех языков).</li></ol><p>Если бы я работал на аутсорсе в Индии и мне платили за количество строк кода - это был бы идеальный вариант. Но я хотел, чтобы одной строки при объявлении было достаточно.</p><h2>Попытка №2. Стандарт (ARB/JSON)</h2><p>Я поплевался, но решил попробовать - «стандарт» всё-таки. Мало ли, может чего поменялось за годы. Вроде всё завелось, но сам процесс… это боль. Бегать по разным файлам, чтобы добавить одну строчку - так себе удовольствие.</p><p>Почему я от него окончательно отказался? Когда данных становится реально много (десятки языков, тысячи строк), ты попадаешь в ловушку: тебе нужно эту махину либо целиком держать в памяти, либо постоянно подгружать и парсить. Ради смены одного слова на кнопке заставлять девайс ворочать тяжелые JSON-ы в рантайме - так себе затея для производительности.</p><h2>Попытка №3. Таблицы и костыли</h2><p>Подумал: «Окей, почему бы не подтянуть старый добрый CSV или вообще закинуть всё в табличку?». И тут официальный пакет локализации сказал: «Извини, мужик, тут наши полномочия всё».</p><p>Ну, я тоже не пальцем деланный. Решил припахать нейросеть, чтобы она написала мне собственный генератор. Флоу получился такой:</p><ol><li>Добавляю строку в таблицу.</li><li>Запускаю генератор.</li><li>Он лепит «родительский» файл.</li><li>После Freezed генерит toJson, fromJson…</li></ol><p>Короче, весело не было. Мало того, я понимал: если языков станет много, мне придется добавлять их все разом и единовременно, иначе в рантайме всё начнет плеваться ошибками. Плюс та же проблема с памятью: таблица - это структура, которую надо парсить и хранить.</p><h2>Красный флаг для программиста</h2><p>Но главная проблема даже не в этом. Необходимость запускать генератор после добавления каждой переменной - это для любого программиста красный флаг.</p><p>Что происходит на практике? Когда ты пишешь код и тебе нужно добавить одну несчастную строку, тебе лень (читать: нехочется выходить из потока творения) запускать весь этот цикл с генерацией. Ты просто её хардкодишь в надежде «потом скопом всё добавлю одним махом». А «потом» наступает тогда, когда уже весь проект завален хардкодом, и вычищать его - то еще удовольствие. Даже нейросетки с такими запросами помогают не с первого раза, и с сомнительной эффективностью.</p><p>Нутром чуял - флоу неправильный. В итоге я пришел к тому, что называю идеальной локализацией.</p><h2>Эволюция лени: почему Enum победил интерфейсы</h2><p>Я начал мучить нейросеть разными вариантами реализации. Для меня в первую очередь был важен флоу работы: мне было тупо лень писать больше одной строки кода, чтобы добавить переменную.</p><p>Моя философия проста: строку захардкодить - моментально. Добавление даже одной строки в другом файле требует доп. действий. НО, если действий минимум, то кодер поймет, что выигрыш во времени сейчас мизерный против больших потерь в будущем, и исправно добавит строку в правильное место. Этого не произойдет, если для добавления строки нужно «отчитаться» в десяти местах.</p><h2>Попытка №4. Рекорды (Records)</h2><p>Присматривался к рекордам. С ними удобно: не нужно писать конструкторы. Но есть подвох: как только ты добавил переменную в один язык, компилятор тут же сходит с ума и требует добавить её во все остальные прямо сейчас. Никакой гибкости и возможности оставить «на потом».</p><h2>Идеальный костыль: Enum</h2><p>В итоге я пришел к самому, казалось бы, «неправильному» способу, который оказался идеальным. Enum. Само название намекает на перечисления и цифры, но оказалось, что хранить в нем буквы и целые фразы - это лучший путь для локализации.</p><p>Знаете, мне моё решение так понравилось, что я пошел к нейросетям и проверил его со всех сторон. Все модели  остались в полном восторге. Под это дело я даже подготовил монументальную «нейро-статью» на полтора часа внимательного чтения, со всеми графиками, бенчмарками и анализом производительности.</p><p>Но потом я заглянул в правила Хабра, прислушался к голосу разума и понял: никто не хочет читать полтора часа сухой статистики. Лучше я просто расскажу вам свою историю «от первого лица», как я докатился до такой жизни. Ну, а если вы совсем уж фанаты цифр - просто скормите этот текст любой нейронке, она вам перескажет всё в лучших академических тонах с графиками на любой вкус.</p><p>А здесь мы будем говорить по делу.</p><p>Ниже я выкатываю сам код. Код тут не для зубрежки, а лишь чтобы указать направление / идею. Самая большая прелесть этой системы в том, что она оставляет гигантское пространство для любого типа реализации. Это архитектурный каркас, который чертовски сложно сломать. Главное — уловить принцип.</p><h2>Реализация</h2><p>Принцип разделения:</p><ul><li>enum Strings → типизированный контракт (что существует).</li><li>translator → источник данных (откуда берётся текст).</li></ul><p>Структура файлов - минимальная. Никаких внешних зависимостей:</p><h2>Ядро - strings.dart</h2><p>Весь контракт локализации в одном enum. Два режима - хардкод switch и серверный кеш - за одним и тем же</p><p>. Даже сообщения об ошибках локализации — сами локализованы:</p><h2>Список языков - languages_enum.dart</h2><p>Каждый язык - самодостаточная единица: знает свой код, название, направление текста и как себя загрузить:</p><p>Хотите грузить с сервера? Одна строка + loader. И</p><p>- тоже одна строка, потому что</p><p>уже является registry:</p><h2>Переводчик - i18n/russian.dart</h2><p>Как это выглядит в жизни (и почему я перестал хардкодить) Я намеренно не привожу здесь код оберток виджетов или конкретных стейт-менеджеров. Всё это - чистая «вкусовщина». Для работы системы нужен лишь элементарный вещатель событий (Notifier), повешенный на метод смены языка.</p><p>Но главное - это мой ежедневный флоу. Сейчас, чтобы добавить строку в UI, я просто вызываю нужный мне ключ: Strings.someKey(). Без контекста, везде.</p><p>А если ключа еще нет? Я тупо иду в Strings и добавляю одну строчку в Enum. Всё.</p><p>Благодаря дефолтному конструктору, приложению абсолютно плевать, что у меня там еще 100 языков не переведены. Оно компилируется и работает здесь и сейчас. А дальше в дело вступают гит-хуки: при комите нейросетка сама подхватывает изменения и заполняет недостающие поля в переводчиках.</p><p>Знаете, какое самое странное чувство? Мне сейчас реально проще и быстрее завести переменную в локализации, чем хардкодить строку в коде. Кажется, это и есть признак здоровой архитектуры - когда делать «правильно» становится физически удобнее, чем делать «быстро» и криво.</p><p>Собственно если в кратце это все о чем я хотел рассказать. Если тема зайдет или кто-то сам не сможет допереть, как прикрутить это к своей архитектуре - пишите в комментариях, разберемся.</p><p>Надеюсь, мой опыт сэкономит вам пару литров нервных клеток. Всех благ и чистого кода без «магических строк»!</p>]]></content:encoded>
    </item>
    <item>
      <title>Паттерн Transactional Outbox с Kafka: как не потерять события при синхронизации баз данных</title>
      <link>https://tproger.ru/articles/pattern-transactional-outbox-s-kafka-kak-ne-poteryat-sobytiya-pr</link>
      <comments>https://tproger.ru/articles/pattern-transactional-outbox-s-kafka-kak-ne-poteryat-sobytiya-pr?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Торопов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/pattern-transactional-outbox-s-kafka-kak-ne-poteryat-sobytiya-pr</guid>
      <description><![CDATA[<p>Описание паттерна Transactional Outbox</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/pattern-transactional-outbox-s-kafka-kak-ne-poteryat-sobytiya-pr">Паттерн Transactional Outbox с Kafka: как не потерять события при синхронизации баз данных</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Паттерны проектирования]]></category>
      <category><![CDATA[PostgreSQL]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 20 May 2026 04:25:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><b>Боль: данные разошлись, и вы не знаете когда</b></p><p>В нашей системе две базы данных:</p><p>- <b>Остатки по счетам</b> - текущий остаток по каждому счёту</p><p>- <b>Остатки по клиентам</b> - агрегированный баланс клиента по всем его счетам.</p><p>При каждом изменении остатка по счёту нужно обновить <b>Остатки по счетам</b> и уведомить <b>Остатки по клиентам</b> через Kafka. Логика простая. Но в какой-то момент клиент звонит в поддержку: его баланс в приложении не совпадает с реальным. Вы смотрите в обе базы — данные разошлись. Когда именно это произошло — непонятно.</p><p>Причина почти всегда одна и та же:</p><p>Транзакция закоммичена, событие не ушло. Базы разошлись. Никто не узнал.</p><p><b>Почему очевидные решения не работают</b></p><p>Первая реакция разработчика — обернуть отправку в try-catch и повторить при ошибке:</p><p>Не работает: транзакция уже закоммичена до отправки. При сбое Kafka данные обновлены, событие потеряно. Retry помогает только если Kafka временно недоступна — но не при падении самого сервиса между коммитом и отправкой.</p><p>Вторая идея — отправить событие до коммита:</p><p>Тоже не работает: если коммит упадёт, Kafka уже получила событие об изменении, которого нет в базе. Данные снова разошлись, но в другую сторону.</p><p>Третья идея — двухфазный коммит (2PC). Это протокол, который координирует атомарный коммит сразу в нескольких системах. Звучит как решение, но на практике Kafka его не поддерживает в классическом смысле, а реализации 2PC с брокерами сообщений крайне сложны в эксплуатации и плохо переносят сбои координатора.</p><p>Все три пути упираются в одну проблему: **невозможно атомарно закоммитить транзакцию в базе и отправить сообщение в Kafka** — это две разные системы без общего менеджера транзакций.</p><p><b>Принцип решения</b></p><p>Раз нельзя сделать две операции атомарными, нужно свести их к одной. Именно это делает паттерн **Transactional Outbox**.</p><p>Вместо того чтобы отправлять событие в Kafka напрямую, мы записываем его в таблицу `outbox` — в той же базе, в той же транзакции, что и изменение остатка. Одна транзакция, одна база, полная атомарность за счёт ACID.</p><p>Доставкой события из `outbox` в Kafka занимается отдельный процесс — уже без транзакционных рисков, с возможностью повторных попыток.</p><p>Это и есть весь паттерн. Дальше — вопрос реализации.</p><p><b>Два способа реализации</b></p><p>Есть два принципиально разных подхода к тому, как читать `outbox` и доставлять события в Kafka. Выбор между ними определяет операционную сложность и задержку доставки.</p><p><b>Способ 1: Polling Relay</b></p><p>Фоновый воркер периодически опрашивает 'outbox' и отправляет неотправленные события в Kafka.</p><figure><img src="https://media.tproger.ru/user-uploads/115582/2026-05-19/dfe8e7cf-f864-432d-a00b-66775ce77f8b.webp" alt="" /></figure><p><b>Структура таблицы outbox:</b></p><p><b>Бизнес-транзакция:</b></p><p><b>Relay-процесс:</b></p><p>При нескольких экземплярах ретранслятора важно, чтобы одно событие забирал только один из них. Используем `FOR UPDATE SKIP LOCKED`:</p><p><b>Когда выбирать:</b> задержка доставки в сотни миллисекунд допустима, хочется минимум зависимостей, команда не готова к операционной сложности CDC.</p><p><b>Способ 2: CDC через Debezium</b></p><p><b>CDC (Change Data Capture)</b> — подход, при котором события читаются не опросом таблицы, а напрямую из журнала транзакций базы данных (WAL в PostgreSQL). [Debezium](https://debezium.io/) подключается к PostgreSQL как репликационный слот и стримит каждое изменение в `outbox` в Kafka в реальном времени.</p><p>Relay-процесс при этом не нужен вообще.</p><figure><img src="https://media.tproger.ru/user-uploads/115582/2026-05-19/db09dce3-7ec8-4b27-b2b0-655904fd43cb.webp" alt="" /></figure><p>Бизнес-транзакция остаётся той же — пишем в `accounts` и `outbox` атомарно. Debezium сам следит за WAL и публикует новые записи в Kafka с минимальной задержкой.</p><p><b>Когда выбирать:</b> нужна задержка доставки в миллисекунды, команда готова к Debezium + Kafka Connect в инфраструктуре.</p><p>Что выбрать для синхронизации остатков</p><figure><img src="https://media.tproger.ru/user-uploads/138533/2026-05-15/4e568b33-b8d1-43dc-b9a0-1324859a2112.webp" alt="" /></figure><p>Для большинства задач с остатками по счетам<b> polling relay достаточен</b>. CDC имеет смысл, если бизнес требует обновления клиентского баланса быстрее чем за секунду.</p><p><b>Получатель: защита от дублей</b></p><p>Оба способа доставляют события <b>как минимум один раз</b> — при повторных попытках одно событие может прийти дважды. На стороне <b>Остатков по клиентам</b> нужна защита.</p><p>Самый надёжный способ — inbox-таблица с уникальным constraint:</p><p>&gt;<b>Почему не `existsById` перед вставкой?</b> При параллельной обработке два консюмера могут одновременно получить `false` и оба начать обработку. Уникальный constraint на уровне БД закрывает эту гонку.</p><p><b>Что сломается при небрежной реализации</b></p><p><b>Relay внутри API-сервиса.</b> Если ретранслятор живёт в том же процессе, что и API, горизонтальное масштабирование до 10–30 реплик создаёт столько же потоков, опрашивающих `outbox`. База тратит CPU не на запросы, а на управление блокировками. Relay — отдельный деплоймент, который масштабируется по объёму событий, а не по HTTP-трафику.</p><p><b>Таблица outbox незаметно растёт.</b> Без очистки запросы замедляются, индексы раздуваются. Настройте автоматическую очистку:</p><p><b>Отсутствие мониторинга outbox.</b> Outbox — скрытая очередь внутри базы. Если relay начнёт отставать, вы узнаете об этом от клиентов, а не от алертов. Следите за количеством и возрастом необработанных событий — это главные сигналы проблемы.</p><p><b>Итог</b></p><p>Проблема потери событий при синхронизации баз — не баг конкретной реализации. Это фундаментальное ограничение: нельзя атомарно закоммитить транзакцию в базе и отправить сообщение в Kafka.</p><p>Transactional Outbox обходит это ограничение, сводя две операции к одной: событие пишется в `outbox` в той же транзакции, что и основные данные. Дальше — дело техники: polling relay, если нужна простота, CDC, если нужна скорость.</p><p>Остатки по счетам и клиентам будут согласованы — даже если между сервисами что-то пойдёт не так.</p>]]></content:encoded>
    </item>
    <item>
      <title>JEP 533: в Java 27 Structured Concurrency меняет обработку исключений</title>
      <link>https://tproger.ru/news/jep-533-v-java-27-structured-concurrency-menyaet-obrabotku-isklyu</link>
      <comments>https://tproger.ru/news/jep-533-v-java-27-structured-concurrency-menyaet-obrabotku-isklyu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/jep-533-v-java-27-structured-concurrency-menyaet-obrabotku-isklyu</guid>
      <description><![CDATA[<p>JEP 533 в JDK 27: FailedException заменён на ExecutionException, Joiner получил третий тип-параметр, новый open()-оверлоад упрощает конфигурацию. Проверьте код.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/jep-533-v-java-27-structured-concurrency-menyaet-obrabotku-isklyu">JEP 533: в Java 27 Structured Concurrency меняет обработку исключений</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Многопоточность]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 14 May 2026 12:45:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>После семи preview Structured Concurrency в JDK 27 впервые избавляется от собственных preview-типов: FailedException заменён на стандартный ExecutionException. JEP 533 интегрирован в JDK 27 и приносит ещё два изменения: третий тип-параметр в Joiner и новый оверлоад open() — без явного Joiner при стандартной политике.</p><p>Structured Concurrency появилась в JDK 19 как инкубатор и прошла два инкубаторных раунда и несколько preview, постепенно сближая модель многопоточности с принципами структурного программирования: подзадачи живут строго внутри своей области видимости, отмена распространяется надёжно, а иерархии потоков отображаются в инструментах наблюдаемости.</p><ul><li><b>FailedException заменён на ExecutionException</b>: стандартные joiners теперь бросают ExecutionException вместо preview-специфичного FailedException — тот же тип, что и Future.get().</li><li><b>Третий тип-параметр R_X</b>: Joiner&lt;T, R, R_X&gt; выносит тип исключения join() в сигнатуру — контракт становится частью типа.</li><li><b>Новый open-оверлоад</b>: StructuredTaskScope.open(UnaryOperator&lt;Configuration&gt;) позволяет задать таймаут и имя без явной передачи Joiner.</li><li>Ранние access-сборки JDK 27 доступны с флагом --enable-preview.</li><li>Форма API, заложенная в preview 5, сохраняется — дизайн сходится к финализации.</li></ul><h2>FailedException уходит — приходит ExecutionException</h2><p>Главное изменение preview 7: joiners Joiner.allSuccessfulOrThrow(), anySuccessfulOrThrow() и awaitAllSuccessfulOrThrow() теперь бросают java.util.concurrent.ExecutionException вместо preview-специфичного FailedException. Причина исключения доступна через getCause() — так же, как в Future.get() со времён Java 5.</p><p>Смена типа сокращает разрыв между классическим и структурированным кодом. Привычный паттерн catch-switch переносится напрямую:</p><p>Команды, которые использовали FailedException в preview 5–6, должны заменить этот тип на ExecutionException при переходе на JDK 27.</p><h2>Третий тип-параметр: исключение становится частью типа</h2><p>StructuredTaskScope и интерфейс Joiner получают третий тип-параметр R_X, описывающий тип исключения, которое может бросить join(). Старая сигнатура Joiner&lt;T, R&gt; становится Joiner&lt;T, R, R_X&gt;.</p><p>Для прикладного кода, который использует стандартные joiners через open(), компилятор выводит все три параметра автоматически — исходный код выглядит так же, как раньше. Разница принципиальна для авторов кастомных joiners: предложение throws теперь становится частью типа, а не деталью реализации. Вызывающий код получает точный checked-exception контракт на join().</p><h2>Новый open-оверлоад: конфигурация без лишнего Joiner</h2><p>До preview 7 установить таймаут или имя области при политике по умолчанию (ждать всех, завершить со сбоем при первом падении подзадачи) требовало передачи явного Joiner рядом с оператором конфигурации. Теперь появился перегруженный StructuredTaskScope.open(UnaryOperator&lt;Configuration&gt;), который принимает только оператор конфигурации:</p><p>Оверлоад принимает UnaryOperator&lt;Configuration&gt; — то же более строгое типирование, которое было введено в preview 6. Политика join по умолчанию (ждать успеха всех или провала хотя бы одной подзадачи) сохраняется.</p><h2>Что осталось без изменений</h2><p>Структурные гарантии API остаются прежними: подзадачи наследуют привязки ScopedValue (JEP 506), JSON thread dump продолжает отображать иерархии областей для инструментов профилирования, StructureViolationException по-прежнему срабатывает при использовании области вне try-with-resources или форке из чужого потока.</p><p>Одно изменение JEP 533, выходящее за рамки трёх основных: метод onTimeout() интерфейса Joiner удалён и заменён на timeout(). Новый метод либо возвращает результат, либо при тайм-ауте бросает исключение с CancelledByTimeoutException как причиной. Авторам кастомных Joiner-реализаций потребуется переименовать метод и скорректировать логику обработки тайм-аута.</p><p>Preview 7 не является редизайном. Форма API, заложенная в preview 5, сохраняется. Изменения сосредоточены на эргономике и типизации, а не на структуре. Сужающийся охват каждого preview — разумный индикатор того, что дизайн сходится. JEP 533 не указывает сроков финализации, но Structured Concurrency прошла два инкубаторных раунда и шесть preview — это значительный путь.</p><h2>Как попробовать</h2><p>Предложение доступно в ранних access-сборках JDK 27 с флагом --enable-preview. Обратная связь принимается через mailing-листы OpenJDK и продолжает влиять на API.</p><ul><li>Скачать early-access сборку JDK 27 с <b>jdk.java.net/27</b></li><li>Добавить --enable-preview при компиляции и запуске</li><li>Заменить FailedException на ExecutionException в catch-блоках</li><li>Обновить сигнатуры кастомных Joiner-реализаций до трёх тип-параметров</li></ul><h2>Выводы</h2><blockquote>Preview 7 не меняет форму API — он делает её честной. Тип исключения теперь в сигнатуре, а не в документации.</blockquote><p>Три изменения в JEP 533 — замена FailedException, третий тип-параметр и новый оверлоад open() — продолжают линию на сближение Structured Concurrency с идиомами стандартной библиотеки. Дизайн, по всем признакам, сходится: если вы следите за эволюцией Java-конкурентности, это хороший момент попробовать JDK 27 early-access и отправить обратную связь в OpenJDK.</p><p>Подробности — в тексте <a href="https://openjdk.org/jeps/533">JEP 533</a> и на страницах <a href="https://www.infoq.com/news/2026/05/jep-533-jdk-27/">InfoQ</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Kotlin 2.4.0-Beta2 и Golden Kodee: дайджест Kotlin за апрель</title>
      <link>https://tproger.ru/news/kotlin-2-4-0-beta2-i-finalisty-golden-kodee-glavnoe-v-kotlin-z</link>
      <comments>https://tproger.ru/news/kotlin-2-4-0-beta2-i-finalisty-golden-kodee-glavnoe-v-kotlin-z?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Евгений Стребков]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/kotlin-2-4-0-beta2-i-finalisty-golden-kodee-glavnoe-v-kotlin-z</guid>
      <description><![CDATA[<p>Главные события Kotlin за апрель: вышел 2.4.0-Beta2 и патч 2.3.21, объявлены финалисты Golden Kodee, готовится KotlinConf 2026. Что обновить уже сейчас.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/kotlin-2-4-0-beta2-i-finalisty-golden-kodee-glavnoe-v-kotlin-z">Kotlin 2.4.0-Beta2 и Golden Kodee: дайджест Kotlin за апрель</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[JetBrains]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 05 May 2026 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>JetBrains <a href="https://blog.jetbrains.com/kotlin/2026/05/kodees-kotlin-roundup-golden-kodee-finalists-kotlin-2-4-0-beta2-and-new-learning-resources/">опубликовала апрельский обзор</a> ключевых событий вокруг Kotlin: вышли <b>Kotlin 2.4.0-Beta2</b> (первый публичный взгляд на следующую мажорную версию языка), <b>Kotlin 2.3.21</b> с фиксами производительности, <b>IntelliJ IDEA 2026.1</b> и <b>Amper 0.10.0</b>. Параллельно объявлены финалисты <b>Golden Kodee</b> — главной комьюнити-награды Kotlin, — и стартовала подготовка к <b>KotlinConf 2026</b>, которая пройдёт 20–22 мая в Мюнхене. До feature-freeze 2.4 остаётся пара месяцев — самое время прогнать бету на своём проекте, пока баги ещё ловят.</p><p>Собрали в одном материале то, что разработчику на Kotlin стоит держать в голове в ближайшие недели — релизы, инструменты, события и ресурсы для прокачки.</p><p><b>Kotlin 2.4.0-Beta2.</b> Ранний обзор будущей мажорной версии: изменения в языке, stdlib, JVM-бэкенде, Kotlin/Native и компиляторе.</p><p><b>Kotlin 2.3.21.</b> Параллельный патч в стабильную ветку 2.3 — оптимизация производительности и баг-фиксы.</p><p><b>KotlinConf 2026.</b> 20–22 мая в Мюнхене, ожидается 2000+ разработчиков. Онлайн-трансляция — на YouTube-канале Kotlin для тех, кто не сможет приехать.</p><p><b>Golden Kodee.</b> Финалисты главной комьюнити-награды объявлены — top 3 в каждой категории получат приглашения в Мюнхен, победителей выберут на конференции.</p><p><b>Tooling.</b> IntelliJ IDEA 2026.1, Amper 0.10.0 (автопровижн JDK, Maven-to-Amper конвертер), Ktor 3.4.3, Dokka 2.2.0, Exposed 1.0+ с поддержкой PostgreSQL array.</p><h2>Kotlin 2.4.0-Beta2 и 2.3.21</h2><p>JetBrains выложила первую <b>Beta2</b> следующей мажорной версии — 2.4.0-Beta2. Это «предварительный взгляд» на то, что попадёт в стабильный релиз 2.4: изменения распределены сразу по нескольким слоям — самому языку, стандартной библиотеке, JVM-бэкенду, Kotlin/Native и компилятору. Если поддерживаете крупный проект — самое время прогнать его на бете и зарепортить регрессии до до заморозки кода.</p><p>Параллельно вышел 2.3.21 в стабильной ветке: фокус на производительности и багфиксах. Если вы пока не готовы переезжать на 2.4 — это безопасный апдейт минор-версии, без сюрпризов.</p><h2>KotlinConf 2026 и Golden Kodee</h2><p>Главное событие года для Kotlin-сообщества — <b>KotlinConf 2026</b>. Пройдёт <b>20–22 мая в Мюнхене</b>, ожидается более 2000 разработчиков из разных стран. Если поехать не получается, JetBrains обещает livestream на <a href="https://www.youtube.com/@Kotlin">YouTube-канале Kotlin</a> — основные кейноты и анонсы можно будет посмотреть в прямом эфире.</p><p>К конференции приурочена ежегодная награда <b>Golden Kodee</b> для самых заметных людей сообщества — тех, кто организует мероприятия, делится знаниями, помогает новичкам. Финалисты в каждой категории объявлены: топ-3 в каждой категории приглашают в Мюнхен, победителей объявляют на конференции.</p><p>Из спикеров — стоит обратить внимание на keynote второго дня от <b>Лены Райнхард</b>: она будет говорить про карьеру в IT, лидерство, неопределённость на рынке и что значит «продуктивность» в эпоху ИИ.</p><h2>Инструменты: IntelliJ, Amper, Koog, Ktor</h2><p>Главные инструментальные апдейты апреля:</p><ul><li><b>IntelliJ IDEA 2026.1.</b> Общая оптимизация производительности + улучшенная поддержка языков и фреймворков. Это значимый апдейт IDE, на который стоит переехать всем Kotlin-разработчикам.</li><li><b>Amper 0.10.0.</b> Инструмент сборки от JetBrains получил автоматический provisioning JDK (больше не нужно вручную ставить нужную версию), Maven-to-Amper конвертер (полезно для миграции проектов с легаси-кодом), поддержку кастомных Kotlin плагины компилятора и общее улучшение IDE-опыта.</li><li><b>Koog для JVM-экосистемы.</b> Koog — фреймворк JetBrains для построения AI-агентов на JVM. Появился идиоматичный Java API — теперь Java-команды могут строить пайплайны агентов без переписывания на Kotlin. Кроме того, Koog интегрировался со <b>Spring AI</b> — для Kotlin/Spring проектов это знакомый стек для работы с агентами.</li><li><b>Ktor 3.4.3.</b> Очередной патч асинхронного фреймворка для серверов и клиентов на Kotlin.</li><li><b>Dokka 2.2.0.</b> Стандартный документ-генератор для Kotlin-проектов.</li><li><b>Exposed 1.0+.</b> SQL-фреймворк теперь поддерживает array-типы PostgreSQL «из коробки» — раньше для этого нужны были custom-расширения.</li></ul><h2>Бэкенд, мультиплатформа и WebAssembly</h2><p>Несколько практических материалов для тех, кто работает с Kotlin на бэкенде или в мультиплатформенных проектах:</p><ul><li><b>Spring Data JPA с Kotlin.</b> Гайд про entities, repositories, custom queries и DTO — полезно для команд, уже сидящих на Spring и думающих про переход с Java на Kotlin.</li><li><b>Spring guide: Uploading Files на Kotlin и Java.</b> Параллельное сравнение помогает увидеть, как Kotlin вписывается в существующие бэкенд-процессы.</li><li><b>Kotlin + WebAssembly</b> с примером wasi:http (стандарт WebAssembly System Interface для HTTP-серверов) — минимальный HTTP-сервер на Kotlin/Wasm. Не production-ready, но ясно показывает, в каком направлении движется WebAssembly у Kotlin.</li><li><b>KMP-аргументы для бизнеса.</b> Гостевой пост от Touchlab про то, как объяснять руководству ценность Kotlin Multiplatform: ускорение поставки, снижение рисков, долгосрочная продуктовая стратегия. На tproger у нас был <a href="https://tproger.ru/news/creating-an-app-for-kotlin-multiplatform">базовый туториал по созданию первого KMP-приложения</a> для тех, кто хочет потрогать руками.</li></ul><h2>Обучение и развлечение</h2><p>Если хочется прокачать или закрепить Kotlin — два полезных ресурса:</p><ul><li><b>Kotlin Professional Certificate by JetBrains</b> на LinkedIn Learning. Четыре курса, финальный экзамен, сертификат на профиль. Заявленная длительность — менее 12 часов общего материала.</li><li><b>Coroutines Races Guesser Game</b> от kt.academy. Интерактивная игра: предсказываете, как поведут себя корутины в разных ситуациях. Хороший способ проверить интуицию по асинхронной логике, особенно если давно не работали со Structured Concurrency.</li></ul><h2>Выводы</h2><p>Апрель в Kotlin-экосистеме оказался плотным: одновременно вышли беты будущей мажорной версии, патчи стабильной ветки, обновления IDE, инструментов сборки и фреймворков. Параллельно сообщество готовится к KotlinConf и финалу Golden Kodee. Если вы поддерживаете Kotlin-проект — стоит как минимум обновить IntelliJ до 2026.1 и поставить 2.3.21 в стабильный пайплайн.</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>AI-агент для ревью документации в Confluence: инструкция как сделать также</title>
      <link>https://tproger.ru/articles/ai-agent-dlya-revyu-dokumentacii-v-confluence--instrukciya-kak-sde</link>
      <comments>https://tproger.ru/articles/ai-agent-dlya-revyu-dokumentacii-v-confluence--instrukciya-kak-sde?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Дима Дмитриев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/ai-agent-dlya-revyu-dokumentacii-v-confluence--instrukciya-kak-sde</guid>
      <description><![CDATA[<p>Как создать AI-агента для ревью документации в Confluence. Архитектура, LLM-проверки, chunking, интеграция с Jira и автоматизация Docs Review.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/ai-agent-dlya-revyu-dokumentacii-v-confluence--instrukciya-kak-sde">AI-агент для ревью документации в Confluence: инструкция как сделать также</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Системный анализ]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Автоматизирование]]></category>
      <category><![CDATA[Промпты]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 16 Mar 2026 07:20:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Мы разработали и внедрили AI-агента в процесс ревью документации в Confluence. Агент является частью экосистемы агентов Desmond, а под капотом у него Java 21, Spring AI, gpt-oss-120b, Docker + Kubernetes во внутреннем AI-кластере банка, Jira (webhook + REST API + Kafka), LibreChat (MCP). Он автоматически проверяет документацию в Confluence на соответствие стандарту. Агент встроен в Jira: получает webhook при смене статуса задачи, находит нужную документацию, проверяет её и оставляет комментарий с результатами ревью.</p><p>Кому это будет нужно:</p><ul><li>Платформенным аналитикам — меньше рутинного ревью, больше времени на рабочие задачи.</li><li>Продуктовым аналитикам и разработчикам — быстрая обратная связь, понятные и шаблонные требования для проекта.</li></ul><h2>Откуда растёт проблема</h2><p>Прежде чем описывать решение, давайте поймем контекст.</p><p>Перед релизом любой фичи команда готовит поставку: у разработчика — code review, у аналитика — ревью документации. Весь процесс идёт по workflow в Jira, и один из обязательных этапов — Docs review.</p><p>За этот этап отвечают платформенные аналитики: они дежурят по очереди и проверяют поставки. Их задача — убедиться, что документация написана по стандарту и отражает все новые изменения по продуктам. Хранится всё в едином Confluence-пространстве платформы, и порядок там очень нужен: документацию читают не только аналитики разных команд, но и саппорт.</p><p>Звучит адекватно. <b>Но на практике вылезают три проблемы:</b></p><ol><li>Задержки. У платформенного аналитика помимо ревью куча других задач. Когда поставок много — Docs review начинает тормозить весь процесс подготовки к релизу.</li><li>Усталость ревьювера. Большой поток однотипных проверок выматывает даже самого внимательного, поэтому риск нужно было сократить.</li><li>Человеческий фактор. Несмотря на наличие стандарта, разные ревьюверы могут расставлять акценты по-разному. Аналитик продуктовой команды никогда не знает наверняка, на что обратят внимание в этот раз.</li></ol><p>Всё это бьёт по времени поставки и непонятно растягивает подготовку к релизу — особенно когда релизиться нужно быстро.</p><h2>Что пробовали раньше</h2><p>Прежде чем идти в сторону AI, рассмотрели два очевидных варианта.</p><p><b>Вариант 1: убрать ревью совсем.</b></p><p>Радикально, экономит время всех участников, но тогда мы теряем контроль над качеством документации — а это дорого. Документацию читают не только аналитики, но и саппорты. Без проверки начнут теряться важные детали о работе функционала, по сути, возвращаемся к тому хаосу, от которого уже уходили раньше. Не вариант.</p><p><b>Вариант 2: алгоритмическая автоматизация без AI.</b></p><p>Теоретически можно написать набор проверок на if-else. Но у документации нет синтаксиса, как у кода — каждый аналитик пишет немного по-своему. Поддержка такого алгоритма со временем станет дороже, чем просто делать ревью руками.</p><h2>Почему AI-агент</h2><p>После того как стандартные подходы отпали, мы стали думать в сторону LLM. И чем дольше разбирались, тем яснее становилось: LLM под это хорошо ложится.</p><p>Вот конкретные факты, которые мы собрали внутри команды:</p><ul><li>LLM умеет понимать суть написанного, а не только искать точные совпадения, если документация написана по-разному — для нейронки это не проблема.</li><li>Когда требования меняются, в большинстве случаев достаточно поправить промпт. Аналитик справится сам, без участия разработчика.</li><li>У агента одна задача — ревью, он делает её сразу, не надо ждать, пока освободится дежурный аналитик.</li><li>Агент интегрируется в существующий Jira-workflow. Для команд ничего не меняется — агент работает в фоне.</li><li>У агента понятный набор инструкций.</li></ul><h2>Архитектура агента</h2><p>Desmond — экосистема агентов. Desmond Docs Reviewer — task-oriented AI-агент для автоматизации ревью внутренней документации на платформе Альфа-Онлайн.</p><p><b>Стек:</b></p><ul><li>Язык: Java 21 + Spring AI</li><li>Инфраструктура: Docker + Kubernetes во внутреннем AI-кластере банка</li><li>Модель: gpt-oss-120b — внутренний продукт банка AlfaGen, развёрнутый локально</li><li>Интеграции: Jira (webhook + REST API + Kafka), Code Review Agent (A2A через MCP), LLM API</li></ul><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-16/69ad3392-c669-478e-94e0-5db2c3e7f948.webp" alt="" /></figure><p>Точка входа — webhook из Jira. Задача переходит в нужный статус → триггерится webhook → агент получает событие и начинает работу.</p><p>На входе агент имеет три сущности:</p><ul><li>описание изменений (фича)</li><li>ссылку на документацию в Confluence</li><li>ссылку на Pull Request разработчика</li></ul><p>Дальше — четыре шага.</p><h2>Как агент решает задачу пошагово</h2><p>Посмотрим на работу агента со стороны процесса и распишем детально каждый.</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-16/5ad8fa87-7a47-441e-adcb-da0ac551e1b0.webp" alt="" /></figure><h2>Шаг 1. Нужна ли вообще проверка?</h2><p>Первое, что делает агент — определяет, техническая это доработка или бизнесовая. Если изменения затрагивают только код и не меняют бизнес-логику — документацию обновлять не нужно, а значит и проверять нечего.</p><p>Агент анализирует описание задачи и diff PR. Смотрит на примеры из промпта и выдаёт решение: техническая доработка или нет, плюс короткое обоснование — не больше 30 слов.</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-16/8b795c5e-9030-476b-9310-09a5c0f126c2.webp" alt="" /></figure><p>Типовые технические доработки, которые не требуют проверки: обновление библиотек, рефакторинг тестов, исправление линтера, дизайнерские правки без влияния на UX. Есть и исключения — например, изменение deeplink-параметров или перемещение приложения в новый репозиторий. Всё это прописано в промпте явно.</p><p>На реальных задачах получили 89,7% корректных ответов (27 из 30). Для старта приемлемо, но будем улучшать.</p><p>Если доработка техническая — агент пишет комментарий в задачу и переводит её в следующий статус. Дальше не идёт.</p><p>Общий сценарий в коде выглядит так:</p><h2>Шаг 2. Есть ли в документации описание фичи?</h2><p>Если доработка бизнесовая — агент ищет в документации фрагменты, которые описывают конкретную фичу. Задача на этом шаге простая: найдено ли описание, и если да — в каких разделах и что именно написано.</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/09aa13e4-2fba-45a8-858a-f8db9ba1b6e9.webp" alt="" /></figure><p>Отдельно проверяется раздел «7. История изменений» — изменение должно быть там зафиксировано.</p><p><b>Проблема с токенами.</b> Документация бывает большой — и она не влезает в контекст целиком. Решение: разбить на чанки и анализировать по частям.</p><p>Стратегия нарезки простая — равномерно по количеству символов, семантическое деление по разделам здесь не критично: мы ищем одни и те же фрагменты вне зависимости от их положения в структуре.</p><p>Чтобы не терять контекст на границах, используем перекрытие (overlap): к каждому чанку добавляем хвост предыдущего и заголовок его раздела. Размер чанка рассчитывается по формуле с коэффициентом, подобранным эмпирически — с запасом на колебания длины токенов.</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/c9f630a0-db7c-4a23-a5f7-406c2c43eba8.webp" alt="" /></figure><p>Смысл её в том, чтобы заранее рассчитать максимально допустимое количество символов на чанк (C_chunk), включая резерв под перекрытие (C_dup) и заголовок. Коэффициент r был подобран эмпирически — с запасом, чтобы учесть возможные колебания в длине токенов.</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/67e6d7bc-70cf-4b0e-8e43-2da4b42229ab.webp" alt="" /></figure><p>После того как все чанки обработаны, агент собирает сводное саммари: в каких разделах нашлось описание фичи, указано ли изменение в истории. Если ничего не найдено — просит проверить формулировку описания в задаче.</p><p>Пример ответа, когда описание фичи найдено:</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/b2f28fa7-e618-455e-8792-0f0be1de4214.webp" alt="" /></figure><p>Пример ответа, когда описание фичи не найдено:</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/b7cdc36b-3043-4fbc-bb8e-e8becc59bc6c.webp" alt="" /></figure><h2>Шаг 3. Соответствует ли документация стандарту?</h2><p>Это самая сложная часть — со звёздочкой. Нужно пройтись по каждому разделу документа и сверить его с требованиями стандарта. Документация структурирована: шапка, основная информация, предусловия, постусловия, сценарии использования, алгоритм, подробное описание, история изменений.</p><p>Возьмем кусочек стандарта, описывающий шапку страницы:</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/1c9adb3a-f0b1-445f-b711-150c56d7fc96.webp" alt="" /></figure><h2>Стандарт для LLM — это не то же самое, что стандарт для людей</h2><p>Когда мы первый раз запустили проверку, скормили агенту существующий стандарт как есть. Результат нам не понравился: LLM интерпретировала одни и те же требования по-разному, часть пунктов игнорировала, часть выполняла непредсказуемо.</p><p>Причина в том, что стандарт писался для аналитиков, которые понимают контекст и в нём много неявных допущений — «вставьте ссылку на команду», «укажите репозиторий» — и ни слова о том, как именно это должно выглядеть.</p><p>Вот типичные вопросы, на которые у стандарта не было ответа:</p><ul><li>Ссылка на команду — это Confluence, Notion или Jira?</li><li>Jira-ссылка — это макрос или обычный URL?</li><li>Как проверить корректность ссылки на репозиторий?</li><li>Всегда ли обязательна эта таблица, или бывают исключения?</li></ul><p>Переписали стандарт в LLM-читаемый формат, руководствуясь простыми принципами:</p><ul><li>Каждое требование сформулировано явно и однозначно.</li><li>Для каждого поля приведены примеры правильного и неправильного заполнения.</li><li>Никаких «подразумевается» и «как правило».</li></ul><p>Вот как выглядит фрагмент переписанного стандарта для шапки документа:</p><p>Кусочек 2</p><h2>Кросс-раздельные проверки</h2><p>Часть требований касается не одного раздела, а согласованности между несколькими. Например: все сервисы, упомянутые в колонке Git Middle шапки, должны иметь ссылку на документацию в разделе «Основная информация».</p><p>Для таких случаев мы выделили отдельный тип — кросс-проверки. Они оформлены как отдельные правила, где явно указано, какие разделы участвуют и что между ними должно быть согласовано. В промпт к агенту передаются сразу несколько чанков документации — те разделы, которые участвуют в проверке.</p><p>Один из примеров кросс-проверок:</p><h3>Chunking strategy</h3><p>В этой задаче нам важно обеспечить максимально точную проверку по всем требованиям, поэтому мы будем здесь использовать стратегию логического разделения по разделам. Выглядит это как-то так:</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-16/1cdd8abb-9714-4d64-a81d-f154a649824b.webp" alt="" /></figure><p>Дано:</p><ul><li>LLM-читаемый формат, разбитый по разделам</li><li>Документация, также структурированная по разделам</li></ul><p>Решение:</p><p>1. <b>Разделяем на чанки документацию.</b> 1 чанк = 1 раздел.</p><p>2. <b>Разделяем на чанки стандарт.</b> 1 чанк = 1 требование.</p><p>3. <b>Сопоставляем чанки</b> стандарта и документации между собой:</p><p><b>Проверка оформления:</b></p><p>1 чанк (раздел) документации ~ 1 чанку стандарта (требование к разделу).</p><p><b>Кросс-проверки: </b></p><p>1 чанк кросс-проверки (отдельный раздел с кросс-проверками) ~ n чанкам (разделам) документации.</p><p>4. <b>Отправляем в LLM запросы</b> на проверку по каждому соответствию.</p><p>5. <b>Собираем в единый отчет.</b></p><p>Примеры:</p><p>Проверка оформления</p><ul><li>1 чанк стандарта</li></ul><ul><li>1 чанк документации (представлено графически для наглядности. В реальности данные передаются в LLM в HTML-формате)</li></ul><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/a5476f12-edf3-4a17-9fc5-f93592557108.webp" alt="" /></figure><p>Кросс-проверка</p><ul><li>1 чанк стандарта:</li></ul><ul><li>2 чанка документации:</li></ul><p>Чанк 1</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/e7a4592b-5ff9-4c14-8c5d-1f236c3a8438.webp" alt="" /></figure><p>Чанк 2</p><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/1fea1c37-64c1-4d73-bb4f-40e0a55e0aa2.webp" alt="" /></figure><p>Итоговый промпт:</p><p>Таким образом, мы проверяем каждый раздел и каждую кросс-проверку отдельно. После прохождения всех проверок собираем итоговое саммари, чтобы зафиксировать результат анализа по всему документу.</p><p>Как выглядит код:</p><p>Мы видим, что при использовании чанков LLM перестала пропускать требования, проверки стали стабильнее, ответы — содержательнее.</p><p>Пример ответа LLM до чанкования в свободном формате:</p><p>Пример ответа LLM после чанкования в JSON-формате. Приведу пример анализа только одного чанка (раздел Алгоритм), т.к. в сумме по чанкам получается тот самый объёмный текст длиной в 200-250 символов.</p><p>А что если раздел слишком большой?</p><p>В таком случае мы используем chunking strategy из <b>шага 2</b> и агрегируем результаты с помощью немного сумасшедшего 💊, но работающего промпта.</p><p>Агент отправляет запрос на проверку по каждому соответствию, затем собирает всё в нормальный отчёт. Изначально отчёт выходил на 200–250 строк — неудобно читать, мы добавили отдельный шаг финального саммари — сократили до 50 строк без потери содержания.</p><h2>Технические грабли</h2><h3>Нестабильность ответов LLM</h3><p>Одна из первых проблем — LLM отвечала в произвольном формате. Иногда JSON, иногда текст, иногда что-то среднее. Решение: Structured Output в Spring AI. Ответ всегда приходит в заданной структуре — никакой самодеятельности.</p><h2>Лимит токенов</h2><p>Встречается на обоих шагах, но по-разному. На шаге поиска фичи — документация слишком большая целиком. На шаге проверки стандарту — в контекст не влезают и документ, и стандарт одновременно. В обоих случаях решение — chunking с правильно рассчитанным размером и overlap.</p><h2>Скрытые элементы Confluence</h2><p>Confluence отдаёт HTML, и часть контента скрыта в элементах, которые не видны при обычном просмотре страницы. Агент работает напрямую с HTML, <b>в котором остаются только нужные для обработки теги </b>— это позволяет не терять данные, которые визуально не отображаются</p><h2>Долгое время обработки</h2><p>Первые версии работали медленно: несколько запросов к LLM шли последовательно. Переключились на Java Virtual Threads — параллельная обработка чанков сократила медианное время ревью с 1:20 до 0:26.</p><p><b>Как это выглядит в коде: </b></p><h2>Что конкретно упростилось</h2><ul><li>Аналитики продуктовых команд стали прогонять документацию через агента ещё до этапа ревью — как самопроверку.</li><li>При повторном ревью после правок не надо ждать человека — достаточно перезапустить агента.</li><li>Проверка корректности ссылок и форматов полностью снята с плеч аналитиков.</li></ul><h2>Ограничения</h2><ol><li>Макеты — проверяется только их наличие, содержимое агент не анализирует.</li><li>Нестандартная структура — если документация сильно отклоняется от шаблона, автоматическая проверка даёт менее надёжный результат.</li></ol><h2>Что дальше</h2><p>Идеи в работе и на горизонте:</p><ul><li>Автоматический аппрув документации, если все проверки прошли успешно.</li><li>Подключение проверок документации по микросервисам, не только фронтенд.</li><li>Проверка полноты документации через код — что позволит закрыть ревью почти полностью, за исключением нестандартных кейсов.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/99633/2026-03-13/56986e79-bf1b-4287-a589-f2afb5c60c44.webp" alt="" /></figure>]]></content:encoded>
    </item>
    <item>
      <title>Java для детей: надежный фундамент для будущего разработчика</title>
      <link>https://tproger.ru/articles/java-dlya-detej--nadezhnyj-fundament-dlya-budushhego-razrabotchika-2</link>
      <comments>https://tproger.ru/articles/java-dlya-detej--nadezhnyj-fundament-dlya-budushhego-razrabotchika-2?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Блог Школа программирования Пиксель]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/java-dlya-detej--nadezhnyj-fundament-dlya-budushhego-razrabotchika-2</guid>
      <description><![CDATA[<p>Рассказываем, почему детям полезно изучать программирование на Java, как этот язык применяется в реальном мире, с каких проектов начать и как эффективно построить обучение.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/java-dlya-detej--nadezhnyj-fundament-dlya-budushhego-razrabotchika-2">Java для детей: надежный фундамент для будущего разработчика</a>»</p>]]></description>
      <category><![CDATA[Партнёрский материал]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Для начинающих]]></category>
      <category><![CDATA[Обучение программированию]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 04 Feb 2026 06:15:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>Для детей Java — это не просто знакомство с кодом, а серьезный шаг в мир «взрослого» программирования. Этот универсальный и востребованный язык учит структурному мышлению, дисциплине и принципам создания настоящих приложений — от мобильных игр до сложных систем. В этой статье мы подробно разберем, почему Java отлично подходит детям, как он применяется в реальном мире, с каких проектов начать и как эффективно построить обучение.</p><h2>Почему Java знают во всем мире</h2><p>Java — один из самых известных и распространенных языков программирования. Он был создан в середине 1990-х годов компанией Sun Microsystems с четкой целью: получить универсальный и надежный инструмент для разработки программного обеспечения. В отличие от многих языков того времени, которые были привязаны к конкретным типам компьютеров или операционных систем, Java с самого начала задумывался как кроссплатформенный. Это означает, что программу, написанную на Java, можно запустить практически на любом устройстве — от мощного сервера до мобильного телефона или даже бытовой техники, — конечно, при наличии специальной среды выполнения.</p><p>В основе этой универсальности лежит принцип: «написано один раз — работает везде». Это стало возможным благодаря технологии JVM (Java Virtual Machine — виртуальная машина Java). Процесс работы выглядит так: разработчик пишет код на Java, который затем компилируется (преобразуется) не в команды для конкретного процессора, а в особый промежуточный код, называемый байт-кодом. Этот байт-код может выполниться на любой платформе, где установлена своя версия JVM. JVM выступает в роли «переводчика» и исполнителя: она читает универсальный байт-код и «объясняет» его конкретному компьютеру на его языке. Именно этот принцип обеспечил Java долголетие и широкое применение.</p><p>Благодаря такой архитектуре, Java стал стандартным, проверенным инструментом для создания сложных программных систем. Его выбирают там, где важны стабильность, безопасность и возможность масштабирования — то есть работы под большой нагрузкой для миллионов пользователей одновременно.</p><p>Для детей Java — это не просто изучение синтаксиса языка, это погружение в принципы построения современного, промышленного программного обеспечения.</p><p>Именно эти принципы — <b>универсальность</b>, <b>четкость</b> и <b>широкие возможности</b> — делают Java не просто языком программирования, а отличным образовательным инструментом. Java учит детей не просто писать код, а мыслить структурно, проектировать решения и понимать, как устроены настоящие программы. Если этот подход вам близок и вы видите потенциал в таком обучении, приглашаем вас и вашего юного программиста познакомиться с Java ближе. В Школе программирования для детей «Пиксель» Java — это один из ключевых языков для обучения старшеклассников.</p><p>Подробнее о нашем онлайн-курсе <a href="https://pixel.study/java-for-children?utm_source=tproger&amp;utm_medium=article&amp;utm_campaign=java-dlya-detej-nadezhnyj-fundament-dlya-budushchego-razrabotchika" rel="nofollow">«Программирование на Java для детей 14-17 лет» можно узнать здесь</a>.</p><p>Первый урок курса — бесплатный, на нем под руководством преподавателя ребенок напишет свой первый код на Java, протестирует формат обучения и сможет задать любые вопросы. <a href="https://pixel.study/demo?utm_source=tproger&amp;utm_medium=article&amp;utm_campaign=java-dlya-detej-nadezhnyj-fundament-dlya-budushchego-razrabotchika" rel="nofollow">Запись на бесплатный пробный урок здесь</a>.</p><h2>Основы языка Java</h2><p>Java известен своим относительно простым и понятным синтаксисом (набором правил написания кода) — именно поэтому Java отлично подходит детям. Многие его ключевые слова заимствованы из английского языка, и это облегчает начальное понимание. Такие команды, как <b>if</b> (если), <b>else</b> (иначе), <b>for</b> (для, цикл), <b>class</b> (класс), делают Java интуитивно понятным для детей. Это помогает новичкам сосредоточиться на изучении логики программирования, а не на запоминании сложных и абстрактных символов.</p><p>Одной из фундаментальных концепций Java является объектно-ориентированное программирование (ООП). В этой парадигме программа представляется как набор взаимодействующих объектов, каждый из которых является экземпляром определенного класса.</p><ul><li>Класс — общее описание сущности. Он определяет, какие данные (свойства) и доступные действия (методы) будут у объектов.</li><li>Объект — это конкретный экземпляр класса.</li></ul><p>Простой пример: представьте класс «Смартфон». В его чертеже указаны общие свойства: «модель», «цвет», «объемПамяти». Также указаны возможные действия: «позвонить()», «сделатьФото()».</p><p>От этого класса можно создать конкретные объекты:</p><ul><li>Объект «смартфонМаши» со значениями: модель = "iPhone 15", цвет = "синий", объемПамяти = 128.</li><li>Объект «смартфонПети» со значениями: модель = "Android Galaxy", цвет = "черный", объемПамяти = 256.</li></ul><p>Оба объекта имеют одинаковый набор свойств и методов (структуру), но у этих свойств и методов разные значения. ООП помогает структурировать сложные программы, делая код более организованным, понятным и пригодным для повторного использования. Вместо одного большого и запутанного списка инструкций, программа делится на логические модули-объекты, которые взаимодействуют друг с другом.</p><h2>Первая программа на Java для детей — «Hello, World!»</h2><p>Знакомство детей с Java, как и с любым другим языком программирования, традиционно начинается с программы, которая выводит на экран приветствие миру. Вот как это выглядит на Java:</p><p>Разберем код построчно:</p><p>public class HelloWorld {</p><ul><li>public — модификатор доступа, означающий, что класс доступен из любого места программы.</li><li>class — ключевое слово для объявления класса.</li><li>HelloWorld — имя класса. Оно должно совпадать с именем файла (HelloWorld.java). Фигурная скобка { обозначает начало тела класса.</li></ul><p>public static void main(String[] args) {</p><ul><li>Это объявление главного метода программы. Его имя main — особое, именно с этой точки Java начинает выполнение кода.</li><li>public static void — это обязательная комбинация для главного метода, которую на начальном этапе можно запомнить как формулу.</li><li>(String[] args) — параметры метода, в данном случае возможность передавать программе аргументы командной строки.</li></ul><p>System.out.println("Hello, World!");</p><ul><li>Это исполнительная строка, которая выполняет действие.</li><li>System.out — стандартный объект для вывода информации.</li><li>println — его метод, который выводит текст и переводит курсор на новую строку.</li><li>("Hello, World!") — текст (строка), который нужно вывести. Текст всегда заключается в двойные кавычки-лапки.</li><li>Каждая команда в Java (кроме объявлений) завершается точкой с запятой ;. Это обязательно.</li></ul><p>Закрывающие фигурные скобки <b>}</b> обозначают конец метода <b>main</b> и конец класса <b>HelloWorld</b>.</p><p>Этот пример показывает детям, что даже самая простая программа в Java демонстрирует важные принципы: обязательное наличие класса, обязательный главный метод main как точка входа и четкий синтаксис с фигурными скобками и точкой с запятой. Такая же структура лежит в основе любого Java-приложения.</p><h2>Где используют Java? Неожиданные места и большие проекты</h2><p>Java успешно применяют в самых разных сферах. Его универсальность и надежность не просто сделали его основой для миллионов приложений по всему миру — и взрослые, и дети взаимодействуют с Java-приложениями ежедневно!</p><p><b>Мобильная разработка на платформе Android</b></p><p>Операционная система Android, которая установлена на подавляющем большинстве смартфонов и планшетов в мире, в значительной степени создана на Java. Большинство приложений в Google Play Store также написано на Java или Kotlin (языке, который полностью совместим с Java и работает на той же виртуальной машине). Для детей Java — это язык мобильных игр и приложений на телефоне, которыми они пользуются каждый день.</p><p><b>Серверная часть веб-сайтов и онлайн-сервисов (бэкенд)</b></p><p>Когда пользователь заходит на сайт интернет-банка, социальной сети или крупного магазина, его браузер показывает лишь интерфейс — «лицевую часть» приложения (фронтенд). Обработка данных, расчеты и взаимодействие с базами данных происходят на удаленных серверах. Эта скрытая от глаз, но критически важная серверная часть приложения (бэкенд) очень часто построена на Java — и именно Java в этом случае отвечает за надежную работу функций поиска, оформления заказов, обработки платежей и личных кабинетов.</p><p><b>Обработка больших данных и корпоративное программное обеспечение</b></p><p>Современные компании и научные организации анализируют колоссальные объемы информации — от финансовых транзакций до данных с различных датчиков. Для обработки таких массивов данных (их обычно называют Big Data) часто используются инструменты, созданные на Java, например, Apache Hadoop и Apache Spark. Кроме того, Java — это традиционный и проверенный язык для сложного корпоративного софта: систем управления предприятиями (ERP), систем автоматизации бизнес-процессов и клиент-серверных приложений в крупных организациях, где в приоритете стабильность и безопасность.</p><p><b>Разработка игр</b></p><p>Еще один пример, близкий детям: на Java была написана первоначальная версия культовой игры Minecraft. Это наглядно демонстрирует возможности языка в создании сложных графических миров. Хотя для высокобюджетных компьютерных игр чаще используются C++ или C#, Java активно применяется для разработки мобильных игр под Android, а также для создания серверных компонентов многопользовательских игр, которые отвечают за логику, учетные записи и взаимодействие игроков в сети.</p><p><b>Устройства «умного» дома и Интернета вещей (IoT)</b></p><p>Java, благодаря своей кроссплатформенности и высокой степени безопасности, применяют и во встраиваемых системах. Его используют в некоторых типах смарт-телевизоров, медиаплееров, системах «умного» дома для программирования работы устройств. Существует специальная оптимизированная версия Java — Java ME (Micro Edition) — предназначенная для программирования маломощных устройств, таких как датчики или бытовая техника с сетевым управлением.</p><p>Все эти примеры показывают, что Java — это язык, который работает в самых разных контекстах. Изучение программирования на Java для детей — это путь не к одной узкой специальности, а к широкому спектру современных и востребованных IT-направлений.</p><h2>Почему Java — отличный выбор для первого «взрослого» языка</h2><p>Переход от визуальных языков программирования (как Scratch) или простых скриптовых языков к первому серьезному, «взрослому» языку — важный этап. Для детей Java является одним из оптимальных вариантов по нескольким причинам:</p><p><b>Строгая дисциплина и структурированное мышление</b></p><p>Java — язык со статической типизацией и четкой, формальной структурой. Это означает, что программисту нужно заранее объявлять тип каждой переменной (например, <b>int</b> для числа, <b>String</b> для текста), а каждая программа должна быть организована в виде классов и методов.</p><p>С Java ребенок не может написать хаотичный код, который «как-нибудь работает». Ему приходится сначала продумать структуру: какие сущности (классы) будут в программе, какие у них будут свойства и действия. Любая опечатка или логическая ошибка приводит к тому, что программа просто не запустится или ее не получится скомпилировать. Это приучает к аккуратности, внимательности к деталям и привычке планировать решение задачи перед тем, как писать код. Такая дисциплина — бесценный навык для любого инженера.</p><p><b>Огромное сообщество и обилие ресурсов</b></p><p>Java существует почти три десятилетия, и за это время вокруг него сформировалось одно из самых больших сообществ разработчиков в мире.</p><p>На любой вопрос, который может возникнуть у ребенка о программировании на Java, с высокой вероятностью уже есть подробный ответ на таких платформах, как Stack Overflow. Существуют миллионы готовых библиотек — наборов кода для решения типовых задач (работа с графикой, сетью, базами данных). Программируя на Java, ребенок учится не только писать все с нуля, но и правильно использовать готовые инструменты — а это стандартная практика в реальной разработке. Качественная документация и огромное количество учебных материалов облегчают процесс обучения.</p><p><b>Прямой путь к востребованной профессии</b></p><p>Java десятилетиями занимает ведущие позиции в рейтингах самых популярных и востребованных языков программирования:</p><ul><li>Это язык, на котором построена критически важная инфраструктура тысяч крупных компаний в банковском секторе, телекоммуникациях, ритейле. Такие системы обновляются и поддерживаются, но крайне редко полностью переписываются. Это обеспечивает постоянный спрос на Java-разработчиков.</li><li>Знание Java для ребенка — это двери в несколько карьерных направлений сразу: разработка корпоративный софта, создание серверной части высоконагруженных веб-сервисов, мобильная разработка под Android. Это дает возможность выбора и специализации в будущем.</li></ul><p><b>Фундамент для изучения других технологий</b></p><p>Принципы, которые ребенок осваивает при изучении Java, фундаментальны для современной software-инженерии.</p><p>Java — один из лучших языков для глубокого понимания ООП. Понимание инкапсуляции, наследования и полиморфизма в Java создаст у ребенка прочную базу.</p><p>Освоив Java, гораздо проще выучить синтаксически и концептуально похожие языки. Например, C# (основной язык для разработки под Windows и игр на Unity) или Kotlin (официальный язык для Android, который полностью совместим с Java). Даже переход на такие языки, как Python, будет осознанным, потому что ребенок уже будет понимать, какие механизмы Python упрощает, а какие остаются общими.</p><p>Программирование на Java учит ребенка инженерной культуре: дисциплинированности, использованию инструментов сообщества, пониманию рыночных требований и фундаментальных принципов, на которых строится современная разработка.</p><h2>Java для детей: первые проекты</h2><p>Прежде чем приступить к изучению Java, нужна несложная, но важная подготовка. Первый шаг — установка профессиональной бесплатной среды разработки (Integrated Development Environment, IDE). Оптимальный выбор для Java — IntelliJ IDEA Community Edition. Эта среда, созданная компанией JetBrains, очень удобна и используется разработчиками по всему миру. Она значительно упрощает процесс: подсвечивает синтаксис, автоматически находит ошибки, предлагает варианты завершения кода и имеет удобный интерфейс для управления проектами. Установка проходит стандартно: нужно зайти на <a href="https://www.jetbrains.com/ru-ru/" rel="nofollow">официальный сайт JetBrains</a>, скачать дистрибутив для вашей операционной системы (Windows, macOS, Linux) и следовать инструкциям установщика. После первого запуска среда готова к созданию нового проекта.</p><p>После настройки инструментов можно приступать к первым проектам:</p><p><b>Текстовый квест или чат-бот в консоли</b>. Для ребенка это отличный способ освоить базовые конструкции Java: переменные, условные операторы (<b>if</b>-<b>else</b>), циклы (<b>while</b>, <b>for</b>) и работу со строковым вводом/выводом. Ребенок может написать программу, которая задает пользователю вопросы, сохраняет ответы в переменных и в зависимости от выбора выводит разные текстовые описания развития сюжета. Такой проект учит алгоритмическому мышлению и построению логических ветвлений.</p><p><b>Простой калькулятор.</b> Этот классический проект помогает понять работу с арифметическими операциями, разными типами данных (например, <b>int</b> для целых чисел и <b>double</b> для дробных) и организацией простейшего пользовательского интерфейса в консоли. Можно начать с программы, которая запрашивает два числа и операцию (+, -, *, /), а затем выводит результат. Затем задачу можно усложнить, добавив обработку ошибок (например, деления на ноль) или цикл, позволяющий производить вычисления без перезапуска программы.</p><p><b>Графическая программа с библиотекой Processing.</b> Для визуального результата, который особенно мотивирует детей, отлично подходит библиотека Processing for Java. Она упрощает создание графики и анимации, предоставляя простые функции для рисования фигур, работы с цветами и обработки событий мыши или клавиатуры. Первым проектом может стать интерактивный рисунок: например, программа, где при клике мышью на холсте появляется круг случайного цвета, или простейшая анимация движущегося объекта. Такая программа наглядно продемонстрирует связь кода и визуального действия, а также познакомит с основами обработки событий — ключевой концепции в программировании.</p><h2>Программирование на Java: правила эффективной учебы для детей</h2><ol><li>Регулярная практика. Постоянство важнее объема. Лучше писать код по 30-40 минут ежедневно, чем 5 часов раз в неделю. Это помогает лучше запоминать синтаксис и развивать мышечную память.</li><li>Чтение и анализ чужого кода. Изучение готовых, хорошо написанных небольших программ или фрагментов кода (например, на GitHub) помогает понять разные стили программирования, узнавать новые приемы и видеть, как решаются типовые задачи.</li><li>Дробление больших задач на маленькие. Любой сложный проект нужно разбивать на простые, последовательные шаги. Сначала — спланировать логику на бумаге или в комментариях, затем — реализовать ядро, потом добавить детали и, наконец, провести тестирование. Этот подход избавляет от ощущения перегруженности и учит системному проектированию.</li><li>Не бояться ошибок. Ошибки компиляции и логические недочеты — естественная часть процесса обучения. Умение внимательно читать сообщения об ошибках от среды разработки, понимать их причину и исправлять — один из самых важных навыков, который нужно формировать с самого начала.</li></ol><h2>Частые вопросы о Java для детей и подростков</h2><p><b>Со скольки лет можно начинать изучать Java? Не слишком ли это сложно для ребенка?</b></p><p>Java действительно является «взрослым» языком, требующим от ученика определенной зрелости мышления. Наиболее подходящий возраст для начала системного изучения — 12-14 лет. К этому времени у ребенка, как правило, уже сформированы базовые навыки логического и абстрактного мышления, необходимые для понимания таких концепций, как объектно-ориентированное программирование. Важным фактором является и мотивация: если ребенок уже имеет опыт работы в визуальных средах (например, Scratch) или проявил интерес к созданию собственных игр и программ, он готов к более сложным задачам. Сложность Java — это его достоинство. Он не позволяет писать небрежный код, и поэтому с самого начала прививает дисциплину, аккуратность и привычку продумывать архитектуру решения. Для талантливого и увлеченного подростка эта сложность становится не барьером, а интересным вызовом.</p><p><b>Чем Java лучше или хуже, чем Python, для первого языка программирования?</b></p><p>Это два разных подхода с разными целями. Python завоевал популярность благодаря минималистичному синтаксису, который позволяет быстро получить результат, что отлично подходит для младших школьников или для изучения основ алгоритмов. Java, в свою очередь, делает акцент на строгости и структуре. Он заставляет явно объявлять типы переменных, организовывать код в классы, что изначально формирует понимание «правильного» промышленного подхода к разработке. Если Python учит решать задачи, то Java учит строить надежные, масштабируемые системы. Выбор зависит от цели: если нужно быстро и увлекательно познакомить с программированием — можно начать с Python. Если стоит задача заложить максимально прочный фундамент для будущей карьеры в IT, особенно в таких областях, как enterprise-разработка или Android, — Java будет предпочтительнее. Многие педагоги считают, что после освоения основ на одном языке переход на второй дается значительно легче.</p><p><b>Что конкретно должен уметь и знать ребенок, чтобы начать изучение Java?</b></p><p>Глубоких специальных знаний не требуется. Нужна базовая компьютерная грамотность: уверенная работа с файловой системой (создание папок, сохранение файлов), навыки печати, понимание, что такое установка программы. Крайне важно иметь развитое логическое и алгоритмическое мышление. Этому часто способствует увлечение математикой, логическими головоломками или даже стратегическими играми. Опыт программирования в любой форме (Scratch, блочное программирование в Minecraft или простые скрипты) является большим преимуществом, но не строго обязательным. Самое главное — желание и готовность к последовательной, иногда кропотливой работе, где результат достигается не мгновенно, а через анализ и исправление ошибок.</p><p><b>Насколько сложна установка среды разработки и подготовка к первым урокам?</b></p><p>Технический порог входа сегодня минимален. Установка бесплатной среды разработки IntelliJ IDEA Community Edition ничем не отличается от установки любой другой программы и занимает 10-15 минут. Современные среды (IDE) максимально упрощены для новичков: они автоматически определяют настройки, предлагают создать первый проект в пару кликов, а встроенные системы подсказок и проверки кода (автодополнение, подсветка ошибок) служат интерактивным учебным пособием. Технические аспекты не должны пугать; основное внимание с первого же занятия уделяется непосредственно логике и синтаксису языка.</p><p><b>Какие реальные проекты сможет делать ребенок после 3-6 месяцев изучения Java?</b></p><p>Прогресс напрямую зависит от регулярности и системности занятий. При условии стабильной практики (2-3 раза в неделю) за несколько месяцев можно пройти путь от основ синтаксиса до создания законченных работающих приложений. Итогом первого этапа обычно становятся:</p><ul><li>Консольные приложения. Разнообразные текстовые квесты с нелинейным сюжетом, программы-шифровальщики, простые имитаторы банкомата или телефонной книги с функциями добавления и поиска.</li><li>Графические приложения (с использованием библиотек, например, Processing). Интерактивные арты, где рисунок реагирует на движения мыши, классические аркады («Змейка» или «Понг»), простые симуляторы (например, падающих снежинок).</li><li>Начало работы с графическим интерфейсом (GUI). Создание оконных приложений с кнопками, текстовыми полями и метками — например, усовершенствованный калькулятор с графическим интерфейсом или программа-напоминалка.Эти проекты не являются строго учебными; они используют те же принципы и подходы, что и в реальной разработке, давая ребенку ощутимый результат своей работы.</li></ul><p><b>Почему в процессе обучения так много внимания уделяется ошибкам (error messages)?</b></p><p>Работа с ошибками — это один из ключевых навыков программиста. Язык и среда разработки Java дают ребенку детальные, часто очень точные описания того, что пошло не так. Умение не пугаться красного текста в консоли, а прочитать, вникнуть в сообщение об ошибке и методично исправить проблему — это фундаментальный мета-навык. Он развивает критическое мышление, терпение и умение самостоятельно искать решение проблем, что гораздо важнее заучивания конкретных конструкций языка. Наставник в этом процессе играет роль проводника, который учит «читать» эти сообщения и применять системный подход к отладке.</p><p><b>Как родитель, не знакомый с программированием, может помочь и поддержать ребенка?</b></p><p>Самая важная роль родителя — организационная и мотивационная. Вы можете помочь создать стабильное расписание для занятий, проявить искренний интерес к проектам ребенка (даже если суть кода не до конца понятна), просто посмотрев, что получилось в итоге. Не ругайте за ошибки, а помогите создать атмосферу, где ошибки воспринимаются как нормальная и полезная часть обучения. Технически вы можете помочь на этапе первоначальной настройки компьютера и установки программ. Главное — поощрять любознательность и настойчивость, и не требовать мгновенных идеальных результатов. Если ребенок задает вопрос, на который вы не знаете ответа, лучшей тактикой будет предложить вместе поискать решение в документации или проверенных источниках в интернете, тем самым моделируя рабочий процесс современного разработчика.</p><p>Java — это не абстрактный или исключительно сложный язык, предназначенный только для опытных инженеров. Это логичный и структурированный язык программирования и изучать его будет увлекательно даже для начинающих. Его синтаксис способствует формированию четкого, алгоритмического мышления, а принципы объектно-ориентированного программирования учат организовывать код так, как это делается в реальных, промышленных проектах.</p><p>Изучение Java для детей — это прямой путь к пониманию того, как создается современное программное обеспечение. От первой строки кода, выводящей приветствие, до проектирования собственных приложений, этот язык дает возможность не только освоить конкретную технологию, но и сформировать прочный фундамент в области информатики и разработки. Это знание открывает двери в мир реальной, востребованной IT-индустрии, где логика, аккуратность и умение строить сложные системы ценятся особенно высоко.</p><p><i>Реклама. Рекламодатель ООО «Пиксель.Стади», ИНН 5074078988, erid: 2W5zFJM8gaL</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Пузырь 2021–2022 годов лопнул: эксперты составили прогноз рынка на 2026 год</title>
      <link>https://tproger.ru/news/puzyr-2021-2022-godov-lopnul--eksperty-sostavili-prognoz-rynka-na-2026-god</link>
      <comments>https://tproger.ru/news/puzyr-2021-2022-godov-lopnul--eksperty-sostavili-prognoz-rynka-na-2026-god?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/puzyr-2021-2022-godov-lopnul--eksperty-sostavili-prognoz-rynka-na-2026-god</guid>
      <description><![CDATA[<p>После пузыря 2021–2022 ИТ-рынок стабилизируется: в 2026 ждут низкий найм, меньше джунов и рост спроса на сильных инженеров</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/puzyr-2021-2022-godov-lopnul--eksperty-sostavili-prognoz-rynka-na-2026-god">Пузырь 2021–2022 годов лопнул: эксперты составили прогноз рынка на 2026 год</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Навыки]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Fullstack]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 30 Dec 2025 11:01:55 GMT</pubDate>
      <content:encoded><![CDATA[<p>IT-рынок пережил болезненную коррекцию после бума и перегрева 2021–2022 годов.</p><p>Тогда компании нанимали инженеров с запасом, под давлением цифровизации, дешевых денег и страха «остаться позади». По данным Indeed и FRED, пик вакансий пришелся на середину 2022 года. После чего последовал резкий спад, так и не вернувшись до прежнего уровня.</p><h2>Почему ИИ — удобный, но не главный виновник</h2><p>ИИ стал публичным оправданием сокращений. Заявление «мы заменяем людей на ИИ» хорошо смотрится в отчетах и перед инвесторами.</p><p>На практике же компании сокращали издержки, выравнивали штат и параллельно активнее нанимали за пределами США и Европы, где инженеры стоят дешевле.</p><p>Исследования показывают, что ИИ пока не делает разработчиков быстрее в реальной работе. Напротив, опытные инженеры иногда теряют в продуктивности из-за необходимости проверять и исправлять сгенерированный код.</p><h2>Как будет выглядеть рынок в 2026 году</h2><p>Эксперты <a href="https://www.finalroundai.com/blog/software-engineering-job-market-2026">сходятся</a> во мнении: 2026 год пройдет в режиме «низкого найма — низких увольнений». Массовых сокращений не ожидается, но и бурного роста вакансий не будет. Так выглядит стабилизация рынка.</p><p>При этом спрос смещается — универсальных «кодеров» нужно меньше. А вот инженеры, которые умеют проектировать системы, работать с производительностью, безопасностью и сложной интеграцией, наоборот будут все чаще находить вакансии под себя.</p><p>По прогнозу Бюро статистики труда США, число вакансий для разработчиков продолжит расти примерно на 15%. Это медленнее, чем ожидалось раньше, но все еще быстрее большинства профессий.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-12-30/3a3ad90f-f354-48b3-83bd-8857158de8e8.jpeg" alt="" /></figure><h2>Почему джунам повезло меньше всего</h2><p>Самое слабое место рынка — начальные позиции. Количество вакансий для junior-разработчиков упало примерно на 40% по сравнению с допандемийным уровнем.</p><p>Компании больше не готовы вкладываться в длительное обучение: им нужны люди, которые могут приносить пользу почти сразу.</p><p>Но это также создает отложенную проблему — без притока новичков рушится кадровый «конвейер».</p><h2>Какие навыки реально востребованы</h2><p>В 2026 году ценятся не языки сами по себе, а связки «язык + область».</p><p>Тот же Python чаще всего нужен при работе с ИИ и данными. JavaScript и TypeScript — для фронтенда и fullstack. Go — для бэкенда и инфраструктуры. Java — для enterprise-систем.</p><p>Параллельно растет спрос на ИИ- и дата-инженеров, а также специалистов по ИИ-инфраструктуре.</p>]]></content:encoded>
    </item>
    <item>
      <title>Java: 15 самых популярных докладов 2025 года на YouTube</title>
      <link>https://tproger.ru/articles/java--15-samyh-populyarnyh-dokladov-2025-goda-na-youtube</link>
      <comments>https://tproger.ru/articles/java--15-samyh-populyarnyh-dokladov-2025-goda-na-youtube?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Валерия Турчак]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/java--15-samyh-populyarnyh-dokladov-2025-goda-na-youtube</guid>
      <description><![CDATA[<p>От базовой прокачки производительности до работы с ИИ и данными. Все доклады доступны бесплатно на YouTube</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/java--15-samyh-populyarnyh-dokladov-2025-goda-na-youtube">Java: 15 самых популярных докладов 2025 года на YouTube</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Конференции]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 20 Dec 2025 12:30:03 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Это перевод и адаптация от Тпрогер <a href="https://www.techtalksweekly.io/p/100-most-watched-talks-in-java-rust">оригинальной статьи</a>. Все доклады доступны на английском языке. Вы можете смотреть их в браузере с включенным синхронным переводом на русский язык (Yandex, как вариант) или с субтитрами. </i></p><p>2025 год получился насыщенным для Java: вышел JDK 25, активно развиваются проекты Amber и Valhalla, улучшается производительность сборщиков мусора. Собрали топ-15 самых просматриваемых докладов о Java с конференций этого года. К каждому найдёте короткое описание, чтобы вы могли быстро решить, стоит ли тратить на него время.</p><h3>1. How Netflix Uses Java - 2025 Edition</h3><p>Конференция - 272 000 просмотров - 26 апреля 2025 - 47 минут</p><p>Netflix управляет более чем 3000 микросервисов на Java. В докладе разбирают, как компания использует Spring Boot, DGS (их GraphQL-фреймворк) и gRPC для взаимодействия между сервисами. Показывают работу с новыми сборщиками мусора, виртуальными потоками (virtual threads) и делятся реальными уроками по управлению зависимостями и созданию native images.</p><p><b>Почему стоит посмотреть:</b> Если работаете с Java в продакшене или планируете масштабировать систему, доклад показывает практики от компании, которая обрабатывает миллионы запросов ежедневно. Много конкретики про инфраструктуру и мало маркетинга.</p><h3>2. Java Performance Update</h3><p>Конференция - 71 000 просмотров - 25 января 2025 - 53 минуты</p><p>Доклад представляет пять недавних улучшений производительности в JDK. Разбирают оптимизацию MergeStore JIT, которая ускоряет слияние массивов, изменения в сборщиках мусора и оптимизации стандартной библиотеки. Главный тезис: Java становится быстрее без изменений в вашем коде.</p><p><b>Почему стоит посмотреть: </b>Если у вас есть приложения на Java 8-11 и вы сомневаетесь, стоит ли обновляться, этот доклад покажет конкретные цифры производительности. Объясняют не только что изменилось, но и почему это работает быстрее на уровне JVM.</p><h3>3. Where is the Java language going?</h3><p>Конференция - 65 000 просмотров - 20 апреля 2025 - 45 минут</p><p>Обзор последних обновлений и планов развития Java. Подробно разбирают новые возможности из Project Amber (улучшения синтаксиса языка) и Project Valhalla (value types и primitive classes), которые формируют будущее языка.</p><p><b>Почему стоит посмотреть:</b> Доклад помогает понять, куда движется Java в следующие несколько лет. Полезно для планирования обучения команды и принятия решений об архитектуре новых проектов.</p><h3>4. Java 24 Launch - Live from JavaOne 2025</h3><p>Конференция - 62 000 просмотров - 19 марта 2025 - 2 часа 47 минут</p><p>Официальная презентация Java 24 с конференции JavaOne. Включает вступительный доклад с живыми демонстрациями, разбор улучшений производительности сборщиков мусора, AOT-кеширование (Ahead-Of-Time compilation cache) и stream gatherers — новый API для работы с потоками данных.</p><p><b>Почему стоит посмотреть: </b>Это официальный обзор релиза от команды разработчиков Java. Если нужно понять, что нового в Java 24 и стоит ли переходить, смотрите это. Длинный формат позволяет подробно разобрать все важные фичи.</p><h3>5. Know Your Java?</h3><p>Конференция - 56 000 просмотров - 11 мая 2025 - 40 минут</p><p>Интерактивная демонстрация странных особенностей поведения Java, которые до сих пор ставят в тупик даже опытных разработчиков. Показывают неочевидные случаи с autoboxing, generics, type erasure и другими особенностями языка. Все с примерами кода, которые можно повторить.</p><p><b>Почему стоит посмотреть:</b> Если вы думаете, что хорошо знаете Java, этот доклад проверит вашу уверенность. Полезно для собеседований и для понимания, почему код иногда ведет себя неожиданно. Формат интерактивный — спикер задает вопросы аудитории, и можно попробовать ответить самостоятельно.</p><h3>6. Modern Java Deep Dive</h3><p>Конференция - 40 000 просмотров - 8 февраля 2025 - 2 часа 31 минута</p><p>Глубокое погружение в Java 22 и 23. Разбирают множество небольших, но важных изменений: безымянные паттерны (unnamed patterns), примитивные паттерны (primitive patterns), Foreign Function and Memory API (для работы с нативным кодом), импорты модулей, stream gatherers, Markdown в JavaDoc и улучшения в сборщиках мусора.</p><p><b>Почему стоит посмотреть:</b> Доклад объясняет не просто что добавилось, но и что финальное (можно использовать в продакшене), что в preview (экспериментальная фича), и почему это важно для реальных проектов.</p><h3>7. Java for AI</h3><p>Конференция - 39 000 просмотров - 3 мая 2025 - 44 минуты</p><p>Доклад показывает, как существующие и будущие возможности Java могут сделать язык конкурентоспособным в области искусственного интеллекта. Разбирают Foreign Function and Memory API (для вызова библиотек машинного обучения), Vector API (для SIMD-операций), Project Valhalla (value types для производительности) и Project Babylon (компиляция Java-кода для GPU).</p><p><b>Почему стоит посмотреть: </b>Если интересуетесь машинным обучением и хотите понять, можно ли использовать Java вместо Python, этот доклад дает конкретные идеи для библиотек и инструментов.</p><h3>8. Real World Lean Java Practices, Patterns, Hacks, and Workarounds</h3><p>Конференция - 35 000 просмотров - 5 мая 2025 - 51 минута</p><p>Практические подходы для Java 21 и выше: как убрать избыточность из кода, структурировать монолиты и микросервисы, улучшить тестирование, использовать data-oriented паттерны (работа с данными вместо объектов), decoupling паттерны (уменьшение связанности), автоматизировать процессы с помощью чистой Java и переосмыслить дизайн кода для работы с LLM-ассистентами вроде GitHub Copilot.</p><p><b>Почему стоит посмотреть:</b> Это не теоретический доклад, а подборка рабочих приемов от опытного разработчика. Полезно для рефакторинга legacy-кода и проектирования новых систем. Много примеров того, как новые возможности Java 21+ упрощают код.</p><h3>9. A Java Developer's Guide to Navigating the Frontend Landscape</h3><p>Конференция - 34 000 просмотров - 1 мая 2025 - 46 минут</p><p>Практическое руководство для Java-разработчиков по современному фронтенду. Сравнивают Java UI-фреймворки (JavaFX, Vaadin) с популярными JavaScript-фреймворками (React, Angular, Vue). Раскрывают современные техники фронтенд-разработки и компромиссы между разными подходами.</p><p><b>Почему стоит посмотреть:</b> Если вы бэкенд-разработчик на Java и хотите понять, что происходит на фронтенде, этот доклад объясняет основы без излишнего погружения. Помогает найти общий язык с фронтенд-командой и принимать осознанные решения при выборе технологий для проекта.</p><h3>10. The New Java Best Practices by Stephen Colebourne</h3><p>Конференция - 36 000 просмотров - 9 октября 2025 - 48 минут</p><p>Лучшие практики Java кардинально изменились со времен Java 8. Stephen Colebourne (создатель Joda-Time и активный участник развития Java) разбирает современные подходы: records versus beans, pattern matching, Optional versus null, data-oriented programming. Дает четкие, аргументированные рекомендации по каждому вопросу.</p><p><b>Почему стоит посмотреть: </b>Если вы пишете на Java по привычкам из эпохи Java 8, этот доклад обновит ваше понимание того, как писать современный Java-код. Спикер немного резкий, но много обоснованных мнений, будет точно полезно.</p><h3>11. AI/ML Introduction for Java Developers</h3><p>Конференция - 29 000 просмотров - 2 июня 2025 - 52 минуты</p><p>Практическое введение в машинное обучение и генеративный ИИ для Java-разработчиков. Объясняют разницу между GenAI (генеративный ИИ вроде GPT) и PredAI (предиктивный ИИ для прогнозирования), стратегии написания промтов, работу с LLM API через библиотеки вроде Langchain4J, векторные базы данных и RAG (Retrieval-Augmented Generation).</p><p><b>Почему стоит посмотреть: </b>Доклад с демонстрациями кода показывает, где генеративный ИИ реально помогает, а где его лучше избегать. Если хотите интегрировать ИИ в Java-приложения, этот доклад даст практическую дорожную карту.</p><h3>12. Growing the Java Language #JVMLS</h3><p>Конференция - 28 000 просмотров - 21 августа 2025 - 1 час 20 минут</p><p>Доклад о том, как Java может развиваться, сохраняя обратную совместимость. Разбирают дизайнерские компромиссы, ограничения JVM и практические пути внедрения новых возможностей языка. Показывают, почему некоторые фичи появляются быстро, а другие застревают в обсуждениях годами.</p><p><b>Почему стоит посмотреть: </b>Если интересует будущее Java или разработка языков программирования в целом, этот доклад показывает реальные процессы принятия решений.</p><h3>13. Java 24 - Better Language, Better APIs, Better Runtime</h3><p>Конференция - 26 000 просмотров - 1 марта 2025 - 51 минута</p><p>Обзор Java 24, который фокусируется на практических улучшениях: AOT-загрузка классов (Ahead-Of-Time class loading для ускорения старта), stream gatherers (новый способ обработки потоков данных), class-file API (программный доступ к байткоду) и улучшения в ZGC (сборщик мусора с низкими паузами).</p><p><b>Почему стоит посмотреть: </b>Доклад показывает, какие изменения в Java 24 действительно нужны для рабочих приложений.</p><h3>14. SQL, JSON, and Java</h3><p>Конференция - 25 000 просмотров - 14 апреля 2025 - 50 минут</p><p>Современные мультимодельные базы данных начинают обходить MongoDB по возможностям, объединяя SQL и JSON в одной системе. Доклад с конференции JavaOne разбирает компромиссы между JSON и реляционными данными, стандарт ISO SQL для работы с JSON, бинарный JSON для низколатентного JDBC, интеграции с Jackson и Jakarta, и как record patterns в Java 21 делают schema-less хранение JSON практичным.</p><p><b>Почему стоит посмотреть: </b>Если работаете с данными в Java и выбираете между реляционными базами и NoSQL, этот доклад показывает современный подход, который объединяет лучшее из обоих миров. Много практических примеров работы с JSON в PostgreSQL, Oracle и других БД.</p><h3>15. Garbage Collection in Java - The progress since JDK 8</h3><p>Конференция - 24 000 просмотров - 15 февраля 2025 - 50 минут</p><p>Сборка мусора в Java прошла долгий путь с JDK 8. Доклад проходит по разным сборщикам (G1GC, ZGC, Shenandoah), объясняет практические компромиссы между ними и показывает, почему простое обновление JDK может реально ускорить приложения.</p><p><b>Почему стоит посмотреть:</b> Если у вас проблемы с производительностью, долгие GC-паузы или высокое потребление памяти, этот доклад объясняет, какой сборщик мусора выбрать и как его настроить.</p><p>Итого вы получили 15 докладов, которые покрывают все актуальные моменты современной Java — от базовых улучшений производительности до работы с ИИ и данными. В следующей части выложим доклады по Rust.</p>]]></content:encoded>
    </item>
    <item>
      <title>Какие навыки в IT будут решающими в 2026 году: разбор по специализациям</title>
      <link>https://tproger.ru/articles/kakie-navyki-v-it-budut-rewayushhimi-v-2026-godu--razbor-po-specializaciyam</link>
      <comments>https://tproger.ru/articles/kakie-navyki-v-it-budut-rewayushhimi-v-2026-godu--razbor-po-specializaciyam?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Валерия Турчак]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kakie-navyki-v-it-budut-rewayushhimi-v-2026-godu--razbor-po-specializaciyam</guid>
      <description><![CDATA[<p>Разбираем, какие скилы и знания станут обязательными в 2026 году, что будут ценить работодатели и как новичку не потеряться на входе в ИТ-индустрию
</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kakie-navyki-v-it-budut-rewayushhimi-v-2026-godu--razbor-po-specializaciyam">Какие навыки в IT будут решающими в 2026 году: разбор по специализациям</a>»</p>]]></description>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Python]]></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, 17 Dec 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Российский IT-рынок продолжает расти, но требования к специалистам меняются быстрее, чем многие успевают адаптироваться. Импортозамещение заставляет компании переходить на отечественные платформы, ИИ внедряется во все процессы, а гибридная работа стала стандартом. При этом начинающие специалисты часто совершают одну и ту же ошибку: хватаются за случайные курсы и не понимают, какие навыки реально влияют на трудоустройство и зарплату.</p><p>По данным World Economic Forum, 44% профессиональных навыков обновятся к 2027 году. Елена Соколова, Product Owner в Компьютерной Академии ТОП (ранее работала карьерным консультантом в Яндекс Практикуме и Нетологии, реализовывала проекты в Carlsberg Group, Лента, РЖД, Danone), за 850+ часов консультаций помогла специалистам устроиться в Яндекс, EPAM, МТС, Сбер и Ozon. Основная проблема, которую она видит: люди учатся хаотично, не понимая системы.</p><p>Разбираемся, какие компетенции станут обязательными в 2026 году и как они связаны между собой.</p><p>Первый блок — универсальные навыки, которые нужны всем, второй — техническая специализация по направлениям, третий — навык-усилитель для тех, кто хочет системно влиять на продукт и процессы.</p><h2>Универсальные навыки: фундамент для всех направлений</h2><p>Рынок требует не десять абсолютно разных скиллов, а три связанных блока компетенций. Первый — универсальные навыки, без которых сложно расти в любом направлении IT.</p><h3>Когнитивное лидерство</h3><p>Аналитическое и креативное мышление заняли первое и второе места в рейтинге навыков будущего по версии World Economic Forum 2024. Это способность разбирать сложные задачи на части, находить нестандартные решения и выстраивать логические цепочки. Вдобавок — устойчивость, гибкость и любознательность: качества, которые помогают адаптироваться к меняющимся требованиям рынка и осваивать новые инструменты.</p><blockquote>На консультациях часто встречаются сильные технические специалисты, которые застревают на одной позиции годами. Проблема не в недостатке знаний кода, а в неумении анализировать карьерную ситуацию и принимать решения в условиях неопределенности.</blockquote><p><b>Как развивать: </b>решайте задачи на алгоритмы на LeetCode или Codewars, участвуйте в хакатонах, разбирайте чужой код на GitHub и пытайтесь объясняйть логику решений.</p><h3>Техно-гуманитарная грамотность</h3><p>IT-специалист в 2026 году необязательно должен быть разработчиком, но должен понимать, как работают технологии и как правильно ставить им задачи. Грамотность в области ИИ и больших данных (AI &amp; Big Data Literacy) заняла седьмое место в рейтинге WEF — это умение сформулировать запрос к нейросети, оценить качество данных, выбрать подходящий инструмент для задачи.</p><p>Продакт-менеджер, который понимает принципы работы машинного обучения, может грамотно поставить задачу дата-сайентисту: объяснить, какие метрики важны, какие данные доступны и какой результат нужен бизнесу. Без этого понимания команда тратит недели на уточнения и переделки.</p><blockquote>На собеседованиях в топовые компании проверяют не только технические знания, но и умение объяснить, как технология решает бизнес-задачу. Кандидат может знать Python, но если он не понимает, зачем компании нужна автоматизация, это становится проблемой.</blockquote><p><b>Как развивать: </b>экспериментируйте с ChatGPT, Claude или Gemini, изучайте основы работы с API, читайте документацию инструментов, которыми пользуетесь ежедневно.</p><p>Для тех, кто хочет системно освоить работу с ИИ, существуют специализированные программы — например, <a href="http://top-academy.ru/education/master-neural">«Нейросети для увеличения дохода»</a> и <a href="http://top-academy.ru/education/artificial-intelligence-for-life">«Искусственный интеллект для жизни» </a>в Академии ТОП учат не просто генерировать контент, а ставить корректные задачи моделям и интегрировать их в рабочие процессы.</p><h3>Эмоциональный интеллект</h3><p>Чем больше команд работает удаленно и чем активнее ИИ забирает рутинные задачи, тем выше ценность навыков, которые невозможно автоматизировать. Эмпатия, активное слушание и лидерство социального влияния заняли восьмое и девятое места в рейтинге World Economic Forum. Эти компетенции помогают выстраивать сотрудничество, разрешать конфликты и вести команду к результату.</p><p>Тимлид замечает, что разработчик стал медленнее закрывать задачи и меньше общается в чате. Специалист с развитым эмоциональным интеллектом не отправляет формальное сообщение о несоблюдении сроков, а назначает личный созвон, выясняет причину и помогает решить проблему до того, как она повлияет на проект.</p><blockquote>В большинстве случаев решающим фактором было не только знание технологий, но и умение объяснить решение понятным языком и продемонстрировать навыки командной работы. Научить фреймворку можно за месяц, научить человека слушать и договариваться значительно сложнее.</blockquote><p>В удаленных командах эмоциональный интеллект становится критичнее: нет невербальных сигналов, сложнее считывать настроение, легче возникают недопонимания.</p><p><b>Как развивать: </b>давайте и запрашивайте обратную связь у коллег, анализируйте конфликты, наблюдайте за тем, как опытные менеджеры ведут сложные переговоры.</p><h3>Селф-менеджмент</h3><p>Мотивация и самосознание заняли четвертое место в рейтинге навыков будущего по версии World Economic Forum. Это способность управлять собственными ресурсами, удерживать фокус в условиях постоянных переключений и не выгорать при плотных дедлайнах.</p><p>Один специалист работает восемь часов, но половину времени тратит на переключения между задачами, проверку уведомлений и созвоны. Другой выделяет два часа глубокой работы утром, когда концентрация максимальна, закрывает мессенджеры и за это время делает больше. При одинаковом стеке технологий второй получает повышение быстрее, потому что стабильно выдает результат.</p><blockquote>Понимания своих триггеров выгорания и умения вовремя установить границы. Специалисты, которые работали на износ и брали все задачи подряд, часто уходили из профессии через полгода. Те, кто умел выстраивать границы, отказываться от неприоритетных задач и распределять нагрузку, строили долгосрочную карьеру.</blockquote><p><b>Как развивать:</b> отслеживайте время, которое тратите на разные типы задач, анализируйте, в какое время дня вы наиболее продуктивны, и планируйте сложные задачи на эти часы. Учитесь отказываться от задач, которые не влияют на ключевые метрики проекта.</p><h2>Специализация: что нужно знать по направлениям</h2><p>Универсальные навыки — это фундамент, но на рынке труда оценивают конкретные компетенции. Требования различаются в зависимости от направления, но общая тенденция одна: работодатели ждут не просто знания инструментов, а понимания, как эти инструменты решают бизнес-задачи.</p><h3>Программист</h3><p>В 2026 году от разработчиков по умолчанию ждут уверенной работы с вебом, API, инструментами разработки и базовой архитектурой. Вот что стало обязательным минимумом для позиции Junior:</p><ul><li>Базовое программирование: переменные, циклы, функции, основы объектно-ориентированного программирования, уверенное владение хотя бы одним языком — Python, JavaScript, Java или C#. Плюсом идут TypeScript, Go или Kotlin.</li><li>Веб и API: понимание протокола HTTP, работа с REST и JSON, базовые знания GraphQL, HTML и CSS для понимания фронтенда, SQL и основы NoSQL-баз данных. Тренд 2026 года — реактивные API и стриминг-данные в реальном времени.</li><li>Инструменты разработки: Git для контроля версий, базовое понимание CI/CD, умение работать с Docker для контейнеризации приложений, навыки деплоя в облако хотя бы на базовом уровне.</li><li>Алгоритмы и структуры данных: работа с массивами, списками, хэш-таблицами, понимание основных алгоритмов сортировки и поиска, базовое представление о сложности алгоритмов (нотация Big O).</li></ul><p>Многое зависит от направления. Во фронтенде нужны JavaScript или TypeScript и React, в бэкенде — Python, Java или Go. Важный момент: импортозамещение делает обязательным опыт работы с отечественными платформами. В вакансиях на позицию Junior Backend Developer все чаще встречается требование знания Yandex Cloud или VK Cloud — это уже не плюс в резюме, а базовое ожидание.</p><blockquote>Часто встречаю резюме, где перечислены десять языков программирования, но кандидат не может объяснить базовые принципы работы. Работодатели проверяют не количество технологий в резюме, а глубину понимания. Лучше знать один стек хорошо, чем пять поверхностно.</blockquote><p>Для тех, кто выбирает разработку как основное направление, важна структурированная база. Программы по программированию в Академии ТОП дают практический стек под востребованные языки — от <a href="http://top-academy.ru/education/python">Python</a> до <a href="http://top-academy.ru/education/java-development">Java</a> — с проектами в портфолио и помощью в трудоустройстве.</p><h3>Дизайнер</h3><p>Среди множества направлений дизайна — графического, UX/UI, 2D, 3D, motion, интерьерного — веб остается одним из самых востребованных. В 2026 году от веб-дизайнера ждут базовых умений работать с Figma, понимания технологий, данных и того, как меняется пользовательский опыт.</p><ul><li>Работа с ИИ: умение ставить задачи моделям и оценивать результат. ИИ не заменяет дизайнера, но специалист, который не умеет его использовать, проигрывает в скорости.</li><li>Адаптивный дизайн: проектирование интерфейсов под разные устройства и разрешения экрана, понимание сеток и основ HTML/CSS.</li><li>Знание UX/UI: построение удобных пользовательских сценариев, навигации, проведение базового юзабилити-тестирования.</li><li>Базовое понимание кода: не обязательно писать код самостоятельно, но понимать, как работают HTML, CSS и JavaScript, чтобы грамотно общаться с разработчиками и не предлагать решения, которые невозможно реализовать.</li><li>Интерактив и анимация: применение CSS/SVG-анимаций и простых эффектов для повышения вовлеченности пользователей.</li><li>Системное мышление: понимание связи данных, логики и поведения пользователя.</li></ul><blockquote>Дизайнеры, которые понимают, как работает код, получают офферы на 30-40% выше рынка. Они говорят с разработчиками на одном языке и экономят недели на правках.</blockquote><p>Освоить веб-дизайн с учетом требований 2026 года можно на практических программах — <a href="http://top-academy.ru/education/web-design">курс по веб-дизайну в Академии ТОП </a>обновляется под актуальные требования рынка и включает работу с адаптивностью, основами кода и UX/UI-проектированием.</p><h2>Маркетолог</h2><p>Маркетолог в IT — это связующее звено между продуктом, аудиторией и цифрами. В 2026 году нужно понимать, что стоит за данными, как работает автоматизация и где ИИ действительно помогает.</p><ul><li>Аналитика и данные: умение читать цифры (конверсии, retention, LTV), сегментировать аудиторию по поведению, работать с инструментами аналитики.</li><li>Креатив: генерировать идеи и использовать новые форматы.</li><li>Автоматизация и CRM: настройка email-цепочек, триггерных сообщений, персонализации контента в зависимости от действий пользователя.</li><li>Понимание целевой аудитории: изучение поведения пользователей, построение customer journey map, создание точных предложений на основе данных.</li><li>Личный бренд: активность в digital-среде и профессиональных сообществах.</li><li>Работа с ИИ: умение ставить задачи моделям для генерации контента и проверять результаты на фактические ошибки.</li><li>Системное мышление: понимание того, как маркетинговые решения влияют на продукт, продажи и техподдержку.</li></ul><p>Специалист должен быть с аналитическим мышлением, который сначала проверяет, куда ведет ссылка, насколько релевантно предложение сегменту аудитории и нет ли технических проблем на посадочной странице. Без этого подхода бюджет уходит на A/B-тесты, которые не дают результата.</p><p>Для системного понимания digital-маркетинга существуют программы, которые учат работать с данными, автоматизацией и ИИ — курсы по<a href="http://top-academy.ru/education/adults/marketing"> маркетингу в Академии ТОП </a>помогают собрать портфолио под реальные задачи и освоить современные инструменты аналитики.</p><h2>Системное мышление и программирование: навык-усилитель</h2><p>Программирование никуда не исчезло — оно стало глубокой специализацией. Навык критически важен для аналитиков, дата-сайентистов, продуктологов, digital-маркетологов и специалистов по автоматизации. World Economic Forum не включает его в топ-10 универсальных навыков, потому что это компетенция для конкретных ролей, но именно она дает значительное преимущество.</p><h3>Почему программирование важно в 2026 году</h3><ol><li>Основа для работы с ИИ и данными. Продвинутые промты для GPT напоминают программирование. Чтобы интегрировать модель в продукт или дообучить ее, нужно знание языков — например, Python. Дата-аналитик, который умеет писать SQL-запросы и Python-скрипты, обрабатывает данные значительно быстрее того, кто работает только в Excel.</li><li>Прямое воздействие на бизнес-метрики. Написание скрипта для автоматизации еженедельного отчета экономит восемь человеко-часов в неделю. Создание простого чат-бота на Python снижает нагрузку на службу поддержки на 30%.</li><li>Язык создания цифровых продуктов. Понимание того, как работают бэкенд и фронтенд, позволяет менеджерам, маркетологам и продуктологам ставить технически грамотные задачи и говорить на одном языке с разработчиками.</li><li>Страховка от поверхностной автоматизации. No-Code инструменты хорошо решают типовые задачи. Но когда нужна кастомизация, сложная логика или интеграция несовместимых систем, без кода не обойтись. Специалист, который знает код, решает задачи, недоступные другим.</li></ol><p>Программирование в 2026 году — это не про то, чтобы стать разработчиком мирового уровня. Это про системное мышление, возможность создавать решения и глубоко влиять на цифровую среду. Это навык для тех, кто хочет не просто адаптироваться к изменениям, а активно влиять на них.</p><h3>Частые вопросы</h3><h4>Можно ли войти в IT без технического образования?</h4><p>Да. Многие направления доступны новичкам без знания математики. Важнее базовая цифровая грамотность, аналитическое мышление и умение работать с ИИ даже на пользовательском уровне.</p><h4>Какие навыки прокачивать в первую очередь?</h4><p>Базовую цифровую грамотность, аналитическое мышление и умение работать с ИИ. Эти компетенции универсальны и применимы в любом направлении IT.</p><h4>Насколько важен английский в 2026 году?</h4><p>На старте достаточно уровня B1 для чтения документации и работы с инструментами. Для международных команд потребуется B2 и выше.</p><h4>Станут ли ИИ-инструменты угрозой для специалистов?</h4><p>Нейросети автоматизируют рутину и становятся помощниками, а не конкурентами. Специалисты, которые умеют работать с ИИ как с инструментом, получают преимущество перед теми, кто их игнорирует.</p><p>В 2026 году на рынке нужны специалисты, которые понимают IT шире своей роли и умеют сочетать технические компетенции с софт-скиллами. Сфокусируйтесь на универсальных навыках для фундамента, выберите специализацию под конкретное направление и при желании углубиться в технологии — добавьте программирование как навык-усилитель. Ваша карьера в IT зависит от того, насколько правильно вы подходите к обучению сегодня.</p><p><i>Реклама. Рекламодатель АНО ДПО «Академия Топ», ИНН 7730257499, erid: 2W5zFJ5yya8</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Инженер реализовал завирусившийся XKCD-комикс про зависимости ПО</title>
      <link>https://tproger.ru/news/inzhener-realizoval-zavirusivwijsya-xkcd-komiks-pro-zavisimosti-po</link>
      <comments>https://tproger.ru/news/inzhener-realizoval-zavirusivwijsya-xkcd-komiks-pro-zavisimosti-po?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/inzhener-realizoval-zavirusivwijsya-xkcd-komiks-pro-zavisimosti-po</guid>
      <description><![CDATA[<p>Инженер создал Stacktower — интерактивную версию культового XKCD-комикса, показывающую, как одна зависимость может «обрушить» все приложение</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/inzhener-realizoval-zavirusivwijsya-xkcd-komiks-pro-zavisimosti-po">Инженер реализовал завирусившийся XKCD-комикс про зависимости ПО</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 05 Dec 2025 09:04:53 GMT</pubDate>
      <content:encoded><![CDATA[<p>Веб-инженер <i>Маттиас Хюэль</i> <a href="https://stacktower.io/">создал</a> <b>интерактивную версию культового комикса XKCD №2347</b>, в котором автор высмеивает хрупкость современного ПО.</p><p>Это тот самый рисунок, который в последние месяцы превратился в популярный мем: огромные цифровые системы стоят на одном крошечном модуле, поддерживаемом энтузиастом из Небраски.</p><p>Но теперь эта «шутка» стала наглядной — <b>проект Stacktower превращает рисунок в настоящую визуализацию зависимостей</b>.</p><p>На заглавной схеме, полностью повторяющей комикс, можно нажать на любой блок — и увидеть реальные пакеты, библиотеки и цепочки зависимостей.</p><p>Проект динамически строит дерево зависимостей, позволяя проследить, как небольшие модули опираются на еще меньшее количество фундаментальных компонентов.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-12-05/1b29d25e-fccc-45ef-ade8-a7c35ad092ba.jpeg" alt="" /></figure><h2>Как работает Stacktower</h2><p>Сайт предлагает две модели: <i>«стабильную башню»</i> и <i>«неустойчивую башню»</i>, где уровни подстраиваются под выбранные библиотеки.</p><p>Пользователь может загрузить зависимости своих приложений — например, на <b>Python</b> или <b>JavaScript</b> — и увидеть, что будет, если убрать даже один элемент.</p><p>На странице приводится пример для <b>Node.js</b>:</p><p>приложение зависит от Express → Express зависит от body-parser → body-parser зависит от qs → и так далее</p><p>Stacktower иллюстрирует, что даже простое приложение тянет десятки модулей, часто неподконтрольных разработчику.</p><p>Есть и <b>Python-вариант</b>:</p><p>импорт Flask тянет Werkzeug, Jinja2, MarkupSafe, Click и еще несколько пакетов. А те, в свою очередь, имеют собственные зависимости.</p><h2>Зачем это нужно</h2><p>Автор подчеркивает: <b>цель проекта — не критиковать экосистемы, а показать их реальное устройство</b>.</p><p>Стек современных приложений неизбежно сложен и даже крошечный модуль может стать критически важным. Именно так в 2022 году случайное удаление библиотеки left-pad временно «сломало» огромный кусок JavaScript-мира.</p><p>Stacktower превращает эту абстрактную проблему в понятный визуальный эффект: убираешь одну зависимость — рушится вся конструкция.</p><h2>Комьюнити уже подхватило идею</h2><p>Проект быстро разошелся по Reddit, Hacker News и X: разработчики делятся скриншотами своих «башен», спорят о хрупкости экосистем и обсуждают, стоит ли пересматривать подход к зависимости.</p><p>Кто-то предлагает добавить поддержку Rust и Go, другие мечтают о корпоративной версии инструмента для визуального аудита безопасности.</p><p>Изучить проект подробнее можно на его <a href="https://github.com/matzehuels/stacktower">странице</a> на GitHub.</p>]]></content:encoded>
    </item>
    <item>
      <title>Разработчик из Apple раскритиковал «Чистый код 2» — много слов, мало практической пользы</title>
      <link>https://tproger.ru/news/razrabotchik-iz-apple-raskritikoval--chistyj-kod-2----mnogo-slov--malo-prakticheskoj-polzy</link>
      <comments>https://tproger.ru/news/razrabotchik-iz-apple-raskritikoval--chistyj-kod-2----mnogo-slov--malo-prakticheskoj-polzy?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/razrabotchik-iz-apple-raskritikoval--chistyj-kod-2----mnogo-slov--malo-prakticheskoj-polzy</guid>
      <description><![CDATA[<p>Инженер Apple раскритиковал Clean Code 2 за многословие и устаревшие практики: книга стала толще, но не полезнее для современных разработчиков</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/razrabotchik-iz-apple-raskritikoval--chistyj-kod-2----mnogo-slov--malo-prakticheskoj-polzy">Разработчик из Apple раскритиковал «Чистый код 2» — много слов, мало практической пользы</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 03 Dec 2025 04:22:22 GMT</pubDate>
      <content:encoded><![CDATA[<p>Вышедшее в октябре <b>второе издание «Чистого кода»</b> вызвало бурную реакцию разработчиков.</p><p>Одна из самых <b>жестких рецензий</b> <a href="https://bugzmanov.github.io/cleancode-critique/clean_code_second_edition_review.html">пришла</a> от инженера Apple — <b>Рафаэля Багманова</b>. Он заявил, что книга стала «толще, но не умнее». Больше отвлеченных рассуждений, повторов и риторики, а вот <b>практической пользы — меньше</b>.</p><p>По его словам, обновленная версия ощущается как смесь Clean Code, Clean Coder, Clean Architecture и блог-постов Роберта Мартина, но без прежней фокусировки.</p><p>При этом сам <b>стиль написания кода почти не изменился</b>, а многие проблемы первого издания <b>перекочевали в новое без правок</b>.</p><h2>«Чрезмерные мини-функции» и странные абстракции</h2><p>Главная претензия Багманова — <b>навязчивый стиль Tiny Functions</b>: функции с одним параметром, длинные имена, множество маленьких методов, вызванных ради избежания комментариев.</p><p>Автор критики приводит пример разбора римских чисел: в книге Мартин <b>превращает простую задачу в набор связанных методов и полей класса</b>. Это усложняет код, а не делает его чище.</p><p>Он отдельно подчеркнул, что такой стиль легко узнаваем, но это <b>не комплимент</b>. В примерах «Чистого кода» <b>создается избыточная структура</b>, которую сложнее читать, тестировать и поддерживать.</p><h2>Слабая работа с производительностью и моделированием</h2><p>Рафаэль Багманов также отметил, что Мартин игнорирует ключевые аспекты разработки:</p><ul><li><b>производительность</b> падает из-за десятков мелких методов и постоянных аллокаций;</li><li><b>тесты замедляются</b> из-за передачи данных через поля объекта;</li><li><b>моделирование домена</b> уступает место механическому применению SOLID.</li></ul><p>Особенно досталось примеру с системой аренды помещений: попытка заменить switch на полиморфизм приводит к интерфейсу, который смешивает цену, налоги и скидки в одной сущности:</p><p>В реальных системах <b>так не работает</b> — налоговые правила зависят от региона, периода и категории товара, а не от «класса предмета».</p><h2>Комментарии: редкие хорошие примеры и странная позиция</h2><p>Несмотря на то, что Мартин снова заявляет, что комментарии — «признак провала», книга почти не показывает хороших примеров того, как писать нужные комментарии.</p><p>Инженер Apple подчеркивает: <b>в реальном мире комментарии — не зло, а инструмент</b>. И хорошую мысль проще объяснить текстом, чем ломать архитектуру ради самодокументируемости.</p><h2>Итог: книга стала объемнее, но не глубже</h2><p>В итоге Багманов пришел к выводу, что второе издание «Чистого кода» <b>скорее разочаровывает</b>. Оно наследует стиль, который не подходит современным языкам и практикам, усиливает слабые стороны первого издания и добавляет многословие без реальных улучшений.</p><p>Для инженеров, которые ищут современные советы по дизайну, сопровождению и архитектуре, книга в 2025 году выглядит устаревшей. <b>Но что хуже всего, вводящей новичков в заблуждение</b>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Математика или программирование? Какие знания нужны ML‑специалисту</title>
      <link>https://tproger.ru/articles/matematik-ili-programmist--chto-nuzhno-znat-ml-specialistu</link>
      <comments>https://tproger.ru/articles/matematik-ili-programmist--chto-nuzhno-znat-ml-specialistu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Валерия Турчак]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/matematik-ili-programmist--chto-nuzhno-znat-ml-specialistu</guid>
      <description><![CDATA[<p>Интервью про ML: бустинг против нейросетей, работа с LLM, валидация и культура кода в команде</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/matematik-ili-programmist--chto-nuzhno-znat-ml-specialistu">Математика или программирование? Какие знания нужны ML‑специалисту</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Многопоточность]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Машинное обучение]]></category>
      <category><![CDATA[Советы]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Инфраструктура]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 12 Nov 2025 14:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p><i>Для Tproger поговорили с Александром Сербулом, руководителем ML‑направления в Битрикс24. Он рассказал, как не застрять на старте и почему в ML инженерная культура важнее модных нейросетей. Внутри — о том, когда градиентный бустинг лучше LLM, почему код нужно покрывать тестами, как работать с нехваткой данных и на что смотреть при выборе команды.</i></p><p>Если вы пишете код и начинаете разбираться с большими данными, здесь много идей, которые можно применить прямо сейчас.</p><p>Главный месседж — зрелый ML‑инженер это не коллекционер нейронок, а разработчик, умеющий проверять гипотезы, валидировать результаты и писать поддерживаемый код.</p><h2>Кем должен быть ML‑специалист — математиком или программистом</h2><p>Без математики в ML далеко не уйдёшь, но и без хорошего кода модели не взлетят. Ошибка в формуле или пробел в логике тестов может стоить недели отладки. Поэтому подход должен быть инженерным: писать чисто, добавлять аннотации типов, покрывать код тестами, следить за читаемостью.</p><h2>Сколько математики нужно в ML</h2><p>Без линейной алгебры, матриц, теории вероятностей и дифференцирования не получится даже понимать, что именно делает модель. Эти базовые знания можно освоить за полгода‑год, но важно не просто формулы выучить, а развить интуицию.</p><p>Инженеру нужно чувствовать, как данные проходят через слои сети, что происходит с тензорами и почему параметры меняются именно так. Это не про сложную теорию — скорее про понимание механики. Когда видишь матрицы не как набор чисел, а как систему преобразований, всё становится проще, и дебаг модели перестаёт быть сложной задачей.</p><h2>Как развиваться в ML и не застрять на старте</h2><p>По мнению Александра, главный способ расти в машинном обучении — постоянно разбирать чужие работы. Читать статьи, пробовать воспроизводить их, собирать сети, смотреть, как устроены архитектуры. Не стоит относиться к программированию как к самоцели. Код — инструмент, но смысл в том, чтобы понимать, что делает модель внутри.</p><blockquote>У многих разработчиков подход поверхностный: берут готовое решение, подают данные и ждут результата, но так не появляется понимания.</blockquote><p>Развитие начинается, когда ты сам задаёшь вопросы вроде «почему слой ведёт себя так», «как меняются веса», «что даёт нормализация». Именно через эти вопросы начинается путь к инженеру, а не к пользователю фреймворков и вайбкодингу.</p><h2>Что с большими языковыми моделями</h2><p>Хайп вокруг больших языковых моделей уже выдохся: корпорации гонятся за размерами, а остальные используют их как библиотеку. Это не плохо — эмбеддинги и промты действительно решают прикладные задачи, от резюмирования встреч до автозаполнения CRM.</p><p>Но инженеру важно понимать, что промт не заменяет модель, это просто способ задать контекст, как преднастройка перед задачей. За ней всё тот же набор весов и вероятностных расчётов. Ошибка — считать промты заменой инженерной работы.</p><p>LLM полезны там, где есть конкретный сценарий и метрики: если видно, что саммари экономит время менеджера или классификатор улучшает отклик в CRM, тогда инструмент оправдан.</p><blockquote>В остальных случаях стоит смотреть на ресурсы и задавать вопрос — нужна ли тяжёлая модель, если задачу решает бустинг или простая логистическая регрессия.</blockquote><h2>Какие методы сейчас реально работают</h2><p>По данным Александра, для бизнес‑задач нет универсального решения, но есть набор проверенных инструментов. <b>Если данные категориальные — лучше использовать градиентный бустинг</b>, например CatBoost или XGBoost. Эти методы часто точнее нейросетей и требуют меньше подгонки.</p><p>Хороший результат даёт <b>комбинация моделей.</b> Например, можно взять LLM для генерации эмбеддингов, а дальше подать их в логистическую регрессию или тот же бустинг. Такой гибрид работает быстрее и требует меньше ресурсов, но при этом сохраняет качество.</p><p>Если данных мало или вычислительных мощностей не хватает, помогает <b>байесовский подход.</b> Он хорошо ведёт себя на шумных и несбалансированных выборках, где другие методы не подходят или не работают. Отдельное направление — <b>оптимизация моделей.</b> Уменьшение моделей через compression позволяет запускать их на обычных серверах без потери точности — актуально для компаний без GPU‑кластеров.</p><h2>Когда ML действительно нужен</h2><p>Не любую задачу стоит решать через машинное обучение. Александр объясняет: если алгоритм можно описать правилами, лучше начинать с классики. Но когда формулы не работают — например, при обработке изображений или машинном переводе — подходит ML. Главное, чтобы были данные: сотни или тысячи пар примеров «правильно» и «неправильно». Без них обучение просто не из чего строить.</p><p>Если данных мало, лучше брать байесовские методы или простые классификаторы — они устойчивее и не требуют много ресурсов. То же самое касается бизнес‑кейсов, где результат критичен, а точность нужно проверять.</p><blockquote>Решение в пользу ML — это не вопрос нового стека, а вопрос наличия данных и понимания задачи. Если подход классических алгоритмов решает проблему быстрее и дешевле, значит, выбираем его.</blockquote><h2>Что делать, если данных мало</h2><p>Недостаток данных — это нормальное состояние, полных и сбалансированных выборок почти не бывает. Поэтому разработчику приходится проявлять креатив. Один из способов — генерировать синтетические данные. Например, создавать дополнительные примеры с небольшими изменениями, чтобы модель видела больше разнообразия.</p><blockquote>Полезно искать и дополнительные источники сигналов. Если пользователь бросил корзину в интернет‑магазине, это может быть прокси‑признак будущей покупки. Такие косвенные данные часто помогают вытащить модель на нужный уровень точности.</blockquote><h2>Где ML приносит реальную пользу бизнесу</h2><p>Александр приводит примеры из практики Bitrix24. <b>Один из самых ощутимых по эффекту — скоринг лидов и сделок.</b> Там используется логистическая регрессия и градиентный бустинг. Метод простой, но позволяет заметно повысить точность прогнозов и напрямую влияет на выручку.</p><p><b>Вторая история — классификация запросов техподдержки.</b> Решение построено на основе алгоритма шинглов и простой модели, оно работает стабильно и подходит для разных языков.</p><p>Алгоритм шинглов — это простой способ представить текст для последующей обработки или сравнения без участия сложных моделей. <br /><br /><i>Пример: текст "машина" при длине шингла 3 даёт набор шинглов: "маш", "аши", "шин", "ина". <br /></i><br />Дальше можно сравнивать эти множества и вычислять похожесть, например через коэффициент Жаккара. <br /></p><p>В Bitrix24 метод шинглов помогает системе одинаково понимать обращения пользователей на разных языках или с разными формулировками.</p><h2>Как проверить, что модель действительно работает</h2><p>Без тестирования и валидации никакая модель не считается готовой. <b>Первое, с чего нужно начинать, — сравнение с базовой линией.</b> Самый простой пример — случайный классификатор. Если ваша модель даёт результат не лучше рандома, значит, смысла в ней нет.</p><p><b>Дальше важно понимать метрики: precision, recall, F1 и другие.</b> Они показывают, на сколько точно модель попадает в нужные ответы и сколько ложных срабатываний допускает. Не стоит воспринимать метрики как формальности — от них зависит, будет ли решение полезно для бизнеса.</p><p><b>Ещё один критерий — устойчивость модели. </b>Александр советует проверять, насколько решение лучше простых эвристик, которые уже используются в компании.</p><blockquote>Если ML‑модель не выигрывает по скорости или точности, её не стоит внедрять. Тестировать нужно на реальных данных и регулярно пересматривать результаты, особенно если бизнес‑процессы меняются.</blockquote><h2>Какие инструменты и ресурсы использовать</h2><p>Основная экосистема машинного обучения сегодня крутится вокруг Python, и начинать логично с него. Хороший старт — <a href="https://realpython.com/">realpython.com</a>, где подробно объясняются основы языка и приёмы написания читаемого кода.</p><p>Но нужно развивать инженерные привычки. Александр рекомендует читать книги вроде <b>Effective Java Джошуа Блоха</b>, чтобы прокачивать культуру разработки и понимать многопоточность. Даже если вы работаете с Python, знания из других языков помогают писать лучше и думать о производительности.</p><p>Из библиотек стоит освоить <b>PyTorch или TensorFlow</b> для нейросетей и <b>scikit‑learn для классического ML</b>. При росте нагрузки полезно переписывать критичные части на <b>Java или Rust</b> — это уменьшает задержки и делает систему устойчивее.</p><h2>Как набраться практики и выбрать правильную команду</h2><p>Лучший способ вырасти в ML — попасть туда, где есть реальные данные и сильная инженерная культура.</p><blockquote>Идите в крупные компании вроде Яндекса, ВК, Сбера или X5 — там есть инфраструктура, процессы и опытные коллеги. Просто читать статьи и собирать pet‑проекты недостаточно, если не сталкиваешься с настоящими продуктами и их ограничениями.</blockquote><p><b>Главный признак хорошей команды — наличие тестов, QA и понятного кода.</b> Если в отделе этого нет, нужно уходить, иначе быстро потеряешь профессиональный уровень. ML уже давно не чудо‑технология, а инструмент. И успех зависит не от того, кто первым применил нейросеть, а от того, чья команда умеет держать систему в рабочем состоянии и проверять результаты каждый день.</p><p>В конце хочется спросить: как вы сами учились или учитесь ML — через курсы, проекты или книги? Делитесь своим опытом и мыслями в комментариях — обсудим, какие подходы к обучению и работе в ML работают сегодня.</p>]]></content:encoded>
    </item>
    <item>
      <title>Хобби айтишников — Андрей Фёдоров о паркуре, DnD и жизни в Люксембурге</title>
      <link>https://tproger.ru/articles/hobbi-ajtiwnikov---andrej-fyodorov-o-parkure--d-amp-d-i-zhizni-v-lyuksemburge</link>
      <comments>https://tproger.ru/articles/hobbi-ajtiwnikov---andrej-fyodorov-o-parkure--d-amp-d-i-zhizni-v-lyuksemburge?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/hobbi-ajtiwnikov---andrej-fyodorov-o-parkure--d-amp-d-i-zhizni-v-lyuksemburge</guid>
      <description><![CDATA[<p>Java-разработчик Андрей Фёдоров рассказывает, как паркур вылечил спину, D&amp;D подарил друзей разных возрастов, а кулинария стала творческим экспериментом. Почему хобби — ключ к балансу в IT, как переезд вдохновил на новые увлечения и почему в маленьком королевстве так легко социализироваться через спорт и настолки.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/hobbi-ajtiwnikov---andrej-fyodorov-o-parkure--d-amp-d-i-zhizni-v-lyuksemburge">Хобби айтишников — Андрей Фёдоров о паркуре, DnD и жизни в Люксембурге</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Музыка]]></category>
      <category><![CDATA[Хобби]]></category>
      <category><![CDATA[Английский]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 04 Nov 2025 12:00:02 GMT</pubDate>
      <content:encoded><![CDATA[<p>В новом выпуске <a href="https://vk.com/video-30666517_456246812">подкаста</a> Tproger Маша Даровская беседует с Андреем Фёдоровым — Java-разработчиком из Люксембурга. Узнайте, как переезд в маленькое королевство открыл двери в мир паркура, D&amp;D, настольных игр и кулинарии. Андрей делится, почему хобби стали спасением от выгорания, как организовать оффлайн- и онлайн-сообщества для ролевых игр и почему в Люксембурге так легко найти баланс между работой, спортом и творчеством. Погрузитесь в историю о том, как разнообразие увлечений помогает не только спине, но и душе!</p><p><b>Маша Даровская</b>: Это Маша, шеф-редактор Тпрогера. Сегодня у нас очередной выпуск подкаста про хобби айтишников. Будем узнавать, как не выгорать и какими хобби можно наслаждаться в свободное от работы время. Сегодня у нас в гостях Андрей Фёдоров из Люксембурга. Он Java-разработчик и расскажет о своих многочисленных увлечениях. Паркур, DnD, а ещё фотография, кулинария. В общем, Андрей, расскажи немного о себе. Как ты оказался в Люксембурге? Как отдыхаешь там?</p><p><b>Андрей Фёдоров:</b> Ну, всё довольно просто: я оказался в Люксембурге, потому что эмигрировал сюда в 2022 году по работе. В этом смысле мне повезло — на тот момент у меня был совсем небольшой стаж, я отработал всего около года, но меня пригласили сюда, в местную компанию, и полностью перевезли. В этом смысле мне очень повезло, я благодарен судьбе. Сейчас работаю здесь уже три года. И, кстати, именно здесь у меня появились почти все хобби — как ответ на те проблемы, с которыми столкнулся на работе.</p><h2>Жизнь в Люксембурге: погода, камерность и инфраструктура</h2><p><b>Маша Даровская: </b>Расскажи, пожалуйста, как тебе вообще в Люксембурге? Как тебе там всё?</p><p><b>Андрей Фёдоров:</b> Здесь всё классно. Единственное — погода вне лета бывает слишком дождливой. Зимы, как мы привыкли в России, здесь нет. Осень очень длинная: начинается где-то в октябре-ноябре и заканчивается только в марте. В это время температура редко опускается ниже минус трёх-пяти градусов, в основном держится около нуля. Дожди идут практически каждый день, либо просто пасмурно. Очень не хватает солнца.</p><p><b>Маша Даровская: </b>Понимаю. В принципе, во многих местах бывает такая дождливая погода. А скажи, пожалуйста, Люксембург — это ведь довольно маленькое королевство. Как тебе его камерность?</p><p><b>Андрей Фёдоров</b>: Это очень здорово. Здесь гораздо спокойнее, чем в Москве, где я жил раньше. Я сам родом из Астрахани, и Люксембург напоминает мне лучшее от обоих этих мест. Здесь очень высокий уровень инфраструктуры, есть общественный транспорт. Кстати, Люксембург — единственная страна в мире, кажется, где общественный транспорт полностью бесплатный и для туристов, и для местных жителей. Все поезда, автобусы и трамваи здесь бесплатные. И, действительно, очень спокойно. Многие говорят, что здесь скучно, особенно те, кто любит ходить на дискотеки или в клубы — такие люди отмечают, что мало движения. Но мне это не близко, я ещё в подростковом возрасте понял, что такие развлечения не для меня, поэтому мне здесь хорошо.</p><p>Значительная часть территории страны покрыта лесами и полями, поэтому для хайкинга тут отличные условия. Например, я живу не в самом городе, не в столице, но буквально в двух минутах от городской границы. До центра города мне примерно двадцать минут: пять минут пешком, потом десять-пятнадцать минут на трамвае, и ещё пять минут пешком. При этом от моей квартиры до большого леса — всего около десяти минут пешком.</p><h2>Социализация и языки в Люксембурге</h2><p><b>Маша Даровская:</b> Скажи, пожалуйста, а в Люксембурге тебе хватает общения? Насколько ты смог социализироваться? Как у тебя с коммуникацией, с языком?</p><p><b>Андрей Фёдоров</b>: С каждым годом становится всё лучше. Общение можно разделить на несколько категорий. Во-первых, это русскоязычное общение внутри диаспоры. В первый год после переезда было довольно сложно, потому что не было ни сил, ни особого желания куда-то ходить, искать новых знакомых. Я начал этим заниматься только на втором году и обнаружил, что у нас уже сформировалось сообщество по «Что? Где? Когда?». Я несколько раз там сыграл. Сейчас уже не играю, но иногда выступаю в роли ведущего — читаю вопросы. Я не организатор, а именно ведущий. Это мне близко, потому что в школьные годы я играл в ЧГК около пяти-шести лет.</p><p>Потом я узнал, что здесь есть клуб настольных игр, в основном мафии. Я туда ходил, участвовал, общался с людьми, а потом начал сам проводить настольные игры. Именно там познакомился с ребятами, с которыми мы позже начали играть в ДНД офлайн. В плане русскоязычного общения с каждым годом становилось всё лучше, потому что здесь на самом деле довольно много людей. Точных цифр не знаю, но, по моим наблюдениям, в Люксембурге живёт примерно три-пять тысяч русскоязычных. Если говорить о людях, которые входят в мой круг интересов, их всё равно довольно много. К нам иногда приезжают ребята из Трира и других соседних городов за границей Люксембурга. Это что касается русскоязычной части.</p><p>Если смотреть на нерусскоязычную, тут тоже есть своя градация, потому что в Люксембурге говорят как минимум на трёх языках. Даже если не учитывать английский, здесь есть французский, немецкий и, собственно, люксембургский. Каждый язык используется в разных контекстах. Например, молодёжь — им по 18–19 лет, кстати, здесь в школе учатся до 20 — между собой часто говорит на люксембургском. Я хожу на паркур, и большинство ребят, с которыми занимаюсь, — подростки. Они постоянно болтают между собой на люксембургском, и я ничего не понимаю. Пока ещё не начал учить этот язык, только зимой собираюсь приступить.</p><p>Дальше — французский. На нём с тобой будут говорить в магазинах в большинстве случаев, потому что здесь очень много людей приезжают работать из-за рубежа. Каждый день люди из приграничных городов Франции приезжают в Люксембург, чтобы работать кассирами, продавцами и не только. Поэтому в магазинах часто нужен французский. Немецкий, честно говоря, я почти не встречал. Слышал, что его используют в новостях и где-то на севере страны, но я живу на юге, так что с этим сталкиваюсь редко.</p><p>Здесь даже есть своеобразная «игра» — познакомиться с люксембуржцем, потому что это довольно сложно. Но, как мне кажется, основная проблема у людей — в подходе. Вместо того чтобы специально искать люксембуржцев, лучше просто ходить в места по интересам и там знакомиться с людьми естественно. Здесь люди в основном знакомятся в спортивных кружках, потому что здесь очень много разных ассоциаций. Я, например, хожу на паркур, но есть ещё футбольные, баскетбольные, теннисные секции, настольный теннис — вариантов действительно много. Это довольно большое пространство, где люди часто встречаются и общаются.</p><p>Есть ещё языковые кафе, но там в основном встречаются другие мигранты, которые тоже приехали сюда. Здесь вообще очень много иммигрантов, их часто называют экспатами. Буквально почти половина населения страны — это люди, которые сюда приехали, а не те, кто здесь родился и вырос. Точную статистику я не знаю, но, кажется, граждан здесь примерно половина населения. Остальные — это экспаты, и, по-моему, в статистику не входят те, кто приезжает сюда каждый день, но не живёт здесь постоянно. В общем, на неродном языке общаться немного сложнее, у меня эта часть пока ещё проседает.</p><p>Сейчас я участвую в организации айтишных митапов в Люксембурге — они называются Lux Tech Pulse. Раньше это был Luxembourg Jazz, но теперь мероприятие расширилось и охватывает разные направления. Там я постепенно знакомлюсь с людьми, которые говорят не только по-русски. В остальном, возможно, я просто не так часто бываю в местах, где можно познакомиться с новыми людьми. Работу я не беру в счёт — я познакомился со всеми своими тридцатью коллегами, и на этом всё. Но это довольно ограниченный круг знакомств.</p><h2>Работа и команда</h2><p><b>Маша Даровская:</b> А чем, кстати, занимается твоя компания, и на каком языке вы общаетесь в команде?</p><p><b>Андрей Фёдоров</b>: Я бы не назвал это стартапом. Это компания, которой уже около шестнадцати лет, она давно вышла из стадии стартапа — по крайней мере, так говорит наш SEO. Это люксембургская компания, основная часть находится в Люксембурге. Мы занимаемся продуктами для финтеха. Есть несколько решений для аутентификации пользователей, а также продукт, похожий на WhatsApp, только более безопасный: компании могут хранить данные у себя, сами хостят сервер. Я работаю в третьей команде, которая занимается кастомными решениями для клиентов — не внутренними продуктами, а разработкой на заказ для других компаний.</p><p><b>Маша Даровская:</b> Поняла. А на каком языке вы общаетесь? На английском?</p><p><b>Андрей Фёдоров: </b>Да, у нас в компании основным языком общения является английский, и это очень удобно. Мы как-то подсчитывали: на тот момент у нас было около четырнадцати или пятнадцати разных национальностей. Есть ребята из СНГ — украинцы, россияне, парень из Молдовы, есть коллеги из Индии, несколько человек из Люксембурга, из Франции, из Германии, из Латинской Америки тоже были ребята. В общем, команда очень интернациональная. Здорово, что английский стал общим языком — он действительно поддерживает мультикультурную среду.</p><p><b>Маша Даровская:</b> Да, это язык для общения между представителями разных культур.</p><p><b>Андрей Фёдоров:</b> В этом смысле в Люксембурге с английским и другими языками проще. Здесь много людей, для которых эти языки не родные, они их учили. И, по крайней мере, с английским нет такого, что тебя стыдят за неправильное произношение или что-то подобное. Все говорят по-разному и стараются понять друг друга.</p><h2>Паркур: от боли в спине к удовольствию</h2><p><b>Маша Даровская:</b> А расскажи, как у тебя появились хобби в Люксембурге? Ты говорил, что только на второй год начал активно общаться. Почему решил заняться паркуром? Какой у тебя вообще спортивный бэкграунд?</p><p><b>Андрей Фёдоров: </b>Паркуром я занялся потому, что у меня болела спина — это короткий ответ. А если подробнее, то особого спортивного бэкграунда у меня нет. Обычное детство, наверное, как у многих парней, которые выросли не в Москве, а просто где-то в России. Не знаю, как в Москве, а я в детстве бегал по дворам, лазил по крышам гаражей, забирался в подъезды — просто ради интереса, ничего не выносил. Мне это нравилось, и, в общем-то, на этом всё. Когда я приехал сюда, первый год был сложным — все силы уходили на адаптацию, нужно было понять, как здесь вообще жить. То есть, какие здесь вообще правила? Как, например, с документами: куда их нужно относить, где получать, какие базовые вещи нужно настроить, чтобы просто нормально жить.</p><p>Я пробовал ходить в спортзал, бегать на дорожке, ещё что-то, но мне это оказалось очень скучно. Просто потому, что мне не подходят такие повторяющиеся действия, когда ты долго делаешь одно и то же. Я подумал: хорошо, а что мне действительно нравится? Наверное, что-то в игровом формате, где спорт — это не основная цель, а скорее приятный побочный эффект. Я смотрел разные спортивные федерации, которые здесь есть, думал, может, заняться чем-то японским с мячами, но на мой имейл так и не ответили.</p><p>Я продолжил искать и в какой-то момент начал смотреть на YouTube видео о мировых соревнованиях по паркуру. Подумал: «Ммм, классно». На самом деле, это называлось Chazen Tech — что-то вроде догонялок, только с элементами паркура: нужно прыгать через препятствия. Я подумал, что это очень прикольная штука, захотел попробовать, и стал размышлять, чему нужно научиться, чтобы участвовать в таких соревнованиях. Понял, что для начала нужен паркур — хотя бы чтобы не сломать себе шею в процессе.</p><p>Я начал искать паркур-секцию в Люксембурге и нашёл одну, хотя она была довольно далеко от моего дома. Потом перешёл в другую, поближе, и с тех пор продолжаю заниматься. Мне очень нравится паркур, потому что для всех этих прыжков, лазания и прочего задействуется множество разных мышц: и руки, и пресс, и спина, и особенно поясница. А так как я работаю сидя, для меня это важно — поясница должна быть в порядке.</p><p>Занятия проходят очень весело: два часа пролетают незаметно, будто оказываешься внутри компьютерной игры, которая нравилась с детства. Мне всегда нравилась серия Assassin’s Creed, где герои лазают по стенам, бегают по крышам и тайно устраняют злодеев. Я часто представлял себя на их месте — бегаю, прыгаю, преодолеваю препятствия. В зале это особенно классно: есть специальный инвентарь, боксы разной высоты, на которые можно залезать и прыгать, есть маты для безопасного приземления. Первый раз, когда сделал сальто, ощущения были как в игре — не успеваешь даже понять, как делаешь кувырок, всё вокруг на мгновение размывается, голова кружится. Это чем-то напоминает Mirror’s Edge — есть такая игра про паркур, бег по стенам, прыжки туда-сюда. Это очень весело. И, главное, благодаря этому у меня не болит спина. Когда я не занимаюсь, например, вот сейчас летом был перерыв, у меня начинает хрустеть вся спина. Я могу потянуться вправо или влево — и слышу, как будто пузырьки воздуха лопаются. А когда я хожу на паркур, ничего не хрустит, как бы я ни тянулся.</p><p><b>Маша Даровская:</b> Да, я тебя понимаю. У меня тоже сидячая работа, и без спортзала спина просто отказывает. Скажи, пожалуйста, как проходят твои тренировки и сколько это стоит в Люксембурге?</p><p><b>Андрей Фёдоров:</b> Паркур здесь стоит очень дёшево. На самом деле, большинство спортивных секций недорогие, потому что их организуют что-то вроде НКО — Ассоциации Федерации Спорта. Например, за сезон, который длится с сентября по июль, то есть почти весь год, я плачу 100 евро. По люксембургским меркам это совсем немного. Для сравнения, месяц занятий йогой стоит столько же, потому что в Люксембурге у йоги нет ассоциации, и там только индивидуальные занятия. А тренировки по паркуру у нас проходят так: обычно это двухчасовое занятие. Первый час тренировки проходит с тренером: он учит нас определённым движениям. Второй час — свободный, можно взять любой инвентарь, который лежит в зале, расставить его как угодно и тренировать что-то своё.</p><p><b>Маша Даровская:</b> Скажи, а сколько у тебя в среднем тренировок в неделю?</p><p><b>Андрей Фёдоров</b>: Здесь только одна тренировка по паркуру. Пока мне этого достаточно — это всё же лучше, чем ничего. Ну, что есть.</p><h2>Настольные игры и D&amp;D-сообщество</h2><p><b>Маша Даровская</b>: Ты говорил, что сначала участвовал в мафии, не организовывал, а именно участвовал. Я так понимаю, это вообще популярная тема среди мигрантов — играть в мафию, потому что…</p><p><b>Андрей Фёдоров</b>: Да, но мне мафия, честно говоря, не нравится.</p><p><b>Маша Даровская</b>: Я тоже не очень люблю, если честно. А потом ты организовал сообщество для тех, кто играет офлайн в ДНД. Расскажешь подробнее?</p><p><b>Андрей Фёдоров:</b> На самом деле, мы играем офлайн не только в ДНД, а вообще в разные настольные игры. У нас есть большое сообщество, где ребята собираются на мафию, но также устраивают и другие активности: ходят в походы, иногда в театр, сейчас вот книжный клуб появился. Как часть этого сообщества я в какой-то момент начал проводить настольные игры. Даже организовал небольшой фестиваль на 35 человек: собрал кучу разных настолок, некоторые взял у знакомых, чтобы все могли прийти и попробовать что-то новое. Для тех, кто раньше не играл, часто кажется, что настолки — это сложно и непонятно. Ой, когда слышишь, что в какую-то игру нужно играть час или даже два, становится немного страшно. А бывает и все пять часов.</p><p>Вот поэтому я решил: хорошо, приходите все, у нас будет, скажем, около двадцати пяти разных настольных игр. Я и ещё пара ребят всегда рядом, чтобы помочь вам разобраться в любой игре — не придётся сидеть один на один с буклетом и правилами. Всегда будет кто-то вроде консультанта. Это похоже на московские антикафе, которые специализируются на играх: приходишь, у них огромная библиотека настолок и консультанты, которые всё объяснят. Мне хотелось хотя бы на один день создать что-то подобное. В итоге получилось весело и здорово, хотя я, конечно, очень устал.</p><p>До этого у меня ещё был интерес попробовать ДНД — слышал о ней, казалось, что это что-то вау, очень интересно. Но мне было страшно браться за это самому, потому что совершенно непонятно, как всё устроено. Все эти разговоры про ДНД — что играть нужно долго, что есть какие-то огромные книги с правилами… В общем, я просто жил с этой мыслью, пока один парень не написал мне: «Давайте сыграем в ДНД, хочу попробовать себя в роли мастера». До переезда в Люксембург он в основном играл как обычный игрок, а тут решил попробовать быть мастером. Мы собрались, играли почти год одной компанией, и у меня остались очень хорошие впечатления. После этого я подумал: ладно, это здорово, надо втягивать в это больше людей.</p><p>После этого я начал проводить ваншоты — односессионные игры для совсем новичков. Проводил такие игры и для детей, например, для двенадцатилетних, и для взрослых тоже, просто чтобы показать людям, как это устроено. Мне хотелось, чтобы число людей, которые хотят играть в D&amp;D здесь, в Люксембурге, росло. Тогда можно будет делать что-то более интересное. Чем больше игроков и мастеров, тем больше всего интересного мы можем вместе придумать. Это ещё и отличный способ знакомиться с новыми людьми. Например, тот год, когда мы играли в кампанию, по сути, подарил мне новых друзей — людей, с которыми я вряд ли бы познакомился иначе, потому что мы из разных возрастных групп: некоторые ребята на двадцать, а то и на тридцать лет старше меня. У них совсем другие заботы, профессии, и в обычной жизни мы, возможно, даже не пересеклись бы, или это было бы как-то странно и непривычно. А когда вы год за одним столом играете, отыгрываете разных персонажей, попадаете в комичные или даже кроваво-комичные ситуации, вы сближаетесь и начинаете общаться уже как настоящие друзья.</p><p>Мне хотелось чего-то большего. Вот так мы и продолжаем играть, и сейчас у нас стало больше и мастеров, и игроков. Последние несколько месяцев мы с одним товарищем ищем место, где можно было бы организовать что-то вроде стационарного клуба. Сейчас основная проблема в том, что приходится постоянно бегать между квартирами или кафе-офисами, таская с собой весь инвентарь. А его немало: книги с правилами, фигурки и прочее. В сумме это может быть килограммов десять-пятнадцать, особенно если ещё брать ноутбук или планшет для музыки. Но в Люксембурге сложно найти подходящее помещение, чтобы аренда не стоила тысячу-две евро в месяц.</p><p>Параллельно с этим я решил, что хочу попробовать сделать то же самое онлайн. Нашёл программу Foundry VTT — если кому-то интересно. Думаю, в предыдущем выпуске вы уже упоминали об этом, когда говорили про ДНД. Я сохранил тот выпуск, хотел посмотреть, потому что видел там Сашу Бриганова и подумал: интересно, надо послушать, что он рассказывает, а то я его только в Твиттере читаю. В итоге я скинулся с несколькими ребятами, они мне задонатили, и я купил лицензию. Подумал, что не хочу, чтобы каждый мастер сам покупал лицензию на эту программу и разбирался, как всё установить и развернуть.</p><p>Я подумал: почему бы не создать сообщество, общий сервер, где буду я и ещё несколько админов? Мы бы решали все технические вопросы — как установить систему, как перенести её на более дешёвый сервер, как мигрировать и обновлять данные и так далее. А мастерам и игрокам просто предоставили бы возможность собираться и играть. Ведь онлайн-игры — отличный способ вновь связаться с друзьями, которые живут в других городах. Мы с друзьями уже играли в разные случайные мультиплеерные игры с 2022 года, в основном через Discord. Но это бывает непросто, особенно если речь о играх, которые быстро устаревают и теряют интерес. А вот такие игры, где нужно импровизировать и общаться, по сути, не стареют. Благодаря этому я стал снова больше общаться с несколькими старыми друзьями. Один из них даже присоединился ко мне, и теперь мы вместе развиваем это сообщество.</p><p>Сейчас у нас уже около 80 человек в Telegram-канале. Мы запустили проект в апреле, и за это время провели, наверное, около 10–15 игр, точно не помню. Сообщество постепенно растёт, и это очень радует. Я вижу, как люди, которые иначе никогда бы не встретились — потому что живут в разных частях мира, — знакомятся, начинают вместе играть, и это действительно здорово.</p><h2>Любимые настольные игры</h2><p><b>Андрей Фёдоров:</b> Я играю в настольные игры ещё с университета. Мы с соседом и другом по комнате оба увлекались настолками и часто собирались поиграть. Моя любимая игра — «Каркассон». У меня большая коробка с, наверное, десятью разными дополнениями. Мы с женой регулярно играем, несколько раз в месяц, и с друзьями тоже собираемся. В нашей библиотеке есть ещё одна игра — «Страшные сказки». Это простая карточная игра, подходит для двоих и до четырёх человек. Ещё есть игра, которую я люблю с детства, потому что играл в неё с дедушкой. Она называется «Реверси». Это что-то вроде го, только гораздо проще.</p><p>Есть ещё классная старая игра — Scotland Yard. Она до сих пор популярна, в неё играют. Мне нравится, что там асимметричный геймплей: один игрок — шпион, остальные — детективы, которые его ловят. Все знают, кто шпион, но пытаются поймать его в Лондоне. Интересная дедуктивная игра, отлично подходит для любителей детективов. Попробовать просчитать, куда пошёл человек, где он сейчас находится — это интересная задача. Есть ещё две игры, которые я бы выделил. Одна из них называется «Азул». Она отлично подходит для двух-четырёх игроков. Мне особенно нравится её тактильность: там есть такие плиточки, которые нужно доставать из тканевого мешочка. Это просто приятно — держать их в руках, играть с друзьями, просчитывать ходы.</p><p>Другая игра — «Палео». Это кооперативная игра, а таких мне встречалось не так много, где вы играете не друг против друга, а против самой игры. Она как раз хорошо подходит для вечера вдвоём, например, с женой. Вместо соперничества вы действуете вместе. Сюжет такой: у вас есть доисторическое племя, и ваша задача — оставить след в истории, просто выжить и не вымереть. Есть ещё игры, которые мне нравятся, но которых у меня сейчас нет, потому что не удалось их перевезти. Например, «Рут» — тоже асимметричная игра. Или «Битва за Рокуган». Это не самые известные игры, но они действительно интересные.</p><p><b>Маша Даровская</b>: Из кооперативных мне нравится «Таинственный остров», но, по-моему, она только на русском.</p><p><b>Андрей Фёдоров:</b> Не слышал про такую. Есть такая игра — «Эволюция», она была придумана в России. Это, кстати, непросто, потому что мне она тоже очень нравится. Но на английском, насколько я знаю, её вообще нигде не найти. Получается, с друзьями, которые не говорят по-русски, в неё не поиграть.</p><p><b>Маша Даровская:</b> Да, есть игры, которые выпускают исключительно российские издатели. А скажи, как часто ты вообще играешь в настольные или настольно-ролевые игры? Это у тебя пару раз в месяц выходит?</p><p><b>Андрей Фёдоров:</b> Точно сказать сложно. Для меня настолки — это и способ провести время, и возможность пообщаться. В среднем, наверное, играю несколько раз в месяц. Если говорить именно о настольно-ролевых играх, например, D&amp;D, то с тех пор, как я начал заниматься онлайн-сообществом, сам стал играть чуть меньше — времени уходит много на организацию: нужно искать мастеров, игроков, помогать им всё настроить, проверить, что всё работает. Это занимает довольно много времени. Здесь, офлайн, я сейчас веду кампанию как мастер, но летом, честно говоря, это просто мёртвый сезон для многих активностей — все разъезжаются, у всех разные графики. Через две недели у нас наконец будет следующая сессия. Надеюсь, мы хотя бы раз в месяц сможем собираться, потому что у нас уже шутка ходит: самое страшное в D&amp;D — это не боссы и не правила, а попытка состыковать графики пяти или шести взрослых людей.</p><p><b>Маша Даровская: </b>Да, да, да, вот именно это меня и пугает в идее начать играть в D&amp;D — где найти время?</p><p><b>Андрей Фёдоров</b>: Это, кстати, одна из причин, почему я начал проводить игры онлайн. Оффлайн эта проблема стояла особенно остро. Например, у нас в Люксембурге всего, допустим, пятнадцать человек, которые хотят играть. Это буквально две-три, максимум четыре группы, а по факту — одна-две. И все заняты: у кого-то дети, у кого-то командировки, у всех свои дела, и состыковаться очень сложно. В онлайне проще: у тебя гораздо больше людей на выбор, и если нет принципиального требования играть именно с конкретным другом, найти компанию становится легче. Просто размещаешь объявление: такая-то игра, столько-то человек. Собираются пять человек, которые раньше друг друга не знали — и начинают играть. В принципе, это работает, я бы сказал. Дальше всё зависит от запроса. Для игр, ваншотов — это вообще отлично подходит, можно легко находить такие игры. Для компаний, конечно, сложнее. Вы один раз собрались, совпали по дате, а потом, когда наступает следующая сессия, снова возникает вопрос — как состыковаться. Тут уже становятся необходимы всякие сервисы для синхронизации календарей.</p><h2>Кулинария и творчество</h2><p><b>Маша Даровская</b>: Скажи, кроме паркура и игр, ты ещё говорил, что любишь готовить. Это увлечение появилось у тебя в Люксембурге или раньше?</p><p><b>Андрей Фёдоров:</b> Наверное, скорее здесь, в Люксембурге, потому что у меня стало больше времени дома. Когда я жил в Москве, большую часть времени я проводил в общаге, и там было сложно готовить что-то особенное. Помню, как-то летом я готовил шаурму и продавал её другим в общаге. Но это быстро надоело — за несколько дней я полностью вымотался и понял, что прибыль того не стоит. До переезда я не так много готовил. То есть, я любил готовить, но в основном обычные блюда. Например, блины — у нас в семье я блинный мастер. Какие-то мясные блюда — и не больше.</p><p>А здесь, когда мы переехали, у нас появилось гораздо больше возможностей попробовать разные кухни. Для нас это стало настоящим открытием. Не знаю, может, у меня вообще переезд получился не дауншифтинг, а скорее наоборот — если использовать это слово, то скорее upshifting. В общем, уровень жизни повысился: зарплата относительно расходов стала больше, а еда, по моим ощущениям, не сильно дороже. Поэтому мы начали ходить в разные места, пробовать новую еду, и мне захотелось повторять эти блюда дома. Например, мы несколько раз ездили в Грецию, пробовали там разные блюда с бобами, с фетой — это было очень вкусно, и захотелось научиться готовить такое самому.</p><p>Иногда можно просто найти рецепт в интернете, а иногда интересно прийти в кафе, заказать блюдо и, пока ешь, пытаться понять, как его приготовили. В какой-то момент я очень увлёкся приготовлением пиццы. Сейчас, скажем так, немного остыл — не потому что разонравилось, а просто жду, когда перееду в другое место, где будет балкон или терраса. Хочется купить специальную печь для пиццы, которую можно поставить на улице. Сейчас я немного устал делать пиццу в духовке, потому что всегда старался готовить её практически с нуля. Тесто нужно оставить в холодильнике на ночь, чтобы оно как следует подошло — шарики, всё как надо. Это классно, но занимает очень много времени.</p><p>В отпуске, конечно, здорово этим заниматься, но когда появились проекты вроде ДНД-сообщества, плюс я ещё немного помогаю ребятам из русскоязычного IT-сообщества в Люксембурге, времени на такие сайт-проекты стало меньше. Два дня на пиццу у меня уже нет. Хотелось бы, но не получается. Хотя это было очень классно, и у меня до сих пор есть такой пункт в виш-листе. Хочется сделать в пицце как можно больше с нуля. Например, самому поехать на поле, собрать помидоры, чтобы потом приготовить из них настоящий томатный соус, параллельно замесить тесто и так далее. Прямо приготовить пиццу максимально с нуля.</p><p>Я как-то делал багеты в духовке — это тоже было интересно. Получается настоящий багет с хрустящей корочкой, с надрезом. Когда только достаёшь его из духовки, от него идёт пар. Я ещё посыпал его кунжутом. И если это редкий зимний или осенний день, когда солнце пробивается через окно в Люксембурге, оно красиво подсвечивает этот пар.</p><p>Я пробовал вести YouTube-канал, где частично показывал бы сам процесс и просто болтал на разные темы, но быстро понял, что это не для меня. Оказалось, у меня просто не хватает времени и сил, чтобы заниматься монтажом самостоятельно. Я уже забыл, как это делается. Лет десять назад я монтировал видео, когда работал фотографом и параллельно снимал ролики, но сейчас полностью утратил эти навыки. Я понимаю, что тратить несколько часов на съёмку, а потом ещё в четыре раза больше на монтаж — мне этого совсем не хочется. Да, когда становишься взрослым, приходится расставлять приоритеты.</p><p><b>Маша Даровская: </b>А какие-то видео с готовкой у тебя остались?</p><p><b>Андрей Фёдоров:</b> Да, что-то осталось. Буквально три штуки, наверное. Я довольно быстро понял, что всё идёт не так, как мне хотелось бы. При этом, конечно, родители моей жены очень ждут новых видео. Они постоянно спрашивают: «Андрей, когда следующее?» А я им отвечаю: «Блин, не знаю, это слишком сложно и долго». Но у меня вообще с YouTube есть своя история. Лет в четырнадцать я уже делал канал, пытался что-то записывать и выкладывать. Я специально с тех пор ничего не удаляю — для меня это часть своего рода наследия. Просто интересно потом посмотреть, что было тогда, что сейчас, и, надеюсь, порадоваться изменениям.</p><h2>Баланс хобби и советы слушателям</h2><p><b>Андрей Фёдоров</b>: Я для себя это когда-то описал как разные корзинки. Представляю себе такую картину: есть игра, в которую я сам никогда не играл, но знаю — советская электроника, где волк ловит яйца. Он бегает вправо-влево и ловит яйца, чтобы они не разбились. Вот примерно так я ещё в школе представлял себе жизнь: как совокупность разных активностей. Вместо того чтобы стоять на одном месте и собирать всё только там, ты постоянно переключаешься — тут немного, там немного. В итоге жизнь получается сбалансированной по разным направлениям. В какой-то период ты больше занимаешься одним делом, потом берёшь паузу и подтягиваешь другие направления. В результате всё идёт довольно ровно и разнообразно. Это действительно помогает не выгорать, потому что активность постоянно меняется.</p><p>Например, на работе я в основном занимаюсь разработкой — не только на Java, а вообще всем подряд, по сути, full-stack. Иногда приходится заниматься и менеджерскими задачами, когда нужно делать проекты вместе с другими разработчиками. Такое действительно случалось пару раз, и это тоже классно. Но в основном на работе у меня, условно говоря, разработка. Потом, например, в D&amp;D у меня большая часть активности связана именно с сообществом, с его развитием. Нужно постоянно общаться, находить новых людей, разговаривать с ними — и оказалось, что это сложнее, чем я думал. Я был очень удивлён, насколько разные бывают люди — по характерам, по тому, как они реагируют на мои слова. Я понял, что с каждым нужно общаться по-разному.</p><p>Паркур. В принципе, мне очень нравится паркур, потому что он позволяет просто отвлечься. Вместо того чтобы включать абстрактное мышление, ты реагируешь на происходящее вокруг. Хотя и здесь приходится много думать: когда хочешь прыгнуть и зацепиться, где-то на подсознании просчитываешь, с какой силой и под каким углом прыгнуть. Мне очень нравится этот момент, когда нужно держать фокус. Настольные игры мне, наверное, больше всего нравятся именно из-за социализации. Когда играешь, общаешься с людьми и не смотришь в экран. В какой-то момент я осознал, что у меня была проблема: все мои хобби были связаны с одним и тем же экраном. Как бы это ни было здорово — я занимаюсь разными вещами, но моя спина этого не понимает, и глаза тоже. Поэтому, когда я просыпаюсь, у меня болит всё тело и слезятся глаза. Я понял, что нужно искать какие-то оффлайн-активности.</p><p>А музыка помогает — не знаю, позволяет выплеснуть творческий порыв. Не могу сказать, что на работе этого не происходит: там тоже много творчества, когда придумываешь, как реализовать что-то. Особенно мне повезло в том, что у меня есть право голоса — могу спрашивать: «А почему вы этого хотите? А чего конкретно хотите достичь?» Иногда даже предлагать альтернативы. Это тоже своего рода творчество. Но музыка помогает именно выражать эмоции. Кроме того, что я сам иногда играю на гитаре или сочиняю песни, я много просто пою — включаю музыку и пою. Это у меня с детства. И это помогает нормализовать эмоциональное состояние, потому что с некоторыми песнями, которые откликаются, ты выплёскиваешь накопившиеся эмоции, и становится легче.</p><p><b>Маша Даровская: </b>Да, понимаю, тоже люблю петь, хотя пою ужасно, если честно.</p><p><b>Андрей Фёдоров:</b> Не знаю, я слышал, что нет людей без голоса — есть люди с плохим слухом, скорее. На самом деле, основная проблема чаще всего именно в слухе — чтобы понимать, как ты поёшь.</p><p><b>Маша Даровская:</b> А всё остальное — дело техники. Я, например, окончила музыкальную школу, но у меня низкий голос, и всё, что высоко, мне просто не даётся. Таких песен, которые можно петь низко, на самом деле не так много, их мало. Поэтому — как есть. Колыбельную петь научилась, уже хорошо. Скажи, пожалуйста, что бы ты мог пожелать нашим слушателям? Как найти себя, своё увлечение, как не потерять себя в этом безумном мире, когда всё вокруг бывает сложно?</p><p><b>Андрей Фёдоров:</b> Не надо бояться пробовать. Если не попробуешь — точно ничего не произойдёт. А если попробуешь — может быть, получится. Мне кажется, не стоит пытаться что-то кому-то доказывать. Конечно, иногда в жизни приходится что-то доказывать другим, но в хобби главное — получать удовольствие от процесса, от самого себя. Если постоянно со всеми соревноваться, это может сильно усложнить жизнь и добавить много негатива в то, что должно приносить радость.</p><p><b>Маша Даровская: </b>Да, согласна. Главное — пробовать и ждать, что отзовётся внутри, что действительно откликнется. Спасибо тебе большое. Ребята, с нами сегодня был замечательный Андрей Фёдоров. Он рассказал много интересного о своих увлечениях. Ищите свои хобби, своё призвание — то, что действительно приносит вам удовольствие. Не выгорайте. Пусть у всех всё будет хорошо.</p>]]></content:encoded>
    </item>
    <item>
      <title>Apple выпустила Swift SDK для написания Android-приложений — спустя 11 лет после релиза языка</title>
      <link>https://tproger.ru/news/apple-vypustila-swift-sdk-dlya-napisaniya-android-prilozhenij---spustya-11-let-posle-reliza-yazyka</link>
      <comments>https://tproger.ru/news/apple-vypustila-swift-sdk-dlya-napisaniya-android-prilozhenij---spustya-11-let-posle-reliza-yazyka?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/apple-vypustila-swift-sdk-dlya-napisaniya-android-prilozhenij---spustya-11-let-posle-reliza-yazyka</guid>
      <description><![CDATA[<p>Apple выпустила Swift SDK для Android — теперь на Swift можно писать нативные Android-приложения и переносить код между платформами</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/apple-vypustila-swift-sdk-dlya-napisaniya-android-prilozhenij---spustya-11-let-posle-reliza-yazyka">Apple выпустила Swift SDK для написания Android-приложений — спустя 11 лет после релиза языка</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Apple]]></category>
      <category><![CDATA[Windows]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[macOS]]></category>
      <category><![CDATA[Objective-C]]></category>
      <category><![CDATA[Flutter]]></category>
      <category><![CDATA[iPhone]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 27 Oct 2025 04:06:16 GMT</pubDate>
      <content:encoded><![CDATA[<p>Apple неожиданно открыла новую страницу в истории Swift.</p><p>Компания <a href="https://www.swift.org/blog/nightly-swift-sdk-for-android/">представила</a> <b>официальный Swift SDK для Android</b>, позволяющий писать нативные Android-приложения на фирменном языке, изначально созданном для iOS и macOS.</p><h2>От iPhone до Android</h2><p>Swift появился в 2014 году как альтернатива Objective-C — более безопасный, современный и лаконичный язык для экосистемы Apple.</p><p>За 11 лет он вырос из «внутреннего» инструмента в многофункциональную платформу, на которой создают <b>облачные сервисы, десктопные приложения для Windows и даже прошивки для микроконтроллеров</b>.</p><p>Теперь Swift впервые официально выходит за пределы «яблочной экосистемы. Превью-версия SDK для Android доступна уже сегодня — в составе Swift-инсталлятора для Windows или отдельно для macOS и Linux.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-10-27/9d4f131a-7f10-47c1-a75b-3180cfe12892.jpeg" alt="" /></figure><h2>Как это работает</h2><p>Новый SDK — результат многомесячной работы <b>Swift Android Workgroup</b>, открытого сообщества, куда может присоединиться любой разработчик. С его помощью можно:</p><ul><li>собирать <b>нативные Android-приложения</b> на Swift;</li><li><b>переносить существующие Swift-пакеты</b> — более 25% уже совместимы с Android;</li><li><b>интегрировать Swift-код с Java</b> через проект <b>swift-java</b>, автоматически генерирующий безопасные биндинги между языками.</li></ul><p>Apple <a href="https://www.swift.org/documentation/articles/swift-sdk-for-android-getting-started.html">опубликовала</a> подробное руководство <i>«Getting Started»</i> и примеры кода, демонстрирующие полный цикл разработки Android-приложений на Swift.</p><h2>Что это значит для экосистемы</h2><p>Релиз открывает дорогу к кроссплатформенным приложениям без использования Flutter, Kotlin Multiplatform или React Native.</p><p>Теперь компании смогут писать бизнес-логику один раз на Swift и использовать ее и в iOS-, и в Android-версиях.</p><p>Эксперты отмечают, что шаг Apple может <b>снизить барьеры между мобильными экосистемами</b> и ускорить развитие open-source сообщества Swift.</p><h2>Что дальше</h2><p>По словам участников проекта, впереди — создание полноценного Android-Toolchain, улучшение совместимости со средами разработки и официальное внедрение CI-сборок.</p><p>Разработчики уже готовят документ с видением будущего Swift на Android, который определит приоритеты и стратегию развития.</p><p><i>«Swift вырос из языка для iOS в универсальный инструмент для всего программного мира. Теперь он будет жить и в Android-экосистеме»</i>, — говорится в сообщении разработчиков.</p>]]></content:encoded>
    </item>
    <item>
      <title>Экспорт приватных типов в Go: почему это антипаттерн</title>
      <link>https://tproger.ru/articles/eksport-privatnyh-tipov-v-go--pochemu-eto-antipattern</link>
      <comments>https://tproger.ru/articles/eksport-privatnyh-tipov-v-go--pochemu-eto-antipattern?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Даниил]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/eksport-privatnyh-tipov-v-go--pochemu-eto-antipattern</guid>
      <description><![CDATA[<p>азбираем антипаттерн, его последствия для инкапсуляции и архитектуры, а также показываем идиоматичные способы инициализации структур и сервисов в Go.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/eksport-privatnyh-tipov-v-go--pochemu-eto-antipattern">Экспорт приватных типов в Go: почему это антипаттерн</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Динамическая типизация]]></category>
      <category><![CDATA[Golang]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sat, 25 Oct 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Разработчики, переходящие в Go из классических ООП-языков вроде Java или PHP, часто пытаются применять знакомые подходы — например, экспортировать приватные типы. Но в Go это не просто лишнее — это антипаттерн.</p><p>Это первая наша пробная статья, но написана по заготовке нашего разработчика с опытом более 15 лет. В этой версии она более ужата, ранее мы писали об этом на нашем сайте, сейчас хотим предоставить её более широкой публике.</p><h2>Почему это плохо</h2><p>Неэкспортируемые типы в Go созданы для внутреннего использования внутри пакета. Они скрывают реализацию и защищают код от нежелательного вмешательства извне. Когда такой тип делают экспортируемым, нарушается принцип инкапсуляции — одна из базовых идей Go.</p><p>Это приводит к тому, что:</p><ul><li>невозможно использовать тип в интерфейсах других пакетов;</li><li>ломается архитектура и DI (dependency injection);</li><li>документация GoDoc не видит такие типы;</li><li>код становится неидиоматичным и сбивает с толку других разработчиков.</li></ul><h2>Правильный подход</h2><h2>Правильный подход</h2><p>Go поощряет простую инициализацию структур. Многие стандартные типы например,</p><p>работают корректно без конструктора. Для сложных сервисов используйте именованные конструкторы, которые проверяют зависимости и возвращают ошибку при некорректной инициализации. Это — идиоматичный путь Go: лучше обработать ошибку явно, чем скрывать её за “удобством”.</p><p>service, err := NewDomainService(cfg, deps)</p><p>if err != nil {</p><p>log.Fatal(err)</p><p>}</p><h2>Итог</h2><p>Экспортировать приватные типы — соблазнительно, но опасно. Это разрушает архитектуру и противоречит философии Go. Используйте приватные структуры только внутри пакета и придерживайтесь идиоматичных решений — они делают ваш код безопаснее и понятнее.</p><p>Источник статьи наш блог, опыт разработчика Webdelo</p>]]></content:encoded>
    </item>
    <item>
      <title>Как изменить код работающего Java-приложения? Пишем свой HotSwap</title>
      <link>https://tproger.ru/articles/kak-izmenit-kod-rabotayushhego-java-prilozheniya--piwem-svoj-hotswap</link>
      <comments>https://tproger.ru/articles/kak-izmenit-kod-rabotayushhego-java-prilozheniya--piwem-svoj-hotswap?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Тюрин ]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-izmenit-kod-rabotayushhego-java-prilozheniya--piwem-svoj-hotswap</guid>
      <description><![CDATA[<p>Практический разбор создания Java-агента для модификации байт-кода на лету. Как использовать Attach API, Instrumentation и Byte Buddy, чтобы изменить поведение работающего приложения. Подробно о реализации и ошибках.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-izmenit-kod-rabotayushhego-java-prilozheniya--piwem-svoj-hotswap">Как изменить код работающего Java-приложения? Пишем свой HotSwap</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 24 Oct 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Представьте: ваше Java-приложение запущено. Например, оно пишет в консоль каждые 5 секунд:</p><p>Вы его не перезапускали. Код не меняли. Но внезапно — без предупреждения — оно начинает писать:</p><p>Никаких рестартов. Никаких деплоев. Никакого git pull. Просто… поменялось.</p><p>Звучит как фокус? Но это — <i>настоящая инструментация JVM</i>, доступная каждому. И сегодня я покажу, как <i>подключиться к живой JVM</i>, <i>загрузить свой агент</i> и <i>изменить поведение класса — без единой строчки в исходнике</i>. Да, даже если метод final. (если только он не static final).</p><h2>Это рантайм, а не компиляция</h2><p>Допустим, по описанному примеру выше, у нас есть простой сервис:</p><p>Он вызывается в бесконечном цикле:</p><p>Приложение работает. Состояние в памяти. Соединения открыты. Кэши разогреты.</p><p>А мы хотим поменять сообщение. Прямо сейчас. Без перезапуска.</p><p>Перезапуск — это потеря данных, времени, пользовательских сессий. А что, если можно просто… заменить реализацию?</p><h3>Как это вообще возможно?</h3><p>Java — не такой уж статичный язык, как кажется.</p><p>JVM предоставляет механизм <i>динамической модификации байт-кода</i> уже загруженных классов. Его используют:</p><ul><li>IDE для HotSwap</li><li>Mockito — чтобы мокать final классы<br /></li><li>Lombok — хотя чаще на этапе компиляции<br /></li><li>Spring AOP — через CGLIB-прокси<br /></li><li>OpenTelemetry, Datadog, New Relic — для трассировки без изменения кода<br /></li></ul><p>Всё это работает благодаря java.lang.instrument.Instrumentation — API, которое позволяет:</p><ul><li>Перехватывать загрузку классов (ClassFileTransformer)</li><li>Изменять байт-код на лету<br /></li><li>Заменять реализации методов через redefineClasses() или retransformClasses()<br /></li></ul><p>Но чтобы получить доступ к Instrumentation, нужно войти внутрь целевой JVM.</p><h2>Этап 1: Подключение к JVM — Attach API</h2><p>JVM позволяет «прицепиться» к себе извне — через Attach API.</p><p>Да, это как ssh, но для Java-процесса. Вы находите PID (jps, ps aux | grep java), подключаетесь — и получаете полный контроль.</p><p>Через loadAgent() вы загружаете JAR-файл, который выполнится внутри целевого приложения. И самое важное: этот агент может получить экземпляр Instrumentation.</p><h2>Этап 2: Агент с правами root</h2><p>У Java-агента особая точка входа — agentmain, а не main:</p><p>Как только агент загружен, он может:</p><ul><li>Регистрировать ClassFileTransformer</li><li>Модифицировать байт-код уже загруженных классов<br /></li><li>Заменять методы, поля, аннотации<br /></li></ul><p>И всё это — без перезапуска.</p><h2>Этап 3: Меняем getMessage() на лету</h2><p>С помощью [Byte Buddy]<i>(https://bytebuddy.net/</i>) (обёртка над ASM) это выглядит почти как обычный Java-код:</p><h4>Что происходит?</h4><ol><li>Мы ищем MessageService среди всех загруженных классов.</li><li>Проверяем, что его можно переопределять (isModifiableClass).<br /></li><li>Через Byte Buddy заменяем тело getMessage() на константу.<br /></li><li>Генерируем новый байт-код.<br /></li><li>Передаём его JVM через redefineClasses().</li></ol><p>И вот — следующий вызов getMessage() уже возвращает "Hello from Agent!". <i>Без прокси. Без интерфейсов. Без рефлексии.</i> Прямая замена байт-кода.</p><p>Почему это важно? Потому что это <i>не обёртка</i>, а это <i>оригинальный класс</i>, но с другим телом метода.</p><h3>Где это реально применяется?</h3><p>Именно такой подход лежит в основе множества современных Java-инструментов:</p><ul><li>Spring AOP — создаёт CGLIB-прокси, например для @Transactional, @Cacheable.</li><li>Mockito — мокает final классы через Byte Buddy<br /></li><li>APM-агенты (OpenTelemetry, Datadog) — внедряют трассировку в HTTP-клиенты, БД-драйверы.<br /></li></ul><p>Все они используют <i>те же самые механизмы</i>. Эта возможность особенно мощна при работе с динамически генерируемыми классами. Например, когда Spring создаёт CGLIB-прокси для @Transactional-бинов, этот класс появляется в памяти во время выполнения. Ваш ClassFileTransformer может перехватить его загрузку и добавить логирование, метрики или аудит.</p><p>APM-системы именно так и работают: они не требуют изменения кода, но умеют измерять время выполнения методов, SQL-запросов, HTTP-вызовов — потому что могут модифицировать байт-код на лету.</p><h2>Реальные трудности: что может пойти не так?</h2><p>На практике всё не так гладко, тк работа с JVM требует некоторой осторожности и подготовленности. Даже незначительные ошибки могут "сломать" исходное приложение. При разработке я сталкнулся с такими проблемами:</p><p>🔹 "Agent JAR not found or no Agent-Class attribute"</p><p>&gt; Причина: jar собирался без MANIFEST.MF. Также возможно, если в MANIFEST.MF не указать Agent-Class или путь к jar.</p><p>&gt; Решение: добавил в pom.xml явное указание манифеста через maven-jar-plugin.</p><p>🔹 "Agent JAR loaded but agent failed to initialize"</p><p>&gt; Причина: агент зависел от ByteBuddy, но зависимости не были встроены в JAR.</p><p>&gt; Решение: перешёл на maven-shade-plugin — собрал fat-jar со всеми зависимостями.</p><p>🔹 "Cannot inject already loaded type"</p><p>&gt; Причина: Я использовал .load(classLoader) после redefine, где пытался <i>загрузить </i>класс, а не <i>переопределить</i>.</p><p>&gt; Решение: убрал .load(...), и вместо этого применил inst.redefineClasses(...) — ведь redefine не загружает, а <i>заменяет</i> существующий класс.</p><p>🔹 Динамический attach в будущем будет отключён по умолчанию</p><p>В новых версиях Java появляются предупреждения:</p><p>Я тестировал на JDK 23. Возможно уже есть решение или потребуется использовать флаг -XX:+EnableDynamicAgentLoading.</p><h2>Заключение</h2><p>Java — это не только язык. Это платформа, которую можно программировать извне.</p><p>Знание java.lang.instrument, attach, redefine и работы с байт-кодом — это отдельный уровень мастерства.</p><p>Когда вы осваиваете эти инструменты, вы перестаёте быть просто пользователем фреймворков. Вы начинаете понимать, как они устроены изнутри.</p><p>Spring, Mockito, Lombok, OpenTelemetry — все они используют эти же механизмы. А теперь вы знаете, как они работают. И можете написать свой.</p><p>Код проекта на github:</p><p>Проект состоит из:</p><ul><li><i>target-app</i> — целевое приложение («жертва»)</li><li><i>hotswap-agent</i> — агент для изменения классов на лету<br /></li><li><i>attach-client</i> — клиент для подключения к JVM<br /></li></ul><p>P.S. А вы когда-нибудь писали свой Java-агент? Делитесь в комментариях!</p>]]></content:encoded>
    </item>
    <item>
      <title>11 топовых библиотек и фреймворков для Java в 2025 году</title>
      <link>https://tproger.ru/articles/11-topovyh-bibliotek-i-frejmvorkov-dlya-java-v-2025-godu</link>
      <comments>https://tproger.ru/articles/11-topovyh-bibliotek-i-frejmvorkov-dlya-java-v-2025-godu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/11-topovyh-bibliotek-i-frejmvorkov-dlya-java-v-2025-godu</guid>
      <description><![CDATA[<p>Топ библиотек и фреймворков Java 2025: Spring Boot, Hibernate, JUnit, Micronaut, Quarkus. Практические советы от Senior и Lead разработчиков.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/11-topovyh-bibliotek-i-frejmvorkov-dlya-java-v-2025-godu">11 топовых библиотек и фреймворков для Java в 2025 году</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Фреймворки и библиотеки]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 17 Oct 2025 12:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>Java-разработчики поделились списком инструментов, которые реально используют в работе. Подборка понравится:</p><ul><li><b>джунам</b>, которые выбирают первый стек технологий;</li><li><b>мидлам</b>, которые хотят сравнить свой опыт с коллегами;</li><li><b>сеньорам</b>, которые подбирают инструменты под новый проект.</li></ul><p>Вы узнаете — какие библиотеки и фреймворки выручают Java-разработчиков в 2025 году. <a href="https://www.linkedin.com/in/kazakov-i/">Игорь Казаков</a>, <a href="https://t.me/three_monitors">Константин Шибков</a> и <a href="http://@vad2604">Вадим Федосеев</a> рассказали, почему джависты предпочитают конкретный инструмент, для каких задач он удобен и на что обращать внимание при выборе.</p><h2>Чем фреймворк отличается от библиотеки?</h2><p><b>Библиотека </b>работает как набор инструментов.</p><p>Хотите парсить JSON? Подключаете Jackson. Нужно логирование? Добавляете SLF4J. Вы решаете, когда и как использовать код библиотеки.</p><p><b>Фреймворк </b>задаёт структуру приложения.</p><p>К примеру, <a href="https://tproger.ru/articles/pishem-java-veb-prilozhenie-na-sovremennom-steke-s-nulja-do-mikroservisnoj-arhitektury-chast-1">Spring Boot</a> — он запускает ваше приложение, создаёт контекст, инжектит зависимости. Хотите вы или нет, но придётся писать контроллеры, сервисы и репозитории по правилам фреймворка.</p><p>Некоторые фреймворки можно использовать как библиотеки. Например, Hibernate — с ним работают как с библиотекой для маппинга объектов или как с полноценным фреймворком с управлением сессиями и жизненным циклом. Выбор зависит от задачи и предпочтений команды.</p><h2>На что смотрят профи, когда выбирают Java-фреймворк?</h2><blockquote>Фреймворк должен сопровождаться хорошей документацией, без этого самый крутой функционал превращается в головную боль. На втором месте — стабильность. Очень расстраивает, когда сделал 90% фичи, а потом всё встало из-за нерешённого бага в библиотеке.</blockquote><p><i>Игорь Казаков, Lead Software Engineer (Java)</i>, при выборе инструмента оценивает:</p><ul><li>Производительность. Следующие преимущества будут неактуальными, если инструмент плохо оптимизирован.</li><li>Документацию. Её наличие экономит массу времени и новичкам, и продвинутым пользователям.</li><li>Поддержку. Важно, чтобы команда разработки инструмента следила за его актуальностью и совместимостью, держала вопросы безопасности на высоком уровне.</li><li>Сообщество. Даже с блестящей документацией важно комьюнити, готовое поделиться опытом.</li></ul><p>Отдельно он подчёркивает модульность и обратную совместимость — никто не хочет переписывать половину проекта после обновления версии.</p><p><i>Константин Шибков, Java-разработчик</i>, ждёт от фреймворка следующее:</p><blockquote>Жду от идеального фреймворка регулярные релизы с поддержкой новых технологий и версий языка, простое подключение модулей и понятный путь при миграции до новых мажорных версий. Идеальный фреймворк закрывает 80% типовых задач без бойлерплейта и лишней магии. Заложенная безопасность, готовая россыпь метрик его работы, обратная связь с командой разработки — это обязательные элементы отличного инструмента.</blockquote><h2>1. Spring Boot</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/e711de5d-2767-4915-ab26-23cea62d42c7.jpg" alt="" /></figure><p>Spring — это целая экосистема фреймворков. Spring Boot — один из его фреймворков. При работе с SB вы используете «стартеры», которые автоматически создают бины для компонентов Spring.</p><p>Фреймворк определяет, какие библиотеки вы используете, и самостоятельно их настраивает. Если подключите базу данных, Spring Boot создаст пул соединений, добавите веб-зависимость — получите встроенный Tomcat-сервер. Любую автоматическую настройку можно переопределить.</p><p>Spring Boot выбирают для разработки:</p><ul><li>REST API и микросервисов,</li><li>веб-приложений с шаблонизаторами,</li><li>консольных утилит и планировщиков задач,</li><li>интеграций с внешними системами.</li></ul><blockquote>Spring Boot — самый распространённый фундамент любого бекэнд приложения. В большинстве вакансий я вижу именно SB. Фреймворк отлично сочетает рабочие библиотеки, хорошо описан и даёт достаточно контроля.</blockquote><blockquote>Новичкам советую начать именно со Spring Boot. Даже если проект в итоге не потребует всего функционала, вы получите отличное понимание современных практик Java-разработки, а также сможете быстро написать приложение без копания в тоннах документации и бесконечных отладок кода.</blockquote><h2>2. Hibernate</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/48d60d2f-d161-485b-acf2-97b0705c74e4.jpg" alt="" /></figure><p>Фреймворк связывает Java-объекты с таблицами в базе данных. Вместо написания SQL-запросов вы работаете с обычными классами и методами.</p><blockquote>Hibernate — зрелая ORM, реализующая стандарт JPA. Используется в большинстве видимых мною проектов с реляционными БД. Снимает с разработчика много рутины и позволяет в достаточной мере оптимизировать работу с базами.</blockquote><p>Инструмент рекомендуют для разработки типичных бизнес-приложений с CRUD-операциями. Hibernate автоматически генерирует SQL, управляет транзакциями и кеширует данные. Вы пишете user.save() — фреймворк сам создаёт INSERT-запрос и выполняет его.</p><blockquote>Иногда складывается обманчивое впечатление, когда запуск простого приложения на фреймворке — это задача 5 минут. Hibernate достаточно прост для создания CRUD приложения. Но когда нужны сложные связи между таблицами, особые типы данных или непростые выборки данных, в этих случаях фреймворк начинает «давить» на разработчика ограничениями и неявными правилами, которые были скрыты в угоду удобства.</blockquote><h2>3. Jackson</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/432d1347-d269-4360-8964-d147957a9870.jpg" alt="" /></figure><p>Библиотека превращает Java-объекты в JSON и обратно. Работает через аннотации — вешаете @JsonProperty на поле, и Jackson понимает, как его назвать в JSON.</p><p>Нужно игнорировать какое-то поле? Добавили @JsonIgnore и забыли. При этом Jackson умеет работать даже без аннотаций — просто смотрит на геттеры и сеттеры вашего класса.</p><blockquote>Jackson стабилен, гибок и незаменим в работе с JSON.</blockquote><p>Базовый модуль работает с JSON, но можно подключить дополнительные: для XML, YAML, CSV. Один и тот же код сериализует объекты в разные форматы. Ещё Jackson дружит с Java 8+ фичами через отдельный модуль.</p><p>Библиотека пригодится, когда пишете REST API, работаете с конфигурационными файлами или интегрируетесь с внешними сервисами. <b>Spring Boot использует Jackson по умолчанию</b> — все @RestController автоматически отдают JSON через него.</p><h2>4. JUnit</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/8074073c-9c4b-4fb9-9a45-9a237cd0e176.jpg" alt="" /></figure><p>Больше 20 лет JUnit лидирует среди фреймворков для тестирования Java-приложений. Разработчики выбирают его за простоту и скорость написания тестов — достаточно поставить аннотацию @Test над методом, и он превращается в полноценный тест.</p><blockquote>JUnit — это модульные тесты через простую аннотационную модель, интеграция с IDE и средами сборки.</blockquote><p>Фреймворк выручает при рефакторинге старого кода. Написали тесты на существующую логику — можете менять реализацию. Тесты покажут, если что-то сломалось.</p><p>JUnit 5 добавил параметризованные тесты: один тестовый метод проверяет сразу десяток разных входных данных.</p><blockquote>К Spring Boot обязательно беру JUnit + AssertJ, Mockito и Testcontainers — вместе они обеспечивают реалистичные интеграционные тесты и быстрый фидбек в CI.</blockquote><h2>5. MapStruct</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/26bfd959-19c8-4f80-8bb3-2e7f17f51164.jpg" alt="" /></figure><p>Библиотека генерирует код маппинга между Java-объектами во время компиляции. Вместо ручного переписывания полей из одного объекта в другой, вы пишете простой интерфейс с аннотациями — MapStruct создаёт реализацию автоматически.</p><blockquote>Не представляю быструю реализацию мапперов без MapStruct. Библиотека избавляет от сотен строк шаблонного кода и ошибок при преобразовании DTO&lt; -&gt;Entity.</blockquote><blockquote>MapStruct изящно решает рутинную задачу преобразования объектов без магии и просадок производительности.</blockquote><h2>6. Lombok</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/21424b29-2056-4c29-8a55-f4678b9d651c.jpg" alt="" /></figure><p>Библиотека автоматически генерирует повторяющийся код через аннотации. Вместо того, чтобы писать геттеры, сеттеры, конструкторы и методы equals/hashCode руками, вы просто ставите аннотацию @Data над классом.</p><blockquote>Lombok экономит время: помогает писать код чище.</blockquote><p>Библиотека встраивается в процесс сборки и добавляет нужные методы в байт-код. Новые разработчики в команде могут удивиться, откуда берутся методы, которых нет в исходниках. Зато вы экономите время на рутине и концентрируетесь на бизнес-логике.</p><blockquote>Jackson и Lombok — стандарт для энтерпрайза, без них не обходится ни один проект. Lombok не идеален, но сильно сокращает шаблонный код и делает DTO более читаемыми, позволяет сосредоточиться на бизнес-логике.</blockquote><h2>7. Testcontainers</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/ae215712-368b-4f9c-9afc-b8f4ca0baa33.jpg" alt="" /></figure><p>Testcontainers решает классическую проблему: как протестировать код, который работает с базой данных или внешними сервисами? Библиотека запускает настоящие Docker-контейнеры прямо из тестов — PostgreSQL, Redis, Kafka, что угодно. Тесты получают реальное окружение вместо заглушек и моков.</p><p>Контейнеры живут ровно столько, сколько выполняются тесты. Запустил тест — поднялась база, прошёл тест — контейнер удалился.</p><p>Testcontainers выручает при:</p><ul><li>интеграционном тестировании с реальными базами данных,</li><li>проверке миграций и SQL-запросов,</li><li>тестировании микросервисов с брокерами сообщений,</li><li>работе с NoSQL-хранилищами.</li></ul><blockquote>JUnit 5 с Jupiter API — стандарт для тестирования. Особенно в связке с Testcontainers — это очень важный инструмент.</blockquote><h2>8. Micronaut</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/a588e1f2-1bfb-4398-b45e-9bb28caf5a82.jpg" alt="" /></figure><p>Фреймворк компилирует магию dependency injection на этапе сборки, а не во время запуска приложения. Ваш сервис стартует за 1-2 секунды вместо привычных 10-30 секунд у Spring Boot. Типичное приложение съедает 50-100 МБ вместо нескольких сотен.</p><p>Фреймворк рекомендуют в трёх случаях:</p><ul><li>Пишете микросервисы и устали ждать перезапуска при каждом изменении.</li><li>Разворачиваете приложения в AWS Lambda, Google Cloud Functions.</li><li>Платите за облачные ресурсы и хотите сэкономить на железе.</li></ul><p>Micronaut поддерживает реактивное программирование из коробки, дружит с GraalVM и компилируется в нативные образы. При этом синтаксис остаётся знакомым — те же аннотации @Controller, @Service, @Repository, что и в Spring.</p><h2>9. Quarkus</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/dd181c07-0c3d-4223-9d15-d6f4627ea7d7.jpg" alt="" /></figure><p>Фреймворк компилирует код в нативные исполняемые файлы через GraalVM. Ещё Quarkus работает с микросервисами и облачными платформами.</p><p>Quarkus потребляет в 10 раз меньше памяти по сравнению с традиционными Java-приложениями. Разработчики пишут обычный Java-код, а фреймворк самостоятельно оптимизирует его под контейнеры и Kubernetes.</p><blockquote>Некоторые компании используют Quarkus как более быструю и легкую альтернативу Spring Boot. Однако мне показалось, что вакансий с ним на рынке СНГ в разы меньше, чем на SB.</blockquote><blockquote>Quarkus и Micronaut хороши для небольших проектов и там, где важен быстрый старт приложения. Но пока они проигрывают Spring Boot в зрелости и глубине интеграций для большинства enterprise-сценариев.</blockquote><h2>10. MyBatis</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/ca5295e9-ed69-4ff3-a51c-769a1e6dcf60.jpg" alt="" /></figure><p>Фреймворк соединяет Java-объекты с БД через SQL-запросы. В отличие от Hibernate, где SQL генерируется автоматически, здесь вы пишете запросы сами и размещаете их в XML-файлах или аннотациях.</p><blockquote>MyBatis выбираю для маппинга запросов, когда планируется сложная бизнес-логика.</blockquote><p>Фреймворк не навязывает архитектуру приложения и легко встраивается в существующий код.</p><h2>11. Guava</h2><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-10-17/81a806a8-8980-4fe0-a1ee-7cbc5ec3412c.jpg" alt="" /></figure><p>Библиотека Google Guava закрывает пробелы стандартной Java. Это набор утилит, который экономит время на рутине. Валидация параметров, работа с Optional до Java 8, удобные билдеры для коллекций — библиотека решает десятки мелких задач, с которыми сталкивается каждый разработчик.</p><blockquote>Новичкам всегда советую брать самые популярные инструменты, которыми пользуются большинство компаний. В Java не так много фреймворков, поэтому по умолчанию рекомендую Spring Boot, Hibernate, JUnit. Это тот опыт, который нужен для большинства вакансий. Изучив перечисленные инструменты, можно попробовать менее популярные инструменты и уже на личном опыте оценить их пользу.</blockquote><p>🙄<i> После публикации заметили, что забыли упомянуть один не менее популярный фреймворк. Делитесь догадками в комментариях — какой инструмент незаслуженно остался на страницах черновика?</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Курсы по автоматизации тестирования: обучение автотестированию бесплатно и платно</title>
      <link>https://tproger.ru/articles/kursy-po-avtomatizacii-testirovaniya--obuchenie-avtotestirovaniyu-besplatno-i-platno</link>
      <comments>https://tproger.ru/articles/kursy-po-avtomatizacii-testirovaniya--obuchenie-avtotestirovaniyu-besplatno-i-platno?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Анастасия Шишкина]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kursy-po-avtomatizacii-testirovaniya--obuchenie-avtotestirovaniyu-besplatno-i-platno</guid>
      <description><![CDATA[<p>Лучшие курсы по автотестированию. Рейтинг вариантов онлайн-обучения для тестировщиков, обзор обучающей программы и стоимости курсов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kursy-po-avtomatizacii-testirovaniya--obuchenie-avtotestirovaniyu-besplatno-i-platno">Курсы по автоматизации тестирования: обучение автотестированию бесплатно и платно</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Обучающие курсы]]></category>
      <category><![CDATA[Автоматизирование]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 06 Oct 2025 11:10:59 GMT</pubDate>
      <content:encoded><![CDATA[<p>Современные курсы по автоматизации тестирования открывают путь к карьерному росту и более высоким зарплатам по сравнению с работой только с ручным тестированием. В крупных компаниях такие навыки особенно ценны: автоматизация снижает издержки и ускоряет вывод продукта на рынок. Кроме того, инженер по автоматизации всегда находится «на стыке» разработки и тестирования, что дает уникальные возможности для профессионального развития в обеих сферах.</p><p>Я изучила около 50 обучающих программ и отобрала 30 лучших курсов по автоматизации тестирования для этой статьи. В материале представлены топ-10 курсов, которые стоит рассмотреть в первую очередь, а также дополнительные варианты с акцентом на тестирование на Java и Python. Отдельно я собрала подборки бесплатных уроков и программ, которые помогут начать обучение самостоятельно.</p><p><b>Для некоторых курсов я даже нашла уникальные промокоды, которые позволят получить приятные скидки и бонусы при записи — отличная возможность сэкономить и начать обучение с дополнительными преимуществами!</b></p><h2>ТОП-10 лучших курсов по автоматизации тестирования в 2026 году</h2><ol><li><a href="https://experts1.ru/XBbfwd?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=1">Инженер по автоматизации тестирования</a> от GeekBrains — комплексная программа с углубленным изучением Java, Python и JavaScript.</li><li><a href="https://experts1.ru/qtcByJ?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=2">Инженер по автоматизации тестирования</a> от Skillbox — практико-ориентированный курс с упором на Selenium и CI/CD.</li><li><a href="https://experts1.ru/rauwOB?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=3">Инженер по тестированию</a> от Нетологии — расширенное обучение с модулями по нейросетям и современным фреймворкам.</li><li><a href="https://experts1.ru/xiqXNb?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=4">Инженер по тестированию</a> от Skypro — системная подготовка с созданием собственного фреймворка и дипломным проектом.</li><li><a href="https://experts1.ru/gdFbrE?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=5">Ав­то­ма­ти­зи­ро­ван­ное тестирование на Python</a> от Skillbox — обучение с акцентом на Python, Pytest и DevOps-практики.</li><li><a href="https://experts1.ru/ZcfLbp?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=6">Инженер по тестированию: от новичка до автоматизатора</a> от «Яндекс Практикума» — поэтапное освоение от ручного тестирования до авто-тестов с реальными проектами.</li><li><a href="https://experts1.ru/vAyDxq?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=7">Python QA Engineer</a> от OTUS — интенсивный курс с PyTest, Selenium и упором на DevOps.</li><li><a href="https://experts1.ru/JvBnrm?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=8">Автоматизатор тестирования на Java</a> от «Яндекс Практикума» — обучение Java с нуля и построение CI/CD пайплайнов.</li><li><a href="https://experts1.ru/MLhyjk?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=9">Инженер по автоматизированному тестированию на JavaScript</a> от «Хекслета» — практика с Playwright, Jest и проектами на GitHub.</li><li><a href="https://experts1.ru/xomLeC?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=10">Автоматизатор тестирования на Python</a> от «Яндекс Практикума» — обучение на Python с упором на pytest, Selenium и Docker.</li></ol><p>Курсы по автоматизации тестирования подойдут тем, кто уже знаком с ручным тестированием и хочет перейти на новый уровень профессионального развития. Они будут полезны начинающим айти-специалистам, которые планируют построить карьеру в тестировании и программировании. Также такие программы подойдут разработчикам, желающим расширить компетенции и работать ближе к процессам контроля качества.</p><h2>Онлайн-курсы по автоматизации тестирования</h2><p><b>1. <a href="https://experts1.ru/XBbfwd?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=1">Инженер по автоматизации тестирования</a> | GeekBrains</b></p><p><i>Используйте промокод kursfinder, чтобы получить скидку 7%</i></p><p><a href="https://experts1.ru/XBbfwd?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=1">Получить скидку &gt;&gt;&gt;</a></p><p>Программа охватывает три популярных языка программирования — Java, Python и JavaScript. Студенты осваивают современные инструменты и практики: Selenium WebDriver, JUnit, Chrome DevTools, Postman, GitLab, Grafana, SQL и Jira. Вы также научитесь созданию автотестов для веб- и мобильных приложений, работе с API и внедрению непрерывной интеграции.</p><p>Обучение ведут практикующие эксперты из Ozon, СКБ «Контур» и других крупных компаний. Курс сочетает теоретические видеоуроки с практикой на реальных проектах, что позволяет студентам формировать портфолио уже во время обучения.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/aca27061-02ad-4861-b6fe-52c21fdb76cd.jpg" alt="" /></figure><ul><li>Стоимость: от 3 358 руб. в месяц при рассрочке</li><li>Длительность: 110 часов теории и 400 часов практики</li><li>Формат обучения: видеоуроки, вебинары, практические задания, проекты, консультации кураторов и проверка домашних заданий</li><li>Сертификат: официальный диплом с лицензией</li></ul><p><b>Кому подойдет:</b> начинающим QA-инженерам, тестировщикам с опытом ручного тестирования, разработчикам, которые хотят освоить автоматизацию.</p><p><b>Преимущества</b></p><ul><li>совместная программа GeekBrains и Skillbox;</li><li>обучение с лицензией государственного образца;</li><li>углубленное изучение Java, Python и JavaScript;</li><li>работа с современными инструментами для тестирования;</li><li>большой объем практики на реальных кейсах;</li><li>персональная обратная связь от экспертов;</li><li>возможность собрать портфолио во время обучения;</li><li>поддержка HR-специалистов для выхода на рынок труда;</li><li>гибкий график и доступ к материалам в любое время;</li><li>рассрочка без переплат и налоговый вычет.</li></ul><p><b>Недостатки</b></p><ul><li>высокая нагрузка по практическим заданиям;</li><li>продолжительный срок обучения.</li></ul><p><b>Программа обучения:</b></p><ul><li>Изучение одного из языков программирования Java/JavaScript/Python</li><li>Создание первых автотестов с использованием Selenium</li><li>Продвинутое автоматизированное тестирование</li><li>Работа с SQL для тестирования баз данных</li><li>Использование Jira для постановки задач и баг-репортов</li><li>Работа с API и Postman</li><li>Настройка CI/CD процессов</li><li>Метрики тестирования и их применение</li><li>Создание UI-тестов</li><li>Итоговые проекты и защита портфолио</li></ul><p><a href="https://experts1.ru/XBbfwd?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=1">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>2. <a href="https://experts1.ru/qtcByJ?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=2">Инженер по автоматизации тестирования</a> | Skillbox</b></p><p><i>Используйте промокод kursfinder, чтобы получить скидку 60%</i></p><p><a href="https://experts1.ru/qtcByJ?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=2">Получить скидку &gt;&gt;&gt;</a></p><p>Студенты осваивают один из трех языков программирования — Java, Python или JavaScript, знакомятся с современными инструментами, такими как Selenium WebDriver, JUnit, Git и CI/CD, и уже с первых модулей применяют знания на практике, создавая проекты для портфолио.</p><p>Обучение ведут практикующие эксперты из крупных компаний, а доступ к видеолекциям остается бессрочным, что позволяет повторять материал и углублять знания. Курс сочетает теорию с практическими заданиями, включает работу с API и SQL, а также предоставляет поддержку в подготовке к трудоустройству, помогая студентам уверенно стартовать в профессии инженера по автоматизации тестирования.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/81adcbc1-a267-4a35-816d-c67ab315f4b7.jpg" alt="" /></figure><ul><li>Стоимость: от 5 382 руб. в месяц при рассрочке</li><li>Длительность: 9 месяцев</li><li>Формат обучения: видеолекции, практические задания, проекты, вебинары, кураторская поддержка и доступ к мобильной версии платформы</li><li>Сертификат: официальный документ с лицензией</li></ul><p><b>Кому подойдет: </b>junior-тестировщикам, студентам курса «Инженер по тестированию» для продолжения обучения, специалистам, которые хотят перейти от ручных проверок к автоматизации.</p><p><b>Преимущества</b></p><ul><li>обучение с лицензией государственного образца;</li><li>освоение Java, Python и JavaScript;</li><li>практика с первого модуля;</li><li>работа с Selenium IDE и WebDriver;</li><li>изучение CI/CD и GitLab;</li><li>доступ к видеоурокам навсегда;</li><li>мобильная версия платформы;</li><li>помощь кураторов и экспертов;</li><li>дополнительные модули по SQL и API;</li><li>участие в двух финальных проектах;</li><li>возможность пополнить портфолио практическими кейсами;</li><li>обучение с опытными спикерами из OZON и СКБ «Контур»;</li><li>налоговый вычет до 13% от стоимости курса.</li></ul><p><b>Недостатки</b></p><ul><li>курс рассчитан только на специалистов с базовыми знаниями ручного тестирования;</li><li>ограничение по языкам программирования (только Java, Python, JavaScript);</li><li>трудоустройство не гарантировано, есть лишь канал с вакансиями.</li></ul><p><b>Программа обучения</b></p><ul><li>Изучение одного из языков программирования Java/JavaScript/Python</li><li>Первые автотесты во фреймворке Selenium</li><li>Продвинутое автоматизированное тестирование</li><li>Настройка CI/CD и параллельных запусков тестов</li><li>Работа с SQL и тестирование баз данных</li><li>Создание UI-тестов и их интеграция в процесс разработки</li><li>Работа с Git и управление версиями кода</li><li>Тестирование API и практические задачи с Postman</li><li>Итоговые проекты и защита работ</li></ul><p><a href="https://experts1.ru/qtcByJ?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=2">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>3. <a href="https://experts1.ru/rauwOB?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=3">Инженер по тестированию</a> | Нетология</b></p><p><i>Используйте промокод kursfinder, чтобы получить скидку 7%</i></p><p><a href="https://experts1.ru/rauwOB?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=3">Получить скидку &gt;&gt;&gt;</a></p><p>Программа построена поэтапно: сначала студенты изучают ручное тестирование веб- и мобильных приложений, затем переходят к автоматизированным сценариям на Python или Java, а в расширенном блоке осваивают JavaScript и популярные фреймворки — Cypress, Playwright и Puppeteer. Курс также включает модули по SQL, тестированию API, нагрузочному тестированию сервисов, анализу сетевого трафика и базовым практикам безопасности с использованием OWASP ZAP и Burp Suite.</p><p>Дополнительно студенты знакомятся с Docker, Git, Postman и JMeter, учатся планировать автоматизацию и анализировать результаты тестов. Четыре блока посвящены применению нейросетей для генерации кода автотестов, оптимизации рутинных задач и подготовки документации. В течение курса выполняется более 20 практических проектов, включая групповые задания на основе кейсов от компаний Dragons, OneTwoTrip, QIWI и «Глобус ИТ».</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/2be20663-b13a-4b6f-a090-73ea381dfa9a.jpg" alt="" /></figure><ul><li>Стоимость: от 3 816 руб. в месяц при рассрочке</li><li>Длительность: 14 месяцев (408 часов практики)</li><li>Формат обучения: вебинары, видеолекции, тренажеры для работы с кодом, домашние задания, проекты, командные кейсы, практические вебинары и поддержка экспертов в чате</li><li>Сертификат: диплом о профессиональной переподготовке установленного образца</li></ul><p><b>Кому подойдет:</b> новичкам, желающим войти в профессию с нуля, инженерам по тестированию для перехода к уровню middle, специалистам смежных направлений, которые хотят освоить автоматизацию и инструменты для тестирования игр, мобильных приложений и веб-сервисов.</p><p><b>Преимущества</b></p><ul><li>обновленная программа 2026 года с модулями по нейросетям;пошаговое погружение от ручного тестирования до автоматизации;</li><li>20 крупных проектов для портфолио;</li><li>командная практика по реальным кейсам от партнеров;</li><li>изучение Python, Java и JavaScript на выбор;</li><li>освоение популярных фреймворков для автоматизации;</li><li>практика работы с SQL и тестированием API;</li><li>модули по нагрузочному и функциональному тестированию;</li><li>основы тестирования безопасности и анализа уязвимостей;</li><li>знакомство с Docker и CI/CD;</li><li>поддержка экспертов из VK, Т-Банка, QIWI и других компаний;</li><li>доступ к мобильному приложению для обучения;</li><li>помощь в трудоустройстве и сопровождение после выпуска.</li></ul><p><b>Недостатки</b></p><ul><li>курс рассчитан на системное освоение, быстрых результатов не будет.</li></ul><p><b>Программа обучения</b></p><ul><li>Ручное тестирование веб-приложений</li><li>Git и система контроля версий</li><li>Python для тестировщиков или Java для тестировщиков</li><li>Автоматизированное тестирование на Python или Java</li><li>JavaScript и фреймворки для автоматизации</li><li>Тестирование API и интеграция в CI</li><li>Нагрузочное тестирование сервисов</li><li>Тестирование мобильных приложений</li><li>Основы тестирования безопасности</li><li>Работа с Docker и CI/CD</li><li>Дополнительные модули по нейросетям для тестировщиков</li><li>Итоговые проекты и дипломная работа</li></ul><p><a href="https://experts1.ru/rauwOB?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=3">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>4. <a href="https://experts1.ru/xiqXNb?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=4">Инженер по тестированию</a> | Skypro</b></p><p><i>Используйте промокод Kursfinder, чтобы получить скидку 10%</i></p><p><a href="https://experts1.ru/xiqXNb?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=4">Получить скидку &gt;&gt;&gt;</a></p><p>Программа построена так, чтобы студенты постепенно осваивали как ручное, так и автоматизированное тестирование. Сначала слушатели изучают работу с баг-репортами, тест-кейсами и системами управления тестами, затем переходят к освоению баг-трекинговых сервисов, методик тест-дизайна, регрессионного и дымового тестирования. Используются Chrome DevTools, Postman, SoapUI, SQL и JMeter для анализа работы веб-платформ, API и баз данных.</p><p>Дальше курс погружает студентов в автоматизацию на Python и Java, работу с Pytest, библиотекой requests и формирование отчетности в Allure. Студенты создают UI-тесты с помощью Selenium, изучают CI/CD и практикуются с Docker для автоматизации запуска тестов. В рамках обучения разрабатывается собственный тестовый фреймворк, а завершающим этапом становится дипломный проект. Программа насыщена практическими заданиями — около 70% материалов основаны на реальных кейсах работодателей и фриланс-платформ, что позволяет выпускникам сформировать полноценное портфолио к концу курса.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/64940a6a-3710-4699-99c6-5a7bbb815366.jpg" alt="" /></figure><ul><li>Стоимость: от 5 972 руб. в месяц при рассрочке</li><li>Длительность: 12 месяцев</li><li>Формат обучения: онлайн-занятия, видеолекции, практические задания, работа с наставниками, тренажеры, проекты и дипломная работа</li><li>Сертификат: диплом о профессиональной переподготовке</li></ul><p><b>Кому подойдет:</b> новичкам без опыта в IT, студентам и выпускникам других направлений, специалистам смежных областей, желающим перейти в сферу тестирования.</p><p><b>Преимущества</b></p><ul><li>системная программа с базовыми и продвинутыми блоками;</li><li>70% практики на реальных задачах;</li><li>изучение баг-трекинговых систем и TMS;</li><li>работа с Chrome DevTools и кросс-браузерным тестированием;</li><li>освоение Postman и SoapUI;</li><li>практика с SQL и нагрузочным тестированием в JMeter;</li><li>автоматизация тестов на Python и Java;</li><li>знакомство с Pytest и библиотекой requests;</li><li>отчетность и визуализация через Allure;</li><li>практика с Selenium WebDriver;</li><li>освоение принципов CI/CD и Docker;</li><li>создание собственного фреймворка для автотестов;</li><li>карьерные консультации и помощь в трудоустройстве.</li></ul><p><b>Недостатки</b></p><ul><li>длительный срок обучения (1 год);</li><li>упор на Python и Java, другие языки не рассматриваются.</li></ul><p><b>Программа обучения</b></p><ul><li>Основы функционального тестирования</li><li>Работа с баг-репортами и баг-трекинговыми системами</li><li>Тест-кейсы и системы управления тестами</li><li>Уровни тестирования и тест-дизайн</li><li>Smoke- и регрессионное тестирование</li><li>Тестирование документации и метрики</li><li>Тестирование веб-приложений и работа с HTML/CSS</li><li>Chrome DevTools и кросс-браузерное тестирование</li><li>Git и основы CI/CD</li><li>Тестирование API с Postman и SoapUI</li><li>Нагрузочное тестирование с JMeter</li><li>Основы SQL и работа с базами данных</li><li>Автоматизация тестирования на Python или Java</li><li>Pytest, requests и Allure для отчетности</li><li>UI-тесты и Selenium WebDriver</li><li>Docker и настройка CI/CD процессов</li><li>Дипломный проект и защита портфолио</li></ul><p><a href="https://experts1.ru/xiqXNb?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=4">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>5. <a href="https://experts1.ru/gdFbrE?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=5">Ав­то­ма­ти­зи­ро­ван­ное тестирование на Python</a> | Skillbox</b></p><p><i>Используйте промокод kursfinder, чтобы получить скидку 50%</i></p><p><a href="https://experts1.ru/gdFbrE?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=5">Получить скидку &gt;&gt;&gt;</a></p><p>На занятиях студенты осваивают написание чистого кода на Python, применяют принципы объектно-ориентированного и функционального программирования, разрабатывают архитектуру тестов и объединяют их в тестсьюты. Особое внимание в программе уделяется работе с DevTools и PyCharm, использованию Pytest и Selenium для построения автотестов, а также созданию сценариев на основе паттернов тестирования.</p><p>Отдельные блоки посвящены DevOps-инструментам: студенты интегрируют тесты в Jenkins, настраивают параллельные и последовательные проверки и внедряют их в CI/CD-процессы. Курс также охватывает работу с Git, решение конфликтов версий и ведение командных проектов. Теория сразу закрепляется практикой, а итогом становится полноценное портфолио готовых кейсов. Программу ведут эксперты: Дарья Манухина, специалист с опытом работы в МТС и Skyeng, и Павел Громов, backend-разработчик с практикой преподавания и участия в конференциях по тестированию.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/d1993c78-089e-4b56-a32a-3974a7224f56.jpg" alt="" /></figure><ul><li>Стоимость: от 5 028 руб. в месяц при рассрочке</li><li>Длительность: 9 месяцев</li><li>Формат обучения: онлайн-лекции, практические задания, вебинары, индивидуальная проверка домашних работ кураторами, обратная связь и доступ к материалам без ограничения по времени</li><li>Сертификат: диплом о профессиональной переподготовке</li></ul><p>Кому подойдет: начинающим тестировщикам, которые хотят с нуля освоить Python и автоматизацию; junior-специалистам для повышения уровня знаний; middle-инженерам по тестированию, желающим закрепить практику и выйти на новый уровень.</p><p><b>Преимущества</b></p><ul><li>обучение с упором на Python;</li><li>освоение Pytest и Selenium;</li><li>практика с DevTools и PyCharm;</li><li>изучение принципов тест-дизайна;</li><li>написание автотестов для реальных кейсов;</li><li>построение архитектуры тестов и паттернов;</li><li>работа с Jenkins и CI/CD;</li><li>интеграция тестов с Git;</li><li>коммит, merge и разрешение конфликтов версий;</li><li>практика на примере веб- и API-проектов;</li><li>участие экспертов-практиков;</li><li>доступ к курсу навсегда;</li><li>бесплатный бонус — год английского языка.</li></ul><p><b>Недостатки</b></p><ul><li>упор на один язык программирования;</li><li>значительный объем теории, требующий регулярной практики;</li><li>курс рассчитан на 9 месяцев, быстрых результатов не будет;ограничение по выбору инструментов вне экосистемы Python.</li></ul><p><b>Программа обучения</b></p><ul><li>Python Basic</li><li>Python Advanced</li><li>Введение в автоматизацию тестирования API</li><li>Автотесты на Python. Базовая часть</li><li>Автотесты на Python. Продвинутая часть</li><li>DevOps для тестировщиков</li><li>Итоговые проекты и дипломная работа</li></ul><p><a href="https://experts1.ru/gdFbrE?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=5">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>6. <a href="https://experts1.ru/ZcfLbp?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=6">Инженер по тестированию: от новичка до автоматизатора</a> | Яндекс Практикум</b></p><p><i>Купите любой курс с выгодой до 20% при оплате сразу или получите скидку 7% за прохождение бесплатной части курса за неделю</i></p><p><a href="https://experts1.ru/ZcfLbp?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=6">Получить скидку &gt;&gt;&gt;</a></p><p>Обучение начинается с освоения принципов тестирования приложений и работы с тестовой документацией, после чего студенты переходят к созданию автотестов на Java или Python. В программе используются инструменты Charles, Postman, Swagger, DevTools, Selenium WebDriver, Pytest, Allure и Jenkins, а также SQL для работы с базами данных. Знания сразу закрепляются практикой: за время курса слушатели выполняют 10 реальных проектов, формируя портфолио для будущего трудоустройства.</p><p>Вы научитесь также тестированию веб- и мобильных приложений, API и работе с инфраструктурой, что позволяет применять навыки в различных сферах — от банковских сервисов до игровых компаний. Обучение проводят эксперты из Яндекса и крупных IT-компаний, включая Константина Булатова, Кристину Тимошенко и Романа Орлова. Дополнительно студенты изучают применение нейросетей в тестировании и получают навыки подготовки резюме для привлечения работодателей.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/994573e9-329d-4c03-bd83-e47dd6dd491a.jpg" alt="" /></figure><ul><li>Стоимость: от 3 225 руб./мес или 79 000 руб. единым платежом</li><li>Длительность: 9 месяцев</li><li>Формат обучения: вебинары с практикующими тестировщиками, видеолекции, интерактивный учебник, командные проекты, поддержка наставников и ревьюеров, доступ к материалам навсегда</li><li>Сертификат: диплом о профессиональной переподготовке от АНО ДПО «Образовательные технологии Яндекса»</li></ul><p><b>Кому подойдет:</b> новичкам без технического образования, желающим освоить тестирование; джунам, планирующим выйти на уровень автоматизации; специалистам других сфер, рассматривающим карьерный переход в IT.</p><p><b>Преимущества</b></p><ul><li>освоение ручного и автоматизированного тестирования;</li><li>выбор языка для автотестов (Java или Python);</li><li>практика на 10 реальных проектах;</li><li>инструменты Charles, Postman, Swagger, SQL, Selenium, Jenkins;</li><li>работа с мобильными приложениями и API;</li><li>модуль по применению нейросетей;</li><li>обучение у специалистов Яндекса и EPAM;</li><li>поддержка наставников и ревьюеров;</li><li>доступ к материалам курса без ограничений;</li><li>помощь в трудоустройстве через карьерный центр;</li><li>возможность совмещать учебу с работой;</li><li>налоговый вычет до 19 500 руб.;</li><li>гарантия возврата средств при отказе от курса.</li></ul><p><b>Недостатки</b></p><ul><li>высокая учебная нагрузка (от 15 часов в неделю);</li><li>основной упор на начинающих.</li></ul><p><b>Программа обучения</b></p><ul><li>Бесплатный вводный модуль</li><li>Основы тестирования</li><li>Регрессионное тестирование и ретест багов</li><li>Тестирование фичи от анализа до баг-репорта</li><li>Расширенное тестирование веб-приложений</li><li>Тестирование мобильных приложений</li><li>Тестирование API</li><li>Основы баз данных</li><li>Автоматизированное тестирование на Java</li><li>Автоматизированное тестирование на Python</li><li>Итоговый проект</li><li>Нейросети для тестировщиков</li><li>Карьерный трек</li></ul><p><a href="https://experts1.ru/ZcfLbp?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=6">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>7. <a href="https://experts1.ru/vAyDxq?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=7">Python QA Engineer</a> | OTUS</b></p><p>Программа построена так, чтобы студенты научились работать с фреймворком PyTest, автоматизировать UI- и API-тесты, использовать Selenium 4 и Appium, проводить тестирование REST API и настраивать процессы в системах непрерывной интеграции. Выпускники осваивают запуск автотестов в CI/CD, анализ результатов и работу с инфраструктурой.</p><p>Преподаватели-практики объясняют материал на реальных кейсах и проводят вебинары с возможностью задавать вопросы и получать подробную обратную связь. Учебный процесс включает не только теорию, но и регулярные практические задания, работу с инструментами диагностики в Linux, а также итоговый проект, в рамках которого студенты создают собственный тестовый фреймворк, пишут UI- и API-тесты и защищают проект перед экспертами.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/bbca2fc4-0273-48b4-a6c9-e3cf586c9102.jpg" alt="" /></figure><ul><li>Стоимость: 121 000 руб. (есть рассрочка и налоговый вычет до 13%)</li><li>Длительность: 6 месяцев</li><li>Формат обучения: вебинары дважды в неделю, доступ к записям и материалам, практические задания, выпускной проект, поддержка в закрытом чате</li><li>Сертификат: официальный сертификат OTUS о прохождении курса</li></ul><p><b>Кому подойдет:</b> ручным тестировщикам, желающим освоить автоматизацию; специалистам, работающим с другими языками, и планирующим перейти на Python; QA-инженерам, которые хотят углубить знания и систематизировать навыки.</p><p><b>Преимущества</b></p><ul><li>упор на практику с реальными кейсами;</li><li>изучение PyTest как основного фреймворка;</li><li>работа с Selenium 4 и Appium;</li><li>тестирование REST API;</li><li>освоение DevOps-практик;</li><li>использование Linux для диагностики;</li><li>обучение у экспертов-практиков;</li><li>участие в живых вебинарах;</li><li>обратная связь по домашним заданиям;</li><li>доступ к закрытому сообществу;</li><li>выпускной проект для портфолио;</li><li>доступ к репозиторию с примерами тестов;</li><li>возможность оплаты курса работодателем.</li></ul><p><b>Недостатки</b></p><ul><li>обязательное вступительное тестирование перед началом;</li><li>курс рассчитан на студентов с базовыми знаниями Python;</li><li>высокая учебная нагрузка (две вечерние сессии в неделю).</li></ul><p><b>Программа обучения</b></p><ul><li>Введение в автоматизацию тестирования</li><li>Тестирование API</li><li>Тестирование UI</li><li>DevOps</li><li>Мобильное тестирование</li><li>Работа с бэкендом</li><li>Другие виды тестирования</li><li>Подготовка к поиску работы</li><li>Проектный модуль и защита выпускного проекта</li></ul><p><a href="https://experts1.ru/vAyDxq?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=7">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>8. <a href="https://experts1.ru/JvBnrm?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=8">Автоматизатор тестирования на Java</a>  | Яндекс Практикум</b></p><p><i>Купите любой курс с выгодой до 20% при оплате сразу или получите скидку 7% за прохождение бесплатной части курса за неделю</i></p><p><a href="https://experts1.ru/JvBnrm?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=8">Получить скидку &gt;&gt;&gt;</a></p><p>В рамках курса студенты осваивают основы языка Java, учатся писать код и применять его для создания автотестов для веб-приложений и API. Программа включает популярные инструменты тестировщика: IntelliJ IDEA, Maven, Git, Selenium WebDriver, Selenide, JUnit, Postman, REST Assured, Allure и Jenkins. Шаг за шагом слушатели погружаются в процесс автоматизации — от базовых конструкций и написания юнит-тестов до разработки архитектуры тестирования и построения полноценного пайплайна CI/CD.</p><p>Отдельные блоки посвящены тестированию интерфейсов, API и баз данных, а также внедрению подхода Behavior-Driven Development с использованием Cucumber и Gherkin. На занятиях студенты выполняют проекты, максимально приближенные к реальным задачам индустрии, и получают обратную связь от опытных специалистов. Завершающим этапом курса становится итоговая работа, где необходимо покрыть автотестами веб-приложение, API и написать юнит-тесты, объединяя все полученные навыки.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/fb12096a-308f-4908-b879-89069335f240.jpg" alt="" /></figure><ul><li>Стоимость: от 4 204 руб. в месяц (есть рассрочка и налоговый вычет)</li><li>Длительность: 5–6 месяцев (в зависимости от тарифа)</li><li>Формат обучения: онлайн-лекции, интерактивные задания в тренажере, вебинары каждые 2 недели, проекты для портфолио, индивидуальные встречи с наставником, обратная связь от экспертов</li><li>Сертификат: диплом о профессиональной переподготовке</li></ul><p><b>Кому подойдет: </b>ручным тестировщикам, которые хотят перейти в автоматизацию; junior-специалистам, готовым укрепить навыки и освоить Java; действующим QA-инженерам, планирующим карьерный рост.</p><p><b>Преимущества</b></p><ul><li>освоение Java с нуля;</li><li>обучение работе с IntelliJ IDEA и Maven;</li><li>практика с Git и GitHub;</li><li>изучение юнит-тестирования на JUnit 5;</li><li>знакомство с Mockito и DI;</li><li>написание автотестов с Selenium и Selenide;</li><li>тестирование интерфейсов через DevTools;</li><li>автоматизация API с использованием Postman и REST Assured;</li><li>отчетность в Allure;</li><li>построение пайплайнов CI/CD в Jenkins;</li><li>работа с Docker и Kubernetes;</li><li>освоение BDD и Cucumber;</li><li>проектная работа для портфолио.</li></ul><p><b>Недостатки</b></p><ul><li>требуется регулярное выделение времени (не менее 15 часов в неделю);</li><li>часть материалов доступна только в расширенной версии.</li></ul><p><b>Программа обучения</b></p><ul><li>Введение в профессию и основы Git</li><li>Изучение Java: базовый и продвинутый уровни</li><li>Объектно-ориентированное программирование и базовые конструкции</li><li>Юнит-тестирование и работа с JUnit, Mockito</li><li>UI-тестирование на Selenium и Page Object Model</li><li>Тестирование API с Postman, Swagger, REST Assured</li><li>Работа с базами данных и SQLCI/CD, Docker, Kubernetes, Jenkins</li><li>Behavior-Driven Development с Cucumber и Gherkin</li><li>Работа с асинхронными сервисами и Kafka</li><li>Итоговый проект и защита работы</li></ul><p><a href="https://experts1.ru/JvBnrm?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=8">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>9. <a href="https://experts1.ru/MLhyjk?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=9">Инженер по автоматизированному тестированию на JavaScript</a> | Хекслет</b></p><p>С первых занятий студенты начинают программировать на JavaScript, осваивают построение автотестов и их применение к реальным веб-приложениям. Вы научитесь работе с Playwright и Jest, а также интеграционному, модульному и e2e-тестированию. Обучение построено на практических заданиях и проектах: студенты пишут автотесты для учебных сервисов, работают с Git, осваивают CI/CD и Docker, создавая полноценные проекты для портфолио.</p><p>Теоретическая часть подается в доступной форме и дополнена большим количеством упражнений для закрепления материала. Учебный процесс сопровождают практикующие инженеры по тестированию, которые помогают разбираться в сложных темах и корректируют траекторию обучения. Финальный акцент сделан на самостоятельной реализации тестов, проверке приложений с разных сторон и работе с инструментами анализа качества, что позволяет выпускникам выйти на рынок с реальными навыками автоматизации.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/a4e6e2c0-6d6f-4e26-8626-c6cbc54317d9.jpg" alt="" /></figure><ul><li>Стоимость: от 85 000 руб. (есть рассрочка и акции)</li><li>Длительность: 8 месяцев</li><li>Формат обучения: теория в текстовом и видеоформате, практические задания, проекты на GitHub, домашние упражнения, вебинары, код-ревью и наставничество</li><li>Сертификат: официальный документ Хекслета, ценимый работодателями</li></ul><p><b>Кому подойдет: </b>ручным тестировщикам, которые переходят в автоматизацию; айти-специалистам, решившим сменить направление; действующим инженерам по тестированию для обновления знаний.</p><p><b>Преимущества</b></p><ul><li>упор на практику с первых занятий;</li><li>изучение JavaScript в контексте тестирования;</li><li>освоение Playwright для UI-тестов;</li><li>работа с Jest и Vitest для модульного тестирования;</li><li>интеграция Git и командной строки в учебный процесс;</li><li>проекты с реальными бизнес-задачами;</li><li>портфолио на GitHub с завершенными проектами;</li><li>коммерческие задачи от партнеров;</li><li>наставничество от опытных инженеров;</li><li>карьерное сопровождение через Хекслет.Карьеру;</li><li>подготовка резюме и собеседований;</li><li>поддержка при трудоустройстве;</li><li>возможность академического отпуска при необходимости.</li></ul><p><b>Недостатки</b></p><ul><li>интенсивный формат может быть сложен для новичков;</li><li>часть проектов предполагает самостоятельное погружение без пошаговых инструкций.</li></ul><p><b>Программа обучения</b></p><ul><li>Основы JavaScript и настройка окружения</li><li>Работа с Git и командной строкой</li><li>Юнит- и интеграционное тестирование на Jest</li><li>Асинхронное программирование и тестирование API</li><li>E2E-тестирование с Playwright</li><li>Работа с HTML, CSS и DOM API</li><li>Тестирование бэкенда и взаимодействие с базами данных</li><li>CI/CD и основы Docker</li><li>Учебные и коммерческие проекты для портфолио</li><li>Итоговый проект с полной автоматизацией веб-приложения</li></ul><p><a href="https://experts1.ru/MLhyjk?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=9">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><p><b>10. <a href="https://experts1.ru/xomLeC?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=10">Автоматизатор тестирования на Python</a> | Яндекс Практикум</b></p><p><i>Купите любой курс с выгодой до 20% при оплате сразу или получите скидку 7% за прохождение бесплатной части курса за неделю</i></p><p><a href="https://experts1.ru/xomLeC?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=10">Получить скидку &gt;&gt;&gt;</a></p><p>Студенты осваивают базовый синтаксис Python и сразу начинают применять его для написания автотестов. Программа включает работу с pytest, Selenium WebDriver, Allure, Git, DevTools, а также использование XPath и CSS-локаторов. Вас научат архитектуре приложений, методам тестирования API и организации тестовых сценариев. Обучение строится на практике: студенты создают проекты для портфолио, покрывают тестами веб-приложения, API и пишут юнит-тесты с использованием моков, стабов и Spy. Курс разработан опытными инженерами по тестированию из Яндекса и других крупных IT-компаний, что гарантирует актуальность материалов и их связь с реальной индустрией.</p><p>Теоретический материал подается в удобной форме и закрепляется интерактивными заданиями в тренажере, а регулярные вебинары позволяют разбирать сложные кейсы вместе с экспертами. В результате выпускники получают навыки построения процессов автоматизации, работы с CI/CD и Docker, а также опыт создания комплексных отчетов о тестировании. Дополнительно студенты формируют портфолио с реальными проектами, которое подтверждает их компетенции перед работодателями.</p><figure><img src="https://media.tproger.ru/user-uploads/108137/2025-10-06/05ce0e14-08f1-4391-bfe7-4f2cd4e638b5.jpg" alt="" /></figure><ul><li>Стоимость: от 4 204 руб. в месяц (есть рассрочка и налоговый вычет)</li><li>Длительность: 5–6 месяцев (в зависимости от тарифа)</li><li>Формат обучения: видеолекции и текстовые материалы, тренажер для практики, домашние задания, вебинары каждые 2 недели, проекты для портфолио, обратная связь от наставников</li><li>Сертификат: диплом о профессиональной переподготовке или справка об обучении</li></ul><p><b>Кому подойдет:</b> ручным тестировщикам, стремящимся перейти в автоматизацию; инженерам QA, которые хотят повысить квалификацию; айти-специалистам, решившим освоить новое направление.</p><p><b>Преимущества</b></p><ul><li>обучение на Python с нуля;</li><li>освоение pytest для юнит-тестов;</li><li>практика с Selenium WebDriver;</li><li>работа с DevTools и XPath;</li><li>создание отчетов в Allure;</li><li>тестирование API с Postman и Swagger;</li><li>изучение принципов архитектуры приложений;</li><li>работа с базами данных и SQL;</li><li>освоение CI/CD и Docker;</li><li>практика в реальных проектах;</li><li>7–10 проектов для портфолио;</li><li>доступ к вебинарам и Q&amp;A-сессиям;</li><li>поддержка наставников и экспертов Яндекса.</li></ul><p><b>Недостатки</b></p><ul><li>высокая нагрузка (нужно минимум 15 часов в неделю);</li><li>часть тем и проектов доступна только в расширенной версии;</li><li>полностью онлайн-формат без живых встреч;</li><li>для новичков могут быть сложны темы ООП и CI/CD.</li></ul><p><b>Программа обучения</b></p><ul><li>Введение и знакомство с Git</li><li>Основы Python и базовые конструкции</li><li>Объектно-ориентированное программирование</li><li>Инкапсуляция и обработка исключений</li><li>Юнит-тестирование с использованием pytest</li><li>UI-тестирование на Selenium и DevTools</li><li>Применение Page Object Model и Allure</li><li>Тестирование API и работа с Postman, Swagger</li><li>Основы архитектуры и организация процессов тестирования</li><li>Итоговый проект с полной автоматизацией веб-приложения</li><li>Дополнительный модуль по SQL и тестированию баз данных</li><li>CI/CD и работа с Docker (в расширенной версии)</li></ul><p><a href="https://experts1.ru/xomLeC?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=10">Ознакомиться с полной программой &gt;&gt;&gt;</a></p><h2>Еще 4 курса по автоматизации тестирования</h2><p>Я нашла также дополнительные курсы по автоматизации тестирования, которые помогут освоить востребованные инструменты и навыки для построения карьеры в QA. Эти программы отличаются форматом, длительностью и набором технологий, но все они ориентированы на практику и подготовку к работе с реальными проектами.</p><ul><li><a href="https://experts1.ru/hfDcaI?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">QA-инженер по тестированию: с нуля до автоматизатора</a> от «Хекслета». Курс построен так, чтобы с нуля подготовить специалиста к профессии QA-инженера и постепенно довести его до уровня автоматизатора на JavaScript. В программе много практики: студенты тестируют реальные веб- и мобильные приложения, пишут баг-репорты, создают автотесты с использованием Vitest и Playwright, осваивают работу с API и SQL. Обучение сопровождается проектами для портфолио и консультациями наставников, а завершение курса подтверждается сертификатами по двум профессиям.</li><li><a href="https://experts1.ru/mlKQav?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Тестировщик в IT</a> от Yagla. Курс рассчитан на тех, кто хочет быстро войти в IT и освоить профессию тестировщика с нуля. Программа охватывает ручное и автоматизированное тестирование, работу с базами данных, инструментами Git, SQL, Selenium, Postman и другими технологиями. Обучение построено на практике и реальных кейсах, к окончанию курса формируется портфолио и выдается сертификат, подтверждающий квалификацию.</li><li><a href="https://experts1.ru/HwfVya?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Тестирование с Pytest</a> от «Хекслета». Курс обучает работе с Pytest и современными техниками автоматизированного тестирования на Python. Студенты осваивают модульные тесты, фикстуры, подход TDD, а также продвинутые инструменты вроде моков, стабов и манкипатчинга. Занятия построены на практике с использованием виртуальной среды и автоматической проверкой решений, что позволяет сразу закреплять полученные знания.</li><li><a href="https://experts1.ru/vgbHtD?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Инженер по тестированию</a> от Skillbox. Программа готовит специалистов по ручному и автоматизированному тестированию с упором на современные ИИ-инструменты. В процессе обучения студенты осваивают Java, Python или JavaScript для написания автотестов, учатся работать с Postman, Selenium, SQL, Git и Unity, а также тестируют реальные проекты от компаний-партнеров. В курс добавлены блоки по тестированию мобильных приложений и игр, что расширяет возможности трудоустройства и формирует сильное портфолио.</li></ul><h2>Еще 2 курса по автоматизации тестирования на Java</h2><p>Если вы хотите углубить знания в автоматизации тестирования на Java, эти два курса станут отличным выбором. Они помогут закрепить навыки создания автотестов, работы с современными инструментами и подготовят к реальным задачам в IT-индустрии.</p><ul><li><a href="https://experts1.ru/ygJzmA?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Автоматизация тестирования ПО (Java). Basic</a> от Level Up. Курс знакомит с основами автоматизации тестирования на Java и учит применять популярные инструменты вроде Selenium, Selenide, Cucumber, JUnit и RestAssured. Обучение построено на сочетании теории и практики, предполагает работу с CI/CD и Jenkins, а также формирование базовых навыков написания автотестов. По окончании программы студенты получают представление о роли инженера по автоматизации и приобретают навыки, достаточные для работы на позиции junior.</li><li><a href="https://experts1.ru/kxMyQe?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Автоматизированное тестирование ПО на Java </a>от Университета «Иннополис». Программа знакомит с автоматизацией тестирования на Java и учит работать с ключевыми инструментами — Selenium, Selenide, RestAssured, Docker и CI/CD. Студенты осваивают написание автотестов для UI и API, работу с базами данных и основы BDD. Обучение построено на практических заданиях и завершается дипломом о профессиональной переподготовке, что позволяет претендовать на позиции AQA-инженера.</li></ul><h2>Еще 4 курса по автоматизации тестирования на Python</h2><p>Для тех, кто уже знаком с основами автоматизации тестирования на Python, мы подготовили подборку еще четырех курсов. Они помогут прокачать навыки, освоить новые инструменты и получить опыт работы с реальными проектами.</p><ul><li><a href="https://experts1.ru/mXLcjl?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Автоматизация тестирования на Python</a> от «Контур.Школы». Программа обучает автоматизации тестирования на Python и помогает создавать автотесты для API, мобильных и веб-приложений. В процессе занятий студенты осваивают PyTest, Selenium, а также принципы Page Object Model. Курс сочетает теорию с практическими задачами и завершается итоговым тестом, после которого выдается официальный документ о повышении квалификации.</li><li><a href="https://experts1.ru/EzpixF?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Тестировщик на Python</a> от SkillFactory. Программа обучает ручному и автоматизированному тестированию, в том числе работа с Python, PyTest, Selenium, SQL и REST API. В процессе обучения студенты выполняют проекты от реальных компаний, составляют баг-репорты и тест-кейсы, проходят практику на коммерческих сервисах. По окончании выдается диплом о профессиональной переподготовке или сертификат, что позволяет претендовать на позиции тестировщика и QA-инженера.</li><li><a href="https://experts1.ru/wgraUY?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Автоматизированное тестирование на Python</a> от EasyUM. Курс помогает освоить автоматизацию тестирования на Python с нуля и шаг за шагом перейти к созданию автотестов для веб-приложений и API. В программе есть работа с PyTest, Selenium, Docker и Jenkins, а также основы DevOps. Обучение построено на практике, есть реальные задания и проекты для портфолио, а по завершении выдается сертификат и проводится подготовка к трудоустройству.</li><li><a href="https://experts1.ru/sJUxmi?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Автоматизированное тестирование на Python</a> от Teachmeskills. Курс учит создавать автотесты на Python с использованием Selenium, PyTest, Docker и Jenkins. В процессе обучения студенты осваивают тестирование API и веб-приложений, а также работу с базами данных и Linux. Программа построена на практике, предполагает также разработку реального проекта для портфолио и завершается защитой диплома с поддержкой в трудоустройстве.</li></ul><h2>Бесплатные курсы по автоматизации тестирования</h2><p>Также нашла бесплатные курсы по автоматизации тестирования, которые подойдут для первого знакомства с профессией. Подобные программы помогают без вложений попробовать себя в написании автотестов и понять, насколько эта сфера интересна. Бесплатный формат удобен для начинающих, а полученные знания можно развить уже на более серьезных учебных программах.</p><p><b>1. <a href="https://experts1.ru/eavRjG?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Легкий старт в профессию тестировщика</a> — Skillbox</b></p><p>Этот интенсив подойдет новичкам, которые хотят попробовать себя в тестировании и понять, насколько им близка эта профессия. За несколько дней слушатели познакомятся с базовыми принципами ручного и автоматизированного тестирования, узнают о юзабилити и стандартах работы в IT-компаниях. Участники получат практику в поиске ошибок, составлении баг-репортов и запуске первых автотестов с помощью Selenium IDE. Такой формат обучения позволяет быстро погрузиться в профессию и сформировать первые навыки.</p><p><b>Главное о курсе:</b></p><ul><li>знакомство с процессами тестирования и профессией QA;проведение первых автотестов с использованием Selenium IDE;</li><li>освоение правил юзабилити и нефункционального тестирования;</li><li>практика в составлении баг-репортов и работе с ошибками;</li><li>выполнение интерактивных заданий на реальных примерах.</li></ul><p><b>2. <a href="https://experts1.ru/jGkVus?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Основы Java для автоматизации тестирования</a> — Stepik</b></p><p>Курс рассчитан на тех, кто хочет освоить Java с нуля и в дальнейшем применять его для автоматизации тестирования. Он подойдет будущим тестировщикам-автоматизаторам, а также всем, кто хочет разобраться в основах языка и понять, стоит ли продолжать обучение. Программа построена так, чтобы постепенно освоить ключевые элементы Java, научиться работать с ООП и закрепить знания практикой. Обучение проходит в удобном темпе и позволяет вернуться к материалам в любое время.</p><p><b>Главное о курсе:</b></p><ul><li>базовые знания языка Java и основы ООП;</li><li>создание первых программ и работа с массивами, строками и классами;</li><li>использование принципов инкапсуляции, наследования и полиморфизма;</li><li>практика обработки исключений и документирования кода;</li><li>более 70 часов обучения с тестами и интерактивными заданиями.</li></ul><p><b>3. <a href="https://experts1.ru/jdXwqC?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Тестировщик программного обеспечения: с нуля до первых проектов</a> — «Содействие занятости»  </b></p><p>Курс предназначен для тех, кто хочет освоить профессию тестировщика с нуля и получить востребованные навыки работы с современными инструментами. Он подойдет людям, ищущим работу, желающим сменить профессию или повысить квалификацию. Программа дает понимание основ тестирования, практику работы с SQL и Postman, а также опыт оформления баг-репортов. Обучение бесплатное, проводится онлайн и завершается выдачей документа установленного образца.</p><p><b>Главное о курсе:</b></p><ul><li>знакомство с базовыми принципами тестирования ПО;</li><li>работа с тестовой документацией и баг-репортами;</li><li>практика в SQL и тестировании API через Postman;</li><li>использование инструментов Jira, Яндекс Трекера, TestRail и DevTools;</li><li>выполнение итогового проекта и получение удостоверения о квалификации.</li></ul><p><b>4. <a href="https://experts1.ru/ubEkcF?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Автоматизация тестирования с помощью Selenium и Python</a> — Stepik</b></p><p>Курс рассчитан на начинающих специалистов в тестировании, которые хотят перейти к автоматизации и освоить работу с Python и Selenium. Он подойдет тем, кто уже знаком с базовой терминологией QA и хочет научиться писать автотесты для веб-интерфейсов. Программа помогает освоить популярные фреймворки, применить хорошие практики проектирования тестов и получить навыки, востребованные на рынке. Обучение бесплатное и завершается сертификатом.</p><p><b>Главное о курсе:</b></p><ul><li>написание автотестов на Python с использованием Selenium;</li><li>работа с веб-элементами и построение стабильных тестов;</li><li>применение pytest и других фреймворков для автоматизации;</li><li>использование паттерна PageObject для удобной поддержки сценариев;</li><li>практика работы с git и Github.</li></ul><p><b>5. <a href="https://experts1.ru/UdirwN?sub1=tproger-kf&amp;sub2=kursy-po-avtomatizaczii-testirovaniya&amp;sub4=netop">Тесты и тренажеры для тестировщиков</a> — LearnQA </b></p><p>Курс подойдет тем, кто только начинает путь в тестировании и хочет оценить свой уровень знаний или закрепить основы на практике. Он поможет проверить понимание популярных инструментов, выявить пробелы и подготовиться к собеседованиям. Формат построен так, чтобы студент мог не только пройти теорию, но и потренироваться в симуляторах реальных задач. Такой подход позволяет получить уверенность перед стартом карьеры.</p><p><b>Главное о курсе:</b></p><ul><li>тесты по Git, SQL, Java, Bash и базовым знаниям IT;</li><li>тренажеры с эмуляцией рабочих ситуаций и поиском багов;</li><li>подготовка к собеседованиям через практические задания;</li><li>возможность закрепить знания и проверить себя в удобном формате.</li></ul><h2>Видеоуроки по автоматизации тестирования</h2><p>Я предлагаю не игнорировать, а просмотреть и видеоуроки по автоматизации тестирования, чтобы еще глубже понять тему. Это дает возможность наглядно увидеть процесс работы и повторить действия за преподавателем. Видео поможет закрепить теорию и быстрее перейти к практике.</p><ol><li><a href="https://www.youtube.com/playlist?list=PLhoN48bkW44GNtpS3qUvCHXbBCVEGZjRG">Введение в автоматизацию для QA</a> — Simple Automation. Плейлист подойдет тем, кто хочет разобраться в автоматизации тестирования с нуля и получить базовые навыки работы с основными инструментами. Видеоуроки построены последовательно — от теории и языка Java до работы с Git, Maven, JUnit, REST Assured и Selenium WebDriver. Такой формат помогает шаг за шагом освоить практику и закрепить знания через наглядные примеры.</li><li><a href="https://www.youtube.com/playlist?list=PLB2iiSfKWtvykq9s0plSVI_Du60i0iphU">Автоматизация тестирования с Pytest и Python</a> — SolveMe. Плейлист подойдет тем, кто хочет научиться работать с Pytest и применять Python для автоматизации тестирования на практике. В уроках разбираются базовые приемы написания автотестов, работа с фикстурами, декораторами и генерацией отчетов. Отдельные видео посвящены использованию Pydantic, SQLAlchemy и Docker, что позволяет получить более глубокое понимание современного тестирования.</li><li><a href="https://www.youtube.com/playlist?list=PLZqgWWF4O-ziBZVXN19WcRHPM5DkH672c">Автоматизация тестирования java + selenium webdriver</a> — Алексей Маршал. Плейлист поможет тем, кто хочет освоить автоматизацию тестирования на Java с использованием Selenium WebDriver. В видеоуроках объясняются основы работы с DOM, локаторами, XPath и CSS-селекторами, а также показано, как взаимодействовать с элементами интерфейса. Отдельное внимание уделяется ожиданиям, работе с модальными окнами, вкладками браузера и построению фреймворка на основе PageObject.</li><li><a href="https://www.youtube.com/playlist?list=PLu2jtpHCDMuvb2o_uQesvGZEzbovgz_3i">Автоматизация на пальцах</a> — Стас Пешкур. Плейлист создан для тех, кто хочет разобраться в автоматизации тестирования на практике и понять ее основы простым языком. В видео разбираются ключевые инструменты и подходы, работа с API-тестами, использование Rest Assured, Cucumber, Selenide и Page Object. Также показаны примеры настройки Maven, Jenkins и Gitlab CI/CD, создания отчетов в Allure и отладки кода на реальных задачах.</li><li><a href="https://www.youtube.com/playlist?list=PLSf2MMXhdBGqMmU6R3pObw223LesJ9ddl">QA с нуля</a> — Александр Хвастович. Этот плейлист подойдет тем, кто только начинает путь в тестировании и хочет понять основы профессии с нуля. В видеоуроках разбираются ключевые темы — от базовых принципов QA и методологий разработки до тестовой документации, работы с Jira, Git и SQL. Формат построен так, чтобы постепенно вести новичка от теории к первым практическим навыкам и подготовке к старту карьеры в IT.</li></ol><h2>Часто задаваемые вопросы (FAQ)</h2><p>Курсы по автоматизации тестирования на Python стабильно занимают верхние позиции в рейтингах IT-обучения. Это объясняется сочетанием доступности языка, высокой востребованности специалистов и тем, что такие программы рассчитаны даже на новичков без опыта. Мы собрали ответы на самые популярные вопросы, которые помогают понять, чего ожидать от обучения и как строится процесс подготовки.</p><h4>Почему именно курсы по автоматизации тестирования на Python пользуются наибольшим спросом среди новичков в IT?</h4><p>Python отличается простым синтаксисом и богатым набором инструментов для тестирования. В курсах Skillbox и Яндекс Практикума студенты начинают с основ языка и сразу переходят к работе с Pytest и Selenium, что позволяет быстро освоить профессию и собрать портфолио.</p><h4>За какой срок реально перейти от нуля до трудоустройства в профессии тестировщика-автоматизатора на Python?</h4><p>Срок зависит от программы: от 5–6 месяцев в Яндекс Практикуме и OTUS до года в Skypro. Нетология предлагает 14-месячное обучение с углублением в ручное тестирование, автоматизацию и нейросети. Такой диапазон позволяет выбрать формат в зависимости от целей и доступного времени.</p><h4>Что конкретно умеют делать после завершения курса по автоматизации тестирования на Python выпускники профильных программ?</h4><p>Выпускники осваивают написание UI- и API-тестов, создание отчетов в Allure, работу с Jenkins, Docker и CI/CD. В Нетологии студенты дополнительно учатся использовать Cypress и Playwright, а в Skillbox углубляются в DevOps-практики и архитектуру тестов.</p><h4>Выбор курса: предпочесть программу с гарантией трудоустройства или сосредоточиться на содержании и уровне подготовки?</h4><p>Skypro и Нетология предоставляют карьерное сопровождение и помощь в поиске работы. В OTUS и Хекслете акцент делается на практических проектах и формировании портфолио. Поэтому выбор зависит от того, что важнее — поддержка в трудоустройстве или глубина подготовки.</p><h4>На каких инструментах делают упор в программах по автоматизации тестирования: Selenium, Pytest или другие решения?</h4><p>Почти в каждом курсе присутствуют Selenium и Pytest. В GeekBrains+Skillbox акцент дополнен Postman, SQL и Jira. В Хекслете главными инструментами становятся Playwright и Jest, а в Нетологии изучают также Cypress и Puppeteer.</p><h4>Подойдут ли курсы по автоматизированному тестированию тем, у кого нет технического образования?</h4><p>Да, большинство программ рассчитано на новичков. В Skypro и Яндекс Практикуме есть вводные блоки по основам тестирования и Python, а в Skillbox добавлены модули Python Basic и Advanced.</p><h4>Нужен ли практический опыт ручного тестирования прежде чем переходить к автоматизации тестов ПО?</h4><p>Некоторые школы начинают именно с ручного тестирования. В Нетологии и Skypro студенты сначала осваивают баг-репорты и тест-дизайн, а затем переходят к автоматизации. В OTUS требуется базовое знание Python, поэтому упор сразу делается на автотесты.</p><h4>Какие карьерные возможности открывает освоение автоматизации тестирования веб-приложений?</h4><p>Выпускники курсов могут претендовать на должности QA Automation Engineer или Python QA Engineer. Например, в GeekBrains+Skillbox студенты учатся работать с CI/CD и SQL, а в Яндекс Практикуме формируют портфолио из 10 проектов, что помогает быстрее выйти на рынок.</p><h4>Включают ли топовые школы обучение API-тестированию в базовую образовательную программу?</h4><p>Да, API-тестирование есть почти в каждом курсе. В Skypro студенты осваивают Postman и SoapUI, в OTUS работают с REST Assured, а в Яндекс Практикуме применяют Postman и Swagger.</p><h4>Содержат ли современные образовательные программы модуль по работе с базами данных и изучению SQL для автоматизаторов?</h4><p>Да, SQL включен в программы большинства школ. В Skillbox есть отдельный модуль для работы с базами, в Нетологии SQL используется в нагрузочном тестировании, а в Яндекс Практикуме он входит в базовую часть курса.</p><h4>Какие практические работы включают в портфолио выпускники программ по автоматизированному тестированию?</h4><p>Это проекты с автотестами для веб-приложений, API и мобильных сервисов, отчеты в Allure и кейсы с CI/CD. В OTUS выпускники создают собственный фреймворк, в Хекслете портфолио публикуется на GitHub, а в Яндекс Практикуме итоговый проект объединяет UI-, API- и юнит-тесты.</p><p>Профессия тестировщика-автоматизатора остается одной из самых востребованных в IT. Начинающие специалисты могут рассчитывать на зарплату от 70 000–90 000 руб., а опытные инженеры в крупных городах, особенно с навыками Python, Java и современными фреймворками, зарабатывают от 250 000 руб. и выше. Автоматизация открывает путь к стремительному карьерному росту, ведь компании ценят специалистов, которые умеют экономить ресурсы и ускорять выпуск продуктов. Выбирая курсы по автоматизации тестирования, важно обращать внимание на практическую часть, количество проектов и поддержку экспертов — это ключ к формированию портфолио и реальным навыкам, которые сразу пригодятся на рынке труда.</p><p><i>А теперь хочу услышать ваше мнение: поделитесь в комментариях, какие курсы по автоматизации тестирования вам показались наиболее полезными и эффективными, и что помогло вам быстрее освоить профессию.</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Лучшие практики для ускорения фронтенда: чек-лист 2025 года</title>
      <link>https://tproger.ru/articles/luchwie-praktiki-dlya-uskoreniya-frontenda--chek-list-2025-goda</link>
      <comments>https://tproger.ru/articles/luchwie-praktiki-dlya-uskoreniya-frontenda--chek-list-2025-goda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/luchwie-praktiki-dlya-uskoreniya-frontenda--chek-list-2025-goda</guid>
      <description><![CDATA[<p>Ускорьте свой сайт с помощью чек-листа по оптимизации фронтенда: от HTML и CSS до изображений и серверов. Практические советы для повышения скорости, SEO и конверсий в 2025 году.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/luchwie-praktiki-dlya-uskoreniya-frontenda--chek-list-2025-goda">Лучшие практики для ускорения фронтенда: чек-лист 2025 года</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[Дизайн интерфейсов и UX]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 03 Oct 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Это перевод <a href="https://crystallize.com/blog/frontend-performance-checklist">статьи</a> с сайта компании Crystallize. Можете поделиться своим мнением в комментариях!</p><h2>Почему скорость сайта так важна</h2><p>В мире, где внимание пользователей <a href="https://time.com/3858309/attention-spans-goldfish/">рассеивается</a> за восемь секунд, быстрая загрузка сайта становится критически важной. Статистика подтверждает: <a href="https://www.thinkwithgoogle.com/consumer-insights/consumer-trends/mobile-site-load-time-statistics/#:~:text=Google%20www.thinkwithgoogle.com%20%2053,statistics%20on%20Think%20with%20Google">53% мобильных пользователей покидают сайт</a>, если он грузится дольше 3 секунд, а 70% потребителей <a href="https://unbounce.com/page-speed-report/#:~:text=Nearly%2070%25%20of%20consumers%20admit%20that%20page%20speed%20influences%20their,time%20is%20slower%20than%20expected.">отмечают</a>, что скорость влияет на их решение о покупке. Walmart, например, <a href="https://wpostats.com/2015/11/04/walmart-revenue/#:~:text=Walmart%20saw%20up%20to%20a,increase%20in">зафиксировал</a> рост конверсий на 2% за каждую секунду сокращения времени загрузки.</p><p>Быстрые сайты обеспечивают:</p><ul><li>Долгое пребывание пользователей на сайте;</li><li>Больше просмотров страниц благодаря быстрой навигации;</li><li>Меньше отказов из-за медленных загрузок;</li><li>Выше конверсии и доходов, так как скорость напрямую влияет на покупки;</li><li>Лучшую удовлетворенность и удержание пользователей;</li><li>Рост органического трафика, так как Google учитывает Core Web Vitals в SEO-ранжировании;</li><li>Экономию на CDN и трафике, ведь оптимизированные сайты потребляют меньше данных;</li><li>Повышение качества рекламы в Google Ads, так как быстрые страницы снижают стоимость кликов.</li></ul><p>Оптимизация фронтенда — это не просто техническая задача, а способ повысить лояльность пользователей и бизнес-показатели.</p><h2>Как измерить производительность сайта</h2><p>Прежде чем оптимизировать, <a href="https://crystallize.com/blog/frontend-performance-measuring-and-kpis">измерьте</a> текущую производительность сайта, чтобы выявить узкие места. Используйте комбинацию лабораторных и полевых инструментов:</p><ul><li><a href="https://pagespeed.web.dev/">Google PageSpeed Insights</a>: быстрый аудит Core Web Vitals с рекомендациями.</li><li><a href="https://developers.google.com/web/tools/lighthouse">Chrome Lighthouse</a>: встроенный в DevTools инструмент для анализа производительности, SEO и лучших практик.</li><li><a href="https://www.webpagetest.org/">WebPageTest</a>: детализированные метрики, визуализация загрузки и советы по оптимизации.</li><li><a href="https://gtmetrix.com/">GTmetrix</a>: анализ скорости загрузки с рекомендациями.</li><li><a href="https://developer.chrome.com/docs/crux/methodology/tools">CrUX в Google Search Console</a>: реальные данные пользовательского опыта (Core Web Vitals) для SEO.</li></ul><p>Лабораторные инструменты дают контролируемые метрики, а мониторинг реальных пользователей (через <a href="https://github.com/GoogleChrome/web-vitals">Web Vitals JS</a>, <a href="https://www.speedcurve.com/">SpeedCurve</a> или <a href="https://calibreapp.com/">Calibre</a>) показывает, как сайт работает в реальных условиях. Это поможет определить приоритеты для оптимизации.</p><h2>Чек-лист оптимизации фронтенда 2025</h2><p>Производительность — это командная работа. Бэкенд должен быть масштабируемым, UX-дизайнеры — балансировать визуал и скорость, а фронтенд-разработчики — реализовывать оптимизированный код. Этот чек-лист подходит для любой платформы: от Next.js и Astro до WordPress и PHP. Адаптируйте его под ваш проект, уделяя внимание ключевым метрикам, таким как LCP, CLS и INP (новый показатель, заменивший FID в 2024 году).</p><h3>HTML</h3><p>HTML — основа страницы, и его оптимизация ускоряет загрузку и улучшает пользовательский опыт.</p><ul><li>Приоритизируйте критический HTML: доставляйте HTML для верхней части страницы первым, чтобы браузер начал рендеринг. Фреймворки вроде Next.js или Astro с SSR/SSG рендерят HTML на сервере, улучшая First Contentful Paint.</li><li>Удаляйте лишний код: уберите ненужные теги, комментарии и пробелы. Компактный HTML загружается быстрее, особенно в мобильных сетях.</li><li>Включите сжатие: используйте GZIP или Brotli, чтобы уменьшить размер HTML. Большинство серверов и CDN это поддерживают.</li><li>Оптимизируйте загрузку ресурсов: размещайте CSS в &lt;head&gt; для быстрого рендера, а скрипты — перед &lt;/body&gt; или с атрибутами async/defer, чтобы не блокировать разбор HTML.</li><li>Минимизируйте iframe: они загружают дополнительные страницы, замедляя сайт. Используйте loading="lazy" для iframe ниже линии сгиба или загружайте их по клику.</li></ul><p><b>Совет:</b> держите DOM компактным. Например, Astro разбивает страницы на «островки», минимизируя гидратацию JavaScript, что ускоряет рендеринг.</p><h3>CSS</h3><p>CSS может блокировать рендеринг, если не оптимизирован. Вот как сделать стили быстрее:</p><ul><li>Удаляйте неиспользуемый CSS: используйте PurgeCSS или Chrome DevTools, чтобы убрать мертвый код, особенно в проектах с Tailwind.</li><li>Модуляризуйте стили: разделяйте CSS по страницам или функциям, загружая только необходимое. Критические стили встраивайте в &lt;head&gt;, остальное загружайте асинхронно.</li><li>Избегайте @import: он создает дополнительные запросы и блокирует рендеринг. Используйте &lt;link rel="stylesheet"&gt; или объединяйте CSS при сборке.</li><li>Используйте критический CSS: встраивайте стили для верхней части страницы в HTML, а остальное загружайте позже (например, через media="print"). Инструменты вроде Critical помогут это автоматизировать.</li><li>Минимизируйте CSS: убирайте пробелы и комментарии с помощью Clean-CSS или cssnano.</li><li>Предварительно загружайте ключевые стили: используйте &lt;link rel="preload" as="style"&gt; для важных CSS-файлов.</li><li>Упрощайте селекторы: избегайте сложных вложенных цепочек, чтобы ускорить вычисления стилей. Например, .headline лучше, чем body div#main article h1.</li><li>Применяйте современный CSS: используйте content-visibility: auto для отложенного рендера контента за пределами экрана. Это ускоряет начальную загрузку и снижает потребление памяти.</li></ul><h2>JavaScript</h2><p>JavaScript часто замедляет страницы из-за объема и времени выполнения. Оптимизируйте его так:</p><ul><li>Заменяйте JS на HTML/CSS: используйте CSS-анимации, &lt;details&gt; или валидацию форм вместо JS, где возможно.</li></ul><ul><li>Минимизируйте фреймворки: избегайте тяжелых библиотек для простых задач. Проверяйте сторонние скрипты (аналитика, реклама) и удаляйте ненужные.</li><li>Разделяйте код: используйте динамический import() или возможности фреймворков для загрузки JS по необходимости.</li><li>Предварительно загружайте важные скрипты: используйте &lt;link rel="preload" as="script"&gt; для ключевых JS-файлов.</li><li>Применяйте async/defer: добавляйте эти атрибуты к &lt;script&gt;, чтобы не блокировать рендеринг. Defer сохраняет порядок выполнения, async подходит для независимых скриптов.</li><li>Минимизируйте JS: используйте UglifyJS или tree shaking для удаления неиспользуемого кода. Настраивайте сборку для ES-модулей.</li><li>Обновляйте зависимости: новые версии фреймворков (esbuild, SWC) часто быстрее. Используйте Renovate или Dependabot для автоматизации.</li><li>Выбирайте подходящий фреймворк: Next.js с React Server Components или Astro с «островковой» архитектурой сокращают объем JS на клиенте, ускоряя загрузку.</li></ul><h2>Изображения</h2><p>Изображения — один из главных факторов загрузки страниц. Оптимизируйте их так:</p><ul><li>Используйте правильный размер: не загружайте изображения больше, чем нужно для отображения. Инструменты вроде ImageMagick или Sharp помогут автоматизировать ресайз.</li><li>Применяйте адаптивные изображения: используйте &lt;img srcset&gt; или &lt;picture&gt; для доставки изображений в зависимости от устройства.</li><li>Сжимайте изображения: используйте ImageOptim, mozJPEG для JPEG, PNGQuant для PNG или SVGO для SVG.</li><li>Предварительно загружайте ключевые изображения: используйте &lt;link rel="preload" as="image"&gt; или fetchpriority="high" для баннеров, влияющих на LCP.</li><li>Откладывайте загрузку: добавляйте loading="lazy" для изображений ниже линии сгиба.</li><li>Используйте WebP/AVIF: эти форматы обеспечивают лучшее сжатие, чем JPEG/PNG. CDN и фреймворки вроде Next.js автоматизируют конвертацию.</li><li>Указывайте размеры: добавляйте width и height или CSS aspect-ratio, чтобы избежать сдвигов макета (CLS).</li><li>Автоматизируйте оптимизацию: используйте Next.js &lt;Image&gt;, Astro или CDN (Cloudinary, Imgix) для автоматической обработки изображений.</li></ul><h2>Видео</h2><p>Видео могут быть тяжелее изображений, поэтому требуют особого внимания:</p><ul><li>Сжимайте видео: используйте Handbrake для MP4/WebM, снижая битрейт или разрешение (например, 720p вместо 1080p).</li><li>Используйте современные кодеки: WebM (VP9) или AV1 обеспечивают лучшее сжатие, чем MP4 (H.264).</li><li>Настройте предварительную загрузку: используйте preload="metadata" или none для видео, чтобы не загружать лишние данные.</li><li>Откладывайте загрузку: применяйте loading="lazy" для iframe или загружайте видео по клику/прокрутке.</li><li>Удаляйте ненужное аудио: уберите звуковую дорожку из фоновых видео с помощью FFmpeg.</li><li>Используйте потоковую передачу: для длинных видео применяйте HLS или DASH для адаптивной загрузки.</li><li>Оптимизируйте сторонние видео: используйте облегченные встраивания (например, lite-youtube-embed) для YouTube/Vimeo.</li></ul><h2>Шрифты</h2><p>Пользовательские шрифты улучшают брендинг, но могут замедлить рендеринг. Оптимизируйте их так:</p><ul><li>Ограничьте количество шрифтов: используйте минимум семейств и начертаний, чтобы сократить запросы.</li><li>Применяйте WOFF2: этот формат компактнее TTF или WOFF и поддерживается всеми браузерами.</li><li>Предварительно подключайтесь к источникам: используйте &lt;link rel="preconnect"&gt; для Google Fonts или других хостов.</li><li>Используйте font-display: swap: это предотвращает FOIT (невидимый текст) и улучшает пользовательский опыт.</li><li>Избегайте сдвигов макета: подбирайте резервные шрифты с похожими метриками или используйте font-size-adjust.</li><li>Рассмотрите переменные шрифты: один файл заменяет несколько начертаний, снижая объем данных.</li><li>Используйте системные шрифты: они не требуют загрузки и работают мгновенно.</li></ul><h2>Хостинг и сервер</h2><p>Конфигурация сервера напрямую влияет на скорость загрузки:</p><ul><li>Используйте HTTPS: это не только безопасно, но и быстрее, благодаря HTTP/2+. Google учитывает HTTPS для SEO.</li><li>Сократите HTTP-запросы: удаляйте ненужные ресурсы и минимизируйте сторонние скрипты.</li><li>Перейдите на HTTP/2 или HTTP/3: HTTP/2 поддерживает мультиплексирование, HTTP/3 (QUIC) ускоряет соединение, особенно на мобильных сетях.</li><li>Используйте CDN: кэшируйте ресурсы на серверах по всему миру для снижения задержек.</li><li>Настройте кэширование: используйте Cache-Control для статических ресурсов и кэширование на уровне приложения.</li><li>Оптимизируйте сервер: держите TTFB ниже 200 мс, оптимизируя запросы к базе данных и вычисления.</li><li>Применяйте статическую генерацию: используйте SSG или ISR (Next.js) для доставки готовых HTML-страниц через CDN.</li></ul><h2>Быстрые улучшения</h2><p>Эти небольшие оптимизации дают заметный эффект:</p><ul><li>Избегайте сдвигов макета: резервируйте место для изображений, iframe и динамического контента, чтобы минимизировать CLS.</li><li>Используйте приоритеты: применяйте fetchpriority="high" для ключевых ресурсов и low для некритических.</li><li>Сократите сторонние запросы: откладывайте загрузку аналитики или рекламы до взаимодействия пользователя.</li><li>Используйте один протокол: избегайте смешанного контента (HTTP/HTTPS).</li><li>Настройте кэширование: используйте длительный max-age для статических ресурсов с хэшами в именах файлов.</li><li>Предварительно загружайте страницы: используйте &lt;link rel="prefetch"&gt; для вероятных переходов.</li><li>Применяйте Service Workers: кэшируйте ресурсы для мгновенной загрузки и оффлайн-доступа.</li></ul><p>Оптимизация фронтенда — это непрерывный процесс, который требует внимания всей команды. Скорость сайта напрямую влияет на пользовательский опыт, SEO и бизнес-показатели. Используйте этот чек-лист, чтобы выявить слабые места и сократить миллисекунды загрузки. Комбинируйте лабораторные тесты и мониторинг реальных пользователей, чтобы отслеживать прогресс. Сделайте скорость приоритетом — ваши пользователи и бизнес скажут спасибо!</p>]]></content:encoded>
    </item>
    <item>
      <title>10 VSCode расширений, которые реально повышают продуктивность</title>
      <link>https://tproger.ru/articles/10-vscode-raswirenij--kotorye-realno-povywayut-produktivnost</link>
      <comments>https://tproger.ru/articles/10-vscode-raswirenij--kotorye-realno-povywayut-produktivnost?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/10-vscode-raswirenij--kotorye-realno-povywayut-produktivnost</guid>
      <description><![CDATA[<p>Топ-10 расширений VSCode для повышения продуктивности: форматирование, тестирование API, управление проектами и многое другое. Ускорьте свою разработку с лучшими инструментами.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/10-vscode-raswirenij--kotorye-realno-povywayut-produktivnost">10 VSCode расширений, которые реально повышают продуктивность</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[SEO]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[BASIC]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Английский]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Vue]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 23 Sep 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Visual Studio Code — мощный редактор, который становится ещё лучше с правильными расширениями. В этой подборке мы собрали 10 инструментов, реально ускоряющих разработку: они избавляют от рутины и помогают сосредоточиться на главном — качественном коде.</p><h2>1. TabNine</h2><p>Если вам важна скорость — <a href="https://www.tabnine.com/">TabNine</a> стоит попробовать хотя бы ради этого. Расширение —  лёгкий AI-ассистент, который работает как умный автодополнитель кода, непохожий на аналоги вроде Codeium или Copilot.</p><p>TabNine обучен на миллионах строк открытого кода и умеет предсказывать, что вы напишете дальше, с учётом контекста проекта и языка. Отлично справляется с рутинными вещами: автозавершает функции, переменные, конструкции — всё быстро и чаще всего в тему.</p><p><b>Кому подойдёт</b>: тем, кто хочет ускорить набор кода, но не готов передавать весь проект в облако или открывать чат с Copilot. Поддерживает офлайн-режим и локальное обучение модели.</p><p>Плюсы:</p><ul><li>Работает из коробки, не требует тонкой настройки;</li><li>Есть локальная версия — удобно для закрытых проектов;</li><li>Поддерживает большинство языков и фреймворков.</li></ul><p><b>Чем полезен:</b> экономит время на повседневной разработке — особенно когда вы не хотите отвлекаться на документацию или поиск нужной переменной в другом файле.</p><h2>2. GitLens</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens">GitLens</a> встраивает историю изменений прямо в VSCode — и делает это максимально удобно. Показывает, кто и когда изменил строку, коммит-месседж, хэш, ветку и другие детали. Можно не уходить в консоль или отдельный Git-клиент для поиска информации.</p><p>Особенно полезен, когда работаете с чужим кодом или хотите быстро вспомнить, зачем вы сами что-то написали месяц назад.</p><p><b>Кому подойдёт</b>: тем, кто работает в команде, часто читает историю изменений или ревьюит чужие коммиты. Также пригодится в проектах с долгой историей или нестабильным кодом.</p><p>Плюсы:</p><ul><li>Информация о коммитах отображается прямо в редакторе под строкой;</li><li>Есть таймлайн изменений файла;</li><li>Удобный diff по коммитам, авторам, веткам и даже фрагментам кода.</li></ul><p><b>Чем полезен:</b> помогает быстрее разбираться в чужом коде, искать причины бага или откатывать ошибки. Особенно ценится за то, что делает Git прозрачным и доступным прямо в процессе разработки.</p><h2>3. Error Lens</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=usernamehw.errorlens">Error Lens</a> выводит диагностику ошибок и предупреждений прямо в строке кода. Это расширение превращает сообщения линтеров и компиляторов в наглядные подсказки, позволяя сразу видеть, что пошло не так.</p><p>Можно настроить отображение: выделять ошибки цветом, добавлять иконки или даже показывать краткие подсказки с предложениями по исправлению. Поддерживает большинство языков и линтеров, включая ESLint, TypeScript и других.</p><p><b>Кому подойдёт:</b> разработчикам, которые хотят моментально видеть ошибки в коде, и тем, кто ценит визуальную чистоту и скорость отладки.</p><p>Плюсы:</p><ul><li>Ошибки и предупреждения отображаются прямо в редакторе, рядом со строкой кода;</li><li>Гибкая настройка стилей и уровня детализации сообщений;</li><li>Ускоряет процесс отладки, особенно при работе с большими файлами.</li></ul><p><b>Чем полезен:</b> минимизирует время на поиск и анализ ошибок, позволяя сразу фокусироваться на их исправлении. Это особенно ценно, когда вы пишете код в реальном времени или работаете с новыми библиотеками, где легко допустить мелкие недочёты.</p><h2>4. Path Intellisense</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense">Path Intellisense</a> — одно из тех расширений, которое просто работает и экономит кучу времени. Оно автоматически подсказывает пути к файлам, папкам и модулям в вашем проекте, как только вы начинаете их набирать. Поддерживает абсолютные и относительные пути, учитывает структуру проекта и форматирует предложения так, как это принято в выбранном языке.</p><p>Работает особенно хорошо в проектах с вложенной структурой, когда нужно быстро сослаться на компоненты, конфиги или ассеты.</p><p><b>Кому подойдёт</b>: всем, кто устал вручную прописывать длинные relative-пути или путаться в структуре проекта. Особенно выручает на фронтенде, где модулей десятки и легко ошибиться в названии.</p><p>Плюсы:</p><ul><li>Подсказки появляются автоматически при наборе пути;</li><li>Поддерживает большинство языков и фреймворков;</li><li>Учитывает jsconfig.json и tsconfig.json при работе с alias-ами.</li></ul><p><b>Чем полезен</b>: снижает количество опечаток и неверных импортов, ускоряет переход между файлами и помогает писать код чуть быстрее.</p><h2>5. TODO Highlight</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight">TODO Highlight</a> подсвечивает комментарии с задачами (например, TODO, FIXME, NOTE) прямо в коде, делая их заметными и удобными для отслеживания. Расширение помогает не терять важные заметки, которые вы оставляете в коде, и быстро находить места, требующие доработки.</p><p>Можно настроить ключевые слова, цвета подсветки и даже добавить свои собственные метки. Работает с любыми языками программирования и интегрируется с панелью задач VSCode для удобного обзора всех TODO в проекте.</p><p><b>Кому подойдёт</b>: разработчикам, которые оставляют заметки в коде, и командам, которым нужно быстро находить задачи или недочёты в проекте.</p><p>Плюсы:</p><ul><li>Яркая подсветка TODO-комментариев прямо в редакторе;</li><li>Гибкая настройка ключевых слов и стилей;</li><li>Интеграция с панелью задач для быстрого обзора.</li></ul><p><b>Чем полезен</b>: экономит время на поиск и управление задачами в коде, помогая не упустить важные доработки или напоминания. Особенно удобно в больших проектах, где комментарии могут затеряться среди строк.</p><h2>6. Prettier – Code formatter</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode">Prettier</a> — расширение, которое автоматически приводит ваш код к единому стилю, избавляет от ручной правки отступов, кавычек и переносов. Оно поддерживает множество языков (JavaScript, TypeScript, CSS, HTML и другие) и интегрируется с линтерами, чтобы ваш код был не только красивым, но и консистентным.</p><p>Можно настроить правила форматирования под ваш проект или использовать готовые пресеты. Prettier форматирует код при сохранении файла или по команде, а также работает с выделенными фрагментами.</p><p><b>Кому подойдёт</b>: разработчикам, которые хотят экономить время на форматировании, и командам, стремящимся к единообразию кода.</p><p>Плюсы:</p><ul><li>Автоматическое форматирование при сохранении или по хоткеям;</li><li>Поддержка множества языков и кастомных настроек;</li><li>Интеграция с ESLint и другими инструментами для проверки кода.</li></ul><p><b>Чем полезен:</b> убирает рутину ручного форматирования, снижает количество ошибок в стиле кода и помогает сосредоточиться на логике, а не на внешнем виде. Идеально, чтобы ускорить работу и поддерживать чистоту в больших проектах.</p><h2>7. Live Server</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer">Live Server </a>запускает локальный сервер прямо из VSCode, позволяя просматривать изменения в HTML, CSS и JavaScript в браузере в реальном времени. После сохранения файла страница автоматически обновляется, что исключает необходимость ручного перезапуска или обновления браузера.</p><p>Поддерживает кастомные порты, HTTPS, и работает с любыми фронтенд-проектами, от простых HTML-страниц до сложных приложений на React или Vue. Можно настроить, чтобы сервер открывался автоматически при запуске проекта.</p><p><b>Кому подойдёт</b>: фронтенд-разработчикам, которые работают над веб-интерфейсами и хотят мгновенно видеть результат изменений без лишних действий.</p><p>Плюсы:</p><ul><li>Автоматическое обновление страницы при изменении кода;</li><li>Простая настройка и поддержка HTTPS для безопасного тестирования;</li><li>Лёгкий запуск сервера прямо из редактора.</li></ul><p><b>Чем полезен</b>: ускоряет цикл разработки и тестирования веб-приложений, избавляет от ручного обновления страниц. Это особенно экономит время при частых правках в стилях или скриптах, так как можно сразу видеть результат в браузере.</p><h2>8. Project Manager</h2><p>Если работаете над несколькими проектами одновременно — это расширение сэкономит вам часы. <a href="https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager">Project Manager</a> позволяет создавать список избранных проектов и открывать их в один клик, без ручного поиска папок и недавних вкладок.</p><p>Можно задать свои алиасы, группировать по папкам, запускать с хоткеев — особенно удобно, если у вас десятки репозиториев на локалке или вы фрилансите на несколько команд.</p><p><b>Кому подойдёт</b>: разработчикам, которые ведут сразу несколько проектов, часто переключаются между ними и устали искать нужный путь через File &gt; Open Folder.</p><p>Плюсы:</p><ul><li>Быстрое переключение между проектами через интерфейс или хоткеи;</li><li>Поддержка избранного и тэгов;</li><li>Можно автоматически подтягивать все папки из заданной директории.</li></ul><p><b>Чем полезен:</b> избавляет от рутинных действий при переходе между проектами — особенно когда важно не терять фокус и не сбиваться с рабочего темпа.</p><h2>9. Code Spell Checker</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker">Code Spell Checker </a>выявляет орфографические ошибки в комментариях, строках и именах переменных прямо в редакторе VSCode. Расширение подчёркивает опечатки волнистой линией и предлагает варианты исправления через Ctrl+. или Cmd+., что позволяет быстро исправить ошибки.</p><p>Поддерживает множество ЯП и словари для разных языков (английский, русский, немецкий — с дополнительными расширениями). Можно добавлять свои слова в пользовательский словарь или игнорировать определённые термины, чтобы адаптировать проверку под проект. Работает с camelCase и snake_case, не помечая их как ошибки.</p><p><b>Кому подойдёт</b>: разработчикам, которые пишут много комментариев или документации в коде, и тем, кто хочет избежать опечаток в строках, API или логах, чтобы повысить читаемость.</p><p>Плюсы:</p><ul><li>Мгновенное обнаружение ошибок с подсказками для исправления;</li><li>Гибкая настройка словарей и игнорируемых слов;</li><li>Поддержка технических терминов и различных стилей написания кода.</li></ul><p><b>Чем полезен:</b> экономит время на поиск и исправление опечаток, особенно в документации или пользовательских сообщениях, которые могут повлиять на восприятие проекта.</p><h2>10. REST Client</h2><p><a href="https://marketplace.visualstudio.com/items?itemName=humao.rest-client">REST Client </a>позволяет отправлять HTTP-запросы и просматривать ответы непосредственно в VSCode. Достаточно создать файл с расширением .http или .rest, написать запрос в простом текстовом формате, и вы увидите кнопку Send Request для моментального выполнения.</p><p>Поддерживает все типы запросов (GET, POST, PUT, DELETE и другие), авторизацию (Basic, OAuth, JWT), переменные окружения и даже генерацию кода на разных языках. Запросы можно сохранять в репозиторий, что удобно для командной работы. Расширение также позволяет использовать динамические переменные по типу {{$timestamp}} или {{$guid}}, всё для гибкой настройки запросов.</p><p><b>Кому подойдёт</b>: тем, кто работает с REST API и хочет тестировать эндпоинты прямо в VSCode, сохранять запросы в проекте и почти не переключаться между инструментами.</p><p>Плюсы:</p><ul><li>Простая отправка запросов через .http или .rest файлы с кнопкой Send Request;</li><li>Поддержка переменных окружения и авторизации для сложных API;</li><li>Возможность сохранять запросы в репозитории для совместной работы.</li></ul><p><b>Чем полезен:</b> ускоряет тестирование API, устраняет необходимость в сторонних приложениях. Запросы хранятся рядом с кодом, что упрощает документирование и повторное использование, особенно в проектах, где API-вызовы нужно часто проверять или делиться ими с командой.</p><p><i>А какими расширениями пользуетесь вы? Пишите в комментариях!</i></p>]]></content:encoded>
    </item>
    <item>
      <title>Как Web3 меняет разработку веб-приложений: от серверов к блокчейну</title>
      <link>https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu</link>
      <comments>https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Диана Тажетдинова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu</guid>
      <description><![CDATA[<p>Поговорили с экспертом и узнали, где Web3 даёт практическую пользу разработчикам: сравниваем подходы, исследуем рынок вакансий и особенности новой реальности.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-web3-menyaet-razrabotku-veb-prilozhenij--ot-serverov-k-blokchejnu">Как Web3 меняет разработку веб-приложений: от серверов к блокчейну</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Блокчейн]]></category>
      <category><![CDATA[Ethereum]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[смарт-контракты]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 22 Sep 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Раньше, чтобы запустить приложение, приходилось настраивать сервер и базу данных. В Web3 всё по-другому: вместо серверов — смарт-контракты, вместо базы — блокчейн. <a href="https://www.esparkinfo.com/web3/statistics">По прогнозам</a>, объём рынка Web3‑разработки вырастет с $4,43 млрд в 2024 году до $6,15 млрд в 2025. Кейсы<a href="https://ru.wikipedia.org/wiki/Plume_Network_%E2%80%93_The_Future_of_Real-World_Assets_on_Web3_%F0%9F%8C%90?utm_source=chatgpt.com"> Plume Network</a> и<a href="https://en.wikipedia.org/wiki/The_Graph?utm_source=chatgpt.com"> The Graph</a> показывают, что Web3 уже работает в реальных продуктах. Что, если нас уже сегодня ждет backend в виде блокчейна? Давайте разберём, как меняются инструменты, архитектуры и карьерные треки.</p><h2>Главные отличия Web3 от Web2</h2><p>Перед тем как углубиться в код и практику, полезно увидеть основные различия между привычной Web2-разработкой и новой логикой Web3.</p><figure><img src="https://media.tproger.ru/user-uploads/114509/2025-09-22/3fa1cc2a-0755-4b71-af24-9b8a6f9d22ea.png" alt="" /></figure><p>Представим себе простой сервис для задач. В классическом Web2 его работа привычна: сервер обрабатывает запросы, база данных хранит задачи, а пользователь авторизуется через почту и пароль. Всё централизовано и зависит от владельца сервера.</p><p>В Web3 логика сильно меняется. Пользователь входит в систему с помощью криптокошелька, например, MetaMask. Каждая задача создаётся транзакцией и записывается в смарт‑контракт, а значит становится частью блокчейна. Удалить её уже нельзя — только отметить статус выполнения. Такой подход даёт прозрачность: любой участник сети может проверить, что задача действительно существует, и её статус изменён честно.</p><h2>Стек Web3: что понадобится на практике</h2><p>Чтобы построить работающий DApp, важно понимать, чем он отличается от обычного приложения. DApp — это децентрализованное приложение, в котором логика хранится в смарт-контрактах на блокчейне, а данные — в распределённых хранилищах, а не на сервере компании. Поэтому одного знания блокчейна мало: нужен полный набор инструментов — от языков и фреймворков до кошельков и сервисов подключения.</p><ul><li>Блокчейн: Ethereum, Layer‑2 (Arbitrum, Optimism, Base, Polygon), Solana.</li><li>Языки: Solidity (EVM), Rust (Solana), Go (инфраструктура и сервисы).</li><li>Библиотеки: ethers.js, wagmi.</li><li>Фреймворки: Hardhat, Foundry, Truffle.</li><li>Хранилища: IPFS/Arweave для файлов и метаданных.</li><li>Кошельки/подключение: MetaMask, WalletConnect (v2/WalletConnect Network), Web3Auth.</li></ul><blockquote>Точка входа для новичка — Alchemy, а также ethers.js.</blockquote><p><b>Пример.</b> Быстрое подключение кошелька (ethers.js).</p><h2>Архитектура DApp: из чего состоит современное Web3‑приложение</h2><p>Любое Web3‑приложение строится из нескольких слоёв, каждый со своей ролью. Фронтенд остаётся привычным SPA, но работает не с сервером, а напрямую с кошельком и смарт-контрактами. Контракты содержат бизнес‑логику и хранят ссылки на данные в децентрализованных хранилищах. Оракулы обеспечивают связь с внешним миром, например, передают цены или сообщения между разными блокчейнами. Важную часть играет off‑chain слой — сервисы вне блокчейна (индексаторы, аналитика), которые помогают быстрее искать и обрабатывать данные, при этом не перегружать сеть.</p><p><b>Пример.</b> Возьмём DeFi‑приложение. Пользователь открывает фронтенд и инициирует операцию swap(). В ответ фронтенд обращается к смарт‑контракту, который выполняет обмен токенов. Чтобы определить курс, контракт тянет актуальные данные через оракул. При этом тяжёлые артефакты, изображения или отчёты не хранятся в блокчейне напрямую — они лежат в IPFS. Сам контракт содержит только контент‑идентификаторы CID. Таким образом, получаем баланс: блокчейн отвечает за логику и безопасность, а децентрализованное хранилище — за данные.</p><h2>Практика: ваш первый DApp за вечер</h2><p>Давайте попробуем собрать простейшее приложение своими руками.</p><p><b>Шаг 0. Подготовка</b></p><p>Сначала убедитесь, что у вас стоит Node.js LTS и Git. Также нужен браузер с установленным MetaMask, где можно создать тестовый аккаунт. Чтобы оплачивать транзакции в тестовой сети, заранее возьмите немного тестовых монет через faucet — например, для Sepolia или Polygon Amoy.</p><p><b>Шаг 1. Проект</b></p><p>Создадим новый проект и установим Hardhat вместе с тулзами. Эта среда нужна для компиляции и деплоя контрактов.</p><p><b>Шаг 2. Контракт</b></p><p>В папке contracts/ создаём файл TaskTracker.sol и копируем туда код смарт-контракта из первого раздела. Это и будет бизнес-логика нашего приложения.</p><p><b>Шаг 3. Сценарий деплоя</b></p><p>Пишем скрипт, который разворачивает контракт в сети. Это простой скрипт на JavaScript, который вызывает методы Hardhat.</p><p><b>Шаг 4. Конфиг сети</b></p><p>В файле hardhat.config.js добавляем настройки для подключения к тестовой сети. Используем RPC-URL от Alchemy или Infura и приватный ключ от тестового аккаунта — его можно экспортировать из MetaMask, но использовать только для тестовой сети.</p><p><b>Шаг 5. Деплой в тестнет</b></p><p>Теперь запускаем скрипт деплоя. После выполнения увидите адрес контракта — он понадобится для фронтенда.</p><p><b>Шаг 6. Фронтенд (React + ethers.js + wagmi)</b></p><p>Собираем простое SPA: форма, чтобы добавить задачи, и кнопка «complete». Здесь мы используем ethers.js для обращения к контракту. Сделайте вызовы addTask и completeTask.</p><h2>Подводные камни Web3-разработки и что с ними делать</h2><p><b>Комиссии (gas): </b>любая запись в блокчейн стоит денег и иногда комиссия выше ценности операции — например, $10 за простую задачу.</p><ul><li>Что делать: использовать Layer-2 (Arbitrum/Optimism/Base/Polygon), выбирать сети с низкими комиссиями (Solana, Avalanche), оптимизировать контракты и батчи транзакций.</li></ul><p><b>Скорость: </b>подтверждение транзакции занимает секунды или десятки секунд, что заметно медленнее обычного сервера.</p><ul><li>Что делать: показывать «оптимистичный UI», кешировать данные, переносить часть логики off-chain, использовать быстрые сети (Solana, Near, Aptos).</li></ul><p><b>Безопасность:</b> код контракта неизменяем, и одна ошибка может стоить миллионов.</p><ul><li>Что делать: проходить аудит (CertiK, Trail of Bits), использовать проверенные библиотеки (OpenZeppelin), писать тесты в тестовых сетях (Goerli, Sepolia), внедрять баг-баунти и ролевую модель доступа.</li><li>Ресурс:<a href="https://consensys.io/diligence/smart-contract-security-best-practices/"> ConsenSys Diligence — Smart Contract Security Best Practices</a>.</li></ul><p><b>UX:</b> вход через кошелёк сложнее привычного логина/пароля. Нужно ставить расширение, пополнять баланс и подтверждать каждую транзакцию.</p><ul><li>Что делать: использовать аккаунт-абстракцию (ERC-4337), социальный логин, gasless транзакции через Paymaster, улучшать UI (подсказки, авто-фокус на MetaMask).</li></ul><p><b>Регуляция: </b>законы о Web3 пока разные в каждой стране. Легальное в одной юрисдикции может быть запрещено в другой (например, токенизация акций без лицензии).</p><ul><li>Что делать: консультироваться с юристами, следить за изменениями. Например, MiCA в ЕС — “Markets in Crypto-Assets Regulation” —  это единый регламент по криптоактивам в Евросоюзе.</li></ul><blockquote>Безопасность всегда должна быть на первом месте, потому что в Web3 есть риск потерять реальные деньги пользователей.</blockquote><h2>Карьерные возможности и перспективы</h2><p>Web3‑разработчиков уже активно ищут: <a href="https://web3.career/learn-web3/web3-intelligence-report">зарплаты в среднем предлагают выше</a>, чем у Web2‑коллег. Кроме программистов, востребованы смежные роли: аудиторы смарт‑контрактов, специалисты по безопасности, а также продакт‑менеджеры и аналитики, которые понимают специфику блокчейна.</p><p>Чтобы войти в профессию, начните с изучения Solidity и базовых паттернов смарт‑контрактов. Сделайте пару пет‑проектов и выложите код в GitHub. Отличный вариант прокачки — участвовать в хакатонах и грантовых программах от Ethereum Foundation или Solana Grants. Это даёт и опыт, и контакты, и иногда финансирование.</p><blockquote>Пара пет‑проектов + понимание блокчейна — хороший старт в Web3‑команду.</blockquote><h2>Будущее Web3</h2><p>Web3 не вытеснит Web2 полностью, но поменяет привычный подход к разработке. Разработчику это открывает новые вызовы: комиссии, безопасность и UX, но одновременно и новые возможности — прозрачные данные, токенизация, децентрализованные бизнес‑модели.</p><p>Для тех, кто только входит в сферу, это шанс попасть в индустрию на раннем этапе и быстро нарастить экспертизу. Простые пет‑проекты, хакатоны и знакомство с инструментами дают ощутимый старт.</p><p>Web3 будет развиваться параллельно с Web2, усиливая те области, где важны децентрализация, доверие и контроль за данными. Попробуйте задеплоить первый контракт — и вы сами почувствуете, что это не просто мода, а новый уровень возможностей.</p>]]></content:encoded>
    </item>
    <item>
      <title>WebAssembly 3.0 добрался до браузеров: 64-битная память, сборщик мусора и настоящие исключения</title>
      <link>https://tproger.ru/news/webassembly-3-0-dobralsya-do-brauzerov--64-bitnaya-pamyat--sborshhik-musora-i-nastoyashhie-isklyucheniya</link>
      <comments>https://tproger.ru/news/webassembly-3-0-dobralsya-do-brauzerov--64-bitnaya-pamyat--sborshhik-musora-i-nastoyashhie-isklyucheniya?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/webassembly-3-0-dobralsya-do-brauzerov--64-bitnaya-pamyat--sborshhik-musora-i-nastoyashhie-isklyucheniya</guid>
      <description><![CDATA[<p>WebAssembly 3.0 уже работает в браузерах: 64-битная память, полноценный GC, система исключений и новые инструменты для языков</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/webassembly-3-0-dobralsya-do-brauzerov--64-bitnaya-pamyat--sborshhik-musora-i-nastoyashhie-isklyucheniya">WebAssembly 3.0 добрался до браузеров: 64-битная память, сборщик мусора и настоящие исключения</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Компиляторы]]></category>
      <category><![CDATA[Scala]]></category>
      <category><![CDATA[Kotlin]]></category>
      <category><![CDATA[Блокчейн]]></category>
      <category><![CDATA[Firefox]]></category>
      <category><![CDATA[WebAssembly]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 18 Sep 2025 03:28:22 GMT</pubDate>
      <content:encoded><![CDATA[<p>Спустя три года после релиза версии 2.0, WebAssembly <a href="https://webassembly.org/news/2025-09-17-wasm-3.0/">получил</a> масштабное обновление.</p><p>Новый стандарт 3.0 уже поддерживается большинством современных браузеров и приносит сразу несколько ключевых нововведений.</p><h2>Главное из нововведений</h2><ul><li><b>64-битная адресация:</b> теперь Wasm может использовать i64 вместо i32, что расширяет лимит адресуемой памяти с 4 ГБ до 16 ЭБ (в реальности — до 16 ГБ в браузерах).</li><li><b>Несколько областей памяти:</b> модули теперь могут напрямую использовать и копировать данные между разной памятью, без обходных трюков с импортом других модулей.</li><li><b>Сборка мусора (GC):</b> добавлена поддержка управляемой памяти для языков с автоматическим управлением памятью (например, Java, Scala, Kotlin, Dart).</li><li><b>Типизированные ссылки:</b> улучшенная типизация ссылок и функций позволяет избежать лишних проверок в рантайме.</li><li><b>Исключения:</b> наконец-то появилась полноценная система обработки исключений — с try, throw и catch, как в других языках.</li><li><b>Хвостовые вызовы:</b> позволяют не занимать стек при возврате через вызов, что критично для функциональных языков и оптимизаций.</li><li><b>Расслабленные SIMD-инструкции:</b> добавлены быстрые, но менее детерминированные версии векторных инструкций для повышения производительности.</li><li><b>Детерминированный профиль:</b> теперь для задач с требованием полной воспроизводимости (например, блокчейны) можно включить строго определенное поведение операций.</li><li><b>Аннотации в тексте:</b> появилась возможность вставлять пользовательские аннотации прямо в текстовый формат .wat.</li></ul><h2>Что это значит</h2><p>WebAssembly становится всё ближе к полноценной виртуальной машине для высокоуровневых языков. В новой версии уже появляются компиляторы для Java, OCaml, Scala и прочих ЯП — благодаря поддержке GC и исключений.</p><p>Новый стандарт уже <b>поддерживается в основных браузерах</b>, включая Chrome и Firefox. Независимые движки, такие как Wasmtime, тоже догоняют.</p>]]></content:encoded>
    </item>
    <item>
      <title>На GitHub выложили исходный код алгоритма рекомендаций X. Разобрались, что там внутри</title>
      <link>https://tproger.ru/news/--na-github-vylozhili-ishodnyj-kod-algoritma-rekomendacij-x--razobralis--chto-tam-vnutri</link>
      <comments>https://tproger.ru/news/--na-github-vylozhili-ishodnyj-kod-algoritma-rekomendacij-x--razobralis--chto-tam-vnutri?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/--na-github-vylozhili-ishodnyj-kod-algoritma-rekomendacij-x--razobralis--chto-tam-vnutri</guid>
      <description><![CDATA[<p>X выложила на GitHub исходный код алгоритма рекомендаций. Внутри — Scala, Java, Rust и ML-модели для ранжирования твитов, поиска и уведомлений</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/--na-github-vylozhili-ishodnyj-kod-algoritma-rekomendacij-x--razobralis--chto-tam-vnutri">На GitHub выложили исходный код алгоритма рекомендаций X. Разобрались, что там внутри</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Scala]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Twitter]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 10 Sep 2025 08:38:08 GMT</pubDate>
      <content:encoded><![CDATA[<p>Компания X (экс-Twitter) опубликовала исходники алгоритма, отвечающего за рекомендации в ленте «Для вас», поиске и уведомлениях.</p><p>Репозиторий уже <a href="https://github.com/twitter/the-algorithm">собрал</a> почти 65 000 звезд на GitHub. Разбираемся, как он устроен и какие интересные модули лежат внутри.</p><h2>Что делает этот алгоритм</h2><p>Алгоритм отвечает за то, какие посты и аккаунты вы видите на всех основных страницах в X: от рекомендаций и трендов до пушей. Внутри — десятки сервисов и моделей, взаимодействующих между собой.</p><p>Например, компонент home-mixer собирает кандидатные твиты из разных источников (например, через search-index, tweet-mixer, user-tweet-entity-graph) и ранжирует их при помощи легкой и тяжелой нейросети (light-ranker, heavy-ranker).</p><p>После этого подключаются фильтры (например, visibility-filters), которые убирают нежелательный контент и скрытые посты.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-09-10/ccd962a9-c580-4418-990f-737091a615d3.jpeg" alt="" /></figure><h2>Из чего это все собрано</h2><p>Проект построен на Scala (66%), Java (20%) и Rust. Некоторые модули используют Python и даже TensorFlow v1 (например, twml). Базовые компоненты включают:</p><ul><li>Данные — tweepypie, unified-user-actions, user-signal-service</li><li>Модели — SimClusters, TwHIN, real-graph, tweepcred, trust-and-safety-models</li><li>Фреймворки — navi (на Rust), product-mixer, representation-scorer, representation-manager</li></ul><p>Также присутствуют специфические компоненты для пушей — сервис pushservice, ранжирующие модели pushservice-light-ranker и pushservice-heavy-ranker, предсказывающие, откроет ли пользователь уведомление.</p><h2>Почему это важно</h2><p>Во-первых, X остается одной из крупнейших социальных платформ в мире, и понимание ее алгоритмов дает представление о принципах ранжирования и фильтрации контента.</p><p>Во-вторых, открытый код — это редкость в мире коммерческих рекомендаций, особенно на таком масштабе.</p><p>Разработчики предлагают сообществу вносить улучшения через пул-реквесты, участвовать в программах по поиску уязвимостей и разрабатывать на базе кода собственные сервисы.</p><h2>Что это значит для разработчиков</h2><p>Этот проект — хорошее поле для изучения реального промышленного машинного обучения. Особенно интересны:</p><ul><li>плотные графовые эмбеддинги в TwHIN</li><li>модели репутации и социальной близости в real-graph и tweepcred</li><li>многозадачные модели в pushservice-heavy-ranker</li></ul><p>Проект можно собрать с помощью Bazel, хотя полноценной инфраструктуры для тестов пока нет.</p>]]></content:encoded>
    </item>
    <item>
      <title>xAI представила grok-code-fast-1 — свою первую ИИ-модель для кодинга и агентных задач</title>
      <link>https://tproger.ru/news/--xai-predstavila-grok-code-fast-1---svoyu-pervuyu-ii-model-dlya-kodinga-i-agentnyh-zadach</link>
      <comments>https://tproger.ru/news/--xai-predstavila-grok-code-fast-1---svoyu-pervuyu-ii-model-dlya-kodinga-i-agentnyh-zadach?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/--xai-predstavila-grok-code-fast-1---svoyu-pervuyu-ii-model-dlya-kodinga-i-agentnyh-zadach</guid>
      <description><![CDATA[<p>xAI выпустила grok-code-fast-1 — первую модель для кодинга и агентных задач. Она поддерживает TypeScript, Python, Java, Rust, C++ и Go, интегрирована в IDE и CLI, работает быстро (до 160 ток/с) и стоит дешевле конкурентов</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/--xai-predstavila-grok-code-fast-1---svoyu-pervuyu-ii-model-dlya-kodinga-i-agentnyh-zadach">xAI представила grok-code-fast-1 — свою первую ИИ-модель для кодинга и агентных задач</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C++]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Искусственный интеллект]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 29 Aug 2025 11:10:09 GMT</pubDate>
      <content:encoded><![CDATA[<p>Компания xAI <a href="https://x.ai/news/grok-code-fast-1">анонсировала</a> <b>grok-code-fast-1</b>. Это первая модель компании, ориентированная на программирование и агентные сценарии.</p><p>Модель создана с нуля, обучена на реальных пулл-реквестах и задачах из практики. Она уже доступна в IDE.</p><h2>Новая глава в «вайб-кодинге»</h2><p>Модель grok-code-fast-1 от xAI позиционируется как конкурент решениям от OpenAI, Google и Anthropic. Она оптимизирована для разработки на <b>TypeScript</b>, <b>Python</b>, <b>Java</b>, <b>Rust</b>, <b>C++</b> и <b>Go</b>, а значит покрывает большинство реальных кейсов в современной разработке.</p><p>Модель уже интегрирована в <i>IDE</i> и <i>CLI</i> вроде <b>GitHub Copilot</b>, <b>Cursor</b>, <b>Cline</b>, <b>Roo Code</b>, <b>Kilo Code</b>, <b>OpenCode</b> и <b>Windsurf</b>. В ближайшее (но ограниченное) время она будет доступна бесплатно.</p><h2>Быстрая, дешевая и довольно-таки умная</h2><p>xAI делает ставку на цену, скорость и удобство. Стоимость использования grok-code-fast-1:</p><ul><li><b>$0,20</b> за 1 млн входных токенов</li><li><b>$1,50</b> за 1 млн выходных токенов</li><li><b>$0,02</b> за 1 млн кэшированных входных токенов</li></ul><p>Во внутреннем бенчмарке <b>SWE-Bench-Verified,</b> модель показала результат <b>70,8%</b>, но независимых тестов пока нет — их ждут в ближайшие недели.</p><p>В xAI утверждают, что при создании модели основное внимание уделялось <b>практическому использованию и удобству в реальных задачах</b>. Якобы разработчики оценили grok-code-fast-1 как «быструю и надежную» при повседневной работе с кодом.</p><figure><img src="https://media.tproger.ru/user-uploads/111041/2025-08-29/0ff28520-4f6d-495d-bb2e-78175b8e78f2.jpeg" alt="" /></figure><h2>До 160 токенов в секунду и 90% кэш-хитов</h2><p>Команды xAI по инференсу и суперкомпьютингу применили ряд новых приемов, чтобы <b>ускорить генерацию до 160 токенов в секунду</b>. Особенно это ощущается в IDE, где задержка — критический параметр.</p><p>Кроме того, реализовано <b>кэширование подсказок</b>, которое обеспечивает <b>до 90% попаданий</b> при работе с GitHub Copilot и другими интеграциями. Это позволяет существенно сократить задержки и стоимость использования.</p>]]></content:encoded>
    </item>
    <item>
      <title>Не только для собеседований: как LeetCode и аналоги помогают новичкам в программировании</title>
      <link>https://tproger.ru/articles/ne-tolko-dlya-sobesedovanij--kak-leetcode-i-analogi-pomogayut-novichkam-v-programmirovanii</link>
      <comments>https://tproger.ru/articles/ne-tolko-dlya-sobesedovanij--kak-leetcode-i-analogi-pomogayut-novichkam-v-programmirovanii?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Диана Тажетдинова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/ne-tolko-dlya-sobesedovanij--kak-leetcode-i-analogi-pomogayut-novichkam-v-programmirovanii</guid>
      <description><![CDATA[<p>Алгоритмические задачи развивают логику, структурное мышление и помогают на собеседованиях и в работе. Узнайте, с чего начать, как избежать выгорания и сохранить мотивацию.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/ne-tolko-dlya-sobesedovanij--kak-leetcode-i-analogi-pomogayut-novichkam-v-programmirovanii">Не только для собеседований: как LeetCode и аналоги помогают новичкам в программировании</a>»</p>]]></description>
      <category><![CDATA[Алгоритмы и структуры данных]]></category>
      <category><![CDATA[Java]]></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>Thu, 21 Aug 2025 14:00:04 GMT</pubDate>
      <content:encoded><![CDATA[<p>Многие новички боятся алгоритмических задач. Кажется, что это бустер для кандидатов в Google, которые решают графы на доске маркером, а не для тех, кто только осваивает циклы. Но опыт разработчиков показывает: даже простые задачи могут заметно улучшить качество кода.</p><p>Мы поговорили с экспертами и попросили их поделиться задачами, которые помогут прокачать логику и навыки работы с данными. Заодно узнали, зачем вообще новичку браться за алгоритмы. Решения оставим в комментариях. Не подглядывайте сразу, а сначала попробуйте свои силы.</p><h2>Зачем вообще решать алгоритмические задачи</h2><p>Алгоритмы в начале карьеры нужны не всем. Эксперты честно говорят, что практика на реальных маленьких проектах может дать больше пользы. Но выкидывать алгоритмы из своего обучающего трека точно не стоит, и вот почему.</p><p>Разработчик Валерий Жила говорит, что на алгоритмы можно смотреть по-разному:</p><blockquote>С одной стороны, алгоритмы новичкам не нужны — пусть лучше берутся за практические проекты, даже если это просто репозиторий на GitHub, который можно запустить на локалхосте. С другой — это как классическая литература или высшая математика. Напрямую в работе может не пригодиться, но здорово прокачивает мозги и помогает найти общий язык с другими разработчиками.</blockquote><p>А Константин Шибков, senior Java-разработчик в СДЭК, автор <a href="https://t.me/three_monitors">канала «Три монитора»</a>, вспоминает, что задачи стали для него тренировочным залом для мозгов:</p><blockquote>Когда я был новичком, знаний для полноценного приложения не хватало, а тренироваться хотелось. LeetCode показал мне, когда использовать массивы, деревья, словари, множества, и как эффективно обходить или искать данные. А просмотр чужих решений после своего помогал находить новые приёмы.</blockquote><p>Даже если вы не мечтаете прямо сейчас попасть в Google или Amazon, алгоритмические задачи — это отличная тренировка. Они помогут:</p><ul><li>развить логику и выстроить чёткий план решения,</li><li>натренировать декомпозицию — разбивку сложного на простое,</li><li>мыслить в терминах массивов, графов и деревьев.</li></ul><p>В бигтехе эти навыки проверяют особо тщательно: Яндекс, OZON и другие компании любят устраивать отдельные алгоритмические сессии. Бонусом вы будете готовы и к ним.</p><figure><img src="https://media.tproger.ru/user-uploads/114509/2025-08-15/90914bb0-f966-49e6-aa1e-3c0990809dbb.jpeg" alt="" /></figure><h2>Простые задачи — лучший вход</h2><p>Начинать сразу со сложного или среднего уровня — это как пытаться пробежать марафон без единой тренировки. Эксперты однозначно советуют начинать с чего-нибудь лёгкого. Чем проще задача, тем выше шанс её довести до конца.</p><blockquote>Например, Merge Two Sorted Lists — простая задача, которая учит работать с указателями. Разобравшись, можно попробовать Merge k Sorted Lists — это более сложная задача с тем же базовым подходом.</blockquote><blockquote>Нужно в первую очередь освоить базовые структуры данных. Научиться видеть в них инструмент с понятной и простой функцией, как лопата или молоток.</blockquote><p>Почему простые задачи действительно приносят пользу:</p><ul><li>вы быстро получаете результат и мотивацию продолжать,</li><li>можно сосредоточиться на логике, а не на дебаге сложных условий;</li><li>легче отрабатывать приёмы и паттерны, которые потом повторяются в сложных задачах.</li></ul><h2>Где искать задачи для практики</h2><p>Загляните на специальные онлайн-сервисы для практики алгоритмического программирования. Вот список популярных в русскоязычной среде сайтов:</p><ul><li><a href="https://leetcode.com/">LeetCode</a> — мировой лидер, база задач от простых до сложных для подготовки к интервью</li><li><a href="https://codeforces.com/">Codeforces</a> — сообщество для соревнований и обучения</li><li><a href="https://coderun.yandex.ru/">CodeRun</a> — российская платформа с задачами на алгоритмы и регулярными контестами</li><li><a href="https://acm.timus.ru/">Timus Online Judge</a> — портал с архивом олимпиадных задач, востребованный у студентов и олимпиадников</li><li><a href="https://adventofcode.com/">Advent of Code</a> — ежегодный онлайн-марафон задач в формате адвент-календаря, стилизованный под приключения</li><li><a href="https://www.codewars.com/">Codewars</a> — геймифицированная платформа с заданиями по разным языкам и уровням сложности</li></ul><blockquote>Как-то раз я завалил экзамен по алгоритмам в университете, будучи уверенным, что предмет — элементарный. Взялся за материалы, LeetCode, Advent of Code, Codewars и пару месяцев плотно ими занимался. Решал по 5−10 задач в день. Экзамен я пересдал на отлично. На последующих собеседованиях уже получалось интуитивно нащупывать решения.</blockquote><figure><img src="https://media.tproger.ru/user-uploads/114509/2025-08-15/3383b7e0-2e3c-4157-9f9e-ac37f079a031.png" alt="" /><figcaption>Фишки LeetCode: большое международное комьюнити, 14 языков программирования и возможность получить оффер от IT-гигантов</figcaption></figure><h2>Что решают разработчики, чтобы держать мозг в тонусе</h2><p>Попросили экспертов выбрать задачи, которые они сами считают полезными для развития алгоритмического мышления.</p><p>Валерий Жила:</p><ol><li><a href="https://leetcode.com/problems/two-sum/">Two Sum</a> — найти два числа в массиве, сумма которых равна заданному значению. Чему учит: работать с хэш-таблицами и быстро находить соответствия. Базовый паттерн, который часто встречается в других задачах.</li><li><a href="https://leetcode.com/problems/number-of-islands/">Number of Islands</a> — посчитать количество связных компонент на карте. Чему учит: обходить граф DFS/BFS, думать в терминах связности элементов.</li><li><a href="https://leetcode.com/problems/decode-string/">Decode String</a> — декодировать строку с вложенными структурами. Чему учит: использовать стек, вложенные циклы и парсинг данных.</li></ol><p>Совет: «Если сухой LeetCode наскучил, попробуйте Advent of Code».</p><p>Константин Шибков:</p><ol><li><a href="https://leetcode.com/problems/maximize-distance-to-closest-person/">Maximize Distance to Closest Person</a> — выбрать место в ряду, чтобы максимизировать расстояние до ближайшего соседа. Чему учит: работать с краевыми случаями, искать оптимальную позицию по условию.</li><li><a href="https://leetcode.com/problems/merge-two-sorted-lists/">Merge Two Sorted Lists</a> — объединить два отсортированных списка в один. Чему учит: работать с указателями и аккуратно обрабатывать данные в упорядоченных структурах.</li><li><a href="https://leetcode.com/problems/move-zeroes/">Move Zeroes</a> — переместить все нули в конец массива, сохранив порядок остальных элементов. Чему учит: оптимизировать алгоритм без создания дополнительных структур.</li><li><a href="https://leetcode.com/problems/partition-to-k-equal-sum-subsets/">Partition to K Equal Sum Subsets</a> — разделить массив на K подмножеств с равной суммой элементов. Чему учит: использовать поиск с возвратом, оптимизировать перебор.</li></ol><p>Никита Дубко, старший руководитель продуктов Яндекс Контеста, автор <a href="http://t.me/mefody_dev">канала mefody.dev</a></p><ol><li><a href="https://coderun.yandex.ru/problem/new-year-fruits-2/">Мандарины и апельсины 2.0</a> — выбрать n ящиков так, чтобы в них оказалось не менее половины всех мандаринов и апельсинов. Чему учит: использовать свойства возрастающих последовательностей, минимизировать количество проходов по данным и находить решение без полного перебора.</li><li><a href="https://coderun.yandex.ru/problem/cha_cha/">Ча-ча-ча</a> — определить итоговую оценку по набору буквенных оценок с ограничением, что итог не может быть более чем на балл выше худшей. Чему учит: работать со строками и символами в ASCII/UTF-8, а также применять решение в лоб, когда оно эффективно.</li></ol><p>Совет: «Тренируйтесь не только решать, но и объяснять, почему ваш алгоритм работает и укладывается в ограничения. Этот навык ценят на собеседованиях».</p><h2>Как не сломаться на старте: выгорание и ошибки новичков</h2><p>Практика алгоритмов должна прокачивать мозг, а не выматывать его. Но у многих новичков энтузиазм быстро сменяется усталостью — чаще всего из-за завышенных ожиданий и неверной стратегии.</p><p>Главные ловушки:</p><ul><li>Гонка на износ. План «100 задач за месяц» звучит амбициозно, но в реальности превращается в марафон без подготовки.</li><li>Залипание на одной задаче. Если вы часами бьётесь над решением, азарт сменяется усталостью.</li><li>Кажется, что все остальные ушли далеко вперед. Вы видите только чужие успехи, но не видите их ошибки.</li><li>Синтаксическая ловушка. Новички пытаются угадать код, вместо того чтобы проработать логику на бумаге.</li><li>Держать всё в голове. Легко потеряться в деталях, если не набросать план на бумаге.</li></ul><blockquote>Если задача по зубам, решение само скомпилируется в голове. Иногда полезно просто отойти, попить чаю или лечь спать.</blockquote><p>Что советуют эксперты:</p><ul><li>Решайте по одной задаче в день, как утреннюю разминку для мозга.</li><li>Чередуйте лёгкие и средние задачи, чтобы тренироваться в комфортном темпе, но с небольшим вызовом. Так вы будете расти без ощущения, что тонете.</li><li>Если за час решение не приходит, то посмотрите разбор без кода, а затем напишите свой вариант.</li><li>Отмечайте, какой приём вы отработали — это даёт чувство прогресса.</li><li>Записывайте решение пошагово. Даже опытные разработчики часто начинают с блокнота.</li></ul><blockquote>Я получал удовольствие, когда решал задачу своим способом, проходил все тесты и потом видел в чужом коде приёмы, о которых даже не думал.</blockquote><h2>Как продолжать развиваться</h2><p>Когда лёгкий уровень перестанет пугать, и вы будете уверенно разбираться в массивах, строках и базовых структурах данных, двигайтесь дальше. Как в спорте: если всегда работать с одной гантелью, прогресса не будет.</p><p>1. Освойте новые темы. Начните с самых популярных направлений, которые часто встречаются в реальной разработке и на собеседованиях:</p><ul><li>сортировки,</li><li>графы,</li><li>строковые алгоритмы,</li><li>деревья.</li></ul><p>2. Устройте себе челлендж. Например, «30 задач за 30 дней». Берите не количеством, а регулярностью. Можно чередовать дни по уровням сложности.</p><p>3. Используйте готовые подборки. Есть отличные списки от экспертов. Приведём лишь некоторые из них</p><ul><li><a href="https://seanprashad.com/leetcode-patterns/">LeetCode Patterns</a> — задачи сгруппированы по типам и темам;</li><li><a href="https://leetcode.com/problem-list/oizxjoit/">Blind 75</a> — 75 самых популярных задач для собеседований;</li><li><a href="https://www.geeksforgeeks.org/blogs/gfg160-160-days-of-problem-solving">GfG‑160</a> — 160 задач для тех, кто хочет по-настоящему прокачать алгоритмы</li></ul><p>4. Пробуйте альтернативные платформы. Чтобы не застревать в одном формате, чередуйте площадки. Разные интерфейсы и условия помогут смотреть на задачи с нескольких сторон.</p><figure><img src="https://media.tproger.ru/user-uploads/114509/2025-08-15/fafb8ef0-7b0e-4b0b-bf24-489d7ad426e7.jpeg" alt="" /></figure><blockquote>Однажды на работе мне нужно было распределить посылки по ячейкам постамата так, чтобы максимально эффективно использовать пространство. По сути, это была вариация задачи Partition to K Equal Sum Subsets: разложить элементы по контейнерам без перегруза. Я использовал поиск с возвратом и оптимизацию, которые до этого отрабатывал на алгоритмических задачах. Закрыл задачу быстрее, чем если бы разрабатывал всё с нуля. <br /><br />Но стоит учесть, что код на LeetCode отличается от того, что мы обычно пишем в прод. У нас на работе даже есть локальный мем «по-литкодовски», когда код — максимально короткий, без попытки быть понятным и простым. Главное для него — быть эффективным. Когда переносишь алгоритмы решения в реальный мир, нужно выделять алгоритм в изолированный класс или метод. Так вы сможете проверить его тестами и сделать более понятным для других.</blockquote><h2>Выводы</h2><ul><li>Алгоритмические задачи развивают логику, структурное мышление и умение разбивать проблему на шаги. Навыки пригодятся и на собеседованиях, и в реальной работе.</li><li>Начинать лучше с простых задач, чтобы закрепить основы и избежать выгорания.</li><li>Нужно научиться не только решать задачи, но и объяснять, почему алгоритм работает.</li><li>Ищите задачи на разных платформах, чтобы сохранить интерес и прокачивать навыки в разных форматах.</li><li>Лучше решать по одной задаче в день, чем десяток в выходные.</li><li>Не гонитесь за чужим темпом и чередуйте уровни сложности.</li><li>Личный опыт экспертов показывает, что алгоритмы могут спасти на экзамене и ускорить поиск рабочих решений.</li></ul><p>Читайте также:</p><p><a href="https://tproger.ru/articles/algoritm-dejkstry--kak-rabotaet-i-gde-ispolzuetsya">Алгоритм Дейкстры: как работает и где используется</a></p><p><a href="https://tproger.ru/articles/top-10-algoritmov--kotorye-realno-nuzhny-na-bekende">ТОП-15 алгоритмов, которые реально нужны на бэкенде</a></p><p><a href="https://tproger.ru/articles/chto-takoe-hew-tablicy-i-kak-ih-ispolzovat">Что такое хэш-таблицы и как их использовать</a></p><p><a href="https://tproger.ru/articles/kviz--kakoj-stek-tehnologij-tebe-podhodit-">Квиз: какой стек технологий тебе подходит?</a></p><p><a href="https://tproger.ru/articles/rabochij-plan--kak-izuchit-novyj-stek-za-3-mesyaca">Рабочий план: как изучить новый стек за 3 месяца</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Осторожно: @Size не проверяет на null! Как я пропустил баг</title>
      <link>https://tproger.ru/articles/ostorozhno---size-ne-proveryaet-na-null--kak-ya-propustil-bag-</link>
      <comments>https://tproger.ru/articles/ostorozhno---size-ne-proveryaet-na-null--kak-ya-propustil-bag-?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Тюрин ]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/ostorozhno---size-ne-proveryaet-na-null--kak-ya-propustil-bag-</guid>
      <description><![CDATA[<p>Почему @Size(min = 1) в Spring не проверяет null и пропускает пустые поля? Разбираем реальный кейс с формой отзыва, объясняем поведение @Size, @NotBlank, @NotNull и показываем, как правильно валидировать обязательные поля в Spring Boot.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/ostorozhno---size-ne-proveryaet-na-null--kak-ya-propustil-bag-">Осторожно: @Size не проверяет на null! Как я пропустил баг</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[Angular]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 10 Aug 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Разрабатывая веб-приложения на Java Spring, мы часто сталкиваемся с необходимостью валидации входных данных. Одна из самых распространённых задач — убедиться, что обязательное текстовое поле заполнено и соответствует определённым критериям, например, длине. Кажется, что решение очевидно: используем аннотацию <i>@Size</i>. Но здесь нас поджидает одна неприятность.</p><p>Недавно я столкнулся с одной проблемой на реальном проекте. У меня есть сайт: бэкенд написан на Spring, а фронтенд — на Angular. Я добавлял новую форму для отправки отзыва пользователя и, в спешке, забыл добавить валидацию на одно из полей формы на фронтенде.</p><p>Я хотел, чтобы поле «комментарий» было обязательным и имело длину от 1 до 100 символов. На бэкенде использовал аннотацию @Size(min = 1, max = 100) к обязательным полям, например для поля `comment` в моем DTO имеет такой вид:</p><p>Тест с пустой строкой {"comment": ""} был корректно отклонён. Однако, когда я отправил запрос без поля "comment" вообще ( {} ), валидация прошла успешно, и поле «comment» пришло как null. Это была серьёзная ошибка — поле, которое по логике было обязательным, могло быть пропущено. Т.е. могли потеряться важные для меня данные.</p><h4>Почему так происходит?</h4><p>Причина кроется в спецификации JSR-303 (Bean Validation). Документация (Javadoc) для аннотации <i>@Size</i> прямо указывает: «null elements are considered valid». Это означает, что если значение поля null, валидатор <i>@Size</i> считает его валидным и не выполняет проверку длины.</p><p>Это поведение подтверждается и в исходном коде валидатора. Метод, отвечающий за проверку строки, сначала проверяет значение на null, и если оно null, сразу возвращает true, не переходя к проверке размера. Это стандартное поведение для многих аннотаций валидации, таких как<i> @Min, @Max, @Pattern</i> и т.д. Они проверяют <b>качество</b> значения, но не его <b>наличие</b>.</p><h4>Предлагаемое решение</h4><p>Чтобы поле было действительно обязательным (не null и не пустое), необходимо использовать аннотации, которые проверяют наличие значения - это <i>@NotNull, @NotEmpty, @NotBlank</i> . Для строк лучшим выбором является комбинация:</p><p>Понимание разницы между этими аннотациями критически важно:</p><ul><li><i>@NotNull</i>: Гарантирует, что значение поля не является null. Однако оно не проверяет пустые строки или строки из пробелов и будут считаться валидными.</li></ul><ul><li><i>@NotEmpty</i>: Гарантирует, что значение не null и не пустое (для строки длина &gt; 0). Это означает, что "" будет отклонено, но строка из одних пробелов "   " пройдёт валидацию, так как её длина больше 0.</li></ul><ul><li><i>@NotBlank</i>: Предназначена исключительно для String. Гарантирует, что строка не null, не пустая и после удаления пробелов с начала и конца (trim) имеет длину больше 0. Это означает, что null, "" и "   " будут отклонены. Именно это поведение обычно ожидается от "обязательного текстового поля".</li></ul><h4>Красивое возвращение ошибок</h4><p>Для того чтобы клиент (в моём случае, Angular-приложение) получал понятные сообщения об ошибках валидации, я настроил глобальный обработчик исключений с помощью <i>@ControllerAdvice</i>. Когда валидация не проходит, Spring выбрасывает MethodArgumentNotValidException. Далее, я его перехватываю и возвращаю структурированный ответ.</p><p>Angular-приложение может легко обработать этот JSON и отобразить пользователю понятное сообщение об ошибке.</p><h4>Выводы</h4><p>Аннотация <i>@Size</i> сама по себе не делает поле обязательным. Она проверяет только длину, если значение не null. Для обязательных строковых полей всегда используйте <i>@NotBlank</i>. Для других типов данных используйте <i>@NotNull</i>.</p><p>Не полагайтесь на @Size(min = 1) как на замену проверки на null или пустую строку. Эта ловушка, в которую я сам попался, может привести к консистентным данным в вашей системе и потенциальным уязвимостям, если бэкенд будет работать с неожиданными null значениями. Всегда явно указывайте, что поле является обязательным, с помощью соответствующих аннотаций.</p><p>Этот материал — не открытие века, а скорее напоминание как себе, так и  коллегам. Даже опытные разработчики иногда могут упустить из виду такие нюансы. Я столкнулся с этой проблемой на проекте, и она стоила мне времени на отладку и тестирование.</p>]]></content:encoded>
    </item>
    <item>
      <title>Фичи будущего в интерфейсе, которые можно и нельзя использовать в 2025 году: разбираем Baseline 2025</title>
      <link>https://tproger.ru/articles/fichi-budushhego-v-interfejse--kotorye-mozhno-i-nelzya-ispolzovat-v-2025-godu--razbiraem-baseline-2025</link>
      <comments>https://tproger.ru/articles/fichi-budushhego-v-interfejse--kotorye-mozhno-i-nelzya-ispolzovat-v-2025-godu--razbiraem-baseline-2025?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Даровская Маша]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/fichi-budushhego-v-interfejse--kotorye-mozhno-i-nelzya-ispolzovat-v-2025-godu--razbiraem-baseline-2025</guid>
      <description><![CDATA[<p>Какие CSS- и HTML-фичи войдут в вёрстку к 2025 году? Разбираем доклад Михаила Балицкого (Яндекс) о Baseline 2025: сабгриды, попапы без JS, анимации скролла и почему SASS ещё рано списывать.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/fichi-budushhego-v-interfejse--kotorye-mozhno-i-nelzya-ispolzovat-v-2025-godu--razbiraem-baseline-2025">Фичи будущего в интерфейсе, которые можно и нельзя использовать в 2025 году: разбираем Baseline 2025</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Новости]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Яндекс]]></category>
      <category><![CDATA[YouTube]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 01 Aug 2025 12:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>О чём говорили на <a href="https://www.youtube.com/live/qQmEGSFKB-8">Яндекс-субботнике</a> для разработчиков интерфейсов в Минске.</p><p>Михаил Балицкий, старший разработчик интерфейсов главной страницы Поиска Яндекс, рассказал об основных фичах ближайшего будущего. Какие-то уже можно пробовать применить в интерфейсах вашего приложения, а с какими-то придётся подождать.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/f4b90e42-47c4-4ea8-8f79-c2d1886f5e32.png" alt="" /></figure><p>Михаил сделал клон страницы Яндекс Поиска,
чтобы испробовать все нововведения (Baseline), поддерживаемые в браузерах на
2025 год. У каждой фичи есть веб-платформенные тесты от сообщества — набор
кейсов, который проверяет функциональность. Многие из фичей, несмотря на то, что
находятся в Baseline 2025 года, не имеют 100% покрытия тестов.</p><h2>Гриды и сабгриды</h2><p>За основу Layout страницы взяли гриды, которые
находятся в продакшене уже более 8 лет.</p><p>API первого уровня позволяет вам создавать
layout страницы как крупными мазками, то есть верхнеуровнево, так и
распределять элементы маленьких блоков.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/edc5e27d-a660-45f9-aebd-8713a0773d89.png" alt="" /></figure><p>Но гриды не стоят на месте, а двигаются вперёд. Недавно появилась спецификация второго уровня. Например, если
у нас есть блок сервисов, то мы его можем задать как грид. А каждый элемент
этого списка — в виде сабгрида. По сути, говоря ему, что он наследует
сетку родителя.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/7186b397-d620-4b3d-ae95-2594643235a9.png" alt="" /></figure><p>Это позволяет за счёт изменения одного
свойства родителя полностью изменить внешний вид элемента — например, сделать
иконки разного размера.</p><p>Но это ещё не всё. Если мы сверстали карточку
в ленте фида, она получилась классной, но тестирование указало нам на проблемы
с доступностью. У нас не оказалось тега &lt;article&gt; и тега
anchor element &lt;a&gt; для ссылки. Но при добавлении этих тегов вёрстка может
поплыть.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/142cce85-093c-4b70-bec0-d2924d9039b4.png" alt="" /></figure><p>Если вы используете сабгриды, всё нормально — будет унаследована сетка родителя, и элемент останется красивым. Это позволяет
верстать блок без использования position легко и удобно.</p><p>CSS сабгриды появились в 2023 году, но пока их
рано использовать, так как в случае, если бразуер пользователя их не
поддерживает, у вас может сломаться вся вёрстка. Но пройдёт несколько лет и их
можно будет использовать.</p><h2>Масштабирование</h2><p>Если у нас страница обладает свойством
резиновости: на больших экранах элементы увеличиваются, на маленьких —
уменьшаются.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/6e33385a-841d-4a46-abeb-f636144c5de9.png" alt="" /></figure><p>Достигается это за счёт того, что страница
свёрстана в em — это величина, которая меняет размер шрифта. А меняя его, мы
меняем размер элементов. Раньше это писалось с помощью медиа-выражений, который
зависит от min-width, то сейчас есть возможность упростить визуальный
синтаксис, добавив интервальный. Он позволяет дописать больше или
равно/ меньше или равно — то, что человеку понятнее. Есть post css плагин,
который позволяет завезти это поведение для старых браузеров, чтобы всё
работало хорошо.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/9516ac0e-8f9a-42fa-9ec0-9bbc0c1b3a50.png" alt="" /></figure><p>А можно ещё сильнее упростить код, за счёт
использования css Nesting из baseline 2023. Поэтому в браузерах новее 2023
года это работает из коробки, а в более старых можно с помощью post css плагина
затрансперировать поведение, чтобы всё корректно работало. Тем самым, мы
сэкономим немного строк кода.</p><p>Но можно пойти ещё дальше в будущее к
@function, и в 139 Chrome уже пообещали запустить эту функциональность, но пока
доступна только в Chrome Canary браузере (для опытных разработчиков). Позволяет
заменить mix in в CSS, SASS для препроцессинга.</p><p>Но можно пойти в @property.
Поддерживается почти во всех браузерах и позволяет задать кастомное
свойство, задать значение по умолчанию и узнать, наследуется ли оно. Здесь мы задаём
стандартное значение размера шрифта в em, потому что оно зависит от контекста.
По спецификации initial value должно быть постоянным значением, которое не
изменяется нигде.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/4c20575a-8f12-4be2-a928-9107c7f5f1dd.png" alt="" /></figure><h2>Отказ от SASS — не всё так просто</h2><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/a6a66ec6-38dd-4334-8b3c-73363f48a53b.png" alt="" /></figure><p>Если у нас есть полоска сервисов, которые в
зависимости от размеров экрана меняют свой размер, то за счёт селектора
nth-child мы можем указать: возьми все элементы, начиная с n, кроме all, и
примени к нему display: none. А внутри медиа-выражение в зависимости от размера
экрана срабатывает по-разному. У медиа-выражений есть явная проблема: если у
нас меняется продуктовое поведение, например, размер блока или расположение
компонента, то все стили устаревают и медиа-выражения приходится заново
переписывать.</p><p>Но у нас появились container queries, которые
позволяют мэтчиться не на размер страницы, а на размер конкретного элемента
— ширину или высоту. Работает с 2023 года, но в продакшен тащить рано
— в старых браузерах вёрстка поедет.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/6926118c-5d20-468a-9abf-f90458eda798.png" alt="" /></figure><p>Код в примере очень репетативен — мы повторяем
одно и тоже много раз.</p><p>Можно ли написать вот так?</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/e7c92318-fb7b-4334-bd63-ce20c02e8827.png" alt="" /></figure><p>Но в таком коде есть много проблем, он не
работает и никогда не будет работать.</p><p>В container queries у нас есть константы,
можно использовать calc, чтобы сложить em и пиксели. Но мы не можем там
использовать CSS-переменные, браузер их просто проигнорирует. А в nth-child всё
ещё хуже: можно использовать только целочисленные значения.</p><h2>Postcss-Preset-Env</h2><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/c8a14e8e-9b3d-4150-848b-52ee937a156c.png" alt="" /></figure><p>Плагин для postcss, который базируется на
возможностях веб-платформы и спецификации, позволяет контролировать, какие
спецификации вы затаскиваете в браузер. Можно контролировать набор возможностей
по списку браузеров и управлять явным списком фичей, включать и отключать
нестинг.</p><h2>Попап сервисов (dialog)</h2><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/f7e3c510-cc35-44cd-8064-63f93bdef40a.png" alt="" /></figure><p>Позволяет сделать доступное модальное окно без
JS. Есть два режима показа: обычный и модальный. В модальном режиме есть
ловушка фокуса, которая позволяет осуществлять навигацию через табы. Также при
использовании скринридера вы не уходите за пределы данного элемента. Раньше это достигалось с помощью JS, а теперь работает из коробки.</p><p>В будущем это должно будет работать так:</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/6f777cd8-a74d-4234-adca-4e9f28291467.png" alt="" /></figure><p>Но спецификация до сих пор не стабилизирована.
Всё, кроме закрытия по парандже работает без JS. Есть полифил (polyfill), но
для его работы нужно писать дополнительные селекторы и он не работает без
JavaScript, нет понятия Top Layer.</p><h2>Меню в фиде</h2><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/ea9f7945-49cb-4f11-b342-bc22135d6601.png" alt="" /></figure><p>В любой элемент страницы, будь то div, span или
dialog, нужно добавить интерактивности, чтобы он открывался по клику. В сочетании с
micro position меню позиционируется рядом с кодом без единой строчки JS и
работает с 2025 года, то есть через пять лет можно будет затащить решение в
продакшене.</p><h2>Прогрессивные улучшения</h2><p>Пользователи старых браузеров эти улучшения не
получают, но их опыт не ухудшается, а это важно.</p><p>Сюда входят дискретные анимации для бинарных
свойств с помощью allow-discrete. Так значение свойств изменится только к концу
анимации.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/977ea182-e64f-4984-b6f8-91dbc94b0410.png" alt="" /></figure><p>В сочетании с элементом @starting-style легко
добиться красивых анимаций — например, показ и скрытие попапа.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/e36097c7-2f7d-4654-b5d9-1634829414ca.png" alt="" /></figure><p>Но оказалось, что прогрессивные улучшения
могут навредить пользователям. В 120 и 121 Chrome есть баг, который крашит
браузер. Совет — экспериментировать, проверять и
замерять.</p><h2>Scrollbars</h2><p>Из коробки они могут вылезать за пределы или
оказаться неправильного цвета. Но с помощью color-scheme можно задать
конкретный цвет блока. Станет лучше, но Scrollbar всё равно может вылезать за
пределы элемента.</p><p>Появился Scrollbar Styling первого уровня,
который позволяет делать красивые скроллбары. Есть набор констант от none до
thin, и можно задавать цвет как самого трекера, так и подложки.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/739f6b9a-e925-4dc1-9744-96990e95cc3a.png" alt="" /></figure><p>Но Scrollbar может всё равно вылезать за
пределы страницы, а ещё сложно управлять цветом и расположением элемента.</p><p>Чтобы это исправить, можно использовать другое свойство без стабильной спецификации, поддерживаемое во всех браузерах — это
webkit-scrollbar.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/1f3a31dc-6c55-46a0-ab66-806a1312175f.png" alt="" /></figure><p>Правда с его помощью не получится добиться
красивого скругления. Но сочетать webkit-scrollbar и scrollbar-styling не выйдет. Либо одно, либо другое.</p><p>Можно использовать scrollbar-gutter, чтоб
зарезервировать пространство с двух сторон скролла. Но если есть элемент с
динамичной высотой, когда элементов может быть то меньше, то больше, то можно
избежать прыжка контента.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/3f103c28-1d11-4e11-b4e6-095587dce308.png" alt="" /></figure><p>Рекомендация — всегда добавлять на
html-тег это свойство, чтоб проблем не было и интерфейс не оказался сдвинут.</p><h2>Анимации</h2><p>Также сейчас можно сдвигать элемент на чистом
CSS без использования JS — с помощью animation timeline scroll или animation
timeline view.</p><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/f420ed73-5f1b-4a97-826c-6a70d423c7bc.png" alt="" /></figure><p>Вы можете управлять положением скролла и тем,
какую часть анимация занимает, а также связываать две анимации.</p><p>Но нужно всегда задаваться вопросом: что
будет, если свойство не поддерживается в старых браузерах.</p><p>Например, в этом случае два элемента будут
наплывать друг на друга или произойдёт мерцание.</p><h2>View Transition API</h2><figure><img src="https://media.tproger.ru/user-uploads/102593/2025-08-01/adb3207e-c79a-426d-bceb-61c6fb326f26.png" alt="" /></figure><p>API крайне мощный, но пока не очень
поддерживается.</p><h2>Итоги</h2><ul><li>Переменные уже заменены и их можно использовать $name-&gt;var(-name).</li><li>Миксины через 5 лет можно будет заменить mixin-&gt;@function.</li><li>Нативный нестинг — хорош!</li><li>Даже функция if() уже доступна в Chrome136.</li><li>Не скоро ещё можно будет отказаться от языков препроцессинга, например, от SASS.</li><li>Область использования var() и env() ограничена.</li><li>CSS не умеет в циклы.</li><li>@function пока слишком рано использовать.</li><li>Но мы можем перейти на CSS + Post CSS. И в Яндекс Поиске пошли по этому пути. При этом во всей кодовой базе mix in использовались всего несколько раз. Поэтому оказалось что функции препроцессора особо не используется. От нестига пришлось мигрировать — но это было не сложно.</li><li>Popover и полифилл есть в baseline 2025, но не все wpt проходят.</li><li>Полифилл имеет ограниченную поддержку.</li><li>Полифилл не работает в браузерах с частичной поддержкой popover.</li><li>Anchor-positioning есть в Inerop 2025 и у него есть полифилл, но спецификация ещё меняется.</li><li>Полифилл не поддерживает множество кейсов — практически никакие, кроме базовых.</li><li>Даже прогрессивные улучшения могут навредить.</li></ul><p>Давно пора исползовать:</p><ul><li>Dialog — упрощает написание кода и работает даже в старых браузерах с полифоллом.</li><li>CSS Nesting и CSS — Variables упрощают написание стилей и хорошо работает в связке с PostCSS.</li><li>Grid Layout — упрощает вёрстку сложных сайтов и работает в браузерах 8-летней давности.</li></ul><p><b>Через пять лет вёрстка сильно изменится за счёт новых фичей, которые появляются уже сейчас! А какую из фичей вы желаете больше всего затащить в продакшен? </b></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>Типизированная навигация в React Router</title>
      <link>https://tproger.ru/articles/tipizirovannaya-navigaciya-v-react-router</link>
      <comments>https://tproger.ru/articles/tipizirovannaya-navigaciya-v-react-router?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Михаил Сахаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/tipizirovannaya-navigaciya-v-react-router</guid>
      <description><![CDATA[<p>Когда прочитаете эту статью, сможете настроить типобезопасную навигацию в своем проекте, забудете про сломанные ссылки после рефакторинга и перестанете нервничать на релизах.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/tipizirovannaya-navigaciya-v-react-router">Типизированная навигация в React Router</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[React]]></category>
      <category><![CDATA[Redux]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 16 Jul 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Типизированная навигация в React Router решает классические проблемы фронтенд-разработки: опечатки в путях, сломанные ссылки после рефакторинга и отсутствие автокомплита. Это полезно и джунам, которые хотят избежать глупых ошибок, и сеньорам, проектирующим большие проекты. Инструмент превращает строковые пути в типобезопасную систему навигации.</p><p>Представьте: пятница, 18:30. Релиз через час. Вы меняете один роут в конфиге — и внезапно половина приложения отлетает. Поздравляем, вы только что познакомились с классической болью фронтендеров.</p><p>Проблема кроется в самой природе JavaScript. Строковые пути вроде /users/profile/${id} существуют в коде как обычные строки — без проверок, автокомплита и гарантий корректности. Опечатался в /usres вместо /users — и твоя навигация сломалась, а TypeScript молчит как рыба.</p><p>Двадцать лет назад мы кликали по window.location.href, десять лет назад — радовались React Router, а сегодня пора переходить на типизированные решения.</p><p>Когда прочитаете эту статью, сможете настроить типобезопасную навигацию в своем проекте, забудете про сломанные ссылки после рефакторинга и перестанете нервничать на релизах.</p><h2>Суть проблемы</h2><p>Проблема очевидна: путь /admin/products размазан по всему коду. TypeScript не знает, что эти строки связаны с определенной директорией, поэтому не проверяет их корректность. Опечатка в product вместо products — и вылетает ошибка 404.</p><p>В больших проектах эта проблема критична. Приложение с 200+ путями, где навигация разбросана по сотне компонентов, превращается в минное поле. Один программист меняет структуру URL, а остальные даже не подозревают об этом. Команды используют TypeScript для типобезопасности, но навигация остается уязвимой.</p><h2>Что такое типизированная навигация?</h2><p>Типизированная навигация превращает строковые пути в типизированные объекты. Вместо /admin/products/123/edit программист работает с функциями, которые знают структуру приложения и проверяют корректность написания путей на этапе компиляции.</p><p>Представьте GPS-навигатор, который знает все адреса в городе. Вы не можете ввести несуществующую улицу — система сразу выдаст ошибку. Так работает типизированная навигация: TypeScript проверяет, что путь существует, параметры переданы правильно, а структура URL соответствует пути.</p><p>Три ключевых преимущества: автокомплит в IDE, проверка на этапе компиляции и безопасный рефакторинг. Поменяете пути в коде — TypeScript сразу покажет все места, которые нужно обновить.</p><p>Польза зависит от уровня разработчика:</p><ul><li>Джуны получают защиту от опечаток и автокомплит — меньше глупых ошибок и быструю разработку.</li><li>Миддлы ускоряют разработку благодаря надежному рефакторингу — можно смело менять структуру URL без страха что-то сломать.</li><li>Сеньоры используют типизацию для построения архитектуры приложения — создают переиспользуемые компоненты навигации, проверяют параметры и строят масштабируемые системы путей и директорий.</li></ul><p>Типизированная навигация превращает хрупкий код в надежную систему, где ошибки находятся до деплоя.</p><h2>Как использовать React Router вместе с TypeScript</h2><p>Для базовой типизации в React Router v6 сначала определите структуру путей. Создайте интерфейс, который описывает все пути в приложении:</p><p>Типизация параметров URL решает проблему с useParams. Вместо any получаете конкретные типы:</p><p>Query-параметры типизируются аналогично через useSearchParams. Создайте интерфейс для каждой страницы с query-параметрами и оберните хук.</p><p>Так система будет дополнять код в IDE, проверять все пути на этапе компиляции и защитит от опечаток. Полчаса настройки сэкономят вам часы отладки и целый вагон нервов.</p><h2>Как внедрить типизированную навигацию в проекты</h2><p>Централизованная система маршрутов облегчает управление навигацией в больших приложениях. Создайте отдельный файл с конфигурацией всех путей:</p><p>Конфигурация избавит от нужды дублировать код при генерации типов. TypeScript автоматически выведет все возможные пути и их параметры из одного объекта.</p><p>Современные библиотеки решают проблему из коробки.<a href="https://tanstack.com/router"> Например, Tanstack Router</a> предоставляет полностью типизированную систему путей с автогенерацией типов, а<a href="https://github.com/typehero/type-route"> Type-route</a> создает типобезопасные пути через API.</p><p>Библиотека<a href="https://github.com/typesafe-routes/typesafe-routes"> typesafe-routes</a> внедряется даже в крупные проекты без необходимости менять сотни строк кода.</p><p>Выбор инструмента зависит от размера программы. Если у вас небольшое приложение — быстрее написать хук в пару строк. Но если разрабатываете сложный сервис — используйте библиотеки.</p><h2>Как не сломать код при использовании типизированной навигации</h2><p>Не пытайтесь переписать весь проект за раз — создайте типизированные хуки для новых фич, а старый код обновляйте по мере рефакторинга.</p><p>Чеклист для код-ревью поможет не уронить прод:</p><ul><li>Все новые navigate() и  используют типизированные версии;</li><li>Параметры путей явно типизированы;</li><li>Нет магических строк в навигации;</li><li>Query-параметры описаны интерфейсами.</li></ul><p>Важно: не используйте одновременно строки и типизированные пути — выберите один подход для проекта и не допускайте высокого уровня вложенности в объектах.</p><p>Автоматизация упрощает процесс. ESLint правило no-hardcoded-routes запретит использование строк в навигации. Код-генераторы создают типы из OpenAPI схем или конфигурации роутера.</p><p>Производительность не страдает — типы исчезают после компиляции. Теряется немного времени на компиляцию TypeScript, но экономия на отладке перекрывает затраты.</p><h2>Где применять типизированную навигацию</h2><p>SPA-приложения получают максимальную пользу от типизированных путей. В дашбордах с десятками страниц навигация становится еще важнее — один сломанный путь может уронить проект.</p><p>E-commerce проекты выигрывают от типизации каталогов и фильтров. Пути вроде /catalog/:category/:subcategory?filters=price,brand содержат много параметров, которые легко сломать при рефакторинге.</p><p>Интеграция с Redux и Zustand упрощает синхронизацию состояния с URL. Типизированные селекторы автоматически обновляются при изменении роутов:</p><p>Вложенные директории требуют особого внимания. Каждый уровень вложенности усложняет типизацию — планируйте структуру заранее, а не рефакторьте задним числом.</p><p>Типизированная навигация — стандарт современной разработки. Команды, которые до сих пор полагаются на строковые пути, тратят лишнее время на поиск багов. Программисты увереннее рефакторят код, не боятся мелких ошибок и не роняют прод в пятницу вечером из-за одного символа в пути.</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>Безопасное исполнение ненадёжного кода</title>
      <link>https://tproger.ru/articles/bezopasnoe-ispolnenie-nenadyozhnogo-koda</link>
      <comments>https://tproger.ru/articles/bezopasnoe-ispolnenie-nenadyozhnogo-koda?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Александр Межов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/bezopasnoe-ispolnenie-nenadyozhnogo-koda</guid>
      <description><![CDATA[<p>Методы безопасного исполнения ненадёжного кода. Рассматриваются уровни изоляции кода, методы ограничения ресурсов процесса, проблемы жёсткого лимитирования и подходы к их решению. Обсуждаются вопросы управления песочницами, а также использование инструментов контейнеризации.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/bezopasnoe-ispolnenie-nenadyozhnogo-koda">Безопасное исполнение ненадёжного кода</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Тестирование]]></category>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Практика]]></category>
      <category><![CDATA[.NET]]></category>
      <category><![CDATA[DevOps]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[Redis]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Kubernetes]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Песочница]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 06 Jul 2025 09:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Мы привыкли к тому, что ведем разработку, используя лучшие инженерные практики, включая настройку CI/CD-конвейера. Сначала код проходит многоэтапные стадии проверки и тестирования, а только потом попадает в production-среду.</p><p>Давайте представим ситуацию, что нужно запустить код, минуя все эти стадии. Прям в production-среде. На первый взгляд — бред! Но если подумать, то на самом деле, не такая уж редкость. Например, некоторые системы предоставляют своим пользователям возможность расширять функциональность за счет прикладных скриптов. Наш любимый CI/CD-конвейер зачастую построен на пользовательских скриптах.</p><p>С одной стороны, для большинства подобная постановка вопроса — крайность. С другой, появляется возможность рассмотреть проблему с разных ракурсов. Уверен, что какие-то части общего решения, о котором пойдёт речь далее, могут быть использованы повторно и в других проектах.</p><p>Предлагаю по частям разобрать проблему безопасного исполнения ненадёжного кода. Последовательно рассмотрим вопросы, ответы на которые поворотные в выборе целевой архитектуры. Большая часть статьи касается разработки, но в конце сделаны важные акценты относительно администрирования и развертывания.</p><h2>Ненадёжный код</h2><p>Для начала определимся, что же считать ненадёжным кодом? На самом деле ответ зависит от решаемой задачи, правил и процессов, принятых в компании:</p><ul><li>Код, который не прошел CI, review и т.п.</li><li>Код из ненадёжного или неизвестного источника.</li><li>Закрытый (проприетарный) код.</li><li>Код, содержащий уязвимости.</li><li>Код, использующий запрещенные функции.</li><li>Любой код, который написал коллега:)</li></ul><p>Чтобы отделять код разрабатываемого приложения от ненадёжного, первый буду называть кодом приложения, а второй — <i>ненадёжным</i> или <i>внешним кодом</i>. Необходимость запуска ненадёжного кода в некоторых случаях буду называть <i>задачей</i>.</p><h2>Уровни изоляции кода</h2><p>Можно выделить три варианта запуска внешнего кода — три уровня изоляции. Каждый следующий увеличивает дистанцию между кодом приложения и запускаемым кодом. Чем выше уровень изоляции, тем меньше вероятность, что запускаемый код нанесет вред приложению и системе.</p><h3>Уровень 1: тот же процесс</h3><p>Запуск внешнего кода в адресном пространстве процесса приложения.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/191fd454-6837-4e91-abbf-c6d4a1fb6121.png" alt="Запуск внешнего кода в адресном пространстве процесса приложения." /><figcaption>Запуск внешнего кода в адресном пространстве процесса приложения.</figcaption></figure><p>Такой способ определяет самый слабый уровень изоляции, поскольку запущенный код теоретически имеет доступ ко всему тому, к чему имеет доступ код самого приложения.</p><p>Примером может служить использование интерпретаторов скриптов (<a href="https://github.com/mozilla/rhino">Rhino</a>, <a href="https://github.com/IronLanguages/ironpython3">IronPython</a>, <a href="https://github.com/jython/jython">Jython</a> и т.п.), визуальных языков программирования (workflow-движков) или подключение модулей расширения (плагинов).</p><p>Способов защиты на этом уровне не так много. Пожалуй, самым эффективным выступает (self-sandboxing), при котором приложение делает самозапрет на доступ к некоторым ресурсам системы. Например, сразу после инициализации — самозапрет на доступ к файловой системе.</p><p>Дополнительно запускаемый код можно подвергать строгому (синтаксическому) анализу, запрещая использование определенных функций, модулей, пакетов и т.п. Некоторые интерпретаторы имеют точки расширения, которые позволяют контролировать процесс исполнения. Если такой возможности нет, можно воспользоваться одной из техник самоизоляции — <a href="https://www.kernel.org/doc/html/latest/userspace-api/seccomp_filter.html">фильтрацией системных вызовов</a>.</p><p>Что же касается плагинов, то они призваны расширять возможности приложения, поэтому их использование изначально не предполагает сильной изоляции. Здесь можно предложить усилить контроль взаимодействия на уровне контракта (API). В идеале — если плагины будут публиковаться в некоторый центральный репозиторий, которому вы доверяете и который может производить дополнительные проверки и тестирование до этапа запуска кода плагина.</p><h3>Уровень 2: отдельный процесс</h3><p>Запуск внешнего кода на той же машине, но в отдельном процессе ОС.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/e0bf62de-65a9-4370-9986-ed21c6e63b8e.png" alt="Запуск внешнего кода на той же машине, но в отдельном процессе ОС." /><figcaption>Запуск внешнего кода на той же машине, но в отдельном процессе ОС.</figcaption></figure><p>Поскольку и приложение, и внешний код взаимодействуют в рамках одного узла, используя локальные ресурсы ОС (оперативная память, файловая система и т.п.), скорость межпроцессного взаимодействия очень высокая.</p><p>Этот уровень изоляции предполагает использование широкого арсенала возможностей. Как минимум, внешний код может быть запущен от имени менее привилегированного пользователя, с ограниченным доступом к ресурсам ОС. Сильные способы изоляции ограничивают ресурсы с помощью средств ОС или инструментов контейнеризации. Однако, чем сильнее контроль, тем больше накладных расходов на запуск и исполнение процесса, что при решении некоторых задач неприемлемо дорого или неоправданно сложно.</p><h3>Уровень 3: отдельная машина</h3><p>Запуск внешнего кода на отдельной машине — песочнице.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/5e48bc50-75c9-4789-9dc7-3bbf2c1659a7.png" alt="Запуск внешнего кода на отдельной машине — песочнице." /><figcaption>Запуск внешнего кода на отдельной машине — песочнице.</figcaption></figure><p>Это максимальный уровень изоляции из всех возможных. Здесь появляется возможность ограничить ресурсы самой песочницы (CPU, память, дисковое пространство, доступ к сети и т.п.). Если в результате исполнения внешнего кода песочница выйдет из строя, приложение продолжит свою работу.</p><p>Самый главный недостаток этого подхода — необходимость сетевого взаимодействия между узлом, на котором работает приложение, и песочницей. Передача входных данных в песочницу, запуск процесса внутри, ожидание окончания его исполнения, получение выходных данных — всё это сетевые обращения. Так существенно замедляется процесс исполнения, а само взаимодействие подвержено сетевым сбоям, что ведёт к нестабильности системы и получаемых результатов.</p><h2>Использование песочницы</h2><p>Предположим, требуется максимальный уровень изоляции ненадёжного кода, следовательно, нужно остановиться на варианте запуска на отдельной машине. Если так, то для принятия последующих архитектурных решений нужно ответить на следующую пару вопросов.</p><h3>Пересоздание или переиспользование песочницы</h3><p>Песочницу требуется пересоздавать перед исполнением каждой задачи, если требуется особенное окружение (например, определенная версия ОС, пакетов или ресурсов) или идентичность этого окружения (для стабильности получаемых результатов). Схожие вопросы возникают, например, при интеграционном тестировании: каждому тесту нужны свои предустановки.</p><p>Переиспользование песочницы становится возможным, если задачи могут исполняться в одном окружении и не оказывают влияния друг на друга (предыдущая задача не портит результаты последующей). Продолжая аналогию с интеграционным тестированием: всем тестам нужны одинаковые предустановки, и тесты могут запускаться повторно на одном стенде, демонстрируя один и тот же результат.</p><p>Основным преимуществом пересоздания песочницы выступает стабильность получаемых результатов. К недостаткам относится медленный запуск и перерасход ресурсов. На пересоздание песочницы уходят десятки секунд или даже минут, следовательно, большая часть ресурсов будет тратиться именно на это. Существует множество техник ускорения пересоздания, благодаря которым можно сократить время запуска. Прежде всего, сюда можно отнести backup/restore (snapshot песочницы, базы данных и т.п.). Также если поток задач небольшой и ресурсы позволяют, можно попробовать организовать пул песочниц и создавать их заранее.</p><p>Ставка на переиспользование делается в случае, когда поток задач большой и нужно сократить время ожидания их запуска. При этом возрастает вероятность получения нестабильных результатов и, возможно, требуется производить какую-то очистку окружения до или после исполнения очередной задачи.</p><h3>Последовательное или параллельное исполнение</h3><p>Теперь осталось ответить на вопрос, как именно можно или нужно исполнять задачи: последовательно или параллельно. Последовательное исполнение требуется в следующих случаях:</p><ul><li>важен порядок следования и исполнения задач;</li><li>задачам нужен эксклюзивный доступ к определенному ресурсу;</li><li>задачи ёмкие и их совместное исполнение вызовет нехватку ресурсов;</li><li>задачи могут мешать исполнению друг друга из-за борьбы за ресурсы.</li></ul><p>Например, шаги установки и настройки ПО; шаги CI/CD-конвейера; рендеринг изображения на GPU; интенсивные вычисления. Все эти задачи, скорее всего, придётся исполнять <b>последовательно</b>.</p><p>В остальных случаях допустимо <b>параллельное исполнение</b>. Яркой аналогией может служить одна из лучших практик в тестировании: тесты не должны оказывать влияние друг на друга, а порядок их запуска не должен иметь значения.</p><p>Последовательное исполнение обеспечивает стабильность получаемых результатов, однако приводит к низкой пропускной способности и дороговизне масштабирования (песочница обходится дороже процесса ОС). Параллельное исполнение, напротив, увеличивает пропускную способность системы и улучшает утилизацию ресурсов песочницы, но одновременно повышает вероятность нестабильных результатов. Более того, при параллельном исполнении появляется шанс перегрузить песочницу или вывести её из строя таким образом, что приведет к увеличению времени исполнения всех запущенных задач или потере результатов их работы.</p><p>На практике было замечено, что при параллельном исполнении, несмотря на увеличенную общую пропускную способность, время исполнения каждой отдельной задачи увеличивается. Если уровень параллелизма становится больше числа CPU-ядер, время исполнения начинает деградировать намного сильней.</p><h2>Управление песочницами</h2><p>Допустим, переиспользование песочниц возможно. В таком случае необходимо определить способ управления ими. Можно выделить два подхода, основанные на принципах микросервисной архитектуры, но адаптированные к специфике рассматриваемой проблемы.</p><h3>Оркестрация</h3><p>Оркестрация предполагает, что приложение совмещает две роли: оркестратор исполнения и оператор песочниц. Оркестратор координирует процесс исполнения кода: выбор подходящей песочницы, загрузка в неё входных данных, запуск удалённого процесса, получение результатов его работы и т.п. Оператор, в свою очередь, отслеживает доступные песочницы и их состояние.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/93758cab-2542-4a80-b47a-d65b04ef4f14.png" alt="Оркестрация песочниц." /><figcaption>Оркестрация песочниц.</figcaption></figure><p>Основное преимущество оркестрации в контексте решаемой проблемы — её простота и ясность. Код легко читается и сосредоточен в одном месте. Однако у этого решения есть и недостатки. Рассмотрим их в порядке от простого к сложному.</p><ul><li><i>Синхронное взаимодействие.</i> Так или иначе, для результата приложение вынуждено ожидать окончания исполнения задачи. Для продуктивного использования ресурсов приходится прибегать к техникам асинхронного программирования: пока задача исполняется, приложение будет занято полезной работой. Это малозаметный недостаток в языках со встроенной поддержкой концепции асинхронного программирования. Для упрощения работы с асинхронным кодом в Java я создал небольшую вспомогательную библиотеку <a href="https://github.com/AlexMAS/asynchronizer">asynchronizer</a>, снабдив её подробной <a href="https://github.com/AlexMAS/asynchronizer/blob/main/docs/README.ru.md">документацией</a>.</li></ul><ul><li><i>Отслеживание доступности песочниц.</i> Поскольку хотелось бы, чтобы количество песочниц менялось в зависимости от нагрузки на систему, придётся отслеживать их доступность. Это прямая обязанность оператора песочниц, которую можно выделить в отдельный discovery-сервис (например, на базе <a href="https://github.com/spring-cloud/spring-cloud-netflix">Netflix Eureka</a>), либо реализовать как часть приложения с использованием инфраструктурных механизмов (например, <a href="https://github.com/fabric8io/kubernetes-client">Kubernetes API</a>). Важно отметить, что оператор песочниц не имеет отношения к бизнес-логике приложения.</li></ul><ul><li><i>Отслеживание загруженности песочниц.</i> Оркестратор исполнения должен выбрать подходящую <a href="https://samwho.dev/load-balancing/">стратегию балансировки</a>, основанную на состоянии песочниц, предоставляемых оператором. На практике наилучшую эффективность демонстрирует алгоритм Least connections, с помощью которого можно выбирать наименее загруженные песочницы. Для этого достаточно вести учёт количества задач, исполняемых каждой песочницей. Конечно, это не серебряная пуля, а лишь частное наблюдение, поэтому в идеале нужно предусмотреть несколько стратегий балансировки и выбрать наилучшую по результатам нагрузочного тестирования.</li></ul><ul><li><i>Неопределённость результата, если нет ответа от песочницы.</i> Песочница может быть недоступна по различным причинам, включая не только проблемы с сетью, но и падения песочницы из-за ненадёжного кода. К сожалению, в общем случае эта проблема не имеет решения, так как делать повторные запуски (retries) может быть опасно. Всё, что остаётся, это использовать таймауты и откладывать неуспешную задачу на потом.</li></ul><p>Ещё один существенный минус, который стоит упомянуть, это возможный побочный эффект, возникающий при масштабировании системы и проявляющийся в виде перегрузки песочниц. Для наглядности рассмотрим конкретный пример.</p><p>Для отслеживания нагрузки на песочницы экземпляр приложения ориентируется на количество задач в каждой из доступных песочниц. Предположим, что было принято решение увеличить количество экземпляров приложения. Этот экземпляр исполняет 5 задач в двух песочницах (3 процесса в одной и 2 в другой). Известно, что каждая песочница может вынести максимум 4 параллельных задачи.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/623f7e7c-71d0-41da-8681-731ef43d3716.png" alt="Экземпляр исполняет 5 задач в двух песочницах (3 процесса в одной и 2 в другой)." /><figcaption>Экземпляр исполняет 5 задач в двух песочницах (3 процесса в одной и 2 в другой).</figcaption></figure><p>Добавив новый экземпляр приложения, неизвестно, сколько задач исполняет каждая песочница. Такая ситуация может произойти по разным причинам.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/7131d310-7c0d-44b8-b031-055436bd64d8.png" alt="Новый экземпляр приложения не знает, сколько задач исполняет каждая песочница." /><figcaption>Новый экземпляр приложения не знает, сколько задач исполняет каждая песочница.</figcaption></figure><p>Вполне очевидно, что новый экземпляр приложения направит очередную задачу в первую попавшуюся песочницу, чем может спровоцировать её перегрузку. В итоге результат исполнения будет испорчен или потерян из-за падения песочницы.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/c65090e5-020f-4eff-826b-566d3dc6da5c.png" alt="Очередная задача направляется в первую песочницу и провоцирует её перегрузку." /><figcaption>Очередная задача направляется в первую песочницу и провоцирует её перегрузку.</figcaption></figure><p>В качестве решения можно предложить два способа, каждый из которых уменьшает вероятность возникновения перегрузок, но не избавляет от них.</p><ul><li><i>Для контроля количества исполняемых задач в песочнице использовать распределённый счётчик</i> (например, на базе Redis). Проблема в том, что распределённый счётчик имеет латентность и на момент запуска задач может выдать устаревшее значение. Кроме того, в системе появляется еще один инфраструктурный компонент, который не несёт бизнес-пользы.</li></ul><ul><li><i>Выделить каждому экземпляру приложения эксклюзивное подмножество песочниц.</i> Подобное решение существенно усложнит deployment-скрипты и процесс масштабирования, а также снизит степень утилизации выделенных ресурсов, ведь нет никаких гарантий того, что экземпляр приложения сможет хорошо нагрузить все выделенные ему песочницы.</li></ul><p>Кстати, после доклада на TechLeadConf 2025 мне задали интересный вопрос: <i>Можно ли при балансировке нагрузки на песочницы учитывать не только количество исполняемых задач, но и процент загрузки CPU, памяти и прочих ресурсов? </i>Если у кого-то возник такой же вопрос, то отвечу, что это не имеет смысла, поскольку ситуация в песочнице может поменяться мгновенно. Полученный практический опыт и нагрузочное тестирование показали, что простой подсчёт задач работает эффективно.</p><h3>Самоорганизация</h3><p>В микросервисной архитектуре подобный подход принято называть хореографией, однако чтобы не возникало неправильных ассоциаций, предлагаю использовать термин <i>самоорганизация</i>.</p><p>Ключевой момент в архитектуре — это появление двух очередей: очередь задач на исполнение (Task Queue) и очередь результата их исполнения (Result Queue). Все поступающие задачи приложение направляет в первую очередь, а результаты — во вторую. Дополнительно появляется роль агента — микросервиса, который исполняется в рамках узла песочницы и координирует исполнение поступающих задач.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/0d449846-e767-49bd-bd50-d1c77c49cf10.png" alt="Самоорганизация песочниц." /><figcaption>Самоорганизация песочниц.</figcaption></figure><p>Основной недостаток самоорганизации — распределённый процесс обработки задач. Учитывая простоту алгоритма обработки, это не так существенно. Стоит отметить преимущества этой архитектуры.</p><ul><li><i>Максимальная изоляция ненадёжного кода.</i> Ненадёжный код, как и в случае с оркестрацией, по-прежнему работает в песочнице в рамках отдельного процесса ОС.</li></ul><ul><li><i>Скорость и стабильность взаимодействия.</i> Никаких проблем с сетью  из-за локальности взаимодействия между агентом и песочницей.</li></ul><ul><li><i>Контролируемая нагрузка на песочницы.</i> Агент, выступая в роли консюмера очереди задач, может точно контролировать степень параллелизма и выбирать новые задачи только тогда, когда он закончил обрабатывать предыдущие.</li></ul><ul><li><i>Минимум инфраструктурного кода.</i> Очереди избавляют от необходимости иметь оператор песочниц, отслеживать их состояние и осуществлять балансировку нагрузки.</li></ul><ul><li><i>Простота масштабирования.</i> Приложение и песочницы масштабируются независимо друг от друга без негативных побочных эффектов.</li></ul><h2>Запуск процесса ОС</h2><p>К запуску процесса ОС, в рамках которого будет исполняться ненадёжный код, нужно подойти с особой осторожностью. Здесь важно ответить как минимум на три вопроса.</p><ul><li><i>Как ограничить права доступа к ресурсам.</i> Самое простое решение — запуск процесса от имени пользователя с ограниченными правами (на доступ к ресурсам ОС).</li></ul><ul><li><i>Как ограничить объем используемых ресурсов.</i> Для запускаемого процесса нужно определить доступные ресурсы и возможные действия.</li></ul><ul><li><i>Как осуществлять анализ поведения и результатов исполнения.</i> Наличие и решение этой проблемы целиком и полностью зависит от специфики проекта. Здесь невозможно предложить универсального решения.</li></ul><p>Рассмотрим варианты ограничения ресурсов процесса ОС.</p><h3>Ограничение ресурсов процесса</h3><p>Ресурсы процесса могут быть ограничены на трех уровнях:</p><ul><li><i>Лимиты узла.</i> Физические ограничения машины, на которой исполняется процесс. В частном случае можно говорить об инфраструктурных лимитах, определённых для Docker/Kubernetes контейнера.</li></ul><ul><li><i>Лимиты контейнера.</i> Программные лимиты, задаваемые выбранным инструментом контейнеризации (cgroup, Docker, <a href="https://dzen.ru/a/Z8sdaQvf5w96SRes">Bubblewrap</a>, <a href="https://github.com/AlexMAS/ProcessSandbox">ProcessSandbox</a> и т.п.).</li></ul><ul><li><i>Лимиты процесса.</i> Программные лимиты, задаваемые средствами ОС. На этом уровне можно осуществлять гибкую настройку вариантов запуска и исполнения.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/d11a1ee8-1780-4ca6-b826-a09d4d95ed0d.png" alt="Уровни лимитирования ресурсов процесса." /><figcaption>Уровни лимитирования ресурсов процесса.</figcaption></figure><p>Можно использовать все три уровня лимитирования, либо какой-то определенный.</p><p>Между тем, важно отметить некоторые трудности, которые могут возникнуть при использовании инструментов контейнеризации.</p><p>Например, для использования cgroup или Docker внутри Kubernetes-контейнера нужно эскалировать привилегии контейнера, что в общем случае небезопасно в контексте исполнения ненадёжного кода. Более того, практика показала, что легковесных rootless-средств, предоставляемых ОС, вполне достаточно, чтобы снять большую часть рисков. В частности, Linux API позволяет не только лимитировать CPU и память, но и блокировать доступ к некоторым возможностям самой ОС. Например, можно наложить фильтр, который запретит вызов определённых системных функций.</p><h3>Проблемы жёсткого лимитирования</h3><p>Рассмотренные выше способы лимитирования задают жёсткие границы (hard limit), нарушение которых замедляет исполнение процесса, либо приводит к его принудительному завершению. При этом поведение наблюдаемого процесса и системы сильно варьируется в зависимости от того, какой лимит был превышен. Например, превышение по использованию CPU может привести к троттлингу (throttling), приостановке работы или принудительному завершению; превышение по использованию памяти заканчивается принудительным завершением со стороны ОС (OOM Killer) либо самостоятельным падением процесса (с ошибкой Out Of Memory).</p><p>Подобная вариативность осложняет <i>анализ поведения и результатов исполнения.</i> В этом случае можно использовать подход с программной мягкой границей (watchdog limit). Суть заключается в запуске дополнительного следящего потока (или процесса) ОС, который контролирует поведение и расход ресурсов у наблюдаемого. Как только детектируется превышение одного из лимитов, производится принудительное завершение наблюдаемого процесса, но уже не со стороны ОС, а со стороны приложения.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/e38eb138-04f3-439f-89b5-9b810f112a69.png" alt="Программная мягкая граница (watchdog limit)." /><figcaption>Программная мягкая граница (watchdog limit).</figcaption></figure><p>Такой подход имеет несколько преимуществ.</p><ul><li><i>Точное определение причин принудительного завершения.</i> Жёсткие лимиты чуть выше мягких, благодаря чему для исполняемого кода создаётся иллюзия отсутствия каких-либо лимитов. Между тем, если лимиты всё-таки нарушаются, процесс всё равно будет завершен (либо со стороны приложения, либо гарантированно со стороны ОС). Но подобный дополнительный контроль со стороны приложения оставляет для него гораздо больше шансов понять причину принудительного завершения наблюдаемого процесса.</li></ul><ul><li><i>Возможность гибкого лимитирования ресурсов.</i> Приложение (или агент), ответственное за запуск наблюдаемого процесса, может обратиться к средствам ОС (в частности, к Linux API) и гибко настроить параметры запуска и исполнения. Как минимум, жёстко определить лимиты по CPU и памяти; наложить ограничения на объем I/O; создать запрет на вызов некоторых системных функций (например, запрет использования сетевых операций или файловой системы) и т.п.</li></ul><p>Такой подход я назвал watchdog и в целях иллюстрации реализовал его в виде .NET-библиотеки <a href="https://github.com/AlexMAS/ProcessSandbox">ProcessSandbox</a>. Помимо прочего, на странице проекта подробно рассмотрена проблематика контроля и анализа поведения процесса ОС со стороны прикладного кода.</p><p>Итоговая схема лимитирования может выглядеть так, как показано на рисунке ниже. Вместо тяжеловесных инструментов контейнеризации используется легковесный rootless-инструмент (watchdog) на базе средств ОС и только.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/2c5e74e4-125b-467d-8b27-30b005364523.png" alt="Лимитирование ресурсов процесса с помощью watchdog." /><figcaption>Лимитирование ресурсов процесса с помощью watchdog.</figcaption></figure><p>Для задач, где не нужен анализ поведения процесса и тонкая настройка лимитов, можно воспользоваться готовым инструментом — утилитой.</p><h2>Многоконтейнерные поды</h2><p>Зная, что контейнеры одного Kubernetes-пода работают на одном и том же узле, можно попытаться решить проблему нестабильности сетевого взаимодействия приложения и песочницы, разместив их контейнеры в одном поде.</p><figure><img src="https://media.tproger.ru/user-uploads/115455/2025-06-18/62400b6a-9c5b-4285-bff8-b0adb5ac8868.png" alt="Размещение контейнера приложения и песочницы в одном Kubernetes-поде." /><figcaption>Размещение контейнера приложения и песочницы в одном Kubernetes-поде.</figcaption></figure><p>Несмотря на всю заманчивость данной идеи, она несёт ряд недостатков.</p><ul><li><i>Плохая масштабируемость.</i> Соотношение приложение-песочница всегда один к одному. Однако не исключено, что в некоторых случаях это вполне приемлемо.</li></ul><ul><li><i>Плохая утилизация ресурсов.</i> Сможет ли приложение достаточно нагрузить песочницу, если количество песочниц будет в избытке; и наоборот, нужно ли столько же экземпляров приложения, сколько и песочниц.</li></ul><ul><li><i>Возможность перегрузки песочницы.</i> В распоряжении экземпляра приложения только одна песочница, которая может не справиться с потоком задач, обрабатываемых приложением.</li></ul><ul><li><i>Риск нарушить работоспособность приложения.</i> Выход песочницы из строя скорее всего приведет к перезапуску всего пода. Более того, если приложение и песочница обмениваются файлами через общий раздел (<a href="https://kubernetes.io/docs/tasks/access-application-cluster/communicate-containers-same-pod-shared-volume/">shared volume</a>), это может стать уязвимым местом.</li></ul><h2>Образ для песочницы</h2><p>Основные моменты, которые следует учесть при создании (Docker) образов песочниц:</p><ul><li><i>Заменить init-процесс</i> на <a href="https://github.com/krallin/tini">tini</a>, чтобы не превысить лимит по PIDs.</li></ul><ul><li><i>Создать непривилегированного пользователя,</i> ограничив ему права на доступ к ресурсам.</li></ul><ul><li><i>Регулярно сканировать версии образов</i> и пакетов на наличие уязвимостей.</li></ul><h2>Инфраструктура исполнения</h2><p>Основные моменты, которые следует учесть при настройке инфраструктуры исполнения:</p><ul><li><i>Обеспечить быстрый (пере)запуск песочниц.</i> Нужно быть готовым к тому, что песочницы будут падать. Если речь идет о Kubernetes, то улучшить время запуска может подходящая настройка <a href="https://kubernetes.io/docs/concepts/containers/images/">Image Pull Policy</a>. При этом лучше не использовать тег `latest`, а указывать конкретную версию или хэш-код образа, чтобы не тратить время на попытки определения последней версии при каждом запуске.</li></ul><ul><li><i>Установить приемлемый <a href="https://kubernetes.io/docs/concepts/policy/pid-limiting/">лимит на PIDs</a>.</i> Необходимо контролировать число активных процессов в системе. Особо вредоносный код может попытаться создать очень много дочерних процессов, поэтому при отсутствии лимита на PIDs узел быстро будет выведен из строя. Важно отметить, что лимит задаётся для пользователя, а не для запускаемого процесса. По этой причине он должен быть разумно большим.</li></ul><ul><li><i>Установить <a href="https://kubernetes.io/docs/concepts/policy/resource-quotas/">лимиты на ресурсы узла</a>.</i> В Kubernetes для каждого контейнера нужно указать, как минимум, лимиты по CPU и памяти. Значения лимитов лучше всего определить в ходе нагрузочного тестирования или путём сбора метрик приложения.</li></ul><h2>Заключение</h2><p>Как можно заметить, задача исполнения ненадёжного кода всегда решается в комплексе, начиная с анализа, продолжая разработкой и заканчивая вопросами уровня DevOps. Думаю, что многие техники и инструменты применимы и к коду самого приложения.</p><p>Я постарался показать последовательность шагов по направлению к целевой архитектуре, которая будет отвечать требованиям бизнеса и справляться с ненадёжным кодом. <i>Если вам интересна данная тематика, подписывайтесь на мой Telegram-канал Архитектоника в ИТ (@arch_and_dev). Буду рад поделиться опытом. </i></p>]]></content:encoded>
    </item>
    <item>
      <title>HUAWEI откроет исходный код «убийцы» Java и Swift — языка Cangjie</title>
      <link>https://tproger.ru/news/--huawei-otkroet-ishodnyj-kod--ubijcy--java-i-swift---yazyka-cangjie</link>
      <comments>https://tproger.ru/news/--huawei-otkroet-ishodnyj-kod--ubijcy--java-i-swift---yazyka-cangjie?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/--huawei-otkroet-ishodnyj-kod--ubijcy--java-i-swift---yazyka-cangjie</guid>
      <description><![CDATA[<p>HUAWEI 30 июля откроет исходный код языка Cangjie — альтернативы Java и Swift, созданной для HarmonyOS с упором на ИИ и безопасность</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/--huawei-otkroet-ishodnyj-kod--ubijcy--java-i-swift---yazyka-cangjie">HUAWEI откроет исходный код «убийцы» Java и Swift — языка Cangjie</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Сервисы]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 04 Jul 2025 04:37:45 GMT</pubDate>
      <content:encoded><![CDATA[<p>HUAWEI <a href="https://www.scmp.com/tech/big-tech/article/3316506/huawei-open-source-self-developed-programming-language-cangjie-rival-java-and-swift">объявила</a>, что 30 июля откроет исходный код собственного языка программирования Cangjie. Это часть стратегии компании по снижению зависимости от иностранных технологий и развития своей экосистемы.</p><h2>Что такое Cangjie</h2><p>Cangjie — язык общего назначения, разработанный для HarmonyOS Next. Это та самая операционная система, созданная на замену Android после американских санкций.</p><p>По словам HUAWEI, язык подходит для <b>разработки «во всех сценариях»</b>, включая мобильные приложения, распределённые системы и ИИ-сервисы.</p><p>Особенности Cangjie:</p><ul><li>Нативная поддержка ИИ</li><li>Фокус на безопасности</li><li>Поддержка приложений не только на HarmonyOS, но и на Android с iOS</li></ul><p>Таким образом, Cangjie позиционируется как альтернатива Java (в экосистеме Android) и Swift (в iOS).</p><h2>Как развивается экосистема</h2><p>Язык разрабатывался почти пять лет и впервые был представлен в июне 2023 года. За несколько недель он привлёк свыше <b>10 000 заявок на участие в тестировании</b>.</p><p>Уже в октябре прошлого года Cangjie стал доступен всем разработчикам HarmonyOS, а к июлю 2025 его используют крупные игроки:</p><ul><li><b>Meituan</b> — пишет на Cangjie приложение для доставки, релиз которого ожидается в III квартале;</li><li><b>JD.com</b> — использует язык в мобильных решениях для собственной платформы.</li></ul><h2>Почему это важно</h2><p>Cangjie — ещё один шаг в сторону <b>технологического суверенитета</b> Китая. Под американскими санкциями HUAWEI активно выстраивает собственную экосистему — от ОС и чипов до языков программирования и облачных сервисов.</p><h2>Что дальше</h2><p>С 30 июля исходный код Cangjie будет доступен всем. HUAWEI рассчитывает, что открытие языка ускорит его адаптацию и создаст альтернативу западным технологиям — в первую очередь в Китае, а затем и за его пределами.</p><p>Посмотреть документацию языка можно по <a href="https://cangjie-lang.cn/en/docs?url=/0.53.13/user_manual/source_en/first_understanding/basic.html">ссылке</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Microsoft выпустил бесплатный курс по Model Context Protocol с практикой на Python, C# и Java</title>
      <link>https://tproger.ru/news/microsoft-vypustil-besplatnyj-kurs-po-model-context-protocol-s-praktikoj-na-python--c--i-java</link>
      <comments>https://tproger.ru/news/microsoft-vypustil-besplatnyj-kurs-po-model-context-protocol-s-praktikoj-na-python--c--i-java?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/microsoft-vypustil-besplatnyj-kurs-po-model-context-protocol-s-praktikoj-na-python--c--i-java</guid>
      <description><![CDATA[<p>Microsoft запустил бесплатный практический курс по протоколу Model Context Protocol (MCP) с примерами на Python, C#, Java и TypeScript для разработки LLM-приложений и серверов MCP.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/microsoft-vypustil-besplatnyj-kurs-po-model-context-protocol-s-praktikoj-na-python--c--i-java">Microsoft выпустил бесплатный курс по Model Context Protocol с практикой на Python, C# и Java</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[TypeScript]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Microsoft Project Scorpio]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[CI/CD]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 03 Jul 2025 10:13:53 GMT</pubDate>
      <content:encoded><![CDATA[<p>На GitHub появился полноценный <a href="https://github.com/microsoft/mcp-for-beginners/?tab=readme-ov-file">бесплатный курс</a> от Microsoft по Model Context Protocol (MCP) — протоколу, который помогает упростить интеграцию LLM и клиентских приложений и стандартизировать их взаимодействие. Учебная программа с открытым исходным кодом рассчитана на разработчиков ИИ, системных архитекторов и инженеров, которые хотят понять, как строить агентные системы и управлять контекстом запросов к языковым моделям.</p><p>Больше новостей — в нашем канале <a href="https://t.me/+WYtyV4-XYmdhZTMy">Представляешь</a></p><h2>Подробности</h2><p>MCP уже становится стандартом для корпоративных ассистентов и мультиагентных систем: протокол позволяет гибко управлять маршрутами вызовов между моделями и сервисами, снижает хаос в интеграциях и упрощает масштабирование LLM-приложений. Теперь у инженеров появилась возможность изучить MCP на практике: в курсе представлены готовые проекты и живой код на Python, C#, Java, TypeScript и JavaScript, есть пошаговые инструкции по настройке среды, запуску серверов и клиентов, интеграции с пайплайнами CI/CD, а также подробные объяснения архитектуры и рекомендаций по безопасности.</p><h3>Что есть в учебной программе</h3><p>Курс разделён на несколько блоков: от основ MCP и настройки окружения до практического создания серверов и клиентов, работы с потоковой передачей данных и построения мультимодальных систем. Также рассматриваются вопросы масштабирования, интеграции с Azure AI и OpenAI, построения защищённых серверов и развертывания LLM-агентов. Особое внимание уделено тому, как MCP помогает организовать работу с контекстом запросов и объединением нескольких моделей, включая сценарии корпоративного применения.</p><p>План следующий:</p><ul><li><b> Уроки 1–2 </b>— введение в протокол, настройка среды, запуск базового MCP-сервера и клиента, интеграция в существующие пайплайны, безопасность.</li></ul><ul><li><b> Урок 3 (большой модуль)</b> — создание и развертывание рабочего MCP-сервера и клиента: от локальной разработки и тестирования в Visual Studio Code с AI Toolkit до развертывания сервера с SSE и HTTP-стримингом, а также построения клиентов на Python и TypeScript.</li></ul><ul><li><b>Уроки 4–5</b> — практическое применение: от отладки и тестирования до масштабирования, мультимодальности и интеграции с Azure AI Foundry, OAuth2 и системами Entra ID.</li></ul><ul><li><b>Уроки 6–9</b> — лучшие практики, вклад сообщества, разбор реальных кейсов ранних внедрений, лабораторные работы.</li></ul><ul><li><b>Урок 10</b> — практическая лаборатория: создание MCP-сервера с помощью AI Toolkit для VSCode, демонстрация потоковой передачи данных в реальном времени, интеграции с внешними LLM и корпоративными пайплайнами.</li></ul><p>Курс будет полезен как тем, кто только начинает изучать работу с языковыми моделями и строит свои первые ассистенты, так и опытным разработчикам, которым нужны структурированные практики и кейсы. Для старта достаточно базового понимания Python, C# или Java, а также представления о модели клиент-сервер и API.</p><p>Учебная программа уже <a href="https://github.com/microsoft/mcp-for-beginners/?tab=readme-ov-file">доступна</a> в официальном репозитории MCP на GitHub. Там можно найти SDK с открытым исходным кодом, инструкции по работе с AI Toolkit для VSCode, шаблоны проектов и примеры кода, которые можно запускать и адаптировать под свои задачи.</p><p>Протокол MCP становится частью экосистемы OpenAI и Azure AI, и умение работать с ним может дать инженерам конкурентное преимущество в новых проектах, связанных с LLM и корпоративными ассистентами. Новые уроки и примеры будут постепенно добавляться в репозиторий, поэтому курс обещает оставаться актуальным в быстро меняющемся мире ИИ.</p><h4>Полезные ссылки</h4><ul><li><a href="https://modelcontextprotocol.io/">Документация MCP</a> — подробные учебные пособия и руководства пользователя</li><li><a href="https://spec.modelcontextprotocol.io/">Спецификация MCP</a> — архитектура протокола и технические рекомендации</li><li><a href="https://github.com/modelcontextprotocol">Репозиторий MCP на GitHub</a> — SDK с открытым исходным кодом, инструменты и примеры кода</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Архитектура BFF (Backend for Frontend): зачем нужна прослойка</title>
      <link>https://tproger.ru/articles/arhitektura-bff--backend-for-frontend---zachem-nuzhna-proslojka</link>
      <comments>https://tproger.ru/articles/arhitektura-bff--backend-for-frontend---zachem-nuzhna-proslojka?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Вадим Егорцев]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/arhitektura-bff--backend-for-frontend---zachem-nuzhna-proslojka</guid>
      <description><![CDATA[<p>Что такое архитектура BFF. Показываем, зачем нужна прослойка Backend for Frontend. Рассматриваем преимущества и основные нюансы ✔ Tproger</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/arhitektura-bff--backend-for-frontend---zachem-nuzhna-proslojka">Архитектура BFF (Backend for Frontend): зачем нужна прослойка</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Оптимизация]]></category>
      <category><![CDATA[Парсинг]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[Производительность]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Стартапы]]></category>
      <category><![CDATA[Бэкенд]]></category>
      <category><![CDATA[App Store]]></category>
      <category><![CDATA[CSR]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Spotify]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Дизайн]]></category>
      <category><![CDATA[NFT]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[микро]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 30 Jun 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Представьте ситуацию: ваш REST API для CRM-системы отлично работает с веб-версией. Создаёте мобильное приложение для курьеров и упираетесь в стену. Эндпоинт заказов тащит 40 лишних полей с финансовой отчётностью, а нужной геолокации складов нет.</p><p>Может плодить новые эндпоинты или заставлять мобилку делать несколько запросов вместо одного? Каждый запрос жрёт трафик и батарею!</p><p>Элегантное решение — <b>архитектура Backend for Frontend (BFF)</b>. Это прослойка между клиентскими приложениями и основным API, которая адаптирует данные под потребности конкретного клиента.</p><h2>Основная идея backend for frontend</h2><p>Один API не может эффективно обслуживать разные типы клиентов. Сайт, приложение для iOS, Android, умные часы — у каждого свои потребности в данных, ограничения по производительности и особенности интерфейса.</p><p>Монолитный API создают с расчётом на универсальность — на практике это приводит к компромиссам. Веб-версии нужны данные для сортировки, мобильному приложению — минимальный набор для экономии трафика.</p><p><b>Следуя архитектуре BFF, вы можете создать логику для каждого типа клиента и не засорять основной API.</b> Вместо одного эндпоинта <i>/api/products</i>, который пытается угодить всем, появляются слои:</p><ul><li>один — оптимизирует данные для веба,</li><li>второй — для мобильных устройств,</li><li>третий — для умных часов.</li></ul><p>Обычно данные приходят в неудобном виде: несколько связанных сущностей нужно запрашивать отдельно и склеивать на клиенте. BFF берёт эту работу на себя.</p><p>Прослойка знает, что мобильному приложению нужны цены в рублях с округлением до целых, а веб-версии — точные значения в долларах. Для списка товаров мобилке достаточно названия и цены, а десктопной версии нужны ещё категории, рейтинги и количество отзывов.</p><p><b>Каждый клиент получает данные в том виде, в котором может их сразу отобразить</b>. Вместо загрузки 50 полей, из которых используется 5, BFF отдаёт только нужные данные.</p><p>«Можете добавить поле user_avatar в ответ?»</p><p>—<i> «Это сломает мобилку».</i></p><p>«Тогда сделайте отдельный эндпоинт».</p><p>—<i> «У нас нет времени».</i></p><p>С BFF этого диалога нет. Фронтенд-команда получает свой API и крутит его, как хочет.</p><p>Мобильное приложение съедает 10к запросов в секунду? Пишите BFF на Go. Веб-версию делает стажёр, который знает только JavaScript? Ставьте Node.js. Никто не заставляет выбирать одну технологию на все случаи жизни.</p><h2>Как работает backend for frontend (BFF)</h2><p>BFF размещается между клиентскими приложениями и основными бэкенд-сервисами, выполняя роль посредника. В отличие от API Gateway, который просто перенаправляет запросы, BFF трансформирует данные.</p><h3>Архитектура взаимодействия</h3><p>Классическая схема выглядит так: мобильное приложение обращается к своему BFF, веб-приложение — к своему, умные часы — к третьему. Каждый BFF знает особенности своего клиента и общается с основными сервисами на их «языке».</p><figure><img src="https://media.tproger.ru/user-uploads/105601/2025-06-06/a765d5ae-2c66-4a1a-83fd-2f977ac31fa2.jpg" alt="" /><figcaption>Прослойка между клиентами и API</figcaption></figure><p>Когда мобильное приложение запрашивает список заказов, его BFF делает несколько вызовов к микросервисам:</p><ul><li>берёт базовую информацию о заказах,</li><li>подтягивает данные о товарах,</li><li>получает статусы доставки.</li></ul><p>Затем склеивает всё в один ответ, отбрасывая ненужные поля и добавляя вычисляемые значения.</p><p>Веб-версия для того же списка заказов получит расширенную информацию: подробные описания товаров, историю изменений статусов, данные для аналитики.</p><h3>Обработка и агрегация данных</h3><p>BFF не просто перекладывает данные из одного формата в другой. Он выполняет бизнес-логику.</p><p><i>Например, мобильный BFF может кешировать часто запрашиваемые данные, чтобы уменьшить количество сетевых запросов.</i></p><p>Если API возвращает цены в центах, мобильный BFF конвертирует их в рубли и округляет для отображения. Веб-версия получает точные значения с копейками для расчётов.</p><h3>Независимость и масштабирование</h3><p>Когда нагрузка на приложение растёт, масштабируется только его BFF. Проблемы с веб-версией не влияют на работу мобильных клиентов.</p><h2>4 ключевых преимущества BFF</h2><h3>Оптимизация передачи данных</h3><p>Самое очевидное преимущество — экономия трафика. Приложение не тащит 2 МБ JSON с полным каталогом товаров на мобильное устройство? BFF отдаёт только нужные поля.</p><p>Количество запросов тоже сокращается. Например, чтобы показать профиль пользователя, фронтенд делает 5 запросов:</p><ul><li>за основными данными,</li><li>аватаром,</li><li>списком друзей,</li><li>последними постами,</li><li>настройками приватности.</li></ul><p>BFF объединяет всё в один запрос, получая данные параллельно от разных сервисов.</p><h3>Упрощение фронтенда</h3><p>Половина фронтенд-кода уходит на трансформацию ответов API:</p><ul><li>парсинг дат,</li><li>группировку массивов,</li><li>вычисление производных значений.</li></ul><p>BFF может взять эту работу на себя.</p><h3>Безопасность через изоляцию</h3><p>BFF создаёт барьер между клиентами и сервисами. Мобильное приложение никогда напрямую не обращается к БД пользователей или платёжке — только через свой BFF.</p><p>Можно настроить разные уровни доступа:</p><ul><li>мобильный BFF видит только публичные данные,</li><li>API для партнёров работает в песочнице.</li></ul><p>Если мобильное приложение скомпрометировано, злоумышленник не получит доступ к внутренним сервисам.</p><h3>Независимое масштабирование</h3><p>Когда приложение попадает в топ App Store, нагрузка взлетает в разы. Но страдает только мобильный BFF — веб-версия продолжает работать стабильно. Можно быстро поднять дополнительные серверы только для мобильного трафика.</p><p>Появляется возможность экспериментировать с технологиями без риска. Хотите попробовать GraphQL для веб-версии? Внедряйте в один BFF. Тестируете новую базу данных? Подключайте к экспериментальной прослойке, не трогая продакшн.</p><h2>Когда стоит использовать backend for frontend</h2><p>BFF — инструмент для конкретных ситуаций.</p><h3>Когда интерфейсы кардинально отличаются</h3><p>Если ловите себя на мысли: <i>«этот эндпоинт нужен только для веба»</i> или <i>«мобилка использует 10% полей из ответа»</i>, — пора задуматься о BFF.</p><p>Красный флаг — когда фронтенд-разработчики начинают писать костыли для обработки «неудобных» данных. Если половина JavaScript-кода занимается парсингом и трансформацией ответов API, что-то пошло не так.</p><h3>Когда интерфейсы эволюционируют быстрее джунов</h3><p>Стартапы и продукты в активной фазе развития меняют интерфейсы каждую неделю.</p><p>Классическая проблема: дизайнеры придумали новый способ отображения товаров в каталоге. Теперь нужны дополнительные поля, другая группировка, новые фильтры.</p><p>Без BFF это означает изменения в основном API, которые могут сломать другие клиенты. С BFF — правки только в одном месте.</p><h3>Когда команды работают независимо</h3><p>Если у вас несколько фронтенд-команд, которые постоянно конфликтуют из-за API, BFF даст им свободу.</p><p>Команды получат свой API, который смогут развивать в нужном темпе. Это важно в больших компаниях, где бэкенд не успевает обрабатывать запросы от всех фронтендеров.</p><p>BFF распределяет ответственность: каждая команда поддерживает свой слой.</p><h3>Когда НЕ стоит использовать BFF</h3><p>Если у вас простое приложение с одним клиентом, BFF добавит лишнюю сложность. Если API уже идеально подходит всем клиентам, зачем что-то менять?</p><h2>3 типичные ошибки при внедрении BFF</h2><h3>Дублирование логики</h3><p>Начинается незаметно: мобильный и веб BFF нуждаются в одинаковой валидации пользователей. Разработчик копирует функцию из одного проекта в другой. Через полгода одинаковый код валидации живёт в четырёх местах, и каждое изменение превращается в квест.</p><p>Хуже, когда дублируется бизнес-логика. Расчёт скидок, обработка промокодов, правила доступа — это должно жить в основных сервисах, а не размазываться по BFF-слоям.</p><h3>Избыточная сложность вместо упрощения</h3><p>Пример: команда создаёт «универсальный BFF-фреймворк» с конфигурацией через YAML, поддержкой плагинов и собственным DSL. В итоге простое добавление поля в ответ требует изучения документации на 50 страниц.</p><p>Другая крайность — микро-BFF для каждой мелочи. Отдельный слой для авторизации, отдельный для форматирования дат, отдельный для валидации.</p><h3>Неправильная гранулярность</h3><p>Один BFF на все мобильные платформы может быть слишком общим: iOS и Android имеют разные особенности интерфейса. Но отдельный BFF для каждой версии приложения — явный перебор.</p><p>Частая ошибка — создание BFF по организационному принципу, а не по техническому. У нас три фронтенд-команды, значит нужно три прослойки. Но если все команды работают с похожими данными и интерфейсами, логичнее объединить усилия.</p><h2>Практические примеры использования BFF</h2><h3>Netflix</h3><p>Компания <a href="https://netflixtechblog.com/seamlessly-swapping-the-api-backend-of-the-netflix-android-app-3d4317155187">сделала</a> разные API для веб-версии, мобильных приложений, Smart TV и игровых консолей. Каждый BFF оптимизирован под особенности устройства, например, TV-версия предзагружает больше контента из-за медленной навигации пультом.</p><h3>Spotify</h3><p><a href="https://developer.spotify.com/documentation/web-api">Используют</a> BFF для разных клиентов: веб-плеер, мобильные приложения, десктопное приложение. Мобильный BFF агрессивно кеширует данные для офлайн-режима, веб-версия работает в реальном времени.</p><h3>SoundCloud</h3><p>Публично <a href="https://developers.soundcloud.com/blog/service-architecture-1">описывали</a> переход на BFF-архитектуру. У них отдельные слои для веб-версии и мобильных приложений, которые по-разному обрабатывают аудиопотоки и метаданные треков.</p><h2>Заключение</h2><p>Страдают все, когда один API пытается обслуживать веб-версию, мобилки и что-то ещё. Фронтенд получает неудобные данные, бэкенд обрастает костылями, пользователи — медленными приложениями.</p><p>Backend for Frontend создаёт слой между клиентами и основными сервисами. Каждый тип устройства получает API, заточенный под его потребности.</p><p>Внедряйте BFF, когда интерфейсы кардинально отличаются, продукт быстро развивается, а текущий API снижает производительность.</p><p>Ты уже программист, если читаешь это! Больше про кодинг — <a href="https://t.me/+a1v-IRDDUqI0MDhi">здесь</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>n8n: установка, настройка и интеграция с Python, Node.JS и PHP</title>
      <link>https://tproger.ru/articles/n8n--ustanovka--nastrojka-i-integraciya-s-python--node-js-i-php</link>
      <comments>https://tproger.ru/articles/n8n--ustanovka--nastrojka-i-integraciya-s-python--node-js-i-php?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Кирилл Косолапов]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/n8n--ustanovka--nastrojka-i-integraciya-s-python--node-js-i-php</guid>
      <description><![CDATA[<p>Подробный туториал по установке и настройки n8n. Примеры интеграции с Python, Node.JS и PHP и взаимодействия с LLM Mistral AI.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/n8n--ustanovka--nastrojka-i-integraciya-s-python--node-js-i-php">n8n: установка, настройка и интеграция с Python, Node.JS и PHP</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[PHP]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Opera]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Telegram]]></category>
      <category><![CDATA[Docker]]></category>
      <category><![CDATA[OpenAI]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Sun, 29 Jun 2025 09:00:00 GMT</pubDate>
      <content:encoded><![CDATA[<p>n8n — open-source платформа для автоматизации рабочих процессов (workflow), позволяющая создавать сложные цепочки задач без глубоких знаний программирования.</p><p><b>В статье рассмотрим:</b></p><p>- Установку локально и в облаке;</p><p>- Интеграцию с Python, Node.js и PHP;</p><p>- Примеры автоматизаций;</p><p>- Интеграцию с AI Mistral.</p><h2>Установка n8n</h2><h3>Локальная установка</h3><p>Нам потребуется Docker, проверьте установку:</p><p><b>Шаги установки:</b></p><p>1. Создайте том данных:</p><p>2. Запустите контейнер:</p><p>После запуска откройте: `http://localhost:5678`</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/32713acd-811d-40dc-8141-4fb625cd4216.png" alt="" /></figure><h3>Установка на удаленном сервере</h3><p>Развертывание мы произведем в облаке <a href="https://amvera.ru/n8n">Amvera</a>, так как в нем n8n предоставляется как преднастроенный сервис с бесплатным доменом (он нам нужен), настроенными переменными и проксированием до заблокированных в РФ LLM (OpenAI, Gemini, Claude и др.).</p><p>1. Регистрируемся на <a href="https://amvera.ru/n8n">Amvera</a>;</p><p>2. Выбираем n8n в плитке на главной странице;</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/e74d96ee-5f96-4c61-bf7a-562a38edc703.png" alt="" /></figure><p>3. Вводим название для проекта и выбираем тариф.</p><p><b>Готово, через 30 секунд запустится n8n с выделенным доменом и настроенными основными переменными.</b></p><h2>Настройка n8n</h2><h3>Первоначальная настройка</h3><p>1. Откройте n8n (локально: `localhost:5678`, в облаке: ваш домен)</p><p>2. Заполните данные администратора:</p><ul><li>Email</li></ul><ul><li>Имя/Фамилия</li></ul><ul><li>Пароль</li></ul><p>3. По желанию вы можете получить бесплатный лицензионный ключ:</p><ul><li>Введите email → "Send me a free license key"</li></ul><ul><li>Активируйте в разделе Settings → Usage</li></ul><h3>Настройка для HTTP</h3><p>1. Создайте новый <b>workflow</b> → Start from scratc</p><p>2. Добавьте триггер: <b>Webhook</b> - <b>On webhook call</b></p><p>3. Настройте:</p><ul><li>HTTP Method: POST</li></ul><ul><li>Path: `/n8n` (пример)</li></ul><ul><li>Respond Mode: Using 'Respond to Webhook' node</li></ul><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/6e51fb08-a901-408c-833e-eb27c3ab1f17.png" alt="" /></figure><p>4. Добавьте обработчик: <b>Core</b> → <b>Respond to Webhook</b></p><p>5. Настройте ответ:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/37a5add7-0873-42e1-9004-d33a228d828b.png" alt="" /></figure><h2>Примеры использования</h2><h3>Пример на Python</h3><p>В примере на Python мы сделаем калькулятор. Суть: отправляем выражение через POST,  n8n делает вычисление, возвращаем результат.</p><p><b>Workflow</b>:</p><p>1. Добавьте <b>Core</b> → <b>Code node</b> между Webhook и Respons:</p><p><b>Клиент (Python):</b></p><p>Запустим код и посмотрим результат:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/c9a2bd14-0a7e-4c6f-8544-e4a098a5cd5e.png" alt="" /></figure><h3>Пример на PHP</h3><p>В примере на PHP мы сделаем валидацию данных. Суть: отправляем данные через POST, n8n проверяет данные, возвращает результат.</p><p><b>Workflow (Code node):</b></p><p><b>Клиент (PHP):</b></p><p>Можем зайти на нашу страницу, все работает нормально:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/722241bc-9794-41eb-9d32-8d73d7147800.png" alt="" /></figure><h3>Пример на Node.js</h3><p>Примером на node.js будет фильтр запрещенных слов. Суть: отправляем текст, n8n проверяет на наличие плохих слов, возвращает результат.</p><p><b>Workflow (Code node):</b></p><p><b>Клиент (Node.js):</b></p><p>Перед запуском установим библиотеку командой `npm install axios`</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/c56f275a-8c74-49bf-80e5-22d5becd222a.png" alt="" /></figure><h3>Интеграция n8n с Mistral AI</h3><p>Мы интегрируем нейросеть Mistral в телеграмм-бота на C# с помощью n8n. Перед тем как начать, нам нужно получить токен.</p><p>1. Зарегистрируйтесь на <a href="https://mistral.ai/">Mistral</a></p><p>2. Создайте агента <b>Сreate an agent</b></p><p>3. Перейдите в раздел <b>API Keys</b></p><p>4. Создайте и скопируйте API-ключ (звездочки наложены):</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/7bb95f2e-0ebe-47af-9089-5e10ee2822cf.png" alt="" /></figure><p>Теперь нужно создать credentials для работы с созданной моделью. Для этого в правом верхнем углу нажмите <b>Create credentials</b>. В списке найдите <b>Mistral Cloud API</b>. В открывшемся окне вставьте скопированный ключ и сохраните.</p><p>Осталось настроить workflow.</p><p>1. Добавляем <b>Webhook</b>:</p><ul><li>Method: POST</li></ul><ul><li>PATH: n8n</li></ul><ul><li>Respond: Using 'Respond to Webhook' Node</li></ul><p>2. Добавляем <b>AI Agent</b>:</p><ul><li>Source for Prompt: Define below</li></ul><ul><li>Prompt: `{{ $json.body.text }}`</li></ul><p>3. Подключаем <b>Chat Model </b>к созданному агенту:</p><ul><li>Credential to connect with: Mistral Cloud API</li></ul><ul><li>Model: mistral-large-2411</li></ul><p>4. Добавляем <b>Respond to Webhook</b></p><p>Вот так выглядит готовый workflow:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/b2618a94-f3eb-4055-9061-ab185aca9d9d.png" alt="" /></figure><p>Можем приступить к созданию бота. Для начала введите эти команды по очередности:</p><p>Переходим в папку с кодом и редактируем файл `Program.cs`:</p><p>Запустите бота с помощью команды `dotnet run`.</p><h3>Автоматизируем с помощью n8n</h3><p>В примере автоматизации мы сделаем бота, который будет отправлять уведомления при заполнении формы, полностью без кода.</p><p>Для работы с <b>Telegram Node</b> понадобиться создать credentials <b>Telegram API</b>. Туда вставляем токен бота, полученный в @BotFater. Сохраняем и переходим к настройке workflow.</p><p><b>Создаем новый workflow. </b></p><p>1. Добавляем <b>On form submission</b>. В качестве примера я создам самую простую форму:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/3bd6f188-16bd-4fa4-bde2-f7a88855bdad.png" alt="" /></figure><p>Перейдите по ссылке в <b>Producrion URL</b> чтобы заполнить форму.</p><p>2. Добавляем <b>Telegram Node</b>:</p><ul><li>Credential to connect with: Telegram account</li></ul><ul><li>Resource: Message</li></ul><ul><li>Operation: Send message</li></ul><ul><li>Chat ID: вставьте свой telegram id</li></ul><p>Text:</p><p>Готово! При новых заявках бот будет присылать уведомления.</p><h3>Деплой бота в Amvera Cloud</h3><p>Перед тем как начать деплой, мы должны создать конфигуационнный файл `amvera.yml`. Для этого создаем его в рабочем каталоге с ботом и вводим следующее:</p><p>Строго говоря, этот файл проще создать в конфигураторе в интерфейсе.</p><p>2. Структура проекта будет такой:</p><p>tg-bot/</p><p>├── Program.cs</p><p>├── tg-bot.csproj</p><p>├── amvera.yml</p><p>├── bin/</p><p>└── obj/</p><p>Идем В Amvera Cloud и создаем приложение <b>Приложения</b> — <b>Создать приложение</b>. Вводим название и выбираем тариф.</p><p>Далее загружаем все файлы, что есть у нас в каталоге, с ботом. В конце будет окно с настройкой конфигуцрации, выглядит оно так:</p><figure><img src="https://media.tproger.ru/user-uploads/115814/2025-06-16/7806bf2f-38e5-4aa4-ade2-6c12d3f6c214.png" alt="" /></figure><p>Нажимаем <b>Завершить</b> и ждем когда приложение будет запущено.</p><h2>Заключение</h2><p>n8n — мощный инструмент для создания интеграций и автоматизаций. Надеюсь, статья была вам полезна и буду рад обсудить в комментариях любые вопросы!</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>Эволюция программиста 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>Комментарии в коде: зло или спасение ?</title>
      <link>https://tproger.ru/articles/kommentarii-v-kode--zlo-ili-spasenie--</link>
      <comments>https://tproger.ru/articles/kommentarii-v-kode--zlo-ili-spasenie--?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Baskon]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kommentarii-v-kode--zlo-ili-spasenie--</guid>
      <description><![CDATA[<p>Когда нужны комментарии в коде, а когда без них лучше. Объясняем на примерах, как писать понятные и полезные комментарии</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kommentarii-v-kode--zlo-ili-spasenie--">Комментарии в коде: зло или спасение ?</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[C#]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Python]]></category>
      <category><![CDATA[IDE]]></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[MIT]]></category>
      <category><![CDATA[QA]]></category>
      <category><![CDATA[Игра]]></category>
      <category><![CDATA[Safari]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Машин]]></category>
      <category><![CDATA[аналитик]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[DeFi]]></category>
      <category><![CDATA[Бизнес]]></category>
      <category><![CDATA[XML]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 23 Jun 2025 10:39:48 GMT</pubDate>
      <content:encoded><![CDATA[<p>Что делать с комментариями в коде — писать или не писать? Одни уверены: чистый код говорит сам за себя, другие не представляют работу без пояснений. Истина, как обычно, посередине. Комментарии — это инструмент, умелый программист применяет их с пользой, неумелый — только усложняет жизнь себе, коллегам, начальству, пользователям и вообщем всем сопричастным. Разберемся, когда комментарии действительно нужны, а когда от них больше вреда и приведем примеры в коде</p><h2>Зачем вообще писать комментарии в коде?</h2><p>Комментарии — это кусочки текста в программе, которые компилятор пропускает, а человек читает. Они не влияют на работу программы, зато сильно влияют на мозг того, кто будет с этой программой разбираться.</p><h3>Какие задачи они решают ?</h3><h4>1. Пояснить неочевидное</h4><p>Код показывает «что» делает программа, а комментарий — «зачем».</p><p>Такой комментарий не просто поясняет логику — он экономит десятки минут будущего чтения.</p><h3>2. Предупредить</h3><p>В коде бывает странное поведение. Иногда это не баг, а фича. И если не предупредить, другой разработчик обязательно «поправит» и всё сломает. Комментарий защитит от этого:</p><h3>3. Пометить незавершёнку</h3><p>TODO, FIXME, HACK — это специальные маячки. Их ставят туда, где нужно что-то доделать, починить или переписать по-человечески.</p><p>Бонусом, IDE умеют обрабатывать такие заметки, каждая по-своему.</p><h3>4. Временно отключить код</h3><p>Иногда нужно что-то закомментировать, чтобы проверить гипотезу. Но такой код нельзя оставлять надолго. Если от него нет пользы — в мусор. Историю всё равно сохранит git.</p><h3>5. Объяснить архитектуру</h3><p>Иногда важно не только «как» сделано, но и «почему так». Особенно это касается паттернов, нестандартных решений или компромиссов.</p><h3>6. Генерация документации</h3><p>Многие языки и фреймворки поддерживают специальные форматированные комментарии для генерации документации. Например, JavaDoc в Java, docstring в Python, XML в C# – предназначены для описания интерфейсов: что делает функция или класс, какие имеют входные параметры и какой результат дают. Такие Комментарии выполняют роль пользовательской документации прямо в коде и могут автоматически собираться в справочник по API.</p><h3>7. Пошутить</h3><p>Программисты – тоже люди, и иногда оставляют в коде шуточные либо эмоциональные комментарии, чтобы снять стресс. В открытых исходниках можно встретить комментарии с шутками, сарказмом или даже ругательствами, адресованными сложному коду или «костылям».</p><p>Как видно, диапазон применения комментариев очень широк. Но одинаково ли хорошо все эти виды влияют на качество кода? Рассмотрим случаи, когда комментарии приносят пользу, а когда создают проблемы.</p><h2>Когда комментарии помогают</h2><p>А часто без комментариев в коде сложно разобраться, особенно когда  код чужой.</p><h3>1. Когда логика не лежит на поверхности</h3><p>Есть участки кода, где без контекста трудно разобраться, даже если код написан довольно читабельно. Например, сложная формула, нетривиальный алгоритм или необычная структура данных – всё, что выбивается из обыденного опыта разработчиков. В таких случаях пара строк комментария, резюмирующих подход, или объясняющих, что происходит, сэкономят часы на анализ. Это особенно важно для командной работы: коллегам, незнакомым с модулем, не придётся разбираться «с нуля».</p><h3>2. Когда нужно документировать контракты и условия</h3><p>Комментарии могут  использоваться для обозначения контрактов – предусловий и постусловий функций, инвариантов и т.д. (подход Design by Contract). Хотя современные языки позволяют выразить многое (например, через assert или декораторы), комментарии могут дополнять код уточнениями вроде:</p><p>Также текстовые пометки в коде полезны для фиксации граничных условий и особых случаев, таких как обработка пустных массивов в бинарном поиске,  другой пример:</p><p>Да, можно это выразить через assert, но комментарий дает сразу и контекст, и предупреждение. Особенно если логика непростая.</p><h3>3. Когда нужно предоставить контекст и ссылки</h3><p>Иногда кусок кода существует благодаря внешнему источнику, например, когда решение просто скопировано из ответа на форуме или из книги по теме. Просто так его не понять — нужна ссылка на источник:</p><h3>4. Когда нужно облегчить ревью</h3><p>Когда код содержит много пояснений к его работе  новому участнику команды проще входить в проект – по сути, комментарии выполняют роль встроенной документации. Кроме того, код-ревью проходит эффективнее, если автор сразу помечает неочевидные места комментариями. Например:</p><p>В PEP 8 (стиле кодирования Python) прямо приводится пример: комментарий “Compensate for border” – полезный, в отличие от банального “Increment x”, который не даёт новой информации.</p><h3>5. Когда нужна поддержка самодокументируемости через структуру</h3><p>Иногда хочется написать: # Этап 1: авторизация пользователя, и в этот момент приходит мысль — а почему бы не вынести это в функцию authorize_user()? И комментарий уже не нужен. То есть сам порыв объяснить словами часто указывает, что код пора расчленить и упростить.</p><h3>6. Когда нужно кого-то обучить программированию или корпоративным стандартам оформления кода</h3><p>Когда человек обучается программированию или только пришел в компанию, где есть свои стандарты, комментарии в коде можно использовать, чтобы дать ему обучающий материал с примерами из практики, пример:</p><p>Комментарий — это инструмент. Если комментарий в коде дает информацию, которую нельзя вытащить из кода напрямую, — значит, работает как надо. Но бывает и обратное — когда комментарии мешают. Об этом — в следующей части.</p><h2>Когда комментарии вредят</h2><p>Худшее, что может случиться с комментариями – когда они вводят в заблуждение или засоряют код впустую. Рассмотрим подробнее:</p><h3>Дублируют очевидное</h3><p>Комментарий, который просто повторяет код своими словами, не несёт никакой пользы:</p><p>А вот так — лучше вообще без пояснений:</p><p>Комментарий должен объяснять, зачем что-то делается, а не что именно:</p><h3>Врут и вводят в заблуждение</h3><p>Классика: код переписали, а про комментарий забыли.</p><p>Спустя некоторое время код могли переписать, и old_api_call() заменили на new_api_call(), но комментарий остался от прежней версии и стал источником дезинформации: разработчик, читающий код, может принять заведомо неверное решение, доверившись устаревшей заметке. По этой причине крайне важно понимать: если уж пишете комментарий, держите его в актуальном состоянии вместе с кодом.</p><h3>Показывают, что код плохой</h3><p>Когда код плохо читается, и его пытаются «объяснить» словами, вместо того чтобы переписать:</p><p>Вместо этого — понятный код:</p><h3>Плодятся бесконтрольно</h3><p>Иногда встречается код, где каждое действие сопровождается избыточными пояснениями:</p><p>Здесь нет ни одной неочевидной строки. Лучше оставить так:</p><h3>Представляют собой мёртвый код</h3><p>Когда в коде остаются большие мёртвые блоки, которые просто закомментированы:</p><p>Может быть, раньше это что-то значило, но сейчас — просто мертвый груз. Если код не нужен — удаляй. История останется в git.</p><h3>Запутывают и размывают смысл</h3><p>Что значит «временное»? Когда переделывать? Почему не постоянное?</p><p>Лучше так:</p><p>Теперь ясно, почему так сделано, и можно отследить, когда это поведение закончится.</p><p>Итак, комментарии становятся злом, когда они не выполняют своей информативной роли, а лишь создают шум или дезинформируют. В худшем случае они могут привести к багам (если программист доверится неверному комментарию) и точно приведут к потере времени на их чтение и разбор. Единственный способ избежать этого зла —  писать комментарии ответственно: убедиться, что они нужны, правдивы и своевременны.</p><h2>Самодокументируемый код vs комментарии</h2><p>Есть мечта у программистов — писать код, который объясняет сам себя. Без сносок, без подсказок, без комментариев. Такой код читается как инструкция: открыл — понял. Это и называется самодокументируемым стилем.</p><p>Как его достигают?</p><ul><li>Говорящие имена. Не x и a, а temperature, retryLimit, userProfile. Лучше сразу по имени понять, что перед тобой — массив с ID или словарь с настройками.</li><li>Функции с характером. У функции должно быть имя-глагол, в котором есть ответ на вопрос “что делает этот код?”. Например: parseInvoice(), sendEmailReminder(), fetchUserByToken().</li><li>Использовать названия для константных значений. Вместо if (status == 4) — if (status == ORDER_CONFIRMED). Вместо 3000 — RETRY_TIMEOUT_MS.</li><li>Структура — как абзацы в тексте. Пустые строки, логические блоки, отступы — чтобы этапы выделялись сами собой.</li></ul><p>Посмотрим например, где простой код поясняется ненужным комментарием:</p><p>Другой пример:</p><p>Комментарий уже не нужен. Из имён всё понятно: считаем среднюю температуру. Здесь самое интересное — само документируемость имеет границы. Потому что:</p><ul><li>Код объясняет «что», но не всегда «почему».</li></ul><p>Вот есть строка:</p><p>А почему 5? Почему не 3, не 10? Если причина — ограничение API, бизнес-логика или чья-то странная прихоть — код не расскажет. А вот комментарий может:</p><p><b>Неочевидные решения и компромиссы</b></p><p>Иногда приходится делать что-то нестандартное. Например:</p><p>Такой кусок кода без пояснений вызовет недоумение: А почему не сортируем?</p><p>Старайтесь писать код так, чтобы его поняли без подсказок. Как будто у вас нет возможности что-то дополнительно объяснить. А если видите, что читателю будет трудно — помогите: добавьте комментарий, который действительно нужен.</p><h2>Влияние ИИ и новых инструментов на подход к комментариям</h2><p>В последние годы в распоряжении разработчиков появились мощные ассистенты на базе искусственного интеллекта — такие как GitHub Copilot (автодополнение кода на основе ИИ) и большие языковые модели вроде ChatGPT. Эти технологии начинают влиять и на практики комментирования кода.</p><p>Во-первых, автогенерация кода по комментариям стала реальностью.</p><p>Инструмент Copilot способен на лету написать фрагмент кода, ориентируясь на описания на естественном языке. Например:</p><p>Copilot тут же может подставить реализацию:</p><p>Такой подход превращает комментарий в своего рода промпт — описание задачи для ИИ. Это приучает писать коротко и по делу. Хотя такие комментарии потом часто удаляют, их роль в генерации кода становится всё важнее.</p><p>Во-вторых, ИИ сам пишет комментарии.</p><p>Можно просто показать код:</p><p>…и попросить ИИ: прокомментируй. В ответ он выдаст:</p><p>Или даже более детальный:</p><p>Такие автокомментарии могут быть полезны, но всё равно требуют проверки: всезнающий ИИ не всегда понимает скрытые нюансы логики, а часто просто галлюцинирует, поэтому доверять полностью не стоит, но, как черновик, вполне годится.</p><p>В-третьих, стало проще понимать чужой код без комментариев.</p><p>Раньше приходилось часами вчитываться, сегодня — можно просто спросить:</p><p>Запрос в ChatGPT: что делает эта функция?</p><p>Ответ: Она возвращает новый список, содержащий удвоенные значения тех элементов исходного списка, которые делятся на 3.</p><p>ИИ не волшебник, но в 90% случаев — удобный переводчик с машинного на человеческий. Это снимает часть нагрузки с необходимости документировать тривиальные вещи.</p><p>В-четвертых, новый тип комментариев: инструкции для ИИ</p><p>Может возникнуть ситуация, когда комментарий пишется не столько для человека, сколько как команда:</p><p>Если вы используете Cursor или Replit, это может очень полезным.</p><h2>Заключение</h2><p>Так всё-таки, комментарии – зло или спасение?</p><p>Это не абсолютное благо и не абсолютное зло, это просто инструмент. Всё зависит от того, в чьих он руках и зачем используется. Комментарии способны помочь понять неочевидные решения, разобраться в сложных структурах, подсказать направление для размышления. Но, как и любой инструмент, в неумелых руках это способ случайно (или не очень) испортить кровь себе и окружающим.</p><p>Но всё-таки чаще наличие комментариев делает жизнь лучше, ведь иногда формулирование мысли разговорным текстом, а не кодом, позволяет понять свою идею лучше, взглянуть на нее с другой стороны.</p>]]></content:encoded>
    </item>
    <item>
      <title>Конечные автоматы (FSM) Просто о сложном</title>
      <link>https://tproger.ru/articles/konechnye-avtomaty--fsm--prosto-o-slozhnom</link>
      <comments>https://tproger.ru/articles/konechnye-avtomaty--fsm--prosto-o-slozhnom?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Эркин Хидиров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/konechnye-avtomaty--fsm--prosto-o-slozhnom</guid>
      <description><![CDATA[<p>Что такое конечный автомат (FSM) и зачем он нужен программисту? Эта статья простыми словами объясняет концепцию FSM, его компоненты, преимущества и реализацию на JavaScript с примерами. Разберём логику состояний, событий и переходов без сложной теории.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/konechnye-avtomaty--fsm--prosto-o-slozhnom">Конечные автоматы (FSM) Просто о сложном</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[IBM]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[1C]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 13 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Часто встречаются задачи, где нужно управлять поведением объекта или системы, которое зависит от текущего режима работы и происходящих событий. Например, кнопка может быть нажата или отпущена, пользователь может быть авторизован или нет, заказ может находиться в стадии обработки, доставки или завершения. Для элегантного решения таких задач существует мощный паттерн — конечный автомат состояний (Finite State Machine, FSM).</p><p>Эта статья предназначена для программистов, которые хотят понять, что такое FSM и как их строить, используя практический пример на JavaScript.</p><h2>Что такое FSM?</h2><p>Если совсем просто, конечный автомат — это модель, описывающая поведение системы, которая может находиться в одном из нескольких предопределенных состояний. Система переходит из одного состояния в другое при наступлении определенных событий. Каждый такой переход называется <b>транзакцией</b> или <b>переходом</b>.</p><h3>Давайте представим обычный светофор</h3><figure><img src="https://media.tproger.ru/user-uploads/115446/2025-05-30/a89f3130-8f78-4f0e-998a-970648df9bd7.png" alt="" /><figcaption>FSM – Светофор</figcaption></figure><p><b>Какие бывают состояния у светофора?</b></p><ol><li>Красный</li><li>Желтый</li><li>Зеленый</li></ol><p><b>Какие бывают события у светофора?</b></p><ol><li>Прошло определенное время (таймер сработал).</li></ol><p>Какие бывают переходы (транзакции) у светофора?</p><ol><li>Из «Красный» по событию «таймер_красного_истек» -&gt; в «Желтый» (или «Красный+Желтый»).</li><li>Из «Желтый» по событию «таймер_желтого_истек» -&gt; в «Зеленый».</li><li>Из «Зеленый» по событию «таймер_зеленого_истек» -&gt; в «Желтый» (мигающий или постоянный).</li></ol><p>Эта простая концепция помогает структурировать сложную логику, делая код более читаемым, предсказуемым и легким в поддержке. Вместо громоздких конструкций <b>if-else</b> появляется четкая карта состояний и переходов.</p><h2>Основные компоненты FSM</h2><p>Состояния (States): Конкретные режимы, в которых может находиться система (например, <i>idle</i>, <i>loading</i>, <i>active</i>, <i>error</i>).</p><p>События (Events): Триггеры, которые инициируют изменение состояния (например, <i>buttonClick</i>, <i>dataLoaded</i>, <i>timeoutOccurred</i>).</p><p>Переходы (Transitions): Правила, определяющие, из какого состояния в какое можно перейти при наступлении конкретного события.</p><p>Действия/Коллбэки (Actions/Callbacks): Фрагменты кода, которые выполняются при входе в состояние, выходе из него или во время перехода.</p><h2>Разбираем код на части: Класс HFSM для создания автоматов</h2><p>Для построения FSM мы будем использовать предоставленный JavaScript класс <b>HFSM</b> (Hierarchical Finite State Machine). «H» означает «иерархический», что позволяет вкладывать одни автоматы в состояния других, но об этом чуть позже.</p><p><b>Ключевые моменты конструктора constructor() HFSM:</b></p><ul><li><i>config.initial</i>: Имя начального состояния, в котором автомат находится сразу после создания.</li><li><i>config.transitions</i>: Объект, где ключи — это имена состояний, а значения — массивы объектов, описывающих возможные переходы. Каждый объект перехода имеет вид { event: “имя_события”, to: "имя_целевого_состояния” }.</li><li><i>config.callbacks</i>: Объект с функциями, которые будут вызываться в определенные моменты жизненного цикла FSM (например, onAfterLogin после успешного события login, или onStateChange при любом изменении состояния).</li><li><i>config.states</i>: Используется для определения вложенных FSM, делая автомат иерархическим.</li></ul><p><b>Важные методы:</b></p><ul><li><b>trigger</b>(event, …args): Основной метод для взаимодействия с FSM. Он принимает имя события и опциональные аргументы. Если для текущего состояния и указанного события есть разрешенный переход, автомат меняет свое состояние и выполняет связанные коллбэки.</li><li><b>can</b>(event): Позволяет проверить, допустимо ли указанное событие в текущем состоянии FSM.</li></ul><h2>FSM в действии — Примеры</h2><p>Рассмотрим, как этот класс используется для управления более сложной логикой на примерах.</p><h3>1. Управление логикой звонков callFSM</h3><p><i>Этот FSM описывает состояния и переходы, связанные с процессом звонка в приложении.</i></p><p>Предположим, пользователь инициирует исходящий звонок контакту «Alice». Код приложения вызовет:</p><ol><li><b>callFSM</b> находится в состоянии <b>idle</b>.</li><li>Он находит переход для события <b>outgoingCall</b>, который ведет в состояние <b>checkCamera</b>.</li><li>Состояние изменяется на <b>checkCamera</b>.</li><li>Выполняется коллбэк <b>onAfterOutgoingCall</b>(«idle», «checkCamera», «Alice»).</li><li>Внутри коллбэка выполняем свою логику</li></ol><h3>2. Управление состоянием камеры cameraFSM</h3><p><i>Это более простой FSM, отвечающий исключительно за логику работы камеры.</i></p><p>Таким образом мы можем создавать сколько угодно fsm конструкции.</p><h2>Преимущества использования FSM</h2><ul><li>Наглядность и читаемость: Структура состояний и переходов четко описывает логику.</li><li>Уменьшение количества ошибок: Явное определение состояний и переходов снижает риск непредвиденного поведения.</li><li>Простота расширения: Добавление новых состояний или событий обычно не требует значительной переработки существующего кода.</li><li>Улучшенная тестируемость: Каждое состояние и переход можно тестировать изолированно.</li><li>Управление сложностью: Особенно полезно для систем с множеством взаимосвязанных состояний.</li></ul><h2>Заключение</h2><p>Конечные автоматы состояний — это не просто теоретическая концепция, а мощный и практичный инструмент в арсенале программиста. Они помогают вносить порядок в сложную логику управления состоянием, делая код более структурированным, предсказуемым и легким для сопровождения. Представленный класс HFSM и примеры показывают, как можно реализовать и использовать FSM в JavaScript для решения реальных задач.</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>
    <item>
      <title>Как встроить распознавание документов в Android: пошаговое руководство</title>
      <link>https://tproger.ru/articles/kak-vstroit-raspoznavanie-dokumentov-v-android--powagovoe-rukovodstvo</link>
      <comments>https://tproger.ru/articles/kak-vstroit-raspoznavanie-dokumentov-v-android--powagovoe-rukovodstvo?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Smart Engines]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/kak-vstroit-raspoznavanie-dokumentov-v-android--powagovoe-rukovodstvo</guid>
      <description><![CDATA[<p>Разбираемся, как быстро добавить возможность распознавания документов в Android. Пошаговое руководство по встраиванию Smart Document Engine.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/kak-vstroit-raspoznavanie-dokumentov-v-android--powagovoe-rukovodstvo">Как встроить распознавание документов в Android: пошаговое руководство</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[SEO]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[IDE]]></category>
      <category><![CDATA[Распознавание]]></category>
      <category><![CDATA[CSS]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[Tor]]></category>
      <category><![CDATA[HTML]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[BASIC]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Intel]]></category>
      <category><![CDATA[ICO]]></category>
      <category><![CDATA[Стартапы]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Библиотеки]]></category>
      <category><![CDATA[XML]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 10 Jun 2025 14:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Привет, Tproger!</p><p>Мы в <a href="https://smartengines.ru/">Smart Engines</a> занимаемся разработкой софта для распознавания самых разных документов — начиная от паспорта РФ, свидетельства о рождении и заканчивая первичкой вроде УПД или ТОРГ-12, а также банковских карт, номеров телефона и баркодов. Наши библиотеки написаны полностью с нуля (на плюсах), мы уделяем огромное внимание скорости алгоритмов, нейросетям (новым архитектурам, размеру и правильному применению) и оптимизации, за счет чего наш софт портируется на любые архитектуры и может быть использован на любой платформе.</p><p>Сегодня продолжим знакомиться через рассказ о нашем софте, на очереди вторая библиотека — Smart Document Engine и ее возможности работы с жесткими и гибкими формами.</p><h2>Гибкие и жесткие формы</h2><p>Вначале про сами формы: они могут быть «жесткими» и «гибкими». Жёсткие формы подразумевают, что положение всех объектов на форме может быть задано прямо в виде координат на шаблоне. Самое простое определение для жестких форм — они совпадают «на просвет». Возьмите пару листов А4 с распечатанной жёсткой формой, наложите друг на друга, и места расположения полей точно совпадут. Гибкие формы устроены гораздо сложнее, но все равно имеют свою характерную структуру и топологию.</p><p>Распознавание жестких форм можно свести к детекции формы на изображении и распознавании определенных областей, где должны быть искомые поля. Гибкие формы требуют гораздо более сложных систем поиска (к тому же, завязанных на результате предыдущих действий, например, OCR, что только увеличивает возможность ошибки).</p><p>Кстати, иногда вместо распознавания текста целиком достаточно просто ответить на вопрос «есть ли текст в выбранной области, и, если есть, то где»</p><p>Но не надо думать, что жёсткие формы совсем просты — большие белые поля без каких-либо символов (или одинаковый узор по краям, как это бывает с бланками гособразца), малый объём статического текста и некоторая вариативность бланков тоже заставляют потрудиться над детекцией и классификацией шаблонов.</p><p>Также существуют общие для подобных форм проблемы. Правильно интерпретировать галочки в чекбоксах, найти штрихкоды, правильно разметить табличные данные — есть куча проблем, каждая из которых имеет своё state-of-the-art решение и набор алгоритмов, над которыми нужно ломать голову.</p><h2>Почему не LLM, хотя казалось бы</h2><p>Сейчас мы переживаем бум развития нейросетей — генеративные и классифицирующие сети появляются как грибы после дождя. Количество задач, которые они могут решить, тоже кажется неисчислимым: казалось бы — дайте обучающую выборку побольше, и всё получится! Тем более, что примеры использования нейросетей для автоматизации рутины уже можно встретить на каждом шагу: об этом пишут заметки и обзорные статьи на научно-популярных ресурсах, а интеграторы и стартапы предлагают решения по созданию чат-ботов и помощников на основе ИИ, обученного на внутренней документации больших компаний.</p><p>Однако чем сложнее нейросеть, чем глубже степень обучения — тем выше шанс, что она начнёт бредить. Мы все какое-то время назад <a href="https://shedevrum.ai/post/bc5bf060107711eeb9ea06d64eab8f23/">смеялись</a> над шести-семипалыми героями очередных сгенерированных изображений, сейчас посмеиваемся над сгенерированными сетями текстами с описанием несуществующих фильмов и книг, но смешно ли будет нам (а особенно бухгалтерии), если нейросеть начнет галлюцинировать при распознавании платёжных реквизитов или суммы НДС? И чем выше степень развития сетей — тем менее заметными будут становиться такие ошибки.</p><p>В прошлом году на одной из ключевых конференций в области анализа и распознавания документов — ICDAR — учёные традиционно задались вопросом о будущем OCR. И сошлись во мнении, что OCR нисколько не устарела, благополучно развивается и остается наиболее надежным инструментом распознавания. Обеспечить требования консистентности (и ещё всякого такого) информации, извлекаемой из изображения, все равно сможет только старый добрый OCR и прочие детерминированные алгоритмы. И именно их разработкой (и доведением до совершенства) мы и занимаемся.</p><p>Вернёмся к библиотеке <a href="https://smartengines.ru/intelligent-document-recognition/">Smart Document Engine</a>. Как уже говорилось выше, гибкие формы на то и гибкие, что исключительно геометрией на них не обойдёшься — вопрос местонахождения полей решается «на лету». На процесс взаимодействия с библиотекой это влияет в самом конце, на моменте работы с результатом. Перейдем к знакомству с интерфейсом на примере всё того же встраивания в андроид.</p><h2>Встраивание</h2><p>В целом, сценарий работы с библиотекой распознавания документов такой же, как и в <a href="https://tproger.ru/articles/kak-vstroit-raspoznavanie-pasporta-rf-v-android--powagovoe-rukovodstvo">прошлой статье</a> про распознавание паспорта: создаём движок, формируем настройки сессии, заводим саму сессию и кормим её картинками, после чего работаем с результатом распознавания. В отличие от документов, удостоверяющих личность, гибкие и жесткие формы могут быть многостраничными, с одинаковыми «по смыслу» полями на каждой странице. Помимо этого, часто документы загружают «пакетом», и в этом случае на одном изображении могут быть несколько разных документов. Поэтому результат распознавания устроен сложнее, чем в прошлом примере. Есть «результат распознавания», внутри него лежит набор найденных документов, каждый документ разбивается на «логический» и «физический» набор полей:</p><p>Логическая и физическая части документа разбираются отдельно, так как в некоторых случаях геометрия вообще не нужна (если результат распознавания документа дальше идёт в базу данных):</p><p>Как правило, результат распознавания представляют в виде json-объекта, но для наглядности лучше всего пользоваться html — особенно в случае, когда логические и физические поля имеют больше одного соответствия. Вот простенький генератор html на основе документа:</p><p>В результате получается удобная для взаимодействия html-страничка. Если добавить немного фантазии, то можно сразу сделать форму, в которой можно будет проверять и дополнять неуверенно распознанные поля — очень удобно в случае, если качество изображения плохое или документ плохо пропечатан.</p><p>Конечно, помимо андроида встроить распознавание и организовать удобные представление документа (при необходимости) можно и на любой другой платформе, однако с трендом на создание банковских офисов нового поколения и развития курьерской сети автоматизация ввода документов с помощью средненьких мобильных устройств на Андроиде становятся актуальной задачей.</p><p>На этом мы не заканчиваем, ждите новых статей!</p>]]></content:encoded>
    </item>
    <item>
      <title>CORS от А до Я: история, ошибки и грамотная настройка</title>
      <link>https://tproger.ru/articles/cors-ot-a-do-ya--istoriya--owibki-i-gramotnaya-nastrojka</link>
      <comments>https://tproger.ru/articles/cors-ot-a-do-ya--istoriya--owibki-i-gramotnaya-nastrojka?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/cors-ot-a-do-ya--istoriya--owibki-i-gramotnaya-nastrojka</guid>
      <description><![CDATA[<p>Что такое CORS, почему браузер блокирует запросы и как избежать типичных ошибок. Простое объяснение для разработчиков + рабочие решения.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/cors-ot-a-do-ya--istoriya--owibki-i-gramotnaya-nastrojka">CORS от А до Я: история, ошибки и грамотная настройка</a>»</p>]]></description>
      <category><![CDATA[API]]></category>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Безопасность]]></category>
      <category><![CDATA[JSON]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[Боты]]></category>
      <category><![CDATA[Node.js]]></category>
      <category><![CDATA[Фронтенд]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Разработка]]></category>
      <category><![CDATA[Сервер]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 09 Jun 2025 11:19:14 GMT</pubDate>
      <content:encoded><![CDATA[<p>CORS (Cross-Origin Resource Sharing) — это механизм, который позволяет веб-приложениям безопасно запрашивать ресурсы с других доменов. Если вы когда-либо видели в консоли браузера ошибку вроде «No ‘Access-Control-Allow-Origin’ header», значит, вы уже столкнулись с его работой. Сегодня разберёмся, как появился CORS, зачем он нужен и как с ним работать.</p><h2>Откуда возник CORS</h2><p>Всё <a href="https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy">началось</a> в начале 2000-х, когда веб-приложения становились всё сложнее, а разработчики чаще нуждались в данных с других доменов. Однако браузеры строго придерживались политики одного источника (Same-Origin Policy, SOP), запрещавшей доступ к сторонним ресурсам. Эта политика появилась ещё в 1995 году в Netscape Navigator 2.0 и была призвана защитить пользователей от атак вроде XSS. Проблема в том, что SOP блокировала не только вредоносные, но и вполне легитимные запросы, например, к внешним API. Разработчики пытались обойти ограничения с помощью JSONP или iframe, но такие решения были небезопасными и нестабильными.</p><p>В 2005 году инженер Мэтт Ошри предложил идею более надёжного и безопасного механизма, который в дальнейшем стал основой CORS. А в 2008-м Анн ван Кестерен <a href="https://fetch.spec.whatwg.org/">подготовила</a> черновик спецификации для W3C. В 2014 году CORS официально вошёл в стандарт Fetch API и с тех пор стал ключевым элементом работы с кросс-доменными запросами. Он помогает контролировать доступ к ресурсам, сохраняя баланс между открытостью веба и безопасностью пользователей.</p><h2>Как устроен CORS</h2><p>CORS работает как диалог между браузером и сервером, основанный на HTTP-заголовках. Когда фронтенд-приложение (например, на сайте frontend.com) запрашивает данные с другого домена (api.com), браузер автоматически добавляет к запросу заголовок Origin: https://frontend.com. Этот заголовок сообщает серверу, откуда пришёл запрос.</p><p>Сервер в ответ решает, разрешать ли доступ. Если он включает в ответ заголовок Access-Control-Allow-Origin и указывает там адрес запроса (например, https://frontend.com) или символ * (разрешение для всех доменов), то браузер пропускает ответ. Если такого заголовка нет или значение не совпадает, браузер блокирует ответ — даже если сервер технически его отправил.</p><p>Для так называемых «сложных» запросов, например, с методом POST или нестандартными заголовками, браузер сначала отправляет предварительный (OPTIONS) запрос, чтобы уточнить у сервера, допустим ли основной. В ответе сервер указывает, какие методы (Access-Control-Allow-Methods) и заголовки (Access-Control-Allow-Headers) разрешены.</p><p>Пример ответа сервера с разрешением:</p><h2>Топ-7 самых частых ошибок в CORS и как их исправить</h2><p>Для того чтобы определить оптимальные методы работы, лучше учиться на ошибках. Хорошая новость в том, что почти все CORS-ошибки легко понять и исправить — если знать, где искать. Ниже собрали 7 <a href="https://arunangshudas.com/blog/7-common-cors-errors-and-how-to-fix-them/">самых распространённых ошибок</a> CORS, с которыми сталкиваются разработчики, и рассказали, как можно с ними справиться без боли и паники.</p><h3>Нет заголовка Access-Control-Allow-Origin</h3><p>Сообщение об ошибке:</p><p>"No ‘Access-Control-Allow-Origin’ header is present on the requested resource"</p><p>Когда ваш JavaScript-код пытается получить данные с другого домена, браузер ожидает, что в ответе будет заголовок Access-Control-Allow-Origin. Если его нет — браузер блокирует ответ, считая его небезопасным.</p><h4>Решение 1: Настроить сервер на разрешение CORS</h4><p>Если вы контролируете сервер, добавьте в ответ заголовок:</p><p>Access-Control-Allow-Origin: *</p><p>* — разрешение запросов с любого домена</p><p>Но для безопасности лучше указать конкретный домен:</p><p>Access-Control-Allow-Origin: http://example.com</p><h4>Решение 2: middleware CORS в Express.js</h4><p>Если вы используете Node.js с Express, добавьте<b>:</b></p><h3>Браузер блокирует preflight-запросы (OPTIONS)</h3><p>Сообщение об ошибке:</p><p>"CORS policy preflight request did not succeed" или что-то похожее.</p><p>Иногда перед настоящим запросом браузер сначала отправляет preflight-запрос методом OPTIONS, чтобы проверить, разрешен ли основной запрос. Это происходит, если:</p><ul><li>Метод запроса не GET или POST (например, PUT, DELETE).</li></ul><ul><li>В заголовках есть что-то нестандартное (например, Authorization или Content-Type: application/json).</li></ul><p>Если сервер не умеет обрабатывать OPTIONS — все ломается.</p><h4>Решение: Обработать OPTIONS-запросы на сервере</h4><p>Пример для Express.js:</p><p>app.options('*', cors()); // Разрешаем preflight-запросы</p><p>Или настройка CORS с поддержкой OPTIONS:</p><h3>Запросы с учётом сессий (credentials) блокируются</h3><p>Сообщение об ошибке:</p><p>"The value of the ‘Access-Control-Allow-Origin’ header in the response must not be '*' when the request's credentials mode is 'include'"</p><p>Вы отправляете запрос с куками или авторизацией (credentials: 'include'), но сервер разрешает доступ всем (Access-Control-Allow-Origin: *). Это запрещено — нельзя слать credentials, если разрешено всем.</p><h4>Решение: Указать конкретный домен и разрешить credentials</h4><p>На сервере также добавьте:</p><p>Access-Control-Allow-Credentials: true</p><h3>Смешанные протоколы — HTTP и HTTPS</h3><p>Сообщение об ошибке:</p><p>"Mixed content: The page at 'https://...' was loaded over HTTPS, but requested an insecure resource 'http://...'."</p><p>Ваш сайт работает по HTTPS, а API — по HTTP. Браузеры считают, что это опасно, и банально блокируют запросы.</p><h4>Решение:</h4><ul><li>Переведите API на HTTPS.</li><li>Обновите все ссылки с http:// на https://.</li></ul><ul><li>Если работаете локально и сервер только HTTP, используйте ngrok, чтобы создать HTTPS-туннель.</li></ul><h3>CORS блокирует редиректы</h3><p>Сообщение об ошибке:</p><p>"Redirect from '...api' to '...login' has been blocked by CORS policy."</p><p>API делает редирект, но в ответе на редирект нет CORS-заголовков. Браузер не знает, можно ли доверять редиректу, и блокирует.</p><h4>Решение:</h4><p>Убедитесь, что редирект тоже возвращает правильные заголовки:</p><p>Access-Control-Allow-Origin: http://example.com</p><p>Если используете fetch, добавьте:</p><h3>Неверно настроен Access-Control-Allow-Headers</h3><p>Сообщение об ошибке:</p><p>"Request header field &lt;X&gt; is not allowed by Access-Control-Allow-Headers"</p><p>Ваш запрос содержит нестандартный заголовок (например, Authorization), а сервер не пропускает его.</p><h4>Решение:</h4><p>На сервере укажите, какие заголовки разрешены:</p><h3>Метод запроса запрещён сервером</h3><p>Сообщение об ошибке:</p><p>"Method PUT is not allowed by Access-Control-Allow-Methods"</p><p>Вы отправляете запрос методом PUT, PATCH, DELETE, а сервер разрешает только GET и POST.</p><h4>Решение:</h4><p>На сервере явно разрешите нужные методы:</p>]]></content:encoded>
    </item>
    <item>
      <title>Java → Rust → 0% готовности: как разработчик за 7 лет так и не дошел до MVP своего проекта</title>
      <link>https://tproger.ru/news/java---rust---0--gotovnosti--kak-razrabotchik-za-7-let-tak-i-ne-dowel-do-mvp-svoego-proekta</link>
      <comments>https://tproger.ru/news/java---rust---0--gotovnosti--kak-razrabotchik-za-7-let-tak-i-ne-dowel-do-mvp-svoego-proekta?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/java---rust---0--gotovnosti--kak-razrabotchik-za-7-let-tak-i-ne-dowel-do-mvp-svoego-proekta</guid>
      <description><![CDATA[<p>Разработчик 7 лет переписывал проект с Java на Rust — и так и не дошёл до MVP. Теперь он признает: без дисциплины, фокуса и приоритизации даже лучший код — пустышка</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/java---rust---0--gotovnosti--kak-razrabotchik-za-7-let-tak-i-ne-dowel-do-mvp-svoego-proekta">Java → Rust → 0% готовности: как разработчик за 7 лет так и не дошел до MVP своего проекта</a>»</p>]]></description>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Рефакторинг]]></category>
      <category><![CDATA[iOS]]></category>
      <category><![CDATA[Swift]]></category>
      <category><![CDATA[Rust]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Mon, 09 Jun 2025 07:25:30 GMT</pubDate>
      <content:encoded><![CDATA[<p>7 июня 2025 года разработчик под ником @jonhoo <a href="https://www.fossable.org/projects/sandpolis/7-years-of-development/">опубликовал</a> пост в честь годовщины проекта Sandpolis — инструмента удаленного администрирования, который он разрабатывает… с 2018 года. За это время проект так и не дошел даже до стадии MVP.</p><p>Вместо успеха — выгорание, фатальный рефакторинг и отсутствие дисциплины. Ниже — краткий пересказ его откровения и важных уроков.</p><h2>Как все начиналось</h2><p>Sandpolis задумывался как универсальный инструмент для системных администраторов. Идея пришла в университете, энтузиазма хватало. Уже в 2019 году у проекта была рабочая Java-серверная часть (~50 000 строк кода) и небольшой iOS-клиент на Swift (~10 000 строк).</p><p>Но затем случился <b>«переписон»</b> — автор решил, что все нужно перевести на Rust, «язык будущего». Так началась вторая жизнь проекта. К сожалению, безрезультатная.</p><h2>Почему за 7 лет не получилось даже MVP</h2><p>Вот как сам автор описывает главные причины провала:</p><ul><li><b>Переписывание ради языка.</b> Rust стал увлечением, и проект превратился в площадку для экспериментов, а не развития продукта.</li><li><b>Фокус на «интересном», а не важном.</b> Вместо ключевых проблем (например, проработки модели данных) автор занимался второстепенными деталями: паролями, мелкой оптимизацией.</li><li><b>Дыры вместо структуры.</b> Поскольку сложные задачи откладывались, проект обрастал кусками кода, которые не складывались в единую систему.</li><li><b>Отсутствие дисциплины.</b> Основной диагноз: нежелание делать трудное и скучное. Работа велась по принципу «где интересней» — но не «где нужней».</li></ul><h2>Что автор понял спустя 7 лет</h2><blockquote><i>Дисциплина — это то, чего в инженерии сегодня не хватает так же сильно, как хорошего вкуса.</i></blockquote><p>Основные выводы:</p><ul><li><b>Делай приоритетное — даже если оно скучное.</b> Не отвлекайся, пока не решишь главную задачу.</li><li><b>Чем дольше код сломан — тем сложнее его починить.</b> Правки должны возвращать проект в рабочее состояние как можно быстрее.</li><li><b>Не переписывай без причин.</b> Переписка кода на новом языке может уничтожить весь прогресс.</li><li><b>Ранние ошибки становятся дорогими.</b> Лучше «заплатить» временем сразу, чем страдать потом.</li><li><b>Идеи без реализации — это просто мечты.</b> Рабочий код важнее красивых концептов.</li></ul><h2>Что дальше</h2><p>Разработчик пообещал, что в 2025 году он сосредоточится только на одной вещи: <b>идеальной модели данных</b> для Sandpolis. А уже после — будет строить вокруг нее приложение.</p>]]></content:encoded>
    </item>
    <item>
      <title>Meta* и Яндекс годами собирали данные о вас через локальные порты Android. Даже в режиме инкогнито</title>
      <link>https://tproger.ru/news/meta--i-yandeks-godami-sobirali-dannye-o-vas-cherez-lokalnye-porty-android--dazhe-v-rezhime-inkognito</link>
      <comments>https://tproger.ru/news/meta--i-yandeks-godami-sobirali-dannye-o-vas-cherez-lokalnye-porty-android--dazhe-v-rezhime-inkognito?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Татьяна Жукова]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/meta--i-yandeks-godami-sobirali-dannye-o-vas-cherez-lokalnye-porty-android--dazhe-v-rezhime-inkognito</guid>
      <description><![CDATA[<p>Meta* и Яндекс отслеживали действия пользователей Android даже в режиме инкогнито через соединение с localhost. Использовались скрипты Pixel и Метрики, встроенные на миллионы сайтов. Теперь механизм отключён, но работал с 2017 года.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/meta--i-yandeks-godami-sobirali-dannye-o-vas-cherez-lokalnye-porty-android--dazhe-v-rezhime-inkognito">Meta* и Яндекс годами собирали данные о вас через локальные порты Android. Даже в режиме инкогнито</a>»</p>]]></description>
      <category><![CDATA[JavaScript]]></category>
      <category><![CDATA[Java]]></category>
      <category><![CDATA[Android]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Git]]></category>
      <category><![CDATA[Опрос]]></category>
      <category><![CDATA[Браузеры]]></category>
      <category><![CDATA[Работа]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[HR]]></category>
      <category><![CDATA[Яндекс]]></category>
      <category><![CDATA[Firefox]]></category>
      <category><![CDATA[Приложение]]></category>
      <category><![CDATA[Уязвимость]]></category>
      <category><![CDATA[WebRTC]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Fri, 06 Jun 2025 09:57:10 GMT</pubDate>
      <content:encoded><![CDATA[<p>Никакие настройки конфиденциальности, удаление cookies или режим инкогнито не спасали пользователей до начала июня 2025 года: приложения Meta* (Facebook*, Instagram*) и Яндекса (включая Карты и Браузер) тайно <a href="https://localmess.github.io/?utm_source=Securitylab.ru">отслеживали действия</a> в мобильных браузерах через соединение с localhost на Android. Всё это происходило при помощи JavaScript-скриптов Meta Pixel и Яндекс.Метрики, встроенных на миллионы сайтов.</p><p>Больше новостей в нашем тг-канале <a href="https://t.me/your_tech">Представляешь</a></p><h2>Как это происходило</h2><p>Пользователь заходил на сайт с установленным Meta* Pixel или Яндекс.Метрикой, и в этот момент JavaScript-скрипт пытался установить соединение с приложением через локальные порты. Через WebRTC (в случае Meta*) или HTTP (в случае Яндекса) передавались cookies, Android Advertising ID и другие идентификаторы. Это позволяло деанонимизировать пользователя, даже если он не был авторизован, использовал режим инкогнито или регулярно очищал cookies. Сессии с разных сайтов можно было связать в одну, а история посещений становилась доступной для дальнейшего анализа.</p><p>Уязвимость заключалась в том, что другие приложения, установленные на том же устройстве, могли подключаться к тем же портам и перехватывать передаваемую информацию. Это нарушало не только пользовательскую приватность, но и фундаментальные ожидания безопасности, встроенные в браузеры. Chrome, Firefox и Edge оказались уязвимы, а Brave и DuckDuckGo блокировали такие попытки благодаря собственным механизмам защиты.</p><p>Методика отслеживания, по данным исследователей, действовала минимум с 2017 года. Meta использовала WebRTC STUN с ноября 2024-го, затем перешла на TURN в мае 2025-го. Только 3 июня компания полностью отключила отправку данных на localhost, удалив соответствующий код. Яндекс использовал HTTP-метод с 2017 года и перешёл на HTTPS в 2018-м. Трекинг через порты также подтверждён и со стороны Яндекса. Оба вендора не документировали эти механизмы, и пользователи не были о них информированы.</p><p>По информации BuiltWith, Meta* Pixel встроен на 5,8 миллиона сайтов, а Яндекс.Метрика — почти на 3 миллиона. При сканировании топ-100 000 доменов Meta* пыталась установить соединение с localhost более чем на 13 тысячах сайтов в США и почти на 12 тысячах в Европе. Яндекс зафиксирован на более чем 1000 сайтов в каждом из этих регионов.</p><p>Стало известно, что эти механизмы отслеживания работали даже без входа в учётные записи, при активном режиме инкогнито и при удалении всех cookie. Это делает обнаруженные схемы особенно тревожными — обходятся ключевые инструменты защиты приватности и поднимаются серьёзные вопросы о допустимости подобных практик.</p><p>* Компания Meta и её продукты признаны экстремистскими, их деятельность запрещена на территории РФ</p>]]></content:encoded>
    </item>
  </channel>
</rss>