1. N+1 문제의 발생 이유와 해결 방법에 대해 설명해주실 수 있을까요? 해결 방법은 3가지 이상 말씀해주시면 좋습니다.
1) N+1 문제란?
연관 관계가 설정된 엔티티를 조회할 경우에 조회된 데이터 갯수 (n) 만큼 연관관계의 조회 쿼리가 추가로 발생하여
데이터를 읽어오는 현상
2) 발생 이유?
JPA가 JPQL 을 분석해서 SQL 을 생성할 때는 글로벌 Fetch 전략을 참고하지 않고 오직 JPQL 자체만을 사용하기
때문이다
3) 해결 방법
a) Fetch Join
JPQL 을 사용하여 DB 에서 데이터를 가져올 때 처음부터 연관된 데이터까지 같이 가져오게 하는 방법
(SQL Join 문을 생각하면 된다)
별도의 메소드를 만들어 줘야 하며 @Query 어노테이션을 사용해서 " join fetch 엔티티.연관관계_엔티티 "
구문을 만들어 주면 된다.
b) EntitiyGraph
@EntitiyGraph 의 attributePaths 에 쿼리 수행시 바로 가져올 필드명을 지정하면 Lazy 가 아닌 Eager 조회로
가져오게 된다 Fetch Join 과 동일하게 JPQL 을 사용하여 Query 문을 작성하고 필요한 연관관계를 설정하면 된다
Fetch Join과는 다르게 join 문이 outer join 으로 실행된다
c) BatchSize
@BatchSize 를 이용하면 연관된 엔티티를 조회할 때 지정된 size 만큼 SQL의 IN절을 조회해서 사용한다
정확히는 N+1 문제를 안 일어나게 하는 방법은 아니고 발생하더라도 select * from user where team_id=? 이
아닌 select * from user where team_id (?, ?, ?) 방식으로 N+1 문제가 발생하게 되는 방법이다
이렇게하면 size 만큼 일어날 N+1 문제를 1번만 더 조회하는 방식으로 성능을 최적화 할 수 있다
d) QueryBuilder
Query 를 실행하도록 지원해 주는 다양한 플로그인이 있는데 대표적으로 Mybatis, QueryDSL, JOOQ,
JDBC Template 등이 있다 이를 사용하면 최적화된 쿼리를 구현할 수 있다.
* JPQL
JPA 는 SQL 을 추상화한 JPQL 이라는 객체 지향 쿼리 언어를 제공한다 테이블을 대상으로 쿼리하는 것이 아닌
엔티티 객체를 대상으로 쿼리한다
2. 즉시로딩과 지연로딩은 각각 언제 사용하면 좋은지 설명해주실 수 있을까요?
1) 즉시로딩 (EAGER) : 엔티티를 조회할 때 연관된 엔티티도 함께 조회함
1) 데이터 로딩 비용 최소화
한번의 쿼리로 모든 관련 데이터를 로드하므로 DB 서버의 부하가 줄어든다
불필요한 DB 쿼리를 피하고 네트워크 대역폭을 절약할 수 있다
2) 읽기 전용작업
데이터를 수정하는 작업이 아닌 읽기 전용 작업에서 즉시로딩을 사용하면 DB의 성능을 향상시킬 수 있다
3) 복잡한 데이터 모델
여러개의 연관관계를 가지고 있는 경우 복잡한 데이터를 효율적으로 로드할 수 있다
2) 지연로딩 (LAZY) : 연관된 엔티티를 실제 사용할 때 조회함
1) 성능 최적화
초기 페이지 로드를 향상시킬 수 있다 필요한 데이터만 로드하므로 초기 DB 쿼리 비용이 감소하고 페이지
응답 시간이 개선될 수 있다
2) 보안 및 권한 관리
데이터 액세스 권한을 미리 정의한 후 필요한 데이터만 로드할 수 있으므로 데이터 보안 및 권한 관리에 용이
3) 대량의 데이터 처리
즉시로딩을 사용하면 메모리 부족 문제가 발생할 수 있는데 지연로딩을 활용하여 필요한 데이터만 로드 가능
3. Spring bean container 생성부터 스프링 종료까지의 사이클에 대해 알려주실 수 있을까요?
@PostConstruct, @PreDestroy 어노테이션의 역할도 함께 알려주시면 좋습니다.
1) Spring bean container 생성부터 스프링 종료까지의 사이클
스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 메소드 호출 -> 사용 ->
소멸전 콜백 메소드 호출 -> 스프링 종료
2) @PostConstruct, @PreDestroy
(1) 장점
a) 최신 스프링에서 가장 권장함
b) 어노테이션 하나만 붙이면 되므로 매우 편리
c) 패키지가 스프링 종속기술이 아닌 자바 표준이므로 다른 컨테이너에서도 동작
d) 컴포넌트 스캔과 잘어울림
(2) 단점
a) 커스터마이징이 불가능한 외부 라이브러리에서 적용 불가
(3) @PostConstruct 란?
빈의 초기화 부분에 해당, 빈이 생성된 후 별도의 초기화 작업을 위해 실행하는 메서드 선언
(4) @PreDestroy 란?
마지막 소멸단계, 스프링컨테이너에서 빈을 제거하기 전에 해야할 작업이 있다면 메서드 위에 사용함
* 콜백
콜백함수를 부를 때 사용되는 용어, 콜백함수를 등록하면 특정 이베트가 발생했을 때 해당 메소드가 호출된다
4. AOP, Interceptor, Filter 의 차이점, Request가 들어올 때 거치는 순서, 각 역할들의 장점을 설명해주실 수 있을까요?
공통 기능을 모아서 처리 할 수 있는 방법이며, 각각의 가장 큰 특징은 호출되는 시기이다
요청이 들어오면 Filter -> Interceptor -> AOP -> Interceptor -> Filter 순
* Filter 는 Dispatcher Sevlet 영역에 들어가기전 Front Controller 앞 범위에서
* Interceptor 는 스프링의 Dispatcher Sevlet 이 Controller 를 호출하기 전
* AOP 는 Controller 처리 이후 주로 비지니스 로직에서 실행됨
1) Filter
(1) 스프링 컨텍스트 외부에 존재하여 스프링에 무관한 자원에 대해 동작
(2) HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 처리함
(3) Dispatcher Sevlet 영역에 들어가기 전 Front Controller 앞 범위에서 진행
(4) 필터 적용시 필터가 호출 된 후에 서블릿이 호출됨
(5) 메서드
a) doFilter( ) : 요청이 들어올 때마다 해당 메서드가 호출됨 HTTP 요청이 오면 작동
b) init( ), destory( ) : 따로 구현 안해도 괜찮음
2) Interceptor
(1) 요청을 가로채기 (작업 전 / 후)
(2) 스프링 컨텍스트 영역 내부에서 Controller 에 관한 요청과 응답에 대해 처리
(3) Interceptor 는 Dispatcher Sevlet 에 N 개 등록 될 수 있다
(4) 스프링의 모든 @Bean 에 접근 가능
(5) 메서드
a) preHandler( ) : 컨트롤러 메서드가 실행되기전, 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우
b) postHandler( ) : 컨트롤러 메서드 실행 직후 view 페이지 렌더링 되기 전 (후처리 작업)
c) afterCompletion( ) : view 페이지가 랜더링 되고 난 후 (모든 뷰에서 최종 결과를 생성하는 일을 포함해
모든 작업이 완료 된 후) 요청 처리 중 사용한 리소스를 반환할 때
3) AOP
(1) Controller 처리 이후 주로 비지니스 로직에서 실행됨
* Dispatcher Sevlet
스프링의 가장 앞단에 존재하는 프론트 컨트롤러이며 HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아
적합한 컨트롤러에 위임해줌
'항해99 기술면접 대비' 카테고리의 다른 글
23.10.23 항해 99 16기 기술면접 대비 (0) | 2023.10.23 |
---|---|
23.10.20 항해 99 16기 기술면접 대비 (0) | 2023.10.20 |
23.10.18 항해 99 16기 기술면접 대비 (0) | 2023.10.18 |
23.10.17 항해 99 16기 기술면접 대비 (0) | 2023.10.17 |
23.10.16 항해 99 16기 기술면접 대비 (1) | 2023.10.16 |