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

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

Интерактивное программирование

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

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

Игра про SQL

Сабж.

В игре есть сюжет, но не могу сказать, что он блещет художественностью, перестал читать его после третьего задания. По комментариям в поле ответа можно узнать все необходимое. Иногда есть небольшие неточности в задании (взбесил момент, когда в комментах были попутаны “Returned” и “Recovered”, благо в большом тексте все было нормально), но больше расстраивают манипуляции со строками в районе 15 главы. Для некоторых ошибок выдается объяснение, но у меня в основном были просто сырые исключения SQL и TypeError: can't convert undefined to object. Местами торчит диалект MySQL (или SQLite?).

Но в целом неплохой тренажер получается для начального уровня. Всего там 20 заданий на select, join, group by и т.п. и аж одно на delete.

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

Микросервисы — решение для тех, кто не осилил модули

Одни из основных причин использования микросервисов (помимо культа карго, разумеется) — изоляция и инкапсуляция. Зачастую разделение на микросервисы сопровождается изоляцией на уровне команд и репозиториев: «это наш огород, даже читать нельзя!» Модно, стильно, молодежно, компетенции растут, ответственность четко ограничена (все же знают, какой команде какой микросервис принадлежит, кек).

Альтернатива микросервисам — использование модулей. Если у вас есть какая-то обособленная функциональность, то не обязательно ее изолировать жесткими мерами. Можно просто этот код иметь в отдельном модуле/пакете/папке, и настроить тупейший линтер, чтобы карал за хождение между модулями. При этом можно переиспользовать какие-то общие вещи вроде конфигов, авторизации или всяких утилит. И сделать отдельный конфиг/модуль собственно для запуска кода: если модули изолированы, то легко сделать опции чтобы запускать/собирать только нужный модуль (например, для продакшена со всяким масштабированием, запихиванием в контейнеры если надо и т.п.), набор модулей (например, какие-нибудь фоновые работы) или все вместе (например, для локального запуска).

Расходы на поддержание сопоставимы с микросервисами — пайплайны все равно нужны, думать о межмодульном взаимодействии и инкапсулироваться все равно надо, надо управлять монорепозиторием и т.д. Но при этом можно снизить дублирование, править что-то по мелочи в «чужом» коде (потому что у «них» приоритета на нужную тебе хрень нет) и делать глобальные улучшения (обновление версий библиотек, например). При этом делить на модули приложение можно со старта и постепенно эволюционировать до большей изоляции между ними (использовать несколько баз вместо одной, вкорячивать очереди задач между модулями и т.п.). Да и на те же самые микросервисы разделиться, если будет оправдано.

Прямо совсем разделяться, на мой взгляд, имеет смысл только на полноценные сервисы, но это актуально только для каких-то очень больших систем. Если ваш микросервис может быть полезен только другому микросервису, то на кой черт он вообще сдался? Микросервисы и так уже часто живут группками за гейтвеями с одной ответственной командой, так зачем их по разным репозиториям пихать? Даже если их надо запускать как отдельные приложения, это не значит, что все у них должно быть разным.

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

Несколько аккаунтов с одной почтой

Если у вас есть почта your@email.com, то большинство почтовиков будут на нее же слать все письма от your+anyvalidcharacters@email.com, потому что будут считать все символы после + дополнительным тегом. Подробнее можно почитать, например, в RFC.

В свою очередь большинство сайтов будут считать your@email.com и your+awesome@email.com разными адресами. Таким образом, можно зарегистрировать два разных аккаунта, имея только одну почту.

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

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

Впечатления от GitHub Copilot

На всякий случай: пробовал не последний Copilot X, а обычную версию.

Когда удаляешь ненужный код, чтобы переписать его получше, он предлагает написать его же. Один раз предложил мне 3 копии моего же кода, т.е. “работает — не трогай” усвоено :/

Довольно часто предлагает вообще невалидный код — например, с несуществующим методом. Нет, я бы конечно сам попробовал так написать, но хоть какую-то валидацию хотелось бы иметь, благо можно спросить IntelliJ, в которой все это запущено. Но иногда Copilot предлагает откровенную дичь — например, предлагает паттерн-матчинг для Option для метода, который обычный String возвращает.

В некоторых простых случаях предлагает прямо то, что надо. Однако это обычно бойлерплейт. Да, для него он весьма хорош, но казалось бы, если надо писать бойлерплейт, то стоит что-то поменять в архитектуре или сменить язык? Хотя даже с ним Copilot может налажать — например, он передал не все аргументы в функцию с аргументами по умолчанию. Да и типовые задачи а-ля получить Stream из Iterator (что в java делается миллионом способов) иногда не может решить, на StackOverflow все еще надо было ходить.

В общем, вау-эффекта не произвело, но и отключать его пока не стал. Если пишете на чем-то унылом типа Java или Go, то иногда может помочь. Если на чем-то помощнее, то чаще будут подсказки не в тему, которые будут отвлекать.

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

Автоматический поиск индексов для базы

Я сталкивался со следующими подходами по добавлению индексов:

  1. Что-то стало тормозить — добавляем индекс “на глаз”. По умолчанию добавляем на что-то очевидное.
  2. Мониторим slow query, анализируем запросы, добавляем индекс по анализу статистики (это обычно выделенные DBA).
  3. Добавляем индексы на все поля по умолчанию, а там авось что пригодится.

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

На прошлой работе написал велосипед, который извлекал все SQL-запросы из юнит-тестов и прогонял их через EXPLAIN ANALYZE на копии продовой базы. Это работало весьма неплохо, но доавтоматизировать это до CI-стадии я так и не успел.

Что-то похоже есть и в опенсорсе — эта утилита делает примерно то же самое, только еще и сама создает “гипотетические” индексы и проверяет, что они дадут ускорение запросов. Использовать ее на проекте не смог, т.к. расширение для этих гипотетических индексов нельзя поставить на AWS-овский Postgres :/

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

GraalVM

Наконец-то дошли руки попробовать компиляцию в нативный код (aka AOT compilation) от GraalVM.

Написал Hello World на java, выбрал GraalVM в качестве JVM, подключил официальный плагин Gradle, запустил nativeCompile и… все, оно скомплировалось и работает. Без ошибок, без разбора какой-то дичи, просто заработало сразу и все. Минут 15 на все про все ушло.

Ладно, попробуем что-нибудь поинтереснее — схавает ли GraalVM Spring с его рефлексией и прокси-классами в рантайме? Создаем простенький контроллер, теперь уже на Kotlin, который выплевывает JSON. Компилируем и… оно тоже работает! о_О

Я просто в шоке, до чего дошел прогресс. Ожидал веселых или не очень потрахушек примерно как с Kotlin native или с KotlinJS, но испытал преимущественно позитивные эмоции. Справедливости ради, на большом проекте все-таки магия сломалась:

Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of CensoredLoggerContext are allowed in the image heap as this class should be initialized at image runtime.

Возможно, еще вернусь к подобным экспериментам в будущем, интересно на перф-тесты всего этого посмотреть.

Единственная проблемка, которая возникла — нужно корректно выставлять JAVA_HOME при компиляции. Кроме этого отмечу, что компиляция довольно долгая (1 контроллер на спринге компилировался аж 2 минуты). Разумеется, больше получается конечный файл — 73 Мб (при этом fat jar занимает 22 Мб), но с учетом того, что сама JVM занимает больше 200 Мб, это фигня.

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

Переназначение клавиш в macOS (часть 2)

Опять появился рабочий мак, опять надо что-то делать с раскладкой. Гореть в аду тем, кто в левом нижнем углу размещает Fn вместо Ctrl! Другой прикол — поставить вместо ~ знак параграфа § — кто его вообще использует? Не помню, когда его в последний раз видел.

Тащить что-то тяжелое вроде karabiner, как в прошлый раз, не хотелось. Fn вместо Ctrl легко поменялись через обычные настройки клавиатуры, а вот для ~ пришлось немного баш-команд выполнить.

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

Фингерпринтинг

Надеюсь, ни для кого уже не секрет, что “приватный режим” в браузерах вообще ни разу не приватный. Комбинация заголовков, информации от JS и локации по IP-адресу и т.п. сама по себе может быть уникальна. Проверить свой браузер можно еще тут. Чуть сгладить проблему в Firefox можно с помощью настройки privacy.resistFingerprinting = true.

С одной стороны не очень весело, что приватность в интернете кончилась, с другой — киберпанк, который мы заслужили.

P.S. это все конечно прикольно на компе, но будет ли кто-то с этим морочиться на телефоне?:)

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