Показаны сообщения с ярлыком Программирование. Показать все сообщения
Показаны сообщения с ярлыком Программирование. Показать все сообщения

вторник, 1 августа 2017 г.

gokai.org

28 августа 2005 года был открыт сайт Белорусской Федедрации Айкидо в Гомеле, т.е. единственной организации, в которой можно было заниматься айкидо в городе. Прошла длительная история его развития, и через почти 12 лет, 18 июля этого года он был выведен из эксплуатации. Большинство материалов доступно в Архиве Интернета.

2005 год в Интернете был во многом совсем другой — это доступ через dial-up, отсутствие социальных сетей, зоопарк браузеров, отсутствие фреймворков и практики работы с ними, нестабильный даже HTML. Сайт собирался с нуля ручную и на собственном движке, использующем файловую БД. При этом использовался легковесный пуленепробиваемый веб-дизайн — один и тот же вариант работал на всех как минимум базовых браузерах и с минимальным трафиком. С сайтом в базовой комплектации можн было легко работать с Opera на мобильных телефонах.

На практике сайт прежде всего выполнял представительскую функцию и сборку материалов (книги, фото с семинаров и т.д.). Другие способы применения (например, общение) пытались взлететь, но не смогли по ряду причин (настоящий мастер не сидит в Интернете, со временем появились боты и др.).

Ресурс нпару раз грозились переписать. Всем давался зелёный свет после того, как будет представлена рабочая версия и получено одобрение о переезде. На практике этого так и не произошло. Со временем активность айкидок перешла в социальные сети, и необходимость поддержки отдельного ресурса отпала, и таким образом gokai.org был выведен из эксплуатации. На моем движке было несколько ресурсов, и это судя по всему был последний из выживших.


вторник, 9 июня 2015 г.

Как тестируются программы, от которых зависит жизнь людей?

Недавно появилась статья, чем-то напоминающая много кем известную "Они пишут правильную вещь" (оригинал).

Мне кажутся интересными ряд моментов для передачи свойств предметной области. А вместо их выделения проще привести и перевести все целиком. Ниже мой перевод.


Как правило, обычный писатель программ-скриптов скорее всего не приводит полный пакет доказательств со всей строгостью формальной верификации. Это хорошо потому, что средний программист также не пишет программы для реактивных самолетов или атомных станций, или для роботов-хирургов. Но кто-то же пишет — и когда ваша жизнь окажется в руках его программы, то хорошо бы иметь высокую вероятность безошибочной её работы. И в тот момент, как вы можете быть уверенным в том, что этот человек, — не бездарность?

А никак. Что ставит другой вопрос: как этот тип программ тестируется?

Это было в небольшом посте блога, написанном Gene Spafford, профессором информатики в Purdue University, написанным на волне ответа на этот конкретный вопрос. Он ссылается на историю об истоках кокпитов, где началась применятся проводная связь — такие самолеты управляются в полете электроникой, внедрение чего случилось непосредственно в конце 1980х. Мы уже привыкли к таким самолетам, но тогда это был большой скачок вперед: прямой контроль был убран и передан в руки программного обеспечения, которое было разработано для телеуправления механическими приводами из кокпита. С того момента компьютер мог разбить самолет.

А фактом являлось то, что людей, которые отвечали за компьтеры, поместили непосредственно в тестируемую среду.

Spafford пишет:

В конце 1980х, где-то когда аэробус A340 был представлен (1991), тем из нас, кто работал над разработкой программного обеспечения, критичного к безопасности, рассказывали историю (возможно апокрифическую). Эта история о том, как программное обеспечение электронной авионики тестировалось на основных коммерческих авиалайнерах. Согласно истории, инженеры аэробуса реализовали и верифицировали согласно последним самым сильным формальным методам, предоставляли результаты проверки моделей и формального доказательства всего кода авионики. В то же время, согласно истории, Боинг выполнял обширное тестирование и рецензию кода, и принуждал всех своих инженеров программного обеспечения участвовать в первых полетах самолетов. Основным результатом истории было то, что для большинства из нас (как казалось) было то, что всем нам было более комфортнее лететь на самолете Боинга (было бы интересно посмотреть осталось ли таким же мнение сообщества программистов).

Таким образом, программисты Боинга имели дополнительную мотивацию потому, что им в будущем приходилось отдать свою жизнь в руки своего же программного обеспечения. Там, на высоте 9 000 метров, нет возможности что-то исправить — оно должно просто работать. И с чем вы будете более комфортно чувствовать: имея чей-то личный подход к верификации программного обеспечения (прим. оценка эксперта, рецензия), или, с другой стороны, имея кучу формальных доказательств и результатов имитационных испытаний?

Я бы предпочел и то и другое, но вопрос как тестируется это все интересен сам по себе. Ветка Stack Exchange 2011-го года предоставляет много интересного внутренней кухни данного процесса и его эволюции. Для начала, подход Боинга выходит из моды и в основном вышел из моды, согласно сообщению гуглера Uri Dekel:

Там серьезный шаг вперед в плане формальной верификации по сравнению со случайным функциональным тестированием. Государственные агенства, такие как НАСА и некоторые военные ведомства, тратят больше и больше денег на развитие этих технологий. Решение задач такого уровня все ещё PITA (pain in the ass — боль в заднице) для среднего программиста, но они намного более эффективны в тестировании систем, критичных по безопасности.

Scott Whitlock, инженер-программист, который поддерживает свою библиотеку для автоматического тестирования FluentDwelling, смотрит глубже, разьясняя проектные требования для безопасных трансляторов, являющихся системами промышленного применения для мониторинга оборудования, который передает сигналы предупреждения и может остановить сложное оборудование в случае необходимости. Они включают в себя, согласно Whitlock'y, "Два резервированных процессора, которые обычно запистываются от независимых источников питания, и выполненных конструкционно по-разному. Код, работающий на каждом процессоре, разработан двумя раными командами программистов, выполнивших свою работу в изолорованных друг от друга условиях. Результат вычислений обеих процессоров должен быть одинаков, иначе срабатывает реле безопасности."

"После того, как вы создали свою безопасную систему, то логика её контроля сама по себе может являтся большой проблемой." И Whitlock добавляет: "Программисты часто ломают машины, из-за чего наносится ущерб в тысячи долларов, но в их случаев никто не получает травм."

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

"Это программное обеспечение никогда не падает" — пишет Charles Fishman. "Оно никогда не требует перезагрузки. Это програмное обеспечение без багов. Оно совершенно настолько, насколько это возможно из всего того, что было создано человеком. Посмотрите на эту статистику: как минимум три версии программы — каждая по 420 000 строк кода, имело только по одной ошибке. Последний 11 версий имели в общей сложности 17 ошибок. Типичные программы на рынке такой сложности будут иметь 5000 ошибок."

