Идеальный программист. Как стать профессионалом разработки ПО

Мартин Роберт С.

4

Написание кода

 

 

В предыдущей книге я подробно описал структуру и природу Чистого Кода. В этой главе будет рассмотрен сам акт написания кода, а также контекст, в котором он происходит.

Когда мне было 18 лет, я набирал текст достаточно быстро, но мне приходилось смотреть на клавиши. Я не умел печатать «вслепую». Однажды вечером я провел несколько часов за перфоратором IBM 029, стараясь не смотреть на клавиши во время набора программы, записанной на нескольких формулярах. После набора я проверил все перфокарты и выбросил те, которые содержали ошибки.

Сначала я ошибался довольно часто, но к концу вечера набор шел почти идеально. За этот долгий вечер я понял, что качество «слепой» печати в основном зависит от уверенности. Мои пальцы уже знали, где находятся клавиши; мне оставалось только набраться уверенности в том, что я не ошибаюсь. Среди прочего, мне помогало то, что я сразу ощущал, когда совершаю ошибку. К концу вечера я почти мгновенно распознавал ошибки ввода и просто выбрасывал испорченную перфокарту, не глядя на нее.

Умение интуитивно ощущать свои ошибки очень важно – не только при наборе текста, но и во всем остальном. «Чувство ошибки» означает, что вы очень быстро замыкаете цикл обратной связи и все быстрее учитесь на своих ошибках. С того дня, проведенного за перфоратором, я изучал – и успешно освоил – немало других дисциплин. И во всех случаях ключом к мастерству была уверенность в себе и «чувство ошибки».

В этой главе описан мой личный набор правил и принципов написания кода. Эти правила и принципы относятся не к самому коду, а к моему поведению, настроению и отношению. Они описывают мой умственный, моральный и эмоциональный контекст написания кода. В них кроются корни моей уверенности и «чувства ошибки».

Возможно, вы не согласитесь с чем-то из сказанного. В конечном счете все это сугубо личное мнение. Более того, какие-то принципы могут вызвать у вас яростный протест. И это нормально – они не являются абсолютными истинами для кого-то, кроме меня. В них отражены воззрения всего лишь одного человека на профессиональное программирование.

Возможно, изучая и обдумывая мои личные взгляды на написание кода, вы найдете в них что-то полезное для себя.

 

Готовность

 

Написание кода – интеллектуально сложное и утомительное занятие. Мало найдется других дисциплин, требующих такого уровня концентрации и внимания. Причина заключается в том, что при написании кода вам приходится жонглировать сразу несколькими взаимно противоречивыми факторами.

1. Прежде всего ваш код должен работать. Вы должны разобраться в сути решаемой проблемы и понять, как ее решать. Вы должны убедиться в том, что написанный код адекватно отражает решение. Вы должны проследить за каждой подробностью решения, не нарушая правил языка, платформы, текущей архитектуры и всех специфических особенностей текущей системы.

2. Ваш код должен решать задачу, поставленную заказчиком. Часто требования заказчика не отражают всего, что необходимо для решения его задачи. Вы должны понять это и обсудить с заказчиком, чтобы написанный код соответствовал истинным потребностям заказчика.

3. Ваш код должен хорошо вписываться в существующую систему. Он не должен приводить к повышению ее жесткости, непрочности или непрозрачности. Вы должны хорошо организовать управление зависимостями. Короче говоря, ваш код должен соответствовать принципам качественного проектирования.

4. Ваш код должен нормально читаться другими программистами. Проблема не сводится к написанию понятных комментариев. Скорее, вы должны строить код таким образом, чтобы в его структуре проявлялись ваши намерения. Сделать это непросто. Вполне возможно, что это самый сложный навык, которым должен овладеть программист.

Жонглировать всеми этими аспектами нелегко. Поддерживать необходимую концентрацию и внимание на протяжении длительного времени трудно хотя бы на физиологическом уровне. Добавьте к этому проблемы и раздражители, связанные с работой в группе и организации, а также заботы повседневной жизни. Как видите, отвлекающих факторов более чем достаточно.

Если вы не можете в достаточной степени сосредоточиться на своей работе, у вас получится плохой код. В нем будет много ошибок. Он будет иметь неверную структуру. Он получится запутанным и непрозрачным. Он не будет соответствовать истинным потребностям заказчика. Короче говоря, код придется перерабатывать или писать заново. Работа без сосредоточенности – напрасная трата времени.

Если вы устали или не можете сосредоточиться – не пишите код. Все равно написанное придется переделывать. Лучше подумайте, как устранить отвлекающие факторы и обрести душевное равновесие.

 

Ночное программирование

