Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Комплексный программный продукт



ОГЛАВЛЕНИЕ

THE MYTHICAL MAN-MONTH (Essays on Software Engineering).............................................................. 1

I. АСФАЛЬТОВАЯ ТОПЬ............................................................................................................................................................. 4

Комплексный программный продукт................................................................................................................................... 4

Радости ремесла........................................................................................................................................................................ 4

Горести ремесла......................................................................................................................................................................... 4

II. МИФИЧЕСКИЙ ЧЕЛОВЕКО-МЕСЯЦ................................................................................................................................. 6

Оптимизм..................................................................................................................................................................................... 6

Человеко-месяц........................................................................................................................................................................... 7

Комплексная отладка............................................................................................................................................................... 8

Объективность оценки............................................................................................................................................................. 8

Нарастающие катастрофы с графиком............................................................................................................................ 9

III. ХИРУРГИЧЕСКАЯ БРИГАДА........................................................................................................................................... 11

Предложение Миллза.............................................................................................................................................................. 12

IV. АРИСТОКРАТИЯ, ДЕМОКРАТИЯ И СИСТЕМНОЕ ПРОЕКТИРОВАНИЕ.......................................................... 15

Концептуальное единство.................................................................................................................................................... 15

Как добиться концептуального единства........................................................................................................................ 15

Аристократия и демократия............................................................................................................................................... 16

Чем может заполнить разработчик период ожидания?............................................................................................ 17

V. ЭФФЕКТ ВТОРОЙ СИСТЕМЫ............................................................................................................................................ 19

Принципы совместной работы........................................................................................................................................... 19

Самодисциплина. Эффект второй системы................................................................................................................... 19

VI. ПУТЬ СЛОВА.......................................................................................................................................................................... 21

Письменные спецификации — руководство..................................................................................................................... 21

Формальные описания............................................................................................................................................................ 21

Прямое внесение....................................................................................................................................................................... 22

Конференции и разбирательства....................................................................................................................................... 23

Совместные реализации........................................................................................................................................................ 23

Журнал регистрации телефонных звонков....................................................................................................................... 24

Проверка конечного продукта............................................................................................................................................. 24

VII. ПОЧЕМУ ОБРУШИЛАСЬ ВАВИЛОНСКАЯ БАШНЯ.............................................................................................. 25

Анализ Вавилонского проекта с точки зрения административного управления.................................................. 25

Связь в больших программистских проектах................................................................................................................. 25

Рабочий документ проекта.................................................................................................................................................. 26

Организация в больших программистских проектах.................................................................................................... 27

VIII. ОБЪЯВЛЕНИЕ ЦЕЛИ........................................................................................................................................................ 30

Данные Портмана.................................................................................................................................................................... 30

Данные Арона............................................................................................................................................................................ 31

Данные Харра............................................................................................................................................................................ 31

Данные по OS/360..................................................................................................................................................................... 32

Данные Корбато...................................................................................................................................................................... 32

IX. ДЕСЯТЬ ФУНТОВ В ПЯТИФУНТОВОМ МЕШКЕ.................................................................................................... 34

Размер программы как стоимость..................................................................................................................................... 34

Контроль за размерами программ...................................................................................................................................... 34

Методы экономии памяти.................................................................................................................................................... 35

Представление данных — сущность программирования............................................................................................. 35

X. ДОКУМЕНТАЦИОННАЯ ГИПОТЕЗА.............................................................................................................................. 37

Документы для разработки ЭВМ........................................................................................................................................ 37

Документы для факультета университета..................................................................................................................... 37

Документы для проекта программного обеспечения.................................................................................................... 38

Зачем нужны формальные документы?............................................................................................................................. 38

XI. ПЛАН НА ВЫБРОС............................................................................................................................................................... 40

Опытные установки и увеличение масштабов............................................................................................................... 40

Постоянны только изменения............................................................................................................................................... 40

Планирование изменений в системе.................................................................................................................................... 40

Планирование изменений в организации............................................................................................................................ 41

Два шага вперед, шаг назад.................................................................................................................................................. 42

Шаг вперед и шаг назад......................................................................................................................................................... 43

XII. ОСТРЫЙ ИНСТРУМЕНТ................................................................................................................................................... 44

Целевые машины...................................................................................................................................................................... 44

Инструментальные машины и служба данных............................................................................................................... 45

Язык высокого уровня и диалоговое программирование.............................................................................................. 46

XIII. ЦЕЛОЕ ИЗ ЧАСТЕЙ........................................................................................................................................................... 49

Проект без ошибок.................................................................................................................................................................. 49

Автономная отладка.............................................................................................................................................................. 50

Системная отладка................................................................................................................................................................ 51

XIV. ПРИБЛИЖЕНИЕ КАТАСТРОФЫ................................................................................................................................... 55

Вехи или помехи?..................................................................................................................................................................... 55

Сор в избе................................................................................................................................................................................... 56

XV. ВТОРОЕ ЛИЦО...................................................................................................................................................................... 60

Какая документация нужна?............................................................................................................................................... 60

Несостоятельность блок-схем............................................................................................................................................ 61

Самодокументированные программы............................................................................................................................... 63

ЭПИЛОГ.......................................................................................................................................................................................... 67

ПРИМЕЧАНИЯ И ССЫЛКИ...................................................................................................................................................... 68

 



I. АСФАЛЬТОВАЯ ТОПЬ

«Корабль на мели — моряку маяк».
(Датская пословица)

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

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

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

Начнем поэтому с определения ремесла системного программирования и присущих ему радостей и горестей.


Радости ремесла

Почему программирование доставляет удовольствие? Как вознаграждаются все усилия профессионала?

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

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

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

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

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

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

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

Горести ремесла

Не все, однако, радует программиста, и знакомство с горестями, присущими нашему ремеслу, позволяет легче перенести их появление.

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

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

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

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

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

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

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

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

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



Оптимизм

Все программисты — оптимисты. Может быть, это современное чародейство особенно привлекает тех, кто верит в добрых фей и счастливый конец. Может быть, cтократное крушение надежд способен пережить только тот, кто привык добиваться поставленной цели. Или, может быть, все дело в том, что вычислительные машины молоды, а юность всегда оптимистична. Однако как ни объясняй, но слышим мы одно и то же:

«К этому сроку программа обязательно пройдет», или «Я только что нашел последнюю ошибку».

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

Широкое распространение оптимизма среди программистов заслуживает более глубокого анализа. До-роти Сейерс в своей прекрасной книге «Мысль творца» («The Mind of the Maker») подразделяет творческую деятельность на три этапа: идея, реализация и взаимодействие. Книга, вычислительная машина, или программа сначала существуют как идея, вне времени и пространства, только в мозгу своего создателя, но в совершенно законченном виде. Замысел реализуется во времени и пространстве посредством пера, чернил и бумаги или же с помощью проводов, полупроводниковых схем н феррптовых сердечников. Процесс создания завершается, когда кто-то другой читает книгу, использует вычислительную машину, пропуская через нее программу, тем самым взаимодействуя с замыслом творца.

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

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

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

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

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

Человеко-месяц

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

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

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

Рис. 2.1. Время и число работников — Рис. 2.2. Время и число работников —
 нераспределяемое задание                 полностью распределяемое задание

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

