Java | Вопросы собесов
11.5K subscribers
34 photos
2 videos
1.38K links
Download Telegram
🤔 Как ты можешь описать абстракцию?

Это принцип объектно-ориентированного программирования (ООП), который скрывает детали реализации объекта и показывает только его наиболее важные характеристики. Она позволяет сосредоточиться на сущности объекта, игнорируя его внутреннюю сложность.

🚩Абстракция

В 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.
}
}


🚩Почему важна абстракция?

🟠Скрытие сложностей
Программистам не нужно знать все детали реализации объекта. Они работают только с его интерфейсом.
🟠Упрощение понимания
Код становится понятным и модульным, так как мы сосредоточиваемся на важной логике.
🟠Повторное использование
Абстракция позволяет использовать один и тот же код для разных объектов.
🟠Гибкость и поддержка
Если нужно изменить реализацию, это не затронет остальную часть программы (если она работает через абстрактный контракт).

Ставь 👍 и забирай 📚 Базу знаний
👍5
🤔 Для чего нужны функциональные интерфейсы ObjDoubleConsumer<T>, ObjIntConsumer<T>, ObjLongConsumer<T>?

Они позволяют выполнять действие над объектом типа T и примитивом (double, int или long). Используются, когда нужно избежать автоупаковки примитива, например, при работе с парами "объект и число".


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥7👍2💊1
🤔 В чём заключается разница между методами start() и run()?

🚩`start()` – создаёт новый поток

Метод start() создаёт новый поток и вызывает run() внутри него.
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Работает поток: " + Thread.currentThread().getName());
}
}

public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // Запускаем новый поток

System.out.println("Работает поток: " + Thread.currentThread().getName());
}
}


Вывод (разные потоки работают параллельно)
Работает поток: main
Работает поток: Thread-0


🚩`run()` – выполняется в ТЕКУЩЕМ потоке (без создания нового)

Если вызвать run() напрямую, код просто выполнится как обычный метод, а не в новом потоке.
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.run(); // Ошибка! Работает в главном потоке

System.out.println("Работает поток: " + Thread.currentThread().getName());
}
}


Вывод (run() работает в главном потоке, а не в новом)
Работает поток: main
Работает поток: main


Ставь 👍 и забирай 📚 Базу знаний
👍6
🤔 От скольки классов может наследоваться класс?

Класс может наследоваться только от одного класса (одинарное наследование). Это ограничение компенсируется возможностью реализации нескольких интерфейсов.

Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍14
🤔 Как работать на Spring?

Spring – это мощный фреймворк для разработки Java-приложений, который упрощает работу с бэкендом, базами данных и веб-сервисами.

🚩Основные шаги для работы на Spring

1⃣Настроить проект
2⃣Создать контроллеры (обрабатывают HTTP-запросы).
3⃣Добавить сервисы (логика приложения).
4⃣Работать с базой данных (Spring Data JPA, Hibernate).
5⃣Запустить приложение и тестировать.

🚩Настройка проекта (Spring Boot)

