🤯 QA в 2026 — это уже не «нажми кнопку»
Архитектура микросервисов, SQL, Kafka, логи, автотесты. Именно это работодатели хотят видеть сейчас — и слово «желательно» в вакансиях давно сменилось на «обязательно».
➡️ С чего начать без IT-бэкграунда
Спойлер:из бэка переход почти не требует усилий
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
Архитектура микросервисов, SQL, Kafka, логи, автотесты. Именно это работодатели хотят видеть сейчас — и слово «желательно» в вакансиях давно сменилось на «обязательно».
Спойлер:
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
😁4🤔1
В Go тип реализует интерфейс неявно, никаких
implements не нужно. Это элегантно, но создаёт тихую ловушку: вы думаете, что тип реализует интерфейс, но из-за несовпадения сигнатуры метода — не реализует. Узнаёте об этом только в рантайме, когда присвоение падает.Лечится одной строкой, которая ничего не стоит в рантайме:
var _ io.Reader = (*MyReader)(nil)
Что здесь происходит
Объявляется переменная типа
io.Reader, ей присваивается nil-указатель на MyReader, результат выбрасывается. Если *MyReader не реализует интерфейс, то компилятор отклонит код. Если реализует, то строка компилируется и не генерирует никакого кода.Такой же приём используется в стандартной библиотеке Go и в крупных open-source проектах.
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍26❤3
Gapcast — это инструмент для аудита WiFi-сетей: перехват пакетов, инъекции, Evil Twin с Captive Portal и оценка дистанции до точки доступа по RSSI. Написан на Go, лицензия GPL-2.0.
Что умеет
Сканирование 2.4 и 5 ГГц одновременно, запись в .pcap, восстановление данных из файла — в том числе от Wireshark. Deep Scan по одному BSSID проходит три фазы: определение канала, сбор пакетов, расчёт дистанции.
Установка
git clone https://github.com/ANDRVV/gapcast.git
cd gapcast && go build -buildvcs=false
./gapcast -i <interface>
Сканирование сетей:
# 2.4 ГГц
./gapcast -i wlan0
# 5 ГГц
./gapcast -i wlan0 -5g
# Оба диапазона + радар дистанции
./gapcast -i wlan0 -2.4+5g -radar
# Только точки доступа, без клиентов
./gapcast -i wlan0 -2.4+5g -beacon
# Долгое сканирование без пропуска неактивных устройств
./gapcast -i wlan0 -2.4+5g -d
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Markdown-CMS — это система управления контентом, где вместо базы данных и визуального редактора используются обычные .md файлы с текстом.
Foundry это свежий проект как раз про такой подход.
Пайплайн простой: конфиг → загрузка контента → граф сайта → маршруты → рендеринг → public/. Два графа в памяти: SiteGraph: документы, роуты, таксономии; и DependencyGraph для инкрементальных пересборок. При изменении файла пересобираются только затронутые страницы.
Что есть из коробки
Плагины с хуками на загрузку/сборку/раздачу, темы с layout-слотами, RSS и sitemap, импорт из WordPress и legacy-Markdown, JS SDK для фронтенда и админки. Валидация битых ссылок, осиротевших медиафайлов и дублирующихся URL — командой foundry validate.
Быстрый старт:
go install github.com/sphireinc/foundry/cmd/foundry@latest
foundry serve # dev-сервер с live reload
foundry build # статика в public/
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍2🤔1
Golang Developer, Middle+ — до 300 000 ₽, удаленно
Go-разработчик (Мониторинг) — до 585 000 ₽, удаленно по Москве
Бэкенд-разработчик (Storage) — до 500 000 ₽, в офисе/гибрид в Москве
#GoWork
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3
🛠 Go Fiber v3: как мигрировать с v2
Fiber v3 вышел в стабильный релиз. Если вы используете v2 в продакшене, вот что нужно знать перед миграцией и зачем она вообще нужна.
Что поменялось
Три изменения, которые влияют на код
1️⃣ fiber.Ctx теперь реализует context.Context
В v2 приходилось вызывать
2️⃣ Статика переехала в middleware
Метод
3️⃣ Изменился метод Listen
Метод
Как мигрировать
Команда Fiber выпустила CLI с встроенным инструментом миграции:
После запуска обязательно проверяйте весь diff вручную. Инструмент иногда меняет код, который к Fiber не относится.
Что ещё появилось в v3
Пакет
Нативная поддержка
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoToProduction
Fiber v3 вышел в стабильный релиз. Если вы используете v2 в продакшене, вот что нужно знать перед миграцией и зачем она вообще нужна.
Что поменялось
Три изменения, которые влияют на код
В v2 приходилось вызывать
c.UserContext(), чтобы передать контекст в стандартные библиотеки. В v3 fiber.Ctx удовлетворяет интерфейсу context.Context напрямую.// v2
ctx := c.UserContext()
rows, err := db.QueryContext(ctx, "SELECT ...")
// v3
rows, err := db.QueryContext(c, "SELECT ...")
Метод
app.Static() убран. Его функциональность перенесена в отдельный static middleware.// v2
app.Static("/", "./public")
// v3
import "github.com/gofiber/fiber/v3/middleware/static"
app.Use("/", static.New("./public"))
Метод
Listen объединён с конфигурацией. Настройки теперь передаются напрямую в вызов. Если у вас есть кастомная конфигурация запуска сервера, придётся поправить.Как мигрировать
Команда Fiber выпустила CLI с встроенным инструментом миграции:
go install github.com/gofiber/cli/fiber@latest
fiber migrate --to v3
После запуска обязательно проверяйте весь diff вручную. Инструмент иногда меняет код, который к Fiber не относится.
Что ещё появилось в v3
Drop() — тихий сброс соединения без ответа клиенту, удобно для DDoS-защиты.End() — немедленный сброс ответа.SendEarlyHints() — поддержка HTTP 103.Пакет
extractors с единым API для извлечения значений из заголовков, кук, query-параметров и форм. Раньше каждый middleware дублировал эту логику по-своему.RouteChain для Express-стиля объявления маршрутов. HEAD-маршруты теперь регистрируются автоматически для каждого GET.Нативная поддержка
context.Context убирает целый класс бойлерплейта. Основные breaking changes — это статика и конфигурация Listen, они чинятся быстро. Запустите CLI-инструмент, прогоните тесты, вручную проверьте diff.📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
❤10🔥5
Это не гипотетический сценарий, а реальный случай. Консьюмер запустился на три минуты позже, чем нужно, и этого хватило, чтобы брокер удалил все сообщения. Проводки не прошли, данные пропали.
Архитектор собрал 5 типичных ошибок при работе с Kafka, тех, что не проявляются сразу, а в самый неподходящий момент.
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11❤1
Сборщик мусора в Go потребляет два ресурса: память и CPU. Чтобы понять, как им управлять, разберём простую модель.
Память
GC нужно помнить две вещи: что осталось живым после прошлого цикла и что выделила программа с тех пор. Сложите эти два числа и получите размер кучи на момент следующего запуска GC.
CPU
Основная работа GC состоит в том, чтобы пройтись по всей живой памяти и пометить, что ещё нужно, а что можно выбросить. Чем больше живой памяти, тем дольше это занимает. Чем больше указателей и связанных списков, тем медленнее обход.
Компромисс на пальцах
Представьте уборщика в офисе. Убирается каждый час — мусора почти нет, но он постоянно мешает работать. Убирается раз в день — мусор накапливается, зато никто не отвлекается.
GC работает так же. Допустим, программа постоянно выделяет 10 МБ/с, а живая куча занимает 10 МБ.
GC запускается каждую секунду: успевает накопиться ещё 10 МБ, куча вырастает до 20 МБ, CPU-нагрузка составляет 10%.
GC запускается каждые 2 секунды: успевает накопиться 20 МБ, куча вырастает до 30 МБ, CPU-нагрузка падает до 5%.
Реже запускаем — меньше грузим CPU, но тратим больше памяти. Чаще запускаем — экономим память, но платим процессорным временем.
Это и есть главный компромисс GC: память vs CPU.
В Go частота запуска GC является единственным параметром, которым разработчик управляет напрямую. Всё остальное GC решает сам.
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10🔥2👏2🥱1
😱 Если ваш продукт не умеет отдавать данные в формате, понятном AI-агенту, то вас просто не существует
Скрипт не будет кликать по красивым кнопкам в браузере, он уйдёт к конкуренту с нормальным API. Перестроить архитектуру под машинных клиентов — это уже не хайп, а необходимое условие сохранения конкурентоспособности.
Как адаптировать продукт и не исчезнуть из выдачи:
— интегрировать
— научиться контролировать стоимость (лимиты, кэш, роутинг между моделями);
— настроить AgentOps: трейсинг, логирование и отлов регрессий.
Всё это ждёт вас на обновлённом курсе «Разработка AI-агентов». Мы специально сделали фокус на утилитарном инжиниринге и production-ready решениях.
Кстати, до 29 марта можно забрать курс с большой скидкой, и стоит поторопиться — мест на потоке всё меньше.
Зафиксировать цену и начать деплоить агентов без слива бюджета 👈
Скрипт не будет кликать по красивым кнопкам в браузере, он уйдёт к конкуренту с нормальным API. Перестроить архитектуру под машинных клиентов — это уже не хайп, а необходимое условие сохранения конкурентоспособности.
Как адаптировать продукт и не исчезнуть из выдачи:
— интегрировать
MCP и A2A-взаимодействие, чтобы агенты могли вас читать;— научиться контролировать стоимость (лимиты, кэш, роутинг между моделями);
— настроить AgentOps: трейсинг, логирование и отлов регрессий.
Всё это ждёт вас на обновлённом курсе «Разработка AI-агентов». Мы специально сделали фокус на утилитарном инжиниринге и production-ready решениях.
Кстати, до 29 марта можно забрать курс с большой скидкой, и стоит поторопиться — мест на потоке всё меньше.
Зафиксировать цену и начать деплоить агентов без слива бюджета 👈
🥱17😁3🤔2👍1
🔄 GoLand 2026.1 вышел
С пылу с жару — GoLand 2026.1. Несколько полезных обновлений для Go-разработчиков.
Синтаксические обновления для Go 1.26. IDE теперь сама находит устаревший код и предлагает перейти на новый синтаксис. Поддерживаются два паттерна: создание указателей через
Git worktrees. Теперь можно работать с несколькими ветками одновременно без переключения контекста. Удобно для hotfix-ов или когда AI-агенту нужна отдельная ветка.
Больше AI-агентов. Помимо Junie и Claude Agent, добавлена поддержка GitHub Copilot, Cursor и других агентов через Agent Client Protocol (ACP). Устанавливаются в один клик через новый ACP Agent Registry.
Terraform Stacks. Базовая поддержка работы со стеками прямо в IDE: навигация по компонентам, автодополнение, создание деплойментов.
Wayland по умолчанию на Linux. Улучшены рендеринг и обработка ввода. Если Wayland недоступен, IDE автоматически переходит на X11.
Code With Me уходит. Начиная с 2026.1 плагин исключён из поставки IDE. Он доступен в JetBrains Marketplace как отдельный плагин, но 2026.1 станет последней версией с официальной поддержкой сервиса.
➡️ Источник
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoLive
С пылу с жару — GoLand 2026.1. Несколько полезных обновлений для Go-разработчиков.
Синтаксические обновления для Go 1.26. IDE теперь сама находит устаревший код и предлагает перейти на новый синтаксис. Поддерживаются два паттерна: создание указателей через
new() и типобезопасное разворачивание ошибок через errors.AsType. Применить изменения можно сразу по всему проекту через меню Refactor → Update Syntax или через Search Everywhere. Перед применением показывается diff-превью каждого изменения.Git worktrees. Теперь можно работать с несколькими ветками одновременно без переключения контекста. Удобно для hotfix-ов или когда AI-агенту нужна отдельная ветка.
Больше AI-агентов. Помимо Junie и Claude Agent, добавлена поддержка GitHub Copilot, Cursor и других агентов через Agent Client Protocol (ACP). Устанавливаются в один клик через новый ACP Agent Registry.
Terraform Stacks. Базовая поддержка работы со стеками прямо в IDE: навигация по компонентам, автодополнение, создание деплойментов.
Wayland по умолчанию на Linux. Улучшены рендеринг и обработка ввода. Если Wayland недоступен, IDE автоматически переходит на X11.
Code With Me уходит. Начиная с 2026.1 плагин исключён из поставки IDE. Он доступен в JetBrains Marketplace как отдельный плагин, но 2026.1 станет последней версией с официальной поддержкой сервиса.
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13🥱3👍1
Есть парсер логов. Работает месяцами. Однажды в лог прилетает одна аномальная строка: 100 КБ без символа переноса.
bufio.Scanner читает файл в цикле. Программа не паникует, не выбрасывает ошибку в stderr, не зависает. Просто эта строка не попадает в обработку. По умолчанию
Scanner не обработает токен длиннее bufio.MaxScanTokenSize, но какое ожидаемое поведение при переполнении?📍 Навигация: Вакансии • Задачи • Собесы
#ReadySetGo
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2
В Go 1.21 вывод типов заметно улучшился: компилятор научился автоматически подбирать типовые параметры дженерик-функции, когда она используется в присваивании или возвращается из другой функции. Но, как оказалось, это работало не везде одинаково.
Но, присваивание дженерик-функции полю структуры через
= компилятор обрабатывает корректно, а то же самое через литерал структуры нет.Вот конкретный пример:
type S struct{ f func(int) }
func g[T any](T) {}
func _(s S) {
s.f = g // ok
s = S{f: g} // error: cannot use generic function g without instantiation
s = S{f: g[int]} // ok — но зачем, если тип и так известен?
}То же самое касается элементов массивов, слайсов, мап и отправки в каналы — паттерн одинаковый: через индекс работает, через литерал — нет.
Во всех этих случаях тип левой стороны присваивания полностью известен во время компиляции, так что вывод типового параметра однозначен. Отсутствие вывода это неожиданное поведение, заставляющее разработчика писать лишний шум вроде
g[int] там, где он очевиден.📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤3
Разработчик сравнил практически все распространённые подходы к конкатенации строк в Go и прогнал их через бенчмарки. Два сценария: фиксированное число аргументов (например, сборка cache key) и переменное (динамические SQL-условия и т.п.).
Что тестировалось
+, +=, fmt.Sprintf, fmt.Sprint, strings.Join, bytes.Buffer, strings.Builder — последние два с предварительной аллокацией через .Grow() и без.Фиксированные аргументы
В сценарии с фиксированным числом аргументов победителем оказался
strings.Builder с предварительной аллокацией, следом + оператор и strings.Join. Все трое с минимальным числом аллокаций и низким потреблением памяти. Проще говоря, привычный + здесь вполне нормален и не нужно его усложнять.// Просто и быстро для фиксированных аргументов
func BuildCacheKey(id, name, region string) string {
return id + "#" + name + "#" + region
}
Переменные аргументы
При переменном числе аргументов лидируют
strings.Builder с .Grow() и strings.Join — оба показали одинаково хорошие результаты по времени, памяти и числу аллокаций. += в цикле оказался катастрофически медленным: на 256 аргументах он требует 255 аллокаций против 1 у Join.// Плохо: O(n) аллокаций
func bad(ss []string) string {
result := ss[0]
for _, s := range ss[1:] {
result += "#" + s // новая аллокация на каждой итерации
}
return result
}
// Хорошо: 1 аллокация
func good(ss []string) string {
return strings.Join(ss, "#")
}
// Хорошо: 1 аллокация, максимум скорости
func best(ss []string) string {
var length int
for _, s := range ss {
length += len(s) + 1
}
var b strings.Builder
b.Grow(length)
b.WriteString(ss[0])
for _, s := range ss[1:] {
b.WriteString("#")
b.WriteString(s)
}
return b.String()
}
Практические рекомендации:
- Фиксированное число строк → просто
+, не думайте об этом- Переменное число строк →
strings.Join как дефолт, strings.Builder + .Grow() если критична производительность-
fmt.Sprintf / fmt.Sprint → только для форматирования, не для конкатенации-
bytes.Buffer → медленнее strings.Builder почти везде, смысла нет-
+= в цикле → никогдаfmt.Sprintf медленнее всех в фиксированном сценарии, а strings.Join оказался неожиданно быстрым. Сам автор признаётся, что использовал Sprintf по привычке из-за удобной форматной строки — и зря.Ничего революционного, но полезно иметь под рукой как шпаргалку, когда кто-то в ревью спрашивает «а почему не Sprintf?».
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
❤17👍8🔥1
📰 Дайджест материалов
Последний дайджест марта.
— QA в 2026 это уже не просто
— Markdown-CMS на Go без базы данных
— Миграция на Fiber v3
— Kafka выстрелила в прод в 7 утра
— GoLand 2026.1
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoLive
Последний дайджест марта.
— QA в 2026 это уже не просто
— Markdown-CMS на Go без базы данных
— Миграция на Fiber v3
— Kafka выстрелила в прод в 7 утра
— GoLand 2026.1
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔1👾1
🐳 Плавающие теги в Docker
Большинство Dockerfile выглядят примерно так:
Решение:
Digest это SHA256 конкретного слоя образа. Он не меняется. Ваш билд от сегодня и билд через полгода используют буквально один и тот же образ.
Получить digest просто:
Как получать обновления безопасности
Тут в игру входят Dependabot и Renovate: они автоматически обновят digest в вашем Dockerfile и откроют PR. Вы видите, что именно изменилось, и сами решаете, мержить или нет.
Добавьте в
Добавьте
После этого обновления приходят сами в виде PR с понятным ченджлогом.
Тег говорит «примерно вот это», digest говорит «именно вот это».
📍 Навигация: Вакансии • Задачи • Собесы
🐸 Библиотека Go-разработчика
#GoDeep
Большинство Dockerfile выглядят примерно так:
FROM golang:1.26.1-alpine
golang:1.26.1-alpine это плавающий тег. Каждый раз, когда upstream обновляет образ: патч безопасности, замена библиотеки, изменение поведения, ваш следующий билд молча подтягивает новую версию. Вы ничего не меняли, а билд сломался.Решение:
# Было
FROM golang:1.26.1-alpine
# Стало
FROM golang:1.26.1-alpine3.20@sha256:a1b2c3d4e5f6...
Digest это SHA256 конкретного слоя образа. Он не меняется. Ваш билд от сегодня и билд через полгода используют буквально один и тот же образ.
Получить digest просто:
docker pull golang:1.26.1-alpine
docker inspect --format='{{index .RepoDigests 0}}' golang:1.26.1-alpine
Как получать обновления безопасности
Тут в игру входят Dependabot и Renovate: они автоматически обновят digest в вашем Dockerfile и откроют PR. Вы видите, что именно изменилось, и сами решаете, мержить или нет.
Добавьте в
.github/dependabot.yml:version: 2
updates:
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
Добавьте
renovate.json в корень репозитория:{
"extends": ["config:base"],
"docker": {
"pinDigests": true
}
}После этого обновления приходят сами в виде PR с понятным ченджлогом.
Тег говорит «примерно вот это», digest говорит «именно вот это».
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤6
YottaDB это key-value база данных с ACID-транзакциями. YDBGo её официальная Go-обёртка. Вышла вторая версия, посмотрим что поменялось.
Что было не так с v1
v1 имел два API — SimpleAPI и EasyAPI — оба многословные, с неудобными сигнатурами. Каждый вызов требовал передавать
tptoken и errstr, вручную вызывать Alloc и Free, и писать обработку ошибок после каждой операции. Вот как выглядело простое чтение значения:// v1 EasyAPI
x, err := ValE(tptoken, &errstr, varname, subsarray)
if err != nil { ... }
// v2
x := n.Get()
Что изменилось в v2
Центральная идея это доступ к базе через экземпляры
*Conn и *Node. Создаёте соединение, создаёте узел, работаете с ним:db := yottadb.MustInit()
defer yottadb.Shutdown(db)
conn := yottadb.NewConn()
n := conn.Node("varname", "sub1", "sub2")
n.Set("hello")
x := n.Get()
n.Kill()
tptoken и errstr больше нигде не передаются — они хранятся внутри Conn. Буферы освобождаются автоматически через GC — Alloc/Free ушли.Итерация раньше её не было вовсе, нужно было вручную вызывать
SubNextE. Теперь:for node := range n.Children() {
println(node)
}
for node := range n.Tree() {
println(node)
}Транзакции стали лаконичнее:
conn.Transaction("BATCH", nil, func() {
n.Set(value)
})Вызов M-кода из Go:
// v1 — 6 строк с проверками ошибок
// v2
table := conn.MustImport("calltab.ci")
retval := table.Call("mfunc", "param1", 2, 3)
Производительность
v2 быстрее v1 за счёт снижения числа аллокаций.
Node переиспользует буферы при итерации через Index() вместо создания нового объекта на каждый шаг. Конкретные цифры: базовые операции быстрее EasyAPI в 4–7 раз, SimpleAPI — на 1–4%.v1 продолжает поддерживаться, v1 и v2 можно использовать в одном приложении одновременно. Для постепенного перехода — есть таблица соответствия синтаксиса в официальном блоге и диффы реальных миграций.
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍2
❤1
Вышел Neovim 0.12.0. Разбираем главное.
LSP
Добавлено много новых возможностей:
•
textDocument/inlineCompletion — inline-подсказки прямо в редакторе•
textDocument/linkedEditingRange — одновременное редактирование связанных символов, например, открывающий и закрывающий HTML-тег•
textDocument/onTypeFormatting — форматирование во время набора•
textDocument/selectionRange — инкрементальное выделение: v_an расширяет выделение, v_in сужает•
textDocument/documentColor + colorPresentation — предпросмотр цветов прямо в буфере• Переработан
codeLens — теперь отображается как виртуальные строки• Новая команда
:lsp для интерактивного управления LSP-клиентами•
DiagnosticRelatedInformation теперь видна в vim.diagnostic.open_float(), а gf прыгает к проблемному месту•
vim.lsp.buf.rename() подсвечивает переименовываемый символ через hl-LspReferenceTargetНовые команды и плагины
•
:DiffTool — сравнение директорий и файлов•
:Undotree — визуальный навигатор по дереву отмен•
:iput — вставка с автовыравниванием отступа•
:uniq — дедупликация строк в буфере•
:restart — перезапуск Nvim с переподключением текущего UI•
:connect — динамическое подключение UI к серверу•
:wall ++p — автоматически создаёт отсутствующие родительские директории•
gx в help-буферах теперь открывает онлайн-документацию по тегу под курсоромНовые опции
•
autocomplete — включает встроенное автодополнение при наборе•
pumborder — рамка вокруг popup-меню завершения•
winborder — кастомный стиль рамки окна, включая "bold"•
diffop' теперь включает "indent-heuristic" и "inline:char" по умолчанию•
maxsearchcoun' — максимум для searchcount(), по умолчанию 999•
busy — статус «занятости» буфера, отображается в статусной строке символом ◐•
pummaxwidth — максимальная ширина popup-меню завершения•
fillchars получил новый флаг "foldinner"•
listchars получил новый флаг "leadtab"Производительность
•
Ctrl-R для вставки из регистров стал в 10 раз быстрее — теперь работает как paste, а не как ввод пользователя•
vim.glob.to_lpeg() — новая реализация на LPeg, ~50% быстрее для сложных паттернов• LSP semantic tokens теперь запрашиваются только для видимой области экрана (
textDocument/semanticTokens/range) — меньше трафика, быстрее отклик•
:packadd больше не инвалидирует кэш Lua-путей — значительный выигрыш при старте для конфигов с множеством :packadd📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
❤🔥11🔥9❤2🤔2
Правильный порядок слоёв в Dockerfile решает половину проблемы.
go mod download не перезапускается, если go.mod не менялся, то это знают все. Но стоит обновить любую зависимость, даже патч-версию, и Docker пересобирает слой с нуля: скачивает все модули заново, прогоняет полную компиляцию.BuildKit решает через постоянный кэш, который живёт между билдами независимо от слоёв.
Как это работает:
# syntax=docker/dockerfile:1
FROM golang:1.26.1-alpine AS builder
WORKDIR /build
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/go/pkg/mod \
go mod download
COPY . .
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
CGO_ENABLED=0 GOOS=linux go build -o /app ./cmd/server
/go/pkg/mod это кэш скачанных модулей. Если пакет уже был загружен в предыдущем билде, он не качается снова даже если слой инвалидирован./root/.cache/go-build это кэш компилятора Go. Файлы, которые не изменились с прошлой сборки, не перекомпилируются. Именно это даёт наибольший выигрыш при инкрементальных изменениях кода.Mount-кэш не попадает в финальный образ. Это не слой, а временная точка монтирования, которая существует только во время RUN. Размер образа не растёт, данные не утекают в прод.
В новых версиях Docker BuildKit включён по умолчанию. Если нет, то включить можно двумя способами:
# Переменная окружения
DOCKER_BUILDKIT=1 docker build .
# Или в /etc/docker/daemon.json
{ "features": { "buildkit": true } }
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤1