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

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

رفتن به کانال در Telegram

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

نمایش بیشتر

📈 تحلیل کانال تلگرام Библиотека Go-разработчика | Golang

کانال Библиотека Go-разработчика | Golang (@goproglib) در بخش زبانی روسی بازیگری فعال است. در حال حاضر جامعه شامل 24 019 مشترک است و جایگاه 5 674 را در دسته فناوری و برنامه‌ها و رتبه 27 915 را در منطقه روسيا دارد.

📊 شاخص‌های مخاطب و پویایی

از زمان ایجاد در невідомо، پروژه رشد سریعی داشته و 24 019 مشترک جذب کرده است.

بر اساس آخرین داده‌ها در تاریخ 05 ژوئن, 2026، کانال فعالیت پایداری دارد. در ۳۰ روز گذشته تغییر اعضا برابر 51 و در ۲۴ ساعت گذشته برابر 6 بوده و همچنان دسترسی گسترده‌ای حفظ شده است.

  • وضعیت تأیید: تأیید نشده
  • نرخ تعامل (ER): میانگین تعامل مخاطب 10.51% است و در ۲۴ ساعت نخست پس از انتشار، محتوا معمولاً 7.82% واکنش نسبت به کل مشترکان کسب می‌کند.
  • دسترسی پست‌ها: هر پست به طور میانگین 2 524 بازدید دریافت می‌کند. در اولین روز معمولاً 1 879 بازدید جمع‌آوری می‌شود.
  • واکنش‌ها و تعامل: مخاطبان به‌طور فعال حمایت می‌کنند؛ میانگین واکنش به هر پست 9 است.
  • علایق موضوعی: محتوا بر موضوعات کلیدی مانند навигация, лучшее_из_библиотеки_2025, git, string, golive تمرکز دارد.

📝 توضیح و سیاست محتوایی

نویسنده این فضا را محل بیان دیدگاه‌های شخصی توصیف می‌کند:
Все самое полезное для Go-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/32d20779 Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0 #WXSSA

به لطف به‌روزرسانی‌های پرتکرار (آخرین داده در تاریخ 07 ژوئن, 2026)، کانال همواره به‌روز و دارای دسترسی بالاست. تحلیل‌ها نشان می‌دهد مخاطبان به‌طور فعال با محتوا تعامل دارند و آن را به نقطه اثرگذاری مهم در دسته فناوری و برنامه‌ها تبدیل کرده‌اند.

24 019
مشترکین
+624 ساعت
-107 روز
+5130 روز
جذب مشترکین
ژوئن '26
ژوئن '26
+41
در 2 کانال‌ها
مه '26
+288
در 3 کانال‌ها
Get PRO
آوریل '26
+249
در 1 کانال‌ها
Get PRO
مارس '26
+216
در 1 کانال‌ها
Get PRO
فوریه '26
+487
در 7 کانال‌ها
Get PRO
ژانویه '26
+346
در 3 کانال‌ها
Get PRO
دسامبر '25
+370
در 4 کانال‌ها
Get PRO
نوامبر '25
+384
در 4 کانال‌ها
Get PRO
اکتبر '25
+331
در 2 کانال‌ها
Get PRO
سپتامبر '25
+290
در 0 کانال‌ها
Get PRO
اوت '25
+316
در 4 کانال‌ها
Get PRO
ژوئیه '25
+317
در 2 کانال‌ها
Get PRO
ژوئن '25
+315
در 0 کانال‌ها
Get PRO
مه '25
+391
در 5 کانال‌ها
Get PRO
آوریل '25
+358
در 4 کانال‌ها
Get PRO
مارس '25
+625
در 53 کانال‌ها
Get PRO
فوریه '25
+527
در 35 کانال‌ها
Get PRO
ژانویه '25
+517
در 37 کانال‌ها
Get PRO
دسامبر '24
+591
در 40 کانال‌ها
Get PRO
نوامبر '24
+605
در 52 کانال‌ها
Get PRO
اکتبر '24
+499
در 36 کانال‌ها
Get PRO
سپتامبر '24
+676
در 36 کانال‌ها
Get PRO
اوت '24
+580
در 36 کانال‌ها
Get PRO
ژوئیه '24
+586
در 37 کانال‌ها
Get PRO
ژوئن '24
+467
در 29 کانال‌ها
Get PRO
مه '24
+674
در 35 کانال‌ها
Get PRO
آوریل '24
+771
در 36 کانال‌ها
Get PRO
مارس '24
+901
در 31 کانال‌ها
Get PRO
فوریه '24
+729
در 31 کانال‌ها
Get PRO
ژانویه '24
+863
در 27 کانال‌ها
Get PRO
دسامبر '23
+850
در 29 کانال‌ها
Get PRO
نوامبر '23
+608
در 10 کانال‌ها
Get PRO
اکتبر '23
+697
در 25 کانال‌ها
Get PRO
سپتامبر '23
+723
در 0 کانال‌ها
Get PRO
اوت '23
+648
در 0 کانال‌ها
Get PRO
ژوئیه '23
+503
در 0 کانال‌ها
Get PRO
ژوئن '23
+422
در 0 کانال‌ها
Get PRO
مه '23
+568
در 0 کانال‌ها
Get PRO
آوریل '23
+365
در 0 کانال‌ها
Get PRO
مارس '23
+841
در 0 کانال‌ها
Get PRO
فوریه '23
+392
در 0 کانال‌ها
Get PRO
ژانویه '23
+395
در 0 کانال‌ها
Get PRO
دسامبر '22
+384
در 0 کانال‌ها
Get PRO
نوامبر '22
+491
در 0 کانال‌ها
Get PRO
اکتبر '22
+256
در 0 کانال‌ها
Get PRO
سپتامبر '22
+292
در 0 کانال‌ها
Get PRO
اوت '22
+394
در 0 کانال‌ها
Get PRO
ژوئیه '22
+472
در 0 کانال‌ها
Get PRO
ژوئن '22
+443
در 0 کانال‌ها
Get PRO
مه '22
+176
در 0 کانال‌ها
Get PRO
آوریل '22
+328
در 0 کانال‌ها
Get PRO
مارس '22
+242
در 0 کانال‌ها
Get PRO
فوریه '22
+135
در 0 کانال‌ها
Get PRO
ژانویه '22
+236
در 0 کانال‌ها
Get PRO
دسامبر '21
+245
در 0 کانال‌ها
Get PRO
نوامبر '21
+219
در 0 کانال‌ها
Get PRO
اکتبر '21
+215
در 0 کانال‌ها
Get PRO
سپتامبر '21
+290
در 0 کانال‌ها
Get PRO
اوت '21
+298
در 0 کانال‌ها
Get PRO
ژوئیه '21
+281
در 0 کانال‌ها
Get PRO
ژوئن '21
+196
در 0 کانال‌ها
Get PRO
مه '21
+389
در 0 کانال‌ها
Get PRO
آوریل '21
+336
در 0 کانال‌ها
Get PRO
مارس '21
+280
در 0 کانال‌ها
Get PRO
فوریه '21
+258
در 0 کانال‌ها
Get PRO
ژانویه '21
+262
در 0 کانال‌ها
Get PRO
دسامبر '20
+6 566
در 0 کانال‌ها
تاریخ
رشد مشترکین
اشارات
کانال‌ها
07 ژوئن+5
06 ژوئن+2
05 ژوئن+10
04 ژوئن+4
03 ژوئن+7
02 ژوئن+8
01 ژوئن+5
پست‌های کانال
🤩 Разбор строк через 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

