Java | Вопросы собесов
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @sendme_ads
نمایش بیشتر📈 تحلیل کانال تلگرام Java | Вопросы собесов
کانال Java | Вопросы собесов (@easy_java_ru) در بخش زبانی روسی بازیگری فعال است. در حال حاضر جامعه شامل 11 296 مشترک است و جایگاه 10 943 را در دسته فناوری و برنامهها و رتبه 56 546 را در منطقه روسيا دارد.
📊 شاخصهای مخاطب و پویایی
از زمان ایجاد در невідомо، پروژه رشد سریعی داشته و 11 296 مشترک جذب کرده است.
بر اساس آخرین دادهها در تاریخ 30 اکتبر, 2026، کانال فعالیت پایداری دارد. در ۳۰ روز گذشته تغییر اعضا برابر -36 و در ۲۴ ساعت گذشته برابر -2 بوده و همچنان دسترسی گستردهای حفظ شده است.
- وضعیت تأیید: تأیید نشده
- نرخ تعامل (ER): میانگین تعامل مخاطب 10.39% است و در ۲۴ ساعت نخست پس از انتشار، محتوا معمولاً 5.99% واکنش نسبت به کل مشترکان کسب میکند.
- دسترسی پستها: هر پست به طور میانگین 1 175 بازدید دریافت میکند. در اولین روز معمولاً 677 بازدید جمعآوری میشود.
- واکنشها و تعامل: مخاطبان بهطور فعال حمایت میکنند؛ میانگین واکنش به هر پست 6 است.
- علایق موضوعی: محتوا بر موضوعات کلیدی مانند ставь, void, string, строка, static تمرکز دارد.
📝 توضیح و سیاست محتوایی
نویسنده این فضا را محل بیان دیدگاههای شخصی توصیف میکند:
“Сайт: https://easyoffer.ru/
Все каналы: t.me/+xGeAw6ckJ4liYzQy
Контакт для рекламы: @sendme_ads”
به لطف بهروزرسانیهای پرتکرار (آخرین داده در تاریخ 31 اکتبر, 2026)، کانال همواره بهروز و دارای دسترسی بالاست. تحلیلها نشان میدهد مخاطبان بهطور فعال با محتوا تعامل دارند و آن را به نقطه اثرگذاری مهم در دسته فناوری و برنامهها تبدیل کردهاند.
equals(), он должен быть транзитивным
class Person {
String name;
Person(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Person person = (Person) obj;
return name.equals(person.name);
}
}
public class Main {
public static void main(String[] args) {
Person p1 = new Person("Иван");
Person p2 = new Person("Иван");
Person p3 = new Person("Иван");
System.out.println(p1.equals(p2)); // true
System.out.println(p2.equals(p3)); // true
System.out.println(p1.equals(p3)); // true (транзитивность)
}
}
🚩Транзитивность в сравнении (`compareTo` из `Comparable`)
Метод compareTo() должен соблюдать транзитивность:
class Student implements Comparable<Student> {
int age;
Student(int age) {
this.age = age;
}
@Override
public int compareTo(Student other) {
return Integer.compare(this.age, other.age);
}
}
public class Main {
public static void main(String[] args) {
Student s1 = new Student(25);
Student s2 = new Student(20);
Student s3 = new Student(15);
System.out.println(s1.compareTo(s2)); // > 0 (s1 > s2)
System.out.println(s2.compareTo(s3)); // > 0 (s2 > s3)
System.out.println(s1.compareTo(s3)); // > 0 (s1 > s3) (транзитивность)
}
}
🚩Транзитивность в наследовании (`extends` / `implements`)
В Java классы могут наследоваться транзитивно
class Animal {}
class Mammal extends Animal {}
class Dog extends Mammal {}
Ставь 👍 и забирай 📚 Базу знанийintern() в классе String используется для оптимизации памяти.
Он добавляет строку в String Pool и возвращает её ссылку, если строка уже там есть.
🚩Как работает `intern()`?
Без intern() – строки создаются в Heap (куче)
String s1 = new String("Hello"); // В куче (Heap)
String s2 = new String("Hello");
System.out.println(s1 == s2); // false (разные объекты)
С intern() – строки хранятся в String Pool
String s1 = new String("Hello").intern();
String s2 = new String("Hello").intern();
System.out.println(s1 == s2); // true (одна строка в String Pool)
🚩Что такое `String Pool`?
Это специальная область памяти, где хранятся уникальные строковые литералы.
Все строковые литералы ("Hello") по умолчанию хранятся в String Pool.
String s1 = "Hello"; // В String Pool
String s2 = "Hello"; // Ссылается на тот же объект
System.out.println(s1 == s2); // true
🚩Когда использовать `intern()`?
Когда у вас много одинаковых строк в памяти (например, имена, идентификаторы).
Для экономии памяти, если строки часто дублируются.
В парсинге JSON, XML – одни и те же строки могут повторяться тысячи раз.
List<String> names = new ArrayList<>();
for (int i = 0; i < 100000; i++) {
names.add(("User" + (i % 100)).intern()); // Используем String Pool
}
Ставь 👍 и забирай 📚 Базу знанийBiConsumer<T, U> — это функциональный интерфейс из пакета java.util.function, который принимает два входных аргумента и не возвращает результат.
Сигнатура BiConsumer<T, U>
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
}
🚩Вывод пар значений
Допустим, у нас есть Map<String, Integer>, и мы хотим вывести все ключи и значения:
import java.util.Map;
import java.util.function.BiConsumer;
public class BiConsumerExample {
public static void main(String[] args) {
Map<String, Integer> map = Map.of("Alice", 30, "Bob", 25, "Charlie", 35);
// Используем BiConsumer для вывода ключа и значения
BiConsumer<String, Integer> printEntry = (key, value) ->
System.out.println("Имя: " + key + ", возраст: " + value);
// Применяем BiConsumer к каждому элементу Map
map.forEach(printEntry);
}
}
Вывод
Имя: Alice, возраст: 30 Имя: Bob, возраст: 25 Имя: Charlie, возраст: 35🚩Использование `BiConsumer` в `Stream` Допустим, у нас есть список продуктов и их цены. Мы хотим увеличить цену каждого товара и напечатать результат.
import java.util.*;
import java.util.function.BiConsumer;
public class BiConsumerStreamExample {
public static void main(String[] args) {
Map<String, Double> products = new HashMap<>();
products.put("Хлеб", 50.0);
products.put("Молоко", 80.0);
products.put("Яблоки", 120.0);
// BiConsumer, который увеличивает цену и выводит её
BiConsumer<String, Double> increaseAndPrint = (name, price) -> {
double newPrice = price * 1.1; // +10%
System.out.println(name + " теперь стоит " + newPrice);
};
products.forEach(increaseAndPrint);
}
}
Вывод
Хлеб теперь стоит 55.0 Молоко теперь стоит 88.0 Яблоки теперь стоят 132.0🚩Объединение `BiConsumer` с `andThen()` Метод
andThen(BiConsumer<T, U>) позволяет объединять несколько действий в цепочку.
import java.util.function.BiConsumer;
public class BiConsumerChaining {
public static void main(String[] args) {
BiConsumer<String, Integer> printUser = (name, age) ->
System.out.println("Пользователь: " + name + ", возраст: " + age);
BiConsumer<String, Integer> checkAdult = (name, age) ->
System.out.println(name + (age >= 18 ? " совершеннолетний" : " несовершеннолетний"));
// Объединяем два BiConsumer'а
BiConsumer<String, Integer> combined = printUser.andThen(checkAdult);
combined.accept("Алексей", 20);
combined.accept("Мария", 16);
}
}
Вывод:
Пользователь: Алексей, возраст: 20 Алексей совершеннолетний Пользователь: Мария, возраст: 16 Мария несовершеннолетнийСтавь 👍 и забирай 📚 Базу знаний
public abstract, даже если явно не указаны эти модификаторы.
void myMethod();
🟠Default методы (начиная с Java 8)
Позволяют определять реализацию метода непосредственно в интерфейсе. Классы, реализующие интерфейс, могут переопределять эти методы, но это не обязательно. Default методы были введены для обеспечения обратной совместимости, позволяя добавлять новые методы в интерфейсы без нарушения существующих реализаций.
default void defaultMethod() {
// Реализация
}
🟠Static методы (начиная с Java 8)
Позволяют определять методы с реализацией, которые могут быть вызваны без создания экземпляра класса, реализующего интерфейс. Эти методы нельзя переопределить в реализующем интерфейс классе.
static void staticMethod() {
// Реализация
}
🟠Private методы (начиная с Java 9)
Позволяют определять вспомогательные методы, которые предназначены для использования в default или static методах внутри того же интерфейса. Эти методы не могут быть вызваны извне интерфейса или реализующих его классов.
private void privateMethod() {
// Реализация
}
Пример
public interface MyInterface {
// Абстрактный метод
void abstractMethod();
// Default метод
default void defaultMethod() {
System.out.println("Default implementation");
}
// Static метод
static void staticMethod() {
System.out.println("Static implementation");
}
// Private метод (используется внутри интерфейса)
private void privateMethod() {
System.out.println("Private helper method");
}
}
Ставь 👍 и забирай 📚 Базу знаний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()));
}
}
}
Ставь 👍 и забирай 📚 Базу знаний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); // Санкт-Петербург (изменилось и у оригинала!)
}
}
🟠Как сделать глубокую копию? (Deep Copy)
Решение: Создать новый вложенный объект в clone()
@Override
protected Object clone() throws CloneNotSupportedException {
User clonedUser = (User) super.clone();
clonedUser.address = new Address(this.address.city); // Копируем вложенный объект
return clonedUser;
}
Ставь 👍 и забирай 📚 Базу знанийGROUP BY) или агрегирования (SUM, COUNT, AVG и т.д.).
Используется для фильтрации строк, которые будут включены в результаты группировки или в финальный набор данных, если группировка не используется.
Не может использоваться для фильтрации агрегированных значений.
SELECT employee_id, SUM(salary)
FROM salaries
WHERE salary > 1000
GROUP BY employee_id;
🚩HAVING
Применяется после агрегации данных. Это означает, что фильтрация происходит уже на агрегированных результатах, полученных после применения GROUP BY и агрегатных функций.
Используется для фильтрации групп в результате запроса с группировкой.
Может использоваться только с GROUP BY или для фильтрации результатов, полученных с помощью агрегатных функций.
SELECT employee_id, SUM(salary)
FROM salaries
GROUP BY employee_id
HAVING SUM(salary) > 10000;
Ставь 👍 и забирай 📚 Базу знаний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.
}
}
🚩Почему важна абстракция?
🟠Скрытие сложностей
Программистам не нужно знать все детали реализации объекта. Они работают только с его интерфейсом.
🟠Упрощение понимания
Код становится понятным и модульным, так как мы сосредоточиваемся на важной логике.
🟠Повторное использование
Абстракция позволяет использовать один и тот же код для разных объектов.
🟠Гибкость и поддержка
Если нужно изменить реализацию, это не затронет остальную часть программы (если она работает через абстрактный контракт).
Ставь 👍 и забирай 📚 Базу знанийRandomAccess, потому что он работает с потоком данных, а не с индексированными структурами.
🚩Почему Stream API не поддерживает `RandomAccess`?
🟠Stream – это поток данных
который не обязательно хранится в памяти в виде структуры, поддерживающей случайный доступ.
🟠Нет индексов
в отличие от List, Stream не позволяет получить элемент по индексу (get(index) отсутствует).
🟠Обход последовательный
элементы проходятся один за другим, что делает случайный доступ невозможным.
List (с RandomAccess)
List<Integer> list = new ArrayList<>(List.of(1, 2, 3, 4, 5));
System.out.println(list.get(2)); // Быстрое получение элемента по индексу
Stream (без RandomAccess)
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
stream.skip(2).findFirst().ifPresent(System.out::println); // Ищем 3-й элемент
Ставь 👍 и забирай 📚 Базу знаний