Новиков > путь в 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
Анализ систем. Финал

Вчера получил сертификат об окончании курса по анализу систем, так как не просто его прослушал, но и выполнил все практические задания (решения выкладывал на 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
Что может пойти не так?

Провел первую в команде сессию по моделированию угроз для перспективного сервиса.

Встреча была запланирована на час, но уже на 45-й минуте стало понятно, что на сессию нужно закладывать 1,5-2 часа, чтобы спокойно все продумать и не торопиться.

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

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

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

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

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

3️⃣ Каталог атак или методику, по которой определяем угрозы желательно продумать заранее. Все команды разные и желательно выбирать инструмент, который лучше подойдет вашей команде. У меня после использования предлагаемого каталога атак появилось сильное желание переработать его под свою, например, используя STRIDE, предлагаемый Microsoft.

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

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

Оценка рисков (risk assessment) - похожий, но совершенно другой процесс. Он подразумевает более широкий подход применительно ко всем рискам, а не только угрозам безопасности. И у него есть свои инструменты для проведения сессии (матрица рисков, Risk-Based Testing и другие).

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

#безопасность
👍3
Осторожно: AI. Как могут обмануть ассистенты и что с этим делать?

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

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

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

А сегодня попробуем найти решение инженерной задачи с помощью AI и разберем на что важно обращать внимание. Использоваться будет GPT-4o, как самый сообразительный из тех, на ком я тестировал (Llama3.1, к сожалению, не смогла выдать правильное решение).

Задача

В повседневной работе, особенно когда пишешь юнит-тесты, возникает необходимость сравнивать JSON-объекты (различные конфиги, например). Зачастую это массив байт, json.RawMessage, ссылка на массив и др.

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

Когда мы пытаемся сравнить объекты, то сталкиваемся со следующим:
1. Порядок ключей может быть произвольный во втором объекте.
2. Отступы или форматирование в 2-х json-ах могут сильно отличаться, а так как мы сравниваем массивы байт, то все влияет на результат.

Идем к AI просить помощи. Мой запрос:

I need to compare two objects containing json.RawMessage in Golang. But I get a mess because of different spaces in the data. How can I solve it?

Provide the most effective and straightforward way to do it.


Получаем подробный ответ с объяснениями и рабочим кодом!

Для решения задачи нам рекомендуют "нормализовать" 2 json'а. И это отличный совет, а вот предлагаемую реализацию разберем подробнее.

// NormalizeJSON takes a json.RawMessage, unmarshals it into a generic map,
// and then marshals it back to a json.RawMessage to normalize it.
func NormalizeJSON(raw json.RawMessage) (json.RawMessage, error) {
var obj map[string]interface{}
if err := json.Unmarshal(raw, &obj); err != nil {
return nil, err
}

normalized, err := json.Marshal(obj)
if err != nil {
return nil, err
}

return normalized, nil
}


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

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

Интересное наблюдение, если вторым запросом поинтересоваться:

Is it straightforward?


То ассистент догадается, что можно обойтись без последнего маршалинга и возможно даже подскажет, что можно вместо map[string]interface{} использовать interface{}.

Вывод

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

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

Если тема будет интересна, то постараюсь собирать подобные истории и делиться тем, как AI помогает в повседневной работе и где он наиболее эффективен.

#ai
🔥31
Мышление письмом

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

Вот таким у меня получился конспект первой главы System Design Interview (Alex Xu).

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

Как я с этим работаю?

1. Читаю главу.
2. По памяти пытаюсь воспроизвести то, что прочитал.
3. В ходе воспроизведения начинают появляться вопросы, почему именно так устроено, а не иначе - записываю их, чтобы вернуться потом.
4. Отвечаю на все возникшие вопросы.
5. Делаю финальный конспект: корректирую то, что не получилось сразу, сверяясь с источником и особо выделяя ответы на свои вопросы.

Конечно, с таким подходом не получается читать по 365 книг в год, но для меня ценнее брать качеством, а не количеством.
👍10🔥4
Улучшаем код, меняя парадигму

В августе приступил к изучению основ функционального программирования.

ФП притягивало к себе еще с тех пор, когда я писал на C# и стажировался в EPAM.

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

На мой наивный вопрос "А что такое монады и тоже хочу писать по-взрослому" - получал добрую улыбку со словами, что мне пока рано про такое думать.

Оглядываясь назад, понимаю такой ответ и полностью с ним согласен, но тогда было немного обидно.

Но зачем изучать ФП, если пишешь на нефункциональном языке и работаешь в императивной парадигме?

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

Вот несколько ключевых преимуществ ФП, которые зацепили меня:

1. Чистые функции и отсутствие побочных эффектов

Чистая функция всегда возвращает одинаковый результат для одинаковых входных данных и не изменяет состояние программы. Это делает код более предсказуемым и легко тестируемым.

2. Неизменяемость данных

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

3. Высокий уровень абстракции

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

Хотя мой ежедневный инструмент не является функциональным языком, в нем можно применять некоторые принципы ФП:

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


func main() {
pow := func(x int)int{
return x*x
}

fmt.Println(pow(2)) // 4
}


Go позволяет использовать чистые функции:


func add(a, b int) int {
return a + b
}


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


func multiplier(factor int) func(int) int {
return func(x int) int {
return x * factor
}
}

func main() {
double := multiplier(2)
fmt.Println(double(5)) // 10
}


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


func filter(slice []int, condition func(int) bool) []int {
var result []int
for _, v := range slice {
if condition(v) {
result = append(result, v)
}
}
return result
}

func main() {
nums := []int{1, 2, 3, 4, 5}
even := filter(nums, func(n int) bool {
return n%2 == 0
})
fmt.Println(even) // [2 4]
}


Другая парадигма => другой взгляд на привычные вещи => больше возможностей по взаимодействию с ними.

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

Замечали ли вы, что использовали подходы функционального программирования, не осознавая этого? А встречались ли вам противники ФП?
👍3🔥3
Конец спринта

Мой любимый день, когда можно столько всего успеть в промежутках между встречами:

Завести и продумать задачи на следующий спринт
Задеплоить в пятницу один микросервис
Задеплоить в пятницу другой микросервис
Провести презентацию своей команды на демо
Быть ежедневным дежурным своей вертикали

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

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

Катарсис же достигается где-то посередине :)
👍21
Фичалидерство: почему это нужно каждому?

