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

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

Константа Буэнос-Айреса

В четверг посмотрел очередной видос с Numberphile и руки зачесались кое-что проверить. Суть видео вкратце: если взять f_1 = 2.920050977316134..., и вычислять n-ный элемент по формуле

f_n+1 = ⌊f_n⌋  * (f_n - ⌊f_n⌋  + 1)

то последовательность из целых частей ⌊f_1⌋, ⌊f_2⌋, ⌊f_3⌋ ... будет совпадать с последовательностью простых чисел.

Звучит очень круто, но конечно есть подвох с тем, что первый элемент (константу Буэнос-Айреса) можно вычислить, только зная простые числа. Но даже если так, то в коде-то это будет смотреться хорошо!

Вот только точность может внести коррективы, поэтому стоит проверить: а сколько простых чисел можно сгенерировать точно? 100? 1000?

Простенький скрипт дает ответ, что все грустно: с 15 десятичными знаками в константе получится всего лишь 12 чисел: 13-ое простое число — 43, а новый метод выдаст 42. Может, если использовать decimal с сумасшедшей точностью, и предвычислить константу по формуле из оригинальной статьи, то все будет лучше? Увы, но нет: с 1000 знаками точности можно сгенерировать правильно всего лишь 166 простых чисел.

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

Ссылка

Pandoc — конвертация между форматами

Я слышал раньше о Pandoc, но не знал, что им пользоваться также просто, как и утилитой convert для изображений, которая выглядит порой как convert input.jpg output.png.

Pandoc мне пригодился, когда нужно было сконвертировать гугл-док с ответами для игры с кучей ссылок в Markdown для сайта. Для этого я скачал гугл-док как odt и потом выполнил

pandoc -f odt -t markdown Ребусы_ответы.odt -o result.md

Хоть форматирование получилось не идеальным, но после пары замен по регуляркам использовать его для верстки ответов под сайт стало гораздо удобнее по сравнению с копированием из гугл-дока.

Ссылка

Нагрузочное тестирование

Помимо старенького JMeter и де-факто стандарта для мира JVM Gatling, узнал на днях еще о существовании Siege. Если для первых двух надо что-то писать/настраивать, то для тестирования чего-то не очень сложного “по-быренькому” siege — отличный вариант, потому что он консольный и все параметры передаются аргументами. Пример команды:

siege -c10 -t60s --content-type "application/json" --header="Connection: Keep-Alive" -b 'https://example.com POST {"some": 0, "payload": "10"}'

Она будет бомбить 10 “пользователями” в течение 1 минуты указанный адрес с нужными заголовками.

А вообще всяких утилит для нагрузочного тестирования довольно много, сравнение можно посмотреть тут.

Ссылка

Сайты с геоинформацией

Когда мне понадобилось построить граф из топонимов для игры, для меня стало открытием, что очень мало городов имеют страницу на Википедии или хоть какой-то след в интернете. Но это еще ничего: еще больше меня удивило, что в нашем киберпанке, где, казалось бы, со спутника всю землю уже зафотографировали и отмашинлернили, вполне распространена ситуация, когда города с населением больше 100 тысяч человек тупо не обозначены на карте. Это, конечно, касается не “первых стран мира”, но все равно как-то мне от этого взгрустнулось. Я, видимо, все еще ношу розовые очки в плане некоторых технологий.

А помогли мне в поиске топонимов Geonames.org, который аггегирует официальные базы государств, позволяет искать топонимы по имени и показывать краткую справку с картой, FallingRain, который еще позволит посмотреть погоду с небольшой историей, ну и поиск на OpenStreetMap, куда уж без него.

Ссылка

Таймауты и токены отмены

Шикарная статья про то, как должны быть сделаны правильные таймауты, от создателя библиотеки Trio. Отлично раскрыта проблема вложенных таймаутов (когда функция с таймаутом 10 секунд делает несколько долгих вызовов — сколько им ставить таймаут?) и тема cancellation token (после этой статьи я наконец до конца понял, зачем в он был понатыкан шарповом коде, который я читал).

Ссылка

История ввода в python

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

В питоне для этого можно использовать readline. Просто написать import readline и стандартный input() будет иметь историю (в рамках этого запуска), по которой можно ходить стрелочками вверх-вниз.

Ссылка

Эмулятор андроида

