기록물 저장소/활동

[SW 마에스트로] 면접 대비 CS의 이론과 예상 질문

모영이 2021. 3. 20. 23:17

아래의 사이트의 정리된 내용을 정리했습니다. 후에 정보가 추가되면 출처를 밝히도록 노력하겠습니다. 누락된 출처가 있고 정보가 섞여서 정리 될 수 있습니다. CS는 처음 공부해봅니다. 자료구조는 학교에서 배운적이 있습니다만, 군생활을 하며 기억이 사라졌습니다.

CS전체 내용

MVC패턴 추가설명1

Restfil API 추가설명1

객체 지향 프로그래밍 추가설명1 opentutorials

객체 지향 프로그래밍 추가설명2 jeong-pro

함수형 프로그래밍 추가설명1 delmasong

네트워크 추가설명1

DNS Round Robin추가설명1

프로세스와 스레드 추가설명1

스케줄러 추가설명1 jhnyang

동기와 비동기 추가설명1 k39335

인덱스 추가설명1 mangkyu

정규화 추가설명1 yaboong

트랜잭션 추가설명1

 

 

Development common sense

좋은 코드란 무엇인가?

읽기 쉬운 코드
코드를 읽었을 때, 이해도 쉽게 되어야 한다. 주석을 다는 것은 중요하지만 과하게 달면 안된다
테스트가 용이한 코드
백문이 불여일견. 코드상으로 이해하는것은 복잡하고 어려울 수 있지만, 실제 테스트 결과를 보면 바로 이해되는 경우가 존재한다.
중복이 없는 코드
함수를 업데이트해야할때, 기존의 코드를 남겨두고 수정하다보면 중복이 발생한다. 쓰이지 않는 코드는 맨 밑으로 빼서 남겨두면 물리적 거리로 쓰이지 않는 것을 확신할 수 있다.
일관성 있는 코드
네이밍과, 디렉토리를 일관성 있게 해주면 변수명, 함수명만 보고 역할을 파악하기가 쉽다. 디렉토리는 이제 프로젝트 범위가 커졌을 때를 생각하고 구성해야한다.
확장성 있는 코드
확장이 어려운 코드는 내부에서 많은 변경이 발생하며 이것은 코드를 읽기 어렵게 만든다

객체 지향 프로그래밍이란 무엇인가? 

객체 : 로직을 상태(state)와 행위(behave)로 이루어진 구조. 변수와 메소드를 그룹핑한 것이다.

추상화 : 복잡함 속에서 필요한 관점만을 추출하는 행위. (지하철 노선도)

캡슐화 : 코드의 재사용성을 높이기 위해 기능과 특성의 모음을 클래스라는 캡슐에 분류해서 넣는 것.

은닉화 : 내부의 동작 방법을 단단한 케이스 안으로 숨긴다.

다형성 : 하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것.

 

객체 지향적 설계 원칙
SRP :
단일 책임 원칙
클래스는 단 하나의 책임을 가져야 하며 클래스를 변경하는 이유는 단 하나의 이유이어야 한다.
OCP :
개방-폐쇄 원칙
확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.
LSP :
리스코프 치환 원칙
상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
ISP :
인터페이스 분리 원칙
인터페이스는 그 인터페이스를 사용하는 클라이언트를 기준으로 분리해야 한다.
DIP :
의존 역전 원칙
고수준 모듈은 저수준 모듈의 구현에 의존해서는 안된다.

RESTFul API 란?

REST란 어떤 자원에 대해 CRUD연산을 수행하기 위해 URL로 요청을 보내는 것. 요청을 위한 Resource(자원, URI)와 이에 대한 Method(행위, POST) 그리고 Representation of Resource(자원의 형태, JSON)을 사용하면 표현이 명확해지므로 이를 REST라고 하며, 이러한 규칙을 지켜 설계된 API를 RESTful API라고 한다.

TDD 란 무엇이며 어떠한 장점이 있는가?

Test-Driven Development(TDD)는 매우 짧은 개발 사이틀의 반복에 의존하는 소프트웨어 개발 프로세스. 테스트가 코드 작성을 주도하는 개발방식. 새로운 기능이 제대로 작동함과 동시에 기존의 기능들이 잘 작동하는지 테스트를 통해 확인 가능. 뚱뚱해진 함수를 여러 함수로 나누는 과정에서 간단히 테스트를 돌려봄으로써 리팩토링을 진행할 수 있다.
테스트 코드를 추가적으로 고려해야 하기에 코드량이 늘어나고, 시간이 더 걸린다.
팀원 전체가 이해하고, 익숙해져야 테스트 코드가 빛을 발하게 된다.
모든 케이스에 대해 테스트 코드를 작성할 필요는 없다

함수형 프로그래밍이란?

Function - 함수를 이용해서

No Side Effect - 사이드 이펙트 없도록(Side Effect :: 부작용)

Declarative Programming - 선언형 프로그래밍을 이용하는 것이다.

 

Function을 사용한다는 것.

#non-FP

account.deposit()

user.login()

#FP

deposit(account)

user(User)

 

Side Effect가 없다는 것.

OOP : 멤버면수와 메소드로 이루어져 있고, 메소드의 수행결과는 멤버변수가 어떤 상태를 가지고 있는가에 따라 결과가 달라지게 된다.

FP : 인풋과 아웃풋이 있고, 동일한 인풋에 대해 동일한 아웃풋을 낸다. 상태를 가지지 않는다.

 

명령형(Imperative) VS 선언형(Declarative)

명령형 프로그래밍 : 어떤 과정을 통하는가-에 대해 적는 것.

선언형 프로그래밍 : 어떤 결과를 얻는가-에 대해 적는것.

 

immutable 객체의 값이 변경될 경우, 새로운 객체를 생성하고 변경된 값을 주입하여 반환해야 한다. mutable 객체는 해당 객체의 값이 변경될 경우 값을 변경한다.
함수(function)는 일급 객체(first class citizen)로 간주된다. 일급 객체는 변수나 데이터 구조안에 함수를 담을 수 있어서 함수의 파라미터로 전달할 수 있고, 함수의 반환값으로 사용할 수 있다. 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다. 함수를 리터럴로 바로 정의할 수 있다.
반응형 프로그래밍(Reactive Programming)은 선언형 프로그래밍(declarative programming)이라고 불리며, 명령형 프로그래밍(imperative programming)의 반대말이다. 반응형 프로그래밍은 기본적으로 모든 것을 스트림(stream)으로 본다. 스트림이란 값들의 집합으로 볼 수 있으며 제공되는 함수형 메소드를 통해 데이터를 immutable 하게 관리할 수 있다.

MVC 패턴이란 무엇인가?

개발 할 때, 3가지 형태로 역할을 나누어 개발하는 방법론. 디자인 패턴 중 하나.

 

Model(모델) : 어플리케이션이 '무엇'을 할건지 정의. 컨트롤러가 호출할 때, 요청에 맞는 역할을 수행한다. 비즈니스 로직, 응용프로그램에서 데이터를 처리하는 부분. DB에 연결하고 데이터를 추출하거나 저장, 삭제, 업데이트, 변환 등의 작업을 수행한다. 상태의 변화가 있을 때 컨트롤러와 뷰에 통보해 후속 조치 명령을 받을 수 있게 한다.

 

