백엔드 이론을 위한 IT 용어 정리

2024-06-01

네트워크 용어 참고 내용

업무만 하다보니 이론을 너무 까먹어서 정리하려고 한다.

용어정리 – 데이터 베이스

  • 트랜잭션 : 하나의 논리적 기능을 수행하기 위한 작업 단위, 쪼갤수 없는 업무의 최소단위
  • 트랜잭션 격리수준(Isolation Level): 동시에 여러 트랜잭션이 실행될 때, 트랜잭션 끼리 서로 얼마나 고립 되어 있는지를 확인하는 것, 격리수준이 내려갈수록 성능이 좋아지지만 오류가 발생할 가능성이 커진다.
    • SERIALIZABLE: 가장 강력한 격리수준으로 읽기 작업에도 잠금을 발생시켜 다른 트랜잭션이 레코드를 변경할 수 없도록 한다. 동시처리 능력이 떨어지고 성능이 저하된다.
    • REPEATABLE READ: 트랜잭션이 시작되기 전에 COMMIT된 내용에 대해서만 조회할 수 있는 격리 수준이다. Phantom Read가 발생할수 있다.
    • READ COMMITTED: 어떤 트랜잭션의 변경내용이 COMMIT되어야만 다른 트랜잭션에서 조회할 수 있다. Non-Repeatable Read가 발생한다.
    • READ UNCOMMITTED: 어떤 트랙잭션의 변경내용이 COMMIT이나 ROLLBACK에 상관없이 모두 노출된다. Dirty Read가 발생 할수 있다.
  • 트랜잭션 부정합 종류:
    • Phantom Read(유령 읽기) : 트랜잭션이 끝나기 전에 다른 트랜잭션에 의해 추가된 레코드가 조회됨
    • Non-Repeatable Read(반복 읽기 불가능) : 서로 다른 트랜잭션이 동일한 행을 업데이트하고 커밋할 때 행을 다시 읽을 때 다른 값을 가져오는 경우
    • Dirty Read : 트랜잭션의 작업이 완료되지 않았는데도 다른 트랜잭션에서 해당 데이터를 읽는 현상
  • ACID 속성 : 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질
    • Atomicity(원자성): 트랜잭션의 연산은 모든 연산이 완벽히 수행되어야 하며, 한 연산이라도 실패하면 트랜잭션 내의 모든 연산은 실패한다.
    • Consistency(일관성): 트랜잭션은 유효한 상태로만 변경될 수 있습니다.
    • Isolation(고립성): 트랜잭션은 동시에 실행될 경우 다른 트랜잭션에 의해 영향을 받지 않고 독립적으로 실행되어야 한다.
    • Durability(내구성): 트랜잭션이 커밋된 이후에는 시스템 오류가 발생하더라도 커밋된 상태로 유지되는 것을 보장해야 한다.
  • 데이터베이스 파티셔닝: 기존에 사용하던 DB시스템의 용량의 한계와 성능저하를 가지고 오게 되어 TABLE을 파티션(Partion)이라는 작은 단위로 나누어 관리하는 기법, 가용성, 관리용이성, 성능 등 이점이 있지만 JOIN 비용이 늘어난다.

  • 정규화: 데이터베이스 설계 시 데이터의 중복을 줄이고, 데이터 무결성을 향상시키며, 데이터베이스의 성능을 최적화하기 위해 데이터를 체계적으로 정리하는 과정, 하나의 릴레이션에 여러 앤티티의 애트리뷰트들을 혼합하게 되면 정보가 중복 저장되며, 저장공간이 낭비되고 이상이 발생한다. (삽입이상, 삭제이상, 갱신이상 등)

    • 제 1 정규형 (1NF: First Normal Form) : 각 필드는 하나의 값만 가져야 합니다
    • 제 2 정규형 (2NF: Second Normal Form) : 기본 키의 부분 집합에 종속된 모든 속성이 없어야 한다.
    • 제 3 정규형 (3NF: Third Normal Form) : 기본 키에 비이행적으로 종속된 모든 속성이 없어야 한다
    • 보이스-코드 정규형 (BCNF: Boyce-Codd Normal Form) : 모든 결정자가 후보 키(candidate key)이어야 한다.
    • 제 4 정규형 (4NF: Fourth Normal Form) : 다치 종속성(Multi-Valued Dependency)을 제거
    • 제 5 정규형 (5NF: Fifth Normal Form) : 조인 종속성(Join Dependency)을 제거


  • 클러스터: 디스크로부터 데이터를 읽어오는 시간을 줄이기 위해 조인이나 자주 사용하는 테이블의 데이터를 디스크의 같은 위치에 저장시키는 것, 데이터 조회 속도는 향상시키지만 저장, 수정, 삭제 또는 한 테이블 전체 Scan의 성능은 감소한다. (주로 조회에 사용되고 컬럼안에 많은 중복데이터를 가지는 테이블, join을 자주 하는 테이블에 클러스터링을 한다.)

  • 인덱스(Index) : 데이터베이스 테이블의 검색 속도를 향상시키기 위해 사용되는 데이터 구조로 인덱스는 책의 색인처럼 특정 열(또는 여러 열)에 대한 빠른 검색을 가능하게 한다. 인덱스를 사용하면 테이블의 전체 행을 스캔하지 않고도 원하는 데이터를 빠르게 찾을 수 있다.

  • Clustered Index와 Non Clustered Index
    • 클러스터 인덱스(Clustered Index): 물리적으로 행을 재배열, 넌 클러스터 인덱스보다 작은 사이즈, 30%이내에서 사용해야 좋다. 테이블당 1개를 갖으며 Primary Key 설정 시 해당 칼럼은 자동적으로 클러스터 인덱스 생성
    • 논클러스터 인덱스(Non Clustered Index): 물리적으로 재배치하지 않음, 클러스터 인덱스 용량이 큼, 3% 이내에서 사용해야 좋은 선택도를 갖는다. 테이블당 249개를 갖으며 논클러스터 인덱스를 따로 명시해야 한다(인덱스 페이지를 따로 만듬)
  • Index 설정 기준
    • 카디널리티 (Cardinality) 높음 : 중복도가 낮은 칼럼
    • 선택도 (Selectivity) 낮음 : 한 칼럼으로 적은 ROW가 찾아진다
  • INDEX SCAN 종류
    • INDEX RANGE SCAN : B*Tree인덱스의 가장 일반적이고 정상적인 형태, 필요한 범위만 스캔
    • INDEX FULL SCAN : 처음부터 끝까지 수평적으로 탐색하는 방식, 최적의 인덱스가 없을 때 차선으로 선택
    • INDEX UNIQUE SCAN : 수직적 탐색만으로 데이터를 찾는 방식, 등치(=)조건으로 탐색하는 경우에 작동
    • INDEX SKIP SCAN : 인덱스 선두 컬럼이 조건절에 없어도 인덱스를 활용하는 방식, 조건절에 빠진 인덱스 선두 컬럼의 중복값이 많고 후행 컬럼의 중복값이 적을때 활용
  • 인덱스(Index) 유형
    • Filtered Index : 비 클러스터형 인덱스를 만들 때 WHERE 절을 사용해 거의 선택되지 않는 데이터를 제외하고 인덱스를 생성하는 방법, 필터 인덱스는 전체 테이블 인덱스에 비해 쿼리 성능을 개선하고 인덱스 유지관리 비용과 인덱스 저장소 비용을 줄일 수 있다는 장점이 있다. (SQL Server에서 사용가능)
    • Unique Index : Unique Index로 컬럼이 잡혀 있으면 해당 컬럼에는 중복된 데이터가 들어가지 않는다 Unique Index는 컬럼에 Null 값을 인정한다. (Primary Key와 차이점)


  • JOIN 기법 종류
    • 중첩 루프 조인 (Nested Loops Join) : 한 쪽 Join의 입력이 작고(10 행 미만), 다른 한 쪽의 Join의 입력이 아주 크고 Join 열에 인덱스가 지정된 경우 가장 빠른 방법, 순차적으로 실행되고 선행 테이블의 처리 범위가 전체 일의 양을 결정하며 선행 테이블 열의 값을 가지고 후행 테이블의 인덱스 페이지를 액세스하기 때문에 후행 테이블의 인덱스 유무가 중요하다.(인덱스가 존재하는 테이블을 후행 테이블로 선택)
    • 병합 조인 (Sort Merge Join) : 두 Join 입력이 작지 않지만 Join 열을 (인덱스로부터 미리) 정렬된 상태로 가져올 수 있는 경우 가장 빠른 방법, 두 입력의 크기가 서로 비슷할 경우에는 Merge Join과 Hash Join 성능이 비슷하지만, 두 입력의 크기가 서로 많이 다를 경우 Hash Join 성능이 더 좋다. 정렬된 양쪽 결과를 스캔하는 방식이므로 인덱스 유무는 중요하지 않음, 조인 조건식이 등차(=)조건이 아니여도 가능
    • 해시 조인 (Hash Match Join) : Join 입력의 크기가 크고 정렬되지 않았으며 인덱싱되지 않은 입력을 효율적으로 처리하는 방법, 조인될 두 테이블 중 하나를 해시 테이블로 선정하여 조인될 테이블의 조인 키 값을 Hash 알고리즘으로 비교하여 매치되는 결과값을 얻는 방식, 조인 조건식이 등차(=)조건 일때만 가능
      • Build Input (outer table) : 테이블 중 작은 테이블을 읽어 해시 테이블을 생성한다.
      • Probe Input (inner table) : 큰 테이블을 읽으며 헤시 테이블을 탐색하며 Join 한다.


  • 데이터 무결성: 데이터의 정확성, 일관성, 유효성을 유지하는 것, RDBMS의 중요한 기능으로 주로 데이터에 적용하는 연산을 제한하여 무결성을 유지한다.
    • 개체 무결성(Entity integrity): 모든 테이블이 기본키로 선택된 필드를 가지고 있어야 한다. 기본키로 선택된 필드는 NULL을 허용하지 않는다.
    • 참조 무결성(Referential integrity): 참조관계에 있는 두 테이블의 데이터가 항상 일관된 값을 갖도록 유지하는 것

