챌린지 11일차 학습 정리

챌린지 11일차 학습 정리

네이버 부스트캠프 9기 챌린지 11일차 학습 정리 페이지입니다.

  • 누군가 작성한 것을 그대로 쓰는 것이 아니라 나만의 언어로 재구조화하여 작성해야 합니다.
  • 기술 키워드에 대한 상세 내용도 좋고, 미션 해결 과정에서 기능 구현을 성공한 사례도, 트러블 슈팅 경험도 좋습니다.

목차

학습한 내용

비동기 처리 문법

비동기 프로그래밍

  • 동기(Synchronous)
    • 현재 작업의 응답이 끝남과 동시에 다음 작업이 요청됨
    • 함수를 호출하는 곳에서 호출하는 함수와 결과가 반환될 때까지 기다림
    • 작업 완료 여부를 계속 확인함
  • 비동기(Asynchronous)
    • 현재 작업의 응답이 끝나지 않은 상태에서 다음 작업이 요청됨
    • 함수를 호출하는 곳에서 결과를 기다리지 않고, 다른 함수(Callback)에서 결과를 기다림
    • 작업 완료 여부를 확인하지 않음

Callback(콜백)

  • 콜백은 실행 가능한 함수를 인자로 전달하여, 특정 상황이 발생할 때 호출되게 하는 방식을 말합니다.
  • 콜백은 깊이가 깊어질 수록 코드의 가독성이 떨어지고, 에러 추적이 어려워집니다. (=콜백 지옥)

Promise

비동기 처리 방법 정리

구분callbackpromiseasync/await
에러 처리콜백 함수 내에서 처리catch() 메서드로 처리try-catch 블록으로 처리
가독성간단한 경우에는 괜찮으나, 점점 복잡해짐.가독성 좋음가독성 좋음
중첩 처리콜백 함수 내에서 처리then() 메서드를 사용await 키워드를 사용

병렬처리와 스레드

병렬처리(Parallel Processing)

  • 병렬처리란 여러 개의 작업을 동시에 실행해서 효율을 높이는 것을 의미한다.
  • 멀티 코어를 활용하여 문제 해결 성능을 향상시킬 수 있다.
  • 병렬처리는 여러 스레드를 활용하는 멀티 스레드 방법이 있고, 여러 개의 프로세스를 활용하는 멀티 프로세싱 방법이 있다.

스레드

  • 스레드란 프로세스 내에서 실행되는 여러 흐름의 단위를 말한다.
  • 프로세스가 할당받은 자원을 이용하는 실행의 단위를 의미한다.
  • 스레드는 프로세스 내에서 각각 Stack만 따로 할당받고 Code, Data, Heap 영역은 공유한다.

스레드 풀

개념

  • 스레드 풀이란 미리 일정 개수의 스레드를 생성하여 관리하는 기법을 말합니다.
  • 생성된 스레드들은 작업을 할당받기 위해 대기 상태에 있다가 작업이 발생하면 대기 중인 스레드 하나가 해당 작업을 수행합니다.
  • 작업이 완료된 스레드는 다시 대기 상태로 돌아가고 새로운 작업을 할당받을 준비를 합니다.

스레드 풀의 장점

  • 자원 효율성
    • 스레드 풀은 미리 정해진 개수의 스레드를 생성하여 관리하기 때문에 스레드 생성 및 삭제에 따른 오버헤드를 줄일 수 있습니다.
  • 응답성 및 처리량 향상
    • 스레드 풀은 스레드가 대기 상태로 존재하다가 작업이 발생하면 대기 중인 스레드 하나에 작업을 즉시 할당하여 실행할 수 있으며, 작업 처리를 병렬로 진행할 수 있고 작업 처리 속도를 향상시킬 수 있습니다.
  • 작업 제어
    • 스레드 풀을 사용하면 동시에 처리할 수 있는 작업의 개수를 제한할 수 있으므로 시스템의 부하를 조절하고 과도한 작업 요청으로 인한 성능 저하를 방지할 수 있습니다.
  • 스레드 관리
    • 스레드의 생명 주기를 관리할 수 있습니다.

객체지향 설계와 데이터 흐름

주요 개념

  • 객체(Object)
    • 데이터와 이를 처리하는 메서드를 하나로 묶은 소프트웨어 단위로, 현실 세계의 사물이나 개념을 반영합니다.
  • 클래스(Class)
    • 객체를 생성하기 위한 청사진으로, 객체의 속성과 메서드를 정의합니다.
  • 추상화(Abstraction) 추상화란 복잡한 시스템으로부터 핵심적인 개념 또는 기능을 간추려내는 것을 의미합니다. 즉, 불필요한 세부 사항을 숨기고 중요한 속성과 행동만을 노출하여 시스템의 복잡성을 줄이는 것을 의미합니다.
  • 캡슐화(Encapsulation) 캡슐화란 객체의 속성과 메서드를 하나로 묶고 일부를 외부에 감추어 은닉하는 것을 말합니다.
    • 정보 은닉(Information Hiding) 정보 은닉이란 프로그램의 세부 구현을 외부로 드러나지 않도록 특정 모듈 내부로 감추는 것을 말합니다. 내부의 구현은 감추고 모듈 내에서의 응집도를 높이며, 외부로의 노출을 최소화하여 모듈 간의 결합도를 떨어뜨려 유연함과 유지보수성을 높일 수 있습니다. 일반적으로 다음과 같이 3가지의 접근 제한자가 존재합니다.
      • public: 클래스의 외부에서 사용 가능하도록 노출시키는 것.
      • protected: 다른 클래스에게는 노출되지 않지만, 상속받은 자식 클래스에게는 노출되는 것.
      • private: 클래스의 내부에서만 사용되며 외부로 노출시키지 않는 것.
  • 상속(Inheritance) 상속이란 상위 클래스의 속성과 기능을 하위 클래스가 이어받아서 재사용하거나 추가, 확장하는 것을 말합니다. 상속은 코드의 재사용 측면, 계층적인 관계 형성, 유지 보수성 측면에서 중요합니다.
  • 다형성(Polymorphism) 다형성은 하나의 메서드나 클래스가 다양한 방법으로 동작하는 것을 말합니다. 다형성을 대표하는 것으로는 다음과 같이 오버로딩, 오버라이딩이 존재합니다.
    • 오버로딩(Overloading) 오버로딩은 같은 이름을 가진 메서드를 여러 개 두는 것을 말합니다. 메서드의 타입, 매개변수의 유형, 개수 등으로 여러 개를 둘 수 있으며 컴파일 중에 발생하는 정적 다형성입니다.
    • 오버라이딩(Overriding) 오버라이딩은 주로 메서드 오버라이딩(Method Overriding)을 말하며 상위 클래스로부터 상속받은 메서드를 하위 클래스에서 재정의하는 것을 말합니다. 오버라이딩은 런타임 중에 발생하는 동적 다형성입니다.

SOLID 원칙

  • 단일 책임 원칙(Single Responsibility Principle, SRP)
    • 모든 클래스는 가각 하나의 책임만 가져야 하며, 변경 사유도 하나만 가져야 합니다.
  • 개방-폐쇄 원칙(Open-Close Principle, OCP)
    • 클래스는 확장에 열려 있어야 하고, 수정에는 닫혀 있어야 합니다.
    • 기존 코드를 변경하지 않고도 기능을 추가할 수 있어야 합니다.
  • 리스코프 치환 원칙(Liskov Substitution Principle, LSP)
    • 자식 클래스는 언제나 부모 클래스를 대체할 수 있어야 합니다.
    • 자식 객체는 부모 객체의 기능을 온전히 수행할 수 있어야 하며, 부모 객체에 자식 객체를 넣어도 시스템이 문제없이 돌아가야 합니다.
  • 인터페이스 분리 원칙(Interface Segregation Principle, ISP)
    • 하나의 일반적인 범용 인터페이스보다 특정 클라이언트를 위한 여러 개의 인터페이스를 만들어야 합니다.
    • 클라이언트는 자신이 사용하지 않는 메서드에 의존하지 않아야 합니다.
  • 의존 역전 원칙(Dependency Inversion Principle, DIP)
    • 고수준 모듈은 저수준 모듈에 의존하지 않아야 합니다.
    • 구체화가 아닌 추상화에 의존해야 합니다.
    • 자신보다 변화하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스에 두어 변하기 쉬운 것의 변화에 영향을 받지 않게 해야 합니다.

객체지향 설계의 장점

  • 재사용성
    • 객체지향 설계를 통해 작성된 클래스와 객체는 다른 프로젝트에서도 재사용될 수 있습니다.
  • 유지보수성
    • 코드의 구조가 명확하고 모듈화되어 있어 수정 및 유지보수가 용이합니다.
  • 확장성
    • 새로운 기능 추가가 비교적 용이하며, 시스템을 확장할 때 기존 코드를 크게 수정할 필요가 없습니다.
  • 유연성
    • 다형성과 상속을 활용하여 시스템의 유연성을 높일 수 있습니다.

이벤트 큐

개념

  • 이벤트 큐는 메세지와 이벤트를 보내는 시점과 이를 처리하는 시점을 다르게 하는 개념을 의미합니다.
  • 프로그램이 처리할 이벤트를 저장하는 관리하는 자료구조로, 비동기 프로그래밍에서 중요한 역할을 수행합니다.

특징

이벤트 큐의 특징은 다음과 같습니다.

  • 이벤트 루프
    • 이벤트 큐는 이벤트 루프에 의해 관리됩니다. 이벤트 루프는 계속해서 큐를 확인하고, 큐에 이벤트가 있을 경우 이를 처리합니다. 이벤트가 처리되면 큐에서 제거됩니다.
  • 비동기 작업
    • 이벤트 큐는 비동기 프로그래밍에서 중요한 역할을 수행합니다. 특히, JavaScript는 단일 스레드로 동작하기 때문에, 긴 작업이 실행되면 프로그램이 멈추는 것을 방지하기 위해 비동기 작업을 이벤트 큐에 넣어 나중에 처리합니다.
  • 실행 순서 보장
    • 이벤트 큐에 들어간 이벤트는 FIFO(First In, First Out) 방식으로 처리됩니다. 즉, 먼저 들어간 이벤트가 먼저 처리됩니다.

이벤트 큐의 장점

이벤트 큐를 사용할 때의 장점은 다음과 같습니다.

  • 비동기 처리
    • 이벤트 큐는 비동기 작업을 처리하여 프로그램의 응답성을 높여줍니다.
  • 작업 관리
    • 이벤트 큐를 작업을 순서대로 관리하여, 동시에 여러 작업이 발생해도 이를 체계적으로 처리할 수 있습니다.
  • 자원 효율성
    • 이벤트 큐는 시스템 자원을 효율적으로 사용하여 멀티 스레딩 없이도 비동기 처리를 가능하게 합니다.

이벤트 핸들러

개념

  • 특정 요소에서 이벤트가 발생했을 때 실행할 함수를 말합니다.
  • 이벤트는 사용자의 입력, 시스템의 변화, 또는 프로그램 내의 상태 변화에 의해 발생할 수 있습니다.

주요 구성 요소

  • 이벤트(Event)
    • 사용자의 입력이나 시스템의 변화와 같은 특정 사건
  • 이벤트 소스(Event Source)
    • 이벤트를 발생시키는 객체나 요소
  • 이벤트 리스너(Event Listener)
    • 이벤트를 감지하고 처리하는 함수 또는 메서드

동작 방식

  1. 이벤트 등록
    • 특정 이벤트가 발생할 때 실행할 함수를 이벤트 소스에 등록합니다.
  2. 이벤트 발생
    • 사용자가 버튼을 클릭하거나 키를 누르는 등의 행위를 통해 이벤트가 발생합니다.
  3. 이벤트 감지
    • 이벤트 리스너가 해당 이벤트를 감지합니다.
  4. 이벤트 처리
    • 감지된 이벤트에 대응하여 등록된 이벤트 핸들러가 실행됩니다.

Promise 객체

  • 콜백 지옥(Callback Hell) 문제를 해결하기 위해 2015년 ES6 버전에 도입되었습니다.
  • 자바스크립트에서 콜백(callback) 대신 사용할 수 있는 방법으로 비동기 작업이 완료되면 결과를 반환하는 객체를 말합니다.
  • 프로미스 객체는 상태를 가지고 있으며 처음에는 대기 상태였다가 작업이 완료되면 성공 또는 실패 상태가 됩니다.
  • Promise 객체를 사용한 비동기 처리를 사용하는 방법은 다음과 같이 2가지 방식을 활용할 수 있습니다.
    • then() & catch()
      • 체이닝(chaining) 방식을 활용하여 로직을 처리하는 방식
      • 복잡한 로직과 예외 처리를 해야 하는 상황에서 사용하기 어렵습니다.
    • async/await
      • 자바스크립트에서 도입한 비동기 처리 방식 중 하나입니다.
      • async 는 함수 앞에 붙이는 키워드이며, asynchronous(비동기)라는 의미입니다.
      • async 가 붙은 함수는 Promise 를 반환합니다.
      • awaitasync 가 붙은 함수 안에서만 사용할 수 있는 키워드로, Promise 객체의 실행이 끝나기를 기다립니다.
      • async/await 키워드를 사용하면 비동기 코드를 가독성 좋게, 디버깅하기 편하게 작성할 수 있습니다.

Event Emitter

개념

  • Node.js에서 이벤트를 발생시키고 처리하는 데 사용되는 가장 기본적인 이벤트 처리 방식 중 하나입니다.
  • 이벤트 기반 프로그래밍에서 특정 이벤트가 발생했을 때 이를 감지하고 등록된 이벤트 핸들러를 호출하는 객체 또는 메커니즘을 말합니다.
  • Event Emitter는 주로 이벤트를 생성하고, 이벤트 핸들러를 등록하며, 이벤트가 발생했을 때 등록된 핸들러를 실행하는 기능을 제공합니다.

장점

  • 이벤트에 여러 개의 리스너를 등록할 수 있습니다.
  • 다른 객체들과 연동해 사용할 수 있습니다.
  • Promise에 비해 더욱 유연합니다.
  • 비동기 작업의 결과를 처리하는 것 뿐만 아니라 이벤트를 사용해 다양한 작업을 처리할 수 있습니다.

단점

  • 이벤트 리스너에 등록된 콜백 함수들이 처리되지 않을 경우 메모리 누수가 발생할 수 있습니다.
  • 자체적인 동기화 메커니즘이 없습니다.
  • 비동기 작업을 보다 쉽게 처리하는 최신 기능을 지원하지 않습니다. (async/await 미지원)

Comments