2. Они сохраняются в объектах HttpServletRequest, HttpSession, ServletContext.
3. Методы: setAttribute(), getAttribute(), removeAttribute() используются для работы с атрибутами.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7👍4💊1
Оптимизация запросов в базе данных (БД) — это процесс улучшения их производительности, чтобы они выполнялись быстрее и использовали меньше ресурсов. Рассмотрим основные способы оптимизации SQL-запросов.
Индексы ускоряют поиск данных, создавая структуру, похожую на оглавление книги. Вместо полного перебора таблицы (Full Table Scan), БД быстро находит нужные строки по индексу.
CREATE INDEX idx_user_name ON users(name);
Избегайте
SELECT *, так как это нагружает систему избыточными данными. Плохо
SELECT * FROM users;
Хорошо
SELECT id, name FROM users;
Перед оптимизацией полезно посмотреть, как БД выполняет запрос.
EXPLAIN SELECT * FROM users WHERE name = 'Ivan';
Если вам нужно получить только первые N строк, используйте
LIMIT, чтобы БД не грузила лишние данные. SELECT * FROM users ORDER BY id LIMIT 10;
Соединение (
JOIN) таблиц может быть дорогостоящим. Вот несколько рекомендаций: - Используйте индексы на полях, участвующих в
JOIN. - Если возможно, замените сложные
JOIN на подзапросы (EXISTS, IN). CREATE INDEX idx_orders_user_id ON orders(user_id);
Часто повторяющиеся запросы можно кэшировать на уровне БД (
QUERY CACHE в MySQL) или в приложении (Redis, Memcached). SET GLOBAL query_cache_size = 1000000;
Нормализация уменьшает дублирование данных, разбивая таблицы.
Денормализация может ускорить работу, дублируя данные и уменьшая количество
JOIN.Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
- interrupted() — статический метод, проверяет и сбрасывает флаг прерывания текущего потока;
- isInterrupted() — экземплярный метод, проверяет, не сбрасывая флаг прерывания для данного потока.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥6💊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
👍10💊3
Используются для распаковки вложенных стримов:
- flatMap() превращает каждый элемент в стрим, затем объединяет их;
- позволяет работать с вложенными коллекциями (например, список списков) как с единым потоком.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥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
👍11
- Singleton — единственный экземпляр класса;
- Factory Method — создание объектов через фабричный метод;
- Abstract Factory — создание семейства связанных объектов;
- Builder — пошаговое создание сложного объекта;
- Prototype — создание копий существующих объектов.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥5
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
👍7🔥2
SLA (Service Level Agreement) — это соглашение об уровне сервиса между поставщиком и клиентом.
Описывает:
- доступность (например, 99.9%);
- время отклика;
- действия в случае сбоя;
- метрики качества сервиса.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12
Нет, Stream API не поддерживает
RandomAccess, потому что он работает с потоком данных, а не с индексированными структурами. который не обязательно хранится в памяти в виде структуры, поддерживающей случайный доступ.
в отличие от
List, Stream не позволяет получить элемент по индексу (get(index) отсутствует). элементы проходятся один за другим, что делает случайный доступ невозможным.
List (с RandomAccess)List<Integer> list = new ArrayList<>(List.of(1, 2, 3, 4, 5));
System.out.println(list.get(2)); // Быстрое получение элемента по индексу
Stream (без RandomAccess)Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
stream.skip(2).findFirst().ifPresent(System.out::println); // Ищем 3-й элемент
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Когда ты вызываешь close() у соединения из пула, оно не закрывает физическое соединение с БД, а возвращает его обратно в пул. Это позволяет эффективно повторно использовать соединения, не создавая каждый раз новые подключения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥14👍5💊1
Это принцип объектно-ориентированного программирования (ООП), который скрывает детали реализации объекта и показывает только его наиболее важные характеристики. Она позволяет сосредоточиться на сущности объекта, игнорируя его внутреннюю сложность.
В Java абстракция достигается через:
Абстрактные классы
Интерфейсы
Абстрактный класс — это класс, который не может быть создан напрямую, но может содержать:
Абстрактные методы (без реализации, только сигнатуры);
Обычные методы (с реализацией).
Используется, если вы хотите описать общее поведение для группы классов, но часть поведения оставить на усмотрение конкретных подклассов.
abstract class Animal {
// Абстрактный метод — реализуется в подклассах
abstract void makeSound();
// Обычный метод
void eat() {
System.out.println("This animal eats food.");
}
}
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("Woof!");
}
}
class Cat extends Animal {
@Override
void makeSound() {
System.out.println("Meow!");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog();
dog.makeSound(); // Woof!
dog.eat(); // This animal eats food.
Animal cat = new Cat();
cat.makeSound(); // Meow!
}
}Интерфейс — это чистый контракт, который определяет набор методов, которые класс должен реализовать.
В отличие от абстрактного класса:
Интерфейс не может содержать полей (кроме
static final).Класс может реализовать несколько интерфейсов (множественное наследование).
interface Vehicle {
void start(); // метод без реализации
void stop();
}
class Car implements Vehicle {
@Override
public void start() {
System.out.println("Car is starting.");
}
@Override
public void stop() {
System.out.println("Car is stopping.");
}
}
class Bike implements Vehicle {
@Override
public void start() {
System.out.println("Bike is starting.");
}
@Override
public void stop() {
System.out.println("Bike is stopping.");
}
}
public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
car.start(); // Car is starting.
car.stop(); // Car is stopping.
Vehicle bike = new Bike();
bike.start(); // Bike is starting.
bike.stop(); // Bike is stopping.
}
}Программистам не нужно знать все детали реализации объекта. Они работают только с его интерфейсом.
Код становится понятным и модульным, так как мы сосредоточиваемся на важной логике.
Абстракция позволяет использовать один и тот же код для разных объектов.
Если нужно изменить реализацию, это не затронет остальную часть программы (если она работает через абстрактный контракт).
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11💊1
Тернарный оператор — это короткая форма условного выражения.
Формат: условие ? значение_если_true : значение_если_false
Он позволяет выбирать одно из двух значений в зависимости от логического условия.
Полезен, когда нужно вернуть результат в одну строку вместо использования if-else.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15
WHERE и HAVING используются для фильтрации записей, но они применяются на разных этапах выполнения запроса и имеют разные цели.
Применяется до агрегации данных. Это значит, что фильтрация происходит непосредственно на строках исходной таблицы или результата объединения таблиц, до того как произойдет любая операция группировки (
GROUP BY) или агрегирования (SUM, COUNT, AVG и т.д.).Используется для фильтрации строк, которые будут включены в результаты группировки или в финальный набор данных, если группировка не используется.
Не может использоваться для фильтрации агрегированных значений.
SELECT employee_id, SUM(salary)
FROM salaries
WHERE salary > 1000
GROUP BY employee_id;
Применяется после агрегации данных. Это означает, что фильтрация происходит уже на агрегированных результатах, полученных после применения
GROUP BY и агрегатных функций.Используется для фильтрации групп в результате запроса с группировкой.
Может использоваться только с
GROUP BY или для фильтрации результатов, полученных с помощью агрегатных функций.SELECT employee_id, SUM(salary)
FROM salaries
GROUP BY employee_id
HAVING SUM(salary) > 10000;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
Java — это:
- Объектно-ориентированный язык программирования;
- Работает по принципу: «Написал один раз — работает везде» благодаря JVM;
- Поддерживает: платформенную независимость, автоматическое управление памятью, обширную стандартную библиотеку, мультипоточность и безопасный синтаксис.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🤔8🔥3💊3
Поверхностное копирование (Shallow Copy) – это процесс создания нового объекта, который содержит ссылки на те же вложенные объекты, что и оригинал.
Способ 1: Метод
clone() (реализация Cloneable) class Person implements Cloneable {
String name;
public Person(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // Поверхностное копирование
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Person original = new Person("Иван");
Person copy = (Person) original.clone();
System.out.println(copy.name); // Иван
}
}Если объект содержит вложенные объекты, они не копируются, а передаются по ссылке.
class Address {
String city;
public Address(String city) { this.city = city; }
}
class User implements Cloneable {
String name;
Address address;
public User(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // Поверхностное копирование
}
}
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("Москва");
User original = new User("Иван", address);
User copy = (User) original.clone();
copy.address.city = "Санкт-Петербург"; // Меняем адрес у копии
System.out.println(original.address.city); // Санкт-Петербург (изменилось и у оригинала!)
}
}Решение: Создать новый вложенный объект в
clone() @Override
protected Object clone() throws CloneNotSupportedException {
User clonedUser = (User) super.clone();
clonedUser.address = new Address(this.address.city); // Копируем вложенный объект
return clonedUser;
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
- Контейнеры Docker работают на одном ядре ОС, изолируя приложения на уровне процессов;
- Виртуальные машины включают полную ОС и гипервизор, что делает их тяжелее и медленнее по сравнению с контейнерами.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🔥6
Java предоставляет встроенные классы для чтения и записи сжатых данных в формате ZIP, GZIP и других. Эти классы находятся в пакете
java.util.zip. GZIPOutputStream – сжимает данные в формат .gz. GZIPInputStream – разжимает данные из .gz. import java.io.*;
import java.util.zip.*;
public class GZipExample {
public static void main(String[] args) throws IOException {
String data = "Привет, мир! Это тестовая строка для GZIP.";
// Сжатие в .gz
try (FileOutputStream fos = new FileOutputStream("data.gz");
GZIPOutputStream gzos = new GZIPOutputStream(fos)) {
gzos.write(data.getBytes());
}
// Разжатие .gz
try (FileInputStream fis = new FileInputStream("data.gz");
GZIPInputStream gzis = new GZIPInputStream(fis);
BufferedReader reader = new BufferedReader(new InputStreamReader(gzis))) {
System.out.println("Разжатый текст: " + reader.readLine());
}
}
}
ZipOutputStream – создаёт ZIP-архив. ZipInputStream – извлекает файлы из ZIP. import java.io.*;
import java.util.zip.*;
public class ZipExample {
public static void main(String[] args) throws IOException {
String fileName = "example.txt";
String zipFile = "archive.zip";
// Создаём файл для сжатия
try (FileWriter writer = new FileWriter(fileName)) {
writer.write("Привет, это файл для архивации!");
}
// Запись в ZIP
try (FileOutputStream fos = new FileOutputStream(zipFile);
ZipOutputStream zos = new ZipOutputStream(fos);
FileInputStream fis = new FileInputStream(fileName)) {
ZipEntry entry = new ZipEntry(fileName);
zos.putNextEntry(entry);
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) > 0) {
zos.write(buffer, 0, length);
}
}
System.out.println("Файл заархивирован в " + zipFile);
}
}
DeflaterOutputStream – сжимает данные без специфического формата. InflaterInputStream – разжимает такие данные. import java.io.*;
import java.util.zip.*;
public class DeflaterExample {
public static void main(String[] args) throws IOException {
String text = "Данные для сжатия";
// Сжатие
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try (DeflaterOutputStream dos = new DeflaterOutputStream(byteStream)) {
dos.write(text.getBytes());
}
byte[] compressedData = byteStream.toByteArray();
// Разжатие
ByteArrayInputStream inputStream = new ByteArrayInputStream(compressedData);
try (InflaterInputStream iis = new InflaterInputStream(inputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int length;
while ((length = iis.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
System.out.println("Разжатые данные: " + new String(outputStream.toByteArray()));
}
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Плюсы:
- просто и понятно;
- встроена в язык;
- достаточно для большинства задач.
Минусы:
- может вызывать блокировки и снижать производительность;
- нет гибкости (нельзя легко попытаться захватить, или сделать timeout);
- не масштабируется на сложные сценарии.
Для сложных кейсов лучше использовать Lock.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥2
В интерфейсе могут располагаться различные типы методов, начиная с Java 8, когда в язык были добавлены новые возможности, такие как default методы и static методы. До Java 8 интерфейсы могли содержать только абстрактные методы. Ниже представлены типы методов, которые могут быть объявлены в интерфейсе:
Это методы без тела, предназначенные для переопределения в классах, которые реализуют интерфейс. Абстрактные методы представляют собой контракт, который должен быть выполнен классом-реализатором. Все методы в интерфейсе неявно являются
public abstract, даже если явно не указаны эти модификаторы.void myMethod();
Позволяют определять реализацию метода непосредственно в интерфейсе. Классы, реализующие интерфейс, могут переопределять эти методы, но это не обязательно. Default методы были введены для обеспечения обратной совместимости, позволяя добавлять новые методы в интерфейсы без нарушения существующих реализаций.
default void defaultMethod() {
// Реализация
}Позволяют определять методы с реализацией, которые могут быть вызваны без создания экземпляра класса, реализующего интерфейс. Эти методы нельзя переопределить в реализующем интерфейс классе.
static void staticMethod() {
// Реализация
}Позволяют определять вспомогательные методы, которые предназначены для использования в default или static методах внутри того же интерфейса. Эти методы не могут быть вызваны извне интерфейса или реализующих его классов.
private void privateMethod() {
// Реализация
}Пример
public interface MyInterface {
// Абстрактный метод
void abstractMethod();
// Default метод
default void defaultMethod() {
System.out.println("Default implementation");
}
// Static метод
static void staticMethod() {
System.out.println("Static implementation");
}
// Private метод (используется внутри интерфейса)
private void privateMethod() {
System.out.println("Private helper method");
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14
Конкретные реализации драйверов предоставляются производителями СУБД (например, PostgreSQL JDBC Driver, MySQL Connector/J).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍8