Swap memory(스왑 메모리)

- 실제 메모의 물리적인 메모리(RAM)이 가득 찬 경우, 운영체제가 사용하는 가상 메모리의 일부

- 운영체제에서 사용 가능한 메모리 보다 더 많은 메모리가 필요한 경우, 데이터 저장을 위한 버퍼 역할

 

 

 

Swapping

- 컴퓨터와 실제 메모리와 가상 메모리 간의 정보 교환이 이루어지는 것

- 현재 메모리에서 다른 저장공간(HDD or SSD)으로 옮겨진 후, 다시 돌아오는 식으로 메모리 교체가 이루어질 수 있다.

- swap-out : 메모리 공간에서 원하는 페이지를 디스크에서 내보내는 방법

- swap-in : 디스크에 있던 페이지를 메모리에 다시 read 하는 과정

 

 

성능 이슈

- 빈번한 Swapping은 디스크 I/O를 발생시키기 때문에 시스템 성능 저하가 일어날 수 있기 때문에 최대한 메모리 부족 상황을 방지하기

 

 

활용 예시

- Hibernation(최대 절전 모드) : 스왑 메모리는 현재 실행 중인 시스템 상태를 디스크에 저장하고 나중에 다시 불러올 수 있다.

- 해당 머신에서 실행해야 하는 애플리케이션이 더 많은 메모리를 요구할 때 스왑 메모리를 활용한다.

- 갑작스런 메모리 사용량을 RAM 대신 스왑 메모리로 완화할 수 있다. 

 

'CS > 운영체제' 카테고리의 다른 글

[운영체제] 운영체제 요약 정리  (0) 2023.07.09
[운영체제] 운영체제란?(Operating System, OS)  (0) 2022.07.04

신장 트리(Spanning Tree)

- 하나의 그래프가 있을 때, 모든 노드를 포함하면서 사이클이 존재하지 않는 그래프

 

신장 트리의 특징

1. 모든 노드를 포함

2. 사이클이 없음

3. 연결성 유지 : 그래프의 모든 노드를 연결


최소 신장 트리 (MST, Minimum Spanning Tree)

- 신장 트리에서 가중치의 합이 최소가 되는 신장 트리

- 알고리즘 종류 : 프림 알고리즘, 크루스칼 알고리즘

 

 