View() : 화면에 무엇인가를 '보여주기 위한' 역할. 컨트롤러로부터 받은 모델의 결과값을 가지고 사용자에게 출력할 화면을 만드는 일을 한다. 만들어진 화면을 웹브라우저에 전송하여 웹브라우저가 출력하게 하는 것이다. 화면에 표시되는 부분으로 추출한 데이터나 일반적인 텍스트 데이터를 표시하거나 입력폼 또는 사용자와의 상호작용을 위한 인터페이스를 표시하는 영역이다.

 

Controller(컨트롤러) : 모델이 '어떻게' 처리할지를 알려주는 역할. 일종의 조정자. 클라이언트의 요청을 받았을 때, 그 요청에 대해 실제 업무를 수행하는 모델 컴포넌트를 호출한다. 또한 클라이언트가 보낸 데이터가 있다면, 모델에 전달하기 쉽게 데이터를 가공한다. 모델이 업무를 마치면 그 결과를 뷰에게 전달한다.

Git 과 GitHub 에 대해서

대충알고 넘기지말고 정리

DataStructure

Array VS Linked List

Array : 가장 기본적인 자료구조. 논리적 저장 순서와 물리적 저장 순서가 일치한다. 따라서 인덱스(index)로 해당 원소(element)에 접근할 수 있다. 인덱스 값을 알고 있으면 Big-O(1)에 해당 원소로 접근할 수 있다. 삭제와 삽입이 시간이 걸린다. 배열의 원소를 삭제하면 배열의 연속성이 깨진다. 빈공간을 매꾸려고 한칸씩 땡겨와야하기 때문에 시간복잡도가 O(n)이 된다. 삽입도 마찬가지다. 배열 중간에 삽입하려면 뒤로 한 칸씩 밀어서 공간을 만들어주어야하기 때문에 시간복잡도가 O(n)이 된다.

Linked List : 이 부분을 해결한 자료구조다. 각 원소들은 자기 자신 다음에 어떤 원소인지만을 기억하고 있다. 따라서 이 부분만 삭제와 삽입하면 되기에 O(1)에 해결가능하다. 하지만 탐색과정에서 처음부터 체크해야하기 때문에 O(n)의 시간이 추가적으로 발생한다. 그래서 탐색, 삽입, 삭제 모드 O(n)이 걸린다. Array보다 느리다. 하지만 Tree 구조의 근간이 된다.

Stack and Queue

Stack : 선형 자료구조. Last In First Out (LIFO 후입선출). 뒤에서부터 빼낸다.

Queue : 선형 자료구조. First In First Out (FIFO 선입선출). 앞에서부터 빼낸다.

Tree

비선형 자료구조. 계층적 관계(Hierarchical Relationship). 표현에 집중.

 

Node(노드) : 트리를 구성하고 있는 각각의 요소.

Edge(간선) : 트리를 구성하기 위해 노드와 노드를 연결하는 선.

Root Node(루트 노드) : 트리 구조에서 최상위에 있는 노드.

Terminal Node(Leaf Node, 단말 노드) : 하위에 다른 노드가 연결되어 있지 않은 노드.

Internal Node(내부 노드, 비단말 노드) : 단말 노드를 제외한 모든 노드로 루트노드를 포함한다.

Binary Tree(이진 트리) : 루트 노드를 중심으로 두개의 서브 트리로 나뉘어 진다. 두 서브 트리도 이진트리여야한다. 공집합도 이진트리에 포함시켜야 한다. 노드가 하나 뿐인 것도 이진 트리 정의에 만족하게 된다

 

트리에서는 각 층별로 숫자를 매겨서 이를 트리의 Level(레벨)이라고 한다. 레벨의 값은 0부터 시작하고, 루트 노드의 레벨은 0이다. 최고 레벨을 가리켜 해당 트리의 height(높이)라고 한다.

 

Perfect Binary Tree(포화 이진 트리) : 모든 레벨이 꽉 찬 이진 트리.

Complete Binary Tree(완전 이진 트리) : 위에서 아래로, 왼쪽에서 오른쪽으로 순서대로 차곡차곡 채워진 이진 트리.

Full Binary Tree(정 이진 트리) : 모든 노드가 0개 혹은 2개의 자식 노드만을 갖는 이진 트리.

 

BST(Binary Search Tree, 이진 탐색 트리)

규칙1. 이진 탐색 트리의 노드에 저장된 키는 유일하다.

규칙2. 부모의 키가 왼쪽 자식 노드의 키보다 크다.

규칙3. 부모의 키가 오른쪽 자식 노드의 키보다 작다.

규칙4. 왼쪽과 오른쪽 서브트리도 이진 탐색 트리이다.

이진 탐색 트리의 탐색 연산은 O(log n)의 시간 복잡도를 갖는다. 정확하게는 O(h)라고 표현하는게 맞다. 배열보다 많은 메모리를 사용하지만, 시간복잡도가 같은. 비효율적인 상황이 발생한다

 

Binary Heap

자료구조의 일종. Tree의 형식. Tree 중에서도 배열에 기반한 Complete Binary Tree이다. 배열에 트리의 값들을 넣어줄 때, 0번째는 건너뛰고 1 index부터 루트노드가 시작된다. (Heap)에는 최대힙(Max Heap), 최소힙(Min Heap) 두 종류가 있다.

Max Heap(최대힙) : 각 노드의 값이 해당 children의 값보다 크거나 같은 Complete Binary Tree(완전 이진 트리)를 말한다. Root Node의 값이 제일 크므로, 최대값을 찾는데 소요되는 연산은 O(1)이다. 그리고 완전 이진 트리이기 때문에 배열을 사용하여 효율적으로 관리할 수 있다. 하지만, heap의 구조를 계속 유지하기 위해 제거된 루트 노드를 대체할 다른 노드가 필요하다. 여기서 Heap은 맨 마지막 노드를 루트 노드로 대체시킨 후, 다시 heapify과정을 거쳐 heap구조를 유지한다. 결국 O(log n)이 걸린다.

 

Red Black Tree

RBT BST(이진 탐색 트리)를 기반으로 하는 트리 형식의 자료구조. 탐색, 삽입, 삭제 O(log n)이 걸린다. 동일한 노드의 개수일 때 depth를 최소화하여 시간 복잡도를 줄이는 것이 핵심. 동일한 노드의 개수일 때 depth가 최소가 되는 경우는 완전 Complete Binary Tree(이진 트리)인 경우이다.

규칙 1 : 각 노드는 Red or Black이라는 색을 갖는다.

규칙 2 : Root Node의 색은 Black이다.

규칙 3 : Leaf Node의 색은 Black이다.

규칙 4 : 어떤 노드의 색이 red라면 두개의 children의 색은 모두 Black이다.

규칙 5 : 각 노드에 대해서 노드로부터 descendant leaves까지의 단순 경로는 모두 같은 수의 black nodes 들을 포함하고 있다. 이를 해당 노드의 Black-Height라고 한다.

 

특징 1 : Binary Search Tree(이진 탐색 트리)이므로 BST의 특징을 모두 갖는다.

특징 2 : Root node부터 Leaf Node까지의 모든 경로 중 최소 경로와 최대 경로의 크기 비율은 2보다 크지 않다. 이러한 상태를 balanced상태라고 한다.

특징 3 : 노드의 child가 없을 경우 child를 가리키는 포인터는 NIL값을 저장한다. 이러한 NIL들은 Leaf Node로 간주한다.

 

삽입 : BST의 특성을 유지하면서 노드를 삽입한다. 그리고 삽입된 노드의 색을 RED로 지정한다. RED로 지정하면 Black-Height변경을 최소화할 수 있다. 삽입 결과 RBT의 특성 위배(violation)시 노드의 색깔을 조정하고, Black-Height가 위배되었다면 rotation을 통해 height를 조정한다. 이러한 과정을 통해 RBT의 동일한 height에 존재하는 internal node들의 Black-Height 가 같아지게 되고 최소 경로와 최대 경로의 크기 비율이 2미만으로 유지된다.

 

삭제 : 삭제도 삽입과 마찬가지로 BST의 특성을 유지하면서 해당 노드를 삭제한다. 삭제될 노드의 child의 개수에 따라 rotation방법이 달라지게 된다. 지워진 노드의 색이 Black이라면 Black-Height 1감소한 경로에 Black node 1개 추가되도록 rotation 하고 노드의 색을 조정한다. 지워진 노드의 색이 red라면 violation이 발생하지 않으므로 RBT가 그대로 유지된다.

 

Java Collection에서 ArrayList도 내부적으로 RBT로 이루어져 있고, HashMap에서의 Separate Chaining에서도 사용된다. 그만큼 효율이 좋고 중요한 자료구조이다.

Hash Table

hash는 내부적으로 배열을 사용하여 데이터를 저장하기 때문에 빠른 검색 속도를 갖는다. 특정한 값을 Search하는데 데이터 고유의 인덱스로 접근하게 되므로 average case에 대하여 O(1)이 된다. 하지만 인덱스로 저장되는 key값이 불규칙하다는 것이다.

그래서 특별한 알고리즘을 이용하여 저장할 데이터와의 연관된 고유한 숫자를 만들어 낸 뒤 이를 인덱스로 사용한다. 특정 데이터가 저장되는 인덱스는 그 데이터만의 고유한 위치이기 때문에, 삽입 연산 시 다른 데이터 사이에 끼어들거나, 삭제 시 다른 데이터로 채울 필요가 없으므로 연산에서 추가적인 비용이 없도록 만들어진 구조이다.

 

Hash Function

'특별한 알고리즘'이란 것을 통해 고유한 인덱스 값을 설정하는 것이 중요해보인다. 위에서 언급한 '특별한 알고리즘' hash method 또는 해시 함수(hash function)라고 하고 이 메소드에 의해 반환된 데이터의 고유 숫자 값을 hashcode라고 한다. 저장되는 값들의 key값을 hash function을 통해서 작은 범위의 값들로 바꿔준다.

하지만 어설픈 hash function을 통해서 key값들을 결정한다면 동일한 값이 도출될 수가 있다. 이렇게 되면 동일한 key값에 복수 개의 데이터가 하나의 테이블에 존재할 수 있게 되는 것인데 이를 Collision이라고 한다. (서로 다른 두개의 키가 같은 인덱스로 hashing되면 같은 곳에 저장할 수 없게 된다.)

 

좋은 hash function

키의 일부분을 참조하여 해쉬 값을 만들지 않고 키 전체를 참조하여 해쉬 값을 만들어 낸다. 키가 어떤 특성을 가지고 있느냐에 따라 달라지게 된다

hash function를 무조건 1:1로 만드는 것보다 Collision을 최소화하는 방향으로 설계하고 발생하는 Collision에 대비해 어떻게 대응할 것인가가 더 중요하다. 1:1 대응이 되도록 만드는 것이 거의 불가능하기도 하지만 그런 hash function를 만들어봤자 그건 array와 다를바 없고 메모리를 너무 차지하게 된다.

collision이 많아질 수록 Search에 필요한 시간복잡도가 O(1)에서 O(n)에 가까워진다. 좋은 hash function을 선택하는 것은 hash table의 성능 향상에 필수적이다.

hashing된 인덱스에 이미 다른 값이 들어 있다면 새 데이터를 저장할 다른 위치를 찾은 뒤에야 저장할 수 있는 것이다. 따라서 충돌해결은 필수이다.

 

Resolve Conflict

방법 1 : Open Address 방식 (개방주소법)

해시 충돌이 발생하면, 다른 해시 버킷에 해당 자료를 삽입하는 방식이다

Collision이 발생하면 데이터를 저장할 장소를 찾아 헤맨다

1.  Linear Probing : 순차적으로 탐색하며 비어있는 버킷을 찾을 때까지 계속 진행된다.

2. Quadratic Probing : 2차 함수를 이용해 탐색할 위치를 찾는다.

3. Double hashing probing : 하나의 해쉬 함수에서 충돌이 발생하면 2차 해쉬 함수를 이용해 새로운 주소를 할당한다. 위 두가지 방법에 비해 많은 연산량을 요구한다.

방법 2 : Separate Chaining 방식 (분리 연결법)

일반적으로 Opend Addressing Separate Chaining보다 느리다. Open Addressing의 경우 해시 버킷을 채운 밀도가 높아질 수록 Worst Case발생 빈도가 더 높아지기 때문이다. 반면 Separate Chaining방식의 경우 해시 충돌이 잘 발생하지 않도록 보조 해시 함수를 통해 조정할 수 있다면 Worst Case에 가까워지는 빈도를 줄일 수 있다. Java 7에서는 Separate Chaining 방식을 사용하여 HashMap을 구현하고 있다.

1. 연결리스트를 사용하는 방식(Linked List) : 각각의 버킷(buchet)들을 연결리스트(Linked List)로 만들어 Collision이 발생하면 해당 buchet list에 추가하는 방식이다. 연결 리스트의 특징을 그대로 이어받아 삭제 또는 삽입이 간단하다. 하지만 단점도 그대로 물려받아 작은 데이터들을 저장할 때 연결 리스트 자체의 오버헤드가 부담이 된다. 또 다른 특징으로는, 버킷을 계속해서 사용하는 Open Address방식에 비해 테이블의 확장을 늦출 수 있다.

2. Tree를 사용하는 방식(Red-Black Tree) : 기본적인 알고리즘은 Separate Chaining과 동일하며 연결리스트 대신 트리를 사용하는 방식이다. 연결 리스트를 사용할 것인가와 트리를 사용할 것인가에 대한 기준은 하나의 해시 버킷에 할당된 key-value 쌍의 개수이다. 데이터의 개수가 적을 때 WOrst Case를 살펴보면 트리와 연결 리스트의 성능 상 차이가 거의 없다. 따라서 메모리 측면을 봤을 때 개수가 적을때는 연결 리스트를 사용한다.

