Ниже — бесплатный вебинар о том, как этого избежать ⚠️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Forwarded from Proglib.academy | IT-курсы
Где-то есть тесты, где-то их забыли. Где-то агент следует архитектуре проекта, где-то предлагает решение, которое с ней не сочетается.
Завтра покажем, как передать AI инженерный контекст команды и не превратить его внедрение в ещё один источник хаоса.
Бесплатно. 60 минут доклада + 30 минут вопросов.
Please open Telegram to view this post
VIEW IN TELEGRAM
😁6⚡1❤1🤔1🥱1
Раньше
go fix вспоминали редко. Команда осталась со времён Go 1.0, когда язык менялся часто и код приходилось подтягивать под новые правила. После обещания об обратной совместимости нужда в ней почти отпала, и многие о ней просто забыли. В Go 1.26 её переписали заново, и теперь это инструмент модернизации кода, а не реликт.Как запускать
Команда принимает шаблоны пакетов, как
go build и go vet. Правка всех пакетов ниже текущей директории:go fix ./...
При успехе файлы меняются молча. Правки в сгенерированных файлах команда пропускает, потому что чинить нужно генератор, а не результат. Запускайте из чистого git-состояния, тогда в диффе будут только изменения от
go fix, и ревьюеру будет проще.Посмотреть правки заранее, ничего не меняя, помогает флаг
-diff:go fix -diff ./...
Список доступных анализаторов выводит отдельная команда:
go tool fix help
Можно запросить документацию по конкретному анализатору:
go tool fix help forvar
По умолчанию запускаются все анализаторы. На большом проекте удобнее применять правки по одному анализатору за раз, чтобы ревью не превращалось в кашу. Включить только нужный можно флагом с его именем, например
-any. Наоборот, выключить один и оставить остальные помогает форма -any=false.Правки под новые возможности применяются только в тех файлах, где версия Go достаточно свежая. Ориентир берётся из директивы
go в go.mod или из build-тега вроде //go:build go1.26. Так инструмент не тащит фичи туда, где они ещё не поддерживаются.Пара нюансов
Одна правка иногда открывает дорогу другой. Например,
minmax сначала подставит max, а на втором проходе увидит и min. Поэтому имеет смысл прогнать команду дважды, обычно этого хватает.Изредка встречаются семантические конфликты, когда две независимые правки вместе оставляют неиспользуемую переменную, а это ошибка компиляции в Go. Такие случаи обычно всплывают сразу при сборке, но требуют ручной доработки. Неиспользуемые импорты
go fix при этом убирает сам отдельным проходом.Мы получили команду, которую есть смысл запускать регулярно, а не раз в пятилетку. Хороший момент — сразу после апгрейда тулчейна. Обновите проект до Go 1.26, запустите
go fix ./... из чистого git-состояния и посмотрите на дифф. Заодно можно подтянуть свежие идиомы языка, которые иначе легко пропустить.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13❤7🔥1🎉1
Когда в приложении на Go с GORM появляется поиск по тексту, первым в код обычно попадает
LIKE '%слово%'. На небольшой таблице это терпимо. Дальше начинаются проблемы. Запрос сканирует всю таблицу, не понимает словоформы, чувствителен к регистру, а обычный индекс ему не помогает. В PostgreSQL для таких задач есть встроенный полнотекстовый поиск на
tsvector и tsquery. GORM с ним работает без отдельных библиотек, потому что нужные операторы можно передать внутрь .Where().Как это устроено
Тип
tsvector — это нормализованный набор лексем из текста. Функция to_tsvector приводит слова к основе и выкидывает стоп-слова, поэтому запрос по слову running находит документ со словом run. Тип tsquery описывает сам поисковый запрос. Функция
plainto_tsquery берёт строку от пользователя и превращает её в запрос, безопасно игнорируя спецсимволы вроде & и |. Оператор @@ проверяет, совпадает ли вектор с запросом, и возвращает булево значение.Базовый вариант
Проще всего собрать условие прямо в
.Where(). Модель и функция поиска выглядят так:package main
import (
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type Product struct {
ID uint `gorm:"primaryKey"`
Title string
Description string
}
func SearchProducts(db *gorm.DB, term string) ([]Product, error) {
var products []Product
err := db.Where(
"to_tsvector('english', title || ' ' || description) @@ plainto_tsquery('english', ?)",
term,
).Find(&products).Error
return products, err
}
Здесь
title и description склеиваются в один вектор, а ввод пользователя уходит параметром через ?, так что про SQL-инъекции можно не беспокоиться. Минус подхода в том, что вектор считается заново для каждой строки в момент запроса. Индекс тут не используется, и на большой таблице это становится медленно.Быстрый вариант с отдельным столбцом и GIN-индексом
Чтобы не пересчитывать вектор на лету, его хранят в отдельном столбце и ускоряют индексом типа GIN. Столбец удобно сделать генерируемым, тогда PostgreSQL сам поддерживает его в актуальном состоянии при любой вставке или обновлении.
В модели этот столбец помечается как доступный только для чтения. Тег
-> говорит GORM не пытаться писать в него, ведь значение вычисляет база:type Book struct {
ID uint `gorm:"primaryKey"`
Title string
Description string
SearchVector string `gorm:"->;type:tsvector"`
}Сам генерируемый столбец и индекс создаются сырым SQL после
AutoMigrate, потому что синтаксис генерируемых столбцов GORM через теги не выразит:func InitDatabase(db *gorm.DB) {
db.AutoMigrate(&Book{})
db.Exec(`
ALTER TABLE books
ADD COLUMN IF NOT EXISTS search_vector tsvector
GENERATED ALWAYS AS (
to_tsvector('english', coalesce(title, '')) ||
to_tsvector('english', coalesce(description, ''))
) STORED;
`)
db.Exec(`
CREATE INDEX IF NOT EXISTS idx_books_search_vector
ON books USING gin(search_vector);
`)
}Запрос теперь обращается к готовому столбцу, поэтому нагрузка не растёт вместе с размером таблицы:
func FastSearch(db *gorm.DB, term string) ([]Book, error) {
var results []Book
err := db.Where("search_vector @@ websearch_to_tsquery('english', ?)", term).
Find(&results).Error
return results, err
}Здесь вместо
plainto_tsquery стоит websearch_to_tsquery. Он понимает привычный по поисковикам синтаксис. Кавычки задают точную фразу, а минус перед словом исключает его из выдачи. Для строки поиска от пользователя это обычно удобнее.Что выбрать
Для прототипа или небольшой таблицы хватит базового варианта через
to_tsvector прямо в .Where(). Как только объём данных растёт и поиск начинает тормозить, переходите на генерируемый столбец с GIN-индексом. Логика запроса при этом почти не меняется, а скорость перестаёт зависеть от размера таблицы.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7❤4😁1
Оптимизировать Go есть смысл, когда приложение упирается в CPU, память или задержки в проде. И только после того, как вы замерили, где именно медленно, а не по ощущениям.
Собрали пять техник, которые убирают лишние аллокации и системные вызовы. Преаллокация слайсов,
strings.Builder, аккуратная работа с []byte, буферы для I/O и выравнивание полей в структурах.📍 Навигация: Вакансии • Задачи • Собесы
#GoVisual
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8👍5❤4
Please open Telegram to view this post
VIEW IN TELEGRAM
Forwarded from Proglib.academy | IT-курсы
Агент работает только с тем контекстом, который ему дали. Если документация неполная или устарела, он начинает додумывать — отсюда появляется неверный код.
Также разберём, как выбирать модель под задачу: Claude, DeepSeek, Qwen и другие
Впереди 7 недель работы со своим репозиторием. Вебинары проходят вживую и остаются в записи.
Стартуем 31 августа. До конца июля можно присоединиться по ранней цене, а доступ к материалам останется бессрочным
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👍1😁1
Go легче учить на реальных задачах, но придумать задачу порой сложнее, чем решить. Собрали идеи по уровням, каждую можно закрыть за вечер.
Для старта
• Утилита командной строки. Го собирается в один бинарник, раздавать удобно.
• Поиск дубликатов файлов по хешу, свой аналог
grep, конвертер csv в json. Освоите флаги, чтение из потока и работу с файлами.Конкурентность
• Чекер доступности сайтов опрашивает адреса параллельно, десять штук проверяются за время самого медленного ответа.
• Пул воркеров покажет, зачем каналы и как ограничивать нагрузку.
• Кэш с временем жизни объяснит, почему доступ к карте без блокировки ломает программу.
Сеть и сервисы
• Сокращатель ссылок закроет тему HTTP сервиса и роутинга.
• Прокси научит перехватывать трафик.
• Телеграм бот даст практику с внешним API и вебхуками.
Ближе к продакшену
• База ключ значение с журналом на диске покажет как организовать долговечность данных.
• Rate limiter познакомит с токен бакетом.
• Сборщик метрик научит работать с системными вызовами.
Берите задачу, которая пригодится вам самим. Начните с утилиты и усложняйте.
📍 Навигация: Вакансии • Задачи • Собесы
#GoTalk
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍5