<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Yeoniee.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sun, 19 Feb 2023 03:24:29 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Yeoniee.log</title>
            <url>https://velog.velcdn.com/images/heyjeong-go/profile/b63d4475-7638-4044-a09e-05d2e7055249/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Yeoniee.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/heyjeong-go" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[HTTP 공부 정리]]></title>
            <link>https://velog.io/@heyjeong-go/HTTP-%EA%B3%B5%EB%B6%80-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@heyjeong-go/HTTP-%EA%B3%B5%EB%B6%80-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 19 Feb 2023 03:24:29 GMT</pubDate>
            <description><![CDATA[<h3 id="🔶html-url-web-brower와-web-server-http">🔶HTML, URL, Web brower와 Web Server, HTTP</h3>
<ul>
<li>HTML : 웹 페이지를 만드는 언어</li>
<li>URL : 원하는 웹 페이지에 접속하게 해주는 주소 체계</li>
<li>Web browser, Web server : 웹 페이지를 주고 받는 소프트웨어</li>
<li><strong>🎈HTTP</strong>(HyperText Transfer Protocol) : Web browser와 Web server가 통신하는 프로토콜</li>
</ul>
<p><img src="https://velog.velcdn.com/images/heyjeong-go/post/416a1a14-127c-4504-9291-5ff2b2746bfd/image.png" alt=""></p>
<p><strong>🎈HTTP란 Request 와 Response를 의미.
🎈서버와 클라이언트가 서로 통신하는 메시지.</strong></p>
<h3 id="🔶http---request-message">🔶HTTP - Request Message</h3>
<h4 id="🔸http-request-header-format">🔸HTTP Request Header format</h4>
<p><img src="https://velog.velcdn.com/images/heyjeong-go/post/d70ea69d-30d4-40a3-8f99-e96efdaaf4a8/image.png" alt=""></p>
<ul>
<li>Get : 데이터를 웹 세버로 가져올 때 쓰이는 메소드<ul>
<li>/doc/test.html : client가 server에 요청한 html</li>
</ul>
</li>
<li>Host : 네트워크의 컴퓨터 주소 식별하는 이름</li>
<li>User-Agent : 유저 컴퓨터, 웹 브라우저 정보</li>
<li>Accept-Encoding : 데이터 양 많으면 압축해서 전송하는데 어떤 압축방식을 지원하는지 설명</li>
<li>If-Modified-since:Tue : 마지막으로 페이지를 다운받은걸 언제든지 확인하여 다시 다운받을지 결정</li>
<li>[blank line] : 빈 줄로 헤더와 바디 구분</li>
</ul>
<h3 id="🔶http---response-message">🔶HTTP - Response Message</h3>
<h4 id="🔸http-response-header-format">🔸HTTP Response Header format</h4>
<p><img src="https://velog.velcdn.com/images/heyjeong-go/post/78569315-1328-426f-bcc8-e54357593d06/image.png" alt=""></p>
<ul>
<li>status 부분<ul>
<li>status code : 응답 결과를 코드로 나타냄<ul>
<li>1xx codes : Informational</li>
<li>2xx codes : Successes</li>
<li>3xx codes : Redirection</li>
<li>4xx codes : Client Error</li>
<li>5xx codes : Server Error</li>
</ul>
</li>
<li>phrase : 응답 결과를 말로 풀어 씀</li>
</ul>
</li>
</ul>
<h3 id="🔶https-cache-cookie-proxy">🔶https://, Cache, Cookie, Proxy</h3>
<h4 id="🔸https">🔸https://</h4>
<p>http:// -&gt; https:// 형식은 암호화하여 내용을 전송한다는 의미. SSL.</p>
<h4 id="🔸cache">🔸Cache</h4>
<p>이미 다운로드 받은 저장된 파일을 읽어서 성능을 향상 시키는 기법</p>
<h4 id="🔸cookie">🔸Cookie</h4>
<p>사용자 정보와 상태를 서버에 전송, 기억.</p>
<h4 id="🔸proxy">🔸Proxy</h4>
<p>중개서버, 서버 분산.</p>
<hr>
<h3 id="🙆♀️참고🙆♂️">🙆‍♀️참고🙆‍♂️</h3>
<p><a href="https://opentutorials.org/course/4848">생활코딩</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SpringBoot 정리(ing)]]></title>
            <link>https://velog.io/@heyjeong-go/SpringBoot-%EC%A0%95%EB%A6%ACing</link>
            <guid>https://velog.io/@heyjeong-go/SpringBoot-%EC%A0%95%EB%A6%ACing</guid>
            <pubDate>Mon, 05 Dec 2022 14:20:44 GMT</pubDate>
            <description><![CDATA[<h2 id="❗spring❗">❗Spring❗</h2>
<h4 id="🔸spring의-첫-걸음">🔸Spring의 첫 걸음</h4>
<ul>
<li>2002년 로드 존슨은 EJB의 문제점을 지적하며 BeanFactory, ApplicationContext, POJO, DI, IOC 등의 개념을 포함하여 EJB없이도 고품질의 애플리케이션을 개발할 수 있음을 보여줌.</li>
<li>EJB란, Java Bean이란 자바 객체를 재사용이 가능하도록, 즉 컴포넌트화시킬 수 있는 코딩 방침을 의미함.</li>
</ul>
<h3 id="🔶spring참고">🔶Spring(<a href="https://spring.io/projects/spring-framework#overview">참고</a>)</h3>
<ul>
<li>자바 언어 기반의 프레임워크</li>
<li>따라서 객체 지향 프로그래밍의 특징을 보이며 그 중 <strong>다형성</strong>을 통해 프로그램을 유연하고 변경이 용이하게 만듦.</li>
</ul>
<h3 id="🔶다형성">🔶다형성</h3>
<p><strong>하나의 객체가 여러 형태를 가질 수 있다</strong>는 객체 지향 특징 중 하나.</p>
<p>📌즉 <strong>역할과 구현</strong>을 구분함.📌
✔️역할 = 인터페이스
✔️구현 = 인터페이스를 구현한 클래스, 구현 객체</p>
<h4 id="🔸정말-심플한-예제">🔸정말 심플한 예제</h4>
<p>&lt;People.java&gt;</p>
<pre><code class="language-java">package polymorphismEx;

// 역할 -&gt; 인터페이스
public interface People {

    void talk();

}</code></pre>
<p>&lt;Man.java&gt;</p>
<pre><code class="language-java">package polymorphismEx;

// 구현 -&gt; 인터페이스를 구현한 클래스
public class Man implements People {

    @Override
    public void talk() {
        System.out.println(&quot;Man.talk()&quot;);
    }

}</code></pre>
<p>&lt;Woman.java&gt;</p>
<pre><code class="language-java">package polymorphismEx;

// 구현 -&gt; 인터페이스를 구현한 클래스
public class Woman implements People {

    @Override
    public void talk() {
        System.out.println(&quot;Woman.talk()&quot;);
    }

}</code></pre>
<p>&lt;Main.java&gt;</p>
<pre><code class="language-java">package polymorphismEx;

public class Main {

    public static void main(String[] args) {

        People people = new Woman();
        // People people = new Man();

        people.talk();
    }

}</code></pre>
<p>&lt;출력&gt;</p>
<ul>
<li>People people = new Woman(); 인 경우
<img src="https://velog.velcdn.com/images/heyjeong-go/post/d3ddf99c-d997-4f7b-b442-3a834fcc1074/image.png" alt=""></li>
<li>People people = new Man(); 인 경우
<img src="https://velog.velcdn.com/images/heyjeong-go/post/a5984507-d000-4084-8d59-50d1a9cad930/image.png" alt=""></li>
</ul>
<h4 id="🔸장점">🔸장점</h4>
<ul>
<li>유연하고 변경이 용이하며 확장 가능한 설계가 가능해짐.</li>
<li>인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경 가능.</li>
<li>클라이언트 - 서버 관계에서는, 클라이언트를 변경하지 않고 서버의 구현 기능을 유연하게 변경할 수 있다.<ul>
<li>클라이언트에서 인터페이스만 알면되고 서버에서 구현 기능을 설계하면 되기 때문.</li>
</ul>
</li>
</ul>
<h4 id="🔸단점">🔸단점</h4>
<ul>
<li>인터페이스 자체가 변하면 인터페이스 뿐만 아니라 구현 객체도 큰 변경이 발생하게 됨.</li>
</ul>
<h4 id="🔸스프링에서의-다형성">🔸스프링에서의 다형성</h4>
<ul>
<li>스프링은 다형성을 극대화해서 이용할 수 있게 도와줌.</li>
<li><strong>IoC( 제어의 역전 ), DI( 의존관계 주입 ) 등 스프링에서의 주요 개념들은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원함.</strong></li>
</ul>
<h3 id="🔶solid">🔶SOLID</h3>
<p>객체 지향 개발 5대 원리</p>
<h4 id="🔸srp-단일-책임-원칙single-responsibility-principle">🔸SRP 단일 책임 원칙(Single responsibility principle)</h4>
<ul>
<li>하나의 클래스는 하나의 책임만.</li>
</ul>
<h4 id="🔸ocp-개방-폐쇄-원칙openclosed-principle">🔸OCP 개방-폐쇄 원칙(Open/closed principle)</h4>
<ul>
<li>확장에는 열려 있으나 변경에는 닫혀 있어야 함.</li>
</ul>
<h4 id="🔸lsp-리스코프-치환-원칙liskov-substitution-principle">🔸LSP 리스코프 치환 원칙(Liskov substitution principle)</h4>
<ul>
<li>프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀수 있어야 함.</li>
</ul>
<h4 id="🔸isp-인터페이스-분리-원칙interface-segregation-principle">🔸ISP 인터페이스 분리 원칙(Interface segregation principle)</h4>
<ul>
<li>특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 나음.</li>
</ul>
<h4 id="🔸dip-의존관계-역전-원칙dependency-inversion-principle">🔸DIP 의존관계 역전 원칙(Dependency inversion principle)</h4>
<ul>
<li>구현 클래스에 의존하지 말고, 인터페이스에 의존.</li>
</ul>
<blockquote>
<p>🔻다형성에서 OCP, DIP 위배하는 경우가 발생할 수 있음.</p>
</blockquote>
<ul>
<li>OCP 위반의 경우 : Main.java의 main함수 안에서 구현 객체인 Woman(), Man() 클래스를 변경하기 위해 코드를 변경해야 함.</li>
<li>DIP 위반의 경우 : 또한 구현 클래스를 직접 선택( = 의존 )하고 있음.</li>
<li><strong>해당 사항들은 스프링 컨테이너( DI, IoC 컨테이너 )와 DI를 통해 문제점 해결 가능</strong></li>
</ul>
<hr>
<h2 id="❗di-ioc❗">❗DI, IoC❗</h2>
<h3 id="🔶di-dependency-injection-">🔶DI( Dependency Injection )</h3>
<p><strong>객체를 직접 생성하는 것이 아닌 외부에서 생성한 후 주입 시켜주는 방식</strong></p>
<h4 id="🔸의존성에-대한-정말-간단한-예제">🔸의존성에 대한 정말 간단한 예제</h4>
<p>&lt;Paper.java&gt;</p>
<pre><code class="language-java">public class Paper {

    private Pen pen;

    public Paper() {
        pen = new Pen();
    }

    public void draw() {
        pen.draw();
    }
}</code></pre>
<p>&lt;Pen.java&gt;</p>
<pre><code class="language-java">public class Pen {

    private String redPen = &quot;redpen is drawing&quot;;

    public void draw() {

        System.out.println(redPen);

    }
}</code></pre>
<p>&lt;dependencyExMain.java&gt;</p>
<pre><code class="language-java">public class dependencyExMain {

    public static void main(String[] args) {

        Paper paper = new Paper();

        paper.draw();
    }
}</code></pre>
<p>&lt;코드 설명&gt;</p>
<ul>
<li><strong>Paper class가 Pen class에 의존성을 가지고 있음.</strong><ul>
<li>Paper class의 생성자에서, new 생성자를 통해 Pen 객체를 생성해줌.</li>
<li>Paper draw() 메소드를 실행하기 위해, Pen class의 draw() 메소드가 필요함.</li>
</ul>
</li>
</ul>
<p><strong>-&gt; 의존성으로 인해 Unit Test 및 Code 변경이 어려워짐.</strong></p>
<h4 id="🔸di-방법">🔸DI 방법</h4>
<p>의존관계 주입 방법은 </p>
<ul>
<li>생성자 주입</li>
<li>수정자 주입(setter 주입)</li>
<li>필드 주입</li>
<li>일반 메서드 주입</li>
</ul>
<p>이렇게 네 가지 정도가 있다. 
이 중, 생성자 주입과 수정자 주입이 일반적으로 쓰임.</p>
<h4 id="🔸생성자-주입">🔸생성자 주입</h4>
<p>생성자를 통해 의존 관계를 주입 받는 방법</p>
<p>&lt;Paper.java&gt;</p>
<pre><code class="language-java">package dependencyEx;

public class Paper {

    private final Pen pen;

    public Paper(Pen pen) {
        this.pen = pen;
    }

    public void draw() {
        pen.draw();
    }
}</code></pre>
<ul>
<li>불변 : 생성자 호출시점에 딱 1번만 호출되므로 값이 변하지 않음.</li>
<li>필수 : private final 로 선언함으로 무조건 값이 있어야 함.</li>
</ul>
<h4 id="🔸수정자-주입">🔸수정자 주입</h4>
<p>setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해서 의존관계를 주입하는 방법</p>
<h3 id="🔶">🔶</h3>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[Windbg에 대해]]></title>
            <link>https://velog.io/@heyjeong-go/Windbg%EC%97%90-%EB%8C%80%ED%95%B4</link>
            <guid>https://velog.io/@heyjeong-go/Windbg%EC%97%90-%EB%8C%80%ED%95%B4</guid>
            <pubDate>Sun, 06 Nov 2022 02:27:40 GMT</pubDate>
            <description><![CDATA[<h2 id="❗windbg-란❗">❗Windbg 란❗</h2>
<p>윈도우용 디버거</p>
<ul>
<li>디버거 : 응용프로그램이나 운영체제의 동작을 확인하고 제어할 수 있는 기능이 있어 어떤 동작을 분석하거나 문제를 확인하려는 목적으로 사용하는 도구<h3 id="🔶windbg-주요-기능">🔶Windbg 주요 기능</h3>
</li>
<li>응용프로그램 디버깅(유저모드 디버깅)</li>
<li>커널모드 드라이버 디버깅(커널모드 디버깅)</li>
<li>크래스 덤프 파일 분석</li>
<li>윈도우 시스템 분석</li>
<li>윈도우 시스템 분석</li>
<li>스크립트와 확장 DLL</li>
<li>디버깅 도움말</li>
<li>디버깅에 필요한 윈도우 내부의 리소스 정보를 상세하게 제공할 뿐만 아니라 리소스를 조작하는 기능도 제공</li>
<li>소스레벨 디버깅</li>
</ul>
<h3 id="🔶windbg-디버깅-용어">🔶Windbg 디버깅 용어</h3>
<h4 id="🔸덤프-디버깅">🔸덤프 디버깅</h4>
<p>유저모드나 커널모드에서 오류가 발생했을 때 생성되는 메모리 덤프 파일을 분석하면서 디버깅하는 것.</p>
<ul>
<li>메모리 덤프 파일 : 응용프로그램에 문제가 발생할 때 그 상태가 저장된 파일</li>
<li>오류 발생 시점의 레지스터, 콜 스택, 메모리, 프로세스, 스레드 정보 등이 저장돼 있음<h4 id="🔸디버그-심볼-파일">🔸디버그 심볼 파일</h4>
실행 파일을 빌드할 때 생성되는 디버그용 정보 파일</li>
<li>디버그용 정보 란, 실행 파일 안에 존재하는 함수나 변수들의 이름과 위치, 소스 파일, 소스 라인 정보<ul>
<li>Visual Studio에서 Debug 빌드 시 생성되는 xxx.pdb 확장자를 가진 파일 의미</li>
</ul>
</li>
<li>Debug빌드 시, 기본적으로 xxx.pdb 파일이 생성되지만 Release 빌드 시에는 기본적으로 xxx.pdb 파일이 생성되지 않음</li>
</ul>
<p>&lt;Visual Studio 2022에서 Realse 빌드 시, xxx.pdb파일 생성 설정&gt;</p>
<ol>
<li>프로젝트 우클릭 -&gt; C/C++ -&gt; 디버그 정보 형식 <strong>&#39;프로그램 데이터베이스(/Zi)&#39;</strong> 로 선택
<img src="https://velog.velcdn.com/images/heyjeong-go/post/68468970-1a30-4f05-a31c-9c6ed4268d2f/image.png" alt=""></li>
<li>링커 -&gt; 디버깅 -&gt; <strong>&#39;디버그 정보 생성(/DEBUG)&#39;</strong> 선택
<img src="https://velog.velcdn.com/images/heyjeong-go/post/8a40d538-9967-4ebe-a677-7bba95211bf1/image.png" alt=""></li>
</ol>
<h3 id="🔶windbg-다운로드">🔶Windbg 다운로드</h3>
<p><a href="https://m.blog.naver.com/dmsdl814/221803553487">여기</a> 참고하면 좋을 듯. 정리를 잘해놓으셨다.</p>
<hr>
<h3 id="🙆♀️참고🙆♂️">🙆‍♀️참고🙆‍♂️</h3>
<p>책 : Windows Debugging 2/e -WinDbg로 배우는 윈도우 디버깅 참고
<a href="https://m.blog.naver.com/dmsdl814/221803553487">Windbg 다운로드</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CreateEvent]]></title>
            <link>https://velog.io/@heyjeong-go/CreateEvent</link>
            <guid>https://velog.io/@heyjeong-go/CreateEvent</guid>
            <pubDate>Thu, 03 Nov 2022 12:01:14 GMT</pubDate>
            <description><![CDATA[<h3 id="🔶syntax">🔶Syntax</h3>
<pre><code class="language-c">HANDLE CreateEventA(
  [in, optional] LPSECURITY_ATTRIBUTES lpEventAttributes,
  [in]           BOOL                  bManualReset,
  [in]           BOOL                  bInitialState,
  [in, optional] LPCSTR                lpName
);</code></pre>
<p><em>lpEventAttributes</em></p>
<ul>
<li>SECURITY_ATTRIBUTES 구조체로 선언된 변수의 주소를 명시.<pre><code class="language-c">typedef struct _SECURITY_ATTRIBUTES {
     DWORD nLength;
     LPVOID lpSecurityDescriptor;
     BOOL bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;</code></pre>
</li>
<li>NULL 명시 시, 생성된 이벤트 객체의 핸들은 자식 프로세스에 상속되지 않으며 일반적인 보안 기술자가 명시된 걸로 간주함.<ul>
<li>현재 로그인되어 있는 사용자의 로그인 정보에 있는 ACL 또는 이벤트 객체를 생성한 프로세스의 ACL을 가져와 사용.</li>
</ul>
</li>
</ul>
<p><em>bManualReset</em></p>
<ul>
<li>TRUE 이면, 발생된 이벤트 정보가 계속 유지되는 이벤트 객체를 생성( 다시 FALSE 값을 설정하기 전까지 계속 TRUE 값 유지 )</li>
<li>FALSE 이면, 일정 조건 만족 시 자동으로 객체에 설정된 상태 값이 TRUE에서 FALSE로 변경되는 이벤트 객체 생성<ul>
<li>이벤트 객체에 TRUE 값이 설정되고 이벤트 객체의 상태를 확인하는 함수가 사용되면 이벤트 객체의 상태값이 TRUE에서 FALSE로 변경 됨.</li>
</ul>
</li>
</ul>
<p><em>bInitialState</em>
생성될 이벤트 객체의 TRUE 또는 FALSE 초깃값 설정. 이벤트 객체는 생성과 함께 이 상태 값을 가지게 됨.</p>
<p><em>LPCTSTR lpName</em>
이벤트 객체에 사용할 이름 명시</p>
<ul>
<li>이름의 길이는 MAX_PATH, 대소문자 구별</li>
<li>같은 프로세스 내에 있는 스레드 간끼리 사용할 경우, NULL 사용 가능하나 서로 다른 프로세스에 있는 스레드 간에 이벤트 객체를 공유하고 싶다면 동일한 이름 적어서 사용 가능<ul>
<li>동일한 이름을 사용하여 이벤트 객체 공유 시, 먼저 만들어진 이벤트 객체의 정보가 우선시되며 나중에 사용한 CreateEvent 함수의 bManualReset, bInitialState의 값은 무시 됨.</li>
</ul>
</li>
<li>명시한 이름이 커널 객체에 사용되고 있다면 객체의 공유가 불가능하기에 NULL 값 반환 됨.</li>
</ul>
<h3 id="🔸return">🔸Return</h3>
<ul>
<li>성공 시, 생성된 이벤트 객체의 핸들이 반환.<ul>
<li>동일한 이름으로 생성된 이벤트 객체가 이미 생성되어 있다면 해당 객체의 핸들이 반환될 것이며, ERROR_ALREADY_EXISTS 반환 됨.</li>
</ul>
</li>
<li>실패 시, NULL 값 반환<ul>
<li>자세한 오류 원인은 GetLastError</li>
</ul>
</li>
</ul>
<h4 id="🔸이벤트-객체의-사용-끝난-후-closehandleh_event_object-로-제거해줘야-함">🔸이벤트 객체의 사용 끝난 후, CloseHandle(h_event_object) 로 제거해줘야 함.</h4>
<h3 id="🔶setevent-함수-resetevent-함수">🔶SetEvent 함수, ResetEvent 함수</h3>
<ul>
<li>SetEvent(HANDLE hEvent) : 이벤트 객체의 상태 값 TRUE로 설정</li>
<li>ResetEvent(HANDLE hEvent) : 이벤트 객체의 상태 값 FALSE로 설정<pre><code class="language-c">// 수동 해제, 초깃값 FALSE
HANDLE h_event_object = CreateEvent(NULL, TRUE, FALSE, NULL);
</code></pre>
</li>
</ul>
<p>// h_event_object 객체의 상태값 TRUE 상태로 변경
SetEvent(h_event_object);</p>
<p>// h_event_object 객체의 사용 중단
CloseHandle(h_event_object);</p>
<p>```</p>
<h3 id="🔶waitforsingleobject-함수">🔶WaitForSingleObject 함수</h3>
<p><a href="https://velog.io/@heyjeong-go/WaitForSingleObject">여기</a> 참고</p>
<hr>
<h3 id="🙆♀️참고🙆♂️">🙆‍♀️참고🙆‍♂️</h3>
<p><a href="https://blog.naver.com/tipsware/221211432527">CreateEvent()</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[typedef, unsigned]]></title>
            <link>https://velog.io/@heyjeong-go/typedef-unsigned</link>
            <guid>https://velog.io/@heyjeong-go/typedef-unsigned</guid>
            <pubDate>Thu, 03 Nov 2022 10:49:36 GMT</pubDate>
            <description><![CDATA[<h2 id="❗typedef❗">❗typedef❗</h2>
<ul>
<li>typedef : 프로그래머가 타입의 별칭을 생성하고, 실제 타입 이름 대신 별칭을 사용할 수 있다.<ul>
<li>즉, C++에서 이미 정의된 자료형 또는 사용자 정의 자료형보다 더 짧거나 의미 있는 이름을 지어줄 수 있다.</li>
<li>typedef + 자료형 + 별칭 이름<ul>
<li>예시) typedef int num_t;</li>
</ul>
</li>
<li>별칭은 관습적으로 &#39;_t&#39; 접미사 사용하여 선언</li>
<li>쓰는 이유( 좀 더 자세한 이유는 참고 확인 )<ul>
<li>가독성을 위해</li>
<li>플랫폼 독립 코딩</li>
<li>복잡한 타입을 간단하게 만들기</li>
</ul>
</li>
<li>C++ 11은 typedef 대신 using 선언 가능</li>
</ul>
</li>
</ul>
<h2 id="❗unsigned❗">❗unsigned❗</h2>
<ul>
<li>unsigned : unsinged는 &#39;부호 없는 정수&#39; 의미하며 양수 값만 가질 수 있는 정수이다.</li>
</ul>
<hr>
<h3 id="🙆♀️참고🙆♂️">🙆‍♀️참고🙆‍♂️</h3>
<p><a href="https://boycoding.tistory.com/182">typedef</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[미리 컴파일 된 헤더파일]]></title>
            <link>https://velog.io/@heyjeong-go/%EB%AF%B8%EB%A6%AC-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EB%90%9C-%ED%97%A4%EB%8D%94%ED%8C%8C%EC%9D%BC</link>
            <guid>https://velog.io/@heyjeong-go/%EB%AF%B8%EB%A6%AC-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EB%90%9C-%ED%97%A4%EB%8D%94%ED%8C%8C%EC%9D%BC</guid>
            <pubDate>Thu, 03 Nov 2022 10:48:01 GMT</pubDate>
            <description><![CDATA[<h2 id="❗미리-컴파일된-헤더-파일pchh❗">❗미리 컴파일된 헤더 파일(pch.h)❗</h2>
<ul>
<li>VS 2017 및 이전 버전에서는 stdafx.h 였음</li>
<li>파일의 목적은 빌드 프로세스의 속도를 높이기 위함.</li>
<li>#include &lt;vector.h&gt; 등과 같은 표준 라이브러리 헤더 파일은 여기에 포함되어야 함.</li>
<li>미리 컴파일 된 헤더 파일은 #include &quot;pch.h&quot; 를 한 모든 파일이 수정될 때만 컴파일 됨. 프로젝트 소스 코드를 변경하는 경우에만 빌드가 미리 컴파일된 헤더에 대한 컴파일을 건너 뜀.</li>
<li>소스 코드를 미리 컴파일 해야 하는 경우<ul>
<li>자주 변경되지 않는 코드의 본문 중 대부분을 항상 사용하는 경우</li>
<li>프로그램은 여러 모듈로 구성되며, 이 모든 모듈은 포함 파일 표준 집합 및 동일한 컴파일 옵션을 사용. 이 경우 모든 포함 파일을 미리 컴파일된 하나의 헤더로 미리 컴파일 할 수 있음.</li>
</ul>
</li>
<li>&#39;프로젝트 속성 -&gt; C/C++ -&gt; 미리 컴파일된 헤더&#39; 에서 속성값 변경 가능
<img src="https://velog.velcdn.com/images/heyjeong-go/post/dd297ef5-db3e-4d7e-a29c-214c0d28f365/image.png" alt="">
<img src="https://velog.velcdn.com/images/heyjeong-go/post/05b4877c-854d-4336-bd79-710f9fb367d1/image.png" alt=""><ul>
<li>사용(/Yu) 선택 시, pch.h 파일을 사용한다는 의미</li>
<li>만들기(/Yc) 선택 시 : pch.h 파일을 만들겠다는 의미</li>
<li>사실 두 개의 차이는 잘 모르겠으나, 미리 컴파일된 헤더 파일로 인한 에러가 생겼다면 두 개의 속성값 중 하나를 수정하면 될 지도...</li>
</ul>
</li>
</ul>
<hr>
<h3 id="🙆♀️참고🙆♂️">🙆‍♀️참고🙆‍♂️</h3>
<p><a href="https://learn.microsoft.com/ko-kr/cpp/build/creating-precompiled-header-files?view=msvc-170">미리 컴파일된 헤더</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java - Singleton 패턴]]></title>
            <link>https://velog.io/@heyjeong-go/Java-Singleton-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@heyjeong-go/Java-Singleton-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Thu, 27 Oct 2022 12:06:51 GMT</pubDate>
            <description><![CDATA[<p>인프런의 <a href="https://www.inflearn.com/course/%EC%9E%90%EB%B0%94-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%9E%85%EB%AC%B8#">&quot;Do it! 자바 프로그래밍 입문&quot;</a> 강의에서 정리한 내용</p>
<hr>
<h3 id="🔶singleton-패턴">🔶Singleton 패턴</h3>
<p>전 시스템에 단 하나의 인스턴스만이 존재하도록 구현하는 방식
<img src="https://velog.velcdn.com/images/heyjeong-go/post/3851092e-f6ea-4f19-8a9f-4e026f53fa69/image.png" alt=""></p>
<h4 id="🔻singleton-생성-예시">🔻singleton 생성 예시</h4>
<pre><code class="language-java">public class Singleton {

    private static Singleton singleton = new Singleton();    // null

    private Singleton() {
        System.out.println(&quot;인스턴스를 생성했습니다.&quot;);
    }

    public static Singleton getInstanec() {
        if(singleton == null)
            singleton = new Singleton();

        return singleton;
    }
}</code></pre>
<h4 id="🔻예제-1">🔻예제 1</h4>
<p>&lt;company.java&gt;</p>
<pre><code class="language-java">package SingletonEx;

public class Company {

    private static Company instance = new Company(); // 유일하게 사용될 인스턴스

    private Company() {
    }

    public static Company getInstance() {

        if (null == instance)
            instance = new Company();

        return instance;
    }
}</code></pre>
<p>&lt;CompanyTest.java&gt;</p>
<pre><code class="language-java">package SingletonEx;

public class CompanyTest {

    public static void main(String[] args) {

        Company c1 = Company.getInstance();
        Company c2 = Company.getInstance();

        System.out.println(c1);
        System.out.println(c2);
    }
}

// 출력
// SingletonEx.Company@4517d9a3
// SingletonEx.Company@4517d9a3</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java에서의 static 정의]]></title>
            <link>https://velog.io/@heyjeong-go/Java%EC%97%90%EC%84%9C%EC%9D%98-static-%EC%A0%95%EC%9D%98</link>
            <guid>https://velog.io/@heyjeong-go/Java%EC%97%90%EC%84%9C%EC%9D%98-static-%EC%A0%95%EC%9D%98</guid>
            <pubDate>Thu, 27 Oct 2022 11:44:23 GMT</pubDate>
            <description><![CDATA[<p>인프런의 <a href="https://www.inflearn.com/course/%EC%9E%90%EB%B0%94-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%EC%9E%85%EB%AC%B8#">&quot;Do it! 자바 프로그래밍 입문&quot;</a> 강의에서 정리한 내용</p>
<hr>
<h3 id="🔶static">🔶static</h3>
<ul>
<li>정적 변수란 의미</li>
<li>여러 개의 인스턴스가 같은 메모리의 값을 공유하기 위해 사용
<img src="https://velog.velcdn.com/images/heyjeong-go/post/e1ef3132-2ac4-45e3-b981-de830db43b40/image.png" alt=""></li>
<li>상수 영역, 정적 영역</li>
<li>static 변수는 인스턴스가 생성될 때 마다 다른 메모리를 가지는 것이 아니라 프로그램이 메모리에 적재(load)될 때 데이터 여역의 메모리에 생성 됨.<ul>
<li>클래스 이름으로 직접 참조 함.<pre><code class="language-java">Student.serialNum = 100;    // serailNum이 static 변수</code></pre>
</li>
<li>클래스 변수라고도 함.</li>
</ul>
</li>
</ul>
<h4 id="🔸예제-1">🔸예제 1</h4>
<p>학생들이 생설될 때 마다 학번을 부여해 줌.
학번은 증가할 때 마다 1씩 증가함.</p>
<p>&lt;Student.java&gt;</p>
<pre><code class="language-java">package staticEx;

public class Student {

    static int serialNum = 10000;

    int studentID;
    String studentName;

    public Student() {

        serialNum++;
        studentID = serialNum;
    }

}</code></pre>
<p>&lt;StudentTest1.java&gt;</p>
<pre><code class="language-java">package staticEx;

public class StudentTest1 {

    public static void main(String[] args) { // 단축키 psvm

        Student studentJ = new Student();
        System.out.println(studentJ.studentID);

        Student studentT = new Student();
        System.out.println(studentT.studentID);

        System.out.println(studentJ.serialNum);
        System.out.println(studentT.serialNum);
    }

    // 출력
    // 10001
    // 10002
    // 10002
    // 10002
}</code></pre>
<ul>
<li>new Student()를 생성할 때 마다, static 변수인 serialNum이 1씩 증가 됨.<ul>
<li>Student studentJ = new Student(); -&gt; 내부에서 serialNum++ 이 진행되고 studentID에 저장 됨.</li>
<li>Student studentT = new Student();</li>
</ul>
</li>
<li>인스턴스 객체에 static 변수를 사용할 때, 아래와 같은 경고문이 뜸
<img src="https://velog.velcdn.com/images/heyjeong-go/post/a012480e-aadf-499b-aa6f-52163d1bd5bd/image.png" alt=""><ul>
<li>클래스 이름으로 static 변수는 참조해줘야 함. -&gt; Student.serialNum 식으로 수정해줘야 함.</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/heyjeong-go/post/b732c308-f007-411a-9367-72f17f790895/image.png" alt=""></p>
<h4 id="🔻static-변수-예">🔻static 변수 예</h4>
<ul>
<li>여러 인스턴스가 하나의 메모리 값을 공유할 때 필요</li>
<li>기준이 되는 값은 static 변수로 생성하여 유지 함.
<img src="https://velog.velcdn.com/images/heyjeong-go/post/93fbbf4b-5a53-4923-922c-de945e1d7ad7/image.png" alt=""></li>
</ul>
<h4 id="🔸예제-2">🔸예제 2</h4>
<p>만약, student.java를 아래와 같이 수정한다면...</p>
<pre><code class="language-java">package staticEx;

public class Student {

    private static int serialNum = 10000;

    int studentID;
    String studentName;

    public Student() {

        serialNum++;
        studentID = serialNum;
    }

    public static int getSerialNum() {

        int i = 10; // 지역 변수

        i++;
        System.out.println(i);

        studentName = &quot;test&quot;;   // 멤버 변수, 인스턴스 변수 =&gt; 에러남

        return serialNum;   // static 변수, 클래스 변수
    }

}</code></pre>
<ul>
<li><strong>static 메서드 안에서는 멤버 변수(인스턴스 변수) 사용 불가능.</strong><ul>
<li>왜냐하면 static은 프로그램이 로드 될 때, 메모리에 적재가 되지만 멤버 변수(인스턴스 변수)는 new로 객체가 생성될 때(인스턴스가 생성 될 때?) 생성이 되기 때문에 에러가 남.</li>
<li>즉, 인스턴스 변수의 경우 꼭 인스턴스가 먼저 생성되어야 하므로 static 메서드에서는 생성이 불확실한 인스턴스 변수를 사용할 수 없음.</li>
</ul>
</li>
</ul>
<h3 id="🔶변수의-유효-범위-정리">🔶변수의 유효 범위 정리</h3>
<p><img src="https://velog.velcdn.com/images/heyjeong-go/post/1519255a-9547-444f-82cf-7dc1239476b2/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Visual Code에서 Java Project 생성]]></title>
            <link>https://velog.io/@heyjeong-go/Visual-Code%EC%97%90%EC%84%9C-Java-Project-%EC%83%9D%EC%84%B1</link>
            <guid>https://velog.io/@heyjeong-go/Visual-Code%EC%97%90%EC%84%9C-Java-Project-%EC%83%9D%EC%84%B1</guid>
            <pubDate>Thu, 27 Oct 2022 11:18:51 GMT</pubDate>
            <description><![CDATA[<ol>
<li>Ctrl + Shift + P 클릭</li>
</ol>
<ul>
<li>명령어 창 실행</li>
</ul>
<ol start="2">
<li>Create Java Project 클릭
<img src="https://velog.velcdn.com/images/heyjeong-go/post/5d155b88-047c-40ba-b645-1aa36ade8da8/image.png" alt=""></li>
</ol>
<p>2-1. &#39;Select the project type&#39; 을 고르라고 나오는데 No bulid tools 선택</p>
<ul>
<li>나머지는 무슨 project type인지 알아봐야 할 듯
<img src="https://velog.velcdn.com/images/heyjeong-go/post/ec911972-5599-4494-949d-a07afd97a996/image.png" alt=""></li>
</ul>
<ol start="3">
<li><p>Java Project를 생성할 폴더를 생성 또는 선택 해주기
<img src="https://velog.velcdn.com/images/heyjeong-go/post/3fa37972-a375-44b9-b68f-021bf176fe06/image.png" alt=""></p>
</li>
<li><p>Java Project Name 설정
<img src="https://velog.velcdn.com/images/heyjeong-go/post/7e29e476-0062-4eb5-ae29-fcb4fdacd518/image.png" alt=""></p>
</li>
<li><p>Java Project 생성 완료
<img src="https://velog.velcdn.com/images/heyjeong-go/post/6de36af5-fe7f-420c-a400-6ccc67d5f516/image.png" alt=""></p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring - DI, IOC]]></title>
            <link>https://velog.io/@heyjeong-go/Spring-DI-IOC</link>
            <guid>https://velog.io/@heyjeong-go/Spring-DI-IOC</guid>
            <pubDate>Thu, 29 Sep 2022 12:13:42 GMT</pubDate>
            <description><![CDATA[<h2 id="❗didependency-injection❗">❗DI(Dependency Injection)❗</h2>
<ul>
<li>스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입기능</li>
<li><strong>객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식</strong></li>
<li>DI(의존성 주입)를 통해 모듈 간의 결합도가 낮아지고 유연성이 높아짐</li>
</ul>
<hr>
<h4 id="🔻의존성이란">🔻의존성이란?</h4>
<pre><code class="language-java">public class Cook {

    private Knife knife;

    public Cook() {
        knife = new Knife();
    }

    public void cook(Food food) {
        knife.cut(food);
    }
}</code></pre>
<ul>
<li>cook class는 cook(Food food) 메소드를 실행 할 때, knife.cut() 을 위해 Knife class가 필요</li>
<li><blockquote>
<p>이러한 사항을 <strong>Cook class가 Knife에 의존성을 가지고 있다 라고 함.</strong></p>
</blockquote>
</li>
<li>의존성에 의한 문제점<ul>
<li>Unit Test가 어려워짐<ul>
<li>내부에서 직접 생성하는 객체에 대해서 mocking을 할 방법이 없기때문...</li>
</ul>
</li>
<li>Code의 변경이 어려워짐<ul>
<li>Knife class 변경 시, Knife class에 의존하고 있는 Cook class도 변경 해줘야 함</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h3 id="🔸그래서-di란">🔸그래서 DI란~</h3>
<p><img src="https://velog.velcdn.com/images/heyjeong-go/post/6ab90d09-bac3-4489-9a59-639d7c7a06d6/image.png" alt=""></p>
<ol>
<li>방법 1 : A객체가 B와 C객체를 New 생성자를 통해 직접 생성하는 방법</li>
<li>방법 2 : 외부에서 생성된 객체를 setter()나 생성자를 통해 사용하는 방법</li>
</ol>
<ul>
<li><p>방법 2가 의존성 주입의 예시</p>
</li>
<li><p>A객체에서 B, C 객체를 사용(의존)할 때 A객체에서 직접 생성하는 것이 아니라 <strong>외부(IOC 컨테이너)에서 생성된 B,C 객체를 조립(주입)시켜 setter 혹은 생성자를 통해 사용하는 방법</strong>
<img src="https://velog.velcdn.com/images/heyjeong-go/post/e38f4994-12a7-495a-b0f2-6fc773c79d7a/image.png" alt="">
🎈 의존성 주입 예제</p>
</li>
<li><p>생성자를 통해 전달 받음</p>
<pre><code class="language-java">public class Cook {

  private Knife knife;

  public Cook(Knife knife) {
      this.knife = knife;
  }
}   </code></pre>
</li>
<li><p>setter를 통해 전달 받음</p>
<pre><code class="language-java">public void setKnife(Knife knife) {
  this.knife = knife;
}</code></pre>
<blockquote>
<p>📚나만의 정리</p>
</blockquote>
</li>
<li><p>하나의 클래스 내부에서 다른 객체를 직접 생성(new 선언 등)해주는 것이 아닌, 외부에서 생성된 객체를 하나의 클래스에서 주입받는 것.</p>
</li>
</ul>
<hr>
<h4 id="🔻bean-컨테이너">🔻Bean 컨테이너</h4>
<ul>
<li>스프링에서는 객체를 Bean 이라고 부름<ul>
<li>스프링 IOC 컨테이너가 관리하는 객체, Spring IOC 컨테이너에 의해서 인스턴스화되고 조립 및 관리되는 객체</li>
</ul>
</li>
<li>프로젝트가 실행될 때 사용자가 Bean으로 관리하는 객체들의 생성과 소멸에 관련된 작업을 자동적으로 수행해주는데 객체가 생성되는 곳을 스프링에서는 Bean 컨테이너라고 부름<h4 id="🔻ioc-containerspring-container">🔻IOC Container(Spring Container)</h4>
</li>
<li>사용자가 작성한 메타데이터(xml 파일 또는 @(어노테이션))에 따라 Bean 클래스를 생성 및 관리하는 Spring의 핵심 컴포넌트</li>
</ul>
<hr>
<h2 id="❗iocinversion-of-control❗">❗IOC(Inversion of Control)❗</h2>
<ul>
<li>&quot;제어의 역전&quot; 이라는 의미, 간단히 말해 &quot;제어의 흐름을 바꾼다&quot; 라고 함</li>
<li><strong>메소드나 객체의 호출작업을 개발자가 결정하는 것이 아닌, 외부에서 결정되는 것을 의미</strong></li>
<li>객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 함</li>
<li>스프링이 모든 의존성 객체를 스프링이 실행될 때 다 만들어주고 필요한 곳에 주입시켜줌 </li>
<li><blockquote>
<p><strong>Bean들은 싱글턴 패턴의 특징을 가짐</strong>( 객체가 한번만 생성됨 )</p>
</blockquote>
</li>
<li>제어의 흐름을 사용자가 컨트롤 하는 것이 아닌 스프링에게 맡겨 작업을 처리하게 됨<h3 id="🔸그래서-ioc-란">🔸그래서 IOC 란~</h3>
</li>
<li>일반적으로 의존성에 대한 제어권은 객체 자기 자신이 갖음</li>
</ul>
<p>&lt;예제1&gt;</p>
<ul>
<li><p>Sample class에서 Apple 객체를 불러옴</p>
</li>
<li><p>의존관계는 new 라는 키워드를 통해 생성됨</p>
<pre><code class="language-java">class Sample{
  private Apple apple = new Apple();
}</code></pre>
<p>&lt;예제2&gt;</p>
</li>
<li><p>SampleTest class에서 Apple 객체를 생성한 뒤 Sample class의 생성자로 주입시켜줌</p>
</li>
<li><p>Sample이 직접 Apple을 생성하는 것이 아니라 생성자로 주입 받음</p>
<pre><code class="language-java">class Sample{
  private Apple apple;

  public Sample(Apple apple) {
      this.apple = apple;
  }
}
</code></pre>
</li>
</ul>
<p>class SampleTest{</p>
<pre><code>Apple apple = new Apple();
Sample sample = new Sample(apple);</code></pre><p>}</p>
<pre><code>- &lt;예제1&gt;에서 Apple 객체의 제어권이 Sample에게 있었다면, &lt;예제2&gt;에서는 SampleTest에게 있음
- **이처럼 의존성을 역전시켜 제어권을 직접 갖지 않는 것을 IOC라고 하며, 의존성을 외부에서 주입시켜 주는 것을 DI라고 함**

#### 🔻@Bean, @Component 차이
- @Configuration 은 스프링 IOC Container에게 해당 클래스를 Bean 구성 Class임을 알려주는 것
- @Component는 개발자가 직접 작성한 class를 Bean으로 만드는 것
  + @Component를 사용한 Bean의 의존성 주입은 @AutoWired 를 이용하여 할 수 있음
- @Bean은 개발자가 작성한 Method를 통해 반환되는 객체를 Bean으로 만드는 것
- 자세한 내용 [여기](https://galid1.tistory.com/494?category=769011) 참고

***
## 🙆‍♀️참고🙆‍♂️
[[Spring] DI, IoC 정리](https://velog.io/@gillog/Spring-DIDependency-Injection)
[Spring - Spring을 왜 사용하나요?(DI)](https://galid1.tistory.com/493?category=769011)
[스프링(Spring) - DI(Depedency Injection) 개념과 예제[공부해서 남 주자]](https://private.tistory.com/39?category=655784)
[[스프링] IoC(Inversion of Control), DI(Dependency Injection), Spring Container, Bean 정리]
(https://leveloper.tistory.com/33)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[WaitForSingleObject]]></title>
            <link>https://velog.io/@heyjeong-go/WaitForSingleObject</link>
            <guid>https://velog.io/@heyjeong-go/WaitForSingleObject</guid>
            <pubDate>Fri, 23 Sep 2022 08:34:42 GMT</pubDate>
            <description><![CDATA[<ul>
<li>지정된 개체가 신호를 받은 상태가 되거나 시간 제한 간격이 경과할 때까지 기다림</li>
<li>지정된 개체의 현재 상태를 확인 -&gt; 개체의 상태가 신호가 없는 경우 -&gt;  호출 스레드는 개체가 신호를 받거나 시간 제한 간격이 경과할 때까지 대기 상태에 들어감</li>
<li>경고 가능한 대기 상태를 입력하려면 WaitForSingleObjectEx 함수를, 여러 객체를 기다리려면 WaitForMultipleObjects 를 사용</li>
</ul>
<hr>
<h3 id="syntax">Syntax</h3>
<pre><code class="language-c">DWORD WaitForSingleObject(
  [in] HANDLE hHandle,
  [in] DWORD  dwMilliseconds
);</code></pre>
<p><em>hHandle</em>
개체에 대한 핸들</p>
<ul>
<li>대기가 아직 보류 중인 동안 이 핸들이 닫히면 함수의 동작이 정의되지 않음( 오류가 발생한다는 의미 인 듯. 이 함수를 호출한 부분이나 호출당한 부분에서 행이 걸리거나... )</li>
<li>핸들에는 SYNCHRONIZE(동기화) 액세스 권한 필요<ul>
<li>이것도 스레드 개념이니까..?</li>
</ul>
</li>
<li>WaitForSingleObject API 끝난 후 CloseHandle( <em>hHandle</em> ); 호출해줘서 핸들 닫기!</li>
</ul>
<p><em>dwMilliseconds</em>
타임아웃 시간</p>
<ul>
<li>INFINITE 이면 객체가 신호를 받을 때만 함수가 반환<ul>
<li>신호를 받을 때 까지 무한정 대기</li>
</ul>
</li>
</ul>
<h3 id="return">Return</h3>
<ul>
<li>실패 시, WAIT_FAILED( (DWORD)0xFFFFFFFF ) 리턴<ul>
<li>확장된 오류 정보를 얻으려면 GetLastError() 를 호출</li>
</ul>
</li>
<li>성공 시<ul>
<li>WAIT_ABANDONED : 지정된 오브젝트는 파기 되어진 뮤텍스  오브젝트 였다. 이 뮤텍스 오브젝트를 소유한 스레드가 뮤텍스 오브젝트의 소유권을 풀어주지 않고 종료했다. 그래서 그 뮤텍스 오브젝트의 소유권이 호출한 쪽 스레드로 옮겨져 그 뮤텍스는 비시그널 상태로 설정되었다.<ul>
<li>이 경우, ResetEvent( hHandle ) 호출하여 해당 개체에 대한 핸들을 reset 하고 다시 WaitForSingleObject() 호출</li>
</ul>
</li>
<li>WAIT_OBJECT_0 : Event가 신호(Signal) 상태가 됨( 대표적으로 성공을 리턴했다고 봐야할 듯 )</li>
<li>WAIT_TIMEOUT : 타임아웃 시간이 경과할 때까지 시그널 생태가 되지 않음.</li>
</ul>
</li>
</ul>
<h3 id="기타">기타</h3>
<ul>
<li>CreateEvent(), SetEvent(), ResetEvent() 와 함께 쓰일 수 있는 듯</li>
<li>CreateProcess() 호출한 후에도 쓰일 수 있음. 아마도</li>
</ul>
<blockquote>
<p>참고</p>
</blockquote>
<ul>
<li><a href="https://tjstory.tistory.com/18">https://tjstory.tistory.com/18</a></li>
<li><a href="https://wwwi.tistory.com/165">https://wwwi.tistory.com/165</a></li>
<li><a href="https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject">https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Controller, Service, DAO, DTO]]></title>
            <link>https://velog.io/@heyjeong-go/Controller-Service-DAO-DTO</link>
            <guid>https://velog.io/@heyjeong-go/Controller-Service-DAO-DTO</guid>
            <pubDate>Thu, 22 Sep 2022 10:56:07 GMT</pubDate>
            <description><![CDATA[<h3 id="controller">Controller</h3>
<ul>
<li>사용자의 요청(request)을 어떻게 처리할지 결정</li>
<li>어노테이션<ul>
<li>@Controller : Controller의 역할을 수행한다고 명시해주는 어노테이션</li>
<li>@RestController</li>
<li>@PostMapping</li>
<li>@GetMapping</li>
<li>@RequiredArgsConstructor : 초기화 되지 않은 final 필드나 @NonNull이 붙은 필드에 대해 생성자 생성<ul>
<li>주로 의존성 주입(Dependency Injection)편의성을 위해서 사용<blockquote>
<p><strong>스프링 의존성 주입</strong>
어떠한 빈(Bean)에 생성자가 오직 하나만 있고, 생성자의 파라미터 타입이 빈으로 등록 가능한 존재라면 이 빈은 @Autowired 없이도 의존성 주입이 가능</p>
</blockquote>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>&lt;Controller 코드 예시&gt;</p>
<pre><code class="language-java">package com.test.demo;

import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
public class userController {

    private final userService userService;

    // 회원가입을 할 수 있는 API...
    @PostMapping(&quot;/join&quot;)
    public String join(@RequestBody userDto userInfo) {

        String userId = userService.join(userInfo);

        return userId;

    }

    // 회원가입된 유저중에 특정 유저 찾음
    @GetMapping(&quot;/find&quot;)
    public String findUser(@RequestParam String id) {

        String result = userService.findUser(id);

        if (result == null) {

            return &quot;error&quot;;

        }

        return result;
    }
}</code></pre>
<h3 id="service">Service</h3>
<ul>
<li>사용자의 요청(request)에 대해 어떤 처리를 할지 결정</li>
<li>어노테이션<ul>
<li>@Service
&lt;Service 코드 예시&gt;<pre><code class="language-java">package com.test.demo;
</code></pre>
</li>
</ul>
</li>
</ul>
<p>import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;</p>
<p>@Service
@RequiredArgsConstructor
public class userService {</p>
<pre><code>private final userDao userDao;

// 회원가입된 유저중에 특정 유저 찾기
public String findUser(String id) {

    return userDao.select(id);

}

// 회원가입
public String join(userDto userInfo) {

    String key = userInfo.getId();

    String value = userInfo.getUserName();

    return userDao.insert(key, value); // key 값 리턴됨

}</code></pre><p>}</p>
<pre><code>
### DAO
- Data Access Object의 약자로 DB의 data에 접근하기 위한 객체
- 오버헤드를 줄일 수 있다는 장점
- 어노테이션
  + @Repository

&lt;DAT 코드 예시&gt;
```java
package com.test.demo;

import org.springframework.stereotype.Repository;

import java.util.HashMap;
import java.util.Map;

@Repository
public class userDao {

    private static Map&lt;String, String&gt; userDb = new HashMap&lt;&gt;();

    public String insert(String key, String value) {

        userDb.put(key, value);

        System.out.println(&quot;key : &quot; + key);
        System.out.println(&quot;value : &quot; + value);

        return key;

    }

    public String select(String key) {

        System.out.println(userDb);

        return userDb.get(key);

    }
}
</code></pre><h3 id="dto">DTO</h3>
<ul>
<li>Data Transfer Object이 약자로 계층 간의 데이터 교환을 위한 Java Bean</li>
<li>Controller -&gt; Service -&gt; Dao 계층 간 데이터 교환에 쓰이는 형식<ul>
<li>Controller에서 Dto 객체 생성 후 Service에 파라미터 형식으로 넘김</li>
</ul>
</li>
<li>외부에 entity 구조 (db 테이블 구조) 를 노출시키지 않기 위함</li>
<li>직렬화,역직렬화를 편리하게 하기 위함</li>
<li>주고받는 데이터들의 캡슐화</li>
<li>하나의 기능(도메인?)마다 각각의 Dto 구성하는 편이 좋음</li>
</ul>
<p>&lt;DTO 코드 예시&gt;</p>
<pre><code class="language-java">package com.test.demo;

import lombok.*;
import org.springframework.lang.Nullable;

@Getter
@Setter
// @RequiredArgsConstructor
@Builder
@NoArgsConstructor
public class userDto {

    @NonNull
    private String id;

    @NonNull
    private String userName;

    // @Builder
    public userDto(String id, String userName) {
        this.id = id;
        this.userName = userName;
    }

}
</code></pre>
<h3 id="spring-boot의-기본적인-데이터-교환-계층">Spring Boot의 기본적인 데이터 교환 계층</h3>
<p><img src="https://velog.velcdn.com/images/heyjeong-go/post/9a7e7c5f-6e8c-4279-b9d3-814331a4e9c9/image.png" alt=""></p>
<hr>
<blockquote>
<p>참고</p>
</blockquote>
<ul>
<li><a href="https://frtt0608.tistory.com/7">https://frtt0608.tistory.com/7</a></li>
<li><a href="https://blog.neonkid.xyz/226">https://blog.neonkid.xyz/226</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[MVC Flow]]></title>
            <link>https://velog.io/@heyjeong-go/SpringBoot-MVC-Flow</link>
            <guid>https://velog.io/@heyjeong-go/SpringBoot-MVC-Flow</guid>
            <pubDate>Mon, 19 Sep 2022 15:42:36 GMT</pubDate>
            <description><![CDATA[<h3 id="동작순서">동작순서</h3>
<ul>
<li>요약</li>
</ul>
<ol>
<li>사용자의 Request를 Controller가 받는다.</li>
<li>Controller는 Business Logic을 처리를 Service와 같이 처리한 후 결과를 Model에 담는다.</li>
<li>Model에 저장된 결과를 바탕으로 시각처리를 담당하는 View를 제어하여 사용자에게 전달한다.</li>
</ol>
<ul>
<li>자세히</li>
</ul>
<ol>
<li>Client로부터 요청이 들어오면 DispatcherServlet이 호출된다.</li>
<li>DispatcherServlet은 받은 요청을 HandlerMapping에게 던져준다. 요청받은 URL을 분석하여 HandlerMapping 적합한 Controller를 선택하여 반환한다.</li>
<li>DispatcherServlet는 다음으로 HandlerAdapter를 호출한다. HandlerApdater는 해당하는 Controller 중 요청한 URL에 맞는 적합한 Method를 찾아준다.</li>
<li>Controller는 Business Logic을 처리하고, 해당하는 결과를 View에 전달할 객체를 Model에 저장한다.</li>
<li>Controller는 View name을 DispatcherServlet에게 리턴한다.</li>
<li>DispatcherServlet은 ViewResolver를 호출하여 Controller가 리턴한 View name을 기반으로 적합한 View를 찾아준다.</li>
<li>DispatcherServlet은 View 객체에 처리결과를 넘겨 최종 결과를 보여주도록 요청한다.</li>
<li>View 객체는 해당하는 View를 호출하며, View는 Model 객체에서 화면 표시에 필요한 객체를 가져와 화면 표시를 처리하고 Client에게 넘겨준다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[MVC 정리]]></title>
            <link>https://velog.io/@heyjeong-go/SpringBoot-MVC</link>
            <guid>https://velog.io/@heyjeong-go/SpringBoot-MVC</guid>
            <pubDate>Mon, 19 Sep 2022 15:18:59 GMT</pubDate>
            <description><![CDATA[<h2 id="mvc-패턴">MVC 패턴</h2>
<ul>
<li>MVC( Model-View-Controller ) : 애플리케이션을 세 가지 역할로 구분한 개발 방법론
<img src="https://velog.velcdn.com/images/heyjeong-go/post/3a96489d-d47f-40cf-9f75-245dbdd12ce7/image.png" alt=""><h3 id="model">Model</h3>
</li>
<li>Controller에서 받은 데이터를 저장하는 역할, 데이터를 가진 객체<ul>
<li>데이터는 내부의 상태에 대한 정보 또는 모델을 표현하는 이름 속성 등</li>
</ul>
</li>
<li>Model의 상태에 변화가 있을 때 Controller와 View에 통보함<ul>
<li>Controller는 Model의 변화에 따른 적용 가능한 명령을 추가, 제거, 수정 가능</li>
<li>View는 최신의 결과를 보여줄 수 있음<h4 id="model-규칙">Model 규칙</h4>
</li>
</ul>
</li>
<li>사용자가 편집하길 원하는 모든 데이터를 가지고 있어야만 함<ul>
<li>즉, 화면안의 네모박스에 글자가 표현된다면, 네모박스의 화면 위치 정보, 네모박스의 크기정보, 글자내용, 글자의 위치, 글자의 포맷 정보 등을 가지고 있어야 한다는 것</li>
</ul>
</li>
<li>뷰나 컨트롤러에 대해서 어떠한 정보도 알지 말아야 함<ul>
<li>데이터 변경이 일어났을 때 모델에서 화면 UI를 직접 조정해서 수정할 수 있도록 뷰를 참조하는 내부 속성값을 가지면 안 된다는 말</li>
</ul>
</li>
<li>변경이 일어나면, 변경 통지에 대한 처리방법을 구현해야 함<ul>
<li>모델의 속성 중 텍스트 정보가 변경이 된다면, 이벤트를 발생시켜 누군가에게 전달해야 하며, 누군가 모델을 변경하도록 요청하는 이벤트를 보냈을 때 이를 수신할 수 있는 처리 방법을 구현해야 합니다. 또한 모델은 재사용가능해야 하며 다른 인터페이스에서도 변하지 않아야 함</li>
</ul>
</li>
</ul>
<h3 id="view">View</h3>
<ul>
<li>클라이언트 측 기술 HTML, CSS, Javascript들을 모아둔 컨테이너</li>
<li>사용자가 볼 결과물을 생성하기 위해 모델로부터 정보를 얻어옴</li>
<li>Controller로 부터 받은 Model 데이터를 바탕으로 사용자에게 표현해준다. 일반적으로 HTML, JSP... 에 해당한다<h4 id="view-규칙">View 규칙</h4>
</li>
<li>모델이 가지고 있는 정보를 따로 저장해서는 안됨<ul>
<li>화면에 글자를 표시 하기 위해, 모델이 가지고 있는 정보를 전달받게 될텐데, 그 정보를 유지하기 위해서 임의의 뷰 내뷰에 저장하면 안됨</li>
</ul>
</li>
<li>모델이나 컨트롤러와 같이 다른 구성 요소를 몰라야 함<ul>
<li>모델과 같은 자기 자신의 빼고는 다른 요소는 참조하거나 어떻게 동작하는지 알아서는 안됨</li>
</ul>
</li>
<li>변경이 일어나면, 변경 통지에 대한 처리방법을 구현해야 함<ul>
<li>뷰에서는 화면에서 사용자가 화면에 표시된 내용을 변경하게 되면 이를 모델에게 전달해서 모델을 변경해야 할 것이다. 그 작업을 하기 위해 변경 통지를 구현</li>
</ul>
</li>
</ul>
<h3 id="controller">Controller</h3>
<ul>
<li>사용자가 접근 한 URL에 따라 요청을 파악한다. URL에 맞는 Method를 호출하여 Service와 함께 Business Logic을 처리한다. 최종적으로 나온 결과는 Model에 저장을 하고, View에 던져준다</li>
<li>사용자가 접근한 URL에 따라 사용자의 요청사항을 파악한 후에 그 요청에 맞는 데이터를 Model을 의뢰하고, 데이터를 View에 반영해서 사용자에게 알려줌<h4 id="controller-규칙">Controller 규칙</h4>
</li>
<li>모델이냐 뷰에 대해서 알고 있어야 함</li>
<li>모델이나 뷰의 변경을 모니터링해야 함<ul>
<li>모델이나 뷰의 변경 통지를 받으면 이를 해석해서 각각의 구성 요소에게 통지</li>
</ul>
</li>
</ul>
<h3 id="mvc-패턴-사용하는-이유">MVC 패턴 사용하는 이유</h3>
<ul>
<li>비즈니스 로직과 UI로직을 분리하여 유지보수를 독립적으로 수행가능</li>
<li>Model과 View가 다른 컴포넌트들에 종속되지 않아 애플리케이션의 확장성, 유연성에 유리함</li>
<li>중복 코딩의 문제점 제거</li>
</ul>
<blockquote>
<p>참고</p>
</blockquote>
<ul>
<li><a href="https://cocoon1787.tistory.com/733#:~:text=%F0%9F%92%A1%20MVC%20%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%9E%80%3F,%EA%B5%AC%EB%B6%84%ED%95%9C%20%EA%B0%9C%EB%B0%9C%20%EB%B0%A9%EB%B2%95%EB%A1%A0%EC%9E%85%EB%8B%88%EB%8B%A4">https://cocoon1787.tistory.com/733#:~:text=%F0%9F%92%A1%20MVC%20%ED%8C%A8%ED%84%B4%EC%9D%B4%EB%9E%80%3F,%EA%B5%AC%EB%B6%84%ED%95%9C%20%EA%B0%9C%EB%B0%9C%20%EB%B0%A9%EB%B2%95%EB%A1%A0%EC%9E%85%EB%8B%88%EB%8B%A4</a>.</li>
<li><a href="https://m.blog.naver.com/jhc9639/220967034588">https://m.blog.naver.com/jhc9639/220967034588</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Model(@ModelAttribute, @Requestparam)]]></title>
            <link>https://velog.io/@heyjeong-go/Spring-Model-%EA%B0%9D%EC%B2%B4</link>
            <guid>https://velog.io/@heyjeong-go/Spring-Model-%EA%B0%9D%EC%B2%B4</guid>
            <pubDate>Mon, 19 Sep 2022 14:40:50 GMT</pubDate>
            <description><![CDATA[<h3 id="model">Model</h3>
<ul>
<li>HashMap 형태 -&gt; key, value 값 갖고 있음</li>
<li>모델에 원하는 속성과 그것에 대한 값을 주어 전달할 뷰에 데이터 전달함</li>
<li>Spring에서 Controller의 메서드를 작성할 때 Model이라는 타입을 파라미터로 지정 가능.</li>
<li>Servelt의 request.setAttribute()와 유사한 역할.</li>
</ul>
<h4 id="예시">&lt;예시&gt;</h4>
<p><em>Controller 생성 -&gt; 메소드 매개변수로 Model 타입의 model 변수 선언</em></p>
<pre><code class="language-java">import org.springframework.ui.Model;

@GetMapping(&quot;hello&quot;)
    public String hello(Model model) {
        model.addAttribute(&quot;data&quot;, &quot;hello!!&quot;);  //key, value 형식
        return &quot;hello&quot;;
}</code></pre>
<ul>
<li>model.addAttribute(&quot;key&quot;;&quot;value&quot;) 통해 view에 데이터 전달</li>
</ul>
<h3 id="modelattribute">@ModelAttribute</h3>
<ul>
<li><p>사용자가 요청시 전달하는 값을 오브젝트 형태로 매핑해주는 어노테이션</p>
</li>
<li><p>외부 데이터가 bean에 등록된 객체로 자동으로 변환되어 사용 가능</p>
</li>
<li><p>스프링에서 Java Beans 규칙( Getter, Setter, 생성자 포함 )에 맞는 객체는 파라미터 전달이 자동으로 가능</p>
<ul>
<li>일반 변수의 경우, 자동 전달이 불가능하며 model 객체 통해서 전달 필요</li>
</ul>
</li>
<li><p>기본적으로 객체의 setter로 받아옴( Default 값 -&gt; 권장됨 )</p>
<h4 id="예시-1">&lt;예시&gt;</h4>
<pre><code class="language-java">  @Getter
  @Setter
  public class TestModel {
      private String name;
      private int age;
  }

  @RestController
  public class TestController {

      @GetMapping(&quot;/&quot;)
      public String getTestPage(@ModelAttribute TestModel testModel) {

          System.out.println(testModel.getname());
          System.out.pringln(testModel.getAge());
          return &quot;test&quot;;
      }
  }</code></pre>
</li>
<li><p>/?name=hyejeong&amp;age=25 로 요청 -&gt; name, age 값이 testModel 객체로 바인딩 됨( Setter 존재해야 함 )</p>
</li>
</ul>
<h3 id="requestparam">@RequestParam</h3>
<ul>
<li>사용자가 요청시 전달하는 값을 Controller 의 매개변수로 1:1 맵핑할 때 사용되는 어노테이션<h4 id="예시-2">&lt;예시&gt;</h4>
<pre><code class="language-java">import org.springframework.web.bind.annotation.RequestParam;
</code></pre>
</li>
</ul>
<p>@GetMapping(&quot;hello-mvc&quot;)
    public String helloMvc(@RequestParam(&quot;name&quot;) String name, Model model) {</p>
<pre><code>    model.addAttribute(&quot;name&quot;, name);
    return &quot;hello-template&quot;;

}</code></pre><p>```</p>
<blockquote>
<p>참고
<a href="https://nancording.tistory.com/90">https://nancording.tistory.com/90</a>
<a href="https://galid1.tistory.com/769">https://galid1.tistory.com/769</a>
<a href="https://iamdaeyun.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC">https://iamdaeyun.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC</a>
<a href="https://velog.io/@sloools/Spring-Boot-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-ModelAttribute-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98">https://velog.io/@sloools/Spring-Boot-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-ModelAttribute-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[SpringBoot 강의정리]]></title>
            <link>https://velog.io/@heyjeong-go/SpringBoot-%EA%B0%95%EC%9D%98%EC%A0%95%EB%A6%AC-1</link>
            <guid>https://velog.io/@heyjeong-go/SpringBoot-%EA%B0%95%EC%9D%98%EC%A0%95%EB%A6%AC-1</guid>
            <pubDate>Sun, 18 Sep 2022 03:17:27 GMT</pubDate>
            <description><![CDATA[<ul>
<li>인프런의 <a href="https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard">&#39;김영한 - 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술&#39;</a> 강의 보면서 공부한 내용 정리</li>
<li>그 외 출처<blockquote>
<p><a href="https://velog.io/@oliviarla/spring-boot%EC%9C%88%EB%8F%84%EC%9A%B0%EC%97%90%EC%84%9C-%EB%B9%8C%EB%93%9C%ED%95%98%EA%B3%A0-%EC%8B%A4%ED%96%89%ED%95%98%EA%B8%B0">window에서 springBoot 실행시키기</a></p>
</blockquote>
</li>
</ul>
<h2 id="1-스프링-부트-스타터-사이트로-스프링-프로젝트-생성">1. 스프링 부트 스타터 사이트로 스프링 프로젝트 생성</h2>
<ul>
<li><a href="https://start.spring.io">https://start.spring.io</a> 에서 스프링부트 프로젝트 생성 가능</li>
<li>project : Gradle</li>
<li>Language : Java</li>
<li>Spring Boot : 2.7.3</li>
<li>project Metadata<ul>
<li>Group : hello</li>
<li>Artifact : hello-spring</li>
<li>Dependencies : Spring Web, Thymeleaf<h4 id="스프링부트-프로젝트">스프링부트 프로젝트</h4>
</li>
</ul>
</li>
<li>main함수 실행 -&gt; Tomcat started on port(s): 8080 (http) with context path &#39;&#39; 참고</li>
<li>웹 페이지에서 localhost:8080 입력</li>
</ul>
<h2 id="2-스프링부트-라이브러리-살펴보기">2. 스프링부트 라이브러리 살펴보기</h2>
<ul>
<li>VSCode에선 왼쪽 칸에 &#39;Gradle&#39; 이란 코끼리 모양 클릭</li>
<li>System.out.println 말고 log 형식으로 남기도록..</li>
<li>Gradle : 의존관계가 있는 라이브러리를 함께 다운로드함<h4 id="스프링부트-라이브러리">스프링부트 라이브러리</h4>
</li>
<li>spring-boot-starter-web<ul>
<li>spring-boot-starter-tomcat : 톰캣(웹서버)</li>
<li>spring-webmvc : 스프링 웹 MVC</li>
</ul>
</li>
<li>spring-boot-starter-thymeleaf : 타임리프 템플릿 엔진(View)</li>
<li>spring-boot-starter(공통) : 스프링 부트 + 스프링 코어 + 로깅<ul>
<li>spring-boot<ul>
<li>spring-core</li>
</ul>
</li>
<li>spring-boot-starter-logging<ul>
<li>logback, slf4j<h4 id="테스트-라이브러리">테스트 라이브러리</h4>
</li>
</ul>
</li>
</ul>
</li>
<li>spring-boot-starter-test<ul>
<li>junit : 테스트 프레임워크( junit5 를 자주 씀 )</li>
<li>mockito : 목 라이브러리</li>
<li>assertj : 테스트 코드를 좀 더 편하게 작성하게 도와주는 라이브러리</li>
<li>spring-test : 스프링 통합 테스트 지원</li>
</ul>
</li>
</ul>
<h2 id="3-view-환경-설정">3. View 환경 설정</h2>
<h3 id="welcom-page-만들기">Welcom page 만들기</h3>
<ul>
<li>static/index.html 을 올려두면 스프링 부트가 제공하는 Welcome page 기능을 제공<ul>
<li>src - main - resources - static - 파일 생성( index.html )</li>
<li>스프링 부트는 index.html 파일을 먼저 찾음</li>
</ul>
</li>
<li>아래 내용 작성<pre><code class="language-html">&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
  &lt;head&gt;
      &lt;title&gt;Hello&lt;/title&gt;
      &lt;meta http-equiv = &quot;Content-Type&quot; content=&quot;test/html&quot;; charset=UTF-8&quot; /&gt;
  &lt;/head&gt;
&lt;body&gt;
  Hello
  &lt;a href = &quot;/hello&quot;&gt;hello&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
  &lt;head&gt;
      &lt;title&gt;Hello&lt;/title&gt;
      &lt;meta http-equiv = &quot;Content-Type&quot; content=&quot;test/html&quot;; charset=UTF-8&quot; /&gt;
  &lt;/head&gt;
&lt;body&gt;
  Hello
  &lt;a href = &quot;/hello&quot;&gt;hello&lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h3 id="thymeleaf-템플릿-엔진">thymeleaf 템플릿 엔진</h3>
</li>
<li>thymeleaf 공식 사이트 : <a href="https://www.thymeleft.org/">https://www.thymeleft.org/</a></li>
<li>스프링 공식 튜토리얼 : <a href="https://spring-io/guides/gs/serving-web-content/">https://spring-io/guides/gs/serving-web-content/</a></li>
<li>스프링부트 메뉴얼 : <a href="https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/spring-boot-features.html!#boot-features-spring-mve-template-engines">https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/html/spring-boot-features.html!#boot-features-spring-mve-template-engines</a></li>
<li>src - main - java - hello - hellospring 에 패키지 생성( 폴더 생성 ) : controller<ul>
<li>VSCode 에서는 폴더 생성해주기</li>
</ul>
</li>
<li>controller 폴더 안에 &#39;HelloController.java&#39; 파일 생성<pre><code class="language-java">package hello.hellospring.controller;
</code></pre>
</li>
</ul>
<p>import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;</p>
<p>@Controller
public class HelloController {</p>
<pre><code>@GetMapping(&quot;hello&quot;)
public String hello(Model model) {
    model.addAttribute(&quot;data&quot;, &quot;hello!!&quot;);
    return &quot;hello&quot;;
}</code></pre><p>}</p>
<pre><code>&gt; - [Model](https://velog.io/@heyjeong-go/Spring-Model-%EA%B0%9D%EC%B2%B4)
- @Controller
- @GetMapping

- resources - templates - hello.html 생성
```html
&lt;!DOCTYPE HTML&gt;
&lt;html xmlns=th=&quot;http://www.thymeleaf.org&quot;&gt;
&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;Hello&lt;/title&gt;
        &lt;meta http-equiv = &quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
    &lt;/head&gt;
&lt;body&gt;
    &lt;p th:text=&quot;&#39;안녕하세요. &#39; + ${data}&quot; &gt;안녕하세요. 손님&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><ul>
<li>컨트롤러에서 리턴 값으로 문자를 반환하면 viewResolver 가 화면을 찾아서 처리함<ul>
<li>스프링 부트 템플릿엔진 기본 viewName 매핑</li>
<li>&#39;resource:templates/&#39; + {Viewname} + .&#39;html&#39;</li>
</ul>
</li>
</ul>
<h2 id="4-빌드하고-실행하기">4. 빌드하고 실행하기</h2>
<h3 id="window에서-cmd창으로-springboot-빌드">window에서 cmd창으로 springBoot 빌드</h3>
<ul>
<li>cmd창 오픈 -&gt; cd (gradle.bat 파일 있는 위치로 이동)</li>
<li>빌드 : gradlew build 명령어 통해 빌드됨<ul>
<li>build 했던 폴더 삭제 : gradlew clean</li>
<li>build 했던 폴더 삭제하고 다시 빌드 : gradlew clean build</li>
</ul>
</li>
<li>실행 : java -jar (프로젝트명)-0.0.1-SNAPSHOT.jar 명령어 통해 실행됨</li>
<li>실행 종료는 Ctrl + C 입력</li>
</ul>
<h2 id="5-정적-컨텐츠">5. 정적 컨텐츠</h2>
<ul>
<li>파일을 그대로 웹브라우저에 보여줌</li>
<li>스프링 부트는 정적 컨텐츠 지원함</li>
<li>resource - static 에 &#39;hello-static.html&#39; 파일 생성<pre><code class="language-html">&lt;!DOCTYPE HTML&gt;
&lt;html&gt;
  &lt;head&gt;
      &lt;title&gt;static content&lt;/title&gt;
      &lt;meta http-equiv = &quot;Content-Type&quot; content=&quot;text/html; charset=UTF-8&quot; /&gt;
  &lt;/head&gt;
&lt;body&gt;
  정적 컨텐츠 입니다.
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</li>
<li>main 실행 -&gt; <a href="http://localhost:8080/hello-static.html">http://localhost:8080/hello-static.html</a> 입력</li>
</ul>
<h2 id="6-mvc와-템플릿-엔진">6. MVC와 템플릿 엔진</h2>
<ul>
<li>MVC : Model, View, Controller</li>
<li>controller -&gt; HelloController.java 에 아래 내용 추가<pre><code class="language-java">import org.springframework.web.bind.annotation.RequestParam;
</code></pre>
</li>
</ul>
<p>@GetMapping(&quot;hello-mvc&quot;)
    public String helloMvc(@RequestParam(&quot;name&quot;) String name, Model model) {</p>
<pre><code>    model.addAttribute(&quot;name&quot;, name);
    return &quot;hello-template&quot;;

}</code></pre><pre><code>- resources -&gt; templates -&gt; hello-template.html 생성
```html
&lt;html xmlns=th=&quot;http://www.thymeleaf.org&quot;&gt;
&lt;body&gt;
    &lt;p th:text=&quot;&#39;hello. &#39; + ${name}&quot; &gt;hello! empty&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><ul>
<li>웹 브라우저에 <a href="http://localhost:8080/hello-mvc?name=spring">http://localhost:8080/hello-mvc?name=spring</a>! 입력</li>
</ul>
<h2 id="7-api">7. API</h2>
<h3 id="responsebody">@ResponseBody</h3>
<ul>
<li>@ResponseBody 사용하면 viewResolver 사용 안함<ul>
<li>viewResolver 대신 HttpMessageConverter 동작</li>
<li>기본 문자처리 : StringHttpMessageConverter</li>
<li>기본 객체처리 : MappingJackson2HttpMessageConverter</li>
<li>byte 처리 등등 기타 여러 HttpMessageConverter 가 기본으로 등록되어 있음</li>
</ul>
</li>
<li>대신 HTTP의 BODY에 문자 내용을 직접 반환( HTML BODY TAG를 말하는 것 아님 )<h4 id="예제-1">예제 1</h4>
</li>
<li>controller -&gt; HelloController.java 에 아래 내용 추가<pre><code class="language-java">import org.springframework.web.bind.annotation.ResponseBody;
</code></pre>
</li>
</ul>
<p>@GetMapping(&quot;hello-string&quot;)
    @ResponseBody
    public String helloString(@RequestParam(&quot;name&quot;) String name) {</p>
<pre><code>    return &quot;hello &quot; + name; // @ResponseBody : http의 body 에 직접 내용을 넣어줌
}</code></pre><pre><code>&gt; - @ResponseBody
- @RequestParam

- 웹 브라우저에 http://localhost:8080/hello-mvc?name=spring! 입력 -&gt; hello spring! 출력됨
#### 예제 2
- controller -&gt; HelloController.java 에 아래 내용 추가
```java
@GetMapping(&quot;hello-api&quot;)
    @ResponseBody
    public Hello helloApi(@RequestParam(&quot;name&quot;) String name) {

        Hello hello = new Hello();
        hello.setName(name);

        return hello;
    }

    static class Hello {

        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }</code></pre><ul>
<li>웹 브라우저에 <a href="http://localhost:8080/hello-api?name=spring">http://localhost:8080/hello-api?name=spring</a>!! 입력 -&gt; {&quot;name&quot;:&quot;spring!!&quot;} 출력됨<ul>
<li>Json 형식 : {Key : Value} 형식</li>
</ul>
</li>
</ul>
<h2 id="8-회원-관리-예제---백엔드-개발">8. 회원 관리 예제 - 백엔드 개발</h2>
<h4 id="비즈니스-요구사항-정리">비즈니스 요구사항 정리</h4>
<ul>
<li>데이터 : 회원 ID, 이름</li>
<li>기능 : 회원 등록, 조회</li>
<li>아직 데이터 저장소가 선정되지 않음( 가상의 시나리오 )<h4 id="일반적인-웹-애플리케이션-계층-구조">일반적인 웹 애플리케이션 계층 구조</h4>
<img src="https://velog.velcdn.com/images/heyjeong-go/post/9687898b-d1b8-4062-97de-753be06df765/image.png" alt=""></li>
<li>컨트롤러 : 웹 MVC의 컨트롤러 역할</li>
<li>서비스 : 핵심 비즈니스 로직 구현</li>
<li>리포지토리 : 데이터베이스에 접근, 도메인 객체를 DB에 저장하고 관리</li>
<li>도메인 : 비즈니스 도메인 객체<ul>
<li>예) 회원, 주문, 쿠폰 등등 주로 데이터베이스에 저장되고 관리됨</li>
</ul>
</li>
</ul>
<h4 id="클래스-의존관계">클래스 의존관계</h4>
<p><img src="https://velog.velcdn.com/images/heyjeong-go/post/194c8cbb-718c-4508-a3dd-0785608a6d2c/image.png" alt=""></p>
<ul>
<li>아직 데이터 저장소가 선정되지 않아서, 우선 인터페이스로 구현 클래스를 변경할 수 있도록 설계</li>
<li>데이터 저장소는 RDB, NoSQL 등등 다양한 저장소를 고민중인 상황으로 가정</li>
<li>개발을 진행하기 위해서 초기 개발 단계에서는 구현체로 가벼운 메모리 기반의 데이터 저장소 사용<h3 id="회원-도메인-레포지토리">회원 도메인, 레포지토리</h3>
<h4 id="도메인">도메인</h4>
</li>
<li>hellospring -&gt; domain 폴더 생성( pcakage 생성 )</li>
<li>domain 폴더 안에 Member.java 생성<pre><code class="language-java">package hello.hellospring.domain;
</code></pre>
</li>
</ul>
<p>public class Member {</p>
<pre><code>private Long id;                // 시스템이 저장하는 id
private String name;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

public String getName() {
    return name;
}</code></pre><p>}</p>
<pre><code>#### 레포지토리
- hellospring -&gt; repository 폴더 생성( pcakage 생성 )
- repository 폴더 안에 MemberRepository.java 생성 -&gt; interface로 선언
```java
package hello.hellospring.repository;

import java.util.List;
import java.util.Optional;

import hello.hellospring.domain.Member;

public interface MemberRepository {

    Member save(Member member);
    Optional&lt;Member&gt; findById(Long id);
    Optional&lt;Member&gt; findByName(String name);
    List&lt;Member&gt; findAll();

}</code></pre><blockquote>
<ul>
<li>Optional : Integer나 Double 클래스처럼 &#39;T&#39;타입의 객체를 포장해 주는 래퍼 클래스(Wrapper class)</li>
</ul>
</blockquote>
<ul>
<li>복잡한 조건문 없이도 널(null) 값으로 인해 발생하는 예외를 처리할 수 있음<ul>
<li>interface</li>
</ul>
</li>
</ul>
<ul>
<li>repository폴더 안에 MemoryMemberRepository.java 생성 -&gt; MemberRepository.java를 implements 함<pre><code class="language-java">package hello.hellospring.repository;
</code></pre>
</li>
</ul>
<p>import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;</p>
<p>import hello.hellospring.domain.Member;</p>
<p>public class MemoryMemberRepository implements MemberRepository {</p>
<pre><code>private static Map&lt;Long, Member&gt; store = new HashMap&lt;&gt;();
private static long sequence = 0L;

@Override
public Member save(Member member) {

    member.setId(++sequence);
    store.put(member.getId(), member);

    return member;
}

@Override
public Optional&lt;Member&gt; findById(Long id) {

    return Optional.ofNullable(store.get(id));
}

@Override
public Optional&lt;Member&gt; findByName(String name) {

    return store.values().stream()
            .filter(member -&gt; member.getName().equals(name))
            .findAny();
}

@Override
public List&lt;Member&gt; findAll() {

    return new ArrayList&lt;&gt;(store.values());
}</code></pre><p>}</p>
<pre><code>&gt; - Map
- ArrayList
- implements

### 회원 리포지토리 테스트 케이스 작성
- 자바는 JUnit 이라는 프레임워크로 테스트 실행
#### 회원 리포지토리 테스트 코드 작성
- src -&gt; test -&gt; java -&gt; hello -&gt; hellospring 안에 repository 패키지(폴더) 생성
- repository 패키지 안에 MemoryMemberRepositoryTest.java 생성
```java
package hello.hellospring.repository;

import java.util.List;

import org.assertj.core.api.Assertions; //assertThat
import org.junit.jupiter.api.AfterEach;
//import org.junit.jupiter.api.Assertions;          //assertEquals
import org.junit.jupiter.api.Test;

import hello.hellospring.domain.Member;

class MemoryMemberRepositoryTest {

    MemoryMemberRepository repository = new MemoryMemberRepository();

    @AfterEach
    public void afterEach() {

        repository.clearStore();        // 테스트 하나씩 실행되고 나서 동작
    }

    @Test
    public void save() {

        Member member = new Member();
        member.setName(&quot;spring&quot;);

        repository.save(member);

        Member result = repository.findById(member.getId()).get();

        // Assertions.assertEquals(result, member);
        Assertions.assertThat(member).isEqualTo(result);

        // System.out.println(&quot;result = &quot; + (result == member));
    }

    @Test
    public void fineByName() {

        Member member1 = new Member();
        member1.setName(&quot;spring1&quot;);
        repository.save(member1);

        Member member2 = new Member();
        member2.setName(&quot;spring2&quot;);
        repository.save(member2);

        Member result = repository.findByName(&quot;spring1&quot;).get();

        Assertions.assertThat(result).isEqualTo(member1);
    }

    @Test
    public void findAll() {

        Member member1 = new Member();
        member1.setName(&quot;spring1&quot;);
        repository.save(member1);

        Member member2 = new Member();
        member2.setName(&quot;spring2&quot;);
        repository.save(member2);

        List&lt;Member&gt; result = repository.findAll();

        Assertions.assertThat(result.size()).isEqualTo(2);
    }

}</code></pre><ul>
<li><p>MemoryMemberRepository.java 추가</p>
<pre><code class="language-java">public void clearStore() {

      store.clear();
  }</code></pre>
</li>
</ul>
<h3 id="회원-서비스-개발">회원 서비스 개발</h3>
<h4 id="서비스-로직">서비스 로직</h4>
<ul>
<li>main -&gt; jave/hello/hellospring -&gt; service 패키지(폴더) 생성</li>
<li>MemberService.java 생성<pre><code class="language-java">package hello.hellospring.service;
</code></pre>
</li>
</ul>
<p>import java.util.Optional;
import java.util.List;</p>
<p>import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;</p>
<p>public class MemberService {</p>
<pre><code>private final MemberRepository memberRepository = new MemoryMemberRepository();

/**
 * 회원가입
 * 
 * @param member
 * @return
 */
public Long join(Member member) {

    validateDuplicateMember(member); // 중복 회원 검증
    memberRepository.save(member);
    return member.getId();
}

private void validateDuplicateMember(Member member) {

    // 같은 이름이 있는 중복 회원 X

    // Optional&lt;Member&gt; result = memberRepository.findByName(member.getName());
    // result.ifPresent(m -&gt; {
    // throw new IllegalStateException(&quot;이미 존재하는 회원입니다.&quot;);
    // });

    memberRepository.findByName(member.getName())
            .ifPresent(m -&gt; {
                throw new IllegalStateException(&quot;이미 존재하는 회원입니다.&quot;);
            });
}

/**
 * 전체 회원 조회
 */
public List&lt;Member&gt; findMembers() {

    return memberRepository.findAll();
}

/**
 * 회원 조회
 */
public Optional&lt;Member&gt; findOne(Long memberId) {

    return memberRepository.findById(memberId);
}</code></pre><p>}</p>
<pre><code>#### 회원 서비스 테스트 코드
- src -&gt; test -&gt; java -&gt; hello -&gt; hellospring 안에 service 패키지(폴더) 생성
- service 패키지 안에 MemberServiceTest.java 생성
```java
package hello.hellospring.service;

import static org.junit.jupiter.api.Assertions.fail;

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
//import org.junit.jupiter.api.Assertions;        //assertThrows
import org.junit.jupiter.api.Test;

import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemoryMemberRepository;

class MemberServiceTest {

    MemberService memberService;
    MemoryMemberRepository memberRepository;

    @BeforeEach
    public void beforeEach() {

        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);
    }

    @AfterEach
    public void afterEach() {
        memberRepository.clearStore();
    }

    @Test
    public void 회원가입() {

        // given
        Member member = new Member();
        member.setName(&quot;hello&quot;);

        // when
        Long saveId = memberService.join(member);

        // then
        Member findMember = memberService.findOne(saveId).get();
        Assertions.assertThat(member.getName()).isEqualTo(findMember.getName());

    }

    @Test
    public void 중복_회원_예외() {

        // given
        Member member1 = new Member();
        member1.setName(&quot;spring&quot;);

        Member member2 = new Member();
        member2.setName(&quot;spring&quot;);

        // when
        memberService.join(member1);

        // 1
        try {
            memberService.join(member2);
            fail();
        } catch (IllegalStateException e) {
            Assertions.assertThat(e.getMessage()).isEqualTo(&quot;이미 존재하는 회원입니다.&quot;);
        }

        // 2
        // Assertions.assertThrows(IllegalStateException.class, () -&gt;
        // memberService.join(member2));

        // 3
        // IllegalStateException e =
        // Assertions.assertThrows(IllegalStateException.class, () -&gt;
        // memberService.join(member2));

        // Assertions.assertThat(e.getMessage()).isEqualTo(&quot;이미 존재하는 회원입니다.&quot;);
        // then
    }

    @Test
    public void findMembers() {

    }

    @Test
    public void findOne() {

    }
}
</code></pre><ul>
<li><p>MemberService.java 추가</p>
<pre><code class="language-java">private final MemberRepository memberRepository;

  public MemberService(MemberRepository memberRepository) {
      this.memberRepository = memberRepository;
  }</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TDD 개념정리]]></title>
            <link>https://velog.io/@heyjeong-go/TDD-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@heyjeong-go/TDD-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 18 Sep 2022 03:00:11 GMT</pubDate>
            <description><![CDATA[<h3 id="tdd-란">TDD 란</h3>
<ul>
<li>TDD(Test-Driven Development) : 테스트 주도 개발<ul>
<li>매우 짧은 개발 사이클을 반복하는 소프트웨어 개발 프로세스 중 하나</li>
<li>진행 방식 : <strong>준비 -&gt; 동작 -&gt; 확인</strong><ul>
<li>요구 기능에 대한 테스트 코드 작성</li>
<li>테스트 케이스를 통과하기 위한 최소한의 코드 생성</li>
<li>리팩토링</li>
</ul>
</li>
<li>작성 방식<ul>
<li>case 1 : 구현 대상 클래스의 외형에 해당하는 메소드들을 먼저 만들고 테스트 케이스를 일괄적으로 만드는 방식</li>
<li>case 2 : 테스트 케이스를 하나씩 추가해가면서 구현 클래스를 점진적으로 만드는 방식</li>
</ul>
</li>
</ul>
</li>
<li>JUnit : 자바 프로그램의 단위 테스트를 위한 대표적인 프레임 워크<ul>
<li>현재 최신 버전은 JUnit5</li>
</ul>
</li>
<li>JUnit에서 지원하는 어노테이션 정리<ul>
<li>@Test<ul>
<li>해당 어노테이션이 선언된 메소드는 테스트를 수행하는 메소드가 됨</li>
<li>각각의 테스트가 서로 영향을 주지 않고 독립적으로 실행됨을 원칙으로 @Test마다 객체를 생성함</li>
</ul>
</li>
<li>@Ignore<ul>
<li>테스트를 실행하지 않음</li>
</ul>
</li>
<li>@Before<ul>
<li>@Test 메소드가 실행되기 전에 반드시 실행됨</li>
<li>@Test 메소드에서 공통으로 사용하는 코드를 해당 메소드에 선언하여 사용하면 됨</li>
</ul>
</li>
<li>@After<ul>
<li>@Test 메소드가 실행된 후 실행됨</li>
</ul>
</li>
<li>@BeforeClass<ul>
<li>@Test메소드보다 먼저 한번만 수행되어야 할 경우에 사용됨</li>
</ul>
</li>
<li>@AfterClass<ul>
<li>@Test메소드보다 나중에 한번만 수행되어야 할 경우에 사용됨</li>
</ul>
</li>
<li>Assert class<ul>
<li>assertArraEquals(a, b) : 배열 a와 b가 일치함을 확인</li>
<li>assertEquals(a, b) : 객체 a와 b의 값이 같은지 확인</li>
<li>assertSame(a, b) : 객체 a와 b가 같은 객체임을 확인</li>
<li>assertTrue(a) : a가 참인지 확인</li>
<li>assertNotNull(a) : a객체가 null이 아님을 확인</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java API 클래스 정리]]></title>
            <link>https://velog.io/@heyjeong-go/Java-API-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@heyjeong-go/Java-API-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 26 Aug 2022 13:08:23 GMT</pubDate>
            <description><![CDATA[<h3 id="java-api-클래스">Java API 클래스</h3>
<p><em>API 클래스 정리는 네이버 블로그 참고!
[<a href="https://blog.naver.com/ko4531/222858282809">Java API 클래스 정리</a>]</em></p>
<p><del>공부하면서 정리가 필요하다고 느껴지는 API는 예제 및 부가설명으로 추가하기...</del></p>
<hr>
<h3 id="javalangstringbuffer">java.lang.StringBuffer</h3>
<h4 id="string-클래스와-stringbuffer-클래스-차이점">String 클래스와 StringBuffer 클래스 차이점</h4>
<ul>
<li>String 클래스의 인스턴스는 최초 생성 후, 읽기만 가능 쓰기는 불가능</li>
<li>StringBuffer 클래스의 인스턴스는 값 변경 및 추가 가능</li>
<li>불변 클래스(immutable class) - String 클래스, 가변 클래스(mutable class) - StringBuffer 클래스</li>
</ul>
<h4 id="stringbuffer-클래스-특징">StringBuffer 클래스 특징</h4>
<ul>
<li>내부적으로 버퍼(buffer) 라는 독립적인 공간을 가짐</li>
<li>버퍼 크기의 기본값은 16개의 문자를 저장할 수 있는 크기이며, 생성자를 통해 별도로 설정 가능<ul>
<li>인스턴스 생성 시, 사용자가 설정한 크기보다 16개의 문자를 더 저장할 수 있도록 여유 있는 크기로 생성됨</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java 개념 정리 2]]></title>
            <link>https://velog.io/@heyjeong-go/Java-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC-2</link>
            <guid>https://velog.io/@heyjeong-go/Java-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC-2</guid>
            <pubDate>Fri, 26 Aug 2022 12:48:50 GMT</pubDate>
            <description><![CDATA[<h3 id="상속-inheritance-">상속( inheritance )</h3>
<ul>
<li>기존의 클래스에 기능을 추가하거나 재정의하여 새로운 클래스를 정의하는 것</li>
<li>부모 클래스( parent class ), 상위 클래스( super class ), 기초 클래스( base class ) : 기존에 정의되어 있던 클래스</li>
<li>자식 클래스( child class ), 하위 클래스( sub class ), 파생 클래스( derived class ) : 상속을 통해 새롭게 작성되는 클래스<ul>
<li>부모 클래스의 필드와 메소드만 상속됨.</li>
</ul>
</li>
</ul>
<p>Ex)</p>
<pre><code class="language-java">class Parent {
    private int a = 10;
    public int b = 20;
}

class Child extends Parent {
    public int c = 30;

    void display() {
        // System.out.println(a);       // 상속받은 private 필드는 참조 불가능
        System.out.println(b);
        System.out.println(c);
    }
}

public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        Child ch = new Child();
        ch.display();
    }</code></pre>
<h4 id="super-키워드">super 키워드</h4>
<ul>
<li>부모 클래스로부터 상속받은 필드나 메소드를 자식 클래스에서 참조하는데 사용하는 참조 변수</li>
</ul>
<p>Ex)</p>
<pre><code class="language-java">class Parent {
    int a = 10;
}

class Child extends Parent {
    int a = 20;

    void display() {
        System.out.println(a);
        System.out.println(this.a);
        System.out.println(super.a);
    }
}

public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        Child ch = new Child();
        ch.display();
    }
}

//결과
20
20
10</code></pre>
<h4 id="super-메소드">super() 메소드</h4>
<ul>
<li>super() 메소드는 부모 클래스의 생성자를 호출할 때 사용</li>
<li>자바에서는 자동으로 super() 메소드를 추가하여, 부모 클래스의 멤버를 초기화할 수 있게 해줌<ul>
<li>하지만 부모 클래스에 매개변수를 가지는 생성자를 하나라도 선언 시, super() 메소드는 자동으로 추가되지 않음</li>
</ul>
</li>
<li>따라서 부모 클래스에서 매개변수를 가진 생성자 선언 시 기본 생성자도 명시적으로 선언해줘야 함</li>
</ul>
<p>Ex)</p>
<pre><code class="language-java">class Parent {
    int a;

    Parent() {
        a = 10;
    }

    Parent(int n) {
        a = n;
    }
}

class Child extends Parent {
    int b;

    Child() {
        // super(40);
        b = 20;
    }

    void display() {
        System.out.println(a);
        System.out.println(b);
    }
}

public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        Child ch = new Child();
        ch.display();
    }
}

//결과
10
20

//주석 해제 시
40
20</code></pre>
<h3 id="메소드-오버라이딩-method-overriding-">메소드 오버라이딩( method overriding )</h3>
<ul>
<li>상속 관계에 있는 부모 클래스에서 이미 정의된 메소드를 자식 클래스에서 같은 시그니쳐를 갖는 메소드로 다시 정의하는 것</li>
<li>상속받은 부모 클래스의 메소드를 재정의하여 사용하는 것</li>
<li>조건<ul>
<li>메소드의 선언부는 기존 메소드와 완전히 같아야 함</li>
<li>메소드의 반환 타입은 부모 클래스의 반환 타입으로 타입 변환할 수 있는 타입이라면 변경 가능</li>
<li>부모 클래스의 메소드보다 접근 제어자를 더 좁은 범위로 변경할 수 없음</li>
<li>부모 클래스의 메소드보다 더 큰 범위의 예외 선언 불가능</li>
</ul>
</li>
</ul>
<p>Ex)</p>
<pre><code class="language-java">class Parent {
    void display() {
        System.out.println(&quot;부모 클래스의 display() 메소드입니다.&quot;);
    }
}

class Child extends Parent {
    void display() {
        System.out.println(&quot;자식 클래스의 display() 메소드입니다.&quot;);
    }
}

public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        Parent pa = new Parent();
        pa.display();

        Child ch = new Child();
        ch.display();

        Parent pc = new Child();
        pc.display();
    }
}</code></pre>
<h3 id="다형성-polymorphism-">다형성( polymorphism )</h3>
<ul>
<li>하나의 객체가 여러 가지 타입을 가질 수 있는 것
Ex)<pre><code class="language-java">class Parent{ ... }
class Child extends Parent{ ... }</code></pre>
</li>
</ul>
<ol>
<li>Parent pa = new Parent();    // 허용</li>
<li>Child ch = new Child();      // 허용</li>
<li>Parent pc = new Child();     // 허용</li>
<li>Child cp = new Parent();     // 오류 발생
```</li>
</ol>
<ul>
<li>코드 설명<ul>
<li>1, 2. 특정 타입의 참조 변수로는 같은 타입의 인스턴스 참조 가능<ul>
<li>참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수와 같음</li>
</ul>
</li>
<li><ol start="3">
<li>부모 클래스 타입의 참조 변수로는 자식 클래스 타입의 인스턴스를 참조 가능</li>
</ol>
<ul>
<li>참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴의 멤버 개수보다 적음</li>
</ul>
</li>
<li><ol start="4">
<li>자식 클래스 타입의 참조 변수로는 부모 클래스 타입의 인스턴스 참조 불가능</li>
</ol>
<ul>
<li>참조 변수가 사용할 수 있는 멤버의 개수가 실제 인스턴스의 멤버 개수보다 많기 때문</li>
<li>클래스는 상속을 통해 확장 가능, 축소 불가능 이므로 자식 클래스에서 사용할 수 있는 멤버의 개수는 부모 클래스와 같거나 많게 됨</li>
</ul>
</li>
</ul>
</li>
<li>참조 변수의 타입 변환<ul>
<li>서로 상속 관계에 있는 클래스 사이에만 타입 변환 가능</li>
<li>자식  클래스 타입에서 부모 클래스 타입으로의 타입 변환 생략 가능</li>
<li>부모 클래스 타입에서 자식 클래스 타입으로의 타입 변환은 반드시 명시</li>
<li>형식 : (변환할 타입의 클래스 이름) 변환할 참조 변수</li>
</ul>
</li>
</ul>
<p>Ex)</p>
<pre><code class="language-java">class Parent{ ... }
class Child extends Parent{ ... }
class Brother extends Parent{ ... }

Parent pa01 = null;
Child ch = new Child();
Parent pa02 = new Parent();
Brother br = null;

pa01 = ch;    // pa01 = (Parent)ch; 와 같으며, 타입 변환 생략 가능
br = (Brother)pa02;    // 타입 변환 생략 불가능
br = (Brother)ch;      // 직접적인 상속 관계가 아니므로 오류 발생</code></pre>
<ul>
<li>instanceof 연산자 : 참조 변수가 참조하고 있는 인스턴스의 실제 타입 확인할 수 있도록 해줌<ul>
<li>참조변수 instanceof 클래스 이름</li>
<li>왼쪽에 전달된 참조 변수가 실제로 참조하고 있는 인스턴스의 타입이 오른쪽에 전달된 클래스 타입이면 true 반환, 아니거나 참조 변수가 null일 경우 false 반환
Ex)<pre><code class="language-java">class Parent { }
class Child extends Parent { }
class Brother extends Parent { }
</code></pre>
</li>
</ul>
</li>
</ul>
<p>public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        Parent p = new Parent();
        System.out.println(p instanceof Object); // true
        System.out.println(p instanceof Parent); // true
        System.out.println(p instanceof Child); // false
        System.out.println();</p>
<pre><code>    Parent c = new Child();
    System.out.println(c instanceof Object); // true
    System.out.println(c instanceof Parent); // true
    System.out.println(c instanceof Child); // true
}</code></pre><p>}</p>
<p>// 결과
true
true
false</p>
<p>true
true
true</p>
<pre><code>
### 추상 클래스( abstract class)
##### 추상 메소드( abstract method ) : 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드
- 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함
- 중복 또는 공통적인 부분은 미리 다 만들어진 것을 사용하고, 이를 받아 사용하는 쪽에서는 자신에게 필요한 부분만을 재정의하여 사용함으로써 생상성이 향상되고 배포 등이 쉬워지기 때문
- 추상 메소드는 선언부만 존재하며 구현부는 작성되지 않음
- 구현부는 자식 클래스에서 오버라이딩하여 사용하는 것
##### 추상 클래스( abstract class ) : 하나 이상의 추상 메소드를 포함하는 클래스
- 인스턴스 생성 불가능 : 동작이 정의되어 있지 않은 추상 메소드를 포함하고 있음
- 상속을 통해 자식 클래스 생성 -&gt; 자식 클래스에서 추상 클래스의 모든 추상 메소드를 오버라이딩 -&gt; 자식 클래스의 인스턴스 생성 가능
- 생성자, 필드, 일반 메소드 포함 가능

Ex)
```java
abstract class Animal {
    abstract void cry();
}
// 이런 형식으로 추상 클래스, 추상 메소드 생성

class Cat extends Animal {
    void cry() {
        System.out.println(&quot;냐옹냐옹!&quot;);
    }
}

class Dog extends Animal {
    void cry() {
        System.out.println(&quot;멍멍!&quot;);
    }
}

public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        // Animal a = new Animal() // 추상 클래스는 인스턴스 생성 불가능
        Cat c = new Cat();
        Dog d = new Dog();

        c.cry();
        d.cry();
    }
}</code></pre><h3 id="인터페이스-interface-">인터페이스( interface )</h3>
<ul>
<li>다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스 의미</li>
<li>다중 상속 지원</li>
<li>추상 메소드와 상수만 포함 가능</li>
<li>선언<pre><code class="language-java">접근제어자 interface 인터페이스이름 {
publlic static final 타입 상수이름 = 값;
public abstract 메소드이름(매개변수목록);
}</code></pre>
</li>
<li>모든 필드는 public static final, 모든 메소드는 public abstract 로 선언<ul>
<li>모든 인터페이스에 공통으로 적용되는 부분이므로 생략 가능</li>
<li>컴파일 시 자바 컴파일러가 자동으로 추가 해줌</li>
</ul>
</li>
<li>인터페이스는 직접 인스턴스 생성 불가능<ul>
<li>인터페이스가 포함하고 있는 추상 메소드를 구현해 줄 클래스는 작성해야 함</li>
<li>class 클래스이름 implements 인터페이스 이름{ ... }</li>
</ul>
</li>
<li>인터페이스 상속과 구현 동시에 생성 가능<ul>
<li>class 클래스이름 extend 상위클래스이름 implements 인터페이스이름{ ... }</li>
</ul>
</li>
<li>인터페이스 구현 Ex)<pre><code class="language-java">interface Animal {
  public abstract void cry();
}
</code></pre>
</li>
</ul>
<p>class Cat implements Animal {
    public void cry() {
        System.out.println(&quot;냐옹냐옹&quot;);
    }
}</p>
<p>class Dog implements Animal {
    public void cry() {
        System.out.println(&quot;멍멍!&quot;);
    }
}</p>
<p>public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        Cat c = new Cat();
        Dog d = new Dog();</p>
<pre><code>    c.cry();
    d.cry();
}</code></pre><p>}</p>
<pre><code>- 다중 상속 Ex)
```java
interface Animal {
    public abstract void cry();
}

interface Pet {
    public abstract void play();
}

class Cat implements Animal, Pet {
    public void cry() {
        System.out.println(&quot;냐옹냐옹&quot;);
    }

    public void play() {
        System.out.println(&quot;쥐 잡기 놀이하자&quot;);
    }
}

class Dog implements Animal, Pet {
    public void cry() {
        System.out.println(&quot;멍멍!&quot;);
    }

    public void play() {
        System.out.println(&quot;산책가자&quot;);
    }
}

public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        Cat c = new Cat();
        Dog d = new Dog();

        c.cry();
        c.play();
        d.cry();
        d.play();
    }
}</code></pre><ul>
<li>인터페이스 장점<ul>
<li>대규모 프로젝트 개발 시 일관되고 정형화된 개발을 위한 표준화 가능</li>
<li>클래스의 작성과 인터페이스의 구현 동시에 진행 가능하며 개발 시간 단축 가능</li>
<li>클래스와 클래스 간의 관계를 인터페이스로 연결하면, 클래스마다 독립적인 프로그래밍 가능</li>
</ul>
</li>
</ul>
<h3 id="내부-클래스-inner-class-">내부 클래스( inner class )</h3>
<ul>
<li>하나의 클래스 내부에 선언된 또 다른 클래스</li>
</ul>
<p>Ex)</p>
<pre><code class="language-java">class Outer {                           // 외부 클래스
  class InstanceInnerClass {}           // 인스턴스 클래스
  static class StaticInnerClass {}      // 정적 클래스
  void myMethod () {
    class LocalInnerClass {}            // 지역 클래스
  }
}</code></pre>
<ul>
<li>익명 클래스( anonymous class ) : 클래스의 선언과 동시에 객체를 생성하므로, 단 하나의 객체만을 생성하는 일회용 클래스<ul>
<li>생성자 선언 불가능, 단 하나의 클래스나  단 하나의 인터페이스를 상속받거나 구현 가능</li>
<li>매우 제한적인 용도에 사용, 구현해야 하는 메소드가 매우 적은 클래스 구현할 때 사용<pre><code class="language-java">// 익명 클래스는 선언과 동시에 생성하여 참조변수에 대입함
클래스이름 참조변수이름 = enw 클래스이름() {
// 메소드의 선언
}</code></pre>
</li>
</ul>
</li>
</ul>
<h3 id="예외-처리-exception-handling-">예외 처리( Exception handling )</h3>
<ul>
<li>예외를 처리하기 위해 try / catch / finally 문 사용
Ex)<pre><code class="language-java">try {
// 예외를 처리하길 원하는 실행 코드;
} catch( e1 ) {
  // e1 예외가 발생할 경우에 실행될 코드;
} catch( e2 ) {
  // e2 예외가 발생할 경우에 실행될 코드;
}
finally {
// 예외 발생 여부와 상관없이 무조건 실행될 코드;
}</code></pre>
</li>
<li>범위가 더 좁은 예외를 처리하는 catch 블록을 먼저 명시, 범위가 더 넓은 예외를 처리하는 catch 블록은 나중에 명시<ul>
<li>Throwable 클래스 : 모든 예외의 조상이 되는 Exception 클래스와 모든 오류의 조상이 되는 Error 클래스의 부모 클래스</li>
<li>String getMessage() : 해당 throwable 객체에 대한 자세한 내용을 문자열로 반환함</li>
<li>void printStackTrace() : 해당 throwable 객체와 표준 오류 스트림( standard error stream )에서 해당 객체의 스택 트레이스를 출력함</li>
<li>String toString() : 해당 throwalbe 객체에 대한 간략한 내용을 문자열로 반환함</li>
</ul>
</li>
<li>예외처리 관련된 클래스는 추후에 알아보도록...</li>
</ul>
<hr>
<h3 id="참고">참고</h3>
<blockquote>
<p><a href="http://www.tcpschool.com/java/intro">TCP School - Java 강의 참고</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java 개념 정리1]]></title>
            <link>https://velog.io/@heyjeong-go/Java-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC1</link>
            <guid>https://velog.io/@heyjeong-go/Java-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC1</guid>
            <pubDate>Fri, 26 Aug 2022 12:17:41 GMT</pubDate>
            <description><![CDATA[<h3 id="static">Static</h3>
<ul>
<li>static으로 선언된 함수(메서드)나 변수는 자바 버추얼 머신에서 인스턴스 객체의 생성 없이 호출 할 수 있음</li>
<li>즉, 객체 생성없이 해당 함수를 호출해서 사용 가능</li>
<li>자바 프로그램 실행하면 static으로 지정된 메서드를 찾아서 먼저 메모리에 할당시킴</li>
<li>static으로 지정된 메서드가 여러개인 경우 객체를 생성하는 것과 상관없이 모두 메모리에 할당시킴</li>
<li>그 후에, &#39;main&#39; (main 은 다른 이름으로 지정할 수 없음)으로 이름이 만들어진 메서드가 있는지를 찾아서 그 메서드를 가장 먼저 시작점의 메서드로써 호출 함</li>
<li>프로그램 시작 시 최초에 단 한번만 생성되고 초기화됨</li>
<li>해당 클래스의 모든 인스턴스가 공유</li>
<li>초기화 블록에도 사용 가능</li>
</ul>
<h3 id="final">final</h3>
<ul>
<li>먼저 상수란, 변수와 마찬가지로 데이터를 저장할 수 있는 메모리 공간을 의미함<ul>
<li>프로그램이 실행되는 동안 메모리에 저장된 데이터를 변경할 수 없음</li>
<li>선언과 동시에 반드시 초기화해줘야 함</li>
</ul>
</li>
<li>C++ 에서는 const 키워드, Java에서는 final 키워드 사용하여 상수 선언<ul>
<li>Ex) final int A = 30;</li>
</ul>
</li>
<li>클래스에 사용 시, 다른 클래스가 상속받을 수 없음</li>
<li>메소드에 사용 시, 해당 메소드는 오버라이딩을 통한 재정의 할 수 없음<ul>
<li>메소드 오버라이딩( method overrinding ) : 상속받은 부모 클래스의 메소드를 재정의하여 사용</li>
</ul>
</li>
</ul>
<h3 id="배열">배열</h3>
<p>( C++과 조금 다른 점이 있어서 기록해둘 겸... )</p>
<ul>
<li>타입[] 배열이름;</li>
<li>타입 배열이름[];</li>
<li>배열이름 = new 타입[ 배열길이 ];</li>
<li>타입[] 배열이름 = new 타입[ 배열길이 ];
Ex)<pre><code class="language-java">int[] grade1 = new int[3];    //타입[] 배열이름 = new 타입[배열길이]
int[] grade3 = new int[]{1, 2, 3};    //타입[] 배열이름 = new 타입[]{}</code></pre>
</li>
</ul>
<h3 id="객체-지향-프로그래밍">객체 지향 프로그래밍</h3>
<h4 id="클래스-class---객체를-정의하는-틀-또는-설계도">클래스( class ) : 객체를 정의하는 틀 또는 설계도</h4>
<ul>
<li>자바에서는 클래스를 가지고 여러 객체를 생성하여 사용함</li>
<li>객체( object ) : 데이터</li>
<li>필드( field ) : 객체의 상태를 나타냄, 클래스에 포함된 변수(variable ) 의미</li>
<li>메소드( method ) : 객체의 행동을 나타냄, 어떤 특정 작업을 수행하기 위한 명령문의 집합<h4 id="인스턴스-instance---클래스로부터-객체를-선언하는-과정을-클래스의-인스턴스-화라고-함">인스턴스( instance ) : 클래스로부터 객체를 선언하는 과정을 클래스의 인스턴스 화라고 함</h4>
</li>
<li>메모리에 할당된 객체 의미</li>
<li>하나의 클래스로부터 여러 개의 인스턴스를 생성할 수 있음</li>
<li>독립된 메모리 공간에 저장된 자신만의 필드 가질 수 있음</li>
<li>해당 클래스의 모든 메소드는 해당 클래스에서 생성된 모든 인스턴스가 공유하게 됨</li>
<li>클래스 변수와 인스턴스 변수는 별도로 초기화하지 않으면, 자동으로 초기화 시켜줌</li>
<li>인스턴스 변수 중 private 변수가 있다면 public 메소드로 해당 변수 초기화...<h4 id="메소드-method-">메소드( method )</h4>
</li>
<li>접근 제어자 : 해당 메소드에 접근할 수 있는 범위 명시( private, public, protected 이런 것들? )</li>
<li>반환 타입( return type )</li>
<li>메소드 이름</li>
<li>매개변수 목록( parameters )</li>
</ul>
<p>Ex)</p>
<pre><code class="language-java">//class
//-차(Car) : 설계도

//filed
car.modleName = &quot;람보르기니&quot;
car.modelYear = 2016
car.color = &quot;주황색&quot;
car.maxSpeed = 350

//method
car.accelerate();
car.brake();

//instance
//myCar : 설계도에 의해 생성된 차량
//friendCar : 설계도에 의해 생상된 또 다른 차량

//자동차 인스턴스는 같은 필드와 메소드 갖게 됨
//각 인스턴스마다 가지고 있는 프로퍼티의 값은 전부 다름</code></pre>
<h3 id="생성자-constructor-">생성자( constructor )</h3>
<ul>
<li>객체의 생성과 동시에 인스턴스 변수를 원하는 값으로 초기화 할 수 있는 생성자 메소드 제공</li>
<li>반환값 없음, 초기화를 위한 인수 전달받을 수 있음, 하나의 클래스가 여러 개의 생성자 가질 수 있음..</li>
<li>메소드 오버로딩 가능</li>
<li>매개변수가 없는 기본 생성자 호출하지만 매개변수가 있는 생성자를 하나 이상 정의한 후 기본 생성자 호출 시 오류 발생</li>
</ul>
<h3 id="this-this">this, this()</h3>
<ul>
<li>this : 인스턴스가 자기 자신을 참조하는데 사용하는 변수<ul>
<li>인스턴스 메소드에서만 사용 가능</li>
</ul>
</li>
<li>this() : 생성자 내부에서만 사용 가능, 같은 클래스의 다른 생성자 호출 시 사용</li>
</ul>
<h3 id="메소드-오버로딩-method-overloading-">메소드 오버로딩( method overloading )</h3>
<ul>
<li>같은 이름의 메소드를 중복하여 정의하는 것</li>
<li>다형성을 구현하는 방법 중 하나</li>
</ul>
<h3 id="제어자-정리">제어자 정리</h3>
<h4 id="패키지-package---클래스와-인터페이스의-집합">패키지( package ) : 클래스와 인터페이스의 집합</h4>
<ul>
<li>물리적으로 하나의 디렉터리 의미</li>
<li>package 패키지이름(패키지의 경로까지 포함한 풀 네임 명시)<h4 id="import-문">import 문</h4>
</li>
<li>풀 네임 명시는 비효율적, 클래스의 패키지에 대한 정보를 미리 제공해줌</li>
<li>다른 패키지에 속한 클래스를 패키지 이름을 제외한 클래스 이름만으로 사용할 수 있게 됨<pre><code class="language-java">import 패키지이름.클래스이름    //해당 패키지의 특정 클래스만을 사용
import 패키지이름.*;            //해당 패키지의 모든 클래스를 클래스 이름만으로 사용하고 싶을 때</code></pre>
</li>
</ul>
<h3 id="접근-제어자-access-modifier-">접근 제어자( access modifier )</h3>
<ul>
<li>정보 은닉을 위해 제공</li>
</ul>
<ol>
<li>private : 해당 멤버를 선언한 클래스에서만 접근 가능</li>
<li>public : 외부로 공개되며, 해당 객체를 사용하는 어느 프로그램 어디에서나 직접 접근 가능</li>
<li>default : 접근 제어자 지정 없을 시 자동으로 세팅됨, 같은 클래스 또는 패키지에 속하는 멤버에서만 접근 가능</li>
<li>protected : 부모 클래스에 대해서는 public멤버처럼 취급, 외부에서는 private 멤버처럼 취급</li>
</ol>
<ul>
<li>같은 패키지에 속하는 클래스와 다른 패키지에 속하는 자식 클래스에서만 접근 가능</li>
<li>*범위 : public &gt; protected &gt; default &gt; private</li>
</ul>
<h3 id="abstract">abstract</h3>
<ul>
<li>선언부만 있고 구현부가 없는 메소드를 추상 메소드라 부름, 반드시 abstract 제어자 붙여야함</li>
<li>하나 이상의 추상 메소드를 포함하고 있는 추상 클래스도 반드시 abstract 제어자 붙여야함</li>
</ul>
<h3 id="field-좀-더-상세히">field 좀 더 상세히!</h3>
<ol>
<li>클래스 변수( = 공유 변수 ) : 클래스 영역에 위치한 변수 중 static 키워드를 가지는 변수</li>
<li>인스턴스 변수 : 클래스 영역에 위치한 변수 중 static 키워드 가지지 않는 변수</li>
<li>지역 변수( local variable ) : 메소드, 생성자, 초기화 블록 내에 위치한 변수
Ex)<pre><code class="language-java">class Field {
 static int classVar = 10; // 클래스 변수 선언
 int instanceVar = 20; // 인스턴스 변수 선언
}
</code></pre>
</li>
</ol>
<p>public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        int var = 30; // 지역 변수 선언
        System.out.println(var + &quot;\n&quot;); // 지역 변수 참조</p>
<pre><code>    Field myField1 = new Field(); // 인스턴스 생성
    Field myField2 = new Field(); // 인스턴스 생성

    System.out.println(Field.classVar); // 클래스 변수 참조
    System.out.println(myField1.classVar);
    System.out.println(myField2.classVar + &quot;\n&quot;);

    myField1.classVar = 100; // 클래스 변수 값 변경

    System.out.println(Field.classVar); // 클래스 변수 참조
    System.out.println(myField1.classVar);
    System.out.println(myField2.classVar + &quot;\n&quot;);

    System.out.println(myField1.instanceVar); // 인스턴스 변수 참조
    System.out.println(myField2.instanceVar + &quot;\n&quot;);

    myField1.instanceVar = 200;
    System.out.println(myField1.instanceVar); // 인스턴스 변수 참조
    System.out.println(myField2.instanceVar);
}</code></pre><p>}</p>
<p>//결과
30</p>
<p>10 
10 
10</p>
<p>100
100
100</p>
<p>20
20</p>
<p>200
20</p>
<p>//클래스 변수는 생성된 모든 인스턴스가 같은 값을 공유함
//인스턴스 변수는 각 인스턴스마다 고유한 값을 가짐</p>
<pre><code>
### method 좀 더 상세히!
1. 클래스 메소드( static method ) : static 키워드를 가지는 메소드
2. 인스턴스 메소드( instance method ) : static 키워드 가지지 않는 메소드
Ex)
```java
class Method {
    int a = 10; // 인스턴스 변수
    int b = 20; // 인스턴스 변수

    int add() {
        return a + b;
    } // 인스턴스 메소드

    static int add(int x, int y) {
        return x + y;
    } // 클래스 메소드
}

public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        System.out.println(Method.add(20, 30)); // 클래스 메소드 호출
        Method myMethod = new Method(); // 인스턴스 생성
        System.out.println(myMethod.add()); // 인스턴스 메소드 호출
    }
}

// 결과
50
30</code></pre><h3 id="초기화-블록">초기화 블록</h3>
<ul>
<li>자바에서 필드는 변수의 타입에 맞는 초깃값으로 자동으로 초기화해줌</li>
<li>명시적 초기화, 생성자를 이용한 초기화, 초기화 블록을 이용한 초기화</li>
<li>인스턴스 초기화 블록<ul>
<li>인스턴스가 생성될 때 마다 실행됨</li>
<li>인스턴스 초기화 블록이 생성자보다 먼저 실행됨</li>
<li>여러 개의 생성자가 있을 경우 공통으로 수행되는 코드를 초기화 블록에 포함하여 코드의 중복 막음</li>
<li>기본값 -&gt; 명시적 초기화 -&gt; 인스턴스 초기화 블록 -&gt; 생성자 순으로 초기화</li>
</ul>
</li>
</ul>
<p>Ex)</p>
<pre><code class="language-java">class Car {
    private String modelName;
    private int modelYear;
    private String color;
    private int maxSpeed;
    private int currentSpeed;

    {
        this.currentSpeed = 0; // 인스턴스 초기화 블록
    }

    Car() {
    }

    Car(String modelName, int modelYear, String color, int maxSpeed) {
        this.modelName = modelName;
        this.modelYear = modelYear;
        this.color = color;
        this.maxSpeed = maxSpeed;
    }

    public int getSpeed() {
        return currentSpeed;
    }
}

public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        Car myCar = new Car(); // 인스턴스 생성
        System.out.println(myCar.getSpeed()); // 인스턴스 메소드 호출
    }
}</code></pre>
<ul>
<li>클래스 초기화 블록<ul>
<li>클래스가 처음으로 메모리에 로딩될 때 단 한 번만 실행됨</li>
<li>기본값 -&gt; 명시적 초기화 -&gt; 클래스 초기화 블록 순으로 초기화</li>
</ul>
</li>
</ul>
<p>Ex) </p>
<pre><code class="language-java">class InitBlock {
    static int classVar;        // 클래스 변수
    int instanceVar;            // 인스턴스 변수

    static {                    // 클래스 초기화 블록을 이용한 초기화
        classVar = 10;
    }
}

public class Java100_variable_HelloJava {
    public static void main(String[] args) {
        System.out.println(InitBlock.classVar);     // 클래스 변수에 접근
    }
}</code></pre>
<hr>
<h3 id="참고">참고</h3>
<blockquote>
</blockquote>
<p>인프런 - 예제로 공부하는 Java 100문제 풀이 Part.1 참고
<a href="http://www.tcpschool.com/java/intro">TCP School - Java 강의 참고</a></p>
]]></description>
        </item>
    </channel>
</rss>