У меня сложилось стойкое ощущение, что сейчас в связи с высокими зарплатами в IT на рынок попадает много самоучек и выпускников курсов с названиями вроде «Стань разработчиком за N месяцев».
Около 6 лет назад таким же самоучкой был и я. На протяжении примерно 4 лет я получал опыт только во фронтенде. Тем не менее, я был уверен, что этого достаточно, чтобы считаться крутым разработчиком. Но потом мне повезло попасть в команду, в которой нет разделения на фронтов, бэков, тестировщиков и девопсов. Я открыл для себя очень много нового и хотел бы поделиться с вами своими наблюдениями.
О команде
Сначала расскажу пару слов о команде. Как уже написал, в ней нет разделения по специализации. Каждый участник команды — это Software Engineer с различным опытом. Кто-то имел опыт преимущественно во фронте, кто-то писал на Python, а кто-то на C++.
В плане управления здесь как в любой другой команде Тинькофф. Вы сами вправе выбрать Kanban или Scrum, придумать что-то свое, провести какой-нибудь эксперимент. Это все приводит к тому, что у тебя нет работы, «скинутой» сверху. Есть цели, а как их достичь — это дело команды.
И вот здесь проявляется главное отличие. Если обычно прорабатывается какая-то задача и делится на фронт и бэк, то фронт делают фронтендеры, бэк — бэкендеры, а инфраструктуру и CI/CD часто настраивает вообще отдельная команда. В нашем же случае это все должен сделать ты сам. То есть нет возможности сказать: «Я свою часть сделал, это Вася не задеплоил, не проверил и не написал в ТЗ». Ты отвечаешь за задачу от начала и до конца. Это очень сильно меняет твой образ мышления.
Спустя полтора года такой работы я стал совершенно иначе смотреть на процесс разработки и собственного развития. Перейдем к тому, чему я научился за это время.
Не торопитесь
Самый главный урок, который я вынес, — не торопитесь! Если вы столкнулись с новой технологией, которая займет прочное место в вашем стеке, просто внимательно и вдумчиво изучите базу: прочитайте документацию, пройдите обучение или, если время совсем поджимает, обратитесь за помощью к экспертам.
Попытка освоить какую-то технологию с наскока быстро приведет к истощению и выгоранию. Конечно, многое зависит от индивидуальных особенностей, но механизм у всех одинаковый: построение новых нейронных связей в мозге. Это очень ресурсоемкий процесс, поэтому не нужно его усложнять.
Базовые знания необходимы
Если в карьере разработчика вы планируете достичь чего-то большего, чем создание компонентов на каком-нибудь фреймворке, то определенно нужны базовые знания. Как работает память, процессор, различные протоколы, браузер, что такое linux-контейнер, как писать алгоритмы и так далее. Мне казалось, что это все не нужно. Я был сильно удивлен.
Возможно, вам никогда не придется настраивать сети в кластере, писать алгоритмы для баз данных или расчета полета ракеты, но полезно будет в случае необходимости упаковать свой код в Docker-контейнер или написать функцию бинарного поиска.
Например, очень популярная реальная задача — написать функцию, которая будет искать элемент в массиве. Мы знаем, что вызываться эта функция будет много раз. Если вы будете понимать базовые вещи, то не сделаете что-то вроде такого:
const some = array.find(el => el.id === someId);
Этот код будет проходить по массиву до первого вхождения, то есть на каждый поиск мы будем обходить весь массив. Представьте, что в нем 100 тысяч элементов. Но если подумать, то будет лучше сложить элементы в Map
по ключам и брать их оттуда. Если ключей нет, можно воспользоваться той самой функцией бинарного поиска. Здесь все зависит от ситуации.
«Черных ящиков» не существует
Данный пункт практически напрямую вытекает из предыдущего. Все, что не касалось напрямую фронта, было для меня «черным ящиком».
В Тинькофф работают крутые специалисты, и я полагал, что они лучше меня знают, что делать на своей стороне, поэтому не сильно вникал. Раньше меня не касалось все то, что происходит на бэке, как работает база данных, как приложение разворачивается. В новой же команде мне предстояло их открыть, и вот что я узнал.
Разделение ответственности — миф
Вас касается все, что происходит в вашем проекте, от идеи до снятия метрик с готовой фичи. Это можно и нужно изучать, предлагать свои решения и в целом всячески участвовать. Вы очень сильно прокачаетесь как профессионал, если не будете скидывать ответственность на других, будете самостоятельно решать проблемы и разбираться со сложностями.
Способов повлиять на продукт очень много. Например, для продуктовых команд можно использовать различные практики вроде «Трех амиго», когда за один стол садятся все узкие специалисты для выработки оптимального решения. Можно участвовать в процессах другой части команды — смотреть мёрдж-реквесты команды бэка или помогать проводить регресс. Вряд ли вам будут мешать.
Код нужно доставлять
Даже если вы написали прекрасный код, он не имеет никакой ценности до тех пор, пока не приносит кому-то конкретному реальную пользу. А для этого ваш код нужно доставить — собрать, проверить и задеплоить. Поэтому любому разработчику нужно хотя бы немного разбираться в девопс.
Не обязательно сразу разворачивать и настраивать кластера Rancher или Kubernetes. Начните с малого — напишите Dockerfile и запустите ваш сервис в Docker'е. Теперь для этого даже не нужен Linux: благодаря WSL он есть даже на Windows 10 Home.
Обмен опытом
Если у вас есть страх погружения в другую область из-за того, что все придется начинать сначала, то выдохните, потому что это не так. Часто вы сможете опереться на свой предыдущий опыт. Например, если вы писали на Angular, Dependency Injection в Spring не создаст практически никаких трудностей, а написание RESTful-сервиса на всех языках и фреймворках будет следовать единым принципам.
Если же говорить о пользе для вашей работы фронтендером, то современные фреймворки говорят нам, чтобы мы мыслили данными, а не DOM-элементами. Мы же в основной своей массе теперь думаем компонентами и часто храним бизнес-логику прямо там (а где еще ее хранить?). Опыт в объектно-ориентированных языках программирования вроде Kotlin изменит ваше мышление, и на фронте у вас появятся разные классы для разных задач:
получение данных —
SomeService
;валидация данных —
SomeValidator
;перевод в нужную модель данных —
AnotherFactory.fromSome(some)
;обработка данных —
AnotherDataService
;хранение данных —
AnotherDataStore
;отображение данных —
AnotherDataComponent
.
Часто эти задачи пытаются уместить в один компонент, из-за чего они очень сильно разрастаются и поддерживать их становится слишком сложно. Раньше я думал, что это нормально и естественно, а не следствие непродуманной архитектуры. Теперь я полностью уверен в обратном.
Да, классов стало много, но каждый из них выполняет только одну функцию. Такой класс очень просто использовать и тестировать. Это реализация принципов SOLID, которые непривычны для фронтендеров, но на бэке используются повсеместно.
Измерения важны
Даже когда ваше приложение работает и им пользуются люди, без снятия показателей вы не знаете, что с ним реально происходит. Рано или поздно вам придется ответить на следующие вопросы:
Как работает сервис? Справляется ли с нагрузкой? Хватает ли ресурсов?
Кто пользуется сервисом? Как он пользуется сервисом? Какой опыт получает?
Если этих данных нет, то вы не знаете о вашем сервисе практически ничего. В моем опыте было время, когда мы узнавали о сбоях в работе только из обращений пользователей. Это был внутренний сервис, но тем не менее.
В итоге мы занялись наблюдаемостью — написали хорошие логи, собрали метрики по потреблению памяти и CPU, работе Garbage Collector и так далее. В итоге удалось обнаружить бесконечное потребление памяти сервисом из-за бага в одной из зависимостей библиотеки мониторинга. Узнать это без метрик было бы невозможно.
Немного о преимуществах
За последний год я успел написать два приложения на Spring в связке с Kotlin, два маленьких фронта на Angular и React, несколько билдов на TeamCity DSL и немного поработать над сервисом на Python. Главное, что я могу сразу сказать: Developer Experience в JavaScript/TypeScript-экосистеме ушел далеко вперед.
Мы уже привыкли, что можем запустить два кейса одного теста вот в этом файле, который я только что поправил. Он автоматически перезапустится после внесения изменений. Можно даже воспользоваться QuokkaJS, и редактор в реальном времени покажет покрытие.
Мы привыкли, что можно не думать о форматировании кода, за нас автоматически это сделает Prettier, а Husky или Lint Staged сами запустят все проверки и форматирование в момент коммита. Трудно представить проект на JS/TS и не увидеть всю эту автоматизацию.
Поэтому готовьтесь к издержкам при работе на других стеках. За некоторыми исключениями на многих других платформах всех этих автоматизаций просто не существует. Возможно, вы станете одним из тех, кто сможет эти автоматизации создать.
Самый главный вывод
Обобщая весь свой опыт, могу сказать, что самое важное — развиваться. Если вам уже стало немного скучно или просто что-то заинтересовало — погрузитесь в это. Если вы фронт, то попробуйте себя в бэке или в девопсе. Чем сильнее вы измените свою привычную работу, тем больше будет создано нейронных связей и тем ярче будет новый опыт.
Более того, чем больше зон вы охватите — тем сильнее будет синергетический эффект. Полученные знания в разных областях дополняют друг друга, и в итоге получается комплексная база Computer Science. Из узкого специалиста вы превращаетесь в софтверного инженера, способного справиться с любой задачей.