좋은 관계형 데이터베이스를 설계하는 목적 중 하나가 정보의 이상현상(Anomaly)이 생기지 않도록 고려해 설계하는 것입니다.

 

이상현상은 아래와 같은 3가지로 구성됩니다.

  • 갱신 이상
    • 반복된 데이터 중에 일부를 갱신할 시 데이터 불일치 발생
  • 삽입 이상
    • 불필요한 정보를 함께 저장하지 않고서는 정보 저장 불가능
  • 삭제 이상
    • 필요한 정보를 함께 삭제하지 않고서는 정보 삭제 불가능

 

갱신이상

 

갱신 이상의 경우 어떤 값을 업데이트 했을 때, 다른 속성값들과의 불일치가 발생하는 현상입니다.
예를들어, 테이블에 사용자의 이름이 같은 사용자 김영진이 2명이상 있다고 가정해봅시다.
여러 명의 사용자 중 한명의 김영진이 김진영이라는 이름으로 개명하여 김영진 -> 김진영으로 바꾸었습니다. 이때, 테이블에는 여러명의 김영진이 있기 때문에 다른 김영진도 바뀔 수 있습니다. 이러한 현상을 갱신 이상이라고 합니다.

 

삽입 이상

내가 원하는 값만 테이블에 삽입하고 싶은데, 테이블에 필요하지 않을 필드들 때문에 원치 않는 필드의 값도 삽입해야 하는 경우 입니다.
예를들어, id, name, password, school의 정보를 입력해야하는 테이블이 있습니다.
해당 테이블에 저는 학교를 다니지 않아서 Id, name, password만 입력하고 싶지만 school의 정보를 입력하지 않는 이상 데이터를 삽입할 수 없습니다.
이렇게 필드 값을 무엇으로 해야할지 결정 못하는 것이 삽입 이상입니다.

 

삭제 이상

내가 원하는 값만 테이블에서 삭제하고 싶은데, 하나의 튜플이 삭제를 원하지 않는 속성값도 갖고있기 때문에 같이 지워져서 발생하는 문제입니다.
예를들어, Id, name, password, school의 정보가 담겨져있는 테이블이 있습니다.
여기서 저는 학교를 졸업했기때문에 school의 정보만 삭제하고 싶지만, 테이블이 더 많은 수의 필드로 구성되어 있기 때문에 이것을 지우기 위해서는 지우고 싶지 않은 필드들의 정보도 같이 지워야합니다. 이것이 삭제 이상입니다.

 

 

 

HTTP 헤더 개요

HTTP 헤더

  • header-field = field-name ":" OWS field-value OWS (OWS: 띄어쓰기 허용)
  • field-name은 대소문자 구문 없음

 

HTTP 헤더 용도

  • HTTP 전송에 필요한 모든 부가정보
  • 예) 메시지 바디의 내용, 메시지 바디의 크기, 압축, 인증, 요청 클라이언트, 서버 정보, 캐시 관리 정보....
  • 표준 헤더가 너무 많음
  • 필요시 임의의 헤더 추가 가능

 

HTTP 헤더

분류 - RFC2616(과거)
  • 헤더 분류
    • General 헤더 : 메시지 전체에 적용되는 정보, 예) Connection : close
    • Request 헤더 : 요청 정보, 예) User-Agent: Mozilla/5.0 (Macintosh; ..)
    • Response 헤더 : 응답 정보, 예) Server: Apache
    • Entity 헤더 : 엔티티 바디 정보, 예) Content-Type: text/html, Content-Length:3423
  • 메시지 본문(message body)은 엔티티 본문(entity body)을 전달하는데 사용
  • 엔티티 본문은 요청이나 응답에서 전달할 실제 데이터
  • 엔티티 헤더는 엔티티 본문의 데이터를 해석할 수 있는 정보 제공
    • 데이터 유형(html, json), 데이터 길이, 압축 정보 등등

 

RFC723x 변화

  • 엔티티 -> 표현
  • Representation = Representation Metadata + Representation Data
  • 표현 = 표현 메타데이터 + 표현 데이터

 

HTTP BODY(Message body) - RFC7230(최신)

  • 메시지 본문(message body)를 통해 표현 데이터 전달
  • 메시지 본문 = 페이로드(payload)
  • 표현은 요청이나 응답에서 전달할 실제 데이터
  • 표현 헤더는 표현 데이터를 해석할 수 있는 정보 제공
    • 데이터 유형(html,json), 데이터 길이, 압축 정보 등등
  • 참고 : 표현 헤더는 표현 메타데이터와, 페이로드 메시지를 구분해야 하지만, 여기서는 생략

 

 

 

표현

  • Content-Type : 표현 데이터 형식 (html, json..)
  • Content-Encoding : 표현 데이터의 압축 방식
  • Content-Language : 표현 데이터의 자연 언어 (한국어, 영어)
  • Content-Length : 표현 데이터(페이로드 헤더)의 길이
  • 표현 헤더는 전송, 응답 둘 다 사용

 

Content-Type

표현 데이터의 형식 설명
  • 미디어 타입, 문자 인코딩
  • 예)
    • text/html;charset=utf-8
    • application/json
    • image/png

 

Content-Encoding

표현 데이터 인코딩
  • 표현 데이터를 압축하기 위해 사용
  • 데이터를 전달하는 고셍서 압축 후 인코딩 헤더 추가
  • 데이터를 읽는 쪽에서 인코딩 헤더의 정보로 압축 해제
  • 예)
    • gzip
    • deflate
    • identity

 

Content-Language

표현 데이터의 자연 언어
  • 표현 데이터의 자연 언어를 표현
  • 예)
    • ko
    • en
    • en-US

 

Content-Length

표현 데이터의 길이
  • 바이트 단위

 

 

 

콘텐츠 협상 (콘텐츠 네고시에이션)

클라이언트가 선호하는 표현 요청
  • Accept : 클라이언트가 선호하는 미디어 타입 전달
  • Accept-Charset : 클라이언트가 선호하는 문자 인코딩
  • Accept-Encoding : 클라이언트가 선호하는 압축 인코딩
  • Accept-Language : 클라이언트가 선호하는 자연 언어
  • 협상 헤더는 요청시에만 사용 (google 홈페이지에서 F12로 검색해보면 헤더에 포함된 Accep-Language등을 볼 수 있습니다.)

콘텐츠 협상은 클라이언트가 원하는 표현으로 달라고 서버한테 요청하는 것이라고 생각하면됩니다. Accept-Language를 예시로 들어보겠습니다.

 

Accept-Language 적용 전

 

Accept-Language 적용 후

 

Accept-Language 복잡한 예시

독일어, 영어만 지원하는 서버에서 한국어를 요청하면 1번째 우선순위인 독일어로 응답이 옵니다.

위의 서버가 있을 수도 있기때문에 우선순위가 필요합니다.

 

 

 협상과 우선순위 1

Quality Values(q)
  • Quality Values(q) 값 사용
  • 0~1, 클수록 높은 우선순위
  • 생략하면 1
  • Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
    1. ko-KR;q=1 (q 생략)
    2. ko;q=0.9
    3. en-US;q=0.8
    4. en;q=0.7

 

이러한 우선순위를 통해 아까의 복잡한 예시로 똑같이 서버로 요청을 보내게 되면 서버에서 응답 가능한 언어 중에서 클라이언트가 요청한 언어 중 가장 높은 우선순위를 가진 언어로 응답을 보내줍니다.

 

협상과 우선순위 2

Quality Values(q)
  • 구체적인 것이 우선한다.
  • Accept : text/*, text/plain, text/plain;format=flowed, */*
    1. text/plain;format=flowed
    2. text/plain
    3. text/*
    4. */*

위처럼 구체적인 것일 수록 우선순위가 높습니다.

 

협상과 우선순위 3

Quality Values(q)
  • 구체적인 것을 기준으로 미디어 타입을 맞춥니다.
  • Accept : text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5
Media Type Quality
text/html;level=1 1
text/html 0.7
text/plain 0.3
image/jpeg 0.5
text/html;level=2 0.4
text/html;leve=3 0.7

 

 

 

전송 방식

  • Transfer-Encoding
  • Range, Content-Range

 

전송 방식 설명

  • 단순 전송
  • 압축 전송
  • 분할 전송
  • 범위 전송

 

단순 전송

한 번에 요청하고 한 번에 쭉 받는 것 

 

압축 전송

보낼 message body를 gzip 등을 이용해 압축해서 전송하는 것
참고) HTTP HEAD 부분에 Contetn-Encoding을 적어주어야함.

 

분할 전송

보낼 데이터를 byte 단위로 끊어서 전송하는 것
참고) HTTP HEAD에 Transfer-Encoding = chunked를 추가해줘야함.
참고) Content-Length를 넣으면 안된다. (총 몇 바이트인지 예상이 안되기때문)
아래의 Body로 예시를 들면
5byte Hello 먼저 전송
5byte World 전송
0Byte 전송
용량이 되게 큰 경우에 이렇게 나누어서 전송함

 

범위 전송

이미지를 받는데, 절반정도 받고 나머지 절반을 받는 형식
이유 : 큰 용량의 데이터를 받는 경우 중간에 받지못하면 많은 양의 데이터를 다시 처음부터 받아야하기 때문

 

 

 

일반 정보

  • From : 유저 에이전트의 이메일 정보
  • Referer : 이전 웹 페이지 주소
  • User-Agent : 유저 에이전트 애플리케이션 정보
  • Server : 요청을 처리하는 오리진 서버의 소프트웨어 정보
  • Data : 메시지가 생성된 날짜

 

From

유저 에이전트의 이메일 정보
  • 일반적으로 잘 사용되지 않음
  • 검색 엔진 같은 곳에서, 주로 사용
  • 요청에서 사용

 

Feferer

이전 웹 페이지 주소
  • 현재 요청된 페이지의 이전 웹 페이지 주소
  • A -> B로 이동하는 경우 B를 요청할 때 Referer: A를 포함해서 요청
  • Referer를 사용해서 유입 경로 분석 가능 (내 사이트를 어디 사이트를 통해 들어왔는지 데이터 분석할 때 많이 사용)
  • 요청에서 사용
  • 참고 : referer는 단어 referrer의 오타 => ...??ㅋㅋㅋ그렇다고합니다...

실제 구글에서 hello를 검색한 뒤, 나무위키를 들어가서 개발자 도구에서 Request Headers를 보시면 referer에 이전 페이지의 주소가 적혀있는 것을 볼 수 있습니다.

 

User-Agent

유저 에이전트 애플리케이션 정보
  • user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/ 537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36
  • 클라이언트의 애플리케이션 정보 (웹 브라우저 정보, 등등)
  • 통계 정보
  • 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능 (Chrome, Edge 등등..)
  • 요청에서 사용

 

Server

요청을 처리하는 ORIGIN 서버의 소프트웨어 정보 (프록시, 캐시 서버를 제외한 진짜 나의 요청을 응답하는 서버 - ORIGIN 서버)
  • Server : Apache/2.2.22 (Debian)
  • server : nginx
  • 응답에서 사용

 

Date

메시지가 발생한 날짜와 시간
  • Date : Tue, 15 Nov 1994 08:12:31 GMT
  • 응답에서 사용

 

 

 

특별한 정보

  • HOST : 요청한 호스트 정보 (도메인)
  • Location : 페이지 리다이렉션
  • Allow : 허용 가능한 HTTP 메서드
  • Retry-After : 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간

 

HOST

요청한 호스트 정보 (도메인)
  • 요청에서 사용
  • 필수
  • 하나의 서버가 여러 도메인을 처리해야 할 때 (구글, 네이버 등등과 같은 경우)
  • 하나의 IP 주소에 여러 도메인이 적용되어 있을 때

하나의 서버가 여러 도메인을 처리한다는 것은 가상호스트를 통해 여러 도메인을 한번에 처리할 수 있는 서버로 실제 애플리케이션이 여러개 구동될 수 있다고 합니다.

문제는 호스트가 없이 /hello만 온다면 아래와 같이 어떤 도메인에 /hello인지 모른다는 것 입니다.

그렇기 때문에 HOST를 적어주어야지 서버에서는 정확한 응답을 해줄 수 있습니다.

 

Location

페이지 리다이렉션
  • 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)
  • 응답코드 3xx에서 설명
  • 201 (Created) : Location 값은 요청에 의해 생성된 리소스 URI
  • 3xx (Redirection) : Location 값은 요청을 자동으로 리다이렉션하기 위한 대상 리소스를 가리킴

 

Allow

허용 가능한 HTTP 메서드
  • 허용하지 않는 HTTP 메서드로 접근하는 경우
  • 405 (Method Not Allowd)에서 응답에 포함해야함
  • Allow : GET, HEAD, PUT

 

Retry-After

유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간
  • 503 (Service Unavailable) : 서비스가 언제까지 불능인지 알려줄 수 있음
  • Retry-After : Fri, 31 Dec 1999 23:59:59 GMT (날짜 표기)
  • Retry-After : 120 (초단위 표기)

 

 

 

인증

  • Authorization : 클라이언트 인증 정보를 서버에 전달
  • WWW-Authenticate : 리소스 접근시 필요한 인증 방법 정의

 

Authorization

클라이언트 인증 정보를 서버에 전달
  • Authorization : Basic xxxxxxxxxxxxxxxxxxx
  • Oauth 인증 등등 value에 들어가는 입력이 다름

 

WWW-Authenticate

리소스 접근시 필요한 인증 방법 정의
  • 리소스 접근시 필요한 인증 방법 정의
  • 401 Unauthorized 응답과 함께 사용
  • WWW-Authenticate : Newauth realm= apps",type=1, title="Login to \"apps\"", Basic realm="simple"
    • 인증을 하려면 "New~simple"과 정보를 참고해서 제대로된 인증 정보를 만들라고 응답

 

 

 

쿠키

  • Set-Cookie : 서버에서 클라이언트로 쿠키 전달 (응답)
  • Cookie : 클라이언트가 서버에서 받은 쿠키를 저장하고, HTTP 요청시 서버로 전달

 

쿠키 미사용

처음 welcome 페이지 접근

로그인

로그인 이후 welcome 페이지 접근

HTTP는 메시지를 다 보내고나면 연결을 끊기 때문에 쿠키를 사용하지 않으면 서버에서 이전에 로그인을 했던 사용자인지 처음온 사람인지 알 수 있는 방법이 없습니다. (HTTP가 Stateless이기 때문)

 

대안 - 모든 요청에 사용자 정보 포함

하지만, 위의 대안으로 하면 모든 요청과 링크에 사용자 정보를 포함해야 합니다.

 

쿠키 사용

로그인

로그인 이후 welcome 페이지 접근

쿠키는 모든 요청에 쿠키 정보가 자동으로 포함됩니다.

 

쿠키

  • 예) set-cookie: sessionId=abcde1234; exires=Sat, 26-Dec-2020 00:00:00 GMT; path=/; domain=.google.com; Secure
  • 사용처
    • 사용자 로그인 세션 관리
    • 광고 정보 트래킹 (이 웹브라우저를 사용하는 사람이 ~~~한 광고를 보는구나 트래킹용도)
  • 쿠키 정보는 항상 서버에 전송됨
    • 네트워크 트래픽 추가 유발 (따라서, 최소한의 정보만을 사용해야함. 로그인정보만)
    • 최소한의 정보만 사용 (세션 id, 인증 토큰)
    • 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지 (localStorage, sessionStorage) 참고
  • 주의!
    • 보안에 민감한 데이터는 저장하면 안됨(주민번호, 신용 카드 번호 등등)

 

쿠키 - 생명주기

Expires, max-age
  • Set-Cookie: expires=Sat, 26-Dec-2020 04:39;21 GMT
    • 만료일이 되면 쿠키 삭제
  • Set-Cookie: max-age=3600 (3600초)
    • 0이나 음수를 지정하면 쿠키 삭제
  • 세션 쿠키 : 만료 날짜를 생략하면 브라우저 종료시 까지만 유지
  • 영속 쿠키 : 만료 날짜를 입력하면 해당 날짜까지 유지

 

쿠키 - 도메인

Domain
  • 예) domain=example.org
  • 명시 : 명시한 문서 기준 도메인 + 서브 도메인 포함
    • domain=example.org를 지정해서 쿠키 생성
      • example.org는 물론이고
      • dev.example.org도 쿠키 접근
  • 생략 : 현재 문서 기준 도메인만 적용
    • example.org에서 쿠키를 생성하고 domain 지정을 생략
      • example.org 에서만 쿠키 접근
      • dev.example.org는 쿠키 미접근

 

쿠키 - 경로

Path
  • 예) path=/home
  • 이 경로를 포함한 하위 경로 페이지만 쿠키 접근
  • 일반적으로 path=/ 루트로 지정
  • 예)
    • path=/home 지정
    • /home -> 가능
    • /home/level1 -> 가능
    • /home/level1/level2 -> 가능
    • /hello -> 불가능

 

쿠키 - 보안

Secure, HttpOnly, SameSite
  • Secure
    • 쿠키는 http, https를 구분하지 않고 전송
    • Secure를 적용하면 https인 경우에만 전송
  • HttpOnly
    • XSS 공격 방지
    • 자바스크립트에서 접근 불가 (document.cookie)
    • HTTP 전송에만 사용
  • SameSite
    • XSRF 공격 방지
    • 요청 도메인과 쿠키에 설정된 도메인이 같은 경우만 쿠키 전송

 

 

 

 

 

출처

 

모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의

실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...

www.inflearn.com

 

상태 코드

클라이언트가 보낸 요청을 처리 상태를 응답에서 알려주는 기능
  • 1xx (Informational) : 요청이 수신되어 처리중
  • 2xx (Successful) : 요청이 정상 처리
  • 3xx (Redirection) : 요청을 완료하려면 추가 행동이 필요
  • 4xx (Client Error) : 클라이언트 오류, 잘못된 문법등으로 서버가 요청을 수행할 수 없음
  • 5xx (Server Error) : 서버 오류, 서버가 정상 요청을 처리하지 못함

 

 

 

2xx (성공)

클라이언트의 요청을 성공적으로 처리
  • 200 OK
    • 요청 성공
  • 201 Created
    • 요청이 성공해서 새로운 시소스가 생성
    • 응답 헤더에 "Location : (새로생성된 리소스 URI)"를 포함해서 응답
  • 202 Accepted
    • 요청이 접수되었으나 처리가 완료되지 않는 경우
    • 배치 처리 같은 곳에서 사용
    • 예) 요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리함
  • 204 No Content
    • 서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음
    • 예) 웹 문서 편집기에서 save 버튼 (클라이언트 입장에서 서버에서 데이터를 보내줄 필요가 없음)
    • 결과 내용이 없는 204 메시지만으로 성공을 인식해도 되는 경우

 

 

 

3xx (리다이렉션1)

요청을 완료하기 위해 클라이언트 웹 브라우저의 추가 조치 필요
  • 300 Multiple Choices
  • 301 Moved Permanently
  • 302 Found
  • 303 See Other
  • 304 Not Modified
  • 307 Temporary Redirect
  • 308 Permanent Redirect

리다이렉션 이해

  • 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)

 

기존 event 시에 /event로 접근하였는데 새로운 이벤트는 /new-event로 접근하는 경우 301 코드와 새로바뀐 path를 Location에 포함해서 응답을 보냅니다. 그렇게되면 웹 브라우저가 스스로 해당 url로 바꾼뒤 새롭게 검색합니다. (자동 리다이렉트)

 

리다이렉션 종류

  • 영구 리다이렉션 - 특정 리소스의 URI가 영구적으로 이동
    • 예) /members -> /users
    • 예) /event -> /new-event
  • 일시 리다이렉션 - 일시적인 변경
    • 주문 완료 후 주문 내역 화면으로 이동
    • PRG 패턴 : Post/Redirect/Get
  • 특수 리다이렉션
    • 결과 대신 캐시를 사용
    • 캐시가 만료된 것 같아 캐시와 관련된 정보를 서버에 제공했는데, 서버에서 캐시사용해도 되니깐 계속 사용하라고 응답하는 경우

 

영구 리다이렉션 - 301, 308

  • 리소스의 URI가 영구적으로 이동
  • 원래의 URL을 사용하지 않고, 검색 엔진 등에서도 변경 인지
  • 301 Moved Permanently
    • 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
    • POST로 요청을 했을 시에는 다시 처음부터 입력을 해야됩니다. (POST 요청 메서드가 GET 메서드로 바뀌었기 때문)
  • 308 Permanent Redirect
    • 301과 기능은 같음
    • 리다이렉트시 요청 메서드와 본문 유지(처음 POST를 보내면 리다이렉트도 POST 유지)

 

일시적인 리다이렉션 - 302, 307, 303

  • 리소스의 URI가 일시적으로 변경
  • 따라서 검색 엔진 등에서 URL을 변경하면 안됨
  • 302 Found
    • 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음
  • 307 Temporary Redirect
    • 302와 기능은 같음
    • 리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안된다.)
  • 303 See Other
    • 302와 기능은 같음
    • 리다이렉트시 요청 메서드가 GET으로 변경

 

PRG : Post / Redirect / Get

일시적인 리다이렉션 - 예시
  • POST로 주문후에 웹 브라우저를 새로고침하면?
  • 새로고침은 다시 요청
  • 중복 주문이 될 수 있다.

 

원칙적으로는 서버에서 막아줘야합니다. 그래도 클라이언트에서도 하나정도는 막아주면 좋습니다. 위의 문제를 해결하기 위해 PRG라는 패턴을 주로 씁니다.

  • POST로 주문후에 새로 고침으로 인한 중복 주문 방지
  • POST로 주문후에 주문 결과 화면을 GET 메서드로 리다이렉트
  • 새로고침해도 결과 화면을 GET으로 조회
  • 중복 주문 대신에 결과 화면만 GET으로 다시 요청

  • 3번의 응답 상태 코드는 302, 303 모두 가능합니다.

이렇게되면 사용성이 좋습니다. 사용자의 입장에서 실수로 새로고침해도 결과화면이 깔끔하게 보이고 서버입장에서는 오류가 줄어들기 때문입니다.

 

위의 경우 303, 307을 권장하지만 현실적으로 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용하고 있다고 합니다. 위처럼 자동 리다이렉션시에 GET으로 변해도 되면 302를 사용해도 큰 문제는 없습니다.

 

기타 리다이렉션

  • 300 Multiple Choices : 안쓴다.
  • 304 Not Modified
    • 캐시를 목적으로 사용
    • 클라이언트에게 리소스가 수정되지 않았음을 알려줍니다. 따라서 클라이언트는 로컬에 저장된 캐시를 재사용합니다.
    • 304 응답은 응답에 메시지 바디를 포함하면 안됩니다. (로컬 캐시를 사용해야 함)
    • 조건부 GET, HEAD 요청 시 사용

 

 

 

4xx (클라이언트 오류), 5xx (서버 오류)

 

4xx (Client Error)

  • 클라이언트의 요청에 잘못된 문법등으로 서버가 요청을 수행할 수 없음
  • 오류의 원인이 클라이언트에 있음
  • 중요! 클라이언트가 이미 잘못된 요청, 데이터를 보내고 있기 때문에, 똑같은 재시도가 실패함

 

400 Bad Request

클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없음
  • 요청 구문, 메시지 등등 오류
  • 클라이언트는 요청 내용을 다시 검토하고, 보내야함
  • 예) 요청 파라미터가 잘못되거나, API 스펙이 맞지 않을 때

 

401 Unauthorized

클라이언트가 해당 리소스에 대한 인증이 필요함
  • 인증(Authentication) 되지 않음
  • 401 오류 발생시 응답에 WWW-Authenticate 헤더와 함께 인증 방법을 설명
  • 참고
    • 인증 (Authentication) : 본인이 누구인지 확인, (로그인)
    • 인가 (Authorization) : 권한 부여 (ADMIN 권한처럼 특정 리소스에 접근할 수 있는 권한, 인증이 있어야 인가가 있음)
    • 오류 메시지가 Unauthorized 이지만 인증 되지 않음 (이름이 아쉬움)

 

403 Foribidden

서버가 요청을 이해했지만 승인을 거부함
  • 주로 인증 자격 증명은 있지만, 접근 권한이 불충분한 경우
  • 예) ADMIN 등급이 아닌 사용자가 로그인은 했지만, ADMIN 등급의 리소스에 접근하는 경우

 

404 Not Found

요청 리소스를 찾을 수 없음
  • 요청 리소스가 서버에 없음
  • 또는 클라이언트가 권한이 부족한 리소스에 접근할 때 해당 리소스를 숨기고 싶을 때

 

 

5xx (Server Error)

  • 서버 문제로 오류 발생
  • 서버에 문제가 있기 때문에 재시도하면 성공할 수도 있음(서버가 복구 되는 경우)

 

500 Internal Server Error

서버 문제로 오류 발생, 애매하면 500 오류
  • 서버 내부 문제로 오류 발생
  • 애매하면 500 오류

 

503 Service Unavailable

서비스 이용 불가
  • 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음
  • Retry-After 헤더 필드로 얼마뒤에 복구되는지 보낼 수도 있음

 

 

 

 

 

출처

 

모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의

실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...

www.inflearn.com

 

클라이언트에서 서버로 데이터 전송

  1. 쿼리 파라미터를 통한 데이터 전송
    • GET
    • 주로 정렬 필터 (검색어 - URL에 치는 검색어)
  2. 메시지 바디를 통한 데이터 전송
    • POST, PUT, PATCH
    • 회원 가입, 상품 주문, 리소스 등록, 리소스 변경

 

클라이언트에서 서버로 데이터 전송 - 4가지 상황

  • 정적 데이터 조회
    • 이미지, 정적 텍스트 문서
  • 동적 데이터 조회
    • 주로 검색, 게시판 목록에서 정렬 필터(검색어)
  • HTML Form을 통한 데이터 전송
    • 회원 가입, 상품 주문, 데이터 변경
  • HTTP API를 통한 데이터 전송
    • 회원 가입, 상품 주문, 데이터 변경
    • 서버 to 서버, 앱 클라이언트, 웹 클라이언트(Ajax)

 

정적 데이터 조회 - 쿼리 파라미터 미사용

이미지 경로만 URI에 넣어서 GET 요청을하면 서버에서는 해당 경로에 있는 데이터를 클라이언트에게 반환해줍니다. 정적 데이터를 조회할 때는 파라미터가 필요하지 않습니다.

 

정적 데이터 조회 - 정리

  • 이미지, 정적 테스트 문서
  • 조회는 GET 사용
  • 정적 데이터는 일반적으로 쿼리 파라미터 없이 리소스 경로로 단순하게 조회 가능

 

동적 데이터 조회 - 쿼리 파라미터 사용

동적 데이터를 조회할 때는 데이터를 서버측에 넘겨줘야합니다. 이때, 쿼리 파라미터를 URI에 추가하여 사용합니다. 


동적 데이터 조회 - 정리

  • 주로 검색, 게시판 목록에서 정렬 필터 (검색어)
  • 조회 조건을 줄여주는 필터, 조회 결과를 정렬하는 정렬 조건에 주로 사용
  • 조회는 GET 사용
  • GET은 쿼리 파라미터를 사용해서 데이터를 전달

 

HTML Form 데이터 전송 - POST 전송 (저장)

form tag를 사용해 웹브라우저가 submit 버튼을 클라이언트에서 누르게 되면 form의 데이터를 읽어서 http 메시지를 생성해줍니다. 

  • username=kim&age=20 
    • 쿼리 파라미터와 거의 유사하게 key=value 스타일로 데이터를 만들고 http body에 넣어준 모습입니다.

만약, 위의 method를 "GET"으로 바꾸면 어떻게 될까요??

 

GET이니까 body에 데이터가 들어가지 않고 쿼리 파라미터처럼 넣어서 서버로 전달합니다.

 

 

HTML Form 데이터 전송 - multipart/form-data

multipart/form-data는 파일 같은 것을 전송할 때 쓰는 인코딩 타입입니다. 이럴 때는 message body에 넣는 방식을 사용해야합니다. message Body에 boundary를 통해 각각의 key의 value가 어떤 값인지 나타낼 수 있또록 자동으로 생성해줍니다. 

 

HTML Form 데이터 전송

  • HTML Form submit시 POST 전송
    • 예) 회원 가입, 상품 주문, 데이터 변경

  • Content-Type : application/x-www-form-urlencoded 사용
    • form의 내용을 메시지 바디를 통해서 전송(key=value, 쿼리 파라미터 형식)
    • 전송 데이터를 url encoding 처리
      • 예) abc김 -> abc%EAA%B9%80
  • HTML Form은 GET 전송도 가능

  • Content-Type: multipart/form-data
    • 파일 업로드 같은 바이너리 데이터 전송시 사용
    • 다른 종류의 여러 파일과 폼의 내용 함께 전송 가능 (그래서 이름이 multipart)
  • 참고: HTML Form 전송은 GET, POST만 지원

 

HTTP API 데이터 전송

보통 라이브러리가 있는데 사용해서 넘기면 됩니다.

 

 

HTTP API 데이터 전송 - 정리

  • 서버 to 서버
    • 백엔드 시스템 통신
  • 앱 클라이언트
    • 안드로이드, 아이폰
  • 웹 클라이언트
    • HTML에서 Form 전송 대신 자바 스크립트를 통한 통신에 사용 (AJAX)
    • 예) React, VueJs 같은 웹 클라이언트와 API 통신
  • POST, PUT, PATCH : 메시지 바디를 통해 데이터 전송
  • GET: 조회, 쿼리 파라미터로 데이터 전달
  • Content-Type: application/json을 주로 사용 (사실상 표준)
    • TEXT, XML, JSON 등등

 

 

 

HTTP API 설계 예시

  • HTTP API - 컬렉션
    • POST 기반 등록
    • 예) 회원 관리 API 제공
  • HTTP API - 스토어
    • PUT 기반 등록
    • 예) 정적 컨텐츠 관리, 원격 파일 관리
  • HTML FORM 사용
    • 웹 페이지 회원 관리
    • GET, POST만 지원

 

회원 관리 시스템 API 설계 - POST 기반 등록

  • 회원 목록 /members -> GET
  • 회원 등록 /members -> POST
  • 회원 조회 /members/{id} -> GET
  • 회원 수정 /members/{id} -> PATCH, PUT, POST
  • 회원 삭제 /members/{id} -> DELETE

 

회원 관리 시스템 POST - 신규 자원 등록 특징 (서버에서 리소스 URI를 결정하고 만들어줌)

  • 클라이언트는 등록될 리소스의 URI를 모릅니다.
    • 회원 등록 /members -> POST
    • POST /members
  • 서버가 새로 등록된 리소스 URI를 생성해줍니다.
    • HTTP/1.1 201 Created
      Location: /members/100
  • 컬렉션(Collection)
    • 서버가 관리하는 리소스 디렉토리
    • 서버가 리소스의 URI를 생성하고 관리
    • 여기서 컬렉션은 /members

 

파일 관리 시스템 API 설계 - PUT 기반 등록

  • 파일 목록 /files -> GET
  • 파일 조회 /files/{filename} -> GET
  • 파일 등록 /files/{filename} -> PUT
  • 파일 삭제 /files/{filename} -> DELETE
  • 파일 대량 등록 /files -> POST

 

파일 관리 시스템 PUT - 신규 자원 등록 특징

  •  클라이언트가 리소스 URI를 알고 있어야 합니다.
    • 파일 등록 /files/{filename} -> PUT
    • 여기서 filename을 클라이언트가 알고 있어야합니다.
  • 클라이언트가 직접 리소스의 URI를 지정합니다.
  • 스토어(Store)
    • 클라이언트가 관리하는 리소스 저장소
    • 클라이언트가 리소스의 URI를 알고 관리
    • 여기서 스토어는 /files

 

POST 등록과 PUT 등록 중 많이 사용하는 것은 POST기반의 컬렉션을 많이 사용합니다. 

 

 

HTML FORM 사용

  • HTML FROM은 GET, POST만 지원
  • AJAX 같은 기술을 사용해서 해결 가능 -> 회원 API 참고
  • 여기서는 순수 HTML, HTML FORM 이야기
  • GET, POST만 지원하므로 제약이 있음

 

회원 관리 시스템 API 설계 - HTML FORM 기반

  • 회원 목록    /members -> GET
  • 회원 등록 폼    /members/new -> GET
  • 회원 등록    /members/new, /members -> POST
  • 회원 조회    /members/{id} -> GET
  • 회원 수정 폼    /members/{id}/edit -> GET
  • 회원 수정    /members/{id}/edit, /members/{id} -> POST 
  • 회원 삭제    /members/{id}/delete -> POST
  • 회원 등록(new), 수정(edit), 삭제(delete)의 경우 GET, POST만 사용할 수 있는 HTML FORM에서는 컨트롤 URI(동사로된 URI)를 쓸 수 밖에 없습니다.
  • 단, 컨트롤 URI는 최대한 리소스로 설계를 하고 도저히 안될때만 사용해야 합니다.

 

정리

  • HTTP API - 컬렉션
    • POST 기반 등록
    • 서버가 리소스 URI 결정
  • HTTP API - 스토어
    • PUT 기반 등록
    • 클라이언트가 리소스 URI 결정
  • HTML FORM 사용
    • 순수 HTML + HTML form 사용
    • GET, POST만 지원

 

참고하면 좋은 URI 설계 개념

  • 문서(document)
    • 단일 개념(파일 하나, 객체 인스턴스, 데이터베이스 row)
    • 예) /members/100, /files/star.jpg
  • 컬렉션(collection)
    • 서버가 관리하는 리소스 디렉터리
    • 서버가 리소스의 URI를 생성하고 관리
    • 예) /members
  • 스토어(store)
    • 클라이언트가 관리하는 자원 저장소
    • 클라이언트가 리소스의 URI를 알고 관리
    • 예) /files
  • 컨트롤러(controller), 컨트롤 URI
    • 문서, 컬렉션, 스토어로 해결하기 어려운 추가 프로세스 실행
    • 동사를 직접 사용
    • 예) /members/{id}/delete

 

 

참고할만한 사이트

 

REST Resource Naming Guide

In REST, having a strong and consistent REST resource naming strategy – will prove one of the best design decisions in the long term.

restfulapi.net

 

 

 

출처

 

모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의

실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...

www.inflearn.com

 

 

싱글톤 패턴은 객체의 인스턴스가 오직 1개만 생성되는 패턴을 의미합니다. 

 

구현

public class Singleton {

    private static Singleton instance = new Singleton();
    
    private Singleton() {
        // 생성자는 외부에서 호출못하게 private 으로 지정해야 한다.
    }

    // 1. Eager Initailization
    public static Singleton getInstance() {
        return instance;
    }
    
    // 2. Lazy Initailization
    public static synchronzied Singleton getInstance() {
      if(uniqueInstance == null) {
         uniqueInstance = new Singleton();
      }
      return uniqueInstance;
    }
    
    // 3. Lazy Initialization. DCL
    public static Singleton getInstance() {
      if(uniqueInstance == null) {
         synchronized(Singleton.class) {
            if(uniqueInstance == null) {
               uniqueInstance = new Singleton(); 
            }
         }
      }
      return uniqueInstance;
    }
}

싱글톤 패턴의 특징은 두가지가 있습니다.

  1. private 생성자
  2. static method

private 생성자는 외부에서 객체를 생성할 수 없도록하기위해 사용합니다. (객체를 오직 한번만 생성하도록)
static 키워드의 특징을 이용해서 클래스 로더가 초기화 하는 시점에서 정적 바인딩(static binding)을 통해 해당 인스턴스를 메모리에 등록해서 사용하는 것 입니다. 

 

 

싱글톤 패턴을 사용하는 이유

  1. 메모리 측면
    • 최초 한번의 new 연산자를 통해서 고정된 메모리 영역을 사용하기 때문에 해당 객체에 접근할 때 사용되는 메모리 낭비를 방지할 수 있습니다.
  2. 쉬운 데이터 공유
    • 싱글톤 인스턴스는 전역으로 사용되는 인스턴스이기 때문에 다른 클래스의 인스턴스들이 접근하여 사용할 수 있습니다.
    • 하지만, 여러 클래스의 인스턴스에서 싱글톤 인스턴스의 데이터에 동시에 접근하게 되면 동시성 문제가 발생할 수 있으니 유의하여 설계해야 합니다.

 

 

싱글톤 패턴의 문제점

  1. 싱글톤 패턴을 구현하는 코드 자체가 많이 필요합니다.
    • 앞서 소개한 구현 방법외에도 정적 팩토리 메서드에서 객체 생성을 확인하고 생성자를 호출하는 경우에 멀티스레딩 환경에서 발생할 수 있는 동시성 문제 해결을 위해 syncronized 키워드를 사용해야 합니다
  2. 테스트하기 어렵다.
    • 싱글톤 인스턴스는 자원을 공유하고 있기 때문에 테스트가 결정적으로 격리된 환경에서 수행되려면 매번 인스턴스의 상태를 초기화시켜주어야 합니다. 그렇지 않으면 애플리케이션 전역에서 상태를 공유하기 때문에 테스트가 온전하게 수행되지 못합니다.
  3. 의존 관계상 클라이언트가 구체 클래스에 의존합니다.
    • new 키워드를 직접 사용하여 클래스 안에서 객체를 생성하고 있으므로, 이는 SOLID 원칙 중 DIP (의존관계역전)를 위반하게 되고 OCP (개방-폐쇄)원칙 또한 위반할 가능성이 높다.   => 스프링에서는 빈 컨테이너를 통해 해결합니다.

'PROGRAM_SOLVING' 카테고리의 다른 글

[선착순 이벤트] 쿠폰 발급  (4) 2024.10.10

HTTP API를 만들어보자

요구사항 - 회원 정보 관리 API를 만들어라.

  • 회원 목록 조회
  • 회원 조회
  • 회원 등록
  • 회원 수정
  • 회원 삭제

 

API URI 설계

  • 회원 목록 조회 /read-member-list
  • 회원 조회 /read-member-by-id
  • 회원 등록 /create-member
  • 회원 수정 /update-member
  • 회원 삭제 /delete-member

 

 

이것은 좋은 URI 설계일까?

URI를 설계할 때 기준을 두어야할 것은 리소스 식별입니다.

 

 

API URI 고민

  • 리소스의 의미는 뭘까?
    • 회원을 등록하고 수정하고 조회하는게 리소스가 아닙니다.
    • 예) 미네랄을 캐라 -> 미네랄이 리소스
    • 회원이라는 개념 자체가 바로 리소스입니다.
  • 리소스를 어떻게 식별하는게 좋을까?
    • 회원을 등록하고 수정하고 조회하는 것을 모두 배제
    • 회원이라는 리소스만 식별하면 됩니다. -> 회원 리소스를 URI에 매핑

그래서 설계를 해보면 아래와 같이 됩니다.

 

 

API URI 설계

  • 회원 목록 조회 /members
  • 회원 조회 /members/{id} -> 어떻게 구분하지??
  • 회원 등록 /members/{id} -> 어떻게 구분하지??
  • 회원 수정 /members/{id} -> 어떻게 구분하지??
  • 회원 삭제 /members/{id} -> 어떻게 구분하지??