Худший код, созданный мной, был написан в 3 часа ночи. Это было в 1988 году, когда я работал в телекоммуникационной начинающей фирме Clear Communications. Мы проводили долгие часы за «трудовыми подвигами» – конечно, мечтая со временем разбогатеть.

Однажды очень поздним вечером (а вернее, очень ранним утром) для решения проблемы синхронизации я организовал отправку моим кодом сообщения самому себе через систему диспетчеризации событий (мы называли это «отправить почту»). Решение было неверным, но в 3 часа ночи оно казалось чертовски привлекательным. В самом деле, после 18 часов непрерывного программирования (не говоря уже о 60–70-часовой рабочей неделе) мне ничего другого в голову уже не приходило.

Помню, я очень гордился своей многочасовой работой. Помню, я ощущал свою целеустремленность. Помню, мне казалось, что работать в 3 часа ночи – удел настоящего профессионала. Как же я ошибался!

Этот код, словно бумеранг, возвращался к нам снова и снова. Он породил ошибочную архитектуру, которую использовали все и недостатки которой постоянно приходилось маскировать обходными решениями. Код приводил к появлению странных ошибок синхронизации и необъяснимых циклов обратной связи. Одно сообщение приводило к отправке другого, потом третьего – и так до бесконечности. У нас вечно не было времени на то, чтобы переписать эту халтуру (нам так казалось), но у нас всегда хватало времени для наложения очередной «заплатки». Мусор накапливался, а мой ночной код обрастал все большими последствиями и побочными эффектами. Через много лет эта история превратилась в популярную шутку нашей группы. Когда я уставал или впадал в отчаяние, коллеги говорили: «Смотрите! Боб собирается отправить себе почту!»

Мораль: не пишите код, когда вы устали. Преданность делу и профессионализм проявляются в дисциплине, а не в продолжительности работы. Обязательно следите за сном, здоровьем и образом жизни, чтобы вы могли ежедневно посвятить работе восемь хороших часов.

 

Программирование в расстроенных чувствах

Когда-нибудь пытались писать код после серьезной ссоры с женой или другом? Замечали, что у вас в мозгу запускается фоновый процесс, который пытается разрешить конфликт или по крайней мере припомнить его? Иногда давление этого фонового процесса ощущается в груди или где-то в животе. Вы ощущаете беспокойство, как если бы выпили слишком много кофе или диетической колы. И это отвлекает от работы.

Когда я беспокоюсь по поводу спора с женой, разногласий с заказчиком или болезни ребенка, я не могу сконцентрироваться на своей работе. Я ловлю себя на том, что глазею на экран, держа руки на клавиатуре, – и ничего не делаю. Кататония. Паралич. Я нахожусь за миллион миль от рабочего места, размышляя над своей фоновой проблемой, – вместо того чтобы заниматься своим прямым делом.

Иногда мне удается заставить себя думать о коде. Я принуждаю себя написать одну-две строки. Усилием воли добиваюсь прохождения одного-двух тестов. Но я не могу продолжить в том же духе. Неизбежно я снова прихожу в состояние оцепенелой бесчувственности, ничего не видя открытыми глазами, переживая свои фоновые неприятности.

Я узнал, что писать код в такие моменты бесполезно. Код, который я напишу, можно сразу отправлять в мусор. Вместо того чтобы работать над кодом, я должен сначала разобраться со своими проблемами.

Конечно, многие проблемы попросту не решаются за час или два. К тому же наши работодатели вряд ли смирятся с нашей неспособностью работать в то время, пока мы переживаем свои личные неурядицы. Значит, вы должны научиться завершать фоновый процесс или по крайней мере понижать его приоритет, чтобы он не отвлекал вас постоянно.

Я решаю эту проблему посредством распределения времени. Вместо того чтобы заставлять себя программировать, пока личные проблемы беспокоят меня, я выделяю специальное время (например, час) на причину. Если мой ребенок заболел, я звоню домой и справляюсь о его состоянии. Если я поссорился с женой, я звоню ей и обсуждаю наши разногласия. Если у меня проблемы с деньгами, я обдумываю возможное решение. Я знаю, что проблема вряд ли будет решена за этот час, но по крайней мере мне с большой вероятностью удастся снизить свое беспокойство и приглушить фоновый процесс.

В идеале на борьбу с переживаниями должно тратиться личное время. Стыдно тратить рабочее время подобным образом. Профессиональные разработчики тратят личное время для того, чтобы время на работе проводилось как можно продуктивнее. Следовательно, вы должны специально выделить время дома на решение своих проблем, чтобы не тащить их на работу. С другой стороны, если вы уже находитесь на работе, а тревожные мысли подрывают вашу производительность, лучше потратить час на их подавление, чем заставлять себя писать код, который позднее все равно будет выброшен (или еще хуже, с которым вам придется жить).

 

