en
Feedback
Библиотека Go-разработчика | Golang

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

Open in Telegram

Все самое полезное для Go-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/32d20779 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0 #WXSSA

Show more

📈 Analytical overview of Telegram channel Библиотека Go-разработчика | Golang

Channel Библиотека Go-разработчика | Golang (@goproglib) in the Russian language segment is an active participant. Currently, the community unites 24 019 subscribers, ranking 5 674 in the Technologies & Applications category and 27 915 in the Russia region.

📊 Audience metrics and dynamics

Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 24 019 subscribers.

According to the latest data from 05 June, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by 51 over the last 30 days and by 6 over the last 24 hours, overall reach remains high.

  • Verification status: Not verified
  • Engagement rate (ER): The average audience engagement rate is 10.51%. Within the first 24 hours after publication, content typically collects 7.82% reactions from the total number of subscribers.
  • Post reach: On average, each post receives 2 524 views. Within the first day, a publication typically gains 1 879 views.
  • Reactions and interaction: The audience actively supports content: the average number of reactions per post is 9.
  • Thematic interests: Content is focused on key topics such as навигация, лучшее_из_библиотеки_2025, git, string, golive.

📝 Description and content policy

The author describes the resource as a platform for expressing subjective opinions:
Все самое полезное для Go-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/32d20779 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0 #WXSSA