Как программисты НАСА все это делают? Ну, в основном им просто приходится. Малейший баг создает риск потери миллиардов доллагоров и жизней людей. И все это под пристальным вниманием публики.

Для кода как такового, идаельность приходит как результат в основном засчет прямой противоположности тому, что обычно ассоциируется под словом "программист". Креативность в команде Шаттла не приветствуется; работа в режиме 9х5; хитрый код и программисты-суперзвезды не приживаются; более половины команды женщины; отладка (debugging) практически отсутствует, так как ошибки являются редчайшим явлением. Программирование стало продуктом не кодеров и инженеров, а Процесса.

"Процесс настолько внедрен, что он чувствителен к любым ошибкам" пишет Fishman, "если есть проблема в программном обеспечении, то видимо что-то не так в организации того, как это все создается, и это должно быть исправлено." И программное обеспечение идеально в рамках погрешности.

И далее:

Группа разработки должна предоставить код, который полностью лишен ошибок, настолько идеальным, что тестировщики не должны ничего найти. Группа тестирования должна идти далеко во множестве сценариев полетов и моделирования, и стараются выявить настолько много недостатков, насколько это возможно. Результат — то, что Tom Peterson называет "дружественно-враждебные отношения". "Они соревнутся в том, что найдет ошибки." говорит Keller. "Иногда они дерутся как кошки и собаки. Разработчики хотят поймать все свои ошибки. Верификаторы возмущаются, что это забирает их время, выделенное на проверку программного обеспечения."

Итак, что вы думаете, астронавт будущего? Программист, который летит на орбиту под контролем своего программного обеспечения, или программист из группы НАСА?


пятница, 5 сентября 2014 г.

Математики и программисты по Дейкстре

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

Сейчас, читая Дейкстру (Programming as a discipline of mathematical nature), обнаружил интересное описание этой разности:

  1. In the standard mathematical curriculum the student becomes familiar (sometimes even very familiar!) with a standard collection of mathematical concepts, he is less trained in introducing new concepts himself.
  2. In the standard mathematical curriculum the student becomes familiar (sometimes even very familiar!) with a standard set of notational techniques, he is less trained in inventing his own notation when the need arises.
  3. In the standard mathematical curriculum the student often only sees problems so "small" that they are dealt with a single semantic level. As a result many students see mathematics rather as the art of organizing their symbols on their piece of paper than as the art of organizing their thoughts.

Не в моем переводе (не с первой попытки нашел на русском):

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

Написано это все в мае 1973 года, и сейчас, с возрастанием сложности систем и с более активной типизацией на прикладной стороне, эта разность стала ещё более явной.


воскресенье, 10 августа 2014 г.

Удобны ли ваши API?

Написанное здесь обусловлено тем, что в последние год-два приходилось сталкиваться наверное раз пять с различными проявлениями в отношении пользователей к API и документации в целом. В данном сообщении в основном все базируется на одноименной статье Стивена Кларка, имеющейся в книге «Идеальная разработка ПО», и в е-виде содержимое на находится. Стивен провел более 10 лет работая над совершенствованием API в Microsoft'е, с 1998-го года, с такими инструментами, как Visual Studio.

Удобство API

Сплошь и рядом попадается ситуация, когда проектирование библиотек, API и т.п. происходит как есть, для себя, по каким-то высшим или подсознательным катеогриям, но без какого-либо обращения внимания на пользователей, их разнообразие и решаемые ими задачи. Так получается, что потери reengineering'a с той стороны либо совершенно не волнуют, либо списываются на глупость или неусидчивость пользователей, и более того, идут аргументы вида «а вы используете неправильно, не ходите туда и не делайте так, делайте как мы».

Цитата С. Кларка:

Меня как разработчика, который пользовался Visual Studio до присоединения к группе Visual Studio, используемые инструменты часто раздражали. Параметры компилятора было трудно найти и задать. Настройка путей к библиотекам выглядела громоздкой и неудобной. У продукта было много недостатков из области удобства использования, которые я хотел исправить при поступлении на работу в Microsoft.

Я не хочу сказать, что у меня не было трудностей с API фирмы Microsoft. Напротив, чуть ли не самые серьезные проблемы, с которыми я когда-либо сталкивался, были связаны с пониманием API библиотек MFC. Но в отличие от ситуации с инструментами, в том, что мне не удается разобраться в правильном использовании VFC, я винил только себя. Ни разу я не подумал, что проблема крылась в проектировании API.

Такая реакция на плохо спроктированные API встречается очень часто. Многие разработчики объясняют возникающие трудности своей неопытностью в обращении с API. Будь у них побольше времени, то они бы во всем разобрались. Я много раз слышал, как разработчики говорят, что им просто не хватает ума для освоения API.

Таким образом, документация и API могут быть неудобными и плохо спроектированными. Если на это не обращать внимания, то именно так и произойдет, а при более внимательном рассмотрении можно даже понять почему.

Работа с API не представляет собой работу со всем API целиком

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

Вторым моментом является то, что все API редко кто понимает или даже пытается понять, так как это большой объем информации. Используется какой-то участок фронта для какой-то задачи в течение какого-то времени. И все. Но с другой стороны баррикад почему-то считается правильным заставлять других учить авторские предрассудки и геометрию граблей архитектуры. Зато удобно и есть кого обвинить.

Аналогичную ситуацию наблюдаю с документацией. Вместо решения конкретных задач и ориентации на пользователя пишется большой талмуд обо всем, а на все вопросы идет ответ — идите читайте нашу прозу и медитируйте над тем, что мы тут натворили. Это как если бы вы пришли на почту с вопросом, когда приходит почтальон, а в ответ вам нужно было бы изучить архитектуру того, как работает организация, кто за что отвечает, откуда берет план и график обхода с точной траекторией.

Таким образом, в редких случаях идет работа пользователя целиком со всем, что есть. А для пользователя есть задачи, которые ему нужно решать. И в круг этих задач не входит постижение некого дао.

Разные пользователи

Одним из результатов исследований было то, что пользователи разные, в том плане что они по разному работают с API и её документацией. И вписаться сразу в каждый мир и угодить всем мягко говоря, сложно.

Три типа пользователей из статьи:

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

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

В данном случае одно из решений — сценарно-ориентированное проектирование. Так понял, что в данном случае это когда на сооветствющем уровне абстракции готовятся API и документация для соответствующего типа пользователя.

Таким образом, пользователи разные, и что хорошо одному, может быть плохо другому, и наобормот.

Архитектура API и интерфейс пользователю

Архитектура это одно, и она не обязана быть известной пользователю. Более того, чаще всего она не помогает в решении задачи. Для пользователя намного важным является интерфейс и предоставляемая функциональность, позволяющая решать его задачи. И если описывать архитектуру, то получится много, и не для пользователя.


пятница, 18 апреля 2014 г.

Carlos Bueno — Mature Optimization

