Творческий кризис
Иногда работа попросту не идет. Такое бывало со мной, и я видел,
как такое случается с другими. Вы сидите за компьютером… и ничего
не происходит.
Часто вы находите другие дела. Вы читаете электронную почту или
Твиттер. Вы просматриваете книги, графики и документы. Вы
устраиваете собрания. Вы затеваете дискуссии. Короче, вы делаете
что угодно
, чтобы вам не пришлось снова оказаться за компьютером.
Из-за чего возникают подобные «творческие кризисы»? Мы уже
обсудили многие причины. Лично для меня главным фактором
является нехватка сна. Если я слишком мало сплю, то я просто не могу
программировать. Также важную роль играют беспокойство, страх и
депрессия.
Как ни странно, у этой проблемы существует очень простое
решение. Оно срабатывает почти всегда. Оно легко реализуется, и оно
может обеспечить необходимый импульс для написания большого
объема кода.
Найдите напарника для парного программирования.
Просто невероятно, насколько эффективно оно работает. Как
только вы садитесь с кем-то рядом, все проблемы, мешавшие работе,
немедленно исчезают. Работа в паре приводит к физиологическим
изменениям. Я не знаю, что именно происходит, но определенно
чувствую. То ли в мозгу, то ли в теле происходит химическое
изменение, которое позволяет мне преодолеть застой и снова взяться
за работу.
Учтите, что решение не идеально. Иногда изменение длится час-
два, а за ним следует истощение настолько серьезное, что мне
приходится отрываться от напарника и искать место для отдыха.
Иногда, даже когда я работаю в паре, у меня хватает сил только
соглашаться с тем, что делает напарник. И все же для меня типичной
реакцией на работу в паре является восстановление творческого
потенциала.
Творческий ввод
Существуют и другие меры для предотвращения застоя. Я уже
давно узнал, что результаты творческой работы зависят от выбора
источников.
Я читаю много книг на разные темы. Я читаю материалы по
программированию, политике, биологии, астрономии, физике, химии,
математике и многим другим темам. Однако я обнаружил, что мои
механизмы творческой работы лучше всего активизирует научная
фантастика.
Для вас это может быть что-то другое – хороший детектив, поэзия
или даже любовный роман. Наверное, дело в том, что творчество
порождает творчество. Также стоит учитывать элемент эскапизма.
Часы, проведенные вдали от повседневных забот под активным
воздействием интересных, творческих идей, вызывают почти
непреодолимое желание создать что-нибудь самому.
Не все формы творческой деятельности работают одинаково
эффективно. Просмотр телевизора обычно не влияет на мой
творческий процесс. Поход в кино работает лучше, но ненамного.
Музыка не помогает создавать код, но способствует созданию
презентаций и подготовке видеоматериалов. И все же из всех форм
творческих источников ничто не воздействует на меня лучше, чем
старая добрая «космическая опера».
Отладка
Один из худших сеансов отладки за всю мою карьеру случился в
1972 году. Терминалы, подключенные к бухгалтерской системе
профсоюза грузоперевозчиков, зависали один-два раза в день.
Сознательно воспроизвести ошибку было невозможно. Ошибка не
отдавала предпочтений какому-то конкретному терминалу или
приложению. Не важно, чем занимался пользователь перед
зависанием: сейчас терминал работает нормально, а в следующую
минуту безнадежно зависает.
На
диагностику
требовались
недели.
Тем
временем
грузоперевозчики испытывали все большее раздражение. Каждый раз
при зависании пользователю приходилось прекращать работу и ждать,
пока все остальные пользователи тоже выполнят свои текущие
операции. После этого они звонили нам, и мы перезагружали
компьютер. Короче, настоящий кошмар.
Первая пара недель была проведена за простым опросом
пользователей, работавших за зависающими терминалами. Мы
спрашивали, чем они занимались в тот момент и что делалось до
этого. Мы спрашивали других пользователей, не заметили ли они
чего-нибудь необычного на своих терминалах в момент зависания.
Собеседования приходилось проводить по телефону, потому что
терминалы были установлены в пригородах Чикаго, а мы работали на
30 миль к северу.
У нас не было журналов, счетчиков или отладчиков. Все
взаимодействие с внутренним состоянием системы осуществлялось
через индикаторы и тумблеры передней панели. Мы могли остановить
компьютер и просмотреть содержимое памяти по словам. Однако
заниматься этим более 5 минут было невозможно, потому что
грузоперевозчикам была нужна их система.
Мы потратили несколько дней на написание простого инспектора,
работавшего в режиме реального времени. Им можно было управлять
с телетайпа ASR-33, который служил нам консолью. Инспектор
позволял читать и изменять содержимое памяти во время работы
системы.
Мы добавили журнальные сообщения, которые выводились на
телетайп в критических ситуациях. Мы создали в памяти счетчики
событий, которые запоминали информацию состояний для ее
просмотра инспектором. И конечно, весь код создавался «с нуля» на
ассемблере и тестировался по вечерам, когда система не
использовалась.
Работа терминалов управлялась прерываниями. Символы,
передаваемые терминалам, хранились в циклических буферах.
Каждый раз при передаче символа последовательным портом
срабатывало прерывание и к отправке готовился следующий символ
циклического буфера.
Со временем выяснилось, что терминал зависал из-за
рассинхронизации трех переменных, управлявших циклическим
буфером. Мы понятия не имели, почему это происходило, но это было
хоть что-то. Где-то в 5K строк кода супервизора содержалась ошибка,
которая некорректно работала с одним из этих указателей.
Новая информация также позволила нам снимать блокировку с
терминалов вручную! Мы могли при помощи инспектора присвоить
этим трем переменным значения по умолчанию, и терминалы, как по
волшебству, начинали работать снова. Вскоре мы написали маленький
фрагмент кода, который проверял синхронизацию счетчиков и
восстанавливал их в случае необходимости. Сначала код запускался
специальным тумблером пользовательского прерывания на передней
панели, когда заказчики по телефону сообщали о зависании. Позднее
мы просто выполняли код восстановления каждую секунду.
Месяц спустя проблема с зависанием исчезла – по крайней мере с
точки зрения профсоюза грузоперевозчиков. Время от времени один
из их терминалов приостанавливался на полсекунды, но с базовой
скоростью передачи 30 символов в секунду никто этого не замечал.
Но почему происходила десинхронизация счетчиков? Мне было 19,
и я был полон решимости разобраться.
Автором кода супервизора был Ричард, уехавший на учебу в
колледж. Никто из нас толком не разбирался в супервизоре, потому
что Ричард относился к своему созданию очень ревниво. Код
принадлежал ему, и нам было не положено разбираться в нем. Но
теперь Ричарда не было, поэтому я нашел листинг толщиной в
несколько дюймов и начал просматривать его страницу за страницей.
Циклические буферы в этой системе были обычными структурами
данных FIFO, то есть очередями. Прикладные программы заносили
символы с одного конца очереди, пока она не заполнялась.
Обработчики прерываний извлекали символы с другого конца
очереди, когда принтер был готов принять их. Если в очереди не
оставалось символов, принтер останавливался. Из-за ошибки
приложения считали, что очередь заполнена, а обработчики
прерываний – что она пуста. Обработчики прерываний выполнялись в
другом «программном потоке», отдельно от остального кода. Таким
образом, счетчики и переменные, доступные для обоих обработчиков
и остального кода, должны быть защищены от параллельного
обновления. В нашем случае это означало, что перед выполнением
любого кода, работавшего с этими тремя переменными, необходимо
было запретить прерывания. К тому моменту, когда я сел за код, мне
уже стало ясно: нужно искать участок кода, который работает с
переменными без предварительного запрета прерываний.
Конечно, сейчас появилось множество мощных инструментов для
поиска всех мест изменения переменных в программе. За считанные
секунды вы найдете все строки кода, которые работают с
переменными. За минуты можно будет определить, где именно автор
забыл запретить прерывания. Однако наша история происходила в
1972 году, и у меня таких инструментов не было. Были только мои
глаза.
Я просмотрел каждую страницу кода в поисках переменных. К
сожалению, переменные использовались везде – почти на каждой
странице программа обращалась к ним тем или иным образом. При
многих обращениях прерывания не запрещались – они ограничивались
чтением, а следовательно, были безвредными. Вдобавок в этом
конкретном ассемблере было невозможно проверить, доступна ли
переменная только для чтения, без анализа логики кода. Каждое
чтение переменной могло сопровождаться ее обновлением. И если
при этом прерывания не были запрещены, содержимое переменных
могло быть легко испорчено.
Мне потребовалось несколько дней интенсивного изучения кода,
но в конце концов я нашел ошибку. В середине кода отыскалось одно
место, в котором одна из трех переменных обновлялась без
предварительного запрета прерываний.
Я занялся вычислениями. Уязвимость существовала на протяжении
двух микросекунд. В системе дюжина терминалов передавала данные
на скорости 30 символов в секунду, так что прерывания происходили
каждые 3 микросекунды или около того. С учетом размера
супервизора и тактовой частоты процессора зависания от этой
уязвимости должны были происходить с частотой примерно 1–2 раза в
день. Есть!
Конечно, я исправил ошибку, но у меня не хватило смелости
отключить автоматический запуск проверки и исправления счетчиков.
До сих пор не уверен в том, что в системе не было другой «дыры».
Do'stlaringiz bilan baham: |