Дан массив нулей и единиц, нужно проверить, что между любыми двумя единицами находится минимум k нулей. Звучит элементарно, но в реализации легко споткнуться.
Массив [1,0,0,0,1,0,0,1] при k=2 валиден: между первой и второй единицей три нуля (достаточно), между второй и третьей — два нуля (достаточно). А вот [1,0,1,0,0,1] при k=2 — нет, потому что первые две единицы разделены только одним нулём.
Запоминаем позицию последней найденной единицы. Когда встречаем новую, проверяем расстояние до неё и сразу обновляем позицию.
Это будет один проход по массиву:
func kLengthApart(nums []int, k int) bool {
lastPos := -k - 1
for i := 0; i < len(nums); i++ {
if nums[i] == 1 {
if i - lastPos - 1 < k {
return false
}
lastPos = i
}
}
return true
}
Результат: O(n) время, O(1) память.
📍 Навигация: Вакансии • Задачи • Собесы
#ReadySetGo
Please open Telegram to view this post
VIEW IN TELEGRAM
1❤6👾4👍1💯1
Нужны шаблоны, миграции или небольшая статика, но не хочется таскать их рядом с бинарником?
import "embed"
//go:embed templates/*.html
var templatesFS embed.FS
Дальше embed.FS можно использовать с html/template, text/template или net/http.
templates.ParseFS(templatesFS, "templates/*.html»)
Можно вшить и отдельный файл:
//go:embed version.txt
var version string
Для шаблонов, миграций и небольшой статики — отличный вариант. Для огромных ассетов — уже стоит подумать о другом подходе.
🔗 Документация
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤩3❤🔥1🥱1
Если fmt.Println уже кажется слишком скучным, посмотрите на экосистему Charm
Например, меню выбора в bash:
gum choose "deploy" "rollback" "cancel"
А если хочется написать полноценный терминальный интерфейс — можно собрать его на Bubble Tea.
📍 Навигация: Вакансии • Задачи • Собесы
Please open Telegram to view this post
VIEW IN TELEGRAM
❤11🥰3😍2👍1🙏1
Для тех, кто занимается разработкой текстовых интерфейсов на Go, есть интересный инструмент — библиотека sysc-Go.
В библиотеке доступны разные категории эффектов: от классического цифрового дождя в стиле «Матрицы» и пламени Doom до красочных фейерверков и подводных анимаций с рыбой.
Есть и текстовые эффекты, которые оживляют ASCII-арт — например, огненный текст, эффекты типографики с имитацией печатной машинки или вращающиеся кольцевые анимации.
Чистая реализация на Go без зависимостей, удобный CLI-интерфейс с выбором и просмотром всех доступных эффектов, а также встроенный ASCII-редактор с живым предпросмотром.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👾5😁1🤩1💯1
До Go 1.25 рантайм ориентировался на CPU всей машины. Поэтому pod с лимитом в 2 CPU на 64-ядерной ноде мог получить GOMAXPROCS=64.
Linux при превышении CPU limit начинал throttling — процесс мог полностью приостанавливаться на оставшуюся часть периода. Это особенно неприятно для tail latency.
runtime.GOMAXPROCS(0)
Например, pod с лимитом в 2 CPU → GOMAXPROCS будет 2. Значение также периодически пересчитывается, если cgroup limit меняется.
⚠️ Но есть ловушка: если вы вручную задаёте GOMAXPROCS через env или:
runtime.GOMAXPROCS(8)
автоматическая настройка отключается.
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👏3👾3😢1
19 августа вышел Go 1.27 — и по политике Go поддерживаемыми теперь остаются только 1.27 и 1.26.
Если проект всё ещё собирается на 1.25, это хороший момент для обновления. Для тех, кто пока не готов переходить на 1.27, есть актуальная ветка 1.26 с патч-релизом 1.26.7.
Проверить зависимости на известные уязвимости можно через:
govulncheck ./…
А заодно стоит посмотреть на изменения в encoding/json: в Go 1.27 появился новый encoding/json/v2, а старый пакет теперь работает поверх его реализации.
📍 Навигация: Вакансии • Задачи • Собесы
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8😢3
This media is not supported in your browser
VIEW IN TELEGRAM
html/template работает со строковыми шаблонами, а templ позволяет писать HTML-компоненты прямо в .templ и превращать их в обычный Go-код.
templ Hello(name string) {
<div class="greeting">Привет, { name }</div>
}
После templ generate компонент можно использовать как обычную функцию:
view.Hello("гофер").Render(ctx, w)
Особенно удобно для серверного рендеринга и связки Go + htmx, когда полноценный frontend-фреймворк не нужен.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6❤5
Подняли тестовую БД, создали временный файл или запустили сервер? t.Cleanup позволяет привязать очистку прямо к жизненному циклу теста.
func newTestDB(t *testing.T) *sql.DB {
t.Helper()
db := openTempDB(t)
t.Cleanup(func() {
db.Close()
})
return db
}
func TestUsers(t *testing.T) {
db := newTestDB(t)
// ...
}
Cleanup выполнится после завершения теста, даже если тот упал через t.Fatal. Несколько cleanup-функций выполняются в обратном порядке регистрации.
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14⚡1👾1
Обычная история: есть функция и десять сценариев. Если писать по тесту на каждый сценарий, код быстро превращается в копипасту. Table driven подход делает один тест, а сценарии складывает в таблицу.
Вы описываете кейсы в таблице, обычно это слайс структур. Потом в цикле запускаете каждый кейс как сабтест через t.Run, чтобы у каждого сценария было имя и его можно было запустить отдельно.
func Split(s, sep string) []string {
return strings.Split(s, sep)
}
func TestSplit(t *testing.T) {
tests := []struct {
name string
input string
sep string
want []string
}{
{name: "simple", input: "a/b/c", sep: "/", want: []string{"a", "b", "c"}},
{name: "no sep", input: "abc", sep: "/", want: []string{"abc"}},
{name: "trailing", input: "a/b/c/", sep: "/", want: []string{"a", "b", "c", ""}},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
got := Split(tc.input, tc.sep)
if !reflect.DeepEqual(got, tc.want) {
t.Fatalf("want %v got %v", tc.want, got)
}
})
}
}
Еще мелочь, но полезная. Внутри сабтеста t.Fatal завершает только текущий сабтест, а не весь набор, поэтому для table driven тестов это часто удобнее чем тянуть continue и пачку if.
📍 Навигация: Вакансии • Задачи • Собесы
#GoDeep
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2❤1
API старого encoding/json остался прежним, но под капотом теперь работает новый движок encoding/json/v2. Для существующего кода это должно быть прозрачно — Go сохраняет старую семантику через набор compatibility-опций.
Но производительность изменилась.
В независимом бенчмарке на одинаковых данных:
🔘 Unmarshal в структуру — примерно в 1,5 раза быстрее;🔘 Unmarshal в any — примерно в 1,5 раза медленнее;🔘 Marshal — немного медленнее, зато заметно меньше аллокаций;🔘 потоковая работа через новый API MarshalWrite требует значительно меньше памяти.
Самая интересная ловушка — any. Старый API разрешает дубликаты ключей JSON, поэтому новый движок не может использовать свой быстрый путь для any. В результате динамический JSON может обрабатываться медленнее.
После перехода на Go 1.27 недостаточно проверить только компиляцию. Если encoding/json находится на горячем пути — стоит прогнать свои бенчмарки. Особенно если приложение активно работает с any или map[string]any.
А encoding/json/v2 уже можно внедрять постепенно, сохраняя нужные v1-семантики через DefaultOptionsV1().
#GoLive
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍3
С Go часто делают так: выбрали версию, прописали её в Dockerfile — и вспоминаем о ней только при следующем большом обновлении. Но security-патчи выходят внутри той же ветки. И если ваша версия старая, опубликованная уязвимость превращает её в известную цель.
Что стоит сделать:
— закрепить конкретный toolchain в go.mod;
— регулярно пересобирать Docker-образ;
— следить за security-анонсами Go;
— проверять зависимости через govulncheck.
Например:
toolchain go1.26.6
А CI может брать версию прямо из go.mod:
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
📍 Навигация: Вакансии • Задачи • Собесы
#GoToProduction
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8