ทำความรู้จัก Queue (FIFO): มาก่อน ได้สิทธิ์ก่อน กฎเหล็กของโลกโปรแกรมมิ่ง

1. 🎯 ตอนที่ 6: ทำความรู้จัก Queue (FIFO) มาก่อน ได้สิทธิ์ก่อน
2. 📖 เปิดฉาก (The Hook)
น้องๆ ลองจินตนาการดูนะครับ สมมติว่าเรากำลังทำระบบจองตั๋วคอนเสิร์ตศิลปินระดับโลกที่มีคนรอคิวซื้อนับแสนคน ถ้าระบบของเราดันเอาคนที่เพิ่งกดเข้าเว็บมาล่าสุดให้ได้ตั๋วไปก่อนคนที่มารอตั้งแต่เมื่อคืน… รับรองว่าโดนผู้ใช้งานด่าจนเซิร์ฟเวอร์ไหม้แน่นอนครับ!
ในโลกของความเป็นจริง “ความยุติธรรม” คือสิ่งที่สำคัญที่สุด ใครมาก่อนก็ต้องได้รับการบริการก่อน (First-Come, First-Served) และในโลกของ Computer Science เรามีโครงสร้างข้อมูลระดับพระเอกที่เกิดมาเพื่อรักษากฎเหล็กข้อนี้โดยเฉพาะ นั่นก็คือ Queue (คิว) ครับ วันนี้พี่จะพาไปล้วะไส้การทำงานของ Queue ว่ามันอยู่เบื้องหลังระบบ Task Scheduling และระบบพิมพ์เอกสารที่เราใช้กันทุกวันได้อย่างไร
3. 🧠 แก่นวิชา (Core Concepts)
Queue (คิว) คือโครงสร้างข้อมูลเชิงเส้นที่ทำงานภายใต้กฎ “มาก่อน ได้ก่อน” หรือ First-In, First-Out (FIFO) ตรงข้ามกับ Stack (LIFO) ที่เราเรียนกันไปในตอนที่แล้วอย่างสิ้นเชิงครับ
เปรียบเทียบให้เห็นภาพง่ายๆ Queue ก็เหมือนกับ “การต่อคิวซื้อตั๋วดูหนัง” หรือคิวซื้อชานมไข่มุกนั่นแหละครับ คนที่มาถึงคิวเป็นคนแรก (Front) จะได้สั่งออเดอร์และเดินออกจากคิวก่อน ส่วนคนที่เพิ่งมาถึงก็ต้องไปต่อท้ายแถว (Rear หรือ Back) รอกระเถิบไปเรื่อยๆ จนกว่าจะถึงคิวตัวเอง
การทำงานของ Queue มีท่าไม้ตายหลักๆ อยู่ 2 ท่า ซึ่งทำงานด้วย Time Complexity ระดับไวแสง $O(1)$ ทั้งคู่:
- Enqueue (หรือ Insert/Add): คือการเพิ่มข้อมูลเข้าไปที่ “ท้ายคิว” (Rear)
- Dequeue (หรือ Remove/Delete): คือการดึงข้อมูลออกจาก “หัวคิว” (Front) เพื่อนำไปใช้งาน
- (แถม) Peek (หรือ Front): คือการแอบดูว่าใครอยู่หัวคิว โดยที่ยังไม่ได้ดึงข้อมูลนั้นออกมา

4. 💻 ร่ายมนต์โค้ด (Show me the Code)
ในภาษา Python ถ้าน้องๆ ใช้ list ธรรมดามาทำ Queue แล้วใช้คำสั่ง pop(0) เพื่อดึงหัวคิวออก พี่บอกเลยว่าหายนะ Performance กำลังจะมาเยือนครับ! เพราะการดึงตัวหน้าสุดออก จะทำให้ Python ต้องขยับ (Shift) ข้อมูลที่เหลือทั้งหมดมาข้างหน้า ซึ่งกินเวลา $O(N)$
เคล็ดวิชาที่ Senior Dev ใช้กันคือการเรียกใช้ deque (Double-Ended Queue) จากไลบรารี collections ซึ่งถูกออกแบบมาให้ Enqueue และ Dequeue ได้ในเวลา $O(1)$ ครับ
from collections import deque
class PrintQueue:
def __init__(self):
# ใช้ deque เป็นโครงสร้างพื้นฐานเพื่อ Performance ระดับ O(1)
self.queue = deque()
def enqueue(self, document):
# เพิ่มงานพิมพ์ใหม่ไปต่อท้ายคิว
self.queue.append(document)
print(f"📥 เพิ่ม '{document}' ลงในคิวพิมพ์ (สถานะคิว: {len(self.queue)} งาน)")
def dequeue(self):
# ดึงงานพิมพ์คิวแรกสุดออกไปพิมพ์
if self.is_empty():
return "❌ ไม่มีงานในคิว!"
# popleft() คือการดึงจากหัวคิวแบบ O(1)
doc = self.queue.popleft()
print(f"🖨️ กำลังพิมพ์... '{doc}'")
return doc
def is_empty(self):
return len(self.queue) == 0
# ----- ลองวิชา: ระบบคิวเครื่องพรินเตอร์ -----
my_printer = PrintQueue()
my_printer.enqueue("รายงานสรุปยอดขาย.pdf") # งานที่ 1 (มาถึงก่อน)
my_printer.enqueue("รูปแมว.png") # งานที่ 2
my_printer.enqueue("สไลด์พรีเซนต์ลูกค้า.pptx") # งานที่ 3 (มาหลังสุด)
print("\n--- เริ่มเคลียร์คิวพรินเตอร์ ---")
my_printer.dequeue() # Output: กำลังพิมพ์... 'รายงานสรุปยอดขาย.pdf'
my_printer.dequeue() # Output: กำลังพิมพ์... 'รูปแมว.png'5. 🛡️ เคล็ดลับจากคัมภีร์ลับ (Under the Hood / Pro-Tips)
ในระดับของการออกแบบ System Architecture คัมภีร์ A Common-Sense Guide และ Data Structures & Algorithms ได้ให้แนวทางการประยุกต์ใช้ Queue ในระบบจริงไว้ดังนี้ครับ:
- Printer Queue & Background Workers: คิวคือหัวใจสำคัญของการจัดการงานที่ต้องใช้เวลาทำนานๆ (Asynchronous Requests) เช่น ระบบเครื่องพรินเตอร์ (Print Spooler) ที่รับคำสั่งพิมพ์จากคอมพิวเตอร์หลายสิบเครื่องในออฟฟิศ มันจะเก็บคำสั่งทั้งหมดไว้ใน Queue แล้วค่อยๆ ทยอยพิมพ์ตามลำดับ FIFO อย่างยุติธรรม
- OS Task Scheduling: ระบบปฏิบัติการ (OS) ในเครื่องของน้องๆ ก็ใช้ Queue ในการจัดการคิวของโปรแกรมที่กำลังรอประมวลผลจาก CPU หรือคิวการตอบสนองต่อการคลิกเมาส์และคีย์บอร์ด เพื่อไม่ให้เครื่องค้าง
- ข้อระวังเรื่อง Memory (Circular Array): ในระดับ Low-level หากเราสร้าง Queue ด้วย Array ธรรมดาแบบ Fix-size เมื่อเรา Dequeue ข้อมูลออกจากหัวคิว พื้นที่ด้านหน้าจะว่างลงและถูกปล่อยทิ้งไปอย่างเปล่าประโยชน์! วิศวกรซอฟต์แวร์จึงคิดค้นเทคนิค Circular Array (หรือ Ring Buffer) ที่ยอมให้ Pointer ของท้ายคิว (Rear) วนกลับมาทับพื้นที่ว่างด้านหน้าได้ (Wrap around) ทำให้เราประหยัด Memory และรักษาความเร็วระดับ $O(1)$ ไว้ได้ครับ
6. 🏁 บทสรุป (To be continued…)
Queue (FIFO) คือฮีโร่ผู้พิทักษ์ความยุติธรรมและจัดระเบียบความวุ่นวายในโลกของซอฟต์แวร์ ไม่ว่าน้องๆ จะทำระบบจองตั๋ว, ระบบจัดการคิวลูกค้า (Call Center), หรือแม้แต่อัลกอริทึมค้นหาเส้นทางที่สั้นที่สุดอย่าง Breadth-First Search (BFS) ล้วนต้องมี Queue เป็นเบื้องหลังทั้งสิ้นครับ
แต่เดี๋ยวก่อน! ถ้าคิวชานมไข่มุกมี “ลูกค้า VIP” เดินมาแทรกคิวล่ะ? ระบบ Queue ธรรมดาคงเอาไม่อยู่แน่นอน ในตอนหน้า พี่จะพาไปอัปเกรดความเทพด้วย Priority Queue (คิวจัดลำดับความสำคัญ) ที่ให้สิทธิ์คนที่มีเส้นสาย (Priority สูง) ได้แซงคิวแบบถูกกฎหมาย เตรียมเปิด IDE รอไว้ได้เลยครับ!
ต้องการที่ปรึกษาด้านการออกแบบ System Architecture และพัฒนาระบบซอฟต์แวร์สเกลใหญ่ให้กับองค์กรของคุณ? ทีมงาน WP Solution พร้อมให้บริการออกแบบและพัฒนาซอฟต์แวร์แบบครบวงจร ดูรายละเอียดบริการของเราได้ที่: www.wpsolution2017.com หรือพูดคุยปรึกษาเบื้องต้นได้ที่ Line: wisit.p