В зрелых кросс-функциональных командах существует понятие фича-лида.

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

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

У нас довольно зрелая команда, поэтому практически каждый инженер становится фича-лидом по той или иной задаче. Это позволяет сильно разгрузить тимлида и повысить качество каждой отдельно взятой функциональности.

Зачем это инженеру?

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

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

Что делает фичалид?

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

Разобьем процесс по этапам:

🌎 Дискавери

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

🚚 Передача в разработку

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

🛠 Разработка

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

🚀 Запуск

- Если есть АБ-эксперимент, то его заведение или контроль заведения
- Оповещение стейкхолдеров о запуске
- Запуск
- Поддержка запущенной фичи: реакция на баги, помощь коллегам по вопросам связанным с фичой

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

Особенно, если этот процесс вас пугает.

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

Но если вас что-то действительно пугает, то рекомендую начать это делать. Сразу заметите как начнете расти, а потом вас уже будет не остановить и это войдет в привычку.
🔥2
Что выведет программа?

Только не спрашивайте ChatGPT (он не справился).
package main

import (
"encoding/json"
"fmt"
)

type Data struct {
Value Arrays `json:"data"`
Name string `json:"name"`
}

type Arrays struct {
IntArray *[]int `json:"values,omitempty"`
}

func assignValues(values *[]int, name string) Data {
data := Data{
Value: Arrays{
IntArray: values,
},
Name: name,
}
return data
}

func main() {
sl := make([]int, 0)
sl = nil

data := assignValues(&sl, "nil")
value, _ := json.Marshal(data)

display(value)
}

func display(v []byte) {
fmt.Println(string(v))
}
🔥1
Простой язык программирования - иллюзия, которая продается

Изначально я хотел написать про Go, но, заметив, что большинство с ним незнакомо, решил обобщить.

Часто можно встретить призывы изучать Go, Python или любой другой ЯП, как самый простой и популярный.

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

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

Наглядные примеры из спорта:

👟 Бег

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

Но:

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

Шахматы

Изучить правила можно за 5 минут. Они умещаются на листке A4.

Но:

- Без стратегии и тактики сложно выигрывать и получать удовольствие от игры.

В мире технологий также.

Пример с nil-слайсами выше - простая иллюстрация того, что в Go множество нюансов. И это еще не говоря о работе с каналами, управлением памятью и указателями.

Уверен, что подобными деталями изобилует каждый язык.

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

Но чтобы писать хороший код, который содержит минимум багов, легко читается и поддерживается - потребуются годы. Это приходит с опытом, в этом и заключается мастерство.
👍9🫡32
Август 2024:

навыки

✔️ Приступил к изучению основ функционального программирования.
✔️ Попрактиковался с имутабельными состояниями в коде вместо передачи сущностей по ссылке.
✔️ Рассмотрел различные виды багов.
✔️ Научился локально разворачивать LLM с помощью ollama и подбирать языковую модель под конкретные задачи.
✔️ Записался на внутренние занятия по "Инженерной культере" и прошел 3, на которых изучил: какие механики предусмотрены для обеспечения стабильности систем (NFR, SLI, SLO, SLA и пр.); как обеспечивать качество и тестировать производительность системы, чтобы это вошло в привычку.
✔️ Решил разбирать каждую из глав книги System Design Interview и делать краткие зарисовки. Выложил 4 первые главы.

карьера

✔️ Согласовал вторую версию документа TDR для нового сервиса. В ближайшем спринте приступаю к реализации.
✔️ Провел сессию по моделированию угроз в команде для нового сервиса.
✔️ Принял роль фичалида перспективной функциональности.

посты

✔️ Как проводить моделирование угроз (читать)
✔️ Помогите AI-ассистентам, чтобы они помогли вам (читать)
✔️ Как читать техническую литературу (читать)
✔️ Функциональное программирование как другой взгляд на привычные вещи (читать)
✔️ Возможен ли катарсис в конце спринта (читать)
✔️ Почему вам нужно фичалидерство (читать)
✔️ ChatGPT бессилен перед классическим вопросом, а вы? (читать)

прочее

✔️ 2 забега на 10 км и 1 на 5 км с препятствиями. Лучший результат - 50:03 (5:00/км). Потихоньку улучшаем показатели. Следующая цель - полумарафон.

#результаты
👍8
Что делать, когда прямой путь не работает

Вчера ставил расширение на VS Code, которое поддерживается коллегами для внутреннего удобства разработки.

Простой плагин, который раскрашивает brief-файлы (корпоративный стандарт для описания контрактов по типу protobuf, подробнее почитать здесь), подкинул очередную задачку.

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

К плагину прилагалась простая инструкция:


1. Скачать `vsix` файл: wget http://<extension-directory>.vsix

2. Добавить его в VSCode: Extensions -> ... -> Install from VSIX -> <extension-directory>.vsix

3. Либо через терминал: code --install-extension <extension-directory>.vsix


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

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

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

Порадовавшись этой нехитрой мысли я переключился с проблемы "отсутствует файл", на задачу "как собрать файл". Через секунду я прочитал, что существует vsce - VS Code Extension Manager, с помощью которого я могу собрать нужный мне vsix. Ставим его:


npm install -g vsce


Далее переходим в директорию с исходником расширения (где живет наш плагин) и упаковываем в нужный vsix:


vsce package


Теперь нужно установить расширение в IDE. Используем следующую команду:


code --install-extension <extension-directory>.vsix


И, если с vsce все было просто, то следующим вызовом для меня как относительно нового пользователя VS Code стала команда code --instal-extension, так как просто в консоли она не выполнялась. Но спустя пару минут, разобравшись, что это CLI, уже устанавливал и ее.

В пределах 5-10 минут мне удалось: разобраться в проблеме, узнать как собирать vsix-файлы с помощью менеджера расширений vsce, устанавливать их через CLI и бонусом, пока все устанавливалось, подробно почитал про проект GNU Wget (небольшой тизер: Wget2 на подходе).

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

Рекомендую, когда прямолинейный подход не сработал, остановиться, записать вопрос и найти альтернативное решение, спустившись на уровень ниже. Так вы не только расширите свою экспертизу, но очередной раз потренируетесь в системном подходе решения задач.
👍4
Привычка, которая поможет расти в Big Tech

Одной из важнейших компетенций, на которую смотрят при возможном пересмотре грейда, является "инженерная культура".

В Авито на уровень E5 (синьор) ее признаки обозначаются как:

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


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

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

