💾 В последний раз о Trek Thumbdrive
Предупреждали ведь меня умные люди в комментариях — сохрани драйвера. Почему я не прислушался?
У нас в городе, силами моего хорошего знакомого — директора высшей школы ИТИС Айрата Хасьянова, создаётся небольшой компьютерный музейчик. Я в размере своих закромов ему помогаю, вот и уникальную флешку на 16 мегабайт тоже передаю.
Но перед этим хотел посмотреть нет ли на ней
Сейчас смешно звучит, но флешки того времени имели ёмкость от 8 до 256 мегабайт (не гигабайт) и продавались с драйвером на дискете.
Оказалось, что сей драйвер не меньший раритет, чем флешка.
И вот вчера повезло — на неком тайском блоге нашёл запись со ссылками на другой сайт с полным комплектом драйверов. К сожалению, сначала драйвера не скачались — сайт давно лежит в обломках. Но мне повезло дважды — через
Дома выкачал виртуальную машину с операционной системой постарее (вы в курсе, что их легально можно скачать с сайта «Микрософта»?), поставил драйвера, всё завёл, но, к сожалению, ничего ценного не нашлось, даже стёртого.
Из примечательного, файловая система на флешке — FAT12, служебная информация на ней хранится очень компактно, но она поддерживает накопители не более 32 мегабайт. Такая же файловая система применяется и на дискетах, которые, как говорят, благодаря некоторым налоговым никак не оставят нас в покое.
«99 бутылок» на языке «Электроники МК-61»
59. Язык калькулятора Электроника
В детстве такие калькуляторы я видел только на картинках в журнале «Наука и жизнь», а программы для них были
Вчера мне в руки попал настоящая «Электроника
Так выглядят мои «99 бутылок…» на этом калькуляторе:
8112000 Х→П c 8 + ИНВ Х→П b Вх 10 ÷ [X] Х→П d 8 + ИНВ Х→П e В/О ПРГ
П→Х 0 1 0 ÷ [x] Х→П 1 Вх {x} 1 0 × Х→П 2
1 1 Х→П 8 1 2 Х→П 7 П→Х 2 ПП 34 Х→П a
1 4 Х→П 8 1 3 Х→П 7 П→Х 1 ПП 34 П→Х a
^ С/П
6 - /-/ x<0 45 9 + К П→Х 7 + ИНВ В/О
1 + К П→Х 7 + ИНВ К П→Х 8 ^ В/ОПоскольку у меня в блоге скорее всего отсутствуют любители работать каждый день с калькуляторами советских времён, то я не буду придерживаться принятой нотации с номерами — не думаю, что
Вкратце о языке. Больше всего это похоже на крайне примитивный ассемблер с гипертрофированным математическим сопроцессором. Всё то же — переходы на адрес, одно- и двухбайтные инструкции с операндами, регистры с определёнными назначениями, сильно ограниченная память (105 команд), наличествует косвенная адресация и подпрограммы (стек вызовов размером в пять вхождений).
До запуска программы нужно в регистр «0» поместить стартовое значение (например, «99», «Х→П», «0») и запустить программу «В/О», «С/П».
Это я сделал
Поэтому на вход подаётся нужное число, например, «42», а на выходе мы можем полюбоваться фразой «BEEr 42». Не весть что, но что вы хотели от калькулятора? Кстати, выводимая фраза — не строка (спойлер: а число), о том как мне пришлось помучаться я ещё расскажу.
🎱 Сложности при написании «99 бутылок» на «Электронике МК-61»
★
Как и обещал в прошлый раз, хочу рассказать с какими сложностями мне пришлось столкнуться при написании «Песни о пиве» на программируемый калькулятор «Электроника
Калькулятор попал ко мне для передачи в компьютерный музей, который готовится к открытию в высшей школе «ИТИС» и у меня
В процессе изучения я наткнулся на заинтриговавшую меня вещь. В некоторых операциях калькулятор переключался в режим шестнадцатеричного счисления, о чём сигнализировала восьмёрка и точка в первом разряде.
Как видно по таблице выше, отображение этих чисел сильно отличается от общепринятого (как правило для цифр больше девятки используются латинские буквы от A до F) и я не мог не отметить, что с их помощью легко написать английское «beer» («пиво»).
Тем более мне очень повезло в том, что индикацией этого режима является именно восьмёрка, стоящая спереди — так похожая на первую букву в нужном мне слове. Как вы теперь понимаете, на экране в моей программе написано не «BEEr», с точки зрения калькулятора там одни числа и индикатор режима — «8.EEГ» или «EED» в привычной записи (десятичное «3821»).
Так же я воспользовался тем, что «F» в этой странной нотации — пробел, что позволило мне отделить число от «надписи». Дальнейшее — дело техники.
Листинг из предыдущего поста начинается с подготовки данных в регистрах — нескольких масок на которые битовыми операциями в дальнейшем наложатся числа так, чтобы получилась нужная мне «строка». Настоящая программа начинается с нажатий на «В/О» и «ПРГ», и активно пользуется подготовленными данными.
Маски и оставшиеся числа побитно накладываются двумя подпрограммами — по отдельности на диапазоны
Для примера кусочек подпрограммы, номер слева соответствует номеру инструкции при вводе в калькулятор и каждую строку я прокомментирую, но следует понимать, что в реальности эти комментарии частью программы не являются:
// когда что-то попадает в «X» предыдущее значение смещается в «Y» (там стек из 4 позиций)
45 1 // «1» кладётся в регистр «X», входной параметр сместился в «Y»
46 + // Y + 1, передаётся в «X», это коррекция данных после операций, которые шли выше
47 К П→Х 7 // в «X» помещается число из регистра (маска), указанного в регистре №7
48 + // Y+X → X
49 ИНВ // инвертирование битов в «X», сейчас на экране написано «8.EEГ» плюс некий пока мусорный символ
50 К П→Х 8 // в «X» помещается число из регистра, указанного в регистре №8
51 ^ // операция «И», на экране — «8.EEГ», из некого символа получилось требуемое число
52 В/О // возврат из подпрограммыДесятки и единицы выбираются адресами масок, которые я передаю при помощи косвенной адресации, хорошо, что такое вообще есть в языке — это позволяет эффективно пользоваться подпрограммами.
Подпрограмма вызывается два раза с разными параметрами — для десятков и единиц, получаются две маски, которые позднее накладываются друг на друга.
Сильно расстраивает отсутствие памяти для долговременного хранения, в устройстве хоть и есть батарейный отсек, но при любом сбое питания (батарейки сели, а блок питания не подключен), память калькулятор сбрасывается и программу придётся набрать заново. То же ожидает и в случае, если одну программу нужно будет заменить другой — хотя программы можно запускать с произвольного адреса, много их в память не уместится — её ёмкость всего 105 инструкций.
🐞 Немного об отладке через var_dump
Недавно поймал, посещая «Вконтакт», такую ситуацию. Владельцы её заметили нескоро — висело ещё минимум час.
«Вконтакте» написан на диалекте ПХП и для тех не знаком с этим языком поясню — это
🔌 Как много кабелей хороших, как много ласковых имён
Сейчас половина олдфагов интернета потешается над пареньком, в объявлении на «Авито» перепутавшим сетевую карточку
Ну не знал человек, бывает. Где сейчас можно встретить сети
Много ли людей сходу, не гугля, скажут что за разъём на переднем торце карты на фотографии рядом с кабельным? Я сети на нём вживую не видел, но зато видел залежи оборудования под него в одном из НГДУ «Татнефти», когда работал там в середине девяностых — видимо то был самый конец их существования в этой организации.
Это так называемый разъём «AUI». Карта через него, по специальному кабелю, похожему на принтерный, соединялся с небольшой коробочкой — трансивером, у которого был разъём BNC. Через него вся эта непростая конструкция подключалась в локальную сеть.
🔍 Линза на телевизоре
В субботу был в музее Истории Сибирского тракта (село Карадуван) и обратил внимание на одну деталь, которую
Я нередко вижу в музеях телевизоры с линзами, но впервые обратил внимание на то, что эти линзы заполняли водой. Мне
Разглядывая свою фотографию из казанского музея Счастливого детства, я заметил, что линза верхнего телевизора
На всякий случай проверил версию, что сотрудники музея заполнили линзу водой по незнанию (всякое бывает). Хотя это было маловероятно — в карадуванском музее смотрительница даже вынула пробку из входного отверстия и показала как это делалось с полным знанием вопроса.
В общем, нашёл в интернете инструкцию к одной линзе тех времён и она недвусмысленно опровергает это сомнение. Кстати, иногда вместо воды использовали глицерин — у него другие характеристики преломления и линза давала большее увеличение.
⌨ Советские калькуляторы в музей
Скоро передам в готовящийся к открытию музей несколько советских и постсоветских калькуляторов. Слева направо: две «Электроники МК 51» (1992 и 1994 гг.), «Электроника
✨ Двойные миграции (Оракл+Постгрес)
У нас идёт замена в наших продуктах сильно платного «Оракла» (это база данных) на бесплатный «Постргес». Несмотря на ударные темпы, продолжаться это ещё будет долго. Продуктов много, несмотря на то, что начали мы ещё в прошлом году, весь этот год будем жить сразу на двух базах.
В этой связи, когда есть различия, приходится миграции писать в двух комплектах — под каждый диалект. Я придумал как писать их так, чтобы каждая БД видела куски кода, предназначенные только ей.
Например:
CREATE UNIQUE INDEX dn_part_num_org_n_cat ON document_n(/*/**/
CASE WHEN d_deleted = 0 AND num IS NULL AND n=0 AND category=0 THEN id END,
CASE WHEN d_deleted = 0 AND num IS NULL AND n=0 AND category=0 THEN org_id END);
--*/ id, org_id) WHERE d_deleted=0 AND num IS NULL AND n=0 AND category = 0;Часть с /*/**/ и до —*/ видит только «Оракл» — для него это выглядит так: комментарий открывается, сразу закрывается, идёт код, который он и воспринимает, а последняя строка закоментирована при помощи двух минусов — это стандартный коментарий в эскуэле.
«Постгрес» эту часть не видит — он поддерживает вложенные коментарии, поэтому его интерпретация другая: открываются два комментария, первый закрывается сразу, а второй — на последней строке, остаток которой «Постгрес» воспринимает как часть кода.
❌ Приметы девяностых
Сейчас многие говорят о кризисе и в этой связи — о возвращении девяностых. У многих упали доходы, как следствие по всей стране выросла преступность (в Казани — на 20% в прошлом году).
Недавно у одного моего знакомого сняли дворники с машины.
Хотя этот случай не показателен, это прямая ассоциация с девяностыми, тогда, я помню, оставляя машину, все снимали дворники так как крали их постоянно.
Я не уверен, что они именно тогда они и появились, однако могли бы — в те времена тащили всё что угодно, оконные стёкла в том числе. А такая пометка, я так это интерпретирую, помогала предотвратить кражу. И теперь, когда я их вижу на стёклах, доживших до нашего времени с тех времён, моя память подкидывает мне чёткую и однозначную ассоциацию.
А что для вас является персональной ассоциацией с тем временем? Я не имею ввиду одежду не по размеру, бандитов и всего того, что обычно люди обычно вспоминают.
⌨ Ещё партия советской техники в музей
Подоспела партия новых экспонатов в музей вычислительной техники, который я помогаю организовывать. Это БК
Бонус — кот Е́жи
🚨 Особенности перехода с «Оракла» на «Постгрес»
В комментариях пообещал поописывать свой опыт перевода продукта с «Оракла» на «Постгрес», особенно в особенностях, которым очень мало уделено внимания на просторах интернета. Начну с простого, зато сразу целой пачкой. Примеры я, естественно, упростил, чтобы максимально выпукло продемонстрировать различия.
У нас довольно много генерируемых простых запросов, иногда они генерировались не очень аккуратно. «Оракл» такое прощает, а «Постгрес» — нет. Запрос, где одни и те же таблицы соединяются дважды «Постгресу» не по вкусу:
SELECT * FROM test INNER JOIN test1 USING(n) INNER JOIN test USING(n);
ERROR: table name "test" specified more than once«Постгрес» очень трепетно относится к тому, чтобы у подзапроса был алиас, даже если он потом нигде не используется:
SELECT * FROM (SELECT * FROM test);
ERROR: subquery in FROM must have an alias
СТРОКА 1: SELECT * FROM (SELECT * FROM test);
^
ПОДСКАЗКА: For example, FROM (SELECT ...) [AS] foo.В «Постгресе», в запросах на обновление нельзя указать алиас. Тут это логично, так как синтаксис подзапросов в этом случае у этой СУБД совершенно иной — они указываются в специальном месте.
UPDATE test t SET t.n=1;
ERROR: column "t" of relation "test" does not exist
СТРОКА 1: UPDATE test t SET t.n=1;Если «Оракл» спокойно относится к двум и более таблицам с одним алиасом, то «Постгресу» от этого плохеет. Жаль, иногда удобно объединить несколько таблиц алиасом прямо на месте и работать дальше с ним, как с единой таблицой.
SELECT t.n FROM test t, another_test t;
ERROR: table name "t" specified more than onceВ «Оракле» ключевое слово FROM не обязательно в запросах на удаление. У нас было несколько запросов без него.
DELETE test;
ERROR: syntax error at or near "test"
СТРОКА 1: DELETE test;В следующий раз буду описывать более комплексные примеры.
💰 Шалаш на острове сокровищ
В общем, теперь я обладатель: одной копейки 1885 года, одной копейки 1897, трёх монет по ¹⁄₄ копейки — одной 1873 года и двух 1878, одной копейки «ранних советов» — 1957, двух свинцовых пломб (одна без надписей, на второй надпись — «Шмидтъ. Лодзь. Шелк. Полуш…») и серебряного колечка
Надпись на пломбе, как удалось выяснить, полностью выглядит так: «Фабр. шерст. полушел. и шелк. изд. // Шмидтъ и Пфитце — Лодзь».
Отдельной строкой. Очень радует сохранность монет, вот что значит не в земле лежали. Следы окисления есть, но большей частью монеты выглядят просто превосходно.
🐘 PostgreSQL, PHP и подготовленные запросы
Одно из отличий «Постгреса» от «Оракла» — подготовленные планы запросов лежат не в разделяемом ресурсе, а в неком хранилище в рамках одного соединения. Программист, в рамках каждого соединения, должен подготовить их оператором PREPARE, в который передаётся выбранный идентификатор запроса и сам запрос, а потом выполнить его при помощи оператора EXECUTE, используя в качестве параметра переданный при подготовке идентификатор и значения параметров.
Польза подготовленных запросов в том, что можно единожды (за время жизни соединения, напоминаю) подготовить запрос, то есть попросить «Постгрес» выполнить его компиляцию в стандартное представление и оптимизацию, а после многократно его использовать, что очевидным образом поднимает производительность приложения.
Схема работы тут очень простая: вычисляем от запроса хеш, ищем его в специальном массиве, если не находим, подготавливаем запрос, используя хеш в качестве идентификатора, после чего хеш добавляем в специальный массив. После чего выполняем подготовленный запрос.
Если план запроса больше не нужен, его можно удалить по идентификатору оператором DEALLOCATE, если же в качестве параметра передать ключевое слово ALL, то будут уничтожены все подготовленные в этом соединении планы. С закрытием соединения, планы так же исчезают.
Теме работы «Постргеса» с ПХП удивительно мало посвящено в руководстве к языку, так что пришлось произвести ряд самостоятельных исследований. Основной вопрос, на который я хотел для себя ответить — есть ли
Оказалось, что это вполне возможно. В ПХП есть «постоянные соединения» — обрабатывающий процесс интерпретатора держит открытым соединение с базой, передавая его новому скрипту, это уменьшает затраты, так как стадия установки соединения и авторизации выполняется только в первый раз.
С открытым соединением в скрипт попадают и подготовленные запросы из предыдущего сеанса, остаётся только
Код всего описанного выглядит вот так, я его упростил и переписал процедурно:
// открываем постоянное соединение с базой
$con = pg_pconnect($connection_string);
// загружаем подготовленные запросы
$res = pg_query("SELECT name FROM pg_prepared_statements");
$prepared = array_fill_keys(pg_fetch_all_columns($res), true);
pg_free_result($res);
// хеш от запроса, tiger — быстрый алгоритм, я люблю его использовать
$hash = base64_encode(hash('tiger160,3', $sql, true));
// смотрим — был ли уже подготовлен такой запрос
if (!isset($prepared[$hash])) {
$prepared[$hash] = true;
pg_prepare($con, $hash, $sql);
}
// выполняем запрос
$res = pg_execute($con, $hash, $params);Общая идея, думаю, понятна из кода. Пока для меня остаётся открытым вопрос «просачиваются» ли в переданное соединение незакрытые транзакции или временные таблицы (предыдущий его владелец, например, мог умереть
Надо заметить, что модуль «Постгреса» в ПХП в каждое соединение, перед его передачей в приложение, посылает команду RESET ALL, но она, насколько я понял из руководства, лишь сбрасывает различные конфигурационные переметры времени выполнения на значения
⌨ Детская Вычислительная Машина (ДВМ-1М)
Всё идёт к тому, что Музей Вычислительной Техники, открытию которого я всеми силами помогаю, будет весьма любопытным уже на первых этапах. Сейчас ко мне в руки попала «Детская Вычислительная Машина» 1983 года выпуска. Между прочим, это первая машина, на которой я
«Машина» в прекрасной сохранности, которую чуть подпортили
Эта приехала ко мне из Новосибирска, а в моём детстве такая же была у сына соседей снизу — мы с ним дружили и я иногда спускался к нему, играть на ДВМ. Прекрасно помню саму «Машину», эти перемычки и штырьки, но память совсем не сохранила карточки, фишки и кубик — генератор случайных чисел.
В книжке одиннадцать «программ» (есть даже такие, где нужно играть вдвоём!), для некоторых из них и нужно это дополнительное «оборудование».
Программа вводится при помощи перемычек и штырьков, после чего надо сдвинуть все три планки в соответсвии с правилами и получить ответ в двоичном виде, нажав на специальную кнопку. Возможно
На фотографии выше программа «Угадай число». Требовалось всё правильно скоммутировать, загадать число от нуля до семи и ответить на три вопроса, выставляя планки в соответствии с ответами.
Я загадал пять. В ответах на вопросы надо было указать чётное ли число, меньше ли восьми сумма задуманного числа и следующего за ним и равняется ли 4 или 5 остаток от деления на шесть суммы задуманного числа и 10? Для моего числа — «пятёрки», ответ на все вопросы — «нет» («ноль»).
После нажатия на кнопку, машина дала ответ в бинарном виде — надо сложить четвёрку и единицу. Интересно, что я показывал эту «программу» трём различным людям и все загадали именно это число.
Так же в коллекции музея теперь есть и «Детская Логическая Машина» — старшая сестра (по возрасту, а не умениям)