Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥2
Симметричность – это свойство, при котором если A связано с B, то B связано с A.
В логике и алгебре отношение \( R \) называется симметричным, если:
a R b \Rightarrow b R a
Но, например, отношение "a > b" не симметрично, потому что если a > b, то b > a – это неверно.
В Java симметричность важна при переопределении метода
equals(). Если
a.equals(b) == true, то обязательно должно быть b.equals(a) == true. Ошибочный код (нарушает симметричность) class Person {
String name;
Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof String) { // ❌ Сравниваем с String (ошибка)
return this.name.equals(obj);
}
return false;
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person("Alice");
System.out.println(p.equals("Alice")); // true
System.out.println("Alice".equals(p)); // false ❌ (нарушена симметричность)
}
}Правильный способ
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return name.equals(person.name);
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8💊4
Нет, ключи в Map не могут повторяться. Если вставить новую пару с уже существующим ключом — старое значение будет перезаписано.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🤔2
Функциональный интерфейс —это интерфейс, который содержит только один абстрактный метод. Это позволяет использовать лямбда-выражения для создания его анонимных реализаций, делая код более лаконичным и читаемым. Функциональные интерфейсы являются основой для лямбда-выражений и методов ссылок, начиная с версии 8.
Примером этого может служить интерфейс
java.util.function.Predicate<T> который принимает объект типа T и возвращает значение типа boolean. Вот пример использования:Predicate<String> isNotEmpty = s -> !s.isEmpty();
System.out.println(isNotEmpty.test("Hello")); // Выведет true
System.out.println(isNotEmpty.test("")); // Выведет falseЧтобы явно указать, что интерфейс предназначен для использования как функциональный, используется аннотация
@FunctionalInterface. Эта аннотация не обязательна (компилятор может определить функциональный интерфейс и без неё), но она помогает в документировании кода и обеспечивает проверку времени компиляции, гарантируя, что интерфейс содержит только один абстрактный метод.@FunctionalInterface
public interface SimpleFunction {
int apply(int value);
}
// Использование
SimpleFunction triple = value -> value * 3;
System.out.println(triple.apply(5)); // Выведет 15Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
- DOM (Document Object Model): загружает весь XML в память в виде дерева.
Плюсы: лёгкий доступ к любому узлу; Минусы: высокая потребляемая память при больших файлах.
- SAX (Simple API for XML): событийный парсер, обрабатывает XML последовательно.
Плюсы: низкое потребление памяти; Минусы: нет прямого доступа к элементам, труднее работать.
- StAX (Streaming API for XML): потоковый парсер с возможностью контролировать чтение.
Плюсы: баланс между SAX и DOM, лучше управляем поток; Минусы: сложнее логика обработки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥10
Когда разработчик пушит код, он проходит несколько этапов перед развертыванием в продакшене. Этот процесс автоматизируется с помощью CI/CD (Continuous Integration / Continuous Deployment).
- Код отправляется в GitHub, GitLab, Bitbucket или другой репозиторий.
- Открывается Pull Request (PR) для ревью.
git add .
git commit -m "Добавлена новая фича"
git push origin feature-branch
После пуша CI-сервер (Jenkins, GitHub Actions, GitLab CI/CD, CircleCI)** запускает автоматические тесты и сборку.
Клонирование репозитория.
Сборка проекта (например,
mvn package для Java). Запуск юнит-тестов (
JUnit, Mockito). Запуск интеграционных тестов (например,
TestContainers). Анализ кода (SonarQube).
name: CI Pipeline
on:
push:
branches:
- main
- develop
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Java
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Build project
run: mvn clean package
- name: Run tests
run: mvn test
После успешного CI код автоматически разворачивается в стейджинг (staging) – это тестовая среда, похожая на продакшен.
Развёртывание может происходить с помощью:
Docker + Kubernetes (K8s)
AWS CodeDeploy, GitLab CD
Terraform + Ansible
FROM openjdk:17
COPY target/app.jar /app.jar
CMD ["java", "-jar", "/app.jar"]
Проверяется чистота кода, читаемость и ошибки.
В некоторых компаниях код проходит Security Review
git merge feature-branch
git push origin main
Blue-Green Deployment – новый код разворачивается на отдельном сервере, затем трафик переключается.
Canary Release – новый код деплоится на 5-10% пользователей, если всё хорошо – на всех.
Rolling Deployment – обновление происходит поэтапно, без даунтайма.
deploy:
stage: deploy
script:
- kubectl apply -f deployment.yaml
only:
- main
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥4💊1
FutureTask — это класс, представляющий асинхронную задачу, которая может быть запущена в другом потоке. Позволяет получить результат выполнения в будущем через методы get() и проверять состояние выполнения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍5
В Java у каждого потока есть приоритет, но он не гарантирует порядок выполнения.
Java позволяет задавать приоритет потока с помощью метода
setPriority(), который принимает значение от 1 до 10: Thread.MIN_PRIORITY (1) – минимальный приоритет Thread.NORM_PRIORITY (5) – стандартный приоритет (по умолчанию) Thread.MAX_PRIORITY (10) – максимальный приоритет class MyThread extends Thread {
public MyThread(String name, int priority) {
super(name);
setPriority(priority);
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(getName() + " выполняется с приоритетом " + getPriority());
}
}
}
public class Main {
public static void main(String[] args) {
MyThread low = new MyThread("Low Priority", Thread.MIN_PRIORITY);
MyThread high = new MyThread("High Priority", Thread.MAX_PRIORITY);
low.start();
high.start();
}
}Приоритет – это всего лишь рекомендация для ОС.
Распределение процессорного времени зависит от планировщика ОС.
В Windows, Linux, macOS приоритеты работают по-разному, и Java не контролирует их на низком уровне.
Реальные способы управления порядком выполнения:
а) Использование
join()Позволяет дождаться выполнения одного потока перед запуском другого.
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread high = new MyThread("High Priority", Thread.MAX_PRIORITY);
Thread low = new MyThread("Low Priority", Thread.MIN_PRIORITY);
high.start();
high.join(); // Ждём, пока high завершится
low.start(); // Теперь запускается low
}
}б) Использование
Executors.newSingleThreadExecutor() Позволяет гарантированно выполнять потоки по очереди.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> System.out.println("Задача 1"));
executor.submit(() -> System.out.println("Задача 2"));
executor.shutdown();
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥2
Строки — неизменяемые (immutable) и живут в памяти столько, сколько на них существуют ссылки.
Если строка находится в String Pool'е, она хранится до завершения работы JVM, если не используется механизм очистки пула (в зависимости от версии Java и GC).
Обычные строки (например, созданные через new) живут как обычные объекты — пока есть ссылки, потом собираются сборщиком мусора.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥5
Все три аннотации используются в Spring для создания бинов, но у каждой есть своё предназначение.
@Component помечает класс как Spring-бин (компонент). Является универсальной аннотацией.
Можно применять к любым классам, которые должны управляться Spring-контейнером.
@Component
public class MyComponent {
public void doWork() {
System.out.println("Работа компонента");
}
}
@Service – это специализированный @Component, используемый для сервисных классов (логика приложения). Упрощает понимание кода (показывает, что этот класс содержит бизнес-логику).
@Service
public class UserService {
public String getUser() {
return "Пользователь Иван";
}
}
@Repository – это специализированный @Component для слоя доступа к данным (DAO, Repository). Автоматически перехватывает SQL-исключения (
PersistenceExceptionTranslationPostProcessor) и преобразует их в DataAccessException. @Repository
public class UserRepository {
public String findUserById(int id) {
return "Пользователь с ID " + id;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍24
В JDBC используются:
- Statement — для простых SQL-запросов без параметров.
- PreparedStatement — для запросов с параметрами, безопасен от SQL-инъекций и переиспользуем.
- CallableStatement — для вызова хранимых процедур из базы данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16🔥1
CAP-теорема (Consistency, Availability, Partition Tolerance) утверждает, что в распределенной системе невозможно одновременно обеспечить три свойства:
все узлы видят одни и те же данные в один момент времени.
каждый запрос получает ответ, даже если некоторые узлы вышли из строя.
система продолжает работать, даже если сеть разделилась на изолированные части.
Рассмотрим сценарий с распределенной системой, состоящей из двух узлов (A и B), которые могут обмениваться данными.
узлы A и B больше не могут обмениваться данными.
Теперь у нас есть выбор
это значит, что данные на A и B должны оставаться идентичными. Однако, так как они не могут обмениваться данными, запросы к B не могут быть обработаны до восстановления связи (нарушается доступность).
это значит, что оба узла должны продолжать отвечать на запросы. Однако, так как они не могут синхронизироваться, данные на A и B могут отличаться (нарушается согласованность). Так как разделение сети (P) может произойти в реальных условиях, система вынуждена выбирать между C и A. Таким образом, невозможно одновременно обеспечить все три свойства (C, A, P).
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🤔5
2. URL Rewriting: Добавление идентификатора сессии в параметры URL.
3. Hidden Form Fields: Передача идентификатора сессии через скрытые поля формы.
4. HTTP Session: Использование объекта HttpSession для хранения данных сессии на сервере.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2
Ограничения (constraints) – это правила, которые ограничивают возможные значения данных или ограничивают поведение системы.
В SQL ограничения гарантируют корректность данных в таблицах.
CREATE TABLE Users (
id INT PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
age INT CHECK (age > 0),
country VARCHAR(50) DEFAULT 'Unknown'
);
Ограничения в Generics позволяют задавать допустимые типы.
class Box<T> {
T value;
public Box(T value) { this.value = value; }
}
Box<String> strBox = new Box<>("Hello");
Box<Integer> intBox = new Box<>(10);class NumberBox<T extends Number> { // Ограничение: T должно быть числом
T value;
public NumberBox(T value) { this.value = value; }
public double square() {
return value.doubleValue() * value.doubleValue();
}
}В многопоточности ограничения помогают избежать гонок потоков.
class Counter {
private int count = 0;
public synchronized void increment() { // Только один поток может изменять count одновременно
count++;
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Основные реализации интерфейса List:
- ArrayList — динамический массив.
- LinkedList — двусвязный список.
- Vector — потокобезопасная версия ArrayList (устаревшая).
- Stack — расширяет Vector, LIFO-структура.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥3🤔2
Это компонент, который отвечает за отправку логов в различные места назначения, такие как файлы, консоль, базы данных, сетевые сокеты или даже удаленные серверы. Каждый Appender реализует конкретный способ обработки и хранения логов.
Appender позволяет гибко управлять тем, куда и как сохраняются логи. В зависимости от требований приложения, вы можете:
Писать логи в файл.
Выводить их в консоль.
Отправлять их в удалённые хранилища или базы данных.
Логи выводятся в консоль.
Полезно для разработки и отладки.
<Appender type="Console" name="ConsoleAppender">
<Target>System.out</Target>
</Appender>
Логи записываются в файл.
Используется для длительного хранения логов.
<Appender type="File" name="FileAppender">
<FileName>logs/app.log</FileName>
<Append>true</Append>
</Appender>
Расширение FileAppender с возможностью ротации логов (ограничение размера файла, создание новых файлов при переполнении).
<Appender type="RollingFile" name="RollingFileAppender">
<FileName>logs/app.log</FileName>
<FilePattern>logs/app-%d{yyyy-MM-dd}.log</FilePattern>
<Policies>
<SizeBasedTriggeringPolicy size="10MB"/>
</Policies>
</Appender>
Логи записываются в файл, который ротационно создаётся каждый день.
<Appender type="DailyRollingFile" name="DailyRollingAppender">
<FileName>logs/app.log</FileName>
<DatePattern>.yyyy-MM-dd</DatePattern>
</Appender>
Отправляет логи через сеть (TCP или UDP).
Используется для централизованного логирования.
Записывает логи в базу данных.
<Appender type="JDBC" name="JDBCAppender">
<ConnectionSource>
<DriverManagerConnectionSource>
<DriverClass>org.h2.Driver</DriverClass>
<Url>jdbc:h2:mem:logdb</Url>
<User>sa</User>
</DriverManagerConnectionSource>
</ConnectionSource>
<TableName>log_table</TableName>
</Appender>
Вот пример конфигурации с использованием нескольких Appender
XML-конфигурация
<Configuration>
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level: %msg%n"/>
</Console>
<File name="FileAppender" fileName="logs/app.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level: %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="FileAppender"/>
</Root>
</Loggers>
</Configuration>
Java-конфигурация
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Main {
private static final Logger logger = LogManager.getLogger(Main.class);
public static void main(String[] args) {
logger.info("This is an info log");
logger.error("This is an error log");
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Временная сложность — это оценка времени выполнения алгоритма в зависимости от размера входных данных. Измеряется через нотацию O(...) и помогает сравнивать эффективность алгоритмов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🤔1
COMMIT – это команда в SQL, которая фиксирует (сохраняет) изменения, сделанные внутри транзакции. После выполнения COMMIT изменения становятся постоянными и их уже нельзя отменить. Простой пример использования
COMMITBEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT; -- Сохраняем изменения
Что будет, если НЕ выполнить
COMMIT? BEGIN TRANSACTION;
UPDATE users SET age = 30 WHERE id = 1;
COMMIT vs ROLLBACK BEGIN TRANSACTION;
UPDATE orders SET status = 'CANCELLED' WHERE id = 10;
ROLLBACK; -- ОТМЕНЯЕМ изменения, данные не меняются
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8💊1
Согласно контракту:
- obj.equals(null) должен возвращать false, не NullPointerException.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍10💊5
Spring и Spring Boot являются частью экосистемы, которая предоставляет широкий спектр инструментов для разработки современных Java-приложений. Несмотря на тесную связь, между ними есть ключевые отличия.
Это мощный и широко используемый фреймворк для разработки приложений на Java. Он предоставляет обширный набор функциональностей, включая инверсию управления (IoC) и внедрение зависимостей (DI), абстракции для работы с транзакциями, обработку исключений, поддержку аспектно-ориентированного программирования (AOP) и многое другое. Он предназначен для упрощения Java EE разработки, обеспечивая легкость создания масштабируемых и легко поддерживаемых приложений.
С другой стороны, представляет собой расширение Spring Framework, предназначенное для упрощения процесса конфигурации и развертывания Spring-приложений. Он автоматизирует многие процессы, предоставляя "готовые к использованию" настройки для быстрого старта проектов и избавления от необходимости вручную определять стандартную конфигурацию.
Spring Framework предоставляет основу для создания приложений на Java, в то время как Spring Boot предлагает конвенции и автоматическую конфигурацию для быстрого старта и развертывания приложений.
В Spring для настройки приложения часто требуется детальная конфигурация, включая XML-файлы или аннотации. Spring Boot стремится уменьшить эту сложность, автоматически конфигурируя компоненты на основе добавленных в проект зависимостей.
Spring Boot по умолчанию включает в себя встроенный сервер приложений, что упрощает развертывание и тестирование веб-приложений.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12💊2