그저 내가 되었고

🌟신입 백엔드 개발자 기술 면접 준비(JS & Node.js) 본문

개발/BE 일반*개발 이야기

🌟신입 백엔드 개발자 기술 면접 준비(JS & Node.js)

hyuunii 2023. 1. 4. 10:37

- Node.js의 V8엔진: 자바스크립트 런타임(구글이 C++로 만듦, 그러나 굳이 크롬이 아니더라도 실행 가능함. 그니까 크롬에서 V8로 자바스크립트 구동 가능하고, Node.js도 V8로 자바스크립트 구동 가능하단 말)

 

- V8엔진의 특징: 싱글스레드 & 콜백큐

 

- 싱글스레드? 아래부터 차례로 이해

스레드? 하나의 프로그램에서 프로세스가 실행되는 흐름의 단위. 하나의 프로세스는 보통 여러개의 스레드로 구성됨. 스레드는 프로세스 안에서 메모리 공간을 공유하지만, 프로세스는 프로세스별로 각각의 메모리 공간을 가짐.

프로세스? 실행중인 프로그램(무언가)!! 프로그램 실행시 코드와 데이터 덩어리가 메모리에 적재(load)된 것

프로그램? 실행되기를 기다리는 특정한 코드(명령어)들과 데이터들의 덩어리

 

그러니까.. 싱글스레드는? 프로그램에서 흐름이 하나만 존재한다는 뜻. 즉 하나의 콜스택과 하나의 힙을 가집니다.

콜스택이 하나? 한번에 하나의 동작만 실행할 수 있다는 뜻(단적인 예로 방 청소를 할 때를 생각해보면 된다. 청소기를 돌리고 있는 상황에서는 청소기밖에 못 돌리는 것이다. 다른 어떤 일도 처리할 수 없다. 이를 홈페이지에서 적용해보면 된다. 특정 화면이 변하고 있는 상황에서는 아무것도 클릭하지도 조작할 수도 없다. 로딩이 끝날 때까지 기다려야 하는 것이다. 하지만 우리는 클릭도 가능하고, 마우스 스크롤을 통해 홈페이지를 살펴볼 수도 있다.)

 

근데 자바스크립트가 한번에 하나만 실행함? 노놉!! 자바스크립트를 비동기적으로 코드를 실행시킬 수 있게 해주는 애들이 있삼.

그게 누구? Web API, Task Queue, Event Loop

출처 https://studium-anywhere.tistory.com/5

- 웹API: 브라우저 자체에서 지원하는 여러 API들. setTimeout, DOM이벤트, Ajax 등의 비동기 작업을 수행하도록 API(Application Programming Interface, 인터페이스는 Inter + face.. 둘이 서로를 바라보는 뉘앙스. 그러니까 서로가 바라보는 연결면, 접점 그런 의미야. 하드웨어 인터페이스는 컴퓨터에 있는 랜선과 랜선 연결 커넥터도 있어. 대표적인 인터페이스로는 컴퓨터와 사람 간의 상호작용에 대한 접점 즉 UI-User Interface-가 있지)로 지원

- 태스크 큐: 실행해야 할 여러 일을 임시로 대기시키는 큐. 일종의 대기열.

- 이벤트룹: 콜스택(그림의 스택)이 비어있는지 아닌지 체크하고 비어있으면 콜백을 콜스택으로 옮김. 자료구조는 큐.

- 콜스택:

  • 함수의 호출을 기록하는 자료구조
  • 우리가 프로그램 안에서 위치한 곳
  • 함수 실행 시 스택에 push 된다.
  • 함수로부터 반환 받을 때, 스택에서 pop 된다.

 

- JS Call Stack 동작 이해

출처 https://new93helloworld.tistory.com/361

코드와 콜스택, 웹 API, 그리고 이벤트 룹튼 위와 같은 관계로 표현된다.

 

1. 처음 시작시 모든 것들이 빈 상태

2. 코드가 실행되면 글로벌 스택 프레임이 호출 스택에 푸쉬됨

3. 그 후 첫번째 라인(setTime() 호출)이 실행됨. 실행된 함수를 스택 안에 넣는다.

4. setTimeout을 실행하면 JS가 아닌 코드가 호출된다(뭔 말인지 모르겠음.) 이는 브라우저가 제공하는 웹 API. 노드 환경에서는 노드에서 사용할 수 있는 다른 API가 제공된다.

3.  &  4.

5. setTimeout의 실행이 끝난다. 그러나 setTimeout으로 호출된 Web API는 요청된 시간동안 대기한다.

6. 실행할 JS 코드가 더 없기 때문에 호출 스택은 비워진다

