0. 기타 개념
- 객체 지향 프로그래밍 (OOP)
> 객체지향 프로그래밍(Object-Oriented Programming, OOP)은 소프트웨어를 개발하는 방법론 중 하나로 객체 중심의 프로그래밍인데 상속, 캡슐화 추상화, 다형성이라는 네가지 특징이 있습니다. 상속은 기존 클래스를 기반으로 새로운 클래스를 정의하는 것이고, 캡슐화는 객체 내부에 직접 접근하지 않고 공개된 인터페이스를 통해서만 객체에 접근할수 있도록 하는 것입니다. 상속을 통해 코드의 재사용성을 높이고 유지보수가 용이해진다는 장점이 있으며 캡슐화를 통해 객체 간 결합도를 낮출수 있습니다. 추상화는 객체의 공통적인 특성을 추출하는 것으로 변수 또는 메서드를 하나로 묶어 단순화 하는 것이며 다형성은 동일한 인터페이스에 대해 다른 기능을 제공하는 것을 의미합니다.
1) 객체지향 프로그래밍 이란?
객체지향 프로그래밍은 소프트웨어를 설계하고 구축하는 방법론 중 하나로, 프로그래밍에서 필요한 데이터를 추상화시켜서 상태(속성, 어트리뷰트)와 행위(메서드)를 가진 객체로 만들고, 그 객체간의 상호 작용을 통해 로직을 구성하는 방법이다.
2) 객체지향의 특징
객체지향은 캡슐화, 상속, 다형성, 추상화 라는 특징을 갖고 있어 이를 통해 코드의 재사용성, 유지보수성, 확장성을 높이고, 프로그램의 구조를 더욱 명확하게 설계할 수 있도록 도와줍니다
- 캡슐화 : 데이터와 함수를 하나로 묶어 캡슐화된 객체는 인터페이스를 제외한 내용이 내부로 은폐된다. 객체의 내부 구현을 외부로부터 숨기고, 객체 간의 결합도를 낮추어 시스템의 유지보수성과 확장성을 향상시킵니다. 외부에서 직접 접근하지 않고도 객체 내부의 상태를 안전하게 유지
- 상속 : 이미 정의된 상의 클래스의 모든 속성과 연산을 하위 클래스가 물려받는것이다. 코드의 재사용성을 높이고, 유지보수를 용이
- 다형성 : 같은 이름의 메서드를 다양한 객체에서 다르게 구현할 수 있는 기능이다. 코드의 유연성과 확장성
- 추상화 : 복잡한 현실 세계를 단순화시켜 필요한 부분만 표현하는 것으로 객체지향 프로그래밍에서는 클래스를 통해 데이터와 기능을 추상화하여 모델링합니다.
참고 자료 : https://backendcode.tistory.com/160
3) 객체지향의 장단점
장점 : 상속과 같은 특징으로 코드의 재사용성을 높일수 있고, 유지보수가 용이하다는 장점이 있다.
단점 : 객체간 상호작용에 필요한 메서드를 호출 등 처리시간이 추가로 소요된다는 단점이 있고, 설계 시 많은 노력이 필요하다는 점이 있다.
객체지향 프로그래밍은 소프트웨어 설계 방법론중 하나로 필요한 데이터를 추상화 시켜서 객체로 만들고 객체간의 상호 작용을 통해 로직을 구성하는 방법입니다. 객체지향의 특징으로 캡슐화와 상속, 다형성과 추상화가 있으며 이러한 특징들로 객채의 내부 구현을 외부로 공개하지 않아 객체간 결합도를 낮추고 코드의 재사용와 유지보수가 용이해 집니다.
객체지향 프로그래밍에서는 클래스를 통대 데이터와 기능을 추상화 합니다. 클래스를 통해 객체는 생성되고 구체화 됩니다. 클래스는 객체를 포함하고 객체는 클래스에 속하는 개념입니다.
4) 객체지향 설계 원칙 (SOLID)
객체지향 프로그래밍에는 5가지 설계 원칙이 있다.
- S (SRP, Single Responsibility Principle) 단일 책임 원칙 : 객체는 단 하나의 책임만 가져야 한다. 응집도는 높고, 결합도는 낮게 설계해야 한다. 이는 클래스가 변경될 때 해당 변경 사항이 다른 부분에 영향을 미치는 것을 최소화하여 클래스의 응집도를 높이는 데 도움이 됩니다. // 객체가 갖는 하나의 책임
- O (OCP, Open-Closed Priniciple) 개방-폐쇄 원칙 : 기존의 코드를 변경하지 않고 기능을 추가할수 있도록 설계해야 한다. 이를 위해 추상화와 다형성을 적절히 활용하여 설계하는 것이 중요하다.
- L (LSP, Liskov Substitution Principle) 리스코프 치환 원칙 : 상위 타입의 객체를 하위 타입의 객체로 치환해도 상위 타입을 사용하는 프로그램은 정상적으로 동작해야 한다. 또한 자식 클래스는 부모 클래스의 메소드를 무시하거나 재정의 하지 않고 확장만 수행하도록 해야 하며 자식 클래스를 사용 중일 때, 거기에 부모 클래스로 치환하여도 문제가 없어야 함.
- I (ISP, Interface Segregation PRinciple) 인터페이스 분리 원칙 : 각 행위에 대한 인터페이스는 서로 분리되어야 한다. 자신이 사용하지 않는 인터페이스와 의존 관계를 맺거나 영향을 받지 않아야 한다. // 인터페이스가 갖는 하나의 책임
- D (DIP, Dependency Inversion Principle) 의존 역전 원칙 : 상위 클래스가 하위 클래스에 의존하면 안 된다는 법칙.
객체지향에는 5가지 설계원칙이 있습니다. SOLID 원칙이라고 하는데요 이는 객체는 단 하나의 책임만 가져야 하며, 기존의 코드를 변경하지 않고 기능을 추가할수 있게 설계해야 하며, 상속 관계에서 서브 클래스는 슈퍼 클래스의 기능을 무시하거나 변경하지 않고 확장할 수 있어야 합니다. 또한 각 행위에 대한 인터페이스는 서로 분리되어야 하며, 상위클래스는 하위클래스에 의존해선 안된다고 정의합니다.
5) 오버라이딩과 오버로딩
오버라이딩은 상속받은 부모 클래스의 메서드를 재정의 하는 것.
오버로딩은 하나의 클래스에서 동일한 이름을 갖는 메서드를 중복해서 정의하는 것. 이름은 같지만 매개변수가 달라서 메소드 호출시 전달되는 매개변수에 따라 호출되는 메소드가 결정된다.
6) 다중상속
하나의 자식클래스가 여러개의 부모클래스로부터 상속받는 구조. 어떤 부모로부터 어떤 메소드를 상속받는지에 대한 확인이 어렵고, 클래스 간 결합도가 높아져 유지보수에 어려움이 생길 수 있다.
- REST API 란?
> REST는 웹에서 데이터를 주고받기 위한 아키텍쳐로 URI로 자원을 명시하고, HTTP 메소드로 CRUD 연산을 합니다. 별도의 인프라 구축 없이 REST를 사용할수 있어 플랫폼과 디바이스에 구애받지 않고 범용으로 사용할수 있다는 장점이 있지만, HTTP 메소드에 맞게 사용해야 해서 연산이 한정적이라는 단점이 있습니다. 이러한 통신 아키텍쳐의 다른 예로는 gRTC가 있습니다.
- ORM 이란?
> object relational mapping 의 약자로 sql 언어 대신 데이터베이스를 연결해 주는 라이브러리 이다.
> raw query로 한번더 변환 후 데이터를 저장하기 때문에 단계가 하나 더 추가되지만 속도 차이에서는 미묘하기 때문에 사용의 편의성을 위해 ORM을 많이 사용한다.
- 세션과 쿠키의 차이?
> 둘다 HTTP 통신이 비연결성과 무상태인것을 보완하기 위해 사용되는 것으로 사용자와 웹 서버 간의 상태를 유지하고 정보를 전달하는 데 사용됩니다. 세션은 서버 측에서 데이터를 저장하고 관리하는 반면, 쿠키는 클라이언트 측에서 데이터를 저장하고 관리합니다. 세션은 보안적인 측면에서 더 안전하며, 쿠키는 클라이언트 측에서 활용성이 더 높습니다.
- 인증 인가
> 인증(Authentication):
인증은 사용자가 자신이 주장하는 신원을 확인하는 과정입니다. 즉, 사용자가 누구인지 확인하는 것입니다.
사용자가 시스템에 로그인하거나 자원에 접근할 때, 자신의 신원을 증명하는 과정을 말합니다.
대표적인 예시로는 아이디와 비밀번호를 사용하여 로그인하는 과정이 있습니다.
인증을 통해 사용자가 자신의 계정에 접속할 수 있는지를 확인합니다.
>인가(Authorization):
인가는 인증된 사용자가 특정 자원이나 기능에 접근할 수 있는 권한이 있는지를 결정하는 과정입니다.
즉, 사용자가 특정 자원에 대한 접근 권한을 가지고 있는지 확인하는 것입니다.
사용자가 로그인하여 인증되었더라도, 인가를 통해 해당 사용자가 특정 자원에 접근할 수 있는지 결정합니다.
예를 들어, 관리자 권한을 가진 사용자만 특정 페이지에 접근할 수 있도록 설정하는 것이 인가의 예시입니다.
1. 네트워크
[프로세스와 스레드]
- 프로세스와 스레드의 차이
> 프로세스는 실행중인 하나의 프로그램이고, 스레드는 프로세스 내에서 실행되는 흐름의 단위이다. 때문에 프로세스는 메모리에 로드 될 시 독립된 메모리를 할당받지만, 스레드는 스택영역만 독립적이고 메모리 영역은 다른 스레드와 공유한다. (힙, 데이터, 코드영역)
- 멀티프로세스와 멀티스레드의 차이
> 멀티프로세스는 응용프로그램 하나를 여러개 프로세스로 구성하는것이고, 멀티 스레드는 하나의 프로세스 내에서 여러 스레드로 작업을 처리하는 것이다. 프로세스는 독립된 메모리를 할당받기 때문에 프로세스 간 자원공유나 통신을 하려면 IPC를 활용해야 한다. 반면 스레드는 스택영역을 제외한 메모리 영역들을 공유하고 있어서 스레드간 통신과 자원공유가 비교적 간단하고, 콘텍스트 스위칭 비용도 적게들지만 동기화를 주의해야 한다.
+) 참고자료 : https://inpa.tistory.com/entry/%F0%9F%91%A9%E2%80%8D%F0%9F%92%BB-multi-process-multi-thread
- 콘텍스트 스위칭?
> 콘텍스트 스위칭은 CPU가 처리중인 프로세스를 변경하는 것을 의미한다. 하나의 CPU는 하나의 프로세스만 처리할수 있기 때문에 CPU 스케쥴링에 의해 인터럽트가 발생해 실행될 프로세스가 변경될때 콘텍스트 스위칭이 발생하는데 이때 레지스터에 저장된 프로세스의 정보가 바뀌면서 시간과 메모리가 소요되어 오버헤드가 발생한다. 이러한 콘텍스트 스위칭은 멀티스레딩에서도 발생하는데 스레드는 스택영역만 독립적이고 나머지는 공유하기 때문에 멀티프로세스에서 보단 발생하는 오버헤드가 적다.
- 스레드세이프란?
> "스레드 세이프(thread-safe)"란 여러 스레드가 동시에 공유된 자원에 접근할 때 발생할 수 있는 문제를 방지하기 위해 프로그램이나 라이브러리가 설계되었음을 나타냅니다. 스레드 세이프한 코드는 여러 스레드에서 동시에 호출되어도 예상대로 작동하며 데이터 일관성을 유지합니다.
+) aws lambda로 실행되는 서로다른 인스턴스와 멀티프로세스의 차이
서로 다른 인스턴스: 서로 다른 인스턴스는 독립적인 가상 환경이나 물리적인 서버를 가리킵니다. 예를 들어, AWS Lambda에서 각 요청은 서로 다른 실행 환경(인스턴스)에서 실행됩니다. 이러한 인스턴스는 서로 독립적으로 처리되며, 상태를 공유하지 않습니다.
멀티프로세스: 멀티프로세스는 단일 프로그램 내에서 여러 개의 프로세스가 동시에 실행되는 것을 의미합니다. 각 프로세스는 독립적으로 실행되며, 각각의 프로세스는 자신만의 메모리 공간을 가지며 다른 프로세스와는 독립적으로 작동합니다. 이러한 멀티프로세스는 다중 처리 환경에서 작업을 병렬로 처리하는 데 사용될 수 있습니다.
[동기화]
- 뮤텍스와 세마포어
> 뮤텍스 : 스레드 동기화 + 프로세스 동기화
> 뮤텍스는 동기화 대상이 오직 하나일때, 세마포어는 동기화 대상이 하나 이상일때 사용된다. 세마포어는 시스템 범위에 걸쳐있고 파일 시스템 상의 파일 형재로 존재하는 반면 뮤텍스는 프로세스 범위를 가지며 프로세스가 종료될 때 자동으로 해제된다.
- 데드락이란?
> 교착상태라고 하며 두개 이상의 작업이 서로 상대의 작업이 끝나기만을 기다리기 때문에 결과적으로 아무것도 완료되지 못하는 상태를 뜻하며 일반적으로 네 가지 조건(상호 배제, 점유와 대기, 비선점, 순환 대기)이 동시에 충족될 때 발생한다. 이를 회피 하기 위해서 상호배제 회피 등등 다양한 전략이 사용된다.
- 교착상태 회피 방법
> 상호 배제를 회피하기: 공유 자원에 대한 접근을 상호 배제하는 대신, 동시에 여러 프로세스나 스레드가 공유 자원을 사용할 수 있도록 합니다. 예를 들어, 읽기-쓰기 락을 사용하여 읽기 연산은 동시에 수행되지만 쓰기 연산은 상호 배제됩니다.
> 자원 할당 순서 지정하기: 모든 프로세스나 스레드가 자원을 동일한 순서로 요청하도록 강제하여 교착 상태를 방지할 수 있습니다. 이를 통해 순환 대기 조건을 방지할 수 있습니다.
> 자원 요청의 타임아웃 설정: 자원을 요청할 때 타임아웃을 설정하여 일정 시간 내에 자원을 얻지 못하면 다른 자원을 찾거나 다른 작업을 수행하도록 합니다. 이를 통해 대기 시간을 제한하여 교착 상태를 방지할 수 있습니다.
> 자원을 할당하기 전에 모든 필요 조건을 확인하기: 자원을 할당하기 전에 해당 자원을 사용해도 교착 상태가 발생하지 않을지 미리 확인합니다. 이를 통해 교착 상태를 사전에 방지할 수 있습니다.
교착 상태 탐지 및 복구: 교착 상태가 발생하면 시스템이 교착 상태인지 감지하고, 교착 상태를 해결하기 위한 적절한 조치를 취합니다. 일반적으로 이러한 조치는 자원을 회수하거나, 프로세스나 스레드를 중지시켜서 자원을 해제하는 것입니다.
[메모리풀 / 커넥션풀]
- 메모리풀이란?
> 메모리 풀은 메모리 할당 및 해제를 최적화하기 위한 기술. 프로그램이 실행될 때 메모리 할당 및 해제 작업은 비용이 큰 작업 중 하나입니다. 메모리 풀은 이러한 비용을 줄이기 위해 미리 할당된 일정 크기의 메모리 블록을 관리하고, 이를 필요한 때에 할당하고 반환
- 커넥션풀이란?
> 커넥션 풀은 데이터베이스나 네트워크 등의 리소스에 대한 연결을 관리하기 위한 기술. 데이터베이스나 네트워크 연결은 매번 연결 및 해제하는 것이 비용이 큰 작업입니다. 커넥션 풀은 이러한 비용을 줄이기 위해 미리 일정 개수의 연결을 생성하여 풀(pool)에 저장하고, 요청이 있을 때마다 이 연결을 재사용한다.
[TCP / UDP]
- OSI 7계층
> 응용 / 표현 / 세션/ 전송 / 네트워크 / 데이터 / 물리
- TCP/IP 4계층
> 응용 / 전송 / 인터넷/ 네트워크 인터페이스
+) TCP / UDP는 전송계층의 프로토콜이고, 응용계층의 프로토콜 예로는 HTTP/HTTPS 가 있다.
+) 인터넷 계층의 프로토콜 예로는 IP가 있고, IP는 컴퓨터 네트워크에서 데이터를 패킷 단위로 전송하는 역할을 한다.
- TCP에 대해서?
> 송신부와 수신부의 연결을 확인하는 연결형 서비스로 패킷이 전달되는 회선이 미리 정해져 있는 가상 회선 방식이다. 패킷의 전송의 순서가 보장되고, 수신여부를 확인하며 손실여부를 확인하기 때문에 신뢰도가 높고 송신부와 수신부는 1:1 통신을 한다. 단, UDP에 비해 송수신 속도가 느리다. 통신 예로는 이메일이나 파일 전송, HTTP통신 등이 있다.
- UDP에 대해서?
> 연결을 확인하지 않고, 여러 회선으로 패킷이 전송되는 데이터그램 방식으로 전송순서가 보장되지 않고 수신여부도 확인하지 않는다. 송신부와 수신부는 1:1, 1:N, N:N 방식으로 통신을 하는데 최소한의 손실여부를 확인하기 위해 체크섬 방식으로 오류를 검출하려 하지만 이것도 완벽하지는 않다. 단, TCP에 비해 송수신 속도가 빠르다. 통신 예로는 동영상 스트리밍 등이 있다.
- TCP 통신 연결과 해제 과정 : 연결은 3 way hand shaking. 해제는 4 way hand shaking
> 클라이언트에서 서버에 연결요청하여 SYN 메세지 전송 -> 전달받은 서버는 연결하기 위해서 ACK 메세지와 함께 SYN 메세지 전송 -> 클라이언트는 다시 ACK 메세지 전송하여 연결이 이뤄진다.
> 클라이언트가 서버에 연결 해제 요청인 FIN 전송 -> 서버는 응답으로 ACK 전송하고, 연결 해제 준비 진행 -> 연결해제준비가 완료된 서버가 클라이언트에서 FIN 메세지 전송 -> 클라이언트가 이에 대한 응답으로 ACK 전송하고 연결 해제 진행.
- 보안계층 : HTTP, HTTPS, SSL암호화 방식 (공개키, 비대칭키)
> HTTP는 응용계층의 프로토콜이며 HTTPS는 HTTP에 보안계층 프로토콜이 더해진 버전으로 보안계층은 응용계층과 전송계층 사이에 위치해 있다. SSL이나 TLS 프로토콜을 통해 암호화가 이뤄지는데 이때 암호화 하는 방식으로는 공개키 방식과 대칭키 방식이 함께 사용되는데 대칭키로 데이터를 암호화 하고 이 공개된 대칭키를 공개키 방식으로 암호화 한다.
- 대칭키, 공개키
> 대칭키는 송수신자가 모두 같은 키를 갖고있어 이를 암호화 및 복호화에 사용한다. 공개키 방식은 공개키로 데이터를 암호화 하고 복호화할때는 비밀키로 복호화 하는 방식이다.
- 인터넷 창에 주소를입력 후 일어나는 일
1. 사용가자 URL을 입력하면 웹 브라우저에서는 호스트명과 프로토콜(일반적으로 HTTP 또는 HTTPS)을 식별하며 URL의 유효성을 판단한다.
2. 유요하지 않을 경우 입력한 내용을 "검색" 하고, 유효할 경우 DNS 서버에 연결할 IP를 요청한다.
3. DNS서버에서 IP 주소를 받으면 3-way hand shaking으로 TCP통신을 위한 가상회선을 연결한다.
4. HTTP연결 요청을 서버에 보내면 응답을 받고 웹 페이지 화면을 출력한다.
2. 자료구조
[시간복잡도]
> 알고리즘의 실행 시간을 정량화 한 것으로 메모리 사용량을 정량화 한것은 공간복잡도라고 한다. 시간복잡도는 최악, 평균, 최선의 시간복잡도를 나타내는 빅오, 빅세타, 빅오메가로 표기한다. 이중 빅오 표기법은 입력값에 대한 수식에서의 최고차항을 기준으로 표기한다.
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(2^n) < O(n**) 순으로 소요시간이 늘어난다.
+) O(1) : 최대힙에서 최고값, 최소힙에서 최소값, Array에서 index로 값 탐색 등등..
+) O(logn) : 이분탐색 등등..
- List (리스트) 와 Array (배열) 의 차이 (랜덤 엑세스, 삽입, 삭제에서 시간복잡도 관련하여)
> 배열은 정해진 크기만큼 데이터가 저장되는 정적 자료구조로 데이터를 배열의 "요소", 데이터가 가리키는 번호를 "인덱스" 라고 하며 배열에서 특정 인덱스에 접근하는 시간복잡도는 O(1) 이다. 반면 인덱스 0부터 탐색하기 때문에 검색하는데에는 O(n) 이다. 삽입도 O(n)인데 이때 마지막 가용공간이 남아있고, 배열의 맨 마지막에 요소를 추가한다면 O(1)이다. 삭제도 O(n)인데 마지막 요소를 삭제하는 경우는 O(1)이다.
> 리스트는 크기가 정해져 있지 않는 동적 선형 자료구조이다. 여러개의 노드로 구성된 리스트는 노드에 데이터와 다음 노드가 저장된 주소값을 가지고 있는 형태이다. 리스트의 검색은 O(n)이다. 첫번째 노드부터 확인하기 때문이다. 추가 자체는 O(1)이지만 추가할 위치를 탐색하는데 O(n)이 걸려 결국 데이터 삽입은 O(n)이다. 첫번째 노드위치에 삽입한다면 O(1)이다. 삭제 연산 자체는 O(1)이지만 위치 탐색 하기 때문에 O(n)이다. 단, 첫번째 노드를 삭제할 경우는 O(1)이다.
- 우선순위 큐
> 우선순위가 높은 데이터 부터 먼저 조회되는 자료구조로 배열과 리스트, 힙으로 표현할 수 있다.
- 힙 이란?
> 힙은 완전이진트리의 한종류의 최대값과 최소값을 찾는데 효율적인 자료구조입니다. 최대힙은 부모노드가 자식노드보다 값이 크고, 최소힙은 부모노드가 자식노드보다 값이 작다는 조건을 갖고있는데 이를 활용해 우선순위큐나 힙정렬을 구현하는데 사용됩니다.
- 힙에서의 삽입/삭제 과정
> 힙에서 데이터 삽입과정은 힙의 맨 끝에서 이뤄지며, 힙의 데이터 삭제는 우선순위가 높은 것을 삭제하여 루트노드를 삭제하는 것이다.
> 삽입 : 힙의 맨 끝에 새로운 값 a를 추가한다. 최대힙일 경우 부모노드가 자식노드보다 항상 커야 하므로 삽입된 노드 a와 이의 부모노드를 비교한다. 비교를 거듭하여 a노드의 올바른 위치를 확정한다.
> 삭제 : 힙의 루트노드를 삭제한다. 삭제된 루트노드위치에는 힙의 마지막 노드를 가져온다. 이 상태에서 부모노드와 자식노드를 비교하여 최대힙과 최소힙의 조건에 맞게 정렬한다.
- HashMap 이란? 이것의 시간복잡도? , 해시충돌과 발생시 해결법
> HashMap (HashTable)은 하나의 키에 대해 하나의 값을 저장하는 자료구조이며 해시함수를 통해 키로부터 해시를 얻을 수 있다. 이때 해시는 값이 들어있는 해시테이블의 인덱스를 찾을수 있는 값이다. 키를 넣으면 값이 나오기 때문에 삽입과 삭제에서 일반적으로 O(1)의 시간복잡도를 갖는다.
> 서로다른 키가 동일한 해시값을 갖는 경우 해시충돌이 발생했다고 말한다. 해시충돌이 발생한 경우 이를 해결하기 위해 체이닝 (같은 해시가 나오는 키의 값을 연결 리스트에 저장), 개방주소법 (인덱스+n에 값 저장) 등을 활용한다.
+) HashMap은 key에 null을 허용하지만 HashTable의 경우 key에 null을 허용하지 않는다.
[자료구조 흐름으로 정리]
"선형" 자료구조와 "비선형" 자료구조가 있다.
- 선형 자료구조는 하나의 데이터 뒤에 하나의 데이터가 존재하는 자료구조 이다.
- 배열, 리스트, 스택, 큐, 덱 (deque) 가 그 예이다.
- 배열과 리스트는 삽입과 삭제에 대한 시간복잡도에서 차이를 보인다. (위 참고)
- 비선형 자료구조는 하나의 데이터 뒤에 N개의 데이터가 이어질수 있는 자료구조이다.
- 그래프, 트리, 우선순위 큐, 힙, 해시테이블이 이에 속한다.
"그래프"
- 데이터를 포함하는 정점과 정점을 잇는 간선으로 이뤄진 자료구조로 사이클이 존재할수 있다. DFS나 BFS 방식으로 탐색할 수 있다.
"트리"
- 그래프의 한 종류로 사이클이 존재하지 않기 때문에 계층관계로 표현이 가능하다.
- "이진 트리"
- 자식노드의 수가 최대 2개인 트리
- "완전 이진 트리"
- 이진 트리에 속하면서 + 리프노드 제외 모든 레벨에 노드가 채워져 있으며 + 리프 노드는 왼쪽 노드부터 값이 차례로 채워져 있는 이진 트리
- "포화 이진 트리"
- 완전 이진 트리 이면서 리프노드의 왼쪽부터 모든 노드가 전부 채워져 있는 이진 트리
- "이진 탐색 트리"
- 왼쪽 노드는 부모 노드보다 값이 작고, 오른쪽 노드는 부모 노드보다 값이 큰 이진 트리
- "자가 균형 이진 탐색 트리"
- 삽입과 삭제 연산을 진행해도 트리의 균형을 유지하는 이진 트리
- 레드-블랙트리, AVL트리
- 삽입과 삭제 연산을 진행해도 트리의 균형을 유지하는 이진 트리
3. 개발도구
[Docker]
[K8s] 쿠버네티스
4. 개발 언어
[Python]
> python의 특징
- Python의 특징은 무엇인가요? 다른 언어와 비교했을 때 Python의 장점은 무엇인가요?
> Python은 인터프리터 언어로 읽기 쉬운 문법과 간결함으로 인해 배우기 쉽고 사용하기 편리해 다른 언어에 비해 코드를 작성하는 시간이 상대적으로 짧고 생산성이 높습니다. 또한 Python은 동적 타입 지정 언어이기 때문에 변수의 데이터 타입을 명시적으로 선언할 필요가 없어 유연성이 높습니다. 파이썬은 가비지 컬렉션을 통해 메모리를 자동으로 관리하여 비교적 개발자가 메모리 관리에 대해 신경쓰지 않아도 된다는 장점이 있습니다.
- 인터프리터란?
> 인터프리터는 프로그래밍 언어의 소스 코드를 한 줄씩 읽고 해석하여 실행하는 프로그램입니다. 즉, 인터프리터 언어인 Python의 경우, 소스 코드를 작성한 후에는 별도의 컴파일 단계 없이 바로 실행할 수 있습니다. 이는 코드를 수정하고 즉시 실행하여 결과를 확인할 수 있게 합니다. 따라서 개발자는 코드를 작성한 후 바로 실행하여 결과를 확인하고 수정할 수 있어서 개발 과정이 더욱 유연해집니다. 반면 컴파일러 언어는 소스 코드를 기계어로 번역한 후에 실행해야 하기 때문에 개발 및 테스트 과정이 상대적으로 번거롭고 시간이 소요될 수 있지만 인터프리터 언어에 비해 실행속도가 빠르다는 장점이 있습니다.
+) 알고리즘 문제풀이에서 Python과 Pypy의 실행속도를 비교해보면 동일한 소스에서 메모리양은 Python이 더 적고, 실행속도는 Pypy가 더 빠르다. 이는 Pypy 는 프로그램이 실행되는 시점에서 일부 코드를 컴파일 하면서 캐싱한다. 때문에 Python보다 메모리사용량은 크고, 실행속도는 빠르다. (참고 : https://ralp0217.tistory.com/entry/Python3-%EC%99%80-PyPy3-%EC%B0%A8%EC%9D%B4)
- decorator
> 선행으로 실행되야 하는 함수가 반복적으로 사용될때, 함수의 내부코드는 수정하지 않고 기능을 수정하고 싶을때 사용됩니다.
- def와 lambda의 차이
> def는 다중표현을 갖고 lambda는 익명함수 입니다. Def는 함수를 정의하는데 사용되며 생성 시 이름을 지정하여 재사용이 가능하고 Lambda는 익명함수를 생성하는데 사용되며 단일표현식으로 작성합니다.
- A callable object
> 파이썬은 모든 것이 객체입니다. 따라서 변수 뿐만이 아니라 함수도 객체로써 인자로 전달이 가능합니다.
- call by value, call by reference
> call by value는 전달되는 값의 복사본이 전달되는 방식으로 함수 내에서 값이 변경되어도 기존 값은 변경되지 않습니다. C나 Java에서 기본적으로 사용되는 방식입니다. 이와달리 call by reference는 전달되는 값의 메모리 주소가 전달되는 방식으로 함수내에서 값이 변경되면 기존 값도 함께 변경됩니다.
- python은 위 둘중 어느거?
> python은 모든 것이 객체이며 변수가 객체에 대한 참조를 가지고 있으므로 함수에 전달되는것은 참조입니다. 그치만 객체가 mutable 한 경우에는 함수 내에서 객체의 상태를 변경할 수 있습니다. 즉, 객체에 따라 call by value이거나 call by reference가 될수 있는 call by object reference라고 볼 수 있습니다. 그 예로 int값이 저장된 변수를 인자로 넘겨서 값을 수정하면 넘긴 쪽의 값은 변경되지 않지만 list 객체를 인자로 넘겨 함수 내부에서 값을 수정하면 넘긴쪽에서의 list 값도 함께 변경됩니다.
- python에서 main() 메소드가 있나요?
> main() 메서드는 일반적으로 프로그램의 진입점(entry point)으로 사용되는 함수입니다. python 에서는 파일의 최상단 부터 코드가 실행되기 때문에 이 함수가 명시적으로 필요하지 않습니다.
- python의 global, globals()
> global은 전역 범위에서 변수를 선언하거나 접근하는 키워드이며 globals()는 파이썬의 내장 함수로, 현재 전역 심볼 테이블을 나타내는 딕셔너리를 반환합니다.
> Python의 자료구조
- 튜플 : immutable 한 collection 데이터 타입 중 하나
- 딕셔너리 : key-value 구조로 이뤄진 collection 데이터의 객체 중 하나. 해쉬, 맵, 해쉬맵 이라고도 불린다.
- set : 순서가 없는 collection 데이터의 객체 중 하나, 유니크한 원소들만 갖고있다
- list : 파이썬의 리스트는 linked list와 다르다. 내부적으로 다른 객체를 참조하기 위한 연속적인 배열을 가지면서 배열 변수에 대한 포인터와 그 길이를 목록 헤드 구조에 저장하고 있다.
- 클래스 : 객체를 만들기 위한 청사진으로써 파이썬을 객체지향 프로그래밍을 지행하며 모든 oop의 특징을 사용할 수 있도록 제공한다.
- 파이선의 class : attribute와 methods
> attribute : 속성은 클래스 내부에 포함되어 있는 메소드나 변수를 의미합니다. 이는 클래스 속성과 인스턴스 속성으로 나뉩니다. 클래스 속성은 모든 클래스에 동일하게 영향을 주지만 인스턴스 속성은 init 메소드에서 self 사용해 정의하며 인스턴스 내에서만 영향을 끼칩니다.
> methods :
> python : generator, iterator, iterable 의 관계
- iterator
> 배열과 같은 객체로 next() 메소드를 통해 다음 구성 성분으로 이동하는것이 가능한 객체입니다. __iter__() 메서드는 이터레이터 객체 자신을 반환하고, __next__() 메서드는 다음 요소를 반환하거나 더 이상 요소가 없을 때 StopIteration 예외를 발생시킵니다.
- iterable
> iterable하다의 의미는 구성성분을 하나씩 차례로 반환 가능한 object 라는 의미로 배열과 문자열, 튜플 이 그 예 이다.
> 배열은 iterable 하지만 iterator 는 아니다.
- generator
> iterator 를 생성하는 함수로 yield를 통해 값을 반환한다. yield 호출 시 함수는 정지되며 반환 값을 next() 메소드를 호출한 쪽에 전달하게 되며 함수 내부에서 사용된 데이터들이 메모리에 그대로 유지된다.
> generator는 메모리를 효율적으로 사용할 수 있게 해주는데 모든 데이터를 메모리에 적재하는 list와 달리 generator는 next() 메소드를 통해 차례로 값에 접근할 때에만 메모리에 적재한다.
- enumerator
> iterable한 객체를 인자로 받아 iterator로 반환하는 메소드로 인자값으로 python의 list를 전달 할 수 있습니다. for loop에서 사용하게 되면 인덱스와 데이터를 한번에 확인할 수 있습니다.
> python 주요 특징 : GIL 관련
- python의 메모리 관리
> 파이썬은 모든것이 객체이고, 객체는 동적으로 할당되는 메모리 영역인 힙(heap)에 저장됩니다. 이 영역에서 reference counting 기법을 통해 파이썬의 가비지 컬렉터가 동작하여 메모리 누수를 방지하고 최적화 합니다.
- GIL 이란?
> Global Interpreter Lock 의 줄임말로 하나의 스레드만이 파이썬 인터프리터를 제어할수 있도록 하여 파이썬 바이트코드를 한번에 하나의 스레드만이 사용할 수 있게 하는 잠금기능(Lock)이다. 이는 파이썬의 GC가 동작하는 방식에 기반하여 쓰레드세이프를 보장하기 위해 적용된 것으로 마치 뮤텍스 처럼 동작하는 것으로 생각하면 되는데, 이 때문에 파이썬은 기본적으로 동기방식으로 프로그램이 실행된다. 한개 인터프리터에서 한개의 쓰레드만 실행되는 제약이 존재한다. 이는 파이썬에서 메모리 관리를 하는 방식이 reference check 방식이기 때문이다.
+) 참고자료 (GIL) : https://velog.io/@sicksong/Python-GILGlobal-Interpreter-Lock
+) 참고자료 (GIL - GC - 파이썬 쓰레드) : https://bloofer.net/114
- GC
> GC는 Garbage Collection의 약자로 여기서 garbage는 사용하지 않는 데이터를 의미한다. 파이썬에서는 참조횟수가 끝난 객체에 대한 메모리를 반환하여 메모리 관리를 한다.
+) 파이썬의 가비지 컬렉션 방식 : 파이썬의 GC는 reference Counting으로 메모리 관리를 하다 순환참조가 발생했을 때 동작한다. 순환참조는 Container 객체에서 발생하기 때문에 Container 객체는 생성 될 때마다 double linked list에 추가된다. 가비지 콜렉션이 실행되면 더블 링크드 리스트 내부에서 gc_refs값을 각 객체의 레퍼런스 카운트와 같게 설정하고 한 컨테이너 객체가 보유하고 있는 다른 컨테이너 객체를 찾아서 그 객체의 gc_refs값을 감소시킨다. 이 과정을 종료한뒤 gc_refs값이 0인 객체를 메모리에서 해제한다.
- Reference counting ?
> 파이썬은 모든것이 객체이다. 그리고 객체는 호출되는 횟수를 저장하는 메모리를 갖고있다. 파이썬의 GC는 이 참조횟수를 기반으로 동작한다. 만약 이러한 파이썬에서 멀티쓰레드를 구현하려면 각 객체별로 참조횟수를 개별로 체크할수 있도록 개별 Garbage Collection이 존재해야 쓰레드세이프한 환경이 조성되는데 이런 복잡한 문제를 해결하기 위해 애초에 파이썬에서는 멀티쓰레드가 동작하지 않도록 GIL이 존재한다.
- 파이썬의 멀티쓰레드 효율?
> 파이썬은 GIL이 존재하기 때문에 기본적으로 한개 인터프리터에서는 한개의 쓰레드만이 동작할수 있다. 때문에 멀티 쓰레드로 코드를 구현하더라도 큰 효과를 기대하기 어렵다. 하지만 아예 없는것은 아닌게 CPU - bound 프로그램이 아닌 I/O -bound 프로그램에서는 멀티쓰레드로 인한 시간 단축을 기대할 수 있다. I/O bound 프로그램에서 파일을 읽고 쓸때 발생하는 시간대기에 다른 쓰레드가 구현되기 때문이다. 따라서 프로그램의 유형에 맞게 활용하면 좋은 효율을 얻을 수 있다.
+) 사내 소스중에 python 프로젝트에 쓰레드가 구현된 기능이 있다. 외부 api 로 상품정보를 조회해 우리쪽 데이터로 컨버팅 하면서 S3에 이미지 업로드까지 하는 기능인데 이때 쓰레드가 구현되어있지만 단일 쓰레드로 구현되어있다. 이 부분을 요청된 데이터를 절반씩 나누어 두개의 쓰레드로 처리하게 하여 소요시간을 단축하게 하였다. 하지만 다양한 컨버팅, 업로드 기능이 있는 프로젝트여서 cpu 부하를 조심해야 한다.
테스트예) 15개 상품 기준
1. 3개씩 5개 쓰레드 -> 소요시간 약 44초, cpu 최대 사용량 3%
2. 15개 한개 쓰레드 -> 소요시간 약 4분 5초 cpu 최대 사용량 1%대 (그냥 서버 실행상태와 같음)
- GC
> GC는 Garbage Collection의 약자로 여기서 garbage는 사용하지 않는 데이터를 의미한다. 파이썬에서는 참조횟수가 끝난 객체에 대한 메모리를 반환하여 메모리 관리를 한다.
+) 파이썬의 가비지 컬렉션 방식 : 파이썬의 GC는 reference Counting으로 메모리 관리를 하다 순환참조가 발생했을 때 동작한다. 순환참조는 Container 객체에서 발생하기 때문에 Container 객체는 생성 될 때마다 double linked list에 추가된다. 가비지 콜렉션이 실행되면 더블 링크드 리스트 내부에서 gc_refs값을 각 객체의 레퍼런스 카운트와 같게 설정하고 한 컨테이너 객체가 보유하고 있는 다른 컨테이너 객체를 찾아서 그 객체의 gc_refs값을 감소시킨다. 이 과정을 종료한뒤 gc_refs값이 0인 객체를 메모리에서 해제한다.
- python의 dataclass 란?
> 제가 사용한 dataclass 는 파이썬 3.7부터 표준 라이브러리에 추가된 dataclasses의 메소드로 이를 통대 데이터만을 담는 클래스를 간단하게 정의할 수 있습니다. 주로 조건에 따른 document 생성시에 이를 사용했습니다. 추가로 pydantic 라이브러리에도 dataclass 메소드가 존재하는데요, pydantic은 데이터 유효성 검사, 직렬화 및 역직렬화와 같은 기능을 제공하여 입력된 정보를 다른곳에 보내기 전, 값이 유효하게 입력되었는지 확인하는 용도로 사용했습니다.
- asyncio와 멀티스레드의 차이
> asyncio는 이벤트 기반의 비동기 프로그래밍을 위한 동시성 모델이며, 싱글 스레드에서 동작합니다. 반면에 스레드는 멀티스레딩을 통해 병렬성을 달성하며, 별도의 동기화 문제에 주의해야 합니다. 선택은 프로그램의 요구사항과 성능 특성에 따라 다를 수 있습니다.
- async 썼다가 멀티스레드로 바꾼 이유
> 당시 외부 호출하여 상품정보 조회하는 부분에 aioHttp를 사용해 시간단축을 확인했는데, 하위의 다른 로직들에서 s3업로드, 바이트코드 변환 등에서도 추가로 시간단축이 필요한것을 알게됨. 전부 다 비동기 소스로 변경하기에는 작업공수가 매우 컸기에 쓰레드 방식으로 변환하여 작업하도록 함.
[Go]
- go의 특징
> Go 언어에서는 함수를 일급 객체(first-class citizen)로 취급하여 함수를 변수에 저장하거나, 다른 함수의 parameter로 전달될 수 있습니다.
> Go 언어는 고루틴(Goroutine)이라는 가벼운 스레드를 제공하여 동시성 프로그래밍을 쉽게 할 수 있도록 합니다.
> Go 언어에는 풍부한 표준 라이브러리가 포함되어 있는데 업데이트와 유지보수가 잘 이루어지므로 안정적으로 사용할 수 있습니다.
> Go 언어는 정적 타입 지정 언어로서 컴파일 과정에서 타입 체크를 수행하여 타입 관련 오류를 사전에 발견할 수 있습니다. 또한 Go 언어는 컴파일 언어로서 코드를 컴파일하여 기계어로 변환하므로 실행 속도가 빠르고 효율적입니다.
> Go 언어는 가비지 컬렉션을 통해 메모리 관리를 자동화하여 개발자가 메모리 관리에 대해 직접적으로 신경 쓸 필요가 없도록 합니다. 이를 통해 메모리 누수(memory leak)와 같은 문제를 방지하고 안정적인 애플리케이션을 개발할 수 있도록 지원합니다.
> go test 명령을 사용하여 단위 테스트를 쉽게 작성하고 실행할 수 있습니다.
- go에서의 OOP (객체 지향 프로그래밍) 사용
> Go 언어는 명시적인 상속이나 클래스 개념이 없지만 다양한 특성을 통해 객체지향 프로그래밍이가능합니다.
- go는 struct, 구조체를 이용해 객체를 표현하고, 구조체에 정의된 함수를 메서드라고 합니다. 메서드는 특정 구조체의 인스턴스에 대해 동작하도록 정의됩니다.
- Go 언어에서는 상속을 지원하지 않지만 내장 타입을 사용하여 구조체에 다른 구조체를 포함시킬 수 있습니다. 이를 통해 코드 재사용성을 높일 수 있습니다.
- Go 언어에서는 코드를 패키지로 구성하여 모듈화하고 재사용할 수 있습니다. 패키지는 관련된 함수, 구조체, 상수 등을 모아놓은 단위입니다.
> Go 언어는 간결하고 간단한 문법을 가지고 있으며, 효율적인 병렬 처리를 위한 고루틴과 채널 등의 기능을 제공하여 강력한 동시성 프로그래밍을 지원합니다.
- go 에서의 에러처리
> 저는 함수 안에서 defer 를 통해 에러처리 하였습니다. defer 문은 코드의 가독성을 높이고 후처리 작업을 효율적으로 관리할 수 있는 강력한 기능으로, Go 언어에서 자주 언급되는데요, defer 문은 함수가 종료되기 직전에 실행되는 지연된 함수 호출을 지원합니다. 이를 통해 리턴 값을 제어하거나, 예기치 못한 함수 종료시에도 적절한 에러처리가 가능합니다.
- go routine
> 고루틴(Goroutine)은 Go 언어에서 사용되는 경량 쓰레드(lightweight thread)로 운영체제의 스레드나 프로세스와는 별개로 Go 런타임에 의해 관리됩니다. 이를 통해 매우 적은 메모리를 사용하면서도 대규모 동시성(concurrency)을 지원하는데요,CPU bound 작업에서는 고루틴의 병렬 처리가 한정적이므로 별다른 성능 향상을 기대하기 어렵지만. i/o bound 작업에서는 cpu가 대기하는 동안 다른 쓰레드가 동작하여 시간단축을 기대할 수 있습니다. 네이버와 인스타그램, 유투브의 api 를 호출해 미디어 인사이트를 갱신하는 로직에서 go routine을 활용한 경험이 있습니다.
질문: Go 언어에서 go routine이란 무엇인가요?
>Go 언어의 go routine은 경량 쓰레드로, 동시성을 지원하는 핵심 개념 중 하나입니다. 이는 프로그램이 동시에 여러 작업을 처리할 수 있도록 하는데, 기본적으로 Go 언어의 런타임이 자동으로 관리해주는 특징입니다. 간단히 말해, go routine은 함수나 메서드를 독립적으로 실행할 수 있는 경량의 실행 단위입니다.
질문: Go routine을 사용하는 이유가 무엇인가요?
> Go routine은 다음과 같은 이유로 사용됩니다:
효율성: Go routine은 경량이며, 수천에서 수십만 개의 go routine을 생성할 수 있습니다. 이는 운영체제 쓰레드보다 훨씬 적은 자원을 사용하므로 효율적인 동시성을 구현할 수 있습니다.
간편한 구현: Go routine은 간단한 문법을 사용하여 생성 및 관리할 수 있습니다. 이는 복잡한 동시성 처리를 단순화하고 오류를 줄이는 데 도움이 됩니다.
통신과 공유 메모리의 간소화: Go 언어는 채널을 통한 통신을 지원하며, 이는 여러 go routine 간의 안전한 데이터 공유를 쉽게 구현할 수 있도록 돕습니다.
넌블로킹 I/O: Go 언어는 넌블로킹 I/O를 통해 여러 작업을 동시에 처리할 수 있습니다. 이는 네트워크나 파일 I/O 작업을 효율적으로 처리하는 데 도움이 됩니다.
질문: Go routine의 사용 예시는 무엇이 있나요?
> Go routine은 다양한 곳에서 사용됩니다. 예를 들어, 웹 서버에서는 클라이언트 요청을 동시에 처리하기 위해 각 요청마다 go routine을 생성할 수 있습니다. 또한 대규모 데이터 처리, 동시 작업 처리, 백그라운드 작업 실행 등에도 사용됩니다. 이를 통해 애플리케이션의 응답성을 향상시키고, 성능을 최적화할 수 있습니다.
질문: Go routine을 사용할 때 고려해야 할 사항은 무엇인가요?
> Go routine을 사용할 때 고려해야 할 중요한 사항은 다음과 같습니다:
자원 사용: 수많은 go routine을 생성할 경우 자원 소비가 증가할 수 있으므로 신중하게 고려해야 합니다.
경쟁 조건 및 동기화: 여러 go routine이 동시에 공유된 자원에 접근할 때 경쟁 조건이 발생할 수 있으므로 적절한 동기화 메커니즘이 필요합니다.
Deadlock 및 Race Condition: 잘못된 동기화로 인해 deadlock이 발생할 수 있으며, 경쟁 조건으로 인해 race condition이 발생할 수 있으므로 이를 방지하기 위해 코드를 검토해야 합니다.
[JAVA]
- JAVA의 GC
> 동적으로 할당된 메모리 영역 (힙메모리) 에서 사용하지 않는 메모리를 정리하는 가비지 컬렉터는 JVM의 구성 요소이다. Java에서 가비지 컬렉터는 reachability 라는 개념이 적용되어 동작하는데 unreachable한 객체들을 불필요하다고 판단하여 이를 제거하는 방식으로 메모리를 관리한다.
- 의존관계 주입 : IoC와 DI
[IoC : Inversion of Control]
[DI : Dependency Injection]
[PHP]
- PHP 언어의 특징
> PHP는 웹 개발을 위한 스크립트 언어로, 다음과 같은 특징을 가지고 있습니다:
> 동적 타이핑: PHP는 동적 타입 언어로 변수의 데이터 타입을 미리 선언할 필요가 없습니다. 변수의 데이터 타입은 할당되는 값에 따라 자동으로 결정됩니다. 이는 개발자가 유연하게 코드를 작성할 수 있도록 도와줍니다.
> 서버 측 스크립트 언어: PHP는 주로 서버 측에서 실행되는 언어로, 클라이언트의 요청에 따라 서버에서 동적으로 웹 페이지를 생성하고 전송합니다. 이는 사용자와 상호작용하는 동적인 웹 애플리케이션을 개발하는 데 적합합니다.
> 크로스 플랫폼 호환성: PHP는 대부분의 운영 체제와 웹 서버에서 실행될 수 있습니다. 이는 다양한 환경에서 PHP를 사용하여 웹 애플리케이션을 개발하고 배포할 수 있음을 의미합니다.
> 내장된 데이터베이스 지원: PHP는 다양한 데이터베이스 시스템과의 상호작용을 지원합니다. MySQL, PostgreSQL, Oracle 등의 데이터베이스와 연동하여 데이터를 처리하고 관리할 수 있습니다.
> 확장성: PHP는 모듈화된 구조를 가지고 있어, 필요에 따라 확장 모듈을 추가하여 기능을 확장할 수 있습니다. 이는 PHP를 사용하여 다양한 유형의 웹 애플리케이션을 개발할 때 유용합니다.
>또한, PHP의 특징 중 데이터 타입 변환에 대해 말씀드리면, PHP는 Python과 마찬가지로 동적 타입 언어이기 때문에 데이터 타입 변환은 비교적 자유롭게 이루어집니다. 하지만 이러한 자유로움은 때로 예상치 못한 버그를 발생시킬 수 있으므로, 개발자는 데이터 타입 변환을 신중하게 다루어야 합니다. 종종 타입 변환을 명시적으로 수행하여 코드의 가독성과 안정성을 향상시키는 것이 좋습니다.
- PHP 쓰레드 원칙
> PHP는 본래 단일 스레드로 설계되어 있지 않으며, 다중 스레드 환경에서 실행될 수 있습니다. 일반적으로 PHP 웹 서버는 다중 요청을 동시에 처리할 수 있는 다중 프로세스 또는 다중 스레드 모델을 사용합니다.
PHP의 주요 웹 서버인 Apache와 Nginx 등은 여러 요청을 병렬로 처리하기 위해 다중 프로세스 또는 다중 스레드 방식을 지원합니다. 이를 통해 여러 요청을 동시에 처리하여 더 효율적인 웹 서비스를 제공할 수 있습니다.
따라서 PHP는 단일 스레드가 원칙이 아니며, 다중 스레드 환경에서 실행되어 다중 요청을 동시에 처리할 수 있습니다. 이는 PHP를 사용하여 동시에 많은 사용자가 접속하는 웹 애플리케이션을 개발하고 운영할 때 중요한 장점 중 하나입니다.
[Spring]
- Spring 프레임워크란 무엇인가요? Spring의 주요 특징은 무엇인가요?
> Spring은 자바 기반의 경량화된 애플리케이션 프레임워크로서, 의존성 주입, 관점 지향 프로그래밍, 트랜잭션 관리, 보안, 웹 개발 등 다양한 기능을 제공합니다. Spring의 주요 특징은 간결하고 유연한 구조, 테스트 용이성, 생산성 향상 등입니다.
의존성 주입(Dependency Injection):
- 의존성 주입(Dependency Injection)이란 무엇인가요? Spring에서 어떻게 구현되나요?
> 의존성 주입은 객체가 직접 의존하는 객체를 생성하거나 제어하는 것이 아니라 외부에서 주입받는 방식입니다. Spring에서는 XML 또는 Java 설정 파일을 통해 의존성을 관리하고, 객체 간의 의존성을 주입하는 방식으로 구현됩니다.
Spring MVC:
- Spring MVC의 역할은 무엇인가요? Spring MVC의 주요 구성 요소는 무엇인가요?
> Spring MVC는 웹 애플리케이션의 모델-뷰-컨트롤러 아키텍처를 구현하기 위한 프레임워크입니다. 주요 구성 요소로는 컨트롤러(Controller), 서비스(Service), 모델(Model), 뷰(View) 등이 있습니다. Spring MVC는 HTTP 요청을 받아 처리하고 응답을 생성하는 데 사용됩니다.
Spring Boot:
- Spring Boot란 무엇인가요? Spring Boot의 주요 장점은 무엇인가요?
> Spring Boot는 스프링 기반의 애플리케이션을 빠르고 쉽게 개발할 수 있도록 도와주는 프레임워크입니다. 주요 장점으로는 자동 구성, 내장 서버, 간편한 의존성 관리, 메트릭 및 상태 확인 기능 등이 있습니다.
ORM과 데이터베이스 연동:
- Spring에서 ORM이란 무엇인가요? Spring에서 ORM을 사용하는 방법은 무엇인가요?
> ORM(Object-Relational Mapping)은 객체와 관계형 데이터베이스 간의 매핑을 자동화하는 기술입니다. Spring에서는 JPA(Java Persistence API)를 기반으로 한 ORM 프레임워크를 사용하여 데이터베이스와의 연동을 처리합니다.
AOP(Aspect-Oriented Programming):
- AOP(Aspect-Oriented Programming)란 무엇인가요? Spring에서 AOP를 어떻게 구현하나요?
> AOP는 관점 지향 프로그래밍의 약어로, 여러 모듈에서 공통적으로 사용되는 기능을 분리하여 관리하는 기술입니다. Spring에서는 메서드 실행 시점에 횡단 관심사(cross-cutting concern)를 적용하는 방식으로 AOP를 구현합니다. 이를 위해 프록시 패턴과 어드바이스(Advice), 포인트컷(Pointcut) 등의 개념을 사용합니다.
[Spring boot]
- Spring Boot란 무엇인가요?:
- Spring Boot는 스프링 기반의 애플리케이션을 빠르고 쉽게 개발할 수 있도록 도와주는 프레임워크입니다. 복잡한 설정 없이 간단한 설정으로 웹 애플리케이션을 개발할 수 있습니다.
- Spring Boot의 주요 특징은 무엇인가요?:
- 주요 특징으로는 자동 구성(Auto-Configuration), 내장 서버(Embedded Server), 스타터 의존성(Starter Dependency), 외부 설정(Externalized Configuration) 등이 있습니다. 이러한 기능들은 개발자가 애플리케이션을 빠르게 구축하고 실행할 수 있도록 도와줍니다.
- Spring Boot를 사용하여 웹 애플리케이션을 개발하는 과정에 대해 설명해주세요:
- Spring Boot로 웹 애플리케이션을 개발할 때는 먼저 스프링 부트 프로젝트를 생성합니다. 그 다음에는 필요한 의존성을 추가하고, 컨트롤러, 서비스, 리포지토리 등의 구성 요소를 작성합니다. 스프링 부트는 자동 구성과 스타터 의존성을 통해 설정을 최소화하고 개발 생산성을 높여줍니다. 마지막으로 애플리케이션을 실행하여 내장 서버를 통해 웹 애플리케이션을 실행할 수 있습니다.
- Spring Boot와 전통적인 Spring 프로젝트의 차이점은 무엇인가요?:
- Spring Boot는 복잡한 설정 없이 간단한 설정으로 애플리케이션을 개발할 수 있도록 도와줍니다. 반면에 전통적인 Spring 프로젝트는 XML 또는 Java 설정 파일을 사용하여 모든 설정을 명시적으로 작성해야 했습니다. Spring Boot는 자동 구성과 스타터 의존성을 제공하여 개발자가 더 빠르게 애플리케이션을 구축할 수 있습니다.
- Spring Boot 애플리케이션에서의 테스트 방법은 무엇인가요?:
- Spring Boot 애플리케이션을 테스트할 때는 JUnit과 같은 테스트 프레임워크를 사용할 수 있습니다. Spring Boot는 테스트를 위한 다양한 어노테이션과 기능을 제공하여 테스트 코드의 작성과 실행을 간편하게 할 수 있습니다. 테스트를 위해 Mock 객체를 사용하여 외부 의존성을 대체할 수도 있습니다.
5. 프레임워크
[Django]
> Django의 특징
- Django란?
> python을 기반으로 하는 웹 프레임 워크로 DB와 Admin페이지, ORM등 기본적으로 제공하는 기능들을 통해 쉽고 빠르게 개발이 가능하다는 장점이 있다. 또한 Django 템플릿을 통해 프론트엔드 개발도 가능한 것으로 알고 있다. python을 기반으로 하는 또 다른 웹 프레임워크인 Flask와 비교하여 기본적으로 제공하는 기능들이 있어 개발은 편리하지만 처음에 기능 파악하는데 시간이 소요될 수 있고, 무겁고 복잡하여 Flask 보다 개발 자유도가 떨어진다는 단점도 있다.
- 어떤 장점과 어떤 단점을 예로 들수 있나요?
인증과 ORM등 다양한 기능을 기본적으로 제공하기 때문에 이러한 기능을 처음에 파악하는데 시간이 소요될수 있다는 단점이 있다. 하지만 학습된 이후에는 빠른 어플리케이션 구축이 가능하며 Flask는 Django에 비해 기본으로 제공되는 기능이 많지 않지만 그만큼 학습난이도가 낮고, 개발의 자유도가 높다는 장점이 있다. 즉, Django는 완성도 있는 프레임워크로 대규모 애플리케이션에 적합하며, Flask는 가벼우면서도 유연한 프레임워크로 작은 프로젝트나 API 개발에 적합하다.
- Django의 동작 원리 (호출이 발생했을때)
> request가 들어오면 urls.py 에 정의된 경로에 따라 지정된 view를 호출하고 정해진 비즈니스 로직을 거쳐 응답한다. 이때 db에 접근하게 되면 models.py에 정의된 스키마를 토대로 CRUD를 진행한다.
- Django의 MTV pattern에 대해 답변해주세요.
> MTV pattern은 소프트웨어 아키텍쳐 패턴 으로 Model-Template-View로 이루어져 있다. Model은 데이터베이스에 저장되는 데이터를 의미하고, template은 사용자가 시각 적으로 확인할 수 있는 화면 즉, UI를 담당하는 부분이고, View는 데이터를 가공하고 처리하는 부분을 의미한다.
- Django 프로젝트에서 선언된 테이블을 실제로 적용하는 방법 : mm, mg
> "makemigrations"과 "migrate"는 Django에서 데이터베이스 모델의 변경 사항을 추적하고 적용하는 데 사용되는 명령어이다. makemigrations는 Django에서 모델의 변경 사항을 추적하는데 사용되며 모델에 변경사항이 있을때 적용을 위해 사용된다. migrate는 Django에서 마이그레이션 파일을 실제 데이터베이스에 적용하는데 사용된다. 따라서 모델의 변경사항을 DB에 적용하기 위해선 mm을 한뒤 mg까지 해주어야 한다.
> Django의 built-in token과 JWT 비교
- Django에서 인증하는 방법
> 인증과 정보 교환을 위한 개방형 표준(Open standard)인 JWT(Json Web Token) 방법과 Django에서 JWT를 사용할수 있도록 지원하는 써드파티 라이브러리를 활용하는 방법이 있다. 먼저 JWT는 토큰 기반의 유저 식별 인증 방법으로, 사용자 인증에 필요한 정보를 토큰에 포함하여 별도의 인증 저장소가 필요하지 않다. 이를 활용하게 되면 DB에 접근하기 전 사용자에 대한 인증체크를 미리 할수 있고, 세션마다 토큰의 유효시간을 지정하여 만료시킬 수 있다. 반면 Django의 써드파티 라이브러리중 하나인 DRF built-in Token은 개별 만료시간 지정하는 것이 없고, 인증 체크를 위해 한번의 DB접속이 필요하다는 특징이 있으며 DB에서 직접적인 토큰정보 수정을 통해 접근권한을 해제할수 있다.
> 둘중에 어느것이 더 적합할지는 적용할 프로젝트의 특성에 따라 결정하면 된다. 내가 만드는 서비스가 DB접근 전에 미리 한차례 인증을 거칠 필요가 있는지 사용자 계정에 대해 일정시간이 흐른 후 접속을 차단해야 할 필요성이 있는지 등을 확인해볼 필요가 있다.
> Django 테스트
- 테스트코드 짜는 이유?
> 코드가 제대로 작동하는지 여부를 자동적으로 알 수 있습니다. 기존에 작성된 비즈니스 로직의 구현방식이 바뀌어도 입력과 출력에 따른 동일한 결과가 발생하는지 확인하기 위해 테스트코드로 확인할 수 있습니다. 초기개발에는 테스트코드 작성을 위한 시간이 많이 걸리지만 장기적으로는 시간과 노력을 절약하고 더 나은 소프트웨어를 개발하는 데 도움이 됩니다.
- Django 프로젝트에서 테스트코드 작성
> Django에는 테스트를 위한 다양한 라이브러리가 존재하는데 그중 testCase class가 있습니다. 해당 클래스를 상속받아 테스트코드를 작성하고, testCase의 setUp과 tearDown 메소드를 오버라이딩 하여 테스트에 필요한 데이터를 임시로 생성하여 활용 할 수 있습니다. testClass 의 client 로 view에 작성된 api를 호출하여 비즈니스 로직을 실행하고, 기대하는결과와 실제 결과값이 일치한지 확인하여 테스트를 진행하게 됩니다. Django 프레임워크에서는 테스트코드 모듈을 활용하기 때문에 테스트코드는 tests.py에 작성하고, manage.py가 존재하는 위치에서 명령어를 통해 지정된 테스트를 수행하게 합니다.
> Django의 기본 설정 : CSRF, Admin, ORM, asgi와 wsgi
- Django의 CSRF
> CsrfViewMiddleware 은 CSRF Protection을 실행하는 미들웨어로 CSRF token을 체크한다.
> Django에서는 default로 CSRF를 방지해준다. 그래서 CSRF token이라는 것을 매 POST요청마다 체크하게 되어있는데 RESTful API 개발시에는 대부분 django의 유저 로그인 세션 기능을 사용하지 않고 JWT를 활용하 때문에 이러한 검증이 무의미하다. 따라서 settings.py에 기본으로 설정되어있는 기능을 주석처리 하여 비활성화 해준다.
- Django의 Admin 이란?
> Django admin은 django에서 기본으로 제공하는 관리자 기능으로 DB의 데이터를 조회하거나 추가,수정,삭제를 할 수 있고 커스터마이징을 통해 페이지를 사용성있게 꾸밀 수 있다.
- Django프로젝트 생성시 기본으로 생성되는 asgi.py와 wsgi.py
> 기본적으로 Django 프로젝트를 생성할 때는 wsgi.py와 asgi.py 파일이 함께 생성되는데 이 두 파일은 Django 애플리케이션이 서로 다른 프로토콜을 지원하기 위한 설정 파일이다.
asgi.py 파일은 Django 애플리케이션을 WSGI 호환 웹 서버에 연결하는 역할을 하고, wsgi.py 파일은 Django 애플리케이션을 ASGI 호환 웹 서버에 연결하는 역할을 한다.
일반적으로 대부분의 Django 애플리케이션은 WSGI를 사용하여 웹 서버와 통신하며, 따라서 wsgi.py 파일이 주로 사용되는데 Django 3.0부터 ASGI를 지원하기 시작했으며, 특히 비동기 웹 소켓 및 실시간 기능을 구현하려는 경우에 사용되는데 이런 경우 asgi.py 파일이 필요하다.
따라서 Django 프로젝트를 생성할 때 이 두 파일이 함께 생성되는 이유는 Django가 다양한 환경에서 사용될 수 있도록 선택의 폭을 넓히기 위함이고, 기본적으로 대부분의 경우 wsgi.py 파일만 사용되지만, ASGI 호환 웹 서버를 사용하거나 비동기 처리가 필요한 경우 asgi.py 파일을 활용할 수 있다.
> Django와 DB와 ORM
- Django의 DB
> Django 에서는 기본적으로 Sqlite 가 내장형으로 지원을 하며 Django 의 ORM 을 지원하며, Django 에서도 기본적으로 Sqlite 를 사용하게 되어 있다. 이와 달리 Flask 는 기본적으로 지원하는 DB가 없으며, Flask에서 sqlite를 사용하려면 추가로 라이브러리를 활용해야 한다.
> sqlite는 사용시 쿼리속도가 비교적 빠르면서 추가적인 메모리와 CPU비용이 들지않고, 사용이 편리하다는 장점이 있지만 보안에 취약하고 단일 프로세스 처리만 가능하다는 단점이 있다. 이러한 점을 보완하고자 DB를 변경하고자 한다면 settings.py 의 DATABASE 설정을 변경해 준다.
- Django의 ORM 이란?
> ORM은 Object-Relational Mapping의 약자로 SQL 언어 대신 데이터베이스를 연결해 주는 라이브러리로 raw query로 한번더 변환 후 데이터를 저장하기 때문에 단계가 하나 더 추가되지만 사용의 편의성을 위해 ORM을 많이 사용한다.
- Django에서 ORM에서 QuerySet과 Object의 차이
> 둘다 DB로 부터 조회된 객체를 담고 있는 것으로 QuerySet은 다수의 Object를 포함할수 있는 list 구조이고, Object는 한개의 객체를 뜻한다.
- QuerySet 조회 방법
> filter() 메소드로 조건에 맞는 객체들을 조회하도록 한다. 조회되는 객체가 없을 경우 빈 QuerySet이 반환된다. 이때 QuerySet은 iterator 로 인덱싱을 지원하지 않아 특정 인덱스의 객체 내용을 확인하려고 한다면 slicing으로 가져오거나, for loop에서 한개 객체의 속성값으로 접근해야 한다.
- Object 조회 방법
> get() 메소드로 조건에 맞는 단 한개의 객체를 조회하도록 한다. 이때, 조건에 해당하는 객체가 두개 이상 존재할 경우 "MultipleObjectsReturned" 에러가 발생하기 때문에 유니크 조건으로 객체를 조회해야 한다.
- 정참조와 역참조
> "정참조" 는 해당 객체가 다른 객체의 ForeignKey를 가지고 있거나 1:1 관계인 상황에서 참조 하는 경우이고, "역참조" 는 다른 객체가 ForeignKey를 가지고 있거나 N:N 관계인 상황으로 해당 객체를 참조하고 있는 다른 객체를 참조하려는 경우이다.
> model의 필드에 선언된 related_name을 통해 정참조객체에 접근할 수 있고, _set을 통해 역참조 객체에 접근할 수 있다.
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
# [정참조]
author = Author.objects.get(id=1)
books = author.books.all() # 정참조 객체에 접근
# [역참조] Author에 책이 많이 있는 경우를 가정하여, 한 저자가 쓴 모든 책을 가져오기 위해 _set을 사용한다..
author = Author.objects.get(id=1)
books = author.book_set.all() # Author 모델의 역참조 객체에 접근
- 1:1 , 1:N, N:N
> django의 Model 클래스에서는 속성을 정의할때 어떤 종류의 필드인지 지정할 수 있다. 문자열인지, Boolean 값인지 등이 있는데 객체간의 관계를 뜻하는 oneToOne, oneToMany, ManyToMany 속성도 있다.
먼저 oneToOne은 각 모델의 참조관계가 1:1로써 예를들어 사람과 그 사람의 프로필 테이블 관계가 있다. oneToMany는 블로그 글에 달린 코멘트들을 예로 들 수 있고, 마지막으로 ManyToMany는 음료의 성분을 예로 들 수 있다. a 음료에 설탕과 소금이 들어있을때 설탕과 소금은 b 음료에도 있을수 있기 때문이다.
ManyToMany 필드로 선언할 경우 해당 관계에 대한 값을 저장하는 테이블을 선언하여 활용할 수 있다. (through 파라미터)
- delete 동작시 실제 데이터 삭제?
> rdb는 서로 참조관계에 있는 경우가 있어 데이터를 삭제할때 주의해야 한다. 어떤 데이터가 삭제될 경우 해당 데이터를 참조하고 있는 다른 데이터가 어떻게 처리될 것인지 Model 클래스를 구현할때 on_delete 매개변수를 어떻게 하느냐에 따라 삭제가 불가능할수도 있고, 가능할 수도있다. 따라서 보존이 필요한 데이터인지 등 다양한 조건을 확인하여 삭제처리를 구현해야 한다.
- CASCADE: 참조하는 객체가 삭제될 때 해당 객체와 연결된 모든 객체도 함께 삭제됩니다.
- PROTECT: 참조하는 객체가 삭제되려고 할 때 참조하는 객체와 연결된 객체가 있으면 삭제를 막습니다.
- SET_NULL: 참조하는 객체가 삭제될 때 해당 객체와 연결된 모든 객체의 참조를 NULL로 설정합니다.
- SET_DEFAULT: 참조하는 객체가 삭제될 때 해당 객체와 연결된 모든 객체의 참조를 기본값으로 설정합니다.
- SET(): 참조하는 객체가 삭제될 때 일부나 모든 연결된 객체의 참조를 지정된 값으로 설정합니다.
- DO_NOTHING: 아무런 동작도 수행하지 않습니다. 연결된 객체가 삭제되더라도 아무런 동작을 취하지 않습니다.
- ORM에서 filtering 하는법 : Q
> Q기능을 통해 데이터를 조회 할때 and , or , not 연산을 사용하여 복잡한 데이터를 조회할 때 유용하게 쓰일 수 있습니다.
> Django와 PostgreSQL
- 두 조합을 선호하는 이유는?
> PostgreSQL은 확장 가능성 및 표준 준수를 강조하는 객체-관계형 데이터베이스 관리 시스템(ORDBMS)의 하나로 Django는 PostgreSQL에서만 작동하는 여러 데이터 유형을 제공한다.
<PostgreSQL에 Django에서 지원하는 기능>
- 집계 함수 기능
- 데이터베이스 제약 기능
- 양식 필드 및 위젯 기능
- 데이터베이스 함수 기능
- 모델 인덱스 기능
- 조회 기능
- 데이터베이스 마이그레이션 작업
- 전체 텍스트 검색
- 검증
> DRF
- DRF란?
> DRF 는 Django REST Framework 의 줄임말로 Django 기반의 웹 애플리케이션을 위한 강력한 웹 API 프레임워크이다.. 이 프레임워크는 Django를 사용하여 RESTful한 API를 쉽게 개발하고 관리할 수 있도록 도와준다.
- 시리얼라이저(Serializer): 데이터베이스 모델과 JSON 또는 다른 형식의 데이터를 변환하는 기능을 제공합니다. 이를 통해 데이터를 직렬화하고 역직렬화할 수 있습니다.
- 클래스 기반 뷰(Class-based views): DRF는 함수 기반 뷰 대신 클래스 기반 뷰를 사용하여 API를 정의합니다. 이를 통해 코드의 재사용성과 구성성을 향상시킵니다.
- 인증과 권한 설정: 사용자 인증 및 권한 관리를 쉽게 구현할 수 있도록 지원합니다. 다양한 인증 및 권한 클래스를 제공하여 세부적으로 사용자 권한을 제어할 수 있습니다.
- 라우팅(Routing): URL을 API 엔드포인트와 뷰 클래스에 매핑하는 라우팅 기능을 제공합니다.
- 쿼리셋(Queryset): DRF는 데이터베이스 조회를 위해 Django의 쿼리셋 기능을 지원합니다. 이를 통해 데이터를 효율적으로 조회하고 필터링할 수 있습니다.
- 파일 업로드 및 다운로드: 파일 업로드와 다운로드를 쉽게 처리할 수 있는 기능을 제공합니다.
- 캐싱(Caching): API 응답을 캐싱하여 성능을 향상시킬 수 있는 기능을 제공합니다.
- API 문서화: API의 사용법을 자동으로 문서화하여 개발자가 API를 쉽게 이해하고 사용할 수 있도록 지원합니다.
- DRF 프로젝트 환경세팅
> Django와 거의 유사하지만 몇가지 설정을 추가해 주어야 한다.
# settings.py
INSTALLED_APPS = [
# Django 기본 앱들...
'rest_framework', # DRF 앱 추가
# 여기에 추가적으로 사용할 앱들을 추가합니다.
]
# DRF 설정
REST_FRAMEWORK = {
# 인증 설정
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication', # 세션 인증 사용 (기본값)
'rest_framework.authentication.TokenAuthentication', # 토큰 인증 사용
],
# 권한 설정
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # 인증된 사용자만 접근 허용 (기본값)
],
# 페이지네이션 설정 (선택 사항)
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10, # 한 페이지에 보여줄 아이템 수
}
이외에도 다양한 설정 옵션을 제공하므로 프로젝트 요구 사항에 따라 설정을 추가하거나 조정할 수 있다.
- Serilization
> Django에서 직렬화(Serialization)는 데이터베이스 모델의 인스턴스를 JSON, XML 또는 다른 형식으로 변환하는 프로세스를 의미한다. 이는 Django의 REST 프레임워크에서 자주 사용되며, 데이터를 웹 API를 통해 클라이언트에게 전송할 때 주로 활용된다.
Django의 직렬화는 주로 Django의 django.core.serializers 모듈을 사용하여 처리됩니다. 이 모듈은 다양한 형식의 직렬화를 지원합니다.
from rest_framework import serializers
from .models import Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = [ # fields 를 명시할수도 있고, __all__ 로 전체 필드를 사용할수도 있다.
'id',
'user',
'content',
'report_cnt',
]
# 새로운 Comment 인스턴스 생성을 위한 뷰 또는 API 뷰
from rest_framework.response import Response
from rest_framework import status
def create_comment(request):
# 클라이언트로부터 전달된 데이터를 Serializer로 변환
serializer = CommentSerializer(data=request.data)
if serializer.is_valid(): # 데이터가 유효한지 확인
serializer.save() # 데이터베이스에 저장
return Response(serializer.data, status=status.HTTP_201_CREATED) # 생성된 데이터를 클라이언트에 반환
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) # 유효하지 않은 데이터일 경우 에러 반환
6. 디자인패턴
1) 디자인 패턴이란?
디자인 패턴은 프로그래밍에서 자주 발생하는 문제들을 해결하기 위한 일종의 설계 템플릿이라고 볼 수 있다.. 이러한 패턴은 공통된 문제 상황에 대한 해결책을 제공하여 코드를 더 효율적이고 유지보수하기 쉽게 만들어준다.
2) 디자인 패턴의 장단점
[장점]
코드의 재사용성을 높임: 반복적인 문제에 대해 반복적인 해결책을 제공하여 코드를 재사용할 수 있게 합니다.
코드의 유연성을 향상시킴: 패턴은 소프트웨어 구조를 유연하게 만들어 새로운 요구사항에 더 쉽게 대응할 수 있도록 도와줍니다.
코드의 가독성을 높임: 디자인 패턴을 사용하면 코드가 일관되고 예측 가능하게 구성되어 다른 개발자들도 이를 이해하고 유지보수하기 쉬워집니다.
[단점]
처음 개발속도다 더뎌질 수 있다.
기본적으로 객체지향을 기반으로 한 설계와 구현을 다루기 때문에 다른 설계방식 기반 프로그래밍에는 적합하지 않다.
3) GoF의 디자인 패턴 정의
GoF 라고 불리우는 4명에 의해 디자인 패턴은 처음 구체화 및 체계화 되었다. 이들의 디자인 패턴은 3가지로 분류하였는데 유형에 따라 5가지의 생성패턴과 7가지의 구조패턴, 그리고 11가지의 행위패턴 총 23개의 패턴으로 구성되며 이들 패턴은 각각 객체의 생성, 객체들 간의 관계, 객체들 간의 상호작용에 관한 문제를 해결하기 위해 사용된다.
참고 : https://gmlwjd9405.github.io/2017/10/01/basic-concepts-of-development-designpattern.html
4) 번외, MVC Pattern
MVC Pattern은 GoF의 디자인 패턴에 속하지 않는다.
디자인 패턴은 기본적으로 객체지향 소프트웨어 디자인에 관한 것으로 소프트웨어 구조와 객체 간의 관계에 초점을 맞추는 반면 MVC Pattern은 아키텍쳐 패턴으로 소프트웨어를 세 가지 구성 요소로 분리하여 애플리케이션의 유연성과 재사용성을 높이는 데 중점을 둔다.
모델(Model), 뷰(View), 컨트롤러(Controller) 세 가지 구성 요소로 애플리케이션을 분리하여 데이터, 사용자 인터페이스 및 비즈니스 로직을 분리하는데 사용한다.