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

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

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

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

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

#WXSSA
Download Telegram
Дайджест недели

Представляем подборку материалов и новостей недели.

HTML-формы из Go-структур

Убрать из Windows 11 всё лишнее

Excelize 2.10.1

Go наконец-то получит обобщённые методы

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

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

#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Стек — это только инструмент. Готов ли ты стать кофаундером продукта? 🚀

Энтерпрайз даёт стабильность, но часто забирает драйв. Proglib App предлагает другое: роль технического лидера в EdTech-платформе. Мы обучаем разработчиков через курсы, квизы и ИИ-агентов. MVP готов, юзеры учатся.

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

🛠️ Стек (современный Fullstack):

TypeScript, React 18, Express 5, PostgreSQL, Drizzle ORM.

Почему это вызов для тебя:

Никакой бюрократии: ты и основатель (он тоже кодит) решаете всё сами. • Инструменты будущего: активное использование Claude Code и Cursor. • Масштаб: путь от MVP до лидера рынка образовательных платформ.

Ожидания:

• Крепкий бэкграунд в разработке и проектировании БД. • Готовность быстро включиться в работу с TS/React/Node.js. • Автономность и продуктовое мышление.

Удалёнка, гибкий график, отсутствие «стеклянного потолка».

Готов сменить привычный цикл обновлений на драйв кофаундера? Пиши в бота 👇

@proglibrary_feedback_bot
😁71
✏️ Записывайте сразу — или будете искать снова

Вы когда-нибудь тратили час на то, чтобы разобраться с задачей, которую уже решали год назад? Нашли нужный инструмент, выставили настройки, сделали всё как надо — и не записали. А теперь начинаете с нуля.

Выход простой: место, куда вы складываете «как я это делал». Не сложная система, не красивый Notion. Просто текстовые заметки с поиском.

Что туда стоит записывать:

— настройки программ, к которым редко возвращаетесь
— процессы с неочевидными шагами
— всё, что вы искали больше одного раза

Чтобы это работало, важны три вещи

Одно место. Не пять приложений — одно. Apple Notes, папка с файлами, что угодно с поиском внутри.

Один тег. Помечайте каждую такую заметку одинаково — например #howto. Тогда все инструкции найдутся за секунду.

Точное название. Подумайте: какое слово вы введёте в поиск через год, когда снова понадобится этот процесс? Оно должно быть в заголовке. «Как написать middleware для JWT в Gin» — работает. «Как добавить авторизацию» — нет.

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

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

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
💡 Вам не нужна Kafka

Большинство команд берут Kafka не потому что нужно, а потому что это звучит солидно на митинге по архитектуре.

Kafka это серьёзная технология. Миллионы сообщений в секунду, replay истории, десятки потребителей.

Но вместе с этим вы берёте на себя:
ZooKeeper или KRaft с миграцией, управление брокерами и ребалансировку партиций, schema registry, координацию consumer groups, мониторинг lag и дискового пространства.

И если ваша задача «отправить уведомление при создании заказа», вы платите за распределённые системы там, где хватило бы одного вечера.

Три вопроса перед тем, как тянуться к Kafka

Сколько сообщений вы обрабатываете? Если это тысячи в день, хорошо настроенный Postgres тянет десятки тысяч записей в секунду. Redis Streams справляется с 10–100k событий в секунду без отдельной команды ops.

Нужно ли вам воспроизведение событий? Это настоящее преимущество Kafka. Но если ваши потребители не хранят состояние, вы платите за функцию, которой не пользуетесь.

Сколько у вас независимых потребителей? Для 1–5 потребителей простой pub/sub закрывает задачу.

Что работает вместо Kafka

Transactional Outbox на Postgres. Пишете бизнес-данные и событие в одной транзакции в таблицу outbox. Отдельный воркер опрашивает её и публикует сообщения.
tx, _ := db.Begin()
tx.Exec(`INSERT INTO orders (id, user_id, total) VALUES ($1, $2, $3)`, orderID, userID, total)
tx.Exec(`INSERT INTO outbox (id, event_type, payload, created_at)
VALUES ($1, $2, now())`, uuid.New(), "order.placed", payload)
tx.Commit()


Redis Streams. Поддерживает группы потребителей, постоянное хранение сообщений, подтверждения и семантику доставки «хотя бы один раз». Даёт 90–95% от того, что даёт Kafka. И, скорее всего, Redis у вас уже есть.
// Produce
rdb.XAdd(ctx, &redis.XAddArgs{
Stream: "orders",
Values: map[string]interface{}{"order_id": orderID, "user_id": userID},
})

// Consume с consumer group
msgs, _ := rdb.XReadGroup(ctx, &redis.XReadGroupArgs{
Group: "notifications",
Consumer: "worker-1",
Streams: []string{"orders", ">"},
Count: 10,
}).Result()


Когда Kafka оправдана

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

➡️ Источник | Зеркало

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

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

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🤔12😁42
🛠 Массивы — фиксированные и быстрые

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

Объявление массива фиксирует его размер навсегда. Пять элементов — значит пять, не больше и не меньше.
arr := [5]int{10, 20, 30, 40, 50}


Обращение к элементам стандартное. Первый элемент через нулевой индекс, последний через len(arr)-1:
arr[0]           // 10
arr[len(arr)-1] // 50


Изменить значение так же просто:
arr[0] = 100


Перебор элементов

Два способа. Классический цикл через индекс:
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}


И через range:
for i, v := range arr {
fmt.Printf("Index: %d, Value: %d\n", i, v)
}


Если индекс не нужен, его заменяют на _.

Главная ловушка

Массивы в Go это значения, не ссылки. При присваивании создаётся полная копия:
a := [3]int{1, 2, 3}
b := a // b это отдельная копия
b[0] = 100

fmt.Println(a[0]) // 1 — не изменился
fmt.Println(b[0]) // 100


a и b живут независимо. Изменения в одном не затрагивают другой.
Это работает не так, как в Python или JavaScript, где присваивание массива передаёт ссылку. В Go это всегда копия.

Если передать большой массив в функцию, Go скопирует его целиком. Для небольших данных это нормально. Для больших лучше использовать срезы или передавать указатель:
func process(arr [1000]int) { ... }  // копирует 1000 элементов
func process(arr *[1000]int) { ... } // передаёт указатель


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

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

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

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤‍🔥64
🔄 Массивы переехали и fuzz-тесты добавлены в mus-go

mus-go — это библиотека для бинарной сериализации на Go. Она реализует формат MUS, который делает упор на компактность и скорость.

Вместо JSON или протобафа вы получаете минималистичный бинарный формат с нулевым аллоцированием при десериализации и поддержкой версионирования данных.

В v0.8.0 три изменения. Одно из них ломает обратную совместимость.

Перенос array.go в пакет unsafe

Это единственное breaking change в релизе. Файл array.go переехал из пакета ord в пакет unsafe. Логика правильная, ведь реализация там и была небезопасной, просто лежала не там.

Fuzz-тестирование

Добавили нативные fuzz-тесты. Битые или специально сформированные байты не должны приводить к панике или неожиданному поведению. Теперь это проверяется автоматически.

Обслуживание

Обновили зависимости common-go и mok до актуальных версий. Папка testdata переименована в testutil — чисто организационное изменение, на код не влияет.

➡️ Release notes

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

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

#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
За простоту не повышают

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

Инженер А смотрит на задачу, выбирает простейшее решение, пишет 50 строк понятного кода и выкатывает за два дня. Инженер Б видит «возможность», он добавляет слой абстракции, pub/sub для коммуникации между компонентами, конфигурационный фреймворк для «расширяемости». Три недели, несколько PR, восторженные эмодзи в слаке.

Приходит время повышения. Б пишет так: «Спроектировал event-driven архитектуру, создал переиспользуемый абстрактный слой, внедрил конфигурационный фреймворк».

У А написать нечего. «Реализовала фичу X». Три слова. Её работа была лучше — но невидима.

Что делать инженеру

Простоту нужно делать видимой. «Рассмотрели три подхода включая event-driven архитектуру, определила что прямолинейная реализация покрывает все текущие и прогнозируемые требования, выкатила за два дня, ноль инцидентов за шесть месяцев» — это то же самое решение, просто описанное честно.

Решение не строить что-то — это тоже решение. Документируйте его.


