Published:
Updated:

깃허브 인터뷰 레포지토리

@Transactional 은 어떤 기능을 하나요?

  • 트랜잭션 경계 설정
    • 메서드나 클래스에 @Transactional을 붙이면 해당 범위가 하나의 트랜잭션으로 처리됩니다.
  • 선언적 트랜잭션 관리
    • 코드 내에 직접 트랜잭션 관련 로직을 작성하지 않고도 어노테이션만으로 트랜잭션을 관리할 수 있습니다.
  • 자동 커밋과 롤백
    • 트랜잭션이 성공적으로 완료되면 자동으로 커밋되고, 예외 발생 시 자동으로 롤백됩니다.
  • 전파 속성 설정
    • 전파 속성이란 이미 트랜잭션이 진행 중일 때, 추가 트랜잭션 진행을 어떻게 결정하는 것을 말합니다.
    • propagation 속성을 통해 트랜잭션의 전파 방식을 지정할 수 있습니다.
    • 예를 들어 REQUIRED, REQUIRES_NEW 등의 옵션이 있습니다.
  • 격리 수준 설정
    • isolation 속성으로 트랜잭션의 격리 수준을 설정할 수 있습니다.
  • 타임아웃 설정
    • timeout 속성으로 트랜잭션 실행 시간 제한을 설정할 수 있습니다.
  • 읽기 전용 트랜잭션
    • readOnly 속성을 통해 읽기 전용 트랜잭션을 설정할 수 있습니다.
  • 특정 예외에 대한 롤백 설정
    • rollbackFor 속성으로 특정 예외 발생 시 롤백하도록 설정할 수 있습니다.

@Transactional(readonly=true) 는 어떤 기능인가요? 이게 도움이 되나요?

@Transactional(readOnly=true)는 스프링에서 제공하는 트랜잭션 관리 기능 중 하나로, 주로 읽기 전용 작업에 사용됩니다. 그리고 이와 같은 장점이 있습니다.

  • 성능 최적화
    • 영속성 컨텍스트의 변경 감지(Dirty Checking) 기능을 비활성화하여 메모리 사용량을 줄입니다.
    • 데이터베이스의 쿼리 최적화가 가능해집니다.
  • 데이터 무결성 보장
    • 실수로 데이터를 수정하는 것을 방지하여 데이터의 일관성을 유지합니다.
  • 가독성 향상
    • 해당 메서드가 읽기 전용 작업임을 명확히 표시하여 코드의 의도를 더 잘 전달합니다.
  • 데이터베이스 최적화
    • 일부 데이터베이스에서는 읽기 전용 트랜잭션에 대해 특별한 최적화를 수행할 수 있습니다.

그런데, 읽기에 트랜잭션을 걸 필요가 있나요? @Transactional을 안 붙이면 되는거 아닐까요?

읽기 작업에 readOnly = true를 사용하는 것에는 몇 가지 이점이 있습니다.

  • 성능 최적화
    • 영속성 컨텍스트의 변경 감지(Dirty Checking) 기능을 비활성화하여 메모리 사용량을 줄입니다.
    • 일부 데이터베이스에서는 읽기 전용 트랜잭션에 대해 특별한 최적화를 수행할 수 있습니다.
  • 데이터 일관성
    • 트랜잭션 내에서 일관된 데이터 스냅샷을 제공하여 데이터 일관성을 보장합니다.
  • 의도 명확화
    • 해당 메서드가 읽기 전용 작업임을 명확히 표시하여 코드의 의도를 더 잘 전달합니다.

Java 에서 Annotation 은 어떤 기능을 하나요?

  • 컴파일러에게 정보 제공
    • 컴파일러에게 코드 작성 문법 오류를 체크하도록 정보를 제공합니다.
    • 예를 들어 @Override 어노테이션은 메서드가 오버라이드되었음을 컴파일러에게 알려줍니다.
  • 런타임 처리
    • 실행 시에 특정 기능을 실행하도록 정보를 제공합니다.
    • 리플렉션을 통해 런타임에 어노테이션 정보를 읽어 처리할 수 있습니다.
  • 메타데이터 제공
    • 코드에 대한 메타데이터를 제공합니다.
      • 메타데이터: 애플리케이션이 처리해야 할 데이터가 아니라, 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지 알려주는 정보
  • AOP(관점 지향 프로그래밍) 지원
    • 비즈니스 로직과 시스템 설정을 분리하여 관심사를 분리할 수 있게 해줍니다.
  • 코드 가독성 및 유지보수성 향상
    • 코드의 의도를 명확히 하고 구조화하는데 도움을 줍니다.
  • 사용자 정의 기능
    • 개발자가 직접 커스텀 어노테이션을 정의하여 원하는 용도로 활용할 수 있습니다.

