Go 시니어 시스템 설계 면접
새 면접Q. 실시간 채팅 시스템을 Go로 구축한다고 가정합니다. WebSocket 기반으로 동시 접속자 100만명을 지원해야 하며, 메시지 전송 보장(at-least-once delivery)과 채팅방별 메시지 순서 보장이 필요합니다. 연결 관리, 메시지 라우팅, 수평 확장 전략, 메시지 큐 선택 및 데이터베이스 설계를 포함한 전체 아키텍처를 설계해주세요.
각 WebSocket 서버는 goroutine pool로 연결을 관리하고, Redis Pub/Sub 또는 NATS로 서버 간 메시지 브로드캐스팅을 구현합니다. 메시지 순서 보장을 위해 채팅방 ID 기반 파티셔닝을 적용하고, Kafka를 메시지 버퍼로 사용해 at-least-once 전송을 보장합니다. PostgreSQL에는 메시지 이력을 저장하며 채팅방별 샤딩을 적용합니다. 연결 정보는 Redis에 캐싱하고, 서버 간 일관된 해시 링을 통해 특정 사용자가 항상 같은 서버로 라우팅되도록 설계합니다. 각 서버는 health check와 graceful shutdown을 구현해 배포 시 연결 유실을 최소화합니다.
- • goroutine 기반 연결 관리와 리소스 제한
- • Redis Pub/Sub 또는 NATS를 통한 서버 간 메시지 전파
- • Kafka 파티셔닝으로 메시지 순서 보장
- • 일관된 해싱을 통한 사용자-서버 매핑
- • graceful shutdown과 reconnection 전략
WebSocket 서버의 메모리 사용량이 예상보다 높게 나타날 때 프로파일링과 최적화는 어떻게 진행하시겠습니까?
Q. 전자상거래 플랫폼의 주문 시스템을 설계합니다. 주문 생성, 재고 차감, 결제 처리가 분산 트랜잭션으로 처리되어야 하며 높은 동시성 환경에서 재고 오버셀링을 방지해야 합니다. Saga 패턴과 2PC 중 선택 기준을 설명하고, Go에서 Saga 패턴 구현 시 상태 관리, 보상 트랜잭션, 멱등성 보장 방법을 구체적으로 제시해주세요.
전자상거래에서는 가용성과 성능이 중요하므로 Saga 패턴을 선택합니다. Orchestration 방식으로 주문 서비스가 중앙 조정자 역할을 하며, 각 단계(재고 예약, 결제, 배송 준비)를 순차 실행하고 실패 시 보상 트랜잭션을 역순으로 실행합니다. 상태는 PostgreSQL에 FSM으로 저장하고, 각 단계마다 idempotency key를 생성해 중복 실행을 방지합니다. 재고 차감은 Redis를 사용한 분산 락과 낙관적 잠금(version 컬럼)을 조합해 동시성을 제어합니다. 각 서비스는 outbox 패턴으로 이벤트를 발행해 데이터 일관성을 보장하며, 실패한 단계는 exponential backoff로 재시도합니다.
- • Saga orchestration 패턴 선택과 중앙 조정자 설계
- • FSM 기반 상태 관리와 보상 트랜잭션
- • idempotency key로 멱등성 보장
- • Redis 분산 락과 낙관적 잠금 조합
- • outbox 패턴으로 이벤트 발행과 데이터 일관성
Saga 실행 중 조정자 서버가 장애로 중단되었을 때 복구 전략은 어떻게 설계하시겠습니까?
Q. 대용량 파일 업로드 API를 설계해야 합니다. 최대 10GB 파일을 지원하며, 업로드 중단 시 재개 가능해야 하고, 여러 클라이언트가 동시에 같은 파일의 다른 부분을 업로드할 수 있어야 합니다. Go에서 multipart upload를 구현할 때 API 엔드포인트 설계, 청크 관리, 메타데이터 저장, 완료 검증 및 에러 처리 전략을 설명해주세요.
3단계 API를 설계합니다. 1) POST /uploads/initiate로 upload_id를 발급하고 메타데이터를 저장합니다. 2) PUT /uploads/{upload_id}/parts/{part_number}로 각 청크를 업로드하며, Content-Range 헤더로 범위를 지정합니다. 3) POST /uploads/{upload_id}/complete로 모든 파트의 ETag를 검증하고 병합합니다. Redis에 업로드 진행 상태(완료된 part 번호, ETag)를 저장하고, 실제 파일은 S3 또는 object storage에 part별로 저장합니다. Go에서는 io.Copy와 버퍼 풀을 사용해 메모리 효율적으로 스트리밍하며, context timeout으로 장시간 연결을 방지합니다. 완료 시 모든 part의 해시값을 검증하고 최종 파일을 생성합니다.
- • 3단계 API 설계(initiate, upload parts, complete)
- • Redis로 업로드 상태와 part 메타데이터 관리
- • Content-Range와 ETag 활용
- • io.Copy와 버퍼 풀로 메모리 효율화
- • part별 해시 검증과 최종 병합
동일한 파일을 여러 사용자가 동시에 업로드할 때 중복 저장을 방지하는 deduplication 전략은 무엇입니까?
Q. OAuth 2.0 인증 서버를 Go로 구현한다고 가정합니다. Authorization Code Flow를 지원하며, JWT 기반 access token과 refresh token을 발급합니다. token 저장 전략, refresh token rotation, token 탈취 대응, PKCE 적용 이유, 그리고 rate limiting과 brute force 방어를 포함한 보안 설계를 상세히 설명해주세요.
Access token은 short-lived JWT(15분)로 stateless하게 검증하고, refresh token은 long-lived(30일)로 Redis에 저장해 무효화 가능하게 합니다. Refresh token rotation을 적용해 사용 시마다 새 토큰을 발급하고 이전 토큰은 즉시 무효화하며, 재사용 감지 시 해당 사용자의 모든 토큰을 revoke합니다. PKCE는 code interception 공격을 방어하기 위해 필수 적용하며, code_verifier를 SHA256 해싱합니다. 로그인 시도는 IP와 사용자별로 Redis sorted set에 기록해 sliding window rate limiting을 적용하고, 5회 실패 시 CAPTCHA를 요구합니다. JWT는 RS256으로 서명하고 public key를 JWKS 엔드포인트로 제공합니다. Token에는 jti(JWT ID)를 포함해 필요 시 blacklist 처리가 가능하도록 설계합니다.
- • Access token은 JWT, refresh token은 Redis 저장
- • Refresh token rotation과 재사용 감지
- • PKCE로 authorization code 탈취 방어
- • Redis 기반 rate limiting과 brute force 방어
- • RS256 서명과 JWKS 엔드포인트
분산 환경에서 여러 인증 서버가 동작할 때 JWT 서명 키 관리와 rotation 전략은 어떻게 구성하시겠습니까?
Q. 전국 매장의 실시간 재고 조회 API를 설계합니다. 10,000개 매장의 100,000개 상품 재고 데이터를 제공하며, 조회는 초당 50,000 QPS이지만 재고 변경은 초당 100회입니다. Redis를 활용한 다층 캐싱 전략, cache invalidation 방법, cache stampede 방지, 그리고 캐시와 DB 간 데이터 정합성을 보장하는 방법을 설계해주세요.
3계층 캐싱을 구성합니다. 1) Application 레벨에서 sync.Map으로 hot item을 1초간 캐싱해 Redis 부하를 줄입니다. 2) Redis에는 매장-상품별 재고를 key로 1분 TTL로 캐싱하고, 재고 변경 시 해당 key를 즉시 삭제합니다. 3) Cache miss 시 singleflight 패턴으로 동일 key에 대한 중복 DB 조회를 방지합니다. 재고 변경은 DB 업데이트 후 Redis Pub/Sub으로 모든 애플리케이션 서버에 invalidation 이벤트를 전파해 로컬 캐시를 삭제합니다. Cache stampede는 probabilistic early expiration(TTL의 10% 시점부터 확률적으로 갱신)과 Redis SET NX로 lock을 획득한 서버만 DB 조회하도록 방어합니다. 정합성은 write-through 패턴으로 DB 업데이트 성공 후 캐시를 삭제하며, 실패 시 outbox 테이블에 기록해 비동기로 재처리합니다.
- • 3계층 캐싱(local cache, Redis, DB)과 TTL 전략
- • singleflight로 cache stampede 방어
- • Redis Pub/Sub으로 분산 cache invalidation
- • probabilistic early expiration
- • write-through 패턴과 outbox로 정합성 보장
Redis 클러스터 장애 시에도 서비스 가용성을 유지하기 위한 fallback 메커니즘은 어떻게 설계하시겠습니까?
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!