용어정리 – JAVA

  • JVM : 자바 가상 머신의 약자를 따서 줄여 부르는 용어로 JVM의 역할은 자바 애플리케이션을 클래스 로더를 통해 읽어 자바 API와 함께 실행하고 메모리 관리(GC)을 수행하는 스택기반의 가상머신이다.
    • Class Loader : VM내로 클래스를 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈
    • Execution engine(실행 엔진) : 바이트 코드를 실행시키는 역할
      • Interpreter : 바이트 코드를 한줄 씩 실행합니다.
      • JIT 컴파일러 : 인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러가 반복되는 코드를 네이티브 코드로 바꿔줍니다. 그 다음부터 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용합니다.
      • GC(Garbage Collector) : 힙 영역에서 사용되지 않는 객체들을 제거하는 작업을 수행
    • Runtime Data Areas: 프로그램 실행 중에 사용되는 다양한 영역
    • JNI(Java Native Interface): 자바 애플리케이션에서 C, C++, 어셈블리어로 작성된 함수를 사용할 수 있는 방법을 제공, Native 키워드를 사용하여 메서드를 호출 (대표적인 메서드는 Thread의 currentThread())
    • Native Method Library: C, C++로 작성된 라이브러리

  • Java의 실행방식
    • 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽어 자바 바이트코드(.class)로 변환
    • Class Loader를 통해 class 파일들을 JVM으로 로딩.
    • 로딩된 class파일들은 Execution engine을 통해 해석
    • 해석된 바이트코드는 Runtime Data Areas 에 배치되어 수행
  • JAVA 버전별 특징
    • JAVA 8 : Lambda, stream, Optional 추가 / 새로운 날짜 API(LocalDateTime) 추가
    • JAVA 11 : OracleJDK & OpenJdk 통합, OracleJDK 유료화, G1 GC 적용 , javac 컴파일 없이 실행 가능
    • JAVA 17 : Sealed Classes(봉인 클래스) 추가, RandomGenerator 추가 , Pattern Matching for switch
      • Sealed Classes : 허용된 클래스 외 상속을 막는다.
      • Pattern Matching for switch : 타입 매칭 추가, Null 처리 추가,
  • GC(Garbage Collector) :Heap 영역에서 동적으로 할당했던 메모리 중 필요 없게 된 메모리 객체(garbage)를 모아 주기적으로 제거한다. GC는 Minor GC, Major GC로 구분 되며, Minor GC는 young 영역에서, Major GC는 old 영역에서 일어난다. GC를 수행할 때는 GC를 수행하는 스레드 이외의 스레드는 모두 정지하며 이를 Stop-the-world라고 한다.
    • Minor GC : Young 영역은 Eden / Survivor 이라는 두 영역으로 나뉨, Eden 영역에서 참조가 남아있는 객체를 mark하고 survivor 영역으로 복사한다. 그리고 Eden 영역을 비운다. Survivor 영역도 가득차면 같은 방식으로 다른 Survivor 영역에 복사하고 비운다. 이를 반복하다 계속 해서 살아남는 객체는 old 영역으로 이동
    • Major GC(Full GC) : Old 영역의 메모리가 부족해지면 발생, 삭제되어야 하는 객체를 mark합니다. 그리고 지웁(sweep)니다. 메모리는 단편화 된 상태이므로 이를 한 군데에 모아주는 것을 Compaction이라 하며 compact라고 한다.
  • Mark & Sweep & Compact & Promotion
    • Mark: 접근 가능한 객체에 Mark하여 표시
    • Sweep: Mark되지 않은 객체들을 제거하는 과정
    • Compact: Sweep 과정에 의해 삭제되면 메모리 단편화가 발생하는데, Compact를 통해 빈자리들을 채워줌
    • Promotion : Survivor 영역에서 계속해서 살아남은 객체들이 특정 age 값에 도달하면, Old Generation으로 이동하게 되는 과정
  • GC(Garbage Collector) 알고리즘
    • Serial GC : 서버의 CPU 코어가 1개일 때 사용하기 위해 개발된 GC, Stop The World 시간이 길다, Mark & Sweep & Compact 알고리즘을 사용
    • Parallel GC : Serial GC와 기본적인 알고리즘은 같지만, Young 영역의 Minor GC를 멀티 쓰레드로 수행
    • G1 GC (Garbage First) : 기존의 GC 알고리즘에서는 Heap 영역을 물리적으로 고정된 Young/Old 영역으로 나누어 사용하였지만, G1 gc는 아예 이러한 개념을 뒤엎는 Region이라는 개념을 새로 도입하여 사용, 전체 Heap에 대해서 탐색하지 않고 부분적으로 Region 단위로 탐색하여, 각각의 Region에만 GC가 발생하기 떄문에 Stop The World 시간이 짧다
  • 자바의 메모리 영역
    • Stack 영역 : 기본 자료형(원시 자료형, Primitive type), 지역변수, 매개변수가 저장되는 메모리 영역, Heap 영역에 생성된 데이터의 참조값이 할당됨, 메소드가 호출될 때 메모리에 할당, 메서드 종료시 메모리에서 삭제된다.
    • Heap 영역 : 인스턴스를 생성(new)할 때 사용되는 메모리 영역, 참조형 데이터 객체의 실제 데이터가 저장되는 공간 (Stack 영역에서 실제데이터가 존재하는 Heap 영역의 참조값을 가지고 있다.), GC가 관리한다.
    • Static 영역 : static 키워드를 통해 생성된 정적멤버들은 모든 객체가 공유하며 어디서든지 참조할 수 있다. 그러나, GC의 관리 영역 밖에 존재하기 때문에 프로그램 종료시까지 메모리가 할당된 채로 존재한다.
  • 자바 원시타입 : boolean(1), char(unsigned 2), byte(1), short(2), int(4), long(8), float(4), double(8) / 단 JVM에 종속적임으로 대략적인 크기

  • Final : final 키워드는 변수(variable), 메서드(method), 또는 클래스(class)에 사용될 수 있으며 프로그램 실행 도중에 수정 할수 없다.
    • final 변수 : 한 번 초기화되면 그 이후에 변경할 수 없다.
    • final 메소드 : 오버라이딩을 금지한다.
    • final 클래스 : 다른 클래스에서 상속할 수 없다.
  • static final : 객체(인스턴스)가 아닌 클래스에 존재하는 단 하나의 상수 라는 의미. 클래스 상수는 클래스 선언과 동시에 초기화 하여야 한다.

  • JDK와 JRE : JDK는 Java Development KIT의 약자로 개발하는데 사용되는 도구이며 JRE를 포함하고 있으며 JRE는 Java Runtime Environment의 약자로 자바로 만들어진 프로그램을 실행시키는데 필요한 도구가 들어있는 차이가 있다.

  • Error와 Exception
    • Error : 실행 중 일어날 수 있는 치명적 오류. 컴파일 시점에 체크할 수 없고, 오류가 발생하면 프로그램은 비정상 종료 한다.
    • Exception : Error보다 비교적 경미한 오류이며, try-catch를 이용해 프로그램의 비정상 종료를 막을 수 있다.
      • Checked Exception과 Unchecked Exception
        • Checked Exception : RuntimeException을 상속하지 않고 반드시 에러 처리(try/catch or throw)를 해야한다. (대표적으로 FileNotFoundException)
        • UncheckedException : RuntimeException을 상속하면 UncheckedException. 체크 예외와는 달리 에러 처리를 강제하지 않음 (대표적으로 NullPointerException)
  • 동일성(identity)와 동등성(equality)
    • 동일성(identity) : 객체의 주소를 비교 ,equals() 사용하고 오버라이드 가능
    • 동등성(equality) : 객체가 같음을 비교 , == 사용
  • 오버라이딩과 오버로딩
    • 오버라이딩(Overriding) : 상위 클래스의 메소드를 재정의 하는 것을 의미.
    • 오버로딩(overloading) : 같은 클래스 내에서 동일한 메소드 이름을 가지지만, 매개변수의 타입, 개수가 다르게 구현할 수 있는 것을 의미
  • 인터페이스와 추상클래스의 차이
    • 추상클래스 : 객체의 추상적인 상위 개념으로 공통된 개념을 표현할 때 사용. 단일 상속만 가능. 추상클래스를 상속하는 집합간에는 연관관계가 있다. 기능을 구체적으로 정의할수 있다.
    • 인터페이스 : 구현 객체가 같은 동작을 한다는 것을 보장하기 위해 사용. 다중 상속 가능. 인터페이스를 구현하는 집합간에는 관계가 없을 수 있다. 시그니처만 정의 가능
  • 제네릭(Generics) : 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법, 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움을 줄여주며 재사용성을 높힌다. 제네릭은 참조 타입에서만 사용할 수 있으며 원시 타입에서 사용하고 싶다면 레퍼 클래스를 사용하여야 한다.
    • 와일드카드 : 와일드카드는 ? 문자를 사용하여 불특정 타입을 나타낼 때 사용되며 주로 메서드 파라미터에 적용한다.
      • 무제한 와일드카드 : 어떤 타입이라도 허용 (List<?> list)
      • 상한 경계 와일드카드 (Upper Bounded Wildcard) : 특정 타입의 하위 클래스만 허용 (List<? extends Number> list)
      • 하한 경계 와일드카드 (Lower Bounded Wildcard) : 특정 타입의 상위 클래스만 허용 (List<? super Integer> list)
  • 리플렉션(Reflection) : 런타임 시에 자바 클래스의 메타데이터(metadata)를 검사하고 조작할 수 있게 해주는 기능, 이를 통해 클래스, 인터페이스, 필드, 메서드 등의 정보를 얻고, 해당 객체의 메서드를 호출하거나 필드 값을 수정할 수 있다.
    • 클래스 로딩 및 인스턴스화 : 런타임 시에 클래스 이름을 통해 클래스를 로딩하고, 인스턴스를 생성
    • 메타데이터 접근 : 클래스의 필드, 메서드, 생성자 등의 메타데이터에 접근
    • 필드 및 메서드 조작: : 객체의 필드 값을 읽거나 수정 또는 메서드를 호출
    • 런타임 동적 바인딩 : 런타임에 동적으로 메서드나 필드를 바인딩하여 호출. (주로 플러그인 시스템, 의존성 주입, 프레임워크 개발 등에 사용)
  • Stram API : Collections Type의 데이터를 Stream 메소드로 내부 반복을 통해 정렬 혹은 필터링을 지원해주는 API, 원본데이터로부터 데이터를 읽기만 할 뿐, 원본데이터 자체를 변경하지 않는다(Immutable). parallel 메서드 제공을 통해 병렬처리가 가능하다.
    • Mutable 객체 : 생성된 이후 수정 가능, 이미 존재하는 객체에 재할당 할수 있다. 값을 변경할 수 있는 메소드 제공한다(setter).
    • Immutable 객체 : 생성된 이후 수정 불가능, 이미 존재하는 객체이더라도 새로운 객체를 생성하여 재할당, 값을 변경할 수 있는 메소드가 없다(setter 없음). Immutable 객체는 스레드 안전성을 보장하기 때문에 동시성 문제를 방지할 수 있다. 자바에서는 많은 기본 클래스들이 Immutable로 설계되어 있으며 대표적으로 String이 있다.
  • 직렬화(Serialization)과 역직렬화(Deserialization)
    • 직렬화(Serialization) : 객체들의 데이터를 연속적인 데이터(스트림)로 변형하여 전송 가능한 형태로 만드는 것 (객체 데이터를 JSON으로 바꾼다.)
    • 역직렬화(Deserialization) : 직렬화된 데이터를 다시 객체의 형태로 만드는 것 (JSON 데이터를 객체로 바꾼다)
  • JWT(Json Web Token) : JWT란 객체에 인증에 필요한 정보들을 담은 후 비밀키로 서명한 토큰, 토큰 자체에 사용자의 권한 정보나 서비스를 사용하기 위한 정보가 포함되어 있고 무상태(Stateless)인 환경에서 사용자 데이터를 주고받을 수 있다.
    • Header(헤더) : 서명 시 사용하는 키(kid), 사용할 타입(typ), 서명 암호화 알고리즘(alg)의 정보가 담겨 있다.
    • Payload(페이로드) : 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨 있다. 클레임(Claim)은 Key/Value 형태로 된 값을 갖는다.
    • Signature(서명) : Header(헤더) 에서 정의한 알고리즘 방식(alg)을 활용하여 Header(헤더)+ 페이로드(Payload)와 서버가 갖고 있는 유일한 key 값을 합친 것을 헤더에서 정의한 알고리즘으로 암호화한다.
  • JWT의 동작 방식
    • 인증(Authentication) : 사용자가 로그인을 하면 서버는 JWT를 생성하여 클라이언트에게 반환, 클라이언트는 이후 요청 시 JWT를 헤더에 포함시켜 서버에 전달한다.
    • 인가(Authorization) : JWT에는 사용자의 권한 정보나 추가적인 메타데이터가 포함될 수 있어, 서버는 JWT를 통해 사용자의 권한을 확인할 수 있습니다.
  • JWT의 장점
    • 자가 포함(Self-contained) : JWT는 필요한 모든 정보를 포함하고 있어 별도의 세션 상태를 관리할 필요가 없다.
    • 확장성 : 클레임을 통해 필요한 정보를 자유롭게 추가할 수 있다.
    • 분산 환경 용이성 : 여러 서비스 간에 JWT를 사용하여 정보를 공유하거나 인증할 수 있다.


용어정리 – SPRING

  • Spring DI/IoC
    • IoC(제어의 역전) : 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것으로 코드의 최종호출은 개발자가 제어하는 것이 아닌 프레임워크의 내부에서 결정된 대로 이루어진다.
    • DI(의존관계 주입) : Spring 프레임워크에서 지원하는 IoC의 형태로, 클래스 사이의 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결하는 것
      • 생성자 주입 : 생성자 호출시점에 딱 1번만 호출되는 것을 보장하며 불변, 필수 의존관계에 사용한다. 불변 보장, 컴파일중 오류 확인 가능, 순환 참조 에러 방지 등 이점이 있어 스프링에서 권장한다.
      • 수정자(Setter) 주입 : 선택, 변경 가능성이 있는 의존관계에 사용되며 스프링빈을 선택적으로 등록한다.
      • 필드 주입 : @Autowired 를 사용하는데 외부에서 변경이 불가능하여 테스트 하기 힘들다. DI 프레임워크 없이는 작동하기 힘들며, 주로 애플리케이션과 관계없는 테스트코드나 @Configuration 같은 스프링 설정 목적으로 사용
  • 스프링 컨테이너(Spring Container) : 스프링 컨테이너는 내부에 존재하는 빈의 생명주기를 관리(빈의 생성, 관리, 제거 등)하며, 생성된 빈을 의존성 주입(DI)을 통해 컴포넌트를 관리하고 서로 다른 빈을 연결하여 애플리케이션 빈을 연결하는 역할을 한다.
    • BeanFactory : 스프링 빈을 관리하고 조회하는 역할, Bean을 미리 생성하지 않고 호출 시점에 생성
    • ApplicationContext : BeanFactory를 상속받고 추가 기능(프로파일 처리, 리소스 읽기 등)을 포함, Application을 시작할때 미리 Bean 생성
  • Spring Bean : 스프링 컨테이너에 의해 생성되고 관리되는 자바 객체를 뜻하며, 스프링 컨테이너는 하나 이상의 빈(Bean)을 관리한다.
    • Spring Bean 생명주기 : 스프링 빈 생성 → 의존관계 주입 → 초기화 콜백 메소드 호출 → 사용 → 제거 콜백 메소드 호출 → 스프링 종료
      • Spring Bean 콜백(초기화 및 소멸) :
        • @PostConstruct : 초기화 콜백 (의존관계 주입이 끝나면 호출)
        • @PreDestory : 제거 콜백 (메모리 반납, 연결 종료와 같은 과정)
  • Spring Bean 등록 : 스프링 빈을 등록할 때는 @ComponentScan을 이용하여 @Component로 설정된 클래스를 자동으로 등록하거나 @Configuration(클래스), @Bean(메소드) 을 사용하여 빈 설정파일에 직접 빈을 등록할 수 있다.
    • Bean/Component 차이점
      • @Bean : 개발자가 작성한 method를 기반으로 메서드에서 반환하는 인스턴스 객체 생성
      • @Component : 개발자가 작성한 class를 기반으로 실행시점에 인스턴스 객체를 생성. (@Controller, @Service, @Repository 는 모두 @Component)
  • Bean Scope : 빈 스코프는 빈이 존재할 수 있는 범위를 뜻하며 싱글톤(singleton), 프로토타입(prototype), request, session, application 등이 있다.
    • singleton Scope : 스프링 빈 스코프의 기본값, 스프링 컨테이너의 시작과 종료까지 유지, 싱글톤 스코프의 빈을 조회하면, 스프링 컨테이너는 항상 같은 인스턴스를 반환한다.
    • prototype Scope : 빈의 생성과 의존관계 주입까지만 관여하고 더는 관리하지 않는 매우 짧은 범위의 스코프, 항상 새로운 인스턴스를 생성해서 반환한다

  • Servlet Filter : 서블릿 실행 전, 후에 어떤 작업을 하고자 할때 사용한다. 이 필터가 있음으로써 WAS에서 설정을 변경하지 않고도 모든 서블릿에 영향을 준다.
    • Filter 에러 처리 : Filter는 DispatcherServlet 외부에 존재하기 때문에 예외가 발생했을 때 ErrorController에서 처리
  • Spring Interceptor : Spring에서 Handler를 실행하기 전후나, ViewResolver를 통해 컨트롤러에서 리턴한 View Name으로부터 렌더링을 담당할 View 오브젝트를 준비해 돌려준 후 실제 View를 렌더링한 후에 어떠한 처리를 담당.
    • Interceptor 에러 처리 : Interceptor는 DispatcherServlet 내부에 존재하기 때문에 전역처리 방법인 @ControllerAdvice를 적용해서 처리.
  • Spring의 레이어드 아키텍처 하나의 레이어는 자신의 고유 역할을 수행하고, 인접한 다른 레이어에 무언가를 요청하거나 응답한다. 각 레이어는 다른 레이어를 신경 쓸 필요가 없기 때문에 자신의 역할에 충실할 수 있다. (특정한 레이어의 기능을 개선하거나 교체할 수 있기 때문에 재사용성과 유지 보수에 유리)
    • Persistence Layer : 데이터 관련 처리를 담당하는 부분, repository
    • Application Layer : 비즈니스 핵심 로직을 처리하는 부분, service
    • Presentation Layer : view를 담당하는 부분, controller
  • AOP(Aspect Oriented Programming) : 기능을 핵심 관심 사항(Core Concern)과 공통 관심 사항(Cross-Cutting Concern)으로 분리시키고 각각을 모듈화 하는 것을 의미, AOP는 부가 기능을 @Aspect로 정의하여, 핵심 기능에서 부가 기능을 분리함으로써 핵심 기능을 설계하고 구현할 때 객체지향적인 가치를 지킬 수 있게 도와주는 개념

  • AOP 특징
    • 스프링 컨테이너가 객체(스프링 빈)를 생성할 때 프록시 객체를 자동으로 생성하고 타겟 객체(Target) 대신 프록시 빈으로 등록
    • 생성된 프록시는 타겟 객체(Target)의 호출을 가로채고 Advice의 기능을 호출 후에 타겟 객체(Target)의 기능을 호출한다.
  • AOP 주요 요소
    • Target : 부가기능을 부여할 대상 (핵심기능을 담고 있는 모듈)
    • Aspect : 부가기능을 정의한 모듈 , Advice 와 PointCut을 갖고 있다.
    • Advice : 실질적으로 부가기능을 담은 구현체
    • PointCut : 부가기능이 적용될 대상(Method)을 선정하는 방법
    • JoinPoint : Advice가 적용될 수 있는 위치
  • @Transactinal : Spring AOP를 통해 구현되어 있다. @Transactional이 선언되면 해당 클래스에 트랜잭션이 적용된 프록시 객체 생성하고 예외가 없을 때는 Commit, 예외가 발생한 경우 Rollback 한다. (스프링 트랜잭션 추상화에서 rollback 대상은 UncheckedException)

  • @Transactinal 특징
    • @Transactional은 우선순위를 가지고 있다. 클래스 메서드에 선언된 트랜잭션의 우선순위가 가장 높고, 인터페이스에 선언된 트랜잭션의 우선순위가 가장 낮다
    • @Transactional은 Proxy Mode가 Default로 설정되어 있어, private 메서드에 적용 할 수 없다.
  • @Transactinal Propagation(트랜잭션 전파) : 이미 트랜잭션이 진행중일 때 추가 트랜잭션 진행을 어떻게 할지 결정할수 있는 옵션
    • REQUIRED : 트랜잭션이 필요함(없으면 새로 만듬)
    • SUPPORTS : 트랜잭션이 있으면 지원함(트랜잭션이 없어도 됨)
    • MANDATORY : 트랜잭션이 의무임(트랜잭션이 반드시 필요함) / 없으면 IllegalTransactionStateException 예외 발생
    • REQUIRES_NEW : 항상 새로운 트랜잭션이 필요함/ 기존 트랜잭션이 있다면 보류 시키고 새로 만듬
    • NOT_SUPPORTED : 트랜잭션이 없으면 진행하고/ 있다면 끝날때 까지 대기
    • NEVER : 트랜잭션을 사용하지 않음(기존 트랜잭션도 허용하지 않음)/ 트랜잭션이 있으면 IllegalTransactionStateException 예외 발생
    • NESTED : 중첩 트랜잭션을 생성함(부모, 자식 트랜잭션 분리) / 부모, 자식 작업이 영향을 받지 않음
  • 물리 트랜잭션과 논리 트랜잭션 : DB의 트랜젝션을 사용하는 것을 물리 트랜잭션이라고 한다. 스프링은 성능을 위해 트랜잭션 매니저를 통해 트랜잭션을 처리하는데 이를 논리 트랜잭션이라고 한다. 모든 논리 트랜잭션이 커밋되어야 물리 트랜잭션이 커밋 되고 하나의 하나의 논리 트랜잭션이라도 롤백되면 물리 트랜잭션은 롤백된다.
    • 물리 트랜잭션 : 실제 데이터베이스에 적용되는 트랜잭션으로, 커넥션을 통해 커밋/롤백하는 단위
    • 논리 트랜잭션 : 스프링이 트랜잭션 매니저를 통해 트랜잭션을 처리하는 단위
  • @Async : Spring AOP를 통해 구현되어 있다. @Async가 선언되면 스프링이 프록시 겍체를 만들어 준다. 프록시 객체 이기 떄문에 private 메소드로 생성하면 작동하지 않는다. self-invocation(자가 호출)의 경우에는 프록시 객체를 거치지 않고 직접 Method A를 호출하기 때문에 Async가 동작하지 않는다.

  • @Async의 Thread Pool
    • SimpleAsyncTaskExecutor : 작업마다 새로운 스레드를 생성하고 비동기 방식으로 동작한다. 스레드 풀 방식이 아니므로, 스레드를 재사용하지 않는다.
    • ThreadPoolTaskExecutor : 스레드 풀 기반의 TaskExecutor, 스프링 부트의 경우 기본 설정
      • ThreadPoolTaskExecutor 옵션
        • corePoolSize : 스레드 풀에 살아있는 최소 개수
        • maxPoolSize : 스레드 풀에 살아있는 최대 개수
        • keepAliveSeconds : 스레드풀 내 스레드 개수가 corePoolSize 초과인 상태에서, 대기 상태의 스레드가 종료되는 시간
      • ThreadPool 작동방식
        • 스레드풀에 작업(task)를 등록하면, 스레드풀에 corePoolSize 만큼의 스레드가 존재하는지 확인한다.
        • corePoolSize보다 적으면, 스레드풀에 새로운 스레드를 생성하고 작업을 할당한다.
        • 스레드풀의 스래드 개수가 corePoolSize보다 크면, 스레드풀의 대기 상태 스레드에게 작업을 할당한다.
        • 스레드풀에 존재하는 모든 스레드가 작업중이면 BlockingQueue에 작업을 넣어 작업을 대기시킨다
        • 작업중인 스레드가 작업을 마치면, BlockingQueue에 대기중인 작업이 있는지 확인한다.
  • @Async의 return : Future, ListenableFuture, CompletableFuture 타입을 리턴 타입으로 사용할 수 있다. 비동기 메소드의 반환 형태를 new AsyncResult() 로 묶으면 된다.
    • Future : future.get() 은 블로킹을 통해 요청 결과가 올때까지 기다리는 역할을 한다. 그래서 비동기 블로킹 방식이 되어버려 성능이 좋지 않다.
    • ListenableFuture : 콜백을 통해 논블로킹 방식으로 작업을 처리할 수 있다. addCallback() 메소드의 첫 번째 파라미터는 작업 완료 콜백 메소드, 두 번째 파라미터는 작업 실패 콜백 메소드를 정의하면 된다.
    • CompletableFuture : java 8에서 추가된 방식, 여러 연산을 결합할 수 있도록 연산이 완료되면 다음 단계의 작업을 수행하거나 값을 연산하는 비동기식 연산 단계를 제공하고 예외 등 다양한 메소드를 제공한다.
  • Spring Security 인증 과정 : 사용자가 로그인 정보와 함께 인증 요청(HttpRequest)을 하면 AuthenticationFilter가 요청을 가로채고 가로챈 정보를 통해 UsernamePasswordAuthenticationToken(인증용 객체)를 만들고 이를 이용해 AuthenticationManager의 인증 메서드를 호출한다. 이후 UserDetailsService 구현체를 통해 DB에 저장된 정보와 비교해 일치하면 UserDetails 구현 객체를 반환해 SecurityContext에 저장한다.

