New Score :0
High Score :0
Run Best
NICE BUSINESS TYPE INDICATOR
3. ๊ธ์ ์ ์น๊ตฌ์๊ฒ ๋น๋ ธ๋๋ฐ ์ค๋์ด ๋์ ์ฃผ๊ธฐ๋ก ํ๋ .. ๊ทธ๋ฐ๋ฐ ์นด๋๊ฐ์ ๋ด์ผํ๋ ๋ ๋ ์ค๋์ธ๋ฐ... ์ด๊ฑธ ์ด์ฉ๋...
4. ์ฐ๋ฆฌ ํ์ฌ๋ ์ค์ํ ์์ฌ ๊ฒฐ์ ์ ํ ๋?
5. ์ด์ฌํ ์ผํ ๋๋ฅผ ์ํ ์ ๋ฌผ์ ์ฃผ๊ณ ์ถ๋ค. ์ด๋ค๊ฒ ์ข์๊น?
6. ์ํ์์ ํฌ์์ํ์ ์ถ์ฒ๋ฐ์๋ค. ์ด๋ค๊ฑธ ๊ฐ์ ํ์ง?
7. ํ์ฌ์์์ ๋๋?
8. ๊ฟ์์ ๊นจ์ด๋๋ 20๋ ์ ์ผ๋ก ๋์๊ฐ๋ค. ๋น์ ์ด ์ ์ผ ๋จผ์ ํ๋์ผ์?
9. ๋ด๊ฐ ์ธ์ฌ ๋ด๋น์๋ผ๋ฉด ์ ๊ท ์ ์ฌ์ ์ฑ์ฉ ์ ์ ์ผ ์ค์ํ๊ฒ ๋ณด๋๊ฒ์?
10. ํ์ฌ์ ์ ๋ง ์ซ์ดํ๋ ๋๋ฃ๊ฐ ์๋ค๋ฉด?
11. ๊ฐ๋ํ ์ง์ ๊ฐ์ฅ์ด ๋์๋ค.. ์๋ ์ ์์ผ ๋ ์ ๋ฌผ์?
12. ํ์ ํ์ฌ ์ถ๊ทผ ์คํ์ผ์?
13.ํ์ฌ ์ฒด์ก๋ํ ํ๋ ๋ ์ด๋ค. ์ค๋ ๋ญํ์ง?
14. ๋์ ์ ๋ฌด ์คํ์ผ์?

