Библиотека Go (Golang) разработчика – Telegram
Библиотека Go (Golang) разработчика
2.7K subscribers
313 photos
102 videos
29 files
391 links
Полезные материалы по всему, что может быть полезно Golang разработчику. По всем вопросам @evgenycarter
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
Легко визуализируйте граф зависимостей вашего Go-проекта с внешними модулями

Преобразуйте граф зависимостей вашего Go-проекта в динамичную, интерактивную визуализацию с помощью modview. Этот мощный инструмент устраняет сложность понимания графа модулей, предоставляя чёткое и удобное представление зависимостей вашего проекта.

modview использует вывод команды go mod graph для создания визуализации в браузере, позволяя вам легко перемещаться по графу, искать элементы и понимать структуру зависимостей. Независимо от того, оптимизируете ли вы кодовую базу, решаете конфликты версий или изучаете экосистему вокруг вашего проекта - modview станет вашим путеводителем в сложном мире модулей Go.

https://github.com/bayraktugrul/modview

👉 @golang_lib
👍21
🧑‍💻 Все еще пишешь типовой код вручную?

Есть способ лучше. Кодогенерация в Go — это мощный инструмент, который автоматизирует рутину и расширяет возможности языка.

На открытом уроке «Кодогенерация в Go: код, который не пришлось писать» разберем, как это работает. Поговорим о том, когда кодогенерация уместна, какие механизмы Go ее позволяют и как это применяется в реальных проектах.

❗️Это тот случай, когда нейросети не заменят глубокого понимания механизмов языка. Практикующий разработчик с опытом в продакшене покажет, как избежать подводных камней и применять кодогенерацию в рабочих проектах. Ваш шанс научиться создавать более эффективные и лаконичные решения. Перестаньте тратить время на шаблонные задачи и начните генерировать код, который работает за вас.

🗓 Урок пройдет 19 ноября в 20:00 в преддверии старта курса «Golang Developer. Professional». Все участники вебинара получат скидку на обучение. Регистрируйтесь по ссылке, чтобы освоить один из самых перспективных навыков в Go: https://vk.cc/cRnaj1

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
Оптимизация Go: как повысить скорость и эффективность кода

Меня зовут Макс, я Go-разработчик в компании SimbirSoft. Язык Go (Golang) стремительно набирает популярность, он всё чаще внедряется в существующие программные решения, а также встречается в стеке новых проектов. Высокая производительность и скорость работы – его главные преимущества, поэтому для реализации бизнес-задач он подходит как нельзя кстати. Go легко поддерживается и отлично годится для создания MVP, из-за чего востребованность в нём растёт.

Но чтобы этот язык программирования был действительно производительным, разработчикам необходимо учитывать некоторые тонкости работы с ним. Иначе ваше приложение станет таким же медленным, как айтишник без чашки кофе :) В этой статье мы с вами на примерах разберём часто возникающие ситуации при работе с Go, а также рассмотрим приёмы, которые позволят повысить производительность кода. Надеюсь, разработчики уровня джуниор и мидл смогут почерпнуть для себя что-то полезное.

https://habr.com/ru/companies/simbirsoft/articles/819015/

👉 @golang_lib
👍2
Транзакции в БД на Go с использованием многослойной архитектуры

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

Однажды, я столкнулся с инцидентом на проде и обратился за помощью к самому опытному инженеру. Он пришел на помощь и с легкостью изменил значение в БД с помощью... ручного обновления. 🤯 Проблема заключалась в том, что набор SQL-обновлений не был выполнен внутри транзакции.

Работа в новой компании — это всегда увлекательно. Я осознал, что даже если какой-то аспект кажется простым, например, SQL-транзакции, его легко упустить из виду.

SQL кажется чем-то, что мы все хорошо знаем, и мало чем может удивить. (Ему уже 50 лет!) Возможно, пришло время пересмотреть подходы, так как мы уже прошли фазу хайпа по поводу NoSQL, и снова возвращаемся к “используйте просто Postgres”, а иногда и к “SQLite тут за глаза”.

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

Основной принцип многослойной архитектуры заключается в разделении критически важных частей кода (логики) от деталей реализации (например, SQL-запросов). Одним из способов достижения такого разделения является паттерн «Репозиторий». Однако, наиболее сложным аспектом такой архитектуры является обработка транзакций.

