Библиотека собеса по Java | вопросы с собеседований
6.48K subscribers
429 photos
11 videos
704 links
Вопросы с собеседований по Java и ответы на них.

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

Учиться у нас: clc.to/3wECtA

Для обратной связи: @proglibrary_feeedback_bot
Download Telegram
✔️ Concurrency-тест: Реализация Thread-Safe Cache

Напишите потокобезопасный кеш с TTL и размером 👇

📦 Задание


Реализуйте ExpiringCache<K, V> — thread-safe кеш с автоматическим удалением устаревших записей.
public class ExpiringCache<K, V> {
public void put(K key, V value, Duration ttl) { }
public Optional<V> get(K key) { }
public void remove(K key) { }
public int size() { }
}


📋 Требования

1. Функциональность

put() — добавить элемент с TTL (time-to-live)
get() — получить элемент, вернуть Optional.empty() если истёк
remove() — удалить элемент
size() — количество валидных (не истёкших) элементов

2. Потокобезопасность

→ Все операции должны быть thread-safe
→ Минимизировать блокировки (не использовать synchronized на весь объект)
→ Одновременное чтение не должно блокироваться
— Производительность
→ get() должен быть O(1) в среднем случае
→ Автоматическая очистка истёкших записей (passive + active eviction)
→ Не создавать отдельный поток для каждого элемента

3. Ограничения

→ Максимальный размер кеша — 1000 элементов
→ При превышении удалять самые старые записи (LRU)
→ Graceful shutdown при закрытии кеша

Бонус: Добавить метрики (cache hits/misses)

Ставьте → 🔥, если нравится формат. Если нет → 🤔

💬 Пишите решение в комментариях, главное прячьте под спойлер.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👍21
✔️ Collections Challenge: Реализация Custom HashMap

Напишите упрощённую версию HashMap с нуля 👇

📦 Задание

Реализуйте SimpleHashMap<K, V> — собственную реализацию хеш-таблицы без использования готовых Map.

📋 Требования


1. Основная функциональность


→ put() — добавить/обновить пару ключ-значение
→ get() — получить значение по ключу (null если нет)
→ remove() — удалить элемент, вернуть старое значение
→ containsKey() — проверка наличия ключа
→ size() — текущее количество элементов
→ keySet() — множество всех ключей

2. Внутренняя структура

→ Использовать массив buckets (корзин)
→ Collision resolution через связный список (chaining)
→ Начальная ёмкость — 16 элементов
→ Load factor — 0.75

3. Обязательные фичи


→ Автоматическое расширение (resize) при превышении load factor
→ Корректная работа с null ключами
→ Правильный расчёт hashCode (учитывать equals/hashCode contract)
→ Обработка коллизий

Ставьте → 🔥, если нравится формат. Если нет → 🤔

💬 Пишите решение в комментариях, главное прячьте под спойлер.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍21
✔️ Java-тест: Debouncer для частых событий

Напишите метод для production-кода 👇

📦 Задание

Реализуйте debouncer, который откладывает выполнение действия пока события продолжают поступать:

public class Debouncer {
public Debouncer(long delayMs) {
// Ваш код здесь
}

public void call(Runnable action) {
// Ваш код здесь
// Если вызов повторяется до истечения delayMs
// - отменить предыдущий и запланировать новый
// Выполнить только когда delayMs прошло без новых вызовов
}
}


🔹 Требования

— Выполнять action только если delayMs прошло без новых вызовов
— Каждый новый call() отменяет предыдущий таймер
— Использовать ScheduledExecutorService
— Потокобезопасность

🔹 Пример:

Debouncer debouncer = new Debouncer(300); // 300ms
debouncer.call(() -> search(query)); // откладываем
debouncer.call(() -> search(query)); // отменяем предыдущий
debouncer.call(() -> search(query)); // отменяем предыдущий
// Через 300ms выполнится только последний


Ставьте → 🔥, если нравится формат. Если нет → 🤔

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍3👏1
✔️ SQL-тест: Фильтрация активных рекламных кампаний

Задача из реального интервью в Google 👇

📦 Задание

Вы аналитик Google Ads. Нужно найти все объявления, которые:

— Имеют статус 'active'
— Показов больше 500,000
— Обновлены в 2024 году

Таблица google_ads на картинке. Напишите SQL-запрос для фильтрации.

Ставьте → 🔥, если нравится формат. Если нет → 🤔

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍2👏1
✔️ Spring-тест: @RateLimit аннотация для методов

Напишите production-ready Spring компонент 👇

📦 Задание

Реализуйте кастомную аннотацию @RateLimit, которая ограничивает количество вызовов метода с использованием Spring AOP.

🔹 Требования

— Использовать Spring AOP
— Потокобезопасность
— Кэш лимитов
— Учитывать имя метода + параметры
— Custom exception при превышении

Ставьте → 🔥, если нравится формат. Если нет → 🤔

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👏21👍1
✔️ SQL-тест: Топ категорий Google Search

Задача из реального интервью в Google 👇

📦 Задание

Google хочет проанализировать самые популярные категории поиска для оптимизации результатов.

Таблицы на картинке. Напишите запрос для подсчета общего количества поисков в каждой категории по месяцам за 2024 год.

Ставьте → 🔥, если нравится формат. Если нет → 🤔

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍3🤔31
✔️ Java-тест: Transactional + EventListener

Ревью и рефактор логики для production-кода 👇

📦 Задание

Команда написала логику для отправки письма после регистрации пользователя. На проде иногда возникает ситуация, что письма приходят, а юзера в БД нет. Найдите проблему и исправьте:

@Service
@RequiredArgsConstructor
public class UserService {

private final UserRepository userRepository;
private final ApplicationEventPublisher eventPublisher;

@Transactional
public void register(UserDto dto) {
User user = new User(dto.email());
userRepository.save(user);

eventPublisher.publishEvent(new UserRegisteredEvent(user));
}
}

@Component
@RequiredArgsConstructor
public class EmailListener {

private final EmailSender emailSender;
private final SomeOtherService someOtherService;

@EventListener
public void onUserRegistered(UserRegisteredEvent event) {
emailSender.sendWelcome(event.user().getEmail());
someOtherService.doSomething();
}
}


🔹 Задачи

— Объяснить, при каком сценарии письмо уйдёт, а пользователь не сохранится
— Исправить код, чтобы событие обрабатывалось только после сохранения юзера

Ставьте → 🔥, если нравится формат. Если нет → 🌚

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍54🤔1🌚1
✔️ Java-тест: CompletableFuture + ThreadLocal

Классическая ловушка в многопоточке👇

📦 Задание


Написали сервис для аудит-логирования действий пользователей. В проде периодически в лог пишется чужой userId — данные одного юзера попадают в запись другого. Найдите баг и исправьте:

@Component
public class UserContext {
private static final ThreadLocal<String> currentUserId = new ThreadLocal<>();

public static void set(String userId) { currentUserId.set(userId); }
public static String get() { return currentUserId.get(); }
public static void clear() { currentUserId.remove(); }
}

@Service
@RequiredArgsConstructor
public class OrderService {
private final AuditLogger auditLogger;

public CompletableFuture<Order> createOrder(String userId, OrderDto dto) {
UserContext.set(userId);

return CompletableFuture.supplyAsync(() -> {
Order order = buildOrder(dto);
auditLogger.log("Order created by: " + UserContext.get());
return order;
});
}
}


🔹 Задачи

— Объяснить, почему UserContext.get() внутри supplyAsync может вернуть чужой userId или null
— Исправить так, чтобы контекст корректно передавался в асинхронный поток
— Бонус: объяснить, почему ThreadLocal вообще опасен с пулами потоков типа ForkJoinPool

Ставьте → 🔥, если нравится формат. Если нет → 🌚

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19👍41🤔1
✔️ Java-тест: что не так с этим сервисом?

Код компилируется, тесты зелёные, в проде всё ломается 👇

📦 Задание — code review


Сервис обрабатывает заявки на вывод средств. Требования простые: нельзя выводить больше, чем есть на балансе, и нельзя создавать две заявки одновременно.

@Service
@RequiredArgsConstructor
public class WithdrawalService {

private final AccountRepository accountRepository;
private final WithdrawalRepository withdrawalRepository;

public void requestWithdrawal(Long userId, BigDecimal amount) {
Account account = accountRepository.findByUserId(userId)
.orElseThrow();

if (account.getBalance().compareTo(amount) < 0) {
throw new InsufficientFundsException();
}

boolean hasPending = withdrawalRepository
.existsByUserIdAndStatus(userId, Status.PENDING);

if (hasPending) {
throw new WithdrawalAlreadyPendingException();
}

account.setBalance(account.getBalance().subtract(amount));
accountRepository.save(account);

withdrawalRepository.save(
new Withdrawal(userId, amount, Status.PENDING)
);
}
}


🔹 Задачи

Два запроса от одного пользователя прилетели одновременно. В итоге — баланс ушёл в минус и создались две заявки.

▪️ Объясни

— Точную последовательность событий при конкурентных запросах.
— Спасёт @Transactional над методом или нет? Почему?
— Как исправить это корректно.

Ставьте → 🔥, если нравится формат. Если нет → 🌚

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥20👍21🤔1
✔️ Java-тест: кэш убивает прод под нагрузкой

Метрики норм, тесты зелёные, при пике трафика — БД ложится 👇

📦 Задание — code review

Сервис отдаёт профили пользователей. Для ускорения добавили кэш на 5 минут.

@Service
@RequiredArgsConstructor
public class UserProfileService {

private final UserRepository userRepository;
private final RedisTemplate<String, UserProfile> redisTemplate;

private static final Duration TTL = Duration.ofMinutes(5);

public UserProfile getProfile(Long userId) {
String key = "profile:" + userId;

UserProfile cached = redisTemplate.opsForValue().get(key);
if (cached != null) {
return cached;
}

UserProfile profile = userRepository.findById(userId)
.map(UserProfile::from)
.orElseThrow(UserNotFoundException::new);

redisTemplate.opsForValue().set(key, profile, TTL);
return profile;
}
}


▪️ Объясни

— Что именно происходит при истечении TTL под нагрузкой.
— Почему добавление @Cacheable над методом не спасёт ситуацию.

Ставьте → 🔥, если нравится формат. Если нет → 🌚

💬 Решения под спойлер. Сравним, какое будет лучше.

🐸 Библиотека собеса по Java

#practise
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥17👍31