<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>codename_hee.log</title>
        <link>https://velog.io/</link>
        <description>진정한 개발자로 가는 길</description>
        <lastBuildDate>Thu, 16 Dec 2021 15:34:22 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>codename_hee.log</title>
            <url>https://images.velog.io/images/codename_hee/profile/cc7f87cb-a82a-4b24-a5db-f64bf7672796/KakaoTalk_20210913_220735445.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. codename_hee.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/codename_hee" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[JAVA 스터디] 15주차 : 람다식]]></title>
            <link>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-15%EC%A3%BC%EC%B0%A8-%EB%9E%8C%EB%8B%A4%EC%8B%9D</link>
            <guid>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-15%EC%A3%BC%EC%B0%A8-%EB%9E%8C%EB%8B%A4%EC%8B%9D</guid>
            <pubDate>Thu, 16 Dec 2021 15:34:22 GMT</pubDate>
            <description><![CDATA[<h3 id="학습할-것">학습할 것</h3>
<ul>
<li>람다식 사용법</li>
<li>함수형 인터페이스</li>
<li>Variable Capture</li>
<li>메소드, 생성자 레퍼런스</li>
</ul>
<h3 id="먼저-알고가기">먼저 알고가기</h3>
<h4 id="💡람다식이란">💡람다식이란?</h4>
<pre><code>int method() {
    return (int) (Math.random()*5) + 1;
}</code></pre><ul>
<li>위의 메소드를 아래와 같이 하나의 식으로 표현한 것<pre><code>int[] arr = new int[5];
Arrays.setAll(arr, (i) -&gt; (int)(Math.random()*5 + 1);</code></pre></li>
<li>람다식을 사용하지 않으면 메소드를 호출하기 위해 클래스를 새로 만들고 객체도 생성해야 했는데 람다식 자체만으로 메서드의 역할을 대신할 수 있게 되었다.</li>
<li>특정 람다식을 어떤 메서드의 매개변수 혹은 결과로 이용이 가능하다. =&gt; 메서드를 변수처럼 다룰 수 있게 되었다.</li>
<li>메소드를 람다식으로 표현하면 메소드의 이름과 반환값이 없으므로, 람다식을 <strong>&#39;익명 함수(anonymous function)&#39;</strong>이라고도 한다.</li>
</ul>
<h3 id="1-람다식-사용법">1. 람다식 사용법</h3>
<h4 id="람다식-작성방법">람다식 작성방법</h4>
<p><strong>case 1.</strong></p>
<pre><code>&lt;기존 메서드 작성 방법&gt;
반환타입 메서드이름(매개변수 선언) {
    문장들
}

&lt;람다식&gt;
(매개변수 선언) -&gt; {
    문장들
}</code></pre><ul>
<li>메소드에서 이름과 반환타입을 제거하고 매개변수 선언부와 몸통{} 사이에 &#39;-&gt;&#39; 화살표를 추가한다.</li>
</ul>
<p><strong>case 2.</strong></p>
<pre><code>&lt;반환값이 있는 메서드를 람다식으로 표현할 경우&gt;
(int a, int b) -&gt; {return a&gt;b ? a : b;}

(int a, int b) -&gt; a &gt; b ? a: b</code></pre><ul>
<li>반환값이 있는 메서드의 경우 return문 대신 식으로 대신 할 수 있다.</li>
<li>문장이 아닌 &#39;식&#39; 이므로 끝에 세미콜론(;)을 붙이지 않는다.</li>
</ul>
<p><strong>case 3.</strong></p>
<pre><code>(int a, int b) -&gt; a &gt; b ? a: b
(a, b) -&gt; a &gt; b ? a : b</code></pre><ul>
<li><strong>람다식에 선언된 매개변수의 타입은</strong> 추론이 가능한 경우는 생략할 수 있는데 <strong>대부분의 경우 생략가능</strong>하다.</li>
</ul>
<p><strong>case 4.</strong></p>
<pre><code>&lt;매개변수가 하나뿐일 경우&gt;
(a)  -&gt; a * a
a -&gt; a * a

&lt;매개변수의 타입이 있을 경우&gt;
(int a) -&gt; a * a</code></pre><ul>
<li>선언된 매개변수가 하나뿐일 경우 괄호()는 생략할 수 있다. (단, 매개변수의 타입이 있으면 괄호는 생략할 수 없다.)</li>
</ul>
<p><strong>case 5.</strong></p>
<pre><code>&lt;괄호{} 안의 문장이 하나일 경우&gt;
(String name, int i) -&gt; {
    System.out.println(name + &quot;=&quot;+i);
}
(String name, int i) -&gt; System.out.println(name + &quot;=&quot;+i);</code></pre><ul>
<li>괄호{} 안의 문장이 하나일 때는 괄호{}를 생략할 수 있다. 이 때, 문장의 끝에 &#39;;&#39;를 붙이지 않아야 한다.</li>
<li>그러나 괄호{} 안의 문장이 return문일 경우 괄호{}를 생략할 수 없다.</li>
</ul>
<h3 id="2-함수형-인터페이스">2. 함수형 인터페이스</h3>
<pre><code>// 1
(int a, int b) -&gt; a &gt; b ? a : b

// 2
new Object() {
    int max(int a, int b) {
        return a &gt; b ? a : b;
    }
}</code></pre><p>람다식은 메소드와 동등한 것처럼 보이지만, 사실 람다식은 익명 클래스의 객체와 동등하다.
위의 익명 객체의 메소드를 어떻게 호출할 수 있을까?
참조변수가 있어야 객체의 메소드를 호출 할 수 있으니 일단 익명 객체의 주소를 f라는 참조변수에 저장하자.</p>
<pre><code>타입 f = (int a, int b) -&gt; a &gt; b ? a : b;   // 참조변수의 타입을 뭘로 해야 할까?</code></pre><p>참조변수 f의 타입은 어떤 것이어야 할까? 참조형이므로 클래스 또는 인터페이스가 가능하다.
그리고 람다식과 동등한 메소드가 정의되어 있는 것이어야 한다. 그래야 참조변수로 익명 객체(람다식)의
메소드를 호출할 수 있기 때문이다.
예를 들어 max()라는 메소드가 정의된 MyFunction 인터페이스가 있다고 가정하자.</p>
<pre><code>interface MyFunction {
    public abstract int max(int a, int b);
}</code></pre><p>위의 인터페이스를 구현한 익명 클래스의 객체는 아래와 같이 생성할 수 있다.</p>
<pre><code>MyFunction f = new Myfunction() {
                public int max(int a, int b) {
                    return a &gt; b ? a : b;
                }
            };

int big = f.max(5, 3);      //  익명 객체의 메소드 호출</code></pre><ul>
<li>MyFunction 인터페이스에 정의된 메소드 max()는 람다식 &#39;(a, b) -&gt; a &gt; b ? a : b&#39;와 메소드 선언부가 일치한다.<br>따라서, 위 코드의 익명 객체를 아래와 같이 람다식으로 변경할 수 있다.<pre><code>MyFunction f = (a, b) -&gt; a &gt; b ? a : b; // 익명 객체를 람다식으로 대체
int big = f.max(5, 3);  //   익명 객체 메소드 호출</code></pre>👉 익명 객체를 람다식으로 대체 가능한 이유?
람다식도 실제로는 익명 객체이고, MyFunction 인터페이스를 구현한 익명 객체의 메소드 max()와
람다식의 매개변수 타입과 개수 그리고 반환값이 일치하기 때문이다.</li>
</ul>
<p>위에서 봤듯이 하나의 메소드가 선언된 인터페이스를 정의해서 람다식을 다루는 것은 기존의 자바 규칙을
어기지 않으면서도 자연스럽다.
그래서 인터페이스를 통해 람다식을 다루기로 결정됐고, 람다식을 다루기 위한 인터페이스를
함수형 인터페이스(functional interface) 라고 부르기로 했다.</p>
<pre><code>@FunctionalInterface
interface MyFunction {  // 함수형 인터페이스 MyFunction을 의미
    public abstract int max(int a, int b);
}</code></pre><ul>
<li>함수형 인터페이스에는 오직 하나의 추상 메소드만 존재 해야 한다.<br>그래야만, 람다식과 인터페이스의 메소드가 1:1로 연결될 수 있음.   </li>
<li>static 메소드와 default 메소드의 개수에는 제약이 없다.<br>💡 @FunctionalInterface를 붙이면, 컴파일러가 함수형 인터페이스를 올바르게 정의하였는지 확인하므로, 꼭 붙이자.</li>
</ul>
<h4 id="매개변수와-반환타입">매개변수와 반환타입</h4>
<pre><code>@FunctionalInterface
interface MyFunction {
    void myMethod();        // 추상메소드
}</code></pre><p>메소드의 매개변수가 MyFunction 타입이면, 이 메소드를 호출할 때 람다식을 참조하는 참조변수를
매개변수로 지정해야한다는 뜻이다.</p>
<pre><code>void aMethod(MyFunction f) {
    f.myMethod();
}

MyFunction f = () -&gt; System.out.println(&quot;myMethod()&quot;);
aMethod(f);</code></pre><p>또는 참조변수 없이 아래와 같이 직접 람다식을 매개변수로 지정할 수도 있다.</p>
<pre><code>aMethod() -&gt; System.out.println(&quot;myMethod()&quot;);</code></pre><p>메소드의 반환타입이 함수형 인터페이스라면, 그 함수형 인터페이스의 추상메소드와 동등한 람다식을
가리키는 참조변수를 반환하거나, 람다식을 직접 반환 할 수 있다.</p>
<pre><code>MyFunction myMethod() {
    MyFunction f = () -&gt; {};
    return f;               //  두 줄을 한 줄로 줆이면, return () -&gt; {};
}</code></pre><p>다음은 위에서 설명한 것들을 사용한 함수형 인터페이스와 람다식 예제이다.</p>
<pre><code>@FunctionalInterface
interface MyFunction {
    void run();     // public abstract void run();
}

public class LambdaEx1 {
    static void execute(MyFunction f) {
        f.run();
    }

    static MyFunction getMyFunction () {
        return () -&gt; System.out.println(&quot;f3.run()&quot;);
    }

    public static void main(String[] args) {
        MyFunction f1 = () -&gt; System.out.println(&quot;f1.run()&quot;);

        MyFunction f2 = new MyFunction() {
            @Override
            public void run() {
                System.out.println(&quot;f2.run()&quot;);
            }
        };

        MyFunction f3 = getMyFunction();

        f1.run();
        f2.run();
        f3.run();

        execute(f1);
        execute(() -&gt; System.out.println(&quot;run()&quot;));

    }
}</code></pre><pre><code>// 결과
f1.run()
f2.run()
f3.run()
f1.run()
run()</code></pre><h4 id="람다식-타입과-형변환">람다식 타입과 형변환</h4>
<p>람다식은 익명 객체이고 익명 객체는 타입이 없다.
따라서, 대입 연산자의 양변의 타입을 일치시키기 위해 형변환 이 필요하다.</p>
<pre><code>MyFunction f = (MyFunction)(() -&gt; {});</code></pre><ul>
<li>위의 람다식은 MyFunction 인터페이스를 직접 구현하지 않았지만, 인터페이스를 구현한 클래스의<br>객체와 동일하기 때문에, 위와 같은 형변환을 허용한다.   <ul>
<li>그리고 이 형변환은 생략가능하다.   <pre><code>Object obj = (Object)(() -&gt; {})     // ERROR. 함수형 인터페이스로만 형변환 가능</code></pre></li>
</ul>
</li>
<li>Object 타입으로는 형변환 할 수 없다.   </li>
<li>오직 함수형 인터페이스로만 형변환 가능한다.<br>굳이 Object 타입으로 형변환하려면, 먼저 함수형 인터페이스로 변환해야 한다.<pre><code>Object obj = (Object)(MyFunction)(() -&gt; {});
String str = ((Object)(MyFunction)(() -&gt; {})).toString();</code></pre></li>
</ul>
<h4 id="javautilfunction-패키지">java.util.function 패키지</h4>
<ul>
<li>java.util.function 패키지에 일반적으로 자주 쓰이는 형식의 메소드를 함수형 인터페이스가 미리 정의되어 있다.
<img src="https://images.velog.io/images/codename_hee/post/33c2fa6f-919d-4a50-bb2a-2cd066097004/image.png" alt=""></li>
</ul>
<p><img src="https://images.velog.io/images/codename_hee/post/9d3302e3-bdfa-4924-8a7e-6ac94e972665/image.png" alt=""></p>
<ul>
<li>매개변수의 타입과 반환타입의 타입이 모두 일치한다는 점을 제외하고는 function과 같다.</li>
</ul>
<h3 id="3-variable-capture">3. Variable Capture</h3>
<p>람다식에서 외부 지역변수를 참조하는 행위를 Lambda Capturing(람다 캡쳐링)이라고 한다.
람다에서 접근가능한 변수는 아래와 같이 세가지 종류가 있다.</p>
<ol>
<li>지역 변수   </li>
<li>static 변수   </li>
<li>인스턴스 변수   </li>
</ol>
<ul>
<li>지역변수만 변경이 불가능하고 나머지 변수들은 읽기 및 쓰기가 가능하다.</li>
<li>람다는 지역 변수가 존재하는 스택에 직접 접근하지 않고, 지역 변수를 자신(람다가 동작하는 쓰레드)의 스택에 복사한다.</li>
<li>각각의 쓰레드마다 고유한 스택을 갖고 있어서 지역 변수가 존재하는 쓰레드가 사라져도 람다는 복사된 값을 참조하면서 에러가 발생하지 않는다.</li>
</ul>
<p>그런데 멀티 쓰레드 환경이라면, 여러 개의 쓰레드에서 람다식을 사용하면서 람다 캡쳐링이 계속 발생하는데
이 때 외부 변수 값의 불변성을 보장하지 못하면서 동기(sync)화 문제가 발생한다.
이러한 문제로 지역변수는 final, Effectively Final 제약조건을 갖게된다.</p>
<p>인스턴스 변수나 static 변수는 스택 영역이 아닌 힙 영역에 위치하고, 힙 영역은 모든 쓰레드가 공유하고 있는 메모리 영역이기 때문에, 값의 쓰기가 발생하여도 별 문제가 없는 것이다.</p>
<p>💡 Effectively Final
람다식 내부에서 외부 지역변수를 참조하였을때 지역 변수는 재할당을 하지 않아야 하는 것을 의미한다.</p>
<p>다음 예제로 살펴보자.</p>
<pre><code>@FunctionalInterface
interface MyFunction3 {
    void myMethod();
}

class Outer {
    int val = 10;

    class Inner {
        int val = 20;

        void method(int i) {    // void method(final int i)
            int val = 30;   // final int val = 30;
//            i = 10;       // ERROR. 상수의 값은 변경할 수 없다.

            MyFunction3 f = () -&gt; {
                System.out.println(&quot;             i : &quot; + i);
                System.out.println(&quot;           val : &quot; + val);
                System.out.println(&quot;      this.val : &quot; + ++this.val);
                System.out.println(&quot;Outer.this.val : &quot; + ++Outer.this.val);
            };

            f.myMethod();
        }
    } // End Of Inner
}   // End Of Outer

public class LambdaEx3 {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
        inner.method(100);
    }
}</code></pre><pre><code>// 결과
             i : 100
           val : 30
      this.val : 21
Outer.this.val : 11</code></pre><ul>
<li>람다식 내에서 참조하는 지역변수는 final이 붙지 않아도 상수로 간주된다.   </li>
<li>람다식 내에서 지역변수 i와 val을 참조하고 있으므로 람다식 내에서나 다른 곳에서도 이 변수들의 값을 변경할 수 없다.   </li>
<li>반면, Inner 클래스와 Outer 클래스의 인스턴스 변수인 this.val과 Outer.this.val은 상수로 간주되지 않아서 값을 변경해도 된다.   </li>
<li>람다식에서 this는 내부적으로 생성되는 익명 객체의 참조가 아니라 람다식을 실행한 객체의 참조다.<br>따라서 위의 코드에서 this는 중첩 객체인 Inner이다. </li>
</ul>
<h3 id="4-메소드-생성자-레퍼런스">4. 메소드, 생성자 레퍼런스</h3>
<h4 id="메소드-참조">메소드 참조</h4>
<p>람다식이 하나의 메소드만 호출하는 경우에는 &#39;메소드 참조(method reference)&#39;를 통해
람다식을 간략하게 작성할 수 있다.
메소드 참조를 작성하는 방법은 아래처럼 간단하다.</p>
<p>클래스이름::메소드이름
or
참조변수::메소드이름</p>
<pre><code>Function&lt;String, Integer&gt; f = s -&gt; Integer.parseInt(s);</code></pre><p>보통 위처럼 람다식을 작성하는데, 이 람다식을 메소드로 표현하면 아래와 같다.</p>
<pre><code>Integer wrapper(String s) { //  이 메소드의 이름은 의미없음. 테스트용
    return Integer.parseInt(s);
}</code></pre><p>이 wrapper 메소드는 별로 하는 일이 없다. 값을 받아서 Integer.parseInt()에게 넘겨줄 뿐.
차라리 Integer.parseInt()를 직접 호출하는게 낫지 않을까???</p>
<pre><code>Function&lt;String, Integer&gt; f = s -&gt; Integer.parseInt(s);

// 메소드 참조
Function&lt;String, Integer&gt; f = Integer::parseInt;</code></pre><p>메소드 참조를 이용하면 더 간략하게 작성할 수 있다.
위 메소드 참조에서 람다식 일부가 생략되었지만, 컴파일러는 생략된 부분을 우변의 parseInt 메소드의 선언부로부터,
또는 좌변의 Function 인터페이스에 지정된 제네릭 타입으로부터 쉽게 알아낸다.
또 다른 예를 보자.</p>
<pre><code>BiFunction&lt;String, String, Boolean&gt; f = (s1, s2) -&gt; s1.equlas(s2);</code></pre><p>위 람다식에서 어떤 부분을 변경할 수 있을까?</p>
<ul>
<li>참조변수 f의 타입으로 유추하면 람다식이 두 개의 String 타입의 매개변수를 받는다. 따라서, 매개변수 생략가능.   </li>
<li>매개변수를 생락하면, equals만 남는데, 두 개의 String을 받아서 Boolean을 반환하는 equals라는 메소드 이므로<br>String::equals로 변경한다.   <pre><code>BiFunction&lt;String, String, Boolean&gt; f = String::equals;</code></pre>메소드 참조로 변경한 결과이다.<pre><code>MyClass obj = new MyClass();
Function&lt;String, Boolean&gt; f = x -&gt; obj.equals(x);   //  람다식
Function&lt;String, Boolean&gt; f2 = obj::equals;         //  메소드 참조</code></pre>메소드 참조를 사용하는 경우가 한 가지 더 있는데, 이미 생성된 객체의 메서드를 람다식에서 사용한 경우에는
클래스 이름 대신 그 객체의 참조변수를 적어야 한다.
메소드 참조를 정리하면 다음과 같다.</li>
</ul>
<h4 id="생성자의-메소드-참조">생성자의 메소드 참조</h4>
<p>생성자를 호출하는 람다식도 메소드 참조로 변환할 수 있다.</p>
<pre><code>Supplier&lt;MyClass&gt; s = () -&gt; new MyClass();      //  람다식
Supplier&lt;MyClass&gt; s = MyClass:new;              //  메소드 참조</code></pre><p>매개변수가 있는 생성자라면, 매개변수의 개수에 따라 알맞은 함수형 인터페이스를 사용하면 된다.</p>
<pre><code>Function&lt;Integer, MyClass&gt; f = i -&gt; new MyClasS(i);     //  람다식
Function&lt;Integer, MyClass&gt; f = MyClass:new;             //  메소드 참조

BiFunction&lt;Integer, String, MyClass&gt; bf = (i, s) -&gt; new MyClass(i, s);  //  람다식
BiFunction&lt;Integer, String, MyClass&gt; bf = MyClass::new;                 //  메소드 참조</code></pre><p>만약 배열을 생성할 때는 다음과 같이 사용한다.</p>
<pre><code>Function&lt;Integer, int[]&gt; f = x -&gt; new int[x];   //  람다
Function&lt;Integer, int[]&gt; f2 = int[]::new;       //  메소드 참조</code></pre><h4 id="예제">예제</h4>
<p>메소드 참조를 연습하여 사용해보자.
처음에는 익숙하지 않아서 조금 헷갈릴 수 있지만 몇 번 사용하면 금방 손에 익는다.</p>
<pre><code>public class MethodReferences {
    public static void main(String[] args) {
//        Function&lt;String, Integer&gt; f = s -&gt; Integer.parseInt(s);
        Function&lt;String, Integer&gt; f = Integer::parseInt;

        System.out.println(f.apply(&quot;100&quot;) + 200);

        // Supplier 입력 X, 출력 O
//        Supplier&lt;MyClass&gt; s = () -&gt; new MyClass();
        Supplier&lt;MyClass&gt; s = MyClass::new;
        System.out.println(s.get());

        Function&lt;Integer, MyClass&gt; f2 = MyClass::new;
        MyClass m = f2.apply(100);
        System.out.println(m.iv);
        System.out.println(f2.apply(200).iv);

        Function&lt;Integer, int[]&gt; f3 = int[]::new;
        System.out.println(f3.apply(10).length);

    }
}

class MyClass {
    int iv;

    MyClass () {}

    MyClass (int iv) {
        this.iv = iv;
    }
}</code></pre><pre><code>// 결과
300
MyClass@5fd0d5ae
100
200
10</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA 스터디] 12주차 : @Annotation]]></title>
            <link>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-12%EC%A3%BC%EC%B0%A8-Annotation</link>
            <guid>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-12%EC%A3%BC%EC%B0%A8-Annotation</guid>
            <pubDate>Tue, 07 Dec 2021 10:58:06 GMT</pubDate>
            <description><![CDATA[<h3 id="학습할-것">학습할 것</h3>
<ul>
<li>어노테이션 정의하는 방법</li>
<li>@retention</li>
<li>@target</li>
<li>@documented</li>
<li>어노테이션 프로세서</li>
</ul>
<h3 id="먼저-알고가기">먼저 알고가기</h3>
<h4 id="어노테이션이란">어노테이션이란?</h4>
<ul>
<li>프로그램의 소스코드 안에 다른 프로그램을 위한 정보를 미리 약속된 형식으로 포함시킨 것</li>
<li>메타데이터. 어플리케이션이 처리하는 데이터가 아닌 컴파일 과정과 실행 과정에서 코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 정보<h4 id="어노테이션의-용도">어노테이션의 용도</h4>
</li>
<li>컴파일러에게 코드 문법 에러를 체크하도록 정보를 제공
소프트웨어 개발 툴이 빌드나 배치 시 코드를 자동으로 생성할 수 있도록 정보를 제공</li>
<li>실행 시(런타임 시)특정 기능을 실행하도록 정보를 제공<h4 id="특징">특징</h4>
</li>
<li>주석처럼 프로그래밍 언어에 영향을 미치지 않으면서도 다른 프로그램에게 유용한 정보를 제공할 수 있다는 장점이 있다.<ul>
<li>예를 들어, 소스코드 중 특정 메서드만 테스트하길 원할 경우, 해당 코드에 &#39;@Test&#39; 라는 어노테이션을 붙이면 테스트 프로그램에게 해당 메서드는 테스트를 해야한다는 것을 알릴 뿐 메서드가 포함된 전체 프로그램 자체에는 해당 어노테이션이 아무런 영향을 미치지 않는다.</li>
</ul>
</li>
<li>JDK에서 제공하는 표준 어노테이션은 주로 컴파일러를 위한 것으로 컴파일러에게 유용한 정보를 제공</li>
<li>새로운 어노테이션을 정의할 때 사용하는 메타 어노테이션도 제공</li>
</ul>
<h4 id="어노테이션의-종류">어노테이션의 종류</h4>
<ul>
<li><strong>Built-in Annotation</strong> : 자바에서 기본적으로 제공하는 어노테이션</li>
<li><strong>Meta Annotation</strong> : 커스텀 어노테이션을 만들수 있게 제공된 어노테이션.</li>
<li><strong>Custome Annotation</strong> : 사용자가 직접 정의한 어노테이션</li>
</ul>
<p><strong>1. Built-in Annotation</strong>
<img src="https://images.velog.io/images/codename_hee/post/aebafec4-aa6d-4d1d-96c2-f1d6c1f41f43/image.png" alt=""></p>
<p><strong>2. Meta Annotation</strong>
<img src="https://images.velog.io/images/codename_hee/post/cb3c4647-5074-4f1d-90d3-fc1f496d3c95/image.png" alt=""></p>
<h3 id="어노테이션을-정의하는-방법">어노테이션을 정의하는 방법</h3>
<ul>
<li>인터페이스를 정의하는 것과 유사하게 다음과 같이 @interface를 사용해서 정의한다.<pre><code>public @interface AnnotaionName{
}</code></pre></li>
<li>엘리먼트(element)를 멤버로 가질 수 있다.<pre><code>public @interface AnnotationName {
  String elementName1(); #=&gt; 값이 없으므로 반드시 값을 기술해야 함
  int elementName2() default 5; #=&gt; 디폴트 값이 있으므로 생략 가능
}</code></pre><pre><code>&lt;위의 어노테이션을 사용할 때&gt;
@AnnotationName(elementName1 = &quot;값&quot;, elementName2 = 3);
또는
@AnnotationName(elementName1 = &quot;값&quot;);</code></pre><pre><code>&lt;기본 엘리먼트가 포함된 어노테이션 선언&gt;
public @interface AnnotationName {
  String value(); #=&gt; 기본 element 선언
  int elementName() default 5;
}</code></pre><pre><code>&lt;Value 엘리먼트를 가진 어노테이션을 적용하는 방법&gt;
@AnnotationName(&quot;값&quot;); #=&gt; value자리에 값이 설정되는 것
</code></pre></li>
</ul>
<p>#value엘리먼트와 다른 엘리먼트의 값을 동시에 주고싶다면
@AnnotationName(value = &quot;값&quot;, elementName=3);</p>
<pre><code>- 메타 어노테이션을 사용하여 어노테이션이 적용되는 대상이나 유지기간 등을 지정한다.
- &#39;@&#39;를 이용하여 선언한다.


#### 메타 어노테이션이란?
- 어노테이션을 위한 어노테이션
- 어노테이션에 붙이는 어노테이션

| 어노테이션 | 설명 |
| --- | --- |
| @Target | 어노테이션이 적용가능한 대상을 지정하는데 사용한다. |
| @Documented | 어노테이션 정보가 javadoc으로 작성된 문서에 포함되게 한다. |
| @Inherited | 어노테이션이 자손 클래스에 상속되도록 한다. |
| @Retention | 어노테이션이 유지되는 범위를 지정하는데 사용한다. |
| @Repeatable | 어노테이션을 반복해서 적용할 수 있게 한다. (JDK 1.8) |

#### @Retention
- 어노테이션이 유지되는 기간을 지정하는데 사용된다.

&lt;어노테이션의 유지 정책&gt;

| 유지 정책 | 의미 |
| --- | --- |
| SOURCE | 소스 파일에만 존재. 클래스파일에는 존재하지 않음. |
| CLASS | 클래스 파일에 존재. 실행시에 사용불가. 기본값 |
| RUNTIME | 클래스 파일에 존재. 실행시에 사용가능. |
- SOURCE : 컴파일러가 사용하는 어노테이션. 컴파일러를 직접 작성할 것이 아니면 해당 유지정책은 필요 없다.
- RUNTIME : 실행 시에 리플렉션(reflection)을 통해 클래스 파일에 저장된 어노테이션의 정보를 읽어서 처리할 수 있다. 
*Reflection : 런타임 시에 클래스의 메타 정보를 얻는 기능. 클래스의 필드가 무엇인지 어떤 생성자를 가지고 있는지 어떤 메소드를 가지고 있는지 적용된 어노테이션이 무엇인지를 알아내는 것.
=&gt; 런타임 시에 어노테이션 정보를 얻으려면 어노테이션 유지 정책을 RUNTIME으로 해야 한다.
- CLASS : 컴파일러가 어노테이션의 정보를 클래스 파일에 저장할 수 있게는 하지만 클래스 파일이 JVM에 로딩될 때에는 어노테이션의 정보가 무시되어 실행 시에 어노테이션에 대한 정보를 얻을 수 없다. 

#### @Target
- 어노테이션이 적용가능한 대상을 지정하는데 사용된다.</code></pre><p>&lt;@SuppressWarnings 어노테이션을 정의하는 예&gt;
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}</p>
<pre><code>- &#39;@Target&#39;으로 지정할 수 있는 어노테이션 적용대상의 종류

| 대상 타입 | 의미 |
| --- | --- |
| ANNOTATION_TYPE | 어노테이션 |
| CONSTRUCTOR | 생성자 |
| FIELD | 필드(멤버변수, ENUM상수) |
| LOCAL_VARIABLE | 지역변수 |
| METHOD | 메서드 |
| PACKAGE | 패키지 |
| PARAMETER | 매개변수 |
| TYPE | 타입(클래스, 인터페이스, ENUM) |
| TYPE_PARAMETER | 타입 매개변수(JDK 1.8) |
| TYPE_USE | 타입이 사용되는 모든 곳(JDK 1.8) |
- TYPE : 타입을 선언할 때 어노테이션을 붙일 수 있다는 뜻
- TYPE_USE : 해당 타입의 변수를 선언할 때 붙일 수 있다는 뜻

#### @Documented
- 어노테이션에 대한 정보가 javadoc으로 작성한 문서에 포함되도록 한다.
- 자바에서 제공하는 기본 어노테이션 중에 &#39;@Override&#39;, &#39;@SuppressWarnings&#39;를 제외하고는 모두 이 메타 어노테이션이 붙어 있다.

#### 위의 세가지 어노테이션이 적용된 코드의 예시</code></pre><p>@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}</p>
<p>```</p>
<h3 id="어노테이션-프로세서">어노테이션 프로세서</h3>
<ul>
<li>컴파일 타임에 어노테이션을 분석하는 단계.</li>
<li>어노테이션을 이용하여 새로운 리소스르 생성해낼 수 있는 방법 및 과정</li>
</ul>
<h4 id="프로세싱-과정">프로세싱 과정</h4>
<ol>
<li>어노테이션 클래스를 생성한다.</li>
<li>어노테이션 파서 클래스(Annotation Parser Class)를 생성한다.</li>
<li>어노테이션을 사용한다.</li>
<li>컴파일하면, 어노테이션 파서가 어노테이션을 처리한다.</li>
<li>자동 생성된 클래스가 빌드 폴더에 추가된다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA 스터디] 9주차 : 예외처리]]></title>
            <link>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-9%EC%A3%BC%EC%B0%A8-%EC%98%88%EC%99%B8%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-9%EC%A3%BC%EC%B0%A8-%EC%98%88%EC%99%B8%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Fri, 12 Nov 2021 10:25:10 GMT</pubDate>
            <description><![CDATA[<h3 id="학습할-것">학습할 것</h3>
<ul>
<li>자바에서 예외 처리 방법(try, catch, throw, throws, finally)</li>
<li>자바가 제공하는 예외 계층 구조</li>
<li>Exception과 Error의 차이는?</li>
<li>RuntimeException과 RE가 아닌 것의 차이는?</li>
<li>커스텀한 예외 만드는 방법</li>
</ul>
<h3 id="먼저-알고가기">먼저 알고가기</h3>
<h4 id="자바의-에러">자바의 에러</h4>
<ul>
<li>컴파일 에러<ul>
<li>컴파일 과정에서 일어나는 에러</li>
<li>자바 컴파일러가 문법 검사를 통해 오류를 잡아준다.</li>
</ul>
</li>
<li>런타임 에러<ul>
<li>실행 과정에서 일어나는 에러</li>
<li>자바는 런타임 에러를 예외(Exception)과 에러(Error) 두 가지로 구분하여 대응하고 있다.</li>
</ul>
</li>
</ul>
<h4 id="예외와-에러">예외와 에러</h4>
<ul>
<li>예외<ul>
<li>발생 시의 코드를 미리 정의함으로써 프로그래머가 이를 핸들링 할 수 있다.</li>
</ul>
</li>
<li>에러<ul>
<li>메모리 부족(OutOfMemoryError), 스택오버플로우(StackOverFlowError)처럼 JVM이나 하드웨어 등의 기반 시스템의 문제로 발생하는 것</li>
<li>프로그래머가 이를 대비하여 핸들링 할 수 없기 때문에 애초에 발생하지 않도록 해야 한다.</li>
</ul>
</li>
</ul>
<h4 id="예외-처리란">예외 처리란?</h4>
<ul>
<li>프로그램에서 예외가 발생했을 경우 프로그램의 갑작스러운 종료를 막고 정상 실행을 유지할 수 있도록 코드를 통해 처리하는 것</li>
</ul>
<h3 id="1-자바의-예외-처리-방법-기법try-catch-throw-throws-finally">1. 자바의 예외 처리 방법, 기법(try, catch, throw, throws, finally)</h3>
<h4 id="1-try---catch">1) try - catch</h4>
<pre><code>&lt;try-catch&gt;문의 기본 구조

try {
...
} catch (예외1) {
...
} catch (예외2) {
....
} finally {
    System.out.println(&quot;이건 반드시 실행되어야 합니다.&quot;);
}</code></pre><ul>
<li>try문 안의 수행할 문장들에서 예외가 발생하지 않을 경우 catch문 다음의 문장들은 수행되지 않는다.</li>
<li>try문 안의 문장들을 수행 중 해당 예외가 발생하면 예외에 해당되는 catch문이 수행된다.</li>
</ul>
<h4 id="2-finally">2) finally</h4>
<ul>
<li>try - catch과 함께 쓰이고 어떤 예외가 발생되더라도 반드시 실행되어야 하는 부분이 있을 때 사용할 수 있는 블록</li>
<li>예외 발생 여부와 상관없이 항상 실행할 내용이 있을 경우 사용한다.</li>
</ul>
<h4 id="3-throw">3) throw</h4>
<ul>
<li>프로그래머가 고의로 예외를 발생시키고자 할 때 사용할 수 있는 키워드<pre><code>&lt;throw 사용 예시&gt;
</code></pre></li>
</ul>
<p>if () {
    throw new IllegalArgumentException(&quot;부적절한 이름입니다.&quot;);
    // throw new IllegalArgumentException 구문을 풀어 쓴 경우
    // IllegalArgumentException e = new IllegalArgumentException(&quot;부적절한 이름입니다.&quot;);
    // throw e;
    }</p>
<pre><code>
#### 4) throws
- 메서드에 예외를 선언하고자 할 때 사용할 수 있는 키워드
- 메서드의 선언부에 예외를 선언해둠으로써 메서드를 사용하는 사람이 해야하는 예외 처리가 어떤 것이 있는 지에 대해 정보를 제공하고 예외 처리를 &#39;위쪽으로 미루어 처리&#39;한다.
- 해당 메서드를 사용할 경우 사용하는 쪽에서 반드시 throws 되어 있는 예외들을 처리해주어야 한다.</code></pre><p>&lt;throws 사용 예시&gt;
// 메소드 호출
public static void main(String[] args) {
    SayHello sayHello = new SayHello();</p>
<pre><code>try {
    sayHello.sayHello();
} catch (Exception1 e) {
    System.out.println(&quot;예외가 발생하였습니다&quot;);
}</code></pre><p>}</p>
<p>// 메소드 선언
public static void sayHello() throws Exception1, Exception2..ExceptionN {
//....
}</p>
<pre><code>### 2. 자바가 제공하는 예외 계층 구조
![](https://images.velog.io/images/codename_hee/post/b0b125de-9109-4329-9004-96180957c365/%EC%98%88%EC%99%B8%20%EC%B2%98%EB%A6%AC%20%EA%B5%AC%EC%A1%B0.png)


#### Throwable 클래스
- 모든 예외와 에러 클래스들의 조상이 되는 클래스
- 예외나 에러에 대한 정보를 확인할 수 있는 메소드를 가진다.
    - getMessage() : 해당 throwable 객체에 대한 자세한 내용을 반환
    - printStackTrace() : 예외나 에러가 발생 할 때까지의 이력을 출력
    - toString() : 해당 throwable 객체의 간단한 내용을 반환


### 3. Exception과 Error의 차이
#### Exception
- 프로그램 실행중 발생한다.
- 프로그래머가 예외를 처리하는 코드를 작성함으로써 방지가 가능하다.
- 프로그램에서 복구할 수 있는 장애를 말한다.
#### Error
- 실행 시 어떠한 원인에 의해 비정상적인 상황이 생겼거나 오작동, 종료되는 경우
- 프로그램에서 복구할 수 없는 심각한 장애를 말한다.
- 보통의 JVM이나 기타 하드웨어 등의 시스템 문제로 발생한다.
- Error가 발생하면 프로그램이 비정상적으로 종료된다.
- OutofMemory, StackOverFlow, ThreadDeath등이 있다.
- 런타임 시 발생하며 예측이 불가능한 Unchecked Error에 속한다. 코드를 수정하지 않고서는 문제를 해결할 수 없다.

### 4. RuntimeException과 RE가 아닌 것의 차이
- Java의 Exception 클래스는 RuntimeException과 이를 상속하는 클래스들은 Unchecked Exception으로, 그 외 Exception 클래스의 자식 클래스들은 Checked Exception으로 분류할 수 있다.
- 둘의 차이는 아래 표의 내용과 같다.
![](https://images.velog.io/images/codename_hee/post/5b73fa02-6922-4193-9112-181f3108ce89/image.png)
#### Unchecked Exception
- RuntimeException을 상속하는 예외들을 말한다.
- 명시적으로 예외처리를 강제하지 않는다.
- 프로그램에 오류가 있을 때 발생하도록 의도되었다.

#### Checked Exception
- RuntimeException을 상속하지 않는 예외들을 말한다.
- try - catch문을 사용하거나 throws로 예외를 자신을 호출한 클래스로 던지는 방법으로 반드시 예외를 처리해주어야 한다.
- 그렇지 않으면 컴파일 시점에 에러가 발생한다.

### 5. 커스텀한 예외 만드는 방법
- 최상위 클래스인 Exception을 상속받아(extends) Checked Exception을 구현한다.
- RuntimeException을 상속받아 Unchecked Exception을 구현한다.
#### Checked Exception 예시</code></pre><p>/*</p>
<ul>
<li><p>이것은 커스텀 CheckedException 입니다.</p>
</li>
<li><p>자바의 기본 예외로 표현할 수 없는 예외를 제공하기 위해 만들어졌습니다. </p>
</li>
<li><p>*/
public class CustomCheckedExceptionEx extends Exception {</p>
<p>  public CustomCheckedExceptionEx() {
  }</p>
<p>  public CustomCheckedExceptionEx(String message) {</p>
<pre><code>  super(message);</code></pre><p>  }</p>
<p>  public CustomCheckedExceptionEx(String message, Throwable cause) {</p>
<pre><code>  super(message, cause);</code></pre><p>  }</p>
<p>  public CustomCheckedExceptionEx(Throwable cause) {</p>
<pre><code>  super(cause);</code></pre><p>  }</p>
<p>  public CustomCheckedExceptionEx(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {</p>
<pre><code>  super(message, cause, enableSuppression, writableStackTrace);</code></pre><p>  }
}</p>
</li>
</ul>
<p>class CustomCheckedExceptionTest {
    public static void main(String[] args) throws CustomCheckedExceptionEx {
        try {
            // doSomething
        } catch (Exception e) {
            throw new CustomCheckedExceptionEx(&quot;커스텀 체크드 예외 발생!!&quot;, e);
        }
    }
}</p>
<pre><code>
#### Unchecked Exception 예시</code></pre><p>public class CustomUncheckedException extends RuntimeException {</p>
<pre><code>public CustomUncheckedException() {
}

public CustomUncheckedException(String message) {
    super(message);
}

public CustomUncheckedException(String message, Throwable cause) {
    super(message, cause);
}

public CustomUncheckedException(Throwable cause) {
    super(cause);
}

public CustomUncheckedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
}</code></pre><p>}</p>
<p>class CustomUncheckedExceptionTest {
    public static void main(String[] args) {
        try {
            // doSomething
        } catch (RuntimeException e) {
            throw new CustomUncheckedException(&quot;커스텀 언체크드 예외 발생!!&quot;, e);
        }
    }
}</p>
<p>```</p>
<p>[참고]
<a href="https://parkadd.tistory.com/69">https://parkadd.tistory.com/69</a>
<a href="https://zannew.tistory.com/23">https://zannew.tistory.com/23</a>
<a href="https://velog.io/@zayson/%EB%B0%B1%EA%B8%B0%EC%84%A0%EB%8B%98%EA%B3%BC-%ED%95%A8%EA%BB%98%ED%95%98%EB%8A%94-Live-Study-9%EC%A3%BC%EC%B0%A8-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC">https://velog.io/@zayson/%EB%B0%B1%EA%B8%B0%EC%84%A0%EB%8B%98%EA%B3%BC-%ED%95%A8%EA%BB%98%ED%95%98%EB%8A%94-Live-Study-9%EC%A3%BC%EC%B0%A8-%EC%98%88%EC%99%B8-%EC%B2%98%EB%A6%AC</a>
<a href="https://youn12.tistory.com/32">https://youn12.tistory.com/32</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Spring] JPA 영속성 컨텍스트]]></title>
            <link>https://velog.io/@codename_hee/Spring-JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@codename_hee/Spring-JPA-%EC%98%81%EC%86%8D%EC%84%B1-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Sun, 07 Nov 2021 16:06:06 GMT</pubDate>
            <description><![CDATA[<h3 id="사전-지식">사전 지식</h3>
<ol>
<li><p>객체로 되어있는 JAVA의 코드를 바로 DB에 적용할 수 없기 때문에 JPA(Java Persistence API)라는 표준 규약을 사용한다.
JAVA -&gt; JPA -&gt; DB</p>
</li>
<li><p>DB에 직접적으로 수정 혹은 삭제를 진행하게 되면 처리 중 오류가 발생하였을 때 DB의 정보가 원하는 방향으로 처리되지 않거나 정보들이 손상될 수 있다. 이를 해결하기 위해 JPA는 영속성 컨텍스트를 이용한다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA 스터디] 6주차 : 상속]]></title>
            <link>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-6%EC%A3%BC%EC%B0%A8-%EC%83%81%EC%86%8D</link>
            <guid>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-6%EC%A3%BC%EC%B0%A8-%EC%83%81%EC%86%8D</guid>
            <pubDate>Thu, 28 Oct 2021 11:22:36 GMT</pubDate>
            <description><![CDATA[<h2 id="학습-목표">학습 목표</h2>
<ul>
<li>자바 상속의 특징</li>
<li>super 키워드</li>
<li>메소드 오버라이딩</li>
<li>다이나믹 메소드 디스패치 (Dynamic Method Dispatch)</li>
<li>추상 클래스</li>
<li>final 키워드</li>
<li>Object 클래스</li>
</ul>
<h3 id="1-자바-상속의-특징">1. 자바 상속의 특징</h3>
<h4 id="자바에서-상속이란-무엇인가">자바에서 상속이란 무엇인가?</h4>
<ul>
<li>현실 세계에서 부모가 자식에게 재산을 &#39;상속&#39;한다고 하는 것처럼 객체 지향 프로그램에서도 <strong>부모가 자식에게 부모의 클래스나 메소드를 자식의 클래스에게 물려주는 경우</strong>를 상속이라고 한다.</li>
</ul>
<h4 id="자바-상속의-특징">자바 상속의 특징</h4>
<ul>
<li>공통된 특징을 가지는 클래스에서 코드 중복을 줄여준다.</li>
<li>부모 클래스의 멤버를 재사용하면서 자식 클래스는 간결해질 수 있다.</li>
<li>클래스간의 계층적 분리를 도와주어 분류, 관리 상의 이점이 있다.</li>
<li>부모 클래스는 Super Class이고 자식 클래스는 Sub Class이다.</li>
<li><strong>다중 상속을 지원하지 않는다</strong>. <strong>즉, extends뒤에는 하나의 부모 클래스만 올 수 있다</strong>.</li>
<li>상속 횟수에 제한이 없다. </li>
<li><strong>자바의 최상위 클래스는 &#39;Object&#39; 라는 클래스</strong>이다. 즉, 자바의 모든 클래스는 &#39;Object&#39;클래스의 자손이다.</li>
</ul>
<h4 id="상속-구현-방법">상속 구현 방법</h4>
<pre><code>&lt;자식 클래스의 부모 클래스 상속 방법&gt;
class 자식 클래스 extends 부모클래스 {
}

&lt;부모 클래스&gt;
public class TV {
    멤버 변수 1;
    멤버 변수 2;
    메소드1;
}

&lt;자식 클래스&gt;
public class LG extends TV {
    String tvType;
}</code></pre><h3 id="2-super-키워드">2. Super 키워드</h3>
<p>자바에서 자식 객체를 생성할 경우 부모 객체가 먼저 생성된 후 자식 객체가 생성된다.</p>
<h4 id="super-키워드란">super 키워드란?</h4>
<ul>
<li>상속관계에서 자식 클래스가 부모 클래스의 멤버 변수나 메소드를 참조하기 위해 사용된다.</li>
<li>자식 클래스에 부모 객체의 생성자를 임의로 지정하지 않았을 경우 <strong>자식 객체 생성시 컴파일러가 자동으로 &#39;super()&#39; 메소드를 통해 부모의 기본 생성자를 호출</strong>한다.</li>
<li>만약 부모 클래스에 기본 생성자가 없고 매개 변수가 있는 생성자만 있다면 자식 생성자의 첫 줄에 반드시 부모 생성자 호출을 위한 super() 메소드를 명시적으로 작성해두어야 한다. 그렇지 않을 경우 컴파일 에러가 발생한다.</li>
</ul>
<h3 id="3-메소드-오버라이딩">3. 메소드 오버라이딩</h3>
<h4 id="메소드-오버라이딩이란">메소드 오버라이딩이란?</h4>
<ul>
<li><strong>자식 클래스에서 부모 클래스를 상속 받은 후, 부모 클래스에 정의되어 있는 메소드를 재정의하여 사용하는 것</strong>이다.</li>
<li>부모 클래스 내의 특정 메소드는 자식 클래스에서 그대로 사용하기에 적합하지 않을 수 있기 때문에 보통 오버라이딩을 거쳐 부모 메소드를 사용하는 경우가 많다.</li>
<li>메소드가 오버라이딩 되면 자식 객체에서 메소드가 호출될 경우 부모 객체의 메소드는 숨겨지고, 오버라이딩된 자식 메소드가 호출된다.</li>
</ul>
<h4 id="오버라이딩-규칙override-어노테이션-사용">오버라이딩 규칙(@override 어노테이션 사용)</h4>
<ol>
<li><strong>오버라이딩된 자식 클래스의 메소드는 부모의 메소드와 &#39;메소드 이름, 매개 변수 조합, 리턴 타입&#39;이 동일해야 한다.</strong></li>
<li>접근 제한을 축소하여 오버라이딩 할 수 없다. 단, 반대는 가능하다.
(<strong>부모 메소드가 public인데 자식 메소드가 private일 수는 없다</strong>는 의미)</li>
<li>새로운 예외를 throw할 수 없다.</li>
</ol>
<h3 id="4-다이나믹-메소드-디스패치dynamic-method-dispatch">4. 다이나믹 메소드 디스패치(Dynamic method dispatch)</h3>
<h4 id="메소드-디스패치란">메소드 디스패치란?</h4>
<ul>
<li>자바는 런타임 시 객체를 생성하고 컴파일 시 생성할 객체 타입에 대한 정보만 보유한다.</li>
<li>메소드 디스패치란 어떤 메소드를 호출할지 결정하여 실제로 실행시키는 과정이다.</li>
<li>그 과정은 static(정적)/dynamic(동적) 두가지가 있다.</li>
</ul>
<h4 id="정적-디스패치static-dispatch">정적 디스패치(static dispatch)</h4>
<ul>
<li><p><strong>컴파일 시점에서 컴파일러가 특정 메소드를 호출할 것이라고 명확하게 알고 있는 경우</strong></p>
</li>
<li><p>컴파일 타임에 컴파일러, 사용자, 바이트코드 모두 어떤 메소드가 실행될 지 아는 것이다.</p>
<pre><code>&lt;코드예시&gt;
&lt;person 클래스&gt;
public class Person{
  private int age;

  public void print() {
      System.out.println(&quot;Hello&quot;);
  }

  public void print(String greeting) {
      System.out.println(greeting);
  }

  public void printJob(){
  }
}
</code></pre></li>
</ul>
<main 클래스>
public class Main {
    public static void Main(String[] args) {
        Person P = new Person();
        p.print();
        p.print("hi");
      }
}

<p>&lt;출력결과&gt;
Hello
Hi</p>
<pre><code>- 보통 오버라이딩한 메소드가 없을 경우, 상속받은 자식 클래스의 메소드가 아닐 경우에 대한 설명이지 않을까 개인적인 생각이다.
- 함수를 오버라이딩하여 사용했을 경우에도 인자의 타입이나 리턴타입 등에 따라 어떤 메소드를 호출할 지 알 수 있는 경우

#### 동적 디스패치(dynamic dispatch)
- dynamic은 runtime의 동의어로 사용되며 dispatch는 어떤 메소드를 호출할지 결정하는 것이므로 **런타임시에 호출할 메소드를 결정할 경우를 의미**한다.
- 컴파일러는 어떤 메소드를 호출할 지 모른다.
- 인터페이스나 추상 클래스에 정의된 추상 메소드를 호출하는 경우

</code></pre><p>&lt;Tv 클래스&gt;
public class Tv {
    public void view() {
        System.out.println(&quot;티비를 보여줌&quot;);
    }
}</p>
<p>&lt;Tv를 상속한 samsung 클래스&gt;
public class Samsung extends Tv {</p>
<pre><code>@Override
public void view() {
    System.out.println(&quot;OLED 티비를 보여줌&quot;);
}</code></pre><p>}</p>
<p>public class Main {
    public static void main(String[] args) {
        Tv tv = new Tv(); // Tv 참조 Tv 객체
        Tv samsungTv = new Samsung(); // Tv 참조, 삼성 객체</p>
<pre><code>    tv.view(); //참조와 객체가 동일
    samsungTv.view();// 참조와 객체가 다름 (상속) =&gt; 다이나믹 메소드 디스패치
}</code></pre><p>}</p>
<pre><code>=&gt; 컴파일 시에는 참조 타입만 확인하고 런타임시 JVM(Java Virtual Machine)이 객체 타입을 파악하여 메소드를 실행시켜준다.

### 5. 추상 클래스
#### 추상 클래스란?
- 먼저 사전적 의미로 추상(abstract)은 실체 간의 공통되는 특성을 추출한 것을 말한다.
- 이를 객체 지향 프로그래밍에 접목해보면, **객체를 직접 생성할 수 있는 클래스를 실체 클래스라고 했을 때, 이 클래스들의 공통적인 특성(즉, 필드와 메소드)을 추출해 선언한 클래스를 추상 클래스**라고 할 수 있다.
- 원론적으로는 **하나 이상의 추상 메소드를 포함하는 클래스를 가리켜 추상 클래스**라고 한다.
- **추상 클래스와 실체 클래스는 &#39;상속 관계&#39;**를 갖는다.
    - 추상 클래스가 부모, 실체 클래스가 자식 관계로 구현된다.
    - 따라서 **실체 클래스는 추상 클래스의 모든 특성을 물려받고 추가적인 특성을 가질 수 있다**.
    *특성 : 필드, 메소드

#### 추상 클래스의 선언
**클래스 선언에 abstract를 붙인다.**</code></pre><p>public abstract class 클래스 {
    //필드
    //생성자
    //메소드
}</p>
<pre><code>
#### 추상 클래스의 특징
- 일반 클래스처럼 필드, 생성자, 메소드를 선언할 수는 있지만 **객체를 직접 생성해서 사용할 수는 없다**. 따라서 new연산자를 통해 인스턴스 또한 생성하지 못한다.
- 그러나 자식 객체가 생성될 때 &#39;super()&#39; 메소드를 호출하여 추상 클래스 객체를 생성하므로 추상 클래스 또한 반드시 생성자가 있어야 한다.
- **추상 클래스를 상속받는 모든 클래스에서는 추상 메소드를 반드시 재정의해야 한다.**
- 추상 클래스는 새로운 실체 클래스를 만들기 위한 부모 클래스로만 사용된다. 즉, **extends 뒤에만 올 수 있다.**

#### 추상 클래스의 용도
**1. 실체 클래스들의 공통된 필드와 메소드의 이름을 통일하고자**
- 실체 클래스를 설계하는 사람들이 여러 명일 경우 실체 클래스마다 결국엔 공통된 역할을 하는 필드와 메소드가 여러번 선언되고 각기 다른 이름을 갖게 된다.
- 이러한 상황에서 실체 클래스의 부모 클래스인 추상 클래스에서 공통된 필드와 메소드를 선언함으로써 각각의 실체 클래스에서는 추상 클래스의 필드 메소드를 상속받아 사용할 수 있다.
=&gt; 코드에 통일성을 부여한다.

**2. 실체 클래스를 작성할 시간을 절약하고자**
- 추상 클래스에 실체 클래스에서 사용될 필드와 메소드를 미리 만들어두고 실체 클래스마다 다른 점만 구현한다면 코드 작성 시간을 절약할 수 있게 된다.

**3. 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위해**
- 일반 메소드를 상속받은 자식 클래스는 해당 클래스 내의 메소드를 구현할 수도, 안 할 수도 있다.
- 그러나 추상 메소드가 포함된 추상 클래스를 상속받은 모든 자식 클래스는 추상 메소드를 구현해야만 인스턴스를 생성할 수 있으므로 반드시 구현하게 하고자 할 때 추상 클래스를 사용할 수 있다.

#### 추상 메소드
- **자식 클래스에서 반드시 오버라이딩 해야만 사용할 수 있는 메소드를 의미**한다.
- 선언부만이 존재하며 구현부는 작성되어 있지 않다.
- 자식 클래스에서 작성되어 있지 않은 구현부를 오버라이딩하여 사용한다.
- 추상 메소드의 선언</code></pre><p>abstract 반환타입 메소드이름();</p>
<p>```</p>
<h3 id="6-final-키워드">6. final 키워드</h3>
<ul>
<li><strong>클래스, 필드, 메소드를 수정할 수 없고 최종 상태임을 선언하고자 할 때</strong> 붙여준다.</li>
<li>클래스, 필드, 메소드에 붙었을 때 각각의 해석이 조금씩 다르다.<ul>
<li><strong>&#39;final + 클래스&#39;</strong> : 해당 클래스는 최종적인 클래스이므로 더이상 자식 클래스를 만들 수 없고 상속할 수 없다.</li>
<li><strong>&#39;final + 메소드&#39;</strong> : 해당 메소드는 최종적인 메소드이므로 오버라이딩 할 수 없다.</li>
<li><strong>&#39;final + 필드(멤버변수)&#39;</strong> : 해당 필드는 초기값 설정 후 더이상 값을 변경할 수 없다.</li>
</ul>
</li>
</ul>
<h3 id="7-object-클래스">7. object 클래스</h3>
<ul>
<li>자바에서 가장 기본적인 동작을 수행하는 클래스들의 집합인 java.lang 패키지 내에서 가장 많이 사용되는 클래스</li>
<li><strong>모든 자바 클래스의 최고 조상 클래스</strong></li>
<li><strong>자바의 모든 클래스는 object클래스의 모든 메소드를 바로 사용할 수 있다.</strong></li>
<li>필드(멤버변수)를 가지지 않고 11개의 메소드로만 구성되어 있다.<h4 id="object-클래스-내의-11가지-메소드">object 클래스 내의 11가지 메소드</h4>
<img src="https://images.velog.io/images/codename_hee/post/821e024e-bc03-4750-9325-2cadae4bea28/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA 스터디] 5주차 : 클래스]]></title>
            <link>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-5%EC%A3%BC%EC%B0%A8-%ED%81%B4%EB%9E%98%EC%8A%A4</link>
            <guid>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-5%EC%A3%BC%EC%B0%A8-%ED%81%B4%EB%9E%98%EC%8A%A4</guid>
            <pubDate>Wed, 27 Oct 2021 01:02:48 GMT</pubDate>
            <description><![CDATA[<h2 id="학습할-것">학습할 것</h2>
<ul>
<li>클래스 정의하는 방법</li>
<li>객체 만드는 방법(new키워드 이해하기)</li>
<li>메소드 정의하는 방법</li>
<li>생성자 정의하는 방법</li>
<li>this 키워드 이해하기</li>
</ul>
<h2 id="클래스-정의하는-방법">클래스 정의하는 방법</h2>
<ul>
<li>자바에서 클래스란?<ul>
<li>서로 관계가 깊은 변수(데이터)와 함수를 함께 정의하여 다룰 수 있게 한 것<ul>
<li>기본 자료형(primitive type)외에 사용자 정의 타입이 바로 클래스</li>
</ul>
</li>
<li>객체지향 프로그래밍에서 객체를 정의해주는 틀, 객체의 속성과 기능을 하나로 묶어놓은 틀</li>
<li>필드, 생성자, 메소드로 구성<ul>
<li>필드(멤버 변수) : 객체지향에서 속성에 해당하며 멤버 변수라고도 한다.</li>
<li>생성자 : 변수에 초기값을 대입하여 사용하듯 클래스에서도 동일한 형식으로 생성해 초기화를 해주는 역할을 한다.</li>
<li>메소드 : 객체지향에서 기능(행위)에 해당하며 클래스를 사용하여 메소드 내에 정의된 행위를 실행하는 역할을 한다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code>클래스 선언하는 방법
//접근지정자 class(키워드) 클래스이름 {}
public class Person {
    //필드, 멤버변수
    private String name;
    private String age;

    //default 생성자, 생략이 가능하지만 파라미터를 가진 생성자가 있을 경우 반드시 명시해야 한다.
    public Person() {}

    //파라미터를 가진 생성자, 파라미터를 가지고 변수를 초기화한다.
    public Person(String name, String age) {
    this.name = name;
    this.age = age;
    }

    // 메소드, 이름을 가져오는 행위를 한다.
    public String getName() {
    //메소드 내부 기능
    return name;
    }
 }</code></pre><h3 id="접근-지정자">접근 지정자</h3>
<p> 자바에서는 클래스를 정의할 때 class 키워드를 사용하며 외부 클래스가 해당 클래스에 접근하는 범위를 접근 지정자를 통해서 제한할 수 있다.
 접근 지정자에는 public, protected, default, private 네 가지가 있다.
 <img src="https://images.velog.io/images/codename_hee/post/aecfab9a-d372-4b16-9788-73a59fa1c2fd/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA 스터디] 3주차_연산자]]></title>
            <link>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-3%EC%A3%BC%EC%B0%A8%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-3%EC%A3%BC%EC%B0%A8%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Thu, 21 Oct 2021 00:59:06 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[[JAVA 스터디] 2주차_자바 데이터 타입, 변수 그리고 배열]]></title>
            <link>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-2%EC%A3%BC%EC%B0%A8%EC%9E%90%EB%B0%94-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85-%EB%B3%80%EC%88%98-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EB%B0%B0%EC%97%B4</link>
            <guid>https://velog.io/@codename_hee/JAVA-%EC%8A%A4%ED%84%B0%EB%94%94-2%EC%A3%BC%EC%B0%A8%EC%9E%90%EB%B0%94-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85-%EB%B3%80%EC%88%98-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EB%B0%B0%EC%97%B4</guid>
            <pubDate>Thu, 21 Oct 2021 00:56:23 GMT</pubDate>
            <description><![CDATA[<h3 id="프리미티브-타입-종류와-값의-범위-그리고-기본-값">프리미티브 타입 종류와 값의 범위 그리고 기본 값</h3>
<h3 id="프리미티브-타입과-레퍼런스-타입">프리미티브 타입과 레퍼런스 타입</h3>
<p>변수를 타입에 따라 구분하면</p>
<ol>
<li><p>기본형(primitive type) 변수</p>
</li>
<li><p>참조형(reference type) 변수
로 나눌 수 있다.</p>
</li>
<li><p>기본형 변수</p>
<ul>
<li>실제 연산에 사용되는 변수</li>
<li>자바에는 8가지 종류의 기본형 변수가 있다.<ul>
<li>정수형 : byte, short, int, long</li>
<li>실수형 : float, double</li>
<li>문자형 : char</li>
<li>논리형 : boolean</li>
</ul>
</li>
</ul>
</li>
<li><p>참조형 변수</p>
<ul>
<li>8개의 기본형 변수를 사용하여 사용자가 직접 만들어 사용하는 변수<h3 id="리터럴">리터럴</h3>
</li>
</ul>
</li>
</ol>
<h3 id="변수-선언-및-초기화하는-방법">변수 선언 및 초기화하는 방법</h3>
<h4 id="변수-선언">변수 선언</h4>
<p>변수를 사용하기 위해서는 우선 변수를 선언해야 하며 그림과 같이 선언한다.</p>
<ul>
<li>변수 타입 : 변수에 저장될 값이 어떤 타입(type)인지 지정하는 것</li>
<li>변수 이름 : 변수에 붙인 이름. 변수가 값을 저장할 수 있는 메모리 공간을 의미하므로 변수 이름은 이 메모리 공간에 이름을 붙여주는 것.</li>
</ul>
<p>이렇게 변수를 선언하면 메모리의 빈 공간에 &#39;변수타입&#39;에 알맞은 크기의 저장공간이 확보되고 변수 이름을 붙여서 이 이름을 통해 해당 저장공간을 사용할 수 있게 된다.</p>
<h3 id="타입-변환-캐스팅-그리고-타입-프로모션">타입 변환, 캐스팅 그리고 타입 프로모션</h3>
<h3 id="1차-및-2차-배열-선언하기">1차 및 2차 배열 선언하기</h3>
<h3 id="타입-추론-var">타입 추론, var</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[ㄹㅇㄴㅁ]]></title>
            <link>https://velog.io/@codename_hee/%E3%84%B9%E3%85%87%E3%84%B4%E3%85%81</link>
            <guid>https://velog.io/@codename_hee/%E3%84%B9%E3%85%87%E3%84%B4%E3%85%81</guid>
            <pubDate>Wed, 20 Oct 2021 00:48:51 GMT</pubDate>
            <description><![CDATA[<p>ㄹㅇㄴㅁㄹㅇㄴㅁㄹㅇㄴㅁ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[WIL(2021.09.27 ~ 2021.10.03)] 항해 99 3주차 회고록]]></title>
            <link>https://velog.io/@codename_hee/WIL2021.09.27-2021.10.03-%ED%95%AD%ED%95%B4-99-3%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@codename_hee/WIL2021.09.27-2021.10.03-%ED%95%AD%ED%95%B4-99-3%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Mon, 04 Oct 2021 00:35:28 GMT</pubDate>
            <description><![CDATA[<h2 id="항해99-3주차-필수-키워드">항해99 3주차 필수 키워드</h2>
<p><strong>1. ORM</strong></p>
<ul>
<li><p>ORM이란?
  : Object - Relational Mapping 객체와 관계형 데이터베이스의 매핑
  : 객체와 DB의 테이블이 매핑을 이루는 것
  : 객체가 테이블이 되도록 매핑 시켜주는 프레임워크
  : SQL문의 작성없이 간단한 매핑설정만으로 데이터베이스의 테이블 데이터를 Java객체로 전달받을 수 있다.</p>
<ul>
<li><p>장점
생산성 및 유지보수성 향상 - 중복된 JDBC 코드를 작성하지 않아도 되며 개발 로직 코드에 집중할 수 있다.
독립성 - DBMS에 종속적이지 않아 어느 DB를 사용하든 매핑 설정 일부만 변경해주면 자바코드를 건드릴 일이 없다.</p>
</li>
<li><p>단점
쿼리가 복잡해지면 ORM으로 표현하는 데에 한계가 있다.
성능이 raw쿼리에 비해 느리다.</p>
</li>
</ul>
</li>
</ul>
<p><strong>2. SQL</strong></p>
<ul>
<li>SQL이란?
  : 관계형 데이터베이스 관리 시스템(RDBMS)의 데이터를 관리하기 위해 설계된 특수 목적의 프로그래밍 언어
  : 데이터베이스 언어</li>
</ul>
<p><strong>3. MVC</strong></p>
<ul>
<li>MVC란?
  : Model - View - Controller로 구성된 소프트웨어 디자인 패턴</li>
<li>구성요소별 역할<ul>
<li>Controller
  모델에 명령을 보내 모델의 상태 변경
  뷰에 명령을 보내 모델의 표시 방법을 변경</li>
<li>Model
  어플리케이션의 데이터를 의미하며 상태 변화에 대해 컨트롤러와 뷰에 이를 통보
  public함수로만 이루어짐
  쿼리에 대해 상태 정보를 제공하거나 상태를 수정</li>
<li>View
  사용자가 볼 결과물을 생성하기 위해 모델로부터 정보를 얻어 옴.</li>
</ul>
</li>
</ul>
<h2 id="git-오류-해결">Git 오류 해결</h2>
<ol>
<li><p>오류 메시지 : ! [rejected] main -&gt; main (non-fast-forward)
원인 : .gitignore 혹은 README 파일로 인해 발생
해결방법 : push 하고자 하는 브런치 이름 앞에 +를 붙이기
git push origin +main</p>
</li>
<li><p>오류 메시지 : main과 매칭되지 않는다는 오류
원인 : 로컬에서 main 이름과 원격에서의 main 이름이 다름(로컬에서는 master, 원격에서는 main)
해결 방법 : 로컬 master브랜치의 이름을 main으로 바꿔준다.
git branch -m master main
git branch -m main</p>
</li>
<li><p>상황 : &#39;git add .&#39;시도
오류 메시지 : does not have a commit checked out
원인 : 해당 폴더에 .git 이 별도로 있을 때 발생. remote저장소로 연결해야하는데 clone을 했거나 했을 때 git이 하나 더 생기면서 발생하는 것
해결 방법 : .git 폴더를 숨김 폴더 표시 처리를 해서 찾아내고 그걸 삭제하고 다시 명령어를 실행하면 됨</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[WIL(2021.09.20 ~ 2021.09.26)] 항해 99 2주차 회고록]]></title>
            <link>https://velog.io/@codename_hee/WIL2021.09.20-2021.09.26-%ED%95%AD%ED%95%B4-99-2%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@codename_hee/WIL2021.09.20-2021.09.26-%ED%95%AD%ED%95%B4-99-2%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Sun, 26 Sep 2021 15:37:26 GMT</pubDate>
            <description><![CDATA[<p>어느덧 항해 99의 2주차가 마무리 되고 있다.
추석 연휴였던 월~수요일 동안 항해의 공식적인 일정은 없었고 1주차를 마무리하며 각자 선택했던 주특기 기본 강의가 지급되어 자율적으로 수강할 수 있었다.</p>
<p>나는 Java 기반의 백엔드 프레임워크인 Spring 기술을 주특기로 선택했다. 시간적 여유가 많지 않아서 오래 고민하지 못했지만 1주차 때 진행됐던 주특기별 세션, 매니저님과의 면담, 주변 개발자들의 조언을 근거 삼아 Spring을 배워보기로 했다.</p>
<p>매니저님께서 연휴기간동안 2주차까지는 수강을 완료해오라 하셨지만 생각보다 본가에 가있으니 강의 듣기가 쉽지 않았다.
결국 1주차 강의도 완벽하게 수강하지 못한 채 목요일 9시에 2주차 발제가 이루어졌다.</p>
<p>이번 2주차는 <strong>&#39;주특기 기본&#39;</strong>주차로, 7일동안 각자 배정받은 팀의 팀원들과 함께 으쌰으쌰하며 spring에 관한 기본적인 지식을 익힌 후 과제 요구사항을 참고하며 웹사이트 하나를 완성해야한다.</p>
<p>목요일에 발제가 이루어진 후 3일동안 공부해보니 나는 왜 추석 연휴동안 강의를 조금이라도 더 듣지 않았을까 하는 약간의 후회가 밀려왔다.</p>
<p>1주차 때 백엔드 언어로 쓰였던 Python과 달리 Java언어는 문법과 작동 원리 등 언어의 구조 자체가 너무 달랐고, 관련 지식이 전혀 없었던 나에게 Java의 클래스, 멤버 변수, 메소드, 객체 등에 대한 개념과 서버의 3계층인 controller, service, repository 의 존재는 굉장히 부담스럽게 다가왔다.</p>
<p>강의를 들으며 따라는 하는데 이게 왜 이렇게 되는건지, 어떨 때 어떤 코드를 어떤 파일에 작성해야하는 건지에 대해 전혀 감이 오질 않았다. 하루는 혼란스럽고 급한 마음에 도저히 집중이 되지 않아 공부는 뒤로 한채 운동을 다녀와 그대로 침대로 직행했다...</p>
<p>다음날 다시 공부를 시작하려 책상에 앉으니 문득 항해 수료생 선발을 위한 인터뷰에서 담당 매니저님께서 했던 말씀이 떠올랐다.</p>
<p>우리는 항해를 하는 동안 &#39;개발자에게 가장 중요한 자세이자 태도, 능력인 문제 해결 능력&#39;을 기를 거라고.</p>
<p>그렇다면 지금 나는 어떻게 해야 이 방대한 내용들을 내 것으로 만들 수 있을 것이며 진정한 &#39;공부&#39;를 할 수 있을까 라는 생각에 빠지게 됐고 이해가 안되는 내용들을 하나 둘 구글링 해보기 시작했다.</p>
<p>역시 구글. 
누군가 지금 내 상황에서 이해가 잘 되도록 쉬운 표현들로 필요한 내용들만 쏙쏙 골라서 java에 대한 설명을 해놓은 글을 찾을 수 있었다.</p>
<p>그 글을 읽으며 지금 내가 이해가 되지 않는 부분이 spring보다는 java 언어라는 것도 깨달을 수 있었다.</p>
<p>자료들을 하나 둘 읽다보니 비로소 듣고있던 강의의 내용이 조금이나마 이해되기 시작했고 많이 버벅대겠지만 주어진 프로젝트를 진행할 수 있을 것 같다는 생각이 들었다.</p>
<p>그리고 오늘 운영진 측에서 &#39;<strong>DI, IoC, Bean</strong>&#39; 라는 키워드를 포함한 회고록을 제출해달라는 숙제를 내주셨다.</p>
<p>2주차에 접어드니 매니저님들께서 내주는 숙제는 다 이유가 있다 라는 걸 알 수 있었기에 해당 내용들에 대해 공부를 하기 시작했다.</p>
<p>아래는 키워드에 대해 내가 공부한 내용이다.</p>
<h3 id="ioc-inversion-of-control">IoC (Inversion of Control)</h3>
<p>: 제어권 역전. </p>
<p>: 개발자가 직접적으로 의존성을 만들지 않고 외부에서 의존성을 가져오는 경우를 의미한다.</p>
<ul>
<li>IoC container : 객체의 생성과 관계설정, 사용, 제거 등의 작업을 대신 해줌. Bean을 저장한다고 하여 BeanFactory라고도 불림.<h3 id="di-dependency-injection">DI (Dependency Injection)</h3>
: IoC의 일종으로 의존성 주입을 의미한다. </li>
</ul>
<p>:객체를 직접 생성하는 게 아닌 외부에서 생성한 후 주입 시켜주는 방식 및 작업을 의미한다.</p>
<h3 id="bean">Bean</h3>
<p>: 스프링의 IoC 컨테이너가 관리하는 객체들.
: </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[WIL(2021.09.13 ~ 2021.09.18)] 항해 99 1주차 회고록 ]]></title>
            <link>https://velog.io/@codename_hee/WIL2021.09.13-2021.09.18-%ED%95%AD%ED%95%B4-99-1%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@codename_hee/WIL2021.09.13-2021.09.18-%ED%95%AD%ED%95%B4-99-1%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Sun, 19 Sep 2021 14:44:43 GMT</pubDate>
            <description><![CDATA[<h3 id="1주차-프로젝트-필수-포함-사항">1주차 프로젝트 필수 포함 사항</h3>
<ol>
<li>Jinja2 템플릿 엔진을 이용한 서버사이드 렌더링</li>
<li>JWT 인증 방식으로 로그인 구현</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[제 2회 스파르톤 생존일지]]></title>
            <link>https://velog.io/@codename_hee/%EC%A0%9C-2%ED%9A%8C-%EC%8A%A4%ED%8C%8C%EB%A5%B4%ED%86%A4-%EC%83%9D%EC%A1%B4%EC%9D%BC%EC%A7%80</link>
            <guid>https://velog.io/@codename_hee/%EC%A0%9C-2%ED%9A%8C-%EC%8A%A4%ED%8C%8C%EB%A5%B4%ED%86%A4-%EC%83%9D%EC%A1%B4%EC%9D%BC%EC%A7%80</guid>
            <pubDate>Sat, 04 Sep 2021 12:34:31 GMT</pubDate>
            <description><![CDATA[<h2 id="900-pm-스파르톤-시작">[9:00 PM] 스파르톤 시작</h2>
<p><img src="https://images.velog.io/images/codename_hee/post/301ccc57-d95a-462e-9dc8-94115b1f7bcd/image.png" alt=""></p>
<blockquote>
<p>드디어 <strong>제 2회 스파르톤</strong>이 시작됐다. </p>
</blockquote>
<p>같은 구역에 모여 앉게 된 분들과 간단한 소개와 인사를 나눈 뒤 팀 명도 정했다.
얼떨결에 6시까지 열심히 하겠다는 선서도 하고...!!!</p>
<p>그나저나 밤샘 코딩은 처음이고 벌써부터 하품이 나오는데.... 잘할 수 있으려나 걱정이 된다.
그래도 죽이되든 밥이되든 해봐야지. </p>
<p>[나만의 목표] : 웹개발 강의 끝까지 수강하기</p>
<h2 id="1000-pm-생존일지">[10:00 PM] 생존일지</h2>
<p><img src="https://images.velog.io/images/codename_hee/post/893af18c-2741-4519-9cf2-6340b76039d6/image.png" alt=""></p>
<blockquote>
<p>9시 생존일지를 쓰고난 뒤 얼마 지나지 않아서 그런가 아직 정신은 쌩쌩하다.</p>
</blockquote>
<p>지금은 2주차 웹개발 ajax 두번째 과제를 하고있다.
그런데 강의를 들은지 3일정도 되어서 그런가... 벌써부터 막힌다ㅠㅠ
15분이면 될 거라고 하셨는데..</p>
<p>조급해하지 말고 차근차근 생각하면서 다시 해보자!
다음 생존일지 쓰기까진 2주차 과제까지 모두 완료했기를!! 화이팅!!!!!!</p>
<h2 id="1100-pm-생존일지">[11:00 PM] 생존일지</h2>
<p><img src="https://images.velog.io/images/codename_hee/post/97145485-3e9a-45a3-a770-c3d978bd1500/image.png" alt=""></p>
<p>슬슬 밤 샐 준비를 해야할 듯 싶어 중간에 잠깐 씻고왔다.
씻고 나니 잠시동안 뭔가 자야될 것 같은 느낌적인 느낌이 들었지만 정신차리고 자리에 앉아서 과제를 이어서 했다.</p>
<p>강의자료와 내 코드를 비교하며 드뎌 잘못된 부분을 찾았고, 조건문을 이용하는 전단계 과제까지는 해낼 수 있었다.
(11시까지 2주차 과제를 모두 끝내고자 했건만.... 느리다 느려..ㅠ)</p>
<p>그래도 오늘밤은 길다면 길테니 문제를 해결했다는 거 자체에 의의를 두고 차근차근 해나가자! 아즈아<del>~</del> </p>
<h2 id="1200-am-생존일지">[12:00 AM] 생존일지</h2>
<blockquote>
<p>아직 말똥말똥 살아있다!! 
11시 30분부터 진행됐던 골든벨에 참가했더니 한시간이 훅 지나가있었다.</p>
</blockquote>
<p>한 문제 정도는 맞추고 싶었는데 다들 너무 빠르고 입력 버튼 누르기도 쉽지 않아서 못맞췄다ㅠㅠ
그래도 조원분들의 활약에 9점이나 획득해서 최종 성적은 공동 4등!!</p>
<p>이따 마라톤을 한다고 하는데 그 전까지 또 집중해서 빡세게 코딩해야겠다. 아좌<del>~</del></p>
<h2 id="100-am-생존일지">[1:00 AM] 생존일지</h2>
<blockquote>
<p>갑자기 졸음이 밀려와서 급 제티 한 잔.....
카페인에 민감해서 커피도, 레드불도 못 먹으니 깡생수와 제티로 간신히 잠을 이겨내고 있당..!!!
<img src="https://images.velog.io/images/codename_hee/post/e28c93d0-d8f3-49eb-9a88-49904a2b709e/image.png" alt=""></p>
</blockquote>
<p>코딩은 간단한 퀴즈 한개만 더 풀면 2주차 과제로 넘어갈 수 있는데... 쉽지 않다....
졸려서 그런건지 잘 몰라서 그러는 건지 복합적인 건지 생각했던 것보다 진도가 쓱쓱 나가지 않는 것 같다.
jquery를 사용하여 img태그의 src를 변경하는 법을 찾고 이를 과제에 적용하는건데, attr 함수를 사용하면 된다는 것 밖에 알아내지 못했다. 나름의 코드를 짜보았으나 <img src="https://images.velog.io/images/codename_hee/post/1e96afd5-f8e4-4d7f-b167-23be26dcdc4c/image.png" alt=""> 이런 이미지만 뜰 뿐...^^
(과제에 적용해야 하는데 왜 파일이 안뜰까..ㅠㅠ)
얼른 끝내고 2주차 마무리 과제로 넘어가고 싶다.</p>
<h2 id="200-am-생존일지">[2:00 AM] 생존일지</h2>
<blockquote>
<p>드디어 위에서 말한 오류를 해결하고 2주차 두번째 퀴즈를 완료했다.
<img src="https://images.velog.io/images/codename_hee/post/aa6832d7-11fd-4346-aeba-bc5d762c1966/image.png" alt="">
=&gt; 위의 오류는 attr함수 형식을 맞추어 쓰지 않아서 생겼더 거였땅.. 나란 사람...몽총이..</p>
</blockquote>
<p>다음으로 2주차 마무리 과제를 시작하려던 중, 매니저님께서 전화를 주셨다.
마침 너무 졸려서 어떻게 하지 고민하던 찰나였는데 매니저님과 몇 마디 나누니 열심히 해야겠다는 생각과 의지가 새록새록 돋아났다.
나를 위해 매니저분들도 덩달아 고생하는 거니깐ㅠㅠㅠ
그리고 매니저님께서 3주차 강의는 2주차 강의보다 잘 들을 수 있을 거라고 해주셨으니 좀만 더 집중해봐야겠다.</p>
<p>이제 스파르톤도 4시간 남았으니!! 좀만 더 화이팅!!!!</p>
<h2 id="300-am-생존일지">[3:00 AM] 생존일지</h2>
<p><img src="https://images.velog.io/images/codename_hee/post/5c966199-b8c6-450b-80fa-2339d84e7e28/image.png" alt=""></p>
<blockquote>
<p>너무 졸려서 정신차리는 데에 15분 정도 걸린 것 같다....</p>
</blockquote>
<p>마지막 과제를 하면서 API에서 데이터를 받아오는 것 까진 됐는데 화면에 해당 데이터를 보여주는 코드가 간단할 듯 하면서 헷갈려서 계속 찾아보고 있당..!!
오늘 5주차 강의까지 다 들을려고 했는데 슬슬 안될 것 같다는 생각이 든다...ㅋㅋㅋㅋㅋ
3시에 전체 마라톤 경주가 있을거라고 했으니 열심히 참여해서 이 고비를 잘 넘겨야겠다!!!</p>
<h2 id="400-am-생존일지">[4:00 AM] 생존일지</h2>
<blockquote>
<p>드디어 2주차 과제를 끝냈다!!!!!
2주차의 내용이 자꾸 개념상 어렵게 느껴지고 잠도 솔솔 쏟아졌던 터라 목표했던 시간보다 한참 오버해서 끝낼 수 있었다.</p>
</blockquote>
<p>2주차 과제는 1주차 과제의 일부에 API로 데이터를 받아오면 페이지가 로드되는 동시에 해당 데이터를 갱신해주는 기능을 붙이는 거였는데 과제를 수행하며 아래 내용들을 새롭게 알게 되었다.</p>
<p><img src="https://images.velog.io/images/codename_hee/post/0cc50d22-2358-4adf-bacc-9e12ddc199ed/image.png" alt="">
$(document).ready(function()) =&gt; 이 코드를 통해 로드되는 동시에 함수를 실행시킬 수 있다.</p>
<p><img src="https://images.velog.io/images/codename_hee/post/77323518-a774-402f-a6a9-4fafcbf2ee0c/image.png" alt="">
API의 데이터를 보여줄 달러-원 환율 div를 따로 만들어 class를 부여해주었고 페이지 로드될 때마다 갱신되는 데이터는 span태그로 묶어 별도 id를 통해 API 데이터와 연동해주었다.</p>
<p>당초 목표했던 시간보다 너무너무 오래걸려서 6시까지 목표했던 바를 이루지 못할 것 같아 아쉽지만 그래도 최선을 다해보려고 한다.</p>
<h2 id="500-am-생존일지">[5:00 AM] 생존일지</h2>
<blockquote>
<p>이제 완주까지 한시간밖에 남지 않았다.</p>
</blockquote>
<p>당초 목표했던 것보다는 다소 적은 양의 공부를 한 것 같긴 하지만 완주가 가까워지니 그 어느 때보다도 기분은 좋다.</p>
<p>매니저님의 두번째 찐~한 관리도 무사히 통과했고, 이제 남은 시간동안 3주차 강의를 최대한 많이 들을려고 한다.</p>
<p>얼마남지 않은 시간. 좀만 더 버티자!!!!!</p>
<h2 id="600-am-스파르톤-마지막-생존일지">[6:00 AM] 스파르톤 마지막 생존일지</h2>
<p><img src="https://images.velog.io/images/codename_hee/post/a90aa5de-5ec5-439f-96ed-ae6be40feec9/KakaoTalk_20210905_060525257.jpg" alt="">
나의 첫번째 밤샘코딩, 스파르톤이 끝났다.
눈꺼풀은 돌덩이 같고, 배에서는 꼬르륵 소리,또 오래 앉아있다보니 다리는 퉁퉁 부었다.</p>
<p>개발자가 되겠다는 마음을 먹고 부트캠프에 신청도 했지만, 그 전에 스스로 나의 의지에 대해 시험 해보고싶어 참가한 대회였다. 
만약 완주하지 못한다면 &#39;개발자의 꿈을 접겠노라&#39; 무섭게 다짐했었다.
다행히도 이 글을 끝까지 씀으로써 개발자의 꿈은 간직할 수 있게 되었고 나의 의지와 가능성 또한 확인할 수 있었다.</p>
<p>물론 미리 만난 우리 항해 99 3기 사람들과 한 팀이 되어 소심하지만 서로를 향한 격려와 응원을 보낸 덕분에 무사히 완주를 할 수 있었던 것 같다. </p>
<p>거기에 사전키트 발송부터 대회 운영, 찐한 관리 등등을 위해 애써주신 우리 운영진들 덕분에!! 끝까지 포기하지 않고 버틸 수 있었다.</p>
<p>앞으로 남들보다 더 많은 시간과 노력을 들여야 하는 여정을 시작하는 시점에서 소중한 경험을 한 것 같아 기분이 너무 좋다.
오늘의 경험이 훌륭한 개발자로 향하는 도약의 발판이 되길!!</p>
<p>#찐개발자로 가는 길=3=3=3   #화이팅</p>
<p>저와 같은 경험을 한번쯤 해보고 싶다면 아래 링크를 이용하세요:)</p>
<blockquote>
<p>스파르타 코딩클럽 친구추천 링크
<a href="https://spartacodingclub.kr/?f_name=%EC%A0%95%ED%9D%AC%EC%9C%A4&amp;f_uid=5f41e1e3afbd130009ea91bb">https://spartacodingclub.kr/?f_name=%EC%A0%95%ED%9D%AC%EC%9C%A4&amp;f_uid=5f41e1e3afbd130009ea91bb</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[스파르타 코딩클럽] 웹개발 종합반 1주차 후기]]></title>
            <link>https://velog.io/@codename_hee/%EC%8A%A4%ED%8C%8C%EB%A5%B4%ED%83%80-%EC%BD%94%EB%94%A9%ED%81%B4%EB%9F%BD-%EC%9B%B9%EA%B0%9C%EB%B0%9C-%EC%A2%85%ED%95%A9%EB%B0%98-1%EC%A3%BC%EC%B0%A8-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@codename_hee/%EC%8A%A4%ED%8C%8C%EB%A5%B4%ED%83%80-%EC%BD%94%EB%94%A9%ED%81%B4%EB%9F%BD-%EC%9B%B9%EA%B0%9C%EB%B0%9C-%EC%A2%85%ED%95%A9%EB%B0%98-1%EC%A3%BC%EC%B0%A8-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sat, 28 Aug 2021 14:51:50 GMT</pubDate>
            <description><![CDATA[<p> 이번이 두번째다. 지난해 나는 초기 스타트업팀에서 근무하며 개발이라는 영역에 흥미를 갖게되었다. 까만 배경에 아주 작은 무지개색 글자들을 채워나가는 모습이 너무나 멋있어 보였달까. 뿐만 아니라 개발자 팀원이 머리를 싸매고 종이에 무언갈 끄적대며 심도 깊게 고민하는 모습이 그동안 내가 꿈꿔왔던 &#39;내가 일하는 나의 모습&#39;과 너무 비슷했다.
 어쩌면 단순히 흥미가 아닌 관련된 직업을 갖고자 하는 마음이 처음부터 있었던 것 같다. 그럴려면 내가 이 분야에 적성이 있을지 판단해야만 했고, 고민 끝에 스파르타 코딩클럽의 웹개발 종합반 수강신청을 했다.
 그러나 잦은 야근과 불규칙한 근무 일정 등으로 당시 웹서핑만 할 줄 알았던 나에게 짧지만 많은 수의 강의들과 퀴즈, 숙제들은 다소 부담으로 다가왔다. 결국 2주차까지밖에 수강하지 못하고 미련만 남긴 채 스파르타를 잠시 떠나게 됐다.</p>
<p> 약 1년의 시간이 흐른 지금, 그간 내 상황은 많이 변했고 결론적으로 지금은 개발에만 완전히 집중할 수 있는 시간이 생겼다. 웹개발 종합반 강의도 다시 듣고있고 이제 막 1주차 과제를 제출하고 왔다.</p>
<h3 id="내가-한-1주차-과제">&lt;내가 한 1주차 과제&gt;</h3>
<p> <img src="https://images.velog.io/images/codename_hee/post/58e09c03-1d2b-41b2-9483-6f0b16076726/image.png" alt=""></p>
<p> 작년에는 1주차 과제 하는데에 거의 삼일 이상을 끙끙 거렸는데 이번엔 훨씬 수월했다.
 강의 중에 다뤘던 내용들과 미니 퀴즈들, 약간의 구글링을 거치니 나름 형태를 갖춘 웹사이트 화면을 구성할 수 있었다.</p>
<p> 따로 복습은 하지 않고 1주차 강의만을 다 들은(+1주차 과제) 시점에서 내 머릿속에 남아있는 건</p>
<ol>
<li><p>이미지나 div의 중앙정렬을 위해서는 width 값을 지정해주고 margin을 auto로 설정해주면 된다는 것</p>
</li>
<li><p>부트스트랩을 통해 누군가가 미리 만들어둔 여러 CSS를 활용할 수 있다는 것</p>
</li>
<li><p>javascript의 반복문, 조건문, 여러 자료형들</p>
</li>
<li><p>html 문서의 head, body 구조와 여러 태그들</p>
</li>
<li><p>구글 폰트 적용하는 방법</p>
<p>등이다.</p>
</li>
</ol>
<p>(음....훨씬 많았는데 빨리 복습해야겠군..^^;)</p>
<p>약 영화 한편 길이의 1주차 강의들을 통해 벌써 웹사이트의 화면을 구성할 수 있게 되고 위에 나열된 것보다 훨씬 많은 내용들을 배우고 익힐 수 있었다.
이정도 속도라면 정말 5주 뒤의 나는 꽤 그럴싸한 사이트를 만들고 배포할 수 있겠구나 싶었다.</p>
<p>의무적으로 주1회 자신이 선택한 시간에 참여해야 하는 온라인 스터디가 있어, 강의에 몰입할 수 있는 시간을 내는 데에 도움이 되기도 했다.</p>
<p>남은 주말동안 1주차 내용들 복습 자세히 하고 얼른 2주차 강의를 들어야겠다.
르탄이가 쫓아오기 전에 머어어어얼리 도망가야지!!!!!!!</p>
]]></description>
        </item>
    </channel>
</rss>