프론트엔드 면접 질문 정리


브라우저


1. 브라우저 동작원리

1) 브라우저는 HTML, CSS, 자바스크립트, 이미지, 폰트 파일 등 렌더링에 필요한 리소스를 요청하고 서버로부터 응답을 받습니다.

2) 브라우저의 렌더링 엔진은 서버로부터 응답된 HTML과 CSS를 파싱하여 DOM과 CSSOM을 생성하고 이들을 결합하여 렌더 트리를 생성합니다.

3) 브라우저의 자바스크립트 엔진은 서버로부터 응답된 자바스크립트를 파싱하여 AST를 생성하고 바이트코드로 변환하여 실행합니다. 이때 자바스크립트는 DOM API를 통해 DOM이나 CSSOM을 변경할 수 있습니다. 변경된 DOM과 CSSOM은 다시 렌더 트리로 결합됩니다. (리플로우 및 리페인트가 발생합니다)

4) 렌더 트리를 기반으로 HTML 요소의 레이아웃(위치와 크기)을 계산하고 브라우저 화면에 HTML 요소를 페인팅 합니다.



2. 브라우저 최적화

1) CSS는 <head> 바로 아래에 작성합니다. CSSOM이 만들어지지 않으면 렌더링을 진행할 수 없으므로 브라우저가 빨리 CSSOM을 생성할 수 있도록 합니다.

2) script 로드 시 async, defer 속성을 활용합니다.

3) requestAnimationFrame을 통해 애니메이션 최적화를 합니다.


디바운스란?
짧은 시간 간격으로 이벤트가 연속해서 발생하면 이벤트 핸들러를 호출하지 않다가 일정시간이 경과한 이후에 이벤트 핸들러를 한 번만 호출되도록 한다. 즉, 디바운스는 짧은 시간 간격으로 발생하는 이벤트를 그룹화해서 마지막에 한 번만 이벤트 핸들러가 호출되도록 한다.


쓰로틀이란?
짧은 시간 간격으로 이벤트가 연속해서 발생하더라도 일정 시간 간격으로 이벤트 핸들러가 최대 한 번만 호출되도록 한다. 즉, 쓰로틀은 짧은 시간 간격으로 이벤트가 연속해서 발생하더라도 일정 시간 간격으로 이벤트 핸들러가 최대 한 번만 호출되도록 한다. 즉, 스로틀은 짧은 시간 간격으로 연속해서 발생하는 이벤트를 그룹화해서 일정 시간 단위로 이벤트 핸들러가 호출되도록 호출 주기를 만든다.


4) 공백과 주석을 없애 압축합니다.

5) 이미지를 적게, 작게 씁니다.

6) 이미지를 디바이스의 크기에 따라 다운받도록 합니다. (반응형 최적화)

7) 리플로우, 리페인트를 최소화 시킵니다.


제일 중요한 결론은,

1) 다운 받을 중요한 리소스들의 수를 최소화 시킵니다.

2) 파일 사이즈와 요청 횟수를 최소화 시킵니다.

3) 중요 리소스의 다운로드 우선 순위를 지정하여 중요 리소스가 로드되는 순서를 최적화하고 CRP 길이를 최대한 줄입니다.


참고자료 :



3. 크로스 브라우징

웹 페이지 제작 시에 모든 브라우저에서 깨지지 않고 의도한 대로 올바르게(호환성) 나오게 하는 작업을 말합니다.
브라우저마다 렌더링 엔진이 다르기 때문에 크로스 브라우징이 필요합니다.


참고자료 :



4. CORS 및 CORS 판정 로직

CORS(Cross-Origin Resource Sharing)는 브라우저가 자원을 표시할 때 자신의 Origin이 아닌 다른 Origin의 자원을 표시하기 위해 다른 Origin의 자원을 갖고 있는 서버에게 자원을 표시해도 되는지 여부를 판단하는 HTTP 헤더기반 메커니즘입니다.


4.1 Simple requests

Simple requests는 CORS preflight를 사용하지 않습니다.
특정 조건을 만족했을 때 Simple Requests를 사용할 수 있습니다.


1) Method는 GET, HEAD, POST만 사용합니다.

2) User agent로부터 자동으로 세팅된 헤더를 제외하고 수동으로 설정할 수 있는 헤더는 Accept, Accept-Language, Content-Language, Content-Type 뿐입니다.

3) Content-Type에 할당될 수 있는 값은 application/x-www-form-urlencoded, multipart/form-data, text/plain 뿐입니다.

4) 만약 XMLHttpRequest로 요청한다면, XMLHttpRequest.upload 속성에 어떤 이벤트 리스너도 등록되지 않아야 합니다.

5) 요청에 ReadableStraeam 객체를 사용하지 않습니다.


요청 헤더에 Origin으로 본인 Origin을 넣고 요청을 보내면, 서버 응답 헤더에 Access-Control-Allow-Origin에 허용여부에 대한 값이 존재하게 됩니다.


4.2. Preflighted requests

Simple requests와 다르게 preflighted requests는 OPTIONS method를 이용하여 HTTP 요청을 보냅니다.
보낼 요청이 안전한지 확인하기 위함입니다.
OPTIONS method에는 Access-Control-Request-Method, Access-Control-Request-Headers 정보를 넣어 해당 요청이 안전한 지 서버에게 확인 요청합니다.
서버는 OPTIONS에 대한 응답으로 Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Max-Age 정보를 줍니다.
이렇게 준 정보들만 요청으로 허용하겠다란 의미입니다.


참고자료 :



5. 언제 document.write()를 사용하나요?



6. JSONP가 어떻게 동작하나요? Ajax와는 어떻게 다르나요?





네트워크


1. HTTP 프로토콜이란

HTTP는 HTML 문서와 같은 리소스들을 가져올 수 있도록 해주는 프로토콜입니다.
HTTP는 웹에서 이루어지는 모든 데이터 교환의 기초이며, 클라이언트-서버 프로토콜이기도 합니다.
클라이언트-서버 프로토콜이란 (보통 웹브라우저인) 수신자 측에 의해 요청이 초기화되는 프로토콜을 의미합니다.


1) HTTP은 간단합니다

2) HTTP은 확장 가능합니다

3) HTTP은 상태가 없지만, 세션은 있습니다

4) HTTP와 연결

5) HTTP 흐름

HTTP는 사용이 쉬운 확장 가능한 프로토콜입니다.
헤더를 쉽게 추가하는 능력을 지닌 클라이언트-서버 구조는 HTTP가 웹의 확장된 수용력과 함께 발전할 수 있게 합니다.


참고자료 :



2. http와 https 차이

1) http와 달리 https는 데이터를 암호화시켜 브라우저와 서버가 데이터를 주고 받을 때 데이터가 도난 당해도 정보가 노출되지 않도록 합니다. HTTP의 일반 텍스트에 SSL이나 TLS 프로토콜을 씌워 데이터를 암호화합니다.

2) 검색엔진 최적화(SEO)에 있어서도 큰 혜택을 줍니다. 구글이 https 구축된 사이트에 가산점을 주며, 사용자들 또한 https가 http보다 안전하다는 것을 알기에 해당 사이트를 더 많이 방문하게 됩니다.

3) 가속화된 모바일 페이지(AMP, Accerlerated Mobile Pages)를 만들 때 https 프로토콜을 사용해야만 합니다.


참고자료 :



3. https 동작 원리

https는 대칭키와 공개키(비대칭키) 방식을 전부 사용하는 하이브리드 방식 입니다.
데이터 전송을 위해 대칭키 방식을 사용하며 대칭키를 안전하게 전달하기 위해 공개키 방식을 사용합니다.


1) Client Hello 단계

2) Server Hello 단계

3) Client 인증 단계

4) Server 인증 단계

5) 악수(Handshake) 종료

6) 데이터 전송

7) 세션 종료


참고자료 :



4. http1.1과 2.0의 차이

HTTP/1.1은 기본적으로 커넥션당 하나의 요청과 응답만 처리합니다.
즉, 여러 개의 요청을 한 번에 전송할 수 없고 응답 또한 마찬가지입니다.
따라서 HTML 문서 내에 포함된 여러 개의 리소스 요청, 즉, CSS 파일을 로드하는 link 태그, 이미지 파일을 로드하는 img 태그, 자바스크립트를 로드하는 script 태그 등에 의한 리소스 요청이 개별적으로 전송되고 응답 또한 개별적으로 전송됩니다.
이처럼 HTTP/1.1은 리소스의 동시 전송이 불가능한 구조이므로 요청할 리소스의 개수에 비례하여 응답 시간도 증가하는 단점이 있습니다.

이처럼 HTTP/1.1은 다중 요청/응답이 불가하다는 단점이 있지만 HTTP/2는 커넥션당 여러 개의 요청과 응답, 즉 다중 요청/응답이 가능합니다.
따라서 HTTP/2.0은 여러 리소스의 동시 전송이 가능하므로 HTTP/1.1에 비해 페이지 로드 속도가 약 50% 정도 빠르다고 알려져 있습니다.

HTTP2는 성능 뿐만 아니라 속도면에서도 월등한 녀석입니다.

위 기능을 사용하여 성능을 획기적으로 향상 시켰습니다.


참고자료 :



5. TCP/IP란?

인터넷으로 통신하는데 가장 기반이 되는 프로토콜입니다.
IP는 Internet Protocol의 약자로써 네트워크 상에서 다른 컴퓨터와 구별할 수 있도록 할당되는 주소입니다.
이 주소를 통해 패킷이라는 단위로 데이터를 전송합니다.
하지만 이 IP만을 이용해서 통신을 하면 신뢰성과 연결성을 보장하지 못합니다. (1 2 3을 보냈으나 3 2 1 순서로 받았을 경우)
이를 위해 TCP를 사용합니다.
TCP는 Transmission Control Protocol의 약자로써 전송제어 프로토콜 정도로 번역할 수 있습니다.
TCP는 IP와 함께 쓰이며 데이터의 누락, 순서 등 신뢰성과 속도를 보장하기 위해 사용됩니다.
TCP는 UDP와 달리 연결지향 프로토콜이며 서버와 클라이언트가 통신하는 동안 연결을 맺고 있는 상태를 유지합니다. 연결을 위해 3 ways handshake를 사용하며, 해제를 위해 4ways handshake를 사용합니다.


네트워크 4계층을 보면(네트워크 인터페이스 > IP > TCP > HTTP) HTTP는 TCP 위에서 동작합니다.
때문에 HTTP 연결의 시작과 끝은 TCP 연결과 해제가 이루어져야 합니다.


참고자료 :



소프트웨어 개발론


1. OOP 특징

프로그램을 명령어의 목록이 아닌 독립된 객체들의 모임으로 바라봅니다.


1) 추상화 (Abstraction)

2) 캡슐화 (Encapsulation)

3) 상속성 (Inheritance)

4) 다형성 (Polymorphism)


참고자료 :


2. 함수형 프로그래밍이란?

순수 함수를 조합하여 소프트웨어를 만드는 프로그래밍입니다.
대표적인 언어로는 클로저, 하스켈, 리스프가 있습니다.
클린 코드에서는 대입문이 없는 프로그램이라고 정의합니다.

부수 효과가 없는 순수 함수를 1급 객체로 간주하여 파라미터로 넘기거나 반환값으로 사용할 수 있으며 참조 투명성을 지킬 수 있습니다.

부수효과란?
변수의 값이 변경되거나 객체의 필드 값을 설정하거나, 에외나 오류로 실행이 중단되거나 콘솔 or 파일 I/O가 발생하는 것들 입니다.

참조 투명성이란?
동일한 인자에 대해 항상 동일한 결과를 반환해야 하는 것을 의미하고, 참조 투명성을 통해 기존의 값은 변경되지 않고 유지되는 것을 의미합니다. (Immutable Data)


참고자료 :
https://mangkyu.tistory.com/111



3. 순수 함수란?

부수효과들을 제거한 함수를 순수함수라고 합니다.


순수 함수를 이용하면 다음과 같은 효과를 얻습니다.



4. 일급 객체란?

다음 4가지 조건을 만족할 때 일급 객체라고 합니다.

1) 무명의 리터럴로 생성할 수 있다. 즉, 런타임에 생성이 가능하다.

2) 변수나 자료구조(객체, 배열 등)에 저장할 수 있다.

3) 함수의 매개변수에 전달할 수 있다.

4) 함수의 반환값으로 사용할 수 있다.


자바스크립트의 함수는 위 조건을 모두 만족하므로 일급 객체라고 할 수 있습니다.



5. 객체지향 프로그래밍 vs 함수형 프로그래밍

두드러지는 특징은 객체지향은 객체 중심으로 프로그래밍을 하는 반면, 함수형 프로그래밍은 함수 실행이 중심이 됩니다.


1) 함수형 프로그래밍 패러다임은 특정한 일을 수행하는 함수들을 어떻게 사용할 지를 강조하는 반면, 객체형 프로그래밍 패러다임은 객체 지향 컨셉을 강조합니다.

2) 함수형 요소는 변수와 함수를 사용하며 함수 내의 데이터는 불변합니다. 객체형 요소는 객체와 메소드, 그리고 변할 수 있는 데이터를 사용합니다.

3) 함수형의 중요성은 데이터가 아닌 함수에 있는 반면, 객체형의 중요성은 프로시져보단 데이터에 있습니다.

4) 함수형은 선언적 프로그래밍 모델인 반면, 객체형은 명령적 프로그래밍 모델입니다.

5) 함수형은 반복을 위해 순환을 사용하지만, 객체형은 loop를 사용합니다.

6) 함수형은 병렬 프로그래밍을 지원하지만, 객체형은 병렬 프로그래밍을 지원하지 않습니다.

7) 함수형은 특정한 접근자가 없는 반면 ,객체형은 세가지 특정 접근자가 있습니다. Public, Private, Protected.

8) 함수형은 새로운 데이터, 함수를 추가하는게 쉽지 않은 반면, 객체형은 쉽게 데이터, 함수를 추가할 수 있습니다.

9) 함수형은 데이터 은닉이 안되지만 객체형은 데이터 은닉을 제공하여 보안 프로그램이 가능합니다.


참고자료 :



6. Loop와 재귀의 차이

가장 큰 차이는 Call Stack에 쌓이는 여부일 것입니다.
Loop는 하나의 실행 컨텍스트를 통해 계속 실행하는 반면, 재귀의 경우 새로운 Function이 계속 실행되기 때문에 Call Stack에 새로운 실행 컨텍스트가 계속 쌓이게 됩니다.
이는 Stack Overflow를 발생시킵니다.
알고리즘에 따라 가독성과 유지보수성이 다르므로 상황에 맞추어 써야될 것입니다.



비동기프로그래밍


1. Ajax란?

Ajax란 자바스크립트를 사용하여 브라우저가 서버에게 비동기 방식으로 데이터를 요청하여, 서버가 응답한 데이터를 수신하여 웹페이지를 동적으로 갱신하는 프로그래밍 방식을 말합니다.
Ajax는 브라우저에서 제공하는 Web API인 XMLHttpRequest 객체를 기반으로 동작합니다.

XMLHttpRequest는 HTTP 비동기 통신을 위한 메서드와 프로퍼티를 제공합니다.

Ajax는 전통적인 방식과 비교했을 때 다음과 같은 장점이 있습니다.

1) 변경할 부분을 갱신하는 데 필요한 데이터만 서버로부터 전송받기 때문에 불필요한 데이터 통신이 발생하지 않는다.

2) 변경할 필요가 없는 부분은 다시 렌더링하지 않는다. 따라서 화면이 순간적으로 깜박이는 현상이 발생하지 않는다.

3) 클라이언트와 서버와의 통신이 비동기 방식으로 동작하기 때문에 서버에게 요청을 보낸 이후 블로킹이 발생하지 않는다.



2. Promise와 callback의 차이, 각각의 장단점

callback은 다음과 같은 2가지 단점이 있습니다.

1) 콜백 헬

비동기 함수는 비동기 처리 결과를 외부에 반환할 수 없고, 상위 스코프의 변수에 할당할 수도 없습니다.
따라서 비동기 함수의 처리 결과(서버의 응답 등)에 대한 후속 처리는 비동기 함수 내부에서 수행해야 합니다.

이때 비동기 함수를 범용적으로 사용하기 위해 비동기 함수에 비동기 처리 결과에 대한 후속 처리를 수행하는 콜백 함수를 전달하는 것이 일반적입니다.
필요에 따라 비동기 처리가 성공하면 호출될 콜백 함수와 비동기 처리가 실패하면 호출될 콜백 함수를 전달할 수 있습니다.

이처럼 콜백 함수를 통해 비동기 처리 결과에 대한 후속 처리를 수행하는 비동기 함수가 비동기 처리 결과를 가지고 또다시 비동기 함수를 호출해야 한다면 콜백 함수 호출이 중첩되어 복잡도가 높아지는 현상이 발생합니다.
이를 콜백 헬이라고 합니다.


2) 에러 처리의 한계

에러는 호출자 방향으로 전파됩니다.
즉, 콜 스택의 아래 방향(실행 중인 실행 컨텍스트가 푸시되기 직전에 푸시된 실행 컨텍스트 방향)으로 전파됩니다.

하지만 setTimeout 함수의 콜백 함수를 호출하는 것은 setTimeout 함수가 아닙니다.
따라서 setTimeout 함수의 콜백 함수가 발생시킨 에러는 catch 블록에서 캐치되지 않습니다.

위 단점을 극복하기 위해 ES6에서 프로미스가 도입되었습니다.



3. Promise란 무엇이고 어떻게 코드가 구성되있는가?

Promise 생성자 함수를 new 연산자와 함께 호출하면 프로미스(Promise 객체)를 생성합니다.
ES6에서 도입된 Promise는 호스트 객체가 아닌 ECMAScript 사양에 정의된 표준 빌트인 객체입니다.

Promise 생성자 함수는 비동기 처리를 수행할 콜백 함수를 인수로 전달받는데 이 콜백 함수는 resolve와 reject 함수를 인수로 전달받습니다.
Promise 생성자 함수가 인수로 전달받은 콜백 함수 내부에서 비동기 처리를 수행합니다.

이때 비동기 처리가 성공하면 콜백 함수의 인수로 전달받은 resolve 함수를 호출하고,
비동기 처리가 실패하면 reject 함수를 호출합니다.


프로미스는 현재 비동기 처리가 어떻게 진행되고 있는지를 나타내는 상태정보를 갖습니다.

1) pending

2) fulfilled

3) rejected