5.  &  6.

7. Web API의 timeout이 만료되면 Web API는 이벤트 룹(큐 구조)에 코드를 추가하여 JS에 알릴 수 있다. 콜스택에 이미 실행중인 코드가 존재할 수 있으므로, 이벤트 룹은 대기중인 function을 콜스택에 바로 푸쉬하지 않는다.

8. 콜스택이 빌때마다 JS 런타임은 이벤트 룹에 대기중인 것이 있는지 확인하고 있으면 콜스택으로 푸쉬하여 function이 실행된다.

7.  &  8.

9. function이 실행되면 코드 내부의 console.log가 호출되고 콜스택에도 푸쉬된다.

10. console.log의 실행이 끝나면 hi가 인쇄되고 console.log는 콜스택에서 제거된다.

9.  &  10.

11. 마지막으로, function에서 실행할 다른 명령이 없으므로 콜스택에서도 제거되며 스택은 텅 비워진다. 프로그램 실행이 정상 종료됨.

 

- 그래서 Node.js가 뭔데?

구글이 만든, 크롬과 같이 V8 JS 엔진을 사용하는 JS 런타임

* runtime? 프로그램이 실행되고 있는 동안의 동작

* JS 런타임? JS가 실행되는 동작... JS가 구동되는 환경

그러므로!!!! Node.js란 JS를 구동할수 있는 환경

(+ Node.js 이전에 JS를 구동하려면 웹브라우저를 통해야했음. 근데 Node.js가 이걸 극복시켜줌... 브라우저 엔진을 사용하는게 아니라 서버에 Node.js 엔진을 설치하고, 서버쪽에서 JS를 구동할 수 있게 만들어준게 Node.js)

(++ 그래서 'Node.js를 활용한 서버 구동'이라는 말이 나올 수 있는 것. 한마디로 Node.js는 server side JS로 많이 사용된다. Node.js === 백엔드 이렇게 오해는 노놉!! Node.js로 서버를 구현할 수 있는 것!!!!! 물론 Node.js가 유일한 server side JS는 아님. 요즘 Node.js가 많이 사용될 뿐. 왜? JS라는 하나의 언어로 FE & BE 둘 다 다룰 수 있게 해주니까. 서버를 위해 추가적인 공부를 하는건 시간과 노력이 많이 소요되므로... 이를 해결해준게 Node.js)

(+++ 그래도 Node.js는 확장성 있는 넽웤 앱을 위해 설계되었으며, 서버를 위해 설계된 플랫폼은 맞음. JS를 쓰면 브라우저에 종속적인데, Node.js를 쓰면 컴퓨터 내부의 File System 등 System call도 가능해짐-이러한 부분을 Node.js는 libuv를 통해 처리함)

 

- Node.js의 장점은 무엇?

* Event-Drive, 이벤트 기반

* Non-Blocking I/O:: 

Blocking I/O? 동작하고 있는 동안에는 다른 일을 처리하지 못하다! 프로그램의 제어권이 호출된 함수가 일을 모두 마무리하기 전까지는 넘어가지 않는 것.

Non-Blocking I/O? 동작을 한 뒤에 바로 다음 제어가 돌아온다! 그래서 앞서 호출된 함수가 일을 마무리짓지 않아도 다른 함수가 일을 진행할 수 있도록, 다음 처리로 넘기게 해주는 것.

⇒ 블라킹에비해 넌블라킹이 일반적으로 좀 더 효율적. 특히, 웹에서 사용되는 JS의 경우 씽글쓰레드를 사용하므로 블라킹으로 진행되면 사용자는 특정 요청 보내놓고 무한정 대기해야...(클릭 한번 했다가 홈페이지에서 아무것도 못하고 멈춰 있어야.....) 이런거 막기 위해 비동기(Asynchronous) 방식을 채택. 백그라운드에서 돌아가야할 함수는 Web-API를 호출하면서 해결(Web-API + Event-Loop으로 케어)

* Single-Thread::

일단..

프로그램? 실행하지 않으면 메모리에 탑재(load)되지 않은채로 저장만 되어 있음. 

프로세스? 프로그램이 실행되면 메모리에 탑재(load)되며 이제는 프로세스로써 실행됨

스레드? 프로세스상에서 하나의 실행 흐름. 스레드는 한개 또는 여러개 다 가능. 각각의 스레드마다 독자적인 스택영역 갖지만 힙영역은 공유(멀티 프로세스는 스택과 힙 모두 따로 가짐)

⇒줄을 서는 대기열은 한줄 but 여러개의 작업 처리함.

