Хороший пример. Но в вашем случае явно виден источник утечки в меткиках DirectBuffer Pool (количество аллокаций и суммарный размер). И включив NMT вы увидите прогрессирующую статистику. Дальше можно снять хипдамп и увидеть ненормальное количество инстансов класса. Но у DirectBuffer есть очень нехороший паттерн поведения, когда RSS процесса растет, а все метрики по Native Memory в норме, что может привести к системному OOMKiller. Это связано с тем, что под капотом DirectBuffer pool никакого пула на самом деле нет. Есть только Atomic каунтеры количества и размера. А механизм это тривиальные malloc() - free(), ну и плюс к объекту, использующему этот "пул" прикручивается java.lang.ref.Cleaner (c 11 версии). Поэтому и зачистка только во время GC. В итоге получается, что в нативной памяти процесса создаются и удаляются "кусочки памяти" которые ведут к её фрагментации и распуханию RSS, который невозможно диагностировать стандартными метриками. Обычно утечка проявляется на хорошо нагруженных сервисах обрабатывающих http/grpc. Раньше с проблемой бороться было невозможно, кроме перезапуска приложения, но в glibc с версии 2.8 завезли malloc_trim() который умеет во всем адресном пространстве процесса релизить "залипшую память". В JVM в DiagnosticCommand сделали метод trimNativeMemory() который можно дернуть через JMX MBean (в контейнере) или через jcmd в обычной инсталляции. А в JVM 17.0.9 сделали ключ -XX:TrimNativeInterval (пока экспериментальный) который взводит таймер регулярных malloc_trim()
С точки зрения GC, проблему, описанную в статье на небольших сервисах "лечил" паллиативно путем использования ZGC (утечки были в зависимостях, не в нашем коде). У G1 да, были проблемы с утечками буферов, но вроде бы они её вылечили и они чистятся сейчас в mixed фазе, но это не точно.
Ну так себе. Законы меняются. Моя жена в "пандемию" уплатила штраф 1500 рублей. За не предоставление инфы о зарубежном счете. По движениям по счету отчетность уже была не нужна, ибо другое налоговое резидентство. Хуже про валютное резидентство. Тут проще запустить процедуру отказа от гражданства, чем иметь "долги"
Это наоборот очень полезно для контейнеров. При текущем подходе docker будет собираться минимум из OS + JVM + App FatJar Вес FatJar может быть сотни мегабайт и гонять этот артифакт в облака могут по несколько раз в день. При наличии CDS OS + JVM + CDS + App Сам по себе App от сотен до нескольких мегабайт обычно. CDS же будет меняться только при обновлении зависимостей, то есть достаточно редко. Если команда пилит несколько сервисов используя общий BOM то получается очень хорошее решение.
А можно для начала обозначить понятие "командный дух"? Такие вещи очень часто звучат в "сетевых магазинах", где люди, работающие за копейки, будут петь утром "гимн компании". А может быть "командный дух", когда ребята из разработки, при содействии HR поехали на пейнтбол. И либо бэкендеры воюют с фронтендерами, либо все с тестерами. На митах и оффлайнах так же возникают связи. Которые могут перейти в "последняя пятница месяца". В баре с пивом.
Командный дух невозможно прописать в регламентах компании. Его невозможно создать навязыванием тупых инициатив от HR (в следующую субботу едем прыгать в мешках. Явка обязательна). Его нужно отращивать, как и компетенции в профессиональной области.
Ну для кликбейта наверное статья хороша. Но (а как извсестно до "Но" инфа игнорируется) Пром не умеет в персистенс. Поэтому мы или видим короткую историю, либо юзаем mimir, который прекрасно реализует персистенс для prom. А если подумаем об обсервабилити приложения, то затащим еще и GrafanaTempo, как универсальный коллектор трейсов. Как Zipkin, Jaeger. Ну и Loki конечно. Но поверх S3. А если отходим от стека Grafana, то там будет VictoriaMetrics и куча своих "чудес"
Хабр "прекрасен". Убить карму в комментах, где только и разрешено писать - это сильно. Причем на корректном посте, задевшем ЧСВ другого комментатора. Ну что же поделать. Мои коллеги теперь знают с кем и каким юрлицом лучше не сотрудничать.
Коллега, вы еще раз подчеркиваете то, что вы далеки от темы. JDK - это Development Kit. Набор инструментов, который предназначен для разработки и отладки приложений на Java. И этот набор должен (TCK) гарантировать, что мнемоническая команда "swap" имея код "5f" свопнет два верхних слова на стеке. То есть javac на выходе даст всегда одинаковый байткод. И JDK он же одинаков. Есть фундаментальная база, обложенная JSR. Если кто-то из производителей хочет "обогатить" JDK своими новыми либами - да пожалуйста. Кто-то мешает использовать в С++ boost? Никто, кроме корпоративных правил. Но наработки boost уходят в апстрим языка. И вот тут возникает Java SE. Набор библиотек, которые работают поверх JVM. И они формируют язык и экосистему. И он стандартен. Иначе это не Java. Кто был не согласен - сделали Scala, Closure, Kotlin (огромное спасибо ребятам из JetBrains) Вы в своем же посте путаете кучу понятий. В вашем перечислении присутствует HotSpot. Но это не JDK, это имплементация рантайма. Как и JamaicaVM, дорогая имплементация JVM под real-time. Это не JDK, это рантаймы. Текущие популярные сбоки Java SE Temurin Coretto Liberica Да и прочие несут в себе стандартный набор библиотек. Не отличающийся от OpenJDK. Байт-код там будет всегда одинаков. Но может быть обогащен. Никто не мешает заменять условно запрещенный sun.misc.Unsafe на новые технологии.
Наш коллега, как мне кажется, катастрофически далёк от мира Java и занимается некоторой подменой понятий.
Если взять за точку отсчета 2010 год (Покупку Sun Microsystems компанией Oracle), то можно назвать достаточное количество имплементаций JVM. * Azul Zing от Azul Systems - старт 2002 год. Проприетарная платная JVM со своим высокопроизводительным Garbage Collector (GC) * JRockit от BEA Systems - старт 2002 год. Затем куплена Oracle. Проприетарная и сильно платная. Уникальный для того времени GC, который скорее всего лег в основу G1 OpenJDK и Oracle JVM. Убита Oracle в 2012 * IBM J9 от понятно кого. С ростом популярности Java и распространением энтерпрайзного софта на этой платформе IBM в 1999 году заключило соглашение с Sun и получило право форкнуть Java SE (кажется 1.3) чтобы сделать порты под AIX, z/OS с учетом специфики IBM POWER и мэнфреймов. * SAP JVM. Не могу назвать точную дату, но первый релиз не позже Java SE 6, то есть 2004-2006 годы. Причина та же, что и у IBM. Дорогущее энтерпрайзное ПО работающее на ОСях - Windows, Solaris, HP-UX, AIX, i5/OS (IBM i) и на процах - x86, x86-64, IA-64, SPARC, PA-RISC, PowerPC (IBM POWER). SAP договаривается с Sun и делает форки под все платформы, чтобы системные интеграторы при внедрении систем не плясали с бубном. * OpenJDK. 2007 год, случилось знаковое событие. Поняв все преимущества коллективной разработки OpenSource компания Sun Microsystems публикует исходники своей JVM под названием OpenJDK и лицензией GPL-2
Можно еще продолжить, но нет смысла. Тут и так 5 абсолютно различных имплементаций, ни в коем случае не сборок, JVM, эпохи до Oracle. И конечно Java software будет на них выполняться одинаково в соответствии с заявленной версией совместимости с TCK (наборами JSR).
Теперь можно и к сборкам перейти. Oracle не стал закрывать OpenJDK лицензиями. Более того, OpenJDK - это основная платформа OracleJDK в которую включены некоторые проприетарные элементы. Лично мне непонятен ход с лицензиями на OracleJDK, как и не понимаю, кому нужна именно сборка от Oracle, там нет киллер фич. Но прошла некоторая волна создания сборок OpenJDK другими компаниями. И в этом вообще нет никаких проблем. Та же AdoptOpenJDK (Eclipse Temurin) это сборка референсной OpenJDK и возможность получить платную поддержку. Российская LibericaJDK - сборка, но плюс ребята дописывают улучшения, не ломающие TCK и являются контрибуторами OpenJDK. Примерно такая же ситуация с Amazone Coretto. Я работаю в компании, в которой уже много лет собираю собственные сборки OpenJDK и дописываю патчи, которые не ломают TCK, но учитывают особенности нашего продакшена в рантайме.
Это ошибка. Всё, что есть в TCP, всякие congestion control, MSS это всё L4, ничего из L5 там нет. Вообще основное количество протоколов L5 это всякие туннели, предоставляющие L2 уровень через L5. L2TP, PPTP. В статье про L4 тоже ошибка. Там указан TLS. Скорее всего из-за названия - Transport Layer Security. Сам протокол работает поверх TCP (DTLS поверх UDP) и фактически обеспечивает уровень представления. Но с точки зрения разработчика приложения работа с TLS строится как с сокетами. Видимо отсюда дополнительная путаница. Но нужно отметить, что не всегда протокол можно четко отнести к одному уровню. Как пример - ARP/RARP. Если мы рассматриваем Ethernet и TCP/IP, то на L2 у нас protocol data unit (PDU) - это Ethernet frame, а идентификатор - MAC address. Для сетевого взаимодействия у нас появляется L3 с PDU IP packet и идентификатор IP address. И собственно ARP/RARP у нас выполняют сопоставление IP-MAC. То есть протоколы между двумя уровнями OSI
Падать при компиляции - это безумие. Ну если это pet-проект, то наверное да. Но Deprecated может висеть годами и десятилетиями. Например Thread.stop() и еще несколько методов ушли в Deprecated в Java 1.2 !!! 26 лет назад. И до сих пор висит со статусом "Deprecated, for removal: This API element is subject to removal in a future version."
А вот собирать в рантайме через JFR и рефакторить по мере обнаружения - очень правильный путь.
Очень сомнительно, что в рантайме будет профит по времени запуска. На прогрев JVM больше влияют параметры типа TieredCompilation. А по памяти разницы вообще не должно быть. Мы же не грузим в память всю либу зависимостей, а только используемые классы в Metaspace по мере обращения к ним. Практическая польза может быть в случае использования контейнеров. Если мы значительное число релизов едем не обновляя зависимости, то легко можно сформировать docker image с зависимостями и вкатывать следующим слоем application. Можно чуть-чуть сэкономить на времени сборки. А если артефакт должен отправлятьься в географически распределенные ДЦ, то и немало.
Хранение "чувствительной" информации в env - плохая идея. Если приложение исполняется не в контейнере, (вот совсем legacy инфра) то его env будет виден всем админам. Если это k8s, то env всё равно должен быть в git где описаны деплойменты и будет виден админам инфры. Хранение секретов нужно выносить в хранилку секретов. Vault, Infiscal, AWS Secret manager. Вариантов много.
Хорошая статья. Если расписывать всю историю, особенности и холиварить за терминологию, то необходим цикл статей только в финале которых была бы статья про тестирование. Наверное цикл я читать бы не стал.
Очень странная статья. Пожалуй стоит по пунктам пройти. Но в обратном порядке. 4. Vararg для методов существует примерно с версии 1.5 Этой фиче лет 15-20 и её должен знать каждый джун. Иначе он не знает инструмент. А дальше возникает вопрос например целесообразности использования в случае myMethod(Object... objects). Вывод - фича уровня джун. Он обязан её знать. Целесообразность (стоимость) использования... ну может джун+ Если на собесе он расскажет почему бы лучше не использовать instanceof 3. Лямбды. Ну вот не смешно. Их завезли в язык вместе с функциональными интерфейсами и Stream API, варианты которого приведены как лямбда выражения. Это начало "реанимации" Java, как конкурентного языка. Вывод - фича уровня джун. Он обязан её знать. И тоже понимать, как оно "под капотом". Иногда эти вещи вредят. Начиная со специфики пробрасывания исключений из лямбд и заканчивая падением производительности в рантайме. 2. Record. Вот полезная фишка в чистом виде для DTO. Удобно и просто. Суперфича? Да хз. По сути это почти аннотация "@Data" из lombok. Уменьшает рутину. 1. Секционные классы. Это можно развидеть как-нибудь? Sealed class это от слова seal - печать. Это "запечатаный класс". Суперфункциональность?.. Да нет. Немного безопасности в коде. Фича ну так себе.
И вот вопрос, а почему тогда нет других фич "JEP", которые были завезены в Java в последние годы? Долгожданные мультистринги, var, новые фичи в switch expression, пробросы в exception источника NPE. Да их не один десяток при прыжке с 1.8 до ключевых 11 - 17 -21 версий, которые и язык делают лучше и очень дорабатывают рантайм.
Я наверное подорву пуканы старожилам, но Лукьяненко давно "не торт". Я не знаю, может по инерции ставят баллы тому же циклу "Соглашение". "Рояли в кустах" это основа всех книг автора. Но в "Соглашении" - это треш какой-то. Я долго ждал третью часть и получил кусок "ерунды".
Это даже не смешно.
Статья - огонь. Для тех, кто понимает.
Спасибо.
Хороший пример.
Но в вашем случае явно виден источник утечки в меткиках DirectBuffer Pool (количество аллокаций и суммарный размер). И включив NMT вы увидите прогрессирующую статистику. Дальше можно снять хипдамп и увидеть ненормальное количество инстансов класса.
Но у DirectBuffer есть очень нехороший паттерн поведения, когда RSS процесса растет, а все метрики по Native Memory в норме, что может привести к системному OOMKiller.
Это связано с тем, что под капотом DirectBuffer pool никакого пула на самом деле нет. Есть только Atomic каунтеры количества и размера. А механизм это тривиальные malloc() - free(), ну и плюс к объекту, использующему этот "пул" прикручивается java.lang.ref.Cleaner (c 11 версии). Поэтому и зачистка только во время GC. В итоге получается, что в нативной памяти процесса создаются и удаляются "кусочки памяти" которые ведут к её фрагментации и распуханию RSS, который невозможно диагностировать стандартными метриками. Обычно утечка проявляется на хорошо нагруженных сервисах обрабатывающих http/grpc.
Раньше с проблемой бороться было невозможно, кроме перезапуска приложения, но в glibc с версии 2.8 завезли malloc_trim() который умеет во всем адресном пространстве процесса релизить "залипшую память".
В JVM в DiagnosticCommand сделали метод trimNativeMemory() который можно дернуть через JMX MBean (в контейнере) или через jcmd в обычной инсталляции. А в JVM 17.0.9 сделали ключ -XX:TrimNativeInterval (пока экспериментальный) который взводит таймер регулярных malloc_trim()
С точки зрения GC, проблему, описанную в статье на небольших сервисах "лечил" паллиативно путем использования ZGC (утечки были в зависимостях, не в нашем коде). У G1 да, были проблемы с утечками буферов, но вроде бы они её вылечили и они чистятся сейчас в mixed фазе, но это не точно.
Ну так себе. Законы меняются.
Моя жена в "пандемию" уплатила штраф 1500 рублей. За не предоставление инфы о зарубежном счете. По движениям по счету отчетность уже была не нужна, ибо другое налоговое резидентство. Хуже про валютное резидентство. Тут проще запустить процедуру отказа от гражданства, чем иметь "долги"
Хорошая статья. Спасибо.
Это наоборот очень полезно для контейнеров.
При текущем подходе docker будет собираться минимум из
OS + JVM + App FatJar
Вес FatJar может быть сотни мегабайт и гонять этот артифакт в облака могут по несколько раз в день.
При наличии CDS
OS + JVM + CDS + App
Сам по себе App от сотен до нескольких мегабайт обычно. CDS же будет меняться только при обновлении зависимостей, то есть достаточно редко. Если команда пилит несколько сервисов используя общий BOM то получается очень хорошее решение.
А можно для начала обозначить понятие "командный дух"? Такие вещи очень часто звучат в "сетевых магазинах", где люди, работающие за копейки, будут петь утром "гимн компании".
А может быть "командный дух", когда ребята из разработки, при содействии HR поехали на пейнтбол. И либо бэкендеры воюют с фронтендерами, либо все с тестерами.
На митах и оффлайнах так же возникают связи. Которые могут перейти в "последняя пятница месяца". В баре с пивом.
Командный дух невозможно прописать в регламентах компании. Его невозможно создать навязыванием тупых инициатив от HR (в следующую субботу едем прыгать в мешках. Явка обязательна). Его нужно отращивать, как и компетенции в профессиональной области.
Ну для кликбейта наверное статья хороша. Но (а как извсестно до "Но" инфа игнорируется)
Пром не умеет в персистенс. Поэтому мы или видим короткую историю, либо юзаем mimir, который прекрасно реализует персистенс для prom. А если подумаем об обсервабилити приложения, то затащим еще и GrafanaTempo, как универсальный коллектор трейсов. Как Zipkin, Jaeger. Ну и Loki конечно. Но поверх S3.
А если отходим от стека Grafana, то там будет VictoriaMetrics и куча своих "чудес"
Хабр "прекрасен". Убить карму в комментах, где только и разрешено писать - это сильно. Причем на корректном посте, задевшем ЧСВ другого комментатора. Ну что же поделать. Мои коллеги теперь знают с кем и каким юрлицом лучше не сотрудничать.
Вы бы обосновали свои заявления до того, как проявлять токсичность.
Коллега, вы еще раз подчеркиваете то, что вы далеки от темы.
JDK - это Development Kit. Набор инструментов, который предназначен для разработки и отладки приложений на Java. И этот набор должен (TCK) гарантировать, что мнемоническая команда "swap" имея код "5f" свопнет два верхних слова на стеке. То есть javac на выходе даст всегда одинаковый байткод.
И JDK он же одинаков. Есть фундаментальная база, обложенная JSR. Если кто-то из производителей хочет "обогатить" JDK своими новыми либами - да пожалуйста. Кто-то мешает использовать в С++ boost? Никто, кроме корпоративных правил. Но наработки boost уходят в апстрим языка.
И вот тут возникает Java SE. Набор библиотек, которые работают поверх JVM. И они формируют язык и экосистему. И он стандартен. Иначе это не Java. Кто был не согласен - сделали Scala, Closure, Kotlin (огромное спасибо ребятам из JetBrains)
Вы в своем же посте путаете кучу понятий.
В вашем перечислении присутствует HotSpot. Но это не JDK, это имплементация рантайма. Как и JamaicaVM, дорогая имплементация JVM под real-time. Это не JDK, это рантаймы.
Текущие популярные сбоки Java SE
Temurin
Coretto
Liberica
Да и прочие несут в себе стандартный набор библиотек. Не отличающийся от OpenJDK. Байт-код там будет всегда одинаков. Но может быть обогащен. Никто не мешает заменять условно запрещенный sun.misc.Unsafe на новые технологии.
Наш коллега, как мне кажется, катастрофически далёк от мира Java и занимается некоторой подменой понятий.
Если взять за точку отсчета 2010 год (Покупку Sun Microsystems компанией Oracle), то можно назвать достаточное количество имплементаций JVM.
* Azul Zing от Azul Systems - старт 2002 год. Проприетарная платная JVM со своим высокопроизводительным Garbage Collector (GC)
* JRockit от BEA Systems - старт 2002 год. Затем куплена Oracle. Проприетарная и сильно платная. Уникальный для того времени GC, который скорее всего лег в основу G1 OpenJDK и Oracle JVM. Убита Oracle в 2012
* IBM J9 от понятно кого. С ростом популярности Java и распространением энтерпрайзного софта на этой платформе IBM в 1999 году заключило соглашение с Sun и получило право форкнуть Java SE (кажется 1.3) чтобы сделать порты под AIX, z/OS с учетом специфики IBM POWER и мэнфреймов.
* SAP JVM. Не могу назвать точную дату, но первый релиз не позже Java SE 6, то есть 2004-2006 годы. Причина та же, что и у IBM. Дорогущее энтерпрайзное ПО работающее на ОСях - Windows, Solaris, HP-UX, AIX, i5/OS (IBM i) и на процах - x86, x86-64, IA-64, SPARC, PA-RISC, PowerPC (IBM POWER). SAP договаривается с Sun и делает форки под все платформы, чтобы системные интеграторы при внедрении систем не плясали с бубном.
* OpenJDK. 2007 год, случилось знаковое событие. Поняв все преимущества коллективной разработки OpenSource компания Sun Microsystems публикует исходники своей JVM под названием OpenJDK и лицензией GPL-2
Можно еще продолжить, но нет смысла. Тут и так 5 абсолютно различных имплементаций, ни в коем случае не сборок, JVM, эпохи до Oracle. И конечно Java software будет на них выполняться одинаково в соответствии с заявленной версией совместимости с TCK (наборами JSR).
Теперь можно и к сборкам перейти. Oracle не стал закрывать OpenJDK лицензиями. Более того, OpenJDK - это основная платформа OracleJDK в которую включены некоторые проприетарные элементы. Лично мне непонятен ход с лицензиями на OracleJDK, как и не понимаю, кому нужна именно сборка от Oracle, там нет киллер фич. Но прошла некоторая волна создания сборок OpenJDK другими компаниями. И в этом вообще нет никаких проблем. Та же AdoptOpenJDK (Eclipse Temurin) это сборка референсной OpenJDK и возможность получить платную поддержку. Российская LibericaJDK - сборка, но плюс ребята дописывают улучшения, не ломающие TCK и являются контрибуторами OpenJDK. Примерно такая же ситуация с Amazone Coretto.
Я работаю в компании, в которой уже много лет собираю собственные сборки OpenJDK и дописываю патчи, которые не ломают TCK, но учитывают особенности нашего продакшена в рантайме.
Это ошибка. Всё, что есть в TCP, всякие congestion control, MSS это всё L4, ничего из L5 там нет. Вообще основное количество протоколов L5 это всякие туннели, предоставляющие L2 уровень через L5. L2TP, PPTP.
В статье про L4 тоже ошибка. Там указан TLS. Скорее всего из-за названия - Transport Layer Security. Сам протокол работает поверх TCP (DTLS поверх UDP) и фактически обеспечивает уровень представления. Но с точки зрения разработчика приложения работа с TLS строится как с сокетами. Видимо отсюда дополнительная путаница.
Но нужно отметить, что не всегда протокол можно четко отнести к одному уровню. Как пример - ARP/RARP. Если мы рассматриваем Ethernet и TCP/IP, то на L2 у нас protocol data unit (PDU) - это Ethernet frame, а идентификатор - MAC address. Для сетевого взаимодействия у нас появляется L3 с PDU IP packet и идентификатор IP address. И собственно ARP/RARP у нас выполняют сопоставление IP-MAC. То есть протоколы между двумя уровнями OSI
Падать при компиляции - это безумие. Ну если это pet-проект, то наверное да. Но Deprecated может висеть годами и десятилетиями. Например Thread.stop() и еще несколько методов ушли в Deprecated в Java 1.2 !!! 26 лет назад. И до сих пор висит со статусом "Deprecated, for removal: This API element is subject to removal in a future version."
А вот собирать в рантайме через JFR и рефакторить по мере обнаружения - очень правильный путь.
Очень сомнительно, что в рантайме будет профит по времени запуска. На прогрев JVM больше влияют параметры типа TieredCompilation. А по памяти разницы вообще не должно быть. Мы же не грузим в память всю либу зависимостей, а только используемые классы в Metaspace по мере обращения к ним.
Практическая польза может быть в случае использования контейнеров. Если мы значительное число релизов едем не обновляя зависимости, то легко можно сформировать docker image с зависимостями и вкатывать следующим слоем application. Можно чуть-чуть сэкономить на времени сборки. А если артефакт должен отправлятьься в географически распределенные ДЦ, то и немало.
Хранение "чувствительной" информации в env - плохая идея. Если приложение исполняется не в контейнере, (вот совсем legacy инфра) то его env будет виден всем админам. Если это k8s, то env всё равно должен быть в git где описаны деплойменты и будет виден админам инфры. Хранение секретов нужно выносить в хранилку секретов. Vault, Infiscal, AWS Secret manager. Вариантов много.
Хорошая статья. Если расписывать всю историю, особенности и холиварить за терминологию, то необходим цикл статей только в финале которых была бы статья про тестирование. Наверное цикл я читать бы не стал.
Очень странная статья. Пожалуй стоит по пунктам пройти. Но в обратном порядке.
4. Vararg для методов существует примерно с версии 1.5 Этой фиче лет 15-20 и её должен знать каждый джун. Иначе он не знает инструмент. А дальше возникает вопрос например целесообразности использования в случае myMethod(Object... objects).
Вывод - фича уровня джун. Он обязан её знать. Целесообразность (стоимость) использования... ну может джун+ Если на собесе он расскажет почему бы лучше не использовать instanceof
3. Лямбды. Ну вот не смешно. Их завезли в язык вместе с функциональными интерфейсами и Stream API, варианты которого приведены как лямбда выражения. Это начало "реанимации" Java, как конкурентного языка.
Вывод - фича уровня джун. Он обязан её знать. И тоже понимать, как оно "под капотом". Иногда эти вещи вредят. Начиная со специфики пробрасывания исключений из лямбд и заканчивая падением производительности в рантайме.
2. Record. Вот полезная фишка в чистом виде для DTO. Удобно и просто. Суперфича? Да хз. По сути это почти аннотация "@Data" из lombok. Уменьшает рутину.
1. Секционные классы. Это можно развидеть как-нибудь? Sealed class это от слова seal - печать. Это "запечатаный класс". Суперфункциональность?.. Да нет. Немного безопасности в коде. Фича ну так себе.
И вот вопрос, а почему тогда нет других фич "JEP", которые были завезены в Java в последние годы? Долгожданные мультистринги, var, новые фичи в switch expression, пробросы в exception источника NPE. Да их не один десяток при прыжке с 1.8 до ключевых 11 - 17 -21 версий, которые и язык делают лучше и очень дорабатывают рантайм.
Я наверное подорву пуканы старожилам, но Лукьяненко давно "не торт".
Я не знаю, может по инерции ставят баллы тому же циклу "Соглашение". "Рояли в кустах" это основа всех книг автора. Но в "Соглашении" - это треш какой-то. Я долго ждал третью часть и получил кусок "ерунды".
В материале много ошибок. Автору его нужно переосмыслить.
Текст напоминает помесь Нейросетей с Гуглотранслейтом.