➡️ RDBMS는 엄격한 스키마를 가진 테이블 기반의 데이터베이스로 데이터 무결성 보장과 명확한 데이터 구조 보장의 장점을 가지지만 유연성이 떨어지고 복잡하며 수직적 확장만 가능하다는 단점을 가집니다.
NoSQL은 유연한 구조를 가지는 데이터베이스로 수평적 확장이 가능하여 서버 확장이 용이하고 대용량 데이터를 처리하는 성능이 뛰어나지만 일관성이 보장되지 않아 데이터 중복이 발생할 수 있습니다. RDBMS에 비해 속도가 빠른 편이라 소셜 미디어나 빅 데이터를 다룰 때 많이 사용됩니다.
➡️ MVC 패턴은 소프트웨어 디자인 패턴의 한 종류로 Model-View-Controller의 약자입니다. 하나의 애플리케이션, 프로젝트를 구성할 때 그 구성요소를 세 가지 역할로 구분하여 코드의 재사용성과 유지보수성을 높입니다.
사용자의 요청이 발생하면 컨트롤러는 모델을 통해 데이터를 가져옵니다. 모델은 필요한 데이터 작업을 수행한 후 결과를 리턴해줍니다. 컨트롤러는 모델이 리턴한 데이터를 뷰에 반영하고 뷰는 최종적으로 사용자에게 결과를 표시합니다.
➡️ RDBMS에서 정규화는 데이터베이스 설계에서 중복을 최소화하고 데이터베이스 구조를 최적화하는 프로세스입니다. 이를 통해 데이터베이스 성능을 향상시키고 저장 공간을 절약할 수 있습니다.
정규화는 제1정규형부터 제5정규형까지의 단계로 이루어집니다. 제1정규형은 각 테이블이 원자적인 값만을 포함하도록하고, 제2정규형은 부분 함수 종속을 제거하여 중복을 최소화합니다. 제3정규형은 이행적 종속성을 제거하며 BCNF는 모든 결정자가 후보키여야합니다.
정규화를 통해 데이터의 일관성과 무결성이 향상되지만 지나친 정규화는 데이터베이스 쿼리를 복잡하게 만들고 성능을 저하시킬 수 있으므로 적절한 정규화 수준을 유지해야합니다.
➡️ http와 https의 가장 주요한 차이점은 데이터 전송 시의 보안 수준 차이입니다. http는 웹에서 데이터를 주고받는데 사용되는 프로토콜입니다. https는 http에 보안 계층을 추가한 것입니다. http는 보안 기능이 없어 평문으로 데이터를 전송하는 반면, https는 데이터가 암호화되어 전송되므로 기밀성과 무결성이 보장됩니다.
https의 핵심 요소 중 하나는 비대칭 키 암호화입니다. 공개키와 비밀키라는 두 개의 키를 사용하여 데이터를 암호화하고 복호화합니다. 공개키는 모두에게 공개된 키, 비밀키는 서버에만 저장되어 있는 키입니다. 클라이언트는 서버의 공개키로 데이터를 암호화하여 전송하고 서버는 자신의 개인키로 데이터를 복화하하여 전송합니다.
간단한 프로젝트를 구현할 때는 http를 적용하여도 괜찮을지 모릅니다. 그러나 OAuth 로그인을 적용하거나 보안적으로 더 우수한 웹사이트를 만들기 위해서는 https를 적용해야 합니다. 이를 위해서 SSL 인증서를 발급받고 웹 서버에 인증서를 설정한 뒤, 포트를 변경하고 http 요청을 https로 리디렉션하는 규칙을 추가하는 과정이 필요합니다.
➡️ DI란 의존성 주입이라는 뜻으로 클래스가 직접 자신이 사용하는 의존 객체를 생성하거나 관리하지 않고 외부에서 의존 객체를 주입받아 사용하는 것을 말합니다. 일반적으로 생성자 주입, setter 주입 등의 방식이 있으며 이를 통해 낮은 결합도와 높은 모듈화를 실현합니다.
IoC란 제어의 역전이라는 뜻으로 소프트웨어 제어 흐름에 대한 권한을 개발자가 아닌 프레임워크가 갖는 것을 말합니다. 이는 주로 의존성 주입을 통해 이루어지며 객체의 생성과 생명 주기를 프레임워크가 담당합니다. 이를 통해 코드의 유연성을 증가시키고 변경 및 확장을 용이하게 합니다.
➡️ 객체지향 프로그래밍은 프로그램을 객체들의 집합으로 모델링하여 설계하는 프로그래밍 패러다임입니다. 객체는 데이터와 그 데이터를 처리하는 메서드로 이루어져 있습니다. 객체지향 프로그래밍의 핵심 개념으로는 캡슐화, 상속, 다형성, 추상화가 있습니다.
캡슐화는 데이터와 관련된 메서드를 하나의 단위로 묶어 정보 은닉을 제공하는 것을 말합니다. 상속은 부모 클래스의 특징과 동작을 자식 클래스가 상속 받아 재사용하는 것을 뜻합니다. 또한 다형성은 동일한 이름의 메서드를 다양한 방식으로 구현할 수 있는 것, 추상화는 복잡한 시스템을 단순화하기 위해 필요한 부분만을 추출하는 것입니다.
객체지향 프로그래밍은 이러한 핵심 개념을 가지고 재사용성, 유지보수성, 확장성, 가독성을 높이는 이점을 제공합니다.
➡️ GET과 POST는 HTTP 프로토콜에서 사용되는 두 가지 주요한 요청 메서드입니다. GET은 서버에 데이터를 요청할 때 사용되고, POST는 데이터를 제출할 때 사용됩니다. GET은 데이터를 URL에 포함하여 서버에 요청하고 데이터를 가져오는데 주로 사용됩니다. POST는 데이터를 HTTP 요청 본문(body)에 포함하여 서버에 전송하고 데이터를 제출하거나 업로드하는데 사용됩니다. 요청 본문에 데이터가 포함되기 때문에 GET 메서드보다 보안적으로 우수합니다. 각각의 용도에 맞게 적절한 메서드를 선택하여 사용해야 합니다.
프로젝트에서는 GET, POST 메서드가 아주 빈번하게 사용됩니다. 예를 들어 게시판이 존재할 때, 게시글을 가져올 때는 GET 요청을, 게시글을 작성할 때는 POST 요청을 사용합니다. 또한 로그인과 같이 보안이 주요한 요청의 경우 POST 요청을 사용하기도 합니다.
➡️ 두 가지 인증은 웹 애플리케이션에서 사용되는 인증 방식입니다. 세션 기반 인증은 서버가 사용자의 상태를 관리하고 사용자의 식별 정보를 서버에 저장하여 유지합니다. 사용자가 로그인하면 서버에서 사용자를 인증하고 해당 사용자에 대한 세션을 생성해 서버에 저장합니다. 그리고 이 생성된 세션의 ID를 사용자에게 응답해줍니다. 이후 사용자가 인증이 필요한 요청을 보낼 때마다 서버는 해당 세션을 확인하고 사용자의 권한을 확인합니다.
반면 토큰 기반 인증은 서버가 상태를 관리하지 않고 사용자가 로그인을 하면 토큰을 발급합니다. 이 토큰은 인증에 필요한 정보들을 암호화시킨 것이며 일반적으로 jwt 형태입니다. 사용자는 이 토큰을 보관하고 필요한 요청을 보낼 때마다 헤더에 토큰을 포함시켜 서버에 같이 전달합니다.
즉, 세션 기반 인증은 서버 측에서 상태를 유지하여 보안성이 높지만 서버에 부담을 주며 확장성에 제한이 있다는 단점이 있고, 토큰 기반 인증은 클라이언트 측에서 직접 토큰을 관리하여 확장성이 우수하지만 보안상의 위험이 있습니다.
➡️ JWT는 암호화된 토큰으로 사용자 정보를 인증합니다. 주로 토큰 기반 인증에서 사용되며 클라이언트와 서버 간의 인증을 유지하고 정보를 전달하는데 사용됩니다.
Access Token은 클라이언트가 서버에게 보내는 인증 정보로 주요 사용자를 인증하고 권한을 부여하는데 사용됩니다. 서버는 토큰 검증을 통해 사용자를 인증합니다. 그러나 이 토큰은 서버 측에서 수정할 수 없다는 단점을 가집니다. 뿐만 아니라 AccessToken은 특정 기간 동안만 유효하여 만료되면 재인증을 해야하는데 만료 시간이 너무 짧으면 클라이언트가 자주 재인증을 해야하고, 너무 길면 보안에 취약해집니다.
이러한 단점을 보완하기 위해 Refresh Token이 사용됩니다. Access Token의 만료 시간이 지나면 새로운 AccessToken을 발급하기 위해 사용됩니다. Access Token은 짧은 시간동안만 유효하고 자주 갱신되어 보안을 유지합니다. Refresh Token을 통해 사용자는 불필요한 재로그인 없이 로그인 상태를 유지하며 보안을 강화할 수 있습니다.
스프링부트 프로젝트에서 스프링 시큐리티와 JWT를 활용한 로그인 기능 구현시 레디스에 해당 토큰들을 저장해두고 사용하였습니다. 이때 토큰을 key로 사용하고 토큰과 관련된 정보를 value로 저장합니다. 사용자가 로그인하면 엑세스 토큰을 발급하고 만료 시간이 지나면 리프래시 토큰을 활용하여 새로운 엑세스 토큰을 발급합니다. 사용자는 반환된 토큰을 사용하여 이후 요청을 보냅니다.
➡️ OAuth는 사용자들이 인증 정보를 직접 공유하지 않고 서로 다른 웹 애플리케이션 간에 안전한 인증을 제공하는 개방형 표준 프로토콜입니다. 사용자의 인증 정보를 공개하지 않고도 안전하게 애플리케이션 간의 권한을 관리할 수 있어 보안상의 이점이 있습니다.
OAuth는 클라이언트, 리소스 소유자, 리소스 서버, 인증 서버의 네 가지 주요 구성 요소를 가집니다. 사용자가 클라이언트 애플리케이션을 통해 특정 서비스를 이용하고자 할 때, 리소스 소유자는 클라이언트에게 접근 권한을 부여합니다. 클라이언트는 권한을 요청하는 애플리케이션 또는 서비스입니다. 이 권한을 인증 서버에 제출하고 인증 서버는 클라이언트가 리소스 서버에 접근할 수 있도록 토큰을 발급합니다. 리소스 서버는 개인정보를 소유하고 있는 서버로 토큰 검증을 통해 요청된 리소스를 제공합니다.
프로젝트에서는 주로 카카오, 네이버, 구글 로그인이 OAuth 로그인으로 활용됩니다. 이를 활용하기 위해 카카오, 네이버 등의 서비스에 애플리케이션을 등록하여 API 이용 신청을 합니다. 사용자는 필수 또는 선택 동의 항목을 확인하고 인증 정보를 제공하여 로그인합니다.
➡️ CI는 지속적 통합이라는 의미로 개발자들이 작성한 코드를 정기적으로 통합하고 테스트하는 프로세스입니다. CI의 주요 목표는 코드에 변경 사항이 발생할 때마다 자동으로 빌드 및 테스트를 실행하여 오류를 최소화하고 빠르게 수정하는 것입니다.
CD는 지속적 배포의 의미로 테스트를 통과한 코드를 자동으로 운영 환경에 배포하는 방식입니다. 개발된 소프트웨어가 자동으로 배포 가능한 상태로 유지되도록 합니다. 이를 통해 소프트웨어의 새로운 버전을 더 빠르고 자주 배포할 수 있으며 사용자의 피드백을 신속하게 반영할 수 있습니다.
CI/CD는 소프트웨어 개발 생명 주기의 각 단계를 자동화하고 지속적인 통합과 전달을 실현함으로써 소프트웨어 개발과 배포 프로세스를 개선하는데 중요한 역할을 합니다.
프로젝트에서는 github actions 또는 jenkins 등을 활용하여 CI/CD 파이프라인을 구축할 수 있습니다. 저는 깃허브 액션을 활용하여 자동 빌드 및 테스트 환경을 구축하고 AWS EC2 서버에 프로젝트 배포를 자동화하였습니다.
또한 CI/CD 파이프라인에서 도커를 사용하여 애플리케이션의 빌드, 테스트, 배포 과정을 자동화 할 수 있습니다. EC2에 도커를 설치하여 활용하면 일관된 실행 환경을 보장 할 수 있게 됩니다. 즉 모든 단계에서 동일한 환경을 사용하여 개발 및 배포 프로세스를 일관되게 유지할 수 있습니다.
➡️ 멀티프로세스와 멀티쓰레드는 동시에 여러 작업을 수행하기 위한 방법입니다.
멀티프로세스는 여러 개의 독립적인 프로세스가 동시에 실행되는 것을 의미합니다. 각 프로세스는 독립적인 메모리 공간을 가지며 서로 영향을 주지 않습니다. 따라서 하나의 프로세스에서 발생한 오류가 다른 프로세스에 영향을 미치지 않아 안정성이 높습니다. 프로세스 간 통신도 가능하지만 쓰레드간 통신에 비해 비용이 많이 들며 추가적인 오버헤드를 발생시킬 수도 있습니다.
멀티쓰레드는 하나의 프로세스 내에서 여러 개의 쓰레드를 동시에 실행하여 작업을 분배하는 것을 의미합니다. 쓰레드는 같은 메모리 공간을 공유하기 때문에 데이터를 공유하여 효율적으로 작업을 수행할 수 있지만 이로 인해 동기화 문제가 발생할 수 있습니다. 쓰레드는 생성 및 소멸이 프로세스보다 더 빠르며 각 쓰레드 간의 통신이 더 간단하고 빠르고 비용이 낮습니다.
➡️ Array는 배열로 연속된 메모리 공간에 데이터를 순차적으로 저장하는 자료구조입니다. 인덱스를 통해 접근 가능하며 크기가 고정되어 있습니다. 데이터의 삽입 및 삭제가 비효율적이지만 빠른 접근이 가능합니다. 따라서 Array는 배열의 크기가 고정되어 있고, 인덱스를 통한 빠른 접근이 필요한 경우 주로 사용됩니다. 리스트, 스택 같은 자료구조를 구현할 때나 메모리 공간을 효율적으로 사용해야할 때에 사용될 수 있습니다.
LinkedList는 데이터 요소들이 노드 형태로 존재하고 각 노드가 다음 노드를 가리키는 형태의 자료구조입니다. 각 노드들이 메모리 상에서 연속적으로 위치하지 않고, 포인터를 통해 서로 연결되어 있습니다. 데이터의 삽입 및 삭제가 빠르지만 데이터에 직접 접근하기 위해서는 처음부터 순차적으로 탐색해야 하므로 접근 속도가 느립니다. 큐나 연결 리스트와 같은 자료 구조를 구현할 때나 데이터의 삽입 및 삭제가 빈번하게 발생하고 데이터의 크기가 동적으로 변하는 경우에 주로 사용됩니다.