그러니까 싱글스레드는? 스레드가 1개. 1개의 스택과 1개의 힙을 가짐. 그래서 직접적인 다중 처리는 불가능함 but 외부 함수 libuv를 통해 비동기적 처리를 넘김. 그렇게 싱글스레드지만 효율적인 처리를 통해 NGINX, Apache와 비슷한 성능을 얻게됨. 구로나 핸들링하는 데이터 양이 많으면 Django가 더 좋다.

 

* Google V8 Engine으로 Rapid한 Code Run, Single-Thread w/ Scalability, No Buffering, Chunk Data Print

** But!!! Not suitable for Big data. If you want to handle it, use Django.

 

- Synchronous 동기 vs Asynchronous 비동기

Synchronous: 호출하는 함수가 호출된 함수의 작업 완료 후 리턴을 기다리거나, 호출된 함수로부터 리턴을 받더라도 작업 완료 여부를 호출하는 함수 자체가 계속 체크하는 경우

Asynchronous: 호출되는 함수에게 콜백을 전달해서, 호출되는 함수가 작업이 완료되면 호출되는 함수가 이전에 전달받은 콜백을 실행. 호출하는 함수는 작업 완료 여부를 체크하지 않음.

⇒ 둘의 차이는 호출되는 함수의 완료 여부를 누가 체크하느냐. 호출하는 함수 스스로가 작업 완료 여부를 계속 체크하면 동기, 체크하지 않는다면 비동기.

 

➜동기/비동기 & 블락/넌블락의 차이?

동기/비동기? 작업의 결과물을 콜백인 메세지를 통해 주고받음. 작업 완료 여부를 신경쓰는지 안쓰는지에 따라 차이점 존재.

블락/넌블락? 함수 호출 이후에 넘어오는 제어권.

그래서... 동기/블락 & 동기/넌블락 && 비동기/블락 & 비동기/넌블락 네 개 다 존재 가능.

 

아니... 그래서 Node.js가 멀티스레드여 싱글스레드여?!!?!!???!??!?!?!?!?!?

기본적으로 JavaScript의 Event-Loop(JavaScript를 실행하는 Single-Thread)을 Main Thread로 활용하기 때문에 Single-Thread가 맞음.

벗뜨!!! 기본 작업 외 특정 작업 수행시 추가 스레드가 필요하면 새로운 스레드 생성하여 실행할 수 있는 Multi-Thread 프로세스기도 함.

node는 이벤트 기반의 플랫폼이기 때문에 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식으로 작동함. 즉 node에서 일어나는 모든 처리는 일련의 콜백을 처리하는 것과 같다.

node는 js는 v8이라는 JS 엔진 + 비동기 작업 처리하는 libuv 라이브러리(C++로 만들어짐..)로 이루어짐. 

 

출처 https://velog.io/@gil0127/%EC%8B%B1%EA%B8%80%EC%8A%A4%EB%A0%88%EB%93%9CSingle-thread-vs-%EB%A9%80%ED%8B%B0%EC%8A%A4%EB%A0%88%EB%93%9C-Multi-thread-t5gv4udj

스레드: 프로세스가 할당받은 자원을 이용하는 실행의 단위//한 프로세스 내에서 동작하는 여러 실행의 흐름. 프로세스 내의 Heap, Data, Codee 영역을 공유(멀티 스레드의 경우, 이 프로세스 영역들을 공유함. 멀티 스레딩의 경우 스레드 간의 자원을 공유하고 자원의 생성과 관리의 중복성을 최소화하여 수행 능력을 향상시킴) 하나의 프로세스 안에서 다양한 작업을 담당하는 최소의 실행 단위(e.g. 크롬 브라우저(=프로세스)에서 스포티파이로 음악 듣기(=스레드 1) & 티스토리 작성하기(=스레드 2)) 각각의 스레드는 독립적인 작업을 수행해야 하기 때문에 고유한 스레드 ID, 프로그램 카운터, 레지스터 집합, 스택을 가지고 있음.

<멀티 스레드 vs 멀티 프로세스>

 

멀티 스레드: CPU의 최대 활용을 위해 하나의 프로세스 내에서 둘 이상의 스레드가 동시에 작업을 수행하는 기술. 이러한 작업은 하나의 스레드에서 다음 스레드로 이동을 하면서 컨텍스트 스위칭(Context Switching)이 일어나고, 이를 통해 멀티 스레딩이 이루어짐. 스위칭이 일어나면서 부분적으로 조금씩 조금씩 각각의 스레드에 대한 작업을 끝내게 된다.

 

즉, context switching이 굉장히 빠르게 일어나기에 유저의 시선에는 프로그램들이 동시에 수행되는 것처럼 보임.