Как стать автором
Обновить
-8
0
Иван Левашев @OCTAGRAM

Удалённый программист Delphi+Ada

Отправить сообщение

У Магистра была не только 8-битная клавиатура, но и 16-битный Магистр16 с клавиатурой (внешней). В 16 битах-то есть, где разгуляться.

SEGA делала клавиатурные приставки, но 8-бит Sega Master System, а следующий раз 32-бит Sega DreamCast.

Ещё можно за импровизированную консоль посчитать старый ПК, который прокачали видеокартой NEC PC-FX GA ISA DOS/V. Это есть и консоль такая NEC PC-FX, и по мотивам консоли видеоускоритель сделали со спрайтами. В основном, видеоускорители проприетарного формата для NEC PC98, но были и для обычного ПК версии ISA, у них в названии DOS/V.

Для прозрачного проксирования HTTPS надо учесть, что старые системы не поддерживали SNI, причём, это даже не такая уж старая Windows XP. А без SNI надо изгаляться. Например, на уровне DNS выдавать под каждый домен новый IP, а потом при попытке подключиться к IP вспоминать, от какого он был домена. А когда DNS генерил IP, то DNS не знал, будет ли IP использоваться для HTTP, HTTPS или для вообще не HTTP подключения. Так что и все остальные порты надо чем-то перенаправить, чтоб шли в хороший настоящий IP. Чем такую магию творить?

У меня, допустим, в макросе исходных текстов раскраска слетала от любых русских букв. В старом LaTeX русские буквы вроде бы как тоже в какие-то макросы превращаются вроде \yo, и этот макрос ломает раскраску исходных текстов

Да из-за этой физики жидкостей у меня грибница проседает до 20 UPS. Впрочем, я так точно и не знаю, от чего больше всего проседает UPS в грибнице

За любимое дитя я голосовал за Factorio 2.0. А ещё Pacific Drive для тех, кому не зашли приколы второго Сталкера, а хочется аномалий. Из знакомых (относительно) игр в списке только Metro Awakening

Мне кажется, VLIW неудачная именно для Windows в начале 2000х. Во-первых, Itanium и Itanium2 двоично не совместимы, и это как-то анти-Windows, анти-Реймонд Чен. Во-вторых, Windows, — это такая экосистема, в которой Microsoft худо-бедно понимает, как делать операционную систему, но ничего не смыслит в компиляторах, библиотеках, да и хорошо, что не смыслит, Microsoft, отодвинься, дальше мы сами напишем компиляторы, программы, и будет хорошо. Возьмём Delphi и напишем QIP, The Bat! и Total Commander с плагинами. Где-то ещё рядом агитируют с Delphi на Аду апгрейдиться. Доминирование Win32 в первой половине нулевых было хорошей питательной средой, чтоб пробовать новое. Работал COM, и через COM разноязыковые компоненты дружить. Помню, целые компакт-диски библиотек ActiveX продавались.

А на Itanium раз, — и ничего нет. Звенящая пустота, задорого. Под Transmeta Crusoe хоть транслятор x86 быстрый был, а на Itanium только какое-то исполнение x86 на одном ядре VLIW.

Я тут пытаюсь VPN службу на Android Delphi распинать. В пересчёте на 8-часовые дни, наверное, тоже на неделю потянет. В принципе, есть много, с чем согласиться и не согласиться.

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

Создание новой службы Android Delphi
Создание новой службы Android Delphi

Вот просто смотришь, и фрустрация. Эм… ну… VPN бы мне. А что из этого VPN? После изучения иерархии классов понятно, что точно не Intent. А что тогда? VpnService = Local или Remote? А если я ошибся и выбрал не то, как исправить. На что это влияет?

Тут, конечно, много открытий ждало меня. Но вспоминая полностью независимую разработку на Objective-C 2.0, я всё ещё считаю, что оно того не стоит. Только Elevation через XPC был оправдан, а всё остальное не стоило того. UI и JSON постоянно менять в двух клиентах, и отказались от этого.

