Обновить
64K+

Go *

Компилируемый, многопоточный язык программирования

172,43
Рейтинг
Сначала показывать
Порог рейтинга
Уровень сложности

HTTP-запрос закончился, а LLM ещё работает: как проектировать AI-задачи на Go

Уровень сложностиПростой
Время на прочтение13 мин
Охват и читатели5.5K

Обычный Go backend привык отменять работу вместе с HTTP-запросом. Но если пользователь закрыл вкладку посреди анализа документа, это ещё не означает, что LLM-провайдер прекратил генерацию и расходы. Разбираю, почему для длительных AI-операций недостаточно r.Context(), как организовать фоновые задачи на PostgreSQL и что делать с идемпотентностью, retry и повторными списаниями за API.

Читать далее

Новости

Как я решал leetcode задачу

Уровень сложностиПростой
Время на прочтение6 мин
Охват и читатели9.8K

Хочу поделиться личным опытом нестандартного решения одной конкретной задачи с leetcode на понимание backtracking алгоритма и немного порассуждать на тему современных собеседований.

Читать далее

Я написал 61 тест для AI-ментора. Потом выяснилось, что тестам тоже нельзя верить

Уровень сложностиСредний
Время на прочтение14 мин
Охват и читатели7.1K

Репетитора не нанимают по резюме. Ему дают тетрадь реального ученика и смотрят не на то, знает ли он ответ, а на то, где он остановится. Подскажет, в какой строке ошибка, или перепишет задачу за ученика? Скажет «не знаю, давай проверим» или уверенно додумает?

Месяц назад я встроил в свою учебную платформу AI-ментора: он видит уроки, прогресс студента и его последнюю попытку по заданию. Чтобы не выбирать модель и не править промпт по ощущениям, я собрал стенд из автоматических проверок и начал принимать решения по его цифрам.

Через неделю выяснилось, что стенд тоже ошибается. Он засчитывал оборванный ответ, пропускал готовое решение задания под другим именем переменной и валил правильный отказ. А ещё через неделю модель на стенде вела себя безупречно, а на проде на тот же класс вопросов - нет. Эта статья про то, как устроен стенд, что он помог решить, где он создавал ложную уверенность и что я в итоге перестал доверять модели совсем.

Где стенд врал

sync.Pool теряет то, что вы хотели сохранить, и держит то, что хотели выбросить

Уровень сложностиСложный
Время на прочтение11 мин
Охват и читатели7K

sync.Pool легко принять за простой способ снизить аллокации: бенчмарк показывает ускорение, код уезжает в прод — а там пул внезапно теряет нужные объекты и удерживает раздутые буферы. Разбираемся, как sync.Pool на самом деле взаимодействует с GC, почему синтетические тесты могут вводить в заблуждение и в каких условиях эта оптимизация действительно окупается.

Разобрать подводные камни

Go 1.25 сам читает лимит CPU, а automaxprocs молча это выключает

Уровень сложностиСложный
Время на прочтение8 мин
Охват и читатели5.6K

Обновили Go до 1.25 и оставили привычный automaxprocs? Пустой импорт теперь может отключить встроенное управление GOMAXPROCS и изменить поведение сервиса под CPU‑квотой. Разбираемся, как новый рантайм работает с cgroup, откуда берётся разница на дробных лимитах и что проверить перед удалением старой зависимости.

Проверить GOMAXPROCS

Почему JSON Schema не делает ответ LLM надёжным

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели5.2K

Structured output решает одну из самых раздражающих проблем LLM-интеграций: модель наконец стабильно возвращает данные в ожидаемом формате. Но валидный JSON ещё не означает правильные данные. Разбираю, где заканчиваются гарантии JSON Schema и как провести границу доверия между LLM и бизнес-логикой Go-сервиса.

Читать далее

LiveKit казался простым, пока не начал протухать токен

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели6.5K

Когда делаешь голосовой мессенджер на Go, React и LiveKit, медиасервер поначалу кажется самой простой частью: поднял комнату по документации, выдал токен — звук пошёл.

На практике всё упирается в протухание JWT. Ровно через полтора часа стрима клиент стабильно вылетал, терял демонстрацию экрана и камеру, а браузер наотрез отказывался перезапускать захват без прямого клика пользователя.

Вдобавок параллельный WebSocket жил своей жизнью: сокет моргнул — человека уже стёрли из списка участников, хотя в WebRTC он всё ещё спокойно говорит.

Ниже разбор того, как мы боролись с гонками таймеров в Go, почему второй клиент выбивал первый и ради чего пришлось залезть в приватные поля SDK LiveKit.

Читать далее

Дайте нормально поработать или я сделаю это сам

Уровень сложностиСредний
Время на прочтение11 мин
Охват и читатели6.8K

Получив на этот и остальные вопросы утвердительный ответ, я принял оффер. 

Каково же было мое удивление в первый день работы, когда мне дали RDP‑доступ к Windows‑тачке — вся работа организовывалась через нее. Маленькое отступление: последний раз я работал на Windows в 2011 году, еще на XP.

Для читателей (да и для меня в какой‑то момент) самым простым и логичным вариантом было бы продолжить поиск работы, но работа на непривычной для меня операционной системе по факту была единственным моментом, который показался неподходящим. После некоторых попыток обустроить быт, выяснилось, что даже WSL там сильно порезанный, с собственными репозиториями и старыми операционками. Естественно, с личных устройств до удаленной машины заблокировано примерно все.

Читать далее

Как я за полдня навайбкодил библиотеку на Go и почему потом всё-таки пришлось вчитываться в код

Уровень сложностиПростой
Время на прочтение8 мин
Охват и читатели8.9K

Опробовал вайб-кодинг, создав с помощью Antigravity рабочую библиотеку на Go для работы с конфигурацией разных форматов. Рассказываю про приколы работы с ИИ-агентами, возникшие в процессе создания проекта.

Читать далее

Как я писал расшифровщик записей, но в итоге получил бота для Яндекс.Телемост, с функциями, которые даже не снились

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели87K

Как расшифровщик созвонов на Go превратился в бота для Яндекс.Телемоста: сам заходит в звонок, пишет, ведёт заметки ИИ и принимает дозвон с телефона.

Читать далее

Утро без телефона: зачем я поставил рядом с кроватью матричный принтер

Уровень сложностиСредний
Время на прочтение17 мин
Охват и читатели18K

Я собрал будильник, который каждое утро печатает мне чек. Рядом с кроватью стоит матричный Star SP700, а за ним — старый Mac mini, сервер, несколько небольших сервисов и приложение для установки времени подъёма.

В назначенный момент принтер с характерным треском выдаёт первый чек и заодно будит меня. Немного позже появляется второй — уже с финальными данными о сне и восстановлении с фитнес-браслета.

Всё это началось с попытки перестать брать телефон сразу после пробуждения. Расскажу, как простая идея превратилась в маленькую домашнюю систему и что пришлось решить, чтобы она действительно работала каждое утро.

Читать далее

DBML Diagram для IntelliJ IDEA с офлайн превью и открытым исходным кодом

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели5.9K

Привет! На связи Boost for Java. Развиваем DBML Diagram — open source плагин для IntelliJ IDEA и других совместимых IDE на платформе IntelliJ. Он строит ER-диаграмму рядом с открытым .dbml-файлом: меняете описание таблиц и связей — превью обновляется прямо в редакторе. Построение диаграммы работает локально, без отправки схемы во внешний сервис.

В этой статье покажем возможности версии 0.1.0, пользу работы со схемами прямо в IntelliJ IDEA и устройство плагина. Отдельно расскажем о планах интеграции с dbdiagram.io для публикации локальных изменений в общую схему.

Проект открыт: будем рады предложениям, примерам проблемных схем и участию в разработке.

Плагин в JetBrains Marketplace · Исходный код на GitHub

Читать далее

DDNS для российских DNS-хостингов: почему не подошли готовые клиенты и что я написал взамен

Уровень сложностиСредний
Время на прочтение10 мин
Охват и читатели5.2K

Я проверил популярные DDNS-клиенты и почти не нашёл в них поддержки российских DNS-хостингов. Поэтому запись для домашнего сервера обычно обновляют самописным скриптом на curl, а такой скрипт ломается молча. Я разобрал API нескольких хостингов и написал на Go свой DDNS-демон, который учитывает их особенности.

В статье рассказываю, почему совет перенести зону в Cloudflare подходит российской аудитории с оговорками и что умеют готовые клиенты. Затем разбираю подводные камни API REG.RU, Selectel и Yandex Cloud, о которые спотыкаются самописные скрипты. В конце показываю, как устроен dnspatch и как запустить его в Docker за пару минут.

Читать далее

Ближайшие события

Продовый REPL: Yaegi поверх composition root

Уровень сложностиСредний
Время на прочтение26 мин
Охват и читатели4.4K

Консоль для прода на Go: отдельный процесс с тем же composition root, read-only по умолчанию и REPL на Yaegi

Читать далее

ч2: Разбор. Как мы закрывали утечку через tun0 в AmneziaVPN

Уровень сложностиСложный
Время на прочтение26 мин
Охват и читатели22K

Приложение, которое вы исключили из VPN на Android, может привязать сокет к tun0, пройти через ваш туннель и узнать адрес сервера. Летом мы взялись закрыть это в AmneziaVPN (issue #2457). Сама проверка в AmneziaWG уместилась в одну строчку цикла, который читает пакеты из tun:

if uidfilter.Supported && !device.tun.uidGate.AllowOutboundPacket(elem.packet, device) { continue }

Вокруг неё набралось полтысячи строк Go и столько же тестов, мост через JNI и три раунда ревью. В статье — почему ядро пропускает такие пакеты, почему «владелец неизвестен» у нас значит отказ, как одно приложение могло остановить весь туннель и какую ошибку мы нашли уже после ревью в собственном мосту. На телефоне с фильтром до сервера доходит 0 попыток обхода из 6, без него все 6. Но улучшать ещё есть что, и разбор мы пишем для двух целей: чтобы другим клиентам было проще закрыть ту же дыру и чтобы собрать критику. Если увидите у нас слабое место, напишите.

Читать далее

Зачем я добавил Go-сервис туда, где его не просили

Уровень сложностиСредний
Время на прочтение7 мин
Охват и читатели6.3K

Недавно мне дали тестовое задание на проектирование интеграции между 1С и Yandex 360. На первый взгляд задача выглядела достаточно прямолинейно: 1С формирует письмо, дальше его нужно передать в почтовую систему, отправить и получить информацию о результате. Но в исходном ТЗ не было отдельного сервиса на Go. Я добавил его сам.

И в этой статье хочу разобрать не столько само тестовое задание, сколько процесс принятия архитектурного решения: зачем вообще добавлять ещё один компонент и в какой момент он действительно оправдан. Потому что сделать архитектуру из нескольких сервисов несложно. Гораздо сложнее объяснить, зачем каждый из них нужен.

Читать далее

xk6-sip: проверка качества звука в нагрузочных и автоматизированных функциональных тестах VoIP/SIP

Уровень сложностиПростой
Время на прочтение13 мин
Охват и читатели8.1K

Разберём, как в xk6-sip, расширении нагрузочного инструмента k6 для тестирования VoIP/SIP-звонков, устроена проверка качества звука: запись звонка, оценка того, что услышал абонент, по эталону, и как это работает в функциональных тестах и под нагрузкой.

200 OK означает, что АТС соединила звонок, но не означает, что люди слышат друг друга. Исчерпанные порты медиасервера, ошибки NAT, перепутанные медиапотоки, транскодинг на пределе CPU дают звонок с успешной сигнализацией и тишиной, чужим голосом или хрипом в трубке. SIPp и большинство нагрузочных инструментов для телефонии проверяют сигнализацию, а RTP в лучшем случае считают пакетами. Для контакт-центра такой звонок — потерянный клиент, а в отчёте нагрузочного теста он зелёный.

В функциональных тестах телефонии эту проблему обычно решают эталонами: записывают, что должен услышать абонент в каждом кейсе, и сравнивают с записью звонка в CI. Подход рабочий, но эталон на каждый кейс нужно поддерживать, а под нагрузкой его не запустишь. В xk6-sip то же сравнение живёт прямо в скрипте k6 и работает на тысячах звонков.

В статье:

Читать далее

Разбор популярного тестового задания с упором на системный дизайн

Время на прочтение17 мин
Охват и читатели7.1K

Эта статья может быть полезна студентам и начинающим специалистам, занимающимся разработкой веб-сервисов. Примеры кода приводятся на языке Go, некоторые особенности языка программирования разъясняются сразу по месту использования. В статье рассматривается одно из довольно типичных тестовых заданий как на навыки программирования, так и на навыки системного дизайна. В жизни встречаются разные формулировки этого тестового задания, но общий шаблон как задачи, так и решения вы наверняка узнаете, если вам уже доводилось сталкиваться с подобным заданием или если оно попадется вам в будущем.

Читать далее

Guardrails для ИИ-агента на Go: от инструкций к автоматическим проверкам

Уровень сложностиСредний
Время на прочтение25 мин
Охват и читатели5.6K

Мы пишем инструкции и скиллы для ИИ-агентов, просим их проверять свою работу, запускаем отдельных агентов на код-ревью. Для важных изменений добавляем ещё одного проверяющего. Каждый такой запуск требует времени и токенов.

При этом замечание, которое агент нашёл однажды, он может пропустить при следующем ревью. Инструкцию можно дополнить, но проверяющему снова придётся прочитать код и решить, выполнено ли требование. Хочется сократить эту повторную работу и закрепить хотя бы часть требований проверками с явным критерием.

Например, если горутина должна завершаться после отмены операции, это поведение можно проверить тестом. Такой тест останется в проекте и будет проверять тот же сценарий при следующих изменениях. Агент сможет запустить его, получить диагностику и проверить исправление той же командой.

Такие автоматические проверки в этой статье я называю guardrails: они задают условия, которым должно соответствовать изменение кода перед принятием. Если проверка обнаруживает нарушение, изменение требует исправления.

В статье разберу, какие требования к Go-коду можно закрепить линтерами и тестами: от обработки ошибок до зависимостей между пакетами. Покажу, как убедиться, что проверка обнаруживает нужное нарушение, и что всё равно останется для ревью.

Статья рассчитана на Go-разработчиков, знакомых с тестами, контекстами, каналами и CI. Исходники, конфигурации и команды воспроизведения лежат в репозитории с примерами. Весь вывод команд получен на Go 1.27.1 и golangci-lint 2.13.2. Версии зафиксированы, чтобы у вас получился тот же вывод, что в статье.

Читать далее

Почему fallback между LLM может сломать семантику ответа

Уровень сложностиПростой
Время на прочтение7 мин
Охват и читатели6.5K

В обычном backend fallback обычно означает: тот же контракт, другой исполнитель. С LLM всё сложнее — резервная модель может вернуть валидный JSON, но изменить смысл результата. Разбираю, почему retry и fallback нужно разделять, как учитывать деградацию качества и когда честная ошибка лучше «успешного» ответа другой модели.

Читать далее
1
23 ...