프론트엔드 엔지니어 면접 가이드
프론트엔드 면접은 프레임워크 상식 이상을 검증합니다. 브라우저를 어떻게 추론하고, UI 상태를 어떻게 구성하며, 접근성 높고 성능 좋은 인터페이스를 어떻게 출시하는지를 살핍니다. 아래 질문들은 렌더링 내부부터 실전 컴포넌트 구축까지 팀이 실제로 묻는 내용을 반영합니다.
면접관이 평가하는 것
JavaScript 기초
클로저, 이벤트 루프, 프로미스/async, 프로토타입, `this` 바인딩.
프레임워크 깊이
React(또는 Vue/Angular)의 렌더링, 재조정, 훅, 상태 관리.
CSS와 레이아웃
Flexbox/grid, 캐스케이드, 쌓임 맥락, 반응형 디자인.
성능
크리티컬 렌더링 경로, 번들 크기, 지연 로딩, Core Web Vitals.
접근성
시맨틱 HTML, ARIA, 키보드 내비게이션, 스크린 리더 지원.
프론트엔드 엔지니어 면접 질문 예시
- 기술 면접브라우저 이벤트 루프와 마이크로태스크가 매크로태스크와 어떻게 다른지 설명하세요.좋은 답변이 다루는 것
- 이벤트 루프 구조
- 매크로태스크 vs 마이크로태스크 큐 우선순위
- 실행 순서 예시 (setTimeout, Promise)
- 브라우저 렌더링과의 관계
- requestAnimationFrame의 위치
샘플 답변 보기
브라우저 이벤트 루프는 싱글 스레드에서 비동기 작업을 처리하는 핵심 메커니즘입니다. 이벤트 루프는 매크로태스크 큐와 마이크로태스크 큐를 관리하며, 각 매크로태스크가 끝날 때마다 마이크로태스크 큐를 전부 처리합니다. 매크로태스크에는 setTimeout, setInterval, I/O, UI 렌더링 이벤트 등이 포함되고, 마이크로태스크에는 Promise의 then/catch/finally, queueMicrotask, MutationObserver 등이 속합니다. 중요한 차이는 마이크로태스크가 다음 매크로태스크가 실행되기 전에 모두 처리되며, 매크로태스크 하나당 한 번의 렌더링 기회가 주어진다는 점입니다. 예를 들어, setTimeout 콜백 안에서 Promise를 resolve하면 해당 then 핸들러는 같은 매크로태스크 내에서 실행됩니다. 반면 requestAnimationFrame은 렌더링 직전에 실행되는 별도의 태스크로 간주됩니다. 흔한 실수는 setTimeout(fn, 0)을 사용해도 이전 마이크로태스크가 모두 끝나기 전에는 실행되지 않는다는 점을 간과하는 것입니다. 이를 이해하면 DOM 업데이트를 비동기로 안전하게 처리할 수 있습니다.
- 기술 면접React에서 재렌더링을 유발하는 것은 무엇이며, 불필요한 재렌더링을 어떻게 막나요?좋은 답변이 다루는 것
- setState 호출 시 재렌더링
- 부모 리렌더링 시 자식도 리렌더링
- useMemo, useCallback, React.memo 사용법
- key prop의 역할
- 불변성 유지의 중요성
샘플 답변 보기
React에서 재렌더링은 주로 state가 변경되거나 부모 컴포넌트가 리렌더링될 때 발생합니다. setState를 호출하면 해당 컴포넌트와 그 자식들이 기본적으로 모두 리렌더링됩니다. 불필요한 재렌더링을 막기 위해 React.memo로 컴포넌트를 감싸면 props가 변경되지 않았을 때 리렌더링을 건너뜁니다. 함수나 객체가 props로 전달될 때는 useCallback과 useMemo로 참조를 고정해야 React.memo가 제대로 동작합니다. 또한 리스트를 렌더링할 때 안정적인 key prop을 제공하면 React가 엘리먼트를 재사용할 수 있어 불필요한 DOM 조작을 줄입니다. 상태 끌어올리기를 적절히 사용하여 불필요한 상태를 하위 컴포넌트로 내리지 않는 것도 중요합니다. React.StrictMode나 개발자 도구의 Profiler를 활용하여 실제로 리렌더링이 발생하는 컴포넌트를 확인하는 습관을 들이면 좋습니다. 가장 흔한 실수는 인라인 함수나 객체를 props로 전달하면서 React.memo를 사용하는 것으로, 이 경우 매번 새로운 참조가 생성되어 메모이제이션이 무용지물이 됩니다.
- 기술 면접CSS 캐스케이드가 충돌하는 규칙을 어떻게 해결하는지 설명하세요.좋은 답변이 다루는 것
- 명시도(Specificity) 계산 규칙
- !important 예외
- 소스 순서의 역할
- 상속과 초기값
- 리셋 CSS 필요성
샘플 답변 보기
CSS 캐스케이드는 충돌하는 규칙을 해결할 때 명시도, 중요도, 소스 순서를 고려합니다. 명시도는 인라인 스타일, ID 선택자, 클래스/속성/의사 클래스 선택자, 요소/의사 요소 선택자 순으로 계산되며, 각 레벨의 개수를 숫자로 비교합니다. 예를 들어 #header .nav a는 명시도가 (0,1,1,1)이고, .nav a는 (0,0,1,1)이므로 전자가 우선합니다. !important가 선언되면 다른 모든 선언을 무시하고 우선하지만, 같은 !important끼리는 다시 명시도 비교를 합니다. 동일한 명시도라면 나중에 선언된 스타일이 적용됩니다. 상속되는 속성(예: color, font-family)은 명시도가 0인 선택자보다 우선하지 않지만, 명시적으로 상속을 받으면 부모의 계산값을 가져옵니다. 브라우저 기본 스타일(User Agent)보다는 개발자 스타일이 우선하지만, Normalize CSS를 사용하면 브라우저 간 일관성을 높일 수 있습니다. 흔한 실수는 !important를 남용하거나 명시도 계산을 잘못하여 예상치 못한 스타일이 적용되는 것입니다. 명시도를 낮게 유지하고 BEM 같은 네이밍 컨벤션으로 충돌을 미리 방지하는 것이 좋습니다.
- 코딩debounce 함수를 구현하고 언제 사용하는지 설명하세요.좋은 답변이 다루는 것
- 클로저와 타이머 활용
- 즉시 실행과 지연 실행 선택
- this 컨텍스트 처리
- 취소 기능 구현
- 사용 예: 검색, 리사이즈
샘플 답변 보기
Debounce는 연속된 호출 중 마지막 호출만 일정 시간 후에 실행되도록 하는 기법입니다. 보통 입력 필드의 자동완성이나 창 리사이즈 이벤트 처리에 사용됩니다. 아래 구현은 leading 옵션을 선택적으로 받아 처음 호출을 즉시 실행할 수도 있게 했습니다. 반환된 함수는 내부에 타이머 ID를 클로저로 유지하며, 각 호출 시 이전 타이머를 취소하고 새 타이머를 설정합니다. 이를 통해 사용자가 입력을 멈춘 후에만 API 호출이 발생하도록 제어할 수 있습니다. 실제 사용 시에는 debounce 함수가 반환한 함수를 이벤트 핸들러로 등록합니다. 주의할 점은 this 바인딩이 원래 함수를 감싸기 때문에 화살표 함수를 사용하거나 apply로 전달해야 하며, 취소 기능을 제공하면 컴포넌트 언마운트 시 타이머를 정리할 수 있습니다. 시간 복잡도는 호출 시 O(1)이고, 메모리는 타이머 하나만 유지하므로 O(1)입니다.
- 코딩키보드를 지원하는 접근성 높은 자동완성 컴포넌트를 만드세요.좋은 답변이 다루는 것
- ARIA 역할과 속성
- 키보드 네비게이션 (Tab, Arrow, Enter, Escape)
- 포커스 관리
- 실시간 결과 목록
- 로딩/에러/빈 상태 처리
샘플 답변 보기
아래는 React로 작성된 접근성 높은 자동완성 컴포넌트입니다. <input>에 role="combobox", aria-autocomplete="list", aria-expanded, aria-activedescendant를 설정하여 스크린 리더가 상태를 인지할 수 있게 했습니다. 결과 목록은 role="listbox"와 각 항목에 role="option"을 부여했습니다. 키보드 이벤트를 처리하여 Arrow Up/Down으로 선택 항목을 이동하고, Enter로 선택, Escape로 목록을 닫습니다. 또한 포커스가 입력창에 유지되도록 하고, 선택된 항목이 있으면 aria-activedescendant로 현재 활성 옵션을 가리킵니다. 결과 목록의 위치는 절대 위치(position: absolute)로 입력창 아래에 배치하고, 로딩 중에는 aria-busy를 true로 설정합니다. 검색어가 없거나 에러가 발생했을 때도 적절한 aria-live 영역을 통해 알립니다. 컴포넌트가 언마운트될 때 debounce 타이머를 정리하고, 포커스를 트랩하지 않도록 주의해야 합니다.
- 시스템 설계실시간 공동 편집 문서 에디터의 프론트엔드 아키텍처를 설계하세요.좋은 답변이 다루는 것
- OT와 CRDT 비교
- 로컬 상태와 서버 상태 분리
- 오퍼레이션 전송 및 적용 순서
- 충돌 해결 전략
- 커서 및 선택 공유
샘플 답변 보기
실시간 공동 편집 문서 에디터의 프론트엔드 아키텍처는 OT(Operational Transformation) 또는 CRDT(Conflict-free Replicated Data Types)를 기반으로 설계합니다. CRDT는 최근 더 선호되는 접근법으로, Yjs나 Automerge 같은 라이브러리를 사용할 수 있습니다. 프론트엔드는 로컬 상태(로컬 문서)와 서버 상태(원격 문서)를 분리하고, 웹소켓을 통해 오퍼레이션을 주고받습니다. 각 오퍼레이션은 타임스탬프나 버전 벡터로 순서를 결정하고, 충돌이 발생하면 CRDT의 병합 규칙에 따라 자동으로 해결됩니다. 커서와 선택 범위는 별도의 채널(예: Awareness 프로토콜)로 공유하며, 동시 편집자들의 커서를 실시간으로 표시합니다. 성능을 위해 변경 내용을 배치 처리하고, Undo/Redo 스택은 로컬 오퍼레이션만 관리합니다. 보안 측면에서 클라이언트의 오퍼레이션을 서버에서 검증하고, 권한이 없는 편집을 차단해야 합니다. 일반적인 함정은 모든 오퍼레이션을 서버에 중계할 때 지연 시간이 길어지면 로컬 반영과 충돌할 수 있다는 점이므로, 낙관적 업데이트와 로컬 머지를 적용하는 것이 좋습니다.
- 행동 면접느린 페이지의 성능을 개선한 경험을 말해 주세요.좋은 답변이 다루는 것
- 문제 진단 도구 (Lighthouse, Performance 탭)
- 병목 현상 식별
- 적용한 개선 기법 (코드 분할, 이미지 최적화, 캐싱)
- 측정 지표 (FCP, LCP, TTI)
- 결과 및 배운 점
샘플 답변 보기
제가 경험한 사례는 대시보드 페이지의 초기 로딩 속도가 8초에 달했던 프로젝트입니다. 먼저 Lighthouse와 Chrome DevTools Performance 탭으로 분석한 결과, 거대한 번들 파일(2MB)과 최적화되지 않은 이미지, 그리고 불필요한 API 호출이 주요 병목이었습니다. 개선 조치로는 Webpack의 코드 분할을 적용하여 라우트 기반으로 번들을 나누었고, 이미지는 WebP 포맷으로 변환하고 lazy loading을 적용했습니다. 또한 데이터를 캐싱하고, API 호출을 병렬화하여 폭포수 현상을 줄였습니다. 결과적으로 FCP가 1.8초, LCP가 2.5초로 개선되었고, TTI는 3초 이내로 단축되었습니다. 이 과정에서 중요한 것은 실제 사용자 환경을 고려한 측정이었고, 개선 후에 3G 네트워크와 저사양 기기에서도 테스트를 진행했습니다. 또한 팀 내에 성능 예산을 도입하여 앞으로의 변경이 성능에 미치는 영향을 지속적으로 모니터링했습니다. 이 경험을 통해 성능은 기능 개발과 동등하게 중요한 요구사항임을 깨달았습니다.
- 행동 면접UX 트레이드오프를 두고 디자이너와의 의견 차이를 어떻게 다루나요?좋은 답변이 다루는 것
- 디자이너와의 협업 과정
- 트레이드오프 명확히 하기
- 데이터 기반 논의
- 대안 제시
- 타협점 찾기
샘플 답변 보기
디자이너와 UX 트레이드오프에 대해 의견 차이가 있을 때는 먼저 서로의 우선순위를 이해하려고 노력합니다. 예를 들어, 한 번의 클릭으로 모든 정보를 보여주는 디자인이 데이터 로딩 시간을 3초 증가시켰던 사례가 있습니다. 저는 디자이너에게 실제 사용자 테스트 결과와 네트워크 지연 데이터를 제시하며 로딩 시간이 사용자 이탈률에 미치는 영향을 설명했습니다. 그런 다음, 처음에는 요약 정보만 보여주고 '자세히 보기' 버튼을 통해 추가 정보를 로드하는 점진적 공개(Pogressive Disclosure) 방식을 제안했습니다. 디자이너는 사용자가 더 많은 정보를 원할 때만 로딩이 발생한다는 점에 동의했고, 최종적으로 두 가지 뷰를 모두 제공하는 하이브리드 방식으로 합의했습니다. 중요한 것은 디자이너의 의도를 존중하면서도 기술적 제약과 사용자 경험 데이터를 객관적으로 전달하는 것입니다. 항상 '아니오'보다는 '다른 방법으로 가능합니다'라는 대안을 제시하는 것이 협업을 원활하게 합니다.
연차에 따른 차이
준비 방법
- 렌더링 경로를 소리 내어 설명하세요 — 면접관은 답뿐 아니라 추론을 채점합니다.
- 명시적으로 묻지 않더라도 접근성과 성능을 항상 언급하세요.
- IDE 자동완성 없이 컴포넌트 하나를 처음부터 끝까지 만드는 연습을 하세요.
자주 묻는 질문
프론트엔드 면접에서 흔한 코딩 문제는?
DOM 조작, debounce/throttle 같은 유틸리티 함수, 자동완성이나 모달 같은 작은 인터랙티브 컴포넌트 구축이 나옵니다.
프론트엔드 면접에 시스템 설계가 포함되나요?
미들·시니어 레벨에서는 그렇습니다. 보통 백엔드 인프라가 아니라 피드, 디자인 시스템, 공동 편집기 같은 프론트엔드 중심 설계입니다.
프론트엔드 면접을 빠르게 준비하려면?
JavaScript 기초를 다지고, 컴포넌트 몇 개를 처음부터 만들며, 시간 제한 모의 면접으로 압박 속에서 추론을 설명할 수 있게 하세요.
프론트엔드 엔지니어 질문을 AI의 즉각적인 피드백으로 연습
Offersly는 당신의 이력서와 목표 직무에 맞춘 모의 면접을 진행하고, 모든 답변을 관련성·깊이·명확성·정확성으로 채점합니다.