Ещё одна книга книга, прочитанная пару месяцев назад, рассказывающая об оптимизации приложений реального времени. Написана одним из членов команды по оптимизации в Facebook.

Из неё хотелось бы процитировать некоторые вещи.

Сложные проблемы и простые решения

For every difficult problem there is a soliution which is simple, obvious, and wrong.

У каждой сложной проблемы есть простое и очевидное решение… но оно неправильное.

Если не контролировать, то это наблюдается постоянно, когда для оптимизации сложных систем начинаются умопостроения на никаком объеме данных. Такие действия представляют собой случайные блуждания с слабопредсказуемым результатом. Противоположным подходом является понимание того, как работает система; упрощение на этапах проектирования для последующего понимания; создание аккуратных систем диагностики.

Простой и целевой мониторинг

It’s a common mistake to overload your dashboard with too much information. The fanciest hospital monitor can describe something as complex and important as a living being with less than ten metrics. "While the human is operating normally, the heart rate graph should never change drastically, go below 60, or above 100." You can do the same with a computer system. A dashboard is for monitoring, not diagnosis. It’s only job is to tell you that something is wrong, and give a rough clue about where to look next.

Это общая ошибка перегружать ваш мониторинг большим количеством информации. Самый модный монитор в больнице может описать такую сложную и важную систему [как человек] с использованием менее чем 10-тью параметров. "Когда человек в порядке, то его сердечный пульс никогда быстро не изменяется, не уменьшается менее 60 и не увеличивается более 100." Вы можете сделать то же самое с компьютерной системой. Панель мониторинга, а не система, ставящая диагноз. Её задача - говорить что что-то пошло не так, и дать грубое направление того, на что смотреть в дальнейшем.

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


четверг, 14 ноября 2013 г.

Защита от Злого гения Декарта

Которой не существует. Но все таки я его нашёл!

Понятие

Регулярно как минимум в инженерной среде при проектировании (а точнее, при валидации) чего-нибудь складывается следующая ситуация. Разработчики придумывают какое-нибудь решение, а критики вокруг начинают придумывать разные идеи по поводу того, «а что будет если …». Изначально предлагаются осмысленные варианты поведения (здравомыслящие и логические), далее идет рассмотрение крайних случаев, потом идут какие-либо безобидные ситуации (как некорректный ввод пользователя), но в дальнейшем начинается нечто более серьезное. Что будет если закончится место на диске? Как разруливать ситуацию, если мы имеем нагрузку X, а нам дадут 10*X? А если задача зависнет? Однако, на этом дело не заканчивается. Идут вопросы о том, что делать если сыпется диск? А что если CPU будет не успевать? А если откажет таймер и часы переведутся? А если выйдет из строя тактовый генератор процессора? … где-то в конце этого списка молния попадает в компьютер, но он все равно должен выжить и выполнить боевую задачу.

В литературе по отказоустойчивым системам (fault-tolerance systems) между строк и сквозь все пронзает мысль о том, что нельзя построить систему, которая была бы оказоустойчивая и безопасная ко всему. Только сейчас в статье Marco Schneider'a нашел понятие того, кто пытается любыми способами сломать систему и с фактом того, что всегда есть возможность ему это сделать. То есть, если мы рассматриваем действующую систему, то мы можем находясь извне всегда придумать такую ситуацию, чтобы эту систему сломать, т.е. сделать так, чтобы она перестала функционировать. В статье такая роль называется malicious adversary или evil demon, последнее из которых — Злой гений Декарта.

Опытные и неопытные разработчики

Уровень 1. Новички в инженерии совершенно лишены тормозов и не знают о том, что вообще этот Злой гений существует. В связи с этим то, что они хотят сделать, они реализуют быстро, как придется и так, чтобы работало (классический Cowboy). У них нет в сознании множества граблей, на которые можно наступить. Нужно отправить e-mail? Где процедура… какие параметры? … сейчас подставим и всё! Готово! (пора рапортавать менеджерам о своей высокоэффективности). Однако то, что SMTP-сервер может быть не доступен, не обрабатывается. Письмо может не влезть в ящик, e-mail совсем не e-mail, пароль захордкожен и в открытом виде, бесконечный запрос отправки вешает всю систему, а ошибки сервера забыты, и это далеко не полный список.

Уровень 2. Более опытные разработчики имеют карту местности с множеством граблей, и отлично понимают, что наступить на новые, или на старые, можно в любой момент. Злой гений Декарта присутствует, но он есть интуитивно: уровень проработанности определяется на глазок, по срокам и ресурсам, а те, кто будет аргументировать методом «а что, если молния в компьютер?», будет мягко говоря, проигнорирован. Но даже для весьма опытных специалистов вопросы Злого гения ставят в тупик. Я несколько раз наблюдал ситуацию, когда в кругу матёрых инженеров (один пример на IT-конференции, второй в обществе специалистов по отказоустойчивым системам, третий в общении программистов со стажем порядка 10 лет) имел место диалог вида:

— Вот вы столько всего рассказали, все так интересно, но все равно ваша система не сможет спасти от всего?

— Да, не сможет.(с виноватым видом без акцента на то, что так вообще-то не сможет любая система)

Такой вот универсальный троллинг 2-го уровня.

Уровень 3. Понимание того, что Злой гений Декарта есть, универсальной защиты от него нет, но с ним можно бороться. А тот, кто предлагает универсальные способы решения — алхимик современности.

А как бы вы решали проблему защиты от Злого гения Декарта?

Мне известны два широкополосных способа, позволяющие эффективно решать данную проблему.

Решение 1: На основе анализа предыдущего опыта

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

Когда спроектировали и пустили на воду Титаник, он считался непотопляемым. Данный вывод был сделан не а пустом месте. В качестве доказательства в пользу имелся ряд аргументов и фактов. Для упрощения (там было много всего), Титаник был спроектирован в качестве корабля с множеством независимых отсеков, который остается на плаву в случае пробоин и затопления 4-х из них. Исторический опыт того времени говорил о том, что во всех катастрофах было так, что корабли не получали повреждений более, чем на заполнение 4-х отсеков. К сожалению, в результате столкновения у Титаника было затоплено 5 отсеков.

Ключевым в данной истории является то, что для решения проблемы непотопляемости был проанализирован исторический опыт и имеющиеся технические возможности, в соответствии с которыми стало возможно ликвидировать на каком-то уровне все опасности, которые угрожали кораблям-предшественникам. Это так называемый Hazard Analysis, используемый сейчас во всех западных системах, критичных к безопасности. Но подобного рода анализ для всех разрабатываемых систем ещё не пришел (дорогое удовольствие).

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

Решение 2: Вероятностная защита

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

Классическими иллюстрациями для этого могут служить криптостойкость ключа при шифровании и контроль CRC в обычных системах (при передаче данных или например для проверки на сбои в памяти).

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