프림 알고리즘(Prim's Alogrithm)

- 시작 노드를 선택한다.

- 해당 노드와 가장 작은 가중치의 간선을 선택한다.

- 새로운 노드를 트리에 추가한다.

- 선택한 노드의 집합을 확장하면서 최소 신장 트리를 형성한다.

 

- 간선의 수가 적을 때 적합하다.

- Priority Queue 우선순위 큐 사용

- 시간 복잡도 : O(E log E) // E는 간선의 수

 

 

크루스칼 알고리즘(Kruskal's Alogrithm)

- 그래프의 간선을 가중치의 오름차순으로 정렬하고, 가장 작은 가중치부터 선택해서 최소 신장 트리를 구성한다.

- 사이클을 형성하지 않는 간선을 선택하면서 트리를 확장한다.

- 유니온 파인드(Union Find) 자료구조 사용으로, 사이클 여부 확인

 

- 그리디 알고리즘 사용

- 간선의 수가 많을 때 적합하다.

- 시간 복잡도 : O(E log V) // V는 노드의 수


[최소 신장 트리 알고리즘 예제]

백준 1414번

https://www.acmicpc.net/problem/1414

 

1414번: 불우이웃돕기

첫째 줄에 컴퓨터의 개수 N이 주어진다. 둘째 줄부터 랜선의 길이가 주어진다. i번째 줄의 j번째 문자가 0인 경우는 컴퓨터 i와 컴퓨터 j를 연결하는 랜선이 없음을 의미한다. 그 외의 경우는 랜선

www.acmicpc.net

- N 개의 컴퓨터가 서로 연결되어 있는 랜선 길이가 주어질 때

- 모든 컴퓨터가 서로 연결되도록 만들고, 랜선 길이가 최대 값이 되는 값을 출력

 

 

- 파이썬 코드

def find(parent, x):  # 특정 원소가 속한 집합 찾기
    if parent[x] != x:  # 루트 노드가 아니면, 루트 노드 찾을 때까지 재귀
        return find(parent, parent[x])
    return parent[x]


def union(parent, a, b):  # 두 원소가 속한 집합 합치기
    a = find(parent, a)
    b = find(parent, b)
    if a < b:  # 더 작은 번호가 부모 노드
        parent[b] = a
    else:
        parent[a] = b


n = int(input())  # 컴퓨터 개수
edges = []
result = 0
parent = [i for i in range(n + 1)]  # 부모 테이블 초기화

for i in range(n):
    s = input()

    for j in range(len(s)):
        cost = 0  # 0이면 그대로
        ch = s[j]
        if ch.islower():  # 소문자
            cost = ord(ch) - ord('a') + 1
        elif ch.isupper():
            cost = ord(ch) - ord('A') + 27
        edges.append((cost, i + 1, j + 1))
        result += cost  # 모든 비용 계산

edges.sort()  # cost 오름차순 정렬

for cost, a, b in edges:
    if cost == 0:
        continue
    if find(parent, a) != find(parent, b):  # 사이클 발생 하지 않는 경우에 MST 포함
        union(parent, a, b)
        # print(cost)
        result -= cost

flag = True
for i in range(1, n + 1):
    if find(parent, i) != 1:
        flag = False

if flag:
    print(result)
else:
    print(-1)

백준 10423번

https://www.acmicpc.net/problem/10423

 

10423번: 전기가 부족해

첫째 줄에는 도시의 개수 N(1 ≤ N ≤ 1,000)과 설치 가능한 케이블의 수 M(1 ≤ M ≤ 100,000)개, 발전소의 개수 K(1 ≤ K ≤ N)개가 주어진다. 둘째 줄에는 발전소가 설치된 도시의 번호가 주어진다. 셋째

www.acmicpc.net

- 도시의 개수 N

- 설치 가능한 케이블 수 M

- 발전소 개수 K

- 모든 도시에 전기를 공급할 수 있도록 연결되어 있고, 케이블 설치 최소 비용 구하기

- 발전소가 설치된 도시는 연결하지 않아도 된다.

 

 

- 파이썬 코드

def find(parent, x):
    if parent[x] != x:
        return find(parent, parent[x])
    return parent[x]


def union(parent, a, b):
    a = find(parent, a)
    b = find(parent, b)
    if a < b:
        parent[b] = a
    else:
        parent[a] = b


n, m, k = map(int, input().split())  # 도시 개수, 케이블 수, 발전소 개수
numbers = list(map(int, input().split()))  # 발전소 설치된 도시 번호
parent = [i for i in range(n + 1)]
edges = []
answer = 0

for num in numbers:  # 발전소 설치된 도시의 루트를 0 으로 초기화
    parent[num] = 0

for _ in range(m):
    u, v, w = map(int, input().split())  # u 도시와 v 도시 연결 비용 w
    edges.append((w, u, v))

edges.sort()

for cost, a, b in edges:
    if find(parent, a) != find(parent, b):  # 사이클이 아닌 경우에만 계산
        union(parent, a, b)
        answer += cost

print(answer)

📌 운영체제

  • 실행할 프로그램에 필요한 자원을 할당하고
  • 프로그램이 올바르게 실행되도록 돕는 프로그램
  • 동시다발적으로 생성, 실행, 삭제되는 다양한 프로세스를 관리한다.
    • 프로세스, 스레드, 프로세스 동기화, 교착 상태 해결
  • 자원 접근 및 할당
    • CPU(CPU 스케줄링), 메모리(페이징, 스와핑), 입출력장치

메모리 구조

  • 커널 영역(Kernel)
    • 운영체제의 핵심 영역
    • 커널 : 운영체제의 핵심 서비스를 담당하는 부분
    • 응용 프로그램이 자원에 접근하려면 운영체제에 도움을 요청(운영체제의 코드를 실행)해야 한다. -> 이중 모드로 구현
    • 시스템의 모든 것을 통제하기 때문에 사용자(유저 모드)가 직접 접근이 불가능하다.
    • 접근 시 system call(시스템 콜)을 통한 커널 모드 전환이 필요하다.
  • 유저 영역
    • 스택 영역, 힙 영역, 데이터 영역, 코드 영역
    • 코드 영역
      • 실행할 수 있는 코드, 기계어로 이루어진 명령어 저장
      • read-only, 데이터가 아닌 CPU가 실행할 명령어가 담기기에 쓰기 금지
    • 데이터 영역
      • 전역 변수와 정적 변수가 저장되는 영역
    • 힙 영역
      • 동적할당된 변수가 저장되는 영역, 프로그래머가 직접 할당 가능
      • 동적할당 : 프로그램이 실행되는 도중에 메모리를 할당하는 것. 동적할당에서 포인터가 저장되는 곳은 스택 영역이다. 메모리 사용 후, 동적할당 해제를 하지 않으면 메모리 누수(memory leak)가 발생할 수 있다.
    • 스택 영역
      • 함수 내에서 지역변수와 매개변수가 저장되는 영역
      • 스택 영역이 생성될 때(함수 실행) 필요한 크기만큼 만들어지고, 데이터 저장
      • 함수가 끝나면 스택 영역 소멸

이중 모드

  • CPU가 명령어를 실행하는 모드를 크게 사용자 모드, 커널 모드로 구분하는 방식
  • 사용자 모드
    • 운영체제 서비스를 제공받을 수 없는 실행 모드
    • 커널 영역의 코드를 실행할 수 없는 실행 모드
    • 자원 접근 불가능
  • 커널 모드
    • 운영체제의 서비스를 제공받을 수 있는 실행 모드
    • 자원 접근을 비롯한 모든 명령어 실행 가능
  • 시스템 호출(시스템 콜, system call)
    • 커널 모드로 전환하여 실행하기 위해 호출
    • 운영체제 서비스를 제공받기 위해 커널 모드로 전환하는 방법
    • 종류
      • 프로세스 관리 : fork(), exit(), waitpid()
      • 파일 관리 : open(), close(), read(), write()
      • 디렉터리 관리 : mkdir(), rmdir()
      • 파일 시스템 관리 : mount(), umount()

프로세스

  • 운영체제로부터 시스템 자원을 할당받는 작업의 단위
  • 메모리에 올라와 실행되고 있는 프로그램의 인스턴스
  • 동적인 개념으로 실행된 프로그램을 의미한다.
  • 프로세스 확인 방법
    • 윈도우 : 작업 관리자
    • 리눅스, macOS : ps 명령어
  • 포그라운드 프로세스(Foreground process)
    • 사용자가 볼 수 있는 공간에서 실행되는 프로세스
  • 백그라운드 프로세스(background process)
    • 사용자와 직접 상호작용이 가능한 프로세스
    • 사용자와 상호작용하지 않고 정해진 일만 수행하는 프로세스 -> 데몬(daemon), 서비스(service)

프로세스 제어 블록(PCB)

  • 모든 프로세스는 실행을 위해 CPU가 필요하다.
  • 하지만 CPU 자원은 한정되어 있기 떄문에, 프로세스들은 돌아가면서 한정된 시간만큼 CPU를 사용해야한다.
  • 프로세스를 관리하기 위해서 PCB 사용
  • 프로세스 관련 정보를 저장하는 자료구조
  • 대표적인 정보
    • 프로세스 ID(PID)
      • 특정 프로세스를 식별하기 위해 부여하는 고유 번호(ex. 학번, 사번)
    • 레지스터 값
      • 프로세스가 자신의 실행 차례가 오면, 이전에 사용한 레지스터 중간 값을 모두 복원한다.
      • 프로그램 카운터, 스택 포인터, ..
    • 프로세스 상태
      • 생성(create), 준비(ready), 실행(running), 대기(waiting), 완료(terminated)
    • CPU 스케줄링 정보
      • 우선 순위, 최종 실행 시각, CPU 점유 시간
      • 프로세스가 언제, 어떤 순서로 CPU를 할당 받을지에 대한 정보
    • 메모리 정보
      • 프로세스가 어느 주소에 저장되어 있는지에 대한 정보
      • 페이지 테이블 정보
    • 사용한 파일과 입출력장치 정보

문맥 교환(context switch)

  • A 프로세스에서 B 프로세스로 넘어 갈 때, 어떤 작업이 수행?
    • 기존 실행 프로세스가 지금까지의 중간 정보를 백업한다.
    • 중간 정보 : context(문맥)
    • 다음 차례가 왔을 때 실행을 재개하기 위해 저장하는 정보
  • 기존 실행 프로세스 문맥을 백업하고, 새로운 프로세스 실행을 위해 문맥을 복구하는 과정

프로세스 상태

  • 생성 상태(create)
    • 이제 막 메모리에 적재되어 PCB를 할당 받은 상태
    • 준비가 완료되면 준비 생태로
  • 준비 상태(ready)
    • 바로 실행 가능하지만, 순서를 기다리는 상태
  • 실행 상태(running)
    • CPU를 할당 받아 실행 중인 상태
    • 할당 시간을 모두 사용하면,(타이머 인터럽트 발생) 준비 상태로 이동
    • 실행 도중 입출력장치를 사용하면 입출력 작업이 끝날 때까지 대기 상태로
  • 대기 상태(waiting)
    • 프로세스가 실행 도중 입출력장치를 사용하는 경우
    • 입출력 작업이 끝나면 준비 상태로 이동
  • 종료 상태(terminated)
    • 프로세스가 종료된 상태
    • PCB 정리


스레드

  • 프로세스를 구성하는 실행 흐름의 단위
  • 하나의 프로세스는 하나 이상의 스레드를 가질 수 있다.
  • 단일 스레드 프로세스 : 실행 흐름 1개
  • 멀티 스레드 프로세스 : 실행 흐름 2개 이상, 여러 명령어 동시 실행 가능
  • 스레드의 구성 요소
    • 스레드 ID, 레지스터 값, 스택 등등
    • 실행에 필요한 최소한의 정보를 갖고 있다.
    • 같은 프로세스에 있는 스레드 끼리 자원을 공유할 수 있다.


 

프로세스 VS 스레드

- 프로세스는 메모리에 올라가는 프로그램으로 운영체제로부터 메모리, 주소 공간 등을 할당 받는다.

- 멀티 프로세스 환경에서는 메모리에 올라간 다양한 프로세스들이 CPU를 선점하며 진행된다.

- CPU 선점과정을 통해 PCB에 각각의 프로세스들이 실행되었던 정보들은 문맥 교환을 통해 저장된다.

- 스레드는 각 프로세스에서 실행 단위를 뜻한다. 하나의 프로세스에 여러 개의 스레드가 동작하는 것을 멀티 스레드라고 한다.

- 각각 스레드는 한 프로세스에서 힙 영역과 데이터 영역을 공유하고, 각 스레드마다 스택과 PC레지스터 값이 따로 존재한다.

- 멀티 스레드는 생성과 관리의 중복을 최소화하고, 멀티 프로세스에 비해 문맥 교환 비용이 낮다.

 

 

멀티 프로세스 vs 멀티 스레드

  • 멀티 프로세스의 프로세스는 자원을 서로 공유하지 않는다.
    • 프로세스 간 통신(IPC)으로, 프로세스 간에도 자원을 주고받을 수 있다.
  • 멀티 스레드에서는 하나의 프로세스 자원을 스레드가 서로 공유한다.

 

멀티 스레드

- 장점 : 여러 프로세스를 동시에 처리하던 일을 자원과 메모리 공유로 자원 소모에 대한 비용 절감

- 또한 프로세스의 문맥 교환과 다르게 캐시 메모리를 비울 필요가 없어 속도가 빠르다.

- 단점 : 여러 자원을 공유하기 때문에, 동기화 문제를 해결하기 위한 작업 필요

 

-> 멀티 프로세스도 다른 프로세스가 점유하고 있는 자원에 대해 접근할 때 동기화 문제가 발생할 수 있다.

- 문재 해결 : 임계 영역으로 동시 접근 방지 -> 세마포어, 뮤텍스

 


CPU 스케줄링

  • 운영체제가 프로세스들에게 공정하고 합리적으로 CPU 자원을 분배하는 것
  • 프로세스 우선순위(priority) 에 따라 프로세스 실행 순서가 정해진다.
  • 스케줄링 큐

선점(preemptive) 스케줄링

  • 프로세스가 CPU를 할당받아 실행 중이어도, 운영체제가 CPU의 사용권을 선점 가능
  • 처리 시간 예측이 어렵다.
  • 잦은 문맥 교환으로 오버헤드 발생 가능성이 있다.
  • CPU 사용 독점 문제를 막을 수 있다.
  • Interrupt, I/O or Event Completion, I/O or Event Wait, Exit

비선점(non-preemptive) 스케줄링

  • 프로세스가 CPU를 점유하고 있으면, 사용을 뺐을 수 없는 방식
  • 필요한 문맥 교환만 일어나기 때문에 오버헤드가 상대적으로 적다.
  • 처리 시간 예측이 쉽다.
  • I/O or Event wait, Exit

프로세스 상태 다이어그램

  • 승인(Admitted) : 프로세스 생성이 가능하여 승인된 상태
  • 스케줄러 디스패치(Scheduler dispatch) : 준비 상태에 있는 프로세스 중 하나를 선택하여 실행
  • 인터럽트(Interrupt) : 예외, 입출력, 이벤트 등이 발생해서 현재 실행 중인 프로세스를 준비 상태로 바꾸고, 해당 작업을 먼저 처리
  • 입출력 또는 이벤트 대기(I/O or event wait) : 실행 중인 프로세스가 입출력이나 이벤트를 처리해야 하는 경우, 입출력/이벤트가 모두 끝날 때 까지 대기 상태로 만드는 것
  • 입출력 또는 이벤트 완료(I/O or event completion) : 입출력/이벤트가 끝난 프로세스를 준비 상태로 전환하여 스케줄러에 의해 선택될 수 있도록 만드는 것

CPU 스케줄링 종류

  • 비선점 스케줄링
    1. FCFS(First Come First Served) 선입 선처리 스케줄링
      • 준비 큐에 삽입된 순서대로 처리하는 비선점 스케줄링
      • 먼저 CPU를 요청한 프로세스부터 CPU 할당
      • 실행 시간이 짧은 것이 뒤로 가면 평균 대기 시간이 길어진다.
    2. SJF(Shortest Job First) 최단 작업 우선 스케줄링
      • 수행 시간이 가장 짧다고 판단되는 작업을 먼저 수행
      • FCFS 보다 평균 대기 시간 감소, 짧은 작업에 유리하다.
  • 선점 스케줄링
    1. RR(Round Roubin) 라운드 로빈
      • FCFS + 타임 슬라이스(time slice) or Time Quantum
      • 타임 슬라이스 : 실행의 최소 단위 시간, 각 프로세스가 CPU를 사용할 수 있는 정해진 시간
      • 정해진 시간을 모두 사용해도, 프로세스가 완료되지 않으면 큐의 맨 뒤에 삽입(문맥 교환)
      • Time Quantum이 크면 FCFS와 같고, 작으면 문맥 교환이 잦아져서 오버헤드 발생
    2. SRT(Shortest Remaining Time) 최소 잔여 시간 우선 스케줄링
      • SJF + RR
      • 정해진 시간만큼 CPU를 사용하고, 다음으로 CPU를 사용할 프로세스를 남은 작업 시간이 가장 적은 프로세스를 선택한다.
    3. Priority Scheduling(우선순위 스케줄링)
      • 프로세스들에 우선순위를 부여하고, 우선순위 높은 프로세스부터 실행
      • 우선순위가 같은 프로세스들은 FCFS 스케줄링
      • 단점 : 우선 순위가 낮은 프로세스를 무한정 기다리는 기아(starvation) 현상
      • Aging 방법으로 기아 현상 해결이 가능하다.
      • Aging : 오랫동안 대시한 프로세스의 우선순위를 점차 높이는 방식
    4. Multilevel-Queue(다단계 큐)
      • 우선순위 스케줄링이 발전된 형태
      • 우선순위별로 준비 큐를 여러 개 사용하는 스케줄링 방식
      • 우선순위가 가장 높은 큐에 있는 프로세스를 먼저 처리하고, 가장 높은 큐가 비어 있으면 그 다음 우선순위 큐에 있는 프로세스를 처리한다.
      • 우선순위가 높은 큐는 작은 Time Quantum, 우선순위가 낮은 큐는 큰 Time Quantum
    5. Multilevel feedback queue(다단계 피드백 큐 스케줄링)
      • 큐 간의 이동이 가능한 다단계 큐 스케줄링
      • 자연스럽게 CPU 집중 프로세스의 우선순위는 상대적으로 낮아지고, 입출력 집중 프로세스의 우선순위는 높아진다.

동기화

  • 프로세스들의 수행 시기를 맞추는 것
  • 실행 순서 제어 : 프로세스를 올바른 순서대로 실행, reader writer problem
    • reader와 writer 프로세스는 아무렇게나 실행 되면 X
  • 상호 배제 : 동시 접근이 안되는 자원에 하나의 프로세스만 접근하게 하기, bank account problem
    • 한 번에 하나의 프로세스만 접근해야 하는 자원에 동시 접근을 피하기 위한 동기화
    • ex. 계좌에 입금할 때 현재 잔액 + 추가 금액
  • 공유 자원 : 여러 프로세스 혹은 스레드가 공유하는 자원
    • ex. 전역 변수, 파일, 입출력장치, 보조기억 장치 등등
  • 임계 구역 : 동시에 실행하면 문제가 발생하는 자원에 접근하는 코드 영역
    • ex. 총합 변수, 잔액 변수
  • 레이스 컨디션(race condition) : 임계 구역에 동시에 접근하면 자원의 일관성이 꺠지는 것

Race Condition

  • 공유 자원에 대해 여러 프로세스가 동시에 접근할 때, 결과값에 영향을 줄 수 있는 상태

동기화 기법

  • 뮤텍스 락, 세마포어, 모니터
  • 뮤텍스 락
    • 상호 배제를 위한 동기화 도구, key를 기반으로 상호 배제
    • 전역 변수 1개, 함수 2개로 구현
    • 자물쇠 역할 : 프로세스들이 공유하는 전역 변수 lock
    • 임계 구역을 잠그는 역할 : acquire 함수
    • 임계 구역의 잠금을 해제하는 역할 : release 함수
    • busy waiting(바쁜 대기) 적용 : 임계 구역이 잠겨 있는지 확인하는 작업을 무한으로 작동
  • 세마포어
    • 일반화된 방식의 동기화 도구
    • 공유 자원이 여러 개 있는 경우에도 적용 가능
    • 멀티프로그래밍 환경에서 공유 자원에 대한 접근을 제한하는 방법
    • 전역 변수 1개, 함수 2개로 구현
    • 전역 변수 S : 임계 구역에 진입할 수 있는 프로세스 개수를 나타내는 변수
    • wait 함수 : 임계구역에 들어가도 되는지, 기다려야 하는지 알려주는 함수
    • signal 함수 : 임계 구역 앞에서 기다리는 프로세스에 가도 된다는 신호를 주는 함수
    • busy waiting(바쁜 대기) 적용 : CPU 사이클 낭비의 단점
      • 계속 반복되는 연산으로 CPU 낭비
      • 해결 방법
        • 사용할 수 있는 자원이 없을 경우 대기 상태로 만든다. -> 해당 프로세스의 PCB를 대기 큐에 삽입
        • 사용할 수 있는 자원이 생겼을 경우 대기 큐의 프로세스를 준비 상태로 만든다. -> 해당 프로세스의 PCB를 대기 큐에서 꺼내 준비 큐에 삽입
wait() {
    while (S <= 0) // 임계 구역에 진입할 수 있는 프로세스 개수가 0 이하면
        ; // 사용 가능한 자원이 있는지 확인하고
    S--; // 임계 구역에 진입할 수 있는 프로세스 개수가 1개 이상이면 S 감소하고 임계 구역 진입
}

signal() {
    S++; // 임계 구역에서의 작업을 마치고 S 증가
        }

 


교착 상태(Dead lock)

  • 두 개 이상의 프로세스나 스레드가 서로 자원을 얻지 못해서 다음 처리를 하지 못하는 상태
  • 무한히 다음 자원을 기다리는 상태
  • 교착 상태 조건
    • 상호 배제 : 한 프로세스가 사용하는 자원을 다른 프로세스가 사용할 수 없는 상태
    • 점유와 대기 : 자원을 할당 받은 상태에서 다른 자원을 할당 받기를 기다리는 상태
    • 비선점 : 어떤 프로세스도 다른 프로세스의 자원을 강제로 빼앗지 못하는 상태
    • 원형 대기 : 프로세스들이 원의 형태로 자원을 대기하는 상태
  • 교착 상태 해결 방법
    • 예방(prevention) : 교착 상태가 발생하지 않도록 발생 조건 중 하나를 없애기
    • 회피(avoidance) : 예방보다 덜 엄격한 제약 조건으로 자원을 좀 더 효율적으로 사용할 수 있도록 해결
      • 은행원 알고리즘 : 프로세스가 자원을 요구할 때, 시스템은 자원을 할당한 후에도 안정 상태인지 사전에 검사하여 교착 상태 회피
    • 회복 : 교착 상태 발생을 인정하고 사후에 조치하는 방식
      • 선점을 통한 회복, 프로세스 강제 종료를 통한 회복
    • 무시 : 교착 상태를 해결할 때, 문맥 교환에 의한 오버헤드로 성능저하가 일어날 수 있어서 무시하는 방법

 

 

메모리 단편화

- 단편화(fragmentation) : 프로세스들이 메모리에 적재되고 해제되는 것이 반복되면, 프로세스들 사이에 사용 못하는 공간이 생긴다.

- 외부 단편화 : 메모리 공간 중 사용하지 못하게 되는 일부 물리 메모리 사이에 남는 공간들을 합쳤을 때 다른 프로세스를 할당할 수 있는 문제

- 내부 단편화 : 프로세스가 사용하는 메모리 공간 내에 사용하지 않는 부분

 

 

페이징

- 페이징 기법으로 논리 메모리는 물리 메모리에 저장될 때 연속되어 저장될 필요 없이 물리 메모리의 남는 프레임에 적절히 배치

- 페이지와 프레임을 대응하는 페이징 테이블 필요(paging table)

- 장점 : 외부 단편화를 해결

- 단점 : 내부 단편화 비중이 늘어난다.

 

 

세그멘테이션

- 페이징처럼 논리, 물리 메모리를 같은 크기의 블록이 아닌 서로 다른 크기의 논리적 단위인 세그먼트로 분할해서 할당

- 각 세그먼트는 연속적인 공간에 저장된다.

- mapping을 위한 segment table 필요

- 필요한 메모리 공간만큼 메모리를 할당하기 때문에 내부 단편화 문제는 없지만, 중간에 메모리를 해제하면 외부 단편화 발생

 

📌 컴퓨터구조

  • 참고 강의 : 혼자 공부하는 컴퓨터구조 + 운영체제

컴퓨터 구조 시작하기

  • 중요한 요소들 : 성능, 용량, 비용
  • 컴퓨터가 이해하는 정보 : 데이터, 언어

데이터

  • 숫자, 문자, 이미지, 동영상과 같은 정적인 정보
  • 컴퓨터는 0과 1로 이루어진 데이터만 이해할 수 있다.

명령어

  • 컴퓨터를 실질적으로 움직이는 정보
  • 데이터는 명령어를 위한 일종의 재료 ex. 명령어 : 1과 2를 더해라
    • 데이터 : 1, 2

컴퓨터의 4가지 핵심 요소

  • CPU, 메모리(주기억장치), 보조기억장치, 입출력장치
  • CPU, Central Processing Unit(중앙처리 장치)
    • 컴퓨터 시스템을 통제하고 프로그램의 연산을 실행하는 컴퓨터의 제어 장치
  • 메모리
    • 현재 실행되는 프로그램의 명령어와 데이터를 저장한다.
    • 메모리에 저장된 값을 효율적으로 접근하기 위해 주소(address) 개념 사용
    • RAM(Random Access Memory) : 휘발성, 작업 중인 파일을 한시적으로 저장한다. 전원이 차단되면 데이터가 사라진다. 일반적으로 메모리는 RAM을 지칭한다.
    • ROM(Read Only Memory) : 비휘발성, 컴퓨터에 지시사항을 영구하게 저장한다. 전원이 차단되어도 데이터가 사라지지 않는다.
  • 보조기억장치 : 주기억장치보다 느리지만, 데이터를 영구적으로 보관할 수 있는 장치
    • HHD(Hard Disk Driver), SSD(Solid State Driver)
    • 메모리는 실행할 정보를 저장하고, 보조기억장치는 보관할 정보를 저장한다.
  • 입출력장치 : 컴퓨터 외부에 연결되어 컴퓨터 내부와 정보를 교환할 수 있는 부품

 

  • 메인 보드(Main board)
    • 컴퓨터의 핵심 부품들을 연결한다.
    • 메인 보드의 부품들은 버스(bus)라는 통로를 이용해서 정보를 주고받을 수 있다.
  • 시스템 버스
    • 메인 메모리와 마이크로프로세서 사이 데이터를 전달하기 위해 사용되는 커넥터와 케이블로 구성된 통로
    • 컴퓨터 시스템의 주요 부품 사이에서 데이터와 제어 시그널을 위한 통신을 제공한다.
    • 구성 요소 : address bus(주소 버스), control bus(제어 버스), data bus(데이터 버스)
    • 주소 버스
      • CPU가 주기억 장치나 입출력 장치로 기억장치 주소를 전달하는 통로.
      • 단방향 버스(주소만 전달)
      • 물리적 주소를 찾는 목적으로 사용.
      • 모든 주소 버스는 bit 형태로 CPU 또는 DMA(Direct Memory Access)에 의해 사용
    • 제어 버스
      • CPU에 의해 사용되고, 컴퓨터 내에 포함된 장치들과의 통신에 사용된다.
      • 데이터 버스와 주소 버스를 제어하기 위해 제어 신호들을 전송하는 통로
      • 양방향 버스(읽기, 쓰기 동작 모두 수행)
    • 데이터 버스
      • 데이터 전달에 사용
      • 양방향 버스

CPU 구성 요소

  • ALU(Arithmetic and Logical Unit)
    • 산술논리연산장치
    • 사칙연산 같은 두 숫자의 산술 연산 계산
    • 배타적 논리합, 논리곱, 논리합 같은 논리 연산 계산
  • 제어 장치(Control Unit, CU)
    • 프로세서의 조작을 지시하는 CPU 의 한 요소
    • 제어 신호를 보내고, 명령어들을 읽고 해석, 데이터 처리를 위한 시퀀스를 결정
    • 제어 신호 : 메모리 읽기 or 메모리 쓰기
  • 레지스터(Register)
    • CPU 내부에 위치한 고속 메모리
    • 바로 사용할 수 있는 데이터를 담고 있는 영역
    • PC, Program Counter(프로그램 카운터)
      • 메모리에서 가져올 명령어의 주소
    • IR, Instruction Register(명령어 레지스터)
      • 해석할 명령어(메모리에서 방금 가져온 명령어)
    • MAR, Memory Address Register(메모리 주소 레지스터)
      • 메모리의 주소를 저장
    • MBR, Memory Buffer Register(메모리 버퍼 레지스터)
      • 메모리와 주고받을 값(데이터 명령어)
    • 플래그 레지스터
      • 연산 결과 또는 CPU 상태에 대한 부가적인 정보
    • 범용 레지스터
      • 다양하고 일반적인 상황에서 자유롭게 사용
      • EAX(Accumulator), EBX(Base), ECX(Counter), EDX(Data)...
    • 스택 포인터
      • 스택 주소 지정에 사용, 스택의 top
    • 베이스 레지스터
      • 기존 주소 지정에 사용

명령어 실행 예시

  • 제어 장치는 1번지의 명령어를 읽기 위해서 메모리에 읽기 제어 신호를 보낸다.

  • 메모리는 1번지에 있는 명령어를 CPU 에게 전달, 이 명령어는 레지스터에 전달된다.
  • 레지스터에 들어온 명령어를 제어장치가 해석한다.
  • 레지스터에 있는 명령어(3번지와 4번지를 더하기)에서 3번지와 4번지의 데이터를 얻기 위해 메모리에 메모리 읽기 제어 신호를 보낸다.

  • 메모리에서 3번지와 4번지의 데이터를 CPU 에게 전달, 각각 레지스터에 데이터가 저장된다.
  • ALU 에서 레지스터에 있는 데이터로 계산
  • 계산한 결과 값은 레지스터에 저장된다.
  • 명령어 실행 종료


데이터 표현

  • 정보(information) : 가공된 데이터를 의미한다. 어떤 사물에 대한 소식이나 자료
  • 데이터(data) : 가공되지 않은 데이터.
  • 정보 단위

  • 워드(word)
    • CPU 가 한 번에 처리할 수 있는 정보의 크기 단위
  • 이진법(Binary)
    • 0과 1로 수를 표현하는 방법
    • 숫자가 1을 넘어가는 시점에 자리
    • 2의 보수(음수 표현) : 모든 0과 1을 뒤집고 1을 더한다.
    • ex. 11(2) = 00(2) = 01(2)
    • 양수인지 음수인지 구분하는 방법? : CPU에 있는 레지스터인 플래그(flag)로 구분한다.
    • 접두어 : 0b

  • 16진법(Hexadecimal)
    • 십진법보다 이진수와의 변환이 간단해서 사용
    • 십진수 : 16 = 16진수 : 10
    • 접두어 : 0x


문자 집합(Character Set)

  • 컴퓨터가 이해할 수 있는 문자의 모음
  • 인코딩(Encoding) : 코드화 => 문자를 0, 1으로 이루어진 문자 코드로 변환
  • 디코딩(Decoding) : 코드 해석 => 0, 1으로 이루어진 문자 코드를 문자로 변환

아스키 코드(ASCII : American Standard Code for Information Interchange)

  • 알파벳, 아라비아 숫자, 일부 특수 문자 및 제어 문자
  • 정보 교환용 7비트 부호 체계
  • 8 비트 중 1비트는 오류 검출을 위해 사용되는 패리티 비트(Parity Bit)
  • 7 비트로 하나의 문자 표현 : 2^7 = 총 128개의 부호 사용

유니코드(Unicode)

  • 전 세계의 모든 문자 집합
  • 인코딩 방식 : utf-8, utf-16, utf-32

UTF-8

  • Unicode Transformation Format
  • 가변 길이 인코딩 : 한 글자가 1~4바이트 중 하나로 인코딩 될 수 있다.

고급 언어와 저급 언어

  • 고급 언어(High-Level Language)
    • 사람 중심 언어
    • 실행을 위한 번역이 필요하다.
    • 컴파일 언어, 인터프리터 언어
  • 저급 언어(Low-Level Language)
    • 기계 중심 언어
    • 빠른 실행 속도
    • 기계마다 다른 코드를 가진다.
    • 기게어(Machine Language) : 0과 1로 이루어진 언어
    • 어셈블리어(Assembly Language) : 0과 1로 이루어진 기계어를 읽기 편한 형태로 번역한 언어
      • push rbp, pop rbp, ret

컴파일 언어

  • 소스 코드(고급 언어) -> 컴파일러(컴파일) -> 목적 코드(저급 언어)
  • 소스코드를 모두 기게어로 변환하기 때문에 인터프리터보다 시간이 소요
  • 런타임 상황에서는 이미 모든 소스코드가 변환되어 있어 빠른 실행 가능
  • C, C++

인터프리터 언어

  • 소스코드 -> 인터프리터 -> 목적 코드
  • 기계어로 변환하는 과정에서 인터프리터에 의해 한 줄씩 해석, 실행한다.
  • Python, Ruby

명령어의 구조

  • 명령코드(Operation Code) : 명령어가 수행할 연산
  • 오퍼랜드(Operand) : 연산에 사용할 데이터 또는 데이터의 주소
  • 오퍼랜드는 1개도 없을 수도 있고, 여러 개를 가질 수도 있다.

  • 연산 코드의 종류
    • 데이터 전송
      • MOVE : 데이터를 옮겨라
      • STORE : 메모리에 저장해라
      • LOAD(FETCH) : 메모리에서 CPU로 데이터를 가져와라
      • PUSH : 스택에 데이터를 저장해라
      • POP : 스택의 최상단 데이터를 가져와라
    • 산술/논리 연산
      • ADD, SUBTRACT, MULTIPLY, DIVIDE : 사칙 연산
      • INCREMENT, DECREMENT : 오퍼랜드에 1 증감, 차감
      • AND, OR, NOT
      • COMPARE : 두 개의 숫자 또는 TRUE, FALSE 값을 비교해라
    • 제어 흐름 변경
      • JUMP : 특정 주소로 실행 순서 이동
      • CONDITIONAL JUMP : 조건에 부합하면 특정 주소로 실행 순서 이동
      • HALT : 프로그램의 실행 중지
      • CALL : 되돌아올 주소 저장, 특정 주소로 실행 순서 이동
      • RETURN : CALL을 호출할 때 저장한 주소로 리턴
    • 입출력 제어
      • READ(INPUT) : 특정 입출력 장치에서 데이터를 읽어라
      • WRITE(OUTPUT) : 특정 입출력 장치에서 데이터를 써라
      • START IO : 입출력 장치를 시작해라
      • TEST IO : 입출력 장치 상태를 확인해라

컴파일 과정

  • C 언어
    • test.c(소스 코드) -> 전처리기(preprocessor) -> 컴파일러(compiler) -> 어셈블러(assembler) -> 링커(linker) -> test.exe(실행 파일)

명령어 사이클

  • 프로그램 속 명령어들은 일정한 주기를 반복하면서 실행한다.
  • 이 주기를 명령어 사이클 이라고 한다.
  • 기본적인 명령어 사이클 : 인출 - 실행 - 인출 - 실행 ...
  • 추가적인 메모리 접근이 필요한 경우? : 간접 주소 방식을 사용해서 필요한 데이터를 가져온다.
  • 인터럽트(interrupt) : CPU 가 실행해야 하는 흐름을 멈추는 작업
  • 인출 사이클 -> 간접 사이클 -> 실행 사이클 -> 인터럽트 사이클

인터럽트(Interrupt)

  • 동기 인터럽트(예외) : CPU가 예기치 못한 상황을 접했을 때 발생
  • 비동기 인터럽트(하드웨어 인터럽트) : 주로 입출력장치에 의해 발생
    • 효율적인 명령어 처리를 위해 사용한다. 만약 사용하지 않는다면, 프린트 완료 여부 확인을 위해 주기적으로 확인해야 하는 비용이 발생한다.
    • ex. 세탁기 완료 알림, 전제레인지 조리 알림

클럭(Clock)

  • 컴퓨터의 부품들이 움직이는 시간 단위
  • 클럭 주기 : CPU의 클럭이 한 사이클에 걸리는 시간
  • 클럭 속도 : 헤르츠(Hz) 단위로 측정
  • 헤르츠(Hz) : 1초에 클럭이 반복되는 횟수
    • ex. 클럭이 1초에 100번에 반복되면 100Hz
  • 일반적으로 클럭 속도를 높이면 CPU 속도가 빨라지긴 하지만 과해지면 발열 발생
    • 다른 방법으로는 코어, 스레드 수를 증가시킨다.

코어(Core)

  • 명령어를 실행하는 부품
  • 멀티 코어 : 두 개 이상의 코어를 가지고 있는 CPU
  • 코어가 많다고 무조건 속도가 향상되는 것이 아니다.

스레드(Thread)

  • 프로그램 실행 흐름의 단위
  • 하드웨어적 스레드, 소프트웨어적 스레드가 있다.
  • 하드웨어워 스레드 : 하나의 코어가 동시에 처리하는 명령어 단위
  • 소프트웨어 스레드 : 하나의 프로그램에서 독립적으로 실행되는 단위

명령어 파이프라인

  1. 명령어 인출(Instruction Fetch)2
  2. 명령어 해석(Instruction Decode)
  3. 명령어 실행(Execute Instruction)
  4. 결과 저장(Write Back)
  • 같은 단계가 겹치지 않으면 각자 단계를 동시에 실행할 수 있다.
  • 동시에 여러 개의 명령어를 겹쳐 실행하는 기법이다.

<


명령어 집합

  • 명령어 집합(구조) : CPU가 이해할 수 있는 명령어들의 모음
  • 일반적으로 인텔의 CPU는 X86 명령어 집합, 애플의 CPU는 ARM 명령어 집합을 사용
  • CISC(Complex Instruction Set Computer)
    • CPU를 설계하는 방식
    • 복잡한 명령어 집합을 갖는 CPU 아키텍처
    • 가변 길이 명령어
    • 메모리를 아낄 때 사용했지만, 명령어 파이프라이닝이 불리하다.
  • RISC(Reduced Instrunction Set Computer)
    • CPU를 설계하는 방식
    • 간단하고 적은 종류의 명령어와 주소 지정 모드를 사용
    • 고정 길이 명령어
    • 메모리 접근 최소화, 레지스터 활용

저장 장치 계층 구조

  • CPU 와 가까운 저장 장치는 빠르고, 멀리 있는 저장 장치는 느리다.
  • 속도가 빠른 저장 장치는 저장 용량이 적고, 가격이 비싸다.
  • CPU 에 가까운 순서 : 레지스터 > 메모리(RAM) > USB
  • 캐시 메모리
    • CPU 와 메모리 사이에 위치
    • 레지스터보다 용량이 빠르고, 메모리보다 빠른 SRAM 기반 저장 장치
    • 메모리에 계속 접근하는 것 보다 일부 데이터를 캐시 메모리에서 저장해둔 뒤 사용
    • 캐시 메모리는 CPU(코어)에 위치 하거나 CPU와 메모리 사이에 위치
      • L1, L2 코어에 위치
      • L3 CPU와 메모리 사이에 위치
    • 멀티 코어 프로세서에서는 각 코어에 위치한 캐시 메모리가 다른 경우가 있기 때문에, 싱크를 맞춰주는 작업이 필요하다.
    • CPU가 자주 사용할 법한 메모리를 저장
      • 캐시 히트 : CPU가 캐시 메모리에 저장된 값을 활용(예측 성공)
      • 캐시 미스 : CPU가 메모리에 접근해야 하는 경우(예측 실패)
    • 참조 지역성의 원리
      • CPU가 최근에 접근했던 메모리 공간에 다시 접근하려는 경향
      • CPU가 접근한 메모리 공간 근처를 접근하려는 경향

정규 표현식(regular expression)

- 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어

- regexp, regex

 

 

정규 표현식 메타 문자(meta characters)

- 문자가 가진 뜻이 아닌 특별한 용도로 사용하는 문자

. ^ $ * + ? { } [ ] \ | ( )

 

문자 클래스(character class) [ ]

- [ ] 사이의 문자들과 매치

ex) [abc] = a, b, c 중에 한 개의 문자와 매치

- 문자 사이에 하이픈(-)을 사용하면 두 문자 사이의 범위가 된다.

ex) [a-c] = [abc], [0-5] = [012345]

