"Компьютер без надежности — это просто груда металла."
Башир Рамеев, разработчик ЭВМ "Урал", сказал это в 1955 году на конференции в Казани, акцентируя важность стабильности систем.
Биография
#Citation #Biography
Please open Telegram to view this post
VIEW IN TELEGRAM
Wikipedia
Рамеев, Башир Искандарович
Баши́р Исканда́рович Раме́ев (тат. Bəşir İskəndər uğlı Rəmiev, Бәшир Искәндәр улы Рәмиев; 1 мая 1918, Баймак, Оренбургская губерния — 16 мая 1994, Москва) — советский учёный-изобретатель, разработчик первых советских ЭВМ (Стрела, Урал-1). Доктор технических…
👍1
Операторы в Java
1. Что такое операторы в Java?
Операторы — это конструкции языка Java, которые выполняют определенные действия с одним или несколькими операндами (значениями или переменными). Они позволяют выполнять вычисления, сравнения, управление потоком программы и манипуляции с битами. Операторы делятся на категории в зависимости от их назначения, такие как арифметические, логические, сравнения и т.д.
Зачем нужны операторы?
Обработка данных: Операторы позволяют выполнять вычисления и преобразования данных.
Управление логикой: Логические и условные операторы управляют потоком выполнения программы.
Читаемость кода: Операторы упрощают запись сложных операций в компактной форме.
Оптимизация: JVM оптимизирует выполнение операций на уровне байт-кода, обеспечивая высокую производительность.
2. Синтаксис операторов
Операторы в Java представляют собой символы (например, +, ==, &&) или ключевые слова (например, instanceof). Они применяются к операндам, которые могут быть переменными, литералами или выражениями. Синтаксис зависит от типа оператора.
Общий синтаксис:
или
Пример:
Классификация операторов:
Арифметические
Логические
Операторы сравнения
Тернарный
Битовые
Операторы присваивания
Условные (управляющие)
Операторы экземпляра (instanceof)
3. Типы операторов
3.1. Арифметические операторы
Используются для выполнения математических операций над числовыми типами (int, double, float, и т.д.).
Пример:
3.2. Логические операторы
Используются для работы с булевыми значениями (true, false).
Пример:
3.3. Операторы сравнения
Сравнивают два операнда и возвращают boolean.
Пример:
3.4. Тернарный оператор
Условный оператор, который заменяет простую конструкцию if-else.
Синтаксис:
Пример:
#Java #для_новичков #beginner #java_syntax #Operators
1. Что такое операторы в Java?
Операторы — это конструкции языка Java, которые выполняют определенные действия с одним или несколькими операндами (значениями или переменными). Они позволяют выполнять вычисления, сравнения, управление потоком программы и манипуляции с битами. Операторы делятся на категории в зависимости от их назначения, такие как арифметические, логические, сравнения и т.д.
Зачем нужны операторы?
Обработка данных: Операторы позволяют выполнять вычисления и преобразования данных.
Управление логикой: Логические и условные операторы управляют потоком выполнения программы.
Читаемость кода: Операторы упрощают запись сложных операций в компактной форме.
Оптимизация: JVM оптимизирует выполнение операций на уровне байт-кода, обеспечивая высокую производительность.
2. Синтаксис операторов
Операторы в Java представляют собой символы (например, +, ==, &&) или ключевые слова (например, instanceof). Они применяются к операндам, которые могут быть переменными, литералами или выражениями. Синтаксис зависит от типа оператора.
Общий синтаксис:
операнд1 оператор операнд2
или
оператор операнд
Пример:
int sum = 5 + 3; // Арифметический оператор +
boolean isEqual = (a == b); // Оператор сравнения ==
Классификация операторов:
Арифметические
Логические
Операторы сравнения
Тернарный
Битовые
Операторы присваивания
Условные (управляющие)
Операторы экземпляра (instanceof)
3. Типы операторов
3.1. Арифметические операторы
Используются для выполнения математических операций над числовыми типами (int, double, float, и т.д.).
+: Сложение (или конкатенация строк).
-: Вычитание.
*: Умножение.
/: Деление (целочисленное для int, с плавающей точкой для double).
%: Остаток от деления.
++: Инкремент (увеличивает значение на 1).
--: Декремент (уменьшает значение на 1).
Пример:
int a = 10, b = 3;
int sum = a + b; // 13
int difference = a - b; // 7
int product = a * b; // 30
int quotient = a / b; // 3 (целочисленное деление)
int remainder = a % b; // 1
a++; // a = 11
b--; // b = 2
3.2. Логические операторы
Используются для работы с булевыми значениями (true, false).
&&: Логическое И (короткого замыкания, вычисляет второй операнд только если первый true).
||: Логическое ИЛИ (короткого замыкания, вычисляет второй операнд только если первый false).
!: Логическое НЕ (инвертирует значение).
Пример:
boolean x = true, y = false;
boolean andResult = x && y; // false
boolean orResult = x || y; // true
boolean notResult = !x; // false
3.3. Операторы сравнения
Сравнивают два операнда и возвращают boolean.
==: Равенство (для примитивов — сравнение значений, для объектов — сравнение ссылок).
!=: Неравенство.
>: Больше.
<: Меньше.
>=: Больше или равно.
<=: Меньше или равно.
Пример:
int a = 5, b = 3;
boolean isEqual = (a == b); // false
boolean isGreater = (a > b); // true
boolean isNotEqual = (a != b); // true
3.4. Тернарный оператор
Условный оператор, который заменяет простую конструкцию if-else.
Синтаксис:
условие ? выражение1 : выражение2
Возвращает выражение1, если условие true, или выражение2, если false.
Пример:
int a = 10, b = 5;
int max = (a > b) ? a : b; // max = 10
#Java #для_новичков #beginner #java_syntax #Operators
👍1
3.5. Битовые операторы
Выполняют операции на уровне битов для целочисленных типов (int, long).
Пример:
3.6. Операторы присваивания
Присваивают значение переменной.
Пример:
3.7. Условные операторы
Управляют потоком выполнения программы.
Пример:
4. Правильное применение операторов
Правильное использование операторов улучшает читаемость, производительность и безопасность кода.
Вот рекомендации по их применению:
4.1. Арифметические операторы
Избегайте деления на ноль: Деление на ноль для целочисленных типов вызывает ArithmeticException, для типов с плавающей точкой возвращает Infinity или NaN.
Используйте явное приведение типов: При работе с разными типами (например, int и double) приводите типы явно, чтобы избежать потери точности.
Остаток от деления: Используйте % для проверки четности или циклических операций.
Пример:
4.2. Логические операторы
Используйте короткое замыкание: Операторы && и || вычисляют второй операнд только при необходимости, что повышает производительность.
Читаемость: Разбивайте сложные логические выражения на промежуточные переменные для улучшения читаемости.
Пример:
4.3. Операторы сравнения
Сравнение объектов: Используйте equals вместо == для сравнения содержимого объектов (например, String).
Проверка на null: Всегда проверяйте объекты на null перед сравнением.
Пример:
4.4. Тернарный оператор
Используйте для простых условий: Тернарный оператор улучшает читаемость для коротких условий, но избегайте вложенных тернарных выражений.
Читаемость: Не заменяйте сложные if-else конструкции тернарным оператором.
Пример:
4.5. Битовые операторы
Оптимизация: Используйте битовые операторы для низкоуровневых операций, таких как работа с флагами или оптимизация вычислений.
Читаемость: Документируйте битовые операции, так как они менее интуитивны.
Пример:
4.6. Операторы присваивания
Составные операторы: Используйте +=, *= и т.д. для сокращения кода и повышения читаемости.
Осторожно с приведениями: Составные операторы автоматически приводят результат к типу переменной.
Пример:
4.7. Условные операторы
Проверка типов: Используйте instanceof для безопасной работы с полиморфизмом и приведениями типов.
Пример:
#Java #для_новичков #beginner #java_syntax #Operators
Выполняют операции на уровне битов для целочисленных типов (int, long).
&: Побитовое И.
|: Побитовое ИЛИ.
^: Побитовое исключающее ИЛИ (XOR).
~: Побитовое НЕ (инверсия).
<<: Сдвиг влево.
>>: Сдвиг вправо (с сохранением знака).
>>>: Сдвиг вправо с заполнением нулями.
Пример:
int a = 5; // 0101 в двоичной системе
int b = 3; // 0011 в двоичной системе
int and = a & b; // 0001 (1)
int or = a | b; // 0111 (7)
int xor = a ^ b; // 0110 (6)
int not = ~a; // 1010 (инверсия, результат -6)
int leftShift = a << 1; // 1010 (10)
int rightShift = a >> 1; // 0010 (2)
3.6. Операторы присваивания
Присваивают значение переменной.
=: Простое присваивание.
+=, -=, *=, /=, %=: Составное присваивание (выполняют операцию и присваивают результат).
&=, |=, ^=, <<=, >>=, >>>=: Битовые составные присваивания.
Пример:
int a = 10;
a += 5; // a = 15
a *= 2; // a = 30
a &= 7; // a = 6 (битовое И)
3.7. Условные операторы
Управляют потоком выполнения программы.
instanceof: Проверяет, является ли объект экземпляром определенного класса или интерфейса.
Пример:
String str = "Hello";
boolean isString = str instanceof String; // true
4. Правильное применение операторов
Правильное использование операторов улучшает читаемость, производительность и безопасность кода.
Вот рекомендации по их применению:
4.1. Арифметические операторы
Избегайте деления на ноль: Деление на ноль для целочисленных типов вызывает ArithmeticException, для типов с плавающей точкой возвращает Infinity или NaN.
Используйте явное приведение типов: При работе с разными типами (например, int и double) приводите типы явно, чтобы избежать потери точности.
Остаток от деления: Используйте % для проверки четности или циклических операций.
Пример:
double result = (double) 5 / 2; // 2.5
int evenCheck = number % 2; // 0 для четных чисел
4.2. Логические операторы
Используйте короткое замыкание: Операторы && и || вычисляют второй операнд только при необходимости, что повышает производительность.
Читаемость: Разбивайте сложные логические выражения на промежуточные переменные для улучшения читаемости.
Пример:
if (user != null && user.isActive()) {
// Безопасный доступ благодаря короткому замыканию
}
4.3. Операторы сравнения
Сравнение объектов: Используйте equals вместо == для сравнения содержимого объектов (например, String).
Проверка на null: Всегда проверяйте объекты на null перед сравнением.
Пример:
String str1 = "Hello";
String str2 = "Hello";
boolean equal = str1.equals(str2); // true
4.4. Тернарный оператор
Используйте для простых условий: Тернарный оператор улучшает читаемость для коротких условий, но избегайте вложенных тернарных выражений.
Читаемость: Не заменяйте сложные if-else конструкции тернарным оператором.
Пример:
String status = (age >= 18) ? "Взрослый" : "Ребенок";
4.5. Битовые операторы
Оптимизация: Используйте битовые операторы для низкоуровневых операций, таких как работа с флагами или оптимизация вычислений.
Читаемость: Документируйте битовые операции, так как они менее интуитивны.
Пример:
int flags = 0b0001; // Флаг 1 включен
flags |= 0b0010; // Включить флаг 2
4.6. Операторы присваивания
Составные операторы: Используйте +=, *= и т.д. для сокращения кода и повышения читаемости.
Осторожно с приведениями: Составные операторы автоматически приводят результат к типу переменной.
Пример:
double x = 10.5;
x *= 2; // x = 21.0
4.7. Условные операторы
Проверка типов: Используйте instanceof для безопасной работы с полиморфизмом и приведениями типов.
Пример:
if (obj instanceof List) {
List<?> list = (List<?>) obj;
}
#Java #для_новичков #beginner #java_syntax #Operators
👍1
5. Назначение операторов
Операторы выполняют несколько ключевых функций:
5.1. Выполнение вычислений
Арифметические и битовые операторы позволяют выполнять математические и низкоуровневые операции.
5.2. Управление логикой программы
Логические и условные операторы определяют поток выполнения программы, делая код гибким.
5.3. Оптимизация кода
Тернарный оператор и составные присваивания сокращают объем кода, сохраняя функциональность.
5.4. Безопасность типов
Оператор instanceof обеспечивает безопасную проверку типов, предотвращая ошибки приведения.
5.5. Интеграция с JVM
Операторы оптимизированы на уровне байт-кода, что обеспечивает высокую производительность.
6. Операторы и работа под капотом
6.1. Обработка в байт-коде
Каждый оператор преобразуется в одну или несколько инструкций байт-кода при компиляции.
Например:
+ для int преобразуется в инструкцию iadd.
&& разбивается на условные переходы (if_icmp).
JVM оптимизирует эти инструкции через JIT-компиляцию, встраивая их в машинный код.
Пример:
Байт-код:
6.2. Память и стек
Стек операндов: Большинство операторов работают с операндами, находящимися в стеке операндов JVM. Например, для a + b JVM загружает a и b в стек, выполняет iadd и возвращает результат в стек.
Локальные переменные: Результаты операций часто сохраняются в локальных переменных, которые хранятся в стеке вызовов.
Куча: Для операций с объектами (например, конкатенация строк через +) результат создается в куче.
Пример конкатенации строк:
6.3. Оптимизация операторов
Короткое замыкание: Операторы && и || используют условные переходы в байт-коде, пропуская вычисление второго операнда, если результат уже определен.
Инлайн-оптимизация: JIT-компилятор может встраивать простые операции (например, a + b) напрямую в машинный код.
Оптимизация конкатенации строк: Современные JVM заменяют + для строк на использование StringBuilder или StringConcatFactory (с Java 9).
6.4. Ошибки в памяти
Переполнение стека: Сложные выражения с большим количеством операторов могут увеличить глубину стека операндов, но это редко вызывает проблемы благодаря оптимизациям JVM.
Утечки памяти: Конкатенация строк в цикле через + создает множество временных объектов StringBuilder и String, что может привести к чрезмерному потреблению памяти в куче.
Пример:
6.5. Битовые операторы и производительность
Битовые операторы (&, |, <<) выполняются на уровне процессора, что делает их быстрее арифметических операций в некоторых случаях.
Например, x << 1 быстрее, чем x * 2, так как сдвиг битов требует меньше процессорных циклов.
7. Лучшие практики
Читаемость: Разбивайте сложные выражения на промежуточные переменные для улучшения понимания.
Избегайте побочных эффектов: Не используйте ++ или -- внутри сложных выражений, чтобы избежать непредсказуемого поведения.
Проверяйте на null: Перед операциями с объектами проверяйте их на null, чтобы избежать NullPointerException.
Используйте тернарный оператор с умом: Применяйте его только для простых условий, чтобы не усложнять код.
Оптимизируйте конкатенацию строк: Используйте StringBuilder для конкатенации в циклах.
Документируйте битовые операции: Добавляйте комментарии, объясняющие назначение битовых операций.
#Java #для_новичков #beginner #java_syntax #Operators
Операторы выполняют несколько ключевых функций:
5.1. Выполнение вычислений
Арифметические и битовые операторы позволяют выполнять математические и низкоуровневые операции.
5.2. Управление логикой программы
Логические и условные операторы определяют поток выполнения программы, делая код гибким.
5.3. Оптимизация кода
Тернарный оператор и составные присваивания сокращают объем кода, сохраняя функциональность.
5.4. Безопасность типов
Оператор instanceof обеспечивает безопасную проверку типов, предотвращая ошибки приведения.
5.5. Интеграция с JVM
Операторы оптимизированы на уровне байт-кода, что обеспечивает высокую производительность.
6. Операторы и работа под капотом
6.1. Обработка в байт-коде
Каждый оператор преобразуется в одну или несколько инструкций байт-кода при компиляции.
Например:
+ для int преобразуется в инструкцию iadd.
&& разбивается на условные переходы (if_icmp).
JVM оптимизирует эти инструкции через JIT-компиляцию, встраивая их в машинный код.
Пример:
int a = 5 + 3;
Байт-код:
iconst_5
iconst_3
iadd
istore a
6.2. Память и стек
Стек операндов: Большинство операторов работают с операндами, находящимися в стеке операндов JVM. Например, для a + b JVM загружает a и b в стек, выполняет iadd и возвращает результат в стек.
Локальные переменные: Результаты операций часто сохраняются в локальных переменных, которые хранятся в стеке вызовов.
Куча: Для операций с объектами (например, конкатенация строк через +) результат создается в куче.
Пример конкатенации строк:
String result = "Hello" + "World";
JVM создает объект StringBuilder, выполняет конкатенацию и вызывает toString, создавая новый объект String в куче.
6.3. Оптимизация операторов
Короткое замыкание: Операторы && и || используют условные переходы в байт-коде, пропуская вычисление второго операнда, если результат уже определен.
Инлайн-оптимизация: JIT-компилятор может встраивать простые операции (например, a + b) напрямую в машинный код.
Оптимизация конкатенации строк: Современные JVM заменяют + для строк на использование StringBuilder или StringConcatFactory (с Java 9).
6.4. Ошибки в памяти
Переполнение стека: Сложные выражения с большим количеством операторов могут увеличить глубину стека операндов, но это редко вызывает проблемы благодаря оптимизациям JVM.
Утечки памяти: Конкатенация строк в цикле через + создает множество временных объектов StringBuilder и String, что может привести к чрезмерному потреблению памяти в куче.
Пример:
String result = "";
for (int i = 0; i < 1000; i++) {
result += i; // Неэффективно, создает много объектов
}
Лучший вариант:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append(i);
}
String result = sb.toString();
6.5. Битовые операторы и производительность
Битовые операторы (&, |, <<) выполняются на уровне процессора, что делает их быстрее арифметических операций в некоторых случаях.
Например, x << 1 быстрее, чем x * 2, так как сдвиг битов требует меньше процессорных циклов.
7. Лучшие практики
Читаемость: Разбивайте сложные выражения на промежуточные переменные для улучшения понимания.
int result = (a * b + c) / d; // Лучше разбить на части
int temp = a * b;
int result = (temp + c) / d;
Избегайте побочных эффектов: Не используйте ++ или -- внутри сложных выражений, чтобы избежать непредсказуемого поведения.
Проверяйте на null: Перед операциями с объектами проверяйте их на null, чтобы избежать NullPointerException.
Используйте тернарный оператор с умом: Применяйте его только для простых условий, чтобы не усложнять код.
Оптимизируйте конкатенацию строк: Используйте StringBuilder для конкатенации в циклах.
Документируйте битовые операции: Добавляйте комментарии, объясняющие назначение битовых операций.
#Java #для_новичков #beginner #java_syntax #Operators
👍2
Что выведет код?
#Tasks
public class Task100725 {
public static void main(String[] args) {
int x = 1;
int y = x++ + x++ + ++x;
System.out.println("x = " + x);
System.out.println("y = " + y);
}
}
#Tasks
🔥1
Что такое suppressed exceptions в Java? 🤓
Ответ:
Suppressed exceptions — это исключения, которые возникают при закрытии ресурсов в try-with-resources, но подавляются основным исключением.
Они доступны через getSuppressed().
Пример:
try (Resource r = new Resource()) {
throw new RuntimeException("Main exception");
} catch (Exception e) {
System.out.println(e.getSuppressed().length); // Подавленные исключения
}
Полезно для отладки проблем с закрытием ресурсов.
#собеседование
Ответ:
Они доступны через getSuppressed().
Пример:
try (Resource r = new Resource()) {
throw new RuntimeException("Main exception");
} catch (Exception e) {
System.out.println(e.getSuppressed().length); // Подавленные исключения
}
Полезно для отладки проблем с закрытием ресурсов.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
А вы знали, что термин "фишинг" родился в 1996 году?
Техника фишинга была подробно описана в 1987 году, а сам термин появился 2 января 1996 года в новостной группе alt.online-service.America-Online сети Usenet, исказив слово "fishing" (рыбалка). Термин описывал атаки, заманивающие пользователей на поддельные сайты.
Proof
#facts
Please open Telegram to view this post
VIEW IN TELEGRAM
"Математика и вычисления — два столпа прогресса."
Михаил Лаврентьев, основатель Сибирского отделения АН СССР, сказал это в 1960 году на открытии вычислительного центра в Новосибирске.
Биография
#Citation #Biography
Please open Telegram to view this post
VIEW IN TELEGRAM
Wikipedia
Лаврентьев, Михаил Алексеевич
Михаи́л Алексе́евич Лавре́нтьев (6 [19] ноября 1900, Казань, Российская империя — 15 октября 1980, Москва, СССР) — советский математик и механик, основатель Сибирского отделения АН СССР (СО АН СССР) и Новосибирского Академгородка, академик АН УССР (1939)…
Расширенные темы и интеграции Maven
CI/CD интеграция
Maven широко используется в CI/CD-пайплайнах для автоматизации сборки, тестирования и развертывания. Рассмотрим интеграцию с популярными системами и связанные процессы, такие как GPG-подпись и развертывание артефактов.
Jenkins, GitLab CI, GitHub Actions с Maven
Jenkins:
Конфигурация: Создайте задачу (Job) типа "Freestyle" или "Pipeline". В Freestyle добавьте шаг "Invoke top-level Maven targets":mvn clean install
В Pipeline используйте Jenkinsfile:
Параллельность: Используйте флаг -T для параллельной сборки модулей, например, -T 4.
Плагины: Используйте maven-release-plugin для автоматизации релизов:mvn release:prepare release:perform
GitLab CI:
Конфигурация: Определите .gitlab-ci.yml:
Кэширование: Кэшируйте ~/.m2/repository для ускорения:
GitHub Actions:
Конфигурация: Создайте .github/workflows/maven.yml:name:
Артефакты: Используйте действие actions/upload-artifact для сохранения JAR/WAR.
В памяти: CI/CD-системы запускают Maven как Java-процесс, загружая POM-модель, зависимости и плагины в оперативную память. Параллельная сборка (-T) увеличивает пиковое потребление памяти, так как одновременно обрабатываются несколько модулей. Кэширование ~/.m2/repository снижает сетевые запросы, но требует места на диске.
Работа с GPG Signing, Artifact Deployment
GPG Signing:GPG-подпись артефактов необходима для публикации в Maven Central. Используется maven-gpg-plugin.
Настройка в POM.xml:
Шаги:
Установите GPG и создайте ключ: gpg --gen-key.
Опубликуйте публичный ключ: gpg --keyserver keyserver.ubuntu.com --send-keys <key-id>.
Настройте ~/.m2/settings.xml с GPG-паролем:
Подпишите артефакты:
В памяти: Плагин maven-gpg-plugin загружает GPG-ключи и артефакты в память для подписи, что увеличивает потребление ресурсов, особенно для крупных JAR/WAR.
Artifact Deployment:Развертывание артефактов в репозиторий (например, Nexus, Maven Central) выполняется через maven-deploy-plugin:
Запуск: mvn deploy.
SNAPSHOT vs Release: SNAPSHOT-версии (1.0.0-SNAPSHOT) обновляются в репозитории, релизные версии (1.0.0) публикуются однократно.
В памяти: Плагин maven-deploy-plugin загружает артефакт и его метаданные в память перед отправкой в репозиторий. Сетевые операции могут замедлить процесс, но потребление памяти минимально.
#Java #middle #Maven #Best_practics
CI/CD интеграция
Maven широко используется в CI/CD-пайплайнах для автоматизации сборки, тестирования и развертывания. Рассмотрим интеграцию с популярными системами и связанные процессы, такие как GPG-подпись и развертывание артефактов.
Jenkins, GitLab CI, GitHub Actions с Maven
Jenkins:
Конфигурация: Создайте задачу (Job) типа "Freestyle" или "Pipeline". В Freestyle добавьте шаг "Invoke top-level Maven targets":mvn clean install
В Pipeline используйте Jenkinsfile:
pipeline {
agent any
tools {
maven 'Maven 3.8.6'
jdk 'JDK11'
}
stages {
stage('Build') {
steps {
sh 'mvn clean install'
}
}
}
}
Параллельность: Используйте флаг -T для параллельной сборки модулей, например, -T 4.
Плагины: Используйте maven-release-plugin для автоматизации релизов:mvn release:prepare release:perform
GitLab CI:
Конфигурация: Определите .gitlab-ci.yml:
stages:
- build
build:
stage: build
image: maven:3.8.6-openjdk-11
script:
- mvn clean install
artifacts:
paths:
- target/*.jar
Кэширование: Кэшируйте ~/.m2/repository для ускорения:
cache:
paths:
- ~/.m2/repository
GitHub Actions:
Конфигурация: Создайте .github/workflows/maven.yml:name:
Maven Build
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
- name: Build with Maven
run: mvn clean install
- name: Cache Maven dependencies
uses: actions/cache@v3
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
Артефакты: Используйте действие actions/upload-artifact для сохранения JAR/WAR.
В памяти: CI/CD-системы запускают Maven как Java-процесс, загружая POM-модель, зависимости и плагины в оперативную память. Параллельная сборка (-T) увеличивает пиковое потребление памяти, так как одновременно обрабатываются несколько модулей. Кэширование ~/.m2/repository снижает сетевые запросы, но требует места на диске.
Работа с GPG Signing, Artifact Deployment
GPG Signing:GPG-подпись артефактов необходима для публикации в Maven Central. Используется maven-gpg-plugin.
Настройка в POM.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
Шаги:
Установите GPG и создайте ключ: gpg --gen-key.
Опубликуйте публичный ключ: gpg --keyserver keyserver.ubuntu.com --send-keys <key-id>.
Настройте ~/.m2/settings.xml с GPG-паролем:
<server>
<id>gpg.passphrase</id>
<passphrase>{encrypted-passphrase}</passphrase>
</server>
Подпишите артефакты:
mvn clean deploy -Dgpg.passphrase=<passphrase>.
В памяти: Плагин maven-gpg-plugin загружает GPG-ключи и артефакты в память для подписи, что увеличивает потребление ресурсов, особенно для крупных JAR/WAR.
Artifact Deployment:Развертывание артефактов в репозиторий (например, Nexus, Maven Central) выполняется через maven-deploy-plugin:
<distributionManagement>
<repository>
<id>nexus</id>
<url>https://nexus.example.com/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus</id>
<url>https://nexus.example.com/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
Запуск: mvn deploy.
SNAPSHOT vs Release: SNAPSHOT-версии (1.0.0-SNAPSHOT) обновляются в репозитории, релизные версии (1.0.0) публикуются однократно.
В памяти: Плагин maven-deploy-plugin загружает артефакт и его метаданные в память перед отправкой в репозиторий. Сетевые операции могут замедлить процесс, но потребление памяти минимально.
#Java #middle #Maven #Best_practics
Archetypes
Архетипы — это шаблоны проектов, которые позволяют быстро создавать структуру с предопределенными файлами, зависимостями и конфигурацией. Maven предоставляет встроенные архетипы, такие как maven-archetype-quickstart.
Использование:
Создание собственного архетипа
Создайте проект с желаемой структурой:
В archetype-metadata.xml опишите структуру:
Сгенерируйте архетип:
Установите архетип:
Используйте архетип:
В памяти: Архетипы загружают шаблонные файлы и их метаданные в память. Плагин maven-archetype-plugin парсит archetype-metadata.xml и заменяет переменные (например, ${groupId}), что требует минимальных ресурсов, но может быть затратным для сложных архетипов с большим количеством файлов.
Использование Maven Wrapper (mvnw)
Maven Wrapper (mvnw) — это скрипт, который обеспечивает использование конкретной версии Maven, независимо от установленной на машине. Он включает файлы mvnw (или mvnw.cmd для Windows), .mvn/wrapper/maven-wrapper.jar и .mvn/wrapper/maven-wrapper.properties.
Установка:
Использование:
В памяти: mvnw запускает Maven как отдельный Java-процесс, загружая maven-wrapper.jar в память. Это добавляет небольшой overhead, но гарантирует согласованность сборки. Кэширование Maven в .m2/repository минимизирует сетевые запросы.
Нюансы:
Храните mvnw и .mvn в репозитории для обеспечения воспроизводимости.
Обновляйте версию Maven в maven-wrapper.properties для поддержки новых функций.
Поддержка Java версий
Maven поддерживает проекты с разными версиями Java через maven-compiler-plugin:
Многомодульные проекты
Каждый модуль может использовать разные версии Java, указав собственную конфигурацию плагина.
Toolchains: Для кросс-компиляции используйте ~/.m2/toolchains.xml:
Укажите toolchain в POM.xml:
#Java #middle #Maven #Best_practics
Архетипы — это шаблоны проектов, которые позволяют быстро создавать структуру с предопределенными файлами, зависимостями и конфигурацией. Maven предоставляет встроенные архетипы, такие как maven-archetype-quickstart.
Использование:
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4
Пользователь вводит groupId, artifactId, version, и Maven генерирует проект.
Создание собственного архетипа
Создайте проект с желаемой структурой:
my-archetype/
├── src/
│ └── main/
│ └── resources/
│ ├── archetype-resources/
│ │ ├── src/main/java/App.java
│ │ └── pom.xml
│ └── META-INF/maven/
│ └── archetype-metadata.xml
└── pom.xml
В archetype-metadata.xml опишите структуру:
<archetype-descriptor>
<fileSets>
<fileSet filtered="true" packaged="true">
<directory>src/main/java</directory>
<includes>
<include>**/*.java</include>
</includes>
</fileSet>
</fileSets>
</archetype-descriptor>
Сгенерируйте архетип:
mvn archetype:create-from-project
Результат появится в target/generated-sources/archetype.
Установите архетип:
cd target/generated-sources/archetype
mvn install
Используйте архетип:
mvn archetype:generate -DarchetypeGroupId=com.example -DarchetypeArtifactId=my-archetype -DarchetypeVersion=1.0
В памяти: Архетипы загружают шаблонные файлы и их метаданные в память. Плагин maven-archetype-plugin парсит archetype-metadata.xml и заменяет переменные (например, ${groupId}), что требует минимальных ресурсов, но может быть затратным для сложных архетипов с большим количеством файлов.
Использование Maven Wrapper (mvnw)
Maven Wrapper (mvnw) — это скрипт, который обеспечивает использование конкретной версии Maven, независимо от установленной на машине. Он включает файлы mvnw (или mvnw.cmd для Windows), .mvn/wrapper/maven-wrapper.jar и .mvn/wrapper/maven-wrapper.properties.
Установка:
mvn -N wrapper:wrapper -Dmaven=3.8.6
Создает mvnw, который загружает указанную версию Maven.
Использование:
./mvnw clean install
Скрипт проверяет .mvn/wrapper/maven-wrapper.properties, загружает нужную версию Maven и выполняет команду.
В памяти: mvnw запускает Maven как отдельный Java-процесс, загружая maven-wrapper.jar в память. Это добавляет небольшой overhead, но гарантирует согласованность сборки. Кэширование Maven в .m2/repository минимизирует сетевые запросы.
Нюансы:
Храните mvnw и .mvn в репозитории для обеспечения воспроизводимости.
Обновляйте версию Maven в maven-wrapper.properties для поддержки новых функций.
Поддержка Java версий
Maven поддерживает проекты с разными версиями Java через maven-compiler-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
Многомодульные проекты
Каждый модуль может использовать разные версии Java, указав собственную конфигурацию плагина.
Toolchains: Для кросс-компиляции используйте ~/.m2/toolchains.xml:
<toolchains>
<toolchain>
<type>jdk</type>
<provides>
<version>11</version>
</provides>
<configuration>
<jdkHome>/path/to/jdk11</jdkHome>
</configuration>
</toolchain>
</toolchains>
Укажите toolchain в POM.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-toolchains-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>toolchain</goal>
</goals>
</execution>
</executions>
<configuration>
<toolchains>
<jdk>
<version>11</version>
</jdk>
</toolchains>
</configuration>
</plugin>
#Java #middle #Maven #Best_practics
Расширение Maven
Extensions
Расширения Maven — это JAR-файлы, которые добавляют функциональность, например, кастомные жизненные циклы или обработчики репозиториев.
Они указываются в .mvn/extensions.xml:
Создание:
Создайте проект с зависимостью maven-core.
Реализуйте интерфейс, например, org.apache.maven.AbstractMavenLifecycleParticipant.
Упакуйте как JAR и установите в репозиторий.
В памяти: Расширения загружаются через Plexus, увеличивая потребление памяти из-за дополнительных классов и их зависимостей.
Интернальные API Maven
Maven предоставляет API (maven-core, maven-plugin-api) для создания плагинов и расширений.
Пример использования org.apache.maven.project.MavenProject для доступа к модели проекта:
В памяти: Интернальные API загружают объекты POM-модели и контекста сборки, что может быть ресурсоемким для сложных операций, таких как анализ зависимостей.
Логирование и отладка:
Флаг -X: Включает отладочный режим, выводя подробную информацию о сборке, плагинах, зависимостях и реакторе:
Флаг -e: Выводит стек вызовов при ошибках:
Плагины для отладки:
mvn help:effective-pom: Показывает итоговую модель POM.
mvn dependency:tree: Анализирует зависимости.
mvn help:effective-settings: Показывает настройки settings.xml.
В памяти: Отладочные флаги создают дополнительные структуры данных для логов, увеличивая временное потребление памяти.
Сравнение и миграция с Ant/Gradle
Ant
Сравнение:
Ant: Императивный подход, где задачи определяются вручную в XML (build.xml). Нет встроенного управления зависимостями или жизненного цикла.
Maven: Декларативный подход с жизненным циклом и автоматическим разрешением зависимостей.
Миграция:
Перенесите задачи Ant в плагины Maven (например, maven-antrun-plugin для запуска Ant-скриптов).
Преобразуйте зависимости в POM.xml с помощью <dependency>.
Используйте mvn ant:ant для генерации build.xml из Maven для обратной совместимости.
Gradle
Сравнение:
Gradle: Гибридный подход (декларативный + императивный), использует Groovy/Kotlin DSL. Более гибкий, но сложнее в освоении.
Maven: Стандартизированный XML, проще для новичков, но менее гибкий.
Gradle быстрее благодаря инкрементальной сборке и кэшированию.
Миграция:
Используйте build.gradle с плагином maven-publish для публикации артефактов в Maven-репозитории.
Конвертируйте POM.xml в build.gradle с помощью инструментов, таких как gradle init.
Перенесите зависимости из <dependencyManagement> в dependencies Gradle.
В памяти: Ant использует меньше памяти из-за отсутствия сложных моделей, но требует больше ручной работы. Gradle может потреблять больше памяти из-за Groovy/Kotlin и сложных скриптов. Maven занимает среднюю позицию, но его POM-модель и граф зависимостей требуют значительных ресурсов в крупных проектах.
#Java #middle #Maven #Best_practics
Extensions
Расширения Maven — это JAR-файлы, которые добавляют функциональность, например, кастомные жизненные циклы или обработчики репозиториев.
Они указываются в .mvn/extensions.xml:
<extensions>
<extension>
<groupId>com.example</groupId>
<artifactId>custom-extension</artifactId>
<version>1.0</version>
</extension>
</extensions>
Создание:
Создайте проект с зависимостью maven-core.
Реализуйте интерфейс, например, org.apache.maven.AbstractMavenLifecycleParticipant.
Упакуйте как JAR и установите в репозиторий.
В памяти: Расширения загружаются через Plexus, увеличивая потребление памяти из-за дополнительных классов и их зависимостей.
Интернальные API Maven
Maven предоставляет API (maven-core, maven-plugin-api) для создания плагинов и расширений.
Пример использования org.apache.maven.project.MavenProject для доступа к модели проекта:
@Mojo(name = "custom")
public class CustomMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}")
private MavenProject project;
public void execute() throws MojoExecutionException {
getLog().info("Project artifact: " + project.getArtifactId());
}
}
В памяти: Интернальные API загружают объекты POM-модели и контекста сборки, что может быть ресурсоемким для сложных операций, таких как анализ зависимостей.
Логирование и отладка:
-X, -e
Флаг -X: Включает отладочный режим, выводя подробную информацию о сборке, плагинах, зависимостях и реакторе:
mvn package -X
Увеличивает объем логов, что может замедлить выполнение и потребовать больше памяти для буферизации вывода.
Флаг -e: Выводит стек вызовов при ошибках:
mvn package -e
Полезно для диагностики, минимально влияет на память.
Плагины для отладки:
mvn help:effective-pom: Показывает итоговую модель POM.
mvn dependency:tree: Анализирует зависимости.
mvn help:effective-settings: Показывает настройки settings.xml.
В памяти: Отладочные флаги создают дополнительные структуры данных для логов, увеличивая временное потребление памяти.
Сравнение и миграция с Ant/Gradle
Ant
Сравнение:
Ant: Императивный подход, где задачи определяются вручную в XML (build.xml). Нет встроенного управления зависимостями или жизненного цикла.
Maven: Декларативный подход с жизненным циклом и автоматическим разрешением зависимостей.
Миграция:
Перенесите задачи Ant в плагины Maven (например, maven-antrun-plugin для запуска Ant-скриптов).
Преобразуйте зависимости в POM.xml с помощью <dependency>.
Используйте mvn ant:ant для генерации build.xml из Maven для обратной совместимости.
Gradle
Сравнение:
Gradle: Гибридный подход (декларативный + императивный), использует Groovy/Kotlin DSL. Более гибкий, но сложнее в освоении.
Maven: Стандартизированный XML, проще для новичков, но менее гибкий.
Gradle быстрее благодаря инкрементальной сборке и кэшированию.
Миграция:
Используйте build.gradle с плагином maven-publish для публикации артефактов в Maven-репозитории.
Конвертируйте POM.xml в build.gradle с помощью инструментов, таких как gradle init.
Перенесите зависимости из <dependencyManagement> в dependencies Gradle.
В памяти: Ant использует меньше памяти из-за отсутствия сложных моделей, но требует больше ручной работы. Gradle может потреблять больше памяти из-за Groovy/Kotlin и сложных скриптов. Maven занимает среднюю позицию, но его POM-модель и граф зависимостей требуют значительных ресурсов в крупных проектах.
#Java #middle #Maven #Best_practics
Maven Best Practices: от Apache и Spring
Apache Best Practices
Централизация конфигурации: Используйте <dependencyManagement> и <pluginManagement> в родительском POM.
Минимизация зависимостей: Исключайте ненужные транзитивные зависимости через <exclusions>.
Профили: Используйте профили для окружений (dev, prod).
Кэширование: Настройте CI/CD для кэширования ~/.m2/repository.
Плагины: Используйте последние версии плагинов и проверяйте их совместимость.
Spring Best Practices
Spring Boot BOM: Используйте spring-boot-starter-parent или spring-boot-dependencies для управления версиями:
Минимизация конфигурации: Полагайтесь на автоконфигурацию Spring Boot вместо ручной настройки плагинов.
Плагины: Используйте spring-boot-maven-plugin для создания исполняемых JAR:
В памяти: Spring Boot BOM увеличивает объем POM-модели из-за большого числа зависимостей, но упрощает управление версиями. Плагин spring-boot-maven-plugin загружает дополнительные данные для создания "fat JAR", что может быть ресурсоемким.
Нюансы и внутренние механизмы
Управление памятью:
Maven загружает POM-модели, настройки и зависимости в память, создавая графы для модулей и артефактов. Крупные проекты с сотнями зависимостей могут потреблять гигабайты памяти.
Параллельная сборка (-T) и отладка (-X) увеличивают пиковое потребление.
Оптимизируйте с помощью -pl, -am и JVM-флагов (-Xmx).
Кэширование:
Локальный репозиторий (~/.m2/repository) снижает сетевые запросы, но требует периодической очистки устаревших SNAPSHOT-версий.
CI/CD-кэширование ускоряет сборку, но увеличивает использование диска.
Безопасность:
Шифруйте пароли для репозиториев с помощью mvn --encrypt-password.
Ограничивайте доступ к ~/.m2/settings-security.xml (chmod 600).
Производительность:
Инкрементальная сборка минимизирует повторные компиляции, но требует точной настройки временных меток в target.
Gradle может быть быстрее для инкрементальных сборок, но Maven проще для стандартизированных проектов.
Отладка:
Используйте -X для анализа реактора и зависимостей.
Проверяйте конфликты с mvn dependency:tree -Dverbose.
Анализируйте итоговую конфигурацию с mvn help:effective-pom.
#Java #middle #Maven #Best_practics
Apache Best Practices
Централизация конфигурации: Используйте <dependencyManagement> и <pluginManagement> в родительском POM.
Минимизация зависимостей: Исключайте ненужные транзитивные зависимости через <exclusions>.
Профили: Используйте профили для окружений (dev, prod).
Кэширование: Настройте CI/CD для кэширования ~/.m2/repository.
Плагины: Используйте последние версии плагинов и проверяйте их совместимость.
Spring Best Practices
Spring Boot BOM: Используйте spring-boot-starter-parent или spring-boot-dependencies для управления версиями:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
</parent>
Минимизация конфигурации: Полагайтесь на автоконфигурацию Spring Boot вместо ручной настройки плагинов.
Плагины: Используйте spring-boot-maven-plugin для создания исполняемых JAR:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
В памяти: Spring Boot BOM увеличивает объем POM-модели из-за большого числа зависимостей, но упрощает управление версиями. Плагин spring-boot-maven-plugin загружает дополнительные данные для создания "fat JAR", что может быть ресурсоемким.
Нюансы и внутренние механизмы
Управление памятью:
Maven загружает POM-модели, настройки и зависимости в память, создавая графы для модулей и артефактов. Крупные проекты с сотнями зависимостей могут потреблять гигабайты памяти.
Параллельная сборка (-T) и отладка (-X) увеличивают пиковое потребление.
Оптимизируйте с помощью -pl, -am и JVM-флагов (-Xmx).
Кэширование:
Локальный репозиторий (~/.m2/repository) снижает сетевые запросы, но требует периодической очистки устаревших SNAPSHOT-версий.
CI/CD-кэширование ускоряет сборку, но увеличивает использование диска.
Безопасность:
Шифруйте пароли для репозиториев с помощью mvn --encrypt-password.
Ограничивайте доступ к ~/.m2/settings-security.xml (chmod 600).
Производительность:
Инкрементальная сборка минимизирует повторные компиляции, но требует точной настройки временных меток в target.
Gradle может быть быстрее для инкрементальных сборок, но Maven проще для стандартизированных проектов.
Отладка:
Используйте -X для анализа реактора и зависимостей.
Проверяйте конфликты с mvn dependency:tree -Dverbose.
Анализируйте итоговую конфигурацию с mvn help:effective-pom.
#Java #middle #Maven #Best_practics
Что выведет код?
#Tasks
public class Task110725 {
public static void main(String[] args) {
int a = 1;
int b = a << 2 + a++ * --a;
System.out.println(b);
}
}
#Tasks
Продолжаем выбирать темы для разбора и голосовать за рассмотрение предложенных! 🤓
Голосуем за тему к рассмотрению в эти выходные!
Выбираем новую тему!
(можете предложить что-то из того, что предлагали на прошлой и позапрошлых неделях и что проиграло в голосовании!)
Не стесняемся!✌️
Голосуем за тему к рассмотрению в эти выходные!
Выбираем новую тему!
(можете предложить что-то из того, что предлагали на прошлой и позапрошлых неделях и что проиграло в голосовании!)
Не стесняемся!
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое CyclicBarrier в Java? 🤓
Ответ:
CyclicBarrier — это синхронизатор, позволяющий нескольким потокам ждать друг друга в определенной точке перед продолжением выполнения.
Пример:
CyclicBarrier barrier = new CyclicBarrier(3);
Runnable task = () -> {
System.out.println("Reached barrier");
try { barrier.await(); } catch (Exception e) {}
System.out.println("Proceeding");
};
new Thread(task).start();
new Thread(task).start();
new Thread(task).start();
После достижения барьера всеми потоками они продолжают выполнение.
#собеседование
Ответ:
Пример:
CyclicBarrier barrier = new CyclicBarrier(3);
Runnable task = () -> {
System.out.println("Reached barrier");
try { barrier.await(); } catch (Exception e) {}
System.out.println("Proceeding");
};
new Thread(task).start();
new Thread(task).start();
new Thread(task).start();
После достижения барьера всеми потоками они продолжают выполнение.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1