I Failed an Interview. Fair or Not, I Built This Workbook | A practical Java interview prep workbook for fintech coding rounds

 April 2024    28 min read

CodingTutorial
<h1 data-number="1" id="introduction"><span class="header-section-number">1</span> Introduction</h1> <p>Some interview rounds do not ask, <q>How experienced are you?</q> They ask, <q>Can you implement this now?</q></p> <p>This workbook is built for that moment. It gives you hands-on Java drills shaped around fintech workflows, where correctness, edge-case handling, and clean syntax matter more than long explanations.</p> <p>You will move from core language fluency to realistic implementation work: money modeling, transaction validation, ledger updates, stream handling, concurrency, and system-style exercises. Treat each section like a timed lab, and by the end you should be able to read an interview task, design quickly, and code with confidence.</p> <hr /> <h1 data-number="2" id="how-to-use-this-workbook"><span class="header-section-number">2</span> How to Use This Workbook</h1> <ol type="1"> <li>Follow stages in order. Do not skip early syntax drills.</li> <li>Write code yourself before checking any reference implementation.</li> <li>Keep each exercise in a separate class/package.</li> <li>For every exercise, include: <ul> <li>Main implementation</li> <li>At least 3 test cases (happy path, edge case, failure case)</li> </ul></li> <li>Prefer correctness first, then optimization.</li> </ol> <hr /> <h1 data-number="3" id="java-version-and-project-setup"><span class="header-section-number">3</span> Java Version and Project Setup</h1> <ul> <li>Java: 21+</li> <li>Build tool: Maven or Gradle (your choice)</li> <li>Testing: JUnit 5</li> <li>Optional: AssertJ for expressive assertions</li> </ul> <p>Recommended project structure:</p> <pre class="text"><code>src/ main/java/ workbook/ foundation/ domain/ ledger/ stream/ fraud/ orderbook/ capstone/ test/java/ workbook/</code></pre> <hr /> <h1 data-number="4" id="global-domain-models-used-across-exercises"><span class="header-section-number">4</span> Global Domain Models (Used Across Exercises)</h1> <p>Define these once and reuse.</p> <div class="sourceCode" id="cb2"><pre class="sourceCode numberSource java numberLines"><code class="sourceCode java"><span id="cb2-1"><a href="#cb2-1"></a><span class="kw">public</span> <span class="kw">enum</span> TransactionType <span class="op">{</span></span> <span id="cb2-2"><a href="#cb2-2"></a> DEPOSIT<span class="op">,</span></span> <span id="cb2-3"><a href="#cb2-3"></a> WITHDRAWAL<span class="op">,</span></span> <span id="cb2-4"><a href="#cb2-4"></a> TRANSFER</span> <span id="cb2-5"><a href="#cb2-5"></a><span class="op">}</span></span></code></pre></div> <div class="sourceCode" id="cb3"><pre class="sourceCode numberSource java numberLines"><code class="sourceCode java"><span id="cb3-1"><a href="#cb3-1"></a><span class="kw">public</span> <span class="kw">enum</span> EntryType <span class="op">{</span></span> <span id="cb3-2"><a href="#cb3-2"></a> DEBIT<span class="op">,</span></span> <span id="cb3-3"><a href="#cb3-3"></a> CREDIT</span> <span id="cb3-4"><a href="#cb3-4"></a><span class="op">}</span></span></code></pre></div> <div class="sourceCode" id="cb4"><pre class="sourceCode numberSource java numberLines"><code class="sourceCode java"><span id="cb4-1"><a href="#cb4-1"></a><span class="kw">public</span> <span class="dt">final</span> <span class="kw">class</span> Money <span class="op">{</span></span> <span id="cb4-2"><a href="#cb4-2"></a> <span class="kw">private</span> <span class="dt">final</span> <span class="bu">BigDecimal</span> amount<span class="op">;</span></span> <span id="cb4-3"><a href="#cb4-3"></a> <span class="kw">private</span> <span class="dt">final</span> <span class="bu">Currency</span> currency<span class="op">;</span></span> <span id="cb4-4"><a href="#cb4-4"></a></span> <span id="cb4-5"><a href="#cb4-5"></a> <span class="kw">public</span> <span class="fu">Money</span><span class="op">(</span><span class="bu">BigDecimal</span> amount<span class="op">,</span> <span class="bu">Currency</span> currency<span class="op">)</span> <span class="op">{</span></span> <span id="cb4-6"><a href="#cb4-6"></a> <span class="kw">this</span><span class="op">.</span><span class="fu">amount</span> <span class="op">=</span> amount<span class="op">;</span></span> <span id="cb4-7"><a href="#cb4-7"></a> <span class="kw">this</span><span class="op">.</span><span class="fu">currency</span> <span class="op">=</span> currency<span class="op">;</span></span> <span id="cb4-8"><a href="#cb4-8"></a> <span class="op">}</span></span> <span id="cb4-9"><a href="#cb4-9"></a></span> <span id="cb4-10"><a href="#cb4-10"></a> <span class="kw">public</span> <span class="bu">BigDecimal</span> <span class="fu">amount</span><span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> amount<span class="op">;</span> <span class="op">}</span></span> <span id="cb4-11"><a href="#cb4-11"></a> <span class="kw">public</span> <span class="bu">Currency</span> <span class="fu">currency</span><span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> currency<span class="op">;</span> <span class="op">}</span></span> <span id="cb4-12"><a href="#cb4-12"></a><span class="op">}</span></span></code></pre></div> <div class="sourceCode" id="cb5"><pre class="sourceCode numberSource java numberLines"><code class="sourceCode java"><span id="cb5-1"><a href="#cb5-1"></a><span class="kw">public</span> <span class="kw">record</span> <span class="fu">Transaction</span><span class="op">(</span></span> <span id="cb5-2"><a href="#cb5-2"></a> <span class="bu">String</span> id<span class="op">,</span></span> <span id="cb5-3"><a href="#cb5-3"></a> <span class="bu">String</span> accountId<span class="op">,</span></span> <span id="cb5-4"><a href="#cb5-4"></a> Money amount<span class="op">,</span></span> <span id="cb5-5"><a href="#cb5-5"></a> TransactionType type<span class="op">,</span></span> <span id="cb5-6"><a href="#cb5-6"></a> Instant timestamp</span> <span id="cb5-7"><a href="#cb5-7"></a><span class="op">)</span> <span class="op">{}</span></span></code></pre></div> <div class="sourceCode" id="cb6"><pre class="sourceCode numberSource java numberLines"><code class="sourceCode java"><span id="cb6-1"><a href="#cb6-1"></a><span class="kw">public</span> <span class="dt">final</span> <span class="kw">class</span> Account <span class="op">{</span></span> <span id="cb6-2"><a href="#cb6-2"></a> <span class="kw">private</span> <span class="dt">final</span> <span class="bu">String</span> id<span class="op">;</span></span> <span id="cb6-3"><a href="#cb6-3"></a> <span class="kw">private</span> Money balance<span class="op">;</span></span> <span id="cb6-4"><a href="#cb6-4"></a></span> <span id="cb6-5"><a href="#cb6-5"></a> <span class="kw">public</span> <span class="fu">Account</span><span class="op">(</span><span class="bu">String</span> id<span class="op">,</span> Money balance<span class="op">)</span> <span class="op">{</span></span> <span id="cb6-6"><a href="#cb6-6"></a> <span class="kw">this</span><span class="op">.</span><span class="fu">id</span> <span class="op">=</span> id<span class="op">;</span></span> <span id="cb6-7"><a href="#cb6-7"></a> <span class="kw">this</span><span class="op">.</span><span class="fu">balance</span> <span class="op">=</span> balance<span class="op">;</span></span> <span id="cb6-8"><a href="#cb6-8"></a> <span class="op">}</span></span> <span id="cb6-9"><a href="#cb6-9"></a></span> <span id="cb6-10"><a href="#cb6-10"></a> <span class="kw">public</span> <span class="bu">String</span> <span class="fu">id</span><span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> id<span class="op">;</span> <span class="op">}</span></span> <span id="cb6-11"><a href="#cb6-11"></a> <span class="kw">public</span> Money <span class="fu">balance</span><span class="op">()</span> <span class="op">{</span> <span class="cf">return</span> balance<span class="op">;</span> <span class="op">}</span></span> <span id="cb6-12"><a href="#cb6-12"></a> <span class="kw">public</span> <span class="dt">void</span> <span class="fu">setBalance</span><span class="op">(</span>Money newBalance<span class="op">)</span> <span class="op">{</span> <span class="kw">this</span><span class="op">.</span><span class="fu">balance</span> <span class="op">=</span> newBalance<span class="op">;</span> <span class="op">}</span></span> <span id="cb6-13"><a href="#cb6-13"></a><span class="op">}</span></span></code></pre></div> <div class="sourceCode" id="cb7"><pre class="sourceCode numberSource java numberLines"><code class="sourceCode java"><span id="cb7-1"><a href="#cb7-1"></a><span class="kw">public</span> <span class="kw">record</span> <span class="fu">LedgerEntry</span><span class="op">(</span></span> <span id="cb7-2"><a href="#cb7-2"></a> <span class="bu">String</span> accountId<span class="op">,</span></span> <span id="cb7-3"><a href="#cb7-3"></a> Money amount<span class="op">,</span></span> <span id="cb7-4"><a href="#cb7-4"></a> EntryType type</span> <span id="cb7-5"><a href="#cb7-5"></a><span class="op">)</span> <span class="op">{}</span></span></code></pre></div> <hr /> <h1 data-number="5" id="stage-1---foundation-syntax-java-basics-with-fintech-context"><span class="header-section-number">5</span> Stage 1 - Foundation Syntax (Java Basics with Fintech Context)</h1> <details> <summary> Exercise 1 - Currency-Aware Amount Parsing </summary> <h2 data-number="5.1" id="problem-description"><span class="header-section-number">5.1</span> Problem Description</h2> <p>A payment gateway receives user input as text. Build parser logic that converts raw amount strings into valid <code>BigDecimal</code> values.</p> <h2 data-number="5.2" id="input"><span class="header-section-number">5.2</span> Input</h2> <ul> <li><code>String rawAmount</code></li> </ul> <h2 data-number="5.3" id="expected-behaviour"><span class="header-section-number">5.3</span> Expected Behaviour</h2> <ul> <li>Trim spaces</li> <li>Reject empty strings</li> <li>Reject non-numeric values</li> <li>Return parsed value with scale 2 using <code>HALF_EVEN</code></li> </ul> <h2 data-number="5.4" id="constraints"><span class="header-section-number">5.4</span> Constraints</h2> <ul> <li>No <code>double</code>/<code>float</code></li> </ul> <h2 data-number="5.5" id="example"><span class="header-section-number">5.5</span> Example</h2> <ul> <li>Input: <code>&quot; 10.257 &quot;</code></li> <li>Output: <code>10.26</code></li> </ul> <h2 data-number="5.6" id="implementation-requirements"><span class="header-section-number">5.6</span> Implementation Requirements</h2> <ul> <li>Method: <code>BigDecimal parseAmount(String rawAmount)</code></li> <li>Throw <code>IllegalArgumentException</code> for invalid input</li> </ul> <h2 data-number="5.7" id="syntax-focus"><span class="header-section-number">5.7</span> Syntax Focus</h2> <ul> <li><code>try/catch</code>, <code>BigDecimal</code>, method signatures, exceptions</li> </ul> <hr /> </details> <details> <summary> Exercise 2 - Fee Calculator with Conditionals </summary> <h2 data-number="5.8" id="problem-description-1"><span class="header-section-number">5.8</span> Problem Description</h2> <p>Compute transaction fee by amount tier.</p> <h2 data-number="5.9" id="input-1"><span class="header-section-number">5.9</span> Input</h2> <ul> <li><code>BigDecimal amount</code></li> </ul> <h2 data-number="5.10" id="expected-behaviour-1"><span class="header-section-number">5.10</span> Expected Behaviour</h2> <ul> <li><code>&lt; 100</code>: fee = 1.00</li> <li><code>100–1000</code>: fee = 2.50</li> <li><code>&gt; 1000</code>: fee = 5.00</li> </ul> <h2 data-number="5.11" id="constraints-1"><span class="header-section-number">5.11</span> Constraints</h2> <ul> <li>Must use <code>compareTo</code> for numeric comparison</li> </ul> <h2 data-number="5.12" id="example-1"><span class="header-section-number">5.12</span> Example</h2> <ul> <li>Input: <code>250.00</code></li> <li>Output: <code>2.50</code></li> </ul> <h2 data-number="5.13" id="implementation-requirements-1"><span class="header-section-number">5.13</span> Implementation Requirements</h2> <ul> <li>Method: <code>BigDecimal calculateFee(BigDecimal amount)</code></li> </ul> <h2 data-number="5.14" id="syntax-focus-1"><span class="header-section-number">5.14</span> Syntax Focus</h2> <ul> <li><code>if / else if / else</code>, <code>BigDecimal.compareTo</code></li> </ul> <hr /> </details> <details> <summary> Exercise 3 - Daily Batch Total Using Loops </summary> <h2 data-number="5.15" id="problem-description-2"><span class="header-section-number">5.15</span> Problem Description</h2> <p>Settlement service receives a list of amounts and needs the total settled value.</p> <h2 data-number="5.16" id="input-2"><span class="header-section-number">5.16</span> Input</h2> <ul> <li><code>List&lt;BigDecimal&gt; amounts</code></li> </ul> <h2 data-number="5.17" id="expected-behaviour-2"><span class="header-section-number">5.17</span> Expected Behaviour</h2> <ul> <li>Sum all values with scale 2</li> <li>Return zero for empty list</li> </ul> <h2 data-number="5.18" id="example-2"><span class="header-section-number">5.18</span> Example</h2> <ul> <li>Input: <code>[10.00, 20.50, 3.25]</code></li> <li>Output: <code>33.75</code></li> </ul> <h2 data-number="5.19" id="implementation-requirements-2"><span class="header-section-number">5.19</span> Implementation Requirements</h2> <ul> <li>Method: <code>BigDecimal total(List&lt;BigDecimal&gt; amounts)</code></li> <li>Implement twice: <ol type="1"> <li><code>for</code> loop</li> <li>enhanced <code>for-each</code></li> </ol></li> </ul> <h2 data-number="5.20" id="syntax-focus-2"><span class="header-section-number">5.20</span> Syntax Focus</h2> <ul> <li>loops, list iteration, accumulator pattern</li> </ul> <hr /> </details> <details> <summary> Exercise 4 - ATM Action Menu (Switch) </summary> <h2 data-number="5.21" id="problem-description-3"><span class="header-section-number">5.21</span> Problem Description</h2> <p>A command-line ATM simulator supports several operations.</p> <h2 data-number="5.22" id="input-3"><span class="header-section-number">5.22</span> Input</h2> <ul> <li><code>String action</code> (<code>&quot;deposit&quot;</code>, <code>&quot;withdraw&quot;</code>, <code>&quot;balance&quot;</code>)</li> </ul> <h2 data-number="5.23" id="expected-behaviour-3"><span class="header-section-number">5.23</span> Expected Behaviour</h2> <ul> <li>Return message for each action</li> <li>Return <code>&quot;UNKNOWN_ACTION&quot;</code> for unknown values</li> </ul> <h2 data-number="5.24" id="implementation-requirements-3"><span class="header-section-number">5.24</span> Implementation Requirements</h2> <ul> <li>Method: <code>String routeAction(String action)</code></li> <li>Use modern switch expression</li> </ul> <h2 data-number="5.25" id="syntax-focus-3"><span class="header-section-number">5.25</span> Syntax Focus</h2> <ul> <li><code>switch</code> expression, <code>yield</code>, string handling</li> </ul> <hr /> </details> <details> <summary> Exercise 5 - Basic DTO with Constructors and Validation </summary> <h2 data-number="5.26" id="problem-description-4"><span class="header-section-number">5.26</span> Problem Description</h2> <p>Create a transaction request DTO used by a REST controller.</p> <h2 data-number="5.27" id="input-4"><span class="header-section-number">5.27</span> Input</h2> <ul> <li><code>id</code>, <code>accountId</code>, <code>amount</code>, <code>currency</code></li> </ul> <h2 data-number="5.28" id="expected-behaviour-4"><span class="header-section-number">5.28</span> Expected Behaviour</h2> <ul> <li>Constructor enforces non-null fields</li> <li>Getter methods expose fields</li> </ul> <h2 data-number="5.29" id="constraints-2"><span class="header-section-number">5.29</span> Constraints</h2> <ul> <li>Immutable object preferred</li> </ul> <h2 data-number="5.30" id="implementation-requirements-4"><span class="header-section-number">5.30</span> Implementation Requirements</h2> <ul> <li>Class: <code>TransactionRequest</code></li> <li>Either classic class or <code>record</code></li> </ul> <h2 data-number="5.31" id="syntax-focus-4"><span class="header-section-number">5.31</span> Syntax Focus</h2> <ul> <li>constructors, fields, <code>Objects.requireNonNull</code>, access modifiers</li> </ul> <hr /> </details> <details> <summary> Exercise 6 - Safe Divide Utility </summary> <h2 data-number="5.32" id="problem-description-5"><span class="header-section-number">5.32</span> Problem Description</h2> <p>Risk engine computes a ratio and must avoid divide-by-zero crashes.</p> <h2 data-number="5.33" id="input-5"><span class="header-section-number">5.33</span> Input</h2> <ul> <li><code>BigDecimal numerator</code>, <code>BigDecimal denominator</code></li> </ul> <h2 data-number="5.34" id="expected-behaviour-5"><span class="header-section-number">5.34</span> Expected Behaviour</h2> <ul> <li>If denominator is zero, throw custom exception <code>InvalidRatioException</code></li> <li>Else return ratio scale 4 <code>HALF_EVEN</code></li> </ul> <h2 data-number="5.35" id="implementation-requirements-5"><span class="header-section-number">5.35</span> Implementation Requirements</h2> <ul> <li>Custom checked exception class</li> </ul> <h2 data-number="5.36" id="syntax-focus-5"><span class="header-section-number">5.36</span> Syntax Focus</h2> <ul> <li>custom exceptions, <code>throws</code>, arithmetic rules</li> </ul> <hr /> </details> <h1 data-number="6" id="stage-2---core-oop-syntax-and-design"><span class="header-section-number">6</span> Stage 2 - Core OOP Syntax and Design</h1> <details> <summary> Exercise 7 - Immutable Money Object </summary> <h2 data-number="6.1" id="problem-description-6"><span class="header-section-number">6.1</span> Problem Description</h2> <p>Implement a correct financial <code>Money</code> type used in all downstream services.</p> <h2 data-number="6.2" id="input-specification"><span class="header-section-number">6.2</span> Input Specification</h2> <ul> <li><code>BigDecimal amount</code></li> <li><code>Currency currency</code></li> </ul> <h2 data-number="6.3" id="expected-behaviour-6"><span class="header-section-number">6.3</span> Expected Behaviour</h2> <p>Implement: - <code>Money add(Money other)</code> - <code>Money subtract(Money other)</code> - <code>Money multiply(BigDecimal multiplier)</code> - <code>Money negate()</code></p> <p>Rules: 1. Currency mismatch throws exception 2. Result scale = 2, rounding = <code>HALF_EVEN</code></p> <h2 data-number="6.4" id="constraints-3"><span class="header-section-number">6.4</span> Constraints</h2> <ul> <li>No floating-point types</li> </ul> <h2 data-number="6.5" id="example-3"><span class="header-section-number">6.5</span> Example</h2> <ul> <li><code>10.25 USD + 5.30 USD = 15.55 USD</code></li> </ul> <h2 data-number="6.6" id="stretch-goal"><span class="header-section-number">6.6</span> Stretch Goal</h2> <ul> <li><code>Money convert(FxRate rate)</code></li> </ul> <h2 data-number="6.7" id="syntax-focus-6"><span class="header-section-number">6.7</span> Syntax Focus</h2> <ul> <li>immutability, value objects, method chaining</li> </ul> <hr /> </details> <details> <summary> Exercise 8 - Account Ledger (Deposit/Withdraw) </summary> <h2 data-number="6.8" id="problem-description-7"><span class="header-section-number">6.8</span> Problem Description</h2> <p>Create an in-memory account ledger for wallet balances.</p> <h2 data-number="6.9" id="input-6"><span class="header-section-number">6.9</span> Input</h2> <ul> <li><code>Map&lt;String, Account&gt;</code></li> <li>Operations: <ul> <li><code>deposit(accountId, Money amount)</code></li> <li><code>withdraw(accountId, Money amount)</code></li> </ul></li> </ul> <h2 data-number="6.10" id="expected-behaviour-7"><span class="header-section-number">6.10</span> Expected Behaviour</h2> <ul> <li>Deposit increases balance</li> <li>Withdraw decreases balance</li> <li>Negative balance is forbidden</li> </ul> <h2 data-number="6.11" id="constraints-4"><span class="header-section-number">6.11</span> Constraints</h2> <ul> <li>Withdraw beyond balance throws <code>InsufficientFundsException</code></li> </ul> <h2 data-number="6.12" id="example-4"><span class="header-section-number">6.12</span> Example</h2> <ul> <li>Balance <code>100.00</code>, withdraw <code>30.00</code> → <code>70.00</code></li> </ul> <h2 data-number="6.13" id="syntax-focus-7"><span class="header-section-number">6.13</span> Syntax Focus</h2> <ul> <li>map lookups, domain exceptions, mutability boundaries</li> </ul> <hr /> </details> <details> <summary> Exercise 9 - Transaction Validator </summary> <h2 data-number="6.14" id="problem-description-8"><span class="header-section-number">6.14</span> Problem Description</h2> <p>Validate transactions before any posting or fraud checks.</p> <h2 data-number="6.15" id="input-7"><span class="header-section-number">6.15</span> Input</h2> <ul> <li><code>Transaction transaction</code></li> <li><code>Set&lt;String&gt; validAccounts</code></li> <li><code>Set&lt;Currency&gt; supportedCurrencies</code></li> </ul> <h2 data-number="6.16" id="expected-behaviour-8"><span class="header-section-number">6.16</span> Expected Behaviour</h2> <p>Reject if: 1. amount &lt;= 0 2. account missing 3. timestamp in future 4. currency unsupported</p> <h2 data-number="6.17" id="output"><span class="header-section-number">6.17</span> Output</h2> <ul> <li><code>List&lt;String&gt; validationErrors</code> (empty means valid)</li> </ul> <h2 data-number="6.18" id="example-5"><span class="header-section-number">6.18</span> Example</h2> <ul> <li>amount = <code>-10</code> → <code>[&quot;INVALID_AMOUNT&quot;]</code></li> </ul> <h2 data-number="6.19" id="syntax-focus-8"><span class="header-section-number">6.19</span> Syntax Focus</h2> <ul> <li>collection APIs, defensive null checks, enum/error codes</li> </ul> <hr /> </details> <details> <summary> Exercise 10 - Double-Entry Ledger Posting </summary> <h2 data-number="6.20" id="problem-description-9"><span class="header-section-number">6.20</span> Problem Description</h2> <p>Convert business transactions into accounting ledger entries.</p> <h2 data-number="6.21" id="input-8"><span class="header-section-number">6.21</span> Input</h2> <ul> <li><code>Transaction transaction</code></li> </ul> <h2 data-number="6.22" id="output-1"><span class="header-section-number">6.22</span> Output</h2> <ul> <li><code>List&lt;LedgerEntry&gt;</code></li> </ul> <h2 data-number="6.23" id="expected-behaviour-9"><span class="header-section-number">6.23</span> Expected Behaviour</h2> <p>For <code>DEPOSIT</code>: - Debit <code>clearing_account</code> - Credit user account</p> <p>For <code>WITHDRAWAL</code>: - Debit user account - Credit <code>clearing_account</code></p> <h2 data-number="6.24" id="implementation-requirements-6"><span class="header-section-number">6.24</span> Implementation Requirements</h2> <ul> <li>Method: <code>List&lt;LedgerEntry&gt; post(Transaction tx)</code></li> </ul> <h2 data-number="6.25" id="syntax-focus-9"><span class="header-section-number">6.25</span> Syntax Focus</h2> <ul> <li>enum branching, object creation, list factories</li> </ul> <hr /> </details> <details> <summary> Exercise 11 - Batch Settlement Report </summary> <h2 data-number="6.26" id="problem-description-10"><span class="header-section-number">6.26</span> Problem Description</h2> <p>Settlement engine processes daily transactions and produces summary metrics.</p> <h2 data-number="6.27" id="input-9"><span class="header-section-number">6.27</span> Input</h2> <ul> <li><code>List&lt;Transaction&gt; batch</code></li> </ul> <h2 data-number="6.28" id="output-2"><span class="header-section-number">6.28</span> Output</h2> <ul> <li><code>BatchReport</code> with: <ul> <li><code>totalCredits</code></li> <li><code>totalDebits</code></li> <li><code>largestTransaction</code></li> <li><code>smallestTransaction</code></li> <li><code>net</code></li> </ul></li> </ul> <h2 data-number="6.29" id="example-6"><span class="header-section-number">6.29</span> Example</h2> <ul> <li>amounts: <code>+100</code>, <code>-40</code>, <code>+20</code></li> <li>credits <code>120</code>, debits <code>40</code>, net <code>80</code></li> </ul> <h2 data-number="6.30" id="syntax-focus-10"><span class="header-section-number">6.30</span> Syntax Focus</h2> <ul> <li>aggregations, min/max tracking, custom result type</li> </ul> <hr /> </details> <details> <summary> Exercise 12 - Generic Result Wrapper </summary> <h2 data-number="6.31" id="problem-description-11"><span class="header-section-number">6.31</span> Problem Description</h2> <p>Service methods should return either value or error cleanly.</p> <h2 data-number="6.32" id="input-10"><span class="header-section-number">6.32</span> Input</h2> <ul> <li>generic payload type <code>T</code></li> </ul> <h2 data-number="6.33" id="expected-behaviour-10"><span class="header-section-number">6.33</span> Expected Behaviour</h2> <p>Create <code>Result&lt;T&gt;</code> with: - <code>boolean success</code> - <code>T data</code> - <code>String errorCode</code></p> <h2 data-number="6.34" id="implementation-requirements-7"><span class="header-section-number">6.34</span> Implementation Requirements</h2> <ul> <li>Static factories: <code>ok(T data)</code>, <code>fail(String errorCode)</code></li> </ul> <h2 data-number="6.35" id="syntax-focus-11"><span class="header-section-number">6.35</span> Syntax Focus</h2> <ul> <li>generics, static factory methods, null safety</li> </ul> <hr /> </details> <h1 data-number="7" id="stage-3---collections-streams-and-time-aware-processing"><span class="header-section-number">7</span> Stage 3 - Collections, Streams, and Time-Aware Processing</h1> <details> <summary> Exercise 13 - Duplicate Transaction Detection </summary> <h2 data-number="7.1" id="problem-description-12"><span class="header-section-number">7.1</span> Problem Description</h2> <p>Detect duplicate transaction IDs in very large batches.</p> <h2 data-number="7.2" id="input-11"><span class="header-section-number">7.2</span> Input</h2> <ul> <li><code>List&lt;Transaction&gt;</code></li> </ul> <h2 data-number="7.3" id="output-3"><span class="header-section-number">7.3</span> Output</h2> <ul> <li><code>Set&lt;String&gt; duplicateTransactionIds</code></li> </ul> <h2 data-number="7.4" id="constraints-5"><span class="header-section-number">7.4</span> Constraints</h2> <ul> <li>up to 10 million rows</li> <li>target complexity <code>O(n)</code></li> </ul> <h2 data-number="7.5" id="implementation-requirements-8"><span class="header-section-number">7.5</span> Implementation Requirements</h2> <ul> <li>one pass using hash-based sets</li> </ul> <h2 data-number="7.6" id="syntax-focus-12"><span class="header-section-number">7.6</span> Syntax Focus</h2> <ul> <li><code>HashSet</code>, linear-time iteration, memory-conscious coding</li> </ul> <hr /> </details> <details> <summary> Exercise 14 - Currency Volume Aggregator </summary> <h2 data-number="7.7" id="problem-description-13"><span class="header-section-number">7.7</span> Problem Description</h2> <p>Compute total transaction volume grouped by currency.</p> <h2 data-number="7.8" id="input-12"><span class="header-section-number">7.8</span> Input</h2> <ul> <li><code>List&lt;Transaction&gt;</code></li> </ul> <h2 data-number="7.9" id="output-4"><span class="header-section-number">7.9</span> Output</h2> <ul> <li><code>Map&lt;Currency, BigDecimal&gt;</code></li> </ul> <h2 data-number="7.10" id="example-7"><span class="header-section-number">7.10</span> Example</h2> <ul> <li><code>100 USD</code>, <code>200 USD</code>, <code>50 EUR</code> → <code>USD=300</code>, <code>EUR=50</code></li> </ul> <h2 data-number="7.11" id="implementation-requirements-9"><span class="header-section-number">7.11</span> Implementation Requirements</h2> <ul> <li>version A: imperative loop</li> <li>version B: streams collector</li> </ul> <h2 data-number="7.12" id="syntax-focus-13"><span class="header-section-number">7.12</span> Syntax Focus</h2> <ul> <li><code>Map.merge</code>, streams <code>groupingBy</code>, <code>reducing</code></li> </ul> <hr /> </details> <details> <summary> Exercise 15 - Sliding 60s Transaction Window </summary> <h2 data-number="7.13" id="problem-description-14"><span class="header-section-number">7.13</span> Problem Description</h2> <p>Fraud pre-filter needs count of recent transactions per node.</p> <h2 data-number="7.14" id="input-13"><span class="header-section-number">7.14</span> Input</h2> <ul> <li>stream of <code>Transaction</code></li> </ul> <h2 data-number="7.15" id="output-5"><span class="header-section-number">7.15</span> Output</h2> <ul> <li><code>int transactionsLastMinute()</code></li> </ul> <h2 data-number="7.16" id="behaviour"><span class="header-section-number">7.16</span> Behaviour</h2> <ul> <li>keep last 60 seconds only</li> <li>expire old events on read/write</li> </ul> <h2 data-number="7.17" id="example-8"><span class="header-section-number">7.17</span> Example</h2> <ul> <li>t=0,10,50,70 with one tx each → at t=70 count = 3</li> </ul> <h2 data-number="7.18" id="implementation-requirements-10"><span class="header-section-number">7.18</span> Implementation Requirements</h2> <ul> <li>use deque with timestamps</li> </ul> <h2 data-number="7.19" id="syntax-focus-14"><span class="header-section-number">7.19</span> Syntax Focus</h2> <ul> <li>queue/deque operations, <code>Instant</code> and <code>Duration</code></li> </ul> <hr /> </details> <details> <summary> Exercise 16 - Top 100 Largest Transactions </summary> <h2 data-number="7.20" id="problem-description-15"><span class="header-section-number">7.20</span> Problem Description</h2> <p>Compliance dashboard shows top 100 largest transactions in real time.</p> <h2 data-number="7.21" id="input-14"><span class="header-section-number">7.21</span> Input</h2> <ul> <li>transaction stream</li> </ul> <h2 data-number="7.22" id="output-6"><span class="header-section-number">7.22</span> Output</h2> <ul> <li><code>List&lt;Transaction&gt; top100()</code> sorted descending by amount</li> </ul> <h2 data-number="7.23" id="constraints-6"><span class="header-section-number">7.23</span> Constraints</h2> <ul> <li>10 million+ inputs</li> <li>memory must stay <code>O(100)</code></li> </ul> <h2 data-number="7.24" id="implementation-requirements-11"><span class="header-section-number">7.24</span> Implementation Requirements</h2> <ul> <li>min-heap (<code>PriorityQueue</code>) of size 100</li> </ul> <h2 data-number="7.25" id="syntax-focus-15"><span class="header-section-number">7.25</span> Syntax Focus</h2> <ul> <li>comparators, heap maintenance, stream-like ingestion</li> </ul> <hr /> </details> <details> <summary> Exercise 17 - Priority Fraud Queue </summary> <h2 data-number="7.26" id="problem-description-16"><span class="header-section-number">7.26</span> Problem Description</h2> <p>Prioritize suspicious transactions for manual review.</p> <h2 data-number="7.27" id="input-15"><span class="header-section-number">7.27</span> Input</h2> <ul> <li><code>Transaction</code> + <code>riskScore</code></li> </ul> <h2 data-number="7.28" id="output-7"><span class="header-section-number">7.28</span> Output</h2> <ul> <li><code>Transaction pollNext()</code> highest priority first</li> </ul> <h2 data-number="7.29" id="ordering-rules"><span class="header-section-number">7.29</span> Ordering Rules</h2> <ol type="1"> <li>higher <code>riskScore</code> first</li> <li>if equal risk, larger amount first</li> </ol> <h2 data-number="7.30" id="syntax-focus-16"><span class="header-section-number">7.30</span> Syntax Focus</h2> <ul> <li>custom comparator composition</li> </ul> <hr /> </details> <details> <summary> Exercise 18 - Stream Median Transaction Amount </summary> <h2 data-number="7.31" id="problem-description-17"><span class="header-section-number">7.31</span> Problem Description</h2> <p>Risk metrics service needs rolling median amount from incoming stream.</p> <h2 data-number="7.32" id="input-16"><span class="header-section-number">7.32</span> Input</h2> <ul> <li>continuous amount values</li> </ul> <h2 data-number="7.33" id="output-8"><span class="header-section-number">7.33</span> Output</h2> <ul> <li><code>BigDecimal getMedian()</code></li> </ul> <h2 data-number="7.34" id="constraints-7"><span class="header-section-number">7.34</span> Constraints</h2> <ul> <li>support high throughput (100k events/sec target)</li> </ul> <h2 data-number="7.35" id="implementation-requirements-12"><span class="header-section-number">7.35</span> Implementation Requirements</h2> <ul> <li>two-heaps approach (<code>maxHeap</code>, <code>minHeap</code>)</li> </ul> <h2 data-number="7.36" id="syntax-focus-17"><span class="header-section-number">7.36</span> Syntax Focus</h2> <ul> <li>heap balancing logic, invariant maintenance</li> </ul> <hr /> </details> <h1 data-number="8" id="stage-4---concurrency-io-and-system-oriented-syntax"><span class="header-section-number">8</span> Stage 4 - Concurrency, IO, and System-Oriented Syntax</h1> <details> <summary> Exercise 19 - Concurrent Ledger </summary> <h2 data-number="8.1" id="problem-description-18"><span class="header-section-number">8.1</span> Problem Description</h2> <p>Make account updates safe under multi-threaded load.</p> <h2 data-number="8.2" id="scenario"><span class="header-section-number">8.2</span> Scenario</h2> <ul> <li>100 threads doing deposits/withdrawals on same account set</li> </ul> <h2 data-number="8.3" id="expected-behaviour-11"><span class="header-section-number">8.3</span> Expected Behaviour</h2> <ul> <li>no lost updates</li> <li>no negative-balance race corruption</li> </ul> <h2 data-number="8.4" id="implementation-requirements-13"><span class="header-section-number">8.4</span> Implementation Requirements</h2> <ul> <li>implement one version using <code>synchronized</code></li> <li>implement one version using <code>ReentrantLock</code></li> </ul> <h2 data-number="8.5" id="syntax-focus-18"><span class="header-section-number">8.5</span> Syntax Focus</h2> <ul> <li>thread safety primitives, critical sections</li> </ul> <hr /> </details> <details> <summary> Exercise 20 - Transaction Worker Pool </summary> <h2 data-number="8.6" id="problem-description-19"><span class="header-section-number">8.6</span> Problem Description</h2> <p>Process queued transactions asynchronously.</p> <h2 data-number="8.7" id="architecture"><span class="header-section-number">8.7</span> Architecture</h2> <ul> <li><code>BlockingQueue&lt;Transaction&gt;</code></li> <li>N worker threads</li> </ul> <h2 data-number="8.8" id="behaviour-1"><span class="header-section-number">8.8</span> Behaviour</h2> <ul> <li>workers <code>take()</code> then <code>process()</code></li> <li>graceful shutdown mechanism</li> </ul> <h2 data-number="8.9" id="metrics"><span class="header-section-number">8.9</span> Metrics</h2> <ul> <li>total processed count</li> <li>average latency</li> </ul> <h2 data-number="8.10" id="syntax-focus-19"><span class="header-section-number">8.10</span> Syntax Focus</h2> <ul> <li>executors, blocking queues, atomic counters</li> </ul> <hr /> </details> <details> <summary> Exercise 21 - Velocity Fraud Detector </summary> <h2 data-number="8.11" id="problem-description-20"><span class="header-section-number">8.11</span> Problem Description</h2> <p>Flag accounts that execute too many transactions too quickly.</p> <h2 data-number="8.12" id="rule"><span class="header-section-number">8.12</span> Rule</h2> <ul> <li>alert when account has <code>&gt; 10</code> transactions within 30 seconds</li> </ul> <h2 data-number="8.13" id="input-17"><span class="header-section-number">8.13</span> Input</h2> <ul> <li>transaction stream</li> </ul> <h2 data-number="8.14" id="output-9"><span class="header-section-number">8.14</span> Output</h2> <ul> <li><code>FraudAlert</code> with accountId, timestamp, count</li> </ul> <h2 data-number="8.15" id="syntax-focus-20"><span class="header-section-number">8.15</span> Syntax Focus</h2> <ul> <li>map of account → deque timestamps, sliding window per key</li> </ul> <hr /> </details> <details> <summary> Exercise 22 - Large File Payment Parser </summary> <h2 data-number="8.16" id="problem-description-21"><span class="header-section-number">8.16</span> Problem Description</h2> <p>Ingest massive CSV payment files without memory blowups.</p> <h2 data-number="8.17" id="file-format"><span class="header-section-number">8.17</span> File Format</h2> <ul> <li><code>txnId,accountId,amount,currency,timestamp</code></li> </ul> <h2 data-number="8.18" id="file-size"><span class="header-section-number">8.18</span> File Size</h2> <ul> <li>up to 10GB</li> </ul> <h2 data-number="8.19" id="expected-behaviour-12"><span class="header-section-number">8.19</span> Expected Behaviour</h2> <ul> <li>stream line-by-line</li> <li>parse to domain objects</li> <li>collect malformed rows in error report</li> </ul> <h2 data-number="8.20" id="constraints-8"><span class="header-section-number">8.20</span> Constraints</h2> <ul> <li>do not load file fully into memory</li> </ul> <h2 data-number="8.21" id="syntax-focus-21"><span class="header-section-number">8.21</span> Syntax Focus</h2> <ul> <li><code>BufferedReader</code>, try-with-resources, parsing, error handling</li> </ul> <hr /> </details> <details> <summary> Exercise 23 - Sharded Ledger Routing </summary> <h2 data-number="8.22" id="problem-description-22"><span class="header-section-number">8.22</span> Problem Description</h2> <p>Route transactions to deterministic shard by account.</p> <h2 data-number="8.23" id="partition-rule"><span class="header-section-number">8.23</span> Partition Rule</h2> <ul> <li><code>hash(accountId) % shardCount</code></li> </ul> <h2 data-number="8.24" id="input-18"><span class="header-section-number">8.24</span> Input</h2> <ul> <li>account id + configured shard count</li> </ul> <h2 data-number="8.25" id="output-10"><span class="header-section-number">8.25</span> Output</h2> <ul> <li>shard id</li> </ul> <h2 data-number="8.26" id="implementation-requirements-14"><span class="header-section-number">8.26</span> Implementation Requirements</h2> <ul> <li>method <code>int getAccountShard(String accountId, int shardCount)</code></li> <li>method <code>Shard routeTransaction(Transaction tx)</code></li> </ul> <h2 data-number="8.27" id="syntax-focus-22"><span class="header-section-number">8.27</span> Syntax Focus</h2> <ul> <li>hashing, modulo, input validation</li> </ul> <hr /> </details> <details> <summary> Exercise 24 - Idempotent Processor </summary> <h2 data-number="8.28" id="problem-description-23"><span class="header-section-number">8.28</span> Problem Description</h2> <p>Payment retries must not post duplicate ledger effects.</p> <h2 data-number="8.29" id="input-19"><span class="header-section-number">8.29</span> Input</h2> <ul> <li><code>Transaction tx</code></li> </ul> <h2 data-number="8.30" id="expected-behaviour-13"><span class="header-section-number">8.30</span> Expected Behaviour</h2> <ul> <li>first processing applies side effects</li> <li>repeated same transaction ID returns previous result without reapplying</li> </ul> <h2 data-number="8.31" id="implementation-requirements-15"><span class="header-section-number">8.31</span> Implementation Requirements</h2> <ul> <li>in-memory dedupe store (<code>ConcurrentHashMap</code>)</li> </ul> <h2 data-number="8.32" id="syntax-focus-23"><span class="header-section-number">8.32</span> Syntax Focus</h2> <ul> <li><code>computeIfAbsent</code>, idempotency patterns</li> </ul> <hr /> </details> <h1 data-number="9" id="stage-5---trading-syntax-track-optional-but-recommended"><span class="header-section-number">9</span> Stage 5 - Trading Syntax Track (Optional but Recommended)</h1> <details> <summary> Exercise 25 - Basic Order Book </summary> <h2 data-number="9.1" id="problem-description-24"><span class="header-section-number">9.1</span> Problem Description</h2> <p>Maintain buy/sell orders and expose best market prices.</p> <h2 data-number="9.2" id="order-fields"><span class="header-section-number">9.2</span> Order Fields</h2> <ul> <li><code>id</code>, <code>side</code>, <code>price</code>, <code>quantity</code></li> </ul> <h2 data-number="9.3" id="storage"><span class="header-section-number">9.3</span> Storage</h2> <ul> <li><code>TreeMap&lt;BigDecimal, List&lt;Order&gt;&gt;</code></li> </ul> <h2 data-number="9.4" id="implement"><span class="header-section-number">9.4</span> Implement</h2> <ul> <li><code>addOrder(Order order)</code></li> <li><code>cancelOrder(String orderId)</code></li> <li><code>bestBid()</code></li> <li><code>bestAsk()</code></li> </ul> <h2 data-number="9.5" id="example-9"><span class="header-section-number">9.5</span> Example</h2> <ul> <li>BUY <span class="citation" data-cites="10">@10</span>, BUY <span class="citation" data-cites="11">@11</span>, SELL <span class="citation" data-cites="12">@12</span> =&gt; bestBid=11, bestAsk=12</li> </ul> <h2 data-number="9.6" id="syntax-focus-24"><span class="header-section-number">9.6</span> Syntax Focus</h2> <ul> <li>sorted maps, navigation methods, mutation safety</li> </ul> <hr /> </details> <details> <summary> Exercise 26 - Simple Matching Engine </summary> <h2 data-number="9.7" id="problem-description-25"><span class="header-section-number">9.7</span> Problem Description</h2> <p>Match orders when spread crosses.</p> <h2 data-number="9.8" id="rule-1"><span class="header-section-number">9.8</span> Rule</h2> <ul> <li>trade occurs when <code>bestBid &gt;= bestAsk</code></li> </ul> <h2 data-number="9.9" id="output-11"><span class="header-section-number">9.9</span> Output</h2> <ul> <li><code>Trade { price, quantity, buyOrderId, sellOrderId }</code></li> </ul> <h2 data-number="9.10" id="syntax-focus-25"><span class="header-section-number">9.10</span> Syntax Focus</h2> <ul> <li>iterative matching loops, object updates, partial fills</li> </ul> <hr /> </details> <h1 data-number="10" id="final-capstone---mini-fintech-payment-system"><span class="header-section-number">10</span> Final Capstone - Mini Fintech Payment System</h1> <p>Build an end-to-end payment workflow using prior modules.</p> <h2 data-number="10.1" id="required-modules"><span class="header-section-number">10.1</span> Required Modules</h2> <ul> <li>Transaction API layer (in-memory simulation is fine)</li> <li>Validator</li> <li>Fraud engine</li> <li>Ledger posting</li> <li>Settlement queue</li> <li>Reporting</li> </ul> <h2 data-number="10.2" id="transaction-flow"><span class="header-section-number">10.2</span> Transaction Flow</h2> <pre class="text"><code>submitTransaction() -&gt; validation -&gt; fraud check -&gt; ledger update -&gt; settlement queue -&gt; reporting</code></pre> <h2 data-number="10.3" id="minimum-functional-requirements"><span class="header-section-number">10.3</span> Minimum Functional Requirements</h2> <ol type="1"> <li>Accept new transaction request</li> <li>Validate and reject invalid payloads with structured errors</li> <li>Detect duplicates (idempotency)</li> <li>Post valid transaction to ledger</li> <li>Enqueue for settlement</li> <li>Update reporting counters: <ul> <li>accepted</li> <li>rejected</li> <li>fraud-flagged</li> <li>total volume by currency</li> </ul></li> </ol> <h2 data-number="10.4" id="non-functional-requirements"><span class="header-section-number">10.4</span> Non-Functional Requirements</h2> <ul> <li>Clear package boundaries</li> <li>Unit tests for each module</li> <li>Integration test for full flow</li> <li>Thread-safe processing where concurrent components exist</li> </ul> <h2 data-number="10.5" id="suggested-package-layout"><span class="header-section-number">10.5</span> Suggested Package Layout</h2> <pre class="text"><code>src/main/java/workbook/ domain/ Money.java Transaction.java Account.java validation/ TransactionValidator.java fraud/ VelocityFraudDetector.java ledger/ LedgerService.java PostingService.java settlement/ SettlementQueue.java reporting/ ReportingService.java api/ TransactionController.java</code></pre> <hr /> <h1 data-number="11" id="final-checklist"><span class="header-section-number">11</span> Final Checklist</h1> <p>Before moving on from any exercise, confirm:</p> <ol type="1"> <li>The method signatures match the exercise specification.</li> <li>You covered happy path, edge case, and failure case.</li> <li>Money logic uses <code>BigDecimal</code> correctly (no <code>double</code>/<code>float</code>).</li> <li>Errors are explicit and intentional.</li> <li>Names are clear and code is clean.</li> </ol> <hr /> <h1 data-number="12" id="conclusion"><span class="header-section-number">12</span> Conclusion</h1> <p>This workbook gives you a concrete training path: 5 stages, 26 exercises, and 1 capstone focused on fintech-style Java implementation work.</p> <p>Real target outcomes:</p> <ul> <li>You can implement each exercise from specification to working code.</li> <li>You can write and pass tests for happy path, edge case, and failure case.</li> <li>You can validate your final implementation against expected behavior before moving on.</li> </ul> <p>If you want the code-style companion version (full implementations + test suites where each exercise must pass, plus final checked solutions), email me at: <a href="mailto:owusu@bohyen.space">owusu@bohyen.space</a></p> <p>I may not always reply quickly, but I will do my best to respond.</p>
Previous Alpine Linux Instal… Next A Domain-Addressabl…

© 2026 | CC0 1.0 Universal Codebase | Powered by django