Об инструментах
Влад «Bill» Князев
24 февраля 2004
Часть 1. Вместо предисловия
Мы живем в век больших скоростей, и с каждым годом динамизм нашей жизни возрастает. Можно по-разному относится к этому. Кому-то это может не нравиться, кому-то это по душе. Я же воспринимаю это как некоторого рода неизбежность, к которой нужно просто приспособится. У всякого явления есть свои как положительные, так и отрицательные свойства. Надо стремиться к тому, чтобы, используя все положительные свойства некоторого явления, не забывать об отрицательных его свойствах и всегда их учитывать.
Возьмем, например, потребность человека в передвижении. Когда-то, давным-давно, единственным средством передвижения человека являлась пара его собственных ног. И хотя скорость передвижения человека была незначительной, но вероятность столкновения двух людей друг с другом была близка к нулю. Еще меньше была вероятность серьезной травмы, опасной для жизни, которую человек мог получить в результате такого столкновения. Оно и понятно. Чем ниже скорость, тем лучше человек мог управлять собой, и тем самым избегать столкновений. И даже тогда, когда человек сел на лошадь вероятность трагических столкновений продолжала оставаться достаточно низкой.
Иное дело сейчас, когда человек пересел с лошади на автомобиль. Скорость передвижения резко возросла, но в результате резко возросло количество столкновений на дорогах с трагическими для людей последствиями. Да и в тех случаях, когда столкновений не было, люди гибли и гибнут в результате неумения управлять автомобилем в сложных условиях на больших скоростях.
Вы можете сказать, что это всем известные прописные истины, о которых не следует особо распространяться, и будете правы. Но ведь компьютер - это тот же самый инструмент, который используется человеком в определенных сферах его деятельности. Причем, инструмент очень и очень мощный. И если при пользовании автомобилем человек еще помнит об опасностях, которой человек подвергается, то при использовании компьютера мы об этом часто забываем, а то и не знаем вовсе.
В до компьютерную эру практически вся информация хранилась на бумажных носителях, попросту на бумаге. Можно легко представить себе, что человек мог по ошибке выбросить в мусорную корзину какую-нибудь бумагу с ценной информацией. Но представить себе, что человек ошибочно выбросит или уничтожит целую папку с документами, уже довольно трудно. Сейчас, когда вся информация хранится в компьютере, и представить, и сделать это довольно легко. Информацию можно уничтожить, не прикладывая к этому абсолютно никаких усилий. Для этого достаточно легкого щелчка по кнопке «мыши». Компьютер хоть и является чрезвычайно эффективным инструментом, но его эффективность есть величина скалярная, не имеющая знака. Компьютер поможет сделать порядок на нашем рабочем месте еще более упорядоченным. Но малейший беспорядок с помощью компьютера легко превратится в хаос. А из этого хаоса выбраться человеку будет очень и очень нелегко.
Поэтому, если мы хотим иметь порядок в «электронных мозгах» и получить от этого максимальный положительный эффект, мы должны прежде всего навести порядок в наших собственных, у себя в голове. Все это означает, что чем более мощный инструмент мы используем в своей деятельности, тем больше мы должны быть осторожными при его использовании. И теперь о главном.
Часть 2. Инструменты для программирования
Я думаю, что аналогия развития средств программирования и средств передвижения здесь вполне уместна. Используя современные инструменты программирования, мы резко ускорили процесс разработки программ. Но стали ли при этом наши программы надежнее? Я думаю, ответ на этот вопрос вряд ли будет однозначным.
Конечно, используя при программировании языки высокого уровня, программист может избежать тех ошибок, которые были возможны в программах на языках ассемблера, особенно в случаях больших программ, состоящих из тысяч строк. Но есть ли гарантия, что при этом не появятся взамен прежних новые ошибки? Я думаю, такой гарантии нет. И для того, чтобы так думать, имеется целый ряд причин.
Средства автоматизации программирования стали появляться практически одновременно с появлением самих компьютеров. Тогда, когда люди поняли, что компьютеры способны не только «перемалывать» числа, но и выполнять более интеллектуальную работу. Так появились языки программирования на уровне ассемблера. И хотя одна строка ассемблера соответствовала одной машинной инструкции, но это был уже некоторый (небольшой) уровень абстракции от аппаратных средств компьютера. Тем не менее, в этом случае программист мог легко контролировать свою программу и ее поведение. И если программа не работала, или работала неправильно в результате ошибок в транслирующей программе, то такая ошибка легко находилась и исправлялась. Благо в те времена разработчики ассемблера и его пользователи были в одном лице.
Но вот появились алгоритмические языки высокого уровня (ЯВУ) и трансляторы для них. Теперь программисты уже не могли полностью контролировать свою собственную программу, поскольку инструкции в программе компьютера генерировались программой транслятора ЯВУ. Программист попал в зависимость к транслятору, стал заложником его. Теперь правильность работы программы стала зависеть не только от программиста, но и от правильности работы транслятора. Конечно, первые трансляторы писались вручную, писались долго и долго тестировались. И вероятность их ошибок была крайне мала. Но программистам все равно требовалось знать, насколько адекватно они воспринимают сам ЯВУ и насколько оптимальным получается код на выходе транслятора. И эта потребность осталась и сейчас, особенно при программировании для встраиваемых систем.
И здесь мне хочется сделать одно замечание. Первые трансляторы ЯВУ были предельно простыми, в них отсутствовала сколь-нибудь глубокая оптимизация программ. А это делало их более надежными, повышало степень доверие к ним у программистов.
А что же мы имеем сейчас? Сейчас мы имеем массу алгоритмических языков высокого и сверхвысокого уровня. Мы имеем множество сложных оптимизирующих трансляторов для них. Но вместе с тем, мы как программисты, попали в глубокую зависимость от них, от их ошибок. А чем сложнее программа, тем больше вероятность появления ошибок в ней. И программы трансляторов не являются здесь исключением из правил.
А если взять инструменты «визуального» программирования. На их примере особенно наглядно видно насколько сильно программист оторвался от основы, от самого компьютера. Использовать такие средства, это все равно, что плыть на маленькой лодочке по глубокому океану не чувствуя под собой дна, или лететь сверхскоростном реактивном лайнере в десятках тысяч метров над землей. Но мы пользуемся такими лайнерами из-за тех преимуществ в скорости, которые они нам дают, несмотря на риск при их использовании.

