Личность
С момента публикации в 1965 году знаменитой статьи Эдсгера Дейкстры «Programming Considered as a Human Activity» («Программирование как человеческая деятельность») личности программистов привлекают самое пристальное внимание ученых. Названия книг «Психология конструирования мостов» и «Экспериментальные исследования поведения юристов» могли бы показаться абсурдными, однако работы «Психология программирования» («The Psychology of Computer Programming»), «Экспериментальные исследования поведения программистов» («Exploratory Experiments in Programmer Behavior») и т. п. уже стали классическими.
В какой бы области ни работали инженеры, они должны знать возможности применяемых инструментов и материалов. Инженеры-электрики знают проводимость разных металлов и сотни способов использования вольтметра. Инженерам-проектировщикам строительных конструкций известны параметры прочности дерева, бетона и стали.
Если вы разрабатываете ПО, вашим основным строительным материалом является интеллект, а главным инструментом — вы сами. Вместо того чтобы спроектировать структуру до последних деталей и передать чертежи конструкторам, вы проектируете фрагмент ПО до последних деталей, и на этом работа над ним завершается. По сути все программирование состоит в создании воздушных замков — это умственная деятельность почти что в самом чистом виде. Соответственно, когда разработчики ПО изучают существенные свойства своих инструментов и материалов, они изучают людей: интеллект, характер и другие атрибуты, не столь осязаемые, как дерево, бетон и сталь.
Если вам нужны конкретные советы, эта глава может показаться вам чересчур абстрактной, чтобы быть полезной. Поэтому прочтите следующий раздел и решите, следует ли ее пропустить.
Причем тут характер?
Крайняя замкнутость программирования придает свойствам личности программиста особую значимость. Вы сами знаете, как сложно поддерживать сосредоточенность на протяжении восьми часов рабочего дня. Наверное, вы можете вспомнить день или месяц, прошедший впустую из-за чрезмерной концентрации в предыдущий день или месяц. Наверняка бывали дни, когда вы продуктивно работали с 8 часов утра до 2 ночи, после чего чувствовали, что пора отдохнуть. Но вы продолжали работать до 5 часов утра и тратили остальные дни недели на исправление того, что написали ночью.
Программирование плохо поддается контролю особенно потому, что никто на самом деле не знает, над чем вы работаете. У всех нас были проекты, при реализации которых мы проводили 80% времени над небольшим фрагментом, казавшимся интересным и тратили 20% времени на создание остальных 80% программы.
Ваш работодатель не может заставить вас стать хорошим программистом, а зачастую он даже не может оценить, насколько хороши вы как программист. Если вы хотите стать отличным программистом, вы отвечаете за это сами. Это зависит от вашего характера.
Как только вы решили стать отличным программистом, перед вами открываются широкие перспективы. Исследования показывают, что лучшие программисты создают программы в 10 раз быстрее, чем их менее квалифицированные коллеги. Время, уходящее на отладку кода, а также объем и быстродействие итоговой программы, уровень ошибок и число обнаруженных ошибок также различаются примерно в 10 раз (Sackman, Erikson, and Grant, 1968; Curtis,1981; Mills, 1983; DeMarco and Lister, 1985; Curtis et al., 1986; Card, 1987; Valett andMcGarry, 1989).
Вы ничего не сделаете со своим интеллектом, но вы можете изменить свой характер — именно от характера зависит, станете ли вы превосходным программистом.
Интеллект и скромность
Чтобы стать экспертом в практической или научной области, нужны огромный труд и долгое время. Если человек добросовестно трудится каждый час рабочего дня, когда-нибудь он проснется одним из самых компетентных специалистов своего поколения.
Уильям Джеймс (William James)
Интеллект не кажется чертой характера и на самом деле не является им. Высочайший уровень интеллекта — далеко не главное условие для человека, желающего стать хорошим программистом.
И что? Для этого не нужно быть суперинтеллектуальным?
Нет, не нужно. Никто не обладает достаточным для программирования уровнем интеллекта. Чтобы полностью охватить и понять сразу все детали даже средней программы, человек должен был бы обладать почти неограниченными возможностями. Способ использования интеллекта важнее, чем его уровень.
Как было сказано в главе 5, лекцию, посвященную получению премии Тьюринга в 1972 году, Эдсгер Дейкстра назвал «The Humble Programmer» («Скромный программист»). Дейкстра заявил, что большинство аспектов программирования являет собой попытки компенсации строго ограниченных способностей разума. Самые лучшие программисты — те, кто понимают, насколько ограничены их возможности. Они скромны. Худшие программисты отказываются признать, что их способности не соответствуют задаче. Характер не позволяет им стать отличными программистами. Чем усерднее вы работаете над компенсацией ограниченных возможностей своего разума, тем лучше будете программировать. Быстрота вашего развития напрямую зависит от вашей скромности.
Многие методики эффективного программирования призваны снизить нагрузку на мозг. Вот несколько примеров.
Цель «декомпозиции» системы — сделать систему проще для понимания.
Обзоры, инспекции и тестирование представляют собой способы компенсации ожидаемых человеческих оплошностей. Эти методики обзоров возникли как часть «обезличенного программирования» (Weinberg, 1998). Если бы мы никогда не совершали ошибок, нам не нужно было бы выполнять обзоры своего кода. Однако наши интеллектуальные способности ограничены, поэтому мы дополняем их способностями других людей.
Ограничение объема методов снижает нагрузку на ум.
Написание программ в терминах проблемной области, а не низкоуровневых деталей реализации, преследует ту же цель.
Использование всевозможных конвенций освобождает разум от забот о банальных аспектах программирования, не приносящих особой пользы.
Возможно, вы думаете, что было бы благороднее развить умственные способности и отказаться от этих костылей. Возможно, вам кажется, что программист, использующий умственные костыли, идет окольными путями. Однако эмпирически было показано, что скромные программисты, компенсирующие свои недостатки, пишут более понятный код, содержащий меньше ошибок. Настоящий окольный путь — это путь ошибок и сорванных планов.
Любопытство
Как только вы признали, что ваши способности слишком малы для понимания большинства программ, и поняли, что эффективное программирование — это поиск способов компенсировать данный недостаток, вы начинаете этот поиск, продолжающийся вплоть до окончания карьеры. А поэтому важная черта характера программиста — любопытство к техническим вопросам. Релевантная техническая информация постоянно изменяется. Многим Web-программистам никогда не приходилось программировать для Microsoft Windows, а многие разработчики программ для Windows никогда не имели дела с DOS, UNIX или перфокартами. Специфические особенности технической среды изменяются каждые 5—10 лет. Если вы недостаточно любопытны для того, чтобы не отставать от изменений, вы рискуете разделить участь динозавров.
Программисты часто так заняты работой, что у них не остается времени на изучение более эффективных способов работы. Если это относится и к вам, вы не одиноки. Ниже я расскажу, как развить любопытство и сделать обучение приоритетом.
Изучите процесс разработки Чем больше вы узнаете о процессе разработки ПО из книг или на собственном опыте, тем лучше будете понимать изменения и тем эффективнее вести свою группу в правильном направлении.
Если ваша работа состоит исключительно из краткосрочных заданий, не способствующих развитию навыков, подумайте, как исправить эту ситуацию. Если вы работаете на конкурентном рынке ПО, половина ваших знаний устареет за три года. Без обучения вы превратитесь в ископаемое.
Не тратьте время, работая на компанию, не учитывающую ваших интересов. Несмотря на экономические подъемы и спады и перемещение некоторых рабочих мест в другие регионы, ожидается, что среднее число рабочих мест, связанных с программированием, за период с 2002 до 2012 года в США значительно увеличится. Ожидается, что число должностей системных аналитиков вырастет примерно на 60%, а разработчиков ПО — примерно на 50%. Что касается всех должностей, связанных с компьютерами, то в дополнение к 3 миллионам имеющихся рабочих мест за это время будет создано еще около 1 миллиона мест (Hecker, 2001; BLS, 2004). Если работа не способствует вашему развитию, найдите другую работу.
Экспериментируйте Экспериментирование с процессами программирования и разработки — эффективный способ самообразования. Если вы не знаете, как работает какая-то возможность языка, напишите небольшую программу и узнайте. Создайте прототип. Изучите выполнение программы в отладчике. Гораздо лучше написать короткую программу для проверки какой-то возможности, чем создать большую программу, реализовав в ней возможность, которую вы не совсем понимаете.
А если короткая программа показывает, что какая-то функция работает не так, как вы хотите? Этого-то вам и нужно! Лучше обнаружить это в небольшой программе, чем в большой. Быстро совершая ошибки и извлекая из них уроки, вы облегчите себе путь к эффективному программированию. Ошибка — не грех. Неспособность к обучению на основе ошибок — вот что такое грех.
Читайте о решении проблем Решение проблем — главный аспект создания ПО. Эксперименты показали, что люди не всегда находят эффективные стратегии решения проблем сами, хотя легко обучаются этим стратегиям (Simon, 1996).
Так что, даже если вы хотите изобрести колесо, успех не гарантирован — ваше колесо может оказаться квадратным.
Анализируйте и планируйте, прежде чем действовать Анализ и действие несколько противоречат друг другу. В какой-то момент вы должны прекратить сбор данных и начать действовать. Однако проблемой большинства программистов является не избыточный анализ. Как правило, чаша действия значительно перевешивает чашу анализа, и проблема «аналитического паралича» крайне редко угрожает программистам.
Изучайте успешные проекты Особенно хороший способ самообразования — изучение опыта лучших программистов. Джон Бентли (Jon Bentley) считает, что вы должны иметь возможность сесть в кресло со стаканом бренди и сигарой и читать программу, как хороший рассказ. Это не так неестественно, как кажется. Большинству людей не хотелось бы тратить свободное время на анализ 500-страничного листинга, но многим вполне понравилось бы изучить высокоуровневый проект кода и погрузиться в некоторые тонкости.
При разработке ПО крайне редко используются данные о прошлых успехах и неудачах. Если бы вас интересовала архитектура, вы изучили бы чертежи Луиса Салливана, Фрэнка Ллойда Райта и других известных архитекторов. Возможно, вы посетили бы спроектированные ими здания. Если бы вас интересовало проектирование строительных конструкций, вы изучили бы мосты Brooklyn Bridge, Tacoma Narrows Bridge и другие структуры из бетона, стали и дерева. Вы изучили бы примеры успехов и неудач в своей отрасли.
Томас Кун указывает на то, что частью любой зрелой науки является набор удачных решений проблем, которые можно использовать в качестве образцов при последующей работе (Kuhn, 1996). Разработка ПО только начинает приближаться к этому уровню зрелости. В 1990 году организация Computer Science and Technology Board пришла к выводу, что задокументированных исследований успехов и неудач в отрасли разработки ПО мало (CSTB, 1990).
В журнале «Communications of the ACM» приводятся доводы в пользу обучения на основе исследований конкретных проблем программирования (Linn and Clancy, 1992). Это кое о чем говорит. То, что один из самых популярных разделов в компьютерных журналах — «Programming Pearls» — был создан на основе исследований конкретных случаев проблем программирования, также наводит на мысли. А одна из самых популярных книг по разработке ПО — «Мифический человеко-месяц» — основана на исследовании управления проектом разработки IBM OS/360.
Имеется ли у вас книга, включающая исследования конкретных проблем программирования, или нет, ищите код, написанный лучшими программистами, и читайте его. Постарайтесь изучить код программистов, которых вы уважаете. Взгляните на код программистов, которых вы не уважаете. Сравните их варианты кода между собой и со своим собственным. Каковы различия? Почему код различается? Какой вариант лучше? Почему?
Не ограничивайтесь чтением кода других программистов — старайтесь также узнать, что эксперты думают о вашем коде. Найдите высококлассных программистов, которые согласились бы покритиковать ваш код. Слушая критику, игнорируйте аспекты, связанные с их субъективными взглядами, и сосредоточьтесь на важных моментах. После этого измените свой подход к программированию так, чтобы он стал еще лучше.
Читайте! У многих программистов документация вызывает страх. Очень часто она плохо написана и организована, и все же преодоление «документофобии» может принести большую пользу. Документация — это ключ к замку ПО, и ее чтение никогда не бывает пустой тратой времени. Игнорирование имеющейся информации стало настолько частым явлением, что привело к возникновению специального акронима «RTFM!», который расшифровывается как «Read the !#*%*@ Manual!»
Почти все современные языки дополняются огромным объемом библиотечного кода. Время, потраченное на изучение документации к библиотекам, будет хорошей инвестицией. Скорее всего компания, разработавшая данную версию языка, уже создала массу нужных вам классов. Если это так, приложите все усилия, чтобы ознакомиться с ними. Просматривайте документацию примерно каждые два месяца.
Читайте другие книги и периодические издания Похвалите себя за чтение этой книги. За это время вы продвинулись вперед гораздо дальше, чем большинство ваших коллег, потому что объем этой книги превышает годичный объем чтения большинства программистов (DeMarco and Lister, 1999). Неторопливое, но регулярное чтение — надежный путь к высоким профессиональным достижениям. Если, читая примерно по 35 страниц в неделю, вы будете прочитывать одну хорошую книгу по программированию каждые два месяца, скоро вы получите основательный багаж знаний и начнете выгодно отличаться почти от всех окружающих вас разработчиков.
Общайтесь с единомышленниками Познакомьтесь с другими людьми, стремящимися улучшить навыки разработки ПО. Посещайте конференции, вступите в группу пользователей, общайтесь на Интернет-форумах.
Постоянно стремитесь к профессиональному развитию Хорошие программисты всегда ищут возможности дальнейшего совершенствования. Обдумайте следующую лестницу профессионального развития, используемую в моей и нескольких других компаниях.
Уровень 1: начало Новичок — это программист, способный использовать базовые возможности одного языка. Такой человек может писать классы, методы, циклы и условные операторы, а также использовать многие средства, поддерживаемые языком.
Уровень 2: средний уровень Программист среднего уровня прошел начальный этап, может использовать базовые возможности нескольких языков и очень хорошо владеет по меньшей мере одним языком.
Уровень 3: компетентность Компетентный программист обладает экспертными знаниями языка, среды или того и другого. Программист этого уровня может знать все тонкости J2EE или помнить все аннотированное справочное руководство по C++. Такие программисты очень ценны для работодателей, и многие из программистов никогда не поднимаются выше этого уровня.
Уровень 4: лидерство Лидер имеет квалификацию программиста 3-го уровня и понимает, что программирование на 85% состоит из общения с людьми и лишь на 15% — из общения с компьютером. Средний программист только 30% времени работает в одиночку (McCue, 1978) и еще меньше времени тратит на взаимодействие с компьютером. Гуру программирования пишут код для людей, а не для машин. Истинные гуру пишут абсолютно ясный код, не забывая при этом комментировать его. Они не хотят тратить свои драгоценные умственные ресурсы на восстановление логики какого-то фрагмента кода, если ее можно было бы легко понять, прочитав краткий комментарий.
Прекрасный программист, не уделяющий должного внимания удобочитаемости кода, вероятно, сможет достичь лишь уровня 3, да и то в самом лучшем случае. Судя по моему опыту, главная причина нечитабельности кода в том, что код плох. Никто не говорит себе: «Мой код плох, поэтому я сделаю его непонятным». Программисты просто не понимают свой код достаточно хорошо, чтобы сделать его удобочитаемым, и это запирает их на одном из более низких уровней.
Самый худший код, который я когда#либо видел, написала женщина, никому не позволявшая изучать ее программы. В конце концов начальник пригрозил ей увольнением, если она не будет сотрудничать с коллегами. В ее коде полностью отсутствовали комментарии, но зато в избытке имелись глобальные переменные с именами вроде x, xx, xxx, xx1 иxx2. Начальник ее начальника считал ее отличным программистом, потому что она быстро исправляла ошибки. Качество ее кода предоставило ей массу возможностей продемонстрировать свой талант исправления ошибок на деле.
Быть программистом начального или среднего уровня — не грех. Быть компетентным программистом, а не лидером, также не грех. Но если вы знаете, что нужно делать для собственного развития, и ничего не предпринимаете, иначе как грехом это назвать нельзя.
Профессиональная честность
Становление высококвалифицированного программиста предполагает развитие обостренного чувства профессиональной честности, которая может проявляться в самых разных формах:
— отказ от притязаний на роль эксперта, если вы им не являетесь;
— охотное признание собственных ошибок;
— стремление разобраться в предупреждениях компилятора вместо их отключения;
— желание ясно понять программу и отказ от компиляции кода с той лишь целью, чтобы узнать, работает ли он;
— предоставление реалистичных отчетов о статусе проекта;
— предоставление реалистичных оценок срока выполнения проекта и отстаивание своей позиции, даже если руководители просят адаптировать оценку.
Два первых элемента этого списка — признание собственных недостатков и ошибок — можно считать отголосками интеллектуальной скромности, рассмотренной выше. Как вы узнаете что-то новое, если будете считать, что уже все знаете? Если на то пошло, гораздо лучше считать, что вы ничего не знаете. Прислушивайтесь к мнениям людей и учитесь у них, но старайтесь при этом понять, действительно ли они знают, что говорят.
Оценивайте степень своей уверенности в тех или иных суждениях. Если вы обычно уверены в них на 100%, это предупреждающий знак.
Отказ от признания ошибок — особенно вредная привычка. Если Салли отказывается признать ошибку, она, очевидно, считает, что сможет убедить в этом окружающих, но на самом деле имеет место обратное. Все будут знать, что ошибку допустила Салли. Ошибки — естественный результат подъемов и спадов сложных интеллектуальных процессов, и если
Салли не была небрежной, никто не будет ее ни в чем упрекать.
Если она отказывается признать ошибку, она сможет одурачить только одного человека — себя. Что касается ее коллег, то они поймут, что они работают с надменным и не совсем искренним программистом. Это уже не просто ошибка, а нечто худшее. Если вы совершили ошибку, признавайте это быстро и охотно.
Любой дурак способен отстаивать свои ошибки — большинство дураков именно так и делают.
Дейл Карнеги (Dale Carnegie)
Еще один распространенный недостаток — убежденность в понимании сообщений компилятора. Если вы не понимаете предупреждение компилятора или думаете, что понимаете, но вам не хватает времени, чтобы проверить свое предположение, к чему это приведет? Вероятно, в итоге вам придется решать проблему с нуля, тогда как компилятор буквально размахивал готовым решением перед вашим носом. Если меня просят помочь отладить программу, я спрашиваю, компилируется ли она без ошибок и предупреждений. Довольно часто программисты отвечают «да» и начинают объяснять симптомы проблемы. Я отвечаю: «Хм… Похоже на неинициализированный указатель, но компилятор должен был предупредить вас об этом». В ответ на это они заявляют: «О да, он предупреждал об этом, но мы думали, что это означает что-то другое». Совершив ошибку, вы едва ли сможете убедить людей в том, что она не ваша. Обмануть компьютер еще сложнее, так что не тратьте попусту свое время.
Похожий вид интеллектуальной небрежности имеет место тогда, когда вы не совсем понимаете свою программу и «просто компилируете ее, чтобы увидеть, будет ли она работать». Примером может служить запуск программы с целью определить, какое условие следует использовать: < или<=. На самом деле работоспособность программы в этой ситуации не играет никакой роли, потому что вы понимаете ее недостаточно хорошо, чтобы сказать, почему она работает. Помните: тестирование может указать только на наличие, но не на отсутствие ошибок. Если вы не понимаете программу, вы не сможете тщательно ее протестировать. Компиляция программы с целью «посмотреть, что будет» — предупреждающий знак. Это может означать, что вам нужно вернуться к проектированию или что вы приступили к кодированию, плохо понимая свои действия. Прежде чем компилировать программу, убедитесь, что вы хорошо понимаете ее.
На первые 90% кода приходятся первые 90% времени разработки. На оставшиеся 10% кода приходятся другие 90% времени разработки.
Том Каргилл (Tom Cargill)
Оценка статуса проекта — один из главных источников лжи в нашей работе. Программисты печально известны своими заявлениями, согласно которым на протяжении всей второй половины проекта программа неизменно «готова на 90%». Если вы плохо представляете ход работы над проектом, постарайтесь лучше разобраться в методах работы. Но если вы не говорите правду, потому что хотите угодить своим руководителям, это совсем другое дело. Как правило, руководители будут благодарны вам за объективные оценки статуса проекта, даже если эти оценки им не понравятся. Если ваши выводы обоснованы, высказывайте их лично и без всяких прикрас. Для координации процессов разработки руководителям нужна точная информация, и искреннее сотрудничество играет при этом очень важную роль.
С сообщением неверного статуса проекта связана неверная оценка сроков выполнения проекта. Типичный сценарий таков: руководитель спрашивает у Берта, сколько времени потребуется на разработку новой БД. Берт беседует с программистами, подсчитывает некоторые показатели, возвращается и говорит, что над проектом должны будут работать восемь программистов в течение шести месяцев. Руководитель говорит: «Нас это не устраивает. Можно ли выполнить проект быстрее и с меньшим числом программистов?» Берт уходит, думает и решает, что он мог бы сократить время обучения и отпуска и попросить каждого из программистов поработать сверхурочно. Он возвращается и говорит, что проект будет реализован шестью программистами за четыре месяца. Руководитель заявляет: «Отлично. Это довольно низкоприоритетный проект, поэтому постарайтесь выполнить его точно вовремя: мы не справимся с дополнительными расходами».
К сожалению, Берт не учел, что оценка не может являться предметом переговоров. Он может пересмотреть оценку и сделать ее более точной, но переговоры с руководителем не повлияют на время, необходимое для реализации проекта. Билл Ваймер из IBM однажды заявил: «Мы обнаружили, что технические специалисты в целом очень точно оценивали требования, предъявляемые к проектам, и сроки их реализации. Но они не могли защитить свои решения — им нужно научиться отстаивать свое мнение» (Weimer в Metzger and Boddie, 1996). Пообещав выполнить проект за четыре месяца и выполнив за шесть, Берт едва ли обрадует своего руководителя сильнее, чем пообещав выполнить проект за шесть месяцев и сдержав свое слово. Не сдержав обещания, Берт потеряет доверие, а отстаивая свою позицию, лишь заслужит уважение.
Если руководство давит на вас, желая услышать более приемлемую оценку, дайте понять, что окончательное решение о том, следует ли браться за проект, остается за ними: «Смотрите: вот сколько это будет стоить. Я не знаю, приемлема ли такая цена для компании, — это ваша работа. Но я могу сказать, сколько времени потребуется для разработки ПО, — это моя работа. Обсуждать сроки в данном случае неуместно: это все равно что обсуждать, сколько футов в миле. Мы не можем пересмотреть законы природы. Однако мы можем пересмотреть другие аспекты проекта, влияющие на срок его выполнения, и переоценить его. Мы можем отказаться от некоторых возможностей, снизить производительность, выполнить проект инкрементно, а также привлечь к работе меньшее число людей и установить более длительный срок выполнения проекта или наоборот: привлечь больше разработчиков и реализовать проект быстрее».
Один из самых ужасных советов я получил на лекции об управлении проектами разработки ПО. Лектором был автор бестселлера по управлению проектами. Один из присутствующих спросил: «Что вы делаете, если руководители просят оценить срок выполнения проекта, но вы знаете, что если вы сообщите верную оценку, они откажутся от проекта?» Лектор ответил, что в такой щекотливой ситуации следует склонить руководителей к реализации проекта, недооценив его. Он сказал, что, как только руководители инвестируют средства в первую часть проекта, им придется довести его до конца.
Абсолютное заблуждение! Начальство отвечает за управление компанией в целом. Если какая-то функция программы обойдется компании в 250 000 долларов, а вы оцените ее в 750 000, разрабатывать программу не следует. Принимать такие решения должны руководители. Когда лектор отстаивал недооценку проекта, он отстаивал скрытое воровство власти у руководителей. Если вы считаете, что проект интересен, открывает перед компанией новые возможности или позволяет многому научиться, так и скажите. Руководители тоже способны взвесить эти факторы. Но подталкивание их к неверным решениям может стоить компании сотен тысяч долларов. Если из#за этого вы лишитесь работы, пеняйте на себя.
Общение и сотрудничество
По-настоящему отличные программисты учатся эффективно сотрудничать, что всегда подразумевает написание удобочитаемого кода. Вероятно, компьютер читает вашу программу так же часто, как другие люди, но он читает плохой код гораздо лучше, чем люди. Работая над кодом, не забывайте про людей, которым придется изменять его в будущем. Программирование — это в первую очередь общение с другим программистом и только во вторую — с компьютером.
Творчество и дисциплина
Закончив институт, я считал себя лучшим программистом в мире. Я мог разработать непобедимый алгоритм игры в крестики-нолики, владел пятью разными языками и мог писать программы из 1000 строк, которые РАБОТАЛИ (в самом деле!). Затем я очутился в Реальном Мире. Первая моя задача в Реальном Мире требовала, чтобы я разобрался в программе из
200 000 строк, написанной на Фортране, и ускорил ее в два раза. Любой Реальный Программист скажет вам, что никакие методики Структурного Кодирования никогда не помогут решить подобную проблему — для этого требуется настоящий талант.
Эд Пост (Ed Post)
Выпускнику института трудно объяснить важность конвенций и дисциплины. Самая крупная программа, написанная мной в институте, состояла примерно из 500 строк исполняемого кода. За свою профессиональную карьеру я написал десятки утилит, включающих менее 500 строк, однако в среднем мои проекты содержали от 5000 до 25 000 строк, а объем некоторых проектов, в которых я принимал участие, достигал полумиллиона строк. Подобные проекты требуют не тех же навыков в более крупном масштабе, а совершенно иных навыков.
Некоторые программисты считают, что стандарты и конвенции подавляют свободу творчества, но с этим трудно согласиться. Можете ли вы представить Web-сайт, на каждой странице которого использовались бы разные шрифты, цвета, способы выравнивания текста, графические стили и способы навигации? Какое уж тут творчество — это хаос. Если стандарты и конвенции не используются в крупном проекте, завершить его становится невозможно. Не тратьте свою творческую энергию на то, что не играет никакой роли. Установите конвенции для второстепенных областей и сосредоточьтесь на действительно важных аспектах.
Анализируя 15-летний опыт работы в Лаборатории проектирования ПО NASA, Макгарри и Паджерски пришли к выводу, что особенно эффективными были методики и инструменты, акцентированные на дисциплине (McGarry and Pajerski, 1990). Многие в высшей степени творческие люди отличаются крайней дисциплинированностью. «Форма освобождает», — гласит пословица. Прекрасные архитекторы и художники работают в условиях ограниченности физических материалов, времени и расходов. Любой, кто изучал произведения Леонардо да Винчи, не может не восхищаться его дисциплинированным вниманием к подробностям. Перед росписью свода Сикстинской капеллы Микеланджело разделил его на симметричные наборы геометрических фигур, таких как треугольники, окружности и прямоугольники. Он разделил свод на три зоны в соответствии с тремя этапами Платона. Без этой структуры и дисциплины 300 человеческих фигур были бы просто хаотично разбросанными фрагментами, а не согласованными элементами художественного шедевра.
Создание шедевра программирования требует не меньшей дисциплины. Если вы не проанализируете требования и проект до начала кодирования, многие знания вам придется приобретать во время кодирования, и результат вашей работы будет больше напоминать мазню трехлетнего ребенка, а не произведение искусства.
Лень
Лень – качество, которое заставляет прилагать больше усилий для снижения общих затрат энергии. Она заставляет писать программы, облегчающие труд, и документировать написанное, чтобы вам не пришлось отвечать на лишние вопросы.
Ларри Уолл (Larry Wall)
Лень может проявляться несколькими способами:
— отсрочка выполнения неприятной задачи;
— немедленное выполнение неприятной задачи с целью как можно более быстрого избавления от нее;
— написание инструмента для выполнения неприятной задачи, чтобы ее никогда не пришлось выполнять снова.
Одни проявления лени лучше, другие — хуже. Первое едва ли когда#нибудь бывает выгодным. Наверное, и вы когда-то тратили несколько часов на выполнение необязательных задач, желая отсрочить решение относительно неважной задачи, избежать которой тем не менее вы не могли. Я ненавижу ввод данных, и многие программы требуют ввода небольшого объема данных. Я иногда откладываю работу над программой на несколько дней только затем, чтобы отсрочить неизбежный ввод нескольких страниц чисел вручную. Это «истинная лень». Она проявляется и в компиляции класса с целью проверки его работоспособности и избавления от проверки класса в уме.
Небольшие задачи никогда не бывают такими плохими, какими кажутся. Вы сможете избавиться от первого типа лени, если выработаете привычку выполнять эти задачи сразу. Эта привычка соответствует второму типу лени — «просвещенному». Вы все так же ленитесь, но решаете неприятные проблемы, тратя на них как можно меньше времени.
Третий вариант лени предполагает написание инструмента для выполнения неприятной задачи. Это «долговременная лень». Несомненно, это самый продуктивный вид лени (если, конечно, инструмент позволяет в итоге сэкономить время). В этом контексте определенная лень даже выгодна.
Однако лень имеет и обратную сторону. «Спешка» и «усилия» ценятся в программировании совсем не так высоко, как на уроках физкультуры. Спешка — это дополнительные, ненужные усилия. Она указывает на активность, но не на выполнение работы. Движение нетрудно спутать с прогрессом, а занятость с продуктивностью. Главную роль в эффективном программировании играет мышление, а размышляющие люди обычно не кажутся занятыми. Если бы я видел, что какой-то программист постоянно занят, я подумал бы, что он — неважный программист, потому что он не использует свой наиболее ценный инструмент, которым, как известно, является голова.
Свойства, которые менее важны, чем кажется
Помимо спешки есть и другие свойства, уместные в других областях жизни, но не особо эффективные при разработке ПО.
Настойчивость
Как и большинство подобных субъективных понятий, настойчивость в зависимости от обстоятельств может быть и достоинством, и недостатком и обозначается разными словами. Если вы хотите считаете ее плохим качеством, вы называете ее «упрямством», а то и «ослиным упрямством». Если вы желаете придать ей хороший оттенок, можете назвать ее «упорством».
Как правило, при разработке ПО настойчивость принимает форму ослиного упрямства, т. е. пользы не приносит. Настойчивое стремление довести код до ума с использованием одного подхода трудно признать достоинством. Попробуйте перепроектировать класс, перепишите код или вернитесь к проблеме позже. Если один подход не работает, самое время испытать другой (Pirsig, 1974).
Во время отладки иногда очень увлекательно отслеживать надоедливую ошибку четыре часа, но, если в течение какого-то времени (скажем, 15 минут) вы не добиваетесь прогресса, обычно лучше отложить поиск ошибки. Позвольте своему подсознанию немного поработать над проблемой.
Попробуйте подумать об альтернативном подходе, который вообще устранил бы проблему. Перепишите проблемный фрагмент кода с нуля. Вернитесь к нему со свежей головой. В борьбе с компьютерными проблемами нет ничего благородного. Лучше их избегать.
Трудно сказать, когда отложить работу, но очень важно, чтобы вы спрашивали себя об этом. Если вы чувствуете замешательство, задайте себе этот вопрос. Это не всегда означает, что пришло время сдаться, однако скорее всего это значит, что пора установить некоторые временные параметры: «Если я не решу эту проблему с использованием этого подхода в следующие полчаса, я проведу 10-минутный „мозговой штурм“ в поиске других подходов и попробую в течение следующего часа самый лучший из них».
Опыт
По ряду причин важность практического опыта в сравнении с книжным образованием в области разработки ПО не столь велика, как во многих других областях.
Вдругих областях базовые положения изменяются довольно медленно, вследствие чего люди, закончившие вуз с интервалом в 10 лет, обладают по сути одинаковы# ми знаниями. В отрасли разработки ПО даже основы претерпевают быстрые из# менения. Человек, закончивший вуз через 10 лет после вас, вероятно, будет знать вдвое больше об эффективных методиках программирования. К программистам старшего возраста относятся с подозрением не только потому, что они якобы не имеют представления об отдельных технологиях, а потому, что они, возможно, никогда и не сталкивались с базовыми концепциями программирования, распространившимися после того, как они закончили вуз.
В других областях текущие знания человека о работе будут служить ему и завтра. Что до разработки ПО, то, если программист неспособен пересматривать привычные способы мышления, приобретенные им при использовании предыдущего языка программирования, или методики оптимизации кода, работавшие на старом компьютере, наличие опыта окажется худшим вариантом, чем его полное отсутствие. Многие программисты тратят время на подготовку к завершившейся битве, а не предстоящей. Если вы не изменяетесь вместе со временем, опыт скорее вредит, чем помогает.
Кроме того, опираясь на собственный опыт, люди часто делают неверные выводы. Трудно объективно оценить свою жизнь. Вы можете упустить из виду ключевые элементы своего опыта, которые подтолкнули бы вас к другим выводам, если бы вы их учли. В этом смысле могут помочь книги о работе других программистов, потому что так вы узнаете опыт других людей, достаточно очищенный, чтобы его можно было изучить объективно.
Стоит упомянуть также абсурдное внимание к объему опыта программистов. «Нам нужен программист, обладающий 5-летним опытом программирования на C» — глупое высказывание. Если программист не изучил C за год или два, еще три года не сыграют особой роли. Подобный вид «опыта» очень слабо связан с производительностью труда.
Быстрые изменения информации в сфере программирования создают странную динамику в области «опыта». Во многих отраслях специалист, имеющий за плечами массу успехов и достижений, может расслабиться и наслаждаться заслуженным уважением. В то же время знания расслабившегося программиста очень быстро устаревают. Чтобы поддерживать компетентность, вы должны идти в ногу со временем. Для молодых и энергичных программистов это преимущество. Более пожилые программисты иногда чувствуют, что они уже заслужили свои эполеты, и возмущаются, когда их год за годом принуждают подтверждать квалификацию.
Главное то, что опыт может иметь разное качество. Если вы работаете 10 лет, получаете ли вы 10 лет опыта или 1 год опыта 10 раз? Чтобы приобрести истинный опыт, вы должны действовать с умом. Если вы постоянно учитесь, вы приобретаете опыт. Если вы не учитесь, о приобретении опыта не может быть и речи, как бы долго вы ни работали.
Страсть к программированию
Если вы не проводили хотя бы месяц, работая над одной программой — работая по 16 часов в день, грезя о ней в остальные 8 часов беспокойного сна, работая несколько ночей подряд над устранением из программы «одной последней ошибки», — вы не писали сложную компьютерную программу. Тогда вам трудно понять, что в программировании есть что%то захватывающее.
Эдвард Йордон (Edward Yourdon)
Настолько щедрая дань богам программирования — едва ли не самый верный путь к неудаче. Ночные бдения позволят вам на какое-то время почувствовать себя самым великим программистом в мире, но потом вам придется потратить несколько недель на исправление дефектов, внесенных в код в безудержном порыве. Во что бы то ни стало вызовите у себя увлечение программированием, но помните, что увлечение никогда не заменит компетентности.
Привычки
Следовательно, нравственные добродетели существуют в нас не от природы и не вопреки природе… а благодаря приучению мы в них совершенствуемся… Ибо если нечто следует делать, пройдя обучение, то учимся мы, делая это… Хорошо строя дома, люди станут добрыми зодчими, а строя худо — худыми… Так что вовсе не мало, а очень много, пожалуй, даже все зависит от того, к чему именно приучаться с самого детства.
Аристотель
Выработать хорошие привычки крайне важно, потому что очень многое из того, что вы делаете как программист, вы делаете не задумываясь. Например, когда-то вы могли думать о форматировании циклов, но вы не думаете об этом при написании каждого нового цикла. Вы пишете их как привыкли. Это относится почти ко всем аспектам форматирования кода. Когда вы в последний раз всерьез задумывались о своем стиле форматирования? Если вы программируете около пяти лет, скорее всего четыре с половиной года назад. Позднее вы просто следовали привычке.
Привычки связаны со многими областями. Так, программисты обычно тщатель# но проверяют индексы циклов и не проверяют операторы присваивания, из#за чего ошибки в операторах присваивания гораздо сложнее искать, чем ошибки индек# сов циклов (Gould, 1975). Вы отвечаете на критику дружелюбно или недружелюбно. Вы всегда стремитесь сделать код удобочитаемым или быстрым или не обращае# те на это никакого внимания. Если при выборе между написанием быстрого или удобочитаемого кода вы каждый раз делаете один и тот же выбор, вы на самом деле не выбираете — вами движет привычка.
Взгляните на изречение Аристотеля еще раз и замените слова «нравственные добродетели» на «программистские добродетели». Аристотель утверждает, что вы не предрасположены ни к хорошему, ни к плохому поведению, поэтому вы можете стать как хорошим, так и плохим программистом. Главным способом становления хорошим или плохим в своей области является сама деятельность: строительство в случае строителей и программирование в случае программистов. То, что вы делаете, становится привычкой, и со временем именно привычки начинают определять, хороший вы программист или плохой.
Билл Гейтс говорит, что любой программист, который впоследствии станет хорошим, хорош уже в первые несколько лет. После этого измениться практически невозможно (Lammers, 1986). Если вы программируете уже много лет, вряд ли вы внезапно зададитесь вопросом: «Как я делаю этот цикл быстрее?» или «Как я делаю этот код более удобочитаемым?» Это привычки, которые хорошие программисты вырабатывают на самых ранних стадиях обучения.
Обучаясь делать что-то, сразу учитесь делать это правильно. В первый раз вы активно обдумываете свои действия и все еще можете с легкостью изменить свой подход. Выполнив что-то несколько раз, вы начинаете уделять меньше внимания своим действиям, и «сила привычки» берет свое. Проверяйте, что вы приобретаете именно те привычки, какие хотите.
Что, если вы еще не выработали самые эффективные привычки? Как изменить плохую привычку? Будь у меня окончательный ответ на этот вопрос, я бы продавал видеокассеты с записями курсов самопомощи!.. Но один стоящий совет я дам. Вы не можете заменить плохую привычку на отсутствие привычки. Именно поэтому люди, пытающиеся бросить курить, сквернословить или переедать, испытывают огромные затруднения, пока не заменят старую привычку на какую-то другую, например, жевание жевательной резинки. Легче заменить старую привычку на новую, чем полностью избавиться от привычки. Таким образом, попробуйте выработать новые, эффективные привычки. Например, выработайте привычку писать класс на псевдокоде перед кодированием или тщательно читать код перед его компиляцией. Тогда вам не придется беспокоиться об избавлении от плохих привычек — они естественным путем будут вытеснены новыми привычками.
Дополнительные материалы
«Человеческому фактору» в разработке ПО также посвящены следующие материалы.
Dijkstra, Edsger. «The Humble Programmer.» Turing Award Lecture. Communications of the ACM 15, no. 10 (October 1972): 859 Эта классическая работа способствовала началу исследования степени зависимости программирования от умственных способностей программиста. Дейкстра постоянно подчеркивает мысль, что основная задача программирования — обуздание огромной сложности компьютерных наук. Он утверждает, что программирование является единственной профессией, представителям которой приходится иметь дело с девятью порядками разницы между самым низким и самым высоким уровнями детальности. Многие мысли Дейкстры свежи и по сей день, однако эту работу интересно прочитать хотя бы только из-за ее исторического значения. Вы почувствуете, что значило быть программистом на ранних этапах развития вычислительной техники.
Weinberg, Gerald M. The Psychology of Computer Programming: Silver Anniversary Edition. New York, NY: Dorset House, 1998. В этой классической книге подробно рассматривается идея обезличенного программирования и другие аспекты человеческой стороны программирования. Она содержит много увлекательных историй и является одной из самых увлекательных книг, посвященных разработке ПО.
Pirsig, Robert M. Zen and the Art of Motorcycle Maintenance: An Inquiry into Values. William Morrow, 1974. Пирсиг подробно обсуждает «качество» в контексте обслуживания мотоциклов. Во время написания этой книги Пирсиг работал техническим писателем в отрасли программирования, и его проницательные комментарии относятся к психологии программирования в не меньшей степени, чем к обслуживанию мотоциклов.
Curtis, Bill, ed. Tutorial: Human Factors in Software Development. Los Angeles, CA: IEEE Computer Society Press, 1985. Это великолепная подборка статей, посвященных человеческим аспектам создания программ. 45 статей разделены на следующие категории: психологические модели знаний о программировании, обучение программированию, решение проблем и проектирование, следствия репрезентаций проектирования, характеристики языка, диагностика ошибок и методология. Если программирование — одна из самых сложных интеллектуальных задач в истории человечества, программисты просто обязаны хорошо разбираться в человеческих умственных способностях. Кроме того, эти статьи помогут вам узнать, как лично вы можете стать более эффективным программистом.
McConnell, Steve. Professional Software Development. Boston, MA: Addison-Wesley, 2004. В седьмой главе этой книги обсуждаются вопросы личности и характера программистов.
Ключевые моменты
Способность к написанию программ напрямую зависит от личного характера.
Важнейшие качества программиста — скромность, любопытство, профессиональная честность, творчество и дисциплина, а также «просвещенная» лень.
Чтобы стать отличным программистом, можно не обладать особым талантом, но необходимо постоянно стремиться к самосовершенствованию.
Удивительно, но интеллект, опыт и настойчивость вредят программистам не меньше, чем помогают.
Многие программисты не ведут активного поиска новых сведений и методик, а полагаются на случайные столкновения с новой информацией на работе. Если вы посвятите небольшую долю своего времени чтению книг и изучению программирования, через несколько месяцев вы будете намного превосходить почти всех своих коллег.
Хороший характер во многом — продукт правильных привычек. Если хотите стать великолепным программистом, выработайте правильные привычки, а все остальное придет само собой.
Поделиться: