Библиотека Go-разработчика | Golang
Все самое полезное для Go-разработчика в одном канале. По рекламе: @proglib_adv Учиться у нас: https://proglib.io/w/32d20779 Для обратной связи: @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 000 obunachidan iborat bo'lib, Texnologiyalar & Aralashmalar toifasida 5 688-o'rinni va Rossiya mintaqasida 27 903-o'rinni egallagan.
📊 Auditoriya ko‘rsatkichlari va dinamika
невідомо sanasidan buyon loyiha tez o‘sib, 24 000 obunachiga ega bo‘ldi.
11 Iyun, 2026 dagi oxirgi ma’lumotlarga ko‘ra kanal barqaror faollikka ega. Oxirgi 30 kunda obunachilar soni 49 ga, so‘nggi 24 soatda esa -2 ga o‘zgardi va umumiy qamrov yuqori darajada qolmoqda.
- Tasdiqlash holati: Tasdiqlanmagan
- Jalb etish (ER): Auditoriya o‘rtacha 10.68% darajada jalb etiladi. Nashrdan keyingi dastlabki 24 soatda kontent odatda umumiy obunachilar sonining 7.60% ini tashkil etuvchi reaksiyalarni to‘playdi.
- Post qamrovi: Har bir post o‘rtacha 2 563 marta ko‘riladi; birinchi sutkada odatda 1 823 ta ko‘rish yig‘iladi.
- Reaksiyalar va o‘zaro ta’sir: Auditoriya faol: har bir postga o‘rtacha 9 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-разработчика в одном канале.
По рекламе: @proglib_adv
Учиться у нас: https://proglib.io/w/32d20779
Для обратной связи: @proglibrary_feeedback_bot
РКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0
#WXSSA”
Yuqori yangilanish chastotasi (oxirgi ma’lumot 12 Iyun, 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.
Ma'lumot yuklanmoqda...
| Sana | Obunachilarni jalb qilish | Esdaliklar | Kanallar | |
| 12 Iyun | +3 | |||
| 11 Iyun | +9 | |||
| 10 Iyun | +3 | |||
| 09 Iyun | +8 | |||
| 08 Iyun | +1 | |||
| 07 Iyun | +7 | |||
| 06 Iyun | +2 | |||
| 05 Iyun | +10 | |||
| 04 Iyun | +4 | |||
| 03 Iyun | +7 | |||
| 02 Iyun | +8 | |||
| 01 Iyun | +5 |
time.Timer, сохраняете в отдельной переменной ссылку на канал Timer.C и хотите понять, остаётся ли этот канал тем же самым после вызова Reset. Если канал пересоздаётся, сохранённая ссылка станет бесполезной, а горутина будет ждать данные, которые никогда не придут.
🖇 Короткий ответ
Канал Timer.C не пересоздаётся при вызове Reset. Вы можете хранить его отдельно, читать из него, ждать на нём, и он остаётся живым после любого числа вызовов Reset. Метод Reset меняет только момент срабатывания, сам канал он не трогает.
Проверить это можно небольшой программой. Таймер срабатывает, мы печатаем прошедшее время, удваиваем задержку и снова запускаем тот же таймер:
package main
import (
"fmt"
"time"
)
func main() {
start := time.Now()
delay := time.Second
t := time.NewTimer(delay)
defer t.Stop()
for range t.C {
fmt.Println(time.Since(start))
delay *= 2
t.Reset(delay)
if delay > 16*time.Second {
return
}
}
}
Цикл for range t.C читает из одного и того же канала на каждой итерации. Если бы Reset подменял канал, цикл завис бы после первого срабатывания. Этого не происходит, программа печатает растущие интервалы, пока задержка не превысит шестнадцать секунд.
Отдельно стоит вспомнить про изменение в Go 1.23. Раньше канал таймера имел буфер на один элемент, поэтому после Stop или Reset в нём мог остаться старый сигнал, и его приходилось вручную вычитывать.
❗️ С версии 1.23 канал стал небуферизованным, устаревшие значения больше в нём не задерживаются. Ещё таймеры и тикеры теперь освобождаются сборщиком мусора сразу, как только на них не осталось ссылок, даже без вызова Stop.
Момент про сборку мусора в этом сценарии не важен. Программа держит ссылку и на сам таймер, и на его канал, поэтому ничего не освобождается раньше времени.
Хранить Timer.C в отдельной переменной безопасно. Канал живёт столько же, сколько и сам таймер, а Reset влияет только на время срабатывания. Если вы пишете на Go 1.23 или новее, вручную чистить канал после Reset тоже не нужно, и это убирает старый источник ошибок.
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoDeep| 2 | 🔥 Строишь ИИ-агентов? Руководитель AI/ML-направления Сloud․ru покажет, где большинство архитектур ломаются, и как этого избежать.
18 июня в 19:00 совместно с Сloud․ru проведём открытый урок «Мультиагентные системы: почему большинство архитектур переусложнены».
Спикер — Дмитрий Юдин, эксперт по масштабированию и оптимизации вычислительных ресурсов для ML. Под его руководством развивается Evolution AI Factory — цифровая среда для работы с GenAI. Он занимается развитием сервисов генеративного ИИ, инфраструктуры для обучения больших языковых моделей и внедрением интеллектуальных агентов.
Что получишь на уроке:
— критерии выбора между одним агентом и мультиагентной системой;
— разбор популярных архитектурных ошибок;
— реальные ограничения современных ИИ-агентов;
— практические рекомендации по проектированию агентных систем.
🎁 Для участников урока подготовили промокод на скидку 10 000 ₽.
🗓️ Когда: 18 июня, 19:00 (МСК)
👉 Занять место на открытом уроке | 769 |
| 3 | 📹 Монтаж видео на Go без ручного ffmpeg
MovieGo это библиотека на Go для монтажа видео. Под капотом она работает поверх пакета ffmpeg-go и даёт API с цепочками методов. Вы пишете обычный Go код, а команду для ffmpeg библиотека собирает сама.
Через неё можно нарезать ролик, склеить несколько в один, поменять размер, добавить плавное появление и затухание или снять кадр. Сам ffmpeg должен стоять в системе отдельно.
Размер
ResizeByWidth задаёт ширину, ResizeByHeight высоту, Resize сразу оба значения:
first, _ := moviego.Load("forest.mp4")
first.Resize(1000, 500).Output("resized.mp4").Run()
Нарезка
SubClip обрезает ролик по началу и концу отрезка в секундах. Тут кусок с третьей по пятую секунду:
first.SubClip(3, 5).Output("final.mp4").Run()
Склейка
Concat собирает слайс Video в один ролик, прямо в слайсе можно применять эффекты к отдельным кускам:
finalVideo, _ := moviego.Concat([]moviego.Video{
first,
second.SubClip(5.3, 10.5),
first.FadeIn(0, 5).FadeOut(5),
})
finalVideo.Output("final.mp4").Run()
Появление и затухание
FadeIn и FadeOut работают с картинкой, AudioFadeIn и AudioFadeOut со звуком. Методы складываются в цепочку:
first.FadeIn(0, 3).FadeOut(5).Output("fade.mp4").Run()
first.FadeOut(5).AudioFadeOut(5).Output("fade-out.mp4").Run()
Скриншот
Screenshot сохраняет кадр по указанной секунде, в том числе после эффектов:
first.Screenshot(5, "simple-screen.png")
MovieGo снимает рутину по сборке команд ffmpeg руками и переводит монтаж на понятные методы. Подойдёт, чтобы автоматизировать обработку видео в Go сервисе, например генерировать превью или собирать ролики из частей.
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoToProduction | 1 424 |
| 4 | 👋 Привет, гоферы!
Канал работает стабильно, без паник и утечек. Но мы нашли такую строку в коде:
if boosts < needed {
return fmt.Errorf("не хватает буста для крутых фич: %w", ErrSadAdmin)
}
Без бустов канал живёт, но с ними — раскрывает все горутины на полную. Один клик, и вы в списке тех, кто помог проекту.
➡️ Бустануть канал
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика | 1 885 |
| 5 | 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoGiggle | 2 162 |
| 6 | 🔄 pgCenter 0.10.0, поддержка Postgres 15–18 и переход на pgx/v5
Вышел релиз v0.10.0 консольной утилиты pgcenter для наблюдения за Postgres. Это в основном обновление совместимости и безопасности, новых экранов в интерфейсе не добавили.
Главное изменение это поддержка Postgres от 15 до 18. Запросы статистики обновили под формат версии 17, прогон тестов идёт на ветках с 14 по 18. Под капотом утилита перешла на драйвер pgx/v5, обновилась до Go 1.25.10 и закрыла накопившиеся уязвимости в зависимостях.
Часть правок касается устойчивости и вывода:
• Теперь pgcenter проверяет, включён ли pg_stat_statements в shared_preload_libraries, и больше не зависает, если расширение установлено в базе, но не активировано в конфигурации.
• Длинные значения application_name из pg_stat_activity перестали обрезаться.
• Адрес клиента в pg_stat_activity и pg_stat_replication теперь оборачивается в функцию host(), поэтому в выводе нет лишней маски подсети.
Если вы уже пользуетесь pgcenter на свежих версиях Postgres, обновление снимает проблемы совместимости и убирает известные CVE.
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoLive | 2 151 |
| 7 | 🥺 Big money вакансии для Go-разработчиков за неделю
Middle / Senior Бэкенд разработчик — до 405 000 $ (в год) — удаленно по Сан-Франциско
Golang-разработчик — до 400 000 ₽ в офис или удаленно (Москва)
➡️ Еще больше топовых вакансий — в нашем канале Go jobs
🐸 Библиотека Go-разработчика
#GoWork | 2 329 |
| 8 | 📎 Почему цепочка middleware ломает безопасность, даже когда каждый обработчик корректен
Стек middleware разрастается до десятка с лишним обработчиков. Каждый написан осознанно и протестирован, а ревью всё равно находит обход аутентификации. Дыра не внутри обработчика, а в порядке их выполнения.
👉 Почему так происходит
Порядок обычно складывается стихийно. Обработчики добавляют по мере задач, и очерёдность повторяет хронологию, а не смысл. Кто добавлен раньше, тот снаружи. При этом влияние нового обработчика на безопасность всей цепочки никто не проверяет.
В итоге порядок принимает решения, которые никто явно не принимал. Когда срабатывает аутентификация, может ли запрос получить ответ до неё, кто видит личность в контексте. Эта политика нигде не записана и меняется при каждой перестановке.
👉 Как этого избежать
Разбейте цепочку на слои доверия и зафиксируйте, что внутри блока безопасности порядок обязателен:
// Слой безопасности, порядок обязателен
// авторизации нужна личность из контекста
// аутентификации нужен резолв тенанта из контекста
handler = authorizationMiddleware(handler)
handler = authenticationMiddleware(handler)
handler = tenantMiddleware(handler)
Запретите ранний выход до аутентификации. Ни один обработчик выше блока безопасности не должен сам возвращать неошибочный ответ. Быстрый ответ на health check выносите на отдельный неаутентифицированный маршрут.
Сделайте порядок проверяемым в CI. Пусть пайплайн отклоняет PR, который переставляет обработчики внутри блока безопасности без явного ревью. Тогда комментарии о порядке работают как ограничение, а не пожелание.
Тестируйте цепочку целиком. Юнит тесты не ловят такие дыры, потому что баг живёт во взаимодействии. Нужны сквозные тесты на враждебные комбинации заголовков, путей и параметров.
Полезнее спрашивать не про то, корректен ли каждый middleware, а про то, что цепочка считает истинным к моменту запуска каждого обработчика. Держите порядок явным, проверяемым и покрытым тестами на всю цепочку сразу.
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoDeep | 2 203 |
| 9 | 💻 top для Postgres прямо в терминале
Postgres отдаёт массу статистики о своей работе. Активные сессии, запросы, репликация, блокировки, обращения к таблицам и индексам, прогресс вакуума. Всё это лежит в системных представлениях вроде pg_stat_activity и pg_stat_statements.
Беда в том, что родного инструмента для удобной работы с этой статистикой у Postgres нет. Приходится держать в голове десятки запросов и руками дёргать представления через psql. Написанный на Go, pgCenter показывает статистику в живом интерфейсе, похожем на top.
🖇 Что он умеет
Основная команда pgcenter top обновляет метрики в реальном времени и переключается между экранами по горячим клавишам.
Видно сводку по базе, активность клиентов из pg_stat_activity, тяжёлые запросы из pg_stat_statements, состояние репликации, обращения к таблицам и индексам, прогресс операций вроде VACUUM, CREATE INDEX и COPY.
Рядом идёт системная статистика, собранная из procfs. Это load average, загрузка CPU, память и swap, нагрузка на диски и сеть.
Отдельно полезен экран по процессам, он открывается по Shift+S. Там pgcenter склеивает данные из pg_stat_activity с метриками каждого бэкенда из /proc/[pid]/stat и /proc/[pid]/io. Сразу видно, во что упёрся медленный запрос, в процессор или в диск, без выхода из утилиты. Экран работает только в локальном режиме.
🖇Как запустить
Проще всего через Docker:
docker pull lesovsky/pgcenter:latest
docker run -it --rm lesovsky/pgcenter:latest pgcenter top -h 1.2.3.4 -U user -d dbname
Если ставите пакетом, под DEB, RPM и APK есть готовые сборки на странице релизов.
После установки запуск выглядит так:
pgcenter top -h 127.0.0.1 -U postgres -d mydb
Кроме живого режима есть запись статистики на будущее. Команда pgcenter record складывает метрики в файлы, а pgcenter report строит из них отчёты для разбора уже после инцидента.
Метрики по процессам тоже пишутся, и их можно проиграть через pgcenter report -N. Ещё внутри есть профайлер событий ожидания, просмотр и правка конфигов с перезагрузкой сервиса, а также чтение логов Postgres без остановки мониторинга.
🖇 Пара ограничений
Утилита рассчитана на Linux и на других системах работать не будет. Для полного доступа к статистике нужны права SUPERUSER либо роли для чтения метрик и логов. С удалённым Postgres и с Amazon RDS часть функций недоступна, потому что туда не попадает системная статистика хоста.
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoToProduction | 2 108 |
| 10 | 🔥 Приглашаем на бесплатный открытый вебинар курса «Высоконагруженные системы: архитектура и масштабирование»:
«Асинхронная обработка данных в высоконагруженных системах»
🗓 Когда: 16 июня, 20:00 (мск)
На вебинаре разберём, как грамотно внедрять асинхронность и строить по-настоящему производительные системы.
Что будет на вебинаре:
— Зачем и когда переходить на асинхронную обработку данных в высоконагруженных проектах
— Очереди сообщений, веб-сокеты и другие инструменты асинхронного взаимодействия
— Реальный архитектурный кейс: от веб-сервера до брокера сообщений и базы данных
— Типичные узкие места асинхронных систем и проверенные способы их устранения
👉 Зарегистрироваться: https://otus.ru/lessons/highloadarchitect/?utm_source=telegram&utm_medium=cpm&utm_campaign=hl&utm_term=goproglib&utm_content=mql-lesson-16-06-2026_test_usp-universal_hl_text_no-headline_text_long_aibanner_lesson-banner_white_standart#event-7191
Бесплатное занятие приурочено к курсу «Высоконагруженные системы: архитектура и масштабирование», где вы научитесь проектировать высоконагруженные системы, способные выдерживать экстремальные нагрузки и работать стабильно в любых условиях.
🎁При покупке курса вы получите в подарок мини-курс по Kafka, который поможет подготовиться к собеседованию в бигтех
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576 | 1 992 |
| 11 | 🧑💻 Зачем мьютекс в uuid, если UUID не хранят состояние
В исходниках пакета uuid рядом с генерацией UUIDv7 лежит мьютекс уровня пакета и переменная с временем последнего вызова. UUID считаются значениями без состояния, поэтому блокировка выглядит лишней. Разберём, зачем она там.
Первые 48 бит UUIDv7 это метка времени в миллисекундах. Поэтому такие значения сортируются по времени создания и удобны как ключи в базе. Но внутри одной миллисекунды программа создаёт тысячи идентификаторов с одинаковой меткой, и без счётчика их порядок стал бы случайным.
Пакет хранит последнее выданное время вместе со счётчиком в lastV7time и проверяет, что новое значение строго больше прошлого:
func getV7Time() (milli, seq int64) {
timeMu.Lock()
defer timeMu.Unlock()
nano := timeNow().UnixNano()
milli = nano / nanoPerMilli
seq = (nano - milli*nanoPerMilli) >> 8
now := milli<<12 + seq
if now <= lastV7time {
now = lastV7time + 1
milli = now >> 12
seq = now & 0xfff
}
lastV7time = now
return milli, seq
}
Если посчитанное время не больше прошлого, функция берёт lastV7time + 1. Так порядок держится даже при переводе часов назад, просто встроенная метка ненадолго разойдётся с реальной.
Мьютекс нужен потому, что NewV7 зовут из разных горутин, а lastV7time одна на весь пакет. Используется общий timeMu, тот же, что защищает время старых версий UUID.
Состояние живёт в одном процессе. Между несколькими машинами строгий порядок внутри миллисекунды не гарантирован, хотя сортировка по времени всё равно работает.
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoDeep | 1 963 |
| 12 | 🌴 Деревья поиска на Go: вставка, поиск, удаление
BST — двоичное дерево поиска. Простая идея: левый потомок всегда меньше родителя, правый — больше. Это даёт поиск за O(log n), но только если дерево сбалансировано. Об этом — в конце поста.
Структура узла
type Node struct {
Val int
Left *Node
Right *Node
}
type BST struct {
Root *Node
}
Вставка
Идём по дереву вниз: если значение меньше текущего узла — налево, больше — направо. Когда упёрлись в nil — вставляем:
func (t *BST) Insert(val int) {
t.Root = insert(t.Root, val)
}
func insert(node *Node, val int) *Node {
if node == nil {
return &Node{Val: val}
}
if val < node.Val {
node.Left = insert(node.Left, val)
} else if val > node.Val {
node.Right = insert(node.Right, val)
}
return node
}
Дубликаты здесь просто игнорируются. Можно добавить счётчик в узел, если нужно их хранить.
Поиск
Та же логика, что и вставка, но вместо создания узла возвращаем результат:
func (t *BST) Search(val int) bool {
return search(t.Root, val)
}
func search(node *Node, val int) bool {
if node == nil {
return false
}
if val == node.Val {
return true
}
if val < node.Val {
return search(node.Left, val)
}
return search(node.Right, val)
}
Удаление
Три случая:
- узел без потомков — просто удаляем
- узел с одним потомком — заменяем им
- узел с двумя потомками — находим минимальный элемент правого поддерева (in-order successor), ставим его на место удалённого
func (t *BST) Delete(val int) {
t.Root = deleteNode(t.Root, val)
}
func deleteNode(node *Node, val int) *Node {
if node == nil {
return nil
}
if val < node.Val {
node.Left = deleteNode(node.Left, val)
} else if val > node.Val {
node.Right = deleteNode(node.Right, val)
} else {
if node.Left == nil {
return node.Right
}
if node.Right == nil {
return node.Left
}
// Находим минимум в правом поддереве
min := findMin(node.Right)
node.Val = min.Val
node.Right = deleteNode(node.Right, min.Val)
}
return node
}
func findMin(node *Node) *Node {
for node.Left != nil {
node = node.Left
}
return node
}
Обходы
Три классических варианта, каждый даёт узлы в разном порядке:
// In-order: левый → корень → правый (отдаёт отсортированный список)
func inOrder(node *Node) {
if node == nil {
return
}
inOrder(node.Left)
fmt.Println(node.Val)
inOrder(node.Right)
}
// Pre-order: корень → левый → правый (удобен для копирования дерева)
func preOrder(node *Node) {
if node == nil {
return
}
fmt.Println(node.Val)
preOrder(node.Left)
preOrder(node.Right)
}
// Post-order: левый → правый → корень (удобен для удаления дерева)
func postOrder(node *Node) {
if node == nil {
return
}
postOrder(node.Left)
postOrder(node.Right)
fmt.Println(node.Val)
}
Где ломается BST
Если вставлять элементы по порядку — 1, 2, 3, 4, 5 — дерево вырождается в связный список. Поиск становится O(n) вместо O(log n):
1
\
2
\
3
\
4
\
5
Именно для этого придумали самобалансирующиеся деревья.
💬 Разбирать механизм, который не даёт дереву деградировать?
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#ReadySetGo | 1 921 |
| 13 | 🗑 Сборщик мусора видно прямо в терминале
Растут задержки в Go-сервисе? Обычно включают GODEBUG=gctrace=1 и втыкают в простыню логов в stderr. Поймать там всплеск STW-паузы или понять, что GC стал срабатывать чаще после правок, почти нереально.
gcscope рисует это вживую. Терминальный TUI показывает GC-циклы, STW-паузы, рост кучи (live/goal) и сигналы pacer в реальном времени.
Попробовать демо
Встроенная демо-нагрузка, ничего ставить не надо.
go run ./cmd/gcscope lab churn
➡️ На своём коде
Собираем бинарник и запускаем под наблюдением.
go build -o ./myapp ./cmd/myapp
gcscope run ./myapp -- --your-flag value
Код приложения менять не нужно. Всё после -- уходит в вашу программу.
➡️ Что ещё умеет
Режим attach цепляется к живому сервису по HTTP через runtime/metrics. Режим diff сравнивает два snapshot-файла и показывает разницу по heap и STW между запусками. Историю можно листать на паузе, графики зумить, состояние сохранять в JSON клавишей s.
Ставится одной командой:
go install github.com/timur-developer/gcscope/cmd/gcscope@latest
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoToProduction | 2 309 |
| 14 | ✏️ Переменная цикла своя на каждой итерации
В Go переменная цикла for ... range создаётся заново на каждой итерации. Это снимает одну из самых частых проблем при работе с горутинами и замыканиями, когда несколько функций случайно ссылаются на одно и то же значение. Разберём как этим пользоваться.
Замыкание захватывает не значение переменной, а саму переменную. Если бы v была одна на весь цикл, все запущенные горутины ссылались бы на общую ячейку и видели бы её последнее значение.
Поскольку в Go у каждой итерации своя v, такого не происходит:
for _, v := range data {
go func() { fmt.Println(v) }()
}
Каждая горутина печатает значение своей итерации, а не последний элемент data. Никаких обходных приёмов внутри тела цикла для этого не нужно.
На каждом проходе компилятор заводит новую переменную и копирует в неё текущее значение. Замыкание, которое вы создаёте внутри тела, привязывается именно к этой копии. Когда итерация заканчивается, её переменная остаётся жить ровно столько, сколько на неё ссылаются запущенные функции.
То же касается и индекса в форме с двумя переменными:
for i, v := range items {
go func() {
fmt.Println(i, v)
}()
}
И i, и v уникальны для каждого прохода, поэтому пара значений всегда соответствует своей итерации.
Поведение привязано к версии языка в директиве go файла go.mod. Оно действует, когда там указано go 1.22 или выше. Если в модуле прописана версия старше, тот же код соберётся со старой семантикой даже на новом компиляторе. Так одна и та же кодовая база ведёт себя предсказуемо, а апгрейд тулчейна не меняет логику молча.
ℹ️ О чём помнить
Копия создаётся под каждую итерацию, но это именно копия значения. Если в v лежит срез или указатель, копируется он, а не данные за ним, и общий доступ к этим данным из горутин по-прежнему требует синхронизации. Свойство решает проблему захвата переменной, а не гонок по самим данным.
Опираться на это можно в любом коде, где замыкания и горутины создаются внутри for ... range. Значение каждой итерации остаётся при ней, и писать переобъявление внутри тела больше не требуется.
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoDeep | 2 233 |
| 15 | 📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoGiggle | 2 503 |
| 16 | 🔥 Инженерная методичка по ИИ от Романа Барлоса (Team Lead в Yandex Cloud)
Продолжаем делиться экспертизой команды курса «Разработка ИИ-агентов».
Роман собрал мастхев-инструменты и ключевые работы для тех, кто хочет выйти за рамки вайбкодинга.
🛠️ Полезные инструменты:
• Understand Anything — граф знаний по коду и зависимостям.
• DeepTutor — open-source платформа для персонализированного обучения.
• Superpowers — набор практик для системной разработки с ИИ.
• Awesome Agent Skills — коллекция навыков для ИИ-агентов.
📚 Ключевые работы по LLM:
• Attention Is All You Need (2017) — архитектура Transformer.
• GPT-1 (2018) — начало эпохи GPT.
• GPT-2 (2019) — решение новых задач без дообучения.
• GPT-3 (2020) — обучение на примерах из запроса.
• InstructGPT (2022) — RLHF и современные чат-боты.
На курсе Роман выступает консультантом программы: помогает формировать содержание уроков с опорой на актуальные инженерные практики».
Занять свое место на потоке:
👉 Курс «Разработка ИИ-агентов» | 2 413 |
| 17 | 🤩 Разбор строк через 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 404 |
| 18 | 📰 Первый летний дайджест
Короткий, как и отпуск..
— Go закрыл три уязвимости
Вышли версии Go 1.26.4 и 1.25.11. Закрывают три уязвимости в стандартной библиотеке.
— Go может разрешить превращать функции в интерфейсы с одним методом
В трекере Go обсуждают предложение #47487. Оно разрешает приводить значение функции к интерфейсу с ровно одним методом, если сигнатура функции совпадает с сигнатурой этого метода.
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoLive | 2 499 |
| 19 | 🧑💻 Конструктор, из которого собран 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 | 2 370 |
| 20 | Попросил нейронку написать счётчик сотрудников..
📍 Навигация: Вакансии • Задачи • Собесы • Канал в Max
🐸 Библиотека Go-разработчика
#GoGiggle | 2 593 |
Endi mavjud! Telegram Tadqiqoti 2025 — yilning asosiy insaytlari 
