Vue.js 미드레벨 CS 기초 기술면접
새 면접Q. Vue 애플리케이션에서 사용자 인증에 JWT를 사용하고 있습니다. Access Token과 Refresh Token을 사용하는 이중 토큰 전략의 동작 원리와 보안상 이점을 설명하고, Access Token 만료 시 자동으로 갱신하는 Axios Interceptor 기반 로직을 어떻게 구현하시겠습니까?
Access Token은 짧은 만료 시간(15-30분)으로 API 요청에 사용되고, Refresh Token은 긴 만료 시간(7-30일)으로 Access Token 갱신에만 사용됩니다. 이는 Access Token 탈취 시 피해를 최소화하면서도 사용자 경험을 유지합니다. Axios Response Interceptor에서 401 에러 발생 시 Refresh Token으로 새 Access Token을 요청하고, 실패한 원래 요청을 재시도합니다. 동시에 여러 요청이 실패할 경우 갱신 요청이 중복되지 않도록 Promise를 공유하는 Queue 패턴을 사용해야 합니다. Refresh Token도 만료되면 로그인 페이지로 리다이렉트합니다.
- • Access Token(단기)과 Refresh Token(장기)의 역할 분리로 보안 강화
- • Axios Interceptor에서 401 에러 감지 및 자동 토큰 갱신
- • 동시 다발적 요청 시 갱신 중복 방지를 위한 Queue 패턴
- • Refresh Token 만료 시 로그인 페이지 리다이렉트 처리
Refresh Token을 LocalStorage에 저장하는 것과 HttpOnly Cookie에 저장하는 것의 보안상 차이점과 각각의 XSS, CSRF 공격 취약성에 대해 설명해주세요.
Q. Vue 애플리케이션에서 최근 검색어 기능을 구현하는데, 최대 10개까지 저장하고 중복된 검색어가 입력되면 가장 최근 위치로 이동시켜야 합니다. 또한 O(1) 시간 복잡도로 검색어 존재 여부를 확인하고 삭제할 수 있어야 합니다. 이 요구사항을 만족하는 자료구조 조합과 각 연산의 시간 복잡도를 설명해주세요.
이중 연결 리스트(Doubly Linked List)와 해시맵(Map)을 조합하여 LRU(Least Recently Used) 캐시 구조를 구현합니다. Map은 검색어를 키로, 이중 연결 리스트의 노드를 값으로 저장하여 O(1)에 존재 여부 확인과 노드 접근이 가능합니다. 이중 연결 리스트는 head가 가장 최근 항목이고, 새 검색어 추가나 기존 검색어 재검색 시 해당 노드를 head로 이동시킵니다. 10개 초과 시 tail 노드를 제거하고 Map에서도 삭제합니다. Vue의 reactive에서는 Map 자체를 ref로 감싸고 변경 시 새 Map 인스턴스를 할당하거나, 배열로 변환하여 렌더링합니다.
- • 이중 연결 리스트와 Map을 조합한 LRU 캐시 구조 사용
- • Map으로 O(1) 검색 및 노드 접근, 이중 연결 리스트로 O(1) 삽입/삭제
- • 중복 검색어는 기존 노드를 head로 이동, 최대 개수 초과 시 tail 제거
- • Vue의 반응성을 위해 ref로 감싼 Map 또는 배열 변환 필요
만약 검색어마다 빈도수를 함께 저장하고, 빈도수가 높은 순으로 정렬된 목록도 유지해야 한다면 어떤 자료구조를 추가로 사용하시겠습니까?
Q. Vue 애플리케이션에서 게시글 목록 조회 API가 느려지는 문제가 발생했습니다. 데이터베이스의 인덱스(Index)가 쿼리 성능에 미치는 영향을 설명하고, WHERE 절과 ORDER BY 절이 함께 사용될 때 복합 인덱스(Composite Index)를 어떻게 설계해야 효과적인지 설명해주세요.
인덱스는 B-Tree 구조로 특정 컬럼의 값을 정렬하여 저장해 O(log N) 시간에 데이터를 찾을 수 있게 합니다. WHERE 절에 사용되는 컬럼에 인덱스가 없으면 Full Table Scan이 발생하여 O(N) 시간이 소요됩니다. 복합 인덱스는 여러 컬럼을 조합하며, 컬럼 순서가 중요합니다. WHERE 절에 사용되는 컬럼을 먼저 배치하고, 그 다음 ORDER BY 컬럼을 배치해야 인덱스를 최대한 활용할 수 있습니다. 예를 들어 WHERE category AND ORDER BY created_at 쿼리에는 (category, created_at) 순서의 복합 인덱스가 효과적입니다. 하지만 인덱스는 INSERT/UPDATE 성능을 저하시키므로 적절한 균형이 필요합니다.
- • 인덱스는 B-Tree 구조로 검색을 O(log N)으로 최적화
- • 복합 인덱스의 컬럼 순서는 WHERE 절 필터링 컬럼 우선
- • ORDER BY 컬럼을 복합 인덱스에 포함하면 정렬 연산 생략 가능
- • 인덱스는 조회 성능을 높이지만 쓰기 성능은 저하시킴
카디널리티(Cardinality)가 낮은 컬럼(예: 성별, 활성화 여부)에 인덱스를 생성하는 것이 비효율적인 이유를 설명해주세요.
Q. Vue 컴포넌트에서 사용자가 입력한 검색어로 대량의 상품 목록을 필터링해야 합니다. 선형 검색(Linear Search)과 이진 검색(Binary Search)의 시간 복잡도 차이를 설명하고, 실시간 검색 기능에서 이진 검색을 적용하기 위해 필요한 전제 조건과 구현 시 고려사항을 설명해주세요.
선형 검색은 배열의 모든 요소를 순회하므로 O(N)의 시간 복잡도를 가지며, 이진 검색은 정렬된 배열에서 중간값과 비교하며 탐색 범위를 절반씩 줄여 O(log N)의 시간 복잡도를 가집니다. 이진 검색을 사용하려면 배열이 정렬되어 있어야 하므로, 초기 데이터 로드 시 또는 필터링 전에 정렬 작업이 필요합니다. 하지만 정렬 자체가 O(N log N)이므로, 데이터가 자주 변경되는 경우 오히려 비효율적일 수 있습니다. 실시간 검색에서는 부분 문자열 매칭이 필요한 경우가 많아 이진 검색보다는 Trie 자료구조나 인덱싱된 검색 엔진 사용이 더 적합합니다.
- • 선형 검색 O(N) vs 이진 검색 O(log N)의 시간 복잡도 차이
- • 이진 검색은 정렬된 배열이 전제 조건이며 정렬 비용 O(N log N) 고려 필요
- • 실시간 검색에서 부분 문자열 매칭은 이진 검색으로 해결 어려움
- • Trie 자료구조나 전문 검색 엔진이 실무에서 더 적합한 선택
문자열 검색에 특화된 KMP 알고리즘이나 Boyer-Moore 알고리즘의 동작 원리와 시간 복잡도를 설명해주세요.
Q. Vue 애플리케이션에서 대용량 파일 업로드 기능을 구현할 때, 브라우저의 메모리 제약을 고려해야 합니다. 운영체제의 가상 메모리(Virtual Memory)와 페이징(Paging) 개념을 설명하고, JavaScript 힙 메모리 한계로 인해 발생할 수 있는 문제와 File API의 Blob.slice()를 활용한 청크 단위 업로드 전략을 설명해주세요.
가상 메모리는 물리 메모리보다 큰 주소 공간을 프로세스에 제공하는 기술로, 페이징을 통해 메모리를 고정 크기 블록(페이지)으로 나누어 필요한 부분만 물리 메모리에 로드합니다. 브라우저의 JavaScript 힙은 일반적으로 2-4GB로 제한되어 있어, 대용량 파일을 한 번에 메모리에 로드하면 Out of Memory 에러가 발생합니다. Blob.slice()를 사용하면 파일을 청크 단위로 나누어 순차적으로 읽고 업로드할 수 있으며, 각 청크 처리 후 가비지 컬렉션으로 메모리를 회수할 수 있습니다. FormData에 청크를 담아 전송하고, 서버에서 조립하는 방식으로 구현하며, 재시도 로직과 진행률 표시를 함께 제공해야 합니다.
- • 가상 메모리와 페이징으로 물리 메모리 한계를 넘는 주소 공간 제공
- • 브라우저 JavaScript 힙은 2-4GB 제한으로 대용량 파일 처리 시 OOM 위험
- • Blob.slice()로 파일을 청크로 분할하여 순차 업로드 및 메모리 관리
- • 각 청크 업로드 후 가비지 컬렉션으로 메모리 회수 및 진행률 표시
브라우저에서 메모리 누수가 발생했을 때 가비지 컬렉션이 자동으로 해결하지 못하는 이유와 Mark-and-Sweep 알고리즘의 동작 원리를 설명해주세요.
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!