몇 년 동안 서류를 작성하고 기다린 끝에, 마침내 은행업 허가를 받았어요. 이제 공식적으로 자신만의 은행을 세울 자격이 생긴 거예요. 만세!
가장 먼저 할 일은 IT 시스템을 돌아가게 만드는 거예요. 하루 동안 열심히 일한 끝에, 이제 계좌를 열고 닫을 수 있고, 출금과 입금도 처리할 수 있어요.
테스트를 작성하기는 귀찮았던 터라, 친구 몇 명을 불러 시스템 테스트를 도와달라고 해요. 그런데 겨우 5분 만에 친구 한 명이 돈을 잃었다고 하네요! 작성한 Code에는 Bug가 없다고 확신하지만, 그래도 조사해 보려고 로그를 뒤져 보기 시작해요.
아, 역시나 예상대로 친구 잘못이었어요! 친구는 자신의 테스트 계정 정보를 다른 친구에게 공유했고, 둘은 짜고 같은 계좌에서 동시에 입금과 출금을 했던 거예요. 누가 이런 짓을 하겠어요?
누군가 자기 계좌에 동시에 접근하는 건 물리적으로 _불가능_하다고 따지지만, 친구는 은행 규정상 이걸 반드시 지원해야 한다고 능글맞게 알려 줘요. 그래서 동시 접근 지원이 없으면 서비스 오픈 신호도 없어요. 한숨을 쉬며, 내일 이걸 처리해야겠다고 머릿속에 메모해 둬요. 이러면 출시일이 최소한 하루는 더 밀리겠지만, 뭐...
이번 과제에서는 계좌 개설과 해지, 출금, 입금을 지원하는 은행 계좌를 구현해요.
은행 계좌에는 인터넷, 휴대폰, 자동 결제 등 다양한 방식으로 접근할 수 있기 때문에, 은행 소프트웨어는 여러 스레드나 프로세스(용어는 사용하는 프로그래밍 언어에 따라 달라요)에서 계좌에 동시에 안전하게 접근할 수 있어야 해요. 예를 들어 입금과 출금이 동시에 여러 번 일어날 수 있는데, 잔액을 읽는 시점과 새 잔액을 설정하는 시점 사이에 경쟁 상태가 생기지 않도록 해야 해요.
계좌를 해지할 수 있어야 하고, 해지된 계좌에 대한 작업은 실패해야 해요.
이 연습 문제에서는 동시성을 소개해요.
마지막 테스트를 통과하려면 synchronized 키워드나 잠금이 도움이 될 거예요.
코드를 동시에 실행하면서 생기는 문제는 코드가 실행되는 순서에 좌우되기 때문에 대개 간헐적으로 나타나요. 그래서 마지막 테스트는 버그를 잡아낼 가능성을 높이기 위해 여러 스레드를 여러 번 실행해요. 즉, 구현이 스레드 안전하지 않다면 이 테스트는 실패해야 하지만, 동시 수정 시도가 없었다는 이유만으로 통과할 가능성도 있어요. 테스트를 실행할 때마다 코드가 실행되는 순서가 달라져야 하므로 이런 일이 연달아 여러 번 일어날 가능성은 낮아요. 그러니까 마지막 테스트를 두어 번 실행했는데 매번 통과한다면, 구현이 올바르다고 어느 정도 확신할 수 있어요.
Exercism에 가입하고 Java 트랙을 개념 26개연습 문제 158개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.