생성된 직후의 프로미스는 기본적으로 pending 상태입니다.
이후 비동기 처리가 수행되면 비동기 처리 결과에 따라 프로미스의 상태가 변경됩니다.


즉, 프로미스는 비동기 처리 상태와 처리 결과를 관리하는 객체입니다.
then 메서드를 통해 첫번째 콜백함수로 fulfilled 상태인 비동기 처리 결과를 핸들링 할 수 있고,
두번째 콜백함수로 rejected 상태인 비동기 처리 결과를 핸들링 할 수 있습니다.
catch 메서드를 통해 콜백 함수로 rejected 상태인 비동기 처리 결과를 핸들링 할 수 있습니다.

이는 콜백을 사용했을 때 에러 처리의 한계 단점을 극복할 수 있게 합니다.
catch 메서드를 사용하면 비동기 처리와 모든 then 메서드 내부에서 발생한 에러까지 모두 캐치할 수 있기 때문입니다.
또한, 프로미스 체이닝을 통해 콜백 헬을 해결할 수 있습니다.



4. 마이크로 태스크 큐란?

프로미스의 후속 처리 메서드의 콜백 함수는 태스크 큐가 아니라 마이크로태스크 큐에 저장됩니다.
마이크로태스크 큐는 태스크 큐와는 별도의 큐입니다.
마이크로태스크 큐에는 프로미스의 후속 처리 메서드의 콜백 함수가 일시 저장됩니다.
그 외의 비동기 함수의 콜백 함수나 이벤트 핸들러는 태스크 큐에 일시 저장됩니다.

콜백 함수나 이벤트 핸들러를 일시 저장한다는 점에서 태스크 큐와 동일하지만 마이크로태스크 큐는 태스크 큐보다 우선순위가 높습니다.

즉, 이벤트 루프는 콜 스택이 비면 먼저 마이크로태스크 큐에서 대기하고 있는 함수를 가져와 실행합니다.
이후 마이크로태스크 큐가 비면 태스크 큐에서 대기하고 있는 함수를 가져와 실행합니다.



5. 제너레이터란?

ES6에서 도입된 제너레이터는 코드 블록의 실행을 일시 중지했다가 필요한 시점에 재개할 수 있는 특수한 함수입니다.

제너레이터와 일반 함수의 차이는 다음과 같습니다.

1) 제너레이터 함수는 함수 호출자에게 함수 실행의 제어권을 양도할 수 있습니다.(yield)

2) 제너레이터 함수는 함수 호출자와 함수의 상태를 주고받을 수 있습니다.

3) 제너레이터 함수를 호출하면 제너레이터 객체를 반환합니다. (이터러블이면서 동시에 이터레이터인 제너레이터 객체)



6. 제너레이터 동작방식

제너레이터 함수를 호출하면 일반 함수처럼 함수 코드 블록을 실행하는 것이 아니라 제너레이터 객체를 생성해 반환합니다.
제너레이터 함수가 반환한 제너레이터 객체는 이터러블이면서 동시에 이터레이터입니다.

제너레이터 객체의 next 메서드를 호출하면 yield 표현식까지 실행되고 일시 중지됩니다.
이때 함수의 제어권이 호출자로 양도됩니다.

제너레이터의 객체의 next 메서드는 value, done 프로퍼티를 갖는 이터레이터 리절트 객체를 반환합니다.
next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티에는 yield 표현식에서 yield 값이 할당되고
done 프로퍼티에는 제너레이터 함수가 끝까지 실행되었는지를 나타내는 불리언 값이 할당됩니다.
제너레이터 객체의 next 메서드에 전달한 인수는 제너레이터 함수의 yield 표현식을 할당받는 변수에 할당됩니다.

이처럼 제너레이터 함수는 next 메서드와 yield 표현식을 통해 함수 호출자와 함수의 상태를 주고받을 수 있습니다.
이러한 제너레이터의 특성을 활용하면 비동기 처리를 동기처럼 구현할 수 있습니다.



7. async, await이란?

ES8(ECMAScript 2017)에서는 간단하고 가독성 좋게 비동기 처리를 동기처럼 동작하도록 구현할 수 있는 async/await이 도입되었습니다.

async/await은 프로미스를 기반으로 동작합니다.
async/await를 사용하면 프로미스의 then/catch/finally 후속 처리 메서드에 콜백 함수를 전달해서 비동기 처리 결과를 후속 처리할 필요 없이 마치 동기처럼 프로미스를 사용할 수 있습니다.

다시 말해, 후속 처리 메서드 없이 마치 동기처리처럼 프로미스가 처리 결과를 반환하도록 구현할 수 있습니다.



8. async, await 동작 방식

await 키워드는 반드시 async 함수 내부에서 사용해야 합니다.
async 함수는 async 키워드를 사용해 정의하며 언제나 프로미스를 반환합니다.

await 키워드는 프로미스가 settled 상태(비동기 처리가 수행된 상태)가 될 때까지 대기하다가 settled 상태가 되면 프로미스가 resolve한 처리 결과를 반환합니다.

async/await에서 에러 처리는 try…cath문을 사용할 수 있습니다.
콜백 함수를 인수로 전달받는 비동기 함수와는 달리 프로미스를 반환하는 비동기 함수는 명시적으로 호출할 수 있기 때문에 호출자가 명확합니다.
async 함수 내에서 catch 문을 사용해서 에러 처리를 하던지, 혹은 async 함수는 reject하는 프로미스를 반환하기 때문에 catch 후속 처리 메서드를 사용하여 에러를 캐치할 수도 있습니다.



Javascript 관련


1. forEach와 map의 차이

forEach는 배열의 각 요소를 순회하며 각 요소에 특정한 작업을 합니다.(예를 들어 각 요소를 데이터베이스에 저장한다는 작업) 그리고 아무런 값도 리턴하지 않습니다.

map은 배열의 각 요소를 순회하며 요소를 변형시켜 같은 사이즈의 새로운 배열을 반환합니다.(예를 들어 배열의 문자를 모두 대문자로 변경시키는 작업) map은 호출한 배열을 변경시키지 않습니다.



2. 자바스크립트의 Number Type은 다른 언어들과 차이점이 무엇인가, 왜 하나만 존재하나.

모든 수를 실수로 처리하기 때문에 숫자 관련 타입이 하나만 존재합니다.
값은 배정밀도 64비트 부동소수점 형식의 2진수로 저장됩니다.



3. 자바스크립트의 원시 타입은 몇가지인가? 종류는?

원시 타입과 객체 타입이 존재합니다.

원시 타입은 변경 불가능한 값이고, 객체 타입은 변경 가능한 값입니다.

변수(식별자)에 원시 값을 저장하면, 변수(식별자)에는 사실 원시 값이 저장된 주소 값이 저장하게 됩니다.
만약 변수에 다른 원시 값을 저장하게 되면, 기존 원시 값이 저장된 주소에 있는 값을 변경하지 않고 새로운 원시 값이 저장된 새로운 주소를 변수에 할당하게 됩니다.

변수(식별자)에 객체 값을 저장하면, 변수(식별자)에는 객체가 저장된 주소 값이 저장하게 됩니다.
만약 객체 내부의 값을 변경하면, 변수가 저장하고 있는 객체의 주소 값을 변경되지 않고, 객체 내부의 값만 변경하게 됩니다.



4. 실행 컨텍스트(Execution Context)에 대해 설명해달라

소스코드를 실행하는 데 필요한 환경을 제공하고 코드의 실행 결과를 관리하는 영역입니다.
좀 더 구체적으로 말해, 실행 컨텍스트는 식별자(변수, 함수, 클래스 등의 이름)를 등록하고 관리하는 스코프와 코드 실행 순서 관리를 구현한 내부 매커니즘으로, 모든 코드는 실행 컨텍스트를 통해 실행되고 관리됩니다.

식별자와 스코프는 실행 컨텍스트의 렉시컬 환경으로 관리하고, 코드 실행 순서는 실행 컨텍스트 스택으로 관리합니다.

동작 방식은 처음엔 소스코드를 평가하고, 두번째론 소스코드를 실행합니다.
위 작업이 전역코드, 함수코드, eval 코드, 모듈 코드에 따라 발생합니다.

소스 코드를 평가하면 실행 컨텍스트가 생기고, 실행 컨텍스트를 실행 컨텍스트 스택에 추가하여 코드를 실행합니다.

렉시컬 환경이란 식별자와 식별자에 바인딩된 값, 그리고 상위 스코프에 대한 참조를 기록하는 자료구조실행 컨텍스트를 구성하는 컴포넌트입니다.
실행 컨텍스트 스택이 코드의 실행 순서를 관리한다면 렉시컬 환경은 스코프와 식별자를 관리합니다.



5. 자바스크립트의 호이스팅(Hoisting)은 어떻게 이루어져 있는가

변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 변수 호이스팅이라 합니다.