용어정리 – JPA

  • 영속성 컨텍스트 : 엔티티를 영구 저장하는 환경. 애플리케이션과 데이터베이스 사이에서 객체를 보관하는 가상의 데이터베이스 같은 역할을 한다. 엔티티 매니저를 통해 엔티티를 저장하거나 조회하면 엔티티 매니저는 영속성 컨텍스트에 엔티티를 보관하고 관리한다.
  • 영속성 컨텍스트의 이점
    • 1차 캐시 : 조회가 가능하며 1차 캐시에 없으면 DB에서 조회하여 1차 캐시에 올려 놓는다.
    • 동일성 보장 : 엔티티의 동일성을 보장, 동일성 비교(==)가 가능합니다.
    • 쓰기 지연 : 트랜잭션 커밋하기 전까지 SQL을 바로 보내지 않고 모아서 보낼 수 있다.
    • 변경 감지 : commit 되는 시점에 Entity와 스냅샷과 비교하여 update SQL을 생성합니다.
    • 지연 로딩 : 엔티티에서 해당 엔티티를 불러올 때 그 때 SQL을 날려 해당 데이터를 가져옵니다.
  • 프록시(JPA) : 엔티티를 조회할 때 연관관계를 맺고 있는 다른 엔티티도 같이 조회 해야 하지만 연관된 엔티티가 항상 필요하지 않은데 DB를 조회하면 불필요한 데이터 조회가 발생하게 되기 때문에, 실제 사용될 때까지 DB 조회를 지연시킬 수 있도록 실제 엔티티 대신할 가짜 객체가 필요한데 이를 프록시 객체라고 한다.

  • N + 1 문제 : 연관 관계가 설정된 엔티티를 조회할 경우에 조회된 데이터 갯수(n) 만큼 연관관계의 조회 쿼리가 추가로 발생하여 데이터를 읽어오게 되는것, 조회 시 1개의 쿼리를 생각하고 설계를 했으나 나오지 않아도 되는 조회의 쿼리가 N개가 더 발생하는 문제
    • 즉시 로딩에서 발생 : JPQL을 사용하는 경우 전체 조회를 했을 때, 영속성 컨텍스트가 아닌 데이터베이스에서 직접 데이터를 조회한 다음 즉시로딩 전략이 동작하기 때문.
    • 지연 로딩에서 발생 : 지연로딩 전략을 사용한 하위 엔티티를 로드할 때, JPA에서 프록시 엔티티를 unproxy 할 때 해당 엔티티를 조회하기 위한 추가적인 쿼리가 실행되어 발생.
  • N + 1 해결
    • 패치 조인(Fetch Join) : 미리 두 테이블을 JOIN 하여 한 번에 모든 데이터를 가져올 수 있다면 애초에 N+1 문제가 발생하지 않음. 1:N 관계가 두 개 이상인 경우 사용 불가, 카테시안 곱(Cartesian Product)이 발생 하여 중복이 생길 수 있다
    • 배치 사이즈(Batch Size) : @BatchSize 어노테이션을 사용하거나 default_batch_fetch_size 설정을 추가하여 한 번의 쿼리로 여러 개의 연관된 엔티티를 조회하는 방법, 엔티티를 지정한 개수 만큼 IN을 활용하여 호출하게 된다.