На днях подключал к новому сервису библиотеку для работы с АБ-экспериментами. Была понятная дока с примерами, а еще были интересные нюансы:

1. Либу можно было использовать несколькими способами. Один из них - подключение как мидлвара (middleware).

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

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

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

Как итог, все заработало.

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

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

2. При использовании либы, как мидлвары, оказалось, что ее нельзя адекватно протестировать юнит-тестами.

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

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

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

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

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

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

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

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

@time2code
👍72👏1
Лучше маленький шаг, чем грандиозный план. Создаем красивый блог за 10 минут.

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

Шло время, но ничего не двигалось, так как я понимал, что нужны ресурсы на это: время и деньги для инфраструктуры.

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

Был даже план по написанию своего блога:

1. Стать фулстек-разработчиком, пройдя несколько курсов, изучая архитектуру фронтенда и JS
2. Мигрировать на стабильный VPS-сервер
3. Купить домен (тот, который нравится, стоит 10к в год)
4. Разработать блог

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

И вот в один прокрастинирующий вторник (вчера) я решил, что откладывать больше нельзя.

У многих профессиональных разработчиков на сайтах или блогах я видел приписки "powered by ..." - и все в этом духе. Это означает, что они используют какое-то внешнее решение для своего сайта/блога.

И тут я подумал: чем я хуже?

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

На втором месте у меня в закладках был Hugo - часто видел его у других авторов.

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

Решил попробовать, тем более у проекта - отличная документация.

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

Осталось самое интересное - мое нелюбимое, но горячо уважаемое - DevOps-кухня, а именно: деплой и хостинг созданного сайта.

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

Меня выручил github.pages, где у меня уже жила страничка с CV. А Hugo даже предоставляет простую инструкцию, как задеплоить туда.

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

Честно говоря, был счастлив, что, наконец, сделал серьезный шаг в сторону создания своего блога.

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

Результат здесь (пока там только интро из гитхаба).

В планах перенести туда профессиональный блог с избранными постами из телеграма + начать активно его развивать с постингом в LinkedIn.

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

На текущий момент кажется, что Hugo идеально подходит, но не исключаю, что через год перееду на полноценное standalone решение, если столкнусь с ограничениями.

Таким образом, фактически я создал свой новый сайт меньше чем за 10 минут + 30-60 минут потратил на чтение документации.

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

Интересно был ли у вас похожий опыт с блогами и на каком решении остановились в итоге?

@time2code
4👍3
Можем ли мы писать код без ошибок?

Мой ответ: нет.

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

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

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

Но все равно случилось интересное. В конце прошлого спринта мы, наконец, смогли начать интеграционно тестировать фичу.

На бэкенде было найдено 3 бага:

1. Приходил цвет в странной кодировке.
2. Пустой массив не возвращался в ответе.
3. Лимит на количество элементов в ответе применялся в неправильном поле.

Что их объединяет? Все они были сделаны сознательно:

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

У каждого бага есть своя предыстория, свой контекст и тип.

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

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

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

Самое важное - делать правильные выводы, обсуждать все проблемы на ретро и формировать такие договоренности внутри команды, чтобы в будущем качество своего продукта держать на стабильно высоком уровне.

@time2code
👍5
Два года в Big Tech. Стоило того?

Вчера было ровно 2 года с момента, как я работаю в Авито.

За это время мне удалось качественно вырасти как специалист.

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

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

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

Попробую проанализировать плюсы и минусы, которые заметил за это время.

👍 Несколько причин стремиться в компании уровня Авито:

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

1. Инженерная культура

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

2. Зрелые процессы

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

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

3. Компенсация и коммьюнити

Сюда попадает то, что связано с гигиеническими факторами: зарплата, мед. страховка, дружелюбная среда и прочее.

По внутренним ощущениям и отзывам коллег - тут все отлично.

4. Привязанность к продукту

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

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

Меня это очень сильно заряжает и дает по-настоящему большое удовлетворение от того, что делаю.

👎 Несколько причин избегать компании уровня Авито:

1. Медленный рост грейда

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

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

2. Прозрачность решений топ-менеджмента

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

3. Потеря гибкости

Быстрорастущие компании постепенно теряют гибкость в процессах ради безопасности и былую атмосферу. Все это может отражаться на «счастье» сотрудников.

4. Маленькие задачи

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

И если в стартапе есть возможность с нуля построить MVP продукта, поработав сразу над множеством задач разной сложности, то в Биг Техе тебя легко могут посадить “красить кнопку” или “перекладывать json”.

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

@time2code
👍12
Сентябрь 2024:

развитие

✔️ Завершил курс «Основы функционального программирования».
✔️ На примере GORM (ORM для Go) рассмотрел, как можно увеличить производительность на 20% при работе с базой данных.
✔️ Прошел отбор на внутренний курс по "Инженерной культуре", который предполагает интенсивное погружение в такие темы, как "проектное управление", "системное мышление" и др.
✔️ Приступил к реализации нового сервиса, по которому в прошлом месяце утвердил TDR: подготовил инфраструктуру и начинаю разработку бизнес-логики.
✔️ Провел сессию по управлению рисками (+моделирование угроз) для важной функциональности в текущем квартале.
✔️ Обнаружил 3 бага в функциональности соседних команд: 1 в продукте и 2 в инфраструктуре. Один из них - коллеги уже исправили, а оставшиеся - запланировали на ближайшие спринты.

прочее

✔️ Пробежал первый полумарафон (21.1км) с результатом 1:50:54 (5:15/км).
✔️ Поставил личный рекорд на 10км - 47.28 (4:50/км).
✔️ Сходил на неделю в отпуск. Хайкинг в горах отлично помогает отвлечься от работы.

посты

🔖 Простой язык программирования - иллюзия, которая продается (читать)
🔖 Что делать, когда прямой путь не работает (читать)
🔖 Привычка, которая поможет расти в Big Tech (читать)
🔖 Лучше маленький шаг, чем грандиозный план. Создаем красивый блог за 10 минут (читать)
🔖 Можем ли мы писать код без ошибок? (читать)
🔖 Два года в Big Tech. Стоило того? (читать)

#результаты
🔥7👍2🫡2
Почему мозг избегает сложных задач. Как его заставить работать?

Мозг - самая энергозатратная часть нашего организма. Нередко он нас обманывает, но зачем?

Ответ банален: чтобы спасти нас, сберегая ресурсы для своей сложной работы.

Очевидно, нас это не устраивает, так как разработка ПО - сложная и творческая задача, требующая от всех максимального включения в работу.

Уверен, многие знакомы с концепцией: задавания вопросов. Есть поговорка: «хорошо заданный вопрос - половина ответа».

Но почему это работает и работает ли?

Зачем задавать вопросы и как это помогает решать задачи?

Сейчас прохожу курс по системному мышлению (СМ) и получаю множество инсайтов.

Кратко: СМ - учит двум вещам:
1. Видеть границы своей компетенции.
2. Видеть проблемы на большем масштабе.

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

Пока обозначим контекст как окружение, в рамках которого существует та или иная проблема.

Теперь самое интересное: решение проблемы может существовать либо в одном контексте, который вы уже рассматриваете, либо в другом.

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

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

Запомнить: через правильные вопросы мы помещаем свой мозг в нужные для решения задачи рамки.

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

@time2code
👍41
Блог готов! С чем пришлось справиться на старте?

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

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

Какая работа была проделана:
- Изучил большинство Hugo-тем, которые предлагаются для ведения блога. Остановился на PaperMod как самой приятной, хорошо работающей и активно поддерживаемой (это важно).
- Принял решение, что буду блог вести на двух языках (от этого зависела структура проекта).
- Так как решил вести блог на двух языках, то сразу выстрелил себе в ногу пришлось изучать множество нюансов, связанных с локализацией. На это потратил большую часть времени: тут и некорректное отображение даты на русском, странные заголовки, которые не хотели убираться из коробки, а также такие простые вещи, как скрытие текста и добавление плейсхолдера "Читать полностью...".

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

Предлагаю ознакомиться 👈

В блоге доступны все свежие посты, начиная с сентября.

В планах (скорее всего, уйдет на 2025 год) добавить:
- Раздел с CV, где по одному клику HR смогут получить PDF.
- Теги, чтобы было удобнее группировать посты (+ облако тегов на главную или другой удобный инструмент для навигации).
- Поисковую строку (опционально, так как видел, что может не стабильно работать).
- Удобную пагинацию при большом количестве постов.

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

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

@time2code
👍11