데이터가 얼마나 적어야할까. key-value 쌍의 개수가 6, 8개를 기준으로 결정한다. 6개면 연결 리스트, 8개면 트리로 사용하면 된다. 2개 텀을 준것은 1개를 추가했을때, 자료구조를 변경하는 일이 발생하기 때문이다. 6개에서 데이터가 2개 추가되면 트리로 변경해주면 된다.

 

Open Address VS Separate Chainig 

Worst Case에서는 O(M)이다. 하지만 Open Address는 연속된 공간에 데이터를 저장하기 때문에 Separate Chainig에 비해 캐시 효율이 높다. 따라서 데이터의 개수가 충분히 적다면 Open Address방식이 Separate Chainig보다 더 성능이 좋다. 한가지 차이점이 더 존재한다. Separate Chaing방식에 비해 Open Address방식은 버킷을 계속해서 사용한다. 따라서 Separate Chainig방식은 테이블의 확장을 보다 늦출 수 있다.

 

보조 해시 함수(Supplement Hash Function)

Key의 해시 값을 변형하여 해시 충돌 가능성을 줄이는 것이다. Separate Chaining방식을 사용할 때 함께 사용되며 보조 해시 함수로 Worst Case에 가까워지는 경우를 줄일 수 있다.

 

해시 버킷 동적 확장(Resize)

해시 버킷의 개수가 적다면 메모리 사용을 아낄 수 있지만 해시 충돌로 인해 성능 상 손실이 발생한다. 그래서 HashMap key-value쌍 데이터 개수가 일정 개수 이상이 되면 해시 버킷의 개수를 두 배로 늘린다. 이렇게 늘리면 해시 충돌로 인한 성능 손실 문제를 어느 정도 해결할 수 있다. 또 애매모호한 일정 개수 이상이라는 표현이 등장했다. 해시 버킷 크기를 두배로 확장하는 임계점은 현재 데이터 개수가 해시 버킷의 개수의 75%가 될 때이다. 0.75라는 숫자는 Load Factor라고 불린다

Graph

정점과 간선의 집합.

트리 또한 그래프이며, 그 중 사이클이 허용되지 않는 그래프를 말한다.

Undirected Graph (방향성이 없는 그래프) Directed Graph (방향성이 있는 그래프, Digraph)

Degree : Undirected Graph에서 각 정점(Vertex)에 연결된 Edge(간선)의 개수를 Degree라 한다. Directed Graph에서는 간선에 방향성이 존재하기 때문에 Degree가 두개로 나뉘게 된다. 각 정점으로부터 나가는 간선의 개수를 OutDegree라 하고, 들어오는 간선의 개수를 InDegree라 한다.

Weight Graph(가중치 그래프) : 간선에 가중치 정보를 두어서 구성한 그래프

Sub Graph(부분 그래프) : 본래의 그래프의 일부 정점 및 간선으로 이루어진 그래프

인접 행렬 (adjacent matrix) : 정방 행렬을 사용하는 방법

인접 리스트 (adjacent list) : 연결 리스트를 사용하는 방법

 

그래프 탐색

DFS(Depth First Search, 깊이 우선 탐색) : Stack을 사용해서 한 정점으로만 나아간다.

BFS(Breadth First Search, 너비 우선 탐색) : Queue를 사용해서 한 정점으로 부터 연결되어 있는 모든 정점으로 나아간다.

 

Minimum Spanning Tree(최소 신장 트리)

그래프 G spanning tree edge weight의 합이 최소인 spanning tree를 말한다. 여기서 말하는 spanning tree란 그래프 G의 모든 vertex cycle이 없이 연결된 형태를 말한다.

Kruskal Algorithm

초기화 작업으로 Edge없이 Vertex들만으로 그래프를 구성한다. 그리고 weight가 제일 작은 Edge부터 검토한다. Edge set을 오름차순으로 정렬하고 작은 weight에 해당하는 edge을 추가한다. 이때, cycle이 생기지 않는 경우에만 추가한다.

cycle생성 여부는 union-find를 사용해서 확인하면 된다.

Edge Weight기준으로 정렬 O(E log E)

union-find + set id 통일 O(E + V log)

O(E log E)가 걸린다.

 

Prim Algorithm

위키백과 예제 사진

ko.wikipedia.org/wiki/%ED%94%84%EB%A6%BC_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98

 

Network

OSI 7 Layer

ISO기구에서 제안한 표준 개방형 시스템 상호연결 모델.

물리 계층 : 물리적 매체를 통해 데이터 비트를 전송하기 위해 요구되는 기능들을 정의.

1) 전송단위 : 비트(Bit)

2) 프로토콜 : 이더넷(Ethernet), RS-232C 등

3) 장비 : 허브, 리피터

 

데이터 계층 : 두개의 개방 시스템간 효율적이고 신뢰성있는 정보전송을 할 수 있도록 함. 오류 제어 기능.

1) 전송단위 : 프레임(Frame)

2) 프로토콜 : MAC, PPP 등

3) 장비 : 브릿지, 스위치

 

네트워크 계층 : 다중 네트워크 링크에서 발신지로부터 목적지까지 전달할 책임.

1) 전송단위 : 패킷(Packet)

2) 프로토콜 : IP, ICMP 등

3) 장비 : 라우터, L3 스위치

 

전송 계층 : 전체 메시지를 종단 VS 종단간  제어와 에러를 관리. 주소설정, 오류 흐름 및 제어, 다중화 수행.

1) 전송단위 : 세그먼트(Segment)

2) 프로토콜 : TCP, UDP 등

3) 장비 : 게이트웨이, L4 스위치

 

세션 계층 : 양 끝단의 응용 프로세스가 통신을 관리하기 위한 방법을 제공.

1) 프로토콜 : NetBIOS, SSH, TLS

 

표현 계층 : 응용 계층으로부터 받은 데이터를 하위 계층인 세션 계층에 보내기 전에 통신에 적당한 형태 변환, 세션 계층에서 받은 데이터는 응용 계층에 맞게 변환하는 역할을 수행.

1) 프로토콜 : JPG, MPEG, SMB, AFP

 

응용 계층 : 응용 프로세스와 직접 관계하여 일반적인 응용 서비스를 수행. 정보교환, 전자메일, 파일전송 서비스.

1) 프로토콜 : DNS, FTP, HTTP

 

간단히 5계층으로 표현 가능

Physical : 전기신호를 전송하기 위한 장치들. UTP cable

Link : 네트워크 노드들 간에 data를 전송하는 기능을 담당. PPP, ethernet

Network : 출발지에서 목적지까지 datagram을 routing담당. IP, routing protocol

Transport : 호스트-호스트간에 데이터 전송 담당. TCP, UDP

Application : 네트워크 응용 프로그램. FTP, SMTP, HTTP

HTTP의 GET과 POST 비교

둘 다 HTTP 프로토콜을 이용해서 서버에 무엇인가를 요청할 때 사용하는 방식이다. 하지만 둘의 특징을 제대로 이해하여 기술의 목적에 맞게 알맞은 용도에 사용해야 한다.

GET

요청하는 데이터가 HTTP Request Message Header부분의 url에 담겨서 전송된다. 때문에 url 상에 ? 뒤에 데이터가 붙어 request를 보내게 되는 것이다. 이러한 방식은 url이라는 공간에 담겨가기 때문에 전송할 수 있는 데이터의 크기가 제한적이다. 또 보안이 필요한 데이터에 대해서는 데이터가 그대로 노출되므로 GET방식은 적절하지 않다.

 

POST

POST방식의 request HTTP Message Body부분에 데이터가 담겨서 전송된다. 때문에 바이너리 데이터를 요청하는 경우 POST방식으로 보내야 하는 것처럼 데이터 크기가 GET방식보다 크고 보안면에서 낫다.

 

차이점

GET은 가져오는 것이다. 서버에서 어떤 데이터를 가져와서 보여준다거나 하는 용도이지 서버의 값이나 상태 등을 변경하지 않는다. SELECT 적인 성향을 갖고 있다고 볼 수 있는 것이다. 반면에 POST는 서버의 값이나 상태를 변경하기 위해서 또는 추가하기 위해서 사용된다.

GET방식의 요청은 브라우저에게 Caching할 수 있다. 때문에 POST방식으로 요청해야 할 것을 보내는 데이터의 크기가 작고 보안적인 문제가 없다는 이유로 GET방식으로 요청한다면 기존에 caching 되었던 데이터가 응답될 가능성이 존재한다.

TCP + 사진설명 LINK

TCP는 웹이나 이메일과 같이 데이터가 정확하게 전달되어야 하는 통신에서 사용된다. 

 

연결 성립(Connection Establishment, 3-way Handshake

1) 클라이언트는 서버에 접속요청(sync) 하고 클라이언트는 sync_sent 상태가 

2) 서버는 요청수락(sync+ack)하고 서버는 sync_received 상태가 

3) 클라이언트는 서버에 수락확인(ack) 보내고 서버는 established 상태가됨

 

연결 해제(Connection Termination, 4-way Handshake

1) 클라이언트가 서버에 연결을 종료 (fin)플래그를 전송, 클아이언트는 종료신호를 기다리는 상태 fin_wait1

2) 서버는 일단 확인(ack) 했다는 메시지를 보내고 자신의 통신이 끝날때 까지 기다리게함. 서버는 close wait 상태 클라이언트는 종료신호를 기다리겠다는 fin_wait2 상태 전환

3) 서버가 통신이 끝나면 이제 종료해도된다는 (fin) 플래그를 클라이언트에 전달. 서버는 last_ack 상태로 전환, 클라이언트는 time_wait 상태 전환

4) 클라이언트는 연결종료를 확인했다는 응답(ack) 플래그를 보냄. 서버 상태 closed

 

SYN : synchronize sequence number

ACK : acknowledgement

TCP와 UDP의 비교

UDP(User Datagram Protocol, 사용자 데이터그램 프로토콜)는 비연결형 프로토콜이다. IP데이터그램을 캡슐화하여 보내는 방법과 연결 설정을 하지 않고 보내는 방법을 제공한다. UDP는 흐름제어, 오류제어 또는 손상된 세그먼트의 수신에 대한 재전송을 하지 않는다. 이 모두가 사용자 프로세스의 몫이다. UDP가 행하는 것은 포트들을 사용하여 IP프로토콜에 인터페이스를 제공하는 것이다. 종종 클라이언트는 서버로 짧은 요청을 보내고 짧은 응답을 기대한다. 만약 요청 또는 응답이 손실된다면, 클라이언트는 time out되고 다시 시도할 수 있으면 된다. 코드가 간단할 뿐만 아니라 TCP처럼 초기설정(initial setup)에서 요구되는 프로토콜보다 적은 메시지가 요구된다. UDP를 사용한 것들에는 DNS가 있다. 어떤 호스트 네임의 IP주소를 찾을 필요가 있는 프로그램은, DNS서버로 호스트 네임을 포함한 UDP패킷을 보낸다. 이 서버는 호스트의 IP주소를 포함한 UDP패킷으로 응답한다. 사전에 설정이 필요하지 않으며 그 후에 해제가 필요하지 않다.

 

TCP

대부분의 인터넷 응용분야들은 신뢰성과 순차적인 전달을 필요로 한다. UDP로는 이를 만족시킬 수 없으므로 다른 프로토콜이 필요하여 탄생한 것이 TCP(Transmission Control Protocol, 전송제어 프로토콜)는 신뢰성이 없는 인터넷을 통해 종단간에 신뢰성 있는 바이트 스트림을 전송 하도록 특별히 설계되었다. TCP서비스는 송신자와 수신자 모두가 소켓이라고 부르는 종단점을 생성함으로써 이루어진다. TCP에서 연결설정(Connection Establishment) 3-way handshake를 통해 행해진다. 모든 TCP연결은 전이중(full-duplex), 점대점(point to point)방식이다. 전이중이란 전송이 양방향으로 동시에 일어날 수 있음을 의미하며 점대점이란 각 연결이 정확히 2개의 종단점을 가지고 있음을 의미한다. TCP는 멀티캐스팅이나 브로드캐스팅을 지원하지 않는다.

HTTP와 HTTPS

HTTP의 문제점

1. HTTP는 평문 통신이기 떄문에 도청이 가능하다.

2. 통신 상대를 확인하지 않기 때문에 위장이 가능하다.

3. 완전성을 증명할 수 없기 때문에 변조가 가능하다.

 

TCP/IP는 도청 가능한 네트워크이다.

TCP/IP구조의 통신은 전부 통신 경로상에서 엿볼 수 있다. 패킷을 수집하는 것만으로 도청할 수 있다. 평문으로 통신할 경우 메세지의 의미를 파악할 수 있기 때문에 암호화하여 통신해야 한다.

 

HTTPS

HTTPS SSL 의 껍질을 덮어쓴 HTTP 라고 할 수 있다. , HTTPS 는 새로운 애플리케이션 계층의 프로토콜이 아니라는 것이다. HTTP 통신하는 소켓 부분을 SSL(Secure Socket Layer) or TLS(Transport Layer Security)라는 프로토콜로 대체하는 것 뿐이다. HTTP 는 원래 TCP 와 직접 통신했지만, HTTPS 에서 HTTP SSL 과 통신하고 SSL TCP 와 통신 하게 된다. SSL 을 사용한 HTTPS 는 암호화와 증명서, 안전성 보호를 이용할 수 있게 된다.

HTTPS SSL 에서는 공통키 암호화 방식과 공개키 암호화 방식을 혼합한 하이브리드 암호 시스템을 사용한다. 공통키를 공개키 암호화 방식으로 교환한 다음에 다음부터의 통신은 공통키 암호를 사용하는 방식이다.

DNS round robin 방식

별도의 소프트웨어, 하드웨어 로드 밸런싱 장비를 사용하지 않고, DNS만을 이용하여 도메인 레코드 정보를 조회하는 시점에서 트래픽을 분산하는 기법이다. DNS를 이용해서 하나의 서비스에 여러 대의 서버를 분산시키는 방법.

 

DNS Round Robin방식의 문제점

1. 서버의 수 만큼 공인 IP 주소가 필요함 부하 분산을 위해 서버의 대수를 늘리기 위해서는 그 만큼의 공인 IP 가 필요하다.

2. 균등하게 분산되지 않음 모바일 사이트 등에서 문제가 될 수 있는데, 스마트폰의 접속은 캐리어 게이트웨이 라고 하는 프록시 서버를 경유 한다. 프록시 서버에서는 이름변환 결과가 일정 시간 동안 캐싱되므로 같은 프록시 서버를 경유 하는 접속은 항상 같은 서버로 접속된다. 또한 PC 용 웹 브라우저도 DNS 질의 결과를 캐싱하기 때문에 균등하게 부하분산 되지 않는다. DNS 레코드의 TTL 값을 짧게 설정함으로써 어느 정도 해소가 되지만, TTL 에 따라 캐시를 해제하는 것은 아니므로 반드시 주의가 필요하다.

3. 서버가 다운되도 확인 불가 DNS 서버는 웹 서버의 부하나 접속 수 등의 상황에 따라 질의결과를 제어할 수 없다. 웹 서버의 부하가 높아서 응답이 느려지거나 접속수가 꽉 차서 접속을 처리할 수 없는 상황인 지를 전혀 감지할 수가 없기 때문에 어떤 원인으로 다운되더라도 이를 검출하지 못하고 유저들에게 제공한다. 이때문에 유저들은 간혹 다운된 서버로 연결이 되기도 한다. DNS 라운드 로빈은 어디까지나 부하분산 을 위한 방법이지 다중화 방법은 아니므로 다른 S/W 와 조합해서 관리할 필요가 있다.

웹 통신의 큰 흐름

우리가 Chrome을 실행시켜 주소창에 특정 URL값을 입력시키면 어떤 일이 일어나는가?

in 브라우저

1. url에 입력된 값을 브라우저 내부에서 결정된 규칙에 따라 그 의미를 조사한다.

2. 조사된 의미에 따라 HTTP Request 메세지를 만든다.

3. 만들어진 메세지를 웹 서버로 전송한다.

이 때 만들어진 메시지 전송은 브라우저가 직접하는 것이 아니다. 브라우저는 메시지를 네트워크에 송출하는 기능이 없으므로 OS에 의뢰하여 메시지를 전달한다. 우리가 택배를 보낼 때 직접 보내는게 아니라, 이미 서비스가 이루어지고 있는 택배 시스템(택배 회사)을 이용하여 보내는 것과 같은 이치이다. , OS에 송신을 의뢰할 때는 도메인명이 아니라 ip주소로 메시지를 받을 상대를 지정해야 하는데, 이 과정에서 DNS서버를 조회해야 한다.

여기까지..!

Operating System

프로세스(Process)와 스레드(Thread)

프로세스(Process)

컴퓨터에서 연속적으로 실행되고 있는 컴퓨터 프로그램. 메모리에 올라와 실행되고 있는 프로그램의 인스턴스(독립적인 개체). 운영체제로부터 시스템 자원을 할당받는 작업의 단위. 동적인 개념으로는 실행된 프로그램을 의미.

 

스레드(Thread)

프로세스 내에서 실행되는 여러 흐름의 단위. 프로세스의 특정한 수행 경로. 프로세스가 할당받은 자원을 이용하는 실행의 단위.

 

멀티 프로세스(Multi Process)

하나의 응용프로그램을 여러 개의 프로세스로 구성하여 각 프로세스가 하나의 작업(Task)을 처리하도록 하는 것.

장점) 여러 개의 자식 프로세스 중, 하나의 문제가 생기더라도 그 영향이 확산되지 않음.

단점) Context Switching(CPU에서 여러 프로세스를 돌아가면서 작업을 처리)에서의 오버헤드. 프로세스 사이의 어렵고 복잡한 통신 기법(IPC)(프로세스 사이의 변수를 공유할 수 없다.)

 

멀티 스레드(Multi Thread)

하나의 응용프로그램을 여러 개의 스레드로 구성하고, 각 스레드로 하나의 작업(Task)을 처리하도록 하는 것. 윈도우, 리눅스 등 많은 OS들이 멀티 스레딩을 기본으로 하고 있다. 웹 서버는 대표적인 멀티 스레드 응용 프로그램.

장점) 시스템 자원 소모 감소. 시스템 처리량 증가. 간단한 통신 방법으로 프로그램 응답 시간 단축.

단점) 주의 깊은 설계. 디버깅이 까다로움. 단일 프로세스 시스템의 경우 효과를 기대하기 어렵다. 다른 프로세스에서 스레드를 제어할 수 없다. 자원 공유의 문제가 발생. 하나의 스레드 문제 발생시, 전체 프로세스 영향. 

 

프로세스 제어 블록(PCB, Process Control Block)

운영체제가 프로세스를 표현한 것. 프로세스가 생성될 때 고유한 PCB가 생성되고 프로세스가 완료되면 PCB는 제거.

1) 프로세스 식별자(Process ID)

2) 프로세스 상태(Process State)

3) 프로그램 카운터(Program Counter)

4) CPU 레지스터

5) CPU 스케줄링 정보

6) 메모리 관리 정보

7) 프로세스 계정 정보

8) 입출력 상태 정보

9) 포인터

스케줄러(Scheduler)의 종류와 CPU스케줄링 알고리즘

장기 스케줄러(Long-Term Scheduler, Job Scheduler)

수행해야할 job이 10개, 메모리 6제한. 10개 중에 6개를 골라서 메모리에 올리는 일을 수행.

 

단기 스케줄러(Short-Term Scheduler, CPU Scheduler)

메모리에 올라온 6개의 job중 CPU가 수행할 1개를 선택하는 일을 수행.

 

중기 스케줄러(Medium-Term Scheduler, Swapper)

6개가 너무 많아서 문제가 발생, 어떤것을 내보낼까 선택하는 일을 수행.

 

CPU 스케줄링 알고리즘

비선점 방법

FCFS(First Come First Served or FIFO, 선입 선처리 스케줄링)

CPU를 요청하는 순서대로 CPU를 할당해준다. Queue로 구현, FIFO형태를 이룬다.

 

SJF(Shortest Job First, 최소작업 우선 스케줄링)

CPU가 사용 가능할 때, 실행 시간이 가장 짧은 프로세스부터 자원을 할당.

 

HRN 스케줄링

SJF방식에서 대기시간과 실행시간을 혼합.

 

비선점 & 선점 방법

Priority(우선순위 스케줄링)

프로세스가 Ready Queue에 도착하면 우선순위를 비교하여 우선순위가 가장 높은 프로세스에 CPU를 할당하는 방식.

 

선점형 방법

Round Robin(라운드 로빈 스케줄링)

프로세스가 CPU에서 동작할 수 있는 시간을 할당해준다. 원형 큐. 프로세스가 시간을 다 쓰면 OS가 인터럽트를 걸어 현재 PCB가 큐의 가장 뒤로 가는 방식.

 

MLQ(MultiLevel Queue, 다단게 큐)

준비 상태 큐를 여러 종류별, 단계별로 분할해두고 자신만의 독자적인 스케줄링 구현이 가능하다. 각 큐는 절대적인 우선순위를 가지며, 우선순위 높은 큐가 모두 비어있기 전에는 낮은 우선순위 큐에 있는 프로세스를 실행할 수 없다.

동기(Sync)와 비동기(Async)

동기(Synchronous)

빨래를 하고, 설거지를 하고 청소를 한다. 실행되었을 때, 값이 반환되기 전까지는 blocking되어 있다.

 

비동기(Asynchronous)

빨래 업체에 시키고 설거지 업체에 시키고 청소 업체에 시킨다. 일을 모두 마치면 나에게 알려준다.  blocking 되지 않고 이벤트 큐에 넣거나 백그라운드 스레드에 해당 task를 위임하고 다음 코드를 실행. 

Database

이전에는 파일 시스템 이용. 각각의 파일 단위로 저장, 독립적 애플리케이션과 상호연동 필요. 데이터 종속성 문제와 중복성, 데이터 무결성이다.

데이터베이스

데이터베이스의 특징

1) 데이터의 독립성

물리적 독립성 : 데이터 파일을 수정해도 응용 프로그램을 수정할 필요가 없다.

논리적 독립성 : 논리적 구조, 응용 프로그램의 논리적 요구를 만족시킨다.

2) 데이터의 유효성 검사를 통해 무결성 구현.

3) 접근 권한 설정으로 보안 구현.

4) 연관된 정보를 논리적 구조로 관리함으로써 불일치성 배제.

5) 통합 관리로 중복성 문제 해결.

 

데이터베이스의 성능

디스크 I/O를 어떻게 줄이느냐. 디스크 헤더의 위치 이동 없이 얼마나 많은 데이터를 한번에 기록하느냐.

순차 I/O가 랜덤 I/O보다 빠를 수 밖에 없다. 데이터베이스 쿼리 튜닝은 랜덤 I/O자체를 줄여주는 것이 목적이다.

Index

인덱스(Index)란 무엇인가?

데이터가 책의 내용이고, 데이터가 저장된 레코드의 주소는 인덱스 목록에 있는 페이지 번호이다

해당 레코드가 저장된 주소를 키와 값의 쌍으로 인덱스를 만들어 두는 것이다.

DBMS의 인덱스는 정렬상태를 유지하며, 삽입, 삭제, 수정시 실행속도가 느리다. 대신 읽기 속도가 빠르다.

 

Index 자료구조

B+Tree

B+Tree는 DB인덱스를 위해 B-Tree(자식 노드의 개수가 2개 이상인 트리)를 개선시킨 자료구조. 리프노드(데이터 노드)만 인덱스와 함께 데이터(Value)를 가지고 있고, 나머지 노드는 인덱스(Key)만을 갖는다.

 

Hash Table

해시 테이블은 Key-Value로 데이터를 저장하는 자료구조. 빠른 데이터 검색이 필요할 때 유용. 등호 연산에만 특화되어 있다. 부등호 연산에 취약하다. 

 

Clustered Index

클러스터드 인덱스는 물리적으로 행을 재배열한다. 프라이머리 키 값이 비슷한 레코드끼리 묶어서 저장하는 것을 클러스터드 인덱스라고 표현한다.

프라이머리 키 값에 의해 레코드 저장 위치가 결정되며, 테이블 당 한개만 생성 가능하다. non클러스터드 인덱스는 테이블당 여러개 생성 가능하다.

 

Composite Index

인덱스를 생성할 때 두개 이상의 컬럼을 합쳐서 인덱스를 만드는 것. WHERE 절의 조건 컬럼이 2개 이상이 AND로 연결되어 함께 사용이 되는 경우에 많이 사용.

 

Index의 성능과 고려해야할 사항

모든 칼럼에 Index생성하면 수정, 삽입, 삭제시 비효율발생.

이름, 나이, 성별 중 이름 인덱스를 생성하는 것이 효율적이다. (이름이 제일 경우의 수가 많다.)

정규화

1. 정규화는 어떤 배경에서 생겨났는가?

데이터가 혼합되면. 갱신 이상이 발생하고, 저장 공간을 낭비한다.

삽입 이상(insertion anomalies) 원하지 않는 자료가 삽입, 삽입하는 데 자료가 부족해 삽입되지 않음.

삭제 이상(deletion anomalies) 하나만 삭제하고 싶지만, 포함된 튜플 전체가 삭제됨. 정보 손실.

갱신 이상(modification anomalies) 정확하지 않음, 일부의 튜플만 갱신되어 정보가 모호해짐. 일관성이 없어져 정보 파악이 되지 않음.

 

2. 그래서 정규화란 무엇인가?

관계형 데이터베이스에서 중복을 최소화하기 위해 데이터를 구조화하는 작업.

나쁜 릴레이션의 애트리뷰트를 나눠 좋은 작은 릴레이션으로 분해하는 작업.

나쁜 릴레이션은 어떻게 파악하는가?

엔티티를 구성하고 있는 애트리뷰트 간에 함수적 종속성을 판단

학번→이름학번→나이학번→성별 학번을 알면 이름, 나이, 성별을 알 수 있다.

각각의 정규형은 어떠한 조건을 만족해야 하는가?

1. 분해 집합 D는 무손실 조인을 보장해야 한다.

2. 분해 집합 D는 함수적 종속성을 보존해야 한다.

 

정규화 사진 예제

1 정규형 (1NF, First Normal Form)

애트리뷰트의 도메인이 오직 원자값만을 포함하고 하나의 값을 가져야 한다.

2 정규형 (2NF, Second Normal Form)

키가 아닌 모든 속성이 기본키에 완전 함수 종속되어야 한다. (종속자가 기본키에만 종속)

3 정규형 (3NF, Third Normal Form)

2 정규형에 속하면서 이행적 함수 종속이 되지 않으면 된다.

(X->Y->Z 이렇게 안되면 됨, X->Y and Y->Z 릴레이션 두개 가능)

BCNF(Boyce-Codd Normal Form, Strong 3NF) 정규형

3 정규형을 보완.

 X->Y라는 FD(Functional Dependency)에서 X Super-key 가 아니고 Y Prime 속성인 경우를 제외.

학생, 과목, 교수 (학생, 과목) -> 교수 일때 교수 -> 과목이 가능하기 때문에 학생 -> 교수, 교수 -> 과목 이렇게 바꿔줘야함.

 

3. 정규화에는 어떠한 장점이 있는가?

1) 데이터베이스 변경 시 이상 현상(Anomaly)제거.

2) 데이터베이스 구조 확장 시 재 디자인 최소화

3) 사용자에게 데이터 모델을 더욱 의미있게 제공.

 

4. 단점은 없는가?

릴레이션 간의 JOIN연산이 많아진다. 느려질 수 있다.

 

5. 단점에 대한 대응책.

반정규화(De-normalization, 비정규화)

데이터를 중복시키거나, 그룹핑함으로써 데이터베이스의 성능 향상.