용어정리 – 운영체제

  • 프로세스와 스레드 : 프로세스는 실행중인 프로그램을 의미, 스레드는 실행 제어만 분리한 것을 의미한다. 한 프로세스 안에 여러개의 스레드가 생성될 수 있다. 프로세스는 운영체제로부터 자원을 할당받지만, 스레드는 프로세스로부터 자원을 할당받고, 프로세스의 코드/데이터/힙영역을 공유하기 때문에 좀 더 효율적으로 통신할 수 있다. 또한 컨텍스트 스위칭도 캐시 메모리를 비우지 않아도 되는 스레드쪽이 빠르다. 그리고, 스레드는 자원 공유로 인해 문제가 발생할 수 있으니 이를 염두에 둔 프로그래밍을 해야한다.

  • 세마포어와 뮤텍스 : 프로세스 간 메시지를 전송하거나, 공유메모리를 통해 공유된 자원에 여러 개의 프로세스가 동시에 접근하면 문제가 발생할 수 있다. 이를 해결하기 위해 데이터를 한 번에 하나의 프로세스만 접근할 수 있도록 제한을 두는 동기화 방식을 취해야 한다. 동기화 도구에는 대표적으로 뮤텍스(Mutex)와 세마포어(Semaphore)가 있다.
    • 뮤텍스(Mutex) : 공유된 자원의 데이터 혹은 임계영역(Critical Section) 등에 하나의 Process 혹은 Thread가 접근하는 것을 막음(동기화 대상이 하나), 임계구역(Critical Section)을 가진 스레드들의 실행시간(Running Time)이 서로 겹치지 않고 각각 단독으로 실행(상호배제_Mutual Exclusion)되도록 하는 기술
    • 세마포어(Semaphore) : 공유된 자원의 데이터 혹은 임계영역(Critical Section) 등에 여러 Process 혹은 Thread가 접근하는 것을 막아줌 (동기화 대상이 하나 이상)
  • 스레드 안전(Thread-Safety) : 여러 스레드가 동시에 접근할 수 있는 자원이나 코드 블록이 안전하게 동작할 수 있도록 하는 개념입니다. 스레드 안전성을 확보하지 않으면, 데이터의 일관성이 깨지거나 예상치 못한 결과가 발생할 수 있다.
    • Critical Section (임계 구역) : 여러 스레드가 동시에 접근하면 문제가 발생할 수 있는 코드 블록이나 자원, 이 부분에서는 스레드 간의 동기화가 필요
    • Race Condition (경쟁 상태) : 두 개 이상의 스레드가 동시에 자원에 접근하려고 할 때, 결과가 스레드의 실행 순서에 따라 달라지는 상태, 이로 인해 예기치 않은 동작이 발생할 수 있습니다.
    • Mutual Exclusion (상호 배제) : 임계 구역에 동시에 여러 스레드가 접근하지 못하도록 하는 메커니즘, 이를 위해 주로 락(Lock)을 사용
  • Thread-Safety를 위한 주요 기법
    • Locks (락) : 상호 배제를 구현하기 위한 가장 일반적인 방법. 자원에 접근할 때 락을 걸고, 작업이 끝나면 락을 해제(Mutex, Spinlock)
    • Atomic Operations (원자적 연산) : 한 번에 하나의 스레드만이 접근할 수 있는 연산을 통해 상태를 변경합니다. CPU 수준에서 지원되는 경우가 많다. (AtomicInteger in Java)
    • Thread-Local Storage : 스레드마다 별도의 저장 공간을 제공하여, 스레드 간의 자원 공유를 피함.(ThreadLocal in Java)
    • Immutable Objects (불변 객체) : 객체의 상태를 변경할 수 없도록 설계하여, 여러 스레드가 동시에 읽기만 할 수 있게 하고 상태 변경이 필요한 경우 새로운 객체를 생성한다.
    • Concurrent Collections : 동시성 문제를 해결하기 위해 설계된 컬렉션으로 내부적으로 필요한 동기화 메커니즘을 포함하고 있다. (ConcurrentHashMap in Java)
  • 교착상태(Deadlock) : 둘 이상의 프로세스들이 자원을 점유한 상태에서 서로 다른 프로세스가 점유하고 있는 자원을 요구하며 무한정 기다리는 상황
    • 교착상태(Deadlock) 조건
      • 비선점 (Nonpreemptive) : 다른 프로세스의 자원을 뺏을 수 없음.
      • 순환 대기 (Circular wait) : 두 개 이상의 프로세스가 자원 접근을 기다릴 때, 관계가 순환적 구조.
      • 점유 대기 (Hold & Wait) : 공유 자원에 대한 접근 권한을 가진 채로 다른 자원에 대한 접근 권한을 요구.
      • 상호 배제(Mutual Exclusion) : 한 번에 한 프로세스만 공유 자원에 접근 가능하며, 접근 권한이 제한적일 경우.
  • 선점 스케줄링 : 하나의 프로세스가 CPU를 차지하고 있을 때, 우선순위가 높은 다른 프로세스가 현재 프로세스를 중단시키고 CPU를 점유하는 스케줄링 방식
    • 라운드로빈(RR): 각 프로세스는 같은 크기의 CPU를 할당 받고 선입선출에 의해 실행된다. 할당시간이 너무 크면 선입선출처럼 동작하고 너무 짧으면 오버헤드가 발생
    • SRT : 짧은 시간동안 순서대로 프로세스를 수행한다. 남은 처리시간이 더 짧은 프로세스가 들어오면 해당 프로세스가 바로 선점된다.
    • 다단계 큐: Ready큐를 여러 개 사용하는 기법, 각 큐는 자신의 스케줄링 알고리즘을 수행하며 큐와 큐 사이에도 우선순위가 있다.
  • 비선점 스케줄링 : 프로세스가 CPU를 할당 받으면 해당 프로세스가 완료될 때까지 CPU를 사용한다. 프로세스 응답 시간 예측이 용이하며, 일괄 처리 방식에 적합
    • 우선순위 : 각 프로세스 별로 우선순위가 주어지고, 우선순위에 따라 CPU를 할당
    • FIFO : 프로세스들은 Ready 큐에 도착한 순서데로 CPU를 할당 받는다. 작업완료 예측이 용이.
    • SJF : 큐 안에 있는 프로세스 중 수행시간이 짧은 것을 먼저수행, 평균 대기시간을 감소
    • HRN : 긴 작업 시간과 짧은 작업시간의 불평등을 어느정도 보장, 수행시간의 길이와 대기시간을 모두 고려하여 우선순위를 정함

용어정리 – 기타

  • SOLID(객체지향 5대원칙)
    • SRP(단일책임원칙) 모든 클래스는 하나의 책임을 갖는다. 클래스는 그 책임을 완전히 캡슐화해야 한다.
    • OCP(개방-폐쇄 원칙) 확장에는 열려 있어야 하고, 수정에 대해서는 닫혀 있어야 한다.
    • LSP(리스코프 치환 원칙) 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다.
    • ISP(인터페이스 분리 원칙) 큰 덩어리의 인터페이스를 구체적으로 작은 단위로 분리시켜, 꼭 필요한 메소드만 사용하게 한다.
    • DIP(의존관계 역전 원칙) 상위 모듈은 하위 모듈에 의존하지 않고, 상위 모듈과 하위 모듈 모두 추상화에 의존해야 한다.

  • 디자인 패턴
    • 생성 패턴(Creational Pattern)
      • Singleton(싱글톤 패턴) : 하나의 클래스 인스턴스를 전역에서 접근 가능하게 하면서 해당 인스턴스가 한 번만 생성되도록 보장하는 패턴
      • Factory Method(팩토리 메서드 패턴) : 객체를 생성하기 위한 인터페이스를 정의하고, 서브클래스에서 어떤 클래스의 인스턴스를 생성할지 결정하는 패턴
      • Abstract Factory(추상 팩토리 패턴) : 관련된 객체들의 집합을 생성하는 인터페이스를 제공하며, 구체적인 팩토리 클래스를 통해 객체 생성을 추상화하는 패턴
      • Builder(빌더 패턴) : 복잡한 객체의 생성 과정을 단순화하고, 객체를 단계적으로 생성하며 구성하는 패턴
      • Prototype(프로토타입 패턴) : 체를 복제하여 새로운 객체를 생성하는 패턴으로, 기존 객체를 템플릿으로 사용하는 패턴
    • 구조 패턴(Structural Pattern)
      • Adapter(어댑터 패턴) : 인터페이스 호환성을 제공하지 않는 클래스를 사용하기 위해 래퍼(Wrapper)를 제공하는 패턴
      • Bridge(브릿지 패턴) : 추상화와 구현을 분리하여 두 가지를 독립적으로 확장할 수 있는 패턴
      • Composite(컴포지트 패턴) : 개별 객체와 복합 객체를 동일하게 다루어, 트리 구조의 객체를 구성하는 패턴
      • Decorator(데코레이터 패턴) : 객체에 동적으로 새로운 기능을 추가하여 객체를 확장할 수 있는 패턴
      • Facade(퍼사드 패턴) : 서브시스템을 더 쉽게 사용할 수 있도록 단순한 인터페이스를 제공하는 패턴
      • Flyweight(플라이웨이트 패턴) : 공유 가능한 객체를 통해 메모리 사용을 최적화하는 패턴
      • Proxy(프록시 패턴) : 다른 객체에 대한 대리자(Proxy)를 제공하여 접근 제어, 지연 로딩 등을 구현하는 패턴
    • 행위 패턴(Behavioral Pattern)
      • Observer(옵저버 패턴) : 객체 간의 일대다 종속 관계를 정의하여 한 객체의 상태 변경이 다른 객체들에게 알려지도록 한다.
      • Strategy(전략 패턴) : 알고리즘을 정의하고, 실행 중에 선택할 수 있게 한다.
      • Command(커맨드 패턴) : 요청을 객체로 캡슐화하여 요청을 매개변수화 하고, 요청을 큐에 저장하거나 로깅하고 실행을 지연시킨다.
      • State(상태 패턴) : 객체의 상태를 캡슐화하고, 상태 전환을 관리한다.
      • Chain of Responsibility(책임 연쇄 패턴) : 요청을 보내는 객체와 이를 처리하는 객체를 분리하여, 다양한 처리자 중 하나가 요청을 처리한다.
      • Visitor(방문자 패턴) : 객체 구조를 순회하면서 다양한 연산을 수행할 수 있게 한다.
      • Interpreter(인터프리터 패턴) : 언어나 문법에 대한 해석기를 제공하여, 주어진 언어로 표현된 문제를 해결하는 패턴
      • Memento(메멘토 패턴) : 객체의 내부 상태를 저장하고 복원할 수 있는 기능을 제공하는 패턴
      • Mediator(중재자 패턴) : 객체 간의 상호 작용을 캡슐화하여, 객체 간의 직접적인 통신을 방지하는 패턴
      • Template Method(템플릿 메서드 패턴) : 알고리즘의 구조를 정의하면서 하위 클래스에서 각 단계의 구현을 제공하는 디자인 패턴
      • Iterator(이터레이터 패턴) : 컬렉션 내의 요소들에 접근하는 방법을 표준화하여 컬렉션의 내부 구조에 독립적으로 접근할 수 있는 패턴
  • REST(Representational State Transfer Application Programming Interface) API 네트워크 기반 애플리케이션의 통신을 위해 설계된 아키텍처 스타일, REST는 웹의 기존 기술과 프로토콜을 활용하여 클라이언트와 서버 간의 상호 작용을 간편하고 효율적으로 만든다. RESTful API는 주로 HTTP 프로토콜을 사용하며, 자원을 URI로 식별하고, 자원에 대한 상태 변화를 HTTP 메서드로 처리한다. HTTP 프로토콜을 기반으로 하므로, 기존 웹 기술과 쉽게 통합 할수 있고 클라이언트/ 서버를 분리 개발하여 확장성이 좋지만 HTTP 헤더와 같은 추가 메타데이터가 포함되어야 하므로, 네트워크 오버헤드가 발생할수 있고 REST는 아키텍처 스타일이지 표준이 아니므로, 구현 방식에 따라 다를 수 있다.

  • REST API의 주요 개념
    • 자원(Resource) : 모든 자원은 고유한 URI(Uniform Resource Identifier)로 식별됨,
    • HTTP 메서드 : REST API는 HTTP 메서드를 사용하여 자원에 대한 작업을 수행한다.
      • GET : 서버에서 자원을 조회 (GET /users/1)
      • POST : 서버에 새로운 자원을 생성 (POST /users)
      • PUT : 서버에서 자원의 전체를 업데이트하거나 새로운 자원을 생성 (PUT /users/1)
      • DELETE : 서버에서 자원을 삭제 DELETE (/users/1)
      • PATCH : 자원의 부분 업데이트를 수행 (PATCH /users/1)
    • 표현(Representation) : 클라이언트와 서버는 자원의 표현을 주고받습니다. 표현은 일반적으로 JSON, XML, HTML 등의 형태로 전송된다.
    • 상태 전이(State Transfer) 클라이언트가 서버의 자원 상태를 변경하는 행위, 클라이언트와 서버는 상태를 주고받으며, 클라이언트는 서버의 자원을 조작하거나 조회하여 상태를 전이한다.
    • HATEOAS(Hypermedia As The Engine Of Application State) : REST 아키텍처 스타일의 원칙 중 하나로, 클라이언트가 서버에서 받은 응답에 포함된 링크를 통해 다른 자원에 접근할 수 있게 한다.