69952.fb2
Программирование доставляет нам радость, потому что позволяет удовлетворить стремление к творчеству, глубоко заложенное в каждом из нас, и разделить это чувство радости с другими.
Горести ремесла
Не все, однако, радует программиста, и знакомство с горестями, присущими нашему ремеслу, позволяет легче перенести их появление.
Во-первых, надо работать очень тщательно. В этом смысле ЭВМ тоже напоминает волшебство из сказок. Если хоть один символ, один пробел в магической формуле не находится строго на своем месте, волшебство не работает. Люди не привыкли к совершенству, и лишь немногие области человеческой деятельности требуют его. Привыкание к требованиям совершенной точности является, по моему мнению, наиболее трудным в процессе обучения программированию)1).
Во-вторькх, задачи, стоящие перед программистом, определяют другие люди, они же отводят ему ресурсы v. снабжают информацией. Один человек крайне редко слм определяет обстоятельства своей работы, не говоря уже о ее целях. В административных терминах это означает, что'степень ответственности превышает объем прав., Однако, по-видимому, во всех областях созидательной деятельности формальный объем прав никогда не согласуется с ответственностью. В действительности же фактический объем прав достигается как только работа завершена.
Зависимость от других проявляется здесь особо, весьма болезненно для системного программиста. Он зависит от чужих программ. В то же время эти программы зачастую неверно спроектированы, плохо .реализованы, не полностью укомплектованы (например, нет программы на входном языке пли нет тестов) п слабо документированы. Поэтому программисту приходится часами разбираться в таких вещах, которые в идеальном случае должны быть вполне завершены, доступны и легко используемы.
Следующее обстоятельство сводится к тому, что приятно выдавать большие идеи, но какой же поистине "адский труд" - иногда поиск самой крошечной ошибки! Любая творческая деятельность подразумевает долгие часы кропотливого и скучного труда, и программирование в этом смысле - отнюдь не исключение.
П, далее, могло бы показаться, что чем меньше ошибок в программе, тем легче их найти, т. е. скорость отладки как бы обладает квадратичной сходимостью. Совсем наоборот - сходимость оказывается линешюп или хуже, т.е. в ходе отладки обнаружение последних ошибок требует гораздо больше времени, чем первых.
Последняя неприятность, а иногда и последнее разочарование заключается в том, что продукт, над которым вы трудились так долго, к моменту завершения (или даже раньше) уже устарел. Всегда коллеги и соперники гоняются за новыми и лучшими идеями. И вот уже'замена выношенной вами идеи не только задумана, но и внесена в план.
Действительность, как правило, не так страшна. Новый и более совершенный продукт обычно еще не доступен к тому моменту, когда вы уже завершили свой собственный; о нем пока только говорят. И на его создание тоже потребуются долгие месяцы. Бумажный тигр не соперник реальному, если речь идет о действительном его использовании. Преимущества реальности всегда получают признание.
Конечно, техническая база, на которой все строится, постепенно идет вперед. Как только проект окончательно принят, он становится устаревшим в смысле своих концепций. По осуществление проекта, направленного на получение реального продукта, требует времени и труда. Степень отсталости реализованного проекта нужно измерять по сравнению с другими существующими реализациями, а не с еще нереализованными концепциями. Цель и задача состоят в том, чтобы йайти реальные решения реальных проблем в соответствии с существующими планами и наличными ресурсами.
Таково программирование - одновременно и асфальтовая топь, поглощающая многие начинания, и творческая деятельность с присущими только ей радостями и горестями. В глазах многих ее радости значительно перевешивают все горести, и именно для них эта книга попытается проложить отдельные тропки через топь.
II. МИФИЧЕСКИЙ ЧЕЛОВЕКО-МЕСЯЦ
"Хорошая кухня требует времени. Если Вы готовы подождать, мы обслужим Вас гораздо лучше, и Вы получите большее удовольствием.
(Меню ресторана "Антуан", Новый Орлеан)
Почти все программистские проекты страдают скорее из-за нехватки времени, нежели из-за отсутствия каких-либо других ресурсов. Почему эта причина бедствий является столь всеобщей?
Во-первых, наши методы оценки весьма несовершенны. Строго говоря, они отражают некоторое неявно высказываемое и в корпе неверное допущение, что все будет идти хорошо.
Во-вторых; наши методы оценки ошибочно путают усилия с достижениями, прячась за допущение, что человек и месяц взаимозаменяемы.
В-третьих, отсутствие уверенности в наших оценках ведет к отсутствию у руководителей программистских проектов вежливого упрямства, свойственного шеф-повару ресторана "Аптуан".
В-четвертых, управление ходом разработки плохо организовано. Методы, давно опробованные и даже рутинные в других технических дисциплинах, в технологии программирования рассматриваются как радикальные новшества.
В-пятых, когда обнаруживается отставание от графика, естественная (и традиционная) реакция руководителя - добавить рабочей силы. А это, аналогично попытке залх1вать огонь бензином,- только ухудшает дело, причем значительно. Чем сильнее огонь, тем больше требуется бензина, круг замыкается, и последствия плачевны.
Наблюдение за выполнением графиков будет темой отдельной главы. Давайте пока подробнее рассмотрим другие аспекты проблемы.
Оптимизм
Все программисты - оптимисты. Может быть, это современное чародейство особенно привлекает тех, кто верит в добрых фей и счастливый конец. Может быть, 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.
Так как разработка программного обеспечения по самой своей сути деятельность системная, т. е. задача на сложные взаимосвязи, то затраты на их обеспечение велики и быстро перевешивают ту экономию затрачиваемого на задачу времени, которая достигается благодаря разбиению задачи на части. Добавление людей лишь удлиняет сроки выполнения работ, а не укорачивает их.
Комплексная отладка
Ни одна часть графика работ не связана так сильно ограничениями на их последовательность, как отладка компонент и комплексная отладка.. Очевидно, что требуемое время зависит от числа встречаемых ошибок и легкости их обнаружения. Будучи оптимистами, мы обычно ожидаем, что ошибок будет меньше, чем это оказывается в действительности. Именно поэтому отладка чаще всего не укладывается в график.
В течение нескольких лет я успешно применял следующее практическое правило планирования работ по созданию программного обеспечения: