프로그래밍 공부
제가 이번주에 공부를 하면서 여러가지를 접하게 되어 정리를 해볼려고 합니다.
1. Observer 패턴
Obseerver 패턴은 객체의 상태 변화를 관찰하는 객체들이 있고, 상태가 바뀌면 자동으로 알림을 받는 디자인 패턴입니다.
주로 이벤트 기반 프로그래밍이나 MVC(Model-View-Controller)구조에서 많이 사용이 됩니다.
Obseerver 패턴은 여타 다른 디자인 패턴들과 다르게 일대다(one-to-many) 의존선을 가집니다.
예를 들면 유튜브 구독 시스템 구조가 있습니다. 유튜브 채널이 있고 채널을 구독한 구독자가 있으면 채널에 새로운 영상이 올라오면 구독자 전체에게 영상이 업로드 됬다고 알림이 갑니다. 이렇듯 변화가 생기면 바로 알림이가 탐지하는 구조입니다.
1-1. Observer 패턴의 흐름
1. 옵저버 패턴에서는 한개의 관찰 대상자와 여러개의 관찰자로 일 대 다 관계로 구성이된다.
2. Obseerver 패턴에서는 관찰 대상의 Subject의 상태가 바뀌면 변경사항을 옵저버 한테 통보해줍니다.(notifyObserver)
3. 대상자로부터 통보를 받은 Obseerver는 값을 바꿀수도 있고, 삭제하는 등 적절히 대응합니다.(update)
4. 또한 Observer들은 언제든 Subject의 그룹에서 추가/삭제 될 수 있습니다. Subject 그룹에 추가되면 Subject로부터 정보를 전달받게 될 것이며, 그룹에서 삭제될 경우 더 이상 Subject의 정보를 받을 수 없게 됩니다.
1-2. Observer 패턴 특징
사용 시기
1. 앱이 한정된 시간, 특정한 케이스에만 다른 객체를 관찰해야 하는 경우
2. 대상 객체의 상태가 변경될 때마다 다른 객체의 동작을 트리거해야 할때
3. 한 객체의 상태가 변경되면 다른 객체도 변경해야 할때 그런데 어떤 객체들이 변경되어야 하는지 몰라도 될때
장점
1.Subject의 상태 변경을 주기적으로 조회하지 않고 자동으로 감지할 수 있습니다.
2. 발행자의 코드를 변경하지 않고도 새 구독자 클래스를 도입할 수 있어 개방 폐쇄 원칙(OCP) 준수합니다.
3. 런타임 시점에서 발행자와 구독 알림 관계를 맞을 수 있습니다.
4. 상태를 변경하는 객체와 변경을 감지하는 객체의 관계를 느슨하게 유지할 수 있습니다.
단점
1. 순서를 제어할 수 없고, 무작위 순서로 알림을 받습니다.
2. 옵저버 패턴을 자주 구성하면 구조와 동작을 알아보기 힘들어져 코드 복잡도가 올라갑니다.
3. 다수의 옵저버 객체를 등록 이후 해제하지 않으면 메모리 누수가 발생할 수 있습니다.
2. Event Loop
Event Loop는 비동기적으로 동작하는 환경에서 이벤트와 콜백을 처리하는 메커니즘입니다.
비동기로 동작하는 핵심 요소는 브라우저가 가지고 있습니다. 여기서 브라우저는 Wed APIs, Event Table, Callback Queue, Event Loop등 으로 구성 되어있습니다.
2-1. 동작원리
1. Call Stack: 현재 실행 중인 코드가 쌓이는 곳
2. Event Queue: 비동기적으로 실행된 콜백함수가 보관되는 영역
3. Event Loop: Call Stack이 비어 있으면 Event Queue 에서 대기 중인 콜백을 Call Stack으로 옮겨서 실행합니다.
즉 Event Loop는 Call Stack과 Event Queue의 상태를 체크하여, Call Stack이 반 상태가 되면, Event Queue의 첫번째 콜백을 Call Stack으로 밀어 넣는다고 볼 수 있습니다.
3. Event Queue
Event Queue는 비동기적으로 발생한 이벤트가 들어있는 큐입니다. 위에서 말했드시 Event Loop가 Call Stack이 비어있을 때 Event Queue에서 이벤트를 꺼내서 실행합니다.
4. Observer 패턴과 Event Loop/Queue의 차이점
Observer 패턴은 객체간의 관계에 초점을 둔것이고 Event Loop/Queue는 비동기 이벤트 처리에 초점을 둔 것 입니다. 그래서 Observer 패턴은 이벤트가 발생했을 때 누가 알림을 받는가에 관한 것이고, Event Loop/Queue는 언제 실행되는가에 관한 것입니다.
5. Pub/Sub 패턴
Pub/Sub 패턴은 이벤트 기반 이키텍처에서 자주 사용되는 메시징 패턴입니다.
발행자는 메시지를 보내고, 구독자는 자신이 관심 있는 주제에 대해 메시지를 받습니다. 이때, 발생자와 구독자는 서로를 직접 알지 못하며, 중간에 메시지 브로커가 존재해 메시지를 중계합니다.
5-1 동작과정
1. 구독자는 자신이 관심 있는 주제를 브로커에 등록합니다.
2. 발행자는 특정 주제에 메시지를 발행합니다.
3. 브로커는 해당 주제를 구독한 모든 구족자에게 메시지를 전달합니다.
5-2 장점/단점
장점
1. 느슨한 결합으로 발행자와 구독자가 서로를 몰라도 됩니다.
2. 확장성이 좋아 구독자, 발행자 수가 늘어나도 시스템 구조가 단순합니다.
3. 비동기 처리여서 메시지가 즉시 전달되지 않아도 됩니다.
단점
1. 메시지 브로커 장애시 전체 시스템에 영향이갑니다.
2. 메시지 순서 보장, 중복 처리 등 추가 설계가 필요합니다.
6. 스레드(Thread)
스레드는 프로세스 내에서 실행되는 가장 작은 실행 단위입니다. 하나의 프로세스는 여러 개의 스레드를 가질 수 있으며, 이 스레드들은 같은 메모리 공간을 공유하게 됩니다.
6-1 특징
1. 경량 프로세스여서 생성과 종료가 빠릅니다.
2. 자원을 공유하기 때문에 같은 프로세스 내에서 데이터를 공유합니다.
3. 각 스레드는 독립적으로 실행합니다.
추가로 스레드는 동기화 문제와 데드락이 발생할 수 있습니다.
7. 멀티 스레드 프로그래밍
멜티 스레드 프로그래밍은 하나의 프로그램에서 여러 스레드가 동시에 실행되도록 하는 방식입니다. 이를 통해서 CPU 자원을 효율적으로 사용하고, 여러 작업을 동시에 처리할 수 있습니다.
7-1 장점/단점
장점
1. 여러 작업을 동시에 처리합니다.
2. 사용자 입력, 네트워크 요청 등 대기 시간이 줄어듭니다.
단점
1. 동기화, 데드락, 레이스 컨디션 등 문제가 발생할 수 있습니다.
2. 디버깅이 어렵습니다.
8. Isolate
Isolate는 Dart에서 사용하는 완전히 분리된 실행 단위 입니다. 각 Isolate는 자신만의 메모리 공간을 가지고, 다른 Isolate와 메모리를 공유하지 않습니다. 메시지를 통해서만 통신을 하게 됩니다.
8-1 특징
1. 병렬 처리에 적합합니다.
2. 메모리 충돌이 없습니다.
8-2 종류
entryPoint
1. 새 Isolate가 시작될 때 실행되는 함수입니다.
2.Main Isolate와 통신하기 위한 SendPort를 받아야 합니다..
message
1. Main Isolate가 새로 만들어지는 Isolate에 전달하는 초기 값입니다.
2. Isolate가 시작될 때 entryPoint 함수에 전달됩니다.
3.이를 통해 격리된 Isolate 간에 데이터 전달 가능합니다.
결국 왜 필요로 하냐면 복잡한 계산이나 오랜 시간이 걸리는 작업을 수행할 때, Dart는 단일 스레드로 동작하기 때문에 다른 작업을 할 수 없는 상황이 발생할 수 있습니다. 이런 상황에서 Isolate를 사용하면 메인 스레드의 응답성을 유지하면서도 복잡한 작업을 처리할 수 있습니다.
9. 레이스 컨디션(Race Condition)
레이스 컨디션은 두 개 이상의 프로세스 혹은 스레드가 공유 자원을 서로 사용하려고 경합(Race)하는 현상을 의미합니다.
이러면 멀티 스레드 환경에서는 프로세스 내의 모든 자원을 공유할 수 있다는 점에서 동기화 문제가 발생하게 됩니다.
상호 배제 조건을 통해서 동시에 공유 자원에 접근할 수 없도록 할 수 있으나 교착상태에 빠질 수 있습니다.
9-1 교착상태(DeadLock)
공유 자원에 대한 요구가 엉켜서 자원 관리를 잘못하여 프로세스나 스레드가 자원의 락을 획득하기 위해 무한 대기하는 것을 의미합니다
9-2 상호배제
레이스 컨디션의 문제를 해결하고자 상호 배제 조건을 두어 동시에 공유 자원에 접근할 수 없도록 하여 한 자원에 한 스레드만 접근 할 수 있게 하는 것을 의미합니다.
9-3 기아 상태
우선 순위가 가장 낮은 스레드가 끊임없이 뒤로 밀려 무한정 대기 상태를 의미 합니다.
9-4 라이브락
스레드가 동시에 실행 되면서 락의 해제와 획득을 반복적으로 하면서 정상적으로 동작하는 것 처럼 보이나 아무것도 하지 않는 상태를 의미합니다.
9-5 임계영역
여러 개의 스레드가 수행되는 시스템에서 각 스레드들이 공유하는 데이터를 변경하는 코드 영역입니다.상호배제, 진행, 제한된 대기 조건을 모두 만족해야 임계영역을 통해서 레이스 컨디션을 예방할 수 있습니다.
9-6 뮤텍스
락 메커니즘으로 오직 하나의 스레드만이 동일한 시점에 뮤텍스를 얻어 임계 영역에 접근할 수 있습니다. 그리고 오직 이 스레드만이 임계 영역에서 나갈 때 뮤텍스를 해제할 수 있습니다.
9-7 세마포어
세마포어도 뮤텍스와 동일하게 공통으로 관리하는 하나의 값을 이용해 상호배제를 달성합니다.
그러나 세마포어는 Signaling 메커니즘으로, 락을 걸지 않은 스레드도 Signal을 보내 락을 해제할 수 있다는 점에서 뮤텍스와 다릅니다.