ما معنى FIFO؟ شرح مبسّط لقاعدة «الأول دخولاً الأول خروجاً» والطابور (Queue)
FIFO اختصار لعبارة First In, First Out، أي «الأوّل دخولاً هو الأوّل خروجاً»، وهي القاعدة التي يعمل بها هيكل البيانات المعروف باسم الطابور (Queue). أمّا عبارة «see queue» التي تراها ملتصقة بالمصطلح فليست جزءاً منه؛ إنّها مجرّد إشارة فهرسة إنجليزية تعني «راجع: Queue»، أي أنّ FIFO والطابور وجهان لمفهوم واحد: كل عنصر يدخل أولاً يُعالَج أولاً، تماماً كما في صفّ انتظار عادل لا يسمح بالتخطّي.
كيف يعمل الطابور فعليّاً؟
تخيّل صفّاً أمام شبّاك بيع التذاكر. من يقف أولاً يُخدَم أولاً، ومن يصل حديثاً يقف في نهاية الصف. الطابور في البرمجة يفعل الشيء نفسه بالضبط، وله طرفان محدّدان:
- المؤخرة (Rear / Tail): المكان الذي تُضاف فيه العناصر الجديدة، وتُسمّى العملية enqueue (الإضافة).
- المقدّمة (Front / Head): المكان الذي تخرج منه العناصر، وتُسمّى العملية dequeue (الإزالة).
النقطة الجوهرية أنّ الإضافة تحدث من طرف والإزالة من الطرف المقابل، وهذا ما يضمن ترتيب «الأول دخولاً الأول خروجاً». لو أضفتَ الأرقام 1 ثم 2 ثم 3، فسيخرج 1 أولاً، ثم 2، ثم 3، بالترتيب نفسه الذي دخلت به دون أي تغيير.
FIFO مقابل LIFO: ما الفرق بين الطابور والمكدّس؟
كثيرون يخلطون بين الطابور (Queue) والمكدّس (Stack)، مع أنّ قاعدتيهما متعاكستان تماماً. الجدول التالي يوضّح الفرق بسرعة:
| الوجه | الطابور (Queue) — FIFO | المكدّس (Stack) — LIFO |
|---|---|---|
| المعنى | الأول دخولاً، الأول خروجاً | الأخير دخولاً، الأول خروجاً |
| مكان الإضافة | المؤخرة | القمّة (Top) |
| مكان الإزالة | المقدّمة | القمّة (Top) |
| التشبيه الواقعي | صفّ انتظار في بنك | كومة أطباق فوق بعضها |
| استخدام شائع | جدولة المهام، بحث العرض أولاً (BFS) | زر «تراجُع» Undo، استدعاء الدوال |
القاعدة البسيطة للتذكّر: الطابور عادل (من سبق خرج أولاً)، أمّا المكدّس فيخدم الأحدث (آخر من دخل يخرج أولاً).
أين تُستخدم قاعدة FIFO؟
قاعدة FIFO ليست مفهوماً نظرياً فحسب، بل تعمل خلف كثير من الأنظمة التي تستعملها يوميّاً:
- طابور الطباعة: المستندات تُطبع بالترتيب الذي أُرسلت به.
- جدولة المهام في أنظمة التشغيل: تنظيم تنفيذ العمليات بترتيب وصولها في أبسط الخوارزميات.
- خوارزمية البحث بالعرض أولاً (BFS): تعتمد على طابور لزيارة عُقَد الرسم البياني مستوىً تلو الآخر.
- الحواجز المؤقتة (Buffers): كتدفّق الفيديو أو الصوت، حيث تُعالَج البيانات بترتيب وصولها.
- أنظمة الرسائل والطلبات: طوابير المهام في الخوادم تضمن معالجة الطلبات بعدالة دون تجاهل الأقدم.
كيف تنفّذ طابور FIFO بشكل صحيح؟ (وخطأ شائع)
في معظم اللغات يمكن بناء طابور عبر مصفوفة أو قائمة مرتبطة. لكن هنا يقع المبتدئون في فخّ الأداء: في لغة بايثون مثلاً، استخدام قائمة عادية مع list.pop(0) لإخراج العنصر الأول يبدو منطقيّاً، لكنّه بطيء؛ لأنّ إزالة أول عنصر تُجبر البرنامج على إزاحة كل العناصر الباقية، فتصبح تكلفتها خطّية O(n).
الحل الصحيح هو استخدام collections.deque، وهي بنية مصمَّمة للإضافة والإزالة من الطرفين بتكلفة ثابتة O(1):
from collections import deque
queue = deque()
queue.append(1) # enqueue
queue.append(2)
print(queue.popleft()) # dequeue -> 1
print(queue.popleft()) # dequeue -> 2
نصيحة عملية: كلما تعاملتَ مع طابور فيه آلاف العناصر، تجنّب المصفوفة العادية مع pop(0) واستعمل بنية مخصّصة (deque في بايثون، أو Queue/LinkedList في جافا). الفرق لا يظهر مع بيانات صغيرة، لكنه يتحوّل إلى بطء ملموس عند الحجم الكبير.
نقطة أخرى مهمّة: قبل عملية dequeue، تحقّق دائماً من أنّ الطابور ليس فارغاً، وإلّا فقد يرمي برنامجك خطأً أو يُعيد قيمة غير متوقّعة.
الأسئلة الشائعة
هل «see queue» جزء من مصطلح FIFO؟ لا. إنّها إشارة فهرسة تعني «راجع: Queue»، ظهرت غالباً من قاموس أو فهرس تقني، وليست جزءاً من الاسم. المصطلح الحقيقي هو FIFO، وهو قاعدة عمل الطابور.
ما الفرق بين FIFO وLIFO باختصار؟ FIFO يُخرِج الأقدم أولاً (الطابور)، وLIFO يُخرِج الأحدث أولاً (المكدّس). القاعدتان متعاكستان في اتجاه الخروج.
هل الطابور دائماً أسرع من المكدّس؟ لا علاقة للسرعة بالاختيار؛ كلاهما يوفّر عمليات بتكلفة O(1) عند تنفيذه بشكل صحيح. الفرق في ترتيب المعالجة لا في السرعة، فاختر بحسب المنطق الذي يحتاجه برنامجك.
متى أستخدم الطابور بدل المكدّس؟ استخدم الطابور حين يهمّك الترتيب الزمني والعدالة (من جاء أولاً يُخدَم أولاً)، مثل جدولة المهام أو خوارزمية BFS. واستخدم المكدّس حين تحتاج الرجوع إلى الخلف، مثل ميزة «التراجع» أو تتبّع استدعاءات الدوال.