Минутка просвещения

Читать в телеге. Когда-то там были посты не только от меня.

Степень влияния задержки на пользовательский опыт

Неплохая статья (хоть и с всратыми картинками) про то, как воспринимается время с точки зрения типичных пользователей:

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 и коллеги вбросили эту статью — там все в целом по делу.

СсылкаКомментировать

Как починить билд Gradle

У Gradle куча разных кэшей и, увы, изредка может получится так, что в них будет записано некорректное состояние. Если есть подозрения, что это действительно так, можно попробовать перезапустить билд…

  1. с флагом --rerun-tasks
  2. с --no-configuration-cache
  3. с --no-build-cache
  4. после clean
  5. с чистой домашней папкой Gradle: --gradle-user-home ./gradle_home
  6. после убийства всех демонов Gradle (по идее то же самое что и выше, но стоит попробовать)
  7. после рестарта IDE, если вызываете билд из нее.

Если вышеперечисленное не помогло, то скорее всего проблема где-то в билд-логике и/или окружении.

СсылкаКомментировать

Частичная автоматизация как интерактивная инструкция

Хорошая статья про неплохую идею: вместо того, чтобы убиваться со 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, закрывающий тикет);
  • для всех задач были тесты -_-

Соответственно, если улучшить тесты/условия, то и проценты в бенчмарках будут на порядок ниже. Вот такие маркетинговые пироги :)

СсылкаКомментировать

Чистое ядро, грязная оболочка

Доклад — базовая база про организацию кода, чтобы он был тестируемым, поддерживаемым, рожь ржилась, пшеница колосилась и т.п. Несмотря на ФП-уклон, суть идеи подойдет к любой парадигме. Солидные сеньоры все из доклада наверняка знают и применяют, но джунам полезно будет. В конце есть еще небольшая секция про управление зависимостями.

СсылкаКомментировать