Новиков > путь в 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
С чего начинать код-ревью? [2/2]

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

Алгоритм (2/2):

7️⃣ Тесты. Вся логика должна быть покрыта тестами. Обязательно. В крайних случаях, если может сорваться запуск эксперимента или нужен срочный хот фикс, допускается завести задачу на написание тестов и положить ее в будущий спринт. На интервью, если показывают только один файл, как на нашем примере, то обязательно проговорить, что должны быть тесты на новую логику.

8️⃣ Общая архитектура (в т.ч. организация директорий в проекте). Свое ли место занимает код, правильно лил организован в пакетах, доступен ли для расширения другими командами и пр. Тема очень обширная. В чужом сервисе иногда сложно понять общую концепцию, посмотрев всего несколько файлов, но при наличии опыта плохую архитектуру видно сразу.

9️⃣ Принципиальным моментом может стать сигнатура функции. Важно обращать внимание на то, что мы передаем (и как) и что возвращаем. В нашем примере можно заметить 2 вещи: 1) Мы работаем с базой данных, но не передаем контекст (ctx.Context) а значит теряем гибкость и другие полезные возможности; 2) Передаем партицию БД в функцию, чего мы делать явно не должны на этом уровне (c партициями работаем снаружи).

1️⃣0️⃣ Нагрузка. Если у вас высоконагруженное приложение, то крайне важно обратить внимание на создаваемую вашими изменениями нагрузку. Согласована ли она с оунерами сервиса и готовы ли мы к ней? Отсюда вытекают всевозможные оптимизации, такие как использование горутин (если возможно делать несколько действий асинхроонно) и работа с ними. Частая ошибка - пересоздавать какой-нибудь объект в цикле в то время, когда он не меняется при итерациях и есть удобная возможность объявить его до.

1️⃣1️⃣ Работа с секретами. Обращайте внимание на то, как организована работа с переменными среды и различными секретами. Очевидно, что:
sql.Open("mysql", "username:password@tcp(127.0.0.1:3306)/jazzrecords") - недопустимо. Чувствительную информацию нужно получать из окружения или защищенного хранилища.

1️⃣2️⃣ Наличие уязвимостей. Так как мы работаем с БД, то важно проверить код на наличие инъекции. Подобный запрос уязвим:
query := fmt.Sprintf("insert into userstatushistory (user_id, status, inserted_at) values (?, ?, ?, ?)", userID, partition, status, time.Now())

Пользовательский ввод важно валидировать. Можно использовать различные средства предоставляемые библиотеками:

rows, err := db.Query("insert into userstatushistory (user_id, status, inserted_at) values (%v, %v, %v, %v)", user_id, status_ inserted_at)


После всех исправлений финальный код может выглядеть так:


// package domain
package storage

import (
"context"
"database/sql"
"fmt"
"os"
"time"
)

// type UserStatusHistoryStore struct {
type UserStatusHistory struct {
db *sql.DB
}

// func New() UserStatusHistoryStore {
func New() UserStatusHistory {
// db, err := sql.Open("mysql", "username:password@tcp(127.0.0.1:3306)/jazzrecords")
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/jazzrecords", os.Getenv("user"), os.Getenv("password"), os.Getenv("ip")))
if err != nil {
panic(err)
}

// return UserStatusHistoryStore{
return UserStatusHistory{
db: db,
}
}

// func (s *UserStatusHistoryStore) Save(userID, partition, status string) {
func (s *UserStatusHistory) Save(ctx context.Context, userID, status string) error {
// query := fmt.Sprintf("insert into userstatushistory (user_id, status, inserted_at) values (%v, %v, %v, %v)", userID, partition, status, time.Now())
// s.db.Exec(query)
_, err := s.db.Query("insert into userstatushistory (user_id, status, inserted_at) values (%v, %v, %v)", userID, status, time.Now())
if err != nil {
return err
}

// ...

return nil
}


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

Если вы учли все вышеописанное, то с большой долей вероятности пройдете очередное код-ревью.
👍2
👤 Делаем CV с ATS >80%

Пару недель назад вдохновился постом Jerry Lee, который опубликовал "продающее" резюме.

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

F-формат

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

XYZ

В блоке со своей карьерой соблюдайте формулу: XYZ (см. статью). Надеюсь, со временем тоже приведу к ней все полностью.

LLM считает ATS

Llama3 высоко оценила мое резюме, обозначив цифру в 84%, преимущественно снизив оценку из-за нерелевантного опыта в строительстве. Учитывайте это, подаваясь на конкретную вакансию.

Мое обновленное резюме доступно здесь. А самая первая версия выглядела так.
👍2
Апрель 2024:

навыки
✔️ Завершил курс по объектно-ориентированному программированию. Основные моменты разбирал здесь.
✔️ В рамках подготовки к собеседованию прочитал книгу “100 Go Mistakes and How to Avoid Them” и довольно подробно изучил Kafka, с которой раньше непосредственно работать не приходилось.
✔️ Написал первый пост, используя telegraph, где рассмотрел задачи с реального интервью.
✔️ Рассказал в 2-х частях как проводить код-ревью.
✔️ Завел репозиторий, где планирую выкладывать реализации основных паттернов проектирования на Go (уже выложены: observer и strategy).

карьера
✔️ Впервые за полтора года поучаствовал в техническом интервью по Go, БД и брокерам сообщений. Рефлексия здесь.
✔️ Обновил верстку своего резюме на github pages.
✔️ Обсудил с руководителем возможности для финансового роста, так как стало казаться, что моя квалификация стала опережать текущую компенсацию.
✔️ Взял на себя ответственность за онбординг нового бэкендера в команду (одна из компетенций инженера уровня senior).

прочее
✔️ Использовал 14 дней из накопленного отпуска, которые очень помогли разгрузиться. Крайне советую не пренебрегать этим, так как усталость в итоге сказывается не только на качестве вашей работы, но и отношениях с коллегами и близкими.

#результаты
🔥6👍2
В конце января обозначил ОКР'ы на этот год.

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

Фокусируемся .

1. Книги: Design Patterns и System Design

📌 Закончить до 31 мая

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

-

2. Новые роли в команде: Чемпион по безопасности и эксперт подачи в своей вертикали.

📌 До 24 мая

Запланировать день, когда проведу сессию по моделированию угроз с командой; также нарисовать схему взаимодействия всех сервисов и библиотек во время подачи объявления.

-

3. Менторство: Онбординг.

📌 Ближайшие 6 месяцев продолжаю активно погружать в разработку нового бэкендера.

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

Никак. Но есть альтернатива.

Несколько лет назад общался со знакомым на тему тайм-менеджмента и личной эффективности. Обсуждали обилие дел и недостаток времени.

В какой-то момент я задался вопросом: «Как все успевать, когда столько всего важного и срочного вокруг?».

Ответ меня поразил. Прозвучало: «Может быть тебе не нужно успевать все?».

* * *

У каждого человека есть ежедневная емкость (capacity) для задач, которые он может сделать с заданным качеством (определяется его опытом).

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

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

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

Сегодня хочу дать универсальный фреймворк, который работает для меня.

🧾 Фреймворк

1) Выписываем все срочные и/или важные задачи на ближайшую неделю.
2) Отбираем N задач, которые хотим сделать за 1 день (число для каждого индивидуальное, у меня, например, 5-6).
3) Распределяем задачи по 3-м зонам:

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

🟨 - зона буфера (делаем по ходу дня, сюда попадают задачи, не требующие больших трудозатрат, но которые желательно выполнить за день без привязки ко времени)

🟩 - зона резерва (делаем, если разобрались с задачами из первых двух зон, невыполнение таких задач не ведет ни к каким последствиям)

4) Все, что не успели за день, отправляется в общий список на неделю (на следующий день автоматически не переносим!).

5) Для очередного дня применяем п.2.

6) По завершении недели оставшиеся задачи оцениваем: что перестало быть актуальным, а что лучше все-таки сделать. «Полезный остаток» отправляется в общий пул задач, из которого затем формируется п.1.

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

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

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

P.S.: Какую бы систему для планирование вы ни использовали, это гораздо лучше полного отсутствия системы.
👍101🥴1
{:permitted_use_established=>

Такой строчкой нас встречает официальный документ из Росреестра, заверенный ЭЦП.

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

В чем сложность покрыть формирование PDF-файла юнит-тестами? Форма стандартная, поля фиксированные. Полагаю, что изменение структуры случается крайне редко, но даже если нет, то добавить/удалить юниты ничего не стоит.

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

Вывод один: пишите тесты, увеличивайте code coverage. Поверьте, лучше написать тесты, а потом удалить, чем так и не написать.
💯31👍1
Не шутите с индексами, не верьте гарантиям и пишите надежный код

Работа с индексами массива сопряжена со множеством проблем. Тут и классическое "IndexOutOfRange", и, конечно же, получение неверного элемента из запрашиваемой позиции.

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

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

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

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


package main

func main() {
tag := getTag([]string{"feature"})
if enableFeatureByTag(tag) {
print("OK")
return
}
print("FAILED")
}

func enableFeatureByTag(tag string) bool {
return tag == "feature"
}

func getTag(values []string) string {
if len(values) == 0 {
return ""
}
return values[0]
}


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

Оказалось, что в код попало то, чего не должно там быть в принципе. Гарантия, что массив состоит из одного значения, была нарушена, соседняя команда решила добавить еще одно значение ("json"), очевидно, не слышав ни про какие договоренности. Это же массив, почему бы его так и не использовать?

* * *

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


package main

func main() {
tag := getTag([]string{"json", "feature"})
if enableFeatureByTag(tag) {
print("OK")
return
}
print("FAILED")
}

func enableFeatureByTag(tag string) bool {
return tag == "feature"
}

func getTag(values []string) string {
for _, v := range values {
if v == "feature" {
return v
}
}
return ""
}


Герои вымешлены, все совпадения случайны :)

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

1. Забудьте про явную завязку на любые индексы, используйте безопасные конструкции (например, итерация по значениям массива). Заворачивайте коллекции в обертки с безопасным доступом к значениям и т.д.
2. Не верьте договоренностям, особенно словесным. Верьте написанному коду и тому, что может произойти в нем, исходя из общей логики и передаваемых аргументов (если код ответственный, то используйте фаззинг).
3. Лучше надежный и читаемый код, чем хрупкий, но сверхоптимизированный.
4. Помните, что код пишут люди, а им свойственно ошибаться.
🤔2
Как сделать продакшн среду стабильнее?

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

В Авито это называется Live Site Review (LSR) и хорошо описано в playbook. Очевидно, идея не нова, а берет свое начало из лучших SRE практик.

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

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

1. На инцидент заводится задача, которая затем станет основным артефактом о произошедшем.
2. Опустим подробности процесса починки, который сопряжен с большим количеством "веселья" (особенно, когда начинается цепочка с призывом ответственных в канал по решению проблемы). После исправления - фиксируем все, что может помочь в дальнейшем разборе, в задаче из п.1 (обязательно должна быть ссылка на тред(ы), где обсуждалась и решалась проблема).
3. Как правило, в больших компаниях есть человек, который фасилитирует данный процесс - инцидент-менеджер. Такой человек следит за всем: от появления первого сообщения о проблеме до момента, когда работы направленные на исправление первопричин произведены и все задокументировано. Одной из обязанностей менеджера является организация встречи со всеми причастными, где будут выясняться причины произошедшего и формироваться экшн-айтемы.
4. Итак, инцидент-менеджер создал встречу и пригласил всех. Теперь необходимо вместе пробежаться по чек-листу (как правило, задача из п.1 имеет унифицированный шаблон для разбора инцидентов), собрать фактуру и зафиксировать всю информацию. Для лучшего понимания предлагаю посмотреть "список типовых вопросов, которые стоит обсудить при разборе LSR".
5. Финальным аккордом должны стать экшн-айтемы с назначенными ответственными и обозначенными сроками выполнения. Очевидно, что такие задачи имеют приоритет при взятии в работу.

За 2 года в компании меня дважды приглашали на разбор инцидента, и это всегда очень интересно. По сути, вся встреча - это мозговой штурм с ответами на вопросы: "Можно ли быстрее было среагировать на проблему?", "Почему это допустили?", "Чего не хватило при тестировании?" и пр.

Удивительно, после LSR, когда о проблеме известно почти все, а обстоятельства очевидны, - видеть какая мелочь могла породить серьезный инцидент.

Часто это последовательность неудачного стечения обстоятельств. Как эффект бабочки или домино: один неосторожный if'чик или взятие элемента по индексу поломало отлично работающую фичу; метрики просели, но алерты не сработали, так как были некорректно настроены; дежурный не придал значение одному из многих упавших тестов синтетического мониторинга, так как после фича-фриза все немного штормило и случалось много ложных срабатываний; в конечном итоге оперативно пофикшенный баг не мог сутки доехать до прода из-за не работающей инфраструктуры… Продолжать такую цепочку можно до бесконечности, но нужно ли? :)

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

Напишите в комментариях как в вашей компании организована практика по разбору инцидентов и насколько считаете такой процесс полезным ⤵️
👍1
Май 2024:

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

Главное, чтобы черные лебеди не выбивали вас из колеи. Взбодрились, наладили расписание и пошли дальше.

навыки

✔️ Завершил курс Быстрая прокачка в ООП (Object Calisthenics - очень интересная штука, хочется порефлексировать в отдельном посте).
✔️ Рассмотрел простые правила проектного дизайна.
✔️ Потренировался в приведении своего очень старого кода в соответствие с SRP: раз, два, три.

карьера

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

прочее

✔️ В какой-то момент у меня отвалилась фича по генерации изображений у шахматного бота, который публикует задачки в рабочий канал. Пришлось фиксить ASAP и выпускать версию v1.0.6, так как 3 раза в неделю коллеги ожидают очередную задачку :)
✔️ Ввел в свои привычки ранний подъем и спорт - эти ребята хорошо помогают оставаться эффективным целый день.

#результаты
👍3🔥3
Новиков > путь в Big Tech
В ближайшие месяцы планирую взять на себя роль Security Champion нашей продуктовой команды. Это поможет улучшить свои знания в кибер-безопасности, а также усилить свою команду экспертизой в этом направлении. Если совсем кратко, то секьюрити чемпион предупреждает…
Моделирование угроз

В начале недели перенял роль SC. Теперь являюсь амбассадором безопасности в нашей фича команде.

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

Основные этапы

1️⃣ Перед моделированием угроз сперва необходимо декомпозировать фичу, нарисовать верхнеуровневую архитектуру, описать как будут использоваться, перемещаться, обрабатываться и храниться данные в системе. Это поможет впоследствии определить узкие места и сразу обозначить возможные пути решения (необходимо будет учесть при разработке).

2️⃣ Теперь важно найти опасные угрозы. Пробуем ответить на вопрос: "Что может пойти не так?". Здесь могут работать подходы:
a) Берем библиотеку атак (крупные компании обычно организуют свою основанную на опыте), но для начала можно начать с тех, которые обозначил OWASP, и задаемся вопросами о возможных последствиях для нашей системы и ее пользователях при попытке осуществления каждой из атак.
b) Используем методику STRIDE, которую активно применяет у себя Microsoft. Такой подход подразделяет угрозы на 6 основных категорий (спуфинг, незаконное изменение, отказ в обслуживании и другие). С данной моделью работаем также, как и с библиотекой атак, задавая, например, такой вопрос применительно к незаконному изменению: "Как злоумышленник может изменить наши данные или повлиять на них?"

3️⃣ Когда угрозы обозначены, приоритизируем их:
a) Учесть сразу - решаем как обработать, заводим задачу и выполняем вместе с разрабатываемой фичой
b) Отложить на будущее - заводим задачу и кладем в бэклог (можно закрывать в рамках тех. долга)
c) Принимаем риск - если вероятность возникновения минимальная, а трудоемкость закрытия уязвимости существенная, то фиксируем данный момент в задаче или документации (если такой риск все-таки случится, то останутся артефакты о том, что мы сознательно пошли на такое решение)

4️⃣ На заключительном этапе остается только проверифицировать, что все, что мы нашли выше, учтено в нашей системе/фиче перед деплоем. Здесь подходят: автоматические тесты, сканнеры уязвимостей, код-ревью, тесты на проникновения и др. Без финальной проверки того, что мы учли в системе все, что описали до, вся наша работа будет напрасна, так как можно найти сколь угодно много угроз, но ничего в результате не сделать.

Самые полезные материалы, чтобы провести моделирование угроз правильно:
- Шпаргалка от OWASP
- Интерактианый курс от Microsoft и его подмодуль, который позволяет за 15 минут познакомиться с темой.

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

В начале июня обещал рассказать как повышаю экспертизу в проектировании систем. Но сперва лирическое отступление.

Ответьте себе: стоит ли туда идти прямо сейчас с текущим опытом? И с какой целью?

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

Зачастую собеседования на такой грейд сопровождаются классическим system-design interview, где вас попросят спроектировать твиттер, ютуб или другую популярную систему.

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

Важно понимать: одно дело научиться правильному проектному мышлению и совсем другое - проходить интервью.

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

Потребность в навыках system design на разных этапах:

1. Представим ситуацию, что человек имеет небольшой опыт (до 2-х лет) и занимает позицию junior/middle- разработчик. В таком случае (на мой взгляд) углубляться в проектирование может оказаться даже вредным, так как легко закопаться в обилии материала, потерять мотивацию и основной рабочий фокус.

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

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

Так как первые пункты по своей сути тривиальны, то стоит внимательнее рассмотреть №3, о чем дальше и пойдет речь.

У меня в закладках давно живут:
- дизайн праймер
- дорожная карта

И еще немало крутого материала, который стараюсь время от времени почитывать 🤓

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

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

В моем фокусе сейчас оказалось 2 проекта:
- курс по анализу систем (АС)
- курс по объектно-ориентированному анализу и проектированию (ООАП)

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

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

⚡️ Уже сейчас крупным открытием из курса по АС для меня было узнать про воркшоп Event Storming. Поставил себе цель - провести его в своей команде. Это действительно захватывающий подход к проектированию, и я про него расскажу отдельно.

Так как же все-таки научиться проектировать системы, если решили, что хотите в этом разобраться?

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

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

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

В конечном итоге, вы сделаете ощутимый скачок в своем развитии.
👍4🔥32
Секрет хорошего дизайна, о котором знают все гиганты в IT [1/2]

Рассмотрим упрощенную модель "зрелости" по реализации проектных решений разбитую на 5 уровней:

Уровень 1
- Пишем код

Уровень 2
- Пишем код -> Согласовываем

Уровень 3
- Согласовываем -> Пишем код

Уровень 4
- Согласовываем -> Пишем код -> Документируем решение

Уровень 5
- Документируем решение -> Согласовываем -> Пишем код

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

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

Важность актуальной документации сложно переоценить, поэтому, если разработчики уже работают на 4-м уровне зрелости, то это очень хороший знак.

В погоне за низким TTM часто 5-ый уровень может быть не достижим, так как требует доп. ресурса, и хорошие разработчики вынуждены лавировать между 3 и 4 в зависимости от капасити спринта.

"Документирование решений" и "Согласования" в совокупности образуют процесс под названием "Дизайн ревью" (Design Review), который стал стандартом для разработки любых решений в Биг Техе.

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

Авито тоже не стоит на месте и постоянно оптимизирует свои процессы. Так в компании на смену дорогих архитектурных комитетов пришел Tech Design Review или просто TDR.

Как с ним работать, чтобы создавать надежные системы, поговорим во второй части.
🔥4👍1
Секрет хорошего дизайна, о котором знают все гиганты в IT [2/2]

Итак, Tech Design Review. Что за ним скрывается?

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

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

В TDR механика абсолютно такая же, а весь процесс состоит из следующих этапов:

0️⃣ Обозначаем проблему

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

1️⃣ Находим решение

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

2️⃣ Собираем вместе

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

проблема <=> описание решения <=> схема зависимостей <=> компромиссы <=> альтернативы <=> FAQ <=> нагрузка и расчеты <=> ресурсы <=> структура баз данных <=> метрики

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

Фактически общая формула такая:
проблема -> решение -> обоснование

3️⃣ Отдаем в ревью

На этом этапе у нас есть оформленная версия документа (v1.0). Выбираем экспертов, в домене которых будет происходить новая разработка. Чтобы найти экспертов можно задать 2 вопроса: "Кто владелец сервиса, на которое будет оказано влияние?" и "Кому потенциально наше решение облегчит или затруднит жизнь?".

Эксперты выбраны. Отправляем на согласование и ждем.

4️⃣ Ревью

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

🟢 - вопросов нет
🟡 - есть неблокирующие вопросы, можно начинать разработку
🔴 - такое решение нельзя запускать в прод

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

5️⃣ Завершение

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

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

Если будете углубляться в тему, то можете столкнуться с ADR (Architecture decision record) - это тоже важный документ, но представляет собой другой процесс и лучше мы рассмотрим его отдельно.

К слову, сейчас нахожусь на этапе ревью собственного TDR в компании. Уже есть интересные инсайты, которыми хочется поделиться.

Но это позже, а пока продолжаем работать.
👍3
Июнь 2024:

навыки

✔️ Завершил больше половины курса по анализу систем, выполнил 4/5 всех заданий курса. Улучшил экспертизу в областях: работа с требованиями и внешними ограничениями, выделение основных частей системы при помощи Event Storming, выбор архитектурного стиля в зависимости от характеристик и пр. Ход мыслей и выполнение заданий можно посмотреть здесь.
✔️ Прошел тренинг по управлению рисками. Запомнить: важно развивать вероятностное мышление, прорабатывать возможные сценарии и помнить, что наступление любого события всегда меньше единицы.
✔️ Зарефакторил старый проект. Полезная мысль: при рефакторинге и код-ревью в первую очередь обращаем внимание на то, как код влияет на остальную часть проекта, как с ним взаимодействует.
✔️ Продолжаю практиковаться в ООАП. Переосмыслил разницу между классами анализа и дизайна (отличный мог бы выйти пост в будущем, а кому интересно копнуть уже сейчас, может начать со статьи).

карьера

✔️ Перенял роль платформенного эксперта в своей вертикали (за несколько лет накопилось немало экспертизы в одном домене, которой могу делиться с коллегами и разгружать горизонтальную команду).
✔️ Написал свой первый TDR в компании. Утвержденный документ + последующая успешная реализация проекта = хорошая основа для будущего промо на следующий грейд, но, конечно, это не гарантия, а лишь один из кирпичиков.
✔️ Подготовился к перф-ревью, собрав все артефакты за полгода работы. По окончании июльского ревью подробнее поговорим о процессе и как к нему лучше готовиться, чтобы он прошел без боли.

посты

✔️ Как сделать продакшн стабильнее и что такое LSR (читать)
✔️ Моделирование угроз - инструмент для обеспечения безопасности ваших фичей (читать)
✔️ Кому нужно изучать проектирование систем и как к этому подступиться (читать)
✔️ Секрет хорошего дизайна и при чем здесь TDR и ADR (читать)

прочее

✔️ Поучаствовал в 2-х массовых забегах: на 7.195 км и 10 км. Кажется бег начинает входить в привычку. Важно к интеллектуальной активности добавлять любую физическую - они хорошо дружат, а вы сможете делать больше.

#результаты
🔥2👍1
Google ворует имена

17 марта 2003 года вышла статья "Go! – A Logic Programming Language for
Implementing Multi-threaded Agents"
(авторы: K.L. Clark и F.G. McCabe).

Был представлен новый мультипарадигменный язык "Go!", над которым велась работа на протяжении 10 лет.

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

Спустя 6 лет осенью 2009 Google представляет свой язык с одноименным названием за исключением пунктуации.

Авторы Go! почти сразу завели issue #9, где просили сменить название, так как такой язык уже существовал, но все тщетно.

Считаю, что про такие моменты важно знать в своей предметной области.

Вот так выглядит, например, «Hello World!» на Go!


MODULE hello.

IMPORT standardio.

PREDICATE main.
main :-
standardio:write("Hello, World!").


А вот здесь можно прочитать про него краткую сводку.

Этично ли поступил Google? Или это просто бизнес и ничего личного?
👍3
Однажды Хемингуэй поспорил, что сможет написать самый короткий рассказ, способный напугать любого…

Он выиграл спор: Performance Review

Разберемся что это такое, почему наступает неожиданно и можно ли что-то с этим сделать?

Если кратко, то это процесс подведения итогов работы за определенный период. Подробнее можно найти здесь.

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

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

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

Рассмотрим основные этапы.

Google Performance Review


В год происходит 2 ревью: превью по окончании первого семестра и полное ревью между октябрем и ноябрем. На полном ревью добавляется оценка по методу 360, на котором коллеги дают обратную связь друг другу и оценивают качество взаимодействия.

Разберем подробно полный процесс ревью.

1. Период самооценки

Это фактически отчет о своих достижениях за прошедший период. Метрики и привязки к ОКРам обязательны, иначе зачем все это, если не приносит бизнесу результат?

Самое пикантное, что все достижения нужно уложить в текстовое поле размером 512 символов :)

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

2. Период оценки 360 (отсутствует на превью)

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

3. Период калибровок

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

4. Обсуждение результатов

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

В Авито процесс устроен аналогично, только у нас нет превью, а есть 2 полноценных перформанс ревью.

Здесь можно посмотреть кратко как процесс устроен в другом Биг Техе: Meta, Apple, Amazon, Netflix.

Из этой же статьи мы узнаем, что Google в 2022 году сменил свой старый процесс на Googler Reviews and Development (GRAD). Самое главное нововведение - работа с ожиданиями и фокус на саморазвитии с построением карьеры в компании.

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

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

Как с комфортом подойти к этому процессу, чтобы извлечь максимальную пользу и не тратить много времени на прохождение, напишу в продолжении.
👍3🔥1
Подчиняем performance review

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

Что мне помогает и почему я уже начал готовиться к следующему? 

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

1️⃣ Готовимся
период: окончание перф. ревью -> начало следующего перф. ревью

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

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

Я использую Obsidian, но подойдет что угодно. Даже простой список с перечислением и небольшими комментариями лучше, чем ничего.

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

- ) Постоянно сверяйтесь с планом своего развития. Задавайте вопросы: Туда ли вы движетесь? Приближает ли выполнение ежедневных задач к цели? Можете ли выйти за рамки своей ответственности, делая какую-то задачу и будет ли кому-то еще это полезно?

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

2️⃣ Пишем
период: начало перф. ревью -> окончание периода оценки коллег

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

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

Формула следующая:
<цель/окр/инициатива/проект> + <ваш вклад: сервис/фича/документация> = <метрики результата>

- ) Используйте поиск по таск-трекинговой системе. В Jira, например, можно фильтровать свои таски за прошедший период, используя JQL.
(5 реакций и дам готовый фильтр на JQL, который использую)

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

- ) Вычитка финального ревью обязательна!

3️⃣ Анализируем
период: окончание периода оценки коллег -> окончание перф. ревью

- ) Обращаем внимание на ОС от руководителя и коллег, что было хорошо, а что можно улучшить. Делаем на это упор в следующем периоде.

- ) Самый важный вопрос: "Куда мы хотим прийти через 6 месяцев?". Ответ напрямую влияет на будущую работу. Важно понимать, что для перехода на следующий грейд требуются совершенно другие акценты, нежели чем классическая работа на "хороший" результат.

Обозначьте цель и следуйте к ней. Если это - промо, то обсудите с тимлидом заранее и уже начинайте над этим работать. 

> > >

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

Какой у вас «секрет» написания ревью или вы счастливо живете без него?

P.S.: Я показал процесс со стороны инженера. У руководителя все гораздо "интереснее". 

Пусть результат вашей работы превзойдет все мыслимые ожидания менеджеров!
🔥9
Маленькие шаги - основа вашей эффективности

Здорово разрабатывать сложные системы, но еще очень приятно автоматизировать мелкую рутину.

Один из примеров - поиск выполненных задач за прошедший период для перформанс ревью.

Делюсь готовым JQL-запросом для получения завершенных задач связанных с вами за последние 6 месяцев в Jira, которым пользуюсь регулярно:


(created >= startOfDay(-180) OR resolution changed after startOfDay(-180) OR status changed after startOfDay(-180)) AND (reporter = currentUser() OR assignee was currentUser()) ORDER BY resolved ASC, updated ASC


Можно настроить фильтр, сохранить в закладки и держать свои выполненные задачи под рукой.

Сами по себе подобные хитрости несут мало практической пользы, но когда вы их встраиваете в работающую для себя систему (подходите системно к перф. ревью, например), то достигается синергетический эффект.
🔥6
Анализ систем. Финал

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

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

Формат курса

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

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

Есть также механика проверок работ коллег (peer-to-peer). Такой подход помогает лучше закрепить материал, заставляя примерить на себя роль учителя и помогая взглянуть на решаемое задание совершенно иначе.

