Владимир Балун
7.54K subscribers
413 photos
46 videos
434 links
Канал Балун Владимира - C++/Go разработчика из BigTech. Здесь вы найдете глубокие знания и материалы по программированию, личные истории и лайв-контент.

Сотрудничество: @vladimir_balun
Download Telegram
Открытый урок «Основы облачных технологий»

• 26 марта, ЧТ
• 19:00 по мск

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

Что будет на уроке:
1. Внутренне устройство любого облака
2. IaaS, PaaS и SaaS – какую модель выбрать, чтобы не переплачивать и не усложнять архитектуру
3. Когда стоит мигрировать в облако, а когда лучше остаться «на земле»
4. Основные преимущества облачных технологий – где надежнее и почему

Рассказывает Илья Смирнов, архитектор решений Cloud.ru

Запись будет для всех, кто зарегистрировался на урок, а записать на урок можно по ссылке: https://clck.ru/3ShuUL

Кто я | Навигация | Спасибо
8👍6🔥5
📹 Записал видео о том, как оптимизации часто усложняют код, увеличивают количество багов и в итоге замедляют разработку, а не ускоряют ее.

Разобрал:
- почему мы попадаем в локальный оптимум
- как преждевременная оптимизация ломает архитектуру
- и почему простой код часто выигрывает

Посмотреть видео можно по ссылке: https://youtu.be/y4z4rfPF6zM

Кто я | Навигация | Спасибо
1👍23🔥752💯1
🧩 panic / recover vs exceptions - что происходит под капотом и почему это две разные модели

Снаружи кажется, что panic в Go и exceptions в языках вроде C++ или Java делают одно и то же: что-то пошло не так, стек раскрутился, где-то это поймали. Но если посмотреть внутрь, различия довольно фундаментальные и они напрямую отражают философию языков.

Начнем с Go. Когда вызывается panic, начинается stack unwinding - раскрутка стека. Но в Go она жестко завязана на defer. На каждом фрейме функции рантайм проверяет, есть ли отложенные вызовы, и начинает выполнять их в обратном порядке. Это не какая-то “магия компилятора” - это реальный исполняемый код, который вызывается рантаймом. Важный момент: defer - это часть обычного control flow. Даже с современными оптимизациями, это все еще логика, встроенная в выполнение функции. Поэтому unwind в Go - это процесс, где на каждом шаге реально выполняются функции, могут происходить аллокации, переходы в рантайм и так далее. Если внутри defer вызывается recover(), паника останавливается, и выполнение продолжается как будто ничего не произошло.

Теперь посмотрим на exceptions. Здесь есть две принципиально разные модели, но наиболее интересная - это zero-cost exceptions, которая используется, например, в C++. Ее ключевая идея в том, что пока исключения не происходят, программа вообще не платит за их существование. Как это достигается: компилятор заранее генерирует специальные таблицы (unwind tables), в которых описано, как раскручивать стек, где находятся catch-блоки и какие деструкторы нужно вызвать. Эти таблицы лежат рядом с кодом, но во время обычного выполнения никак не используются. Никаких дополнительных структур, регистраций или проверок в рантайме не происходит. Когда происходит throw, включается совсем другой, дорогой путь. Рантайм начинает использовать эти таблицы, чтобы пройти по стеку, найти нужный обработчик и корректно выполнить все деструкторы. Это сложная операция, но она происходит только в момент ошибки. Поэтому модель и называется zero-cost - потому что в обычном пути стоимость почти нулевая.

📌 Если сравнить это с Go, разница становится очевидной. В Go нет отдельного слоя unwind-таблиц и нет “ленивой” модели. defer регистрируется и учитывается во время выполнения, panic обрабатывается рантаймом, и unwind - это часть обычного исполнения программы. Даже если defer оптимизирован и заинлайнен, все равно остаются проверки и логика, встроенная в код. И еще один интересный момент - стоимость в худшем случае. В zero-cost модели обычный путь бесплатный, но throw - очень дорогой. В Go стоимость более “размазана”: нет почти бесплатного happy path, но и нет резкого скачка сложности при panic. Модель более равномерная и предсказуемая.

Теперь главный вопрос - почему в Go вообще нет exceptions.

