🛠️ История создания “storage-agnostic” message queue
Автор — Fahim Faisaal — делится опытом разработки гибкой очереди задач на Go, которая может использовать любые хранилища: in-memory, Redis, SQLite и др. :contentReference[oaicite:0]{index=0}
Контекст:
Занимаясь на Go, автор вдохновился инструментами из Node.js экосистемы (BullMQ, RabbitMQ) и захотел сделать что-то похожее, но с нуля, без зависимостей. Так родилась идея — сначала он создал Gocq (Go Concurrent Queue): простую concurrent-очередь, работающую через каналы :contentReference[oaicite:1]{index=1}.
⚡ Основная проблема
Gocq отлично работал в памяти, но не поддерживал устойчивое хранение задач.
Автор задумался: а можно ли сделать очередь, не зависящую от конкретного хранилища — так, чтобы её можно было подключить к Redis, SQLite или совсем без них?
🧱 Как это реализовано в VarMQ
После рефакторинга Gocq был разделён на два компонента:
1. Worker pool — пул воркеров, обрабатывающих задачи.
2. Queue interface — абстракция над очередью, не зависящая от реализации.
Теперь воркер просто берёт задачи из очереди, не зная, где они живут. :contentReference[oaicite:2]{index=2}
---
### 🧠 Пример использования
- In-memory очередь:
- С SQLite-поддержкой:
- С Redis (для распределённой обработки):
В итоге воркер обрабатывает задачи одинаково — независимо от хранилища. :contentReference[oaicite:3]{index=3}
✅ Почему это круто
- Гибкость: адаптеры позволяют легко менять хранилище без правок воркера.
- Минимальные зависимости: в ядре — zero-deps, весь функционал — через адаптеры.
- Self-hosted и легковесно: можно развернуть локально или в продакшене.
- Написано на Go: использует горутины и каналы, удобен и эффективен.
📣 Отзывы сообщества
На Reddit отметили, что автор добился "queue system that doesn’t care if your storage is Redis, SQLite, or even in-memory" :contentReference[oaicite:4]{index=4}
🔗 Ссылки
- Статья: A Story of Building a Storage‑Agnostic Message Queue на DEV :contentReference[oaicite:5]{index=5}
- GitHub VarMQ (Var-storage-agnostic message queue): репозиторий с кодом адаптеров и примерами использования :contentReference[oaicite:6]{index=6}
Итог: VarMQ — это элегантное решение на Go для создания задач-очереди, универсально по отношению к хранилищу: выбрал нужный адаптер — и система работает.
📌 Читать
Автор — Fahim Faisaal — делится опытом разработки гибкой очереди задач на Go, которая может использовать любые хранилища: in-memory, Redis, SQLite и др. :contentReference[oaicite:0]{index=0}
Контекст:
Занимаясь на Go, автор вдохновился инструментами из Node.js экосистемы (BullMQ, RabbitMQ) и захотел сделать что-то похожее, но с нуля, без зависимостей. Так родилась идея — сначала он создал Gocq (Go Concurrent Queue): простую concurrent-очередь, работающую через каналы :contentReference[oaicite:1]{index=1}.
⚡ Основная проблема
Gocq отлично работал в памяти, но не поддерживал устойчивое хранение задач.
Автор задумался: а можно ли сделать очередь, не зависящую от конкретного хранилища — так, чтобы её можно было подключить к Redis, SQLite или совсем без них?
🧱 Как это реализовано в VarMQ
После рефакторинга Gocq был разделён на два компонента:
1. Worker pool — пул воркеров, обрабатывающих задачи.
2. Queue interface — абстракция над очередью, не зависящая от реализации.
Теперь воркер просто берёт задачи из очереди, не зная, где они живут. :contentReference[oaicite:2]{index=2}
---
### 🧠 Пример использования
- In-memory очередь:
w := varmq.NewVoidWorker(func(data any) {
// обработка задачи
}, 2)
q := w.BindQueue()
- С SQLite-поддержкой:
import "github.com/goptics/sqliteq"
db := sqliteq.New("test.db")
pq, _ := db.NewQueue("orders")
q := w.WithPersistentQueue(pq)
- С Redis (для распределённой обработки):
import "github.com/goptics/redisq"
rdb := redisq.New("redis://localhost:6379")
pq := rdb.NewDistributedQueue("transactions")
q := w.WithDistributedQueue(pq)
В итоге воркер обрабатывает задачи одинаково — независимо от хранилища. :contentReference[oaicite:3]{index=3}
✅ Почему это круто
- Гибкость: адаптеры позволяют легко менять хранилище без правок воркера.
- Минимальные зависимости: в ядре — zero-deps, весь функционал — через адаптеры.
- Self-hosted и легковесно: можно развернуть локально или в продакшене.
- Написано на Go: использует горутины и каналы, удобен и эффективен.
📣 Отзывы сообщества
На Reddit отметили, что автор добился "queue system that doesn’t care if your storage is Redis, SQLite, or even in-memory" :contentReference[oaicite:4]{index=4}
🔗 Ссылки
- Статья: A Story of Building a Storage‑Agnostic Message Queue на DEV :contentReference[oaicite:5]{index=5}
- GitHub VarMQ (Var-storage-agnostic message queue): репозиторий с кодом адаптеров и примерами использования :contentReference[oaicite:6]{index=6}
Итог: VarMQ — это элегантное решение на Go для создания задач-очереди, универсально по отношению к хранилищу: выбрал нужный адаптер — и система работает.
📌 Читать
🧪 Go synctest — решение для нестабильных (flaky) тестов
Flaky-тесты в многопоточном Go-коде — боль. Новый экспериментальный инструмент
📌 Что это такое:
•
• все goroutine исполняются детерминированно
• нет зависимости от планировщика и нагрузки ОС
🔧 Пример:
⏱ Даже с
⚙️ Преимущества:
✅ Устранение race-условий при тестировании
✅ Нет задержек —
✅ Можно тестировать поведение с точностью до микросекунды
✅ Подходит для любых
🚫 Ограничения:
• Пока экспериментально: нужно запускать с
• Не подходит для ввода-вывода, работы с сетью или временем вне "bubble"
📖 Подробнее:
https://victoriametrics.com/blog/go-synctest/
Flaky-тесты в многопоточном Go-коде — боль. Новый экспериментальный инструмент
synctest
из Go 1.24 решает эту проблему с помощью синтетического времени и контроля исполнения goroutine.📌 Что это такое:
synctest
— специальный режим, запускающий тесты в изолированной "песочнице", где:•
time.Sleep
не ждёт реального времени • все goroutine исполняются детерминированно
• нет зависимости от планировщика и нагрузки ОС
🔧 Пример:
import "testing/synctest"
func TestSharedValue(t *testing.T) {
synctest.Run(func() {
var shared atomic.Int64
go func() {
shared.Store(1)
time.Sleep(1 * time.Microsecond)
shared.Store(2)
}()
time.Sleep(5 * time.Microsecond)
if shared.Load() != 2 {
t.Errorf("shared = %d, want 2", shared.Load())
}
})
}
⏱ Даже с
Sleep
, результат всегда стабилен. Без synctest
такой тест может иногда проваливаться.⚙️ Преимущества:
✅ Устранение race-условий при тестировании
✅ Нет задержек —
Sleep
срабатывает мгновенно ✅ Можно тестировать поведение с точностью до микросекунды
✅ Подходит для любых
atomic
, mutex
, select
, time.After
и др.🚫 Ограничения:
• Пока экспериментально: нужно запускать с
GOEXPERIMENT=synctest
• Не подходит для ввода-вывода, работы с сетью или временем вне "bubble"
📖 Подробнее:
https://victoriametrics.com/blog/go-synctest/
Расширенный_гайд_по_Docker_для_DevOps_специалистов_1_2.pdf
391.1 KB
• как устроен Docker изнутри
• как упаковать любое приложение в контейнер
• как запускать десятки сервисов одной командой
• как дебажить, оптимизировать и защищать контейнеры
• как не сойти с ума с volumes, networks и образами
Сохраняй и делись с коллегами, чтобы не потерять
@golang_books
Please open Telegram to view this post
VIEW IN TELEGRAM
📢 GORM теперь поддерживает дженерики — работа с БД в Go стала ещё проще и безопаснее!
С версии GORM v1.30.0 появилась полноценная поддержка дженериков (Go 1.18+), которая позволяет писать более выразительный и типобезопасный код без шаблонных повторов.
🔧 Пример:
✅ Что это даёт:
• Типобезопасность на этапе компиляции
• Более компактный и читаемый код
• Лёгкая интеграция с
• Улучшенный DX (developer experience)
📎 Документация: https://gorm.io/docs/the_generics_way.html
Если ты пишешь на Go и используешь GORM — самое время перейти на новый стиль.
С версии GORM v1.30.0 появилась полноценная поддержка дженериков (Go 1.18+), которая позволяет писать более выразительный и типобезопасный код без шаблонных повторов.
🔧 Пример:
ctx := context.Background()
// Создание
gorm.G[User](db).Create(ctx, &User{Name: "Alice"})
// Поиск
user, err := gorm.G[User](db).Where("name = ?", "Alice").First(ctx)
// Обновление
gorm.G[User](db).Where("id = ?", user.ID).Update(ctx, "age", 30)
// Удаление
gorm.G[User](db).Where("id = ?", user.ID).Delete(ctx)
✅ Что это даёт:
• Типобезопасность на этапе компиляции
• Более компактный и читаемый код
• Лёгкая интеграция с
OnConflict
, Joins
, Hints
, Preload
и пр. • Улучшенный DX (developer experience)
📎 Документация: https://gorm.io/docs/the_generics_way.html
Если ты пишешь на Go и используешь GORM — самое время перейти на новый стиль.
🚀 Кэширование в Go: как делать правильно
В свежей статье от Leapcell рассматриваются ключевые аспекты эффективного кэширования в Go:
- Планирование объёма памяти: важно заранее оценить, сколько данных будет кэшироваться, чтобы избежать переполнения памяти (OOM).
- Классификация данных: разделение данных на "горячие" и "холодные" помогает оптимизировать использование ресурсов, сохраняя часто используемые данные в быстром доступе, а редко используемые — на более экономичных носителях.
- Стратегии кэширования в распределённых системах:
- Использование распределённого кэша (например, Redis).
- Направление одинаковых запросов на один и тот же экземпляр приложения.
- Репликация кэша на каждом экземпляре приложения.
- Политики вытеснения: применение алгоритма LRU (Least Recently Used) помогает контролировать размер кэша, удаляя наименее используемые элементы.
Подробнее: https://dev.to/leapcell/caching-in-go-doing-it-right-25i5
В свежей статье от Leapcell рассматриваются ключевые аспекты эффективного кэширования в Go:
- Планирование объёма памяти: важно заранее оценить, сколько данных будет кэшироваться, чтобы избежать переполнения памяти (OOM).
- Классификация данных: разделение данных на "горячие" и "холодные" помогает оптимизировать использование ресурсов, сохраняя часто используемые данные в быстром доступе, а редко используемые — на более экономичных носителях.
- Стратегии кэширования в распределённых системах:
- Использование распределённого кэша (например, Redis).
- Направление одинаковых запросов на один и тот же экземпляр приложения.
- Репликация кэша на каждом экземпляре приложения.
- Политики вытеснения: применение алгоритма LRU (Least Recently Used) помогает контролировать размер кэша, удаляя наименее используемые элементы.
Подробнее: https://dev.to/leapcell/caching-in-go-doing-it-right-25i5
🚀 Go — идеально подходит для AI-агентов
Агент дорогим в использовании (например, из-за использования LLM), и часто требует взаимодействия с пользователем или другими агентами.
⚙️ Преимущества Go для работы с агентами:
- Go позволяет запускать тысячи горутин с минимальными накладными расходами, что идеально подходит для масштабируемых агентных систем.
- Общение через каналы: Go поощряет передачу данных через каналы, что упрощает синхронизацию и уменьшает вероятность ошибок, связанных с общим доступом к памяти.
- Контекстное управление: Механизм context.Context в Go обеспечивает централизованное управление отменой операций, что особенно полезно для долгоживущих процессов.
- Богатая стандартная библиотека: Go предоставляет обширный набор инструментов для работы с сетью, JSON, криптографией и другими аспектами, необходимыми для разработки агентов.
- Профилирование: Инструменты, такие как pprof, позволяют эффективно отслеживать и устранять утечки памяти и горутин.
🙅 Минусы:
— Мало библиотек для ML
— Нет "магии" как у Python-экосистемы
Но если тебе важны надежность, скорость и контроль, Go — это отличный выбор 🔥
📖 Читать полностью
Агент дорогим в использовании (например, из-за использования LLM), и часто требует взаимодействия с пользователем или другими агентами.
⚙️ Преимущества Go для работы с агентами:
- Go позволяет запускать тысячи горутин с минимальными накладными расходами, что идеально подходит для масштабируемых агентных систем.
- Общение через каналы: Go поощряет передачу данных через каналы, что упрощает синхронизацию и уменьшает вероятность ошибок, связанных с общим доступом к памяти.
- Контекстное управление: Механизм context.Context в Go обеспечивает централизованное управление отменой операций, что особенно полезно для долгоживущих процессов.
- Богатая стандартная библиотека: Go предоставляет обширный набор инструментов для работы с сетью, JSON, криптографией и другими аспектами, необходимыми для разработки агентов.
- Профилирование: Инструменты, такие как pprof, позволяют эффективно отслеживать и устранять утечки памяти и горутин.
🙅 Минусы:
— Мало библиотек для ML
— Нет "магии" как у Python-экосистемы
Но если тебе важны надежность, скорость и контроль, Go — это отличный выбор 🔥
📖 Читать полностью
🌀 Middleware и RoundTripper в Go: гибкая обработка HTTP-запросов
В Go нет встроенного понятия "middleware", как в других фреймворках — но вы можете легко реализовать его сами, особенно в контексте
🔧 RoundTripper — это интерфейс, который обрабатывает HTTP-запросы на уровне клиента (`http.Client`). Это даёт возможность внедрять логику *до* и *после* отправки запроса.
🧱 Пример: логгер запросов
📦 Использование:
💡 Таким образом, вы можете создавать middleware прямо внутри
• логирование
• кэширование
• модификация заголовков
• retry-логика
• трейсинг
🔗 Подробнее: dev.to/calvinmclean/middleware-and-roundtrippers-in-go-30pa
#golang #httpclient #middleware #webdev #devtools
В Go нет встроенного понятия "middleware", как в других фреймворках — но вы можете легко реализовать его сами, особенно в контексте
http.RoundTripper
.🔧 RoundTripper — это интерфейс, который обрабатывает HTTP-запросы на уровне клиента (`http.Client`). Это даёт возможность внедрять логику *до* и *после* отправки запроса.
🧱 Пример: логгер запросов
type LoggingRoundTripper struct {
rt http.RoundTripper
}
func (l *LoggingRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
log.Printf("📤 Запрос: %s %s", req.Method, req.URL)
resp, err := l.rt.RoundTrip(req)
if err == nil {
log.Printf("📥 Ответ: %d", resp.StatusCode)
}
return resp, err
}
📦 Использование:
client := &http.Client{
Transport: &LoggingRoundTripper{rt: http.DefaultTransport},
}
💡 Таким образом, вы можете создавать middleware прямо внутри
http.Client
, например:• логирование
• кэширование
• модификация заголовков
• retry-логика
• трейсинг
🔗 Подробнее: dev.to/calvinmclean/middleware-and-roundtrippers-in-go-30pa
#golang #httpclient #middleware #webdev #devtools
This media is not supported in your browser
VIEW IN TELEGRAM
Раньше: многоэтапные собеседования и тестовые
Сейчас: возможность получить оффер за один день!
Сбер зовёт Go-разработчиков на One Day Offer — он пройдёт 21 июня в онлайн-формате. Команда ищет будущих коллег в рекламную платформу SberAds сразу в несколько продуктов:
— Медийная реклама
— Performance Ads
— Инструменты разработки
— RTS
Регистрируйтесь на One Day Offer и будьте готовы к карьерным изменениям и работой над действительно масштабными задачами!
Сейчас: возможность получить оффер за один день!
Сбер зовёт Go-разработчиков на One Day Offer — он пройдёт 21 июня в онлайн-формате. Команда ищет будущих коллег в рекламную платформу SberAds сразу в несколько продуктов:
— Медийная реклама
— Performance Ads
— Инструменты разработки
— RTS
Регистрируйтесь на One Day Offer и будьте готовы к карьерным изменениям и работой над действительно масштабными задачами!
Отличный технический гайд — как на языке Go реализовать свой инструмент для анализа разделов диска (аналог `fdisk -l`), работая напрямую с «сырыми» байтами.
📌 Что делает утилита:
• Считывает первые 512 байт с диска (MBR)
• Определяет тип таблицы разделов: MBR или GPT
• Парсит нужные структуры (MBRPartition, GPTHeader и др.)
• Выводит информацию о каждом разделе: смещение, размер, активность, тип, имя (для GPT)
🔧 Поддерживается два формата:
1. MBR (Master Boot Record)
• До 4 основных разделов
• Ограничение — 2 ТБ
• Таблица находится в первом секторе (512 байт)
• Каждая запись — 16 байт, с полями CHS, LBA, типом и флагами
• В конце сигнатура
0x55AA
2. GPT (GUID Partition Table)
• Современный стандарт с поддержкой >2 ТБ
• Использует специальные GUID-идентификаторы
• Поддерживает до 128 разделов
• Содержит основной и резервный заголовки + таблицу с метаданными и именами разделов в UTF‑16
📖 Примеры кода в Go:
• Структуры описаны через
struct
с бинарными полями • Используется
binary.Read
для чтения блоков • Есть вспомогательные функции для расшифровки типов и конвертации размеров
Выводит таблицу всех разделов, включая размер, активность, смещение и, при GPT, имя раздела.
💡 Почему это полезно:
• Позволяет лучше понять, как устроена разметка дисков
• Учит читать бинарные форматы и парсить их в Go
• Подходит для системного программирования, утилит, диагностики и низкоуровневой работы с железом
🧪 Автор также упоминает возможные улучшения:
• Проверка CRC
• Поддержка расширенных и логических разделов
• Чтение заголовков файловых систем
• Реализация в WebAssembly для запуска в браузере
📎 Читать
Please open Telegram to view this post
VIEW IN TELEGRAM
Пейзаж программирования продолжает развиваться: языки Rust и Go бросают вызов традиционным парадигмам и удовлетворяют высокие требования современности. Оба находят важные ниши благодаря эффективной работе на уровне системы и возможностям в конкуренции blog.jetbrains.com.
Согласно данным отчёта State of Developer Ecosystem за 2024 год, Rust установил рекорд популярности — 2,27 млн. пользователей, из которых 709 000 используют его как основной язык. Пользователей Go стабильно много, и каждый шестой сейчас задумывается о переходе на Rust blog.jetbrains.com.
Выбор между ними зависит от требований проекта — будь то производительность, удобство или конкуренция. Давайте разберём оба языка.
📌 Читать
Please open Telegram to view this post
VIEW IN TELEGRAM
⚙️ Написание собственного Load Balancer всего за 250 строк кода
В свежей статье на *Beyond the Syntax* Sushant Dhiman показывает, как создать HTTP‑балансировщик нагрузки с нуля, используя всего ~250 строк Go-кода!
👨💻 Что в статье:
- Простой балансировщик, который принимает HTTP-запросы и распределяет их на пул серверов.
- Поддержка алгоритма round‑robin.
- Health‑checks: временно убирает из пула серверы, которые не отвечают.
- Как добавлять и убирать бэкенды динамически.
- Версия с конкурентной обработкой запросов.
🧩 Почему это полезно:
- Понятный, минималистичный код — отлично подойдёт для учебы и практики.
- Пошагово объясняется каждый компонент: от приёма соединений до проверок здоровья серверов.
- Реализация буквально «на коленке», без сложных фреймворков.
🚀 Итог:
Учебный, но практичный пример, как за минимальными усилиями и строками кода получить работующий Layer‑7 балансировщик. Отлично для новичков и тех, кто хочет вникнуть «под капот» инфраструктуры.
🔗 Читайте статью
@golang_books
В свежей статье на *Beyond the Syntax* Sushant Dhiman показывает, как создать HTTP‑балансировщик нагрузки с нуля, используя всего ~250 строк Go-кода!
👨💻 Что в статье:
- Простой балансировщик, который принимает HTTP-запросы и распределяет их на пул серверов.
- Поддержка алгоритма round‑robin.
- Health‑checks: временно убирает из пула серверы, которые не отвечают.
- Как добавлять и убирать бэкенды динамически.
- Версия с конкурентной обработкой запросов.
🧩 Почему это полезно:
- Понятный, минималистичный код — отлично подойдёт для учебы и практики.
- Пошагово объясняется каждый компонент: от приёма соединений до проверок здоровья серверов.
- Реализация буквально «на коленке», без сложных фреймворков.
🚀 Итог:
Учебный, но практичный пример, как за минимальными усилиями и строками кода получить работующий Layer‑7 балансировщик. Отлично для новичков и тех, кто хочет вникнуть «под капот» инфраструктуры.
🔗 Читайте статью
@golang_books
♟️ Новая шахматная библиотека на Go — chess v2
Разработчик Brigham Skarda представил chess v2 — лёгкую и мощную библиотеку для работы с шахматами на языке Go.
📦 Что умеет:
• Валидация и исполнение ходов
• Поддержка PGN и FEN
• Расчёт состояния: шах, мат, пат, троекратное повторение
• Работа с произвольных позиций
🔧 Отличия версии v2:
• Переработанный API с акцентом на читаемость и безопасность
• Повышенная производительность
• Улучшенная архитектура — удобна для использования в ИИ, анализаторах партий и игровых движках
🚀 Отличный инструмент для тех, кто пишет:
• шахматные движки
• телеграм-ботов
• шахматные редакторы и визуализаторы
🔗 Статья: https://brighamskarda.com/articles/introducing_chess_v2_a_new_chess_library_in_golang
#golang #chess #opensource #gamedev #библиотекиGo
Разработчик Brigham Skarda представил chess v2 — лёгкую и мощную библиотеку для работы с шахматами на языке Go.
📦 Что умеет:
• Валидация и исполнение ходов
• Поддержка PGN и FEN
• Расчёт состояния: шах, мат, пат, троекратное повторение
• Работа с произвольных позиций
🔧 Отличия версии v2:
• Переработанный API с акцентом на читаемость и безопасность
• Повышенная производительность
• Улучшенная архитектура — удобна для использования в ИИ, анализаторах партий и игровых движках
🚀 Отличный инструмент для тех, кто пишет:
• шахматные движки
• телеграм-ботов
• шахматные редакторы и визуализаторы
🔗 Статья: https://brighamskarda.com/articles/introducing_chess_v2_a_new_chess_library_in_golang
#golang #chess #opensource #gamedev #библиотекиGo
VK Weekend Offer: отправьте заявку, пройдите интервью и получите офер!
28–29 июня VK проведёт Weekend Offer для бэкендеров с опытом от трёх лет. Участников со знанием Java, Go, Python или C++ ждут технические собеседования, знакомство с продуктами и, если всё сложится, офер уже в конце выходных.
Ребята много лет создают облачные решения, системы рекомендаций и поисковые движки — всё с миллионами пользователей в проде — и сейчас ищут новых коллег. Поэтому оставляйте заявку до 25 июня, чтобы попасть в команду за выходные!
Подробности — на сайте.
28–29 июня VK проведёт Weekend Offer для бэкендеров с опытом от трёх лет. Участников со знанием Java, Go, Python или C++ ждут технические собеседования, знакомство с продуктами и, если всё сложится, офер уже в конце выходных.
Ребята много лет создают облачные решения, системы рекомендаций и поисковые движки — всё с миллионами пользователей в проде — и сейчас ищут новых коллег. Поэтому оставляйте заявку до 25 июня, чтобы попасть в команду за выходные!
Подробности — на сайте.
📝 Trumbowyg: лёгкий WYSIWYG-редактор для веб-разработчиков
🚀 Основные преимущества
• Мини-размер: ~30 KB JS (10 KB gzip) — мгновенная загрузка
• Простая инициализация:
• Семантический HTML без «вредных» обёрток
• Богатый набор кнопок: жирный, курсив, списки, ссылки, вставка изображений и многое другое
• Кроссбраузерность: IE9+ и все современные браузеры
🎯 Установка и подключение
• Подключи jQuery и стили/скрипты Trumbowyg
• Инициализируй редактор с параметрами:
🛠 Плагины и расширяемость
• Более 35 официальных плагинов: таблицы, эмодзи, автосохранение, автоподгонка высоты, fullscreen и др.
• Подключи плагин — инициализируй сразу после основного скрипта:
⚙️ Кастомизация
• Настраиваемые тулбары: создавай свои группы кнопок
• Локализации на более чем 45 языков
• Собственные модальные окна:
🌐 Когда выбирать Trumbowyg
• Если важна скорость загрузки и простота
• Для админок, CMS и лёгких веб-приложений
• Когда нужен чистый семантический код и минимальные зависимости
🔗 Полезные ссылки
• Документация и демо: https://alex-d.github.io/Trumbowyg/
• Репозиторий GitHub: https://github.com/Alex-D/Trumbowyg
🚀 Основные преимущества
• Мини-размер: ~30 KB JS (10 KB gzip) — мгновенная загрузка
• Простая инициализация:
$('#editor').trumbowyg();
• Семантический HTML без «вредных» обёрток
• Богатый набор кнопок: жирный, курсив, списки, ссылки, вставка изображений и многое другое
• Кроссбраузерность: IE9+ и все современные браузеры
🎯 Установка и подключение
• Подключи jQuery и стили/скрипты Trumbowyg
<link rel="stylesheet" href="dist/ui/trumbowyg.min.css">
<script src="dist/trumbowyg.min.js"></script>
• Инициализируй редактор с параметрами:
$('#editor').trumbowyg({
btns: [
['strong','em'],
['link','insertImage'],
['unorderedList','orderedList']
],
autogrow: true
});
🛠 Плагины и расширяемость
• Более 35 официальных плагинов: таблицы, эмодзи, автосохранение, автоподгонка высоты, fullscreen и др.
• Подключи плагин — инициализируй сразу после основного скрипта:
$.trumbowyg.plugins.autosave = {
fn: {
init: function(t) { /* … */ }
}
};
$('#editor').trumbowyg({ plugins: { autosave: { delay: 5000 } } });
⚙️ Кастомизация
• Настраиваемые тулбары: создавай свои группы кнопок
• Локализации на более чем 45 языков
• Собственные модальные окна:
var $modal = $('#editor').trumbowyg('openModal', {
title: 'Моё окно',
content: '<p>Любой HTML</p>'
});
$modal.on('tbwconfirm', () => $('#editor').trumbowyg('closeModal'));
🌐 Когда выбирать Trumbowyg
• Если важна скорость загрузки и простота
• Для админок, CMS и лёгких веб-приложений
• Когда нужен чистый семантический код и минимальные зависимости
🔗 Полезные ссылки
• Документация и демо: https://alex-d.github.io/Trumbowyg/
• Репозиторий GitHub: https://github.com/Alex-D/Trumbowyg
📁 Go: быстрая обработка гигантских файлов
Подход к обработке огромных файлов (миллионы строк) в Go: быстро, параллельно и без лишнего потребления памяти.
🔧 Идея: pipeline с каналами и воркерами
1. Читаем файл по строкам через bufio.Scanner
2. Передаём строки в батчах (например, по 100 000) в канал
3. Несколько горутин-воркеров обрабатывают эти батчи
4. Объединяем результаты и записываем/анализируем дальше
💡 Результаты:
• Последовательная обработка занимала ~19 секунд
• Параллельная (10 воркеров + batch size 100 000) — ~9 секунд
• Потребление памяти остаётся стабильным, даже на файлах 20+ ГБ
🛠 Почему это эффективно:
• Каналы позволяют читать и обрабатывать одновременно
• Батчи уменьшают количество аллокаций
• Возможна повторная инициализация []string через sync.Pool
• GC остаётся под контролем — без резких пиков
✅ Подходит для:
• CSV, JSONL, логов, текстовых потоков
• ETL-пайплайнов: чтение → обработка → сохранение
• Стриминговой обработки в аналитике и ML
📌 Советы:
• Используй runtime.NumCPU() для адаптивного количества воркеров
• Подбирай batchSize экспериментально (10–100 тыс строк)
•
Читать
Подход к обработке огромных файлов (миллионы строк) в Go: быстро, параллельно и без лишнего потребления памяти.
🔧 Идея: pipeline с каналами и воркерами
1. Читаем файл по строкам через bufio.Scanner
2. Передаём строки в батчах (например, по 100 000) в канал
3. Несколько горутин-воркеров обрабатывают эти батчи
4. Объединяем результаты и записываем/анализируем дальше
💡 Результаты:
• Последовательная обработка занимала ~19 секунд
• Параллельная (10 воркеров + batch size 100 000) — ~9 секунд
• Потребление памяти остаётся стабильным, даже на файлах 20+ ГБ
🛠 Почему это эффективно:
• Каналы позволяют читать и обрабатывать одновременно
• Батчи уменьшают количество аллокаций
• Возможна повторная инициализация []string через sync.Pool
• GC остаётся под контролем — без резких пиков
✅ Подходит для:
• CSV, JSONL, логов, текстовых потоков
• ETL-пайплайнов: чтение → обработка → сохранение
• Стриминговой обработки в аналитике и ML
📌 Советы:
• Используй runtime.NumCPU() для адаптивного количества воркеров
• Подбирай batchSize экспериментально (10–100 тыс строк)
•
Читать