Сложность сама по себе — не враг. Если вы обрабатываете миллионы транзакций — распределённые системы нужны. Проблема в незаработанной сложности.

➡️ Источник

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

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

#GoTalk
Please open Telegram to view this post
VIEW IN TELEGRAM
👍216🔥31
🍕 Топ-вакансий для Go-разработчиков за неделю

Senior Golang разработчик (команда Campaigner) — Удаленно

Middle Golang — от 284 300 ₽, удаленно

Middle Golang — от 280 000 ₽, тоже удаленно

Бустер — удалённо (не только Москва)

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

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

#GoWork
Please open Telegram to view this post
VIEW IN TELEGRAM
📎 Делаем примитивы говорящими

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

Представьте функцию в платёжной системе:
func Transfer(amount float64, currency, fromAccount, toAccount string) error


Четыре параметра разных смыслов, но компилятор видит просто float64 и три string. Перепутать аргументы местами проще, чем кажется.

Проблема в том, что string и float64 не несут никакой семантики. Это просто формы данных. Является ли строка кодом валюты, номером счёта или чем-то ещё — известно только из документации, которую никто не читает в спешке.

Решение простое:
type Amount float64
type Currency string
type AccountNumber string

func Transfer(amount Amount, currency Currency, from, to AccountNumber) error {
// реализация
}


Теперь передать сумму туда, где ждут номер счёта, физически невозможно:
// Это не скомпилируется
Transfer(AccountNumber("ACC-001"), Currency("USD"), Amount(100.0), ...)

// А это читается без комментариев
Transfer(
Amount(100.0),
Currency("USD"),
AccountNumber("ACC-001"),
AccountNumber("ACC-002"),
)


Следующий шаг — валидация прямо в конструкторе типа. Отрицательная сумма перевода не должна существовать в системе как валидное значение:
func NewAmount(v float64) (Amount, error) {
if v <= 0 {
return 0, fmt.Errorf("сумма должна быть больше нуля, получено: %v", v)
}
return Amount(v), nil
}

var supportedCurrencies = map[string]bool{
"USD": true, "EUR": true, "RUB": true,
}

func NewCurrency(s string) (Currency, error) {
if !supportedCurrencies[strings.ToUpper(s)] {
return "", fmt.Errorf("неподдерживаемая валюта: %s", s)
}
return Currency(strings.ToUpper(s)), nil
}


type Amount float64 создаёт не синоним, а новый несовместимый тип. Передать обычный float64 туда, где ждут Amount, без явного приведения не выйдет.

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

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

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

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍289🤔4
🤔 Спам тимлидам, фейковые офферы и приукрашенное резюме

IT-рынок 2026 года — это не конкурс честных и талантливых. Компании говорят об экологичной культуре, а сами гостят после четырёх этапов отбора.

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

➡️ Узнать приёмы тех, кто смог

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

🐸 Библиотека Go-разработчика
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
😁6
👍 На курсе по контролируемой разработке AI-агентов мы будем разбирать ровно то, о чём говорит Владислав в голосовом, но уже в формате системной практики.

📅 Старт курса — 20 апреля.

Если хотите разобраться, как строить управляемые агентные системы:
➡️ Присоединяйтесь.

P.S. С первого занятия будет практика: код и разбор реальных ошибок, а не только теория.
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱5👍1
🔄 Go 1.26.1 и 1.25.8

Вышли новые версии Go. Ничего революционного, просто патчи безопасности.

В crypto/x509 нашли проблему с проверкой email-адресов в сертификатах. Когда сертификат содержит несколько ограничений на emai система игнорирует все ограничения кроме последнего.

В html/template нашли проблему с экранированием URLs в meta-тегах. Если у вас в контенте есть refresh meta-тег и вы туда подставляете какой-то URL через действия шаблона, он не будет экранирован.

net/url.Parse оказывается принимал невалидные IPv6-адреса, потому что недостаточно проверял хост-компонент. Теперь IPv6-литералы должны стоять в начале хоста, остальное будет отклонено.

➡️ Анонс

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

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

#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍86🔥1😁1
👨‍💻 Горутины живут своей жизнью: как не создать утечку памяти

Горутины дешёвые, но не бесплатные. Каждая занимает минимум 2KB памяти. Когда запускаете сотни или тысячи горутин, это становится ощутимо. Но главная проблема не в памяти, а в том, что горутина может зависнуть и никогда не завершиться.

Проблема с time.Sleep

Часто видим такой паттерн:
func Job(d time.Duration) {
for {
doWork()
time.Sleep(d)
}
}


На первый взгляд это удобно. Но когда приложение получает SIGTERM и нужно выключиться, горутина может быть посередине sleep. Она просто проигнорирует сигнал выключения и продолжит спать. Graceful shutdown не будет таким graceful.

time.Sleep не знает про контекст и не может быть прерван. Поэтому используйте context:
func Job(ctx context.Context, d time.Duration) {
for {
select {
case <-ctx.Done():
return
default:
doWork()
time.Sleep(d)
}
}
}


Теперь горутина проверит контекст перед каждой итерацией. Если приложение выключается, context будет отменён и горутина выйдет. Даже если она посередине sleep, следующая итерация её закроет.

Утечки через каналы

Вот другой сценарий:
func worker(jobs <-chan int) {
for i := range jobs {
process(i)
}
}

jobs := make(chan int)
go worker(jobs)


Выглядит просто. Закроем канал jobs и горутина выйдет. Но что если где-то в коде забыли закрыть канал? Горутина будет ждать бесконечно. Даже не упадёт, просто повиснет в памяти. Утечка.

Часто это происходит, когда забывают про defer или неправильно структурируют код. Горутина ждёт данных из канала, но никто их туда не отправляет.

Как правильно

Главное правило: сделайте очевидным, когда горутина стартует и когда заканчивается. Не надо полагаться на магию вроде автоматического закрытия канала.

Передавайте context во все горутины, которые крутятся долго. Используйте select с <-ctx.Done(). Явно закрывайте каналы, по которым читаете. Не создавайте горутины просто так, всегда планируйте как их остановить.

Если горутина может зависнуть, добавьте таймаут:
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()

go worker(ctx, jobs)


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

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

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

#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1611
Что выведет код

В коде есть функция вывода, но успеет ли она отработать до выхода из прогарммы?

➡️ Ответ смотрите по ссылке

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

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

#ReadySetGo
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔4🔥3😁1
💿 Ещё одна ORM для Go

Берешь популярную ORM, она обещает удобство, а потом выясняется, что код либо медленный, либо писать его больнее, чем на сыром SQL. Ent от Meta подходит к проблеме иначе.

Вместо того чтобы выбирать между скоростью и удобством, Ent просто генерирует тебе type-safe код прямо из схемы. Пишем структуру в Go, и она автоматически становится слоем работы с БД.

Полезные фичи

Поддержка PostgreSQL JSONB из коробки. Если нужны гибкие структуры данных, не нужно городить велосипед с отдельной таблицей или JSON-полем, которое трудно индексировать.

Миграции генерируются автоматически. Меняете схему, и CLI сам создает SQL. Конечно, проверить стоит, но руки уже не болят от написания однотипного кода.

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

Вот как выглядит код на практике:
client.User.
Create().
SetName("Aashish").
SetEmail("aashish@example.com").
Save(ctx)


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

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

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

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

#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍147🥱2
💥 Открытый вебинар | ИИ-агенты в продакшене: от хайпа к деньгам

Агенты уже везде. Но мало кто признаётся, сколько денег сжёг на бесконечных циклах, галлюцинациях в RAG и отсутствии мониторинга.

Полина Полунина, руководитель AI-направления Альфа-Банка, расскажет честно:

▪️ Чем агент отличается от «просто GPT с промптом» и когда бизнесу достаточно обычного LLM
▪️ 3 реальных кейса из корпоративной среды: что взлетело, а что нет
▪️ Live-демо работающего агента
▪️ ТОП-5 граблей, на которые наступают команды при внедрении

⏱️ 10 марта в 19:00 (МСК)

🎁 Участники получат промокод на скидку на самый полный курс по ИИ-агентам

👉 Регистрируйся
💃 Дайджест недели

Пришло время собрать интересные материалы первой недели весны.

Go 1.26.1 и 1.25.8

Вам не нужна Kafka

mus-go обновился

За простоту не повышают

Спам тимлидам, фейковые офферы и приукрашенное резюме

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

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

#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
1