Думаю, что это не ограничение, а осознанный дизайн:
Первая причина - явность. В Go ошибки - это значения, и ты их обрабатываешь явно через err != nil. Это делает поток выполнения предсказуемым. В случае с exceptions управление может “прыгнуть” через несколько уровней вызовов, и чтобы понять поведение функции, нужно знать, какие исключения она может бросить. Это усложняет чтение и сопровождение кода.
Вторая причина - сложность реализации. Zero-cost exceptions требуют тесной интеграции компилятора и поддержки unwind-таблиц, а также платформозависимой логики. Go изначально делал ставку на простой и переносимый рантайм, без таких сложных механизмов.

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

Кто я | Навигация | Спасибо
1👍38🔥1312
🚀Разбор задач с Go-собеседований

📅 30 марта в 19:00 по МСК пройдет бесплатный открытый урок от Senior Golang-разработчика Алексея Бакина!

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

На открытом уроке узнаешь:
- Типичные ловушки Go и как объяснить их интервьюеру - замыкания в горутинах, nil-интерфейсы, поведение слайсов;
- Как писать безопасный конкурентный код с sync.Mutex, atomic и каналами, и понимать, когда и что применять;
- Как объяснять решения, чтобы произвести впечатление даже при неточном ответе;
- Ожидания интервьюеров на Junior / Middle-грейды, и на что делать упор при подготовке.

📌 Запись будет для всех зарегистрировавшихся, а зарегистрироваться на открытый урок можно по ссылке: https://clck.ru/3SnsxX

Кто я | Навигация | Спасибо
👍183🔥3
💭 Два дня был на офлайн-тренинге по менеджменту у Александра Фридмана

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

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

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

Теперь главное - не оставить это на уровне идей и мыслей, а начать внедрять 😅

Кто я | Навигация | Спасибо
👍31🔥155🏆2
🧩 Go придумали, пока компилировались программы на C++ или почему Go компилируется так быстро, а C++ нет

Кажется, что компиляция - это просто стандартный процесс и везде работает одинаково. Но если сравнить C++ и Go, разница во времени может быть в разы. И дело не в том, что один компилятор “лучше написан”, а в фундаментально разных моделях компиляции.

Начнем с C++

Главная проблема - это header files. В C++ нет нормальной модели модулей (за исключением новых версий С++), поэтому используются заголовочные файлы, которые просто текстово вставляются через #include. Это не импорт, это буквально копипаст кода на этапе препроцессинга. Если у тебя есть файл main.cpp, который включает iostream, vector и еще пару библиотек, то компилятор видит не маленький файл, а огромный кусок кода, куда подтянуты тысячи строк из стандартной библиотеки и всех зависимостей. И это происходит для каждого .cpp файла отдельно. Отсюда возникает ключевая проблема - дублирование работы. Один и тот же header может парситься и обрабатываться десятки или сотни раз. Компилятор не переиспользует результат, он снова и снова проходит по одному и тому же коду. Чтобы хоть как-то это ускорить, появились precompiled headers, но я думаю, что это скорее костыль, а не решение архитектурной проблемы.

Дальше - templates. Шаблоны в C++ - это не просто дженерики, а полноценный механизм генерации кода во время компиляции. Шаблоны в С++ Тьюринг-полные, с рекурсией, SFINAE и сложной логикой. В результате компиляция превращается в выполнение программы внутри компилятора.

Теперь добавим dependency graph. В C++ он неявный и размытый. Из-за include невозможно быстро понять, какие именно части кода реально нужны. Малейшее изменение в header файле может привести к перекомпиляции огромной части проекта.

Теперь посмотрим на Go

В Go изначально отказались от header files. Есть только один источник правды - .go файлы. Никакого текстового include нет, только import. Причем импорт работает на уровне пакетов, а не файлов, поэтому компиляция происходит по пакетам. Когда ты импортируешь пакет, компилятор не читает заново весь его исходный код. Он использует уже скомпилированное представление пакета - это ключевой момент.

Dependency graph в Go явный и простой. Импорты явно указаны, нет скрытых зависимостей через include. Поэтому компилятор точно знает, что нужно пересобрать, а что нет. Изменил один пакет - пересобрал только его и то, что от него зависит. Еще один важный момент - стандартная библиотека. В Go она уже предскомпилирована и поставляется в виде кеша. Тебе не нужно каждый раз компилировать “iostream на стероидах”, как в C++.

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

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

Кто я | Навигация | Спасибо
🔥39👍2712🏆3
📹 Мы редко пишем плохой код специально - обычно все начинается с мелочей: небольшой баг, быстрый костыль, «потом поправлю»

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

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

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

Посмотреть видео можно по ссылке: https://www.youtube.com/watch?v=zsuTQPif53E

Кто я | Навигация | Спасибо
1👍16🔥651💯1
🔊 В конце мая буду выступать на конференции DDConf в Ростове-на-Дону с докладом «Почему разработчики ничего не успевают (и как это исправить)»

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

Кстати, 24 мая там же пройдет DonDevFest - IT-фестиваль на СтереоПляже: волейбол, открытый микрофон, гости и разные активности на свежем воздухе.

Подбробнее познакомиться с конференцией и фестивалем можно по ссылке: https://ddconf.ru/

Кто я | Навигация | Спасибо
👍157🔥6🏆32🎉2
😂👍👍❤️👌😅😊😊😍😘
13 апреля в 18:00 ч. (Мск)

Уже завтра — новый эфир на тему «Профессиональная устойчивость в IT: как не потерять опору в эпоху автоматизации»

У меня в гостях:

⚡️ Владимир Балун — основатель it-interview.io и balun.courses, ex-руководитель команды в Яндекс, ex-ведущий разработчик в Ozon, ex-разработчик в Mail.ru, Kaspersky и Тинькофф.
⚡️ Андрей Кобец — программист, преподаватель, основатель Kobezzza.Lab.

IT стремительно меняется: автоматизация, AI и ускорение рынка заставляют специалистов и управленцев сомневаться в своей ценности и усложняют принятие решений.

Разберем подробно:

1️⃣ почему именно сейчас в IT так много сомнений в себе, даже у сильных специалистов. Это влияние AI или кризис профессиональной идентичности на фоне ускорения рынка?

2️⃣ где реальный источник нестабильности: во внешней среде или в том, как мы её интерпретируем?

3️⃣ где проходит граница между «техническим исполнителем» и специалистом, сохраняющим ценность на любой технологической волне?

4️⃣ как руководителям поддерживать устойчивость команд, если сами лидеры находятся в зоне неопределённости? Где грань между честностью о рисках и созданием дополнительной тревоги в команде?

Пройдите РЕГИСТРАЦИЮ, чтобы быть с нами онлайн. Вам придет ссылка на почту и так вы сможете задать свои вопросы в прямом эфире. И до встречи уже завтра!
Please open Telegram to view this post
VIEW IN TELEGRAM
👍85🔥5
💭 Есть интересный момент, который часто всплывает, когда разработчики переходят в Go с других языков. Во многих языках есть тернарный оператор - короткий и удобный способ записать условие в одну строку, к нему быстро привыкаешь. А потом приходишь в Go - и его там нет...

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

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

Почитать можно здесь: https://dburov.com/ru/research/go-ternary

А вам не хватает тернарного оператора или нет?

Кто я | Навигация | Спасибо
👍177🔥7👨‍💻1
Как мигрировать приложение в облако

• 20 апреля, ПН
• 19:00 по мск

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

Что будет на уроке:

1️⃣Создание виртуальной инфраструктуры

2️⃣Миграция монолитного приложения подходом Lift and Shift

3️⃣Безопасная настройка публичного доступа к приложению в облаке

4️⃣Оценка затрат на инфраструктуру, и как их оптимизировать

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

Что еще важно знать:
1) Применимо к любому ЯП. Примеры будут на Python, но язык простой и много программировать не придется. Неважно, написан код на Go или C++ — принципы миграции везде одинаковы

2) Применимо к любому облаку. Мигрируем на примере Cloud.ru, но знания применимы к Yandex Cloud или любому другому облаку — паттерны и антипаттерны одинаковы везде


Рассказывает Илья Смирнов, архитектор решений Cloud.ru.

➡️Записаться на урок по ссылке: https://clck.ru/3T8drG

Кто я | Навигация | Спасибо
Please open Telegram to view this post
VIEW IN TELEGRAM
12👍5🔥3
🔊 Делаем митап в Ростове-на-Дону для разработчиков - без формализма, с реальными кейсами и приятным общением

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

На странице митапа можно посмотреть, как прошла наша встреча в Ростове-на-Дону в прошлом году - там есть фотографии и атмосфера, чтобы понять, чего ожидать: https://vladimir-balun.timepad.ru/event/3922777/ (количество билетов ограничено, записаться уже можно сейчас)

Митап платный - у нас нет спонсоров, поэтому стоимость билетов покрывает организацию, площадку, кейтеринг и администрирование


Кто я | Навигация | Спасибо
👍14🔥74🎉3
Как выбрать лучшую LLM для агента или приложения и не переплачивать

• 27 апреля, ПН
• 19:00 по мск

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

Разработчики, лиды и продакты часто выбирают модели как «самые лучшие». При этом задача - определить тональность отзыва или сделать RAG.

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


Что будет на уроке:

1️⃣Типы LLM и по каким критериям делать выбор под свою задачу

2️⃣Почему «самая умная модель» – не всегда самый умный выбор

3️⃣Как инженерно подойти к выбору LLM и на какие метрики смотреть

4️⃣Каскады и повышение эффективности — что это такое и как помогает экономить деньги без потери качества

Рассказывает Антипов Дмитрий: руководитель разработки AI-продуктов в Группе Сбер (АБТ).

Записать на урок можно по ссылке: https://clck.ru/3TDiwA

Кто я | Навигация | Спасибо
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍85
🧩 Lock contention - вещь, о которой почти никто не думает… пока все не начинает тормозить

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

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

Простой пример на Go:

type Counter struct {
mtx sync.Mutex
value int
}

func (c *Counter) Inc() {
c.mtx.Lock()
defer c.mtx.Unlock()
c.value++
}


Выглядит корректно! Но если у тебя 500-1000+ горутин дергают Inc() - начинаются проблемы: все ждут мьютекс, а также растут задержки и падает пропускная способность.

Из личного опыта: один раз уперлись в интересный деградационный кейс - сервис начинал сильно тормозить при росте нагрузки, хотя CPU был далеко не на 100% и проблема никак не была связана с внешними источниками данных. Долго копали, а в итоге оказалось, что все упирается в один мьютекс при агрегации метрик. После того как структуру данных пошардировали с разными мьютексами - проблема была решена.

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

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

Кто я | Навигация | Спасибо
23👍14🔥9🏆2🤩1
💭 Есть довольно популярное мнение в разработке: system design нужен только сеньорам и архитекторам, а мидлу он, по сути, не нужен - достаточно хорошо писать код

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

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

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

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

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

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

Это довольно типичная ситуация для мидлов: код пишется уверенно, но при обсуждении системы возникает непонимание. Разница между middle и senior часто не в качестве кода, а в уровне мышления. Middle думает задачей и реализацией. Senior думает системой и последствиями решений. И даже если цель не стать сеньором прямо сейчас, оставаться только на уровне реализации задач - это ограничение роста.

Если резюмировать, то System Design для middle-разработчика - это не про обязанность проектировать сложные системы с нуля. Это про более осознанный код, понимание устройства системы, уверенность в технических обсуждениях и фундамент для дальнейшего роста. И эффект от этого обычно заметен довольно быстро - как в работе, так и в том, как меняется само восприятие разработки.

Кто я | Навигация | Спасибо
27👍15🔥8
Розыгрыш в честь 1 мая

В преддверии майских праздников мы разыгрываем три приза для развития ваших профессиональных навыков.

Призы:
• Один курс на выбор.
• Один интенсив на выбор.
• Одно mock-собеседование от it-interview.io с обратной связью.

Все подробности в посте по ссылке: https://xn--r1a.website/balun_courses/369

Кто я | Навигация | Спасибо
Please open Telegram to view this post
VIEW IN TELEGRAM
12🔥7👍3🎉1
🧩 В Go select устроен так, что при одновременной готовности нескольких каналов он не пытается как-то честно распределять выполнение.

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

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


for {
select {
case msg := <-ch1:
fmt.Println(msg)
case msg := <-ch2:
fmt.Println(msg)
}
}


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

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


for {
select {
case msg := <-highPriority:
handleHigh(msg)
case msg := <-lowPriority:
select {
case msg := <-highPriority:
handleHigh(msg)
default:
handleLow(msg)
}
}
}


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

Есть вариант чуть мягче, когда приоритет не фиксируется настолько строго, а скорее “подсвечивается” через вероятность. Например, можно повторять ветку несколько раз:


