인덱스

인덱스의 필요성

  • 인덱스는 데이터를 빠르게 찾을 수 있는 하나의 장치이다.

B-트리

  • 인덱스는 보통 B-트리라는 자료 구조로 이루어져있다.
  • B-트리는 이진 탐색 트리의 일종으로 탐색 성능을 높이기 위해 균형있게 높이를 유지하는 균형 트리 입니다.
  • 규칙에 따라 여러개의 자식노드를 가질 수 있다.

인덱스가 효율적인 이유와 대수확장성

  • 인덱스가 효율적인 이유는 효율적인 단계를 거쳐 모든 요소에 접근할 수 있는 균형 잡힌 트리 구조와 트리 깊이의 대수확장성 때문이다.

인덱스 만드는 방법

  • MySQL의 경우 클러스터형 인덱스와 세컨더리 인덱스가 있다.
  • 클러스터형 인덱스
    • 테이블당 하나를 설정할 수 있다.
    • primary key 옵션으로 기본키를 만들면 클러스터형 인덱스를 생성할 수 있다.
    • 기본키가 아닌 unique not null 옵션을 붙이면 클러스터형 인덱스로 만들 수 있다.
  • 세컨더리 인덱스
    • 명령어를 기반으로 만들면 세컨더리 인덱스를 만들 수 있다.
    • 여러개의 필드 값을 기반으로 쿼리를 많이 보낼 때 생성해야 하는 인덱스

인덱스 최적화 기법

  • 인덱스는 비용이다.
    • 인덱스는 두 번 탐색하도록 강요한다. 인덱스 리스트 그다음 컬렉션 순으로 탐색하기 때문에 관련 읽기 비용이 들게 된다.
    • 컬렉션이 수정되었을 때 인덱스도 수정되어야 한다. 이때 많은 비용이 발생
    • 그렇기 때문에 쿼리에 있는 필드에 무작정 인덱스를 설정하는 것은 답이 아니다.
    • 데이터 양이 많을수록 인덱스를 사용하는 것은 비효율적이다.
  • 항상 테스팅 하라
    • EXPLAIN 함수를 통해 인덱스를 만들고 ㅜ커리를 보낸 이후에 테스팅을 하며 걸리는 시간을 최소화 해야 한다.
  • 복합 인덱스는 같음, 정렬, 다중 값, 카디널리티 순이다.
    • 여러 필드를 기반으로 조회를 할 때 복합 인덱스를 생성하는데, 이 인덱스를 생성할 때는 순서가 있고, 생성 순서에 따라 인덱스 성능이 달라진다. 같음, 정렬, 다중값, 카디널리티 순으로 생성해야 한다.

조인

  • 하나의 테이블이 아닌 두 개 이상의 테이블을 묶어서 하나의 결과물을 만드는 것을 말한다.
  • 내부 조인(inner join)
    • 왼쪽 테이블과 오른쪽 테이블의 두 행이 모두 일치하는 행이 있는 부분만 표기(교집합)
  • 왼쪽 조인(left outer join)
    • 왼쪽 테이블의 모든 행이 결과 테이블에 표기된다.
  • 오른쪽 조인(right outer join)
    • 오른쪽 테이블의 모든 행이 결과 테이블에 표기된다.
  • 합집합 조인(full outer join)
    • 두 테이블을 기반으로 조인 조건에 만족하지 않는 행까지 모두 표기한다.

내부 조인

  • 두 테이블 간의 교집합을 나타낸다.
  • SELECT * FROM tableA A INNER JOIN tableB B ON A.key = B.key

왼쪽 조인

  • 테이블 B의 일치하는 부분의 레코드와 함께 테이블 A를 기준으로 완전한 레코드 집합을 생성
  • 만약 B에 일치하는 항목이 없으면 해당 값은 null 값이 된다.
  • SELECT * FROM tableA A LEFT JOIN tableB B ON A.key = B.key

오른쪽 조인

  • 테이블 A에서 일치하는 부분의 레코드와 함께 테이블 B를 기준으로 완전한 레코드 집합을 생성
  • A에 일치하는 항목이 없으면 해당 값은 NULL이 된다.
  • SELECT * FROM tableA A RIGHT JOIN tableB B ON A.key = B.key

합집합 조인

  • 양쪽 테이블에서 일치하는 레코드와 함께 테이블 A와 테이블 B의 모든 레코드 집합을 생성
  • 일치하는 항목이 없으면 누락된 쪽에 NULL 포함
  • SELECT * FROM tableA A FULL OUTER JOIN tableB B ON A.key = B.key

조인의 원리

중첩 루프 조인

  • 중첩 for 문과 같은 원리로 조건에 맞는 조인을 하는 방법
  • 랜덤 접근에 대한 비용이 많아 대용량 테이블에서는 사용하지 않음
  • ex) 테이블 a에서 행 하나를 읽고 다음 반복문에서 조건에 맞는 레코드를 찾음

정렬 병합 조인

  • 각각의 테이블을 조인할 필드 기준으로 정렬하고 정렬이 끝난 이후에 조인 작업을 수행
  • 조인 시에 적절한 인덱스가 없고 대용량 테이블들을 조인 조건으로 범위 비교 연산자가 있을 때 사용

해시 조인

  • 해시 테이블을 기반으로 조인
  • 두 테이블을 조인 시에 하나의 테이블이 메모리에 온전히 들어간다면 중첩 루피 조인보다 더 효율적이다.
  • 동등(=) 조인 에서만 사용할 수 있다.

'Computer science > 데이터베이스' 카테고리의 다른 글

트랜잭션과 무결성  (2) 2023.09.06

트랜잭션

  • 데이터베이스에서 하나의 논리적 기능을 수행하기 위한 작업의 단위
  • ACID 특징을 가짐
    • 원자성
    • 일관성
    • 독립성
    • 지속성

