Библиотека Go-разработчика | Golang
24K subscribers
2.48K photos
48 videos
88 files
4.95K links
Все самое полезное для Go-разработчика в одном канале.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/32d20779

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0

#WXSSA
Download Telegram
🛠 Cобираем результаты от множества горутин

Fan-In — паттерн, обратный Fan-Out. Несколько горутин производят данные независимо, а один канал собирает всё воедино. Это финальная часть пайплайна.

Каждый воркер пишет в свой канал → merge-функция сливает все каналы в один → потребитель читает из одного места, не зная сколько источников было.

Ключевая идея

На каждый входящий канал запускается своя горутина-переливщик. Все они пишут в общий merged. Когда все источники иссякли — merged закрывается:
func merge(channels ...<-chan int) <-chan int {
merged := make(chan int)
wg := sync.WaitGroup{}

pipe := func(c <-chan int) {
defer wg.Done()
for v := range c {
merged <- v
}
}

wg.Add(len(channels))
for _, c := range channels {
go pipe(c)
}

go func() {
wg.Wait()
close(merged)
}()

return merged
}


Также можно отменять через контекст:
pipe := func(c <-chan int) {
defer wg.Done()
for {
select {
case v, ok := <-c:
if !ok {
return
}
merged <- v
case <-ctx.Done():
return
}
}
}


Без этого горутины-переливщики зависнут, если потребитель неожиданно отвалится.

Три правила Fan-In:

— Каждый источник сам закрывает свой канал
close(merged) только после wg.Wait()
— Горутина с wg.Wait() всегда отдельная, иначе дедлок

Fan-Out + Fan-In вместе = полный пайплайн

Fan-Out раздаёт задачи, Fan-In собирает ответы. Между ними — изолированные воркеры без общего состояния.

Порядок результатов не гарантирован — это цена параллельности. Если порядок важен, нужно добавлять индекс к каждому результату и сортировать после сбора.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥53
⚙️ Библиотека для управления долгоживущими процессами

Небольшая, но элегантная zero-dependency библиотека для Go, которая решает классическую задачу: как правильно запустить несколько фоновых процессов и корректно их завершить.

В основе лежит один интерфейс:
type Runnable interface {
Run(context.Context) error
}


Завершение работы управляется через отмену контекста — всё предсказуемо и идиоматично.

Главная фича — менеджер с двухуровневой иерархией. Cначала останавливаются процессы: HTTP-серверы, воркеры, задачи по расписанию; и только потом сервисы: очереди, БД, метрики.

Менеджер сам является Runnable — значит менеджеры можно вкладывать друг в друга для независимого управления жизненным циклом.

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍103🤔2
🧑‍💻 Приоритизация каналов в Go

select выбирает кейс случайно, если готовы несколько каналов. Звучит просто, но на практике это боль: срочное сообщение может ждать в очереди, пока обрабатывается менее важное.

Разберём, как это починить:
select {
case msg := <-urgent:
handle(msg)
case msg := <-normal:
handle(msg)
}


Никаких гарантий, что срочное обработается первым.

Решение: двойной select

for {
// Сначала пробуем срочный канал
select {
case msg := <-urgent:
handle(msg)
default:
}

// Потом общий
select {
case msg := <-urgent:
handle(msg)
case msg := <-normal:
handle(msg)
}
}


Первый select с default не блокируется — он мгновенно проверяет, есть ли что-то срочное. Если да — обрабатываем и идём на следующую итерацию. Если нет — падаем во второй select и ждём любой из каналов.

Главная опасность — голодание. Если urgent забит сообщениями постоянно, normal не получит ничего никогда.

Защита — счётчик или таймер:
normalTimeout := time.After(5 * time.Second)

for {
select {
case msg := <-urgent:
handle(msg)
default:
}

select {
case msg := <-urgent:
handle(msg)
case msg := <-normal:
handle(msg)
case <-normalTimeout:
// Принудительно даём слово normal
msg := <-normal
handle(msg)
normalTimeout = time.After(5 * time.Second)
}
}


Простота против гибкости. Согласны с таким выбором или предпочли бы встроенный механизм?

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
9👍6🥱3🤔1
Go на бэкенде, Python в «мозгах»

Как подружить высокопроизводительный Go-бэкенд с AI-агентами? В 2026-м это стандартная задача. Мы обновили курс «Разработка AI-агентов», сделав упор на архитектуру и интеграцию в продакшн.

Что полезного для Go-разработчика?

🔹 Архитектура системы. Асинхронное взаимодействие, очереди задач, управление состоянием агентов (`State Management`).

🔹 Экономика и ресурсы. Контроль токенов, кэширование, роутинг запросов — всё, что нужно для HighLoad AI.

🔹 Интеграция. Как встроить RAG и агентные цепочки (`LangGraph`) в существующую микросервисную архитектуру.

🔹 Надёжность. Трассировка ошибок, метрики и runbook для восстановления.

Стартуй сейчас!
Получи базу знаний сразу после покупки.

🎟 Промокод Agent — скидка 10 000 ₽ (до 28 февраля).

👉 Строим архитектуру AI-сервисов
🥱14🔥3
🤩 Топ-вакансий для Go-разработчиков за неделю

Senior Golang developer (Gamedev) — удалёнка

Junior Go-developer — от 160 000 ₽, удаленно

Senior Go Developer — 406 000 ₽, удаленно

➡️ Еще больше топовых вакансий — в нашем канале Go jobs

🐸 Библиотека Go-разработчика

#GoWork
Please open Telegram to view this post
VIEW IN TELEGRAM
3🥱1
🔄 go-testdeep — большое обновление

Вышел релиз go-testdeep v1.15.0 — одной из библиотек для глубокого сравнения данных в тестах на Go. И в этот раз изменений особенно много.

Главное: библиотека теперь без зависимостей

go-testdeep стал полностью dependency-free. Авторы встроили go-spew напрямую. Меньше go.sum, меньше проблем с совместимостью.

Новые операторы

List — простая и лёгкая альтернатива массивов и слайсов для сравнения в строгом порядке:
td.Cmp(t, []int{1, 9, 5}, td.List(1, 9, 5))


Sort — сортирует слайс перед сравнением. Поддерживает сложные ключи, вложенные поля и даже использование внутри JSON-оператора:
td.Cmp(t, got, td.Sort("-props[priority]", []A{p34, p23, p12}))


Sorted — просто проверяет, что слайс уже отсортирован:
td.Cmp(t, aSlice, td.Sorted())
td.Cmp(t, aStructSlice, td.Sorted("-FieldName")) // по убыванию


Must, Must2, Must3 — меньше бойлерплейта

Раньше нужно было писать две строки на обработку ошибки. Теперь одну:
// было
val, err := myfunction()
td.Require(t).CmpNoError(err)

// стало
val := td.Must(myfunction())


Если вы пишете тесты на Go и ещё не пробовали go-testdeep — самое время.

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🧑‍💻 Контекст + канал = контролируемая отмена

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

Вместо того чтобы ждать только данных из канала, горутина одновременно слушает сигнал отмены из контекста. Как только кто-то вызывает cancel() или истекает таймаут — ctx.Done() закрывается, и все горутины, которые его слушают, корректно завершаются.

Это работает на любой глубине вложенности: отменили корневой контекст — сигнал получат все дочерние.

Реальный пример: HTTP-запрос с отменой
func fetchData(ctx context.Context, url string) ([]byte, error) {
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return nil, err
}

resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err // ctx.Err() если отменили
}
defer resp.Body.Close()

return io.ReadAll(resp.Body)
}

// Вызов с таймаутом:
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel() // всегда defer cancel()!

data, err := fetchData(ctx, "https://api.example.com/data")


Если сервер не ответил за 3 секунды — запрос автоматически отменяется. Никаких висящих горутин.

Context или просто close(ch)

• Используйте close(ch) когда хотите сигнализировать, что данные закончились — один продюсер завершил работу, консюмеры это видят.

• Используйте context когда нужна отмена извне — пришёл сигнал остановиться, истёк таймаут, пользователь нажал cancel. Контекст распространяется вниз по дереву вызовов сам.

• Они не конкурируют — часто используются вместе: канал несёт данные, контекст несёт намерение остановиться.

Главные правила:

defer cancel() сразу после создания контекста — без исключений. Передавайте ctx первым аргументом в функцию. Не кладите context внутрь структур, это спорно, но большинство стайлгайдов против. Проверяйте ctx.Err() после долгих операций.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
🤩 go fix — новая жизнь старой команды

Go 1.26, привёз полностью переписанный go fix. Разбираемся, что изменилось.

go fix — это статический анализатор + автоматический рефакторинг. Он находит устаревшие паттерны в коде и заменяет их более современными аналогами. Без ручной правки, без регрессий.

Как запустить:
# Починить всё в проекте
go fix ./...

# Посмотреть что изменится, не применяя
go fix -diff ./...

# Список доступных анализаторов
go tool fix help

# Документация по конкретному
go tool fix help forvar

# Запустить только один анализатор
go fix -minmax ./...

# Запустить все, кроме одного
go fix -any=false ./...


Иногда одно исправление открывает возможность для второго. Например, замена конкатенации строк в цикле на strings.Builder может затем подсветить, что WriteString(fmt.Sprintf(...)) лучше заменить на fmt.Fprintf. Поэтому рекомендуют запускать go fix ./... дважды.

В Go 1.26 go fix и go vet унифицированы: оба работают на одном фреймворке статического анализа. Разница только в критериях: vet ищет ошибки и репортит их, fix генерирует безопасные правки и применяет их.

Команда Go строит «самообслуживаемую» модель: авторы библиотек смогут поставлять анализаторы вместе со своим кодом, а пользователи — применять их через go fix без необходимости ждать обновлений.

➡️ Блог разработчиков

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥23👍53
Стандартный вопрос на собесе

В Go есть три тесно связанных понятия и их обозначают аббревиатурой GMP. Вообще программисты любят аббревиатуры, например, SOLID, DRY, KISS.

Но что значит GMP в контексте Go? Может быть Горутина Материнской Платы? Скорее всего нет. Попробуйте дать ответ сами, прежде чем смотреть ответ.

➡️ Ответ: в канале с задачами с собесов

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#ReadySetGo
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱8
Как интегрировать ИИ в микросервисы и не положить прод

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

Мы пересобрали курс по AI-агентам под суровые реалии 2026 года. Сместили фокус с базовых концепций на управляемый инжиниринг: как зажать агентов в жёсткие рамки лимитов, настроить роутинг и не дать им выжрать всю память и бюджет.

Что в программе для сурового бэкенда:

— продвинутый RAG: подготовка разнородных данных к промышленным нагрузкам;
— контроль состояний: time-travel, восстановление систем после сбоев и runbooks;
— экономика агентов: ограничение вычислительных ресурсов, кэширование и динамический роутинг;
— интеграции: работа агентов с legacy-интерфейсами и визуальными подтверждениями;
— безопасность: деплой с учётом изоляции доменов и требований 152-ФЗ.

До 28 февраля по промокоду Agent действует скидка 10 000 рублей.

Включайтесь в акцию «3 курса по цене 1» — забирайте агентов и ещё два курса бесплатно.

Прокачать архитектуру ИИ-решений
😁1🤔1🥱1
💡 Конкурентность в Go

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

Конкурентность ≠ параллелизм

Конкурентность — это структура программы, где задачи продвигаются независимо.

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

Go даёт инструменты конкурентности, а параллелизм — уже дело железа и планировщика.

Почему не потоки

Обычный OS-поток весит ~1 МБ памяти и дорого переключается. Тысячи потоков — и планировщик ОС уже задыхается.

Горутина стартует с ~2 КБ стека, растёт динамически, создаётся и уничтожается молниеносно. Go-рантайм мультиплексирует тысячи горутин на маленький пул OS-потоков. Запустить 100 000 горутин — норма. 100 000 потоков — трэш.

Общение вместо общей памяти

Классика с потоками — общая память + мьютексы + гонки данных. Go предлагает другой подход:
Не общайтесь через общую память — передавайте данные через общение


Канал — типизированный конвейер для передачи данных между горутинами.

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

Одно слово go — и задача живёт своей жизнью. Никакого церемониала, никакого страха.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13👍5
👩‍💻 Гендерный разрыв в IT

Женщины в российском IT зарабатывают в среднем 99 тысяч рублей, мужчины — 156 тысяч. Разрыв в 40% выглядит тревожно, но объяснить его одной лишь дискриминацией не получится.

Где начинается реальное неравенство, а где просто статистика — разбираемся в статье 👈

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика
Please open Telegram to view this post
VIEW IN TELEGRAM
😁12🤔62🥱1🌚1
🐹 Высоконагруженные AI-агенты: инжиниринг вместо промпт-инжиниринга

В 2026 году AI-системы становятся частью высоконагруженной инфраструктуры. Для Go-разработчика это означает вызовы в области управления ресурсами, токенами и задержками. Наш обновлённый курс сфокусирован именно на технической стороне вопроса.

📚 В обновлённой программе:

— экономика агентов: управление затратами, кэшированием и эффективным роутингом;
— продвинутый RAG: методы улучшения поисковых запросов в промышленной эксплуатации;
LangGraph: построение сложных цепочек решений с контролем промежуточных состояний;
— безопасность и закон: работа с конфиденциальными данными в рамках 152-ФЗ.

Материалы для подготовки уже ждут вас — начните изучение фундамента агентов прямо сейчас.

Специальные условия до 28 февраля:

— введите промокод Agent для получения скидки 10 000 рублей**;
— участвуйте в **акции «3 курса по цене 1» — выберите два любых курса в дополнение к основному.

👉 Получить доступ к курсу и подаркам
😢2🥱21😁1
🎉 Завтра понедельник, но выходной

А значит можно наконец:

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

💬 Что выбираете? 👇

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoTalk
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
🪟 HTML-формы из Go-структур

Если вы пишете веб-приложения на Go и устали вручную рендерить HTML-формы — посмотрите на эту библиотеку.

go-form генерирует формы автоматически: берёт Go-структуру и отдаёт готовый HTML.

Как это работает

Описываете форму как обычную структуру:
type LoginForm struct {
Username string `form:"input,text" label:"Имя пользователя" required:"true"`
Password string `form:"input,password" label:"Пароль" required:"true"`
Email string `form:"input,email" label:"Email" required:"true"`
}


Подключаете шаблон и рендерите:
f := form.NewForm(templates.BootstrapV5)
funcMap := f.FuncMap()
tmpl := template.Must(
template.New("form").Funcs(funcMap).Parse(`{{ form_render .Form nil }}`),
)


Готово — форма с лейблами, плейсхолдерами и валидацией.

Что внутри

Поддерживаемые типы полей: text, password, email, number, date, datetime-local, time, color, range, hidden, search, url, tel, checkbox, radio, dropdown, textarea, multicheckbox.

Три готовых стиля оформления:

• Plain HTML — минимум стилей
• Bootstrap 5 — стандартная Bootstrap-разметка
• Tailwind CSS v3 — классы Tailwind

CSRF-защита — встроенная, с поддержкой middleware для стандартного http.ServeMux и Chi-роутера. Токены автоматически генерируются, проверяются и обновляются.

➡️ Репозиторий

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
11🤔6👍3
⚡️ Быстрый старт без лишних шагов

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

Для одного файла:
go run main.go


Для проекта с несколькими файлами:
go run .


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

Да, для продакшена всё равно нужен go build — бинарник быстрее стартует и проще деплоить. Но на этапе разработки и экспериментов go run — это про скорость мышления, а не скорость компилятора.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱186😁2
⚙️ unsafe.Add вместо ручной арифметики указателей

В Go есть анализатор unsafefuncs, который находит в коде ручную арифметику с указателями и предлагает заменить её на вызовы функций-хелперов из пакета unsafe.

Паттерн unsafe.Pointer(uintptr(ptr) + uintptr(n)) заменяется на unsafe.Add(ptr, n).

Функция unsafe.Add появилась в Go 1.17 именно для того, чтобы убрать громоздкое приведение типов, которое легко написать неправильно.

Цепочка uintptr(ptr) + uintptr(n) — это арифметика над голыми числами, и GC не знает, что тут был указатель.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
🧑‍💻 Вопрос сообществу

Гоферы, вопрос к вам:
Используете ли вы Windows в качестве основной ОС для разработки на Go?


Как вам опыт? Всё работает гладко, или предпочитаете Linux/macOS?

Расскажите в комментариях — особенно интересно, как вы решаете вопросы с тулингом, WSL и окружением.

📍 Навигация: ВакансииЗадачиСобесы

🐸 Библиотека Go-разработчика

#GoTalk
Please open Telegram to view this post
VIEW IN TELEGRAM