React 미드레벨 코딩 및 알고리즘 면접

React 미드레벨 (3~7년) 코딩 · 알고리즘 5문항 조회수 96 · 2026-07-02 (목) 03:11:02
1 React 성능 최적화
Medium

Q. React 컴포넌트에서 무한 스크롤을 구현할 때, 스크롤 이벤트 핸들러가 과도하게 호출되어 성능 문제가 발생합니다. throttle과 debounce의 차이를 설명하고, 무한 스크롤 구현에는 어느 것이 더 적합한지, 그리고 Custom Hook으로 추상화할 때 클린업 처리를 어떻게 해야 하는지 설명해주세요.

A. 모범답안

throttle은 일정 시간 간격으로 함수를 실행하고, debounce는 마지막 호출 후 일정 시간이 지나야 실행합니다. 무한 스크롤에는 throttle이 적합한데, 스크롤 중에도 주기적으로 위치를 체크해야 추가 데이터를 로드할 수 있기 때문입니다. Custom Hook에서는 useEffect의 cleanup 함수에서 타이머를 clear해야 하며, useRef로 타이머 ID를 저장하여 컴포넌트 언마운트 시 메모리 누수를 방지해야 합니다. 또한 throttle 간격은 보통 100-200ms가 적절하며, 너무 짧으면 성능 이점이 없고 너무 길면 사용자 경험이 저하됩니다.

핵심 포인트
  • • throttle은 일정 간격 실행, debounce는 마지막 호출 후 대기
  • • 무한 스크롤은 연속적 체크가 필요하므로 throttle 사용
  • • useRef로 타이머 ID 저장 및 cleanup에서 clearTimeout
  • • 적절한 throttle 간격 설정(100-200ms)
Follow-up 질문

React 18의 useDeferredValue나 useTransition을 활용하여 무한 스크롤의 성능을 더 개선할 수 있는 방법이 있을까요?

2 알고리즘 및 자료구조
Hard

Q. React에서 태그 입력 컴포넌트를 구현할 때, 중복 태그 체크와 빠른 검색을 위해 Set을 사용하기로 했습니다. 그런데 태그의 순서도 유지해야 하고, 특정 위치의 태그를 삭제하거나 삽입하는 기능도 필요합니다. Set과 Array를 함께 사용하는 하이브리드 접근법의 장단점과, 각 연산(추가, 삭제, 중복체크, 순서변경)의 시간 복잡도를 분석하고 최적화 방안을 제시해주세요.

A. 모범답안

Set과 Array를 동시에 유지하는 방식은 중복 체크는 O(1)로 빠르지만, 두 자료구조를 동기화해야 하는 오버헤드가 있습니다. 추가 시 Set.has()로 중복 체크 후 Array.push()와 Set.add()를 모두 수행하면 O(1)이고, 삭제 시 Array.splice()는 O(n), Set.delete()는 O(1)입니다. 대안으로 Map을 사용하여 태그를 key로, 인덱스를 value로 저장하면 순서 정보도 함께 관리할 수 있습니다. 또는 단순히 Array만 사용하고 중복 체크 시 Array.includes()를 사용하되, 태그 개수가 적다면(100개 이하) O(n) 복잡도도 실용적입니다. 실무에서는 태그 개수가 보통 수십 개 이하이므로 Array만 사용하는 것이 코드 복잡도 측면에서 더 나을 수 있습니다.

핵심 포인트
  • • Set+Array 하이브리드는 중복체크 O(1), 동기화 오버헤드 존재
  • • 삭제는 Array.splice() O(n), Set.delete() O(1)
  • • Map으로 태그-인덱스 매핑도 가능
  • • 실무에서는 태그 개수가 적어 Array만으로도 충분한 경우 많음
Follow-up 질문

만약 태그가 수천 개까지 늘어날 수 있는 상황이라면 어떤 자료구조와 알고리즘을 선택하시겠습니까?

3 React 리팩토링
Medium

Q. 컴포넌트에서 여러 개의 boolean 상태(isLoading, isError, isSuccess, isEmpty)를 각각 useState로 관리하고 있는데, 상태 전환 시 여러 setState를 순차적으로 호출하다 보니 중간 상태가 발생하여 UI가 깜빡이는 문제가 있습니다. 이를 단일 상태 머신으로 리팩토링하는 방법과, TypeScript의 discriminated union을 활용하여 타입 안정성을 확보하는 방법을 설명해주세요.

A. 모범답안

