Skip to main content

GDSC mount - BackEnd 탐구 (1)

·15 mins· loading · loading ·
CS GDSC
Soeun Uhm
Author
Soeun Uhm
problem-solving engineer, talented in grit.
Table of Contents

GDSC Yonsei
#

9월부터 GDSC 에서 본격적으로 활동하기에 앞서 백엔드 부분을 더 깊이 탐구하고자 Mount 과정을 진행하고 있다. 아래는 주어진 여러 질문들이고 공부하며 답변을 작성하였다.

BE 이론
#

VM과 컨테이너의 차이가 무엇인가요? (Docker, Python VirtualEnv 는 어디에 속하나요?)
#

  • VM과 컨테이너가 필요한 이유

    • 하나의 어플리케이션을 실행시키고자 할 때, 이것은 OS와 라이브러리에 의존한다. 그러므로 하나의 컴퓨터에서 성격이 다른 (OS, 라이브러리 버전이 다른) 소프트웨어를 실행하기 어렵다.

    • 컨테이너 및 가상 머신은 어플리케이션을 IT 인프라 리소스(각 로컬 컴퓨터마다 설치되어 있는 OS, 라이브러리 버전 등)로부터 독립적으로 만드는 기술이다. 컨테이너와 가상 머신을 사용하면 여러 환경에서 독립적으로 실행할 수 있도록 어플리케이션을 완전히 격리할 수 있다.

      image

  • VM : Virtual Machine (가상머신)

    • 가상머신은 호스트 운영체제 위에 가상의 하드웨어를 서비스하는 하이퍼바이저 같은 가상머신을 관리하는 소프트웨어가 돌아가고, 해당 소프트웨어가 제공하는 가상의 하드웨어에 게스트 운영체제를 설치해서 사용한다.
    • VM방식은 어플리케이션이 돌아갈 수 있는 OS 환경이 포함된다. 그렇기 때문에 어플리케이션을 실행하기 위해서는 VM을 띄워 자원을 할당한 다음, OS를 부팅한 후 어플리케이션을 구동할 수 있기 때문에 시간이 오래 걸린다.
    • 가상머신의 단점
      1. 완전한 OS가 설치되기 때문에 대량의 메모리가 필요하다.
        • 독립적인 환경을 만들 때마다 불필요한 OS를 만드는 작업을 계속해야 해서, 확장성이 떨어진다. 또한 메모리나 자원을 유동적으로 관리하는 것이 아니라 처음부터 정해놓고 실행하기 때문에 비효율적이다.
      2. CPU 성능 확보에 대한 문제가 있다.
        • 서로 다른 어플리케이션이 CPU 자원에 대한 요청을 할 때, CPU 자원에 대한 경쟁이 발생한다. 하나의 VM내에서 어떤 어플리케이션의 우선순위가 높다고 해도, 이 VM의 OS가 전체 VM OS 상에서 우선순위가 낮다면, 이 어플리케이션은 물리적인 CPU를 많이 할당받지 못할 수 도 있다. VM에서는 이러한 문제를 해결하기 위해 CPU같은 물리적인 자원을 특정 게스트 OS에 전담배치하는 Dedicate 서비스를 제공한다.
      3. 시스템 운영에 대한 통합적인 지식이 필요하다.
        • VM에서는 새로운 시스템을 구축하는 개념이기 때문에 시스템 운영에 대한 지식도 필요하다.
  • 컨테이너

    • 각 어플리케이션이 모두 하나의 OS 커널*을 공유하여 사용한다. 각 컨테이너마다 OS가 필요없으므로 더 가볍고, 크기고 작아 복제와 배포에 간편하다.
      • 여기서 커널이란, 운영 체제의 핵심으로 하드웨어의 자원(CPU, Memory, Devices)을 각 프로세스에 사용할 수 있도록 나눠주고, 프로세스 및 메모리 제어 등 시스템의 모든 것을 통제하는 것이다.
    • 불필요한 OS 만드는 작업 및 Infra 를 독립적으로 나눌 필요가 없어서 확장성이 좋고 빠르다.
    • 흔히 도커 컨테이너라고 말하는데, 여기서 도커는 컨테이너 서비스를 지원하기 위한 플랫폼이다. 도커를 사용하면 인프라에서 어플리케이션을 분리하여 컨테이너로 추상화*시켜 소프트웨어를 빠르게 제공할 수 있다.
    • 추상화란, 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려 내는 것이다. 즉 추상화는 복잡한 것을 우리가 이해하기 쉽고, 연상하기 쉽고, 공유하기 쉽도록 하는 것이다. 컨테이너는 표준화된 소프트웨어 유닛을 추상화한다. 그 추상화에 들어가는 요소들은 코드, 런타임, 셋팅, 라이브러리이다.
  • Python VirtualEnv vs. Docker

    • 도커는 컨테이너를 이용하여 어플리케이션을 쉽게 생성(create), 전개(deploy), 실행(run)할 수 있도록 설계된 툴이다. 쉽게 말해서 다른 운영체제를 가신 컴퓨터에서도 동일한 실행환경을 만들어주는 툴이다.
    • 파이썬 가상환경은 python 프로젝트의 종속성 구조만 보는 반면, 도커 컨테이너는 운영체제의 이미지 전체가 포함되어 있다.
    • 가상 환경은 오로지 python의 의존성을 캡슐화 하지만 도커는 컨테이너는 OS 전체를 캡슐화한다.
    • 이 때문에 virtualenv를 통해서는 파이썬 버전은 쉽게 바꿀 수 있었지만 결국 호스트 OS 내부에 갇혀있어야 했다. 하지만 도커 이미지를 사용하면 OS를 교체해버릴 수 있다. Ubuntu, Debian, Alpine, Windows Server Core에도 설치하고 실행할 수 있다.
    • 도커에서는 image 라는 개념을 통해 내 로컬 컴퓨터에 직접 설치하는 대신 이미지를 가져와서 실행할 수 있다. 내가 nodejs 를 기반으로 프로젝트를 만들고 싶으면 도커 컨테이너를 만들어서 dockerhub 에서 Nodejs 이미지를 pull 하면 된다.
    • 그냥 내 로컬 컴퓨터에서 프로젝트를 실행한다고 해보자. A 프로젝트는 pythorch, transformers, pandas 등을 사용하고, B 프로젝트는 tensorflow, fastapi 등을 이용한다고 하자. 이따는 그냥 venv 2가지를 만들어서 파이썬 버전과 맞는 라이브러리들을 관리하면 된다.
    • 하지만 나는 맥 환경에서 프로젝트를 빌드 했는데, 이것을 내 친구의 윈도우 컴퓨터에서 문제없이 실행하고 싶다면 ? 내 로컬 컴퓨터에서 도커 이미지로 만든 다음, 이 이미지를 도커 컨테이너로 실행하면 OS 에 상관없이 실행할 수 있다.

토큰 기반 인증과 세션 기반 인증을 비교해주세요. 본인이라면 어떤 방식을 사용할 것 같나요?
#

  • 인증(Authorization)과 인가(Authorization)은 무엇인가?

    • 인증을 쉽게 말하자면 로그인이다. 클라이언트가 자기자신이라고 주장하고 있는 사용자가 맞는지를 검증하는 과정이다. 로그인 화면에서 유저가 아이디와 비밀번호를 입력하면, 서버에서는 내가 진짜로 유저가 맞는지 확인한다.
    • 인가는 인증 작업 이후에 행해지는 작업으로, 인증된 사용자에 대한 자원에 대한 접근 확인 절차를 의미한다. 각 유저마다 접근 권한이 다를 수 있다. 관리자는 모든 게시판에 접근가능하지만, 일반 유저는 자신이 쓴 게시판에만 접근 가능하다고 하자. 이때 관리자와 일반 유저에게 각각 인증된 자원에 접근 절차를 확인하는 것이 인가이다.
      image
  • 세션 기반 인증

    • HTTP는 Stateless 하다. 즉, 서버에서는 사용자가 날린 request 에 대한 정보를 기억하고 있지 않는다. 따라서 사용자 인증을 할 때, 서버 측에서 사용자들의 정보를 기억하고 있어야 한다. 사용자들이 로그인을 하면, 서버는 **세션***을 출력한다.

      • 세션(Session) : 컴퓨터 공학에서 ‘정보 간의 정보 교환’을 의미하며, 서버에 ‘로그인이 되어있음’이 지속 되는 상태도 ‘세션’이라고 한다.
    • 세션 기반 인증을 하기 위해서는 Session 과 Cookie 가 사용되며, 아래와 같이 진행된다.

      image

    • 절차

      1. 유저가 서버에 로그인 정보를 보낸다.
      2. 서버의 세션 저장소에 사용자 인증 정보를 저장한다.
      3. 유저에게는 Session ID 를 발급한다. 이때 발급된 Session ID는 유저 브라우저 상에 Cookie 형태로 저장된다.
      4. 유저는 이후 서버에 request 를 보낼 때마다 HTTP Cookie header 에 Session ID 를 함께 서버로 전송한다.
      5. 서버는 Session ID를 저장된 사용자 인증 정보와 비교한다.
      6. Session ID 와 사용자 세션 정보가 일치하면 success response 를 보낸다.
  • 토큰 기반 인증

    • 토큰 기반 인증은 인증 정보를 클라이언트가 직접 들고 있는 방식이다. 클라이언트의 정보는 JWT(JSON Web Token)으로 변환되어 저장된다. 쉽게 말하자면 클라이언트 정보를 암호화 하는 기술을 서버 쪽에서 가지고 있고, 사용자가 자기 정보를 보내면 그 기술로 암호화해서 클라이언트에게 다시 전송해준다. 그 암호를 풀 수 있는 기술도 서버만 가지고 있다.

    스크린샷 2023-09-03 오후 4 19 08

    • 절차
      1. 클라이언트가 인증 정보를 서버에게 보낸다.
      2. 클라이언트의 인증 정보를 사용해서 JWT 를 만든다.
      3. 만든 JWT 를 다시 클라이언트에게 보낸다.
      4. 클라이언트는 JWT 를 로컬 저장소에 저장한다.
      5. 클라이언트가 request를 보낼때 가지고 있는 JWT를 HTTP 의 Authorization 헤더에 실어서 보낸다.
      6. 서버는 JWT가 진짜인지 확인하고, 맞으면 success response 를 보낸다.
  • 세션 기반 인증 vs 토큰 기반 인증

    • 사이즈
      • 세션 기반 인증은 Cookie 헤더에 Session ID만 보내므로 트래픽을 적게 사용한다. 하지만 토큰 기반 인증을 할 때 JWT는 사이즈가 상대적으로 더 크다. 따라서 더 많은 트래픽을 사용한다.
    • 안정성과 보안문제
      • 세션은 모든 인증 정보가 서버의 세션 저장소에 저장된다. 따라서 클라이언트의 컴퓨터가 해킹 당해도 로그인 정보는 안전한다.
      • 토큰 기반 인증은 클라이언트가 JWT를 가지고 있기 때문에, 클라이언트의 컴퓨터가 해킹당해서 JWT를 뺴앗기게 되면 속수무책이다.
    • 확장성
      • 여기까지만 보면 세션 인증 기반을 사용하는 것이 장점이 더 많아 보인다. 하지만 현재 거의 모든 웹 어플리케이션이 토큰 기반 인증을 사용하고 있다고 한다. 그것의 이유가 뛰어난 확장성이다.
      • 세션 기반 인증은 서버가 사용자 데이터를 저장하고 있으므로, 유저는 자기 정보가 저장된 딱 그 서버 한대와만 소통해야 한다. 하지만 수평 확장을 적용하는 웹 어플리케이션 특성상, 이것은 매우 불리하다.
      • 토큰 기반 인증은 클라이언트에게 정보가 있으므로 어느 서버와 소통해도 인증이 가능하다. 따라서 토큰 기반 인증은 HTTP 의 stateless 한 특성을 그대로 사용할 수 있고, 높은 확장성을 가진다.
  • 나라면 어떤 인증 방식을 사용할 것인가?

    • 위 두가지의 특성을 보아, 나는 은행 로그인 정보와 같이 보안이 정말 중요한 데이터를 다룬다면 세션 기반 인증을 사용할 것 같다. 아무래도 JWT는 브라우저에 그대로 노출되어 있으므로 노출의 위험이 크다. 만약 JWT 토큰을 쓴다면 보안을 2중화 (핸드폰 인증을 거친다던지..) 해서 사용하면 좋을 듯 하다.

동기와 비동기, 블로킹과 논블로킹의 차이에 대해 설명해주세요. 또한, 각각을 사용한 예시 또한 설명해주세요.
#

  • 블로킹 vs 논블로킹

    • 알아야 할 키워드
      • 제어권 : 함수 내용을 실행시킬 수 있는 권리
      • 결과값 : 함수의 리턴값
    • 블로킹(Blocking)
      • 함수를 호출할 때 제어권도 함께 넘겨주고 작업이 끝난 후 돌려받는 것이다. 즉, 호출된 함수의 작업이 종료될 때까지 호출하는 함수는 다른 작업을 진행할 수 없다.
      • 호출된 함수는 모든 실행을 마치고 결과값을 리턴해준다.
    • 논블로킹(Non-Blocking)
      • 논블로킹도 마찬가지로 함수를 호출할 때 제어권을 넘겨주긴 하지만, 곧바로 돌려받는다. 즉 함수A의 작업이 끝나지 않아도 부모함수(호출한 함수)는 제어권을 넘겨받고 다음 함수B를 실행할 수 있다.
    • 블로킹 vs 논블로킹
      • 이 둘을 구분짓는 기준은 ‘호출된 함수가 제어권을 호출한 함수에게 언제 돌려주는지’ 이다.
  • 동기 vs 비동기

    • 동기(syschronous) 방식

      • ‘시간을 맞추는’ 방식이다.
      • 함수가 두개 이상 존재할 때, 동기방식은 함수들의 작업을 동시에 시작하거나, 끝나는 타이밍을 맞추거나, 하나가 끝나고 다른 하나를 차례로 실행하는 방식이다.
      • 동기는 제어권과 결과값을 동시에 반환한다. 부모함수가 자식함수A를 호출할 때, 제어권을 넘겨준다. 자식함수A의 실행이 끝나고 결과값을 리턴할 때, 제어권도 같이 반환한다. 그러면 부모함수는 다른 자식함수B를 실행할 수 있다.
    • 비동기(Asynchoronous) 방식

      • 비동기는 동기가 아닌 방식이다. 즉 두 함수가 서로 언제 시작하고, 언제 끝나는지 전혀 신경쓰지 않는다.
      • 부모함수는 여러 자식함수A,B,C 를 호출하면, 함수A,B,C가 각각 알아서 완료되었는지 여부를 알려준다.
      • 비동기는 제어권과 결과값을 다른 시점에 따로따로 반환한다.
    • 동기 vs 비동기

      • 둘을 구분짓는 기준은 여러개의 함수들이 ‘시간을 맞춰서 실행하느냐’ 이다.
      • 동기방식은 설계가 직관적이고 간단하지만, 하나의 요청이 처리될 때까지 아무것도 못하고 기다려야 한다는 단점이 있다.
      • 비동기 방식은 동기보다는 복잡하고 속도가 느리지만, 하나의 요청이 처리되는 동안 다른 작업도 할 수 있으므로 자원을 효율적으로 사용할 수 있다는 장점이 있다.
  • 예시

    image

    • Javascript 에서 비동기 처리 방식
      • Javascript 는 싱글 스레드 기반으로 프로레스를 처리한다. 즉, 동기 방식이다.
      • 하지만 실제 코드에서 비동기가 필요한 상황들이 있다. 만약 무거운 작업이 있다면 이것을 비동기적으로 요청해두고 바로 다음 작업을 수행하면 훨씬 더 효율적인다.
      • 자바스크립트는 이벤트 루프 덕분에 비동기 작업을 수행할 수 있다. 코드를 실행하며 비동기 작업은 “실행해!” 라는 명령을 담아 어딘가로 요청한다. 여기서 어딘가가 이벤트 루프이다. 덕분에 자바스크립트 엔진은 무거운 작업을 어딘가에 요청해두고, 동기적으로 바로 다음 코드를 실행할 수 있다. 이때 이벤트 루프에서 그 무거운 작업이 완료되면, 콜백 함수를 통해 후속 작업을 진행한다. 비동기 처리가 끝난 후 코드를 순차적으로 실행하기 위해 promise 함수를 사용하기도 한다.

