crative 풀이 - CommonJS & Event Loop

이벤트 루프는 진짜 프로그램 안돌려보면 이해가 쉽게 가진 않는다.
그리고 CommonJS를 풀면서 다시한번 스코프와 클로저에 대해 복습할 수 있었다.
그럼 풀이를 해보도록 하겠다.

1 . 다음과 같이 subject.js 파일이 작성되어 있다고 가정해봅시다.

let x = 10
let mod = require('./lib/my-module.js') 
let result = mod.x

그리고 다음과 같이 lib/my-module.js 파일이 있습니다.

let x = 20
exports.x = 30

subject.js가 실행되면, result의 값은 무엇이 될까요?

풀이)
변수 mod에 할당된 require()은 module.exports를 리턴하는 함수인데 lib/my-module.js 내에서 exports를 참조하고 있기때문에 30이 나온다.

따라서 답은 30이다.

2 . 다음과 같이 subject.js 파일이 작성되어 있다고 가정해봅시다.

let mod = require('./lib/my-module.js')
let result = mod.x

그리고 다음과 같이 lib/my-module.js 파일이 있습니다.

let x = 10
exports.x = 20
module.exports.x = 30

subject.js가 실행되면, result의 값은 무엇이 될까요?

풀이)
require은 module.exports를 리턴하고 exports는 그냥 defalut값으로 module.exports를 참조하고 있다(exports shortcuts).
만약 exports에 강제로 할당을 해버린다면 exports값만 바뀌고 module.exports의 값은 30이 된다.

위의 그림 기억하자!

따라서 답은 30이다.

3 . 다음과 같이 subject.js 파일이 작성되어 있다고 가정해봅시다.

let mod1 = require('.lib/my-module.js');
let mod2 = require('.lib/my-module.js');
let result = (mod1 === mod2);

그리고 다음과 같이 lib/my-module.js 파일이 있습니다.

exports.obj = { name: "Alice" };

subject.js가 실행되면, result의 값은 무엇이 될까요?

풀이)
mod1, mod2 둘다 같은곳을 바라보고 있기 때문에 true가 나온다.

따라서 답은 이다.

4 . 다음과 같이 subject.js 파일이 작성되어 있다고 가정해봅시다.

let mod1 = require('.lib/my-module.js');
let mod2 = require('.lib/my-module.js');

mod1.increment();
let result = mod2.increment();

그리고 다음과 같이 lib/my-module.js 파일이 있습니다.

let counter = 0;
exports.increment = function () {
  counter += 1;
  return counter;
};

subject.js가 실행되면, result의 값은 무엇이 될까요?

풀이)
mod1.increment()를 실행함으로써 lib/my-module.js의 exports.increment 함수가 호출되어 (count++) count는 1이되고, result가 다시 호출하기 때문에(count++) count는 2가된다.

따라서 답은 2이다.

5 . 다음과 같이 subject.js 파일이 작성되어 있다고 가정해봅시다.

let mod1 = require('.lib/my-module.js');
let mod2 = require('.lib/my-module.js');

그리고 다음과 같이 lib/my-module.js 파일이 있습니다.

console.log("Loading module!")

subject.js가 실행되면, 몇번의 console.log가 찍히게 될까요?

풀이)
mod1, mod2에 require을 실행해서 파일을 각각 한번씩 호출하게 된다(총 2번).
그러나 node.js의 캐싱(메모이제이션 기능이라 생각하자)으로 require의 cache가 바뀌지 않았다면 여러번 호출하더라도 모듈코드가 여러번 실행되지 않는다.
따라서 mod2에서는 mod1에서 한 번 실행했기 때문에 '파일을 실행했다'는 데이터가 저장되어 두 번 실행하지 않는다.

따라서 답은 1이다.

6 . 모든 setTimeout 콜백이 실행되고 난 후, 어떤 순서로 문자열이 콘솔에 찍히게 될까요?

consule.log("A");

setTimeout(function() {
  console.log("B");
}, 1000);

setTimeout(function() {
  console.log("C");
}, 500);

console.log("D");

풀이)
setTimeout함수는 비동기로 실행된다.
로직의 모든것이 실행된 후 setTimeout은 callstack -> WebApis로 넘어가게 되어 n초 후 callback queue로 이동하게 되고, callStack이 다 빌때까지 기다리게 된다.

따라서 consule.log("A");가 먼저 실행되어 A가 먼저찍히고, console.log("D");이 실행되어 그 다음이 D, 그리고 5초 후 C가 찍히고 그 다음 B가 찍힌다.

따라서 답은 ADCB이다.

7 . 모든 setTimeout 콜백이 실행되고 난 후, 어떤 순서로 문자열이 콘솔에 찍히게 될까요?

console.log("A");

setTimeout(function() {
  console.log("B");
}, 0);

console.log("C");

풀이)
setTimeout함수는 비동기이기 때문에 0초로 설정해 놓았어도 callstack이 다 비워질 때 까지 순서를 기다리게 된다.
따라서 A가 제일 먼저 찍히고 그다음이 C, 마지막으로 B가 찍히게 된다.

따라서 답은 ACB이다.

8 . superLongComputation()은 5초가 걸리는 동기함수라고 가정합시다. 모든 setTimeout 콜백이 실행되고 난 후, 어떤 순서로 문자열이 콘솔에 찍히게 될까요?

console.log("A");

setTimeout(function() {
  console.log("B");
}, 1000);

superLongComputation();

console.log("C");

풀이)
A(동기적) -> B(WebApis에서 1초 기다린다) -> superLongComputation()(동기적으로 실행, callstack에서 5초동안 실행된다) ->(그 사이 1초 후 B가 callback queue에서 기다린다) -> C(동기적, superLongComputation()실행 후 바로 callstack에서 실행된다) -> callstack이 비어진 후 B 실행된다.

따라서 답은 ACB이다.

9 . superLongComputation()은 5초가 걸리는 동기함수라고 가정합시다. 모든 setTimeout 콜백이 실행되고 난 후, 어떤 순서로 문자열이 콘솔에 찍히게 될까요?

console.log("A");

setTimeout(function() {
  console.log("B");
}, 1000);

superLongComputation();

setTimeout(function() {
  console.log("C");
}, 500);

console.log("D");

풀이)
A(동기적) -> B(WebApis에서 1초 기다린다) -> superLongComputation()(동기적으로 실행, callstack에서 5초동안 실행된다) ->(그 사이 1초 후 B가 callback queue에서 기다린다) -> D(동기적, superLongComputation()실행 후 바로 callstack에서 실행된다) -> callstack이 비어진 후 C 실행됨 -> C가 실행된 뒤 B가 실행된다.

따라서 답은 ACB이다.

10 . 모든 setTimeout 콜백이 실행되고 난 후, 어떤 순서로 문자열이 콘솔에 찍히게 될까요?

console.log("A");

setTimeout(function() {
  console.log("B");
}, 500);

setTimeout(console.log("C"), 1000);

풀이)
A는 동기적이므로 먼저 실행된다.
setTimeout(console.log("C"), 1000)에서 console.log("C")는 C를 바로 실행하게 된다.
그다음 B가 실행된다.

따라서 답은 ADBC이다.

11 . 모든 setTimeout 콜백이 실행되고 난 후, 어떤 순서로 문자열이 콘솔에 찍히게 될까요?

console.log("A");

setTimeout(go, 100);

setTimeout(function() {
  console.log("B");
}, 50);

function go () {
  console.log("X")
}

풀이)
setTimeout(go, 100)에서는 go함수를 호출한다.
go함수는 바로 X를 실행하는데 setTimeout(go, 100)이므로 바로 실행되지는 않고 1초후에 실행된다.

따라서 답은 AXB이다.

12 . 모든 setTimeout 콜백이 실행되고 난 후, 어떤 순서로 문자열이 콘솔에 찍히게 될까요?

console.log("A");

setTimeout(go(), 100);

setTimeout(function() {
  console.log("B");
}, 50);

function go () {
  console.log("X")
}

풀이)
setTimeout(go(), 100)에서는 go함수를 바로 실행한한다.

따라서 답은 AXB이다.

좋은 웹페이지 즐겨찾기