Pull to refresh
4
0
Send message

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

В данном случае проблема не в этом, а в "наивной" реализации, ещё и не на ассемблере с трюками. А то бы кубик вполне себе вертелся со скорость 50 fps.

Вы это серьёзно или тролите?
Это же 8-ми битный компьютер с частотой процессора 3.5 МГц. Кроме того, это так называемая проволочная графика (wireframe), а не растровая — тут нет ни каких граней, на отсечении которых можно сильно сэкономить. Максимальная экономия из-за "отсечения" тут будет заключаться только в том, что надо будет в лучшем случае нарисовать 4 линии вместо 16-и. И то это редкий случай, когда кубик "смотрит" прямо на нас одной из своих "граней".
Ну и как уже писали выше — надо писать на ассемблере и использовать разные трюки для ускорения.

У MongoDB есть только один отличительный и важный плюс перед реляционными решениями. И при выборе базы имеет смысл учитывать только его. Это простое шардирование из "коробки".
Это то, ради чего она создавалась. И как писали выше — то из-за чего всё остальное в монге сделано так, как оно сейчас есть.
Если вы не планируете использовать шардирование, то выбор MongoDB в качестве основной базы — очень спорное решение. Для этого надо очень хорошо знать и понимать ради чего же вы её выбираете.
Ну и конечно поддержка шардирования — это не совсем "бесплатная" фича. Часто об этом не говорят, расхваливая монгу. Оно требует правильного проектирования того, как вы храните данные в базе. Не получиться просто так взять и включить шардирование в продакшен базе, которая под это не планировалась.


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


  • Отсутствие схемы — маркетинговая уловка. Схема, и все гарантии связанные с ней, просто переезжает в приложение. Да, это добавляет гибкости — можно навертеть чего угодно. Но усложняет приложения для наиболее типовых ситуаций. Кроме того это увеличивает объёмы базы, т.к. каждый документ, кроме своих данных, хранит так же имена полей. Можно найти рекомендации использовать в MongoDB как можно более короткие имена полей, если есть проблема с местом под базу.
  • Отсутствие JOIN-ов и как решение этой проблемы — денормализация. Это точно не плюс — это просто особенность реализации. Возможности денормализации в монге ограничиваются размером документа (16 Мб по умолчанию). Об этом маркетологи забывают упомянуть. А если надо поддерживать актуальность вложенных документов — это становится головной болью из-за отсутствия в монге транзакций (об этом далее). "Эмуляция" JOIN-ов в приложении — в принципе работающее решение, но не самое дешёвое в плане реализации и требуемых ресурсов. Есть ещё $lookup для агрегаций, но он не работает на шардированных коллекциях. А, как я писал выше, монга без шардирования — это очень странный выбор. Денормализацию можно использовать и в реляционных базах (и типы вроде JSONB этому только помогают).
  • Транзакции — можно считать, что их нет. Они конечно заявлены в версии 4.x, но пока что они работают только в реплик-сетах и без шардирования. Можно конечно и без них прожить, до тех пор пока у вас нет необходимости атомарно вносить изменения более чем в один документ. А как только это понадобится, то придётся навешивать костылей в коде приложения и очень внимательно и аккуратно проектировать структуру коллекций и документов, создавать доп. сущности. Например делать эмуляцию транзакций, что бы после завершения всех изменений можно было обновлением ОДНОГО документа сделать "commit", который сделает изменения "видимыми" для приложения. Плюс делать крон-задчу, которая ищет зависшие "транзакции" и удаляет их. Другой вариант — сделать так, что бы "транзакцию", которая прервалась, можно было продолжить с места обрыва.
    В этом контексте очень странно видеть платёжные системы в списке проектов с Монгой. Надеюсь она там используется для хранения не очень важной информации.

Я уже 9 лет работаю с MongoDB и много раз мы на неё ругались, плевались, писали в приложении больше кода, чем могло бы понадобится если бы были транзакции. Мы заранее понимаем, что любые простые счётчики "документов" в монге по умолчанию врут, и если их значение очень важно — надо писать крон-задачу, которая будет делать агрегацию и обновлять счётчики. Любые задачи, требующие изменения нескольких документов, вызывают "изжогу", т.к. приходится делать выбор: или писать доп. код для обеспечения гарантий, или забить и будь как будет — в случае чего руками в базе поправим.
В данный момент мы не планируем мигрировать с неё на реляционки только из-за шардирования — всё остальные "плюсы" вообще ни как не лочат нас на монгу.

Как бы вы не уменьшали размер вложенного документа, если их количество ни чем не ограниченно, то у вас нет 100% гарантии, что однажды вы не упрётесь в лимит 16Мб. 16Мб для большого проекта — это не так и много.

работают они только в режиме графики с низким разрешением 32х48

Формально у спектрума нет такого режима. У него вообще только один режим — 256x192. А 32x48 — это судя по всему эмуляция за счёт оперирования с областью памяти управляющей цветами "чернил" и "фона" для знакоместа (8x8 пикселей). Разрешение в знакоместах у спектрума — 32x24. Если закрасить верхнюю половину каждого знакоместа, то можно как раз эмулировать 32x48 путём изменения цвета "чернил" и "фона" для нужного знакоместа. В вашем видео это видно — горизонтальные линии в два раза тоньше вертикальных.


А при работе с реальными пикселями может оказаться выгоднее просто ещё раз "нарисовать" те-же самые линии фоновым цветом (технически сбросить биты пикселей в 0). Если область изображения и число линий не велико, то это может оказаться быстрее, чем обнулять весь "буфер экрана".
Ну или можно было стирать не весь экран, а только ту часть, которую занимало изображение. А ещё оптимальнее было бы "нарисовать" всё куда-то в отдельный буфер-спрайт, и потом его скопировать в буфер экрана, тем самым затирая изначальное изображение. Что бы не было "тиринга" надо синхронизировать этот процесс с "обратным ходом луча ЭЛТ" — для этого в спектруме использовалось специальное прерывание.


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


Когда у меня был в своё время клон спектрума, я тоже делал такие штуки. Но я использовал вычисления с фиксированной точкой (уже не помню с какой точностью, возможно 16 бит на целую часть + 16 на дробную). Синусы и косинусы хранил в заранее посчитанной "таблице" с шагом 1 градус. При таком низком разрешении экрана и не очень больших объектах — этого вполне хватало. Ну и кроме того вращал я всё с шагом в 1 градус, поэтому не надо было ничего интерполировать. Писал я всё на ассемблере.

Это называется вычисления с фиксированной точкой, можно в интернете найти информацию об этом. И удобнее их делать с выравниванием по байтам. Например в случае 16-и битной точности старший байт — целая часть (от -128 до +127), младший — дробная. Не надо будет заморачиваться со сдвигами и делениями — целая часть числа просто лежит в старшем байте.

Если его нет, тогда это не имеет отношения к REST и нельзя использовать это слово. Сам Филдинг запретил "поминать всуе" REST, если у вас нет HATEOAS.

Оверхед на создание конектов? Медленная скорость передачи сообщений в REST?
Берём HTTP-клиент с полной поддержкой HTTP2, вместо JSON используем Protobuf и вот у нас уже REST API не в 7-10 раз медленнее передаёт сообщения, а всего 1.x раз (x — оверхед на передачу обязательных HTTP-заголовков, которых, наверное, больше чем в gRPC, но я не проверял).


Компрессия передаваемых данных?
Это есть в самом HTTP.


Балансировка без использования прокси-балансера (т.е. клиент сразу отправляет запрос на нужную ноду)?
Вспоминаем про забытый в статье HATEOAS, который является обязательным для REST. И вот у нас сервер сообщает клиенту на какие URL-ы он должен обращаться, тем самым осуществляя балансировку нагрузки без прокси-балансера.


Итого можно убрать эти пункты из списка отличий, на который надо смотреть при выборе REST API vs gRPC.

Ваш пример с рыбалкой кажется мне не очень удачным, "детским", если смотреть на определения из статьи. Вот какую проблему вы решаете с помощью рыбалки? Где тут "враг", против которого требуются единомышленники? Какой след вы оставите после себя с помощью рыбалки (не считая мусора в кустах)? Рыбалка — это как раз больше про потребление и развлечение.
Как отмечено в статье, главное не интерсы и цели, а проблема, которую вы хотите и можете решить, которая вам интересна. А уже из этого проистекают интересы и цели, которые, очень вероятно, будут аналогичными у "единомышленников" решающих эту же проблему.

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


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


Меня вполне устраивает современный топовый смартфон на Андроид, и у меня нет желания заниматься установкой кастомов только ради того, что бы Гугл знал обо мне немного меньше.
Ни какой вездесущей рекламы в моей стоковой прошивке нет. Мне кажется это "болячка" в основном бюджетных решений, которая позволяет производителям всё таки заработать на них. Хорошие вещи стоят денег, редко они бывают дешёвыми.

Это не только с АлиЭкспресс такое. Очень многие известные интернет магазины и сервисы (например Steam) не требуют повторного подтверждения всех транзакций через 3D Secure после первого подтверждения при добавлении карты. Вероятно это связанно с доверием банков конкретному магазину или платёжной системе.

Я вполне могу интерпретировать современные мобильные и веб приложения именно как "начать работу не обладая никаким знанием".
В мобилках, используя code-on-demand (установку приложения из "магазина"), мы получаем от сервера код, который расширяет возможности операционной системы и позволяет ей "узнать" как работать с внешним сервисом. В дальнейшем этот "код" продолжает следовать инструкциям сервера, и использовать данные и ссылки полученные от него.
С веб-приложениями это ещё более всё очевидно — юзер вбивает в браузере адрес сайта, и получает готовое приложение, которое меняет своё состояние либо только с помощью пользователя (обычные HTML страницы с формами) или подгружает JS-код и может какие-то действия выполнять "самостоятельно".

Но тем не менее — это надо назвать. Т.е. надо написать доку для системы, в которой будет указано: "Вот это и это — считать кешируемым по умолчанию".


Если в доке для системы нет ни каких указаний по поводу того как работает кеширование, то можно воображать что угодно. Лучше такую архитектуру не причислять к "REST".

Версия/ETag ресурса, например, это контракт, с помощью которого и клиент может понять, что произошло, и сервер может нивелировать проблемы.

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


Тем не менее, ни о каких ожиданиях сильной/слабой консистентности в REST нет ни слова.

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

Ну там много над чем надо работать, т.к. это всего лишь принципы. И они даже не для непосредственно разработки системы, а для его архитектуры.
Например в HTTP таким "implicitly labeled" могут быть определённые статусы ответа.
RFC 7231


Responses with status codes that are defined as cacheable by default
(e.g., 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, and 501 in
this specification) can be reused by a cache with heuristic
expiration unless otherwise indicated by the method definition or
explicit cache controls [RFC7234]; all other status codes are not
cacheable by default.
no prior knowledge beyond the initial URI

Это только про URI, а не вообще про всё на свете, кроме начального URI.


all application state transitions must be driven by client selection of server-provided choices that are present in the received representations

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


The transitions may be determined (or limited by) the client’s knowledge of media types and resource communication mechanisms, both of which may be improved on-the-fly (e.g., code-on-demand).

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


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

Клиент вправе ожидать то, что оговорено контрактом, в том числе сильной консистентности и неизменности «своих» данных, если таков контракт.

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


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

Можно не предусмотреть в дизайне способа управления этим кешированием с обеих сторон.

Каким образом клиент узнает свой user_id?

Скорее всего он узнает этот URL в процессе авторизации, когда будет создавать токен или сессию. Сервер вернёт ему этот URL в теле ответа, как и завещает делать HATEOAS.
Я именно так и делаю.

раз можно сделать альтернативную имплементацию сервера — значит, можно сделать и многослойную архитектуру, поставив дополнительный прокси между клиентом и сервером;

Если можно что-то сделать, то это не означает что это "разрешено". "Многослойность" архитектуры должна быть изначально заложена в неё, что бы разработчики сервера и клиента всегда помнили об этом, и соответствующим образом писали код. Иначе они могут сделать не верные предположения (например, что клиент всегда напрямую соединяется с требуемым приложением на сервере), и не корректно реализовать некоторые кейсы.


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

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


Что касается правила на букву S («stateless»), то систем, в которых сервер вообще не хранит никакого контекста клиента в мире вообще практически нет, поскольку ничего полезного для клиента в такой системе сделать нельзя.

Под stateless подразумевается не то, что какая-то из сторон ничего не хранит, а только то, что стороны процесса не должны рассчитывать на то что другая сторона буквально "помит" их предыдущие запросы и принимать на основе этого какие-то решения.
Например клиент не должен ожидать от сервера какой-то особой "памяти" и считать, что раз он только что создал на сервере документ, то он 100% получит его обратно вторым запросом. Как будто сервер — это гардеробщик, который запомнил вас в лицо и выдаст куртку без предъявления номерка, и заодно он ещё волшебник — создаст куртку из воздуха, если её успели украсть (удалили документ).
Это ограничение направлено на возможность простого горизонтального масштабирования сервисов. Что бы не было проблем, если первый запрос клиента обработает первая нода кластера, а второй запрос прилетит на вторую ноду, которая ничего не знает про первый запрос.


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

Это Вы сами додумали и перегнули палку. Нет у Филдинга такого. HATEOAS не требует написание "всемогущего клиента с ИИ". Он нужен только для того, что бы клиент не хардкодил конкретные ссылки, которые требуются для выполнения его задач. Он должен только знать где и как их найти в ответах сервера.
Например как человек на веб-сайте интернет магазина ничего не знает о том, на какую ссылку ему перейти, что бы получить информацию о товаре или добавить его корзину. Но человек знает (ему показали другие люди или он прочитал об этом, в общем у него есть "знание"), что надо искать в тексте особые надписи-ссылки или кнопки, на которых будет написано нужное ему действие (например "Добавить в корзину"). После чего нажимает на них и браузер переходит на нужную страницу или посылает POST запрос на какой-то URL. При этом даже сам браузер не знает смысла этих URL-ов — их сообщил ему сервер. В этом случае человек действует по вполне определённому алгоритму, который очень просто формализовать.
Точно так же и "программный" клиент для API может извлекать из ответов сервера ссылки, нужные ему для выполнения конкретной задачи (которую в него заложили программисты, а не он сам как-то выдумал её по ответам сервера). Для этого просто достаточно дать ссылкам понятное фиксированное название. Для человека это был текст "Добавить в корзину", а для "программы" будет в ответе сервера поле с именем "add_to_cart", а конкретная ссылка будет в значении этого поля.
И как для человека, отсутствие кнопки на странице, означает что он не может выполнить это действие, так и для "программы" отсутствие в ответе ссылки с названием "add_to_cart" может означать, что это действие нельзя выполнить (например товар закончился на складе).
HATEOAS требует только наличие гиперссылок, но не требует что бы клиент как-то мог только по одному тексту ссылки догадываться как её использовать, каким методом её вызывать и какие параметры передавать. Всё это может быть либо заложено в клиент. Либо, как в случае с браузерами, ссылка ведёт на другую страницу, где может находится HTML-форма в которой есть чёткие инструкции для браузера куда и какие данные надо отправлять. Или на другой странице может быть встроен code-on-demand, который выполнит требуемое действие.
Т.е. всё это не является чем-то не реализуемым и волшебным как "всемогущий ИИ".


Как-то вы вскользь упомянули про HATEOAS в начале статьи, хотя Филдинг-2008 чётко написал в конце заметки, что "hypertext constraint" это наиболее важная штука. И если у вас его нет, то не используйте слово REST, придумайте что-то другое.


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

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


О метапрограммировании и REST по Филдингу

Про это я уже выше написал. Нет ни какой необходимости в сильных ИИ, что бы система могла соответствовать термину REST. Все задачи по прежнему можно решать с помощью умных людишек. Для начала они могут написать клиент, который умеет выполнять конкретные задачи не зашивая у себя в коде полные ссылки на все API-методы. А если потребуется налету добавлять в него новый функционал, то это делается с помощью code-on-demand. Людишки пишут код, а сервер этот код передаёт клиенту для выполнения.
Или вы считаете современные браузеры вершиной развития машин, и они умеют сами себя расширять без привлечения программистов? А ведь браузер — это наверное один из самых лучших клиентов, которому не стыдно повесить ярлык "REST compatible". Ну или правильнее этот ярлык повесить на HTTP + HTML&Co.

Information

Rating
6,045-th
Location
Россия
Registered
Activity