BOJ 14719

🕵️‍♀️ 문제


2차원 세계에 블록이 쌓여있다. 비가 오면 블록 사이에 빗물이 고인다.비는 충분히 많이 온다. 고이는 빗물의 총량은 얼마일까?

 

 

💡 입력


첫 번째 줄에는 2차원 세계의 세로 길이 H과 2차원 세계의 가로 길이 W가 주어진다. (1 ≤ H, W ≤ 500)

두 번째 줄에는 블록이 쌓인 높이를 의미하는 0이상 H이하의 정수가 2차원 세계의 맨 왼쪽 위치부터 차례대로 W개 주어진다.

따라서 블록 내부의 빈 공간이 생길 수 없다. 또 2차원 세계의 바닥은 항상 막혀있다고 가정하여도 좋다.

 

 

 

 

📌 출력


2차원 세계에서는 한 칸의 용량은 1이다. 고이는 빗물의 총량을 출력하여라.

빗물이 전혀 고이지 않을 경우 0을 출력하여라.

 

 

🙋‍♀️ 풀어보자~


빗물이 고이기 위해서는 기둥이 필요하다. 

이 기둥이 어떻게 생기는지 생각해보자.

 

위 사진과 같이 max인 4를 기준으로 좌우의 가장 큰 값인 3과 2의 값이 중요함을 알 수 있다.

왼쪽은 3을 기준으로 빗물이 받아지고 오른쪽은 2를 기준으로 빗물이 받아지기 때문~

 

더 자세하게 보자면..

각 자리를 i로 보고 0부터 7까지 번호를 매겼을 때 2번째 블럭을 보자.

i=2번째 블럭은 2개로 이 블럭을 기준으로 빗물 기둥이 되어줄 좌우의 max 숫자를 살펴보면 3과 4임을 알 수 있다.

여기서 max중 작은 수가 기준이 되기 때문에 3이라는 숫자를 이용해주게 된다.

 

 

정리하자면~

  • 양쪽에 더 높은 블럭이 존재하면 빗물이 고임
  • 반복문을 돌면서 현재의 블럭 기준 left_max와 right_max를 구하고 이 두 값중 작은 수를 구함
    • 구해진 수 - 현재 블럭의 수 가 빗물이 담길 칸수다.
    • 첫 블럭과 마지막 블럭은 볼필요 없다. (그림과 같은 예시를 이용하자면, i=0일 때와 i=7일 때)

 

# 빗물

# 입력을 받아 준다.
H, W = map(int, input().split())
block = list(map(int, input().split()))
answer = 0

# 맨 앞뒤를 제외한 for문을 돌면서 왼쪽과 오른쪽에서 최댓값을 찾는다.
for i in range(1, W-1):
    left_max = max(block[:i]) # 현재 블럭을 기준으로 왼쪽에서 max 값 찾기
    right_max = max(block[i+1:]) # 현재 블럭을 기준으로 오른쪽에서 max 값 찾기
    m = min(left_max, right_max) #left_max와 right_max 중 작은 값을 변수에 담자.
    
    # 현재 블럭이 지정한 기준값보다 작으면 빗물이 고인다.
    if block[i] < m:
        answer += m - block[i]

print(answer)

 

 

'🕵️‍♀️ > BOJ' 카테고리의 다른 글

[Python] BOJ 2606 바이러스 (BFS/DFS)  (0) 2021.11.17
코테대비 백준문제추천  (0) 2021.11.05
[Python] BOJ 1149 RGB거리 (dp)  (0) 2021.11.04
[BOJ] Python 백준 11650번  (0) 2021.08.19
[BOJ] Python 백준 2751번  (0) 2021.08.16

BOJ 1149

🕵️‍♀️ 문제


RGB거리에는 집이 N개 있다. 거리는 선분으로 나타낼 수 있고, 1번 집부터 N번 집이 순서대로 있다.

집은 빨강, 초록, 파랑 중 하나의 색으로 칠해야 한다. 각각의 집을 빨강, 초록, 파랑으로 칠하는 비용이 주어졌을 때, 아래 규칙을 만족하면서 모든 집을 칠하는 비용의 최솟값을 구해보자.

  • 1번 집의 색은 2번 집의 색과 같지 않아야 한다.
  • N번 집의 색은 N-1번 집의 색과 같지 않아야 한다.
  • i(2 ≤ i ≤ N-1)번 집의 색은 i-1번, i+1번 집의 색과 같지 않아야 한다.

 

 

💡 입력


