Федор Борщев

Процесс vs результат у разработчиков

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

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

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

Самый хороший способ — прямо сейчас найти у себя на работе проект с жестким дедлайном и взять на себя ответственность за его завершение. После второго просранного таким образом проекта, вы научитесь вести правильный внутренний диалог с собой: «Действительно ли то, что я делаю необходимо для запуска?»; «Для чего мы запускаем этот проект? Какая у нас цель?»; «Что из того, что я запланировал можно НЕ делать?».

Если не хотите искать проекты на работе — сделайте свой. Только поставьте жесткий дедлайн с осязаемым результатом. Пример хорошей личной задачи — завести блог. Пойдете писать бекенд на гошечке и микросервисах? Возьмете модный генератор статичных сайтов? Или все-таки медиум?

Боязнь ошибиться у программистов

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

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

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

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

На таких страхах вырастают неуклюжие, плохо пахнущие классы с копипастой, которые постепенно превращаются в легаси.

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

Нужен ли докер в продакшене?

Если вы задаетесь этим вопросом, значит вам — не нужен.

Проблема докера — в пороге вхождения. Уметь докер — это как уметь HTML: чтобы его применить, нужно учить еще вагон технологий: CSS, JS, и еще бекенд желательно. У докера этот вагон состоит минимум из swarm (а лучше k8s), чтобы запускать контейнеры, prometheus, чтобы их мониторить, и кучи самописных скриптов, чтобы все это деплоить.

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

Если вы до этого еще не доросли, то используйте докер «как все» — чтобы быстро разворачивать куски инфраструктуры на машине разработчика.

Триггеры, когда действительно пора задуматься про докер:

У вас появился выделенный тестировщик. Тестировщикам нужно окружение для каждой новой задачи. Если задача упала тестировщику — рядом с ней должна лежать ссылка на песочницу, в которой ее можно потыкать.

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

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

Сначала эта заметка вышла на моем телеграм-канале. Подписывайтесь, чтобы читать быстрее и больше.

Тестовые задания для программистов

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

Самая большая ошибка — вместо тестового задания давать абстрактные задачи на знание алгоритмов. Часто ли в работе ваши программисты обходят графы или вручную реализуют шейкерную сортировку?

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

Такое задание — как открытый вопрос. Поймет ли новенький наш стиль для названий тестов? Не испугается ли сложности? Дополнит ли документацию? Напишет ли переиспользуемый код? Не постесняется задавать вопросы? Выдержит ли дедлайн, который сам назовёт?

Если вдруг проект не получается отдать из-за НДА-шных причин — отдаю специально хранимый для этих целей pet project.

Сдавать с первого раза

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

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

Я говорю о простых случаях, которые может заметить кто угодно, банальном «нажимаю на кнопку — получаю ошибку». Непосредственных причин такой хуйни может быть много — CI упал, код не прошёл валидацию\тесты, программист забыл сделать git push.

А вот фундаментальная причина одна, и ее легко исправить — это непонимание definition of done. В случае бага все просто, сделанная работа — это когда баг не воспроизводится на продакшене. В сложных фичах нужно позадавать себе вопросы — что постановщик ожидал получить? Какой самый частый сценарий использования? В каком виде лучше показывать результат?

Самое лучшее средство от непонимания definition of done — всегда подкреплять свои слова доказательством. Пофиксил баг — приложи скриншот. Выкатил фичу — запиши видосик. Если не понимаешь, что скриншотить/записывать — иди за пониманием задачи к тимлиду или менеджеру.

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

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

Воображение!

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

О таких проблемах гораздо лучше узнавать от воображаемого коллеги, а не от реального.

Пацан сказал — пацан сделал

Если приглядеться, то куча людей вокруг нас не имеют простого навыка — пообещать ответить в среду и, действительно, ответить в среду. Работать с такими людьми — дорого: куча энергии и внимания уходит на банальный контроль того, что порученные задачи действительно делаются.

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

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

Пацан сказал — пацан сделал

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

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

Программистам: три варианта развития мидла

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

Их на самом деле всего три: ничего не делать, стать синьором или податься в управление.

Ничего не делать

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

Голован: чувак, который отлично умеет ничего не делать

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

Синьор

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

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

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

Жизнь в большой компании

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

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

Тимлид\Менеджер

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

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

Скрам-доска: инструмент любого потного менеджера

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

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

А там уже до CTO недалеко.

Итого

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

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

Топ-даун и прогрессивный джипег для программистов

Правило Парето гласит, что 80% времени программиста тратится на 20% требований. К примеру, на любом современном фронтенд-фреймворке работающую корзину в интернет-магазине можно запилить за день — можно будет добавить/удалить товар и отправить заказ.

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

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

Инженеры называют этот подход top-down, дизайнеры — прогрессивным джипегом.

Технические долги

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

Представь что ты увидел в магазине новый охуенный iMac pro. Можно пойти и накопить 400 тысяч (долго и муторно), а можно достать кредитку и купить прямо сейчас.

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

Технический долг — он как финансовый

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

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

Расплата по долгам

В командах у технического долга появляется еще одно вредное свойство — по долгам одного нерадивого участника приходится платить другим. Относись к такому долгу, как к деньгам: представь, что ты в баре, и нашел в кармане кредитку коллеги. Ты же не станешь угощать весь бар Макаланом, правда?

Давайте жить не в долг и писать понятный код — так быстрее. И работу можно будет менять по собственной воле, а не из-за долговой ямы.

Книга: Строим нейросеть

Пару лет назад я не видел разницы между нейросетями и искусственным интеллектом. Ну а что — и в голове нейроны, и в нейросетях.

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

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

Ладно, хватит сложностей. Если вы программист, вы и без меня найдете что почитать. А если менеджер — рекомендую книгу Тарика Рашида «Строим нейросеть».

Тарик Рашид — Строим нейросеть

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

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