220521 스터디 준비

백규현·2022년 5월 21일
0

[JS]

이벤트 루프에 관하여 설명해주세요.

Callback Event Queue에서 하나씩 꺼내서 동작시키는 루프를 말한다.
자바스크립트는 싱글 스레드 기반 언어이기 때문에, 한번에 하나씩 작업을 진행한다.
자바스크립트는 이벤트 루프를 이용해서 비동기 방식으로 동시성을 지원한다.

동시성에 대한 처리는 자바스크립트 엔진을 구동하는 환경, 즉 브라우저나 Node.js가 담당한다.

비동기 호출을 위해 사용하는 함수들은 Web API영역에 따로 정의되어있고,
이벤트 루프와 테스크 큐 같은 장치도 자바스크립트 엔진 외부에 구현되어 있다.

자바스크립트가 '단일 스레드' 기반 언어라는 말은 '자바스크립트 엔진이 단일 호출 스택을 사용한다' 라는 관점에서만 사실이다.
자바스크립트가 구동되는 환경에서는 주로 여러 개의 스레드가 사용되며, 이런 구동 환경이 단일 호출 스택을 사용하는 자바 스크립트 엔진과 상호 연동하기 위해 사용하는 장치가 '이벤트 루프'인 것이다.

Run to Completion : 자바스크립트의 함수가 실행되는 방식으로, 하나의 함수가 실행되면 이 함수의 실행이 끝날 때까지는 다른 어떤 작업도 중간에 끼어들지 못한다는 의미이다.

태스크 큐는 콜백 함수들이 대기하는 Queue 형태의 배열이라 할 수 있고,
이벤트 루프는 호출 스택이 비워질 때 마다 큐에서 콜백 함수를 꺼내와서 실행하는 역할을 해준다.

* 모든 비동기 API들은 작업이 완료되면 콜백함수를 태스크 큐에 추가한다.
* 이벤트 루프는 호출 스택이 비워졌을 때 태스크 큐의 첫 번째 태스크를 꺼내와 실행한다.

참고 문서 / 참고 영상


콜백 지옥이 무엇인지 설명해주세요. 또 어떻게 해결할 수 있나요?

콜백 지옥이란 콜백 함수를 익명 함수로 전달하는 과정에서 또 다시 콜백 안에 함수 호출이 반복되어 코드의 가독성이 떨어지는 현상을 말합니다.

해결법 1 : Promise

자바스크립트 비동기 처리에 사용되는 객체로 ES6에서 추가되었다.

프로미스의 구조

new Promise(function(resolve, reject) {
  // ...
});

프로미스는 3가지 상태가 있다.

  • Pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태 (resolve 나 reject가 호출되기 전)
  • Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태
    resolve를 실행하면 Fullfilled 상태가 된다. 이후 then을 이요하여 처리 결과 값을 받을 수 있다.
  • Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태
    reject를 실행하면 rejected 상태가 된다. 이후 실패한 이유를 Catch로 받을 수 있다.

에러를 잡는방식으로 reject를 사용하는 방식, catch를 사용하는 방식 2가지가 있는데, 보통 catch를 사용한다. reject를 사용하면 then에서 발생하는 에러를 잡지 못하기 때문이다.

Promise는 Promise를 반환하기 때문에 다음 작업을 체이닝 하여 작성할 수 있다.
그렇기 때문에 콜백지옥을 해결 할 수 있다.

해결법 2 : async await

async function f() {

  let promise = new Promise((resolve, reject) => {
    setTimeout(() => resolve("완료!"), 1000)
  });

  let result = await promise; // 프라미스가 이행될 때까지 기다림 (*)

  alert(result); // "완료!"
}

f();

async는 function 앞에 붙여서 활용한다.
function 앞에 async를 붙이면 해당 함수는 항상 Promise를 반환한다. Promise가 아닌 값을 반환하더라도 resolved Promise로 값을 감싸 반환한다.

await은 Promise가 처리될 때까지 기다린다.
Promise가 처리되면 그 결과와 함께 실행이 재개된다.
Promise 보다 가독성이 좋기 때문에 자주 사용된다.


이벤트 버블링, 캡쳐, 위임을 설명해주세요.

<body>
	<div class="one">
		<div class="two">
			<div class="three">
			</div>
		</div>
	</div>
</body>
var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
	div.addEventListener('click', logEvent);
});

function logEvent(event) {
	console.log(event.currentTarget.className);
}

이벤트 버블링
특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 특성을 의미한다.
위의 코드에서 <div class="three"></div> 를 클릭하게 된다면
three
two
one
순서로 찍히게 된다.

var divs = document.querySelectorAll('div');
divs.forEach(function(div) {
	div.addEventListener('click', logEvent, {
		capture: true // default 값은 false입니다.
	});
});

function logEvent(event) {
	console.log(event.currentTarget.className);
}