첫째 줄에 집의 수 N(2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄부터 N개의 줄에는 각 집을 빨강, 초록, 파랑으로 칠하는 비용이 1번 집부터 한 줄에 하나씩 주어진다. 집을 칠하는 비용은 1,000보다 작거나 같은 자연수이다.

 

 

 

📌 출력


  • 첫째 줄에 모든 집을 칠하는 비용의 최솟값을 출력한다.

 

 

🙋‍♀️ 풀어보자~


다이나믹 프로그래밍으로 접근해서 Memoization을 사용하자.

 

2차원 배열을 이용해서 각 자리마다 RGB의 비용을 담을 수 있게 하자.

just like... -> [ [ 1번 집의 R비용, 1번 집의 G비용, 1번 집의 B비용 ] , [ 2번 집의 R비용, ....

 

점화식을 떠올리기 위해서 i번째의 집과 그 앞뒤의 i-1번째 집과 i+1번째 집을 생각해보자.

i+1번째 집은 i번째 집의 색에 영향을 받지만 i-1번째 집의 색에는 영향을 받지 않는다.

 

 

이 같은 상황을 점화식으로 생각해보자. i와 i+1만 생각해주면된다~

  1. i+1번째 집이 R일 때, i-1은은 G나 B 중 더 적은 비용을 갖는 것을 선택하면 된다.
  2. i+1번째 집이 G일 때, i-1은은 R나 B 중 더 적은 비용을 갖는 것을 선택하면 된다.
  3. i+1번째 집이 B일 때, i-1은은 R나 G 중 더 적은 비용을 갖는 것을 선택하면 된다.

 

 

 

# RGB

# n : 집의 수
n = int(input())

# 초기세팅 0으로 다 깔아놓거라
dp = [[0, 0, 0] for _ in range(n)]

for i in range(n):
    # 우선 먼저 입력받음
    cost = list(map(int, input().split()))

    # 첫 입력인 경우, 그냥 cost를 담아주세요.
    if i == 0:
        dp[0] = cost
    else:
        # 점화식 넣어주세효
        dp[i][0] = min(dp[i-1][1], dp[i-1][2]) + cost[0] # i번째집이 R일경우
        dp[i][1] = min(dp[i-1][0], dp[i-1][2]) + cost[1] # i번째집이 G일경우
        dp[i][2] = min(dp[i-1][0], dp[i-1][1]) + cost[2] # i번째집이 B일경우

# dp 리스트의 n-1번째에 있는 누적된 RGB 비용 중 가장 최소 값을 출력한다.
print(min(dp[n-1]))

'🕵️‍♀️ > BOJ' 카테고리의 다른 글

[Python] BOJ 2606 바이러스 (BFS/DFS)  (0) 2021.11.17
코테대비 백준문제추천  (0) 2021.11.05
[Python] BOJ 14719 빗물  (0) 2021.11.04
[BOJ] Python 백준 11650번  (0) 2021.08.19
[BOJ] Python 백준 2751번  (0) 2021.08.16

46. Permutations

🕵️‍♀️ Question


Given an array nums of distinct integers, return all the possible permutations. You can return the answer in any order.

 

 

💡 Example


1:

Input: nums = [1,2,3]

Output: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

 

2:

Input: nums = [0,1]

Output: [[0,1],[1,0]]

 

3:

Input: nums = [1]

Output: [[1]]

 

 

 

📌 Constraints


  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • All the integers of nums are unique.

 

 

🙋‍♀️ 풀어보자~


서로 다른 정수를 입력받아 가능한 모든 수열을 리턴하는 간단한 순열 문제다.

두가지의 풀이가 존재한다.

 

version1 : DFS를 활용한 순열 생성

백트래킹(backtracking)이란? :

해를 찾는 도중 해가 아니어서 막히면, 되돌아가서 다시 해를 찾아가는 기법을 말합니다.

최적화 문제와 결정 문제를 푸는 방법이 됩니다.

순열이란 모든 가능한 경우를 그래프 형태로 나열한 결과이다. -> 그래프로 표현 가능하다.

The graph of Permutation with backtracking

# Runtime: 69 ms
# Memory Usage: 14.4 MB

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        results = []
        prev_elements = []
        
        def dfs(elements) :
            #리프노드일때
            if len(elements) == 0 :
                results.append(prev_elements[:])
                
            #순열 생성 재귀 호출
            for e in elements:
                next_elements = elements[:]
                next_elements.remove(e)
               
                prev_elements.append(e)
                # print("perv",prev_elements)
                # print("next재귀돌러가즈아",next_elements)
                dfs(next_elements)
                prev_elements.pop()
                # print("**백트래킹",prev_elements)
    
        dfs(nums) 
        return results
# input이 [1,2,3] 면 나오는 출력,,,
perv [1]
next재귀돌러가즈아 [2, 3]
perv [1, 2]
next재귀돌러가즈아 [3]
perv [1, 2, 3]
next재귀돌러가즈아 []
**백트래킹 [1, 2]
**백트래킹 [1]
perv [1, 3]
next재귀돌러가즈아 [2]
perv [1, 3, 2]
next재귀돌러가즈아 []
**백트래킹 [1, 3]
**백트래킹 [1]
**백트래킹 []
perv [2]
next재귀돌러가즈아 [1, 3]
perv [2, 1]
next재귀돌러가즈아 [3]
perv [2, 1, 3]
next재귀돌러가즈아 []
**백트래킹 [2, 1]
**백트래킹 [2]
perv [2, 3]
next재귀돌러가즈아 [1]
perv [2, 3, 1]
next재귀돌러가즈아 []
**백트래킹 [2, 3]
**백트래킹 [2]
**백트래킹 []
perv [3]
next재귀돌러가즈아 [1, 2]
perv [3, 1]
next재귀돌러가즈아 [2]
perv [3, 1, 2]
next재귀돌러가즈아 []
**백트래킹 [3, 1]
**백트래킹 [3]
perv [3, 2]
next재귀돌러가즈아 [1]
perv [3, 2, 1]
next재귀돌러가즈아 []
**백트래킹 [3, 2]
**백트래킹 [3]
**백트래킹 []
=========
perv [0]
next재귀돌러가즈아 [1]
perv [0, 1]
next재귀돌러가즈아 []
**백트래킹 [0]
**백트래킹 []
perv [1]
next재귀돌러가즈아 [0]
perv [1, 0]
next재귀돌러가즈아 []
**백트래킹 [1]
**백트래킹 []

 

 

 

version2. 파이썬의 itertools 모듈을 사용한다.

itertools 
반복자 생성에 최적화된 효율적인 기능들을 제공.
이미 잘 구현된 라이브러리라 버그 발생 가능성이 낮고 효율적으로 설계된 C 라이브러리라 속도도 빠름
📍 사용할 때 주석으로 "# 구현의 효율성, 성능을 위해 사용했다" 라고 달아주면 쵝오~

permutation( ) 함수가 튜플 모음을 반환하기 때문에 리트코드 문제에서는 리스트를 반환하도록 요구하기 때문에 변환처리를 해줘야한다.

 

# Runtime: 28 ms
# Memory Usage: 14.3 MB

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        import itertools
        return list(map(list, itertools.permutations(nums)))
SQL Injection

웹 사이트의 보안상 허점을 이용해 특정 SQL 쿼리문을 전송하여
공격자가 원하는 데이터베이스의 중요한 정보를 가져오는 해킹 기법이다.

대부분 클라이언트가 입력한 데이터를 제대로 필터링하지 못하는 경우에 발생한다.

공격이 쉬운 난이도에 비해 피해가 상당하기 때문에
보안 위협 1순위로 불릴만큼 중요한 기법이다.

 

 

 

 

간략한 공격 시나리오


예를 들어 회원이 자신의 일련번호를 조회할 수 있는 상황이 있다고 가정하자.

기본적인 SQL 진행은 클라이언트가 일련번호 조회를 클릭하여 웹서버에 이름이 들어가고 DB에 입력한 값이 있는지 확인 후 존재한다면 번호 DB를 출력해준다.

 

예를 들어 번호 조회를 클릭하면 url이 http://numbersearch.com/mysearch?=ohyaelim 이 된다고 가정하자.

그럼 공격자의 조회는 http://numbersearch.com/mysearch?=blackhat  에서 탈취하고 싶은 정보의 유저인 ohyaelim으로 변경해줘야하는데, 그냥 변경하는 것으로는 현재 로그인 된 자신과는 다르기 때문에 웹서버에서 인정하지 않는다. 

 

그러므로 특정 쿼리문을 넣어준다. 'ohyaelim' or '1' = '1' 과 같이 넣어부념 1과 1은 같다라는 구문이 참이므로 결과를 출력해준다.

 

이러한 SQL Injection의 공격 범위는 매우 다양하다.

bypass
data access
content change
db delete

 

 

 

 

 

공격 종류 및 방법


Error based SQL Injection

- 논리적 에러를 이용한 SQL Injection

SQL 공격 기법은 여러가지가 있는데 논리적 에러를 이용한 SQL Injection은 가장 많이 쓰이고 대중적인 공격 기법이다.

앞서 살펴봤던 공격 시나리오가 여기에 해당된다. 

 

select * from client where name='ohyaelim' and password='1122'

 

가 올바른 로그인의 예라면 

 

select * from client where name='ohyaelim' and password=' or '1'='1

 

와 같이 작성해 or 앞의 값과 뒤에 값 중 하나라도 참이면 참이므로 이 구문 자체가 참으로 인식되어 로그인에 성공하게 된다.

 

 

 

UNION based SQL Injection = UNION

- 명령어를 이용한 SQL Injection

SQL UNION이란, 여러개의 SQL문을 합쳐 하나의 SQL문으로 만들어주는 방법이다. 
쿼리를 날리기에 앞서 사전 조건이 필요하다. Union 하는 두 테이블의 컬럼 수가 같아야 하고 데이터 형이 같아야 한다.

UNION과 UNION ALL로 나뉘는데 중복 값을 제외 하고 안하고의 차이다. 

UNION - 중복 값을 제외한다.

UNION ALL - 중복 값을 제외하지 않고 전체를 합친다.

 

입력값을 title  contents 컬럼의 데이터랑 비교한 뒤 비슷한 글자가 있는 게시글을 출력한다.

여기서 입력값으로 Union 키워드와 함께 컬럼 수를 맞춰서 SELECT 구문을 넣어주게 되면 두 쿼리문이 합쳐서서 하나의 테이블로 보여지게 된다.

현재 인젝션 한 구문은 사용자의 id passwd를 요청하는 쿼리문으로 인젝션이 성공하게 되면, 사용자의 개인정보가 게시글과 함께 화면에 보여지게 된다.

 

( * 물론 패스워드를 평문으로 데이터베이스에 저장하지는 않겠지만 인젝션이 가능하다는 점에서 이미 그 이상의 보안위험에 노출되어 있습니다. 이 공격도 역시 입력값에 대한 검증이 없기 때문에 발생하게 되었다. )

 

 

 

 

Blind SQL Injection 

- Boolean based Blind SQL Injection

Blind SQL Injection은 데이터베이스로부터 특정한 값이나 데이터를 전달받지 않고, 단순히 참과 거짓의 정보만 알 수 있을 때 사용한다. 로그인 폼에 SQL Injection이 가능하다고 가정 했을 때, 서버가 응답하는 로그인 성공과 로그인 실패 메시지를 이용하여, DB의 테이블 정보 등을 추출해 낼 수 있다.

 

위 사진과 같은 예시를 살펴보면 limit 키워드를 통해 하나의 테이블만 조회하고, SUBSTR 함수로 첫 글자만, 그리고 마지막으로 ASCII 를 통해서 ascii 값으로 변환해준다. 만약에 조회되는 테이블 명이 Users 라면 ‘U’ 자가 ascii 값으로 조회가 될 것이고, 뒤의 100 이라는 숫자 값과 비교를 하게 된다. 거짓이면 로그인 실패가 될 것이고, 참이 될 때까지 뒤의 100이라는 숫자를 변경해 가면서 비교를 하면 된다.  공격자는 이 프로세스를 자동화 스크립트를 통하여 단기간 내에 테이블 명을 알아 낼 수 있다.

 

한글자씩 끊어온 값을 아스키코드로 변환시키고 임의의 숫자와 비교하여 참과 거짓을 비교하는 과정을 거쳐가며 계속 질의를 보내어 일치하는 아스키코드를 찾아내는데 이러한 과정을 반복하여 결과들을 조합하여 원하는 정보를 얻어냄으로써 공격을 이루어지게 한다. 많은 비교 과정을 요하므로 악의적 목적을 가진 크래커들은 자동화된 툴을 사용하여 공격한다. 

 

 

Blind SQL Injection

- Time based SQL

Time Based SQL Injection 도 마찬가지로 서버로부터 특정한 응답 대신에 참 혹은 거짓의 응답을 통해서 데이터베이스의 정보를 유추하는 기법이다. 사용되는 함수는 MySQL 기준으로 SLEEP  BENCHMARK 이다.

 

위의 그림의 예시에서 로그인 폼에 주입이 되었으며 임의로 abc123 이라는 계정을 생성해 두었는데 악의적인 사용자가 abc123’ OR (LENGTH(DATABASE())=1 AND SLEEP(2)) – 이라는 구문을 주입한 상황이다. 

 주입된 구문에서, LENGTH(DATABASE()) = 1 가 참이면 SLEEP(2) 가 동작하고, 거짓이면 동작하지 않는다. 이를 통해서 숫자 1 부분을 조작하여 데이터베이스의 길이를 알아 낼 수 있다. 만약에 SLEEP 이라는 단어가 치환처리 되어있다면, 또 다른 방법으로 BENCHMARK  WAIT 함수를 사용 할 수 있다

BENCHMARK 는
BENCHMARK(1000000,AES_ENCRYPT('hello','goodbye'));
이런 식으로 사용하고 이 구문을 실행 하면 약 4.74초가 걸린다. 

 

 

Stored Procedure SQL Injection

- 저장된 프로시저에서의 SQL Injection

stored procedure는 일련의 쿼리들을 모아 하나의 함수처럼 사용하기 위한것이다.

공격에 사용되는 대표적인 저장 프로시저는 MS-SQL 에 있는 xp_cmdshell로 윈도우 명령어를 사용할 수 있게 된다. , 공격자가 시스템 권한을 획득 해야 하므로 공격난이도가 높으나 공격에 성공한다면, 서버에 직접적인 피해를 입힐 수 있는 공격이다.

 

 

Mass SQL Injection

- 다량의 SQL Injection 공격

 2008년에 처음 발견된 공격기법이다.

기존 SQL Injection 과 달리 한번의 공격으로 다량의 데이터베이스가 조작되어 큰 피해를 입히는 것을 의미한다. 보통 MS-SQL을 사용하는 ASP 기반 웹 애플리케이션에서 많이 사용되며, 쿼리문은 HEX 인코딩 방식으로 인코딩 하여 공격한다. 보통 데이터베이스 값을 변조하여 데이터베이스에 악성스크립트를 삽입하고, 사용자들이 변조된 사이트에 접속 시 좀비PC로 감염되게 하는데 이렇게 감염된 좀비 PC들은 DDoS 공격에 사용됩니다.

 

 

 

 

대응방안


  • 입력 값에 대한 검증 
  • Prepared Statement 구문 사용
  • Error Message 노출 금지
  • 웹 방화벽 사용

 

입력 값에 대한 검증

SQL Injection 에서 사용되는 기법과 키워드는 엄청나게 많습니다. 사용자의 입력 값에 대한 검증이 필요하다. 서버 단에서 화이트리스트 기반으로 검증해야 한다. 블랙리스트 기반으로 검증하게 되면 수많은 차단리스트를 등록해야 하고, 하나라도 빠지면 공격에 성공하게 되기 때문이다. 공백으로 치환하는 방법도 많이 쓰이는데, 이 방법도 취약한 방법이다. 예를 들어 공격자가 SESELECTLECT 라고 입력 시 중간의 SELECT가 공백으로 치환이 되면 SELECT 라는 키워드가 완성되게 된다. 공백 대신 공격 키워드와는 의미 없는 단어로 치환되어야 한다.

 

 

Prepared Statement 구문사용

 Prepared Statement 구문을 사용하게 되면, 사용자의 입력 값이 데이터베이스의 파라미터로 들어가기 전에DBMS가 미리 컴파일 하여 실행하지 않고 대기하는데 그 후 사용자의 입력 값을 문자열로 인식하게 하여 공격쿼리가 들어간다고 하더라도, 사용자의 입력은 이미 의미 없는 단순 문자열 이기 때문에 전체 쿼리문도 공격자의 의도대로 작동하지 않는다.

 

 

Error Message 노출 금지

공격자가 SQL Injection을 수행하기 위해서는 데이터베이스의 정보(테이블명, 컬럼명 등)가 필요하다. 데이터베이스 에러 발생 시 따로 처리를 해주지 않았다면, 에러가 발생한 쿼리문과 함께 에러에 관한 내용을 반환헤 주는데 여기서 테이블명 및 컬럼명 그리고 쿼리문이 노출이 될 수 있기 때문에, 데이터 베이스에 대한 오류발생 시 사용자에게 보여줄 수 있는 페이지를 제작 혹은 메시지박스를 띄우도록 하여야 한다.

 

웹 방화벽 사용

웹 공격 방어에 특화되어있는 웹 방화벽을 사용하는 것도 하나의 방법. 웹 방화벽은 소프트웨어 형, 하드웨어 형, 프록시 형 이렇게 세가지 종류로 나눌 수 있는데 소프트웨어 형은 서버 내에 직접 설치하는 방법이고, 하드웨어 형은 네트워크 상에서 서버 앞 단에 직접 하드웨어 장비로 구성하는 것이며 마지막으로 프록시 형은 DNS 서버 주소를 웹 방화벽으로 바꾸고 서버로 가는 트래픽이 웹 방화벽을 먼저 거치도록 하는 방법이다.

 

 

 

 

 


참고

link1 link2

NoSQL이란?

일명 "SQL만을 사용하지 않는 데이터베이스"
표 형식이 아니며, 관계형 테이블과는 다른 방식으로 데이터를 저장

 

NoSQL은 Not Only SQL의 약자로 기존 RDBMs 형태의 관계형 데이터베이스가 아닌 다른 형태의 데이터 저장 기술을 의미하며, 관계형 데이터 베이스의 한계를 극복하기 위한 데이터 저장소의 새로운 형태로, 수평적 확장성을 갖고 있다. 문서, 그래프, 키 값, 인 메모리, 검색을 포함해 다양한 데이터 모델을 사용한다. RDBMS가 클라이언트/서버 환경에 맞는 데이터 저장기술이라면, NoSQL은 클라우드 환경에 맞는 저장 기술이다.

 

 

 

 

 

 

NoSQL 데이터베이스를 사용해야하는 이유


NoSQL 데이터베이스는 탁월한 사용자 경험을 제공하기 위하여 유연성과 확장성을 비롯해 고성능의 매우 기능적인 데이터베이스를 필요로 하는 모바일, 웹이나 게이밍과 같은 다양한 현대적인 애플리케이션에 적합하다.

  • 유연성: NoSQL 데이터베이스는 일반적으로 유연한 스키마를 제공하여, 보다 빠르고 반복적인 개발을 가능하게 해준다. 이 같은 유연한 데이터 모델은 NoSQL 데이터베이스를 반정형 및 데이터에 이상적으로 만들어준다.
  • 확장성: NoSQL 데이터베이스는 일반적으로 고가의 강력한 서버를 추가하는 대신 분산형 하드웨어 클러스터를 이용해 확장하도록 설계되었다. 일부 클라우드 제공자들은 완전 관리형 서비스로서 이런 운영 작업을 보이지 않게 처리한다.
  • 고성능: NoSQL 데이터베이스는 특정 데이터 모델(문서, 키 값, 그래프 등) 및 엑세스 패턴에 대해 최적화되어 관계형 데이터베이스를 통해 유사한 기능을 충족하려 할 때보다 뛰어난 성능을 얻게 해준다.
  • 고기능성: NoSQL 데이터베이스는 각 데이터 모델에 맞추어 특별히 구축된 뛰어난 기능의 API와 데이터 유형을 제공한다.
SQL 장점
명확하게 정의된 스키마, 데이터 무결성 보장관계는 각 데이터를 중복없이 한번만 저장
SQL 단점
덜 유연함. 데이터 스키마를 사전에 계획하고 알려야 함. (나중에 수정하기 힘듬)관계를 맺고 있어서 조인문이 많은 복잡한 쿼리가 만들어질 수 있음대체로 수직적 확장만 가능함


NoSQL 장점
스키마가 없어서 유연함. 언제든지 저장된 데이터를 조정하고 새로운 필드 추가 가능데이터는 애플리케이션이 필요로 하는 형식으로 저장됨. 데이터 읽어오는 속도 빨라짐수직 및 수평 확장이 가능해서 애플리케이션이 발생시키는 모든 읽기/쓰기 요청 처리 가능
NoSQL 단점
유연성으로 인해 데이터 구조 결정을 미루게 될 수 있음데이터 중복을 계속 업데이트 해야 함데이터가 여러 컬렉션에 중복되어 있기 때문에 수정 시 모든 컬렉션에서 수행해야 함 (SQL에서는 중복 데이터가 없으므로 한번만 수행이 가능)

 

 

 

NoSQL의 특징


  1. NoSQL은 RDBMS와는 달리 데이터 간의 관계를 정의하지 않는다.
    • 가장 큰 특징 중 하나는 관계형 데이터 베이스인 RDBMS가 데이터의 관계를 Foreign Key 등으로 정의하고 이를 이용해 Join 등의 관계형 연산을 한다고 하면, NoSQL은 데이터 간의 관계를 정의하지 않는다. 데이터 테이블은 그냥 하나의 테이블이며 각 테이블 간의 관계를 정의하지 않고 일반적으로 테이블 간의 Join도 불가능하다.
  2. RDBMS에 비해 훨씬 더 대용량의 데이터를 저장할 수 있다.
    • RDBMS의 복잡도와 용량의 한계를 극복하기 위한 목적으로 등장한 만큼 페타바이트급의 대용량 데이터를 저장할 수 있다.
  3. 분산형 구조이다.
    • NoSQL은 기존 RDBMS와는 다르게 하나의 고성능 머신에 데이터를 저장하는 것이 아니라 일반적인 서버 수십 대를 연결해 데이터를 저장 및 처리하는 구조를 갖는다. 즉 분산형 구조를 통해 데이터를 여러 대의 서버에 분산해 저장하고 분산 시에 데이터를 상호 복제해 특정 서버에 장애가 발생했을 때에도 데이터 유실이나 서비스 중지가 없는 구조의 형태를 가진다.
  4. 고정되지 않은 테이블 스키마를 갖는다.
    • RDBMS와는 다르게 테이블의 스키마가 유동적이다. 데이터를 저장하는 컬럼은 각기 다른 이름과 다른 데이터 타입을 갖는 것이 허용된다.
    • 스키마란? 데이터베이스의 구조와 제약 조건에 관한 전반적인 명세를 기술한 메타데이터의 집합이다.

 

 

CAP 이론


1. 일관성(Consistency)

일관성은 동시성 또는 동일성이라고도 하며 다중 클라이언트에서 같은 시간에 조회하는 데이터는 항상 동일한 데이터임을 보증하는 것을 의미한다. 이것은 관계형 데이터베이스가 지원하는 가장 기본적인 기능이지만 일관성을 지원하지 않는 NoSQL 을 사용한다면 데이터의 일관성이 느슨하게 처리되어 동일한 데이터가 나타나지 않을 수 있다. 느슨하게 처리된다는 것은 데이터의 변경을 시간의 흐름에 따라 여러 노드에 전파하는 것을 말한다. 이러한 방법을 최종적으로 일관성이 유지된다고 하여 최종 일관성 또는 궁극적 일관성을 지원한다고 한다.

각 NoSQL 들은 분산 노드 간의 데이터 동기화를 위해서 두 가지 방법을 사용한다. 첫번째로 데이터의 저장 결과를 클라이언트로 응답하기 전에 모든 노드에 데이터를 저장하는 동기식 방법이 있다. 그만큼 느린 응답시간을 보이지만 데이터의 정합성을 보장한다. 두번째로 메모리나 임시 파일에 기록하고 클라이언트에 먼저 응답한 다음, 특정 이벤트 또는 프로세스를 사용하여 노드로 데이터를 동기화하는 비동기식 방법이 있다. 빠른 응답시간을 보인다는 장점이 있지만, 쓰기 노드에 장애가 발생하였을 경우 데이터가 손실될 수 있다.

 

2. 가용성(Availability)

가용성이란 모든 클라이언트의 읽기와 쓰기 요청에 대하여 항상 응답이 가능해야 함을 보증하는 것이며 내고장성이라고도 한다. 내고장성을 가진 NoSQL 은 클러스터 내에서 몇 개의 노드가 망가지더라도 정상적인 서비스가 가능하다.

몇몇 NoSQL 은 가용성을 보장하기 위해 데이터 복제(Replication)을 사용한다. 동일한 데이터를 다중 노드에 중복 저장하여 그 중 몇 대의 노드가 고장나도 데이터가 유실되지 않도록 하는 방법이다. 데이터 중복 저장 방법에는 동일한 데이터를 가진 저장소를 하나 더 생성하는 Master-Slave 복제 방법과 데이터 단위로 중복 저장하는 Peer-to-Peer 복제 방법이 있다.

 

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

분할 허용성이란 지역적으로 분할된 네트워크 환경에서 동작하는 시스템에서 두 지역 간의 네트워크가 단절되거나 네트워크 데이터의 유실이 일어나더라도 각 지역 내의 시스템은 정상적으로 동작해야 함을 의미한다.

 

 

 

 

 

 

 

NoSQL의 종류


  • Key-Value DB
    • Key와 Value의 쌍으로 데이터가 저장되는 유형으로써 Amazon의 Dynamo Paper에서 유래되었다. Riak, Vodemort, Tokyo 등의 제품이 알려져 있다.
가장 기본적인 형태의 NoSQL 이며 키 하나로 데이터 하나를 저장하고 조회할 수 있는 단일 키-값 구조를 갖는다. 단순한 저장구조로 인하여 복잡한 조회 연산을 지원하지 않는다. 또한 고속 읽기와 쓰기에 최적화된 경우가 많다. 사용자의 프로필 정보, 웹 서버 클러스터를 위한 세션 정보, 장바구니 정보, URL 단축 정보 저장 등에 사용한다. 하나의 서비스 요청에 다수의 데이터 조회 및 수정 연산이 발생하면 트랜잭션 처리가 불가능하여 데이터 정합성을 보장할 수 없다. 
ex) Redis

 

 

  • Wide Column DB
    • Big Table DB라고도 하며, Google의 BigTable Paper에서 유래되었다. Column Family 데이터 모델을 사용하고 있고, HBase, Cassandra, Hypertable이 이에 해당된다.
하나의 키에 여러 개의 컬럼 이름과 컬럼 값의 쌍으로 이루어진 데이터를 저장하고 조회한다. 모든 컬럼은 항상 타임 스탬프 값과 함께 저장된다.
구글의 빅테이블이 대표적인 예로 차후 컬럼형 NoSQL 은 빅테이블의 영향을 받았다. 이러한 이유로 Row key, Column Key, Column Family 같은 빅테이블 개념이 공통적으로 사용된다. 저장의 기본 단위는 컬럼으로 컬럼은 컬럼 이름과 컬럼 값, 타임스탬프로 구성된다. 이러한 컬럼들의 집합이 로우(Row)이며, 로우키(Row key)는 각 로우를 유일하게 식별하는 값이다. 이러한 로우들의 집합은 키 스페이스(Key Space)가 된다.
대부분의 컬럼 모델 NoSQL 은 쓰기와 읽기 중에 쓰기에 더 특화되어 있다. 데이터를 먼저 커밋로그와 메모리에 저장한 후 응답하기 때문에 빠른 응답속도를 제공한다. 그렇기 때문에 읽기 연산 대비 쓰기 연산이 많은 서비스나 빠른 시간 안에 대량의 데이터를 입력하고 조회하는 서비스를 구현할 때 가장 좋은 성능을 보인다. 채팅 내용 저장, 실시간 분석을 위한 데이터 저장소 등의 서비스 구현에 적합하다.

 

 

  • KDoument DB
    • Lotus Notes에서 유래되었으며, JSON, XML과 같은 Collection 데이터 모델 구조를 채택하고 있다. Mongo DB, Cough DB가 이 종류에 해당된다.
키-값 모델을 개념적으로 확장한 구조로 하나의 키에 하나의 구조화된 문서를 저장하고 조회한다. 논리적인 데이터 저장과 조회 방법이 관계형 데이터베이스와 유사하다. 키는 문서에 대한 ID 로 표현된다. 또한 저장된 문서를 컬렉션으로 관리하며 문서 저장과 동시에 문서 ID 에 대한 인덱스를 생성한다. 문서 ID 에 대한 인덱스를 사용하여 O(1) 시간 안에 문서를 조회할 수 있다.
대부분의 문서 모델 NoSQL 은 B 트리 인덱스를 사용하여 2 차 인덱스를 생성한다. B 트리는 크기가 커지면 커질수록 새로운 데이터를 입력하거나 삭제할 때 성능이 떨어지게 된다. 그렇기 때문에 읽기와 쓰기의 비율이 7:3 정도일 때 가장 좋은 성능을 보인다. 중앙 집중식 로그 저장, 타임라인 저장, 통계 정보 저장 등에 사용된다. ex) MongoDB

 

 

  • Graph DB
    • Euler & Graph Theory에서 유래한 DB이며, Nodes, Relationship, Key-Value 데이터 모델을 채용하고 있다. Neo4J 등의 제품이 있다.

 

 

 

 

 


References.

link1 link2

 

IPC란?

프로세스는 독립적으로 실행된다.
이처럼 독립적인 공간을 가진 프로세스 간 통신에 사용되는 기법이 IPC 통신이다.
프로세스는 커널이 제공하는 IPC 설비를 이용해 프로세스 간의 통신을 할 수 있게 된다.

 

 

  • IPC = Inter-Process Communication
  • 프로세스들 사이에 서로 데이터를 주고받는 행위

  • 위 그림처럼 우리가 사용하는 프로세스들은 모두 유저공간(user-space, user-mode)에서 개별로 OS로부터 할당받은 독립된 공간에서 운행중에 있다
  • 말한것 처럼 프로세스는 독립된 공간에서 운행하다보니 서로간에 통신이 어렵다는 문제가 있다
  • 이를 해결하고자 커널 영역(kernel-space, kernel-mode)에서 IPC(Inter-Process Communication)라는 프로세스들 간에 통신을 제공하고 있다
  • 이처럼 프로세스들은 커널이 제공하는 IPC 기술을 통해 프로세스간에 통신을 할 수 있다

 

 

 

 

 

 

 

IPC의 종류


PIPE (파이프)

  • 파이프는 두 개의 프로세스를 연결하고 하나의 프로세스는 데이터를 쓰기만 하고, 다른 프로세스는 데이터를 읽기만 한다
  • 부모 자식 간에 단방향 통신으로 자주 사용한다
  • 한쪽 방향으로만 통신이 가능한 PIPE의 특징 때문에 Half-Duplex(반이중) 통신 이라고도 불린다
  • PIPE는 반이중 통신이기에 하나의 통신선로는 읽기/쓰기 중 하나만 가능하므로 만약 읽기/쓰기, 즉 송/수신을 모두 하기 원한다면 두 개의 파이프를 만들어야 가능하다
  • read()와 write()가 기본적으로 block mode로 작동되기에 프로세스가 read 대기중이라면 read가 끝나기전에는 write를 할 수 없다

장점

  • PIPE는 간단하게 사용할 수 있다는 장점이 있다. 한쪽 프로세스는 단지 읽기만하고 다른 프로세스는 단지 쓰기만 하는 단순한 데이터 흐름에 적합

단점

  • Full-Duplex(전이중) 통신 방식으로 활용하려면 PIPE를 두개 만들어야 하는데, 구현이 꽤나 복잡해 질 수 있다 (굳이 전이중을 활용해야한다면 PIPE말고 다른 방법을 찾는게 효율적일 수 있다)
  • buffer가 상대적으로 작기때문에 overflow 될 확률이 높다 (read처리를 빨리빨리 해줘야한다)
  • 부모 자식 관계의 프로세스들 사이에서 가능

 

 

 

Named PIPE (익명 파이프)

  • Linux는 모든 것을 파일(fd)로 통하고 있다는 개념을 기억하고 보자
  • Named PIPE는 통신을 할 프로세스가 명확히 알 수 있는 경우 사용
  • 보통 PIPE는 부모자식간에 사용하고 Named PIPE는 전혀 모르는 상태의 프로세스들 사이에서 통신할 경우 사용
  • Named PIPE는 부모프로세스와 무관하게 전혀 다른 모든 프로세스들 사이에서 통신이 가능한데, 이유는 프로세스간에 통신을 위해 이름이 있는 파일을 매개체로 사용하기 때문
  • mkfifo를 통해 Named PIPE를 생성하는데, mkfifo가 성공하면 이름이 명명된 파일이 생성되고 이를 활용해서 프로세스 간에 통신이 이루어짐

장점

  • 기본 PIPE와 비슷

단점

  • 읽기/쓰기가 동시에 이루어지지 않음, 단방향 통신, read-only or write-only
  • 기본 PIPE와 비슷
PIPE 와 Named PIPE

공통점
먼저 입력된 데이터가 먼저 전달되는 흐름을 가진다는 측면에서 동일한 데이터 흐름 메커니즘을 가진다

차이점
Named PIPE는 사용할 PIPE를 명명할 수 있다는 점
PIPE는 사용할 PIPE를 명명할 수 없다
(그렇기 때문에 PIPE는 익명 PIPE라 부른다)


추가 설명
익명 파이프(PIPE)는 데이터 통신을 할 프로세스가 명확하게 알 수 있을 때 사용
송신할 프로세스는 수신할 프로세스를 알고, 수신할 프로세스는 송신할 프로세스를 아는 경우
가장 대표적인 예가 부모프로세스와 자식프로세스간에 데이터 통신을 하고자 할 때 부모 프로세스와 자식 프로세스는 서로를 명확히 알고 있으므로 굳이 파이프에 이름을 줄 필요가 없을 것이다

반면, 자식과 부모 관계가 아닌 전혀 모르는 프로세스들 사이에서 pipe를 이용해서 통신을 해야하는 경우는 우리가 생판 모르는 사람과 대화를 하려면 이름을 알아야 하듯 pipe에 이름을 주어져야 한다, 그것이 Named PIPE를 만든 이유이다

 

 

 

 

Message Queue (메시지 큐)

  • FIFO(First-In First-Out, 선입선출) 자료구조를 가지는 통신설비로 커널에서 관리
  • 입출력 방식으로보면 위에 Named PIPE와 동일하다 할 수 있다
  • 차이점이라면, Named PIPE는 데이터의 흐름이라면 Message Queue는 메모리 공간이라는 점
  • 어디서나 물건을 꺼낼 수 있는 컨테이너 벨트와 같다 보면 된다
  • Message Queue에 쓸 데이터에 번호를 붙힘으로써 다수의 프로세스가 동ㅇ시에 데이터를 쉽게 다룰 수 있다

장점

  • 비동기 방식이기에 방대한 처리량이 있다면 큐에 넣은 후 나중에 처리 할 수 있다
  • 다수의 프로세스들이 큐에 메시지를 보낼 수 있고 다수의 프로세스들이 큐로부터 메시지를 꺼낼 수 있다
  • 분산처리 및 경쟁처리 방식에 사용할 수 있다
  • (비동기, 비동조, 탄력성, 과잉, 확장성이 있는데 이건 다른 포스트 참조해도 충분할 거 같다)

단점

  • 메시지가 정말 잘 전달되었는지 알 수 없다
  • 큐에 데이터를 넣고 나오는 과정에서 오버헤드가 발생 할 수 있다
  • 데이터가 많이 쌓일수록 추가적인 메모리 자원이 필요하다

 

 

 

 

Shared Memory (공유메모리)

  • 데이터 공유 방법에는 크게 2가지가 있는데,
  1. 통신을 이용해서 데이터를 주고 받는 방법 (ex. PIPE, Named PIPE, Message Queue, ...)
  2. 데이터를 공유, 즉 함께 사용하는 것 (ex. Shared Memory, ...)
    • 즉, 공유메모리가 데이터 자체를 공유하도록 지원하는 설비이다
    • Shared Memory(공유 메모리)는 프로세스간 메모리 영역을 공유해서 사용할 수 있도록 허용
    • 프로세스가 공유 메모리 할당을 커널에 요청하면 커널은 해당 프로세스에 메모리 공간을 할당해 주게되고, 이후 어떤 프로세스건 해당 메모리영역에 접근 할 수 있다
    장점
    • 공유 메모리는 중개자 없이 곧바로 메모리에 접근할 수 있기 때문에 모든 IPC중에서 가장 빠르게 작동한다
    • (다시말해, 커널메모리영역에서 관리하기에 빠르게 접근 가능)
    단점
    • 메시지 전달 방식이 아니기에 데이터를 읽어야하는 시점을 알 수 없다
    • 커널 설정에 종속적이기에 사용하기전에 커널에서 허용하고 있는 공유메모리 사이즈를 확인해야 한다

 

 

 

Semaphore (세마포어)

  • PIPE, Named PIPE, Message Queue와 같은 다른 IPC 설비들이 대부분 프로세스간 메시지 전송을 목적으로 하는데 반해,
  • Semaphore는 프로세스 간 데이터를 동기화하고 보호하는데 그 목적이 있다
  • 프로세스간 메시지 전송을 하거나 공유메모리를 통해 데이터를 공유하게 될 경우 발생하는 문제가 공유된 자원에 다수의 프로세스가 동시에 접근하면 안되며 단지 하나의 프로세스만 접근가능하게 해주는것이 세마포어(Semaphore) 이다
  • 즉, 운영 체계 또는 프로그램 작성 내에서 공유 자원에 대한 접속을 제어하기 위해 사용되는 신호
  • 한 프로세스가 사용하고 있는 동안에 세마포어를 세워서 다른 프로세스를 대기시키고 사용이 끝나면 해제시키는 방법으로 사용
뮤텍스 Mutex 세마포어 Semaphore
공유된 자원의 데이터를 여러 스레드가 접근하는 것을 막는 것 공유된 자원의 데이터를 여러 프로세스가 접근하는 것을 막는 것
상태가 0, 1 두개 (이진 세마포어) 세마포어는 뮤텍스가 될 수 있다
뮤텍스 소유 중인 스레드가 뮤텍스를 해제 세마포어를 소유하지 않는 스레드가 세마포어 해제
프로세스 범위를 가지고 종료 될 때, 자동 Clean 파일 시스템 상의 파일 형태로 존재
동기화 대상이 오직 하나일 때 동기화 대상이 하나 이상일 때
(한가지 예를 들자면, 화장실에 갔을때 화장실 칸을 생각하면 된다. 화장실 한 칸에 대해 관리를 하는것이 뮤텍스이고 화장실 자체를 관리하는게 세마포어가 된다)

장점

  • 많은 Thread들은 크리티컬 섹션을 허락받아야 한다. 즉, 크리티컬 섹션에서 충돌이 나지 않는다

단점

  • 많은 Thread들은 block을 당한다. 즉, CPU가 가만히 waiting하는 시간 낭비가 발생할 수 있다

 

 

 

 

Memory Map (메모리 맵)

메모리 맵도 공유 메모리와 마찬가지로 메모리를 공유한다는 측면에서는 비슷하다

    • 차이점은 메모리 맵은 열린 파일을 메모리에 맵핑시켜서 공유한다는 점
    • 파일(fd)는 리눅스의 시스템의 전역적인 자원이므로 즉, 모두 공유할수 있는 자원이므로 서로 다른 프로세스들끼리 데이터를 공유하는데 문제가 없음을 예상할 수 있다
    장점
    • 데이터가 메모리에 이미 올라와있는 것처럼 간단하게 접근 할 수 있다
    • 일반적인 파일 IO에 비해 나은 성능을 보여준다
    • 비동기 IO를 사용하지만 시스템에서 처리해주기 때문에 스레드 문제를 걱정할 필요 없다
    단점
    • 일반 파일 IO에 비해 상당히 많은 메모리를 요구
    • 많은 데이터를 얼마나 오랫동안 메모리에 둘 것인지 컨트롤할 수 없다

 

 

 

 

 

Socket (소켓, UDS = Unix Domain Socket)

  • 같은 도메인 내에서 연결 될 수 있고 프로세스들 사이의 통신을 가능하게 한다
  • 서버단에서는 bind, listen, accept 진행해 소켓 연결을 위한 준비를 한다
  • 클라이언트 단에서는 connect을 통해 서버에 요청하고 연결이 수립 된 후에서는 socket에 send 함으로써 데이터를 주고 받는다.
  • 연결이 끝나면 반드시 close()로 clear 한다
  • 즉, 네트워크를 통해 프로세스간에 통신을 진행한다

장점

  • 서버/클라이언트 환경을 구축하는데 용이하다
  • Internet Socket인 경우 데이터 유실이 발생할 수 있지만, Unix Domain소켓은 PIPE와 같은 형태로 이루어지고 같은 시스템에서 교환이 일어나므로 패킷이 유실되거나, 순서가 바뀌는 등 문제가 발생하지 않을거라 장담 할 수 있다
  • 범용적인 IPC로써 양방향 통신이 가능하다
  • 패킷 단위로 주고 받음으로 직관적으로 이해하기 쉬운 코드를 만들 수 있다

단점

  • Internet UDP와는 달리 경로를 지정할 수 없다 (다중의 클라이언트를 받아들이는 서버의 경우 문제가 될 수 있다)

 

 

 

 

 

 

 


References.

 

link1 link2

 

 

OSI 7계층

표준화를 통해 이질적인 포트 문제나 프로토콜 등으로 인한 문제를 해결하여 비용을 절감했다.
또한, 계층별의 기능과 통신 과정을 단계별로 나누어서 쉽게 알 수 있고, 특정한 곳에 이상이 생기면 그 단계만 수정할 수 있기 때문에 편리하다.



 

 

 

1) 물리(Physical)