На курсе были разные тарифы. Я выбрал тот, который отличается подробной ОС по каждому ДЗ - и это было невероятно полезно. Когда проверял чужие работы, то видел, что автор дает краткий комментарий с пунктами, требующими внимания, но в моем случае все было детально расписано - и такой фидбек был очень ценен.

Рефлексия

В последнем ДЗ предлагалось поделиться рефлексией с оглядкой на свою самую первую систему в курсе. Прикрепляю основную выдержку ниже (полная версия):

Идеи и подходы, которые интересно внедрить в будущем:
- Думать на уровне поддоменов и ограниченных контекстов. Понравилось, что такой подход учит собирать конкретный бизнесовый контекст, вытекающий из требований к системе, в одном месте. Мыслить на уровне поддоменов - выглядит как системный подход к анализу и проектированию любой системы.
- Event Storming обязательно станет одним из постоянных инструментов в моем арсенале. Интересно его попробовать применить в своей команде для проектирования новой системы.
- Не всегда одинаковые по смыслу системы, например, в домене биллинга, должны располагаться в одном микросервисе. Иногда полезно их разделить. Тут важно смотреть на контекст, в котором они существуют. Возможно, он очень специфичный для каждой из систем.
- Характеристики системы определяют архитектурный стиль, а также помогают при распиле монолита.
- Каждое требование важно. Нужно прорабатывать каждый консерн стейкхолдеров и каждый пункт требований еще на моменте анализа.
- При наличии неопределенности в требованиях и любых сомнениях по работе будущей системы - задавайте вопросы.
- Оставляем артефакты принятых решений. В идеале - делать ADR по каждому.

Еще очень понравилась нотация C4, про которую узнал на курсе. Теперь рисую схемы только по ней (использую уровень контейнеров C2). Потихоньку готовлю пост про C4 и про использования DSL для создания схем - полезно для тех, кто устал рисовать и выравнивать стрелки 🤓
🔥7
3 в ряд 🍒🍒🍒

В рамках экспериментального погружения в ООАП написал консольную игру.

Не все удалось реализовать согласно первоначальной задумке, многое упростил. В основном мешало, что уже несколько лет не работаю в ООП-парадигме и на смену C# пришел Go. 

Однако очень помогло описание архитектуры, с которого начинал проектирование, то есть формально заставлял себя следовать тому, что я когда-то уже проанализировал и запроектировал. Из интересных открытий: во время анализа отбраковал некоторые классы, которые (как мне казалось) понадобились во время реализации. Но когда написал код, то понял, что все-таки отбраковал их правильно и они на самом деле не нужны. 

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

Запомнить: время на проектирование и анализ всегда следует тратить больше, тщательнее продумывая взаимодействия между модулями. Это действительно вам поможет на этапе реализации.
👍5🔥51
Июль 2024:

навыки

✔️ Завершил курс по анализу систем. Выполнил 5/5 всех заданий курса, проверил 12 работ других студентов и получил финальный сертификат.
✔️ Завершил курс по ООАП и написал консольную игру (3 в ряд). Рефлексия в прошлом посте.
✔️ Попрактиковался в приведении запутанного интерфейса в более выразительный.

карьера

✔️ Получил хороший фидбек по окончании перф-ревью. Коллеги отметили качество коммуникации и проявление инициативы по нашим стримам.
✔️ Написанный TDR по новому сервису породил активную дискуссию, особенно спорным стал выбор БД (NoSQL VS SQL) - документ ушел на второй круг. Цель на ближайший спринт - качественно обработать все комментарии и согласовать финальное решение, чтобы приступить к разработке.

посты

✔️ Как устроен TDR изнутри (Tech Design Review) (читать)
✔️ Чем отличается Go! от Go (читать)
✔️ Performance Review в Big Tech (читать)
✔️ Как готовиться и писать Performance Review (читать)
✔️ Полезный фильтр для ваших задач в Jira (читать)
✔️ Анализ систем. Что унести с собой? (читать)

прочее

✔️ Поучаствовал в двух массовых забегах: на 10 км. Лучший результат - 52:20 (5:14/км). Бег определенно вошел в привычку - помогает хорошо разгрузиться. На сентябрь запланировал полумарафон, надеюсь, хватит времени на подготовку.

#результаты
9👍1