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

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

Kanalga Telegram’da o‘tish

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

Ko'proq ko'rsatish

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

Библиотека Go-разработчика | Golang (@goproglib) Rus til segmentidagi kanali faol ishtirokchi. Hozirda hamjamiyat 24 053 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 5 416-o'rinni va Rossiya mintaqasida 27 441-o'rinni egallagan.

📊 Auditoriya ko‘rsatkichlari va dinamika

невідомо sanasidan buyon loyiha tez o‘sib, 24 053 obunachiga ega bo‘ldi.

25 Avgust, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni 115 ga, so‘nggi 24 soatda esa -1 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.

  • Tasdiqlash holati: Tasdiqlanmagan
  • Jalb etish (ER): Auditoriya o‘rtacha 15.32% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 8.08% ini tashkil etuvchi reaksiyalarni to‘playdi.
  • Post qamrovi: Har bir post o‘rtacha 3 683 marta ko‘riladi; birinchi sutkada odatda 1 942 ta ko‘rish yig‘iladi.
  • Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 20 ta reaksiya keladi.
  • Tematik yo‘nalishlar: Kontent навигация, лучшее_из_библиотеки_2025, git, string, golive kabi asosiy mavzularga jamlangan.

📝 Tavsif va kontent siyosati

Muallif resursni shaxsiy fikrni ifoda etish maydoni sifatida ta’riflaydi:
Все самое полезное для Go-разработчика в одном канале. Учиться у нас: clc.to/qaSdww По рекламе: @proglib_adv Для обратной связи: @proglibrary_feeedback_bot РКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0 #WXSSA

Yuqori yangilanish chastotasi (oxirgi ma’lumot 26 Avgust, 2026 da olingan) sababli kanal doimo dolzarb va katta qamrovli bo‘lib qoladi. Analitika auditoriya kontent bilan faol hamkorlik qilishini, uni Texnologiyalar & Aralashmalar toifasidagi muhim ta’sir nuqtasiga aylantirishini ko‘rsatadi.

24 053
Obunachilar
-124 soatlar
+27 kunlar
+11530 kunlar
Postlar arxiv
✏️ Расстояния между единицами: находим нужный паттерн Дан массив нулей и единиц, нужно проверить, что между любыми двумя единицами находится минимум k нулей. Звучит элементарно, но в реализации легко споткнуться. Массив [1,0,0,0,1,0,0,1] при k=2 валиден: между первой и второй единицей три нуля (достаточно), между второй и третьей — два нуля (достаточно). А вот [1,0,1,0,0,1] при k=2 — нет, потому что первые две единицы разделены только одним нулём. Запоминаем позицию последней найденной единицы. Когда встречаем новую, проверяем расстояние до неё и сразу обновляем позицию. Это будет один проход по массиву:

func kLengthApart(nums []int, k int) bool {
    lastPos := -k - 1
    
    for i := 0; i < len(nums); i++ {
        if nums[i] == 1 {
            if i - lastPos - 1 < k {
                return false
            }
            lastPos = i
        }
    }
    return true
}
Результат: O(n) время, O(1) память. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #ReadySetGo

🛠️ sqlc: пишешь SQL → получаешь типобезопасный Go Вместо ORM и ручного Scan можно оставить SQL как есть, а Go-код сгенериров
🛠️ sqlc: пишешь SQL → получаешь типобезопасный Go Вместо ORM и ручного Scan можно оставить SQL как есть, а Go-код сгенерировать:
-- name: GetAuthor :one
SELECT id, name, bio
FROM authors
WHERE id = $1;
sqlc generate
После генерации:
author, err := queries.GetAuthor(ctx, id)
sqlc проверяет запросы относительно схемы и генерирует типизированные структуры и методы. Поддерживаются PostgreSQL, MySQL и SQLite. ⚡️ Документация 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoToProduction

🛡 Go tip: не открывайте локальный сервис наружу случайно Если HTTP-сервис должен быть доступен только на вашей машине, слуша
🛡 Go tip: не открывайте локальный сервис наружу случайно Если HTTP-сервис должен быть доступен только на вашей машине, слушайте 127.0.0.1, а не 0.0.0.0:

