🧑💻 Эмулятор AWS-сервисов
Kumo — это небольшой инструмент на Go для локальной имитации AWS-сервисов. Он помогает разработчикам тестировать приложения без облака.
Проект подходит для unit-тестов, где нужен мок для облачных вызовов. Устанавливается через
Поддерживает базовые операции над S3: создание бакетов, загрузку объектов, список файлов. Для DynamoDB эмулирует таблицы, put/get item. Конфиг через флаги или env.
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoLive
Kumo — это небольшой инструмент на Go для локальной имитации AWS-сервисов. Он помогает разработчикам тестировать приложения без облака.
Проект подходит для unit-тестов, где нужен мок для облачных вызовов. Устанавливается через
go install github.com/sivchari/kumo@latest. Запускается как прокси, а SDK настраивается на локальный эндпоинт.Поддерживает базовые операции над S3: создание бакетов, загрузку объектов, список файлов. Для DynamoDB эмулирует таблицы, put/get item. Конфиг через флаги или env.
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20❤1❤🔥1
🛠 ECS на Go
Entity Component System (ECS) это архитектурный паттерн, популярный в геймдеве и симуляциях. Идея простая: вместо объектов с данными и поведением используются сущности без данных, компоненты с данными и системы/запросы, которые обрабатывают сущности с нужным набором компонентов.
Ark это архетипная реализация ECS для Go. Архетипный подход означает, что сущности с одинаковым набором компонентов хранятся вместе в памяти, что максимизирует локальность данных при итерации.
Что внутри
Типобезопасный API с дженериками, никакого
Никаких встроенных систем, только запросы. Структуру приложения выбираем сами, или используем ark-tools со scheduler'ом:
Свежий релиз v0.8.0
7 апреля вышла v0.8.0 с заметными изменениями. Добавлена итерация по таблицам, которая даёт примерно двукратное ускорение по сравнению с обычной итерацией:
Также очистка памяти компонентов через
➡️ Репозиторий
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction
Entity Component System (ECS) это архитектурный паттерн, популярный в геймдеве и симуляциях. Идея простая: вместо объектов с данными и поведением используются сущности без данных, компоненты с данными и системы/запросы, которые обрабатывают сущности с нужным набором компонентов.
Ark это архетипная реализация ECS для Go. Архетипный подход означает, что сущности с одинаковым набором компонентов хранятся вместе в памяти, что максимизирует локальность данных при итерации.
Что внутри
Типобезопасный API с дженериками, никакого
interface{} и рефлексии в горячих путях. Отношения между сущностями как first-class feature. Система событий с фильтрацией. Batch-операции для массовых изменений. Сериализация мира через ark-serde. Ноль внешних зависимостей, 100% покрытие тестами.Никаких встроенных систем, только запросы. Структуру приложения выбираем сами, или используем ark-tools со scheduler'ом:
world := ecs.NewWorld()
mapper := ecs.NewMap2[Position, Velocity](world)
filter := ecs.NewFilter2[Position, Velocity](world)
query := filter.Query()
for query.Next() {
pos, vel := query.Get()
pos.X += vel.DX
pos.Y += vel.DY
}
Свежий релиз v0.8.0
7 апреля вышла v0.8.0 с заметными изменениями. Добавлена итерация по таблицам, которая даёт примерно двукратное ускорение по сравнению с обычной итерацией:
for query.NextTable() {
positions, velocities := query.GetColumns()
for i := range positions {
pos, vel := &positions[i], &velocities[i]
pos.X += vel.X
pos.Y += vel.Y
}
}Также очистка памяти компонентов через
memclrNoHeapPointers вместо обнуления вручную, перемещение нетривиальных компонентов стало быстрее на 30% за счёт typedmemmove вместо рефлексии, добавлены регрессионные бенчмарки для сравнения PR с main-веткой.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6👍2
strings.ContainsAny проверяет, содержит ли строка хотя бы один символ из набора. Но что происходит, когда оба аргумента пустые строки?
Подсказка:
Ответ: в нашем канале с задачами
📍 Навигация: Вакансии • Задачи • Собесы
#ReadySetGo
Please open Telegram to view this post
VIEW IN TELEGRAM
Go 1.26 принёс незаметное, но важное изменение в type checker. Команда Go опубликовала подробный разбор того, как именно компилятор конструирует типы и обнаруживает циклические зависимости.
Как устроена конструкция типов
Когда компилятор встречает объявление типа, он строит внутреннее дерево структур. Для простого случая:
type T []U
type U *int
Всё линейно: сначала строится
T, внутри неё []U, внутри неё U, внутри неё *int. Каждый тип становится «завершённым» когда все его поля заполнены и все зависимые типы тоже завершены. Процесс идёт вглубь и разматывается обратно.Рекурсивные типы
С рекурсией интереснее:
type T []U
type U *T
Здесь
T встречается пока ещё строится. Компилятор просто ставит указатель на незавершённый T и движется дальше, рассчитывая что T завершится позже. Когда конструкция доходит до конца, весь "цикл" типов завершается одновременно.Проблема возникает когда незавершённый тип нужно не просто упомянуть, а заглянуть внутрь:
type T [unsafe.Sizeof(T{})]intЧтобы вычислить размер массива, нужно знать размер
T. Но чтобы знать размер T, нужно завершить построение массива. Круговая зависимость, которую невозможно разрешить, это ошибка цикла.В Go 1.26 переписали подход: вместо сложной bespoke-логики для каждого случая, компилятор теперь отслеживает неполные значения систематически. В каждом месте где может возникнуть значение неполного типа, вставлена проверка:
if !isComplete(T) {
reportCycleErr(T)
return invalid
}Это закрыло несколько краевых случаев, которые раньше приводили к панике компилятора вместо нормальной ошибки.
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11👍5🔥2👏1
В Go давно есть идиоматичный способ обходить коллекции:
range. Но многие стандартные типы исторически предлагали только Len() и At(i), и код превращался в ручной счётчик. Анализатор stditerators из golang.org/x/tools находит такие места и предлагает замену.Типичный паттерн, который можно встретить в Go-проекте:
for i := 0; i < x.Len(); i++ {
use(x.At(i))
}Это работает, но многословно. Появились итераторы: метод
All() у ряда стандартных типов возвращает iter.Seq, по которому можно пройтись через range. stditerators находит старые конструкции и предлагает переписать их вот так:for elem := range x.All() {
use(elem)
}Анализатор понимает оба варианта счётчика — классический
for i := 0; i < x.Len(); i++ и более новый for i := range x.Len().Что покрывает
Анализатор работает с конкретными типами из стандартной библиотеки, у которых уже есть метод
All(). Это не универсальный «переписыватель» для всего подряд, а точечный инструмент с заранее известным списком поддерживаемых типов.Как запустить:
go install golang.org/x/tools/gopls@latest
Или через
go vet с плагином:go run golang.org/x/tools/go/analysis/passes/stditerators/cmd/stditerators@latest ./...
В большинстве редакторов с gopls анализатор подсветит проблемное место прямо в коде и предложит автоматический фикс.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9
🤔 Разрабатываете ИИ-агентов, но всё ещё не уверены в их стабильности и прогнозируемости?
Мы поговорили с десятками разработчиков ИИ-агентов и сделали отдельный курс по AgentOps.
🧠 На нём вы узнаете:
– как оптимизировать траты на токены;
– как на практике оценить качество работы агента;
– как «докручивать» RAG-системы без потери качества;
– как обеспечить устойчивость агента к сбоям внешних сервисов без падения всей системы и про многое-многое другое.
📅 Старт: 19 мая.
👥 Спикеры — практики с опытом в AI и Data Science в крупных IT-компаниях, таких как Яндекс, Huawei, МТС и др.
Длительность: 6-12 недель в зависимости от тарифа.
🔗 Программа курса и другие подробности
Мы поговорили с десятками разработчиков ИИ-агентов и сделали отдельный курс по AgentOps.
🧠 На нём вы узнаете:
– как оптимизировать траты на токены;
– как на практике оценить качество работы агента;
– как «докручивать» RAG-системы без потери качества;
– как обеспечить устойчивость агента к сбоям внешних сервисов без падения всей системы и про многое-многое другое.
📅 Старт: 19 мая.
👥 Спикеры — практики с опытом в AI и Data Science в крупных IT-компаниях, таких как Яндекс, Huawei, МТС и др.
Длительность: 6-12 недель в зависимости от тарифа.
🔗 Программа курса и другие подробности
❤1
🤯 Представьте, что ваш AI-агент работает так же предсказуемо, как обычный микросервис. Звучит утопически, но это именно то, к чему должна прийти разработка в 2026 году.
Основная боль текущих реализаций — полная непредсказуемость поведения. Сегодня агент выполнил задачу за два шага, а завтра ушёл в рекурсию и потратил все лимиты.
Наш обновлённый курс «Разработка AI-агентов» научит, как приручить этот хаос с помощью
✅ Что вы получите:
— понимание того, как управлять логикой агента на уровне кода;
— навыки работы с
— готовые паттерны для обработки ошибок и галлюцинаций;
— опыт создания систем, которые реально экономят время.
Есть пара мест со скидкой до завтра, решайтесь 👈🏻
Основная боль текущих реализаций — полная непредсказуемость поведения. Сегодня агент выполнил задачу за два шага, а завтра ушёл в рекурсию и потратил все лимиты.
Наш обновлённый курс «Разработка AI-агентов» научит, как приручить этот хаос с помощью
Python и современных фреймворков. Мы не будем учить «общаться» с нейросетью, мы будем строить из неё надёжный инструмент.✅ Что вы получите:
— понимание того, как управлять логикой агента на уровне кода;
— навыки работы с
LangChain и библиотеками оркестрации;— готовые паттерны для обработки ошибок и галлюцинаций;
— опыт создания систем, которые реально экономят время.
Есть пара мест со скидкой до завтра, решайтесь 👈🏻
Что прошло уже не вернуть, но стоит ознакомиться с нашей подборкой прошедшей недели.
— oaswrap/spec v0.4.0
— Патчи с исправлениями безопасности
— Эмулятор AWS-сервисов
— Entity Component System на Go
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
Типичная ситуация: запущен dev-сервер на порту 3000, нужно на полминуты освободить порт под другую задачу. Убиваете процесс и теряете кэши в памяти, состояние билд-вотчера, прогретые соединения. Потом поднимаете всё заново.
Разработчик написал инструмент park, который решает это иначе: замораживает процесс и освобождает порт, а потом возвращает всё как было. Тот же PID, та же память, те же открытые файлы. Процесс не знает, что что-то произошло.
park 3000 # заморозить и освободить порт
# делаем что нужно на порту 3000
park resume 3000 # вернуть всё обратно
Почему Ctrl+Z не работает
Ctrl+Z отправляет SIGSTOP — процесс замирает, но ядро по-прежнему считает порт занятым. Попытка занять его другим процессом даёт Address already in use. SIGSTOP не закрывает сокет.park решает это через инъекцию
close(fd) прямо в работающий процесс без его перезапуска и изменения кода.Установка:
curl -fsSL https://raw.githubusercontent.com/mr-vaibh/park/main/install.sh | sh
Инсталлятор сам определяет ОС и архитектуру. На macOS автоматически подписывает бинарник с нужными правами для инъекции в процессы.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Большинство Go-разработчиков знают про
go generate, но редко его используют. А зря — это простой способ убрать ручную работу из цикла разработки.Что такое go generate и зачем оно нужно
В каждом проекте есть код, который кто-то должен написать руками: моки для тестов, protobuf-файлы, бойлерплейт для новых сущностей. Обычно это делается руками, иногда забывается, иногда делается неправильно.
go generate решает эту проблему. Вы один раз описываете команду прямо в коде, а потом запускаете одну команду и всё генерируется автоматически.Как это работает
Вы добавляете специальный комментарий в .go-файл:
//go:generate mockgen -source=service.go -destination=mock_service.go -package=service
Потом запускаете:
go generate ./...
Go находит все такие комментарии в проекте и выполняет указанные команды. Всё.
Что можно генерировать
Моки для тестов. Если вы используете
mockgen или moq, достаточно добавить комментарий рядом с интерфейсом и мок всегда будет актуальным://go:generate moq -out=user_repo_mock.go . UserRepository
type UserRepository interface {
FindByID(id int) (*User, error)
Save(user *User) error
}
Protobuf-файлы. Вместо того чтобы каждый раз вспоминать флаги protoc, достаточно один раз прописать команду:
//go:generate protoc --go_out=. --go-grpc_out=. api.proto
Встраивание ресурсов. Генераторы вроде go-bindata упаковывают статику прямо в бинарник.
Строковые представления для констант. stringer автоматически генерирует метод
String() для ваших типов://go:generate stringer -type=Status
type Status int
const (
Active Status = iota
Inactive
Banned
)
Практический совет
Добавьте
go generate ./... в ваш Makefile или CI-пайплайн. Тогда сгенерированный код всегда будет пересоздаваться при сборке, и никто не забудет обновить моки после изменения интерфейса:generate:
go generate ./...
build: generate
go build ./...
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
🧑💻 Свой diff-драйвер для git
Чем это отличается от
Есть более простой способ —
Что git передаёт в драйвер
Многие ожидают, что инструмент получит два аргумента: файл «до» и файл «после». На самом деле git передаёт семь:
При создании или удалении файла вместо несуществующей версии придёт
Пример драйвера:
Аргументы
Как подключить драйвер
В
В
После этого
Diff-драйвер нужен, когда стандартный вывод git бесполезен. Написать его несложно: достаточно bash-скрипта, который принимает семь аргументов и знает, что делать с
➡️ Источник
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction
git diff умеет делегировать сравнение файлов внешнему инструменту. Это называется diff-драйвер. Штатный вывод git не всегда читаем особенно для JSON, YAML или OpenAPI-спецификаций. Вместо того чтобы смотреть на кашу из + и -, можно подключить инструмент, который покажет изменения в удобном виде.Чем это отличается от
textconvЕсть более простой способ —
textconv. Он конвертирует файл в текст, и git сравнивает уже текст. Но если нужно не просто показать разницу построчно, а сформировать собственный вывод, например, changelog между двумя версиями API, textconv не подойдёт. Тут нужен полноценный драйвер.Что git передаёт в драйвер
Многие ожидают, что инструмент получит два аргумента: файл «до» и файл «после». На самом деле git передаёт семь:
# при изменении существующего файла
my-diff-tool \
path/to/file.json # 1: путь к файлу в репозитории
/tmp/git-blob-xxx/file.json # 2: "до"
f0a1311ae439... # 3: SHA-1 хэш "до"
100644 # 4: octal mode "до"
/tmp/git-blob-yyy/file.json # 5: "после"
e39975894a72... # 6: SHA-1 хэш "после"
100644 # 7: octal mode "после"
При создании или удалении файла вместо несуществующей версии придёт
/dev/null, а неприменимые аргументы заменяются точкой .:# новый файл
my-diff-tool \
path/to/file.json
/dev/null # файла "до" не было
.
.
/tmp/git-blob-yyy/file.json
5c55e5b99b21...
100644
# удалённый файл
my-diff-tool \
path/to/file.json
/tmp/git-blob-xxx/file.json
6b24e38aa4aa...
100644
/dev/null # файла "после" нет
.
.
Пример драйвера:
#!/usr/bin/env bash
# diff-драйвер для OpenAPI-спецификаций через oasdiff
if [[ "$2" == "/dev/null" ]]; then
echo "$1 was added"
exit 0
elif [[ "$5" == "/dev/null" ]]; then
echo "$1 was deleted"
exit 0
fi
oasdiff changelog "$2" "$5" --color always
Аргументы
$2 и $5 это пути к временным файлам «до» и «после», которые git уже подготовил.Как подключить драйвер
В
.gitattributes указываем, для каких файлов его использовать:*.yaml diff=oasdiff
В
.git/config или глобальном ~/.gitconfig регистрируем сам драйвер:[diff "oasdiff"]
command = /path/to/oasdiff-driver.sh
После этого
git diff будет вызывать скрипт для всех .yaml-файлов вместо стандартного построчного сравнения.Diff-драйвер нужен, когда стандартный вывод git бесполезен. Написать его несложно: достаточно bash-скрипта, который принимает семь аргументов и знает, что делать с
/dev/null для новых и удалённых файлов. Всё остальное берёт на себя git.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
❤9👍2
Когда проект растёт, рано или поздно кто-то импортирует не то, что нужно. Репозиторий тянет сервис, хендлер лезет напрямую в базу и архитектура начинает разваливаться. Go решает это на уровне компилятора.
Что такое internal
Папка
internal это встроенный механизм Go для ограничения импортов. Любой пакет внутри internal/ можно импортировать только из кода, который находится в родительском модуле этой папки. Всё остальное компилятор просто не пропустит.Типичная структура проекта:
myapp/
├── cmd/
│ └── main.go
├── internal/
│ ├── service/
│ │ └── user.go
│ └── repository/
│ └── user.go
└── pkg/
└── utils/
Код в
cmd/ может импортировать internal/service и internal/repository. А вот внешний пакет или другой модуль нет. Go выдаст ошибку компиляции:imports myapp/internal/service: use of internal package not allowed
Можно вкладывать internal глубже
internal работает не только на уровне корня проекта. Его можно положить внутрь любого пакета:
myapp/
├── payment/
│ ├── internal/
│ │ └── processor/
│ └── payment.go
internal это не соглашение, а правило, которое компилятор применяет сам.
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
❤16❤🔥5👍5🔥1🌚1
Doors это бэкенд-фреймворк для веб-приложений на Go. Он позволяет строить реактивный UI без JS-фреймворков, без гидратации и без npm. Весь бизнес-логика живёт на сервере, браузер работает только как тонкий клиент для отображения.
Стандартный стек Go + React требует писать и поддерживать два слоя: API на Go и фронт на JS. Это дублирование типов, синхронизация состояния, сборка, зависимости. Htmx даёт частичные обновления страницы, но не даёт нормального реактивного состояния и контроля из Go.
Doors убирает API-слой полностью. Сервер держит живое состояние каждой вкладки пользователя, а браузер просто синхронизирует изменения DOM.
Как это работает
При загрузке страницы сервер создаёт экземпляр сессии и отдаёт cookie. Дальше между клиентом и сервером держится лёгкое соединение через короткие HTTP-запросы с поддержкой QUIC.
Пользователь что-то делает и событие летит на Go-обработчик. Сервер считает изменения и отдаёт конкретные обновления DOM.
Два ключевых примитива:
Door — динамический контейнер в HTML. Умеет обновляться, заменяться, удаляться. Каждый Door имеет свой жизненный цикл и локальный context, который можно использовать как хук при размонтировании.
Beam — реактивное состояние на сервере. SourceBeam хранит мутабельное значение, производные Beam считаются из него. Обновления гарантированно консистентны по дереву контейнеров.
Пример запуска:
import "github.com/doors-dev/doors"
func main() {
app := doors.New()
// регистрация страниц и обработчиков
app.Run(":8080")
}
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥8👍4❤3🌚1
Senior Go Developer — удаленно по Москве
Golang Middle/Senior Developer — до 420 000 ₽, удаленно кроме РФ, РБ и Израиля
Junior Бэкенд-разработчик — от 80 000 до 120 000 ₽ в офис в Тамбове
#GoWork
Please open Telegram to view this post
VIEW IN TELEGRAM
Мокать базу данных — занятие неблагодарное. Каждое изменение схемы тянет за собой правки в моках, а уверенности в корректности поведения всё равно нет. Настоящий тест это тест против реального PostgreSQL, Redis или любого другого сервиса.
ory/dockertest решает эту задачу: библиотека поднимает Docker-контейнеры прямо из Go-теста и убирает их по завершении.Как это работает:
func TestPostgres(t *testing.T) {
pool := dockertest.NewPoolT(t, "")
postgres := pool.RunT(t, "postgres",
dockertest.WithTag("14"),
dockertest.WithEnv([]string{
"POSTGRES_PASSWORD=secret",
"POSTGRES_DB=testdb",
}),
)
hostPort := postgres.GetHostPort("5432/tcp")
err := pool.Retry(t.Context(), 30*time.Second, func() error {
db, err := sql.Open("pgx", "postgres://postgres:secret@"+hostPort+"/testdb")
if err != nil {
return err
}
return db.Ping()
})
if err != nil {
t.Fatalf("не удалось подключиться: %v", err)
}
}Контейнер поднимается, тест выполняется, контейнер удаляется. Всё через
t.Cleanup, без лишнего кода.Установка:
go get github.com/ory/dockertest/v4
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14😁1