Новиков > путь в Big Tech – Telegram
Новиков > путь в Big Tech
184 subscribers
94 photos
192 links
От зеро-кодинга на стройке до написания высоконагруженных сервисов в Big Tech. 

Пишет SWE в Avito.ru (backend), в прошлом: .NET developer и сертифицированный специалист по использованию BIM.

Написать автору: @nvkv_ai

Книги: https://boosty.to/time2code
Download Telegram
Новиков > путь в Big Tech pinned «Пролетело 3 года! Хочется отметить основные вехи, чтобы зафиксировать достигнутое и двигаться дальше: 2020 год 👷‍♂️ Весной я решил поменять свою жизнь и стать программистом. Я был ведущим инженером и придумал как делать свои задачи быстрее при помощи C#.…»
Постепенно возвращаюсь к решению Литкода.

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

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

#процесс #алгоритмы
Почему я стал меньше писать кода?

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

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

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

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

Очевидно, что весь фокус смещается с вопроса "как написать фичу?" на вопрос "где написать?". И на вычитку всего проекта и поиск подходящего места с учетом разделения ответственности и всех лучших практик проектирования может уйти много времени. У меня уходило несколько дней только для того, чтобы разобраться в каком сервисе и в каком файле я должен буду добавить 1 строку кода!

Вот так и получается, что для добавления ифчика и закрытия 1 задачи может уйти полспринта. Пример решения заурядной задачи:
1) знакомство с кодовой базой сервиса и поиск места для нового условия;
2) добавление нового юнит-теста на свой ифчик;
3) деплой в дев-окружение;
4) тестирование QA (при необходимости)
5) код-ревью от ответственных сервиса или всех заинтересованных;
6) выкатка в продакшн с последующим мониторингом и готовностью быстро откатить изменения.

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

#опыт
👍1
Практика

На скриншоте представлены взаимосвязи между некоторыми файлами .go в одном из микросервисов компании (кажется их чуть больше тысячи на текущий момент). Каждый файлик содержит от 100 до нескольких тысяч строк кода.

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

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

Без построения подобных диаграмм довольно трудно продираться через все слои абстракции в незнакомом сервисе.

В общем случае, при реализации сложной задачи помогает 2 вещи:
1) Максимальная декомпозиция. Всегда проще решать маленькие задачи, а потом их закладывать в решение для сложной.
2) Создание диаграммы взаимоотношений, как, например, на скриншоте.

#инструменты #практика
Март 2023:

Довольно напряженный был месяц в плане работы. Необходимо было реализовать важную фичу, которая должна была работать на всех клиентах: Android, iOS, Mobile, тщательно протестировать (чему, конечно, способствует QA, но до передачи тестировщику разработчик обязан покрыть все юнит-тестами и базово самостоятельно протестировать) и задеплоить на прод, анализируя метрики в Графане во время выкатки. Пришлось, конечно, овертаймить, чтобы успеть вовремя, но это я списываю на недостаток опыта. Когда задача уже завершена, ничто не сравнится с эмоциями от работающей функциональности в живом продукте, к которой ты непосредственно приложил руку.

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

Очередной раз попал в Высшую Школу Программирования Сергея Бобровского (в августе 2022 получил "пожизненный" бан за просроченный дедлайн - сделал серьезные выводы из этого). Спустя полгода удалось попасть под амнистию и записаться на курс по парадигмам программирования, которым сейчас активно занимаюсь в фоне.
// Знаю, что Школа может показаться очень специфичной, но мне она помогла с развитием правильного программистского мышления в начале пути и уверен, что поможет заложить необходимую базу - концентрат айтишного образования.

Решил 2 задачки на литкоде. Всего две, но это на 2 больше, чем за прошлые месяцы.

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

#результаты
Апрель 2023:

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

Закончил курс в ВШПСБ по парадигмам программирования. Познакомился с мультипарадигменным языком Julia и углубился в проблемы параллелизма и нюансы атомарности.

В рамках ВШПСБ приступил ко второму курсу по парадигмам программирования (изучаю декларативную модель). Также получил задание подтянуть свои знания по стеку HTML/CSS/JS + веб-фреймворк Gin, с помощью которых нужно будет сделать в мае-июне дипломный проект.

Познакомился с протоколом odata, с помощью которого реализую небольшой заказной проект.

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



📌 С данного момента планирую коммититься на определенный объем работы в грядущем месяце

Планы на май:
🔖 Пройти курс по верстке HTML / CSS (до 14 мая)
🔖 Пройти курс по JS (до 14 мая)
🔖 Освоить веб-фреймворк Gin для Go на базовой уровне (до 14 мая)
🔖 Реализовать первую версию заказного проекта (odata) и передать Заказчику в тестирование
🔖 Пройти не менее половины второго курса по парадигмам программирования
🔖 Наметить планы по дальнейшему развитию, как инженера-программиста, на промежутке 3/6/12/36 месяцев

#результаты
Начал делать "дипломный" проект в ВШПСБ. Он идет бонусом к основному курсу, который прохожу по декларативной модели, и состоит из 25 заданий (основные боли в бэкенд разработке). Тема: автопарк, регистрация и учет автомобилей.

Проект нужно успеть выполнить в течение 50 дней, то есть на каждое задание 1-3 дня. Для простоты будем нумеровать их как "День N".

Вся разработка открыта и будет здесь.

#проект
День 1

Задание
:
1. Создать основную модель Vehicle (автомобиль) без марки и тех. характеристик.
2. Сделать веб-интерфейс, чтобы можно было посмотреть список машин в базе.

Ход работы:
1. Создал структуру проекта в соответствии с общепринятым стилем.
2. Подключил БД (PostgreSQL), которую предварительно развернул через Docker.
3. Создал основные модельки для БД + метод получения всех моделей из базы.
4. Написал файлы миграций (для создания всех таблиц в БД), но пока запускал их руками без создания какого-либо механизма миграций.
5. Завел Changelog, который помогает быстро просмотреть всю историю изменений в удобном формате.
6. Написал первый в своей жизни динамически формирующийся *html-файл для отображения всех моделей из базы и даже подключил Bootstrap!

Подумать:
1. Как лучше всего писать файлы-миграций и автоматически их применять при деплое проекта.
2. Как в Go организуются файлы html/css, которые используются для отображения различных страниц.

Результат на скриншоте.

#проект
День 2

Задание
:
1. Добавить отдельную модель брендов (имя бренда, тип (легковой, грузовой, автобус, ...), 3-4 другие хар-ки - бак, грузоподъёмность, кол-во мест).
2. Привязать её к основной модели Vehicle.
3. Сделать вьюшку для просмотра брендов (аналогично первой).

Ход работы:
1. Добавил отдельную модель для брендов (тип машины почему-то решил енамом делать - также как и цвет).
2. Бренд привязал через внешний ключ в модели Vehicle "Model ID" (связь один ко многим).
3. Пришлось пересоздавать БД, так как основная табличка обновилась (когда появятся миграции, то с этим проблем вообще не будет).

Подумать:
1. Как лучше проектировать БД с учетом множества связей и нормальных форм.
2. Сейчас получение моделей сделано немного костыльно, поэтому лучше переписать все, используя контроллеры.

Результат на скриншоте.

#проект
Дисциплина x Мотивация

Если бы меня спросили одно из ключевых качеств в обучении чему-нибудь новому (например, программированию), то мгновенным ответом последовало бы: "дисциплина".

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

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

Уже несколько лет пытаюсь нащупать идеальное соотношение work-life-balance, но пока с переменным успехом, в современном мире очень сложно держать концентрацию - слишком много отвлекающих факторов. Но я стараюсь.

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

Наверстываю упущенное:
1
День 3

Задание
:
Добавить в UI максимально простой CRUD: редактирование, добавление, удаление автомобилей.

Ход работы:
1. Добавил новый эндпоинт '/api/v1/vehicles/admin', на котором доступны все основные операции над автомобилями (vehicle).
2. Добавил редирект с основной вьюшки '/view/vehicles' через кнопку "admin" на новый эндпоинт из п.1 (так как верстку еще осваиваю, то мне оказалось проще все разместить на отдельном экране, чем компоновать круды вместе с основным view всех авто).
3. Удивился сколько рутинной работы требует верстка простого блока с добавлением новой модели... (валидация полей, обработка ошибок, вывод понятных пользователю сообщений о некорректном вводе или успешной операции, логирование и пр.).

Подумать:
1. Как применяется паттерн MVC в Go (лучшие практики).
2. Как организуется компонентная верстка.
3. Как можно улучшить свой проект и учесть все детали из п.3 выше (в первую очередь - обработка ошибок).

Результат на скриншоте.

#проект
День 4

Задание
:
Сделать выбор бренда выпадающим списком названий.

Ход работы:
1. Выпадающий список - это фактически метод получения необходимых опций из БД и представление его в HTML.
2. За получение всех моделек у нас отвечает уже существующий метод контроллера "models.Provider.FetchAllModels", поэтому нужно лишь подобрать подходящий элемент управления, которым стал select, опции которого создаем итерируясь по результатам провайдера.
3. Еще сделал список цветов выпадющим списком, но так как для них нет таблички, то он пока хардкодом.
4. Также немного отрефакторил существующую структуру и поправил компоновку.

#проект
День 5

Задание
:
Добавить REST API, по которому (по отдельному url) будет выдаваться список всех машинок в формате json (пока без авторизации и прочего).

Ход работы:
1. Так как основной ендпоинт по выдаче машинок у меня был уже готов (я с него начинал и уже им обогощал HTML-файлик для создания view), то осталось только его оформить в соответствии с REST.
2. Добавил json-тэги для внутренних моделек, чтобы json отображался красивее + настроил округление дат до секунды.

Подумать:
Как еще можно улучшить проект согласно лучшим практикам использования JSON API.

#проект
Май 2023:

Пройти курс по верстке HTML / CSS (до 14 мая)

Пройти не менее половины второго курса по парадигмам программирования

Начал разрабатывать "дипломный проект" писал о нем выше. Текущий прогресс: 6/25

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

▶️ Пройти курс по JS (до 14 мая) // активно взялся за учебник JS (прошел 1/3 основ языка)

▶️ Освоить веб-фреймворк Gin для Go на базовой уровне (до 14 мая) // читаю документацию, изучаю примеры (в объеме, необходимом для проекта)

▶️ Реализовать первую версию заказного проекта (odata) и передать Заказчику в тестирование // выпустил предрелизную версию, остались небольшие доработки

Наметить планы по дальнейшему развитию, как инженера-программиста, на промежутке 3/6/12/36 месяцев



Планы на июнь:
🔖 Закончить курс по JS
🔖 Закончить освоение веб-фреймворка Gin
🔖 Завершить проект odata и передать Заказчику в тестирование
🔖 Завершить второй курс по парадигмам программирования
🔖 Наметить планы по дальнейшему развитию, как инженера-программиста, на промежутке 3/6/12/36 месяцев
🔖 Выполнить, по меньшей мере, 16 из 25 заданий дипломного проекта

#результаты
День 6

Задание
:
1. Добавить ещё две базовые модели: Enterprise (предприятие) и Driver (водитель). Основные поля этим моделям придумать самостоятельно. Например, название + город, имя + зарплата.
2. Организовать между ними такие связи:
- Предприятию могут принадлежать несколько автомобилей (один ко многим).
- Предприятию могут принадлежать несколько водителей (один ко многим).
- Автомобиль и водитель могут принадлежать только одному предприятию.
- Каждому автомобилю может быть назначено несколько водителей (один к многим).
- Водители для разных автомобилей могут пересекаться (один водитель может быть назначен разным автомобилям).
- Один из назначенных водителей дополнительно считается "активным" (флажок или через связь) -- это тот, кто работает на машине в данный момент.
- Активный водитель может работать только на одной машине (не может быть назначен активным на второй автомобиль).
- Создаваемый водитель исходно ни к какой машине не привязан.
3. Списки водителей и предприятий отдельно выдавать через REST.
4. Сделать 2-3 предприятия, в каждом по нескольку автомобилей с водителями и без.

Ход работы:
1. Завел в проект 2 новые модельки (файлик со структурой + миграции в БД).
2. Реализовал провайдеры для них, чтобы получать выдачу по REST.
3. Сложнее всего было продумать все необходимые поля для таблиц, чтобы обеспечить соответствующие заданию связи. Пришлось даже набросать схемку в draw.io, чтобы не запутаться. Обязательно нужно помнить про необходимые связи и ключи между таблицами.
4. Также создал табличку drivers_vehicles для реализации связи "многие ко многим". При таком типе связи неизбежно приходится создавать таблицу посредника.

Подумать:
1. Как проектируются БД (изучить лучшие практики).
2. Как грамотно составлять схемы с таблицами и правильно указывать все необходимые отношения между ними.

#проект
День 6

Результат работы:
1. Получение всех автомобилей (REST-ручка).
2. Получение всех водителей (REST-ручка).
3. Получение всех предприятий (REST-ручка).
4. Получение значений таблички со связями между водителями и автомобилями (REST-ручка).
5. Схематическое изображение всех табличек в БД (черновик).

#проект
День 7

Задание
:
1. Добавить модель Manager (менеджер) - наследник от стандартного пользователя, для которого нужна авторизация.
2. Предприятию могут принадлежать несколько менеджеров.
3. Менеджеру могут "принадлежать" (быть видимыми) несколько предприятий.
4. Менеджер получает в REST-запросах только объекты видимых ему предприятий.
5. Сделать случай, когда три предприятия 1,2,3 и два менеджера, одному принадлежат предприятия 1,2, другому 2,3.

Ход работы:
1. Завел модельку Manager (в основном понадобился только файл миграции, но не сама гошная структура).
2. Создал табличку manager_enterprise, чтобы хранить связку менеджер-предприятие, по которой я впоследствии достаю все предприятия, принадлежащие менеджеру.
3. Добавил стандартную мидлвару BasicAuth(), которая идет с джином из коробки и с ее помощью по адресу: /admin авторизую менеджера по связке логин/пароль и затем выдаю ему список его предприятий.

Подумать:
1. Почитать больше про middleware.
2. Изучить JWT-аутентификацию.

#проект
День 8

Задание
:
Изучить, что такое curl, и организовать с его помощью запрос машинок с авторизацией менеджера, как было в браузере в предыдущем задании.

Ход работы:
1. Прочитал по диагонали документацию.
2. Для организации запроса добавил path /admin/vehicles (доступный только через авторизацию), через который выдаю все машинки, принадлежащие менеджеру, через привязанные к нему предприятия. То есть теперь менеджер сможет посмотреть и список всех предприятий (/admin/enterprises), и машин.

Запрос с авторизацией выглядит так:
curl -v --user ismirnov:one http://localhost:8080/admin/vehicles.

#проект