🐈⬛
블로그
전체 62024. 10. 20.
1
[인프런 워밍업 클럽 CS 2기] 3주차 발자국
이번 주에는 운영체제와 자료구조 및 알고리즘에 대한 심도 깊은 학습을 진행하였다. 특히 운영체제의 기초부터 고급 개념까지 폭넓게 다루며, 이론과 실습을 통해 이해도를 높였다. 운영체제우선, 메모리의 종류에 대한 이해를 심화했다. 레지스터, 캐시, 메인 메모리, HDD/SSD 각각의 속도 차이를 인지하면서, 각 메모리가 시스템에서 어떤 역할을 하는지 명확히 알게 되었다. 특히, 물리주소와 논리주소의 개념을 통해 메모리 관리의 중요성을 깨달았다. 메모리 할당 방식으로는 가변 분할 방식과 고정 분할 방식을 배웠고, 두 방식의 장단점을 이해하며 현대 시스템에서 왜 버디 시스템과 같은 혼합 방식을 사용하는지에 대한 통찰도 얻었다. 가상 메모리의 원리는 매우 흥미로웠다. 프로그램이 실제 메모리 크기와 상관없이 실행될 수 있게 해주는 이 기술을 통해, 메모리 사용의 효율성을 크게 향상시킬 수 있다는 점을 배웠다. 또한, 디맨드 페이징, 세그멘테이션, 페이징 등 메모리 주소 변환 기법에 대한 이해가 깊어지면서, 이들이 시스템 성능에 미치는 영향을 고려할 수 있게 되었다. 특히, 스레싱과 워킹셋 개념을 통해 과도한 스왑 작업으로 인한 성능 저하 현상을 이해하게 되었다. 이와 함께 주변장치의 구분 및 파일 시스템의 구조에 대해서도 배웠으며, 파일 관리의 중요성을 다시 한번 깨닫게 되었다. 다양한 파일 구조의 특징을 정리하면서 각 구조의 장단점을 비교하고, 실제 응용에서의 활용 가능성을 고민해 보았다. 자료구조와 알고리즘자료구조와 알고리즘에서는 정렬 알고리즘의 기초를 다지는 데 주력했다. 버블, 선택, 삽입 정렬과 같은 구현이 간단하지만 성능이 떨어지는 알고리즘과, 병합 정렬 및 퀵 정렬과 같은 성능이 뛰어난 알고리즘의 차이를 비교하며 각 알고리즘의 특징을 파악했다. 각 정렬 알고리즘의 시간 복잡도를 분석하면서, 어떤 상황에서 어떤 알고리즘이 적합한지를 고민해보는 기회가 되었다. 또한, 동적 프로그래밍의 두 가지 기법인 메모이제이션과 타뷸레이션을 깊이 있게 이해하게 되었다. 메모이제이션은 재귀를 사용하여 중복 계산을 피할 수 있게 해주며, 타뷸레이션은 필요한 값을 모두 미리 계산해 테이블에 저장하는 방식으로, 각각의 장단점과 적용 가능성을 분석하는 데 중점을 두었다. 3주차 회고이번 주는 운영체제와 자료구조 및 알고리즘 강의를 모두 마치게 되어 매우 기쁘다. 강의를 통해 시스템의 작동 원리와 알고리즘의 이론을 명확히 이해할 수 있었고, 혼자서는 경험하지 못했을 깊이 있는 학습이 이루어졌다. 특히 가상 메모리와 동적 주소 변환 개념은 흥미롭고 유용했다. 메모리 관리의 중요성을 깨닫고, 스레싱과 워킹셋의 이해를 통해 성능 최적화에 대한 고민을 하게 되었다. 강의를 통해 배운 이론들을 실제로 어떻게 적용할 수 있을지 고민하며, 더 나아가 이 지식을 바탕으로 실무에서도 활용할 수 있는 방법을 찾아보려 한다.강의를 제작하고 이끌어주신 감자 님에게도 깊은 감사의 인사를 전하고 싶다. 향후 더 많은 강의를 수강할 기회를 기대하며, 앞으로도 계속해서 배우고 성장해 나갈 예정이다. 이 경험이 나의 개발자로서의 길에 큰 밑거름이 될 것이라 확신한다.😁
알고리즘 · 자료구조
・
워밍업클럽
・
CS
2024. 10. 20.
1
[인프런 워밍업 클럽 2기 - CS] 3주차 미션
운영체제1. 메모리의 종류는 어떤 것들이 있나요? 각 메모리의 특징도 함께 적어주세요.• 레지스터: CPU 내부에 있는 가장 빠른 메모리로, 휘발성이다. CPU가 데이터를 처리할 때 메인메모리에서 데이터를 가져와 레지스터에서 연산을 수행한다.• 캐시: 레지스터보다는 느리지만 메인메모리보다는 빠른 메모리로, 필요한 데이터를 미리 저장해 CPU의 메모리 접근 시간을 줄인다.• 메인메모리 (RAM): 실제 운영체제와 실행 중인 프로세스가 올라가는 공간으로, 휘발성이다. 가격이 비싸기 때문에 실행 중인 프로그램을 저장하는 용도로만 사용된다.• 보조저장장치 (HDD/SSD): 비휘발성 메모리로, 데이터를 영구적으로 저장하는 장치이다. 메모리 중에서 가장 느리지만, 대용량 저장이 가능하고 가격이 저렴하다. 2. 사용자 프로세스가 메모리의 운영체제 영역에 침범하지 못하도록 만든 레지스터는 무엇인가요?경계 레지스터이다. 이 레지스터는 운영체제 영역을 보호하며, 프로세스가 경계를 벗어나면 그 프로세스를 종료시킨다. 3. 메모리 할당 방식에서 가변 분할 방식과 고정 분할 방식의 장단점은 무엇인가요?• 가변 분할 방식: 메모리를 프로세스 크기에 맞게 할당하므로 내부 단편화가 발생하지 않는다. 그러나 프로세스 종료 후 남은 공간이 연속적이지 않으면 외부 단편화가 발생할 수 있다.• 고정 분할 방식: 메모리를 고정된 크기로 나누기 때문에 구현이 간단하고 오버헤드가 적다. 그러나 작은 프로세스도 큰 메모리 공간에 할당되므로 내부 단편화가 발생한다. 4. CPU 사용률을 높이기 위해 멀티프로그래밍을 올렸지만, 스왑이 너무 자주 발생해 CPU 사용률이 0%에 가까워지는 현상을 무엇이라고 하나요?이 현상은 스레싱 (Thrashing)이라고 한다. 스왑이 너무 빈번하게 이루어져 CPU가 거의 사용되지 않는 상태를 의미한다. 5. HDD나 SSD는 컴퓨터를 실행시키는 데 꼭 필요한가요?꼭 필요하지는 않다. 컴퓨터 부팅 시 운영체제를 메모리로 불러오는 저장장치가 필요하지만, 이 저장장치가 반드시 HDD나 SSD일 필요는 없다. 예를 들어, USB에 운영체제를 설치하여 이를 통해 부팅할 수도 있다. 6. 파일을 삭제해도 포렌식으로 복구할 수 있는 이유는 무엇인가요?파일을 삭제하면 실제로는 파일 테이블의 헤더만 삭제되고, 데이터 블록은 그대로 남아 있기 때문이다. 복구를 원치 않는 경우, 데이터를 여러 번 덮어씌워야 한다. 자료구조와 알고리즘1. 지금까지 배운 5개의 정렬 알고리즘의 장단점과 시간 복잡도를 적어주세요.• 버블 정렬 (Bubble Sort):장점: 이해와 구현이 매우 간단하다.단점: 성능이 매우 나쁘다.시간 복잡도: O(n²).• 선택 정렬 (Selection Sort):장점: 이해와 구현이 간단하다.단점: 성능이 좋지 않다.시간 복잡도: O(n²).• 삽입 정렬 (Insertion Sort):장점: 구현이 쉽고, 적은 데이터에서는 효율적이다.단점: 많은 데이터에서는 성능이 떨어진다.시간 복잡도: O(n²).• 병합 정렬 (Merge Sort):장점: 안정적이며 성능이 우수하다.단점: 추가적인 메모리 공간이 필요하고, 구현이 다소 어렵다.시간 복잡도: O(nlogn).• 퀵 정렬 (Quick Sort):장점: 평균적으로 매우 빠르다.단점: 피벗 선택이 잘못되면 O(n²)까지 성능이 떨어질 수 있다.시간 복잡도: O(nlogn) (평균), O(n²) (최악). 2. 메모리가 부족한 시스템에서 어떤 문제를 해결하는데 재귀로 쉽게 구현이 가능할 것 같습니다. 여러분이라면 메모이제이션과 타뷸레이션 중 어떤 걸 이용하실 건가요? 이유를 함께 적어주세요.메모리가 부족한 경우 타뷸레이션 방식을 선택하는 것이 적절하다.메모이제이션은 재귀 호출로 인해 스택 오버플로우 위험이 있으며, 메모리 사용량이 많아질 수 있다. 반면, 타뷸레이션은 반복문을 사용하여 미리 정해진 메모리 테이블로 문제를 해결하므로, 메모리 사용을 더 효율적으로 관리할 수 있다!
알고리즘 · 자료구조
・
워밍업클럽
・
CS
2024. 10. 13.
1
[인프런 워밍업클럽 CS 2기] 2주차 발자국
운영체제프로세스 간 통신:프로세스는 같은 컴퓨터 내에서는 파이프나 쓰레드를 사용하고, 다른 컴퓨터 간에는 네트워크를 통해 통신한다.소켓 통신과 원격 프로시저 호출(RPC)을 사용하여 원격 통신을 처리한다.공유 자원과 임계 구역:여러 프로세스가 동시에 접근해서는 안 되는 영역을 임계구역이라 하며, 상호 배제 메커니즘을 통해 하나의 프로세스만 접근할 수 있도록 관리한다. 경쟁 상태를 방지하기 위해 세마포어와 모니터 등의 기법을 사용한다.세마포어:세마포어는 대기 큐와 열쇠 관리자를 통해 프로세스 간의 자원 접근을 관리한다. 그러나 세마포어는 잘못 사용할 경우 문제가 발생할 수 있으며, 이를 보완하기 위해 모니터와 같은 상호배제 메커니즘이 사용된다.데드락:교착 상태는 프로세스들이 자원을 점유하고 다른 프로세스의 작업이 완료되기를 기다리는 상황에서 발생한다. 이를 방지하기 위해 은행원 알고리즘과 같은 회피 기법을 사용한다.메모리 관리:메모리 할당 방식은 고정분할방식(페이징), 가변분할방식(세그멘테이션), 버디 시스템으로 나뉜다. 각 방식은 내부 단편화와 외부 단편화 문제를 해결하며, 효율적인 메모리 관리를 위해 사용된다. 알고리즘재귀:재귀는 함수가 자기 자신을 호출하는 방식으로 문제를 해결하는 기법이다. 이를 통해 반복되는 문제를 하위 문제로 나누어 해결한다. 대표적인 예시로 팩토리얼 계산, 배열의 합, 문자열의 길이 계산, 지수 함수 계산, 하노이 탑 문제를 재귀적으로 풀어낸다. 재귀의 핵심은 기저조건 설정이며, 이를 통해 무한 호출을 방지할 수 있다. 콜스택(FILO 구조)을 사용하여 함수 호출과 종료를 처리한다.재귀 패턴:하위 문제를 해결한 뒤 상위 문제로 확장하는 하향식 계산 방식.반복적인 문제 해결보다는 하위 문제의 결과를 기반으로 상위 문제를 개선하는 방식이 효율적임.재귀 함수 예시:팩토리얼 계산: 하위 문제에서 구한 값을 상위 문제로 연결.배열의 합: 배열을 분할하고 합을 구하는 방식.문자열의 길이: 문자열을 하나씩 제거하면서 길이를 계산.지수 함수: 지수 계산을 재귀적으로 처리.하노이 탑: 문제를 나누어 하향식으로 접근하는 방법을 학습.회고이번 학습을 통해 운영체제의 핵심 원리와 알고리즘의 재귀적 사고 방식을 체계적으로 이해할 수 있었다. 특히, 알고리즘에서는 재귀적 사고를 통한 문제 분할이 얼마나 유용한지 체감할 수 있었으며 간단해 보이지만 재귀 함수 설계 시 기저 조건 설정과 스택 사용이 중요한 부분이라는 점을 깨달았다. 또한, 운영체제에서는 프로세스 간의 자원 공유와 통신이 어떻게 관리되는지, 그리고 자원 경쟁으로 인해 발생할 수 있는 교착 상태를 회피하고 해결하는 다양한 방법을 학습하면서 시스템의 안정성과 성능을 유지하는 것이 매우 중요한 문제임을 알게 되었다!☺
알고리즘 · 자료구조
・
워밍업클럽
・
CS
2024. 10. 13.
1
[인프런 워밍업 클럽 2기 - CS] 2주차 미션
운영체제FIFO 스케줄링의 장단점이 뭔가요?:장점:구현이 간단하며 요청된 순서대로 처리(선입선출).CPU 점유가 긴 프로세스가 없다면 응답 속도가 빠를 수 있다.단점:긴 작업이 앞에 있을 경우 짧은 작업이 오래 기다려야 한다. SJF를 사용하기 여러운 이유가 뭔가요?:각 프로세스의 실행 시간을 미리 예측하기 어렵다.실행시간이 너무 긴 프로세스는 너무 늦게 실행된다. RR 스케줄링에서 타임 슬라이스가 아주 작으면 어떤 문제가 발생할까요?:컨텍스트 스위칭 비용이 증가하여 CPU 시간이 많이 소모된다.실제로 작업 처리 시간이 감소하여 성능 저하 발생 가능하다. 운영체제가 MLFQ에서 CPU Bound Process와 I/O Bound Process를 어떻게 구분할까요?:PU 사용량이 많다 보니 타임 슬라이스를 넘어 CPU가 뺏기게 된다.I/O Bound Process의 경우 CPU 사용량이 적다 보니 타임 슬라이스 내에 CPU를 반납한다. 공유자원이란무엇인가요?:여러 프로세스가 동시에 접근할 수 있는 자원을 말한다(예: 프린터, 파일, 데이터베이스 등). 교착상태에 빠질 수 있는 조건은 어떤 것들을 충족해야할까요?:상호 배제: 자원을 프로세스가 가져갔다면 다른 프로세스에게 공유되면 안된다.비선점: 다른 프로세스가 자원을 강제로 뺏을 수 없어야 한다.점유 및 대기: 자원을 점유한 채 다른 프로세스는 이 리소스를 원하면서 기다리고 있어야 한다. 원형 대기 : 점유와 대기를 하는 프로세스들의 관계가 원형을 이루고 있어야 한다. 위에 조건이 하나라도 충족되지 않으면 교착상태가 일어나지 않는다.자료구조와 알고리즘재귀함수에서 기저조건을 만들지 않거나 잘못 설정했을 때 어떤 문제가 발생할 수 있나요?:무한 루프: 기저 조건이 없거나 잘못 설정되면 함수가 종료되지 않고 계속 호출되면서 무한 루프가 발생한다.Stack Overflow: 재귀 호출이 무한정 계속되면 스택 메모리가 가득 차서 Stack Overflow 에러가 발생하게 된다. 0부터 입력 n까지 홀수의 합을 더하는 재귀 함수를 만들어보세요. :function sumOdd(n){ // 재귀 로직 if (n
알고리즘 · 자료구조
・
워밍업클럽
・
CS
2024. 10. 06.
1
[인프런 워밍업클럽 CS 2기] 1주차 발자국
자료구조와 알고리즘자료구조 : 데이터를 효율적으로 저장하고 관리하는 방법. 배열, 연결리스트, 스택, 큐, 트리, 그래프 등이 있다. 알고리즘 : 어떤 문제를 해결하기 위해 정해진 일련의 절차나 규칙을 의미하며, 주어진 입력에 대해 결과를 도출하는 과정이다. 시간 복잡도 : 알고리즘이 수행되는 데 걸리는 시간을 입력 크기에 대한 함수로 표현한 것. 주로 O(1), O(n), O(n²) 등의 표기법으로 나타낸다. 배열 : 고정된 크기의 연속된 메모리 공간에 데이터를 저장하는 자료구조. 인덱스를 통해 빠르게 접근할 수 있지만 크기가 고정되어 있으며 중간에 데이터를 삽입하거나 삭제하는 데는 비효율적이다. 시간 복잡도: 접근 O(1), 삽입/삭제 O(n) 연결 리스트(Linked List) :각 노드가 데이터와 다음 노드의 주소를 가지는 동적 자료구조. 삽입과 삭제가 용이하지만,특정 위치에 접근하려면 순차적으로 접근해야 하므로 시간이 더 걸린다.시간 복잡도: 접근 O(n), 삽입/삭제 O(1)export class Node{ constructor(data, next = null){ this.data = data; this.next = next; } } // * 연결 리스트 추상 자료형 // 1. 모든 데이터 출력 -> printAll(); // 2. 모든 데이터 제거 -> clear(); // 3. 원하는 인덱스에 데이터를 삽입 -> insertAt(index, data); // 4. 마지막 데이터 뒤에 데이터를 삽입 -> insertLast(data); // 5. 원하는 인덱스에 데이터를 삭제 -> deleteAt(index); // 6. 마지막 데이터를 제거 -> deleteLast(); // 7. 원하는 인덱스에 있는 데이터 읽기 -> getNodeAt(index); export class LinkedList { constructor(){ // 연결 리스트의 시작 Node를 가리킨다. this.head = null; // 총 저장된 Node의 수 this.count = 0; } /** * 원하는 인덱스에 데이터를 삽입 * @param {number} index - 삽입할 위치 index * @param {any} data - 삽입할 데이터 */ insertAt(index, data){ // 예외 처리 if(index > this.count || index = this.count || index = this.count || index 스택(Stack) :후입선출(LIFO: Last In, First Out) 방식의 자료구조. 마지막에 추가된 요소가 먼저 제거된다. 함수 호출, 되돌리기 기능 등에서 사용된다.시간 복잡도: 접근/삽입/삭제 O(1)import { LinkedList } from './../LinkedList/LinikedList.mjs'; // * 스택의 추상자료형 // 1. 데이터 삽입 -> push(); // 2. 데이터 제거 -> pop(); // 3. top에 있는 데이터 참조 -> peek(); // 4. 스택이 비었는지 체크 -> isEmpty(); export class Stack{ constructor(){ this.list = new LinkedList(); } push(data){ this.list.insertAt(0, data); } pop(){ try { return this.list.deleteAt(0); } catch (error) { return null; } } peek(){ return this.list.getNodeAt(0); } isEmpty(){ return this.list.count === 0; } } 큐 (Queue):선입선출(FIFO: First In, First Out) 방식의 자료구조. 먼저 들어온 데이터가 먼저 처리된다. 대기열, 주문 처리 등 순차적으로 처리해야 할 때 사용된다.시간 복잡도: 접근/삽입/삭제 O(1) import { DoublyLinkedList } from "./DoublyLinkedList.mjs"; // * 기존에 구현한 Node에서 이전 Node도 가리킬 수 있도록 Node를 수정 // * 기존의 LinkedLst를 연결 리스트의 끝을 가리킬 수 있도록 수정 -> DoublyLinkedList // * 큐의 추상자료형 // 1. 데이터 삽입 -> enqueue(); // 2. 데이터 제거 -> dequeue(); // 3. 데이터 참조 -> front(); // 4. 큐가 비었는지 확인 -> isEmpty(); class Queue{ constructor(){ this.list = new DoublyLinkedList(); } enqueue(data){ this.list.insertAt(0, data); } dequeue(){ try{ return this.list.deleteLast(); } catch(e){ return null; } } front(){ return this.list.tail; } isEmpty(){ return (this.list.count == 0); } } export {Queue}; 운영체제폴링 방식 : 주기적으로 상태를 확인하는 방식.인터럽트 : 외부나 내부에서 발생하는 사건이 CPU의 주의를 끌어 현재 작업을 중단하고 즉시 그 사건을 처리하도록 하는 메커니즘.프로그램과 프로세스 :프로그램: 실행되지 않은 상태의 정적 코드. 하드디스크 등에 저장된 명령어 집합. 프로세스: 실행 중인 프로그램. 운영체제에서 메모리와 CPU 등의 자원을 할당받아 실행되는 단위.PCB : 프로세스 제어 블록으로, 운영체제가 프로세스를 관리하기 위한 정보(프로세스 상태, 프로그램 카운터, 메모리 정보 등)를 담고 있는 구조체.프로세스 : 실행 중인 프로그램으로, CPU와 메모리 자원을 할당받아 동작하며 독립적인 실행 단위를 형성한다.컨텍스트 스위칭: 하나의 프로세스나 스레드가 CPU에서 실행되다가 다른 프로세스로 전환될 때, 현재 프로세스의 상태를 저장하고 새로운 프로세스의 상태를 복구하는 과정.
알고리즘 · 자료구조
・
워밍업클럽
・
CS
2024. 10. 06.
1
[인프런 워밍업 클럽 2기 - CS] 1주차 미션
운영체제while(true){ wait(1); // 1초 멈춤 bool isActivated = checkSkillActivated(); // 체크 } 위 코드는 1초 마다 플레이어가 스킬을 사용했는지 체크하는 코드입니다. 이 방식은 폴링방식입니다. 1초마다 체크하기 때문에 성능에 좋지 않습니다. 이를 해결하기 위한 방식으로 어떤 걸 이용해야 할까요?인터럽트 방식을 사용하는게 좋을 것 같습니다.인터럽트는 비동기적으로 동작하기 때문에 성능을 개선할 수 있는 이점이 있습니다.이와 같이 인터럽트를 사용하면 폴링 방식보다 더 효율적으로 스킬 사용 여부를 체크할 수 있으며,CPU 자원을 보다 효과적으로 활용할 수 있습니다. 프로그램과 프로세스가 어떻게 다른가요? 프로그램: 저장장치에 저장된 실행 가능한 코드(정적 개체)입니다.실행되기 전까지는 하드디스크나 메모리에만 존재하는 단순한 명령어 집합입니다.프로세스: 프로그램이 메모리에 적재되어 실행되고 있는 상태(동적 개체)입니다.프로세스는 운영체제에 의해 메모리, CPU 등 자원을 할당받고 실행됩니다. 멀티프로그래밍과 멀티프로세싱이 어떻게 다른가요?멀티프로그래밍: 여러 프로그램이 메모리에 동시에 적재되어 실행되도록 하는 기법입니다.하나의 CPU가 각 프로그램을 번갈아가며 실행하는 방식입니다.즉, 프로그램 간 자원을 효율적으로 나누는 것을 목표로 합니다.멀티프로세싱: 둘 이상의 CPU(또는 코어)를 사용하는 기법으로, 여러 프로세스가 동시에 실행됩니다.각 프로세스는 독립된 CPU에서 병렬적으로 실행되므로 성능이 더 뛰어납니다. 운영체제는 프로세스를 관리하기 위해서 어떤 것을 사용하나요? 운영체제는 프로세스를 효율적으로 관리하기 위해 프로세스 제어 블록(PCB)을 사용합니다.PCB에는 프로세스의 상태, 메모리 정보, 프로그램 카운터, 레지스터 정보 등 프로세스의 실행 상태를 저장하고 있습니다.운영체제는 PCB를 기반으로 프로세스를 생성, 관리, 스케줄링합니다. 컨텍스트 스위칭이란 뭔가요? 컨텍스트 스위칭은 운영체제가 CPU에서 실행 중인 프로세스를 다른 프로세스로 교체할 때 발생하는 과정입니다. 실행 중이던 프로세스의 상태(레지스터, 프로그램 카운터 등)를 저장하고, 새로 실행할 프로세스의 상태를 복구하는 과정이 포함됩니다. 컨텍스트 스위칭은 프로세스나 스레드 간 전환을 가능하게 하지만, 빈번하게 발생하면 성능에 부담이 될 수 있습니다. 자료구조와 알고리즘여러분은 교실의 학생 정보를 저장하고 열람할 수 있는 관리 프로그램을 개발하려고 합니다.이 때 여러분이라면 학생의 정보를 저장하기 위한 자료구조를 어떤 걸 선택하실 건가요?이유를 함께 적어주세요. 연결 리스트(Linked List) 자료구조를 사용하겠습니다.그 이유는 학생 정보가 추가되거나 삭제될 때 효율적으로 처리할 수 있기 때문입니다.배열과 달리, 연결리스트는 중간에 있는 학생 정보를 쉽게 추가하거나 삭제할 수 있어 유연한 데이터 관리를 할 수 있기 때문입니다. 여러분은 고객의 주문을 받는 프로그램을 개발하려고 합니다.주문은 들어온 순서대로 처리됩니다. 이 때 여러분이라면 어떤 자료구조를 선택하실 건가요?이유를 함께 적어주세요. 큐(Queue) 자료구조를 사용하겠습니다.큐는 선입선출 방식으로 동작하는 자료구조로, 먼저 들어온 주문이 먼저 처리되도록 보장하므로 이는 실제 주문 시스템에서 자연스러운 흐름을 구현할 수 있기 때문입니다.
알고리즘 · 자료구조
・
워밍업클럽
・
CS