Рис. 2.3. Время и число работников — Рис. 2.4. Время и число работников —
задача со сложными взаимосвязями.            распределяемое задание,
                                                                      требующее связей между частями.

Дополнительные затраты на обеспечение связи слагаются из двух частей — обучения и взаимосвязи. Каждый работник должен получить определенные технические навыки, познакомиться с целями и задачами, общей стратегией и планом работы. Такое обучение нельзя разбить на отдельные части, так что эта часть дополнительных затрат изменяется линейно в зависимости от числа работников1).

С установлением взаимосвязи дело обстоит хуже. Если каждая часть задачи должна отдельно координироваться с каждой другой частью, затраты возрастают как п(п—1)/2. Между тремя работниками в три раза больше попарных взаимосвязей, чем между двумя;

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

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




Комплексная отладка

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

В течение нескольких лет я успешно применял следующее практическое правило планирования работ по созданию программного обеспечения:

Ø проектирование — 1/3,

Ø написание команд —1/6,

Ø отладка компонент и отдельных подсистем — 1/4,

Ø системная (комплексная) отладка всех компонент — 1/4.

Это разбиение отличается от общепринятого по нескольким важным показателям:

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

2) половина времени отводится на отладку написанной программы, что гораздо более обычного;

3) часть, которую легко оценить, т. е. собственно написание команд, занимает только одну шестую графика.

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

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

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

Объективность оценки

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

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

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

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

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

III. ХИРУРГИЧЕСКАЯ БРИГАДА

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

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

Однако эта наивная формулировка альтернативы уводит от ответа на тяжелый вопрос — как построить большую систему в разумный срок? Рассмотрим каждую сторону этого вопроса более подробно.


В чем проблема?

Руководители программистских проектов давно уже поняли, как значительны различия в производительности хороших и плохих программистов. Тем не менее результаты точных измерений этой величины просто поражают. В одной из своих работ Сакмен, Эриксон и Грант измеряли производительность группы опытных программистов. Даже внутри этой группы отношение максимальной и минимальной производительности в среднем составило 10:1, а для времени работы программы и затрат памяти — 5:1. Короче говоря, производительность труда программиста, получающего 20 тыс. долларов в год, может быть в 10 раз больше, чем у того, кто зарабатывает 10 тыс. долларов. Обратное также может быть справедливо. Статистические данные утверждают, что нет никакой зависимости между опытом и производительностью. (Сомневаюсь, впрочем, чтобы это было верно всегда.)

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

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

OS/360, Exes-8, Scope-6600, Multics, TSS, SAGE — этот список можно существенно расширить.

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

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

С другой стороны, первоначальная группа в 200 человек не настолько велика, чтобы можно было сделать действительно большую систему методом грубой силы. Рассмотрим, например, операционную систему OS/360. В пиковые периоды над ней работало около 1000 человек — программисты, составители технической документации, операторы, лаборанты, секретари, руководители, вспомогательные службы и т. д. За период с 1963 по 1966 гг. около 5000 человеко-лет понадобилось на проектирование, реализацию этой системы и создание документации на нее. Нашей группе из 200 человек понадобилось бы 25 лет, чтобы довести систему до ее нынешнего состояния, да и то при условии, что люди и месяцы действительно взаимозаменяемы.

Вот тут-то и обнаруживается слабая сторона концепции маленькой энергичной группы: это слишком медленно для действительно больших систем. Посмотрим, что получилось бы, если бы создание операционной системы OS/360 поручили такой группе. Допустим, в ней 10 человек. Пусть благодаря энергии и опыту их производительность в программировании и создании документации в 7 раз выше, чем у средних программистов. Допустим, что OS/360 создавалась только средними программистами (но это, впрочем, очень далеко от истины). И допустим, наконец, что еще один коэффициент повышения производительности, равный 7, появился из-за уменьшения затрат на обеспечение взаимосвязи в меньшем коллективе. Допустим, также, что состав группы не менялся все это время. Тогда 5000/(10><7Х7) ==10; они сделают работу объемом 5000 человеко-лет за 10 лет. Будет ли эта система интересна через 10 лет? Или же она безнадежно устареет в результате быстрого развития идей и методов программного обеспечения ЭВМ?

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

Предложение Миллза

Харлан Миллз выдвинул оригинальное и творческое решение этой проблемы2'3). Он предлагает, чтобы над каждой частью большой задачи работала отдельная группа, и считает, что группа должна быть организована по принципу хирургической бригады, где операцию делает один, а остальные ему ассистируют.

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

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

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

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

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

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

Два секретаря. И администратору, и редактору нужны свои секретари; секретарь администратора будет вести корреспонденцию проекта и архивы.

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

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

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

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

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

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

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

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

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

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

Рис. 3.1. Структура связей в коллективе программистов из 10 человек.

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

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

«Экскалация». Пока все хорошо. Проблема, однако, заключается в том, что же делать с проектами, создание которых требует не 20 или 30, а 5000 человеко-лет. Группа из 10 сотрудников может работать эффективно и независимо от того, как она организована, если только вся задача находится в сфере ее действия. Но как использовать концепцию хирургической бригады применительно к большой задаче, в решении которой принимают участие несколько сот человек?

Залог успеха «эскалации» заключается в том, что нами уже обеспечена высокая степень концептуального единства на уровне частей — в каждой из них число умов, определяющих проект, сократилось в семь раз. Тогда можно отдать всю работу 200 сотрудникам, но проблемы координации поручить 20 хирургам.

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



Концептуальное единство

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

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

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

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

В этой и двух последующих главах мы рассмотрим именно эту сторону создания систем программирования и попытаемся ответить на вопросы:

Ø Как добиться концептуального единства проекта?

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

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

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

Аристократия и демократия

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

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

Отделение архитектурных проблем от реализации является весьма эффективным путем достижения концептуального единства очень больших проектов. Я убедился в этом на примере успешного создания фирмой IBM вычислительной машины Stretch и промышленной серии ЭВМ Системы 360.

Отсутствие такого подхода сказалось при разработке операционной системы OS/360.

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

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

Необходимо тщательно отделять архитектуру от реализации. Как сказал Блау, «Там, где архитектура говорит, что происходит, разработка говорит, как это должно происходить»3). В качестве простого примера он приводит часы, архитектура которых — циферблат, стрелки и головка завода. Когда ребенок познакомится с этой архитектурой, он с одинаковой легкостью сможет определять время как по ручным часам, так и по башенным курантам. Разработка и реализация, однако, каждый раз описывают внутреннюю структуру — механизмы, приводящие часы в действие и обеспечивающие точность хода.

В Системе 360, например, одна машинная архитектура реализована совершенно по-разному в каждой из девяти моделей, и наоборот, одна реализация, средства обмена, память и микропрограммы модели 360/30 используются в четырех различных архитектурах: серия ЭВМ Системы 360, мультиплексный канал с 224 логическими независимыми подканалами, селекторный канал и вычислительная машина IBM-14014).

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

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

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

Что касается вопроса о появлении новой аристократии, то следует ответить и да, и нет.

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

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

