Quick summary
Tail recursion is when a function’s recursive call is the last operation before returning, enabling tail-call elimination in languages/runtimes that support it; non-tail recursion performs additional work after the recursive call returns. In Java, tail-call optimization is not guaranteed by the JVM, so tail recursion does not reduce stack usage unless transformed to iterative code; still, converting non-tail recursion to tail style can make iterative conversion straightforward and avoid stack overflow in production.
What is recursion?
Recursion is a divide-and-conquer technique where a function calls itself with smaller inputs until a base case is reached, with the JVM allocating a stack frame for each invocation; deep recursion risks StackOverflowError if not controlled. Each call must eventually reduce the problem and hit a base case to terminate safely and predictably.