Читать в телеге. Когда-то там были посты не только от меня.
DSL для роутинга
В Spring 5.2 можно писать в функциональном стиле не только для WebFlux, но и для обычного MVC. Т.е. вместо анноташек над контроллерами можно писать что-то вроде
fun routes() = router {
accept(ALL).nest {
GET("/hello/{name}") {
val name = it.pathVariable("name")
ok().body("Hello, $name!")
}
}
}
где лямбды принимают ServerRequest
и возвращают ServerResponse
. Такой подход можно использовать для генерации эндпоинтов из конфига.
Подобный подход очень напоминает Ktor:
routing {
get("/hello/{name}") {
val name = call.parameters["name"]
call.respondText("Hello $name!")
}
}
Модели памяти языков программирования
Хорошая, хоть и длинная, статья про то, какие проблемы могут быть с точки зрения распространения изменений данных при многопоточной обработке, от создателя языка Go. Есть еще и первая часть, про те же проблемы с точки зрения процессоров, но она поскучнее и менее интересна (большая часть кратко повторена в программной части).
В хардварной части в основном рассматриваются разные ситуации с гонками и последовательной согласованностью (Sequential consistency). Раскрывается мысль, что даже на уровне железа есть приколы с многопоточностью. Получается, что очень похожие проблем с параллелизмом случаются в разных контекстах и на разных уровнях абстракций: в процессоре, языке программирования, узлах распределенной БД, микросервисах. И методы решения похожи: куча очередей (как в x86), куча синхронизирующихся копий состояния (как в ARM). Разумеется, x86 и ARM дают разные гарантии консистентности. Под конец статьи рассказывается о модели синхронизации DRF (data-race-free). Вкратце суть такая: кроме чтения и записи, для памяти есть еще операция синхронизации. Сихнронизация служит “барьером”: операции чтения и записи можно перемешивать как угодно, но нельзя перемещать через барьер. И в 1990 доказали, что если писать программу без гонок (нормально синхронизировать чтение-запись между потоками), то тогда на железо, соответствующее DRF, будет выполнять с последовательной согласованностью, т.е. как будто она вся выполнялась в одном потоке. И это очень классный результат, потому что позволил абстрагироваться от кучи проблем, написанных в начале статьи, и дать хоть какой-то простор для оптимизаций компилятору.
В программной части больше интересного. Например, Java, оказывается, первый язык, в котором была попытка прописать поведение многопоточных программ на уровне спецификации (1996). С первого раза не получилось, но в 2004 в Java 1.5 добавили фич и она стала поддерживать модель DRF, причем в этом активно участвовала одна из авторов оригинальной статьи. Отношение happens-before как реализация DRF — важная часть модели памяти Java. Однако создатели в 2010 году признали, что у этой реализации есть баги, хоть она и является хорошим компромиссом между сложностью и надежностью.
В C++11 использовали модель Java как основу (sic!), пытались сделать проще, но в итоге только усложнили и она стала менее полезной для программистов. Ну и undefined behaviour добавили, куда ж без него, и стремные атомики, которые особо ничего не гарантируют. Однако в Си, Rust и Swift использовали модель C++11 (последние два — потому что LLVM и интеграция). JavaScript пошел своим путем: его модель памяти совместима с C++11, но ближе к Java (место для вашей шутки про название языка).
Хоть автор и с оптимизмом смотрит в будущее, текущая ситуация с моделями памяти тяжелая: до сих пор не предложена модель конкурентных вычислений с примитивами для корректной быстрой синхронизации памяти, и никто до конца не понимает и не может формализовать гонки.
Запуск графического приложения с админскими правами
Раньше для этого можно было вызвать команду с gksu
, например gksu kse
. Однако, gksu убрали из дистрибутивов, т.к. он не безопасен.
Альтернатива — использовать политики (для параноиков) или pkexec
. Но есть проблемка: при подтверждении запуска виден только исполняемый файл, но не его аргументы. Т.е. окно авторизации для pkexec sh -c 'echo hello'
и для pkexec sh -c 'rm -rf /'
будет выглядеть одинаково. Решить это можно через политики, но писать душный xml — скучно, поэтому можно извратиться по-другому.
Можно отредактировать сообщение сервиса polkit
, вставив туда шаблон $(command_line)
. Для этого:
- Берем файл с переводом для британского языка и распаковываем его
msgunfmt /usr/share/locale-langpack/en_GB/LC_MESSAGES/polkit-1.mo -o polkit-1.po
- Редактируем
polkit-1.po
любым текстовым редактором, добавляя вmsgstr
Authentication is needed to run '$(program)' ('$(command_line)')
,msgid
не трогаем. - Пакуем отредактированный файл обратно, в директорию со своей локалью (у меня это en_US)
msgfmt polkit-1.po -o /usr/share/locale/en_US/LC_MESSAGES/polkit-1.mo
- Рестартуем сервис polkit, чтобы изменения применились:
systemctl restart polkit
После этого можно будет увидеть полную команду, которую кто-то хочет выполнить с правами супер-пользователя. Ибо нечего авторизовывать что попало, а то какой-нибудь дропбокс любит запрашивать таким макаром право на запуск баш-скрипта, который меняет владельца и права на свои папки.
Неявная конкатенация строк в Python
В питоне есть баг фича, что строковые литералы, написаные рядом, автоматически соединяются в один:
>>> print("ololo" "alala")
ololoalala
>>> ["1" "2", "3"]
['12', '3']
Иногда это может очень бесить (и не только меня, но PEP с предложением выпилить это наследие Си отклонили). Теоретически, помочь могут линтеры: pylint или flake8. А тут можно посмотреть примеры, почему такое поведение может быть полезным.
Тестирование распределенных систем
В продолжение постов про Jepsen и чек-листы по архитектуре микросервисов — ресурс, на котором собрана полезная информация про тестирование распределенных систем (в т.ч. всеми любимых микросервисов).
Уровни языков программирования
Был в Академгородке на выставке “Наука Сибири”, там попалась книжка 2015 года про парадигмы программирования. В оглавлении встретились “языки низкого уровня”, “языки высокого уровня” и … “языки сверхвысокого уровня”. “О таком я еще не слышал, — подумал я, — наверно, это про какой-нибудь Haskell или Prolog, которые сильно абстрагированы от железа. Или про DSL?”
Но оказалось, что сибирские ученые таким языком считают Sisal — еще один достаточно специфичный язык для параллельных вычислений, который позволяет не заботится о синхронизации и разбивке на отдельные процессоры/компьютеры. Он является “функциональным потоковым языком, ориентированным на написание больших научных программ”, “одним из самых известных потоковых языков промышленного уровня”, “позиционируется как замена языка Fortran для научных применений” и позволяет “предоставить широкому кругу прикладных программистов, не имеющих достаточного доступа к параллельным вычислительным системам, но являющихся специалистами в своих прикладных областях, возможность быстрой разработки высококачественных переносимых параллельных алгоритмов на своем рабочем месте”. Создан язык в 1983 году, вторая версия вышла в 1991, а в ИСИ СО РАН развивают этот язык после третьей версии, уже даже cloud-версия есть. По синтаксису напоминает Pascal.
Что такое язык сверхвысокого уровня, я в итоге и не понял (но можете попробовать вы, начать можно отсюда, осторожно, опасно для мозга), но по идее Erlang, любой язык с акторами, Spark DSL — это все языки сверхвысокого уровня в данной терминологии.
Любопытно, что Википедия языками сверхвысокого уровня считает Python и Visual Basic. Правда, это термин из 90х, когда Си был языком высокого уровня (а сегодняшний программист скорее выделит для него “средний” уровень). А еще можно почитать про поколения языков программирования, где первое поколение — машинные коды, третье — С++, Java и т.п., а пример четвертого — 1C. Такие дела :)
CAP теорема
Доступная статья, где кратко изложена суть теоремы, ее история, вопрос ее “теоремности” и продолжение в лице PACELC.
Альтернативы классическому менторству
Делал презентацию для встречи, чтобы вбросить пищу для размышлений по теме менторства, но встреча перенеслась непонятно куда, поэтому почему бы и не выложить ее сюда.
В ней нет никаких глубоких изысканий, да и делал ее я в основном для того, чтобы поиздеваться над первой фразой от коллеги (:toxic:).
Чек-лист тимлида
Хорошая статья, которая пригодится не только всяким руководителям, но и каждому в команде. В ней рассмотрены типичные боли проекта и команды с позиции “что можно улучшить новому руководителю”, но можно использовать ее как источник идей для того, что можно улучшить в команде самостоятельно. Содержит жизы :)
16 Кб хватит всем
У докера обнаружилась веселая особенность: он разделяет строки лога длиной более 16 Кб, чтобы оптимизировать использование буфера. Настроить размер нельзя. При разбиении лог помечается как разделенный, и подразумевается, что склейка должна быть на стороне агрегатора логов (причем есть несколько их реализаций). Однако не все агрегаторы это адекватно поддерживают: например, Filebeat не может это сделать для двух записей из разных файлов (в разные файлы они могут попасть при ротации логов).