Захотел я тут одно мобильное приложение запустить на компе. Думаю — ну, в 2020 живем, сейчас минут за 10 скачаю эмулятор какой-нибудь и запущу. Смотрим на варианты эмуляторов: этот платный, этот облачный, для этого виртуалку качай, этот — только для винды и мака, один так вообще плагин к браузеру, этот — порт системы под x86, который ставить отдельно с загрузочной флешки. В общем, “богатый” выбор. В итоге остановился на Anbox.

Поставить его проблем особых нет:

snap install --devmode --beta anbox
sudo apt install android-tools-adb

Все довольно быстро, можно потыкать в стандартные приложения, вроде как работает. Потом качаю apk через apkcombo или evozi, ставлю через

adb install apk_name.apk

И, разумеется, наступаю на грабли INSTALL_FAILED_NO_MATCHING_ABIS. Ну ок, проблема в архитектуре проца. Пробую для x86 скачать apk — те же грабли. Но можно поставить слой совместимости и после этого приложения ставятся и даже запускаются. Однако целевое приложение мне выдало какую-то свою ошибку. Решил проверить на чем-нибудь поинтереснее: ночная сборка Firefox запустилась, но вместо сайта показывает белый экран. А рандомная игруля (Plants vs Zombies) вообще не запустилась. Пару раз при этом эмулятор падал. Думаю ­— ну ладно, кривая фигня, попробую лучше “официальный” эмулятор — Android SDK.

Надо скачать Android Studio, через нее скачать пару миллиардов гигов зависимостей, потом найти, где собственно закопан эмулятор, и запустить его через командную строку (впечатляющий UX). Система запустилась, тыкать в нее по-прикольнее, чем в Anbox, но как домашний экран провертеть до приложений, я так и не разобрался, запускал все через настройки. Установка приложений тоже закончилась весело: я попробовал 4 комбинации apk и архитектуры (x86/arm) и ни одна не сработала. Два варианта ошибки: Segmentation fault (core dumped) и Couldn't parse error message (еще один впечатляющий UX). Понятия не имею, как люди могут использовать этот эмулятор для разработки.

Возможно, у этой истории будет продолжение (я уверен, что это случай “информация была дана, вы не разобрались”), но сейчас у меня от нее пригорело, и пробовать что-то еще сил уже нет.

Ссылка

Грабли генерации id в Hibernate

За использование фреймворков приходится платить. Пусть есть Entity с простым полем

@Id
val id: UUID = UUID.randomUUID()

Вроде все просто: при создании сущности ей сгенерируется id, потом запишем его в базу одним запросом. Однако добрый EntityManager сделает тут один дополнительный запрос — а вдруг это не новая сущность? Поэтому приходится писать так:

@Id
@GeneratedValue
@Column(name = "id", updatable = false, nullable = false)
val id: UUID? = null

Тут мы информируем EntityManager, что это поле он должен сгенерировать сам (по умолчанию генерируется UUID), и что лезть в базу не надо, если id отсутствует. А потом защищаемся от самих себя — запрещаем писать в базу сущность с отсутствующим id, ведь компилятор это уже проверить не может. Зато он не знает ничего про генерацию этого поля и вполне справедливо считает, что раз оно может отсутствовать, то изволь переписать почти весь код его использующий, как минимум equals и hashCode.

(Скоро у меня кончатся идеи для постов и канал превратится в нытье про то, как я не люблю Spring и стандартный стек вокруг него).

Ссылка

Ускорение ввода-вывода в С++

Если вдруг пришлось залезть в такие дебри, что нужно это ускорять (например, чтобы сделать лабу по алгоритмам:)), то помогут две магические строчки:

ios_base::sync_with_stdio(false);
cin.tie(NULL);

Первая говорит о том, что нам плевать на C, его средствами мы читать/выводить ничего не будем, поэтому не будем синхронизировать буферы стандартных потоков ввода-вывода от С и C++. Вторая говорит о том, что не надо синхронизировать cin и cout (по умолчанию при любой операции над одним автоматически очищается буфер другого). Это можно себе позволить, если, например, программа однопоточная.

Ссылка

Чек-листы для кода и архитектуры микросервисов

https://kislayverma.com/programming/code-review-checklist-for-distributed-systems/ https://kislayverma.com/programming/design-review-checklist-for-distributed-systems/

Местами спорно и рассказаны довольно базовые вещи, но в целом годно — статьи дают неплохое представление, откуда начать.

Ссылка