Здесь изложение идет в форме диалогов между вымышленными персонажами как и в моей книге "Занимательная математика. Множества и отношения"
Профессор. Радость творчества программиста омрачается, в первую очередь, необходимостью отладки практически любой программы. А это нередко требует в несколько раз больше времени и умственных усилий, чем исходный замысел и последующая разработка, и представляет собой в основном кропотливый процесс поиска и устранения ошибок, которых при написании кода программы очень трудно избежать. Если листинг вашей только что написанной программы занимает более четверти страницы, то почти наверняка в нем есть хотя бы одна ошибка. Даже если вам удалось устранить как будто все ошибки, вероятность существования еще не вскрытых все же остается большей нуля. Как говорят программисты, "последняя обнаруженная ошибка в действительности является предпоследней". Наиболее простым по своей сути является элементарное нарушение синтаксиса языка: пропуск символа, запятой, скобки и т. п. В обычных текстах на естественном языке подобного рода ошибки называют опечатками, причиной которых является небрежность писателя, редактора или корректора. Большинство опечаток устраняют при подготовке рукописи к публикации. Программист, в отличие от обычного писателя, не может рассчитывать на помощь редактора и корректора. Он должен самостоятельно отыскать и исправить подобного рода ошибки. В противном случае его программа просто не будет работать. Поэтому программы подвергают испытаниям или, как еще говорят, тестированию.
Простак. А чем отличается отладка от тестирования программы? Как я понимаю, и то и другое проводят для проверки наличия ошибок.
Профессор. Отличие состоит в том, что отладку выполняет программист (автор программы), а тестирование — обычно другие люди. Дело в том, что к тестированию приступают после того, как программист устранил, как он считает, основные ошибки (главным образом, синтаксические) и программа стала работоспособной, т. е. способной выполнять все заданные функции хотя бы при определенных условиях. Чтобы это стало возможным, необходимо устранить по крайней мере все синтаксические ошибки. Далее следует проверить, что программа действительно способна выполнить все возложенные на нее функции, пусть даже не при всех возможных, а только при благоприятных обстоятельствах. Однако программист, проверяя свою программу, вольно или невольно действует в соответствии с правильной логикой ее использования, не допуская грубых смысловых и логических ошибок. Иначе говоря, при проверке своей программы он избегает заведомо "глупых" действий пользователя. Например, если поле предназначено для ввода чисел, то при тестировании программист введет в него какое-нибудь число, а не буквы. Но пользователь, в отличие от автора программы, может действовать как угодно и набрать вместо числа произвольную последовательность символов, получив в результате либо что-то бессмысленное, либо (в лучшем случае) сообщение об ошибке, либо "зависание" (аварийную остановку) программы. Самый неблагоприятный вариант с точки зрения программиста состоит в зависании или, иначе говоря, в "падении" его программы, а самый худший исход с точки зрения пользователя — получение семантически неверных данных без каких либо сообщений об аномалиях. Программист может заранее предусмотреть некоторые подобные ситуации, но не все из них в состоянии проверить при отладке. Поэтому и проводят тестирование, выступая на стороне "дикого" пользователя, а не "умного" автора программы. Лучше, если это сделает кто-то другой (беспристрастный), а не разработчик. Однако при создании Web-приложений часто случается, что и дизайнер, и программист, и тестировщик один и тот же человек. Разумеется, тестирование не ограничивается только выявлением оставшихся ошибок. Нередко следует еще проверить, как ваша программа будет работать на других платформах, при разных мониторах, в различных браузерах и т.п.
Простак. Я слышал, что есть такие уникальные люди, которые умудряются все испортить, даже не желая этого. Наверное, из них получились бы идеальные тестировщики
Профессор. Действительно, такие феномены встречаются. При этом их нельзя заподозрить в какой бы то ни было злонамеренности. Так известно, что лишь одно появление в лаборатории знаменитого физика-теоретика Вольфганга Паули приводило к срыву до этого успешных экспериментов и выходу из строя высокоточного оборудования. Этот феномен назвали эффектом Паули. Я думаю, что для успешного тестирования своих программ автору достаточно просто стать злонамеренным, вести себя преднамеренно против своего детища, стремясь спровоцировать появление ошибок, или, по крайней мере, действовать как можно более нелогично и глупо.
Многие теоретики и практики программирования положили немало труда, чтобы увеличить производительность программистов и качество их продукции. С этой целью разрабатывались различные языки высокого уровня. С одной стороны, их стремились как-то приблизить к естественным (точнее, к английскому), а с другой, — обеспечить поддержку технологий программирования, которые способствовали бы уменьшению количества дефектов кода, облегчали бы сопровождение программных продуктов, а также их разработку большими коллективами людей.
Как оказалось, идея сделать языки программирования более доступными широкому кругу людей, приблизив их к естественным, не оправдала себя, поскольку такое приближение касалось главным образом лексики, а не синтаксиса и грамматики. Например, никто из говорящих на русском не испытал бы облегчения при замене в языке программирования ключевого слова if на если, а begin — на начало. Ключевые слова, как и слова любого иностранного естественного языка довольно легко понимаются и запоминаются при достаточно частом их употреблении в речи. Несколько сложнее дело обстоит со словоупотреблением, когда из известных слов необходимо составлять правильные выражения. Если выражение неправильно грамматически и/или синтаксически, то оно скорее всего не будет понято правильно, т.е. так, как этого хотел бы говорящий.
Зануда. Однако в повседневной речи мы часто слышим грамматически неправильную речь, но все же достаточно адекватно воспринимаем ее.
Профессор. Так происходит, пока примитивные выражения выражают столь же простые мысли типа "дай", "хорошо", "я тебя люблю", "я в шоке", "пора смываться" и т. п. Простые лингвистические конструкции предназначены в основном для передачи оценок ситуации, отношений к окружающим предметам и соответствующих реакций. Примерно для этих же целей служит сигнальная система высших животных. Задумайтесь над тем, как следует построить языковое выражение, чтобы что-нибудь объяснить, доказать или просто рассказать, как, например, из пункта А попасть в пункт Б. Здесь вам примитивными сигналами не обойтись.
Итак, ошибки даже у опытных программистов встречаются настолько часто, что их появление можно считать почти неизбежным. Поэтому программист должен писать свои программы в таком виде, чтобы было легко их отлаживать, а в дальнейшем — сопровождать, т. е. устранять вновь обнаруженные дефекты, вносить изменения, включать в состав более сложных проектов и т.п. Дело в том, что нередко автор с трудом разбирается в тексте своей же программы, если не занимался ею месяц или более. Поэтому при написании текстов программ не следует скупиться на достаточно развернутые комментарии к ним. К сожалению, новички обычно пренебрегают этой рекомендацией и вспоминают о ней, когда приходится обращаться к своей старой программе, даже если она написана неделю тому назад. Кроме того, необходимо стремиться к тому, чтобы программа имела достаточно понятную структуру, состоящую из элементов программного кода (функций, объектов, блоков выражений и т.п.), относительно каждого из которых достаточно ясно, что он делает и с какими другими программными элементами связан. Это важно как для локализации ошибок, так и при модификации программы. Любая корректировка уже отлаженной программы, направленная на ее усовершенствование, как правило чревата внесением новых ошибок. Так что, обычно подтверждается принцип "лучшее — враг хорошего". Если исходная программа хорошо структурирована, то при внесении изменений вам легче будет проследить, куда и как распространилось влияние модифицированного элемента, содержащего ошибки.
Следует также отметить, что коллективная работа над созданием сложного программного продукта также может привести к определенным неприятностям.
Простак. А мне нравится работать в компании. Где как не в хорошей команде единомышленников можно ощутить "чувство локтя", воспользоваться взаимовыручкой и взаимным оплодотворением идеями?
Зануда. Хотя я предпочитаю работать в одиночку, но в принципе согласен с Простаком. К тому же не следует упускать из виду, что существуют настолько сложные задачи, которые либо просто не под силу одному человеку, либо требуют для своего решения неприемлемо много времени. К примеру, я умею писать HTML-код для сайтов, но слабо владею компьютерной обработкой графических изображений, да и в дизайне я далеко не профессионал. Поэтому при разработке сайта было бы разумно скооперироваться с художником-дизайнером. Вместе мы выполним проект и быстрее, и качественнее.
Профессор. Это верно, но не сбрасывайте со счета то очень важное обстоятельство, что при коллективной работе растут накладные расходы на всяческие согласования. Чтобы проект мог быть выполнен группой разработчиков качественно и в срок, необходимы как предварительная тщательная проработка самого проекта, так и его грамотный руководитель — главный конструктор или архитектор. Привлечение к разработке проекта нескольких программистов — довольно непростое дело. Представьте себе, что получилось, если бы мы решили создать "суперроман", поручив это дело десяти самым выдающимся писателям?
Простак. Скорее всего, они передрались бы друг с другом. По крайне мере, увязли в бесконечной взаимной критике. Однако дело не совсем безнадежное, просто среди них нужно назначить руководителя.
Зануда. А ты уверен, что кто-либо из выдающихся авторов согласится писать по чьей-то указке? Писатель не может написать некоторую часть общего романа, если не знает его общего замысла, драматургии и стиля исполнения. Наконец, он просто не сможет писать так, как это делает кто-то другой.
Простак. Но ведь существуют превосходные художественные произведения, написанные в соавторстве, например, книги Ильфа и Петрова, братьев Стругацких и братьев Вайнеров
Зануда. Это, скорее, исключение из общего правила. Даже если авторов художественного произведения всего лишь двое, то и в этом случае остается только удивляться, как им удалось сотрудничать. Другое дело — создание увесистого справочника, словаря, энциклопедии или учебника. Здесь очевидно, что всю работу можно разделить между многими коллегами, каждый из которых напишет свою статью более или менее автономно. В конце концов, главный редактор "причешет" под единый стиль "многоцветное и разношерстное" произведение коллектива авторов, придав ему композиционную и стилевую целостность.
Профессор. Программисты в большинстве своем творческие люди, во многом похожие на писателей, но результат их работы все же существенно отличается от литературного художественного произведения и, главным образом, тем, что носит в большей мере технологический, чем психологический или эстетический характер. Поэтому для программ применимы методы разработки и производства, близкие к методам создания технических проектов с привлечением труда не только единиц, но и десятков специалистов различной квалификации. При этом руководителям проектов очень важно учитывать специфику их труда. Программист может просидеть над решением своей задачи несколько часов или даже дней, не написав ни строчки кода. А в один прекрасный день он придет и за полчаса создаст превосходную рабочую версию заданной ему программы. Важно понимать, что программист это не просто производитель кодов, подобный, например, токарю, из под рук которого выскакивают болты. Чем дольше работает токарь, и чем выше его квалификация, тем больше болтов он выпустит. Программист же, напротив, большую часть времени тратит на обдумывание проекта своей программы и отладку ее реализации, и меньше всего — на написание самого кода, т.е. текста из выражений на языке программирования. Со стороны может показаться, что большую часть времени он ничего не делает. Так уж повелось, что за обдумывание никто не платит, и это время расценивается как праздное. Иногда разработчик затратит целую неделю, чтобы заменить многостраничный листинг первоначальной версии своей программы всего лишь несколькими строками более эффективного кода. Другой раз, чтобы получить всего лишь несколько окончательных строк кода, программисту нередко приходится исписать груды бумаги или экранных страниц. Поэтому нелепо оценивать производительность программиста количеством операторов (команд), написанных в единицу времени, а объем выполненной работы — длиной окончательного листинга.
Простак. А как же тогда оценивать его работу?
Профессор. Сейчас мне хотелось лишь обратить ваше внимание на нетривиальность оценки труда программистов. Мы не будем углубляться в данную тему. Отмечу только, что на этот и многие другие вопросы организации производства программ обратил внимание Фредерик Брукс в своей знаменитой книге "Мифический человеко-месяц, или как создаются программные системы". Указанную книгу обязан прочитать каждый менеджер программного проекта, а также специалист, который в том или ином качестве вовлечен в процесс промышленного производства программных продуктов. Вы же, друзья, находитесь лишь только в начале пути к профессии программиста. Возможно, кто-то из вас свернет с него. Так что, сначала взгляните на предстоящее путешествие с высоты птичьего полета. Сверху, возможно, вы не все, что надо для практической и профессиональной работы, разглядите достаточно отчетливо, но сможете хотя бы немного ориентироваться в "непролазных джунглях" программирования.