مضى على دخولي إلى عالم البرمجة 7 سنوات و خلال هذه المدة تعلمت عدة لغات برمجة (Programming Languages) و قمت بإعداد مراجع لتعلمها أيضاً. من بعد تعلمي لهذه اللغات تعلمت استخدام عدة أطر برمجية (Frameworks) معدة لها من أجل بناء المشاريع سواء كانت عبارة عن موقع إلكتروني, تطبيق ديسكتوب, تطبيق للهاتف أو لعبة.
خلال هذه الرحلة واجهت مئات الأخطاء البرمجية منها ما هو تافه جداً, منها ما هو متوسط و منها ما أمضيت أياماً حتى استطعت في النهاية إيجاد حلول لها. بالإضافة لذلك قمت بتجربة أشهر البرامج المخصصة لكتابة الكود سواء محررات نصية (Editors) أو بيئات عمل كاملة (IDE’s) منها ما ساعدني بشكل كبير على التعلم و العمل بسرعة و منها ما تمنيت لو أنني لم أسمع به من شدة ما أتعبني حين كنت مبتدئاً.
في هذا المقال سأعلمك كل الطرق البسيطة و المتقدمة التي يمكنك اتباعها لحل المشاكل البرمجية بالإضافة إلى كيفية البحث في جوجل عن حلول للمشاكل التي تظهر لك في الكود و التي لم تتمكن من معرفة سببها أو كيفية حلها.
أهمية مواجهة أخطاء برمجية
الإنسان غالباً ما يتعلم اتخاذ قرارات صائبة بسبب أخطائه التي ارتكبها في السابق, من هذا المنطلق نلاحظ أن الإنسان بطبعه يتعلم و يزداد وعيه من الأخطاء التي يواجهها في حياته.
ما ذكرناه قبل قليل ينطبق على البرمجة أيضاً حيث أن من يملك خبرة فيها تجده قادر على معرفة الخطأ الموجود في الكود و تصحيحه بكل سهولة في حين أنك كمبتدئ تنظر للخطأ تقول بينك و بين نفسك هذه هي النهاية سأترك البرمجة!
الشخص الذي تجده خبير في كتابة الكود و حل مشاكله ليس بالضرورة أن يكون أذكى منك كما تتصور فقد تكون هذه الأخطاء التي تجده يحلها مجرد أخطاء روتينية تافهة بالنسبة له. لا تظن أنك غبي بسبب عدم قدرتك على حل الأخطاء البرمجية كما يفعل أهل الخبرة و لا يجب أن تفكر بهذه الطريقة لأنك تظلم نفسك.
كن على يقين أن الشخص الذي يعرف كيف يحل المشاكل التي تظهر في الكود بسهولة و بسرعة هو مجرد شخص واجه نفس هذه المشاكل في السابق و أكثر من مرة مما جعله معتاداً عليها و أصبح بمجرد أن يرى رسائل الأخطاء التي تظهر في الكود تجده فهم المشكلة و أصلحها.
خلاصة, حين تواجه مشكلة في الكود إياك و أن تغضب بل إفرح لأنه بسبب هذه المشكلة فإن خبرتك ستزيد و وعيك البرمجي سيزيد.
إفهم سبب المشكلة قبل أن تبحث عن حل لها
للأسف, غالباً ما أجد المبتدئ مستعجلاً يريد الحل و لا يريد معرفة سبب المشكلة!
إذا كنت من هذا النوع و تنوي البقاء من هذا النوع فكن على يقين أنك لن تصبح مبرمجاً في حياتك.
أي برنامج تستخدمه لكتابة الكود تجده في بعض الأحيان يظهر لك خطوط رمادية أو صفراء أو حمراء تحت الكود حتى يلفت نظرك له. ليس بالضرورة أن تكون جميع هذه الخطوط تشير لوجود مشاكل في الكود بل قد تكون مجرد إقتراحات يعلمك بها لكي تحسن الكود و سأعطيك بعض الأمثلة.
الخطوط الظاهرة في الصورة التالية لا تشير لوجود خطأ في الكود بل هي مجرد نصائح يظهرها لك البرنامج لكي تكتب الكود بأفضل شكل ممكن.
الخط الأحمر العامودي هدفه جعلك لا تكتب الكود كله على سطر حتى لا تكون قراءته صعبة فمن المتعارف عليه أن لا يتم وضع أكثر من 80 حرف على كل سطر حتى يكون سهل القراءة.
الخط الرمادي الذي يظهر تحت إسم المتغير total
هدفه إعلامك أنك قمت بتعريف هذا المتغير و لكنك لم تستخدمه في الكود لذلك يفضل أن تمسحه حتى لا تحجز له مساحة في الذاكرة بدون داعي و بالتالي لتحسن أداء برنامجك.
إذا قمت بتمرير الماوس فوق إسم المتغير total
سيظهر لك رسالة Variable total is not used
كالتالي و التي تعني أن هذا المتغير لم يتم استخدامه في الكود و هذا يعني أنك تستطيع حذفه.
إذاً فهمنا الآن أنه ليس بالضرورة أن تكون كل الخطوط التي تظهر لنا في الكود تشير لوجود أخطاء و أن هذه الخطوط قد تكون مفيدة جداً لنا إذا فهمنا الغاية من ظهورها.
من فضلك, أي تحذيرات أو تنبيهات تظهر لك في الكود إقرأها لتفهم سببها كما فعلنا لأننا باعتماد هذا الأسلوب نفسه سنحل بعض المشاكل الحقيقية التي ستظهر لنا في الكود و التي يواجهها أغلب المبتدئين.
معالجة الأخطاء البرمجية التي تظهر قبل تشغيل الكود
عند كتابة الكود لا بد من أن تحترم قواعد لغة البرمجة التي تتعامل معها و إلا فإن البرنامج الذي تستخدمه لكتابة الكود سيظهر لك خطوط حمراء تحت الكود ليخبرك بوجود مشاكل يجب أن تحلها لكي يعمل الكود.
كمثال بسيط, في لغة جافا إذا حاولت تخزين عدد يحتوي على فاصلة عشرية مثل 1.5
في متغير نوعه int
فإن هذا الأمر غير مسموح لأن هذا النوع مخصص لتخزين أعداد صحيحة لا تحتوي فاصلة مثل 1
– 2
– 3
– 4
إلخ..
إذاً مخالفتك لقواعد اللغة تستدعي إظهار خط أحمر تحت الكود الذي يسبب المشكلة حتى تصلحها, و إذا مررت الماوس فوق الخط الأحمر سيظهر لك سبب المشكلة كالتالي.
إذا نقرت على زر اللمبة الذي سيظهر لك بجانب السطر الذي فيه المشكلة سيظهر لك إقتراحات لحل المشكلة.
إنتبه جيداً, الإقتراحات التي تظهر لك عند النقر على اللمبة قد تكون مناسبة للكود و تعتبر الحل الذي تحتاجه و قد تكون غير مناسبة لهذا عليك أيضاً أن تقرأ الإقتراحات و تراجع قواعد اللغة بنفسك لمعرفة ما هو الإقتراح المناسب. في حالتنا الإقتراح الأول غير مناسب لأنه يعني التخلي عن الرقم 5
الموجود بعد الفاصلة قبل تخزينه في المتغير total
بينما الإقتراح الثاني يعني تغيير نوع المتغير total
من الأساس ليكون قادراً على تخزين العدد 1.5
و بالطبع هذا الخيار يعتبر أفضل.
بمجرد النقر على الخيار الثاني ستجد أن الكود تم تحديثه بشكل تلقائي و الخطأ إختفى كالتالي.
هل الإصلاح التلقائي للكود هو دائماً الحل الأفضل؟
كلا طبعاً و إياك التفكير بأن الإقتراحات التي يظهرها لك البرنامج هي دائماً أفضل الحلول الممكنة.
لتفهم ما نقصده أكثر, في المثال السابق كان الأفضل تحويل نوع المتغير total
إلى النوع float
بدل النوع double
لأن النوع double
يحتاج مساحة أكبر في الذاكرة و هذه المساحة لم نكن بحاجتها أصلاً.
لاحظ إن إذا كتبنا float
بدل double
فإنه لن يظهر أي مشكلة في الكود و لكننا هذه المرة نعرف أننا استخدمنا نوع يلبي طلبنا و يحتاج مساحة أقل من الذاكرة.
معالجة الأخطاء البرمجية التي تظهر عند تشغيل الكود
المشاكل البرمجية التي تظهر عند التشغيل (Runtime Errors) تعتبر النوع الأصعب من الأخطاء لأن البرنامج الذي نستخدمه في كتابة الكود لا يظهر وجود أي أخطاء في الكود.
عندما تجد شخص يحلف أنه لا يوجد أي مشكلة في الكود و رغم ذلك البرنامج لا يعمل إعلم أنه يواجه مشكلة من هذا النوع.
لنرجع لموضعنا, المشاكل التي تظهر عند التشغيل يوجد ثلاث طرق لإيجاد حلول لها:
1- قراءة رسالة الخطأ الذي ظهر عند التشغيل و إن عرفت سببه تستطيع إصلاحها بنفسك بشكل سريع.
2- تشغيل الكود سطراً سطراً لمعرفة السطر الذي حدثت فيه المشكلة و هذا يسمى Debugging.
3- نسخ رسالة الخطأ و البحث عنها في جوجل و هكذا ستجد أشخاص آخرين واجهوا نفس مشكلتك من قبل و ستجد الحلول التي توصلوا لها و التي يمكنك تطبيقها بنفسك على الكود الذي تكتبه.
هناك حيل أخرى يمكنك فعلها لمعرفة ما هو الأمر الذي سبب المشكلة و لكن هذه الطرق هي الأساسية و الأسرع لفعل ذلك.
تحليل رسالة الخطأ الذي ظهر عند التشغيل
رسائل الخطأ التي تظهر لك عند التشغيل ليس الهدف منها إرعابك بل مساعدتك في اكتشاف مكان الخطأ فكلما قمت بتجميع معلومات أكبر عن الخطأ كلما كان اكتشاف سببه و تصحيحه أسهل.
كمثال بسيط, البرنامج التالي يطلب من المستخدم إدخال عدد و إذا ركزت في الكود فإنك ستلاحظ أنه لا يظهر أي مشكلة أو تنبيه فيه قبل التشغيل و لكن عند التشغيل يظهر مشكلة في حال قام المستخدم بإدخال العدد كنص بدل أن يدخله كأرقام.
الأسهم الثلاثة التي وضعناه في الصورة تشير لثلاث معلومات استطعنا تجميعها عند النظر للخطأ:
- السهم الأول يشير أن الخطأ حدث مباشرةً بعد أن قام المستخدم بإدخال كلمة
one
. - السهم الثاني يشير إلى أن الخطأ الذي حدث نوعه
InputMismatchException
. - السهم الثالث يشير إلى أن الخطأ حدث بالضبط عند محاولة تنفيذ الكود الموضوع في السطر رقم 10.
كشخص درس مبادئ لغة جافا, لقد علمت ما هو سبب المشكلة من خلال قراءة رسالة الخطأ و بالتالي أصبح بإمكاني وضع الكود بداخل try/catch
لحماية البرنامج من هذا الخطأ.
كيف أبحث عن حل للمشكلة في جوجل؟
هناك عدة طرق للبحث عن حلول للمشاكل التي تظهر في الكود و لكن بشكل عام سيكون عليك إجراء البحث باللغة الإنجليزية و ليس العربية لأن المراجع الرسمية للغات البرمجة و المواقع المخصصة لإعطاء حلول للمشاكل البرمجية مكتوبة باللغة الإنجليزية.
دائماً إبدأ المشكلة بإسم اللغة البرمجية التي تستخدمها فإذا كنت تستخدم لغة java و تريد البحث عن معنى الخطأ الذي ظهر لنا في المثال السابق فسيكون عليك البحث كالتالي:
java java.util.InputMismatchException
في هذه الحالة أي موقع تجده شرح هذا الخطأ يمكنك قراءة ما كتبه عنه و الإستفادة منه.
إذا أردت طريقة أكثر ذكاءً و سرعة في البحث عن حلول فيمكنك البحث بشكل مباشر عن طرق معالجة الخطأ الذي ظهر, ففي مثالنا السابق يمكن البحث عن حل للمشكلة التي ظهرت كالتالي:
java handle InputMismatchException
هنا ستجد جوجل يعرض لك الكثير من النتائج و أولها في العادة سيكون من موقع stackoverflow كالتالي. بشكل عام عندما يظهر لك هذا الموقع في نتائج البحث أدخل له لمشاهدة الحلول المقترحة.
في موقع stackoverflow قد تجد إجابات كثيرة مقترحة لمشكلة معروضة شبيهة بمشكلتك, لمعرفة الحل الأنسب توجه مباشرةً للحل المقترح الذي تجد بجانبه علامة صح كالتالي و هنا إذا كنت تفهم اللغة الإنجليزية فإنك ستجد أن الحل المقترح هو نفسه ما ذكرناه قبل قليل و هو أنه يجب وضع الكود بداخل try/catch
لحماية البرنامج من أي خطأ نوعه InputMismatchException
قد يحدث عندما يقوم المستخدم بإدخال بيانات.
ظهر لي خطأ واحد, قمت بإصلاحه فظهر لي خطأين 😯
أحياناً ترى البرنامج يخبرك بوجود خطأ واحد فقط في الكود فتظن أنك بمجرد إصلاحه فإن البرنامج سيعمل و لكنك تتفاجئ في ظهور أخطاء أخرى بسبب التغيير الذي أجريته على الكود بدل أن يعمل البرنامج.
سبب حدوث هذه المشكلة هو قيامك بكتابة الكثير من الأكواد من دون تجربتها و التأكد ما إن كان يعمل كما يجب أم لا. فما يحدث هنا عادةً أنك أثناء كتابة الكود تكون ارتكبت خطأ منطقي في مكان معين و بالطبع لم تلاحظ أي مشكلة لأنك لم تجربه. عندها حين تقوم بتجربة تشغيل الكود كله دفعة واحدة تلاحظ أن الجزئية الأساسية التي تحتوي على المشكلة ظهرت لك و لكنك بمجرد إصلاحها فإنك ستضطر لإصلاح كل الكود الآخر المبني عليها أو الذي كتبته من بعدها.
لتجنب الوقوع في هكذا مشكلة, لا تقم بكتابة الكثير من الكود بدون تجربة ما إن كانت نتائجه صحيحة لأنك على سبيل المثال إذا كتبت كود يتألف من 1000 سطر بدون إجراء أي تجربة عليه, و في النهاية حين قمت بتجربة البرنامج اكتشفت أنه من البدابة كان هناك مشكلة منطقية في الكود و أنك كنت تفكر بطريقة غير صحيحة فعندها ستضطر لإعادة كتابة الكود كله من جديد.
خلاصة, قم دائماً بتقسيم برنامجك لخطوات و كل خطوة تقوم بأدائها قم باختبار نتائجها.
أخطاء غير معروفة سببها أوامر سابقة
هذه المشكلة يومياً أرى المبتدئين في تعلم البرمجة يقعوا بها لهذا هي أول مشكلة أفكر باحتمالية وجودها عندما يخبرني أحد طلابي بوجود مشكلة في الكود.
الجميع يقع في هذه المشكلة و لكن على حسب لغة البرمجة التي تستخدمها فإنك تقع بها بطريقة مختلفة, فعلى سبيل المثال من يدرس لغة جافا أو لغة ++C يواجه مشاكل مع الفاصلة المنقوطة (Semicolon) و من يدرس لغة بايثون يواجه مشاكل مع المسافات الفارغة (Indentations) التي يفترض أن يضيفها قبل الأوامر.
المبتدئ الذي يستخدم لغة تتطلب إضافة فاصلة منقوطة في نهاية كل أمر أنه أحياناً ينسى وضعها و أحياناً يقوم بإضافتها في مكان لا يفترض به إضافتها فيه و في الحالتين الكود سيحدث فيه مشكلة إما قبل التشغيل و إما مشكلة منطقية تظهر عند التشغيل على حسب نوع الخطأ و سأعطيك مثال على ذلك.
الكود التالي مكتوب بلغة جافا و المشكلة الموجودة فيه هي وجود فاصلة منقوطة في نهاية السطر رقم 5 الذي تم فيه تعريف الحلقة لهذا تم اعتبار الحلقة غير موجودة من الأساس لهذا لم يتم طباعة الجملة Hello World
عشر مرات.
المبتدئ الذي يستخدم لغة تتطلب إضافة مسافات فارغة في بداية الأسطر أو بين الأسطر و بشكل دقيق جداً حتى يعمل الكود كما يفترض أحياناً لا يضع هذه المسافات بشكل صحيح فيؤدي ذلك إما لظهور أخطاء قبل التشغيل أو لمشاكل منطقية أثناء التشغيل و سأعطيك مثال على ذلك.
الكود التالي مكتوب بلغة بايثون و المشكلة الموجودة فيه غالباً ما يكون معرفة سببها الحقيقي صعب جداً بالنسبة للمبتدئ لأن مكان الخطأ الذي يظهر له فعلياً غير صحيح!
إذا ركزت جيداً في الصورة, فإنك ستلاحظ وجود خط أحمر صغير في نهاية السطر رقم 4 في حين أن السطر رقم 5 لا يظهر فيه أي مشكلة. فعلياً المشكلة الحقيقة سببها السطر رقم 5 و ليس في السطر رقم 4. البرنامج يحاول إخبارك أنه من بعد السطر رقم 4 يوجد مشكلة في عدد المسافات الفارغة الموضوعة في السطر التالي و لكنه لا يخبرك ذلك بشكل واضح.
ختام
من فضلك لا تغضب بسبب الأخطاء البرمجية التي تواجهك أثناء كتابة الكود و تذكر أن إيجاد حلول لها يساعدك كثيراً على اكتساب خبرة في التعامل معها. لا تكره البرمجة من أساسها إن واجهتك بعض المشاكل أثناء التعلم و بالتوفيق للجميع.