Laravel 주니어 시스템 설계 면접

Laravel 주니어 (1~3년) 시스템 설계 5문항 조회수 109 · 2026-06-20 (토) 03:10:59
1 API 설계
Medium

Q. 도서 대여 시스템에서 사용자가 도서를 대여하고 반납하는 API를 설계하려고 합니다. 대여 중인 도서는 다른 사용자가 대여할 수 없으며, 반납 시 연체 여부를 확인해야 합니다. RESTful 원칙에 따라 대여와 반납 API의 엔드포인트, HTTP 메서드, 요청/응답 구조를 어떻게 설계해야 하는지 설명해주세요.

A. 모범답안

대여 API는 POST /api/books/{bookId}/rentals로 설계하여 특정 도서에 대한 대여 리소스를 생성합니다. 요청 시 user_id와 rental_period를 받고, 응답으로 rental_id, due_date, status를 반환합니다. 반납 API는 PATCH /api/rentals/{rentalId}/return으로 설계하여 대여 상태를 업데이트하며, 응답으로 return_date, is_overdue, late_fee를 반환합니다. 대여 전에 해당 도서의 현재 대여 상태를 확인하는 로직을 컨트롤러에서 구현하고, 이미 대여 중이면 422 Unprocessable Entity 상태 코드를 반환합니다. 연체 확인은 due_date와 현재 날짜를 비교하여 계산하고, 연체료는 비즈니스 로직으로 처리합니다.

핵심 포인트
  • • 대여는 POST /api/books/{bookId}/rentals, 반납은 PATCH /api/rentals/{rentalId}/return
  • • 대여 가능 여부를 검증하고 이미 대여 중이면 422 에러 반환
  • • 반납 시 due_date 기준으로 연체 여부와 연체료 계산
  • • RESTful 리소스 중심 설계: 대여(rental)를 독립적인 리소스로 관리
Follow-up 질문

동일한 도서를 여러 사용자가 동시에 대여 요청할 때 발생할 수 있는 race condition 문제를 Laravel에서 어떻게 해결할 수 있을까요?

2 DB 모델링
Medium

Q. 음식 배달 서비스에서 레스토랑(Restaurant), 메뉴(Menu), 주문(Order), 주문 항목(OrderItem) 간의 관계를 설계하려고 합니다. 하나의 레스토랑은 여러 메뉴를 가지고, 하나의 주문은 여러 메뉴 항목을 포함하며, 각 주문 항목에는 수량과 가격이 저장됩니다. 테이블 구조와 Laravel Eloquent 관계를 어떻게 설계해야 하는지 설명해주세요.

A. 모범답안

restaurants 테이블(id, name, address), menus 테이블(id, restaurant_id, name, price), orders 테이블(id, user_id, restaurant_id, total_amount, status), order_items 테이블(id, order_id, menu_id, quantity, price)로 설계합니다. Restaurant 모델에서 hasMany로 menus와 orders 관계를 정의하고, Menu 모델에서 belongsTo로 restaurant 관계를 정의합니다. Order 모델에서 belongsToMany로 menus 관계를 정의하되 withPivot('quantity', 'price')를 사용해 중간 테이블 필드에 접근하고, hasMany로 orderItems 관계도 정의합니다. OrderItem 모델에서는 belongsTo로 order와 menu 관계를 정의합니다. 주문 생성 시 메뉴의 현재 가격을 order_items.price에 저장하여 가격 변동에 영향받지 않도록 합니다.

핵심 포인트
  • • Restaurant-Menu는 1:N, Order-Menu는 N:M 관계
  • • order_items 중간 테이블에 quantity, price 저장
  • • belongsToMany에서 withPivot()으로 추가 필드 접근
  • • 주문 시점의 가격을 저장하여 메뉴 가격 변동과 무관하게 유지
Follow-up 질문

주문 취소 기능을 구현할 때 order_items 데이터를 실제로 삭제하는 것과 소프트 삭제를 사용하는 것 중 어떤 방식이 더 적절하며 그 이유는 무엇인가요?

3 캐싱 전략
Medium

Q. 날씨 정보 API를 제공하는 서비스에서 외부 기상청 API를 호출하여 데이터를 가져옵니다. 외부 API는 호출 비용이 발생하고 응답이 느리지만, 날씨 정보는 10분마다 업데이트됩니다. Laravel에서 어떤 캐싱 전략을 사용하여 비용을 절감하고 성능을 개선할 수 있는지 설명해주세요.

A. 모범답안

Cache::remember() 메서드를 사용하여 TTL(Time To Live)을 10분(600초)으로 설정하는 캐싱 전략을 사용합니다. 첫 요청 시 외부 API를 호출하고 결과를 캐시에 저장하며, 이후 10분 동안은 캐시된 데이터를 반환합니다. 캐시 키는 지역 정보를 포함하여 'weather:{city_id}'와 같이 구성하여 지역별로 독립적으로 캐시합니다. Redis나 Memcached 같은 인메모리 캐시 드라이버를 사용하여 빠른 조회 성능을 확보합니다. 외부 API 호출 실패 시를 대비해 stale cache 전략으로 만료된 캐시라도 임시로 제공하는 로직을 추가할 수 있습니다.

핵심 포인트
  • • Cache::remember()로 TTL 10분 설정하여 자동 갱신
  • • 지역별로 독립적인 캐시 키 사용 (weather:{city_id})
  • • Redis/Memcached 같은 인메모리 드라이버 활용
  • • 외부 API 실패 시 만료된 캐시라도 제공하는 fallback 전략
Follow-up 질문

특정 지역에 기상 특보가 발령되어 즉시 업데이트가 필요한 경우, 10분 TTL을 기다리지 않고 캐시를 즉시 갱신하는 방법은 무엇인가요?

4 보안
Medium

Q. Laravel API에서 사용자의 비밀번호 변경 기능을 구현할 때 고려해야 할 보안 사항은 무엇이며, 현재 비밀번호 확인, 새 비밀번호 검증, 안전한 저장을 어떻게 구현해야 하는지 설명해주세요.

A. 모범답안

비밀번호 변경 시 반드시 현재 비밀번호를 입력받아 Hash::check()로 검증하여 본인 확인을 수행합니다. 새 비밀번호는 Laravel Validation의 'required|min:8|confirmed|regex' 규칙을 사용하여 최소 길이, 특수문자 포함 등을 검증합니다. 비밀번호 저장 시 Hash::make()나 bcrypt()를 사용하여 암호화하며, 절대 평문으로 저장하지 않습니다. 비밀번호 변경 성공 후에는 기존 세션을 무효화하고 새로 로그인하도록 하여 다른 디바이스의 세션을 차단합니다. API 엔드포인트에는 인증 미들웨어(auth:sanctum)와 rate limiting을 적용하여 무차별 대입 공격을 방지합니다.

핵심 포인트
  • • 현재 비밀번호를 Hash::check()로 검증하여 본인 확인
  • • 새 비밀번호는 Validation 규칙으로 강도 검증 (길이, 복잡도)
  • • Hash::make()로 암호화 저장, 절대 평문 저장 금지
  • • 변경 후 기존 세션 무효화 및 rate limiting 적용
Follow-up 질문

비밀번호 변경 시 이메일로 알림을 보내는 것이 보안상 왜 중요하며, Laravel에서 이를 어떻게 구현할 수 있나요?

5 확장성
Medium

Q. 이벤트 티켓 예매 시스템에서 인기 공연의 경우 예매 오픈 시점에 수천 명의 사용자가 동시에 접속하여 좌석을 예매하려고 합니다. 동일한 좌석에 대한 중복 예매를 방지하고, 높은 트래픽을 처리하기 위해 Laravel에서 어떻게 시스템을 설계해야 하는지 설명해주세요.

A. 모범답안

데이터베이스 수준에서 seats 테이블의 (event_id, seat_number) 컬럼에 unique 인덱스를 설정하여 중복 예매를 원천 차단합니다. 예매 처리 시 DB::transaction()과 lockForUpdate()를 사용하여 비관적 잠금(Pessimistic Locking)을 적용해 동시성 문제를 해결합니다. Redis를 활용한 분산 락(distributed lock)을 구현하여 좌석 선택부터 결제까지의 과정 동안 해당 좌석을 임시로 잠급니다. 예매 요청을 Laravel Queue에 넣어 비동기로 처리하고, 대기열 번호를 부여하여 사용자에게 순서를 안내합니다. 읽기 성능 향상을 위해 좌석 현황은 Redis 캐시에 저장하고, 예매 완료 시에만 DB에 기록하며 캐시를 갱신합니다.

핵심 포인트
  • • DB unique 인덱스와 lockForUpdate()로 중복 예매 방지
  • • Redis 분산 락으로 좌석 선택부터 결제까지 임시 잠금
  • • Queue를 활용한 비동기 처리와 대기열 시스템 구현
  • • Redis 캐시로 좌석 현황 조회 성능 향상
Follow-up 질문

lockForUpdate() 대신 낙관적 잠금(Optimistic Locking)을 사용하는 경우 어떤 장단점이 있으며, 티켓 예매 시스템에서는 어떤 방식이 더 적합한가요?

댓글 0

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

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