Существует множество примеров из других областей искусства и ремесла, заставляющих поверить в то, что дисциплина полезна. Как утверждает афоризм, распространенный среди художников, «форма освобождает». Хуже всего получаются сооружения, бюджет которых -больше, чем это нужно для достижения поставленной цели. Вряд ли необходимость каждую неделю писать по кантате отрицательно сказывалась на творческих возможностях Баха. Я уверен, что архитектура вычислительной машины Stretch много выиграла бы от введения более строгих ограничений; так, ограничения, накладываемые бюджетом модели 30 Системы 360, по моему мнению, положительно сказались на архитектуре модели 75. Аналогично я подметил, что заданная архитектура повышает, а не подавляет творческие возможности группы разработчиков. Они сразу же сосредоточиваются на той части проблемы, которой еще не занимались, и в результате появляются творческие находки. Если же на работу группы не накладывается никаких ограничений, то много времени и усилий, размышлений и обсуждений уйдет на архитектурные решения, а с самой реализацией они справятся очень быстро5).

Существование этого эффекта, который я наблюдал неоднократно, подтверждает Р. Конвей — руководитель группы, создавшей транслятор PL/G с языка PL/I в Корнелльском университете. Он говорит: «В конце концов, мы решили реализовать язык без всяких изменений и улучшений, потому что дебаты по этому вопросу отняли бы у нас все силы»6).

V. ЭФФЕКТ ВТОРОЙ СИСТЕМЫ

Если ответственность за функциональные спецификации отделить от ответственности за быстрое создание дешевого конечного продукта, то как поставить пределы творческому энтузиазму архитектора?

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

Принципы совместной работы

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

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

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

Ø помнить, что строитель несет творческую ответственность за реализацию, поэтому архитектор предлагает, но не приказывает;

Ø быть готовым к тому, чтобы предложить свой способ реализации продукта, спецификацию которого он написал, \i к тому, чтобы принять любой другой способ, если последний отвечает поставленным задачам;

Ø выдвигать такие предложения спокойно, в узком кругу;

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

VI. ПУТЬ СЛОВА

 «Он сядет здесь и будет распоряжатъся: Сделайте то! Сделайте это!—- Но абсолютно ничто не сдвинется с места».

(Г. С. Т р у м е н. «О президентской власти»)

Допустим, что в распоряжении руководителя есть несколько дисциплинированных и опытных архитекторов и большой коллектив разработчиков. Как руководитель сможет добиться того, чтобы все разработчики услышали, поняли и реализовали решения, предложенные архитекторами? Каким образом группа из 10 архитекторов сможет обеспечить концептуальное единство системы, которую создают 1000 человек? Целая технология, позволяющая это осуществить, была разработана для проекта Системы 360, и она равно приложима к проектам создания программного обеспечения.

Формальные описания

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

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

Старая пословица предупреждает: «Никогда не выходи в море с двумя хронометрами: бери один или три». Ее вполне можно отнести и к проблеме текстовых и формальных описаний. Если у вас есть и то, и другое, то одно должно быть стандартом, а второе — производным описанием, что следует указать ясно. В качестве исходного стандарта можно выбрать любое из них. Алгол-68 имеет в качестве стандарта формальное описание и, кроме того, поясняющее текстовое описание. Стандартное описание PL/I дано текстом, а формальное описание — как производное. Система 360 также имеет текстовое описание в качестве стандарта и рядом — производное формальное описание.

Существует множество способов представления формальных описаний. Бэкусова — Наурова форма (БНФ), разработанная для описания языков, широко освещена в литературе2). Формальное описание PL/I использует новую систему обозначении абстрактного синтаксиса, и она адекватно описана3). Язык APL, разработанный Айверсоном, применялся для описания машин, в частности, IBM-70904) и Системы 3605).

Белл и Ныоэлл предложили новую систему для описания конфигураций и архитектуры машин и проиллюстрировали ее на примере нескольких машин, включая PDP-8 фирмы DEC6), IBM-70906) и Системы 3607).

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

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

Программы-имитаторы аппаратуры или математического обеспечения могут использоваться точно таким же образом. Это реализация; она работает. Поэтому все вопросы описания можно разрешить путем ее проверки.

Использование реализации в качестве описания имеет некоторые преимущества. Все вопросы разрешаются однозначно посредством эксперимента. Дискуссии не нужны, потому что ответы получаются быстро. Ответы всегда точны в той степени, которая нужна, ц они по определению верны. Но, кроме преимуществ, такой подход имеет и очень много недостатков. Реализация может вызвать переопределение даже внешних спецификаций. Ошибка в синтаксисе в реализации приводит к любому результату; в «чистой» системе этот результат является лишь указанием на некорректность и ничем больше. В «неряшливой» системе могут появиться самые разнообразные побочные эффекты, которые могут быть использованы программистами. Когда мы предприняли эмуляцию ЭВМ IBM-1401 на Системе 360, то обнаружилось около 30 различных «курьезов», или побочных эффектов, вызываемых, предположительно, ошибочными операциями, которые, однако, стали широко использоваться и должны теперь рассматриваться как часть описания. Реализация, выступающая в качестве описания, предлагает избыточные определения; она говорит не только о том, что машина должна делать, но, в значительной степени, и о том, как она это должна делать.

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

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

текстовое описание или формальное. Это особенно справедливо в отношении программных имитаторов;

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

Прямое внесение

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

Совместные реализации

Архитекторы Системы 360 имели два почти беспрецедентных преимущества: достаточное время для тщательной и неторопливой работы и политическое равенство с разработчиками. Разумные сроки были обусловлены графиком выпуска новой техники; политическое равенство вытекало из факта одновременного ведения нескольких разработок. Необходимость их строгой совместимости служила наилучшей движущей силой проектирования.

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

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

Проверка конечного продукта

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

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



Рабочий документ проекта

Что. Рабочий документ проекта — это не столько отдельный документ, сколько структура, накладываемая на документы, выпускаемые проектом.

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

Зачем. Техническая проза почти бессмертна. Рассматривая генеалогию технического руководства по какой-то части оборудования или математического обеспечения, можно проследить, что не только идеи, но одни и те же предложения и даже абзацы сохраняются с самого первого меморандума, предлагающего продукт или поясняющего начальный проект. Ножницы и клей нужны создателю технического документа не менее, чем авторучка.

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

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

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

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

Я думаю, что в проекте OS/360 это вполне удалось. На необходимости хорошо структурированных рабочих документов особенно настаивал О. С. Локен, который убедился в их эффективности на примере своего предыдущего проекта, операционной системы IBM 1410— 7010.

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

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

Однако человек, получивший все эти новые варианты страниц, оказывался перед проблемой сравнения. Когда ему впервые попадает страница с изменениями, он хочет знать: «Что изменилось?». Когда же он позже обращается к ней, ему нужно знать: «А как это определяется сегодня?».

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

Нашему проекту не исполнилось еще и полугода, как мы столкнулись с другой проблемой. Рабочие документы уже стали около 1,5 м толщиной! Если бы сложить друг на друга все 100 экземпляров, которыми пользовались наши программисты в своем здании на Манхэттене, то получилась бы башня выше самого дома. И далее, ежедневно распространялись изменения толщиной в 5 см, т. е. приблизительно 150 страниц вновь подшивалось в документ. В.едение рабочих документов стало занимать значительную часть каждого дня.

В этот момент мы переключились на микрофиши, что сэкономило нам миллион долларов, учитывая даже стоимость проекторов для чтения с микрофиш. Мы смогли прекрасно организовать производство микрофиш, объем рабочих документов сократился с 1,7 м3 до 0,004 м3 и, что важнее всего, изменения сразу вносились в куски по 100 страниц, тем самым в 100 раз облегчилась проблема организации документов.

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

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

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

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

