TeleBolkNote
183 subscribers
1.46K photos
4 videos
1.6K links
Моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь, большие языковые модели и программирование. Совпадает с сайтом bolknote.ru
Download Telegram
«В поисках утраченного ковчега»

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

Этот фильм я смотрел, наверное, ещё в детстве и совсем его не помнил, кроме двух сцен — с гигантским камнем и когда Индиана стреляет в мужика с саблей. Их сложно забыть, так как их регулярно цитируют.

Но, в целом, я думал, что фильм должен был неплохо состариться за 45 лет, что ему будет-то? Приключения и приключения.

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

Можно подумать, что фильм совсем детский и дети на такое внимание не обращают, но даже дочка отметила как нелепо они прячутся.

Фильм мы досмотрели, несмотря на все недостатки, скучать не приходилось, но пересматривать я его уже точно никогда не буду.
😭2😁1
Прототипирование и ИИ

На работе у нас проект одного очень сложного модуля к нашему продукту, дизайн которого мы делаем уже почти год. Бывает так, что мы его откладываем, занимаемся другими делами, потом возвращаемся, но длится это уже очень долго. Одна из причин — никак не удаётся нащупать правильные решения.

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

А на днях я подумал — почему бы не попробовать сделать прототип (срезав кое-какие острые углы, разумеется) при помощи ИИ? Выделил на это несколько рабочих часов, заперся в переговорки с дизайнерам и аналитиками и мы попробовали.

Выгрузить вёрстку из «Фигмы», где у нас нарисован дизайн, нам не удалось — предназначенные для этого плагины ничего не дали. Я решил с этой проблемой не бодаться, а попробовать сделать вёрстку из картинки «нулевого состояния», постепенно добавляя поведение так, как это описано в техническом задании.

Это был самый утомительный этап — картинку нейросеть «видит», но судя по тому как получилась первая версия, она её себе каким-то образом описывает на словах, а потом верстает со словесного рассказа.

Особенно хорошо это было заметно на иконках — элементы на них, чаще всего, те же самые, но нарисованы совсем иначе. Если остальную вёрстку я сумел выправить промптами, то иконки мы просто вытащили из «Фигмы», назвали говорящими именами и нейронка сама догадалась куда их применить.

Так же пришлось, кстати, поступить и с цветами. На скриншоте я убрал весь получившийся интерфейс, потому что не могу его показывать, но полоску заголовка оставил, только всё оттуда стёр. Бледно-голубой цвет этой полоски у нейросети превратился в просто какой-то голубой. Поэтому все цвета я взял пипеткой из исходной картинки и передал нейросети в виде значений.

На приведение в порядок того, что модель наверстала, ушёл, наверное, час, после этого мы вырезали кусок из технического задания, где описывались механики и я скормил это нейросети как есть. Часа через три у нас был прототип, с которым худо-бедно уже можно было работать.

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

На этом прототипе днём позже мы смогли оценить кое-какие наши решения и даже найти серьёзную техническую проблему, для которой смогли тут же придумать решение. Я считаю, что это отличный результат, надо продолжать работать с в таком ключе дальше.


При этом я не рассматриваю сделанную работу как готовый кусок кода, который можно затем будет интегрировать в проект. Этому есть несколько причин:

Во-первых, писал я натуральным «вайб-кодингом», вообще не заглядывая в код, если вы программист и видели какой код пишут нейросети без присмотра, когда решают комплексные задачи, понимаете, что иногда это потом проще выкинуть, чем использовать.

Во-вторых, это чисто интерфейсный прототип без учёты взаимодействия с сервером. Тут никак не учтены очень важные детали, которые необходимо положить в фундамент архитектуры, чтобы потом всё не переделывать.

В-третьих, этот код никак не учитывает архитектуру остального проекта, написан он с «чистого листа», совершенно изолированно, соответственно, при попытке его интегрировать его придётся серьёзно переделывать.

В-четвёртых, мы опасаемся утечек нашего кода в чужие облака. Что там делать с ним будут — неизвестно.
👍3
«Ollee Watch»

Приехала моя прелесть, ехавшая ко мне через Китай из Нидерландов. Эта штука похожа на «The Sensor Watch» — тоже вставляется внутрь корпуса часов «Касио», но возможностей у неё куда больше, — например, в ней есть шагомер и она умеет соединяться со смартфоном через «Блютуз».

Ждал этой посылки в сентября прошлого года, наконец сегодня забрал. Осталось купить часы подходящей модели и всё смонтировать в корпус.
2
Человек: как убить трёхчасовой вайбкодинг

Я уже рассказывал как нейросеть из-за неправильно понятой ею фразы как-то стёрла результаты совместной трёхчасовой работы, а в этот раз хочу рассказать как опростоволосился я сам.

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

Уже после обеда, решив зафиксировать, всё-таки, достигнутый результат, я создал репозиторий через git init, добавил в него все файлы через git add -A, но сообразил, что в туда попадёт слишком много мусора и решил сначала «прибраться».

Тут меня буквально на мгновение отвлекли каким-то вопросом и я, не до конца переключившись обратно, набрал вместо git reset немного другую команду — git reset −−hard, то есть вместо сброса коммита, я синхронизировал содержимое своей директории с состоянием репозитория, который я только что создал. Открываю директорию, а там ни одного файла, созданного за мой трёхчасовой сеанс вайбкодинга.

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

В том же редакторе, где вайбкодил, — в «Курсоре», спросил у нейросети нельзя ли как-то восстановить стёртое и я оказался прав — нейросеть мне всё восстановила!

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

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

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

В середину поверхности шарика наклеиваем что-нибудь лёгкое и светоображающее. Зеркало не подойдёт, оно слишком тяжёлое. В оригинале закрепляли кусочек компакт-диска, но у нас дома их нет, поэтому я взял блёстку от ёлочного серпантина.

Внутрь банки кладём смартфон на котором запускаем какую-нибудь музыку через динамик, а на блёстку направляем лазерную указку, так чтобы отражение попадало на стену. Для простоты всё это я просто разложил на столе, даже не закрепляя.

В итоге лазер начинает рисовать на стене разнообразные пятна в такт музыке или речи, очень интересно смотрится.
🔥8👍2
Силиконовый брат

Вроде Доли́ну, которая Кремниевая, уже мало кто называет «Силиконовой» (путаница произошла из-за того что слово «кремний» по-английски будет «silicon»), так может и Старшего Брата (Big Brother) сможем научиться не называть «Большим Братом»?
😢2
Год с «Дуолинго»

Как-то незаметно прошёл год, как я занимаюсь английским с «Дуолинго». Хотелось бы сказать, что я заметил как вырос мой уровень, но на самом деле я не могу с уверенностью сказать так это или нет. Хотя задания в приложении за этот год стали сложнее, у меня всё же нет ощущения, что я как-то заметно прокачался, в том смысле что ни к какому новому качеству в моей жизни это не привело.

Книги по-английски не читаю, видео на английском не смотрю. Я пытался подобрать какой-нибудь регулярный видеоконтент мне по силам, но всё что мне интересно явно выше моего уровня.

Правда купил пару книг на английском и, думаю, я вполне способен прочесть их целиком без словаря, но пока как-то не приступлю — увлекла серия книг про Боба, пока не дочитаю, ни на что другие отвлекаться не хочется.

В общем, спустя год похвастаться мне особо нечем, но всё равно буду заниматься дальше, — ощущения, что я впустую трачу время у меня тоже нет. Думаю польза есть, просто год по пятнадцать минут в день — это мало.
👍41🤡1
Cardputer ADV + «мышастик»

Как говорится, когда у тебя в руке молоток, всё вокруг превращается в гвозди. Бог знает зачем купил модуль «мышастика» к «Кардпьютеру». Даже не уверен, что буду использовать его в качестве узла связи, наверное просто хотелось посмотреть какими ещё возможностями обладает это устройство, тем более, что модуль стоил недорого.

Не знаю почему, но через блютуз к модулю подцепиться не удалось, поэтому, чтобы настроить его через приложение, пришлось цепляться к смартфону шнурком. Прошивку поставил, как водится, альтернативную — с поддержкой русского языка. Скачал её в зип-архиве, положил на карточку и выбрал в M5 Laucher.

Получается с «Кардпьютером» у нас теперь пять нод — две стационарные ретрансляционные на окнах квартиры, плюс ещё три — носимые.
🔥5
«Our Red Army Ally»

Читал на днях брошюру «Our Red Army Ally» («Наш Союзник — Красная Армия»), которая была выпущена весной 1945 года американцами, чтобы объяснить бойцам что из себя представляет союзная Красная Армия и как себя вести при встрече с красноармейцами.

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

Еда проста, питательна, тяжела. Красноармеец привык к сытным супам и овощно-мясным похлёбкам, по возможности заправленным сметаной. Обычное блюдо — каша с жирным мясом. Большое количество грубого, но полезного чёрного хлеба — ещё одна основа питания. Щи — любимое блюдо.

Пищу запивают бесконечными стаканами горячего чая. В целом красноармеец может обходиться без сладостей, но к чаю ему обязательно нужен хоть кусочек сахара, который он держит между зубами, пока пьёт. Чай служит и напитком, и десертом. Трапезу завершают русские сигареты — либо готовые папиросы с прикреплённым мундштуком, либо самокрутки из махорки.

В холодную погоду неразбавленная водка с кусочком селёдки на чёрном хлебе помогает согреть желудок красноармейца.


В общем, очень интересное чтиво на самом-то деле и написано хорошо.

Одно мне непонятно — почему так плохо нарисован Ленин на Ордене Ленина? Скорее похоже на профиль Полифема в костюме. При этом детализация остальных рисунков нареканий не вызывает. Очень странно.
Слово денисовца

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

Некоторые учёные считают, что язык мог возникнуть куда раньше, чем считалось, — около полумиллиона лет назад — и не только у сапиенсов, но и у неандертальцев с денисовцами. Это как будто бы подтверждают генетические исследования: часть генов, отвечающих за возможность появления речи, есть в геноме и этих видов тоже.

Получается, в теории, в наших современных языках вполне могут быть слова, доставшиеся нам от «альтернативных ветвей» человечества. К сожалению, узнать об этом нет никакой возможности. Разве что обнаружатся инопланетяне, которые уже сотни тысяч лет за нами наблюдают и отдадут нам записи того, как это всё было.

Есть ещё вариант найти какую-то чёткую разницу между языками народов, у которых есть вклад денисовцев в ДНК и тех, у кого его нету, но за давностью истории это вполне может быть и просто случайностью, которая возникла по другим причинам.
🤔1
«Виола», формулы и стилизация

Долго же я прикидывал правда ли автор «Виолы» задумывал, чтобы математические формулы у него выводились на красном фоне. С одной стороны в коде именно так, да и мне это кажется даже в чём-то логичным, с другой стороны комментарий одного из читателей посеял во мне сомнения.

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

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

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

Вот, кстати, как выглядело недописанное место, где можно подсмотреть что планировалось сделать:


tagPtr = STG_tagPtr("MATH");
i = STG_attr(tagPtr, "BGColor");
if (i) set("BGColor", i);
i = STG_attr(tagPtr, "FGColor");
if (i) set("FGColor", i);
i = STG_attr(tagPtr, "BDColor");
if (i) set("BDColor", i);


А то некоторые читатели недоумевают, наверное, откуда я вообще знаю что задумывал автор.

Нередко такие места содержат в себе достаточно понятные намёки на то как это было задумано, в других же случаях помогают комментарии, главы из недописанной книги автора или его редкие письма в различные группы рассылок, куда он редкий раз писал свои мысли в самом начале 90-х.
Собрал «Ollee Watch»

Что-то меня увлекла идея переделанных «Касио» — вторые такие часы себе уже приобрёл. Думаю, меня привлекает возможность вложить туда немного личного — хоть это и довольно просто, но их приходится собирать самостоятельно, плюс для первых своих таких часов — «The Sensor Watch» я даже написал свою игру. Кроме того, сама идея такого апгрейда довольно обычных наручных часов очень гиковская, мне такое нравится.

Правда вторые часы, «Ollee Watch» ощущаются чуть менее гиковскими, чем предыдущие и похожи на что-то, что могла выпустить какая-нибудь большая компания. Та же «Касио», например. У них, в отличие от «The Sensor Watch», есть приложение для смартфона, с которым они умеют соединяться через блютуз, NFC (я пока не разобрался зачем) и шагомер.

Шагомер — пока наиболее интересная для тут меня штука, я когда-то решил нахаживать не менее 10 тысяч шагов в день и выполнял норму, пока мог контролировать её на часах. Но с тех пор, как я приобрёл «The Sensor Watch», ношу, в основном, только их и вся эта история с шагами ушла на задний план — следить перестал, а надо бы, я думаю.

Мои новые часы показывают, что я сегодня прошёл 196 шагов и выполнил свою норму на ноль процентов ↓↓
Джойстик для «Кардпьютера»

Блин, ничего не понимаю. Чтобы было удобнее играть в эмуляторе в игры на «Кардпьютере» мне нужен вот такой джойстик, как у меня на картинке. Другие модели не подходят. Называется он Joystick2 и доступен для заказа везде — на «Озоне», «Алиэкспрессе» и так далее.

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

Окей, я верю, нет, не выпускается, но почему, товарищи продавцы, после отмена заказа вы не закрываете позицию в своих магазинах, а продолжаете продавать товар, которого у вас нет? Я проверил карточки всех товаров, за которые мне вернули деньги — ни один продавец не снял этот джойстик с продажи.
PHP: (unset) и (void)

Язык PHP часто ругают. Большей частью — заслуженно, но часть давно решённых проблем тянется за ним, как смрад за народным ополчением в Средние века. Ненавистники часто глубоко в проблемы языка не вникают — им неинтересно, перепечатывая аргументы, которые много лет как несостоятельны.

Как мне кажется, самая большая проблема языка сейчас — это его процедурное прошлое, которое торчит изо всех щелей. Но есть и менее заметная, при этом системная проблема: у языка нет «великодушного пожизненного диктатора», как у Пайтона или Линукса, или более «сыгранной» команды, определяющей долгосрочные цели в развитии языка.

Некоторые разумные, в общем-то, вещи забрасываются (например, SPL — стандартная библиотека), некоторые — не дожимаются до конца (например, в языке появились обнуляемые типы, но приведение одного типа к другому этого не учитывает).

Я хочу поворчать на одну из таких мелких тем.

В ПХП с незапамятных времён была конструкция (unset), которая приводила любой тип к NULL. Не самое очевидное название, поэтому, наверное, и применял её мало кто — не всем очевидно чем она могла бы быть полезна.

Тем не менее, я со временем догадался, что можно её приспособить, чтобы обозначать, что чем-либо возвращаемое значение я не просто забыл как-то использовать, а вполне сознательно выкинул. Что-то вроде такого:


class Smth
{
private function saveSmth($stat)
{
// тут какие-то действия
// прошло успешно, но выше где-то может быть и false
return true;
}

public function doSmth($action, $stat)
{
// тут какой-то код
// результат вызова метода ниже мы игнорируем
(unset) $this->saveSmth($stat);
return true;
}
}


Мне казалось и до сих пор кажется, что это полезный паттерн. В «Гоу», например, в этом случае нужно присвоить возвращаемое значение специальной переменной _, иначе компилятор ругается.

И вот, много лет назад, в версии 7.2 использование (unset) в коде стало вызывать предупреждение об устаревшей конструкции. Я тогда попытался как-то повлиять на это, но не осилил пробиться к людям принимающим решение и махнул рукой. Позже в версии 8.0 конструкцию убрали вовсе и много лет не в языке было хорошего способа делать то же самое.

А в версии 8.5 внезапно та же идея возвращается под новым именем, только теперь нужно писать (void), а не (unset).

Да, имя более логичное, да функционал расширен — появился ещё и новый атрибут, да синтаксис изменён — результат (unset) можно было чем-то присвоить, с (void) так поступать нельзя. Но почему столько лет назад выплеснули с водой ребёнка и вообще никак не смотрели в эту сторону?
2👍2
PHP: (binary)

И, чтобы, как говорится «два раза не вставать», расскажу про самую бесполезную конструкцию в ПХП. Я знаю, что не так много народу знают про (unset), про которую я ворчал вчера, а про эту вещицу, как мне кажется, знает ещё меньше программистов на ПХП.

Одна из неприятных вещей, которые остались в ПХП с давних времён — работа встроенных функций и конструкций только со строками в однобайтовых кодировках. С этим можно жить — есть библиотеки, которые позволяют замести эту проблему под ковёр, но сам язык помогать вам в этом не будет.

Какое-то время назад с этим пытались что-то сделать — в шестой, так и не вышедшей версии ПХП строки решили разделить на два типа — binary, это однобайтовые строки, которые остались в языке до сих пор и string — строки с Юникодом.

К сожалению, работу доделать не осилили, очень уж было сложно, особенно тяжело шло с расширениями. В итоге версия так и не вышла, но так как о ней широко раструбили, пришлось даже пропустить номер — после ПХП 5 вышла сразу седьмая версия.

Но некоторые отголоски этой не совершившейся революции всё-таки можно обнаружить и в современных версиях ПХП.

В версии 8.5 по сих пор есть преобразование типа (binary), которое является алиасом к (string), но выдаёт предупреждение об устаревшей конструкции. А кроме этого, у строки есть префикс b: b"string", придуманный для того, чтобы создавать в ПХП6 однобайтовые строки. В современных версиях ПХП он, разумеется, ничего со строкой не делает.

И эту всю красоту из языка почему-то не удалили, а от (unset) избавились. Никакой логики.
1👍1
Фотография как источник

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

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

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

Если же попробовать изучить, например, мою жизнь по фото на моём сайте, не факт, что мелкие детали на фотографиях соответствуют моменту и месту съёмки — у меня много лет нет ни одной необработанной, так или иначе, нейросетями фотографии.

Понятно, что иногда я убираю что-то очень незначительное — вроде грязи в кадре или бликов на стекле, но бывает, что часть интересного мне объекта чем-то заслонена, и я прошу нейросетку убрать лишнее, а в освободившееся пространство что-то врисовывается, наверняка далёкое от истины.

Как пример, фотография ниже, сделанная изнутри здания казанского айти-парка. Сравните мою фотку (думаю легко понять где она) и результат обработки нейросетями.

Понятно, что информацию о тех участках, которые заслонены металлическими конструкциям, взять неоткуда, нейросеть там нарисовала отсебятину, пусть и достоверную. Если туда попали какие-то важные детали, то они только по случайности совпадут с реальностью.
👍4
Локальные адреса в «Веб-архиве»

Я тут благодаря «Виоле» обнаружил кое-что интересное в «Веб-архиве».

В моей версии этого браузера я делал логику, согласно которой, если домен не открывается, то я пытаюсь найти и открыть его самую раннюю сохранённую копию в «Веб-архиве».

В браузере есть несколько встроенных ссылок на разные давно не существующие сайты, и эта логика нужна, чтобы внешние ссылки с них нормально открывались.

Я не учёл, что локальные адреса — localhost, 127.0.0.1 и прочие — не должны искаться в «Веб-архиве», ведь из интернета их не видно. Вчера случайно я запустил «Виолу» с URL https://localhost/, и вдруг у меня начал открываться какой-то сайт на японском.

Оказалось, «Веб-архив» хранит зеркала каких-то случайных сайтов, доступных по локальным адресам и портам бог знает каких сетей. Я навскидку посмотрел несколько адресов — 127.0.0.1:8080, 192.168.0.1 и так далее — и обнаружил около десятка разных сайтов. И это только вершина айсберга!

Поскольку снапшоты за разное время в «Веб-архив» попали из разных источников, по одному и тому же адресу в таймлайне «Веб-архива» лежат копии разных сайтов. Хорошо бы их найти все и выкачать — это, судя по всему, какой-то совершенно новый пласт информации, сохранённый там!

