مقابلاتي التقنية كانت صندوقاً أسود: كيف أنقذني ‘التفكير بصوت عالٍ’ من رفض الشركات رغم صحة الكود؟

يا جماعة الخير، السلام عليكم ورحمة الله وبركاته، معكم أخوكم أبو عمر.

بتذكر قبل سنوات، في بداية طريقي المهني، كنت مقدم على وظيفة في شركة كبيرة كنت أحلم فيها. دخلت المقابلة التقنية وكلي ثقة. أعطاني المحاور سؤال برمجي، مش سهل ومش مستحيل. مسكت الكيبورد، وعشت حالة من التركيز العميق… صمت مطبق في الغرفة إلا من صوت طقطقة أصابعي على الأزرار. خلال 20 دقيقة، سلمته الحل: كود نظيف، فعال، وبيشتغل زي الليرة الذهب. ابتسم المحاور ابتسامة غامضة وقلي “تمام، يعطيك العافية بنتواصل معك”.

طلعت من المقابلة وأنا حاسس إني “كسّرت الدنيا”. الكود صح، الوقت قياسي، شو بدهم أحسن من هيك؟ مرت أيام، وأسابيع… وما حدا تواصل. بعد فترة، إجاني إيميل الرفض المعتاد. بصراحة، انصدمت! يا زلمة شو القصة؟ تكرر هالموقف مرة ومرتين وثلاث. كود صحيح، أداء ممتاز، ونتيجة المقابلة دايماً رفض. حسيت إنه مقابلاتي عبارة عن صندوق أسود، بدخل عليه وبطلع منه بدون ما أفهم شو اللي بصير جوة عقل المحاور.

الفرج إجا لما قابلتني مهندسة لطيفة في إحدى الشركات، وبعد ما رفضوني، تجرأت وبعتلها إيميل أشكرها فيه وسألتها عن أي نصيحة ممكن تفيدني للمستقبل. كان ردها هو نقطة التحول في مسيرتي كلها. قالتلي: “يا عمر، الكود تبعك كان ممتاز، بس إنت كنت صامت تماماً. ما عرفنا كيف فكرت، ما عرفنا شو الحلول الثانية اللي استبعدتها، ولا كيف وصلت لهاي النتيجة. كنا بندور على زميل يحل المشاكل معنا، مش مجرد آلة بتكتب كود”.

هون فهمت… المشكلة ما كانت في الكود، المشكلة كانت في الصمت. ومن يومها، تعلمت فن “التفكير بصوت عالٍ”، اللي حابب أحكيلكم عنه اليوم.

الصندوق الأسود: ليش الكود الصح مش كفاية؟

كثير من المبرمجين المبتدئين (وأحياناً حتى المحترفين) بيقعوا في نفس الفخ اللي وقعت فيه. بنفكر إنه المقابلة التقنية هي مجرد امتحان، والمحاور هو مُصحح آلي (Compiler) مهمته يتأكد إذا الكود بيشتغل أو لأ. هذا أكبر غلط.

المحاور مش بس بده يشوف النتيجة النهائية، هو بده يفهم “الرحلة” اللي وصلتك لهاي النتيجة. هو بيقيّم مجموعة أشياء أهم من الكود نفسه:

  • مهارات حل المشكلات (Problem-Solving Skills): كيف بتحلل المشكلة؟ كيف بتقسمها لأجزاء أصغر؟
  • مهارات التواصل (Communication Skills): هل بتقدر تشرح فكرة معقدة بوضوح؟ هل بتطرح أسئلة ذكية؟
  • التعاون (Collaboration): هل بتتعامل مع المحاور كشريك في حل المشكلة، ولا كخصم في امتحان؟
  • المعرفة بالأساسيات: هل فاهم المقايضات (Trade-offs) بين الحلول المختلفة؟ (مثلاً، السرعة مقابل استهلاك الذاكرة).

لما تكون صامت، إنت بتحرم المحاور من رؤية كل هاي المهارات. عقلك بصير بالنسبة إله “صندوق أسود”: هو شايف المدخلات (المشكلة) والمخرجات (الكود)، بس العملية اللي بالنص، واللي هي أهم إشي، مختفية تماماً.

“التفكير بصوت عالٍ”: مفتاح فك شيفرة المقابلة

التفكير بصوت عالٍ هو ببساطة إنك “تروي” قصة حلك للمشكلة للمحاور خطوة بخطوة. هو مش مجرد حكي عشوائي، هو عملية منظمة بتحول المقابلة من استجواب إلى جلسة عمل ثنائية. خلينا نقسمها لمراحل.

المرحلة الأولى: قبل ما تكتب أول سطر كود

هاي المرحلة أهم من كتابة الكود نفسه. هون بتبني الأساس الصح وبتوري المحاور إنك شخص منظم ومنهجي.

  1. أعد صياغة المشكلة وتأكد من فهمك: أول خطوة، كرر المشكلة بكلماتك الخاصة. قول: “تمام، إذاً فهمي للسؤال هو إنه مطلوب مني أعمل دالة تستقبل مصفوفة أرقام ورقم مستهدف، والمفروض أرجع فهرس أول رقمين مجموعهم بيساوي الهدف. هل فهمي صحيح؟” هاي الحركة بتورجيهم إنك حريص على الفهم وبتفتح مجال للمحاور يصححلك لو كنت فاهم غلط.
  2. ناقش المدخلات والحالات الخاصة (Edge Cases): لا تفترض أي إشي! اسأل أسئلة ذكية:
    • “هل ممكن المصفوفة تكون فارغة؟”
    • “هل الأرقام كلها موجبة، ولا ممكن يكون في سالب أو صفر؟”
    • “هل ممكن يكون في حلول متعددة، وإذا آه، أي واحد أرجع؟”
    • “شو حجم المدخلات المتوقع؟ هذا بيساعدني أحدد إذا الحل البطيء مقبول أو لأ.”
  3. ابدأ بالحل الساذج (Brute-Force): لا تقفز مباشرة للحل الأمثل. ابدأ بالحل الأوضح والأبسط حتى لو كان بطيئاً. قول: “كفكرة أولية، ممكن أعمل حلقتين متداخلتين (nested loops). آخذ كل عنصر وأقارنه مع كل العناصر اللي بعده. هذا الحل تعقيده الزمني راح يكون O(n^2). هو مش أفضل حل، بس كنقطة بداية جيدة عشان نتأكد من فهمنا للمنطق. شو رأيك أبدأ فيه أو نفكر بتحسينه مباشرةً؟”

بهذه الطريقة، أنت أثبت للمحاور إنك بتفكر بشكل منظم، بتفهم في تعقيد الخوارزميات (Big O)، وبتعرف تتعاون معه.

المرحلة الثانية: أثناء كتابة الكود

الآن، وأنت بتكتب الكود، استمر في الحوار. أنت مش مبرمج صامت، أنت مرشد سياحي في رحلة داخل عقلك.

  • علّق على قراراتك: “الآن راح أستخدم `HashMap` (أو `dictionary` في بايثون) عشان أخزن الأرقام اللي مريت عليها والفهرس تبعها. اخترت الـ `HashMap` تحديداً لأن عملية البحث فيه سريعة جداً، متوسطها O(1)، وهذا راح يساعدنا نحسن الأداء بشكل كبير.”
  • اذكر المقايضات (Trade-offs): “طبعاً، استخدام الـ `HashMap` بيعني إني راح أستهلك ذاكرة إضافية حجمها ممكن يوصل لـ O(n). بس أعتقد إنها مقايضة مقبولة مقابل تحسين سرعة الخوارزمية من O(n^2) إلى O(n).”
  • صحح نفسك بصوت عالٍ: إذا عملت غلطة بسيطة، عادي جداً! الأفضل إنك تكتشفها وتصلحها بنفسك. “اه لحظة… هون كنت راح أضيف الرقم للـ `map` قبل ما أبحث. الأصح إني أبحث عن الرقم المكمّل أول، وبعدين أضيف الرقم الحالي، عشان أتجنب استخدام نفس العنصر مرتين في حالة مثل [3, 2, 4] والهدف 6. ممتاز، منيح انتبهت لهاي النقطة.”

مثال عملي: مشكلة “Two Sum” الشهيرة

خلينا نطبق الحكي هذا على أشهر سؤال في المقابلات: “Two Sum”.

المشكلة: بالنظر إلى مصفوفة من الأعداد الصحيحة `nums` وعدد صحيح `target`، أرجع فهرس الرقمين الذين مجموعهما يساوي `target`.

السيناريو الأول: المقابلة الصامتة (الخطأ الذي كنت أقع فيه)

المبرمج الصامت راح يسمع السؤال، يصمت لمدة 5 دقائق، ثم يكتب الكود التالي مباشرة:


function twoSum(nums, target) {
    const map = new Map();
    for (let i = 0; i < nums.length; i++) {
        const complement = target - nums[i];
        if (map.has(complement)) {
            return [map.get(complement), i];
        }
        map.set(nums[i], i);
    }
}

الكود صحيح 100% وممتاز. لكن المحاور ما عنده أي فكرة كيف وصلت له. هل أنت حافظ الحل؟ هل تعرف ليش هذا الحل أفضل من غيره؟ هل فكرت في أي حلول أخرى؟ كل هذا يبقى في الصندوق الأسود.

السيناريو الثاني: المقابلة الحوارية (طريقة أبو عمر)

هنا يبدأ السحر. هكذا سأدير الحوار:

أبو عمر: “تمام، مشكور على السؤال. فهمي هو إني محتاج ألاقي فهرس رقمين في مصفوفة `nums` مجموعهم بيساوي `target`. هل ممكن أفترض إنه دايماً في حل واحد بالضبط؟ وهل ممكن أستخدم نفس العنصر مرتين؟”

المحاور: “افترض أن هناك حلاً واحداً بالضبط، ولا يمكنك استخدام نفس العنصر مرتين.”

أبو عمر: “ممتاز، شكراً للتوضيح. أول فكرة بتخطر ببالي هي الحل المباشر أو الـ Brute Force. ممكن أعمل حلقة خارجية تمسك كل رقم، وحلقة داخلية تمشي على باقي الأرقام وتجمعهم وتشوف إذا بيساووا الـ `target`. هذا الحل بسيط وواضح، بس أداءه راح يكون O(n^2) لأنه عندي حلقتين متداخلتين. هل حابب أكتب هذا الحل كبداية، أو نفكر مباشرة في حل أسرع؟”

المحاور: “لا، خلينا نفكر في حل أسرع.”

أبو عمر: “تمام. عشان نحسن الأداء من O(n^2)، لازم نتخلص من الحلقة الداخلية اللي بتعمل بحث. المشكلة الأساسية في كل لفة هي: ‘هل الرقم المكمّل موجود في باقي المصفوفة؟’. البحث في مصفوفة بطيء وبياخذ O(n). طيب، كيف ممكن أعمل عملية البحث هاي بشكل أسرع؟ أفضل طريقة للبحث السريع هي باستخدام هيكل بيانات بيعطيني بحث في زمن ثابت O(1)، مثل الـ `HashMap` أو الـ `Set`.”

أبو عمر (يكمل): “فكرتي هي كالتالي: راح أمشي على المصفوفة مرة واحدة فقط (O(n)). في كل لفة، عند الرقم `num`، راح أحسب الرقم اللي بيكمله `complement = target – num`. بعدين، راح أسأل: هل الـ `complement` هذا موجود في الـ `HashMap` تبعي؟ إذا كان موجود، معناته لقيت الحل! وبرجع الفهرس المخزن في الـ `map` مع الفهرس الحالي. إذا ما كان موجود، بضيف الرقم الحالي `num` وفهرسه `i` للـ `HashMap`، عشان الأرقام الجاية في المصفوفة تقدر تشوفه. بهذه الطريقة، كل رقم بضيفه للـ `map` عشان يخدم الأرقام اللي بتيجي بعده. هيك بضمن إني بمشي على المصفوفة مرة واحدة بس.”

(الآن فقط، يبدأ أبو عمر بكتابة الكود، وهو يشرح ما يفعله)

أبو عمر: “راح أبدأ بتعريف `map` فاضي… الآن حلقة `for` من بداية المصفوفة لنهايتها… في كل لفة، بحسب الـ `complement`… وبعمل `if` عشان أتأكد إذا الـ `map` بيحتوي عليه… إذا لأ، بضيف العنصر الحالي للـ `map`…”.

شفت الفرق؟ الكود النهائي هو نفسه، لكن في السيناريو الثاني، المحاور شاف كل عملية التفكير، التحليل، المقارنة، والتخطيط. هو الآن واثق 100% إنك مش بس بتعرف تكتب كود، بل بتعرف تحل مشاكل.