Отметим, что сам рабочий документ при этом не изменяется. Он остается объединением всей документации по проекту и имеет тщательно разработанную структуру. Изменения претерпевают только механизм его распространения и работа с ним. Д. Энгельбарт вместе со своими коллегами из Стэнфордского исследовательского института создали такую систему и использовали ее при разработке и ведении документации по проекту создания сети ARPA.

Д. Парнас из Университета Карнеги — Меллона предложил еще более радикальное решение'). Он выдвинул тезис о том, что программист работает наиболее эффективно, если он не вдается в детали организации других частей системы. Это подразумевает полное и исчерпывающее определение всех сопряжении. Несмотря на то, что это звучит весьма разумно, реализация такой идеи может оказаться затруднительной. Однако хорошо организованная система информации не только выявляет ошибки в сопряжениях, но и стимулирует их исправление.

VIII. ОБЪЯВЛЕНИЕ ЦЕЛИ

«Практика — лучший учитель».
(Публилиус)

«Опыт — хороший учитель, но и он ничему не научит дурака».
(Альманах «Бедный Ричард»)

Сколько времени занимает решение задачи системного программирования? Сколько усилий потребуется? И как все это оценивать?

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

!' Во-вторых, необходимо отметить, что данные, относящиеся к созданию отдельных маленьких программ, не приложимы к комплексному программному продукту. Так, например, Сакмен, Эриксон и Грант приводят среднее время на написание и отладку программы объемом около 3200 слов — 178 часов для одного программиста, что дает производительность в 35 800 команд в год. В два раза меньшая программа требует в четыре раза меньше времени, так что средняя производительность получается равной почти 80 000 команд в год '). Сюда следует, однако, прибавить затраты времени на проектирование, документирование, отладку, объединение в систему, обучение и всякие перерывы. Экстраполяция таких малых цифр не имеет смысла. Так, если экстраполировать время, показываемое бегуном на дистанции в 100 ярдов, то получится, что человек может пробежать милю быстрее, чем за 3 минуты.

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

На рис. 8.1 показаны начальные результаты исследования, проведенного Нанусом и Фарром2) в фирме System Development. Здесь появляется показатель степени 1,5, т. е., затраты == (константа) X, X (число команд)''5.

В других исследованиях, проведенных этой же фирмой и опубликованных Вайн-вурмом3), также приводится показатель степени, близкий к 1,5.

Производительность программистов неоднократно бы- р„, g.l. Программировала предметом изучения, пред- ние как функция разме-лагались различные методы ров программы. ее оценки. Моурин подготовил обзор публикаций4) по этой тематике. Здесь я коснусь только некоторых фактов, представляющих особый интерес.



Данные Портмана

Чарльз Портман, руководитель Северного отделения системного программирования фирмы ICL в Манчестере, высказал другую интересную точку зрения.

Он обнаружил, что его коллективы программистов не укладывались в график почти наполовину — каждая задача занимала в два раза больше времени, чем ей отводилось по плану, несмотря на то, что оценки были очень тщательны (их делали опытные люди, которые определили затраты в человеко-часах для нескольких сотен подзадач с помощью схем PERT). Когда выявилось отставание от графика, Портман попросил своих сотрудников вести подробные ежедневные записи расхода времени. Эти записи показали, что ошибочная оценка полностью объясняется тем фактом, что коллективы тратили только 50% рабочего времени собственно на программирование и отладку. Остальное врем"я уходило на побочные, но срочные дела, совещания, За работу с бумагами, общественные дела, болезни, личные нужды, а также терялось из-за простоев машины. Короче говоря, при составлении графика было сделано нереальное предположение о том, какая часть времени затрачивается непосредственно на работу. Мой собственный опыт полностью подтверждает это заключение.

Данные Арона

Джоель Арон, руководитель отдела системной технологии фирмы IBM в Гейтесбурге (штат Мэриленд), изучал производительность программистов, принимавших участие в разработке девяти больших систем (большой считалась система объемом более 30 тыс. команд, в создании которой участвовало более 25 программистов)7). Он классифицировал системы по числу сопряжении между программистами (и тем самым, по числу отдельных частей системы) и получил следующие значения производительности одного программиста:

Очень мало сопряжения                10000 команд в год

Среднее число сопряжения          5000 » »

Много сопряжении                          1500 » »

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

Данные Харра

Джон Харр, руководитель работ по программированию системы электронной коммутации фирмы Bell Telephone Laboratories обобщил свой опыт в докладе^ представленном в 1969 г. на осенней объединенной конференции по вычислительной технике8). Эти данные приведены в табл. 8.1 и на рис. 8.2 и 8.3.

Таблица 8.1

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

Производительность разбивается на две категории:

для управляющих программ она составляет около 600 команд на человеко-год,

а для трансляторов — около 2200 команд на человеко-год.

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

Рис. 8.2. Предсказываемая и реальная скорости программирования системы электронной коммутации.

Рис. 8.3. Предсказываемая и реальная скорости отладки системы электронной коммутации.

На рис. 8.2 и 8.3 приводятся некоторые интересные данные о скорости программирования и отладки по сравнению с предсказаниями.

Данные по OS/360

Опыт разработки OS/360, не учитывавший данных Харра, тем не менее подтверждает их. Производительность групп, занимавшихся управляющими программами, составила 600 — 800 отлаженных команд на человеко-год. Производительности в 2000 — 3000 отлаженных команд на человеко-год достигли группы, разрабатывавшие языковые трансляторы. Сюда входит проектирование на уровне групп, написание программ отладка компонент, комплексная отладка и некоторые вспомогательные операции. Насколько я могу судить, ати данные вполне сопоставимы с данными Харра.

Данные Арона, Харра и OS/360 подтверждают существенные различия в производительности программистов в зависимости от сложности и трудности самой задачи. Чтобы не увязнуть в трясине определения этой сложности, я предлагаю придерживаться следующего правила: трансляторы в три раза сложнее обычных прикладных программ, а операционные системы в три раза сложнее трансляторов9).

Данные Корбато

Данные Харра и фирмы IBM относятся к программированию на языке ассемблера. Данные о производительности программирования на языках высокого уровня, кажется, еще не публиковались. Корбато из проекта MAC Массачусетского технологического института сообщает среднюю производительность в 1200 отлаженных операторов на PL/I для системы Multics (объемом один, два миллиона команд)10). :

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

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

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

Ø производительность программирования можно увеличить по крайней мере в пять раз путем использования подходящего языка высокого уровня12).



Методы экономии памяти

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

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

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

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

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

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

График работ.

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

Схема организации.

Размещение рабочих мест.

Предсказание, оценка, цены. Они находятся в циклической взаимосвязи, которая определяет успех или неудачу проекта (рис. 10.1). Чтобы сделать предсказание относп-1ельно рынка, необходимы спецификации производительности и установленные цены. Для того чтобы установить оценку производ ственных затрат, предсказания объединяются с расчетом компонент проекта и определяют долю труда па создание каждой единицы, а также фиксированные затраты. Эти затраты, в свою очередь, определяют цены.

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

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

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

Документы для факультета университета

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

Цели работы.

Программы курсов.

Квалификационные требования.

Предложения по НИР, переходящие в планы при получении фондов.

Бюджет.

Рабочие места.

Когда: график работ.

Сколько: бюджет.

Где: рабочие места.

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

XI. ПЛАН НА ВЫБРОС

«В атом мире нет ничего постояннее непостоянства».
(Свифт)

«Общепринято выбрать метод, а затем опробовать его. Если он неудачен, оставьте его и испробуйте другой. Но как бы то ни было, не оставляйте попыток».
(Ф. Д, Рузвельт)



Постоянны только изменения

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

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

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

Тем нс менее, некоторые изменения в целях и задачах неизбежны, и лучше быть готовым к ним, чем считать, что их не будет. Неизбежны изменения не только в целях, но н в стратегии и методах разработки. Концепция «работы в корзину» сама по себе является принятием того факта, что, научившись чему-то, мы вносим в проект изменения4).

Планирование изменений в системе

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

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

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

Планирование изменений в организации

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

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

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

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

Барьеры носят социологический характер, и при их преодолении следует постоянно проявлять бдительность. Во-первых, сами руководители зачастую считают ведущих специалистов «слишком ценными» для того, чтобы использовать их непосредственно в программировании. Во-вторых, работа .в области административного управления имеет более высокий престиж. Чтобы справиться с этой проблемой, на некоторых предприятиях, например в фирме Bell Labs, отказались от каких бы то ни было титулов и званий. Каждый профессинальный служащий является «штатным техническим сотрудником». Другие, например, фирма IBM, имеют двойную лестницу продвижения по службе (см. рис. 11.1). Ступени теоретически эквивалентны.

Рис. 11.1. Двойная лестница продвижения по службе в фирме IBM.

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

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

Все главные специалисты должны быть профессионально и эмоционально готовы как к руководству группой, так и к тому, чтобы собственными руками написать программу. Это не так-то просто, но дело того стоит.

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

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

Два шага вперед, шаг назад

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

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

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

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

Бетти Кэмпбелл из Лаборатории ядерной физики Массачусетского Технологического Института заметила интересный цикл жизни конкретного варианта программы. Он показан на рис. 11.2. Первоначально старые ошибки, обнаруженные в предыдущих вариантах и уже устраненные в них, проявляют тенденцию к появлению в новом варианте. Новые функции нового варианта порождают новые ошибки. Эти ошибки вылавливаются, и несколько месяцев все идет хорошо. Но потом число ошибок опять начинает расти. Мисс Кемпбелл находит объяснение этому факту в том, что пользователи выходят на более высокий уровень и начинают полностью использовать все возможности, заложенные в новом варианте. Ценой многих усилии из. этого варианта вылавливаются наиболее топкие ошибки 5).

Рпс. 11.2. Количество ошибок как функция времен;! жизни одного варианта программы.

Основная проблема сопровождения программ заключается в том, что исправление одного дефекта со значительной вероятностью (20—50%) влечет за собой появление другого. Поэтому, образно говоря, весь процесс напоминает два шага вперед и шаг назад.

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

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

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

Шаг вперед и шаг назад

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

И таким образом, на основе статистической механической модели Леман и Биледи пришли к выводу, подтверждаемому опытом всей жизни на земле, который также применим для систем программирования: «Вещи всегда лучше, когда они совсем еще новые»,— сказал Паскаль. Это же в более доходчивой форме сформулировал в своей книге7) С. Лыос.

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

XII. ОСТРЫЙ ИНСТРУМЕНТ

«Хорошего работника узнают по его инструментам».
(Пословица)

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

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

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

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

О каких же инструментах должен думать руководитель? Что планировать и организовывать? Прежде всего, это вычислительные средства: необходимы машины и определенная целенаправленность в распределении ресурсов. Нужны операционная система и установленный стиль обслуживания. Необходим язык и необходимо выработать языковую политику. Сюда же относятся вспомогательные средства, службы отладки, генераторы тестов и система обработки текстов для ведения документации. Давайте последовательно все это рассмотрим ').


Целевые машины

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

Каковы целевые машины? Группы, разрабатывающие новые супервизоры или другое математическое обеспечение, составляющее «сердце» системы, конечно, нуждается в своей собственной машине. В таких группах потребуются операторы и один-два системных программиста, отвечающих за состояние машины.

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

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

График работы. Когда вы имеете дело с новой целевой машиной, для которой создается первая операционная система, то машинного времени обычно не хватает, и его распределение становится главной про блемой. Потребность во времени для целевой машины растет по своеобразному закону. При разработке OS/360 у нас были хорошие имитаторы Системы 360 и другие средства. Из опыта предыдущей работы мы представляли, сколько машинного врем.ени нам понадобится, и потребовали от изготовителей, чтобы машины были поставлены нам заранее. По сначала они месяц за месяцем простаивали. И вдруг сразу все шестнадцать систем оказались загружены полностью и возникла проблема распределения времени. Примерный характер изменения времени использования машин показан па рис. 12.1. Все вышли на отладку своих первых блоков одновременно, а уж затем почти каждая бригада все время что-нибудь да отлаживала.

Рис. 12.1. Рост времени использования целевой машины.

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

Однако, от такой организации пришлось отказаться, После нескольких месяцев медленного оборота, взаимных обвинений и всеобщего недовольства мы решили распределить машинное время большими блоками. Вся группа сортировки, состоящая из 15 человек, получала, например, систему на 4—6 ч. Они сами распределяли это время между собой. Даже если машина простаивала, никто посторонний не мог ею пользоваться. ' Оказалось, что это наилучший способ распределения времени. Хотя машина использовалась несколько меньше (впрочем, не всегда), производительность возросла. Каждый член бригады может работать гораздо продуктивнее, если он получает десять выдач за шестичасовой период, чем те же десять выдач с трехчасовыми интервалами, потому что постоянная сосредоточенность почти не оставляет времени па обдумывание. После такого «рывка» бригада обычно день или два разбирает полученные результаты, а уж потом снова на шесть часов выходит на машину. Зачастую всего несколько программистов, может быть, даже только трое, распределяют между собой и плодотворно используют весь шестичасовой период. Этот способ использования целевой машины представляется наилучшим.

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

XIII. ЦЕЛОЕ ИЗ ЧАСТЕЙ

«Я духов вызывать могу уз бездны».
«И я могу и каждый это может. Вопрос лишь, явятся лъ они на зов».
(Ш е к с п и р, «Генрих IV» )

Среди современных магов не перевелись хвастуны:

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

Как создается работоспособная программа? Как отлаживается программа? И как объединяется множество отлаженных программ-компонентов в проверенную и надежную систему? Мы эпизодически касались этих методов; теперь настала пора рассмотреть их более систематично.



Проект без ошибок

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

Подобную же роль играет подробная и тщательная разработка архитектуры, присущая этому подходу. В. А. Выссотски руководитель проекта Safeguard в фирме Bell Telephone Laboratories, утверждает: «Гвоздь проблемы состоит в том, чтобы описать продукт. Многие и многие неудачи вызваны теми его аспектами, которые не были как следует специфицированы»'). Аккуратное описание функций, тщательная спецификация и последовательное изгнание всяческих украшательств как в функциях, так и в методиках позволяет сократить число системных ошибок, которые предстоит отыскать в дальнейшем.

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

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

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

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

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

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

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

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

