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

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

ИИ-перевод

Попробовал перевести статью про техдолг клодом, в основном ради любопытства, насколько хорошо это делают нейронки. Сохранится ли стиль? Будут ли добавлены load-bearing словечки и прочие LLM-измы? Сможет ли нейронка использовать оригинальные термины (потому что я их перевел с английского изначально)?

Я запустил 2 сессии параллельно: в первой промпт был буквально “Translate this for an international audience”, во второй это был уже абзац с несколькими подсказками, на что стоит обратить внимание. Обе сессии были с Opus 5 High.

Первый перевод был в целом норм с точки зрения сохранения смысла, но выбор слов был местами довольно странный (например, “logical” вместо “makes sense” или “take seriously” вместо “take into consideration”), и порядок слов иногда тоже был непривычным. Разумеется, картинки остались без перевода, и было предоставлено ровно ноль контекста для локальных мемов. Цинизм и мат были смягчены. Больше всего досталось определению техдолга — оно стало более многословным и менее точным. Стиль оригинала местами сохранился, но в основном был потерян, а перевод воспринимался как машинный. Короче, мне не понравилось.

Однако я доволен этим отрицательным результатом, потому что большинство этих проблем “предсказал” во втором варианте промпта. На удивление, разница между вариантами перевода была не очень большой, в основном отличия в синонимах, числе и временах — не очень даже понятно, повлиял ли как-то на это промпт или это “естественная” случайность модели (или вообще фингерпринтинг). К сожалению, второй вариант перевода оказался не сильно лучше первого: да, там были переводы картинок и сноски про мемы, потому что я это попросил, и они в целом были средненькие, но сам перевод был местами лучше, местами хуже, и клод не смог передать стиль (“вайб”?).

Далее, я сбросил сессиям варианты друг друга и спросил что они думают (“меняемся листочками”). Первый чат ответил прямо: бери второй, с минорными правками. А второй похвалил первый за “better English rhythm”, посетовал на отсутствие перевода картинок и сносок и нашел нестыковки. Наконец, я попросил “лУчШуЮ” модель Fable 5.1 Max выдать лучший результат, даже немного помог ей, и все равно на выходе получилось не то, как будто ИИ-рулетку в третий раз покрутил.

В общем, для передачи смысла сойдет, а так средне. Сейчас модно говорить, что “ИИ заменит Х-чиков” — штош, если вы хотите качественный перевод, то ИИ еще не способен заменить переводчиков.

UPD: попробовал по совету экспертов — чистый контекст, второй промпт + нэтив спикер + косяки которые нашлись в переводах:

  1. Определение техдолга — все еще говно, и совпадает с определением из “грязного” контекста буква в букву.
  2. Опять рулетка с выбором слов/синонимов/порядка/временами/числами и т.п. Но, справедливости ради, реже спотыкаешься об такое.
  3. Перевод картинок хуже: например, “Можно, а зачем” в этом варианте переведен как “You could. But why?”, а Opus из второго варианта перевел как “Sure, but why?”, и в “грязном” контексте то же самое.
  4. У Opus “костыль” остался костылем с контекстом про слэнг, а у чистого Fable — тупо “hack”.
  5. Да в и целом опус интереснее/лучше объяснил мемы (чемодан, “если бы мы знали”, ТЗ и т.п.)

Короче, я не увидел качественного улучшения по сравнению с Opus — все равно надо доделывать.

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

Хорошая спецификация — долго, дорого и не всегда возможно

Занятная статья про 2 основные аспекта формальной верификации: дороговизну и сложность формализации. И если первый аспект можно закидать деньгами, вычислительными ресурсами и теперь еще ИИ (который уже может нагенерить, например, формальное доказательство для теоремы Ферма), то понять, а как, собственно, система должна себя вести, все еще очень тяжело (за редкими исключениями). Спецификацию сейчас не для каждого языка программирования можно найти, а для чего-то более приближенного к бизнесу если что-то и будет задокументировано, то информация о поведении будет размазана по документации, тикетам, коду, презентациями, тестам и т.п. Но даже если собрать это все в одном месте и начать формализовывать, то появляется куча вопросов про сценарии. А бизнес на большинство и не знает ответа, или ему вообще пофиг, что будет в этом случае.