srv := &http.Server{
    Addr: "127.0.0.1:8001",
}
127.0.0.1 — только локальный интерфейс. А:
Addr: "0.0.0.0:8001»
означает прослушивание всех IPv4-интерфейсов. 📌 Для локальных админок, debug-сервисов и dev-инструментов это простая настройка, которую легко забыть — и случайно выставить сервис в сеть. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoToProduction

💡 Как append растит слайс Все знают, что append добавляет элемент в слайс. А вот что происходит, когда место в массиве кончилось, знают не всегда, и как раз тут прячется пара неожиданностей. 🔵 Пока есть запас У слайса есть len и cap. Пока len меньше cap, append дописывает элемент прямо в тот же массив и возвращает слайс, который смотрит туда же. Никакого копирования, дёшево. Именно поэтому два слайса, делящие один массив, могут внезапно перетирать данные друг друга при append в один из них. 🔵 Когда запас кончился Как только cap исчерпан, рантайм выделяет новый массив побольше, копирует туда старые элементы и возвращает слайс уже на новую память. С этого момента старый и новый слайс не связаны, и запись в один не видна в другом. Отсюда правило, которое многих спасало от багов. Всегда присваивайте результат обратно.
s = append(s, x)
🔵 На сколько растёт Точный коэффициент это деталь реализации, которая менялась от версии к версии, поэтому закладываться на конкретное число не стоит. Грубый ориентир такой. Маленькие слайсы растут примерно вдвое, большие прибавляют около четверти за раз, а переход между режимами сглажен в районе нескольких сотен элементов. Смысл в том, чтобы амортизировать стоимость и не копировать массив на каждом добавлении. Если вы заранее знаете примерный размер, выделяйте вместимость сразу.

s := make([]int, 0, n)
for i := 0; i < n; i++ {
    s = append(s, f(i))
}
Так вы избегаете череды перевыделений и копирований, а заодно снимаете нагрузку со сборщика мусора. На горячих циклах это заметно. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoDeep

⚙️ Go tip: errgroup вместо ручного управления группой горутин Нужно параллельно выполнить несколько задач, остановиться при ошибке и ограничить количество одновременно работающих операций? Вместо WaitGroup + канала ошибок можно использовать golang.org/x/sync/errgroup:

g, ctx := errgroup.WithContext(ctx)
g.SetLimit(8)

for _, url := range urls {
    g.Go(func() error {
        return fetch(ctx, url)
    })
}

if err := g.Wait(); err != nil {
    return err
}
WithContext отменяет контекст при первой ошибке, SetLimit(8) держит максимум 8 активных горутин, а Wait() возвращает ошибку. 🔗 Источник 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoToProduction

🔎 Go tip: откуда в проекте взялась эта зависимость? Нашли незнакомый модуль в go.mod и не понимаете, кто его подтянул? Помож
🔎 Go tip: откуда в проекте взялась эта зависимость? Нашли незнакомый модуль в go.mod и не понимаете, кто его подтянул? Поможет:

go mod why -m golang.org/x/text
Go покажет цепочку зависимостей, из-за которой модуль оказался нужен проекту. Например:
your-project
    ↓
github.com/example/api
    ↓
golang.org/x/text
📌 Полезно перед чисткой go.mod, обновлением зависимостей или разбором supply chain. А если нужно посмотреть, какие модули вообще используются, пригодится:

go mod graph
📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoToProduction

Go-Go-Gadg...Error? Смотрим, как ошибаются Go разработчики! В Go разработчики ошибаются как и в любом другом языке: опечатки,
Go-Go-Gadg...Error? Смотрим, как ошибаются Go разработчики! В Go разработчики ошибаются как и в любом другом языке: опечатки, дубликаты, нерабочие условия проверок и тому подобное. Но почему? Ведь многие используют тот же go vet который прекрасно находит всё это… ведь так... да? На вебинаре разработчик PVS-Studio Глеб Асламов разберет частые и типовые ошибки Go разработчиков в известных проектах. А еще вы узнаете, какие ошибки не могут найти стандартные инструменты и подходы (и что с этим делать). Регистрируйтесь по ссылке! После вебинара все регистранты получат запись. Подписывайтесь на PVS-Studio, чтобы оставаться в курсе последних новостей о статическом анализе: — Telegram — MAX