Структурированное программирование. Другой важный подход к проблеме программирования без ошибок принадлежит Дейкстре3) и основывается на теоретических построениях Боема и Якопппи4).

Это метод написания программ, в которых структуры управления состоят только из циклов, определяемых оператором DO WHILE, и условных операторов, составленных из взятых в скобки групп операторов, которым предшествует условие IF... THEN... ELSE. Боем и Якопини показали теоретическую достаточность этих структур. Дейкстра убедил, что произвольное употребление перехода по оператору GO TO дает структуры, ведущие к логическим ошибкам.

Обоснованность основной идеи очевидна. Она широко обсуждалась и совершенствовалась; в частности, такие управляющие структуры, как га-значный переход (так называемый оператор CASE), и «аварийный прыжок с парашютом» (GO TO ABNORMAL END) оказались очень удобны. В то же время призыв некоторых рьяных приверженцев этого метода к отказу от всех операторов GO TO кажется чрезмерным.

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

Автономная отладка

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

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

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

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

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

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

Выборочная выдача. Машины, в которых при-менялась выдача памяти, имели сначала 2000—4000 слов, или от 8 до 16 тыс. байтов памяти. Но размеры памяти стремительно росли, и вскоре производить выдачу всей памяти стало непрактично. Поэтому появились методы для выборочной выдачи, для избирательной трассировки и для вставки в программу команд выдачи. Test ran в OS/360 может считаться последним словом в этом направлении; он позволяет вводить в программу команды выдачи без повторного ассемблирования пли рекомпиляции.

Диалоговая отладка. В 1959 г. Кодд со своими коллегами3) и Стрейчи6) независимо опубликовали работы, посвященные отладке в режиме разделения времени, методу, позволяющему сочетать преимущества быстрой оборачиваемости в случае машинной отладки и эффективного использования машины при отладке " в пакетном режиме.

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

Мультипрограммная система Кодда была создана, но основное внимание ее разработчики направили на увеличение производительности путем улучшения эффективности ввода/вывода, и диалоговая отладка в ней не была реализована. Идеи Стрейчи были усовершенствованы Корбато п его коллегами и реализованы в 1963 г. на экспериментальной системе для IBM 7090 в MIT7). Эта разработка непосредственно привела к проектам Multics, TSS и другим сегодняшним системам разделения времени.

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

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

Тем не менее, известны интересные экспериментальные данные Гоулда8), показывающие, что при диалоговой отладке наиболее успешным бывает первый диалог 'каждого сеанса. Это позволяет с уверенностью утверждать, что мы не реализуем всех потенциальных возможностей диалога именно из-за отсутствия плана отладки. Настало время вернуть к жизни старые методы машинной отладки.

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

Тесты. Что касается разработки реальных процедур отладки и тестов, то все это очень хорошо изложено в работе Груенбергера9), хотя есть и менее подробные изложения в некоторых других учебниках 10'11).

Системная отладка

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

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

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

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

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

Оснастка. Под «оснасткой» я понимаю все программы и данные, подготавливаемые для проведения отладки, но никогда не появляющиеся в конечном продукте. Нет ничего страшного, если объем таких программ примерно равен половине объема всей системы.

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

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

Предельным случаем мини-файла является фиктивный файл, которого в действительности вовсе нет. Язык управления задачами (ЯУЗА) в OS/360 обеспечивает такое средство, крайне полезное при отладке компонент.

Еще одна сторона оснастки — это вспомогательные программы. Генераторы тестовых данных, специальные анализирующие распечатки, анализаторы таблиц перекрестных ссылок — все это примеры той специальной «арматуры», которую вы можете подготавливать по своему желанию 13).

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

Прежде всего кто-то дол-кон быть ответственным. Этот кто-то, и только он один, должен давать разрешения на внесение изменении в компоненты или на замену одного варианта другим. Затем, как уже указывалось выше, следует иметь контрольные копии системы: одну неизменяемую копию последней версии, использованной для отладки компонент; одну проверяемую копию, в которую вносят исправления; для каждого программиста — копии, с которыми он может работать в своей части системы, исправляя ошибки или осуществляя расширения.

В инженерных моделях Системы 360 среди обычной желтой проволоки вдруг оказывались ярко-красные внткп. Дело в том, что когда обнаруживалась ошибка, инженеры делали две вещи. Быстро придумывался способ ое исправления, который и вносился в систему с тем, чтобы проверка могла продолжаться. Это исправление делалось красной проволокой и выделялось, как зияющая рана. Оно вносилось в журнал. Тем временем подготавливался официальный документ об изменениях и закладывался в мельницу автоматизации проектирования. Наконец, появлялись исправленные чертежи и монтажные схемы и новая панель с изменениями, реализованными в печатных схемах или желтой проволокой. Теперь физическая модель п ее описание опять соответствовали друг другу, и красная проволока убиралась.

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

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

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

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

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

Каждая бригада, разрабатывающая новый вариант своей компоненты, использует последнюю отлаженную версию объединенной системы как основание для отладки своего куска. Их работа усложнится, если это основание вдруг окажется шатким — начнет изменяться. Конечно, изменения необходимы, но их следует квантовать. Тогда в распоряжении каждого пользователя будут периоды продуктивной стабильности, прерываемые точками — внесением изменений в систему. Но. они гораздо менее разрушительны, чем постоянное встряхивание. Биледи и Леман н) утверждают очевидное: кванты должны быть очень большими и редкими во времени пли, напротив, очень маленькими и частыми. Последняя стратегия в соответствии с их моделью ближе к неустойчивости. Мой опыт подтверждает это:

я никогда не рискнул бы применить эту стратегию на практике.

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



XIV. ПРИБЛИЖЕНИЕ КАТАСТРОФЫ

«Никто не любит вестника, приносящего плохие новости».
(Софокл)

— Как выходит, что проект опаздывает на год?
— Постепенно.

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

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



Вехи или помехи?

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

Существует только одно разумное правило устанав-ления вех. Вехи должны быть конкретными, специфическими, датируемыми событиями, определенными строго и четко. Вот контрпримеры: уже по истечении половины всего времени, отведенного на программирование, видимо, можно утверждать, что оно «закончено на 90%»; почти с самого начала отладки кажется, что она «завершена на 99%»; «проектирование завершено* — это событие, о котором можно заявлять практически когда угодно').

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

Гораздо важнее, чтобы вехи были четкими и недвусмысленными, нежели удобными для проверки со стороны начальства. Вряд ли человек станет вводить в заблуждение других, если перед ним стоят четкие вехи и он сам не обманывается относительно их достижения. Если же вехи определены неясно и расплывчато, то руководитель, принимая желаемое за действительное, часто сам воспринимает совсем не то, что до1-;ладывает ему подчиненный. Дополняя Софокла, скажем, что п приносить плохие известия никто не любит; поэтому говорящий невольно смягчает их, не имея никакого желания солгать.

Два интересных исследования по оценке поведения исполнителей в больших проектах показали, что:

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

2. Во время работы переоценка ее длительности непрерывно уменьшается по мере продвижения к концу.

3. Недооценка не изменяется сколько-нибудь значительно во время работы за исключением последних трех недель перед завершением по графику 2).

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

«Другие все равно опаздывают» Мы на день отстали от графика, ну и что? Кто станет волноваться из-за одного дня? Мы сделаем это дозже. И многое другое мы тоже откладываем на потом.

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

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

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

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