Если используем простейший CRC, то он позволяет также сделать так, что проявление сбоя будет замечено с высокой вероятностью, и не замечено — с пренебрежимо малой. Мы не защищаемся от всех сбоев, но зато защита идет от абсолютного большинства из них. И, если например CRC32, то следует помнить, что в случае сбоя если один из TCP/IP пакетов или запакованных архивов будет распакован или разобран в битом виде, при этом с вероятностью 2-32 мы этого не заметим и никто нам об этом не скажет.

Здесь Злой гений Декарта есть, и полностью победить его невозможно, но он для победы должен быть достаточно мощен, чтобы перебрать ключ или достаточно удачлив, чтобы пройти через CRC.

Завершение

Кроме описанных могут быть другие, близкие решения. Например стоимость взлома крипто-ключа в экономических единицах. Но по-моему, это косвенное, а не прямой метод решения.

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


среда, 13 ноября 2013 г.

О проблемах программного обеспечения в 1983-м году

Цитата из статьи 1983-го года:

If you look at when the Bank of America central computer crashes and start doing statistics, you find that occasionally somebody has spilled coffee in the mainframe, or something like that happened that you can understand. But, in about 95% of those crashes, they don't really know what caused it. The system goes down, somebody says "Oh, here it goes again," and they push the reboot button. It takes them a couple of minutes to bring the stuff in from disk, the system starts again, and everying is fine. So, depending on the particular prejudices of whoever is recording those things, it was either a transient hardware failure, or whatever they like to call it. But basically, they just don't really know what happened.

Если вы взглянете на статистику аварий центрального Банка Америки, то вы обнаружите, что кто-то внезапно пролил чашку кофе на центральный процессор, или что-нибудь подобное, что может произойти и при этом можно понять что именно. Где-то в 95% случаев этих аварий никто не знает что на самом деле произошло. Система падает, и кто-то говорит: «Ё-мое.. опять..», и нажимает кнопку рестарта. Это требует нескольких минут, так как требуется загрузка с диска, после чего система стартует снова, и опять все хорошо. Однако, в зависимости от пожеланий-заморочек сопровождающих, они записывают это как временный аппаратный сбой или что-то в этом духе. Но на самом деле они даже не представляют, что это было.

Такое ощущение, что за 30 лет ничего не изменилось.

Хотя например есть свидетельства и результаты исследований ещё на рубеже 90-х (в книге Leveson), что там, где есть специальные меры и отсутствуют быстрокодописатели и какможнобыстреереализаторы, все намного лучше.

Разное

Статья сама по себе интересная, просто отмечу тезисно несколько вещей.

  • FIFO и LIFO — это все приоритетные очереди, только их частные случаи. Эти структуры данных не обязательно должны быть реализованы так, как это пишут в учебниках (массивы, списки) — они должны выполнять внешние спецификации, и только.
  • Ограничения и стоимость синхронизации и параллельности определяются аппаратной частью, и не могут быть решены в вакууме.
  • Сначала идет идея и реализация, а только потом формализация того, что было сделано.
  • В распределенных и параллельных системах спецификация и доказательство корректности должно быть на высоком уровне, а реализации их выполняющие — на низком.

пятница, 8 ноября 2013 г.

Фальсифицируемость спецификаций

— Какие могут быть формальности между друзьями! Вася, сделай мне программу сортировки.
— А что такое сортировка?
— Мне надо, чтобы я вводил любые числа, а программа выдавала упорядоченные числа.

(через неделю)

— Ты что, Вася! Я ввожу 5 4 7 6, а твоя программа выдает 1 2 8 9.
— Так бы и сказал, что она должна использовать введенные числа.

(через неделю)

— Ты что, Вася! Я ввожу 5 4 7 6, а она выдает 4 5 6.
— Так бы и сказал, что все числа должны присутствовать.

(через неделю)

— Ты что, Вася! Я ввожу 5 4 7 6, а она выдает 4 5 6 7 и 8 и 9.
— Я выдал все, а от себя добавил, по дружбе, чтобы ты от меня отстал, наконец.

(через неделю)

— Ты что, Вася! Я ввожу 5.4 и 7.6, а она даже два числа отказывается сортировать.
— А откуда я знал, что тебе не только целые надо сортировать? Может тебе завтра взбредет комплексные сортировать?! Последний раз!!!

(через неделю)

— Ты что, Вася! Программа больше девяти чисел не сортирует…

© Конспект лекций для Светы

Фальсифицируемость

Одним из величайших последних изобретений в философии является фальсифицируемость, позволяющая эффективно бороться против любых чайников Рассела. В последнее время все чаще и чаще убеждаюсь в том, что по отношению к инженерии и сферы IT в частности, сторонники чайников живут среди нас и пока что процветают, но их позиции, к счастью, слабеют.

Что такое фальсифицируемость подробно есть в википедии, но для моего контекста достаточно того, что. Любое утверждение должно быть проверяемо (тестируемо). Если оно не проверяемо, т.е. его нельзя протестировать, значит оно ничего не стоит и его нужно выбросить на свалку. В крайнем случае, переформулировать или заменить. То, что можно протестировать — фальсифицируемо. То что нельзя — нефальсифицируемо.

Иллюстрация первая: классическая (в качестве введения)

Приходит заказчик и говорит: «Я хочу программу, и чтобы она работала». Переводя с пользовательского на народный это означает: «У меня есть проблема, и я хочу, чтобы её не было. Разберитесь пожалуйста, что это у меня за такая проблема, и решите её, и чтобы у меня её не было. А что за проблема я знать не знаю и знать не желаю.»

Иллюстрация вторая: недавняя

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

WTF?? С каких это пор можно сделать систему, которая решает любую проблему и приспосабливается к любой ситуации?? Для меня вышенаписанное это звучит как: «Мы вас просили спроектировать непотопляемый корабль. А то, что сделали вы, утонуло после первого попадания ядерной боеголовки».

Удобные спецификации

«Так, вам задание. Система должна работать быстро. Отвечать на запросы — как можно быстрее. И не занимать много памяти. И, ещё, это…, проект должен быть готов чем скорее, тем лучше. »

Сделать универсальную систему невозможно, нужно оптимизировать по каким-либо параметрам. Но кроме этого, здесь следующее: такая формулировка очень удобна. Если вдруг окажется, что система тормозит, то всегда можно сказать «Мы же просили сделать так, чтобы система работала быстро! Почему не сделали?». «Медленно отвечает? Мы говорили вам!» …

Но с другой стороны: «Система вообще-то работает быстро. Может не так быстро, как хотелось бы, но это быстро!»

В результате никто ни в чем не виноват и никому ничего не должен.

Исторический пример неточных требований

Даже в больших и серьезных системах не удается всегда избежать подобных проблем. Для примера рассмотрим случай с верификацией программного обеспечения атомной станции в Онтарио, рассматриваемая здесь часть которой подробно расписана в статье автора, проводившего верификацию.

