ApplicationContext — это контейнер Spring, расширяющий функциональность BeanFactory. Он управляет жизненным циклом бинов, предоставляет доступ к ресурсам, событийному механизму, авто-конфигурации, поддерживает аннотации, AOP и другие функции фреймворка.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
LEFT JOIN, RIGHT JOIN и INNER JOIN являются операциями соединения таблиц, каждая из которых используется для объединения строк из двух или более таблиц на основе связанных столбцов между ними. Различие между этими типами соединений заключается в том, какие строки выбираются для включения в результаты запроса.
Возвращает только те строки, которые имеют соответствующие значения в обеих таблицах. Если совпадение не найдено, строки не включаются в результаты. Это наиболее часто используемый тип соединения, так как он обеспечивает строгое соответствие между таблицами.
Возвращает все строки из левой таблицы (
ТаблицаA), а также соответствующие строки из правой таблицы (ТаблицаB). Если совпадение в правой таблице не найдено, результат будет содержать NULL на месте столбцов правой таблицы.Работает аналогично
LEFT JOIN, но возвращает все строки из правой таблицы (ТаблицаB), а также соответствующие строки из левой таблицы (ТаблицаA). Если совпадение в левой таблице не найдено, результат будет содержать NULL на месте столбцов левой таблицы.INNER JOIN используется для получения строк с совпадениями в обеих таблицах.LEFT JOIN возвращает все строки из левой таблицы и соответствующие строки из правой таблицы; если соответствий нет, вместо столбцов правой таблицы будут NULL.RIGHT JOIN возвращает все строки из правой таблицы и соответствующие строки из левой таблицы; если соответствий нет, вместо столбцов левой таблицы будут NULL.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Типы ограничений:
- NOT NULL — поле не может быть пустым.
- UNIQUE — уникальные значения.
- PRIMARY KEY — идентификатор строки.
- FOREIGN KEY — ссылка на другую таблицу.
- CHECK — ограничение значений по условию.
- DEFAULT — значение по умолчанию.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥2
Это два интерфейса в JDBC, которые используются для выполнения SQL-запросов к базе данных. Основные различия между ними касаются производительности, безопасности и удобства использования.
Statement используется для выполнения простых SQL-запросов. Запросы формируются и передаются в базу данных в виде строки. Подходит для простых запросов. Не оптимизирован для повторного выполнения. Каждый раз, когда запрос передается в базу данных, он компилируется и выполняется заново. Уязвим к SQL-инъекциям. Поскольку запрос формируется путем конкатенации строк, злоумышленники могут внедрять вредоносный SQL-код.
Statement stmt = connection.createStatement();
String query = "SELECT * FROM employees WHERE department = 'HR'";
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
stmt.close();
PreparedStatement используется для выполнения предварительно скомпилированных SQL-запросов. Это позволяет повысить производительность и безопасность. Оптимизирован для повторного выполнения. Запрос компилируется только один раз, а затем может многократно выполняться с разными параметрами, что повышает производительность. Защита от SQL-инъекций. Использует параметризованные запросы, которые помогают избежать уязвимостей, связанных с SQL-инъекциями. Удобство работы с параметрами. Позволяет устанавливать значения параметров с использованием методов setInt(), setString() и других.
String query = "SELECT * FROM employees WHERE department = ?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, "HR");
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
pstmt.close();
Statement: Каждый запрос компилируется заново, что снижает производительность при многократном выполнении одного и того же запроса.PreparedStatement: Запрос компилируется один раз и может многократно выполняться с разными параметрами, что повышает производительность.Statement: Уязвим к SQL-инъекциям, поскольку запросы формируются путем конкатенации строк.PreparedStatement: Использует параметризованные запросы, что защищает от SQL-инъекций.Statement: Подходит для простых, одноразовых запросов.PreparedStatement: Удобен для многократного выполнения запросов с разными параметрами.Оба интерфейса могут выполнять запросы типа
SELECT, INSERT, UPDATE, DELETE, но PreparedStatement более удобен для запросов с параметрами.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11💊4
Конструкция
finally в Java используется для гарантированного выполнения кода, независимо от того, произошло исключение или нет. Обычно применяется для освобождения ресурсов, таких как закрытие файлов, соединений с базой данных или потоков. try {
// Код, который может выбросить исключение
} catch (Exception e) {
// Обработка исключения
} finally {
// Этот блок выполнится всегда
}Пример
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream("file.txt");
System.out.println(fileInputStream.read());
} catch (IOException e) {
System.out.println("Ошибка: " + e.getMessage());
} finally {
if (fileInputStream != null) {
fileInputStream.close(); // Всегда закрываем файл
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
List — это интерфейс, определяющий поведение коллекции с доступом по индексу. LinkedList — одна из реализаций, основанная на связном списке. Она эффективна при частом добавлении и удалении элементов, но медленнее при случайном доступе по индексу.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15
As-If-Serial Semantics – это принцип оптимизации компилятором, при котором код может перестраиваться, но результат его выполнения остаётся таким же, как если бы инструкции выполнялись строго по порядку. Обычный код
int a = 10;
int b = 20;
int c = a + b;
System.out.println(c);
Что может сделать компилятор?
int c = 30;
System.out.println(c);
Менять порядок инструкций, если это не влияет на результат.
Удалять лишние переменные и вычисления.
Заменять выражения константами (
10 + 20 → 30). int x = 5;
int y = 10;
x = x + 1; // x = 6
System.out.println(y);
Компилятор может поменять местами
y и xint y = 10;
int x = 6;
System.out.println(y);
int x = 10;
int y = x + 5;
x = 20;
System.out.println(y);
Если поменять порядок
x = 20;
int y = x + 5; // ❌ Неверно! y теперь 25, а должно быть 15
В многопоточной среде компилятор может менять порядок команд внутри одного потока, но он не знает о другом потоке!
Опасный пример без
volatile boolean ready = false;
int data = 0;
void writer() {
data = 42;
ready = true;
}
void reader() {
if (ready) {
System.out.println(data); // Может напечатать 0 из-за перестановки!
}
}
Решение –
volatile для readyvolatile boolean ready = false;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Да, Spring MVC — это веб-фреймворк, реализующий архитектурный шаблон MVC (Model-View-Controller), обрабатывающий HTTP-запросы через DispatcherServlet, маппинг контроллеров, модель данных и генерацию ответа.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊11👍9
Коллекция
HashMap не является потокобезопасной. Это означает, что при одновременном доступе к нему из нескольких потоков без должной синхронизации могут возникнуть проблемы, такие как потеря данных, гонки за данные и другие виды состояний гонки. Если один поток изменяет ее структуру (например, добавляя или удаляя элементы), в то время как другой поток итерирует по ней или также пытается внести изменения, результаты могут быть непредсказуемыми.Collections.synchronizedMap(Map)Оборачивает ее (или любую другую карту) в потокобезопасную обёртку, гарантируя безопасность при доступе из разных потоков. Однако при использовании этого метода важно помнить, что если итерация по коллекции происходит в многопоточной среде, необходимо синхронизировать весь блок итерации на возвращённой карте для предотвращения конкурентных модификаций.
Map<String, String> map = Collections.synchronizedMap(new HashMap<>());
ConcurrentHashMapПредоставляет потокобезопасную реализацию карты без блокировки всей карты.
ConcurrentHashMap разработан для высокой конкуренции и эффективности при доступе из множества потоков, обеспечивая лучшую производительность по сравнению с synchronizedMap. ConcurrentHashMap позволяет одновременно читать данные из карты несколькими потоками без блокировки и записывать данные при минимальной блокировке.Map<String, String> concurrentMap = new ConcurrentHashMap<>();
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
- Структурные: диаграмма классов, объектов, компонентов, развёртывания.
- Поведенческие: диаграмма последовательностей, диаграмма состояний, диаграмма действий, диаграмма вариантов использования (use case).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊12🔥5👍4
Транзитивность — это математическое и логическое свойство отношений, означающее, что если A связано с B, а B связано с C, то A связано с C.
Согласно контракту метода
equals(), он должен быть транзитивнымclass Person {
String name;
Person(String name) {
this.name = name;
}
@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);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Иван");
Person p2 = new Person("Иван");
Person p3 = new Person("Иван");
System.out.println(p1.equals(p2)); // true
System.out.println(p2.equals(p3)); // true
System.out.println(p1.equals(p3)); // true (транзитивность)
}
}Метод
compareTo() должен соблюдать транзитивность:class Student implements Comparable<Student> {
int age;
Student(int age) {
this.age = age;
}
@Override
public int compareTo(Student other) {
return Integer.compare(this.age, other.age);
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student(25);
Student s2 = new Student(20);
Student s3 = new Student(15);
System.out.println(s1.compareTo(s2)); // > 0 (s1 > s2)
System.out.println(s2.compareTo(s3)); // > 0 (s2 > s3)
System.out.println(s1.compareTo(s3)); // > 0 (s1 > s3) (транзитивность)
}
}В Java классы могут наследоваться транзитивно
class Animal {}
class Mammal extends Animal {}
class Dog extends Mammal {}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16
JAXP (Java API for XML Processing) — это стандартный набор API в Java для парсинга, генерации и преобразования XML, поддерживающий DOM, SAX, и XSLT.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥5💊1
JPQL (Java Persistence Query Language) и HQL (Hibernate Query Language) – это языки запросов, похожие на SQL, но работающие с объектами, а не с таблицами БД.
Главное отличие: JPQL – стандарт JPA, а HQL – специфичен для Hibernate.
Стандартный язык JPA, работает со всеми JPA-совместимыми провайдерами (
Hibernate, EclipseLink, OpenJPA). Опирается на JPA Entity-классы, а не на реальные таблицы в БД.
TypedQuery<User> query = entityManager.createQuery(
"SELECT u FROM User u WHERE u.age > :age", User.class);
query.setParameter("age", 18);
List<User> users = query.getResultList();
Язык запросов специфичный для Hibernate.
Работает аналогично JPQL, но поддерживает дополнительные возможности, например, вызов методов и фильтрацию по подзапросам.
Query query = session.createQuery(
"FROM User u WHERE LENGTH(u.name) > 5"); // Использование функции LENGTH()
List<User> users = query.list();
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥1
Связь устанавливается через указание удалённого URL, обычно с помощью git remote add. Это позволяет отправлять (push) и получать (pull) изменения между локальным и удалённым репозиторием.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15
В контексте JVM (Java Virtual Machine) типы данных делятся на два основных класса: примитивные типы данных и ссылочные типы данных.
Примитивные типы данных представляют собой базовые типы, которые не являются объектами и хранят непосредственно значения. Они делятся на числовые типы, логический тип и символьный тип.
Целочисленные типы
byte: 8-битный знаковый целочисленный тип данных (диапазон от -128 до 127).
short: 16-битный знаковый целочисленный тип данных (диапазон от -32,768 до 32,767).
int: 32-битный знаковый целочисленный тип данных (диапазон от -2^31 до 2^31-1).
long: 64-битный знаковый целочисленный тип данных (диапазон от -2^63 до 2^63-1).
Типы с плавающей точкой
float: 32-битный IEEE 754 тип данных с плавающей точкой одинарной точности.
double: 64-битный IEEE 754 тип данных с плавающей точкой двойной точности.
boolean: Представляет логическое значение (true или false).char: 16-битный тип данных, представляющий символ Unicode (диапазон от '\u0000' до '\uffff').Ссылочные типы данных представляют собой объекты и массивы. Они хранят ссылку на область памяти, где хранятся данные объекта или массива.
Любой объектный тип данных является экземпляром класса. Классы могут быть как стандартными (например,
String, Integer), так и пользовательскими.Интерфейсы определяют набор методов, которые должны быть реализованы классами, которые их реализуют.
Массивы могут быть одномерными или многомерными и могут хранить как примитивные, так и ссылочные типы данных.
public class DataTypesExample {
public static void main(String[] args) {
// Примитивные типы данных
byte aByte = 10;
short aShort = 100;
int anInt = 1000;
long aLong = 10000L;
float aFloat = 10.5f;
double aDouble = 10.55;
boolean aBoolean = true;
char aChar = 'A';
// Ссылочные типы данных
String aString = "Hello, World!";
Integer anInteger = 1000;
int[] anArray = {1, 2, 3, 4, 5};
// Вывод примитивных типов данных
System.out.println("byte: " + aByte);
System.out.println("short: " + aShort);
System.out.println("int: " + anInt);
System.out.println("long: " + aLong);
System.out.println("float: " + aFloat);
System.out.println("double: " + aDouble);
System.out.println("boolean: " + aBoolean);
System.out.println("char: " + aChar);
// Вывод ссылочных типов данных
System.out.println("String: " + aString);
System.out.println("Integer: " + anInteger);
System.out.println("Array: " + java.util.Arrays.toString(anArray));
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
В Java:
- int — 32-битное знаковое целое число.
- Минимум: -2^31 = -2147483648
- Максимум: 2^31 - 1 = 2147483647
Это определяется битовой длиной и знаком (первый бит — знак).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥3
В Java интерфейс
List представляет упорядоченную коллекцию элементов, допускающую дубликаты. В зависимости от конкретной реализации (ArrayList, LinkedList, Vector), используется разная структура данных. Динамический массив
Структура данных: массив
Быстрая индексация
O(1), но медленное удаление/вставка в середину O(n). List<String> list = new ArrayList<>();
Двусвязный список
Структура данных: двусвязный список
Быстрое добавление/удаление элементов
O(1), но медленный доступ по индексу O(n). List<String> list = new LinkedList<>();
Динамический массив (синхронизирован)
Структура данных: массив (как
ArrayList), но с синхронизацией. Устарел, используется редко из-за
synchronized методов (медленнее ArrayList). List<String> list = new Vector<>();
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15
- map() — преобразует каждый элемент в новый объект;
- mapToInt, mapToDouble, mapToLong — то же самое, но возвращают стрим примитивов, что позволяет избежать упаковки и использовать специфические методы (sum, average, и т.д.).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥4
Остановить поток в Java можно несколькими способами, но важно помнить, что принудительная остановка потока – плохая практика. Java предлагает безопасные методы управления потоком, чтобы избежать неожиданных ошибок и некорректного поведения программы.
Раньше использовался метод
Thread.stop(), но он был устаревшим и удалённым из-за того, что мог оставить программу в неконсистентном состоянии. Thread thread = new Thread(() -> {
while (true) {
System.out.println("Работаю...");
}
});
thread.start();
thread.stop(); // ОПАСНО! Может привести к некорректному завершению работы.Самый безопасный способ – это использование флага (
volatile boolean). class MyTask implements Runnable {
private volatile boolean running = true;
public void run() {
while (running) {
System.out.println("Работаю...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Важно восстанавливать флаг прерывания
}
}
System.out.println("Поток остановлен.");
}
public void stop() {
running = false;
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
MyTask task = new MyTask();
Thread thread = new Thread(task);
thread.start();
Thread.sleep(2000);
task.stop(); // Корректно останавливаем поток
}
}Этот способ удобен для потоков, которые ждут (
sleep(), wait(), join()), потому что прерывание выбрасывает InterruptedException. class MyTask implements Runnable {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("Работаю...");
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println("Поток прерван.");
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new MyTask());
thread.start();
Thread.sleep(2000);
thread.interrupt(); // Прерывание потока
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥1
volatile применимо к ссылке на объект, но не к самому объекту.
Это значит:
- ссылка будет видна всем потокам;
- поля объекта не становятся volatile, если они изменяются напрямую;
- это не защищает от состояний гонки внутри объекта.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥1