Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

seaking110 님의 블로그

헷갈리는 개념 정리 본문

Today I Learned

헷갈리는 개념 정리

seaking110 2025. 3. 5. 23:42

AOP vs Intercepter

  • AOP
    • 관점 지향형
    • 횡단 관심사를 분리하여 모듈화하는 기법
    • 즉 핵심 비즈니스 로직과 관계없는 공통 기능을 한 곳에서 관리할 수 있도록 기능
    • 주요 기능
      • Aspect : 공통적으로 적용할 기능
      • Advice : 실행할 코드
      • Pointcut : 적용할 대상 메서드 지정
      • JoinPotin : 실행 가능한 모든 지점
      • Weaving : 실제 코드에서 AOP 기능을 결함하는 과정
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("Method 실행 전: " + joinPoint.getSignature().getName());
    }

    @AfterReturning("execution(* com.example.service.*.*(..))")
    public void logAfterReturning(JoinPoint joinPoint) {
        System.out.println("Method 실행 후: " + joinPoint.getSignature().getName());
    }
}
  • Interceptor (HandlerInterceptor)
    • Spring MVC 에서 HTTP 요청을 가로채고 특정 로직을 실행하는 역할
    • 즉 클라이언트가 컨트롤러에 도달하기 전에 실행되는 필터 역할
    • 주요 기능
      • preHanle() : 컨트롤러 실행 전에 실행
      • postHandle () : 컨트롤러 실행 후에 실행
      • afterCompletion(): View 렌더링 후 실행됨 (예외 발생 여부 상관없이 실행)
JWT 인증 인터셉터


import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;

public class JwtAuthInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        String token = request.getHeader("Authorization");
        if (token == null || !isValidToken(token)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            return false;
        }
        return true;
    }

    private boolean isValidToken(String token) {
        // JWT 토큰 검증 로직 (단순 예제)
        return token.startsWith("Bearer ");
    }
}

 

 

비교 정리

비교 AOP Interceptor
사용 목적 횡단 관심사 적용 (로깅 트랜잭션)  HTTP 요청 전후 처리 (인증 권한)
적용 범위  Spring Bean (서비스, 레파지토리) Spring MVC 요청 처리 과정
실행 위치 메서드 실행 전후, 예외 발생 시 요청 전 후 / 응답 처리
주요 메서드 @Before, @After, @Around preHandle(), postHandle(),
afterCompletion()
주요 용도 로깅 트랜잭션, 성능 측정 인증, 권한 체크, 요청 로깅
등록 방식 @Aspect + @Component WebMvcConfigurer를 사용하여 addInterceptors()로 등록
적용 대상 모든 스프링 빈에서 사용 가능 컨트롤러 요청에 대해서만 동작

 

 

동기(Synchronous) vs 비동기 (Asynchronous)

DB와 연결되면 성능차이가 그렇게 크지 않다고 생각

  • 동기란?
    • 한 작업이 완료될 때까지 대기한 후 다음 작업을 수행하는 방식
    • 순차적으로 실행되므로 코드의 실행 흐름을 예측하기 쉽지만 속도가 느림
    • 특정 작업이 오래 걸릴 경우 다른 작업이 블로킹(Blocking) 됨
public class SyncExample {
    public static void main(String[] args) {
        System.out.println("작업 시작");
        String result = fetchData();  // 데이터를 가져올 때까지 대기 (Blocking)
        System.out.println("결과: " + result);
        System.out.println("작업 종료");
    }

    public static String fetchData() {
        try {
            Thread.sleep(3000);  // 3초 대기
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "동기 처리 완료";
    }
}

작업 시작
(3초 대기)
결과: 동기 처리 완료
작업 종료
  • 비동기란?
    • 한 작업을 실행하는 동안 다른 작업을 동시에 수행 가능 (즉 대기 X)
    • 시간이오래 걸리는 작업을 비동기로 처리하면 성능이 향상
    • Java에서는 @Async, CompletableFuture 등을 이용하여 비동기 진행
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.concurrent.CompletableFuture;

@Service
public class AsyncService {

    @Async  // 별도 스레드에서 실행됨
    public CompletableFuture<String> fetchDataAsync() {
        try {
            Thread.sleep(3000);  // 3초 대기
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return CompletableFuture.completedFuture("비동기 처리 완료");
    }
}


@RestController
@RequestMapping("/api")
public class AsyncController {

    private final AsyncService asyncService;

    public AsyncController(AsyncService asyncService) {
        this.asyncService = asyncService;
    }

    @GetMapping("/async")
    public CompletableFuture<String> getAsyncData() {
        System.out.println("비동기 요청 시작"); //로거 그냥 안씀
        CompletableFuture<String> future = asyncService.fetchDataAsync();
        System.out.println("비동기 요청 종료");
        return future;
    }
}


비동기 요청 시작
비동기 요청 종료  <-- 3초 대기하지 않고 즉시 다음 코드 실행
(3초 후) 비동기 처리 완료

 

비교 정리

비교 항목
동기
비동기
작업 처리 방식
순차적으로 실행
동시에 여러 작업 가능
응답 대기 여부
요청이 끝날 때까지 대기
결과를 기다리지 않고 즉시 다음 코드 실행
성능
속도가 상대적으로 느림
대규모 트래픽에서 성능 향상
사용 방식
일반 메서드 호출
@Async, CompletableFuture, ExecutorService
적용 예제
CRUD, 데이터 조회
대량 데이터 처리, 비동기 API

 

 

Blocking vs Non-Blocking 

  • Blocking (블로킹)
    • 작업을 수행할 때 결과가 나올 때까지 현재 스레드가 멈춰있는 방식
    • 요청을 보낸 스레드는 결과를 받을 때 까지 아무 작업도 못하고 기다림
    • 대표적인 예 : Java의 InputStream.read(), JDBC
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class BlockingIOExample {
    public static void main(String[] args) {
        try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) {
            String line = reader.readLine();  // 파일 읽기 작업이 끝날 때까지 블로킹됨
            System.out.println("읽은 데이터: " + line);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


(파일을 읽을 때까지 프로그램이 멈춰있음)
읽은 데이터: Hello World
  • Non-Blocking
    • 작업을 요청한 후 즉시 제어권을 반환하고 다른 작업을 수행할 수 있는 방식
    • 요청을 보낸 스레드는 응답을 기다리지 않고 다른 작업 수행 가능
    • Java NIO, WebFix 등
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.CompletableFuture;

public class NonBlockingIOExample {
    public static void main(String[] args) {
        System.out.println("파일 읽기 시작");
        
        CompletableFuture.supplyAsync(() -> {
            try {
                return Files.readString(Path.of("data.txt"), StandardCharsets.UTF_8);
            } catch (Exception e) {
                e.printStackTrace();
                return "";
            }
        }).thenAccept(content -> System.out.println("읽은 데이터: " + content));

        System.out.println("다른 작업 수행 중...");
    }
}

파일 읽기 시작
다른 작업 수행 중...
읽은 데이터: Hello World

 

차이점

비교 Blocking Non-Blocking
작업 처리 방식 요청을 보낸 후 응답이 올때 까지 대기 요청을 보낸 후 즉시 다른 작업 수행
예제 InputStream.read, JDBC Java NIO,CompletableFuture
스레드 효율 하나의 요청이 하나의 스레드를 점유
효율적이지는 않음
하나의 스레드가 여러 요청을 처리
효율적
적용 예시 일반적인 파일, I/O JDBC 연결 WebFlux, Netty 기반 웹서버
장점 코드가 직관적이고 이해하기 쉽고 반드시 필요한 부분이 생김 성능 향상
단점 응답 대기 시간이 길어지면 성능 저하 코드가 복잡해 질 수 있음

 

  • Sync vs Async 와 Blocking vs Non-Blocking는 다르다!!
  • Blocking vs Non-Blocking은 "작업이 완료될 때까지 기다리는가?"의 차이
    • Blocking → 스레드가 멈춰서 기다림
    • Non-Blocking → 스레드가 기다리지 않고 다른 작업 수행 가능
  • Sync vs Async는 "작업이 순차적으로 실행되는가?"의 차이
    • Sync → 이전 작업이 끝나야 다음 작업 시작
    • Async → 여러 작업을 동시에 진행 가능

 

동시성 VS 병렬성

  • 동시성
    • 하나의 CPU 코어에서 여러 작업을 번갈아가며 실행하는 방식
    • 실제로 같은 순간에 여러 작업이 실행되는 것이 아닌 작업 간 전환(Context Switching)을 통해 빠르게 수행되는 것 처럼 보임
    • 멀티 스레드, 비동기 프로그래밍과 관련
public class ConcurrencyExample {
    public static void main(String[] args) {
        Runnable task1 = () -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("Task 1 실행 중...");
                try { Thread.sleep(100); } catch (InterruptedException ignored) {}
            }
        };

        Runnable task2 = () -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("Task 2 실행 중...");
                try { Thread.sleep(100); } catch (InterruptedException ignored) {}
            }
        };

        new Thread(task1).start();
        new Thread(task2).start();
    }
}


번갈아가면서 실행됨

Task 1 실행 중...
Task 2 실행 중...
Task 1 실행 중...
Task 2 실행 중...
...
  • 병렬성
    • 여러 개의 CPU를 활용하여 여러 작업을 완전히 동시에 실행하는 방식
    • 멀티코어 시스템에서 각 작업이 독립적으로 실행되며 속도가 크게 향상
    • 멀티 프로세싱, 병령 스트림, ForkJoinPool과 관련됨
병렬성 예제 (자바 병렬 스트림)

import java.util.stream.IntStream;

public class ParallelExample {
    public static void main(String[] args) {
        IntStream.range(1, 10).parallel().forEach(i -> 
            System.out.println(Thread.currentThread().getName() + " - Task " + i)
        );
    }
}


ForkJoinPool.commonPool-worker-1 - Task 2
ForkJoinPool.commonPool-worker-2 - Task 3
ForkJoinPool.commonPool-worker-3 - Task 1
ForkJoinPool.commonPool-worker-1 - Task 4
...
  • 여러 개의 CPU(멀티코어)를 사용하여 작업이 완전히 동시에 실행됨
  • 동시성과 다르게 "스레드 전환"이 아니라 "각 작업이 독립적으로 실행됨"

 

 

차이점

비교 항목
동시성(Concurrency)
병렬성(Parallelism)
개념
여러 작업을 번갈아 실행 (스레드 전환)
여러 작업을 완전히 동시에 실행
CPU 개수
단일 CPU에서도 가능
멀티코어 CPU 필요
작업 방식
여러 작업을 빠르게 스위칭하여 처리
여러 작업을 동시에 실행
적용 기술
멀티스레딩, 비동기 처리
멀티프로세싱, 병렬 연산
장점
하나의 CPU로도 다중 작업 가능
성능 최적화, 대량 데이터 병렬 처리
단점
스레드 전환 오버헤드 발생
멀티코어 환경에서만 효과적, 비쌈
예제
웹 서버의 요청 처리, 비동기 이벤트 루프
머신러닝 연산, 대량 데이터 처리

 

 

 

 

동시성이 필요한 경우

웹 서버 요청 처리 (Spring MVC)

  • HTTP 요청이 많을 때 멀티스레드를 사용하여 여러 요청을 동시 처리
  • 하지만 각 요청이 같은 순간에 실행되는 것이 아니라 빠르게 전환되는 것

게임에서 여러 캐릭터의 행동 처리

  • 한 캐릭터의 공격, 이동, 대화 이벤트가 동시에 발생하는 것처럼 보이지만 실제로는 번갈아가면서 실행됨

병렬성이 필요한 경우

머신러닝 모델 학습

  • 각 CPU 코어에서 데이터를 병렬로 처리하여 속도를 크게 향상

비디오 렌더링

  • 여러 개의 프레임을 여러 CPU에서 동시에 처리하여 성능 향상

Java의 ForkJoinPool (병렬 처리)

'Today I Learned' 카테고리의 다른 글

연관관계와 N+1  (0) 2025.03.11
테스트 코드 remind  (1) 2025.03.10
트러블 슈팅  (0) 2025.02.27
프로젝트에 부족한 부분을 찾아 리팩토링  (0) 2025.02.27
Cookie, JWT  (0) 2025.02.26