프론트엔드 개발자 면접 준비 (Javascript)

LUCAS·2021년 5월 13일
45

면접 대비 시리즈

목록 보기
3/3

본고에서는구글링을 통해 찾은 면접 문항 리스트들을 나열한다.
각 문항에 대한 답변은 내 머리에서 나오는대로 적는다.

브라우저의 렌더링 과정에 대해 설명해주세요.

  1. 사용자가 특정 페이지에 접속하여 HTML을 서버로부터 내려받으면, 브라우저의 렌더링 엔진에서는 이를 파싱한다.
  2. HTML 파싱을 진행하면서, DOM 트리를 만들게 되는데, 이 때 Link 태그를 만나 StyleSheet를 내려받게 될 경우 CSS 파싱을 통해 CSSOM 트리를 만들게 된다.
  3. 이 일련된 과정을 통해 둘을 결합하여 렌더 트리를 만들고, 레이아웃 작업을 통해 사용자에게 그려줄 영역을 계산한 뒤, 화면에 뿌려주게된다.
  4. 위 과정을 진행하면서 자바스크립트를 만나면, 자바스크립트 런타임 환경에 컨트롤(수행권한)을 넘겨 결과 값을 받는다.
    이 과정 중, DOM파싱은 중단된다.
  5. 생성된 DOM 노드의 레이아웃 수치(너비, 높이, 위치 등) 변경 시 영향 받은 모든 노드의 수치를 재계산하여, 렌더 트리를 재생성하는 과정을 Reflow 과정이라고하며, 이 과정이 끝난 후 재생성된 렌더 트리를 다시 그리게 되는데 이 과정을 Repaint라고 합니다.
  • reflow가 이루어졌다고 항상 repaint가 되는 것은 아니며, background-color, visibillty, outline 등 레이아웃 수치에 영향을 끼치지 않는 것은 repaint 과정만 진행됩니다.

호이스팅에 대해 설명해주세요.

  1. 함수 안에 있는 선언들을 모두 끌어올려서 해당 함수 유효 범위의 최상단에 선언하는 것을 말합니다.
  1. 호이스팅에는 함수 호이스팅과 변수 호이스팅이 있는데, 변수 호이스팅의 경우 각 변수 선언 키워드 마다 차이가 있습니다.
  1. 함수 호이스팅의 경우에는 함수 선언식을 통해 작성한 함수는 해당 함수의 내부 블럭까지 호이스팅되기 때문에 어디서든지 사용할 수 있으나, 함수 표현식의 경우에는 변수 호이스팅과 동일하게 동작하기 때문에 이 점을 유의하여 코드를 작성해야합니다.

이는 실행컨텍스트의 동작 방식을 통해 더 자세히 이해할 수 있습니다.

클로저는 무엇인가요? 원리와 사용하는 이유를 설명해주세요.

MDN를 통해 알 수 있듯이, 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경(Lexical environment)인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수입니다.

즉, 자신을 감싸고 있는 바깥 함수의 변수에 접근할 수 있는 내부의 함수를 모두 클로저라 일컫으며, 이러한 클로저의 사용을 통해 전역 변수의 사용을 억제할 수 있고, OOP의 장점 중 하나인 캡슐화가 가능캐함으로써 데이터의 은닉화가 가능합니다.

모든 함수는 각자의 실행 컨텍스트에 스코프 체인을 가지고 있는데, 외부 함수에 대한 실행이 종료되어도 스코프 체인은 유지된다는 원리를 통해 클로저의 구현이 가능해집니다. (스코프 체인을 통한 외부 함수의 실행 컨텍스트에 대한 객체 변수에 접근이 가능해짐)

this 용법을 아는대로 설명해주세요.

this는 '자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수' 입니다.

this는 함수의 호출 방식에 따라 특정 객체를 바인딩하게됩니다.

  1. 생성자 함수 내부에서 this는 생성자 함수가 생성할 인스턴스와 바인딩됩니다.
  2. Call, Apply, Bind 메소드 사용 시, 함수의 첫 번째 인수로 전달하는 객체에 바인딩됩니다.
  3. Object.method 형태와 같이 객체 내에서 호출할 경우, this는 해당 객체와 바인딩됩니다.
  4. 위 세 가지를 제외한 일반적인 함수 호출의 경우, this는 전역 객체와 바인딩됩니다.
  5. 마지막으로 ES6의 화살표 함수 내에서 this가 사용될 경우, this는 상위 스코프의 this와 바인딩됩니다.

브라우저 저장소에 대해 설명해주세요.

브라우저 저장소로는 쿠키가 있으며, HTML5를 통해 추가된 WebStorage(LocalStorage와 SessionStorage)가 있습니다.
HTML5를 통해 새롭게 추가되었다하더라도 기존의 쿠키가 쓰이지 않는 것은 아니며, 각 활용 특성에 따라 적절히 사용하면 좋습니다.

웹 애플리케이션에서 쿠키를 설정하면, 이후 모든 웹 요청은 쿠기정보를 포함하여 서버로 전송하게 되며, 새로이 추가된 WebStorage의 경우에는 클라이언트에만 존재할 뿐 서버로 전송되지 않습니다.
이는 네트워크 트래픽 비용을 줄여준다는 장점이 있습니다.

쿠키는 WebStorage와 다르게 단순 문자열만 저장할 수 있으며 용량에 제한이 있고, 저장된 데이터는 영구적이지 못합니다.
WebStorage는 LocalStorage와 SessionStorage가 있는데, LocalStorage는 데이터를 영구적으로 저장할 수 있으나, SessionStorage는 이름에서 알 수 있듯이 브라우저가 종료되면 데이터도 같이 지워지는 특성이 있다.

Restful API에 대해서 아는대로 설명해주세요.

REST란 HTTP URI를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미합니다.
API란 데이터와 기능의 집합을 제공함으로써 컴퓨터 프로그램간 상호작용을 촉진하며, 서로 정보를 교환 가능하도록 하는 것을 의미합니다.
따라서 RESTAPI란 REST를 기반으로 서비스 API를 구현한 것으로 설명할 수 있겠습니다.

CRUD Operation

  • Create: 생성(POST)
  • Read: 조회(GET)
  • Update: 수정(PUT)
  • DELETE: 삭제(DELETE)
  • HEAD: header 정보 조회(HEAD)

REST가 필요한 이유

기술의 발전으로 다양한 클라이언트가 등장하면서 자연스레 멀티 플렛폼의 지원을 위한 아키텍처가 필요해짐

REST의 장점

HTTP 프로토콜의 인프라를 그대로 사용하므로 REST API 사용을 위한 별도의 인프라를 구축할 필요가 없으며, HTTP 표준 프로토콜을 따르는 모든 플랫폼에서 사용이 가능하다.
서버와 클라이언트의 역할을 명확하게 분리할 수 있다.

REST의 단점

구형 브라우저의 경우 PUT, DELETE 메소드를 지원하지 않으며, 사용할 수 있는 HTTP Method의 형태가 제한적입니다.

Javascript는 어떤 언어인가요?

Javascript는 싱글 스레드 언어이므로, 단일 호출 스택이 있습니다.
단일 호출 스택이 있다는 뜻은 한 번에 하나의 일만 처리할 수 있다는 뜻입니다.
만일 브라우저에서 무거운 처리를 진행하려고 하면 단일 스레드로 인해 작업에 블로킹이 발생할 수 있습니다.
브라우저에서의 블로킹은 웹에 대한 기능 혹은 UI가 멈추는 것을 뜻합니다.
흔히들 말하는 먹통이 바로 주된 증상이 될 수 있겠습니다.

이러한 단점을 극복하기 위한 해결 방안이 바로 비동기 콜백입니다.
싱글 스레드 언어임에도 불구하고 웹사이트에서 여러 작업을 동시에 할 수 있는 것은 브라우저가 Web APIs 같은 것들을 제공하여 비동기 작업을 가능하게 해주기 때문입니다.

만일 함수를 동기 호출하게 되면 호출 스택에 차곡차곡 쌓여 순차적으로 실행되게 됩니다.
이때, AJAX나 setTimeout 혹은 DOM event 함수를 실행하면, Javascript 엔진은 호출 스택에서 Web APIs로 보내고 정해진 시간 혹은 이벤트가 발생한 순간에 순차적으로 Callback queue(Task Queue)에 적재합니다.
Callback queue에 적재된 함수들은 호출 스택에 쌓여있던 태스크들이 모두 처리될 경우, 차례대로 스택에 쌓여서 실행되게 됩니다.

이것에 대한 순환이 이벤트 루프(Event Loop)입니다.
자바스크립트에서는 이 것을 통해 동시성을 지원하게 해줍니다.
(물론 이는 동시에 일어나는 것이 아닌, 동시에 일어나는 것 처럼 보이게 하는 것임)

이벤트 버블링에 대해서 말씀해주세요.

이벤트 버블링은 특정 화면 요소에서 이벤트가 발생했을 때, 해당 이벤트가 더 상위의 화면 요소들로 전달되어가는 특성을 의미합니다.
이벤트 버블링은 이벤트 위임의 동작 메커니즘이라고 볼 수 있습니다.

Q: 이벤트 버블링은 기본적으로 child -> parent 인데 반대로 구현하는 방법은 무엇일까요?

반대로 구현하는 것을 보통 이벤트 캡쳐라고 합니다.
addEventListener의 옵션 객체에 capture: true 를 설정해주면 됩니다.

Q: 이벤트 버블링을 막기 위한 방법은 무엇일까요?

stopPropagation(); 웹 API를 사용하여 이벤트의 전파를 막을 수 있습니다.

Q: 이를 잘 활용하면 어떻게 사용할 수 있을까요?

이벤트가 발생한 요소는 상위의 요소들로 이벤트가 위임되는 특성을 활용해 TO-DO 리스트와 같이 체크박스가 일일히 추가되어야 하는 기능에서 체크박스의 상위 요소에 이벤트를 처리하게 함으로써 코드 량을 줄이고 유지보수 및 공수를 크게 절약할 수 있습니다.

타입스크립트에 대해서 사용해본 적이 있나요? 어땠나요?

타입스크립트는 기존의 자바스크립트에 정적 타입을 추가해 큰 프로젝트에서 여러가지 이 점을 부여할 수 있습니다.
IDE를 통해 각 함수 별 필요 인수를 한눈에 확인할 수 있으며, 변수와 함수의 인수 및 반환 데이터 등에 정적 타입을 지정해 코드가 옳바르지 못한 방향으로 구성되는 것을 사전에 방지합니다.
이러한 이 점은 코드량이 많아지는 거대한 프로젝트에서 유지보수성을 크게 높일 수 있다는 장점이 있으며, 저는 이러한 장점으로 타입스크립트는 선택이 아니라 필수라고 생각하고 있습니다.

Promise와 Callback의 차이점은 무엇이며 각각의 장단점에 대해서 설명해주세요.

둘 다 자바스크립트에서 비동기처리를 위해 사용되는 패턴입니다.
Callback 같은 경우 함수의 처리 순서를 보장하기 위해서 함수를 중첩되게 사용하는 경우가 발생해 콜백지옥이 발생한다는 단점과 에러 처리가 힘들다는 단점이 있습니다.

이러한 단점을 해결하기 위해 Promise가 ES6에서부터 정식 채택되어 사용되어지고 있다.

Async, Await가 무엇이며, Promise와의 차이점을 설명해주세요.

Promise를 더욱 쉽게 사용할 수 있도록 하는 ES8 문법입니다.
함수의 앞부분에 async 키워드를 추가하고 함수 내부에서 Promise의 앞부분에 await 키워드를 사용하면 됩니다.

