ПО как экосистема

/ Просмотров: 1263
«В ходе весьма общих размышлений ... я задался вопросом: почему одни погибают, а другие выживают? Ответ был вполне определенным: в целом выживают наиболее приспособленные... Затем меня внезапно озарило, что этот протекающий сам по себе процесс должен улучшать популяцию... Наиболее приспособленные будут выживать. И я сразу, как мне показалось, увидел все последствия этого» (А. Уоллес).
"Since we cannot expect to have algorithms that perform perfectly in all possible conditions, we would like to create a pool of methods that work very well for a particular situation instead, and use them in conjunction with each other whenever more complex problems are to be solved" (Radu Bogdan).
Хорошая вычислительная схема — это «надежная система из ненадежных элементов»

Сегодня мы поговорим о предметах, имеющих отношение к индустриальной надежности наших алгоритмов. Известно, что всякий зрелый инженерный код должен быть защищен юнит-тестом. Это особенно актуально, если речь идет не о готовом приложении, а о библиотеке с примитивным или вовсе несуществующим фронт-эндом. Причем полезная функциональность должна не просто работать, а работать надежно, если нас интересует качество программного обеспечения, выходящее за рамки требований к университетской лабораторной работе. О важности юнит-тестирования, как первого рубежа «конструкторских испытаний» нашего кода мы немного говорили в другой заметке.

С философской точки зрения, мне кажется весьма удачной аллегория, предложенная одним из архитекторов ACIS в заметке ACIS as an Ecosystem. Заметка небольшая, но я все-таки повторю основные моменты здесь, поскольку они представляются довольно важными в нелегком деле пропаганды «правильного» тестирования. Кроме того, взгляд на сложное (набор изолированных и взаимодействующих компонент) программное обеспечение как на экосистему применим отнюдь не только к «респектабельной» (характеристика Кена Версприлла, изобретателя NURBS) библиотеке ACIS, но и к любой другой библиотеке.

Итак, отдадим должное господину Джону Слоану (John Sloan) — автору указанной заметки — за удачно подобранное сравнение, и двинемся к сути вопроса. Начать следует с того, что «индустриальная зрелость», как характеристика программного обеспечения, определяется вовсе не нашим братом программистом и даже не командой QA. Говорить об этом явлении серьезно можно только по результатам реального применения ПО в промышленности (или бизнесе, это неважно). Сколь угодно исчерпывающая база нерегрессионного тестирования всего-лишь эмулирует применение наших алгоритмов в реальной жизни, но не дает гарантии безупречной работы. Это очевидно, поскольку тестируем мы обычно не совсем то, с чем алгоритму доведется столкнуться вне стен «лаборатории».

Библиотека как экосистема

Так же как ракета-носитель проходит ЛКИ, чтобы заступить в работу, так и программное обеспечение не может считаться предсказуемым и надежным без своего аналога «летно-конструкторских испытаний» — тестов. При этом набор тестов можно рассматривать как воздействие внешней среды на биологическую систему, в которой акторами (зверьками) являются алгоритмы.

Надежность не бывает абсолютной, она всегда относительна. Говорить, что алгоритм надежен можно только применительно к некоторой конкретной среде его исполнения. Например, автомобиль УАЗ Патриот является надежным аппаратом на российском бездорожье, но теряет эти качества в условиях, скажем, Антарктиды.

