Всем привет! Меня зовут Даниил, и я программист-самоучка.

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

Я стажируюсь в нашем бэкенд-отделе, который занимается продуктами для трекинга и параллельно работаю в своем родном отделе технической интеграции (вот уже на протяжении 6 месяцев). Основной язык в команде — Python. Его я учил самостоятельно, чтобы попасть на стажировку. В основном, конечно, по мануалам и роликам в Интернете.



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

Командная работа с Git


Когда человек приходит на свою первую стажировку, он представляет себе, что такое Git (иначе его вообще вряд ли возьмут), однако слабо представляет, как с ним работают в команде. Все мы создавали в свое время аккаунт на GitHub и радостно коммитили в master-ветку первую строчку кода, чувствуя себя настоящими профи. Так вот: это не лучший подход для больших проектов.

В командной разработке работа с Git ведется в соответствии с утвержденным git-flow. У нас, например, есть две ветки: develop и master. Никто, кроме тимлида, не может заливать код в master-ветку, потому что команда должна гарантировать, что там лежит рабочий код, который при деплое не разрушит прод. Ответственность за это ляжет на плечи тимлида, а тимлида злить не хочет никто.


Чтобы предотвратить такие ситуации, существует командное ревью. Каждый разработчик ведет работу над задачей в своей собственной ветке и в конце работы ставит merge request в develop-ветку. А тимлид уже ставит merge request в master-ветку и отвечает за качество кода перед его владельцем. Таким образом гарантируется чистота кода, который попадает в конечном итоге на прод, и минимизируются риски залить что-то, что испортит работу проекта.

Вывод: если вы хотите лучше подготовиться к работе в команде, почитайте о git-flow и начните добавлять новые коммиты в свой пет-проект через ветки.

Архитектура кода важна


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

Однако все сложилось иначе. Нет, никто не поручил мне что-то ультрасложное, но мне назначили мини-проект (milestone) по мониторингу (Python + Prometheus + Grafana), который я должен был сделать за время стажировки. Причем я сам должен был продумать архитектуру, декомпозировать проект на задачи и двигать его по стадиям Канбана. Это было волнительно, но очень правильно. Такой подход позволил моему куратору и мне самому отчетливо понять, с чем у меня проблемы, и приступить к их исправлению.

Скажу честно: первое мое решение было неудачным. И второе тоже. Я делал слишком крупные задачи, несколько раз возвращал их в бэклог, выстраивал неудачную архитектуру и не мог учесть нюансы.


Однако на данный момент большая часть проекта уже реализована, и я все отчетливее понимаю, как мой код влияет на остальной проект. Это захватывает. Я прочитал несколько статей о чистой архитектуре, изучил абстрактные классы, научился сначала планировать интерфейс и только потом приступать к реализации. Не могу сказать, что я во всем разобрался, но точно лучше понял фразу «Любую проблему можно решить введением дополнительного уровня абстракции, кроме проблемы чрезмерного количества уровней абстракции». А еще я научился правильно оценивать свои силы (но это не точно).
Вывод: интересуйтесь архитектурой кода. Ничего страшного, если поймете не сразу, это вопрос контекста. Почитайте, как спроектирован Netflix, или загляните на сайт Мартина Фаулера. Попробуйте спроектировать небольшую систему до того, как сядете писать код.

Умение работать с окружением упрощает жизнь


В нашей компании все сервисы запускаются в контейнерах. Соответственно, каждый разработчик должен понимать, как работает тот же Docker, как написать простой Dockerfile или поднять свои сервисы через Docker Compose.

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


В этот же совет можно включить и работу с IDE. До начала стажировки я писал все свои программы исключительно в Emacs, но, когда начал работу, решил перейти на более продвинутый инструмент, и в итоге не пожалел. Кое-где я до сих пор предпочитаю пользоваться консолью (например, опустить все контейнеры удобнее через docker stop $(docker ps -qa)), но в остальном я от всей души благодарен Git GUI и подсказкам в PyCharm.
Вывод: почитайте о Docker. Попробуйте запустить код в контейнере. Попробуйте IDE для вашего языка и посмотрите, какие возможности она вам может дать.

Документация и тесты — не менее важны чем код


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

До стажировки я пользовался UnitTest и PyTest, но только в рамках обучения. А Mock, например, не пользовался вообще, потому что мои проекты не были настолько сложны, чтобы нужно было подменять данные (ну, либо мои тесты были настолько плохи).


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

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

В дополнение скажу, что мы еще и подробно аннотируем типы в Python, но если вы пишете на строго типизированном языке, этот комментарий не для вас. (В этом плане очень помогает использование линтера, например Flake8).
Вывод: Уделяйте внимание тестам и документации. Начните с обычного readme-файла на Git — опишите, как запустить проект, что он делает и какой результат ожидается. Попробуйте написать тесты к ключевым методам и функциям, а еще лучше сделайте Docker Compose, который запускает прогон всех тестов.

А какой опыт был у вас?


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

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