Библиотека собеса по Java | вопросы с собеседований
6.36K subscribers
354 photos
4 videos
188 links
Вопросы с собеседований по Java и ответы на них.

По рекламе: @proglib_adv

Учиться у нас: https://proglib.io/w/08c603b6

Работать у нас: https://job.proglib.io/

Наши каналы: https://yangx.top/proglibrary/9197
加入频道
В чем разница между final, finally и finalize() в Java?

Эти три термина часто путают, но они имеют принципиально разные значения:

🔹 final — это ключевое слово, используемое для ограничения:
▪️ Переменная: значение не может быть изменено после инициализации.
▪️ Метод: не может быть переопределён в подклассе.
▪️ Класс: запрещает наследование.

🔹 finally — это блок кода, который всегда выполняется после блока try-catch, независимо от того, было ли исключение выброшено или нет. Часто используется для освобождения ресурсов (например, закрытия файлов или потоков).

🔹 finalize() — это метод, который вызывается сборщиком мусора перед уничтожением объекта. Использовался для освобождения ресурсов, но сейчас его использование не рекомендуется из-за непредсказуемости момента вызова.
Please open Telegram to view this post
VIEW IN TELEGRAM
Разница между «Lambdas» и «Anonymous Classes»

— Лямбда-выражения имеют лаконичный синтаксис по сравнению с анонимными классами. Лямбды проще читать и писать, так как они не требуют явного объявления метода, тогда как анонимные классы содержат больше «лишнего» кода.

— Лямбды используются, когда интерфейс имеет один абстрактный метод (функциональные интерфейсы), тогда как анонимные классы могут реализовать несколько методов и применяться для интерфейсов с несколькими методами.

— Лямбды могут быть более эффективными, так как они компилируются в байт-код, который может быть оптимизирован. Анонимные классы обычно компилируются как отдельные классы, что может требовать больше ресурсов.
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое Heap и Stack?

🔹 Heap (Куча):
Это область памяти, где хранятся объекты и динамически создаваемые данные. Всё, что создаётся с помощью оператора new, помещается в кучу. Управление памятью здесь осуществляется автоматически через сборщик мусора (Garbage Collector). Память на куче выделяется динамически, и она имеет больший объём, чем стек.

🔹 Stack (Стек):
Это область памяти, где хранятся примитивные типы данных (int, float и т.д.) и ссылки на объекты, которые находятся в куче. Стек работает по принципу LIFO (последним пришёл — первым ушёл), и память выделяется под локальные переменные методов. Память на стеке освобождается автоматически, когда метод завершает выполнение.
Please open Telegram to view this post
VIEW IN TELEGRAM
В чем разница между sleep() и wait()?

🔹 sleep():

▪️ Приостанавливает выполнение текущего потока на заданное количество времени.
▪️ Не освобождает монитор (блокировку) объекта.
▪️ Вызывается как статический метод Thread.sleep(millis).

🔹 wait():

▪️ Приостанавливает текущий поток до тех пор, пока другой поток не вызовет метод notify() или notifyAll() на том же объекте.
▪️ Освобождает монитор объекта, позволяя другим потокам его использовать.
▪️ Вызывается на любом объекте, внутри синхронизированного блока synchronized.

Используйте sleep() для временной паузы, а wait() для синхронизации между потоками.
Please open Telegram to view this post
VIEW IN TELEGRAM
В чем разница между LinkedHashMap и TreeMap в Java?

🔹 Порядок хранения элементов:

▪️ LinkedHashMap сохраняет порядок вставки элементов. То есть, когда вы итерируете по коллекции, элементы будут возвращаться в том порядке, в котором они были добавлены.
▪️ TreeMap, с другой стороны, сортирует элементы по ключу. Это означает, что порядок следования элементов при итерации определяется натуральным порядком ключей (если ключи реализуют Comparable) или компаратором, который вы передадите.

🔹 Время доступа к элементам:

▪️ LinkedHashMap использует хеш-таблицу, и поэтому в среднем имеет более быстрый доступ к элементам — поиск, вставка и удаление выполняются в среднем за время, близкое к O(1).
▪️ TreeMap реализована на основе красно-чёрного дерева, что делает операции поиска, вставки и удаления в среднем более медленными — за время O(log n), так как элементы поддерживаются в отсортированном виде.

🔹 Использование в различных задачах:

▪️ LinkedHashMap подходит для задач, где важен порядок вставки элементов, например, при реализации кэша с ограниченным количеством элементов.
▪️ TreeMap полезна, когда необходимо хранить элементы в отсортированном порядке или когда важен быстрый поиск минимального/максимального ключа.
Please open Telegram to view this post
VIEW IN TELEGRAM
В чем разница между перегрузкой метода и переопределением метода?

🔵 Перегрузка метода (Overloading):

▪️ Параметры метода должны отличаться — это могут быть разные типы, количество или порядок параметров.
▪️ Наследование не требуется. Все происходит внутри одного класса.


public void Print(int number) {  }
public void Print(string text) { }


🔵 Переопределение метода (Overriding):


▪️ Параметры метода должны быть идентичны (тип, количество и порядок).
▪️ Наследование обязательно. Метод переопределяется в классе-наследнике для изменения поведения базового метода.


class Animal {
public void sound() { System.out.println("Animal sound"); }
}

class Dog extends Animal {
@Override
public void sound() { System.out.println("Dog barks"); }
}
Please open Telegram to view this post
VIEW IN TELEGRAM
🧑‍💻 Статьи для IT: как объяснять и распространять значимые идеи

Напоминаем, что у нас есть бесплатный курс для всех, кто хочет научиться интересно писать — о программировании и в целом.

Что: семь модулей, посвященных написанию, редактированию, иллюстрированию и распространению публикаций.

Для кого: для авторов, копирайтеров и просто программистов, которые хотят научиться интересно рассказывать о своих проектах.

👉Материалы регулярно дополняются, обновляются и корректируются. А еще мы отвечаем на все учебные вопросы в комментариях курса.
Как работает механизм компиляции JIT (Just-In-Time) в JVM?

JIT-компиляция — это механизм в JVM, который позволяет динамически компилировать байт-код в машинный код во время выполнения программы. Он объединяет в себе преимущества интерпретации и компиляции.

1. Основные этапы работы JIT:

🔹 Интерпретация байт-кода:
Сначала JVM интерпретирует байт-код, строчка за строчкой. Это позволяет быстрее запускать программы.

🔹 Сбор статистики:
JVM отслеживает, какие методы выполняются чаще всего (горячие методы). Для этого используется счётчик вызовов.

🔹 Триггер для компиляции:
Когда счётчик вызовов достигает определённого порога, JVM принимает решение скомпилировать этот метод в машинный код с помощью JIT. Это позволяет ускорить выполнение программы, так как скомпилированный машинный код выполняется гораздо быстрее.

🔹 Оптимизации:
▪️ Inlining: Встраивание часто вызываемых методов прямо в вызывающий код, что уменьшает накладные расходы на вызов методов.
▪️ Unboxing и устранение лишних объектов: Это снижает затраты на выделение памяти и сборку мусора.
▪️ Удаление мёртвого кода: Устранение инструкций, которые никогда не будут выполнены.

2. Профилирование и адаптивная оптимизация:

JIT использует адаптивный подход, который позволяет JVM оптимизировать код на основе реальных данных профилирования. Например, если JVM видит, что одна ветка условия выполняется чаще, она может оптимизировать её исполнение.

3. Кэширование и компиляция на лету:

Скомпилированный машинный код кэшируется в памяти, что позволяет JVM использовать его при последующих вызовах метода без необходимости повторной интерпретации или компиляции.

4. Видов JIT-компиляции несколько:

🔹C1-компилятор: Работает с менее оптимизированным кодом, но быстрее компилирует его. Обычно используется на ранних этапах работы программы.
🔹C2-компилятор: Более агрессивный и выполняет больше оптимизаций, но компиляция занимает больше времени. Используется для часто вызываемых методов.
Please open Telegram to view this post
VIEW IN TELEGRAM
❗️Задача для конкурса в честь дня программиста

Условие:

Даны две строки s и f (начальная и конечная) и словарь D (набор слов).

Нужно определить, можно ли преобразовать s в f, используя только слова из словаря D. При этом каждое преобразование должно менять только один символ, а длина слова должна оставаться неизменной. Если преобразование возможно, нужно найти кратчайшую последовательность таких преобразований и вернуть ее длину. Если преобразование невозможно, вернуть "Преобразование невозможно".

Пример ввода 1:
    D = ["cat", "cot", "dot", "dog", "bat", "dag"]
    s = "cat"
    t = "dog"

Вывод:
Минимальное количество шагов для преобразования 'cat' в 'dog': 3

Пример ввода 2:
    D = ["cat", "cot", "bat"]
    s = "cat"
    t = "dog"

Вывод:
Минимальное количество шагов для преобразования 'cat' в 'dog': Преобразование невозможно
Please open Telegram to view this post
VIEW IN TELEGRAM
Как работает AtomicInteger?

AtomicInteger — это класс из пакета java.util.concurrent.atomic, который обеспечивает атомарные операции над целыми числами. Он используется в многопоточных средах без явной синхронизации.

Ключом к потокобезопасности является механизм CAS (Compare-And-Swap), который сравнивает текущее значение переменной с ожидаемым и заменяет его на новое, если значения совпадают. Это предотвращает состояние гонки, так как только один поток может успешно завершить операцию, а остальные будут повторять попытки.

Механизм CAS (Compare-And-Swap):

Представьте, что два потока одновременно пытаются увеличить значение переменной:

Поток A читает значение 10.
Поток B тоже читает значение 10.
Поток A увеличивает значение до 11 и с помощью CAS заменяет 10 на 11.
Поток B пытается сделать то же самое, но так как его ожидаемое значение было 10, а сейчас уже 11, CAS не позволяет ему выполнить замену, и поток B повторяет операцию.


В отличие от блокировок (synchronized), AtomicInteger не блокирует потоки, что делает его более быстрым в условиях параллелизма.
Please open Telegram to view this post
VIEW IN TELEGRAM
Самые полезные каналы для программистов в одной подборке!

Сохраняйте себе, чтобы не потерять 💾

🔥Для всех

Библиотека программиста — новости, статьи, досуг, фундаментальные темы
Книги для программистов
IT-мемы
Proglib Academy — тут мы рассказываем про обучение и курсы
Азбука айтишника — здесь мы познаем азы из мира программирования

🤖Про нейросети
Библиотека робототехники и беспилотников | Роботы, ИИ, интернет вещей
Библиотека нейрозвука | Транскрибация, синтез речи, ИИ-музыка
Библиотека нейротекста | ChatGPT, Gemini, Bing
Библиотека нейровидео | Sora AI, Runway ML, дипфейки
Библиотека нейрокартинок | Midjourney, DALL-E, Stable Diffusion

#️⃣C#

Книги для шарпистов | C#, .NET, F#
Библиотека шарписта — полезные статьи, новости и обучающие материалы по C#
Библиотека задач по C# — код, квизы и тесты
Библиотека собеса по C# — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Вакансии по C#, .NET, Unity Вакансии по PHP, Symfony, Laravel

☁️DevOps

Библиотека devops’а — полезные статьи, новости и обучающие материалы по DevOps
Вакансии по DevOps & SRE
Библиотека задач по DevOps — код, квизы и тесты
Библиотека собеса по DevOps — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования

🐘PHP

Библиотека пхпшника — полезные статьи, новости и обучающие материалы по PHP
Вакансии по PHP, Symfony, Laravel
Библиотека PHP для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по PHP — код, квизы и тесты

🐍Python

Библиотека питониста — полезные статьи, новости и обучающие материалы по Python
Вакансии по питону, Django, Flask
Библиотека Python для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Python — код, квизы и тесты

Java

Книги для джавистов | Java
Библиотека джависта — полезные статьи по Java, новости и обучающие материалы
Библиотека Java для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Java — код, квизы и тесты
Вакансии для java-разработчиков

👾Data Science

Книги для дата сайентистов | Data Science
Библиотека Data Science — полезные статьи, новости и обучающие материалы по Data Science
Библиотека Data Science для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Data Science — код, квизы и тесты
Вакансии по Data Science, анализу данных, аналитике, искусственному интеллекту

🦫Go

Книги для Go разработчиков
Библиотека Go разработчика — полезные статьи, новости и обучающие материалы по Go
Библиотека Go для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по Go — код, квизы и тесты
Вакансии по Go

🧠C++

Книги для C/C++ разработчиков
Библиотека C/C++ разработчика — полезные статьи, новости и обучающие материалы по C++
Библиотека C++ для собеса — тренируемся отвечать на каверзные вопросы во время интервью и технического собеседования
Библиотека задач по C++ — код, квизы и тесты
Вакансии по C++

💻Другие каналы

Библиотека фронтендера
Библиотека мобильного разработчика
Библиотека хакера
Библиотека тестировщика
Вакансии по фронтенду, джаваскрипт, React, Angular, Vue
Вакансии для мобильных разработчиков
Вакансии по QA тестированию
InfoSec Jobs — вакансии по информационной безопасности
Библиотека разработчика игр | Gamedev, Unity, Unreal Engine

📁Чтобы добавить папку с нашими каналами, нажмите 👉сюда👈

Также у нас есть боты:
Бот с IT-вакансиями
Бот с мероприятиями в сфере IT

Мы в других соцсетях:
🔸VK
🔸YouTube
🔸Дзен
🔸Facebook *
🔸Instagram *

* Организация Meta запрещена на территории РФ
Что делает метод Thread.yield()?

Метод yield() — это статический метод класса Thread, который даёт возможность текущему потоку «уступить» своё время процессора другим потокам того же приоритета. Когда поток вызывает этот метод, он переходит в состояние готовности (runnable) и ждёт, пока планировщик потоков вновь даст ему доступ к CPU. Важно отметить, что вызов yield() — это лишь рекомендация, а не обязательное действие для планировщика потоков, и его поведение зависит от реализации JVM.
Please open Telegram to view this post
VIEW IN TELEGRAM
Singleton и его реализации в многопоточной среде

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

Один из популярных способов реализации — это Double-Checked Locking. Он заключается в том, что проверка на существование экземпляра класса производится дважды: до блокировки и после. Это позволяет минимизировать количество синхронизаций, сохраняя потокобезопасность.

Пример реализации:

public class Singleton {
private static volatile Singleton instance;

private Singleton() {}

public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}


Здесь ключевую роль играет ключевое слово volatile, которое предотвращает оптимизацию кэша и гарантирует корректную видимость изменений в разных потоках.
Что такое монолит?

Монолит — это архитектурный стиль, при котором приложение представляет собой единое целое, в котором все модули и компоненты тесно связаны друг с другом и работают как одна программа. Все функциональные части приложения, такие как интерфейс пользователя, бизнес-логика и доступ к данным, объединены в одном проекте и деплоятся одновременно.

🔹 Ключевые особенности:
▪️ Единая кодовая база.
▪️ Центральная точка развертывания.
▪️ Тесная взаимозависимость модулей.
▪️ Масштабируется как единое приложение.

🔹 Плюсы:
▪️ Простота разработки на начальных этапах.
▪️ Легко управлять одной кодовой базой.
▪️ Отсутствие необходимости в сложной инфраструктуре.

🔹 Минусы:
▪️ Сложность масштабирования по частям.
▪️ Высокая связанность увеличивает риски при изменениях.
▪️ Затруднена разработка и развертывание отдельных компонентов.
Please open Telegram to view this post
VIEW IN TELEGRAM
ℹ️ Как устроен под капотом ArrayList?

ArrayList — это реализация динамического массива в Java. Он базируется на массиве, который может изменять свой размер по мере добавления элементов.

🔹 Массив как основа
В основе ArrayList лежит массив типа Object[]. Этот массив инициализируется с начальной емкостью (по умолчанию 10, если не указано иное).

🔹 Динамическое изменение размера
Когда добавляется элемент, а текущий массив заполнен, ArrayList расширяет массив, создавая новый с увеличенной емкостью — обычно это 1.5x от текущего размера. Старые данные копируются в новый массив с помощью System.arraycopy.

🔹 Добавление элементов
▪️ В среднем: добавление элемента занимает O(1), потому что в большинстве случаев просто добавляется новый элемент в конец массива, без необходимости его увеличения.
▪️ В худшем случае: добавление элемента может занять O(n), потому что, если внутренний массив переполняется, ArrayList вынужден создать новый массив большего размера и скопировать в него все существующие элементы.

🔹 Удаление элементов

При удалении элемента сдвигаются все последующие элементы на одну позицию влево, что приводит к сложностям:
▪️ Удаление по индексу: O(n) в худшем случае (сдвиг элементов после удаленного).
▪️ Удаление последнего элемента: O(1).

🔹Преимущества и недостатки

▪️ Преимущества: Быстрое добавление в конец, быстрый доступ по индексу O(1).
▪️ Недостатки: Медленное удаление или вставка в середине массива O(n), особенно при работе с большими коллекциями.
Please open Telegram to view this post
VIEW IN TELEGRAM
Что такое bytecode?

Bytecode — это набор инструкций, которые виртуальная машина Java (JVM) использует для выполнения программ. При компиляции Java-код, не превращается сразу в машинный код, а сначала в bytecode. JVM переводит этот bytecode в машинный код уже во время исполнения программы, что делает Java независимой от платформы — один и тот же байт-код может быть выполнен на любой системе, где есть JVM.

⚙️ Этот подход позволяет добиться переносимости Java-приложений на различные операционные системы без изменения исходного кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
Какая разница между java.util.Collection и java.util.Collections?

🔵 java.util.Collection — это интерфейс, который является основой для всех коллекций в Java. Он определяет общие методы, такие как add(), remove(), size(), и служит для работы с коллекциями объектов. Реализуется такими классами, как ArrayList, HashSet и другими.

Когда нужно работать с базовыми операциями коллекций — добавление, удаление, проверка размера и т. д.


🔵 java.util.Collectionsэто утилитарный класс, который предоставляет набор статических методов для работы с коллекциями. Эти методы позволяют сортировать коллекции, синхронизировать их или возвращать неизменяемые версии коллекций.

Когда нужно выполнять операции над коллекциями, такие как сортировка, синхронизация или создание неизменяемых коллекций.


🚀 Главное отличие:

Collection — это интерфейс, определяющий поведение коллекций.
Collections — это класс, предоставляющий вспомогательные методы для работы с коллекциями.
Please open Telegram to view this post
VIEW IN TELEGRAM
Вакансии «Библиотеки программиста» — ждем вас в команде!

Мы постоянно растем и развиваемся, поэтому создали отдельную страницу, на которой будут размещены наши актуальные вакансии. Сейчас мы ищем:
👉контент-менеджеров для ведения телеграм-каналов

Подробности тут

Мы предлагаем частичную занятость и полностью удаленный формат работы — можно совмещать с основной и находиться в любом месте🌴

Ждем ваших откликов 👾