회원이라는 리소스만 식별했지만 조회, 등록, 수정, 삭제를 구분하기가 불가능해졌습니다. 

 

 

리소스와 행위를 분리 - 가장 중요한 것은 리소스를 식별하는 것

  • URI는 리소스만 식별
  • 리소스와 해당 리소스를 대상으로 하는 행위를 분리
    • 리소스 : 회원
    • 행위 : 조회, 등록, 삭제, 변경
  • 리소스는 명사, 행위는 동사(미네랄을 캐라)
  • 행위(메서드)는 어떻게 구분할까??

이러한 행위는 HTTP Method가 합니다.

 

 

 

HTTP 메서드 - GET, POST

 

HTTP 메서드 종류 - 주요 메서드

  • GET : 리소스 조회
  • POST : 요청 데이터 처리, 주로 등록에 사용
  • PUT : 리소스를 대체, 해당 리소스가 없으면 생성 (파일에 폴더를 넣는 것과 같다고 생각하면 됨.)
  • PATCH : 리소스 부분 변경 (회원의 이름을 바꾸거나 특정 필드를 바꿀 때 사용)
  • DELETE : 리소스 삭제

 

GET 

  • 리소스 조회
  • 서버에 전달하고 싶은 데이터는 query(쿼리 파라미터, 쿼리 스트링)을 통해서 전달
  • 메시지 바디를 사용해서 데이터를 전달할 수 있지만, 지원하지 않는 곳이 많아서 권장하지 않음

 

 

POST

  • 요청 데이터 처리
  • 메시지 바디를 통해 서버로 요청 데이터 전달
  • 서버는 요청 데이터를 처리
    • 메시지 바디를 통해 들어온 데이터를 처리하는 모든 기능을 수행한다.
  • 주로 전달된 데이터로 신규 리소스 등록, 프로세스 처리에 사용

POST 클라이언트 -> 서버 -> 클라이언트

 

POST - 요청 데이터를 어떻게 처리한다는 뜻일까에 대한 예시

  • 스펙 : POST 메서드는 대상 리소스가 리소스의 고유 한 의미 체계에 따라 요청에 포함 된 표현을 처리하도록 요청합니다. (구글번역)
  • 예를 들어 POST는 다음과 같은 기능에 사용됩니다.
    • HTML 양식에 입력 된 필드와 같은 데이터 블록을 데이터 처리 프로세스에 제공
      • 예) HTML FORM에 입력한 정보로 회원 가입, 주문 등에서 사용
    • 게시판, 뉴스 그룹, 메일링 리스트, 블로그 또는 유사한 기사 그룹에 메시지 게시
      • 예) 게시판 글쓰기, 댓글 달기
    • 서버가 아직 식별하지 않은 새 리소스 생성
      • 예) 신규 주문 생성
    • 기존 자원에 데이터 추가
      • 예) 한 문서 끝에 내용 추가하기
    • 정리 : 이 리소스 URI에 POST 요청이 오면 요청 데이터를 어떻게 처리할지 리소스마다 따로 정해야 함 -> 정해진 것이 없음

 

POST 정리

  1. 새 리소스 생성(등록)
    • 서버가 아직 식별하지 않은 새 리소스 생성
  2. 요청 데이터 처리
    • 단순히 데이터를 생성하거나, 변경하는 것을 넘어서 프로세스를 처리해야 하는 경우
    • 예) 주무에서 결제완료 -> 배달시작 -> 배달완료 처럼 단순히 값 변경을 넘어 프로세스의 상태가 변경되는 경우
    • POST의 결과로 새로운 리소스그ㅏ 생성되지 않을 수도 있음
    • 예) POST /orders/{orderId}/start-delivery (컨트롤 URI)
  3. 다른 메서드로 처리하기 애매한 경우
    • 예) JSON으로 조회 데이터를 넘겨야 하는데, GET 메서드를 사용하기 어려운 경우
    • 애매하면 POST

 

 

 

HTTP 메서드 - PUT, PATCH, DELETE

 

PUT

  • 리소스가 있으면 대체
  • 리소스가 없으면 생성
  • 쉽게 이야기해서 덮어버림
  • 중요! 클라이언트가 리소스를 식별
    • 클라이언트가 리소스 위치를 알고 URI 지정 (/members/100 - 100번째라는 리소스 위치를 알고 있음)
    • POST와 차이점

PUT은 resource를 바꾸는게 아닌 덮어버림

 

PATCH

  • 리소스 부분 변경



DELETE

  • 리소스 제거

 

 

 

HTTP 메서드의 속성

 

안전

  • 호출해도 리소스를 변경하지 않는다.

 

멱등

  • f(f(x)) = f(x)
  • 한 번 호출하든 두 번 호출하든 100번 호출하든 결과가 같아야 합니다.
  • 멱등 메서드
    • GET : 한 번 조회하든, 두 번 조회하든 같은 결과가 조회됩니다.
    • PUT : 결과를 대체합니다. 따라서 최종 결과는 같습니다.
    • DELETE : 결과를 삭제합니다. 따라서 최종 결과는 같습니다.
    • POST : 멱등이 아닙니다. 두 번 호출하면 같은 결제가 중복해서 발생할 수 있습니다.
  • 활용
    • 자동 복구 메커니즘
    • 서버가 TIMEOUT 등으로 정상 응답을 못주었을 때, 클라이언트가 같은 요청을 다시 해도 되는가? 판단 근거
  • 생각
    • Q: GET을 재 요청할 때 중간에 리소스를 변경해버리면?
      • 사용자 1 : GET -> username : A, age : 20
      • 사용자 2 : PUT -> age : 30
      • 사용자 1 : GET -> username: A, age: 30
    • A: 멱등은 외부 요인으로 중간에 리소스가 변경되는 것 까지는 고려하지 않습니다.

 

캐시가능

  • 응답 결과 리소스를 캐시해서 사용해도 되는가?
  • GET, HEAD, POST, PATCH 캐시가능
  • 실제로는 GET, HEAD 정도만 캐시로 사용 (body를 사용하지 않기 때문에 url만 Key로 잡으면 되기 때문에 심플)
    • POST, PATCH는 본문 내용까지 캐시 키로 고려해야 하는데, 구현이 쉽지 않음

 

 

 

출처

 

모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의

실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...

www.inflearn.com

 

가상 메모리란?

보조 기억장치에 비해 상대적으로 작은 크기를 가지고 있는 메인 메모리를, 더욱 더 효율적이고 대용량의 프로그램을 사용하기 위해 사용하는 기술입니다.
특정 시점마다 실제 사용하는 메모리는 그렇게 크지 않다는 점에 착안해서 고안된 기술입니다. 

가상 메모리를 사용하게 되면 프로세스 간 공간 분리를 하게 되는데 이를 통해 프로세스 간 메모리 영역 침범 이슈를 방지할 수 있고, 보조 기억장치를 활용하면서 메모리 용량 부족에 대한 이슈도 해결할 수 있습니다.

가상 메모리 기법을 사용하게 되면 CPU는 메모리의 실제 주소인 Physical Address 대신 Virtual address에 먼저 접근하게 됩니다. 이때 페이지 테이블을 참조하여 Virtual Address를 Physical Address로 변환하여 실제 메모리에 접근하게 되는데 이러한 변환 과정이 굉장히 빈번하게 일어나고 속도가 굉장히 중요하므로 MMU라는 하드웨어 칩의 지원을 받습니다.

 

MMU란?

MMU는 Memory Management Unit으로 CPU가 코드를 실행하며 가상 메모리 주소에 접근할 때 가상 메모리 주소를 실제 물리적인 주소로 변환해주는 하드웨어 장치입니다.


Page란?

가상 메모리 기법을 사용할 때 어느정도의 크기씩 실제 메모리에 올려놓는 기본 단위가 되는 것이 페이지입니다. 

페이지 단위로 관리하게 되며 페이지 번호를 바탕으로 가상 메모리 주소와 실제 메모리 주소를 매핑하여 페이지 테이블에 기록하고 관리하게 됩니다.

가상 메모리 주소 = (p, d)로 이루어져있고, p는 가상 메모리 페이지, d는 distance로 p 내 offset을 의미합니다.

 

 

가상 메모리 기법의 흐름

지금까지 배운 가상 메모리 기법의 흐름을 정리해보면, CPU가 명령어를 실행하던 중 가상 메모리 주소를 참조하게 되면 하드웨어 칩셋인 MMU를 거쳐서 실제 메모리에 올라가있는 페이지 테이블을 참조하여 실질적인 메모리 주소로 변환하게 되고 메모리에 접근하게 됩니다. 메모리에 반복적으로 접근하고 데이터를 읽어오게 되는데 이러한 속도는 CPU나 레지스터 처리 속도에 비하면 굉장히 느린 속도입니다. 이 부분에서 성능 향상을 위해서 TLB라는 하드웨어를 사용하게 됩니다.

 

TLB(Translation Lookaside Buffer)란?

TLB란 최근에 접근한 페이지 정보를 기록하는 하드웨어 칩셋입니다. 즉, 가상 메모리 주소가 한번 물리 주소로 변환되면 TLB에 기록하고 그 다음부턴 MMU가 페이지 테이블을 참조하는 것이 아닌 TLB를 통해 물리 주소를 먼저 찾습니다. 이를 통하여 상대적으로 속도가 느린 메모리에 접근하는 횟수를 줄여 성능을 향상 시켜줍니다.

 

페이지 폴트(Page fault)란?

가상 메모리 주소를 통해서 실제 물리 주소를 얻고 메모리에 접근했지만 내가 원하는 페이지가 실제 메모리에 적재되어 있지 않을수도 있습니다. 이렇게 내가 찾는 페이지가 실제 메모리에 현재 적재되어 있지 않을 때를 페이지 폴트라고 합니다. 페이지 폴트가 발생하면 보조기억장치에서 지금 내가 필요한 페이지를 가져오게 됩니다. 보조 기억장치는 메모리보다 속도가 더 느리기 때문에 자주 참조하면 성능이 떨어지게 됩니다. 따라서 페이지 폴트를 줄이기 위해서 다양한 기법들이 사용됩니다. 

 

페이지 교체 알고리즘

페이지 폴트가 발생했을 시 물리 메모리에 비어있는 프레임이 있다면, 비어있는 프레임에 원하는 메모리를 보조 기억장치에서 가져오면 됩니다. 하지만, 프레임이 가득 차 있을 시에는 페이지 교체 알고리즘을 통해 빈 프레임을 만들어주고 보조 기억장치에서 원하는 메모리를 가져와 적재해야 합니다. 페이지 교체 알고리즘에는 FIFO, LRU 등이 있습니다.

FIFO는 가장 먼저 물리 메모리에 적재된 페이지를 선택하는 방식입니다.
LRU는 Least Recent Used의 약자로 가장 오랫동안 사용되지 않았던 페이지를 선택하는 방식입니다.

 

AVL 트리는 스스로 균형을 잡는 이진 탐색 트리로 일반적인 이진 탐색 트리의 최악의 경우를 보완하기 위해 만들어진 트리입니다. 모든 노드에 대해서 노드의 왼쪽 자식 노드와, 오른쪽 자식 노드의 높이 차이가 1이하인 이진탐색트리입니다.

AVL 트리는 어떤 시점에서 왼쪽 자식의 노드와 오른쪽 자식 노드의 높이 차이가 1보다 커지면 AVL 트리 속성을 유지하기 위해 스스로 균형을 잡습니다.

 

AVL 트리의 검색, 삽입, 삭제는 평균과 최약의 경우 모두 O(log N) 시간복잡도 걸립니다. 삽입과 삭제는 이상의 트리 회전을 통해 균형을 잡을 있습니다.

 

AVL 트리의 속성을 유지하기 위해 4가지(LL, RR, LR, RL)의 문제가 발생했을 때 균형을 잡기위해 트리를 회전합니다. 예시와 해결 방법은 아래와 같습니다.



LL
문제

  • 왼쪽으로 노드가 쏠리는 문제입니다.  (부모노드의 균형도가 양수)

해결 방법: 부모노드를 좌측 자식 노드의 우측 자식 노드로, 좌측 자식 노드의 우측 노드를 부모노드의 좌측 자식 노드로 연결합니다.



RR
문제

  • 오른쪽으로 노드가 쏠리는 문제입니다.  (부모노드의 균형도가 음수)

해결 방법: 부모 노드를 우측 자식 노드의 좌측 자식노드로 연결하고, 우측 자식의 좌측 노드를 부모노드의 우측 자식노드로 연결합니다.


LR
문제

  • 부모 노드 균형 2, 좌측 자식 노드 균형이 -1인 경우

해결 방법


RL
문제

  • 부모 노드 균형 -2, 오른 자식 노드 균형이 1인 경우


해결 방법: 위의 LR 문제 해결 방법의 순서를 반대로 LL 문제 해결과 동일하게 해준 뒤, RR 문제 해결방식으로 해결해주면 됩니다.

 

'자료구조 & 알고리즘' 카테고리의 다른 글

monotone stack  (0) 2023.05.23

+ Recent posts