Инженерия ПО

Что такое Software Engineering

Цели урока

  • Понимать разницу между ремеслом программирования и инженерной дисциплиной
  • Назвать причины провалов проектов: требования, коммуникация, процессы, не только код
  • Знать ключевые роли в команде: PM, dev, QA, DevOps, SRE и зачем они нужны
  • Понимать что 70-80% стоимости ПО приходится на поддержку, а не первичную разработку
  • Видеть карьерные траектории: IC, lead, staff, principal, manager

Предварительные знания

  • Базовый опыт программирования на любом языке
  • Понимание что такое функция, переменная, баг
  • Желание разобраться, как индустрия делает софт массово, а не только в учебниках

В 1996 году ракета за 370 миллионов взорвалась из-за одной строчки кода. Код был правильным - он просто оказался в неправильной системе. Это не баг программиста, это провал инженерии. Разница между «писать код» и «строить программные системы» - это разница между умением класть кирпичи и проектированием небоскрёба.

  • **Стартапы**: 90% проектов провалены не из-за «плохого кода», а из-за хаоса в требованиях и процессах
  • **Корпорации**: Amazon деплоит каждые 11.7 секунд - это результат зрелой инженерной культуры, не только хороших программистов
  • **Ваша карьера**: разница в зарплате между «кодером» и «инженером» - в 2-3 раза, потому что инженер решает проблемы бизнеса, а не только пишет функции

Инженерия vs Кодинг

В 1996 году ракета **Ariane 5** взорвалась через 37 секунд после старта. Стоимость - 370 миллионов. Причина? Переполнение 16-битного целого числа при конвертации 64-битного float. Код работал идеально - на **Ariane 4**. Его скопировали без анализа новых условий. Программист написал правильный код. Инженер должен был задать вопрос: «А этот код подходит для новой системы?»

**Кодинг** - написание инструкций для компьютера. **Software Engineering** - дисциплина создания программных систем, которые работают надёжно, долго и в команде. Разница - как между укладкой кирпичей и проектированием здания.

Фредерик Брукс в эссе **"No Silver Bullet" (1986)** сформулировал ключевое наблюдение: главная сложность софта - не в синтаксисе языков и не в скорости компиляции. Сложность - в самой **природе задач**: требования меняются, системы растут, люди не понимают друг друга.

Standish Group CHAOS Report

С 1994 года Standish Group публикует отчёт CHAOS о судьбе IT-проектов. Первый отчёт шокировал: **31%** проектов отменены, **53%** превысили бюджет вдвое, лишь **16%** завершены в срок. К 2020-м ситуация улучшилась, но всё ещё **~66%** проектов сталкиваются с серьёзными проблемами. Причина №1 - не «плохой код», а нечёткие требования, отсутствие коммуникации и слабое управление.

АспектКодингSoftware Engineering
МасштабСкрипт, утилитаСистема из сотен модулей
Команда1 человек10–1000 человек
Время жизниДни–неделиГоды–десятилетия
Главный вызовАлгоритм, синтаксисКоммуникация, сложность, изменения
Цена ошибкиБаг в скрипте370M ракета / утечка данных

Хороший инженер не тот, кто пишет самый умный код, а тот, чей код **другие люди** могут прочитать, изменить и развивать через 5 лет.

Ракета Ariane 5 взорвалась из-за бага в коде. Почему это проблема инженерии, а не кодинга?

Жизненный цикл разработки (SDLC)

Если software engineering - это не просто кодинг, то из чего он состоит? Ответ - **Software Development Life Cycle (SDLC)** - набор фаз, через которые проходит каждый проект. Разные методологии по-разному организуют эти фазы, но сами фазы неизбежны: анализ → проектирование → реализация → тестирование → развёртывание → поддержка.

МетодологияКогда подходитСильные стороныСлабые стороны
WaterfallТребования фиксированы (госзаказ, hardware)Предсказуемость, документацияНет обратной связи до конца
V-ModelSafety-critical (медицина, авиация)Каждый уровень тестируетсяЖёсткость, дорогие изменения
Agile/ScrumСтартапы, продукты, неясные требованияБыстрая обратная связь, адаптацияСложно планировать на год вперёд
DevOpsЗрелые команды, cloud-nativeНепрерывная доставка, автоматизацияТребует культуры и инфраструктуры

**Waterfall** (Уинстон Ройс, 1970) - линейная последовательность фаз. Ройс описал эту модель как **анти-паттерн**, но индустрия приняла её буквально. Результат: команды год писали требования, год кодили, а на тестировании обнаруживали, что требования устарели.

**Agile Manifesto (2001)** стал ответом на провалы Waterfall. Четыре ценности: люди важнее процессов, рабочий софт важнее документации, сотрудничество с заказчиком важнее контракта, адаптация важнее следования плану.

**DevOps** (2009+) - следующая эволюция: стена между Dev и Ops разрушается. CI/CD pipeline автоматизирует сборку, тестирование и деплой. Amazon деплоит в production **каждые 11.7 секунд**.

Не существует «лучшей» методологии. SpaceX использует элементы Agile для ПО и Waterfall для hardware. Выбор зависит от контекста: степени неопределённости, цены ошибки и размера команды.

Стартап разрабатывает мобильное приложение. Требования меняются каждую неделю после пользовательского тестирования. Какая методология подходит лучше всего?

Качество ПО: внешнее и внутреннее

Пользователь видит, что приложение **тормозит** (внешнее качество). Разработчик видит, что код - **спагетти из копипасты** (внутреннее качество). Обе проблемы реальны, но решаются по-разному и имеют разную видимость.

