جلستُ على جانبَي مقابلة Laravel — مرشّحاً متوتراً قبل سنوات، ومؤخراً أساعد فرقاً في توظيف مطوّري باك-إند. النمط دائماً نفسه: الأسئلة التي تبدو صعبة على الورق نادراً ما تُسقط الناس. ما يُسقطهم هو العمق في الأساسيات المملّة التي ظنّوا أنهم يعرفونها.

هذه هي الأسئلة التي تهمّني فعلاً، ولماذا، وكيف أستعد لها.

"اشرح لي ما يحدث بين وصول الطلب وخروج الاستجابة"

سؤالي المفضّل للبداية لأنه بلا حيلة — يكافئ من يفهم الإطار بدل من يحفظه. الإجابة الجيدة تمرّ على نقطة الدخول، وطبقة الـHTTP kernel وسلسلة الـmiddleware، وحلّ المسار وربط النماذج، ثم الكنترولر، ثم الاستجابة في طريق العودة.

المتابعة هي الممتعة: أين تضيف فحصاً يعمل مع كل طلب؟ إن كانت الإجابة "middleware" وميّز بين العام والمرتبط بالمسار، فهذا شخص صحّح دورة حياة طلب حقيقية لا قرأ التوثيق مرة.

سؤال استعلامات N+1

الجميع يقول "Eager loading" — هذا الحدّ الأدنى لا الأقصى. ما أريد سماعه بعده هو كيف اكتشف الـN+1 أصلاً. في الإنتاج نادراً ما تراه؛ تشعر به كنقطة نهاية بطيئة.

// الرائحة: استعلام داخل حلقة
$orders = Order::all();
foreach ($orders as $order) {
    echo $order->customer->name; // استعلام لكل طلب
}

// الحلّ واضح بمجرد أن تراه
$orders = Order::with('customer')->get();

الإجابة الحقيقية هي الأدوات: Laravel Debugbar محلياً، وModel::preventLazyLoading() خارج الإنتاج ليُطلق خطأً فور حدوث تحميل كسول، وتسجيل الاستعلامات البطيئة في الإنتاج. في إحدى المنصّات خفّضت لوحة تحكم من ~40 استعلاماً إلى 4 فقط بتفعيل منع التحميل الكسول وإصلاح كل ما اشتكى منه.

"كيف تُبقي الكنترولر رفيعاً؟"

أسأل هذا لأنه يكشف كيف يبني الشخص الكود تحت الضغط لا في الدرس. قاعدتي أن دالة الكنترولر تفعل ثلاثة أشياء: تستقبل الطلب (Form Request للتحقّق)، تستدعي دالة خدمة واحدة، وتُعيد استجابة. لا استعلامات ولا قواعد عمل ولا سلالم if.

public function store(StoreOrderRequest $request, OrderService $orders)
{
    $order = $orders->place($request->validated());

    return new OrderResource($order);
}

حين يعيش كل ما يفعل شيئاً داخل خدمة، تصبح الكنترولرات فهرساً ويصبح المنطق قابلاً للاختبار دون تشغيل HTTP.

الطوابير، والسؤال وراء السؤال

"كيف ترسل بريداً دون حجب الاستجابة؟" هو في الحقيقة "هل تفهم أن بعض العمل لا ينتمي للطلب؟" ضعه في طابور. لكن ما يفوت الناس هو الفشل: ماذا يحدث حين تفشل المهمة الثالثة في دفعة؟ هل يمكن أن تعمل مرتين بأمان؟ أريد سماع كلمتَي idempotent وretry، ويفضّل قصة عن webhook أُطلق مرتين وقيد فريد أنقذهم.

أسئلة قواعد البيانات التي ليست عن حفظ صيغ SQL

لا أطلب سرد صيغ الـjoin. أسأل: لديك جدول users بعشرة ملايين صف واستعلام بطيء — ماذا تفعل؟ المسار الذي أصغي إليه: اقرأ الاستعلام الفعلي، شغّل EXPLAIN، انظر هل يُستخدم فهرس، أضف الفهرس المركّب الصحيح، ثم فكّر في التخزين المؤقت. القفز إلى Redis قبل قراءة خطة الاستعلام غريزة خاطئة وتخبرني بالكثير.

السؤال الذي يفرز المستويات فعلاً: التزامن

هذا هو. طلبان يحاولان استخدام نفس القسيمة ذات الاستخدام الواحد في نفس المللي ثانية — ماذا يحدث؟ إجابة المبتدئ: if ($voucher->used) reject(); else markUsed();. الـSenior يرى الفجوة فوراً: كلا الطلبين يقرأ used = false، فيمرّان معاً، ويُستخدم مرتين. "افحص ثم نفّذ" ليست عملية ذرّية.

ما أريده دفاع حقيقي — ويفضّل أكثر من واحد:

// تشاؤمي: امسك قفل الصف طوال المعاملة
DB::transaction(function () use ($code) {
    $voucher = Voucher::where('code', $code)->lockForUpdate()->first();
    abort_if($voucher->used, 409);
    $voucher->update(['used' => true]);
});

والأفضل سماع أن قاعدة البيانات هي الحَكَم الحقيقي: قيد فريد على (voucher_id, user_id) يحوّل السباق إلى استثناء مُمسَك بدل صرفٍ مزدوج صامت. أقفال تشاؤمية، عمود إصدار تفاؤلي، UPDATE ... WHERE used = false ذرّي — أيّها إجابة مقبولة. الإجابة الخاطئة هي عدم معرفة أن السباق موجود. من شغّل كوداً للدفع أو للمحافظ يجيب هذا وهو نائم؛ ومن لم يفعل يكتشفه عادةً هنا.

كيف أستعد — وما أقوله لمن أوجّههم

قراءة الإجابات ليست استعداداً. البناء هو الاستعداد. قبل المقابلات أفعل ثلاثة:

  • أعِد بناء جزء صغير من الذاكرة. تدفّق تسجيل دخول، نقطة نهاية API بترقيم وفلترة، مهمة في طابور بإعادة محاولة. إن فعلتها دون توثيق فأنا أفهمها. إن رجعت للتوثيق فقد وجدت ثغرتي.
  • أعيد قراءة كودي القديم وأشرح لماذا. المقابلات تحبّ أسئلة "لماذا". لماذا خدمة لا كنترولر؟ لماذا مهمة لا تنفيذ مباشر؟ امتلاك السبب أفضل من حفظ النمط.
  • أحضّر قصة واقعية لكل موضوع. الـwebhook الذي أُطلق مرتين. الترحيل الذي أقفل جدولاً في الإنتاج. الاستعلام الذي نزل من 800 إلى 40 مللي ثانية. القصص الملموسة تتفوّق على إجابات الكتب لأنها تُثبت أنك كنت هناك فعلاً.

الحقيقة أن مقابلات الـSenior ليست عن معرفة حقائق أكثر، بل عن ارتكاب أخطاء كافية في الإنتاج حتى تصبح الغريزة الصحيحة تلقائية. لا يمكن تزييف ذلك — لكن يمكنك الاستعداد لتشرحه بوضوح.