Spiiin's blog

Хорошие качества программистов

Качества программистов, которые мне нравятся:

  • умение держать в голове большое количество информации
  • понимание, как использовать язык программирования в своих целях
  • умение решать задачу минимальным количеством изменений в коде
  • умение искать причины трудновоспроизводимых багов
  • слежение за качеством кодовой базы
  • умение ставить эксперименты
  • любовь к “тинкерингу”
  • умение довести решение сложной задачи до конца

Умение держать в голове большое количество информации

demoman
Часто в большом проекте приходится переключаться между разными контекстами (исправление багов в различных подсистемах на разных уровнях, участие в обсуждениях будущих фич, базовое слежение за тем, что вообще происходит во всём проекте). Также это умение связано с навыками пользоваться системами структурирования информации — за осознанием, как мало на самом деле можно удерживать информации в голове (по сравнению с потоком информации в проекте), следует желание найти и пользоваться удобной системой задач, организовывать и расшаривать информацию, оптимизировать потоки информации там, где ощущается бардак. То есть, вытащить контекст из головы, и создать “паутину” вспомогательной информации, в которой можно будет найти то, что забылось.

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

Понимание, как использовать язык программирования в своих целях

soldier
Каждый язык программирования имеет свои плюсы и минусы. Часто о них не говорят, но принимают как должное вместе с языком (библиотекой, фреймворком, движком). Минусы языка могут быть не абсолютными, а проявляться только при использовании языка в определенной области — при решении определенного типа задач, для которых определенные свойства языка становятся критичными.

Например, требование к скорости выполнения программ при разработке игр. Вот рассуждения о недостатках C# в качестве языка для описания игровой логики и способов борьбы с этими ограничениями — как обойти минусы языка и платформы, чтобы воспользоваться его преимуществами, что было сделано в Unity. Если оценивать язык и пользоваться им только “как принято” и “как пишут в книжках”, то можно просто пропустить то, что возможно сделать с его помощью.

Хорошее понимание особенностей предметной области позволяет формулировать цели, с которыми можно подходить к выбору языков. Часто целью самого языка или фреймворка является стать “дефолтным выбором” в определенной нише, для тех, кто не задумывается о своих целях. Это может стать опасным в случаях, когда от инструмента автоматически ожидают, что его использование приведёт к тому, что продукт автоматически будет обладать нужными свойствами. За тем, чтобы желаемое свойство не потерялось, нужно следить, никакой язык не будет делать это за вас. Возможность писать быстрый код обеспечивает не язык, а понимание, как писать быстрый код (возможно, отличающиеся для различных языков).

Чем осознанние цель, с которой выбираешь инструмент, тем проще его выбрать (или даже решиться допилить в своих нуждах), а также отбросить/исправить/запретить “мусорные” вещи, которые, мешают достижению поставленной цели, и не заниматься вещами, которые никак не относятся к поставленным целям.

Интересный ретроспективный доклад от Wargaming про выбор движка BigWorld для танков с рассуждениями о важности понимания целей выбора технологии (5-я минута, оценка качеств движка на рынке).

Умение решать задачу минимальным количеством изменений в коде

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

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

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

Умение искать причины трудновоспроизводимых багов

sniper
Под слоем логики современной игры лежит множество других, которые являются для неё чёрным ящиком — код движка, вызовы функций операционной системы, обращение с сервером, слой графического API, взаимодействие множества 3rdParty библиотек, код которых также может обновляться по сети через пакетные менеджеры, особенности компилятора и реализаций стандартной библиотеки, особенности железа. Связи в собственном коде отследить просто, но какое-нибудь хитрое взаимодействие API между собой, без возможности посмотреть, что под капотом у этого API (относительно простой пример с opengl) — отдельное искусство, которое иногда основывающется на рассуждениях “как бы я реализовал это, будь я разработчиком библиотеки” или на информации о похожих ошибках, собранной по крупицам из разных мест (в хорошем случае — прямым вопросом авторам библиотеки, в плохом — “о, это уже ломалось у них 3 версии назад, снова сломали”).

Хорошо развитый навык поиска таких ошибок развивает умение писать самому максимально простой код, который с наименьшей вероятностью создаст ошибки, которые трудно обнаружить.
Философия поиска ошибок — более развёрнутое описание этой связи.

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

Слежение за качеством кодовой базы

pyro
Пуш в мастер.gif
Качество, которое, кажется, практически невозможно привить, и сложно организовать через рабочие процессы и постановку задач. Либо человек проходит мимо “грязи” в кодовой базе спокойно, либо раздражается, до тех пор, пока не решит исправить. Ответственность за качество кода зависит а от желания работать в комфорте, а не от уровня отвественности или способностей программиста.
Мотивация честного программиста — повышение качества кода связано с желанием работать в комфортных условиях.

Умение ставить эксперименты

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

Особенно необходимо для реализации различных оптимизаций в коде — есть много теоретически работающих трюков, которые не работают на практике. Для отдельных замеров необходимо написание кода, который в несколько раз по объёму больше, чем сам проверяемый код, или написание отдельных программ, позволяющих изучить качества кода, не проверяемые стандартными средствами.
Расположение объектов C++ в памяти — способы увидеть расположение объектов C++ классов в памяти, с целью улучшения cache locality.

В более общем случае умение ставить эксперименты позволяет организовать проверки гипотез о продукте — элемент Lean Development.

Любовь к тинкерингу

engineer
“Тинкерить” — мастерить что-то, изучать, хакать, исследование без особой цели. Попробовать поиграться с новым движком, изучить новый алгоритм или библиотеку. Часто в таком случайном изобретении приобретается полезная экспертиза, на стыке дисциплин можно найти интересные и необычные идеи, нестандартные способы решения задач.

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

Умение довести решение сложной задачи до конца

scout
Есть два типа программистов, которые не могут справиться с задачей — те, у которых код настолько плох, что его дольше исправлять, чем написать заново (чаще всего в попытках внести в него улучшения, ломают то, что уже “залатали” во время предыдущего этапа исправлений, исправления никогда не “сходятся” к нормальному решению) и те, которые вообще не понимают, что от них хотят. Никаких уточняющих вопросов или чернового варианта решения дождаться от них невозможно, а в перед дед-лайном наступает какая-нибудь катастрофа, которая уничтожает их решение, существующее только на их машине. Бывают ещё программисты, которые делают часть работы, но не заканчивают её по каким-либо причинам, не хватает фантазии, инициативы, желания связать созданные части в одно целое. В этом случае чаще всего их код не собирается и требует для проверки внесения в него изменений проверяющим.

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