![[인프런 워밍업 클럽 스터디 3기] CS - 2주차 발자국](https://cdn.inflearn.com/public/files/blogs/5d57d2a3-90bf-4d31-87ab-88749b1717e1/1-01c09616.jpg) 
    [인프런 워밍업 클럽 스터디 3기] CS - 2주차 발자국
학습 내용
운영체제
- 프로세스 동기화 - 컴퓨터 내 프로세스 간 통신 - 동일 프로세스 내 통신: 운영체제가 생성한 파이프로 데이터를 읽고 씀 
- 스레드 간 통신: 데이터 영역이나 힙 영역 사용 시 통신 가능 
 
- 동일 네트워크 내 프로세스 간 통신 - 소켓 통신, RPC(원격 프로시저 호출) 
 
 
- 공유 자원: 프로세스 통신 시 공동으로 이용하는 변수나 파일 
- 임계구역 (Critical Section): 여러 프로세스가 동시에 사용하는 영역 - 해결책: 상호 배제의 매커니즘 
 
- 경쟁 조건 (Race Condition): 공유 자원을 서로 사용하기 위해 경쟁하는 것 
- 상호 배제의 요구사항 - 임계 영역에는 동시에 하나의 프로세스만 접근 
- 여러 요청에도 하나의 프로세스의 접근만 허용 
- 임 영역에 들어간 프로세스는 빠르게 나와야함. 
 
- 세마포어 - 공유자원이 하나 이상일 때 처리하는 동기화 방법 
- 예) 프린터 실을 예시로 들때 - 직원: 프로세스 
- 기존 프린터: 공유자원 
- 프린터실: 임계구역 
- 대기줄: 대기큐 
- 열쇠 관리자: 운영체제 
- 열쇠: 세마포어 
 
- 자바스크립트는 멀티 스레드 환경이 아니라서 비동기 코드에서 적용할 수 있음 
 
- 모니터: - 세마포어의 단점을 해결한 상호배제 매커니즘 
- 교착 상태 (데드락) - 여러 프로세스가 서로 다른 프로세스의 작업을 기다리다가 아무도 작업을 진행하지 못하는 상태 
- 필요 조건 ( - 모두 충족 시 교착 상태 발생) - 상호 배제: A가 리소스 점유 시 B에게 공유될 수 없음 (즉, 한 번에 하나의 프로세스만 특정 자원을 사용할 수 있음) 
- 비선점: A 프로세스는 B가 점유한 리소스를 뺏을 수 없음 
- 점유와 대기: 리소스 A를 가지고 있는 상태에서 리소스 B를 원하는 상태 (무한정 대기) 
- 원형 대기: 점유와 대기를 하는 프로세스가 원형을 이룸 (서로 교차해서 자원을 기다리고 있는 상태, 모든 프로세스가 영원히 자원을 획득할 수 없음) 
 
- 회피 방법 - 은행원 알고리즘: 교착 상태를 피하기 위해 상태 확인 뒤 실행 - 안정 상태: 자원 요청을 했으나 사용 가능한 자원이 더 적을 경우 요청 거부 
- 불안정 상태: 모든 프로세스에 자원을 공급할 수 없는 경우 
 
- 교착상태 검출 - 가벼운 교착 상태 검출: 일정시간동안 작업하지 않을 시 교착 상태 발생으로 간주 - 과정: 일정 시간마다 체크포인트 생성 -> 작업 저장 -> 타임 아웃으로 교착 상태 발생 시 마지막 지점으로 롤백 
 
- 무거운 교착 상태 검출: 운영체제가 자원 사용 여부를 지켜보고 교착 상태 발생 시 해결 - 과정: 자원 할당 그래프 사용 -> 교착 상태 발생 시 순환 구조 형성 -> 교착 상태 해결을 위해 순환 구조 단절 -> 해결 후 재실행 시 체크포인트 롤백 
 
 
 
 
- 컴파일 과정: 문법 오류 확인, CPU에서 처리 가능한 기계어로 실행 파일 생성 => 속도 빠름 - 대표 언어: C, C++, C# 
 
- 인터프리터 과정: 코드를 한 줄씩 해석 후 변환 (미리 검사하지 않음) => 속도 느림, 오류 발생 가능성 높음 - 대표 언어: JavaScript, Python, Ruby 
 - 1. - test.c→ 전처리기 → 전처리 구문 처리 →- test.i→ 컴파일러로 어셈블리어로 변환 →- test.s→ 어셈블러로 오브젝트 파일 변환 →- test.o→ 링커에서 실행 파일로 생성 →- test.exe
 2.- test.exe프로그램 실행 → 운영체제가 프로세스 생성 → PCB 생성 → 프로그램 카운터를 코드 영역의 첫번째 주소로 설정 → CPU 스케줄링에 따라 프로세스 실행 → 종료
- 메모리 종류: 레지스터, 캐시, 메인메모리(RAM), 보조저장장치(HDD, SSD) 
- 레지스터 - 가장 빠른 기억장소, CPU 내 존재, 휘발성 메모리, 빠름 
- RAM의 값을 레지스터로 가져와서 계산 -> 계산 결과는 다시 RAM에 저장 
 
- 캐시 - 레지스터에서 쓸 법한 데이터를 RAM에서 미리 가져와서 저장, 사용 완료 후 다시 RAM에 저장 
 
- 보조 저장장치: 가격 저렴, 비휘발성 메모리 
휘발성 메모리: 전원 공급이 없으면 데이터가 사라짐
비휘발성 메모리: 전원 공급이 없어도 데이터가 사라지지 않음
- 메인 메모리 RAM - 운영체제에 프로세스가 올라가는 공간, 휘발성 메모리, 가격 비쌈 
- 멀티 프로그래밍 환경에서 여러 프로그램을 올리다 보니 복잡해짐 
- 운영체제는 메모리 관리를 위해 1바이트 구역으로 나누고 숫자(주소)를 매김 
- 32bit 메모리 - 레지스터 크기, 산술논리연산장치, 데이터 이동 버스 === 32bit 
- 가능한 메모리: 2³² ⇒ 4GB 
 
- 64bit 메모리 - 레지스터 크기, 산술논리연산장치, 데이터 이동 버스 === 64bit 
- 가능한 메모리: 2⁶⁴ ⇒ 거의 무한대 
- 32bit에 비해 한 번에 처리할 수 있는 양이 많음 → 속도가 더 빠름 
 
- 물리주소 공간(절대 주소): 0x0번지부터 시작하는 주소공간 - 메모리 관리자가 바라본 실제 주소 
 
- 논리 주소 공간(상대 주소): 사용자 관점에서 바라본 주소, 물리주소를 몰라도 접근 가능 - 메모리 어디선가 실행되겠지~~하고 컴파일러는 0번지에서 실행한다고 가정하고 컴파일함 
 
- 경계 레지스터: 하드웨어적으로 운영체제 공간과 사용자 공간 분리 - CPU 내 존재 
- 사용자 프로세스가 경계 레지스터의 값을 벗어났는지 감시 (메모리 관리자) 
- 벗어났을 경우 프로세스 종료 
 
 
- 유니 프로그래밍에서의 메모리 분리 - 당장 실행해야하는 부분만 잘라서 메모리에 올리고 나머지는 하드디스크의 스왑 영역에 저장 
- 스왑: 스왑영역에 있는 데이터 일부를 메모리로 가져오고 메모리에 있는 데이터를 스왑영역으로 이동 
 
- 멀티 프로그래밍에서의 메모리 분리 - 가변 분할 방식 (Segmentation) - 프로세스의 크기에 따라 메모리를 나누는 방식 
- 연속 메모리 할당: 프로세스가 연속된 메모리 공간에 할당 
- 장점: 낭비 공간인 내부 단편화가 없음 
- 단점: 외부 단편화 발생 
 
- 고정 분할 방식 (Paging) - 메모리를 정해진 크기로 나누는 방식 
- 예) 고정 크기가 2MB인 경우 5MB인 프로세스는 2MB + 2MB + 1MB + 낭비 공간 1MB 
- 비연속 메모리 할당: 프로세스가 여러 개로 쪼개어 여러 곳에 할당됨 
- 장점: 구현 간단, 오버헤드 적음 
- 단점: 낭비 공간 내부 단편화 발생 
 
 - 현대 운영체제는 가변 분할 방식과 고정 분할 방식을 혼합함 
- 외부 단편화 - 메모리의 공간보다 프로세스의 크기가 더 큰 경우 
- 해결책: 조각 모음 - 단점: 현재 사용 중인 프로세스 전체 일시 중지, 메모리 공간을 이동시키는 작업을 해야함 ⇒ 오버헤드 발생 
 
 
- 내부 단편화 - 메모리 공간보다 프로세스의 크기가 더 작은 경우 
- 해결책: 없음 
 
- 버디 시스템: 2의 승수로 메모리 분할 및 할당 - 방법 - 2의 승수로 프로세스 크기보다 작은 값이 나올때 까지 분리 (예: 1024 - 1024(512 - 512(256 - 256))) 
- 비슷한 크기의 프로세스에 할당 (예: 512byte에 할당 (내부 단편화가 적게 발생, 실행이 끝나고 근접한 메모리와 합치기 쉬움)) 
 
- 2의 승수로 분할했기 때문에 조립만 하면 큰 공간이 만들어짐 (조각모음보다 간단함) 
- 장점 - 가변 분할: 프로세스 크기에 따라 할당되는 메모리 크기가 다름 
- 외부 단편화 방지를 위해 메모리 공간 확보가 간단함 
- 내부 단편화가 발생하나 많은 공간이 낭비되지 않음 
 
 
자료구조 & 알고리즘
- 재귀 함수: 자기 자신을 호출하여 문제를 해결하는 함수 - 필수: 기저 조건 - 기저 조건이 없으면 반복되는 출력으로 호출 스택의 메모리 공간이 가득 차서 자동으로 종료됨 
 
- 기본 패턴 - 단순 반복 계산 (예: 누적합, 누적곱, DFS 등) 
- 하위 문제의 결과를 기반으로 현재 문제 계산 (예: 팩토리얼, 피보나치 등) 
 
- 상향식 계산: for문, 재귀 함수 
- 하향식 계산: 재귀 함수만 가능 
 
- 호출 스택 - 함수가 호출되면서 올라가는 메모리 영역, FILO 
- 재귀함수는 모든 호출이 콜 스택에 올라가고 for문은 1개만 올라감 
 
- 예) 팩토리얼 
function factorial(number) {
  if (number <= 1) return 1;
  return number * factorial(number - 1)
}
console.log(factorial(4))  // 4 * 3 * 2 * 1- 예) 모든 원소의 합 
function sumArray(arr){
  if (arr.length == 1) return arr[0];
  return sumArray(arr.slice(0, -1)) + arr[arr.length - 1]
}
const arr = [1,2,3,4,5]
const sum = sumArray(arr);
console.log(sum)- 예) 하노이 탑 
규칙
1. 한 번에 하나의 원반을 움직일 수 있다.
2. 가장 위에 있는 원반만 옮길 수 있다
3. 아래에 작은 원반이 올 수 있다.
function hanoi(count, start, target, tmp) {
  if (count === 0) return;
  hanoi(count - 1, start, tmp, target)
  hanoi(count - 1, tmp, target, start)
}
hanoi(3, 'A', 'C', 'B')1. count - 1개의 작은 원반을 start → tmp로 옮긴다. (임시: target)
2. 가장 큰 원반을 start → target으로 옮긴다.
3. count - 1개의 작은 원반을 tmp → target으로 옮긴다 (임시: start)
4. 이전 과정을 반복하며 모든 원반을 start에서 target으로 옮긴다.
5. 모든 원반을 옮겨 count가 0이 되면 재귀를 종료한다.
- 버블 정렬 - 장점: 구현하기 쉬움 
- 단점: 성능이 좋지 않음 
- 방법: 근접한 두 개의 숫자를 비교하여 정렬되어있지 않다면 오름차/내림차 순으로 정렬한다. 
- 시간 복잡도: O(n²) 
 
- 버블 정렬 구현 
function bubbleSort(arr) {
  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = 0; j < arr.length - i - 1; j++) {
      if (arr[j] > arr[j + 1]) {
        let temp = arr[j]
    	arr[j] = arr[j + 1]
    	arr[j + 1] = temp
      }
    }
  }
}
const arr = [4, 2, 3, 1]
// ===== 정렬 전 =====
console.log(arr)
// ==== 정렬 후 =====
console.log(bubbleSort(arr)- 선택 정렬 - 장점: 구현하기 쉬움 
- 단점: 성능이 좋지 않음 
- 방법: 정렬되지 않은 영역의 첫번째 원소와 가장 작은 값의 위치 교환 
- 시간 복잡도: O(n²) 
 
- 선택 정렬 구현 
function selectionSort(arr) {
  for (let i = 0; i < arr.length - 1; i++) {
    let minValueIndex = i
	  
    for (let j = i + 1; j < arr.length; j++) {
      if (arr[j] < arr[minValueIndex]) {
        minValueIndex = j
      }
    }
		
    let temp = arr[i]
    arr[i] = arr[minValueIndex]
    arr[minValueIndex] = temp;
  }
}
회고
- Keep - 시간표에 따라 매일 CS 지식을 학습했다. 뿌듯 
- 나머지 한 주를 잘 마무리하면 좋겠다. 
 
- Problem - 없다 
 
- Try - 재귀를 구현할 때 더 작은 문제로 나누는 연습을 해야할 것 같다. 기저 조건과 점화식은 바로 이해되는데 나머지가 약간 알쏭달쏭하다. 
 
댓글을 작성해보세요.