- [a-zA-Z] 알파벳 전부

- [0-9] 숫자 

 

 

^ 메타 문자

- not 의미를 갖는다.

ex) [^0-9] = 숫자가 아닌 문자

 

 

자주 사용하는 문자 클래스

메타 문자 매치 같은 의미
\d 숫자 [0-9]
\D 숫자가 아닌 것 [^0-9]
\s whitespace 문자 [ \t\n\r\f\v]
\S whitespace 문자가 아닌 것 [^ \t\n\r\f\v]
\w 문자+숫자 [a-zA-Z0-9_]
\W 문자+숫자 [^a-zA-Z0-9_]

 

Dot(.) 메타문자

- \n 을 제외한 모든 문자와 매치

ex) a.b = a + 모든문자 + b

- aab, a0b는 정규식과 매치된다.

 

 

문자열을 앞이나 뒤에 매치할 때

- 맨 앞 : ^

ex) ^foo = foo + 아무거나

- 맨 뒤 : $ 

- 문자열이 $ 앞에 있는 문자로 끝나면 매치된다.

ex) abc$ = 아무거나 + abc

 

기호 의미
| or
[] [abc] = a, b, c 중에 하나를 포함
[^문자] [^ab] = a, b 제외
^문자열 ^abc = abc로 시작
문자열$ abc$ = abc로 끝남

 

 

