Представляем подборку материалов и новостей недели.
— HTML-формы из Go-структур
— Убрать из Windows 11 всё лишнее
— Excelize 2.10.1
— Go наконец-то получит обобщённые методы
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
Стек — это только инструмент. Готов ли ты стать кофаундером продукта? 🚀
Энтерпрайз даёт стабильность, но часто забирает драйв. Proglib App предлагает другое: роль технического лидера в EdTech-платформе. Мы обучаем разработчиков через курсы, квизы и ИИ-агентов. MVP готов, юзеры учатся.
Нужен сильный инженер, который перерос рамки одного языка и хочет влиять на архитектуру и бизнес-логику всего сервиса.
🛠️ Стек (современный Fullstack):
TypeScript, React 18, Express 5, PostgreSQL, Drizzle ORM.
Почему это вызов для тебя:
• Никакой бюрократии: ты и основатель (он тоже кодит) решаете всё сами. • Инструменты будущего: активное использование Claude Code и Cursor. • Масштаб: путь от MVP до лидера рынка образовательных платформ.
Ожидания:
• Крепкий бэкграунд в разработке и проектировании БД. • Готовность быстро включиться в работу с TS/React/Node.js. • Автономность и продуктовое мышление.
Удалёнка, гибкий график, отсутствие «стеклянного потолка».
Готов сменить привычный цикл обновлений на драйв кофаундера? Пиши в бота 👇
@proglibrary_feedback_bot
Энтерпрайз даёт стабильность, но часто забирает драйв. Proglib App предлагает другое: роль технического лидера в EdTech-платформе. Мы обучаем разработчиков через курсы, квизы и ИИ-агентов. MVP готов, юзеры учатся.
Нужен сильный инженер, который перерос рамки одного языка и хочет влиять на архитектуру и бизнес-логику всего сервиса.
🛠️ Стек (современный Fullstack):
TypeScript, React 18, Express 5, PostgreSQL, Drizzle ORM.
Почему это вызов для тебя:
• Никакой бюрократии: ты и основатель (он тоже кодит) решаете всё сами. • Инструменты будущего: активное использование Claude Code и Cursor. • Масштаб: путь от MVP до лидера рынка образовательных платформ.
Ожидания:
• Крепкий бэкграунд в разработке и проектировании БД. • Готовность быстро включиться в работу с TS/React/Node.js. • Автономность и продуктовое мышление.
Удалёнка, гибкий график, отсутствие «стеклянного потолка».
Готов сменить привычный цикл обновлений на драйв кофаундера? Пиши в бота 👇
@proglibrary_feedback_bot
😁7❤1
Anonymous Poll
26%
🔥 Отличная фича
41%
👍 Полезны, но использую редко
17%
😐 Спорно — усложняют простоту Go
10%
🚀 Нужно развивать дальше
6%
❌ Лишние — Go был хорош без них
Вы когда-нибудь тратили час на то, чтобы разобраться с задачей, которую уже решали год назад? Нашли нужный инструмент, выставили настройки, сделали всё как надо — и не записали. А теперь начинаете с нуля.
Выход простой: место, куда вы складываете «как я это делал». Не сложная система, не красивый Notion. Просто текстовые заметки с поиском.
Что туда стоит записывать:
— настройки программ, к которым редко возвращаетесь
— процессы с неочевидными шагами
— всё, что вы искали больше одного раза
Чтобы это работало, важны три вещи
Одно место. Не пять приложений — одно. Apple Notes, папка с файлами, что угодно с поиском внутри.
Один тег. Помечайте каждую такую заметку одинаково — например #howto. Тогда все инструкции найдутся за секунду.
Точное название. Подумайте: какое слово вы введёте в поиск через год, когда снова понадобится этот процесс? Оно должно быть в заголовке. «Как написать middleware для JWT в Gin» — работает. «Как добавить авторизацию» — нет.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Большинство команд берут Kafka не потому что нужно, а потому что это звучит солидно на митинге по архитектуре.
Kafka это серьёзная технология. Миллионы сообщений в секунду, replay истории, десятки потребителей.
Но вместе с этим вы берёте на себя:
ZooKeeper или KRaft с миграцией, управление брокерами и ребалансировку партиций, schema registry, координацию consumer groups, мониторинг lag и дискового пространства.
И если ваша задача «отправить уведомление при создании заказа», вы платите за распределённые системы там, где хватило бы одного вечера.
Три вопроса перед тем, как тянуться к Kafka
Сколько сообщений вы обрабатываете? Если это тысячи в день, хорошо настроенный Postgres тянет десятки тысяч записей в секунду. Redis Streams справляется с 10–100k событий в секунду без отдельной команды ops.
Нужно ли вам воспроизведение событий? Это настоящее преимущество Kafka. Но если ваши потребители не хранят состояние, вы платите за функцию, которой не пользуетесь.
Сколько у вас независимых потребителей? Для 1–5 потребителей простой pub/sub закрывает задачу.
Что работает вместо Kafka
Transactional Outbox на Postgres. Пишете бизнес-данные и событие в одной транзакции в таблицу outbox. Отдельный воркер опрашивает её и публикует сообщения.
tx, _ := db.Begin()
tx.Exec(`INSERT INTO orders (id, user_id, total) VALUES ($1, $2, $3)`, orderID, userID, total)
tx.Exec(`INSERT INTO outbox (id, event_type, payload, created_at)
VALUES ($1, $2, now())`, uuid.New(), "order.placed", payload)
tx.Commit()
Redis Streams. Поддерживает группы потребителей, постоянное хранение сообщений, подтверждения и семантику доставки «хотя бы один раз». Даёт 90–95% от того, что даёт Kafka. И, скорее всего, Redis у вас уже есть.
// Produce
rdb.XAdd(ctx, &redis.XAddArgs{
Stream: "orders",
Values: map[string]interface{}{"order_id": orderID, "user_id": userID},
})
// Consume с consumer group
msgs, _ := rdb.XReadGroup(ctx, &redis.XReadGroupArgs{
Group: "notifications",
Consumer: "worker-1",
Streams: []string{"orders", ">"},
Count: 10,
}).Result()
Когда Kafka оправдана
Миллионы событий в секунду с горизонтальным масштабированием. Долгосрочное воспроизведение на дни и недели. Событийный источник данных, где журнал и есть источник истины. Много независимых команд-потребителей. Потоковая передача в хранилище данных в реальном времени.
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍22🤔12😁4❤2
🛠 Массивы — фиксированные и быстрые
Массивы в Go работают не так, как в большинстве других языков. Главное отличие — они передаются по значению.
Объявление массива фиксирует его размер навсегда. Пять элементов — значит пять, не больше и не меньше.
Обращение к элементам стандартное. Первый элемент через нулевой индекс, последний через len(arr)-1:
Изменить значение так же просто:
Перебор элементов
Два способа. Классический цикл через индекс:
И через range:
Если индекс не нужен, его заменяют на
Главная ловушка
Массивы в Go это значения, не ссылки. При присваивании создаётся полная копия:
a и b живут независимо. Изменения в одном не затрагивают другой.
Это работает не так, как в Python или JavaScript, где присваивание массива передаёт ссылку. В Go это всегда копия.
Если передать большой массив в функцию, Go скопирует его целиком. Для небольших данных это нормально. Для больших лучше использовать срезы или передавать указатель:
Массивы в Go просты, но ведут себя иначе, чем в других языках.
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoDeep
Массивы в Go работают не так, как в большинстве других языков. Главное отличие — они передаются по значению.
Объявление массива фиксирует его размер навсегда. Пять элементов — значит пять, не больше и не меньше.
arr := [5]int{10, 20, 30, 40, 50}Обращение к элементам стандартное. Первый элемент через нулевой индекс, последний через len(arr)-1:
arr[0] // 10
arr[len(arr)-1] // 50
Изменить значение так же просто:
arr[0] = 100
Перебор элементов
Два способа. Классический цикл через индекс:
for i := 0; i < len(arr); i++ {
fmt.Println(arr[i])
}И через range:
for i, v := range arr {
fmt.Printf("Index: %d, Value: %d\n", i, v)
}Если индекс не нужен, его заменяют на
_.Главная ловушка
Массивы в Go это значения, не ссылки. При присваивании создаётся полная копия:
a := [3]int{1, 2, 3}
b := a // b это отдельная копия
b[0] = 100
fmt.Println(a[0]) // 1 — не изменился
fmt.Println(b[0]) // 100a и b живут независимо. Изменения в одном не затрагивают другой.
Это работает не так, как в Python или JavaScript, где присваивание массива передаёт ссылку. В Go это всегда копия.
Если передать большой массив в функцию, Go скопирует его целиком. Для небольших данных это нормально. Для больших лучше использовать срезы или передавать указатель:
func process(arr [1000]int) { ... } // копирует 1000 элементов
func process(arr *[1000]int) { ... } // передаёт указательМассивы в Go просты, но ведут себя иначе, чем в других языках.
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18❤🔥6❤4
🔄 Массивы переехали и fuzz-тесты добавлены в mus-go
mus-go — это библиотека для бинарной сериализации на Go. Она реализует формат MUS, который делает упор на компактность и скорость.
Вместо JSON или протобафа вы получаете минималистичный бинарный формат с нулевым аллоцированием при десериализации и поддержкой версионирования данных.
В v0.8.0 три изменения. Одно из них ломает обратную совместимость.
Перенос array.go в пакет unsafe
Это единственное breaking change в релизе. Файл array.go переехал из пакета ord в пакет unsafe. Логика правильная, ведь реализация там и была небезопасной, просто лежала не там.
Fuzz-тестирование
Добавили нативные fuzz-тесты. Битые или специально сформированные байты не должны приводить к панике или неожиданному поведению. Теперь это проверяется автоматически.
Обслуживание
Обновили зависимости common-go и mok до актуальных версий. Папка testdata переименована в testutil — чисто организационное изменение, на код не влияет.
➡️ Release notes
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoLive
mus-go — это библиотека для бинарной сериализации на Go. Она реализует формат MUS, который делает упор на компактность и скорость.
Вместо JSON или протобафа вы получаете минималистичный бинарный формат с нулевым аллоцированием при десериализации и поддержкой версионирования данных.
В v0.8.0 три изменения. Одно из них ломает обратную совместимость.
Перенос array.go в пакет unsafe
Это единственное breaking change в релизе. Файл array.go переехал из пакета ord в пакет unsafe. Логика правильная, ведь реализация там и была небезопасной, просто лежала не там.
Fuzz-тестирование
Добавили нативные fuzz-тесты. Битые или специально сформированные байты не должны приводить к панике или неожиданному поведению. Теперь это проверяется автоматически.
Обслуживание
Обновили зависимости common-go и mok до актуальных версий. Папка testdata переименована в testutil — чисто организационное изменение, на код не влияет.
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
«Простота — великая добродетель, но она требует тяжёлого труда и образования, чтобы её оценить. И к тому же сложность продаётся лучше» — Дейкстра сказал это давно, но инженерные команды до сих пор не услышали.
Инженер А смотрит на задачу, выбирает простейшее решение, пишет 50 строк понятного кода и выкатывает за два дня. Инженер Б видит «возможность», он добавляет слой абстракции, pub/sub для коммуникации между компонентами, конфигурационный фреймворк для «расширяемости». Три недели, несколько PR, восторженные эмодзи в слаке.
Приходит время повышения. Б пишет так: «Спроектировал event-driven архитектуру, создал переиспользуемый абстрактный слой, внедрил конфигурационный фреймворк».
У А написать нечего. «Реализовала фичу X». Три слова. Её работа была лучше — но невидима.
Что делать инженеру
Простоту нужно делать видимой. «Рассмотрели три подхода включая event-driven архитектуру, определила что прямолинейная реализация покрывает все текущие и прогнозируемые требования, выкатила за два дня, ноль инцидентов за шесть месяцев» — это то же самое решение, просто описанное честно.
Решение не строить что-то — это тоже решение. Документируйте его.
Сложность сама по себе — не враг. Если вы обрабатываете миллионы транзакций — распределённые системы нужны. Проблема в незаработанной сложности.
📍 Навигация: Вакансии • Задачи • Собесы
#GoTalk
Please open Telegram to view this post
VIEW IN TELEGRAM
👍21❤6🔥3⚡1
Senior Golang разработчик (команда Campaigner) — Удаленно
Middle Golang — от 284 300 ₽, удаленно
Middle Golang — от 280 000 ₽, тоже удаленно
Бустер — удалённо (не только Москва)
#GoWork
Please open Telegram to view this post
VIEW IN TELEGRAM
Есть один приём, который почти не требует усилий, но заметно улучшает читаемость и надёжность кода. Речь про type aliases для доменного моделирования.
Представьте функцию в платёжной системе:
func Transfer(amount float64, currency, fromAccount, toAccount string) error
Четыре параметра разных смыслов, но компилятор видит просто
float64 и три string. Перепутать аргументы местами проще, чем кажется.Проблема в том, что
string и float64 не несут никакой семантики. Это просто формы данных. Является ли строка кодом валюты, номером счёта или чем-то ещё — известно только из документации, которую никто не читает в спешке.Решение простое:
type Amount float64
type Currency string
type AccountNumber string
func Transfer(amount Amount, currency Currency, from, to AccountNumber) error {
// реализация
}
Теперь передать сумму туда, где ждут номер счёта, физически невозможно:
// Это не скомпилируется
Transfer(AccountNumber("ACC-001"), Currency("USD"), Amount(100.0), ...)
// А это читается без комментариев
Transfer(
Amount(100.0),
Currency("USD"),
AccountNumber("ACC-001"),
AccountNumber("ACC-002"),
)
Следующий шаг — валидация прямо в конструкторе типа. Отрицательная сумма перевода не должна существовать в системе как валидное значение:
func NewAmount(v float64) (Amount, error) {
if v <= 0 {
return 0, fmt.Errorf("сумма должна быть больше нуля, получено: %v", v)
}
return Amount(v), nil
}
var supportedCurrencies = map[string]bool{
"USD": true, "EUR": true, "RUB": true,
}
func NewCurrency(s string) (Currency, error) {
if !supportedCurrencies[strings.ToUpper(s)] {
return "", fmt.Errorf("неподдерживаемая валюта: %s", s)
}
return Currency(strings.ToUpper(s)), nil
}type Amount float64 создаёт не синоним, а новый несовместимый тип. Передать обычный float64 туда, где ждут Amount, без явного приведения не выйдет.Один из тех приёмов, который стоит закладывать в доменную модель с самого начала.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍28❤9🤔4
🤔 Спам тимлидам, фейковые офферы и приукрашенное резюме
IT-рынок 2026 года — это не конкурс честных и талантливых. Компании говорят об экологичной культуре, а сами гостят после четырёх этапов отбора.
На одну вакансию — тысяча откликов за сутки. В таких условиях выигрывают не самые опытные, а самые адаптивные.
➡️ Узнать приёмы тех, кто смог
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
IT-рынок 2026 года — это не конкурс честных и талантливых. Компании говорят об экологичной культуре, а сами гостят после четырёх этапов отбора.
На одну вакансию — тысяча откликов за сутки. В таких условиях выигрывают не самые опытные, а самые адаптивные.
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2
This media is not supported in your browser
VIEW IN TELEGRAM
😁6
📅 Старт курса — 20 апреля.
Если хотите разобраться, как строить управляемые агентные системы:
P.S.
Please open Telegram to view this post
VIEW IN TELEGRAM
🥱5👍1
🔄 Go 1.26.1 и 1.25.8
Вышли новые версии Go. Ничего революционного, просто патчи безопасности.
В crypto/x509 нашли проблему с проверкой email-адресов в сертификатах. Когда сертификат содержит несколько ограничений на emai система игнорирует все ограничения кроме последнего.
В html/template нашли проблему с экранированием URLs в meta-тегах. Если у вас в контенте есть refresh meta-тег и вы туда подставляете какой-то URL через действия шаблона, он не будет экранирован.
➡️ Анонс
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoLive
Вышли новые версии Go. Ничего революционного, просто патчи безопасности.
В crypto/x509 нашли проблему с проверкой email-адресов в сертификатах. Когда сертификат содержит несколько ограничений на emai система игнорирует все ограничения кроме последнего.
В html/template нашли проблему с экранированием URLs в meta-тегах. Если у вас в контенте есть refresh meta-тег и вы туда подставляете какой-то URL через действия шаблона, он не будет экранирован.
net/url.Parse оказывается принимал невалидные IPv6-адреса, потому что недостаточно проверял хост-компонент. Теперь IPv6-литералы должны стоять в начале хоста, остальное будет отклонено.📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤6🔥1😁1
Горутины дешёвые, но не бесплатные. Каждая занимает минимум 2KB памяти. Когда запускаете сотни или тысячи горутин, это становится ощутимо. Но главная проблема не в памяти, а в том, что горутина может зависнуть и никогда не завершиться.
Проблема с time.Sleep
Часто видим такой паттерн:
func Job(d time.Duration) {
for {
doWork()
time.Sleep(d)
}
}На первый взгляд это удобно. Но когда приложение получает SIGTERM и нужно выключиться, горутина может быть посередине
sleep. Она просто проигнорирует сигнал выключения и продолжит спать. Graceful shutdown не будет таким graceful.time.Sleep не знает про контекст и не может быть прерван. Поэтому используйте context:func Job(ctx context.Context, d time.Duration) {
for {
select {
case <-ctx.Done():
return
default:
doWork()
time.Sleep(d)
}
}
}Теперь горутина проверит контекст перед каждой итерацией. Если приложение выключается,
context будет отменён и горутина выйдет. Даже если она посередине sleep, следующая итерация её закроет.Утечки через каналы
Вот другой сценарий:
func worker(jobs <-chan int) {
for i := range jobs {
process(i)
}
}
jobs := make(chan int)
go worker(jobs)Выглядит просто. Закроем канал
jobs и горутина выйдет. Но что если где-то в коде забыли закрыть канал? Горутина будет ждать бесконечно. Даже не упадёт, просто повиснет в памяти. Утечка.Часто это происходит, когда забывают про
defer или неправильно структурируют код. Горутина ждёт данных из канала, но никто их туда не отправляет.Как правильно
Главное правило: сделайте очевидным, когда горутина стартует и когда заканчивается. Не надо полагаться на магию вроде автоматического закрытия канала.
Передавайте
context во все горутины, которые крутятся долго. Используйте select с <-ctx.Done(). Явно закрывайте каналы, по которым читаете. Не создавайте горутины просто так, всегда планируйте как их остановить.Если горутина может зависнуть, добавьте таймаут:
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
go worker(ctx, jobs)
Каждая горутина которую вы запускаете, это потенциальная утечка если забыть её корректно завершить. Всегда знайте, как горутина заканчивается.
Context, каналы и таймауты это ваши друзья.📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16⚡1❤1
В коде есть функция вывода, но успеет ли она отработать до выхода из прогарммы?
📍 Навигация: Вакансии • Задачи • Собесы
#ReadySetGo
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔4🔥3😁1
Берешь популярную ORM, она обещает удобство, а потом выясняется, что код либо медленный, либо писать его больнее, чем на сыром SQL. Ent от Meta подходит к проблеме иначе.
Вместо того чтобы выбирать между скоростью и удобством, Ent просто генерирует тебе type-safe код прямо из схемы. Пишем структуру в Go, и она автоматически становится слоем работы с БД.
Полезные фичи
Поддержка PostgreSQL JSONB из коробки. Если нужны гибкие структуры данных, не нужно городить велосипед с отдельной таблицей или JSON-полем, которое трудно индексировать.
Миграции генерируются автоматически. Меняете схему, и CLI сам создает SQL. Конечно, проверить стоит, но руки уже не болят от написания однотипного кода.
GraphQL встроен в архитектуру. Ваша модель данных тут же становится запрашиваемой. Не нужно отдельно писать резолверы для каждого поля.
Вот как выглядит код на практике:
client.User.
Create().
SetName("Aashish").
SetEmail("aashish@example.com").
Save(ctx)
Разработчики его любят не за маркетинговый лозунг, а за то, что он просто решает задачи.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14❤7🥱2
💥 Открытый вебинар | ИИ-агенты в продакшене: от хайпа к деньгам
Агенты уже везде. Но мало кто признаётся, сколько денег сжёг на бесконечных циклах, галлюцинациях в RAG и отсутствии мониторинга.
Полина Полунина, руководитель AI-направления Альфа-Банка, расскажет честно:
▪️ Чем агент отличается от «просто GPT с промптом» и когда бизнесу достаточно обычного LLM
▪️ 3 реальных кейса из корпоративной среды: что взлетело, а что нет
▪️ Live-демо работающего агента
▪️ ТОП-5 граблей, на которые наступают команды при внедрении
⏱️ 10 марта в 19:00 (МСК)
🎁 Участники получат промокод на скидку на самый полный курс по ИИ-агентам
👉 Регистрируйся
Агенты уже везде. Но мало кто признаётся, сколько денег сжёг на бесконечных циклах, галлюцинациях в RAG и отсутствии мониторинга.
Полина Полунина, руководитель AI-направления Альфа-Банка, расскажет честно:
▪️ Чем агент отличается от «просто GPT с промптом» и когда бизнесу достаточно обычного LLM
▪️ 3 реальных кейса из корпоративной среды: что взлетело, а что нет
▪️ Live-демо работающего агента
▪️ ТОП-5 граблей, на которые наступают команды при внедрении
⏱️ 10 марта в 19:00 (МСК)
🎁 Участники получат промокод на скидку на самый полный курс по ИИ-агентам
👉 Регистрируйся
Пришло время собрать интересные материалы первой недели весны.
— Go 1.26.1 и 1.25.8
— Вам не нужна Kafka
— mus-go обновился
— За простоту не повышают
— Спам тимлидам, фейковые офферы и приукрашенное резюме
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1