ORM이 무엇인가요? 단점은 없을까요?
#

  • ORM(Object Relational Mapping)이란?

    • ORM 은 객체와 데이터베이스의 관계를 매핑해주는 도구이다. 즉, 프로그래밍 언어의 객체와 관계형 데이터베이스의 데이터를 자동으로 매핑(연결)해주는 도구이다.
    • python에서 class 객체를 만들면, 이것이 Database의 table에 자동으로 매핑되는 것이다.
  • ORM을 사용하는 이유

    • 직관적인 코드 + 가독성
      • ORM을 사용하면, SQL Query 를 사용하지 않고 직관적인 코드(메소드)를 사용하여 데이터를 조작할 수 있다.
      • 개발자가 기존에 개발하던 언어 그대로 객체 모델만 프로그래밍하면 된다.
      • SQL의 절차적이고 순차적인 접근이 아닌 객체 지향적인 접근으로 생산성이 증가한다.
    • 재사용 및 유지보수 편리성 증가
      • ORM은 독립적으로 작성되고, 만든 객체들을 재사용할 수 있기 때문에 편리하다
    • DBMS에 대한 종속성이 줄어듦
      • 객체 간의 관계를 바탕으로 SQL을 자동으로 생성하기 때문에 RDBMS의 데이터 구조와 프로그래밍 언어의 객체지향 모델 사이의 간격을 좁힐 수 있다.
      • 프로그래머는 객체에 집중해서, DBMS를 교체하거나 보수할때도 적은 리스크와 시간이 소요된다.
  • ORM의 단점

    • ORM만을 사용해서 모든 것을 해결할 수 없다.
      • ORM은 매우 편리하지만, 데이터베이스를 설계할 때는 매우 신중하게 설계해야 한다. 또한 속도를 위해서 결국에는 SQL문을 사용해야 되는 경우가 생긴다.
    • 패러다임 불일치
      불일치설명
      세분성(Granularity)경우에 따라서 데이터베이스에 있는 테이블 수보다 더 많은 클래스를 가진 모델이 생길 수 있다.
      상속성(Inheritance)RDBMS는 객체지향 프로그래밍 언어의 특징인 상속 개념이 없다.
      일치(Identity)RDBMS는 기본키(primary key)를 이용하여 동일성을 정의한다.
      그러나 자바는 객체 식별(a==b) 과 객체 동일성(a.equals(b)) 을 모두 정의한다.
      연관성(Associations)객체지향 언어는 방향성이 있는 객체의 참조(reference)를 사용하여 연관성을 나타내지만 RDBMS는 방향성이 없는 외래키(foreign key)를 이용해서 나타낸다.
      그래서 객체 모델에서 양방향을 참조하려면 양쪽에 연관을 두 번 정의해야 한다.
      탐색(Navigation)자바와 RDBMS에서 객체를 접근하는 방법이 근본적으로 다르다.
      자바는 그래프형태로 하나의 연결에서 다른 연결로 이동하며 탐색하지만 RDBMS는 일반적으로 SQL문을 최소화하고 JOIN 을 통해 여러 엔티티를 로드하고 원하는 대상 엔티티를 선택하는 방식으로 탐색한다.

