Push 163 file(s) from Obsidian

This commit is contained in:
2026-09-24 13:22:58 +05:00
parent 4c6a45e2e8
commit 9777f9490f
163 changed files with 36730 additions and 0 deletions
+12
View File
@@ -0,0 +1,12 @@
#java #SpringBoot
Сценарий: В приложении есть и традиционные веб-эндпоинты с Thymeleaf, и REST API.
Нужно централизовать обработку ошибок (например, перехват ResourceNotFoundException):
Как вернуть страницу 404 для обычных web-эндпоинтов?
Как вернуть JSON с ошибкой 404 для REST API?
@ControllerAdvice — используется с @Controller, возвращает view.
@RestControllerAdvice — сочетает @ControllerAdvice + @ResponseBody (для REST API).
View File
+67
View File
@@ -0,0 +1,67 @@
#java #абстракции
Одна из ключевых концепций ООП – абстракция. Мы постоянно используем её в [[Java]], даже не задумываясь. Но давайте разберёмся, зачем она нужна и как правильно применять.
📌 Что такое абстракция?
Абстракция – это процесс выделения существенных характеристик объекта, скрывая при этом детали реализации. Это позволяет нам работать с объектами через их интерфейсы, а не конкретные реализации.
Пример из жизни:
Когда вы едете на машине, вам не нужно знать, как работает двигатель. Достаточно уметь жать на газ, тормозить и поворачивать руль. Вот это и есть абстракция – вам доступен только необходимый интерфейс, а детали скрыты.
🔹 Как реализуется абстракция в Java?
В Java абстракция достигается двумя способами:
1. Абстрактные классы (abstract class)
2. Интерфейсы (interface)
🚀 Абстрактные классы
Абстрактный класс может содержать как реализованные, так и абстрактные (без реализации) методы. Его нельзя создать через new, он служит основой для дочерних классов.
```java
abstract class Vehicle {
abstract void start(); // абстрактный метод, без реализации
void stop() {
System.out.println("Машина остановилась");
}
}
class Car extends Vehicle {
@Override
void start() {
System.out.println("Запуск двигателя...");
}
}
public class Main {
public static void main(String[] args) {
Vehicle car = new Car();
car.start();
car.stop();
}
}
```
💡 Тут start() – это абстрактный метод, его реализация будет в Car. А вот stop() реализован в базовом классе.
🚀 Интерфейсы
Интерфейсы содержат только сигнатуры методов (до Java 8), а с Java 8 можно добавлять default и static методы.
```java
interface Engine {
void start();
}
class ElectricCar implements Engine {
@Override
public void start() {
System.out.println("Электродвигатель включен!");
}
}
```
📌 Разница между интерфейсом и абстрактным классом в том, что интерфейсы описывают, что класс ДОЛЖЕН делать, а абстрактные классы – как он МОЖЕТ это делать.
🎯 Где применять абстракцию?
- Если у вас иерархия классов с общими методами – используйте абстрактный класс.
- Если вам нужно гибкое поведение без наследования – используйте интерфейсы.
👉 Абстракция позволяет писать гибкий, расширяемый и поддерживаемый код, уменьшая зависимость от конкретных реализаций.
+8
View File
@@ -0,0 +1,8 @@
#java #SpringBoot
Сценарий: Ты добавил в проект стороннюю библиотеку (например, кастомный логгер) и просто положил её JAR в classpath.
Без написания конфигурационных классов Spring автоматически подхватывает нужные бины.
Объясни, как Spring Boot определяет и подключает их при старте.
Использует SpringFactoriesLoader, который читает META-INF/spring.factories и конфигурирует бины в зависимости от содержимого classpath.
@@ -0,0 +1,18 @@
#java #поиск
```java
public class BinarySearch {
public static int binarySearch(int[] arr, int target) {
int left = 0, right = arr.length - 1;
while (left <= right) {
int mid = (left + right) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1; // элемент не найден
}
}
```
+17
View File
@@ -0,0 +1,17 @@
#java #коллекции
Коллекции [[Java]] и производительность
🍩List (Списки)
🟣ArrayList – быстрый доступ к элементам и их обход, но вставка/удаление в середине списка требует сдвига элементов.
🟣LinkedList – удобен для вставки и удаления, но случайный доступ медленный, так как элементы обходятся с начала или конца.
🍩Set (Множества)
🟣HashSet – быстрые операции добавления, удаления и поиска (за O(1)), но не сохраняет порядок элементов.
🟣LinkedHashSet – сохраняет порядок вставки и быстрее перебирается, чем HashSet.
🟣TreeSet – поддерживает сортировку, но операции добавления, удаления и поиска имеют логарифмическую сложность O(log n).
🍩Map (Словари/Отображения)
🟣HashMap – обеспечивает O(1) доступ по ключу, но не сохраняет порядок. Возможны коллизии, которые могут замедлить работу.
🟣LinkedHashMap – сохраняет порядок вставки и перебирается быстрее, чем HashMap.
🟣TreeMap – хранит ключи в отсортированном порядке, но операции выполняются за O(log n).
![[collection.jpg]]
@@ -0,0 +1,23 @@
#docker
`docker compose up -d` Запуск всех сервисов в фоновом режиме.
`docker compose down` Остановка и удаление контейнеров, сетей и служебных ресурсов проекта.
`docker compose restart` Перезапуск всех сервисов проекта.
`docker compose stop` Остановка сервисов без удаления контейнеров.
`docker compose start` Запуск ранее остановленных контейнеров.
`docker ps` Просмотр запущенных контейнеров.
`docker ps -a` Просмотр всех контейнеров, включая остановленные.
`docker compose ps` Просмотр состояния контейнеров текущего проекта.
`docker stats` Мониторинг потребления CPU, RAM и сетевых ресурсов контейнерами в реальном времени.
`docker compose logs` Просмотр журналов всех сервисов проекта.
`docker compose logs -f` Просмотр журналов в режиме реального времени.
`docker compose logs <service>` Просмотр журналов конкретного сервиса.
`docker logs <container>` Просмотр журналов конкретного контейнера.
`docker inspect <container>` Получение полной информации о контейнере (сеть, тома, переменные окружения и др.).
`docker exec -it <container> bash` Подключение к оболочке контейнера для диагностики и выполнения команд.
`docker exec -it <container> sh` Аналогично для контейнеров без Bash.
`docker top <container>` Просмотр процессов внутри контейнера.
`docker images` Список локальных Docker-образов.
`docker image inspect <image>` Информация об образе.
`docker system df` Статистика использования диска Docker.
`docker volume ls` Список томов Docker.
`docker network ls` Список сетей Docker.
@@ -0,0 +1,7 @@
#java #SpringBoot
Сценарий: Твой публичный API перегружен — один клиент шлет слишком много запросов, мешая остальным.
Какой практичный, независимый от технологий подход можно применить для ограничения, например, 100 запросов в минуту на клиента, и где обычно реализуется такая логика?
Bucket4j / Resilience4j, счетчики в Redis, лимитирование на уровне API Gateway.
@@ -0,0 +1,11 @@
```java
public class MaxInArray {
public static int findMax(int[] arr) {
int max = arr[0];
for (int num : arr) {
if (num > max) max = num;
}
return max;
}
}
```
@@ -0,0 +1,3 @@
#java
Потому что интерфейс описывает контракт, а не состояние. Все поля интерфейса — это константы, доступные без создания экземпляра. Они автоматически public static final, даже без явного указания.
@@ -0,0 +1,15 @@
```java
public class PalindromeCheck {
public static boolean isPalindrome(String str) {
int left = 0, right = str.length() - 1;
while (left < right) {
if (str.charAt(left++) != str.charAt(right--)) {
return false;
}
}
return true;
}
}
```
@@ -0,0 +1,7 @@
#java #SpringBoot
Сценарий: В микросервисной архитектуре оформление заказа включает два шага — списание товара в Inventory Service и списание денег через Payment Service.
Если списание товара прошло успешно, а оплата — нет, какой шаблон проектирования поможет откатить изменения в Inventory и обеспечить согласованность данных?
Шаблон Saga (хореография или оркестрация), либо двухфазный коммит (2PC, но редко используется на практике).
@@ -0,0 +1,10 @@
#java #SpringBoot
Сценарий: У тебя есть OrderService с методом createOrder(), помеченным @Transactional.
Внутри он вызывает updateInventory() (тоже в OrderService и тоже с @Transactional).
Если updateInventory() выбрасывает runtime-исключение, что произойдет с транзакцией, начатой в createOrder()?
Как изменить дизайн, если нужно, чтобы оба метода выполнялись в отдельных, независимых транзакциях?
Транзакция не будет распространяться (прокси не сработает при внутреннем вызове).
Решение — self-injection (внедрение самого себя как зависимости) или использование AOP.
+8
View File
@@ -0,0 +1,8 @@
#java #SpringBoot
Сценарий: Нужно хранить товары пользователя в корзине и управлять временным списком поисковых фильтров, который очищается после каждого HTTP-запроса.
Какой скоуп ты выберешь для ShoppingCart и какой — для SearchFilter, и почему?
@SessionScope — для корзины (привязано к пользовательской сессии),
@RequestScope — для поискового фильтра (новый бин на каждый HTTP-запрос).
@@ -0,0 +1,17 @@
```java
public class BubbleSort {
public static void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// обмен
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
}
```
@@ -0,0 +1,10 @@
#Java #SpringBoot
Сценарий: Представь, что ты проектируешь сложную e-commerce платформу. Где ты используешь интерфейс с аннотацией
@Repository, а где — с аннотацией @Service? Приведи конкретный пример, какую роль каждая из этих аннотаций играет в процессе оформления заказа пользователем.
@Component — универсальный бин,
@Service — бизнес-логика,
@Repository — DAO + перевод исключений в DataAccessException,
@Controller — контроллер уровня MVC.
@@ -0,0 +1,8 @@
```java
public class Factorial {
public static long factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
}
```
@@ -0,0 +1,9 @@
Ключевое слово final в [[Java]] — это модификатор, который может применяться к переменным, методам и классам. Когда оно используется с переменной, это делает её неизменяемой, другими словами — константой. Например, переменная PI объявлена как final в классе ниже:
```java
public class CircleCalculator {
private final double PI = 3.14159;
public double calculateArea(double radius) {
return PI * radius * radius;
}
}
```
@@ -0,0 +1,8 @@
#java #SpringBoot
Сценарий: Коллега добавил новую фичу, и теперь твое Spring-приложение не стартует, выдавая BeanCurrentlyInCreationException из-за циклической зависимости между ServiceA и ServiceB.
Предположим, что быстро переработать бизнес-логику невозможно. Какое минимальное изменение кода ты бы предложил, чтобы приложение хотя бы запустилось, и почему это считается временным решением?
Spring по умолчанию может использовать проксирование и конструкторную/сеттерную инъекцию.
Лучшее решение — перепроектировать зависимости или использовать @Lazy.
+3
View File
@@ -0,0 +1,3 @@
#java
Объект - это объединение данных и кода, который эти данные обрабатывает ()
Класс - это шаблон описания объектов. В классе могут описываться поля, методы, конструкторы и другие классы.
@@ -0,0 +1,81 @@
#PostgreSQL #PostgreSQL #SQL
-- ***********************************
-- Редактирование таблиц, расширенные возможности SELECT, функции
-- ***********************************
-- Добавление поля в таблицу
```sql
ALTER TABLE table_name ADD COLUMN new_field
BOOLEAN NOT NULL DEFAULT TRUE;
```
-- добавление поля с автоинкрементом и primary key в таблицу
```sql
ALTER TABLE test1 ADD COLUMN id SERIAL PRIMARY KEY;
```
-- Удаление поля из таблицы
```sql
ALTER TABLE table_name DROP COLUMN new_field;
```
-- переименовать поле
```sql
ALTER TABLE table_name RENAME old_field TO new_field;
```
-- сменить тип данных
```sql
ALTER TABLE table_name ALTER COLUMN any_field SET
DATA TYPE VARCHAR(255);
```
-- изменить значение по умолчанию
```sql
ALTER TABLE table_name ALTER COLUMN any_field SET
DEFAULT 'new value';
```
-- добавить/удалить constraint NOT NULL
```sql
ALTER TABLE table_name ALTER COLUMN any_field
SET|DROP NOT NULL;
```
-- переименовать таблицу
```sql
ALTER TABLE table_name RENAME TO new_table_name;
```
-- Расширенные возможности SELECT
```sql
SELECT * FROM table WHERE field1 LIKE 'value'; -- field1 = 'value'
SELECT * FROM table WHERE field1 LIKE 'val%'; -- field1 начинается с 'val'
SELECT * FROM table WHERE field1 LIKE '%lue'; -- field1 заканчивается на 'lue'
SELECT * FROM table WHERE field1 LIKE '%e%'; -- field1 содержит 'e'
```
несколько условий
```sql
SELECT * FROM table WHERE field1 = 'value' AND field2 > 'value2';
SELECT * FROM table WHERE field1 = 'value' OR field2 > 'value2';
```
-- вывод уникальных записей
```sql
SELECT DISTINCT field1 FROM table;
```
-- группирование записей
```sql
SELECT field1, COUNT(field1) FROM table GROUP BY field1;
```
-- сгруппирует записи таблицы table по полю field и выведет уникальные значения field и количество повторений
```sql
```
SELECT field1, COUNT(field1) FROM table GROUP BY field1
HAVING COUNT(field) > 3;
-- сгруппирует записи таблицы table по полю field и выведет уникальные значения field и количество повторений, где количество повторений больше 3
+107
View File
@@ -0,0 +1,107 @@
#PostgreSQL #PostgreSQL #SQL
Перенес в my-mans
-- подключиться к postgres (утилита psql)
```bash
psql -U postgres
```
-- команды помощи
help
\h -- помощь по командам SQL
\? -- помощь по командам psql
-- выход из консоли postgres
\q
-- создать базу
```sql
CREATE DATABASE my_database;
```
-- подключиться к базе
```
\connect my_database;
```
-- создать таблицу my_table с полями field1 (тип целочисленный, обязательное для заполнения), field2 (тип строка 255 символов)
```sql
CREATE TABLE my_table (field1 INT NOT NULL, field2 VARCHAR(255));
```
-- вывести все таблицы
```sh
\d
```
-- удалить таблицу my_table
```sql
DROP TABLE my_table;
```
-- внести в таблицу запись
```sql
INSERT INTO my_table(field1, field2) VALUES(1,'Any text value');
```
-- вывести записи
```sql
SELECT * FROM my_table; -- все записи
SELECT * FROM my_table WHERE field1 = 1; -- все, где field1 = 1
SELECT * FROM my_table WHERE field1 != 1; -- и т д
SELECT * FROM my_table WHERE field1 > 1;
SELECT * FROM my_table LIMIT 100; -- первые 100 записей;
SELECT * FROM my_table LIMIT 100 OFFSET 200; -- запись с 201 по 300;
```
-- сортировка при выводе
```sql
SELECT * FROM my_table ORDER BY field1 ASC; -- вывести отсортировав в возрастающем порядке
SELECT * FROM my_table ORDER BY field1 DESC; -- вывести отсортировав в убывающем порядке
```
-- изменить запись таблицы (поле field2 строки, где field1 = 1);
```sql
UPDATE my_table SET field2 = 'Other text value' WHERE field1 = 1;
```
-- удаление данных
```sql
DELETE FROM my_table; -- удалить все записи;
DELETE FROM my_table WHERE field1 = 1; -- удалить запись где field1 = 1;
```
-- ***********************************
-- нормализация (разбиение таблиц на несколько)
-- ***********************************
-- Constraints - ограничения типов данных
```sql
CREATE TABLE my_table (
field1 INT NOT NULL, -- запись обязательна
field2 VARCHAR(255) NOT NULL UNIQUE, -- запись должна быть уникальной
field3 BOOLEAN NOT NULL DEFAULT TRUE -- значение по умолчанию - true
...
);
```
-- Первичный и внешние ключи
-- при создании записи таблицы с отсутствующим внешним ключом выведется запись об ошибке. будут выводится ошибки и в иных случаях, когда будут нарушаться связи.
CREATE TABLE IF NOT EXISTS my_table ( -- ключ IF NOT EXISTS проверяет, существует ли таблица.
field1 SERIAL INT PRIMARY KEY, -- при добавлении PRIMARY KEY поле автоматически наследует ограничения NOT NULL и UNIQUE, и создается индекс. SERIAL тип данных являющийся автоматически увеличивающимся счетчиком (аналог ключа AUTOINCREMENT в Sqlite)
field2 VARCHAR(255) NOT NULL UNIQUE,
field3 INT NOT NULL,
FOREIGN KEY(field3) REFERENCES other_table(field_name) -- поле ссылается на внешнюю таблицу other_table на поле field_name, которое обязательно должно быть с PRIMARY KEY
);
-- вывод данных из нескольких таблиц со связанными полями
```sql
SELECT * FROM table_1 LEFT JOIN table_2 ON (table_2.field = table_1.field);
```
-- алиасы, нужны для удобства. Также, при выводе наименование таблиц или полей выводится алиасом, при его наличии.
```sql
SELECT * FROM table_1 as tab1 LEFT JOIN table_2 as tab2 ON (tab1.field = tab2.field);
```