Backend
home

cs_app_roadmap_v2

CS ๊ต์œก ์•ฑ ๊ฐœ๋ฐœ ๋กœ๋“œ๋งต v2
์™„์ „ ๋‚ด์žฅํ˜•(Offline-First) ยท Kotlin ์ž…๋ฌธ์ž ๊ธฐ์ค€ ยท ํด๋ผ์šฐ๋“œ ๋น„์šฉ $0
MacBook Pro 14 M2 Pro ยท Android Studio + Kotlin + Room DB
์ด ๋ฌธ์„œ์˜ ํ•ต์‹ฌ ์›์น™ 3๊ฐ€์ง€
โ‘  ์™„์ „ ์˜คํ”„๋ผ์ธ โ€” ์ธํ„ฐ๋„ทยทํด๋ผ์šฐ๋“œ ์—†์ด ์•ฑ์ด 100% ์ž‘๋™ํ•œ๋‹ค
โ‘ก ๋น„์šฉ $0 โ€” Play Store ๋“ฑ๋ก๋น„ $25 ์™ธ ์ถ”๊ฐ€ ์„œ๋ฒ„ยท๊ตฌ๋… ๋น„์šฉ ์—†์Œ
โ‘ข Kotlin ์™„์ „ ์ž…๋ฌธ์ž ๊ธฐ์ค€ โ€” ์•„๋Š” ๊ฒŒ ์—†์–ด๋„ ์ˆœ์„œ๋Œ€๋กœ ๋”ฐ๋ผ๊ฐ€๋ฉด ์•ฑ์ด ๋‚˜์˜จ๋‹ค
์ „์ฒด ๊ฐœ๋ฐœ ๋กœ๋“œ๋งต
Phase 0 0 ~ 2์ฃผ
Kotlin ๋ง›๋ณด๊ธฐ (์‚ฌ์ „ ์ค€๋น„) โ€ข ๋ณ€์ˆ˜ยทํƒ€์ž…ยท์กฐ๊ฑด๋ฌธยทํ•จ์ˆ˜ ๋”ฑ ์ด๊ฒƒ๋งŒ ๋จผ์ € โ€ข ์•ˆ๋“œ๋กœ์ด๋“œ ์—†์ด ์›น์—์„œ ๋ฐ”๋กœ ์—ฐ์Šต (play.kotlinlang.org) โ€ข Hello World ํ•˜๋‚˜ ์ถœ๋ ฅํ•ด๋ณด๊ธฐ
Phase 1 1์ฃผ
Android Studio ์„ธํŒ… โ€ข Android Studio ์„ค์น˜ ยท ์ฒซ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ โ€ข ์‹ค์ œ ์•ˆ๋“œ๋กœ์ด๋“œ ๊ธฐ๊ธฐ ์—ฐ๊ฒฐ ยท ์•ฑ ์‹คํ–‰ ํ™•์ธ โ€ข ํ”„๋กœ์ ํŠธ ํด๋” ๊ตฌ์กฐ ์ดํ•ด
Phase 2 2 ~ 3์ฃผ
Kotlin ํ•ต์‹ฌ๋งŒ ๋น ๋ฅด๊ฒŒ โ€ข ํด๋ž˜์Šค ยท ๋ฐ์ดํ„ฐ ํด๋ž˜์Šค ยท ๋„ ์•ˆ์ „์„ฑ โ€ข ์ปฌ๋ ‰์…˜(ListยทMap) ยท ๋žŒ๋‹ค โ€ข Coroutine ๊ธฐ์ดˆ (๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ)
Phase 3 3 ~ 4์ฃผ
UI ํ™”๋ฉด ๋งŒ๋“ค๊ธฐ (Compose) โ€ข ํ™ˆ ํ™”๋ฉด ยท CS ์นด๋“œ ํ™”๋ฉด ยท ํ€ด์ฆˆ ํ™”๋ฉด โ€ข ํ™”๋ฉด ์ด๋™(Navigation) ๊ตฌํ˜„ โ€ข ๋‹คํฌ๋ชจ๋“œ ยท ํฐํŠธ ยท ํ…Œ๋งˆ ์„ค์ •
Phase 4 2 ~ 3์ฃผ
์™„์ „ ์˜คํ”„๋ผ์ธ ๋ฐ์ดํ„ฐ ๊ตฌ์ถ• โ€ข CS ์ฝ˜ํ…์ธ  JSON ํŒŒ์ผ๋กœ ์ž‘์„ฑ (assets ํด๋”) โ€ข Room DB ์„ค๊ณ„ ยท ์ฒซ ์‹คํ–‰ ์‹œ DB ์ด์‹ โ€ข ํ•™์Šต ์ง„๋„ ยท ์ฆ๊ฒจ์ฐพ๊ธฐ ยท ํ€ด์ฆˆ ๊ธฐ๋ก ์ €์žฅ
Phase 5 2์ฃผ
์ˆ˜์ตํ™” & ์ถœ์‹œ โ€ข Freemium ์ž ๊ธˆ ๋กœ์ง ๊ตฌํ˜„ (ํด๋ผ์šฐ๋“œ ์—†์ด) โ€ข Google Play Console ๋“ฑ๋ก ยท ๋ฒ ํƒ€ ์ถœ์‹œ โ€ข ์ •์‹ ์ถœ์‹œ & ์ฝ˜ํ…์ธ  ์—…๋ฐ์ดํŠธ ์šด์˜ ๋ฐฉ์‹
์™„์ „ ๋‚ด์žฅํ˜• ๊ตฌ์กฐ๋ž€?
Firebaseยท์„œ๋ฒ„ ์—†์ด ์•ฑ ํ•˜๋‚˜๋งŒ์œผ๋กœ ๋ชจ๋“  ๊ฒŒ ๋™์ž‘ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.
CS ๋ฐ์ดํ„ฐ๋Š” ์•ฑ ์„ค์น˜ ํŒŒ์ผ ์•ˆ์— ์ฒ˜์Œ๋ถ€ํ„ฐ ํฌํ•จ๋˜์–ด ์žˆ๊ณ , ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋Š” ๊ธฐ๊ธฐ ๋‚ด๋ถ€ DB์—๋งŒ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
๋ฐ์ดํ„ฐ ํ๋ฆ„ ํ•œ๋ˆˆ์— ๋ณด๊ธฐ
์•ฑ ์„ค์น˜ ์‹œ (๋”ฑ ํ•œ ๋ฒˆ)
โ‘  APK ์•ˆ์˜ assets/cs_data.json ํŒŒ์ผ ์ฝ๊ธฐ
โ‘ก Room DB(๊ธฐ๊ธฐ ๋‚ด๋ถ€ ์ €์žฅ์†Œ)์— CS ๊ฐœ๋… ์ „์ฒด ์ด์‹
โ‘ข ์ดํ›„ ์ธํ„ฐ๋„ท ์—ฐ๊ฒฐ ์—†์ด๋„ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์ ‘๊ทผ ๊ฐ€๋Šฅ
์•ฑ ์‚ฌ์šฉ ์ค‘ (๋งค๋ฒˆ)
โ€ข
CS ๊ฐœ๋… ์นด๋“œ ์ฝ๊ธฐ โ†’ Room DB์—์„œ ์ฆ‰์‹œ ์กฐํšŒ
โ€ข
ํ€ด์ฆˆ ํ’€๊ธฐ โ†’ ๊ฒฐ๊ณผ Room DB์— ์ €์žฅ
โ€ข
์ฆ๊ฒจ์ฐพ๊ธฐ ์ถ”๊ฐ€ โ†’ Room DB์— ์ €์žฅ
โ€ข
ํ•™์Šต ์ง„๋„ โ†’ Room DB์— ์ €์žฅ
โ†’ ์ธํ„ฐ๋„ท 0% ํ•„์š”
์ฝ˜ํ…์ธ  ์—…๋ฐ์ดํŠธ ์‹œ
โ€ข
cs_data.json ํŒŒ์ผ์— ์ƒˆ ๊ฐœ๋… ์ถ”๊ฐ€
โ€ข
Play Store์— ์ƒˆ ๋ฒ„์ „ ์•ฑ ๋ฐฐํฌ
โ€ข
์‚ฌ์šฉ์ž๊ฐ€ ์—…๋ฐ์ดํŠธํ•˜๋ฉด ์ž๋™์œผ๋กœ ์ƒˆ ๋ฐ์ดํ„ฐ ์ ์šฉ
โ†’ ์„œ๋ฒ„ ์—†์ด ์•ฑ ์—…๋ฐ์ดํŠธ = ์ฝ˜ํ…์ธ  ์—…๋ฐ์ดํŠธ
Firebase vs ์™„์ „ ๋‚ด์žฅํ˜• ๋น„๊ต
๊ธฐ๋Šฅ
Firebase ๋ฐฉ์‹
์™„์ „ ๋‚ด์žฅํ˜• (์šฐ๋ฆฌ ๋ฐฉ์‹)
CS ๋ฐ์ดํ„ฐ ์ €์žฅ
Firestore (ํด๋ผ์šฐ๋“œ)
assets/JSON โ†’ Room DB (๊ธฐ๊ธฐ ๋‚ด)
์‚ฌ์šฉ์ž ์ง„๋„ ์ €์žฅ
Firestore (ํด๋ผ์šฐ๋“œ)
Room DB (๊ธฐ๊ธฐ ๋‚ด)
์ฝ˜ํ…์ธ  ์—…๋ฐ์ดํŠธ
์‹ค์‹œ๊ฐ„ ๋ฐ˜์˜
์•ฑ ์—…๋ฐ์ดํŠธ๋กœ ๋ฐ˜์˜
์ธํ„ฐ๋„ท ํ•„์š” ์—ฌ๋ถ€
ํ•ญ์ƒ ํ•„์š”
์„ค์น˜ ํ›„ ๋ถˆํ•„์š”
์›” ๋น„์šฉ
$0~์ˆ˜์‹ญ ๋‹ฌ๋Ÿฌ
$0 (์˜๊ตฌ ๋ฌด๋ฃŒ)
๋กœ๊ทธ์ธ ํ•„์š”
ํ•„์š” (Firebase Auth)
๋ถˆํ•„์š”
๋ณต์žก๋„
๋†’์Œ (SDK ์„ค์ • ๋ณต์žก)
๋‚ฎ์Œ (Room๋งŒ ๋ฐฐ์šฐ๋ฉด ๋จ)
Phase 0 ยท Kotlin ๋ง›๋ณด๊ธฐ (์ž…๋ฌธ์ž ์ „์šฉ)
Kotlin์„ ์ „ํ˜€ ๋ชจ๋ฅธ๋‹ค๋ฉด ์—ฌ๊ธฐ์„œ ์‹œ์ž‘ํ•˜์„ธ์š”. Android Studio ์„ค์น˜ ์ „์— ์›น์—์„œ ๋ฐ”๋กœ ์—ฐ์Šตํ•ฉ๋‹ˆ๋‹ค.
์ง€๊ธˆ ๋‹น์žฅ ์‹œ์ž‘ํ•˜๋Š” ๋ฒ• (์„ค์น˜ ์—†์Œ)
1. ๋ธŒ๋ผ์šฐ์ €์—์„œ play.kotlinlang.org ์ ‘์†
2. ์™ผ์ชฝ ์˜ˆ์ œ ์ฝ”๋“œ ์ง€์šฐ๊ณ  ์ง์ ‘ ํƒ€์ดํ•‘
3. Run ๋ฒ„ํŠผ ํด๋ฆญ โ†’ ๊ฒฐ๊ณผ ํ™•์ธ
โ†’ ์ด๊ฒƒ๋งŒ์œผ๋กœ Kotlin ๊ธฐ์ดˆ ์™„์ „ํžˆ ์ตํž ์ˆ˜ ์žˆ์Œ
Phase 0 ํ•™์Šต ์ˆœ์„œ (๋”ฑ ์ด๊ฒƒ๋งŒ)
STEP 1 ยท ๋ณ€์ˆ˜ (val / var)
val = ํ•œ๋ฒˆ ์ •ํ•˜๋ฉด ๋ชป ๋ฐ”๊ฟˆ / var = ๋‚˜์ค‘์— ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Œ
โ†’ CS ๊ฐœ๋… ์ œ๋ชฉ์ฒ˜๋Ÿผ ๋ฐ”๋€Œ์ง€ ์•Š๋Š” ๊ฑด val, ํ•™์Šต ์ ์ˆ˜์ฒ˜๋Ÿผ ๋ฐ”๋€Œ๋Š” ๊ฑด var
STEP 2 ยท ์กฐ๊ฑด๋ฌธ (if / when)
โ†’ when์€ Java์˜ switch์™€ ๊ฐ™์€๋ฐ, Kotlin์—์„œ ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์”๋‹ˆ๋‹ค
โ†’ ํ€ด์ฆˆ ์ •๋‹ต ํŒ๋‹จ, ์นดํ…Œ๊ณ ๋ฆฌ ๋ถ„๋ฅ˜ ๋“ฑ์— ๋ฐ”๋กœ ์“ฐ์ž„
STEP 3 ยท ๋ฐ˜๋ณต๋ฌธ (for / forEach)
โ†’ CS ๊ฐœ๋… ๋ชฉ๋ก ์ „์ฒด๋ฅผ ํ™”๋ฉด์— ๋ฟŒ๋ฆด ๋•Œ ์‚ฌ์šฉ
STEP 4 ยท ํ•จ์ˆ˜ (fun)
โ†’ ๋ฐ˜๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ฌถ์–ด์„œ ์ด๋ฆ„ ๋ถ™์ด๊ธฐ
โ†’ ์•ฑ์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ์ด ํ•จ์ˆ˜ ๋‹จ์œ„๋กœ ๊ตฌ์„ฑ๋จ
STEP 5 ยท ๋„ ์•ˆ์ „์„ฑ (? ์™€ ?:)
โ†’ Kotlin์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฐœ๋… ์ค‘ ํ•˜๋‚˜
โ†’ ์•ฑ์ด ๊ฐ‘์ž๊ธฐ ๊บผ์ง€๋Š” ์˜ค๋ฅ˜(NullPointerException)๋ฅผ ์–ธ์–ด ์ฐจ์›์—์„œ ๋ง‰์•„์คŒ
Phase 0 ๋ชฉํ‘œ ์‹œ๊ฐ„
โ€ข
STEP 1~3 : ํ•˜๋ฃจ 30๋ถ„์”ฉ 3์ผ โ†’ ์™„๋ฃŒ
โ€ข
STEP 4~5 : ํ•˜๋ฃจ 30๋ถ„์”ฉ 3์ผ โ†’ ์™„๋ฃŒ
โ€ข
Kotlin Koans (play.kotlinlang.org) 1~20๋ฒˆ ํ’€๊ธฐ โ†’ 1์ฃผ ์™„์„ฑ
โ†’ ์ด ์ •๋„๋ฉด Android Studio์—์„œ ์ฝ”๋“œ ์ฝ๊ณ  ์ดํ•ดํ•˜๋Š” ๋ฐ ์ถฉ๋ถ„
Phase 1 ยท Android Studio ์„ธํŒ…
์„ค์น˜ ์ ˆ์ฐจ (M2 Mac ๊ธฐ์ค€)
1.
developer.android.com/studio ์ ‘์†
2.
Mac with Apple chip (.dmg) ๋‹ค์šด๋กœ๋“œ โ€” ๋ฐ˜๋“œ์‹œ Apple Silicon ๋ฒ„์ „ ์„ ํƒ
3.
.dmg ์—ด๊ธฐ โ†’ Android Studio๋ฅผ Applications ํด๋”๋กœ ๋“œ๋ž˜๊ทธ
4.
์ฒซ ์‹คํ–‰ โ†’ Setup Wizard โ†’ Standard ์„ค์น˜ โ†’ SDK ์ž๋™ ๋‹ค์šด๋กœ๋“œ (์•ฝ 10~20๋ถ„)
5.
์„ค์น˜ ์™„๋ฃŒ ํ›„ New Project โ†’ Empty Activity ์„ ํƒ
์ฒซ ํ”„๋กœ์ ํŠธ ์„ค์ •๊ฐ’
ํ•ญ๋ชฉ
์ž…๋ ฅ๊ฐ’
์ด์œ 
Name
CSStudyApp
ํ”„๋กœ์ ํŠธ ์ด๋ฆ„
Package name
com.yourname.csstudyapp
์•ฑ ๊ณ ์œ  ์‹๋ณ„์ž
Language
Kotlin
ํ•„์ˆ˜
Minimum SDK
API 26 (Android 8.0)
๊ตญ๋‚ด ๊ธฐ๊ธฐ 95% ์ด์ƒ ์ปค๋ฒ„
Build configuration
Kotlin DSL
์ตœ์‹  ํ‘œ์ค€ ๋ฐฉ์‹
์‹ค์ œ ๊ธฐ๊ธฐ ์—ฐ๊ฒฐ ์ถ”์ฒœ (์—๋ฎฌ๋ ˆ์ดํ„ฐ๋ณด๋‹ค ๋น ๋ฆ„)
1. ์•ˆ๋“œ๋กœ์ด๋“œ ํฐ โ†’ ์„ค์ • โ†’ ํœด๋Œ€ํฐ ์ •๋ณด โ†’ ๋นŒ๋“œ ๋ฒˆํ˜ธ 7๋ฒˆ ํƒญ
2. ๊ฐœ๋ฐœ์ž ์˜ต์…˜ ํ™œ์„ฑํ™” โ†’ USB ๋””๋ฒ„๊น… ON
3. USB๋กœ Mac์— ์—ฐ๊ฒฐ โ†’ Android Studio ์ƒ๋‹จ์— ๊ธฐ๊ธฐ ์ด๋ฆ„ ํ‘œ์‹œ
4. Run ๋ฒ„ํŠผ โ†’ ํฐ์— ์•ฑ ์„ค์น˜ ยท ์‹คํ–‰ ํ™•์ธ
Phase 2 ยท Kotlin ํ•ต์‹ฌ๋งŒ ๋น ๋ฅด๊ฒŒ
์ž…๋ฌธ์ž ๊ธฐ์ค€์œผ๋กœ ์•ฑ ๊ฐœ๋ฐœ์— ๊ผญ ํ•„์š”ํ•œ ๊ฒƒ๋งŒ ๊ณจ๋ž์Šต๋‹ˆ๋‹ค. ์ „๋ถ€ ๋‹ค ์•Œ ํ•„์š” ์—†์–ด์š”.
๊ผญ ์•Œ์•„์•ผ ํ•˜๋Š” ๊ฒƒ vs ๋‚˜์ค‘์— ๋ด๋„ ๋˜๋Š” ๊ฒƒ
์ฃผ์ œ
์ค‘์š”๋„
์ด์œ 
val / var ยท ๊ธฐ๋ณธ ํƒ€์ž…
ํ•„์ˆ˜
๋ชจ๋“  ์ฝ”๋“œ์˜ ๊ธฐ๋ณธ
if ยท when ยท for
ํ•„์ˆ˜
๋กœ์ง ํ๋ฆ„ ์ œ์–ด
fun (ํ•จ์ˆ˜)
ํ•„์ˆ˜
๊ธฐ๋Šฅ ๋‹จ์œ„ ๊ตฌ์„ฑ
data class
ํ•„์ˆ˜
CS ๊ฐœ๋… ๋ฐ์ดํ„ฐ ๋ชจ๋ธ
List ยท Map ยท filter
ํ•„์ˆ˜
๋ฐ์ดํ„ฐ ๋‹ค๋ฃจ๊ธฐ
๋„ ์•ˆ์ „์„ฑ (? ยท ?:)
ํ•„์ˆ˜
์•ฑ ์•ˆ์ •์„ฑ
Coroutine (launch ยท suspend)
์ค‘์š”
DB ์ €์žฅ ์‹œ ํ•„์š”
sealed class ยท enum
์ค‘์š”
์ƒํƒœ ๊ด€๋ฆฌ
generics ยท ๊ณ ๊ธ‰ ํƒ€์ž…
๋‚˜์ค‘์—
์ฒ˜์Œ์—” ๋ชฐ๋ผ๋„ ๋จ
Java ์ƒํ˜ธ์šด์šฉ
๋‚˜์ค‘์—
์ง€๊ธˆ ๋‹น์žฅ ๋ถˆํ•„์š”
์ฃผ์ฐจ๋ณ„ ํ•™์Šต ๊ณ„ํš
1์ฃผ์ฐจ โ€” ์–ธ์–ด ๊ธฐ์ดˆ (Phase 0 ๋ณต์Šต + ์‹ฌํ™”)
โ€ข
val ยท var ์™„๋ฒฝ ์ดํ•ด, String ํ…œํ”Œ๋ฆฟ ($๋ณ€์ˆ˜๋ช…) ํ™œ์šฉ
โ€ข
when ํ‘œํ˜„์‹์œผ๋กœ ํ€ด์ฆˆ ์ •๋‹ต ํŒ๋‹จ ๋กœ์ง ์ง์ ‘ ์งœ๋ณด๊ธฐ
โ€ข
for๋ฌธ์œผ๋กœ CS ๊ฐœ๋… ๋ฆฌ์ŠคํŠธ ์ถœ๋ ฅํ•ด๋ณด๊ธฐ
2์ฃผ์ฐจ โ€” ๋ฐ์ดํ„ฐ ๋ชจ๋ธ ์„ค๊ณ„
โ€ข
data class๋กœ CS ๊ฐœ๋… ๋ชจ๋ธ ์ง์ ‘ ๋งŒ๋“ค๊ธฐ
โ—ฆ
์˜ˆ์‹œ: data class CsConcept(val id: Int, val title: String, val description: String, val category: String)
โ€ข
List<CsConcept>๋กœ ๋ฐ์ดํ„ฐ ๋ฌถ๊ธฐ ยท filter๋กœ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๊ฒ€์ƒ‰
โ€ข
nullable(?) ์ฒ˜๋ฆฌํ•ด์„œ ์•ˆ์ „ํ•œ ์ฝ”๋“œ ์ž‘์„ฑ ์—ฐ์Šต
3์ฃผ์ฐจ โ€” Coroutine ๊ธฐ์ดˆ (Room DB ์‚ฌ์šฉ ์ „ ํ•„์ˆ˜)
โ€ข
์™œ ํ•„์š”ํ•œ๊ฐ€: DB ์ฝ๊ธฐ/์“ฐ๊ธฐ๋Š” ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋ฏ€๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•จ
โ€ข
launch { } ๋ธ”๋ก ์•ˆ์—์„œ DB ์ž‘์—…ํ•˜๋Š” ํŒจํ„ด ์ดํ•ด
โ€ข
suspend fun ์ด ๋ถ™์€ ํ•จ์ˆ˜๋Š” ๊ธฐ๋‹ค๋ ค์ค˜์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ๋งŒ ์•Œ๋ฉด ์ถฉ๋ถ„
Kotlin ์ž…๋ฌธ์ž๋ฅผ ์œ„ํ•œ ํ•™์Šต ํŒ
โ€ข
๋ฌธ๋ฒ• ์•”๊ธฐ๋ณด๋‹ค '์ง์ ‘ ์ณ๋ณด๊ธฐ'๊ฐ€ 10๋ฐฐ ํšจ์œจ์  โ€” play.kotlinlang.org์—์„œ ๋ฐ”๋กœ ์‹คํ—˜
โ€ข
์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฌด์„œ์›Œํ•˜์ง€ ๋งˆ์„ธ์š” โ€” ์˜ค๋ฅ˜๊ฐ€ ๋‚˜์•ผ ๋ฐฐ์›๋‹ˆ๋‹ค
โ€ข
๊ตฌ๊ธ€ ๊ฒ€์ƒ‰ํ•  ๋•Œ 'Kotlin [๋ชจ๋ฅด๋Š” ๊ฒƒ] example'๋กœ ๊ฒ€์ƒ‰ํ•˜๋ฉด ์˜ˆ์ œ ์ฝ”๋“œ ๋ฐ”๋กœ ๋‚˜์˜ด
โ€ข
ChatGPT/Claude์—๊ฒŒ '์ด ์ฝ”๋“œ ํ•œ๊ตญ์–ด๋กœ ์„ค๋ช…ํ•ด์ค˜'๋ผ๊ณ  ๋ฌผ์–ด๋ณด๋Š” ๊ฒƒ๋„ ๋งค์šฐ ํšจ๊ณผ์ 
Phase 3 ยท UI ํ™”๋ฉด ๋งŒ๋“ค๊ธฐ (Jetpack Compose)
Compose๋Š” XML ์—†์ด Kotlin ์ฝ”๋“œ๋งŒ์œผ๋กœ ํ™”๋ฉด์„ ๋งŒ๋“œ๋Š” ์ตœ์‹  ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ž…๋ฌธ์ž์—๊ฒŒ ๋” ์ง๊ด€์ ์ด์—์š”.
๋งŒ๋“ค์–ด์•ผ ํ•  ํ™”๋ฉด ๋ชฉ๋ก (์šฐ์„ ์ˆœ์œ„์ˆœ)
ํ™”๋ฉด
์ฃผ์š” ๊ธฐ๋Šฅ
๋‚œ์ด๋„
์šฐ์„ ์ˆœ์œ„
ํ™ˆ ํ™”๋ฉด
์นดํ…Œ๊ณ ๋ฆฌ ๋ชฉ๋ก ยท ํ•™์Šต ์ง„๋„ ์š”์•ฝ
1์ˆœ์œ„
CS ์นด๋“œ ํ•™์Šต
๊ฐœ๋… ์นด๋“œ ๋„˜๊ธฐ๊ธฐ ยท ์•ž/๋’ท๋ฉด ๋’ค์ง‘๊ธฐ
1์ˆœ์œ„
ํ€ด์ฆˆ ํ™”๋ฉด
๊ฐ๊ด€์‹ 4์ง€์„ ๋‹ค ยท ๊ฒฐ๊ณผ ํ‘œ์‹œ
2์ˆœ์œ„
์ฆ๊ฒจ์ฐพ๊ธฐ
๋ถ๋งˆํฌ ๋ชฉ๋ก ๋ชจ์•„๋ณด๊ธฐ
2์ˆœ์œ„
๊ฒ€์ƒ‰
ํ‚ค์›Œ๋“œ ๊ฒ€์ƒ‰ ยท ์‹ค์‹œ๊ฐ„ ํ•„ํ„ฐ
3์ˆœ์œ„
์„ค์ •
๋‹คํฌ๋ชจ๋“œ ยท ์•Œ๋ฆผ ์„ค์ •
3์ˆœ์œ„
ํด๋” ๊ตฌ์กฐ (์ฒ˜์Œ๋ถ€ํ„ฐ ์ด๋Œ€๋กœ ๋งŒ๋“œ์„ธ์š”)
CSStudyApp ํ”„๋กœ์ ํŠธ ํด๋” ๊ตฌ์กฐ
app/src/main/
โ”œโ”€โ”€ assets/
โ”‚ โ””โ”€โ”€ cs_data.json โ† CS ๊ฐœ๋… ๋ฐ์ดํ„ฐ ํŒŒ์ผ (ํ•ต์‹ฌ!)
โ””โ”€โ”€ java/com.yourname.csstudyapp/
โ”œโ”€โ”€ data/
โ”‚ โ”œโ”€โ”€ CsConceptEntity.kt โ† Room DB ํ…Œ์ด๋ธ” ์ •์˜
โ”‚ โ”œโ”€โ”€ CsConceptDao.kt โ† DB ์กฐํšŒยท์ €์žฅ ์ฟผ๋ฆฌ
โ”‚ โ”œโ”€โ”€ CsDatabase.kt โ† DB ์ธ์Šคํ„ด์Šค
โ”‚ โ””โ”€โ”€ CsRepository.kt โ† UI ๏ธŽ DB ์ค‘๊ฐ„ ๊ด€๋ฆฌ
โ”œโ”€โ”€ ui/
โ”‚ โ”œโ”€โ”€ home/HomeScreen.kt
โ”‚ โ”œโ”€โ”€ card/CardScreen.kt
โ”‚ โ”œโ”€โ”€ quiz/QuizScreen.kt
โ”‚ โ””โ”€โ”€ theme/Theme.kt
โ”œโ”€โ”€ viewmodel/
โ”‚ โ””โ”€โ”€ CsViewModel.kt โ† ํ™”๋ฉด ์ƒํƒœ ๊ด€๋ฆฌ
โ””โ”€โ”€ MainActivity.kt
Phase 4 ยท ์™„์ „ ์˜คํ”„๋ผ์ธ ๋ฐ์ดํ„ฐ ๊ตฌ์ถ•
์ด ํŒŒํŠธ๊ฐ€ ์ด ์•ฑ์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ์ธํ„ฐ๋„ท ์—†์ด CS ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๊ธฐ์— ๋‚ด์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋‹จ๊ณ„๋ณ„๋กœ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.
STEP 1 ยท CS ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ ์ž‘์„ฑ
assets/cs_data.json ํŒŒ์ผ์— ๋ชจ๋“  CS ๊ฐœ๋…์„ ์•„๋ž˜ ํ˜•์‹์œผ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
cs_data.json ๊ตฌ์กฐ ์˜ˆ์‹œ
[
{
"id": 1,
"title": "์Šคํƒ (Stack)",
"description": "LIFO(Last In First Out) ๊ตฌ์กฐ. ๋งˆ์ง€๋ง‰์— ๋“ค์–ด์˜จ ๋ฐ์ดํ„ฐ๊ฐ€ ๋จผ์ € ๋‚˜๊ฐ„๋‹ค.",
"category": "์ž๋ฃŒ๊ตฌ์กฐ",
"difficulty": "๊ธฐ์ดˆ",
"keywords": ["์Šคํƒ", "LIFO", "push", "pop"]
},
...
]
STEP 2 ยท Room DB ํ…Œ์ด๋ธ” ์„ค๊ณ„
ํ…Œ์ด๋ธ”
์ฃผ์š” ์ปฌ๋Ÿผ
์—ญํ• 
cs_concepts
id ยท title ยท description ยท category ยท difficulty
CS ๊ฐœ๋… ์›๋ฌธ ์ €์žฅ
user_progress
concept_id ยท is_learned ยท last_studied_at
ํ•™์Šต ์ง„๋„ ์ถ”์ 
bookmarks
concept_id ยท created_at
์ฆ๊ฒจ์ฐพ๊ธฐ
quiz_history
concept_id ยท is_correct ยท answered_at
ํ€ด์ฆˆ ๊ธฐ๋ก
STEP 3 ยท ์•ฑ ์ฒซ ์‹คํ–‰ ์‹œ DB ์ด์‹ ๋กœ์ง
์•ฑ์„ ์ฒ˜์Œ ์„ค์น˜ํ•˜๋ฉด ์ž๋™์œผ๋กœ JSON โ†’ Room DB ๋ณ€ํ™˜์ด ํ•œ ๋ฒˆ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
์ฒซ ์‹คํ–‰ ๋กœ์ง ํ๋ฆ„
์•ฑ ์‹คํ–‰
โ†“
Room DB๊ฐ€ ๋น„์–ด์žˆ๋Š”๊ฐ€? (์ฒซ ์„ค์น˜ ์—ฌ๋ถ€ ํ™•์ธ)
โ†“ YES
assets/cs_data.json ํŒŒ์ผ ์ฝ๊ธฐ
โ†“
JSON โ†’ CsConceptEntity ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜
โ†“
Room DB์— ์ „์ฒด ์‚ฝ์ž… (insert)
โ†“
์ดํ›„ ๋ชจ๋“  ๋ฐ์ดํ„ฐ ์ ‘๊ทผ์€ Room DB์—์„œ๋งŒ โ†’ ์˜คํ”„๋ผ์ธ ์™„์„ฑ
STEP 4 ยท ์ฝ˜ํ…์ธ  ์—…๋ฐ์ดํŠธ ์šด์˜ ๋ฐฉ์‹
์ƒํ™ฉ
์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•
์‚ฌ์šฉ์ž ๊ฒฝํ—˜
์ƒˆ CS ๊ฐœ๋… ์ถ”๊ฐ€
cs_data.json์— ์ถ”๊ฐ€ โ†’ ์•ฑ ์ƒˆ ๋ฒ„์ „ ๋ฐฐํฌ
Play Store ์—…๋ฐ์ดํŠธ ์•Œ๋ฆผ
์˜คํƒ€/์˜ค๋ฅ˜ ์ˆ˜์ •
JSON ์ˆ˜์ • โ†’ ์•ฑ ์ƒˆ ๋ฒ„์ „ ๋ฐฐํฌ
์—…๋ฐ์ดํŠธ ํ›„ ์ž๋™ ๋ฐ˜์˜
์นดํ…Œ๊ณ ๋ฆฌ ์ถ”๊ฐ€
JSON์— ์ƒˆ ์นดํ…Œ๊ณ ๋ฆฌ ํ•ญ๋ชฉ ์ถ”๊ฐ€
์—…๋ฐ์ดํŠธ ํ›„ ์ฆ‰์‹œ ๋…ธ์ถœ
์‚ฌ์šฉ์ž ์ง„๋„ ์ดˆ๊ธฐํ™”
์„ค์ • ํ™”๋ฉด์—์„œ ์ง์ ‘ ์ดˆ๊ธฐํ™” ๊ธฐ๋Šฅ ์ œ๊ณต
๋ฐ์ดํ„ฐ ์œ ์‹ค ์—†์ด ์„ ํƒ์  ์ดˆ๊ธฐํ™”
Phase 5 ยท ์ˆ˜์ตํ™” & ์ถœ์‹œ
Freemium ๊ตฌ์กฐ (ํด๋ผ์šฐ๋“œ ์—†์ด ๊ตฌํ˜„)
์„œ๋ฒ„ ์—†์ด๋„ Freemium์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ๋… ์—ฌ๋ถ€๋ฅผ ๊ธฐ๊ธฐ ๋‚ด๋ถ€์— ์ €์žฅํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
์œ ์ € ์œ ํ˜•
์ ‘๊ทผ ๊ฐ€๋Šฅ ์ฝ˜ํ…์ธ 
์ˆ˜์ต
๋ฌด๋ฃŒ ์œ ์ €
์ž๋ฃŒ๊ตฌ์กฐ + ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์นดํ…Œ๊ณ ๋ฆฌ (์ „์ฒด์˜ 40%)
๊ด‘๊ณ  ๋…ธ์ถœ (AdMob)
ํ”„๋ฆฌ๋ฏธ์—„ ์œ ์ €
์ „ ์นดํ…Œ๊ณ ๋ฆฌ + ๊ด‘๊ณ  ์ œ๊ฑฐ + ์˜คํ”„๋ผ์ธ ์ €์žฅ
์›” ๊ตฌ๋… ๊ฒฐ์ œ
์ถ”์ฒœ ๊ตฌ๋… ๊ฐ€๊ฒฉ (๊ตญ๋‚ด ๊ธฐ์ค€)
โ€ข
์›”๊ฐ„ ๊ตฌ๋…: 2,900์›/์›”
โ€ข
์—ฐ๊ฐ„ ๊ตฌ๋…: 19,900์›/๋…„ (์•ฝ 43% ํ• ์ธ)
โ€ข
์ฒซ ๋‹ฌ ๋ฌด๋ฃŒ ์ฒดํ—˜ โ†’ ์œ ๋ฃŒ ์ „ํ™˜ ์œ ๋„
โ†’ Google Play Billing์œผ๋กœ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ (Kotlin ์ฝ”๋“œ ๋ช‡ ์ค„๋กœ ์—ฐ๋™ ๊ฐ€๋Šฅ)
Play Store ์ถœ์‹œ 7๋‹จ๊ณ„
1.
play.google.com/console ์ ‘์† โ†’ ๊ฐœ๋ฐœ์ž ๋“ฑ๋ก ($25 ์ผํšŒ์„ฑ)
2.
์•ฑ ์„œ๋ช… ํ‚ค์Šคํ† ์–ด ์ƒ์„ฑ (Android Studio์—์„œ Generate Signed Bundle)
3.
๋‚ด๋ถ€ ํ…Œ์ŠคํŠธ ๋ฒ„์ „ ์—…๋กœ๋“œ โ†’ ๋ณธ์ธ ๊ธฐ๊ธฐ์—์„œ ์ตœ์ข… ํ™•์ธ
4.
์Šคํ† ์–ด ๋ฆฌ์ŠคํŒ… ์ž‘์„ฑ: ์•ฑ ์ด๋ฆ„ ยท ์„ค๋ช…(ํ•œ๊ตญ์–ด) ยท ์Šคํฌ๋ฆฐ์ƒท 5์žฅ ยท ์•„์ด์ฝ˜
5.
๊ฐœ์ธ์ •๋ณด์ฒ˜๋ฆฌ๋ฐฉ์นจ URL ๋“ฑ๋ก (GitHub Pages ๋ฌด๋ฃŒ ํ™œ์šฉ)
6.
์ฝ˜ํ…์ธ  ๋“ฑ๊ธ‰ ์„ค๋ฌธ ์™„๋ฃŒ
7.
์ •์‹ ์ถœ์‹œ ์ œ์ถœ โ†’ ๊ฒ€ํ†  1~3์ผ โ†’ ์Šคํ† ์–ด ๊ณต๊ฐœ
์ฃผ์ฐจ๋ณ„ ์‹คํ–‰ ์ฒดํฌ๋ฆฌ์ŠคํŠธ
์ฃผ์ฐจ
์ด๋ฒˆ ์ฃผ ๋ชฉํ‘œ
์™„๋ฃŒ
0์ฃผ์ฐจ (์ง€๊ธˆ)
play.kotlinlang.org ์ ‘์† ยท Kotlin Koans 1~10๋ฒˆ ํ’€๊ธฐ
โ˜
1์ฃผ์ฐจ
Android Studio ์„ค์น˜ ยท Hello World ์‹คํ–‰ ยท ๊ธฐ๊ธฐ ์—ฐ๊ฒฐ
โ˜
2์ฃผ์ฐจ
Kotlin ๋ณ€์ˆ˜ยท์กฐ๊ฑด๋ฌธยทํ•จ์ˆ˜ยท๋„ ์•ˆ์ „์„ฑ ํ•™์Šต
โ˜
3์ฃผ์ฐจ
data class ยท List ยท filter ยท ๊ฐ„๋‹จํ•œ ๋ฐ์ดํ„ฐ ๋ชจ๋ธ ์ง์ ‘ ์„ค๊ณ„
โ˜
4์ฃผ์ฐจ
Coroutine ๊ธฐ์ดˆ ยท ViewModel ๊ฐœ๋… ์ดํ•ด
โ˜
5์ฃผ์ฐจ
Compose ๊ธฐ์ดˆ ยท ํ™ˆ ํ™”๋ฉด ๋ ˆ์ด์•„์›ƒ ํ”„๋กœํ† ํƒ€์ž… ์ œ์ž‘
โ˜
6์ฃผ์ฐจ
CS ์นด๋“œ ํ•™์Šต ํ™”๋ฉด ๊ตฌํ˜„ ยท Navigation ์—ฐ๊ฒฐ
โ˜
7์ฃผ์ฐจ
cs_data.json ์ž‘์„ฑ ยท Room DB ์„ค๊ณ„ ยท ์ฒซ ์‹คํ–‰ ์ด์‹ ๋กœ์ง
โ˜
8์ฃผ์ฐจ
ํ€ด์ฆˆ ํ™”๋ฉด ยท ์ฆ๊ฒจ์ฐพ๊ธฐ ยท ํ•™์Šต ์ง„๋„ ์ €์žฅ ๊ธฐ๋Šฅ
โ˜
9์ฃผ์ฐจ
Freemium ์ž ๊ธˆ ๋กœ์ง ยท Google Play Billing ์—ฐ๋™
โ˜
10์ฃผ์ฐจ
UI ๋‹ค๋“ฌ๊ธฐ ยท ๋ฒ„๊ทธ ์ˆ˜์ • ยท ๋ฒ ํƒ€ ์ถœ์‹œ
โ˜
11์ฃผ์ฐจ
ํ”ผ๋“œ๋ฐฑ ๋ฐ˜์˜ ยท ์Šคํ† ์–ด ๋ฆฌ์ŠคํŒ… ์ž‘์„ฑ ยท ์ •์‹ ์ถœ์‹œ
โ˜
์ง€๊ธˆ ๋‹น์žฅ ์‹œ์ž‘ํ•˜๊ธฐ (์˜ค๋Š˜ ํ•  ์ผ)
โ‘  play.kotlinlang.org ์ ‘์† โ†’ ์™ผ์ชฝ ์˜ˆ์ œ ์ง€์šฐ๊ณ  val name = '๋‚ด ์ด๋ฆ„' ํƒ€์ดํ•‘ํ•ด๋ณด๊ธฐ
โ‘ก developer.android.com/studio ๋ถ๋งˆํฌ ํ•ด๋‘๊ธฐ
โ‘ข ๊ณต๋ถ€ํ•˜๊ณ  ์‹ถ์€ CS ์นดํ…Œ๊ณ ๋ฆฌ 5๊ฐœ ์ ์–ด๋ณด๊ธฐ (์ž๋ฃŒ๊ตฌ์กฐ? OS? ๋„คํŠธ์›Œํฌ?)
โ‘ฃ ์ด ๋ฌธ์„œ 1์ฃผ์ฐจ ์ฒดํฌ๋ฐ•์Šค ์™„๋ฃŒ ๋ชฉํ‘œ์ผ ์ ๊ธฐ
Kotlin ๋ชฐ๋ผ๋„ ๊ดœ์ฐฎ์•„์š”. ์ˆœ์„œ๋Œ€๋กœ๋งŒ ํ•˜๋ฉด ์•ฑ์ด ๋‚˜์˜ต๋‹ˆ๋‹ค.