Golang Дайджест
Как устроены новые мапы в Go 1.24 https://habr.com/ru/companies/ru_mts/articles/915880/ Ещё одна неплохая статья про внутреннее устройство Swiss Map #article #swissmap
Пройти мимо статьи, которая сложнее инструкции к зубной щётке: 🙅♂️
В грубой быдло-форме объяснить автору, что разбираться во внутреннем устройстве чего-либо совершенно ни к чему:✨
Всё правильно, одному деградировать скучно, а вместе веселее!
————
Эх, помню времена, когда на Хабре токсично критиковали статьи за то, что они слишком простые.. А теперь за то, что слишком сложные😩
Не показывайте ему, пожалуйста, статью про планировщик !
В грубой быдло-форме объяснить автору, что разбираться во внутреннем устройстве чего-либо совершенно ни к чему:
Всё правильно, одному деградировать скучно, а вместе веселее!
————
Эх, помню времена, когда на Хабре токсично критиковали статьи за то, что они слишком простые.. А теперь за то, что слишком сложные
Please open Telegram to view this post
VIEW IN TELEGRAM
❤34🤯13👍7🤔6
- Оригинал
- Перевод
Хорошая статья о том, почему DI-фреймворки в Go часто создают больше проблем, чем решают.
Вкратце суть статьи:
- DI — это просто передача зависимостей в конструкторы
- Фреймворки типа dig и wire часто пытаются исправить проблемы, которых нет, добавляя лишнюю сложность.
- Самый понятный и надёжный подход для большинства проектов — внедрять зависимости вручную.
————
Я полностью согласен с автором. Чем проще — тем лучше.
Сколько лет работаю с проектами на Go, и DI-фреймворки встречал ровно ноль раз (ну разве что QA себе иногда прикручивали, но им можно).
Что интересно, ни разу не ощущал, что мне без этого плохо. Всё прекрасно работает, всё прозрачно, без магии. Я всегда понимаю, откуда что берётся. Я чётко понимаю откуда что берётся.
Чего ради такие сложности? Чтобы
main()
был короче? Да он и так не супер большой, и заглядывать туда каждый день не приходится.Кстати, сравните лучше эту тему объяснил Claude Opus 4. Его вариант выглядит намного проще и понятней, при всём уважении к автору статьи.
В любом случае, статьи от кожаных всё же имеют бОльшую ценность, т.к. передают реальный опыт, а не синтетический.
#article #di
Please open Telegram to view this post
VIEW IN TELEGRAM
👍33❤12🔥5🤯3
Golang тихо умирает? 🙅♂️
- Перевод
- Оригинал (недоступен: This account is under investigation or was found in violation of the Medium Rules)
Автор статьи заявляет, что крупные компании начали "тихий отказ" от Go в пользу Rust, Kotlin и TypeScript.
Причины:
- Простота языка👍
- Непредсказуемые паузы из-за GC💪
- Бедность абстракций и неудобная обработка ошибок😩
В качестве примеров приводятся Cloudflare, Dropbox и Amazon, которые частично заменили Go на Rust.
————
Звучит страшновато, конечно. Но есть нюанс: примеры автора выглядят скорее как исключения и диверсификация, а не отказ. Cloudflare и Dropbox переписали лишь части проектов, а вся остальная инфраструктура и дальше спокойно живёт на Go. Сами же Google, AWS и куча других активно инвестируют в язык, а сообщество стабильно растёт.
Да, Go отдал Rust-у узкую нишу «real-time без GC». И это логично — нельзя идеально закрывать сразу все сценарии. Но говорить про смерть Go рановато (и даже смешно): тот же Docker, K8s, Terraform, Grafana, Prometheus и весь облачный стек чувствуют себя отлично и никуда не собираются.
Ну и вот эта цитата особенно забавляет: ... Но эпоха, когда Go был будущим программирования? Она угасает.
А что, кто-то считал Go "будущим программирования"?🙃
Итого: языки не умирают так просто. Сколько лет уже хоронят Java и PHP?
#article
- Перевод
- Оригинал (недоступен: This account is under investigation or was found in violation of the Medium Rules)
Автор статьи заявляет, что крупные компании начали "тихий отказ" от Go в пользу Rust, Kotlin и TypeScript.
Причины:
- Простота языка
- Непредсказуемые паузы из-за GC
- Бедность абстракций и неудобная обработка ошибок
В качестве примеров приводятся Cloudflare, Dropbox и Amazon, которые частично заменили Go на Rust.
————
Звучит страшновато, конечно. Но есть нюанс: примеры автора выглядят скорее как исключения и диверсификация, а не отказ. Cloudflare и Dropbox переписали лишь части проектов, а вся остальная инфраструктура и дальше спокойно живёт на Go. Сами же Google, AWS и куча других активно инвестируют в язык, а сообщество стабильно растёт.
Да, Go отдал Rust-у узкую нишу «real-time без GC». И это логично — нельзя идеально закрывать сразу все сценарии. Но говорить про смерть Go рановато (и даже смешно): тот же Docker, K8s, Terraform, Grafana, Prometheus и весь облачный стек чувствуют себя отлично и никуда не собираются.
Ну и вот эта цитата особенно забавляет: ... Но эпоха, когда Go был будущим программирования? Она угасает.
А что, кто-то считал Go "будущим программирования"?
Итого: языки не умирают так просто. Сколько лет уже хоронят Java и PHP?
#article
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔36👍25❤9🤯1
Как разогнать TLS на Go до 100 Gbps — опыт Kinescope
https://habr.com/ru/companies/oleg-bunin/articles/913272/
Ребята из Kinescope показывают, как они добились скорости раздачи видео в 100 Gbps на обычных 1U-серверах, используя Go и kTLS.
Что интересного:
- Перенесли TLS-шифрование из user space в ядро Linux с помощью kTLS — получили zero-copy и минимальную нагрузку на CPU (1.4% при 40 Gbps)
- Обнаружили, что Let's Encrypt по умолчанию выдаёт RSA-сертификаты. Переход на ECDSA ускорил handshake в 40 раз (с 1.6 сек до 40 мс)
- Написали минимальный патч к стандартной библиотеке Go для поддержки kTLS — всё работает через обычные интерфейсы
- Решили проблему session resumption на множестве серверов простым способом — синхронизацией ключей между машинами
Интересный момент: когда из-за ошибки в конфиге весь трафик (40 Gbps) ушёл на одну машину — и она выдержала, хотя и "молотила" 600% CPU.
————
Хорошая статья с реальными продакшн-кейсами. Авторы не стесняются рассказывать про свои косяки (история с ChaCha и бабушкафонами) и показывают конкретные метрики.
Кстати, как заметил автор, в Go уже принято решение добавить поддержку kTLS в стандартную библиотеку — issue #44506 наконец-то сдвинулся с мёртвой точки.
#article #performance #tls
https://habr.com/ru/companies/oleg-bunin/articles/913272/
Ребята из Kinescope показывают, как они добились скорости раздачи видео в 100 Gbps на обычных 1U-серверах, используя Go и kTLS.
Что интересного:
- Перенесли TLS-шифрование из user space в ядро Linux с помощью kTLS — получили zero-copy и минимальную нагрузку на CPU (1.4% при 40 Gbps)
- Обнаружили, что Let's Encrypt по умолчанию выдаёт RSA-сертификаты. Переход на ECDSA ускорил handshake в 40 раз (с 1.6 сек до 40 мс)
- Написали минимальный патч к стандартной библиотеке Go для поддержки kTLS — всё работает через обычные интерфейсы
- Решили проблему session resumption на множестве серверов простым способом — синхронизацией ключей между машинами
Интересный момент: когда из-за ошибки в конфиге весь трафик (40 Gbps) ушёл на одну машину — и она выдержала, хотя и "молотила" 600% CPU.
————
Хорошая статья с реальными продакшн-кейсами. Авторы не стесняются рассказывать про свои косяки (история с ChaCha и бабушкафонами) и показывают конкретные метрики.
Кстати, как заметил автор, в Go уже принято решение добавить поддержку kTLS в стандартную библиотеку — issue #44506 наконец-то сдвинулся с мёртвой точки.
#article #performance #tls
🔥49👍6
Forwarded from Thank Go! (Anton Zhiyanov)
GOMAXPROCS для контейнеров
Параметр рантайма GOMAXPROCS определяет максимальное количество потоков операционной системы, которые планировщик Go может использовать для одновременного выполнения горутин.
Начиная с Go 1.5, по умолчанию он равен значению runtime.NumCPU, то есть количеству логических CPU на машине.
Например, на моем ноутбуке с 8 ядрами значение GOMAXPROCS по умолчанию тоже равно 8:
Программы на Go часто запускаются в контейнерах под управлением Docker или Kubernetes. В этих системах можно ограничить использование процессора для контейнера с помощью функции Linux, которая называется cgroups.
До версии 1.25 рантайм Go не учитывал ограничение по CPU (CPU-квоту) при установке значения GOMAXPROCS. Как бы вы ни ограничивали ресурсы процессора, GOMAXPROCS всегда устанавливался равным количеству CPU на хосте.
А теперь начал учитывать:
Если лимит CPU изменяется, рантайм автоматически обновляет значение GOMAXPROCS. Сейчас это происходит не чаще одного раза в секунду.
подробности
Параметр рантайма GOMAXPROCS определяет максимальное количество потоков операционной системы, которые планировщик Go может использовать для одновременного выполнения горутин.
Начиная с Go 1.5, по умолчанию он равен значению runtime.NumCPU, то есть количеству логических CPU на машине.
Например, на моем ноутбуке с 8 ядрами значение GOMAXPROCS по умолчанию тоже равно 8:
maxProcs := runtime.GOMAXPROCS(0)
fmt.Println("NumCPU:", runtime.NumCPU())
fmt.Println("GOMAXPROCS:", maxProcs)
NumCPU: 8
GOMAXPROCS: 8
Программы на Go часто запускаются в контейнерах под управлением Docker или Kubernetes. В этих системах можно ограничить использование процессора для контейнера с помощью функции Linux, которая называется cgroups.
До версии 1.25 рантайм Go не учитывал ограничение по CPU (CPU-квоту) при установке значения GOMAXPROCS. Как бы вы ни ограничивали ресурсы процессора, GOMAXPROCS всегда устанавливался равным количеству CPU на хосте.
А теперь начал учитывать:
docker run --cpus=4 golang:1.25rc1-alpine go run /app/nproc.go
NumCPU: 8
GOMAXPROCS: 4
Если лимит CPU изменяется, рантайм автоматически обновляет значение GOMAXPROCS. Сейчас это происходит не чаще одного раза в секунду.
подробности
🔥37👍8❤6
🛠 AI агент в 400 строк кода на Go
https://ampcode.com/how-to-build-an-agent
Оличная статья от Thorsten Ball про создание собственного ИИ агента. Особая прелесть в том, что автор объясняет всё настолько просто и доступно, что осилить её можно буквально за полчаса, получив полностью рабочего агента (с перспективами для развития, конечно).
В общем, всё в лучших традициях его замечательных книг Interpreter In Go и Compiler In Go, но в формате короткой статьи.
Это очень полезное упражнение для понимания того, как агенты устроены внутри. Да и в целом, это очень весело, вдохновляет на собственные эксперименты.
Очень рекомендую, я уже написал по ней своего, и даже немного прокачал, просто веселья ради. Мне очень понравилось✨
Конечно, замену полноценному агенту вы таким образом не получите, впереди ещё много работы. Но главное, что отправная точка уже есть.
————
И вдогонку ещё одна статья на ту же тему от нашего соотечественника на Хабре
#ai_agent #diy #llm
https://ampcode.com/how-to-build-an-agent
Оличная статья от Thorsten Ball про создание собственного ИИ агента. Особая прелесть в том, что автор объясняет всё настолько просто и доступно, что осилить её можно буквально за полчаса, получив полностью рабочего агента (с перспективами для развития, конечно).
В общем, всё в лучших традициях его замечательных книг Interpreter In Go и Compiler In Go, но в формате короткой статьи.
Это очень полезное упражнение для понимания того, как агенты устроены внутри. Да и в целом, это очень весело, вдохновляет на собственные эксперименты.
Очень рекомендую, я уже написал по ней своего, и даже немного прокачал, просто веселья ради. Мне очень понравилось
Конечно, замену полноценному агенту вы таким образом не получите, впереди ещё много работы. Но главное, что отправная точка уже есть.
————
И вдогонку ещё одна статья на ту же тему от нашего соотечественника на Хабре
#ai_agent #diy #llm
Please open Telegram to view this post
VIEW IN TELEGRAM
Ampcode
How to Build an Agent
Building a fully functional, code-editing agent in less than 400 lines.
🔥39❤4👍2
Полноценное RAG-приложение на Go — безумие?
https://habr.com/ru/articles/930090/
Хорошая статья от начинающего разработчика, который решил пойти против течения и построить RAG-систему на Go, вместо привычного Python.
Спойлер: вышло интересно, хоть и с нюансами.
Получилась довольно нетривиальная система:
- 5 микросервисов с разделением ответственности
- Kafka в роли брокера сообщений
- Ollama для локального inference на собственной GPU
- gRPC-стриминг + SSE для передачи токенов в реальном времени (без вебсокетов)
👴 Учитываем, что это пет-проект, и архитектура немного перегружена ради учебных целей.
Узкие места и проблемы:
Главный bottleneck оказался в Ollama — весь трафик генерации и эмбеддингов упирается в неё, локальная GPU тянет всего один запрос за раз.
Мои мысли по оптимизации:
- Для продакшена точно нужен vLLM кластер или платные API (OpenAI/Anthropic)
- Kafka здесь оверкилл — NATS или Redis Streams справятся не хуже и проще в деплое
- Можно добавить кеширование эмбеддингов и результатов поиска
- Рассмотреть pgvector вместо отдельного векторного хранилища
В целом, статья полезная, и выбор Go вместо Python для RAG выглядит вполне логично — действительно, RAG это по большей части инфраструктура, а не ML-магия.
Особенно ценно, что автор честно описывает проблемы и не идеализирует решение.
#article #rag #llm
https://habr.com/ru/articles/930090/
Хорошая статья от начинающего разработчика, который решил пойти против течения и построить RAG-систему на Go, вместо привычного Python.
Спойлер: вышло интересно, хоть и с нюансами.
Получилась довольно нетривиальная система:
- 5 микросервисов с разделением ответственности
- Kafka в роли брокера сообщений
- Ollama для локального inference на собственной GPU
- gRPC-стриминг + SSE для передачи токенов в реальном времени (без вебсокетов)
Узкие места и проблемы:
Главный bottleneck оказался в Ollama — весь трафик генерации и эмбеддингов упирается в неё, локальная GPU тянет всего один запрос за раз.
Мои мысли по оптимизации:
- Для продакшена точно нужен vLLM кластер или платные API (OpenAI/Anthropic)
- Kafka здесь оверкилл — NATS или Redis Streams справятся не хуже и проще в деплое
- Можно добавить кеширование эмбеддингов и результатов поиска
- Рассмотреть pgvector вместо отдельного векторного хранилища
В целом, статья полезная, и выбор Go вместо Python для RAG выглядит вполне логично — действительно, RAG это по большей части инфраструктура, а не ML-магия.
Особенно ценно, что автор честно описывает проблемы и не идеализирует решение.
#article #rag #llm
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Полноценное RAG-приложение на Go — безумие?
Предисловие Прежде всего хочу сказать, что я не являюсь никаким специалистом, даже джуновского лвла, просто безработный студент, пишущий на коленке свои пет-проекты. И код, и тем более архитектура...
👍39❤19🤔3
Forwarded from Go Update
🔀 Динамический GOMAXPROCS 🔀
До релиза Go 1.25 осталось около недели, а значит, самое время восполнить пробелы и написать всё то, о чем я (по-хорошему) должен был рассказать в течение последнего полугодия разработки новой версии языка. Начнем с небольшого, но значимого изменения: динамического
Для тех, кто не в курсе: Go позволяет определить число горутин, которые могут одновременно выполняться в пределах рантайма. Ключевое слово — одновременно. Это значит, что горутин у вас может быть сколько угодно, но выполняться из них (лопатить код, а не находится в ожидании сети, файлов или ответа из сишной либы), в момент времени, будет только число, указанное в
Смысл вот в чем: в контейнеризированном мире на приложение может быть выделено даже не ядро, а фракция или квота, при этом значения сии могут быть динамическими и изменяться в процессе работы кластера. Процесс может ошибочно исходить из того, что у него есть 64 ядра всего блейда (и как следствие — возможность 64-х активных потоков), но по факту доступных именно нашему процессу ядер намного меньше. И это не вдаваясь в подробности таких вещей, как "привязка к ядрам CPU конкретного процесса" которые актуальны в NUMA окружениях.
До версии Go 1.25 эту проблему частично решала библиотека automaxprocs от Uber, которая выставляла значения наиболее приближенные к ожидаемым оркестратором. Но делала она это только один раз и только на старте. Кроме того, много людей банально не знали об этой тонкости работы рантайма Go и, как следствие, неправильно использовали доступные ресурсы CPU.
Начиная с версии Go 1.25,
На изменение
• Изменение числа логических ядер на машине.
• Изменение привязки приложения к ядрам CPU.
• И, специально для Linux, средний лимит пропускной способности, основанный на квотах CPU
Стоит заметить, что это изменение, при всех его очевидных плюсах, имеет один, но явный неочевидный минус — если вы шардировали кеши по числу
• Вы можете не выставлять в
• Вы можете самостоятельно выставить
• Также можно оставить прошлое поведение с помощью
P.S. Для полноценного мониторинга Go теперь держит в памяти дескриптор доступа к файлам cgroups на время жизни всего процесса.
До релиза Go 1.25 осталось около недели, а значит, самое время восполнить пробелы и написать всё то, о чем я (по-хорошему) должен был рассказать в течение последнего полугодия разработки новой версии языка. Начнем с небольшого, но значимого изменения: динамического
GOMAXPROCS
.Для тех, кто не в курсе: Go позволяет определить число горутин, которые могут одновременно выполняться в пределах рантайма. Ключевое слово — одновременно. Это значит, что горутин у вас может быть сколько угодно, но выполняться из них (лопатить код, а не находится в ожидании сети, файлов или ответа из сишной либы), в момент времени, будет только число, указанное в
GOMAXPROCS
. По-хорошему, это число обычно равно числу физических ядер на вашем CPU. Но в серверных окружениях начинаются тонкости, главная из которых, cgroups
, является столпом для Docker и K8S.Смысл вот в чем: в контейнеризированном мире на приложение может быть выделено даже не ядро, а фракция или квота, при этом значения сии могут быть динамическими и изменяться в процессе работы кластера. Процесс может ошибочно исходить из того, что у него есть 64 ядра всего блейда (и как следствие — возможность 64-х активных потоков), но по факту доступных именно нашему процессу ядер намного меньше. И это не вдаваясь в подробности таких вещей, как "привязка к ядрам CPU конкретного процесса" которые актуальны в NUMA окружениях.
До версии Go 1.25 эту проблему частично решала библиотека automaxprocs от Uber, которая выставляла значения наиболее приближенные к ожидаемым оркестратором. Но делала она это только один раз и только на старте. Кроме того, много людей банально не знали об этой тонкости работы рантайма Go и, как следствие, неправильно использовали доступные ресурсы CPU.
Начиная с версии Go 1.25,
GOMAXPROCS
будет не только выставляться автоматически, но и периодически обновляться в течение жизни приложения, в зависимости от того, как меняется внешнее окружение.На изменение
GOMAXPROCS
будут влиять в совокупности три вещи:• Изменение числа логических ядер на машине.
• Изменение привязки приложения к ядрам CPU.
• И, специально для Linux, средний лимит пропускной способности, основанный на квотах CPU
cgroup
.Стоит заметить, что это изменение, при всех его очевидных плюсах, имеет один, но явный неочевидный минус — если вы шардировали кеши по числу
GOMAXPROCS
то вас ожидают очень неприятные паники или скачки нагрузки. Поэтому, если-же вас по какой-то причине не устраивает новое поведение, то у вас есть целых три варианта:• Вы можете не выставлять в
go.mod
версию go 1.25.x
— обновление придёт к вам только когда вы захотите перейти на поведение языка версии 1.25.• Вы можете самостоятельно выставить
GOMAXPROCS
с помощью переменных окружения или с помощью функции GOMAXPROCS. В таком случае автообновление будет выключено, и рантайм доверится вашему суждению.• Также можно оставить прошлое поведение с помощью
GODEBUG
переменных containermaxprocs=0
и updatemaxprocs=0
.P.S. Для полноценного мониторинга Go теперь держит в памяти дескриптор доступа к файлам cgroups на время жизни всего процесса.
GitHub
Go compiler and runtime meeting notes · Issue #43930 · golang/go
Google's Go compiler and runtime team meets periodically (roughly weekly) to discuss ongoing development of the compiler and runtime. While not open to the public, there's been desire by th...
🔥29❤6👍4
Forwarded from Go Update
🏎️ Об оптимизациях в Go 1.25 🏎️
В новом релизе, как и всегда, к нам приедут новые оптимизации для компилятора. Две из них меня заинтересовали больше всего:
• Цепочка из четырёх 1, 2, 3, 4 PR, суть которых можно описать с помощью одного примера:
Если в Go 1.24 и ранее такой код приводил к аллокации в хипе, то начиная с Go 1.25 — нет. А всё просто:
• Нулевые значения и "константные" переменные больше не аллоцируют память в хипе при присвоении значения интерфейсу. Продемонстрировать проще всего вот так:
Если ранее подобный код приводил к аллокации, то теперь компилятор достаточно умён, чтобы на этапе компиляции выделить специальное read-only место в памяти и использовать именно его во время исполнения. Особенно приятно, что
В новом релизе, как и всегда, к нам приедут новые оптимизации для компилятора. Две из них меня заинтересовали больше всего:
• Цепочка из четырёх 1, 2, 3, 4 PR, суть которых можно описать с помощью одного примера:
var x []int
for i := 0; i < 4; i++ {
x = append(x, i)
}
Если в Go 1.24 и ранее такой код приводил к аллокации в хипе, то начиная с Go 1.25 — нет. А всё просто:
make
и append
теперь, в большинстве случаев, не аллоцируют память в хип до 32 байтов включительно. Вместо этого они используют память на стеке и лишь при превышении объёма начинают идти в хип. Такая вот консервативная оптимизация для слайсов всех типов.• Нулевые значения и "константные" переменные больше не аллоцируют память в хипе при присвоении значения интерфейсу. Продемонстрировать проще всего вот так:
type doubleInt struct{ value1, value2 int }
localVariable := doubleInt{value1: 3, value2: 2}
globalAny = any(localVariable)
localVariable2 := doubleInt{}
globalAny2 = any(localVariable2)
Если ранее подобный код приводил к аллокации, то теперь компилятор достаточно умён, чтобы на этапе компиляции выделить специальное read-only место в памяти и использовать именно его во время исполнения. Особенно приятно, что
reflect.Value.IsZero
теперь использует сравнение по указателю для нулевых значений структур и массивов, что существенно удешевляет проверку.GitHub
cmd/compile: storing zero value into interface should not allocate · Issue #71323 · golang/go
Go version go1.23.5 Output of go env in your module/workspace: GOARCH=amd64 GOOS=linux What did you do? I ran this benchmark: var sinkAny any func BenchmarkInterfaceAny(b *testing.B) { b.ReportAllo...
👍38❤16🔥9
Forwarded from Go Update
🎉 Вышел Go 1.25! 🎉
Пока я не успел статью про новый сборщик мусора написать, поэтому быстро пробегусь по основным нововведениям которых не касался в прошлых записях.
— ♻️ Бинарей в комплекте теперь меньше. Разработчики компилятора активно использовать команду
— Новая директива
— Когда go команда обновляет
—
— 🍵 Новый экспериментальный сборщик мусора. О нем статья будет позже.
— 🔀️️️️️️ Новый тип
— 🛠 Компилятор теперь генерирует дебаг-инфу в формате DWARF5. Практический итог: бинари едят меньше места и быстрее комбинируются.
— 🏎️️️️️️ Новый экспериментальный пакет
— Тип
— 🏎️️️️️️ Функция
— Директива
—
— Новый метод
— 🔥
Читать про релиз вот тут.
Пока я не успел статью про новый сборщик мусора написать, поэтому быстро пробегусь по основным нововведениям которых не касался в прошлых записях.
— ♻️ Бинарей в комплекте теперь меньше. Разработчики компилятора активно использовать команду
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
который позволяет правильно редиректить вывод внутри вызова теста.Читать про релиз вот тут.
go.dev
Go Modules Reference - The Go Programming Language
1🔥43👍22❤9🤯3
Ещё одна статья про Swiss Tables в Go
https://habr.com/ru/companies/oleg-bunin/articles/934906/
Если вам было мало статей на эту тему, то держите ещё один неплохой подробный разбор:
#article #swiss_map
https://habr.com/ru/companies/oleg-bunin/articles/934906/
Если вам было мало статей на эту тему, то держите ещё один неплохой подробный разбор:
Попробуем найти ответы на вопросы о том, почему мапы изменились, что лежит в основе новой реализации и как к ней пришли.
#article #swiss_map
Хабр
Швейцария в картах Go: путешествие по Swiss Tables
Golang продолжает развиваться. Изначальные проектные решения ставятся под сомнения, а новые вызовы заставляют язык меняться: дженерики, итераторы, новая имплементация мап. Однако, даже нововведения...
👍13❤5🔥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
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
Хабр
Как мы обслуживаем 5 млрд карточек в сутки с задержкой меньше 1 мс
Меня зовут Ескендиров Мурат, я — архитектор сайта в Ви.Tech, IT-дочке ВсеИнструменты.ру. В этой статье расскажу, как мы строили сервис для выдачи карточек товаров, обратывающий до 5 миллиардов...
🔥29👍13❤5
Как я пытался засунуть 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 года. Хотя, автор статьи как раз предполагает, что у Гугла были свои внутренние наработки:
Бонус для меня: благодаря статье узнал, что автор gRPC-Gateway — японка, будет что почитать теперь для практики языка.
#article #grpc #web
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
#article #grpc #web
Хабр
Как я пытался засунуть gRPC в браузер — часть первая
Одна из самых основных проблем в работе с gRPC - необходимость наружу вытаскивать отдельно REST API для web клиента, но, надо ли отдельно его писать, или можно как-то унифицировать и эту историю? И...
🔥11❤4👍4
This media is not supported in your browser
VIEW IN TELEGRAM
Лучшие ресурсы, чтобы не отставать от трендов Go разработки.
👣 Golang Go - авторский канал, посвященный Go разработке, Devops и созданию высоконагруженных сервисов.
📚 Golang books — редкая литература, статьи, курсы и уникальные гайды для Golang специалистов любого уровня. Читайте, развивайтесь, практикуйте.
💼 Golang Jobs — актуальные вакансии для Golang разработчиков от самых крупных работодателей и лидеров рынка.
🧠 Golang interview - решаем и разбираем задачи Go с собеседований.
⚡️ Machine Learning - ИИ, разбор моделей машинного обучение, rag, современные LLM, объясняем на пальцах как запускать вроде в своих проектах.
🎁 Продвинутый Go - собрали для вас лучшие ресурсы по Go на любой вкус в одной папке.
#промо #текст_прислан
⚡️ Machine Learning - ИИ, разбор моделей машинного обучение, rag, современные LLM, объясняем на пальцах как запускать вроде в своих проектах.
🎁 Продвинутый Go - собрали для вас лучшие ресурсы по Go на любой вкус в одной папке.
#промо #текст_прислан
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥9👍8❤4
Как вы знаете, в текущем канале я придерживаюсь правила: делюсь только теми материалами, с которыми сам ознакомился, и всегда добавляю комментарий со своим мнением.
Мне по-прежнему нравится такой подход, но порой он меня ограничивает. Я часто нахожу что-то интересное, но не всегда есть время глубоко вникнуть, дать оценку и написать вдумчивый комментарий.
— Статьи, которые выглядят интересными, но пока не осилил
— Утилиты или проекты, которые заинтриговали — хочется поиграться, пощупать самому
— Прочие материалы из моих 50+ открытых вкладок
Также я буду добавлять по каждому материалу небольшой TLDR с пояснением что это и кому может пригодиться. С той лишь разницей, что это будут выводы, сделанные по беглому обзору или по LLM-выжимке.
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
defer Read()
Интересные и полезные материалы по Go: репозитории, статьи, библиотеки и др.
👍15🤔5❤1🤯1
Testing Time: тестируем асинхронный код без time.Sleep в Go 1.25
Пост про testing/synctest в официальном блоге разработчиков Go
- Оригинал
- Хороший перевод
Go Team наконец-то решили давнюю проблему тестирования конкурентного кода. В 1.24 вышел экспериментальный пакет
Очень краткая суть: запускаешь тест в "пузыре" с фейковым временем и ждёшь, пока все горутины станут "устойчиво заблокированными" — то есть могут быть разблокированы только другими горутинами из того же пузыря.
Проблема стара как мир:
- Тестируешь context.WithDeadline — либо ждёшь реальную секунду (медленно), либо не ждёшь достаточно (тест нестабилен, флапает)
- Добавляешь
- Убираешь запас — тест падает на CI под нагрузкой
Классический выбор: slow or flaky, pick... one!
Решение — пузырь с двумя функциями:
-
-
- Время идёт только когда все заблокированы, вычисления занимают 0 времени
- Начало эпохи: полночь 1 января 2000 UTC (как в Go Playground)
Пример до/после:
————
Мне понравилось, что автор также рассказывает про историю создания. Сначала пытались добавить поддержку тестирования прямо в http-пакет — не вышло, особенно с HTTP/2. Потом сделали грязный хак с парсингом
Из ограничений: не работает с реальной сетью (вместо этого нужно использовать их имитацию в памяти — in-memory fake), мьютексы не считаются durably blocking, syscalls и cgo тоже. Но для 95% кейсов — самое то.
Забавно, что самый первый пример в статье — тест для context.WithDeadline. Видимо, это была та самая боль, с которой всё началось🙃
#go1_25 #go_official #testing #concurrency
Пост про 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 используют
- minimock генерирует строго типизированные методы:
- На практике: можно пропустить ошибку в стиле
2. Контроль количества вызовов
- gomock по умолчанию разрешает только один вызов метода
- mockery и minimock позволяют неограниченные вызовы
- Двойственная ситуация: gomock помогает поймать лишние вызовы, но требует явного
3. Тестирование асинхронного кода
- mockery: приходится встраивать каналы через
- gomock: нужен самописный хелпер с
- minimock: встроенная поддержка через
————
Выбор автора, предсказуемо — minimock как "самый простой и топорный, покрывающий 99% случаев".
И я в целом согласен: строгая типизация экономит время на дебаге, встроенная поддержка асинхронности избавляет от костылей.
Хотя, я не отношусь к выбору моков настолько же серьёзно — я сам всё ещё использую mockery, потому что описанные его минусы не столь существенны, чтобы мне захотелось взять и перейти на что-то другое.
#article #testing #mocks
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
Хабр
Самый лучший мок на свете: разбираемся с инструментами для генерации моков в Go
Всем привет! Меня зовут Семён Эйгин, я бэкендер в Авито , люблю опенсорс и периодически что-то туда контрибьючу. В этой статье разбираемся с моками и выбираем самый удобный инструмент (не обязательно...
50👍10🤔2
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
letsgoconf.ru
Конференция для Go разработчиков | Let's GoConf
Конференция по языку программирования Go, Москва, 12 сентября 2025
👍7❤3🔥3
Bubble Tea — TUI-фреймворк для Go
https://habr.com/ru/articles/939574/
Коротенький обзор фреймворка Bubble Tea. Сам обзор ни чем особо не примечателен, но фреймворк шикарный, очень рекомендую. Если вы любите красивые консольные утилиты. вам точно понравится.
#article #tui
https://habr.com/ru/articles/939574/
Коротенький обзор фреймворка Bubble Tea. Сам обзор ни чем особо не примечателен, но фреймворк шикарный, очень рекомендую. Если вы любите красивые консольные утилиты. вам точно понравится.
#article #tui
Хабр
Bubble Tea — TUI-фреймворк для Go. Мои открытия и ошибки
Недавно я наткнулся на Bubble Tea — терминальный UI-фреймворк для Go, и буквально влюбился в то, как он отрисовывает интерфейсы в консоли . В репозитории есть множество примеров — и...
👍10🔥8
Forwarded from Николай Тузов
Golang Дайджест
Bubble Tea — TUI-фреймворк для Go https://habr.com/ru/articles/939574/ Коротенький обзор фреймворка Bubble Tea. Сам обзор ни чем особо не примечателен, но фреймворк шикарный, очень рекомендую. Если вы любите красивые консольные утилиты. вам точно понравится.…
Раз уж на то пошло, советую обратить внимание вообще на все проекты 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
GitHub
Charm
We make the command line glamorous. Charm has 49 repositories available. Follow their code on GitHub.
1👍17🔥4