Внешнее качество (видит пользователь)Внутреннее качество (видит разработчик)
UX - удобство интерфейсаReadability - код читается как текст
Performance - скорость откликаTestability - код покрыт тестами
Reliability - система не падаетMaintainability - изменения не ломают всё
Security - данные защищеныModularity - компоненты независимы
Accessibility - доступна для всехConsistency - единые паттерны

Внешнее качество **зависит** от внутреннего. Спагетти-код рано или поздно приведёт к тормозам, багам и падениям. Но внутреннее качество **невидимо** бизнесу - поэтому его часто приносят в жертву срокам.

В 1992 году Уорд Каннингем ввёл метафору **Technical Debt** - технический долг. Как финансовый долг, он позволяет «занять» время сейчас (срезать углы), но требует «процентов» потом (каждое изменение занимает всё больше времени).

**Не всякий долг - плох.** Каннингем различал **осознанный** долг ("знаем, что срезаем, вернёмся и исправим") и **неосознанный** ("написали как смогли, не знаем, что это плохо"). Первый - стратегическое решение. Второй - мина замедленного действия.

Правило бойскаута: оставляй код **чище**, чем нашёл. Не нужен грандиозный рефакторинг - каждый коммит немного улучшает качество.

Команда решает скопировать 200 строк кода вместо рефакторинга, чтобы успеть к дедлайну. Менеджер говорит: «Потом исправим». Что произойдёт?

Сложность: главный враг инженера

Почему софт так сложен? Брукс в «No Silver Bullet» разделил сложность на два вида. **Essential complexity** - неизбежная сложность самой задачи. Налоговый кодекс сложен не из-за плохого кода, а потому что налоги - сложная предметная область. **Accidental complexity** - сложность, которую мы **добавили сами**: неудачная архитектура, плохие инструменты, лишние абстракции.

**Закон Конвея (1967)**: «Организации проектируют системы, которые копируют структуру коммуникации этих организаций.» Если у вас 4 команды - получится 4 сервиса. Если команды не общаются - сервисы не будут хорошо интегрированы.

Как **измерить** сложность? Несколько ключевых метрик:

МетрикаЧто измеряетХорошоПлохо
Cyclomatic ComplexityКоличество путей через функцию (if/else/loop)1–10> 20
CouplingЗависимость между модулямиLoose (слабая)Tight (сильная)
CohesionСвязность внутри модуляHigh (всё по теме)Low (каша из функций)
Lines per functionРазмер функции< 30 строк> 100 строк
Depth of inheritanceГлубина иерархии классов1–3 уровня> 5 уровней

**Coupling и Cohesion** - две стороны одной медали. Хороший модуль имеет **высокую cohesion** (делает одно дело хорошо) и **низкий coupling** (минимально зависит от других). Если модуль `UserService` содержит логику отправки email, работы с платежами и генерации PDF - у него низкая cohesion.

Сложность растёт **нелинейно**. Система из 10 модулей может иметь 45 потенциальных связей (n*(n-1)/2). Из 100 модулей - 4950. Каждая новая связь увеличивает когнитивную нагрузку на разработчика.

Хороший код - это максимально короткий код. Меньше строк = меньше багов.

Хороший код - это читаемый и поддерживаемый код. Иногда больше строк делают намерение яснее.

Однострочник `users.filter(u=>u.a>18&&u.s=='active'&&!u.d).map(u=>({...u,r:'premium'}))` - короткий, но непонятный. Развёрнутая версия с именованными переменными и комментариями длиннее, но любой член команды поймёт и изменит её через год. Readability и maintainability побеждают краткость.

Разработчик жалуется: «Наш проект сложный, потому что бизнес-логика запутанная - налоги, скидки, правила.» Это какой тип сложности?

Ключевые идеи

  • **Инженерия ≠ кодинг**: код - это ~20% работы. Остальное - требования, архитектура, тестирование, поддержка
  • **SDLC - жизненный цикл**: Waterfall → V-Model → Agile → DevOps. Нет «лучшей» методологии - есть подходящая для контекста
  • **Качество двойственно**: внешнее (видит пользователь) и внутреннее (видит разработчик). Технический долг связывает их: плохое внутреннее → плохое внешнее
  • **Сложность - главный враг**: essential (неизбежна) vs accidental (наша вина). Цель инженера - минимизировать accidental complexity
  • Помните Ariane 5? Строчка кода была идеальной. Инженерный процесс - нет. Код без инженерии - ракета без системы управления

Куда дальше?

Software Engineering - фундамент. Теперь разберём конкретные навыки инженера:

  • Требования и спецификации — Как превратить идею в точное описание системы
  • Архитектурные паттерны — Как организовать код в масштабе

Вопросы для размышления

  • Вспомните проект, который «провалился». Это была проблема кода или инженерного процесса?
  • Какой технический долг есть в проектах, над которыми вы работаете? Он осознанный или случайный?
  • Если бы вы проектировали Ariane 5, какой этап SDLC предотвратил бы взрыв?

Связанные уроки

  • prog-01-intro — Базовое программирование - предпосылка для инженерной дисциплины
  • se-02 — Следующий урок: практические методологии разработки
  • st-01-feedback-loops — Системное мышление - ключевой инструмент software engineer
  • db-01-intro — Проектирование данных - первое крупное инженерное решение в любом проекте
  • sd-01-intro
Что такое Software Engineering

0

1

Войти