class ATM {

В показанном фрагменте выдача увеличивает остатки через Integer::sum, хотя должна уменьшать их. Расчёт набора купюр и его списание необходимо выполнять атомарно; код также содержит необъявленные переменные.

Короткий ответ

Что ответить на собеседовании

В показанном фрагменте выдача увеличивает остатки через Integer::sum, хотя должна уменьшать их. Расчёт набора купюр и его списание необходимо выполнять атомарно; код также содержит необъявленные переменные.

Подробный разбор

Ответ с пояснениями

Условие

class ATM { public Map<Integer, Integer> withdraw(int amount, String currency) throws Exception { int use = Math.min(need, available); if( use > 0) { result.put(denomination, use); remaining -= denomination*use; }

    if(remaining != 0) {
        throw new Exception();
    }

    result.forEach((Integer denomination, Integer count)
        -> bills.merge(denomination, count, Integer::sum));

    return result;
}

}

Ответ

В показанном фрагменте выдача увеличивает остатки через Integer::sum, хотя должна уменьшать их. Расчёт набора купюр и его списание необходимо выполнять атомарно; код также содержит необъявленные переменные.

При условии, что result уже рассчитан и проверен, финальное обновление должно вычитать count:

result.forEach((denomination, count) ->
    bills.put(denomination, bills.get(denomination) - count));

Это не полная реализация: весь расчёт и списание защищают одним lock либо транзакцией, иначе конкурентная выдача нарушит остатки. Проверяют amount > 0 и валюту. Жадный выбор крупнейших купюр при ограниченных остатках не всегда находит существующую комбинацию: например, 6 из купюр 4, 3, 3.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее