Про разработку сложного софта
Feb. 21st, 2011 09:31 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Распространено мнение, согласно которому с увеличением программной системы число ошибок в ней обязано расти сверхлинейно (в зависимости от пессимизма носителя встречаются различные конкретизации, от "квадратично" до "экспоненциально"), и этот эффект неотвратим, как закон природы. Это мнение неверно.
Частично оно вызвано тем, что стандартный способ обеспечения отказоустойчивости, воспетый Кларком в "Свидании с Рамой", в софте плохо применим: три копии имеют большую отказоустойчивость, чем одна, только если речь идет об отказах оборудования, и то с оговорками.
Несколько раз я уже писал о том, как обходится этот "закон природы" в частных случаях (1, 2, 3, 4, 5), попробую обобщить.
Кроме abstraction leaks бывают и, назовем их так, abstraction sinks - методы, подсистемы, и алгоритмы, которые умеют "переваривать" ошибки и протечки соседей. К abstraction sink'у всегда можно подключить очередной "черный ящик", реализующий некоторый заранее обговоренный интерфейс. Работа системы в целом будет улучшаться, если этот "черный ящик" работает разумно, и не ухудшаться, если он ошибается (в том числе, если "заранее обговоренный" интерфейс оказывается протекающей абстракцией). После этого конкретные "чёрные ящики" могут писать эскимосские аутсорсеры, умные студенты, эволюционные процедуры, whatever, они могут быть сколь угодно "глючными" - лишь бы хоть иногда преодолевали порог полезности.
Здесь следует считать, что каждый черный ящик работает в собственной песочнице, т.е. не может, например, испортить память, или выбросить "неловимое" исключение. Если он примет управление и "упадет", начнет жутко тормозить, или зависнет, то можно продолжить работу так, как будто его никогда и не было. Как именно этого добиться в боевых условиях - вопрос интересный, но, надеюсь, понятно, что решаемый (если осознанно ставить себе такую задачу). Для простоты можно принять не очень реалистичное допущение, что каждый "черный ящик" запущен на собственном железе, и общается с abstraction sink'ом по сети.
Известно по крайней мере два типа abstraction sink'ов: машинное обучение ("черными ящиками" в этом случае являются отдельные features), и алгоритмы поиска и планирования ("черные ящики" - эвристики выбора "макроходов"). Ни тот, ни другой - не панацея, но их применение позволяет очень долго наращивать сложность системы уже после того, как она перестает помещаться у человека в голове, и оставлять её при этом работающей. Намного дольше, чем в привычных иерархическом или объектно-ориентированном подходах, где недопущение abstraction leak'ов критически важно.
Кое-какие современные задачи иначе и не решаются. Те, которые решаются именно так, по не до конца мне понятному совпадению чаще всего относятся к "искусственному интеллекту".
Для старых друзей: в геймдеве всё это практически не применимо. :)
Частично оно вызвано тем, что стандартный способ обеспечения отказоустойчивости, воспетый Кларком в "Свидании с Рамой", в софте плохо применим: три копии имеют большую отказоустойчивость, чем одна, только если речь идет об отказах оборудования, и то с оговорками.
Несколько раз я уже писал о том, как обходится этот "закон природы" в частных случаях (1, 2, 3, 4, 5), попробую обобщить.
Кроме abstraction leaks бывают и, назовем их так, abstraction sinks - методы, подсистемы, и алгоритмы, которые умеют "переваривать" ошибки и протечки соседей. К abstraction sink'у всегда можно подключить очередной "черный ящик", реализующий некоторый заранее обговоренный интерфейс. Работа системы в целом будет улучшаться, если этот "черный ящик" работает разумно, и не ухудшаться, если он ошибается (в том числе, если "заранее обговоренный" интерфейс оказывается протекающей абстракцией). После этого конкретные "чёрные ящики" могут писать эскимосские аутсорсеры, умные студенты, эволюционные процедуры, whatever, они могут быть сколь угодно "глючными" - лишь бы хоть иногда преодолевали порог полезности.
Здесь следует считать, что каждый черный ящик работает в собственной песочнице, т.е. не может, например, испортить память, или выбросить "неловимое" исключение. Если он примет управление и "упадет", начнет жутко тормозить, или зависнет, то можно продолжить работу так, как будто его никогда и не было. Как именно этого добиться в боевых условиях - вопрос интересный, но, надеюсь, понятно, что решаемый (если осознанно ставить себе такую задачу). Для простоты можно принять не очень реалистичное допущение, что каждый "черный ящик" запущен на собственном железе, и общается с abstraction sink'ом по сети.
Известно по крайней мере два типа abstraction sink'ов: машинное обучение ("черными ящиками" в этом случае являются отдельные features), и алгоритмы поиска и планирования ("черные ящики" - эвристики выбора "макроходов"). Ни тот, ни другой - не панацея, но их применение позволяет очень долго наращивать сложность системы уже после того, как она перестает помещаться у человека в голове, и оставлять её при этом работающей. Намного дольше, чем в привычных иерархическом или объектно-ориентированном подходах, где недопущение abstraction leak'ов критически важно.
Кое-какие современные задачи иначе и не решаются. Те, которые решаются именно так, по не до конца мне понятному совпадению чаще всего относятся к "искусственному интеллекту".
Для старых друзей: в геймдеве всё это практически не применимо. :)
no subject
Date: 2011-02-21 07:00 pm (UTC)no subject
Date: 2011-02-22 08:59 am (UTC)no subject
Date: 2011-02-22 01:15 pm (UTC)no subject
Date: 2011-02-24 07:02 pm (UTC)no subject
Date: 2011-02-22 01:17 pm (UTC)no subject
Date: 2011-02-22 10:29 pm (UTC)no subject
Date: 2011-02-22 10:41 pm (UTC)no subject
Date: 2011-02-23 10:21 am (UTC)no subject
Date: 2011-02-24 09:08 am (UTC)no subject
Date: 2011-02-24 09:10 am (UTC)no subject
Date: 2011-02-24 09:13 am (UTC)no subject
Date: 2011-02-21 08:13 pm (UTC)no subject
Date: 2011-02-21 09:09 pm (UTC)Кстати в играх эти sink'и сплошь и рядом еще лучше чем, так как кому какая разница если вместо 65537 партиклов нарисуется 65536 или часть предмета затекстурируется другой текстурой ? Люди даже терпят в мультиплейере когда клиент показывает что они выиграли а с сервера приходит проиграли и клиент как ни в чем небывало поверх рисует проиграли :)) и ничего. Но количество багов от этого почему-то не уменьшается.
А когда данные ходят кругами и результат влияет на будущий вход ...
В общем не смотря на личности и авторитеты ктото тут сильно не прав.
no subject
Date: 2011-02-22 09:10 am (UTC)У задачи, в которой можно соорудить abstraction sink, должно быть следующее свойство: код, проверяющий, с каким качеством она решена, гораздо проще, чем код, который её решает. Так, чтобы можно первый проверить от и до, и написать без ошибок. Например, распознавание образов - такая задача (потому что можно качество измерять на 1000 примерах с ручной разметкой), или веб-поиск, или там, не знаю, задача поддержания динамического равновесия.
no subject
Date: 2011-02-21 09:23 pm (UTC)там принцип let it fail
no subject
Date: 2011-02-22 09:14 am (UTC)no subject
Date: 2011-02-21 10:06 pm (UTC)Кстати, если ты про наш поиск - то не забывай Лешу, который, фактически, и есть такой "abstraction sink", все остальное без его приемки рассыпалось бы. А это не машина, а живой человек.
no subject
Date: 2011-02-22 09:18 am (UTC)Собственно, без Леши никак именно потому, что измерения эти кое-где недоформализованы и недоавтоматизированы.
no subject
Date: 2011-02-21 10:29 pm (UTC)С другой стороны, возможны архитектуры, в которых похожий подход возможен. Но разработка таких архитектур -- отдельная сложная задача. Возможно, для поиска это и применимо, так как данные нестрогие по своей природе. Кстати да, в случае нестрогих требований к корректности результата такой подход представляется более реалистичным.
no subject
Date: 2011-02-22 09:37 am (UTC)no subject
Date: 2011-02-22 10:33 am (UTC)no subject
Date: 2011-02-21 11:33 pm (UTC)То есть я бы поспорил, о наблюдаемости эффектов "закона природы" на системах такого типа.
Есть другие системы, богатые бизнес-логикой, например тот же Биллинг, это структурно сложная система, в ней не работают подходы "сконвертируем все входные сигналы к единообразному виду и обработаем одинаково".
Пока писал понял: можно выделить три вида сложности системы:
- структурная (алгоритмическая) сложность программной системы
- сложность данных
- кумулятивная, поведенческая сложность
Ты показываешь нам системы с высокой поведенческой сложностью, но при этом она достигается через сложность гомоморфных данных. А "закон природы" наблюдается на системах с высокой структурной сложностью.
no subject
Date: 2011-02-22 09:26 am (UTC)no subject
Date: 2011-02-22 04:42 am (UTC)Или нет?
no subject
Date: 2011-02-22 09:28 am (UTC)no subject
Date: 2011-02-22 08:17 pm (UTC)no subject
Date: 2011-02-24 09:05 am (UTC)no subject
Date: 2011-02-24 10:01 pm (UTC)Пример - защита микроядер: в Minix есть автоматический рестарт драйверов, в Виндах 7 вроде видеодрайвера изолированы, и если вылетают, то ОС их перезапускает и таки выводит на экран то, что нужно.
В геймдеве, как я понимаю, песочница - это компьютер без эффекторов (чтобы ничего не сломал :-), а диспетчер - человек. :-)
no subject
Date: 2011-02-22 06:57 am (UTC)тем не менее, прочитать было интересно!
no subject
Date: 2011-02-22 09:29 am (UTC)no subject
Date: 2011-02-23 08:31 am (UTC)no subject
Date: 2011-02-24 09:04 am (UTC)no subject
Date: 2011-02-22 07:46 am (UTC)В общем, кажется, что вся эта кухня красива, но применима только к достаточно ограниченному классу задач, а не к "сложном софту" вообще. Этот класс задач неплохо бы попробовать описать более четко. Кстати, наверное, это кто-то уже пытался делать?
А верность или неверность утверждения "число ошибок обязано расти сверхлинейно", насколько я понимаю, очень зависит от того, что понимать под ошибкой. Потому как при наличии обработки отличной от "записать данные, какие получится, и упасть" понятие ошибки становится не вполне бинарным.
no subject
Date: 2011-02-22 09:35 am (UTC)Я не знаю, как правильно называется такой класс задач, но основной их признак - автоматом проверить, с каким качеством задача решена, проще, чем решить. Поэтому и ко всяческим драйверам, большей части "системных" вещей, к созданию rich UI и т.п. это действительно не очень применимо.
Заниматься формализацией исходного утверждения не очень хочется, поскольку я в него все равно не верю :)
no subject
Date: 2011-02-22 12:13 pm (UTC)no subject
Date: 2011-02-24 08:55 am (UTC)no subject
Date: 2011-02-22 09:10 pm (UTC)Класс задач достаточно узкий, но теоретически методика отличная, все красивенько и нарядненько. Элегантно получаем вроде бы приличное решение для не самой простой задачи, после чего спокойно его тюнингуем. Ага, как бы не так. В реале все получается не так прикольно, т.к. алгоритм для "автоматом проверить" как правило выбирается совсем не тот. Т.е., если не копать вглубь, то все вроде зашибись, а вот если копнуть... То жопа. :)
К тому же, в угоду качеству "автоматом проверить" логика черных ящиков иногда полностью отрывается от реальности.
Но если этого не замечать и тащиться от методики проверки качества, то да, все здорово. :)
no subject
Date: 2011-02-24 08:48 am (UTC)Что тут дополнительно обсуждать?
no subject
Date: 2011-02-23 06:54 pm (UTC)no subject
Date: 2011-02-24 08:54 am (UTC)no subject
Date: 2011-03-07 07:45 pm (UTC)Приняли решение заливать неинициализированную память нулями в аллокаторе - получили хороший sink и помощь в отладке.
Решили синхронизировать на разных компьютерах операции с double - получили очень хрупкий объект. Пересылаем fixed point по сетке - получили маскировку неважных ошибок.
Запретили не-explicit конструкторы (совсем уж микро) - получили чуть-чуть sink.
Пишем на Haskell вместо assembler (крайности, для иллюстративности) - избежали массы ненужных ошибок.
Дядя Дима выкидывает сложную физику из "заваленный камнями лифт" и меняет на скриптовую катсцену.
WinWord/VisualStudio делает автосейвы каждую минуту - уже можно жить с каким-то багом который обрушивает Visual Studio раз в два дня.
Сервер ММО толерантен к ошибкам в скриптовых функциях на питоне, разумно расставлены try/catch - и сервер выглядит адекватным для 90% игроков, у разрабов есть пара дней для спокойной починки. Вообще сервер ММО целиком про abstracion sinks, все легкие способы работать на одном крыле, и пришивать крылья на лету - стараются использовать.