⏱️ testing/synctest: тестируем время и горутины без Sleep на секунды Тесты конкурентного кода часто либо долго выполняются из
⏱️ testing/synctest: тестируем время и горутины без Sleep на секунды Тесты конкурентного кода часто либо долго выполняются из-за реального времени, либо флакают из-за гонок. В Go 1.25 появился стабильный testing/synctest, который позволяет запускать тест в изолированном bubble с виртуальным временем.

func TestTimeout(t *testing.T) {
    synctest.Test(t, func(t *testing.T) {
        ctx, cancel := context.WithTimeout(
            context.Background(),
            time.Hour,
        )
        defer cancel()

        <-ctx.Done()

        if ctx.Err() != context.DeadlineExceeded {
            t.Fatal("timeout did not expire")
        }
    })
}
Час здесь не проходит в реальном времени: когда все горутины заблокированы, виртуальные часы автоматически перемещаются к следующему событию. А synctest.Wait() позволяет дождаться, пока конкурентная работа в bubble завершится или перейдёт в состояние ожидания. 📌 synctest был экспериментом в Go 1.24, а с Go 1.25 входит в стандартную библиотеку. 🔗 Источник 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoToProduction

💡 Что внутри у any Раньше мы разбирали, что обычный интерфейс это структура из двух указателей, на таблицу типа и на данные. Пустой интерфейс, он же any, устроен похоже, но проще, и об этом стоит знать отдельно. 🟢 Две разные структуры Непустой интерфейс в рантайме это iface. Внутри у него itab, где лежат тип интерфейса, конкретный тип, хеш и таблица методов. У пустого интерфейса методов нет, значит и таблица методов ему не нужна. Поэтому any представлен другой, более лёгкой структурой, eface.

type eface struct {
    _type *_type
    data  unsafe.Pointer
}
Здесь _type это указатель на описание конкретного типа, а data это указатель на само значение. Никакого itab и списка методов, потому что вызывать через any всё равно нечего. Из-за этого приведение типа и type switch по any сводятся к сравнению указателя на тип, без похода в таблицу методов. 🟢 Классическая ловушка с nil Из устройства следует известный подвох. Интерфейс равен nil, только когда оба поля пустые, и тип, и данные. Стоит завернуть в интерфейс нетипизированный `nil`-указатель, и получится интерфейс, у которого тип уже не пустой.

var p *MyError = nil
var err error = p
fmt.Println(err == nil) // false
Тип внутри err теперь *MyError, поэтому сравнение с nil даёт false, хотя указатель внутри нулевой. Отсюда практичное правило. Возвращайте из функций именно nil литералом, а не заранее объявленную типизированную переменную, если хотите, чтобы вызывающий код честно увидел nil. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoDeep

Вам доклады по Go или Java? VK приглашает на митап с двойной начинкой 26 августа VK собирает Go- и Java-инженеров, чтобы прокачать знания. В программе два трека — Go и Java, по три доклада в каждом. Трек Go: • «Компиляция Go в динамическую либу, или как мы ускорили выкатку фичи в два раза, но нам не понравилось», Михаил Кичигин, бэкенд-разработчик, Avito Tech • «Go-платформа VK: как мы построили единую основу для создания Go-сервисов», Александр Апанасенко, руководитель команды SDK Backend, VK • «Почтальон от Kubernetes до Palo Alto. Как осуществляется доставка информации об адресах», Дарья Кулькина, бэкенд-разработчик, Точка Банк Трек Java: • «Перформанс-трюки в поисковой платформе Ozon», Пётр Портнов, ведущий разработчик среднего поиска, Ozon • «Архитектура современного движка платёжной системы и переход к новой архитектуре», Игорь Крикунов, технический лидер разработки DBC, Альфа-Банк • «Переход от федерации S3-кластеров в пользу коммунального и мультитенантного кластера», Кирилл Боблак, ведущий разработчик One-cloud, VK А ещё будет мастер-класс по прокачке навыка, который сделает вас звездой любого вечера, и афтепати, чтобы обсудить доклады в неформальной обстановке. Встречаемся в 17:00, начало в 18:00. Участие бесплатное, регистрация обязательна.

⏱️ Go 1.27: ещё одно изменение, которое стоит проверить в старом коде В прошлом посте разбирали дженерик-методы, которые появ
⏱️ Go 1.27: ещё одно изменение, которое стоит проверить в старом коде В прошлом посте разбирали дженерик-методы, которые появятся в Go 1.27. Но в релизе есть и менее заметное изменение — окончательно убирают GODEBUG=asynctimerchan. Этот переключатель временно возвращал старое поведение time.Timer и time.Ticker из Go 1.22 и более ранних версий. С Go 1.27 таймерные каналы окончательно становятся синхронными. Поэтому старый код вроде:

if !t.Stop() {
    <-t.C
}
t.Reset(d)
теперь стоит пересмотреть: ручное вычитывание канала перед Reset больше не требуется и может привести к блокировке. 📌 Если уже готовитесь к Go 1.27, проверьте по проекту: ⬆️ asynctimerchan → удалить ⬆️ Stop() + <-t.C → проверить ⬆️ Stop() + Reset() → проверить 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoLive

🔥 Go 1.27 наконец разрешит дженерик-методы Дженерики появились ещё в Go 1.18, но метод до сих пор не может объявить собственные type parameters. Поэтому вместо:

func (s Set[T]) Map[U comparable](f func(T) U) Set[U]
приходится писать отдельную generic-функцию:
func MapSet[T, U comparable](s Set[T], f func(T) U) Set[U]
В Go 1.27 это ограничение снимают: собственные type parameters можно будет объявлять прямо у метода. Но есть граница: generic methods не работают как методы интерфейсов и не могут их реализовывать. 📌 Go 1.27 пока не вышел в stable — изменение уже есть в draft release notes, релиз ожидается в августе. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoLive

Что на самом деле лежит внутри слайса Слайс — не массив, а небольшая структура:

type slice struct {
    array unsafe.Pointer
    len   int
    cap   int
}
array указывает на массив с данными, len хранит текущую длину, cap — доступную вместимость. Отсюда две важные особенности. 1️⃣ Срез не копирует данные
s2 := s1[1:3]
s1 и s2 смотрят в один массив. Изменение элемента через s2 может быть видно через s1. 2️⃣ А вот append может разорвать эту связь Пока хватает cap → запись идёт в существующий массив. Не хватает cap → выделяется новый backing array, элементы копируются туда. Поэтому два слайса могут сначала делить память, а после append — уже нет. И наоборот, append без реаллокации способен неожиданно изменить данные, доступные через соседний слайс. 💡 Есть способ контролировать такое поведение через s[low:high:max] — разберём отдельно. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoDeep

🤷‍♂️ Почему Go удобен для AI-кодинга Команда Go выпустила разбор о том, почему язык хорошо подходит для работы с AI-агентами
🤷‍♂️ Почему Go удобен для AI-кодинга Команда Go выпустила разбор о том, почему язык хорошо подходит для работы с AI-агентами. Ключевой аргумент — Go легко проверять: ⬆️gofmt стандартизирует код ⬆️компилятор ловит ошибки ⬆️типов и выдуманные API ⬆️тесты и fuzzing встроены в ⬆️toolchain govulncheck проверяет ⬆️уязвимые зависимости ⬆️go fix и gopls помогают с ⬆️рефакторингом Когда агент пишет код быстрее, чем человек успевает его читать, предсказуемость языка становится отдельным преимуществом. Go + AI — мэтч или удачный маркетинг 🔥 — Мэтч: агентам нужны строгие рамки 🌚 — Маркетинг: агент нагенерит приключений на любом языке 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoLive

Красивые таблицы в Go Иногда данные хочется вывести не просто строками в консоль, а в аккуратной читаемой таблице. Чтобы не изобретать велосипеды с fmt.Printf и ручными отступами, можно взять библиотеку tabby. Что умеет — Форматировать данные в консольные таблицы. — Поддерживает выравнивание колонок. — Позволяет строить вложенные таблицы (nested). Как использовать:

t := tabby.New()
t.AddHeader("ID", "Name", "Age")
t.AddLine(1, "Alice", 23)
t.AddLine(2, "Bob", 30)
t.Print()
Вывод:
ID   Name   Age
1    Alice  23
2    Bob    30
📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoToProduction

MWS проведет онлайн-митап для Go-разработчиков. 11 августа в 15:00 подключайся к эфиру: тебя ждут доклады экспертов и ответы
MWS проведет онлайн-митап для Go-разработчиков.  11 августа в 15:00 подключайся к эфиру: тебя ждут доклады экспертов и ответы на вопросы участников.  В программе митапа: — «Построение агентов на A2A с изолированным исполнением на Go» от MWS DevRails; — «Как разрабатывать эффективные и экономичные Kubernetes-операторы на Go» от Cloud.ru;  — «Точный Rate Limiting на API Gateway в мульти-ЦОД инфраструктуре» от MWS Octapi; — «Взросление OpenAPI-кодогенерации» от MWS Cloud Platform. Узнай больше о докладах, регистрируйся и добавляй в календарь по ссылке. Реклама. О рекламодателе | Сделано в WOWBLOGGER

🫣 Почему for range иногда работает не так, как ожидаешь for range выглядит простой конструкцией, но именно с ним связано множество неочевидных ошибок. Разберём три самые распространённые. 1. Переменная цикла содержит копию элемента При обходе слайса значение элемента записывается в переменную цикла:

users := []User{
    {Name: "Alice"},
    {Name: "Bob"},
}

for _, user := range users {
    user.Name = strings.ToUpper(user.Name)
}
Исходный слайс не изменится. user — это копия структуры, а не сам элемент. ➡️ Если нужно изменить данные, работайте через индекс:

for i := range users {
    users[i].Name = strings.ToUpper(users[i].Name)
}
Для слайса указателей поведение будет другим: копируется указатель, а не объект, на который он указывает. 2. Адрес переменной цикла — не адрес элемента Такой код встречается довольно часто:

var result []*User

for _, user := range users {
    result = append(result, &user)
}
Начиная с Go 1.22 при использовании := каждая итерация получает собственную переменную цикла, поэтому указатели больше не будут ссылаться на одну и ту же переменную, как это происходило раньше. Но &user всё равно указывает на копию элемента, а не на элемент исходного слайса. ➡️ Если нужны адреса элементов, используйте индекс:

for i := range users {
    result = append(result, &users[i])
}
Если же переменная объявлена заранее и используется присваивание =, она по-прежнему переиспользуется между итерациями. 3. Изменение коллекции во время обхода Для слайсов выражение после range вычисляется один раз — до начала цикла. Поэтому количество итераций определяется исходной длиной слайса.

numbers := []int{1, 2, 3}

for _, n := range numbers {
    numbers = append(numbers, n)
}
Добавленные элементы в текущий обход автоматически не попадут. Кроме того, append может выделить новый underlying array, поэтому изменять слайс во время обхода стоит с осторожностью. ➡️ С map правила другие:

for key := range cache {
    delete(cache, key)
}
Удалять элементы во время обхода разрешено. А вот элементы, добавленные в процессе итерации, могут как попасть в текущий обход, так и быть пропущены — спецификация этого не гарантирует. Порядок обхода map также не определён.
И помните: одновременно читать и изменять map из разных горутин без синхронизации нельзя.
for range скрывает немало деталей реализации. Если помнить, что переменная цикла часто содержит копию элемента, а поведение зависит от типа коллекции, многих неприятных ошибок удастся избежать. 📍 Навигация: ВакансииЗадачиСобесы 🐸 Библиотека Go-разработчика #GoToProduction

👨‍💻 Команды терминала, которые должен знать каждый разработчик Многие знакомы с cd, ls, pwd, но под капотом терминала — мор
👨‍💻 Команды терминала, которые должен знать каждый разработчик Многие знакомы с cd, ls, pwd, но под капотом терминала — море полезных шорткатов и трюков. Вот список тех, которые экономят время, исправляют ошибки и упрощают работу: 🔴 Запуск предыдущей команды — !! Бывает забываешь написать sudo, тогда можно просто sudo !! 🔴 Заменить очепятку и выполнить команду заново — ^old^new 🔴 Заменить все вхождения в команде — !!:gs/old/new/ 🔴 Поиск по тексту в файлах — grep -R "pattern" . 🔴 Открыть последнюю команду в редакторе для редактирования — fc 🔴 Проверка доступности порта — nc -zv <host> <port> 🔴 Проверить чем занят порт — lsof -i :<port> 🐸Библиотека Go-разработчика #GoToProduction