В этой статье хотелось бы поделиться накопленным за несколько лет опытом, связанным с разработкой программного обеспечения. Пару лет назад я заметил, что отслеживать свой прогресс стало труднее, и задался вопросом: расту ли я вообще как программист? Надеюсь, что мои соображения окажутся полезными и для тех, кто только в начале пути, и для более опытных специалистов. В самые первые годы обучения и затем работы программистом мне очень хорошо запомнились моменты, когда рост был заметен чуть ли не каждый день. Было очевидно, что я освоил какой-то новый навык: вот вчера не знал, как написать хоть какую-нибудь программу, а вот сегодня у меня уже есть простенький скрипт на Python, который перенес фотографии из множества вложенных каталогов на диске в одну папочку. Весь мой программный код жил в одном файле, а вот у меня уже целый пакет со множеством модулей. И если раньше приходилось проверять, что программа работает корректно после каждого изменения, то теперь у меня уже есть какие-никакие юнит-тесты, которые прогоняются за пару секунд. В качестве допущения условимся, что в начале пути программист будет со временем заметно расти. На этом этапе прогресс ожидаем и его трудно не заметить; программы становятся все больше по размеру, разработчик осваивает стандартную библиотеку языка программирования, появляется представление о том, как лучше реализовать ту или иную функциональность с учетом предыдущего опыта: "хардкодить локальные пути было плохой идеей, потому что пользователям моей программы нужно их менять перед запуском" "больше не буду использовать четыре вложенных цикла, потому что через месяц я уже не понимаю, как это все работает". На этом этапе никакого анализа и рефлексии не требуется, чтобы понять, что программист растет - достаточно посмотреть на код сегодня и сравнить его с кодом недельной/месячной давности. Однако спустя какое-то время - для кого-то несколько месяцев, а для кого-то год-другой - интенсивность освоения новых навыков снижается; задачи все чаще становятся типовыми, а решения предсказуемыми. Стандартная библиотека языка программирования освоена, используемый фреймворк изучен на должном уровне, и знаний стандартного технического стека (Docker, Git, система сборки кода, CI) хватает. Кажется, что возможность получения новых навыков появляется редко и нерегулярно, например, когда возникает задача не по вашему профилю (коллега попросил помочь с созданием проекта в CI), или появляется необходимость в оптимизации производительности (клиент жалуется, что файл PDF-отчета генерируется медленнее, чем обычно). Если вы смотрите в ретроспективе на полгода назад и понимаете, что толком ничего нового не узнали, новых технологий не освоили, и не "прокачались" в разработке, то, возможно, это сигнал к тому, чтобы начать отслеживание своего прогресса как программиста. Вполне возможно, что рост был, но вы не успели этого заметить. Для чего это нужно? Возможно, вам это и не нужно. В конце концов, с рабочими обязанностями вы справляетесь, зарплату вам исправно платят и вроде бы все хорошо. Однако мне кажется, что для многих разработчиков важно видеть прогресс, понимать, что они растут как специалисты, как инженеры в широком смысле. Идея отслеживания роста в рамках профессии появилась давно: как у программистов есть понятия "грейда", или уровня (junior -> middle -> senior -> staff -> principal и т.д.), так у и других профессий есть некие ступени мастерства. Вот вам и слесари с разрядами мастера, и учителя с квалификационными категориями, и спортсмены со спортивными разрядами. Будучи достаточно молодой, профессия программиста не имеет единой системы "разрядов", и переход от одного уровня к другому не всегда напрямую связан с подтверждением полученных навыков. Если добавить к этому, что в разных компаниях уровни могут подразумевать разные навыки и разные обязанности, то все становится еще сложнее (middle в Google может быть "сильнее" VP of Engigeering из какого-то стартапа). Если легкоатлету достаточно пробежать 100 метров за условные 10 секунд, чтобы стать мастером спорта (легко измерить и понятно, как достигнуть), то непонятно, какого рода "тренировки" должны быть у программиста, чтобы он стал "сеньором". Некоторые софтверные компании пытаются формализовать такие "разряды" для программистов в матрицах компетентности. Например, очень продуманный, на мой взгляд, документ опубликовали CircleCI: CircleCI Engineering Competency Matrix. На такие ресурсы очень полезно посматривать периодически, чтобы понять, в какой степени вы становитесь более опытным разработчиком и как растет круг ваших обязанностей. Однако в этой статье мне бы хотелось сфокусироваться на росте исключительно в плане технологии разработки, а не на формальных переходах между уровнями. Представим, что прошло какое-то время, и в работе программиста ничего кардинально не изменилось, и расширять "кругозор" разработчика в рамках трудовой деятельности становится все сложнее. При анализе своего опыта я однажды понял, что оказался в такой точке на нелинейном графике роста, что для продвижения по навыкам требуется все больше времени, и заметить этот рост становится труднее. Для кого-то такое положение дел может означать, что пришло время сменить работу и принять вызовы на новом месте в надежде увидеть более интенсивный рост. Так казалось и мне, но я решил потратить выходные на то, чтобы разобраться в том, что уже изучил и какой опыт получил за последние пару лет на текущем месте работы. Я также хотел понять, какие инструменты могу использовать для отслеживания роста в более "реальном" режиме времени (несколько месяцев, а не год). Оказалось, что я вырос довольно значительно, но тогда просто не мог этого заметить. Инструменты и методики, взятые мной на вооружение несколько лет назад, помогают теперь следить за тем, что я изучил и в какой степени вырос как разработчик. После завершения работы над задачей (и иногда по ходу работы) я заношу в заметки те маленькие "открытия", которые сделал для себя, или те решения, которые привели к более удачному дизайну и лучшей расширяемости кода. Такие заметки я периодически пересматриваю; из них также получаются хорошие темы для обсуждения на совещаниях после окончания спринта (когда есть чем поделиться). Например, недавно была задача сделать так, чтобы приложение для внутреннего пользования загружало артефакты, которые совместимы с текущей версией MacOS и той, чтобы была перед ней. Представив все релизы (вплоть до Mojave) в виде списка, я брал последний элемент и искал артефакты для последней версии, и если ничего не находил, то брал артефакты предыдущего элемента в списке (предыдущего релиза MacOS). Все выглядело неплохо, но это означало бы, что нужно выпускать новую версию программы с каждым новом релизом MacOS, чтобы обновить такой список истории релизов. Вроде бы мелочь, но хотелось бы этого избежать. При изучении документации Apple оказалось, что они гарантируют очень хорошую совместимость на уровне API (например, можно запустить графическое приложение CMake 10-летней давности на свежем Big Sur). В качестве такого "дневника" я использую Joplin, но подойдет и любое другое приложение для ведения заметок. Поскольку в заметках полно кода, без поддержки Markdown будет трудно. В заметке по упомянутой задаче я привел ссылки на документацию Apple, несколько кусочков кода, которые позволяют посмотреть системную информацию об артефактах, а также обоснование, почему стоит внимательнее относиться к вопросу совместимости между версиями ОС. Те кусочки кода, которые пригодятся в будущем (мне наверняка будет нужно изучить атрибуты файла и в других задачах), идут в отдельный общий раздел заметок по MacOS. Спустя какое-то время я изучаю свои заметки и вижу, что вообще-то узнал очень много, хотя о некоторых задачах мог бы и не вспомнить. Когда я думаю, что мало знаю по какому-то вопросу (не вижу роста), то понимаю по таким заметкам, что на самом деле хорошо изучил этот вопрос, но просто этого не помню. Такие "дневники" будут особенно полезны для инженеров DevOps и SRE и тех, кто пишет инструменты для внутреннего пользования или работает с инфраструктурой разработки (системы сборки, CI/CD и так далее). Очень сложно понять, вырос ли ты как инженер, только глядя на кучу закрытых тикетов в Jira. А небольшие заметки с разбором проблем (устранение потерь при загрузке документов в Elastic, периодически падающий Jenkins и пр.) помогут зафиксировать успех и не забыть, сколько всего было сделано (и изучено) при "пожаротушении", в рамках техподдержки инженеров или реализации функциональности, которая не видна другим. Для инженеров техподдержки, например, часто требуется быстро разобраться с основами какой-то технологии, чтобы оказать помощь (запрос к SQL Server может выполняться минуты, но T-SQL вы писали 15 лет назад в институте), но копать глубоко и вдумчиво просто нет времени, ведь важно, чтобы "оно заработало". А когда наконец все работает и хочется посмотреть на проблему шире, разгорается новое "пламя срочной работы". Так могут проходить месяцы и годы, при этом возникает ощущение, что толком ни с чем новым и не разобрался; заметки в этом случае позволят вспомнить обо всей проделанной работе, которая не видна в тикетах. Такие отдельные заметки я веду для материала, который изучаю впервые (это могут быть какие-то алгоритмы, структуры данных, языки программирования, библиотеки или фреймворки). Это помогает мне сохранить объективную оценку сложности освоения каких-то понятий спустя какое-то время. Я замечаю, что после освоения навыка, особенно через несколько лет, кажется, что освоить его не было сложно. Похожий опыт у меня был с жонглированием: когда меня спрашивают, трудно ли было научиться жонглировать тремя мячами, я говорю, что нет, забывая, какое количество гневных эпитетов слышали соседи в процессе моих тренировок. Трудно ли научиться кататься на велосипеде или играть на гитаре? Трудно ли понять, как написать рекурсивную функцию человеку, незнакомому с рекурсией? Да в общем-то нет, что тут такого, я же освоил, давно еще и "вроде нетрудно" было. Если же глянуть в заметки, которые были оставлены в процессе обучения, то можно увидеть всю экзистенциальную боль человечества, собранную в одной функции рекурсивного вычисления чисел Фибоначчи. Такие заметки особенно пригодятся старшим разработчикам, которые будут делегировать задачи менее опытным коллегам - вспомните, так ли уж легко вам дались каррирование и метаклассы, когда перечитаете свои заметки. А еще они помогают бороться с синдромом самозванца: когда я вижу, что преодолев боль, смог написать взаимнорекурсивную функцию на ML, то понимаю, что я небезнадежен, и котелок все-таки варит. О том, сколько нового и сложного мы изучили, легко забыть, если этого не записать. Я помню, как думал, что на работе делаю только элементарные вещи, но просмотрев заметки, увидел, какое реальное количество новых навыков и знаний пришлось освоить в ходе работы за последний год. Когда мне надо сделать какой-то хитрый запрос к Git репозиторию или распаковать файл архива с какой-то опцией, я почти всегда обращаюсь к поисковику (есть кто-то вообще, кто набирает tar -xzvf правильно с первого раза?). Иногда бывает, что находишь нужную команду на каком-то форуме типа Stackoverflow, используешь ее как есть или слегка видоизменяешь под свои нужды. Попытки заносить страницы с такими ответами в закладки или избранное были тщетны: страницы терялись, ответы редактировались, найти в закладках браузера то, что нужно, становилось все труднее. Для удобства хранения и поиска я решил копировать все такие кусочки кода и команды в приложение для заметок с тегами и категориями. Теперь у меня есть такой своего рода "швейцарский нож" с командами, которые мне были когда-то нужны (посмотреть что-то в истории Git, запустить Docker-контейнер с передачей переменных окружения или собрать информацию о версии Linux сразу с нескольких машин с помощью Ansible). Скорость извлечения команды или нахождения максимально близкой команды к тому, что мне нужно, из собственного приложения заметок выше, чем из сети Интернет (при условии, что такие заметки у меня все-таки есть). По мере расширения набора команд и небольших утилит я вижу, что новые задачи (пусть и маленькие) у меня все же появляются; я узнал больше о возможностях Bash или Git, узнал об еще нескольких встроенных в Linux командах или пакетах (ncdu изменило мою жизнь!). Во многих компаниях есть некий аналог performance review - анализа производительности инженера в рамках решаемых им задач. Метрики, которые используют менеджеры при анализе, могут сильно отличаться от компании к компании. Не исключаю, что во многих случаях это может быть субъективное ощущение менеджмента о том, насколько успешен был инженер за прошедший год. Полагаться исключительно на такое ревью я бы не стал, но если у вас адекватный начальник (тимлид или техлид), можно смело попросить более подробной обратной связи о вашей работе. Они так или иначе видят, какие задачи вы закрывали (сложность и охват), какой код вы писали (если они производили его ревью), какое ревью оставляли сами, что привнесли в дизайн-документы или чаты в каналах корпоративного месенджера. Есть вероятность, что они смогут подтвердить ваш рост (даже пусть не на основе измеряемых показателей). Если учитывать рабочее время в компании особенно не нужно (речь не идет об учете времени вашей работы над каждой задачей индивидуально, консалтинге или почасовой оплате), то вести учет времени, которое идет на самообразование, на мой взгляд, очень важно. Помню, как решил заниматься вечерами алгоритмами "для общего развития" (ну и на случай, если придется искать новую работу, чтобы пройти техническое интервью, где просят крутить деревья). Проходила неделя, и я был недоволен прогрессом; мне казалось, что я лентяй и занимался слишком мало. После этого я стал использовать мобильное приложение для учета времени. Теперь каждый раз, садясь за видео с Coursera или решая задачки с Leetcode, запускаю таймер. Я пользуюсь Boosted, но подойдет любой трекер времени, в котором можно создать разные проекты и подзадачи. Когда вижу, что потратил несколько сотен часов за год, читая теорию программирования и решая задачки, я чувствую удовлетворение, понимая, что вырос как инженер (с допущением моего предположения, что такая деятельность обеспечивает мой рост как разработчика). Ведение заметок с хранением утилит и кусочков кода - это делается в рамках текущей работы. Когда на работе все нравится, есть небольшой потенциал для роста, откровенно не скучаете, но есть силы изучить что-то новое, мне кажется, есть смысл изучать рынок труда. Например, на работе вы пишете на Angular, но подавляющее большинство вакансий frontend-разработчика упоминают React. Или вы пишете backend сервисы на CPython, но заинтересовались альтернативной имплементацией, например, PyPy. Делаете анализ данных с помощью pandas? Очень интересно изучить Dask. Используете в качестве системы сборки Bazel? Вот вы уже настраиваете небольшую фабрику сборки с Buildbarn. Машинное обучение на Tensorflow? Хорошо бы глянуть PyTorch. Чтобы понять, какие технологии актуальны для конкретного рода деятельности (в моем случае - инфраструктура разработки), я раз в две недели пролистываю вакансии и выписываю названия продуктов, которых не знаю. Хочется верить, что изучив эти продукты, я не только вырасту, но и стану более привлекателен на рынке труда. Помимо этого, уже несколько раз было так, что узнавал о каком-то продукте и, изучив его, внедрял на работе. Разумеется, я против того, чтобы "тащить в проект" все новые игрушки, которые только есть; любые изменения должны быть оправданы и выгодны. Если технология упоминается во множестве вакансий, то это, на мой взгляд, идеальный вариант, чтобы присмотреться к ней. Так можно и принести пользу бизнесу (только если вы думаете, что она действительно есть), и разобраться с популярной технологией, и вырасти в профессиональном плане. Можно пойти дальше и смотреть, какое количество незнакомых технологий упоминается в описании вакансии. Если их немного (или если их число уменьшается), то можно сделать допущение, что вы растете (успеваете изучать появляющиеся технологии). Помимо вакансий на популярных сайтах вроде LinkedIn, Glassdoor и Indeed, я стараюсь присматриваться к так называемым техническим радарам. Это документы, в которых крупные компании делятся тем, о каких технологиях - продуктах, языках программирования, библиотеках и фреймворках - они узнали, и планируют ли они их использовать. Для примера можно изучить такие радары от Zalando и Thoughtworks. Можно даже создать собственный радар, чтобы следить за технологиями, которые важны для вас. Главный вывод, который я сделал для себя, заключается в том, что мой рост разработчика было бы очень трудно заметить, если бы не использование упомянутых подходов и инструментов. Удовлетворение от жизни (в рамках карьеры) за последние годы, когда я активно применял такие подходы, у меня существенно повысилось. Теперь мне не приходится переживать, что не развиваюсь, потому что могу в любой момент открыть заметки (или тайм-трекер) и посмотреть результаты проделанной работы. Надеюсь, что если другие специалисты возьмут на вооружение какие-то из этих инструментов, их жизнь тоже станет лучше.