전체 글
-
람다 자기 함수 재지정을 통한 Lazy 캐싱 패턴 이해하기kotlin 2025. 11. 28. 17:14
람다 안에서 자기 자신을 재정의하면 어떤 일이 벌어질까?ViewModel에서 “첫 호출만 실행 & 이후 호출은 캐싱된 값 반환” 패턴의 동작 원리를 완전히 이해하기.Objective"ViewModel 내부에서 expensive한 suspend 함수 호출을 단 한 번만 수행하고, 이후에는 캐싱된 Boolean 값만 반환하는 패턴을 완전히 이해한다."이 Objective는 다음과 같은 실제 현업 문제에서 출발한다:DataStore/DB/Repository 호출은 비싸다 → 매 호출마다 접근하면 안 됨ViewModel에서는 한 번만 값 계산 + 이후에는 메모리에 저장된 값 재사용하는 패턴이 필요함Kotlin에서는 이걸 “람다(self-replacing lambda)” 패턴으로 구현할 수 있음하지만 이 패턴은 ..
-
ScrollableState recompostion을 막는 derivedStateOf 완전 이해하기Android 2025. 11. 28. 16:52
Jetpack Compose 를 쓰다 보면 스크롤할 때 Recomposition 이 미친 듯이 발생하는 경우가 종종 있다.특히 ScrollState.value 를 직접 읽어 UI를 제어하는 경우, 스크롤 1px 움직이는 순간마다 전체 UI가 재구성될 수 있다.오늘은 이 문제를 해결하는 마법 같은 도구👉 derivedStateOf를 이해하고, 실제로 얼마나 Recomposition이 줄어드는지 카운팅 예제까지 보여주겠다.문제의 코드: "스크롤 1px마다 재구성됩니다"다음 코드는 스크롤 시 바닥에 Fade Shadow를 표시하는 예제다.if (scrollState.maxValue > 0 && scrollState.value 여기서 문제는…scrollState.value 가 스크롤할 때 매 픽셀마다 업데이트..
-
Room에서 CASCADE ON DELETE + REPLACE(=DELETE + INSERT) 의 충돌시 전략 정리Android 2025. 11. 28. 16:32
Room 데이터베이스를 사용하다 보면, 두 테이블을 Foreign Key 로 연결해 참조 무결성(referential integrity) 을 유지하고 싶고, 동시에 Row 업데이트 시 CASCADE 를 통해 데이터 일관성을 유지하고 싶은 상황이 자주 생긴다.하지만 실제로 구현해보면 다음과 같은 문제가 생긴다.문제: CASCADE ON DELETE + REPLACE(=DELETE + INSERT) 의 충돌Room에서 @Insert(onConflict = REPLACE) 는 내부적으로 "DELETE → INSERT" 로 동작한다.이 때문에:부모 테이블에서 REPLACE 로 데이터를 삽입내부적으로 기존 row DELETECASCADE DELETE 발동 → 자식 테이블 row 모두 삭제됨이후 INSERT 로 새..
-
[CodeReadability] 8장 Code Reivewkotlin/[Book] Code Readability 2025. 11. 9. 16:13
Objective코드 리뷰(Code Review)를 통해 코드의 가독성, 품질, 생산성을 높인다.코드 자체만이 아니라 “리뷰 과정” 또한 효율적이고 협력적으로 설계해야 한다.Key Results[KR1] 리뷰 요청자는 리뷰하기 쉬운 Pull Request(PR)을 만든다.[KR2] 리뷰 수행자는 코드를 “비판”이 아닌 “협업”의 관점에서 검토한다.[KR3] 리뷰의 핵심은 “변경의 의도와 책임 범위”를 명확히 하는 것이다.[KR4] PR의 크기와 구조를 조절해 리뷰 생산성을 높인다.[KR5] 리뷰 코멘트의 목적은 코드 품질 향상이 아니라 지속 가능한 팀 협업이다.Part 1. 리뷰의 필요성과 본질개념코드 리뷰는 단순히 오류를 찾는 과정이 아니라,가독성(Readability)논리적 정확성(Logic corr..
-
Actor의 생명주기 (공유 자원은 언제까지 살아있는가?)kotlin/coroutine 2025. 11. 9. 15:41
Actor의 내부에서 관리하는 공유 자원(lifecycle-managed resource) 은 “Actor 코루틴의 생명주기(lifecycle)”에 종속적으로 존재합니다.Actor의 생명주기가 곧 그 내부 상태(State)와 자원의 생명주기다.1️⃣ Actor의 생명주기(Lifecycle)란?Kotlin에서 Actor는 CoroutineScope.actor 로 생성되죠.fun CoroutineScope.counterActor() = actor { var count = 0 // 내부 상태 for (msg in channel) { when (msg) { is Inc -> count++ is Get -> msg.response.complete(c..
-
Actor 모델을 통한 동시성 문제 해결kotlin/coroutine 2025. 11. 9. 15:35
1️⃣ Actor 모델의 본질개념 요약Actor = 독립된 코루틴 + 메시지 큐(Channel)외부에서는 actor.send(Message) 로만 상호작용 가능내부 상태는 오직 해당 Actor 코루틴 안에서만 수정 가능즉, 여러 스레드가 동시에 Actor의 내부 상태를 건드릴 수 없습니다.→ 이게 Actor가 race condition을 구조적으로 줄이는 핵심 원리입니다.2️⃣ 일반적인 race condition 예시일반 코드 (shared mutable state)var counter = 0fun main() = runBlocking { val jobs = List(1000) { launch { repeat(1000) { counter++ } // race 발생 가..
-
비동기 의존 완화 (Asynchronous Dependency Mitigation) 가이드kotlin/coroutine 2025. 11. 9. 15:07
Objective비동기 로직에서 발생하는 양방향 의존성(circular dependency) 을 제거하고, caller → callee 단방향 구조로 유지한다.즉, “콜백 기반 제어”를 “결과 반환 기반 구조”로 전환함으로써 테스트 가능한 단방향 의존 설계를 실현한다.Key Results[KR1] 콜백 기반 구조에서 caller와 callee 간의 순환 참조를 제거한다.[KR2] Promise / Future / Coroutine / Actor / async-await 같은비동기 패턴을 활용해 단방향 데이터 흐름을 만든다.[KR3] 비동기 결과를 반환값(return value) 으로 표현한다.[KR4] 모든 비동기 함수는 “caller는 관찰자, callee는 수행자” 역할로 명확히 분리한다.[KR5] ..
-
[Code Readability] 7장 Dependency (의존성의 가독성 설계)kotlin/[Book] Code Readability 2025. 11. 9. 13:15
Objective코드의 가독성을 해치는 가장 큰 요인은 “불투명한 의존성” 이다.좋은 코드란 “무엇이 무엇에 의존하는지”를 한눈에 알 수 있어야 한다.이를 위해 결합도(coupling)를 줄이고, 방향(direction)을 정하며, 중복(redundancy)을 없애고, 명시성(explicitness)을 높인다.Key Results[KR1] 의존성은 가능한 한 비순환(acyclic) 구조로 유지한다.[KR2] 강결합(content/common/control coupling) 을 피하고, 데이터 중심 결합(data coupling) 을 선호한다.[KR3] caller → callee, concrete → abstract, complex → simple 방향을 지킨다.[KR4] 중복된 의존성 관계를 제거해, ..