Используете ли нативные SQL-запросы или ORM?
Что проверяют
Есть ли у вас осознанная позиция по работе с базой в Go и знаете ли вы экосистему дальше GORM. В Go-сообществе заметный крен в сторону SQL и генерации кода, и интервьюер проверяет, понимаете ли вы почему. Следом спрашивают про транзакции, пул соединений или N+1.
Как отвечать
Назовите, чем пользуетесь сами, и объясните выбор через спектр инструментов:
database/sqlиpgx: чистый SQL, полный контроль над запросом и планом. Для PostgreSQLpgxс пуломpgxpoolбыстрее и богаче по типам, чем стандартный интерфейс;sqlx: тот же SQL, но строки сканируются в структуры без ручногоScanпо каждому полю;sqlc: вы пишете запросы в.sql-файлах, генератор выдаёт типизированные функции и структуры. Ошибка в имени колонки ловится при генерации, а не в проде;- конструкторы запросов вроде
squirrel: для динамических фильтров, где иначе пришлось бы клеить строки; - ORM (
GORM,ent,bun): быстрый CRUD и связи, но запрос строится неявно, а рефлексия и хуки усложняют отладку.
Разумная позиция для большинства сервисов: SQL через sqlc или pgx, миграции через goose или golang-migrate, ORM допустим в админке или прототипе. При любом подходе покажите базовую гигиену: context с таймаутом на каждый запрос, defer rows.Close() и проверка rows.Err(), обработка sql.ErrNoRows, настройка SetMaxOpenConns и SetConnMaxLifetime, транзакции с defer tx.Rollback().
Приведите свой пример: где ORM мешал и что показал EXPLAIN ANALYZE, или где ручной SQL разросся и вы ввели генерацию. Если работали только с одним подходом, скажите это и объясните, когда выбрали бы другой.
Где спотыкаются
Говорят, что ORM сам защищает от SQL-инъекций. В GORM строка, склеенная через fmt.Sprintf и переданная в Where или Raw, так же уязвима. Защищают плейсхолдеры ($1 в PostgreSQL, ? в MySQL), а не ORM.
Не видят N+1: цикл по записям с запросом связей на каждой итерации. В GORM это лечится Preload или Joins, в SQL одним запросом с JOIN или ANY($1).
Забывают rows.Close() при раннем выходе из цикла. Соединение не возвращается в пул, и под нагрузкой сервис упирается в лимит соединений.