React 주니어 시스템 설계 면접
새 면접Q. React 애플리케이션에서 사용자 로그인 기능을 구현할 때, 인증 토큰(JWT)을 어디에 저장해야 하는지 각 저장소(LocalStorage, SessionStorage, Cookie)의 장단점을 비교하고, 가장 안전한 방법을 추천해주세요.
JWT 토큰은 HttpOnly Cookie에 저장하는 것이 가장 안전합니다. LocalStorage와 SessionStorage는 JavaScript로 접근 가능해 XSS 공격에 취약합니다. HttpOnly Cookie는 JavaScript로 접근할 수 없어 XSS 공격을 방어할 수 있으며, Secure 플래그와 SameSite 속성을 함께 설정하면 CSRF 공격도 방어할 수 있습니다. 다만 Cookie 사용 시 CORS 설정에서 credentials 옵션을 true로 설정해야 합니다.
- • LocalStorage/SessionStorage는 XSS 공격에 취약
- • HttpOnly Cookie는 JavaScript 접근 불가로 보안성 높음
- • Secure, SameSite 속성으로 추가 보안 강화
- • Cookie 사용 시 CORS credentials 설정 필요
Refresh Token과 Access Token을 분리해서 관리하는 이유와, 각각을 어떻게 저장하고 갱신하는 것이 좋을까요?
Q. 게시판 애플리케이션에서 무한 스크롤 기능을 구현하려고 합니다. 페이지네이션 API를 설계할 때 Offset 기반 방식과 Cursor 기반 방식의 차이점을 설명하고, 각각의 장단점을 비교해주세요.
Offset 기반 방식은 페이지 번호와 크기를 사용(예: page=2&size=20)하여 간단하지만, 데이터가 추가/삭제되면 중복이나 누락이 발생할 수 있습니다. Cursor 기반 방식은 마지막 항목의 ID를 기준으로 다음 데이터를 가져오므로(예: cursor=123&limit=20) 데이터 변경에 안정적이고 성능도 우수합니다. 실시간으로 데이터가 자주 변경되는 소셜 피드나 무한 스크롤에는 Cursor 방식이, 고정된 페이지 번호가 필요한 검색 결과에는 Offset 방식이 적합합니다.
- • Offset 방식은 구현이 간단하지만 데이터 변경 시 불안정
- • Cursor 방식은 안정적이고 성능이 좋음
- • 무한 스크롤에는 Cursor 방식 권장
- • 페이지 번호 표시가 필요하면 Offset 방식 사용
Cursor 기반 페이지네이션을 React에서 구현할 때, 이전 페이지로 돌아가는 기능을 어떻게 구현할 수 있을까요?
Q. SNS 애플리케이션에서 사용자(User)와 게시물(Post), 댓글(Comment)의 관계를 데이터베이스로 설계한다고 가정합니다. 각 테이블 간의 관계(1:1, 1:N, N:M)를 정의하고, 외래키(Foreign Key)를 어느 테이블에 어떻게 설정해야 하는지 설명해주세요.
User와 Post는 1:N 관계로, Post 테이블에 user_id 외래키를 설정합니다. Post와 Comment도 1:N 관계로, Comment 테이블에 post_id 외래키를 설정합니다. User와 Comment도 1:N 관계이므로 Comment 테이블에 user_id도 추가합니다. 만약 좋아요 기능을 추가한다면 User와 Post는 N:M 관계가 되므로 중간 테이블(Likes)을 생성하여 user_id와 post_id를 함께 저장해야 합니다.
- • 1:N 관계는 N쪽 테이블에 외래키 설정
- • Comment는 post_id와 user_id 모두 필요
- • N:M 관계는 중간 테이블로 구현
- • 외래키 설정으로 데이터 무결성 보장
댓글에 대댓글(중첩 댓글) 기능을 추가하려면 Comment 테이블을 어떻게 설계해야 할까요?
Q. React 애플리케이션에서 자주 변경되지 않는 사용자 프로필 정보를 API로 가져올 때, 불필요한 네트워크 요청을 줄이기 위한 캐싱 전략을 설명해주세요. 클라이언트 레벨과 HTTP 레벨에서 각각 어떤 방법을 사용할 수 있나요?
클라이언트 레벨에서는 React Query나 SWR 같은 라이브러리를 사용해 staleTime과 cacheTime을 설정하여 메모리에 데이터를 캐싱할 수 있습니다. HTTP 레벨에서는 서버가 Cache-Control 헤더(예: max-age=3600)를 설정하여 브라우저 캐시를 활용하거나, ETag를 사용해 조건부 요청(If-None-Match)으로 304 응답을 받아 대역폭을 절약할 수 있습니다. 두 방법을 함께 사용하면 네트워크 요청을 최소화하면서도 최신 데이터를 유지할 수 있습니다.
- • React Query/SWR로 클라이언트 메모리 캐싱
- • Cache-Control 헤더로 브라우저 캐시 활용
- • ETag로 조건부 요청 구현
- • 캐싱 전략으로 성능과 최신성 균형
사용자가 프로필을 수정한 직후에는 캐시된 데이터를 어떻게 갱신해야 할까요?
Q. 이미지 업로드 기능을 구현할 때, 대용량 이미지 파일을 서버로 직접 전송하는 방식과 클라우드 스토리지(S3 등)의 Presigned URL을 사용하는 방식의 차이점을 설명하고, 각 방식의 장단점과 적합한 사용 사례를 말씀해주세요.
서버 직접 전송 방식은 파일이 서버를 거쳐 스토리지로 저장되므로 서버 부하가 크고 대역폭 비용이 증가하지만, 파일 검증과 보안 제어가 용이합니다. Presigned URL 방식은 클라이언트가 S3에 직접 업로드하므로 서버 부하를 줄이고 확장성이 뛰어나며, 업로드 속도도 빠릅니다. 다만 파일 검증이 어렵고 URL 만료 시간 관리가 필요합니다. 대용량 파일이나 트래픽이 많은 서비스에는 Presigned URL 방식이, 엄격한 파일 검증이 필요한 경우에는 서버 직접 전송이 적합합니다.
- • 서버 직접 전송은 서버 부하 증가
- • Presigned URL은 서버 부하 분산과 확장성 우수
- • Presigned URL로 업로드 속도 개선
- • 파일 검증 필요성에 따라 방식 선택
Presigned URL을 사용할 때, 업로드 완료 후 서버에 파일 정보를 어떻게 전달하고 데이터베이스에 저장해야 할까요?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!