Очевидно, что суровые условия среды (много разнообразных тестов) способны выдержать только наиболее подготовленные особи. Естественный отбор здесь обусловлен необходимостью подстраиваться под среду: вы не можете сказать заказчику, чтобы он поменял свои входные данные на что-то более «валидное». В результате отбора часть алгоритмов мутирует, обрастая припарками надежности (что нередко сопровождается нарушением фен-шуя в коде), а часть умирает, не выдерживая пресса и уступая место более приспособленным особям (новым алгоритмам). Процессы, происходящие в таких системах, нагляднее всего иллюстрируются феноменологически (на живых примерах без попыток формализации):

  • Пусть алгоритм построения гладких сопряжений работает на точной геометрии, используя три опорные кривые (см. заметку Безье на семействе кривых).

  • От заказчика поступает модель с «плохой» геометрией, где срединная кривая не имеет точного представления, и алгоритм перестает работать. В этом случае мы имеем дело с несоответствием реальной и лабораторной сред. Модификация алгоритма для работы с толерантной геометрией (см., например, введение в булевы операции для начального знакомства с толерантным моделированием) делает его более надежным для конкретной среды заказчика.


  • Другой пример. Пусть параметрическая триангуляция Делоне использовалась для построения конечно-элементной сетки по CAD-модели. Если поверхности, входящие в модель, имеют небольшую кривизну, то доморощенный фасетер может давать удовлетворительные результаты. Однако, если у заказчика найдется «более криволинейная» поверхность, то результаты триангуляции могут оказаться плачевными. В этом случае алгоритм построения регулярной сетки часто дешевле выбросить и использовать сторонний продукт, нежели доводить существующий.

Равновесие

Система пригодна к использованию только в том случае, если ее алгоритмы обладают достаточной надежностью в условиях конкретной среды. Такое состояние системы Джон Слоан именует равновесием (equilibrium), отмечая его хрупкость и чрезвычайную сложность осознания факторов, в результате которых таковое равновесие было достигнуто. Фактически, держать в уме все взаимосвязи между компонентами и степени их влияния друг на друга становится невозможно для человека. Поэтому физически невозможно модифицировать алгоритмы, не нарушая равновесия, если только речь не идет о совсем тривиальных изменениях.

Таким образом, любое изменение экосистемы (в ответ на изменение среды) есть не что иное, как движение от одного неустойчивого равновесного состояния к другому. В каждом равновесном состоянии система отвечает вызовам среды, то есть нерегрессионные тесты проходят успешно. В каждом промежуточном состоянии система не удовлетворяет тестам и мутирует до тех пор, пока очередное равновесие не будет достигнуто.

«Кто будет сторожить сторожа?»

Здесь следует сделать важную оговорку. Архитектор системы не должен воспринимать регрессионную базу как некий сверхмозг, управляющий развитием алгоритма. База должна гарантировать безотказную работу алгоритма в рамках его СОБСТВЕННОЙ ЛОГИКИ, которая остается прозрачной и максимально простой. Иногда для того, чтобы сохранить безупречную логику алгоритма, некоторыми тестами базы НУЖНО ПОЖЕРТВОВАТЬ. Слепое следование от одного «зеленого» состояния системы к другому может привести к чрезвычайной хрупкости алгоритма, его насыщению «припарками», откалиброванными под одну ситуацию и беспомощными в другой. Такой путь ведет на кладбище, так как рано или поздно алгоритм превращается в клубок явных и неявных логических нитей, переплетение которых лишено сквозной логики, или, если хотите, руководящей идеи.

Последний термин очень важен для формирования правильной методологической установки. Руководит идея, а не база и не тесты. Скептик тут же достанет козырь из кармана, дескать, реальный мир сложнее. Да, сложнее. Поэтому алгоритмы не воюют в одиночку. Они организуются в вычислительные схемы, где у каждого зверька своя роль и своя безупречная логика. Для понимающих скажем даже так: формирование вычислительной схемы — это инновация, тогда как наращивание технической оснащенности конкретного алгоритма — это модернизация. Здесь уместно отправить читателя на знакомство с концепцией S-образной кривой, которая здорово объясняет, чем инновация отличается от модернизации. Впрочем, в данной заметке мы лишь набрасываем контуры методологии разработки алгоритмических схем, поэтому давайте пока остановимся на сказанном.

Зачем нам это?

Имея в виду все сказанное, становится понятно, что следует делать для достижения истинной индустриальной надежности. Рецепт прост: обеспечьте адекватную и предельно агрессивную среду для экосистемы вашего ПО и ищите равновесное состояние в ней. При этом негодные алгоритмы будут исчезать, а перспективные — отращивать когти и зубы, чтобы не спасовать в реальной производственной среде. Такова идея. А ее реальное применение на практике — это целая жизнь.

Оставьте комментарий!

Имя и сайт используются только при регистрации

Выберите человечка с поднятой рукой!

При нажатии на картинку, Ваш комментарий будет добавлен.