Еще одна проблема заключается в строго следовать спецификации тупо невыгодно. Это разобрано на примере PDF читалок: лучше как-то криво отобразить сломанный документ, чем сказать “ой, не по спецификации” и ничего не делать (закон Постела).

В общем, хотя формальная верификация и стала более доступной, она все еще слабо применима на практике.

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

Игры OverTheWire

Когда учился в универе, CTF был не очень популярен и прошел мимо меня. Игры OverTheWire как раз в таком формате: чтобы пройти на следующий уровень надо найти спрятанный флаг (пароль), выполняя задания.

Минимальную базу по Linux можно получить, пройдя Bandit. Даже с учетом того, что я все там знаю, все равно было занятно.

Азы по web-безопасности покроет Natas, а по шифрованию — Krypton. Остальные — про реверс-инженеринг.

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

Культуры зависимостей

Неплохой доклад с тезисом, что различные подходы к управлениям зависимостями в индустрии — это культурный вопрос, а не технический. Начинается, разумеется, с веба, а другим примером служат игры. Жирные зависимости — плохо (потому что большая часть вам не нужна), мелкие — тоже (left-pad). Не забыт и вопрос обновления — и часто плохо, и редко плохо (но это решаемо). Короче, перед добавлением зависимости надо думать, шансы прикидывать.

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

Сравнение Proguard и R8

ProGuard — это обфускатор и минификатор для java, а R8 — тоже минификатор для java и де-факто стандарт для Android. У последнего сложилась репутация как более мощной замены для ProGuard, некоторые не-Android проекты даже рассматривают замену ProGuard на R8 (например, Kotlin), благо формат настроек у них почти совпадает. У меня раньше в голове был образ, что R8 — это то же самое, что и ProGuard, только новее и лучше. Реальность полна разочарований, как говорится:)

Я буду рассматривать только вопрос минификации (обфусцировать java — очень странная идея), и стоит обговориться, что область ее применения очень ограничена — на серверах места полно, а на пользовательские системы java сейчас редко доставляют (Gradle тут скорее исключение).

Вот что я обнаружил, я когда попробовал заменить кастомную минификацию в Gradle сначала на R8, а потом на ProGuard:

  1. Вывод R8 зависит от версии JVM, а ProGuard для работы нужна JVM с jmods, которые могут быть не включены в JDK.
  2. R8 не позволяет ничего настроить относительно ресурсов и, как следствие, мультирелизных jar, манифестов, неактуальных контрольных сумм и т.п.
  3. R8 нельзя заставить удалить класс или метод, если на него есть ссылки (даже если знаете, что это логически мертвый код).
  4. R8 переписывает метаданные Kotlin и ломается, если ваш Kotlin новее.
  5. R8 переписывает методы, и, с одной стороны, код получается меньше, но может из-за этого сломаться на новейших JVM/Kotlin с чем-то вроде java.lang.VerifyError: Bad invokespecial instruction: interface method reference is in an indirect superinterface.

При этом R8:

  1. Cжимает лучше, потому что работает на уровне методов, а ProGuard — на уровне классов. Т.е. ProGuard может оставить класс с 1 живым методом и сотней неиспользуемых.
  2. Требует меньше настроек “корневых” классов.
  3. Не такой строгий — если не видны какие-нибудь родительские классы, то предполагает, что они есть.
  4. Поддерживает Kotlin.
  5. Не имеет зависимостей — это один jar.

Мой сценарий довольно особенный и ProGuard оказался лучше, но для Android описанные минусы R8 слабо релеватны, так что для него он будет лучше.

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

ИИ-переписывание Bun

Многие наверняка слышали историю про то, что bun переписали с Zig на Rust с помощью тучи ИИ-агентов: впечатляющие графики, “новый уровень ИИ-инженеринга”, blazing fast™, убедительные результаты и т.п. Спонсирует все это Антропик, который купил bun в декабре. Эксперимент успешный, переписанный bun уже внутри Claude Code, аж с июня. А еще автор Bun на досуге запромптил Claude, чтобы сделать прорыв по гипотезе Римана. Короче, гений, миллионер, еще и плейбой наверняка.

Мало кто видел ответ создателя Zig на эту статью: “вы не разобрались”, проблема не в Zig и не в языках, потому что вопросики к автору bun были и до этой эпопеи.

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

Выводы делайте сами, как говорится.

UPD: таки зарелизили.

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

Zero-defects code

Капсула времени: служебка Microsoft аж из 1989 года про нулевую терпимость к багам. Кажется, она не очень помогла, но вещи написаны хорошие, которые по большей части актуальны до сих пор.

Даже если идеал кода без багов недостижим, все равно надо к нему стремиться. Если думать, что баги неизбежны, то не будут стараться их предотвратить; будет фокус на количестве фич и скорость — будет соответствующее качество; надо править корень проблемы, а не симптомы и бороться со сложностью и т.п.. Увы, пока никто не придумал, как убедить руководителей в пользе долговременного планирования после того как прошел этап MVP, и как бороться с тем, что награждают не за качество работы.

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

Семантический diff

Из-за того, что в последнее время стало кратно больше код-ревью (потому что нейронку надо худо-бедно контролировать), многие начали присматриваться к “семантическим” инструментам для отображения изменений в коде, хотя они давно известны: Difftastic, sem, diffsitter, SemanticDiff и т.п.

Не могу сказать, что какой-то из инструментов произвел на меня вау-эффект: да, вроде получше, но не настолько, чтобы пересилить неудобства. Я честно пытался, но пользоваться ими на постоянной основе у меня не получилось: это все консольные инструменты, а мне окошки подавай с графической IDE. Да, вроде есть какая-то интеграция с VS Code у некоторых, но на спектре IDE-шности у меня он все еще ближе к текстовому редактору лежит.

В IntelliJ можно настроить внешний инструмент для разницы, но это по сути ярлык для вызова терминала (да и то без приседаний не обойтись). А еще у них есть тикет, чтобы сделать “нормально”, которому аж 21 год (sic!).

В итоге я, прости господи, навайбкодил плагин для IntelliJ, чтобы интегрировать консольные инструменты в окошко сравнения. Получилось не очень: сами модели в IntelliJ довольно ограничены и с помощью них все выразить не получается. Но все-таки, чуть-чуть лучше встроенного diff в некоторых сценариях.

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

50 оттенков Brainfuck

Brainfuck, хоть и весьма минималистичный (8 односимвольных команд), изначально задумывался как язык, для которого можно сделать минимальный компилятор (уже вторая версия была 240 байт, а на современном железе можно уложиться в 100).

Если же минимизировать количество команд — то легко уложиться в 2 простые команды (можете поиграться тут), или в одну посложнее.

А если минимизировать количество различных символов? Если отбросить эзотерику, одним из первых тут стал JSFuck, который выразил весь JS через 6 символов: +!()[]. А потом код-гольфисты продолжили:

  • JS дожали до 5 символов — []+=`. Как и в JSFuck — приколы типизации.
  • Ожидаемо нашлись варианты для Python (exc="%\n) и Perl (<>^es), но там скучный exec/eval.
  • Внезапно для Haskell надо всего 4 символа — ()=;, разумеется, не обошлось без λ-исчисления, точнее, SKI.
  • Для Си есть решение за 5 символов — +1;=$, в котором напрямую прописываются машинные коды.
  • В java унылые 02367?\abcdeitu, по сути просто обычный исходник, написанный через юникод-последовательности \u0a23, с гимнастикой для снижения количества нужных цифр.
  • В bash — аналогичный подход с 01456\$ ', zsh чуть интереснее с $#< (){}.
  • В PHP — 5 символов, (^.9), подходы похожи с JS: делаем числа, из них буквы, потом имена функций и т.д..

Если вернуться к эзотерике, то стоит упомянуть Whitespace, где нужны только \t \n. Но победителем будет бесспорно Unary с прикольной идеей: берем код на Brainfuck, преобразуем его (биективно) в число, пишем соответствующее количество нулей (или любых других символов), и программа готова.

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

Наглядный пример, почему важны хорошие генераторы случайных чисел и QA

Неплохой разбор вскрывшейся недавно уязвимости биткоин-кошелька Coldcard. Вкратце: из-за кривой сборки (в этой статье чуть подробнее расписано) вместо нормального генератора случайных чисел с физическим источником энтропии использовался программный, с гораздо меньшей энтропией. Как следствие, стало легко подобрать приватный ключ. В итоге украдено более 1500 BTC ($100 млн.+) с 7300+ адресов.

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