История технологии сегодня — 11 мая
ℹ️ Кто родился в этот день
Э́дсгер Ви́бе Де́йкстра (нид. Edsger Wybe Dijkstra (11 мая 1930, Роттердам, Нидерланды — 6 августа 2002, Нюэнен, Нидерланды) — нидерландский учёный, труды которого оказали влияние на развитие информатики и информационных технологий; один из разработчиков концепции структурного программирования, исследователь формальной верификации и распределённых вычислений. Тьюринговский лауреат (1972).
Известность Дейкстре принесли его работы в области применения математической логики при разработке компьютерных программ. Он активно участвовал в разработке языка программирования Алгол и написал первый компилятор Алгол-60. Будучи одним из авторов концепции структурного программирования, он проповедовал отказ от использования инструкции GOTO. Также ему принадлежит идея применения «семафоров» для синхронизации процессов в многозадачных системах и алгоритм нахождения кратчайшего пути на ориентированном графе с неотрицательными весами рёбер, известный как алгоритм Дейкстры.
Ри́чард Фи́ллипс Фе́йнман (Фа́йнман) (англ. Richard Phillips Feynman; 11 мая 1918, Куинс, Нью-Йорк, США — 15 февраля 1988, Лос-Анджелес, США) — американский физик, основные достижения относятся к области теоретической физики и квантовой физики. Один из создателей квантовой электродинамики. Лауреат Нобелевской премии по физике (1965, совместно с С. Томонагой и Дж. Швингером).
В 1943—1945 годах входил в число разработчиков атомной бомбы в Лос-Аламосе. Разработал метод интегрирования по траекториям в квантовой механике (1948), а также так называемый метод диаграмм Фейнмана (1949) в квантовой теории поля, с помощью которых можно объяснять превращения элементарных частиц. Предложил партонную модель нуклона (1969), теорию квантованных вихрей. Реформатор методов преподавания физики в вузе.
🌐 Знаковые события
1997 — чемпион мира по шахматам Гарри Каспаров признал поражение в матче с компьютером IBM «Deep Blue».
#Biography #Birth_Date #Events #11мая
Э́дсгер Ви́бе Де́йкстра (нид. Edsger Wybe Dijkstra (11 мая 1930, Роттердам, Нидерланды — 6 августа 2002, Нюэнен, Нидерланды) — нидерландский учёный, труды которого оказали влияние на развитие информатики и информационных технологий; один из разработчиков концепции структурного программирования, исследователь формальной верификации и распределённых вычислений. Тьюринговский лауреат (1972).
Известность Дейкстре принесли его работы в области применения математической логики при разработке компьютерных программ. Он активно участвовал в разработке языка программирования Алгол и написал первый компилятор Алгол-60. Будучи одним из авторов концепции структурного программирования, он проповедовал отказ от использования инструкции GOTO. Также ему принадлежит идея применения «семафоров» для синхронизации процессов в многозадачных системах и алгоритм нахождения кратчайшего пути на ориентированном графе с неотрицательными весами рёбер, известный как алгоритм Дейкстры.
Ри́чард Фи́ллипс Фе́йнман (Фа́йнман) (англ. Richard Phillips Feynman; 11 мая 1918, Куинс, Нью-Йорк, США — 15 февраля 1988, Лос-Анджелес, США) — американский физик, основные достижения относятся к области теоретической физики и квантовой физики. Один из создателей квантовой электродинамики. Лауреат Нобелевской премии по физике (1965, совместно с С. Томонагой и Дж. Швингером).
В 1943—1945 годах входил в число разработчиков атомной бомбы в Лос-Аламосе. Разработал метод интегрирования по траекториям в квантовой механике (1948), а также так называемый метод диаграмм Фейнмана (1949) в квантовой теории поля, с помощью которых можно объяснять превращения элементарных частиц. Предложил партонную модель нуклона (1969), теорию квантованных вихрей. Реформатор методов преподавания физики в вузе.
1997 — чемпион мира по шахматам Гарри Каспаров признал поражение в матче с компьютером IBM «Deep Blue».
#Biography #Birth_Date #Events #11мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
[Совет по Java #035]
Тема:
Проблема:
При неперехваченном исключении поток умирает, печатая stack trace в stderr, но все последующие задачи никогда не выполняются. Это особенно опасно, так как исключение можно не заметить в логах, а критическая логика (очистка кешей, heartbeat'ы) перестанет работать.
Решение: Вместо
Объяснение:
После этого поток завершается, и
Кроме того,
#Java #советы
Тема:
java.util.Timer создает один поток для всех задач.Проблема:
Timer использует единственный фоновый поток для выполнения всех запланированных задач. При неперехваченном исключении поток умирает, печатая stack trace в stderr, но все последующие задачи никогда не выполняются. Это особенно опасно, так как исключение можно не заметить в логах, а критическая логика (очистка кешей, heartbeat'ы) перестанет работать.
Решение: Вместо
Timer используйте ScheduledThreadPoolExecutor из пакета java.util.concurrent. Он поддерживает пул потоков, и падение одной задачи не влияет на выполнение других. public class TimerVsScheduler {
//Антипаттерн: Timer умирает при исключении
public static void badTimer() throws InterruptedException {
Timer timer = new Timer("BadTimer");
// Задача, которая упадет
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("Падающая задача выполняется");
throw new RuntimeException("Ошибка в задаче!");
}
}, 0);
// Периодическая задача (должна выполняться каждые 500 мс)
timer.scheduleAtFixedRate(new TimerTask() {
private int count = 0;
@Override
public void run() {
System.out.println("Нормальная задача: " + (++count));
}
}, 500, 500);
Thread.sleep(2000);
// После падения первой задачи вторая перестала выполняться!
System.out.println("После исключения нормальная задача больше не выполняется");
}
//Решение: ScheduledThreadPoolExecutor
public static void goodScheduler() throws InterruptedException {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
// Падающая задача
scheduler.schedule(() -> {
System.out.println("Падающая задача выполняется");
throw new RuntimeException("Ошибка в задаче!");
}, 0, TimeUnit.MILLISECONDS);
// Периодическая задача
scheduler.scheduleAtFixedRate(() -> {
System.out.println("Нормальная задача выполняется: " + System.currentTimeMillis());
}, 500, 500, TimeUnit.MILLISECONDS);
Thread.sleep(2000);
System.out.println("Нормальная задача продолжает работать после исключения");
scheduler.shutdown();
}
public static void main(String[] args) throws InterruptedException {
System.out.println("=== Демонстрация проблемы Timer ===");
try {
badTimer();
} catch (Exception e) {
System.out.println("Timer упал целиком");
}
Thread.sleep(1000);
System.out.println("\n=== Демонстрация ScheduledThreadPoolExecutor ===");
goodScheduler();
}
}Объяснение:
TimerTask является подклассом Runnable, и если его метод run() выбрасывает исключение, то поток Timer не перехватывает его. После этого поток завершается, и
Timer переходит в некорректное состояние. ScheduledThreadPoolExecutor использует пул потоков, где каждый Runnable обернут в безопасный код, перехватывающий исключения. Даже если всё пул из нескольких потоков, падение одного потока не останавливает остальные, и пул создаст новый поток при необходимости.Кроме того,
ScheduledThreadPoolExecutor правильно обрабатывает ситуации, когда задача выполняется дольше интервала (в отличие от Timer, где это может вызвать смещение). Для фиксированного интервала между завершениями используйте scheduleWithFixedDelay.#Java #советы
👍4
13. Kafka: переход от очереди задач к журналу событий
RabbitMQ из прошлого видео — это очередь задач: сообщение исчезает после обработки. А если аналитический сервис захочет перечитать историю заказов за вчера?
Не получится.
В этом видео мы переходим от модели очереди к журналу событий (commit log) с помощью Apache Kafka.
Разбираем, почему Kafka — это не просто ещё один брокер, а архитектурный сдвиг: события не удаляются, а хранятся, и их могут читать множество независимых потребителей.
Исходный код проекта на GitHub наверняка заслуживает Ваших звезд!🙂
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!✌️
Буду крайне благодарен🙂
RabbitMQ из прошлого видео — это очередь задач: сообщение исчезает после обработки. А если аналитический сервис захочет перечитать историю заказов за вчера?
Не получится.
В этом видео мы переходим от модели очереди к журналу событий (commit log) с помощью Apache Kafka.
Разбираем, почему Kafka — это не просто ещё один брокер, а архитектурный сдвиг: события не удаляются, а хранятся, и их могут читать множество независимых потребителей.
Исходный код проекта на GitHub наверняка заслуживает Ваших звезд!
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!
Буду крайне благодарен
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Что выведет код?
#Tasks
import java.util.Timer;
import java.util.TimerTask;
public class Task110526 {
static int counter = 0;
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
counter++;
if (counter == 2) {
throw new RuntimeException("Boom!");
}
System.out.print("A" + counter + " ");
}
}, 0, 100);
Thread.sleep(450);
timer.cancel();
System.out.println("Done");
}
}
#Tasks
👍4
Варианты ответа:
Anonymous Quiz
55%
Сначала A1, потом исключение (в stderr), потом Done.
15%
A1 A2 A3 A4 Done
25%
A1 Done
5%
Исключение, Done
👍2
Please open Telegram to view this post
VIEW IN TELEGRAM
Telegram
Java Developer
👩💻 Autoboxing: одна из самых незаметных ловушек Java
В статье показывают, как автоматическая упаковка примитивов превращается в лишние объекты, нагрузку на GC и рост потребления памяти.
Особенно актуально сейчас, когда AI и cloud-инфраструктура снова делают…
В статье показывают, как автоматическая упаковка примитивов превращается в лишние объекты, нагрузку на GC и рост потребления памяти.
Особенно актуально сейчас, когда AI и cloud-инфраструктура снова делают…
🔥5
Что такое TreeMap? Какая у него сложность? 🤓
Ответ:
TreeMap — это реализация NavigableMap, основанная на красно-черном дереве (сбалансированное бинарное дерево поиска).
Ключи хранятся отсортированными (natural order или по переданному Comparator). Операции put, get, remove, containsKey имеют сложность O(log n).
В отличие от HashMap (O(1) в среднем), TreeMap медленнее, но предоставляет методы для работы с диапазонами: subMap(), headMap(), tailMap(), firstKey(), lastKey(), ceilingKey() и др. Ключи должны быть взаимно сравнимы.
#собеседование
Ответ:
Ключи хранятся отсортированными (natural order или по переданному Comparator). Операции put, get, remove, containsKey имеют сложность O(log n).
В отличие от HashMap (O(1) в среднем), TreeMap медленнее, но предоставляет методы для работы с диапазонами: subMap(), headMap(), tailMap(), firstKey(), lastKey(), ceilingKey() и др. Ключи должны быть взаимно сравнимы.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
История технологии сегодня — 12 мая
ℹ️ Кто родился в этот день
Я́ков Моде́стович Га́ккель (30 апреля [12 мая] 1874, Иркутск — 12 декабря 1945, Ленинград) — русский и советский инженер-изобретатель, внёсший значительный вклад в развитие отечественного самолёто- и тепловозостроения первой половины XX века, автор многих научных работ и изобретений, учёный-электротехник.
🌐 Знаковые события
2010 — запущен национальный домен верхнего уровня для России .рф, первый в Интернете домен на кириллице.
2017 — начал распространение сетевой червь-вымогатель WannaCry, который поразил более 200 тысяч компьютеров под Microsoft Windows в более чем 150 странах мира.
2022 — телескоп горизонта событий получил изображение сверхмассивной черной дыры Стрелец А* (Sgr A*).
#Biography #Birth_Date #Events #12мая
Я́ков Моде́стович Га́ккель (30 апреля [12 мая] 1874, Иркутск — 12 декабря 1945, Ленинград) — русский и советский инженер-изобретатель, внёсший значительный вклад в развитие отечественного самолёто- и тепловозостроения первой половины XX века, автор многих научных работ и изобретений, учёный-электротехник.
2010 — запущен национальный домен верхнего уровня для России .рф, первый в Интернете домен на кириллице.
2017 — начал распространение сетевой червь-вымогатель WannaCry, который поразил более 200 тысяч компьютеров под Microsoft Windows в более чем 150 странах мира.
2022 — телескоп горизонта событий получил изображение сверхмассивной черной дыры Стрелец А* (Sgr A*).
#Biography #Birth_Date #Events #12мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2
Раздел 9. Исключения, логирование, отладка
Глава 2. Логирование (Logging)
Подключение SLF4J + Logback в проект (Maven/Gradle). Базовый пример получения логгера
Для использования SLF4J с Logback требуется две основные зависимости:
Указание
В Gradle Kotlin DSL:
Правило единственного binding
Критически важное правило classpath: должен присутствовать ровно один SLF4J binding. Наличие нескольких bindings приводит к предупреждению при старте и непредсказуемому выбору реализации. Типичная ошибка — транзитивное включение нескольких реализаций через зависимости.
Для разрешения конфликтов используется исключение транзитивных зависимостей:
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
Глава 2. Логирование (Logging)
Подключение SLF4J + Logback в проект (Maven/Gradle). Базовый пример получения логгера
Для использования SLF4J с Logback требуется две основные зависимости:
slf4j-api — фасадный интерфейс, и logback-classic — реализация, включающая нативный binding для SLF4J. Важно понимать, что logback-classic транзитивно подтягивает logback-core и slf4j-api, поэтому явное объявление slf4j-api не обязательно, но рекомендуется для явности контракта.<dependencies>
<!-- Фасадный API, обязателен для компиляции -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<!-- Реализация Logback с нативным SLF4J binding -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
<scope>runtime</scope>
</dependency>
</dependencies>
Указание
scope как runtime для logback-classic корректно, потому что код приложения напрямую не ссылается на классы Logback — только на SLF4J API. Компилятору достаточно интерфейсов, а реализация требуется только при выполнении. Однако на практике часто оставляют compile scope для простоты, особенно если конфигурация Logback загружается программно.dependencies {
implementation 'org.slf4j:slf4j-api:2.0.9'
runtimeOnly 'ch.qos.logback:logback-classic:1.4.11'
}В Gradle Kotlin DSL:
dependencies {
implementation("org.slf4j:slf4j-api:2.0.9")
runtimeOnly("ch.qos.logback:logback-classic:1.4.11")
}Правило единственного binding
Критически важное правило classpath: должен присутствовать ровно один SLF4J binding. Наличие нескольких bindings приводит к предупреждению при старте и непредсказуемому выбору реализации. Типичная ошибка — транзитивное включение нескольких реализаций через зависимости.
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:.../logback-classic-1.4.11.jar]
SLF4J: Found binding in [jar:file:.../slf4j-simple-2.0.9.jar]
SLF4J: See https://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
Для разрешения конфликтов используется исключение транзитивных зависимостей:
<!-- Maven: исключение конфликтующего binding -->
<dependency>
<groupId>com.some.library</groupId>
<artifactId>library-with-log4j</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
// Gradle: исключение конфликтующего binding
implementation('com.some.library:library-with-log4j:1.0') {
exclude group: 'org.slf4j', module: 'slf4j-log4j12'
}
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
👍4
Базовый пример получения логгера
Конвенция получения логгера в SLF4J строго определена:
Ключевые конвенции именования:
Поле объявляется
Имя поля —
В Lombok доступна аннотация
Spring Boot: автоматическая конфигурация
Spring Boot радикально упрощает подключение логирования. Стартер
Где находятся зависимости
Стартер
Maven для Spring Boot
Gradle для Spring Boot
Проверка подключенных зависимостей
Для проверки фактического дерева зависимостей используются команды:
Ожидаемый вывод для Spring Boot:
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
Конвенция получения логгера в SLF4J строго определена:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PaymentService {
// Конвенция: private static final, имя logger или LOG
private static final Logger logger = LoggerFactory.getLogger(PaymentService.class);
public void processPayment(String paymentId) {
logger.debug("Starting payment processing for id={}", paymentId);
try {
executePayment(paymentId);
logger.info("Payment {} processed successfully", paymentId);
} catch (PaymentException e) {
logger.error("Payment {} failed: {}", paymentId, e.getMessage(), e);
}
}
}
LoggerFactory.getLogger(Class<?>) создает именованный логгер с полным именем класса (com.example.service.PaymentService). Это имя формирует иерархию в конфигурации, позволяя управлять уровнем детализации на уровне пакета или класса. Альтернативный вариант — LoggerFactory.getLogger(String name) для произвольного имени, используемый при динамическом создании логгеров.Ключевые конвенции именования:
Поле объявляется
private static final для единственного экземпляра на классИмя поля —
logger (camelCase) или LOG (UPPER_CASE) в зависимости от code style командыВ Lombok доступна аннотация
@Slf4j, генерирующая поле автоматическиSpring Boot: автоматическая конфигурация
Spring Boot радикально упрощает подключение логирования. Стартер
spring-boot-starter-logging транзитивно включает logback-classic, slf4j-api и необходимые bridges. Это означает, что в типичном Spring Boot проекте никаких дополнительных зависимостей для логирования подключать не требуется.Где находятся зависимости
Стартер
spring-boot-starter-web или spring-boot-starter уже включает spring-boot-starter-logging, который разрешается в следующий набор:org.springframework.boot:spring-boot-starter-logging
ch.qos.logback:logback-classic
org.apache.logging.log4j:log4j-to-slf4j
org.slf4j:jul-to-slf4j
log4j-to-slf4j и jul-to-slf4j — bridges, перенаправляющие вызовы из Log4j API и java.util.logging в SLF4J. Это обеспечивает единый канал логирования даже если транзитивные зависимости используют разные API.Maven для Spring Boot
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
<dependencies>
<!-- Транзитивно включает logback-classic и slf4j-api -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Явное подключение не требуется, но допустимо для управления версией -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
</dependencies>
Gradle для Spring Boot
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
// Никаких дополнительных зависимостей для логирования
}Проверка подключенных зависимостей
Для проверки фактического дерева зависимостей используются команды:
# Maven
mvn dependency:tree | grep -E "(slf4j|logback|log4j)"
# Gradle
gradle dependencies --configuration runtimeClasspath | grep -E "(slf4j|logback|log4j)"
Ожидаемый вывод для Spring Boot:
+--- org.springframework.boot:spring-boot-starter-logging -> 3.2.0
| +--- ch.qos.logback:logback-classic:1.4.11
| | +--- ch.qos.logback:logback-core:1.4.11
| | \--- org.slf4j:slf4j-api:2.0.9
| +--- org.apache.logging.log4j:log4j-to-slf4j:2.21.1
| \--- org.slf4j:jul-to-slf4j:2.0.9
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
👍5
Исключение Logback в пользу Log4j2
Spring Boot по умолчанию использует Logback, но позволяет переключиться на Log4j2. Это требует исключения
Конфигурация в Spring Boot проектах
Spring Boot автоматически загружает конфигурацию Logback из файлов в порядке приоритета:
Файл размещается в
Интеграция с application.properties
Spring Boot позволяет управлять уровнями логирования через
Эти свойства переопределяют или дополняют XML-конфигурацию. При наличии
Пример logback-spring.xml с профилями
Элемент
#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
Spring Boot по умолчанию использует Logback, но позволяет переключиться на Log4j2. Это требует исключения
spring-boot-starter-logging и подключения spring-boot-starter-log4j2:<!-- Maven: переход на Log4j2 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
</dependencies>
// Gradle: переход на Log4j2
dependencies {
implementation('org.springframework.boot:spring-boot-starter-web') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
}
Конфигурация в Spring Boot проектах
Spring Boot автоматически загружает конфигурацию Logback из файлов в порядке приоритета:
logback-spring.xml — предпочтительный вариант, поддерживает расширения Spring (профили, свойства окружения)logback.xml — стандартный файл конфигурации Logback, загружается напрямую без Spring-расширенийlogback-test.xml — для тестового classpath, имеет приоритет над production-конфигурацией в тестахФайл размещается в
src/main/resources/ для production или src/test/resources/ для тестовой конфигурации.Интеграция с application.properties
Spring Boot позволяет управлять уровнями логирования через
application.properties без XML-конфигурации:# Корневой уровень
logging.level.root=INFO
# Уровень для пакета
logging.level.com.example.service=DEBUG
# Уровень для конкретного класса
logging.level.com.example.service.PaymentService=TRACE
# Формат вывода
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
# Файл логов
logging.file.name=application.log
logging.file.path=/var/log/myapp
Эти свойства переопределяют или дополняют XML-конфигурацию. При наличии
logback-spring.xml свойства application.properties применяются через механизм Spring Boot, который инжектирует значения в Logback configuration.Пример logback-spring.xml с профилями
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<springProfile name="dev">
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<springProfile name="prod">
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/var/log/app/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/var/log/app/application.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
</root>
</springProfile>
</configuration>
Элемент
<springProfile> доступен только в logback-spring.xml, не в стандартном logback.xml. Он активирует конфигурацию на основе active Spring profiles, что позволяет разделять настройки для development, staging и production без дублирования файлов.#Java #для_новичков #beginner #logging #Log4j2 #Logback #SLF4J
👍4
Что выведет код?
#Tasks
import java.time.*;
import java.time.temporal.ChronoUnit;
public class ZonedDateTimeTricky {
public static void main(String[] args) {
ZonedDateTime utc = ZonedDateTime.of(2025, 1, 1, 12, 0, 0, 0, ZoneId.of("UTC"));
ZonedDateTime paris = ZonedDateTime.of(2025, 1, 1, 13, 0, 0, 0, ZoneId.of("Europe/Paris"));
System.out.print(utc.equals(paris));
System.out.print(" " + utc.isEqual(paris));
}
}
#Tasks
👍2
👍2
Что такое Comparable vs Comparator? 🤓
Ответ:
Comparable имеет метод compareTo(T o), возвращающий отрицательное число, 0 или положительное.
Реализуется самим классом и определяет естественный порядок (например, у чисел по возрастанию, у строк лексикографически).
Comparator имеет метод compare(T o1, T o2). Это отдельный класс, определяющий альтернативный порядок сортировки. Comparator часто реализуется лямбдами: (a, b) -> a.getValue() - b.getValue().
Можно создавать цепочки сравнений через thenComparing(). Оба требуют согласованности с equals() (не строго, но желательно).
#собеседование
Ответ:
Реализуется самим классом и определяет естественный порядок (например, у чисел по возрастанию, у строк лексикографически).
Comparator имеет метод compare(T o1, T o2). Это отдельный класс, определяющий альтернативный порядок сортировки. Comparator часто реализуется лямбдами: (a, b) -> a.getValue() - b.getValue().
Можно создавать цепочки сравнений через thenComparing(). Оба требуют согласованности с equals() (не строго, но желательно).
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
История технологии сегодня — 13 мая
ℹ️ Кто родился в этот день
Моисе́й Алекса́ндрович Ма́рков (30 апреля [13 мая] 1908; Рассказово, Тамбовская губерния — 1 октября 1994; Москва) — советский и российский физик-теоретик. Основные работы по квантовой механике и физике элементарных частиц. Предложил теорию так называемых нелокализуемых полей в виде некоммутативности поля и координаты. Разработал составную модель элементарных частиц, на основе которой предсказывал возможность возбуждённых состояний адронов. Ему принадлежат фундаментальные исследования по физике нейтрино. Обосновал целесообразность проведения нейтринных экспериментов на больших глубинах под землёй и возможность проведения нейтринных опытов на ускорителях. Впервые выдвинул гипотезу о том, что полные сечения рассеяния лептонов на нуклонах с ростом энергии стремятся к сечениям упругих рассеяний на точечных нуклонах. Выдвинул идею о возможном существовании элементарных частиц предельно больших масс — максимонов, а также фридмонов — частиц с микроскопическими полной массой и размерами, являющихся по своей структуре почти замкнутыми вселенными.
🌐 Знаковые события
1991 — корпорация «Apple» выпустила в продажу «Macintosh System 7.0».
#Biography #Birth_Date #Events #13мая
Моисе́й Алекса́ндрович Ма́рков (30 апреля [13 мая] 1908; Рассказово, Тамбовская губерния — 1 октября 1994; Москва) — советский и российский физик-теоретик. Основные работы по квантовой механике и физике элементарных частиц. Предложил теорию так называемых нелокализуемых полей в виде некоммутативности поля и координаты. Разработал составную модель элементарных частиц, на основе которой предсказывал возможность возбуждённых состояний адронов. Ему принадлежат фундаментальные исследования по физике нейтрино. Обосновал целесообразность проведения нейтринных экспериментов на больших глубинах под землёй и возможность проведения нейтринных опытов на ускорителях. Впервые выдвинул гипотезу о том, что полные сечения рассеяния лептонов на нуклонах с ростом энергии стремятся к сечениям упругих рассеяний на точечных нуклонах. Выдвинул идею о возможном существовании элементарных частиц предельно больших масс — максимонов, а также фридмонов — частиц с микроскопическими полной массой и размерами, являющихся по своей структуре почти замкнутыми вселенными.
1991 — корпорация «Apple» выпустила в продажу «Macintosh System 7.0».
#Biography #Birth_Date #Events #13мая
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
[Совет по Java #037]
Тема:
Проблема: Метод
Он не выбрасывает исключение при ошибке (например, файл не существует, нет прав доступа, файл занят другим процессом). Разработчики часто игнорируют возвращаемое значение, полагая, что удаление гарантированно произойдет. Это приводит к тому, что приложение продолжает работу с неверным предположением об отсутствии файла, что может вызвать логические ошибки, повторные попытки записи, или накопление "мусорных" файлов.
Решение: Используйте современный NIO API:
Для неблокирующего удаления используйте
Объяснение: legacy API
NIO API (
#Java #советы
Тема:
File.delete() не бросает исключение при неудаче.Проблема: Метод
java.io.File.delete() возвращает boolean — true при успешном удалении, false в противном случае. Он не выбрасывает исключение при ошибке (например, файл не существует, нет прав доступа, файл занят другим процессом). Разработчики часто игнорируют возвращаемое значение, полагая, что удаление гарантированно произойдет. Это приводит к тому, что приложение продолжает работу с неверным предположением об отсутствии файла, что может вызвать логические ошибки, повторные попытки записи, или накопление "мусорных" файлов.
Решение: Используйте современный NIO API:
java.nio.file.Files.delete(Path), который выбрасывает четкие исключения: NoSuchFileException, DirectoryNotEmptyException, AccessDeniedException. Альтернативно, проверяйте возвращаемое значение File.delete() и бросайте собственное исключение. Для неблокирующего удаления используйте
Files.deleteIfExists(), который возвращает boolean, но не выбрасывает исключение при отсутствии файла (однако при других ошибках исключение будет).public class FileDeleteExample {
//Антипаттерн: игнорирование возвращаемого значения
public static void badDelete(String path) {
File file = new File(path);
file.delete(); // Возврат значения проигнорирован - ошибка не будет замечена
System.out.println("Файл " + path + " удален (предположительно)");
// Если файл не удалился, программа об этом не знает
}
//Недостаточно: проверка без обработки
public static void insufficientCheck(String path) {
File file = new File(path);
if (!file.delete()) {
System.out.println("Не удалось удалить файл"); // Нет информации о причине
}
}
//Решение 1: Files.delete() с исключениями (рекомендуется)
public static void goodDeleteNio(String path) {
try {
Files.delete(Path.of(path));
System.out.println("Файл успешно удален: " + path);
} catch (NoSuchFileException e) {
System.err.println("Файл не существует: " + path);
} catch (DirectoryNotEmptyException e) {
System.err.println("Каталог не пуст: " + path);
} catch (AccessDeniedException e) {
System.err.println("Нет прав на удаление: " + path);
} catch (IOException e) {
System.err.println("Ошибка удаления: " + e.getMessage());
}
}
//Решение 2: deleteIfExists() - не выбрасывает исключение при отсутствии файла
public static void goodDeleteIfExists(String path) throws IOException {
boolean deleted = Files.deleteIfExists(Path.of(path));
if (deleted) {
System.out.println("Файл удален");
} else {
System.out.println("Файл не существовал");
}
// Другие ошибки (доступ, занятость) все равно выбросят IOException
}
//Решение 3: проверка возвращаемого значения с собственным исключением
public static void checkedFileDelete(String path) throws IOException {
File file = new File(path);
if (!file.delete()) {
throw new IOException("Не удалось удалить файл: " + path +
" (файл существует? " + file.exists() +
", можно записать? " + file.canWrite() + ")");
}
}
}Объяснение: legacy API
java.io.File был спроектирован в ранних версиях Java с использованием возвращаемых кодов ошибок вместо исключений. Это приводило к ненадежному коду, так как разработчики часто игнорировали проверку. NIO API (
java.nio.file) в Java 7+ исправил этот недостаток, используя исключения для всех ошибок ввода-вывода. Files.delete() выбрасывает IOException с конкретным типом, позволяя обрабатывать разные сценарии. Files.deleteIfExists() удобен, когда отсутствие файла не является ошибкой (например, очистка временных файлов).#Java #советы
👍5
Что выведет код?
#Tasks
import java.io.File;
import java.io.IOException;
public class Task130526 {
public static void main(String[] args) throws IOException {
File file = new File("test.txt");
file.createNewFile();
File dir = new File("testDir");
dir.mkdir();
System.out.print(file.delete() + " ");
System.out.print(file.delete() + " ");
System.out.print(dir.delete() + " ");
dir.mkdir();
File fileInDir = new File(dir, "test.txt");
fileInDir.createNewFile();
System.out.print(dir.delete());
}
}
#Tasks
👍2
Варианты ответа:
Anonymous Quiz
12%
true false false true
59%
true false true false
12%
true true true true
18%
true false false false
👍3
