All streams
Search
Write a publication
Pull to refresh
31
0
Антон Куранов @Throwable

Пользователь

Send message

ЗАЧЕМ? Отдаем другу конверт не говоря какого цвета в нем карта

Плохо объяснено как всегда. Основное отличие в том, что в квантовой системе можно произвести частичное изменение, например получить результат, что карта на 40% синяя и на 60% красная. Другая соответственно будет на 60% синяя и на 40% красная. К тому же частичное изменение можно проводить с помощью третьей квантовой системы, запутанной с первыми двумя. К этому сложно подобрать классические аналоги.

Недостаток модели Эверетта в том, что количество вселенных счетно, а волновая функция непрерывна.

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

Немного оффтопика: по запросу графовых бд сразу выходит Neo4j, у которой просто отвратительная таргетированная рекламная кампания. После этого из каждого утюга ещё долго будут абьюзить рекламой оной. Так что открывайте в инкогнито.

А вообще главное отличие реляционных и графовых бд в том, что в первой отношения задаются статически, а во второй - динамически. Все.

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

Может, и уже достаточно давно.

Возьмём наипростейший пример с пользователем и его банковским счётом

Это понятно. Но это не единственный кейс, хоть и распространенный. Если у вас инвентарная система с сотнями сущностей, и нужно организовать универсальный доступ к этим данным, при этом основной потребитель даже не фронт, а другие сервисы... задолбаетесь строчить тонны ненужных DTO и маппингов. Проще выставить всю модель наружу, при этом контролируя доступ к определенным полям. В качестве референтов можно указать Hateos и JPARS.

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

Это понятно. Просто изначально вопрос был, если модели данных практически полностью совпадает с API, то зачем делать ещё один слой, вместо того, чтобы отдать сразу Entities? Пример из прошлого: инвентарная система с огромным количеством разных Entities и API для доступа ко всем ним.

Там до Api как такового никому особо дела не было. Проект прошел по куче рук, и каждый реализовал тикет как мог. Для каждой новой фичи на бэке тупо писался свой контроллер, сервис, DTO и маппер. В итоге все т.н. "api" -- это куча findByXxx, которые отдают схожие DTO с немного разным набором филдов под каждый конкретный кейс.

Для сильно служебных полей есть @JsonIgnore и ещё куча способов исключить их из сериализации. Хорошая модель данных организована так, чтобы отделить процессинг от стейта: не загромождать сами Entities промежуточными состояниями и служебными данными, а выделить их в отдельный объект.

Согласно моему горькому опыту в любом проекте очень быстро замусоривается DTO, всевозможными мепперами и промежуточными сервисами. Доходит до того, что на одну entity получается с десяток схожих DTO. В то же время успешный рефакторинг на раздачу Entities уменьшил кодовую базу сразу на 90%.

Меня всегда удивляет боязнь девелоперов вместо DTO отдавать сразу Entities. Начинают что-то говорить, что это неправильно, и что-то про разные модели и секьюрити. Но на практике это те же самые POJO, и в 99% случаев из fieldset-ы совпадают. А при грамотно выставленных EntityGraphs можно четко контролировать отдаваемый контент. Поэтому чаще всего следуя каким-то искусственным паттернам, сами себе усложняем жизнь.

Не совсем понял как вы за 12 лет при месячном пробеге 500км смогли накатать 700к миль... И в описанном режиме реальная доступная ёмкость батареи составляет 40% минус деградация. Или я что-то не понял?

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

То есть время от растопки до закипания котла не берется в рассчет? К тому же:

  • Теплопотери у паровых двигателей на порядки больше. Огромный расход топлива на начальный нагрев рабочего тела, особенно в старт-стоп режиме.

  • Возможно по CO и углю паровой двигатель чище, но NOx выхлопов будет гораздо больше ввиду бОльшей температуры горения.

Электромобиль выигрывает в среднесрочной стратегии использования за счет меньших затрат на обслуживание и «заправку».

Извечный вопрос при покупке гибрида/электромобиля: через сколько лет мне придется менять батарею стоимостью полавтомобиля?

А что же у электромобилей? Тут как раз обратная картина — эти автомобили только подбираются к средней границе ежедневного пробега.

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

Идея интересная, однако не стоит так делать повсеместно. Здесь вы инкапсулируете в класс животного свойства, которые относятся больше к компетенции ZooWorker-а, и не имеют большого смысла в отрыве от него. Например вот у нас в зоопарке открылся ветеринарный отдел, и теперь снова будем нагружать бедных животных новыми свойствами и всей логикой, относящейся к ветеринарной службе? В итоге когда предметная область вырастет, ваши животные превратятся в пухлых монстров.

Есть еще файлик lombok.config, который позволяет выставить параметры по-умолчанию для аннотаций всех подпакетов. У меня, например, выставлено:

lombok.anyConstructor.addConstructorProperties = true
lombok.fieldDefaults.defaultPrivate = true

Первый параметр обеспечивает безгеморную десериализацию с Jackson-ом для immutable объектов, второй -- корректирует идиотское соглашение Java насчет package-private области видимости по умолчанию.

Собственно остается непонятным, сколько реальных тредов работает в Executor-е для виртуальных тредов, и где это подкручивается. Также покрыта мраком работа планировщика: имеет ли он ввиду Thread.priority, когда несколько виртуальных потоков одновременно "просыпаются", и где можно ловить и мониторить очередь потоков ожидающих выполнения, когда все реальные треды заняты...

Все еще аргумент про Graceful degradation в случае, если падает монолит целиком

Не совсем понял, что такое "падает монолит целиком". Для Graceful degradation существуют всеразличные пулы ресурсов, и очереди с лимитированной глубиной. Если свободного ресурса нет, то вместо ожидания сразу отфутболить реквест, тем самым предотвращая каскадное истечение ресурсов.

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

Как я уже сказал выше, внутри монолита можно также использовать разные пулы ресурсов как душе будет угодно.

возможность писать разные сервисы разными командами, на разных стеках

Принимается, хотя со стратегической точки зрения это скорей не плюс, а минус.

возможность делать большие обновления зависимостей поэтапно, без конфликтов

Большие обновления зависимостей в микросервисной архитектуре -- это боль. Особенно когда малейшее изменение затрагивает сразу много микросервисов (а таких бывает большинство).

возможность делать большие обновления зависимостей поэтапно, без конфликтов

Это да. Принимается.

Вобщем, все "плюсы" и "минусы" разложены хрестоматийно и как обычно без всякой критики. В монолите имплементируется любой паттерн из микросервисной архитектуры, и делается это все порядки проще подручными средствами, а любые ресурсы могут быть точно также изолированы для каждого компонента. Кроме двух: CPU и memory. Вот тут и находится главный мотив по которому стоит переходить на микросервисную архитектуру. Железные инстансы теперь являются такими же ресурсами, как и любые пулы, а микросервисная архитектура позволяет осуществлять динамическое выделение инстансов под компоненты, изолируя при этом использование CPU и памяти. Цена перехода -- усложнение инфры, бизнес логики, процессов и общей стоимости.

А кто запрещает в монолите использовать хоть для каждого компонента свой пул ресурсов? Так что не убедительно. Еще аргументы.

Может я немного отстал от жизни, AOP уже тоже вышел из моды? Я думал в статье коснутся деталей Spring AOP, AspectJ, java.lang.Proxy, ByteBuddy, а статья о том как добавить кучу boilerplate-а к бизнес коду.

Плюсы микросервисного подхода

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

С чего это? Монолит также может быть горизонтально отмасштабирован с load balancer-ом и high availability.

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

В случае с монолитом точно также испортится функционал, затронутый изменением, а остальное будет работать как раньше.

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

Зато весь процесс тестировать становится на порядки сложнее.

Так где плюсы-то?

Для Java нечто подобное уже реализовано в библиотеке JINQ. Только там парсится сам байткод лямбды, и поэтому очень много подковерной магии.

Information

Rating
Does not participate
Location
Madrid, Испания
Registered
Activity