Читать в телеге. Когда-то там были посты не только от меня.
Help me, step-container, I'm stuck!
Иногда контейнер не может подняться, а в логах полезной информации нет. Надо бы провалиться в консоль контейнера, чтобы проверить все изнутри, но из-за постоянных рестартов это не получится сделать. В этом случае можно сохранить текущее состояние контейнера:
docker commit %container_id% %some_name%
и стартовать его с командной строкой:
docker run -it %some_name% /bin/sh
А потом уже дебажить, что там внутри не так.
Из-за чего команда профессионалов может работать фигово
В продолжение заметки про продуктивность — а почему в команде из кучи замотивированных сеньоров все равно может получиться что-то не то?
Причин может может быть масса [1, 2, 3]:
- Они делают не то, что важно (в т.ч. из-за того, что увлекаются чем-то интересным для себя), часто из-за отсутствия четких целей, отсутствует фокус или пытаются сделать все и сразу.
- Они ждут другую команду (из-за плохого разделения, из-за мутных процессов или из-за чрезмерной специализации, когда не можешь помочь другой команде).
- Нет четкого понимания, что нужно сделать, тратится время на выяснение этого (хорошо еще, если до разработки, плохо, если на миллионе встреч).
- Нет четких зон ответственности и ролей — непонятно, кто должен что сделать, чаще всего превращается в “не делает никто”. В том числе когда что-то можно было предотвратить малой кровью вместо героического расхлебывания последствий.
- Они не умеют говорить “нет”.
- Нет долговременного планирования, слишком большая сосредоточенность на скорости, а не качестве.
- Они плохо понимают предметную область и конечного потребителя.
- Нет признания результатов, чувства достижения, мотивация делать нормально падает, появляется куча новых проблем.
Визуализация 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 билда + отключение шагов, которые можно пропустить, для более быстрой проверки работоспособности.