Skip to content

Commit 5baad59

Browse files
committed
Adding a Summary Section and fixing typo in Chapter 7
1 parent d96e143 commit 5baad59

1 file changed

Lines changed: 118 additions & 1 deletion

File tree

source/ch7_recursion.ptx

Lines changed: 118 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ public class ArrayProcessor {
289289
Neither language supports <idx> tail call optimization </idx><term>tail call optimization</term>, so the practical limits on recursion depth are a factor in both. If an algorithm requires thousands of recursive calls, an iterative (loop-based) approach is the preferred solution in both Python and Java.
290290
</p>
291291
<p>
292-
The following Python code demonstrates a situation where a function calls itself indefinitely without a base case, leading to aRecursionError.
292+
The following Python code demonstrates a situation where a function calls itself indefinitely without a base case, leading to a RecursionError.
293293
</p>
294294
<program xml:id="python-recursion-error" interactive="activecode" language="python">
295295
<code>
@@ -331,4 +331,121 @@ public class ArrayProcessor {
331331
</code>
332332
</program>
333333
</section>
334+
335+
<section xml:id="recursion_java_summary">
336+
<title>Summary &amp; Reading Questions</title>
337+
<p><ol label="1">
338+
<li>
339+
<p>Recursion solves problems by defining a <em>base case</em> and a <em>recursive step</em>; each call reduces the problem size until the base case is reached.</p>
340+
</li>
341+
<li>
342+
<p>Java methods must declare visibility, static/instance context, return type, and parameter types; e.g., <c>public static int factorial(int n)</c>.</p>
343+
</li>
344+
<li>
345+
<p>The recursive logic in Java mirrors Python conceptually, but Java uses curly braces <c>{}</c> and explicit types instead of indentation and dynamic typing.</p>
346+
</li>
347+
<li>
348+
<p>The helper-method pattern keeps public APIs clean (e.g., <c>sumArray(int[] arr)</c>) while a private helper (e.g., <c>sumHelper(int[] arr, int index)</c>) carries extra state like the current index.</p>
349+
</li>
350+
<li>
351+
<p>Closing over array bounds and indexes in the helper avoids forcing callers to provide implementation details (like a starting index).</p>
352+
</li>
353+
<li>
354+
<p>Deep or unbounded recursion can exhaust the call stack: Python raises <c>RecursionError</c>; Java throws <c>StackOverflowError</c>.</p>
355+
</li>
356+
<li>
357+
<p>Neither Java nor Python guarantees tail call optimization; prefer iterative solutions for algorithms requiring very deep recursion.</p>
358+
</li>
359+
<li>
360+
<p>Error signaling differs across languages; for example, a Java factorial that receives a negative <c>n</c> might return a sentinel value (e.g., <c>-1</c>) after printing an error message.</p>
361+
</li>
362+
</ol></p>
363+
<reading-questions xml:id="rqs-recursion-java">
364+
<exercise label="recursion-1">
365+
<statement>
366+
<p>Which method signature and behavior best match a typical Java recursive factorial implementation?</p>
367+
</statement>
368+
<choices>
369+
<choice>
370+
<statement><p><c>public void factorial(int n)</c> that prints each partial product and stops when <c>n</c> reaches zero.</p></statement>
371+
<feedback><p>No. Printing results is fine for testing, but a proper factorial method should return the computed value.</p></feedback>
372+
</choice>
373+
<choice correct="yes">
374+
<statement><p><c>public static int factorial(int n)</c> that returns <c>1</c> when <c>n &lt;= 1</c> and otherwise returns <c>n * factorial(n - 1)</c>.</p></statement>
375+
<feedback><p>Correct. This matches the standard recursive factorial definition in Java.</p></feedback>
376+
</choice>
377+
<choice>
378+
<statement><p><c>private static int factorial(double n)</c> that repeatedly multiplies <c>n</c> and decrements it until it reaches 1.</p></statement>
379+
<feedback><p>No. Factorials are for integers, and using <c>double</c> here is unnecessary and can cause rounding issues.</p></feedback>
380+
</choice>
381+
<choice>
382+
<statement><p><c>public int factorial()</c> that uses a stored class field for <c>n</c> instead of a method parameter.</p></statement>
383+
<feedback><p>No. Relying on a class field hides the input and makes recursion less flexible.</p></feedback>
384+
</choice>
385+
</choices>
386+
</exercise>
387+
<exercise label="recursion-2">
388+
<statement>
389+
<p>Why use a private helper method (e.g., <c>sumHelper(int[] arr, int index)</c>) behind a public method (e.g., <c>sumArray(int[] arr)</c>) in recursive array processing?</p>
390+
</statement>
391+
<choices>
392+
<choice>
393+
<statement><p>Because it allows Java to automatically optimize the recursion for faster execution.</p></statement>
394+
<feedback><p>No. Java does not automatically optimize recursion just because you use a helper method.</p></feedback>
395+
</choice>
396+
<choice correct="yes">
397+
<statement><p>To keep the public API simple while encapsulating extra recursion state (such as the current index) inside a private method.</p></statement>
398+
<feedback><p>Correct. This keeps the interface clean while hiding internal details from the caller.</p></feedback>
399+
</choice>
400+
<choice>
401+
<statement><p>Because public methods cannot take more than one parameter in recursive calls.</p></statement>
402+
<feedback><p>No. Public methods can take multiple parameters; this is about interface clarity, not parameter limits.</p></feedback>
403+
</choice>
404+
<choice>
405+
<statement><p>To eliminate the need for a base case by handling termination in the helper method automatically.</p></statement>
406+
<feedback><p>No. The helper method still needs an explicit base case to stop recursion.</p></feedback>
407+
</choice>
408+
</choices>
409+
</exercise>
410+
<exercise label="recursion-3">
411+
<statement>
412+
<p>Which statement about recursion limits and errors is accurate?</p>
413+
</statement>
414+
<choices>
415+
<choice>
416+
<statement>
417+
<p>Java can handle very deep or even infinite recursion if the method body is short and does not perform significant operations.</p>
418+
</statement>
419+
<feedback>
420+
<p>No. Regardless of the method’s complexity, each recursive call consumes stack space, and infinite recursion will always cause a stack overflow.</p>
421+
</feedback>
422+
</choice>
423+
<choice correct="yes">
424+
<statement>
425+
<p>When the call stack is exhausted, Python raises a <c>RecursionError</c> whereas Java throws a <c>StackOverflowError</c>, and neither language applies automatic tail call optimization.</p>
426+
</statement>
427+
<feedback>
428+
<p>Correct. This difference in exception types and the lack of built-in tail call optimization is a key distinction between the two languages.</p>
429+
</feedback>
430+
</choice>
431+
<choice>
432+
<statement>
433+
<p>Declaring a recursive method as <c>static</c> in Java reduces memory usage per call, allowing more recursive calls before a stack overflow occurs.</p>
434+
</statement>
435+
<feedback>
436+
<p>No. The <c>static</c> modifier changes method context (class vs. instance) but does not meaningfully affect per-call stack memory usage.</p>
437+
</feedback>
438+
</choice>
439+
<choice>
440+
<statement>
441+
<p>Increasing a method’s parameter type from <c>int</c> to <c>long</c> in Java can prevent stack overflows for large input values by storing bigger numbers more efficiently.</p>
442+
</statement>
443+
<feedback>
444+
<p>No. The size of the number type does not influence the maximum recursion depth; stack space usage depends on the number of active calls, not numeric range.</p>
445+
</feedback>
446+
</choice>
447+
</choices>
448+
</exercise>
449+
</reading-questions>
450+
</section>
334451
</chapter>

0 commit comments

Comments
 (0)