Всем привет!
Для далекой канадской компании - разработчика лучшего в мире графического редактора, важны русские платящие пользователи: https://habr.com/ru/news/738514/
А для компании - разработчика лучшей в мире IDE, имеющей русские корни, увы, нет(((
#IDEA
Для далекой канадской компании - разработчика лучшего в мире графического редактора, важны русские платящие пользователи: https://habr.com/ru/news/738514/
А для компании - разработчика лучшей в мире IDE, имеющей русские корни, увы, нет(((
#IDEA
Хабр
Adobe решила бесплатно продлевать российским пользователям-физлицам лицензии, купленные через официальный магазин
image Американская компания Adobe решила бесплатно продлевать лицензии российским пользователям-физлицам, которые ранее купили доступ к ПО через официальный интернет-магазин. «У пользовательских...
Всем привет!
Есть типичный пример плохого кода - большие процедуры, десятки или даже сотня строк каждая, неговорящие имена переменных, клубок вызовов, также известный как спагетти код. А тут прилетает задача - сервис нужно доработать, добавив какую-то важную проверку.
Есть техники для борьбы с плохим кодом. В первую очередь это собственно ООП - разделение кода по классам. Потом можно применить принцип единственной ответственности - каждый класс и метод отвечает за что-то одно. Далее идут принципы, описанные в книге "Чистый код" - понятные наименования, небольшие методы. Можно еще заполировать все это DDD - выделив ограниченный контекст. И разделить код по слоям, например, используя гексагональную архитектуру. Или даже разделить на микросервисы)
В результате получим десятки маленьких объектов, с четкой областью ответственности, хорошо читаемый код в каждом методе.
Но можно упустить важный момент - после выполнения всех доработок понять как работает система в целом (!) все равно будет сложно. Т.к. система стала слишком большой и сложной. И тут на приходит на помощь принцип KISS - Keep it simple. Перед тем, как начинать проектировать и кодить стоит задать вопрос - нужна ли еще одна валидация в коде? Может она уже есть в микросервисе, из которого мы получаем данные? Может вероятность появления таких данных в ПРОМ (PROD) стремится к нулю? Может можно подключить внешнюю библиотеку, где все уже сделано до нас?
В общем не забывайте про KISS)
#arch #clean_code #principles
Есть типичный пример плохого кода - большие процедуры, десятки или даже сотня строк каждая, неговорящие имена переменных, клубок вызовов, также известный как спагетти код. А тут прилетает задача - сервис нужно доработать, добавив какую-то важную проверку.
Есть техники для борьбы с плохим кодом. В первую очередь это собственно ООП - разделение кода по классам. Потом можно применить принцип единственной ответственности - каждый класс и метод отвечает за что-то одно. Далее идут принципы, описанные в книге "Чистый код" - понятные наименования, небольшие методы. Можно еще заполировать все это DDD - выделив ограниченный контекст. И разделить код по слоям, например, используя гексагональную архитектуру. Или даже разделить на микросервисы)
В результате получим десятки маленьких объектов, с четкой областью ответственности, хорошо читаемый код в каждом методе.
Но можно упустить важный момент - после выполнения всех доработок понять как работает система в целом (!) все равно будет сложно. Т.к. система стала слишком большой и сложной. И тут на приходит на помощь принцип KISS - Keep it simple. Перед тем, как начинать проектировать и кодить стоит задать вопрос - нужна ли еще одна валидация в коде? Может она уже есть в микросервисе, из которого мы получаем данные? Может вероятность появления таких данных в ПРОМ (PROD) стремится к нулю? Может можно подключить внешнюю библиотеку, где все уже сделано до нас?
В общем не забывайте про KISS)
#arch #clean_code #principles
Всем привет!
По моему опыту далеко не все разработчики пришли в профессию с ИТ образованием. Я сам такой, в ВУЗе изучал только курс по базам данных, причем преподаватель изучал их вместе с нами) Следовательно, не все знают т.н. Computer Science, в т.ч. теорию алгоритмов.
Чтобы иметь понимание о базовых вещах предлагаю пару видео:
Сложность алгоритмов https://youtu.be/cXCuXNwzdfY
Сортировка https://youtu.be/PF7AqefS4MU
Да и в целом канал неплохой.
Мне понравилась наглядность - разбирается все на картинках - и пошаговый подход к разбору алгоритма, очень похожий на TDD)
Один минус, на каждые 10 минут видео в среднем одна реклама) Но что сделаешь, контент бесплатный)
#algorithms
По моему опыту далеко не все разработчики пришли в профессию с ИТ образованием. Я сам такой, в ВУЗе изучал только курс по базам данных, причем преподаватель изучал их вместе с нами) Следовательно, не все знают т.н. Computer Science, в т.ч. теорию алгоритмов.
Чтобы иметь понимание о базовых вещах предлагаю пару видео:
Сложность алгоритмов https://youtu.be/cXCuXNwzdfY
Сортировка https://youtu.be/PF7AqefS4MU
Да и в целом канал неплохой.
Мне понравилась наглядность - разбирается все на картинках - и пошаговый подход к разбору алгоритма, очень похожий на TDD)
Один минус, на каждые 10 минут видео в среднем одна реклама) Но что сделаешь, контент бесплатный)
#algorithms
YouTube
ВСЯ СЛОЖНОСТЬ АЛГОРИТМОВ ЗА 11 МИНУТ | ОСНОВЫ ПРОГРАММИРОВАНИЯ
Онлайн-буткемп «Junior-аналитик с нуля за 10 недель»: https://go.skillfactory.ru/JD4LkA
По промокоду ALEKOS скидка 45%
Оценка сложности алгоритмов за 11 минут.
Подписывайся в соц. сетях:
Телеграм - https://t.me/Alek_OS
ВК - https://vk.com/alekos1
❤️ Поддержка…
По промокоду ALEKOS скидка 45%
Оценка сложности алгоритмов за 11 минут.
Подписывайся в соц. сетях:
Телеграм - https://t.me/Alek_OS
ВК - https://vk.com/alekos1
❤️ Поддержка…
Всем привет!
Иногда возникает необходимость создать ветку в репозитории Git никак не связанную с уже существующими ветками.
Первым делом при такой потребности я хочу процитировать наверное самый популярный ответ на StackOverflow - а вам точно нужно это делать?) В данном случае он справедлив, т.к. не стоит хранить в одном репозитории слабосвязанный код:
а) приложение и его библиотеки
б) код и API\документацию\настройки\скрипты БД если их создают члены команды с разными ролями и разным подходом к код-ревью и слиянию - к примеру разработчики и аналитики
в) наоборот, если API\документацию\настройки\скрипты БД создают одни и те же люди - не стоит их разносить по разным веткам.
Но бывают кейсы, требующие нескольких несвязанных между собой веток. Например, две сильно различающиеся версии приложения.
Есть три способа решить эту задачу.
1) очевидный и неправильный - создать новую ветку на основе существующей, удалить все файлы и залить новые
2) изначально завести ветку c readme.md, от которой можно будет создавать новые чистые ветки
3) выполнить вот такие команды
git checkout --orphan newbranch
git rm -rf .
и далее как обычно.
#git
Иногда возникает необходимость создать ветку в репозитории Git никак не связанную с уже существующими ветками.
Первым делом при такой потребности я хочу процитировать наверное самый популярный ответ на StackOverflow - а вам точно нужно это делать?) В данном случае он справедлив, т.к. не стоит хранить в одном репозитории слабосвязанный код:
а) приложение и его библиотеки
б) код и API\документацию\настройки\скрипты БД если их создают члены команды с разными ролями и разным подходом к код-ревью и слиянию - к примеру разработчики и аналитики
в) наоборот, если API\документацию\настройки\скрипты БД создают одни и те же люди - не стоит их разносить по разным веткам.
Но бывают кейсы, требующие нескольких несвязанных между собой веток. Например, две сильно различающиеся версии приложения.
Есть три способа решить эту задачу.
1) очевидный и неправильный - создать новую ветку на основе существующей, удалить все файлы и залить новые
2) изначально завести ветку c readme.md, от которой можно будет создавать новые чистые ветки
3) выполнить вот такие команды
git checkout --orphan newbranch
git rm -rf .
и далее как обычно.
#git
Всем привет!
Уже говорил про переиспользование кода в общих библиотеках https://t.me/javaKotlinDevOps/137
Поднимемся на уровень выше: возьмем набор библиотек с общим кодом, добавим туда реализацию обязательных архитектурных стандартов, требований сопровождения и безопасности - и получим платформу.
Какой должна быть хорошая платформа? Первый напрашивающийся ответ - смотри на Spring Framework. Но попытаюсь конкретизировать.
1) модульность и минимум зависимостей между модулей. Наверняка есть какое-то ядро, которое часто именно так и называется, обязательное в любом случае. Но подключение остальных модулей должно быть опциональным, пользователь должен понимать зачем ему нужен тот или иной модуль.
2) хорошая документация, cookbook, отвечающий на вопросы: зачем использовать? как подключить? особенности реализации, антипаттерны?
3) работающее синтетическое приложение, каркас, позволяющее в коде увидеть ответы на вопросы из предыдущего пункта. С одной стороны получается дублирование, но учитывая что мы пытаемся "продать" не библиотеку, а целую платформу - код первичен, но одного кода недостаточно, не все можно показать в коде.
4) код и документация должны быть актуальными. Скорее всего на это потребуются отдельные люди, возможно даже отдельная команда. Т.к. разработка платформы скорее всего разделена на команды, команды заточены под свои локальные цели и не смотрят на платформу в целом, в особенности не видят проблем как пользователи.
5) self-service - у бизнес-команды должна быть возможность самостоятельно выполнять любые задачи, не связанные с исправлением багов и доработками компонента платформы. Пример таких задач - регистрация нового потребителя, метаданные для компонентов платформы, валидация скриптов. Самостоятельно - т.е. без тикетов на платформу, без согласований в почте, без встреч с платформенной командой. В идеале - кладем нужные нам стройке в git, далее DevOps pipeline их обрабатывает и результат отражается как результат выполнения джоба. Если есть возможность доработать код платформы самостоятельно - через механизм Inner Source - вообще отлично!)
6) должны быть четко очерчены сроки поддержки старых версий платформы. Естественно, сроки должны соблюдаться
7) API платформенных компонент должен быть единообразным. Хороший пример из Spring - многочисленные xxxTemplate. Или использование application.yml как централизованное место для настроек. За этим должен следить архитектор(ы) и команда, отвечающая за cookbook и синтетическое приложение.
8) платформенные компоненты должны предоставлять заглушки для возможности локальной отладки, информация о них должна быть в cookbook
9) convention over configuration = минимум настроек, которые разработчики должны прописать руками. Как пример - Spring Boot, хотя надо сказать сам Spring пришел к этому не сразу) Конечно каждая бизнес-задача уникальна, но по моему опыту в большинстве случаев достаточно типовой конфигурации с небольшими доработками. Рассмотрим альтернативу: если для поднятия минимального каркаса нужны сотни настроек - никто не будет в них разбираться, все их просто будут копировать. И хорошо, если из последней проверенной версии синтетического приложения.
10) платформа должна своевременно выпускать фиксы уязвимостей. Вроде очевидно, но важно.
11) у платформенной команды есть свой team lead, свой бэклог и главное - свое видение продукта. И это правильно. Но фокус в развитии продукта должен быть на потребителях. Всех потребителях - сопровождение, ИБ и конечно же бизнес-команды. Лично знаю случаи, когда разработчики платформы уходили в бизнес-команды и говорили - да, что-то я не думал, что нашей платформой так сложно пользоваться) Еще кейс - в бизнес-командах изобретено несколько похожих друг на друга "велосипедов", которые по хорошему должны быть в платформе изначально.
#arch #conv_over_conf
Уже говорил про переиспользование кода в общих библиотеках https://t.me/javaKotlinDevOps/137
Поднимемся на уровень выше: возьмем набор библиотек с общим кодом, добавим туда реализацию обязательных архитектурных стандартов, требований сопровождения и безопасности - и получим платформу.
Какой должна быть хорошая платформа? Первый напрашивающийся ответ - смотри на Spring Framework. Но попытаюсь конкретизировать.
1) модульность и минимум зависимостей между модулей. Наверняка есть какое-то ядро, которое часто именно так и называется, обязательное в любом случае. Но подключение остальных модулей должно быть опциональным, пользователь должен понимать зачем ему нужен тот или иной модуль.
2) хорошая документация, cookbook, отвечающий на вопросы: зачем использовать? как подключить? особенности реализации, антипаттерны?
3) работающее синтетическое приложение, каркас, позволяющее в коде увидеть ответы на вопросы из предыдущего пункта. С одной стороны получается дублирование, но учитывая что мы пытаемся "продать" не библиотеку, а целую платформу - код первичен, но одного кода недостаточно, не все можно показать в коде.
4) код и документация должны быть актуальными. Скорее всего на это потребуются отдельные люди, возможно даже отдельная команда. Т.к. разработка платформы скорее всего разделена на команды, команды заточены под свои локальные цели и не смотрят на платформу в целом, в особенности не видят проблем как пользователи.
5) self-service - у бизнес-команды должна быть возможность самостоятельно выполнять любые задачи, не связанные с исправлением багов и доработками компонента платформы. Пример таких задач - регистрация нового потребителя, метаданные для компонентов платформы, валидация скриптов. Самостоятельно - т.е. без тикетов на платформу, без согласований в почте, без встреч с платформенной командой. В идеале - кладем нужные нам стройке в git, далее DevOps pipeline их обрабатывает и результат отражается как результат выполнения джоба. Если есть возможность доработать код платформы самостоятельно - через механизм Inner Source - вообще отлично!)
6) должны быть четко очерчены сроки поддержки старых версий платформы. Естественно, сроки должны соблюдаться
7) API платформенных компонент должен быть единообразным. Хороший пример из Spring - многочисленные xxxTemplate. Или использование application.yml как централизованное место для настроек. За этим должен следить архитектор(ы) и команда, отвечающая за cookbook и синтетическое приложение.
8) платформенные компоненты должны предоставлять заглушки для возможности локальной отладки, информация о них должна быть в cookbook
9) convention over configuration = минимум настроек, которые разработчики должны прописать руками. Как пример - Spring Boot, хотя надо сказать сам Spring пришел к этому не сразу) Конечно каждая бизнес-задача уникальна, но по моему опыту в большинстве случаев достаточно типовой конфигурации с небольшими доработками. Рассмотрим альтернативу: если для поднятия минимального каркаса нужны сотни настроек - никто не будет в них разбираться, все их просто будут копировать. И хорошо, если из последней проверенной версии синтетического приложения.
10) платформа должна своевременно выпускать фиксы уязвимостей. Вроде очевидно, но важно.
11) у платформенной команды есть свой team lead, свой бэклог и главное - свое видение продукта. И это правильно. Но фокус в развитии продукта должен быть на потребителях. Всех потребителях - сопровождение, ИБ и конечно же бизнес-команды. Лично знаю случаи, когда разработчики платформы уходили в бизнес-команды и говорили - да, что-то я не думал, что нашей платформой так сложно пользоваться) Еще кейс - в бизнес-командах изобретено несколько похожих друг на друга "велосипедов", которые по хорошему должны быть в платформе изначально.
#arch #conv_over_conf
Telegram
(java || kotlin) && devOps
Всем привет!
В развитие темы про готовые решения и переиспользование знаний хочу поговорить про переиспользование кода.
Ясно, что все разработчики переиспользуют готовые решения - Spring Framework, Apache Commons да и вообще любые подключаемые к проекту…
В развитие темы про готовые решения и переиспользование знаний хочу поговорить про переиспользование кода.
Ясно, что все разработчики переиспользуют готовые решения - Spring Framework, Apache Commons да и вообще любые подключаемые к проекту…
Всем привет!
Минигайд по кодировкам в Maven.
Для начала - главное, что нужно знать про кодировки в целом:
1) UTF-8 рулит)
2) нужно явно указывать кодировку.
Как это сделать в Maven?
1)
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
Работает практически везде, за исключением пунктов 2) и 3) ниже.
2)
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
Работает для отчетных плагинов. Чтобы не выяснять для каких именно - проще установить и забыть)
3) Переменная среды JAVA_TOOL_OPTIONS равная -Dfile.encoding=UTF8
Работает тогда, когда Maven запускает отдельный Java процесс, в частности при запуске unit тестов из Maven. Причина падения тестов на Win, до этого успешно работающих на Mac\Lin. Падают из-за другой кодировки по умолчанию в Win.
4) Возможна точечная установка или переопределение кодировки для нужного плагина, например:
а) unit тесты
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
</plugin>
б) компиляция
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
Как видно из примеров - формат настроек у разных плагинов различается.
#maven
Минигайд по кодировкам в Maven.
Для начала - главное, что нужно знать про кодировки в целом:
1) UTF-8 рулит)
2) нужно явно указывать кодировку.
Как это сделать в Maven?
1)
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
Работает практически везде, за исключением пунктов 2) и 3) ниже.
2)
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
Работает для отчетных плагинов. Чтобы не выяснять для каких именно - проще установить и забыть)
3) Переменная среды JAVA_TOOL_OPTIONS равная -Dfile.encoding=UTF8
Работает тогда, когда Maven запускает отдельный Java процесс, в частности при запуске unit тестов из Maven. Причина падения тестов на Win, до этого успешно работающих на Mac\Lin. Падают из-за другой кодировки по умолчанию в Win.
4) Возможна точечная установка или переопределение кодировки для нужного плагина, например:
а) unit тесты
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Dfile.encoding=UTF-8</argLine>
</configuration>
</plugin>
б) компиляция
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
Как видно из примеров - формат настроек у разных плагинов различается.
#maven
Всем привет!
Еще немного про Maven. Есть несколько способов настроить версию Java в Maven, все они описаны в этой статье - https://www.baeldung.com/maven-java-version
Оптимальным начиная с Java 9 выглядит вариант с указанием
<properties>
<maven.compiler.release>9</maven.compiler.release>
</properties>
т.к. данное свойство заменяет собой три: source, target и bootclasspath. Последнее означает, что начиная с Java 9 все JDK умеют притворяться более ранними версиями с точностью до classpath, т.е. до предоставляемого API. А это важно при переходе на 11-ю и 17-ю Java - в первой выпилили Java EE модули, типа SOAP, во второй - закрыли internal пакеты.
Но это не все, что нужно знать про настройки версии JDK.
Если в проекте есть Kotlin - надежнее явно указать ему версию JDK. Для справки - старые версии Kotlin поддерживали только JDK 6 как target bytecode, потом был период JDK 8, сейчас поддерживается все версии https://kotlinlang.org/docs/maven.html
Настраивается так:
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<configuration>
<jvmTarget>1.9</jvmTarget>
По хорошему плагин Kotlin должен переиспользовать maven.compiler.release, но я не нашел подтверждающей это информации.
Второй тонкий момент связан с IDEA. IDEA смотрит на maven.compiler.release, в результате правильно проставляет:
а) Source language level для корневого и дочерних модулей Maven - это можно увидеть в Project Structure -> Modules
б) Target bytecode для всех модулей - Double Shift, далее вбиваем "java compiler".
Но есть еще одна важная опция Project Structure -> Project -> SDK. Она определяет версию JDK, на которой будет собираться проект. Повторюсь, из-за сильных изменений в структуре JDK как минимум в 11 и 17 версиях сборка на более новой JDK может сломаться. Причем из логов причина ошибки будет не ясна(
Так вот, IDEA в данном кейсе игнорирует настройки Maven. Прямого решения у проблемы я не нашел, судя по всему, ребята из IntelliJ считают, что корневой модуль в проекте Maven и проект IDEA это не одно и тоже. И это фича, а не баг)
Но есть обходной путь. Если все или большинство ваших проектов живут на определенной версии JDK, то ее можно выставить в IDEA по умолчанию. Настраивается вот здесь: Double Shift, далее вбиваем "structure for new projects"
#maven #java #kotlin
Еще немного про Maven. Есть несколько способов настроить версию Java в Maven, все они описаны в этой статье - https://www.baeldung.com/maven-java-version
Оптимальным начиная с Java 9 выглядит вариант с указанием
<properties>
<maven.compiler.release>9</maven.compiler.release>
</properties>
т.к. данное свойство заменяет собой три: source, target и bootclasspath. Последнее означает, что начиная с Java 9 все JDK умеют притворяться более ранними версиями с точностью до classpath, т.е. до предоставляемого API. А это важно при переходе на 11-ю и 17-ю Java - в первой выпилили Java EE модули, типа SOAP, во второй - закрыли internal пакеты.
Но это не все, что нужно знать про настройки версии JDK.
Если в проекте есть Kotlin - надежнее явно указать ему версию JDK. Для справки - старые версии Kotlin поддерживали только JDK 6 как target bytecode, потом был период JDK 8, сейчас поддерживается все версии https://kotlinlang.org/docs/maven.html
Настраивается так:
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<configuration>
<jvmTarget>1.9</jvmTarget>
По хорошему плагин Kotlin должен переиспользовать maven.compiler.release, но я не нашел подтверждающей это информации.
Второй тонкий момент связан с IDEA. IDEA смотрит на maven.compiler.release, в результате правильно проставляет:
а) Source language level для корневого и дочерних модулей Maven - это можно увидеть в Project Structure -> Modules
б) Target bytecode для всех модулей - Double Shift, далее вбиваем "java compiler".
Но есть еще одна важная опция Project Structure -> Project -> SDK. Она определяет версию JDK, на которой будет собираться проект. Повторюсь, из-за сильных изменений в структуре JDK как минимум в 11 и 17 версиях сборка на более новой JDK может сломаться. Причем из логов причина ошибки будет не ясна(
Так вот, IDEA в данном кейсе игнорирует настройки Maven. Прямого решения у проблемы я не нашел, судя по всему, ребята из IntelliJ считают, что корневой модуль в проекте Maven и проект IDEA это не одно и тоже. И это фича, а не баг)
Но есть обходной путь. Если все или большинство ваших проектов живут на определенной версии JDK, то ее можно выставить в IDEA по умолчанию. Настраивается вот здесь: Double Shift, далее вбиваем "structure for new projects"
#maven #java #kotlin
Baeldung
Setting the Java Version in Maven | Baeldung
Learn about different ways to set the Java version for your Maven project
Всем привет!
Когда-то давно - год назад - у меня была заметка, чем хорош k8s: https://t.me/javaKotlinDevOps/6
Там был упомянут Docker, пришло время подробнее раскрыть, что же дают нам контейнеры. Вообще говоря контейнеры и Docker не одно и тоже, но в данном случае различием можно пренебречь.
1) идентичное окружение на dev, test и prod. Да, JRE уже дает нам уровень абстракции от ОС и железа, и это большой плюс в плане запуска Java в разных ОС. Но есть проблемы:
а) разные версии JDK
б) разные сервера приложений\контейнеры сервлетов
в) разный classpath, часто как следствие предыдущего пункта
г) разные переменные среды
д) разное состояние файловой системы
Все это можно решить, но часто решение дорогое - сложные CD pipeline, долгое время деплоя, сложность поднятия prod-like среды на машине разработчика.
C Docker-ом мы получаем immutable infrastructure - набор ПО, настроек и состояние файловой системы зафиксированы на dev и остаются неизменными дальше.
2) легковесная изоляция сервисов. Контейнеризация обеспечивает изоляцию файловой системы, процессов, сетевых интерфейсов и резервирование ресурсов для каждого запущенного на сервере контейнера. Используются механизмы ядра Linux, подробнее см. https://habr.com/ru/articles/659049/
Ключевой момент тут - легковесная, т.к. технологии изоляции в виде виртуальных машин известны давно. Но виртуальная машина эмулирует железо, что сложно, см. стоимость лицензии VMware, к тому же приводит к достаточно высоким накладным расходам по CPU, памяти и диску. Плюс поверх виртуалки нужна гостевая операционная система, а значит запуск виртуалки - это долго.
3) легкость установки. Т.к в Docker сейчас упаковывается почти все (https://hub.docker.com/search, нужна регистрация), то появляется возможность быстро и без ущерба для компьютера разработчика развернуть необходимое серверное ПО - СУБД, Kafka, кэши, мониторинг... А если данные сервисы нужны для тестов - на помощь приходит Testсontainers https://java.testcontainers.org/ Все это работает на Linux, MacOS и Windows, например, с помощью Docker Desktop https://www.docker.com/products/docker-desktop/ Может возникнуть вопрос - откуда на Windows появились механизмы ядра Linux? Ответ: благодаря технологии WSL - https://learn.microsoft.com/ru-ru/windows/wsl/.
Аналогично на серверах - установка образа проще и стабильнее установки классического серверного ПО.
Если говорить именно о Docker - то в общем то это все, остальные преимущества раскрываются в связке с k8s и Service Mesh.
#docker #k8s
Когда-то давно - год назад - у меня была заметка, чем хорош k8s: https://t.me/javaKotlinDevOps/6
Там был упомянут Docker, пришло время подробнее раскрыть, что же дают нам контейнеры. Вообще говоря контейнеры и Docker не одно и тоже, но в данном случае различием можно пренебречь.
1) идентичное окружение на dev, test и prod. Да, JRE уже дает нам уровень абстракции от ОС и железа, и это большой плюс в плане запуска Java в разных ОС. Но есть проблемы:
а) разные версии JDK
б) разные сервера приложений\контейнеры сервлетов
в) разный classpath, часто как следствие предыдущего пункта
г) разные переменные среды
д) разное состояние файловой системы
Все это можно решить, но часто решение дорогое - сложные CD pipeline, долгое время деплоя, сложность поднятия prod-like среды на машине разработчика.
C Docker-ом мы получаем immutable infrastructure - набор ПО, настроек и состояние файловой системы зафиксированы на dev и остаются неизменными дальше.
2) легковесная изоляция сервисов. Контейнеризация обеспечивает изоляцию файловой системы, процессов, сетевых интерфейсов и резервирование ресурсов для каждого запущенного на сервере контейнера. Используются механизмы ядра Linux, подробнее см. https://habr.com/ru/articles/659049/
Ключевой момент тут - легковесная, т.к. технологии изоляции в виде виртуальных машин известны давно. Но виртуальная машина эмулирует железо, что сложно, см. стоимость лицензии VMware, к тому же приводит к достаточно высоким накладным расходам по CPU, памяти и диску. Плюс поверх виртуалки нужна гостевая операционная система, а значит запуск виртуалки - это долго.
3) легкость установки. Т.к в Docker сейчас упаковывается почти все (https://hub.docker.com/search, нужна регистрация), то появляется возможность быстро и без ущерба для компьютера разработчика развернуть необходимое серверное ПО - СУБД, Kafka, кэши, мониторинг... А если данные сервисы нужны для тестов - на помощь приходит Testсontainers https://java.testcontainers.org/ Все это работает на Linux, MacOS и Windows, например, с помощью Docker Desktop https://www.docker.com/products/docker-desktop/ Может возникнуть вопрос - откуда на Windows появились механизмы ядра Linux? Ответ: благодаря технологии WSL - https://learn.microsoft.com/ru-ru/windows/wsl/.
Аналогично на серверах - установка образа проще и стабильнее установки классического серверного ПО.
Если говорить именно о Docker - то в общем то это все, остальные преимущества раскрываются в связке с k8s и Service Mesh.
#docker #k8s
Telegram
(java || kotlin) && devOps
Чем kubernetes, он же k8s лучше контейнера сервлетов или сервера приложений.
Во-первых под капотом k8s лежит Docker, а значит мы получаем все его плюшки. Не зря k8s называют оркестратором контейнеров. Чем занимается оркестратор?
1) планированиеи ресурсов.…
Во-первых под капотом k8s лежит Docker, а значит мы получаем все его плюшки. Не зря k8s называют оркестратором контейнеров. Чем занимается оркестратор?
1) планированиеи ресурсов.…
Всем привет!
Один из самых больших плюсов Java - ее экосистема. Что я под этим словом понимаю - библиотеки, фреймворки, инструменты для сборки, CI инструменты, клиенты для различных БД, очередей, систем мониторинга и т.д.
Приведу пример.
Есть такая штука Lombok.
У него одна из фичей - аннотация @Value, которая по сути добавляет поддержку records в Java до 14 версии. Еще аналогичная фича - data class в Kotlin. Другими словами, решаем задачу: без boiler plate кода получить иммутабельный класс, служащий только для хранения данных. Для использования как DTO к примеру.
Так вот. Недавно выяснил, что есть еще 2 специализированные библиотеки: AutoValue и Immutables - также решающие данную задачу)
Вот статья со сравнением https://dzone.com/articles/lombok-autovalue-and-immutables
Сравнивай, выбирай. Экосистема.
P.S. В самой статье, к слову поднимается один интересный вопрос - если Lombok получает целевой класс путем генерации байткода, то две другие библиотеки - путем генерации исходного кода. Второй подход на первый взгляд более прозрачный и надежный - сразу видно, что получается в итоге. А с Lombok - получаем "магию" и возможность посмотреть, что получилось под капотом, с помощью опции DeLombok. С другой строны код, который приходится писать самому, в случае Lombok проще.
#java
Один из самых больших плюсов Java - ее экосистема. Что я под этим словом понимаю - библиотеки, фреймворки, инструменты для сборки, CI инструменты, клиенты для различных БД, очередей, систем мониторинга и т.д.
Приведу пример.
Есть такая штука Lombok.
У него одна из фичей - аннотация @Value, которая по сути добавляет поддержку records в Java до 14 версии. Еще аналогичная фича - data class в Kotlin. Другими словами, решаем задачу: без boiler plate кода получить иммутабельный класс, служащий только для хранения данных. Для использования как DTO к примеру.
Так вот. Недавно выяснил, что есть еще 2 специализированные библиотеки: AutoValue и Immutables - также решающие данную задачу)
Вот статья со сравнением https://dzone.com/articles/lombok-autovalue-and-immutables
Сравнивай, выбирай. Экосистема.
P.S. В самой статье, к слову поднимается один интересный вопрос - если Lombok получает целевой класс путем генерации байткода, то две другие библиотеки - путем генерации исходного кода. Второй подход на первый взгляд более прозрачный и надежный - сразу видно, что получается в итоге. А с Lombok - получаем "магию" и возможность посмотреть, что получилось под капотом, с помощью опции DeLombok. С другой строны код, который приходится писать самому, в случае Lombok проще.
#java
DZone
Lombok, AutoValue, and Immutables
I liked Brandon's suggestion of a blog post comparing Project Lombok, AutoValue, and Immutables and this is a post that attempts to do that. I have covered Project Lombok, AutoValue, and Immutables individually with brief overviews, but this post is different…
Всем привет!
Три лайфхака по работе с Maven:
1) чтобы заработала отладка в IDEA при запуске через Maven к примеру unit тестов:
для версий surefire плагина >= 2.14: use -DforkCount=0
http://maven.apache.org/plugins/maven-surefire-plugin/examples/debugging.html
2) запустить цель (goal) на дочернем модуле и всех его детях: maven --projects artifactId --also-make-dependents
Полезно на больших многомодульных проектах. Подбробнее https://maven.apache.org/guides/mini/guide-multiple-modules-4.html
Запускать цель напрямую но дочернем проекте нельзя, т.к в таком случае не применятся настройки из корневого проекта - как Maven, так и к примеру Lombok.
Еще важно - перед тем, как отлаживать дочерний проект нужно проинсталлировать в локальный Maven репозиторий те модули, от которых он зависит. Я про maven install.
3) по умолчанию maven следует принципу fail fast и это правильно) Но если нужно понять, в каком состоянии проект - можно запустить полную сборку игнорирую промежуточные ошибки до окончания сборки: maven --fail-at-end
#maven #java
Три лайфхака по работе с Maven:
1) чтобы заработала отладка в IDEA при запуске через Maven к примеру unit тестов:
для версий surefire плагина >= 2.14: use -DforkCount=0
http://maven.apache.org/plugins/maven-surefire-plugin/examples/debugging.html
2) запустить цель (goal) на дочернем модуле и всех его детях: maven --projects artifactId --also-make-dependents
Полезно на больших многомодульных проектах. Подбробнее https://maven.apache.org/guides/mini/guide-multiple-modules-4.html
Запускать цель напрямую но дочернем проекте нельзя, т.к в таком случае не применятся настройки из корневого проекта - как Maven, так и к примеру Lombok.
Еще важно - перед тем, как отлаживать дочерний проект нужно проинсталлировать в локальный Maven репозиторий те модули, от которых он зависит. Я про maven install.
3) по умолчанию maven следует принципу fail fast и это правильно) Но если нужно понять, в каком состоянии проект - можно запустить полную сборку игнорирую промежуточные ошибки до окончания сборки: maven --fail-at-end
#maven #java
maven.apache.org
Maven Surefire Plugin – Debugging Tests
Всем привет!
В последние годы стала "модной" тема null safety. Суть в том, что не нужно хранить и передавать null значения, чтобы не напороться на Null Pointer Exception. В том же Kotlin null safety встроена в язык - все типы по умолчанию не могут содержать null.
И на самом деле это правильный подход. Но есть нюансы)
Рассмотрим такой случай - мы идем куда-то за данными, данные по бизнес-процессу там обязаны быть. Например, мы прихранили id записи где-то в пользовательском контексте в начале процесса и идем за данными в конце процесса. Но данных нет. Следуя null safety можно просто создать пустой объект - например, с помощью конструктора. Как вариант, часть полей этого объекта будет проинициализирована значениями по умолчанию.
Так вот - в случае, когда данных нет из-за какой-то нештатной редко воспроизводимой ситуации: неверные тестовые данные, на сервис идет атака с перебором всех возможных значений, в процессе операции данные некорректно мигрировали, кривая архитектура - лучше просто "упасть", т.е. выбросить исключение. Есть такой принцип - fail fast. Т.к. создавая пустой объект, мы во-первых надеемся что он будет корректно обработан выше, а это может быть не так. А во-вторых - а зачем передавать управление дальше?
P.S. Как всегда - напомню каждую ситуацию нужно рассматривать индивидуально, чтобы различать отсутствие данных как часть бизнес-процесса и нештатную ситуацию.
#kotlin #code #patterns #principles #nullsafety #fail_fast
В последние годы стала "модной" тема null safety. Суть в том, что не нужно хранить и передавать null значения, чтобы не напороться на Null Pointer Exception. В том же Kotlin null safety встроена в язык - все типы по умолчанию не могут содержать null.
И на самом деле это правильный подход. Но есть нюансы)
Рассмотрим такой случай - мы идем куда-то за данными, данные по бизнес-процессу там обязаны быть. Например, мы прихранили id записи где-то в пользовательском контексте в начале процесса и идем за данными в конце процесса. Но данных нет. Следуя null safety можно просто создать пустой объект - например, с помощью конструктора. Как вариант, часть полей этого объекта будет проинициализирована значениями по умолчанию.
Так вот - в случае, когда данных нет из-за какой-то нештатной редко воспроизводимой ситуации: неверные тестовые данные, на сервис идет атака с перебором всех возможных значений, в процессе операции данные некорректно мигрировали, кривая архитектура - лучше просто "упасть", т.е. выбросить исключение. Есть такой принцип - fail fast. Т.к. создавая пустой объект, мы во-первых надеемся что он будет корректно обработан выше, а это может быть не так. А во-вторых - а зачем передавать управление дальше?
P.S. Как всегда - напомню каждую ситуацию нужно рассматривать индивидуально, чтобы различать отсутствие данных как часть бизнес-процесса и нештатную ситуацию.
#kotlin #code #patterns #principles #nullsafety #fail_fast
Всем привет.
Вопрос знатокам IDEA - что это за фича? Я знаю есть quick fix - и у некоторых из них есть опция - исправить во всем файле. Но тут я даже ничего не сделал) Т.е. IDEA сама нашла нужный enum и сделала import.
P.S. За пыль на экране извиняюсь)
#idea
Вопрос знатокам IDEA - что это за фича? Я знаю есть quick fix - и у некоторых из них есть опция - исправить во всем файле. Но тут я даже ничего не сделал) Т.е. IDEA сама нашла нужный enum и сделала import.
P.S. За пыль на экране извиняюсь)
#idea
Всем привет!
В продолжение темы функциональности IDEA и подготовки кода к code review, см. https://t.me/javaKotlinDevOps/148
Некоторые проверки и исправления можно подвесить на одно из двух событий:
1) на сохранение файла: Alt-Alt - Actions on Save. Рекомендую включить Reformat code и Optimize import.
2) перед commit на Git сервер - открыть окно Commit (Ctrl-K) и нажать там шестеренку. Рекомендую включить Analyze code, Check TODO и если выполнение тестов занимает приемлемое время - то еще и прогон тестов.
Легко заметить, что набор опций в обоих случаях похож, но на сохранении можно включить только те, где фиксы применяются без участия человека. В частности и Cleanup, и Analyze выполняют правила из набора инспекций (Inspections), только в первом случае включаются только те правила, где есть quick fixes, которые можно применить автоматически.
Насчет Cleanup - IMHO его вполне можно включить на commit, главное перепроверить набор активных правил: Shift-Shift - Inspections, а там включить фильтр Cleanup only. К слову - там еще есть профили с набором правил, можно добавить свой.
И еще важный момент - инспекции из IDEA можно запустить из командной строки, и т.об. включить в CI процесс: https://www.jetbrains.com/help/idea/command-line-code-inspector.html
Они частично повторяют проверки SonarQube, но не идентичны им.
#idea #code_review #clean_code #git
В продолжение темы функциональности IDEA и подготовки кода к code review, см. https://t.me/javaKotlinDevOps/148
Некоторые проверки и исправления можно подвесить на одно из двух событий:
1) на сохранение файла: Alt-Alt - Actions on Save. Рекомендую включить Reformat code и Optimize import.
2) перед commit на Git сервер - открыть окно Commit (Ctrl-K) и нажать там шестеренку. Рекомендую включить Analyze code, Check TODO и если выполнение тестов занимает приемлемое время - то еще и прогон тестов.
Легко заметить, что набор опций в обоих случаях похож, но на сохранении можно включить только те, где фиксы применяются без участия человека. В частности и Cleanup, и Analyze выполняют правила из набора инспекций (Inspections), только в первом случае включаются только те правила, где есть quick fixes, которые можно применить автоматически.
Насчет Cleanup - IMHO его вполне можно включить на commit, главное перепроверить набор активных правил: Shift-Shift - Inspections, а там включить фильтр Cleanup only. К слову - там еще есть профили с набором правил, можно добавить свой.
И еще важный момент - инспекции из IDEA можно запустить из командной строки, и т.об. включить в CI процесс: https://www.jetbrains.com/help/idea/command-line-code-inspector.html
Они частично повторяют проверки SonarQube, но не идентичны им.
#idea #code_review #clean_code #git
Telegram
(java || kotlin) && devOps
Всем привет!
Теперь перейдем к рекомендациям для авторов Pull Request (PR), они же Merge Request.
1) не нужно тратить время ревьювера на то, что могут сделать роботы) Я про чистку import и форматирование кода. Рекомендую поставить эти действия на автовыполнение…
Теперь перейдем к рекомендациям для авторов Pull Request (PR), они же Merge Request.
1) не нужно тратить время ревьювера на то, что могут сделать роботы) Я про чистку import и форматирование кода. Рекомендую поставить эти действия на автовыполнение…
Всем привет!
Когда-то давным-давно все, ну или почти все, использовали сборку JDK от Oracle. Хочу рассказать что же изменилось и что можно использовать сейчас.
В 2019 году Oracle изменила лицензионную политику и использовать JDK, а также JRE, бесплатно можно лишь для личных нужд. Версия, которую можно так использовать, получила название OpenJDK. Для коммерческих целей нужно приобретать лицензию, вне зависимости от того, нужна вам поддержка Oracle или нет. Эта версия - Oracle JDK. Кроме лицензионных условий сейчас эти сборки ничем не отличаются. Закон обратной силы не имеет, поэтому все предыдущие сборки можно использовать бесплатно, но любой hotfix JDK после 2019 года попадет под новые условия.
Это была первая проблема. Но кроме нее есть еще одна. Каждая версия OpenJDK от Oracle - это важно, что от Oracle - распространяется только полгода, потом идет переход на новую версию. И патчи выходят только для самой последней версии. Это касается и LTS - версий с долговременной поддержкой. Т.е Oracle OpenJDK 17 патчилась и распространялась полгода, потом стала доступна OpenJDK 18. Для тех, кто всегда готов к обновлениям - гуд) Но это не только лишь все)
Подробнее про это все можно почитать тут https://habr.com/ru/articles/448632/
Что же можно выбрать взамен? Есть довольно много компаний и opensource сообществ, которые берут исходники от Oracle OpenJDK, добавляют туда необходимые патчи, компилируют все это под определенные ОС и процессоры и выпускают для свободного скачивания. Отличаются они по следующим характеристикам:
1) набор версий Java. Как правило у всех есть 3 последние LTS - 8, 11, 17. У большинства есть последняя версия не LTS версия. У некоторых - даже 6-я и 7-я Java! А наличие 6-й Java означает не просто доступность ее для скачивания, но и обратное портирование туда критических патчей.
2) набор поддерживаемых ОС - Linux, Windows, MacOS
3) набор поддерживаемых процессорных архитектур - x64, x86 (32 бита), ARM
4) поддержка из коробки native image https://www.graalvm.org/native-image/
5) поддержка из коробки минималистичного образа Linux - Alpine. Я писал об различиях Docker образов тут https://t.me/javaKotlinDevOps/131
6) формат дистрибутива - инсталлятор, Docker образ. А если говорить про Дinux - поддержка разных менеджеров пакетов - rpm, deb...
7) формат поддержки - как правило он всегда доступен за деньги, но в некоторых случаях - JDK от ИТ гигантов - SAP, Microsoft, Amazon - поддержка доступна только вместе с продуктами этих компаний. Т.е. по сути эти JDK не для всех, а для тех кто использует соответствующее облако или продукт.
Неплохая статья со сравнением - https://bell-sw.com/blog/oracle-java-alternatives-comparison-of-openjdk-distributions
В конце статьи - сравнительная таблица.
Я бы особо выделил Temurin - JDK от Opensource сообщества и Liberica - JDK от российских разработчиков, который по перечисленным выше 7 пунктам обгоняет всех конкурентов.
P.S. Еще один интересный факт: IntelliJ также выпускает свою версию JDK - с доработками для отрисовки IDE UI.
#jdk #java
Когда-то давным-давно все, ну или почти все, использовали сборку JDK от Oracle. Хочу рассказать что же изменилось и что можно использовать сейчас.
В 2019 году Oracle изменила лицензионную политику и использовать JDK, а также JRE, бесплатно можно лишь для личных нужд. Версия, которую можно так использовать, получила название OpenJDK. Для коммерческих целей нужно приобретать лицензию, вне зависимости от того, нужна вам поддержка Oracle или нет. Эта версия - Oracle JDK. Кроме лицензионных условий сейчас эти сборки ничем не отличаются. Закон обратной силы не имеет, поэтому все предыдущие сборки можно использовать бесплатно, но любой hotfix JDK после 2019 года попадет под новые условия.
Это была первая проблема. Но кроме нее есть еще одна. Каждая версия OpenJDK от Oracle - это важно, что от Oracle - распространяется только полгода, потом идет переход на новую версию. И патчи выходят только для самой последней версии. Это касается и LTS - версий с долговременной поддержкой. Т.е Oracle OpenJDK 17 патчилась и распространялась полгода, потом стала доступна OpenJDK 18. Для тех, кто всегда готов к обновлениям - гуд) Но это не только лишь все)
Подробнее про это все можно почитать тут https://habr.com/ru/articles/448632/
Что же можно выбрать взамен? Есть довольно много компаний и opensource сообществ, которые берут исходники от Oracle OpenJDK, добавляют туда необходимые патчи, компилируют все это под определенные ОС и процессоры и выпускают для свободного скачивания. Отличаются они по следующим характеристикам:
1) набор версий Java. Как правило у всех есть 3 последние LTS - 8, 11, 17. У большинства есть последняя версия не LTS версия. У некоторых - даже 6-я и 7-я Java! А наличие 6-й Java означает не просто доступность ее для скачивания, но и обратное портирование туда критических патчей.
2) набор поддерживаемых ОС - Linux, Windows, MacOS
3) набор поддерживаемых процессорных архитектур - x64, x86 (32 бита), ARM
4) поддержка из коробки native image https://www.graalvm.org/native-image/
5) поддержка из коробки минималистичного образа Linux - Alpine. Я писал об различиях Docker образов тут https://t.me/javaKotlinDevOps/131
6) формат дистрибутива - инсталлятор, Docker образ. А если говорить про Дinux - поддержка разных менеджеров пакетов - rpm, deb...
7) формат поддержки - как правило он всегда доступен за деньги, но в некоторых случаях - JDK от ИТ гигантов - SAP, Microsoft, Amazon - поддержка доступна только вместе с продуктами этих компаний. Т.е. по сути эти JDK не для всех, а для тех кто использует соответствующее облако или продукт.
Неплохая статья со сравнением - https://bell-sw.com/blog/oracle-java-alternatives-comparison-of-openjdk-distributions
В конце статьи - сравнительная таблица.
Я бы особо выделил Temurin - JDK от Opensource сообщества и Liberica - JDK от российских разработчиков, который по перечисленным выше 7 пунктам обгоняет всех конкурентов.
P.S. Еще один интересный факт: IntelliJ также выпускает свою версию JDK - с доработками для отрисовки IDE UI.
#jdk #java
Хабр
Java теперь платная? Развенчиваем слухи (или нет?)
Уже 2 дня как вступили в силу изменения лицензионной политики Oracle на распространение сборок Java SE . В среде разработчиков-слоупоков (я тоже в их числе) начали носиться кошмарные слухи. Что...
Всем привет!
Я уже писал про паттерны https://t.me/javaKotlinDevOps/52 и их важность. Но есть штука поважнее паттернов - базовые принципы разработки. Чтобы стало понятнее приведу пример - SOLID.
Почему принципы важнее паттернов? Паттерн - это решение частной задачи. Лично я знаю больше паттернов, чем применял на практике) А в разработке я давно. Принципы же применимы практически к любой задачи.
Тот же S из SOLID - Single Responsibility: дорабатываешь какой-то метода - применим, создаешь новый класс - тоже, делишь код по модулям - аналогично, проектируешь набор микросервисов...
Я не люблю повторять то, что уже хорошо описано в интернете, поэтому вот статья с неплохим описанием - https://skillbox.ru/media/code/eto-klassika-eto-znat-nado-dry-kiss-solid-yagni-i-drugie-poleznye-sokrashcheniya/
Оффтопик - не ожидал от skillbox, обычно все ссылки у меня на Хабр или baeldung.
Что бы я добавил к описанным в статье принципам:
1) null safety. Плюсы: не получишь NullPointerException, не нужен код с проверкой на null, не нужно думать - так, на уровень выше я уже на null проверяю, тут вроде не нужно.. но если в будущем этот метод будет вызываться откуда-то еще. Жаль в Java ее достичь сложно, есть куча библиотек с аннотациями @Null\@NotNull, действуют они по разному, на эту тему можно отдельную статью написать. Важно то, что простого решения в Java нет. Зато есть в Kotlin)
2) иммутабельность. Главный плюс - большая устойчивость к ошибкам. Приведу пример: объект - это ссылка на область в памяти. Где еще в сервисе используется объект - часто быстро определить сложно. Вывод - меняя что-то в переданном в метод объекте можно поломать программу в неожиданном месте. Также неожиданным плюсом может быть большая производительность. Самый очевидный пример - иммутабельность строк. Еще - если у вас есть List и нужно убрать из него лишнее - возможно (возможно, надо проводить тесты!) оптимальнее будет создать новый список с нужными объектами, т.к. каждая модификация существующего - это перемещения в heap. Главное чтобы памяти было много и использовался современный сборщик мусора. Еще плюс - если объект иммутабельный, то его можно спокойно использовать в многопоточной программе. Изменения состояния нет, синхронизация доступа не нужна. Ну и бонусом - иммутабельный объект можно использовать как ключ, в том же HashSet\HashMap. В Java для иммутабельности есть records и final, в Kotlin - data class.
3) понятные наименования - я про переменные, методы, классы. Часто вижу две ошибки. Первая - злоупотребление сокращениями. Вторая - ситуативные названия. Т.е. при реализации конкретной фичи название кажется очевидным для автора кода. Но вот приходит новый разработчик. Он знает только о сервисе в целом, никакую старую аналитику он читать не будет, сразу полезет в код - в итоге многие названия покажутся ему непонятными. Общий принцип - называйте так, чтобы назначение кода было понятно новому разработчику. А любые более менее сложные условия выносите в методы с говорящими названиями. За подробностями - снова порекомендую книгу "Чистый код" Мартина.
#arch #patterns #solid
Я уже писал про паттерны https://t.me/javaKotlinDevOps/52 и их важность. Но есть штука поважнее паттернов - базовые принципы разработки. Чтобы стало понятнее приведу пример - SOLID.
Почему принципы важнее паттернов? Паттерн - это решение частной задачи. Лично я знаю больше паттернов, чем применял на практике) А в разработке я давно. Принципы же применимы практически к любой задачи.
Тот же S из SOLID - Single Responsibility: дорабатываешь какой-то метода - применим, создаешь новый класс - тоже, делишь код по модулям - аналогично, проектируешь набор микросервисов...
Я не люблю повторять то, что уже хорошо описано в интернете, поэтому вот статья с неплохим описанием - https://skillbox.ru/media/code/eto-klassika-eto-znat-nado-dry-kiss-solid-yagni-i-drugie-poleznye-sokrashcheniya/
Оффтопик - не ожидал от skillbox, обычно все ссылки у меня на Хабр или baeldung.
Что бы я добавил к описанным в статье принципам:
1) null safety. Плюсы: не получишь NullPointerException, не нужен код с проверкой на null, не нужно думать - так, на уровень выше я уже на null проверяю, тут вроде не нужно.. но если в будущем этот метод будет вызываться откуда-то еще. Жаль в Java ее достичь сложно, есть куча библиотек с аннотациями @Null\@NotNull, действуют они по разному, на эту тему можно отдельную статью написать. Важно то, что простого решения в Java нет. Зато есть в Kotlin)
2) иммутабельность. Главный плюс - большая устойчивость к ошибкам. Приведу пример: объект - это ссылка на область в памяти. Где еще в сервисе используется объект - часто быстро определить сложно. Вывод - меняя что-то в переданном в метод объекте можно поломать программу в неожиданном месте. Также неожиданным плюсом может быть большая производительность. Самый очевидный пример - иммутабельность строк. Еще - если у вас есть List и нужно убрать из него лишнее - возможно (возможно, надо проводить тесты!) оптимальнее будет создать новый список с нужными объектами, т.к. каждая модификация существующего - это перемещения в heap. Главное чтобы памяти было много и использовался современный сборщик мусора. Еще плюс - если объект иммутабельный, то его можно спокойно использовать в многопоточной программе. Изменения состояния нет, синхронизация доступа не нужна. Ну и бонусом - иммутабельный объект можно использовать как ключ, в том же HashSet\HashMap. В Java для иммутабельности есть records и final, в Kotlin - data class.
3) понятные наименования - я про переменные, методы, классы. Часто вижу две ошибки. Первая - злоупотребление сокращениями. Вторая - ситуативные названия. Т.е. при реализации конкретной фичи название кажется очевидным для автора кода. Но вот приходит новый разработчик. Он знает только о сервисе в целом, никакую старую аналитику он читать не будет, сразу полезет в код - в итоге многие названия покажутся ему непонятными. Общий принцип - называйте так, чтобы назначение кода было понятно новому разработчику. А любые более менее сложные условия выносите в методы с говорящими названиями. За подробностями - снова порекомендую книгу "Чистый код" Мартина.
#arch #patterns #solid
Telegram
(java || kotlin) && devOps
Всем привет!
Давно хотел написать про паттерны/шаблоны программирования. Основной вопрос, возникающий при разговоре про паттерны - какая от них польза? Ведь главное - умеет человек кодить или нет.
С одной стороны паттерны - это лишь часть арсенала программиста.…
Давно хотел написать про паттерны/шаблоны программирования. Основной вопрос, возникающий при разговоре про паттерны - какая от них польза? Ведь главное - умеет человек кодить или нет.
С одной стороны паттерны - это лишь часть арсенала программиста.…
Всем привет!
Сегодня пост про очередной типичный вопрос на собеседовании.
Звучит он так: расскажите про жизненный цикл сборки Maven, он же build lifecycle.
Я вкратце уже писал про это https://t.me/javaKotlinDevOps/10. Но т.к. типичный ответ на собеседовании - перечисление циклов и фаз сборки, то хочется раскрыть тему. На самом деле вопрос про другое - в чем суть цикла сборки?
1) набор фаз сборки JVM проекта уже придуман и зафиксирован умными людьми) из команды Maven в виде Default Lifecycle https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference Т.е. считается, что список покрывает все потребности сборки. Как пример продуманности могу привести фазы pre-integration-test и post-integration-test, которые нужны для того, чтобы поднять и опустить контейнер сервлетов, менеджер очередей или БД до и после фазы интеграционных тестов (integration-test). Для обычных тестов (test) таких вспомогательных фаз нет.
2) последовательность фаз также зафиксирована, порядок менять нельзя да и нет смысла
3) большинство фаз являются опциональными, запускаются только если к фазе подключен хоть один плагин и либо в проекте присутствуют определенные файлы, либо есть настройки плагина, указывающие что ему делать - например, generate-sources или компиляция Kotlin
4) на одной фазе могут работать несколько целей (goal) из разных плагинов - например, компиляция Java и Kotlin на фазе compile или несколько тестовых фреймворков на фазе test
5) запуская определенный шаг сборки - mvn install - вы запускаете все предыдущие шаги цикла. И в большинстве случаев это правильно. Если такое поведение не требуется - нужно запустить конкретную цель у конкретного плагина, для моего примера это mvn install:install (плагин:цель). Т.е. тут совпадают название фазы сборки, плагина и цели. Так бывает не всегда, например, для фазы test-compile цель выглядит так compiler:testCompile
Итого: цель жизненного цикла сборки - стандартизировать процесс сборки.
Да и в принципе стандартизация - конек Maven. Тут и типовой набор папок https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html, и цикл сборки, и сложность написания своего кода для сборки, и достаточно богатый набор стандартных плагинов, для подключения которых ничего не надо делать (если быть точным - неплохо бы зафиксировать версию в pom), и архетипы, и конвенция по наименованию артефактов, и наконец центральный репозиторий - https://mvnrepository.com/repos/central
#maven #interview_question
Сегодня пост про очередной типичный вопрос на собеседовании.
Звучит он так: расскажите про жизненный цикл сборки Maven, он же build lifecycle.
Я вкратце уже писал про это https://t.me/javaKotlinDevOps/10. Но т.к. типичный ответ на собеседовании - перечисление циклов и фаз сборки, то хочется раскрыть тему. На самом деле вопрос про другое - в чем суть цикла сборки?
1) набор фаз сборки JVM проекта уже придуман и зафиксирован умными людьми) из команды Maven в виде Default Lifecycle https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference Т.е. считается, что список покрывает все потребности сборки. Как пример продуманности могу привести фазы pre-integration-test и post-integration-test, которые нужны для того, чтобы поднять и опустить контейнер сервлетов, менеджер очередей или БД до и после фазы интеграционных тестов (integration-test). Для обычных тестов (test) таких вспомогательных фаз нет.
2) последовательность фаз также зафиксирована, порядок менять нельзя да и нет смысла
3) большинство фаз являются опциональными, запускаются только если к фазе подключен хоть один плагин и либо в проекте присутствуют определенные файлы, либо есть настройки плагина, указывающие что ему делать - например, generate-sources или компиляция Kotlin
4) на одной фазе могут работать несколько целей (goal) из разных плагинов - например, компиляция Java и Kotlin на фазе compile или несколько тестовых фреймворков на фазе test
5) запуская определенный шаг сборки - mvn install - вы запускаете все предыдущие шаги цикла. И в большинстве случаев это правильно. Если такое поведение не требуется - нужно запустить конкретную цель у конкретного плагина, для моего примера это mvn install:install (плагин:цель). Т.е. тут совпадают название фазы сборки, плагина и цели. Так бывает не всегда, например, для фазы test-compile цель выглядит так compiler:testCompile
Итого: цель жизненного цикла сборки - стандартизировать процесс сборки.
Да и в принципе стандартизация - конек Maven. Тут и типовой набор папок https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html, и цикл сборки, и сложность написания своего кода для сборки, и достаточно богатый набор стандартных плагинов, для подключения которых ничего не надо делать (если быть точным - неплохо бы зафиксировать версию в pom), и архетипы, и конвенция по наименованию артефактов, и наконец центральный репозиторий - https://mvnrepository.com/repos/central
#maven #interview_question
Telegram
(java || kotlin) && devOps
Всем привет!
Хочу рассказать собрать в одном посте несколько мало и среднеизвестных фичей Maven.
Поехали!
Для начала немного теории. Жизненный цикл сборки = фиксированная последовательность фаз сборки. К фазе сборки можно подключить плагин(ы), а точнее…
Хочу рассказать собрать в одном посте несколько мало и среднеизвестных фичей Maven.
Поехали!
Для начала немного теории. Жизненный цикл сборки = фиксированная последовательность фаз сборки. К фазе сборки можно подключить плагин(ы), а точнее…
Всем привет!
Сегодня пост с картинками, поэтому ловите https://telegra.ph/Urovni-izolyacii-sovremennogo-Java-prilozheniya-07-29
#java #jvm #docker #performance
Сегодня пост с картинками, поэтому ловите https://telegra.ph/Urovni-izolyacii-sovremennogo-Java-prilozheniya-07-29
#java #jvm #docker #performance
Telegraph
Уровни изоляции современного Java приложения
Всем привет! Уже писал про плюсы Docker - https://t.me/javaKotlinDevOps/165 Но все ли так безоблачно?) Обычно, когда сравнивают Docker с виртуальной машиной (VM) приводят такую схему Из нее видно, что Docker - более легковесное решение по сравнению с VM.…