В ходе выполнения проекта схема PERT разоблачает деморализующую отговорку: «Другие все равно опаздывают». Она показывает, как избежать критического пути и что делать, если задержка все-таки произошла.

Сор в избе

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

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

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

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

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

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

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

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

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

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

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

В. Выссотски из фирмы Bell Telephone Laboratories принадлежит следующее замечание: «Я обнаружил, что в качестве вех выполнения проекта полезно указывать как «назначенные», так и «ожидаемые» даты. Назначенные даты принадлежат руководителю проекта и представляют собой план последовательного выполнения проекта как единого целого, который априори рассматривается как вполне обоснованный и выполнимый. Ожидаемые даты принадлежат младшему руководителю, в чьей компетенции находится данная часть проекта, и представляют собой его точку зрения на то, когда работа будет завершена при наличии необходимых ресурсов. Ожидаемые даты не касаются руководителя проекта, он должен в основном заботиться о получении вовсе не приятных, оптимистических, пусть даже самозащитных, заниженных, а точных и беспристрастных оценок. Как только это будет осознано, руководителе проекта сможет ясно увидеть те направления, где он встретится с затруднениями, если не предпримет чего-нибудь заранее»4).

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

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

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





XV. ВТОРОЕ ЛИЦО

«Mы не обладаем тем, чего не понимаем».
(Гете)

«О, дайте мне талант комментатора, который, не углубляясь в суть явлений, будоражит умы людей».
(Краббе)

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

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

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

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

Томас Дж. Уотсон-старший *) рассказывал как-то о своем первом опыте в качестве коммивояжера, продающего кассовые аппараты. Полный энтузиазма, он отправился в путь, погрузив кассовые аппараты в фургон. Он прилежно изъездил всю местность, но так и не продал ни одного аппарата. Совершенно подавленный неудачей, он доложил о пей хозяину. Тот выслушал отчет, а затем сказал: «Помогите мне погрузить аппараты в фургон, запрягите лошадь, и снова в путь». Так они в сделали, объехали одного покупателя аа другим, и старший показывал, как, продавать кассовые аппараты. Дальнейшее показало, что урок не пропал зря.

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



Какая документация нужна?

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

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

1. Назначение. Какова основная функция программы, для чего она?

2. Ситуация. На каких мшинах, в какой конфигурации и на какой операционной системе она будет работать?

3. Область и сфера действия. Какова область входных данных? В каком диапазоне могут появиться выходные результаты?

4. Реализуемые функции и используемые алгоритмы. Что именно она делает?

5. Форматы ввода/вывода. Точные и полные.

6. Рабочие процедуры, включая нормальное И аварийное окончание, описывают все, что видно с пульта и будет получено на выдачах.

7. Варианты. Какие функции может выбирать пользователь? Как этот выбор определяется?

8. Время исполнения. Сколько времени требует задача указанного объема при определенной конфигурации оборудования?

9. Точность и проверка. Какова ожидаемая точность ответов? Каковы способы проверки точности?

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

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

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

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

1. Главные тесты, которые проверяют основные функции программы для наиболее типичных данных.

2. Предельно допустимые тесты, которые устанавливают границы области входных данных, проверяя, работает ли программа с максимально допустимыми величинами, с минимально допустимыми величинами или с какими-либо исключениями.

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

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

1. Блок-схема или граф подчиненности подпрограмм. Последнее предпочтительней. (Подробнее обсуждается ниже.)

2. Полные описания используемых алгоритмов или ссылки на соответствующие описания в литературе.

3. Форматы всех используемых файлов.

4. Схема передачи информации — последовательность считывания данных или программ с ленты или диска — и описание того, что происходит на каждом этапе передачи.

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

Несостоятельность блок-схем

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

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

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

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

Подробные блок-схемы, однако, устарели; они только мешают, и в лучшем случае пригодны для обучения повичков, еще не умеющих алгоритмически мыслить. В свое время предложенные Голдстайном и Нейманом ') маленькие квадратики на блок-схемах вместе со своим содержанием выступали в качестве языков высокого уровня, объединяя абсолютно непонятные операторы машинного языка в группы, имеющие определенный смысл. Как давно уже указал Айверсон2), в систематическом языке высокого уровня такая группировка уже осуществлена, так что каждый квадратик просто соответствует оператору (рис. 15.2). Тогда сами квадратики превращаются в случайное и ненужное упражнение по рисованию, и от них можно отказаться. Но теперь не остается ничего, кроме стрелок. Стрелки, соединяющие оператор со следующим за ним, не нужны, сотрем их. Остаются только операторы перехода. Но если следовать хорошей практике ,а использовать блочные структуры для минимизации числа операторов перехода, то останется совсем/немного стрелок, вот они-то очень сильно облегчают понимание. Эти стрелки можно перенести прямо ни распечатку программы и совсем избавиться от блок-схемы.

Рис. 15.2. Сравнение блок-схемы и соответствующей программы на PL/I.

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

Апостол Петр так говорил о новообращенных язычниках и иудейских законах: «Что же вы желаете возложить на выи (их) иго, которого не могли понести ни отцы наши, ни мы?» (Деяние 15, 10). Я хотел бы сказать то же самое о начинающих программистах п устаревшей практике .использования блок-схем.

ЭПИЛОГ

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



ПРИМЕЧАНИЯ И ССЫЛКИ

I

1. А. И. Ершов считает, что это обстоятельство определяет не только трудные, но и радостные моменты ремесла программиста. Ershov A. P. Aesthetics and teh human factor in programming.— CACM, July 1972, 15, 7, 501—505. (Ершов А. П.. Эстетический и человеческий факторы в программировании.— Кибернетика, 1972, № 5.)

II

1. По оценкам В. А. Выссотски из фирмы: Bell-Telephone Laboratories, прирост рабочей силы в большом программистском проекте допускается на 30% в год. Больший рост числа сотрудников затрудняет и даже препятствует созданию важнейшей неформальной структуры и установлению связей в проекте, что обсуждается в гл. VII.

Ф. Д;к. Корбато из Массачусоттского Технологического института утверждает, что в большом проекте следует предвидеть текучесть кадров в пределах 20% в год, и заранее предусмотреть необходимость подготовки новичков и ввода их в формальную структуру проекта.

2. Ч. Портман из фирмы International Computers Limited утверждает: «Когда кажется, что уже все работает, все объединено в систему — вам еще осталось работы на четыре месяца». Некоторые графики распределения работ приводятся в статье Wolverion И. W. The cost of developing largescale software: — IEEE Trans. on Computers, June 1974, С—23, 6, р. 615—636.

3. Рисунками 2.5—2,8 мы обязаны Джерри Огдену, который, цитируя мой пример по первой публикации этой главы, значительно улучшил его оформление". Ogdin J. L. The Mongolian hordes versus superprogrammer.— Infosystems, December, 1972, p. 20—23.

Ill

1. Sackman H., Erikson W. J., Grant E. E. Exploratory experimental studies comparing online and offline programming performance.—CACM, January, 1968, 11, 1, 3—11.

2. Mills H. Chief programmer teams, principles, and procedures,—IBM Federal Systems Division Report FSC 71—5108, Gai-thersburg, Md., 1971V"9'"


[1] Номера сносок указывают на примечания автора, собранные в конце книги. {Прим. ред.}

* Следует, однако, признать, что авторская оценка относительной престижности производственной и административной работы не является универсальной. {Прим, ред.)


ОГЛАВЛЕНИЕ

THE MYTHICAL MAN-MONTH (Essays on Software Engineering).............................................................. 1

I. АСФАЛЬТОВАЯ ТОПЬ............................................................................................................................................................. 4

Комплексный программный продукт................................................................................................................................... 4

Радости ремесла........................................................................................................................................................................ 4

Горести ремесла......................................................................................................................................................................... 4

II. МИФИЧЕСКИЙ ЧЕЛОВЕКО-МЕСЯЦ................................................................................................................................. 6

Оптимизм..................................................................................................................................................................................... 6

Человеко-месяц........................................................................................................................................................................... 7

Комплексная отладка............................................................................................................................................................... 8

Объективность оценки............................................................................................................................................................. 8

Нарастающие катастрофы с графиком............................................................................................................................ 9

III. ХИРУРГИЧЕСКАЯ БРИГАДА........................................................................................................................................... 11

Предложение Миллза.............................................................................................................................................................. 12

IV. АРИСТОКРАТИЯ, ДЕМОКРАТИЯ И СИСТЕМНОЕ ПРОЕКТИРОВАНИЕ.......................................................... 15

Концептуальное единство.................................................................................................................................................... 15

Как добиться концептуального единства........................................................................................................................ 15

Аристократия и демократия............................................................................................................................................... 16

Чем может заполнить разработчик период ожидания?............................................................................................ 17

V. ЭФФЕКТ ВТОРОЙ СИСТЕМЫ............................................................................................................................................ 19

Принципы совместной работы........................................................................................................................................... 19

Самодисциплина. Эффект второй системы................................................................................................................... 19

VI. ПУТЬ СЛОВА.......................................................................................................................................................................... 21

Письменные спецификации — руководство..................................................................................................................... 21

Формальные описания............................................................................................................................................................ 21

Прямое внесение....................................................................................................................................................................... 22

Конференции и разбирательства....................................................................................................................................... 23

Совместные реализации........................................................................................................................................................ 23

Журнал регистрации телефонных звонков....................................................................................................................... 24

Проверка конечного продукта............................................................................................................................................. 24

VII. ПОЧЕМУ ОБРУШИЛАСЬ ВАВИЛОНСКАЯ БАШНЯ.............................................................................................. 25

Анализ Вавилонского проекта с точки зрения административного управления.................................................. 25

Связь в больших программистских проектах................................................................................................................. 25

Рабочий документ проекта.................................................................................................................................................. 26

Организация в больших программистских проектах.................................................................................................... 27

VIII. ОБЪЯВЛЕНИЕ ЦЕЛИ........................................................................................................................................................ 30

Данные Портмана.................................................................................................................................................................... 30

Данные Арона............................................................................................................................................................................ 31

Данные Харра............................................................................................................................................................................ 31

Данные по OS/360..................................................................................................................................................................... 32

Данные Корбато...................................................................................................................................................................... 32

IX. ДЕСЯТЬ ФУНТОВ В ПЯТИФУНТОВОМ МЕШКЕ.................................................................................................... 34

Размер программы как стоимость..................................................................................................................................... 34

Контроль за размерами программ...................................................................................................................................... 34

Методы экономии памяти.................................................................................................................................................... 35

Представление данных — сущность программирования............................................................................................. 35

X. ДОКУМЕНТАЦИОННАЯ ГИПОТЕЗА.............................................................................................................................. 37

Документы для разработки ЭВМ........................................................................................................................................ 37

Документы для факультета университета..................................................................................................................... 37

Документы для проекта программного обеспечения.................................................................................................... 38

Зачем нужны формальные документы?............................................................................................................................. 38

XI. ПЛАН НА ВЫБРОС............................................................................................................................................................... 40

Опытные установки и увеличение масштабов............................................................................................................... 40

Постоянны только изменения............................................................................................................................................... 40

Планирование изменений в системе.................................................................................................................................... 40

Планирование изменений в организации............................................................................................................................ 41

Два шага вперед, шаг назад.................................................................................................................................................. 42

Шаг вперед и шаг назад......................................................................................................................................................... 43

XII. ОСТРЫЙ ИНСТРУМЕНТ................................................................................................................................................... 44

Целевые машины...................................................................................................................................................................... 44

Инструментальные машины и служба данных............................................................................................................... 45

Язык высокого уровня и диалоговое программирование.............................................................................................. 46

XIII. ЦЕЛОЕ ИЗ ЧАСТЕЙ........................................................................................................................................................... 49

Проект без ошибок.................................................................................................................................................................. 49

Автономная отладка.............................................................................................................................................................. 50

Системная отладка................................................................................................................................................................ 51

XIV. ПРИБЛИЖЕНИЕ КАТАСТРОФЫ................................................................................................................................... 55

Вехи или помехи?..................................................................................................................................................................... 55

Сор в избе................................................................................................................................................................................... 56

XV. ВТОРОЕ ЛИЦО...................................................................................................................................................................... 60

Какая документация нужна?............................................................................................................................................... 60

Несостоятельность блок-схем............................................................................................................................................ 61

Самодокументированные программы............................................................................................................................... 63

ЭПИЛОГ.......................................................................................................................................................................................... 67

ПРИМЕЧАНИЯ И ССЫЛКИ...................................................................................................................................................... 68

 



I. АСФАЛЬТОВАЯ ТОПЬ

«Корабль на мели — моряку маяк».
(Датская пословица)

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

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

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

Начнем поэтому с определения ремесла системного программирования и присущих ему радостей и горестей.


Комплексный программный продукт

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

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

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

Существуют два пути преобразования программы в более полезный, но и более дорогостоящий продукт. Они представлены на диаграмме вертикальной и гори-зоптп;г)>пон стрелками.

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

Пересекая вертикальную границу, программа превращается в компоненту программного комплекса. Это набор взаимодействующих программ, согласованных по функциям и по формату так, что их объединение представляет собой единое средство для решения больших задач. Чтобы стать частью программного комплекса, программа должна быть написана так, чтобы каждый вход и выход по синтаксису и семантике соответствовал точно определенным сопряжениям. Кроме того, программа должна быть организована так, чтобы она использовала только отведенные ей ресурсы: объем памяти, устройства ввода/вывода, машинное время. И, наконец, программа должна быть отлажена во всех возможных сочетаниях с другими компонентами комплекса. Эта отладка должна быть очень большой по объему, ведь число вариантов растет комбинаторно. Она требует больших затрат времени, ибо появляются очень тонкие ошибки из-за непредвиденных взаимодействий отлаживаемых частей. Компонента программного комплекса стоит, по крайней мере, в три раза больше, чем отдельная программа с . той же функцией. Ее стоимость может быть выше, если система имеет много компонент.

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

Радости ремесла

Почему программирование доставляет удовольствие? Как вознаграждаются все усилия профессионала?

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

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

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

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

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

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

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

Горести ремесла

Не все, однако, радует программиста, и знакомство с горестями, присущими нашему ремеслу, позволяет легче перенести их появление.

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

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

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

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

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

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

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

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

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


Поделиться:



Последнее изменение этой страницы: 2019-03-22; Просмотров: 298; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (1.3 с.)
Главная | Случайная страница | Обратная связь