Но кроме инструментов программирования, как таковых, на надежность программ оказывает влияние такой фактор, как объем разрабатываемых программ. Я склонен думать, что использование ЯВУ при разработке программ не только не уменьшает, а наоборот, увеличивает их сложность. Кажущаяся простота использования ЯВУ и резко возросшая скорость разработки программ просто подталкивают программиста к созданию все более сложных программ. И если раньше программа состояла, скажем, из одной тысячи строк на языке ассемблера и соответствовала той же тысяче инструкций процессора, то теперь та же программа будет состоять из полутора тысяч строк на языке Си++ и примерно из десяти-пятнадцати тысяч инструкций процессора, полученных в результате трансляции. И даже если допустить, что надежность компилятора на порядок выше надежности ручного кодирования, то надежность программы останется примерно на одном уровне. Но всегда ли оправдано такое допущение?
Я помню времена, когда на мини-компьютерах в режиме разделения времени могло работать одновременно до десятка человек. При этом и быстродействие компьютеров было на несколько порядков ниже, и объем памяти у компьютеров был на несколько порядков меньше (размер памяти в 1Мбайт был пределом мечтаний). И ничего, работали и не имели тех постоянных проблем, какие мы имеем, работая, скажем, в среде Windows. Хотя надежность прежних мини-ЭВМ была гораздо ниже нынешних персональных компьютеров.
Конечно, можно возразить, что задачи, которые решаются сейчас на порядок сложнее тех, которые решались тридцать лет назад. Да и сама среда ОС Windows стала намного дружественней для пользователя, чем, скажем, ОС RSX-11M. Но это возражение только подтверждает то, о чем я сказал ранее. Если исходный текст для RSX был написан на ассемблере, то для создания Windows явно использовался Си (или С++). Но стала ли Windows надежней, чем старенькая RSX? Я в этом сильно сомневаюсь. И хотя дело здесь, скорее всего не в инструментах как таковых, но и они сыграли вполне определенную (и не последнюю) роль.
Наконец, использование ЯВУ при создании больших программных комплексов не гарантирует от ошибок даже в тех случаях, когда отдельные модули программ, взятые порознь, тщательно оттестированы и не содержат ошибок. Тем не менее, бездумное соединение таких модулей в единую программу, без учета внешних требований к программе делают ее полностью неработоспособной. Здесь я имею в виду неудачи при запусках новых французских ракет «Ариан», анализ причин этих неудач можно найти в Интернете (cм. http://www.91.ru/Education/Books/Os/21.htm).
Часть 3. И что теперь делать?
Я думаю, этот вопрос наверняка у Вас появится после прочтения всего того, что я написал выше. Что же теперь возвращаться назад к ассемблеру, а то и вовсе к ручному кодированию программ? Отнюдь! Ведь летаем же мы на суперскоростных лайнерах, несмотря на риск. То же самое можно сказать и обо всех других инструментах вообще, и инструментах программирования, в частности.
И рекомендации здесь довольно просты. Во-первых, выбор того или иного инструмента должен быть адекватен решаемой с его помощью задаче. Не следует стрелять из пушек по воробьям. Во-вторых, следует тщательно изучить используемый инструмент, «прочувствовать» его, подружиться с ним. Нужно хорошо изучить как все его достоинства, так и его недостатки. И не стоит для этого жалеть времени. Эти затраты времени потом многократно окупятся. Но чем сложнее и мощнее инструмент, тем больше времени придется затратить на овладение им. Отсюда вытекает и третья рекомендация: не стоит торопиться с заменой хорошо проверенного, надежного инструмента на более новый, и, возможно, более мощный. Это касается и более новых версий используемого инструмента. Следует помнить, что старый друг лучше новых двух. Вполне возможно, что для изучения нового инструмента понадобиться не меньше времени, чем для изучения старого.
Наконец, нужно понять, что самый лучший инструмент тот, которым ты владеешь наилучшим образом. И любые «религиозные войны» типа XX vs. YY, я думаю, не только неуместны, но и вредны по своей сущности, как любая настоящая война.
И последнее. Независимо от того, какой инструмент Вы используете, Вашим главным инструментом будет Ваш профессионализм, Ваше профессиональное самолюбие, Ваша профессиональная добросовестность. И только Ваш профессионализм способен компенсировать недостатки любого инструмента и умножить его достоинства.
И в заключение, перефразируя известное выражение всем известного моего тезки (отнюдь не претендуя на его известность), могу сказать, что главной задачей любого программиста является ДУМАТЬ, ДУМАТЬ и еще раз ДУМАТЬ.
Влад, он же Bill.