별 기능이 없는 것 같은데, 어떻게 Spring 에서는 Annotation 이 그렇게 많은 기능을 하는 걸까요?

  • 리플렉션(Reflection) 활용
    • Spring은 Java의 리플렉션 기능을 적극적으로 활용합니다.
    • 리플렉션을 통해 런타임에 클래스, 메서드, 필드 등의 메타데이터를 분석하고 조작할 수 있습니다.
  • AOP(Aspect-Oriented Programming) 지원
    • Spring은 AOP를 통해 어노테이션이 적용된 코드 주변에 추가적인 동작을 삽입할 수 있습니다.
    • 이를 통해 트랜잭션 관리, 보안 등의 기능을 구현합니다.
  • IoC(Inversion of Control) 컨테이너
    • Spring의 IoC 컨테이너는 어노테이션을 해석하여 Bean을 생성하고 관리합니다. - 예를 들어 @Autowired 어노테이션은 의존성 주입을 자동화합니다.
  • 컴포넌트 스캔
    • @ComponentScan 어노테이션을 통해 Spring은 특정 패키지 내의 컴포넌트들을 자동으로 검색하고 등록합니다.
  • 설정 자동화
    • @EnableAutoConfiguration 어노테이션은 클래스패스 설정, 다른 빈, 다양한 프로퍼티 설정에 기반하여 자동으로 빈들을 등록합니다.
  • 메타 어노테이션
    • Spring은 어노테이션 위에 다른 어노테이션을 정의하는 메타 어노테이션을 지원합니다.
    • 이를 통해 복잡한 설정을 단순화할 수 있습니다.
  • 어노테이션 프로세서
    • Spring은 컴파일 시점에 어노테이션을 처리하는 어노테이션 프로세서(ex. Lombok)를 사용하여 추가적인 소스 코드나 리소스 파일을 생성할 수 있습니다.
  • 프레임워크 통합
    • Spring은 JPA, Spring Security 등 다양한 프레임워크와 통합되어 있어, 이들 프레임워크의 기능을 어노테이션을 통해 쉽게 활용할 수 있습니다.

Lombok의 @Data를 잘 사용하지 않는 이유는 무엇일까요?

  • 과도한 기능 생성
    • @Data는 너무 많은 기능을 한 번에 생성합니다. getter, setter, toString(), equals(), hashCode() 등 모든 메서드를 자동으로 만들어내어 의도치 않은 코드를 만들어낼 수 있습니다.
  • 성능 및 안전성 문제
    • 특히 JPA 엔티티에서 @Data 사용 시 양방향 관계에서 StackOverflow 에러가 발생할 수 있습니다.
    • toString()이나 equals(), hashCode() 메서드가 무한 재귀에 빠질 위험이 있습니다.
  • 코드 가독성 저하
    • @Data가 생성하는 모든 메서드를 명시적으로 볼 수 없어 코드의 의도를 파악하기 어려울 수 있습니다.
  • 불변성 침해 - 모든 필드에 대해 setter를 생성하므로, 객체의 불변성을 유지하기 어려워집니다.
  • 세밀한 제어 부족
    • 특정 필드만 포함하거나 제외하는 등의 세밀한 제어가 어렵습니다.
    • 개별 어노테이션(@Getter, @Setter 등)을 사용하는 것이 더 명확하고 제어가 용이합니다.
  • 디버깅 어려움 - 자동 생성된 코드로 인해 디버깅이 어려워질 수 있습니다.

Tomcat이 정확히 어떤 역할을 하는 도구인가요?