🟠Создание проекта через Spring Initializr
Самый быстрый способ – использовать [Spring Initializr](https://start.spring.io/).

Заходим на [start.spring.io](https://start.spring.io/)
Выбираем:
Maven / Gradle
Java 17+
Spring Boot 3+
Зависимости: Spring Web, Spring Data JPA, PostgreSQL/MySQL (если нужна БД)
Скачиваем и открываем в IntelliJ IDEA или VS Code.
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Spring Boot JPA + Hibernate -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Драйвер для PostgreSQL -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>

<!-- Lombok (автоматически генерирует геттеры/сеттеры) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>


🚩Создание контроллера (REST API)

Контроллер обрабатывает HTTP-запросы (GET, POST, PUT, DELETE).
@RestController
@RequestMapping("/hello")
public class HelloController {

@GetMapping
public String sayHello() {
return "Привет, Spring!";
}
}


Запрос в браузере
http://localhost:8080/hello


Ответ
Привет, Spring!


🚩Добавление бизнес-логики (Service Layer)
Сервисы обрабатывают данные и реализуют бизнес-логику.
@Service
public class UserService {

public String getUserGreeting(String name) {
return "Привет, " + name + "!";
}
}


Использование сервиса в контроллере
@RestController
@RequestMapping("/user")
public class UserController {

private final UserService userService;

@Autowired // Внедрение зависимости
public UserController(UserService userService) {
this.userService = userService;
}

@GetMapping("/{name}")
public String getUserGreeting(@PathVariable String name) {
return userService.getUserGreeting(name);
}
}


Запрос в браузере:
http://localhost:8080/user/Иван


Ответ
Привет, Иван!


Ставь 👍 и забирай 📚 Базу знаний
👍6🤔1
🤔 Что такое гетерогенные типы?

Это разнородные типы данных, которые могут сосуществовать в одной структуре (например, в Map<Object, Object>). Они полезны, когда неизвестно заранее, какие данные будут храниться в контейнере.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥6💊5👍3
🤔 Какие знаешь методы чтения XML, опиши сильные и слабые стороны каждого метода?

В Java существуют несколько подходов для чтения XML-файлов, каждый из которых имеет свои преимущества и недостатки.

🚩С использованием DOM (Document Object Model)

XML-файл загружается целиком в память в виде древовидной структуры. Разработчик может работать с узлами (nodes), элементами (elements) и атрибутами (attributes) через API.
import org.w3c.dom.*;
import javax.xml.parsers.*;

public class DomExample {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("example.xml");

NodeList nodeList = doc.getElementsByTagName("element");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
System.out.println(element.getTextContent());
}
}
}


🚩С использованием SAX (Simple API for XML)

XML обрабатывается построчно (по событиям). При чтении вызываются методы обработчика событий (например, начало элемента, конец элемента).
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

public class SaxExample {
public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
parser.parse("example.xml", new DefaultHandler() {
public void startElement(String uri, String localName, String qName, Attributes attributes) {
System.out.println("Start Element: " + qName);
}

public void characters(char[] ch, int start, int length) {
System.out.println("Text: " + new String(ch, start, length));
}

public void endElement(String uri, String localName, String qName) {
System.out.println("End Element: " + qName);
}
});
}
}


🚩С использованием StAX (Streaming API for XML)

XML обрабатывается как поток, но предоставляет больше контроля, чем SAX. Поддерживает чтение и запись.
import javax.xml.stream.*;
import java.io.FileReader;

