Испытание дозиметра
Когда в руке молоток, всё вокруг — гвозди. К чему я только не подносил свой дозиметр в тайной надежде увидеть как он меня предупредит об Опасности, но нет, хвала судьбе, источника радиации я нигде не нашёл. Даже по казанскому танковому училищу поносил, нет.
А тут, задумчиво минуя проходную, вспомнил, что приборчик видит у меня ещё и рентген, а он используется внутри машины, которой под настроение праздно светят сумки наши охранники.
Замерил фон снаружи (слева) и сфотографировал цифры сразу после путешествия дозиметра по недрам (справа). 30,7 микрозиверт — это довольно много, 0,5 микрозиверта в час — это верхняя планка допустимого фона, так что та китаянка, которая залезла в багажный сканнер в аэропорту везла по всей видимости
Голоса 20 века
Послушал несколько записей, прикладываю. Невозможно удержаться от того, чтобы приложить ещё и запись голоса Николая Второго, его никто не пародирует, но с него начинался двадцатый век.
Надо сказать местами попадание точное, в других же случаях комики ударяются в гротеск, карикатуру.
Я вовсе не нападаю на комиков, они всегда показывают не человека, а его народную память, иначе все решат, что не похоже. И чем реже оригинал появляется в телевизоре, тем более гротескными становятся в памяти его черты. Но всё же иногда хочется услышать именно оригинал.
Квантовые компьютеры
Долгое время я почти не интересовался квантовыми компьютерами — они существовали лишь в мире идей, причём идей сложных, что из этих идей удастся воплотить на практике в ближайшее время понятно не было.
Тем не менее, глаз цеплялся
А в прошлом году компания «АйБиЭм» предоставила удалённый доступ к своему квантовому компьютеру всем желающим — достаточно было записаться и дождаться своей очереди (назад во времена майнфрэймов, хаха). И я решил узнать в подробностях что же такое квантовые компьютеры — куда идёт этот поезд и надо ли на него запрыгивать.
Прочитал несколько статей, посмотрел пару эмуляторов (один из эмуляторов на скриншоте выше) и вот какой вывод сделал.
Квантовые компьютеры в данный момент не являются самостоятельными устройствами — это специализированные чипы, вроде ЦСП, так что правильнее было бы их назвать не компьютерами, а сопроцессорами.
Квантовые сопроцессоры (КС) интересны тем, что имеют колоссальное преимущество в скорости выполнения отдельных алгоритмов, их появление — угроза многим алгоритмам криптографии, например, старичку RSA. Задача перебора его ключей не по плечу классическим компьютерам за разумное время, но с ней справится квантовый сопроцессор с достаточным количеством кубитов.
Думаю появление на рынке гибридов — обычных компьютеров с КС, уже не за горами, а там чипы обрастут соответствующими АПИ, мясом и встроятся в обычные распространённые языки программирования. Специализированные языки программирования уже существуют.
Кажется квантовые компьютеры компании
99 бутылок: Postscript
62. Postscript — интерпретируемый стековый язык программирования. Предназначен для стандартизации вывода документов на различные устройства.
Люди на нём программы пишут крайне редко, в основном это делают другие программы — например, при печати на принтер. Этот же язык программирования используется внутри формата PDF.
Язык строго типизирован, система типов включает: целые числа, числа с плавающей запятой, логический тип, строку, массив, процедуру, словарь и имя. Для всех операций используется стек и обратная польская запись.
%!
%%Title: (Beer song)
%%Creator: Evgeny Stepanischev
%%EndComments
/beer % (int) -> (int)
{
dup 0 eq {
(no bottles) print
} {
dup 1 eq {
(1 bottle) print
} {
dup //=string cvs print ( bottles) print
} ifelse
} ifelse
} bind def
99 -1 1 {
beer ( of beer on the wall, ) print beer (\n) print
(Take one down and pass it around, ) print
dup 1 sub beer pop
( of beer on the wall.\n\n) print
} for
(No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.) print
quitФизиологическая обувь
В вузе я занимался спортивной гимнастикой и заработал травму спины. Прошло более 20 лет, но меня всё ещё это беспокоит и я хочу поговорить об этом.
Конечно такой травмой нельзя не заниматься и помимо различных общеизвестных методик (врачи, массаж) я иногда пробую
Купил две пары — демшанские «Скечерсы» (модель «Шейп Ап») на «Ебее» и более дорогую обувь марки «Джоя», в Казани есть их магазин. Взял модели сразу двух производителей — вдруг особенности одной пары помешают мне ощутить пользу, заодно хотел определить стоит ли в будущем платить больше.
Хотел бы сказать, что у меня есть чёткие выводы, но увы. Носил сначала «Скечерсы», потом «Джою». Что я точно заметил — по всей видимости у меня очёнь жёсткий шаг на пятку, та и другая обувь это хорошо компенсирует («Джоя», пожалуй, получше) — у обеих моделей мягкая пятка и поначалу я отчётливо чувствовал как меня подбрасывает при ходьбе.
Самое главное — не могу определить стало ли лучше спине. Для чистоты эксперимента следует наверное на полгода перейти на традиционную подошву, но это не раньше, чем сношу обе пары —
Татарстанские деньги
Годы назад таксист, который вёз меня из Самары в Казань с конференции «404», поразил до глубины души своей дремучестью, спросив какие в Казани деньги.
Вспомнил эту историю, потому что в выходные ездил помахать металлоискателем над фундаментом свежесрытого дома — знакомый купил участок в деревне под Казанью и нашёл, в числе прочих находок, татарстанский жетон — самые настоящие «казанские деньги».
Татарстанские жетоны и купоны — суррогантое платёжное средство, которое в девяностые годы выдавались по программе социальной защиты населения. Жетоны были «хлебные» (как на фото) — на них покупали продукты и «топливные» — с нефтяной качалкой на реверсе, ими оплачивали ЖКХ и покупали бензин.
Не помню, чтобы я пользовался жетонами, а вот купоны помню — я тогда был студентом и нам их выдавали в Университете. Купить на них можно было только продукты. А чтобы умные люди не меняли их на деньги, покупая на купон коробок спичек, через
«Википедия» утверждает, что татарстанские купоны — уникальная вещь, так как собственные
Сороковой выезд
В прошлые выходные ездил посмотреть не найдётся ли
Итак, что нашлось. Монета 3 копейки конец 19—начало 20 века, 2 копейки 1899, 2 копейки 1916, советская серебряная монета 10 копеек 1928 года, 20 копеек 1931 («щитовик»), 3 копейки 1931, 2 копейки 1939, 15 копеек 1941, 20 копеек 1945, 20 копеек 1946, 2 копейки 1951, 5 копеек 1953, 10 копеек 1954, 10 копеек 1957, 3 копейки 1957, татарстанский хлебный жетон.
Обручальное кольцо, две «конины», сломанный крестик,
Гигиена истории поиска
Развитие контекстной рекламы и необходимое для этого хранение привязанной к пользователю истории поиска, привело к новым шаблонам поведения — я уже на автомате выбираю в какой вкладке
Если есть хоть малейшее подозрение, что потом это ляжет в историю поиска несмываемым пятном, я открываю приватную вкладку.
Очень интересно, многие ли так поступают? Никаких исследований на эту тему найти не удалось.
Особенность языка Postscript
Есть вы вдруг заинтересовались и прочитали программу «99 бутылок» на Постскрипте, то даже при полном незнании языка, примерно понятно где у него аналоги функций, блоков, ветвлений и прочих сущностей.
Единственная конструкция, которая должна смущать, это место, где происходит печать числа:
% печать числа
//=string cvs printДело в том, что операторы show и print, принимают на вход только строку, поэтому число на входе надо преобразовать. Для этого используется оператор cvs, на мой взгляд очень странный — он требует не один, как можно было бы ожидать, а два параметра — число, которое будет преобразовано и строку, которую оператор снимет со стека и положит вместо неё преобразованное в строку число. Причём по размеру строка должна быть не короче, чем строковое представление числа, которое мы надеемся преобразовать. Иначе мы получим ошибку «rangecheck». Видимо строковый параметр используется как
Чаще всего cvs используется так (правда это прямо запрещено стилем кодирования Постскрипта, рекомендуется использовать не готовую строку, а формировать пустую строку оператором string, но всё равно широко встречается):
% печать числа 42
42 ( ) cvs printКладём на стек «42», потом строку из двух пробелов (скобки задают строку в Постскрипте), далее вызываем cvs, которая берёт со стека два значения, работает с ними и кладёт обратно строку, содержащую преобразованное число, print берёт значение со стека и выводит в консоль.
Но если места нужно много, нередко используют оператор =string, который кладёт на стек буфер в 128 байт, его хватит всем — таких больших числе в языке нет, любое гарантированно поместится:
% печать числа 10000000000, cvi нужно, чтобы преобразовать плавающее 1e+10 в целое
1e+10 cvi =string cvs printПока, надеюсь, всё просто и понятно. Далее надо знать такую вещь. Конструкция «{…}» кладёт на стек специальный тип — исполняемый блок, посмотрим как он выглядит на стеке:
% посмотрим как выглядит исполняемый блок на стеке:
{1e+10 cvi =string cvs print} ==
% выведет {1e+10 cvi =string cvs print}Оператор «два равно» берёт значение со стека и выводит его на экран. Как видим блок попал на стек в неизменном виде. И вот тут можно сделать микрооптимизацию — если этот кусок кода кладётся не на стек, а в словарь (можно считать, что будет создана именованная функция) и мы рассчитываем вызвать его несколько раз, вызов =string можно сразу раскрыть в строку — это делается двумя слешами.
Два слеша — специальная конструкция, которая похожа на вызов анонимной функции по месту определения, в данном случае мы выполняем ровно один оператор и на стеке внутри блока кода мы увидим не вызов, а порождённую им строку:
{1e+10 cvi //=string cvs print} ==
% выведет {1e+10 cvi (x255Unicode\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000...) cvs print}Не вымыл лицо — спас дерево
Чёрт возьми, помешались все на экономии бумаги в общественных туалетах! Скажите — в них никто не моет ничего, кроме рук или есть
Две раздражающие частности в PHP
В ПХП немало глобальных проблем, которые многих раздражают, об этом написано много статей. Но есть две частные проблемы, два примера неинтуитивного поведения, которые рождают досадные баги на ровном месте. Они раздражают лично меня.
На текущем месте я работаю более шести лет и прежде чем у нас появилось ревью кода до пуша, в общую ветку регулярно попадали результаты недопонимания работы двух функций, которые порой рождали весьма причудливые баги.
Первый относится к функции exec. Свой второй параметр она получает по ссылке и выводит туда массив строк, которые выдаёт запускаемая команда. Беда возникает в следующем коде:
exec('1st command', $out, $ret);
// … проверяем $ret, делаем что-то полезное с $out
exec('2nd command', $out, $ret);
// … проверяем $ret, делаем что-то полезное с $outДело в том, что вторая команда exec не очистит второй параметр и добавит в него вывод второй команды. Таким образом вызов двух команд склеится, а это не то, что мы обычно ожидаем.
Такое поведение описано в руководстве и возможно это полезно для цикла с накоплением, но в общем случае контринтуитивно.
Второй раздражающей частностью является результат работы array_unique. Опять же, особенность описана в руководстве, но про неё нередко забывают: эта функция сохраняет ключи массива. Вот как это выглядит на практике:
var_dump(array_unique([1,1,2]));
/* array(2) {
[0]=>
int(1)
[2]=>
int(2)
} */В случае ассоциативного массива претензий нет, это необходимо, возможно есть случаи, когда это полезно и для обычного массива, но чаще всего пропуски в ключах мешают в самых неожиданных местах.
Самый замысловатый баг, который я помню был таким. Результирующий массив превращался в джейсон-строку и передавался микросервису на Гоу. Чаще всего значения были уникальными и всё работало как ожидается.
Но однажды звёзды сошлись так, что уникальность нарушилась и в результате работы array_unique в массиве появились пропуски. В обычный массив такое в джейсоне превратить нельзя, поэтому ПХП сделал из него объект с числовыми ключами. Гоу такое не простил — у него статическая типизация и в него нельзя пихать всякое.
Микросервис выдал ошибку в лог, данные не принял. У тестеров возникла очень странная ошибка, которая повторялась
Увы, но документацию к языкам сейчас никто подробно не читает, а если читает, то такие особенности не помнит — такова данность и ничего не изменить. Хотелось бы чтобы в языках было меньше такого поведения, либо чтобы специализированные редакторы
Парфенон
Леонид Парфёнов неожиданно (для меня по крайней мере) начал вести очень качественный видеоблог, видео выше — уже четвёртый выпуск.
МОСКИТО
В детстве у меня были другие хобби — в основном собирал всякие электронные схемы, вполне традиционные, из журнала «Радио». Но не обходилось и без экспериментов. С тех пор я знаю, что советская бритва, будучи засунута в почти исчезнувшую сейчас радиорозетку, становится плохенькой радиоточкой, а динамик может при необходимости заменить микрофон — давление на диффузор двигает звуковую катушку вдоль магнита, что, в конечном, счёте создаёт небольшой ток ну и так далее.
Ребята из Университета имени Давида
В аудиокартах на основе распространённого чипа Реалтек и многих других есть возможность программно переключать тип порта с аудиовыхода на вход и наоборот. Оказалось, что если порту, куда воткнуты наушники или подключен динамик, сменить тип с выходного на входной, то можно слушать, что происходит вокруг.
Исследователи разработали протокол для обмена информацией между двумя не связанными близкостоящими компьютерами, пользуясь только их динамиками и/или наушниками. Передача происходит на частотах в диапазоне близких к ультразвуку — 18—24 кГц, большинство людей такое уже не слышит.
На картинке для привлечения внимания — спектрограмма
Дистанция, конечно, невелика — метры, да и скорость не радует — лучший результат
В реальной жизни компьютер только с наушниками или динамиками может сливать ваш разговор в сеть в реальном времени. Так что параноикам есть о чём задуматься.
Сдутие таблиц без блокировки
Братишка прислал ссылку на интересную статью — «Reducing bloat without locking». Речь идёт о так называемом «распухании» (bloating) таблиц в «Постгресе».
Подробно суть в трёх предложениях не объяснить, если вкратце, то механизм изоляции в транзакциях у «Постгреса» устроен так, что при обновлении и удалении строк в таблицах могут образовываться «дыры», которые увеличивают общий объём таблицы. Если происходят вставки или обновления и новые данные помещаются в неиспользуемое пространство, то «дыры» могут со временем заполняться. Но иногда «дыр» остаётся много и это проблема с которой надо
Вот например создадим таблицу из тысячи строк, посмотрим сколько страниц она занимает, потом удалим половину строк и снова посмотрим количество занятых страниц:
test=> CREATE TABLE test AS SELECT generate_series(1, 1000) id;
SELECT 1000
test=> SELECT MAX(ctid) FROM test;
max
--------
(4,96)
(1 row)
test=> DELETE FROM test WHERE id & 1 = 1;
DELETE 500
test=> SELECT MAX(ctid) FROM test;
max
--------
(4,96)
(1 row)ctid — это специальный внутренний столбец «Постгреса», который отображает физическое расположение строки. Для каждой строки в нём записано два числа — номер страницы, где располагается строка и порядковый номер строки в странице.
Как видим, таблица «распухла» — половина строк удалена, а количество занимаемых страниц не изменилось. Что же можно сделать? Давайте попробуем команду VACUUM:
test=> VACUUM VERBOSE test;
INFO: vacuuming "public.test"
INFO: "test": found 0 removable, 500 nonremovable row versions in 5 out of 5 pages
DETAIL: 0 dead row versions cannot be removed yet.
There were 500 unused item pointers.
Skipped 0 pages due to buffer pins.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUMУвы, ничего не изменилось — она умеет урезать страницы только если они находятся в конце и полностью свободны.
Что же делать? Можно выполнить VACUUM FULL — эта команда полностью перельёт таблицу на новое место, избавив нас от «дыр», но во время работы таблица будет эксклюзивно заблокирована, для больших таблиц, да ещё в продуктиве это непозволительно.
Другой способ — перенести строки с последних страниц в «дыры» на первых, освободив таким образом несколько страниц в конце. Попробуем:
test=> BEGIN;
BEGIN
test=> UPDATE test SET id=id WHERE ctid>='(3,0)';
UPDATE 161
test=> UPDATE test SET id=id WHERE ctid>='(3,0)';
UPDATE 161
test=> UPDATE test SET id=id WHERE ctid>='(3,0)';
UPDATE 48
test=> UPDATE test SET id=id WHERE ctid>='(3,0)';
UPDATE 48
test=> UPDATE test SET id=id WHERE ctid>='(3,0)';
UPDATE 34
test=> UPDATE test SET id=id WHERE ctid>='(3,0)';
UPDATE 0
test=> COMMIT;
COMMITВ одной транзакции мы обновили все строки, которые располагаются на первой странице и дальше. Попробуем теперь сделать VACUUM:
test=> VACUUM VERBOSE test;
INFO: vacuuming "public.test"
INFO: "test": removed 452 row versions in 2 pages
INFO: "test": found 452 removable, 500 nonremovable row versions in 5 out of 5 pages
DETAIL: 0 dead row versions cannot be removed yet.
There were 469 unused item pointers.
Skipped 0 pages due to buffer pins.
0 pages are entirely empty.
CPU 0.00s/0.00u sec elapsed 0.00 sec.
INFO: "test": truncated 5 to 3 pages
DETAIL: CPU 0.00s/0.00u sec elapsed 0.00 sec.
VACUUMКак видимо команда удалила две неиспользуемые страницы и уменьшила общее количество страниц с пяти до трёх.
Идея, описанная в статье, лежит в основе скрипта pgcompacttable из инструментария компании «Дейта Игрет».
Переезд на PHP7
В почте попросили описать переезд на ПХП7, с какими сложностями встретились, как они решались. Опишу, пока не забыл — я этим занимался почти в одиночку, так как задача не была приоритетной. Я считал, что мы сможем получить хороший прирост производительности, поэтому сам её и делал в свободное время.
Если кому интересно, загруженность серверов, где крутится ПХП, действительно упала, примерно в 1,5—1,7 раза.
Вообще говоря, у ПХП есть довольно детальные описания того, что может пойти не так при смене версий, достаточно заглянуть в раздел «Изменения, ломающие обратную совместимость» нужной версии. Там можно сразу прикинуть что придётся поменять в коде, если вы хорошо его знаете.
Ниже мой собственный опыт.
Сначала я составил список всех модулей ПХП, которые у нас используются — натурально выписал из зависимостей пакета нашего продукта в табличку в местной «вики». На тот момент не все модули поддерживали «семёрку», поэтому к табличке я иногда возвращался и вносил изменения, если они случались.
Когда в табличке без поддержки остался единственный модуль ctwig от шаблонизатора «Твиг», решил, что без него мы можем обойтись — к этому времени в интернете появились замеры скорости и «Твиг» без модуля под «семёркой» демонстрировал похожие результаты с «пятёркой» и модулем.
Дальше я проверил не используются ли у нас
find . -type f \( -name '*.php' -o -name '*.inc' \) -exec php -l {} \; |
fgrep -v 'No syntax errors'У нас, к слову, было несколько таких мест — например, был объявлен класс с разными полезными штуками для обработки строк, который назывался String. Так больше нельзя — зарезервированное слово.
Посложнее с обработкой исключений — класс Exception перестал быть базовым и если требуется ловить все исключения, то в «семёрке» лучше всего перехватывать всё, что реализует интерфейс Throwable.
У нас необработанные кодом исключения ловятся и пишутся в логи, для этого в нескольких местах кода есть перехват всего подряд. Выглядело это примерно так:
try {
// … какой-то код
} catch (Exception $e) {
DI::log->get('exception')->error($e);
throw $e;
}Несложными регулярками поискал различные непрямые выражения, там теперь тоже есть разница, нашёл всего несколько штук и поправил.
Потом я
Далее в дело вступили тестеры и программисты — в основном были исправления, связанные с тем, что в «семёрки» некоторые вещи устарели, ничего сверх этого я не припомню.
В целом мне кажется, переход прошёл безболезненнее, чем можно было бы ожидать —
Пушит
Читаю «Письма из деревни» Александра Николаевича Энгельгардта — это оформленные в виде книги довольно обстоятельные письма, которые Александр Николаевич слал, начиная с 1872 года, в журнал «Отечественные записки». Прекрасное описание жизни деревни после выхода «Положения» — реформы 1861 года, отменяющей крепостное право.
И вот там, в пятом письме я неожиданно встречаю:
На что уже начальник железнодорожной станции — и кокарды у него нет, только красная шапка, — а и тот считает себя начальником над всеми пассажирами пришедшего поезда. А генерал
какой-нибудь из Петербурга, тот всех считает своими подчиненными и при случае пушит начальника станции за остановку поезда.
Слово «пу́шит» мне знакомо — программистский жаргонизм от глагола «push». «Пушить» — передать изменения локального репозитория в удалённый. Но как оно попало в 19 век?
Оказывается это слово «пуши́т», однокоренное со словом «пух». «Пуши́ть» — вздымать, делать пушистыми волосы, а так же упрекать, бранить, делать выговор.
Казанская страховая доска ★
Страховые доски — металлические таблички, которые до революции крепились на фасад застрахованного строения (или над дверью застрахованной квартиры). Они всё ещё попадаются на старинных зданиях в российских городах, но всё реже — за ними охотятся коллекционеры.
Предпоследняя, довольно известная в Казани страховая доска висела на улице Волкова, но в прошлом году я заметил, что её нет на прежнем месте — говорят выкупил у хозяев известный в Казани коллекционер. Большинство сохранившихся досок сейчас в плачевном состоянии — без краски, ржавые,
Узнать местоположение последней страховой доски оказалось непросто, возможно поэтому коллекционеры пока до неё не добрались. Даже зная примерный адрес, нашёл только через полчаса поисков. Доска маленькая, сильно заржавела, пришлось занимать объектив у приятеля, чтобы снять.
Написано там следующее: «въ обществѣ РОССІЯ застраховано». На фоне — почти уже незаметная восьмиугольная звезда, намёк на икону «Неопалимая Купина». «Неопалимая Купина» почитается как заступница при пожарах, так что такая страховая доска одновременно играла ещё и роль оберега.
Дополнение: позже оказалась, что эта страховая доска вовсе не последняя.
Установка Lubunta 12.10 на Toshiba AC100
Избавляюсь потихоньку ото всяких гаджетов, которые не используются, а только собирают пыль дома. В прошлом году самое габаритное в сердцах вынес на помойку, а в этом распродаю менее объёмные вещи.
Дошла очередь до так называемой «тошки» — смартбука Toshiba
Так он у меня и лежал несколько лет. За это время в интернете потихоньку попротухали ссылки на необходимый для перепрошивки софт и инструкции, так что пришлось потратить полдня и натащить с миру по нитке. Для прошивки я использовал Виндоуз. Последовательность такая:
- Заряжаем «тошку» до упора
- Скачиваем утилиту Nvflash под Виндоуз, распаковываем
куда-нибудь - Отключаем проверку цифровой подписи на Виндоузе
- Подключаем «тошку» через
мини-ЮСБ (маленький разъём справа), нажимаем Ctrl+Esc+Power, должна загореться лампочка, экран останется тёмным - Ставим драйвер устройства APX, который есть в скачанном архиве. Если Виндоуз сама не спросит, идём в «Диспетчер устройств», устанавливаем оттуда
- Скачиваем два файла «Лубунты» — с расширениями bootimg и tar.gz
- Файлы, который заканчивается на bootimg переименовываем в new.img, кладём к распакованному архиву, который мы скачали на шаге №2 и запускаем flash_new.cmd
- После окончания процесса, выключаем «тошку»
- Берём SD-карту, записываем на неё скачанный файл с расширением tar.gz (занимает около 413 мегабайт)
- Вставляем карту в «тошку», включаем, начинается процесс установки «Лубунты», ставим, там ничего сложного, тачпад может не работать, это нормально, потом заработает
По большому счёту, это всё. Остальное — оптимизации: можно более оптимально настроить файл подкачки, установить проприетарные драйвера видеокарты, заставить работать верхний ряд горячих клавиш, но без этого всего жить можно.
Дочка
Читая время спустя свои записи, обычно сильно жалею, что мало пишу о своей жизни — именно это спустя годы читать интереснее всего. Поэтому напишу, пожалуй, про дочку. Снимок ниже августовский, дочке на нём около годика.
Очень интересно наблюдать как человечек, который полтора года назад и ползать не умел, уже носится по дому с визгом. Всё больше пользуется многосложными предложениями — с двумя и (сильно реже) больше словами. Недавно прошли
Очень нравится музыка, песни, потихоньку начинает подпевать — бо́льшая часть слов свои собственные, но часть проговаривается чисто (например, поёт «облакааа», потом отсебятина). Так же любит рисовать — красками и фломастерами, лепить. Недавно лепили грибочек, у меня посмотрела как делается, пристойно слепила свой, подошедшая жена не смогла точно сказать где лепил я, а где дочка.
Что пока сама не делает — не ест, если дать ложку, то пару раз зачерпнёт и считает, что поела.
Одно время стали интересны буквы — различала «А», «О», некоторые другие, сейчас интерес
Не оттащишь от горок, каруселей и прочих качелей — это давняя любовь, но с ростом самостоятельности моё беспокойство растёт, недавно купили беговел, сразу взяли шлем. Правда беговел пока не оценила.
Вообще отцовство новый, трудный, но очень позитивный опыт, изменилась вся жизнь целиком, распорядок, привычки, приходится к жизни
Баг ★
Принято считать, что слово «баг» появилось 9 сентября 1946 года, когда Грейс Хоппер, которая работала в тот момент в Гарвардском университете с ЭВМ «Марк II», проследила ошибку в работе программы до реле машины, куда попал мотылёк. Грейс вклеила насекомое в технический журнал, сопроводив шуткой «Первый реальный случай обнаружения жучка» («First actual case of bug being found»).
На самом деле это одна из версий проникновения термина в среду компьютерщиков. В выпущенном в 1892 году «Стандартизованном словаре электротехники» можно прочитать:
Баг — это любая неисправность или дефект в электрических соединениях или работе электрических аппаратов
Как видим слово появилось раньше 1946 и даже не в 20 веке. По одной из версий термин придумал и популяризировал Томас Эдисон — известный американский предприниматель, Стив Джобс своего времени.
В своих письмах и дневниковых заметках он нередко употребляет это слово. Выше — скан его письма от 3 марта 1878 года (оригинал можно купить за пару тысяч долларов). В пятой строчке, сразу после артикля, написано «bug».
Употреблял ли Эдисон это слово в знакомом нам значении? Да! Так 18 ноября 1878 года он написал Тивадару Пушкашу (венгерскому учёному, физику, и изобретателю первой в мире телефонной станции):
Так было со всеми моими изобретениями. Первый шаг — интуиция, которая приходит как вспышка, затем возникают трудности — устройство отказывается работать, и именно тогда проявляются «баги» — как называют эти мелкие ошибки и трудности — и требуются месяцы пристального наблюдения, исследований и усилий, прежде чем дело дойдёт до коммерческого успеха или неудачи.
Так что термину в этом году исполняется по меньше мере 140 лет.
Переезд на «Эгею»: впечатления
Шестого февраля мой блог переехал на «Эгею», пишу об этом, потому что сегодня возвращал
Пользуясь случаем, хочу сказать Илье Бирману, моему давнему другу, больше спасибо за приятный дизайн интерфейса «Эгеи»! Это кайф! Мне снова стало приятно писать в блог, думаю читатели это почувствовали, и вообще ощущение такое, будто я его помыл с порошочком и от него отвалились куски грязи, он помолодел и стал секси!
Если думаете какой движок блога выбрать, обязательно обратите внимание на «Эгею», тем более, что его можно попробовать в действии на специальном
PHP8 ★
Пока всё прогрессивное человечество переходит на ПХП7, а менее прогрессивное до сих пор чахнет
В официальной вики есть страница, где можно ознакомиться с довольно пока скудным списком предложений на восьмую версию. Меня больше всего заинтересовали два изменения, серьёзно ломающие обратную совместимость:
Изменение оправдано унификацией синтаксиса — сейчас используемая сущность выводится из контекста, скажем статические свойства начинаются с доллара, а методы — нет, но если имя метода хранится в переменной, синтаксис разваливается — нет способа указать что же имел ввиду программист.
Или вот похожий пример с константой:
class Sample
{
const test = 'const';
public static $test = 'variable';
}
$test = 'test';
// что ты такое?
var_dump(Sample::$test);
// на самом деле вернётся «variable», очевидно; константу придётся получить так:
var_dump(constant("Sample::$test"));В действительности можно было бы выкрутиться скобками (сейчас так можно вызывать анонимную функцию, записанную в свойство класса), не знаю рассматривали ли такой вариант, но возможно он менее интуитивен.
// так можно было бы получать константу по имени в переменной (не работает!)
var_dump(Sample::($text));Самым серьёзным внутренним изменением нового релиза, вероятно будет добавление JIT, Дмитрий Стогов, человек, которому мы обязаны фантастическим ускорением в «семёрке», ещё в позапрошлом году написал в рассылку php.internals, что работа над динамической компиляцией начата. Получившийся к тому времени прототип показал 20% прироста на синтетических тестах и снижение производительности на реальных приложениях.
Кстати, это не первая попытка совместить динамическую компиляцию и ПХП, в языке HHVM, диалекте ПХП от «Фейсбука», такая компиляция даёт хороший прирост в скорости. Да и Дмитрий сотоварищи ещё
Более свежий тест того, что будет в ПХП8 показывает, что на трёх тестах (два стандартных зендовских теста и построение множества Мандельброта) динамическая компиляция уделывает версию 7.1.0 примерно вдвое. Это отличный результат! Но понятно, что в реальной жизни всё будет скромнее.
Когда же выйдет «восьмёрка»? Дата, увы, неизвестна, но есть предположение, что новую мажорную версию вряд ли можно ожидать раньше сентября 2021 года.
Банан велик, а кожура еще больше
Много
А тут братишка прислал в «Телеграм» кусок кода, который всплывает на «Стек Оверфлоу» не первый год:
console.log(0 >= null); // выведет true
console.log(0 > null || 0 == null); // выведет falseСтранное поведение, как ни крути, ведь даже название операции «больше или равно» раскладывается на две — либо «больше», либо «равно». Казалось бы оба варианта должны давать одинаковый результат.
Решил я полюбопытствовать есть ли объяснение этому феномену.
Во всех браузерах работает одинаково странно, а это значит, что
Let r be the result of performing abstract relational comparison lval < rval
If r is true or undefined, return false. Otherwise, return true
Что означает примерно следующее: если нам надо выполнить операцию
Не вырубишь топором
Как известно, в блоки биткойна можно вложить какую угодно информацию. Вот к примеру её можно кодировать, последовательно скидывая минимальные суммы на фейковые кошельки, записывая в их номере необходимую бинарную последовательность. По этому поводу в январе писал своему другу в «Телеграм»:
А вчера он мне кинул ссылку на статью «Биткоин под угрозой полного запрета: В его блокчейне найдены образцы детской порнографии»:
Ученые
из Рейнско-Вестфальского технического университета Ахена в Германии обнаружили, что блокчейн биткоина используется для хранения изображений, относящихся к разряду детской порнографии. Также в блокчейне присутствуют ссылки на изображения жестокого обращения с детьми, размещенные на других ресурсах. Это может сделать хранение биткоинов незаконным в тех странах, где детская порнография запрещена.
Мне непонятно что с такой угрозой теперь делать. Обычная практика в таких случаях — подчистки («хардфорки»), то есть отматываем историю назад и вшиваем в клиент информацию о том где у нас правда.
Но тут она вряд ли годится — раз
99 бутылок: SCSS
63. SCSS — язык шаблонизации для файлов CSS. Я написал реализацию «99 бутылок» на нём ещё в 2012 году, но по неизвестной причине так никуда и не выложил. Возможно к лучшему — посмотрел свежим взглядом и исправил несколько неточностей.
Язык полностью процедурный, с примитивными типами (есть массивы, включая ассоциативные и собственный тип — «цвет»), поддержкой интерполяции в строках и с массой своих особенностей, диктуемых областью применения.
Шаблонизатор не имеет обособляющих элементов (типа двойных фигурных скобок), его конструкции «живут» прямо в коде, который генерируется, поэтому иногда нужно ставить немного уродливые подпорочки — например, символ деления используется и в математической операции, и в синтаксисе таблиц стилей, так что иногда приходится указывать что имеется ввиду.
Переводы строк пришлось оставить в строках как есть, поскольку, по всей видимости, нет никаких специализированных управляющих последовательностей для этого — в практике такой задачи не встречается.
@function bottles($beer) {
@if $beer == 0 { @return "no bottles" }
@if $beer == 1 { @return "1 bottle" }
@return $beer + " bottles"
}
@function beer($beer) {
$b: bottles($beer);
@return "#{ $b } on the wall, #{ $b }.
Take one down and pass it around, " + bottles($beer - 1) + " of beer on the wall.
"
}
$result: "
";
@for $i from 99 through 1 {
$result: $result + beer($i)
}
@debug $result +
"No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall."Машина
В книге «Письма из деревни» Энгельгардта, о которой я уже упоминал, персонажи нередко разъезжают на машинах, хотя на дворе
Вот только одно упоминание, в пятом письме:
Наверное легко догадаться, что «машинами» в таком контексте тогда называли паровозы. В те времена их как только не называли — «самокатная паровая машина», «паровая фура», «паровая телега», «паровой экипаж», «паровая карета», «пароходка» и даже «пароход».
Вот что пишет Виктор Одинцов в своей книге «Лингвистические парадоксы» об истории более привычного нам названия:
Но в 1836 г. в связи с предстоящим открытием Царскосельской железной дороги и приобретением первых локомотивов в петербургской газете «Северная пчела» в № 223 от 30 сентября сообщалось: «Немедленно по прибытии паровых машин, которые для отличия от водяных пароходов можно было бы назвать паровозами, последуют опыты употребления их…» Наш современник, известный лингвист Ю. С. Сорокин считает, что редактор газеты Н. Греч, немец по происхождению, создал слово паровоз по образцу соответствующего немецкого слова.
Кстати, паровозы сошли с арены только к концу
Правда некоторые действуют до сих пор — как аттракцион или на манёврах в железнодорожных депо и узлах.
Так в 2012 году мы с женой проехались на таком аттракционе при посещении Музея железнодорожного транспорта Московской железной дороги. Кстати, в высшей степени рекомендую этот музей, упомянутая поездка не слишком запоминающаяся, но вот экспонаты — огромные старинные паровозы, я помню до сих пор, сильное впечатление.
Оригами: лягушка
По первому попавшемся видео в интернете сделал первые в своей жизни три прыгающие лягушки из бумаги. В школе
Первая версия из обычной бумаги, с нарисованными глазами своими прыжками произвела бомбический эффект — дочка хохотала несколько минут, как безумная. Более капитальные поделки из зелёной бумаги с игрушечными глазками её едва заинтересовали.
Думаю теперь, что такого из школьного оригами могло бы её так же поразить?
Lubunta 13.04 на Toshiba AC100
Делал недавно предпродажную установку «Лубунты» 12.10 на «тошку» — смартбук «Тошиба
13.10 после установки не нашла точку вайфая, в логах были
sudo sed -i -e 's/us.archive.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
sudo sed -i -e 's/\(.*ports\)/#\1/' /etc/apt/sources.list
sudo apt-get update ; sudo apt-get upgradesudo apt-get install gcc make xdotool wmctrl
cd input-event-daemon; makeУтилиту и конфиг можно положить в
Нашёлся и недостаток. В установленной «Лубунте»
Попробовал поставить «Файерфокс», думал может там проблем не будет, но он еле ворочается. Больше ничего по этому поводу не предпринимал.
Баг в PHP 7.2 с output_add_rewrite_var
Для того, чтобы не подставлять в каждую ссылку и форму глобальные для проекта параметры запроса (идентификатор сессии, например), в ПХП используется техника, называемая Url Rewriting. У нас в проекте так передаётся токен против XSRF — благо есть возможность указать собственные параметры, которые надо передать и даже задать список тегов с атрибутами в которых это будет работать.
И при переходе на ПХП 7.2 словили неприятный баг, который уже поправлен в 7.1.9, но ещё
<?php
output_add_rewrite_var('foo', 'bar');
?>
<a href="index.php">This is link</a>
<a href="#place">This is anchor</a>В первую ссылку «foo=bar» добавится нормально, а во второй это будет не к месту, якорь будет испорчен:
<a href="index.php?foo=bar">This is link</a>
<a href="#place/?foo=bar">This is anchor</a>Наверняка со стандартными сессиями ПХП, передаваемыми в урле, будет тот же результат, но я не пробовал.
Либо надо ждать обновления, либо поставлять вместо якоря текущий полный урл.
Клейма или счётные метки?
Можно подумать, что я забросил одно из своих хобби — изучение казанский счётных меток. Это не так, хоть я ничего об этом и не пишу. Просто не появляется новых клейм или сведений, я фотографирую уже знакомые и даже добавил в свой справочник ещё один источник (к сожалению информации он не добавил).
Ничего нового за последнее время не обнаружилось, тем не менее, я не поделился
Постоянные читатели моего блога знают, что на старинных кирпичах бывают клейма, я много об этом писал, — так производители маркировали свою продукцию. Клейма ставились
Помимо клейм на кирпичах встречаются так называемые «счётные метки», которые наносились кустарно (скорее всего тем, что было под рукой — прутиком
Их рисовали кто во что горазд, от незатейливых точек, до листочков и прочего творчества — у каждого счётчика были


А вот отметины на снимках выше загадочны тем, что совершенно неясно что это такое. Найдены они в своде здания первой половины
Эти отметины явно наносились как клейма —
Я пока больше склоняюсь к версии клейм — тяжело представить, что при счёте партии
Телеграм приуныл
«Телеграм» не работает около сорока минут, а в фейсбуке уже расползаются теории, что это российская блокировка. Я написал нескольким приятелям со всего мира, у всех такие же проблемы. В официальном твиттере так же указано, что проблемы по всему миру.
Яндекс.Аллергия
«Яндекс» в рамках сервиса Погоды выкатил полезную вещь, за которую я, сезонный аллергик, хочу сказать огромное спасибо — мониторинг распространения аллергенов на территории России.
Если зайти туда сейчас, то появится надпись, что
Интонационное ударение
Я тут на днях вынужден был сильно удивиться, узнав, что некоторые люди не знают о существовании интонационного ударения. Я о нём узнал в школе, на обычном уроке русского языка и считал частью школьной программы, а вот поди ж.
Интонационное ударение ставится, чтобы указать место, где в речи мы выделили бы слово интонацией. В стихотворении Лермонтова о Бородине есть строчки:
Вам не видать таких сражений!..
Носились знамена, как тени,
В дыму огонь блестел,
Звучал булат, картечь визжала,
Рука бойцов колоть устала,
И ядрам пролетать мешала
Гора кровавых тел.
Фраза «рука бойцов колоть устала» ушла в народ и её, не зная контекста, можно прочитать двояко:
В скобках у меня как раз интонационное ударение, от обычного оно отличается не графически, а местом использования. Если перед вами не словарь и не детская книжка и на обычном слове стоит ударение в привычном месте, то оно интонационное.
Помимо устранения неоднозначностей, подобных вышеописанному, интонационное ударение так же используется для усиления: нейтральное «что я сказал?» можно усилить до «что́ я сказал?», а в нём сместить акцент: «что я́ сказал?», «что я сказа́л?».
Структуры и CGO
Обновление: в комментариях в Фейсбуке мне бывший коллега попенял, что я забыл Си и что поведение правильное — тут объявляется анонимная структура, а потом к ней определяется тип. Верно, практики на Си у меня за последние годы почти не было, вымылось всё из памяти. Так что текст ниже читайте с учётом этого обновления заметки.
Каждый раз расстраиваюсь, когда сталкиваюсь с CGO.
Документация говорит нам, что сишные структуры доступны в Гоу через конструкцию C.struct_name, а её размер — через C.sizeof_struct_name.
Я так и пытался сделать и получал ошибки:
package main
/*
typedef struct {
int x, y;
} test;
*/
import "C"
import . "fmt"
func main() {
Println(C.struct_test{}) // «{}»? Что за…
Println(C.sizeof_struct_test) // could not determine kind of name for C.sizeof_struct_test
}Упрощённый код выше кратко иллюстрирует проблему. В первом случае никакая ошибка не выводится (что ещё больше сбивает с толку), но структура
Оказывается, и я набрёл на это случайно, в ходе экспериментов, struct просто не надо писать, тогда всё будет работать:
Println(C.test{}) // «{0 0}»
Println(C.sizeof_test) // 8Если будет время, ещё поизучаю этот вопрос — посмотрю историю коммитов и всё такое, возможно была
Структуры в Си и CGO
По горячим следам хочу написать какая забытая мною особенность языка Си вчера ввела меня в заблуждение и почему несмотря на то, что я работал с сишной структурой, CGO так как будто не считало.
Для начала посмотрим как определяются и передаются структуры в Си. Полную спецификацию я приводить не буду, посмотрим на два распространённых способа. Первый используется в этом небольшом примере:
#include <stdio.h>
#include <math.h>
struct point {
double x, y;
};
double point(struct point p) {
return sqrt(pow(p.x, 2) + pow(p.y, 2));
}
int main() {
printf("%g\n", point((struct point){1, 2}));
}Тут можно обратить внимание на две особенности —
Это происходит потому, что имена структур обитают в своём собственном пространстве имён, на его использование и указывает struct. Там же живут имена объединений (union) и перечислений (enum). Имена функций находятся в общем пространстве, так что два таких определения с одним именем друг другу не мешают.
Структуры, объявленные таким образом видны через CGO компилятора Гоу как C.struct_name (C.struct_point в данном случае). К сожалению, тут есть особенность, о которую я споткнулся — если запрашиваемая структура не определена, то Гоу не выдаст ошибки, мы просто получим пустую структуру:
package main
import ("C"; . "fmt")
func main() {
Println(C.struct_undefined{}) // ошибки не будет
}Но программисты — люди ленивые, писать всюду struct неудобно. К счастью есть способ этого не делать — можно завести структуру, а потом дать ей имя в пространстве всех остальных типов. Это делается при помощи ключевого слова typedef позволяющего создавать алиасы типов:
struct point {
double x, y;
};
typedef struct point point;Теперь у нас есть два имени для одного типа — один в пространстве структур и прочего, второе — в общем пространстве. Можно даже сделать их одинаковыми, что очень удобно. Если второе имя нам ни к чему (бывают случаи, когда оно необходимо, но я не буду их тут рассматривать), то можно определить анонимную структуру и сразу дать имя этому типу в общем пространстве, так тоже будет работать.
Это нас подводит ко второму способу работы со структурами:
#include <stdio.h>
#include <math.h>
typedef struct {
double x, y;
} point;
double veclen(point p) {
return sqrt(pow(p.x, 2) + pow(p.y, 2));
}
int main() {
printf("%g\n", veclen((point){1, 2}));
}Ключевое слово struct перед типом уже не нужно, раз все имена в общем пространстве. Это же касается и CGO.
Как раз на эти грабли я и наступил — позабыл про эти все особенности. Когда я ещё писал на Си, всегда пользовался вторым способом, с именем в общем пространстве и привык к тому, что это и есть структуры.
Крутая пасхалка
Посмотрел сегодня «Первому игроку приготовиться», там сюжет строится вокруг «пасхального яйца» в программе виртуальной реальности, и вспомнил, что самое крутая «пасхалка», которую я видел за последние несколько лет — это тетрис в «Газели Некст».
Специально выкладываю это сегодня, а то завтра первое апреля и люди подумают, что это розыгрыш. На ютубе около двух тысяч роликов на эту тему, поищите.
Скриншот выше я взял из ролика на официальном канале кампании «Группа ГАЗ» и в комментарии к нему поясняется, что тетрис используется как тест бортового компьютера — можно быстро погонять и процессор, и все зоны дисплея. Наверное так оно и есть, но обычно такие тесты выглядят намного утилитарнее, тут видимо
Говорят на тетрис
После запуска игры, правой крутилкой можно двигать фигуры, а левой — вращать и бросать вниз. Выйти из игры можно либо выключив зажигание, либо начав движение.