반복 (*)

- 반복을 의미하는 메타 문자

- *은 *앞에 있는 문자가 무한대로 반복될 수 있다.

 

 

반복 (+)

- 최소 1번 이상 반복될 떄 사용한다.

 

정규식 문자열 매치
ca+t ct X
ca+t cat O

 

반복 ({m, n}, ?)

- 반복 횟수를 제한할 때 사용

- m부터 n까지 

ex) {3,} = 반복 횟수 3 이상

ex) {,3} = 반복 횟수 3 이하

 

 

? 메타 문자

- {0, 1} 을 의미한다.


정규 표현식을 지원하는 re 모듈

import re
p = re.compile('abc')

 

 

컴파일된 패턴 객체가 제공하는 메서드

method 목적
match() 문자열의 처음부터 정규식과 매치되는지 조사한다.
search() 문자열 전체를 검색해서 정규식과 매치되는지 조사한다.
findall() 정규식과 매치되는 모든 문자열(substring)을 리스트로 리턴한다.
finditer() 정규식과 매치되는 모든 문자열(substring)을 반복 가능한 객체로 리턴한다.

 

 

match

- 문자열의 처음부터 정규식과 매치되는지 조사한다.

- 처음부터 끝까지 전부 일치해야 하는경우 -> fullmatch 사용

