본문 바로가기

전체 글143

[Android/Compose] LazyColumn vs RecyclerView 비교 : RecyclerView 없이 리스트 만들기 Jetpack Compose를 공부하면서 LazyColumn을 접하게 되었습니다.기존에는 리스트 성능을 최적화하려면 RecyclerView를 사용하고, 그때마다 Adapter와 ViewHolder를 직접 구현해야 했습니다.그런데 LazyColumn을 사용하면 코드가 훨씬 간결해지면서도 자동으로 성능이 최적화된다는 점이 신기했습니다.그래서 기존 RecyclerView와 비교하며 어떤 차이가 있는지 정리해보려고 합니다.1. 기존 RecyclerView의 동작 방식RecyclerView는 리스트의 성능을 최적화하기 위해다음과 같은 요소들을 개발자가 직접 구현해야 합니다.Adapter → 리스트 데이터를 표시하는 역할 ViewHolder → 뷰를 재사용하여 성능을 최적화 LayoutManager → 리스트의 배.. 2025. 2. 19.
[Android/Coroutine] launch vs async 차이점 정리 Coroutine에서 launch와 async는 모두 새로운 코루틴을 시작하는 데 사용되지만, 반환값을 처리하는 방식이 다릅니다.이 글에서는 공부한 내용을 정리하며, launch와 async의 차이를 코드 예제와 함께 살펴보겠습니다.1. launch: 결과를 반환하지 않는 Jobval job = GlobalScope.launch { delay(1000L) println("launch 완료!")}job.join() // 완료될 때까지 대기특징launch는 Job을 반환합니다.Job은 단순히 실행을 시작하고, join()을 호출하기 전까지는 실행 완료 여부를 기다리지 않습니다.launch는 비동기적으로 실행되지만, 결과 값을 반환하지 않습니다.즉, 실행은 하지만 결과를 받아서 처리하는 용도가 아닙.. 2025. 2. 19.
[Algorithm/Kotlin] 백준 11659번 구간 합 구하기 4: 누적 합(Prefix Sum)을 활용한 풀이법 문제 설명주어진 수열에서 특정 구간 [i, j]의 합을 여러 번 구해야 하는 문제입니다. 입력으로 N개의 수와 M개의 구간이 주어집니다. 각 구간에 대해 빠르게 합을 구하는 프로그램을 작성해야 합니다. 제한 사항1 ≤ N ≤ 100,0001 ≤ M ≤ 100,0001 ≤ i ≤ j ≤ N각 숫자는 1,000 이하의 자연수문제 해결 아이디어기본 접근법 (O(N × M), 시간 초과 가능)   M개의 구간 합을 구하기 위해 for 루프를 사용해 N개의 값을 더하면 O(N × M) 시간이 걸립니다.   N, M이 최대 100,000일 경우 10^10 이상의 연산이 발생하여 비효율적입니다.누적 합(Prefix Sum) 기법 (O(N + M), 효율적)   먼저 누적 합 배열을 생성하여 O(N) 시간에 각 위치까.. 2025. 2. 19.
[DataStructure/Kotlin] Kotlin에서 Array, List, MutableList, ArrayList의 차이 정리 Kotlin에서는 Array, List, MutableList, ArrayList 등 다양한 컬렉션 타입을 사용할 수 있습니다.이들은 모두 여러 개의 값을 저장하는 자료구조이지만, 동작 방식과 활용법이 서로 다릅니다.이번 글에서는 각 자료구조의 특징과 차이점, 그리고 언제 어떤 것을 사용해야 하는지 정리하겠습니다.1. Array vs List → 수정 가능 여부 차이Array는 값 변경 가능하지만 크기 변경은 불가능val arr = arrayOf(1, 2, 3)arr[0] = 10 // 값 변경 가능println(arr.joinToString()) // 10, 2, 3// arr.add(4) // 컴파일 오류 (크기 변경 불가능)Array는 배열 크기가 고정되어 있지만, 인덱스를 통해 값 변경이 가.. 2025. 2. 13.
[DataStructure/Tree] 우선순위 큐, 힙, 이진 탐색 트리의 개념과 차이점 정리 트리 자료구조를 공부하다 보니 이진 트리(Binary Tree), 힙(Heap), 이진 탐색 트리(BST), 우선순위 큐(Priority Queue) 등의 개념이 서로 얽혀 있어 혼란스러웠습니다.각 개념의 관계를 정리하면 트리를 더 잘 이해하는 데 도움이 될 것 같아, 이번 기회에 깔끔하게 정리해 보았습니다.1. 이진 트리 (Binary Tree)개념각 노드는 최대 두 개의 자식 노드를 가질 수 있는 트리 구조입니다.이진 트리는 단순한 자료구조이며, 정렬 방식이나 데이터 접근 규칙이 따로 정해져 있지 않습니다.노드 개수는 최대 2^h - 1 개입니다. (h는 트리의 높이)특징탐색 규칙이 없는 단순한 구조적 개념입니다.왼쪽, 오른쪽 자식을 가지는 트리 형태일 뿐입니다.예시 A / \.. 2025. 2. 12.
[DataStructure/Map, Set, List] Map vs Set vs List: 순서 보장과 중복 허용 차이 정리 Map, Set, List는 대부분의 프로그래밍 언어에서 자주 사용되는 대표적인 자료구조입니다.어렴풋이 알고 있다고 생각했지만, 막상 설명해보려니 정확하게 이해하지 못하고 있다는 느낌이 들었습니다.그래서 이번 글에서는 Map, Set, List의 동작 방식과 구현체별 차이점을 정리하면서, 순서 보장 여부와 중복 허용 여부를 명확하게 정리해두려고 합니다.1. Map, Set, List의 기본적인 차이점특징Map (Key-Value 저장)Set (중복 없는 값 저장)List (중복 허용, 순서 유지)데이터 저장 방식Key-Value 쌍으로 저장중복 없는 단일 값(Value) 저장중복을 허용하며 순서대로 값 저장중복 허용 여부Key 중복 ❌, Value는 중복 가능중복 ❌중복 ⭕순서 보장 여부구현체에 따라 다.. 2025. 2. 12.
[DataStructure/Set] Set의 contains() 시간 복잡도 정리: HashSet, TreeSet, LinkedHashSet 비교 Set을 공부하던 중, Set.contains() 메서드의 시간 복잡도가 궁금했는데, Set의 자료구조 종류에 따라 contains()의 성능이 달라진다는 것을 알게 되었습니다.특히, HashSet, TreeSet, LinkedHashSet과 같이 구현 방식이 다른 Set은 각각 다른 자료구조를 사용하기 때문에 contains()의 시간 복잡도도 다르게 동작합니다.이번 글에서는 Set의 종류별 contains() 성능 차이와 시간 복잡도를 정리해 보겠습니다.1. Set.contains()의 시간 복잡도는 언제 달라질까?Set.contains(element) 메서드는 Set에 특정 요소가 존재하는지 여부를 확인하는 메서드입니다.하지만 Set의 내부 자료구조에 따라 검색 속도가 다르게 동작합니다.HashSe.. 2025. 2. 11.
[DataStructure/LinkedHashMap] LRU 캐시와 LinkedHashMap 기반 Glide Bitmap 최적화 최근에 LinkedList 사용 예제를 공부하던 중, LRU 캐시(Least Recently Used Cache)라는 개념을 알게 되었습니다.LRU 캐시는 오래 사용되지 않은 데이터를 자동으로 삭제하는 캐싱 기법으로, 메모리 관리에서 중요한 역할을 합니다.그런데, LRU 캐시는 단순한 LinkedList가 아니라, "해시 테이블과 이중 연결 리스트가 결합된 LinkedHashMap을 활용하여 구현되는 경우가 많다"는 것을 알게 되었습니다.또한, 안드로이드에서 Glide 라이브러리도 LinkedHashMap을 기반으로 한 LRU 캐시를 활용하여 Bitmap(이미지) 데이터를 캐싱하고 있었습니다.따라서 이번 글에서는 LRU 캐시의 개념과 함께, Glide가 이를 활용하여 어떻게 성능을 최적화하는지 정리해 두.. 2025. 2. 11.
[Algorithm/Kotlin] 백준 1003번 피보나치 함수: DP를 활용한 풀이법 문제 설명주어진 문제는 재귀적으로 정의된 피보나치 함수에서 0과 1이 출력되는 횟수를 구하는 것입니다.C++의 재귀 구현을 보면, fibonacci(n)을 호출할 때 fibonacci(n-1)과 fibonacci(n-2)를 호출하는 방식으로 동작합니다. 이 과정에서 동일한 fibonacci 함수가 여러 번 호출되며 중복 계산이 발생합니다.예를 들어, fibonacci(3)을 호출하면 아래와 같은 과정이 발생합니다:fibonacci(3) -> fibonacci(2) + fibonacci(1)을 호출합니다.fibonacci(2) -> fibonacci(1) + fibonacci(0)을 호출합니다.fibonacci(1)이 1을 출력하고 반환합니다.fibonacci(0)이 0을 출력하고 반환합니다.fibonac.. 2025. 2. 7.
[Android/Compose] Recomposition: 상태 변화에 따른 UI 갱신 Jetpack Compose를 사용하면서 기존 방식과 다르게 LiveData.observe() 같은 코드도 없고, notifyDataSetChanged()를 호출하지 않았는데도 UI가 알아서 갱신되는 것이 신기하게 느껴졌습니다."LiveData도 사용하지 않았는데, 왜 상태가 변하면 UI가 자동으로 업데이트되지?"라는 궁금증이 들었습니다.기존 XML 기반의 View 시스템에서는 명시적인 호출이 필요했지만, Compose에서는 mutableStateOf만으로 UI가 알아서 갱신됩니다. 이는 Recomposition(재구성) 덕분입니다.이번 글에서는 공부한 내용을 바탕으로 Compose의 Recomposition이 무엇인지, 그리고 어떻게 동작하는지를 정리 해 보겠습니다.Recomposition이란?Reco.. 2025. 2. 6.
[Android/Kotlin] mutableMapOf vs hashMapOf 차이점 및 성능 비교 Kotlin에서 Map을 사용할 때 mutableMapOf와 hashMapOf 중 어떤 것을 선택하는 것이 더 좋을까요? 이번 글에서는 두 가지의 차이점과 성능 비교를 통해 언제 어떤 것을 선택하면 좋은지를 알아보겠습니다.1. mutableMapOf vs hashMapOf 차이점mutableMapOfval sitesAndPasswords = mutableMapOf()내부적으로 LinkedHashMap을 사용합니다.입력 순서를 유지하는 특징이 있습니다.성능은 일반적인 HashMap과 동일 (O(1) 조회, 삽입 가능).hashMapOfval sitesAndPasswords = hashMapOf()명시적으로 HashMap을 사용합니다.입력 순서를 유지하지 않음 (순서가 중요하지 않다면 더 적합).성능은 mu.. 2025. 2. 6.
[Android/Compose] Modifier를 파라미터로 전달하는 이유 Jetpack Compose에서 Column과 같은 레이아웃 컴포저블을 사용할 때, Modifier를 기본 인자로 직접 설정할 수 있습니다.그런데, 코드에서 Modifier를 바로 적용할 수 있는데도 불구하고, 굳이 파라미터로 Modifier를 전달하는 방식을 사용하는 이유가 궁금했습니다.이러한 의문을 가지고 공부하던 중, Compose의 재구성(Recomposition)과 성능 최적화와 관련된 중요한 개념을 알게 되었습니다.이 글에서는 왜 Modifier를 직접 선언하는 것이 아니라, 파라미터로 전달하는 것이 더 좋은 방법인지 정리해 보겠습니다.Modifier를 직접 사용하면 생기는 문제처음에는 아래처럼 Column 내부에서 바로 Modifier.padding(16.dp)을 적용하는 것이 자연스러워 보.. 2025. 2. 5.
반응형