Что такое ForkJoinPool и RecursiveTask? 🤓
Ответ:
ForkJoinPool — это специальный пул потоков, реализующий алгоритм work-stealing (воровства задач).
Каждый поток имеет свою очередь задач. Когда поток завершает свои задачи, он может "украсть" задачу из очереди другого потока.
RecursiveTask<V> — это абстрактный класс для задач, которые возвращают результат и могут разделяться (fork) на подзадачи и объединяться (join).
Классический пример — рекурсивные алгоритмы, такие как быстрая сортировка, слияние массивов, вычисление чисел Фибоначчи. Используется в parallelStream().
#собеседование
Ответ:
ForkJoinPool — это специальный пул потоков, реализующий алгоритм work-stealing (воровства задач).
Каждый поток имеет свою очередь задач. Когда поток завершает свои задачи, он может "украсть" задачу из очереди другого потока.
RecursiveTask<V> — это абстрактный класс для задач, которые возвращают результат и могут разделяться (fork) на подзадачи и объединяться (join).
Классический пример — рекурсивные алгоритмы, такие как быстрая сортировка, слияние массивов, вычисление чисел Фибоначчи. Используется в parallelStream().
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
История технологии сегодня — 21 мая
ℹ️ Кто родился в этот день
Андре́й Дми́триевич Са́харов (21 мая 1921, Москва — 14 декабря 1989, Москва) — советский физик-теоретик, академик АН СССР, общественный деятель, диссидент и правозащитник. Один из создателей первой советской водородной бомбы.
Гаспа́р-Гюста́в де Кориоли́с (фр. Gaspard-Gustave de Coriolis; 21 мая 1792 — 19 сентября 1843) — французский математик, механик и инженер. Больше всего известен работой, посвящённой изучению эффекта Кориолиса. Также известен теоремой об ускорениях в абсолютном и относительном движениях, называемой теорема Кориолиса.
🌐 Знаковые события
2019 — Microsoft выпустила Windows Server 2019.
#Biography #Birth_Date #Events #21мая
Андре́й Дми́триевич Са́харов (21 мая 1921, Москва — 14 декабря 1989, Москва) — советский физик-теоретик, академик АН СССР, общественный деятель, диссидент и правозащитник. Один из создателей первой советской водородной бомбы.
Гаспа́р-Гюста́в де Кориоли́с (фр. Gaspard-Gustave de Coriolis; 21 мая 1792 — 19 сентября 1843) — французский математик, механик и инженер. Больше всего известен работой, посвящённой изучению эффекта Кориолиса. Также известен теоремой об ускорениях в абсолютном и относительном движениях, называемой теорема Кориолиса.
2019 — Microsoft выпустила Windows Server 2019.
#Biography #Birth_Date #Events #21мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
[Совет по Java #040]
Тема: Переменные в
Проблема: Блоки
Это приводит к распространенной ошибке: разработчик объявляет и инициализирует ресурс (например,
Решение: Начиная с Java 7, предпочтительный способ —
Объяснение: Область видимости переменной в Java ограничена блоком, в котором она объявлена. Внутри
#Java #советы
Тема: Переменные в
catch и finally не видны снаружи.Проблема: Блоки
try, catch, finally образуют собственную область видимости. Переменная, объявленная внутри блока try, недоступна в блоках catch и finally. Это приводит к распространенной ошибке: разработчик объявляет и инициализирует ресурс (например,
BufferedReader) внутри try, а затем пытается закрыть его в finally. Код не компилируется с ошибкой "cannot find symbol". В попытке исправить это, некоторые объявляют переменную вне блока, но инициализируют её null, а затем в finally проверяют на null. Такой подход громоздок и чреват NullPointerException, если инициализация выбросила исключение. Кроме того, если ресурс поддерживает AutoCloseable, ручное закрытие в finally излишне и опасно (можно забыть закрыть, или исключения при закрытии перекроют исходное).Решение: Начиная с Java 7, предпочтительный способ —
try-with-resources. Ресурс объявляется в круглых скобках после try и автоматически закрывается после выполнения блока. Он доступен внутри try, catch и даже finally (хотя finally обычно не нужен). Если try-with-resources недоступен (старые версии Java или ресурс не реализует AutoCloseable), объявляйте переменную вне блока try, инициализируйте её значением null, затем в finally проверяйте на null перед закрытием. Однако первый вариант значительно чище и безопаснее.public class TryCatchScope {
//Антипаттерн: переменная объявлена в try, недоступна в finally
public static void badScope() {
try {
BufferedReader reader = new BufferedReader(new FileReader("file.txt"));
String line = reader.readLine();
} catch (IOException e) {
System.err.println(e);
} finally {
// reader.close(); // Ошибка компиляции: reader не виден!
}
}
//Громоздкое ручное управление (не рекомендуется)
public static void manualManagement() {
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader("file.txt"));
String line = reader.readLine();
} catch (IOException e) {
System.err.println(e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
// Проглатывание или логирование
}
}
}
}
//Решение: try-with-resources (лучший способ)
public static void goodTryWithResources() throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
String line = reader.readLine();
// reader доступен здесь
} catch (IOException e) {
System.err.println("Ошибка: " + e);
// reader уже закрыт автоматически
}
}
//Если ресурс не реализует AutoCloseable, объявляйте вне try
public static void legacyResource() {
final int[] fileDescriptor = { -1 }; // имитация
try {
fileDescriptor[0] = openNativeResource();
} finally {
if (fileDescriptor[0] != -1) {
closeNativeResource(fileDescriptor[0]);
}
}
}
private static int openNativeResource() { return 42; }
private static void closeNativeResource(int fd) { }
}Объяснение: Область видимости переменной в Java ограничена блоком, в котором она объявлена. Внутри
try создается локальная переменная, которая уничтожается после выхода из блока, поэтому finally её не видит.try-with-resources решает проблему иначе: ресурсы объявляются в специальной секции, их область видимости распространяется на try, catch и finally. Кроме того, компилятор генерирует правильный код закрытия с подавленными исключениями. Даже если вы не используете catch, блок finally становится не нужен.#Java #советы
👍7
Что выведет код?
#Tasks
import java.io.*;
public class Task210526 {
public static void main(String[] args) throws IOException {
BufferedReader reader = null;
String result = "";
try {
reader = new BufferedReader(new StringReader("hello"));
result = reader.readLine();
throw new RuntimeException("error");
} catch (RuntimeException | IOException e) {
reader.close();
result = "catch";
} finally {
reader.close();
}
System.out.println(result);
}
}
#Tasks
👍2
👍4
Что такое stamped lock (StampedLock)? 🤓
Ответ:
StampedLock (Java 8) — это альтернатива ReentrantReadWriteLock, которая поддерживает оптимистическое чтение.
Он возвращает "штамп" (long), который проверяется при попытке преобразования в полную блокировку. Оптимистическое чтение не блокирует запись и не требует блокировок, но после чтения нужно проверить, не изменились ли данные. Если изменились — можно повторить чтение с пессимистичной блокировкой.
Это повышает производительность в сценариях с частыми чтениями и редкими записями. Не поддерживает реентерабельность.
#собеседование
Ответ:
StampedLock (Java 8) — это альтернатива ReentrantReadWriteLock, которая поддерживает оптимистическое чтение.
Он возвращает "штамп" (long), который проверяется при попытке преобразования в полную блокировку. Оптимистическое чтение не блокирует запись и не требует блокировок, но после чтения нужно проверить, не изменились ли данные. Если изменились — можно повторить чтение с пессимистичной блокировкой.
Это повышает производительность в сценариях с частыми чтениями и редкими записями. Не поддерживает реентерабельность.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Всем привет!
https://habr.com/ru/articles/1036992/ - если вы читали статью и согласны с ее выводами, прошу поддержать их в комментах, а то я не вывожу наплыва "инженеров")))
Заранее ❤️
https://habr.com/ru/articles/1036992/ - если вы читали статью и согласны с ее выводами, прошу поддержать их в комментах, а то я не вывожу наплыва "инженеров")))
Заранее ❤️
Хабр
Java нас обманывает: скрытая цена чистого кода
Все началось с того что я неожиданно стал безработным Java-разработчиком. Да, сейчас такое случается. (и я кстати в поиске работы, если что) . А что делает увлеченный Java-разработчик, когда у него...
👍3
История технологии сегодня — 22 мая
ℹ️ Кто родился в этот день
Па́вел Алексе́евич Зару́бин (10 (22) мая 1816, посад Пучеж, Костромская губерния — 31 июля (12 августа) 1886, Санкт-Петербург) — русский механик-самоучка, изобретатель, землемер и писатель.
Получил известность благодаря созданию ряда оригинальных приборов для межевания (в том числе планиметра-самоката, за который был дважды удостоен Демидовской премии), а также литературным произведениям, реалистично описывавшим быт провинциального мещанства и оказавшим, по признанию самого писателя, влияние на раннее творчество А. М. Горького.
Уильям Стёрджен (англ. William Sturgeon, 22 мая 1783 года — 4 декабря 1850 года) — британский физик, электротехник и изобретатель, создал первые электромагниты и изобрёл первый английский работающий электродвигатель.
Джордж Хейлмейер (англ. George Harry Heilmeier; (22 мая 1936 года — 21 апреля 2014 года)) — американский инженер и менеджер.
В 1964 году исследовал электрооптические эффекты в жидких кристаллах, что привело к появлению плоских жидкокристаллических экранов в 1968 году.
Сю́дзи Накаму́ра (яп. 中村修二 Накамура Сю:дзи, род. 22 мая 1954) — японский и американский физик, изобретатель синего светодиода, лауреат Нобелевской премии по физике (2014), в настоящее время работает в Калифорнийском университете в Санта-Барбаре (США).
🌐 Знаковые события
1906 — братья Райт получили патент на свой летательный аппарат.
1911 — профессор Технологического института Борис Розинг получил изображения геометрических фигур на экране электронно-лучевой трубки — прообразы нынешнего телевизионного изображения.
1973 — Роберт Меткалф составил докладную записку для главы PARC о потенциале технологии Ethernet. Этот день общепринято считать днём изобретения данной технологии.
1990 - состоялся релиз программной оболочки Windows 3.0 компании Microsoft.
#Biography #Birth_Date #Events #22мая
Па́вел Алексе́евич Зару́бин (10 (22) мая 1816, посад Пучеж, Костромская губерния — 31 июля (12 августа) 1886, Санкт-Петербург) — русский механик-самоучка, изобретатель, землемер и писатель.
Получил известность благодаря созданию ряда оригинальных приборов для межевания (в том числе планиметра-самоката, за который был дважды удостоен Демидовской премии), а также литературным произведениям, реалистично описывавшим быт провинциального мещанства и оказавшим, по признанию самого писателя, влияние на раннее творчество А. М. Горького.
Уильям Стёрджен (англ. William Sturgeon, 22 мая 1783 года — 4 декабря 1850 года) — британский физик, электротехник и изобретатель, создал первые электромагниты и изобрёл первый английский работающий электродвигатель.
Джордж Хейлмейер (англ. George Harry Heilmeier; (22 мая 1936 года — 21 апреля 2014 года)) — американский инженер и менеджер.
В 1964 году исследовал электрооптические эффекты в жидких кристаллах, что привело к появлению плоских жидкокристаллических экранов в 1968 году.
Сю́дзи Накаму́ра (яп. 中村修二 Накамура Сю:дзи, род. 22 мая 1954) — японский и американский физик, изобретатель синего светодиода, лауреат Нобелевской премии по физике (2014), в настоящее время работает в Калифорнийском университете в Санта-Барбаре (США).
1906 — братья Райт получили патент на свой летательный аппарат.
1911 — профессор Технологического института Борис Розинг получил изображения геометрических фигур на экране электронно-лучевой трубки — прообразы нынешнего телевизионного изображения.
1973 — Роберт Меткалф составил докладную записку для главы PARC о потенциале технологии Ethernet. Этот день общепринято считать днём изобретения данной технологии.
1990 - состоялся релиз программной оболочки Windows 3.0 компании Microsoft.
#Biography #Birth_Date #Events #22мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Раздел 9. Исключения, логирование, отладка
Глава 2. Логирование (Logging)
Конфигурация Logback через logback.xml (или logback-test.xml)
Logback ищет файл конфигурации в classpath в строго определенном порядке приоритетов. Первый найденный файл используется, остальные игнорируются.
Последовательность поиска:
Автоматическая конфигурация через SPI (Service Provider Interface)
Базовая конфигурация по умолчанию — консольный вывод с уровнем DEBUG
Файл
Структура XML-конфигурации
Корневой элемент
Элемент
ConsoleAppender: вывод в консоль
Элемент
Для контейнеризированных приложений рекомендуется выводить логи в stdout без форматирования времени, так как Docker добавляет собственную временную метку:
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
Глава 2. Логирование (Logging)
Конфигурация Logback через logback.xml (или logback-test.xml)
Logback ищет файл конфигурации в classpath в строго определенном порядке приоритетов. Первый найденный файл используется, остальные игнорируются.
Последовательность поиска:
logback-test.xml — предназначен для тестов, имеет наивысший приоритетlogback.xml — стандартная production-конфигурацияlogback.groovy — альтернативный формат на языке GroovyАвтоматическая конфигурация через SPI (Service Provider Interface)
Базовая конфигурация по умолчанию — консольный вывод с уровнем DEBUG
Файл
logback-test.xml размещается в src/test/resources/ и гарантирует, что тесты используют собственную конфигурацию независимо от production-настроек. Это критично для изоляции: тесты могут подавлять лишний вывод или направлять логи в память для верификации.Структура XML-конфигурации
Корневой элемент
<configuration> поддерживает атрибуты для управления поведением сканирования:<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- scan="true" — автоматическая перезагрузка при изменении файла -->
<!-- scanPeriod — интервал проверки в секундах, минутах, часах -->
<!-- debug="true" — вывод внутренней диагностики Logback в консоль -->
<!-- Определение переменных свойств -->
<property name="LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"/>
<property name="LOG_DIR" value="/var/log/myapp"/>
<!-- Appenders -->
<!-- ... -->
<!-- Логгеры -->
<!-- ... -->
<!-- Корневой логгер -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
Элемент
<property> определяет переменные, доступные во всей конфигурации через синтаксис ${NAME}. Переменные могут ссылаться на системные свойства JVM (${user.home}), переменные окружения (${ENV_VAR:-default}) или внешние файлы свойств через <property file="..."/>.ConsoleAppender: вывод в консоль
ConsoleAppender направляет логи в System.out или System.err. Это стандартный appender для development-окружений и контейнеризированных приложений, где stdout/stderr собираются Docker или Kubernetes.<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<!-- Целевой поток: System.out (по умолчанию) или System.err -->
<target>System.out</target>
<!-- Фильтр уровня: пропускать только INFO и выше -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- Кодировка вывода -->
<encoder>
<charset>UTF-8</charset>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<!-- Немедленный сброс буфера (для контейнеров) -->
<immediateFlush>true</immediateFlush>
</appender>
Элемент
<filter> ограничивает проходящие сообщения. ThresholdFilter пропускает только сообщения с уровнем не ниже указанного. Это позволяет направлять в консоль только INFO и выше, даже если корневой уровень установлен на DEBUG — фильтр appender работает после фильтра логгера.Для контейнеризированных приложений рекомендуется выводить логи в stdout без форматирования времени, так как Docker добавляет собственную временную метку:
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>
</encoder>
</appender>
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
👍1
FileAppender и RollingFileAppender: вывод в файл
Базовый FileAppender
Атрибут
RollingFileAppender с ротацией по размеру
RollingFileAppender с ротацией по времени
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
FileAppender записывает в единственный файл без ограничения размера. Это опасно для production, так как файл растет бесконечно. RollingFileAppender расширяет FileAppender политиками ротации, автоматически архивируя и заменяя файлы при достижении условий.Базовый FileAppender
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${LOG_DIR}/application.log</file>
<append>true</append> <!-- Дописывать в существующий файл -->
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<!-- Права доступа к создаваемым файлам (только Unix) -->
<prudent>false</prudent> <!-- true — безопасная запись из нескольких JVM -->
</appender>
Атрибут
prudent="true" включает режим безопасной записи из нескольких JVM в один файл через FileChannel locks. Это снижает производительность, но предотвращает повреждение при кластерном развертывании.RollingFileAppender с ротацией по размеру
<appender name="ROLLING_SIZE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<!-- Имя архивного файла с индексом -->
<fileNamePattern>${LOG_DIR}/application.%i.log.zip</fileNamePattern>
<!-- Максимальный индекс архива -->
<minIndex>1</minIndex>
<maxIndex>10</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<!-- Максимальный размер файла перед ротацией -->
<maxFileSize>100MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
FixedWindowRollingPolicy с SizeBasedTriggeringPolicy создает архивы с числовыми индексами: application.1.log.zip, application.2.log.zip и так до maxIndex. Когда достигнут maxIndex, самый старый архив удаляется. Эта политика проста, но имеет ограничение: при перезапуске приложения индексация начинается с 1, что может привести к перезаписи существующих архивов.RollingFileAppender с ротацией по времени
<appender name="ROLLING_TIME" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Шаблон имени архива с датой -->
<fileNamePattern>${LOG_DIR}/application.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- Хранить архивы за 30 дней -->
<maxHistory>30</maxHistory>
<!-- Общий лимит размера архивов -->
<totalSizeCap>3GB</totalSizeCap>
<!-- Очистка устаревших архивов при старте -->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
TimeBasedRollingPolicy использует дату в шаблоне fileNamePattern для определения периода ротации. Спецификатор %d{yyyy-MM-dd} означает ежедневную ротацию. %d{yyyy-MM-dd_HH} — почасовую, %d{yyyy-MM} — ежемесячную. Logback автоматически вычисляет ближайший момент ротации на основе наиболее мелкой единицы времени в шаблоне.maxHistory удаляет архивы старше указанного количества периодов. totalSizeCap ограничивает суммарный размер всех архивов — когда лимит превышен, самые старые архивы удаляются независимо от maxHistory. cleanHistoryOnStart выполняет очистку при старте приложения, что полезно для долгоживущих сервисов, которые могут перезапускаться редко.#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
👍1
Комбинированная ротация: время + размер
Практические шаблоны
Стандартный шаблон для development:
Production-шаблон без ANSI-цветов:
JSON-формат для систем агрегации:
Установка уровней: корневой и пакетные логгеры
Корневой логгер
Корневой логгер (
Здесь корневой уровень WARN означает, что по умолчанию выводятся только WARN и ERROR. Любой логгер без явного уровня наследует эту настройку.
Логгеры для пакетов и классов
Элемент
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
<appender name="ROLLING_COMBINED" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/application.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- Ежедневная ротация, но если файл превысит 100MB — дополнительная ротация -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
SizeAndTimeBasedRollingPolicy комбинирует оба подхода. %i — индекс, который инкрементируется при достижении maxFileSize в течение одного временного периода. Таким образом, за один день может быть создано несколько архивов: application.2024-01-15.0.log, application.2024-01-15.1.log и так далее. Это решает проблему чрезмерно больших файлов при высокой нагрузке.Практические шаблоны
Стандартный шаблон для development:
<pattern>%d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>%highlight раскрашивает уровень в цвет терминала: ERROR красный, WARN желтый, INFO зеленый, DEBUG и TRACE синий. %cyan применяет циановый цвет к имени логгера.Production-шаблон без ANSI-цветов:
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%rEx</pattern>%rEx (root exception) выводит сокращенный стектрейс, исключая фреймы из стандартных библиотек, что существенно уменьшает объем лога при частых исключениях.JSON-формат для систем агрегации:
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
LogstashEncoder из библиотеки logstash-logback-encoder формирует структурированный JSON с полями timestamp, level, logger, message, thread, stack_trace и MDC-значениями. Это устраняет необходимость парсинга регулярными выражениями в ELK или Splunk.Установка уровней: корневой и пакетные логгеры
Корневой логгер
Корневой логгер (
root) является предком всех остальных логгеров. Его уровень применяется, когда для конкретного логгера уровень не задан явно.<root level="WARN">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ROLLING_TIME"/>
</root>
Здесь корневой уровень WARN означает, что по умолчанию выводятся только WARN и ERROR. Любой логгер без явного уровня наследует эту настройку.
Логгеры для пакетов и классов
Элемент
<logger> позволяет переопределить уровень для конкретного имени логгера, формируя иерархию:<!-- Уровень DEBUG для всего пакета сервисов -->
<logger name="com.example.service" level="DEBUG"/>
<!-- Уровень TRACE для конкретного класса при расследовании -->
<logger name="com.example.service.PaymentGateway" level="TRACE"/>
<!-- Отключение additivity для изоляции аудита -->
<logger name="com.example.audit" level="INFO" additivity="false">
<appender-ref ref="AUDIT_FILE"/>
</logger>
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
👍1
Свойство
Это критично для разделения потоков. Логгер аудита направляет сообщения только в файл аудита, не дублируя их в общий консольный вывод:
Полный пример конфигурации
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
additivity управляет наследованием appenders. По умолчанию true: сообщение, обработанное логгером com.example.service, передается также в appenders предков (com.example, com, root). При additivity="false" сообщение обрабатывается только указанными appenders и не поднимается выше.Это критично для разделения потоков. Логгер аудита направляет сообщения только в файл аудита, не дублируя их в общий консольный вывод:
<appender name="AUDIT_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/audit.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/audit.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %msg%n</pattern>
</encoder>
</appender>
<logger name="com.example.audit" level="INFO" additivity="false">
<appender-ref ref="AUDIT_FILE"/>
</logger>
Полный пример конфигурации
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds">
<property name="LOG_DIR" value="/var/log/myapp"/>
<property name="LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n%rEx"/>
<!-- Консоль: только INFO и выше, с цветами -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %highlight(%-5level) %cyan(%logger{36}) - %msg%n</pattern>
</encoder>
</appender>
<!-- Основной файл: DEBUG и выше -->
<appender name="APPLICATION" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/application.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Файл ошибок: только ERROR -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/error.log</file>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Аудит: изолированный поток -->
<appender name="AUDIT_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/audit.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_DIR}/audit.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>365</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %msg%n</pattern>
</encoder>
</appender>
<!-- Логгеры пакетов -->
<logger name="com.example.service" level="DEBUG"/>
<logger name="org.springframework.web" level="WARN"/>
<logger name="org.hibernate.SQL" level="DEBUG"/>
<!-- Изолированный аудит -->
<logger name="com.example.audit" level="INFO" additivity="false">
<appender-ref ref="AUDIT_FILE"/>
</logger>
<!-- Корневой логгер -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="APPLICATION"/>
<appender-ref ref="ERROR_FILE"/>
</root>
</configuration>
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
👍5
Что выведет код?
#Tasks
public class Task220526 {
public static void main(String[] args) {
StringBuilder sb1 = new StringBuilder("Java");
StringBuilder sb2 = sb1.append("Script");
System.out.println(sb1 == sb2);
System.out.println(sb1.toString() == sb2.toString());
System.out.println(sb1.toString().equals(sb2.toString()));
}
}#Tasks
👍3
Варианты ответа:
Anonymous Quiz
35%
true true true
24%
true false true
18%
false false true
24%
true false false
👍2
Что такое Phaser? 🤓
Ответ:
Phaser — это более гибкая замена CyclicBarrier и CountDownLatch, появившаяся в Java 7.
Он поддерживает многофазную синхронизацию потоков, которые могут динамически регистрироваться и дерегистрироваться. Каждая фаза имеет номер.
Потоки вызывают arriveAndAwaitAdvance() — прибытие и ожидание перехода к следующей фазе. Phaser может использоваться для организации синхронизации в алгоритмах с несколькими итерациями (фазами), где количество участников меняется.
Поддерживает иерархию (родительские Phaser'ы).
#собеседование
Ответ:
Phaser — это более гибкая замена CyclicBarrier и CountDownLatch, появившаяся в Java 7.
Он поддерживает многофазную синхронизацию потоков, которые могут динамически регистрироваться и дерегистрироваться. Каждая фаза имеет номер.
Потоки вызывают arriveAndAwaitAdvance() — прибытие и ожидание перехода к следующей фазе. Phaser может использоваться для организации синхронизации в алгоритмах с несколькими итерациями (фазами), где количество участников меняется.
Поддерживает иерархию (родительские Phaser'ы).
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
История технологии сегодня — 23 мая
Сегодня Java исполнился 31 год! 🎉
Изначально язык назывался Oak («Дуб»), разрабатывался Джеймсом Гослингом для программирования бытовых электронных устройств. Из-за того, что язык с таким названием уже существовал, Oak был переименован в Java. Назван в честь марки кофе Java, которая, в свою очередь, получила наименование одноимённого острова (Ява), поэтому на официальной эмблеме языка изображена чашка с горячим кофе. Существует и другая версия происхождения названия языка, связанная с аллюзией на кофемашину как пример бытового устройства, для программирования которого изначально язык создавался. В соответствии с этимологией в русскоязычной литературе с конца двадцатого и до первых лет двадцать первого века название языка нередко переводилось как Ява, а не транскрибировалось.
С середины 1990-х годов язык стал широко использоваться для написания клиентских приложений и серверного программного обеспечения. Тогда же определённое распространение получила технология Java-апплетов — графических Java-приложений, встраиваемых в веб-страницы; с развитием возможностей динамических веб-страниц в 2000-е годы технология стала применяться редко.
ℹ️ Кто родился в этот день
Роберт Артур Муг (Моуг; англ. Robert A. Moog, Bob Moog /ˈmoʊɡ/; 23 мая 1934 — 21 августа 2005) — американский изобретатель, предприниматель, пионер электронной музыки, известен как создатель синтезатора Муга.
Джон Ба́рди́н (англ. John Bardeen; 23 мая 1908, Мадисон, Висконсин, США — 30 января 1991, Бостон, Массачусетс, США) — американский физик, один из пяти человек, получивших за свою жизнь по две Нобелевские премии: в 1956 году за транзистор совместно с Уильямом Брэдфордом Шокли и Уолтером Браттейном и в 1972 году за основополагающую теорию обычных сверхпроводников совместно с Леоном Нилом Купером и Джоном Робертом Шриффером. Сейчас эта теория называется теорией Бардина — Купера — Шриффера, или просто БКШ-теория.
🌐 Знаковые события
1934 — первый полёт экспериментальной крылатой ракеты, спроектированной под руководством С. П. Королёва в ГИРД, оснащённой ГРД.
1995 — компания Sun официально представила Java и HotJava на выставке SunWorld '95.
#Biography #Birth_Date #Events #23мая
Сегодня Java исполнился 31 год! 🎉
Изначально язык назывался Oak («Дуб»), разрабатывался Джеймсом Гослингом для программирования бытовых электронных устройств. Из-за того, что язык с таким названием уже существовал, Oak был переименован в Java. Назван в честь марки кофе Java, которая, в свою очередь, получила наименование одноимённого острова (Ява), поэтому на официальной эмблеме языка изображена чашка с горячим кофе. Существует и другая версия происхождения названия языка, связанная с аллюзией на кофемашину как пример бытового устройства, для программирования которого изначально язык создавался. В соответствии с этимологией в русскоязычной литературе с конца двадцатого и до первых лет двадцать первого века название языка нередко переводилось как Ява, а не транскрибировалось.
С середины 1990-х годов язык стал широко использоваться для написания клиентских приложений и серверного программного обеспечения. Тогда же определённое распространение получила технология Java-апплетов — графических Java-приложений, встраиваемых в веб-страницы; с развитием возможностей динамических веб-страниц в 2000-е годы технология стала применяться редко.
Роберт Артур Муг (Моуг; англ. Robert A. Moog, Bob Moog /ˈmoʊɡ/; 23 мая 1934 — 21 августа 2005) — американский изобретатель, предприниматель, пионер электронной музыки, известен как создатель синтезатора Муга.
Джон Ба́рди́н (англ. John Bardeen; 23 мая 1908, Мадисон, Висконсин, США — 30 января 1991, Бостон, Массачусетс, США) — американский физик, один из пяти человек, получивших за свою жизнь по две Нобелевские премии: в 1956 году за транзистор совместно с Уильямом Брэдфордом Шокли и Уолтером Браттейном и в 1972 году за основополагающую теорию обычных сверхпроводников совместно с Леоном Нилом Купером и Джоном Робертом Шриффером. Сейчас эта теория называется теорией Бардина — Купера — Шриффера, или просто БКШ-теория.
1934 — первый полёт экспериментальной крылатой ракеты, спроектированной под руководством С. П. Королёва в ГИРД, оснащённой ГРД.
1995 — компания Sun официально представила Java и HotJava на выставке SunWorld '95.
#Biography #Birth_Date #Events #23мая
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5🍾3
С 09.05 по 22.05
Предыдущий пост(с 02.05 по 08.05)
Запись встреч/видео:
13. Kafka: переход от очереди задач к журналу событий
Keycloak с нуля: от первого токена до современной auth-архитектуры
Обучающие статьи:
[Совет по Java #035]
Тема: java.util.Timer создает один поток для всех задач.
[Совет по Java #037]
Тема: File.delete() не бросает исключение при неудаче.
[Совет по Java #038]
Тема: SimpleDateFormat не потокобезопасен.
[Совет по Java #039]
Тема: String.split() принимает регулярное выражение.
[Совет по Java #040]
Тема: Переменные в catch и finally не видны снаружи.
Раздел 9. Исключения, логирование, отладка
Глава 2. Логирование (Logging)
Подключение SLF4J + Logback в проект (Maven/Gradle). Базовый пример получения логгера
Уровни логирования: TRACE, DEBUG, INFO, WARN, ERROR. Когда что использовать. Иерархия и фильтрация
Параметризованные сообщения SLF4J: почему это лучше конкатенации строк
Логирование исключений — правильная передача throwable последним параметром
Конфигурация Logback через logback.xml (или logback-test.xml)
Полезные статьи и видео:
Java нас обманывает: скрытая цена чистого кода
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
Предыдущий пост(с 02.05 по 08.05)
Запись встреч/видео:
13. Kafka: переход от очереди задач к журналу событий
Keycloak с нуля: от первого токена до современной auth-архитектуры
Обучающие статьи:
[Совет по Java #035]
Тема: java.util.Timer создает один поток для всех задач.
[Совет по Java #037]
Тема: File.delete() не бросает исключение при неудаче.
[Совет по Java #038]
Тема: SimpleDateFormat не потокобезопасен.
[Совет по Java #039]
Тема: String.split() принимает регулярное выражение.
[Совет по Java #040]
Тема: Переменные в catch и finally не видны снаружи.
Раздел 9. Исключения, логирование, отладка
Глава 2. Логирование (Logging)
Подключение SLF4J + Logback в проект (Maven/Gradle). Базовый пример получения логгера
Уровни логирования: TRACE, DEBUG, INFO, WARN, ERROR. Когда что использовать. Иерархия и фильтрация
Параметризованные сообщения SLF4J: почему это лучше конкатенации строк
Логирование исключений — правильная передача throwable последним параметром
Конфигурация Logback через logback.xml (или logback-test.xml)
Полезные статьи и видео:
Java нас обманывает: скрытая цена чистого кода
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
👍1🔥1
История технологии сегодня — 24 мая
ℹ️ Кто родился в этот день
Алекса́ндр Алексе́евич Лема́нский (24 мая 1935, Москва — 27 сентября 2007, Капустин Яр, Ахтубинский район, Астраханская область) — советский и российский учёный, генеральный конструктор НПО «Алмаз», заведующий кафедрой «Радиолокация, радиоуправление и информатика» Факультета радиотехники и кибернетики МФТИ, доктор технических наук, профессор, руководитель работ по созданию системы С-400.
Даниель Габриель Фаренгейт (Фаренхайт; нем. Daniel Gabriel Fahrenheit; 24 мая 1686, Данциг (ныне — Гданьск, Польша) — 16 сентября 1736, Гаага) — немецкий физик, родившийся в Польше. В Нидерландах он впервые изготовил термометр и барометр. Вначале термоскопической жидкостью ему служил спирт, но затем около 1715 года он заменил спирт ртутью, чем достиг гораздо большей точности измерений. Фаренгейтом изготовлены также первый весовой ареометр и термобарометр. В 1721 году он открыл, что вода может быть охлаждена ниже точки замерзания и оставаться в жидком состоянии; работал также над устройством машины для осушения местностей, подвергшихся наводнениям. Единица измерения температуры градус Фаренгейта (°F) была названа в его честь.
🌐 Знаковые события
1949 — пуск первой советской геофизической ракеты В-1А. Начало регулярных научных исследований верхних слоёв атмосферы.
2001 — в русской Википедии появилась первая статья.
2006 — запущен проект Wikimapia.
#Biography #Birth_Date #Events #24мая
Алекса́ндр Алексе́евич Лема́нский (24 мая 1935, Москва — 27 сентября 2007, Капустин Яр, Ахтубинский район, Астраханская область) — советский и российский учёный, генеральный конструктор НПО «Алмаз», заведующий кафедрой «Радиолокация, радиоуправление и информатика» Факультета радиотехники и кибернетики МФТИ, доктор технических наук, профессор, руководитель работ по созданию системы С-400.
Даниель Габриель Фаренгейт (Фаренхайт; нем. Daniel Gabriel Fahrenheit; 24 мая 1686, Данциг (ныне — Гданьск, Польша) — 16 сентября 1736, Гаага) — немецкий физик, родившийся в Польше. В Нидерландах он впервые изготовил термометр и барометр. Вначале термоскопической жидкостью ему служил спирт, но затем около 1715 года он заменил спирт ртутью, чем достиг гораздо большей точности измерений. Фаренгейтом изготовлены также первый весовой ареометр и термобарометр. В 1721 году он открыл, что вода может быть охлаждена ниже точки замерзания и оставаться в жидком состоянии; работал также над устройством машины для осушения местностей, подвергшихся наводнениям. Единица измерения температуры градус Фаренгейта (°F) была названа в его честь.
1949 — пуск первой советской геофизической ракеты В-1А. Начало регулярных научных исследований верхних слоёв атмосферы.
2001 — в русской Википедии появилась первая статья.
2006 — запущен проект Wikimapia.
#Biography #Birth_Date #Events #24мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Почему все-таки программирование?
Мне, 40-летнему человеку, по теории, должно было быть сложно менять профессию.
Тем более, я уже успел получить несколько других и добиться в них немалого успеха.
Так почему же я решился на такую авантюру? (а по другому, мои родные это не называли😂 )
Вот некоторые из тех принципов, которые определили пройденный путь:
1. Успех в определенной профессии != достойной зарплате и условиям труда🫰 .
Поработав в разных сферах и в разных условиях, посмотрев как трудятся люди разных профессий, начинаешь понимать ценность спокойной, "удаленной" работы и достойного, денежного эквивалента этого труда. ☝️
2. Развитие и перспективы в обозримом будущем🏝 .
По моему скромному мнению, пределов развития и так называемого "потолка", у человека выбравшего программирование - нет. Вот нет и все. Кто готов поспорить - жду в комментариях🤓
А есть лишь естественные причины - физические ограничения и ЛЕНЬ.😵
А это значит, что пока руки поднимаются - опускать их мимо клавиатуры, противоестественно!💪
3. Неугасаемый интерес к процессу созидания (написанию кода)🧑💻 .
Один из мощнейших, мотивационных принципов для меня.
Ведь, что может быть прекраснее, чем наблюдать как созданный тобой корабль (условно, конечно же), держится и продолжает плыть в самом современном море, которое еще не исследовано до конца?⛵️
Все это, в совокупности, перевесило мое нежелание (или инерцию мышления и жизни) изучать программирование.
И даже когда (очень часто, столкнувшись с нерешаемой задачей😭 ) мне казалось, что я сделал опрометчиво-глупый выбор - эти принципы помогали преодолеть сомнения (и конечно же задачу, потому что нерешаемых задач НЕТ 💪 ).
😎
#motivation
Мне, 40-летнему человеку, по теории, должно было быть сложно менять профессию.
Тем более, я уже успел получить несколько других и добиться в них немалого успеха.
Так почему же я решился на такую авантюру? (а по другому, мои родные это не называли
Вот некоторые из тех принципов, которые определили пройденный путь:
1. Успех в определенной профессии != достойной зарплате и условиям труда
Поработав в разных сферах и в разных условиях, посмотрев как трудятся люди разных профессий, начинаешь понимать ценность спокойной, "удаленной" работы и достойного, денежного эквивалента этого труда. ☝️
2. Развитие и перспективы в обозримом будущем
По моему скромному мнению, пределов развития и так называемого "потолка", у человека выбравшего программирование - нет. Вот нет и все. Кто готов поспорить - жду в комментариях
А есть лишь естественные причины - физические ограничения и ЛЕНЬ.
А это значит, что пока руки поднимаются - опускать их мимо клавиатуры, противоестественно!
3. Неугасаемый интерес к процессу созидания (написанию кода)
Один из мощнейших, мотивационных принципов для меня.
Ведь, что может быть прекраснее, чем наблюдать как созданный тобой корабль (условно, конечно же), держится и продолжает плыть в самом современном море, которое еще не исследовано до конца?
Все это, в совокупности, перевесило мое нежелание (или инерцию мышления и жизни) изучать программирование.
И даже когда (очень часто, столкнувшись с нерешаемой задачей
#motivation
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍2