Это вторая часть моего проекта, посвященного кроссоверам, людям перешедшим из «инженерных» профессий в разработку. Первую часть можно прочитать здесь (примечание — перевод статьи доступен по ссылке), а третью — здесь.
Ни один строитель не решится перенести мост на другое место посреди работы. — Джастин Кейв
А мне приходилось передвигать мосты. — Аноним
Карл работал инженером по проведению испытаний: он тестировал нефтяные вышки, чтобы определить степень их вибрации. Люди подолгу трудятся и даже живут на нефтяных вышках, и если вибрация слишком велика, заснуть становится невозможно. И даже несмотря на то, что буровые установки проектируются с учетом того, что уровень вибрации не должен превышать порогового значения, проект и конечный результат зачастую расходятся.
Карл как раз закончил объяснять мне, как находят нефть. После бурения отверстия, по его словам, «можно кое-что туда закачать: кислоту или ореховую скорлупу, или...».
Я перебил его. «В смысле, ореховую скорлупу?!»
Он выразительно улыбнулся. «Месторождение не похоже на воздушный шар, под завязку заполненный нефтью. Это, скорее, пористая структура». При бурении давление в трубе может неожиданно пропасть. Это очень опасно, потому что неизвестно, попал ты в океан или дошел до небольшой пустоты в породе. В последнем случае дальнейшее бурение и внезапный возврат в зону высокого давления могут привести к разрыву трубы. Скорлупой лесных орехов можно потихоньку заполнять небольшие пустоты, постепенно выравнивая давление.
Как утверждает Карл, нефтяные компании являются крупнейшими потребителями ореховой скорлупы в Норвегии.
Споры вокруг традиционной и программной инженерии сводятся, как правило, к обсуждению различий между ними. Речь в этой статье пойдет вовсе не о том, что делает инженера инженером. Сам подход к объяснению понятия «инженерия», часто работает на маргинализацию сферы разработки программного обеспечения. Выявление различий типа «вам не нужно получать лицензию» или «у вас нет строгих правил» — это попытки подчеркнуть, что разработка ПО гораздо менее престижна и «крута», чем традиционная инженерия. Как мы убедились в предыдущей статье, большинство из этих аргументов не выдерживает критики, и инженеры-кроссоверы, в отличие от тех, кто работал только в одной нише, находят между своей «старой» и «новой» профессиями больше сходства, чем различий.
А когда речь заходит о фундаментальных расхождениях профессий, они, как правило, не ставят перед собой цель дискредитировать сферу разработки ПО. Вместо этого неявный акцент ставится на то, что делает программирование «особенным» процессом. Непохожим на классическую инженерию и невозможным для понимания по ее лекалам.
Мне это представляется неким защитным механизмом, который нередко доводит людей до крайностей. Судите сами: мир ПО так сильно отличается от мира классической инженерии, что разработчикам дозволяется не быть инженерами. Можно не планировать все наперед, потому, что требования к ПО меняются едва ли не каждый месяц. Можно не применять инженерные методы, потому что им это не нужно. Наглядным примером является движение NoEstimates: поскольку в программном обеспечении, якобы так не похожем на инженерные изыскания, трудно составлять сметы, следует полностью от них отказаться.
Но есть небольшая проблема: будучи инженерами-программистами, мы совершенно неправильно толкуем природу традиционной инженерии. Нет, мы не особенные. Почти все, что мы считаем своим уникальным отличием, есть в любой другой инженерной отрасли. И это по-своему хорошо. Потому что даже проблемы классических инженеров и разработчиков ПО во многом схожи.
Заявляемые различия
Сравнение «традиционной» инженерии, объединяющей в себе целый ряд технических дисциплин, с разработкой программного обеспечения, само по себе порочно. Большинство споров не выходят за рамки «программисты против инженеров», в них широкий термин «инженерия» теряет свою идентичность и сводится, например, к гражданскому строительству. Притом все специальности различны, и свойства одной из них не зависят от свойств других. После нескольких интервью я остановился на наборе «универсальных» различий:
Традиционной инженерии лучше подходит методология Waterfall, а разработке ПО — Agile.
Традиционная инженерия очень предсказуема, а программное обеспечение — нет.
Инженерия — это в основном про производство, в то время как код — это в первую очередь архитектура.
Традиционная инженерия гораздо более строга, чем программная.
Развитие отрасли разработки ПО происходит гораздо быстрее, чем развитие традиционной инженерии.
Не все эти утверждения ошибочны. Как мы увидим далее, между программным обеспечением и классической инженерией есть безусловные различия. Но в большинстве случаев противопоставления одного другому или некорректно, или требует серьезных уточнений.
Инженерия — Waterfall, программное обеспечение — Agile
Если и есть что-то (по нашему мнению) уникальное в области разработки ПО, так это Agile.
История гласит, что Agile — это попытка отказаться от Waterfall, устаревшей парадигмы, изобретенной Уинстоном Ройсом в 1970 году. Ройс предложил модель Waterfall в качестве подражания тому, как «настоящие» инженеры строят здания. Согласно Waterfall, все нужно делать в строгом порядке, переходя к следующему этапу разработки только после завершения текущего этапа. Разработка осуществляется только после завершения проектирования, тестирование — только после завершения разработки и т.д. Это отлично работает в «настоящей» инженерии, но совершенно не подходит для программного обеспечения, где требования меняются и зачастую заказчик не знает, чего он хочет, до того, как все будет готово. Поэтому в 2001 году Agile Manifesto отверг эту идею, и все стали жить долго и счастливо.
Конечно, в этой истории больше вымысла, чем правды. Несмотря на то, что Waterfall в течение долгого времени оставался популярен, он никогда не был так строг, как мы привыкли считать. Кроме того, эта модель не применялась везде и всюду: большинство разработчиков в 70-х и 80-х годах работали либо по индивидуальным планам, либо придерживались одной из многих, многих, многих модных в то время «инкрементных» моделей, например, Spiral Model или V Model. Agile был не столько радикальным новшеством, сколько естественным продолжением существовавших в то время тенденций.
Но все это не имеет отношения к основному утверждению: программная инженерия — это Agile, а традиционная инженерия — это Waterfall. А это, как ни удивительно, является существенным упрощением.
Это правда, что классические инженеры гораздо больше времени уделяют проектированию и тестированию, чем инженеры-программисты. Но это вовсе не свидетельствует о том, что у них доминирует Waterfall, а Agile им чужд. Более того, трата большого количества времени на прохождение тех или иных этапов — естественное следствие экономической модели, принятой в инженерной среде. Если итерации получаются продолжительными и дорогими, имеет смысл тратить на их планирование побольше времени. Однако люди по-разному воспринимают понятия «проектирование» и «реализация». Когда инженер-строитель строит масштабную модель, это проектирование или реализация? Когда инженер-автомобилист делает миниатюрную копию автомобиля для оценки его внешнего вида и аэродинамики, это проектирование или реализация?
Если речь идет о производстве печатных плат, то нередко с первого раза ничего не выходит. Приходится переделывать, отправлять заказ на завод, и всё по новой. Это обходится еще в 1000 фунтов стерлингов и занимает еще две недели рабочего времени». — Майк (инженер-схемотехник)
Подходы, характерные для Agile, встречаются во многих отраслях. Например, тоннели строят по австрийской технологии, которая предполагает итеративную разработку и простор для импровизации. В «Справочнике по промышленной инженерии» особое внимание уделяется перекрестному сотрудничеству и быстрой обратной связи с клиентом. Даже самый «водопадный» вид инженерии — гражданское строительство — после запуска проекта постепенно сводится к более гибким процессам, имеющим сходство с Agile. Людям необходимо открытое общение и адаптация для решения проблем на месте.
Почему мы уверены, что в области разработки ПО необходим Agile, а не Waterfall? Непредсказуемость. Модель Waterfall имеет смысл только в том случае, если можно точно предсказать и оценить препятствия, возникающие в ходе реализации проекта. Но ведь может случиться и так, что на полпути мы решим, что нужно начинать все сначала. А разве у инженеров дело обстоит иначе? Разве их работа более предсказуема, более однозначна, чем наша?
«Программное обеспечение более непредсказуемо»
Смеются — Доун, Мэтт, Стив, Майк, Мэтт, еще один Мэтт
Отчасти это заблуждение связано с тем, что мы наблюдаем лишь результат инженерной деятельности, а не сам процесс. Мы не видим трения, перерасходы средств, задержки, которые происходят из-за того, что кто-то построил стену на один дюйм левее или критически важный поставщик внезапно обанкротился. Предполагать, что программное обеспечение уникально непредсказуемо, — это особый вид самонадеянности.
Отчасти это суждение основывается на том, как быстро меняется программное обеспечение. Кажется, будто раз в год или два возникает новый доминирующий фреймворк или язык, на который все стремятся перейти. Предполагается, что в традиционной инженерии не происходит такой же частой смены инструментария и парадигм. В какой-то степени это действительно так. Но лишь отчасти. В инженерии многое может пойти не по плану, даже смены парадигм не надо. Один из разработчиков микросхем, Стив, считает это крайне забавным:
В мире программного обеспечения все думают о том, «какой новый JavaScript-бандлер появится в этом месяце». А в сфере аппаратного обеспечения — «что новенького приготовили кремниевые фабрики в этом сезоне». Если у литейщиков появляется новое оборудование для производства чипов, ваши планы идут коту под хвост. Разумеется, это происходит не так часто, как в случае с библиотеками ПО, но все равно происходит». — Стив (инженер-схемотехник)
Слишком много существует подобных, подчас анекдотичных примеров, чтобы описывать здесь их все. У кого-то посреди строительства могут возникнуть территориальные претензии, методики, проверенные временем, внезапно перестанут работать, а новых еще нет... Один из участников проекта рассказывал о том, как обидно начинать работу над фундаментом моста, а потом обнаружить, что грунт этой местности промерзает каким-то странным образом, в результате чего в случае землетрясения он становится слишком жидким. Что ж, проектируем все заново.
«Код — это сплошная архитектура и проектирование»
Я был удивлен, когда Ник Коглан (Nick Coghlan) предложил мне взять у него интервью; мне он был известен как ведущий разработчик CPython. Однако прежде он работал инженером по системной интеграции в компании Boeing. Он называл это «дипломатический стиль системной архитектуры». В Boeing было несколько независимых систем — в его случае это сам самолет, система контроля воздушного движения и система антенн. Он должен был работать со всеми тремя командами, чтобы гарантировать, что они создадут совместимые интерфейсы. По сути, это была интеграционная работа. Он полагает, что в утверждении, будто «программное обеспечение — это только архитектура» скрывается фундаментальное различие между его прежней работой и нынешней.
Но с ним много кто не согласен. «С моей точки зрения, — сказал один из участников моего проекта, — это все проектирование — от создания первой схемы процессора до выпуска готовой микросхемы. Все время уходит на проектирование — как и в случае с программным обеспечением. Конструировать же изделия было проще простого: достаточно передать проект на производство и получить обратно готовые микросхемы.
Конечно, микросхемы могут иметь дефекты, что будет означать необходимость внести изменения в конструкцию. Проектирование и конструирование не так уж далеки друг от друга, как кажется нам, инженерам-программистам. Многие инженеры-механики это прекрасно понимают.
Кроме того, есть еще одна проблема: «архитектура» — понятие растяжимое. Имеется ли в виду формальная спецификация? Или детальные чертежи? Если речь идет о коде — то какова формальная спецификация нашего кода? В сложных проектах существует множество различных подходов к проектированию на множестве уровней детализации. Если вы взглянете на чертежи мостов, то увидите, что там много «слоев», каждый из которых состоит из собственных деталей.
Строгость и ответственность
В разработке ПО в 1 000 000 раз больше контроля и балансировки, чем в традиционной инженерии. [...] Всякий раз, читая Твиттер и натыкаясь на новость о том, что какие-то Excel-таблички испортились и сломали работу корпорации, я удивляюсь, что небоскребы не рушатся по пять раз на дню, а самолеты не падают каждую неделю». — Мэтт
Говорят, что традиционная инженерия гораздо строже, чем программирование. Инженеры-традиционалисты тщательно рассуждают, опираясь на исходные данные, а не копируют что попало. Обычно это преподносится как проблема программного обеспечения, которую мы должны исправить, чтобы стать «настоящими» инженерами. Это в корне неверно.
Прежде всего, меньшая строгость, с которой мы работаем, имеет не столько культурный характер, сколько продиктована самой природой программного обеспечения, что делает этот компромисс вполне приемлемым. Ник объясняет это как разницу в подходе к «проверке гипотез»: «самый простой способ проверить, верно ли ваше предположение, — это взять и попробовать». Программное обеспечение позволяет проще собирать эмпирическую информацию, что само по себе является источником достоверности.
Но высказывания о строгости основаны на том, что ПО сильно отличается от инженерных продуктов, которые в массе своей более последовательны и точны. Многие инженеры готовы убить за возможность так же легко и просто тестировать свои разработки, как это делают создатели ПО.
Всегда можно добавить еще пару скобочек. — Карл
Реальные отличия
Чем же отличается разработка программного обеспечения от всего прочего? Сразу несколькими вещами.
Последовательность
Программное обеспечение полностью синтезировано. Оно всецело ограничивается логикой. Оно не изнашивается, как, например, пружинка, верно? Оно просто делает то, что должно делать. Все, что может пойти не так, — это спецификации.» — Натан
Программное обеспечение гораздо более последовательно, чем любой другой вид инженерии. Мы привыкли думать о программном обеспечении как о сплошном хаосе, тумане взаимозависимостей и несовместимых аппаратных средств, но на самом деле у нас все довольно красиво. Если я дам вам функцию сортировки, можно ожидать, что она будет сортировать. Напротив, глупо будет закладывать риск, что она корректно отработает лишь в 95% случаев.
Для сравнения, рассмотрим физические материалы. В области электроники один из ключевых компонентов — резистор. Сопротивление резисторов измеряется в омах. Для облегчения идентификации многие резисторы имеют цветовую маркировку:
Таким образом, резистор с зеленой, синей и красной полосами будет иметь сопротивление 5600 Ом. Обратите внимание на последнюю полоску: она указывает допуск. Цветовой код описывает только теоретическое сопротивление: если полоса допуска золотистая, это означает, что отклонение от номинала может составлять до 5%. Если у вас есть партия из 100 таких резисторов, то некоторые из них будут иметь сопротивление 5320 Ом, другие — 5880 Ом, и единственный способ узнать, какой из них какой, — проверить каждый по отдельности. И это не говоря уже об износе, изменении сопротивления в зависимости от температуры и т.д.
Так обстоит дело со всеми физическими материалами. Одним из моих любимых открытий в Интернете, сделанных задолго до начала работы над этим проектом, была страница лаборатории компании Fastenal. Компания Fastenal производит винты. В одной из публикаций компания предостерегает от использования винтов из нержавеющей стали на алюминиевых пластинах.
В программной инженерии ничего подобного нет.
Гибкость и скорость
Код — это спецификация того, как должно работать оборудование. В традиционной инженерии нам пришлось бы проделать всю ту же работу, чтобы составить спецификацию, а затем ждать, когда завод соберет эту чертовски сложную штуку. А затем пришлось бы налаживать ее своими руками, либо нанимать кого-то со стороны. Плюс к этому в течение нескольких недель мы проводили бы испытания, чтобы понять, работает она или нет». — Мэтт (химическая промышленность)
Это неоспоримая истина. Мы можем менять программное обеспечение гораздо быстрее, чем кто-либо другой способен модифицировать свою систему. Несколько инженеров рассказывали мне, что все изменения в их работе стоили ощутимых денег: каждый раз, когда нужно было что-то подправить, ты знал, что отнимаешь у бюджета 5000 долларов. А я могу изменить несколько строк кода и провести все тесты за несколько секунд.
В химической промышленности есть нечто подобное. «Утром я прихожу посмотреть, что вчера вечером пошло не так, — говорит Раджа, бывший инженер-химик. В разработке ПО такое долгое тестирование — скорее редкость, чем данность.
Оборотная сторона этой особенности мира ПО – возможность в ряде случаев решить сугубо инженерную проблему программным способом, без внедрения сложных и дорогостоящих изменений.
Инженера-программиста буквально окружают остальные члены команды. Он непременно должен всех спасать. Если что-то в электронике или механике работает не совсем корректно, часто это можно обойти с помощью программирования». — Майк
И иногда эта ставка приводит к катастрофическим последствиям. В 2019 году в двух катастрофах самолетов 737 MAX погибло более 300 человек. Расследование показало, что это произошло из-за ошибки в «Системе дополнения маневренных характеристик» (MCAS), одной из автоматизированных систем управления полетом. Компания Boeing добавила MCAS для того, чтобы компенсировать выявленные проблемы аэродинамического профиля самолета. Вместо того чтобы решать традиционную проблему с помощью традиционных инженерных решений, компания Boeing предпочла использовать программное обеспечение, в результате чего погибли люди.
Ограничения
Во всех интервью прослеживалась неявная тенденция к обсуждению лимитов и ограничений. Существуют жесткие физические ограничения, которым должны подчиняться разрабатываемые продукты. Устройство должно быть достаточно легким, или достаточно прочным, или достаточно стойким, или достаточно холодным. Существует известная величина, которую они должны максимизировать или минимизировать.
Ограничения присутствуют и в программном обеспечении. Код должен поместиться в памяти аппаратного устройства, датчик должен реагировать ровно за 10 циклов, API не должен выходить за пределы допустимой производительности. Но ограничения в программном обеспечении, как правило, являются довольно мягкими. Выходить за их пределы, конечно, не стоит. Но можно слегка поступиться лимитами в угоду другим преимуществам, например, ускорению разработки или упрощению алгоритмов. В традиционной инженерии большинство ограничений — жесткие. Если площадь корпуса чуть больше заданной, он не протиснется на место установки.
Иногда это приводит к нестандартным решениям. Однажды команда Карла должна была установить шнековый конвейер на нефтяной вышке, но обнаружила, что его высота на пару дюймов превышает высоту помещения. Уменьшить оборудование или поднять потолок было невозможно, так как выше было еще четыре этажа. Решение команды? Вырезать кусочек потолка, установить конвейер, а на следующем этаже установить защитный короб, чтобы никто не провалился в дырку. Это изменение теперь навсегда стало частью конструкции буровой установки и должно учитываться при каждом последующем изменении. Отсюда вытекает еще одно отличие: инженеры-программисты могут отменить свои ошибки. Традиционные инженеры — нет.
Делают ли эти различия нас особенными?
Несмотря на то, что мы во многом отличаемся друг от друга, есть разница между «отличаться» и «быть особенным». Да, инженеры-механики и электротехники не сталкиваются с теми же проблемами безопасности, что и мы. Им также не приходится иметь дело с погодными условиями в такой степени, как инженерам-строителям, и ни одному из этих трех специалистов не приходится решать проблемы, присущие химической инженерии. Каждая область техники имеет свои уникальные проблемы, и программное обеспечение не является исключением.
Но все они гораздо больше похожи, чем отличаются друг от друга. В каждой области ценится опережающее, абстрактное мышление, аккуратность в работе и хорошая задумка, примененная в нужном месте. Каждая область сталкивается с меняющимися требованиями и неизвестными факторами. Каждая область изолирована от других: мы так же мало знаем о работе инженеров-механиков, как и инженеров-химиков. Много раз на собеседованиях меня спрашивали, что представляют собой другие области техники. Ни у кого нет шанса покинуть свой «пузырь».
И это хорошо, что в сфере разработки программного обеспечения нет ничего исключительного. Это означает, что мы можем многое узнать о том, как сделать программное обеспечение лучше, из других областей. А им есть чему поучиться у нас. Потому что, как ни странно, есть несколько аспектов, в которых мы разбираемся лучше, чем традиционные инженеры. В следующий раз мы поговорим о том, чему мы можем научиться и чему можем научить.
Спасибо Гленну Вандербургу, Челси Трой, Уиллу Крафту и Дэну Луу за отзывы, а также всем инженерам, у которых я брал интервью.