Примеры игрушечных VPN на Java/Kotlin есть, но я же ничего действительно толкового не могу с ними сделать, если я не врубился, так как же всё устроено. Android VpnService = Local или Remote? Started или Bound? Как узнать, что служба запущена? Для VPN несколько примеров на Java/Kotlin, и они отличаются. Запросто может отсутствовать проверка, что VpnService уже запущена. Остановка службы из программы сделана по-разному. Без понимания сути не сильно бы это помогло. А с пониманием сути удобнее поддерживать кроссплатформенный единый код, допиливая рашпилем только выходы наружу в операционную систему.

Ну да, кое-что Embarcadero стоило бы расписать получше в документации.

и в какой школе их дают?

Например, в гимназии №42 г. Барнаула. Меня в неё пытались перетянуть ещё в 8м классе, заметив на олимпиадах, но оттянул этот момент до 9го, когда аттестат выдают. В новой школе и на математике было, допустим, интегрирование рациональных функций. Отсюда способ узнать, где такие школы: куда перетягивают олимпиадников.

До этой гимназии ещё ходил в кружок информатики, который сначала размещался в АКИПКРО (центр повышения квалификации преподавателей, в котором преподаватели хорошие со всего города были, особенно те, кто кружки вели), потом в школе №22. Как сама школа, не знаю, но вот кружок там какое-то время был, да.

В ЛКШ мне довелось побывать только один раз. Именно там нам преподавали дерево Фенвика, которое на самом деле дерево Рябко, и ещё дерево отрезков. Так и не помню, чтобы это где-то на олимпиадах пригодилось, но в душу запало. Этот один раз пришёлся как раз между 10м и 11м классом в гимназии №42. Чтобы туда поехать, надо деньги собрать. Нет, не так. Надо и узнать про ЛКШ, и после того, как узнать, ещё и деньги собрать. У меня родители оба программисты, но в житейском плане глупые, и в своей глупости невероятно изобретательные, оба нашли способы, как, будучи программистами, умудриться остаться в нищете. Чтобы поехать в ЛКШ, это какой-то предприниматель оплатил, который считал, что морально должен. Это мог быть МИТРА, Энтерра или Сибирикс. Отсюда ещё один способ узнавать, где такие школы: смотреть, откуда едут в ЛКШ. Каким школам доверяют местные предприниматели. Кроме Перми. Из Перми ехать далеко не надо.

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

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

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

left/right указателями

Так left/right в двусвязном списке, а в дереве left/right/parent. И если надо обменять два узла, то, как я сейчас понимаю, надо расписать отдельные случаи, когда два обмениваемых узла друг с другом не связаны напрямую, и когда связаны. Это я сейчас понимаю, а сам писал так, что LRP из одного скопировали во временные переменные, потом LRP из другого вставили во временные переменные, потом выгружаем, поменяв местами, потом у нас всё глючит, потом мы понимаем, что среди LRP, что у первого, что у второго могли оказаться 1 или 2, а мы же их типа меняем местами, а если мы их меняем местами, то надо в во временной копии LRP искать, а нет ли среди них 1 или 2, и если есть, то 1 заменять на 2 и наоборот, и только после подстановки вписывать обратно.

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

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

Без практики и тренеровок, минут за 30, в крайнем случае за час, такую структуру вам любой олимпиадник напишет.

Было бы небезынтересно узнать, правда ли любой. Насколько любой. Я вот помню, что проталкивание предпотока не осилил. Так и был Форд-Фалкерсон всю дорогу. У всех какие-то лоскутные одеяла, кто что понял, но если по трое собрать, шансы на успех выше. А про декартово дерево я даже не помню, пытались нам его преподать или нет. Ни про дерево это особо не знал, ни даже что олимпиадникам его следует знать. Сильно позже школьных олимпиад, когда с олимпиадниками общался, мне поведали, что декартово дерево раньше писали. Ну, правда, это такое раньше, в котором C++ на олимпиадах не было, и декартово дерево было в роли обычной карты, а не для того, чтобы было, что аугментировать.

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

Так вот, это прибавляет некоторого скепсиса по поводу того, что прям-таки любой олимпиадник.

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

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

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

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

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

Пока такие мысли после прочтения.

В Хаскелл трассирующая сборка мусора, которая далеко не всем подходит. TGC, — основная причина, по которой я отбриваю функциональные языки программирования, а по заветам Ивана Чукича пишу на Delphi и Ada. И только Кока своим гениальным выбором подсчёта ссылок поколебал этот статус кво. Ну в самом деле, если они там в ФП такие умные, должен же был когда-то Боженька хоть кому-то дать мозгов сделать язык без непрошенного TGC.

Хаскелл транслируется через свой C--, который может быть хорош для поддерживаемых платформ, но пролетит мимо Эльбруса. Кока транслируется в Си.

Ещё про Коку пишут, что там FBIP, Functional But In-place. То есть, если такое возможно, то замена производится прямо на месте, как в императивных языках. Вот если ошибиться и выбрать трассирующую сборку мусора, то всё, приплыли, уже такие плюшки не получим. А тут сделали правильный выбор и с правильным выбором пошли требовать причитающиеся плюшки.

Когда я делал такую штуку для оптимизированной замены TCollection и TList в Delphi, в той литературе, которая мне попадалась на тему, это называлось order statistic tree, без какой-либо привязки к декартовому дереву. Я плясал от дерева отрезков, ведь по-любому же дерево отрезков можно припахать для индексации, и так вышел на то, что могут и припахивают. Моё дерево было АВЛ, а подошло бы и красно-чёрное.

в западной литературе, статьях и Интернете ни одного упоминания о декартовом дереве по неявному ключу мне найти не удалось

Раздобыв Кнута и первую редакцию Кормена, я обнаружил, что там всё это время было упоминание о такой возможности. Кстати, Кнут справедливо упоминает о том, что, раз уж мы в каждом узле храним вес, а неплохо бы и сбалансированное дерево взять WBT, чтоб одним и тем же параметром и балансировалось, и индексировалось. В функциональных ЯП оно почему-то популярно, какой Хаскелль ни возьми, а в императивных скорее КЧ или АВЛ будет.

Никогда и нигде я на этом пути не встретил термина implicit treap.Сегодня я искал про верёвки, и так через NEERC вышел на этот термин. На английской Вики связал термины, а у кого есть доступ, предлагаю в NEERC тоже связать.

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

Дело в том, что в TList можно писать одинаковые указатели, и сам TList не интрузивен, так что интрузия производится в TListSlot, невидимый извне. И в этот слот вгрызание производится дважды: один раз для обычного индекса, второй раз для ускорения IndexOf. Чтобы IndexOf мог работать, он должен для выбранного значения возвращать самый первый индекс среди одинаковых значений, а на случай, если вдруг его удалят, он должен оптимально узнавать следующий такой же. Так что IndexOf должен знать вообще все одинаковые указатели, и в том порядке, как они в списке. Для IndexOf строится карта с составным ключом (значение, индекс в списке). Здесь индекс в списке может гулять, но предполагается, что если в TList вставляют и удаляют какие-то другие значения, то все остальные значения остаются друг относительно друга в том же порядке, так что на конкретный вызов метода TList индексы определены и их можно сравнивать, но между вызовами устаревают, но порядок сохраняется. Так вот, если значения отличаются, а это почти 100% так, то и не надо вычислять индекс в списке, тратя O(log n) времени и превращая общую стоимость в квадрат логарифма.

Можно было вместо составного ключа сделать карту карт. Для оптимального XPath так и было сделано. То есть, если есть <A/><B/><A/><B/><C/>, то для поиска B[2] честно строится карта всех B, упорядоченных по их индексам в объемлющем теге, и среди них ищется второй, который в общем списке окажется четвёртый, а четыре больше двух, где находится B[1]. Учитывая, что в TList почти наверняка все элементы разные, вот прямо очень не хотелось два слоя, так что сделал карту в один слой, но с составным ключом, и по возможности во всей полноте вычислять этот ключ не надо. Чтобы искать по карте, можно сделать поиск (значение, -1), и ничего не найдётся, но относительно этого ничего можно посмотреть значение в более правом элементе, и если совпадает, то это то, что надо.

Да есть разработчики, которые упорно тащат UUIDv5 в БД, так как у них в источнике данных строка, а в БД у них уже UUID ("исторически так сложилось").

О, даже так. Ну, я в шоке с них.

Просто если не самый новый Постгрес брать, там ничего встроенного, кроме UUIDv4, не было. И если Delphi взять, там ничего, кроме UUIDv4, из коробки нет. И так типично повсюду. Это надо специально заморочиться, чтобы какой-то другой UUID появился, ну вот я и подумал, что тот, кто заморочился, отдаёт себе отчёт, что делает. Когда я заморачивался с UUIDv5 в Delphi, я отдавал себе отчёт.

