"스택은 성급해 — 마지막에 온 사람을 모셔. 큐는 공정해 — 가장 오래 기다린 사람을 모셔. 사람을 건드리는 대부분 시스템은 공정한 쪽을 원해."
먼저 들어온 게 먼저 나간다
큐는 도착 순으로 모셔: enqueue 는 뒤에 추가, dequeue 는 앞에서 제거, 가장 오래된 항목이 늘 먼저 가. 시간에 따른 공정함의 구조야 — 계산대 줄, 인쇄 작업, 번호표 시스템, 작업 스케줄러. "선착순" 이 맞는 정책인 어디든, 밑에 큐가 깔려.
리스트 함정, 한 번 더
Python 리스트로 큐를 지으려 할 수 있어: enqueue 에 append, dequeue 에 pop(0). 작동해 — 그리고 dequeue 당 조용히 O(n) 이야, pop(0) 이 인덱스 0 을 채우려 남은 모든 원소를 왼쪽으로 미니까. 진짜 작업을 통과시키면 큐가 몰래 O(n²). 고침은 collections.deque, 정확히 이걸 위해 지어졌어: 양 끝에서 O(1). 큐엔 반사적으로 deque 로 가; 평범한 리스트는 틀린 기계야.
덱: 맥가이버 칼 버전
덱 ("deck", double-ended queue) 은 앞과 뒤 양쪽에서 O(1) push 와 pop 을 허용해. 그래서 상위집합이야: 한쪽만 쓰면 스택; 반대 끝을 쓰면 큐; 양쪽을 자유롭게 쓰면 슬라이딩 윈도우나 작업-훔치기 구조. Python 의 deque 는 고정 크기 블록의 연결 리스트가 받쳐 — Linked Lists 트랙이 약속한, 연결 구조가 배열을 진짜로 이기는 바로 그 자리야.
링 버퍼: 잊는 큐
아름다운 특수 케이스: deque(maxlen=N) 은 고정 크기 링 버퍼야. 용량 너머로 push 하면 가장 오래된 항목이 반대쪽 끝으로 조용히 떨어져. "마지막 N 개만 유지" 에 완벽해 — 최근 100 로그 줄, 센서 읽기의 롤링 윈도우, 마지막 50 채팅 메시지. 수동 자르기 없음, 성장 없음, push 당 O(1). 큐이면서 잊는 기계고, 스트리밍이랑 모니터링 코드에 끊임없이 나타나.
피파의 고백
[-100:] 슬라이싱으로 마지막 100 개를 유지했어. 작동했지만, 매 이벤트가 리스트를 다시 슬라이싱하고 다시 복사했어. 아빠가 전체를 deque(maxlen=100) 으로 바꿨어 — 한 줄, 이벤트당 O(1), 오래된 것 자동 퇴출. 내 자르기 로직 열 줄이 사라졌어. 맞는 구조는 속도만 올린 게 아니라; 내가 애초에 안 써도 됐을 코드를 지웠어.