Да. Иначе не продастся. Целевая аудитория верит в Бога.
Обычно в подобных книгах встречается сильно попсово изложенный научный материал, и либо:
— отрицается существование Бога
— доказывается существование Бога
— намерено оставляют вопрос открытым
Big Data — это такой фрейдизм. Сегодня каждый разведенный презентациями подкованный клиент требует себе решение BigData. Типа у него этот Data очень Big, и чтобы все стояло, требуются различные модные велосипеды типа Hadoop и NoSQL. Но как показывает практика, в итоге в 90% случаев все решается в рамках обычной RDBMS, а остальные 10% — простым скриптом, который парсит логи.
Чтобы доходчиво объяснить что такое BigData с практической точки зрения, нужно задать вопрос: для начала у вас есть 20+ свободных машин в датацентре? Если ответ отрицательный, дальнейший разговор не имеет смысла.
Это все от лукавого. JavaEE контейнер изначально не был задуман ни как тестиуемый ни как удобоваримый для разработки. От цикла write-package-deploy-test спасет лишь JRebel, и то в редких случаях. Arquillian по сути автоматизирует этот цикл, но делает это также медленно: ресурсы запаковываются, а потом распаковываются на сервере. К тому же если Вы хотите добавить в деплоймент jar из maven dependency, включается резольвинг, который тормозит безбожно.
Что мы реально хотим:
— возможность пускать контейнер в embedded режиме (здравствуй, дебаг!)
— конфигурировать ресурсы контейнера (jndi, datasources, jms, etc...) программно прямо при старте, а не хранить черт знает где 10 различных конфигураций в xml и пускать свой сервер для каждого случая
— автоматический деплой приложения при запуске контейнера из текущего classpath без необходимости упаковки в jar
— конфигурировать программно classpath (для мокирования) и ресурсы приложения (дескрипторы xml)
— возможность тестирования и инъектирования теста в окружение контейнера
Все это умеет с некоторыми косяками Apache OpenEJB. Первый проект делал на JBoss + Arquillian, вторые два разрабатывал на OpenEJB (в продакшне все проекты деплоились на Weblogic) — производительность разработки возросла в несколько раз. Из недостатков: есть кое-какие баги, много приходится допиливать самому, версия 5.0 с JEE7 до сих пор еще в SNAPSHOT-ах.
Когда я был маленьким, на физике нам объясняли, что существует как минимум три типа энергии: потенциальная, кинетическая и внутренняя. Их можно преобразовывать друг в друга. Механическая работа совершается только тогда, когда есть разность потенциалов для одного типа энергии.
В данном случае, электростанция преобразует кинетическую энергию воды (течения, приливы, волны) в электрическую. При этом вода не охлаждается, но замедляется. Электрическая энергия в свою очередь тратится на изменение единичек и нулей в разныху устройствах и в итоге преобразуется в тепловую (внутреннюю), которая нагревает воду.
То есть при помощи датацентра быстрая холодная вода превращается в медленную и теплую.
Или тролли. Навеяло норвежским фильмом «Troll Hunter» :)
Вообще в таких помещениях самое опасное — это пожар. Пространство изолировано, снаружи не подобраться, тушить практически невозможно. В лучшем случае наглухо изолируется секция и заполняется инертным газом.
Scala — это все-таки отдельная область, с собственной системой типов, стандартной библиотекой, экосистемой, и парадигмами, которые имеют лишь определенную совместимость с Java. Смешивать в решении одновременно Java и Scala, довольно нецелесообразно, хотя и можно.
Groovy же натурально интегрируется с Java, не выходя из ее парадигмы. В данном случае я имел ввиду такой мощный инструмент Groovy как AST. В стандартной библиотеке уже есть гибкие трансформации для создания properties и билдеров. При указании @CompileStatic Groovy AST генерирует код, который 100% интероперабелен с Java и не требует присутствия groovy в рантайме.
В тему: есть прекрасный проект Joda-Beans, который решает многие задачи и исправляет косяки спецификации Java Beans: генерирует автоматически boilerplate code для properties (в том числе и билдеры), добавляет метаданные, equals/hashcode, immutability, etc… Другая хорошая альтернатива — Groovy, которая при необходимости также может генерировать билдеры для объектов.
Спасибо. Всегда интересовали возможности моделирования с помощью Eclipse Modelling Tools. К сожалению, существует очень мало информации на этот счет.
Насколько я могу судить, последнее поколение тулзов отошло от OMG в сторону генерации собственных описательных языков (Epsilon).
Если Вы специалист в EMFT, будет очень интересно увидеть статьи, освещающие использование полного стека технологий на примере от создания модели и до работающего приложения, включающего persistence и xml-mapping.
Все решают деньги. Силенд особо никому не впился, чтобы хотя бы поднять вопрос о признании или нет его государством. А вот когда за платформами стоят реальные мультинациональные корпорации которые производят и потребляют сервисы и участвуют в финансовом обороте, и которые могут себе позволить лоббировать свои интересы в конкретно взятой стране и нанять солидную вооруженную охрану… Тогда так или иначе придется с ними считаться.
Совершенно верно. Плавучие платформы будут фактически свободны от юрисдикции любой конкретно взятой страны, и при желании смогут объявить себя собственным государством. И дело не столько в картинках котиков, сколько в экономической оправданности в виде свободы от налогов прямых и косвенных.
В данном примере основная потеря производительности будет при передаче данных от одного процесса к другому: работа с памятью внутри одной JVM в сотни раз быстрее, чем сериализация/десериализация и дерганье сетевого стека, даже если учесть накладки с GC. Если сервис построен правильно, при необходимости его можно горизонтально масштабировать. Запускается много однотипных JVM-процессов, каждый из которых реализует сразу весь требуемый функционал, но в ограниченном объеме ресурсов (память, процессор, etc). А вся нагрузка равномерно распределена среди всех запущенных процессов.
От статьи за километр разит пиаром.
Во-первых, непонятна сама цель портирования, если все работало без проблем.
Во-вторых, непонятен экономический выигрыш: стоимость портирования несравненно больше лишнего гигабайта памяти.
В-третьих, в разы увеличилась стоимость разработки и поддержки проекта, и как следствие, риски.
В-четвертых, почему сначала не попытались решить проблему в рамках экосистемы Java? «Маленький tomcat servlet с единственным HTTP-вызовом» говорит о заведомо неверно выбранной архитектуре. Пускать кучу Tomcat контейнеров по одному на каждый модуль и удивляться потом почему так много памяти отъедено. Есть куча легковесных решений на Java, умеющих работать с HTTP, и еще много чего.
В-пятых, зачем столько процессов? Специфика JVM такая, что процесс отъедает значительную память, поэтому лучше собирать решение по возможности внутри одной JVM, нежели пускать кучу процессов. Конечно, если не было целью продемонстрировать «Java vs Go».
В-шестых, вконце вскользь упомянулось быстродействие: улучшение лишь «в некоторых случаях». Видимо, хвастаться особо было не чем.
Это красиво, но потенциально небезопасно. Очень легко «захватить» с собой весь внешний объект со всем поддеревом, только лишь упомянув одно его поле в лямбде.
Но! Если программа сложная, планируется ее доработка и поддержка, то применение всех этих «лишних сложностей» будет напрямую влиять на самое
Миф, цитируемый разводилами-теоретиками недалеким менеджерам. До сих пор не доказана эффективность разработки с ООП перед процедурным подходом. Кроме того, имеется множество авторитетных мнений за то, что ООП является скорей антипаттерном и в реальной жизни лишь усложняет проектирование и разработку, заставляя концентрироваться на абстрактных вещах, не имеющих отношения к решаемой задаче.
Расцвет ООП начался в эпоху оконных интерфейсов, где иерархическая модель однотипных визуальных компонентов с наследованием и инкапсуляцией поведения (отрисовка, реакция на ввод) хорошо вписывалась в предлагаемую парадигму. В реальных задачах концепты ООП становятся рудиментарными.
— Миллионы приложений используют реляционную модель и живут счастливо без всякого наследования в своей предметной области. Приложение в 99% случаев работает с конкретной сущностью, нежели абстрактным надклассом.
— Инкапсуляция становится бесполезной, когда изменения состояния затрагивает сразу много объектов, и когда зависимости одни от других нетривиальны и не вписываются в иерархическую схему. Пример: бильярдный стол с шарами и физикой. Каждый шар хранит и изменяет состояние. Инкапсулировать физику отскоков в шары невозможно, поскольку шар ничего не знает о других.
— Переопределяя очередной метод в большой иерархии, программист не может быть уверен, что не нарушит деятельность объекта на каком-то уровне.
Когда я смотрю на заумные паттерны типа DAO и Repository мне представляется какой-то сферический конь в вакууме. При работе с базой данных основную роль играет не теоретическое обоснование выбранного паттерна и стройность архитектуры, а тупо быстродействие и оптимальность выполнения. Видел кучу проектов на Spring Repository. На тестах все хорошо, но когда проект обрастает данными, приходится делать оптимизации, которые рушат всю структуру этих паттернов. Вылазят проблемы типа N+1 запросов, проблемы выборки нескольких связанных сущностей, «проекции» сущностей, etc… Поэтому все паттерны очень условны и ограничены.
Здесь же автор совершенно не убедил преимуществами Repository перед DAO.
Сложнее создавать моки для интерфейса DAO во время юнит-тестирования. Необходимо было бы реализовывать больше методов DAO даже в тех тестовых сценариях, когда они не используются;
Пусть реализует только те, которые используются в данном сценарии, в чем проблема? IDE не сгенерит заглушки? Или же пусть создает один универсальный осмысленный mock для DAO, реализующий все методы, который будет использоваться во всех тестах. Если DAO описывает интерфейс между логикой программы и хранилищем, то mock должен симулировать это хранилище.
Интрфейс DAO становится все более привязанным к полям класса Account. Возникает необходимость в изменении интрфейса и его реализаций при изменении типов полей класса Account.
А к чему еще он должен быть привязан? Это же DAO этой сущности! Нафига тогда он нужен, если он ничего ни знает о самой сущности? И как Repository нас избавляет от необходимого рефакторинга при изменении типа поля? В том, что типы заткнуты в Specification?
List query(AccountSpecification specification);
И как мокировать данный метод? Вы можете по этому методу сказать, какие запросы тут нужно мокировать? Если бы стоял простой findByUserName(), все было бы просто и понятно. Здесь же приходится писать дополнительную логику, узнающую specification, переданную в параметре.
Более того, specification у нас зависима от платформы, а не какой-то там абстрактный критерий!!! Т.е. простой unit-test с repository мокнутым в коллекцию и простым поиском по имени без привлечения hibernate criteria уже не сделать, если в итоге мы хотим использовать hibernate.
P.S. Риторический вопрос: какой человек в здравом уме и с лимитированным бюджетом будет писать для каждого запроса кучу рудиментарного по сути кода типа specification и прочей лабуды? Ну и апофеоз маразма — это юзать Repository с ORM, когда EntityManager решает абсолютно ВСЕ задачи, поставленные перед этим паттерном.
Извиняюсь за резкость, но по-моему подобные теоретические изыскания топят Java, заставляя адептов делать сложно простые вещи.
Хмм. Я был уверен, что корень зла лежит именно в mdadm. Лет пять назад похожая проблема была с нашими серверами, на которых стояли обычные HDD включеные в софтверный рейд на Ubuntu. Концы файлов также отсутствовали, последние изменения периодически не записывались. Проблема решилась покупкой и установкой hardware RAID контроллеров.
Ребята проделали огромную и стоящую работу по нахождению проблемы. Однако причина кроется по большей мере в кустарной архитектуре: сервера скорей всего были собраны самостоятельно из разных компонентов. При покупке готовых серверов проблемы, возможно, можно было бы избежать, т.к. компании-производители подвергают свои продукты нагрузочному тестированию на отказоустойчивость. Ну и SW RAID — это несерьезно, в основном для домашнего использования.
Хорошо. А где собственно здесь JavaEE? Это обычное Spring-приложение, которое даже не деплоится на JEE контейнер. На сегодняшний день JEE уже умеет многое из того, что предлагает Spring, поэтому использование обеих технологий в одном приложении — вопрос целесообразности.
Формально поведение кода всегда детерминировано, если вы про это. Однако для ФП связывание (композиция) может происходит в рантайме и может зависеть от сторонних факторов. В качестве примеров возьмите джавовский CompletableFuture или reactive programming. Сначала программа вычисляет результат композиции — некую комбинированную функцию, а затем данная функция применяется к набору данных и вычисляется конечный результат. Комбинированная функция состоит из множества блоков, но может быть скомпонована каждый раз по-разному — компоновка полностью контролируется рантаймом, отсюда и динамическая композиция. Для императивного подхода данный метод недоступен, поскольку вся композиция происходит на этапе компиляции. Не знаю, объяснил ли я мысль.
А теперь задумаемся о смысле (жизни) к чему все это. Ключевое слово — динамическая композиция кода.
Т.н. «классический императивный стиль» соответствует статической композиции. Ветвистый код намертво прибит гвоздями к экрану изнутри, а его поведение определяется исключительно данными. Достоинства: простота и предопределенность. Недостаток — многописанина и сложности с более высоким уровнем абстракции: все должно быть записано явно.
В динамической композиции кода, из которой более чем полностью состоит это ваше функциональное программирование, последовательность действий выстраивается в процессе выполнения. Это позволяет абстрагироваться от конкретики и сконцентрироваться на результате действий (т.н. «декларативный стиль»), тогда как вся конкретика реализуется уже готовыми паттернами. Недостатки: сложность пошаговой отладки и чтения кода «с нуля».
Так что все эти модные акторы, монады, ФРП — способы динамической композиции кода.
> Unix-way
Сложность решения задачи будет представлять уже интеграция атомарных программулечек в единое решение. Выполнение будет далеко не оптимальным.
> Велосипед существует
Существует не велосипед, а средства передвижения. От лыж до железной дороги. Типичные проблемы сторонних решений: либо оно сырое и требует значительного допила руками, либо оно негибкое и его сложно приспособить для своей задачи, либо оно чересчур абстрактное, громоздкое и сложное в использовании, что проще все написать самому. Плюс все это противоречит первому пункту.
> Сначала тесты
Сначала моделирование и прототипирование! Чтобы хотя бы было из чего писать эти тесты.
> Не нужно отрабатывать время
К сожалению, платят именно за время, а не за продуктивность.
Обычно в подобных книгах встречается сильно попсово изложенный научный материал, и либо:
— отрицается существование Бога
— доказывается существование Бога
— намерено оставляют вопрос открытым
разведенный презентациямиподкованный клиент требует себе решение BigData. Типа у него этот Data очень Big, и чтобы все стояло, требуются различные модные велосипеды типа Hadoop и NoSQL. Но как показывает практика, в итоге в 90% случаев все решается в рамках обычной RDBMS, а остальные 10% — простым скриптом, который парсит логи.Чтобы доходчиво объяснить что такое BigData с практической точки зрения, нужно задать вопрос: для начала у вас есть 20+ свободных машин в датацентре? Если ответ отрицательный, дальнейший разговор не имеет смысла.
Что мы реально хотим:
— возможность пускать контейнер в embedded режиме (здравствуй, дебаг!)
— конфигурировать ресурсы контейнера (jndi, datasources, jms, etc...) программно прямо при старте, а не хранить черт знает где 10 различных конфигураций в xml и пускать свой сервер для каждого случая
— автоматический деплой приложения при запуске контейнера из текущего classpath без необходимости упаковки в jar
— конфигурировать программно classpath (для мокирования) и ресурсы приложения (дескрипторы xml)
— возможность тестирования и инъектирования теста в окружение контейнера
Все это умеет с некоторыми косяками Apache OpenEJB. Первый проект делал на JBoss + Arquillian, вторые два разрабатывал на OpenEJB (в продакшне все проекты деплоились на Weblogic) — производительность разработки возросла в несколько раз. Из недостатков: есть кое-какие баги, много приходится допиливать самому, версия 5.0 с JEE7 до сих пор еще в SNAPSHOT-ах.
В данном случае, электростанция преобразует кинетическую энергию воды (течения, приливы, волны) в электрическую. При этом вода не охлаждается, но замедляется. Электрическая энергия в свою очередь тратится на изменение единичек и нулей в разныху устройствах и в итоге преобразуется в тепловую (внутреннюю), которая нагревает воду.
То есть при помощи датацентра быстрая холодная вода превращается в медленную и теплую.
Вообще в таких помещениях самое опасное — это пожар. Пространство изолировано, снаружи не подобраться, тушить практически невозможно. В лучшем случае наглухо изолируется секция и заполняется инертным газом.
Groovy же натурально интегрируется с Java, не выходя из ее парадигмы. В данном случае я имел ввиду такой мощный инструмент Groovy как AST. В стандартной библиотеке уже есть гибкие трансформации для создания properties и билдеров. При указании @CompileStatic Groovy AST генерирует код, который 100% интероперабелен с Java и не требует присутствия groovy в рантайме.
Насколько я могу судить, последнее поколение тулзов отошло от OMG в сторону генерации собственных описательных языков (Epsilon).
Если Вы специалист в EMFT, будет очень интересно увидеть статьи, освещающие использование полного стека технологий на примере от создания модели и до работающего приложения, включающего persistence и xml-mapping.
Во-первых, непонятна сама цель портирования, если все работало без проблем.
Во-вторых, непонятен экономический выигрыш: стоимость портирования несравненно больше лишнего гигабайта памяти.
В-третьих, в разы увеличилась стоимость разработки и поддержки проекта, и как следствие, риски.
В-четвертых, почему сначала не попытались решить проблему в рамках экосистемы Java? «Маленький tomcat servlet с единственным HTTP-вызовом» говорит о заведомо неверно выбранной архитектуре. Пускать кучу Tomcat контейнеров по одному на каждый модуль и удивляться потом почему так много памяти отъедено. Есть куча легковесных решений на Java, умеющих работать с HTTP, и еще много чего.
В-пятых, зачем столько процессов? Специфика JVM такая, что процесс отъедает значительную память, поэтому лучше собирать решение по возможности внутри одной JVM, нежели пускать кучу процессов. Конечно, если не было целью продемонстрировать «Java vs Go».
В-шестых, вконце вскользь упомянулось быстродействие: улучшение лишь «в некоторых случаях». Видимо, хвастаться особо было не чем.
Миф, цитируемый разводилами-теоретиками недалеким менеджерам. До сих пор не доказана эффективность разработки с ООП перед процедурным подходом. Кроме того, имеется множество авторитетных мнений за то, что ООП является скорей антипаттерном и в реальной жизни лишь усложняет проектирование и разработку, заставляя концентрироваться на абстрактных вещах, не имеющих отношения к решаемой задаче.
Расцвет ООП начался в эпоху оконных интерфейсов, где иерархическая модель однотипных визуальных компонентов с наследованием и инкапсуляцией поведения (отрисовка, реакция на ввод) хорошо вписывалась в предлагаемую парадигму. В реальных задачах концепты ООП становятся рудиментарными.
— Миллионы приложений используют реляционную модель и живут счастливо без всякого наследования в своей предметной области. Приложение в 99% случаев работает с конкретной сущностью, нежели абстрактным надклассом.
— Инкапсуляция становится бесполезной, когда изменения состояния затрагивает сразу много объектов, и когда зависимости одни от других нетривиальны и не вписываются в иерархическую схему. Пример: бильярдный стол с шарами и физикой. Каждый шар хранит и изменяет состояние. Инкапсулировать физику отскоков в шары невозможно, поскольку шар ничего не знает о других.
— Переопределяя очередной метод в большой иерархии, программист не может быть уверен, что не нарушит деятельность объекта на каком-то уровне.
Здесь же автор совершенно не убедил преимуществами Repository перед DAO.
Пусть реализует только те, которые используются в данном сценарии, в чем проблема? IDE не сгенерит заглушки? Или же пусть создает один универсальный осмысленный mock для DAO, реализующий все методы, который будет использоваться во всех тестах. Если DAO описывает интерфейс между логикой программы и хранилищем, то mock должен симулировать это хранилище.
А к чему еще он должен быть привязан? Это же DAO этой сущности! Нафига тогда он нужен, если он ничего ни знает о самой сущности? И как Repository нас избавляет от необходимого рефакторинга при изменении типа поля? В том, что типы заткнуты в Specification?
И как мокировать данный метод? Вы можете по этому методу сказать, какие запросы тут нужно мокировать? Если бы стоял простой findByUserName(), все было бы просто и понятно. Здесь же приходится писать дополнительную логику, узнающую specification, переданную в параметре.
Более того, specification у нас зависима от платформы, а не какой-то там абстрактный критерий!!! Т.е. простой unit-test с repository мокнутым в коллекцию и простым поиском по имени без привлечения hibernate criteria уже не сделать, если в итоге мы хотим использовать hibernate.
P.S. Риторический вопрос: какой человек в здравом уме и с лимитированным бюджетом будет писать для каждого запроса кучу рудиментарного по сути кода типа specification и прочей лабуды? Ну и апофеоз маразма — это юзать Repository с ORM, когда EntityManager решает абсолютно ВСЕ задачи, поставленные перед этим паттерном.
Извиняюсь за резкость, но по-моему подобные теоретические изыскания топят Java, заставляя адептов делать сложно простые вещи.
Ребята проделали огромную и стоящую работу по нахождению проблемы. Однако причина кроется по большей мере в кустарной архитектуре: сервера скорей всего были собраны самостоятельно из разных компонентов. При покупке готовых серверов проблемы, возможно, можно было бы избежать, т.к. компании-производители подвергают свои продукты нагрузочному тестированию на отказоустойчивость. Ну и SW RAID — это несерьезно, в основном для домашнего использования.
Т.н. «классический императивный стиль» соответствует статической композиции. Ветвистый код намертво прибит гвоздями к экрану изнутри, а его поведение определяется исключительно данными. Достоинства: простота и предопределенность. Недостаток — многописанина и сложности с более высоким уровнем абстракции: все должно быть записано явно.
В динамической композиции кода, из которой более чем полностью состоит это ваше функциональное программирование, последовательность действий выстраивается в процессе выполнения. Это позволяет абстрагироваться от конкретики и сконцентрироваться на результате действий (т.н. «декларативный стиль»), тогда как вся конкретика реализуется уже готовыми паттернами. Недостатки: сложность пошаговой отладки и чтения кода «с нуля».
Так что все эти модные акторы, монады, ФРП — способы динамической композиции кода.
Сложность решения задачи будет представлять уже интеграция атомарных программулечек в единое решение. Выполнение будет далеко не оптимальным.
> Велосипед существует
Существует не велосипед, а средства передвижения. От лыж до железной дороги. Типичные проблемы сторонних решений: либо оно сырое и требует значительного допила руками, либо оно негибкое и его сложно приспособить для своей задачи, либо оно чересчур абстрактное, громоздкое и сложное в использовании, что проще все написать самому. Плюс все это противоречит первому пункту.
> Сначала тесты
Сначала моделирование и прототипирование! Чтобы хотя бы было из чего писать эти тесты.
> Не нужно отрабатывать время
К сожалению, платят именно за время, а не за продуктивность.