👨💻 Цепочка append в слайсахЕсли в часто вызываемом коде есть цепочка append, то скорее всего там скрытая лестница аллокаций.// аллокация #1defaultFields := []zap.Field{...} // аллокация #2 — вместимость кончиласьdefaultFields = append(defaultFields, ...) // аллокация #3 — финальное слияниеLog.Info("...", append(defaultFields, ...)...) Каждый раз когда append упирается в capacity, Go выделяет новый массив, копирует данные, а старый уходит сборщику мусора. В логгере, который вызывается на каждый запрос, это поток короткоживущего мусора.Решение простое — посчитать финальный размер заранее и передать его в make:allFields := make([]zap.Field, 0, 7+len(fields))allFields = append(allFields, zap.Int("status_code", code))// ... остальные поля ...Log.Info("Response sent", allFields...)📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#GoToProduction
Библиотека Go-разработчика | Golang
@goproglib
Все самое полезное для Go-разработчика в одном канале.По рекламе: @proglib_advУчиться у нас: https://proglib.io/w/32d20779Для обратной связи: @proglibrary_feeedback_botРКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0#WXSSA
Последние посты
👨💻 Инкапсуляция внутри пакета в Go В Go инкапсуляция работает на уровне пакета. Всё с маленькой буквы видно только внутри пакета, всё с большой буквы доступно снаружи. Звучит просто, пока пакет небольшой. Но когда пакет разрастается, внутри него появляется несколько файлов и сотни строк кода, и возникает вопрос: как ограничить доступ к конкретным структурам или функциям между файлами внутри одного пакета? В Java для этого есть private. В Go такого нет. Почему это вообще проблема В Go весь код внутри одного пакета видит всё, что объявлено в этом пакете, независимо от файла. Если у вас payment пакет с файлами processor.go, validator.go и refund.go, то любая функция из refund.go может обратиться к любому unexported-идентификатору из processor.go. Компилятор не запрещает, конвенций нет, всё держится на дисциплине команды. Три подхода, которые используют в реальных проектах • Разбить пакет на подпакеты Первый и самый частый совет. Если логика достаточно самостоятельная, вынесите её в отдельный пакет. Тогда вы явно контролируете, что экспортировать, а что нет. Это идиоматичный Go.payment/ processor.go validator/ validator.go // видит только то, что экспортирует payment refund/ refund.go Минус: иногда код слишком связан, чтобы разбивать его на подпакеты без боли. • Директория internal Это не просто конвенция, это механизм компилятора. Пакет внутри internal можно импортировать только из пакетов, которые находятся в том же дереве директорий выше internal.myapp/ payment/ processor.go internal/ cardutils/ cardutils.go // доступен только внутри payment/ cardutils не получится импортировать из myapp/order или любого другого места вне myapp/payment. Компилятор выдаст ошибку. Это настоящая изоляция, которую не обойти дисциплиной.// myapp/order/order.goimport "myapp/payment/internal/cardutils" // ошибка компиляции• Интерфейсы для скрытия деталей Если нужно скрыть конкретную реализацию от остальных частей пакета, можно работать через интерфейс. Дру
✏️ Вопрос, который отделяет Go-разработчиков от оффераСколько раз можно вызвать cancel() из context.WithCancel до паники?Большинство мидлов отвечают уверенно — и ошибаются. Не потому что не знают контексты, а потому что никогда не проверяли это руками и не читали исходники пакета context.ctx, cancel := context.WithCancel(context.Background())cancel()cancel() // что будет?cancel() // а теперь?А там есть один нюанс, который меняет ответ.Проверить себя → в канале с вопросами с собесов 📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#ReadySetGo
Самый востребованный навык в ИТ в 2026-м — навык создания ИИ-агентовМы полностью переработали курс «Разработка AI-агентов» под реалии 2026 года. Никакой долгой теории — с самого начала пишем код. Обучать и делиться набитыми шишками будут эксперты-практики из Газпромбанка, Альфа-Банка и других бигтехов.В программе:— архитектура автономных систем с тестированием, ReAct-циклами и контролем токенов;— практическая работа с актуальными фреймворками LangGraph, AutoGen, MCP и CrewAI;— настройка продвинутого RAG для парсинга документов и точного поиска;— внедрение решений с учётом действующего законодательства (152-ФЗ);— дипломная работа, за основу которой можно взять свой рабочий проект или задачу, которую предложим мы.Эксперты поделятся инсайтами из реального продакшна — тем, о чём вам никогда не расскажет ни одна нейросеть.Запись первого открытого вебинара, на котором мы вместе с руководителем AI-направления в Альфа-Банке Полиной Полуниной пилили агента в прямом эфире.Ах да, чуть не забыли! Дарим промокод AGENTSWEB на скидку 10 000 рублей и два курса сверху при покупке до 15 марта 🎁→ Освоить разработку AI-агентов
📎 Невидимый пожиратель памятиPrometheus собирает метрики через периодические HTTP-запросы к эндпоинту /metrics каждого сервиса — это называется скрейпом.Вот эта строка его регистрирует:r.GET("/metrics", gin.WrapH(promhttp.Handler()))Проблема в том, что promhttp.Handler() по умолчанию включает Gzip-компрессию ответа. На каждый скрейп Go создаёт новый compress/flate.NewWriter. Сжатие имеет смысл, когда Prometheus снимает метрики через WAN. Если он живёт в том же кластере это CPU и RAM в никуда.Явно отключаем компрессию:r.GET("/metrics", gin.WrapH(promhttp.HandlerFor( prometheus.DefaultGatherer, promhttp.HandlerOpts{DisableCompression: true},)))Это уменьшит нагрузку на GC, хип и CPU.📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#GoToProduction

👨💻 PVS-Studio запускает бета-тест анализатора для GoPVS-Studio известна своим статическим анализатором для C, C++ и C#. Теперь команда добралась до Go. С 6 апреля начинается бета-тестирование. Первая версия включает около двух десятков диагностических правил, CLI-утилиту и плагин для GoLand. Поддержка VS Code запланирована позже.Чтобы попасть в программу, нужно заполнить форму на сайте pvs-studio.com и указать email. 6 апреля придёт письмо с инструкциями. Если найдёте ошибки, ложные срабатывания или крэши, команда просит сообщать через форму обратной связи.➡️ Источник📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#GoLive

👨💻 Стандартный flag, Cobra или urfave/cliКаждый раз, когда Go-разработчик начинает новый CLI-инструмент, возникает один и тот же вопрос: какую либу брать? Cobra, urfave/cli, стандартный flag или вообще Bubbletea?Cobra — выбор по умолчанию для большинства. Используется в kubectl, Hugo, GitHub CLI. Поддерживает вложенные команды, автогенерацию хелпа, наследование флагов. Хорошо работает в связке с Viper для конфигов. Но есть нюанс: Cobra берёт контроль над структурой приложения. Если тебе нужен простой тул на 200 строк, она может ощущаться как фреймворк ради фреймворка.urfave/cli проще и прямолинейнее. Нет инверсии контроля, API читается легче. Хороший выбор, когда команд немного и не нужна глубокая иерархия. Минус — экосистема поменьше, и при росте проекта можно упереться в ограничения.Стандартный flag вообще не либа, а пакет из коробки. Если CLI простой и флагов штук пять, иногда правда не надо тащить зависимости.Bubbletea стоит отдельно — это TUI-фреймворк, а не парсер аргументов. Cobra и Bubbletea часто используют вместе: первая разбирает команды, вторая рисует интерфейс в терминале.💬 Что будете брать под CLI-тулзу? Ответы в комменты 👇📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#GoTalk

🤝 По резюме не берут. Берут по рекомендации 70–80% IT-вакансий закрываются ещё до того, как попадают на джоб-борды. Не потому что компании скрывают позиции — просто у кого-то из команды уже есть нужный человек на примете. Реферальный найм в 2026 году — это…Не забудьте прочитать статью, чтобы найти таких друзей📍 Навигация: Вакансии • Задачи • Собесы🐸 Библиотека Go-разработчика#GoGiggle
👨👩👧👦 Топ-вакансий для Go-разработчиков за неделю Backend Engineer — от 175 000 до 325 000 ₽, удаленно.Middle Go разработчик — от 224 700 ₽, удаленно.Team Lead Go — от 450 000 до 600 000 ₽, удаленно в Москве. ➡️ Еще больше топовых вакансий — в нашем канале Go jobs🐸 Библиотека Go-разработчика#GoWork

🛠 Конкурентность не делает код быстрее автоматическиМногие разработчики, столкнувшись с задачей ускорить код, сразу думают о конкурентности. Горутины дешевле потоков, каналы выглядят элегантно, паттерны Fan-Out/Fan-In хорошо описаны в документации. Всё это создаёт иллюзию, что конкурентность и производительность — это одно и то же. Простой эксперимент это хорошо показывает. Возьмём элементарную задачу: умножить набор чисел на 20, затем возвести каждое в квадрат. Ничего тяжёлого, чистые вычисления без IO, без сети, без базы данных.Бенчмарк:package benchmarkimport ( "sync" "testing")// Сама задача: умножить на 20, затем возвести в квадратfunc process(n int) int { n = n * 20 return n * n}// Последовательный подходfunc sequential(numbers []int) []int { result := make([]int, len(numbers)) for i, n := range numbers { result[i] = process(n) } return result}// Конкурентный подход через Fan-Out / Fan-Infunc concurrent(numbers []int) []int { numWorkers := 4 jobs := make(chan int, len(numbers)) results := make(chan int, len(numbers)) var wg sync.WaitGroup for w := 0; w < numWorkers; w++ { wg.Add(1) go func() { defer wg.Done() for n := range jobs { results <- process(n) } }() } for _, n := range numbers { jobs <- n } close(jobs) go func() { wg.Wait() close(results) }() out := make([]int, 0, len(numbers)) for r := range results { out = append(out, r) } return out}// Генерация тестовых данныхfunc makeNumbers(n int) []int { nums := make([]int, n) for i := range nums { nums[i] = i + 1 } return nums}// Бенчмаркиfunc BenchmarkSequential_100(b *testing.B) { nums := makeNumbers(100) b.ResetTimer() for i := 0; i < b.N; i++ { sequential(nums) }}func BenchmarkConcurrent_100(b *testing.B) { nums := makeNumbers(100) b.ResetTimer() for i := 0; i < b.N; i++ { concurrent(nums) }}func BenchmarkSequential_10000(b *testing.B) { nums := makeNumbers(10000) b.ResetTimer() for i := 0; i < b.N; i++ { seque