یادگیری یک مفهوم با توانایی بهیادآوردن و استفاده از آن در زمان مناسب فرق دارد. در این مقاله بررسی میکنیم چرا حتی برنامهنویسان باتجربه بسیاری از چیزهایی را که خوانده یا یاد گرفتهاند فراموش میکنند و چگونه میتوان این فرایند را بهتر کرد.
احتمالاً برای شما هم پیش آمده است.
چند ماه قبل دربارهی یک موضوع مهم مطالعه کردهاید. شاید یک فصل از کتابی دربارهی معماری نرمافزار بوده، شاید یک Design Pattern، یک مفهوم در سیستمهای توزیعشده یا حتی یک API که آن زمان کاملاً برایتان واضح بوده است.
آن موقع با خودتان فکر کردهاید:
«این را کاملاً فهمیدم.»
چند ماه بعد، در یک پروژه با همان مسئله مواجه میشوید.
اما حالا جزئیات را به خاطر نمیآورید.
اسم الگو یادتان نیست.
نمیدانید دقیقاً کجا خوانده بودید.
حتی شاید بدانید که «یک راهحل درست برای این وجود دارد»، اما نتوانید آن را از حافظه بیرون بکشید.
بعد از چند دقیقه جستوجو، ناگهان همان مطلب را پیدا میکنید و میگویید:
«آهان! این همون چیزی بود که قبلاً خونده بودم.»
این اتفاق به معنی ضعیف بودن حافظه یا کمهوش بودن شما نیست.
فراموش کردن بخش طبیعی فرایند یادگیری است.
مسئله این است که روش یادگیری ما معمولاً برای مقابله با همین فراموشی طراحی نشده است.
یکی از رایجترین اشتباهات در یادگیری برنامهنویسی این است که احساس آشنایی با یک مفهوم را با یادگیری واقعی آن اشتباه بگیریم.
وقتی یک مقاله یا فصل کتاب را میخوانیم، مطالب برایمان آشنا میشوند.
تعریف را میبینیم.
مثال را میخوانیم.
کد را بررسی میکنیم.
همهچیز منطقی به نظر میرسد.
اما چند روز بعد، اگر کتاب را ببندیم و از خودمان بپرسیم:
«حالا این مفهوم را بدون نگاه کردن توضیح بده.»
ممکن است پاسخ دادن خیلی سختتر شود.
این تفاوت مهمی است:
Recognition با Recall یکی نیست.
در حالت اول، وقتی پاسخ را میبینیم، آن را میشناسیم.
در حالت دوم، باید پاسخ را خودمان از حافظه بازیابی کنیم.
و برای یک برنامهنویس، حالت دوم اهمیت بسیار بیشتری دارد.
چون هنگام حل یک مسئله واقعی، کتاب معمولاً باز نیست که جواب را با فونت ۲۴ جلوی صورتمان نشان دهد. زندگی حرفهای متأسفانه اینقدر UI-friendly نیست.
برنامهنویسی حوزهای نیست که یک بار آن را یاد بگیریم و تمام شود.
هر روز با مفاهیم جدید مواجه میشویم:
حتی اگر روزانه فقط مقدار کمی مطالعه کنیم، در طول یک سال با حجم بسیار بزرگی از اطلاعات روبهرو خواهیم شد.
بنابراین مشکل فقط «حافظه ضعیف» نیست.
ما دائماً در حال اضافه کردن اطلاعات جدید هستیم.
در چنین شرایطی، طبیعی است که بخشی از اطلاعاتی که استفاده نمیکنیم به مرور کمدسترستر شوند.
فرض کنید امروز دربارهی Event-Driven Architecture مطالعه میکنید.
یک فصل کامل میخوانید و احساس میکنید مفهوم را فهمیدهاید.
اما اگر شش ماه هیچوقت دوباره به آن برنگردید، احتمال اینکه جزئیات آن را دقیقاً به خاطر داشته باشید کاهش پیدا میکند.
یادگیری یک رویداد نیست.
یک فرایند است.
اگر یک مفهوم برای مدت طولانی دوباره بازیابی نشود، دسترسی به آن دشوارتر میشود.
به همین دلیل مرور کردن اهمیت دارد.
اما یک مشکل دیگر هم وجود دارد:
مرور کردن همهچیز به یک اندازه منطقی نیست.
اگر هر روز تمام مطالبی را که قبلاً خواندهایم دوباره بخوانیم، خیلی زود تبدیل به انسانی میشویم که شغلش مرور کردن است و دیگر وقتی برای برنامهنویسی ندارد.
اینجاست که روشهای هوشمندتر مرور اهمیت پیدا میکنند.
فرض کنید این سؤال را ببینید:
Dependency Injection چیست؟
اگر پاسخ را زیر سؤال نوشته باشیم، احتمالاً هنگام خواندن آن احساس میکنیم که مفهوم را میدانیم.
اما اگر صفحه را ببندیم و خودمان پاسخ را بنویسیم، شرایط کاملاً متفاوت میشود.
در این حالت مغز باید اطلاعات را بازیابی کند.
این همان چیزی است که به آن Active Recall یا بازیابی فعال گفته میشود.
به جای اینکه فقط دوباره اطلاعات را ببینیم، خودمان تلاش میکنیم آن را به یاد بیاوریم.
مثلاً:
مطالعه معمولی:
Dependency Injection یعنی ...
بازیابی فعال:
بدون نگاه کردن توضیح بده Dependency Injection چیست و چه مشکلی را حل میکند.
روش دوم ذهن را مجبور میکند واقعاً به دنبال پاسخ بگردد.
یکی دیگر از دلایل فراموشی این است که گاهی یک مفهوم را میخوانیم اما هیچوقت از آن استفاده نمیکنیم.
ممکن است دربارهی:
مطالعه کنیم.
اما اگر هیچ مسئلهای نداشته باشیم که این مفاهیم را در آن به کار ببریم، دانش ما ممکن است خیلی زود کمرنگ شود.
به همین دلیل ارتباط میان مفهوم و مسئله واقعی اهمیت زیادی دارد.
وقتی یک مفهوم را در یک مسئله واقعی استفاده میکنیم، آن مفهوم دیگر فقط یک تعریف در کتاب نیست.
به بخشی از تجربه ما تبدیل میشود.
گاهی مشکل این نیست که چیزهای کمی میدانیم.
مشکل این است که چیزهای زیادی میدانیم اما ارتباط میان آنها مشخص نیست.
مثلاً ممکن است این مفاهیم را جداگانه یاد گرفته باشیم:
Caching
Load Balancing
Database Replication
Message Queue
Horizontal Scaling
اما اگر ندانیم این مفاهیم چگونه در یک سیستم بزرگ به یکدیگر مرتبط میشوند، دانش ما پراکنده باقی میماند.
یادگیری مؤثر فقط جمع کردن اطلاعات نیست.
باید بتوانیم میان اطلاعات ارتباط ایجاد کنیم.
برای یک Software Engineer، این موضوع اهمیت ویژهای دارد.
چون در سطح حرفهای، مسئله معمولاً این نیست که:
«تعریف این تکنولوژی چیست؟»
بلکه سؤال این است:
«در این شرایط، چرا باید از این راهحل استفاده کنم؟»
یک نکته مهم وجود دارد:
قرار نیست هیچچیز را فراموش کنیم.
هدف یادگیری مؤثر این نیست که همه اطلاعات را برای همیشه بدون نقص در ذهن نگه داریم.
چنین چیزی نه لازم است و نه واقعبینانه.
یک برنامهنویس حرفهای هم قرار نیست تمام APIهای تمام ابزارهایی را که در طول سالها دیده حفظ باشد.
چیزی که اهمیت دارد این است که:
این تفاوت بین دانستن همهچیز و داشتن یک سیستم یادگیری خوب است.
اگر فراموشی بخشی طبیعی از یادگیری است، باید فرایند یادگیری را طوری طراحی کنیم که با آن مقابله کند.
چهار اصل میتوانند نقش مهمی داشته باشند:
به جای دوباره خواندن، خودمان را مجبور کنیم پاسخ را از حافظه پیدا کنیم.
مثلاً به جای اینکه دوباره دربارهی SOLID بخوانیم، از خودمان بپرسیم:
اصل Dependency Inversion چیست؟
و قبل از دیدن پاسخ، تلاش کنیم آن را توضیح دهیم.
مطالب را در فواصل زمانی مختلف مرور کنیم.
نه همهچیز را هر روز.
نه همهچیز را فقط یک بار.
بلکه مفاهیم را در زمانهایی مرور کنیم که احتمال فراموش شدن آنها بیشتر شده است.
به این ترتیب مرور میتواند از یک کار خستهکننده به یک فرایند هدفمند تبدیل شود.
به جای حفظ کردن صدها قطعه اطلاعات جداگانه، سعی کنیم مفاهیم را در قالب یک ساختار به هم مرتبط کنیم.
مثلاً به جای اینکه فقط تعریف Microservices را حفظ کنیم، دربارهی این موارد فکر کنیم:
این نوع یادگیری باعث میشود دانش از مجموعهای از تعریفها به یک مدل ذهنی تبدیل شود.
در نهایت، هیچ روشی جای تجربه را نمیگیرد.
اگر چیزی را یاد گرفتیم، باید تا حد امکان آن را در پروژه، تمرین، طراحی سیستم یا حل مسئله به کار ببریم.
حتی یک پروژه کوچک میتواند به اندازه چندین ساعت مطالعه به تثبیت یک مفهوم کمک کند.
هوش مصنوعی میتواند این فرایند را سادهتر کند، اما یک تفاوت مهم وجود دارد.
AI نباید فقط پاسخ را به ما بدهد.
اگر برای هر سؤال بلافاصله پاسخ آماده دریافت کنیم، ممکن است فرایند فکر کردن و بازیابی اطلاعات را از خودمان بگیریم.
یک سیستم آموزشی بهتر میتواند از AI برای مواردی مثل:
استفاده کند.
در این حالت، AI به جای اینکه جایگزین یادگیری شود، میتواند یادگیری را شخصیتر و فعالتر کند.
ایدهی CardDev از همین مسئله شروع میشود.
برنامهنویسان و مهندسان نرمافزار منابع بسیار خوبی برای یادگیری دارند، اما خواندن یک کتاب به تنهایی تضمین نمیکند که دانش آن کتاب ماهها بعد همچنان قابل استفاده باشد.
CardDev تلاش میکند این فاصله را با ترکیب مفاهیمی مانند:
Active Recall
Spaced Repetition
یادگیری مفهومی
پیگیری پیشرفت
و کمک هوش مصنوعی
کاهش دهد.
هدف این نیست که برنامهنویس را مجبور کنیم اطلاعات بیشتری حفظ کند.
هدف این است که یادگیری به یک فرایند مداوم تبدیل شود.
چیزی که امروز میخوانید، نباید لزوماً همان امروز تمام شود.
میتواند دوباره برگردد، از شما سؤال شود، با مفاهیم دیگر ارتباط پیدا کند و در طول زمان به بخشی از دانش حرفهای شما تبدیل شود.
برنامهنویسها چیزهایی را که یاد میگیرند فراموش میکنند، چون انسان هستند.
مغز قرار نیست تمام چیزهایی را که در طول سالها خواندهایم با همان جزئیات نگه دارد.
مسئله اصلی این نیست که چرا فراموش میکنیم؟
سؤال بهتر این است:
چطور سیستم یادگیری خودمان را طوری طراحی کنیم که فراموشی، بخشی از مسیر یادگیری باشد نه پایان آن؟
با بازیابی فعال، مرور با فاصله، یادگیری مفهومی و استفاده واقعی از دانش، میتوانیم فاصله میان «خواندهام» و «بلدم» را کمتر کنیم.
چون در مهندسی نرمافزار، ارزش یک مفهوم فقط در این نیست که یک بار آن را در یک کتاب دیدهایم.
ارزش واقعی زمانی است که ماهها بعد، هنگام مواجهه با یک مسئله، بتوانیم آن مفهوم را به یاد بیاوریم و بدانیم چگونه از آن استفاده کنیم.