Golang Дайджест
8.09K subscribers
37 photos
1 file
180 links
Самое интересное из мира Go: новости, статьи, проекты, сервисы, изменения в языке и др.

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

Поэтому можно не мьютить канал =)

Обратная связь: @justskiv
Download Telegram
Forwarded from Go Update
🎉 Вышел Go 1.25! 🎉

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

♻️ Бинарей в комплекте теперь меньше. Разработчики компилятора активно использовать команду go tool у себя внутри, что убирает необходимость поставлять заготовки в комплекте. Но как минимум go build и go test бинари все еще на месте.

— Новая директива ignore в go.mod. Подробное описание тут. Если в вкратце: для этого вы раньше использовали каталог testdata и каталоги которые начинаются с точки.

— Когда go команда обновляет go 1.xx.y директиву в go.mod она больше не добавляет toolchain директиву.

go vet теперь ругается на неправильное использование sync.WaitGroup.Add и fmt.Sprintf("%s:%d", host, port) ибо есть net.JoinHostPort.

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

🔀️️️️️️ Новый тип runtime/trace.FlightRecorder позволяет записывать только значимые события, а не всё подряд для tracing’га (под капотом используется циклический буфер, который помнит N последних секунд).

🛠 Компилятор теперь генерирует дебаг-инфу в формате DWARF5. Практический итог: бинари едят меньше места и быстрее комбинируются.

🏎️️️️️️ Новый экспериментальный пакет encoding/json/v2. По хорошему про него тоже надо писать отдельную статью, но если в кратце — он намного быстрее того что было внутри encoding/json. А другая хорошая новость заключается в том, что если вы включили GOEXPERIMENT=jsonv2 то больше ничего менять не надо, так как encoding/json сам подключит новую внутряку.

— Тип os.Root приобрел несколько новых методов.

🏎️️️️️️ Функция reflect.TypeAssert позволяет приводить типы из reflect.Value в конкретный тип, минуя потенциально аллоцирующий вызов reflect.Value.Interface.

— Директива GODEBUG=checkfinalizers=1 позволяет понять, как дела в вашей очереди cleanup’ов и finalizer’ов во время каждого GC.

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

— Новый метод sync.WaitGroup.Go - больше нет необходимости тащить errgroup если вам не нужен был возврат ошибок и отмена контекста.

🔥testing.T/B/F теперь имеют метод Output() io.Writer который позволяет правильно редиректить вывод внутри вызова теста.

Читать про релиз вот тут.
1🔥43👍229🤯3
Ещё одна статья про Swiss Tables в Go

https://habr.com/ru/companies/oleg-bunin/articles/934906/

Если вам было мало статей на эту тему, то держите ещё один неплохой подробный разбор:

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


#article #swiss_map
👍135🔥3
Как мы обслуживаем 5 млрд карточек в сутки с задержкой меньше 1 мс

https://habr.com/ru/articles/942274/

Классическая история, ребята столкнулись с проблемой выросшего стартапа — PHP-монолит с миллионами товаров начал задыхаться под нагрузкой. Решили вынести самые нагруженные части в отдельные сервисы. Один из них — сервис карточек товаров с жесткими требованиями: 99% ответов за 30 мс, 300к RPS в пике. О нём и пойдёт речь.

Что сделали:

— Двухуровневая архитектура с горячим и холодным хранилищами

— Горячий кеш в памяти с алгоритмом вытеснения 2Q (а не LRU/LFU): защита от sequential scan.

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

— Инвалидация через Redis Streams: декораторы на репозиториях отправляют события об изменениях

— Прогрев после деплоя: собирают статистику популярных товаров и греют только их (старт занимает несколько минут)

Результат: медиана 348 микросекунд при 5 млрд запросов в сутки. Для одной карточки нужно 35 обращений к кешу и данные из 130 сущностей.

————

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

Немного смущает выбор 2Q "по непонятным причинам" — это же архитектурное решение, а не цвет кнопки 🦄

В целом — must read для тех, кто интересуется высоконагруженными системами.

#article #highload #cache
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥29👍135
Как я пытался засунуть gRPC в браузер — часть первая

https://habr.com/ru/articles/941816/

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

Причина: браузеры не умеют работать с HTTP/2 стримами из JavaScript. За 10 лет было 4 серьёзных попытки это исправить, и самая первая до сих пор остаётся самой адекватной.

История про gRPC-Gateway (2015):

- Японская разработчица Yuki Yugui Sonoda придумала гениально простое решение: не надо тащить gRPC в браузер, давайте сделаем прокси

- Добавляешь в proto-файлы HTTP-аннотации, генерируешь код — получаешь REST API для фронта и gRPC для бэкенда

- Вся бизнес-логика пишется один раз, интерсепторы работают

- Стримы тоже работают... через WebSocket (ну хоть так)

- Бонусом идёт автоматическая генерация Swagger-документации

Результат: это не настоящий gRPC в браузере, а "REST с протобафами". Но работает, и это главное.

————

Забавно, что такой большой Google так и не смог придумать ничего лучше, чем решение одного разработчика из 2015 года. Хотя, автор статьи как раз предполагает, что у Гугла были свои внутренние наработки:

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


Бонус для меня: благодаря статье узнал, что автор gRPC-Gateway — японка, будет что почитать теперь для практики языка.

#article #grpc #web
🔥11👍54
👴 Отдельный канал — defer Read()

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

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

🟢 Поэтому я завёл defer Read() — эдакий канал-радар или буфер для интересного контента, который попадается быстрее, чем я успеваю его переварить:

— Статьи, которые выглядят интересными, но пока не осилил

— Утилиты или проекты, которые заинтриговали — хочется поиграться, пощупать самому

— Прочие материалы из моих 50+ открытых вкладок 😩

🟠Во всяком случае, это будет не канал-помойка, а отфильтрованный поток — туда попадает только то, что прошло мой внутренний "code review" на интересность.

Также я буду добавлять по каждому материалу небольшой TLDR с пояснением что это и кому может пригодиться. С той лишь разницей, что это будут выводы, сделанные по беглому обзору или по LLM-выжимке.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🤔5🤯21
Testing Time: тестируем асинхронный код без time.Sleep в Go 1.25

Пост про testing/synctest в официальном блоге разработчиков Go

- Оригинал
- Хороший перевод

Go Team наконец-то решили давнюю проблему тестирования конкурентного кода. В 1.24 вышел экспериментальный пакет testing/synctest, а в 1.25 он стал стабильным.

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

Проблема стара как мир:

- Тестируешь context.WithDeadline — либо ждёшь реальную секунду (медленно), либо не ждёшь достаточно (тест нестабилен, флапает)

- Добавляешь time.Sleep с запасом — тест тормозит

- Убираешь запас — тест падает на CI под нагрузкой

Классический выбор: slow or flaky, pick... one!

Решение — пузырь с двумя функциями:

- synctest.Test(t, func(t *testing.T) {...}) — запускает функцию в пузыре с фейковым временем

- synctest.Wait() — ждёт, пока все горутины в пузыре станут "durably blocked"

- Время идёт только когда все заблокированы, вычисления занимают 0 времени

- Начало эпохи: полночь 1 января 2000 UTC (как в Go Playground)

Пример до/после:
// Было: медленно и ненадёжно
time.Sleep(time.Until(deadline) + 100*time.Millisecond)

// Стало: быстро и стабильно
synctest.Test(t, func(t *testing.T) {
time.Sleep(time.Until(deadline))
synctest.Wait()
})


————

Мне понравилось, что автор также рассказывает про историю создания. Сначала пытались добавить поддержку тестирования прямо в http-пакет — не вышло, особенно с HTTP/2. Потом сделали грязный хак с парсингом runtime.Stack() — работало, но стыдно показать. В итоге добавили поддержку прямо в рантайм.

Из ограничений: не работает с реальной сетью (вместо этого нужно использовать их имитацию в памяти — in-memory fake), мьютексы не считаются durably blocking, syscalls и cgo тоже. Но для 95% кейсов — самое то.

Забавно, что самый первый пример в статье — тест для context.WithDeadline. Видимо, это была та самая боль, с которой всё началось 🙃

#go1_25 #go_official #testing #concurrency
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍5🔥5
🧪 Сравнение инструментов для генерации моков

https://habr.com/ru/companies/avito/articles/939388/

Семён Эйгин из Авито (мейнтейнер minimock) сравнивает три популярных инструмента для генерации моков:

- mockery
- gomock
- minimock

Очевидно, автор предвзят, но статья всё равно интересная. Просто учитывайте это во время чтения.

Какие проблемы обсуждаются:

1. Типизация параметров

- mockery и gomock используют interface{} в ожиданиях: GetUser(1) интерпретируется как int вместо int64
- minimock генерирует строго типизированные методы: Expect(id int64)
- На практике: можно пропустить ошибку в стиле (int64=1) != (int=1)

2. Контроль количества вызовов

- gomock по умолчанию разрешает только один вызов метода
- mockery и minimock позволяют неограниченные вызовы
- Двойственная ситуация: gomock помогает поймать лишние вызовы, но требует явного Times() или AnyTimes()

3. Тестирование асинхронного кода

- mockery: приходится встраивать каналы через RunAndReturn — плохо масштабируется
- gomock: нужен самописный хелпер с controller.Satisfied()
- minimock: встроенная поддержка через mc.Wait(timeout)

————

Выбор автора, предсказуемо — minimock как "самый простой и топорный, покрывающий 99% случаев".

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

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

#article #testing #mocks
50👍10🤔2
🦄 Let's GoConf — новая конференция по Go

12 сентября в Москве пройдёт первая Let’s GoConf — конференция для Go-разработчиков от ребят из Speach, которые уже больше 12 лет проводят IT-ивенты (DUMP, PyCon Russia, RustCon)

Что обещают:

- Около 300 участников и 10 докладов уровня middle+

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

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

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

Посмотреть программу и купить билеты можно здесь.

❤️ По промокоду go_digest вы получите скидку 10%

#промо #go_conf
Please open Telegram to view this post
VIEW IN TELEGRAM
👍73🔥3
Bubble Tea — TUI-фреймворк для Go

https://habr.com/ru/articles/939574/

Коротенький обзор фреймворка Bubble Tea. Сам обзор ни чем особо не примечателен, но фреймворк шикарный, очень рекомендую. Если вы любите красивые консольные утилиты. вам точно понравится.

#article #tui
👍11🔥8
Golang Дайджест
Bubble Tea — TUI-фреймворк для Go https://habr.com/ru/articles/939574/ Коротенький обзор фреймворка Bubble Tea. Сам обзор ни чем особо не примечателен, но фреймворк шикарный, очень рекомендую. Если вы любите красивые консольные утилиты. вам точно понравится.…
🦄 Экосистема Charm: полезные инструменты для терминала

Раз уж на то пошло, советую обратить внимание вообще на все проекты Charm, там много интересного. Например:

- Bubbles — готовые компоненты для Bubble Tea: текстовые поля, списки, таблицы, прогресс-бары, спиннеры.

- Lip Gloss — библиотека стилей для терминальных приложений. Цвета, рамки, отступы, выравнивание — всё как в CSS, только для консоли. Используется как база для Bubble Tea.

- Gum — эдакий мост между Bubbles / Lip Gloss и shell-скриптами. То есть, можно делать те же красивые скрипты, но без кода на Go.

- Glow — рендеринг Markdown прямо в терминале с подсветкой синтаксиса и красивым форматированием. Можно читать README не выходя из консоли.

- VHS — записывает GIF/видео демонстраций терминальных приложений через простой скрипт. Идеально для документации и README.

- Soft Serve — self-hosted Git-сервер с TUI интерфейсом. Можно красиво смотреть репозитории, коммиты и файлы прямо через SSH

Ну и наше любимое:
- Crushкрасивый консольный ИИ-агент . Поддерживает разные LLM (Claude, GPT, Gemini), использует LSP для контекста как в IDE, можно переключаться между моделями на лету.

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

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

Ну да, люблю я свистелки и перделки, теперь вы знаете обо мне всё 💅

Теперь подумываю сделать большое обзорное видео про всё это. Будет ли вам такое интересно?

#cli #tui
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍17🔥4
🐳 Container-aware GOMAXPROCS: Go наконец-то видит лимиты контейнеров

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

Go Team решили давнюю проблему совместимости с контейнерами. До версии 1.25 Go определял все ядра хоста, не учитывая CPU limits контейнера. Теперь GOMAXPROCS выставляется в соответствии с лимитами автоматически.

Суть проблемы:

- Контейнеру выделено 2 CPU на машине с 128 ядрами
- Go видит 128 ядер, создаёт кучу тредов
- Linux throttling тормозит приложение каждые 100ms
- Tail latency растёт

Что изменилось в 1.25:

- Go читает cgroup CPU limits и ставит GOMAXPROCS по ним
- Динамически обновляется при изменении лимитов
- Работает из коробки — просто обновите go.mod
- CPU requests игнорируются (только limits)

————

Наконец-то.. Проблеме много лет, и всё это время приходилось костылить через uber/automaxprocs или ENV-переменные. А теперь оно работает из коробки, как и должно было уже давно.

P.S. В Java эту проблему решили ещё в 2017 году 😩

#go1_25 #go_official #kubernetes #docker
Please open Telegram to view this post
VIEW IN TELEGRAM
18🔥18🤯2🤔1
Как устроиться на Go-разработчика осенью 2025 года и получить оффер от 250к?

Ребята из Interview Hustlers 20 сентября проводят воркшоп о том, как junior и middle-разработчикам быстрее вырасти до уровня крепкого Senior, овладеть hard skills, востребованными в продуктовых компаниях и BigTech, и получить новую работу в Golang на сложном рынке в 2025 году, где AI уже наступает на пятки.

🗓 20 сентября 17:00 по МСК

Программа:
▪️ Какие hard и soft skills качать, чтобы устроиться на Golang-разработчика в BigTech?
▪️ Как эффективно собеседоваться на тяжелом рынке осенью 2025? Как выбивать максимальные офферы в РФ и заграницей?
▪️ Разборы реальных кейсов студентов, кто перекатился из Java, Python, Frontend, Mobile в Golang

Спикеры:
▪️Максим Аверин — Senior Golang Developer, основатель школы Interview Hustlers, 8 лет опыта

Регистрируйся на бесплатный воркшоп по ссылке

📎 После регистрации на воркшоп ты получишь бонус: «Как разобрать неудачное собеседование без фидбека за 3 шага с AI?» и сможешь попасть на бесплатную карьерную консультацию от команды школы

#промо #текст_прислан
🤔11👍74🔥4