원자성

  • 트랜잭션과 관련된 일이 모두 수행되었거나 되지 않았음을 보장하는 특징
  • 트랜잭션 단위로 여러 로직들을 묶을 때 외부 API를 호출하는 것이 있으면 안된다.
    • 만약 있다면 롤백이 일어났을 때 어떻게 해야 할 것인지에 대한 해결 방법이 있어야 하고 트랜잭션 전파를 신경써서 관리해야 한다. → 스프링의 @transactional이 이를 지원해줌
  • commit
    • 여러 쿼리가 성공적으로 처리되었다고 확정하는 명령
  • rollback
    • 트랜잭션으로 처리한 하나의 묶음 과정을 일어나기 전으로 돌리는 (취소)명령
  • 트랜잭션 전파
    • 트랜잭션을 수행할 때 커넥션 단위로 수행하기 때문에 커넥션 객체를 넘겨서 수행해야 한다.
      • 하지만 이를 매번 넘겨주기가 어렵고, 귀찮다.
    • 이를 넘겨서 수행하지 않고 여러 트랜잭션 관련 메서드의 호출을 하나의 트랜잭션에 묶이도록 하는 것을 트랜잭션 전파라고 한다.

일관성

  • 허용된 방식으로만 데이터를 변경해야 하는 것을 의미

격리성

  • 트랜잭션 수행 시 서로 끼어들지 못하는 것을 의미한다.
  • 복수의 병렬 트랜잭션은 서로 격리되어 마치 순차적으로 실행되는 것처럼 작동되어야 하고 데이터베이스는 여러 사용자가 같은 데이터에 접근할 수 있어야 한다.
  • 순차적으로 하면 쉽게 되겠지만 성능이 나빠진다.
  • 격리성은 여러 개의 수준으로 나뉘어 격리성을 보장한다.

 💡 격리성 높음, 동시성 낮음

  1. SERIALIZABLE
  2. REPEATABLE_READ
  3. READ_COMMITTED
  4. READ_UNCOMMITTED

 💡 격리성 낮음, 동시성 높음

  • 밑으로 갈수록 동시성이 강해지지만 격리성은 약해지고 위로 갈수록 동시성은 약해지고 격리성은 강해진다.

격리 수준에 따라 발생하는 현상

  • 팬텀 리드
    • 한 트랜잭션 내에서 동일한 쿼리를 보냈을 때 해당 조회 결과가 다른 경우
  • 반복 가능하지 않은 조회
    • 한 트랜잭션 내의 같은 행에 두 번 이상 조회가 발생했는데, 그 값이 다른 경우를 가리킨다.
    • 팬텀 리드와 다른 점은 행 값이 달라질 수 있지만 팬텀리드는 다른 행이 선택될 수도 있다는 점이다.
  • 더티 리드
    • 한 트랜잭션이 실행 중일 때 다른 트랜잭션에 의해 수정되었지만 아직 커밋되지 않은 행의 데이터를 읽을 수 있을 때 발생

격리 수준

  • SERIALIZABLE
    • 트랜잭션을 순차적으로 진행시키는 것
    • 동시에 같은 행에 접근 불가
    • 성능이 가장 떨어지는 격리 수준
  • REPEATABLE_READ
    • 하나의 트랜잭션이 수정한 행을 다른 트랜잭션이 수정할 수 없도록 막아준다.
    • 새로운 행을 추가하는 것은 막지 않는다.
  • READ_COMMITTED
    • 가장 많이 사용되는 격리 수준
    • 다른 트랜잭션이 커밋하지 않은 정보는 읽을 수 없다.
      • 커밋 완료된 데이터에 대해서만 조회를 허용한다.
    • 어떤 트랜잭션이 접근한 행을 다른 트랜잭션이 수정할 수 있다.
  • READ_UNCOMMITTED
    • 가장 낮은 격리 수준
    • 하나의 트랜잭션이 커밋되기 이전에 다른 트랜잭션에 노출되는 문제가 있다.
      • 하지만 가장 빠르다.
    • 되도록 사용하지 않는 것이 이상적이다.
      • 어림잡아 집계하는 데에 사용하면 좋다.

지속성

  • 성공적으로 수행한 트랜잭션은 영원히 반영되어야 하는 것을 의미한다.
    • 이를 위해 체크섬, 저널링, 롤백 기능을 제공

무결성

  • 데이터의 정확성, 일관성, 유효성을 유지하는 것을 말한다.

개체 무결성

  • 기본키로 선택된 필드는 빈 값을 허용하지 않는다.

참조 무결성

  • 서로 참조 관계에 있는 두 테이블의 데이터는 항상 일관된 값을 유지해야 한다.

고유 무결성

  • 특성 속성에 대해 고유한 값을 가지도록 조건이 주어진 경우 그 속성 값은 모두 고유한 값을 가진다.

NULL 무결성

  • 특정 속성 값에 NULL이 올 수 없다는 조건이 주어진 경우 그 속성 값은 NULL이 될 수 없다는 제약조건

'Computer science > 데이터베이스' 카테고리의 다른 글

인덱스 / 조인  (1) 2023.09.07

프로세스

  • 프로세스는 컴퓨터에서 실행되고 있는 프로그램을 말하며 CPU 스케줄링의 대상이 되는 작업이라는 용어와 같은 의미로 쓰인다.
  • 쓰레드는 프로세스 내 작업의 흐름을 지칭한다.

프로세스의 상태

생성

  • 생성 상태는 프로세스가 생성된 상태를 의미하며 fork(), exec() 함수를 통해 생성한다. 이때 PCB가 할당된다
  • fork()
    • 부모 프로세스의 주소 공간을 그대로 복사하며, 새로운 자식 프로세스를 생성하는 함수
    • 주소 공간만 복사할 뿐이지 부모 프로세스의 비동기 작업 등을 상속하지는 않는다.
  • exec()
    • 새롭게 프로세스를 생성하는 함수

대기 상태

  • ready(대기 상태)는 메모리 공간이 충분하면 메모리를 할당받고 아니면 아닌 상태로 대기하고 있으며 CPU 스케줄러로부터 CPU 소유권이 넘어오기를 기다리는 상태.

대기 중단 상태

  • 메모리 부족으로 일시 중단된 상태

실행 상태

  • CPU 소유권과 메모리를 할당받고 인스트럭션을 수행 중인 상태를 의미

중단 상태

  • 어떤 이벤트가 발생한 이후 기다리며 프로세스가 차단된 상태
  • I/O 디바이스에 의한 인터럽트로 이런 현상이 발생하기도 한다.

일시 중단 상태

  • 중단된 상태에서 프로세스가 실행되려고 했지만 메모리 부족으로 일시 중단된 상태이다.

종료 상태

  • 메모리와 CPU 소유권을 모두 놓고 가는 상태를 말한다.
  • 부모 프로세스가 자식 프로세스를 강제시키는 비자발 종료로 종료되는 것도 있다.
  • 사용자가 process, kill 등 여러 명령어로 프로세스를 종료할 때 발생

프로세스 메모리 구조

https://velog.io/@cchloe2311/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0

  • 운영체제는 프로세스에 적절한 메모리를 할당하는데 다음 구조를 기반으로 할당

스택

  • 지역변수, 매개변수, 함수가 저장되고 컴파일 시에 크기가 결정되며 동적인 특징을 갖는다.
  • 스택 영역은 함수가 함수를 재귀적으로 호출하면서 동적으로 크기가 늘어날 수 있고, 이때 힙 과 스택의 메모리 영역이 겹치면 안되기 때문에 힙과 스택 사이의 공간을 비워 놓는다.

  • 동적 할당할 때 사용되며 런타임 시 크기가 결정된다.

데이터 영역

  • 전역변수, 정적변수가 저장, 정적인 특징을 갖는 프로그램이 종료되면 사라지는 변수가 들어있는 영역
  • BSS
    • 초기화 되지 않은 변수가 0으로 초기화되어 저장된다.
  • DATA
    • 0이 아닌 다른 값으로 할당된 변수들이 저장된다.

코드 영역

  • 프로그램에 내장되어 있는 소스 코드가 들어가는 영역

PCB

  • 프로세스에 대한 메타데이터를 저장한 데이터를 뜻한다.
    • 프로세스를 나타내기 위한 모든 정보들
  • 프로세스 제어 블록이라고도 한다.
  • 프로세스가 생성되면 운영체제는 해당 PCB를 생성
  • 커널 스택의 가장 앞부분에서 관리된다. (일반 사용자가 접근하지 못함)

컨텍스트 스위칭

https://www.crocus.co.kr/1364

  • PCB를 교환하는 과정
  • 한 프로세스에 할당된 시간이 끝나거나 인터럽트에 의해 발생

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

메모리  (0) 2023.08.10

CPU는 메모리에 올라와 있는 프로그램의 명령어들을 실행할 뿐이다.

메모리 계층

  • 레지스터
    • CPU 안에 있는 작은 메모리, 휘발성, 속도 가장 빠름, 용량 가장 적음
  • 캐시
    • L1,L2 캐시를 지칭 휘발성, 속도 빠름, 용량적음
  • 주기억장치
    • RAM을 뜻한다. 휘발성, 속도 보통, 용량 보통
    • 램은 하드디스크로 부터 일정량의 데이터를 복사 → 임시저장 → 필요시 cpu에 전달
  • 저장장치(HDD, SSD)/보조기억장치
    • 비휘발성, 속도 낮음, 용량 높음

캐시

  • 데이터를 미리 복사해 놓는 임시 저장소
  • 빠른 장치와 느린 장치에서 속도 차이에 따른 병목현상을 줄이기 위한 메모리

시간 지역성

  • 최근 사용한 데이터에 다시 접근하려는 특성

공간 지역성

  • 최근 접근한 데이터를 이루고 있는 공간이나 가까운 공간에 접근하는 특성

캐시 히트

  • 캐시에서 원하는 데이터를 찾는 행위
  • 해당 데이터를 제어장치를 거쳐 가져오게 된다.
  • cpu 내부 버스 기반으로 작동하기 때문에 빠르다

캐시 미스

  • 데이터가 캐시에 없다면 주 메모리로 가서 데이터를 찾아오는 것
  • 시스템 버스 기반으로 작동하기 때문에 느리다.

캐시 매핑

  • 캐시가 히트되기 위해 매핑하는 방법
  • CPU의 레지스터와 주 메모리 간에 데이터를 주고받을 때를 기반으로 설명
  • 메모리 용량 차이가 나기 때문
    • 직접매핑
      • 처리가 빠르지만 충돌이 잦음
    • 연관매핑
      • 순서를 일치시키지 않고 관련 있는 캐시와 메모리를 매핑
      • 충돌은 적지만 모든 블럭을 탐색해서 속도가 느리다.
    • 집합 연관 매핑
      • 위 두개를 합침 순서를 일치시키지만 집합을 둬서 저장하며 블록화되어 있기 때문에 검색은 좀 더 효율적이다.

웹 브라우저의 캐시

  • 웹 브라우저의 작은 저장소 쿠키
    • 만료기한이 있는 키-값 저장소
  • 로컬 스토리지
    • 만료기한이 없는 키-값 저장소
  • 세션 스토리지
    • 만료기한이 없는 키-값 저장소
    • 탭 단위로 스토리지를 생성하며 탭을 닫을 때 데이터가 삭제된다.

데이터 베이스의 캐싱 계층

  • ex) redis

메모리 관리

  • 운영체제의 역할 중 하나, 한정된 메모리를 극한으로 활용해야 한다.

가상 메모리

  • 메모리 관리 기법의 하나로 실제로 이용 가능한 메모리 자원을 추상화하여 큰 메모리로 보이게 만드는 것을 말한다.
  • 가상주소
    • 가상으로 주어진 주소
    • 메모리 관리 장치(MMU)에 의해 실제주소로 변환
  • 실제주소
    • 실제 메모리에 존재하는 주소
  • 가상 메모리는 가상 주소와 실제 주소가 매핑되어 있고 프로세스의 주소 정보가 들어있는 페이지 테이블로 관리

스와핑

  • 가상 메모리에는 존재하지만 실제 메모리인 RAM에는 현재 없는 데이터나 코드에 접근할 경우 페이지 폴트가 발생
  • 메모리에서 사용하지 않는 영역을 하드디스크로 옮기고 하드디스크의 일부분을 마치 메모리처럼 불러와서 사용하는것 → 페이지 폴트가 일어나지 않은 것처럼 만든다.
  • 페이지 폴트
    • 프로세스의 주소 공간에는 존재하지만 ram에 없는 데이터에 접근했을 경우 발생
  • 페이지
    • 가상 메모리를 사용하는 최소 크기 단위
  • 프레임
    • 실제 메모리를 사용하는 최소 크기 단위

스레싱

  • 메모리의 페이지 폴트율이 높은 것을 의미한다.
  • 심각한 성능 저하 초래
  • 메모리에 너무 많은 프로세스가 동시에 올라가게 되면 스와핑이 많이 일어나서 발생
  • cpu이용률이 낮아진다. 낮아지면 os는 가용성을 높이기 위해 더 많은 프로세스를 메모리에 올린다.
  • 메모리를 늘리거나 HDD를 사용한다면 SSD로 바꾸는 방법이 있다.
  • 운영체제에서 이를 해결할 수 있는 방법
    • 작업 세트
      • 프로세스의 과거 사용 이력인 지역성을 통해 결정된 페이지 집합을 만들어서 미리 메모리에 로드하는것.
      • 미리 메모리에 로드하면 탐색에 드는 비용을 줄이고 스와핑 또한 줄일 수 있다.
    • PFF
      • 페이지 폴트 빈도를 조절하는 방법 상한선과, 하한선을 만드는 방법
      • 상한선에 도달한다면 프레임을 즐리고 하한선에 도달한다면 프레임을 줄인다.

메모리 할당

  • 메모리에 프로그램을 할당할 때는 시작 메모리 위치, 메모리의 할당 크기를 기반으로 할당하는데, 연속 할당과 불연속 할당으로 나뉜다.
  • 연속할당
    • 메모리에 연속적으로 공간을 할당하는 것을 말한다.
      • 고정 분할 방식
        • 메모리를 미리 나누어 관리하는 방식
        • 내부 단편화 발생
          • 메모리를 나눈 크기보다 프로그램이 작아서 들어가지 못하는 공간이 발생하는 현상
      • 가변 분할 방식
        • 매 시점 프로그램의 크기에 맞게 동적으로 메모리를 나눠 사용
        • 외부 단편화 발생
          • 메모리를 나눈 크기보다 프로그램이 커서 들어가지 못하는 공간이 많이 발생하는 현상
        • 최초 적합
          • 시작 지점부터 홀을 찾으면 바로 할당
        • 최적 적합
          • 프로세스의 크기 이상인 공간 중 가장 작은 홀부터
        • 최악 적합
          • 프로세스의 크기와 가장 차이가 많이는 홀에 할당
  • 불연속 할당
    • 현대 운영체제가 쓰는 방법
    • 페이징
      • 동일한 크기의 페이지 단위로 나누어 메모리의 서로 다른 위치에 프로세스를 할당한다.
      • 주소 변환이 복잡해진다.
    • 세그멘테이션
      • 프로세스는 코드, 데이터, 스택, 힙 등으로 이뤄지는데, 코드와 데이터 등 이를 기반으로 나눌 수 있으며 함수 단위로 나눌 수 있음을 의미한다.
      • 공유, 보안 측면에서 좋고, 홀 크기가 균일하지 않은 문제가 발생
    • 페이지드 세그멘테이션
      • 공유나 보안을 의미 단위의 세그먼트로 나누고, 물리적 메모리는 페이지로 나누는 것

페이지 교체 알고리즘

  • 메모리는 한정되어 있기 때문에 스와핑이 많이 일어난다. 스와핑은 많이 일어나지 않도록 설계되어야 하며 이는 페이지 교체 알고리즘을 기반으로 스와핑이 일어난다.
  • FIFO
    • 가장 먼저 온 페이지를 교체 영역에 가장 먼저 놓는 방법을 의미한다.
  • LRU(least Recentle Used)
    • 참조가 가장 오래된 페이지를 바꾼다.
  • NUR(Not Used Recently)
    • 시계방향으로 탐색하며 최근 참조되지 않은 프로세스를 교체하고 체크하는 방법?
  • LFU(Least Frequently Used)
    • 가장 참조 횟수가 적은 페이지를 교체

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

프로세스  (0) 2023.08.10

TCP/IP 4계층 모델

  • 인터넷 프로토콜 스위트는 인터넷에서 컴퓨터들이 서로 정로블 주고 받는데 쓰이는 프로토콜의 집합이며, 이를 TCP/IP 4계층 모델로 설명하거나 OSI 7계층 모델로 설명하기도 한다.
  • TCP/IP 4계층 모델은 네트워크에서 사용되는 통신 프로토콜의 집합으로 계층들은 프로토콜의 네트워킹 범위에 따라 네 개의 추상화 계층으로 구성된다.

계층 구조

  • OSI 7계층은 애플리케이션 계층을 세 개로 쪼개고 링크 계층을 데이터링크, 물리 계층으로 나눠서 표현하는 것이 다르며, 인터넷 계층을 네트워크 계층으로 부른다.
  • 이 계층들은 특정 계층이 변경되었을 떄 다른 계층이 영향을 받지 않도록 설계되었다. 예를들어 TCP를 UDP로 변경한다고 해서 웹 브라우저를 다시 설치해야 하는 것은 아니듯 유연하게 설계되었다.

애플리케이션 계층

  • FTP,HTTP,SSH,SMTP,SSH,DNS 등 응용 프로그램이 사용되는 프로토콜 계층이며 웹 서비스, 이메일 등 서비스를 실질적으로 사람들에게 제공하는 계층이다.
  • FTP
    • 장치와 장치 간의 파일을 전송하는 데 사용되는 표준 통신 프로토콜
  • SSH
    • 보안되지 않은 네트워크에서 네트워크 서비스를 안전하게 운연하기 위한 암호화 네트워크 프로토콜
  • HTTP
    • World Wide Web을 위한 데이터 통신의 기초이자 웹 사이트를 이용하는데 쓰는 프로토콜
  • SMTP
    • 전자 메일 전송을 위한 인터넷 표준 통신 프로토콜
  • DNS
    • 도메인 이름과 IP 주소를 매핑해주는 서버

전송 계층

  • 송신자와 수신자를 연결하는 통신 서비스를 제공하며 연결 지향 데이터 스트림 지원, 신뢰성, 흐름 제어를 제공할 수 있으며 애플리케이션과 인터넷 계층 사이의 데이터가 전달될 때 중계 역할을 한다. 대표적으로 TCP,UDP가 있다.
  • TCP
    • 패킷 사이의 순서를 보장하고 연결지향 프로토콜을 사용해서 연결을 하여 신뢰성을 구축해서 수신여부를 확인하며 ‘가상회선 패킷 교환 방식’을 사용한다.
      • 가상회선 패킷 교환 방식
        • 각 패킷에는 가상회선 식별자가 포함되며 모든 패킷을 전송하면 가상회선이 해제되고 패킷들은 전송된 순서대로 도착하는 방식을 말한다.
      • TCP연결 성립 과정
        • TCP는 신뢰성을 확보할 떄 3-way handshake라는 작업을 진행한다.
          1. SYN 단계
            • 클라이언트는 서버에 클라이언트의 ISN을 담아 SYN을 보낸다. ISN은 새로운 TCP 연결의 첫 번째 패킷에 할당된 임의의 시퀀스 번호를 말한다.
          2. SYN+ACK 단계
            • 서버는 클라이언트의 SYN을 수신하고 서버의 ISN을 보내며 승인번호로 클라이언트의 ISN+1을 보낸다.
          3. ACK 단계
            • 클라이언트는 서버의 ISN+1한 값인 승인번호를 담아 ACK를 서버에 보낸다.
      • TCP연결 해제 과정
        • TCP는 연결을 해제할 때는 4-way handshake 과정이 발생
          1. 클라이언트가 연결을 닫으려고 할 때 FIN으로 설정된 세그먼트를 보낸다. 그 후 FIN_WAIT_1상태로 들어가고 서버의 응답을 기다린다.
          2. 서버는 클라이언트로 ACK라는 승인 세그먼트를 보내고, CLOSE_WAIT 상태에 들어간다. 클라이언트가 세그먼트를 받으면 FIN_WAIT_2 상태에 들어간다.
          3. 서버는 ACK를 보내고 일정 시간 이후에 클라이언트에 FIN이라는 세그먼트를 보낸다.
          4. 클라이언트는 TIME_WAIT 상태가 되고 다시 서버로 ACK를 보내서 서버는 CLOSED 상태가 되고 클라이언트는 어느 정도의 시간을 대기한 후 연결이 닫히고 클라이언트와 서버의 모든 자원의 연결이 해제된다.
        • 이 과정 중 가장 눈 여겨 봐야할 것은 TIME_WAIT이다. 그냥 연결을 닫으면 되지 왜 굳이 일정 시간 뒤에 닫을까?
          1. 지연 패킷이 발생할 경우를 대비하기 위함
            • 패킷이 뒤늦게 도달하고 이를 처리하지 못한다면 데이터 무결성 문제가 발생
          2. 두 장치가 연결이 닫혔는지 확인하기 위함
            • LAST_ACK 상태에서 닫히게 되면 다시 새로운 연결을 하려고 할 때 장치는 줄곧 LAST_ACK로 되어 있기 떄문에 오류가 발생
  • UDP
    • 순서를 보장하지 않고, 수신 여부를 확인하지 않으며 단순히 데이터만 주는 ‘데이터그램 패킷 교환 방식’을 사용한다.
      • 데이터그램 패킷 교환 방식
        • 패킷이 독립적으로 이동하며 최적의 경로를 선택하여 가는데, 하나의 메시지에서 분할된 여러 패킷은 서로 다른 경로로 전송될 수 있으며 도착한 순서가 다를 수 있는 방식을 말한다.

인터넷 계층

  • 인터넷 계층은 장치로부터 받은 네트워크 패킷을 IP주소로 지정된 목적지에 전송하기 위해 사용되는 계층이다.
  • IP, ARP, ICMP 등이 있으며 패킷을 수신해야 할 상대의 주소를 지정하여 데이터를 전달한다. 상대방이 제대로 받았는지에 대해 보장하지 않는 비연결형적인 특징을 가지고 있다.

링크 계층

  • 전선, 광섬유, 무선 등으로 실질적으로 데이터를 전달하며 장치 간에 신호를 주고받는 규칙을 정하는 계층이다.
  • 물리 계층과 데이터 링크 계층으로 나누기도 하는데 물리 계층은 무선 LAN과 유선 LAN을 통해 0과 1로 이뤄진 데이터를 보내는 계층을 말하며, 데이터 링크 계층은 ‘이더넷 프레임’을 통해 에러 확인, 흐름 제어, 접근 제어를 담당하는 계층을 말한다.

캡슐화란?

  • 캡슐화는 객체가 내부적으로 기능을 어떻게 구현하는지를 감추는 것이다.
  • 단순히 프라이빗한 데이터를 직접 데이터를 직접 접근하지 못하게 하기 위해 사용하는 것이 아닌 내부적인 기능에 초점을 맞춰야 한다. 단순히 데이터를 접근하기 위한 용도로 캡슐화를 사용한다면 객체에 대한 책임이 분산될 수 있다.

캡슐화를 하기 위한 두가지 규칙

묻지 말고 시켜라

  • 참조한 객체의 데이터에 대한 로직이 필요할 경우에 직접 구현하지 말고 구현된 데이터를 요청하여 데이터에 대한 책임을 전가 시킬 수 있다.

데미테르의 법칙

  • 1 뎁스만 사용할 뿐 2뎁스로 사용하지 말아야 한다. 이것은 묻지 말고 시켜라의 연장선으로 참조하는 객체가 가지고 있는 데이터를 참조하는 사용자 입장에서는 알 필요가 없고 데이터를 사용하여 데이터의 내부 기능을 사용하게 되면 내부 기능의 변화에 범위가 외부에도 노출되어 의존성이 낮아진다.

'Computer science > 디자인패턴 및 프로그래밍 패러다임' 카테고리의 다른 글

SOLID 원칙  (0) 2023.06.30
상속과 합성  (0) 2023.06.30
객체지향과 절차지향  (0) 2023.06.30
싱글톤 패턴  (0) 2022.12.15

단일 책임 원칙(Single Responsibility Principle , SRP)

  • 객체는 단 하나의 책임만을 가져야 한다. 책임이 많아지면 클래스 내부의 함수끼리 강한 결합을 발생할 가능성이 높아지며 이는 유지보수에 비용이 증가하게 되므로 책임을 분리시킬 필요가 있다.

개방 폐쇄 원칙(Open Closed Principle, OCP)

  • 기존의 코드를 변경하지 않고 기능을 수정하거나 추가할 수 있도록 설계해야 한다.
  • OCP를 만족한 설계는 변경에 유연하므로 유지보수 비용을 줄여주고 코드의 가독성 또한 높아지는 효과를 얻을 수 있다.

리스코프 치환 원칙(Liskov Substitution Principle, LSP)

  • 자식 클래스는 부모 클래스에서 가능한 행위를 수행할 수 있어야 한다.
  • 상속 관계에서는 일반화 관계(IS-A)가 성립해야 한다. 일반화 관계에 있다는 것은 일관성이 있다는 것이다.

인터페이스 분리 원칙(Interface Segregation Principle, ISP)

  • 한 클래스는 자신이 사용하지 않는 인터페이스는 구현하지 말아야 한다. 하나의 일반적인 인터페이스 보다는 여러개의 구체적인 인터페이스가 낫다. 자신이 사용하지 않는 기능에는 영향을 받지 말아야 한다.

의존 역전 원칙(Dependency Inversion Principle)

  • 의존 관계를 맺을 때 변화하기 쉬운 것 보단 변화하기 어려운 것에 의존해야 한다. 의존관계를 맺을 때 구체적인 클래스보다 인터페이스나 추상 클래스와 관계를 맺는 게 변화에 유연하게 대처할 수 있다.

'Computer science > 디자인패턴 및 프로그래밍 패러다임' 카테고리의 다른 글

캡슐화  (0) 2023.06.30
상속과 합성  (0) 2023.06.30
객체지향과 절차지향  (0) 2023.06.30
싱글톤 패턴  (0) 2022.12.15

상속이란?

  • 자식 클래스가 부모클래스를 상속받아 설계된 구조를 일컫는다. 상속으로 이루어진 관계에서는 부모 클래스의 멤버 변수나 메서드를 사용할 수 있다.

자식 클래스는 부모 클래스의 모두 접근이 가능한가?

  • 모두 접근이 가능한 것은 아니다. 부모 클래스의 멤버 변수나 메서드의 접근자가 private가 아닌 public 이나 protected일 경우메나 사용할 수 있다.

protected 접근자는 왜 사용할까?

  • 우선, public 과 protected의 차이를 살펴보자
    • public 접근자는 외부에 노출이 가능하다.
    • public 접근자는 자식 클래스가 접근할 수 있다.
    • protected 접근자는 외부에 노출되지 않는다.
    • protected 접근자는자식 클래스가 접근할 수 있다.
  • 두 접근자 모두 자식 클래스에게 노출이 되지만 외부에 노출 여부에 차이가 있다.\
  • 변경 가능성이 열려있다는 것을 암시
  • 상속받은 자식 클래스에서 구현을 완성시켜야 한다는 것

상속은 언제 사용해야 할까?

  • SOLID 원칙의 리스코프 치환 원칙을 통해서 해답을 얻을 수 있다.
  • 리스코프 치환 원칙은 상속받은 자식 클래스는 부모 클래스를 대체할 수 있는 경우에만 상속을 해야한다고 명시하고 있다.
  • 자식 클래스가 부모 클래스를 대체할 수 있는 경우는 부모 클래스의 외부로 노출되는 메서드를 자식 클래스에서도 같은 의미로 제공되어야 한다는 것을 의미함. → IS-A 관계가 성립

상속으로 얻을 수 있는 장점은 무엇이 있을까?

  • 상속 관계에서는 외부로부터 다형성을 보장하면서 클래스 내부 구현 코드를 모두 구현하지 않고 공통된 로직을 그대로 사용할 수 있다.
  • 클래스 타입에 따라 변경되는 로직만 일부분 구현하면 된다는 것이 장점
  • 하지만 이러한 장점도 java8 부터 인터페이스의 디폴트 메서드 기능이 나오면서 인터페이스내에서 로직 구현이 가능하여 상속의 장점이 약화되었다고 할 수 있다.

추상 클래스는 왜 사용할까?

  • 추상 클래스는 protected 접근자를 사용하는 이유를 더 명확하게 나타내기 위해서 사용한다고 볼 수 있다.
  • 부모 클래스에서는 변경되는 로직을 abstract로 정의하여 내부 로직은 구현하지 않고 상속받은 자식 클래스에서는 무조건 구현할 수 있게 만들어 변경되어야 할 부분과 변경되지 않을 부분을 더 명확히 구분할 수 있게 되었다.
  • 컴파일 단계에서 자식 클래스가 abstract 메서드를 오버라이딩 하지 않을 경우에는 에러가 발생하므로 런타임 단계에서 발생할 수 있는 예외를 명확하게 확인할 수 있는 장점이 있다.
  • 이러한 추상 클래스를 사용한 대표적인 사례가 템플릿 메서드 패턴이라고 할 수 있다. 템플릿 메서드 패턴은 외부로 노출되는 메서드는 그대로이나 내부에서 변경되는 로직만 별도로 추상화하여 외부에서 필요한 전략을 선택하여 내부 구현만 변경되도록 노출하는 디자인 패턴이다.

잘못된 상속 방법

  • 어떤 이는 상속은 코드를 재사용 하기 위해 사용한다고 주장하기도 한다. 이는 전형적인 상속의 잘못된 사용 사례이다.

코드 재사용을 위해 상속을 하면 어떠한 단점이 있나?

캡슐화를 위반할 수 있다.

  • 부모의 public 메서드는 외부에 노출하기 위한 용도로 사용된다. 그러나 자식 클래스에서도 부모 클래스의 public 메서드는 외부로 노출되기 때문에 자식 클래스에서 의도하지 않는 동작을 수반할 수 있게 되며 캡슐화를 위반하게 된다.

설계가 유연하지 않게된다.

  • 상속으로 인해 결합도가 높아지면 다음과 같은 두 가지 문제점이 발생
    • 하나의 기능을 추가하거나 수정하기 위해 불필요하게 많은 수의 클래스를 추가하거나 수정해야 한다.
    • 단일 상속만 지원하는 언어에서는 상속으로 인해 오히려 중복 코드의 양이 늘어날 수 있다.

합성이란?

  • 합성은 객체가 다른 객체의 참조자를 얻는 방식으로 런타임시에 동적으로 이뤄진다. 이는 보통 has-a 관계라고 일컫는다. 따라서 다른 객체의 참조자를 얻은 후 그 참조자를 이용해서 객체의 기능을 이용하기 때문에 해당 객체의 인터페이스만을 바라보게 됨으로써 캡슐화가 잘 이뤄질 수 있다.

합성은 언제 사용해야 할까?

  • 구현 코드를 재사용하고 싶을 때 사용하면 유리하다. 또한 합성으로 사용된 코드는 사용하는 클래스에 따라 외부로 노출시킬 수 있고 내부로 캡슐화 할 수도 있어 클래스 특성에 맞게 캡슐화를 할 수 있다.
  • 합성을 사용하고 인터페이스 타입을 사용한다면 런타임 시에 외부에서 필요한 전략에 따라 교체하며 사용할 수 있으므로 좀 더 유연한 설계를 할 수 있다.
  • 대표적인 사례가 전략 패턴이다.

합성의 단점은?

  • 합성은 객체 간의 관계가 수직관계가 아닌 수평관계가 된다.
  • 따라서 큰 시스템에서 많은 부분에 걸쳐 합성이 사용될 때 객체나 메서드 명이 명확하지 않으면 코드가 가독성이 떨어지고 이해하기 어려워지게 된다.
  • 합성을 사용할 시 용도에 따라 클래스들을 패키지로 분리하고 각각의 사용 용도가 명확하게 드러나도록 인터페이스를 잘 설계해야 한다.

결론

  • 상속을 사용하고 싶다면 단순히 코드를 재사용 하는 용도가 아닌 부모 클래스를 대체할 수 있는 IS-A 관계인지 고려해야 한다. IS-A 관계에서도 변경되는 부분이 있다고 하면 protected 접근자나 abstract 를 사용하여 자식 클래스에게 명확하게 전달해야 한다.
  • 단순히 코드를 재사용하고 싶다면 합성을 고려해보자 합성을 사용하면 코드 재사용도 가능할 뿐더러 캡슐화도 지킬 수 있다. 또한 다양한 전략에 따라 런타임시에 교체도 가능하여 유연한 설계가 가능하다. 단 합성을 하려는 클래스에 너무 많은 기능들이 정의되어 있거나 합성하는 인터페이스의 기능이 단일 책임보다 많은 책임을 가진 설계라면 분리해야할 필요가 있다.

'Computer science > 디자인패턴 및 프로그래밍 패러다임' 카테고리의 다른 글

캡슐화  (0) 2023.06.30
SOLID 원칙  (0) 2023.06.30
객체지향과 절차지향  (0) 2023.06.30
싱글톤 패턴  (0) 2022.12.15

절차지향

  • 절차지향이란 프로시저로 프로그램을 구성하는 기법이다.
  • 프로시저는 대체로 데이터를 중심으로 구현한다.
  • 단점은 데이터 타입이나 의미를 변경해야 할 때, 함께 수정해야 하는 프로시저가 증가하는 것이다.

객체지향

  • 객체는 자신만의 데이터와 프로시저를 갖는다.
  • 객체는 자신만이 기능을 제공한다.
  • 객체들은 서로 연결되어 다른 객체가 제공하는 기능을 사용할 수 있다.

절차지향 vs 객체지향

설계 방식

  • 절차지향 프로그래밍은 프로그램의 순서와 흐름을 먼저 세우고 필요한 자료구조와 함수들을 설계하는 방식
  • 객체지향 프로그래밍은 자료구조와 이를 중심으로 한 모듈 들을 먼저 설계한 다음 이들의 실행 순서와 흐름을 조합하는 방식

목적

  • 절차지향 언어를 사용한다면, 말 그대로 실행 순서, 즉 절차가 더 중심이 된다.
  • 객체지향 언어를 사용한다면, 필요한 객체들의 종류와 속성등이 더 중점이 된다.

더 나은 설계는?

  • 더 나은 설계란 없고, 비즈니스 모델의 성격에 따라 다를 뿐이다.
  • 객체는 변수와 함수를 추상화 과정을 통해 좀 더 모듈화한 도구에 불과하다. 모듈화 함으로써 객체지향이 지닐 수 있는 강점인 정보은닉화, 상속 및 다형성을 통한 확장성과 재사용, 이를 기반한 생산성과 유지보수의 용이성이 OOP의 진정한 특징이자 정체성일지도 모른다.

'Computer science > 디자인패턴 및 프로그래밍 패러다임' 카테고리의 다른 글

캡슐화  (0) 2023.06.30
SOLID 원칙  (0) 2023.06.30
상속과 합성  (0) 2023.06.30
싱글톤 패턴  (0) 2022.12.15

AOP란?

  • AOP는 공통의 관심사를 추상화해 잘 보관하고 있다가 필요한 곳에 동적으로 삽입하며 적용해주는 기술이다. 이로 인해 핵심 로직과 부가 기능을 분리할 수 있고 각각의 기능은 단일 책임을 가진 코드를 유지할 수 있다.

핵심 로직과 부가 기능이 같이 있다면

  • 두 가지 책임을 가지므로 하나의 책임에 인한 코드 수정은 다른 코드에 side effect가 발생할 수 있다.
  • 두 가지 기능이 접목되어 있어 테스트 코드를 작성하려 할 때도 두가지 기능을 다 고려 해야한다.
  • 비즈니스 로직이 복잡하거나 부가 기능이 추가될수록 유지보수 하기가 어려워진다.
  • 유지보수와 비슷한 맥락으로 기능을 확장하거나 다른 전략으로 기능을 변경하기도 어려워 진다.

AOP를 적용한다면?

  • 코드에는 핵심 로직만 남기고 부가 기능은 별도로 추상화하여 주입 받는 방식으로 리팩토링 할 수 있을 것이다.
  • //대표적인 AOP 방식이 @Transactional 적용 @Transactional public void upgradeLevels() throws Exception { List<User> users = userDao.getAll(); for (User user : users) { if (canUpgradeLevel(user)) { upgradeLevel(user); } } this.transactionManager.commit(status); }

코드를 분리하면 어떤 점이 좋을까?

  • 메서드 또는 클래스는 한 책임을 가질 수 있는 코드를 작성할 수 있고 응집도 높은 코드를 작성할 수 있다.
  • 테스트 코드 또한 비즈니스 로직에 대한 테스트 케이스만 작성하면 된다.
  • 유지보수 측면에서도 비즈니스 로직 수정시에 부가 기능에 대한 side effect는 찾아 볼 수 없게 된다.

프록시란?

  • 자신의 클라이언트가 사용하려고 하는 실제 대상인 것처럼 위장해서 클라이언트의 요청을 받아주는 것(대리인 ,대리자)
  • 사용 목적에 따라
    • 클라이언트가 타깃에 접근하는 방법을 제어하기 위해
      • 프록시 패턴
    • 타깃에 부가적인 기능을 부여 해주기 위
      • 데코레이터 패턴

AOP 용어 정리

  • Target Object
    • 부가 기능을 부여할 대상
  • Aspect
    • AOP의 기본 모듈. 그 자체로 애플리케이션의 핵심 기능을 담고있진 않지만 애플리케이션을 구성하는 중요한 한가지 요소, 부가될 기능을 정의한 Advice와 어드바이스를 어디에 적용할지 결정하는 Pointcut을 함께 가짐
  • Advice
    • 타깃에게 제공할 부가 기능을 담은 모듈. 타깃이 필요없는 순수한 부가 기능. Aspect가 무엇을 언제 할지를 정의하고 있음
  • Join point
    • 프로그램의 실행 내부에서 Advice가 적용될 수 있는 위치
  • Pointcut
    • Advice에 적용할 Joinpoint를 선별하는 작업 또는 그 기능을 정의한 모듈

AOP를 구현하는 방법

  • 컴파일 시점에 코드에 공통 기능 삽입
  • 클래스 로딩 시점에 바이트 코드에 공통 기능 삽입
  • 런타임 시점에 프록시 객체를 생성하여 공통 기능 삽입
    • Spring에서 사용하는 방법

'Computer science > Spring' 카테고리의 다른 글

Stereo Type  (0) 2023.06.22
Spring Security  (0) 2023.06.21
@Controlleradvice,@ExceptionHandler  (0) 2023.06.21
@Transactional  (0) 2023.06.15
영속성 컨텍스트  (0) 2023.06.15

+ Recent posts