У Магистра была не только 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, и этот макрос ломает раскраску исходных текстов
За любимое дитя я голосовал за 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
Вот просто смотришь, и фрустрация. Эм… ну… 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/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 в первичных ключах.
Очень странно, что вы пишете про 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, тогда снова начинаем раздвигать записи.
Hand386 собирает любитель. Минус, что 386. Плюс, что ISA можно из него наружу вытащить. Не очень понял, подходит ли к нему плата AdLib, или это только для Book8088. Кроме AdLib, встроенного звука там быть не может, но хоть через ISA можно подключить всякое
У Магистра была не только 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 выглядит так:
Вот просто смотришь, и фрустрация. Эм… ну… 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/parent. И если надо обменять два узла, то, как я сейчас понимаю, надо расписать отдельные случаи, когда два обмениваемых узла друг с другом не связаны напрямую, и когда связаны. Это я сейчас понимаю, а сам писал так, что LRP из одного скопировали во временные переменные, потом LRP из другого вставили во временные переменные, потом выгружаем, поменяв местами, потом у нас всё глючит, потом мы понимаем, что среди LRP, что у первого, что у второго могли оказаться 1 или 2, а мы же их типа меняем местами, а если мы их меняем местами, то надо в во временной копии LRP искать, а нет ли среди них 1 или 2, и если есть, то 1 заменять на 2 и наоборот, и только после подстановки вписывать обратно.
А до временных переменных ещё догадаться надо было. Мы же в двухсвязных списках без переменных обходились, ну и тут то же. Но нет. Тесты не проходят, тесты показывают, что из-за того, что что-то не в правильном порядке перезаписывалось, обращение по перезаписанному указателю идёт уже в какой-то другой объект.
Спустя время понимаю, что, пожалуй, если бы взять и разделить ситуации прямого родства от ситуации любого далёкого родства, я бы, скорее всего, написал сразу правильно. В двусвязных списках если нужно кодировать обмен и если не расписать отдельную обработку для непосредственных соседей, тоже можно угореть пытаться отладить код, общий на все случаи жизни. Но в двусвязных списках редко нужен обмен, а в деревьях сразу как только понадобилось удаление. Кстати, возможно, что на олимпиаде не понадобится. Но в жизни оно точно нужно.
Было бы небезынтересно узнать, правда ли любой. Насколько любой. Я вот помню, что проталкивание предпотока не осилил. Так и был Форд-Фалкерсон всю дорогу. У всех какие-то лоскутные одеяла, кто что понял, но если по трое собрать, шансы на успех выше. А про декартово дерево я даже не помню, пытались нам его преподать или нет. Ни про дерево это особо не знал, ни даже что олимпиадникам его следует знать. Сильно позже школьных олимпиад, когда с олимпиадниками общался, мне поведали, что декартово дерево раньше писали. Ну, правда, это такое раньше, в котором 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), и ничего не найдётся, но относительно этого ничего можно посмотреть значение в более правом элементе, и если совпадает, то это то, что надо.
О, даже так. Ну, я в шоке с них.
Просто если не самый новый Постгрес брать, там ничего встроенного, кроме UUIDv4, не было. И если Delphi взять, там ничего, кроме UUIDv4, из коробки нет. И так типично повсюду. Это надо специально заморочиться, чтобы какой-то другой UUID появился, ну вот я и подумал, что тот, кто заморочился, отдаёт себе отчёт, что делает. Когда я заморачивался с UUIDv5 в Delphi, я отдавал себе отчёт.
Имелась в виду не принципиальная возможность набить как в бочку селёдки, а только дружественная к производительности.
Ну, если она и правда так успешно решается, то нет применения 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, тогда снова начинаем раздвигать записи.
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
Может быть, запрограммировать Intel Atom E6x5C