리피터, 케이블, 허브 등

주로 전기적, 기계적, 기능적인 특성을 이용해서 통신 케이블로 데이터를 전송하는 역할을 한다.

 

 

 

 

 

 

 

 

 

2) 데이터 링크(Data Link)

브릿지, 스위치 등

물리 계층을 통해 송, 수신되는 정보의 오류와 흐름을 관리하여 안전한 정보의 전달을 수행할 수 있도록 도와주는 역할을 한다.

MAC 주소를 이용해 통신한다.

Frame에 MAC 주소를 부여하고 에러검출, 재전송, 흐름 제어를 진행한다.

 

 

 

 

 

 

 

 

 

3) 네트워크(Network)

라우터, IP

여러 개의 노드를 거칠 때마다 경로를 찾아주는 역할을 하며, 다양한 길이의 데이터를 목적지까지 가장 안전하고 빠르게 전달하는 기능을 담당한다. (전송 계층이 요구하는 서비스 품질을 제공하기 위한 기능적, 절차적 수단을 제공한다.)

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

라우팅, 흐름 제어, 오류 제어, 세그먼테이션 등을 수행한다.

 

 

 

 

 

 

 

 

4) 전송 계층(Transport)

TCP, UDP

TCP, UDP 프로토콜을 통해 통신을 활성화 한다. 포트를 열어두고, 프로그램들이 전송을 할 수 있도록 제공해준다. 이를 통해 양 끝 단의 사용자들이 데이터를 주고 받을 수 있다.

  • TCP : 신뢰성, 연결 지향적
  • UDP : 비신뢰성, 비연결성, 실시간

 

TCP 프로토콜(Transmission Control Protocol)

 

OSI 계층모델의 관점에서 전송 계층(4계층)에 해당

 

양종단 호스트 내 프로세스 상호 간에 신뢰적인 연결지향성 서비스를 제공

- IP의 비신뢰적인 최선형 서비스에다가 신뢰적인 연결지향성 서비스를 제공하게 됨

. 신뢰적인 전송을 보장함으로써, 어플리케이션 구현이 한층 쉬워지게 됨

 

1. 신뢰성 있음 (Reliable)

 

패킷 손실, 중복, 순서바뀜 등이 없도록 보장

TCP 하위계층인 IP 계층의 신뢰성 없는 서비스에 대해 다방면으로 신뢰성을 제공

 

2. 연결지향적 (Connection-oriented)                                        ☞ TCP 연결

 

같은 전송계층의 UDP가 비연결성(connectionless)인 것과는 달리, TCP는 연결지향적 임

이 경우, 느슨한 연결(Loosly Connected)을 갖으므로 강한 연결을 의미하는 

가상회선이라는 표현 보다는 오히려 연결지향적이라고 말함

연결 관리를 위한 연결설정 및 연결해제 필요          ☞ TCP 연결설정, TCP 연결종료

양단간 어플리케이션/프로세스는 TCP가 제공하는 연결성 회선을 통하여 서로 통신

 

 

 