Kotlin์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฉ์ปค๋์ฆ
์ต์ ์ํํธ์จ์ด ๊ฐ๋ฐ ํ๊ฒฝ์์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ ์ต์ ํ์ ํต์ฌ ์์๋ก ์๋ฆฌ ์ก์์ต๋๋ค. ํนํ Kotlin์ ์ฝ๋ฃจํด(coroutine)์ ๊ธฐ๋ฐ์ผ๋ก ํ ๊ฐ๋ ฅํ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์์คํ ์ ์ ๊ณตํ๋ฉฐ, ์ด๋ ๊ธฐ์กด์ ์ฝ๋ฐฑ ์ง์ฅ(callback hell) ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ง๊ด์ ์ธ ์ฝ๋ ์์ฑ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ๋ณธ ๋ณด๊ณ ์์์๋ Kotlin์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋ฉ์ปค๋์ฆ์ ์ฌ์ธต ๋ถ์ํ๊ณ , runBlocking, Dispatchers.IO, Promise ๊ฐ๋ ์ ์ฐจ์ด์ ๊ณผ ์ค์ ์ ์ฉ ์๋๋ฆฌ์ค๋ฅผ ๊ตฌ์ฒด์ ์ธ ์ฝ๋ ์์ ์ ํจ๊ป ์ค๋ช ํฉ๋๋ค.
1. Kotlin ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ํต์ฌ ๊ฐ๋
1.1 ์ฝ๋ฃจํด์ ๊ตฌ์กฐ์ ๋์์ฑ
Kotlin ์ฝ๋ฃจํด์ ๊ฒฝ๋ ์ค๋ ๋(lightweight thread) ๊ฐ๋ ์ ๊ตฌํํ์ฌ ๊ธฐ์กด Java ์ค๋ ๋๋ณด๋ค 100๋ฐฐ ์ด์ ๊ฐ๋ฒผ์ด ์คํ ๋จ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ตฌ์กฐ์ ๋์์ฑ(structured concurrency) ์์น์ ๋ฐ๋ผ ๋ถ๋ชจ-์์ ๊ด๊ณ๋ฅผ ํ์ฑํ๋ฉฐ, ์ด๋ ๋ฆฌ์์ค ๋์ ๋ฐฉ์ง์ ์์ธ ์ ํ ๋ฉ์ปค๋์ฆ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch { // ๋ถ๋ชจ ์ฝ๋ฃจํด
launch { // ์์ ์ฝ๋ฃจํด 1
delay(1000L)
println("์ฒซ ๋ฒ์งธ ์์
์๋ฃ")
}
launch { // ์์ ์ฝ๋ฃจํด 2
delay(1500L)
println("๋ ๋ฒ์งธ ์์
์๋ฃ")
}
}
job.join() // ๋ชจ๋ ์์ ์ฝ๋ฃจํด ์๋ฃ ๋๊ธฐ
}
1.2 ์ค๋จ ํจ์(Suspend Function)์ ๋์ ์๋ฆฌ
suspend
ํค์๋๋ก ํ์๋ ํจ์๋ ์ฝ๋ฃจํด ๋ด์์๋ง ํธ์ถ ๊ฐ๋ฅํ๋ฉฐ, ์คํ ์ค๋จ๊ณผ ์ฌ๊ฐ๋ฅผ ํตํด ๋น์ฐจ๋จ(non-blocking) ๋์์ ๊ตฌํํฉ๋๋ค. ์ปดํ์ผ๋ฌ๋ CPS(Continuation-Passing Style) ๋ณํ์ ํตํด ์ค๋จ ์ง์ (suspension point)์ ์๋์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
suspend fun fetchUserData(userId: String): User {
return withContext(Dispatchers.IO) {
// ๋คํธ์ํฌ ์์ฒญ ์๋ฎฌ๋ ์ด์
delay(2000L)
User(userId, "ํ๊ธธ๋")
}
}
2. ์ฃผ์ ๋น๋๊ธฐ ๊ตฌ์ฑ ์์ ์ฌ์ธต ๋ถ์
2.1 runBlocking: ๋๊ธฐ-๋น๋๊ธฐ ๋ธ๋ฆฟ์ง
runBlocking
์ ์ฝ๋ฃจํด ์ธ๊ณ์ ์ผ๋ฐ ๋ธ๋กํน ์ฝ๋๋ฅผ ์ฐ๊ฒฐํ๋ ํน์ํ ์ฝ๋ฃจํด ๋น๋์
๋๋ค. ํ์ฌ ์ค๋ ๋๋ฅผ ์ฐจ๋จํ๋ฉฐ ๋ด๋ถ ์ฝ๋ฃจํด ์คํ์ ์๋ฃํ ๋๊น์ง ๋๊ธฐํฉ๋๋ค.
ํน์ง:
- ํ ์คํธ ํ๊ฒฝ์ด๋ ๋ฉ์ธ ํจ์์์ ์ ํ์ ์ฌ์ฉ
- Android ๋ฉ์ธ ์ค๋ ๋ ์ฌ์ฉ ์ ๋ฐ๋๋ฝ ์ํ
- ๋์คํจ์ฒ ์ง์ ์ ์ด๋ฒคํธ ๋ฃจํ ์ถฉ๋ ๊ฐ๋ฅ์ฑ
fun main() {
runBlocking {
launch {
delay(1000L)
println("runBlocking ๋ด๋ถ ์คํ")
}
}
println("runBlocking ์ข
๋ฃ ํ ์คํ") // ๋ธ๋ก ์๋ฃ ํ ์คํ
}
2.2 Dispatchers.IO vs Dispatchers.Default
Kotlin์ ์์ ์ ํ์ ์ต์ ํ๋ ๋์คํจ์ฒ๋ฅผ ์ ๊ณตํ๋ฉฐ, CPU ์ง์ฝ์ ์์ ๊ณผ I/O ์์ ์ ๋ช ํํ ๊ตฌ๋ถํฉ๋๋ค.
ํน์ฑ | Dispatchers.Default | Dispatchers.IO |
๋ชฉ์ | CPU ์ง์ฝ์ ์ฐ์ฐ(์ ๋ ฌ, ๋ณต์กํ ๊ณ์ฐ) | ํ์ผ I/O, ๋คํธ์ํฌ ์์ฒญ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ทผ |
์ค๋ ๋ ํ ํฌ๊ธฐ | CPU ์ฝ์ด ์ (์ต์ 2) | ์ต๋ 64๊ฐ |
์ฌ์ฉ ์ฌ๋ก | ์ด๋ฏธ์ง ์ฒ๋ฆฌ, ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ ์คํ | REST API ํธ์ถ, ๋ก์ปฌ DB ์ฟผ๋ฆฌ |
๋ฆฌ์์ค ๊ณต์ | ์ฝ์ด๋น ์ ์ฉ ์ค๋ ๋ | Default์ ์ค๋ ๋ ํ ๊ณต์ |
// CPU ์ง์ฝ์ ์์
์์
fun calculateFibonacci(n: Int) = runBlocking {
withContext(Dispatchers.Default) {
// ํผ๋ณด๋์น ์ ๊ณ์ฐ
}
}
// I/O ์์
์์
suspend fun loadFileContent(path: String) =
withContext(Dispatchers.IO) {
File(path).readText()
}
2.3 Deferred(Promise ํจํด ๊ตฌํ์ฒด)
Kotlin์ Deferred
๋ JavaScript์ Promise์ ์ ์ฌํ ๊ฐ๋
์ผ๋ก, ๋น๋๊ธฐ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ ์บก์ํํฉ๋๋ค. async
๋น๋๋ก ์์ฑ๋๋ฉฐ await()
์ ํตํด ๊ฒฐ๊ณผ๋ฅผ ํ๋ํฉ๋๋ค.
suspend fun fetchMultipleData() = coroutineScope {
val userDeferred = async { getUserData() }
val productDeferred = async { getProductList() }
val user = userDeferred.await() // ๊ฒฐ๊ณผ ๋๊ธฐ
val products = productDeferred.await()
combineData(user, products)
}
JavaScript Promise์์ ์ฃผ์ ์ฐจ์ด์ :
- ๋ช ์์ ์ค๋จ(resume) ๋ฉ์ปค๋์ฆ
- ๊ตฌ์กฐ์ ๋์์ฑ ์ง์
- ์ทจ์ ๋ฉ์ปค๋์ฆ ๋ด์ฅ
3. ๊ตฌ์ฑ ์์ ๊ฐ ์ํธ์์ฉ ๋ฐ ์ฑ๋ฅ ๋น๊ต
3.1 ์คํ ์ปจํ ์คํธ ๊ตํ ์ ๋ต
fun complexWorkflow() = runBlocking {
val result = withContext(Dispatchers.Default) {
// CPU ์ง์ฝ์ ์์
val processed = processData()
withContext(Dispatchers.IO) {
// ๊ฒฐ๊ณผ ์ ์ฅ
saveToDatabase(processed)
}
}
updateUI(result)
}
3.2 ์ฑ๋ฅ ๋ฒค์น๋งํฌ (๊ฐ์ ๋ฐ์ดํฐ)
์๋๋ฆฌ์ค | runBlocking | Dispatchers.IO | Dispatchers.Default |
10,000๊ฐ ํ์ผ ์ฒ๋ฆฌ | 12,450ms | 8,230ms | 15,670ms |
๋์ฉ๋ JSON ํ์ฑ | 6,780ms | 7,890ms | 3,210ms |
๋์ ๋คํธ์ํฌ ์์ฒญ 100ํ | 9,870ms | 4,560ms | 10,340ms |
4. ์ค์ ์ ์ฉ ํจํด ๋ฐ ์ต์ ํ ๊ธฐ๋ฒ
4.1 ๋ณ๋ ฌ ์ฒ๋ฆฌ ์ต์ ํ
suspend fun parallelProcessing() = coroutineScope {
val deferredList = (1..1000).map {
async(Dispatchers.Default) {
processItem(it)
}
}
deferredList.awaitAll()
}
4.2 ๋์คํจ์ฒ ํผํฉ ์ฌ์ฉ ์ฌ๋ก
fun optimizedFileProcessor() = runBlocking {
val ioDispatcher = Dispatchers.IO.limitedParallelism(32)
val cpuDispatcher = Dispatchers.Default
launch(ioDispatcher) {
val rawData = readLargeFile()
val processed = withContext(cpuDispatcher) {
parseData(rawData)
}
withContext(ioDispatcher) {
writeProcessedData(processed)
}
}
}
4.3 ์์ธ ์ฒ๋ฆฌ ์ ๋ต
suspend fun robustNetworkCall() {
try {
val response = withContext(Dispatchers.IO) {
apiClient.getData()
}
handleResponse(response)
} catch (e: IOException) {
logError("๋คํธ์ํฌ ์ค๋ฅ", e)
} catch (e: CancellationException) {
throw e // ์ฝ๋ฃจํด ์ทจ์ ์์ธ๋ ์์๋ก ์ ํ
}
}
5. ๊ตฌ์ฑ ์์ ์ ํ ๊ฐ์ด๋๋ผ์ธ
5.1 runBlocking ์ฌ์ฉ ์๋๋ฆฌ์ค
- ์ ํฉํ ๊ฒฝ์ฐ:
- JUnit ํ ์คํธ ์ผ์ด์ค
- ๋ฉ์ธ ํจ์ ์ง์ ์
- ๋ ๊ฑฐ์ ์ฝ๋ ํตํฉ
- ์ฃผ์ ์ฌํญ:
- Android ๋ฉ์ธ ์ค๋ ๋์์์ ์ฌ์ฉ ๊ธ์ง
- ์ฅ์๊ฐ ์คํ ์์ ํํผ
5.2 Dispatchers ์ ํ ๋งคํธ๋ฆญ์ค
graph TD
A[์์
์ ํ?] --> B{CPU ์ง์ฝ์ }
B --> |Yes| C[Dispatchers.Default]
B --> |No| D{์ฐจ๋จ ๊ฐ๋ฅ์ฑ}
D --> |Yes| E[Dispatchers.IO]
D --> |No| F[Dispatchers.Main/Unconfined]
5.3 Deferred ํ์ฉ ์ ๋ต
- ์ต์ ์ฌ์ฉ ์ฌ๋ก:
- ๋ค์ค ๋ ๋ฆฝ ์์ ๋ณ๋ ฌ ์ฒ๋ฆฌ
- ์ ํ ์์ ๊ฒฐ๊ณผ ์์กด์ฑ ๊ด๋ฆฌ
- ํ์์์ ์ ์ด๊ฐ ํ์ํ ์ฐ์ฐ
- ์ฑ๋ฅ ๊ฐ์ ํ:
awaitAll()
์ ํตํ ์ผ๊ด ์ฒ๋ฆฌcoroutineScope
๋ด์์์ ์ ํ์ ์ฌ์ฉ- ์ทจ์ ๋ฉ์ปค๋์ฆ ์ ๊ทน ํ์ฉ
6. ๊ณ ๊ธ ์ฃผ์ ๋ฐ ์ต์ ๋ํฅ
6.1 Kotlin Flow์์ ํตํฉ
fun observeDataStream() = runBlocking {
dataSource.getLiveUpdates()
.flowOn(Dispatchers.IO)
.map { processRawData(it) }
.flowOn(Dispatchers.Default)
.collect { updateUI(it) }
}
6.2 ๋ฉํฐํ๋ซํผ ํ๊ฒฝ ๊ณ ๋ ค์ฌํญ
- iOS์ DispatchQueue ํตํฉ
- JavaScript ๋ฐํ์๊ณผ์ ์ํธ์ด์ฉ์ฑ
- ๋ค์ดํฐ๋ธ ํ๋ซํผ๋ณ ์ค๋ ๋ฉ ์ ์ฑ
๊ฒฐ๋ก : ์ํฉ๋ณ ์ต์ ์ ์ ๊ทผ๋ฒ
Kotlin์ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋๊ตฌ๋ค์ ๊ฐ๊ธฐ ๋ช ํํ ์ฌ์ฉ ์ฌ๋ก๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. runBlocking์ ํ ์คํธ์ ํ๋กํ ํ์ดํ์ ์ ์ฉํ์ง๋ง ํ๋ก๋์ ์ฝ๋์์๋ ์ ์คํ๊ฒ ์ฌ์ฉํด์ผ ํฉ๋๋ค. Dispatchers.IO๋ ํ์ผ ์ฒ๋ฆฌ๋ ๋คํธ์ํฌ ํต์ ์ ํ์์ ์ด๋ฉฐ, Dispatchers.Default๋ ๋ณต์กํ ๊ณ์ฐ ์์ ์ ์ต์ ํ๋์ด ์์ต๋๋ค. Deferred๋ JavaScript์ Promise ํจํด์ Kotlin ์คํ์ผ๋ก ๊ตฌํํ ๊ฒ์ผ๋ก, ๋ณต์กํ ๋ณ๋ ฌ ์์ ํ๋ฆ์ ๊ด๋ฆฌํ๋ ๋ฐ ํ์ํฉ๋๋ค.
์ค์ ๊ฐ๋ฐ ์ ์์ ์ ํน์ฑ์ ์ ํํ ๋ถ์ํ๊ณ (CPU-bound vs I/O-bound), ๊ตฌ์กฐ์ ๋์์ฑ ์์น์ ์ค์ํ๋ฉฐ, Kotlin ์ฝ๋ฃจํด์ ๊ณ์ธต์ ์ทจ์ ๋ฉ์ปค๋์ฆ์ ์ ๊ทน ํ์ฉํด์ผ ํฉ๋๋ค. ํนํ Android ํ๊ฒฝ์์๋ ๋ฉ์ธ ์ค๋ ๋ ์ฐจ๋จ์ ๋ฐฉ์งํ๊ธฐ ์ํด Dispatchers.Main๊ณผ์ ์กฐํฉ์ ์ ์คํ๊ฒ ๊ณ ๋ คํด์ผ ํฉ๋๋ค. ์ต์ Kotlin ๋ฒ์ ์์๋ ํ๋ก์ฐ(Flow)์์ ํตํฉ์ด ๋์ฑ ๊ฐํ๋์ด ์์ผ๋ฉฐ, ์ ์ฐจ RxJava ํจํด์ ๋์ฒดํด ๋๊ฐ๋ ์ถ์ธ์ ๋๋ค.