Thanks to the high frequency of updates (latest data received on 07 June, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.

24 019
Subscribers
+624 hours
-107 days
+5130 days
Posts Archive
🤩 Разбор строк через strings.Cut Часто строку нужно разрезать ровно один раз по разделителю. Так делят почту на имя и домен, заголовок на ключ и значение, путь на префикс и остаток. Раньше для этого брали strings.Index или strings.Split, и оба варианта тянули за собой лишний код с проверкой границ. В Go 1.18 появился strings.Cut, который закрывает этот случай одной строкой. strings.Index возвращает позицию разделителя или -1, если его нет. Дальше нужно вручную проверять результат и аккуратно нарезать строку по смещениям, не выходя за границы. Старый способ:
i := strings.Index(email, "@")
if i < 0 {
    return "", "", false
}
username := email[:i]
domain := email[i+1:]
Три строки на нарезку плюс отдельная проверка на -1. Если забыть про +1, в домен попадёт сам символ разделителя. Современный способ:
username, domain, found := strings.Cut(email, "@")
Функция возвращает часть до разделителя, часть после него и флаг found. Если разделителя нет, found будет false, а первой частью вернётся вся исходная строка. Чем отличается от `strings.Split` strings.Split режет строку по всем вхождениям и возвращает срез. Когда разрез нужен один, приходится брать SplitN с лимитом и потом разбирать срез по индексам. strings.Cut сразу отдаёт две именованные части и не выделяет срез под результат, поэтому работает экономнее. Практический пример Разбор строки заголовка вида Content-Type: application/json выглядит так:
key, value, ok := strings.Cut(header, ": ")
if !ok {
    return fmt.Errorf("invalid header: %q", header)
}
key = strings.TrimSpace(key)
value = strings.TrimSpace(value)
Флаг ok сразу отделяет корректные строки от мусора, без ручной возни с индексами. Используйте strings.Cut везде, где строку нужно разделить ровно один раз, а Split оставьте для случаев с множеством вхождений. Код станет короче, а ошибок с границами среза не будет. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoToProduction

📰 Первый летний дайджест Короткий, как и отпуск.. — Go закрыл три уязвимости Вышли версии Go 1.26.4 и 1.25.11. Закрывают три
📰 Первый летний дайджест Короткий, как и отпуск.. Go закрыл три уязвимости Вышли версии Go 1.26.4 и 1.25.11. Закрывают три уязвимости в стандартной библиотеке. — Go может разрешить превращать функции в интерфейсы с одним методом В трекере Go обсуждают предложение #47487. Оно разрешает приводить значение функции к интерфейсу с ровно одним методом, если сигнатура функции совпадает с сигнатурой этого метода. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoLive

🧑‍💻 Конструктор, из которого собран Docker Когда вы запускаете контейнер, под капотом работает движок. Писать такой движок
🧑‍💻 Конструктор, из которого собран Docker Когда вы запускаете контейнер, под капотом работает движок. Писать такой движок с нуля никто не хочет, там слишком много низкоуровневой возни с неймспейсами, cgroups, образами и сетью. Moby — это открытый проект, который Docker вынес в апстрим, набор готовых компонентов для сборки систем на контейнерах. Из этих кубиков собран сам Docker, и из них же вы можете собрать что-то своё. ➡️ Что внутри. Moby это не одна программа, а коллекция компонентов с понятными API, среди них движок выполнения контейнеров, инструменты сборки образов, работа с реестром и оркестрация. Идея в том, чтобы каждый кусок имел чёткую функцию и при желании заменялся на другой. ➡️ Как с ним работать. Чаще всего вы общаетесь с движком через Docker CLI, но из Go можно дёргать тот же Engine API напрямую. Вот аналог docker ps, который читает настройки из переменных окружения вроде DOCKER_HOST и сам согласует версию API с демоном:
package main

import (
  "context"
  "fmt"
  "log"

  "github.com/moby/moby/client"
)

func main() {
  apiClient, err := client.New(client.FromEnv)
  if err != nil {
    log.Fatal(err)
  }
  defer apiClient.Close()

  result, err := apiClient.ContainerList(context.Background(), client.ContainerListOptions{
    All: true,
  })
  if err != nil {
    log.Fatal(err)
  }

  for _, ctr := range result.Items {
    fmt.Printf("%s  %s  %s\n", ctr.ID, ctr.Status, ctr.Image)
  }
}
Этого хватает, чтобы из своего сервиса запускать контейнеры, тянуть образы, читать логи и управлять сетью, то есть делать всё то же, что умеет команда docker. ➡️ Кому это нужно. Moby рассчитан на инженеров и энтузиастов, которым интересно ковыряться в открытом коде, чинить баги и строить системы на контейнерах. Если коротко, Moby это фундамент Docker, открытый и модульный. Брать его стоит тогда, когда вам мало готового движка и хочется собрать или допилить свой. ➡️ Репозиторий 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoToProduction

Попросил нейронку написать счётчик сотрудников.. 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max 🐸 Библиотека Go-разр
Попросил нейронку написать счётчик сотрудников.. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoGiggle

📎 Чего не дают логи, метрики и трейсы Идея «три столпа наблюдаемости» звучит убедительно. Соберите логи, метрики и трейсы, отправьте в одну платформу, и поймёте систему. На практике у команды есть все три, а баг в проде она всё равно не находит. Ниже главные мысли статьи о том, почему так выходит, с примерами на Go. 🖇 Данные есть, понимания нет Три столпа дают сигналы, но не объяснение. На инциденте вы коррелируете то, что собрали заранее, часто в спешке, и этого набора не хватает под конкретный сбой. 🖇 Высокая кардинальность бьёт первой Как только вам нужен разрез по user_id, арендатору или связке эндпоинт плюс регион, метрики ломаются. Так делать не стоит, потому что число рядов взрывается:
// Плохо. user_id и tenant дают почти неограниченное число комбинаций.
httpRequests := prometheus.NewCounterVec(
    prometheus.CounterOpts{Name: "http_requests_total"},
    []string{"endpoint", "region", "user_id", "tenant"},
)
httpRequests.WithLabelValues(endpoint, region, userID, tenant).Inc()
Безопаснее держать в метках только ограниченный набор значений, а детали уносить в трейс или лог:
// Лучше. В метках только то, у чего мало возможных значений.
httpRequests := prometheus.NewCounterVec(
    prometheus.CounterOpts{Name: "http_requests_total"},
    []string{"endpoint", "region", "status"},
)
httpRequests.WithLabelValues(endpoint, region, status).Inc()
🖇 Инструментация видит только ожидаемое Вы измеряете то, что предусмотрели заранее. Новый тип сбоя не попадает ни в один график, и в этот момент вы слепы. 🖇 Худшие баги живут между сервисами Два микросервиса по своим метрикам здоровы, задержки в трейсах нормальные, логи чистые. А вместе они выдают неверный ответ. Проблема в связи между ними, и ни одна отдельная метрика её не ловит. 🖇 Зелёные метрики не значат правильный результат Три столпа описывают инфраструктуру, а не бизнес. Сервис может держать отличную задержку и нулевые ошибки, при этом считать цену неверно. Поэтому полезно мерить сам бизнес-результат, а не только технику:
// Считаем не задержку, а расхождение цены. Это и есть семантическая наблюдаемость.
span.SetAttributes(
    attribute.String("order.id", order.ID),
    attribute.Int64("order.expected_cents", expected),
    attribute.Int64("order.charged_cents", charged),
)
if charged != expected {
    priceMismatchTotal.Inc()
}
🖇 Лучшее улучшение делается после инцидента Самый сильный приём звучит скучно. После разбора спросите, какой информации не хватило, и добавьте её. Часто это пара полей в структурном логе через slog, которых раньше не было:
// После разбора добавили request_id и tenant. Без них инцидент искали вслепую.
slog.Error("payment declined",
    "request_id", reqID,
    "tenant", tenant,
    "provider", provider,
    "code", declineCode,
)
Эффект накапливается, и через год полтора команда отлаживает прод заметно быстрее. Вывод простой. Три столпа это стартовая точка, а не финал. Современные системы грязнее и сильнее завязаны на деньги, поэтому и наблюдаемость нужна с высокой кардинальностью, ориентированная на события и привязанная к бизнес-результату. Наша рассылка даёт максимум за минимум. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoDeep

😎 Знакомьтесь с экспертом Proglib.academy: Senior Software Engineer и Team Lead в Yandex Cloud Роман Барлос Роман — консульт
😎 Знакомьтесь с экспертом Proglib.academy: Senior Software Engineer и Team Lead в Yandex Cloud Роман Барлос Роман — консультант нашего курса «Разработка ИИ-агентов». Он работает на стыке cloud-native архитектуры и AI, активно внедряя современные ИИ-подходы в реальные процессы разработки. За что его ценит IT-комьюнити? 🟣 Team Lead и AI-евангелист в команде UX Yandex Cloud
14-лет в разработке. Занимается AI-адопшеном в команде Yandex Cloud, проводит мастер-классы и продвигает лучшие практики для повышения эффективности разработчиков.
🟣 Техлид Sourcecraft Code Assistant
С сильным практическим бэкграундом принимал участие как технический лид в создании мощного AI-расширения для VS Code.
🟣 Создатель полезного Open Source
Разрабатывает утилиты, которые позволяют быстро начать эксперименты с инференсом и агентами в локальном окружении: например, набор скриптов vllm-setup для быстрого запуска окружения и mini-proxy — минималистичный прокси для OpenAI API провайдеров.
🟣 Автор интерактивных ML-визуализаций
Объясняет сложные концепции наглядно. Создал серию залипательных обучающих материалов, где можно вживую пощупать работу сетей Хопфилда, машин Больцмана и VC-размерности.
Роман регулярно делится инженерными наработками, инсайтами и экспертизой в своем авторском Telegram-канале На курсе Роман выступает консультантом программы: он помогает формировать содержание уроков с опорой на актуальные инженерные практики и жесткие требования индустрии. Узнать больше о программе и разработке автономных систем: 👉 Курс «Разработка ИИ-агентов» Так, продолжаем знакомить вас с командой? 👍 — Да, ждем новых лиц 🔥 — Жду полезные материалы от Романа

Можно ли использовать слайс как ключ в мапе Вопрос на первый взгляд простой, но именно такие мелочи отделяют тех, кто Go использует, от тех, кто Go понимает. Прежде чем лезть в документацию — подумайте сами. Вот что стоит вспомнить: 🔹 В Go ключ мапы должен быть comparable — то есть поддерживать операции == и != 🔹 Спросите себя: можно ли сравнить два слайса через ==? Что вообще значит «два слайса равны»? ➡️ Ответ 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #ReadySetGo

📎 Обёртывание ошибок через %w В Go 1.13 появился %w, который сохраняет исходную ошибку внутри обёртки и позволяет проверять её дальше по коду через errors.Is и errors.As. Когда ошибка проходит через несколько слоёв приложения, на каждом уровне к ней добавляют контекст. Если при этом теряется исходный тип, наверху остаётся только текст, и проверить причину можно лишь по подстроке. Любая правка формулировки ломает такую проверку. Старый способ:
fmt.Errorf("failed to fetch user: %v", err)
%v подставляет текст ошибки и выбрасывает сам объект. Узнать, что под капотом лежала sql.ErrNoRows, после этого уже нельзя. Современный способ:
fmt.Errorf("failed to fetch user: %w", err)
%w оборачивает ошибку и сохраняет ссылку на оригинал, поэтому цепочку потом можно размотать. Как проверять причину errors.Is идёт по всей цепочке обёрток и сравнивает каждое звено с конкретным значением:
if errors.Is(err, sql.ErrNoRows) {
    // пользователь не найден
}
Не важно, сколько слоёв обёрток сверху, проверка доберётся до нужной ошибки. Когда нужен сам объект Если требуется не просто факт совпадения, а доступ к полям ошибки, помогает errors.As. Он находит в цепочке ошибку нужного типа и записывает её в переменную:
var pathErr *os.PathError
if errors.As(err, &pathErr) {
    slog.Error("ошибка пути", "path", pathErr.Path)
}
Своя ошибка в цепочке Чтобы ваш тип распознавался через errors.Is и errors.As, достаточно реализовать метод Unwrap:
type AppError struct {
    Code int
    Err  error
}

func (e *AppError) Unwrap() error { return e.Err }
%w заменил хрупкое сравнение строк на надёжную проверку по значению и по типу. Оборачивайте ошибки этим глаголом везде, где добавляете контекст, и используйте errors.Is вместо сравнения текста. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoToProduction

🫳 Типичная микросервисная архитектура 🫳 Постоянно слышу, что монолит - это прошлое, а микросервисы, типа единственный путь
🫳 Типичная микросервисная архитектура 🫳 Постоянно слышу, что монолит - это прошлое, а микросервисы, типа единственный путь к успеху. Все ищут ту самую структуру, которая позволит масштабироваться до бесконечности. На схеме классический скелет современной системы. Выглядит разумно, но без четкого понимания каждый блок может стать точкой отказа:API Gateway Единая точка входа для всех клиентов. Итог: если гейтвей "прилег" или перегружен, твои крутые микросервисы внизу превращаются в бесполезный набор кода, до которого никто не может достучаться. • Load Balancer Раскидывает трафик, чтобы один сервер не закипел. Итог: всё работает плавно, пока балансировщик правильно настроен. Ошибка в конфиге и весь трафик летит в один сервис, убивая его за секунды. • Service Registry & Discovery Сервисы должны как-то находить друг друга. Итог: если эта штука заглючит, сервис А просто не узнает, где искать сервис Б. Система развалится на куски, которые не умеют общаться. • Разделение по доменам (Domain A / Domain B) У каждого сервиса своя база. Итог: ты получаешь независимость, но платишь за это адом при попытке собрать общую аналитику или сделать сложный транзакционный запрос между доменами. Уже переезжали на микросервисы? ❤️ — да, это было больно, но оно того стоило 🔥 — сидим на монолите и в ус не дуем 🔹 Практический интенсив «Архитектуры и шаблоны проектирования» 🔹 Получить консультацию менеджера 🔹 Сайт Академии 🔹 Сайт Proglib 🏃‍♀️ Азбука айтишника #ликбез

💰 Деньги в Go без потери копеек Как работать с деньгами в Go Дробные типы в Go хранят значения в двоичном виде, и многие дес
💰 Деньги в Go без потери копеек Как работать с деньгами в Go Дробные типы в Go хранят значения в двоичном виде, и многие десятичные дроби в нём не представимы точно. Из-за этого простые суммы дают неожиданный результат, а ошибки копятся с каждой операцией. Ниже разберём, как считать деньги без потери копеек. ℹ️ Почему float64 не подходит Классический пример:
fmt.Println(0.1 + 0.2) // 0.30000000000000004
На одной операции это незаметно, но в отчёте на тысячи позиций расхождение в копейки превращается в расхождение в рубли. Сравнивать такие суммы через == тоже нельзя, потому что равные на бумаге значения в памяти отличаются. 📎 Способ первый. Целые числа в минимальных единицах Самый надёжный приём хранить сумму в наименьшей единице валюты, то есть в копейках или центах, как int64. Целочисленная арифметика точна, сложение и вычитание не теряют ничего:
type Money int64 // сумма в копейках

func (m Money) String() string {
    sign := ""
    if m < 0 {
        sign = "-"
        m = -m
    }
    return fmt.Sprintf("%s%d.%02d", sign, m/100, m%100)
}
Цену 199 рублей 99 копеек вы храните как Money(19999), а метод String собирает её обратно в читаемый вид. Этого подхода хватает для подавляющего большинства задач с фиксированной валютой. 📎 Способ второй. Библиотека shopspring/decimal Целые числа неудобны там, где много делений и процентов, например при расчёте НДС или распределении суммы между участниками. Тут помогает пакет decimal, который хранит число как набор цифр с десятичной точкой и считает в десятичной системе:
import "github.com/shopspring/decimal"

price := decimal.RequireFromString("199.99")
tax := price.Mul(decimal.RequireFromString("0.20"))
total := price.Add(tax).Round(2)

fmt.Println(total.StringFixed(2)) // 239.99
Обратите внимание, что значение задаётся строкой через RequireFromString, а не из float64. Так в число не попадёт двоичная погрешность ещё на входе. 📎 Округление и деление При делении суммы остаток никуда не девается, и его нужно осознанно куда-то отнести. decimal позволяет задать правило округления явно:
total := decimal.RequireFromString("100.00")
share := total.Div(decimal.NewFromInt(3)).Round(2)
fmt.Println(share.StringFixed(2)) // 33.33
Сумма трёх таких долей даст 99.99, и одну копейку придётся добавить к одной из частей вручную. Это не баг библиотеки, а свойство самих денег, и решать его нужно по правилам вашей предметной области. Для денег в Go не используйте float64 и точка. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoDeep

🌐 Пакет из стандартной библиотеки Go, про который почти никто не знает Он даёт хуки внутрь исходящего HTTP-запроса — туда, к
🌐 Пакет из стандартной библиотеки Go, про который почти никто не знает Он даёт хуки внутрь исходящего HTTP-запроса — туда, куда снаружи не заглянуть: • DNS lookup: начало и конец • TCP connect • TLS handshake • Момент получения первого байта ответа • Факт переиспользования соединения Вся магия через контекст: трейс кладётся в ctx, транспорт сам его достаёт. Никаких интерфейсов, никакого middleware. Что можно собрать за пару строк: 1. curl-like тайминги
fmt.Printf("DNS: %v\n", dnsDone.Sub(dnsStart))
fmt.Printf("TLS: %v\n", tlsDone.Sub(tlsStart))
fmt.Printf("TTFB: %v\n", firstByte.Sub(gotConn))
2. Логирующий RoundTripper Оборачиваете транспорт, в каждом запросе автоматически пишутся тайминги. Одна инициализация и всё. Лайфхак: GotConnInfo.Reused = false на каждом запросе к одному хосту = где-то не закрывается тело ответа. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoToProduction

❔Готовишься к собеседованию по Go — или просто хочешь понимать тонкости языка? 🙂Тогда этот канал для тебя. Задачи с реальных
Готовишься к собеседованию по Go — или просто хочешь понимать тонкости языка? 🙂Тогда этот канал для тебя. Задачи с реальных собеседований, разбор подводных камней языка и честно про рынок. Как выглядит твоё резюме глазами нанимателя и что спрашивают прямо сейчас в топовых компаниях 👍 Подписывайся, если хочешь расти в Golang! ПОДПИСАТЬСЯ ПОДПИСАТЬСЯ Реклама. Урин Дмитрий Алексеевич, ИНН 760404084194. Erid 2Vtzqvb278C

👨‍💻Структурное логирование в Go через slog До версии 1.21 в Go не было единого подхода к логированию. Команды выбирали между сторонними библиотеками вроде zap, logrus и zerolog, поэтому кодовая база разных проектов выглядела неодинаково. Стандартный пакет log умел писать только обычные текстовые строки, которые тяжело парсить и собирать в системах вроде Loki или ELK. В Go 1.21 появился slog, который принёс структурное логирование прямо в стандартную библиотеку. Если из всего списка новинок вы захотите взять только одну, берите эту. Какую боль решает Структурные логи это пары ключ значение, а не склеенная строка. Их легко фильтровать, искать по конкретным полям и отдавать в JSON прямо в систему сбора. Раньше ради этого приходилось тянуть внешнюю зависимость, теперь хватает стандартной библиотеки. Старый способ выглядел так:
log.Printf("[ERROR] User %d login failed from IP %s", userID, ip)
Здесь данные смешаны с текстом, и чтобы вытащить userID, нужно писать регулярки. Современный способ:
import "log/slog"

slog.Error("Login failed", "userID", userID, "ip", ip)
Сообщение остаётся читаемым, а данные лежат в отдельных полях. Что он делает slog строится вокруг трёх частей. Logger принимает вызовы вроде Info и Error. Handler решает, куда и в каком формате писать. Attr это пара ключ значение. В комплекте идут два обработчика, TextHandler для человекочитаемого вывода и JSONHandler для машинного. Как настроить JSON вывод Чтобы получать логи в JSON, достаточно подменить обработчик у глобального логгера:
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
slog.SetDefault(logger)

slog.Info("server started", "port", 8080)
На выходе получится строка JSON с полями time, level, msg и port. Её сразу можно отправлять в сборщик логов без дополнительной обработки. Группировка и контекст Часто к каждому запросу удобно прикреплять одни и те же поля. Метод With создаёт логгер с заранее заданными атрибутами:
reqLogger := slog.With("requestID", reqID, "userID", userID)
reqLogger.Info("processing request")
reqLogger.Warn("slow response", "ms", 320)
Теперь requestID и userID попадут в каждую запись без повторного перечисления. Переводить проект можно постепенно, начав с замены log на slog в новых модулях. Старый код при этом продолжит работать, а новые записи сразу станут пригодными для машинного разбора. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoToProduction

Главное не отменить подписку на нашу рассылку 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max 🐸 Библиотека Go-разрабо
Главное не отменить подписку на нашу рассылку 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoGiggle

🤭 Топ-вакансий для Go-разработчиков за неделю Team Lead Go — до 600 000 ₽, удаленно (Москва) Senior Golang Developer — до 400 000 ₽, удаленно (Москва) Middle Golang Developer — Remote (udalyonka) ➡️ Еще больше топовых вакансий — в нашем канале Go jobs 🐸 Библиотека Go-разработчика #GoWork

🔄 Вышли Go 1.26.4 и 1.25.11 с исправлениями безопасности Команда Go выпустила минорные версии 1.26.4 и 1.25.11. Это патч-рел
🔄 Вышли Go 1.26.4 и 1.25.11 с исправлениями безопасности Команда Go выпустила минорные версии 1.26.4 и 1.25.11. Это патч-релизы, которые закрывают три уязвимости в стандартной библиотеке. Если вы используете одну из этих веток, обновиться стоит сразу. ➡️ Проблема в пакете mime. Метод WordDecoder.DecodeHeader имел квадратичную сложность, поэтому специально собранный заголовок с множеством некорректных encoded-word мог съесть процессор. Это CVE-2026-42504. ➡️ Уязвимость в net/textproto. Функции пакета подставляли входные данные в текст ошибки без экранирования, а вход часто приходит от внешней стороны, например когда net/http разбирает заголовки ответа сервера. Через это можно было протащить в чужие логи управляющие байты терминала и вводящий в заблуждение текст. Это CVE-2026-42507. ➡️ Фикс в crypto/x509. Метод VerifyHostname вызывал strings.Split по точке в цикле для каждой записи DNS SAN, и при длинном списке имён проверка росла квадратично, причём даже для недоверенных сертификатов. Это CVE-2026-27145. ➡️ Источник 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoLive

⚡️ Продолжаем знакомить вас с экспертами курса AgentOps! — Сергей Нотевский расскажет, как выстроить FinOps для AI-продуктов:
⚡️ Продолжаем знакомить вас с экспертами курса AgentOps!Сергей Нотевский расскажет, как выстроить FinOps для AI-продуктов: оптимизировать затраты на разработку и продакшен, внедрить model routing, semantic cache и систему алертов для контроля расходов — Эмиль Сатаев разберет Context Engineering: управление контекстом, защиту от prompt injection, работу с длинными контекстами и построение безопасного пайплайна входа для AI-систем — Михаил Бондаревский покажет, как подготовить инфраструктуру для AI-агентов: Docker, sandboxing, streaming, docker-compose и воспроизводимое окружение для разработки и продакшена — Мурат Хажгериев расскажет про Enterprise Integrations & MCP: когда MCP действительно нужен, как подключать внешние сервисы и реализовывать интеграции с OAuth2 delegation — Герман Сабиров разберет Governance & Compliance для AI-систем: data flow, audit logs, требования 152-ФЗ, локализацию данных и построение compliance-подхода на уровне архитектуры Курс для backend-разработчиков, тимлидов и LLM инженеров о том, как внедрять AI-логику в бэкенд IT-продуктов и сохранять стабильность сервиса. 👉 Изучить обновленную программу AgentOps и занять место.

🧑‍💻 Один middleware режет ответ в десять раз Большой JSON без сжатия это лишние мегабайты по сети. На быстром канале незаметно, а пользователь на мобильном интернете ждёт лишние секунды. Лечится одним middleware, который сжимает ответ перед отправкой. Как это работает GZIP хорошо жмёт текст с повторяющимися структурами, а JSON именно такой. Клиент говорит, что умеет принимать сжатое, через заголовок Accept-Encoding: gzip. Сервер сжимает тело, ставит Content-Encoding: gzip и отдаёт. Клиент распаковывает сам, его код менять не нужно. Middleware Проверяем заголовок клиента, оборачиваем ResponseWriter в gzip.Writer и пропускаем через него ответ хендлера:
func gzipMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        if !strings.Contains(r.Header.Get("Accept-Encoding"), "gzip") {
            next.ServeHTTP(w, r)
            return
        }

        w.Header().Set("Content-Encoding", "gzip")
        gz := gzip.NewWriter(w)
        defer gz.Close()

        gzr := gzipResponseWriter{Writer: gz, ResponseWriter: w}
        next.ServeHTTP(gzr, r)
    })
}