자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서 먼저 소스코드의 평가 과정을 거치면서 소스코드를 실행하기 위한 준비를 합니다.
이때 소스코드 실행을 위한 준비 단계인 소스코드의 평가 과정에서 자바스크립트 엔진은 변수 선언을 포함한 모든 선언문(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아내 먼저 실행합니다.
그리고 소스코드의 평가 과정이 끝나면 비로소 변수 선언을 포함한 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행합니다.



6. 클로저(Closure)란 무엇이며, 왜 이러한 패턴을 사용하는가?

클로저란 함수와 그 함수가 정의된 렉시컬 환경과의 조합을 의미합니다.

외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있습니다.
이러한 중첨 합수를 클로저라고 부릅니다.

클로저는 상태를 안전하게 변경하고 유지하기 위해 사용합니다.
다시 말해, 상태가 의도치 않게 변경되지 않도록 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용합니다.


렉시컬 스코프란?
자바스크립트 엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정합니다. 이를 렉시컬 스코프(정적 스코프)라고 합니다.
렉시컬 환경의 “외부 렉시컬 환경에 대한 참조”에 저장할 참조값, 즉 상위 스코프에 대한 참조는 함수 정의가 평가되는 시점에 함수가 정의된 환경(위치)에 의해 결정됩니다.
이것이 바로 렉시컬 스코프입니다.


함수는 자신의 내부 슬롯 [[Environment]]에 자신이 정의된 환경, 즉 상위 스코프의 참조를 저장합니다.
이때 자신의 내부 슬롯 [[Environment]]에 저장된 상위 스코프의 참조는 현재 실행 중인 실행 컨텍스트의 렉시컬 환경을 가리킵니다.
왜냐하면 함수 정의가 평가되어 함수 객체를 생성하는 시점은 함수가 정의된 환경, 즉 상위 함수(또는 전역코드)가 평가 또는 실행되고 있는 시점이며, 이때 현재 실행 중인 실행 컨텍스트는 상위 함수(또는 전역 코드)의 실행 컨텍스트이기 때문입니다.

따라서 함수 객체의 내부 슬롯 [[Environment]]에 저장된 현재 실행 중인 실행 컨텍스트의 렉시컬 환경의 참조가 바로 상위 스코프입니다.
또한 자신이 호출되었을 때 생성될 함수 렉시컬 환경의 “외부 렉시컬 환경에 대한 참조”에 저장될 참조값입니다.

함수 객체는 내부 슬롯 [[Environmnet]]에 저장한 렉시컬 환경의 참조, 즉 상위 스코프를 자신이 존재하는 한 기억합니다.



8. 가비지컬렉터의 역할은? 어떻게 동작하나요?

가바지컬렉터는 사용하지 않는 메모리를 해제시킵니다. (메모리 누수 방지 목적)
해제 방법은 여러가지가 존재하지만 대표적으로는 2가지가 있습니다.

1) 참조-세기(Reference-counting) 가비지 콜렉션

2) 표시하고-쓸기(Mark-and-sweep) 알고리즘



10. 자바스크립트의 순환참조란? 어떤게 문제이고 해결방법은?

자바스크립트 모듈은 런타임 시 최초 Import를 만날 때 단 한번만 평가하고 반환됩니다.
이렇게 반환된 모듈은 Global로 관리되고 있는 모듈 객체에 추가됩니다.
따라서 이후 다른 곳에서 동일한 모듈을 Import하게 되면 다시 평가하는 것이 아닌 모듈 객체에서 가지고 오게 됩니다.

이런 모듈을 사용할 때 중요한 점은 순환 참조를 주의해야 한다는 것입니다. 순환 참조란 A모듈에서 B모듈을 Import하고, B모듈에서도 A모듈을 Import할 때 아직 반환되지 않은 함수를 사용하면 에러가 나는 문제입니다.

이 문제를 해결하는 방법으로는 모듈의 Dependency 순서를 명확히 지정하는 것이고, 좀 복잡하고 Dependency가 많다면 별도의 모듈을 Import하는 파일을 만들어서 해당 파일 내부에서 모듈 Import를 관리하는 것도 하나의 방법입니다.


참조자료 :



11. 자바스크립트의 배열이 실제 자료구조 배열이 아닌데 그 이유는?

자바스크립트의 배열은 일반적인 배열의 동작을 흉내 낸 특수한 객체입니다. 인덱스를 나타내는 문자열을 프로퍼티 키로 가지며, length 프로퍼티를 갖는 특수한 객체입니다.

자바스크립트 배열의 요소는 사실 프로퍼티 값입니다. 자바스크립트에서 사용할 수 있는 모든 값은 객체의 프로퍼티 값이 될 수 있으므로 어떤 타입의 값이라도 배열의 요소가 될 수 있습니다.

일반적인 배열과 자바스크립트 배열의 장단점을 정리해보면 다음과 같습니다.

즉, 자바스크립트 배열은 인덱스로 배열 요소에 접근하는 경우에는 일반적인 배열보다 느리지만 특정 요소를 검색하거나 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠릅니다.

자바스크립트 배열은 인덱스로 접근하는 경우의 성능 대신 특정 요소를 탐색하거나 배열 요소를 삽입 또는 삭제하는 경우의 성능을 선택한 것입니다.



12. 이벤트 루프, 동시성 모델에 대해서 설명해달라

자바스크립트의 특징 중 하나는 싱글 스레드로 동작한다는 것입니다.
싱글 스레드 방식은 한 번에 하나의 태스크만 처리할 수 있다는 것을 의미합니다.
하지만 브라우저가 동작하는 것을 살펴보면 많은 태스크가 동시에 처리되는 것처럼 느껴집니다.

예를 들어, HTML 요소가 애니메이션 효고를 통해 움직이면서 이벤트를 처리하기도 하고, HTTP 요청을 통해 서버로부터 데이터를 가지고 오면서 렌더링하기도 합니다.
이처럼 자바스크립트의 동시성을 지원하는 것이 바로 이벤트 루프입니다.

자바스크립트는 이벤트 루프 기반의 동시성 모델을 갖습니다.

동시성이란 실제 물리적으로 동시에 일어나는 것이 아니라, 실행시키는 주체는 하나이지만, 작은 타임 슬라이스 단위로 실행시켜서 동시에 일어나는 것 처럼 보이게 하는 방식입니다.

이벤트 루프는 브라우저에 내장되어 있는 기능 중 하나로 콜 스택이 비어 있고 태스크 큐에 대기 중인 함수가 있다면 순차적(FIFO)으로 태스크 큐에 대기 중인 함수를 콜스택으로 이동시킵니다.

대부분 자바스크립트 엔진은 크게 2개의 영역으로 구분할 수 있습니다.

1) 콜 스택

2) 힙

이처럼 콜 스택과 힙으로 구성되어 있는 자바스크립트 엔진은 단순히 태스크가 요청되면 콜 스택을 통해 요청된 작업을 순차적으로 실행할 뿐입니다.

비동기 처리에서 소스코드의 평가와 실행을 제외한 모든 처리는 자바스크립트 엔진을 구동하는 환경인 브라우저 또는 Node.js가 담당합니다.

예를 들어, 비동기 방식으로 동작하는 setTimeout의 콜백 함수의 평가와 실행은 자바스크립트 엔진이 담당하지만 호출 스케줄링을 위한 타이머 설정과 콜백 함수의 등록은 브라우저 또는 Node.js가 담당합니다.
이를 위해 브라우저 환경은 태스크 큐와 이벤트 루프를 제공합니다.

1) 태스크 큐

2) 이벤트 루프

자바스크립트는 싱글 스레드 방식으로 동작합니다.
이때 싱글 스레드 방식으로 동작하는 것은 브라우저가 아니라 브라우저에 내장된 자바스크립트 엔진이라는 것에 주의하길 바랍니다.

만약 모든 자바스크립트 코드가 자바스크립트 엔진에서 싱글 스레드 방식으로 동작한다면 자바스크립트는 비동기로 동작할 수 없습니다.

즉, 자바스크립트 엔진은 싱글 스레드로 동작하지만 브라우저는 멀티 스레드로 동작합니다.



13. 프로토타입이란?

프로토타입이란 객체지향 프로그래밍의 근간을 이루는 객체 간 상속을 구현하기 위해 사용됩니다.

프로토타입은 어떤 객체의 상위(부모) 객체의 역할을 하는 객체로서 다른 객체에 공유 프로퍼티(메서드 포함)를 제공합니다.
프로토타입을 상속받은 하위(자식) 객체는 상위 객체의 프로퍼티를 자신의 프로퍼티처럼 자유롭게 사용할 수 있습니다.

모든 객체는 [[Prototype]]이라는 내부 슬롯을 가지며, 이 내부 슬롯의 값은 프로토타입의 참조입니다.
[[Prototype]]에 저장되는 프로토타입은 객체 생성 방식에 의해 결정됩니다.

즉, 객체가 생성될 때 객체 생성 방식에 따라 프로토타입이 결정되고 [[Prototype]]에 저장됩니다.



14. 프로토타입체인이란?

자바스크립트는 객체의 프로퍼티(메서드 포함)에 접근하려고 할 때 해당 객체에 접근하려는 프로퍼티가 없다면 [[Prototype]] 내부 슬롯의 참조를 따라 자신의 부모 역할을 하는 프로토타입의 프로퍼티를 순차적으로 접근합니다.

이를 프로토타입 체인이라고 합니다.

프로토타입 체인은 자바스크립트가 객체지향 프로그래밍의 상속을 구현하는 메커니즘입니다.



15. 자바스크립트에서 This는 몇가지로 추론 될수 있는가, 아는대로 말해달라

자바스크립트에서 this는 4가지 정도로 추론 가능합니다.

1) 일반 함수 호출

2) 메서드 호출

3) 생성자 함수 호출

4) Function.prototype.apply/call.bind 메서드에 의한 간접 호출



16. 일반함수의 this와 화살표 함수의 this는 어떻게 다른가?

1) 화살표 함수는 인스턴스를 생성할 수 없는 non-constructor 입니다.

2) 중복된 매개변수 이름을 선언할 수 없습니다.

3) 화살표 함수는 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않습니다.



17. Call, Apply, Bind 함수에 대해 설명해달라

apply와 call 메서드의 본질적인 기능은 함수를 호출하는 것입니다.

첫 번째 인수로 전달한 특정 객체를 호출한 함수의 this에 바인딩 합니다.
apply 메서드는 호출할 함수의 인수를 배열로 묶어 전달하고, call 메서드는 호출할 함수의 인수를 쉼표로 구분한 리스트 형식으로 전달합니다.

bind 메서드는 apply와 call 메서드와 달리 함수를 호출하지 않고 this로 사용할 객체만 전달합니다.
그럼 전달된 객체가 해당 함수의 this로 바인딩 됩니다.



18. use strict모드란? use strict모드에서의 this 값은?

ES5부터 지원된 모드로, 자바스크립트 언어의 문법을 좀 더 엄격히 적용하여 오류를 발생시킬 가능성이 높거나, 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러를 발생시킵니다.

ESLint 같은 린트 도구와 유사한 효과를 가집니다.
린트 도구는 정적 분석기능을 통해 소스코드를 실행하기 전에 소스코드를 스캔하여 문법적 오류만이 아니라, 잠재적 오류까지 찾아내고 오류의 원인을 리포팅해주는 유용한 도구입니다.

예를 들어 use strict 모드일 경우 일반 함수에서 this는 undefined로 바인딩 됩니다.
생성자 함수가 아닌 일반 함수 내부에서는 this를 사용할 필요가 없기 때문입니다.



22. ES6 에서 추가된 스펙에 대해 아는대로 다 말해달라

1) 화살표 함수
2) 클래스
3) 향상된 객체 리터럴(축약표현)

4) 템플릿 문자열
5) 디스트럭처링
6) 매개변수 디폴트 값, Rest, Spread 문법
7) let, const
8) 이터레이터와 for..of
9) 제너레이터
10) 모듈 (import, export)
11) 모듈 로더 (다이나믹 로딩)
12) map, set, weakmap, weakset
13) 심볼
14) 프로미스
15) Object assign



23. var 와 let, const의 차이점은 무엇인가?

var는 다음과 같은 세 가지 특징이 있습니다.

1) 변수 중복 선언이 허용됩니다.
2) 함수 레벨 스코프를 갖습니다.
3) 호이스팅 됩니다. (호이스팅으로 인해 undefined 값을 기본적으로 갖습니다)

위 특징을 보완하기 위해 ES6에서 let, const가 나왔습니다.
let의 다음과 같은 세 가지 특징을 갖습니다.

1) 변수 중복 선언이 금지됩니다.
2) 블록 레벨 스코프를 갖습니다.
3) 호이스팅이 발생하지 않는 것처럼 동작합니다.

런타임 이전에 자바스크립트 엔진에 의해 “선언 단계”와 “초기화 단계”가 진행됩니다.
var는 “선언 단계”와 “초기화 단계”가 한번에 진행되어 undefined를 갖게 되지만, let의 경우 “선언 단계”와 “초기화 단계”가 분리되어 진행됩니다.
즉, 런타임 이전에 자바스크립트 엔진에 의해 암묵적으로 선언 단계가 먼저 실행되지만 초기화 단계는 변수 선언문에 도달했을 때 실행됩니다.
그래서 만약 초기화 단계가 실행되기 이전에 변수에 접근하려고 하면 undefined 값이 나오는 것이 아니라 참조 에러가 발생합니다.

또 다른 특징은, var 키워드로 선언한 전역 변수와 전역 함수, 그리고 선언하지 않은 변수에 값을 할당한 암묵적 전역은 전역 객체 window의 프로퍼티가 됩니다.
그러나 let 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아닙니다.
let 전역 변수는 보이지 않는 개념적인 블록(전역 렉시컬 환경의 선언적 환경 레코드) 내에 존재하게 됩니다.

const는 다음과 같은 특징을 갖습니다.

1) const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화해야 합니다.
2) 재할당이 금지됩니다.
3) 그래서 상수로 활용됩니다.
4) 객체 변경은 안되나, 객체 내부 값은 변경이 가능합니다.



24. Class 는 무엇이고, Prototype, fucntion의 ES5 스펙만으로 Class를 구현할수 있는가

Class를 통해 기존 프로토타입 기반 객체지향 프로그래밍보다 자바나 C#과 같은 클래스 기반 객체지향 프로그래밍에 익숙한 프로그래머가 더욱 빠르게 학습할 수 있도록 클래스 기반 객체지향 프로그래밍 언어와 매우 흡사한 새로운 객체 생성 매커니즘을 제시합니다.

그렇다고 ES6의 클래스가 기존의 프로토타입 기반 객체지향 모델을 폐지하고 새롭게 클래스 기반 객체지향 모델을 제공하는 것은 아닙니다.
사실 클래스는 함수이며 기존 프로토타입 기반 패턴을 클래스 기반 패턴처럼 사용할 수 있도록 하는 문법적 설탕이라고 볼 수도 있습니다.

단, 클래스와 생성자 함수는 모두 프로토타입 기반의 인스턴스를 생성하지만 정확히 동일하게 동작하지는 않습니다.
클래스는 생성자 함수보다 엄격하며 생성자 함수에서는 제공하지 않는 기능도 제공합니다.

1) 클래스를 new 연산자 없이 호출하면 에러가 발생합니다. 하지만 생성자 함수를 new 연산자 없이 호출하면 일반 함수로서 호출됩니다.

2) 클래스는 상속을 지원하는 extends와 super 키워드를 제공합니다. 하지만 생성자 함수는 extends와 super 키워드를 지원하지 않습니다.

3) 클래스는 호이스팅이 발생하지 않는 것처럼 동작합니다. 하지만 함수 선언문으로 정의된 생성자 함수는 함수 호이스팅이, 함수 표현식으로 정의한 생성자 함수는 변수 호이스팅이 발생합니다.

4) 클래스 내의 모든 코드에는 암묵적인 strict mode가 지정되어 실행되며 strict mode를 해제할 수 없습니다. 하지만 생성자 함수는 암묵적으로 strict mode가 지정되지 않습니다.

5) 클래스의 constructor, 프로토타입 메서드, 정적 메서드는 모두 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 false입니다. 다시 말해, 열거되지 않습니다.



25. Object.Assign vs Spread Operator

여러 개의 객체를 병합하거나 특정 프로퍼티를 변경 또는 추가하는데 사용됩니다.

Object.assign과 Spread operator의 가장 큰 차이는 Spread는 새로운 프로퍼티를 정의하는 반면, object.assign()은 set을 이용한다는 것입니다.

1) Object.assign()은 2가지 방식을 사용합니다.

2) spread와 object.assign()은 get 접근자 프로퍼티를 통해 value를 읽어옵니다.

3) spread는 속성을 정의하나, object.assgin()은 속성 값을 set합니다.

4) spread와 object.assign()은 오직 ennumerable한 속성만 고려대상입니다.


참고자료:



26. 이벤트 위임이란?

여러 개의 하위 DOM 요소에 각각 이벤트 핸들러를 등록하는 대신 하나의 상위 DOM 요소에 이벤트 핸들러를 등록하는 방법을 말합니다.
이벤트는 이벤트 타깃은 물론 상위 DOM 요소에서도 캐치할 수 있기 때문입니다.

이벤트 위임을 통해 상위 DOM 요소에 이벤트 핸들러를 등록하면 여러 개의 하위 DOM 요소에 이벤트 핸들러를 등록할 필요가 없습니다.
또한, 동적으로 하위 DOM 요소를 추가하더라도 일일이 추가된 DOM 요소에 이벤트 핸들러를 등록할 필요가 없습니다.

이벤트 위임을 통해 하위 DOM 요소에서 발생한 이벤트를 처리할 때 주의할 점은 상위 요소에 이벤트 핸들러를 등록하기 때문에 이벤트 타깃, 즉 이벤트를 실제로 발생시킨 DOM 요소가 개발자가 기대한 DOM 요소가 아닐 수도 있다는 것입니다.
따라서 이벤트에 반응이 필요한 DOM요소에 한정하여 이벤트 핸들러가 실행되도록 이벤트 타깃을 검사할 필요가 있습니다.

일반적으로 이벤트 객체의 target 프로퍼티와 currentTarget 프로퍼티는 동일한 DOM 요소를 가리키지만 이벤트 위임을 통해 상위 DOM 요소에 이벤트를 바인딩한 경우 이벤트 객체의 target 프로퍼티와 currentTarget 프로퍼티가 다른 DOM 요소를 가르킬 수 있습니다.



27. 이벤트 버블링이란?

이벤트 발생 시 생성된 이벤트 객체는 이벤트를 발생시킨 DOM 요소인 이벤트 타깃을 중심으로 DOM 트리를 통해 전파됩니다.
이벤트 전파는 이벤트 객체가 전파되는 방향에 따라 3단계로 구분할 수 있습니다.

1) 캡쳐링 단계 : 이벤트가 상위 요소에서 하위 요소 방향으로 전파
2) 타깃 단계 : 이벤트가 이벤트 타깃에 도달
3) 버블링 단계 : 이벤트가 하위 요소에서 상위 요소 방향으로 전파

li 요소를 클릭하여 클릭 이벤트가 발생한다고 하면, 클릭 이벤트 객체가 생성되고 클릭된 li 요소가 이벤트 타깃이 됩니다.
이때 클릭 이벤트 객체는 window에서 시작해서 이벤트 타깃 방향으로 전파됩니다. 이것이 캡쳐링 단계입니다.
이후 이벤트 객체는 이벤트를 발생시킨 이벤트 타깃에 도달합니다. 이것이 타깃 단계입니다.
이후 이벤트 객체는 이벤트 타깃에서 시작해서 window 방향으로 전파됩니다. 이것이 버블링 단계입니다.

이벤트 핸들러 어트리뷰트/프로퍼티 방식으로 등록한 이벤트 핸들러는 타깃 단계와 버블링 단계의 이벤트만 캐치할 수 있습니다.
캡쳐링 단계의 이벤트를 캐치하려면 addEventListener 메서드의 3번째 인수로 true를 전달해야 합니다.



28. Rest 파라미터란?

Rest 파라미터(나머지 매개변수)는 매개변수 이름 앞에 세개의 점 …을 붙여서 정의한 매개변수를 의미합니다.

Rest 파라미터는 함수에 전달된 인수들의 목록을 배열로 전달받습니다.

Rest 파라미터는 단 하나만 선언할 수 있으며, 함수 객체의 length 프로퍼티에 영향을 주지 않습니다.

ES5에서는 함수를 정의할 때 매개변수의 개수를 확정할 수 없는 가변 인자 함수의 경우 매개변수를 통해 인수를 전달받는 것이 불가능하므로 arguments 객체를 활용하여 인수를 전달받았습니다.

arguments 객체는 함수 호출 시 전달된 인수들의 정보를 담고 있는 순회가능한 유사 배열 객체이며, 함수 내부에서 지역 변수처럼 사용할 수 있습니다.

하지만 arguments 객체는 배열이 아닌 유사 배열 객체이므로 배열 메서드를 사용하려면 Function.prototype.call이나 Function.prototype.apply 메서드를 사용해 arguments 객체를 배열로 반환해야 하는 번거로움이 있었습니다.

ES6에서는 rest 파라미터를 사용하여 가변 인자 함수의 인수 목록을 배열로 직접 전달받을 수 있습니다.

이를 통해 유사 배열 객체인 arguments 객체를 배열로 변환하는 번거로움을 피할 수 있습니다.



29. 스프레드 문법이란?

ES6에서 도입된 스프레드 문법 …은 하나로 뭉쳐 있는 여러 값들의 집합을 펼쳐서(전개, 분산하여, spread) 개별적인 값들의 목록으로 만듭니다.

스프레드 문법을 사용할 수 있는 대상은 Array, String, Map, Set, DOM 컬렉션(NodeList, HTMLCollection), arguments와 같이 for…of 문으로 순회할 수 있는 이터러블에 한정됩니다.

스프레드 문법의 결과물은 값으로 사용할 수 없고, 다음과 같이 쉼표로 구분한 값의 목록을 사용하는 문맥에서만 사용할 수 있습니다.

스프레드 프로퍼티를 사용하면 객체 리터럴의 프로퍼티 목록에서도 스프레드 문법을 사용할 수 있습니다.
스프레드 문법의 대상은 이터러블이어야 하지만 스프레드 프로퍼티 제안은 일반 객체를 대상으로도 스프레드 문법의 사용을 허용합니다.

스프레드 프로퍼티가 제안되기 이전에는 ES6에서도 도입된 Object.assign 메서드를 사용하여 여러 개의 객체를 병합하거나 특정 프로퍼티를 변경 또는 추가했습니다.



30. 디스트럭처링 할당이란?

디스트럭처링 할당(구조 분해 할당)은 구조화된 배열과 같은 이터러블 또는 객체를 destructuring(비구조화, 구조 파괴)하여 1개 이상의 변수에 개별적으로 할당하는 것을 말합니다.

배열과 같은 이터러블 또는 객체 리터럴에서 필요한 값만 추출하여 변수에 할당할 때 유용합니다.


1) 배열

ES6의 배열 디스트럭처링 할당은 배열의 각 요소를 배열로부터 추출하여 1개 이상의 변수에 할당합니다.
이때 배열 디스트럭처링 할당의 대상(할당문의 우변)은 이터러블이어야 하며, 할당 기준은 배열의 인덱스입니다.

즉, 순서대로 할당됩니다.

배열 디스트럭처링 할당을 위한 변수에 Rest 파라미터와 유사하게 Rest 요소 …을 사용할 수 있습니다.
Rest 요소는 Rest 파라미터와 마찬가지로 반드시 마지막에 위치해야 합니다.

const [x, ...y] = [1, 2, 3];
console.log(x, y); // 1 [2, 3]


2) 객체

ES5에서 객체의 각 프로퍼티를 객체로부터 디스트럭처링하여 변수에 할당하기 위해서는 프로퍼티 키를 사용해야 합니다.
ES6의 객체 디스트럭처링 할당은 객체의 각 프로퍼티를 객체로부터 추출하여 1개 이상의 변수에 할당합니다.
이때 객체 디스트럭처링 할당의 대상(할당문의 우변)은 객체이어야 하며, 할당 기준은 프로퍼티 키 입니다.

즉, 순서는 의미가 없으며 선언된 변수 이름과 프로퍼티 키가 일치하면 할당됩니다.

객체 디스트럭처링 할당은 객체에서 프로퍼티 키로 필요한 값만 추출하여 변수에 할당하고 싶을 때 유용합니다.
객체 디스트럭처링 할당은 객체를 인수로 전달받는 함수의 매개변수에도 사용할 수 있습니다.

객체 디스트럭처링 할당을 위한 변수에 Rest 파라미터나 Rest 요소와 유사하게 Rest 프로퍼티 …을 사용할 수 있습니다.
Rest 프로퍼티는 Rest 파라미터나 Rest 요소와 마찬가지로 반드시 마지막에 위치해야 합니다.

// Rest 프로퍼티
const { x, ...rest } = { x: 1, y: 2, z: 3 };
console.log(x, rest); // 1 { y: 2, z: 3}



31. 심벌이란?

심벌은 ES6에서 도입된 7번째 데이터 타입으로 변경 불가능한 원시 타입의 값입니다.

실범 값은 다른 값과 중복되지 않는 유일무이한 값입니다.
따라서 주로 이름의 충돌 위험이 없는 유일한 프로퍼티 키를 만들기 위해 사용합니다.

자바스크립트가 기본 제공하는 빌트인 심벌 값을 ECMAScript 사양에서는 Well-known Symbol이라고 부릅니다.
Well-known Symbol은 자바스크립트 엔진의 내부 알고리즘에 사용됩니다.

예를 들어 Array, String, Map, Set, TypedArray, arguments, NodeList, HTMLCollection과 같이 for…of 문으로 순회 가능한 빌트인 이터러블은 Well-known Symbol인 Symbol.iterator를 키로 갖는 메서드를 가지며, Symbol.iterator 메서드를 호출하면 이터레이터를 반환하도록 ECMAScript 사양에 규정되어 있습니다.
빌트인 인터러블은 이 규정 즉, 이터레이션 프로토콜을 준수합니다.

만약 빌트인 이터러블이 아닌 일반 객체를 이터러블처럼 동작하도록 구현하고 싶다면 이터레이션 프로토콜을 따르면 됩니다.
즉, ECMAScript 사양에 규정되어 있는 대로 Well-known Symbol인 Symbol.iterator를 키로 갖는 메서드를 객체에 추가하고 이터레이터를 반환하도록 구현하면 그 객체는 이터러블이 됩니다.

이때 이터레이션 프로토콜을 준수하기 위해 일반 객체에 추가해야 하는 메서드의 키 Symbol.iterator는 기존 프로퍼티 키 또는 미래에 추가될 프로퍼티 키와 절대로 중복되지 않을 것입니다.

이처럼 심벌은 중복되지 않는 상수 값을 생성하는 것은 물론 기존에 작성된 코드에 영향을 주지 않고 새로운 프로퍼티를 추가하기 위해, 즉 하위 호환성을 보장하기 위해 도입되었습니다.



32. 이터러블이란? 이터레이터란?

ES6에서 도입된 이터레이션 프로토콜은 순회 가능한 데이터 컬렉션(자료구조)을 만들기 위해 ECMAScript 사양에 정의하여 미리 약속한 규칙입니다.

ES6 이전의 순회 가능한 데이터 컬렉션, 즉, 배열, 문자열, 유사 배열 객체, DOM 컬렉션 등은 통일된 규약없이 각자 나름의 구조를 가지고 for 문, for…in문, forEach 메서드 등 다양한 방법으로 순회할 수 있었습니다.
ES6에서는 순회 가능한 데이터 컬렉션을 이터레이션 프로토콜을 준수하는 이터러블로 통일하여 for…of문, 스프레드 문법, 배열 디스트럭처링 할당의 대상으로 사용할 수 있도록 일원화 했습니다.

1) 이터러블 프로토콜

2) 이터레이터 프로토콜

