[인프런 워밍업 클럽 3기 CS전공지식] 2주차 발자국
1일차프로세스 동기화와 통신,재귀 프로세스 간 통신프로세스는 독립적으로 실행될 수도 있지만 다른 프로세스와 데이터를 주고받으며 통신하기도 합니다.통신 방식은 한 컴퓨터 내의 프로세스 간 통신과 네트워크를 통해 다른 컴퓨터의 프로세스와 통신하는 방법으로 나눌 수 있습니다. 프로세스 간 통신 방법파일(File) 이용통신하려는 프로세스들이 공통된 파일을 이용하여 데이터를 읽고 씁니다.파이프(Pipe) 이용운영체제가 생성한 파이프를 통해 데이터를 읽고 쓰는 방식입니다. 한 프로세스가 파이프에 데이터를 쓰면, 다른 프로세스가 이를 읽습니다. 쓰레드를 이용한 통신한 프로세스 내에서 쓰레드 간 통신 방법입니다.쓰레드는 코드, 데이터, 힙 영역을 공유하고, 각 쓰레드는 독립적인 스택을 가집니다. 따라서 공유된 데이터나 힙 영역을 통해 쓰레드 간 데이터를 주고받을 수 있습니다.네트워크를 이용한 통신소켓(Socket): 운영체제가 제공하는 소켓을 사용하여 네트워크 상의 다른 컴퓨터와 통신합니다.RPC(Remote Procedure Call, 원격 프로시저 호출): 네트워크를 통해 다른 컴퓨터의 프로세스에 있는 함수를 호출하는 방식입니다. 공유 자원과 임계 구역공유 자원프로세스 간 통신에서 공동으로 사용하는 변수나 파일 등을 공유 자원(Shared Resource) 이라고 합니다.공유 자원은 여러 프로세스가 동시에 접근할 경우, 접근 순서에 따라 결과가 달라질 수 있습니다.경쟁 조건 (Race Condition)여러 프로세스가 동시에 공유 자원에 접근하려고 경쟁하는 상황을 경쟁 조건이라 합니다.컨텍스트 스위칭(Context Switching)으로 인해 어떤 프로세스가 먼저 실행될지 예측하기 어렵습니다.따라서 여러 프로세스가 동시에 사용하면 안되는 영역을 정의했는데 이를 **임계구역이라 함**임계 구역 (Critical Section)여러 프로세스가 동시에 접근하면 안 되는 코드 영역을 임계 구역이라 합니다. 임계 구역 문제 해결 - 상호 배제 매커니즘(Mutual Exclusion)임계 구역 문제를 해결하려면 상호 배제 매커니즘이 필요합니다.주요 상호 배제 메커니즘뮤텍스(Mutex):상호 배제를 위한 동기화 도구로, 한 번에 하나의 프로세스 또는 스레드만 접근할 수 있도록 합니다.세마포어(Semaphore):공유 자원에 여러 프로세스가 동시에 접근하는 것을 방지하기 위한 동기화 도구입니다.모니터(Monitor):공유 자원과 해당 자원에 대한 연산을 묶어서 관리하는 동기화 도구입니다.상호 배제를 만족하기 위한 요구사항:상호 배제: 어떤 시점에도 하나의 프로세스만 임계 구역에 접근해야 합니다.진행 조건: 여러 프로세스가 임계 구역에 들어가기를 원하면, 하나의 프로세스만 선택되어야 합니다.유한 대기: 임계 구역에 들어간 프로세스는 최대한 빨리 종료해야 하며, 다른 프로세스가 무한정 기다리는 것을 방지해야 합니다. 프로세스 동기화 기법세마포어 (Semaphore)공유 자원에 여러 프로세스가 동시에 접근하는 것을 방지하기 위한 동기화 도구입니다.wait() 함수와 signal() 함수를 사용하여 자원 접근을 조절합니다.문제점: wait()와 signal()을 잘못 사용하면 **교착 상태(Deadlock)나 **경쟁 상태가 발생할 수 있습니다.**교착 상태 : 여러 프로세스가 서로 필요한 자원을 기다리면서 무한정 대기하는 상태입니다. 세마포어의 wait() 함수를 잘못 사용하면 교착 상태가 발생할 수 있습니다.**경쟁 상태 : 세마포어의 signal() 함수를 잘못 사용하면 여러 프로세스가 동시에 임계 구역에 접근하여 데이터 불일치 등의 문제가 발생할 수 있습니다. 세마포어의 사용 코드 예제(JAVA) public static void main(String[] args) throws InterruptedException { Semaphore semaphore = new Semaphore(1); semaphore.acquire(); // acqurie()는 wait()과 같은 역할을 담당 System.out.println("wait 실행"); semaphore.release(); // release()는 signal()과 같은 역할을 담당 System.out.println("signal 실행"); } 모니터 (Monitor)세마포어의 문제점을 보완한 상호 배제 매커니즘입니다.운영체제가 아닌 프로그래밍 언어 차원에서 제공하며, Java의 synchronized 키워드가 대표적입니다.synchronized 키워드가 붙은 메서드는 한 번에 하나의 쓰레드만 접근할 수 있습니다. 그럼 세마포어의 문제점을 보완한게 모니터니까 모니터를 사용하는게 가장 좋은건가??세마포어와 모니터: 세마포어는 개발자가 직접 'wait'과 'signal'을 조작해야 하기 떄문에 세밀한 관리가 가능하지만 호출 순서 및 위치를 잘못 설정하면 교착상태,경쟁조건이 생길 수 있어 복잡하고 세밀한 동기화를 사용하기 좋음모니터는 공유 자원에 접근하는 코드를 '모니터'라는 방 안에 넣으면 알아서 한 번에 한 명씩만 들어가도록 관리를 해줘 개발자는 안전하게 코드가 작성이 가능해 안전한 동기화에 좋지만 세마포어보다 오버헤드가 클 수 가있음모니터의 사용 코드 예제(JAVA) public static void main(String[] args) { Object lock = new Object(); // 락으로 사용할 객체 synchronized (lock) { // 락이 있을경우 해당 메서드에 진입해 실행 System.out.println("Inside synchronized block."); //실행문 종료 후 별다른 명령어 없이 자동으로 lock 반납 } } 뮤텍스 (Mutex)세마포어와 유사하지만, 뮤텍스는 오직 하나의 프로세스/스레드만 공유 자원에 접근하도록 제한합니다.잠금(lock)과 해제(unlock) 연산을 통해 임계 영역을 보호합니다.주로 하나의 공유 자원에 대한 접근을 순차적으로 처리해야 할 때 사용됩니다.뮤텍스는 잠금을 소유한 스레드만이 잠금을 해제할 수 있다는 특징이 있습니다.뮤텍스의 사용 코드 예제(JAVA) public static void main(String[] args) { ReentrantLock lock = new ReentrantLock(); lock.lock(); // lock 활성화 System.out.println("Lock acquired."); lock.unlock(); // lock 반납 System.out.println("Lock released."); }재귀 (Recursion)재귀란?어떤 것을 정의할 때 자기 자신을 참조하는 방식입니다.함수가 자기 자신을 호출하는 재귀 함수가 대표적인 예입니다.재귀 함수의 종료 조건재귀 함수에는 반드시 탈출 조건이 필요합니다.탈출 조건이 없으면 무한 재귀가 발생하며, **콜 스택(Call Stack)이 가득 차 프로그램이 비정상 종료됩니다.함수를 호출하면 해당 함수는 콜스택 위에 올라가고 함수가 종료되면 콜스택에서 제거됨**콜 스택 (Call Stack)함수 호출 기록을 저장하는 메모리 영역입니다.FILO(First In Last Out) 구조를 가지며, 마지막에 호출된 함수가 가장 먼저 종료됩니다. 재귀, 반복문반복문(for, while)으로 해결 가능한 문제를 재귀 함수로 구현하면 비효율적일 수 있습니다.재귀 함수는 함수를 호출할 때마다 새로운 **스택 프레임을 생성합니다. 이 스택 프레임에는 함수의 매개 변수지역 변수,반환 주소 등의 정보가 저장되어 코드만 실행하면 되는 반복문에 비해 함수 호출 및 스택 관리에 더 많은시간과 메모리를 소비해야함** 스택 프레임??프로그램 실행 중에 함수가 호출될 때 생성되는 메모리 블록으로 함수에 호출된 정보를 저장그러나 팩토리얼 계산등 문제의 구조 자체가 재귀적인 경우 재귀 함수가 유리합니다.// 반복문 int sum = 0; for (int i = 1; i <= n; i++) { sum += i; } // 재귀 함수 int recursiveSum(int n) { if (n == 1) { return 1; } return n + recursiveSum(n - 1); } 팩토리얼 예제(JAVA)public class FactorialExample { public static int factorial(int n) { if (n == 1) return 1; // 탈출 조건 return n * factorial(n - 1); } public static void main(String[] args) { System.out.println("5! = " + factorial(5)); // 120 출력 } }2일차프로세스 동기화와 통신,재귀 교착상태 (Deadlock)교착상태란?교착상태(Deadlock)는 여러 프로세스가 서로 다른 프로세스가 보유한 자원을 기다리며 무한히 대기하는 상태를 의미합니다. 이 상태에 빠지면 어떤 프로세스도 작업을 진행하지 못하게 됩니다.공유 자원: 프로세스들이 서로 공유하는 자원(예: 프린터, 메모리 등)이 있을 때 발생할 수 있음.독립 자원: 반대로, 공유하지 않는 자원만 사용한다면 교착상태는 발생하지 않음. 교착상태의 필요조건교착상태가 발생하기 위한 4가지 필요조건이 있으며, 이 중 하나라도 충족되지 않으면 교착상태가 발생하지 않습니다.상호 배제 (Mutual Exclusion)어떤 자원이 한 프로세스에 의해 점유되었다면, 그 자원은 다른 프로세스와 공유되지 않아야 함.비선점 (No Preemption)다른 프로세스가 점유한 자원을 강제로 빼앗을 수 없어야 함.점유와 대기 (Hold and Wait)어떤 프로세스가 자원을 점유한 상태에서 추가 자원을 기다려야 함.즉, 이미 할당된 자원을 보유하면서 다른 자원을 요청하고 대기하는 상태여야 합니다.원형 대기 (Circular Wait)점유와 대기 상태의 프로세스들이 원형으로 연결되어 있어야 함.예를 들어, 프로세스 A는 프로세스 B가 가진 자원을 기다리고, 프로세스 B는 프로세스 C가 가진 자원을 기다리고, 프로세스 C는 프로세스 A가 가진 자원을 기다리는 식입니다. 교착상태 해결 방법교착 상태는 여러 프로세스가 서로 필요한 자원을 기다리며 무한히 대기하는 상황을 의미합니다. 이러한 교착 상태를 해결하기 위한 다양한 방법 중 하나가 바로 **교착 상태 회피입니다.**교착 상태 회피란?시스템이 자원을 할당하기 전에 교착상태 가능성을 검사하고, 교착상태가 발생하지 않도록 자원을 할당.대표 알고리즘: **은행가 알고리즘 (Banker's Algorithm)** 은행가 알고리즘의 특징시스템은 프로세스들의 최대 요구 자원을 미리 알고 있어야 함.자원 할당 전에 시스템의 상태를 안정 상태(Safe State)와 불안정 상태(Unsafe State)로 구분안정 상태(Safe State): 교착상태에 빠지지 않을 수 있는 상태.불안정 상태(Unsafe State): 교착상태에 빠질 가능성이 있는 상태. (불안정 상태가 반드시 교착상태를 의미하진 않음)안정 상태의 예시시스템의 총 자원 14개P1: 최대 9개, 현재 5개 점유 → 추가로 4개 필요P2: 최대 6개, 현재 4개 점유 → 추가로 2개 필요P3: 최대 4개, 현재 3개 점유 → 추가로 1개 필요사용 가능한 자원: 2개자원 할당 순서P1은 4개를 요청하므로 거절.P2는 2개 요청 가능 → 작업 완료 후 6개 반납.P1은 이제 4개 요청 가능 → 작업 완료 후 자원 반납.불안정 상태의 예시시스템의 총 자원 10개P1: 최대 7개, 현재 5개 점유 → 추가로 2개 필요P2: 최대 5개, 현재 3개 점유 → 추가로 2개 필요P3: 최대 4개, 현재 2개 점유 → 추가로 2개 필요사용 가능한 자원: 1개자원 할당 상태P1, P2, P3 모두 추가 자원을 받기 위해 대기.사용 가능한 자원이 1개뿐이라 어느 프로세스도 필요한 자원을 다 받지 못함.세 프로세스가 서로 자원을 기다리며 무한 대기 상태 → 교착상태 발생 교착상태가 발생한지 알아내는 방법가벼운 교착상태 검출:타이머를 설정해 특정 시간 동안 프로세스가 작업을 하지 않으면 교착상태라고 판단.해결 방법 : 체크포인트를 통해 주기적으로 상태를 저장하고, 교착상태 발생 시 마지막 체크포인트로 롤백.간단하지만, 오탐지 가능성이 있고 롤백에 따른 오버헤드가 발생할 수 있습니다무거운 교착상태 검출:**자원 할당 그래프(Resource Allocation Graph, RAG)를 사용.프로세스-자원 관계를 그래프로 표현하고 사이클이 발견되면 교착상태로 간주.정확도가 높지만, 자원 할당 그래프를 관리하고 순환을 탐지하는 데 오버헤드가 발생합니다.오버헤드가 발생하지만, 프로세스를 강제로 종료하지 않고 교착상태를 해결 가능. **자원 할당 그래프자원할당 그래프의 사이클이 존재하는 지 그림으로 확인해당 그림처럼 프로세스와 자원 간의 사이클이 존재한다면 교착상태이고 해당 그림처럼 프로세스와 자원간의 사이클이 없으면 교착상태가 아니다하지만 사이클이 있어도 교착상태에 안걸리는 경우도 존재하는데P2와 P4가 작업을 완료하고 자원을 반납하면R1과 R2의 자원을 반납P1과 P3가 필요한 자원을 얻을 수 있음.원형 대기 상태가 깨지므로 교착상태가 해소됨. 재귀적으로 생각하기 패턴 1: 단순 반복의 재귀적 구현 (비효율적)반복문으로 간단하게 해결할 수 있는 문제를 재귀 함수로 구현하는 것은 일반적으로 비효율적입니다. 재귀 호출은 콜 스택 공간 사용을 발생시키므로 단순 반복 작업은 for 문을 사용하는 것이 좋습니다.// 반복문 (효율적) public static int sum1(int n) { int total = 0; for (int i = 1; i <= n; i++) { total += i; } return total; } // 재귀 함수 (비효율적) public static int sum2(int n) { if (n == 1) { return 1; } return n + sum2(n - 1); } 패턴 2: 하위 문제 기반 문제 해결 (하향식 vs. 상향식)재귀는 하위 문제의 결과를 기반으로 현재 문제를 해결하는 데 특히 유용합니다. 대표적인 예가 팩토리얼 계산입니다.재귀함수를 이용한 팩토리얼 자바코드 예시public static int factorial(int n) { if (n == 0) { return 1; } return n * factorial(n - 1); }for문을 이용한 팩토리얼 자바코드 예시public static int factorial(int n) { int result = 1; for (int i = 1; i <= n; i++) { result *= i; } return result; } 재귀와 반복문재귀 함수는 상향식 계산도 가능하지만, 반복문으로 구현하는 것보다 성능이 좋지 않습니다.재귀 함수는 하향식 계산에서 위력을 발휘합니다. 특히 문제의 구조 자체가 재귀적인 경우 재귀 함수를 사용하면 코드를 간결하고 이해하기 쉽게 만들 수 있습니다. 재귀와 for문을 이용해 배열의 합 구현// 재귀 함수 public static int arraySum(int[] arr, int n) { if (n == 0) { return 0; } return arr[n - 1] + arraySum(arr, n - 1); } // 반복문 public static int arraySum(int[] arr) { int total = 0; for (int num : arr) { total += num; } return total; } 문자열 길이 계산 public static int strLength(String arr) { if (arr == null || arr.isEmpty()) { return 0; } return strLength(arr.substring(1)) + 1; } 지수 함수 하향식 구현public static int power(int x, int y) { if (y == 0) { return 1; } return x * power(x, y - 1); } 3일차컴파일과 프로세스, 재귀 - 하노이 탑 컴파일과 프로세스프로그래밍 언어의 종류프로그래밍 언어는 컴파일 언어와 인터프리터 언어로 구분할 수 있습니다.컴파일 언어개발자가 코드를 작성하고 컴파일이라는 과정을 거쳐 기계어(0과 1) 로 된 실행 파일을 생성합니다.컴파일 과정에서 문법 오류가 있는지 검사하고, CPU에서 실행할 수 있는 기계어로 변환합니다.미리 실행 파일을 만들어 놓으므로 실행 속도가 빠릅니다.예시: C, C++, C# 등인터프리터 언어개발자가 작성한 코드를 미리 기계어로 변환하지 않고, 실행 시점에 한 줄씩 해석하며 실행합니다.실행 전에 오류 검사를 하지 않기 때문에 실행 중 오류가 발생할 수 있으며, 속도도 컴파일 언어보다 느립니다.예시: JavaScript, Python 등 컴파일 언어로 작성된 파일이 프로세스가 되기까지C 언어로 작성된 test.c 파일이 실행 파일이 되고, 최종적으로 프로세스가 되는 과정1. 컴파일 과정전처리컴파일러가 실행되면 가장 먼저 전처리기가 동작합니다.전처리기는 #include, #define 등 전처리 구문을 처리합니다.주석 제거를 수행한 후 전처리된 코드를 .i 파일로 저장합니다.컴파일전처리된 코드를 기계어에 가까운 어셈블리어로 변환합니다.이 과정에서 문법 오류 체크도 함께 이루어집니다.결과물은 어셈블리 코드가 담긴 .s 파일입니다.어셈블어셈블리어를 기계어 코드(오브젝트 코드)로 변환합니다.생성된 오브젝트 파일은 .o 확장자를 가집니다.이 오브젝트 파일에는 코드 영역과 데이터 영역이 나눠져 있습니다.링커오브젝트 파일은 실행 파일이 되기 위해 링커(Linker) 를 거칩니다.링커는 여러 오브젝트 파일을 하나로 합치고, 코드 영역과 데이터 영역을 하나로 묶습니다. 결과물은 실행 파일(.exe)입니다. 2. 프로세스 생성 과정실행 파일이 프로세스가 되려면 다음 과정을 거칩니다프로그램 실행사용자가 .exe 파일을 실행합니다.운영체제가 프로세스를 생성합니다.메모리 할당운영체제는 실행 파일에 있는 코드 영역과 데이터 영역을 가져와 프로세스의 코드 영역과 데이터 영역에 로드합니다.그리고 빈 스택(Stack)과 힙(Heap) 영역도 할당합니다.PCB 생성운영체제는 PCB를 생성하여 프로세스를 관리합니다.PCB에는 프로세스 상태, 프로그램 카운터(PC), CPU 레지스터, 메모리 정보 등이 저장됩니다.프로그램 카운터 설정프로그램 카운터(PC) 는 다음 실행할 명령어의 주소를 가리킵니다.처음에는 코드 영역의 첫 번째 명령어의 주소를 가리킵니다.CPU 스케줄링운영체제의 CPU 스케줄러가 프로세스를 준비 상태에 놓고, CPU를 할당받으면 실행 상태로 전환되어 명령어가 실행됩니다. 재귀-하노이탑자바 코드 사용 예시 public static void hanoi(int count, String from, String to, String temp) { if (count == 0) { return; } hanoi(count - 1, from, temp, to); System.out.println(count + "를 " + from + "에서 " + to + "로 이동"); hanoi(count - 1, temp, to, from); } public static void main(String[] args) { hanoi(3, "A", "C", "B"); // 3은 옮겨야할 갯수 A는 시작위치 C는 도착해야할 위치 B는 거쳐갈 위치 }결과창4일차메모리 관리,버블정렬과 선택정렬 메모리의 종류레지스터가장 빠른 기억 장소로 CPU 내부에 존재합니다.컴퓨터의 전원이 꺼지면 데이터가 사라지므로 휘발성 메모리입니다.CPU의 32비트, 64비트는 레지스터 크기를 의미합니다.CPU는 연산 시 메인 메모리(RAM)에 있는 데이터를 레지스터로 가져와 계산하고, 결과를 다시 메인 메모리에 저장합니다. 캐시(Cache)레지스터와 메인 메모리 사이에 위치하여, 데이터 접근 속도를 향상시키는 역할을 합니다.CPU는 필요한 데이터를 메인 메모리에서 가져오기 전에 L1 캐시 → L2 캐시 → L3 캐시 순으로 확인합니다.캐시에 가져올 데이터가 없으면 메인 메모리에서 데이터를 가져옵니다. 메인 메모리(RAM) 실제 운영체제와 프로세스가 로드되는 공간입니다.휘발성 메모리로, 전원이 꺼지면 데이터가 사라집니다.속도는 HDD/SSD보다 빠르지만, 가격이 비싸기 때문에 실행 중인 프로그램만 저장합니다. HDD/SSD비휘발성 메모리로, 전원이 꺼져도 데이터가 보존됩니다.속도는 메인 메모리보다 느리지만, 가격이 저렴하여 데이터 저장 용도로 사용됩니다. 메모리 할당 방식메모리 오버레이:프로그램을 분할하여 필요한 부분만 메모리에 로드하고, 나머지는 스왑 영역에 저장합니다.스왑(Swap): 스왑영역에 있는 데이터를 메모리로 가져오고 메모리에 있는 데이터를 스왑영역으로 옮기는것을 말합니다.가변 분할 방식(Variable Partitioning)프로세스 크기에 따라 메모리를 연속된 공간에 동적으로 할당합니다.장점: 연속된 공간으로 할당하기 때문에 내부 단편화가 발생하지 않습니다.단점: 외부 단편화가 발생합니다.예시: 프로세스 A(50MB), B(30MB), C(15MB), D(10MB)가 메모리에 차례로 로드이후 A와 D가 종료되어 빈 공간(50MB + 10MB)이 생기고 새로운 프로세스 E(60MB)를 로드하려고 할 때 이 공간들은 연속되어 있지 않아 할당할 수 없는데 이를 외부 단편화라고 하며, 조각 모음을 통해 빈 공간들을 하나로 합쳐야 합니다. 이 과정은 메모리에 있는 프로세스를 일시 중지하고 공간을 이동시키는 작업이므로 오버헤드가 발생합니다. 고정 분할 방식(Fixed Partitioning)메모리를 고정 크기 블록으로 나눠 프로세스를 할당합니다.장점: 구현이 간단하고 오버헤드가 적습니다.단점: 프로세스 크기와 상관없이 고정된 크기로 메모리를 할당하므로 내부 단편화가 발생합니다.예시: 메모리를 2MB로 나눈다 가정할 때 프로세스 A(1MB), B(2MB), C(5MB)를 할당할 경우,A는 2MB 블록에 할당되어 1MB의 내부 단편화가 발생합니다. B는 2MB 블록에 할당되고 B는 2MB이기 때문에 정확히 떨어짐. C는 총 5MB이기 때문에 2MB 블록을 3개의 구역에 나눠서 저장해 1MB의 내부 단편화가 발생. 버디 시스템(Buddy System)가변 분할 방식과 고정 분할 방식을 혼합하여 단점을 보완합니다.메모리를 2의 제곱수 크기로 나누고, 필요할 때마다 나눠 프로세스를 할당합니다.장점: 외부 단편화를 방지하고, 메모리 합병(병합)이 간단합니다.단점: 약간의 내부 단편화가 발생할 수 있습니다. 그럼 메모리 할당 방식은 둘의 단점을 최소화한 버디 시스템이 최고인가??버디 시스템의 내부 단편화와 작은 크기의 블럭을 지나치게 나누면 생기는 메모리 관리 오버헤드가 커질수있어 최신 운영체제는 페이징 기법을 활용하거나, 세그멘테이션과 조합해서 사용페이징 기법 (Paging)정의:메인 메모리를 고정된 크기의 블록인**페이지 프레임(Page Frame)으로 나누고, 프로세스의 가상 메모리 공간도 동일한 크기의 **페이지(Page)로 나눕니다.프로세스의 페이지들은 메모리의 페이지 프레임에 비연속적으로 할당됩니다.페이지 프레임과 페이지란???페이지는 프로세스를 나눈 조각페이지 프레임은 메모리를 나눈 조각장점:외부 단편화가 발생하지 않습니다.메모리 관리가 단순해집니다.단점:내부 단편화가 발생할 수 있습니다. (마지막 페이지가 완전히 채워지지 않는 경우)예시:프로세스 A가 5KB이고, 페이지 크기가 2KB라면, A는 3개의 페이지로 나뉩니다.마지막 페이지는 1KB만 사용되고 1KB는 낭비되므로 내부 단편화가 발생합니다.추가 설명: 페이지 테이블을 사용하여 가상 주소를 물리 주소로 변환합니다.고정 분할 방식과 페이징 기법은 비슷하지만 고정 분할 방식은 메모리를 나눈 후 프로세스를 맞춰 넣는 방식이고,페이징은 프로세스를 나눈 후 메모리에 퍼즐처럼 넣는 방식 세그멘테이션 (Segmentation)정의:프로세스를 논리적인 의미 단위인 세그먼트(Segment)로 나누어 메모리에 로드합니다.세그먼트의 크기는 가변적입니다.장점:논리적으로 관련된 코드나 데이터가 한 곳에 모이므로 효율적입니다.프로그램의 구조를 반영하여 메모리를 관리할 수 있습니다.단점:외부 단편화가 발생할 수 있습니다.예시:프로그램이 코드(10KB), 데이터(5KB), 스택(8KB)으로 나뉜 경우, 각 부분이 독립적인 세그먼트로 관리됩니다.추가 설명:세그먼테이션은 프로그램의 논리적인 구조를 반영하여 메모리를 관리하는 데 유용합니다.최근에는 페이징과 함께 사용되어 메모리 보호 및 공유 기능을 강화합니다.요약:페이징은 메모리를 고정 크기로 나누어 관리하고, 세그멘테이션은 논리적인 단위로 나누어 관리합니다.페이징은 외부 단편화를 해결하고, 세그멘테이션은 프로그램의 논리적인 구조를 반영합니다.. 페이징 + 세그먼테이션을 사용하면 내부/외부 단편화가 완전히 사라지는 것은 아니지만, 각각의 단점을 최소화할 수 있습니다. 버블 정렬과 선택 정렬정렬 알고리즘은 데이터를 특정 순서로 나열하는 방법을 정의버블 정렬과 선택 정렬은 가장 기본적인 정렬 알고리즘으로 이해와 구현이 쉽지만 성능은 다소 아쉬움1. 버블 정렬 (Bubble Sort)원리:인접한 두 원소를 비교하여 순서가 맞지 않으면 교환하는 과정을 반복합니다. 예시:[4, 2, 3, 1] 배열을 정렬하는 과정:[2, 4, 3, 1] (4와 2 교환)[2, 3, 4, 1] (4와 3 교환)[2, 3, 1, 4] (4와 1 교환)위 과정을 반복하여 [1, 2, 3, 4] 완성성능:시간 복잡도: O(n²) - 데이터가 많아질수록 비교 횟수가 제곱으로 증가합니다.장단점:장점: 이해와 구현이 매우 쉽습니다.단점: 성능이 좋지 않아 대규모 데이터 처리에는 부적합합니다. 자바코드로 예시 구현 public static void bubble(int[] arr) { int n = arr.length; for (int i = 0; i < n - 1; i++) { // arr 배열의 길이에서 -1만큼만 반복 for (int j = 0; j < n - i - 1; j++) { if (arr[j] > arr[j + 1]) { // arr[j]번쨰 값이 arr[j]다음의 값보다 크다면 int temp = arr[j]; // 현재 arr[j]번째의 값을 저장해두고 arr[j] = arr[j + 1]; // arr[j]의 값을 arr[j] 다음의값으로 변경 arr[j + 1] = temp;// arr[j] 다음의값을 이전에 temp에 저장해둔 arr[j]값으로 변경 } } } } public static void main(String[] args) { int[] arr = {4, 2, 3, 1}; bubble(arr); for (int num : arr) { System.out.print(num + " "); } } 2. 선택 정렬 (Selection Sort)원리:배열에서 가장 작은 원소를 찾아 첫 번째 위치로 이동시키고, 다음으로 작은 원소를 찾아 두 번째 위치로 이동시키는 과정을 반복합니다.정렬되지 않은 부분에서 최소값을 선택하여 정렬된 부분의 마지막 위치로 이동시킵니다.예시:[4, 2, 1, 3] 배열을 정렬하는 과정:[1, 2, 4, 3] (최소값 1을 첫 번째 위치로 이동 기존에 있던 4는 1이있던 자리로 이동)[1, 2, 4, 3] (다음 최소값 2는 이미 정렬된 위치)[1, 2, 3, 4] (다음 최소값 3을 세 번째 위치로 이동)성능:시간 복잡도: O(n²) - 버블 정렬과 마찬가지로 성능이 좋지 않습니다.장단점:장점: 버블 정렬과 마찬가지로 이해와 구현이 쉽습니다.단점: 성능이 좋지 않아 대규모 데이터 처리에는 부적합합니다. 자바코드로 예시 구현 public static void selection(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { // 정렬되지 않은 부분의 첫 번째 원소를 최소값으로 가정 // 정렬된 부분은 반복에서 제거하기위해 사용 int minValueIndex = i; // 정렬되지 않은 부분에서 최소값을 찾음 for (int j = i + 1; j < arr.length; j++) { if (arr[j] < arr[minValueIndex]) {// arr[j]값이 arr[minValueIndex] 값보다 작을경우 minValueIndex = j; // 정렬할 인덱스 값을 넣어주고 } } // 최소값을 정렬되지 않은 부분의 첫 번째 원소와 교환 int temp = arr[i]; // 현재 arr[i]의 값을 temp에 저장 arr[i] = arr[minValueIndex]; // arr[i]의 값을 arr[minValueIndex] 변경 arr[minValueIndex] = temp; // arr[minValueIndex]값을 이전에 temp에 저장해둔 값으로 변경 } } public static void main(String[] args) { int[] arr = {4, 2, 1, 3}; selection(arr); System.out.print("실행 결과 :"); for (int num : arr) { System.out.print(num + " "); } } 정리버블 정렬과 선택 정렬은 기본적이지만 비효율적인 정렬 알고리즘입니다. 2주차 회고 잘한 점저번주에 다짐했던 그날그날 강의를 듣고 정리하는건 잘지켰고 확실히 그날 배운 내용을 바로바로 정리하니 저번주보다 죽은지식이 덜했습니다.저번주는 몰아서 정리하다보니 아 이거 뭐였지 하며 다시 찾아보고 하는 경우가 많았는데 현저히 줄어든게 느껴졌습니다. 아쉬운 점운영체제는 역시 여전히 어려웠습니다.아무래도 강의가 기본으로 쉽게 이해하려는데 초점이 맞춰져있다보니 아주 쉽게 동작원리를 알려주다보니 하나의 내용을 던져주고 궁금해서 그걸 가지고 파다보면 끝도없는 용어와 또 다른 내용이 튀어나와 역시 쉽지않았습니다.자료구조와 알고리즘은 재귀 버블정렬 등 해당 알고리즘의 개념을 이해만 한다면 코드로 녹여내는건 생각보다 어렵지않았고 오히려 정말 재밌게 공부했었습니다.이무래도 코드를 작성하면 시각적으로 결과가 바로바로 보여지다보니 좀더 흥미를 느꼈던거같습니다. 개선할 점이제 다음주가 마지막 주차인데 이번주 보다 공부 시간을 좀 더 늘리겠습니다. 목표이번주 역시 로드맵에 맞게 해당 강의 영상을 듣고 바로바로 발자국으로 내용 정리하기2주차에 투자한 공부시간보다 더 늘리기질문 더 많이하기