Dopo anni passati a compilare moduli e ad aspettare, hai finalmente ottenuto la licenza bancaria. Questo significa che ora puoi aprire ufficialmente la tua banca, evviva!
La tua prima priorità è far funzionare i sistemi informatici. Dopo una giornata di duro lavoro, sai già aprire e chiudere conti, oltre a gestire prelievi e versamenti.
Siccome non avevi voglia di scrivere i test, inviti alcuni amici a dare una mano a collaudare il sistema. Però, dopo appena cinque minuti, uno dei tuoi amici sostiene di aver perso dei soldi! Anche se sei sicuro che il tuo codice sia privo di bug, inizi a spulciare i log per indagare.
Ah, già, proprio come sospettavi: la colpa è del tuo amico! Ha condiviso le sue credenziali di test con un altro amico, e insieme hanno cospirato per fare versamenti e prelievi dallo stesso conto in parallelo. Chi mai farebbe una cosa del genere?
Mentre sostieni che sia fisicamente impossibile accedere al proprio conto in parallelo, il tuo amico ti fa notare con aria di sufficienza che le regole bancarie ti impongono di supportarlo. Quindi niente supporto bancario in parallelo, niente via libera per il lancio. Sospirando, ti riprometti mentalmente di occupartene domani. Questo sposterà la data di lancio di almeno un altro giorno, ma vabbè...
Il tuo compito è implementare conti bancari che supportino l'apertura e la chiusura, i prelievi e i depositi di denaro.
Poiché è possibile accedere ai conti bancari in molti modi diversi (internet, telefoni cellulari, addebiti automatici), il software bancario deve permettere di accedere ai conti in modo sicuro da più thread/processi (la terminologia dipende dal linguaggio di programmazione che usi) in parallelo. Ad esempio, possono verificarsi molti depositi e prelievi in parallelo; devi assicurarti che non ci siano race condition tra il momento in cui leggi il saldo del conto e quello in cui imposti il nuovo saldo.
Dovrebbe essere possibile chiudere un conto; le operazioni su un conto chiuso devono fallire.
Questo esercizio introduce la concorrenza.
Per superare l'ultimo test potresti trovare utile la parola chiave synchronized o i lock.
I problemi che derivano dall'esecuzione concorrente del codice sono spesso intermittenti, perché dipendono dall'ordine in cui il codice viene eseguito. Per questo motivo l'ultimo test esegue molti thread più volte, per aumentare le probabilità di individuare un bug. Ciò significa che questo test dovrebbe fallire se la tua implementazione non è thread safe, ma c'è la possibilità che passi semplicemente perché non c'è stato alcun tentativo di modifica concorrente. È improbabile che questo accada più volte di seguito, dato che l'ordine in cui il codice viene eseguito dovrebbe variare ogni volta che esegui il test. Quindi, se esegui l'ultimo test un paio di volte e passa ogni volta, puoi essere ragionevolmente sicuro che la tua implementazione sia corretta.
Iscriviti a Exercism per imparare e padroneggiare Java con 26 concetti158 esercizi e il mentoring di persone reali, tutto gratis.