다음은 React 19 및 Next.js 16의 최신 기술 표준을 기반으로 편집된 2026년 프런트엔드 인터뷰 질문에 대한 상세하고 심층적인 답변 세트입니다.
I. JavaScript 및 TypeScript 핵심
1. 이벤트 루프 및 작업 우선순위 지정: 마이크로태스크 대기열(Promises, async/await, MutationObserver)은 매크로태스크 대기열(setTimeout, I/O, 이벤트)보다 우선순위가 높습니다. 마이크로태스크는 동기 코드 직후에 실행되며 브라우저가 다음 다시 그리기 단계를 수행하기 전에 완전히 해제되어야 합니다. "기아 현상"은 반복적인 Microtask 스레드가 대기열에 새 작업을 지속적으로 추가할 때 발생하며 이로 인해 Macrotasks 및 렌더링이 무기한 차단되어 전체 애플리케이션 충돌이 발생합니다.
2. 메모리 관리(Mark-and-Sweep & WeakMap): "Mark-and-Sweep" 메커니즘은 루트 개체에서 시작하여 액세스 가능한 모든 개체를 "활성"으로 표시하고 표시되지 않은 개체의 메모리를 회수합니다. WeakMap 및 WeakSet은 개체에 대한 약한 참조를 보유합니다. 즉, 개체에 다른 강력한 참조가 없는 경우 가비지 수집기가 메모리를 회수하는 것을 막지 않습니다. 이는 메모리 누수에 대한 걱정 없이 DOM 노드 또는 캐시에 대한 메타데이터를 저장하는 강력한 도구입니다.
3. 객체 복사 메커니즘:
얕은 복사본: 첫 번째 수준 속성만 복사하고 중첩된 객체는 여전히 동일한 참조를 공유합니다.
딥 카피: 객체 구조를 완전히 복사합니다.
비교:
structuredClone()은 다음을 지원하는 가장 빠른 기본 웹 API입니다.Map,Set및 순환 참조는 있지만 함수나 DOM 노드를 복사할 수는 없습니다.JSON.parse(JSON.stringify())는 매우 느리고 특수 데이터(Date, RegExp)가 손실됩니다.lodash.cloneDeep은 모든 사례를 처리하지만 번들 크기가 약 17KB 늘어납니다.
4. 참조 논리 및 복사 알고리즘: b = a를 할당하면 두 변수 모두 동일한 메모리 위치를 가리킵니다. b의 속성을 변경하면 a가 직접 변경됩니다. 중첩된 객체를 복사하기 위해 Lodash와 같은 라이브러리는 맵과 결합된 재귀 알고리즘을 사용하여 처리된 객체를 추적하므로 순환 참조가 발생할 때 무한 루프를 방지하고 복잡한 데이터 유형을 보존하는 데 도움이 됩니다.
5. Promise.all 대 Sequential Await: 작업이 서로 의존하지 않고 병렬로 실행되는 경우 Promise.all을 사용하여 총 대기 시간을 가장 긴 작업 시간으로 줄입니다. Promise.allSettled는 (성공 또는 실패에 관계없이) 모든 약속이 완료될 때까지 기다리고 자세한 결과 배열을 반환하므로 Promise.all과 같은 전체 체인이 충돌하는 실패한 작업을 방지하므로 안정성을 제공합니다.
6. 조건부 성능(Switch 대 If-Else): 조건이 여러 개일 때 switch는 if-else보다 빠른 경우가 많습니다. 왜냐하면 컴파일러(예: V8)는 각 분기를 순차적으로 검사(O(n))하는 대신 실행될 명령 블록(O(1))에 직접 액세스할 수 있는 "점프 테이블"을 생성할 수 있기 때문입니다.
7. TypeScript 진화(Unions 대 Enum): 2026년에는 const로 결합된 "문자열 리터럴 공용체"('A' | 'B')가 선호됩니다. 왜냐하면 컴파일 후에는 완전히 사라지고(번들 크기 0) Enum은 중복 JavaScript 코드를 생성하기 때문입니다. 또한 숫자 열거형은 숫자 값을 할당할 수 있으므로 유형 안전성이 부족합니다.
8. 고급 입력(추론 및 충족): infer를 사용하면 조건부 유형의 복잡한 구조 내에서 데이터 유형을 추출할 수 있습니다(예: 함수의 반환 유형 가져오기). satisfies 연산자는 리터럴 데이터 형식을 유지하면서 개체가 인터페이스와 일치하는지 확인하는 데 도움이 되므로 IntelliSense가 as를 사용하여 캐스팅하는 것보다 더 정확하게 작동하는 데 도움이 됩니다.
II. React 19 코어 및 후크
9. useMemo는 함수를 기억합니다: 예, useMemo는 해당 함수가 내부 계산 논리 블록의 반환 값인 경우 함수 정의를 완전히 기억할 수 있습니다. 그러나 useCallback은 이러한 목적을 위한 특수한 단축 구문입니다.
10. useCallback 사용 사례: 재렌더링 최적화 외에도 useCallback은 함수를 다른 후크(useEffect, useMemo)에 종속성으로 전달하거나 React.memo에 래핑된 하위 구성 요소에 대한 재렌더링을 방지할 때 참조 안정성을 보장하는 데 중요합니다.
11. 내부 후크 저장소: React는 후크 값을 각 Fiber 노드의 memoizedState 속성에 연결된 연결 목록으로 저장합니다. Hook 호출 순서는 "신성하다". React는 이전 상태를 해당 Hook에 적절하게 매핑하기 위해 실행 순서에 의존하기 때문입니다. 조건에서 Hook을 호출하면 이 목록이 색인화됩니다.
12. useMemo 대 useEffect(동일한 논리, 다른 결과):
useMemo: 렌더링 프로세스 중에 동기적으로 실행됩니다. 내부에 불순한(부작용) 로직이 있는 경우 UI 렌더링 속도가 느려지거나 정지될 수 있습니다.useEffect: 인터페이스가 그려진 후 비동기적으로 실행됩니다.예: 로직이 전역 변수를 업데이트하는 것이라면
useMemo는 렌더링 시 즉시 해당 변수를 변경하고useEffect는 렌더링 시까지 기다립니다. 사용자가 그것을 봅니다. 새로운 인터페이스가 변경되어 데이터 표시 시점에 불일치가 발생했습니다.
13. DOM 동기화(useEffect 대 useLayoutEffect): useLayoutEffect는 DOM 변경 직후, 브라우저가 그리기 전에 동기식으로 실행됩니다. 깜박임을 방지하기 위해 요소 크기를 측정하고 UI를 즉시 업데이트하는 데 사용되는 반면, useEffect(페인트 후 실행)는 사용자에게 몇 밀리초 동안 이전 UI를 표시하게 합니다.
14. 함수 구성요소 수명주기: 마운트(DOM에 추가), 업데이트(렌더링), 마운트 해제(제거)의 3단계로 구성됩니다. useEffect는 렌더링 후에 실행됩니다. 정리 기능은 구성 요소가 마운트 해제되기 직전이나 다음 렌더링에서 효과가 다시 실행되어 오래된 리소스를 정리하기 직전에 실행됩니다.
15. Hooks의 규칙: React는 Fiber 연결 목록의 호출 순서에 따라 상태를 관리하므로 루프나 조건에서 Hooks를 호출하지 마세요. 순서가 변경되면 React는 어떤 상태가 어떤 후크에 속하는지 확인할 수 없습니다.
16. useRef 메커니즘(React 19): useRef는 값이 변경될 때 다시 렌더링을 트리거하지 않고 구성 요소의 수명 주기 전반에 걸쳐 지속되는 영구 객체 {current:...}를 반환합니다. React 19에서는 ref를 하위 구성 요소에 일반 prop으로 전달할 수 있으므로 forwardRef를 사용할 필요가 없습니다.
17. 컨텍스트 API 최적화: 컨텍스트 분할(컨텍스트 분할)을 사용하여 자주 변경되는 상태를 격리하거나 useMemo/React.memo에 하위 구성 요소를 래핑하여 상위의 Context 값이 변경되었지만 하위 구성 요소가 이를 사용하지 않을 때 다시 렌더링되는 것을 방지합니다.
18. 새로운 React 19 후크:
-
if/else).
19. React 컴파일러 규칙: 컴파일러는 빌드 시간 수준에서 메모를 자동화합니다. 프로그래머는 props/state의 순수성(멱등성)과 불변성(불변성)을 준수해야 합니다. 위반할 경우 컴파일러는 해당 구성요소에 대한 최적화를 '건너뛰기'합니다.
III. Next.js 16+ 및 렌더링 전략
20. 수화 메커니즘: 서버는 태그에 초기화 데이터가 포함된 정적 HTML을 보냅니다. 브라우저에서 React는 이 데이터를 읽고 Virtual DOM을 다시 생성하며 이벤트 리스너를 다시 생성하지 않고 기존 실제 DOM 노드에 "연결"합니다.
21. 렌더링 비교(SSG, SSR, ISR, PPR): PPR(부분 사전 렌더링)은 완벽한 조합입니다. 서버는 "정적 셸"을 즉시 보낸 다음 Suspense를 통해 동적 구성 요소를 병렬로 스트리밍합니다. 이는 기존 SSR의 "네트워크 폭포" 현상을 제거하는 데 도움이 됩니다.
22. RSC에서 클라이언트 직렬화: 직렬화 가능한 데이터만 서버-클라이언트 경계를 넘어 전송될 수 있습니다. 함수, 클래스 인스턴스 또는 DOM 노드는 직렬화될 수 없으며 오류가 발생합니다.
23. Next.js 16 캐싱: use cash 지시어를 사용하여 구성요소/함수 결과를 기억하세요. revalidateTag() API는 백그라운드에서 캐시를 새로 고치는 데 사용되는 반면(재검증 기간 동안 오래된) updateTag()(서버 작업에서만 사용됨)는 캐시를 즉시 삭제하여 "쓰기 읽기" 메커니즘을 구현합니다.
IV. 스타일, 성능 및 상황
24. Tailwind v4 Oxide 엔진: Tailwind v4는 소스 파일을 자동으로 스캔하여 실제로 사용되는 클래스에 대한 CSS만 생성하는 '소스 감지' 메커니즘과 함께 Rust(Oxide)로 작성된 엔진을 사용하므로 빌드 속도가 35~50% 더 빨라집니다.
25. CRP(중요 렌더링 경로) 심층 분석: 태그(async/defer 없음)가 발생하면 브라우저는 코드 로드 및 실행을 위해 HTML 구문 분석을 중지합니다. 변형 및 불투명도 속성은 비용이 많이 드는 레이아웃 및 페인트 단계를 건너뛰고 Compositor 스레드에 의해 처리되기 때문에 더 효율적입니다.
26. 기본 동작 및 패시브 리스너: preventDefault() 외에도 이벤트 리스너에서 passive: true를 사용하면 핸들러가 페이지 스크롤을 차단하지 않을 것임을 브라우저가 알 수 있어 UI 부드러움이 향상됩니다.
27. 스토리지 비교:
SameSite.28. XSS/CSRF 보호: LocalStorage는 JavaScript에 액세스할 수 있기 때문에 XSS에 취약합니다. 쿠키는 HttpOnly를 사용하여 XSS를 방지하고 Secure를 사용하여 HTTPS를 시행하며 SameSite=Strict/Lax를 사용하여 CSRF 공격을 차단합니다.
29. 토큰 순환 새로 고침(Next.js 16 프록시): proxy.ts 파일을 사용하여(기존 미들웨어 대체) 요청을 차단합니다. 액세스 토큰이 만료되면 프록시는 새로 고침 토큰 API를 호출하고 새 HttpOnly 쿠키를 업데이트하며 요청이 새 정보로 계속되도록 허용합니다.
30. 중앙 집중식 정책 엔진(RBAC): 별도의 파일에 권한 규칙을 정의하는 중앙 집중식 엔진(예: Oso)을 사용합니다. 이 논리는 서버 구성 요소(UI 렌더링) 및 서버 작업(실행 보안)에 균일하게 적용되어 사용자가 권한을 속이기 위해 클라이언트 코드를 편집하는 것을 방지합니다.
31. 10,000 입력 양식 디자인: 사용자가 onBlur하자마자 각 필드(필드 수준 저장)를 서버에 저장합니다. Redis를 사용하여 브라우저 지문 또는 세션 쿠키를 기반으로 초안을 저장하면 사용자가 로그인하거나 클라이언트 저장소를 사용하지 않고도 돌아와서 계속 입력할 수 있습니다.
32. 3 탭 지연 솔루션(React 19): useTransition을 사용하여 탭 전환을 비선점형 업데이트로 표시하여 UI 응답성을 유지합니다. 구성 요소(React 19.2)를 적용하면 상태/DOM을 잃지 않고 이전 탭을 숨길 수 있어 돌아올 때 즉시 다시 표시할 수 있습니다.
33. 페이지 매김 경쟁 조건: AbortController를 사용하세요. 사용자가 새 페이지로 전환하자마자 controller.abort()를 호출하여 실행 중인 이전 페이지의 요청을 취소하고 마지막으로 표시된 데이터가 항상 최신 페이지와 일치하는지 확인하세요.
공유








