Да, 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
JVM (Java Virtual Machine) управляет памятью приложения и делит её на несколько областей.
Здесь хранятся ВСЕ объекты и массивы, созданные через
new. Управляется Garbage Collector (GC)
Локальные переменные (
int, double, String – если не new) Ссылки на объекты в
Heap Вызовы методов (кадры стека)
public class StackExample {
public static void main(String[] args) {
int a = 5;
int b = sum(a, 10);
}
public static int sum(int x, int y) {
return x + y;
}
}Хранит информацию о загруженных классах (названия, методы, поля, байт-код).
При загрузке нового класса
ClassLoader выделяет память в Metaspace. В Java 8 заменил устаревший
PermGen. while (true) {
ClassLoader loader = new MyClassLoader();
Class<?> clazz = loader.loadClass("MyDynamicClass");
}Хранит адрес текущей инструкции, выполняемой потоком.
У каждого потока свой PC Register.
Работает как указатель в машинном коде.
Хранит данные, связанные с вызовами нативных методов (
JNI – Java Native Interface). Если Java вызывает C++-код, информация о вызове хранится здесь.
public class NativeExample {
public native void callCMethod();
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15
Идемпотентный метод — это метод, который можно вызывать многократно без изменения результата. Примеры:
- GET — безопасен и идемпотентен;
- PUT — перезаписывает, но не дублирует;
- DELETE — если ресурс уже удалён, не вызывает ошибку. Это важно для безопасного повторного выполнения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍20🔥5
Когда у объекта много параметров.
Когда объект трудно создавать через конструктор.
class Car {
private String engine;
private int wheels;
private boolean sunroof;
private Car(CarBuilder builder) {
this.engine = builder.engine;
this.wheels = builder.wheels;
this.sunroof = builder.sunroof;
}
public static class CarBuilder {
private String engine;
private int wheels;
private boolean sunroof;
public CarBuilder setEngine(String engine) {
this.engine = engine;
return this;
}
public CarBuilder setWheels(int wheels) {
this.wheels = wheels;
return this;
}
public CarBuilder setSunroof(boolean sunroof) {
this.sunroof = sunroof;
return this;
}
public Car build() {
return new Car(this);
}
}
}Создаём объект пошагово
Car car = new Car.CarBuilder()
.setEngine("V8")
.setWheels(4)
.setSunroof(true)
.build();
Когда у системы много сложных классов, и вы хотите предоставить один упрощённый интерфейс.
Когда нужно скрыть детали реализации от клиента.
class CPU {
void start() { System.out.println("Процессор запущен."); }
}
class Memory {
void load() { System.out.println("Память загружена."); }
}
class HardDrive {
void read() { System.out.println("Чтение данных с диска."); }
}Создаём
Facade, который скрывает сложность class ComputerFacade {
private CPU cpu;
private Memory memory;
private HardDrive hardDrive;
public ComputerFacade() {
this.cpu = new CPU();
this.memory = new Memory();
this.hardDrive = new HardDrive();
}
public void startComputer() {
cpu.start();
memory.load();
hardDrive.read();
System.out.println("Компьютер включен!");
}
}Теперь клиенту не нужно вызывать кучу методов
ComputerFacade computer = new ComputerFacade();
computer.startComputer(); // Запускает всю систему через 1 метод
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
- Статические вложенные классы не имеют доступа к нестатическим членам внешнего класса. Они не требуют экземпляра внешнего класса и больше похожи на обычные классы, но с ограниченной областью видимости.
- Внутренние классы (non-static) имеют доступ ко всем полям и методам внешнего класса, в том числе к приватным. Их использование возможно только через экземпляр внешнего класса.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥6
В Spring термин Bean (бин) означает объект, управляемый Spring-контейнером.
Создаётся вручную, Spring о нём ничего не знает
class Car {
void drive() {
System.out.println("Машина едет...");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car(); // Создаём объект вручную
car.drive();
}
}Spring создаёт и управляет бином через аннотации.
import org.springframework.stereotype.Component;
@Component // Сообщает Spring, что этот класс - Bean
class Car {
void drive() {
System.out.println("Spring-машина едет...");
}
}
Теперь объект создаётся Spring-контейнером
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Car car = context.getBean(Car.class); // Получаем Bean из Spring-контейнера
car.drive();
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Iterable<T> — базовый интерфейс для всех коллекций, поддерживающих цикл for-each.
Обязательный метод: iterator(), который возвращает Iterator<T>.
Это позволяет использовать коллекции в конструкциях.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3
В контексте Java, Heap (куча) и Stack (стек) являются областями памяти, используемыми JVM для управления памятью, необходимой для выполнения программы. Каждая из этих областей имеет свои характеристики и используется для разных целей.
Heap — это область памяти, выделенная для динамического распределения памяти объектов и массивов. Все объекты, созданные с использованием оператора
new, размещаются в куче.Куча разделена на поколения: молодое поколение (Young Generation) и старое поколение (Old Generation).
Молодое поколение включает в себя области Eden Space и Survivor Spaces (S0 и S1).
Старое поколение хранит долгоживущие объекты.
Куча управляется сборщиком мусора (Garbage Collector), который автоматически освобождает память, занятую объектами, которые больше не используются.
Куча используется для хранения объектов, массивов и классов, информация о которых сохраняется на протяжении всего времени их жизни.
public class Example {
public static void main(String[] args) {
Example obj = new Example(); // obj создается в куче
}
}Стек — это область памяти, используемая для управления вызовами методов и хранения локальных переменных, параметров методов и информации о возвратах.
Каждый поток имеет свой собственный стек.
Стек хранит кадры (frames) для каждого вызова метода. Каждый кадр содержит локальные переменные метода и информацию о вызовах.
Память в стеке автоматически управляется при вызове методов и выходе из них. Когда метод вызывается, создается новый кадр в стеке; когда метод завершает выполнение, его кадр удаляется из стека.
Стек используется для хранения примитивных типов данных и ссылок на объекты, которые находятся в куче.
Локальные переменные методов и параметры методов хранятся в стеке.
public class Example {
public static void main(String[] args) {
int localVar = 10; // localVar хранится в стеке
Example obj = new Example(); // Ссылка на obj хранится в стеке, а сам объект — в куче
obj.method();
}
public void method() {
int anotherVar = 20; // anotherVar хранится в стеке
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Определять конструктор для сервлета не рекомендуется, потому что создание экземпляров управляется контейнером. Лучше использовать метод init() для инициализации данных.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11