프론트엔드 면접 모아보기1
1. Sync, Async의 차이점(동기, 비동기의 차이점)에 대해서 설명해주세요.
Sync는 작업 요청이 이뤄지고, 요청 응답을 기다리는 것을 의미합니다. Async는 특정한 요청의 응답을 기다리지 않고 다음 작업을 수행하는 것을 의미합니다. 자바스크립트는 기본적으로 싱글스레드이기 때문에 요청된 작업을 하나씩 수행하지만 setTimeout이나 fetch과 같은 Web API를 사용하여 비동기로 처리할 수 있게 됩니다.
2. 자바스크립트의 동작 원리에 대해 설명해주세요.
자바스크립트는 자바스크립트 엔진 위에서 동작하는데요, 대표적으로 구글의 V8엔진이 있습니다. 자바스크립트 엔진은 메모리힙과 콜스택으로 구성되어 있습니다. 메모리 힙은 변수, 함수 등 메모리 할당이 이루어지는 공간입니다. 콜스택에는 자바스크립트 코드를 한 줄씩 읽으면서 수행할 작업들이 쌓이고, 작업이 수행되면 콜스택에서 제거됩니다. 자바스크립트는 싱글스레드이기 때문에 한번에 하나의 작업만 수행할 수 있습니다. 하지만 Web API를 이용하여 비동기로 작업을 수행할 수 있는데요, 콜스택에서 실행된 비동기 함수는 Web API를 호출하고, Web API는 콜백함수를 Task Queue(Callback Queue)에 넣습니다. 이벤트 Loop를 통해 콜스택과 태스크큐를 확인하여 콜스택에 있는 작업을 우선적으로 처리하고 이후, 태스크큐에 있는 작업을 콜스택에 넣어 처리하게 됩니다.
3. 클로저에 대해 설명해주세요.
클로저는 선언됐을때 그때의 렉시컬 스코프를 기억하는 함수입니다. 자바스크립트에서 모든 함수들을 Environment라는 프로퍼티를 가지는데 여기에 외부 함수의 변수의 참조값이 저장되어 외부 함수의 변수에 접근이 가능합니다.
4. 클로저의 단점과 해결방법에 대해 설명해주세요.
클로저는 외부환경의 변수를 계속 기억하고 있기 때문에 가비지컬랙터의 대상이 되지 않아 메모리 누수가 일어날 수 있다는 단점이 있습니다. 이때 null을 할당해줌으로써 메모리를 해제시킬 수 있습니다.
5. reflow와 repaint의 차이점에 대해 설명해주세요.
reflow와 repaint는 모두 렌더링과 관련이 있습니다.
화면이 리랜더링 됐을 때, 각 상황에 따라 reflow와 repaint가 일어나게 됩니다. reflow는 브라우저가 페이지의 레이아웃을 다시 계산하는 과정을 의미하고 repaint는 계산 결과를 바탕으로 화면에 다시 그리는 과정입니다.
reflow는 DOM의 구조가 변경되거나 요소의 크기나 위치가 변경될 때 일어납니다. repaint는 레이아웃은 그대로이고 색상이나 배경 등의 스타일만 변경되었을 때 일어납니다. 레이아웃을 다시 계산하는 reflow가 일어나면 repaint가 필연적으로 일어나기도 하고, reflow는 비용이 더 들기 때문에 레이아웃 계산이 다시 일어나지 않도록 관리하는 것이 중요합니다.
6. reflow가 다시 일어나지 않게 하려면 어떻게 해야하나요?
reflow를 유발하는 CSS 속성 사용을 최소화해야합니다. width, height, margin, padding, border 등의 속성은 요소의 레이아웃을 다시 계산하게 하기때문에 reflow를 일으킵니다. 미리 해당 속성 값을 설정해 초기 로드 시에만 계산이 이루어지도록 하고, 이후에는 변경하지 않는 것이 좋습니다.
7. 실행컨텍스트에 대해 설명해주세요.
실행컨텍스트는 자바스크립트에서 코드가 실행되는 환경을 의미합니다. 함수와 같이 자바스크립트 엔진이 코드를 실행할 때, 그 코드가 실행될 때의 환경을 정의하고 관리하기 위해 실행컨텍스트가 존재합니다.
실행컨텍스트는 자바스크립트가 처음 실행될 때 전역으로 먼저 생성되고, 함수가 호출될 때 역시 생성됩니다. 이러한 실행 컨텍스트는 생성될 때 콜스택에 쌓이게되며 함수가 종료되거나 프로그램이 종료될 때 사라지게 됩니다.
8. 실행컨텍스트는 어떤 구성 요소로 이루어져 있나요?
실행컨텍스트는 변수 객체와 스코프체인, this 로 구성되어 있습니다.
먼저 변수 객체는 실행 컨텍스트 내에서 사용되는 변수와 함수의 선언을 저장하는 공간입니다.
스코프 체인은 현재 실행 중인 컨텍스트와 외부 렉시컬 환경의 연결을 유지합니다. 따라서 변수를 참조할 때 현재 실행컨텍스트에서 찾지 못하면 스코프 체인을 통해 외부 환경에서 변수를 찾을 수 있습니다.
마지막으로 this는 실행 컨텍스트에 따라 참조하는 객체가 달라집니다.
이러한 구성 요소들을 통해 코드가 실행되는 동안의 환경을 관리하고 코드를 실행할 때 변수의 유효 범위나 함수 호출의 맥락을 결정 지을 수 있습니다.
9. 이미지 최적화 경험이 있던데 어떤 방식으로 진행되었는지 설명해주세요.(개인질문)
온라인 졸업전시 사이트를 운영하며 이미지 최적화를 진행했습니다. 20MB이상의 용량이 큰 이미지를 주로 사용하고 있던 졸업작품 사이트의 특성을 고려하여 사용자가 긴 로딩없이 빠르게 작품을 감상할 수 있도록 이미지 최적화를 진행했습니다.
먼저 파일 포맷을 변경하는 작업을 진행했습니다. webp 포맷을 사용하여 용량을 개선했는데요, webp 포맷은 구글에서 발표한 포맷으로 압축 효과가 좋아 많은 용량을 줄일 수 있기 때문에 png 포맷에서 webp로 변경하게 되었습니다. 그 결과 png 포맷일때보다 31%의 용량 개선이 있었습니다.
두번째로 이미지 사이즈가 실제 웹사이트에서 사용하는 것보다 1.5배정도 큰 사이즈로 사용되고 있어서 웹페이지에서 사용하는 최대 사이즈의 이미지로 맞추어 제공하였습니다. 이를 통해 추가적인 용량 개선을 이루었습니다.
마지막으로 AWS cloudfront에서 제공하는 CDN 기술을 이용하여 엣지 스테이션에 이미지 리소스를 캐싱하여 사용할 수 있도록 하였습니다. 이를 통해 사용자는 캐싱된 이미지를 더 빠르게 로딩할 수 있었습니다.
10. 이벤트루프에 대해 설명해주세요.
이벤트 루프는 자바스크립트 엔진이 비동기 작업을 처리할 수 있게 해주는 중요한 메커니즘입니다. 자바스크립트는 싱글스레드 기반으로 동작하기 때문에 모든 작업들은 하나씩 처리되고, 콜스택에 현재 실행 중인 코드들이 쌓이게 됩니다. 하지만 자바스크립트 fetch를 통해 데이터를 받거나 setTimeout 함수 등의 Web API를 사용하여 비동기 작업을 수행할 수 있습니다. 콜스택에 비동기 작업이 실행되면 비동기함수는 Wep API를 호출하고 Web API는 Callback Queue라고도 하는 Task Queue에 콜백함수를 넣습니다. 이벤트 루프는 콜스택과 태스크큐를 관리하며 콜스택에 있는 작업을 우선적으로 처리하고 콜스택이 비워지면 태스크큐에 있는 작업을 콜스택에 넣어 처리하는 방식으로 자바스크립트가 동작합니다.
11. 앞서 말씀하신 태스크 큐의 종류에는 무엇이 있나요?
태스크 큐는 매크로 태스크 큐와 마이크로 태스크 큐로 나뉩니다. 매크로 태스크 큐는 setTimeout, setInterval 과 같은 일반적인 비동기 작업들이 대기하는 큐입니다. 매크로 태스크 큐는 이벤트 루프가 콜스택과 마이크로 태스크 큐의 작업을 모두 처리한 후 하나씩 처리됩니다.
마이크로 태스크 큐는 Promise.then()과 같이 높은 중요도의 작업들이 대기하는 큐입니다. 마이크로 태스크 큐는 매크로 태스크 큐보다 우선순위가 높으며 콜스택이 비워져있으면 마이크로 태스크 큐의 작업들을 먼저 처리합니다.
정리하면, 태스크큐는 매크로 태스크 큐와 마이크로 태스크 큐로 이루어져 있으며, 마이크로 태스크 큐에 있는 작업들이가 매크로 태스크 큐보다 우선순위가 높아 먼저 처리됩니다.
12. 리액트의 props와 state에 대해 설명해주세요.
props는 부모컴포넌트에서 자식 컴포넌트로 전달하는 데이터로 전달된 데이터는 자식컴포넌트에서 수정이 불가능합니다. 이를 통해 컴포넌트 간에 데이터 흐름의 예측이 가능하고 데이터를 바꿀 수 없기때문에 컴포넌트를 재사용할 수 있습니다.
state는 컴포넌트 내에서 관리되는 데이터로 setState로 값을 변경할 수 있으며 값이 바뀔때마다 리랜더링이 이루어 집니다. 따라서 state가 변경되면 리랜더링을 통해 UI가 업데이트 됩니다.
13. HTTP 통신에 대해서 설명해주세요.
HTTP는 HyperText transfer protocol로 웹에서 정보를 주고받을 수 있는 프로토콜입니다. 그래서 클라이언트와 서버간에 통신을 가능하게 합니다. 클라이언트가 서버로 웹페이지나 데이터를 요청하면 서버는 클라이언트에게 요청받은 웹페이지나 데이터를 전송하게 됩니다.
14. HTTP의 stateless에 대해서 설명해주세요.
HTTP 통신은 stateless의 특징을 가지고 있습니다. stateless는 이전 요청의 결과, 즉 상태를 저장하고 있지 않음을 의미합니다. 따라서 모든 요청은 독립적인 특징을 가지고 있습니다.
15. HTTP 프로토콜의 request와 response 구조에 대해 설명해보세요.
HTTP request를 보낼때는 구조에 맞게 보내야 하는데, 먼저 start line에 http method가 들어가야 합니다. get, post, delete 등 어떤 요청인지를 나타내야 합니다. 그리고 header에 메타데이터를 넣어 요청에 필요한 데이터를 넣게 됩니다. body에는 요청시 들어갈 수도 있는 데이터를 넣어주게 됩니다. response에는 상태 코드가 넘어오게 됩니다. 200ok나 400error 등이 담겨져있고, header에는 역시 응답에 대한 메타데이터가 들어있습니다. body에는 요청에 대한 데이터가 담겨있습니다.
16. 브라우저 렌더링 파이프라인에 대해서 설명해주세요.
브라우저 렌더링 파이프라인은 브라우저가 웹페이지를 화면에 표시하기 위해 거치는 과정을 의미합니다. 저는 이 과정을 5단계로 나눠 설명해보겠습니다. 첫 번째로 DOM트리 생성 단계입니다. 브라우저는 HTML파일에서 받으면 이 파일을 바이트 단위로 읽고 문자로 변환 한 뒤 HTML토큰으로 변환합니다. 이후 토큰을 이용하여 DOM트리를 생성합니다. 두 번째로 DOM생성 CSS 파일을 파싱하여 CSSOM 트리를 생성합니다. 세 번째로 DOM과 CSSOM트리가 다 생성되면 이를 결합해 렌터 트리를 생성합니다. 렌더 트리에는 실제로 화면에 표시될 요소로만 구성됩니다. 네 번째로 레이아웃 단계입니다. 브라우저는 렌더 트리를 이용해 각 요소의 정확한 위치와 크기를 결정하는 레이아웃 단계를 진행합니다. 마지막으로 페인팅 단계입니다. 레이아웃이 완료되면 브라우저는 각 요소를 실제로 화면에 그리는 작업을 합니다.
브라우저 렌더링은 이렇게 5단계로 나눠 설명할 수 있습니다.
17. 자바스크립트 ES6에서 클래스는 무엇인가요?
클래스는 객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 일종의 틀로, 객체를 정의하기 위한 상태(멤버 변수)와 메서드(함수)로 구성됩니다. 그런데 ES6에서 클래스는 함수의 한 종류입니다. 그렇기 때문에, 함수와 동일하게 클래스 선언(Class declarations)과 클래스 표현(Class expressions)으로 클래스를 만들 수 있습니다.
18. hydrate란 무엇인지와 render와의 차이점을 설명해주세요.
hydrate함수는 생성된 HTML 콘텐츠에 자바스크립트 핸들러나 이벤트를 붙이는 역할을 합니다.
render와의 차이점은 다음과 같습니다. hydrate는 이미 렌더링된 HTML이 있다는 가정하에 이 렌더링된 HTML을 기준으로 이벤트를 붙이는 작업만 수행합니다. 하지만 render는 빈 HTML에 정보를 요소들을 렌더링하며 여기에 이벤트를 붙이는 작업까지 모두 한 번에 수행합니다.
19. 리액트의 render phase와 commit phase에 대해서 설명해주세요.
리액트의 랜더링 과정은 render phase과 commit phase로 나뉩니다.
render phase에서는 DOM에 그려질 요소들을 파악하는 단계입니다. 이때 재조정 과정을 거치게 됩니다. 재조정 과정에서 이전에 생성한 가상 DOM 트리와 새로 만든 가상 DOM 트리를 비교해서 실제 DOM 트리에 반영할 변경 사항을 파악합니다. 그리고 상태 업데이트가 발생한 컴포넌트를 호출해 새로운 가상 DOM트리를 만듭니다.
다음으로 commit phase에서는 render phase에서 진행한 두 가상 DOM트리의 변화를 실제 DOM에 적용하는 단계입니다.
요약해서 render phase는 변경된 사항을 파악하는 단계이고, commit phase는 변겅된 사항을 실제 DOM에 적용하는 단계입니다.
20. <script scr=“”></script>코드는 <head>태그와 <body>태그 중에 어디에 들어가는 것이 좋은 것 같은지 본인의 생각을 말해주세요.
자바스크립트 파일의 크기와 사용성에 따라 다를 수 있지만 파일의 크기와 사용성이 비슷하다면 <body>태그 제일 하단에 들어가는 것이 좋습니다. 렌더링 엔진은 HTML을 읽어 DOM을 생성합니다. 생성중 script 태그를 만나게 되면 코드 파싱 제어권이 렌더링 엔진에서 자바스크립트 엔진으로 넘어가게 됩니다. (이를 blocking이 일어났다고도 합니다) 이후에 자바스크립트 파싱과 실행이 종료되면 다시 렌더링 엔진으로 제어권이 넘어가 HTML 파싱이 중단된 시점부터 다시 DOM 생성을 시작합니다.
결국 <script scr=“”></script>코드를 만나게 되면 위에서 아래로 동기적으로 이루어지던 파싱이 중단된다는 의미이고 블로킹되는 것은 DOM 생성을 지연시킬 수 있습니다. 또한 script 내부에서 특정 요소를 불러오는 코드가 존재한다면 아직 HTML 요소가 만들어지지 않았기 때문에 오류가 발생할 수 있습니다.
21. 힙에 대해 설명해주세요.
힙은 동적 메모리 할당에 사용되며, 프로그램 실행 중에 메모리 크기가 결정됩니다. 힙에 할당된 메모리는 개발자가 직접 관리해야 하며, 사용이 끝난 메모리는 명시적으로 해제해야 합니다.
22. CI/CD에 대해 설명해주세요.
"지속적인 통합/지속적인 서비스 제공 또는 배포 CI(Continuous Integration)/CD(Continuous Delivery, Continuous Deployment)"의 약자입니다. `지속적인 통합(CI)`은 코드 변경사항을 정기적으로 빌드 및 테스트를 거쳐 공유 레포지토리에 통합하는 것을 의미합니다. 협업에서 발생할 수 있는 conflict를 수시로 확인하고 해결이 가능하며, 새로운 업데이트의 테스트와 출시 시간을 단축시킬 수 있습니다. `지속적인 서비스 제공 또는 배포(CD)`는 코드 변경사항이 레포지토리뿐만 아니라 사용자 production 환경까지 release 되는 것을 의미합니다.
23. useEffect 사용 시 의존성 배열에 빈 배열을 넣는 것을 지양해야 하는 이유는 무엇일까요?
useEffect는 의존성 배열로 전달한 값의 변경에 의해 실행되야 하는 훅입니다. 그러나 의존성 배열에 값을 전달하지 않고 단순히 최초 렌더링 때 한 번 실행하도록 한다면 이 콜백 함수로 인해 발생하는 부수 효과가 실제로 관찰해서 실행돼야 하는 값과는 별개로 작동한다는 것을 의미하기 때문에 빈 배열을 넣는 것은 useEffect 훅의 취지와 맞지 않습니다.
24. 자바스크립트 배열에 대해서 설명해주세요.
자바스크립트의 배열은 순서가 있는 리스트 형태의 배열입니다. 따라서 여러 값을 하나의 자료구조에 저장할 수 있습니다. 자바스크립트 배열은 동적 배열이기 때문에 크기를 미리 지정해 놓지 않아도 되며, 요소를 자유롭게 추가하거나 제거할 수 있습니다. 요소를 추가할 때마다 배열의 크기가 자동으로 조절되는 방식으로 동작합니다.
또한 배열은 자바스크립트의 객체와 유사한 방식으로 관리됩니다. 해시 테이블과 같은 형태로 구현되어 있어, 배열 요소들은 메모리 상에서 연속적이지 않아도 되고, 배열 크기를 미리 지정하지 않아도 사용할 수 있습니다. 마지막으로 내장된 메소드를 사용하여 배열을 쉽게 조작할 수 있습니다. 예를 들어 reduce, map 등의 메소드가 존재합니다.
정리하면, 자바스크립트 배열은 동적 배열로 요소를 추가하거나 제거할 때 배열 크기가 자동적으로 조정되며, 여러 내장 메소드를 통해 배열을 쉽게 조작할 수 있습니다.