Vue.js 주니어 시스템 설계 면접

Vue.js 주니어 (1~3년) 시스템 설계 5문항 조회수 56 · 2026-07-12 (일) 19:10:52
1 API 설계
Medium

Q. Vue.js로 개발하는 전자상거래 쇼핑몰에서 상품 목록 조회 API를 설계해야 합니다. 페이지네이션, 정렬, 필터링 기능을 제공하기 위해 RESTful API의 쿼리 파라미터를 어떻게 설계하시겠습니까? 또한 프론트엔드에서 이러한 쿼리 파라미터를 관리하는 방법을 설명해주세요.

A. 모범답안

쿼리 파라미터는 page, limit, sort, order, category, minPrice, maxPrice 등으로 설계하며, GET /api/products?page=1&limit=20&sort=price&order=asc&category=electronics 형태로 구성합니다. Vue Router의 query를 활용하여 URL과 동기화하고, watch를 통해 쿼리 변경 시 API를 재호출합니다. 초기값은 컴포넌트의 data나 reactive 객체로 관리하고, 사용자 액션에 따라 router.push로 쿼리를 업데이트합니다. API 응답에는 총 개수(total), 현재 페이지, 전체 페이지 수 등의 메타데이터를 포함하여 페이지네이션 UI 구성에 활용합니다.

핵심 포인트
  • • RESTful 쿼리 파라미터 설계 (page, limit, sort, filter)
  • • Vue Router의 query와 URL 동기화
  • • watch를 통한 쿼리 변경 감지 및 API 재호출
  • • API 응답의 메타데이터 활용
Follow-up 질문

사용자가 필터를 변경할 때마다 API를 호출하면 성능 문제가 발생할 수 있습니다. 이를 개선하기 위한 디바운싱(Debouncing) 처리를 Vue.js에서 어떻게 구현하시겠습니까?

2 DB 모델링
Medium

Q. Vue.js로 개발하는 블로그 플랫폼에서 게시글(Post), 사용자(User), 댓글(Comment), 태그(Tag) 엔티티 간의 관계를 설계해야 합니다. 각 엔티티 간의 관계(1:N, N:M)를 정의하고, 게시글과 태그의 다대다 관계를 처리하기 위한 중간 테이블 설계 방법을 설명해주세요.

A. 모범답안

User와 Post는 1:N 관계(한 사용자가 여러 게시글 작성), Post와 Comment는 1:N 관계(한 게시글에 여러 댓글), User와 Comment도 1:N 관계입니다. Post와 Tag는 N:M 관계로, 중간 테이블 PostTag(post_id, tag_id)를 생성하여 두 엔티티를 연결합니다. 각 테이블은 id를 기본키로 가지며, 외래키를 통해 참조 무결성을 유지합니다. Vue.js 프론트엔드에서는 API 응답으로 받은 관계 데이터를 normalize하여 Vuex나 Pinia 스토어에 효율적으로 저장하고, getter를 통해 필요한 형태로 조합하여 사용합니다.

핵심 포인트
  • • 엔티티 간 관계 정의 (1:N, N:M)
  • • 다대다 관계의 중간 테이블(Junction Table) 설계
  • • 외래키를 통한 참조 무결성
  • • 프론트엔드에서의 데이터 정규화 및 스토어 관리
Follow-up 질문

게시글 목록을 조회할 때 각 게시글의 댓글 수와 태그 목록을 함께 표시해야 한다면, N+1 쿼리 문제를 방지하기 위해 백엔드에서 어떤 방식으로 데이터를 조회하고, 프론트엔드에서는 어떻게 처리해야 할까요?

3 캐싱 전략
Medium

Q. Vue.js 애플리케이션에서 자주 변경되지 않는 공통 코드 데이터(예: 국가 목록, 카테고리 목록)를 효율적으로 관리하기 위한 캐싱 전략을 설계해주세요. 클라이언트 사이드 캐싱 방법과 캐시 만료 전략을 포함하여 설명해주세요.

A. 모범답안

Vuex나 Pinia 스토어에 공통 코드 데이터를 저장하고, localStorage나 sessionStorage에 영구 보관하여 새로고침 시에도 재사용합니다. 초기 로딩 시 localStorage를 확인하고 데이터가 없거나 만료되었을 때만 API를 호출합니다. 캐시 만료는 timestamp를 함께 저장하여 TTL(Time To Live) 방식으로 관리하며, 예를 들어 24시간 후 만료되도록 설정합니다. API 응답 헤더의 Cache-Control이나 ETag를 활용하여 서버와 협상 캐싱도 구현할 수 있습니다. 관리자가 공통 코드를 수정했을 때는 버전 정보를 활용하여 강제로 캐시를 무효화합니다.

핵심 포인트
  • • Vuex/Pinia와 localStorage를 활용한 클라이언트 캐싱
  • • timestamp 기반 TTL 캐시 만료 전략
  • • 초기 로딩 시 캐시 확인 로직
  • • 버전 관리를 통한 캐시 무효화
Follow-up 질문

여러 탭에서 동시에 애플리케이션을 사용할 때, 한 탭에서 공통 코드가 업데이트되면 다른 탭에도 자동으로 반영되도록 하려면 어떤 방법을 사용할 수 있을까요?

4 보안 설계
Medium

Q. Vue.js SPA에서 JWT 토큰 기반 인증을 구현할 때, Access Token과 Refresh Token을 어디에 저장해야 하는지 설명하고, 각 저장 방식의 보안 취약점과 해결 방법을 설명해주세요. 또한 토큰 갱신 프로세스를 설계해주세요.

A. 모범답안

Access Token은 메모리(Vuex/Pinia)에 저장하고, Refresh Token은 HttpOnly, Secure 속성을 가진 쿠키에 저장하는 것이 권장됩니다. localStorage는 XSS 공격에 취약하므로 민감한 토큰 저장에 부적합합니다. Access Token은 짧은 만료 시간(15분)을 가지며, 만료 시 Refresh Token으로 자동 갱신합니다. Axios 인터셉터에서 401 에러 발생 시 Refresh Token으로 재발급 API를 호출하고, 새로운 Access Token을 받아 실패한 요청을 재시도합니다. CSRF 방지를 위해 쿠키에는 SameSite 속성을 설정하고, Refresh Token은 일회성으로 사용하여 Refresh Token Rotation을 구현합니다.

핵심 포인트
  • • Access Token은 메모리, Refresh Token은 HttpOnly 쿠키에 저장
  • • 짧은 Access Token 만료 시간과 자동 갱신
  • • Axios 인터셉터를 통한 토큰 갱신 로직
  • • XSS, CSRF 공격 방지 방법
Follow-up 질문

사용자가 여러 탭에서 동시에 애플리케이션을 사용하는 경우, 한 탭에서 토큰이 갱신되면 다른 탭에서도 새로운 토큰을 사용해야 합니다. 이를 어떻게 동기화할 수 있을까요?

5 확장성 설계
Hard

Q. Vue.js로 개발한 대시보드 애플리케이션에서 실시간 데이터를 표시해야 합니다. WebSocket과 Server-Sent Events(SSE), Polling 방식을 비교하고, 각 방식의 장단점을 설명해주세요. 또한 연결이 끊어졌을 때의 재연결 로직과 대량의 실시간 데이터를 효율적으로 처리하기 위한 프론트엔드 최적화 방안을 설명해주세요.

A. 모범답안

WebSocket은 양방향 통신이 가능하고 오버헤드가 적어 실시간성이 중요한 채팅, 게임에 적합하지만 구현이 복잡합니다. SSE는 서버에서 클라이언트로만 단방향 푸시가 가능하며 자동 재연결 기능이 있어 알림, 대시보드에 적합합니다. Polling은 구현이 간단하지만 불필요한 요청이 많아 서버 부하가 큽니다. 재연결 로직은 exponential backoff 알고리즘을 사용하여 재시도 간격을 점진적으로 늘립니다. 대량 데이터 처리는 throttle이나 debounce로 업데이트 빈도를 제한하고, Virtual Scrolling으로 보이는 영역만 렌더링하며, 변경된 데이터만 감지하여 부분 업데이트합니다.

핵심 포인트
  • • WebSocket, SSE, Polling의 특징과 사용 사례
  • • Exponential backoff를 활용한 재연결 전략
  • • Throttle/Debounce로 업데이트 빈도 제어
  • • Virtual Scrolling과 부분 업데이트 최적화
Follow-up 질문

실시간 대시보드에서 여러 차트가 동시에 업데이트될 때 브라우저 렌더링 성능이 저하될 수 있습니다. requestAnimationFrame을 활용한 최적화 방법을 설명해주세요.

댓글 0

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

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