Spring 미드레벨 기술면접
새 면접Q. 대용량 데이터(수백만 건)를 처리하는 배치 작업을 Spring Batch로 구현할 때, Chunk-oriented Processing의 동작 원리를 설명하고, Chunk Size 설정 시 고려해야 할 요소들을 메모리 사용량과 성능 관점에서 설명해주세요. 또한 처리 중 일부 데이터에서 예외가 발생했을 때 Skip과 Retry 정책을 어떻게 설정해야 하는지 설명해주세요.
Chunk-oriented Processing은 데이터를 Reader로 한 건씩 읽고, Processor로 가공한 뒤, 설정된 Chunk Size만큼 모아서 Writer로 일괄 처리하는 방식입니다. Chunk Size가 너무 크면 메모리 부족과 롤백 범위 증가 문제가 발생하고, 너무 작으면 DB 커밋 횟수가 증가하여 성능이 저하됩니다. Skip 정책은 특정 예외 발생 시 해당 아이템만 건너뛰고 계속 진행하며, Retry 정책은 일시적 오류(네트워크 타임아웃 등)에 대해 재시도를 수행합니다. 실무에서는 skipLimit과 retryLimit을 설정하여 무한 루프를 방지하고, 실패한 데이터는 별도 테이블에 기록하여 추적 가능하도록 구현합니다.
- • Chunk 단위로 Read-Process-Write를 묶어 트랜잭션 처리
- • Chunk Size는 메모리와 커밋 빈도의 트레이드오프 고려
- • Skip은 예외 발생 시 해당 아이템 건너뛰기, Retry는 재시도
- • 실패 데이터는 별도 저장소에 기록하여 추적
멀티 스레드 환경에서 Spring Batch의 Partitioning과 Multi-threaded Step의 차이점과 각각의 적합한 사용 사례를 설명해주세요.
Q. Spring Security의 Filter Chain 구조에서 UsernamePasswordAuthenticationFilter, AuthenticationManager, AuthenticationProvider, UserDetailsService의 역할과 상호작용 흐름을 설명하고, 커스텀 인증 로직(예: 2FA, 소셜 로그인)을 구현할 때 어느 컴포넌트를 확장해야 하는지 설명해주세요.
UsernamePasswordAuthenticationFilter는 로그인 요청을 가로채 인증을 시작하고, AuthenticationManager는 인증 처리를 위임하는 인터페이스이며, 실제 구현체인 ProviderManager는 여러 AuthenticationProvider 중 적합한 것을 선택합니다. AuthenticationProvider는 실제 인증 로직을 수행하며, UserDetailsService를 통해 사용자 정보를 조회합니다. 2FA 구현 시에는 커스텀 AuthenticationFilter와 AuthenticationProvider를 구현하여 추가 인증 단계를 처리하고, 소셜 로그인은 OAuth2LoginAuthenticationFilter와 OAuth2UserService를 커스터마이징합니다. 인증 성공 시 SecurityContext에 Authentication 객체가 저장되어 이후 요청에서 사용됩니다.
- • Filter가 요청을 가로채고 Manager가 Provider에 위임하는 구조
- • Provider가 실제 인증 로직 수행, UserDetailsService로 사용자 조회
- • 커스텀 인증은 Filter와 Provider를 확장하여 구현
- • 인증 결과는 SecurityContext에 저장되어 전역 접근 가능
SecurityContextHolder의 ThreadLocal 저장 방식이 비동기 처리나 @Async 메서드에서 문제가 되는 이유와 해결 방법을 설명해주세요.
Q. Spring MVC의 동기 블로킹 방식과 Spring WebFlux의 비동기 논블로킹 방식의 차이점을 Thread 모델 관점에서 설명하고, WebFlux가 높은 동시성 처리에 유리한 이유를 설명해주세요. 또한 WebFlux로 전환하는 것이 항상 성능 향상을 보장하지 않는 이유와 적합한 사용 사례를 설명해주세요.
Spring MVC는 Thread-per-Request 모델로 각 요청마다 스레드를 할당하며, I/O 대기 시 스레드가 블로킹되어 자원이 낭비됩니다. WebFlux는 Event Loop 기반으로 소수의 스레드로 많은 요청을 처리하며, I/O 작업 시 스레드를 반환하고 완료되면 콜백으로 재개합니다. 높은 동시성 환경에서 스레드 생성 오버헤드와 컨텍스트 스위칭을 줄여 효율적이지만, CPU 집약적 작업이나 블로킹 라이브러리 사용 시에는 오히려 성능이 저하됩니다. 실무에서는 마이크로서비스 간 다수의 외부 API 호출이나 실시간 스트리밍 데이터 처리에 적합하며, 기존 JDBC나 JPA는 블로킹이므로 R2DBC 같은 리액티브 드라이버가 필요합니다.
- • MVC는 Thread-per-Request, WebFlux는 Event Loop 기반
- • I/O 대기 시 스레드 반환으로 높은 동시성 처리 가능
- • CPU 집약 작업이나 블로킹 라이브러리 사용 시 비효율적
- • 외부 API 다수 호출, 스트리밍 처리에 적합
Reactor의 Mono와 Flux의 차이점과 backpressure 메커니즘이 무엇인지 설명하고, 실무에서 backpressure 전략을 어떻게 선택하는지 설명해주세요.
Q. JPA의 1차 캐시(영속성 컨텍스트)와 2차 캐시(Shared Cache)의 동작 원리와 차이점을 설명하고, 2차 캐시 사용 시 발생할 수 있는 데이터 정합성 문제와 해결 방법을 설명해주세요. 또한 @Cacheable과 JPA 2차 캐시의 차이점을 설명해주세요.
1차 캐시는 EntityManager 범위(트랜잭션 단위)에서 동작하며 같은 엔티티의 반복 조회 시 DB 접근 없이 캐시에서 반환하고, 변경 감지와 쓰기 지연을 지원합니다. 2차 캐시는 EntityManagerFactory 범위(애플리케이션 전역)로 여러 트랜잭션 간 공유되며, Hibernate의 경우 Ehcache나 Redis를 사용합니다. 2차 캐시는 엔티티의 데이터만 캐싱하므로 다른 서버에서 DB를 직접 수정하면 캐시 불일치가 발생할 수 있으며, Cache Concurrency Strategy(READ_ONLY, NONSTRICT_READ_WRITE 등)로 제어합니다. @Cacheable은 Spring의 메서드 레벨 캐싱으로 반환값 자체를 캐싱하며, JPA 2차 캐시는 엔티티 레벨에서 동작하여 쿼리 결과가 아닌 엔티티를 캐싱합니다.
- • 1차 캐시는 트랜잭션 범위, 2차 캐시는 애플리케이션 전역 범위
- • 2차 캐시는 엔티티만 캐싱하며 동시성 전략 설정 필요
- • 다른 서버의 직접 수정 시 캐시 불일치 발생 가능
- • @Cacheable은 메서드 결과 캐싱, 2차 캐시는 엔티티 캐싱
OSIV(Open Session In View) 패턴의 동작 원리와 장단점을 설명하고, OSIV를 비활성화했을 때 발생할 수 있는 LazyInitializationException을 해결하는 방법들을 설명해주세요.
Q. @SpringBootTest, @WebMvcTest, @DataJpaTest의 차이점과 각각의 적합한 사용 사례를 설명하고, 통합 테스트 시 @Transactional을 사용할 때의 장단점과 주의사항을 설명해주세요. 또한 테스트 격리를 위한 데이터 초기화 전략을 비교 설명해주세요.
@SpringBootTest는 전체 애플리케이션 컨텍스트를 로드하여 통합 테스트에 사용하며 느리지만 실제 환경과 유사합니다. @WebMvcTest는 Controller 계층만 로드하여 MockMvc로 HTTP 요청을 테스트하며, Service는 @MockBean으로 대체합니다. @DataJpaTest는 JPA 관련 설정만 로드하고 내장 DB를 사용하여 Repository 테스트에 적합합니다. 테스트에 @Transactional을 사용하면 각 테스트 후 자동 롤백되어 데이터 격리가 쉽지만, 실제 프로덕션과 다른 트랜잭션 동작으로 버그를 놓칠 수 있습니다. 데이터 초기화는 @DirtiesContext로 컨텍스트 재생성, @Sql로 스크립트 실행, 또는 TestContainers로 독립된 DB 인스턴스를 사용하는 방법이 있으며, 실무에서는 속도와 격리 수준의 트레이드오프를 고려하여 선택합니다.
- • @SpringBootTest는 전체 컨텍스트, @WebMvcTest는 Web 계층, @DataJpaTest는 JPA 계층
- • @Transactional 롤백은 편리하지만 실제 환경과 다를 수 있음
- • 데이터 초기화는 @Sql, @DirtiesContext, TestContainers 등 사용
- • 테스트 속도와 격리 수준의 균형을 고려하여 전략 선택
Testcontainers를 사용한 통합 테스트의 장점과 단점을 설명하고, CI/CD 파이프라인에서 테스트 실행 시간을 단축하기 위한 방법들을 설명해주세요.
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!