Зона потока

 

О сверхпроизводительном состоянии, называемом «потоком» (flow), написано много литературы. Некоторые программисты называют его «зоной». Как бы оно ни называлось, вероятно, вам знакомо это ощущение предельной концентрации сознания, в которое может войти программист при написании кода. В этом состоянии программисты ощущают себя сверхэффективными и непогрешимыми, поэтому они стремятся войти в это состояние, а их самооценка часто определяется тем, какая часть времени в нем проводится.

А теперь небольшой совет от того, кто неоднократно бывал в Зоне и возвращался из нее: Избегайте Зоны. На самом деле это состояние не настолько уж эффективно и, безусловно, не непогрешимо. Это всего лишь умеренно-медитативное состояние, в котором мыслительные способности снижаются ради ощущения скорости.

Позвольте мне высказаться более определенно. В Зоне можно написать больше кода. Если вы практикуете разработку через тестирование (TDD), то вы скорее преодолеете цикл «красный/зеленый/рефакторинг». И у вас появится легкая эйфория или чувство достижения цели. Проблема заключается в том, что во время нахождения в Зоне теряется часть «общей картины», поэтому вы скорее примете решения, которые вам позднее придется исправлять. Код быстрее пишется в Зоне, но вам придется чаще возвращаться к нему.

Теперь когда я чувствую, что мое сознание постепенно входит в Зону, я на несколько минут отхожу от края. Я стараюсь прояснить свои мысли: отвечаю на электронную почту, просматриваю твиты. Если время идет к полудню – я делаю обеденный перерыв. Если я работаю в группе, то нахожу кого-нибудь для парного программирования.

У парного программирования есть одно важное преимущество: паре практически невозможно войти в Зону. Состояние Зоны некоммуникативно, тогда как парная работа требует интенсивного, постоянного общения. В самом деле, одна из претензий к парному программированию как раз и заключается в том, что оно блокирует вхождение в Зону. Отлично! Зона – это не то место, где вам стоит находиться.

Вообще-то это не совсем так. В некоторых ситуациях Зона – именно то место, где вам стоит находиться. Когда вы тренируетесь! Но мы поговорим об этом в другой главе.

 

Музыка

Когда я работал в Teradyne в конце 1970-х, у меня была отдельная комната. Я был системным администратором нашей PDP 11/60, поэтому я был одним из нескольких программистов, имевших собственный терминал. Это был терминал VT100 со скоростью передачи данных 9600 бод, подключенный к PDP11 25 метрами кабеля RS232, который я лично прокладывал над подвесным потолком из офиса в машинный зал.

В моей комнате стояла стереосистема: старый проигрыватель, усилитель и динамики. У меня была довольно серьезная коллекция винила, включая Led Zeppelin, Pink Floyd, … В общем, вы поняли.

Обычно я включал свою стереосистему перед тем, как писать код. Мне казалось, что она способствует моей концентрации. Тем не менее я ошибался.

Однажды я просматривал модуль, который редактировал во время прослушивания начала «Стены». Комментарии в коде содержали слова из песни и упоминания о звуковых вставках: пикирующие бомбардировщики, плачущие дети и т. д. И тогда я понял: читатель такого кода намного больше узнает о музыкальной коллекции автора (меня самого), чем о задаче, для решения которой был написан этот код.

Мне стало ясно, что я просто не могу хорошо писать код во время прослушивания музыки. Музыка не помогает мне сосредоточиться. Более того, на само прослушивание расходуются ресурсы, необходимые моему мозгу для написания чистого, хорошо спланированного кода.

Возможно, у вас дело обстоит иначе. Возможно, вам музыка помогает писать код. Я знаю много людей, которые программируют в наушниках. Я допускаю, что музыка помогает им, но также подозреваю, что в действительности она лишь помогает им войти в Зону.

 

Помехи

Представьте, что вы программируете за рабочей станцией. Как вы отреагируете на заданный вопрос? Огрызнетесь? Смерите холодным взглядом? Ваш «язык тела» намекнет, что вы заняты? Короче, вы среагируете невежливо? Или вы прервете свою текущую работу и любезно поможете? Проявите ли вы такое же отношение, какое хотели бы видеть от других, если бы сами обратились к ним за помощью?

Невежливые ответы часто исходят из Зоны. Возможно, вас раздражает, что вас вытаскивают из Зоны или кто-то мешает вашим попыткам войти в Зону. Как бы то ни было, грубость часто объясняется вашей связью с Зоной.

В некоторых случаях виновником оказывается не Зона, а лично вы. Просто вы пытаетесь разобраться в сложном вопросе, требующем полной концентрации. У этой задачи есть несколько решений.

Парная работа отлично помогает справиться с помехами. Ваш напарник погружается в контекст задачи, а вы разбираетесь с телефонными звонками и вопросами коллег. Когда вы возвращаетесь к напарнику, он быстро помогает восстановить интеллектуальный контекст на момент до возникновения помехи.

Также большую помощь оказывает разработка через тестирование. Если какой-то тест не проходит, то он определяет текущий контекст вашей работы. Разобравшись с помехой, вы возвращаетесь к нему и продолжаете работать над устранением проблемы.

Разумеется, вам не удастся полностью избежать помех, которые неизбежно будут отвлекать вас и приводить к потерям времени. Вспомните, что в следующий раз помощь может понадобиться вам. Таким образом, профессионализм проявляется в вежливой готовности прийти на помощь.

 

Творческий кризис

 

Иногда работа попросту не идет. Такое бывало со мной, и я видел, как такое случается с другими. Вы сидите за компьютером… и ничего не происходит.

Часто вы находите другие дела. Вы читаете электронную почту или Твиттер. Вы просматриваете книги, графики и документы. Вы устраиваете собрания. Вы затеваете дискуссии. Короче, вы делаете что угодно, чтобы вам не пришлось снова оказаться за компьютером.

Из-за чего возникают подобные «творческие кризисы»? Мы уже обсудили многие причины. Лично для меня главным фактором является нехватка сна. Если я слишком мало сплю, то я просто не могу программировать. Также важную роль играют беспокойство, страх и депрессия.

Как ни странно, у этой проблемы существует очень простое решение. Оно срабатывает почти всегда. Оно легко реализуется, и оно может обеспечить необходимый импульс для написания большого объема кода.

Найдите напарника для парного программирования.

Просто невероятно, насколько эффективно оно работает. Как только вы садитесь с кем-то рядом, все проблемы, мешавшие работе, немедленно исчезают. Работа в паре приводит к физиологическим изменениям. Я не знаю, что именно происходит, но определенно чувствую. То ли в мозгу, то ли в теле происходит химическое изменение, которое позволяет мне преодолеть застой и снова взяться за работу.

Учтите, что решение не идеально. Иногда изменение длится час-два, а за ним следует истощение настолько серьезное, что мне приходится отрываться от напарника и искать место для отдыха. Иногда, даже когда я работаю в паре, у меня хватает сил только соглашаться с тем, что делает напарник. И все же для меня типичной реакцией на работу в паре является восстановление творческого потенциала.

 

Творческий ввод

Существуют и другие меры для предотвращения застоя. Я уже давно узнал, что результаты творческой работы зависят от выбора источников.

Я читаю много книг на разные темы. Я читаю материалы по программированию, политике, биологии, астрономии, физике, химии, математике и многим другим темам. Однако я обнаружил, что мои механизмы творческой работы лучше всего активизирует научная фантастика.

Для вас это может быть что-то другое – хороший детектив, поэзия или даже любовный роман. Наверное, дело в том, что творчество порождает творчество. Также стоит учитывать элемент эскапизма. Часы, проведенные вдали от повседневных забот под активным воздействием интересных, творческих идей, вызывают почти непреодолимое желание создать что-нибудь самому.

Не все формы творческой деятельности работают одинаково эффективно. Просмотр телевизора обычно не влияет на мой творческий процесс. Поход в кино работает лучше, но ненамного. Музыка не помогает создавать код, но способствует созданию презентаций и подготовке видеоматериалов. И все же из всех форм творческих источников ничто не воздействует на меня лучше, чем старая добрая «космическая опера».

 

Отладка

 

Один из худших сеансов отладки за всю мою карьеру случился в 1972 году. Терминалы, подключенные к бухгалтерской системе профсоюза грузоперевозчиков, зависали один-два раза в день. Сознательно воспроизвести ошибку было невозможно. Ошибка не отдавала предпочтений какому-то конкретному терминалу или приложению. Не важно, чем занимался пользователь перед зависанием: сейчас терминал работает нормально, а в следующую минуту безнадежно зависает.

На диагностику требовались недели. Тем временем грузоперевозчики испытывали все большее раздражение. Каждый раз при зависании пользователю приходилось прекращать работу и ждать, пока все остальные пользователи тоже выполнят свои текущие операции. После этого они звонили нам, и мы перезагружали компьютер. Короче, настоящий кошмар.

Первая пара недель была проведена за простым опросом пользователей, работавших за зависающими терминалами. Мы спрашивали, чем они занимались в тот момент и что делалось до этого. Мы спрашивали других пользователей, не заметили ли они чего-нибудь необычного на своих терминалах в момент зависания. Собеседования приходилось проводить по телефону, потому что терминалы были установлены в пригородах Чикаго, а мы работали на 30 миль к северу.

