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

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

@goproglib

Все самое полезное для Go-разработчика в одном канале.

Учиться у нас: clc.to/qaSdww

По рекламе: @tproger_sales_bot

Для обратной связи: @proglibrary_feeedback_bot

РКН: https://gosuslugi.ru/snet/67a4a8c24689c2151c752af0

Заявка: 8137752389
Subscribers
24.1K
Photos
2.8K
Videos
54
Links
5.4K

Showing posts older than #7101 · Back to latest

Older Posts 15 shown
Post #7099 3.93K
📶 WiFi на ESP32 через TinyGo

espradio это пакет для TinyGo, который добавляет поддержку беспроводной связи на ESP32-C3 и ESP32-S3. Работает режим WiFi-клиента, точки доступа и сканирование сетей

Под капотом два слоя.

Нижний это бинарные блобы от Espressif, которые вызываются напрямую через CGo. Они отвечают за низкоуровневую работу с радиомодулем.

Верхний слой — чистый Go: пакет lneto реализует сетевой стек второго уровня.

Помимо простого HTTP-сервера в репозитории есть примеры для MQTT, , точки доступа с DHCP-сервером, сканирования WiFi-сетей и низкоуровневой работы через lneto без net/http.

➡️ Репозиторий

📍 Навигация: Вакансии • Задачи • Собесы

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

#GoToProduction
  • ❤‍🔥 6
  • 👍 6
  • 🔥 2
  • ❤ 1
Post #7098 3.71K
⭐️ Task без установки

Если вы пишете на Go и используете Task как таск-раннер, то знаете боль: нужно попросить коллег установить его. У каждого свой пакетный менеджер, своя ОС, свои предпочтения. Часть поставит через Homebrew, часть через apt, часть скачает бинарник вручную. А потом окажется, что версии у всех разные.

Начиная с Go 1.24 это можно решить через механизм go tool.

Что делает go tool

Go умеет компилировать и запускать внешние инструменты, объявленные как зависимости проекта. Версия фиксируется в go.mod, и Go кеширует скомпилированный бинарник, так что повторные вызовы работают быстро.

Как подключить Task

Добавляем Task как tool-зависимость проекта:
go get -tool github.com/go-task/task/v3/cmd/task@latest


В go.mod появится строка:
tool github.com/go-task/task/v3/cmd/task


Вместо просто task везде пишем go tool task:
go tool task build
go tool task test
go tool task lint


Зачем это нужно

• Версия Task теперь зафиксирована в go.mod и go.sum, как любая другая зависимость. Dependabot или Renovate будут обновлять её автоматически.

• CI больше не требует отдельного шага установки Task. Достаточно, чтобы в образе был Go, и go tool task сделает остальное самостоятельно.

• Новые разработчики в команде не тратят время на выяснение, как и откуда ставить таск-раннер. Они просто клонируют репозиторий и работают.

📍 Навигация: Вакансии • Задачи • Собесы

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

#GoToProduction
  • 👍 17
  • ❤ 6
Post #7097 3.32K
👨‍💻 Покрытие кода тестами в Go

Команда DoltHub пишет Dolt на Go уже много лет. Тесты у них есть в огромном количестве, но покрытие кода они никогда не измеряли. Недавно один из инженеров вспомнил, что Go добавил поддержку инструментирования покрытия в обычных бинарниках ещё в версии 1.20, не только в go test. Решили проверить, что из этого выйдет.

Хорошая часть их покрытия приходит на интеграционные тесты, которые запускают бинарник напрямую, а не через go test. В частности, у них тысячи BATS-тестов для CLI, и большая часть кодовой базы проверяется только ими.

Для юнит-тестов достаточно добавить несколько флагов к go test:
go test -cover -coverpkg="$COV_PKGS" ./... -args -test.gocoverdir=/tmp/coverdata/unit


Флаг -cover включает сбор данных. -coverpkg задаёт список пакетов для инструментирования. Чтобы не перечислять их вручную, используют go list:
go list -f '{{if not .Standard}}{{.ImportPath}}{{end}}' -deps . | \
grep dolthub | paste -sd"," - > "pkgs.txt"

export COV_PKGS=$(cat pkgs.txt)


Для интеграционных тестов собирают инструментированный бинарник:
go build -cover -coverpkg="$COV_PKGS" ./cmd/dolt/.
export GOCOVERDIR=/tmp/coverdata/integration


Теперь любой запуск этого бинарника пишет данные о покрытии в указанную директорию.