В спецификации было указано следующее:

“Shut off the pumps if the water level remains above 100 meters for more than 4 seconds.”

“Выключите насос в случае, если уровень воды остается выше 100 метров в течение более чем 4-х секунд.”

Как бы вы проверяли программно эту ситуацию? Т.е. какая математическая формула выдавала бы ответ о том, нужно выключать насос или нет.

Особенности верификации ответственных систем таковы, что проверка делается независимой группой, которая выполняет полный цикл обратной разработки. В том числе и интерпретацию требований без заглядывания в исходники. Специалисты по проверке предложили три интерпретации:

  1. Среднее арифметическое за последние 4 секунды больше 100 м.
  2. Среднее между минимумом и максимум за последние 4 секунды больше 100 м.
  3. Среднее квадратическое за последние 4 секунды больше 100 м.

В дальнейшем оказалось, что разработчики использовали 4-ю интерпретацию, отличную от 3-х предложенных: вычисление минимального уровня воды и сравнение его с 100 м. Кроме того, что это неоднозначно, это была самая опасная из 4-х формулировок, так как кратковременный высокий уровень воды может привести к серьезным проблемам на станции, а последняя из формулировок оставит этот факт незамеченным.

Таким образом, чтобы требования были проверяемы, нужна их точная математическая формулировка. Если требования сделаны на естественном языке, то это приводит к множеству различных противоречивых толкований, и в том числе к ошибкам и проблемам.

Необходимость фальсификации

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

В более жестком варианте необходимость фальсификации спецификаций звучит так: если мы не можем проверить требование, то оно считается нефальсифициуемым и подлежит удалению, замене или пересмотру.

Таки образом, для каждой из спецификаций должны быть описаны конкретные условия проверки (что проверяется, условия, обстоятельства и т.д.; полная постановка эксперимента (теста) ). Иначе они трактуются как попало и не работают.

Позитивные сдвиги

К таким сигналам отношу следующее. В последнее время несколько раз встречал из различных источников (внутренние правила компании по качеству; слова умных людей; методологии в IT), что: в разработке необходимо 100%-е покрытие тестами; если вы не можете проверить тестами, то и не реализуйте — практически наверняка есть проблема на предыдущих этапах.

Вывод

Таким образом, фальсифицируемость решает проблему демаркации — отделения реальных требований к системе от бесконтрольных хотелок.

Кроме того, фальсифицируемые требования являются надежным контрактом между заказчиком и разработчиком.


пятница, 13 сентября 2013 г.

Синглтоны языков программирования

Разбираясь с некоторыми вопросами высоконадежных систем, предназначенных для управления критически важных процессов информатизации (safety-critical systems), нашел некоторую особенность и попытался её разгрызть, почему сделано так.

Согласно стандарту ISO 61508 (сейчас он же действующий ГОСТ Р МЭК 61508), крайне не рекомендуется использовать динамическую память и динамические объекты (что для серьезных западных систем означает нельзя). Аналогичные требования есть в JPL Coding Standard (это ответственные системы NASA, например софт для марсоходов и МКС) и в MISRA C/C++(ответственные системы по умолчанию, например химическое производство которое может устроить катастрофу или автомобильный транспорт с тем же потенциалом для последствий).

Однако, если создать свою структуру данных и верифицировать её в рамках проекта (это обычно не означает написать пару сотен строк кода за день-два, а работу нескольких высококлассных специалистов в течение нескольких месяцев (счет для самых простых структур данных начинается с 3-х месяцев), которые проведут её через все этапы разработки с многоверсионными проверками спецификаций, полным черно-белым тестированием, верификацией формальными методами с использованием дедуктивного анализа и модели с задействованием автоматики, экспертная оценка как человеком, так и автоматикой (статическими анализаторами кода в т.ч.), и все это умножить на два из-за проверки независимой группой по всем этапам). Удовольствие дорогое, но возможное. (отдельным путем является использование компилятора, обеспечивающего безопасное поведение в случае отказов; классические и всем известные C/C++ к таковым не относятся; к ним обычно относится верифицированный куцый C/C++).

Авторов всего этого понять можно: динамика поставила на колени далеко не один проект С/C++, а в последние годы много усилий ушло на уменьшение последствий от возможных проблем на данном минном поле.

Прошло какое-то время, прежде чем мною ощутилась разница между описанным первым (глобальной динамикой) и вторым (верифицированными структурами данных): отдельно разрабатываемые структуры данных играют (в том числе) роль специализированных менеджеров памяти, а поставляемые в коробке new/delete и malloc/free — синглтонов языка программирования.

Динамика как синглтон

new/malloc и delete/free работают глобально, в одной большой куче. Доступ к ней есть отовсюду. О том, как лучше работать с этой кучей — изобретается множество инструментов и техник, так как надо контролировать создание (только один раз) и удаление (только один раз и только после создания), обрабатывать ошибки (переполнение памяти), попадать куда надо указателем (неопределенное поведение) и типом (срезка), получать доступ и разделять ответственность. Фактически сама куча является глобальной структурой данных, поддерживаемой на уровне языка.

Если мы переключаемся с фокуса глобального хранения на малую изолированную структуру данных, то сразу посредством модульности снимается комплекс проблем, в основном за счёт резкого снижения сложности и разделения ответственности.

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

Синглтоны C++

Прошелся по языку и нашел следующие синглтоны:

  • new/delete
  • static
  • cout/cerr/cin
  • Ресурсы (файловые дескрипторы, коннекты, потоки, …).
  • Нелокальные макросы.
  • Указатели.

Т.о. язык предоставляет пользователю набор синглтонов в упаковке, готовых к использованию.

Свойства

Свойства очень похожи из того, что есть в оригинальном синглтоне. Для всех описанных (кроме макросов, они на этапе сборки):

  • необходимо заниматься синхронизацией в многопоточном приложении;
  • все сущности видны отовсюду, и любой может сломать сразу все;
  • если в проекте/библиотеке сущность уже прибита гвоздями к стенке, то её размножить сложно;
  • нужно заботиться о потенциальных побочных эффектах и сводить в stateless после каждого вызова;
  • узкое горлышко многопоточной производительности;
  • некоторые синглтоны обладают разной степенью глобальности.

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