У нас не было журналов, счетчиков или отладчиков. Все взаимодействие с внутренним состоянием системы осуществлялось через индикаторы и тумблеры передней панели. Мы могли остановить компьютер и просмотреть содержимое памяти по словам. Однако заниматься этим более 5 минут было невозможно, потому что грузоперевозчикам была нужна их система.

Мы потратили несколько дней на написание простого инспектора, работавшего в режиме реального времени. Им можно было управлять с телетайпа ASR-33, который служил нам консолью. Инспектор позволял читать и изменять содержимое памяти во время работы системы.

Мы добавили журнальные сообщения, которые выводились на телетайп в критических ситуациях. Мы создали в памяти счетчики событий, которые запоминали информацию состояний для ее просмотра инспектором. И конечно, весь код создавался «с нуля» на ассемблере и тестировался по вечерам, когда система не использовалась.

Работа терминалов управлялась прерываниями. Символы, передаваемые терминалам, хранились в циклических буферах. Каждый раз при передаче символа последовательным портом срабатывало прерывание и к отправке готовился следующий символ циклического буфера.

Со временем выяснилось, что терминал зависал из-за рассинхронизации трех переменных, управлявших циклическим буфером. Мы понятия не имели, почему это происходило, но это было хоть что-то. Где-то в 5K строк кода супервизора содержалась ошибка, которая некорректно работала с одним из этих указателей.

Новая информация также позволила нам снимать блокировку с терминалов вручную! Мы могли при помощи инспектора присвоить этим трем переменным значения по умолчанию, и терминалы, как по волшебству, начинали работать снова. Вскоре мы написали маленький фрагмент кода, который проверял синхронизацию счетчиков и восстанавливал их в случае необходимости. Сначала код запускался специальным тумблером пользовательского прерывания на передней панели, когда заказчики по телефону сообщали о зависании. Позднее мы просто выполняли код восстановления каждую секунду.

Месяц спустя проблема с зависанием исчезла – по крайней мере с точки зрения профсоюза грузоперевозчиков. Время от времени один из их терминалов приостанавливался на полсекунды, но с базовой скоростью передачи 30 символов в секунду никто этого не замечал.

Но почему происходила десинхронизация счетчиков? Мне было 19, и я был полон решимости разобраться.

Автором кода супервизора был Ричард, уехавший на учебу в колледж. Никто из нас толком не разбирался в супервизоре, потому что Ричард относился к своему созданию очень ревниво. Код принадлежал ему, и нам было не положено разбираться в нем. Но теперь Ричарда не было, поэтому я нашел листинг толщиной в несколько дюймов и начал просматривать его страницу за страницей.

Циклические буферы в этой системе были обычными структурами данных FIFO, то есть очередями. Прикладные программы заносили символы с одного конца очереди, пока она не заполнялась. Обработчики прерываний извлекали символы с другого конца очереди, когда принтер был готов принять их. Если в очереди не оставалось символов, принтер останавливался. Из-за ошибки приложения считали, что очередь заполнена, а обработчики прерываний – что она пуста. Обработчики прерываний выполнялись в другом «программном потоке», отдельно от остального кода. Таким образом, счетчики и переменные, доступные для обоих обработчиков и остального кода, должны быть защищены от параллельного обновления. В нашем случае это означало, что перед выполнением любого кода, работавшего с этими тремя переменными, необходимо было запретить прерывания. К тому моменту, когда я сел за код, мне уже стало ясно: нужно искать участок кода, который работает с переменными без предварительного запрета прерываний.

Конечно, сейчас появилось множество мощных инструментов для поиска всех мест изменения переменных в программе. За считанные секунды вы найдете все строки кода, которые работают с переменными. За минуты можно будет определить, где именно автор забыл запретить прерывания. Однако наша история происходила в 1972 году, и у меня таких инструментов не было. Были только мои глаза.

Я просмотрел каждую страницу кода в поисках переменных. К сожалению, переменные использовались везде – почти на каждой странице программа обращалась к ним тем или иным образом. При многих обращениях прерывания не запрещались – они ограничивались чтением, а следовательно, были безвредными. Вдобавок в этом конкретном ассемблере было невозможно проверить, доступна ли переменная только для чтения, без анализа логики кода. Каждое чтение переменной могло сопровождаться ее обновлением. И если при этом прерывания не были запрещены, содержимое переменных могло быть легко испорчено.

Мне потребовалось несколько дней интенсивного изучения кода, но в конце концов я нашел ошибку. В середине кода отыскалось одно место, в котором одна из трех переменных обновлялась без предварительного запрета прерываний.

Я занялся вычислениями. Уязвимость существовала на протяжении двух микросекунд. В системе дюжина терминалов передавала данные на скорости 30 символов в секунду, так что прерывания происходили каждые 3 микросекунды или около того. С учетом размера супервизора и тактовой частоты процессора зависания от этой уязвимости должны были происходить с частотой примерно 1–2 раза в день. Есть!

Конечно, я исправил ошибку, но у меня не хватило смелости отключить автоматический запуск проверки и исправления счетчиков. До сих пор не уверен в том, что в системе не было другой «дыры».

 

Время отладки

По какой-то неведомой причине разработчики не считают отладку естественной частью процесса разработки. Им кажется, что отладка сродни физиологической потребности: ей занимаются просто потому, что это неизбежно. Однако время отладки обходится фирме ровно в такую же сумму, что и время написания кода, поэтому любые меры по его сокращению будут полезны.

Сейчас я провожу за отладкой намного меньше времени, чем десять лет назад. Я не проводил точных измерений, но, по моим оценкам, продолжительность отладки сократилась раз в 10. Я добился этого воистину радикального сокращения переходом на методологию разработки через тестирование (TDD, Test Driven Development), которая будет рассматриваться в следующей главе.

Независимо от того, используете ли вы TDD или другую методологию аналогичной эффективности, вы как профессионал обязаны стремиться по возможности приблизить время отладки к нулю. Конечно, нуль – цель асимптотическая, но от этого она не перестает быть целью.

Врачи не любят заново делать операции пациентам, чтобы исправить свои прошлые ошибки. Адвокаты не любят повторно браться за «заваленные» дела. Врач или адвокат, который слишком часто допускает ошибки, не будет считаться профессионалом. Аналогичным образом разработчик, создающий слишком много ошибок, действует непрофессионально.

 

Выбор темпа

 

Программирование – марафон, а не спринт. Невозможно выиграть забег, набрав максимальную скорость на старте. Побеждает тот, кто бережет силы и разумно выбирает темп. Марафонец должен заботиться о своем организме как до, так и во время соревнований. Точно так же и профессиональные программисты берегут силы и творческий потенциал.

 

Умейте остановиться

Не можете уйти домой, пока не решили свою задачу? Уйти не только можно, но и нужно! Творческое мышление и интеллектуальная деятельность – недолговечные состояния нашего разума. Когда мы устаем, они исчезают. Если вы будете силой заставлять свой уставший мозг решить задачу в поздний час, скорее всего, это кончится лишь дополнительной усталостью и снижением вероятности того, что задачу удастся решить в душе (или в машине).

Если вы зашли в тупик, если вы устали – отвлекитесь на время. Дайте своему творческому подсознанию отдохнуть от задачи. Внимательно относясь к своим ресурсам, вы сделаете больше за меньшее время и с меньшими усилиями. Сами определяйте темп работы для себя и своей группы. Изучите свои закономерности проявления творческих способностей и озарений и используйте их вместо того, чтобы подчинять насильно.

 

По дороге домой

Многие задачи были успешно решены мной в машине, когда я возвращался с работы домой. Вождение требует больших затрат нетворческих интеллектуальных ресурсов. Ваши глаза, руки и часть ума заняты управлением машиной, и вы отвлекаетесь от своей задачи на работе. И в этом отвлечении есть что-то такое, что помогает вашему разуму находить другие, более творческие пути поиска решений.

 

Душ

Неожиданно много задач было решено мной в душе. Возможно, утренние водные процедуры помогают мне проснуться и припомнить все решения, которые возникли в моем мозгу, пока я спал.

Работая над задачей, вы иногда подбираетесь к ней так близко, что не видите всех возможных вариантов. Вы упускаете элегантные решения, потому что творческая часть вашего разума подавляется излишней сосредоточенностью. Иногда лучшее решение задачи – пойти домой, поужинать, посмотреть телевизор и лечь спать, а на следующее утро проснуться и принять душ.

 

Отставание от графика

 

Вы будете отставать от графика. Это происходит с самыми лучшими из нас. Это происходит с самыми прилежными. Оценки срываются, а результат запаздывает.

Чтобы свести к минимуму проблемы, связанные с отставанием, помните о двух важнейших аспектах: раннем обнаружении и прозрачности. Хуже всего, когда вы до последнего момента уверяете окружающих, что работа будет завершена вовремя, а потом подводите всех. Не делайте этого. Регулярно проверяйте ход проекта по отношению к конечной цели и представьте три обоснованные конечные даты: лучшую, номинальную и худшую. Будьте по возможности честны в своих оценках. Оптимизму в них не место! Представьте все три даты своей группе и ключевым участникам проекта. Ежедневно обновляйте их.

 

Надежда

Что делать, если из этих чисел следует, что вы можете не успеть к критической дате? Например, через десять дней начинается торгово-промышленная выставка, на которой должен быть представлен продукт. С другой стороны, тройственная оценка времени готовности подсистемы, над которой вы работаете, равна 8/12/20.

Не надейтесь, что вам удастся сделать все за 10 дней! Надежда убивает проекты. Надежда срывает графики и рушит репутации. Надежда навлечет на вас большие неприятности. Если выставка начнется через 10 дней, а номинальная оценка составляет 12 дней, вы не успеете к сроку. Убедитесь в том, что группа и ключевые участники проекта понимают ситуацию, и не успокаивайтесь до тех пор, пока не будет сформулирован альтернативный план. И не позволяйте надеяться другим.

 

Спешка

А если начальник приглашает вас на беседу и настоятельно просит успеть к сроку? Если он настаивает, что вы должны сделать «все возможное»? Не отступайте от своих оценок! Исходные оценки всегда точнее любых изменений, вносимых под давлением. Скажите начальнику, что вы уже рассмотрели все варианты (потому что вы их действительно рассмотрели) и что ускорить работу можно только одним способом – усечением части функциональности. Не поддавайтесь искушению ускорить темп.

Горе несчастному разработчику, который уступит давлению и попробует успеть к сроку. Он начинает искать обходные пути и работать сверхурочно в тщетной надежде совершить чудо. Это верный путь к катастрофе, потому что он внушает вам, вашей группе и ключевым участникам проекта неоправданные надежды. Все это оборачивается только нежеланием взглянуть в лицо реальности и откладыванием неприятных, но необходимых решений.

Спешка бессмысленна. Вы не заставите себя программировать быстрее. Вы не заставите себя быстрее решать задачи. А если попытаетесь – вы только замедлите работу и устроите хаос, который замедлит работу других.

Итак, вы должны ответить начальнику, группе и ключевым участникам проекта так, чтобы у них не осталось иллюзий.

 

Сверхурочные

Начальник говорит: «А если увеличить рабочий день на пару часов? Если работать по воскресеньям? Наверняка как-нибудь можно выжать лишние часы, чтобы успеть ко времени».

Сверхурочная работа возможна, а иногда просто необходима. Иногда можно завершить работу к вроде бы невозможной дате, работая по 10 часов в сутки, с одним-двумя воскресеньями. Однако это очень рискованно. Вряд ли 20 % увеличение продолжительности рабочего дня позволит вам выполнить на 20 % больше работы. Что еще важнее, сверхурочная работа на протяжении более чем двух-трех недель наверняка приведет к провалу.

Следовательно, на сверхурочную работу можно соглашаться только при выполнении некоторых условий: 1 – лично вы можете ее себе позволить; 2 – аврал будет продолжаться недолго, не более двух недель, и 3 – у руководства имеется резервный план на случай, если ваши усилия завершатся неудачей.

Последний критерий имеет решающее значение. Если ваш начальник не может объяснить, что он собирается делать в случае неудачного исхода, не соглашайтесь на сверхурочную работу.

 

Ложная готовность

Вероятно, худший из всех видов непрофессионализма со стороны программиста – это попытка выдать недоделку за готовый продукт. Иногда это просто открытая ложь, что достаточно плохо. Но гораздо опаснее другая ситуация – попытки подвести рациональную основу под новое определение «готовности». Мы убеждаем себя в том, что сделано достаточно, и переходим к следующей задаче. Мы говорим, что оставшуюся работу можно выполнить позднее, когда у нас будет больше времени.

Эта болезнь заразна. Если одному программисту такое поведение сходит с рук, другие видят и следуют его примеру. Один из них расширяет определение «готовности» еще дальше, и все остальные следуют его примеру. Я видел, как подобные ухищрения доходили до ужасающих крайностей. Один из моих клиентов под «готовностью» понимал регистрацию изменений в базе данных. При этом код мог даже не компилироваться!

Когда группа попадает в эту ловушку, начальство слышит, что все идет нормально. Все отчеты о ходе работ показывают, что работа будет завершена к сроку. Ситуация напоминает пикник слепых на железнодорожных рельсах: никто не видит приближающийся грузовой состав незавершенной работы, пока не будет слишком поздно.

 

Определение «готовности»

Проблема ложной готовности решается созданием независимого определения «готовности». Для этого следует поручить бизнес-аналитикам и специалистам по тестированию создать автоматизированные приемочные тесты, без прохождения которых продукт не может считаться готовым. Тесты пишутся на тестовых языках – таких как FitNesse, Selenium, RobotFX, Cucumber и т. д. Тесты должны быть понятны для бизнесменов и ключевых участников проекта, не связанных с технической стороной, и они должны выполняться по возможности часто.

 

Помощь

 

Программирование – трудная работа. Чем вы моложе, тем слабее в это верится. В конце концов, программный код – всего лишь последовательность команд if и while. Но по мере накопления опыта вы понимаете, что важнейшую роль играет способ объединения этих команд if и while. Нельзя просто свалить их в одну кучу и надеяться на лучшее. Вместо этого систему необходимо тщательно разбить на небольшие, понятные блоки, которые должны быть как можно меньше связаны друг с другом, – а это действительно сложно.

Более того, программирование настолько сложно, что одному человеку с этой работой не справиться. Даже самому квалифицированному специалисту пригодятся мысли и идеи других программистов.

 

Как помогать другим

Ответственные программисты должны быть готовы помогать друг другу. Программист, который изолируется в своем офисе или кабинке и отказывается отвечать на вопросы других, нарушает профессиональную этику. Ваша работа не настолько важна, чтобы вы не могли выделить немного времени на помощь другим. Честь профессионала обязывает предложить ближним помощь тогда, когда это потребуется.

Это не означает, что вы должны отказаться от «личного времени». Конечно, оно необходимо, но к его выбору следует подойти вежливо и честно. Например, вы можете сообщить, что между 10:00 и полуднем вас нельзя беспокоить, а с 13:00 до 15:00 ваша дверь открыта для других.

Также будьте внимательны к состоянию работы ваших коллег. Если кто-то испытывает затруднения, предложите помощь. Просто удивительно, насколько эффективной порой оказывается такая помощь. Дело не в том, что вы намного умнее своего коллеги; просто свежая точка зрения нередко становится мощным катализатором для решения проблем.

Когда вы кому-то помогаете, сядьте и напишите код вместе. Запланируйте на помощь не менее часа. Возможно, вам понадобится меньше времени, но торопиться не стоит. Сосредоточьтесь на задаче и приложите максимум усилий. Скорее всего, вы в конечном итоге от такого сотрудничества получите больше, чем отдадите.

 

Как принимать помощь

Когда кто-то предлагает вам помощь, будьте признательны. Примите помощь с благодарностью и отнеситесь к ней со всем вниманием. Не отказывайтесь от помощи, потому что вам не хватает времени. Выделите на разговор около минут 30. Если особой пользы от предложенной помощи не видно, вежливо извинитесь и завершите беседу с благодарностью. Помните: профессионализм обязывает вас не только предлагать, но и принимать предложенную помощь.

Научитесь просить о помощи. Когда вы зашли в тупик или не можете разобраться в задаче, попросите других помочь вам. Если вы находитесь в общей комнате, просто скажите: «Мне нужна помощь». В остальных случаях можно воспользоваться Твиттером, электронной почтой или телефоном. Обратитесь за помощью – в конце концов, это также является делом профессиональной этики. Непрофессионально оставаться в тупике, когда помощь так доступна.

Думаете, я сейчас нарисую радужную картину – хор поет проникновенную песню, пушистые зайчики прыгают на спины единорогам и все дружно отправляются к радуге надежды и изменений? Нет, не совсем так. Видите ли, программисты обычно бывают самонадеянными, эгоцентричными интровертами. Мы идем в эту область не потому, что мы любим людей. Большинство из нас приходит в программирование, потому что нам нравится концентрироваться на мелочах, жонглировать множеством абстрактных концепций и иным образом доказывать себе, что мы являемся обладателями выдающегося интеллекта, – а вовсе не для того, чтобы разбираться с досадными сложностями других людей.

Да, это стереотип. Да, это обобщение со множеством исключений. Однако реальность такова, что программисты не склонны к сотрудничеству. Тем не менее сотрудничество играет исключительно важную роль в эффективном программировании. А раз для многих из нас оно не является инстинктом, значит, нам нужны методологии, которые заставляют нас сотрудничать.

 

Обучение

Позднее этой теме будет посвящена целая глава. А пока позвольте мне просто сказать, что ответственность за обучение менее квалифицированных программистов возлагается на их опытных коллег. Учебных курсов недостаточно. Книг недостаточно. Ничто не приведет молодого разработчика к высокой производительности быстрее, чем его собственное желание в сочетании с эффективным обучением со стороны старших товарищей. Итак, еще одна сторона профессиональной этики проявляется в том, что опытные программисты берут под опеку молодых программистов и обучают их. Аналогичным образом профессиональная обязанность неопытных программистов заключается в том, чтобы найти наставника и перенять его опыт.