نصائح أبو عمر الذهبية 💡

  • تدرب على الحكي: الموضوع مهارة، والمهارة بدها تدريب. المرة الجاي لما تحل سؤال على LeetCode أو أي منصة ثانية، لا تحله بصمت. افتح محرر نصوص واكتب أفكارك، أو الأفضل، اشرح الحل بصوت عالٍ وكأنك في مقابلة حقيقية. في تكنيك مشهور اسمه “Rubber Duck Debugging” (تصحيح أخطاء البطة المطاطية)، وهو إنك تشرح الكود لبطة مطاطية (أو أي جماد) على مكتبك. صدقني، مجرد شرح الفكرة بصوت عالٍ بيكشفلك الثغرات في منطقك.
  • لا تخاف من الصمت القصير: التفكير بصوت عالٍ لا يعني إنك لازم تحكي بدون توقف. عادي جداً تقول: “ممم، هاي نقطة مثيرة للاهتمام. أعطيني لحظة أفكر فيها.” أخذ 15-20 ثانية لترتيب أفكارك أفضل من إنك تتسرع وتحكي شي مش مدروس.
  • حوّل المقابلة لـ “Pair Programming”: تعامل مع المحاور كأنه زميلك في الفريق. اسأله عن رأيه: “أنا بفكر بين حلين، واحد أسرع والثاني بيستهلك ذاكرة أقل. هل في أفضلية لوحدة منهم في سياق النظام اللي بتشتغلوا عليه؟” هذا يظهر أنك شخص تعاوني ويفكر في الصورة الكبيرة.
  • استخدم السبورة (الافتراضية أو الحقيقية): ارسم مربعات، أسهم، اكتب ملاحظات. الشرح المرئي بيساعدك ترتب أفكارك وبيساعد المحاور يتابع معك بسهولة أكبر.

الخلاصة: المقابلة حوار مش امتحان 🤝

يا صديقي المبرمج، ويا صديقتي المبرمجة، تذكروا دايماً: الشركة ما بتوظف “كود”، الشركة بتوظف “عقل” قادر على حل المشاكل والتواصل بفعالية. الكود الصحيح هو مجرد نتيجة طبيعية لعملية تفكير سليمة.

تحرر من عقلية الامتحان، وتبنى عقلية الحوار وحل المشاكل التعاوني. “التفكير بصوت عالٍ” هو الجسر اللي بتبنيه بين عقلك اللامع وبين فهم المحاور لهذا اللمعان. لا تتركهم يخمنون، بل خذهم معك في رحلة ممتعة داخل طريقة تفكيرك.

الكود الصح هو النتيجة، بس طريقة تفكيرك هي القصة كلها. احكي قصتك! بالتوفيق يا وحوش. 💪

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

التوسع والأداء العالي والأحمال

طلباتي كانت تتراكم كطابور لا ينتهي: كيف أنقذني ‘طابور الرسائل’ (Message Queue) من جحيم الاختناقات المفاجئة؟

أشارككم قصة حقيقية من تجربتي كادت أن تدمر إطلاق أحد أهم مشاريعي، وكيف كانت بنية "طوابير الرسائل" (Message Queues) البسيطة هي طوق النجاة الذي حوّل...

29 مارس، 2026 قراءة المزيد
التكنلوجيا المالية Fintech

حساباتي البنكية كانت جزرًا معزولة: كيف أنقذتني واجهات ‘الخدمات المصرفية المفتوحة’ من جحيم البيانات المبعثرة؟

أنا أبو عمر، مطور برمجيات فلسطيني، وأروي لكم كيف حوّلت الخدمات المصرفية المفتوحة (Open Banking) فوضى حساباتي المالية إلى نظام متكامل. في هذه المقالة، أغوص...

29 مارس، 2026 قراءة المزيد
اختبارات الاداء والجودة

اختباراتي كانت واثقة من نفسها أكثر من اللازم: كيف كشف لي ‘الاختبار الطفري’ (Mutation Testing) الثقوب الخفية في جودة الكود؟

كنت أظن أن تغطية الاختبارات بنسبة 100% تعني كودًا مثاليًا، حتى كشف لي الاختبار الطفري أن اختباراتي كانت سطحية وهشة. في هذه المقالة، أشارككم رحلتي...

29 مارس، 2026 قراءة المزيد
​معمارية البرمجيات

تطبيقي كان كتلة واحدة متجمدة: كيف أنقذتني ‘معمارية الخدمات المصغرة’ (Microservices) من جحيم الصيانة المستحيلة؟

هل تعاني من تطبيق ضخم وبطيء أصبح كابوسًا في الصيانة والتطوير؟ في هذه المقالة، أشارككم تجربتي الشخصية في الانتقال من المعمارية المتجمدة (Monolith) إلى مرونة...

29 مارس، 2026 قراءة المزيد
البودكاست