티스토리 뷰

Web/Frontend

프론트엔드 개발자 기술 면접 질문 정리

코딩잘하고있어 2025. 4. 20. 18:17

1. JavaScript & TypeScript

클로저(Closure)에 대해 설명해 주세요

클로저는 함수가 생성될 때 외부 스코프의 변수를 기억하는 기능입니다. 즉, 외부 함수의 실행 컨텍스트가 종료되어도 내부 함수가 그 변수를 참조할 수 있게 해줍니다.

function outer() {
  let counter = 0;
  return function () {
    counter++;
    console.log(counter);
  };
}

const count = outer(); // outer 실행되어 counter 캡처
count(); // 1
count(); // 2

 

이처럼 클로저를 사용하면 counter 변수는 외부 함수가 종료된 후에도 유지됩니다. 이러한 구조는 함수 내부에서 상태를 캡슐화하거나 유지해야 할 때, 혹은 이벤트 핸들러나 비동기 처리에서 변수 값을 유지해야 할 때 매우 유용합니다.

JavaScript 동작 과정에서 콜스택, 콜백 큐, Web API 등의 역할을 설명해 주세요

순서대로 설명을 드리겠습니다.

콜스택이란 함수 실행 순서를 저장하는 스택이고, Web API란  setTimeout, DOM 이벤트, fetch 등이 등록되는 것입니다.

또한, 콜백 큐란 Web API가 끝나고 등록된 콜백을 담는 큐입니다.

JavaScript는 싱글 스레드 언어이기 때문에, 한 번에 한 가지 작업만 수행할 수 있습니다.
비동기 작업은 Web API 영역에서 실행되고, 완료된 콜백은 콜백 큐에 들어갑니다.
이벤트 루프는 콜스택이 비어있는지 확인하고, 콜백 큐에서 작업을 하나씩 꺼내 실행합니다. 이 구조 덕분에 JavaScript는 블로킹 없이 비동기 처리를 할 수 있습니다.

가비지 컬렉션(Garbage Collection) -> JavaScript에서는 메모리를 어떻게 자동으로 해제하나요?

자바스크립트는 도달할 수 없는(unreachable) 객체를 자동으로 제거합니다. 즉, 어떤 변수도 참조하지 않으면 GC가 메모리를 해제합니다.

호이스팅이란 무엇인가요?

변수나 함수 선언이 스코프 상단으로 끌어올려지는 현상입니다.

var 같은 경우엔, undefined가 뜨게 되고요. const나 let 같은 경우엔 TDZ 때문에 참조 전 사용이 불가합니다.

함수 선언식은 전체 코드에서 접근 가능하지만, 함수 표현식은 호이스팅 시 undefined가 되어 에러가 발생할 가능성이 있습니다.

JavaScript 데이터 타입 - 원시 타입(Primitive)과 참조 타입(Reference)의 차이

원시 타입이란 값 자체를 저장하며, 변경 불가능한 특징을 가집니다.

  • number, string, boolean, null, undefined, symbol, bigint가 있습니다.
  • 비교 시 값 자체를 비교합니다.

참조 타입이란 값이 저장된 메모리 주소를 저장하며, 객체 구조를 가진 타입입니다.

  • object, array, function 등이 있습니다.
  • 변수에는 실제 값이 아니라, 메모리 주소가 저장됩니다. 그래서 비교 시 참조를 비교하므로, 서로 다른 객체는 내용이 같아도 같지 않다고 판단합니다.

Typescript 유틸리티 타입에 대해 설명해 주세요

Partial<T>   // 모든 속성을 선택적으로
Pick<T, K>   // T에서 K 속성만 선택
Omit<T, K>   // T에서 K 속성을 제외
Readonly<T> // T의 모든 속성을 읽기 전용으로

2. 브라우저 동작 원리

Stacking Context란 무엇인가요? 

stacking context는 요소의 z-index가 다른 요소와 비교될 수 있는 렌더링 계층입니다. 새로운 stacking context는 position, z-index, opacity, transform 등의 속성에 의해 생성됩니다.

  • z-index가 1과 5인데, 왜 5가 아래에 있을 수 있나요?
    • z-index는 같은 stacking context 안에서만 비교되며, 다른 context에 속해 있으면 부모 stacking context의 순서에 따라 달라질 수 있습니다.
    • 아래와 같이 child1이 z-index가 999 더라도, parent2가 더 높은 stacking context를 가지므로 child2가 위에 표시될 수 있습니다.
.parent1 {
  position: relative;
  z-index: 1;
}
.child1 {
  position: relative;
  z-index: 999;
}

.parent2 {
  position: relative;
  z-index: 2;
}
.child2 {
  position: relative;
  z-index: 1;
}

캐시에 대해 설명해 주세요

캐시는 반복된 요청에 대해 빠르게 응답하기 위한 임시 저장소입니다.

  • 지역성(Locality)이란 무엇인가요?
    • 지역성이란 공간적 지역성과 시간적 지역성으로 나뉘게 됩니다. 공간적 지역성은 인접한 데이터는 함께 사용될 가능성이 높다는 뜻이고, 시간적 지역성은 최근 사용된 데이터는 곧 다시 사용될 가능성이 높다는 것입니다.
  • 시간적 지역성에서 "가까운 미래에 접근 가능성"은 어떻게 판단하나요?
    • 자주 접근되는 데이터는 메모리나 브라우저 캐시에 남겨두고 LRU 등의 알고리즘으로 교체합니다.
    • LRU 알고리즘이란? 가장 오래 사용되지 않은 데이터를 먼저 제거하는 방식입니다. 브라우저는 이를 활용해 메모리 부담을 줄이면서도 자주 접근하는 데이터는 빠르게 제공할 수 있도록 합니다.
  • 웹 캐시에서 no-cache와 no-store의 차이
    • no-cache는 캐싱은 하지만 매 요청마다 서버에 재검증을 합니다. no-store의 경우엔 아예 저장하지 않습니다. 보안 민감 정보에 사용됩니다.
  • ETag에 대해 아시나요?
    • 서버가 리소스 버전을 식별하기 위해 부여한 고유 식별자입니다. 클라이언트는 ETag를 저장했다가 이후 요청 시 함께 보내고, 서버는 변경 여부를 판단해 304 Not Modified를 반환할 수 있습니다.

브라우저에 네이버 주소를 입력 후 엔터를 치면 일어나는 일

1. 브라우저가 주소창에 입력된 도메인을 DNS 서버를 통해 IP 주소로 변환합니다.

2. IP 주소를 바탕으로 TCP 연결(3-way handshake)을 설정합니다.

3. HTTP 요청을 전송하고, 서버 응답을 받습니다. (HTML, CSS, JS 등)

4. 브라우저는 HTML을 파싱하며 DOM 트리를 구성하고, CSS 파싱을 통해 CSSOM을 만듭니다.

5. DOM + CSSOM을 결합하여 렌더 트리를 구성합니다.

6. 레이아웃 계산 -> 페인팅 -> 컴포지팅 -> GPU 렌더링을 거칩니다.

7. 최종 화면을 렌더링 합니다.

DOM 생성부터 화면 렌더링까지의 과정 설명

1. HTML을 파싱 하여 DOM 트리를 생성합니다.

2. CSS를 파싱하여 CSSOM 트리를 생성합니다.

3. 위 두 트리를 결합하여 렌더 트리를 생성합니다.

4. 레이아웃을 계산하여 페인트, 컴포지트, GPU를 차례대로 렌더링 합니다.


3. 프론트엔드 프레임워크

Vue.js도 프레임워크가 있는 걸로 알고 있는데 사용해 보셨나요?

Vue 생태계의 SSR 프레임워크인 Nuxt.js가 있는 걸로 알고 있습니다.

  • Nuxt.js는 라이브러리인가요?
    • Nuxt는 Vue 기반의 SSR 프레임워크로, 단순한 라이브러리 이상의 역할을 합니다. 설정을 최소화하고 구조화된 프로젝트 설계를 도와주는 점에서 프레임워크에 가깝습니다. 
    • 파일 기반 라우팅이며, 서버 사이드 렌더링을 하고, 자동 코드를 분할하는 기능이 있습니다.

React의 useEffect 훅에 대해 설명해 주세요

useEffect는 컴포넌트가 렌더링 된 이후에 부수 효과를 수행할 때 사용하는 훅입니다.

useEffect(() => {
  const id = setInterval(() => {
    console.log("1초마다 실행");
  }, 1000);

  return () => clearInterval(id); // 언마운트 시 정리
}, []);

예를 들어, 위 코드는 setInterval로 주기적인 작업을 설정하고, 컴포넌트가 언마운트될 때 정리합니다.

그리고 의존성이 변경될 때 정리 로직을 실행합니다.

useEffect는 네트워크 요청, DOM 조작, 타이머 설정 등을 다룰 때 사용됩니다.


4. 웹 개발 일반

CSS 선택자 우선순위(Specificity)란 무엇인가요?

우선순위 순서를 알려드리겠습니다.

 

  1. 인라인 스타일 (1000점)
  2. ID 선택자 (100점)
  3. 클래스/속성/가상 클래스 (10점)
  4. 태그/요소 선택자 (1점)
!important는 모든 우선순위보다 강합니다.

컴파일러와 인터프리터의 차이를 설명해 주세요

컴파일러는 전체 코드를 한 번에 분석 및 번역하여 실행파일을 생성합니다. 예) C, C++

인터프리터의 경우는 코드를 한 줄씩 해석하며 즉시 실행합니다. 예) JavaScript, Python