최신 글
-
코루틴 Thread confinement 기법
스레드의 동시 상태변경 문제는 코루틴에서도 동일하게 접할 수 있다.상태공유를 코루틴 간에 무분별하게 하면, thread-safe 하지 못한 코드가 작성될 수 있다.따라서 아래처럼 임계영역은 하나의 스레드 컨텍스트로 제한할 수 있다. 이를 Thread confinement이라 한다.Completed 100000 actions in 474 ms 임계영역에 진입할 때마다 싱글 스레드 컨텍스트로 전환시키는 위와 같은 방법을 fine-grained 방식이라 한다. 다음에 소개할 coarse-grained 방식보다 상대적으로 느리다. Completed 100000 actions in 9 ms 위 방식은 coarse-grained 방식이라 한다. 애초에 임계영역에 진입하기 전에 임계영역을 호출하는 함수 자체를 싱..
2024.10.28
-
[Kotlin, Jackson] @JsonCreator 로 enum 값 유연하게 역직렬화
Spirng 개발을 하다 보면 json 직렬화에는 기본으로 jackson 라이브러리를 사용하게 된다. 다른 API 통신, FE 클라이언트와 통신할 때 제일 많이 쓰는 포맷이 json일 듯하다. Java 에는 enum 클래스를 지원해서 상수값을 편하게 관리할 수 있는데, 대외 통신 시 직렬화 작업을 할 때 그 값이 꼭 Enum에 정의한 값이 아니어도 가능해야할 때가 있다. 예를 들어 enum에는 성별을 MEN, FEMALE로 정의했지만, 호출 단에서는 M, F로 정의해서 보낸다던지 등이다. 따라서 아래처럼 직렬화를 실패하게 된다. 그러나 Jackson 라이브러리는 @JsonCreator 애노테이션을 지원한다. 아래처럼 선언해주면 역직렬화 시 enum을 유연하게 생성할 수 있다. 이제 아래와 같은 테..
2024.08.09
-
[Kotlin] runBlocking vs coroutineScope
코루틴은 Structured Concurrency 원칙을 따른다. Structured Concurrency이란 새로운 코루틴은 반드시 CoroutineScope 안에서만 생성 (런치)될 수 있다는 것으로 코루틴의 범위를 제한하는 메커니즘이다. 코루틴의 범위를 제한하고 코루틴의 라이프사이클을 관리하는 인터페이스는 kotlinx.coroutines.CoroutineScope이다. Scope builder Scope builder란 코루틴의 범위를 나타내는 인터페이스 CorotuineScope을 생성하고, 그 안에서 생성된 모든 코루틴 (자식 코루틴)이 완료될 때까지 기다리는 빌더 함수 (람다)를 말한다. 코루틴 스코프의 최상위 코루틴 (부모 코루틴)은 블로킹된다. 스코프 빌더는 크게 2가지 runBlock..
2024.08.02
-
ELK 스택으로 구축하는 로그 수집, 시각화
목차모니터링 방법과 ELK 스택구축해 보기모니터링 방법과 ELK 스택 어제 8시 즈음 회원 서버 로그 좀 봐볼까? (회원 서버만 10대인데요?) 애플리케이션이 많아질수록 개발자 (관리자)가 조회해야 하는 애플리케이션 관련 데이터가 급격히 늘어난다. metric, 로그 데이터와 같은 것들이다. 애플리케이션이 한 개이고, 레플리카도 하나라면 직접 서버에 접속해 로그 파일을 추적해 보면 되지만, 여러 대인 상황에서는 쉽지 않다. APM (Application Performance Monitoring) 솔루션을 사용하면 애플리케이션의 실시간 모니터링이 가능하다. 성능 관련 데이터는 실시간에 가깝게 조회되어야 하는 데이터지만, 로그나 사용자 추적 데이터 (히스토리, 페이지 이동 이력 등)는 성격이 다르다...
2024.07.24
-
[Database] MySQL ORDER BY 방식 비교와 성능
목차인덱스를 이용한 정렬 (extra에 별도 표기 없음)driving table만 정렬 (Using filesort)임시 테이블을 이용한 정렬 (Using temporary; Using filesort) MySQL에서 ORDER BY (정렬)을 처리하는 방식은 크게 2가지가 있다. 인덱스를 활용하는 인덱스 정렬과, 메모리 (혹은 디스크까지)를 활용해서 정렬하는 filesort이다. 이 2가지 방법을 토대로 옵티마이저는 크게 세 가지 형태로 정렬을 진행할 수 있는데 결론부터 말하자면,가능하다면 인덱스를 사용한 정렬로 유도 하고, (인덱스 정렬)그렇지 못하면 최소한 드라이빙 테이블만 정렬해도 되는 수준으로 유도하는 것이 좋은 튜닝방법이다. (filesort)그렇지 않으면 임시 테이블을 이용해 정렬하게 되는..
2024.07.16
-
[Kotlin, jackson] non-null 객체에 런타임에 null 초기화하는 문제
코틀린은 compile-time에 변수의 null 여부를 검사할 수 있는 null-safety 기능을 제공한다. 그러나 run-time에 null이 초기화되는 것은 체크할 방도가 없다. 따라서 위 테스트는 말끔하게 통과하는 불상사가 일어난다. 코틀린으로 스프링 개발할 때 jackon 라이브러리에서 필드값들을 (역) 직렬화 작업을 하면서 위 현상을 보고, NPE까지 터지는 일이 발생한다. 다행히도 jackson에서 아래 같은 애노테이션을 지원한다.
2024.06.25
-
[algorithm] 정렬 4. 정리 및 응용
목차어떤 정렬 알고리즘을 사용해야 하는가환원 : 정렬 알고리즘 응용하기정렬알고리즘 사용 사례어떤 정렬 알고리즘을 사용해야 하는가 명제 : 퀵-정렬은 가장 빠른 범용 정렬 알고리즘이다.위 가설은 퀵-정렬이 개발된 이래 수십 년간 수많은 컴퓨팅 시스템에서 수많은 방식으로 구현되어 왔다. 일반적으로 퀵 정렬이 빠른 이유는 내부 루프의 명령어 수가 적기 때문이다. 결론 : 대부분의 실제 상황에서 퀵-정렬을 선택하는 것이 안전하다. 그 선택이 올바른지는 예외 상황들을 토대로 살펴봐야 한다. 예를 들어 안정정렬이 중요하고 공간이 충분하다면 병합 정렬이 최선일 것이다. 기본형 데이터 타입의 정렬성능에 매우 민감하거나 숫자의 정렬에만 집중한다면 int와 같은 기본형을 사용하는 것이 좋다. int는 후술 할 포인터 ..
2024.06.22
-
[Kotlin, JPA] Should have [public, protected] no-arg constructor
@Entity@Table(name = "member")data class Member( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long? = null, @Column val nameMember: String, @Column val ymdtCre: LocalDateTime = LocalDateTime.now(), @Column val ymdtUpdt: LocalDateTime?) 에러 메시지에 원인이 나와있다. public, protected 접근제어자로 기본생성자를 만들라는 컴파일 에러다. 엔티티는 반드시 기본 생성자를 가져야한다. Java라면 Lombok을 사용해 @NoArg..
2024.06.10
-
[Java, Spring] 버전 선택 가이드 2024 (Java 21)
2023년 버전으로 자바 버전 채택 가이드를 포스팅을 한 지 1년이 채 안 돼 조회수가 1만이 넘었다;; 내 티스토리의 명실상부 효자 포스팅이 아닐 수 없어 2024 버전으로 다시 작성해보려 한다.https://kghworks.tistory.com/137 [JAVA, SPRING] 버전 선택 가이드 2023Java와 Spring을 선택함에 있어 Java version과 Spring version은 매우 중요합니다. 특히 Java 8부터 소개된 lamda, stream, Java 11의 var 타입추론 등은 같은 Java여도 버전에 따라 꽤 다른 가독성, 문법을 보여주기kghworks.tistory.com 미리 쓰는 결론 : JDK 17 쓰자Spring Framework로 개발하는 경우 : JDK17..
2024.04.27
Programming
-
[Java, Spring] 버전 선택 가이드 2024 (Java 21)
2023년 버전으로 자바 버전 채택 가이드를 포스팅을 한 지 1년이 채 안 돼 조회수가 1만이 넘었다;; 내 티스토리의 명실상부 효자 포스팅이 아닐 수 없어 2024 버전으로 다시 작성해보려 한다.https://kghworks.tistory.com/137 [JAVA, SPRING] 버전 선택 가이드 2023Java와 Spring을 선택함에 있어 Java version과 Spring version은 매우 중요합니다. 특히 Java 8부터 소개된 lamda, stream, Java 11의 var 타입추론 등은 같은 Java여도 버전에 따라 꽤 다른 가독성, 문법을 보여주기kghworks.tistory.com 미리 쓰는 결론 : JDK 17 쓰자Spring Framework로 개발하는 경우 : JDK17..
2024.04.27
-
[Java] JDK 21 Virtual Threads 톺아보기
목차 OS 스레드와 Java Platform Thread Java Virtual Thread Virtual Thread 사용해 보기 Virtual Thread 효율적으로 사용하기 Java 21에 새롭게 추가된 Virtual Thread에 대해 알아본다. 먼저, 가상 스레드를 일목요연하게 정리해 주신 카카오 안정수(James.star)님께 감사드린다. 아래 링크를 통해 영상을 볼 수 있다. https://youtu.be/vQP6Rs-ywlQ 추가로 Oracle에서 제공한 Virtual Thread 문서를 참고하여 가상 스레드를 정리해 보았다. 예시코드는 모두 아래 깃헙에서 볼 수 있다. https://github.com/gihyeon6394/hello-java-virtualthread GitHub - gi..
2024.01.04
-
ELK 스택으로 구축하는 로그 수집, 시각화
목차모니터링 방법과 ELK 스택구축해 보기모니터링 방법과 ELK 스택 어제 8시 즈음 회원 서버 로그 좀 봐볼까? (회원 서버만 10대인데요?) 애플리케이션이 많아질수록 개발자 (관리자)가 조회해야 하는 애플리케이션 관련 데이터가 급격히 늘어난다. metric, 로그 데이터와 같은 것들이다. 애플리케이션이 한 개이고, 레플리카도 하나라면 직접 서버에 접속해 로그 파일을 추적해 보면 되지만, 여러 대인 상황에서는 쉽지 않다. APM (Application Performance Monitoring) 솔루션을 사용하면 애플리케이션의 실시간 모니터링이 가능하다. 성능 관련 데이터는 실시간에 가깝게 조회되어야 하는 데이터지만, 로그나 사용자 추적 데이터 (히스토리, 페이지 이동 이력 등)는 성격이 다르다...
2024.07.24
-
[JPA] JPA와 @Transactional
@Transactional은 Spring AOP를 기반으로 동작하는 프락시이기 때문에 AOP에 대한 이해가 없다면 먼저 이해한 뒤 보길 바란다. 아래 두 포스팅을 참고해도 좋다. 2023.12.02 - [Programming/JAVA] - [Java] AOP 1편 - 핵심 기술 Proxy, Dynamic proxy, Factory bean [Java] AOP 핵심 기술 - Proxy, Dynamic proxy, Factory bean 목차 AOP란 프락시(Proxy)의 정의, 프락시 패턴 다이내믹 프락시 다이내믹 프락시 예제 한계 스프링의 ProxyFactoryBean : 어드바이저 Spring 3대 기술 (DI, PSA, AOP) 중 하나인 AOP는 프락시 기반으로 동작한 kghworks.tistory..
2023.12.03
-
[Spring] AOP 2편 - Spring의 AOP과 @Transactional
2023.12.02 - [Programming/JAVA] - [Java] AOP 핵심 기술 - Proxy, Dynamic proxy, Factory bean [Java] AOP 핵심 기술 - Proxy, Dynamic proxy, Factory bean 목차 AOP란 프락시(Proxy)의 정의, 프락시 패턴 다이내믹 프락시 다이내믹 프락시 예제 한계 스프링의 ProxyFactoryBean : 어드바이저 Spring 3대 기술 (DI, PSA, AOP) 중 하나인 AOP는 프락시 기반으로 동작한 kghworks.tistory.com 이전 포스팅에서 이어진다. 이번 포스팅에서는 트랜잭션을 스프링 AOP를 사용해 구현해 본다. 스프링이 제공하는 어노테이션 @Transactional을 사용해 더 직관적이고 간단..
2023.12.03
-
[Message Brokers] Streaming data와 Pub / Sub system
목차 Streaming Data Streaming Data를 쿼리하는 방법 Algebraic Operations Publish / Subscribe system [참고] 트위터의 데이터 처리 방식 Streaming Data : 지속적인 데이터 흐름 웹 서비스에서의 데이터는 주로 데이터베이스 시스템에서 관리된다. Relational Database Management System (RDBMS, 관계형 데이터베이스)가 대표적이다. 데이터베이스에 저장된 데이터를 불러오기 위해 많은 client들이 질의 (query)하는데 이 질의를 지속적으로 (혹은 주기적으로) 해야 하는 데이터들이 있다. 예를 들면, SNS 게시글은 데이터가 추가될 때마다 엄청난 질의가 들어올 것이다. 호날두가 인스타그램에 글을 올리면 해당..
2023.11.25
-
[Java] JPA N+1 원리 이해하기
목차 N+1 문제 정의 N+1 원인 1. 연관관계의 주인이 누구인가 N+1 원인 2. JPQL은 연관객체의 fetchType을 모른다 N+1 해결방법 정리 참고 포스팅에는 아주 간단히 아래 2개의 테이블을 사용한다. @Entity @Table(name = "team") public class Team { @Id private String id; private String name; @OneToMany(mappedBy = "team", fetch = FetchType.LAZY) private List members = new ArrayList(); // 생략 } @Entity @Table(name = "member") public class Member { @Id private String id; priv..
2023.11.14
-
[클라우드] 가상화 - 클라우드 컴퓨팅의 핵심 기술
목차 가상화란 가상화 구성요소 가상화 방식 가상화란? 컴퓨터 분야에서 가상이란 말이 붙으면 logical의 동의어로 물리적으로 실체가 있지 않은 무언가를 뜻한다. 가상화는 컴퓨터를 하나의 인스턴스(머신)의 개념으로 간주하여 물리적인 컴퓨터를 인스턴스(머신) 수준으로 가상화한 것을 말한다. 즉 IT 리소스를 논리적으로 분할하는 기술이다. 왜 가상화를 하나? 컴퓨터를 인스턴스로 가상화하여 하나의 컴퓨터 (Host)에서 1개 이상의 가상 컴퓨터를 논리적으로 운용할 수 있기 때문이다. 가상화를 통해 하나의 물리적 하드웨어에 여러 개의 컴퓨터 (인스턴스, 머신)를 운용할 수 있다. 가상화는 굳이 클라우드 컴퓨팅 기술을 사용하지 않더라도 가능하다. 가상화를 할 수 있는 프로그램을 Host 컴퓨터에 설치한다면 해당 ..
2023.10.25
-
[Database] 인덱스 (Index) 1장 : 필요성과 기본 컨셉
특정 DBMS에 대한 인덱스 구조가 아닌 데이터베이스 시스템 자체에 대한 인덱스에 대해 정리한다. 기본 개념, 종류와 메커니즘에 대해 말하겠다. 전체적인 흐름은 데이터베이스 시스템 (Abraham Silberschatz , Henry F. Korth , S. Sudarshan 저)의 14장 Indexing을 따른다. 1개 이상의 DBMS에서 인덱스를 생성해봤고, 인덱스에 대한 이해가 어느 정도 있다면 더 수월하게 포스팅을 읽어나갈 수 있을 것이다. 첫 번째 포스팅으로 데이터베이스에서 인덱스의 필요성과 기본 콘셉트를 정리한다. 목차 인덱스의 필요성 좋은 인덱스를 판별하는 기준 search key 인덱스 생성하기 인덱스의 필요성 데이터베이스의 인덱스를 책의 색인에 비유하곤 한다. 책의 색인 데이터베이스 인덱..
2023.10.12
-
[개발일지] 채번(採番) 개발하기
채번(採番)이란 번호를 딴다는 의미로 번호표의 목적으로 DBMS에서 PK 혹은 고윳값을 부여할 때 사용하는 용어다. 일본말이라고 함. 채번되는 값이 업무적으로 의미 있는 값이건, 단순 고윳값이건 각각의 목적이 충분히 존재한다. 나의 경우 고객에게 노출하는 값은 아니었지만 고윳값을 가지면서 SELECT도 가능해야 했다. (이건 이후에 후술) 웹서비스에서 채번 하는 업무는 꽤 있다. (계좌번호, 자동차 번호판 등) 단순히 sequence (ORACLE), auto_increment (MYSQL) 등 사용해 채번 할 수 있지만 그 이상의 요구사항이 존재한다. 채번 결과가 어떤 포맷을 유지해야 한다던지 등..(계좌번호, 자동차 번호판 등) 이번 포스팅에서는 채번 프로세스를 어떻게 개발하게 되었는지 과정과 결과를..
2023.10.05
-
[Java] Java 8 사용하기 : 람다와 스트림으로 리팩터링
목차 람다로 대체할 수 있는 코드 method reference로 한번 더 리팩터링 Streams를 활용한 declarative programming 람다와 OOP 디자인 패턴 https://kghworks.tistory.com/140 [Java] Java 8 사용하기 : 가독성과 유연성, 람다와 Streams API 목차 Java 8로 향상되는 가독성과 유연성 익명 클래스 -> 람다 표현식 람다 표현식 -> 메서드 참조 명령적 데이터 가공 -> Streams API 함수형 인터페이스 Java 8 이상의 버전을 사용하면서 legacy를 Java 8 kghworks.tistory.com 앞선 포스팅에서 Java 8이 제공하는 람다와 스트림에 대한 유용함을 간단히 알아보았다. 이번에는 기존 코드들을 람다로 ..
2023.09.23