В показанном фрагменте выдача увеличивает остатки через Integer::sum, хотя должна уменьшать их. Расчёт набора купюр и его списание необходимо выполнять атомарно; код также содержит необъявленные переменные.
class ATM {
В показанном фрагменте выдача увеличивает остатки через 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.