Один день из жизни Программиста

Пятница - лучший день для работы, ибо впереди отдых. А в эту пятницу Программисту предстояло начинать изучение нового большого компонента, так что день сулил много интересного.
Утро, как обычно, началось с ежедневного SCRUM собрания минут на 10 и еще с пары совещаний. Потом были письма и ответы на них и быстрый обед.
Зато после этого Программист выгрузил Outlook и Skype и исчез для всех (ибо нет ничего хуже для программиста, чем постоянное отвлечение).
Исчез для всех, кроме второго Программиста, который разработал этот большой компонент, который предстояло изучать. Для ускорения передачи знаний было решено поработать несколько дней в паре за одним компьютером (ибо pair programming офигительно хорош для передачи знаний).
Начали с попыток скачать и сбилдить проект на новом компьютере, для чего надо было установить и прописать в системе кучу нужных SDK и тулзов. К счастью многое уже было установлено и все ограничилось установкой и настройкой QT и Python26. После небольшого колдовства (а QT без колдовства, как известно, не работает), билд заработал. И еще как!
Ребилд на не сильно мощной машине Программиста занял 40 минут!
“Вот оно - приключение”, подумал Программист и сказал второму:
“Я не смогу работать над тем, что билдится 40 минут. Сейчас мы с тобой ускорим билд в несколько раз!”
Второй Программист не очень-то поверил (ибо уже год мучался с таким медленным билдом), но первый настоял, ибо знал, что лучше 1 день потерять, но зато потом за 5 минут долететь. (ибо время билда - один из самых важных факторов в программировании. Сделай долгий билд и никто не сможет вносить легко и просто изменения в компонент, т.к. цикл изменение-проверка будет занимать слишком много времени - тут уже никакие юнит тесты и test automation не помогут. А сделай билд и тестирование мгновенными и получишь легко расширяемый компонент)
И они приступили к ускорению билда.



Что первым делом надо сделать, чтобы ускорить билд? Конечно же проверить правильность precompiled headers. Проверили - они вообще не используются. Тут первый подумал “Оба-на, сейчас будет Voodoo magic” и сказал второму:
“Чувак, сейчас я тебя сильно удивлю.” (Ибо неиспользовать precompiled headers - это главная из глупостей, которые программист совершает (т.к. сделать просто и помогает), хотя не все со мной согласятся в этом).
Включить precompiled оказалось непросто, ибо проекты генерировались с помощью qmake, но терпенье и Google все перетрут. Сначала было найдено, что qmake поддерживает параметры PRECOMPILED_HEADER и PRECOMPILED_SOURCE, в которых можно указать хедер и cpp, а в дефайны надо добавить USING_PCH.
Был добавлен stable.h, в который включены все нужные QT инклюды. Естественно, сразу это не заработало, ибо не всем нужны были эти инклюды, а в паре мест C-API юнит-тестировался с помощью .c файлов, которые с precompiled просто не живут, так что пришлось применять разные трюки.
В итоге через пару часов precompiled заработал и ускорил билд в 5 раз! Было 40 минут, а стало 8. И из этих 8 минут 2 занимает работа qmake и 6 - ребилд 30 проектов. Неплохое ускорение.
Потом было обнаружено, что проекты билдятся в 1 поток.
“Оба-на, еще одно приключение” - подумал первый Программист и сказал:
- А давай-ка сделаем билд на много потоков и ускорим его еще в пару раз! (Ибо 1 поток - это прошлый век и не масштабируется).
Начали. В итоге оказалось, что qmake создает невалидные .sln для Visual Studio 2005 и они не могут быть сбилжены с помощью vcbuild, а только с devenv, а для devenv нельзя указать число потоков.
Но настоящего джедай-программиста такое не остановит - был быстренько написан скрипт, исправляющий невалидность .sln и скоро всё заработало! На многопроцессорной системе билд ускорился еще в пару раз и занимал уже не 40 минут, а 5! Впечатляющее ускорение.
На этом решено было остановиться с ускорением билда (Ибо можно провести сколько угодно времени улучшая environment, но нужно знать и меру и уметь вовремя остановиться).
Параллельно с ускорением билда, второй Программист передавал знания про систему билда компонента, так что кроме очевидной пользы ускорения процесса сборки, заодно была еще изучена эта система сборки - двойная польза.
А до конца рабочего дня оставался еще час.


А что можно сделать за час? Правильно - открыть багтрекер и исправить пару багов (да и изучать код проще, исправляя баги в нем).
Первый баг - компонент не выгружается, когда ему шлют сообщение “Выйти”. Нашли код - функция OnExit пустая. Понятно, как исправить.
Но сначала надо научиться повторять баг, ибо иначе не проверить исправление. Быстренько пишется скриптик, посылающий событие на выход. Запускается скрипт - не выходит компонент.
Добавляется код в onExit, запускается скрипт - выходит компонент. Отлично, работает. Скрипт сохранен, чтобы впоследствии добавить его в Test Automation (Ибо наличие regression тестирования - важный шаг к будущему качеству продукта).
Опять открывается багтрекер и берется второй баг. Креш при выходе в Win7 64bit. Дамп плюс магия WinDBG показывают всё про баг. Анализ кода показывает банальнейший race condition в сильно многопоточном коде. Лечится вроде как легко добавлением одной критической секции. Но опять же - прежде чем фиксить, надо повторить.
Пара минут обсуждений и получена идея скрипта для повторения бага. Еще 5 минут и скрипт готов и, о чудо, он сразу крешит компонент в том же месте! Отлично!
Теперь добавляем код исправления, билдим, запускаем скрипт и, о чудо, ничего больше не крешится!
Правда скрипт оказался настолько хорош, что кроме этого бага выявил и еще один - компонент не крешится, зато зависает при выходе в результате работы скрипта. Отлично, пофиксим еще один баг и скрипт для проверки исправления бага уже написан!
Но рабочий день закончился и второму Программисту надо убегать.
“Продолжим в понедельник?”
“Конечно - это было очень интересно.”


На этом рабочая пятница закончилась и началась совсем другая история…

6 комментариев к Один день из жизни Программиста

Ответить

 

 

 

Вы можете использовать эти HTML тэги

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>