이벤트 캡쳐
위위 코드와 위 코드의 차이점은 {capture: true} 가 있다는 점이다. 해당 옵션으로 인해 이벤트 버블링과는 반대로 최상위 요소인 body 태그부터 해당 태그까지 찾아 내려간다.
그렇기 때문에 <div class="three"></div> 를 클릭하게 된다면
one
two
three
순서로 찍히게 된다.

이벤트 버블링 혹은 캡쳐를 막고 싶다면 콜백함수안에서 event.stopPropagation() 라는 웹 API를 사용하면 된다. 만약 예제에 있는 logEvent에서 사용했다면
버블링에서는 three, 캡쳐링에서는 one만 출력된다.

이벤트 위임

<ul class="itemList">
	<li>
		<input type="checkbox" id="item1">
		<label for="item1">이벤트 버블링 학습</label>
	</li>
	<li>
		<input type="checkbox" id="item2">
		<label for="item2">이벤트 캡쳐 학습</label>
	</li>
</ul>
var inputs = document.querySelectorAll('input');
inputs.forEach(function(input) {
	input.addEventListener('click', function(event) {
		alert('clicked');
	});
});

만약 다음과 같이 input태그에 이벤트 리스너를 추가한다면 위 2개의 input 태그에서는 정상적으로 작동할 것이다.
하지만 이벤트 리스너가 추가된 이후 동적으로 새로운 리스트 아이템이 추가된다면 새로 추가된 input 태그에는 이벤트 리스너가 등록되어 있지 않다.

이를 해결하기 위해

var itemList = document.querySelector('.itemList');
itemList.addEventListener('click', function(event) {
	alert('clicked');
});

다음과 같이 리스트 아이템의 상위 태그인 ul 태그에 이벤트 리스너를 추가하게 된다면, 이벤트 버블링에 의해서 동적으로 추가된 리스트 아이템들도 이벤트를 감지할 수 있게 된다.
출처 : 이벤트 버블링, 이벤트 캡처 그리고 이벤트 위임까지


프로토타입이 무엇인지 설명해주세요.

출처

프로토타입 != 클래스의 상속 -> js에서는 클래스가 없기 때문.
js에서는 복사를 통한 상속 또한 존재하지 않는다. -> JS는 객체자체를 복사하거나 코드 내용을 복사하는 등의 깊은복사를 수행할 수 없기 때문이다. JS에서는 원시값,객체의 참조값 만이 복사할 수 있다.
prototype은 클래스, 객체의 내용 복사 없이도 상속을 구현할 수 있게 해주는 방법이다.
prototype은 연결이다.

new 연산자와 함수를 사용하면 새로운 빈 객체를 메모리 상에 생성함.
생성된 빈 객체가 this에 바인딩 된다.
함수안에 return이 없다면 이 this가 리턴된다.

.__proto__ : 객체와 객체를 연결하는 링크

  • 객체는 자신의 원형이라고 할 수 있는 객체가 있다면 그 객체를 가리키는 __proto__링크를 자동으로 가짐.

  • 함수의 경우, 함수가 만들어 질때 함수의 프로토타입 객체도 같이 만들어진다. 이후 그림처럼 순환참조 관계를 가진다.

  • new + 함수로 만들어진 객체라면 만들어진 새로운 객체의 __proto__링크가 Person 객체의 프로토타입 객체를 가리키게 된다.

프로토타입 체이닝 (Prototype Chaining)



만약 진짜 존재하지 않는 경우, Object의 프로토타입 객체까지 찾아가는데 Object의 프로토타입 은 null이기 때문에 탐색을 종료하고, undefined를 리턴한다.

프로퍼티 할당


이 상황에서 chiris객체에 sayHello가 추가될까?
Person.prototype.sayHello 가 덮어씌워질까?
(읽기전용은 Object.defineProperty 로 설정할 수 있다.)
-> sayHello가 읽기전용 메소드인 경우, JS가 엄격모드라면 에러가 발생하고, 비 엄격 모드라면 아무일도 일어나지 않는다
-> 읽기 전용이 아니라면 chris.sayHello 가 추가된다. 하지만 이렇게 된다면 정상적인 접근으로는 기존의 sayHello에 접근할 수 없다. 이 현상을 오바라이딩이 아닌 가려짐 이라고 표현한다.

프로토타입 응용예시



타입스크립트가 자바스크립트랑 비교했을때 가지는 장,단점을 설명해주세요.

타입스크립트는 자바스크립트로 컴파일 된 후 실행된다. 그렇기 때문에 자바스크립트에 의존적이고, 컴파일 언어이다.

장점 :

  • 타입스크립트는 정적타입을 사용하기 때문에 타입 관련 에러를 컴파일 과정에서 막을 수 있다.
  • 함수의 매개변수로 들어오는 값의 타입이 무엇인지 알기 위해 따로 찾아 볼 필요 없다.
  • 컴파일 과정에서 Babel의 도움 없이 문법을 변환해주기 때문에 크로스 브라우징 문제를 해결 할 수 있다. (크로스 브라우징 : 브라우저 간 호환이 안되는 문제)

