Pull to refresh
19

User

9
Subscribers
Send message

Хм, а если бы они вместо cookies сохраняли бы в LocalStorage то штрафа бы не было? Вообще непонятно почему вокруг GDPR и закона про персональные данные все говорят только про куки если есть еще куча различных способов сохранить индефикатор сессии на устройствах клиента

Пожалую попробую прояснить подробней — суть не в том чтобы юзать kvm вместо докера — тут суть в том чтобы избавиться от лишнего программного слоя. Сейчас когда заказываем машинку у хостера (vps или различные облачные решения) то вместо целой физической машинки получаем лишь запущенный образ виртуальной машины с другими такими же соседями.
И дальше поверх этой запущенной машины мы добавляем еще один программный слой в виде докера для еще одной изоляции. И появляется вопрос — почему нельзя точно также как с докером собрать весь код, зависимости и окружение вместе в виде некого контейнера но только без докера? То есть это будет не контейнер (который будет запускаться внутри виртуальной машины которую нам предоставил хостер) это будет уже сразу готовый iso-образ операционной системы который будет запущен хостером на той виртуальной машине которую мы арендуем.
Уже сейчас многие хостеры предоставляют возможность загрузить кастомные iso-образы — и если можно собрать весь код и деплоить сразу в виде iso-образа то тогда докер становится просто ненужной абстракцией и лишним программным слоем

А чем же миграция через сборку нового iso-образа вместе запуском нужного кода в качестве init-а (pid 1) будет отличаться от сборки такого же docker-контейнера где будет минимум ненужного софта (FROM scratch + статически собранные бинарники, либо только самое необходимое)? Как по мне отличий практически нет — iso-образы наверняка точно также можно собирать инкрементально, деплой и миграцию также можно автоматизировать.

А я вот не понимаю зачем нужен докер. Сейчас большинство хостеров и так используют kvm для виртуализации и разделения ресурсов, так зачем внутри такой vm которая предоставляется клиенту нужна еще одна абстракция для разделения ресурсов? Почему нельзя взять код сервера и необходимые зависимости (обычно это ядро линукса + код бэка, то есть никакого ненужного и предустановленного софта в виде различных linux дистрибутивов, даже busybox и ssh-сервер с таким подходом будет не нужен) и запаковать его в виде образа vm (обычно это iso-файл) и загрузить через апи хостера как kvm-образ и запустить как обычный сервер. Таким образом получаем все те же плюсы что у докера, но главное — мы избавляемся от лишнего программного слоя и получаем меньшую воронку для уязвимостей поскольку на сервере не будет ничего лишнего (не будет даже открытого ssh-порта так как деплой будет происходить снаружи)

А зачем нужны эти костыли с софтварной растеризацией и перенос на видеокарту в виде текстурки если можно сразу отрендерить на gpu текст через глифы и кривые безье как описано в этой статье — https://medium.com/@evanwallace/easy-scalable-text-rendering-on-the-gpu-c3f4d782c5ac ?

Уже лет 10 как есть webgl, где есть полная свобода и максимальная производительность. Только никто не хочет этим заниматься потому это максимально низкий уровень графического стека — там даже рендер текста нужно делать самому (разбивая текст на глифы а глифы на кривые безье и т.д не говоря уже про поддержку юникода и всех этих сложностей с многоязычным вводом). Но с другой стороны для некоторых кейсов как например редактор кода где многоязычность не нужна и есть только английский моноширинный шрифт задача уже упрощается. Вот тут человек для редактора кода заменил весь этот стек (html/css/svg/2d-canvas) на webgl — https://makepad.github.io/makepad — написал свой рендер текста, рендер прямоугольников и других ui-примитивов, написал алгоритм лейаута подобно флексбоксам и теперь уже пишет высокоуровневые компоненты, логику, фичи и постоянно пишет в твиттере (https://twitter.com/rikarends) как все стало намного удобнее и на порядок быстрее чем с html/css

Спасибо за статью, очень интересно. На первый взгляд кажется что вся эта машинерия и все эти абстракции в android довольно элегантны но чувствую должна быть и критика и перечень недостатков в сравнением с каким-нибудь десктопным ubuntu, так как сейчас есть планшеты как на андроиде так и на десктопных ос (как windows так и на ubuntu, debian и др)