UDP 프로토콜(User Datagram Protocol)

 

전송 계층의 통신 프로토콜의 하나 (TCP에 대비됨)

- 신뢰성이 낮은 프로토콜로써 완전성을 보증하지 않으나,  

- 가상회선을 굳이 확립할 필요가 없고 유연하며 효율적 응용의 데이타 전송에 사용

 

1. 비연결성이고, 신뢰성이 없으며, 순서화되지 않은 Datagram 서비스 제공 

- 메세지가 제대로 도착했는지 확인하지 않음 (확인응답 없음)

- 수신된 메세지의 순서를 맞추지 않음 (순서제어 없음) 

- 흐름 제어를 위한 피드백을 제공하지 않음 (흐름제어 없음)

- 검사합을 제외한 특별한 오류 검출 및 제어 없음 (오류제어 거의 없음)

UDP를 사용하는 프로그램 쪽에서 오류제어 기능을 스스로 갖추어야 함

- 데이터그램 지향의 전송계층용 프로토콜 (논리적인 가상회선 연결이 필요없음)

비연결접속상태 하에서 통신 

 

2. 실시간 응용 및 멀티캐스팅 가능

- 빠른 요청과 응답이 필요한 실시간 응용에 적합

- 여러 다수 지점에 전송 가능 (1:多)

 