여러 boolean을 단일 status 상태로 통합하여 'idle', 'loading', 'success', 'error', 'empty' 같은 문자열 리터럴로 관리하면 상태 전환이 원자적으로 일어나 중간 상태를 방지할 수 있습니다. TypeScript에서는 type Status = { status: 'loading' } | { status: 'error', error: Error } | { status: 'success', data: Data } 같은 discriminated union을 사용하면, status 값에 따라 error나 data 속성의 존재가 타입 레벨에서 보장됩니다. useReducer와 함께 사용하면 상태 전환 로직을 명확히 정의할 수 있고, 불가능한 상태 조합(isLoading과 isSuccess가 동시에 true)을 원천적으로 방지할 수 있습니다. 이 패턴은 XState 같은 상태 머신 라이브러리의 기본 원리이기도 합니다.

핵심 포인트
  • • 여러 boolean을 단일 status로 통합하여 원자적 상태 전환
  • • discriminated union으로 타입 안정성 확보
  • • useReducer로 상태 전환 로직 명확화
  • • 불가능한 상태 조합 원천 차단
Follow-up 질문

상태 머신 패턴을 과도하게 적용하면 오히려 코드가 복잡해질 수 있는데, 어떤 기준으로 도입 여부를 판단하시나요?

4 React 동시성 제어
Hard

Q. React에서 파일 업로드 기능을 구현할 때, 사용자가 여러 파일을 선택하면 각 파일을 병렬로 업로드하되 동시 업로드 개수를 3개로 제한하고 싶습니다. Promise.all을 사용하면 모든 파일이 동시에 업로드되어 서버 부하가 큽니다. 동시성 제어를 구현하는 알고리즘과, 진행률을 개별적으로 추적하여 UI에 표시하는 방법을 설명해주세요.

A. 모범답안

큐와 실행 중인 작업 카운터를 사용한 동시성 제어 패턴을 구현해야 합니다. 전체 파일 배열에서 처음 3개를 시작하고, 하나가 완료될 때마다 큐에서 다음 파일을 가져와 업로드하는 방식입니다. 각 파일의 상태를 Map이나 객체로 관리하여 { id, progress, status }를 저장하고, XMLHttpRequest의 onprogress나 fetch의 ReadableStream을 사용하여 진행률을 추적합니다. React 상태로는 Map<fileId, FileUploadState>를 사용하여 개별 파일의 진행 상황을 업데이트하고, 컴포넌트에서는 이를 배열로 변환하여 렌더링합니다. p-limit 같은 라이브러리를 사용하면 더 간단하지만, 직접 구현 시에는 재귀나 while 루프로 큐를 소비하는 로직을 작성할 수 있습니다.

핵심 포인트
  • • 큐와 실행 카운터로 동시성 제어
  • • 각 파일 상태를 Map으로 개별 관리
  • • XMLHttpRequest.onprogress나 ReadableStream으로 진행률 추적
  • • 완료 시 큐에서 다음 작업 가져오기
Follow-up 질문

업로드 중 사용자가 특정 파일의 업로드를 취소하거나, 실패한 파일만 재시도하는 기능을 추가한다면 어떻게 구현하시겠습니까?

5 React 성능 디버깅
Hard

Q. 대시보드 애플리케이션에서 차트 컴포넌트가 데이터 업데이트 시 전체가 리렌더링되어 애니메이션이 끊기는 문제가 있습니다. React DevTools Profiler를 사용하여 성능 병목을 분석하는 방법과, 차트 라이브러리(예: Chart.js, Recharts)를 React와 통합할 때 불필요한 리렌더링을 방지하는 최적화 기법을 설명해주세요.

A. 모범답안

React DevTools Profiler의 Flamegraph와 Ranked 뷰를 사용하여 렌더링 시간이 긴 컴포넌트를 식별하고, 'Why did this render?' 기능으로 리렌더링 원인을 파악합니다. 차트 라이브러리 통합 시에는 useRef로 차트 인스턴스를 저장하고, useEffect에서 데이터 변경 시 차트의 update() 메서드만 호출하여 전체 재생성을 피해야 합니다. React.memo로 차트 컴포넌트를 감싸되, props 비교 함수에서 실제 데이터 변경 여부를 깊은 비교로 체크합니다. 또한 데이터를 useMemo로 메모이제이션하고, 차트 옵션 객체도 useMemo로 안정화하여 참조 동일성을 유지해야 합니다. 대용량 데이터의 경우 Web Worker로 데이터 가공을 오프로드하는 것도 고려할 수 있습니다.

핵심 포인트
  • • Profiler로 렌더링 병목 식별 및 원인 분석
  • • useRef로 차트 인스턴스 저장, update() 메서드만 호출
  • • React.memo와 깊은 비교로 불필요한 재생성 방지
  • • useMemo로 데이터와 옵션 메모이제이션
Follow-up 질문

실시간으로 데이터가 스트리밍되는 상황에서 차트를 매끄럽게 업데이트하려면 어떤 추가 최적화가 필요할까요?

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!