Попробовать что ли сканер написать, который составит список всего этого богатства…
🔥4🤔1
Посканировал сеть «Веб-архива»

Я был излишне оптимистичен по поводу сканирования локальных адресов «Веб-архива» — не учёл, что таких адресов потенциально несколько миллионов. Была мысль сканировать параллельно, но тоже не вышло — «Веб-архив» через какое-то время банит, если слишком интенсивно бомбить его запросами.

В итоге я взял самый маленький диапазон и стал смотреть только 80-й порт, открывая самый последний снапшот, иначе придётся сканировать много лет.

Даже в таком режим нашлось куча веб-интерфейсов каких-то внутренних систем — роутер «Микротик», мониторинг «Нагиос», несколько серверов «Петабокса» и прочее, а так же множество каких-то частных страничек.

Например, на моём скриншоте найденный блог с рассказом как автор гнобит своего коллегу. Копия этого сайта, кстати, есть на «Веб-архиве» и по внешнему адресу, правда я не в курсе есть ли там этот рассказ.
👍2
«Invalid page» и «тост»

Недавно у одного из клиентов развалилась часть таблицы в «Постгресе» — в логах видно, что при чтении не совпадают контрольные суммы. Ничего особо нового — за последние несколько лет встречал эту проблему несколько раз у разных клиентов и даже описал алгоритм восстановления базы из разных источников у себя на сайте.

Там у меня в заметке есть хранимая функция, которая сканирует таблицу и сообщает какие именно строки требуется восстановить. Но в этот раз она мне, как ни странно, не помогла — завершилась, не выдав ничего. Раньше она осечек не давала и я, не поверив себе, даже запустил её дважды.

Долго разбирался в чём дело, разобрался. Принцип работы моей функции такой — она вынимает каждую строку, если получает ошибку, то сообщает об этом. Но оказалось, что если какие-либо разрушенные данные лежат в «тостах» (это механизм автоматического сжатия и выноса больших значений полей в «Постгресе»), то этого недостаточно. Видимо «Постгрес» в реальности не достаёт эти данные, пока они не понадобятся для чего-либо и поэтому ошибки не возникает.

В итоге я переделал хранимку — передаю всё строку целиком в функцию ROW_TO_JSON, чтобы прочитались и значения из «тостов». Это помогло, функция стала работать как и задумывалось.


CREATE OR REPLACE FUNCTION check_table(table_name TEXT)
RETURNS void AS $$
DECLARE
rec RECORD;
row_data RECORD;
BEGIN
FOR rec IN EXECUTE format('SELECT ctid::text AS ctid_str, id FROM %I', table_name)
LOOP
BEGIN
EXECUTE format('SELECT * FROM %I WHERE ctid = %L::tid', table_name, rec.ctid_str)
INTO STRICT row_data;

row_data := ROW(ROW_TO_JSON(row_data)); /* to read the toasts */

EXCEPTION WHEN others THEN
RAISE WARNING 'CTID: %, ID: %, Error: %', rec.ctid_str, rec.id, SQLERRM;
END;
END LOOP;
END;
$$ LANGUAGE plpgsql;
🔥2
«Кардпьютер» и джойстик

Так я и не смог заказать нужный мне джойстик к «Кардпьютеру» — как я уже рассказывал везде конец истории один — отправляю деньги, продавец выжидает, потом отменяет заказ, деньги возвращаются. В итоге сделал ход конём — купил джойстик другой версии и просто дописал прошивку, чтобы она его поддерживала.

Оказалось несложно — я нашёл коммит, где добавили поддержку другого джойстика, там очень понятный код. Заработало сразу почти правильно, только пришлось поменять верх и низ местами. Эмулятор я пока не нашёл (если предположить, что он существует), а сама прошивка компилируется очень просто, запишу себе, чтобы не забыть:


# установка всех нужных инструментов
curl -fsSL -o get-platformio.py \
https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
python3 get-platformio.py

# сборка прошивки
~/.platformio/penv/bin/pio run
👍4