GoMiddleExperience
Для каких задач Go (Golang) является сильным выбором, а где лучше честно выбрать другой язык?
Go отлично подходит для сетевых сервисов, CLI-инструментов и высоконагруженных систем с конкурентностью. Для ML, сложной математики или богатой OOP-иерархии лучше выбрать Python, Rust или Java.
Сильные стороны Go
Go создавался в Google для конкретного класса задач — сетевые сервисы, системные инструменты и крупные монорепозитории. Там он действительно блестит:
- HTTP-сервисы и API — стандартная библиотека
net/httpпроизводительна «из коробки», goroutine-модель позволяет обрабатывать десятки тысяч соединений на скромном железе. - CLI-инструменты — бинарь компилируется в один статически слинкованный файл, что упрощает дистрибуцию. kubectl, Terraform, Hugo — всё это Go.
- gRPC-сервисы — официальная поддержка protobuf (
google.golang.org/protobuf) и первоклассный grpc-go. - Конкурентная обработка данных — pipelines на каналах, worker pools, fan-out/fan-in — всё выражается идиоматично без внешних фреймворков.
- DevOps/Infra tooling — Docker, Kubernetes, Prometheus, Terraform написаны на Go.
package main
import (
"fmt"
"sync"
)
// Worker pool: обработка задач несколькими goroutines
func process(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for j := range jobs {
results <- j * j
fmt.Printf("worker %d обработал %d\n", id, j)
}
}
func main() {
jobs := make(chan int, 10)
results := make(chan int, 10)
var wg sync.WaitGroup
for w := 1; w <= 3; w++ {
wg.Add(1)
go process(w, jobs, results, &wg)
}
for j := 1; j <= 9; j++ {
jobs <- j
}
close(jobs)
wg.Wait()
close(results)
for r := range results {
fmt.Println(r)
}
}
Где Go — не лучший выбор
- Machine Learning / Data Science — экосистема несопоставима с Python (PyTorch, NumPy, pandas). Go-пакеты типа
gorgoniaзаброшены или нишевые. - Высоконагруженные числодробилки (финансовые расчёты, симуляции) — GC-паузы и отсутствие SIMD-оптимизаций делают Rust или C++ предпочтительнее, когда нужна латентность <100 мкс.
- Сложные доменные модели с наследованием — Go не имеет классического ООП. Попытка реализовать глубокую иерархию через интерфейсы и embedding выходит громоздкой. Java/Kotlin или C# уместнее.
- Скриптинг и автоматизация — накладные расходы на компиляцию и многословный синтаксис делают Python или Bash практичнее для одноразовых скриптов.
- GUI / mobile — нет зрелого UI-фреймворка; Flutter (Dart), Swift, Kotlin — очевидные альтернативы.
Подводные камни
- Отсутствие generics до Go 1.18 породило много дублирующего кода; проекты на старых версиях могут содержать тонны copy-paste вместо параметрических функций.
- GC в Go — concurrent mark-and-sweep, но он всё равно вызывает stop-the-world фазы; приложения с латентностью <1 мс требуют тюнинга
GOGCиGOMEMLIMIT. - CGo резко снижает производительность и ломает кросс-компиляцию — многие команды используют его, не осознавая цены.
- Пакет
database/sqlне имеет поддержки async; при большом числе запросов горутины блокируются на сетевом вызове — нужен connection pool с разумнымSetMaxOpenConns. - Ошибки-значения легко проигнорировать:
_ = f()компилируется без предупреждения. - Не стоит использовать Go там, где команда экспертна в другом языке, а Go выбирается «по хайпу» — потеря производительности разработки перевешивает технические преимущества.
What hurts your answer
- Выбирать Go (Golang) по популярности, а не по требованиям проекта
- Игнорировать опыт команды, эксплуатацию и стоимость поддержки
- Не называть ситуации, где Go (Golang) будет плохим выбором
What they're listening for
- Называет критерии выбора Go (Golang)
- Учитывает команду, эксплуатацию, стоимость и риски
- Может назвать сценарии, где выбрал бы альтернативу