Это мы сейчас фантазируем или это есть в спецификации GQL?

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


А можно пойти дальше и прямо фигачить JS-код получения данных, который так же выносится на сервер, оставляя на клиенте лишь id ручки.

Вооот, вы все правильно поняли — как только мы имеем возможность написать код на клиенте который будет загружен на бэк то рано или поздно появится мысль — а зачем нам этот ограниченный формат graphql который годится всего лишь для вытаскивания вложенных сущностей для которого все равно нужно будет писать большую часть логики в резолверах (проверку прав, фильтрацию и т.д) если можно сразу написать код любой логики обработки запроса используя удобный орм и этот код на этапе сборки заменится айдишником и будет загружен на сервер. В итоге что graphql что rest становятся лишней абстракцией (или технической деталью не говоря уже про транспорты в виде http с его статус-кодами и кучей способов пробросить данные (url, headers, body) или вебсокетов) на пути к высокоуровневой коммуникации клиента с сервером


Впрочем, дебажить такое приложение, где все запросы имеют вид GET /3433523/473842/true — то ещё удовольствие.

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

А какие хостеры предоставляют возможность загрузить свой iso (ну и также управлять запуском сервера) через api а не вручную через ui?

Вместе с айдишником запроса. Например если где-то в компоненте нужно загрузить какие-то данные


const projectWithTasks = await gql`{
  project(id: ${router.params.id}){
    id,
    name,
    tasks(archived: ${router.params.archived}){
      id,
      name,
      completed
    }
  }
}`

то некий плагин на этапе сборки заменит код выше на примерно такой, сохранив аргументы запроса


const projectWithTasks = await gql("id3433523", router.params.id, router.params.archived)

ну а сервер получив айдишник вытащит нужный запрос и подставит в него переданные аргументы

В каком смысле больше, чем нужно?

Скорее всего подразумевалось что больше чем нужно для отображения ui. То есть плохой пользователь может вручную собрать н-этажный запрос и отправить на сервер
Чтобы решить эту проблему можно пытаться анализировать вложенность, сложность, ставить таймауты на время запроса но есть куда более простое решение — на этапе сборки фронта вытащить все graphql-запросы и заменить их айдишниками в клиентском коде и загрузить эти запросы на сервер. И тогда клиент просто не сможет построить н-этажный запрос потому что сервер будет принимать только те запросы которые были вытащены из клиентского кода при сборке фронта.

B-деревья эффективнее работают с кешем процессора

Что внешняя память что оперативка имеет один и тот же параметр — размер блока и понятие локальности когда работать с размерами меньше этого блока не имеет смысла потому что любое обращение к памяти будет грузить или записывать весь этот блок. Соотвественно B-деревья походят не только для внешней памяти а и для структур в памяти поскольку нет смысла делать узел меньше чем размер блока (для оперативной памяти вместо блока используется название "кеш-линия") — то есть для современных процессоров нет смысла делать узел дерева размером меньше 64 байта (размер кеш-линии в x64 и arm). И узнать какой будет ранг у б-дерева можно просто поделив 64 байта на размер указателя на другие узлы (указатели тоже можно закодировать более компактно если ограничить их общее количество)

Когда падает? В рантайме? В момент рендера нужного компонента? То есть для того чтобы задетектить ошибку непрокинутого стора нужно будет запустить приложение, наклацать нужное состояние чтобы отрендерился нужный компонент и только тогда в консоли увидеть ошибку отсутствующего стора? Нет уж, спасибо, я лучше буду импорты юзать с которыми тайпскрипт сразу в редакторе подсветит ошибку в момент копирования файла с компонентом в проект

А используя inject тайпскрипт или флоу покажет ошибку если не был прокинут стор через Provider? Преимущество импортов в том что они статически тайпчекаются и ошибки будут видны сразу а вот все эти инжекты и провайдеры (и прочие di) под большим сомнением (причем если и тайпчекаются то скорее всего нужно будет заимпортить тип чтобы передать дженерик инжекту и тогда смысл в этом вообще пропадает если все равно связь через импорты)

Там сложность зависит от того насколько сильно изменился массив — K*Log(N) где K это количество перестановок в массиве. Например если в списке из 10к элементов произошла перестановка 3 элементов то LIS будет практически линейным — будет последовательно заполнятся массив из 10к элементов и только в трех случаях будет бинарный поиск до нужного элемента. Зато LIS позволит выполнить всего три insertBefore dom-операции вместо почти полного перестроения всего списка как это делает реакт

Про diff списка на основе LIS неплохо описано
в самих исходниках ivi — https://github.com/localvoid/ivi/blob/master/packages/ivi/src/vdom/reconciler.ts#L578. А сам алгоритм LIS неплохо объясняется в этом видео
https://www.youtube.com/watch?v=1RpMc3fv0y4

Интересно а как вы с веб-компонентами работаете с динамическими списками? Допустим есть список тодошек где можно удалить элемент или вставить новый в любое место в списке. Как вы будете синхронизировать изменения списка тодошек в состоянии с шаблоном? Реакт, ангуляр и вью выполняют так называемый diff списка сравнивая элементы по ключу и перемещая нужные элементы чтобы избежать проблем соответствия компонентов и их дом-элементов. А некоторые фреймворки вроде ivijs или infernojs для сравнения списков вообще реализуют LIS алгоритм который вычисляет минимальное количество перестановок чтобы в итоге уменьшить число dom-операций insertBefore

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


function fib(n) {
  return n <= 1 ? n : fib(n - 1) + fib(n - 2);
}

человек заоптимизирует через цикл так


function fib (n){
 if(n <= 1) return n;
 let fib = [0, 1];
 for (let i = 2; i <= n; i++) {
   fib[i] = fib[i - 2] + fib[i - 1];
 }
 return fib[fib.length - 1];
}

но с рекурсией можно записать так


function fib (n){
 if(n <= 1) return n;
 let fib = [0, 1];
 let i = 1;
 let recur = () => {
  i++;
  fib[i] = fib[i - 2] + fib[i - 1];
  if(i < n) recur();
 };
 recur();
 return fib[fib.length - 1];
}

И любой компилятор который умеет в хвостовую рекурсию будет выполнять этот код так же быстро как и с циклом.
Что касается удобства — да, получается на пару строчек больше но сейчас и так мало где можно встретить ручные циклы (обычно всякие .map(), .filter и т.д) так что экономия пары строчек для кода который будет занимать меньше 1 процента от всего проекта не имеет смысла. Зато мы избавились от кучи лишних синтаксический конструкций в языке (for, while, break, continue и labels) и упростили не только язык но и работу статическому анализатору (так как ему теперь нужно будет заняться анализом только рекурсии а не учитывать еще кучу кейсов и контрукций обычных циклов)

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

Если у рекурсии не будет условий выхода то она будет выполняться бесконечно. И статический анализатор мог бы проверить что условий выхода нет и подсветить ошибку в редакторе.
Вообще у меня есть мнение что для высокоуровневого языка программирования надо запрещать как раз таки циклы и оставить рекурсию как единственное средство для итераций. Суть такого решения в том что не нужно для языка программирования иметь несколько способов сделать одно то же — раз мы одну и ту же задачу можем решить и с помощью рекурсии и с помощью циклов то очевидно что одно их этих средств является избыточным. И появляется вопрос что убрать — циклы или рекурсию. Очевидно что рекурсия это более высокий уровень абстракции (рекурсия сводится к циклам через стек) — а значит более мощный и удобный инструмент. А что касается производительности то это уже задача компилятора (или статического анализатора с транспиляцией) преобразовать tail-call рекурсию в цикл без стека или провести кучу других оптимизаций. Что же касается циклов то мало того что в том же js для них есть разные избыточные синтаксические конструкции (while, do-while, for) да еще и с кучей нюансов и вопросов на который не каждый js-миддл ответит правильно (https://www.youtube.com/watch?v=Nzokr6Boeaw)

Information

Rating
Does not participate
Registered
Activity