# 패턴 만들기
import re
p = re.compile('[a-z]+')

# match 매치 확인
m = p.match('3 python')
print(m) # None : 3이 [a-z]+ 에 매치 되지 않는다

# search
m = p.match('3 python')
print(m) # <re.Match object; span=(2, 8), match='python'>
# search는 문자열을 전체를 검색하기 때문에 매치된다.

 

 

findall

result = p.findall("life is too short")
print(result) 
# ['life', 'is', 'too', 'short']
# [a-z]+ 와 매치되는 모든 값을 리스트로 리턴

 

 

finditer

result = p.finditer("life is too short")
print(result)
<callable_iterator object at 0x01F5E390>
for r in result: print(r)
...
<re.Match object; span=(0, 4), match='life'>
<re.Match object; span=(5, 7), match='is'>
<re.Match object; span=(8, 11), match='too'>
<re.Match object; span=(12, 17), match='short'>

match 객체의 메서드

method 목적
group() 매치된 문자열을 리턴한다.
start() 매치된 문자열의 시작 위치를 리턴한다.
end() 매치된 문자열의 끝 위치를 리턴한다.
span() 매치된 문자열의 (시작, 끝)에 해당하는 튜플을 리턴한다.

 

m = p.match("python")
m.group() # 'python'
m.start() # 0
m.end() # 6
m.span() # (0, 6)

 

문제 풀이

https://hhiyeon.tistory.com/245

 

[백준] 1264번 모음의 개수

https://www.acmicpc.net/problem/1264 1264번: 모음의 개수 입력은 여러 개의 테스트 케이스로 이루어져 있으며, 각 줄마다 영어 대소문자, ',', '.', '!', '?', 공백으로 이루어진 문장이 주어진다. 각 줄은 최대

hhiyeon.tistory.com

 

 

https://hhiyeon.tistory.com/246

 

[백준] 23627번 driip

https://www.acmicpc.net/problem/23627 23627번: driip 드립이가 생각하기에 주어진 문자열이 귀여우면 "cute", 그렇지 않으면 "not cute"를 출력한다. (따옴표 제외) www.acmicpc.net 백준 풀이 - driip 으로 끝나는 문자

hhiyeon.tistory.com

 

 

https://hhiyeon.tistory.com/247

 

[백준] 23303번 이 문제는 D2 입니다.

https://www.acmicpc.net/problem/23303 23303번: 이 문제는 D2 입니다. 문자열 안에 $D2$나 $d2$가 들어있다면 D2를 출력한다. 두 글자는 반드시 붙어있어야 하며, $D$/$d$와 $2$ 사이에 공백이 있어도 안 된다. 만약

hhiyeon.tistory.com

 

 

https://hhiyeon.tistory.com/248

 

[백준] 17413번 단어 뒤집기2

https://www.acmicpc.net/problem/17413 17413번: 단어 뒤집기 2 문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다. 먼저, 문자열 S는 아래와과 같은 규칙을 지킨다. 알파벳 소문자('a'-'z'), 숫자('

hhiyeon.tistory.com

 

 

https://hhiyeon.tistory.com/249

 

[백준] 15904번 UCPC는 무엇의 약자일까?

https://www.acmicpc.net/problem/15904 15904번: UCPC는 무엇의 약자일까? 첫 번째 줄에 알파벳 대소문자, 공백으로 구성된 문자열이 주어진다. 문자열의 길이는 최대 1,000자이다. 문자열의 맨 앞과 맨 끝에 공

hhiyeon.tistory.com

 

 

https://hhiyeon.tistory.com/250

 

[백준] 1543번 문서검색

https://www.acmicpc.net/problem/1543 1543번: 문서 검색 세준이는 영어로만 이루어진 어떤 문서를 검색하는 함수를 만들려고 한다. 이 함수는 어떤 단어가 총 몇 번 등장하는지 세려고 한다. 그러나, 세준

hhiyeon.tistory.com

 

 

 

https://hhiyeon.tistory.com/251

 

[백준] 9996번 한국이 그리울땐 서버에 접속하지

https://www.acmicpc.net/problem/9996 9996번: 한국이 그리울 땐 서버에 접속하지 총 N개의 줄에 걸쳐서, 입력으로 주어진 i번째 파일 이름이 패턴과 일치하면 "DA", 일치하지 않으면 "NE"를 출력한다. 참고로,

hhiyeon.tistory.com

 

동기(Synchronous) VS 비동기(Asynchronous)

  • 동기 : 함수A가 함수B의 작업 완료 후 리턴을 기다리거나, 작업의 완료(리턴)를 계속해서 확인하는 작업 흐름
  • 비동기 : 함수 A가 함수 B를 호출할 때 콜백 함수를 함께 전달하여 함수 B의 작업이 완료되면 함께 보낸 함수를 실행
    • 이전에 호출한 함수의 작업 완료 여부를 신경쓰지 않는 상황
    • call back이 오기 전까지 신경쓰지 않고 다른 일을 할 수 있다.
  • 호출되는 함수의 작업 완료 여부를 신경쓰냐, 함수 실행/리턴 순차적인 흐름을 따르는가

 

 

블로킹(blocking) vs 논블로킹(non-blocking)

  • 블로킹
    • A 함수가 B를 호출하면 제어권을 B 함수에게 넘겨짐
    • A에겐 제어권이 없기 떄문에 실행을 멈춤
    • B함수 실행이 끝나면 제어권을 다시 A가 받아서 실행
  • 논블로킹
    • A함수가 B함수를 호출해도 본인 행동의 제어권을 본인(A)이 가지고 있음
    • B 함수가 실행되지만 A는 B를 호출한 이후에도 자신의 코드를 계속 실행할 수 있다.

 

 

4가지의 조합적 동작의 차이

  • Sync - Blocking
    • 함수 A는 함수 B의 리턴값을 필요로한다. (동기)
    • 제어권을 함수 B 에게 제어권을 넘겨준다. (블로킹)
    • 함수 B가 실행을 완료하여 리턴값과 제어권을 돌려줄 때까지 기다린다. 
  • Sync - NonBlocking
    • A 함수는 B 함수를 호출한다.
    • 이 때 A 함수는 B 함수에게 제어권을 주지 않고 본인의 코드를 계속 실행한다 (논블로킹)
    • 하지만 A 함수는 B 함수의 리턴값이 필요하기 때문에, 계속 B 함수에게 함수 실행을 완료했는지 물어본다 (동기)
      • 대기 시간동안 다른 일 수행 가능
  • Async - Nonblocking
    • A 함수는 B 함수를 호출한다.
    • 이 때 제어권을 A는 계속 가지고 있어서 B 함수를 호출한 이후에도 멈추지 않고 자신의 코드를 계속 실행 (논블로킹)
    • B 함수를 호출할 때 콜백 함수를 같이 넘겨서 B 함수가 작업이 끝나면 콜백함수 실행을 통해 리턴 전달 (비동기)
  • Async - Blocking
    • A 함수는 B 함수를 호출
    • 제어권을 함수 B 에게 제어권을 넘겨준다. 제어권을 받기 전까지 기다린다. (블로킹)
    • B 함수를 호출할 때 콜백함수를 같이 넘겨서 B 함수가 작업이 끝나면 콜백함수 실행을 통해 리턴 전달 (비동기)
     

'CS > 네트워크' 카테고리의 다른 글

[네트워크] HTTP와 HTTPS, TCP & UDP, GET & POST, OSI 7 계층  (0) 2022.09.30

디자인 패턴

  • 객체지향 프로그래밍 설계를 할 때 자주 발생하는 문제들을 피하기 위해 사용하는 패턴
  • 목적
    • 재사용성, 호환성, 유지보수성
  • 원칙 - SOLID(객체지향 설계 원칙)
    • Single Reponsibility Principle(SRP) : 하나의 클래스는 하나의 동작만
    • Open - Close Principle : 확장(상속)에는 열려있고, 수정에는 닫기
    • Liskov Substitution Principle : 자식이 부모의 자리에 항상 교체될 수 있어야 한다.
    • Interface Segregation Principle : 인터페이스가 잘 분리되서, 클래스가 꼭 필요한 인터페이스만 구현하도록 제어
    • Dependency Inversion Property : 상위모듈이 하위 모듈에 의존적 X. 둘 다 추상화에 의존해야 한다.

 

디자인 패턴의 3가지 분류

1. 생성 패턴 : 객체의 생성 방식 결정

  • 싱글톤 패턴(Singleton)
    • 하나의 인스턴스만 사용할 수 있도록 객체를 생성하는 방법
    • 객체가 여러 번 생성되지 않고, 최초 하나의 인스턴스만 생성 후 이 인스턴스만 참조하게 된다.
    • 커넥션 풀, 스레드 풀, 디바이스 설정 객체 등의 경우 인스턴스를 여러 개 만들게 되면 자원을 낭비하게 된다.
    • 버그를 발생시킬 수 있는 위험으로 오직 하나만 생성하고 그 인스턴스를 사용하는 것이 목적

public class Singleton {
    private static Singleton singletonObject;

    private Singleton() {}

    public static Singleton getInstance() {
        if (singletonObject == null) {
            singletonObject = new Singleton();
        }
        return singletonObject;
    }
}
  • 멀티 스레드 환경에서는 싱글턴 패턴을 사용하다가 동시 접근을 해야 하는 상황이 생길 경우, 인스턴스가 두 개 생성될 위험이 잇다. synchronzied 사용
  • 동기화 사용 : 멀티 코어에서  하나의 CPU를 제외한 다른 CPU가 Lock에 걸릴 위험이 있다.
  • 사전 초기화 : 클래스 로딩 시점에 미리 객체를 생성하고, 그 객체를 반환한다.
    • volatile 키워드 사용 : 캐시에 저장된 값 X -> main memory 값 사용
    • 메모리 효율이냐 연산 효율은 사후 초기화보다 낮다.
public class Singleton {
    private static volatile Singleton singletonObject = new Singleton();

    private Singleton() {}

    public static Singleton getSingletonObject() {
        return singletonObject;
    }
}

 

 

  • 프로토타입 패턴(Prototype)
    • 기존의 인스턴스를 그대로 복제(clone)해서 새로운 객체를 생성하는 기법
    • 싱글톤과 반대의 개념
    • 데이터베이스에서 받아온 데이터 인스턴스를 하나 더 만들어야 하는 경우 사용

 

  • 팩토리 패턴(Factory)
    • 인스턴스를 만드는 공장(Factory)를 통해 객체를 생성하는 방법
    • 인스턴스를 직접 생성하지 않고, 객체 반환 함수를 (생성자 대신) 제공
    • 초기화 과정을 외부에서 보지 못하게 숨기고 반환 타입을 제어할 수 있다.
    • 비슷한 분류의 클래스들의 생성을 모아 처리하는게 편한 경우 사용

 

  • 추상 팩토리(Abstract Factory)
    • 공장을 만드는 상위 공장을 먼저 정의한다.
    • 많은 수의 연관된 서브 클래스를 특정 그룹으로 묶어 한 번에 교체할 수 있다.

 

  • 빌더(Builder)
    • 객체를 생성할 때 필요한 파라미터가 많은 경우, 인스턴스를 생성자를 통해 직접 생성하지 않고 빌더라는 내부 클래스로 간접적으로 생성하게 하는 패턴
    • 클래스와 사용 대상의 결합도를 낮추기 위해 사용
    • 생성자에 전달하는 인수에 의미를 부여하기 위해 사용

 

2. 구조 패턴 : 객체간의 관계를 조직

  • 어댑터 패턴(Adapter)
    • 서로 다른 클래스의 인터페이스를 연결하고자 사용하는 패턴
    • 인터페이스는 바뀌어도, 변경 내역은 어댑터에 캡슐화 되어 클라이언트는 바뀔 필요가 없다.
    • ex. 110V -> 220V 플러그

 

  • 컴포지트 패턴(Composite)
    • 객체의 hierarchies(계층) 표현
    • 각각의 객체를 독립적으로 동일한 인터페이스를 통해 처리할 수 있게 한다.
    • 여러 개의 클래스가 크게 보면 같은 요소(Component)에 속하지만, 여기에 속한 어떤 클래스(Composite)가 자신이나 다른 클래스(Leaf)를 가질 수 있는 구조
    • 트리 형태의 클래스
    • 데코레이터와 비교
      • 데코레이터 패턴 : 객체가 상황에 따라 다양한 기능이 추가되거나 삭제되어야 할 경우(크리스마스 트리 장식)
      • 공통점 : composition이 재귀적으로 발생
      • 차이점 : 데코레이터 패턴은 responsibilityes를 추가하는 것이 목적
        • composite 패턴은 계층구조를 표현하기 위해서 사용

 

  • 프록시(Proxy) 패턴
    • 연산을 스스로 객체가 직접 처리하는 것이 아니라, 숨겨진 객체를 통해 처리하는 방법
    • 구체적 업무 담당 클래스 접근 전에, 간단 사전 작업 처리 클래스(Proxy)를 두는 구조

 

 

3. 행위 패턴 : 객체의 행위를 조직, 관리, 연합

  • 스트레티지(Strategy) 패턴
    • 어떤 동작을 하는 로직을 정의하고, 이것들을 하나로 묶어(캡슐화) 관리하는 패턴
    • 새로운 로직을 추가하거나 변경할 때, 한 번에 효율적으로 변경이 가능하다.
    • 미사일 쏘기, 폭탄 사용 캡슐화
    • 전투기와 헬리콥터를 묶을 Unit 추상 클래스 생성
