Pull to refresh
18
0

User

Send message

Такое чувство что весь этот фронтенд катится в ад со всей этой раздутой сложностью. Интересно есть ли в it-индустрии области где для тех же 100к требуется меньше знаний? Может быть чисто бэкенд-разработка? Или database (dba) разработка, или может разработка встраиваемых систем и микроконтроллеров?

Вот смотришь на весь этот прогресс и удивляешься что например купив за пару сотен долларов 7нм процессор становишься обладателем невероятно длинной цепочки открытий, огромных вложений и труда. Интересно есть ли попытки собрать эту цепочку воедино как например в известном рассказе Жюля Верна "Таинственный остров" (про то как несколько человек попали на необитаемый остров и не имея ничего с собой пошагово проходят технологический прогресс от выплавки посуды из глины до телеграфа) только более формально — собрать все "зависимости" 7нм процессора до уровня первобытного человека и пошагово их описать (отсортировать в топологическом порядке) ?

Интересно а существует ли язык который с одной стороны будет максимально строгим (то есть гарантировать отсутствие рантайм-ошибок) а с другой стороны в нем не будет никакого синтаксиса объявления типов так как он будет выводить и проверять все типы из кода?


Почему без объявления типов?

Возможность указать тип имеет тенденцию усложняться — просто указать тип недостаточно надо еще добавить возможность generic-типов а потом потребуется добавить контр- и ковариантность и различные ограничений по иерархии типов а потом возможность объединения-пересечения типов, но потом этого тоже будет недостаточно и появится желание добавить conditional-типы как в последнем тайпскрипте, а потом всякие параметризированные или зависимые типы как в julia или idris — и в итоге внутри языка мы создаем еще один язык со своим синтаксисом но уже на типах

Вдогонку к статье советую посмотреть очень крутой доклад про то как работают нереляционные базы данных — https://www.youtube.com/watch?v=yrTF3qH8ey8 (ну и также крутой доклад про атомарность и транзакции https://www.youtube.com/watch?v=5ZjhNTM8XU8)

Интересно что в рейтинге производительных фреймворков нет настоящего победителя — dpdk который выдерживает миллион запросов в секунду на одном ядре (https://habr.com/ru/post/416651)

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

Интересно как с этой концепцией иммутабельной бд вы собираетесь поддерживать консистентность для различной бизнес-логики? Допустим юзер хочет перевести деньги другому юзеру. При параллельной обработке таких запросов может возникнуть ситуация гонки (race-condition) когда параллельный запрос увидит только только часть изменений другого запроса и таким образом перезапишет значения тем самым нарушив консистентность (не сойдутся остатки по счетам)
Ок, с предлагаемым вами иммутабельным подходом можно не изменять данные в разных местах а просто запушить в лог некую запись об операции перевода а потом при чтении выполнить reduce и получить остатки по счету.
Но стоит только добавить условие что юзер может выполнить перевод только при положительном остатке так вся эта идея с иммутабельностью проваливается потому что уже не получится запушить в лог факт операции так как клиенту нужно вернуть либо успех либо ошибку а значит проверку положительного остатка при переводе (редюс по всему списку переводов) нужно выполнить в самом запросе
И таким образом получаем на порядок худший вариант чем изначально "мутабельная" версия так как редюс списка истории переводов (чтобы проверить остаток) будет занимать больше времени что увеличивает время конфликта с другими параллельными запросами (не говоря уже про саму неэффективность редюса при каждом запросе)
И в конечном счете получается что мутабельность (точечные изменения в разных местах) и поддержка нужных индексов вместо пуша в лог и свертки (или всяких там подходов разделения чтения и записи а-ля cqrs) это самый эффективный способ реализации serializable-транзакций в базах данных (если конечно вам нужна консистентность чтобы сошлись остатки по счетам). Кстати советую посмотреть хороший доклад про уровни изоляции транзакций https://www.youtube.com/watch?v=5ZjhNTM8XU8
Ну а хранение данных полнотью в оперативке (с консистентным сохранением на диск в режиме append-log) позволит выполнять несколько сот тысяч таких serializable-транзакций в секунду.
Правда sql-базы под это не заточены но яркий пример базы данных которая умеет в больше 100к serializable-транзакций в секунду это Tarantool (https://habr.com/ru/company/oleg-bunin/blog/340062/, https://habr.com/ru/company/oleg-bunin/blog/310690/).
Если вкратце то отличия подобных тарантулу in-memory баз от sql-баз (когда просто увеличиваем кеш) заключаются в следующем:
а) не нужно поддерживать индексы на диске — так как используется только последовательная запись в конец файла то получаем скорость больше 100мб в секунду даже на крутящихся дисках а это позволяет записать больше сотни тысяч транзакций в секунду в бинарном формате
б) изначально заточена под хранение в оперативке архитектура которая намного эффективнее кеша sql-баз — подробности тут — https://habr.com/ru/company/oleg-bunin/blog/310560/)
в) при переходе с клиентских транзакций на серверные уменьшается время конфликта параллельных запросов и вообще необходимость в mvcc так как можно тупо выполнять транзакции в одном потоке что гарантирует serializable. Серверные транзакции отличаются от клиентских тем что вместо того чтобы стартовать транзакцию на клиенте и посылать отдельные запросы а потом посылать коммит (как это традиционно делают c sql-базами) — в базу одним запросом сразу передается вся логика обработки данных включая if-ы и разные циклы и вся эта логика уже выполняется на самой бд максимально близко к данным

А есть еще подход CSS-in-HTML (когда пишем стили рядом с тегами: <div style="margin: 10px, padding: 10px; color: red; ....">...</div>) который решает и проблему модульности стилей и проблему синхронизации с компонентами-версткой (удаление куска верстки заодно удалит и стили и т.д) и проблему именования классов

А почему вы завязываетесь на древний способ 2д отрисовки — возней с пикселями, копиями, битмапами, кешированием и софтварной растеризацией? Сейчас практически на каждом устройстве есть поддержка как минимум OpenGL ES а это значит что графическую подсистему можно построить так что заниматься растеризацией и прочей возней с пикселями будет видеокарта а со стороны программы или os достаточно просто на каждый фрейм отрисовки передать на gpu массив объектов данных примитивов (если это прямоугольик то координаты вершин или точка + ширина-высота, если кривая безье то координаты контрольных точек и т.д) — и уже на видеокарте в шейдерах будет происходить отрисовка. Причем примитивы можно бесконечно усложнять поскольку шейдеры можно программировать.
Что касается взаимодействия отдельных программ-окон то тут есть 2 варианта
1) Каждое окно будет лично взаимодействовать с видеокартой — вызывать функцию отрисовки (draw-call) но результат будет сохраняться во временный буфер-текстурку а потом os еще раз вызовет отрисовку композируя из нескольких текстурок итоговую картинку. Причем надо заметить что результат отрисовки каждого окна можно хранить на видеокарте а не заниматься копированием между cpu и gpu
2) Можно попробовать построить взаимодействие так чтобы вызов отрисовки (draw-call) на видеокарте был только один — для этого собираем результат от каждого окна и дополнительно препроцессим смещая координаты — либо на уровне массива примитивов (через постпроцессинг либо через некий общий апи рисования) смещая координаты каждого примитива с соотвествии со смещением каждого окна либо на уровне компиляции кода шейдеров добавить дополнительный код который будет относительно каждого окна добавлять смещение для gl_Position

Хм, а если бы они вместо 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-запросы и заменить их айдишниками в клиентском коде и загрузить эти запросы на сервер. И тогда клиент просто не сможет построить н-этажный запрос потому что сервер будет принимать только те запросы которые были вытащены из клиентского кода при сборке фронта.

Information

Rating
Does not participate
Registered
Activity