- Annotation이란 무엇이고 구체적으로 어떤 것이 있는지 예시를 들어 설명해주실 수 있을까요?
" Annotation은 Java에서 클래스, 메서드, 파라미터, 필드 등에 특별한 표시를 남기기 위해 사용하는 일종의 태그 같은 것입니다. 자체로는 직접적인 기능을 수행하지 않지만, '리플렉션(Reflection)' 기술을 이용하면, 이 Annotation들이 붙어 있는 코드 부분에 추가 작업을 할 수 있게 됩니다.
예를 들어, ‘@Autowired’라는 Annotation이 어떤 필드에 붙어 있다면, 스프링(Spring) 프레임워크의 '빈 컨테이너(Bean Container)'는 그 필드에 알맞은 타입의 객체(빈)를 자동으로 넣어줍니다. 이를 '의존성 주입(Dependency Injection)'이라고 하며, 이 과정을 통해 개발자는 객체를 직접 생성하고 연결하는 복잡한 과정 없이도 필요한 객체를 사용할 수 있게 됩니다.
또 다른 예로, ‘@Component’ Annotation이 클래스에 붙어 있다면, 해당 클래스는 빈 컨테이너에 자동으로 등록됩니다. 이렇게 등록된 클래스(빈)는 프로그램 전체에서 필요할 때마다 재사용될 수 있습니다.
간단히 말해서, Annotation은 코드에 추가 정보나 규칙을 표시하는 역할을 하며, 이를 기반으로 프레임워크나 라이브러리가 동작하여 개발자가 더 쉽고 효율적으로 프로그램을 작성할 수 있도록 도와줍니다. 이처럼 Annotation을 통해 특별한 처리를 자동으로 해주는 기능은 Java 개발에서 매우 유용하게 사용됩니다. "
꼬리 질문 > 그렇다면, 사용자 정의 Annotation을 생성하고 이를 사용하는 과정은 어떻게 되나요?
"사용자 정의 Annotation을 생성하는 과정은 주로 세 가지 주요 단계로 구성됩니다. 먼저, @interface 키워드를 사용해 새로운 Annotation을 정의합니다. 이 때, 필요에 따라 default 값을 가지는 속성을 포함시킬 수 있습니다. 예를 들어, 작업을 추적하기 위한 @WorkItem Annotation을 생성할 때, id, description 같은 속성을 정의할 수 있습니다.
다음으로, 이 사용자 정의 Annotation을 실제 코드에 적용합니다. 클래스, 메소드, 필드 등 원하는 대상에 @WorkItem Annotation을 추가하고, 정의한 속성에 알맞은 값을 할당합니다.
마지막으로, 리플렉션 API를 사용하여 런타임에 이 Annotation을 처리합니다. 이를 통해, Annotation에 포함된 정보를 읽고, 해당 정보에 따라 다른 작업을 수행할 수 있습니다. 예를 들어, 특정 조건을 만족하는 메소드에만 특정 로직을 적용하는 것이 가능합니다.
사용자 정의 Annotation을 사용함으로써, 코드에 대한 메타데이터를 효율적으로 관리하고, 실행 시 동적으로 이를 활용하는 로직을 구현할 수 있습니다. 이는 코드의 가독성과 유지보수성을 크게 향상시킬 뿐만 아니라, 개발 과정에서의 유연성을 제공합니다."
- Spring Security의 구조와 JWT 발급 과정에 대해 설명해주실 수 있을까요?
" Spring Security는 웹 애플리케이션 보안을 위한 핵심 프레임워크로, 사용자의 로그인 확인과 권한 부여를 위해 세 가지 주요 요소를 활용합니다.
첫번째는 인증 매니저(Authentication Manager)로 사용자가 로그인 시 제공한 아이디와 비밀번호가 정확한지 검증합니다.
다음으로는 필터 체인(Filter Chain)으로 웹 요청을 받을 때마다, 사용자가 인증되었는지와 요청이 허용되는지를 체크합니다.
마지막으로 시큐리티 컨텍스트(Security Context)를 통해 로그인한 사용자의 정보를 보관하고, 이를 통해 사용자의 권한을 확인할 수 있습니다.
JWT(Json Web Token)는 로그인 정보를 안전하게 전송하고 관리하는 방식입니다. Spring Security에서는 사용자가 로그인 정보를 제출하면, 그 정보를 검증한 후 JWT를 생성해 사용자에게 반환합니다. 사용자는 이 토큰을 요청에 포함시켜 보내고, 서버는 토큰을 검증해 요청을 처리합니다. 이 방식은 서버가 사용자의 로그인 상태를 기록하지 않아도 되게 해주어, 보안을 강화시킵니다.
간단히 말해, Spring Security는 웹 사이트의 보안을 담당하며, 사용자 식별과 권한 관리를 돕습니다. JWT는 이 과정에서 사용자 정보를 안전하게 주고받는 데 중요한 역할을 합니다. "
꼬리 질문 > Spring Security와 JWT를 사용하여 인증을 구현할 때, 보안 측면에서 고려해야 할 주요 사항은 무엇인가요?
"Spring Security와 JWT를 사용하여 인증 시스템을 구현할 때 보안은 매우 중요한 측면입니다. 여기에는 몇 가지 주요 사항이 있습니다.
첫째, JWT의 안전한 저장과 전송입니다. JWT는 클라이언트 측에서 저장되며, 주로 쿠키나 로컬 스토리지에 저장됩니다. 쿠키에 저장할 경우, HttpOnly와 Secure 플래그를 사용하여 XSS 공격으로부터 보호하고, 데이터가 암호화된 연결을 통해서만 전송되도록 해야 합니다.
둘째, JWT의 서명 검증입니다. 서버 측에서는 JWT가 변조되지 않았는지 확인하기 위해, 발급할 때 사용한 비밀키 또는 공개키/개인키 쌍으로 서명을 검증해야 합니다. 이는 JWT의 신뢰성을 보장합니다.
셋째, JWT의 유효기간 관리입니다. JWT는 유효기간이 지정되어 있어야 하며, 이는 짧게 설정하는 것이 좋습니다. 유효기간이 짧으면, 토큰이 탈취되더라도 사용될 수 있는 시간을 최소화할 수 있습니다. 필요한 경우, 리프레시 토큰을 사용하여 사용자의 세션을 연장할 수 있습니다.
마지막으로, 보안 취약점에 대한 지속적인 모니터링과 패치 적용이 필수적입니다. Spring Security와 같은 프레임워크는 정기적으로 업데이트되며, 새로운 보안 패치가 포함될 수 있습니다. 따라서, 최신 버전을 유지하고 보안 취약점에 대해 주의 깊게 모니터링하는 것이 중요합니다.
이러한 사항들을 철저히 고려하고 적용함으로써, 애플리케이션의 인증 시스템을 보다 안전하게 구현할 수 있습니다."
- N+1 문제의 발생 이유와 해결 방법에 대해 설명해주실 수 있을까요? 해결 방법은 3가지 이상 말씀해주시면 좋습니다.
" N+1 문제는 데이터베이스에서 관계가 설정된 엔티티를 조회할 때, 가져온 각 데이터에 대해 추가적인 쿼리가 실행되어 성능 저하를 일으키는 현상입니다. 이는 주로 지연 로딩 설정이 원인이 될 때 발생합니다. 지연 로딩은 엔티티 목록을 조회할 때 필요한 시점까지 연관된 엔티티의 로딩을 미루는 것인데, 이로 인해 각각의 엔티티에 대해 별도의 쿼리가 실행됩니다. 반면, 연관 관계가 즉시 로딩(Eager)으로 설정되어 있으면, 원본 쿼리 실행 시 모든 연관 엔티티를 한꺼번에 불러오려고 시도하며, 이 경우에도 N+1 문제가 발생할 수 있습니다.
이 문제를 해결하는 방법은 다음과 같습니다. 첫번째로는 Fetch Join을 사용하는 것입니다. ‘@Query’ 어노테이션과 JPQL을 이용하여 연관된 엔티티를 포함한 쿼리를 작성합니다. 이 방식으로 처음 쿼리할 때 필요한 모든 데이터를 한 번에 가져올 수 있습니다.
다음으로는 ‘@EntityGraph’ 어노테이션을 사용해 연관 관계에 대한 Fetch Join을 적용할 멤버 변수를 지정합니다. 이를 통해 필요한 데이터만 선택적으로 불러올 수 있으며, Fetch Join과 유사하게 작동합니다.
다음은 ‘@BatchSize’를 통해 연관된 엔티티 조회 시, 지정된 크기만큼 SQL의 IN 절을 사용하여 한 번에 여러 데이터를 조회할 수 있게 합니다. 이 방법으로 쿼리의 수를 줄일 수 있습니다.
이러한 해결책들을 적절히 사용함으로써, N+1 문제를 효과적으로 방지하고 데이터베이스 성능을 개선할 수 있습니다. "
꼬리 질문 > N+1 문제 해결 방법 중 하나로 Fetch Join을 언급했습니다. 그렇다면 Fetch Join을 사용할 때 주의해야 할 점은 무엇인가요?
"Fetch Join을 사용할 때 주의해야 할 중요한 점은, 연관된 데이터의 양이 매우 많은 경우 성능 저하를 일으킬 수 있다는 것입니다. Fetch Join은 연관된 엔티티를 한 번의 쿼리로 함께 로딩하기 때문에, 로딩해야 할 데이터의 양이 많을 경우 메모리 사용량이 급증하고, 네트워크를 통한 데이터 전송량도 증가할 수 있습니다.
또한, Fetch Join을 사용할 때는 무한 루프에 빠질 위험도 고려해야 합니다. 예를 들어, 양방향 연관 관계가 있는 엔티티에서 서로를 Fetch Join하는 경우, 상호 참조로 인해 데이터를 무한히 로딩하려고 시도할 수 있습니다. 이를 방지하기 위해, 적절한 단방향 연관 관계를 설정하거나, JPA의 @JsonIgnore 같은 어노테이션을 사용하여 순환 참조를 방지해야 합니다.
Fetch Join을 효과적으로 사용하기 위해서는 로딩할 데이터의 양과 구조를 사전에 잘 파악하고, 필요한 경우 페이지네이션과 같은 기법을 사용하여 데이터 로딩을 최적화하는 전략을 고려해야 합니다. 이러한 주의 사항을 잘 관리한다면, Fetch Join은 N+1 문제 해결에 매우 효과적인 방법이 될 수 있습니다."
'면접 (Java) > 기술면접' 카테고리의 다른 글
[면접] 기술 면접 - Java (6) (0) | 2024.03.11 |
---|---|
[면접] 기술 면접 - Java (5) (0) | 2024.03.09 |
[면접] 기술 면접 - Java (3) (0) | 2024.03.07 |
[면접] 기술 면접 - Java (2) (0) | 2024.03.06 |
[면접] 기술 면접 - Java (1) (0) | 2024.03.05 |