단점 :

  • 컴파일을 하는 시간이 들기 때문에 상대적으로 속도가 차이난다.
  • 매번 타입을 결정해주어야 한다.

[WEB]

cdn이 무엇인지, 장단점을 설명해주세요.

Content Delivery Network 은 지리적 제약 없이 전 세계 사용자에게 빠르고 안전하게 콘텐츠를 전송할 수 있는 콘텐츠 전송 기술을 말한다.
CDN은 서버와 사용자 사이의 물리적인 거리를 줄여 콘텐츠 로딩에 소요되는 시간을 최소화한다.
각 지역에 캐시 서버(edge)를 분산 배치해, 근접한 사용자의 요청에 원본 서버가 아닌 캐시 서버가 콘텐츠를 전달한다.
보통 이미지, 동영상, 미디어, CSS, JS 같은 정적 파일을 호스팅한다.

장점 :

  • 사용자의 지역에 맞춰 빠른 다운로드 시간을 제공한다.
  • 부하를 분산하고 대역폭을 절약할 수 있다. 호스트 비용이 절감된다.
  • JQuery 같이 많은 사이트에서 사용되는 컨텐츠의 경우 이미 CDN 서비스를 사용하는 다른 사이트에서 방문했을 확률이 높다. 그렇다면 파일은 이미 브라우저에 캐싱되어 다시 다운로드 할 필요가 없다.
  • DDos 공격을 완화 할 수 있다.

단점 :

  • 특정지역에서 접근불가 할 수 있다.
  • 특정 국가나 지역만을 타깃으로 하는 웹 서비스를 운영한다면 오히려 불필요한 연결지점이 늘어나 웹 사이트의 성능 저하를 불러올 수 있다.

Node.JS가 무엇인지 설명해주세요.

  • Chrome V8 엔진으로 빌드 된 JS 런타임 환경이다. 그렇기 때문에 언어가 아닌 환경이다.
  • JS를 웹 브라우저에서 독립시킨 것으로 Node.js를 설치하게 되면 터미널에서 실행할 수 있다.
  • 기본적으로 싱글 스레드, 논 블로킹 모델을 사용하므로 I/O 요청이 많이 발생하면 노드를 서버로 사용하는 것 이 좋다. 하지만 CPU 부하가 큰 작업에는 적합하지 않다.
  • 그러므로 개수는 많지만 크기는 작은 데이터를 실시간으로 주고받는데 적합한다. 예를 들어 네트워크,DB,디스크 작업 같은 I/O에 특화되어 있다.
  • 웹 서버가 내장되어 있어 별도의 웹 서버를 설치할 필요없다.

[DB]

B-tree,B+tree가 무엇인지 그리고 DB index와 연관지어 설명해주세요.

B-tree

자식 노드의 개수가 2개 이상인 트리를 말한다. 또 노드내의 데이터가 1개 이상일 수 있다.
노드 내 최대 데이터 수가 n개 라면 n차 B-Tree라고 말한다.
노드들이 한쪽으로 치우쳐 연결리스트의 형태가 되는 것을 방지하여 검색 효율을 높인다.
어느 한 데이터의 검색은 효율적이지만, 모든 데이터를 한번 순회하는데에는 트리의 모든 노드를 방문해야 하므로 비효율적이다.

성립조건 :

  • 노드의 데이터 수가 n개라면 자식 노드의 개수는 n+1개이다.
  • 노드의 데이터는 반드시 정렬된 상태이다.
  • 노드의 자식노드의 데이터들은 노드 데이터를 기준으로 데이터보다 작은 값은 왼쪽 서브 트리에, 큰 값은 오른쪽 서브 트리에 배치된다.
  • Root노드가 자식이 있다면 2개 이상의 자식을 가져야 한다.

자세한 개념

B+Tree

오직 리프 노드에만 데이터를 저장하고 리프노드가 아닌 노드에서는 자식 포인터만 저장한다.
리프노드끼리는 LinkedList로 연결되어 있다.
중간 노드에서 키가 중복될 수 있다.

장점
리프 노드를 제외하고 데이터를 저장하기 않기 때문에 메모리를 더 확보할 수 있다.
Full Scan을 하는 경우 B+Tree는 리프노드에만 데이터가 저장되어 있고, 리프 노드끼리 연결되어 있기 때문에 선형 시간이 소모된다. 반면 B-Tree는 모든 노드를 확인해야 한다.
인덱스 컬럼은 부등호를 이요한 순차 검색 연산이 자주 발생하는데, B-Tree나 Hash Table에 비해 훨씬 성능이 좋다.


[기타]

머신러닝 혹은 빅데이터에 경험이 있는지, 있다면 경험을 설명해주시고 없다면 어떤 분야에 관심이 있는지 말해주세요. 또 그 분야를 어떻게 이용할 수 있을 지 설명해주세요.

[추가적으로 공부할만한 키워드]

  • Object.create
  • Object.defineProperty
  • JS 엄격모드
profile
반갑습니다.

0개의 댓글