بازگشت/ریکرژن (Java Recursion)
بازگشت/ریکرژن (Recursion): متدی که خودش را صدا میزند! 🌀🪆
ریکرژن تکنیکی است که در آن یک متد برای حل یک مسئله بزرگ، خودش را با نسخههای کوچکتری از همان مسئله فراخوانی میکند. این مفهوم شبیه به عروسکهای روسی (ماتروشکا) است!
۱. ساختار یک متد بازگشتی
هر متد بازگشتی باید دو بخش اصلی داشته باشد:
- شرط پایه (Base Case): شرطی که باعث توقف بازگشت میشود (بسیار حیاتی!).
- گام بازگشتی (Recursive Step): جایی که متد خودش را دوباره صدا میزند.
مثال: محاسبه مجموع اعداد ۱ تا ۱۰
{code_block('static int sum(int k) {\n if (k > 0) {\n return k + sum(k - 1);\n } else {\n return 0; // شرط پایه\n }\n}')}۲. چرا از ریکرژن استفاده کنیم؟
ریکرژن برای مسائلی که ساختار تکراری پیچیده دارند (مثل پیمایش درختها یا حل پازلهای ریاضی مثل هانوی) کد را بسیار کوتاهتر و زیباتر میکند.
StackOverflowError کرش کند.
while یا for هم حل کرد. ریکرژن معمولاً تمیزتر است اما حافظه بیشتری مصرف میکند.
بخش تخصصی: مهندسی متدها و مدیریت حافظه 🛠️💎
در این بخش، به مفاهیمی میپردازیم که برای درک عمیق مدیریت حافظه و کارایی در جاوا حیاتی هستند.
۱. پشته متد (Method Stack) و فریمها
هر بار که متدی فراخوانی میشود، جاوا یک Stack Frame جدید در حافظه Stack ایجاد میکند. این فریم شامل متغیرهای محلی و پارامترهای متد است. وقتی متد تمام میشود، فریم آن از پشته حذف (Pop) میشود. درک این فرآیند برای دیباگ کردن خطاهایی مثل StackOverflowError بسیار مهم است.
۲. انتقال پارامتر: Pass-by-Value
یک نکته بسیار مهم در جاوا این است که جاوا همیشه مقادیر را به صورت Pass-by-Value منتقل میکند. برای انواع اولیه، خودِ مقدار کپی میشود. برای اشیاء (Objects)، "کپیِ ریفرنس" به متد فرستاده میشود. این یعنی شما میتوانید ویژگیهای یک شیء را داخل متد تغییر دهید، اما نمیتوانید خودِ ریفرنس اصلی را به شیء دیگری متصل کنید.
۳. کدهای ماژولار و اصل Single Responsibility
در مهندسی نرمافزار حرفهای، هر متد باید فقط و فقط "یک کار" انجام دهد. اگر متد شما بیش از ۲۰ خط شده یا نام آن شامل کلمه "And" است، احتمالاً باید آن را به متدهای کوچکتر تقسیم کنید. این کار باعث میشود کد شما قابل تست (Testable) و قابل نگهداری باشد.
تمرینهای عملی
برای تثبیت یادگیری این درس تمرینهای زیر را حل کنید
متد factorial را طوری کامل کنید که فاکتوریل عدد n را به صورت بازگشتی حساب کند. (فرمول: n * factorial(n-1)). شرط پایه (n == 1) از قبل نوشته شده است.
public class Main {
static int factorial(int n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
public static void main(String[] args) {
System.out.println(factorial(5));
}
}
آماده رفتن به درس بعدی هستید؟
این درس را به پایان رساندید و میتوانید به درس بعدی بروید.