public class StaxExample {
public static void main(String[] args) throws Exception {
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader reader = factory.createXMLStreamReader(new FileReader("example.xml"));

while (reader.hasNext()) {
int event = reader.next();
if (event == XMLStreamReader.START_ELEMENT) {
System.out.println("Start Element: " + reader.getLocalName());
} else if (event == XMLStreamReader.CHARACTERS) {
System.out.println("Text: " + reader.getText().trim());
} else if (event == XMLStreamReader.END_ELEMENT) {
System.out.println("End Element: " + reader.getLocalName());
}
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
👍6
🤔 Что такое «анонимные классы», где они применяются?

Анонимные классы — это классы без имени, определённые внутри метода.
Применяются, когда:
- нужно реализовать интерфейс или абстрактный класс на месте;
- использовать в Runnable, обработчиках событий и т.п.
С Java 8 и лямбдами используются реже, но применяются в случаях, где нужен доступ к контексту.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍7🔥1
🤔 В чем разница между request mapping и put mapping?

Главное отличие:
@RequestMapping – универсальная аннотация, поддерживающая все HTTP-методы (GET, POST, PUT, DELETE и т. д.).
@PutMapping – специализированная аннотация для PUT-запросов.

🚩`@RequestMapping` – универсальная аннотация

Можно использовать для любого 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 + " обновлён!";
}
}


🚩`@PutMapping` – упрощённый способ для `PUT`-запросов

Это специализированная аннотация, эквивалентная @RequestMapping(method = RequestMethod.PUT).
@RestController
@RequestMapping("/users")
public class UserController {

@PutMapping("/{id}")
public String updateUser(@PathVariable Long id, @RequestBody String userData) {
return "Пользователь с ID " + id + " обновлён!";
}
}


Ставь 👍 и забирай 📚 Базу знаний
👍7💊1
Завтра последний день!

Успей купить пожизненный easyoffer PRO - по цене 1 года

Покупаешь один раз — пользуешься всю жизнь.

👉 Акция до 31 марта: https://easyoffer.ru/pro
🤔 В чём разница между «конкуренцией» и «параллелизмом»?

- Конкуренция (Concurrency) — обработка нескольких задач, которые могут прерывать друг друга, выполняясь поочередно.
- Параллелизм (Parallelism) — одновременная обработка нескольких задач на разных процессорах или ядрах.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍5🔥2
🤔 Где в обработке исключений может применяться конструкция с finally?

Конструкция finally в Java используется для гарантированного выполнения кода, независимо от того, произошло исключение или нет. Обычно применяется для освобождения ресурсов, таких как закрытие файлов, соединений с базой данных или потоков.

🚩Основная структура

try {
// Код, который может выбросить исключение
} catch (Exception e) {
// Обработка исключения
} finally {
// Этот блок выполнится всегда
}


Пример
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream("file.txt");
System.out.println(fileInputStream.read());
} catch (IOException e) {
System.out.println("Ошибка: " + e.getMessage());
} finally {
if (fileInputStream != null) {
fileInputStream.close(); // Всегда закрываем файл
}
}


Ставь 👍 и забирай 📚 Базу знаний
👍4
🤔 Для чего нужна IdentityHashMap?

Для случаев, когда нужно использовать сравнение по ссылке (==), а не equals(), например:
- при кэшировании объектов;
- при построении графов, где важна идентичность объектов.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥9👍4🤔1
🤔 Опиши разницу типов данных DATETIME и TIMESTAMP?

В MySQL (и других реляционных БД) типы данных DATETIME и TIMESTAMP используются для хранения даты и времени, но у них есть несколько ключевых отличий.

🚩Когда использовать `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;


Ставь 👍 и забирай 📚 Базу знаний
👍4
🤔 Зачем нужны сервера приложений, если есть контейнеры сервлетов?

Сервера приложений (например, WildFly, GlassFish) обеспечивают не только поддержку сервлетов, но и расширенные возможности:
- Управление транзакциями;
- EJB-компоненты;
- Распределённые вычисления;
- Более сложные сервисы безопасности.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
🔥2🤔1
🤔 Какие классы поддерживают чтение и запись потоков в компрессированном формате?

Java предоставляет встроенные классы для чтения и записи сжатых данных в формате ZIP, GZIP и других. Эти классы находятся в пакете java.util.zip.

🚩GZIP (формат `.gz`)

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());
}
}
}


🚩ZIP (формат `.zip`)

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);
}
}


🚩Deflater/Inflater (общая компрессия без формата)

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()));
}
}
}


Ставь 👍 и забирай 📚 Базу знаний
👍5
🤔 В чём разница между throws и throw?

- throw — используется для генерации исключения:
- throw new IOException();
- throws — используется в сигнатуре метода, чтобы указать, какие исключения он может выбросить:
- public void read() throws IOException { ... }


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍13
🤔 Как найти ошибку в программе?

Это процесс отладки (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) — если нужно найти позицию по индексу, т.к. происходит линейный проход.
Физическая вставка — быстрая, но поиск позиции может быть медленным.


Ставь 👍 если знал ответ, 🔥 если нет
Забирай 📚 Базу знаний
👍14
🤔 Что стоит в центре парадигмы?

Парадигма программирования определяет способ мышления и подход к написанию кода. В зависимости от выбранной парадигмы, в центре может стоять разное ключевое понятие.

🚩Процедурное программирование

Код строится вокруг последовательности инструкций.
Данные изменяются с помощью вызова функций (процедур).
Пример: 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