Читать в телеге. Когда-то там были посты не только от меня.
Степень влияния задержки на пользовательский опыт
Неплохая статья (хоть и с всратыми картинками) про то, как воспринимается время с точки зрения типичных пользователей:
TLDR:
- 0.1 с — “мгновенный ответ”, “это сделал я” (печатаю символ)
- 1 с — максимальное время без потери фокуса (предпочтительное время загрузки веб-страницы), “это сделал комп”
- 10 с — нет сил ждать, время смотреть тик-токи и подумать о чем-нибудь другом
- 1 м — если неинтересно, то пока
- 1 д — оптимальное время ответа от техподдержки, ежедневная рутина
- 1 неделя — если пользователь посещает сайт раз в неделю, то это можно назвать привычкой
- 1 месяц — время решения в B2B процессах
- 1 год — время, за которое можно стать “продвинутым пользователем”
- 10 лет — время изменения орг структуры/процессов большой компании
- 100 лет — время для перемен в обществе (эээ, сомнительно, но ладно)
Впечатления от Cursor
На прошлой неделе потыкали с коллегами палкой в Cursor, который AI агент и кодит за вас. Мы попытались пофиксить относительно мелкий баг (отсутствие валидации пользовательского ввода у одного из эндпоинтов) в реальном приложении, которое уже несколько лет в проде. Написано оно на Scala + Play (что может дать представление как и о его почтенном возрасте, так и о степени легаси).
Мы открыли проект, дали агенту лог с ошибкой от невалидного ввода и попросили Cursor sanitize input
. Он изменил глобальный обработчик ошибок контроллеров, по сути добавив try-catch. Попросили исправить ошибку собственно в контроллере, но не сказали, в каком. ИИ нашел похожую ошибку в другом эндпоинте, но мы решили в рамках эксперимента закрыть на это глаза и продолжить.
Что хуже, обработка была заточена под конкретный пример неправильного ввода. Промт важен: мы уточнили, что надо именно validate
. ИИ использовал херовую регулярку (даже если проигнорировать контекст/инварианты). После пары итераций с доведением ее до уровня “и так сойдет”, попросили добавить валидацию для всех эндпоинтов с таким же параметром. Cursor сделал отдельный статический класс валидатора и добавил его вызов в паре контроллеров (но точно не везде, где было нужно). Решение в итоге получилось хреновым, код тоже был не супер, но по виду это должно было худо-бедно работать.
Далее мы попросили ИИ добавить тесты. Он что-то нагенерировал, но проект в итоге даже не скомпилировался из-за отсутствующих импортов. Понадобилось 3 промпта, чтобы исправить ошибки компиляции.
Наконец, запустили тесты и получили ошибки. И после этого агент резко сдулся. В тестах были проблемами с ассертами и моками, и Cursor не смог их сам исправить даже после 30 итераций “запусти тесты и поправь ошибки”. Мы даже пробили максимальный лимит на количество запущенных команд от одного промпта (25). Мы давали небольшие подсказки, предлагали решать проблемы по порядку и т.п., но ИИ не смог побороть тесты. В то время как продакшн-код был написан за полчаса, с тестами провозились больше часа и в итоге бросили.
Посмотрев на изменения, обнаружили, что ИИ в процессе добавил новый эндпоинт, хотя его никто не просил. Попросили по приколу Copilot отревьюить PR — но он не смог, потому что не знает скалу:) Мержить PR не стали — проще с нуля сделать, чем править.
В итоге впечатления похожи на те, что я писал ранее (1, 2, 3): можно использовать как помощь для рутины и грязной работы, но если ИИ застрял, то проще сделать самому. Одно из полезных открытий — если давать ИИ наводки типа “залогируй параметры, чтобы лучше понять ошибку”, то он чуть лучше работает. Не исключено, что ИИ испытывал трудности из-за стека технологий, но сомнительно, что для какого-нибудь JS были бы кардинально другие впечатления.
С точки зрения самого Cursor: есть прикольная фича, что можно заставить ИИ править код, пока не пройдут тесты, но разумеется, это не поможет, если ИИ тупит или ходит по кругу. Был еще один мелкий баг: если использовать режим “ask”, итеративно дорабатывать решение и затем применить его, код может оказаться в неконсистентном состоянии – например, в какой-то момент ИИ добавил приватный метод, который нигде не вызывался, хотя в его первом ответе вызов был.
В общем процесс ощущался как общение с гиперактивным, быстрым, не очень опытным, а иногда и очень тупым джуном.
P.S. P.S. На следующий день на HN в топе попался сборник проблем кодинга с AI и коллеги вбросили эту статью — там все в целом по делу.
Эволюция user agent
Занятная и в то же время печальная история про то, как менялся user agent у популярных браузеров, и как родился монструозный Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
.
Как починить билд Gradle
У Gradle куча разных кэшей и, увы, изредка может получится так, что в них будет записано некорректное состояние. Если есть подозрения, что это действительно так, можно попробовать перезапустить билд…
- с флагом
--rerun-tasks
- с
--no-configuration-cache
- с
--no-build-cache
- после
clean
- с чистой домашней папкой Gradle:
--gradle-user-home ./gradle_home
- после убийства всех демонов Gradle (по идее то же самое что и выше, но стоит попробовать)
- после рестарта IDE, если вызываете билд из нее.
Если вышеперечисленное не помогло, то скорее всего проблема где-то в билд-логике и/или окружении.
16 оттенков локов Postgres
У Postgres отличные доки. Например, достаточно одной странички, чтобы узнать большую часть необходимой информации, которую нужно знать про виды локов в БД.
Частичная автоматизация как интерактивная инструкция
Хорошая статья про неплохую идею: вместо того, чтобы убиваться со 100% автоматизацией, можно просто сделать вспомогательный скрипт-инструкцию к процессу: делай раз, делай два и т.д. Подход встречал на практике, особенно хорошо подходит всяким сисадминам, извините, девопсам: полная автоматизация потребует решить кучу приколов с выдачей доступов/убогими API, а подобный промежуточный вариант позволит относительно дешево ускорить/систематизировать некоторые процессы.
Обедающие философы
На выходных чисто ради освежения памяти решил накодить обедающих философов. Вроде задачка из учебника (про дедлоки, если кто не помнит), миллион раз обсужденная в литературе, блогах и т.п., должно быть приключение на 20 минут, да? Читаешь описание задачи, описание проблем и решения — вроде все просто и понятно.
Однако после непосредственно программирования вскрывается, что и условие, мягко говоря, не очень точное/полное, да и описания решений умалчивают о куче нюансов и/или имеют неясности. Я очень долго вникал в решение от Дейкстры, и еще дольше — в статью Чанди-Мисры с универсальным решением. И не могу сказать, что я на 100% понял, как они должны работать, и как стыкуются с изначальными неясностями в условии. Я более чем уверен, что налажал с их реализацией. По Чанди-Мисре смотрел готовый код и там все в итоге сводилось к переизобретению упорядоченных ресурсов. И в итоге лучшим оказалось одно из простейших решений.
А еще примитивы java добавили веселья: семафор, которому можно бесконечно увеличивать количество разрешений — ну, такое.
Но в целом упражнение было интересным. Применимость на практике — очень сомнительная, я и освежить память как раз хотел потому, что давно все это не трогал — не было надобности.
Код можно посмотреть тут.
Очередная драма с Mozilla
Кого не разбудил шторм недельной давности — Mozilla убрала из документации Firefox пункт про то, что она не продает никому ваши данные. В целом принцип “если вы что-то получаете бесплатно, то продукт — это вы” выполнен, вроде ничего удивительного (ну а так же “ты либо умираешь героем, либо живешь достаточно долго, чтобы стать злодеем”). Напоминает ситуацию с телегой, которая обещала всегда быть без рекламы, хотя продажа данных — немного другое.
В целом, от Mozilla и до этого доносились не очень хорошие новости — сокращения сотрудников, уменьшение поддержки раста и нового движка, сомнительные зарплаты топов при плохих показателях и т.п.
Почему то, что случилось, не очень хорошо — вам и так уже каждый утюг проорал. Но есть и попытка чуть более объективно взглянуть положение вещей: в статье пытаются выстроить “линию защиты” для Mozilla, где вывод примерно сводится к тому, что чисто теоретически, это юристы лютуют, пиарщики обосрались, но есть шанс, что не все так уж и плохо.
Mozilla выпустила заявление, мол, пацаны, правда не продаем, просто юридически так написать не можем, на что им уже насовали, что как раз из-за таких хитрожопых юристы и сделали формулировку продажи данных очень широкой. Ну и еще пишут, что вряд ли FAQ, где для человеков написано, является прям супер-юридическим источником.
Интересно, как отреагируют дистрибутивы Linux, во многих из которых ФФ — браузер по умолчанию.
Качественный анализ SWE-bench
SWE-bench — это бенчмарк на основе ~2300 реальных тикетов и связанных пулл-реквестов из 12 GitHub репозиториев на питоне. Его часто используют для того, чтобы заявить, что скоро нейронки заменят прогеров: например, недавний Claude 3.7 показал в нем аж 70% (в то время как у текущих рекордсменов — 49%). Бенчмарк изначально задумывался как способ проверки решения “реальных” проблем в реальных проектах.
Вообще, вопросы к репрезентативности должны возникнуть уже на стадии более подробного описания/аннотации (только питон, 12 реп и т.д.), но для своего времени (полтора года назад всего) бенчмарк был хорош — лучшая модель в нем набирала меньше 2%. А вот год спустя появилась статья с качественным анализом бенчмарка.
Результаты получились довольно яркие:
- в 33% случаев решение можно было довольно тривиально вывести из условия (например, решение было предоставленно в комментарии к тикету);
- в 31% решений были хреновые тесты (и “решение” хоть и проходило тесты, но было неполным/некорректным);
- 94% тикетов были созданы до даты отсечки знаний LLM (т.е. датасет нейронки потенциально мог включать в себя PR, закрывающий тикет);
- для всех задач были тесты -_-
Соответственно, если улучшить тесты/условия, то и проценты в бенчмарках будут на порядок ниже. Вот такие маркетинговые пироги :)
Чистое ядро, грязная оболочка
Доклад — базовая база про организацию кода, чтобы он был тестируемым, поддерживаемым, рожь ржилась, пшеница колосилась и т.п. Несмотря на ФП-уклон, суть идеи подойдет к любой парадигме. Солидные сеньоры все из доклада наверняка знают и применяют, но джунам полезно будет. В конце есть еще небольшая секция про управление зависимостями.