Для учебной in-memory реализации храните балансы в Map и синхронизируйте все операции одним монитором. Перевод проверяет счета, положительность суммы и достаточность средств до изменения данных.
In‑memory financial ledger service implementation
Для учебной in-memory реализации храните балансы в Map и синхронизируйте все операции одним монитором. Перевод проверяет счета, положительность суммы и достаточность средств до изменения данных.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Реализуйте интерфейс LedgerService, который обеспечивает основные банковские операции. Все данные (счета, балансы) должны храниться в памяти с использованием стандартных коллекций Java, таких как HashMap.
import java.math.BigDecimal;
public interface LedgerService {
long createAccount();
void transferFunds(long source, long destination, BigDecimal sum);
BigDecimal getBalance(long id);
}
Ответ
Для учебной in-memory реализации храните балансы в Map и синхронизируйте все операции одним монитором. Перевод проверяет счета, положительность суммы и достаточность средств до изменения данных.
final class InMemoryLedger implements LedgerService {
private final java.util.Map<Long, BigDecimal> balances = new java.util.HashMap<>();
private long nextId;
public synchronized long createAccount() {
long id = Math.incrementExact(nextId);
nextId = id;
balances.put(id, BigDecimal.ZERO);
return id;
}
public synchronized BigDecimal getBalance(long id) {
BigDecimal balance = balances.get(id);
if (balance == null) throw new IllegalArgumentException("Unknown account");
return balance;
}
public synchronized void transferFunds(long source, long destination, BigDecimal sum) {
if (source == destination || sum == null || sum.signum() <= 0)
throw new IllegalArgumentException();
BigDecimal from = getBalance(source), to = getBalance(destination);
if (from.compareTo(sum) < 0) throw new IllegalStateException("Insufficient funds");
BigDecimal newFrom = from.subtract(sum), newTo = to.add(sum);
balances.put(source, newFrom);
balances.put(destination, newTo);
}
}
Импорт BigDecimal из java.math. Интерфейс не содержит пополнения: новые нулевые счета не смогут выполнить положительный перевод без отдельной операции начального зачисления. Валюта, scale и идемпотентность требуют дополнительного контракта; это не production-ledger.