Парадигма программирования определяет способ мышления и подход к написанию кода. В зависимости от выбранной парадигмы, в центре может стоять разное ключевое понятие.
Код строится вокруг последовательности инструкций.
Данные изменяются с помощью вызова функций (процедур).
Пример: C, Pascal.
int sum(int a, int b) {
return a + b;
}
int main() {
int result = sum(5, 3);
printf("%d", result);
return 0;
}Мир представляется в виде объектов, у которых есть состояние (поля) и поведение (методы).
Используются принципы: инкапсуляция, наследование, полиморфизм.
Пример: Java, C++, Python.
class Car {
private String model;
public Car(String model) {
this.model = model;
}
public void drive() {
System.out.println(model + " едет!");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car("Tesla");
car.drive(); // Tesla едет!
}
}Использование чистых функций (без изменения состояния).
Избегание побочных эффектов и мутабельности.
Пример: Haskell, Scala, Kotlin, Java (Stream API).
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
numbers.stream()
.map(n -> n * 2) // Умножаем каждый элемент на 2
.forEach(System.out::println); // Вывод результата
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
ApplicationContext управляет жизненным циклом бинов: создание, внедрение зависимостей, инициализация, хранение и уничтожение объектов в рамках приложения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥4
Поверхностное копирование (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
👍13
role — часть ARIA, помогает обозначить назначение элемента для вспомогательных технологий (например, экранных читалок).
Например: role="button", role="dialog", role="navigation".
Это важно, когда семантика не может быть получена напрямую из тега.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊26
Главное отличие:
@RequestMapping – универсальная аннотация, поддерживающая все HTTP-методы (GET, POST, PUT, DELETE и т. д.). @PutMapping – специализированная аннотация для PUT-запросов. Можно использовать для любого HTTP-метода (
GET, POST, PUT, DELETE). Необходимо явно указывать method = RequestMethod.PUT, если нужен PUT. @RestController
@RequestMapping("/users")
public class UserController {
@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
public String updateUser(@PathVariable Long id, @RequestBody String userData) {
return "Пользователь с ID " + id + " обновлён!";
}
}
Это специализированная аннотация, эквивалентная
@RequestMapping(method = RequestMethod.PUT). @RestController
@RequestMapping("/users")
public class UserController {
@PutMapping("/{id}")
public String updateUser(@PathVariable Long id, @RequestBody String userData) {
return "Пользователь с ID " + id + " обновлён!";
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15💊1
Плохо, если:
- Это делается вместо нормального контроля логики (например, вместо if).
- Исключение выбрасывается без документации и понимания.
- Не происходит логгирования и неясно, что именно пошло не так.
RuntimeException — мощный инструмент, но требует аккуратного подхода, иначе может ломать приложение неожиданно.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥7
В базах данных и многопоточных системах транзакция — это атомарная последовательность операций, которая должна выполняться корректно и полностью.
Транзакция выполняется полностью или не выполняется вовсе.
Перевод 1000 рублей с одного счёта на другой:
- Списать 1000 рублей с А
- Зачислить 1000 рублей на B
Если вторая операция не удалась, первая должна быть отменена.
try {
connection.setAutoCommit(false); // Отключаем автокоммит
withdraw(accountA, 1000);
deposit(accountB, 1000);
connection.commit(); // Подтверждаем транзакцию
} catch (Exception e) {
connection.rollback(); // Откат в случае ошибки
}После транзакции данные должны оставаться в логически правильном состоянии.
Одна транзакция не должна мешать выполнению другой.
Два клиента одновременно бронируют одно и то же место в самолёте.
Система должна обработать их по очереди, а не одновременно.
В Java изолированность регулируется уровнями транзакций (
TRANSACTION_READ_COMMITTED, TRANSACTION_REPEATABLE_READ и т. д.), чтобы избежать проблем, таких как "грязное чтение" или "фантомные записи".connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
После успешного завершения транзакции данные не должны теряться даже при сбоях (например, отключении электричества).
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
- ConcurrentHashMap;
- CopyOnWriteArrayList;
- CopyOnWriteArraySet;
- BlockingQueue и её реализации (LinkedBlockingQueue, ArrayBlockingQueue);
- ConcurrentSkipListMap, ConcurrentSkipListSet;
Они позволяют безопасно работать в многопоточном окружении без явной синхронизации.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍14🔥1
Spring Bean – это ОБЪЕКТ, который управляется Spring-контейнером.
Обычный класс (НЕ Bean)
class Car {
void drive() {
System.out.println("Машина едет...");
}
}public class Main {
public static void main(String[] args) {
Car car = new Car(); // Создание обычного объекта вручную
car.drive();
}
}Bean в Spring
import org.springframework.stereotype.Component;
@Component // Аннотация говорит Spring, что этот класс – Bean
class Car {
void drive() {
System.out.println("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); // Получаем объект из Spring-контейнера
car.drive();
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
- PRIMARY KEY — уникальность и не-null.
- FOREIGN KEY — ссылка на другой ключ.
- UNIQUE — уникальность значений.
- NOT NULL — запрет на пустые значения.
- CHECK — логическое условие.
- DEFAULT — значение по умолчанию.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊8👍5🔥2
В основе фреймворка Spring лежит концепция инверсии управления (IoC, Inversion of Control) и внедрения зависимостей (DI, Dependency Injection). Эти принципы обеспечивают гибкость, расширяемость и удобство в управлении зависимостями между компонентами приложения, делая код более модульным, тестируемым и поддерживаемым.
Это парадигма, при которой контроль над выполнением программы частично или полностью передаётся фреймворку или библиотеке. В контексте Spring IoC означает, что сам фреймворк управляет созданием объектов и их жизненным циклом, а не программист напрямую. Это достигается через использование "контейнера IoC", который автоматически создаёт и связывает объекты в соответствии с конфигурацией приложения, заданной в XML-файлах, аннотациях или Java-конфигурации.
Это техника реализации IoC, при которой объектам "внедряются" или "предоставляются" их зависимости извне. Вместо того чтобы компоненты приложения самостоятельно создавали или искали необходимые им объекты (зависимости), Spring контейнер автоматически предоставляет им все необходимые зависимости в момент создания объекта. Это уменьшает связность между компонентами и упрощает управление зависимостями, а также их изменение и тестирование.
Включает в себя IoC и DI, обеспечивая основу для фреймворка.
Позволяет реализовывать поперечные задачи (например, логирование, транзакции) в виде аспектов, не изменяя основной бизнес-логики.
Фреймворк для создания веб-приложений по модели MVC.
Предоставляет набор инструментов для быстрой разработки и запуска приложений с минимальной конфигурацией.
Упрощает доступ к данным, работу с базами данных и операциями CRUD.
Предоставляет комплексные средства безопасности для аутентификации и авторизации.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🤔1
Модель OSI включает семь уровней:
1. Физический уровень
2. Канальный уровень
3. Сетевой уровень
4. Транспортный уровень
5. Сеансовый уровень
6. Представительный уровень
7. Прикладной уровень
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥4🤔1
REST – это удобный и популярный архитектурный стиль, но в высоконагруженных системах у него есть недостатки.
Проблема: Каждый REST-запрос передаёт много мета-информации (заголовки, cookies, CORS, JSON/XML).
GET /users/123 HTTP/1.1
Host: api.example.com
Authorization: Bearer token123
Content-Type: application/json
В WebSocket/gRPC запрос выглядел бы так
{ "userId": 123 }Проблема: REST использует "запрос-ответ", но **не поддерживает real-time.
Что происходит в REST?
1. Клиент делает HTTP-запрос к серверу.
2. Сервер обрабатывает и отправляет ответ.
3. Если клиенту нужно новое сообщение, он снова делает запрос (Polling) или использует Long Polling.
Проблема: Не все REST-запросы можно кэшировать.
Кэшируются только
GET-запросы (если сервер поддерживает ETag и Cache-Control). POST, PUT, DELETE – не кэшируются, потому что меняют данные. Проблема: REST требует много отдельных запросов, если нужно загрузить связанные данные.
Пример проблемы REST:
Получить пользователя:
/users/123 Получить заказы этого пользователя:
/users/123/orders Получить детали заказов:
/orders/456/detailsСтавь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍16💊1
Проверяет условие на двух параметрах, возвращает boolean. Пример — сравнение двух строк или валидация пары значений.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥2
Синхронизация — это механизм, который используется для контроля доступа к общим ресурсам или критическим секциям кода в среде, где несколько потоков или процессов могут одновременно выполняться. Основная цель — обеспечить корректное взаимодействие между потоками, предотвращая одновременное выполнение определённых участков кода, которые могут привести к конфликтам или неконсистентному состоянию данных.
Гонка данных возникает, когда два или более потоков одновременно пытаются изменить общие данные, и результат выполнения зависит от того, в каком порядке потоки выполняют операции. Синхронизация помогает управлять доступом к данным таким образом, чтобы обеспечить их целостность.
В многопоточной среде изменения, сделанные одним потоком в общем ресурсе, могут не быть сразу видны другим потокам из-за кэширования данных в процессорах или оптимизаций компилятора. Синхронизация гарантирует, что изменения, сделанные одним потоком, будут корректно видны другим потокам.
Некоторые операции или ресурсы требуют последовательного доступа для предотвращения конфликтов или некорректной работы. Например, запись в файл или обновление базы данных должны выполняться последовательно, чтобы избежать наложения данных или повреждения структуры данных.
synchronizedМожет использоваться для блокировки целого метода или определённого блока кода, обеспечивая монопольный доступ к этому участку кода для одного потока одновременно.
java.util.concurrent.locksПредоставляют более гибкие возможности для управления блокировками, включая попытку захвата блокировки без ожидания, захват прерываемых блокировок и блокировки с возможностью повторного входа.
volatile)Обеспечивают видимость изменений переменных между разными потоками, но не контролируют последовательность доступа к переменной.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Асинхронные сообщения — это обмен сообщениями между сервисами, при котором отправитель не ждёт немедленного ответа. Получатель может обработать сообщение позже. Используются в микросервисах и очередях.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥3
Каждый бин (компонент) проходит через жизненный цикл, который начинается с его создания и заканчивается уничтожением. Этот цикл включает в себя ряд этапов, на которых он предоставляет различные точки для настройки поведения бина. Вот основные этапы жизненного цикла:
Создает экземпляр бина из класса определения бина.
Внедряет значения и ссылки на другие бины в свойства текущего бина, используя конфигурацию, заданную в XML, аннотациях или конфигурации.
Если бин реализует один из Aware интерфейсов, он вызывает соответствующие методы, передавая экземпляру бина ссылку на контекст, фабрику бинов и т.д.
Перед инициализацией бина, он дает возможность BeanPostProcessor'ам обработать объект. Это может быть использовано для проксирования бинов или для иной предварительной обработки.
Если для бина определен метод инициализации (через аннотацию
@PostConstruct, интерфейс InitializingBean или атрибут init-method в XML-конфигурации), он вызывает его после того, как все свойства бина были установлены.После вызова метода инициализации бин полностью инициализирован и готов к использованию в приложении.
Когда контекст приложения закрывается, и бины должны быть уничтожены, он вызывает метод уничтожения для бинов, которые определяют его (через аннотацию
@PreDestroy, интерфейс DisposableBean или атрибут destroy-method в XML-конфигурации).Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥1
Также O(n) — при множестве коллизий и плохой хеш-функции, все элементы могут оказаться в одной цепочке.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥4
В 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
👍13
Способы:
- ключевое слово synchronized;
- Lock из java.util.concurrent.locks;
- потокобезопасные коллекции (ConcurrentHashMap, CopyOnWriteArrayList);
- атомарные переменные (AtomicInteger, AtomicReference).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
В MySQL (и других реляционных БД) типы данных
DATETIME и TIMESTAMP используются для хранения даты и времени, но у них есть несколько ключевых отличий. Используйте
DATETIME, если: Нужно хранить фиксированное значение даты и времени, не зависящее от часового пояса.
Работаете с датами за пределами 1970-2038 гг.
Требуется удобочитаемый формат (без конверсий).
Используйте
TIMESTAMP, если: Нужно учитывать часовой пояс (например, хранить время в UTC, а при запросе автоматически конвертировать в локальное).
Важно автоматическое обновление при изменении строки (
ON UPDATE CURRENT_TIMESTAMP). Нужно экономить память (занимает в 2 раза меньше места, чем
DATETIME). DATETIME (Фиксированная дата и время)
CREATE TABLE events (
id INT PRIMARY KEY,
event_time DATETIME NOT NULL
);
INSERT INTO events VALUES (1, '2025-02-17 12:30:00');
TIMESTAMP (Автообновление + Часовые пояса)
CREATE TABLE logs (
id INT PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
Если изменим
time_zone, TIMESTAMP отобразится в новом часовом поясе. SET time_zone = 'Europe/Moscow';
SELECT created_at FROM logs;
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7