Laravel 미드레벨 기술면접

Laravel 미드레벨 (3~7년) 종합 5문항 조회수 95 · 2026-06-27 (토) 19:11:08
1 쿼리 최적화
Medium

Q. Laravel Eloquent에서 subquery를 사용해야 하는 상황과 성능상의 이점을 설명해주세요. 특히 addSelect()와 selectRaw()를 활용한 서브쿼리 구현 방법과, JOIN을 사용하는 것과 비교했을 때의 장단점을 실무 예시와 함께 설명해주세요.

A. 모범답안

서브쿼리는 각 행마다 관련된 집계 값을 가져올 때 유용합니다. 예를 들어 사용자별 최근 주문일자를 함께 조회할 때, JOIN은 메인 쿼리를 복잡하게 만들지만 서브쿼리는 명확하게 분리됩니다. addSelect()는 Eloquent 빌더를 사용해 타입 안정성을 제공하고, selectRaw()는 복잡한 SQL 표현식을 직접 작성할 수 있습니다. 서브쿼리는 가독성이 좋고 인덱스를 효율적으로 사용할 수 있지만, 대량 데이터에서는 JOIN이 더 빠를 수 있어 실행 계획을 확인해야 합니다. withAggregate() 메서드를 사용하면 Laravel이 자동으로 최적화된 서브쿼리를 생성합니다.

핵심 포인트
  • • 서브쿼리는 집계 값을 각 행에 추가할 때 유용하며, 쿼리 구조를 명확하게 분리
  • • addSelect()는 Eloquent 빌더 사용, selectRaw()는 raw SQL 표현식 사용
  • • JOIN 대비 가독성이 좋고 인덱스 활용이 유리하지만, 데이터 규모에 따라 성능 차이 존재
  • • withAggregate(), withCount() 등 Laravel 헬퍼 메서드가 자동 최적화 제공
Follow-up 질문

서브쿼리가 N+1 문제를 해결하는 방법과 lazy eager loading과의 차이점을 설명해주세요.

2 보안 및 트러블슈팅
Hard

Q. Laravel에서 SQL Injection, XSS, CSRF 공격을 방어하는 메커니즘을 각각 설명하고, 개발자가 실수로 보안 취약점을 만들 수 있는 상황과 이를 방지하기 위한 코드 리뷰 체크리스트를 제시해주세요. 특히 raw query를 사용할 때의 주의사항을 포함해주세요.

A. 모범답안

SQL Injection은 Eloquent와 Query Builder의 파라미터 바인딩으로 자동 방어되지만, DB::raw()나 whereRaw()에 사용자 입력을 직접 넣으면 취약해집니다. XSS는 Blade 템플릿의 이중 중괄호가 자동 이스케이핑하지만, {!! !!}나 v-html 사용 시 위험합니다. CSRF는 @csrf 토큰으로 방어되며 VerifyCsrfToken 미들웨어가 검증합니다. 코드 리뷰 시 raw 메서드 사용 여부, 사용자 입력의 validation 누락, unescaped 출력, API 라우트의 인증/인가 누락을 확인해야 합니다. 또한 Mass Assignment 보호를 위해 fillable/guarded 설정을 점검하고, 민감한 데이터는 hidden 속성으로 숨겨야 합니다.

핵심 포인트
  • • SQL Injection: 파라미터 바인딩 자동 적용, raw query 사용 시 반드시 바인딩 파라미터 사용
  • • XSS: Blade 자동 이스케이핑, {!! !!} 사용 시 htmlspecialchars() 적용 필수
  • • CSRF: @csrf 토큰 및 미들웨어 검증, API는 Sanctum/Passport 사용
  • • 코드 리뷰: raw 메서드, validation 누락, unescaped 출력, Mass Assignment 설정 점검
Follow-up 질문

Laravel Sanctum의 SPA 인증에서 CSRF 보호가 어떻게 동작하는지, 그리고 쿠키 기반 인증의 SameSite 속성 설정의 중요성을 설명해주세요.

3 아키텍처 및 설계 패턴
Hard

Q. Laravel 프로젝트에서 Repository 패턴과 Service 패턴을 도입하는 것에 대한 찬반 의견이 있습니다. 각 패턴의 목적과 장단점을 설명하고, 어떤 프로젝트 규모와 상황에서 도입하는 것이 적절한지 판단 기준을 제시해주세요. 또한 과도한 추상화의 문제점도 함께 설명해주세요.

A. 모범답안

Repository 패턴은 데이터 액세스 로직을 추상화하여 테스트 용이성과 ORM 교체 가능성을 제공하지만, Laravel Eloquent가 이미 Active Record 패턴으로 추상화를 제공하므로 중복될 수 있습니다. Service 패턴은 복잡한 비즈니스 로직을 캡슐화하고 재사용성을 높이지만, 단순 CRUD는 오히려 코드만 늘립니다. 팀 규모가 크고 도메인 로직이 복잡하며 다수의 모델이 협력하는 경우 도입이 유용합니다. 그러나 작은 프로젝트에서 무분별한 추상화는 개발 속도를 저하시키고 코드 추적을 어렵게 만듭니다. Controller-Service-Model 정도의 레이어링으로 시작하고, 필요시 점진적으로 Repository를 도입하는 것이 실용적입니다.

핵심 포인트
  • • Repository: 데이터 액세스 추상화, Eloquent와 중복 가능성, ORM 교체나 복잡한 쿼리 로직 분리 시 유용
  • • Service: 비즈니스 로직 캡슐화 및 재사용, 단순 CRUD는 불필요한 복잡성 증가
  • • 도입 기준: 팀 규모, 도메인 복잡도, 테스트 요구사항, 장기 유지보수 계획
  • • 과도한 추상화: 개발 속도 저하, 코드 추적 어려움, 불필요한 보일러플레이트
Follow-up 질문

DDD(Domain-Driven Design)를 Laravel에 적용할 때의 장단점과, Eloquent Model을 Entity로 사용하는 것과 별도 Entity 클래스를 만드는 것의 차이를 설명해주세요.

4 배포 및 성능 최적화
Medium

Q. Laravel 애플리케이션을 프로덕션 환경에 배포할 때 반드시 실행해야 하는 최적화 명령어들과 각각의 역할을 설명해주세요. 또한 config 캐싱 시 env() 헬퍼를 사용하면 안 되는 이유와, 무중단 배포(Zero-downtime Deployment) 시 캐시 관련 주의사항을 설명해주세요.

A. 모범답안

프로덕션 배포 시 php artisan config:cache는 설정 파일을 캐싱하여 매번 파싱하는 오버헤드를 제거하고, route:cache는 라우트 등록을 최적화하며, view:cache는 Blade 컴파일을 사전에 수행합니다. optimize 명령어는 이들을 일괄 실행합니다. config 캐싱 후에는 env() 헬퍼가 항상 null을 반환하므로, 설정 값은 반드시 config 파일을 통해 접근해야 합니다. 무중단 배포 시에는 새 버전을 별도 디렉토리에 배포하고 심볼릭 링크를 전환하는데, 이때 cache:clear를 실행하면 구버전과 신버전이 캐시를 공유하여 문제가 발생할 수 있으므로 배포 스크립트 순서를 신중히 설계해야 합니다.

핵심 포인트
  • • config:cache, route:cache, view:cache로 파싱 오버헤드 제거 및 성능 향상
  • • config 캐싱 후 env() 헬퍼는 null 반환, 모든 환경 변수는 config 파일로 접근
  • • 무중단 배포: 심볼릭 링크 전환 방식, 캐시 공유 문제 고려
  • • opcache 설정, composer install --optimize-autoloader --no-dev 실행 필수
Follow-up 질문

Laravel Octane을 사용할 때의 성능 이점과 주의사항, 특히 메모리 누수와 전역 상태 관리 문제를 설명해주세요.

5 데이터베이스 설계
Hard

Q. Laravel에서 Soft Delete를 사용할 때의 장단점을 설명하고, 외래키 제약조건과 함께 사용할 때 발생할 수 있는 문제점과 해결 방법을 제시해주세요. 또한 Soft Delete된 레코드의 unique 제약조건 처리 전략과, 대용량 데이터에서 Soft Delete 테이블의 성능 문제를 해결하는 방법을 설명해주세요.

A. 모범답안

Soft Delete는 데이터 복구 가능성과 감사 추적을 제공하지만, 쿼리 성능 저하와 스토리지 증가 문제가 있습니다. 외래키 관계에서 부모를 Soft Delete하면 자식 레코드가 고아가 되므로, onDelete('cascade')를 사용할 수 없고 Model Observer나 deleting 이벤트에서 수동으로 처리해야 합니다. unique 제약조건은 deleted_at 컬럼을 포함한 복합 인덱스로 해결하거나, deleted_at이 null인 경우만 unique를 적용하는 partial index를 사용합니다. 대용량 데이터는 deleted_at에 인덱스를 추가하고, 오래된 Soft Delete 레코드는 아카이브 테이블로 이동시키는 파티셔닝 전략을 적용합니다. 또한 withTrashed() 사용 시 deleted_at IS NULL OR deleted_at IS NOT NULL 조건이 인덱스를 타지 못할 수 있어 주의가 필요합니다.

핵심 포인트
  • • Soft Delete: 데이터 복구 및 감사 추적 가능, 성능 및 스토리지 비용 증가
  • • 외래키 문제: cascade 불가, Model Observer로 수동 처리 필요
  • • unique 제약: deleted_at 포함 복합 인덱스 또는 partial index 사용
  • • 성능 최적화: deleted_at 인덱스, 아카이브 테이블 분리, 파티셔닝 전략
Follow-up 질문

Polymorphic 관계에서 Soft Delete를 사용할 때의 복잡성과, forceDelete()를 실행할 때 관련 파일이나 외부 리소스를 함께 정리하는 패턴을 설명해주세요.

댓글 0

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

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