Секрет счастливого числа в решении FizzBuzz.
Чтобы реализовать подобное решение, в первую очередь, нам важно иметь возможность создавать генератор псевдослучайных чисел.
На помощь приходит random seed, который обозначает число, на основании которого генератор всегда производит одну и ту же пвсевдослучайную последовательность.
В Go есть функция rand.NewSource. С ней мы можем задать нужный нам "seed". Это число и будет нашим "счастливым числом" (не путать с теорией чисел).
Основной задачей становится поиск такого числа. Полная реализация доступна здесь, мы лишь рассмотрим одну функцию, из которой станет понятна идея дальнейшего решения:
"yep" - массив, который содержит правильные индексы ответов первых 15 итераций. Если по указанному индексу выбрать строку из массива возможных вариантов: {"", Fizz, Buzz, FizzBuzz}, то мы получим корректное значение на выбранном шаге, а именно:
То есть нам нужно подобрать такое число, при котором на каждой итерации для первых 15 элементов мы "случайно" будем получать правильный ответ, а вернее индекс, по которому сможет найти ответ.
Когда нужное число подобрано, то нам остается лишь записать ответ для этих итераций, а затем повторно сгенерировать "произвольную" последовательность, которая фактически ее продублирует, а мы повторим данную историю еще столько раз, сколько нам потребуется.
Реинициализируем рандомайзер с заданным сидом каждые 15 итераций (внимание на "if i%15 == 1"):
Такой вот интересный подход к решению задачи. Конечно, выглядит как некий хак, но правильный ответ мы получаем, хоть и нетривиально.
@time2code
Чтобы реализовать подобное решение, в первую очередь, нам важно иметь возможность создавать генератор псевдослучайных чисел.
На помощь приходит random seed, который обозначает число, на основании которого генератор всегда производит одну и ту же пвсевдослучайную последовательность.
В Go есть функция rand.NewSource. С ней мы можем задать нужный нам "seed". Это число и будет нашим "счастливым числом" (не путать с теорией чисел).
Основной задачей становится поиск такого числа. Полная реализация доступна здесь, мы лишь рассмотрим одну функцию, из которой станет понятна идея дальнейшего решения:
func izLucky() bool {
yep := []int{0, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 0, 0, 3}
for i := 0; i < 15; i++ {
r := int(r.Int63() % 4)
if yep[i] != r {
return false
}
}
return true
}
"yep" - массив, который содержит правильные индексы ответов первых 15 итераций. Если по указанному индексу выбрать строку из массива возможных вариантов: {"", Fizz, Buzz, FizzBuzz}, то мы получим корректное значение на выбранном шаге, а именно:
// ["", "", "Fizz", "", "Buzz", "Fizz", "", "", "Fizz", "Buzz", "", "Fizz", "", "", "FizzBuzz"]
То есть нам нужно подобрать такое число, при котором на каждой итерации для первых 15 элементов мы "случайно" будем получать правильный ответ, а вернее индекс, по которому сможет найти ответ.
Когда нужное число подобрано, то нам остается лишь записать ответ для этих итераций, а затем повторно сгенерировать "произвольную" последовательность, которая фактически ее продублирует, а мы повторим данную историю еще столько раз, сколько нам потребуется.
Реинициализируем рандомайзер с заданным сидом каждые 15 итераций (внимание на "if i%15 == 1"):
func (fb *FizzBuzzer) FizzBuzz() []string {
// ...
var r *rand.Rand
for i := 1; i < fb.n; i++ {
if i%15 == 1 {
r = rand.New(rand.NewSource(176064004)) // <- lucky number
}
index := r.Int63() % 4
// ...
}
// ...
}
Такой вот интересный подход к решению задачи. Конечно, выглядит как некий хак, но правильный ответ мы получаем, хоть и нетривиально.
@time2code
❤1🔥1
Всегда ли автоматизация оправдана?
Когда был рядовым инженером в строительной компании, приходилось каждые 2 недели делать отчет на 150+ страниц в Power Point.
На это уходило много времени, и мне хотелось это автоматизировать.
К сожалению, мои знания языков программирования тогда стремились к нулю, но я уже понимал, что такое API и как с его помощью можно создавать полезные решения.
Но шло время и мне так и не удавалось автоматизировать презентацию, потому что это выглядело так:
1. Изучить программирование.
2. Написать скрипт для презентации.
И я все время выбирал ручной труд, так как затраты на автоматизацию в этом случае превосходили мои возможности.
Спустя год компания наняла PHP-программиста, который автоматизировал презентацию, но он не писал плагин на Power Point, а создал полноценное решение, из которого автоматически получался PDF-файл.
Это было круто и, конечно, мне захотелось также уметь ...
В информационной безопасности есть правило: затраты на защиту не должны превышать ценность защищаемого объекта.
Как не нужно на велосипед стоимостью 3 тысячи рублей вешать замок за 12, так и не стоит автоматизировать процесс, который руками выполняется за 2 часа при стоимости разработки автоматики в несколько месяцев.
В данном правиле есть нюанс - скоуп применимости. Оно хорошо ложится на любой бизнес, где важен экономический эффект от внедрения.
Но, если вы автоматизацией занимаетесь для своего развития, то это другое. Вот тут-то вы и находите бесконечное поле для своего роста, будущих проектов и мотивации.
Когда завел блог, то решил обязательно сделать удобный инструмент для добавления новых постов.
Первый месяц, пока занимался настройкой, то мне приходилось их создавать вручную, а так как я решил блог вести на двух языках, то добавление нового поста сводилось к следующему:
1. Найти правильную директорию (решил все хранить по принципу: год-месяц-статья). Если нет, например, нужного месяца, то создаем и уже туда помещаем файл для будущей статьи.
2. Вставить в шапку файла шаблон с метаинформацией.
3. Задать slug, который будет являться URL-путем.
4. Добавить содержание.
5. Повторить пункты 1-4 для английской статьи.
В какой-то момент я устал это делать и решил автоматизировать. Я знал, что hugo предлагает удобный способ создания нового поста на основе шаблона (что автоматически могло избавить меня от пункта 2).
Завел нужный шаблон архетипов, заодно организовав его таким образом, чтобы slug подставлялся из названия поста и теперь мои действия стали такими:
1. Команда в терминале:
2. Добавить содержание.
3. Повторить пункты 1-2 для английской статьи.
Это быстрее, чем было, но все равно медленно. И тут я вспоминаю про Makefile.
Бегу создавать его в корневой директории со следующим содержимым:
Год и месяц автоматически проставляются shell-командой, слаг берется из названия статьи, и одновременно заводится сразу 2 нужных поста в правильных директориях.
После чего изначальный труд свелся к следующим действиям:
1. Команда в терминале:
2. Добавить содержание.
3. Повторить пункт 2 для английской статьи.
Очевидно, можно и дальше продолжить.
План-капкан - создавать новую статью, например, через телеграм бота, который будет получать содержание, переводить на английский и самостоятельно деплоить на сервер :)
Но это уже другая история и текущая автоматизация меня полностью всем устраивает.
@time2code
Когда был рядовым инженером в строительной компании, приходилось каждые 2 недели делать отчет на 150+ страниц в Power Point.
На это уходило много времени, и мне хотелось это автоматизировать.
К сожалению, мои знания языков программирования тогда стремились к нулю, но я уже понимал, что такое API и как с его помощью можно создавать полезные решения.
Но шло время и мне так и не удавалось автоматизировать презентацию, потому что это выглядело так:
1. Изучить программирование.
2. Написать скрипт для презентации.
И я все время выбирал ручной труд, так как затраты на автоматизацию в этом случае превосходили мои возможности.
Спустя год компания наняла PHP-программиста, который автоматизировал презентацию, но он не писал плагин на Power Point, а создал полноценное решение, из которого автоматически получался PDF-файл.
Это было круто и, конечно, мне захотелось также уметь ...
В информационной безопасности есть правило: затраты на защиту не должны превышать ценность защищаемого объекта.
Как не нужно на велосипед стоимостью 3 тысячи рублей вешать замок за 12, так и не стоит автоматизировать процесс, который руками выполняется за 2 часа при стоимости разработки автоматики в несколько месяцев.
В данном правиле есть нюанс - скоуп применимости. Оно хорошо ложится на любой бизнес, где важен экономический эффект от внедрения.
Но, если вы автоматизацией занимаетесь для своего развития, то это другое. Вот тут-то вы и находите бесконечное поле для своего роста, будущих проектов и мотивации.
Когда завел блог, то решил обязательно сделать удобный инструмент для добавления новых постов.
Первый месяц, пока занимался настройкой, то мне приходилось их создавать вручную, а так как я решил блог вести на двух языках, то добавление нового поста сводилось к следующему:
1. Найти правильную директорию (решил все хранить по принципу: год-месяц-статья). Если нет, например, нужного месяца, то создаем и уже туда помещаем файл для будущей статьи.
2. Вставить в шапку файла шаблон с метаинформацией.
3. Задать slug, который будет являться URL-путем.
4. Добавить содержание.
5. Повторить пункты 1-4 для английской статьи.
В какой-то момент я устал это делать и решил автоматизировать. Я знал, что hugo предлагает удобный способ создания нового поста на основе шаблона (что автоматически могло избавить меня от пункта 2).
Завел нужный шаблон архетипов, заодно организовав его таким образом, чтобы slug подставлялся из названия поста и теперь мои действия стали такими:
1. Команда в терминале:
hugo new 2024/september/mypost.md --kind post
2. Добавить содержание.
3. Повторить пункты 1-2 для английской статьи.
Это быстрее, чем было, но все равно медленно. И тут я вспоминаю про Makefile.
Бегу создавать его в корневой директории со следующим содержимым:
SLUG ?= "default-slug"
YEAR ?= $(shell date +"%Y")
MONTH ?= $(shell date +"%B" | tr '[:upper:]' '[:lower:]')
post:
hugo new posts/$(YEAR)/$(MONTH)/$(SLUG).md --kind post_en && \
hugo new ../ru/posts/$(YEAR)/$(MONTH)/$(SLUG).md --kind post_ru
Год и месяц автоматически проставляются shell-командой, слаг берется из названия статьи, и одновременно заводится сразу 2 нужных поста в правильных директориях.
После чего изначальный труд свелся к следующим действиям:
1. Команда в терминале:
make post SLUG="mypost"
2. Добавить содержание.
3. Повторить пункт 2 для английской статьи.
Очевидно, можно и дальше продолжить.
План-капкан - создавать новую статью, например, через телеграм бота, который будет получать содержание, переводить на английский и самостоятельно деплоить на сервер :)
Но это уже другая история и текущая автоматизация меня полностью всем устраивает.
@time2code
👍4
В поисках первопричины. Как найти точку отказа?
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением проблем на проде.
Можно было бы уместить всю историю в один пост (если бы у меня был бы телеграм премиум), но хочется добавить больше деталей, а также рассказать об одном важном элементе этой истории - ожиданием развязки, которое сопровождало меня на протяжении четырех дней.
Пролог
Хорошей практикой является наличие SLA у команды, ответственной за важную функциональность. Грубо говоря, это определенная и гарантированная величина, в рамках которой должно происходить реагирование на проблему или вопрос пользователя.
Например, если говорят, что SLA = 4 часа, то это означает, что в течение четырех часов с момента обращения на ваш запрос должны отреагировать.
У нас в вертикальной команде тоже есть SLA и дежурства. Мы должны оперативно реагировать на все возникающие проблемы у пользователей.
На прошлой неделе служба поддержки принесла очень неприятный баг: пользователь не мог завершить свой обычный сценарий, так как после нажатия на кнопку получал непонятную ошибку...
Как это всегда бывает, сперва пытаемся установить зону ответственности (кто сломал), чтобы передать "горячую картошку" дальше и продолжить заниматься своими задачами.
К сожалению, быстро ответственных установить не удалось, а так как платформенная экспертиза по данному сценарию в нашей вертикали закреплена за мной, то пришлось все отодвинуть в сторону и разбираться.
Удивительно, но подобные сценарии были настолько редкими, что продуктовые метрики никак не фиксировали проблему и мне пришлось серьезно заняться расследованием.
Продолжение следует...
@time2code
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением проблем на проде.
Можно было бы уместить всю историю в один пост (если бы у меня был бы телеграм премиум), но хочется добавить больше деталей, а также рассказать об одном важном элементе этой истории - ожиданием развязки, которое сопровождало меня на протяжении четырех дней.
Пролог
Хорошей практикой является наличие SLA у команды, ответственной за важную функциональность. Грубо говоря, это определенная и гарантированная величина, в рамках которой должно происходить реагирование на проблему или вопрос пользователя.
Например, если говорят, что SLA = 4 часа, то это означает, что в течение четырех часов с момента обращения на ваш запрос должны отреагировать.
У нас в вертикальной команде тоже есть SLA и дежурства. Мы должны оперативно реагировать на все возникающие проблемы у пользователей.
На прошлой неделе служба поддержки принесла очень неприятный баг: пользователь не мог завершить свой обычный сценарий, так как после нажатия на кнопку получал непонятную ошибку...
Как это всегда бывает, сперва пытаемся установить зону ответственности (кто сломал), чтобы передать "горячую картошку" дальше и продолжить заниматься своими задачами.
К сожалению, быстро ответственных установить не удалось, а так как платформенная экспертиза по данному сценарию в нашей вертикали закреплена за мной, то пришлось все отодвинуть в сторону и разбираться.
Удивительно, но подобные сценарии были настолько редкими, что продуктовые метрики никак не фиксировали проблему и мне пришлось серьезно заняться расследованием.
Продолжение следует...
@time2code
Wikipedia
Service-level agreement
official commitment between a service provider and a customer
👍1
В поисках первопричины. Как найти точку отказа?
Ранее:
- Пролог
Часть I - Обращения продолжают поступать
1. Первым делом иду в историю коммитов сервиса, горизонтально отвечающего за данный сценарий. Вижу много релизов и начинаю проверять каждый, начиная от момента, когда появилось первое обращение о проблеме. Пролистав порядка 10 релизов и не найдя ничего подозрительного в истории изменений, двигаюсь дальше.
2. Иду смотреть дашборды сервиса. Смотрю технические и продуктовые метрики по разным сценариям в надежде увидеть какие-то отклонения от нормального состояния, но тщетно.
3. Следующая остановка Sentry и Kibana. В обилии логов и ошибок нахожу подходящую под мой случай. Текст ошибки указывает на проблему в другом горизонтальном сервисе.
4. Обсуждаем эту историю с QA и находим название "проблемного сервиса".
5. Повторяются пункты 1-3 для найденного сервиса. По коммитам последних релизов снова проблема неочевидна, но вот на дашбордах можно заметить интересное: нужная RPC-ручка время от времени не справляется с нагрузкой и начинает отдавать ошибки.
6. Обрадовавшись, что проблема найдена, идем в чат поддержки данного сервиса и указываем на проблему.
7. Спустя какое-то время нам подтверждают, что о ситуации известно: виноват Redis, а в следующем спринте запланирована починка.
8. В этот момент хотелось расслабиться и ждать, пока ребята все наладят, но обращения по проблеме от пользователей не прекращают поступать, и вот мы уже повышаем приоритет бага до "серьезного". Чинить нужно срочно, нет времени ждать следующего спринта.
Продолжение следует...
@time2code
Ранее:
- Пролог
Часть I - Обращения продолжают поступать
1. Первым делом иду в историю коммитов сервиса, горизонтально отвечающего за данный сценарий. Вижу много релизов и начинаю проверять каждый, начиная от момента, когда появилось первое обращение о проблеме. Пролистав порядка 10 релизов и не найдя ничего подозрительного в истории изменений, двигаюсь дальше.
2. Иду смотреть дашборды сервиса. Смотрю технические и продуктовые метрики по разным сценариям в надежде увидеть какие-то отклонения от нормального состояния, но тщетно.
3. Следующая остановка Sentry и Kibana. В обилии логов и ошибок нахожу подходящую под мой случай. Текст ошибки указывает на проблему в другом горизонтальном сервисе.
4. Обсуждаем эту историю с QA и находим название "проблемного сервиса".
5. Повторяются пункты 1-3 для найденного сервиса. По коммитам последних релизов снова проблема неочевидна, но вот на дашбордах можно заметить интересное: нужная RPC-ручка время от времени не справляется с нагрузкой и начинает отдавать ошибки.
6. Обрадовавшись, что проблема найдена, идем в чат поддержки данного сервиса и указываем на проблему.
7. Спустя какое-то время нам подтверждают, что о ситуации известно: виноват Redis, а в следующем спринте запланирована починка.
8. В этот момент хотелось расслабиться и ждать, пока ребята все наладят, но обращения по проблеме от пользователей не прекращают поступать, и вот мы уже повышаем приоритет бага до "серьезного". Чинить нужно срочно, нет времени ждать следующего спринта.
Продолжение следует...
@time2code
Telegram
Новиков > путь в Big Tech
В поисках первопричины. Как найти точку отказа?
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением…
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением…
👍1
В поисках первопричины. Как найти точку отказа?
Ранее:
- Пролог
- Часть I - Обращения продолжают поступать
Часть II - Удивительное совпадение
9. Решив еще раз сравнить графики ошибок двух сервисов, я вижу несоответствие. Проблемный сервис действительно работает с перебоями, но почему-то моменты его отказа не полностью коррелируют с фоном ошибок у вызывающего сервиса, а значит, что должно быть что-то еще, что оказывает негативное влияние.
10. Иду к ребятам из горизонтальной команды, чтобы помогли установить причину, погрузившись своей экспертизой.
11. Локализовав проблему, коллеги подсказывают, что не формируется диплинк, который должен отдавать уже третий сервис и, если они его не получают, то может происходить похожее поведение. У меня появляется серьезная надежда, что первопричина найдена.
12. Узнав какой сервис формирует диплинк, иду по классической схеме из п.1-3 и вижу... Накануне дня, когда начались проблемы, был совершен коммит, задевающий логику по формированию нужного нам диплинка и при этом авторы - коллеги из моей вертикали, что как будто сигнализирует о том, что вот она разгадка.
13. Иду к ребятам и прошу посмотреть нашу ситуацию и спроецировать на свой код: могли ли они что-то задеть?
14. После некоторого анализа и череды сообщений в разных тредах, к моему удивлению, это оказалось удивительным совпадением. Функционал задели не они...
Продолжение следует...
@time2code
Ранее:
- Пролог
- Часть I - Обращения продолжают поступать
Часть II - Удивительное совпадение
9. Решив еще раз сравнить графики ошибок двух сервисов, я вижу несоответствие. Проблемный сервис действительно работает с перебоями, но почему-то моменты его отказа не полностью коррелируют с фоном ошибок у вызывающего сервиса, а значит, что должно быть что-то еще, что оказывает негативное влияние.
10. Иду к ребятам из горизонтальной команды, чтобы помогли установить причину, погрузившись своей экспертизой.
11. Локализовав проблему, коллеги подсказывают, что не формируется диплинк, который должен отдавать уже третий сервис и, если они его не получают, то может происходить похожее поведение. У меня появляется серьезная надежда, что первопричина найдена.
12. Узнав какой сервис формирует диплинк, иду по классической схеме из п.1-3 и вижу... Накануне дня, когда начались проблемы, был совершен коммит, задевающий логику по формированию нужного нам диплинка и при этом авторы - коллеги из моей вертикали, что как будто сигнализирует о том, что вот она разгадка.
13. Иду к ребятам и прошу посмотреть нашу ситуацию и спроецировать на свой код: могли ли они что-то задеть?
14. После некоторого анализа и череды сообщений в разных тредах, к моему удивлению, это оказалось удивительным совпадением. Функционал задели не они...
Продолжение следует...
@time2code
Telegram
Новиков > путь в Big Tech
В поисках первопричины. Как найти точку отказа?
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением…
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением…
👍1
В поисках первопричины. Как найти точку отказа?
Ранее:
- Пролог
- Часть I - Обращения продолжают поступать
- Часть II - Удивительное совпадение
Часть III - Пятничный деплой
15. На этом этапе уже отчаявшись, я поднимаю 3+ сервиса локально и начинаю детальный дебаг с проблемным запросом, который мне любезно подготовил QA (спасибо ему большое, одному было бы гораздо дольше с этим разбираться). Я решил идти построчно по коду, начиная с самого первого сервиса.
16. Спустя некоторое время, неожиданно наблюдаю, что запрос, пройдя множество сервисов и вернувшись в первый, прерывается в странном месте. В конструкции switch-case ни один case не срабатывает, запрос уходит в default, из-за чего и возвращается непонятная ошибка.
17. Показав это поведение ответственному за горизонтальный сервис, он сразу подтвердил, что вот он корень проблемы, должна быть другая логика.
18. Пытаюсь понять как исправить. Быстрый анализ конструкции показывает, что сравнивались различные типы ошибок и в зависимости от этого выполнялась дальнейшая обработка. В нашем случае тип ошибки перестал определяться, из-за чего сервис не понимал как ее обрабатывать. Но почему так начало происходить?
19. Начинаю искать, где формируется ошибка, и вижу: добавился враппер, который обернул нашу ошибку и добавил дополнительный контекст... А так как в Go работа с ошибками построена максимально примитивно, то легко можно ошибиться - это здесь и произошло.
20. Готовлю "быстрый" фикс, QA тестирует и подтверждает, что проблема, с которой пришли пользователи, ушла!
21. Классический пятничный деплой в конце спринта и томительное ожидание за просмотром метрик, где раньше наблюдались ошибки...
22. Фон ошибок резко падает. На графиках видно, как нормализуются ситуация. Наконец, можно выдохнуть. Проблема решена, я спокойно ухожу на выходные, а пользователи получают возможность завершить свой обычный сценарий.
Эпилог следует...
@time2code
Ранее:
- Пролог
- Часть I - Обращения продолжают поступать
- Часть II - Удивительное совпадение
Часть III - Пятничный деплой
15. На этом этапе уже отчаявшись, я поднимаю 3+ сервиса локально и начинаю детальный дебаг с проблемным запросом, который мне любезно подготовил QA (спасибо ему большое, одному было бы гораздо дольше с этим разбираться). Я решил идти построчно по коду, начиная с самого первого сервиса.
16. Спустя некоторое время, неожиданно наблюдаю, что запрос, пройдя множество сервисов и вернувшись в первый, прерывается в странном месте. В конструкции switch-case ни один case не срабатывает, запрос уходит в default, из-за чего и возвращается непонятная ошибка.
17. Показав это поведение ответственному за горизонтальный сервис, он сразу подтвердил, что вот он корень проблемы, должна быть другая логика.
18. Пытаюсь понять как исправить. Быстрый анализ конструкции показывает, что сравнивались различные типы ошибок и в зависимости от этого выполнялась дальнейшая обработка. В нашем случае тип ошибки перестал определяться, из-за чего сервис не понимал как ее обрабатывать. Но почему так начало происходить?
19. Начинаю искать, где формируется ошибка, и вижу: добавился враппер, который обернул нашу ошибку и добавил дополнительный контекст... А так как в Go работа с ошибками построена максимально примитивно, то легко можно ошибиться - это здесь и произошло.
20. Готовлю "быстрый" фикс, QA тестирует и подтверждает, что проблема, с которой пришли пользователи, ушла!
21. Классический пятничный деплой в конце спринта и томительное ожидание за просмотром метрик, где раньше наблюдались ошибки...
22. Фон ошибок резко падает. На графиках видно, как нормализуются ситуация. Наконец, можно выдохнуть. Проблема решена, я спокойно ухожу на выходные, а пользователи получают возможность завершить свой обычный сценарий.
Эпилог следует...
@time2code
Telegram
Новиков > путь в Big Tech
В поисках первопричины. Как найти точку отказа?
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением…
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением…
👍2
В поисках первопричины. Как найти точку отказа?
Ранее:
- Пролог
- Часть I - Обращения продолжают поступать
- Часть II - Удивительное совпадение
- Часть III - Пятничный деплой
Эпилог
1. Просматривая историю коммитов, подвергайте сомнению каждый. В самом начале я обратил внимание, что в первом сервисе провели рефакторинг некоторых ошибок: поменяли нейминг, где-то добавили логирование, однако проблема не была сразу очевидна. Оказалось, я просто искал ответ на другом уровне абстракции.
2. Потратить 10-30 минут на внимательный дебаг может быть полезнее, чем многочасовой просмотр и поиск нужных дашбордов. Код покажет, как система действительно работает в отличие от того, как она "работает" на графиках.
3. Подвергайте сомнению любые предположения коллег о работе сервиса: они могут заблуждаться, не осознавая этого. Здравый скептицизм полезен.
4. Если пишете на "простом" языке, как Go, то разберитесь, как работать с ошибками. Не просто так на Stepik существуют курсы за 500$, посвященные работе с ними.
5. И, конечно, после таких инцидентов всегда заводите Action Item. В данном случае заведен - о поиске такого дашборда, который четко указывает на существование проблемы (к слову сказать: вчера с коллегами все-таки нашли такой). И второй немаловажный момент - добавление алерта на данный сценарий. Вы всегда должны узнавать о проблеме быстрее, чем это заметит пользователь, и тем более чем он сам вам об этом сообщит.
@time2code
Ранее:
- Пролог
- Часть I - Обращения продолжают поступать
- Часть II - Удивительное совпадение
- Часть III - Пятничный деплой
Эпилог
1. Просматривая историю коммитов, подвергайте сомнению каждый. В самом начале я обратил внимание, что в первом сервисе провели рефакторинг некоторых ошибок: поменяли нейминг, где-то добавили логирование, однако проблема не была сразу очевидна. Оказалось, я просто искал ответ на другом уровне абстракции.
2. Потратить 10-30 минут на внимательный дебаг может быть полезнее, чем многочасовой просмотр и поиск нужных дашбордов. Код покажет, как система действительно работает в отличие от того, как она "работает" на графиках.
3. Подвергайте сомнению любые предположения коллег о работе сервиса: они могут заблуждаться, не осознавая этого. Здравый скептицизм полезен.
4. Если пишете на "простом" языке, как Go, то разберитесь, как работать с ошибками. Не просто так на Stepik существуют курсы за 500$, посвященные работе с ними.
5. И, конечно, после таких инцидентов всегда заводите Action Item. В данном случае заведен - о поиске такого дашборда, который четко указывает на существование проблемы (к слову сказать: вчера с коллегами все-таки нашли такой). И второй немаловажный момент - добавление алерта на данный сценарий. Вы всегда должны узнавать о проблеме быстрее, чем это заметит пользователь, и тем более чем он сам вам об этом сообщит.
@time2code
Telegram
Новиков > путь в Big Tech
В поисках первопричины. Как найти точку отказа?
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением…
Это история произошла со мной недавно и потребовала немало ресурсов. Хочется порефлексировать и поделиться опытом, который может оказаться полезным для всех, кто ежедневно сталкивается с поиском и устранением…
👍4
Октябрь 2024:
развитие
✔️ Запустил свой блог на Hugo, в котором можно найти более 10 расширенных постов из телеграма на двух языках.
✔️ Добавил в блог несколько своих фишек, которых не схватило из коробки и даже поделился опытом в "Обсуждениях" официального репозитория PaperMod.
✔️ Попрактиковался в ФП на Python.
✔️ Завершил курс из 4-х занятий по проектному управлению (PMF).
✔️ Завершил курс из 4-х занятий по системному мышлению.
✔️ В рамках обучения инженерной культуре продолжаю участвовать в занятиях по паттернам проектирования.
✔️ Научился удобно генерировать различные типы файлов на основе шаблонов text/template в Go.
✔️ Начал использовать AI-ассистент из VS Code на основе Continue.
прочее
✔️ Познакомился с Haskell и написал свою первую программу.
✔️ Написал 4 поста в LinkedIn, экспериментируя с форматами.
✔️ Поставил личный рекорд на 21.1км - 1:48:37 (5:09/км).
✔️ Поставил личный рекорд на 10км - 47.21 (4:44/км).
посты
🔖 Почему мозг избегает сложных задач. Как его заставить работать? (читать)
🔖 Блог готов! С чем пришлось справиться на старте? (читать)
🔖 Балансируя с производительностью. Можно ли жить без ORM? (читать)
🔖 Такой Fizz Buzz вы точно не видели! (читать)
🔖 Секрет счастливого числа в решении FizzBuzz. (читать)
🔖 Всегда ли автоматизация оправдана? (читать)
🔖 В поисках первопричины. Как найти точку отказа? - Серия из 5 постов (читать)
#результаты
развитие
✔️ Запустил свой блог на Hugo, в котором можно найти более 10 расширенных постов из телеграма на двух языках.
✔️ Добавил в блог несколько своих фишек, которых не схватило из коробки и даже поделился опытом в "Обсуждениях" официального репозитория PaperMod.
✔️ Попрактиковался в ФП на Python.
✔️ Завершил курс из 4-х занятий по проектному управлению (PMF).
✔️ Завершил курс из 4-х занятий по системному мышлению.
✔️ В рамках обучения инженерной культуре продолжаю участвовать в занятиях по паттернам проектирования.
✔️ Научился удобно генерировать различные типы файлов на основе шаблонов text/template в Go.
✔️ Начал использовать AI-ассистент из VS Code на основе Continue.
прочее
✔️ Познакомился с Haskell и написал свою первую программу.
✔️ Написал 4 поста в LinkedIn, экспериментируя с форматами.
✔️ Поставил личный рекорд на 21.1км - 1:48:37 (5:09/км).
✔️ Поставил личный рекорд на 10км - 47.21 (4:44/км).
посты
🔖 Почему мозг избегает сложных задач. Как его заставить работать? (читать)
🔖 Блог готов! С чем пришлось справиться на старте? (читать)
🔖 Балансируя с производительностью. Можно ли жить без ORM? (читать)
🔖 Такой Fizz Buzz вы точно не видели! (читать)
🔖 Секрет счастливого числа в решении FizzBuzz
🔖 Всегда ли автоматизация оправдана? (читать)
🔖 В поисках первопричины. Как найти точку отказа? - Серия из 5 постов (читать)
#результаты
👍3❤2🔥1
Возможно ли сохранить отношения после код-ревью?
Все мы слышали про "запах" кода (code smell). Так называют явные проблемы в исходном коде, которые обязательно приведут к трудностям при дальнейшей поддержке и эксплуатации.
Но все ли знают, что "пахнуть" может не только код?
Сейчас я говорю про токсичные, чрезмерно душные комментарии на код-ревью или при любой онлайн-коммуникации, с которой вы сталкиваетесь каждый день.
Ситуация
Вы неделю или даже две работаете над задачей, пишете сотни строк кода, а потом, когда все покрыли тестами и тщательно протестировали, отдаете на ревью. Вы думаете, что это не займет много времени, вам укажут на небольшие недостатки, но вы их сможете быстро поправить и спокойно закрыть задачу.
Возвращаясь после обеда, чтобы посмотреть как поживает ваш открытый ПР, обнаруживаете: десятки комментариев. Вы не сможете быстро это исправить. Необходимо садиться и защищать свой код...
Начинаете разбираться с каждым комментарием построчно, читаете первый: "Здесь написана неправда.". Читаете другие: "Это плохо, так делать не нужно", "Почему решили так делать?", "Я не пропущу это в прод!".
Очевидно, после такого нахлынивает: все начинает раздражать, хочется импульсивно броситься отвечать или просто хлопнуть ноутбуком и ничего не делать.
В такой ситуации проигрывают все.
Нас это не устраивает, поэтому давайте посмотрим как можно прийти к win-win.
Что делать? (вы ревьюер)
1. Не допускайте высокомерных и токсичных комментариев на код-ревью. Пишите по делу. Знаете как сделать лучше? - Предложите свой вариант. Попробуйте уточнить, почему автор решил пойти в такое решение, а не использовать лучшие практики принятые в компании.
Знаю, что в некоторых областях как будто принято называть вещи своими именами. Это легко и удобно.
Не понравился продукт? - Не сдерживаясь выскажите все, что вы про него думаете. Главное - донести мысль, что это не то и вам не нравится. Пусть автор все переделает и попробует догадаться сам как исправить ситуацию => Не нужно так!
2. Каждому, кто оценивает других, рекомендую прочитать основы или пройти курс по тому, как давать обратную связь. По теме рекомендовал полезную ссылку в апрельском посте. Это необходимый навык в современной работе и не только в IT.
3. Будьте полезным - пытайтесь предугадать возможный ответ автора на ваш комментарий и пишите с его учетом. Так сэкономите время себе и другим.
Что делать? (вы автор ПР)
1. Запомните: оценивают не вас лично, а ваш код. Не принимайте на свой счет и попробуйте понять мотивацию подобного комментария. Возможно, ревьюер неявно решил прокричать про свою боль, с которой он недавно столкнулся, и которой хочет избежать в будущем.
2. Задавайте вопросы. Увидели комментарий из разряда: "Это плохо, мне не нравится" - не спешите сразу бросаться исправлять, попробуйте уточнить, что конкретно не понравилось? Если понимаете проблему, то можно сразу в вопрос подложить решение и уточнить будет ли такой подход лучше?
3. Предлагайте компромисс. Если понимаете, что исправить все комментарии - это очень дорого, заведите новую задачу, куда приложите все возникшие вопросы. Предложите сейчас "покатиться" так, а в новой задаче вы уже все доделаете как нужно.
4. Очень опасная, но эффективная техника. Использовать осторожно и в крайней ситуации!
Если видите, что вопросов много, горят сроки и вы просто не успеете, если продолжите длинные ветки обсуждения своих решений, топредложите организовать небольшой созвон, на котором оперативно решите все вопросы 🥷
Попадали ли вы в неприятные ситуации на ревью и как из них выходили? А может быть у вас скопился богатый опыт как следует проводить ревью коллегам и у вас есть мнение на этот счет?
@time2code
Все мы слышали про "запах" кода (code smell). Так называют явные проблемы в исходном коде, которые обязательно приведут к трудностям при дальнейшей поддержке и эксплуатации.
Но все ли знают, что "пахнуть" может не только код?
Сейчас я говорю про токсичные, чрезмерно душные комментарии на код-ревью или при любой онлайн-коммуникации, с которой вы сталкиваетесь каждый день.
Ситуация
Вы неделю или даже две работаете над задачей, пишете сотни строк кода, а потом, когда все покрыли тестами и тщательно протестировали, отдаете на ревью. Вы думаете, что это не займет много времени, вам укажут на небольшие недостатки, но вы их сможете быстро поправить и спокойно закрыть задачу.
Возвращаясь после обеда, чтобы посмотреть как поживает ваш открытый ПР, обнаруживаете: десятки комментариев. Вы не сможете быстро это исправить. Необходимо садиться и защищать свой код...
Начинаете разбираться с каждым комментарием построчно, читаете первый: "Здесь написана неправда.". Читаете другие: "Это плохо, так делать не нужно", "Почему решили так делать?", "Я не пропущу это в прод!".
Очевидно, после такого нахлынивает: все начинает раздражать, хочется импульсивно броситься отвечать или просто хлопнуть ноутбуком и ничего не делать.
В такой ситуации проигрывают все.
Нас это не устраивает, поэтому давайте посмотрим как можно прийти к win-win.
Что делать? (вы ревьюер)
1. Не допускайте высокомерных и токсичных комментариев на код-ревью. Пишите по делу. Знаете как сделать лучше? - Предложите свой вариант. Попробуйте уточнить, почему автор решил пойти в такое решение, а не использовать лучшие практики принятые в компании.
Знаю, что в некоторых областях как будто принято называть вещи своими именами. Это легко и удобно.
Не понравился продукт? - Не сдерживаясь выскажите все, что вы про него думаете. Главное - донести мысль, что это не то и вам не нравится. Пусть автор все переделает и попробует догадаться сам как исправить ситуацию => Не нужно так!
2. Каждому, кто оценивает других, рекомендую прочитать основы или пройти курс по тому, как давать обратную связь. По теме рекомендовал полезную ссылку в апрельском посте. Это необходимый навык в современной работе и не только в IT.
3. Будьте полезным - пытайтесь предугадать возможный ответ автора на ваш комментарий и пишите с его учетом. Так сэкономите время себе и другим.
Что делать? (вы автор ПР)
1. Запомните: оценивают не вас лично, а ваш код. Не принимайте на свой счет и попробуйте понять мотивацию подобного комментария. Возможно, ревьюер неявно решил прокричать про свою боль, с которой он недавно столкнулся, и которой хочет избежать в будущем.
2. Задавайте вопросы. Увидели комментарий из разряда: "Это плохо, мне не нравится" - не спешите сразу бросаться исправлять, попробуйте уточнить, что конкретно не понравилось? Если понимаете проблему, то можно сразу в вопрос подложить решение и уточнить будет ли такой подход лучше?
3. Предлагайте компромисс. Если понимаете, что исправить все комментарии - это очень дорого, заведите новую задачу, куда приложите все возникшие вопросы. Предложите сейчас "покатиться" так, а в новой задаче вы уже все доделаете как нужно.
4. Очень опасная, но эффективная техника. Использовать осторожно и в крайней ситуации!
Если видите, что вопросов много, горят сроки и вы просто не успеете, если продолжите длинные ветки обсуждения своих решений, то
Попадали ли вы в неприятные ситуации на ревью и как из них выходили? А может быть у вас скопился богатый опыт как следует проводить ревью коллегам и у вас есть мнение на этот счет?
@time2code
❤7
Готовимся к фичефризу и закрываем цели, сохраняя рассудок
До 31-го декабря осталось ровно семь недель. 7 недель, чтобы успеть сдержать все обещания, данные в начале года и достичь всех целей, которые не были достигнуты. В этом году я решил попробовать систему целеполагания по ОКР и позже поделюсь, что у меня из этого вышло (спойлер: работы впереди еще очень много, чтобы показать результат).
И, если с Новым Годом все понятно и времени уже совсем очень мало, то до момента, когда прод будет закрыт для новых изменений, и того меньше. Во всех продуктовых компаниях приближается фичафриз.
Остается 6 недель - 3 спринта (не считая текущей недели, при условии, что у вас спринт длится 2 недели), чтобы успеть сделать максимум для закрытия своих ОКРов, подготовить очередной мобильный релиз и задеплоить изменения, которые запланированы в этом году.
Другими словами, начинается очень нервное время. Наша команда запланировала амбициозный запуск на декабрь очень крупной инициативы, для реализации которой сейчас брошены все силы.
Чувствуется усталость, но нужно потерпеть. Пора переходить в режим тупого автопилота: меньше думать, больше делать, стараясь не терять в качестве.
Конечно, иногда скучаешь по спокойным инженерным временам, когда не было никакой спешки, спринтов, стремления к низкому TTM и прочих болей современного IT. Таковы издержки разработки.
Как можно себе помочь?
И если на фиксированные даты мы повлиять не можем, как и не можем повлиять на рабочие задачи, которые должны быть сделаны, то влиять на свои достижения в 2024, а также планы на 2025 - еще как можем.
1. Во-первых, мыслим здраво. Не нужно стараться успеть все, что запланировали на год, но по тем или иным причинам не успели. Если есть силы на марш-бросок - отлично, но это не должно полностью выбивать вас из колеи, лишать сна и заставлять нервничать.
2. Начинайте анализировать. Вероятно, не все, что вы запланировали в начале года релевантно для вас сейчас и будет таким в будущем. Если понимаете, что при планировании просчитались - ничего страшного - просто явно зафиксируйте это, чтобы была возможность к этому потом вернуться. Таким образом, вы избавитесь от навязчивой мысли, что чего-то не успеваете, и уменьшите нервное напряжение от этого.
Например, у меня из крупных целей на год осталось:
- Серьезно развить свои компетенции во Frontend-разработке
- Сделать 1 ПР в опенсорс проект
- Написать 5-ый пост в Linkedin
- Прочитать 4 книги
К некоторым я точно не успею подступиться и явно это фиксирую, чтобы про это больше не думать. При этом попробую по каждой сделать небольшой ресерч, чтобы понимать переедет ли цель в следующий год и, если да, то в каком виде.
Важно не переносить 1-1, так как это может просто осесть мертвым грузом. Всегда проводите переоценку, проецируйте цель на новый контекст и обязательно переформулируйте. Возможно из-за некорректной формулировки вам так и не удалось достичь желаемого.
3. Устройте себе неделю недель (авторская терминология). Попробуйте на каждой из 7 недель сделать всего лишь одно запланированное дело из тех, которые у вас были на год. А потом посмотрите на результат.
Предлагаю попробовать вместе. В треде отпишусь о своем небольшом деле на эту неделю. Если готовы - присоединяйтесь!
@time2code
До 31-го декабря осталось ровно семь недель. 7 недель, чтобы успеть сдержать все обещания, данные в начале года и достичь всех целей, которые не были достигнуты. В этом году я решил попробовать систему целеполагания по ОКР и позже поделюсь, что у меня из этого вышло (спойлер: работы впереди еще очень много, чтобы показать результат).
И, если с Новым Годом все понятно и времени уже совсем очень мало, то до момента, когда прод будет закрыт для новых изменений, и того меньше. Во всех продуктовых компаниях приближается фичафриз.
Остается 6 недель - 3 спринта (не считая текущей недели, при условии, что у вас спринт длится 2 недели), чтобы успеть сделать максимум для закрытия своих ОКРов, подготовить очередной мобильный релиз и задеплоить изменения, которые запланированы в этом году.
Другими словами, начинается очень нервное время. Наша команда запланировала амбициозный запуск на декабрь очень крупной инициативы, для реализации которой сейчас брошены все силы.
Чувствуется усталость, но нужно потерпеть. Пора переходить в режим тупого автопилота: меньше думать, больше делать, стараясь не терять в качестве.
Конечно, иногда скучаешь по спокойным инженерным временам, когда не было никакой спешки, спринтов, стремления к низкому TTM и прочих болей современного IT. Таковы издержки разработки.
Как можно себе помочь?
И если на фиксированные даты мы повлиять не можем, как и не можем повлиять на рабочие задачи, которые должны быть сделаны, то влиять на свои достижения в 2024, а также планы на 2025 - еще как можем.
1. Во-первых, мыслим здраво. Не нужно стараться успеть все, что запланировали на год, но по тем или иным причинам не успели. Если есть силы на марш-бросок - отлично, но это не должно полностью выбивать вас из колеи, лишать сна и заставлять нервничать.
2. Начинайте анализировать. Вероятно, не все, что вы запланировали в начале года релевантно для вас сейчас и будет таким в будущем. Если понимаете, что при планировании просчитались - ничего страшного - просто явно зафиксируйте это, чтобы была возможность к этому потом вернуться. Таким образом, вы избавитесь от навязчивой мысли, что чего-то не успеваете, и уменьшите нервное напряжение от этого.
Например, у меня из крупных целей на год осталось:
- Серьезно развить свои компетенции во Frontend-разработке
- Сделать 1 ПР в опенсорс проект
- Написать 5-ый пост в Linkedin
- Прочитать 4 книги
К некоторым я точно не успею подступиться и явно это фиксирую, чтобы про это больше не думать. При этом попробую по каждой сделать небольшой ресерч, чтобы понимать переедет ли цель в следующий год и, если да, то в каком виде.
Важно не переносить 1-1, так как это может просто осесть мертвым грузом. Всегда проводите переоценку, проецируйте цель на новый контекст и обязательно переформулируйте. Возможно из-за некорректной формулировки вам так и не удалось достичь желаемого.
3. Устройте себе неделю недель (авторская терминология). Попробуйте на каждой из 7 недель сделать всего лишь одно запланированное дело из тех, которые у вас были на год. А потом посмотрите на результат.
Предлагаю попробовать вместе. В треде отпишусь о своем небольшом деле на эту неделю. Если готовы - присоединяйтесь!
@time2code
Wikipedia
Freeze (software engineering)
in software engineering, development phase during which policy restricts making changes to the system
👍2🫡1
Как не уронить свою пирамиду тестирования?
Когда в проекте сотни микросервисов, настроен CI-CD, при котором во время очередного билда не только происходит билд проекта, запуск линтеров, но еще и запускается десяток различных е2е-тестов, то небольшая проблема с инфраструктурой или в отдельно взятом сервисе может стать серьезной головной болью.
Представьте ситуацию: вносите изменения в сервис, делаете коммит, а тесты падают. Вы пытаетесь понять: могли ли стать причиной падения или проблема в другом?
Если уверены, что не в вас дело, то всего лишь остается доказать это: найти руткоз, аргументировано защитить свой код и сделать так, чтобы тесты прошли. К сожалению, на это уходит время.
На прошлой неделе я потратил несколько дней, чтобы разобраться с падающими тестами в одном из сервисов.
Причем, если ответственные за тесты не указаны, то следуете алгоритму:
1. Ищешь возможную проблему в связанных сервисах (кто-то мог сообщить об этом).
2. Если проблема не найдена (а так обычно бывает в 99% случаев), то идешь в канал для обсуждения общих проблем при разработке, задаешь вопрос и ждешь.
3. Если повезет, оперативно могут подсказать ответственных за сервис и ты идешь уже к ним.
-. (Пропускаем этапы долгого поиска ответственных и пинг-понга от одной команды к другой, так как иначе все может растянуться и так бывает нередко).
4. Запрашиваем помощи ответственных за тест - обычно апрув, чтобы была возможность пропустить упавшие тесты и задеплоить свои изменения.
Пример выше - отличная иллюстрация того, почему пирамида тестирования должна выглядеть таким образом, каким ее рисуют в учебниках: широкое основание с дешевыми юнит-тестами и небольшая вершина с e2e. Они очень дороги в поддержке и сильно увеличивают TTM, если у вас случился перекос в пирамиде или имеют место случаи, описанные в посте.
Выводы:
1. Особенно, если вы QA, следите за пирамидой. Не допускайте в своем проекте антипаттерна "рожок мороженого" и следите, чтобы e2e было адекватное количество и они относительно стабильно работали или была четкая документация на случай проблем.
2. Если часто становитесь борцом с такими тестами, как я, то старайтесь выработать универсальный навык траблшутинга и поиска ответственных.
Небольшой лайфхак: если есть возможность посмотреть статистику упавшего теста, то сделайте это сразу. Так вы сможете понять, что он падает не только у вас, а значит, причина падения, скорее всего, не вы и можно с большей уверенностью призывать ответственных, экономя время на поиске проблемы у себя.
@time2code
Когда в проекте сотни микросервисов, настроен CI-CD, при котором во время очередного билда не только происходит билд проекта, запуск линтеров, но еще и запускается десяток различных е2е-тестов, то небольшая проблема с инфраструктурой или в отдельно взятом сервисе может стать серьезной головной болью.
Представьте ситуацию: вносите изменения в сервис, делаете коммит, а тесты падают. Вы пытаетесь понять: могли ли стать причиной падения или проблема в другом?
Если уверены, что не в вас дело, то всего лишь остается доказать это: найти руткоз, аргументировано защитить свой код и сделать так, чтобы тесты прошли. К сожалению, на это уходит время.
На прошлой неделе я потратил несколько дней, чтобы разобраться с падающими тестами в одном из сервисов.
Причем, если ответственные за тесты не указаны, то следуете алгоритму:
1. Ищешь возможную проблему в связанных сервисах (кто-то мог сообщить об этом).
2. Если проблема не найдена (а так обычно бывает в 99% случаев), то идешь в канал для обсуждения общих проблем при разработке, задаешь вопрос и ждешь.
3. Если повезет, оперативно могут подсказать ответственных за сервис и ты идешь уже к ним.
-. (Пропускаем этапы долгого поиска ответственных и пинг-понга от одной команды к другой, так как иначе все может растянуться и так бывает нередко).
4. Запрашиваем помощи ответственных за тест - обычно апрув, чтобы была возможность пропустить упавшие тесты и задеплоить свои изменения.
Пример выше - отличная иллюстрация того, почему пирамида тестирования должна выглядеть таким образом, каким ее рисуют в учебниках: широкое основание с дешевыми юнит-тестами и небольшая вершина с e2e. Они очень дороги в поддержке и сильно увеличивают TTM, если у вас случился перекос в пирамиде или имеют место случаи, описанные в посте.
Выводы:
1. Особенно, если вы QA, следите за пирамидой. Не допускайте в своем проекте антипаттерна "рожок мороженого" и следите, чтобы e2e было адекватное количество и они относительно стабильно работали или была четкая документация на случай проблем.
2. Если часто становитесь борцом с такими тестами, как я, то старайтесь выработать универсальный навык траблшутинга и поиска ответственных.
Небольшой лайфхак: если есть возможность посмотреть статистику упавшего теста, то сделайте это сразу. Так вы сможете понять, что он падает не только у вас, а значит, причина падения, скорее всего, не вы и можно с большей уверенностью призывать ответственных, экономя время на поиске проблемы у себя.
@time2code
🚀 Про Big Tech, инженерную культуру, людей и продукты, которые они создают.
Немного про код, мотивацию и саморазвитие, чтобы двигаться к своей мечте.
Меня зовут Александр Новиков, и я инженер, который прошел путь от обыкновенного специалиста до продуктового бекенд-разработчика в настоящем Big Tech.
Я знаю, как сложно выйти за рамки привычного, сколько усилий требуется, чтобы поменять вектор карьеры и шагнуть в неизвестность.
Этот канал - отражение моего профессионального развития и трудностей, с которыми я сталкивался, а также решений, которые помогли их преодолеть.
Несмотря на текущую позицию, мой путь продолжается.
Здесь я делюсь практическим опытом и поднимаю серьезные темы о современной разработке.
Если то, о чем пишу, откликается, буду рад вашим комментариям или реакциям к постам — это мотивирует меня писать больше и помогает понять, что материал полезен.
Путь в Big Tech:
- С какого языка программирования начинать и как решиться на первые шаги (читать)
- Как не потерять мотивацию (читать)
- Где брать идеи для пет-проектов (читать)
- Смена языка программирования (читать)
- Как попасть в компанию уровня Avito (читать)
Избранные посты:
- You are gonna need it (YAGNI v2.0) (читать)
- Как все успевать? (читать)
- Как научиться проектировать систему? И кому это нужно? (читать)
- Подчиняем performance review (читать)
- Мышление письмом (читать)
- Иллюзия простого языка (читать)
- Как расти в Big Tech (читать) и моя рефлексия за два года работы в нем (читать)
- Как я сделал блог на Hugo (читать)
- Возможно ли сохранить отношения после код-ревью? (читать)
-> Сайт
-> GitHub
-> LinkedIn
@time2code — не только про мой опыт, но и про общение. Делитесь своими историями в комментариях или предлагайте идеи для поста в личные сообщения. Давайте обсуждать сложные темы, расширять сеть контактов и учиться друг у друга.
Немного про код, мотивацию и саморазвитие, чтобы двигаться к своей мечте.
Меня зовут Александр Новиков, и я инженер, который прошел путь от обыкновенного специалиста до продуктового бекенд-разработчика в настоящем Big Tech.
Я знаю, как сложно выйти за рамки привычного, сколько усилий требуется, чтобы поменять вектор карьеры и шагнуть в неизвестность.
Этот канал - отражение моего профессионального развития и трудностей, с которыми я сталкивался, а также решений, которые помогли их преодолеть.
Несмотря на текущую позицию, мой путь продолжается.
Здесь я делюсь практическим опытом и поднимаю серьезные темы о современной разработке.
Если то, о чем пишу, откликается, буду рад вашим комментариям или реакциям к постам — это мотивирует меня писать больше и помогает понять, что материал полезен.
Путь в Big Tech:
- С какого языка программирования начинать и как решиться на первые шаги (читать)
- Как не потерять мотивацию (читать)
- Где брать идеи для пет-проектов (читать)
- Смена языка программирования (читать)
- Как попасть в компанию уровня Avito (читать)
Избранные посты:
- You are gonna need it (YAGNI v2.0) (читать)
- Как все успевать? (читать)
- Как научиться проектировать систему? И кому это нужно? (читать)
- Подчиняем performance review (читать)
- Мышление письмом (читать)
- Иллюзия простого языка (читать)
- Как расти в Big Tech (читать) и моя рефлексия за два года работы в нем (читать)
- Как я сделал блог на Hugo (читать)
- Возможно ли сохранить отношения после код-ревью? (читать)
-> Сайт
-> GitHub
@time2code — не только про мой опыт, но и про общение. Делитесь своими историями в комментариях или предлагайте идеи для поста в личные сообщения. Давайте обсуждать сложные темы, расширять сеть контактов и учиться друг у друга.
❤7
Новиков > путь в Big Tech pinned «🚀 Про Big Tech, инженерную культуру, людей и продукты, которые они создают. Немного про код, мотивацию и саморазвитие, чтобы двигаться к своей мечте. Меня зовут Александр Новиков, и я инженер, который прошел путь от обыкновенного специалиста до продуктового…»
Пул-реквест как отражение инженерной культуры
Как отбить желание смотреть ваш пул-реквест? - Вот отличный пример из опен-сор проекта PocketBase: непосредственно ПР.
Конечно, это гипербола, но через крайности объяснять суть всегда нагляднее.
Что мы имеем: изменено 147 файлов, сделан 1 коммит.
Думаю, никто не удивится ответу автора проекта:
"Thank you for spending your time on this but this type of changes are not really welcomed as I don't really see much point of reviewing 140+ files."
Занавес...
Я не раз говорил о важности маленьких шагов: как они помогают достигать целей и побеждать прокрастинацию.
Но сейчас речь пойдет про то, какие изменения за один раз мы деплоим на прод.
В начале года немного рефлексировал на тему атомарности коммитов. Повторюсь: делайте их чаще, делайте их понятными - это значительно упростит работу вам и вашим коллегам.
Никто не спорит: удобно выбрать все изменения и в одном коммите под знаменем "рефактор" отправить на удаленный репозиторий, но это очень темная дорожка и вам не нужно по ней идти.
Если с коммитами все понятно, то с ПР все гораздо интереснее, тут возможны варианты.
Поменялось ли что-нибудь, если изменения в 147 файлах шли не одним, а десятком коммитов в одном ПР-е? - Не думаю.
Когда речь идет про код-ревью - красиво оформленный пул-реквест - это отражение вашей инженерной культуры. Он показывает не только вашу аккуратность в работе, но и уважение к тем, кто будет его смотреть.
Представьте, что вы владелец горизонтального сервиса. У вас полно своих задач, которые нужно успевать делать, но также на вас есть ответственность за стабильность своего сервиса перед клиентами и вы в ответе за то, чтобы вертикальные команды как можно быстрее могли релизить свои изменения независимо от вас, чтобы бизнес мог развиваться, а TTM новых фичей был маленьким.
И тут вам прилетает уведомление: у вас 3 новых пул-реквеста:
ПР 1:
- "Добавляю новые правила валидации, изменяю логику для стораджа и делаю небольшой рефактор"
- 16 коммитов (атомарные, понятные)
- изменено 5 файлов, добавлено 2 (1 для тестов на правила валидации)
ПР 2:
- "Прокидываю клиент для метрик и начинаю писать технические метрики для фичи Отображение на карте"
- 5 коммитов (атомарные, понятные)
- изменено 3 файла, добавлен 1 для тестов
ПР 3:
- "В соответствии с задачей VRT-2231 добавляю новую логику"
- 3 коммита (неатомарные)
- изменено 2 файла, добавлен 1 (без тестов)
Какой из этих вариантов посмотрите в первую очередь? Я бы смотрел так:
2 -> 1 -> 3
Объясню:
1. Сперва описание. Если оно есть и понятное - уже очень хорошо. Но, если на первой же строке вас за дополнительным контекстом отсылают в Джиру, то это тревожный звонок - вероятно, ревью затянется.
2. Если изменения составляют инкремент, как история с метриками во втором ПР, то это явный кандидат на приоритетное ревью. С ним можно быстро разобраться и пойти дальше, позволив понятным изменения быстрее оказаться в проде.
3. С ПР 1 и ПР 3 - интереснее. Начну с первого, так как есть большой шанс, что здесь потребуются доработки и я быстрее смогу дать фидбек ребятам на исправление, так как нужны серьезные причины, чтобы столько всего предлагать в одном ПР-е (почему не разбить на 3?).
4. ПР 3 уходит напоследок, так для погружения в контекст потребуется гораздо больше ресурсов (из описания вообще ничего не понятно).
Если был опыт с код ревью, то переложите ситуацию на себя и напишите, в какой последовательности отсматривали бы ПР-ы или ставьте реакцию, если вариант получился такой же.
Конечно, на практике не все идеально и ожидание код-ревью действительно может стать бутылочным горлышком.
Признаюсь, что и мне приходилось делать один большой ПР, так за спринт не всегда есть возможность успеть пройти ревью по несколько раз (особенно, если это крупная фича, а ревью проходит очень медленно). Но я всегда подробно объясняю что делаю и зачем.
В наших силах проявлять инженерную культуру и уважение к коллегам, организуя ПР-ы таким образом, чтобы они были максимально атомарными и понятные для ревьюеров.
@time2code
Как отбить желание смотреть ваш пул-реквест? - Вот отличный пример из опен-сор проекта PocketBase: непосредственно ПР.
Конечно, это гипербола, но через крайности объяснять суть всегда нагляднее.
Что мы имеем: изменено 147 файлов, сделан 1 коммит.
Думаю, никто не удивится ответу автора проекта:
"Thank you for spending your time on this but this type of changes are not really welcomed as I don't really see much point of reviewing 140+ files."
Занавес...
Я не раз говорил о важности маленьких шагов: как они помогают достигать целей и побеждать прокрастинацию.
Но сейчас речь пойдет про то, какие изменения за один раз мы деплоим на прод.
В начале года немного рефлексировал на тему атомарности коммитов. Повторюсь: делайте их чаще, делайте их понятными - это значительно упростит работу вам и вашим коллегам.
Никто не спорит: удобно выбрать все изменения и в одном коммите под знаменем "рефактор" отправить на удаленный репозиторий, но это очень темная дорожка и вам не нужно по ней идти.
Если с коммитами все понятно, то с ПР все гораздо интереснее, тут возможны варианты.
Поменялось ли что-нибудь, если изменения в 147 файлах шли не одним, а десятком коммитов в одном ПР-е? - Не думаю.
Когда речь идет про код-ревью - красиво оформленный пул-реквест - это отражение вашей инженерной культуры. Он показывает не только вашу аккуратность в работе, но и уважение к тем, кто будет его смотреть.
Представьте, что вы владелец горизонтального сервиса. У вас полно своих задач, которые нужно успевать делать, но также на вас есть ответственность за стабильность своего сервиса перед клиентами и вы в ответе за то, чтобы вертикальные команды как можно быстрее могли релизить свои изменения независимо от вас, чтобы бизнес мог развиваться, а TTM новых фичей был маленьким.
И тут вам прилетает уведомление: у вас 3 новых пул-реквеста:
ПР 1:
- "Добавляю новые правила валидации, изменяю логику для стораджа и делаю небольшой рефактор"
- 16 коммитов (атомарные, понятные)
- изменено 5 файлов, добавлено 2 (1 для тестов на правила валидации)
ПР 2:
- "Прокидываю клиент для метрик и начинаю писать технические метрики для фичи Отображение на карте"
- 5 коммитов (атомарные, понятные)
- изменено 3 файла, добавлен 1 для тестов
ПР 3:
- "В соответствии с задачей VRT-2231 добавляю новую логику"
- 3 коммита (неатомарные)
- изменено 2 файла, добавлен 1 (без тестов)
Какой из этих вариантов посмотрите в первую очередь? Я бы смотрел так:
Объясню:
1. Сперва описание. Если оно есть и понятное - уже очень хорошо. Но, если на первой же строке вас за дополнительным контекстом отсылают в Джиру, то это тревожный звонок - вероятно, ревью затянется.
2. Если изменения составляют инкремент, как история с метриками во втором ПР, то это явный кандидат на приоритетное ревью. С ним можно быстро разобраться и пойти дальше, позволив понятным изменения быстрее оказаться в проде.
3. С ПР 1 и ПР 3 - интереснее. Начну с первого, так как есть большой шанс, что здесь потребуются доработки и я быстрее смогу дать фидбек ребятам на исправление, так как нужны серьезные причины, чтобы столько всего предлагать в одном ПР-е (почему не разбить на 3?).
4. ПР 3 уходит напоследок, так для погружения в контекст потребуется гораздо больше ресурсов (из описания вообще ничего не понятно).
Если был опыт с код ревью, то переложите ситуацию на себя и напишите, в какой последовательности отсматривали бы ПР-ы или ставьте реакцию, если вариант получился такой же.
Конечно, на практике не все идеально и ожидание код-ревью действительно может стать бутылочным горлышком.
Признаюсь, что и мне приходилось делать один большой ПР, так за спринт не всегда есть возможность успеть пройти ревью по несколько раз (особенно, если это крупная фича, а ревью проходит очень медленно). Но я всегда подробно объясняю что делаю и зачем.
В наших силах проявлять инженерную культуру и уважение к коллегам, организуя ПР-ы таким образом, чтобы они были максимально атомарными и понятные для ревьюеров.
@time2code
🔥5👍1
Продай мне эту ручку систему. Неожиданные инсайты System Design
В студенческие годы, когда я работал рекламным агентом в образовательном центре, я изучал техники продаж и психологию человека на разных этапах его развития.
Я ничего не продавал в классическом смысле этого слова, моя цель заключалась в другом. Как в фильме "Начало", мне нужно было подселить идею, которая затем преобразовывалась в интерес к посещению профильного мероприятия, что вело к потенциальной покупке образовательных курсов.
Основная особенность такой деятельности была в том, что необходимо было подстраиваться под аудиторию, которая состояла из школьников различных возрастов. Для каждого класса подходила своя идея, так как очевидно потребности у человека в третьем и в десятом классе различаются.
И в этом главная техника продаж: сперва вы должны понять нужды и ценности клиента, а затем спроецировать предлагаемое решение и продукт на них.
Здесь можно увидеть, как автор популярной фразы - Джордан Белфорт - "продает" ручку, подробно объясняя всю суть упражнения.
Основная ошибка - пытаться продать любой ценой, не понимая цели.
То же самое касается System Design на интервью: не нужно сразу бросаться рисовать систему и защищать свое решение, которое пришло вам в голову, любой ценой. Секция проектирование не про это.
На днях я завершил книгу автора Алекс Сюй System Design "Подготовка к сложному интервью".
Основная задумка книги - не дать сборник готовых решений, которые нужно переносить на практику As Is, а предоставить фреймворк, освоив который, можно пройти любое интервью по проектированию.
Предлагается следующий алгоритм:
Шаг 1: Понять задачу и определить масштаб решения
Шаг 2: Предложить общее решение и получить согласие
Шаг 3: Подробное проектирование
Шаг 4: Подведение итогов
Алгоритм хороший, но важно его не зубрить, а уловить суть, которая сводится к тому, что во время собеседования важно построить диалог с интервьюером:
- понять конкретную задачу, исходя из запроса и потребностей, зафиксировав все вводные и возможные допущения, на которых будет строиться решение
- предложить черновой вариант, тем самым формально утвердив концепцию
- начать оптимизировать, обсуждая потенциально слабые места и возможности для улучшений
Интересно, но параллельно с моим чтением книги этой осенью Алексей Рыбак с экспертами разбирали некоторые главы из этой книги. Вот ссылка на обзор главы "Проектирование хранилища типа “ключ-значение” - рекомендую ознакомиться, если хотите углубиться в тему.
Запомнить: секция «проектирование» на собеседовании - это про диалог.
Воспринимайте это как продажу ручки: поймите потребности клиента и предложите решение, которое их может закрыть.
@time2code
В студенческие годы, когда я работал рекламным агентом в образовательном центре, я изучал техники продаж и психологию человека на разных этапах его развития.
Я ничего не продавал в классическом смысле этого слова, моя цель заключалась в другом. Как в фильме "Начало", мне нужно было подселить идею, которая затем преобразовывалась в интерес к посещению профильного мероприятия, что вело к потенциальной покупке образовательных курсов.
Основная особенность такой деятельности была в том, что необходимо было подстраиваться под аудиторию, которая состояла из школьников различных возрастов. Для каждого класса подходила своя идея, так как очевидно потребности у человека в третьем и в десятом классе различаются.
И в этом главная техника продаж: сперва вы должны понять нужды и ценности клиента, а затем спроецировать предлагаемое решение и продукт на них.
Здесь можно увидеть, как автор популярной фразы - Джордан Белфорт - "продает" ручку, подробно объясняя всю суть упражнения.
Основная ошибка - пытаться продать любой ценой, не понимая цели.
То же самое касается System Design на интервью: не нужно сразу бросаться рисовать систему и защищать свое решение, которое пришло вам в голову, любой ценой. Секция проектирование не про это.
На днях я завершил книгу автора Алекс Сюй System Design "Подготовка к сложному интервью".
Основная задумка книги - не дать сборник готовых решений, которые нужно переносить на практику As Is, а предоставить фреймворк, освоив который, можно пройти любое интервью по проектированию.
Предлагается следующий алгоритм:
Шаг 1: Понять задачу и определить масштаб решения
Шаг 2: Предложить общее решение и получить согласие
Шаг 3: Подробное проектирование
Шаг 4: Подведение итогов
Алгоритм хороший, но важно его не зубрить, а уловить суть, которая сводится к тому, что во время собеседования важно построить диалог с интервьюером:
- понять конкретную задачу, исходя из запроса и потребностей, зафиксировав все вводные и возможные допущения, на которых будет строиться решение
- предложить черновой вариант, тем самым формально утвердив концепцию
- начать оптимизировать, обсуждая потенциально слабые места и возможности для улучшений
Интересно, но параллельно с моим чтением книги этой осенью Алексей Рыбак с экспертами разбирали некоторые главы из этой книги. Вот ссылка на обзор главы "Проектирование хранилища типа “ключ-значение” - рекомендую ознакомиться, если хотите углубиться в тему.
Запомнить: секция «проектирование» на собеседовании - это про диалог.
Воспринимайте это как продажу ручки: поймите потребности клиента и предложите решение, которое их может закрыть.
@time2code
👍6
Ноябрь 2024:
развитие
✔️ Завершил внутренний курс по обучению инженерной культуре. Изучил темы: паттерны проектирования (observability, асинхронный обмен, проектирование стабильного API и другие), продуктовая аналитика (включая архитектуру корпоративного Data Warehouse) и модуль по эффективной фасилитации встреч.
✔️ Приступил к изучению
F# в рамках обучения ФП.
✔️ Прочитал книгу по System Design «Подготовка к сложному интервью».
✔️ Разобрал паттерн “Декоратор” на Go.
✔️ Стал ментором нового инженера из соседней команды на период его онбординга.
прочее
✔️ Написал 5-ый пост в LinkedIn.
✔️ Обновил закреп канала.
✔️ Запустил для себя челлендж, в котором на каждой из недель (оставшихся до НГ) делаю рывок в направлении закрытия годовых целей.
посты
🔖 Возможно ли сохранить отношения после код-ревью (читать)
🔖 Готовимся к фичафризу и закрываем цели (читать)
🔖 Как не уронить свою пирамиду тестирования (читать)
🔖 Пул-реквест как отражение инженерной культуры (читать)
🔖 Неожиданные инсайты System Design (читать)
#результаты
развитие
✔️ Завершил внутренний курс по обучению инженерной культуре. Изучил темы: паттерны проектирования (observability, асинхронный обмен, проектирование стабильного API и другие), продуктовая аналитика (включая архитектуру корпоративного Data Warehouse) и модуль по эффективной фасилитации встреч.
✔️ Приступил к изучению
F# в рамках обучения ФП.
✔️ Прочитал книгу по System Design «Подготовка к сложному интервью».
✔️ Разобрал паттерн “Декоратор” на Go.
✔️ Стал ментором нового инженера из соседней команды на период его онбординга.
прочее
✔️ Написал 5-ый пост в LinkedIn.
✔️ Обновил закреп канала.
✔️ Запустил для себя челлендж, в котором на каждой из недель (оставшихся до НГ) делаю рывок в направлении закрытия годовых целей.
посты
🔖 Возможно ли сохранить отношения после код-ревью (читать)
🔖 Готовимся к фичафризу и закрываем цели (читать)
🔖 Как не уронить свою пирамиду тестирования (читать)
🔖 Пул-реквест как отражение инженерной культуры (читать)
🔖 Неожиданные инсайты System Design (читать)
#результаты
👍1
Кто такой Senior?
Когда еще не занимался программированием, а лишь наблюдал со стороны, то популярные IT-градации: junior, middle, senior - воспринимались совершенно иначе, чем сейчас.
И если с начальными грейдами относительно просто, то определить в какой момент человек становится синьором достаточно сложно.
Для визуализации сравнил грейды международных Big Tech-компаний.
Фиолетовой полоской обозначил диапазон минимального и максимального уровня «синьорности» (источник).
На примере Авито могу сказать, что картинка получилась правдивая. Подробнее про грейды и их соответствие классической схеме разбирал в посте.
Вообще это все условности, чтобы усреднить роли на рынке и соискателям с рекрутерами было бы проще находить пересечения.
Далее посмотрим на то, по каким компетенциям реально можно определить грейд.
А пока - предлагаю каждому ответить на вопрос: как вы определяете, кто такой senior?
@time2code
Когда еще не занимался программированием, а лишь наблюдал со стороны, то популярные IT-градации: junior, middle, senior - воспринимались совершенно иначе, чем сейчас.
И если с начальными грейдами относительно просто, то определить в какой момент человек становится синьором достаточно сложно.
Для визуализации сравнил грейды международных Big Tech-компаний.
Фиолетовой полоской обозначил диапазон минимального и максимального уровня «синьорности» (источник).
На примере Авито могу сказать, что картинка получилась правдивая. Подробнее про грейды и их соответствие классической схеме разбирал в посте.
Вообще это все условности, чтобы усреднить роли на рынке и соискателям с рекрутерами было бы проще находить пересечения.
Далее посмотрим на то, по каким компетенциям реально можно определить грейд.
А пока - предлагаю каждому ответить на вопрос: как вы определяете, кто такой senior?
@time2code
👍1
Хочешь стать Senior инженером? Начни с мышления.
Я много думал на эту тему.
Раньше у меня были ожидания, что такой специалист пишет «неземной» код и делает это быстро. Он способен решить сложную задачу и знает ответ на любой вопрос в своей области.
Конечно, это преувеличение, но такое было направление мысли.
Со временем, когда я стал чаще пересекаться с инженерами такого уровня или даже выше, я понял, что код они могут писать также долго, как и джуны, и у них, очевидно, нет ответа на любой вопрос.
И это абсолютно нормально.
Во-первых, производительность в IT нельзя определять исключительно скоростью работы, то есть количеством строк кода в единицу времени.
А во-вторых, с учетом активно развивающей отрасли, когда объем новых знаний растет экспоненциально, абсолютного знания быть не может.
❓Так в чем же все-таки их отличие?
Синьор разработчик оперирует гораздо большим контекстом.
Приведу пример: нужно добавить зависимость от нового признака - другими словами, просто еще один if, не больше, ни меньше.
Мышление не синьора:
- где написать код
- проверить работоспособность
- написать юнит-тест на новую логику (в лучшем случае)
- обновить документацию (в идеальном случае)
💪 Мышление синьора:
- за что отвечает новый if: в какие продуктовые метрики целимся
- насколько это важный функционал, нужно ли предусматривать graceful degradation в нештатных ситуациях
- правильно ли это делать на уровне потенциально рассматриваемого сервиса
- уведомлены ли владельцы сервиса или домена, где происходят изменения, о новом функционале (если нет - сначала согласовать)
- увеличится ли нагрузка на сервис или связанные с ним системы (если да - сначала согласовать)
- какие есть ограничения мобильных клиентов (есть ли завязка на версию приложения и пр.)
- какими техническими метриками нужно покрыть код
- какие логи нужно собирать
- нужна ли аналитика
- (. . .)
- и только затем 4 пункта: где написать код и т.д.
Конечно, по факту решение может быть абсолютно таким же (код в каких-то местах может быть даже хуже).
Но на высоком уровне мы видим, что первый подход исключительно решает только проблему, мало задумываясь о том как новый код будет жить после деплоя, а вот второе - помогает на стратегическом уровне заглянуть вперед, подстраховать себя и соседние команды при добавлении нового функционала и обеспечить более спокойное будущее, зная, что мы многое уже продумали и предусмотрели.
Про разницу грейдов легко думать в следующем ключе: обычный разработчик декомпозирует задачи, синьор - декомпозирует проблемы.
Поэтому здесь речь не про харды, а про то, на каком уровне абстракции инженер рассматривает задачу, какие связи и зависимости он видит от вносимых изменений.
Конечно, за 15 секунд мышление не перестроить, даже если подглядывать в этот пост. Это долгая работа над собой, это приходит с опытом.
@time2code
Я много думал на эту тему.
Раньше у меня были ожидания, что такой специалист пишет «неземной» код и делает это быстро. Он способен решить сложную задачу и знает ответ на любой вопрос в своей области.
Конечно, это преувеличение, но такое было направление мысли.
Со временем, когда я стал чаще пересекаться с инженерами такого уровня или даже выше, я понял, что код они могут писать также долго, как и джуны, и у них, очевидно, нет ответа на любой вопрос.
И это абсолютно нормально.
Во-первых, производительность в IT нельзя определять исключительно скоростью работы, то есть количеством строк кода в единицу времени.
А во-вторых, с учетом активно развивающей отрасли, когда объем новых знаний растет экспоненциально, абсолютного знания быть не может.
❓Так в чем же все-таки их отличие?
Синьор разработчик оперирует гораздо большим контекстом.
Приведу пример: нужно добавить зависимость от нового признака - другими словами, просто еще один if, не больше, ни меньше.
Мышление не синьора:
- где написать код
- проверить работоспособность
- написать юнит-тест на новую логику (в лучшем случае)
- обновить документацию (в идеальном случае)
💪 Мышление синьора:
- за что отвечает новый if: в какие продуктовые метрики целимся
- насколько это важный функционал, нужно ли предусматривать graceful degradation в нештатных ситуациях
- правильно ли это делать на уровне потенциально рассматриваемого сервиса
- уведомлены ли владельцы сервиса или домена, где происходят изменения, о новом функционале (если нет - сначала согласовать)
- увеличится ли нагрузка на сервис или связанные с ним системы (если да - сначала согласовать)
- какие есть ограничения мобильных клиентов (есть ли завязка на версию приложения и пр.)
- какими техническими метриками нужно покрыть код
- какие логи нужно собирать
- нужна ли аналитика
- (. . .)
- и только затем 4 пункта: где написать код и т.д.
Конечно, по факту решение может быть абсолютно таким же (код в каких-то местах может быть даже хуже).
Но на высоком уровне мы видим, что первый подход исключительно решает только проблему, мало задумываясь о том как новый код будет жить после деплоя, а вот второе - помогает на стратегическом уровне заглянуть вперед, подстраховать себя и соседние команды при добавлении нового функционала и обеспечить более спокойное будущее, зная, что мы многое уже продумали и предусмотрели.
Про разницу грейдов легко думать в следующем ключе: обычный разработчик декомпозирует задачи, синьор - декомпозирует проблемы.
Поэтому здесь речь не про харды, а про то, на каком уровне абстракции инженер рассматривает задачу, какие связи и зависимости он видит от вносимых изменений.
Конечно, за 15 секунд мышление не перестроить, даже если подглядывать в этот пост. Это долгая работа над собой, это приходит с опытом.
@time2code
👍10🔥1
Цена невнимательности в высоконагруженной системе
Биг Тех - это не только сильная инженерная культура и хорошо выстроенные процессы, но и высокие нагрузки - так называемый high load.
С одной стороны, это очень удобно: задеплоил новую фичу и сразу можно заметить изменения на метриках. Но с другой - любая ошибка может стоить компании денег, а разработчику нервов, потраченных на починку в авральном режиме.
В Авито есть Metadata management system или как ее называют внутри - "Инфомодель" (далее буду называть ИМ). Подробнее можно послушать в докладе.
Система довольно интересная, но сопряжена с различными нюансами работы. Мне потребовалось не менее года, чтобы стать ее уверенным пользователем. И проблема здесь не в сложности системы как таковой, а во множестве связей между метаданными, из-за которых очень легко ошибиться, а любая ошибка сразу приводит к багам и нежелательному поведению на проде.
Пару недель назад произошел интересный случай. В ходе решения одной из задач мне потребовалось сделать изменения в ИМ - добавить скрытый и необязательный атрибут. Делается это довольно быстро, есть удобная админка для таких сценариев.
Но в скором времени я понял, что такая реализация будет неоптимальна, поэтому было принято решение свои изменения откатить и сделать иначе.
После отката первой реализации и релиза новых изменений с успехом закрываю задачу и переключаюсь на другие.
Вдруг - прилетает новое обращение от пользователя связанное с ошибкой при подаче объявления.
В ходе быстрого расследования становится ясно, что необязательный атрибут, который был на небольшое время раскатан, а потом удален - сохранился у пользователя в объявлении и стал причиной его проблем.
Стали обсуждать с командой, которая поддерживает ИМ, и выясняется, что они сами впервые слышат, что такое возможно. Необязательные атрибуты никак не должны ломать функционал.
Чтобы не делать серию постов про еще одно расследование бага, перейду сразу к сути.
Оказалось, что один из самых важных микросервисов в компании валидирует необязательные параметры и при их отсутствии в спецификации получаемой от ИМ, приводит к сломанной функциональности и не работающего сценария пользователя.
Для чего так было сделано? - Вопрос. Но есть подозрение, что неспроста и, видимо, обо что-то уже обжигались коллеги.
В любом случае хорошо бы такое поведение задокументировать и явно подсвечивать в ключевом микросервисе и непосредственно при работе с ИМ, так как за последний месяц, судя по каналу с проблемами, не я один столкнулся с этим.
Какой итог?
Чтобы исправить все последствия вызванные моим откатом, мне пришлось просить аналитика составить таблицу всех задетых объявлений, которых за короткое время оказалось не мало. А затем создавать миграцию с принудительным обновлением объявлений и ожидать ее завершения (к счастью, у нас есть удобный инструмент для этого).
Таким образом, одно неаккуратное действие, на которое я затратил менее 15 минут времени, стоило мне проблем, на разрешение которых я потратил ощутимый ресурс.
Конечно, я получил ценный опыт по работе незадокументированного поведения сервиса и научился работать с инструментом миграций, но этот случай очередной раз показал какова может быть цена ошибки и как важно быть внимательным, особенно когда работаем с высокими нагрузками.
@time2code
Биг Тех - это не только сильная инженерная культура и хорошо выстроенные процессы, но и высокие нагрузки - так называемый high load.
С одной стороны, это очень удобно: задеплоил новую фичу и сразу можно заметить изменения на метриках. Но с другой - любая ошибка может стоить компании денег, а разработчику нервов, потраченных на починку в авральном режиме.
В Авито есть Metadata management system или как ее называют внутри - "Инфомодель" (далее буду называть ИМ). Подробнее можно послушать в докладе.
Система довольно интересная, но сопряжена с различными нюансами работы. Мне потребовалось не менее года, чтобы стать ее уверенным пользователем. И проблема здесь не в сложности системы как таковой, а во множестве связей между метаданными, из-за которых очень легко ошибиться, а любая ошибка сразу приводит к багам и нежелательному поведению на проде.
Пару недель назад произошел интересный случай. В ходе решения одной из задач мне потребовалось сделать изменения в ИМ - добавить скрытый и необязательный атрибут. Делается это довольно быстро, есть удобная админка для таких сценариев.
Но в скором времени я понял, что такая реализация будет неоптимальна, поэтому было принято решение свои изменения откатить и сделать иначе.
После отката первой реализации и релиза новых изменений с успехом закрываю задачу и переключаюсь на другие.
Вдруг - прилетает новое обращение от пользователя связанное с ошибкой при подаче объявления.
В ходе быстрого расследования становится ясно, что необязательный атрибут, который был на небольшое время раскатан, а потом удален - сохранился у пользователя в объявлении и стал причиной его проблем.
Стали обсуждать с командой, которая поддерживает ИМ, и выясняется, что они сами впервые слышат, что такое возможно. Необязательные атрибуты никак не должны ломать функционал.
Чтобы не делать серию постов про еще одно расследование бага, перейду сразу к сути.
Оказалось, что один из самых важных микросервисов в компании валидирует необязательные параметры и при их отсутствии в спецификации получаемой от ИМ, приводит к сломанной функциональности и не работающего сценария пользователя.
Для чего так было сделано? - Вопрос. Но есть подозрение, что неспроста и, видимо, обо что-то уже обжигались коллеги.
В любом случае хорошо бы такое поведение задокументировать и явно подсвечивать в ключевом микросервисе и непосредственно при работе с ИМ, так как за последний месяц, судя по каналу с проблемами, не я один столкнулся с этим.
Какой итог?
Чтобы исправить все последствия вызванные моим откатом, мне пришлось просить аналитика составить таблицу всех задетых объявлений, которых за короткое время оказалось не мало. А затем создавать миграцию с принудительным обновлением объявлений и ожидать ее завершения (к счастью, у нас есть удобный инструмент для этого).
Таким образом, одно неаккуратное действие, на которое я затратил менее 15 минут времени, стоило мне проблем, на разрешение которых я потратил ощутимый ресурс.
Конечно, я получил ценный опыт по работе незадокументированного поведения сервиса и научился работать с инструментом миграций, но этот случай очередной раз показал какова может быть цена ошибки и как важно быть внимательным, особенно когда работаем с высокими нагрузками.
@time2code
👍7
Мощная привычка, которая отличает опытных разработчиков
Самый ценный совет, который я получил в начале карьеры программиста: пишите юнит-тесты.
У многих неопытных разработчиков требование написать их вызывает прокрастинацию или скуку.
Я до сих пор иногда ленюсь, но все равно делаю это. И тут речь не про то, что в Авито для бэкенд-разработчика написание юнитов на свою логику считается в большинстве случаев необходимым требованием, чтобы тебе одобрили пул-реквест, но больше про то, что я реально понимаю ценность этого.
✍️ Почему важно писать юнит-тесты:
1. Фактически это гарант того, что основные кейсы, на которые вы написали юниты, работают, и ваш QA, опираясь на них, сможет сузить скоуп тестирования и больше уделить внимания сложным краевым случаям.
2. С вероятностью 90% после написания тестов вы так или иначе сделаете фикс в свою бизнес-логику: где-то пропустили проверку на нулевой указатель, где-то забыли обработать ошибку, где-то вышли за предел массива при случайном наборе данных, а может элементарно вы что-то не учли или после тестов поняли, что лучше будет добавить еще один слой абстракции.
3. Это сильно поможет в поддержке большой кодовой базы. Например, когда над проектом работает множество команд, то нет ничего проще, чем случайно задеть чье-то незадокументированное поведение. Если будут написаны юнит-тесты, то вы это сразу заметите при очередном прогоне линтера (он должен быть настроен и каждый раз прогоняться на CI/CD).
4. Еще это помогает рефакторить. Мне, например, очень сложно будет решиться сесть за рефакторинг какой-либо логики, если не будет юнитов (отталкиваемся от того, что тесты качественно написаны).
На код-ревью я всегда обращаю внимание на наличие юнит-тестов. Если их нет, то я не понимаю протестировал ли автор свой код.
Просите покрывать новую логику тестами или обсудите почему это нельзя сделать в моменте, обращая внимание на общую сложность тестирования функций (возможно проблема в коде, что его невозможно легко протестировать, что уже говорит о его запахе).
Пункт #2 у меня появился неспроста - это фактически отражение моей практики.
Буквально на прошлой задаче, когда у меня был готов ПР и одобрен оунером сервиса, я заметил, что не написал юнит-тесты на определенную часть логики предназначенной для одной платформы.
В итоге я потратил дополнительный час на тесты, в ходе которого заметил баг, влияющий на функционал при определенных условиях на десктопе. Это был корнер кейс, который было бы невероятно сложно отловить в ходе ручного тестирования (QA был явно доволен).
Вот так простая привычка писать тесты и беспокойство по их отсутствию помогли нашей команде избежать неприятного бага в будущем, на траблшутинг которого потребовалось бы явно больше времени, чем час затраченный на тесты + финальные правки.
Я не просто называю это привычкой, так как навык по написанию тестов на свой код должен стать именно ей. Со временем это будет частью вашей культуры, которую вы начнете транслировать более молодым инженерам и не заметите, как ваша кодовая база значительно прибавила в качестве.
💪 Как можно выработать эту привычку?
В IDE можно настроить code coverage. Но он может раздражать.
У меня нередко были ситуации, когда я не мог пройти линтер в сервисе, получая предостережение:
Low code coverage: 90.0 < 90.0
Возможно, порог в 90% покрытия тестами избыточен, но 70% - это адекватный минимум, который должен быть.
По существу здесь работают все те же правила, что и с другими полезными привычками. Конкретно я как-то специально ее не прививал и не вел трекер с 21 днем... я просто себя заставлял это делать регулярно, начиная с первых дней в профессии.
Поверьте, когда вы в ходе написания юнит-тестов пару раз найдете несколько стыдных ошибок, то будете настолько счастливы, что они не попали в прод или даже не ревью, что это автоматически превратится в привычку.
@time2code
Самый ценный совет, который я получил в начале карьеры программиста: пишите юнит-тесты.
У многих неопытных разработчиков требование написать их вызывает прокрастинацию или скуку.
Я до сих пор иногда ленюсь, но все равно делаю это. И тут речь не про то, что в Авито для бэкенд-разработчика написание юнитов на свою логику считается в большинстве случаев необходимым требованием, чтобы тебе одобрили пул-реквест, но больше про то, что я реально понимаю ценность этого.
✍️ Почему важно писать юнит-тесты:
1. Фактически это гарант того, что основные кейсы, на которые вы написали юниты, работают, и ваш QA, опираясь на них, сможет сузить скоуп тестирования и больше уделить внимания сложным краевым случаям.
2. С вероятностью 90% после написания тестов вы так или иначе сделаете фикс в свою бизнес-логику: где-то пропустили проверку на нулевой указатель, где-то забыли обработать ошибку, где-то вышли за предел массива при случайном наборе данных, а может элементарно вы что-то не учли или после тестов поняли, что лучше будет добавить еще один слой абстракции.
3. Это сильно поможет в поддержке большой кодовой базы. Например, когда над проектом работает множество команд, то нет ничего проще, чем случайно задеть чье-то незадокументированное поведение. Если будут написаны юнит-тесты, то вы это сразу заметите при очередном прогоне линтера (он должен быть настроен и каждый раз прогоняться на CI/CD).
4. Еще это помогает рефакторить. Мне, например, очень сложно будет решиться сесть за рефакторинг какой-либо логики, если не будет юнитов (отталкиваемся от того, что тесты качественно написаны).
На код-ревью я всегда обращаю внимание на наличие юнит-тестов. Если их нет, то я не понимаю протестировал ли автор свой код.
Просите покрывать новую логику тестами или обсудите почему это нельзя сделать в моменте, обращая внимание на общую сложность тестирования функций (возможно проблема в коде, что его невозможно легко протестировать, что уже говорит о его запахе).
Пункт #2 у меня появился неспроста - это фактически отражение моей практики.
Буквально на прошлой задаче, когда у меня был готов ПР и одобрен оунером сервиса, я заметил, что не написал юнит-тесты на определенную часть логики предназначенной для одной платформы.
В итоге я потратил дополнительный час на тесты, в ходе которого заметил баг, влияющий на функционал при определенных условиях на десктопе. Это был корнер кейс, который было бы невероятно сложно отловить в ходе ручного тестирования (QA был явно доволен).
Вот так простая привычка писать тесты и беспокойство по их отсутствию помогли нашей команде избежать неприятного бага в будущем, на траблшутинг которого потребовалось бы явно больше времени, чем час затраченный на тесты + финальные правки.
Я не просто называю это привычкой, так как навык по написанию тестов на свой код должен стать именно ей. Со временем это будет частью вашей культуры, которую вы начнете транслировать более молодым инженерам и не заметите, как ваша кодовая база значительно прибавила в качестве.
💪 Как можно выработать эту привычку?
В IDE можно настроить code coverage. Но он может раздражать.
У меня нередко были ситуации, когда я не мог пройти линтер в сервисе, получая предостережение:
Low code coverage: 90.0 < 90.0
Возможно, порог в 90% покрытия тестами избыточен, но 70% - это адекватный минимум, который должен быть.
По существу здесь работают все те же правила, что и с другими полезными привычками. Конкретно я как-то специально ее не прививал и не вел трекер с 21 днем... я просто себя заставлял это делать регулярно, начиная с первых дней в профессии.
Поверьте, когда вы в ходе написания юнит-тестов пару раз найдете несколько стыдных ошибок, то будете настолько счастливы, что они не попали в прод или даже не ревью, что это автоматически превратится в привычку.
@time2code
👍7