Читать в телеге. Когда-то там были посты не только от меня.
Визуализация explain для SQL-запроса и рекомендации по индексам
Хороший пост, в котором как для даунов объяснены основные типы индексов, даны советы, когда какие использовать, и приведены примеры запросов, которые можно оптимизировать. А еще там есть ссылка на сервис, в котором можно визуализировать выполнение запроса и получить рекомендации, какие индексы добавить.
Docker на Маке
brew install docker
поставит только клиенты докера, без демона. docker-machine
, который запускает докер в виртуалке (sic!), уже устарел и его хрен запустишь. Docker Desktop платный (ну, на честном слове платный, но все же) и требует GUI…
В итоге рабочий вариантом оказалась… установка кубера, а именно minikube. Можно еще туннелирование в локальную сеть настроить или поиграться с kubectl. Но после таких приколов хотя бы понимаешь, почему некоторые считают, что надо минимум 32 гига оперативки для разработки на маке :/
Даты изобретения сортировок и кроссбаузерность
После изучения всяких фронтенд штук захотелось сделать что-нибудь очень простое. Прям наговнякать. Решил сделать временную шкалу с датами изобретения алгоритмов сортировки на CSS, и собирать HTML на голом питоне.
Во-первых, я все еще офигеваю, как сложно сделать какие-то элементарные вещи. Во-вторых, что до сих пор в трех разных браузерах одно и то же форматируется по-разному, хотя я использую все из древних стандартов. Я честно пытался написать кросс-браузерно, но в итоге мне это надоело и я сделал браузеро-зависимый CSS на основе всяких трюков. Отправляйте пулл-реквест, если умеете верстать или хотите попытать силы :)
Наконец, самой тяжелой частью оказались собственно данные. Нашел статью, где вроде есть все, что нужно, но качество данных там просто впечатляющее. Например, в качестве авторов Stooge Sort указаны “Prof. Howard Fine and Howard”. А на самом деле она фигурирует в упражнении из Кормена: “Professors Howard, Fine, and Howard have proposed the following “elegant” sorting algorithm…” — и является отсылкой на комедийный коллектив. Изначально в планах было найти оригинальные источники для каждой сортировки, но это оказалось нетривиальной задачей, поэтому я отложил это до лучших времен.
Демка тут.
Статическая типизация — не панацея
Что выведет этот кусочек кода на Kotlin?
fun main() {
data class SomeClass(val someValue: Int)
val someNull = null
println(someNull + SomeClass(12))
}
Ответ
Выведет nullSomeClass(someValue=12)
. Почти как в JS:)
Все благодаря выводу типов: компилятор находит расширение operator fun String?.plus(other: Any?)
, вызывает у обоих аргументов toString()
и склеивает их.
Хорошо хоть, узнал это не из продакшен-кода, а из познавательного видео, в котором мужик рассказывает про “переопределение” оператора сложения для nullable типов.
Экономьте газ
В мире “современной” разработки, где бизнесу часто нужно чтобы “лишь бы работало”, компиляторы “сами все оптимизируют”, а проблемы с производительностью решаются методом “ну накинь там пока ресурсов на под”, оптимизация алгоритмов сверх банального “для поиска используй хэш-таблицу” кажется излишней, потому что “и так сойдет”.
Однако есть ниша, в которой экономить элементарные операции все еще актуально — смарт-контракты. Каждое вычисление чего-то стоит. Например, в Etherium каждая операция смарт-контракта тратит немного “газа”, не уложился в лимит — транзакция откатывается. В периоды большой нагрузки на сеть газ стоит дороже, в периоды низкой, соответственно, дешевле. Если алгоритм оптимизирован, то на его выполнение будет потрачено меньше газа и, как следствие, меньше криптовалюты.
Хотя некоторые паттерны неоптимального кода довольно тривиально обнаруживаются и исправляются, и вызваны скорее незрелостью технологии (например, расчет суммы, которая не зависит от внешних параметров, может быть заменен формулой). Есть несколько инструментов для оценки использования газа, а еще можно покрыть контракт тестами (например, с помощью hardhat или brownie) и выводить либо оценку, либо точное значение потраченного газа. Но чтобы оптимизировать — тут головой еще надо думать, увы.
Я немного поигрался с двумя последними инструментами, сделал пару тестовых контрактов и посмотрел на использование газа, в целом занятно. Думал даже как-нибудь поиздеваться над студентами, чтобы они оптимизировали в лабах использование элементарных операций, но экосистема nodejs в обоих случаях не очень к этому располагает. Хоть свою RAM-машину пиши…
Буфер обмена с консольной виртуалкой
Сымитировать буфер обмена в консоли без графического окружения (например, на виртуалке) можно, установив gpm
— демон для мышки. С помощью него можно выделять текст левой кнопкой, а правой — вставлять. Кто-то даже упоролся и сделал интеграцию с буфером хост-машины, но выглядит стремно. Древние фиче-реквесты прилагаются.
Оптимизация хэш-таблицы
Прикольный доклад про пошаговую оптимизацию хэш-таблицы в плюсах: начинается с экономии указателей в методе цепочек и заканчивается оптимизацией под кэши процессора.
Кто “выше” таких оптимизаций — может посмотреть про оптимизацию хэш-таблицы для многопоточного доступа (и там же можно освежить в памяти как хэш-таблицы вообще работают).
Отладка Jenkins пайплайна
Чтобы быстрее отладить/доработать скрипт пайплана в jenkins, можно использовать:
- Генератор кода http://${jenkinsHost}/pipeline-syntax, в котором можно накликать один из шагов из плагинов.
- REPL http://${jenkinsHost}/script, чтобы проверить небольшие кусочки или какие-то моменты из Groovy. Недостаток — контекст немного отличается от пайплайна (запускается без песочницы), и код из REPL не всегда будет работать в пайплайне.
- Список глобальных переменных и методов http://${jenkinsHost}/pipeline-syntax/globals, чтобы посмотреть, что доступно.
- Скрипт для одобрения методов за пределами песочницы (если пришлось залезть в кишки), чтобы одобрять методы не по одному.
- Replay билда + отключение шагов, которые можно пропустить, для более быстрой проверки работоспособности.
Запуск нескольких целей в Maven
С помощью defaultGoal
и профиля можно запускать несколько фаз или целей:
<profile>
<id>some-profile</id>
<build>
<defaultGoal>
test
a.group:an.artifact:some-plugin:goal@custom-goal-config
</defaultGoal>
...
При такой настройке mvn -Psome-profile
будет эквивалентен mvn test a.group:an.artifact:some-plugin:goal@custom-goal-config
. Это удобно для разделения этапов в пайплайне (и когда есть конфигурации для целей). Мне пригодилось для получения агрегированного результата покрытия после параллельного выполнения тестов.
Проектирование API
Посмотрел на днях доклад про проектирование API, он неплох (особенно для джунов), но ничего нового для себя, увы, не узнал. Доклад довольно старый, аж из 2007 вернуть бы его, но рекомендую хотя бы пролистать презентацию: повторение — мать ученья.
Интересно в этом докладе то, что докладчик — автор книги Effective Java, той самой, которую очень любили создатели Kotlin, и откуда пошли многие (в том числе спорные) решения в языке. Забавно, что некоторые API java и Гугла (где работал автор) советам, изложенным в докладе, явно не соответствуют.