[면접대비 예상꼬리질문] JavaScript의 동작원리에 대해서 알고 계신가요?

임정민·2022년 4월 3일
0
post-thumbnail

JavaScript의 동작원리에 대해서 알고 계신가요?

JavaScript의 대표적인 예인 Google V8 엔진으로 설명드리겠습니다.
엔진은 Memory Heap(메모리 할당이 일어나는 곳), Call Stack(호출 스택이 쌓이는 곳) 두 개로 이루어져 있습니다.

이 두개와 Event Loop, setTimeout과 같은 브라우저 내장 API를 사용하게 해주는 Web APIs들을 통해 동작하게 됩니다.

Call Stack에 대해서 자세하게 알려주세요.

JavaScript는 한 개의 호출 스택을 가지고 있습니다. (single thread) 따라서 한 번에 한 작업만 처리할 수 있습니다.


function multiply(x, y) {
    return x * y;
}
function printSquare(x) {
    var s = multiply(x, x);
    console.log(s);
}
printSquare(5);


PrintSquare을 실행하면 어떻게 될까요?


printSquare(5) -> printSquare(5) - multiply(x, x) -> printSquare(5) - console.log(s) -> printSquare(5) -> empty!

위와같은 스택 프레임이 생기게 됩니다.

싱글 스레드와 멀티 스레드의 장단점에 대해서 말씀해주세요.

싱글 스레드의 장점 
1. Context Switching을 사용하지 않기 때문에 자원 소모가 적다
2. 자원 접근에 대한 동기화를 신경쓰지 않아도 된다.
3. 단순 CPU만 사용한다면 싱글스레드로 프로그래밍하는 것이 효율적이다.(Context Switching안하니까!!)

싱글 스레드의 단점
1. 여러 개의 CPU를 활용하지 못한다.
2. 연산량이 많은 작업을 하는 경우 그 작업이 완료되어야 다른 작업을 수행할 수 있다.

멀티 스레드의 장점
1. 응답성 : 프로그램의 일부분이 중단되거나 긴 작업을 수행하더라도 프로그램의 수행이 계속되어 응답을 유지할 수 있다. (새로운 스레드를 생성하여 극복이 가능하다) 하지미나 싱글 스레드는 프로그램이 중단된다.
2. 다중 CPU 구조에서는 각각의 스레드가 다른 프로세서에서 병렬로 수행될 수 있으므로 병렬성이 증가한다.

멀티 스레드의 단점
1. Context Switching, 동기화 등의 이유로 싱글 스레드보다 느리다.
2. 프로그래밍 난이도가 높다. 스레드 수만큼 사원을 많이 사용한다.

JavaScript는 싱글 스레드의 단점을 어떻게 극복하나요?

비동기처리를 통해서 단점을 극복합니다. Callback 함수, ES6 이후의 Promise, async/await가 있습니다.

V8 엔진에 대해서 자세하게 설명해주세요.

구글이 만든 오픈 소스 자바스크립트﹒웹어셈블리 엔진으로, 자바스크립트 코드를 실행 전에 최적화된 머신 코드로 컴파일하는 엔진이다. (즉, V8은 자바스크립트 코드를 받아 컴파일하고 실행하는 C++ 프로그램이다.) 크롬 브라우저와 노드 js에서 사용된다.

왜 머신 코드로 컴파일해야 하나요?

우리가 사용하는 컴퓨터 안에는 마이크로프로세서라는 작은 기계가 있는데, 이것은 CPU의 핵심 기능을 통합한 집적 회로(IC)입니다. 프로그래머가 어떤 코드를 짜서 컴퓨터에게 일을 시키려면 결국 이 마이크로프로세서가 해석할 수 있는 언어로 전달해야 합니다. 마이크로프로세서는 이것을 만든 회사나 버전에 따라 각자 다른 언어를 사용하는데, 가장 많이 쓰이는 것들은 IA-32, x86-64, MIPS, ARM 등입니다. 이 언어들은 하드웨어와 직접적으로 소통할 수 있는 코드들이고 그래서 기계어, 머신 코드라 불리는데, 결국 프로그래머들은 프로그래밍 효율을 위해 추상화 수준이 높은 high level 언어를 사용해서 코딩을 하지만 이는 결국 머신 코드로 컴파일되어야만 CPU가 이해하고 처리를 할 수 있습니다.

V8이 하는 일에 대해서 설명해주세요.

1. JavaScript 코드를 컴파일하고 실행합니다.
2. 콜 스택을 핸들링해서 JavaScript 함수를 특정 순서에 따라 실행합니다.
3. 메모리 힙에 객체들의 메모리 할당을 관리합니다.
4. 더 이상 쓰이지 않는 객체들을 가비지 콜렉팅합니다.
5. 모든 데이터 타입, 연산자, 객체, 함수를 제공합니다.
6. 이벤트 루프를 제공합니다.

V8은 어떻게 JavaScript 코드를 컴파일할까요?

V8에는 Ignition이라는 JS 인터프리터와 TurboFan 이라는 컴파일러를 이용합니다.
이전에는 Crankshaft와 Full-codegen을 통해서 컴파일하였습니다.

1. 코드 실행 전에 Full-codegen이 JS 코드를 빠르게 non-optimized 머신 코드로 컴파일
2. 한 번 컴파일된 코드를 런타임 동안 분석하여 Crankshaft가 optimized 머신 코드로 재 컴파일

이 과정을 

1. Ignition이 JS코드를 non-optimized 바이트코드를 생성
2. TurboFan이 optimized 머신 코드로 컴파일

로 변경하였습니다. 그 이유는 TurboFan이 ES6를 제공하고 TryCatch와 같은 것들을 Crankshaft가 최적화하지 못했고
Ignition이 바이트 코드로 컴파일하는 것이 머신 코드로 컴파일 하는 것보다 1/2~1/4 정도로 사이즈가 작았기 때문에 웹페이지 로드 시간을 줄였기 때문입니다.

0개의 댓글