Een Schip op bet strand is een baken in zee.
[Корабль на мели - моряку маяк.]
ГОЛЛАНДСКАЯ ПОСЛОВИЦА
Самая яркая сцена доисторических времен - борьба огромных животных со смертью в смоляных ямах. Воображение представляет динозавров, мамонтов и саблезубых тигров, пытающихся высвободиться из смолы. Чем отчаянней борьба, тем сильнее затягивает смола, и как бы ни был силен или ловок зверь, в конечном итоге ему уготована гибель.
Такой смоляной ямой в последнее десятилетие было программирование больших систем: в ней сгинул не один большой и сильный зверь. По большей части это происходило в области систем, где мало кому удалось реализовать спецификации, уложиться в график и бюджет. Большие и малые, массивные и жилистые - одна за другой эти команды увязли в смоле. Казалось, ничто в отдельности не вызывает трудностей - одну лапу всегда можно вытащить. Но накопление действующих одновременно и взаимовлияющих факторов все более и более замедляет движение. Вызывает удивление неприятность возникшей проблемы, и распознать ее сущность нелегко. Но нужно это сделать, если мы собираемся решить ее.
Поэтому начнем с определения того, что такое системное программирование, и какие радости и печали оно таит.
Время от времени можно прочесть в газете о том, как в переоборудованном гараже пара программистов сделала замечательную программу, оставившую позади разработки больших команд. И каждый программист охотно верит в эти сказки, поскольку знает, что может создать любую программу со скоростью, значительно превышающей те 1000 операторов в год, которые, по сообщениям, пишут программисты в промышленных бригадах.
Почему же до сих пор все профессиональные бригады программистов не заменены одержимыми дуэтами из гаражей? Нужно посмотреть на то, что, собственно, производится.
В левом верхнем углу рисунка 1.1 находится программа. Она является завершенным продуктом, пригодным для запуска своим автором на системе, на которой была разработана. В гаражах обычно производится такой продукт, и это - тот объект, посредством которого отдельный программист оценивает свою производительность.
Есть два способа, которыми программу можно превратить в более полезный, но и более дорогой объект. Эти два способа представлены по краям рисунка.
Рис.1.1. Эволюция системного программного продукта
При перемещении вниз через горизонтальную границу программа превращается в программный продукт. Это программа, которую любой человек может запускать, тестировать, исправлять и развивать. Она может использоваться в различных операционных средах и со многими наборами данных. Чтобы стать общеупотребительным программным продуктом, программа должна быть написана в обобщенном стиле. В частности, диапазон и вид входных данных должны быть настолько обобщенными, насколько это допускается базовым алгоритмом. Затем программу нужно тщательно протестировать, чтобы быть уверенным в ее надежности. Для этого нужно подготовить достаточное количество контрольных примеров для проверки диапазона допустимых значений входных данных и определения его границ, обработать эти примеры и зафиксировать результаты. Наконец, развитие программы в программный продукт требует создания подробной документации, с помощью которой каждый мог бы использовать ее, делать исправления и расширять. Я пользуюсь практическим правилом, согласно которому программный продукт стоит, по меньшей мере, втрое дороже, чем просто отлаженная программа с такой же функциональностью.
При пересечении вертикальной границы программа становится компонентом программного комплекса. Последний представляет собой набор взаимодействующих программ, согласованных по функциям и форматам, и вкупе составляющих полное средство для решения больших задач. Чтобы стать частью программного комплекса, синтаксис и семантика ввода и вывода программы должны удовлетворять точно определенным интерфейсам. Программа должна быть также спроектирована таким образом, чтобы использовать заранее оговоренный бюджет ресурсов - объем памяти, устройства ввода/вывода, процессорное время. Наконец, программу нужно протестировать вместе с прочими системными компонентами во всех сочетаниях, которые могут встретиться. Это тестирование может оказаться большим по объему, поскольку количество тестируемых случаев растет экспоненциально. Оно также занимает много времени, так как скрытые ошибки выявляются при неожиданных взаимодействиях отлаживаемых компонентов. Компонент программного комплекса стоит, по крайней мере, втрое дороже, чем автономная программа с теми же функциями. Стоимость может увеличиться, если в системе много компонентов.
В правом нижнем углу рисунка 1.1 находится системный программный продукт. От обычной программы он отличается во всех перечисленных выше отношениях. И стоит, соответственно, в десять раз дороже. Но это действительно полезный объект, который является целью большинства системных программных проектов.
Почему заниматься программированием интересно? Какими радостями вознаграждаются те, кто им занимается?
Во-первых, это просто радость, получаемая при создании чего-либо своими руками. Как ребенок радуется, делая куличики из песка, так и взрослый получает удовольствие, создавая какие-либо вещи, особенно если сам их и придумал. Я думаю, что этот восторг - отражение восторга Господа, творящего мир, восторга, проявляющегося в индивидуальности и новизне каждого листочка и каждой снежинки.
Во-вторых, это удовольствие создавать вещи, которые могут быть полезны другим людям. Глубоко в душе мы испытываем потребность в том, чтобы другие использовали результаты нашего труда и считали их полезными. В этом отношении программная система по своей сути - то же, что и изготовленная ребенком подставка для карандашей "папе в подарок".
В-третьих, это очарование создания сложных головоломных объектов, состоящих из взаимодействующих движущихся частей и наблюдения за их работой, круг за кругом демонстрирующей результаты изначально заложенных принципов. Компьютер с работающей на нем программой обладает доведенным до высшего предела очарованием игорного или музыкального автомата.
В-четвертых, это радость, получаемая от неизменного узнавания нового, проистекающего из неповторимой природы задачи. В том или ином отношении задача всегда ставится по-новому, и тот, кто ее решает, получает новые знания - либо практические, либо теоретические, либо те и другие вместе.
Наконец, наслаждение доставляет работа со столь податливым материалом. Программист, подобно поэту, работает почти непосредственно с чистой мыслью. Он строит свои замки в воздухе и из воздуха, творя силой воображения. Трудно найти другой материал, используемый в творчестве, который столь же гибок, прост для шлифовки или переработки и доступен для воплощения грандиозных замыслов. (Как мы позднее увидим, такая податливость таит свои проблемы.)
Однако программная конструкция, в отличие от поэтических творений, реальна, в том смысле, что она движется и работает, производя видимые результаты, которые отделимы от самой конструкции. Она печатает результаты, рисует картинки, производит звуки, приводит в движение рычаги. В наше время осуществилось волшебство мифа и легенды. С клавиатуры вводится верное заклинание, и экран монитора оживает, показывая то, чего никогда не было и не могло быть.
Таким образом, программирование доставляет удовольствие, поскольку отвечает глубокой внутренней потребности в творчестве и удовлетворяет чувственные потребности, которые есть у всех нас.
Не все, однако, в радость, и если предвидеть присущие этому ремеслу огорчения, то они легче переносятся.
Во-первых, необходима безошибочная точность действий. В этом отношении компьютер также напоминает волшебство. Один неверный знак, одна пауза в заклинании, и чудо не состоялось. Человеку несвойственно совершенство, и оно является необходимым лишь в немногих сферах его деятельности. Мне кажется, что при освоении программирования труднее всего привыкнуть к требованию совершенства.1
Кроме того, постановка задач, обеспечение ресурсами и предоставление информации осуществляется другими людьми. Редко удается контролировать условия работы и даже ее цели. На языке администрирования это означает, что полномочия ниже ответственности. Впрочем, похоже, что в любой работе, где должен быть получен результат, формальная власть никогда не соизмерима с ответственностью. На практике фактическая (в противоположность формальной) власть приобретается в результате успешного выполнения задач.
Зависимость от других имеет особенно неприятную системному программисту сторону. Он находится в зависимости от программ, написанных другими людьми, и эти программы зачастую плохо спроектированы, слабо написаны, получены в неполном виде (без исходного текста и контрольных примеров) и плохо документированы. Поэтому программисту приходится тратить многие часы на изучение и исправление вещей, которые, в идеале, должны быть полными, доступными и годными к использованию.
Следующий "минус" связан с тем, разработка грандиозных идей - это удовольствие, а поиск паршивых маленьких "жучков" - это всего лишь работа. В каждом творческом деле бывают ужасные периоды однообразного и кропотливого труда, и программирование не является исключением.
Далее оказывается, что при отладке программы сходимость является линейной, если не хуже, хотя можно было предполагать некое квадратичное приближение к окончанию. В итоге отладка продолжается долго, причем на поиск последних более сложных ошибок уходит больше времени, чем на отыскание первых.
Последняя горесть, а часто и последняя капля, - то, что продукт, на который было положено столько труда, оказывается устаревшим в момент его завершения (или даже раньше). Коллеги и конкуренты уже с пылом работают над новыми и лучшими идеями. И уничтожение плода вашей мысли уже не только задумано, но и запланировано.
На самом деле положение обычно лучше, чем, кажется. В то время как ваш продукт уже завершен, этот новый и лучший продукт, как правило, отсутствует на рынке, о нем лишь много разговоров, и для его разработки потребуются месяцы. Настоящий тигр не пара бумажному, если требуется реальное использование. Реальное существование имеет преимущества.
Конечно, технологическая основа разработки всегда развивается. Как только разработка проекта закончена, он становится устаревшим в смысле заложенных в нем концепций. Но для осуществления реального проекта необходимо разбиение на стадии и уровни. Судить о том, является ли некая реализация устаревшей, можно лишь сравнивая ее с другими существующими реализациями, а не с нереализованными идеями. Трудность и цель состоят в том, чтобы найти реальные решения для реальных задач в установленные сроки, используя имеющиеся ресурсы.
Таково программирование - и смоляная яма, в которой увязли многие проекты, и творчество со своими радостями и печалями. Для многих радости значат гораздо больше, чем печали. Для них и написана эта книга в попытке проложить какие-то мостки через это болото.
1 А.П.Ершов полагает, что это не только печаль, но отчасти и радость. A.P.Ershov. Aesthetics and the human factor in programming // CACM. 1972. Vol.15, N 7. July. P.501-505.
Пользователь, раз уж ты добрался до этой строки, ты нашёл тут что-то интересное или полезное для себя. Надеюсь, ты просматривал сайт в браузере Firefox, который один правильно отражает формулы, встречающиеся на страницах. Если тебе понравился контент, помоги сайту материально. Отключи, пожалуйста, блокираторы рекламы и нажми на пару баннеров вверху страницы. Это тебе ничего не будет стоить, увидишь ты только то, что уже искал или ищешь, а сайту ты поможешь оставаться на плаву.