2
📰 Первый летний дайджест Короткий, как и отпуск.. — Go закрыл три уязвимости Вышли версии Go 1.26.4 и 1.25.11. Закрывают три
📰 Первый летний дайджест Короткий, как и отпуск.. — Go закрыл три уязвимости Вышли версии Go 1.26.4 и 1.25.11. Закрывают три уязвимости в стандартной библиотеке. — Go может разрешить превращать функции в интерфейсы с одним методом В трекере Go обсуждают предложение #47487. Оно разрешает приводить значение функции к интерфейсу с ровно одним методом, если сигнатура функции совпадает с сигнатурой этого метода. 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max 🐸 Библиотека Go-разработчика #GoLive
1 074
3
🧑‍💻 Конструктор, из которого собран 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
1 498
4
Попросил нейронку написать счётчик сотрудников.. 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max 🐸 Библиотека Go-разр
Попросил нейронку написать счётчик сотрудников.. 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max 🐸 Библиотека Go-разработчика #GoGiggle
1 779
5
📎 Чего не дают логи, метрики и трейсы Идея «три столпа наблюдаемости» звучит убедительно. Соберите логи, метрики и трейсы, отправьте в одну платформу, и поймёте систему. На практике у команды есть все три, а баг в проде она всё равно не находит. Ниже главные мысли статьи о том, почему так выходит, с примерами на 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
1 737
6
😎 Знакомьтесь с экспертом 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-канале На курсе Роман выступает консультантом программы: он помогает формировать содержание уроков с опорой на актуальные инженерные практики и жесткие требования индустрии. Узнать больше о программе и разработке автономных систем: 👉 Курс «Разработка ИИ-агентов» Так, продолжаем знакомить вас с командой? 👍 — Да, ждем новых лиц 🔥 — Жду полезные материалы от Романа
1 715
7
❓ Можно ли использовать слайс как ключ в мапе Вопрос на первый взгляд простой, но именно такие мелочи отделяют тех, кто Go использует, от тех, кто Go понимает. Прежде чем лезть в документацию — подумайте сами. Вот что стоит вспомнить: 🔹 В Go ключ мапы должен быть comparable — то есть поддерживать операции == и != 🔹 Спросите себя: можно ли сравнить два слайса через ==? Что вообще значит «два слайса равны»? ➡️ Ответ 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max 🐸 Библиотека Go-разработчика #ReadySetGo
1 907
8
📎 Обёртывание ошибок через %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
2 022
9
🫳 Типичная микросервисная архитектура 🫳 Постоянно слышу, что монолит - это прошлое, а микросервисы, типа единственный путь
🫳 Типичная микросервисная архитектура 🫳 Постоянно слышу, что монолит - это прошлое, а микросервисы, типа единственный путь к успеху. Все ищут ту самую структуру, которая позволит масштабироваться до бесконечности. На схеме классический скелет современной системы. Выглядит разумно, но без четкого понимания каждый блок может стать точкой отказа: • API Gateway Единая точка входа для всех клиентов. Итог: если гейтвей "прилег" или перегружен, твои крутые микросервисы внизу превращаются в бесполезный набор кода, до которого никто не может достучаться. • Load Balancer Раскидывает трафик, чтобы один сервер не закипел. Итог: всё работает плавно, пока балансировщик правильно настроен. Ошибка в конфиге и весь трафик летит в один сервис, убивая его за секунды. • Service Registry & Discovery Сервисы должны как-то находить друг друга. Итог: если эта штука заглючит, сервис А просто не узнает, где искать сервис Б. Система развалится на куски, которые не умеют общаться. • Разделение по доменам (Domain A / Domain B) У каждого сервиса своя база. Итог: ты получаешь независимость, но платишь за это адом при попытке собрать общую аналитику или сделать сложный транзакционный запрос между доменами. Уже переезжали на микросервисы? ❤️ — да, это было больно, но оно того стоило 🔥 — сидим на монолите и в ус не дуем 🔹 Практический интенсив «Архитектуры и шаблоны проектирования» 🔹 Получить консультацию менеджера 🔹 Сайт Академии 🔹 Сайт Proglib 🏃‍♀️ Азбука айтишника #ликбез
2 018
10
💰 Деньги в 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
1 880
11
🌐 Пакет из стандартной библиотеки 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
2 202
12
❔Готовишься к собеседованию по Go — или просто хочешь понимать тонкости языка? 🙂Тогда этот канал для тебя. Задачи с реальных
❔Готовишься к собеседованию по Go — или просто хочешь понимать тонкости языка? 🙂Тогда этот канал для тебя. Задачи с реальных собеседований, разбор подводных камней языка и честно про рынок. Как выглядит твоё резюме глазами нанимателя и что спрашивают прямо сейчас в топовых компаниях 👍 Подписывайся, если хочешь расти в Golang! ПОДПИСАТЬСЯ ПОДПИСАТЬСЯ Реклама. Урин Дмитрий Алексеевич, ИНН 760404084194. Erid 2Vtzqvb278C
2 211
13
👨‍💻Структурное логирование в 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
2 149
14
Главное не отменить подписку на нашу рассылку 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max 🐸 Библиотека Go-разрабо
Главное не отменить подписку на нашу рассылку 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max 🐸 Библиотека Go-разработчика #GoGiggle
2 473
15
🤭 Топ-вакансий для Go-разработчиков за неделю Team Lead Go — до 600 000 ₽, удаленно (Москва) Senior Golang Developer — до 400 000 ₽, удаленно (Москва) Middle Golang Developer — Remote (udalyonka) ➡️ Еще больше топовых вакансий — в нашем канале Go jobs 🐸 Библиотека Go-разработчика #GoWork
2 610
16
🔄 Вышли 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
2 742
17
⚡️ Продолжаем знакомить вас с экспертами курса 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 и занять место.
2 449
18
🧑‍💻 Один 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
2 373
19
❤️‍🔥 Причина полюбить 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
2 401
20
💡 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
2 498