Go — это язык, который задумывался для конкурентности. Но даже опытные разработчики часто пишут горутины как попало, а потом ловят гонки данных и утечки. Я собрал 12 промтов, которые использую сам, чтобы AI помогал мне писать эффективный, безопасный и быстрый код на Go. Каждый промт — проверен в бою, с примерами и кодом.
1. Разбор конкурентного кода
Когда использовать: Вы унаследовали код с горутинами и подозреваете гонки данных.
Промт: «Проанализируй этот код на Go, найди гонки данных и объясни, как их исправить. Используй детектор гонок go run -race и покажи вывод.»
Пример: Я скормил этому промту код с общей переменной-счётчиком. AI нашёл гонку, предложил использовать sync.Mutex и показал, как запустить детектор.
var counter int
func increment() { counter++ } // гонка данных!
Результат: AI объяснил, что counter++ — это не атомарная операция, и предложил три варианта: мьютекс, atomic.Int64 или канал. Я выбрал атомику — она быстрее.
2. Проектирование каналов
Когда использовать: Нужно спроектировать конвейер обработки данных.
Промт: «Спроектируй конвейер на Go с тремя стадиями, используя каналы. Покажи, как закрывать каналы и обрабатывать ошибки.»
Пример: Я попросил AI построить конвейер для обработки чисел: генерация → фильтрация → вывод. Вот что он выдал:
func generate(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums { out <- n }
close(out)
}()
return out
}
Результат: AI показал паттерн «генератор → фильтр → потребитель» и предупредил о важности закрытия каналов, чтобы избежать утечек.
3. Пул воркеров
Когда использовать: Нужно обрабатывать много задач конкурентно, но ограничить число горутин.
Промт: «Создай пул воркеров на Go для обработки задач из очереди. Используй каналы и WaitGroup.»
Пример: Я попросил AI реализовать пул из 5 воркеров для обработки URL. Вот ключевой фрагмент:
jobs := make(chan int, 100)
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for job := range jobs { process(job) }
}()
}
Результат: AI объяснил, как балансировать нагрузку и корректно завершать воркеры через close(jobs).
4. Обработка ошибок в горутинах
Когда использовать: Нужно собрать ошибки из нескольких горутин.
Промт: «Покажи, как собрать ошибки из нескольких горутин в Go, используя errgroup.»
Пример: Я попросил AI использовать golang.org/x/sync/errgroup. Вот что получилось:
g, ctx := errgroup.WithContext(ctx)
for _, url := range urls {
g.Go(func() error { return fetch(url) })
}
if err := g.Wait(); err != nil { return err }
Результат: AI показал, как отменять контекст при первой ошибке — это стандартный паттерн для микросервисов.
5. Оптимизация производительности
Когда использовать: Код работает медленно, нужно найти узкие места.
Промт: «Проведи профилирование этого кода на Go с помощью pprof. Найди горячие точки и предложи оптимизации.»
Пример: Я скормил AI функцию с конкатенацией строк в цикле. AI предложил использовать strings.Builder вместо +=.
var sb strings.Builder
for _, s := range parts { sb.WriteString(s) }
Результат: AI показал, как запустить go test -bench . -cpuprofile cpu.out и проанализировать вывод. Скорость выросла в 3 раза.
6. Проектирование микросервиса
Когда использовать: Нужно создать новый микросервис с REST API.
Промт: «Спроектируй микросервис на Go с REST API, используя chi или stdlib. Включи middleware для логирования и CORS.»
Пример: AI предложил структуру проекта: cmd/server/main.go, internal/handler, internal/service. Вот пример handler:
func getUser(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
// ...
}
Результат: AI показал, как организовать код и добавить graceful shutdown.
7. Работа с базами данных
Когда использовать: Нужно написать слой доступа к БД с пулом соединений.
Промт: «Напиши код на Go для работы с PostgreSQL через database/sql. Настрой пул соединений и используй контекст.»
Пример: AI показал, как настроить sql.DB:
db, _ := sql.Open("postgres", connStr)
db.SetMaxOpenConns(25)
db.SetMaxIdleConns(5)
Результат: AI объяснил, почему важно устанавливать лимиты, и показал, как выполнять запросы с контекстом.
8. Тестирование и моки
Когда использовать: Нужно написать юнит-тесты с моками.
Промт: «Напиши юнит-тесты для этого кода на Go, используя стандартный пакет testing и моки через интерфейсы.»
Пример: AI создал интерфейс Repository и мок для него:
type MockRepo struct{ users []User }
func (m *MockRepo) GetUser(id int) (User, error) { ... }
Результат: AI показал, как писать табличные тесты и использовать t.Run для подтестов.
9. Генерация кода
Когда использовать: Нужно сгенерировать boilerplate для CRUD-операций.
Промт: «Сгенерируй код на Go для CRUD-операций над структурой User, используя GORM.»
Пример: AI выдал модель и функции Create/Read/Update/Delete:
type User struct { ID uint; Name string }
func CreateUser(db *gorm.DB, u *User) error { return db.Create(u).Error }
Результат: AI показал, как использовать GORM для миграций и запросов.
10. Контекст и таймауты
Когда использовать: Нужно добавить таймауты к HTTP-запросам.
Промт: «Покажи, как использовать context.WithTimeout в Go для HTTP-клиента.»
Пример: AI написал:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
req, _ := http.NewRequestWithContext(ctx, "GET", url, nil)
Результат: AI предупредил о необходимости отменять контекст, чтобы избежать утечек.
11. Graceful shutdown
Когда использовать: Нужно корректно завершать сервер.
Промт: «Реализуй graceful shutdown для HTTP-сервера на Go, используя signal.NotifyContext.»
Пример: AI показал:
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()
server := &http.Server{Addr: ":8080"}
go server.ListenAndServe()
<-ctx.Done()
server.Shutdown(context.Background())
Результат: AI объяснил, как обрабатывать сигналы и завершать соединения.
12. Взаимодействие с внешними API
Когда использовать: Нужно написать клиент для внешнего API.
Промт: «Напиши клиент на Go для REST API с ретраями и экспоненциальной задержкой.»
Пример: AI использовал github.com/hashicorp/go-retryablehttp:
client := retryablehttp.NewClient()
client.RetryMax = 3
Результат: AI показал, как обрабатывать 429 и 5xx ошибки.
Эти промты — моя ежедневная палочка-выручалочка. Они экономят часы на рутине и помогают избегать типичных ошибок. Сохраните себе, чтобы не потерять. А если хотите освоить Go глубже — загляните в наш блог: там много материалов про конкурентность и микросервисы.
Комментарии