[ 슈팅 게임을 설계하시오 ]
유닛 종류 : 전투기, 헬리콥터
유닛들은 미사일을 발사할 수 있다.
전투기는 직선 미사일을, 헬리콥터는 유도 미사일을 발사한다.
필살기로는 폭탄이 있는데, 전투기에는 있고 헬리콥터에는 없다.

 

  • 템플릿 메소드(Template Method) 패턴
    • 로직을 단계 별로 나누어야 하는 상황에서 사용한다.
      • 상위 클래스가 뼈대
      • 하위 클래스가 각각 로직 구현
    • 단계별로 나눈 로직들이 앞으로 수정될 가능성이 있을 때 효율적이다.
    • 조건
      • 클래스는 추상 클래스로 만든다. -> 자식 클래스에서 선택적 메소드 오버라이딩 가능
        • abstract : 부모의 기능을 자식에서 확장시켜나가고 싶을 때
        • interface : 해당 클래스가 가진 함수의 기능을 활용하고 싶을 때
      • 단계를 진행하는 메소드는 수정이 불가능하도록 final 키워드 사용
      • 각 단계들은 외부는 막고, 자식들만 활용 가능하도록 protected 으로 선언
    • 예시 (반죽 -> 토핑 -> 굽기)
      •  피자 종류에 따라 토핑만 바꿔준다.

 

  • 옵저버(Observer) 패턴
    • 서로의 정보를 주고 받는 과정에서 단위가 크면, 객체 규모가 크면 복잡성 증가
    • 객체의 변경은 복잡한 코드에서 객체의 변경 추적을 어렵게 한다.
    • 객체의 변경을 추적하기 위해 옵저버 패턴을 사용하여 객체를 참조하는 모든 이들에게 변경 사실을 알리고 대처하는 추가 대응이 필요하다.
    • 인터페이스를 통해 연결하여 느슨한 결합성을 유지하고, Publisher와 Observer 인터페이스 적용

 

HTTP(HyperText Transfer Protocol)

  • HTTP -> TCP
  • 인터넷에서 클라이언트와 웹 서버가 자원을 주고 받을 때 사용하는 통신 규약
  • HTTP 1.1 : connection 당 하나의 요청 처리 -> 동시 전송의 문제
  • HTTP 2.0 : 서버로부터 여러 파일을 병렬적으로 전송하기 때문에, 속도 개선이 가능하다.
  • 클라이언트 요청과 서버의 응답에 필수 적인 정보인 ‘헤더’ 
    • 데이터 중복 전송을 방지
    • 데이터를 압축해서 전송하기 때문에 서버와의 통신으로 인해 발생하는 전송 트래픽을 절감할 수 있다.
  • 필요한 리소스를 클라이언트가 요청하기 전에 서버에서 먼저 전송할 수 있는 ‘서버푸시’ 기능도 새롭게 도입되어서 불필요한 통신 과정을 없앴다.
  • REST API는 HTTP 통신으로 이루어진다.
  • 단점
    • 통신 상대를 확인하지 않아서 모르는 사람에게서도 요청이 오면 무조건 응답을 한다.
    • 이를 보완하기 위해서 SSL 사용 -> SSL은 증명서를 이용해서 상대를 확인할 수 있다.

 

HTTPS(HyperText Transfer Protocol Secure)

  • HTTPS -> SSL -> TCP
  • 인터넷에서 정보를 암호화하는 SSL 프로토콜을 사용해서 클라이언트와 서버가 자원을 주고 받을 때 쓰는 통신 규악
    • SSL(Secure Socket Layer) or TLS(Transport Layer Security)
    • 암호화되지 않은 HTTP, 암호회된 HTTPS

  • 텍스트를 공개키 암호화 방식으로 암호화한다.
  • 통신 흐름
    • A 기업은 HTTPS을 적용하기 위해 공개키, 개인키 생성
    • 신뢰할 수 있는 CA 기업 선택 후, 공개키 관리를 부탁한다. (CA : Certifiacte Authority)
    • CA 기업은 공개키, 공개키 암호화 방법을 담은 인증서를 만들고, 인증서로 CA 기업의 개인키로 암호화해서 A 서버에게 제공
    • A 서버는 암호화된 인증서를 갖게된다. A 서버는 공개키로 암호화된 요청이 오면, 암호화된 인증서를 클라이언트에게 준다.
    • CA 기업의 공개키는 브라우저가 이미 알고 있기 때문에 브라우저는 암호화된 인증서를 해독하고 A 서버의 공개키를 얻게 된다.
    • A 서버와 통신할 때 얻은 A 서버의 공개키로 암호화해서 요청이 가능해진다.

 

대칭키(Symmetric Key)

  • 암호화와 복호화에 같은 암호키(대칭키)를 사용하는 알고리즘
  • 키를 하나만 사용하기 때문에 빠르다.
  • 하지만 해킹 위험이 있다.

 

공개키(Public Key), 비대칭키(Asymmetric Key)

  • 대칭키 키 분배 문제를 해결하기 위해 생긴 개념
  • 고유 암호키(비밀키)를 사용해서 복호화할 수 있는 암호키(공개키)를 공개해서 사용

 

SSL - 대칭키 + 공개키 암호화 방식

  • A가 웹 상에 공개된 B의 공개키로 암호화 통신에 사용할 대칭키를 암호화해서 B에게 보낸다.
  • B는 자신의 비밀키로 복호화 한다.
  • B는 A로부터 얻은 대칭키로 A에게 보낼 평문을 암호화해서 A에게 보낸다.
  • A는 자신의 대칭키로 암호문을 복호화한다.

TCP와 UDP

  • TCP(Transmission Control Protocol)
    • 신뢰성 있는 바이트 스트림 전송
    • 송신자와 수신자가 소켓이라고 부르는 종단점을 생성한다.
    • 3-way handshake 으로 연결 설정
    • 전이중(full-duplex), 점대점(point to point) 방식
    • 멀티캐스팅, 브로드캐스팅을 지원하지 않는다.
  • UDP(User Datagram Protocol)
    • 비연결형 프로토콜
    • 흐름제어, 오류제어 또는 손상된 세그먼트의 수신에 대해 재전송 X

 

GET과 POST

  • GET
    • HTTP Request Message의 Header에 URL이 담겨서 전송
    • query string : ? 뒤에 데이터가 붙어 request
    • 제한적인 크기
    • URL에 데이터가 노출된다.
  • POST
    • HTTP Request Message의 Body에 데이터가 담겨서 전송
    • 보안이 필요한 데이터는 POST가 더 낫다. -> 패킷 스니핑 위험으로 완전하지는 않다.

OSI 7 계층

 

1. 물리(physical)

- 리피터, 케이블, 허브

- 전기적인 신호로 변환해서 주고받는 기능을 진행하는 공간

- 데이터의 전송

 

2. 데이터 링크(Data link)

- 브릿지, 스위치

- 물리 계층으로 송수신되는 정보를 관리해서 안전하게 전달되도록 도와주는 역할

- MAC 주소로 통신

- 흐름제어, 에러검출, 재전송

 

3. 네트워크(Network)
- 라우터, IP

- 데이터를 목적지까지 가장 안전하고 빠르게 전달하는 기능 담당

- 라우터를 통해 이동할 경로를 선택하여 IP 주소를 지정하고, 해당 경로에 따라 패킷 전달

- 라우팅, 흐름제어, 오류제어, 세그멘테이션

 

4. 전송(Transport)

- TCP, UDP

- 프로토콜을 통해 통신 활성화. 프로그램들이 전송을 할 수 있도록 제공

- TCP : 신뢰성, 연결지향적

- UDP : 비신뢰성, 비연결성, 실시간

 

5. 세션(Session)

- API, Socket

- 데이터가 통신하기 위한 논리적 연결 담당

 

6. 표현(Presentation)

- JPEG, MPEG

- 데이터 표현에 대한 독립성을 제공하고 암호화하는 역할

- 파일 인코딩, 명령어 포장, 압축, 암호하ㅗ

 

7. 응용(Application)

- HTTP, FTP, DNS

- 응용 프로세스와 직접 관계하여 일반적인 응용 서비스를 수행

- 사용자 인터페이스, 전자우편, 데이터베이스 관리 등의 서비스 제공

'CS > 네트워크' 카테고리의 다른 글

[네트워크] 동기 vs 비동기, 블로킹 vs 논블로킹  (0) 2022.10.04

+ Recent posts