внутри одной таблицы совместимы UUID любых версий

Имелась в виду не принципиальная возможность набить как в бочку селёдки, а только дружественная к производительности.

Да, есть такая проблема, но она успешно решается в современных СУБД.

Ну, если она и правда так успешно решается, то нет применения v7, когда есть v4, а кто-то изобретательный ещё любит v5 в первичных ключах.

Я бы добавил: вставка записи с первичным ключом UUID

Очень странно, что вы пишете про UUIDv1-5. Я думаю, большинство не знало ни о чём, кроме UUIDv4.

А UUIDv3 и UUIDv5 суть MD5 и SHA-1 от строки, посоленной UUID пространства имён, и их смысл в том, чтобы повторяемо преобразовывать одну и ту же строку в один и тот же UUID. Например, параметризованные интерфейсы Windows Runtime обладают PIID, который по традиции может быть UUIDv4, а специализации интерфейсов имеют IID, вычисленный как UUIDv5 от специально составленных машинных строк с участием PIID и закодированных типов-параметров. Ну и ещё там участвует, конечно, пространство имён специализированных интерфейсов. Это я всё расписал к тому, что в Windows Runtime понятно, как и зачем повторяемо вычислять UUIDv5, а в базе данных применять UUIDv5 почти то же самое, что применять строку в качестве первичного ключа, но если у вас на примете есть строка, подходящая на роль первичного ключа, то почему бы не взять её напрямую.

В UUIDv4 первые шесть байтов заполнены случайно. В UUIDv7 первые шесть байтов заполнены 48-битным временем в миллисекундах с потенциально каким-то смещением. Можно от эпохи Юникс, но стандарт допускает смещение, и тогда это просто какое-то миллисекундное время. Среди прошлых UUIDv4 случайные значения как-то по Пуассону заполнили диапазон, а когда мы начинаем подмешивать UUIDv7, то они интенсивно заполняют очень узкую полосу значений, и всё, что оказалось правее, становится практически вечными кандидатами на смещение. Если не сдвигать время, справа оказывается чуть менее, чем всё.

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

Устаревшим можно считать UUIDv3 (MD5), так как есть UUIDv5 (SHA-1), но если где-то уже принято использование UUIDv3, то от него не представляется возможным отказаться. А UUIDv5 не устарел, замены-то ему нет. Но в базе данных ни то, ни другое вряд ли встретишь из-за их антисуррогатной природы, а на месте UUID в базе данных обычно ожидаются суррогатные ключи. И UUIDv4 не устарел, другое дело, что мы можем больше не хотеть писать UUIDv4 именно в базу данных.

Устаревшим можно считать ULID, с которого и начался сыр-бор с отказом от UUIDv4. У ULID нет номера. Ну или номером ULID можно считать UUIDv7, который его стандартизирует.

Нельзя однозначно считать устаревшим UUIDv6, который просто поменял порядок байт UUIDv1, и больше ни на какую новизну не претендовал. Я так понял, кому-то очень полезно, что в UUID штампуется идентификатор узла, и они осознанно применяют UUIDv6, а не UUIDv7.

Если не использовать сдвиг времени, то ULID, UUIDv6 и UUIDv7 совместимы внутри одной таблицы.

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

Сейчас активно ищу ноут на 486/586 для тестов

Hand386 собирает любитель. Минус, что 386. Плюс, что ISA можно из него наружу вытащить. Не очень понял, подходит ли к нему плата AdLib, или это только для Book8088. Кроме AdLib, встроенного звука там быть не может, но хоть через ISA можно подключить всякое

Учить надо не только ассемблер, но ещё и https://koapp.narod.ru/tehlit/hardware/27videoega/ega_1.htm

А что про UEFI программирование? Уже сделали UEFI Commander и тетрис

Тачскриновые кнопки как-то не очень. Лучше как была панель 123456789, так и воспроизвести. Как ожидают игры J2ME и N-Gage 2.0

1
23 ...

Информация

В рейтинге
Не участвует
Откуда
Воркута, Коми, Россия
Дата рождения
Зарегистрирован
Активность