Skip to content
Beside the Wheel
Search
Ctrl
K
Cancel
Email
GitHub
Select theme
Dark
Light
Auto
공부
(5)
spot 인스턴스에서 서버 가용성 개선하기
eBPF로 서버 성능 Profiling하는 법: Pyroscope의 구현 살펴보기
정수론부터 RSA까지
strace로 shaka-packager 버그 추적
Kubernetes The Hard Way
TIL
(956)
AI
(43)
DevOps
(230)
Network
(61)
OS
(155)
개발
(113)
데이터베이스
(64)
서버
(72)
수학
(20)
알고리즘
(24)
암호학
(32)
언어
(113)
컴퓨터구조
(5)
코드
(24)
독후감
(43)
과학
(1)
사회
(2)
산문
(3)
소설
(12)
인문
(11)
자기계발
(7)
철학
(7)
생각
(6)
고민
변화에 대하여
의식의 영역에 대하여
본질을 보려면
짧은 생각들
소유냐 존재냐
회고
(14)
2022.03-04 대덕소마고 입학소감/다짐
2022.05-08 프로젝트와 인간관계
2022.09-2023.02 불안과 판단
2023.03-07 DMS 리더 회고
2023.08-11 나는 누구인가?
2023.12 더 많은 걸 배우기 위한 경험
2024.01-02 회사 인턴 회고
2024.03-04 고3 근황
2024.05-07 고등학교 마무리
2024.08-12 첫 회사
2025.01-03 입출력
2025.03-08 효능감이란 무엇일까
2025.09-12 연말회고
2026.01-08 담론
Email
GitHub
Select theme
Dark
Light
Auto
태그: 코드
총 24개의 글이 있습니다.
Kotest
kotlin
2024. 3. 13.
코틀린에서는 아래와 형태와 같은 DSL(Domain Specific Language) 스타일의 중괄호를 활용한 코드 스타일을 제공한다. 코틀린 내부에서 제공하는 Standard library 대부분도 DSL을 이용해 작성된 것을 볼 수 있다. [Type safe builders]( [Kotlin Stand
Kotest Assertions
kotlin
2024. 3. 13.
Assertions shouldBe kotlin name shouldBe "eunbin" // == assertThat(name).isEqualTo("eunbin") Inspectors forExactly kotlin mylist.forExactly(3) { it.city shouldBe "Chicago" } forAtLeast kotlin val xs = listOf("sam", "gareth", "timothy", "muhammad") xs.forAtLeast(2) { it.shouldHaveMinLength(7) } Except
Kotest Specs
kotlin
2024. 3. 13.
Kotest는 10가지 다른 스타일의 테스트 레이아웃을 제공한다. 그중 일부는, 다른 테스트 프레임워크와 비슷한 구조로 만들어지기도 했다. 스타일 간에 기능적인 차이는 없다. 스레드, 태그 등 모두 동일한 유형의 구성을 허용하지만, 이는 단순히 테스트를 구성하는 방법에 대한 선호도의 문제이다. 코테스트를 사용하려면 테스트 스타일 중 하나를 확장하는 클래스 파일을 만들어야 한다. 그런 다음 원하는 Spec (추상)클래스를 상속받고 init {} 블록 안에서 테스트 케이스를 작성하면 된다. |테스트 스타일|유사한 테스트 프레임워크| |-|-| |Fun Spec|ScalaTest| |String Spec|A Ko
Mockk
kotlin
2024. 3. 13.
!image.willReturn(expectedUser) //Mockk every { userRepository.findById(1L) } answers { expectedUser } Mockk의
Mock과 Spy
testcode
2024. 3. 13.
Mockito 등의 라이브러리를 쓰다보면, Mock과 Spy를 사용하게 될 것이다. 둘 다 클래스의 가상 객체를 만들어서 메소드와 필드를 모의 실험하기 위해 쓰인다는 공통점이 있다. 그렇다면 차이점은 무엇일까? 비교 간단히 말하자면, Mock은 완벽한 가짜 객체를 만드는데 반해, Spy는 기본적으로 기존에 구현되어있는 동작을 따르고 일부 메소드만 stub 한다. Mock 객체의 함수를 호출했을때 그 함수에 stub된 동작이 없으면 코드나 라이브러리에 따라 문제가 생길 수 있다. strict 하게 규칙이 설정된 라이브러리(`ex. mockk`)의 경우에는 호출 즉시 예외가 던져질 수 있고, null이나 기본값 (`int = 0, String = ""...`)이 반환되도록 되어있을 수도 있다.(
cold stream과 hot stream
비동기
2024. 3. 13.
flow에서 사용되는 개념인 cold stream과 hot stream에 대해 알아보고, 서로 비교해보자. 우선 observable과 producer의 개념에 대해 알아보자. observable Observable은 observer를 producer에 연결해주는 함수이다. obserable을 함수처럼 call하면 observer에 값이 전달된다고 생각하면 된다. producer producer는 obserable의 실행 값이다. producer는 web socket이 될 수도 있고, DOM event가 될 수 있고, iterator도 될 수 있다. 보통은 `observer.next(value)`를 통해 값을 받는 것이 producer라고 생각할 수 있다. cold stream cold s
Coroutine vs Reactor
비동기
2024. 3. 13.
코틀린 코루틴과 리액티브 스트림의 구현체 중 하나인 Reactor의 차이점은 무엇이 있을까? 아래와 같이 사용자의 정보를 받아 환영 메세지를 생성한 후 반환하는 메서드가 있을때, 이 메서드를 호출하는 코드를 각 방식으로 작성해보자. kotlin fun generateWelcome( usernameOrIp: String, userProfile: UserProfile?, // 프로필 정보 block: Block?, // 차단 여부 ): WelcomeMessage = when { block != null -WelcomeMessage( "You are blocked. Reason: ${block.reason}", WARN
Channel
coroutine
2024. 3. 13.
Channel은 2개의 Coroutine 사이를 연결한 파이프라고 생각하면 된다. 이 파이프는 두 Coroutine 사이에서 정보를 전송할 수 있도록 한다. 하나의 Coroutine은 파이프를 통해서 정보를 보낼 수 있고, 다른 하나의 Coroutine은 정보를 받기위해 기다린다. 이 채널을 통한 두 Coroutine간의 커뮤니케이션은 공유메모리가 아닌, 커뮤니케이션을 통해서 이뤄진다. Thread는 어떻게 Communicate 할까 소프트웨어를 만들면서 Resource를 Blocking하는 작업, 예를 들면 네트워킹이나 DB를 사용하거나 아니면 계산이 필요한 작업을 할때 우리는 그 작업들을 쓰레드로 분리한다. 이 쓰레드간에 공유할 자원이 필요할때 우리는 두개의 쓰레드가 동시에 그걸 쓰거나 읽게
Coroutine CPS
coroutine
2024. 3. 13.
Kotlin coroutines are managed at the JVM level using the concept of "continuations." Continuations are a programming technique that allows suspending the execution of a function at a certain point and resuming it later from where it left off. Coroutines build upon this concept to provide a high-level and efficient way to write asynchronous code. Continuation When a code with suspend is conv
Coroutine Delay
coroutine
2024. 3. 13.
아래와 같은 timeout(혹은 delay)가 내부적으로 어떻게 동작하는지 알아보자. kotlin GlobalScope.launch { withTimeout(10) { ... } } 일단 `withTimeout`의 코드를 살펴보자면 아래와 같다. 가장 아랫부분을 보면 time이 실제로 track되는 것은 CoroutineDispatcher의 구현이라고 적혀있다. Implementation note: how the time is tracked exactly is an implementation detail of the context's [CoroutineDispatcher]. kotlin / * Runs a given suspending [block
Coroutine Dispatcher
coroutine
2024. 3. 13.
Coroutines always execute in some context represented by a value of the CoroutineContext type, defined in the Kotlin standard library. The coroutine context is a set of various elements. The main elements are the Job of the coroutine, which we've seen before, and its dispatcher, which is covered in this section. The coroutine context includes a co
Coroutine Scope, Context
coroutine
2024. 3. 13.
To launch a coroutine, we need to use a coroutine builder like launch or async. These builder functions are actually extensions of the `CoroutineScope` interface. So, whenever we want to launch a coroutine, we need to start it in some scope. kotlin public interface CoroutineScope { / * The context of this scope. * Context is encapsulated by the scope and used for implementation
Integration
coroutine
2024. 3. 13.
kotlin interface Service { fun savePost(token: Token, item: Item): Call } suspend fun createPost(token: Token, item: Item): Post = serviceInstance.savePost(token, item).await() Let's say you want to use Coroutine with code that used futur (which corresponds to several libraries such as reactor). We are going to call 'savePost' which returns the future 'Call' from 'createPost'. I
공유객체 스레드 동기화
thread
2024. 3. 13.
동시에 읽고 쓰이는 공유 객체에서 스레드 동기화를 적절하게 사용하는 방법에 대해 알아보자. Atomic Synchronized block 스레드 한정 Mutex Actor AtomicInteger CAS(Compare And Swap) 알고리즘을 사용한다. 원리를 간단하게 말하자면, 변경하려는 값과 현재 저장된 값을 비교해서 같으면 변경하고 다르면 값을 변경하지 못하게 하는 것이다. 변경하려는 값과 현재 저장된 값이 다른 경우는 중간에 다른 스레드에 의해 값이 변경된 경우로 볼 수 있기에 변경을 허용하지 않는다. 사용법은 아래와 같다. kotlin suspend fun exampleFun(action: suspend () -Unit) { val n = 100 val k = 1
코루틴
coroutine
2024. 3. 13.
프로그래밍 언어에는 루틴이라는 개념이 있다. kotlin fun main() { ... val addedValue = plusOne(value) } fun plusOne(value: Int) { return value + 1 } 위와 같은 코드가 있다고 했을떄, main 함수가 메인루틴이고 함수를 호출해서 이동하는 것은 서브루틴이라고 부른다. 서브루틴은 진입하고, 빠져나오는 지점이 명확하다. 메인 루틴이 서브루틴을 호출하면, 서브루틴의 맨 처음 부분에 진입하여 return문을 만나거나 서브루틴의 닫는 괄호를 만나면 해당 서브루틴을 빠져나오게 된다. 그리고 진입점과 탈출점 사이에 쓰레드는 블락되어있다. 우리가 보통 짜는 코드는 이렇게 동작한다. 그러나 코루틴(Coro
Flow
비동기
2024. 3. 13.
coroutine의 Flow는 데이터 스트림이며, 코루틴 상에서 리액티브 프로그래밍을 지원하기 위한 구성요소이다. `kotlinx-coroutines-core-jvm` 라이브러리의 `kotlinx.coroutines.flow` 패키지에 인터페이스로 정의되어있다. kotlin public interface Flow { public suspend fun collect(collector: FlowCollector) } Flow 생성시 연산자(`map`, `filter`, `take`, `zip` 등)들이 추가되면 Flow (SafeFlow) 의 형태로 체인을 형성하게 되고 `collect()` 호출 시 루트 스트림 (최상위 업스트림) 까지 `collect()`가 연쇄적으로 호출되어 데이터
netty 사례연구
비동기
2024. 3. 13.
파일을 업로드하면 그 파일을 순간 공유할 수 있도록 하는 플랫폼이 있다고 해보자. 그 파일 자체는 아마존 S3에 저장된다. 간단한 업로드 흐름을 구축하자면 아래와 같이 할 수 있다. 1. 전체 파일을 수신한다. 2. S3로 업로드한다. 3. 이미지인 경우 섬네일을 생성한다. 4. 클라이언트 애플리케이션에 응답한다. 여기에서는 2단계와 3단계가 병목 지점이 될 수 있다. 클라이언트에서 서버로 아무리 빠른 속도로 업로드하더라도 실제 드롭을 생성하고 클라이언트에 응답하려면 업로드가 완료된 후 파일을 S3로 업로드라고 섬네일을 생성할 때까지 오랫동안 기다려야했다. 파일이 클수록 대기 시간은 길었고, 아주 큰 파일의 경우 서버로부터 응답을 기다리다가 시간이 만료되는 경우도 있다. 업로드 시간을 줄이기 위한
Callback과 Futures
reactor
2024. 3. 13.
어떻게 해야 JVM 위에서 비동기적인 코드를 작성할 수 있을까? Java는 asynchronous programming을 위해 두가지 모델을 제공한다. Callbacks: return 값을 직접 가지지 않고, 비동기 처리가 끝난 후 result 값을 가져올 수 있을때 추가 callback parameter(a lambda or anonymous class)를 가져오는 Asynchronous 메서드이다. Swing의 `EventListener`와 그 구현 클래스들이 대표적인 예시이다. Futures: `Future`를 즉시 반환하는 Asynchronous 메서드이다. The asynchronous process computes a T value, but the Future object wr
Reactor
reactor
2024. 3. 13.
Reactor란 Pivotal의 오픈소스 프로젝트로, JVM 환경에서 동작하는 non-blocking reactive 라이브러리로서 non-blocking IPC(Inter-Process Commumication)을 지원한다. Reactive Programing 반응형 프로그래밍(reactive programming)은 데이터 스트림과 변화의 전파와 관련된 선언적 프로그래밍 패러다임이다. 이 패러다임을 사용하면 정적 또는 동적 데이터 스트림을 쉽게 표현할 수 있다. In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change. Wi
Reactor Pattern과 event loop
reactor
2024. 3. 13.
Reactor 패턴은 동시에 들어오는 여러 종류의 이벤트를 처리하기 위한 동시성을 다루는 디자인 패턴 중 하나이다. Reactor 패턴은 관리하는 리소스에서 이벤트가 발생할 때까지 대기하다가 이벤트가 발생하면 해당 이벤트를 처리할 수 있는 핸들러(`handler`)에게 디스패치(`dispatch`)하는 방식으로 이벤트에 반응하며, '이벤트 핸들링(event handling)', event loop 패턴이라고도 부른다. Reactor 패턴은 크게 Reactor와 핸들러로 구성된다. |name|description| |-|-| |Reactor|무한 반복문을 실행해 이벤트가 발생할 때까지 대기하다가 이벤트가 발생하면 처리할 수 있는 핸들러에게 디스패치한다. 이벤트 루프라고도 부흔다.| |Handler|이벤트를
DependencyHandler
gradle
2024. 3. 13.
DependencyHandler을 생성해주는 인터페이스이다. kotlin public interface DependencyHandler extends ExtensionAware { @Nullable Dependency add(String configurationName, Object dependencyNotation); Dependency add(String configurationName, Object dependencyNotation, Closure conf
Git action gradle caching
gradle
2024. 3. 13.
Gradle은 빌드할때 의존성 패키지들을 모두 다운받는다. 이때 Gradle은 빌드 시간과 네트워크 통신을 줄이기 위해 의존성 패키지를 캐싱해서 재사용하는 방법을 사용한다. 하지만 Github Actions의 workflow는 매 실행하다 새로운 환경을 구축하고, 매번 새롭게 의존성 패키지들을 가지고 와야 한다. 이는 전체 빌드 시간의 증가로 이어진다. 빌드 시간의 단축을 위해서 우리는 Github Actions의 actions/cache를 사용해서 gradle의 의존성을 캐싱할 수 있다. yml name: Gradle Caching uses: actions/cache@v3 with: path: | ~/.gradle/caches ~/.gradle/w
Gradle LifeCycle
gradle
2024. 3. 13.
Gradle은 의존성 기반의 프로그래밍용 언어이다. 이 말은 태스크를 정의하고 또한 태스크들 사이의 의존성도 정의 할 수 있다는 뜻이다. Gradle은 태스크들이 의존성의 순서에 따라 실행되고, 오직 한 번만 실행될 것임을 보장한다. Gradle은 태스크를 실행하기 전에 완전한 의존성 그래프를 구축한다. 빌드 단계 Gradle 빌드는 3단계로 구분된다. md Initialization Gradle supports single and multi-project builds. During the initialization phase, Gradle determines which projects are going to take part in the build, and creates a Project
멀티모듈
gradle
2024. 3. 13.
멀티모듈은 하나의 프로젝트를 여러개의 모듈로 구성하는 것을 말한다. 모듈은 독립적으로 운영될 수 있는 의미를 가지는 구성요소 단위이며, 다른 모듈과의 상호작용으로 애플리케이션을 구성한다. intelij에서는 가장 상위 프로젝트에서 마우스 오른쪽 클릭을 하고, New Module 을 선택 후, 모듈 이름을 입력하면 프로젝트 내부에 여러개의 모듈을 만들 수 있다. 멀티모듈을 생성하면 모듈별로 `build.gradle` 파일이 생기기 때문에, 각 모듈에 맞게 의존성을 설정할 수 있다. 메인 프로젝트의 `build.gradle`에서는 모든 모듈에 대해 공통적인 설정을 적용할 수도 있다. subprojects { } allprojects { } subprojects에서는 메인 프로젝트