for {
select {
case msg := <-highPriority:
handleHigh(msg)
case msg := <-highPriority:
handleHigh(msg)
case msg := <-lowPriority:
handleLow(msg)
}
}


Тут highPriority просто статистически будет выигрывать чаще, но без полного подавления lowPriority.

Третий способ - использовать дополнительный select с default перед основным. Сначала делается неблокирующая проверка приоритетного канала.


for {
select {
case msg := <-highPriority:
handleHigh(msg)
default:
}

select {
case msg := <-highPriority:
handleHigh(msg)
case msg := <-lowPriority:
handleLow(msg)
}
}


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

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

Кто я | Навигация | Спасибо
👍60🔥1413🏆1
💭 Написал подробную статью про подготовку к алгоритмическим собеседованиям - там собрал все, что обычно вызывает больше всего вопросов у разработчиков: как вообще устроена алгосекция, что именно спрашивают, какие темы нужно знать, и как к этому системно готовиться, чтобы не "зазубривать задачи", а понимать их суть.

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

🔗 Ссылка на статью: https://balun.courses/blog/algorithmic_interview/

Ещё в ближайшее время буду рассказывать про алгоритмы и подготовку к собеседованиям на конференциях:
- 13 мая, Москва - конференция Mobius
- 16 мая, Чебоксары - конференция IT-Link
- 30 мая, Ростов-на-Дону - митап по программированию

Если будете на этих мероприятиях - приходите на доклады, буду рад пообщаться вживую!

Кто я | Навигация | Спасибо
👍38🔥1312
ИИ уже стал частью нашей жизни и работы. И именно поэтому о нем стоит говорить и говорить

В мае совместно с Центральным Университетом пройдет митап, посвященный разработке, внутреннему устройству ИИ и работе с ним!

В программе 3 доклада и один круглый стол, на которых:
• подумаем над разворачиванием LLM-моделей на своих телефонах для приватных ассистентов
• узнаем про Agent Client Protocol, который помогает интегрировать модели прямо в плагины для IDE
• поговорим о том, как заставить агентов выдавать качественный код
• и конечно поспорим о том, какую дорогу стоит выбирать компаниям: покупать готовые модели или разворачивать open source решения

Спикеры из Ozon, OpenIDE, H3llo Cloud и BlackHub Games! Митап пройдет в кампусе Центрального Университета 21 мая в 18:30 🚀

Зарегистрироватсья можно по ссылке: https://cu.ru/career/events/good-bad-ai?utm_source=partners&utm_campaign=allo_ada

Кто я | Навигация | Спасибо
🔥135👍5🎉1💯1👨‍💻1
💭 Есть известная шутка: "There are only two hard things in Computer Science: cache invalidation, naming things, and off-by-one errors"

И сначала кажется, что насчет кеша это просто мем. Ну реально - что сложного? Обновил данные в БД, очистил кеш и все. А потом появляется баг: данные уже обновились, но пользователь все еще видит старое значение. Проблема в том, что кеш - это почти всегда еще одна копия данных. Есть оригинал в БД, а есть копия, например в Redis, локальном кеше, CDN или браузере. И теперь все это нужно держать синхронным.

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

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


db.UpdateUser(user)
redis.Del("user:123")


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

Именно поэтому вокруг кеширования столько паттернов: например cache aside, write through, write behind и так далее. Но ни один из них не решает проблему полностью. Они просто по-разному влияют на задержки, консистентность или сложность системы.

Отдельная боль - многоуровневый кеш. Когда у вас одновременно: in-memory cache, Redis, CDN, кеш браузера или кеш на фронте. И теперь инвалидировать нужно не один слой, а сразу всю цепочку. Особенно весело, когда в одном месте данные уже обновились, а в другом еще нет. И система начинает сама себе противоречить.

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

Кто я | Навигация | Спасибо
👍398🔥71🤩1
💭 Периодически провожу бесплатные консультации в формате Q&A-встреч, где можно задать вопросы про программирование, карьеру, собеседования, развитие в IT и просто обсудить разные рабочие ситуации

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

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

Следующие встречи пройдут 26 и 28 мая.

Участие бесплатное, но записи не делаем - только онлайн присутствие вживую. Если интересно, можно присоединиться по ссылке: balun.courses/open_lessons/qa

Кто я | Навигация | Спасибо
🔥1510👍8🏆1