1) 자주 사용되는 테이블에 엑세스 하는 프로세스의 수가 가장 많고, 항상 일정한 범위만 조회.

2) 테이블에 대량 데이터, 대량의 범위를 자추 처리하는 경우, 성능 상 이슈.

3) 조인이 너무 많아 조회하는것이 기술적으로 어려울 경우

주의점.

과도하게 적용하면 데이터의 무결성이 깨질 수 있다. 응답시간이 늦어질 수 있다.

트랜잭션(Transaction)과 교착상태

트랜잭션(Transaction)이란 무엇인가?

작업의 완전성을 보장. 원상태로 복구해서 작업의 일부만 적용되는 현상을 방지. 사용자의 입장에서는 작업의 논리적 단위. 시스템의 입장에서는 데이터들을 접근, 변경하는 프로그램의 단위

 

트랜잭션과 Lock

잠금(Lock)은 동시성 제어. 트랜잭션은 데이터의 정합성을 보장. 잠금은 여러 커넥션에서 동시에 동일한 자원을 요청할 경우 순서대로 한 시점에는 하나의 커넥션만 변경할 수 있게 해줌. 자원은 레코드나 테이블을 의미. 트랜잭션은 여러개이든 아니든 논리적 작업 셋 자체가 100%적용되거나 0%적용됨을 보장하는 것이다. HW에러, SW에러 났을 때 실패될 경우 원상태로 복구하는 보장을 해준다.

 

트랜잭션의 특성

원자성(Atomicity) : 중간에 문제 발생시 STOP. 아무런 문제가 없을 때 작업이 수행되어야 함.

일관성(Consistency) : 완료된 다음의 상태에서도 트랜잭션이 일어나기 전의 상황과 동일하게 일관성을 보장해야 함.

고립성(Isolation) : 각각의 트랜잭션은 서로 간섭없이 독립적으로 수행되어야 함.

지속성(Durability) : 종료된 다음에는 영구적으로 데이터베이스에 작업의 결과가 저장되어야 함.

 

트랜잭션 연산 및 상태

Commit연산

한개의 논리적 단위(트랜잭션)에 대한 작업이 성공적으로 끝났고 데이터베이스가 다시 일관된 상태에 있을 때, 이 트랜잭션이 행한 갱신 연산이 완료된 것을 트랜잭션 관리자에게 알려주는 연산이다. 잘 끝났을때 완료됐다고 알려주는 연산.

 

Rollback연산

하나의 트랜잭션 처리가 비정상적으로 종료되어 데이터의 일관성을 깨뜨렸을 때, 일부가 정상적으로 처리 되었더라도 트랜잭션의 원자성을 구현하기 위해 이 트랜잭션이 행한 모든 연산을 취소(Undo)하는 연산. Rollback시에는 해당 트랜잭션을 재시작하거나 폐기한다.

 

Active : 활동. 트랜잭션이 실행중이며 동작중인 상태.

Failed : 실패. 트랜잭션이 더이상 정상적으로 진행할 수 없는 상태.

Partially Committed : 부분 완료. Commit 명령이 도착한 상태. 커밋 이전 SQL문이 수행되고 커밋만 남은 상태.

Committed : 완료. 트랜잭션이 정상적으로 완료된 상태.

Aborted : 취소. 취소되고 트랜잭션 실행 이전 데이터로 돌아간 상태.

 

주의할 점

꼭 필요한 최소의 코드에만 적용하는 것이 좋다. 데이터베이스 커넥션 수가 제한적이어서, 각 단위 프로그램이 커넥션 소유 시간이 길어지면 여유 커넥션 수가 줄어들고 대기 상황이 발생할 수 있다.

 

교착상태

복수의 트랜잭션을 사용하다 발생가능.

트랜잭션 1 B -> A 접근하여 B의 잠금을 얻고 A를 요구하고

트랜잭션 2 A -> B 접근하여 A의 잠금을 얻고 B를 요구하면

다른 트랜잭션이 소유한 잠금을 요구하면 아무리 기다려도 상황이 바뀌지 않고 이를 교착상태라고 한다.

1) 트랜잭션을 자주 커밋한다.

2) 정해진 순서로 테이블에 접근한다.

3) 읽기 잠금 획득의 사용을 피한다.

4) ?

NoSQL

관계형 데이터 모델을 지양. 스키마 없이 사용 가능. 느슨한 스키마를 제공. 대량의 분산된 데이터를 저장하고 조회하는데 특화.

 

CAP 이론

일관성 (Consistency)

다중 클라이언트에서 같은 시간에 조회하는 데이터는 항상 동일한 데이터임을 보증하는 것.

데이터의 일관성이 느슨하게 처리되어 동일한 데이터가 나타나지 않을 수 있다. 시간의 흐름에 따라 여러 노드에 전파하는 것을 말한다. 최종적으로는 일관성이 유지된다하여, 최종 일관성 또는 궁극적 일관성을 지원한다.

 

가용성, 내고장성 (Availabilty)

모든 클라이언트의 읽기와 쓰기 요청에 대하여 항상 응답이 가능해야 함을 보증.

클러스터 내에서 몇개의 노드가 망가지더라도 정상적인 서비스가 가능. 몇몇 NoSQL은 데이터 복제를 사용한다. 망가져도 유실되지 않도록 저장소를 하나 더 생성하는 Master-Slave 복제 방법, 데이터 단위로 중복 저장하는 Peer-to-Peer 복제 방법이 있다.

 

네트워크 분할 허용성(Partition tolerance)

네트워크가 단절되거나 네트워크 데이터의 유실이 일어나더라도 각 지역 내의 시스템은 정상적으로 동작해야 함을 의미한다.

 

저장 방식에 따른 NoSQL 분류

Key-Value Model

가장 기본적인 형태. 키 하나로 데이터 하나를 저장하고 조회. 단순한 저장구조로 복잡한 조회 연산을 지원하지 않는다. 고속 읽기와 스기에 최적화. 사용자의 프로필 정보, 세션 정보, 장바구니 정보, URL 단축 정보 저장. ex) Redis

 

Document Model

Key-Value Model의 확장한 구조. 관계형 데이터베이스와 유사. 키는 문서에 대한 ID. 문서 ID에 대한 인덱스 사용. B 트리 인덱스를 사용하여 2차 인덱스를 생성. 읽기와 쓰기 비율이 7:3 정도일 때 가장 좋은 성능을 보인다. 중앙 집중식 로그 저장, 타임라인 저장, 통계 정보 저장. ex) MongoDB

 

Column Model

하나의 키에 여러개의 컬럼 이름과 컬럼 값의 쌍으로 이루어진 데이터. 모든 컬럼은 항상 타임 스탬프 값과 함께 저장. 쓰기와 읽기 중 쓰기에 특화되어 있다. 데이터를 먼저 커밋로그와 메모리에 저장한 후 응답하기 때문에 빠른 응답속도를 제공한다. 채팅 내용 저장, 실시간 분석을 위한 데이터 저장소.

 

Design Pattern

Singleton pattern(싱글턴 패턴)이란 애플리케이션에서 인스턴스를 하나만 만들어 사용하기 위한 패턴이다