This media is not supported in your browser
VIEW IN TELEGRAM
Легко визуализируйте граф зависимостей вашего Go-проекта с внешними модулями
Преобразуйте граф зависимостей вашего Go-проекта в динамичную, интерактивную визуализацию с помощью modview. Этот мощный инструмент устраняет сложность понимания графа модулей, предоставляя чёткое и удобное представление зависимостей вашего проекта.
modview использует вывод команды
https://github.com/bayraktugrul/modview
👉 @golang_lib
Преобразуйте граф зависимостей вашего Go-проекта в динамичную, интерактивную визуализацию с помощью modview. Этот мощный инструмент устраняет сложность понимания графа модулей, предоставляя чёткое и удобное представление зависимостей вашего проекта.
modview использует вывод команды
go mod graph для создания визуализации в браузере, позволяя вам легко перемещаться по графу, искать элементы и понимать структуру зависимостей. Независимо от того, оптимизируете ли вы кодовую базу, решаете конфликты версий или изучаете экосистему вокруг вашего проекта - modview станет вашим путеводителем в сложном мире модулей Go.https://github.com/bayraktugrul/modview
👉 @golang_lib
👍2❤1
🧑💻 Все еще пишешь типовой код вручную?
Есть способ лучше. Кодогенерация в Go — это мощный инструмент, который автоматизирует рутину и расширяет возможности языка.
На открытом уроке «Кодогенерация в Go: код, который не пришлось писать» разберем, как это работает. Поговорим о том, когда кодогенерация уместна, какие механизмы Go ее позволяют и как это применяется в реальных проектах.
❗️ Это тот случай, когда нейросети не заменят глубокого понимания механизмов языка. Практикующий разработчик с опытом в продакшене покажет, как избежать подводных камней и применять кодогенерацию в рабочих проектах. Ваш шанс научиться создавать более эффективные и лаконичные решения. Перестаньте тратить время на шаблонные задачи и начните генерировать код, который работает за вас.
🗓 Урок пройдет 19 ноября в 20:00 в преддверии старта курса «Golang Developer. Professional». Все участники вебинара получат скидку на обучение. Регистрируйтесь по ссылке, чтобы освоить один из самых перспективных навыков в Go: https://vk.cc/cRnaj1
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Есть способ лучше. Кодогенерация в Go — это мощный инструмент, который автоматизирует рутину и расширяет возможности языка.
На открытом уроке «Кодогенерация в Go: код, который не пришлось писать» разберем, как это работает. Поговорим о том, когда кодогенерация уместна, какие механизмы Go ее позволяют и как это применяется в реальных проектах.
Реклама. ООО «Отус онлайн-образование», ОГРН 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
Меня зовут Макс, я 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
Когда я присоединяюсь к новой компании, меня часто посещает синдром самозванца. После всех этих собеседований кажется, что парни знают, что делают и я смиренно настравиаюсь учиться у лучших.
Однажды, я столкнулся с инцидентом на проде и обратился за помощью к самому опытному инженеру. Он пришел на помощь и с легкостью изменил значение в БД с помощью... ручного обновления. 🤯 Проблема заключалась в том, что набор SQL-обновлений не был выполнен внутри транзакции.
Работа в новой компании — это всегда увлекательно. Я осознал, что даже если какой-то аспект кажется простым, например, SQL-транзакции, его легко упустить из виду.
SQL кажется чем-то, что мы все хорошо знаем, и мало чем может удивить. (Ему уже 50 лет!) Возможно, пришло время пересмотреть подходы, так как мы уже прошли фазу хайпа по поводу NoSQL, и снова возвращаемся к “используйте просто Postgres”, а иногда и к “SQLite тут за глаза”.
Я хочу сосредоточиться на том, как правильно применять транзакции в коде, а не на их технической сложности. Когда ваш проект становится больше, вы начинаете разделять логику и код базы данных с помощью слоев. Однако это не всегда так просто, как кажется. Вы можете запутаться и столкнуться с неочевидными ошибками.
Основной принцип многослойной архитектуры заключается в разделении критически важных частей кода (логики) от деталей реализации (например, SQL-запросов). Одним из способов достижения такого разделения является паттерн «Репозиторий». Однако, наиболее сложным аспектом такой архитектуры является обработка транзакций.
Когда мы используем транзакции, обычно происходит следующее: сначала мы получаем данные из базы, затем выполняем необходимую логику, обновляем данные и коммитим транзакцию.
Как же организовать код таким образом, чтобы избежать путаницы между слоями? Я часто вижу, как люди задаются этим вопросом, и мне знакома эта боль. Мы сами искали решение, и со временем наши подходы менялись. Вот список различных методов, которые можно рассмотреть, и всё, что я узнал по этому поводу.
https://habr.com/ru/articles/848596/
👉 @golang_lib
👍4
11 декабря(уже в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Go-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для 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
Таймкоды:
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. Звучит как идеальный план на вечер среды. Только не забудьте зарегистрироваться по ссылке и добавить встречу в календарь.
За полтора часа стрима вы научитесь:
— понимать внутреннюю механику линтеров;
— писать свои анализаторы под нужды проекта;
— работать с 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-таблицы.
- Поддерживает рамки, цвета, заголовки и футеры.
- Умеет объединять ячейки (как
- Экспорт в CSV, HTML и Markdown.
2. Прогресс-бары (Progress Bars):
- Показывает полосы загрузки или выполнения задач.
- Умеет отслеживать несколько задач одновременно.
- Показывает скорость, ETA (время до окончания) и проценты.
3. Списки (Lists):
- Форматирует иерархические списки (деревья) с отступами и различными стилями маркеров.
4. Работа с текстом (Text):
- Утилиты для выравнивания текста (по центру, слева, справа).
- Управление цветами и стилями (жирный, курсив) с поддержкой ANSI-кодов.
https://github.com/jedib0t/go-pretty
👉 @golang_lib
Это популярная библиотека для языка программирования 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
👍3❤1
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
На открытом уроке 23 декабря в 20:00 МСК разберём, как работать с HTTP-клиентом и сервером: от простых GET-запросов до JSON-RPC. Покажем, как строить REST API с роутингом, контекстом, авторизацией, логированием и rate-limiting.
Максимальная скидка 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).
Сравним две структуры:
📉 Кажется, что 8 байт разницы - ерунда. Но:
1. Масштаб: Если у вас слайс из 10 миллионов таких структур, вы экономите ~76 МБ RAM просто переставив поля.
2. CPU Cache & Spatial Locality: Меньший размер структуры = больше структур влезает в кэш-линию процессора (обычно 64 байта). Это снижает Cache Miss rate и ускоряет итерацию по слайсам.
🛠 Не нужно считать байты в уме.
Используйте fieldalignment из официальных тулзов:
💡 В Go 1.20+ и новее аллокатор стал умнее, но физику не обманешь. Если вы пишете под архитектуры с жестким выравниванием (например, ARM или WASM), игнорирование alignment может привести не просто к оверхеду, а к панике при атомарных операциях (хотя Go старается это хэндлить).
#golang #optimization #architecture #memory
👉 @golang_lib
Часто при проектировании структур мы группируем поля логически: 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
25 декабря(уже в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Go-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Go-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_go_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
🧠 sync.Pool: Это не кэш, это амортизатор GC
Многие используют
Разберем неочевидные нюансы, которые могут выстрелить в ногу.
1. Механика Victim Cache (Go 1.13+)
До версии 1.13
Сейчас работает механизм Victim Cache:
🩵 При GC данные не удаляются, а перемещаются в «жертвенный» кэш (victim).
🩵 При запросе
🩵 Данные удаляются окончательно только если они пережили два цикла GC без использования.
👉 Это сглаживает latency, но не гарантирует сохранность данных. Никогда не полагайтесь на то, что объект останется в пуле.
2. Локальность данных и Per-P Sharding
🩵 У каждого P есть свой
🩵 Горутина всегда пытается взять объект из локального P. Если там пусто — пытается «украсть» (steal) из shared-списка другого P.
👉
3. Проблема «Толстых» объектов и Memory Leaks
Классическая ошибка: использовать пул для
Если однажды через пул пролетит буфер на 100 МБ, и вы вернете его через
Решение: Перед
4. Reset State - зона ответственности разработчика
Всегда делайте явный
✅ Идеально для: Hot-path, сериализаторов (json/proto), буферов, короткоживущих DTO.
❌ Плохо для: Долгоживущих объектов, кэширования БД-запросов, объектов с огромным разбросом размеров.
#golang #internals #gc #performance #syncpool
👉 @golang_lib
Многие используют
sync.Pool просто чтобы «сэкономить память». Но вы должны понимать физику процесса: sync.Pool предназначен не для хранения состояния, а для снижения GC pressure (нагрузки на сборщик мусора) путем переиспользования короткоживущих объектов.Разберем неочевидные нюансы, которые могут выстрелить в ногу.
1. Механика Victim Cache (Go 1.13+)
До версии 1.13
sync.Pool полностью очищался при каждом запуске GC. Это вызывало спайки CPU: сразу после GC пул пуст, аллокации взлетают, GC снова триггерится быстрее.Сейчас работает механизм Victim Cache:
Get() сначала проверяется основной пул, затем victim.👉 Это сглаживает latency, но не гарантирует сохранность данных. Никогда не полагайтесь на то, что объект останется в пуле.
2. Локальность данных и Per-P Sharding
sync.Pool внутри - это не один мьютекс на всех. Это массив localPool для каждого P (процессора, GOMAXPROCS).private (lock-free доступ) и shared (thread-safe, для "кражи" другими 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
Этот всеобъемлющий курс поможет вам пройти путь от новичка до опытного 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
👍2❤1
Accept Interfaces, Return Structs
В Go-комьюнити есть пословица, которую часто нарушают выходцы из Java или C#: "Accept interfaces, return structs".
Вижу в PR часто такую картину: разработчик создает сервис и сразу интерфейс к нему, хотя реализация всего одна.
Почему не надо возвращать интерфейс?
Когда ваша функция возвращает интерфейс, вы отнимаете у пользователя этой функции гибкость. Он вынужден работать с абстракцией, даже если ему нужны детали конкретной структуры. Плюс, это усложняет навигацию по коду (Go to definition ведет в интерфейс, а не в код).
Почему надо принимать интерфейс?
Это и есть Dependency Injection по-гошному.
Если вашей функции нужно просто "что-то, что умеет читать байты", не требуйте
Пример:
❌ Плохо (Pre-emptive interfaces):
✅ Хорошо:
Определяйте интерфейс там, где он используется, а не там, где он реализуется. Это делает код менее связанным.
#golang #architecture #clean_code
👉 @golang_lib
В 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
Внутри
Смотрим код:
В чем проблема?
В цикле с высокой нагрузкой вы создадите тысячи таймеров, которые будут ждать свои 3 минуты, пожирая хип.
Решение:
Используйте
Да, кода больше. Да, выглядит не так элегантно. Зато OOM Killer не придет к вам ночью.
#golang #performance #memory_leak
👉 @golang_lib
Внутри
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
👍9❤1
This media is not supported in your browser
VIEW IN TELEGRAM
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2👎1🤣1🤓1
JSON быстрее, чем вы думаете
Стандартный
Если ваш сервис в основном занимается перекладыванием JSON-ов, посмотрите в сторону генерации кода.
Лично я в проде часто использую easyjson или fastjson (для парсинга без структуры), но сейчас набирает популярность Sonic (от ByteDance).
🚀 Sonic:
🩵 Использует JIT-компиляцию (нужен AVX на CPU).
🩵 В 2-3 раза быстрее стандартной библиотеки.
🩵 API совместим с
⚠️ Warning: Sonic работает только на Linux/macOS и amd64/arm64. Если деплоите на Windows или экзотику - аккуратнее.
Кто что юзает для JSON в 202X? Пишите в комменты.
#golang #libs #performance
👉 @golang_lib
Стандартный
encoding/json в Go надежный, но... медленный. Он активно использует рефлексию, что бьет по CPU на высоконагруженных сервисах.Если ваш сервис в основном занимается перекладыванием JSON-ов, посмотрите в сторону генерации кода.
Лично я в проде часто использую easyjson или fastjson (для парсинга без структуры), но сейчас набирает популярность Sonic (от ByteDance).
🚀 Sonic:
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
Хватит мучить
Каждый джун проходит этот путь:
1. Запускаем 10 горутин через
2. Добавляем
3. Понимаем, что одна горутина может вернуть ошибку.
4. Создаем канал для ошибок, мьютекс или (о ужас) глобальную переменную.
5. Код превращается в нечитаемую простыню.
Коллеги, для групповых задач с возвратом ошибок есть стандартный (почти) инструмент - errgroup.
Пакет
1. Ждет завершения всех горутин.
2. Возвращает первую случившуюся ошибку.
3. (Опционально) Отменяет контекст для остальных, если кто-то один упал.
Как это выглядит:
🔥 Senior Tip:
В последних версиях добавили метод
Это киллер-фича. Она превращает
Чисто, лаконично, и никаких дедлоков на
#golang #concurrency #patterns #bestpractices
👉 @golang_lib
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🔥3⚡2
29 января(в четверг!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Go-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Go-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_go_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
"Семафор". Не убей базу данных
Запустить 10,000 горутин в Go дешево. А вот открыть 10,000 коннектов к базе или внешнему API - дорого и больно.
Если вы просто запустите
Самый идиоматичный способ в Go - буферизированный канал в роли семафора.
Реализация:
Почему это круто:
1. Backpressure: Мы не создаем миллион горутин, которые висят в
2. Простота: Никаких внешних библиотек.
Нюанс для профи:
Если порядок обработки не важен - это идеальное решение. Если важен - смотрите в сторону Pipeline паттерна.
Ставьте ❤️, если хоть раз роняли прод, забыв про лимиты.
#golang #concurrency #semaphore #architecture
👉 @golang_lib
Запустить 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