Когда мы используем транзакции, обычно происходит следующее: сначала мы получаем данные из базы, затем выполняем необходимую логику, обновляем данные и коммитим транзакцию.

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

https://habr.com/ru/articles/848596/

👉 @golang_lib
👍4
🔍Тестовое собеседование с Go-разработчиком из Яндекса

11 декабря(уже в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Go-разработчика.

Как это будет:
📂 Владислав Кирпичов, Go-разработчик в Яндексе, ex-VK, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Влад будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Владу

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Go-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир →
@shortcut_go_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
Media is too big
VIEW IN TELEGRAM
Ты не все знаешь о массивах и слайсах в Go

Таймкоды:
00:00 - Введение
00:47 - Устройство массивов в Go
01:40 - Работа с массивами в Go
10:00 - Перемещение массива в стеке
11:29 - Итерация по массивам в Go
15:11 - Где аллоцируются массивы в Go
17:22 - Педедача массива в функцию
18:16 - Слайсы в Go
21:34 - Реаллокация слайса в Go
24:45 - Резервирование памяти под слайс
25:44 - Создание слайса без инициализации
27:38 - Модификация строк в Go
28:35 - Приведение слайсов в строки и обратно без копирования
30:13 - Передача слайса в функцию
31:12 - Итерация по слайсам в Go
33:55 - Оптимизация итерации по слайсам в Go
35:42 - Получение слайсов в Go
42:40 - Получение слайса из массива в Go
43:15 - Конвертация слайса в массив в Go
44:15 - Конвертация слайса в указатель на массив в Go
45:02 - Указатель на нулевой массив в Go
46:18 - Удаление из конца слайса в Go
46:51 - Удаление из начала слайса в Go
49:02 - Реализация стека и очереди в Go
50:00 - Как увеличить размер слайса в Go
50:48 - Как уменьшить емкость слайса в Go
54:05 - Где аллоцируются слайсы в Go
59:12 - Как очистить слайс в Go
01:01:51 - В чем разница пустых и нулевых слайсов в Go
01:05:17 - Как сравнивать слайсы в Go
01:07:53 - Как скопировать данные слайса в Go
01:09:47 - Почему функция appeng возвращает слайсв в Go
01:12:39 - Потенциальные проблемы с функцией append в Go
01:14:10 - Реализация функции append в Go
01:15:32 - Утечки памяти при работе со слайсами в Go
01:21:59 - Курс по глубокому Go

источник

👉 @golang_lib
👍3
Ещё не пишете собственные линтеры? Приходите на Go live-coding от коллег из AvitoTech 17 декабря 🚀ㅤㅤ

За полтора часа стрима вы научитесь:
— понимать внутреннюю механику линтеров;
— писать свои анализаторы под нужды проекта;
— работать с AST Go-проектов.

Вместе со спикером Вячеславом Овчинниковым вы напишете собственный линтер на базе go/ast и go/types. Звучит как идеальный план на вечер среды. Только не забудьте зарегистрироваться по ссылке и добавить встречу в календарь.
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Go-pretty

Это популярная библиотека для языка программирования Go (Golang), которая используется для красивого форматирования текста в консоли (терминале).

Если вы пишете CLI-утилиты (программы командной строки), эта библиотека помогает превратить скучный текстовый вывод в структурированные и приятные для глаз данные.

Основные возможности библиотеки:

1. Таблицы (Tables):

- Создает красивые ASCII-таблицы.
- Поддерживает рамки, цвета, заголовки и футеры.
- Умеет объединять ячейки (как colspan / rowspan в HTML).
- Экспорт в CSV, HTML и Markdown.

2. Прогресс-бары (Progress Bars):

- Показывает полосы загрузки или выполнения задач.
- Умеет отслеживать несколько задач одновременно.
- Показывает скорость, ETA (время до окончания) и проценты.

3. Списки (Lists):

- Форматирует иерархические списки (деревья) с отступами и различными стилями маркеров.

4. Работа с текстом (Text):

- Утилиты для выравнивания текста (по центру, слева, справа).
- Управление цветами и стилями (жирный, курсив) с поддержкой ANSI-кодов.


https://github.com/jedib0t/go-pretty

👉 @golang_lib
👍31
This media is not supported in your browser
VIEW IN TELEGRAM
👣 Пишете на Go и хотите изучить HTTP?

На открытом уроке 23 декабря в 20:00 МСК разберём, как работать с HTTP-клиентом и сервером: от простых GET-запросов до JSON-RPC. Покажем, как строить REST API с роутингом, контекстом, авторизацией, логированием и rate-limiting.

❗️ Урок будет полезен Go-разработчикам, которые хотят уверенно писать продакшн-сервисы. Вы увидите связку стандартной библиотеки, middleware и подходов к оптимизации через пулы соединений и таймауты.

➡️ Встречаемся в преддверие старта курса «Golang Developer. Professional», регистрация открыта: https://vk.cc/cSwiLE

🎄 Учитесь в новом году по старым ценам!
Максимальная скидка 30% на обучение до 21.12.2025:
1 курс — тающая скидка 15% до 21.12
2 курса −25%, 3 курса −30%
Учиться системно — выгоднее!

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
Memory Alignment: Когда порядок полей стоит гигабайты

Часто при проектировании структур мы группируем поля логически: ID рядом с Name, флаги рядом с конфигами. Но с точки зрения железа и аллокатора Go - это может быть расточительством.

Для Senior-разработчика понимание padding (отступов) и alignment (выравнивания) - мастхэв, особенно в HighLoad проектах, где крутятся миллионы объектов в памяти.

🔍CPU читает память машинными словами (обычно 64 бита / 8 байт). Чтобы доступ был атомарным и быстрым, компилятор Go выравнивает поля по адресам, кратным их размеру. Если поля идут в «неудачном» порядке, компилятор вставляет пустые байты (padding).

Сравним две структуры:


// Bad layout
type BadStruct struct {
Flag bool // 1 byte
// +7 bytes padding
Counter int64 // 8 bytes
Active bool // 1 byte
// +7 bytes padding (для выравнивания всей структуры)
}
// Итог: 24 байта (Sizeof)




// Good layout
type GoodStruct struct {
Counter int64 // 8 bytes
Flag bool // 1 byte
Active bool // 1 byte
// +6 bytes padding
}
// Итог: 16 байт (Sizeof)



📉 Кажется, что 8 байт разницы - ерунда. Но:

1. Масштаб: Если у вас слайс из 10 миллионов таких структур, вы экономите ~76 МБ RAM просто переставив поля.
2. CPU Cache & Spatial Locality: Меньший размер структуры = больше структур влезает в кэш-линию процессора (обычно 64 байта). Это снижает Cache Miss rate и ускоряет итерацию по слайсам.

🛠 Не нужно считать байты в уме.
Используйте fieldalignment из официальных тулзов:


go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@latest
fieldalignment -fix ./...



Внимание: -fix может нарушить вашу «логическую» группировку полей и добавить комментарии, так что используйте с умом (или добавьте в линтер как варнинг).


💡 В Go 1.20+ и новее аллокатор стал умнее, но физику не обманешь. Если вы пишете под архитектуры с жестким выравниванием (например, ARM или WASM), игнорирование alignment может привести не просто к оверхеду, а к панике при атомарных операциях (хотя Go старается это хэндлить).

#golang #optimization #architecture #memory

👉 @golang_lib
🔥10
🔴 Тестовое собеседование с Go-разработчиком из Яндекса

25 декабря(уже в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Go-разработчика.

Как это будет:
📂 Владислав Кирпичов, Go-разработчик в Яндексе, ex-VK, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Влад будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Владу

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Go-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир →
@shortcut_go_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
🧠 sync.Pool: Это не кэш, это амортизатор GC

Многие используют sync.Pool просто чтобы «сэкономить память». Но вы должны понимать физику процесса: sync.Pool предназначен не для хранения состояния, а для снижения GC pressure (нагрузки на сборщик мусора) путем переиспользования короткоживущих объектов.

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

1. Механика Victim Cache (Go 1.13+)
До версии 1.13 sync.Pool полностью очищался при каждом запуске GC. Это вызывало спайки CPU: сразу после GC пул пуст, аллокации взлетают, GC снова триггерится быстрее.

Сейчас работает механизм Victim Cache:
🩵При GC данные не удаляются, а перемещаются в «жертвенный» кэш (victim).
🩵При запросе Get() сначала проверяется основной пул, затем victim.
🩵 Данные удаляются окончательно только если они пережили два цикла GC без использования.

👉 Это сглаживает latency, но не гарантирует сохранность данных. Никогда не полагайтесь на то, что объект останется в пуле.

2. Локальность данных и Per-P Sharding
sync.Pool внутри - это не один мьютекс на всех. Это массив localPool для каждого P (процессора, GOMAXPROCS).
🩵 У каждого P есть свой private (lock-free доступ) и shared (thread-safe, для "кражи" другими P) списки.
🩵 Горутина всегда пытается взять объект из локального P. Если там пусто — пытается «украсть» (steal) из shared-списка другого P.

👉 sync.Pool работает молниеносно в happy path (lock-free), но если у вас перекос нагрузки и горутины часто мигрируют между процессорами, эффективность падает из-за lock contention при "краже".

3. Проблема «Толстых» объектов и Memory Leaks
Классическая ошибка: использовать пул для bytes.Buffer или слайсов без контроля размера.
Если однажды через пул пролетит буфер на 100 МБ, и вы вернете его через Put(), он засядет в памяти до следующего GC (или дольше, из-за victim cache). В высоконагруженном сервисе это может привести к тому, что весь пул будет забит огромными кусками памяти, хотя 99% запросов требуют 1 КБ.

Решение: Перед Put() проверяйте Cap() слайса/буфера. Если он превышает разумный порог - выбрасывайте его (пусть GC заберет), не кладите в пул.


var bufPool = sync.Pool{
New: func() any { return new(bytes.Buffer) },
}

func process() {
b := bufPool.Get().(*bytes.Buffer)
b.Reset() // Обязательно сбрасываем состояние!
defer func() {
// Защита от утечки памяти: не возвращаем гигантские буферы
if b.Cap() <= 64*1024 {
bufPool.Put(b)
}
}()
// logic...
}



4. Reset State - зона ответственности разработчика
sync.Pool не обнуляет поля структуры. Если вы взяли объект, записали туда чувствительные данные (token, PII) и вернули в пул, следующая горутина может прочитать этот мусор.
Всегда делайте явный Reset() методов у структур после Get() (или перед Put(), но лучше после Get для надежности).

Идеально для: Hot-path, сериализаторов (json/proto), буферов, короткоживущих DTO.
Плохо для: Долгоживущих объектов, кэширования БД-запросов, объектов с огромным разбросом размеров.

#golang #internals #gc #performance #syncpool

👉 @golang_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Media is too big
VIEW IN TELEGRAM
Полный курс по программированию на Golang (Eng Ver)

Этот всеобъемлющий курс поможет вам пройти путь от новичка до опытного Go-разработчика. Вы изучите всё: от установки и настройки Go до освоения структур данных, управляющих конструкций, функций и таких продвинутых тем, как конкурентность и интерфейсы.

📌 00:00 Chapter 0: Introduction – Overview of Go, its features, and why it's great for system programming and web development.

📌 07:36 Chapter 1: Setup – Install Go and set up your development environment.

📌 12:28 Chapter 2: Basic Syntax – Write your first Go program and understand Go’s syntax and structure.

📌18:28 Chapter 3: Data Types – Explore Go’s primitive data types like integers, floats, booleans, and strings.

📌 29:55 Chapter 4: Variables – Learn about variable declaration, initialization, and scoping in Go.

📌 44:59 Chapter 5: Constants – Discover how constants work in Go and why they are useful.

📌 54:52 Chapter 6: Operators – Understand arithmetic, comparison, logical, and bitwise operators in Go.

📌 1:08:02 Chapter 7: Control Flow (if-else) – Learn how to use conditional statements to control the flow of your programs.

📌 1:13:47 Chapter 8: Control Flow (Loops) – Master for loops, range, and loop control mechanisms in Go.

📌 1:25:08 Chapter 9: Functions – Understand how to define and use functions, including variadic functions and multiple return values.

📌 1:37:25 Chapter 10: Scope – Learn about local and global scope, closures, and best practices for managing variable visibility.

📌 1:43:02 Chapter 11: Strings – Work with strings, understand string manipulation, and explore Go’s built-in string functions.

📌 1:49:39 Chapter 12: Arrays – Learn how to use fixed-size arrays and their practical use cases.

📌 1:54:25 Chapter 13: Pointers – Understand pointers, memory addresses, and how Go handles memory safely.

📌 1:59:48 Chapter 14: Structures (Structs) – Define and use structs to organize data more effectively.

📌 2:05:20 Chapter 15: Slices – Dive into dynamic data structures and how slices differ from arrays.

📌 2:18:41 Chapter 16: Range – Learn how to iterate over collections using the range keyword.

📌 2:22:01 Chapter 17: Maps – Work with key-value pairs and understand how Go's hash maps work.

📌 2:30:15 Chapter 18: Recursion – Learn recursive function calls and when to use them.
Recursion (functional Programming): • Functional Programming | [ Part C : Recurs...

📌 2:35:09 Chapter 19: Type Casting – Convert between different data types safely and efficiently.

📌 2:40:35 Chapter 20: Interfaces – Explore Go’s interface system and how to achieve polymorphism.

📌 2:48:38 Chapter 21: Error Handling – Understand Go’s unique approach to error handling using error values and best practices.

источник

👉 @golang_lib
👍21
Accept Interfaces, Return Structs

В Go-комьюнити есть пословица, которую часто нарушают выходцы из Java или C#: "Accept interfaces, return structs".

Вижу в PR часто такую картину: разработчик создает сервис и сразу интерфейс к нему, хотя реализация всего одна.

Почему не надо возвращать интерфейс?
Когда ваша функция возвращает интерфейс, вы отнимаете у пользователя этой функции гибкость. Он вынужден работать с абстракцией, даже если ему нужны детали конкретной структуры. Плюс, это усложняет навигацию по коду (Go to definition ведет в интерфейс, а не в код).

Почему надо принимать интерфейс?
Это и есть Dependency Injection по-гошному.
Если вашей функции нужно просто "что-то, что умеет читать байты", не требуйте *os.File. Требуйте io.Reader.

Пример:

Плохо (Pre-emptive interfaces):


type UserService interface {
GetUser(id int) User
}

func NewUserService() UserService { ... } // Возвращаем интерфейс



Хорошо:


func NewUserService() *UserService { ... } // Возвращаем структуру

// А вот на стороне потребителя:
type UserFetcher interface {
GetUser(id int) User
}

func ProcessUser(f UserFetcher) { ... } // Принимаем интерфейс



Определяйте интерфейс там, где он используется, а не там, где он реализуется. Это делает код менее связанным.

#golang #architecture #clean_code

👉 @golang_lib
👎3👍2🤔2
Тихая смерть памяти c time.After

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

Смотрим код:


for {
select {
case msg := <-ch:
process(msg)
case <-time.After(3 * time.Minute):
return errors.New("timeout")
}
}



В чем проблема?
time.After создает таймер, который не собирается мусорщиком, пока не истечет его время. Даже если case msg := <-ch сработает мгновенно, таймер на 3 минуты останется висеть в памяти.

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

Решение:
Используйте time.NewTimer и останавливайте его вручную.


timer := time.NewTimer(3 * time.Minute)
defer timer.Stop()

for {
timer.Reset(3 * time.Minute)
select {
case msg := <-ch:
process(msg)
if !timer.Stop() {
<-timer.C
}
case <-timer.C:
return errors.New("timeout")
}
}



Да, кода больше. Да, выглядит не так элегантно. Зато OOM Killer не придет к вам ночью.

#golang #performance #memory_leak

👉 @golang_lib
👍91
This media is not supported in your browser
VIEW IN TELEGRAM
🔼 Требования к Go-разработчикам растут быстрее, чем обновляются резюме. То, что вчера считалось сильным навыком, завтра становится необходимым опытом.

🗓 15 января в 20:00 МСК пройдет встреча с двумя экспертами, которые формируют требования к рынку: рекрутером Ксенией Маловой, знающей, почему 90% кандидатов отсеиваются ещё до техсобеса, и архитектором Александром Хохловым, который понимает, какие инженерные компетенции станут критичными для новых проектов.

❗️ Разберём тренды, требования и реальные ожидания компаний, поговорим о том, какие пробелы чаще всего мешают росту и как сформировать долгосрочную траекторию развития в Go-разработке.

▶️ Встречаемся в преддверие старта курса «Golang Developer. Professional», регистрация открыта: https://vk.cc/cTke9z

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2👎1🤣1🤓1
JSON быстрее, чем вы думаете

Стандартный encoding/json в Go надежный, но... медленный. Он активно использует рефлексию, что бьет по CPU на высоконагруженных сервисах.

Если ваш сервис в основном занимается перекладыванием JSON-ов, посмотрите в сторону генерации кода.

Лично я в проде часто использую easyjson или fastjson (для парсинга без структуры), но сейчас набирает популярность Sonic (от ByteDance).

🚀 Sonic:

🩵Использует JIT-компиляцию (нужен AVX на CPU).
🩵В 2-3 раза быстрее стандартной библиотеки.
🩵API совместим с encoding/json (почти drop-in replacement).


import "github.com/bytedance/sonic"

var json = sonic.ConfigDefault

// Используем как обычно
output, err := json.Marshal(&data)



⚠️ Warning: Sonic работает только на Linux/macOS и amd64/arm64. Если деплоите на Windows или экзотику - аккуратнее.

Кто что юзает для JSON в 202X? Пишите в комменты.

#golang #libs #performance

👉 @golang_lib
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Хватит мучить sync.WaitGroup для HTTP-запросов

Каждый джун проходит этот путь:

1. Запускаем 10 горутин через go func().
2. Добавляем wg.Add(1).
3. Понимаем, что одна горутина может вернуть ошибку.
4. Создаем канал для ошибок, мьютекс или (о ужас) глобальную переменную.
5. Код превращается в нечитаемую простыню.

Коллеги, для групповых задач с возвратом ошибок есть стандартный (почти) инструмент - errgroup.

Пакет golang.org/x/sync/errgroup делает три вещи, которые вы обычно пишете руками:

1. Ждет завершения всех горутин.
2. Возвращает первую случившуюся ошибку.
3. (Опционально) Отменяет контекст для остальных, если кто-то один упал.

Как это выглядит:


import "golang.org/x/sync/errgroup"

func fetchAll(urls []string) error {
// Создаем группу и контекст
g, _ := errgroup.WithContext(context.Background())

for _, url := range urls {
url := url // Go 1.22 fix not needed, but habit 🙂

// g.Go принимает функцию вида func() error
g.Go(func() error {
resp, err := http.Get(url)
if err == nil {
resp.Body.Close()
}
return err // Если вернем err != nil, контекст отменится
})
}

// Ждем всех. Если была ошибка — получим её.
return g.Wait()
}



🔥 Senior Tip:
В последних версиях добавили метод g.SetLimit(n).
Это киллер-фича. Она превращает errgroup в Worker Pool с ограничением конкурентности. Больше не нужно создавать семафоры на каналах, чтобы не за-DDOS-ить внешний API. Просто добавьте g.SetLimit(10) перед циклом.

Чисто, лаконично, и никаких дедлоков на wg.Done().

#golang #concurrency #patterns #bestpractices

👉 @golang_lib
👍9🔥32
🔍Тестовое собеседование с Go ТехЛидом из WildBerries в этот четверг

29 января(в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Go-разработчика.

Как это будет:
📂 Рамиль Мясоутов, ТехЛид из WildBerries, ex-Купер будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Рамиль будет комментировать каждый ответ респондента, чтобы дать понять, чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Рамилю

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Go-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир →
@shortcut_go_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
"Семафор". Не убей базу данных

Запустить 10,000 горутин в Go дешево. А вот открыть 10,000 коннектов к базе или внешнему API - дорого и больно.

Если вы просто запустите go func() в цикле по всему слайсу данных, OOM Killer или таймауты придут мгновенно. Нам нужно ограничить количество одновременно работающих воркеров.

Самый идиоматичный способ в Go - буферизированный канал в роли семафора.

Реализация:


func ProcessItems(items []int) {
maxConcurrency := 5
// Семафор — канал с емкостью = лимиту
sem := make(chan struct{}, maxConcurrency)
var wg sync.WaitGroup

for _, item := range items {
wg.Add(1)

// Блокируемся здесь, если в канале уже 5 токенов
sem <- struct{}{}

go func(val int) {
defer wg.Done()
// Освобождаем слот в семафоре при выходе
defer func() { <-sem }()

// Тяжелая логика тут
process(val)
}(item)
}

wg.Wait()
}



Почему это круто:

1. Backpressure: Мы не создаем миллион горутин, которые висят в sleep. Горутина создается только когда есть свободный слот (точнее, цикл for блокируется на записи в канал).
2. Простота: Никаких внешних библиотек.

Нюанс для профи:
Если порядок обработки не важен - это идеальное решение. Если важен - смотрите в сторону Pipeline паттерна.

Ставьте ❤️, если хоть раз роняли прод, забыв про лимиты.

#golang #concurrency #semaphore #architecture

👉 @golang_lib
9