diff --git a/ch10/item71.md b/ch10/item71.md
new file mode 100644
index 0000000..764ec5d
--- /dev/null
+++ b/ch10/item71.md
@@ -0,0 +1,51 @@
+# Item 71
+
+## 필요 없는 검사 예외 사용은 피하라
+
+### 검사 예외란?
+> - 어플리케이션 수행 중에 일어날법한 예외를 검사하고 대비하라는 목적으로 사용.
+> - 반드시 예외 처리를 해야한다.
+> - 컴파일러가 발견해서 컴파일 오류를 발생시킨다.
+> - try/catch, throws 방식이 존재
+> - 처리를 강요하는 것이기 때문에 과하게 사용한다면 API 사용자에게 부담을 준다.
+
+
+### 검사 예외를 피하는 방법
+- 빈 Optional을 반환
+- 상태 검사 메서드와 Unchecked Exception을 추가
+
+
+#### 예시 1, 빈 Optional
+```java
+public static Optional create() {
+
+ try {
+ database.create(); // create() 메서드 안에선 throws IOException으로 컴파일 에러 발생 가정.
+ } catch (IOException e) {
+ return Optional.empty(); // 빈 옵셔널 반환
+ }
+ return Optional.of(Database);
+}
+```
+- 예외가 발생한 부가 정보를 담을 수 없으므로 좋은 방법은 아님
+
+
+#### 예시 2, 상태 검사 메서드와 Unchecked Exception
+``` java
+public static Optional create() {
+
+ if (database.canCreateFile()) { // 예외가 던져질 지 여부를 boolean값으로 반환
+ database.create();
+ } else {
+ throw new CustomDatabaseIOException();
+ }
+}
+```
+- 여러 스레드가 동시에 접근한다면 canCreateFile와 create 호출부 사이에 외부 요인이 접근 가능.
+- 그로 인해 객체의 상태가 변할 수 있다.
+
+
+### 결론
+1. API호출자가 예외 상황에서 복구할 방법이 없다 => 비검사 예외를 던진다.
+2. API호출자가 예외 상황에서 복구할 방법이 있으며, 호출자가 처리하기를 원한다. => optional 반환 고려, 예외가 발생할 수 있음을 암시해야함.
+3. API호출자가 예외 상황에서 복구할 방법이 있으며, 예외를 api에서 던진다. => 검사 예외를 던진다.
diff --git a/ch10/item72.md b/ch10/item72.md
new file mode 100644
index 0000000..1a5b136
--- /dev/null
+++ b/ch10/item72.md
@@ -0,0 +1,44 @@
+# Item 72
+
+## 표준 예외를 사용하라
+
+
+### 표준 예외란?
+> - 자바 API에서 제공하는 예외.
+> - 가독성이 높아지고, 사용하기 쉽다.
+> - 메모리 사용량도 줄어들고, 클래스를 메모리에 적재하는 시간도 적게 걸린다.
+
+
+### 대표적인 표준 예외
+- IllegalArgumentException
+ - 허용하지 않은 값이 인수로 전달되었을 때
+
+- IllegalStateException
+ - 객체가 메서드를 사용하기에 적절하지 않은 상태일 때
+
+- NullPointerException
+ - null을 허용하지 않는 메서드가 null을 인자로 받을 때
+
+- IndexOutOfBoundsException
+ - 인덱스의 범위를 넘어설 때
+
+- ConcurrentModificationException
+ - 허용되지 않은 동시 수정이 발견되었을 때
+
+- UnsupportedOperationException
+ - 호출한 메서드가 지원하지 않을 때
+
+
+
+### Exception, RuntimeException, Throwable, Error는 직접 재사용 하지 말 것
+- 위 클래스들은 예외 클래스들의 상위 클래스이다. 즉, 구체적인 예외 정보를 알 수 없으므로 안정적으로 테스트할 수 없다.
+
+
+
+### 주의사항
+
+- 상황에 부합한다면 항상 표준 예외를 재사용하자. 단, API 문서를 참고하여 사용하고자 하는 Exception이 이름 뿐만아니라 맥락에도 부합하는지 확인해야한다.
+
+- 더 많은 정보를 제공하고자 한다면 표준 예외를 확장해도 된다. 단, 예외는 직렬화할 수 있다는 것을 감안해야한다.
+
+ 직렬화에는 많은 부담이 따르므로 이 사실만으로도 커스텀한 예외를 사용해야할 이유가 사라진다.
diff --git a/ch11/item83.md b/ch11/item83.md
new file mode 100644
index 0000000..fe4b99d
--- /dev/null
+++ b/ch11/item83.md
@@ -0,0 +1,108 @@
+# Item 83
+
+## 지연 초기화는 신중히 사용하라
+
+### 지연초기화란?
+> - 필드의 초기화 시점을 그 값이 처음 필요할 때까지 늦추는 기법.
+> - 주로 최적화 용도로 사용.
+> - 클래스와 인스턴스 초기화 때 발생 하는 위험한 순환문제를 해결하는 효과도 있음.
+
+
+### 지연초기화는 양날의 검이다.
+- 지연초기화를 사용한다면 인스턴스 생성 시의 초기화 비용은 줄지만 그 대신 필드에 접근하는 비용은 커진다.
+- 지연 초기화가 실제로는 성능을 느려지게 할 수 있다.
+> - 초기화가 이뤄지는 비율은 어떠한가.
+> - 실제 초기화에 비용이 얼마나 드는가.
+> - 초기화된 각 필드를 얼마나 빈번히 호출되는가.
+
+
+따라서, 성능을 생각한다면 지연초기화는.
+- 해당 클래스의 인스터스 중 그 필드를 사용하는 인스턴스의 비율이 낮고
+- 그 필드를 초기화하는 비용이 크다면 사용하자.
+- 즉. 초기화 시점 해당 필드 or 클래스가 필요할 때 시키는 것이다!
+- 그러나, 성능을 측정해보기 전까지는 어떤 것이 더 나은지 확신하지 못함.
+
+또한, 멀티스레드 환경에서는 지연초기화 하는 필드를 둘 이상의 스레드가 공유한다면
+어떠한 형태로든 반드시 동기화를 해야함!
+
+#### 예시 1, 일반적인 초기화 방법
+```java
+public class TestClass {
+ private final Member member = createMember();
+
+ private Member createMember() {
+ return new Member("KJJ");
+ }
+}
+```
+- 대부분의 상황에서 일반적인 초기화가 지연 초기화보다 낫다.
+
+
+#### 예시 2, 인스턴스 필드의 지연초기화
+``` java
+public class TestClass {
+ private Member member;
+
+ public synchronized Member getMember(){
+ if(member==null){
+ member = createMember();
+ }
+ return member;
+ }
+ private Member createMember() {
+ return new Member("KJJ");
+ }
+}
+```
+- 지연 초기화가 초기화 순환성(initialization circularity) 을 깨뜨릴 것 같으면 synchronized 를 단 접근자를 사용하자.
+
+
+#### 예시 3, 정적 필드용 지연 초기화 홀더 클래스 관용구
+``` java
+public class TestClass {
+
+ static final private Member member = createMember();
+
+ private static Member createMember() {
+ System.out.println("init");
+ return new Member("KJJ");
+ }
+
+ public static Member getMember(){
+ return TestClass.member;
+ }
+}
+```
+- 해당 방식은 클래스는 클래스가 처음 쓰일 때 비로소 초기화 된다는 특성을 이용한 관용구다.
+- 이러한 방식은 getMember 메서드가 필드에 접근하면서 동기화를 전혀 하지않으니 성능이 느려질 거리가 전혀 없다.
+
+
+#### 예시 4, 인스턴스 필드 지연 초기화용 이중검사 관용구
+``` java
+public class TestClass {
+
+ private volatile Member member;
+
+ private Member createMember() {
+ return new Member("KJJ");
+ }
+
+ public Member getMember() {
+ Member result = member;
+ if(result!=null){
+ return result;
+ }
+ synchronized (this){
+ if(member == null){
+ member = createMember();
+ }
+ return member;
+ }
+ }
+}
+```
+- 성능 때문에 인스턴스 필드를 지연 초기화해야 한다면 이중검사 관용구를 사용하라.
+- 해당 관용구는 초기화된 필드에 접근할 때의 동기화 비용을 없애준다.
+- 필드가 초기화 된 후로는 동기화 하지 않으므로 해당 필드는 반드시 volatile로 선언한다.
+- result 지역변수는 필드가 이미 초기화된 상황에서는 이 필드를 딱 한번만 읽도록 보장하는 역할을 한다
+
diff --git a/ch11/item84.md b/ch11/item84.md
new file mode 100644
index 0000000..4dfcbb9
--- /dev/null
+++ b/ch11/item84.md
@@ -0,0 +1,26 @@
+# Item 84
+
+## 프로그램의 동작을 스레드 스케줄러에 기대하지 말라
+
+### 스레드 스케줄러란?
+> - 스레드의 실행 시점을 관리하는 역할을 한다.
+> - 사용자가 제어할 수 없다.
+> - 제한된 자원을 여러 프로세스가 효율적으로 사용하도록 다양한 정책(Policy)을 가지고 할당한다.
+
+
+### 당장 처리해야할 작업이 없다면 실행하지 마라
+- 스레드 풀 크기를 적절히 설정하고, 작업은 짧게 유지해야 한다.
+ - 단, 너무 짧으면 오히려 작업 분배에 부담이가서 성능을 떨어뜨릴 수 있다.
+ - 바쁜 대기(busy waiting) 상태가 되면 안된다
+
+
+### Tread.yield에 의존하지 마라
+- Tread.yield 사용하여 성능을 개선시킬 수 있다.
+- 하지만, 어느정도 개선이 될 수 있지만, 효과가 없을수도 있고 오히려 느려질 수 있다.
+- Tread.yield는 테스트할 수단도 없다.
+- 애플리케이션 구조를 바꿔 동시에 실행가능한 스레드 수가 적어지도록 조치하는 것이 올바른 방법이다.
+
+
+### 스레드 우선 순위에 의존하지 마라
+- 스레드 우선순위는 자바에서 이식성이 가장 나쁜 특성에 속한다
+- 심각한 응답 불가 문제를 스레드 우선순위로 해결하려는 시도는 진짜 원인을 찾아 수정하기 전까지 같은 무넺가 반복해서 터져 나올 것이다.
diff --git a/ch12/item89.md b/ch12/item89.md
new file mode 100644
index 0000000..4665635
--- /dev/null
+++ b/ch12/item89.md
@@ -0,0 +1,69 @@
+# Item 89
+
+## 인스턴스 수를 통제해야한다면 readResolve보다는 열거 타입을 사용하라
+
+### readResolve 란?
+> - 인스턴스 통제 목적으로 사용함 .
+> - 단 객체 참조 타입 인스턴스 필드는 모두 transient로 선언해야한다.
+> - 그렇지 않으면 readResolve 메서드가 수행되기 전에 역직렬화된 객체의 참조를 공격할 여지가 남는다.
+
+
+### transient 란?
+-
+-
+
+
+### 싱글톤을 직렬화하는 경우 문제점
+- 클래스에 implements Serializable 을 추가하는 순간 더 이상 싱글턴이 아니게 된다.
+- 기본 직렬화를 쓰지 않고, 명시적인 readObject를 제공하더라도 소용없다.
+- 어떤 readObject를 사용하든 이 클래스가 초기화될 때 만들어진 인스턴스와는 별개인 인스턴스를 반환하게 된다.
+
+###
+
+#### 예시 1, 싱글톤 객체
+```java
+public final class Elvis implements Serializable {
+ private static final Elvis INSTANCE = new Elvis();
+
+ private static Elvis() {
+ }
+
+ public static Elvis getINSTANCE() {
+ return INSTANCE;
+ }
+
+ private String[] favoriteSongs = {"Sandman", "aquaman"}
+
+ public void printFavorites() {
+ System.out.println(Arrays.toString(favoriteSongs);
+ }
+
+ private Object readResolve() {
+ return INSTANCE;
+ }
+}
+```
+- 위 예시에서는 favoriteSongs를 transient로 선언할 것이 아니라면 enum타입으로 만드는 것이 좋다.
+- 싱글턴이 non-transient 참조필드를 가지고 있으면 이 내용은 readResolve가 실행되기 전에 역직렬화 된다.
+- 그렇게 되면 조작된 스트림을 사용하여 해당 참조 필드의 내용이 역직렬화되는 시점에 참조를 훔쳐올 수 있다.
+
+
+``` java
+public enum Elvis {
+ INSTANCE;
+ private String[] favoriteSongs = {"sandman", "aquaman"};
+
+ public void printFavorites() {
+ System.out.println(Arrays.toString(favoriteSongs);
+ }
+}
+```
+- 이렇게 enum 타입으로 하면 된다.
+
+
+##결론
+- 직렬화가 필요하며 인스턴스 수가 하나임을 보장하고 싶을 때, enum 타입을 가장 먼저 고려해라.
+- 만약 enum 타입을 사용하는 것이 불가능하며, 인스턴스 수를 제한해야 한다면, readResolve를 구현해라.
+- 또한, 해당 클래스의 모든 필드를 원시타입 또는 임시타입으로 정의되어야 한다.
+
+
diff --git a/ch12/item90.md b/ch12/item90.md
new file mode 100644
index 0000000..d60192f
--- /dev/null
+++ b/ch12/item90.md
@@ -0,0 +1,78 @@
+# Item 90
+
+## 직렬화된 인스턴스 대신 직렬화 프록시 사용을 검토하라
+- Serializable을 구현하기로 결정한 순간, 언어의 생성자 이외의 방법으로도 인스턴스를 생성할 수 있게 된다.
+- 버그 및 보안 문제가 일어날 가능성이 커진다.
+- 직렬화 프록시 패턴 (Serialization Proxy Pattern)을 이용하면 이러한 위험을 크게 줄여줄 수 있다.
+-
+
+### 직렬화 프록시 패턴이란?
+> - 가짜 바이트 스트림 공격과 내부 필드 탈취 공격을 프록시 수준에서 차단해준다.
+> - 필드들을 final로 선언해도 되므로 Period 클래스를 진정한 불변으로 만들 수 있다.
+> - 역직렬화때 유효성 검사를 하지 않아도 된다.
+> - 역직렬화한 인스턴스와 원래의 직렬화된 인스턴스의 클래스가 달라도 정상 작동한다.
+
+
+#### 예시 1, 직렬화 프록시 패턴
+```java
+ public final class Period implements Serializable {
+
+ private final Date start;
+ private final Date end;
+
+ public Period(Date start, Date end) {
+ if (this.start.compareTo(this.end) > 0) {
+ throw new IllegalArgumentException(start + "가 " + end + "보다 늦다.");
+ }
+ this.start = new Date(start.getTime());
+ this.end = new Date(end.getTime());
+ }
+
+ //자바의 직렬화 시스템이 바깥 클래스의 인스턴스 말고 SerializationProxy의 인스턴스를 반환하게 하는 역할
+ //이 메서드 덕분에 직렬화 시스템은 바깥 클래스의 직렬화된 인스턴스를 생성해낼 수 없다
+ //"프록시야 너가 대신 직렬화되라"
+ private Object writeReplace() {
+ return new SerializationProxy(this);
+ }
+
+ //불변식을 훼손하고자 하는 시도를 막을 수 있는 메서드
+ //"Period 인스턴스로 역직렬화를 하려고해? 안돼"
+ private void readObject(ObjectInputStream stream) throws InvalidObjectException {
+ throw new InvalidObjectException("프록시가 필요합니다");
+ }
+
+ //바깥 클래스의 논리적 상태를 정밀하게 표현하는 중첩 클래스(Period의 직렬화 프록시)
+ private static class SerializationProxy implements Serializable {
+
+ private static final long serialVersionUID = 234098243823485285L;
+
+ private final Date start;
+ private final Date end;
+
+ //생성자는 단 하나여야 하고, 바깥 클래스의 인스턴스를 매개변수로 받고 데이터를 복사해야 함
+ SerializationProxy(Period p) {
+ this.start = p.start;
+ this.end = p.end;
+ }
+
+ //역직렬화시 직렬화 시스템이 직렬화 프록시를 다시 바깥 클래스의 인스턴스로 변환하게 해줌.
+ //역직렬화는 불변식을 깨뜨릴 수 있다는 불안함이 있는데,
+ //이 메서드가 불변식을 깨뜨릴 위험이 적은 정상적인 방법(생성자, 정적 팩터리, 다른 메서드를 사용)으로 역직렬화된 인스턴스를 얻게 한다.
+ //"역직렬화 하려면 이거로 대신해"
+ private Object readResolve() {
+ return new Period(start, end);
+ }
+ }
+ }
+ ```
+
+### 직렬화 프록시 패턴의 한계?
+- 클라이언트가 조건없이 확장할 수 있는 클래스에는 적용할 수 없다.
+- 객체그래프 순환이 있는 클래스에는 적용할 수 없다.
+- 방어적 복사보다 느리다.
+
+
+## 결론
+- 확장할 수 없는 클래스라면 가능한 직렬화 프록시 패턴을 사용하자.
+
+