Т.о., понимание синглтонов позволяет лучше ощутить источник проблем и ведет к светлому будущему (;


четверг, 12 сентября 2013 г.

Алхимики современности или неразрешимые проблемы

Раньше алхимики искали философский камень и способ превратить что-нибудь простое и подручное в золото. Т.е., каким-то простым действием (например хитрым ударом молотка и словами «крэкс-пэкс-фэкс») сделать из куска глины кусок золота. Закончилось все это тем, что простого способа не нашли (в настоящее время на это нужно потратить огромное количество энергии для ядерных реакций), но попутно было изобретено много чего.

Но алхимики никуда не исчезли. Они до сих пор среди нас, только декорации изменяются.

Здесь хочу выделить отдельный класс т.н. неразрешимых проблем и описать пару их свойств.

Современные примеры

Поиск серебряной пули

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

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

Поиск элексира вечной молодости

Это алхимики как древности, так и современности. В древности правители щедро финансировали поиск вечной молодости, стараясь как выведать что-нибудь за тридевять земель или шпионажем, так и спонсируя отдельных естествопытателей.

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

В этом контексте можно провести аналогию с автомобилем. Нет одного способа сделать так, чтобы машина всегда ездила исправно и без проблем (кроме как заменить все). Нужно регулярно проводить осмотр, менять масло и фильтры, ездить по правилам, не выходить за нормы эксплуатации, использовать качественное топливо и т.д.. Остается только представить, что человечество если что может починить автомобиль, так как оно его понимает, а биотехнологии ещё не дошли до того, чтобы понимать все в человеке. И даже когда мы будем все понимать, то будет существовать вероятность трагедии.

Знание языка

Имеется ввиду человеческого языка общения.

Язык выучить или знать полностью невозможно, как не свой, так и родной. Носители языка регулярно допускают ошибки и не знают всех слов, даже профессиональные редакторы делают опечатки и могут чего-то не знать. Мы всегда знаем какие-то подмножество языка, например его ядро плюс специфические профессиональные области. Мы можем попробовать выразить свою мысль, но всегда найдется способ сделать это точнее, быстрее или доступнее.

Легко обратить внимание, что на данном поле многие предлагают легкие пути освоения языка. Но царского пути нет, и использовать надо все доступные способы. Мы быстро учимся говорить когда нужно общаться вживую, быстро пополняем лексику если читаем книги, быстро учимся правильно писать если пишем и наши ошибки исправляют, мы можем научиться слышать язык только прослушав множество его носителей. Для результата надо использовать весь комплекс методов и средств.

General Problem Solver

Это мое прогностическое мнение. Не существует универсального AI, решающего любую проблему. Есть много разных AI с разной эффективностью, и естественный интеллект не исключение.

Было и будет много разных интеллектов. Много предлагателей универсальных интеллектов. Много попыток его построить с провалом, но с косвенными плюшками.

Свойства

Все свойства расписаны выше, но здесь их явная систематизация.

Кроме того, мое контекстное определение. Неразрешимая проблема — такая проблема, которая решается частично, но не может быть решена полностью, либо полное её решение слишком затратно; мы можем решить её частично, и улучшить результат, но полного решения нет.

Полезность и бесполезность попыток

Исторически показано, что подобные попытки зачастую не приводят к решению самой проблемы, но приносят большое количество косвенных плюшек и изобретений. С одной стороны, проблема не нешена, а с другой — плюшки есть.

Полагаю, что зачастую получается так, что коэффициент полезность/затраты такого поиска слишком мал и множество усилий уходит впустую.

Множество предложений простого способа

Вокруг проблемы расцветает большое количество предлагателей простого способа решения проблемы, как забесплатно, так и втридорога.

Нет простого способа

Нет унивесального способа, но путь есть. Он тяжелый и трудный, но он есть, и нужно использовать весь комплекс методов и средств для решения проблемы.

Оптимизм

Есть вещи, которые не таковы, какими мы хотели бы их видеть. Очень хочется иметь философский камень, универсальный молоток, элексир молодости и пр.. Но реальность не такова.

Заключение

Когда каркас данного сообщения был готов, то перечитал Брукса (его Мифический человеко-месяц, где есть No Silver Bullet с историей 10 и 20 лет спустя). И с восхитительным удивлением нашел там следующую цитату:

Из всех попыток науки продвинуться в ложном направлении наиболее возвышенны те, которые были направлены на поиск философского камня — вещества, с помощью которого предполагалось обращать простые металлы в золото. Высшая цель алхимии, к которой с рвением стремились поколения исследователей, щедро финансировавшиеся светскими и духовными правителями, — это в чистом виде стремление принимать желаемое за действительное и общепринятое мнение, что вещи таковы, какими мы хотели бы их видеть. Это очень по-человечески. Нужно сделать над собой большое усилие, чтобы смириться с существованием неразрешимых проблем. Стремление вопреки всему найти выход, даже когда доказано, что его не существует, очень и очень сильно. И в большинстве своем мы с большим сочувствием относимся к этим храбрецам, которые пытаются достичь невозможного. Это продолжается и по сей день. Пишутся сочинения о квадратуре круга. Стряпаются лосьоны для восстановления утраченных волос — и неплохо продаются. Рождаются методы повышения производительности программирования — и хорошо расходятся. Мы слишком часто склонны доверять своему оптимизму (или эксплуатировать оптимистические надежды своих спонсоров). Мы слишком часто не хотим прислушиваться к голосу рассудка и обращаем много внимания на продавцов панацей, поющих голосами сирен.

Turski W. M. And no philosophers’ stone, either // Kugler H. J. (Ed.). Information Processing 86. Amsterdam : Elsevier Science, North Holland, 1986. P. 1077-1080.

суббота, 24 августа 2013 г.

Развитие технических систем — Взрыв и стандартизация (с примером IBM)

Лампочки накаливания появились не сразу, а долгое время изобретались разные варианты решения. В свое время Эдисон перебрал две тысячи лампочек, прежде чем выбрал ту самую, которая победила газовое освещение.

При выходе в новую область наблюдается взрыв разнообразия различных форм. Так было с самолетами в 20-30-х гг., так было в войне Unix'ов, так было с кодировками до ASCII и до UTF-8.

Аналогичный процесс есть в биологических системах, где классическими примерами являются взрывы разнообразия при выходе на сушу и при освоении воздуха, а самым большим выглядит Кеймбрийский взрыв.

После взрыва запускается процесс естественного отбора, когда разнообразие начинает уменьшаться, а видообразование приостанавливается. Отдельные наиболее приспособленные особи выживают и захватывают большие области, другим видам питаться нечем и они отмирают. Так, на сушу в свое время вышли 5-ти, 6-ти и 8-ми пальцевые существа, но выжили только потомки первых, потому мы такие и других больше не наблюдаем.

В технических системах происходит аналогичный процесс, когда остаются в основном 4-хколесные машины шириной в две крупы лошади, мейнстримовые языки программирования, типовые решения для аппаратных устройств (генераторы, трансформаторы), коробочные продукты (one-the-shelf), … Большие выжившие монстры решают большие классы задач, а в маленьких закоулках ютятся отдельные подвиды, зачастую мало кому известные и потенциально отмирающие.

Технические пути отбора

В технических системах с точки зрения отбора можно выделать два механизма.

Первый — насильственный захват и выбивание конкурентов. Например как это делает Windows — разработчики Windows сами себе стандарт, не обращая внимания на других, и способ захвата — выживают те решения, которые выигрывают на рынке, даже если эти решения не являются сильными. Это и сама ОС, и Ctrl-C Ctrl-V (задолго до них был Ctrl+Insert и Shift+Insert), и Win-1251 и др.. С точки зрения разработки — это решения для себя, для полного контроля и для вписывания в внутрикорпоративные стандарты.

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

Технетика

Естественно, напрямую переносить эволюцию с био- на техно- нельзя, но в них много похожего и подходит для аналогичного объяснения. Био-эволюция по большому счету слепа в своем отборе (по очень малому нет), а для технических систем несколько шагов вперед проверяет человек, сразу отрабатывает несколько вариантов и имеет некоторую цель для реализации.

Таким образом, любые технические системы развиваются, живут и умирают. И, как ни странно, есть целые труды и школы, которые описывают данный процесс. С одной из таких я познакомился где-то на рубеже 2000-х, это была Технетика Б.И.Кудрина — информация в ней зубодробительна и слишком философска для обычных людей, но базовые понятия развития техники удалось почерпнуть именно оттуда. В дальнейшем элементы технетики встречались и замечались в жизни много раз, иногда принося существенную пользу.

Стандартизация вычислений с плавающей точкой

Сейчас ещё один такой случай, который увиделся при чтении Fatal Defect (chapter Wrong Number), где подробно разобрана история становления стандарта по вычислительным арифметическим операциям на компьютерах/калькуляторах с плавающей точкой. Особенность в том, что в 60-х не было единого подхода и решения того, как хранить вещественные числа в компьютере, а также как проводить вычислительные операции. Каждая организация делала свое решение, а зачастую внутри организации разные аппаратные разработки имели разные реализации.

Особенностей разностей несколько. Для примера, первая в том, что для повышения точности можно хранить разное количество дополнительных разрядов (кроме отображаемых на дисплее калькулятора можно хранить 0, 1, 3, … разрядов за краем табло, чтобы потом результат вычисления был более точным; например если не хранить, то 1/3*3 получится 0.99999). Второй является то, что можно использовать разные способы округления, которые также могут отражаться на конечном результате. Третьей являются разные алгоритмы выполнения данных операций, каждый из которых может отличаться точностью, быстродействием и неравномерным распределением ошибок. Четвертой — возможно разные преобразования между отображением и вычислением (например сначала берется то что на дисплее в 10-й системе счисления, переводится в 2 с/c, считается, далее обратно в 10 с/c). Пятой — стоимость системы.

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

Компьютер в любом случае не может обеспечить 100%-й точности для всех математических вычислений (так как числа в памяти есть конечное число единиц и нулей), и, казалось бы, с этим мало чего можно сделать. Однако в 70-х запустился процесс продвижения идеи, согласно которой необходимо было привести зоопарк к общему знаменателю, чтобы мы не всегда получали точный результат, но на разных компьютерах этот неточный результат был бы одинаковым.

В конце 70-х IBM инициировала внутри себя процесс создания подобного стандарта, так как зоопарк был внутри данной организации и руководство уговорили это сделать. После запуска процесса был собран IEEE-комитет из ~70 представителей различных компаний и институтов (не только из IBM). После многочисленных штурмов и споров (потому что каждый эксперт считает свои заблуждения самыми правильными) был выпущен черновой вариант с сомнениями о том, что этому кто-то будет следовать. Однако IBM в 1980-м выпускает первые чипы 8087, которые соответствовали описанным требованиям, и после этого запустился лавинообразный процесс, который охватил всех мировых производителей, хотя официальный чистовой вариант был принят в 1984-м.

По-моему, отличный пример гибридного решения стандартизации после взрыва (гибридное в плане потому, что с одной стороны был комитет экспертов, а с другой силовое решение о реализации стандарта в железе).


понедельник, 19 августа 2013 г.

О правильном

В начале всяческой философии лежит удивление, ее развитием является исследование, ее концом — незнание.

М. Монтень

Не бывает правильных (тру-шных и т.п.) программ. Бывают программы с определенными свойствами. Мы не проверяем тестами корректность программы, и не доказываем правильность формальными методами — а определяем вполне её конкретные свойства.

Не бывает правильного способа решения проблемы. Бывают способы с определенными последствиями.

Не бывает правильного принципа или метода. Бывают принципы и методы с определенными достоинствами и недостатками, работающие в определенном окружении.

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

Одно дело когда известен контекст и все понимают, чем «правильный» вариант лучше, чем остальные. Другое дело, когда контекст теряется, и народ уже не понимает что стоит за словом «правильный». «Потому что так написано в книге Х», «Потому что так сказал Y», «Мы всегда делали Z, и в дальнейшем будем делать так же», …

«Правильное» мышление дешевле. Не нужно заморачиваться о причинах, достаточно принять на веру. Так например учатся дети у взрослых, принимая опыт как есть, без какой-либо критики, но в том числе, не понимая причин почему именно так. Так принимают схемы поведения у авторитетов.

После того, как схема принята, то изменить её сложно. Классическая цитата Лоренца:

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

Если существо работает «правильными методами», которые лишены понимания причинно-следственных взаимосвязей, то мы и получаем такую картину, когда делается потому, что так делалось всегда, а шаг в сторону — это страшно. И работает эта штука подсознательно.

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

Понимайте причинно-следственные взаимосвязи.


пятница, 16 августа 2013 г.

Поступательное развитие

В последнее время вокруг меня что-то много звезд выстроилось по этому понятию…

Примеры

Нельзя сразу собрать проект, который реализует полет на Луну. Или создаст термоядерную бомбу. Или реализует национальную ПРО.

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

Для термояда сначала надо найти радий. Потом изучить его свойства и саму природу радиоактивности. Инженерно задача начинается с выделения конкретных изотопов в чистом виде. В процессе нужно как минимум заняться обогащением, что долго. Придумать конструкцию обычной ядерной бомбы. Взорвать. И потом только прийти к термояду.

Для ПРО сначала необходимо создать что-то, что сможет зарегистрировать массы самолетов. Потому что-то, что сможет засечь одиночный самолет. Потом что-то, что сможет засечь и определить высоту полета. Потом что-то, что сможет засечь, определить x,y,z,t и сбить. И только потом можно думать о чем-то, что сможет отразить атаку в глобальном масштабе.

Два простых правила

Давно в данной теме знаю и использую два простых правила:

Законченные и дискретные решения
Необходимость поступательного развития — серия законченных проектов, каждый из которых имеет конкретную реализуемую цель, решая часть общей конечной задачи. На одних чертежах виртуально запустить в космос человека нельзя — должна быть конкретная задача и её воплощение, все этапы жизненного цикла.
Сложные системы строятся из простых
После Буча сейчас много где цитируют J.Gall'a *: «Любая работающая сложная система является результатом развития работавшей более простой системы... Сложная система, спроектированная "с нуля", никогда не заработает. Следует начинать с работающей простой системы».

Процесс роста

Совсем недавно встретил через Стратоплан картинку роста в любой области (источник — недра психологии потока):

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

На графике по вертикали сложность постановки задачи, они же требования к её исполнению (масштабность проекта, процент отказов, производительность системы, … — все это может быть большим уровнем по требованиям). По горизонтали наши умения (+ знания и навыки). Т.е. способность что-либо делать.

В самом начале мало чего умеем. И лучше, если не предъявляем к себе каких-либо сверх-требований. Тогда это нижний левый угол.

Делая что-то, мы учимся это делать лучше. Если делать это долго, то мы научимся это самое делать, но нам становится скучно. A1→A2. Если мы предъявляем к себе более высокие требования, то появляется чувство тревоги — получится ли? сложно! много всего.. и все такое. A1→A3.

В состояниях A2 и A3 зоны дискомфорта — человек может бросить этим заниматься, а может получить большой стимул к развитию.

Оптимальное развитие — как по красной линии, можно немного иногда заходить в сторону тревоги. Если делаем переход вида A1→A4, то растем и можем осуществить большее.

Следствия:

  • Сначала мы все ничего не умеем. Если мы предъявляем к себе большие требования, то станет страшно, ничего не будет получаться и все будет заброшено. Поэтому начинать надо с простых вещей.
  • Если долго делать одни и те же простые вещи, то станет скучно и уныло. Что делать? Повышать требования.
  • Что делать чтобы быстро расти вверх? Идти согласно коридору потока. Если проект большой и масштабный, то идти придется долго, зачастую окольными путями.

Под другим ракурсом

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

Слишком сложная цель

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

Здесь вижу два больших разных пути решения: «составление программы» и «работа в стол». Первый вариант предпочтителен — есть ресурсы, понятно приблизительно что делать, вехи отмечены. Второй вариант — за неимением первого, когда цель недостижима, не хватает ресурсов, практическая область не понятна.

Работа в стол: переход на самообразование в случае плохого образования; постепенная выработка мастерства; методический и системный сбор информации.

Составление программы: серия последовательных целей; законченные проекты, решающие часть задачи; проекты, релевантные конечной цели; моральная готовность к длительной работе.

Отсутствие цели

Проект выполнен, а дальнейших целей нет.

Активный поиск качественно более широкой и дальней цели и отсутствие ожидания. Без этого — останов процесса роста и потеря поступательного развития.

Отсутвие возможности работы над следующим этапом (не важно по каким причинам) — способствует потере команды и задела.

Цель забирают

По разным причинам — недопущение до информации, высмеивание, потеря контроля, куча соавторов.

Здесь в данном контексте важен фокус следующей цели. Это переход в другую область или расширение, популяризация, поиск независмимой цели (вплоть до работы в одиночку).


* — данная мысль только в программной инженерии лет на 20 старше; у Брукса в статье о серебрьяной пуле есть ссылка на научную публикацию 1971 года и цитата коллеги 1958-го года.


воскресенье, 4 августа 2013 г.

Fatal Defect & Computer Related Risks

Читаю сейчас книги Fatal Defect и Computer Related Risks. Сначала планировал по отдельности, но придется читать вместе.

Эти книги рассказывают о том, как далеки от совершенства любые компьютеры и о том, к каким последствиям могут приводить различные программные и аппаратные ошибки. Компьютеры глубже проникают в нашу жизнь — они находятся в микроволновках и пылесосах, в автомобилях и самолетах, управляют биржами и опасным химическим производством, роботами и военными системами, выполняя при этом ключевые функции — и постепенно последствия дефектов становятся все более ощутимыми, разрушения более стремительными и масштабными. Цена ошибки возрастает и этому вопросу требуется уделять больше внимания.

Книги написаны в одно время и на одну тему, и, более того, основаны на очень похожем материале. Однако внутри имеют разные приближения к одной и той же проблематике. Computer Related Risks — весьма научная, где изложено все по полочкам и темам, по большей части сухая статистическая информация и тематический и факторный анализ. Fatal Defect — напротив, это книга для рядового читателя, где рассказывается множество различных случаев и историй, а сама книга читается как детектив и является хорошим кандидатом на то, чтобы вдохновить людей в или на данную область (Safety-Critical Systems).

Источники для книг основаны в первую очередь на Computer Risks Forum — это онлайновый ресурс, действующий с 1985 года. Его назначение — оповещение и обсуждение любых проблем, связанных с компьютерными рисками, но в первую очередь фокус ставится на больших системах автоматизации процессов, на системах, проблемы в которых могут приводить к большим экономическим потерям и угрожать здоровью и жизни людей. C самого начала существования форума его модератором является активист Peter G. Neumann (Harvard ph.D., длительное время работал в Bell Labs и ACM), занимающийся им в свое свободное время, — он же автор второй книги на моей картинке.

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

Форум представляет собой место, где информация о дефектах в аппаратно-программных комплексах собирается с различных источников, высказывается и обсуждается. Кроме того, любой может анонимно прислать что-либо, и это станет предметом обсуждения и достоянием общественности. Компьютерные системы нельзя полностью лишить дефектов, но с помощью обратной связи можно улучшить и ускорить процесс учета ошибок прошлого и делать новые системы лучше.

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


вторник, 18 июня 2013 г.

The Art of Readable Code

Когда-то у Александра Дëминa была замечена данная книга попала в мой пул на прочтение, приехала уже не помню с какого магазина и сейчас процесс завершился. С review Александра полностью согласен, здесь некоторые добавления.

С точки зрения английского книга легко читается. Большое количество примеров (и меньше соответственно текста), плюс простой язык и малое количество редких слов. Это наверно первая книга более сотни страниц, в которой я перестал замечать, что она на написана на другом языке.

Авторы по-видимому, сами используют множество языков C++/Python/Javascript как основное и внутри на этом разнообразии строятся все примеры и обобщения. Кроме того, чувствуется уровень отношения к коду, который как к Web-разработке.

В книге принята попытка некоторой классификации того набора отверток, который предлагается к рассмотрению, и, на мой взгляд, сделано удачно. Есть общая постановка задачи (The Fundamental Theorem of Readability), есть разбиение области на крупные цели и каждое правило/совет выполняют свою малую задачу и дополняют более общую.

Больше половины содержания оказалось знакомой, но с ощущением, что лучше бы это увидеть на лет 10 раньше. Ещё где-то четверть была знакомой, но знакомой интуитивно, а взгляд авторов вывел вопросы на более сознательный уровень: например дефрагментацию кода по задачам для разбиения функций делал интуитивно и зачастую brute-force'ом, но явное её осознание помогает сделать это более целенаправленно и по конкретным шагам.