После всех прогонов данные сводятся в один файл:
go tool covdata textfmt -i /tmp/coverdata/unit,/tmp/coverdata/integration -o cov.out
go tool cover -html=cov.out


Получается HTML-файл с построчным покрытием. Проблема в том, что стандартный интерфейс предлагает выбрать нужный файл из выпадающего списка всех 1910 файлов проекта что неудобно.

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

Что получилось в итоге

Итоговый отчёт охватывал 1910 файлов со средним покрытием 49%. Ниже, чем типичные 70% в Java-проектах. Но результат объясним: в числе проанализированных файлов оказались форкнутые зависимости вроде Vitess, мёртвый код и автогенерированные фичи без тестов.

Когда результаты показали коллегам, реакция была спокойной. Никто не рвался писать новые тесты, чтобы поднять цифры. Всех больше интересовало, какой AI-инструмент помог сгенерировать отчёт.

Три причины, почему покрытие не стало приоритетом:

1. Кодовая база большая: больше полумиллиона строк кода. Понять, с чего начать после восьми лет без покрытия, непросто.

2. Go-код даёт много шума из-за обработки ошибок. Каждый блок if err != nil порождает непокрытую ветку, и требовать её покрытия нереалистично.

3. У команды уже есть наборы тестов, которым они доверяют.

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

➡️ Источник

📍 Навигация: Вакансии • Задачи • Собесы

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

#GoDeep
  • 👍 4
  • 👏 1
Post #7096 3.35K
📎 Попросить ИИ улучшить резюме это не стратегия

Большинство соискателей используют нейросети поверхностно: переписать текст, проверить письмо, придумать ответы на банальные вопросы.

Но настоящая сила LLM в другом. Она способна превратить разрозненную карьерную информацию в реальное конкурентное преимущество.

➡️ Разобрали 5 рабочих промптов

📍 Навигация: Вакансии • Задачи • Собесы

🐸 Библиотека Go-разработчика
  • 👍 2
  • 😁 2
Post #7095 3.16K
⚡️ Мы рады представить команду экспертов курса AgentOps!

— Дмитрий Антипов расскажет, как грамотно проверить работу AI-моделей
— Курилл Кухарев поделится, почему компаниям выгодно использовать локальные модели и как их развернуть
— Андрей Носов расскажет, как работать с данными и знаниями в AI-системах: построение RAG, выбор подходов к поиску и организация хранения данных
— Антон Будняк разберет, как обеспечить устойчивость сервиса, в котором используется ИИ
— Александр Ошурков расскажет, как оценивать качество работы LLM в backend-сервисах
— Екатерина Трофимов разберет, как проектировать инструменты для AI-агентов и выстраивать взаимодействие с внешними сервисами

Курс для backend-разработчиков, тимлидов и LLM инженеров о том, как внедрять AI-логику в бэкенд IT-продуктов и сохранять стабильность сервиса.

К концу обучения вы получите:

• Структурированный подход к архитектуре и деплою AI-агентов
• Навыки настройки мониторинга, тестирования и контроля расходов на токены
• Разбор сложных инженерных кейсов из реальной практики

🎁 Доступ к материалам курса
«Разработка ИИ-агентов» в подарок при покупке Инженерного трека

👉 Все подробности и программа обучения.
  • 🥱 3
  • 🤔 2
Post #7094 2.94K
⭐️ go-duckfs: монтируем io/fs в DuckDB

DuckDB умеет читать Parquet, CSV и JSON прямо из S3, HTTP и других источников. Но его встроенные расширения — httpfs, aws — написаны на C++. Они живут в отдельном I/O-стеке, не видят ваш Go-код, не участвуют в трейсинге и не уважают ваши политики доступа. go-duckfs решает эту проблему.

Что делает библиотека

Пакет монтирует любой io/fs.FS как виртуальную файловую систему внутрь DuckDB. Всё I/O, которое DuckDB делает при выполнении запросов, проходит через Go-рантайм. Это значит, что вы можете использовать нативные Go SDK облачных провайдеров, оборачивать доступ в middleware для метрик и логов, контролировать доступ на уровне приложения.

Установка и сборка

Пакет требует динамической линковки DuckDB. Рекомендуемый способ через pixi:
# Установить DuckDB
pixi install --locked

# Собрать с динамической линковкой
CGO_ENABLED=1 \
CGO_LDFLAGS="-L.pixi/envs/default/lib" \
go build -tags=duckdb_use_lib


Тег duckdb_use_lib обязателен. Он переключает Go-биндинги DuckDB в режим динамической линковки.

Базовый пример:
c, err := duckfs.Open("", nil, os.DirFS("testdata"))
if err != nil {
log.Fatal(err)
}

db := sql.OpenDB(c)
defer db.Close()

rows, err := db.Query(`SELECT * FROM read_parquet('data.parquet')`)


duckfs.Open создаёт коннектор с вашим fs.FS в качестве файловой системы. Дальше — стандартный sql.DB. DuckDB при выполнении запроса обращается к файлам через ваш Go-код, а не напрямую.

Протокольные пути

DuckDB использует URI-подобные пути вида myproto://file.parquet. Если хотите сохранить такой префикс в запросах, оберните свою реализацию fs.FS:
type myFS struct {
fsys fs.FS
}

func (f *myFS) Open(name string) (fs.File, error) {
name = strings.TrimPrefix(name, "myproto://")
return f.fsys.Open(name)
}

c, err := duckfs.Open("", nil, &myFS{fsys: os.DirFS("data")})
if err != nil {
log.Fatal(err)
}

db := sql.OpenDB(c)
row := db.QueryRow(`SELECT * FROM read_csv('myproto://records.csv')`)


Это удобно, если DuckDB-запросы генерируются автоматически и вы хотите разграничить разные источники данных по префиксу.

Запуск тестов:
CGO_ENABLED=1 \
CGO_LDFLAGS="-L.pixi/envs/default/lib" \
LD_LIBRARY_PATH=".pixi/envs/default/lib" \
go test -v ./... -tags=duckdb_use_lib


Когда это полезно

Если вы используете DuckDB в Go-сервисе и хотите читать данные из S3, GCS или любого другого хранилища через собственный Go-клиент go-duckfs даёт для этого готовый мост. Трейсинг, ретраи, авторизация, кастомные заголовки — всё остаётся на вашей стороне, в Go, а не уходит в C++-расширение DuckDB.

➡️ Репозиторий

📍 Навигация: Вакансии • Задачи • Собесы

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

#GoToProduction
Post #7093 3.13K
🧑‍💻 Семафор для прода

В прошлый раз мы разобрали, как буферизованный канал работает как семафор. Это хороший паттерн, но у него есть потолок: нет встроенной поддержки контекста, нет возможности задать разный «вес» для разных операций. Пакет golang.org/x/sync закрывает оба этих пробела.

Что внутри

Пакет предоставляет взвешенный семафор semaphore.NewWeighted. Принцип тот же: ограничиваете число параллельных операций. Но теперь каждая операция может занимать не один слот, а несколько. И Acquire умеет слушать контекст.

Базовое использование:
import "golang.org/x/sync/semaphore"

var (
maxWorkers = int64(10)
sem = semaphore.NewWeighted(maxWorkers)
)

func processAll(ctx context.Context, tasks []Task) error {
for _, task := range tasks {
if err := sem.Acquire(ctx, 1); err != nil {
return fmt.Errorf("semaphore acquire: %w", err)
}

go func(t Task) {
defer sem.Release(1)
process(ctx, t)
}(task)
}

// Ждём завершения всех горутин
if err := sem.Acquire(ctx, maxWorkers); err != nil {
return fmt.Errorf("final acquire: %w", err)
}
sem.Release(maxWorkers)
return nil
}


Два момента, на которые стоит обратить внимание.

Acquire возвращает ошибку, если контекст отменён или истёк дедлайн. Горутины не зависают — они получают сигнал и завершаются. Это именно то, чего не хватало буферизованному каналу.

Финальный Acquire(ctx, maxWorkers) — это трюк для ожидания. Мы пробуем занять все слоты сразу. Это возможно только тогда, когда все горутины завершились и освободили свои слоты. Как только захват прошёл — сразу отпускаем и выходим.

Взвешенный захват: зачем он нужен

Не все задачи одинаково нагружают систему. Загрузка большого файла потребляет куда больше ресурсов, чем быстрый запрос в базу.

Взвешенный семафор моделирует напрямую:
// Тяжёлая операция занимает 3 слота
if err := sem.Acquire(ctx, 3); err != nil {
return err
}
go func() {
defer sem.Release(3)
heavyOperation(ctx)
}()

// Лёгкая операция занимает 1 слот
if err := sem.Acquire(ctx, 1); err != nil {
return err
}
go func() {
defer sem.Release(1)
lightOperation(ctx)
}()


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