RDB와 NoSQL의 차이가 무엇인가요? 왜 각자 그런 형태를 선택했을까요?
#

  • Database와 DBMS 그리고 SQL

    • 데이터베이스는 여러 사람이 공유하여 사용할 목적으로 체계화해 통합, 관리하는 데이터의 집합이다. 논리적으로 연관된 하나 이상의 자료의 모음으로 이 관계를 구조화해서 검색과 업데이트가 용이하도록 한다.
    • DBMS(Database Management System)은 데이터베이스를 관리하고 운영하는 소프트웨어이다. 즉 DBMS를 사용해서 DB를 생성하고 수정하고 관리한다. MySQL, PostgreSQL, SQL Server 등 많은 종류의 DBMS가 있다. DBMS의 유형은 계층형(Hierarchical), 망형(Network), 관계형(Relational), 객체지향형(Object-Oriented), 객체관계형(Object-Relational) 등으로 분류된다. 이 중 가장 많이 쓰이는 유형이 관계형 DBMS(RDB) 이다.
    • SQL(Structured Query Language)은 관계형 데이터베이스에서 사용되는 언어이다.
  • RDB(Relational Database)

    • RDB는 테이블(table) 이라는 최소 단위로 구성되며, 이 테이블은 하나 이상의 열(column)과 행(row)으로 이루어져 있다.
    • RDB에는 테이블을 조인하여 정보 간 관계 또는 링크를 설정할 수 있는 기능이 있어, 여러 데이터 포인트 간의 관계를 쉽게 이해하고 정보를 얻을 수 있다. 두 테이블 간의 관계는 외래 키(foreign key)를 사용해서 나타낸다. 테이블간의 관계에서 외래 키를 이용한 테이블 간 Join이 가능하다.
    • RDB에서 정보를 가져올때 SQL 쿼리 언어를 사용한다.
    • RDB의 주요 이점은 직관적인 데이터 표현 방법을 제공하고 관련 데이터 포인트에 쉽게 액세스할 수 있다는 점이다.
    • RDB는 매우 정교한 초기 설계로 만들어진다. 테이블 사이에 의존성이 있고, 쳇바퀴처럼 맞물려서 돌기 때문에 데이터 타입을 바꾼다던지 새로운 열을 추가한다던지 하는 작업은 실제 프로덕션 환경에서 사실상 불가능하다.
    • RDB는 수평적인 확장이 어려운데, 이것은 각 테이블이 여러 테이블에 의존해있기 때문이다. 따라서 만약 확장을 할 경우에는 수직적인 확장을 주로 한다.
    • 수직적인 확장은 서버의 용량을 늘리는 개념이다.
  • NoSQL

    • Not only SQL의 약자로, RDB 형태의 관계형 데이터베이스가 아닌 다른 형태의 데이터(Document, Graph, Key-Value, Wide-column)로 저장한다. 데이터를 읽어올 때 SQL언어를 사용하지 않는다.
      img
    • NoSQL에서는 RDBMS와는 달리 테이블 간 관계를 정의하지 않는다. 데이터 테이블은 그냥 하나의 테이블이며 테이블 간의 관계를 정의하지 않아 일반적으로 테이블 간 Join도 불가능하다. 데이터 일관성은 포기하되 비용을 고려하여 여러 대의 데이터에 분산하여 저장하는 수평적 확장(Scale-Out)을 목표로 등장했다.
    • 수평적인 확장은 서버의 개수를 늘릴 수 있는 것이다.
  • RDB vs NoSQL

    RDBNoSQL
    데이터 저장 모델tableJson document/key-value/graph
    개발 목적데이터 중복 감소애자일/확장가능성/수정가능성
    예시Oracle, MySQL, PostgreSQLMongoDB, DynamoDB
    Schema엄격한 데이터 구조유연한 데이터 구조
    장점- 명확한 데이터 구조 보장
    - 데이터 중복없이 한 번만 저장(무결성)
    - 중복 데이터가 없기 때문에 업데이트 용이
    - 유연하고 자유로운 데이터 구조
    - 새로운 필드 추가 자유로움
    - 수평적 확장(scale-out)용이
    단점- 시스템이 커지면 join문이 많은 복잡한 쿼리
    - 수평적 확장이 까다로워 비용이 많이 드는 수직적 확장(scale-up)이 사용됨
    - 데이터 중복 발생 가능
    -중복 데이터가 많기 때문에 데이터 변경 시 모든 컬렉션에서 수정 필요
    - 명확한 데이터 구조 보장X
    사용- 데이터 구조가 변경될 여지 없이 명확한 경우
    - 데이터 업데이트가 잦은 시스템
    - 정확한 데이터 구조가 정해지지 않은 경우
    - 업데이트가 자주 이뤄지지 않는 경우
    - 데이터 양이 매우 많은 경우

DB의 인덱스의 개념에 대해 설명해주세요.
#

  • 인덱스?

    • 인덱스는 데이터베이스 테이블에 대한 검색 성능의 속도를 높여주는 자료구조이다. 테이블의 특정 컬럼에 인덱스를 생성하면, 해당 컬럼의 데이터들을 정렬하여 별도의 메모리 공간에 데이터의 물리적 주소와 함께 저장된다.
    • 마치 책에서 목차와 비슷한 개념이다. 책에서 원하는 내용을 찾을 때 목차나 색인을 이용하면 훨씬 빠르게 찾을 수 있듯이 테이블에서 원하는 데이터를 찾기 위해 인덱스를 이용하면 빠르게 찾을 수 있다.
    • 인덱스 생성 시 데이터를 오름차순으로 정렬하기 때문에 정렬된 주소체계라고 표현할 수 있다.
  • 인덱스를 사용하는 이유

    • 조건 검색 Where 절의 효율성
      • 레코드의 처음부터 끝까지 다 읽어서 검색 조건과 맞는지 비교해보는 것이 풀 테이블 스캔(Full Table Scan)이다. 반면 인덱스 테이블은 정렬되어 저장되어 있기 때문에 해당 조건에 맞는 데이터를 더 빠르게 찾아낼 수 있다.
    • 정렬 Order by 절의 효율성
      • 인덱스를 사용하면 Order by에 의한 sort 과정을 피할 수 있다. 인덱스를 사용하면 이미 정렬되어 있기 때문에 자원을 많이 소모하는 재정렬 작업을 피할 수 있다.
    • MIN, MAX 의 효율적인 처리
      • MIN , MAX 값을 가져올때 레코드의 시작값과 끝값 한건씩만 가져오면 되므로 풀 테이블 스캔보다 훨씬 빠르다.
  • 인덱스의 단점

    • 정렬된 상태를 계속 유지 시켜줘야 한다. INSERT, UPDATE, DELETE를 통해 데이터가 추가되거나 값이 바뀐다면 INDEX 테이블 내에 있는 값들을 다시 정렬을 해야한다. 그리고 INDEX 테이블, 원본 테이블 이렇게 두 군데에 데이터 수정 작업해줘야 해서 비효율적이다.
    • 인덱스는 테이블의 전체 데이터 중에서 10~15% 이하의 데이터를 처리하는 경우에만 효율적이고 그 이상의 데이터를 처리할 땐 인덱스를 사용하지 않는 것이 더 낫다. 그리고 인덱스를 관리하기 위해서는 데이터베이스의 약 10%에 해당하는 저장공간이 추가로 필요하다. 따라서 인덱스를 남발하면 안된다.
  • 인덱스 생성 전략

    • 조건절에 자주 등장하는 컬럼
    • 항상 = 으로 비교되는 컬럼
    • 중복되는 데이터가 최소한인 컬럼 (분포도가 좋은) 컬럼
    • ORDER BY 절에서 자주 사용되는 컬럼
    • 조인 조건으로 자주 사용되는 컬럼
  • 인덱스 자료구조

    • Hash Table
    • B+ Tree

DB의 트랜잭션과, ACID 원칙에 대해 설명하고, Lock에 대해 설명해주세요.
#

  • DB의 트랜잭션

    • 트랜잭션(Transaction)이란, 데이터베이스의 상태를 변화시키기 해서 수행하는 작업의 단위을 뜻한다.
    • 데이터베이스의 상태를 변화시키는 것은 SQL 쿼리어(SELECT, INSERT, DELETE, UPDATE)를 사용하여 데이터베이스에 접근하는 것이다.
    • 작업 단위는 SQL질의 한 문장이 아니라 사람이 정하는 기준에 따라 한꺼번에 모두 수행되어야 할 일련의 연산들이다.
    • 사용자가 게시판에 글을 올리고, 다시 게시판에 돌아왔을 때 자신의 글이 포함된 게시판을 보게 된다. 이때 DB에서는 사용자가 글을 올릴 때 INSERT 를 사용해서 사용자가 입력한 글을 게시글의 데이터로 옮긴다. 그 후 사용자가 다시 게시판으로 돌아올 때 SELECT 문을 사용하여 최신 정보로 유지한다. 여기서 작업 단위는 INSERT 문과 SELECT 문 모두 합친 것이다.
    • 하나의 트랜잭션은 Commit(저장) 되거나 Rollback(철회) 할 수 있다. Commit 은 하나의 트랜잭션이 성공적으로 끝났고, 데이터베이스가 일관성있는 상태에 있을 때, 하나의 트랜잭션이 끝났다라는 것을 알려주는 연산이다. Rollback이란 하나의 트랜잭션 처리가 비정상적으로 종료되어 트랜잭션의 원자성이 깨진경우, 트랜잭션을 처음부터 다시 시작하거나, 트랜잭션의 부분적으로만 연산된 결과를 다시 취소시킨다.
    • 개발자가 하나의 트랜잭션 설계를 잘 하는 것이 데이터를 다루는 데 많은 이점이 있다.
  • ACID 원칙

    • Atomicity(원자성)
      • 원자성은 트랜잭션이 데이터베이스에 모두 반영되던가, 아니면 전혀 반영되지 않아야 한다는 것이다. 트랜잭션 단위로 데이터가 처리되지 않는다면, 개발자가 설계한 의도대로 데이터의 흐름이 이루어지지 않을 것이다.
    • Consistency(일관성)
      • 일관성은 트랜잭션의 작업 처리 결과가 항상 일관성이 있어야 한다는 것이다.
      • 트랜잭션이 진행되는 동안에 데이터베이스가 변경 되더라도 업데이트된 데이터베이스로 트랜잭션이 진행되는것이 아니라,처음에 트랜잭션을 진행 하기 위해 참조한 데이터베이스로 진행된다. 이렇게 함으로써 각 사용자는 일관성 있는 데이터를 볼 수 있는 것이다.
    • Isolation(독립성)
      • 독립성은 둘 이상의 트랜잭션이 동시에 실행되고 있을 경우 어떤 하나의 트랜잭션이라도, 다른 트랜잭션의 연산에 끼어들 수 없다는 점을 가리킨다.
    • Durability(지속성)
      • 지속성은 트랜잭션이 성공적으로 완료됬을 경우, 결과는 영구적으로 반영되어야 한다는 점이다.
  • Lock

    • DB는 여러 사용자들이 같은 데이터를 동시에 접근하는 상황에서, 데이터의 무결성과 일관성을 지키기 위해 Lock을 사용한다.
    • Lock 이란 트랜잭션 처리의 순차성을 보장하기 위한 방법이다.
  • Lock의 종류

    • Lock의 종류에는 Shared Lock, Exclusive Lock 이 있다.
    • Shared(공유) Lock
      • Shared Lock 은 데이터를 읽을 때 사용되는 Lock 이다. 여러 사용자가 동시에 데이터를 읽어도 데이터의 일관성에는 아무런 영향을 주지 않기 때문에, 공유 락끼리는 동시에 접근이 가능하다. 즉, 하나의 데이터를 읽는 것은 여러 사용자가 동시에 할 수 있다.
      • Read Lock 이라고도 불리며, Shared Lock 의 앞글자를 따서 S로 표기한다.
    • Exclusive(베타) Lock
      • 베타 Lock은 데이터를 변경하고자 할 때 사용되며, 트랜잭션이 완료될 때까지 유지된다. 베타락은 Lock이 해제될 때까지 다른 트랜잭션(읽기 포함)은 해당 리소스에 접근할 수 없다.
      • Write Lock 이라고도 불리며, X로 표기한다.
  • Dead Lock

    • deadlock은 트랜젝션간의 교착상태이다. 두개의 트랜젝션간에 각각의 트랜젝션이 가지고 있는 리소스의 Lock을 획득하려고 할 때 발생한다.
      img
      가장 흔한 deadlock 상황이다. Write Lock ,즉 베타락을 사용해서 1,2번 트랜잭션이 각각 1,2번 리소스의 잠금을 획득했다. 이때 동시에 상대방의 데이터에 Read Lock 을 사용해서 접근하려고 할 때 기존의 Lock 이 해제될 때까지 기다려야 한다.

동시성과 병렬성의 차이가 무엇인가요? 멀티코어 프로그래밍 관점에서 설명해주세요.
#

  • 동시성(Concurrency)

    • 동시성은 여러 작업이 겹치는 기간에 실행될 수 있음을 의미한다. 동시에 실행하는 것이 아니라 CPU가 작업마다 시간을 분할해 적절하게 context switching을 해서 동시에 실행되는 것처럼 보이게 한다.
    • 동시성의 핵심 목표는 유휴 시간을 최소화하는 것이다. 유휴 시간은 컴퓨터가 작동 가능한데도 작업을 하지 않는 시간으로 아무것도 안하고 놀고 있는 시간이라고 생각하면 된다.
  • 병렬성(Parallelism)

    • 병렬성은 동일한 시간에 독립적인 작업을 실행할 수 있음을 의미한다.
    • 동시성과는 달리 여러 작업을 다른 코어, 다른 프로세스, 별도의 컴퓨터 등에서 동시에 실행할 수 있다.
  • 동시성 vs 병렬성

    img

    image
    • 동시성두개의 task 가 있을 때 이 두개를 계속 번갈아가며 실행한다. 여기서 문제가 발생할 수 있다. 만약 task 1 이 사용하고 있던 자원이 있다고 해보자. task1 이 끝나기 전에 task2가 같은 자원을 접근한다면 자원의 값이 변경되어 서로의 실행 결과에 영향을 미칠 수 있다. 따라서 Race Condition, Deadlock, Starvation 등의 문제가 생길 수 있다.
    • 병렬성각 코어에서 task 를 독립적으로 실행한다. 병렬성은 어떤 task 가 어떤 자원을 사용하고 있는지 고려해야 하기 때문에 메모리 손상, 누수 등의 문제가 발생할 수 있다.
      동시성병렬성
      동시에 실행되는 것 같이 보이는 것실제로 동시에 여러 작업이 처리되는 것
      싱글 코어에서 멀티 쓰레드를 동작 시키는 방식멀티 코어에서 멀티 쓰레드를 동작시키는 방식
      한 번에 많은 것을 처리한 번에 많은 일을 처리
      논리적인 개념물리적인 개념

Reference
#