Tomcat은 Java 기반의 웹 애플리케이션 서버입니다.

  • 서블릿 컨테이너
    • Tomcat의 가장 중요한 역할은 Java 서블릿을 실행하는 컨테이너 기능입니다.
      • 서블릿: 클라이언트의 요청을 처리하고 동적인 웹 콘텐츠를 생성하는 Java 프로그램
    • Tomcat은 이러한 서블릿을 관리하고 실행하여 동적인 웹 애플리케이션을 제공합니다.
  • JSP 엔진
    • Tomcat은 JavaServer Pages(JSP)를 처리하는 엔진 역할도 수행합니다.
      • JSP: HTML 내에 Java 코드를 포함하여 동적인 웹 페이지를 생성하는 기술
    • Tomcat은 JSP 페이지를 컴파일하고 실행하여 HTML로 변환한 후 클라이언트에게 제공합니다.
  • 웹 서버 기능
    • Tomcat은 기본적인 웹 서버 기능도 제공합니다.
    • HTML, CSS, JavaScript 등의 정적 파일을 클라이언트에게 제공할 수 있습니다.
      • 하지만 주로 동적 콘텐츠 처리에 특화되어 있습니다.
  • 애플리케이션 서버
    • Tomcat은 Java 웹 애플리케이션을 실행하고 관리하는 애플리케이션 서버 역할을 합니다.
    • 개발자들이 작성한 Java 웹 애플리케이션을 배포하고 실행할 수 있는 환경을 제공합니다.
  • 확장성 제공
    • Tomcat은 다양한 설정 옵션과 확장 가능한 구조를 제공하여 사용자의 요구에 맞게 커스터마이징할 수 있습니다.
    • 이를 통해 성능 튜닝, 보안 설정, 추가 기능 구현 등이 가능합니다.

혹시 Netty에 대해 들어보셨나요? 왜 이런 것을 사용할까요?

Netty는 비동기 이벤트 기반 네트워크 애플리케이션 프레임워크입니다. 고성능, 고확장성 네트워크 애플리케이션을 개발할 때 자주 사용됩니다.

  • 높은 성능과 확장성
    • 비동기 및 이벤트 기반 아키텍처를 사용하여 적은 수의 스레드로 많은 동시 연결을 처리할 수 있습니다.
    • Non-Blocking I/O를 사용하여 리소스를 효율적으로 활용합니다.
  • 개발 편의성
    • 복잡한 네트워크 프로그래밍을 추상화하여 개발자가 비즈니스 로직에 집중할 수 있게 합니다.
    • 다양한 프로토콜(HTTP, WebSocket 등)을 기본적으로 지원합니다.
  • 유연성과 확장성
    • 모듈식 아키텍처를 통해 필요한 기능만 선택적으로 사용할 수 있습니다.
    • 사용자 정의 프로토콜 및 코덱을 쉽게 구현할 수 있습니다.
  • 안정성과 성숙도
    • 많은 대규모 기업(예: 라인, 카카오, 트위터)에서 사용되어 검증되었습니다.
    • 지속적인 업데이트와 커뮤니티 지원을 받고 있습니다.

동기(Synchronous)와 비동기(Asynchronous)

동기와 비동기는 작업의 완료 시점과 결과 처리에 관한 개념입니다.

  • 동기(Synchronous)
    • 작업의 결과를 바로 받아 처리합니다.
    • 작업의 순서와 완료 여부에 관심이 있습니다.
    • 한 작업이 끝나야 다음 작업을 진행합니다.
  • 비동기(Asynchronous)
    • 작업의 결과를 나중에 받아 처리합니다(주로 콜백 함수 사용).
    • 작업의 순서와 완료 여부에 크게 관심을 두지 않습니다.
    • 여러 작업을 동시에 진행할 수 있습니다.

Blocking과 Non-blocking

Blocking과 Non-blocking은 제어권에 관한 개념입니다.

  • Blocking
    • 작업을 요청한 후 그 작업이 완료될 때까지 대기합니다.
    • 제어권을 작업을 수행하는 함수가 가집니다.
  • Non-blocking
    • 작업을 요청한 후 즉시 다음 작업을 수행합니다.
    • 제어권을 작업을 요청한 함수가 계속 가지고 있습니다.

주요 차이점

  • 관심사
    • 동기/비동기는 작업 완료와 결과에, Blocking/Non-blocking은 제어권에 초점을 맞춥니다.
  • 조합 가능성
    • 동기/비동기와 Blocking/Non-blocking은 서로 조합될 수 있습니다.
    • 예를 들어, 동기-Non-blocking이나 비동기-Blocking 같은 조합이 가능합니다.
  • 구현 방식
    • 비동기는 주로 콜백, Promise, async/await 등으로 구현되며
    • Non-blocking은 주로 이벤트 루프나 폴링 방식으로 구현됩니다.

Leave a comment