Когда использовать

Буферизованный канал подходит для скриптов и простых утилит, где все задачи равнозначны и контекст не нужен. golang.org/x/sync/semaphore — выбор для продакшена: корректно обрабатывает отмену, не теряет горутины при завершении и позволяет точнее контролировать нагрузку.

📍 Навигация: Вакансии • Задачи • Собесы

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

#GoToProduction
  • 👍 16
  • 🥱 1
Post #7092 3.41K
🏃‍♀️ Уже завтра стартует курс по разработке AI-агентов.

Про AI-агентов часто думают, что это просто модная обертка над джпт для пет-проектов. Кажется, прикрутил API к скрипту и типа готово. А вот и нет! Когда дело доходит до прода, начинаются настоящие проблемы.

Зачем глубоко копать мультиагентные системы, если можно обойтись старым добрым кодом? Как контролировать расходы на токены, чтобы новая фича не разорила бизнес? Как заставить агента работать стабильно и предсказуемо, а не галлюцинировать?


Эту инженерную часть мы и будем разбирать на курсе. Будем учиться интегрировать внешние API, работать с RAG, LangGraph, CrewAI и деплоить всё это так, чтобы работало как часы.

Стартуем завтра. Для участия и доступа к программе переходите по ссылке.
  • 🥱 2
Post #7090 3.17K
🦾 Надоело чинить «упавших» ИИ-агентов после каждого микросбоя внешних сервисов?

Анонсируем старт продаж большого курса по AgentOps. Мы собрали опыт десятков разработчиков и сделали программу, которая учит выводить ИИ в стабильный прод.

🗓 Ждем вас 28 апреля в 19:00 МСК на эфире: «Как эффективно управлять контекстным окном LLM в мультиагентных системах и не сливать бюджет на токены».

👉 Кто вещает и в чем польза?

Спикер Кирилл Кухарев (Senior AI Engineer в Raft, спикер AI Conf и Highload++). Он реализовал более 50 коммерческих проектов в GenAI и на вебинаре покажет, как взять под контроль работу нескольких агентов, чтобы они не перекидывали друг другу лишний контекст и не сжигали ваши деньги.

В прямом эфире разберем:
• Как формируется контекст в LLM при маршрутизации между агентами;
• Куда утекают лишние токены и возникает перерасход;
• Практические методы: как сжимать историю, грамотно делить задачи, лимитировать передачу контекста и собирать промпты прямо в процессе запроса пользователя.

🔥 Два способа получить максимум:

1. Приходите на вебинар 28 апреля. Дарим участникам промокод на 5.000 ₽ (работает 3 дня после эфира - это шанс забрать курс по самому низу рынка).

2. Выбирайте Инженерный трек. В подарок к нему идет полный доступ к записям и автопроверкам завершенного курса «Разработка ИИ-агентов».

👉 Занять место на вебинаре и стать профи в AgentOps
  • 😁 6
  • 😢 1
  • 🥱 1
Post #7089 3.23K
👨‍💻 Семафор в Go через буферизованный канал

Параллелизм в Go легко выходит из-под контроля. Запустил 1000 горутин и сервер задыхается. Семафор ограничивает количество горутин, которые работают одновременно и сервер становится более стабильным.

Что такое семафор и почему в Go его нет

В других языках семафор встроен в стандартную библиотеку. В Go его нет, но есть буферизованный канал и он делает ту же работу.

Логика простая: ёмкость канала = максимальное число параллельных горутин. Хотите запустить горутину — отправьте в канал пустую структуру. Нет свободного места — ждите. Горутина завершилась — прочитайте из канала, освободите слот.

Базовая реализация:
sem := make(chan struct{}, 10) // максимум 10 горутин одновременно

for _, task := range tasks {
sem <- struct{}{} // занять слот (блокирует, если канал полон)
go func(t Task) {
defer func() { <-sem }() // освободить слот при выходе
process(t)
}(task)
}

// Ждём завершения всех горутин
for i := 0; i < cap(sem); i++ {
sem <- struct{}{}
}


У struct{} нулевой размер в памяти. Канал здесь нужен только для сигнализации, а не для передачи данных. Это чисто ибез лишних зависимостей.

Где это ломается

Базовый вариант работает для скриптов и одноразовых утилит. Но у него есть жёсткое ограничение: он не знает про отмену контекста.

Если приложение получило сигнал завершения или истёк дедлайн, горутины, заблокированные на sem <- struct{}{}, просто продолжают ждать. Бесконечно. Приложение не завершится корректно.

Для чего-то серьёзнее скрипта нужен select с ctx.Done().

Версия с отменой контекста:
func acquire(ctx context.Context, sem chan struct{}) error {
select {
case sem <- struct{}{}:
return nil
case <-ctx.Done():
return ctx.Err()
}
}


Теперь при отмене контекста горутина не зависнет, она получит ошибку и завершится.

📍 Навигация: Вакансии • Задачи • Собесы

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

#GoToProduction
  • 👍 7
  • 🥱 6
  • ❤ 4
Post #7088 3.02K
🥸 Чужой код, свои руки

Один из самых частых вопросов от начинающих разработчиков:
Я переписал своими руками. Это теперь моё?


И один из самых опасных мифов в нашей профессии.

Что такое авторское право на код


Код защищается авторским правом автоматически в момент создания. Не нужна регистрация, не нужен значок ©. Человек написал функцию и она его.

Но авторское право защищает конкретное выражение, то есть именно эти строки, эту структуру, эту последовательность решений. Оно не защищает идею или алгоритм как таковой.
Отсюда и рождается миф.

Миф о переписывании

Логика звучит разумно: «Я не копировал, я написал сам, значит нарушений нет.»

Проблема в том, что суд смотрит не только на текст кода. Он смотрит на структуру, последовательность, выбор решений и итоговое сходство. Есть понятие clean room implementation. Это когда одна команда изучает спецификацию, а другая, которая никогда не видела оригинал, пишет реализацию. Только так можно говорить о независимой разработке с юридической точки зрения.

Если вы смотрели в репозиторий, а потом переписали своими словами, то это не clean room. Это производная работа. И она всё ещё подпадает под лицензию оригинала.

А если вы вообще не смотрели в код?

Это уже другая история. Если вы реализовали тот же алгоритм независимо, не видели оригинал и не опирались на него, то у вас есть своё авторское право на свою реализацию. Но доказать это постфактум бывает сложно.

Вот здесь важно понимать, какая лицензия стоит на оригинале.

MIT и Apache 2.0 разрешают почти всё, включая коммерческое использование, при условии сохранения уведомления об авторских правах. Можно брать код, менять его и включать в закрытый продукт. Тут переписывать вообще смысла нет. Проще взять напрямую и указать автора.

GPL работает иначе. Если вы используете GPL-код в своём проекте, весь ваш проект должен стать GPL. Это называется вирусный эффект. И переписывание не спасает, если суд признает ваш код производным от GPL-оригинала.

Проприетарные лицензии это отдельная история. Там всё, что не разрешено явно, запрещено. Никакое переписывание не поможет, если вы воспроизводите логику и структуру закрытого продукта.

Что это значит


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

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

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

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

📍 Навигация: Вакансии • Задачи • Собесы

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

#GoTalk
  • 👍 9
  • 🌚 1
Post #7082 3.52K
💡 Фриланс для разработчиков

Вы ищете заказы там, где их ищут все. А локальный бизнес даже не знает о существовании биржи — ИП пишут в чатах «посоветуйте программиста» или листают Авито.

Будьте там, где нет толпы.

➡️ Остальные 4 способа найти первые проекты без бирж

📍 Навигация: Вакансии • Задачи • Собесы

🐸 Библиотека Go-разработчика
  • 😁 6
  • ❤ 4
  • 🥱 3
  • 👾 1
Post #7081 3.43K
🤖 Ваш ИИ-агент съедает бюджет на токены и падает при сбоях API?

Пора переходить на новый уровень. Открыли продажи курса по AgentOps — управлению ИИ-агентами в рабочих процессах.

Рынок требует инженеров, которые умеют:

• Контролировать метрики и качество ответов;
• Эффективно работать с RAG-архитектурой;
• Строить системы, готовые к реальным нагрузкам.

Обучение займет 6-12 недель под руководством практиков с опытом в AI и Data Science в крупных IT-компаниях, таких как Яндекс, Сбер, МТС, Huawei, Raft и др.

🎁 Можно подождать, пока про AgentOps начнут говорить все. Или зайти сейчас — НА 30% ДЕШЕВЛЕ!

Работа с AI начинается с систем.
Системы — с AgentOps.


🔥 Забрать скидку и изучить программу.
  • ❤ 1
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →