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

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

Модели памяти языков программирования

Хорошая, хоть и длинная, статья про то, какие проблемы могут быть с точки зрения распространения изменений данных при многопоточной обработке, от создателя языка 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). Для этого:

  1. Берем файл с переводом для британского языка и распаковываем его msgunfmt /usr/share/locale-langpack/en_GB/LC_MESSAGES/polkit-1.mo -o polkit-1.po
  2. Редактируем polkit-1.po любым текстовым редактором, добавляя в msgstr Authentication is needed to run '$(program)' ('$(command_line)'), msgid не трогаем.
  3. Пакуем отредактированный файл обратно, в директорию со своей локалью (у меня это en_US) msgfmt polkit-1.po -o /usr/share/locale/en_US/LC_MESSAGES/polkit-1.mo
  4. Рестартуем сервис 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. Такие дела :)

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

Альтернативы классическому менторству

Делал презентацию для встречи, чтобы вбросить пищу для размышлений по теме менторства, но встреча перенеслась непонятно куда, поэтому почему бы и не выложить ее сюда.

В ней нет никаких глубоких изысканий, да и делал ее я в основном для того, чтобы поиздеваться над первой фразой от коллеги (:toxic:).

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

Чек-лист тимлида

Хорошая статья, которая пригодится не только всяким руководителям, но и каждому в команде. В ней рассмотрены типичные боли проекта и команды с позиции "что можно улучшить новому руководителю", но можно использовать ее как источник идей для того, что можно улучшить в команде самостоятельно. Содержит жизы :)

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

16 Кб хватит всем

У докера обнаружилась веселая особенность: он разделяет строки лога длиной более 16 Кб, чтобы оптимизировать использование буфера. Настроить размер нельзя. При разбиении лог помечается как разделенный, и подразумевается, что склейка должна быть на стороне агрегатора логов (причем есть несколько их реализаций). Однако не все агрегаторы это адекватно поддерживают: например, Filebeat не может это сделать для двух записей из разных файлов (в разные файлы они могут попасть при ротации логов).

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

Google Calendar API

Писал скриптик заполнения командного гугл-календаря. API вроде простое, но нужно пройти N кругов ада, чтобы создать приложение и получить на него креды, с которыми хоть что-то можно сделать. Конечно, классно, что я из коробки могу следить за использованием приложения, квотами, запустить его в облаке, управлять биллингом и все такое... но это поганый скрипт, который мне надо запускать раз в месяц примерно. Прокликивать ради этого больше трех инструкций — как-то стремно.

И поскольку гугл заботится о своих пользователях, то нельзя просто так взять и разрешить какому-то приложению подключиться к календарю. Во-первых, нужно его опубликовать и пройти модерацию (альтернатива — работать в тестовом режиме, что я и выбрал). Во-вторых, нужно получить разрешение у каждого пользователя — тоже логично, но вот только разрешение дается на ограниченный период времени. В моем случае это было 2-3 дня, т.е. при каждом использовании скрипта приходится заново давать ему разрешение в браузере.

Наконец, аутентификация и авторизация должны быть по последнему слову техники, поэтому процесс в совокупности занимает 9 "простых" шагов. Изначально я рассчитывал собрать скрипт из говна и палок на requests, как это делал для Upsource, но пришлось использовать гугловые библиотеки, ибо такую шляпу реализовывать ради скрипта — безумие. Никаких тебе basic-auth или "получи токен 1 раз и делай что хочешь".

Итого, с одной стороны, все логично: безопасно для пользователя, удобно для крупных приложений. А с другой — у меня есть логин-пароль к этому календарю, я и так с ним могу сделать что угодно — зачем городить огород для "владельца" ресурса?

P.S. Кажется, стоит вводить рубрику #пригорело, но тогда половина постов с ней будет :)

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