type gzipResponseWriter struct {
    http.ResponseWriter
    Writer *gzip.Writer
}

func (g gzipResponseWriter) Write(b []byte) (int, error) {
    return g.Writer.Write(b)
}
Подключаем к нужному эндпоинту:
mux.Handle("/data", gzipMiddleware(http.HandlerFunc(dataHandler)))
Проверяем размер ответа:
curl http://localhost:8080/data --output raw.json
curl -H "Accept-Encoding: gzip" http://localhost:8080/data --output gz.json
ls -lh raw.json gz.json
Когда не стоит Уже сжатые форматы вроде JPEG, PNG или ZIP жать заново смысла нет, размер почти не упадёт, а CPU потратите. Совсем мелкие ответы тоже лучше не трогать, накладные расходы перевесят. GZIP в Go это одно middleware и пара заголовков. Клиент менять не надо, а текстовый ответ ужимается в разы. В продакшене удобно взять готовый gziphandler или включить сжатие на reverse proxy, но понимать, как оно устроено, полезно в любом случае. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoDeep

❤️‍🔥 Причина полюбить Go В командах время уходит не только на логику, но и на споры о стиле. Табы или пробелы, где ставить с
❤️‍🔥 Причина полюбить Go В командах время уходит не только на логику, но и на споры о стиле. Табы или пробелы, где ставить скобку, чей конфиг линтера правильнее. Ценности это не приносит, а силы на ревью отнимает. Go закрывает вопрос на уровне инструментов. Один стиль на всех В Go есть стандартный форматтер gofmt. Он не настраивается, опций про отступы и скобки у него нет, потому что стиль уже определён за вас. Любой код после gofmt выглядит одинаково в любом проекте. Обсуждать нечего. Неаккуратный, но рабочий код:
func main(){
x:=10
if x>5{
fmt.Println("big")
}
}
После gofmt:
func main() {
  x := 10
  if x > 5 {
    fmt.Println("big")
  }
}
Запуск по всему проекту:
gofmt -w .
Импорты делает goimports Рядом есть goimports. Он форматирует так же, но ещё правит импорты. Убирает то, что вы перестали использовать, и добавляет нужное. В Go это важно, потому что неиспользуемый импорт не предупреждение, а ошибка компиляции. То есть инструмент реально помогает коду собраться.
goimports -w .
Хороший опыт в редакторе В VSCode и других редакторах это работает на сохранение файла. Вы пишете, жмёте сохранить, код уже отформатирован, импорты подчищены. Отдельный шаг не нужен. Похожие форматтеры есть и в других языках, тот же Prettier или Black. Разница в том, что в Go это часть стандартного подхода, а не выбор команды среди десятка настроек. Один инструмент, один стиль, ноль споров. 💬 За что вы любите Go? Подписаны на нашу рассылку? 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoTalk

💡 Go может разрешить превращать функции в интерфейсы с одним методом В трекере Go обсуждают предложение #47487. Оно разрешает приводить значение функции к интерфейсу с ровно одним методом, если сигнатура функции совпадает с сигнатурой этого метода. На момент обсуждения предложение помечено как likely accept. Это значит, что склонны принять, но сначала хотят прототип и эксперименты. Сейчас, чтобы замыкание реализовало интерфейс, приходится заводить отдельный тип с методом. Классический пример из стандартной библиотеки это http.HandlerFunc. Шаблон выглядит так:
type FooerFunc func(A, B) (C, D)

func (f FooerFunc) Foo(a A, b B) (C, D) {
    return f(a, b)
}
Когда нужен, например, io.Writer, который считает записанные байты, обычно пишут структуру с полем и методом Write. Кода становится больше, чем сути, а единственная важная строка теряется среди обвязки. Что предлагают Предложение даёт писать то же самое через приведение функции к интерфейсу напрямую:
var N int64
cw := io.Writer(func(p []byte) (n int, err error) {
    n, err = os.Stdout.Write(p)
    N += int64(n)
    return n, err
})
Важная деталь в том, что это именно явное приведение, а не неявное присваивание. У io.Reader и io.Writer одинаковая сигнатура метода, поэтому неявное превращение было бы опасным. Явное приведение снимает двусмысленность, ведь вы сами указываете, чем должна стать функция. По задумке компилятор сам сгенерирует скрытый именованный тип с неэкспортируемым именем, который и несёт метод. Менять reflect, инструменты или работу с type assertion при этом не нужно. Более того, функцию можно положить прямо в таблицу методов, и тогда лишних накладных расходов на обёртку не будет. Альтернатива В обсуждении всплыл и более общий вариант. Это интерфейсные литералы из #25860, где интерфейс собирают из нескольких замыканий, по одному на каждый метод:
cw := io.Writer{
    Write: func(p []byte) (n int, err error) {
        // ...
    },
}
Такой вариант не ограничен одним методом, но его заметно сложнее встроить в текущий язык. Часть участников переживает, что появится ещё один способ писать одно и то же, и это размывает консистентность Go, за которую язык и ценят. Решение пока не финальное, но направление выбрано. Если предложение примут, обвязочных типов вроде http.HandlerFunc в коде станет заметно меньше. 📍 Навигация: ВакансииЗадачиСобесыКанал в Max 🐸 Библиотека Go-разработчика #GoLive