async, await을 사용할 경우 Promsise ... then보다 코드가 간결해지며 에러 핸들링의 경우에는 try...catch를 사용해야합니다.
async가 사용된 함수는 promise를 반환하기 때문에 사용 시 유의해야합니다.

실행 컨텍스트에 대해 설명해주세요.

실행 컨텍스트 (execution context), ECMAScript Spec에는 아래와 같이 설명하고 있습니다.

  • 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념

제가 이해하고 있는 내용을 바탕으로 설명드리겠습니다.
자바스크립트 코드가 실행되면 실행 컨텍스트 스택에 GEC (전역 실행 컨텍스트, 이하 GEC)를 기반으로 해 컨트롤이 함수에 접근할 때 마다 각각의 EC (실행 컨텍스트, 이하 EC)를 추가하고 스택 순차대로 처리하게 됩니다.

실행 컨텍스트의 구조로는 세 가지로 요약할 수 있는데 아래와 같습니다.
1. VO (Variable Object, 전역 객체)
2. Scope Chain
3. this

VO의 경우에는 실행 컨텍스트 환경의 할당된 변수나 함수가 각각의 프로퍼티로써 저장되게 되며, EC의 경우 GEC와 상이하게 해당 함수의 인수가 키이고, 인자가 해당 프로퍼티의 값이 되는 프로퍼티를 추가적으로 갖게 됩니다.
이 때, var 키워드로 선언된 변수는 선언과 동시에 메모리에 할당되므로, 호이스팅의 원리를 설명할 수 있게 됩니다.
함수의 경우에는 선언문의 경우 해당 함수 객체를 프로퍼티의 값으로써 갖고 있을 수 있게되어 함수 표현식과 달리 함수호이스팅을 통한 함수 접근이 가능하게 됩니다.

Scope Chain의 경우에는 자신을 포함해 외부 함수와 최상위인 GEC까지의 VO에 접근할 수 있도록 배열 형태로 보관하게 됩니다.
이 때, 외부 함수가 실행이 종료되어도 Scope Chaining을 통해 접근이 가능하다는 특성을 사용해 클로저라는 원리를 설명할 수 있게됩니다. (Lexical Scope 접근)

this는 해당 함수가 호출되는 형태에 따라 값이 다르게 바인딩되며 GEC에서 this 항상 전역 객체 자신입니다. (Brower의 경우 Window, Nodejs의 경우 Global)

자바스크립트를 최적화하는 방법을 설명해주세요.

자바스크립트는 High-Level 프로그래밍 언어입니다.

우리가 자바스크립트를 통해 변수나 객체, 배열 등을 선언하고 할당하게 되면, 자바스크립트는 자동으로 운영체제에 해당 데이터에 대한 메모리를 할당해줍니다.

이는 C언어와 같은 Low-Level 프로그래밍 언어와 다르게 직접 메모리를 할당해줄 필요가 없어 메모리에 대한 부분은 개발자가 신경쓸 부분이 아니라고 오해할 수 있게 되는데, 이는 옳지 못한 생각입니다.

자바스크립트는 가비지 컬렉션(Garbage Collection)을 사용해 더 이상 참조되지 않는 변수 등의 데이터의 메모리 할당을 릴리즈해줌으로써, 자바스크립트가 최적의 성능을 보장받을 수 있도록 해주는데, 다음과 같은 여러가지 문제들로 인해 가비지 컬렉션이 실질적으로 참조되지 않으나 메모리를 릴리즈해주지 못하는 이른바 메모리 누수(Memory Leaks) 현상이 발생할 수 있습니다.

  1. 전역 변수로 인한 메모리 누수
  • 전역 변수는 가비지 컬렉션이 불가능한 영역입니다.
  1. 잊혀진 타이머 혹은 콜백함수로 인한 메모리 누수
  • 특정 요소를 참조하는 콜백함수를 일정 주기로 실행하는 WebApis의 setInterval 함수가 돌고 있다고 가정해볼 때, 더이상 사용하지 않아 명시적으로 반복되는 setInterval을 Clear해주지 않는 한 계속 동작하게 될겁니다.
  1. 클로저
  • 자바스크립트 런타임 구현의 특성상 클로저도 메모리누수를 일으키는 것이 가능합니다.
  • 최신 자바스크립트 엔진은 1 depths 클로저에 한해 gc가 동작하지만 2depths 부터는 동작하지 않습니다. [자세한건 여기서]
  1. DOM
  • DOM노드를 객체의 데이터로 저장하는 경우, 해당 데이터 구조에서 DOM 노드를 참조하지 못하게끔 해야 gc를 통한 메모리 릴리즈가 가능합니다.

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

우선 자바스크립트는 클래스라는 개념이 없습니다.
자바스크립트는 기존의 객체를 복사하여 새로운 객체를 생성하는 프로토타입 기반의 언어입니다.

자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있습니다.
그리고 이 것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메소드를 상속받아 사용할 수 있게 합니다.
이러한 부모 객체를 Prototype(프로토타입) 객체 또는 줄여서 Prototype(프로토타입)이라 합니다.

프로토타입 객체는 생성자 함수에 의해 생성된 각각의 객체에 공유 프로퍼티를 제공하기 위해 사용합니다.

__proto__ 접근자 프로퍼티로 자신의 프로토타입, 즉 Prototype 내부슬롯에 접근할 수 있습니다.

프로토타입 체인이 무엇인가요?

객체의 프로퍼티에 접근하려고 할 때, 객체에 접근하려는 프로퍼티가 없으면 __proto__ 접근자 프로퍼티가 가리키는 링크를 따라 자신의 부모역할을 하는 프로토타입의 프로퍼티를 순차적으로 검색하는 것을 말합니다.
프로토타입의 최상위 객체는 Object.protype으로, 이 객체의 프로퍼티와 메소드는 모든 객체에 상속됩니다.

HTML Body 최하단에 <Script> 태그를 두어야 하는 이유가 있을까요?

Script 태그를 처리할 때에는 DOM 파싱이 중단됨으로 사용자에게 화면이 늦게 그려질 수 있습니다.
따라서, 최하단에 둠으로써, 모든 DOM 노드가 그려진 뒤 Javascript를 수행될 수 있도록 최하단에 두는 것이 일반적으로 좋습니다.

Interface와 Type의 차이는 무엇일까요?

Type aliases는 Interface 처럼 동작합니다.
다만 미묘한 차이가 몇가지 있습니다.

  1. interface는 여러곳에서 사용되는 새로운 이름을 만들지만, type aliases는 새로운 이름을 만들지 않습니다.
    이로인해 타입에 오류가 발생하면, type aliases는 실제 타입을 보여주나 interface는 생성한 인터페이스에 문제가 있다고 알려준다.

  2. 그 외로 과거에는 type aliases에 대한 확장이 불가능했지만 지금은확장이 가능해졌다.

Mutable과 Immutable을 설명하세요.

Mutable은 바뀔 수 있는 변수 타입을 말하며, Immutable은 이와 반대되는 개념입니다.
Javascript에서는 Object와 Array만 Mutable한 타입이고, 다른 원시 타입의 경우 Immutable하다고 볼 수 있습니다.

Throttle과 Debounce의 차이를 설명하세요.

이 두가지는 DOM 이벤트를 기반으로 실행하는 자바스크립트를 성능상의 이유로 JS의 양적인 측면, 즉 이벤트를 제한하는 방법입니다.
스크롤 이벤트와 같이, 이벤트가 많이 발생하는 경우에 대해 적용하어 사용되는 것이 보편적입니다.

  1. Throttle은 이벤트를 일정한 주기마다 발생하도록 하는 기술입니다.
  2. Debounce는 이벤트를 그룹화하여, 특정시간이 지난 후 하나의 이벤트만 발생하도록 하는 기술입니다.

