From b7f48dd9ab611a6523b2a4204f6c86e631c04785 Mon Sep 17 00:00:00 2001
From: "[jina4066]" <[jina4066@naver.com]>
Date: Tue, 26 Sep 2023 19:53:49 +0900
Subject: [PATCH 1/9] =?UTF-8?q?[1=EC=A3=BC=EC=B0=A8]=20=EA=B9=80=EC=A7=80?=
=?UTF-8?q?=EB=82=98=20=ED=95=99=EC=8A=B5=20PR=20=EC=A0=9C=EC=B6=9C?=
=?UTF-8?q?=ED=95=A9=EB=8B=88=EB=8B=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
"week01/1\354\243\274\354\260\250.md" | 30 ---
.../\352\271\200\354\247\200\353\202\230.md" | 172 ++++++++++++++++++
2 files changed, 172 insertions(+), 30 deletions(-)
delete mode 100644 "week01/1\354\243\274\354\260\250.md"
create mode 100644 "week01/\352\271\200\354\247\200\353\202\230.md"
diff --git "a/week01/1\354\243\274\354\260\250.md" "b/week01/1\354\243\274\354\260\250.md"
deleted file mode 100644
index 95ebbae..0000000
--- "a/week01/1\354\243\274\354\260\250.md"
+++ /dev/null
@@ -1,30 +0,0 @@
-## COW SPRING 2기 PRE-ONBOARDING 학습 과제
-
-### 자바의 필수 개념들을 차근차근 살펴보자.
-
-* 자바의 primitive Type과 Reference Type은 어떤 차이가 있나요?
-
-
-* 자바의 접근 제어자에 대해 설명해주세요.
-
-
-* static 키워드에 대해 설명해주세요.
-
-
-* final 키워드에 대해 설명해주세요.
- * ++ 상속 관련된 내용도 포함할 것!
-
-* 오버로딩(Overloading)과 오버라이딩(Overriding)에 대해 설명해주세요.
-
-
-* 추상 클래스와 인터페이스는 각각 무엇이고, 어떤 차이를 가지는지 설명해주세요
- * 반드시 추상 클래스와 인터페이스의 사용 목적을 명시해주세요.
-
-
-* Java Enum에 대해 설명해주세요.
-
-
-* 객체지향이란 무엇일까요? 객체지향을 지키면 어떤 이점을 얻을 수 있나요?
-
-
-* 자바 객체지향의 4대 특성에 대해 각각 설명해주세요.
\ No newline at end of file
diff --git "a/week01/\352\271\200\354\247\200\353\202\230.md" "b/week01/\352\271\200\354\247\200\353\202\230.md"
new file mode 100644
index 0000000..2d54b20
--- /dev/null
+++ "b/week01/\352\271\200\354\247\200\353\202\230.md"
@@ -0,0 +1,172 @@
+## COW SPRING 2기 PRE-ONBOARDING 학습 과제
+
+### 자바의 필수 개념들을 차근차근 살펴보자.
+
+* 자바의 primitive Type과 Reference Type은 어떤 차이가 있나요?
+
+ - 타입(Data Type)이란?
+ - 해당 데이터가 메모리에 어떻게 저장되고, 프로그램에서 어떻게 처리되어야 하는지를 명시적으로 알려주는 것이다.
+ - 자바에서 타입을 크게 `기본형 타입`과 `참조형 타입`이 있다.
+
+ - **기본형 타입(Primitive type)**
+ - 총 8가지의 기본형 타입을 미리 정의하여 제공한다.
+ - 기본값이 있기 때문에 Null이 존재하지 않는다. 만약 기본형 타입에 Null을 넣고 싶다면 래퍼 클래스를 활용한다
+ - **실제 값**을 저장하는 공간으로 **스택(Stack)** 메모리에 저장된다.
+ - 컴파일 시점에 담을 수 있는 크기를 벗어나면 에러를 발생시키는 `컴파일 에러`가 발생한다.
+ - 타입 종류: boolean, int, double, char 등
+
+ - **참조형 타입(Reference type)**
+ - 기본형 타입을 제외한 모든 타입
+ - 빈 객체를 의미하는 Null이 존재
+ - 값이 저장되어 있는 곳의 **주소값**을 저장하는 공간으로 **힙(Heap)** 메모리에 저장된다.
+ - 문법상으로는 에러가 없지만 실행시켰을 때 에러가 나는 `런타임 에러` 발생.
+ _(예를 들어 객체나 배열을 Null 값으로 받으면 NullPointException이 발생 -> 변수값을 넣어야 한다.)_
+ - 타입 종류: 배열(Array), 열거(Enumeration), 클래스(Class), 인터페이스(Interface)
+
+
+
+* 자바의 접근 제어자에 대해 설명해주세요.
+ - 제어자(modifier)란
+ - 클래스와 클레스 멤버의 선언 시 사용하여 부가적인 의미를 부여하는 키워드를 말한다.
+ - 접근 제어자(access modifier)와 기타 제어자로 구분할 수 있다.
+ - 접근 제어자(access modifier)
+ - 접근 제어자를 사용하여 클래스 외부에서의 직접적인 접근을 허용하지 않는 멤버를 설정하여 정보 은닉을 구체화할 수 있다.
+ 1. private
+ - private 접근 제어자를 사용하여 선언된 클래스 멤버는 외부에 공개되지 않으며, 외부에서는 직접 접근할 수 없다.
+ - private 멤버는 해당 멤버를 선언한 클래스에서만 접근 가능
+
+ 2. public 접근 제어자
+ - public 접근 제어자를 사용하여 선언된 클래스 멤버는 외부로 공개되며, 해당 객체를 사용하는 프로그램 어디에서나 직접 접근할 수 있다.
+ - 자바 프로그램은 public 메소드를 통해서만 해당 객체의 private 멤버에 접근할 수 있다.
+ - 즉, public 메소드는 private 멤버와 프로그램 사이의 인터페이스(interface) 역할을 수행한다고 할 수 있다.
+
+ 3. default 접근 제어
+ - 자바에서는 클래스 및 클래스 멤버의 접근 제어 기본값으로 default 접근 제어를 별도로 명시하고 있다.
+ - 이러한 default를 위한 접근 제어자는 따로 존재하지 않으며, 접근 제어자가 지정되지 않으면 자동적으로 default 접근 제어를 가지게 된다.
+ - default 접근 제어를 가지는 멤버는 같은 클래스의 멤버와 같은 패키지에 속하는 멤버에서만 접근할 수 있다.
+
+ 4. protected 접근 제어자
+ - protected 멤버는 부모 클래스에 대해서는 public 멤버처럼 취급되며, 외부에서는 private 멤버처럼 취급된다.
+ - 즉, 같은 패키지에 속하는 클래스와 다른 패키지에 속하는 자식 클래스에서만 접근할 수 있다.
+ - 클래스의 protected 멤버에 접근할 수 있는 영역
+ 1. 이 멤버를 선언한 클래스의 멤버
+ 2. 이 멤버를 선언한 클래스가 속한 패키지의 멤버
+ 3. 이 멤버를 선언한 클래스를 상속받은 자식 클래스의 멤버
+
+
+
+* static 키워드에 대해 설명해주세요.
+ - Java에서 Static 키워드를 사용한다는 것은 메모리에 한번 할당되어 프로그램이 종료될 때 해제되는 것을 의미한다
+
+ - 일반적으로 만든 Class -> Static 영역에 생성 / new 연산으로 생성한 객체 -> Heap 영역에 생성
+ - 객체의 생성시에 할당된 Heap 영역의 메모리는 Garbage Collector를 통해 수시로 관리를 받는다.
+ - Static 영역에 할당된 메모리는 모든 객체가 공유하는 메모리라는 장점을 갖는다.
+ - 하지만 Garbage Collector의 관리 영역 밖에 존재하므로 Static을 자주 사용하면 프로그램의 종료시까지 메모리가 할당된 채로 존재
+ -> 자주 사용하게 되면 시스템의 퍼포먼스에 악영향을 주게 된다.
+
+
+* final 키워드에 대해 설명해주세요.
+ * ++ 상속 관련된 내용도 포함할 것!
+ - final은 오직 한 번만 할당할 수 있는 entity를 정의할 때 사용된다.
+ - final 변수가 객체를 참조하고 있다면, 그 객체의 상태가 바뀌어도 final 변수는 매번 동일한 내용을 참조한다.
+
+ - final 클래스
+ - final이 붙어있는 클래스는 상속할 수 없다. -> 보안이나 효율성 측면에서 장점을 갖게된다.
+ - java.lang.System이나 java.lang.String 처럼 자바에서 기본적으로 제공하는 라이브러리 클래스는 final을 사용한다.
+
+ - final 메서드
+ - 어떤 클래스를 상속하는데 그 안에 final 메서드가 있다면, 오버라이딩으로 수정할 수 없다.
+
+ - final 변수
+ - final 변수는 한 번 값을 할당하면 수정할 수 없다.
+ - 즉, 초기화는 한 번만 가능하다
+
+
+* 오버로딩(Overloading)과 오버라이딩(Overriding)에 대해 설명해주세요.
+
+ - 오버로딩(Overloading)
+ - 자바의 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메소드가 있더라도
+ 매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메소드를 정의할 수 있다.
+ - 조건: 메소드의 이름이 같고, 매개변수의 개수나 타입이 달라야 한다.
+ - 주의할 점: 주의할 점은 '리턴 값만' 다른 것은 오버로딩을 할 수 없다.
+ - 사용하는 이유
+ 1. 같은 기능을 하는 메소드를 하나의 이름으로 사용할 수 있다.
+ 2. 메소드의 이름을 절약할 수 있다
+
+
+ - 오버라이딩(Overriding)
+ - 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재정의하는 것을 의미한다.
+ - 상속받은 메소드를 그대로 사용할 수도 있지만, 자식 클래스에서 상황에 맞게 변경해야하는 경우 오버라이딩할 필요가 생긴다.
+ - 조건: 오버라이딩은 부모 클래스의 메소드를 재정의하는 것이므로, 자식 클래스에서는 **오버라이딩하고자 하는 메소드의 이름, 매개변수, 리턴 값이 모두 같아야 한다**.
+ - 접근 제어자를 설정하는 규칙
+ 1. 자식 클래스에서 오버라이딩하는 메소드의 접근 제어자는 부모 클래스보다 더 좁게 설정할 수 없다.
+ 2. 예외(Exception)는 부모 클래스의 메소드 보다 많이 선언할 수 없다.
+ 3. static메소드를 인스턴스의 메소드로 또는 그 반대로 바꿀 수 없다.
+
+ -참고 링크: https://hyoje420.tistory.com/14
+
+
+* 추상 클래스와 인터페이스는 각각 무엇이고, 어떤 차이를 가지는지 설명해주세요
+ * 반드시 추상 클래스와 인터페이스의 사용 목적을 명시해주세요.
+
+ - 추상 클래스
+ - 일반 클래스와 크게 다르지 않다
+ - 단지, 추상 메서드를 선언하여 상속을 통해 자손 클래스에서 완성하도록 유도하는 클래스이다.
+ - 사용 목적: 상속을 위한 클래스
+ -> 따로 객체를 생성할 수 없음
+ - 클래스 앞에 'abstract'라는 예약어를 사용
+
+ - 인터페이스
+ - 추상 클래스가 미완성 설계도라면 인터페이스는 기본 설계도라고 할 수 있다.
+ - 추상클래스처럼 다른 클래스를 작성하는 데에 도움을 주는 목적으로 작성하고, 클래스와 다르게 다중상속(구현)이 가능하다
+
+
+
+* Java Enum에 대해 설명해주세요.
+ - 자바에서는 `enum` 키워드를 사용하여 열거를 정의할 수 있다.
+ - 사용예시
+ `enum Day {
+ MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, STURDAY, SUNDAY;
+ }`
+ - 장점
+ - 코드가 단순해지며 가독성이 좋아진다.
+ - 키워드 enum 을 사용함으로써 구현의 의도가 열거임을 분명하게 나타낼 수 있다.
+ - 자체 클래스 상수와 달리 switch 문에서도 사용할 수 있다.
+ - 단순 상수와 비교되는 자동완성, 오타검증, 텍스트 리팩토링 등의 IDE 지원을 받을 수 있다.
+
+
+
+* 객체지향이란 무엇일까요? 객체지향을 지키면 어떤 이점을 얻을 수 있나요?
+
+ - 객체지향이란, 프로그래밍에서 필요한 데이터를 추상화 시켜 **상태와 행위를 가진 객체**로 만들고,
+ 객체들간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
+
+ - 객체지향의 이점
+ - 코드의 재사용성이 높다
+ - 상속을 통해 불필요한 코드의 중복을 제거하고, 쉽고 빠르게 설계할 수 있다.
+
+ - 유지보수가 용이하다.
+ - 기존 기능을 수정할 때, 캡슐화에 의해 주변에 미치는 영향을 최소화할 수 있다.
+ - 새 기능을 추가할 때, 상속을 통해 기존의 기능을 활용할 수 있다.
+
+ - 디버깅이 쉽다.
+
+
+* 자바 객체지향의 4대 특성에 대해 각각 설명해주세요.
+ 1. 추상화
+ - 객체에서 공통된 속성과 행위를 추출하는 것
+ - 공통의 속성과 행위를 찾아서 타입을 정의하는 과정
+ - 추상화는 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 프로그램을 간단하게 만드는 것
+
+ 2. 캡슐화
+ - 데이터 구조와 데이터를 다루는 방법들을 결합 시켜 묶는 것 (변수와 함수를 하나로 묶는 것을 뜻함)
+ - 낮은 결합도를 유지할 수 있도록 설계하는 것
+
+ 3. 상속
+ - 클래스의 속성과 행위를 하위 클래스에 물려주거나 하위 클래스가 상위 클래스의 속성과 행위를 물려받는 것을 말한다
+ - 새로운 클래스가 기존의 클래스의 데이터와 연산을 이용할 수 있게 하는 기능
+
+ 4. 다형성
+ - 하나의 변수명, 함수명이 상황에 따라 다른 의미로 해석 될 수 있는 것
+ - 어떠한 요소에 여러 개념을 넣어 놓는 것
+ - 객체 지향 프로그래밍은 하나의 클래스 내부에 같은 이름의 행위를 여러개 정의하거나 상위 클래스의 행위를 하위 클래스에서 재정의하여 사용할 수 있기 때문에 다형성이라는 특징을 갖게 된다.
\ No newline at end of file
From 8c838094d095111ed59052ed498ccd9297e1f0c7 Mon Sep 17 00:00:00 2001
From: "[jina4066]" <[jina4066@naver.com]>
Date: Tue, 3 Oct 2023 23:27:01 +0900
Subject: [PATCH 2/9] =?UTF-8?q?2=EC=A3=BC=EC=B0=A8=20=ED=95=99=EC=8A=B5=20?=
=?UTF-8?q?PR=20=EB=93=B1=EB=A1=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../\352\271\200\354\247\200\353\202\230.md" | 40 +++++++++++++++++++
1 file changed, 40 insertions(+)
create mode 100644 "week02/\352\271\200\354\247\200\353\202\230.md"
diff --git "a/week02/\352\271\200\354\247\200\353\202\230.md" "b/week02/\352\271\200\354\247\200\353\202\230.md"
new file mode 100644
index 0000000..5e0343c
--- /dev/null
+++ "b/week02/\352\271\200\354\247\200\353\202\230.md"
@@ -0,0 +1,40 @@
+### 2주차 학습 PR
+
+- 요구사항 정의
+ 1. 추첨 결과 출력
+ - 수익률 출력 (수익률 = 당첨 금액 / 구입 금액)
+ 2. 추첨
+ - 숫자랑 위치 일치하는지 확인
+ - 보너스볼 확인
+ 3. 보너스 번호 입력
+ - 숫자는 1 ~ 45
+ - (error) 당첨 번호와 중복 불가
+ 4. 당첨 번호 입력
+ - 6개 숫자 입력 (ex: 1, 2, 3)
+ - 숫자는 1 ~ 45
+ - 입력 구분자는 ,
+ - (error) 중복된 숫자 불가
+ 5. 로또 목록
+ - 로또 생성
+ - 숫자는 1 ~ 45
+ - (error) 중복된 숫자 불가
+ - Collections.shuffle() 활용
+ - 목록 출력
+ - 로또 숫자 정렬
+ 6. 구매한 로또 개수 출력
+ 7. 로또 구입 금액
+ - 로또 가격은 1000원
+ - (error) 1000원 단위 외의 금액 불가
+ - (error) 문자열 입력
+ - 구매 로또 개수 구하기 (입력받은 금액 / 1000)
+
+- 구현에 대한 고민
+ - 하나의 클래스가 하나의 책임을 가지도록 하고 싶은데 어디까지 쪼개고 나눠야 할 지 감이 잘 안 잡힌다.
+ - 예를 들면, 로또 금액 입력받는 클래스, 발행된 로또들을 관리하는 클래스 같이 하나하나 쪼개면 너무 클래스들이 많아질 것 같아 고민이 된다..
+
+- LottoManager와 LottoGenerator의 책임 분리가 조금 어려웠다. 로또 숫자 생성과 저장 및 관리를 같이하게 되면 단일책임의 원칙에 어긋날 것 같아 클래스를 분리해봤는데, 또 한편으로는 비슷한 기능이라 하나의 클래스 내에서 메소드로 구현해도 괜찮지 않을까 하는 생각도 들었다.
+- `WARNING: An illegal reflective access operation has occurred` 이란 경고문구 발생
+ - `--illegal-access=deny` 이라는 jvm 옵션을 추가해 일단은 경고문구가 뜨지 않게 했으나, `unable to determine if the scanner is closed.`이라는 경고문구가 다시 추가되었다..
+ - 라이브러리의 업데이트를 받아와야 하는지,, 일단은 프로그램 정상 동작이 최우선 목표였기에 넘어갔다.
+- LottoGenerator 클래스의 generateLotto메서드에서 구매한 로또 장 수 만큼 로또를 발행하게끔 구현했는데, 후에 이를 Lottomanager클래스에서 발행된 로또를 관리하게끔 메서드를 끌어와 사용하다보니 에러가 발생했다.. 너무 클래스간 관계가 복잡해진것 같다..
+- 또한 LottoResult 부분은 로또 당첨번호와 구입한 번호들을 비교하여 통계를 내는 마지막 단계인데, 워낙 클래스도 많고 비슷한 변수도 많다보니 결국 꼬여버린 것 같다. 어떻게든 동작되게끔 하려 했지만 그보다는 다시 클래스간 관계를 정의하고 정리된 상태에서 다시 코드를 짜보는게 맞는 것 같다는 생각을 했다.
\ No newline at end of file
From f22200c06fdc0f3148e7191e60b842d489fe542d Mon Sep 17 00:00:00 2001
From: "[jina4066]" <[jina4066@naver.com]>
Date: Tue, 10 Oct 2023 21:47:49 +0900
Subject: [PATCH 3/9] =?UTF-8?q?docs=20:=203=EC=A3=BC=EC=B0=A8=20README=20?=
=?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
"week03/3\354\243\274\354\260\250.md" | 334 +++++++++++++++++++++++---
1 file changed, 306 insertions(+), 28 deletions(-)
diff --git "a/week03/3\354\243\274\354\260\250.md" "b/week03/3\354\243\274\354\260\250.md"
index f19c798..1bf35b9 100644
--- "a/week03/3\354\243\274\354\260\250.md"
+++ "b/week03/3\354\243\274\354\260\250.md"
@@ -1,45 +1,323 @@
-# 3주차 학습 PR
-학습 PR 역시 로또 리팩토링에 도움이 되는 내용들로 구성되어 있습니다.
-해당 개념들을 학습한 뒤, 본인의 로또 코드에 적용까지 해 보신다면..? 비로소 본인 것이 됩니다 ㅎㅎ
+# [카우 3주차]
-아래 `*` 은 여러분들의 학습을 위한 **최소한의** 가이드라인입니다.
-꼭 깊이있는 학습 후에 꼼꼼하게 기록해주세요💯
+---
-## 일급 컬렉션이란?
+**3주차 학습 PR**
-* 일급 컬렉션이란?
+학습 PR 역시 로또 리팩토링에 도움이 되는 내용들로 구성되어 있습니다. 해당 개념들을 학습한 뒤, 본인의 로또 코드에 적용까지 해 보신다면..? 비로소 본인 것이 됩니다 ㅎㅎ
-* 일급 컬렉션은 왜 사용하는가? 어떤 장점이 있는지?
+아래 `*` 은 여러분들의 학습을 위한 **최소한의** 가이드라인입니다. 꼭 깊이있는 학습 후에 꼼꼼하게 기록해주세요💯
-+ 불변 객체..방어적 복사도 함께 찾아보시면 좋을 것 같아요!
-+ https://tecoble.techcourse.co.kr/post/2021-04-26-defensive-copy-vs-unmodifiable/
+## **일급 컬렉션이란?**
-## MVC 패턴이란?
-
+- 일급 컬렉션이란?
+ - Java에서 일급 컬렉션(First-Class Collection)은 다른 객체와 동등한 지위를 갖는 컬렉션 객체
+ - 특징
+ - 컬렉션 객체는 변수나 매개변수에 할당할 수 있다.
+ - 컬렉션 객체는 다른 객체와 동등한 지위를 가진다.
+ - 컬렉션 객체는 반환값으로 사용할 수 있다.
+ - 컬렉션 객체는 필요한 경우 메서드에서 생성할 수 있다.
-* MVC는 왜 사용하는지?
+
-## Java의 Stream이란?
+ - 일급 컬렉션을 사용하지 않은 코드
-* Stream의 특징? 장점?
- * 병렬 처리
- * 작업 분류
- * lazy Evaluation
- * 내부 반복 방식
- * for문과의 차이점?
+ ```jsx
+ public class Student {
+ private List subjects;
+
+ public Student(List subjects) {
+ this.subjects = subjects;
+ }
+
+ public List getSubjects() {
+ return subjects;
+ }
+ }
+ ```
-* 중간 연산 메서드
+ 위 코드 중 Student 클래스에서 List 타입의 subjects를 직접 다루고 있다. 이 경우 Student 클래스는 List 타입에 의존성을 갖게 되며, List의 구현이 변경될 경우 Student 클래스도 함께 변경되어야 하는 문제점을 가지고 있다.
-* 최종 연산 메서드
-## 제네릭이란?
+ - 일급 컬렉션을 사용한 코드
+ ```jsx
+ public class Student {
+ private Subjects subjects;
+
+ public Student(Subjects subjects) {
+ this.subjects = subjects;
+ }
+
+ public Subjects getSubjects() {
+ return subjects;
+ }
+ }
+
+ public class Subjects {
+ private List subjects;
+
+ public Subjects(List subjects) {
+ this.subjects = subjects;
+ }
+
+ public void addSubject(String subject) {
+ subjects.add(subject);
+ }
+
+ public List getSubjects() {
+ return new ArrayList<>(subjects);
+ }
+ }
+ ```
-## Optional이란?
+ 위 코드에서는 Student 클래스에서 Subjects 클래스를 사용하도록 변경되었다. Subjects 클래스는 List타입의 Subjects를 감싸고 있으며, Subject 객체를 추가하거나, 모든 Subject 객체를 가져올 수 있도록 메서드를 제공한다.
+ -
+ 이렇게 함으로써, Student 클래스는 Subjects 클래스랑만 의존성을 갖게 되고 이전에 지녔던 문제점인 List타입에 대한 의존성을 제거할 수 있다.
+- 일급 컬렉션은 왜 사용하는가? 어떤 장점이 있는지?
-## References
-
-*
\ No newline at end of file
+ 1. 가독성과 유지보수성이 향상된다.
+
+ 일급컬렉션을 사용하면 해당 컬렉션을 사용하는 클래스에서 해당 컬렉션의 역할과 의미를 바로 파악할 수 있고, 유지보수성이 향상된다.
+
+ 1. 유효성 검증이 용이해진다.
+
+ 일급 컬렉션을 사용하면 해당 컬렉션의 내부 구현을 캡슐화할 수 있기 때문에 유효성 검증 코드를 해당 컬렉션 클래스 내부에 구현하여 컬렉션의 사용자들이 해당 유효성 검증 로직을 호출하는 번거로움을 줄일 수 있다.
+
+ 2. 불변성을 보장할 수 있다.
+
+ 일급 컬렉션을 사용하면 해당 컬렉션을 불변(immutable)으로 만들어서 변경을 방지할 수 있다.
+
+- 불변 객체..방어적 복사도 함께 찾아보시면 좋을 것 같아요!
+- [https://tecoble.techcourse.co.kr/post/2021-04-26-defensive-copy-vs-unmodifiable/](https://tecoble.techcourse.co.kr/post/2021-04-26-defensive-copy-vs-unmodifiable/)
+
+## **MVC 패턴이란?**
+
+- MVC는 왜 사용하는지?
+ - Intro
+ - 스프링 프레임워크의 모듈 중에는 웹 계층을 담당하는 몇 가지 모듈이 있다. 웹 계층에 서블릿(Servlet) API를 기반으로 클라이언트의 요청을 처리하는 모듈이 있는데 이를 **스프링 웹 MVC** 라고 한다.
+ - 서블릿(Servlet)이란?
+ - 클라이언트의 요청을 처리하도록 특정 규약에 맞춰 Java 코드로 작성하는 클래스 파일이다.
+ - **아파치 톰캣(Apache Tomcat)**은 이러한 서블릿들이 웹 애플리케이션으로 실행할 수 있도록 해주는 서블릿 컨테이너(Servlet Container) 중 하나이다.
+ - Spring MVC 내부에서는 서블릿을 기반으로 웹 애플리케이션을 동작하며, 스프링 부트는 기본적으로 아파치 톰캣이 내장되어 있다.
+ - MVC란?
+
+ MVC 패턴은 애플리케이션을 개발할 때 사용하는 디자인 패턴이다.
+
+ 애플리케이션의 개발 영역을 MVC(Model, View, Controller)로 구분하여 각 역할에 맞게 코드를 작성하는 개발 방식이다.
+
+ MVC 패턴을 도입하면서 UI 영역과 도메인(비즈니스 로직) 영역으로 구분되어 서로에게 영향을 주지 않으면서 개발과 유지보수가 가능해지게 되었다.
+
+ ![[출처: 인프런 김영한 강의]](%5B%E1%84%8F%E1%85%A1%E1%84%8B%E1%85%AE%203%E1%84%8C%E1%85%AE%E1%84%8E%E1%85%A1%5D%2013426a9837e040c1bb5d8e3db912cf43/Untitled.png)
+
+ [출처: 인프런 김영한 강의]
+
+ - Model(모델)
+
+ > 데이터(data) 가공을 책임지는 컴포넌트(component)
+ >
+
+ 모델은 어플리케이션의 정보, 데이터를 나타냅니다. 데이타베이스, 초기화 된 상수나 값, 변수 등을 뜻합니다. 비즈니스 로직을 처리한 후 모델의 변경 사항을 컨트롤러와 뷰에 전달합니다.
+
+ 모델은 다음과 같은 규칙을 가지고 있습니다.
+
+ - 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야 합니다.
+ - 뷰나 컨트롤러에 대해서 어떤 정보도 알지 말아야 합니다.
+ - 변경이 일어나면, 변경 통지에 대한 처리 방법을 구현해야만 합니다.
+
+ - View(뷰)
+
+ > *사용자에게 보여지는 부분, 즉 유저 인터페이스(User interface)*
+ >
+
+ MVC 패턴은 여러 개의 뷰가 존재할 수 있으며, Model에게 데이터를 전달받는다.
+
+ View는 받은 데이터를 화면에 표시해주는 역할을 가지고 있다. 모델에게 전달받은 데이터를 별도로 저장하지 않아야 한다. 사용자가 화면에 표시된 내용을 변경하게 되면 모델에게 전달하여 모델을 변경해야 합니다.
+
+ 뷰는 다음과 같은 규칙을 가지고 있습니다.
+
+ - 모델이 가지고 있는 정보를 따로 저장해서는 안됩니다.
+ - 모델이나 컨트롤러와 같이 다른 구성 요소들을 몰라야 됩니다.
+ - 변경이 일어나면 변경통지에 대한 처리방법을 구현해야만 합니다.
+
+ View는 Model을 이용하여 웹 브라우저와 같은 애플리케이션의 화면에 보이는 리소스(Resource)를 제공하는 역할을 한다.
+
+ 스프링 MVC에서 “View”는 사용자에게 표시되는 UI부분이다. 이는 데이터를 사용자에게 시각적으로 제공하도록 설계된 컴포넌트로, 일반적으로 HTML 형식으로 브라우저에 표시된다.
+
+ 그러나 “View”는 HTML만 한정되는 것은 아니며, JSON, XML 등 다른 형식으로도 데이터를 제공할 수 있다.
+
+ - Controller(컨트롤러)
+
+ > 모델과 뷰 사이를 이어주는 브릿지(bridge) 역할
+ >
+
+ 모델이나 뷰는 서로의 존재를 모르고 있다. 변경 사항을 외부로 알리고 수신하는 방법만 있는데, 컨트롤러는 이를 중재하기 위한 컴포넌트다.
+
+ 모델과 뷰에 대해 알고 있으며, 모델이나 뷰로부터 변경 내용을 통지 받으면 이를 각 구성 요소에게 통지한다. 사용자가 어플리케이션을 조작하여 발생하는 변경 이벤트들을 처리하는 역할을 수행한다.
+
+ 컨트롤러는 다음과 같은 규칙을 가지고 있다.
+
+ - 모델이나 뷰에 대해서 알고 있어야 한다.
+ - 모델이나 뷰의 변경을 모니터링 해야 한다.
+
+- MVC 패턴은 왜 등장했는가? 등장 배경?
+ - 초기
+
+ MVC 패턴을 적용하지 않고 서블릿만을 사용하여 상품 등록 뷰를 클라이언트에게 전달하기 위해서는 Response Body에 직접 HTML를 작성하여 응답해야 한다.
+
+ HTML을 직접 개발자가 작성하면 생산성이 매우 떨어진다. 이로인해 HTML과 유사한 JSP가 나타난다.
+
+ - JSP의 등장
+
+ 동적인 결과를 나타내기위해 HTML의 필요한 곳에 자바 코드를 작성하려는 시도가 있었고 그 결과 **JSP**가 탄생하였다. JSP를 사용하면 손쉽게 HTML을 작성할 수 있고 필요에 따라 자바 코드를 작성하여 클라이언트의 동적인 요청을 처리할 수 있다.
+
+ JSP에 자바 코드를 작성하면 HTML 형식의 데이터를 손쉽게 작성할 수 있고, 서블릿은 단순히 요청이 들어오면 해당 서블릿에 렌더링만 해주면된다. 서블릿만 사용했을 때보다는 많이 발전했지만 문제는 여전히 존재한다.
+
+ JSP에 너무 많은 책임이 부여된다. JSP에는 비즈니스 로직과 뷰에 대한 책임이 혼재한다. 비즈니스 로직을 수정 했을 때, 뷰에 대한 수정이 필요할 때 모두 JSP 코드를 수정해야한다. 그리고 결정적으로
+
+ **비즈니스 로직과 뷰는 변경의 라이프 사이클이 다르다.**
+
+ 즉 비즈니스 로직의 변경 시기와 뷰의 변경 시기가 서로 다르다는 것이다. 보통 변경의 라이프 사이클이 다를 경우 역할을 분리해주는 것이 좋다.
+
+ - MVC 패턴의 등장
+
+ MVC 패턴은 이전에 JSP나 서블릿으로만 처리했던 과정을 모델-뷰-컨트롤러로 역할을 나누는 것을 의미한다.
+
+
+## **Java의 Stream이란?**
+
+- Stream의 특징? 장점?
+ - 기존 루프문 처리의 문제점
+
+ 기존 Java에서 컬렉션 데이터를 처리할때는 for, foreach 루프문을 사용하면서 컬렉션 내의 요소들을 하나씩 다루었다. 간단한 처리나 컬렉션의 크기가 작으면 큰 문제가 아니지만 복잡한 처리가 필요하거나 컬렉션의 크기가 커지면 루프문의 사용은 성능저하를 일으키게 되었다.
+
+ - 스트림의 등장
+
+ 스트림은 Java8에서 추가된 기능으로 컬렉션 데이터를 선언형으로 쉽게 처리할수 있다. 복잡한 루프문을 사용하지 않아도 되며 루프문을 중첩해서 사용해야 되는 최악의 경우도 더 이상 없어졌다.
+
+ - 병렬 처리
+
+ **외부 반복자(`external iterator`)**란 **개발자가 코드로 직접 컬렉션의 요소를 반복해서 가져오는 코드 패턴**이다. index를 이용하는 for문, 그리고 Iterator를 이용하는 while문은 모두 외부 반복자를 이용하는 것이다.
+
+ 반대로 **내부 반복자(iternal iterator)**란 **컬렉션 내부에서 요소들을 반복시키고, 개발자는 요소 당 처리해야 할 코드만 제공하는 코드 패턴**을 말한다.
+
+ 
+
+ - 내부 반복자를 사용했을 때의 이점
+
+ 내부 반복자를 사용하면 컬렉션 내부에서 어떻게 요소를 반복시킬 것인가는 컬렉션에게 맡겨두고, **개발자는 요소 처리 코드에만 집중할 수 있게 된다.** 내부 반복자는 요소들의 반복 순서를 변경하거나, 멀티 코어 CPU를 최대한 활용하기 위해 요소들을 분배시켜 병렬 작업을 할 수 있게 도와주기 때문에 **하나씩 처리하는 순차적 외부 반복자보다는 효율적으로 요소를 반복시킬 수 있다.**
+
+
+ **Iterator**는 **컬렉션의 요소를 가져오는 것에서부터 처리하는 것까지 모두 개발자가 작성**해야 하지만,**스트림**은 람다식으로 요소 처리 내용만 전달할 뿐, **반복은 컬렉션 내부에서 일어난다.**
+
+ 스트림을 이용하면 **코드도 간결**해지지만, 무엇보다도 **요소의 병렬 처리가 컬렉션 내부에서 처리**된다는 효과까지 있다.
+
+
+
+ - 작업 분류
+ - 중간 연산
+ - 연산결과가 스트림을 반환하기 때문에 스트림에 연속해서 중간 연산을 할 수 있다. (0 ~ n번)
+ - 최종 연산
+ - 연산 결과가 스트림이 아닌 연산으로, 스트림의 요소를 소모하기 때문에 마지막에 단 한번만 사용이 가능하다. (0~1번)
+
+ ```jsx
+ stream.distinct().limit(5).sorted().forEach(System.out::println);
+ // distinct(), limit(), sorted() -> 중간 연산
+ // 마지막 스트림을 소모하여 각 스트림의 요소를 출력하는 forEach -> 최종 연산
+ ```
+
+ - lazy Evaluation (지연된 연산)
+ - 스트림에서 연산을 할때 한 가지 중요한 점은, 최종 연산이 수행되기 전까지는 중간 연산이 수행 되지 않는다는 점이다.
+ - 위 코드에서 distinct()나 sorted()같은 중간 연산을 호출한다고 해도 즉각적인 연산이 시행되는 것이 아니다. 중간 연산을 호출하는 것은 단지 어떤 작업이 수행되어야 하는지를 지정해주는 것일 뿐이다.
+ - **최종 연산이 수행 될때야 비로소 스트림의 요소들이 중간 연산이 수행된다.**
+
+ - 내부 반복 방식
+ - 외부 반복
+ - 사용자가 직접 요소를 반복
+ - 내부 반복
+ - 스트림은 반복을 알아서 처리하고 결과 스트림값을 어딘가에 저장
+ - 장점: 작업을 투명하게 병렬적으로 처리하거나 최적화된 다양한 순서로 처리가 가능하다.
+ - for문과의 차이점?
+- 중간 연산 메서드
+ - ****filter() / distinct()****
+ - filter()
+ - Stream에서 조건에 맞는 데이터만을 정제하여 더 작은 컬렉션을 만드는 데 사용한다. 매개 값으로 조건이 주어지며, 참이 되는 요소만을 필터링한다.
+ - distinct()
+ - Stream 요소들의 중복된 데이터를 제거하기 위해 사용한다.
+ - ****map() / flatMap()****
+ - map()
+ - 기존의 Stream 요소들을 대체하는 요소로 구성된 새로운 Stream을 형성하는 연산이다. 저장된 값을 특정한 형태로 변환하는 데 주로 사용된다.
+ - flatMap()
+ - 여러 개의 요소들로 구성된 새로운 스트림을 반환한다.
+ - sorted()
+ - Stream의 요소들을 정렬하기 위해 사용한다. sorted() 메서드는 파라미터로 Comparator를 넘길 수 있다.
+
+ 만약, 파라미터의 인자 없이 호출할 경우에는 오름차순 정렬을 한다.
+
+ 내림차순 정렬을 하기 위해서는 Comparator의 `reverseOrder(`) 메서드를 이용한다.
+
+ - ****limit()****
+ - 스트림에서 입력 값의 숫자만큼 요소들을 가져와 새로운 스트림을 생성한다.
+ - ****peek()****
+ - 요소를 하나씩 돌면서 출력하는 기능이다.
+ - 중간 연산이므로 하나의 스트림에 여러 번 사용이 가능하다.
+- 최종 연산 메서드
+ - ****forEach()****
+ - 요소를 하나씩 돌면서 출력하는 기능이다.
+ - 스트림의 요소를 소모하기 때문에 한 번만 호출할 수 있다.
+ - match()
+ 1. allMatch() : 모든 요소들이 매개 값으로 주어진 Predicate의 조건 검사
+ 2. anyMatch() : 최소한 한 개의 요소가 매개 값으로 주어진 Predicate의 조건 검사
+ 3. noneMatch() : 모든 요소들이 매개 값으로 주어진 Predicate의 만족하지 않는 조건 검사
+ - ****sum(), count(), average(), max(), min()****
+ - 집계에 대한 메서드
+
+## **제네릭이란?**
+
+**클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법**을 의미한다.
+
+객체별로 다른 타입의 자료가 저장될 수 있도록 한다.
+
+```jsx
+ArrayList list = new ArrayList<>();
+// 꺽쇠 괄호가 제네릭!
+
+```
+
+괄호 안에는 타입명을 기재한다. 그러면 위 리스트 클래스 자료형의 타입은 String 타입으로 지정되어 문자열 데이터만 리스트에 적재할 수 있게 된다.
+
+## **Optional이란?**
+
+- NullPointerException(NPE)를 방지할 수 있도록 도와준다.
+- **Optional는 NULL이 올 수 있는 값을 감싸는 Wrapper 클래스로, NPE가 발생하지 않도록 도와준다.**
+- Optional 클래스는 아래 예제처럼 value에 값을 저장하기 때문에 NULL이더라도 바로 NPE가 발생하지 않으며, 각종 메서드를 제공한다.
+
+```jsx
+public final class Optional {
+
+ private final T value;
+...
+
+}
+```
+
+- 하지만, Optional은 데이터를 Wrapping하고 다시 풀고, NULL일 경우에는 대체 함수를 호출하는 등의 오버헤드가 있으므로 성능이 저하될 수 있다.
+- 그래서 메서드의 반환 값이 절대 NULL이 아니라면 Optional을 사용하지 않는 것이 성능 저하가 적다.
+
+
+
+## **References**
+
+- [일급 컬렉션(First-Class Collection)이란? (tistory.com)](https://dkswnkk.tistory.com/696)
+- [[Java] 스트림과 병렬 처리 ① (velog.io)](https://velog.io/@mmy789/Java-%EC%8A%A4%ED%8A%B8%EB%A6%BC%EA%B3%BC-%EB%B3%91%EB%A0%AC-%EC%B2%98%EB%A6%AC-1)
+- [[Java] Optional이란? 개념과 사용법 - 1 (tistory.com)](https://frtt0608.tistory.com/152)
\ No newline at end of file
From c4079f673c3c13deba8e8867e9599400f06932c0 Mon Sep 17 00:00:00 2001
From: "[jina4066]" <[jina4066@naver.com]>
Date: Thu, 12 Oct 2023 23:11:37 +0900
Subject: [PATCH 4/9] =?UTF-8?q?docs:=203=EC=A3=BC=EC=B0=A8=20=ED=95=99?=
=?UTF-8?q?=EC=8A=B5=20PR=20=EB=93=B1=EB=A1=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../jina4066.md | 43 +++++++++----------
1 file changed, 21 insertions(+), 22 deletions(-)
rename "week03/3\354\243\274\354\260\250.md" => week03/jina4066.md (87%)
diff --git "a/week03/3\354\243\274\354\260\250.md" b/week03/jina4066.md
similarity index 87%
rename from "week03/3\354\243\274\354\260\250.md"
rename to week03/jina4066.md
index 1bf35b9..63159a2 100644
--- "a/week03/3\354\243\274\354\260\250.md"
+++ b/week03/jina4066.md
@@ -112,9 +112,7 @@
MVC 패턴을 도입하면서 UI 영역과 도메인(비즈니스 로직) 영역으로 구분되어 서로에게 영향을 주지 않으면서 개발과 유지보수가 가능해지게 되었다.
- ![[출처: 인프런 김영한 강의]](%5B%E1%84%8F%E1%85%A1%E1%84%8B%E1%85%AE%203%E1%84%8C%E1%85%AE%E1%84%8E%E1%85%A1%5D%2013426a9837e040c1bb5d8e3db912cf43/Untitled.png)
-
- [출처: 인프런 김영한 강의]
+ 
- Model(모델)
@@ -205,33 +203,34 @@
반대로 **내부 반복자(iternal iterator)**란 **컬렉션 내부에서 요소들을 반복시키고, 개발자는 요소 당 처리해야 할 코드만 제공하는 코드 패턴**을 말한다.
- 
+ 
+
- - 내부 반복자를 사용했을 때의 이점
+- 내부 반복자를 사용했을 때의 이점
- 내부 반복자를 사용하면 컬렉션 내부에서 어떻게 요소를 반복시킬 것인가는 컬렉션에게 맡겨두고, **개발자는 요소 처리 코드에만 집중할 수 있게 된다.** 내부 반복자는 요소들의 반복 순서를 변경하거나, 멀티 코어 CPU를 최대한 활용하기 위해 요소들을 분배시켜 병렬 작업을 할 수 있게 도와주기 때문에 **하나씩 처리하는 순차적 외부 반복자보다는 효율적으로 요소를 반복시킬 수 있다.**
+내부 반복자를 사용하면 컬렉션 내부에서 어떻게 요소를 반복시킬 것인가는 컬렉션에게 맡겨두고, **개발자는 요소 처리 코드에만 집중할 수 있게 된다.** 내부 반복자는 요소들의 반복 순서를 변경하거나, 멀티 코어 CPU를 최대한 활용하기 위해 요소들을 분배시켜 병렬 작업을 할 수 있게 도와주기 때문에 **하나씩 처리하는 순차적 외부 반복자보다는 효율적으로 요소를 반복시킬 수 있다.**
- **Iterator**는 **컬렉션의 요소를 가져오는 것에서부터 처리하는 것까지 모두 개발자가 작성**해야 하지만,**스트림**은 람다식으로 요소 처리 내용만 전달할 뿐, **반복은 컬렉션 내부에서 일어난다.**
+**Iterator**는 **컬렉션의 요소를 가져오는 것에서부터 처리하는 것까지 모두 개발자가 작성**해야 하지만,**스트림**은 람다식으로 요소 처리 내용만 전달할 뿐, **반복은 컬렉션 내부에서 일어난다.**
- 스트림을 이용하면 **코드도 간결**해지지만, 무엇보다도 **요소의 병렬 처리가 컬렉션 내부에서 처리**된다는 효과까지 있다.
+스트림을 이용하면 **코드도 간결**해지지만, 무엇보다도 **요소의 병렬 처리가 컬렉션 내부에서 처리**된다는 효과까지 있다.
-
- - 작업 분류
- - 중간 연산
- - 연산결과가 스트림을 반환하기 때문에 스트림에 연속해서 중간 연산을 할 수 있다. (0 ~ n번)
- - 최종 연산
- - 연산 결과가 스트림이 아닌 연산으로, 스트림의 요소를 소모하기 때문에 마지막에 단 한번만 사용이 가능하다. (0~1번)
+- 작업 분류
+ - 중간 연산
+ - 연산결과가 스트림을 반환하기 때문에 스트림에 연속해서 중간 연산을 할 수 있다. (0 ~ n번)
+ - 최종 연산
+ - 연산 결과가 스트림이 아닌 연산으로, 스트림의 요소를 소모하기 때문에 마지막에 단 한번만 사용이 가능하다. (0~1번)
- ```jsx
- stream.distinct().limit(5).sorted().forEach(System.out::println);
- // distinct(), limit(), sorted() -> 중간 연산
- // 마지막 스트림을 소모하여 각 스트림의 요소를 출력하는 forEach -> 최종 연산
- ```
+ ```jsx
+ stream.distinct().limit(5).sorted().forEach(System.out::println);
+ // distinct(), limit(), sorted() -> 중간 연산
+ // 마지막 스트림을 소모하여 각 스트림의 요소를 출력하는 forEach -> 최종 연산
+ ```
- lazy Evaluation (지연된 연산)
- 스트림에서 연산을 할때 한 가지 중요한 점은, 최종 연산이 수행되기 전까지는 중간 연산이 수행 되지 않는다는 점이다.
@@ -244,7 +243,7 @@
- 내부 반복
- 스트림은 반복을 알아서 처리하고 결과 스트림값을 어딘가에 저장
- 장점: 작업을 투명하게 병렬적으로 처리하거나 최적화된 다양한 순서로 처리가 가능하다.
- - for문과의 차이점?
+ - for문과의 차이점?
- 중간 연산 메서드
- ****filter() / distinct()****
- filter()
From 975ae14c2cc5f2a84fe3e234265414665ba6b511 Mon Sep 17 00:00:00 2001
From: "[jina4066]" <[jina4066@naver.com]>
Date: Tue, 17 Oct 2023 19:13:43 +0900
Subject: [PATCH 5/9] =?UTF-8?q?docs=20:=204=EC=A3=BC=EC=B0=A8=20=ED=95=99?=
=?UTF-8?q?=EC=8A=B5=20PR=20=EB=93=B1=EB=A1=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
"week04/4\354\243\274\354\260\250.md" | 21 ----
week04/jina4066.md | 161 ++++++++++++++++++++++++++
2 files changed, 161 insertions(+), 21 deletions(-)
delete mode 100644 "week04/4\354\243\274\354\260\250.md"
create mode 100644 week04/jina4066.md
diff --git "a/week04/4\354\243\274\354\260\250.md" "b/week04/4\354\243\274\354\260\250.md"
deleted file mode 100644
index ecbc830..0000000
--- "a/week04/4\354\243\274\354\260\250.md"
+++ /dev/null
@@ -1,21 +0,0 @@
-# 4주차 학습 PR
-
-이번 주의 메인 테마는 테스트입니다.
-단위 테스트와 테스트 툴인 JUnit5, AssertJ를 공부하고, 로또 미션에 충분한 테스트를 작성해주세요!
-많은 예시 코드를 보시면 금방 감이 오실 겁니다!
-
-* 테스트 코드란? 테스트 코드는 왜 작성하는지?
-
-* 단위 테스트란?
-
-* JUnit5, AssertJ란?
-
-* BDD란?
-
-* private method test
-
-* @ParameterizedTest
-
-* 참고하면 좋을 것 같은 링크
-* https://youtu.be/mIO4Rbe_M74?feature=shared
-* https://tecoble.techcourse.co.kr/post/2021-05-25-unit-test-vs-integration-test-vs-acceptance-test/
\ No newline at end of file
diff --git a/week04/jina4066.md b/week04/jina4066.md
new file mode 100644
index 0000000..3e6d59c
--- /dev/null
+++ b/week04/jina4066.md
@@ -0,0 +1,161 @@
+# [4주차 학습 PR]
+
+---
+
+이번 주의 메인 테마는 테스트입니다. 단위 테스트와 테스트 툴인 JUnit5, AssertJ를 공부하고, 로또 미션에 충분한 테스트를 작성해주세요! 많은 예시 코드를 보시면 금방 감이 오실 겁니다!
+
+- 테스트 코드란? 테스트 코드는 왜 작성하는지?
+ - 테스트 코드란, 소프트웨어의 기능과 동작을 테스트하는 데 사용되는 코드로, 개발자가 작성한 코드를 실행하고 예상된 결과가 정상적으로 나오는지 확인하는 데 사용된다.
+ - 테스트 코드에는 단위 테스트(Unit Testing), 통합 테스트(Integration Testing), E2E(End to End Testing) 등의 다양한 종류가 있으며, 각각의 테스트는 특정한 측면에서 소프트웨어의 동작을 테스트한다.
+ - 이처럼 테스트를 구분하는 이유는 테스트 대상의 범위가 다르기 때문이다.
+ - 개발자는 테스트 코드를 작성함으로써, 개발 과정 중 예상치 못한 문제를 미리 발견할 수 있고, 코드 수정이 필요한 상황에서 유연하고 안정적인 대응을 할 수 있다.
+
+
+
+- 단위 테스트란?
+ - 단위 테스트(Unit Test)는 소프트웨어 개발에서 일반적으로 사용되는 테스트 중 하나로, 개별적인 코드 단위(하나의 기능을 하는 코드)가 의도한 대로 작동하는지 확인하는 과정이다.
+ - 구현 단계에서 각 모듈의 개발을 완료한 후 개발자가 명세서의 내용대로 정
+ 확히 구현되었는지를 테스트한다.
+- JUnit5, AssertJ란?
+ - `JUnit5`
+
+ > JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
+ >
+ - JUnit Platform : 테스트를 실행해주는 런처 제공, TestEngine API 정의
+ - JUnit Jupiter : TestEngine API 구현체로 JUnit5 제공
+ - JUnit Vintage : 하위 버전을 실행할 수 있는 TestEngine 제공
+
+ - 특징
+ - 테스트를 작성하고 실행하는 데 사용되는 오픈 소스 프레임 워크
+ - annotation을 제공한다.
+ - 테스트 기대 결과를 위한 assertion을 제공한다.
+ - test runner를 제공한다.
+ - 퀄리티를 올리며 빠르게 코드를 작성할 수 있게 해준다.
+ - 자동으로 테스트가 실행될 수 있으며 자체의 결과를 확인하고 바로 결과를 제공한다.
+ - 테스트 cases 및 기타 테스트 suites를 포함하는 test suites로 구성된다.
+ - 테스트 성공 시 초록, 실패 시 빨강으로 표시된다.
+ - `AssertJ`
+ - AssertJ는 많은 assertion을 제공하는 자바 라이브러리이다.
+ - 에러 메세지와 테스트 코드의 가독성을 매우 높여주고 IDE에서 쓰기 굉장히 쉽다.
+ - 특히, junit에서 제공하는 assertEquals에 비해 훨씬 가독성이 올라간다.
+
+ ```java
+ assertEquals(expected, actual); //junit
+
+ assertThat(actual).isEqualTo(expected); //AssertJ
+ ```
+
+- BDD란?
+ - ****BDD (Behavior Driven Development)는 제품이나 서비스의 행동에 초점을 맞춘 개발 방법론이다****
+ - TDD에서 파생된 개발 방법론으로 개발자와 비개발자간의 협업 과정을 녹여낸 방법
+
+
+
+ - BDD의 개발 절차
+ - Given - When -Then 세가지로 테스트를 진행하는 것
+ - Given
+ - 시나리오 상에서 주어진 환경을 정의
+ - When
+ - 사용자가 어떤 행위를 하는 것을 정의
+ - Then
+ - 그에 따른 어떠한 결과를 정의
+
+ - private method test
+ - Java Reflection API를 이용한 메소드 호출
+ - 자바는 클래스와 메소드 자체를 포함해 클래스의 변수, 메소드의 파라미터 타입, 메소드 이름 등의 메타 정보들을 위한 Class, Method 등을 정의해두었다.
+ - 리플렉션을 이용하면 정적으로 고정된 메소드의 코드를 메타정보로 추상화된 Method를 얻어낼 수 있으며 직접 호출 또한 가능하다.
+ - 그러므로 우리가 테스트하고자 하는 클래스로부터 Method를 추출하여 해당 메소드를 직접 invoke해주면 된다.
+
+ ```java
+ @ExtendWith(MockitoExtension.class)
+ class PrivateTestClassTest {
+
+ @InjectMocks
+ private PrivateTestClass target;
+
+ @Test
+ void isPredifined가True_ReflectionAPI() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+ // given
+ String name = "Jina";
+ Method method = target.getClass().getDeclaredMethod("isPredefined", String.class);
+ method.setAccessible(true);
+
+ // when
+ boolean result = (boolean)method.invoke(target, name);
+
+ // then
+ assertThat(result).isTrue();
+ }
+ }
+ ```
+
+ 해당 메소드를 얻어오기 위해서는 메소드의 이름과 타입 클래스를 넘겨주어야 하며, private 메소드는 기본적으로 접근 가능 여부가 false이므로 이를 true로 변경해주어야 한다. —> 스프링 프레임워크로 더 간단히 test 가능
+
+ - ****Spring의 ReflectionTestUtils를 이용한 메소드 호출****
+ - 스프링 프레임워크는 내부적으로 리플렉션을 상당히 많이 활용하고 있다.
+ - 그래서 직접 자바의 리플렉션 API를 하는 것 보다는 효율적으로 리플렉션을 사용하기 위한 유틸성 클래스인 ReflectionTestUtils를 제공하고 있다.
+
+ ```java
+ @ExtendWith(MockitoExtension.class)
+ class PrivateTestClassTest {
+
+ @InjectMocks
+ private PrivateTestClass target;
+
+ @Test
+ void isPredifined가True_ReflectionTestUtils() {
+ // given
+ String name = "MangKyu";
+
+ // when
+ boolean result = ReflectionTestUtils.invokeMethod(target, "isPredefined", name);
+
+ // then
+ assertThat(result).isTrue();
+ }
+ }
+ ```
+
+ private 메소드를 호출하기 위한 ReflectionTestUtils의 invokeMethod는 파라미터로 타깃 객체, 메소드 이름, 파라미터 목록(가변 변수)를 받고 있다. 위의 코드를 실행하면 테스트가 성공함을 확인할 수 있다.
+
+ - ****private 메소드 테스트를 지양해야 하는 이유****
+
+ 리플렉션은 런타임에 동작하는 기술로, 클래스와 메소드의 메타정보를 사용해서 애플리케이션을 동적으로 유연하게 만들 수 있다. 그래서 리플렉션을 사용하면 private 메소드를 invoke 할 수 있다.
+
+ 그런데 문제는 이렇게 작성한 private 메소드에 대한 테스트는 깨지기 쉬운 테스트가 된다는 것이다.
+
+ private 메소드는 내부를 감추어 클라이언트와의 결합도를 낮춰주는데, 클라이언트인 테스트 클래스가 내부 메소드를 알고 있으니 결합도가 높아진다. 그리고 이는 유지보수할 때 테스트에 대한 비용을 증가시키는 요인이 될 수 있는데, 메소드 이름이나 파라미터 등을 변경할 때 실패하게 된다. 또한 리플렉션 자체 역시 컴파일 에러를 유발하지 못하므로 최대한 사용을 자제해야 한다.
+
+- @ParameterizedTest
+ - 여러 argument를 이용해 테스트를 여러번 돌릴 수 있는 테스트를 할 수 있는 기능
+ - 사용하기 위해서는 `@Test` 대신 `@ParameterizedTest` 를 붙이면 된다.
+ - `@ParameterizedTest`를 사용하게 되면 최소 하나의 source 어노테이션을 붙여주어야 한다.
+
+ ---
+
+ - source annotaion
+ - ****ValueSource****
+ - **argument가 하나**인 테스트에 사용할 수 있다.
+ - short, byte, int, long ,float, double, char, boolean, String, java.lang.Class에 사용할 수 있다.
+ - ****NullSource, EmptySource, NullAndEmptySource****
+ - NullSource : null을 보낸다
+ - EmptySource : 비어 있는 배열, 컬렉션, 문자열 등을 반환한다
+ - NullAndEmptySource : NullSource와 EmtpySource를 합쳐놓은 것이다
+ - ****EnumSource****
+ - Enum을 argument로 보내줄 수 있다.
+
+ 1. Enum 전체를 가져오기
+
+ 1. Enum의 특정 목록만 가져오기
+ 2. regex 사용하기
+ - ****MethodSource****
+ - 테스트 클래스 내의 메소드 혹은 외부 클래스의 메소드가 반환하는 값을 source로 삼는 것이다.
+ - 테스트 클래스 내에 있고 `@TestInstance(Lifecycle.PRE_CLASS)`를 붙인 것이 아니라면, 모두 static 메소드여야 한다.
+ - 한 파라미터만 넣을 수도 있고, 여러 파라미터를 넣을 수도 있다.
+ - 테스트 메소드와 이름이 동일하면 source를 명시적으로 적어주지 않아도 된다.
+- 참고하면 좋을 것 같은 링크
+- [https://youtu.be/mIO4Rbe_M74?feature=shared](https://youtu.be/mIO4Rbe_M74?feature=shared)
+- [https://tecoble.techcourse.co.kr/post/2021-05-25-unit-test-vs-integration-test-vs-acceptance-test/](https://tecoble.techcourse.co.kr/post/2021-05-25-unit-test-vs-integration-test-vs-acceptance-test/)
From 7dad91b1e7a1fa09ff884013f0e0dbc20e7ec86b Mon Sep 17 00:00:00 2001
From: "[jina4066]" <[jina4066@naver.com]>
Date: Tue, 7 Nov 2023 21:47:07 +0900
Subject: [PATCH 6/9] =?UTF-8?q?docs:=207=EC=A3=BC=EC=B0=A8=20=ED=95=99?=
=?UTF-8?q?=EC=8A=B5=20PR=20=EB=93=B1=EB=A1=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../\352\271\200\354\247\200\353\202\230.md" | 0
"week07/7\354\243\274\354\260\250.md" | 24 ---
.../\352\271\200\354\247\200\353\202\230.md" | 161 ++++++++++++++++++
3 files changed, 161 insertions(+), 24 deletions(-)
rename week04/jina4066.md => "week04/\352\271\200\354\247\200\353\202\230.md" (100%)
delete mode 100644 "week07/7\354\243\274\354\260\250.md"
create mode 100644 "week07/\352\271\200\354\247\200\353\202\230.md"
diff --git a/week04/jina4066.md "b/week04/\352\271\200\354\247\200\353\202\230.md"
similarity index 100%
rename from week04/jina4066.md
rename to "week04/\352\271\200\354\247\200\353\202\230.md"
diff --git "a/week07/7\354\243\274\354\260\250.md" "b/week07/7\354\243\274\354\260\250.md"
deleted file mode 100644
index cd83de7..0000000
--- "a/week07/7\354\243\274\354\260\250.md"
+++ /dev/null
@@ -1,24 +0,0 @@
-## 7주차 학습 PR
-
-### 싱글톤 패턴이란?
-
-
-### 싱글톤 컨테이너란?(feat.싱글톤의 단점..?)
-
-
-### Java의 POJO란 무엇인가?(feat.Spring의 Bean)
-
-
-### 스프링의 사용 이유, 장점이나 특징(이거 중요!!)
-
-
-### 스프링에서 사용되는 어노테이션 10개 이상 정리하기
--> 세션을 맡아주셨던 경호님께서 이때 어노테이션 한번에 정리해두니 그렇게 편했다고..
-
-
-### controller - service - repository란?
-
-
-### (선택) 지난 세션에서 추가적으로 궁금했던 것들 자유롭게 기록
-지난 세션이나 학습 pr을 공부하시면서 어 그럼 이건 뭐지..? 하는 궁금증이 생겨난다면,
-더 깊이있게 학습하시고 소제목(###)을 추가적으로 달아서 정리해보세요!!
\ No newline at end of file
diff --git "a/week07/\352\271\200\354\247\200\353\202\230.md" "b/week07/\352\271\200\354\247\200\353\202\230.md"
new file mode 100644
index 0000000..28aec9d
--- /dev/null
+++ "b/week07/\352\271\200\354\247\200\353\202\230.md"
@@ -0,0 +1,161 @@
+## **7주차 학습 PR**
+
+### **싱글톤 패턴이란?**
+
+- 소프트웨어 디자인 패턴에서 싱글턴 패턴(Singleton pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 **실제로 생성되는 객체는 하나**이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다.
+- 간단히 설명하면 싱글톤 패턴은 **객체의 인스턴스를 한개만 생성되게 하는 패턴이다.**
+- 즉, 싱글톤 패턴은 아래와 같은 상황에 사용한다.
+ - 프로그램 내에서 하나의 객체만 존재해야 한다.
+ - 프로그램 내에서 여러 부분에서 해당 객체를 공유하여 사용해야한다.
+
+- 싱글톤 패턴의 이점은?
+
+ **1. 메모리 측면의 이점**
+
+ 싱글톤 패턴을 사용하게 된다면 한개의 인스턴스만을 고정 메모리 영역에 생성하고 추후 해당 객체를 접근할 때 메모리 낭비를 방지할 수 있다.
+
+ **2. 속도 측면의 이점**
+
+ 생성된 인스턴스를 사용할 때는 이미 생성된 인스턴스를 활용하여 속도 측면에 이점이 있다.
+
+ **3. 데이터 공유가 쉽다**
+
+ 전역으로 사용하는 인스턴스이기 때문에 다른 여러 클래스에서 데이터를 공유하며 사용할 수 있다. 하지만 동시성 문제가 발생할 수 있어 이 점은 유의하여 설계하여야 한다.
+
+ - 동시성 문제란?
+ - 여러 스레드가 동시에 같은 인스턴스의 필드 값을 변경하면서 발생하는 문제
+ - 중요한 점은 값에 무조건 동시에 접근한다고 문제가 발생하는 것이 아니라 값을 어디선가 **변경**할 때 발생한다.
+ - 스레드는 별도의 stack 영역을 갖기 떄문에, 인스턴스를 갖도록 설계하지 않고 지역변수나 매개변수 등으로 객체를 넘겨서 사용하게 되면 적은 노력으로 동시성 이슈를 피할 수 있다.
+
+
+### **싱글톤 컨테이너란?(feat.싱글톤의 단점..?)**
+
+- 싱글톤 패턴은 많은 문제들을 가지고 있다.
+ - 싱글톤 패턴을 적용하기 위해 구현할 코드양이 많아지면서 비용이 늘어난다.
+ - 싱글톤 패턴은 클래스 내에서 하나의 유일한 인스턴스를 생성하고 유지해야 한다. 이를 위해 인스턴스 변수를 선언하고, 생성자를 private으로 만들어야 한다. 또한 인스턴스를 얻거나 생성하는 메서드를 만들어야 한다. 싱글톤 패턴을 구현하는 데에 이 모든 코드가 필요하므로 코드 양이 늘어나게 된다.
+ - 의존관계상 클라이언트가 구현체에 의존하면서 DIP를 위반하게 된다.
+ - DIP를 위반하면 자연스럽게 OCP를 위반할 가능성도 높아진다.
+ - 테스트가 어려워진다.
+ - 인스턴스를 미리 다 받아서 설정이 끝난 상태이기에 유연한 테스트가 힘들다.
+ - 내부 속성을 변경하거나 초기화가 어렵다.
+ - private 생성자로 자식 클래스를 만들기 어렵다.
+ - 유연성이 떨어진다.
+
+ → 하지만 스프링 컨테이너에서는 싱글톤의 이러한 단점들을 해결하면서 장점만 가지는 싱글톤을 사용한다.
+
+- 싱글톤 컨테이너
+ - 스프링 컨테이너는 싱글톤 패턴을 적용하지 않아도 싱글톤으로 객체들을 관리한다.
+ - 스프링 컨테이너는 싱글톤 컨테이너 역할을 한다. 이처럼 싱글톤 객체를 생성 및 관리하는 기능을 **싱글톤 레지스트리**라 한다.
+ - 이렇게 스프링 컨테이너에서 싱글톤 컨테이너 역할을 해줌으로써 싱글톤 패턴의 단점을 없애고 객체의 단일성을 유지할 수 있다.
+
+ → 그렇기에 각각의 빈들은 싱글톤 패턴 적용을 위한 코드를 작성할 필요가 없다.
+ → 더하여 DIP, OCP, 테스트, private 생성자를 고민하지 않아도 된다.
+
+
+### **Java의 POJO란 무엇인가?(feat.Spring의 Bean)**
+
+
+
+- POJO란 Plain Old Java Object의 약자로, 이를 직역하면 순수한 오래된 자바 객체이다. 즉, Java로 생성하는 순수한 객체를 뜻한다.
+- 위 이미지는 Spring 삼각형이라는 유명한 이미지로 Spring의 핵심 개념들을 모두 표현하고 있다. POJO는 IoC/DI, AOP, PSA를 통해서 달성할 수 있다는 것을 의미한다.
+- POJO는 객체 지향적인 원리에 충실하면서 환경과 기술에 종속되지 않고, 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 의미한다. 이러한 POJO에 애플리케이션의 핵심 로직과 기능을 담아 설계하고 개발하는 방법을 `POJO 프로그래밍`이라고 한다.
+
+- POJO 프로그래밍
+ - POJO를 이용하여 프로그래밍 코드를 작성하는 것이다. 그러나 순수 자바 객체만을 사용한다고 해서 POJO 프로그래밍이라고 볼 수는 없다.
+ - POJO 프로그래밍으로 작성한 코드가 되기 위해서는 기본적인 규칙들을 지켜야 한다.
+ 1. Java나 Java의 스펙에 정의된 것 이외에는 다른 기술이나 규약에 얽매이지 않아야 한다.
+ - Java 프로그래밍에서 자바 언어와 자바 플랫폼의 표준 스펙에는 의존성을 가질 수 있지만, Java 이외의 외부 기술, 프레임워크, 라이브러리, 또는 규약에 대한 의존성을 최소화해야 한다는 의미
+ 2. 특정 환경에 종속적이지 않아야 한다.
+ - 자체 개발한 코드와 Java 표준 라이브러리를 주로 사용하며, 특정 프레임워크나 플랫폼에 강하게 의존하지 않아야 한다.
+
+ - POJO 프로그래밍이 필요한 이유
+ - 특정 환경이나 기술에 종속적이지 않으면 재사용이 가능하고, 확장 가능한 유연한 코드를 작성할 수 있다.
+ - 저수준 레벨의 기술과 환경에 종속적인 코드를 제거하여 코드를 간결해지며 디버깅하기에도 상대적으로 쉬워진다.
+ - 특정 기술이나 환경에 종속적이지 않기 때문에 테스트가 단순해진다.
+ - **객체지향적인 설계를 제한 없이 적용할 수 있다.**
+
+
+### **스프링의 사용 이유, 장점이나 특징(이거 중요!!)**
+
+1. POJO 프로그래밍을 지향
+ - POJO는 순수 Java만을 사용하여 만든 객체이므로 특정 기술이나 환경에 종속되지 않는다. 따라서, **외부 기술이나 규약의 변화에 얽매이지 않아, 보다 유연하게 변화와 확장에 대처할 수 있다.** 이러한 POJO를 사용하여 비즈니스 로직을 구현하면 **객체지향 설계를 제한없이 적용할 수 있으며, 코드가 단순해져 테스트와 디버깅 또한 쉬워진다.**
+ - 메소드나 객체(bean)의 호출 작업은 제어의 역전을 통해 외부에서 이루어진다.
+ - 제어의 역행을 전제조건으로 DI가 일어난다.
+ - 의존성을 가진 객체에 대해 스프링에서 의존성 주입이 발생하도록 한다.
+ - 의존성 주입 특성으로 인해 개발자가 POJO 개발이 가능하게 된다.
+
+2. PSA(Portable Service Abstraction, 일관된 서비스 추상화)
+ - 만일, 개발을 하던 중 사용 중이던 DB를 바꿔야 하는 상황이 왔을 떄, 각 DB 마다 사용 방법이 다르다면 코드를 모두 수정해 주어야 한다.
+ - 그러나 스프링을 사용하면 동일한 사용방법을 유지한 채로 데이터베이스를 바꿀 수 있다. 이는 **스프링이 데이터베이스 서비스를 추상화한 인터페이스를 제공해주기 때문에 가능**하다.
+ - 즉, 스프링은 Java를 사용하여 데이터베이스에 접근하는 방법을 규정한 인터페이스를 제공하고 있으며, 이를 J**DBC(Java DataBase Connectivity)**라고 한다.
+ - 각 데이터베이스를 만든 회사들은 자신의 데이터베이스에 접근하는 드라이버를 Java 코드의 형태로 배포하는데, **이 드라이버에 해당하는 Java 코드의 클래스가 JDBC를 구현합니다.** 따라서, JDBC를 기반으로 하여 데이터베이스 접근 코드를 작성해두면, 이후에 데이터베이스를 바꾸어도 기존에 작성한 데이터베이스 접근 로직을 그대로 사용할 수 있다.
+ - 이러한 JDBC처럼 **특정 기술과 관련된 서비스를 추상화하여 일관된 방식으로 사용될 수 있도록 한 것을 PSA(Portable Service Abstraction, 일관된 서비스 추상화)라고 한다.**
+
+3. AOP(관점지향 프로그래밍) 지원
+ - 애플리케이션을 개발할 때에 구현해야 하는 기능들은 크게 **공통 관심 사항**과 **핵심 관심 사항**으로 분류할 수 있다. 먼저, **핵심 관심 사항은 애플리케이션의 핵심 기능과 관련된 관심 사항**으로, 커피 주문 애플리케이션을 예로 든다면 메뉴 등록하기, 주문하기, 주문 변경하기 등이 있다.
+ - 반면, **공통 관심 사항은 모든 핵심 관심 사항에 공통적으로 적용되는 관심 사항들을 의미한다.** 예를 들어, 메뉴 등록하기, 주문하기, 주문 변경하기 등 모든 핵심 관심 사항에는 로깅이나 보안 등과 관련된 기능들이 공통적으로 적용되어야만 한다.
+ - 이 때, 핵심 관심 사항과 공통 관심 사항이 코드에 함께 모여 있으면 필연적으로 **공통 관심 사항과 관련된 코드가 중복**될 수밖에 없다. 이처럼 코드가 중복되어져 있는 경우, **공통 관심 사항을 수행하는 로직이 변경되면 모든 중복 코드를 찾아서 일일이 수정해주어야만 한다.**
+ - 코드의 중복이라는 문제를 해결하기 위해서는 공통 관심 사항과 관련된 기능들을 별도의 객체로 분리해낸 다음, 분리해낸 객체의 메서드를 통해 공통 관심 사항을 구현한 코드를 실행시킬 수 있도록 해야 한다. 이처럼, 애플리케이션 전반에 걸쳐 적용되는 공통 기능을 비즈니스 로직으로부터 분리해내는 것을 AOP(Aspect Oriented Programming, 관심 지향 프로그래밍)라고 한다.
+
+### **스프링에서 사용되는 어노테이션 10개 이상 정리하기**
+
+- `Annotation`은 클래스와 메서드에 추가하여 다양한 기능을 부여하는 역할을 한다. Annotation을 활용하여 Spring Framework는 해당 클래스가 어떤 역할인지 정하기도 하고, Bean을 주입하기도 하며, 자동으로 getter나 setter를 생성하기도 한다. 이러한 Annotation을 통하여 **코드량이 감소하고 유지보수하기 쉬우며, 생산성이 증가된다.**
+- @Component
+ - 개발자가 생성한 Class를 Spring의 Bean으로 등록할 때 사용하는 Annotation
+ - Spring은 해당 Annotation을 보고 Spring의 Bean으로 등록
+- ****@ComponentScan****
+ - Spring Framework는 @Component, @Service, @Repository, @Controller, @Configuration 중 1개라도 등록된 클래스를 찾으면, Context에 bean으로 등록
+ - @ComponentScan Annotation이 있는 클래스의 하위 Bean을 등록 될 클래스들을 스캔하여 Bean으로 등록
+- ****@Bean****
+ - @Bean Annotation은 개발자가 제어가 불가능한 외부 라이브러리와 같은 것들을 Bean으로 만들 때 사용
+- ****@Controller****
+ - Spring에게 해당 Class가 Controller의 역할을 한다고 명시하기 위해 사용하는 Annotation
+- @****RequestHeader****
+ - Request의 header값을 가져올 수 있으며, 해당 Annotation을 쓴 메소드의 파라미터에 사용
+- @****RequestMapping****
+ - @RequestMapping(value=”“)와 같은 형태로 작성하며, 요청 들어온 URI의 요청과 Annotation value 값이 일치하면 해당 클래스나 메소드가 실행
+ - Controller 객체 안의 메서드와 클래스에 적용 가능하며, 아래와 같이 사용
+ - Class 단위에 사용하면 하위 메소드에 모두 적용
+ - 메소드에 적용되면 해당 메소드에서 지정한 방식으로 URI를 처리
+- ****@ResponseBody****
+ - @ResponseBody은 메소드에서 리턴되는 값이 View 로 출력되지 않고 HTTP Response Body에 직접 쓰인다.
+ - return 시에 json, xml과 같은 데이터를 return
+- ****@RequestParam****
+ - URL에 전달되는 파라미터를 메소드의 인자와 매칭시켜, 파라미터를 받아서 처리할 수 있는 Annotation
+ - Json 형식의 Body를 MessageConverter를 통해 Java 객체로 변환
+- ****@Autowired****
+ - Spring Framework에서 Bean 객체를 주입받기 위한 방법은 크게 3가지가 있다.
+ - @Autowired
+ - 생성자 (@AllArgsConstructor 사용)
+ - setter
+ - Bean을 주입받기 위하여 @Autowired 를 사용 Spring Framework가 Class를 보고 Type에 맞게(Type을 먼저 확인 후, 없으면 Name 확인) Bean을 주입
+- ****@SpringBootTest****
+ - Spring Boot Test에 필요한 의존성을 제공
+- ****@Test****
+ - JUnit에서 테스트 할 대상을 표시
+
+### **controller - service - repository란?**
+
+1. **Controller**:
+ - Controller는 웹 애플리케이션에서 HTTP 요청을 처리하고 클라이언트에게 HTTP 응답을 제공하는 역할
+ - 클라이언트에서 HTTP 요청을 보내면 Controller는 해당 요청을 처리하고 비즈니스 로직을 호출하거나 다른 서비스와 상호작용
+ - 주요 역할은 요청을 라우팅하고 모델 및 뷰를 결합하여 클라이언트에게 응답을 제공
+ - 스프링 프레임워크에서는 **`@Controller`** 어노테이션을 사용하여 Controller 클래스를 정의하며, 이러한 클래스는 특정 URL 경로에 매핑된다.
+2. **Service**:
+ - Service는 비즈니스 로직을 포함
+ - Controller에서 요청을 받아와서 해당 요청에 대한 비즈니스 로직을 처리하거나, 데이터베이스와 상호작용하는 역할
+ - Service는 코드를 재사용하고 애플리케이션의 모듈화를 촉진하는 데 사용
+ - 주요 역할은 비즈니스 로직을 구현하고, 이 로직이 잘 작동하도록 하는 것
+ - 스프링에서는 **`@Service`** 어노테이션을 사용하여 Service 클래스를 정의하며, 이러한 클래스는 주로 Controller와 Repository 사이에서 중재자 역할로 이루어짐.
+3. **Repository**:
+ - Repository는 데이터베이스와 상호작용하여 데이터를 저장, 검색, 업데이트, 삭제하는 역할
+ - 데이터에 접근하는 역할로, 데이터베이스와 직접 상호작용하는 코드를 캡슐화
+ - 주로 데이터베이스와의 통신을 추상화하고 데이터 액세스 코드를 관리
+ - 스프링에서는 **`@Repository`** 어노테이션을 사용하여 Repository 클래스를 정의하며, 이러한 클래스는 데이터베이스 연동을 위한 CRUD(Create, Read, Update, Delete) 작업을 수행
+
+
+즉, Controller는 클라이언트와 상호작용하고, Service는 비즈니스 로직을 처리하며, Repository는 데이터베이스와의 상호작용을 담당한다.
+
+### **(선택) 지난 세션에서 추가적으로 궁금했던 것들 자유롭게 기록**
+
+지난 세션이나 학습 pr을 공부하시면서 어 그럼 이건 뭐지..? 하는 궁금증이 생겨난다면, 더 깊이있게 학습하시고 소제목(###)을 추가적으로 달아서 정리해보세요!!
From 14f48f978d13f3b13b64114e4c873035fdcda767 Mon Sep 17 00:00:00 2001
From: "[jina4066]" <[jina4066@naver.com]>
Date: Tue, 14 Nov 2023 22:00:41 +0900
Subject: [PATCH 7/9] =?UTF-8?q?docs:=208=EC=A3=BC=EC=B0=A8=20=ED=95=99?=
=?UTF-8?q?=EC=8A=B5=20PR=20=EB=93=B1=EB=A1=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
"week08/8\354\243\274\354\260\250.md" | 10 -
.../\352\271\200\354\247\200\353\202\230.md" | 171 ++++++++++++++++++
2 files changed, 171 insertions(+), 10 deletions(-)
delete mode 100644 "week08/8\354\243\274\354\260\250.md"
create mode 100644 "week08/\352\271\200\354\247\200\353\202\230.md"
diff --git "a/week08/8\354\243\274\354\260\250.md" "b/week08/8\354\243\274\354\260\250.md"
deleted file mode 100644
index c553a92..0000000
--- "a/week08/8\354\243\274\354\260\250.md"
+++ /dev/null
@@ -1,10 +0,0 @@
-# 8주차 학습 PR
-
-안녕하세요! 여러분 벌써 8주차라니, 15주차까지니까 벌써 반 정도 왔네요??
-이번 학습 PR은 심플하게 문항 딱 하나만 준비했습니다!
-그러니 가능하면 딥하게!! 준비해주셔야 합니다~ 다음 세션 주제이기도 해요 ㅎ
-
-## HTTP 요청이 들어왔을 때 요청을 받고 응답하기 까지의 전 과정을 설명해주세요.
-* 필수 포함 단어(필터, 인터셉터, dispatcherServlet)
-
-## (선택) 혹시 위 질문에 대한 답을 찾다가 새로운 개념들을 발견하면 정리해볼까요??
diff --git "a/week08/\352\271\200\354\247\200\353\202\230.md" "b/week08/\352\271\200\354\247\200\353\202\230.md"
new file mode 100644
index 0000000..6234f5f
--- /dev/null
+++ "b/week08/\352\271\200\354\247\200\353\202\230.md"
@@ -0,0 +1,171 @@
+# 8주차 학습 PR
+
+안녕하세요! 여러분 벌써 8주차라니, 15주차까지니까 벌써 반 정도 왔네요??
+이번 학습 PR은 심플하게 문항 딱 하나만 준비했습니다!
+그러니 가능하면 딥하게!! 준비해주셔야 합니다~ 다음 세션 주제이기도 해요 ㅎ
+
+## HTTP 요청이 들어왔을 때 요청을 받고 응답하기 까지의 전 과정을 설명해주세요.
+* 필수 포함 단어(필터, 인터셉터, dispatcherServlet)
+
+- 웹의 존재 이유는 정보 자원의 공유이다. 웹은 수많은 요청과 응답 사이클의 연속으로 이루어진다.
+- 서버는 정보, 자원, 서비스를 제공하는 측. 즉, 요청을 받고 이에 응답하는 측이다.
+ - 예시로는 웹 서버들이 있다.
+- 클라이언트는 정보, 자원, 서비스를 사용하는 측. 요청을 보내는 측이다.
+ - 예시로는 웹 브라우저들이 있다.
+- `HTTP`란?
+ - HyperText Transfer Protocol의 약자이다.
+ - 컴퓨터들끼리 HTML 파일을 주고 받을 수 있도록 하는 약속, 소통 방식이다.
+- 그렇다면 `HTML`이란?
+ - HyperText Markup Language의 약자이다.
+ - 문서와 문서가 링크로 연결되도록 하는 태그로 구성된 언어이다. 그 문서들이 웹브라우저 위에서 동작하도록 하는 언어가 HTML이다.
+ - HTML로 작성된 문서(웹페이지)를 주고 받을 수 있게 하는 통신규약이 바로 HTTP다.
+- `Request`
+ - HTTP Request(요청)는 백엔드(서버)에서 데이터를 처리하기 위한 또는 가져오기 위한 메시지이다. 메시지의 구조는 크게 세 부분으로 구성되어 있다.
+
+ > **1. Start Line**
+ >
+ >
+ > 요청의 첫번 째 줄이며, 시작 줄도 세 부분으로 구성되어있다.
+ >
+ > - HTTP Method: 해당 요청이 의도한 액션을 정의하는 부분. GET, POST, DELETE 가 주로 쓰임.
+ > - Request target: 해당 request 가 전송되는 목표 url
+ > - HTTP Version: 사용되는 HTTP 의 버전. 주로 1.1이 쓰인다.ex) GET /login HTTP/1.1GET 메서드로 login 이라는 요청 타겟에 HTTP 1.1 버전으로 요청을 보냄
+
+ > **2. Header**
+ >
+ >
+ > 해당 요청에 대한 추가 정보(메타 데이터)를 담고 있는 부분.
+ >
+ > - key : value 값으로 되어있다. 자주 사용되는 HEADER 의 정보는 아래와 같다.
+ >
+ > ```
+ > Headers:{
+ > HOST: 요청을 보내는 타켓의 주소. 웹사이트는 기본 주소 (ex: www.naver.com)
+ > User-Agent: 요청을 보내는 클라이언트에 대한 정보 (ex: chrome, firefox 등)
+ > Content-Type: 해당 요청이 보내는 메세지 body 타입 (ex: application/json 등)
+ > Content-Length: body 내용의 길이
+ > Authorization: 회원 인증/인가를 처리하기 위해 로그인 토큰을 Authorization 에 담는다.
+ > }
+ > ```
+ >
+
+ > **3. Body**
+ >
+ >
+ > 해당 요청의 실제 내용. 주로 body 를 사용하는 메서드는 POST 이다.
+ >
+ > ```
+ > body{
+ > "email" : "aaa@aaa.com",
+ > "user_name" : "swd"
+ > }
+ > ```
+ >
+- `Response`
+ - 요청과 마찬가지로 Response도 메시지이다.
+ - HTTP 규약에 따른 응답의 구조도 크게 3부분으로 나뉜다.
+
+ > **1. Start Line**
+ >
+ >
+ > 응답의 상태 줄. 응답은 요청에 대한 처리 상태를 클라이언트에게 알려주면서 시작한다.
+ >
+ > - **HTTP Version** - 요청의 HTTP버전과 동일
+ > - **Status Code** - 응답 메세지의 상태 코드
+ > - **Status Text** - 응답 메세지의 상태를 간략하게 설명해주는 텍스트ex) HTTP/1.1 404 Not Foundex) HTTP/1.1 200 SUCCESS
+
+ > **2. Headers**
+ >
+ >
+ > 요청의 헤더와 동일하다. 응답의 추가 정보(메타 데이터)를 담고 있는 부분이다.
+ >
+ > **다만, 응답에서만 사용되는 헤더의 정보들이 있는데, 요청하는 브라우저의 정보가 담긴 User-Agent 대신 Server 헤더가 사용된다.**
+ >
+
+ > **3. Body**
+ >
+ >
+ > 요청의 Body 와 일반적으로 동일하다.
+ >
+ > 요청의 메서드에 따라서 Body 가 항상 존재하지 않듯이, 응답도 응답의 형태에 Body 가 없을 수 있다. 주로 사용되는 Body 의 데이터 타입은 JSON(JavaScript Object Notation) 이다.
+ >
+
+## HTTP의 동작과정
+
+> 서버 접속 -> 클라이언트 -> **요청** -> 서버 -> **응답** -> 클라이언트 -> 연결 종료
+>
+
+
+1. 사용자가 웹 브라우저에 URL 주소를 입력한다.
+2. DNS 서버에 웹 서버의 호스트 이름을 IP 주소로 변경 요청한다.
+ - DNS 작동원리
+ 1. 웹 브라우저에 `google.com`을 입력
+ 2. `Local DNS`에게 Hostname(google.com)에 대한 IP 주소 요청
+ 3. Local DNS에 IP 주소가 없다면 다른 DNS Name Server(Root DNS) 정보를 응답
+ 4. `Root DNS` 서버에게 Hostname 에 대한 IP 주소를 요청
+ 5. Root DNS 서버는 .com 도메인을 관리하는 TLD(Top-Level Domain) Name Server 정보 응답
+ 6. `TLD`에게 Hostname에 대한 IP 주소 요청
+ 7. TLD는 Hostname을 관리하는 `DNS Server` 정보 응답
+ 8. [google.com](http://google.com) 도메인을 관리하는 DNS Server에게 Hostname에 대한 IP 주소를 요청
+ 9. `DNS Serve`r는 Hostname 에 대한 IP 주소 응답
+ 10. `Local DNS Server`는 응답으로 받은 Hostname에 대한 IP 주소를 캐싱하고 IP 주소 정보로 HTTP 요청
+
+ - [`google.com`](http://google.com) 으로 요청했지만, 실제로는 DNS 서버를 통해 알아낸 IP주소와 입력한 URL 정보가 함께 요청으로 전달된다.
+ - URL 정보와 전달받은 IP 주소는 HTTP Protocol을 사용하여 HTTP `Request Message`를 생성한다.
+
+ 
+
+3. 웹서버와 TCP 연결을 시도한다.
+ - HTTP 요청 Message는 TCP Protocol을 사용하여 인터넷을 거쳐 해당 IP주소의 컴퓨터 Web Server로 전송된다.
+4. 클라이언트가 서버에게 요청한다.
+ - Web Server 로 도착한 HTTP 요청 Message는 HTTP Protocol을 사용하여 URL 정보로 변환된다.
+
+ > **HTTP Request Message = Request Header + 빈 줄 + Request Body**
+ >
+ > - Request Header
+ > - 요청 메소드 + 요청 URI + HTTP 프로토콜 버전
+ > - `GET /background.png HTTP/1.0` `POST / HTTP 1.1`
+ > - Header 정보(key-value 구조)
+ > - 빈 줄
+ > - 요청에 대한 모든 메타 정보가 전송되었음을 알리는 용도
+ > - Request Body
+ > - GET, HEAD, DELETE, OPTIONS처럼 리소스를 가져오는 요청은 바디 미포함
+ > - 데이터 업데이트 요청과 관련된 내용 (HTML 폼 콘텐츠 등)
+ - Web Server는 HTTP 요청을 받고, 바로 컨텐츠를 응답하거나 WAS에 요청을 전달한다.
+ - WAS에 요청이 전달되고, WAS에서 처리된 요청이 있다면 해당 컨텐츠를 응답한다.
+ - WAS 의 동작원리
+ - Web Server 로부터 받은 요청과 관련된 `Servlet 을 메모리에 로딩`
+ - web.xml 을 참조하여 해당 Servlet 에 대한 Thread 생성 (Thread Pool 활용)
+ - HttpServletRequest, HttpServletResponse 객체를 생성하여 생성된 Servlet에 전달
+ - Thread는 Servlet의 service() 호출
+ - service() 는 요청에 맞는 `doGet()` or `doPost()` 호출
+ - doGet() or doPost() 는 인자에 맞게 생성된 적절한 동적 컨텐츠를 Response 객체에 담아 WAS에 전달
+ - WAS는 Response 객체를 HttpResponse 형태로 바꾸어 Web Server에 전달
+ - 생성된 Thread를 종료하고, HttpServletRequest, HttpServletResponse 객체 제거
+
+ 
+
+ - Servlet Filter
+ - 클라이언트의 요청이 Servlet Container에 도착하면, 먼저 설정된 필터들이 요청을 가로채어 필터 체인을 통과한다.
+ - 필터는 요청 로깅, 권한 검사, 문자 인코딩 설정 등의 작업을 수행한다.
+ - Dispatcher Servlet
+ - doGet() or doPost()를 통해 전달된 요청을 확인해서 적합한 Controller에 위임해주는 Front Controller를 거친다.
+ - Spring Interceptor
+ - Servlet Filter와 동일하게 웹 공통 관심사를 처리한다.
+ - Spring MVC 구조에 특화된 필터 기능을 제공한다.
+ - HandlerMapping을 통해 요청 URL에 매핑되는 Handler를 조회한다.
+ - 조회한 Handler를 실행할 수 있는 Handler Adapter를 조회한다.
+ - 앞서 조회한 Handler Adapter를 실행하면 Handler Adapter가 실제 Handler(Controller)를 실행한다.
+ - Handler Adapter는 Handler(Controller)가 반환하는 정보를 ModelAndView로 변환해서 반환한다.
+
+5. 서버가 클라이언트에게 데이터를 응답한다.
+ - 최종적으로 생성된 응답은 클라이언트로 전송되어 브라우저에 렌더링된다.
+
+ > **HTTP Response Message = Response Header + 빈 줄 + Response Body**
+ >
+ > - Response HeaderHTTP 프로토콜 버전 + 응답 코드 + 응답 메시지ex. `HTTP/1.1 404 Not Found.`Header 정보(key-value 구조)
+ > - 빈 줄요청에 대한 모든 메타 정보가 전송되었음을 알리는 용도
+ > - Response Body응답 리소스 데이터201, 204 상태 코드는 바디 미포함
+6. 서버 클라이언트 간 연결 종료
+
+## (선택) 혹시 위 질문에 대한 답을 찾다가 새로운 개념들을 발견하면 정리해볼까요??
From 28933370020fa38077de483786ac39d66e53f4cf Mon Sep 17 00:00:00 2001
From: "[jina4066]" <[jina4066@naver.com]>
Date: Tue, 21 Nov 2023 19:09:18 +0900
Subject: [PATCH 8/9] =?UTF-8?q?docs:=209=EC=A3=BC=EC=B0=A8=20=ED=95=99?=
=?UTF-8?q?=EC=8A=B5=20PR=20=EB=93=B1=EB=A1=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
"\352\271\200\354\247\200\353\202\230.md" | 81 +++++++++++++++++++++++
1 file changed, 81 insertions(+)
create mode 100644 "\352\271\200\354\247\200\353\202\230.md"
diff --git "a/\352\271\200\354\247\200\353\202\230.md" "b/\352\271\200\354\247\200\353\202\230.md"
new file mode 100644
index 0000000..a7f296d
--- /dev/null
+++ "b/\352\271\200\354\247\200\353\202\230.md"
@@ -0,0 +1,81 @@
+## Dispatcher Servlet이란?
+
+HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러라고 정의할 수 있다.
+
+## Dispatcher Servlet이 요청을 받아 컨트롤러로 위임하는 과정
+
+1. 서블릿 요청/응답을 HTTP 서블릿 요청/응답으로 변환
+2. HTTP Method에 따른 처리 작업 진행
+3. 요청에 대한 공통 처리 작업 진행
+4. 컨트롤러로 요청을 위임
+
+ 1) 요청에 매핑되는 HandlerExecutionChain 조회
+
+ 2) 요청을 처리할 HandlerAdapter 조회
+
+ 3) HandlerAdapter를 통해 컨트롤러 메소드 호출(Handler ExecutionChain 처리)
+
+
+---
+
+### 1. 서블릿 요청/응답을 HTTP 서블릿 요청/응답으로 변환
+
+
+
+HTTP 요청은 등록된 필터들을 거쳐 디스패처 서블릿이 처리하게 되는데, 가장 먼저 요청을 받는 부분은 부모 클래스인 HttpServlet에 구현된 service 메소드이다.
+service에서는 먼저 Servlet 관련 Request/Response 객체를 Http 관련 Request/Response로 캐스팅해준다.
+
+### 2. HTTP Method에 따른 처리 작업 진행
+
+
+그리고 나서 HttpServletRequest 객체를 파라미터로 갖는 service 메소드를 호출한다.
+
+요청 메소드에 따라 필요한 처리와 doX 메소드를 호출해준다. 그러면 doX 메소드를 오버라이딩하고 있는 자식 클래스인 FrameworkServlet로 다시 요청이 이어지게 된다.
+
+#### do X 메소드 구현
+
+
+각각의 doX 메소드에서는 Http Method에 맞는 작업을 한 후, 공통적으로 processRequest를 거치게 된다.
+
+### 3. 요청에 대한 공통 처리 작업 진행
+
+
+processRequest에서는 request에 대한 공통 작업을 한 후, doService를 호출한다.
+
+
+자식 클래스인 DispatcherServlet의 doService 코드는 위와 같다.
+doDispatch를 통해 HTTP 요청을 컨트롤러로 위임해준다.
+
+### 4. 컨트롤러로 요청을 위임
+[doDispatch 코드]
+
+#### 1) 요청에 매핑되는 HandlerMapping(HandlerExecutionChain) 조회
+
+getHandler에서는 HandlerMapping 목록을 순회하여 HandlerExecutionChain을 찾는다.
+
+탐색을 통해 찾아진 HandlerMethod는 최종적으로 HandlerExecutionChain으로 반환된다.
+
+#### 2) 요청을 처리할 HandlerAdapter 조회
+
+디스패처 서블릿은 HandlerExecutionChain을 직접 실행하지 않고, HandlerAdapter라는 어댑터 인터페이스를 통해 실행한다. 컨트롤러의 구현 방식에 상관없이 요청을 위임하도록 어댑터 패턴을 사용했다. doDispatch에서는 getHandlerAdapter를 통해 handlerAdapter를 조회한다.
+
+#### 3) HandlerAdapter를 통해 컨트롤러 메소드 호출 (HandlerExecutionChain 처리)
+
+
+HandlerAdapter를 통해 HandlerExecutionChain을 처리하는데, 내부적으로 인터셉터를 가지고 있어 공통적인 전/후처리 과정이 처리된다.
+적합한 HandlerAdapter가 HandlerExecutionChain을 모두 찾았으면 HandlerAdapter가 요청을 처리한다.
+요청의 종류에 따라 HandlerAdapter 구현체가 달라지고 그에 따른 전/후처리가 달라진다.
+
+RequestMappingHandlerAdapter의 handleInternal은 실제로 요청을 위임하는 invokeHandlerMethod를 호출한다.
+
+InvokeHandlerMethod에서는 컨트롤러의 파라미터를 처리하는 ArgumentResolver와 반환값을 처리하는 ReturnValueHandler의 공통적인 전/후처리가 진행된다. 세팅이 끝나면 ServletInvocableHandlerMethod의 invokeAndHandle로 이어진다.
+
+invokAndHandle에서는 바로 부모 클래스인 InvocablehandlerMethod의 invokeForRequest로 이어진다.
+
+invokeForRequest에서는 메소드 호출을 위해 필요한 인자값을 처리한다. 그리고 doInvoke에서 만들어진 인자값을 통해 컨트롤러의 메소드를 호출한다.
+
+doInvoke에서는 먼저 요청을 처리할 컨트롤러의 메소드 객체를 꺼내온다. 그리고 Method 객체의 invoke를 통해서 실제 컨트롤러로 위임을 해준다.
+
+컨트롤러에서 성공적으로 작업을 처리한 후에 ResponseEntity를 반환했다면 invokeAndHandle의 returnValue로 해당 객체가 온다.
+이후, returnValueHandler를 통해 후처리를 한다. 응답에 따라 다양한 형태로 처리하기 위해 리스트로 갖고 있다.
+ResponseEntity 객체를 반환한 경우에는 HandlerMethodeReturnValueHandler 구현체 중에서 HttpEntityMethodProcessor가 사용된다. 내부에서는 Response를 set 해주고, 응답 가능한 MediaType인지 검사한 후에 적절한 MessageConverter를 선택해 응답을 처리하고 결과를 반환한다.
\ No newline at end of file
From 649bcd84640a1f3696f7a60bc8c38bd6424a9fc8 Mon Sep 17 00:00:00 2001
From: "[jina4066]" <[jina4066@naver.com]>
Date: Tue, 28 Nov 2023 23:39:38 +0900
Subject: [PATCH 9/9] =?UTF-8?q?docs:=2010=EC=A3=BC=EC=B0=A8=20=ED=95=99?=
=?UTF-8?q?=EC=8A=B5=20PR=20=EB=93=B1=EB=A1=9D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../\352\271\200\354\247\200\353\202\230.md" | 0
.../\352\271\200\354\247\200\353\202\230.md" | 0
2 files changed, 0 insertions(+), 0 deletions(-)
rename "\352\271\200\354\247\200\353\202\230.md" => "week09/\352\271\200\354\247\200\353\202\230.md" (100%)
rename "week10/10\354\243\274\354\260\250.md" => "week10/\352\271\200\354\247\200\353\202\230.md" (100%)
diff --git "a/\352\271\200\354\247\200\353\202\230.md" "b/week09/\352\271\200\354\247\200\353\202\230.md"
similarity index 100%
rename from "\352\271\200\354\247\200\353\202\230.md"
rename to "week09/\352\271\200\354\247\200\353\202\230.md"
diff --git "a/week10/10\354\243\274\354\260\250.md" "b/week10/\352\271\200\354\247\200\353\202\230.md"
similarity index 100%
rename from "week10/10\354\243\274\354\260\250.md"
rename to "week10/\352\271\200\354\247\200\353\202\230.md"