Главное отличие:
@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
👍6
Популярные инструменты CI/CD (Continuous Integration / Continuous Deployment) включают Jenkins, GitLab CI, GitHub Actions, CircleCI, Travis CI, ArgoCD, Spinnaker, Bamboo. Они автоматизируют процессы сборки, тестирования и развертывания приложений.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
В Java класс Object является базовым родителем для всех классов. Это значит, что любые классы в Java неявно наследуются от него, если явно не указан другой родительский класс. От класса Object каждый класс в Java получает набор методов.
toString()Что делает: Возвращает строковое представление объекта.
Зачем нужен: Этот метод часто используется для вывода объектов в человекочитаемом виде, особенно для отладки или логирования.
Как работает по умолчанию: Возвращает строку, включающую имя класса и хэш-код объекта (неинтуитивно для человека).
Как переопределить: Обычно переопределяют, чтобы возвращать содержимое полей объекта в удобном формате.
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("Анна", 25);
System.out.println(person.toString()); // Person{name='Анна', age=25}
}
}equals(Object obj)Что делает: Проверяет, равны ли два объекта.
Зачем нужен: Сравнивать два объекта на логическое равенство (например, у вас есть два объекта типа Person и вы хотите понять, одинаковые ли у них значения полей).
Как работает по умолчанию: Сравнивает ссылки объектов (т.е. проверяет, указывают ли переменные на один и тот же объект в памяти).
Как переопределить: Переопределяют, чтобы сравнивать содержимое объектов (их поля).
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
}
public class Main {
public static void main(String[] args) {
Person person1 = new Person("Анна", 25);
Person person2 = new Person("Анна", 25);
System.out.println(person1.equals(person2)); // true
}
}hashCode()Что делает: Возвращает числовой хэш-код объекта.
Зачем нужен: Используется для оптимизации работы хэш-структур данных, таких как HashMap, HashSet.
Как работает по умолчанию: Генерирует уникальный хэш-код на основе местоположения объекта в памяти (что не всегда полезно).
Как переопределить: Если переопределён метод equals, обязательно переопределите hashCode, чтобы объекты, которые равны по equals, имели одинаковый хэш-код.
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
return name.hashCode() + age * 31; // Простая, но эффективная формула
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("Анна", 25);
System.out.println(person.hashCode()); // Например, 2084975
}
}Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4💊2
Принимает два аргумента и возвращает результат. Используется для логики преобразования или комбинирования двух значений.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥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
👍7
Нет, основной поток программы нельзя сделать демоном. Демон-потоки должны быть установлены как демоны до их запуска, но основной поток запускается JVM автоматически.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥12👍7
Фиксированный размер – при создании массива его длина задаётся раз и навсегда.
Нельзя изменить размер – нельзя добавить или удалить элементы после создания массива.
int[] numbers = new int[5]; // Размер 5, изменить нельзя!
В Java есть динамические структуры данных, например
ArrayList. import java.util.ArrayList;
import java.util.List;
public class DynamicArrayExample {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list); // [1, 2, 3]
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥1
Если речь о Vue и JavaScript — используется async/await, так как это:
- читаемо;
- удобно обрабатывать ошибки через try/catch;
- лучше сочетается с Promise.
(Вероятно, "send" — это опечатка, могли иметь в виду then).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊42🤔3🔥2
Inversion of Control (IoC) — это принцип проектирования, при котором управление созданием и жизненным циклом объектов передаётся внешней системе.
Без IoC код сильно зависит от конкретных классов, что усложняет тестирование и поддержку.
class Car {
private Engine engine;
public Car() {
this.engine = new Engine(); // Прямое создание зависимости ❌
}
}С IoC (зависимость передаётся извне)
class Car {
private final Engine engine;
public Car(Engine engine) { // Зависимость передаётся через конструктор
this.engine = engine;
}
}IoC достигается через паттерны проектирования, такие как:
Dependency Injection (DI) – передача зависимостей извне (через конструктор, поле или метод).
Factory Method – создание объектов через фабрики.
Event-driven подход – реакция на события вместо явного вызова методов.
Spring реализует IoC через контейнер IoC, который управляет созданием объектов (бинов) и их зависимостями.
@Component
class Engine {}
@Component
class Car {
private final Engine engine;
@Autowired
public Car(Engine engine) { // Spring автоматически передаст нужный объект
this.engine = engine;
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
BDD (Behavior-Driven Development) — это подход к разработке, в котором поведение системы описывается на понятном языке (например, Gherkin). BDD помогает:
- улучшить коммуникацию между командами;
- писать сценарии, ориентированные на поведение;
- интегрировать автотесты с требованиями.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥1💊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
👍9
Сериализация — это механизм сохранения состояния объекта в виде байтов.
Она используется для:
- хранения в файле;
- передачи по сети;
- межпроцессного взаимодействия.
Объекты должны реализовать интерфейс Serializable.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥1💊1
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
👍6
ООП состоит из четырёх ключевых принципов:
1. Инкапсуляция — скрытие реализации внутри объекта.
2. Наследование — повторное использование кода через иерархию.
3. Полиморфизм — способность объектов вести себя по-разному.
4. Абстракция — выделение ключевых характеристик и игнорирование несущественного.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
💊12👍8🔥2🤔1
В Spring действительно можно создать два синглтона, но тут важно понимать, что Spring использует паттерн Singleton на уровне контейнера, а не на уровне JVM. Давайте разберёмся, как это возможно.
В Spring синглтон означает, что в рамках одного контекста (
ApplicationContext) создаётся один экземпляр бина. @Component
public class MySingletonBean {
public MySingletonBean() {
System.out.println("Создан экземпляр MySingletonBean");
}
}
Есть несколько способов создать два синглтона.
Создание двух контекстов (
ApplicationContext) Spring гарантирует синглтонность только в одном контексте. Если создать два контекста, можно получить два независимых синглтона.
AnnotationConfigApplicationContext context1 = new AnnotationConfigApplicationContext(AppConfig.class);
AnnotationConfigApplicationContext context2 = new AnnotationConfigApplicationContext(AppConfig.class);
MySingletonBean bean1 = context1.getBean(MySingletonBean.class);
MySingletonBean bean2 = context2.getBean(MySingletonBean.class);
System.out.println(bean1 == bean2); // false! Два разных объекта
Определение двух бинов одного типа
Можно создать два разных бина, просто давая им разные имена в конфигурации.
@Configuration
public class AppConfig {
@Bean
public MySingletonBean firstSingleton() {
return new MySingletonBean();
}
@Bean
public MySingletonBean secondSingleton() {
return new MySingletonBean();
}
}
Теперь оба метода создадут разные объекты.
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MySingletonBean bean1 = context.getBean("firstSingleton", MySingletonBean.class);
MySingletonBean bean2 = context.getBean("secondSingleton", MySingletonBean.class);
System.out.println(bean1 == bean2); // false
Изменение области (
scope) бина Если изменить область (
@Scope), можно получить два экземпляра в одном контексте, но тогда это уже не будет синглтон. @Component
@Scope("prototype")
public class MyBean {
public MyBean() {
System.out.println("Создан новый экземпляр MyBean");
}
}
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7💊2
Да, начиная с Java 7 можно объединить несколько исключений в одном catch с помощью | (pipe). Это упрощает код, если обработка для них одинаковая.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥4
HQL (Hibernate Query Language) – это язык запросов, используемый в Hibernate (фреймворке для работы с базами данных в Java), который похож на SQL, но оперирует не таблицами и столбцами, а объектами и их свойствами.
Когда мы работаем с базами данных в Hibernate, мы используем объектно-реляционное отображение (ORM), где каждая таблица представляется как класс, а строки – как объекты. Однако иногда нам нужно делать запросы к базе данных, например:
Получить список объектов, соответствующих определённому критерию
Отфильтровать, отсортировать или объединить данные
Выполнить массовое обновление или удаление
Можно, конечно, использовать чистый SQL, но тогда мы потеряем преимущества ORM, такие как переносимость кода между разными базами данных. HQL решает эту проблему, позволяя писать запросы в объектных терминах, а Hibernate сам преобразует их в правильный SQL для конкретной базы данных.
HQL очень похож на SQL, но вместо таблиц и столбцов мы используем имена классов и их полей.
Допустим, у нас есть класс User, связанный с таблицей users:
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
// Геттеры и сеттеры
}
Теперь напишем HQL-запрос, чтобы получить всех пользователей старше 18 ле
String hql = "FROM User WHERE age > 18";
List<User> users = session.createQuery(hql, User.class).getResultList();
Выборка только имен пользователей
String hql = "SELECT u.name FROM User u";
List<String> names = session.createQuery(hql, String.class).getResultList();
Запрос с параметрами (предотвращает SQL-инъекции)
String hql = "FROM User WHERE name = :name";
Query<User> query = session.createQuery(hql, User.class);
query.setParameter("name", "Иван");
List<User> users = query.getResultList();
HQL автоматически адаптируется под MySQL, PostgreSQL, Oracle и другие базы.
вместо таблиц и столбцов мы работаем с сущностями (классами Java).
использование параметров (
setParameter()) предотвращает SQL-инъекции. поддержка JOIN, GROUP BY, ORDER BY и других SQL-конструкций.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Да. forEach — это удобный способ итерации по коллекции:
- используется с лямбдами или методами;
- появился с Java 8;
- реализован в Iterable и Stream.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11💊3
Шардирование – это метод горизонтального разделения базы данных на несколько частей (шардов) для повышения производительности и масштабируемости.
Данные делятся по диапазону значений (например,
ID 1–1000, 1001–2000). Данные распределяются с помощью хеш-функции.
int shardNumber = userId % numberOfShards;
Данные разделяются по географическому признаку (например, Европа, Азия, США). Минимальная задержка (пользователь получает данные ближе к себе)
Некоторые регионы могут перегружаться.
Ставь 👍 и забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Через метод get(key):
- Вычисляется хеш ключа.
- Ищется соответствующий бакет.
- Происходит сравнение ключей через equals().
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥3