diff --git a/app.sh b/app.sh
new file mode 100755
index 0000000..4d805c6
--- /dev/null
+++ b/app.sh
@@ -0,0 +1,12 @@
+#! /usr/bin/env bash
+
+case $1 in
+ gitup)
+ echo "Pushing to git"
+ git add -A
+ git commit -m $(date "+%Y-%m-%dT%H:%M:%S")
+ git push origin
+ ;;
+ *)
+ code .
+esac
diff --git a/docs/02_기본 문법.md b/docs/02_기본 문법.md
new file mode 100644
index 0000000..edefcf7
--- /dev/null
+++ b/docs/02_기본 문법.md
@@ -0,0 +1,118 @@
+# **코틀린 vs 자바: 기본 문법 비교**
+
+코틀린은 자바 개발자가 배우기 쉬운 언어이지만, 몇 가지 중요한 문법적 차이가 있다. 이 글에서는 **변수 선언**, **null 안정성**, **타입 추론**을 중심으로 코틀린과 자바의 차이점을 비교해보겠다.
+
+## **1. 변수 선언: `val`과 `var`**
+
+자바에서 변수를 선언할 때는 반드시 데이터 타입을 명시해야 한다.
+
+### **자바의 변수 선언**
+```java
+int x = 10; // 변경 가능한 변수
+final int y = 20; // 변경 불가능한 변수 (상수)
+```
+
+코틀린에서는 `var`와 `val` 키워드를 사용하여 변수를 선언한다.
+
+- `var` → **변경 가능**(mutable) 변수
+- `val` → **변경 불가능**(immutable) 변수 (자바의 `final`과 유사)
+
+### **코틀린의 변수 선언**
+```kotlin
+var x = 10 // 변경 가능
+val y = 20 // 변경 불가능 (한 번만 할당 가능)
+```
+
+> **차이점 요약**
+> - 코틀린에서는 **데이터 타입을 생략**할 수 있다. (타입 추론 덕분)
+> - `val`은 `final`과 유사하지만, **런타임 상수는 아님**. (즉, `val` 변수는 런타임에서 초기화 가능)
+
+---
+
+## **2. 널 안정성 (Null Safety)**
+
+자바에서는 `null` 값이 있을 경우 `NullPointerException(NPE)`이 발생할 수 있다.
+
+### **자바의 null 처리**
+```java
+String name = null; // 컴파일러가 오류를 발생시키지 않음
+System.out.println(name.length()); // NullPointerException 발생 가능
+```
+
+코틀린에서는 **기본적으로 모든 변수는 null을 허용하지 않는다.** 만약 null을 허용하려면 `?`를 붙여야 한다.
+
+### **코틀린의 null 처리**
+```kotlin
+var name: String = "Kotlin" // null 허용 X
+// name = null // 컴파일 오류 발생
+
+var nullableName: String? = "Kotlin" // null 허용 O
+nullableName = null // 가능
+```
+
+#### **안전한 null 처리 방법**
+1. **안전 호출 연산자 (`?.`)**
+ ```kotlin
+ println(nullableName?.length) // null이면 null 반환, 아니면 length 값 반환
+ ```
+2. **엘비스 연산자 (`?:`)**
+ ```kotlin
+ val length = nullableName?.length ?: 0 // null이면 기본값(0) 반환
+ ```
+3. **강제 호출 연산자 (`!!`)**
+ ```kotlin
+ println(nullableName!!.length) // null이면 강제 NPE 발생
+ ```
+
+> **차이점 요약**
+> - 코틀린은 기본적으로 모든 변수에 대해 null을 허용하지 않음.
+> - `?`를 붙이면 null 허용 변수로 선언 가능.
+> - 안전한 호출 (`?.`), 기본값 제공 (`?:`), 강제 호출 (`!!`) 등의 문법을 제공.
+
+---
+
+## **3. 타입 추론 (Type Inference)**
+
+자바에서는 변수 선언 시 반드시 타입을 명시해야 한다.
+
+### **자바의 타입 선언**
+```java
+String message = "Hello, Java!";
+int number = 42;
+```
+
+코틀린에서는 타입을 **컴파일러가 자동으로 추론**하므로, 명시적으로 쓸 필요가 없다.
+
+### **코틀린의 타입 추론**
+```kotlin
+val message = "Hello, Kotlin!" // String으로 추론
+var number = 42 // Int로 추론
+```
+
+하지만 타입을 명확하게 하고 싶다면 명시적으로 적을 수도 있다.
+
+```kotlin
+val message: String = "Hello, Kotlin!"
+var number: Int = 42
+```
+
+> **차이점 요약**
+> - 코틀린은 **타입을 생략 가능**(컴파일러가 추론).
+> - 하지만 필요하면 타입을 명시할 수도 있음.
+
+---
+
+## **정리: 자바 vs 코틀린 비교**
+
+| 기능 | 자바 | 코틀린 |
+|------|------|--------|
+| **변수 선언** | `int x = 10;`
`final int y = 20;` | `var x = 10`
`val y = 20` |
+| **null 안정성** | `String name = null;` (가능하지만 NPE 위험) | `var name: String? = null` (null 허용 여부를 명확히 지정) |
+| **안전한 null 처리** | `if (name != null) { name.length(); }` | `name?.length ?: 0` |
+| **타입 추론** | `String message = "Hello";` | `val message = "Hello"` (타입 생략 가능) |
+
+---
+
+코틀린은 **더 간결하고 안전한 코드**를 작성할 수 있도록 설계된 언어다. 자바 개발자가 코틀린을 배우면 **불필요한 코드가 줄어들고**, **NPE 걱정 없이 더 안전한 프로그래밍**이 가능해진다.
+
+다음에는 어떤 코틀린 개념을 비교해볼까?
\ No newline at end of file
diff --git a/docs/03_함수형 프로그래밍.md b/docs/03_함수형 프로그래밍.md
new file mode 100644
index 0000000..8ef0fda
--- /dev/null
+++ b/docs/03_함수형 프로그래밍.md
@@ -0,0 +1,193 @@
+# **코틀린 vs 자바: 함수형 프로그래밍 차이점**
+
+코틀린은 **객체지향 프로그래밍(OOP)과 함수형 프로그래밍(FP)을 모두 지원**하는 하이브리드 언어다. 반면, 자바는 원래 객체지향 언어였지만, 자바 8 이후로 람다 표현식과 스트림 API를 도입하면서 함수형 스타일을 부분적으로 지원하게 되었다.
+
+이 글에서는 **함수형 프로그래밍의 핵심 개념**인 **고차 함수, 람다 표현식, 확장 함수, 불변성** 등을 자바와 코틀린을 비교하며 설명하겠다.
+
+---
+
+## **1. 함수형 프로그래밍이란?**
+함수형 프로그래밍(FP, Functional Programming)은 **순수 함수**와 **불변성(immutability)**을 중심으로 하는 프로그래밍 패러다임이다. 핵심 원칙은 다음과 같다.
+
+- **순수 함수 (Pure Function):** 같은 입력에 대해 항상 같은 출력을 반환하며, 외부 상태를 변경하지 않는다.
+- **불변성 (Immutability):** 데이터를 변경하지 않고 새로운 값을 반환하는 방식으로 동작한다.
+- **고차 함수 (Higher-Order Function):** 함수를 인자로 받거나 반환하는 함수.
+- **람다 표현식 (Lambda Expression):** 간결한 익명 함수 표현.
+
+---
+
+## **2. 함수 선언 방식 차이**
+
+### **자바의 함수 선언 (객체지향 스타일)**
+```java
+public class Calculator {
+ public static int add(int a, int b) {
+ return a + b;
+ }
+}
+```
+```java
+int result = Calculator.add(3, 5);
+```
+
+### **코틀린의 함수 선언 (함수형 스타일 지원)**
+```kotlin
+fun add(a: Int, b: Int): Int {
+ return a + b
+}
+```
+```kotlin
+val result = add(3, 5)
+```
+
+> **차이점 요약:**
+> - 코틀린에서는 클래스 없이 **함수를 직접 정의 가능**(파일 수준 함수).
+> - `fun` 키워드를 사용하며 **반환 타입을 `:`로 지정**.
+> - 한 줄짜리 함수는 `{}` 없이 `=`로 간결하게 표현 가능.
+
+```kotlin
+fun add(a: Int, b: Int) = a + b
+```
+
+---
+
+## **3. 람다 표현식 (Lambda Expression)**
+
+람다 표현식은 **익명 함수(Anonymous Function)**의 한 형태로, 간결한 함수형 코드를 작성하는 데 사용된다.
+
+### **자바의 람다 표현식 (Java 8 이상)**
+```java
+// 두 수를 더하는 람다 함수
+BiFunction sum = (a, b) -> a + b;
+System.out.println(sum.apply(5, 3)); // 출력: 8
+```
+> 자바에서는 `BiFunction` 같은 **함수형 인터페이스**를 사용해야 람다를 활용할 수 있다.
+
+### **코틀린의 람다 표현식**
+```kotlin
+// 두 수를 더하는 람다 함수
+val sum: (Int, Int) -> Int = { a, b -> a + b }
+println(sum(5, 3)) // 출력: 8
+```
+> 코틀린은 별도의 함수형 인터페이스 없이 **람다 표현식을 바로 변수에 할당 가능**.
+
+#### **더 간결한 표현**
+코틀린에서는 **타입 추론**이 가능하므로, 타입을 생략할 수도 있다.
+```kotlin
+val sum = { a: Int, b: Int -> a + b }
+```
+
+> **차이점 요약:**
+> - 자바는 람다를 사용하려면 `BiFunction<>` 같은 **함수형 인터페이스**가 필요.
+> - 코틀린은 **별도의 인터페이스 없이 람다를 변수에 직접 할당 가능**.
+> - `{ 파라미터 -> 함수 본문 }` 형태로 사용.
+
+---
+
+## **4. 고차 함수 (Higher-Order Function)**
+
+고차 함수는 **다른 함수를 인자로 받거나 반환하는 함수**를 의미한다.
+
+### **자바에서 고차 함수 구현 (익명 클래스 사용)**
+자바에서는 **람다 도입 전**에는 익명 클래스를 활용해야 했다.
+```java
+public interface MathOperation {
+ int operate(int a, int b);
+}
+
+// 고차 함수
+public static int executeOperation(int x, int y, MathOperation operation) {
+ return operation.operate(x, y);
+}
+
+// 사용 예시
+int result = executeOperation(5, 3, new MathOperation() {
+ @Override
+ public int operate(int a, int b) {
+ return a + b;
+ }
+});
+```
+
+자바 8 이후에는 람다 표현식 덕분에 훨씬 간결해졌다.
+```java
+int result = executeOperation(5, 3, (a, b) -> a + b);
+```
+
+### **코틀린에서 고차 함수 구현**
+코틀린에서는 **함수를 직접 타입으로 선언 가능**.
+```kotlin
+fun executeOperation(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
+ return operation(a, b)
+}
+
+// 사용 예시
+val result = executeOperation(5, 3) { x, y -> x + y }
+```
+
+> **차이점 요약:**
+> - 자바에서는 **인터페이스를 먼저 정의해야 하지만**, 코틀린에서는 **함수를 직접 타입으로 선언 가능**.
+> - 코틀린의 람다는 **더 간결한 문법 제공**.
+
+---
+
+## **5. 확장 함수 (Extension Function)**
+
+자바에서는 기존 클래스를 확장하려면 **상속(Inheritance)이나 유틸리티 클래스**를 사용해야 한다.
+
+### **자바의 유틸리티 메서드 방식**
+```java
+public class StringUtils {
+ public static String greet(String name) {
+ return "Hello, " + name + "!";
+ }
+}
+System.out.println(StringUtils.greet("Java"));
+```
+
+### **코틀린의 확장 함수**
+코틀린에서는 **기존 클래스에 새로운 메서드를 추가하는 것처럼 확장 가능**.
+```kotlin
+fun String.greet(): String {
+ return "Hello, $this!"
+}
+
+println("Kotlin".greet()) // 출력: Hello, Kotlin!
+```
+
+> **차이점 요약:**
+> - 자바에서는 **유틸리티 클래스의 정적 메서드**를 사용해야 함.
+> - 코틀린에서는 **클래스를 수정하지 않고도 확장 함수로 기능 추가 가능**.
+
+---
+
+## **6. 불변성과 컬렉션 처리**
+
+### **자바의 불변 컬렉션**
+```java
+List names = List.of("Alice", "Bob"); // 변경 불가능한 리스트 (Java 9+)
+```
+
+### **코틀린의 불변 컬렉션**
+```kotlin
+val names = listOf("Alice", "Bob") // 변경 불가능한 리스트
+```
+
+> **차이점 요약:**
+> - 코틀린은 `listOf()`, `setOf()` 등을 통해 불변 컬렉션을 쉽게 생성 가능.
+> - 자바 8까지는 `Collections.unmodifiableList()`를 사용해야 했음.
+
+---
+
+## **정리: 자바 vs 코틀린 함수형 프로그래밍**
+
+| 기능 | 자바 | 코틀린 |
+|------|------|--------|
+| 람다 표현식 | `(a, b) -> a + b` (`BiFunction` 필요) | `{ a, b -> a + b }` (함수형 타입 지원) |
+| 고차 함수 | 함수형 인터페이스 필요 | 함수 타입 `(Int, Int) -> Int` 직접 사용 가능 |
+| 확장 함수 | 유틸리티 메서드 필요 | `fun String.greet() = "Hello, $this"` |
+| 불변 컬렉션 | `List.of()` (Java 9+) | `listOf()` |
+
+코틀린은 자바보다 함수형 프로그래밍을 **더 자연스럽고 간결하게 지원**한다.
+
+다음에는 어떤 개념을 비교해볼까?
\ No newline at end of file
diff --git a/docs/04_OOP.md b/docs/04_OOP.md
new file mode 100644
index 0000000..8f9e5ea
--- /dev/null
+++ b/docs/04_OOP.md
@@ -0,0 +1,231 @@
+# **코틀린 vs 자바: 객체지향 프로그래밍(OOP) 비교**
+
+코틀린과 자바는 둘 다 객체지향 프로그래밍(OOP)을 지원하는 언어지만, 코틀린은 더 간결하고 유연한 문법을 제공한다.
+이번 글에서는 **클래스 선언, 생성자, 상속, 접근 제어자, 데이터 클래스, 객체 선언** 등을 중심으로 자바와 코틀린의 차이점을 비교하겠다.
+
+---
+
+## **1. 클래스 선언 방식 차이**
+
+자바에서는 클래스를 선언할 때 `class` 키워드를 사용하고, **필드와 생성자를 분리**해서 작성하는 것이 일반적이다.
+
+### **자바의 클래스 선언**
+```java
+public class Person {
+ private String name;
+ private int age;
+
+ public Person(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ public String getName() { return name; }
+ public int getAge() { return age; }
+}
+```
+### **코틀린의 클래스 선언**
+코틀린에서는 **주 생성자(Primary Constructor)**를 **클래스 헤더에 직접 정의**할 수 있다.
+
+```kotlin
+class Person(val name: String, val age: Int)
+```
+
+> **차이점 요약:**
+> - **자바:** 필드, 생성자, 게터를 따로 작성해야 함.
+> - **코틀린:** `val` 또는 `var`을 사용하면 **자동으로 필드와 게터 생성**.
+
+---
+
+## **2. 생성자 (Constructors)**
+
+자바에서는 **기본 생성자**와 **매개변수가 있는 생성자**를 따로 정의해야 한다.
+
+### **자바의 생성자 오버로딩**
+```java
+public class Car {
+ private String model;
+
+ public Car() {
+ this.model = "Unknown";
+ }
+
+ public Car(String model) {
+ this.model = model;
+ }
+}
+```
+
+코틀린에서는 **기본값을 지정**할 수 있어 생성자 오버로딩을 줄일 수 있다.
+
+### **코틀린의 기본값 제공 방식**
+```kotlin
+class Car(val model: String = "Unknown")
+```
+
+> **차이점 요약:**
+> - 자바는 **생성자 오버로딩**이 필요하지만,
+> - 코틀린은 **기본값을 제공하면 생성자 하나로 해결 가능**.
+
+---
+
+## **3. 상속 (Inheritance)과 `open` 키워드**
+
+자바에서 클래스를 상속하려면 `extends` 키워드를 사용하고, **메서드 오버라이딩 시 `@Override`를 명시**해야 한다.
+
+### **자바의 상속**
+```java
+public class Animal {
+ public void makeSound() {
+ System.out.println("Some sound");
+ }
+}
+
+public class Dog extends Animal {
+ @Override
+ public void makeSound() {
+ System.out.println("Bark!");
+ }
+}
+```
+
+코틀린에서는 클래스가 **기본적으로 `final`이므로 상속을 허용하려면 `open` 키워드를 붙여야 한다**.
+
+### **코틀린의 상속**
+```kotlin
+open class Animal {
+ open fun makeSound() {
+ println("Some sound")
+ }
+}
+
+class Dog : Animal() {
+ override fun makeSound() {
+ println("Bark!")
+ }
+}
+```
+
+> **차이점 요약:**
+> - **자바:** 모든 클래스가 기본적으로 **상속 가능**(`final`이 아님).
+> - **코틀린:** 모든 클래스가 기본적으로 **`final`이며, 상속하려면 `open`을 붙여야 함**.
+> - **오버라이딩 시 자바는 `@Override` 사용**, 코틀린은 **`override` 키워드 필수**.
+
+---
+
+## **4. 접근 제어자 (Access Modifiers)**
+
+자바와 코틀린 모두 **`public`, `protected`, `private`** 접근 제어자를 제공하지만,
+코틀린에는 **추가로 `internal`이 있다**.
+
+| 접근 제어자 | 자바 | 코틀린 |
+|------------|------|--------|
+| `public` | 모든 곳에서 접근 가능 | 동일 |
+| `protected` | 같은 패키지 + 하위 클래스에서 접근 가능 | 하위 클래스에서만 접근 가능 (패키지 무관) |
+| `private` | 같은 클래스 내에서만 접근 가능 | 동일 |
+| `default` (생략 시) | 같은 패키지 내에서 접근 가능 | `internal` (같은 모듈 내에서 접근 가능) |
+
+### **코틀린의 `internal` 키워드**
+```kotlin
+internal class InternalClass {
+ fun greet() = "Hello"
+}
+```
+> - `internal`은 **같은 모듈 내에서만 접근 가능**(자바에는 해당 없음).
+
+---
+
+## **5. 데이터 클래스 (Data Class)**
+
+자바에서는 **`equals()`, `hashCode()`, `toString()` 메서드를 직접 구현**해야 한다.
+
+### **자바의 데이터 클래스를 수동 구현**
+```java
+public class User {
+ private String name;
+ private int age;
+
+ public User(String name, int age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null || getClass() != obj.getClass()) return false;
+ User user = (User) obj;
+ return age == user.age && Objects.equals(name, user.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name, age);
+ }
+
+ @Override
+ public String toString() {
+ return "User{name='" + name + "', age=" + age + "}";
+ }
+}
+```
+
+코틀린에서는 **`data` 키워드를 추가하는 것만으로 자동 생성**된다.
+
+### **코틀린의 데이터 클래스**
+```kotlin
+data class User(val name: String, val age: Int)
+```
+> **차이점 요약:**
+> - 자바에서는 `equals()`, `hashCode()`, `toString()`을 직접 작성해야 함.
+> - 코틀린에서는 `data class`만 선언하면 자동 생성됨.
+
+---
+
+## **6. 싱글턴 (Singleton) 객체 선언**
+
+자바에서 싱글턴 패턴을 구현하려면 **`static` 키워드를 사용하거나, `enum`을 활용**해야 한다.
+
+### **자바의 싱글턴 패턴**
+```java
+public class Singleton {
+ private static final Singleton INSTANCE = new Singleton();
+
+ private Singleton() {}
+
+ public static Singleton getInstance() {
+ return INSTANCE;
+ }
+}
+```
+
+코틀린에서는 **`object` 키워드를 사용하면 자동으로 싱글턴이 된다**.
+
+### **코틀린의 싱글턴**
+```kotlin
+object Singleton {
+ fun greet() = "Hello"
+}
+
+println(Singleton.greet()) // Hello
+```
+
+> **차이점 요약:**
+> - 자바는 **싱글턴을 만들기 위해 보일러플레이트 코드 필요**.
+> - 코틀린은 `object`를 사용하면 자동으로 싱글턴 객체 생성됨.
+
+---
+
+## **정리: 자바 vs 코틀린 OOP 차이점**
+
+| 기능 | 자바 | 코틀린 |
+|------|------|--------|
+| **클래스 선언** | 필드 + 생성자 + 게터 필요 | `class Person(val name: String)` |
+| **생성자 오버로딩** | 여러 개의 생성자 정의 필요 | 기본값 사용 가능 |
+| **상속** | 기본적으로 가능 (`final`을 붙여야 제한) | 기본적으로 `final`, `open`을 붙여야 상속 가능 |
+| **데이터 클래스** | `equals()`, `hashCode()`, `toString()` 직접 구현 | `data class`로 자동 생성 |
+| **싱글턴 패턴** | `static` 필드 사용 | `object` 키워드 사용 |
+| **`protected` 접근 제어자** | 같은 패키지 + 하위 클래스 접근 가능 | 오직 하위 클래스만 접근 가능 |
+
+코틀린은 **객체지향 프로그래밍을 더 간결하고 효율적으로 작성할 수 있도록 개선**된 언어다.
+다음에는 어떤 개념을 비교해볼까?
\ No newline at end of file
diff --git a/docs/05_컬렉션.md b/docs/05_컬렉션.md
new file mode 100644
index 0000000..f9f2d49
--- /dev/null
+++ b/docs/05_컬렉션.md
@@ -0,0 +1,183 @@
+# **코틀린 컬렉션과 스트림 API vs 자바 스트림 API**
+
+코틀린은 자바와 마찬가지로 **리스트(List), 세트(Set), 맵(Map)** 등의 컬렉션을 제공한다. 하지만 자바와는 다르게, **컬렉션을 더욱 간결하게 다룰 수 있는 함수형 API**를 기본 제공하며, 대부분의 연산을 **람다식과 메서드 체이닝**을 통해 쉽게 수행할 수 있다.
+
+이번 글에서는 **코틀린의 컬렉션 사용법과 자바 스트림 API와의 차이점**을 비교해보겠다.
+
+---
+
+## **1. 코틀린 컬렉션 기본 개념**
+
+### **1.1. 불변(Immutable) vs 가변(Mutable) 컬렉션**
+
+코틀린의 컬렉션은 **불변형(`listOf`, `setOf`, `mapOf`)**과 **가변형(`mutableListOf`, `mutableSetOf`, `mutableMapOf`)**으로 나뉜다.
+자바에서는 `Collections.unmodifiableList()` 등을 사용해야 하지만, 코틀린에서는 기본적으로 **불변 컬렉션을 사용하도록 유도**한다.
+
+#### **자바의 리스트 선언**
+```java
+List immutableList = List.of("A", "B", "C"); // Java 9+
+List mutableList = new ArrayList<>();
+mutableList.add("A");
+mutableList.add("B");
+```
+
+#### **코틀린의 리스트 선언**
+```kotlin
+val immutableList = listOf("A", "B", "C") // 불변 리스트
+val mutableList = mutableListOf("A", "B") // 가변 리스트
+mutableList.add("C")
+```
+> **차이점 요약:**
+> - **자바**: `List.of()`(불변) vs `ArrayList<>()`(가변)
+> - **코틀린**: `listOf()`(불변) vs `mutableListOf()`(가변)
+
+---
+
+## **2. 코틀린 컬렉션 사용 예제**
+
+### **2.1. 리스트(List)**
+```kotlin
+val numbers = listOf(1, 2, 3, 4, 5)
+println(numbers[0]) // 1
+println(numbers.size) // 5
+```
+가변 리스트:
+```kotlin
+val mutableNumbers = mutableListOf(1, 2, 3)
+mutableNumbers.add(4)
+println(mutableNumbers) // [1, 2, 3, 4]
+```
+
+---
+
+### **2.2. 집합(Set)**
+```kotlin
+val names = setOf("Alice", "Bob", "Charlie")
+println(names.contains("Alice")) // true
+```
+가변 집합:
+```kotlin
+val mutableNames = mutableSetOf("Alice", "Bob")
+mutableNames.add("Charlie")
+```
+
+---
+
+### **2.3. 맵(Map)**
+```kotlin
+val userMap = mapOf("Alice" to 25, "Bob" to 30)
+println(userMap["Alice"]) // 25
+```
+가변 맵:
+```kotlin
+val mutableUserMap = mutableMapOf("Alice" to 25)
+mutableUserMap["Bob"] = 30
+```
+
+---
+
+## **3. 코틀린의 스트림 API vs 자바의 스트림 API**
+
+자바에서는 컬렉션을 처리할 때 **스트림 API(`Stream`)**를 사용해야 하지만,
+코틀린은 **컬렉션 자체가 스트림 API처럼 동작**한다.
+
+### **3.1. 자바 스트림 예제**
+```java
+List names = List.of("Alice", "Bob", "Charlie");
+List filteredNames = names.stream()
+ .filter(name -> name.startsWith("A"))
+ .map(String::toUpperCase)
+ .collect(Collectors.toList());
+
+System.out.println(filteredNames); // [ALICE]
+```
+> **자바의 특징:**
+> - `.stream()`을 호출해야 함
+> - `.collect(Collectors.toList())`를 사용해야 리스트 반환
+
+---
+
+### **3.2. 코틀린 컬렉션 API 예제**
+```kotlin
+val names = listOf("Alice", "Bob", "Charlie")
+val filteredNames = names
+ .filter { it.startsWith("A") }
+ .map { it.uppercase() }
+
+println(filteredNames) // [ALICE]
+```
+> **코틀린의 특징:**
+> - `stream()` 없이 컬렉션 자체에서 메서드 체이닝 가능
+> - `collect()` 없이 리스트 반환
+
+---
+
+### **3.3. 숫자 리스트 필터링 & 변환**
+#### **자바 (Stream API 사용)**
+```java
+List numbers = List.of(1, 2, 3, 4, 5, 6);
+List evenSquares = numbers.stream()
+ .filter(n -> n % 2 == 0)
+ .map(n -> n * n)
+ .collect(Collectors.toList());
+
+System.out.println(evenSquares); // [4, 16, 36]
+```
+#### **코틀린 (컬렉션 API 사용)**
+```kotlin
+val numbers = listOf(1, 2, 3, 4, 5, 6)
+val evenSquares = numbers
+ .filter { it % 2 == 0 }
+ .map { it * it }
+
+println(evenSquares) // [4, 16, 36]
+```
+
+> **차이점 요약:**
+> - **자바**: `.stream()` 호출 → `filter()`, `map()` → `.collect(Collectors.toList())` 필요
+> - **코틀린**: 바로 `filter()`, `map()` 사용 가능
+
+---
+
+## **4. 추가적인 컬렉션 함수들**
+
+### **4.1. `forEach`**
+```kotlin
+val numbers = listOf(1, 2, 3)
+numbers.forEach { println(it) }
+```
+
+### **4.2. `groupBy`**
+```kotlin
+val words = listOf("apple", "banana", "avocado", "blueberry")
+val grouped = words.groupBy { it.first() }
+println(grouped)
+// {a=[apple, avocado], b=[banana, blueberry]}
+```
+
+### **4.3. `associateBy` (키 매핑)**
+```kotlin
+data class Person(val name: String, val age: Int)
+
+val people = listOf(Person("Alice", 25), Person("Bob", 30))
+val personMap = people.associateBy { it.name }
+println(personMap["Alice"]) // Person(name=Alice, age=25)
+```
+
+---
+
+## **5. 정리: 코틀린 vs 자바 스트림 API 차이점**
+
+| 기능 | 자바 (Stream API) | 코틀린 (컬렉션 API) |
+|------|----------------|----------------|
+| 스트림 사용 | `.stream()` 필요 | 컬렉션 자체에서 사용 가능 |
+| 리스트 반환 | `.collect(Collectors.toList())` 필요 | 자동 반환 |
+| `filter()` 사용 | `filter(n -> 조건)` | `filter { it 조건 }` |
+| `map()` 사용 | `map(n -> 변환)` | `map { it 변환 }` |
+| 그룹핑 | `.collect(Collectors.groupingBy())` | `groupBy { it 기준 }` |
+| 가변 리스트 | `new ArrayList<>()` | `mutableListOf()` |
+
+코틀린은 **컬렉션을 더욱 직관적이고 간결하게 다룰 수 있도록 설계**되었다.
+자바에서 스트림 API를 써야 하는 많은 경우를 **코틀린에서는 기본 컬렉션 함수만으로 해결**할 수 있다.
+
+> **코틀린으로 스트림 API를 더 쉽게 다룰 수 있다는 점을 기억하자!**
\ No newline at end of file
diff --git a/docs/06_예외 처리 및 흐름 제어.md b/docs/06_예외 처리 및 흐름 제어.md
new file mode 100644
index 0000000..bfbbac9
--- /dev/null
+++ b/docs/06_예외 처리 및 흐름 제어.md
@@ -0,0 +1,216 @@
+# **코틀린 vs 자바: 예외 처리와 흐름 제어 차이점**
+
+코틀린과 자바는 기본적으로 예외 처리(Exception Handling)와 흐름 제어(Control Flow)를 비슷하게 제공하지만,
+코틀린은 **더 간결한 문법과 강력한 기능**을 제공하여, 예외를 보다 효과적으로 처리하고 흐름 제어를 쉽게 구현할 수 있다.
+
+이 글에서는 **예외 처리와 흐름 제어**에서 **코틀린과 자바의 차이점**을 비교해 보겠다.
+
+---
+
+## **1. 예외 처리 (Exception Handling)**
+
+자바와 코틀린 모두 **`try-catch-finally`** 블록을 지원하지만,
+코틀린에서는 **예외가 표현식(Expression)으로 사용 가능**하고, **Checked Exception이 없다**는 차이가 있다.
+
+### **1.1. 자바의 예외 처리**
+```java
+public class JavaExceptionExample {
+ public static void main(String[] args) {
+ try {
+ int result = divide(10, 0);
+ System.out.println(result);
+ } catch (ArithmeticException e) {
+ System.out.println("예외 발생: " + e.getMessage());
+ } finally {
+ System.out.println("예외 여부와 관계없이 실행됨");
+ }
+ }
+
+ static int divide(int a, int b) throws ArithmeticException {
+ return a / b; // 0으로 나누면 예외 발생
+ }
+}
+```
+**출력 결과:**
+```
+예외 발생: / by zero
+예외 여부와 관계없이 실행됨
+```
+
+> **자바의 특징:**
+> - `throws` 키워드를 사용하여 Checked Exception을 선언해야 할 수 있음
+> - `try-catch-finally` 블록 필요
+
+---
+
+### **1.2. 코틀린의 예외 처리**
+```kotlin
+fun main() {
+ try {
+ val result = divide(10, 0)
+ println(result)
+ } catch (e: ArithmeticException) {
+ println("예외 발생: ${e.message}")
+ } finally {
+ println("예외 여부와 관계없이 실행됨")
+ }
+}
+
+fun divide(a: Int, b: Int): Int {
+ return a / b // 0으로 나누면 예외 발생
+}
+```
+**출력 결과:**
+```
+예외 발생: / by zero
+예외 여부와 관계없이 실행됨
+```
+
+> **코틀린의 특징:**
+> - `throws` 선언이 필요 없음 (Checked Exception이 없음)
+> - 예외 처리를 **표현식(Expression)으로 사용할 수 있음**
+
+---
+
+### **1.3. 예외를 반환값으로 사용하는 경우 (코틀린만 가능)**
+자바에서는 `try-catch` 블록을 표현식으로 사용할 수 없지만,
+코틀린에서는 **`try` 자체가 값(value)을 반환할 수 있다**.
+
+```kotlin
+val result: Int = try {
+ divide(10, 2)
+} catch (e: ArithmeticException) {
+ -1 // 예외 발생 시 기본값 반환
+}
+println(result) // 5
+```
+> **코틀린의 특징:**
+> - `try-catch` 블록을 값처럼 사용 가능
+> - 예외 발생 시 기본값을 쉽게 설정 가능
+
+---
+
+## **2. 흐름 제어 (Control Flow) 차이점**
+
+자바와 코틀린은 기본적인 흐름 제어 구조(`if`, `when`, `for`, `while`)가 유사하지만,
+코틀린은 **표현식(Expression) 기반으로 설계**되어 보다 간결하게 코드를 작성할 수 있다.
+
+### **2.1. `if` 문법 차이**
+#### **자바의 `if-else` (Statement 기반)**
+```java
+int number = 10;
+String result;
+
+if (number % 2 == 0) {
+ result = "짝수";
+} else {
+ result = "홀수";
+}
+
+System.out.println(result);
+```
+
+#### **코틀린의 `if-else` (Expression 기반)**
+```kotlin
+val number = 10
+val result = if (number % 2 == 0) "짝수" else "홀수"
+
+println(result)
+```
+> **차이점 요약:**
+> - 자바는 `if-else`가 **Statement(문장)**
+> - 코틀린은 `if-else`가 **Expression(값을 반환할 수 있음)**
+
+---
+
+### **2.2. `switch-case` vs `when`**
+자바에서는 `switch-case` 문을 사용하지만, 코틀린에서는 더 강력한 **`when`**을 제공한다.
+
+#### **자바의 `switch-case`**
+```java
+int number = 2;
+String result;
+
+switch (number) {
+ case 1:
+ result = "One";
+ break;
+ case 2:
+ result = "Two";
+ break;
+ default:
+ result = "Unknown";
+}
+
+System.out.println(result);
+```
+
+#### **코틀린의 `when` (더 강력한 표현 가능)**
+```kotlin
+val number = 2
+val result = when (number) {
+ 1 -> "One"
+ 2 -> "Two"
+ else -> "Unknown"
+}
+
+println(result)
+```
+> **코틀린의 특징:**
+> - `when`은 **Expression**으로 값을 반환 가능
+> - `break`가 필요 없음
+> - 복합 조건 사용 가능 (`in`, `is` 활용 가능)
+
+```kotlin
+val result = when (number) {
+ in 1..5 -> "1~5 범위"
+ is Int -> "정수"
+ else -> "알 수 없음"
+}
+```
+
+---
+
+### **2.3. 반복문 차이점**
+#### **자바의 `for` 반복문**
+```java
+List names = List.of("Alice", "Bob", "Charlie");
+
+for (String name : names) {
+ System.out.println(name);
+}
+```
+#### **코틀린의 `for` 반복문**
+```kotlin
+val names = listOf("Alice", "Bob", "Charlie")
+
+for (name in names) {
+ println(name)
+}
+```
+> **차이점 요약:**
+> - 코틀린은 **`for (element in collection)`** 형식을 사용
+> - **인덱스가 필요하면 `withIndex()` 활용 가능**
+
+```kotlin
+for ((index, name) in names.withIndex()) {
+ println("$index: $name")
+}
+```
+
+---
+
+## **3. 결론: 코틀린이 더 간결하고 유연하다**
+
+| 기능 | 자바 | 코틀린 |
+|------|------|------|
+| 예외 처리 | Checked Exception 있음 | Checked Exception 없음 |
+| `try-catch` | Statement (값 반환 불가) | Expression (값 반환 가능) |
+| `if-else` | Statement | Expression |
+| `switch-case` | `break` 필요 | `when`으로 더 강력하게 가능 |
+| `for` 반복문 | `for (item : collection)` | `for (item in collection)` |
+| `for` 인덱스 | `for (int i = 0; i < list.size(); i++)` | `for ((index, item) in list.withIndex())` |
+
+코틀린은 **표현식 기반**으로 설계되어 불필요한 문법을 줄이고 **더 간결한 코드**를 작성할 수 있다.
+특히 예외 처리에서 Checked Exception이 없고, `when`과 `try-catch`를 표현식으로 사용할 수 있어
+**보다 유연하고 직관적인 코드 작성이 가능**하다. 🚀
\ No newline at end of file
diff --git a/docs/07_코루틴.md b/docs/07_코루틴.md
new file mode 100644
index 0000000..795115d
--- /dev/null
+++ b/docs/07_코루틴.md
@@ -0,0 +1,223 @@
+# **코틀린의 코루틴과 비동기 프로그래밍**
+
+코틀린은 **코루틴(Coroutines)** 을 통해 **비동기(Asynchronous) 프로그래밍**을 쉽고 직관적으로 구현할 수 있다.
+코루틴은 **스레드보다 가볍고 효율적**이며, **콜백 지옥을 피할 수 있는 강력한 기능**을 제공한다.
+
+이 글에서는 **코루틴의 개념과 주요 기능**을 설명하고,
+**비동기 프로그래밍을 구현하는 예제**를 함께 살펴보겠다. 🚀
+
+---
+
+## **1. 비동기 프로그래밍이란?**
+비동기 프로그래밍은 **작업이 완료될 때까지 기다리지 않고 다음 코드를 실행하는 방식**이다.
+즉, **시간이 오래 걸리는 작업(예: 네트워크 요청, 파일 I/O 등)** 도 프로그램이 멈추지 않고 실행된다.
+
+### **1.1. 전통적인 방식 (콜백 지옥)**
+자바에서는 비동기 작업을 콜백(callback) 방식으로 처리해야 한다.
+콜백이 중첩되면 **콜백 지옥(Callback Hell)** 이 발생할 수 있다.
+
+#### **자바의 콜백 예제**
+```java
+void fetchData(Callback callback) {
+ new Thread(() -> {
+ try {
+ Thread.sleep(2000); // 2초 대기 (네트워크 요청 가정)
+ callback.onSuccess("데이터를 가져왔습니다!");
+ } catch (InterruptedException e) {
+ callback.onError(e);
+ }
+ }).start();
+}
+
+interface Callback {
+ void onSuccess(String data);
+ void onError(Exception e);
+}
+
+public static void main(String[] args) {
+ fetchData(new Callback() {
+ @Override
+ public void onSuccess(String data) {
+ System.out.println(data);
+ }
+
+ @Override
+ public void onError(Exception e) {
+ System.out.println("에러 발생: " + e.getMessage());
+ }
+ });
+}
+```
+> - `fetchData()` 가 비동기적으로 데이터를 가져오지만, **콜백을 계속 중첩해서 작성해야 한다.**
+> - 코드가 복잡해지고 가독성이 나빠지는 문제가 있다.
+
+---
+
+## **2. 코루틴이란?**
+**코루틴(Coroutines)** 은 **비동기 프로그래밍을 간결하고 가독성 높게** 구현할 수 있도록 도와준다.
+코루틴을 사용하면 **콜백 없이도 순차적인 코드 스타일**로 **비동기 작업**을 작성할 수 있다.
+
+> **코루틴의 특징:**
+> - **스레드보다 가벼움** (필요할 때만 실행되고, 자동으로 일시 중단됨)
+> - **순차적 스타일로 작성 가능** (콜백 없이 비동기 코드 작성 가능)
+> - **비동기 코드가 직관적이고 읽기 쉬움**
+
+---
+
+## **3. 코틀린에서 코루틴 사용하기**
+### **3.1. 기본적인 코루틴 사용**
+```kotlin
+import kotlinx.coroutines.*
+
+fun main() = runBlocking { // 코루틴 블록 시작
+ launch {
+ delay(1000L) // 1초 대기
+ println("코루틴 실행!")
+ }
+ println("메인 함수 실행")
+}
+```
+**출력 결과:**
+```
+메인 함수 실행
+코루틴 실행!
+```
+
+> - `runBlocking {}`: 메인 함수에서 코루틴을 실행하는 블록
+> - `launch {}`: 새로운 코루틴을 실행
+> - `delay(1000L)`: 1초 동안 비동기 대기 (스레드 차단 없이 실행 가능)
+
+---
+
+## **4. 코루틴 빌더 (`launch` vs `async`)**
+코루틴을 실행할 때는 **`launch`** 와 **`async`** 를 사용할 수 있다.
+
+| 빌더 | 반환값 | 특징 |
+|------|------|------|
+| `launch` | 없음 (`Job` 반환) | 단순히 코루틴을 실행 |
+| `async` | `Deferred` 반환 | 결과 값을 반환하는 비동기 작업 |
+
+### **4.1. `launch` 사용 예시 (결과 값 없음)**
+```kotlin
+import kotlinx.coroutines.*
+
+fun main() = runBlocking {
+ launch {
+ delay(1000L)
+ println("launch: 비동기 작업 완료!")
+ }
+}
+```
+> - `launch {}` 는 단순히 비동기 작업을 실행하고, 결과를 반환하지 않음.
+> - `Job` 객체를 반환하지만, 보통 `join()`을 호출하지 않는 이상 결과를 기다리지 않음.
+
+---
+
+### **4.2. `async` 사용 예시 (결과 값 반환)**
+```kotlin
+import kotlinx.coroutines.*
+
+fun main() = runBlocking {
+ val result = async {
+ delay(1000L)
+ "async: 비동기 작업 완료!"
+ }
+ println(result.await()) // 결과 값을 기다림
+}
+```
+> - `async {}` 는 **결과 값을 반환하는 비동기 작업**을 실행.
+> - `await()` 을 호출해야 실제 값을 가져올 수 있음.
+
+---
+
+## **5. 여러 개의 비동기 작업 실행 (`async` 활용)**
+비동기 작업을 병렬로 실행하려면 **`async {}` 를 여러 개 실행**하면 된다.
+```kotlin
+import kotlinx.coroutines.*
+
+fun main() = runBlocking {
+ val time = measureTimeMillis {
+ val job1 = async { fetchData(1) }
+ val job2 = async { fetchData(2) }
+ println(job1.await())
+ println(job2.await())
+ }
+ println("총 실행 시간: $time ms")
+}
+
+suspend fun fetchData(id: Int): String {
+ delay(1000L) // 네트워크 요청 시뮬레이션
+ return "데이터 $id 가져옴"
+}
+```
+**출력 결과:**
+```
+데이터 1 가져옴
+데이터 2 가져옴
+총 실행 시간: 1003 ms
+```
+> - `async {}` 로 실행된 두 개의 코루틴이 **병렬로 실행됨**.
+> - `await()` 를 호출하면 해당 코루틴이 완료될 때까지 기다림.
+> - 실행 시간은 1초 내외 (동시 실행되었기 때문).
+
+---
+
+## **6. `suspend` 함수 사용하기**
+코루틴에서 비동기 함수를 만들려면 **`suspend` 키워드**를 사용해야 한다.
+```kotlin
+suspend fun fetchData(): String {
+ delay(1000L) // 1초 대기
+ return "데이터 가져옴"
+}
+
+fun main() = runBlocking {
+ val data = fetchData()
+ println(data)
+}
+```
+> - `suspend` 함수는 **코루틴 내에서만 실행 가능**
+> - `delay()` 같은 비동기 함수 호출 가능
+
+---
+
+## **7. 예외 처리 (`try-catch` 활용)**
+코루틴에서도 **예외 처리를 `try-catch` 로 할 수 있음**.
+```kotlin
+import kotlinx.coroutines.*
+
+fun main() = runBlocking {
+ try {
+ val result = async { errorTask() }.await()
+ println(result)
+ } catch (e: Exception) {
+ println("예외 발생: ${e.message}")
+ }
+}
+
+suspend fun errorTask(): String {
+ delay(500L)
+ throw RuntimeException("오류 발생!")
+}
+```
+**출력 결과:**
+```
+예외 발생: 오류 발생!
+```
+> - `try-catch` 를 사용하면 **비동기 코드에서도 예외를 안전하게 처리 가능**.
+
+---
+
+## **8. 정리**
+| 기능 | 자바 | 코틀린 |
+|------|------|------|
+| 비동기 실행 | 콜백 기반 | 코루틴 기반 (`launch`, `async`) |
+| 가독성 | 콜백 중첩 발생 | 순차적 코드 스타일 |
+| 예외 처리 | 예외 전달 어려움 | `try-catch` 사용 가능 |
+| 실행 효율 | 스레드 사용 | 가벼운 코루틴 사용 |
+
+> **코루틴을 사용하면:**
+> ✅ **비동기 코드가 더 간결하고 직관적**
+> ✅ **콜백 지옥 없이 순차적 스타일로 작성 가능**
+> ✅ **스레드보다 가볍고 효율적**
+
+코틀린에서 **비동기 프로그래밍을 쉽게 구현하려면 코루틴을 적극 활용하자!** 🚀
\ No newline at end of file
diff --git a/docs/08_특수 기능.md b/docs/08_특수 기능.md
new file mode 100644
index 0000000..6fd4d21
--- /dev/null
+++ b/docs/08_특수 기능.md
@@ -0,0 +1,220 @@
+# **코틀린의 특수 기능과 주요 키워드**
+
+코틀린은 **개발 생산성을 높이는 다양한 특수 기능**을 제공한다.
+이 글에서는 **코틀린의 고급 기능**을 **사용 예시와 함께** 설명하겠다. 🚀
+
+### ✨ **소개할 내용**
+1. **`inline` 함수**
+2. **`reified` 키워드**
+3. **제너릭(Generic)**
+4. **위임(Delegation) 패턴과 `by` 키워드**
+
+---
+
+## **1. `inline` 함수: 함수 호출 비용 줄이기**
+코틀린의 `inline` 함수는 **함수 호출 오버헤드를 줄이기 위해 사용**된다.
+
+### **1.1. 기본적인 `inline` 함수 예제**
+```kotlin
+inline fun execute(block: () -> Unit) {
+ println("실행 시작")
+ block()
+ println("실행 종료")
+}
+
+fun main() {
+ execute {
+ println("실제 로직 실행")
+ }
+}
+```
+**출력 결과:**
+```
+실행 시작
+실제 로직 실행
+실행 종료
+```
+> - **함수 호출이 사라지고 코드가 그대로 복사됨 (인라이닝)**
+> - **람다를 인자로 받을 때 유용**
+> - 단점: **코드 크기가 증가할 수 있음 (작은 함수에만 사용)**
+
+---
+
+## **2. `reified` 키워드: 실행 시점에서 타입 유지**
+코틀린에서는 **제너릭 타입 정보가 실행 시점에 사라지는 문제(type erasure)가 있음**.
+하지만 `reified` 키워드를 사용하면 **실행 시점에서도 타입을 유지할 수 있음**.
+
+### **2.1. `reified` 없이 제너릭 타입 확인 불가**
+```kotlin
+fun getClassName(): String {
+ return T::class.simpleName // 오류 발생!
+}
+
+fun main() {
+ println(getClassName())
+}
+```
+> - 오류 발생! **제너릭 타입은 실행 시점에서 사라지기 때문**.
+
+### **2.2. `reified` 키워드 사용하여 해결**
+```kotlin
+inline fun getClassName(): String {
+ return T::class.simpleName ?: "알 수 없음"
+}
+
+fun main() {
+ println(getClassName()) // "String"
+ println(getClassName()) // "Int"
+}
+```
+> - **`reified`를 사용하면 실행 시점에서도 제너릭 타입을 알 수 있음**
+> - 주의: **`inline` 함수에서만 `reified` 사용 가능**
+
+---
+
+## **3. 제너릭(Generic): 타입을 유연하게 만들기**
+제너릭을 사용하면 **코드의 재사용성을 높이고, 타입 안정성을 유지할 수 있음**.
+
+### **3.1. 기본적인 제너릭 사용**
+```kotlin
+class Box(val value: T) {
+ fun get(): T = value
+}
+
+fun main() {
+ val intBox = Box(123)
+ val strBox = Box("Hello")
+
+ println(intBox.get()) // 123
+ println(strBox.get()) // Hello
+}
+```
+> - `T`를 사용하여 **어떤 타입이든 저장할 수 있는 클래스**를 정의
+
+### **3.2. 제너릭 함수 사용**
+```kotlin
+fun printItem(item: T) {
+ println("아이템: $item")
+}
+
+fun main() {
+ printItem(42) // 아이템: 42
+ printItem("코틀린") // 아이템: 코틀린
+}
+```
+> - **함수에도 제너릭 적용 가능**
+
+---
+
+## **4. 위임(Delegation) 패턴과 `by` 키워드**
+코틀린의 `by` 키워드는 **객체의 기능을 다른 객체에 위임할 때 사용**된다.
+이를 통해 **불필요한 코드 중복을 방지**할 수 있다.
+
+### **4.1. 인터페이스를 이용한 기본 위임 패턴**
+```kotlin
+interface Printer {
+ fun printMessage()
+}
+
+class ConsolePrinter : Printer {
+ override fun printMessage() {
+ println("콘솔에 출력")
+ }
+}
+
+class SmartPrinter(private val printer: Printer) : Printer {
+ override fun printMessage() {
+ println("스마트 프린터 작동 중...")
+ printer.printMessage()
+ }
+}
+
+fun main() {
+ val printer = SmartPrinter(ConsolePrinter())
+ printer.printMessage()
+}
+```
+**출력 결과:**
+```
+스마트 프린터 작동 중...
+콘솔에 출력
+```
+> - `SmartPrinter`가 `ConsolePrinter`의 기능을 **위임(Delegation)**
+
+### **4.2. `by` 키워드를 사용한 간결한 위임 패턴**
+```kotlin
+class SmartPrinter2(private val printer: Printer) : Printer by printer
+
+fun main() {
+ val printer = SmartPrinter2(ConsolePrinter())
+ printer.printMessage() // "콘솔에 출력"
+}
+```
+> - `by printer` 를 사용하면 **위임을 자동으로 처리**
+> - 코드가 훨씬 간결해짐
+
+---
+
+## **5. `by lazy`를 활용한 지연 초기화**
+`by lazy`를 사용하면 **객체를 필요할 때만 초기화**할 수 있다.
+```kotlin
+class Example {
+ val lazyValue: String by lazy {
+ println("초기화 중...")
+ "Hello, Kotlin!"
+ }
+}
+
+fun main() {
+ val example = Example()
+ println("객체 생성 완료")
+ println(example.lazyValue) // 여기서 초기화 발생
+ println(example.lazyValue) // 이미 초기화됨, 출력만 함
+}
+```
+**출력 결과:**
+```
+객체 생성 완료
+초기화 중...
+Hello, Kotlin!
+Hello, Kotlin!
+```
+> - `by lazy`는 **최초 접근 시점에만 실행됨**
+> - 이후에는 **이미 생성된 값을 사용**
+
+---
+
+## **6. `object` 키워드: 싱글톤 객체**
+코틀린에서 싱글톤 객체를 만들 때 **`object` 키워드**를 사용한다.
+```kotlin
+object Singleton {
+ fun showMessage() {
+ println("싱글톤 객체 실행!")
+ }
+}
+
+fun main() {
+ Singleton.showMessage()
+}
+```
+**출력 결과:**
+```
+싱글톤 객체 실행!
+```
+> - **별도의 인스턴스 생성 없이** `Singleton.showMessage()` 사용 가능
+> - **앱 설정, 네트워크 요청 관리 등에 유용**
+
+---
+
+## **🔹 정리: 코틀린의 특수 기능 요약**
+| 기능 | 설명 | 사용 예시 |
+|------|------|------|
+| `inline` 함수 | 함수 호출을 줄이고 성능 향상 | `inline fun execute(block: () -> Unit) {}` |
+| `reified` | 실행 시점에서도 제너릭 타입 유지 | `inline fun getType() = T::class.simpleName` |
+| 제너릭 | 코드의 재사용성과 타입 안정성 유지 | `class Box(val value: T)` |
+| Delegation | 클래스 기능을 다른 객체에 위임 | `class PrinterImpl : Printer by ConsolePrinter()` |
+| `by lazy` | 지연 초기화 | `val name: String by lazy { "코틀린" }` |
+| `object` | 싱글톤 객체 | `object Singleton {}` |
+
+코틀린의 강력한 기능들을 활용하면 **코드를 더 간결하고 효율적으로 작성**할 수 있다.
+이제 **직접 사용해보면서** 익숙해지자! 🚀
\ No newline at end of file
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 0000000..66cd266
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,55 @@
+### **코틀린 원포인트 레슨: 자바 개발자를 위한 빠른 학습서**
+#### **목차**
+
+#### **1. 코틀린 시작하기**
+1.1 코틀린의 특징과 철학
+1.2 자바 코드와의 상호운용성
+1.3 코틀린 개발 환경 설정 (IntelliJ, Gradle, Maven)
+
+#### **2. 기본 문법과 차이점**
+2.1 변수 선언: `val`과 `var`
+2.2 null 안전성: `?` 연산자와 `!!` 연산자
+2.3 타입 추론과 `is` 연산자
+
+#### **3. 함수형 프로그래밍 요소**
+3.1 함수 선언 방식 (`fun` 키워드)
+3.2 고차 함수와 람다 표현식
+3.3 확장 함수와 확장 프로퍼티
+
+#### **4. 객체지향 프로그래밍 차이점**
+4.1 클래스와 생성자 (기본, 보조 생성자)
+4.2 데이터 클래스와 자바의 `record` 비교
+4.3 객체 선언 (`object`)과 싱글턴 패턴
+4.4 `sealed class`와 `enum class`
+
+#### **5. 코틀린 컬렉션과 스트림 API**
+5.1 리스트, 맵, 셋 사용법
+5.2 `filter`, `map`, `reduce` 활용법
+5.3 자바 스트림 API와 비교
+
+#### **6. 예외 처리와 흐름 제어**
+6.1 `try-catch`와 `check` 키워드
+6.2 `when` 표현식과 자바의 `switch` 비교
+
+#### **7. 코루틴과 비동기 프로그래밍**
+7.1 `suspend` 함수와 `async/await`
+7.2 `launch`, `runBlocking`, `withContext` 개념
+
+#### **8. 코틀린의 특수 기능**
+8.1 `inline` 함수와 `crossinline`, `noinline`
+8.2 `reified` 키워드와 제네릭
+8.3 `delegation` 패턴과 `by` 키워드
+
+#### **9. 코틀린을 활용한 실제 개발**
+9.1 Spring Boot에서 코틀린 활용하기
+9.2 Android 개발에서 코틀린 적용하기
+9.3 Kotlin DSL과 Gradle 설정
+
+#### **10. 자바에서 코틀린으로 마이그레이션**
+10.1 코틀린으로 코드 변환 (IntelliJ 기능 활용)
+10.2 자바-코틀린 혼용 프로젝트 관리
+10.3 코틀린 도입 시 고려할 점
+
+---
+
+이 책의 핵심은 자바 개발자가 코틀린을 빠르게 이해하고 실무에서 바로 활용할 수 있도록 짧고 명확한 레슨으로 구성하는 것입니다. 추가하고 싶은 내용이 있으면 말해줘!
\ No newline at end of file