이전 글까지는 SpringBoot 가 부팅될 때 일어나는 톰캣 설정과 초기화를 알아보았습니다. 해당 글에서는 톰캣이 논블락킹으로 요청을 받아내고 처리하는 과정과 함께, 왜 톰캣이 NIO 여도 Spring MVC 는 블락킹 서버인지 알아보도록 하겠습니다.Tomcat의 논블로킹(NIO) 소켓 처리Tomcat은 Java NIO(Non-blocking I/O)를 사용하여 소켓을 처리함으로써 높은 성능과 효율적인 자원 관리를 실현합니다. 이번 글에서는 Tomcat이 어떻게 논블로킹 방식으로 요청을 처리하는지에 대해 코드 레벨에서 자세히 알아보겠습니다. Tomcat 의 전체적인 구조를 한번 보도록 하겠습니다. 먼저, Coyote Connector 는 요청을 받아 프로토콜 스펙 (EndPoint) 에 맞게 프로세싱 ..
프로젝트 코드 리뷰 시간에, 한 캠퍼 분께서 Tomcat의 내부 구조를 설명해 주셨습니다. 특히, Acceptor Thread가 모든 요청을 받아 Worker Thread에 전달하고, Worker Thread에서 실제로 요청을 처리한다고 말씀하셨습니다. 당시에는 잘 몰랐지만 주말 동안 공부해보니 이는 바로 `Tomcat NIO Connector`에 대한 이야기였습니다. 이 이야기를 듣자마자 Tomcat 서버와 Spring WebFlux가 비슷하다는 느낌이 들었습니다. 그렇다면 Tomcat을 이용한 Spring Web MVC도 논블로킹이어야 할 것 같은데, 왜 우리는 여전히 one thread per request 동기 블로킹 서버로 알고 있을까요? 먼저 Tomcat 자체를 공부해보며 Servlet과 어..
InnoDB 엔진 기준으로 작성된 글 입니다. 클러스터링 인덱스 MySQL 은 물리적으로 데이터를 저장함에 있어 두 가지 특징이 있다.비슷한 PK 를 가진 데이터는 같은 페이지에 저장된다. 즉, PK 가 데이터 저장 위치를 결정한다. 예를 들면, 그림에서 emp_no 가 PK 일 때, PK 4번 5번은 페이지 번호 9에 같이 저장되어 있고, PK 11 12번은 페이지 번호 10에 저장되어 있다.페이지 안의 데이터는 정렬되어 저장되어 있다. 예를 들면, 그림에서 페이지 번호 안의 데이터는 PK 를 기준으로 오름차순 정렬되어 있다.이 때, PK 가 비슷한 데이터끼리 물리적으로 저장된다는 이유 때문에 PK 를 `클러스터링 인덱스` 라고 부른다. 인덱스에 대한 오해?여기서 짚고 넘어가야할 점이 있다. 흔히 C..
MySQL 서버MySQL 서버는 크게 `MySQL 엔진` 과 `스토리지 엔진` 으로 나뉜다. MySQL 엔진이 사람의 머리 역할을 하고 스트로지 엔진은 손발 역할을 하는데 구성 요소는 다음과 같다. MySQL 엔진클라이언트 접속 및 쿼리 요청을 처리하는 `커넥션 핸들러`, `SQL 파서 및 전처리기`, `옵티마이저` 가 해당된다.스토리지 엔진실제 데이터를 디스크 스토리지에 저장하거나 디스크 스토리지로부터 데이터를 읽어오는 부분이다. MySQL 엔진은 하나지만 스트리지 엔진은 여러 개 동시 사용 가능하다. MySQL 엔진은 `핸들러 API` 를 통해 스토리지 엔진에 읽기 쓰기 요청을 하는데, 그렇게 되면 스토리지 엔진의 `핸들러` 가 실제 액션을 실행한다.MySQL 스레딩 구조MySQL 서버는 프로세스 기..
Spring Framework 6.1 부터 JDK 21 (Virtual Thread) 와의 호환을 지원하기 시작한다고 합니다. 비슷하게 block 된 쓰레드에 대한 관리를 해주는 Webflux 가 Virtual Thread 덕분에 이젠 필요가 없어지는 걸까요? 먼저 Virtual Thread (가상 쓰레드) 가 기존의 쓰레드와 어떠한 점이 달라졌는지 먼저 살펴보고, 성능 차이를 확인해보도록 하겠습닌다.기존 자바 쓰레드 동작 원리Spring Web MVC 기준Thread t = Thread.ofPlatform() JVM 의 플랫폼 쓰레드를 생성합니다.플랫폼 쓰레드가 동작하려면 CPU 에 접근해야 합니다. 그러기 위해서는 커널 쓰레드와 매핑이 1:1 로 되어야하는데 이에 대한 중간 매개체가 JNI(Java ..
정렬 알고리즘 구현을 공부하던 중, 자바의 정렬 알고리즘이 어떻게 구현되어 있는지 궁금해져서 조사해 보았습니다. 그 결과는 다음과 같습니다.원시타입: DualPivotQuickSort를 사용합니다. 이는 Quick Sort의 변형으로, 배열의 크기에 따라 다른 정렬 알고리즘과 섞어 사용됩니다. 자세한 내용은 여기 참조: Java Arrays.sort() 분석객체타입: 이전에는 MergeSort를 사용했으나 현재는 TimSort를 사용합니다. TimSort는 InsertionSort와 MergeSort의 조합입니다. Collections.sort 또한 내부적으로 Object[]로 변환하여 Arrays.sort()를 사용합니다. TimSort 는 왜 Insertion Sort 를 썼을까?TimSort가 ..
제네릭 타입 파라미터 코틀린에서는 자바와는 달리, 제네릭 타입의 타입 인자를 프로그래머가 명시하거나 컴파일러가 추론할 수 있어야 합니다. // 1. 컴파일러 타입 추론 val authors = listof("A", "B") // 2. 변수 선언쪽에 타입 선언 val readers: MutableList = mutableListOf() // 3. 변수를 만드는 함수의 타입인자 지정 val readers = mutableListOf() 1. 제네릭 함수 fun List.slice(indices: IntRange): List 제네릭 함수의 타입 파라미터 T를 선언합니다. 2. 제네릭 확장 프로퍼티 val List.penultimate: T 3. 제네릭 클래스 선언 interface List { operator..
Field 필드 / Property 프로퍼티 자바에서는 필드와 접근자 메서드를 묶어 프로퍼티라고 지칭한다. 코틀린에서는 필드에 대한 기본 접근자 메서드를 자동으로 만들어주기 때문에 필드 대신 프로퍼티라는 말을 사용한다. Backing Field 프로퍼티의 값을 메모리에 저장하기 위한 필드 대부분의 프로퍼티에는 backing field 가 존재하지만 원한다면 프로퍼티 값을 메모리에 저장하지 않고 바로바로 계산하도록도 할 수 있다 프로퍼티를 선언해줄 때 다음 조건을 만족시킨다면 (메모리에 저장할 필요가 있어지기 때문에) 자동으로 backing field 가 생김 적어도 하나의 접근자가 기본으로 구현되는 접근자를 사용하는 경우 커스텀 접근자가 field 키워드를 통해 backing field 를 참조하는 경우..
https://school.programmers.co.kr/learn/courses/30/lessons/154539 프로그래머스 코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요. programmers.co.kr 문제 설명 정수로 이루어진 배열 numbers가 있습니다. 배열 의 각 원소들에 대해 자신보다 뒤에 있는 숫자 중에서 자신보다 크면서 가장 가까이 있는 수를 뒷 큰수라고 합니다. 정수 배열 numbers가 매개변수로 주어질 때, 모든 원소에 대한 뒷 큰수들을 차례로 담은 배열을 return 하도록 solution 함수를 완성해주세요. 단, 뒷 큰수가 존재하지 않는 원소는 -1을 담습니다. 제한사..
스프링 시큐리티를 사용하며 의도하지 않은 403 에러가 떴을 때가 제일 스트레스였던 몇 주가 흘렀습니다. 그 동안 공부했던 내용을 한번 정리해보면 다음엔 고생을 덜 하지않을까 싶기도 하고 그 동안 인증에 대해 놓쳤던 개념(특히 익명유저)에 대해 정리해보고자 합니다.스프링 시큐리티 필터 순서FilterChainProxy 가 사실상 스프링 시큐리티 필터 동작의 시작점이기 때문에 디버깅하기에 적당한 곳입니다. 여기서 확인해보니 12개의 필터가 기본적으로 등록되어 있습니다. 모든 것을 알기 어렵지만 제일 중요한 사실은 인증 (Authentication) 후 인가 (Authorization) 필터가 동작한다는 사실입니다.그 외에도 여러가지 필터는 표에서 살펴보면 됩니다.FilterAdded byCsrfFilter..