🤔 Как найти ошибку в программе?
Это процесс отладки (debugging), который позволяет выявить и исправить дефекты в коде. Ошибки в программе могут быть синтаксическими, логическими или связанными с выполнением программы.
1⃣Понимание ошибки
Симптомы ошибки: Программа выдает ошибочное поведение, например, неожиданный результат, исключение или сбой.
Типы ошибок:
Синтаксические: Ошибки в написании кода (например, пропущенная точка с запятой).
Логические: Код выполняется без ошибок, но результат не соответствует ожиданиям.
Ошибки выполнения: Программа завершает работу из-за исключения (например, деление на ноль).
2⃣Использование сообщений об ошибках
Компилятор/интерпретатор: Сообщает о синтаксических ошибках и указывает строку, где возникла проблема.
Стек вызовов (stack trace): Для ошибок выполнения предоставляет информацию о том, где произошла ошибка.
Пример:
3⃣Ручное исследование кода
Прочитайте проблемный участок кода и проверьте его на соответствие логике задачи.
Ищите типичные ошибки, такие как:
Неправильное использование переменных.
Ошибки в условных операторах (
Пропущенные или лишние элементы кода.
4⃣Использование инструментов отладки
Отладчик (Debugger):
Отладчики встроены в IDE, такие как IntelliJ IDEA, Eclipse или NetBeans.
Позволяют ставить точки останова (breakpoints), чтобы программа останавливалась в конкретных местах.
Позволяют пошагово выполнять код и проверять значения переменных.
Логирование (Logging):
Используйте
Пример
5⃣Тестирование
Покрытие тестами: Напишите автоматические тесты для выявления ошибки.
Используйте фреймворки, такие как JUnit или TestNG.
6⃣Анализ чужого кода
Если ошибка в сторонней библиотеке, проверьте документацию и известные проблемы. Убедитесь, что вы правильно используете методы и классы.
7⃣Рефакторинг и исправление
Исправьте ошибку, убедившись, что исправление не приводит к новым ошибкам. Проверьте весь код на предмет аналогичных ошибок.
Ставь 👍 и забирай 📚 Базу знаний
Это процесс отладки (debugging), который позволяет выявить и исправить дефекты в коде. Ошибки в программе могут быть синтаксическими, логическими или связанными с выполнением программы.
1⃣Понимание ошибки
Симптомы ошибки: Программа выдает ошибочное поведение, например, неожиданный результат, исключение или сбой.
Типы ошибок:
Синтаксические: Ошибки в написании кода (например, пропущенная точка с запятой).
Логические: Код выполняется без ошибок, но результат не соответствует ожиданиям.
Ошибки выполнения: Программа завершает работу из-за исключения (например, деление на ноль).
2⃣Использование сообщений об ошибках
Компилятор/интерпретатор: Сообщает о синтаксических ошибках и указывает строку, где возникла проблема.
Стек вызовов (stack trace): Для ошибок выполнения предоставляет информацию о том, где произошла ошибка.
Пример:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Main.main(Main.java:5)
3⃣Ручное исследование кода
Прочитайте проблемный участок кода и проверьте его на соответствие логике задачи.
Ищите типичные ошибки, такие как:
Неправильное использование переменных.
Ошибки в условных операторах (
if, switch).Пропущенные или лишние элементы кода.
4⃣Использование инструментов отладки
Отладчик (Debugger):
Отладчики встроены в IDE, такие как IntelliJ IDEA, Eclipse или NetBeans.
Позволяют ставить точки останова (breakpoints), чтобы программа останавливалась в конкретных местах.
Позволяют пошагово выполнять код и проверять значения переменных.
Логирование (Logging):
Используйте
System.out.println для вывода промежуточных данных: System.out.println("Value of x: " + x);
Пример
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
int x = 10;
int y = 0;
try {
int result = x / y;
} catch (ArithmeticException e) {
logger.error("Division by zero!", e);
}
}
}
5⃣Тестирование
Покрытие тестами: Напишите автоматические тесты для выявления ошибки.
Используйте фреймворки, такие как JUnit или TestNG.
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CalculatorTest {
@Test
void testAddition() {
assertEquals(5, Calculator.add(2, 3));
}
}
6⃣Анализ чужого кода
Если ошибка в сторонней библиотеке, проверьте документацию и известные проблемы. Убедитесь, что вы правильно используете методы и классы.
7⃣Рефакторинг и исправление
Исправьте ошибку, убедившись, что исправление не приводит к новым ошибкам. Проверьте весь код на предмет аналогичных ошибок.
Ставь 👍 и забирай 📚 Базу знаний
👍6
🤔 Какая сложность вставки элемента в LinkedList?
- O(1) — если вставка происходит в начало или конец (через указатель);
- O(n) — если нужно найти позицию по индексу, т.к. происходит линейный проход.
Физическая вставка — быстрая, но поиск позиции может быть медленным.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- O(1) — если вставка происходит в начало или конец (через указатель);
- O(n) — если нужно найти позицию по индексу, т.к. происходит линейный проход.
Физическая вставка — быстрая, но поиск позиции может быть медленным.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍14
🤔 Что стоит в центре парадигмы?
Парадигма программирования определяет способ мышления и подход к написанию кода. В зависимости от выбранной парадигмы, в центре может стоять разное ключевое понятие.
🚩Процедурное программирование
Код строится вокруг последовательности инструкций.
Данные изменяются с помощью вызова функций (процедур).
Пример: C, Pascal.
🚩Объектно-ориентированное программирование (ООП)
Мир представляется в виде объектов, у которых есть состояние (поля) и поведение (методы).
Используются принципы: инкапсуляция, наследование, полиморфизм.
Пример: Java, C++, Python.
🚩Функциональное программирование (FP)
Использование чистых функций (без изменения состояния).
Избегание побочных эффектов и мутабельности.
Пример: Haskell, Scala, Kotlin, Java (Stream API).
Ставь 👍 и забирай 📚 Базу знаний
Парадигма программирования определяет способ мышления и подход к написанию кода. В зависимости от выбранной парадигмы, в центре может стоять разное ключевое понятие.
🚩Процедурное программирование
Код строится вокруг последовательности инструкций.
Данные изменяются с помощью вызова функций (процедур).
Пример: 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 едет!
}
}🚩Функциональное программирование (FP)
Использование чистых функций (без изменения состояния).
Избегание побочных эффектов и мутабельности.
Пример: 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); // Вывод результата
}
}
Ставь 👍 и забирай 📚 Базу знаний
👍9
🤔 Что представляет собой «обмен сообщениями»?
Обмен сообщениями — это концепция взаимодействия между объектами, при которой один объект отправляет сообщение другому для вызова его метода или получения данных. Это основа взаимодействия компонентов в ООП.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Обмен сообщениями — это концепция взаимодействия между объектами, при которой один объект отправляет сообщение другому для вызова его метода или получения данных. Это основа взаимодействия компонентов в ООП.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
💊8👍4🔥1
🤔 Какой цикл жизни Spring Beans?
Каждый бин (компонент) проходит через жизненный цикл, который начинается с его создания и заканчивается уничтожением. Этот цикл включает в себя ряд этапов, на которых он предоставляет различные точки для настройки поведения бина. Вот основные этапы жизненного цикла:
🟠Инстанцирование бина
Создает экземпляр бина из класса определения бина.
🟠Заполнение свойств бина
Внедряет значения и ссылки на другие бины в свойства текущего бина, используя конфигурацию, заданную в XML, аннотациях или конфигурации.
🟠Вызов методов жизненного цикла BeanNameAware
Если бин реализует один из Aware интерфейсов, он вызывает соответствующие методы, передавая экземпляру бина ссылку на контекст, фабрику бинов и т.д.
🟠Post-Processing Bean
Перед инициализацией бина, он дает возможность BeanPostProcessor'ам обработать объект. Это может быть использовано для проксирования бинов или для иной предварительной обработки.
🟠Вызов метода инициализации
Если для бина определен метод инициализации (через аннотацию
🟠Готовность к использованию
После вызова метода инициализации бин полностью инициализирован и готов к использованию в приложении.
🟠Вызов метода уничтожения
Когда контекст приложения закрывается, и бины должны быть уничтожены, он вызывает метод уничтожения для бинов, которые определяют его (через аннотацию
Ставь 👍 и забирай 📚 Базу знаний
Каждый бин (компонент) проходит через жизненный цикл, который начинается с его создания и заканчивается уничтожением. Этот цикл включает в себя ряд этапов, на которых он предоставляет различные точки для настройки поведения бина. Вот основные этапы жизненного цикла:
🟠Инстанцирование бина
Создает экземпляр бина из класса определения бина.
🟠Заполнение свойств бина
Внедряет значения и ссылки на другие бины в свойства текущего бина, используя конфигурацию, заданную в XML, аннотациях или конфигурации.
🟠Вызов методов жизненного цикла BeanNameAware
Если бин реализует один из Aware интерфейсов, он вызывает соответствующие методы, передавая экземпляру бина ссылку на контекст, фабрику бинов и т.д.
🟠Post-Processing Bean
Перед инициализацией бина, он дает возможность BeanPostProcessor'ам обработать объект. Это может быть использовано для проксирования бинов или для иной предварительной обработки.
🟠Вызов метода инициализации
Если для бина определен метод инициализации (через аннотацию
@PostConstruct, интерфейс InitializingBean или атрибут init-method в XML-конфигурации), он вызывает его после того, как все свойства бина были установлены.🟠Готовность к использованию
После вызова метода инициализации бин полностью инициализирован и готов к использованию в приложении.
🟠Вызов метода уничтожения
Когда контекст приложения закрывается, и бины должны быть уничтожены, он вызывает метод уничтожения для бинов, которые определяют его (через аннотацию
@PreDestroy, интерфейс DisposableBean или атрибут destroy-method в XML-конфигурации).Ставь 👍 и забирай 📚 Базу знаний
👍6
🤔 Что произойдёт при вызове Iterator.next() без предварительного Iterator.hasNext()?
Если элементов больше нет — будет выброшено NoSuchElementException. Лучше всегда проверять hasNext().
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Если элементов больше нет — будет выброшено NoSuchElementException. Лучше всегда проверять hasNext().
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍9
🤔 Bean это класс или объект?
Spring Bean – это ОБЪЕКТ, который управляется Spring-контейнером.
🚩Пример: Обычный класс vs. Bean
Обычный класс (НЕ Bean)
Bean в Spring
Ставь 👍 и забирай 📚 Базу знаний
Spring Bean – это ОБЪЕКТ, который управляется Spring-контейнером.
🚩Пример: Обычный класс vs. Bean
Обычный класс (НЕ 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();
}
}
Ставь 👍 и забирай 📚 Базу знаний
💊3👍2
🤔 Что значит первая нормальная форма (1NF)?
1NF требует:
- атомарности значений (одно значение в ячейке);
- отсутствие повторяющихся групп или вложенных структур.
Это означает: ни массивов, ни списков, ни JSON в одном поле — только чёткие, отдельные значения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
1NF требует:
- атомарности значений (одно значение в ячейке);
- отсутствие повторяющихся групп или вложенных структур.
Это означает: ни массивов, ни списков, ни JSON в одном поле — только чёткие, отдельные значения.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥7👍1
🤔 Базовые отличия между List и Linked List?
В Java
🚩Структура данных
🚩Использование памяти
Пример кода: разница в скорости вставки в середину списка
Ставь 👍 и забирай 📚 Базу знаний
В Java
List — это интерфейс, а его самые популярные реализации — ArrayList и LinkedList. Они имеют разную структуру данных, что влияет на производительность и область применения. 🚩Структура данных
ArrayList использует динамический массив, который хранит элементы в непрерывной области памяти. LinkedList — это двусвязный список, где каждый элемент (Node) содержит ссылку на предыдущий и следующий элементы. 🚩Использование памяти
ArrayList требует непрерывного блока памяти, что может быть проблемой при нехватке места. LinkedList требует дополнительной памяти на хранение ссылок (prev и next), что увеличивает общий размер. Пример кода: разница в скорости вставки в середину списка
import java.util.*;
public class ListComparison {
public static void main(String[] args) {
List<Integer> arrayList = new ArrayList<>();
List<Integer> linkedList = new LinkedList<>();
int size = 100000;
// Заполнение списков
for (int i = 0; i < size; i++) {
arrayList.add(i);
linkedList.add(i);
}
// Вставка в середину
long start = System.nanoTime();
arrayList.add(size / 2, 999);
long end = System.nanoTime();
System.out.println("ArrayList вставка в середину: " + (end - start) + " нс");
start = System.nanoTime();
linkedList.add(size / 2, 999);
end = System.nanoTime();
System.out.println("LinkedList вставка в середину: " + (end - start) + " нс");
}
}
Ставь 👍 и забирай 📚 Базу знаний
👍5💊3
🤔 Что является самым главным объектом для всех?
Это корневой базовый класс в Java.
Каждый класс неявно наследует от Object, если не указано иное.
Он задаёт базовые методы: toString, equals, hashCode, getClass, wait, notify, clone и др.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Это корневой базовый класс в Java.
Каждый класс неявно наследует от Object, если не указано иное.
Он задаёт базовые методы: toString, equals, hashCode, getClass, wait, notify, clone и др.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
💊9👍7
🤔 Роль `serialVersionUID` в сериализации
Это уникальный идентификатор версии класса, который используется механизмом сериализации для проверки совместимости классов при десериализации объектов. Он играет ключевую роль в предотвращении ошибок при изменении классов, участвующих в сериализации.
🚩Почему `serialVersionUID` важен?
🟠Гарантия совместимости при десериализации
Когда объект сериализуется (превращается в поток байтов), вместе с ним сохраняется и
🟠Предотвращение ошибок при изменениях класса
Если класс изменяется (например, добавляется новое поле), но
🟠Явное управление версиями
Если
🚩Как использовать `serialVersionUID`?
🚩Что будет, если не указать `serialVersionUID`?
Если не определить
Он будет зависеть от структуры класса.
Малейшее изменение в коде (даже порядок методов) изменит
Это может привести к
Ставь 👍 и забирай 📚 Базу знаний
Это уникальный идентификатор версии класса, который используется механизмом сериализации для проверки совместимости классов при десериализации объектов. Он играет ключевую роль в предотвращении ошибок при изменении классов, участвующих в сериализации.
🚩Почему `serialVersionUID` важен?
🟠Гарантия совместимости при десериализации
Когда объект сериализуется (превращается в поток байтов), вместе с ним сохраняется и
serialVersionUID. При десериализации JVM сравнивает serialVersionUID сохранённого объекта с serialVersionUID текущего класса. Если они не совпадают, выбрасывается исключение InvalidClassException, так как структура класса могла измениться.🟠Предотвращение ошибок при изменениях класса
Если класс изменяется (например, добавляется новое поле), но
serialVersionUID остаётся неизменным, JVM считает, что класс всё ещё совместим с более старой версией, и десериализация проходит успешно.🟠Явное управление версиями
Если
serialVersionUID не указан явно, JVM генерирует его автоматически на основе структуры класса. Это может привести к неожиданным проблемам, если класс изменится, так как автоматически вычисленный serialVersionUID изменится.🚩Как использовать `serialVersionUID`?
import java.io.*;
class Person implements Serializable {
private static final long serialVersionUID = 1L; // Версия класса
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
}
🚩Что будет, если не указать `serialVersionUID`?
Если не определить
serialVersionUID, JVM сгенерирует его автоматически. Однако:Он будет зависеть от структуры класса.
Малейшее изменение в коде (даже порядок методов) изменит
serialVersionUID.Это может привести к
InvalidClassException при десериализации.Ставь 👍 и забирай 📚 Базу знаний
👍11
🤔 Что будет, если добавлять элементы в TreeSet по возрастанию?
TreeSet всегда отсортирован по естественному порядку или Comparator. Добавление по возрастанию не вызывает проблем, структура автоматически сбалансируется (использует Red-Black Tree).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
TreeSet всегда отсортирован по естественному порядку или Comparator. Добавление по возрастанию не вызывает проблем, структура автоматически сбалансируется (использует Red-Black Tree).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍7
🤔 Как бы выразил полиморфизм в коде?
Это способность объектов разных классов реагировать на одинаковые методы по-разному. В Java полиморфизм достигается через наследование, переопределение методов и использование абстрактных классов или интерфейсов.
🚩Пример полиморфизма в коде
Наследование и переопределение методов
Использование интерфейсов
Реальный пример использования полиморфизма
Результат
Ставь 👍 и забирай 📚 Базу знаний
Это способность объектов разных классов реагировать на одинаковые методы по-разному. В Java полиморфизм достигается через наследование, переопределение методов и использование абстрактных классов или интерфейсов.
🚩Пример полиморфизма в коде
Наследование и переопределение методов
class Animal {
public void sound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Dog barks");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Cat meows");
}
}
public class Main {
public static void main(String[] args) {
Animal myDog = new Dog(); // Полиморфизм
Animal myCat = new Cat(); // Полиморфизм
myDog.sound(); // Вывод: Dog barks
myCat.sound(); // Вывод: Cat meows
}
}Использование интерфейсов
interface Shape {
void draw();
}
class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Circle");
}
}
class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
public class Main {
public static void main(String[] args) {
Shape shape1 = new Circle(); // Полиморфизм
Shape shape2 = new Rectangle(); // Полиморфизм
shape1.draw(); // Вывод: Drawing a Circle
shape2.draw(); // Вывод: Drawing a Rectangle
}
}Реальный пример использования полиморфизма
class Animal {
public void sound() {
System.out.println("Some generic animal sound");
}
}
class Dog extends Animal {
@Override
public void sound() {
System.out.println("Woof Woof");
}
}
class Cat extends Animal {
@Override
public void sound() {
System.out.println("Meow");
}
}
public class Main {
public static void main(String[] args) {
Animal[] animals = {new Dog(), new Cat(), new Animal()};
for (Animal animal : animals) {
animal.sound(); // Полиморфный вызов
}
}
}Результат
Woof Woof
Meow
Some generic animal sound
Ставь 👍 и забирай 📚 Базу знаний
👍5
🤔 В каких случаях можно использовать локальное состояние, а в каких глобальный state?
- Локальное состояние (data, ref) — когда данные:
- не нужны другим компонентам;
- касаются только внутренней логики UI (модалки, чекбоксы и т.д.).
- Глобальный state (Vuex, Pinia) — когда:
- нужно делиться данными между компонентами;
- сохраняется авторизация, корзина, настройки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- Локальное состояние (data, ref) — когда данные:
- не нужны другим компонентам;
- касаются только внутренней логики UI (модалки, чекбоксы и т.д.).
- Глобальный state (Vuex, Pinia) — когда:
- нужно делиться данными между компонентами;
- сохраняется авторизация, корзина, настройки.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
💊19👍1
🤔 Есть ли возможность создать два Singleton'а в Spring'е
В Spring действительно можно создать два синглтона, но тут важно понимать, что Spring использует паттерн Singleton на уровне контейнера, а не на уровне JVM. Давайте разберёмся, как это возможно.
🟠Определение Singleton в Spring
В Spring синглтон означает, что в рамках одного контекста (
🟠Два Singleton'а в Spring? Как это возможно?
Есть несколько способов создать два синглтона.
Создание двух контекстов (
Spring гарантирует синглтонность только в одном контексте. Если создать два контекста, можно получить два независимых синглтона.
Определение двух бинов одного типа
Можно создать два разных бина, просто давая им разные имена в конфигурации.
Теперь оба метода создадут разные объекты.
Изменение области (
Если изменить область (
Ставь 👍 и забирай 📚 Базу знаний
В Spring действительно можно создать два синглтона, но тут важно понимать, что Spring использует паттерн Singleton на уровне контейнера, а не на уровне JVM. Давайте разберёмся, как это возможно.
🟠Определение Singleton в Spring
В Spring синглтон означает, что в рамках одного контекста (
ApplicationContext) создаётся один экземпляр бина. @Component
public class MySingletonBean {
public MySingletonBean() {
System.out.println("Создан экземпляр MySingletonBean");
}
}
🟠Два Singleton'а в Spring? Как это возможно?
Есть несколько способов создать два синглтона.
Создание двух контекстов (
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");
}
}
Ставь 👍 и забирай 📚 Базу знаний
👍5
🤔 Что такое ZonedDateTime?
Класс, представляющий дату, время и часовой пояс. Используется, когда важна привязка ко времени по региону (например, Europe/Moscow).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
Класс, представляющий дату, время и часовой пояс. Используется, когда важна привязка ко времени по региону (например, Europe/Moscow).
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍12🔥2
🤔 Что за исключение Interrupted Exception?
🚩Почему `InterruptedException` существует?
В многопоточной среде иногда требуется прервать выполнение потока, например, для завершения долгой задачи или для корректной остановки программы. Вместо грубого завершения потока (
🚩Когда выбрасывается `InterruptedException`?
Это исключение выбрасывается, если поток:
1. Ожидает (
2. Спит (
3. Блокируется на очереди (
И при этом его прерывают с помощью метода
Пример кода: обработка
Вывод программы
🚩Что делать после `InterruptedException`?
1. Просто обработать исключение (как в примере выше).
2. Передать исключение дальше — например, если метод не может корректно обработать прерывание, он передает его вызывающему коду:
🟠Восстановить флаг прерывания
если прерывание важно для логики программы:
Ставь 👍 и забирай 📚 Базу знаний
InterruptedException — это проверяемое исключение (checked exception) в Java, которое выбрасывается, когда поток (Thread) прерывается во время выполнения метода, который поддерживает прерывание (например, sleep(), wait(), join() и др.). 🚩Почему `InterruptedException` существует?
В многопоточной среде иногда требуется прервать выполнение потока, например, для завершения долгой задачи или для корректной остановки программы. Вместо грубого завершения потока (
Thread.stop(), который устарел и считается небезопасным) Java предлагает мягкий способ прерывания через флаг прерывания и обработку InterruptedException.🚩Когда выбрасывается `InterruptedException`?
Это исключение выбрасывается, если поток:
1. Ожидает (
wait(), join()) 2. Спит (
sleep()) 3. Блокируется на очереди (
BlockingQueue.take(), LockSupport.park()) И при этом его прерывают с помощью метода
interrupt().Пример кода: обработка
InterruptedException class MyThread extends Thread {
public void run() {
try {
System.out.println("Поток засыпает...");
Thread.sleep(5000); // Поток засыпает на 5 секунд
} catch (InterruptedException e) {
System.out.println("Поток был прерван во время сна!");
}
System.out.println("Поток продолжает работу...");
}
}
public class Main {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
try {
Thread.sleep(2000); // Даем потоку 2 секунды поработать
} catch (InterruptedException e) {
e.printStackTrace();
}
t.interrupt(); // Прерываем поток
}
}Вывод программы
Поток засыпает...
Поток был прерван во время сна!
Поток продолжает работу...
🚩Что делать после `InterruptedException`?
1. Просто обработать исключение (как в примере выше).
2. Передать исключение дальше — например, если метод не может корректно обработать прерывание, он передает его вызывающему коду:
void myMethod() throws InterruptedException {
Thread.sleep(1000); // Может выбросить исключение
}🟠Восстановить флаг прерывания
если прерывание важно для логики программы:
catch (InterruptedException e) {
Thread.currentThread().interrupt(); // Восстанавливаем флаг прерывания
}Ставь 👍 и забирай 📚 Базу знаний
👍8
🤔 Какой класс реализует динамический массив в Java?
ArrayList — это реализация динамического массива в Java, основанная на обычном массиве. Он автоматически расширяется при добавлении новых элементов и предоставляет методы для управления коллекцией — добавления, удаления, сортировки и доступа по индексу.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
ArrayList — это реализация динамического массива в Java, основанная на обычном массиве. Он автоматически расширяется при добавлении новых элементов и предоставляет методы для управления коллекцией — добавления, удаления, сортировки и доступа по индексу.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍11💊1
🤔 Какие минусы Rest в высоконагруженных сис-мах?
REST – это удобный и популярный архитектурный стиль, но в высоконагруженных системах у него есть недостатки.
🚩Высокие накладные расходы HTTP (избыточность)
Проблема: Каждый REST-запрос передаёт много мета-информации (заголовки, cookies, CORS, JSON/XML).
В WebSocket/gRPC запрос выглядел бы так
🚩REST-запросы неэффективны для чатов и real-time
Проблема: REST использует "запрос-ответ", но **не поддерживает real-time.
Что происходит в REST?
1. Клиент делает HTTP-запрос к серверу.
2. Сервер обрабатывает и отправляет ответ.
3. Если клиенту нужно новое сообщение, он снова делает запрос (Polling) или использует Long Polling.
🚩Проблемы с кэшированием
Проблема: Не все REST-запросы можно кэшировать.
Кэшируются только
🚩REST API неэффективен для сложных запросов
Проблема: REST требует много отдельных запросов, если нужно загрузить связанные данные.
Пример проблемы REST:
Получить пользователя:
Получить заказы этого пользователя:
Получить детали заказов:
Ставь 👍 и забирай 📚 Базу знаний
REST – это удобный и популярный архитектурный стиль, но в высоконагруженных системах у него есть недостатки.
🚩Высокие накладные расходы HTTP (избыточность)
Проблема: Каждый 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 использует "запрос-ответ", но **не поддерживает real-time.
Что происходит в REST?
1. Клиент делает HTTP-запрос к серверу.
2. Сервер обрабатывает и отправляет ответ.
3. Если клиенту нужно новое сообщение, он снова делает запрос (Polling) или использует Long Polling.
🚩Проблемы с кэшированием
Проблема: Не все REST-запросы можно кэшировать.
Кэшируются только
GET-запросы (если сервер поддерживает ETag и Cache-Control). POST, PUT, DELETE – не кэшируются, потому что меняют данные. 🚩REST API неэффективен для сложных запросов
Проблема: REST требует много отдельных запросов, если нужно загрузить связанные данные.
Пример проблемы REST:
Получить пользователя:
/users/123 Получить заказы этого пользователя:
/users/123/orders Получить детали заказов:
/orders/456/detailsСтавь 👍 и забирай 📚 Базу знаний
👍10
🤔 Что означают отношения "являюсь" и "имею" в ООП?
- "Являюсь" (is-a) — отношение наследования:
- Кошка is-a Животное → class Cat extends Animal.
- "Имею" (has-a) — отношение композиции/агрегации:
- Машина has-a Двигатель → class Car { Engine engine; }.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
- "Являюсь" (is-a) — отношение наследования:
- Кошка is-a Животное → class Cat extends Animal.
- "Имею" (has-a) — отношение композиции/агрегации:
- Машина has-a Двигатель → class Car { Engine engine; }.
Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍9🔥3