아파치 Tomcat의 BIO Connector / NIO Connector 개념 1) BIO Connector - Response를 보내고 끝내는 것이 아니라 TCP Connection이 만료될 때까지 Thread가 활성 상태로 남아있으며 소켓이 닫히면 Pool로 반환되는 구조 - Connection이 만료되기 전까지 Thread가 활성상태로 남아 있기 때문에 Idle Thread 발생 - '최대 동시접속 클라이언트 수'와 '쓰레드 풀의 쓰레드 수'가 같음 2) NIO Connector - Java의 I/O 라이브러리인 NIO를 활용하여 Tomcat에서 만들어진 Connector - Poller라는 단일 쓰레드가 Selector를 이용하여 처리가 가능한 순간에만 Thread를 활성화시킴으로써 Idle T..
최근 MockMvc 기반으로 컨트롤러 단의 테스트 코드를 작성하다가 핸들러가 호출되지 않는 문제를 마주했고 이를 해결하기 위해 컨트롤러까지 요청이 들어오기까지 어떤 과정을 거치는지 알아야 할 필요성을 느껴 포스팅을 준비했다. 서블릿이란 과거에는 거의 동적인 컨텐츠만 다루는 웹 시스템이었으나 동적인 컨텐츠를 다루면서 웹 서버에 프로그램을 붙여 동적인 페이지를 제공하도록 변화했다. 그래서 등장한 것이 서블릿과 WAS이고 서블릿은 자바 Interface로 정의된 명세사항(specification)이다. (servlet은 javax 패키지에 정의된, 자바에서 정의한 스펙 사항이며 다른 플랫폼에서는 사용되지 않는다) 서블릿의 스펙사항을 기반으로 만들어진, 서블릿을 관리하는 서블릿 컨테이너가 WAS에서 구동된다. ..
디폴트 메소드 도입 자바 8부터 인터페이스의 기능이 개선되었다. 그중 하나가 인터페이스가 구현체를 가지게 된 것인데 이것이 인터페이스의 디폴트 메소드이다. 인터페이스는 모든 메소드가 추상 메소드로만 이루어진 클래스를 의미한다. 하지만 자바 8부터 디폴트메소드가 인터페이스에 들어갈 수 있게 되면서 추상 클래스와의 차이가 거의 없어졌다. 예시 default void say() { // 디폴트 메소드의 구현 몸체부 // 디폴트 메소드의 구현 몸체는 이를 구현하는 클래스가 아닌, // 인터페이스가 자체적으로 가지고 있음 } 디폴트 메소드를 사용하는 이유 - 어뎁터의 기능 사용 - 디폴트 메소드 등장으로 인해 static 메소드도 가질 수 있게 됨. - default, static 메소드들은 implements를..
Collection 인스턴스 동기화 - 2개 이상의 쓰레드가 컬렉션에 동시에 접근한다는 가정이 필요할 땐 동기화를 해주어야 한다. - 일반적인 대부분의 컬렉션들(ArrayList, HashMap 등)은 동기화가 되어있지 않다. 컬렉션 동기화 메소드 1) public static Set synchronizedSet(Set s) 2) public static List synchronizedList(List list) 3) public static Map synchronizedMap(Map m) 4) public static Collection synchronizedCollection(Collection c) - 위 메소드에서 동기화가 되어 있지 않은 컬렉션을 인자로 주면 동기화 기능이 추가된 컬렉션으로 반환..
모델 단을 단위 테스트하는 것과 비슷하게, 컨트롤러도 Mockito와 Junit을 이용해 단위 테스트할 수 있다. 하지만 이 경우 실질적인 HTTP 제이슨 페이로드를 받아 검증하는 방식은 아니다. @Vaild와 같은 어노테이션을 포함한 다양한 것들을 검증하기 위해서는 Mockito와 Junit 만으로는 부족하다. 이러한 경우를 대비해 스프링이 MockMvc를 제공하고 이를 활용해 컨트롤러 end point를 적용한 테스트를 진행할 수 있다. 즉, MockMvc를 활용하면 모의 서블릿 환경에 대한 테스트를 작성할 수 있다. 또한 Mockito에서 제공하는 @Mock이나 @InjectMocks와 같은 어노테이션은 스프링 컨텍스트에 로드하지 않기 때문에 컨트롤러 테스트에서는 사용될 수 없다. 이때는 @Mock..
쓰레드 생성 과정 1. Runnable 인터페이스를 구현한 인스턴스 생성 2. Thread 인스턴스 생성 3. start 메소드 호출 예제코드1 class Solution { final static ThreadLocal threadLocal = new ThreadLocal(); public static void main(String[] args) { Runnable task = () -> { threadLocal.set(1); int num1 = 10; int num2 = 20; String ctName = Thread.currentThread().getName(); System.out.println(MessageFormat.format("num1 + num2 = {0} from {1} and threa..
정렬 알고리즘에서 시간복잡도의 핵심 - 정렬 알고리즘의 평균적인 시간복잡도는 C * nlg(n) + A이지만 (C는 상수) 여기서 C값을 결정하는 요인은 '지역성의 원리'이다. - 지역성의 원리란 '최근에 참조된' 또는 '참조된 데이터의 주변의 데이터'가 또다시 참조될 가능성을 의미한다. - 따라서 이를 활용하면 캐시 hit 발생률이 높아지고 메모리까지 가지 않아도 빠르게 데이터를 읽어올 수 있다. - 예를 들어, merge sort의 경우에는 인접한 데이터들끼리 쪼개서 정렬 후 병합하기 때문에 지역성의 원리가 잘 활용된다고 볼 수 있다. - 퀵 소트의 경우 pivot 주변에서 데이터의 이동이 빈번하게 발생하기 때문에 작은 C값을 가진다. (퀵 소트는 추가적인 메모리 사용 없이도 정렬한다는 점에서 '평균..
HashMap - HashTable과 다르게 쓰레드 동기화를 하지 않음(single-thread에서 유용) - 기본적으로 해쉬값을 반환하는 해쉬함스로써 hashCode()를 사용함 - hashCode()의 반환형은 int임 - int는 32비트(4Byte)이고 2^32개로 완벽한 해쉬값을 만들 수 없음(표현해야 할 key가 2^32개 보다 많을 경우) - HashMap은 O(1)을 보장하기 위해 random access가 가능하게 하려면 HashMap의 크기는 2^32개 여야 함 - 그래서 보통 2^32보다 작은 숫자 M을 이용해 해쉬값을 다음과 같이 다시 정의함 (int index = X.hashCode() % M) - 여기서 M은 2의 지수승 형태임. 즉, M이 2^a 형태라면 hashCode()의 ..
- Total
- Today
- Yesterday
- db
- golang
- argocd
- container
- Linux
- kafka
- LFCS
- Kubernetes
- 코틀린
- rolling update
- jvm
- RDB
- 쿠버네티스
- ci/cd
- CICD
- Controller
- Java
- spring
- ubuntu
- helm
- go
- Stream
- 우분투
- docker
- github actions
- K8s
- Non-Blocking
- 카프카
- GitOps
- 컨트롤러
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |