개요최근 새로 개발하는 서비스에서 사용자별 정산내역을 엑셀파일로 다운로드할 수 있는 기능을 담당해 개발하게 되었다. 서치를 좀 해보니 "POI" 이라는 아파치 라이브러리를 이용해 엑셀파일을 Java에서 구성할 수 있다는 것을 알 수 있었다. 처음에는 정산내역에서 제공해야하는 데이터 양식에 맞춰 하드코딩한 메서드를 구현하려 했으나, 정산내역 이외의 도메인에서도 엑셀파일을 다운로드 해야하는 이슈가 있었고 유틸리티 클래스를 만들어 전달받는 리스트에 동적으로 대응할 수 있는 메서드를 만들고자 하는 욕심이 생겼다. 본 글에서 그 과정과 배운 내용들을 기록해두고자 한다. 아파치 POI 라이브러리Apache POI는 Apache에서 만든 라이브러리로 MS오피스(엑셀, 워드 등) 파일을 자바 언어로 읽고 쓰는 기..
MergeSort - 합병 정렬합병(병합) 정렬은 문제를 분할하고 분할한 문제를 다시 합치는 과정에서 정렬을 수행하는 알고리즘이며 분할 정복(Divide and Conquer) 알고리즘을 기반으로 두고 있다. 시간복잡도는 모든 상황에서 O(nlog(n))의 시간복잡도를 가진다. 합병 정렬은 문제 분할 후 데이터를 비교하면서 찾기 때문에 비교 정렬이며, 정렬의 대상이 되는 데이터 외에 추가적인 공간을 필요로 하기 때문에 제자리 정렬이 아니다. 예제코드public class MergeSort { private static final Logger logger = Logger.getLogger(MergeSort.class.getName()); private static int[] arr; p..
GoRoutineGoRoutine은 Go언어의 빠른 병렬 처리를 도와주는 경량 스레드이다. 많은 개발자들이 Go를 채택하는 많은 이유 중 하나가 바로 이 GoRoutine이 있기 때문이라고 생각한다. GoRoutine은 OS thread보다 매우 가볍기 때문에 생성 및 관리 비용이 적고, 컨텍스트 스위칭 오버헤드가 적기 때문에 높은 처리량과 낮은 코스트를 보장한다. 또한 구현이 매우 간단해 빠른 개발을 도와준다. 아래는 AI가 작성한 내용이다.Go 언어의 핵심 기능 중 하나인 GoRoutine은 경량 쓰레드로, 일반적인 멀티 스레딩과 달리 OS 쓰레드보다 훨씬 가볍고 효율적으로 동작합니다. GoRoutine은 Go 런타임에 의해 관리되며, go 키워드를 사용하여 함수를 호출하면 해당 함수가 새로운 Go..
Go언어의 접근 제어Java에서는 default, public, protected, private와 같이 접근제어자가 존재한다. Go에서도 다른 패키지에서 import 해온 구조체, 함수, 변수 등에 대해 접근을 제어할 수 있는데 이름 첫 글자의 대/소문자로 판별한다. 예를 들어, 아래와 같이 accounts 패키지에 두 개의 구조체가 있고 구조체명 첫 글자의 대/소문자가 다르다고 할때, AccountA는 public 구조체로 접근이 가능하고 accountB는 private 구조체로 다른 패키지에서 접근이 불가능하다.package accountstype AccountA struct { Owner string Balance int}type accountB struct { Owner string ..
VariablesGo언어의 상수, 변수 선언은 JS(JavaScript)와 TS(TypeScript)의 중간에 있다는 느낌을 받았다. TS처럼 type을 명시하는 것을 기본으로 하고 JS처럼 타입을 명시하지 않고 빠른 개발이 가능하도록 축약형을 제공한다. 하지만, 축약형은 상수가 아닌 변수일때만 가능하고 처음 초기화된 type에서 다른 type으로의 변경을 허용하지 않는다. JS와 같은 편리함은 있지만 그래도 엄격하다.func main() { /* literal */ const firstName string = "jisung" /* variable */ var lastName string = "jung" lastName = "kim" /* 축약형 - 변수에만 사용 가능 ..
Recordrecord는 kafka의 데이터 통신을 위한 객체이며 이를 위해 필요한 값들을 저장하고 있다. record는 프로듀서가 메세지를 보낼 때 사용하는 producer-record와 컨슈머가 메세지를 받을 때 사용하는 consumer-record로 나뉜다. Producer Recordtopicrecord가 어느 topic으로 전송되어야하는지를 저장하는 값이며 레코드 생성시 초기화한다.partition record가 어느 partition으로 전송되어야하는지를 저장하는 값이며 레코드 생성시 초기화해 파티션을 명시하거나, partitioner가 round-robin 방식 또는 hash-key를 이용해 목적지 partition데이터를 세팅한다.headersrecord에 부가적인 정보를 담기 위한 부분..
Kafka Producerkafka 에서 topic에 메세지를 보내는 주체를 producer라고 한다. producer는 kafka-console-producer를 사용할 수도 있지만 보통 프로듀서 애플리케이션으로 구현해 사용한다. kafka에서 지원하는 공식 언어는 java다. python, javascript, golang 등의 언어를 사용해 애플리케이션을 구축할 수도 있지만 공식 지원 언어가 아니기 때문에 구조적/성능적 이슈가 존재할 수 있으니 주의해야한다.kafka library를 이용해 구현한 프로듀서 애플리케이션은 아래와 같은 구조를 가진다. producer record를 사용해 메세지를 전송하고 직렬화 후 partitioner가 producer record를 어떤 partition으로 보..
1. 카프카 등장 배경카프카는 Linked-In에서 소스 애플리케이션고 타켓 애플리케이션을 분리하기 위해 만들어졌다. 기존의 데이터 파이프라인은 아래와 같이 각각의 애플리케이션을 직접 연결하는 구조였는데 아래와 같이 타겟 애플리케이션에 장애가 발생하면 소스 애플리케이션에도 치명적인 문제가 발생한다. 또한, 아키텍처가 복잡해짐에따라 애플리케이션의 갯수가 많아지면서 데이터 파이프라인도 기하급수적으로 복잡해졌다. 이러한 문제를 해결하고자 Linked-In에서는 카프카를 만들어냈고 카프카는 애플리케이션을 직접 연결하는 방식이 아니라 중앙에서 데이터를 처리하는 방식으로 모든 애플리케이션이 카프카를 통해 데이터를 수집하고 분배한다. 2. 카프카의 특징1️⃣ 높은 처리량카프카도 결국 데이터를 전송하려면 송수신..
Kruskal AlgorithmKruskal 알고리즘은 최소신장트리 MST(Minimum Spanning Tree)를 구하는 알고리즘이다. Greedy하게 N개의 정점을 N-1개의 간선을 이용해 최소 비용으로 연결한다. Kruskal 알고리즘의 기본 개념은 Greedy이기 때문에 간선 정보를 가중치 기준으로 오름차순 정렬한다. 다음으로, Union-Find 알고리즘을 이용해 모든 N개의 정점을 N-1개의 간선을 통해 최소 비용으로 연결할 수 있다. 따라서, Kruskal 알고리즘은 Greedy + Union-Find 알고리즘의 개념을 합쳐놓은 알고리즘으로 최소신장트리를 구하는데 이용된다. [Data Structure] Minimum Spanning Tree - 최소 신장 트리노드의 갯수가 n개일때, 간..