3. 헤더가 단순함

- UDP는 TCP 처럼 16 비트의 포트 번호를 사용하나,

- 헤더는 고정크기의 8 바이트(TCP는 20 바이트) 만 사용

즉, 헤더 처리에 많은 시간과 노력을 요하지 않음

 

 

 

 

 

 

 

 

5)세션(Session)

API, Socket

데이터가 통신하기 위한 논리적인 연결을 말한다. 통신을 하기위한 대문이라고 보면 된다.

하지만 4계층에서도 연결을 맺고 종료할 수 있기 때문에 우리가 어느 계층에서 통신이 끊어 졌나 판단하기는 한계가 있다. 

그러므로 세션 계층은 4 계층과 무관하게 응용 프로그램 관점에서 봐야 한다. 

세션 설정, 유지, 종료, 전송 중단시 복구 등의 기능이 있다.

 

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

동시 송수신 방식(duplex), 반이중 방식(half-duplex), 전이중 방식(Full Duplex)의 통신과 함께, 체크 포인팅과 유휴, 종료, 다시 시작 과정 등을 수행한다. 

이 계층은 TCP/IP 세션을 만들고 없애는 책임을 진다.

 

-> 

통신하는 사용자들을 동기화하고 오류복구 명령들을 일괄적으로 다룬다. 

통신을 하기 위한 세션을 확립/유지/중단 (운영체제가 해줌)

 

 

 

 

 

 

 

 

 

6) 표현(Presentation)

JPEG, MPEG 등

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

코드 간의 번역을 담당하여 사용자 시스템에서 데이터의 형식상 차이를 다루는 부담을 응용 계층으로부터 덜어준다.

파일 인코딩, 명령어를 포장, 압축, 암호화한다.

 

 

 

 

 

 

 

 

7) 응용(Application)

HTTP, FTP, DNS 등

최종 목적지로 응용 프로세스와 직접 관계하여 일반적인 응용 서비스를 수행한다.

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

Git이란?


git은 컴퓨터 파일의 변경 사항을 추적하고 여러 명의 사용자들 간에 해당 파일들의 작업을 조율하기 위한 오픈소스 분산 버전 관리 시스템이다.

주로 소프트웨어를 개발하며 코드 관리에도 사용되지만 어떠한 프로젝트의 변경사항을 지속적으로 추적하기 위해 사용될 수 있다. (나는 보통 소스코드 관리와 변경사항 추적을 목적으로 사용하고 있다)

 

 

 

 

 

Git-flow란?


Git-flow는 Git이 활성화가 될 2010년 정도에 Vincent Driessen이라는 사람이 만든 Git을 사용한 개발 작업 절차이다. Git-flow라고 해서 프로그램 같지만 프로그램이 아닌 약속, 규칙같은 개념이다.

Vincent Driessen또한 Git-flow는 완벽한 방법론이 아닌, 각자 팀에 맞는 개발 환경에 따라 변형해서 사용하는 것이 좋다고 언급했다.

 

 

 

 

Git-flow의 브랜치


Git-flow의 브랜치는 다음과 같이 구성되어 있다.

  • master 와 devleop브랜치
    • master와 develop브랜치가 존재하고, develop브랜치는 master 브랜치에서 시작된 브랜치.
    Develop브랜치
    • develop브랜치에는 상시로 버그를 수정한 커밋들이  추가되게 된다.
    • 새로운 기능을 추가하는  경우  develope 브랜치에서 시작하는 feature브랜치를 생성
    Feature브랜치
    • 이 feature브랜치는 기능 추가 작업이 완료되었다면, develop 브랜치로 merge 
    • 새로운 기능을 추가하는  경우  develope 브랜치에서 시작하는 feature브랜치를 생성
    release 브랜치
    • develop브랜치에 이번 버전에 포함하는 모든 기능이 merge되었다면 , QA를 위해 develop브랜치에서 release브랜치를 생성
    •  QA를 무사히 통과하게되면 relase브랜치를 master와 develop브랜치로  merge
    • QA를  진행하면서 발생한 버그들은 모두 release브랜치에 수정

 

 

master와 develop은 항상 유지되는 메인 브랜치들이며 그 외에 feature, release, hotfixes는 필요한 기간에만 유지되는 보조 브랜치들이다.

 

 

다음은 Vincent Driessen의 블로그에서 Git-flow를 설명할때 사용하는 이미지이다.

 

타임라인을 보면 알겠지만 처음에는 master로 시작해 develop브랜치만 존재한다.

아직 소프트웨어를 배포하지 않았기 때문에 develop브랜치에서 개발을 시작한다.

개발을 진행하다가 추가로 필요한 기능이 생기면 feature브랜치를 생성해 작업을 한다. 

feature브랜치는 언제나 develop브랜치로부터 시작된다.

 

기능을 다 개발했다면 작업한 feature브랜치를 검토한 후 develop브랜치에 병합한다.

이제 이번 버전에서 필요한 기능이 모두 개발되었다면 QA를 위해 release브랜치를 생성한다.

QA를 진행하며 발견하는 버그들은 모두 이 release브랜치를 통해 fix된다.

 

이제 QA과정이 모두 끝났다면 release브랜치를 master와 develop브랜치로 병합한다.

그리고 master브랜치에 버전명시를 위한 태그를 생성 후 배포한다.

 

여기까지가 기본적인 개발 단계에서의 Git-flow이다.

 

 

 

 

하지만 배포 후에도 버그가 발생하는 경우가 있다.

 

그렇다면 긴급하게 수정을 해야하는데 그럴 경우 hofixes브랜치를 생성해 발생한 버그를 수정한다.

버그 수정이 완료되었다면 release브랜치가 완료됬을 때와 같이 master develop브랜치로 병합 후 버그 수정을 완료했다는 태그를 추가한다.

 

 

 

 

 

버전 태그


보통 소프트웨어를 표시할때 버전은 x.x.x의 형태로 이루어진다. 이 숫자들은 무엇을 의미할까? 버전의 가장 첫 번째 숫자는 Major Version을 의미한다. Major Version은 보통 1로 시작해서 소프트웨어 전체적으로 큰 변화가 생겼을때 버전 업을 한다. 두 번째 숫자는 Minor Version을 의미한다. Miner Version은 보통 0으로 시작해서 없던 기능의 추가나 기존 기능의 수정 등의 변화가 발생했을 때 버전 업을 한다. 마지막 세 번째 자리는 Build or Maintenance Version이라고 하며 자잘한 버그나 내부적 코드 보안 등의 변화가 발생했을 때 버전 업을 한다. 이 버전은 0으로 시작하지만 생략하는 경우도 있다.

 

 

 

 

 


Reference.

link1 link2

'🔥 > 기타 등등 🎸' 카테고리의 다른 글

[개발상식] MVC 패턴이란  (0) 2021.08.18

+ Recent posts