<?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>Ошибки в ПО</title>
    <description/>
    <link>https://tproger.ru/tag/oshibki-v-po</link>
    <atom:link href="https://tproger.ru/tag/oshibki-v-po/feed" rel="self" type="application/rss+xml"/>
    <lastBuildDate>Tue, 06 Oct 2026 08:57:39 GMT</lastBuildDate>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>12</sy:updateFrequency>
    <image>
      <title>Ошибки в ПО</title>
      <link>https://tproger.ru</link>
      <url>https://tproger.ru/apple-touch-icon.png</url>
    </image>
    <item>
      <title>Архитектура микросервисов: как избежать 7 типичных ошибок — разбор реальных кейсов</title>
      <link>https://tproger.ru/articles/arhitektura-mikroservisov--kak-izbezhat-7-tipichnyh-owibok---razbor-realnyh-kejsov</link>
      <comments>https://tproger.ru/articles/arhitektura-mikroservisov--kak-izbezhat-7-tipichnyh-owibok---razbor-realnyh-kejsov?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Денис Кудерин]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/arhitektura-mikroservisov--kak-izbezhat-7-tipichnyh-owibok---razbor-realnyh-kejsov</guid>
      <description><![CDATA[<p>Разбираем реальные ошибки при переходе на микросервисную архитектуру. Узнайте, как избежать распределенного монолита, чрезмерного дробления сервисов и проблем с коммуникацией между ними. Практические решения и чек-лист для вашего проекта на основе опыта команд 2023-2025 годов.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/arhitektura-mikroservisov--kak-izbezhat-7-tipichnyh-owibok---razbor-realnyh-kejsov">Архитектура микросервисов: как избежать 7 типичных ошибок — разбор реальных кейсов</a>»</p>]]></description>
      <category><![CDATA[Микросервисы]]></category>
      <category><![CDATA[Архитектура ПО]]></category>
      <category><![CDATA[Ошибки в ПО]]></category>
      <category><![CDATA[Архитектура приложений]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 01 Oct 2025 10:00:03 GMT</pubDate>
      <content:encoded><![CDATA[<p>Архитектура микросервисов — не панацея от всех бед. Она не гарантирует успеха, но точно показывает слабые места в процессах команды. Некоторые компании проходят этот путь с блестящим результатом. Другие оказываются в ситуации, которую эксперт Крис Ричардсон, автор книги «Microservice Patterns», метко <a href="https://microservices.io/post/architecture/2025/02/03/microservices-ate-my-application.html">называет</a> «микросервисы съели моё приложение» — когда технологию незаслуженно назначают причиной собственных провалов.</p><p>Правда в том, что микросервисы не собираются стаями, чтобы атаковать ни в чём не повинные проекты. Проблемы возникают из-за неверных архитектурных решений или когда вы игнорируете явные сигналы, что что-то пошло не так.</p><p>Разберём семь провальных сценариев, которые допускают команды при переходе на микросервисы. Вы узнаете, как избежать этих ловушек и построить систему, которая будет по-настоящему гибкой и масштабируемой.</p><h2>Зачем вообще нужны микросервисы</h2><p>Архитектура микросервисов — это не универсальное решение, а альтернативный подход к построению систем.</p><p>Микросервисы подходят не для всех проектов. Они оправданы, когда:</p><ul><li>система действительно большая и сложная;</li><li>разные компоненты требуют разного масштабирования;</li><li>команды могут работать независимо;</li><li>нужно использовать разные технологии для разных задач.</li></ul><p>Монолит часто лучше для:</p><ul><li>небольших проектов с четкими границами;</li><li>команд до 10 человек;</li><li>ситуаций, когда важна простота развертывания;</li><li>проектов с неясными требованиями.</li></ul><p>Представьте монолит как специализированный магазин. Все товары в одном помещении. Покупатель быстро находит нужное. Владелец легко управляет ассортиментом.</p><p>Микросервисы работают иначе. Это сеть специализированных магазинов, расположенных в одном торговом центре. Хлебный магазин, мясная лавка, овощной павильон. Каждый работает независимо. Если в хлебном магазине ремонт, мясная лавка продолжает работать.</p><p>Конкретные преимущества микросервисов:</p><ul><li>Независимое развертывание. Можно обновлять один сервис без остановки всей системы.</li><li>Масштабируемость. Сервисы с высокой нагрузкой масштабируются отдельно от остальных.</li><li>Технологическая гибкость. Разные сервисы можно писать на разных языках и технологиях.</li><li>Устойчивость к ошибкам. Если один сервис упадёт, это не приведёт к коллапсу всей системы.</li></ul><p>Но эти преимущества работают только при правильной реализации. На практике слишком часто команды создают систему, где сервисы так тесно связаны, что преимущества независимости теряются. Возникает ситуация, когда каждый сервис по отдельности прост, но вместе они создают сложную для управления конструкцию. Проблема в одном сервисе при такой реализации отражается на всех остальных. Внесение изменений требует согласования с несколькими командами. Нет ни гибкости микросервисов, ни предсказуемости монолита. Вместо этого получается наихудший из вариантов.</p><p>Далее мы рассмотрим наиболее типичные антипаттерны, которые встречаются в практике разработки. Стоит изучить эти ошибки, чтобы не допускать их в своих проектах.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/cbd1b012-d704-4131-b3b5-ab4bf833766e.jpg" alt="" /></figure><h2>Ошибка 1: Распределенный монолит</h2><p>Команды хотят получить преимущества микросервисов, но не могут отказаться от мышления в стиле монолита.</p><p><b>В чем проблема:</b> Вместо независимых сервисов получается система, где все компоненты жёстко связаны. Это и есть распределённый монолит.</p><p><b>Реальный кейс:</b> Консультант IBM Холли Каммингс <a href="https://www.infoq.com/articles/microservices-seven-fail/">описывает</a> проект, где команда жаловалась: «каждый раз, когда мы меняем один микросервис, ломается другой». Сервисы были распределены по разным репозиториям, но использовали идентичные копии сложной объектной модели. Изменение одного поля требовало синхронного обновления всех сервисов. Команда потеряла преимущества монолита — компилятор больше не проверял типы, — но не получила преимуществ микросервисов — независимости развёртывания.</p><p>Как избежать:</p><ul><li>Проектируйте сервисы вокруг бизнес-доменов, а не технических слоев. Интерфейсы сервисов должны быть узкими и специфичными. Например, сервис заказов сам управляет своими данными, логикой и API для операций с заказами.</li><li>Откажитесь от общих библиотек с моделью данных. Каждый сервис должен владеть своими данными и иметь свою модель.</li><li>Используйте подход, когда клиенты сервиса задают ожидания от его API. Для этого подходят инструменты вроде Pact. Такой метод проверяет совместимость сервисов без громоздких интеграционных тестов.</li></ul><p>Распределённый монолит — это худший из возможных сценариев. Вы получаете сложность распределённых систем без преимуществ модульности.</p><h2>Ошибка 2: Чрезмерное дробление сервисов (декомпозиция)</h2><p>Стремление сделать сервисы как можно меньше приводит к противоположному эффекту. Система дробится на сотню мелких компонентов, которыми невозможно управлять.</p><p><b>В чем проблема:</b> Каждый микросервис — это отдельное приложение со своей базой данных, зависимостями и пайплайном развёртывания. Чрезмерное дробление увеличивает сложность управления, мониторинга и эксплуатации. Растут сетевые издержки — латентность становится узким местом, работа системы замедляется.</p><p><b>Реальный кейс: </b>Компания Gilt <a href="https://theburningmonk.com/2015/05/craftconf15-takeaways-from-scaling-micro-services-at-gilt/">перешла</a> на микросервисы в 2015 году и столкнулась с проблемой излишнего дробления. Изначально они создали более 450 микросервисов для платформы электронной коммерции. Многие сервисы были настолько малы, что выполняли лишь одну простую функцию. Это привело к экспоненциальному росту операционных расходов. Команда тратила больше времени на координацию взаимодействия между сервисами и устранение сетевых сбоев, чем на разработку новой функциональности. В итоге они провели рефакторинг, объединив сервисы с высокой связностью, что значительно упростило систему и ускорило разработку .</p><p>Как найти баланс:</p><ul><li>Объединяйте функциональности с высокой связностью. Если два компонента постоянно общаются, возможно, они должны быть одним сервисом.</li><li>Ориентируйтесь на функциональную связность. Сервис должен иметь чёткую зону ответственности в бизнес-логике.</li><li>Оценивайте операционные расходы, прежде чем создавать новый сервис. Спросите себя: готовы ли мы поддерживать ещё одну базу данных, ещё один конвейер развёртывания?</li></ul><p>Сервис должен быть достаточно автономным, чтобы его могла поддерживать одна команда. Ему необходимо решать конкретную бизнес-задачу. Если сервис слишком мал, он не принесет реальной пользы, но потребует полноценных затрат на поддержку. Золотая середина — когда команда полностью владеет одним или несколькими логически связанными сервисами и может развивать их без постоянной координации с другими.</p><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/4b2ae5b4-4b86-4306-b1e1-08344636e3dc.jpg" alt="" /></figure><h2>Ошибка 3: «Болтливые» микросервисы</h2><p>Микросервисы много общаются друг с другом. Мелкозернистые API вынуждают делать десятки вызовов для одной операции. Это создаёт каскады зависимостей, где сбой одного сервиса вызывает цепную реакцию.</p><p><b>В чем проблема:</b> При такой структуре возникает следующий сценарий провала:</p><ul><li>Частые взаимодействия — сервисы обмениваются множеством мелких запросов, генерируя насыщенный сетевой трафик.</li><li>Каскад вызовов — один пользовательский запрос запускает длинную цепочку обращений к разным сервисам.</li><li>Мелкозернистые API — для выполнения одной бизнес-транзакции требуется множество вызовов.</li></ul><figure><img src="https://media.tproger.ru/user-uploads/113565/2025-09-30/fe3bcc40-a9b3-43ba-8c5a-21baea22b4c7.png" alt="" /></figure><p><b>Реальный кейс:</b> Команда Amazon Prime Video <a href="https://amplication.com/blog/amazon-ditches-microservices-for-monolith-decoding-prime-videos-architectural-shift">столкнулась</a> с проблемой производительности своей системы мониторинга видео. Изначально они построили архитектуру на основе микросервисов, где каждый этап обработки видео (метаданные, детекция дефектов, анализ качества) был отдельным сервисом.</p><p>Система состояла из множества «болтливых» сервисов, которые постоянно обменивались сообщениями через AWS Step Functions. Это привело к резкому росту затрат и проблемам с производительностью из-за постоянной сериализации/десериализации данных между сервисами. В итоге команда консолидировала несколько сервисов в единый монолит, что снизило затраты на 90% и улучшило производительность .</p><p>Решение:</p><ul><li>Используйте асинхронную коммуникацию через очереди событий.</li><li>Проектируйте крупнозернистые API, которые охватывают полный бизнес-контекст за один вызов.</li><li>Внедряйте архитектурные паттерны типа API Gateway для агрегации данных и Backend For Frontend для оптимизации под конкретные клиенты.</li></ul><p>Сервисы должны обмениваться данными минимально необходимое количество раз. Каждый лишний вызов между сервисами увеличивает задержки и создаёт новые точки отказа. Вместо потока мелких запросов проектируйте взаимодействие вокруг завершённых операций. Один запрос должен передавать все данные, необходимые для выполнения следующего шага бизнес-процесса.</p><h2>Ошибка 4: Игнорирование сквозной функциональности</h2><p>Команды часто откладывают на потом реализацию системных компонентов: логирование, аутентификацию, кеширование, мониторинг, поэтому разработка быстро останавливается.</p><p><b>В чем проблема:</b> Разработка бизнес-сервисов начинается до подготовки общесистемных компонентов. В результате каждый сервис изобретает собственные способы логирования и аутентификации. Приходится переделывать готовый код, чтобы добавить единый стандарт.</p><p><b>Реальный кейс:</b> Команда, создающая микросервисы на Go, <a href="https://habr.com/ru/articles/459130/">разработала</a> единый подход к обработке ошибок и логированию. Они используют структурированное логирование с обязательным контекстом — идентификаторами пользователей, транзакциями, следами запросов. При необходимости специалисты сразу находят корневые причины проблем, не переключаясь между десятками лог-файлов.</p><p>Правильный подход:</p><ul><li>Сначала создайте базовые сервисы для логирования, кеширования, управления пользователями и мониторинга.</li><li>Разработайте стандарты и библиотеки для их использования. Командам не придётся дублировать функциональность.</li><li>Внедрите централизованное логирование с самого начала. Без него невозможно отлаживать распределённую систему.</li></ul><h3>Наблюдаемость как основа стабильности</h3><p>Современные микросервисные системы требуют полноценной наблюдаемости (observability). Это не просто мониторинг, а понимание, что именно происходит внутри системы, без дополнительных вопросов к разработчикам.</p><p>Три столпа наблюдаемости:</p><ol><li>Логи — записи о конкретных событиях с временными метками и контекстом.</li><li>Метрики — числовые показатели, отслеживаемые во времени (загрузка CPU, latency, error rate).</li><li>Трассировка — отслеживание пути запроса через распределённую систему.</li></ol><h2>Ошибка 5: Нечеткие границы сервисов</h2><p>Сервисы без чётких границ начинают обрастать несвязанной функциональностью. Order Service вдруг получает отчётность, а Payment Service — нотификации. На выходе — монстр с размытой ответственностью.</p><p><b>В чем проблема:</b> Нарушается принцип единой ответственности. Сервисы становятся большими и сложными. Их трудно тестировать и поддерживать. Код дублируется — разные команды реализуют одинаковую функциональность в разных сервисах.</p><p><b>Реальный кейс: </b>Компания Kong (тогда еще Mashape) <a href="https://buttercms.com/books/microservices-for-startups/breaking-up-a-monolith/">начала</a> декомпозицию монолита в 2013 году. Монолитное приложение, написанное на Java, объединяло функциональность маркетплейса API, включая биллинг, аналитику и управление каталогом. В процессе декомпозиции команда столкнулась с трудностями, которые позже были признаны классическими ошибками.</p><p>Первоначально четкие границы между компонентами со временем размылись, что привело к серьезным проблемам:</p><ul><li>Сложность развертывания. Любое небольшое изменение требовало полного переразвертывания всей системы.</li><li>Размытие границ. Компоненты маркетплейса стали переплетаться, границы ответственности стерлись.</li><li>Технический долг. Система становилась все сложнее для поддержки и развития.</li></ul><p>Попытка исправить ситуацию переходом на микросервисы изначально ухудшила положение. Команда, разделенная на две части (одна поддерживала монолит, другая разрабатывала новую архитектуру), столкнулась с трудностями координации. В итоге процесс разработки замедлился, а не ускорился.</p><p>Как избежать:</p><ul><li>Используйте Domain-Driven Design (DDD). Определяйте Bounded Context — чёткие границы бизнес-доменов.</li><li>Перед созданием сервиса документально зафиксируйте его зону ответственности. Что он делает? Какими данными владеет?</li><li>Сопротивляйтесь искушению добавить «ещё одну маленькую функцию» в существующий сервис. Часто лучше создать новый, но для начала нужно разобраться с конкретной задачей продукта.</li></ul><h3>Антипаттерн Entity Service</h3><p>Частный случай размытых границ — создание сервисов по принципу «одна сущность — один сервис». Это кажется логичным: сервис пользователей, сервис заказов, сервис товаров. Но на практике такой подход создаёт ещё больше проблем. Entity Service (сервис одной сущности) часто превращается в обычный CRUD-интерфейс к базе данных. Вся бизнес-логика перемещается в вызывающие сервисы, которые вынуждены делать десятки вызовов для выполнения одной операции.</p><p><b>Альтернатива:</b> Создавайте сервисы вокруг бизнес-операций, а не данных. Вместо общего «сервиса пользователей», который отвечает за всё подряд, выделите отдельные сервисы с конкретными зонами ответственности:</p><ul><li>сервис регистрации — создает новые учетные записи;</li><li>сервис аутентификации — проверяет логины и пароли;</li><li>сервис управления профилем — обновляет личные данные.</li></ul><p>Каждый такой сервис содержит и данные, и логику своей операции. Названия сразу показывают, что сервис делает. Такой подход помогает избежать «божественных» сервисов, которые знают слишком много.</p><h2>Ошибка 6: Смешивание баз данных</h2><p>Общая база данных для нескольких микросервисов — это красный флаг. Сервисы теряют независимость. Изменение схемы данных одним сервисом ломает остальные.</p><p><b>В чем проблема:</b> Единая база данных создает скрытую связность между сервисами. Невозможно выбрать оптимальную СУБД для конкретного сервиса — все используют одно решение. Затрудняется горизонтальное масштабирование.</p><p><b>Реальный кейс:</b> Крис Ричардсон <a href="https://microservices.io/patterns/data/shared-database.html">описывает</a> классическую проблему, возникающую при использовании общей базы данных. В этом сценарии сервисы OrderService и CustomerService напрямую обращаются к таблицам друг друга в единой базе данных.</p><p>Это создает тесную связность на уровне разработки и времени выполнения:</p><ul><li>Зависимость разработки. Разработчик, вносящий изменения в OrderService, должен согласовывать изменение схемы таблиц с командой, отвечающей за CustomerService, что значительно замедляет работу.</li><li>Блокировки времени выполнения: Длительная транзакция в CustomerService, которая удерживает блокировку на таблице ORDERS, может полностью заблокировать работу OrderService.</li></ul><p>Такой подход лишает микросервисы их ключевых преимуществ — независимости развертывания и масштабирования.</p><p>Правила работы с данными:</p><ul><li>У каждого сервиса должна быть собственная база данных. Сервис владеет своими данными — другие сервисы получают доступ только через его API.</li><li>Используйте шаблон Saga для управления распределёнными транзакциями вместо двухфазного коммита.</li><li>Реализуйте CQRS (Command Query Responsibility Segregation) для отделения операций записи от операций чтения, когда это необходимо.</li></ul><p>Общая база данных создаёт жесткую зависимость между сервисами. Изменение схемы данных в одном месте может сломать функциональность в другом. Команды теряют возможность независимо развивать свои сервисы — любая правка требует согласования со всеми участниками.</p><p>Такая архитектура лишает микросервисы их главного преимущества — автономности, и напоминает жизнь в студенческом общежитии. Вместо независимых компонентов получается система, где всё связано невидимыми нитями зависимостей.</p><h2>Ошибка 7: Неготовность организации</h2><p><b>В чем проблема: </b>Микросервисы требуют изменений в структуре команды и процессах. Если продолжать работать как с монолитом, ничего не получится.</p><p><b>Реальный кейс:</b> в одной из <a href="https://medium.com/@b.stoilov/a-short-horror-story-about-migrating-from-monolith-to-microservices-28d35801b188">компаний</a> команда разрабатывала микросервис, но была вынуждена тесно интегрировать его с унаследованным монолитом. Они зависели от его цикла выпуска, что свело на нет все преимущества независимой разработки. Проект в итоге закрыли.</p><p>Какие организационные изменения помогут:</p><ul><li>Перейдите к командам по сервисам — небольшим автономным группам, которые полностью владеют своими сервисами (You Build It, You Run It).</li><li>Внедрите культуру DevOps — автоматизацию сборки, тестирования и развёртывания для каждого сервиса.</li><li>Наладьте независимые циклы выпуска. Возможность развёртывать сервисы без координации с другими командами — ключевое преимущество микросервисов.</li></ul><p>Успешный переход на микросервисы требует изменения мышления всей команды. Разработчики должны стать ответственными за свои сервисы на протяжении всего жизненного цикла — от проектирования до эксплуатации в продакшене.</p><p>Что меняется:</p><ul><li>Ответственность. Разработчики отвечают не только за написание кода, но и за работоспособность сервиса в продакшн.</li><li>Коммуникация. Команды должны чётко определять контракты между сервисами и соблюдать их.</li><li>Экспертиза. Появляется потребность в специалистах по DevOps, наблюдаемости, распределенным системам.</li></ul><p>Микросервисы — это не про технологии, а про архитектуру и организацию работы. Без правильной культуры даже самая совершенная техническая реализация обречена на провал.</p><h2>Чек-лист для вашего перехода</h2><p>Прежде чем переходить на микросервисы, проверьте себя по этому списку:</p><ul><li>вы определили бизнес-проблему, которую будете решать микросервисами (а не просто хотим «быть как Netflix»);</li><li>спроектировали границы сервисов на основе бизнес-доменов — DDD, Bounded Context;</li><li>у каждого сервиса будет собственное хранилище данных;</li><li>предусмотрели кросс-каттинговые сервисы — логирование, аутентификацию, мониторинг;</li><li>готовы к организационным изменениям — автономные команды, DevOps;</li><li>выбрали правильный уровень детализации сервисов (не слишком мелкий);</li><li>продумали межсервисную коммуникацию — асинхронную, через события.</li></ul><p>Netflix, Amazon и Uber прошли этот путь. Они не избежали ошибок, но выстроили процессы для развития сложных систем. Микросервисы — это эволюция архитектуры и команды. Начинайте с малого, не бойтесь менять решения. Главный критерий успеха — скорость доставки ценности пользователям без поломок продакшена. Если этот показатель растет — вы на правильном пути.</p>]]></content:encoded>
    </item>
    <item>
      <title>Статический анализ в разработке встраиваемых систем</title>
      <link>https://tproger.ru/articles/staticheskij-analiz-v-razrabotke-vstraivaemyh-sistem</link>
      <comments>https://tproger.ru/articles/staticheskij-analiz-v-razrabotke-vstraivaemyh-sistem?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Yuliya Khushnamova]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/articles/staticheskij-analiz-v-razrabotke-vstraivaemyh-sistem</guid>
      <description><![CDATA[<p>Статический анализатор проверяет код и помогает находить проблемы во встраиваемых системах. Ключевые аспекты: его возможные функции и практическая польза.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/articles/staticheskij-analiz-v-razrabotke-vstraivaemyh-sistem">Статический анализ в разработке встраиваемых систем</a>»</p>]]></description>
      <category><![CDATA[Безопасный код]]></category>
      <category><![CDATA[Инструменты]]></category>
      <category><![CDATA[Пост пользователя]]></category>
      <category><![CDATA[Ошибки в ПО]]></category>
      <category><![CDATA[Статьи]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Tue, 07 Dec 2021 09:57:25 GMT</pubDate>
      <content:encoded><![CDATA[<p>Быстрый рост количества встраиваемых систем актуализирует вопрос качества их программного кода. А с учётом специфики разработки (затруднительная отладка, высокая цена ошибки и так далее), просто необходимо использовать специальные инструменты, позволяющие повысить их качество.</p><p>Одним из таких инструментов является статический анализатор кода. О статическом анализе и его пользе для встраиваемых систем и пойдёт речь в этой статье.</p><h2>Статический анализ кода</h2><p>В первую очередь разберёмся, что такое статические анализаторы кода и какие функции они могут потенциально выполнять.</p><p>Статический анализатор кода — это ПО, которое проводит анализ программы без её реального выполнения. Инструменты статического анализа проводят более глубокую проверку исходного кода, чем это делает компилятор, который обычно находит только синтаксические ошибки. Их принцип работы заключается в следующем:</p><ul><li>на вход принимают исходный код проекта (желательно компилируемый);</li><li>преобразуют исходный код в специальную модель для дальнейшего анализа (AST, семантическая информация и так далее);</li><li>ищут дефектные места, применяя к модели набор диагностических правил, в основе которых лежат различные <a href="https://pvs-studio.com/ru/blog/posts/cpp/0592/">методологии</a>;</li><li>сохраняют все полученные предупреждения в удобный для вас формат;</li><li>остаётся только изучить отчёт и исправить все дефектные места;</li><li>PROFIT!</li></ul><p>Статические анализаторы применяются для широкого спектра задач. Можно выделить наиболее распространённые:</p><p>Поиск ошибок в программном коде (наиболее распространённое применение). В этом плане статический анализ здорово дополняет процесс обзора кода, позволяя найти и исправить ряд проблем до того, как засядете на долгое время с коллегой.</p><p>Улучшение качества кода в широком смысле этого слова. К качеству можно отнести читаемость, поддерживаемость, сложность кода, уровень связанности и другие аспекты, которые прямо или косвенно могут влиять на количество ошибок. Тем самым, статические анализаторы могут помогать следовать стандартам кодирования (как принятым внутри компании, так и общепринятым).</p><p>Анализ кода как часть механизма Quality Gates в CI/CD. Анализаторы могут не только сообщать о наличии возможных ошибок в коде, но и служить защитным механизмом, предотвращающим доставку кода, если уровень его качества не соответствует заданным требованиям. Такую роль могут выполнять анализаторы кода, расширяющие поведение компилятора и блокирующие сборку, если были обнаружены ошибки или несоответствия кода принятым стандартам;</p><p>Сбор метрик проекта, сбор статистики, построение графиков и диаграмм, отражающих общее «состояние здоровья» проекта.</p><h2>Польза внедрения</h2><p>Польза от внедрения статического анализатора в разработку встроенного ПО несомненна. Давайте рассмотрим самые очевидные положительные стороны использования статического анализа.</p><h3>Использование статического анализа позволит уменьшить вероятность дорогой, а то и вовсе невозможной «перепрошивки» уже выпущенных устройств</h3><p>Ошибки в ПО встраиваемых систем крайне неприятны. Неприятность в том, что ошибки невозможно или почти невозможно исправить, если началось серийное производство. Если уже выпущены сотни тысяч стиральных машин и они разъехались по магазинам, то что делать при обнаружении неадекватной работы машины в определённом режиме? В общем-то вопрос риторический и реальных вариантов два:</p><ol><li>Смириться и получать негативные отзывы клиентов на различных сайтах, портя свою репутацию. Можно, конечно, выпустить и разослать к инструкции приложение «не делайте вот так», но это тоже слабый вариант;</li><li>Отозвать серию и заняться обновлением прошивок. Дорогое развлечение.</li></ol><p>Далее, независимо от того, велик тираж устройств или мал, правка ошибок может быть проблемной или запоздалой. Ракета <a href="https://pvs-studio.com/ru/blog/posts/cpp/0426/">упала</a> — ошибка обнаружена, но поздно. Пациенты <a href="https://pvs-studio.com/ru/blog/posts/0438/">умерли</a> — ошибка обнаружена, но людей это не вернёт. Противоракетный комплекс начинает <a href="https://pvs-studio.com/ru/blog/posts/0445/">промахиваться</a> — ошибка обнаружена, но ничего приятного в этой истории нет. Машины <a href="https://pvs-studio.com/ru/blog/posts/0439/">не тормозили</a>, ошибки найдены, но пострадавшим с этого прока нет. Цена ошибки ужасает, не правда ли?</p><p>Вывод очень простой: код встраиваемых устройств должен тестироваться как можно тщательнее, особенно, если ошибки могут привести к жертвам или серьёзным материальны потерям.</p><p>Статический анализ не гарантирует отсутствие ошибок в коде. Однако просто необходимо использовать любую возможность дополнительно проверить корректность кода. Статические анализаторы могут указать на множество разнообразных ошибок, которые умудряются оставаться даже после нескольких Code-Review.</p><p>Если в устройстве благодаря статическому анализу будет на несколько ошибок меньше, это великолепно. Возможно, благодаря обнаружению именно вот этих ошибок никто не погибнет или компания не потеряет большие деньги и репутацию из-за претензий со стороны клиентов.</p><h3>Статические анализаторы кода значительно удешевляют процесс тестирования и отладки программ</h3><p>Использование статического анализа позволяет находить ошибки ещё на этапе кодирования или, по крайней мере, во время ночных запусков на сервере. Вследствие чего поиск и исправление большинства ошибок будут обходиться гораздо дешевле.</p><p>Наверняка у каждого разработчика была неудачная попытка «прошить» устройство, в результате чего, например, оно некорректно держало заданное напряжение или вовсе перегорало. Что произошло и где искать проблему? Ведь причиной этому может быть не только программная ошибка, но и ошибка в самом «железе» или в некачественном изготовлении макета. В результате процесс поиска ошибки может сильно затянуться. Самый обидный сценарий:</p><ul><li>разработчик с полной уверенностью считает, что код написан верно;</li><li>привлекаются схемотехники и другие коллеги, отвечающие за hardware-часть;</li><li>идут долгие и мучительные поиски проблемы;</li><li>разработчик возвращается к коду и внезапно обнаруживает, наконец, нелепую опечатку;</li><li>колоссально неэффективный расход сил и времени коллектива;</li><li>стыдно и неприятно.</li></ul><p>Такая ошибка вполне могла появиться из-за того, что разработчик использовал в текущем проекте свои старые наработки, которые нужно было по минимуму адаптировать под текущий проект. Например, мог получиться такой ошибочный фрагмент кода:</p><p>А предыстория этой ошибки такая. За основу были взяты наработки от предыдущего проекта, и код во многом написан методом Copy-Paste. По невнимательности разработчик в одном месте забыл заменить 4 на 3. Как итог, неопределённое поведение при обращении к индексу за пределами массива. Коварность такого кода в том, что при отладке программа может работать корректно, а в реальных условиях при многократном запуске у клиента может происходить сбой. Великолепно, если такую ошибку найдёт статический анализатор.</p><p>Поэтому, чтобы избежать мучительного и нервного отлаживания программы, важно обнаружить как можно больше дефектных мест перед «прошивкой» устройства.</p><h3>Использование статического анализа позволит подстраховать разработчика с недостаточной экспертизой</h3><p>Ошибки в программах образно можно разделить на два типа. Про ошибки первого типа программист знает, и появляются они в коде случайно, по невнимательности. Ошибки второго рода возникают в ситуации, когда программист просто не знает о том, что так писать код нельзя. Другими словами, он может сколько угодно читать такой код, но всё равно не найдёт ошибку.</p><p>Статические анализаторы имеют базу знаний о различных паттернах, которые в определённых условиях приводят к ошибке. Поэтому они могут указать программисту на ошибку, о существовании которой он сам вряд ли бы догадался. Примером может служить использование 32-битного типа <i>time</i><i>_t</i>, который может привести к неправильной работе устройства после <a href="https://pvs-studio.com/ru/blog/posts/cpp/0505/">2038 года</a>.</p><p>Другим примером может служить неопределённое поведение программы, которое возникает из-за <a href="https://pvs-studio.com/ru/blog/posts/cpp/0142/">неправильного использования</a> операторов сдвига &lt;&lt;/&gt;&gt;. Эти операторы очень широко используются в коде микроконтроллеров. К сожалению, программисты <a href="https://pvs-studio.com/ru/blog/examples/v610/">часто</a> используют эти операторы крайне неаккуратно, делая программы ненадёжными и зависимыми от версии и настроек компилятора. При этом программа может работать, но вовсе не потому, что написана правильно, а потому, что везёт.</p><p>Используя статический анализатор, программисты могут подстраховать себя от множества подобных неприятных ситуаций. Дополнительно анализатор может применяться для контроля качества кода в целом, что актуально, когда состав участников проекта растёт или меняется. Другими словами, анализатор помогает отследить, не начал ли новичок писать плохой код.</p><h3>Современные статические анализаторы предоставляют поддержку стандартов кодирования для встраиваемых систем, которые позволяют повысить уровень безопасности, переносимость и надёжность программ</h3><p>Для встраиваемых систем популярными языками программирования считаются C и С++. Именно для них были разработаны такие стандарты, как MISRA C, MISRA C++ и AUTOSAR C++. Каждый стандарт имеет немалое количество правил и рекомендаций (MISRA C: 143, MISRA C++: 228, AUTOSAR C++: более 350), придерживаться которых при кодировании просто невозможно без статических анализаторов кода.</p><p>Правила представляют собой паттерны кодирования, которые необходимо избегать, тем самым уменьшая вероятность допустить ошибку. Сейчас все крупные игроки статического анализа (<a href="https://www.synopsys.com/software-integrity/security-testing/static-analysis-sast.html">Coverity</a>, Klockwork, <a href="https://pvs-studio.com/">PVS-Studio</a> и так далее) стремятся к тому, чтобы максимально покрыть эти стандарты в своих инструментах.</p><h2>Стандарты кодирования</h2><p>История MISRA началась достаточно давно. В начале 90-x правительственная программа Великобритании под показательным названием «Safe IT» выделяла финансирование для различных проектов, так или иначе связанных с безопасностью электронных систем. Сам проект MISRA (Motor Industry Software Reliability Association) был основан ради создания руководства по разработке ПО для микроконтроллеров в наземных транспортных средствах – в машинах, в общем.</p><p>MISRA (как организация) – это содружество заинтересованных сторон из различных авто- и авиастроительных индустрий:</p><ul><li>Bentley Motor Cars;</li><li>Ford Motor Company;</li><li>Jaguar Land Rover;</li><li>Delphi Diesel Systems;</li><li>HORIBA MIRA;</li><li>Protean Electric;</li><li>Visteon Engineering Services;</li><li>The University of Leeds;</li><li>Ricardo UK;</li><li>ZF TRW.</li></ul><p>Весьма сильные игроки рынка. Неудивительно, что их первый связанный с языком стандарт — MISRA C — стал общепринятым среди разработчиков критически важных встраиваемых систем. Чуть позже появился и MISRA C++. Постепенно версии стандартов обновлялись и дорабатывались, чтобы охватывать новые возможности языков. На данный момент актуальными версиями являются MISRA C: 2012 и MISRA C++: 2008.</p><p>Отличительные черты MISRA: невероятное внимание к деталям и крайняя дотошность. Авторы не просто собрали в одном месте все пришедшие в голову «дыры» C и C++ (как, например, авторы CERT) — они тщательно проработали международные стандарты этих языков и выписали все возможные способы ошибиться. А потом взяли и сверху дописали правила и рекомендации про читаемость кода. Ведь в простом и легко читаемом коде тяжелее допустить ошибку и легче её обнаружить при Code-Review.</p><p>Зачастую у людей, которые впервые сталкиваются с MISRA, складывается мнение, что философия стандарта заключается в «запретить вон то и запретить вот это». На самом деле, это так, но лишь отчасти.</p><p>Да, стандарт действительно имеет много подобных правил, но его цель — не запретить всё возможное, а перечислить все-все-все способы как-то нарушить безопасность кода. Для большинства правил вы сами выбираете, стоит им следовать или нет. Объясню это подробнее.</p><p>В MISRA C правила делятся на три основных категории: Mandatory, Required и Advisory. Mandatory — это правила, которые нельзя нарушать ни под каким предлогом. Например, в этот раздел входит правило «не используйте значение неинициализированной переменной». Required-правила менее строги: они допускают возможность отклонения, но только если эти отклонения тщательно документируются и письменно обосновываются. Остальные правила входят в категорию Advisory — это правила, которым следовать необязательно.</p><p>В MISRA C++ немного по-другому: там отсутствует категория Mandatory, и большинство прави принадлежит к категории Required. Поэтому, по сути, вы имеете право нарушить любое правило — только не забывайте документировать отклонения. Также там есть категория Document — это обязательные к выполнению правила (отклонения не допускаются), которые связаны с общими практиками вроде «Каждое использование ассемблера должно быть задокументировано» или «Подключаемая библиотека должна соответствовать MISRA C++».</p><p>Помимо описания проблематики, в стандарте содержится большое количество советов о том, что нужно знать перед началом работы: как наладить процесс разработки по MISRA; об использовании статических анализаторов для проверки кода на соответствие; какие документы нужно вести, как их заполнять и так далее.</p><p>На данный момент MISRA живёт и развивается. Например, в начале 2019 года был анонсирован The MISRA C:2012 Third Edition (First Revision) — обновлённый и дополненный новыми правилами стандарт 2012 года. Тогда же объявили о грядущем выходе MISRA C:2012 Amendment 2 — C11 Core — стандарта 2012 года, в который будут добавлены правила, впервые охватывающие версии языка Си 2011 и 2018 годов.</p><p>Не стоит на месте и MISRA C++. Как известно, последний стандарт MISRA C++ датируется 2008 годом, поэтому наиболее старшая версия языка, которую он охватывает — это C++03. Из-за этого появился ещё один стандарт, аналогичный MISRA, и называется он AUTOSAR C++. Он изначально задумывался как продолжение MISRA С++ и имел своей целью охватить более поздние версии языка. В отличие от своего вдохновителя, AUTOSAR C++ обновляется два раза в год и на данный момент поддерживает C++14. Планируется дальнейшее обновление до C++17, а затем C++20 и так далее.</p><h2>Заключение</h2><p>В данной статье хотелось показать, что использование статического анализатора однозначно целесообразно для любого встраиваемого проекта. Используя эту методологию, вы сможете:</p><ul><li>сократить время на поиск и устранение ошибок;</li><li>уменьшить вероятность критических ошибок;</li><li>уменьшить вероятность необходимости обновления прошивок;</li><li>контролировать общее качество кода;</li><li>контролировать качество работы новых членов команды;</li><li>строго следовать определённому стандарту разработки программного обеспечения;</li><li>контролировать качество кода сторонних модулей/библиотек.</li></ul><p>Нужен ли вам статический анализ или нет, решать именно вам!</p>]]></content:encoded>
    </item>
    <item>
      <title>«Сломался» Ubuntu-репозиторий Microsoft</title>
      <link>https://tproger.ru/news/slomalsja-ubuntu-repozitorij-microsoft</link>
      <comments>https://tproger.ru/news/slomalsja-ubuntu-repozitorij-microsoft?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/slomalsja-ubuntu-repozitorij-microsoft</guid>
      <description><![CDATA[<p>Microsoft пока никак не отреагировала на случившееся. Но в сети уже появилась информация о том, что это далеко не первый подобный случай на счету компании.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/slomalsja-ubuntu-repozitorij-microsoft">«Сломался» Ubuntu-репозиторий Microsoft</a>»</p>]]></description>
      <category><![CDATA[Linux]]></category>
      <category><![CDATA[Microsoft]]></category>
      <category><![CDATA[GitHub]]></category>
      <category><![CDATA[Ошибки в ПО]]></category>
      <category><![CDATA[Баги и ошибки]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Thu, 17 Jun 2021 10:57:08 GMT</pubDate>
      <content:encoded><![CDATA[<p>На GitHub появился <a href="https://github.com/dotnet/core/issues/6381">тред</a> с обсуждением недоступности репозитория Ubuntu от Microsoft.</p><p>При попытке загрузить списки пакетов из репозитория и «обновить» их с помощью apt update, пользователи наблюдают следующую картину:</p><figure><img src="https://media.tproger.ru/uploads/2021/06/1_1-4.png" alt="" /></figure><p>404 ошибка преследует их и при попытке скачать эти пакеты заново. Сообщается, что проблема затронула вообще все версии Ubuntu, а не какие-то определённые.</p><p>В ответ на первое сообщение в треде, пользователь charliemenke отметил, что не может скачать не только Ubuntu, но и Debian-пакеты:</p><figure><img src="https://media.tproger.ru/uploads/2021/06/1_2-1.png" alt="" /></figure><p>Проблема оказалась настолько массовой, что её обсуждение началось даже на Hacker News. Пользователь ресурса <a href="https://news.ycombinator.com/item?id=27537696">заявил</a>, что проблема встречается не в первый раз — ранее пользователи также <a href="https://social.msdn.microsoft.com/Forums/en-US/5d090bb8-6c22-4e8d-a534-3e79b3cb3113/failed-to-fetch">не могли обновить пакеты</a> при использовании Ubuntu через Azure.</p><p>Microsoft пока никак не прокомментировала случившееся.</p>]]></content:encoded>
    </item>
    <item>
      <title>Сотни заключённых в США не могут выйти на свободу из-за ошибок в ПО</title>
      <link>https://tproger.ru/news/sotni-zakljuchjonnyh-v-ssha-ne-mogut-vyjti-na-svobodu-iz-za-oshibok-v-po</link>
      <comments>https://tproger.ru/news/sotni-zakljuchjonnyh-v-ssha-ne-mogut-vyjti-na-svobodu-iz-za-oshibok-v-po?scrollTo=tproger-comments</comments>
      <dc:creator><![CDATA[Булат Яббаров]]></dc:creator>
      <guid isPermaLink="true">https://tproger.ru/news/sotni-zakljuchjonnyh-v-ssha-ne-mogut-vyjti-na-svobodu-iz-za-oshibok-v-po</guid>
      <description><![CDATA[<p>В Аризоне более 700 осуждённых сидят дольше положенного: департамент исправительных учреждений не обновил ПО, зная о проблеме с 2019 года.</p><p>— Читать дальше «<a rel="follow" href="https://tproger.ru/news/sotni-zakljuchjonnyh-v-ssha-ne-mogut-vyjti-na-svobodu-iz-za-oshibok-v-po">Сотни заключённых в США не могут выйти на свободу из-за ошибок в ПО</a>»</p>]]></description>
      <category><![CDATA[Ошибки в ПО]]></category>
      <category><![CDATA[Автоматизирование]]></category>
      <category><![CDATA[Новости]]></category>
      <slash:comments>0</slash:comments>
      <pubDate>Wed, 24 Feb 2021 07:30:27 GMT</pubDate>
      <content:encoded><![CDATA[<p>Радиостанция KJZZ <a href="https://kjzz.org/content/1660988/whistleblowers-software-bug-keeping-hundreds-inmates-arizona-prisons-beyond-release">рассказала</a> об очень неприятной ситуации в штате Аризона, США. Местный Департамент исправительных учреждений не озаботился своевременным обновлением ПО для управления тюрьмами, из-за чего более 700 осужденных прямо сейчас находятся в заключении дольше положенного.</p><p>По данным журналистов, управление ведомства в курсе проблемы ещё с 2019 года. Но несмотря на это, никаких попыток исправить ситуацию с их стороны не исходит. А после того, как вся эта история была обнародована, департамент и вовсе заблокировал своим сотрудникам доступ к сайту KJZZ.</p><p>В Аризоне за досрочное освобождение заключённых должна отвечать автоматика, т.к. два года назад в штате были приняты соответствующие поправки к закону. Но из-за проблем программного обеспечения, система не работала и дня, как ей положено.</p><p>Источники радиостанции заявили, что они практически сразу же начали делать внутренние предупреждения IT-сотрудникам департамента. И до сих пор ведомство не исправило большую часть из них. Речь идёт в том числе о модулях, отвечающих за «отслеживание медицинского обслуживания заключенных, их количество, имущество, комиссионные и финансовые счета, религиозную принадлежность, классификацию безопасности и принадлежность к группировкам».</p><p>Источник: <a href="https://kjzz.org/content/1660988/whistleblowers-software-bug-keeping-hundreds-inmates-arizona-prisons-beyond-release">KJZZ</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>