requestAnimationFrame이 무엇인가요?

window.requestAnimationFrame()은 브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출하게 합니다.
이 메소드는 리페인트 이전에 실행할 콜백을 인자로 받습니다.
이 메소드의 사용을 위해서는 다른 비동기 함수인 setInterval과 다르게 재귀적으로 호출해야합니다.

Iterator과 Generator을 설명해주세요.

Iterator은 반복을 위해 설계된 특정 인터페이스가 있는 객체입니다.
모든 Iterator 객체는 결과 객체를 반환하는 next() 메서드를 가지고 있습니다.
결과 객체에는 두 가지 프로퍼티, 즉 다음 값인 value와 반환한 값이 더 이상 없을 때 true인 부울 값인 done 프로퍼티입니다.
Iterator은 값 컬렉션 내의 위치에 대한 내부 포인터를 유지하고 next() 메서드를 호출할 때마다 다음 적절한 값을 반환합니다.

Generator은 Iterator를 반환하는 함수입니다.
ES6에서 제너레이터 함수가 도입되어 함수선언식의 함수명 앞에 별표(*)를 붙여 사용할 수 있습니다.
또한 next() 메서드를 호출할 때마다 반환할 값은 yield 키워드를 사용해 지정할 수 있습니다.

OOP을 설명해주세요.

OOP란 Object Oriented Programming, 즉 객체지향프로그래밍을 말합니다.
객체지향프로그래밍이란 객체들이 유기적으로 동작하는 프로그래밍 이론을 말하며,
객체지향프로그래밍을 하는 주요 장점으로는 코드 재사용 및 중복 제거등이 있습니다.

그 외에도 OOP는 4가지 특성이 있는데

첫 번째는 다형성, 선언되어있는 하나의 메소드를 오버라이딩하여 여러가지의 기능으로 동작시킬 수 있는 것.
두 번째는 캡슐화, 데이터와 데이터 구조를 묶음으로써 외부에 데이터를 노출시키지않는 데이터 은닉화가 가능하다는 것.
세 번째는 상속, 상속관계에 있는 두 클래스에서 자식 클래스가 부모 클래스의 메소드를 상속받아 사용함으로써 코드의 재사용이 가능하는 것.
마지막으로 추상화, 클래스에 대해 공통 속성이나 기능을 묶어 이름을 붙여서 객체지향관점으로 봤을 때 추상화가 가능하다는 점 입니다.

FP를 설명해주세요.

FP란 Functional Programming, 즉 함수 프로그래밍을 말합니다.

FP는 순수함수로 이루어져있는 프로그래밍 방식을 말하며 순수함수란 사이드이펙트가 없는, 즉.
항상 동일한 인풋에 동일한 아웃풋이 나오는 함수를 말합니다.

이러한 함수의 조합과같은 합성함수나, Point-free, 재귀함수의 사용 등 함수형 프로그래밍 방식을 사용해 코드를 구성하는 것을 말합니다.

OOP와의 차이점으로는 OOP는 각각에 대한 상태를 메소드로 변경하고 관리하지만 FP에서는 순수함수의 조합으로 상태 개념과 다르게 처리합니다. 흔히 말하는 공유 상태가 없어야한다는 것이 FP의 특징 중 하나입니다.
공유 상태가 없어야 되다는 뜻은 두 함수가 동작한다는 관점에서 봤을 때 두 함수가 외부의 상태로 인한 처리결과 값이 상이해서는 안된다는 특징을 지닙니다.

TODO: 리액트 렌더링 (diffing) -> 요거 -> 시간복잡도
https://meetup.toast.com/posts/110
https://velog.io/@ansrjsdn/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%A9%B4%EC%A0%91-%EC%A7%88%EB%AC%B8-%EC%A0%95%EB%A6%AC
https://velog.io/@suyeonme/JavascriptOOP

profile
안녕하세요! FE개발자 최근원입니다.

2개의 댓글

감사합니다 도움이 많이되었습니다

1개의 답글