이터러블의 Symbol.iterator 메서드를 호출하면 이터레이터 프로토콜을 준수한 이터레이터를 반환합니다.
이터러블의 Symbol.iterator 메서드가 반환한 이터레이터는 next 메서드를 갖습니다.
이터레이터의 next 메서드는 이터러블의 각 요소를 순회하기 위한 포인터의 역할을 합니다.

즉, 이터레이터의 next 메서드를 호출하면 이터러블을 순차적으로 한 단계씩 순회하며 순회 결과를 나타내는 이터레이터 리절트 객체를 반환합니다.

이터레이터의 next 메서드가 반환하는 이터레이터 리절트 객체의 value 프로퍼티는 현재 순회 중인 이터러블의 값을 나타내며 done 프로퍼티는 이터러블의 순회 완료 여부를 나타냅니다.



33. null vs undefined ?

Javascript에서 undefined는 선언은 되었으나 아직 값이 할당되지 않은 상태를 의미합니다.
null은 명시적으로 할당된 값입니다.





리액트


1. 리액트의 상태관리에 대해 알고 있는가? Redux를 사용해봤다면, 그것에 대한 설명 - Redux-saga와 옵저버블에 대해 들어봤는가?



2. Context-API에 대해서 설명하세요.



3. 클래스형과 함수형의 차이는 무엇인가?



4. 라이프사이클 메소드에 대해서 설명하세요.



5. 상태 관리 라이브러리를 사용해 보았는지?



기타


1. 타입스크립트를 사용해본 경험이 있는가, 타입스크립트에 대한 본인의 생각과 도입시의 장점을 말해달라



2. Angular와 React의 차이점은 무엇이라고 생각? - 라이브러리와 프레임워크에 대해서 설명



3. 두 명의 프론트엔드 개발자가 있다 git을 관리하는 방식?



4. 메소드 체이닝이란 무엇이며, 이것의 장단점은 무엇인가?



5. 메모이제이션이란?

함수내에 불필요한 작업을 피하기 위해 이전에 연산된 결과를 저장하고 사용하는 패턴입니다.
클로저를 활용하여 구현할 수 있습니다.

var fibonacci = (function () {
  var save = {};
  var fibo = function (number) {
    if (number < 2) {
      return number;
    } else {
      var saved1 = save[number - 1] || fibo(number - 1);
      var saved2 = save[number - 2] || fibo(number - 2);
      var result = saved1 + saved2;
      save[number] = result;
      console.log(saved1, saved2, result);
      return result;
    }
  };
  return fibo;
})();
fibonacci(5); // 1 0 1, 1 1 2, 2 1 3, 3 2 5, 5
fibonacci(5); // 3 2 5, 5



6. RESTful API 가 무엇인가, 아는대로 다 말해달라

웹이 HTTP를 제대로 사용하지 못하고 있는 상황을 보고 HTTP의 장점을 최대한 활용할 수 있는 아키텍처로서 처음 REST가 소개되었습니다.

REST는 HTTP 프로토콜을 의도에 맞게 디자인하였고, REST의 기본 원칙을 성실히 지킨 서비스 디자인을 “RESTful”이라고 표현합니다.

REST API는 자원, 행위, 표현의 3가지 요소로 구성됩니다.
REST는 자체 표현 구조로 구성되어 REST API만으로 HTTP 요청의 내용을 이해할 수 있습니다.

REST에서 가장 중요한 원칙은 두 가지입니다.
URI는 리소스를 표현하는 데 집중하고 행위에 대한 정의는 HTTP 요청 메서드를 통해 하는 것이 RESTful API를 설계하는 중심 규칙입니다.

1) URI는 리소스를 표현해야 합니다.

URI는 리소스를 표현하는 데 중점을 두어야 합니다.
리소스를 식별할 수 있는 이름은 동사보다는 명사를 사용합니다.
따라서 이름에 get 같은 행위에 대한 표현이 들어가서는 안됩니다.

2) 리소스에 대한 행위는 HTTP 요청 메서드로 표현합니다.

HTTP 요청 메서드는 클라이언트가 서버에게 요청의 종류와 목적(리소스에 대한 행위)을 알리는 방법입니다.
주로 5가지 요청 메서드(GET, POST, PUT, PATCH, DELETE 등)을 사용하여 CRUD를 구현합니다.

리소스에 대한 행위는 HTTP 요청 메서드를 통해 표현하며 URI에 표현하지 않습니다.

예를 들어, 리소스를 취득하는 경우에는 GET, 리소스를 삭제하는 경우에는 DELETE를 사용하여 리소스에 대한 행위를 명확히 표현합니다.



7. CORS(Cross-Origin Resource Sharing)는 무엇인가 왜 이러한 방법이 정의 되었으며, 본인이 코드를 작성하면서 CORS와 관련하여서 경험하였던 이슈는 무엇인가



8. Eslint가 무엇인가요?

ES는 ECMA Script 와 동일하며, ECMA Script란 ECMA-262 기술 규격에 정의된 표준화된 스크립트 프로그래밍 언어입니다.
자바스크립트를 표준화하기 위해 만들어진 규격입니다.

린트 도구는 정적 분석기능을 통해 소스코드를 실행하기 전에 소스코드를 스캔하여 문법적 오류만이 아니라, 잠재적 오류까지 찾아내고 오류의 원인을 리포팅해주는 유용한 도구입니다.



9. Webpack이란?

Webpack은 여러 개의 Javascript 파일들을 하나의 파일로 묶어주는 모듈 Bundler 입니다.

기존에 Javascript 파일이 각각 분리되어 있는 경우 HTML에 Import 하는 과정에서 Script 태그를 이용해 Dependency 관리가 매우 어렵다는 단점이 있습니다.
또한 스크립트 파일끼리 데이터 교환도 전역 변수를 사용해야하는 등 여러 제약 사항이 많습니다.
그렇다고 하나의 Javascript 파일에 모든 Javascript 소스를 합치면 코드가 몇 천 줄이 넘어가기 때문에 개발할 때 유지보수가 매우 어렵다는 단점이 있습니다.

하지만 Webpack을 사용하게 되면 이러한 단점들을 극복이 가능하며, 각종 플러그인이나 최신 문법 등 개발할 때 유용한 기능들을 다양하게 사용할 수 있습니다.


참고자료 :



10. 패키지매니저로 어떤거 사용? npm과 yarn은 어떤게 다른가?



11. 적응형과 반응형의 차이를 아는가? - package.json파일의 역할을?



12. package.json에서 dependencies와 devDependencies의 차이는?



13. 프로세스와 스레드의 차이



14. CSR과 SSR의 차이?

SSR(Server Side Rendering)이란 단어 그대로 서버에서 렌더링 작업을 하는것을 의미합니다.

기존에 존재하던 방식으로 사용자가 웹페이지에 접근할 때 서버에서 페이지에 대한 요청을 하며 서버에서는 html, view와 같은 리소스들을 어떻게 보여질지 해석하고 렌더링하여 사용자에게 반환합니다.

CSR이란 최초에 1번 서버에서 전체 페이지를 로딩하여 보여주고 이후에는 사용자의 요청이 올 때마다, 리소스를 서버에서 제공한 후 클라이언트가 해석하고 렌더링을 하는 방식입니다.

Angular js, Backbone js 같이 SPA개발이 쉬운 js프레임워크가 등장했습니다.

1) 초기로딩 속도

2) 서버 부담

3) SEO


참고 자료 :



16. DOM을 건드리는 방식과 아닌 방식들의 차이



17. 반응형 프로그래밍?



18. Call by value & call by ref



20. inline vs inline block ?



21. vue와 React의 차이?



22. 가상돔 (virtual DOM)



23. AMD와 Common JS의 차이

자바스크립트는 웹페이지의 단순한 보조 기능을 처리하기 위한 용도를 목적으로 태어났습니다.
이러한 태생적 한계로 인해 다른 프로그래밍 언어와 비교할 때 부족한 부분들이 존재합니다.

대표적인 것이 모듈 시스템을 지원하지 않는다는 것입니다.

다시 말해, 자바스크립트는 모듈이 성립하기 위해 필요한 파일 스코프와 import export를 지원하지 않았습니다.

자바스크립트 파일을 여러 개의 파일로 분리하여 script 태그로 로드해도 분리된 자바스크립트 파일들은 결국 하나의 자바스크립트 파일 내에 있는 것처럼 동작했습니다.
즉, 모든 자바스크립트 파일은 하나의 전역을 공유합니다. 따라서 자바스크립트 파일들의 전역 변수가 중복되는 등의 문제가 발생할 수 있습니다.

자바스크립트를 클라이언트 사이드, 즉 브라우저 환경에 국한하지 않고 범용적으로 사용하려는 움직임이 생기면서 모듈 시스템은 반드시 해결해야 하는 핵심 과제가 되었습니다.

이런 상황에서 제안된 것이 CommonJS와 AMD 입니다.

이로써 자바스크립트의 모듈 시스템은 크게 CommonJS와 AMD 진영으로 나뉘게 되었고 브라우저 환경에서 모듈을 사용하기 위해서는 CommonJS 또는 AMD를 구현한 모듈 로더 라이브러리를 사용해야 하는 상황이 되었습니다.

자바스크립트 런타임 환경인 Node.js는 모듈 시스템의 사실상 표준인 COmmonJS를 채택했고 독자적인 진화를 거쳐, 현재는 CommonJS 사양과 100% 동일하지는 않지만 기본적으로 CommonJS 사양을 따르고 있습니다.

즉, Node.js는 ECMAScript 표준 사양은 아니지만 모듈 시스템을 지원합니다. 따라서 Node.js 환경에서는 파일별로 독립적인 파일 스코프(모듈 스코프)를 갖습니다.

두 가지 모두 ES2015가 등장하기 전까지 JavaScript에 기본적으로 존재하지 않는 모듈 시스템을 구현하는 방법입니다.

CommonJS는 동기식인 반면 AMD(Asynchronous Module Definition - 비동기식 모듈 정의)는 분명히 비동기식입니다.

CommonJS는 서버사이드 개발을 염두에 두고 설계되었으며, AMD는 모듈의 비동기 로딩을 지원하므로 브라우저용으로 더 많이 사용됩니다. AMD은 구문이 매우 장황하고, CommonJS은 다른 언어처럼 import 문을 작성하는 스타일에 더 가깝습니다.

대부분의 경우 AMD를 필요로 하지 않습니다.
모든 JavaScript를 연결된 하나의 번들 파일로 제공하면 비동기 로딩 속성의 이점을 누릴 수 없기 때문입니다.
또한 CommonJS 구문은 모듈 작성의 노드 스타일에 가깝고 클라이언트 사이드와 서버사이드 JavaScript 개발 사이를 전환할 때 문맥 전환 오버 헤드가 적습니다.

ES2015 모듈이 동기식 및 비동기식 로딩을 모두 지원하는 것이 반가운 것은 마침내 하나의 접근 방식만 고수할 수 있다는 점입니다.
브라우저와 노드에서 완전히 작동되지는 않지만, 언제나 트랜스파일러를 사용하여 코드를 변환할 수 있습니다.



24. Prettier가 무엇인가요?



25. Babel이란 무엇인가요?



20. 크롬 정도의 브라우저를 제외하곤 ES6 스펙에 대한 지원이 완벽하지 않다. 해결방법은 무엇인가



정규표현식의 유용한 패턴
#집합찾기 #반복찾기 #역참조 #조건달기
A 액티비티에서 B 액티비티로 데이터 전달하기
#WorkflowFoundation #InArgument #OutArugment #Variables
Microsoft UI Automation Framework 이해하기
#AutomationElement #TreeWalker #ControlPatterns
AppDomain 탐구
#AppDomain #격리 #어셈블리별도실행 #플러그인시스템
Chrome Extension 활용하여여 웹 페이지 XPath 정보 가져오기
#ChromeExtension #크롬확장프로그램 #XPath
Workflow 디자이너와 액티비티의 관계
#WorkflowFoundation #Designer #Activity #ModelItem
ExpressionTextBox와 ModelItem의 바인딩 관계
#WorkflowFoundation #ExpressionTextBox #ModelItem #Binding
Windows 레지스트리 간단 정리
#Windows #Registry #레지스트리
WPF MVVM 패턴, 그리고 Binding
#WPF #MVVM #Binding #Modle #View #ViewModel
오라클 SQL 성능 최적화 - 바인드 변수와 Shared Memory 이해하기
#Oracle #바인드변수 #SharedMemory #LibraryCache #SqlPlan
ActivityDesigner와 CodeActivity 이해하기
#WorkflowFoundation #ActivityDesigner #CodeActivity
Selenium Implicit vs Explicit - 웹 요소 기다리기
#Selenium #IWebDriver #Implicit #Explicit
.NET에서 Selenium 활용하기 - 3가지 실전 예제
#Selenium #ChromeDriver #FindElements
.NET에서 CommandBinding 활용하기
#.NET #CommandBinding #디자인패턴
워크플로우 파운데이션(Workflow Foundation) 소개
#WorkflowFoundation #소개 #기본개념
AWS SAA 준비 - (4) 비용에 최적화된 아키텍처 설계
(정리) Exam Readiness - AWS Solutions Architect Associate
AWS SAA 준비 - (3) 안전한 아키텍처
(정리) Exam Readiness - AWS Solutions Architect Associate
AWS SAA 준비 - (2) 성능이 뛰어난 아키텍처 설계
(정리) Exam Readiness - AWS Solutions Architect Associate
AWS SAA 준비 - (1) 복원력을 갖춘 아키텍처 설계
(정리) Exam Readiness - AWS Solutions Architect Associate
15분 안에 ToC를 구현해보자!
Vanilla JS로 Table of Contents 구현하기
모듈
모던 자바스크립트 Deep Dive | 48장 | 모듈
에러 처리
모던 자바스크립트 Deep Dive | 47장 | 에러 처리
제너레이터와 async/await
모던 자바스크립트 Deep Dive | 46장 | 제너레이터와 async/await
프로미스
모던 자바스크립트 Deep Dive | 45장 | 프로미스
REST API
모던 자바스크립트 Deep Dive | 44장 | REST API
Ajax
모던 자바스크립트 Deep Dive | 43장 | Ajax
비동기 프로그래밍
모던 자바스크립트 Deep Dive | 42장 | 비동기 프로그래밍
타이머
모던 자바스크립트 Deep Dive | 41장 | 타이머
Set과 Map
모던 자바스크립트 Deep Dive | 37장 | Set과 Map
디스트럭처링
모던 자바스크립트 Deep Dive | 36장 | 디스트럭처링
브라우저의 렌더링 과정
모던 자바스크립트 Deep Dive | 38장 | 브라우저의 렌더링 과정
스프레드 문법
모던 자바스크립트 Deep Dive | 35장 | 스프레드 문법
이터러블
모던 자바스크립트 Deep Dive | 34장 | 이터러블
7번째 데이터 타입 Symbol
모던 자바스크립트 Deep Dive | 33장 | 7번째 데이터 타입 Symbol
String
모던 자바스크립트 Deep Dive | 32장 | String
RegExp
모던 자바스크립트 Deep Dive | 31장 | RegExp
Date
모던 자바스크립트 Deep Dive | 30장 | Date
Math
모던 자바스크립트 Deep Dive | 29장 | Math
DOM
모던 자바스크립트 Deep Dive | 39장 | DOM
Number
모던 자바스크립트 Deep Dive | 28장 | Number
배열
모던 자바스크립트 Deep Dive | 27장 | 배열
이벤트
모던 자바스크립트 Deep Dive | 40장 | 이벤트
ES6 함수의 추가 기능
모던 자바스크립트 Deep Dive | 26장 | ES6 함수의 추가 기능
클래스
모던 자바스크립트 Deep Dive | 25장 | 클래스
this
모던 자바스크립트 Deep Dive | 22장 | this
빌트인 객체
모던 자바스크립트 Deep Dive | 21장 | 빌트인 객체
strict mode
모던 자바스크립트 Deep Dive | 20장 | strict mode
클로저
모던 자바스크립트 Deep Dive | 24장 | 클로저
프로토타입
모던 자바스크립트 Deep Dive | 19장 | 프로토타입
함수와 일급 객체
모던 자바스크립트 Deep Dive | 18장 | 함수와 일급 객체
실행 컨텍스트
모던 자바스크립트 Deep Dive | 23장 | 실행 컨텍스트
생성자 함수에 의한 객체 생성
모던 자바스크립트 Deep Dive | 17장 | 생성자 함수에 의한 객체 생성
프로퍼티 어트리뷰트
모던 자바스크립트 Deep Dive | 16장 | 프로퍼티 어트리뷰트
let, const 키워드와 블록 레벨 스코프
모던 자바스크립트 Deep Dive | 15장 | let, const 키워드와 블록 레벨 스코프
전역 변수의 문제점
모던 자바스크립트 Deep Dive | 14장 | 전역 변수의 문제점
스코프
모던 자바스크립트 Deep Dive | 13장 | 스코프
함수
모던 자바스크립트 Deep Dive | 12장 | 함수
원시 값과 객체의 비교
모던 자바스크립트 Deep Dive | 11장 | 원시 값과 객체의 비교
객체 리터럴
모던 자바스크립트 Deep Dive | 10장 | 객체 리터럴
타입 변환과 단축 평가
모던 자바스크립트 Deep Dive | 9장 | 타입 변환과 단축 평가
제어문
모던 자바스크립트 Deep Dive | 8장 | 제어문
연산자
모던 자바스크립트 Deep Dive | 7장 | 연산자
데이터 타입
모던 자바스크립트 Deep Dive | 6장 | 데이터 타입
표현식과 문
모던 자바스크립트 Deep Dive | 5장 | 표현식과 문
변수
모던 자바스크립트 Deep Dive | 4장 | 변수
Iteration와 Generator
코드스피츠 77 ES6+ 3화 참조
WHATWG 탄생 배경
WHATWG, W3C, HTML의 관련에 대한 역사
프론트엔드(FE) 면접 질문 정리
FE관련 면접 질문 및 답변 정리한 내용입니다.
쿠버네티스(kubernetes, k8s) 용어 정리
쿠버네티스(kubernetes, k8s) 용어 정리
젠킨스(Jenkins) 정리
젠킨스(Jenkins) 정리
Docker 용어 정리
Docker 용어 정리
Git 용어 정리
Git 용어 정리
반응형 웹 디자인(Responsive Web Design)
CSS responsive 에 대하여
JS this에 대하여
this에 대해 알아보자
SQL*PLUS에 대하여
SQL*PLUS 정의 및 사용방법
Oracle에서 SQL Plan 확인하기
Oracle에서 SQL Plan을 확인해보자