<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>haha_hoho.log</title>
        <link>https://velog.io/</link>
        <description>읽히는 코드를 짜고싶습니다.</description>
        <lastBuildDate>Mon, 22 Apr 2024 02:43:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>haha_hoho.log</title>
            <url>https://velog.velcdn.com/images/haha_hoho/profile/75f869e2-d8aa-4de1-80fe-9efca1daa28f/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. haha_hoho.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/haha_hoho" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[더이상 상속을 못하는 final 키워드 (클래스와 메소드)]]></title>
            <link>https://velog.io/@haha_hoho/%EB%8D%94%EC%9D%B4%EC%83%81-%EC%83%81%EC%86%8D%EC%9D%84-%EB%AA%BB%ED%95%98%EB%8A%94-final-%ED%82%A4%EC%9B%8C%EB%93%9C-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EB%A9%94%EC%86%8C%EB%93%9C</link>
            <guid>https://velog.io/@haha_hoho/%EB%8D%94%EC%9D%B4%EC%83%81-%EC%83%81%EC%86%8D%EC%9D%84-%EB%AA%BB%ED%95%98%EB%8A%94-final-%ED%82%A4%EC%9B%8C%EB%93%9C-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EB%A9%94%EC%86%8C%EB%93%9C</guid>
            <pubDate>Mon, 22 Apr 2024 02:43:54 GMT</pubDate>
            <description><![CDATA[<h1 id="final">final</h1>
<p>final 키워드는 변수, 메소드, 클래스를 선언할때 사용할 수 있다.
final 키워드가 어디에 쓰이느냐에 따라 해석이 조금씩 달라지는데, 특징이 있다면
final 키워드가 붙으면 제한을 건다는 것이다.
상수, 리터럴 값을 설정하려면 변수에 final이 쓰인다. 즉, final이 붙은 변수는 더이상 값을 변경할 수 없다.</p>
<h2 id="final-클래스">final 클래스</h2>
<p>클래스 선언할 때 final 키워드를 붙이면 이 클래스는 최종적인 클래스이므로 더이상 부모 클래스가 될 수 없다. 즉, 클래스 자체가 최종 클래스가 되는 것이다.
&#39;여기에서 대를 끊을래&#39;와 같은 의미이다.</p>
<p>형식</p>
<pre><code class="language-java">public final class 클래스명{ ... }</code></pre>
<h3 id="string-클래스">String 클래스</h3>
<p>우리가 마치 기본형처럼 사용하지만 첫글자가 대문자로 시작하는 String타입도 사실 final 클래스이다.
확인해보자!
<img src="https://velog.velcdn.com/images/haha_hoho/post/7714ce26-da26-4263-85f7-76700c9d7e52/image.png" alt="">
<img src="https://velog.velcdn.com/images/haha_hoho/post/920d78fc-f793-4b41-aa68-4a778d59b817/image.png" alt=""></p>
<p>코드</p>
<pre><code class="language-java">package myPractice;

public final class FinalClassPra {
    public int i = 1;
}
</code></pre>
<pre><code class="language-java">package myPractice;

public class FinalClass extends FinalClassPra {

}</code></pre>
<blockquote>
<p>FinalClassPre cannot be resolved to a type</p>
</blockquote>
<h2 id="final-메서드">final 메서드</h2>
<p>메소드를 선언할때 final 키워드가 붙으면 어떻게 될까?
이 메소드는 최종 메소드가 되어 오버라이딩 할 수 없는 메소드가 된다.</p>
<p>형식</p>
<pre><code class="language-java">public final 리턴타입 메소드(){...}</code></pre>
<p>코드
FinalClassPra</p>
<pre><code class="language-java">public class FinalClassPra {
    public int speed;

    public void go() {
        System.out.println(&quot;주행중&quot;);
        speed++;
    }
    public final void stop() {
        System.out.println(&quot;브레이크&quot;);
        speed = 0;
    }
}
</code></pre>
<p>FinalClass</p>
<pre><code class="language-java">public class FinalClass extends FinalClassPra {

    @Override
    public void go() {
        // TODO Auto-generated method stub
        super.go();
    }

    @Override // 오류
    private void stop() {
        // TODO Auto-generated method stub

    }
}</code></pre>
<blockquote>
<p>Cannot override the final method from FinalClassPra</p>
</blockquote>
<h2 id="정리">정리</h2>
<p>단어 자체 의미인 &#39;최종&#39;의 의미는 변하지 않는다.
final 키워드가 쓰인 멤버라면, 변하지 않을 것이라는 낙인이 찍힌 코드라고 생각하자.</p>
<h1 id="protected-접근-제한자">protected 접근 제한자</h1>
<p>앞서 다른 접근 제한자는 정리를 했다.
오늘 정리할 protected는 상속과 연관이 있기에 상속을 배운 지금, 정리를 해보고자 한다.</p>
<p>같은 패키지에서 default와 같이 접근 제한이 없지만 다른 패키지에서 자식 클래스만 접근이 허용되는 접근 제한이다.</p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/2c3d3169-81e9-4fb9-9a0c-483ce6231524/image.png" alt=""></p>
<ul>
<li>같은 패키지 내에 접근 가능</li>
<li>다른 패키지이지만 상속받았으면 접근 가능</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[스레드 동기화 java 코드로 보기 (Synchronized키워드, wait()와 notify())]]></title>
            <link>https://velog.io/@haha_hoho/%EC%8A%A4%EB%A0%88%EB%93%9C-%EB%8F%99%EA%B8%B0%ED%99%94-java-%EC%BD%94%EB%93%9C%EB%A1%9C-%EB%B3%B4%EA%B8%B0-Synchronized%ED%82%A4%EC%9B%8C%EB%93%9C-wait%EC%99%80-notify</link>
            <guid>https://velog.io/@haha_hoho/%EC%8A%A4%EB%A0%88%EB%93%9C-%EB%8F%99%EA%B8%B0%ED%99%94-java-%EC%BD%94%EB%93%9C%EB%A1%9C-%EB%B3%B4%EA%B8%B0-Synchronized%ED%82%A4%EC%9B%8C%EB%93%9C-wait%EC%99%80-notify</guid>
            <pubDate>Sun, 21 Apr 2024 01:07:22 GMT</pubDate>
            <description><![CDATA[<p>이전 <a href="https://velog.io/@haha_hoho/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4process%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9Cthread%EC%9D%98-%EA%B0%9C%EB%85%90">프로세스와 스레드를 코드로</a> 정리했다.
이번엔 스레드 동기화에대해 알아보자.</p>
<h1 id="🤔동기화">🤔동기화</h1>
<p>늘 사용하던 단어이지만 의미를 한번 더 짚고 넘어가려고 한다.
동기화를 배우면서 &#39;스레드&#39;를 조금 더 이해할 수 있었기에 짚고 넘어간다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/2be04c26-b5e4-4b47-bbd9-4e5be01aea0b/image.png" alt="">
위키백과에서 동기화는 <strong>시스템을 동시에 작동시키기 위해 여러 사건들을 조화시키는 것을 의미</strong>한다고 설명하고 있다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/e23a27d2-6919-4c4f-af5e-ce47394fc104/image.png" alt="">
네이버 어학사전은 <strong>작업들 사이의 수행 시기를 맞추는 것</strong>, 사건이 동시에 일어나거나, 일정한 간격을 두고 일어나도록 시간의 간격을 조정하는 것이라 설명한다.</p>
<p>👻<strong>약간의 제약(공유 정보는 한 스레드만 사용할 수 있도록)을 통해 공유하는 스레드가 최신 정보를 실시간으로 공유할 수 있도록 하는 것</strong>이라고 개인적으로 정리를 해보고 글을 시작하겠다.
(+ java 코드를 보고나면 더 잘 이해할 수 있다.)</p>
<h1 id="스레드-동기화">스레드 동기화</h1>
<p>싱글 스레드 프로그램에서는 1개의 스레드가 객체를 독차지해서 사용하면 되지만, <strong>멀티 스레드 프로그램에서는 스래드끼리 객체를 공유해서 작업해야 하는 경우</strong>가 있다.
이 경우에 문제가 발생할 가능성이 있다.</p>
<h2 id="스레드-동기화시-주의-사항">스레드 동기화시 주의 사항</h2>
<p> 다수의 스레드가 동시에 공유 데이터에 접근하면 공유 데이터가 훼손되는 문제가 발생한다.</p>
<h3 id="공유-데이터-훼손되는-문제-발생-가능">공유 데이터 훼손되는 문제 발생 가능</h3>
<ul>
<li><p><strong>두 스레드가 동시에 공유 데이터를 읽는 경우,</strong>
문제가 발생하지 않는다.</p>
</li>
<li><p>** A 스레드는 쓰고 B 스레드는 읽을 경우,**
: 읽고 쓰는 순서에 따라 읽는 값이 달라질 가능성이 있지만 공유 데이터의 훼손은 없다.</p>
</li>
<li><p><strong>A 스레드와 B 스레드가 동시에 공유 데이터에 쓰는 경우,</strong>
데이터의 훼손 가능성이 있다.</p>
<p>✨ 이런 경우 <strong>스레드 동기화</strong>를 사용하면 A스레드가 해당 객체를 사용할때 B 스레드가 대기 상태로 둘 수 있다. (FIFO의 느낌)</p>
</li>
</ul>
<h2 id="synchronized-키워드">Synchronized 키워드</h2>
<p>위와 같이 여러 스레드가 공유 변수에 접근할 때, 공유 데이터 훼손을 막기 위해서는 A 스레드가 <strong>공유 데이터 사용을 마칠때까지 다른 스레드가 공유 데이터에 접근 못하도록 제어(lock)하는 키워드</strong>이다.
즉, <strong>동기화를 가능하게 하는 키워드</strong></p>
<p>(운영체제도 정리해야하는데, 이번 글은 코드, 키워드에 집중하도록 하겠다.)</p>
<ul>
<li>사용자의 멀티스레드 프로그램에서 자주 발생한다. <strong>커널에 공유 데이터가 많기 때문에 자주 발생</strong>한다.</li>
<li><ul>
<li><strong>다중 코어에서 더욱 조심</strong>해야한다.<h3 id="✏️-임계구역과-상호배제">✏️ 임계구역과 상호배제</h3>
</li>
<li><strong>임계구역(critical Section)</strong>
공유 데이터에 접근하는 프로그램 코드들을 의미한다.</li>
</ul>
</li>
</ul>
<ul>
<li><strong>상호배제(Mutual Exelusion)</strong>
임계구역을 오직 한 스레드만 배타적, 독점적으로 사용하는 기술을 의미한다.<ul>
<li>임계구역에 먼저 진입한 스레드의 실행이 끝날 때까지 다른 스레드가 진입하지 못하도록 보장한다.</li>
</ul>
</li>
</ul>
<h1 id="💻-java-코드로-이해하기">💻 java 코드로 이해하기</h1>
<p>전에는 스레드를 2개 만들어 구현해봤다.
그동안은 읽고 출력하는 코드였기에 문제가 크게 없었다.</p>
<p>객체를 공유하여 사용할때 문제를 코드로 이해해보자.</p>
<hr>
<p><strong>✒️상황</strong>
(현실에서는 이러면 안되지만 가정이다.)
tom이 계좌를 계설해 통장이 있는데 lily도 해당 통장을 사용할 수도 있다.
<strong>통장에는 10000원이 있었다.</strong> 즉, 이 10000원이 공유자원이다.
tom은 입금을 하고 wife인 lily는 출금을 한다고 가정해보자.</p>
<hr>
<h2 id="synchronized-사용-전">synchronized 사용 전</h2>
<h3 id="bank-클래스">Bank 클래스</h3>
<pre><code class="language-java">public class Bank{
    private int money = 10000; //공유자원으로 사용할 자료

    public int getMoney(){ // getter
        return money;
    }

    public void setMoney(int money){ //setter
        this.money = money;
    }

    public void saveMoney(int mon){ //입금 기능
        int m = this.getMoney();
        try{
                Thread.sleep(2000); // 입금 시 지연시간(2초) 표현
        } catch (Exception e) {
            System.out.println(e);
        }
        setMoney(m + mon);
    }
    public void minusMoney(int mon){ //출금 기능
        int m = this.getMoney();
        if (mon &gt; m) {
            System.out.println(&quot;잔고액 보다 출금액이 더 큽니다.&quot;);
            return; //메소드의 탈출
        }
        try {
            Thread.sleep(3000); // 은행에 출금 시 약간의 지연 시간(3초)을 표현
        } catch (Exception e) {
            System.out.println(e);
        }
        setMoney(m - mon);
    }
}</code></pre>
<h3 id="main-메서드">Main 메서드</h3>
<p>실행되어야하는 메서드가 있어야한다. main 메서드를 만들기 위해 main클래스를 만들도록 하자. 위의 bank클래스로 접근하기 위해서는 객체 생성을 해야한다.
바로 불러올 수 있도록 static으로 만들것이다.</p>
<pre><code class="language-java">public class BankMain {
    public static Bank bank = new Bank();
    //생성자를 호출해서 객체 변수에 치환했다.
    //static 객체 변수로 만든 이유는 객체 변수명으로 바로 접근하기 위해서이다.

    public static void main (String[] args){
        System.out.println(&quot;원금 : &quot; + bank.getMoney() );

        Tom tom = new Tom(); // tom 인스턴스를 만들었다.
        Lily lily = new Lily(); // lily 인스턴스를 만들었다.

        tom.start(); // 스레드를 실행시킨다.
        lily.start(); // 스레드를 실행시킨다.

    }
}
</code></pre>
<h3 id="tom-클래스하나의-스레드">Tom 클래스(하나의 스레드)</h3>
<p>tom의 클래스를 만들것이다. 이용객을 하나의 흐름, 즉 스레드로 만들것이다.
implement로 runnable해도 되지만 Thread 객체를 만들어야하는 과정을 생략하고자
Thread를 상속받기로하자.</p>
<pre><code class="language-java">public class Tom extends Thread {
    @Override
    public void run(){
        BankMain.bank.saveMoney(5000); // tom이 입금
        //main을 통해서 Bank에 접근했다.

        System.out.println(&quot;남편 Tom 예금 후 잔고: &quot;+BankMain.bank.getMoney());
        //Bank클래스에서 money를 가져온다.
    }
}</code></pre>
<h3 id="lily-클래스-하나의-스레드">Lily 클래스 (하나의 스레드)</h3>
<p>lily의 클래스를 만들것이다. lily가 출금하는 상황이다.
tom과 동일하지만 implement로 runnable해도 되지만 Thread 객체를 만들어야하는 과정을 생략하고자 Thread를 상속받기로하자.</p>
<pre><code class="language-java">public class Lily extends Thread {
    @Override
    public void run(){
        BankMain.bank.minusMoney(2000); // Lily의 출금
        //main을 통해서 Bank클래스에 접근했다.

        System.out.println(&quot;아내 Lily 출금 후 잔고: &quot;+BankMain.bank.getMoney());
        //Bank클래스에서 money를 가져온다.
    }
}
</code></pre>
<p><strong>이 코드를 통해 우리가 원하는 결과가 무엇인가?</strong>
메서드 실행이 누가 먼저 끝날지 확신할 수 없지만, (무슨 실행이 먼저이든) 원금이 10,000원이 있었고 톰이 5,000원을 입금했고 릴리가 2,000원을 출금했으니 결과는 13,000원이길 바란다.</p>
<p>결과를 확인해보자.</p>
<blockquote>
</blockquote>
<p>원금 : 10000
남편 Tom 예금 후 잔고: 15000
Lily 출금 후 잔고: 8000</p>
<p>결과는 우리가 원하던 방식대로 몇초뒤에 출금과 적금이 이뤄졌다.
결과를 확인해보자. 우리가 원하는 결과인가? 아니다.
tom과 lily는 원금을 각자 읽어와서 각자의 과정을 수행했다.
시간 또한 의도한대로 입금은 2초가 걸렸고 출금은 3초가 <strong>각각</strong> 걸렸다.</p>
<h2 id="synchronized-사용-후">synchronized 사용 후</h2>
<p>위와 같이 특정 데이터를 동기화(바뀌면 바뀐 정보를 사용하도록)하고 싶다면, synchronized 키워드를 사용하면 된다.
Bank 클래스에 공유자원을 사용하는 메서드에 키워드를 추가해주면된다.</p>
<h3 id="bank-클래스-1">Bank 클래스</h3>
<pre><code class="language-java">public class Bank{
    private int money = 10000; //공유자원으로 사용할 자료

    public int getMoney(){ // getter
        return money;
    }

    public void setMoney(int money){ //setter
        this.money = money;
    }

    public synchronized void saveMoney(int mon){ //입금 기능
        int m = this.getMoney();
        try{
            Thread.sleep(2000) ;// 입금 시 지연시간(2초) 표현
        } catch (Exception e) {
            System.out.println(e);
        }
        setMoney(m + mon);
    }
    public synchronized void minusMoney(int mon){ //출금 기능
        int m = this.getMoney();
        if (mon &gt; m) {
            System.out.println(&quot;잔고액 보다 출금액이 더 큽니다.&quot;);
            return; //메소드의 탈출
        }
        try {
            Thread.sleep(3000); // 은행에 출금 시 약간의 지연 시간(3초)을 표현
        } catch (Exception e) {
            System.out.println(e);
        }
        setMoney(m - mon);
    }
}
</code></pre>
<p>결과를 확인해보자.</p>
<blockquote>
<p>원금 : 10000
남편 Tom 예금 후 잔고: 15000
Lily 출금 후 잔고: 13000</p>
</blockquote>
<p>원하는 결과가 나왔다!
synchronized 키워드로 인해 걸리는 시간 또한 다르다. 이전 실행결과는 각자 시간이 걸렸다면 동기화를 했기때문에 출금결과가 나오기까지는 5초가 걸렸다.</p>
<h4 id="🌼-동기화를-정리해보자-🌼">🌼 동기화를 정리해보자. 🌼</h4>
<p>A 스레드가 공유 자원을 사용하는 경우, B 스레드는 바로 접근하지 못한다.(lock기능) A 스레드가 공유 자원을 사용을 마칠때까지 대기 상태가 된다.
배운 용어들로 멋있게 풀어보자면, 하나의 스레드가 임계구역에 들어오면 상호배제 조건을 만족시키기 위해 lock을 걸어 접근을 제한시킨다.
이를 통해 공유하는 데이터에 최신성을 유지한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로세스(process)와 스레드(thread)의 코드]]></title>
            <link>https://velog.io/@haha_hoho/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4process%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9Cthread%EC%9D%98-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@haha_hoho/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4process%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9Cthread%EC%9D%98-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Fri, 19 Apr 2024 00:15:59 GMT</pubDate>
            <description><![CDATA[<h1 id="✏️-프로세스process란">✏️ 프로세스(process)란?</h1>
<p>프로세스란 단순히 실행 중인 프로그램(program)을 말한다.
프로그램은 코드의 모음이다. 특정 작업을 수행하는 일련의 명령어들의 모음을 의미한다.
사용자가 프로그램을 실행하여 <strong>운영체제에 의해 메모리 공간을 할당받아 실행 중인 프로그램을 말한다.</strong> 즉, 프로그램이 돌아가고 있는 상태, 작업중인 상태의 프로그램을 의미한다.
프로세스는 <strong>프로그램에 사용되는 데이터와 메모리 등의 자원 그리고 스레드로 구성</strong>된다.</p>
<h2 id="프로세스의-한계">프로세스의 한계</h2>
<p>오늘날 컴퓨터를 생각해보자. 파일을 다운받으며 유튜브 영상을 보거나 노래를 받는다. 멀티 작업이 가능하다는 것이다.
과거의 컴퓨터를 생각해보면 파일을 다운받으면 실행 시작부터 실행 끝까지 프로세스 하나만 사용했다. 즉, 파일이 완료될때까지 하루종일 기다려야했다.</p>
<h3 id="프로그램을-여러-개의-프로세스로-만들게-되잖아">프로그램을 여러 개의 프로세스로 만들게 되잖아?</h3>
<p>맞다. 가능은 하다. 하지만 프로그램이 메모리로 올라오면서 차지하는 메모리가 있고 CPU에서 할당받는 자원이 중복될 것이다.</p>
<h3 id="process-단위-실행-코드">process 단위 실행 코드</h3>
<p>실제로 이렇게 사용하진 않지만 계산기를 실행시켜보는 코드를 짜보자.</p>
<pre><code class="language-java">public static void main(String[] args)  { 
    try {
        //process 단위의 실행 (하나의 작업단위)
        Process p1 = Runtime.getRuntime().exec(&quot;calc.exe&quot;);
    } catch (Exception e) {
            System.out.println(&quot;err : &quot;+ e);
    }
}</code></pre>
<h4 id="runtime">Runtime</h4>
<p>Runtime클래스의 getRuntime()메서드가 있다.
해당 클래스에 들어가 설명을 읽어보자.</p>
<hr>
<p>Every Java application has a single instance of class</p>
<ul>
<li><strong>{@code Runtime} that allows the application to interface with</strong></li>
<li>the environment in which the application is running. The current</li>
<li>runtime can be obtained from the {@code getRuntime} method.</li>
<li>An application cannot create its own instance of this class.
....</li>
</ul>
<p>Returns the runtime object associated with the current Java application.
 <strong>✨해석</strong>
 현재 Java 응용 프로그램과 연결된 런타임 개체를 반환합니다.</p>
<h4 id="exec">exec()</h4>
<p> Executes the specified string command in a separate process.
  <strong>✨해석</strong>
  지정한 문자열 명령을 별도의 프로세스에서 실행합니다.</p>
<hr>
<p>🪄위와 같이 프로세스 하나를 실행할 수 있다.
<strong>하나의 프로세스에 하나의 스레드를 가지고 있으면 싱글스레드라고 한다.</strong>
싱글 스레드의 경우, 코드는 순차적으로 진행한다.
즉, cpu가 연산작업을 안하는 <strong>idle time</strong>이 발생한다.</p>
<h1 id="✏️스레드thread란">✏️스레드(thread)란?</h1>
<p>스레드(thread)란 <strong>프로세스(process)내에서 실제로 작업하는 주체</strong>를 의미한다.
<strong>모든 프로세스는 한개 이상의 스레드가 존재한다.</strong> 메인 스레드가 돌아가야 프로그램이 돌아가기 때문이다.
응용 프로그램의 실행은 <strong>실행단위(thread)</strong>가 담당한다.
두개 이상의 스레드를 가지는 프로세스를 멀티스레드 프로세스(multi-threaded process)라고 한다.
multi thread에 의한 multi tasking이 가능하다.</p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/c70ad6fd-98f2-461d-8d3d-50923a18ab02/image.png" alt=""></p>
<ul>
<li>Code, Data, Heap 영역을 공유한다.</li>
<li>각 Thread에 Stack은 따로 할당된다.</li>
</ul>
<p>프로세스 내의 <strong>주소 공간이나 자원을 같은 프로세스 내에 스레드끼리 공유하면서 실행</strong>한다.
다른 프로세스의 메모리는 직접 접근할 수 없어 IPC를 이용해 접근해야한다.
한 스레드가 프로세스 자원을 변경하면 다른 스레드(Sibling thread)도 그 변경 사항을 즉시 공유받을 수 있다.</p>
<h2 id="스레드의-생성">스레드의 생성</h2>
<p>스레드를 생성하는 방법에는 크게 2가지 방법이 있다.
<strong>스레드 기능을 사용하기 위해서는 run()메서드를 오버라이딩해야한다.</strong>
run()메서드는 Runnable에 구현되어있는데 해당 클래스를 열어보자. </p>
<pre><code class="language-java">public interface Runnable {
    public abstract void run();
}</code></pre>
<ul>
<li>extends Thread 
: Thread 클래스는 Runnable을 구현하고 있는 클래스이다. 이 클래스는 마치 adapter와 같은 역할을 한다.</li>
<li>implements Runnable
: Runnable를 구현받는 것을 의미한다.</li>
</ul>
<h3 id="1-extends-thread-방법">1. extends Thread 방법</h3>
<pre><code class="language-java">public class ThreadTest1 extends Thread{
    public ThreadTest1(){

    }
    public ThreadTest1(String name) {
        super(name);
    }

    public void run() { 
        for(int i = 1; i &lt;=10;i++) {
            System.out.print(i+&quot; : &quot;+getName()+&quot; &quot;);

        }
    }
    public static void main(String[] args)  {
        try {
            ThreadTest1 th1 =new ThreadTest1(&quot;one&quot;);
            th1.start();
            Ex37ThreadTest1 th2 =new Ex37ThreadTest1(&quot;two&quot;);
            th2.start();
            System.out.println();
            System.out.println(&quot;프로그램 종료&quot;);
        } catch (Exception e) {
            System.out.println(&quot;err : &quot;+ e);
        }
    }
} </code></pre>
<blockquote>
<p><strong>출력 결과</strong>
프로그램 종료
1: one 2: one 1: two 3: one 2: two 3: two 4: one 4: two 5: one 5: two 6: two 7: two 8: two 9: two 10: two 6: one 7: one 8: one 9: one 10: one</p>
</blockquote>
<p>java에서는 단일 상속을 원칙으로 하기때문에 extends를 키워드를 아껴서 사용해야한다.
만약 코드를 짜다가 다른 클래스를 상속받아야하는 경우, 또 다른 방법인 <code>implements</code> 키워드를 사용하는 방법을 사용하자.
++Thread 클래스에 start(), sleep(), yield() ..등 다양한 메서드가 있어 바로 사용할 수 있다는 장점이 있다.</p>
<h3 id="2-implements-runnable-방법">2. implements Runnable 방법</h3>
<pre><code class="language-java">
public class Thread2 implements Runnable {

    public Thread2() {

    }
    //public Thread2(String name) { //생성자 이용
    //    Thread tt = new Thread(this,name);
    //    tt.start();
    //}
    @Override
    public void run() {
        for (int i = 1; i &lt;= 10; i++) {
            System.out.println(i+&quot;: &quot;+Thread.currentThread().getName());
            //currentThread() 현재 사용중인 쓰레드
            try {
                Thread.sleep(100); 
                //Unhandled exception type InterruptedException 예외처리
                //thread를 일정 시간동안 비활성화.

            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
    public static void main(String[] args) {
        Ex38Thread2 my1 = new Ex38Thread2();
        Ex38Thread2 my2 = new Ex38Thread2();
        Thread t1 = new Thread(my1);
        t1.start();
        Thread t2 = new Thread(my2);
        t2.start();

        //new Ex38Thread2(&quot;하나&quot;);
        //new Ex38Thread2(&quot;둘&quot;);

        System.out.println(&quot;종료&quot;);
    }

}</code></pre>
<p>Runnable클래스를 implements하는 방법이다. Thread 클래스의 메서드를 사용하기 위해서는 인스턴스해야하는 약간의 단점이 있다.</p>
<h4 id="💫자주-사용하는-thread-메서드">💫자주 사용하는 Thread 메서드</h4>
<p>스레드 상태를 제어하기 위해 다양한 메서드가 있는데, 크게 2가지로 나뉜다. (우선순위 메서드인 .setPriority()메서드는 어디에 둬야하나..)
우선, 스레드의 상태를 확인하는 메서드를 알아보자.</p>
<h5 id="getstate">get.state()</h5>
<pre><code class="language-java"> //현재 쓰레드 상태 확인
 System.out.println(thread.getState());

 //추가로 현재 사용중인 쓰레드 확인 (currentThread())
 System.out.println(Thread.currentThread().getName());</code></pre>
<p>위와 같은 코드를 사용하면 현재 상황을 확인할 수 있다.</p>
<p>state()의 메서드를 열어보면 state0()</p>
<h5 id="✨-실행-대기-상태로-만드는-메서드">✨ 실행 대기 상태로 만드는 메서드</h5>
<ul>
<li><p><strong>interrupt()</strong>
일시 중지 상태인 스레드를 실행 대기 상태로 복귀시키는 메서드이다. <code>멈춘 스레드.interrupt()</code>를 호출하여 정지 상태를 실행 대기 상태로 전환할 수 있다.</p>
<pre><code class="language-java">thread.interrupt();</code></pre>
<p>이 메서드는 <strong>실행하는 강제하는 메서드</strong>이다.</p>
</li>
<li><p><strong>yield()</strong>
실행을 다른 스레드에게 양보하는 메서드이다.
스케줄러에 의해 10초동안 할당받은 스레드가 있다면, 4초 동안 작업을 수행하다가 yield() 메서드를 호출하면, 남은 6초를 뒤의 스레드에게 양보하는 메서드이다.</p>
</li>
</ul>
<hr>
<p> 메서드를 열어보면 설명이 나오는데,
 <code>Causes the currently executing thread to sleep (temporarily cease
 execution) for the specified number of milliseconds, subject to  the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.</code>
 ✨<em>변역</em>
 현재 실행 중인 스레드를 <strong>절전 모드로 전환</strong>합니다 <strong>(일시적으로 중지)</strong>
execution) 시스템 타이머 및 스케줄러의 정밀도 및 정확도에 따라 지정된 밀리초 수에 대해. 스레드는 모니터의 소유권을 잃지 않습니다.</p>
<hr>
<pre><code class="language-java">try{
    Ex37ThreadTest1 th1 =new Ex37ThreadTest1(&quot;one&quot;);
    th1.start();

    th1.yield();
} catch(Exception e){
    ...
}</code></pre>
<h5 id="✨-실행을-멈추는-메서드">✨ 실행을 멈추는 메서드</h5>
<ul>
<li><strong>sleep(long milliSecond)</strong></li>
</ul>
<pre><code class="language-java">try{
    Thread.sleep(1000); // 1000 = 1초
} catch (Exception e){
    System.out.print(e.getMessage)
}</code></pre>
<p>sleep()메서를 사용하면 실행한 스레드의 상태는 일시 정지 상태가 된다. <strong>인자로 전달한 시간이 지나거나 interrupt() 메서드를 호출한 경우 다시 실행 대기 상태로 복귀</strong>한다.
약간의 오차는 발생할 수 있다.</p>
<ul>
<li><p><strong>join()</strong></p>
<pre><code class="language-java">try{
  Ex37ThreadTest1 th1 =new Ex37ThreadTest1(&quot;one&quot;);
  th1.start();

  th1.join();
} catch(Exception e){
  ...
}</code></pre>
<p>th1 스레드가 종료될 때까지 main 스레드 종료를 대기시키는 메서드이다.
join() 메서드를 열어보자.
<img src="https://velog.velcdn.com/images/haha_hoho/post/84bd1e0b-ff13-4f76-be01-aef8430047d1/image.png" alt="">
(메서드를 잘 안 열어봐서 그런지 첫문장이 좀 웃겼다ㅋㅋㅋ)
현재 스레드가 죽기를 기다리는 메서드이다.</p>
</li>
</ul>
<p>그 다음 문단이 약간 이해가 안가는데, &quot;이 메스드의 호출은 호출과 정확히 동일한 방식으로 동작한다.&quot;는 문장이다..?</p>
<p>그리고 InterruptedException을 던지고 있다.
때문에 해당 메서드를 사용할때는 try-catch구문을 사용해야한다.</p>
<ul>
<li><p><strong>th1.setPriority(MAX_PRIORITY);</strong>
스레드는 CPU 우선순위에 의해 동작되어 java에서 제어하기 힘들다. 스레드 스케줄러에게 우선 순위를 요청할 수 있다.
.setPriority(...)이다.</p>
<ul>
<li>최대 우선 순위
MAX_PRIORITY = 10</li>
<li>최소 우선 순위
MIN_PRIORITY = 1</li>
<li>일반적 우선순위
NORM_PRIORITY = 5</li>
</ul>
</li>
</ul>
<pre><code class="language-java">try{
    Ex37ThreadTest1 th1 =new Ex37ThreadTest1(&quot;one&quot;);
    th1.start();
    Ex37ThreadTest1 th2 =new Ex37ThreadTest1(&quot;two&quot;);
    th2.start();

    th2.setPriority(MAX_PRIORITY);

} catch(Exception e){
    ...
}</code></pre>
<p>물론 요청하는 것이기에 스레드 스케줄러에 무조건 적용이 되는 것은 아니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[입출력 스트림 Stream _1]]></title>
            <link>https://velog.io/@haha_hoho/%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%8A%A4%ED%8A%B8%EB%A6%BC-Stream-1</link>
            <guid>https://velog.io/@haha_hoho/%EC%9E%85%EC%B6%9C%EB%A0%A5-%EC%8A%A4%ED%8A%B8%EB%A6%BC-Stream-1</guid>
            <pubDate>Thu, 18 Apr 2024 05:38:41 GMT</pubDate>
            <description><![CDATA[<h1 id="입출력-스트림">입출력 스트림</h1>
<p>자바에서 데이터는 Stream을 총해 입출력된다.
스트림은 FIFO 형식으로 단일 방향으로 연속적으로 흘러간다.
위치에 따라 달라진다.</p>
<h2 id="javaio">java.io</h2>
<p>java.io 패키지에는 여러가지 종류의 스트림 클래스를 제공하고 있다.
크게 2가지 종류로 구분된다.</p>
<ul>
<li>바이트 byte기반 스트림
:그림, 멀티미디어 등의 바이너리 데이터를 읽고 출력할 때 사용</li>
<li>문자 character 기반 스트림
: 문자 데이터를 읽고 출력할 때 사용</li>
</ul>
<p>📝구별하는 방법은 최상위 클래스를 보면 된다.</p>
<h3 id="바이트-기반-스트림">바이트 기반 스트림</h3>
<h4 id="입력스트림-inputstream">입력스트림 InputStream</h4>
<p>InputStream 클래스를 상속받아서 만들어진다.</p>
<h4 id="출력스트림-outputstram">출력스트림 OutputStram</h4>
<p>OutputStram 클래스를 상속받아서 만들어진다.</p>
<h3 id="문자-기반-스트림">문자 기반 스트림</h3>
<h4 id="입력스트림-readr">입력스트림 Readr</h4>
<p>Readr 클래스를 상속받아서 만들어진다.</p>
<h4 id="출력스트림-writer">출력스트림 Writer</h4>
<p>Writer 클래스를 상속받아서 만들어진다.</p>
<h2 id="console과-file을-통한-입력">console과 file을 통한 입력</h2>
<h3 id="1-inputstreamreader와-bufferedreader-사용">1. InputStreamReader와 BufferedReader 사용</h3>
<pre><code class="language-java">package io;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class IoTest {
    public static void main(String[] args) throws Exception {
        //console과 file을 통한 입력
        //1. console을 통한 입력 (예전 방식)
        InputStreamReader in = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(in); //속도 조절
        System.out.print(&quot;이름은 &quot;);
        String ir = br.readLine(); //Unhandled exception type IOException //예외처리
        System.out.println(&quot;이름은 &quot; + ir);
        br.close();
        in.close();
    }
}
</code></pre>
<h3 id="2-scanner-사용">2. Scanner 사용</h3>
<pre><code class="language-java">
package pack5io;

import java.io.BufferedReader;
import java.io.InputStreamReader; //scanner가 없을때
import java.util.Scanner;

public class Ex34IoTest {
    public static void main(String[] args) throws Exception {
        //console과 file을 통한 입력

        //scnner 클래스
        Scanner scanner = new Scanner(System.in);
        System.out.print(&quot;이름은&quot;);
        String ir= scanner.nextLine();
        System.out.print(&quot;몸무게는&quot;);
        double w = scanner.nextDouble();
        System.out.println(ir+&quot;님의 몸무게는 &quot;+w);
        scanner.close();
    }
}

</code></pre>
<h2 id="파일-데이터-가져와-읽어보자">파일 데이터 가져와 읽어보자.</h2>
<p><strong>파일을 가져올때 반드시 저작권에 주의하자.</strong></p>
<h3 id="🔧사용할-데이터-준비">🔧사용할 데이터 준비</h3>
<p>나라에서 제공하는 정보인 공공 데이터포털이 있다.
<a href="https://www.data.go.kr/">https://www.data.go.kr/</a>
다양한 데이터들이 존재하는데, 전국 도서관 정보를 가져와보자.
(다른 데이터여도 상관없다.)</p>
<p>전국 도서관 표준데이터 검색 &gt; csv를 다운 &gt;<br><img src="https://velog.velcdn.com/images/haha_hoho/post/a7019968-8872-453a-ba23-bdeec7030ebb/image.png" alt=""></p>
<p>엑셀 파일이 다운로드 되었을 거다.
해당 파일을 메모장으로 열어보자.
<img src="https://velog.velcdn.com/images/haha_hoho/post/77af4fed-f8d8-4084-8040-7385b78dc775/image.png" alt=""></p>
<p>메모장에는 csv 파일답게 데이터들이 ,(쉼표)로 되어있을 것이다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/360d8e5d-00a4-469f-8b40-92c7b82804a6/image.png" alt="">
(공공데이터이지만 혹시 몰라 색칠했다.)
중요한 것은 하단에 UTF-8로 되어 있는지 확인하는 것이다.
만약 UTF-8로 저장되지 않는다면
*<em>상단<code>파일</code> &gt; 다른이름으로 저장 &gt; utf-8로 설정 *</em>
<img src="https://velog.velcdn.com/images/haha_hoho/post/6bda1210-1e1c-4f16-8dd7-92877918b472/image.png" alt="">
위의 사진처럼 다시 저장을 해주면 된다 (덮어쓰기 OK)</p>
<h3 id="✏️-파일-읽기">✏️ 파일 읽기</h3>
<pre><code class="language-java">System.out.println(&quot;전국 도서관 정보 파일 일부 읽기 =--=-=-=-=&quot;);
        //파일위치를 알려준다.
        File file = new File(&quot;c:/work/전국도서관표준데이터.csv&quot;);
        //파일에서 입력을 받는다.
        FileReader fr2 = new FileReader(file);
        BufferedReader br2 = new BufferedReader(fr2);

        int count = 0;
        //한 줄씩 값을 읽고 객체에 전달한다.
        String ss = br2.readLine();
        while (true) {
            count++;
            ss = br2.readLine();
            if (ss == null || count &gt;= 10)
                break;
            //받은 파일을  ,(쉼표)단위로 잘라 입력해준다.
            StringTokenizer tok = new StringTokenizer(ss, &quot;,&quot;);
            String s1 = tok.nextToken();
            String s2 = tok.nextToken();
            String s3 = tok.nextToken();
            String s4 = tok.nextToken();

            System.out.println(s1 + &quot;\t&quot; + s2 + &quot;\t&quot; + s3 + &quot;\t&quot; + s4);
        }
        System.out.println(&quot;건수: &quot; + count);
</code></pre>
<h4 id="bufferedreader">BufferedReader</h4>
<p>: Scanner와 유사gkek</p>
<p><strong>Scanner보다 속도가 훨씬 빠르다.</strong>
왜냐하면 <strong>입력된 데이터가 바로 전달되지 않고 버퍼를 거쳐 전달되므로 데이터 처리 효율성이 높인다.</strong>
BufferedReader는 많은 양의 데이터를 처리할 때 유리하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Lombok에 대해서 + 설치]]></title>
            <link>https://velog.io/@haha_hoho/Lombok%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%84%A4%EC%B9%98</link>
            <guid>https://velog.io/@haha_hoho/Lombok%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%84%A4%EC%B9%98</guid>
            <pubDate>Wed, 17 Apr 2024 11:01:36 GMT</pubDate>
            <description><![CDATA[<h1 id="lombok이란">Lombok이란?</h1>
<p>기존에 getter와 setter를 직접 적어주거나 이클립스에서 제공하는 소스를 사용했다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/12865d1d-1ed1-4846-859d-9f1e8a721553/image.png" alt=""></p>
<p>Lombok은 java의 라이브러리인데, 기계적인 코드를 자동화하여 코드를 간략하게 적을 수 있는 압축파일이다.</p>
<p><strong>어노테이션 기반으로</strong> 반복되는 클래스나 메서드 코드를 자동 완성해주는 기능을 한다. </p>
<h2 id="✏️-장점-단점">✏️ 장점/ 단점</h2>
<h3 id="특징">특징</h3>
<p>한쪽만 설치해야한다.
한쪽에 풀면 다른쪽에 사용하지 못한다.</p>
<h3 id="장점">장점</h3>
<p>lombok은 복잡하고 반복되는 코드를 어노테이션 기반으로 자동 생성을 통해 <strong>코드가 축소되어 가독성 및 유지보수성을 높일 수 있다.</strong></p>
<h3 id="단점">단점</h3>
<p>축소되어 어노테이션의 모양으로 숨어있기때문에 직관성이 떨어질 수 있다.</p>
<h2 id="🔧설치">🔧설치</h2>
<h3 id="1-lombokjar-파일을-다운로드한다">1. lombok.jar 파일을 다운로드한다.</h3>
<p><a href="https://projectlombok.org/download">https://projectlombok.org/download</a></p>
<p>다운로드할때 파일 위치는 자신이 찾기 편한 곳에 설치하는 것을 권장한다!</p>
<h3 id="2-cmd-창으로-들어간다">2. cmd 창으로 들어간다.</h3>
<p>명령 프롬프트 창에 들어간다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/c38b9424-0fac-46f3-9620-6819b6c51aea/image.png" alt=""></p>
<h4 id="cd-c위치">cd (c:/위치)</h4>
<p>lombok이 다운로드된 곳으로 찾아가야한다.</p>
<h3 id="jar파일을-풀어주자">jar파일을 풀어주자.</h3>
<h4 id="java--jar-파일명jar">java -jar 파일명.jar</h4>
<p><a href="https://velog.io/@haha_hoho/.jar">jar</a>는 java 압축파일이다. jar를 풀려면 위와 같은 명령어를 사용해야한다.</p>
<h3 id="3-창이-실행된다">3. 창이 실행된다.</h3>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/85e848ec-3779-42f1-a43b-41161e0ab9b6/image.png" alt="">
왼쪽 <strong>Specify location..</strong> 버튼을 눌러 lombok을  선택한다.</p>
<p>자신이 사용하고 있는 (자신이 사용하는 이클립스를 선택해야한다. 럼북은 한곳을 설정하면 설정된 다른 곳은 풀린다.)이클립스를 선택한다.</p>
<p>선택 후 오른쪽에 있는 <strong>install/Update</strong>를 선택하고 Quit Installer를 클릭해준다.</p>
<h3 id="4-이클립스를-다시-실행한다">4. 이클립스를 다시 실행한다.</h3>
<p>확인의 단계이다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/162ceb51-9158-4640-90a8-58103fa3c380/image.png" alt="">
우선 위의 사진처럼 <code>outline</code>을 창의 띄워준다.</p>
<p>클래스를 하나 만들고 클래스 상단에 @Getter와 @Setter를 적어보자.
<img src="https://velog.velcdn.com/images/haha_hoho/post/91e2b037-d30c-4851-ab08-eb160e631e3f/image.png" alt=""></p>
<p>아래와 같이 getter와 Setter가 생성되었으면 럼북이 정상적으로 설치되었다는 의미이다.</p>
<h3 id="-만약-설정이-잘-안되었다면">+ 만약 설정이 잘 안되었다면?</h3>
<h4 id="1-자신이-사용하는-프로젝트를-선택하고-우클릭-build-path--configure-build-path를-클릭해준다">1. 자신이 사용하는 프로젝트를 선택하고 우클릭&gt; Build Path &gt; configure Build Path...를 클릭해준다.</h4>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/9095a8bc-12fc-4641-b1f8-3a5572b52978/image.png" alt=""></p>
<h4 id="2-libraries를-선택한-후-classpath를-선택해주자-왼쪽-add-external-jars클릭">2. Libraries를 선택한 후 classPath를 선택해주자. 왼쪽 Add External JARs..클릭</h4>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/2091f778-2cdb-424f-a786-db97528e3ce7/image.png" alt=""></p>
<p>저도 바로 설정이 안되었기에 Build Path를 해줬습니다.! Apply and Close를 눌러주고
<strong>다시 실행해주세요(4번 반복)</strong>
그래도 안되면 이클립스를 다시 재실행해주세요 :-)</p>
<h2 id="✨-자주-사용되는-lombok-어노테이션">✨ 자주 사용되는 lombok 어노테이션</h2>
<ul>
<li><strong>@Getter / @Setter</strong>
:getter와 setter를 만들어 줍니다.</li>
<li><strong>@NoArgsConstructor</strong>
:아규먼트가 없는 생성자를 만들어줍니다.</li>
<li><strong>@AllArgsConstructor</strong>
:모든 아규먼트가 있는 생성자를 만들어줍니다.</li>
<li><strong>@RequiredArgsConstructor</strong>
: final이나 @NonNull인 필드 값만 파라미터로 받는 생성자를 만들어줍니다.</li>
<li>@NonNull
:메서드나 생성자의 매개변수에 사용하면 null check를 한다.</li>
<li><strong>@EqualsAndHashCode</strong>
:equals와 hashcode를 자동으로 생성해줍니다.</li>
<li><strong>@Data</strong>
:@Getter,Setter,RequiredArgsConstructor, ToString, EqualsAndHashCode를 모두 만들어 주는 어노테이션입니다. (많은 데이터를 가지고 있는만큼 무겁고 lombok의 단점인 직관성또한 굉장히 떨어지는 어노테이션입니다. 사용을 지양)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[1. Git 개념과 기본 용어 정리]]></title>
            <link>https://velog.io/@haha_hoho/Git-%EA%B0%9C%EB%85%90%EA%B3%BC-%EA%B8%B0%EB%B3%B8-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC-%EB%B0%8F-%EC%97%B0%EC%8A%B5</link>
            <guid>https://velog.io/@haha_hoho/Git-%EA%B0%9C%EB%85%90%EA%B3%BC-%EA%B8%B0%EB%B3%B8-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC-%EB%B0%8F-%EC%97%B0%EC%8A%B5</guid>
            <pubDate>Tue, 16 Apr 2024 09:19:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>git은 분산 버전 관리 시스템 중 하나입니다.
<strong>즉, 도구</strong>입니다.</p>
</blockquote>
<h1 id="git이란">Git이란?</h1>
<p>오픈 소스 버전 관리 시스템(VCS: Version Control System)으로 로컬에서 버전을 관리하는 도구이다.
git은 자신의 코드와 그 수정 내역을 기록하고 관리하도록 하는 버전 관리 프로그램이다.</p>
<p>git을 통해 <strong>브랜치를 생성</strong>하고 이전 <strong>브랜치로 복구, 삭제, 병합</strong>이 가능하다.</p>
<p><strong>로컬 저장소를 사용하기 때문에 다른 개발자와 실시간으로 작업을 공유할 수 없다.</strong></p>
<h2 id="특징">특징</h2>
<ul>
<li>로컬 및 원격 저장소 생성</li>
<li>로컬 저장소에 파일생성 및 추가</li>
<li>수정 내역을 로컬 저장소에 제출</li>
<li>파일 수정내역 추적</li>
<li>원격 저장소에 제출된 수정 내역을 로컬 저장소에 적용</li>
<li>master에 영향을 끼지치 않는 브랜치(branch) 생성</li>
<li>브랜치 병합(merge)</li>
</ul>
<h1 id="설치하기">설치하기</h1>
<p><a href="https://git-scm.com/downloads">git 설치페이지 바로가기</a></p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/37668990-1a70-4ea6-b70c-534389e6b66d/image.png" alt=""></p>
<p>각 OS에 맞는 프로그램을 설치하면 된다.
나는 윈도우를 사용하고 있기때문에 윈도우를 선택했다.</p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/4b88f431-aae0-4f14-8308-c17747cd8730/image.png" alt="">
들어가 글 가장 상단에 download를 클릭하면 바로 프로그램이 다운로드된다.</p>
<p>모든 프로그램이 그렇지만 <strong>파일 저장 위치</strong> 잘 확인해주세요!</p>
<h1 id="사용자-정보-설정">사용자 정보 설정</h1>
<p>다운로드를 한 파일에 들어가면 Git 파일을 확인할 수 있다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/9b61a647-7486-40ce-a453-a26d9159d1ad/image.png" alt=""></p>
<p>우리가 작업할 공간은 <strong>git Bash</strong>이다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/fcd449a2-f3d0-447a-ab23-c94b06eb8547/image.png" alt="">
 ++ .exe 확장자는 실행 파일을 의미한다.</p>
<hr>
<blockquote>
<p>git Bash란?</p>
</blockquote>
<p> Bash는 &#39;Bourne Again Shell&#39;의 줄임말이다. 스티븐 본 이라는 사람이 개발한 <strong>유닉스 쉘 프로그램인 sh의 확장판</strong>이라는 의미를 담고있다.</p>
<h4 id="shell">shell?</h4>
<p> 쉘이란 키보드로 입력한 명령어를 운영체제에 전달하여, 실행하게 하는 프로그램이다.</p>
<h4 id="유닉스">유닉스?</h4>
<p> Git Bash는 리눅스 환경이다.
 리눅스는 유닉스 계열의 운영체제를 기반으로 만들어졌다. </p>
<p> Git Bash를 설치하면 window 환경에서 리눅스 커맨드를 사용할 수 있다.</p>
<hr>
<h2 id="git-버전-확인">Git 버전 확인</h2>
<pre><code class="language-git"> git -v</code></pre>
<p> <img src="https://velog.velcdn.com/images/haha_hoho/post/3562baa6-db90-4a29-994f-e10f448176e8/image.png" alt=""></p>
<h2 id="사용자-정보-설정-1">사용자 정보 설정</h2>
<p><strong>Git 설치 후 가장 먼저 할 것</strong>
사용자 이름과 이메일 주소를 설정해야 한다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/a75743c9-b17d-4fe6-8be9-24c688cf1381/image.png" alt=""></p>
<pre><code class="language-git">git config --global user.name &quot;본인 아이디&quot;

git config --global user.email ~~@~~.com</code></pre>
<p>위와 같이 적고나면 사용자 이름과 이메일 주소가 잘 들어갔는지 확인해보자.</p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/5dc0f9f4-8ff5-4731-8120-41759cd29f03/image.png" alt=""></p>
<pre><code class="language-git">git config user.name

git config user.email</code></pre>
<p>git은 커밋할 때마다 이 정보를 사용한다.
한번 커밋한 후에는 정보를 변경할 수 없다.</p>
<h1 id="기본-명령어">기본 명령어</h1>
<h2 id="git의-기본-용어">git의 기본 용어</h2>
<p>git은 하나의 도구이지만 처음 사용할 때 어려움을 느낀다. 가장 먼저 기본되는 용어부터 알아보는 것이 장벽을 낮출 수 있는 것 같다.</p>
<h3 id="저장소-종류">저장소 종류</h3>
<p>Git은 Repository내의 파일을 관리한다.</p>
<h4 id="remote-repository-원격-저장소">Remote Repository :원격 저장소</h4>
<p>원격 서버(GitHub)에 저장된 저장소이다. 여러 사람이 함께 공유한다.</p>
<h4 id="local-repository-로컬-저장소">Local Repository :로컬 저장소</h4>
<p>사용자가 직접 관리하는 저장소이다. 내 PC에 저장되어 있다.</p>
<blockquote>
<p>로컬 내부 구조로 <strong>3가지 영역</strong>으로 나눠진다.</p>
</blockquote>
<p> <img src="https://velog.velcdn.com/images/haha_hoho/post/5e25a814-2415-47ed-996e-e20922d9e894/image.png" alt="">
(직접 그린 그림..ㅎ)</p>
<h5 id="-working-directory--작업폴더-작업트리">* Working Directory : 작업폴더, 작업트리</h5>
<p> 실제 작업하는 영역이다.</p>
<h5 id="-staging-area--스테이징-스태시">* Staging Area : 스테이징, 스태시</h5>
<p> Working tree에서 작업한 파일을 임시로 올려놓는 공간이다.</p>
<h5 id="-local-repository-로컬-저장소">* Local Repository: 로컬 저장소</h5>
<p> PC 내에서 동작하는 저장소를 의미한다. PUSH하기 전까지는 원격 저장소에 반영되지 않기 때문에 원격 저장소에 Dependency없이 오프라인으로 작업이 가능하다.</p>
<h2 id="git-기본-명령어">git 기본 명령어</h2>
<p><strong>git bash는 리눅스 커멘드를 사용한다.</strong>
CLI 환경에서 git을 설치하고 git ~~으로 사용한다.</p>
<h4 id="add">add</h4>
<p>수정된 파일들을 Staging 영역으로 보낸다.</p>
<h4 id="commit--커밋">Commit : 커밋</h4>
<p>Staging Repository로 내용을 전달한다.</p>
<h4 id="clone--클론">Clone : 클론</h4>
<p>Remote Repository의 특정 브랜치를 Local로 복사한다.
remote 설정을 자동으로 해주는 초기 다운로드 때 사용한다.</p>
<h4 id="fork--포크">Fork : 포크</h4>
<p>Clone과 비슷하게 저장소를 복사하지만 Remote에서 Remote로 복사한다.</p>
<h4 id="pull--풀">Pull : 풀</h4>
<p>Fetch와 Merge가 한번에 수행된다.
Remote 설정이 이미 되어있을 때, 업데이트 사항 등을 다운로드 할 때 사용한다.</p>
<h4 id="fetch--패치">Fetch : 패치</h4>
<p>Remote 영역의 내용을 가져와서 업데이트를 한다.
Merge하기 전까지는 작업영역인 Working Directory에 반영되지 않는다.</p>
<h4 id="merge--머지">Merge : 머지</h4>
<p>Local 영역에서 갱신된 내용을 거져와서 반영한다. 이때 같은 영역에 다른 변경사항이 있다면 <strong>충돌</strong>이 발생한다.</p>
<h2 id="리눅스-명령어">리눅스 명령어</h2>
<h4 id="pwd">pwd</h4>
<p>CLI가 작업하고 있는 장소를 알려준다.</p>
<h4 id="cd-디렉토리명">cd 디렉토리명</h4>
<p>적은 디렉토리로 진입하겠다는 의미이다.</p>
<h4 id="cd-">cd ..</h4>
<p>현재 디렉토리에서 부모 디렉토리로 빠져나간다는 뜻이다.</p>
<h5 id="">.</h5>
<p>현재 디렉토리를 의미한다.</p>
<h5 id="-1">..</h5>
<p>현재 디렉토리에서 상위 디렉토리를 의미한다.</p>
<h4 id="ctrl--c">ctrl + c</h4>
<p>잘못 눌러 명령이 나가지지 않는 경우, ctrl + c를 누르면 된다.</p>
<h4 id="ls">ls</h4>
<p>현재 디렉토리의 파일 목록을 표시해준다.</p>
<h4 id="ls--al">ls -al</h4>
<p>현재 디렉토리의 숨김 목록까지 표시해준다.</p>
<h4 id="ls-git">ls *.git</h4>
<p>확장자가 git인 목록을 표시해준다.
뒤에 확장자를 적으면 된다.</p>
<h4 id="rm-파일명">rm 파일명</h4>
<p>Remove의 약자로 해당 파일을 지워준다. </p>
<h4 id="mkdir">mkdir</h4>
<p>새로운 디렉토리를 생성한다.</p>
<p><a href="https://m.hanbit.co.kr/channel/category/category_view.html?cms_code=CMS6390061632">더 많은 명령어들이 있다.</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[.jar]]></title>
            <link>https://velog.io/@haha_hoho/.jar</link>
            <guid>https://velog.io/@haha_hoho/.jar</guid>
            <pubDate>Mon, 15 Apr 2024 00:34:18 GMT</pubDate>
            <description><![CDATA[<p>아예 다른 프로젝트에 원하는 클래스를 사용하고 싶을 때 java를 압축하여 다른 프로젝트에 넘길 수 있다.</p>
<h2 id="같은-프로젝트에서">같은 프로젝트에서</h2>
<p><strong>같은 프로젝트이면서 다른 패키지인 경우,</strong>
import를 사용하여 (C#은 using) 해당 클래스를 가져오면된다.</p>
<pre><code class="language-java">package my;

import pack1.ClassPre2;

public class ExWhile {
    public static void main(String[] args) {

        ClassPre2 cp2 = new ClassPre2();
    }
}</code></pre>
<p>대부분 idle을 사용하면 자동으로 import를 사용해 가져와준다.</p>
<h1 id="java-프로젝트-압축--jar">java 프로젝트 압축 &gt; .jar</h1>
<p>같은 프로젝트 내에서 클래스를 사용할 수 있지만 다른 프로젝트 공간에서 다른 프로젝트에서 사용한 클래스를 사용하고 싶은 경우도 있다.</p>
<p>위의 경우와 같이 import를 사용하면 좋겠지만 그렇게 사용하지 못하고
<strong>다른 프로젝트를 압축한 후 사용할 프로젝트 공간에 build해주면 된다.</strong></p>
<h2 id="다른-프로젝트에서">다른 프로젝트에서</h2>
<h3 id="방법">방법</h3>
<h4 id="1-압축하기">1. 압축하기</h4>
<h5 id="1-내보내길-원하는-파일을-선택한-후-우클릭--export를-선택한다">1) 내보내길 원하는 파일을 선택한 후 우클릭 &gt; Export를 선택한다.</h5>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/abad6182-ca6a-47a3-993d-d50becf1a97b/image.png" alt=""></p>
<h5 id="2-java-선택후-jar-file-선택하기">2) java 선택후 JAR file 선택하기</h5>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/2eee1f50-e92f-4505-89f9-4b938132e4d4/image.png" alt=""></p>
<h5 id="3-압축하기-원하는-파일을-선택한-후-압축-파일을-경로를-선택한다">3) 압축하기 원하는 파일을 선택한 후, 압축 파일을 경로를 선택한다.</h5>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/bcec663c-ca8c-4130-8026-cbd6d499627d/image.png" alt=""></p>
<h4 id="2build-path">2.Build path</h4>
<p>압축한 파일을 작업할 클래스를 가져올 것입니다.</p>
<h5 id="1-build-path--configure-build-path">1) Build Path &gt; Configure Build Path...</h5>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/c40b3824-c5e8-401e-a7de-8be09005256c/image.png" alt=""></p>
<h5 id="2-add-external-jars">2) Add External JARs...</h5>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/775f7319-dad9-46e9-b3e6-49acc6b9dcaf/image.png" alt=""></p>
<p>위에서 압축시킨 경로로 가서 해당 jar을 가져온다.</p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/f006d81b-8883-4c0e-930e-0c26e43d1573/image.png" alt=""></p>
<p>그러면 위와 같이 우유병이 생긴다. <code>Apply and Close</code>를 눌러준다.</p>
<p>이후 <code>package Explorer</code> 창에서 파일의 구조를 확인해보자.
<img src="https://velog.velcdn.com/images/haha_hoho/post/b4bacad2-22ce-41a9-8ec0-776b78225d1b/image.png" alt=""></p>
<p>Referenced Libraries가 생겼다. 토글을 내려보면 안에 압축을 푼 파일이 보인다.</p>
<p>이제 import를 사용해서 불러주면 클래스 사용이 가능하다.</p>
<hr>
<h4 id="cmd창에서-먼저-압축푸는법">cmd창에서 먼저 압축푸는법</h4>
<p>java의 압축파일인 jar는 명령 프롬프트를 사용해 압축을 풀어줄 수 있다.</p>
<p><strong>java -jar 파일명.jar</strong></p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/89c78156-a305-4372-a7be-6796f2076cef/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[기본 윈도우 창만들기 (Java 내장 클래스Frame 사용)_ has a(포함) / is a(상속)]]></title>
            <link>https://velog.io/@haha_hoho/%EA%B8%B0%EB%B3%B8-%EC%9C%88%EB%8F%84%EC%9A%B0-%EC%B0%BD%EB%A7%8C%EB%93%A4%EA%B8%B0-Java-%EB%82%B4%EC%9E%A5-%ED%81%B4%EB%9E%98%EC%8A%A4Frame-%EC%82%AC%EC%9A%A9-has-a%ED%8F%AC%ED%95%A8-is-a%EC%83%81%EC%86%8D</link>
            <guid>https://velog.io/@haha_hoho/%EA%B8%B0%EB%B3%B8-%EC%9C%88%EB%8F%84%EC%9A%B0-%EC%B0%BD%EB%A7%8C%EB%93%A4%EA%B8%B0-Java-%EB%82%B4%EC%9E%A5-%ED%81%B4%EB%9E%98%EC%8A%A4Frame-%EC%82%AC%EC%9A%A9-has-a%ED%8F%AC%ED%95%A8-is-a%EC%83%81%EC%86%8D</guid>
            <pubDate>Fri, 12 Apr 2024 09:04:50 GMT</pubDate>
            <description><![CDATA[<p>java가 제공해주는 클래스에는 Frame이라는 클래스가 존재한다.
Frame의 클래스에는 다양한 메서드가 있는데
우리가 할 일은 창을 띄우는 것이다.</p>
<h1 id="클래스간의-관계">클래스간의 관계</h1>
<p>다른 클래스를 가져오는 방법은 크게 2가지가 있는데.
하나는 포함 관계이고 다른 방법은 상속 관계이다.</p>
<p>Frame은 atw클래스에 위치해있다.</p>
<h2 id="문서-찾기">문서 찾기</h2>
<p><strong>Frame관련 문서 공식문서(api)</strong>를 찾아보자.
공식적인 문서를 찾는게 가장 먼저되어야한다.</p>
<ol>
<li>구글 &#39;java (버전) api&#39;검색한다.
java 17을 사용하고 있기에 <strong>&#39;java 17 api&#39;</strong> 검색하자.
<img src="https://velog.velcdn.com/images/haha_hoho/post/83e28ce8-5a46-4e21-aad2-ea43cd448e9b/image.png" alt="">
<a href="https://docs.oracle.com/en/java/javase/17/docs/api/">Oracle에서 공식적으로 제공 하는 문서</a>들이 제공한다.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/179807ea-71d9-4b2b-b05b-a744dffceb28/image.png" alt=""></p>
<p>API는 java에서 이미 만들어 놓은 다양한 클래스, 메서드, 인터페이스 등의 집합입니다. 개발자들이 프로그램을 개발에 도움을 주는 기능들을 모아놓았습니다.
또 어떻게 사용해야하는지 방법이나 관련 설명이 쭉 서술되어 있습니다.</p>
<ol start="2">
<li>Frame클래스를 찾아 들어갑니다. 위에서 말했듯 atw클래스 하위에 있음을 알고 있습니다.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/78f32569-a688-4c76-8532-0b4f55e52398/image.png" alt="">
<img src="https://velog.velcdn.com/images/haha_hoho/post/a7676152-279a-4bee-87d4-b6f1b3812c64/image.png" alt="">
위의 사진과 같이 java.desktop &gt; java.awt 를 찾을 수 있습니다. java.awt안에 들어가면 Frame을 찾을 수 있습니다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/6aa26ee2-8292-463e-a9ea-ef783fee7233/image.png" alt=""></p>
<ol start="3">
<li>해당 설명이 적혀있다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/6159db7b-ae57-4d21-bb9a-0f236008a393/image.png" alt="">
자신의 코드에 사용할 클래스를 찾아 import해서 찾아야한다.
우리는 Constructor을 보면 Frame(String title)을 사용할 것이기에 찾아서 참고하며 사용하면 된다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/32f12ec9-5f39-45f9-90eb-c149552b889e/image.png" alt=""></li>
</ol>
<h1 id="포함has-a">포함(has a)</h1>
<p><strong>포함 관계는 약한 결합이다.</strong>
우선 포함관계로 윈도우 창을 띄어보자.
클래스의 멤버로 클래스를 참조 변수를 선언하는 것이다.</p>
<pre><code class="language-java">package pack2;

import java.awt.Frame;

//java가 지원하는 Frame 클래스로 창띄우기 : 포함관계
public class MyFrame {
    private String title = &quot;포함관계&quot;;
    private Frame frame;

    public MyFrame() {
        frame = new Frame(title); //객체를 만들었다.
    }

    private void display() {
        frame.setSize(500, 300);//윈도우 창 크기
        frame.setLocation(200, 150); //왼쪽 상단에서부터 윈도우창 위치
        frame.setVisible(true);

    }


    public static void main(String[] args) {
        MyFrame frame = new MyFrame();
        frame1.display();

    }

}</code></pre>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/00811fe2-e913-4627-845d-73899059db0e/image.png" alt=""></p>
<p>실행하면 아래와 같이 윈도우 창이뜬다. 물론 다른 코드 작업을 안했기에 내용은 없다.
윈도우창은 사진과 같이 메뉴창도 나오고 <code>최대화</code> 혹은 <code>최소화</code>도 가능하다.
하지만, 닫기는 불가하다. 개발자의 취향대로 작동되도록 코드에 포함시키지 않은 것같다.</p>
<h1 id="상속is-a">상속(is a)</h1>
<p>상속은 extends로 부모 클래스를 가져오는 것이다.
(private를 제외한)부모의 메서드나 변수를 사용할 수 있다.</p>
<ul>
<li>중요한 특징<ul>
<li>상속은 <strong>단일 상속</strong>만 허용한다.</li>
<li>2개의 부모 클래스(상위 클래스)를 받을 수 없다.</li>
</ul>
</li>
</ul>
<pre><code class="language-java">package pack3;

import java.awt.Frame;

public class MyFrame2 extends Frame{

    public MyFrame2() {
        super(&quot;상속 사용&quot;);
    }

    void display() {
        setSize(500,300); //현재 클래스setSize를 정의하지 않았으면 super키워드는 필요없다.
        //super.setSize(500,300);
        setLocation(200,150);
        setVisible(true);
    }

    public static void main(String[] args) {
//      [1번 방법]
//        MyFrame2 frame = new MyFrame2();
//        frame.display();
//        [2번 방법]
        new MyFrame2().display();

    }

}
</code></pre>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/c9d9f1c8-e63f-4316-a2f5-a41a0eb23171/image.png" alt=""></p>
<p>상속은 포함관계와 비교하면 강한 결합을 가진다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[오류 해결]No enclosing instance of type 클래스명 is accessible. Must qualify the allocation with an 
enclosing instance of type 클래스명]]></title>
            <link>https://velog.io/@haha_hoho/%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0No-enclosing-instance-of-type-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%AA%85-is-accessible.-Must-qualify-the-allocation-with-an-enclosing-instance-of-type-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%AA%85</link>
            <guid>https://velog.io/@haha_hoho/%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0No-enclosing-instance-of-type-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%AA%85-is-accessible.-Must-qualify-the-allocation-with-an-enclosing-instance-of-type-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%AA%85</guid>
            <pubDate>Thu, 11 Apr 2024 11:21:15 GMT</pubDate>
            <description><![CDATA[<p>프로그래머스 코딩테스트를 풀어보는 중 오류가 발생했다.</p>
<hr>
<p><strong>전개</strong>
문제를 풀다가 찍어보고 싶다는 생각이 들었다.
프로그래머스가 익숙하지 않아서 그런지 중간 중간 코드실행이 안되길래,
내가 사용하는 idel 환경에서 풀어보고자 했다.
문제는 풀었는데 main메서드에서 찍어보려고 하니, 오류가 발생한 것이다!</p>
<hr>
<h3 id="프로그래머스-문제">프로그래머스 문제</h3>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/11069411-6d9e-4a26-8f2d-c230f41e8345/image.png" alt=""></p>
<hr>
<h3 id="문제-발생">문제 발생</h3>
<p>문제는 충분히 통과할 수 있었지만 예상치 못한 곳에서 오류가 발생했다.
main 메서드에서 new로 생성하려했는데 계속 오류가 발생했다. </p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/be4e0618-b4e0-4473-a631-4d71db8bca41/image.png" alt=""></p>
<h4 id="오류-메시지">오류 메시지</h4>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/02895478-6a0f-4160-9762-0759c9130822/image.png" alt=""></p>
<p>Multiple markers at this line
    - The value of the local variable solu is not used
    - No enclosing instance of type diceGame is accessible. Must qualify the allocation with an enclosing instance of type 
diceGame (e.g. x.new A() where x is an instance of diceGame).</p>
<h3 id="해결-방법">해결 방법</h3>
<p>&quot;나는 컴퓨터다.&quot;라는 생각으로 컴퓨터의 흐름을 따라가야한다.</p>
<ol>
<li>위의 해당 문제 풀이가 들어가는 클래스는 Solution 클래스이다.</li>
<li>메인 메서드가 실행되는 클래스는 diceGame이다.</li>
</ol>
<p>두번째 단계에서 문제는 해결할 수 있었다.(생각보다 어이없는 실수였다.)
<strong>클래스의 }의 위치 문제였다.</strong>
메인 메서드가 있는 클래스가 Solution 클래스까지 담고 있었다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/23ce3df8-5db7-493f-8e7f-3fb27def9a8c/image.png" alt="">
이렇게 이동시켜주면 오류가 해결된다.!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[생성자에서 다른 생성자 부르기 this() (vs this. 과의 차이)]]></title>
            <link>https://velog.io/@haha_hoho/%EC%83%9D%EC%84%B1%EC%9E%90%EC%97%90%EC%84%9C-%EB%8B%A4%EB%A5%B8-%EC%83%9D%EC%84%B1%EC%9E%90-%EB%B6%80%EB%A5%B4%EA%B8%B0-this-vs-this.-%EA%B3%BC%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@haha_hoho/%EC%83%9D%EC%84%B1%EC%9E%90%EC%97%90%EC%84%9C-%EB%8B%A4%EB%A5%B8-%EC%83%9D%EC%84%B1%EC%9E%90-%EB%B6%80%EB%A5%B4%EA%B8%B0-this-vs-this.-%EA%B3%BC%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Fri, 05 Apr 2024 00:25:02 GMT</pubDate>
            <description><![CDATA[<p><a href="https://velog.io/@haha_hoho/gettersetter-%EC%82%AC%EC%9A%A9%EC%9D%98-%EC%9D%B4%EC%9C%A0%EB%A5%BC-%EC%BD%94%EB%93%9C%EB%A5%BC-%ED%86%B5%ED%95%B4-%EC%9D%B4%ED%95%B4%ED%95%98%EC%9E%90-this.-%EA%B9%8C%EC%A7%80">getter와 setter_ this.까지 정리</a></p>
<p>지난 캡슐화를 배우면서 접근제한자와 getter와 setter를 배우면서 this.까지 정리했다.
오늘은 같은 단어인 this이지만 사용이 다른, this()를 알아보고자 한다.
this()를 구분하기 위해서는 this.을 먼저 이해하고 오는게 좋다.</p>
<p><strong>전혀 다른 키워드이다.</strong></p>
<hr>
<p>지난 코드를 생각해보면,
초기화하는 방법 중 setter를 이용할때 this.을 사용했다.
Java는 setter메서드에서 매개변수로 가져온 값을 대입할 때, 같은 변수명을 사용하면 따로 구분하지 못한다.
지역변수의 변수를 그냥 사용한다. 즉, 자기 자신에게 값을 대입한다.</p>
<p>이렇게 되면 setter로 들어온 값은 멤버 변수에 초기화 되지 않고 지역 변수에만 저장되고 끝난다. <strong>heap메모리</strong>에서 머물다가 끝난다.
멤버 변수(클래스의 전역변수)에 초기화를 시키면 static메모리 저장된다.</p>
<hr>
<p><strong>생성자안에 다른 생성자를 포함시킬 수 없을까?</strong>
메서드 안에 메서드는 호출할 수 있다.
생성자는 특별한(?) 메서드이기에 특정 생성자 안에서 다른 생성자를 부르는 로직이 필요하다? 이때 <strong>this()</strong> 가 쓰인다.</p>
<h1 id="this">this()</h1>
<pre><code class="language-java">package my;

public class TestThisMethod {

    public TestThisMethod() {
        //기본 생성자
    }

    public TestThisMethod(int i) {
        System.out.println(&quot;1번째 기능이 들어가있다.&quot;+i);
    }

    public TestThisMethod(String st) {
        System.out.println(&quot;2번째 기능이 들어가있다.&quot;+st);
    }
}</code></pre>
<p>다른 생성자로 호출되면 각 기능을 하고싶지만, <strong>기본 생성자가 호출되면 다른 생성자의 기능도 함께 진행되면 좋겠다</strong>면 기본 생성자에 다른 생성자를 불러야한다.
일반 메서드처럼 직접 불러야하나? </p>
<pre><code class="language-java">package my;

public class TestThisMethod {

    public TestThisMethod() {
        TestThisMethod(2);
        haha(); //생성자가 일반 메서드를 불러오는 방법
        System.out.println(&quot;기본생성자입니다.&quot;);
    }

    public TestThisMethod(int i) {
        System.out.println(&quot;1번째 기능이 들어가있다.&quot;+i);
    }

    public TestThisMethod(String st) {
        System.out.println(&quot;2번째 기능이 들어가있다.&quot;+st);
    }
}
</code></pre>
<blockquote>
<p>오류 메시지
The method TestThisMethod(int) is undefined for the type TestThisMethod</p>
</blockquote>
<p>이런 메서드는 없다는 오류메시지가 뜬다. 물론 new키워드를 사용하고 불러낼 수 있다.</p>
<pre><code class="language-java">public TestThisMethod() {
        new TestThisMethod(2);
        System.out.println(&quot;기본생성자입니다.&quot;);
    }
</code></pre>
<p><strong>new 키워드를 사용해 객체를 생성한다는 것은 동적메모리(heap)에 저장된다는 의미이다.</strong>
new키워드를 사용하지 않고 생성자를 부르는 키워드가 있다.
<strong>this</strong>를 사용해서 다른 생성자의 기능을 넣어야겠다.</p>
<h3 id="this-사용-코드">this 사용 코드</h3>
<pre><code class="language-java">package my;

public class TestThisMethod {

    public TestThisMethod() {
        this(0);
        System.out.println(&quot;기본생성자입니다.&quot;);
    }

    public TestThisMethod(int i) {
        System.out.println(&quot;1번째 기능이 들어가있다.&quot;+i);
    }

    public TestThisMethod(String st) {
        System.out.println(&quot;2번째 기능이 들어가있다.&quot;+st);
    }

    private void haha() {
        System.out.println(&quot;hhhhaaaa&quot;);
    }
}</code></pre>
<p>위와 같이 this();를 사용하면된다.</p>
<h4 id="생성자가-여러개면-this로-어떻게-구분하나요">생성자가 여러개면 this로 어떻게 구분하나요?</h4>
<p>this()는 인자로 구분합니다.
생성자 오버로딩을 했으니, <strong>인자의 타입이나 개수, 순서로 구분</strong>한다.</p>
<h4 id="this를-사용하니-컴파일-에러가-발생합니다">this를 사용하니 컴파일 에러가 발생합니다.</h4>
<blockquote>
<p><strong>오류</strong>
Constructor call must be the first statement in a constructor</p>
</blockquote>
<p>생성자는 다른 생성자를 호출할 수 있지만 다른 행위보다 가장 먼저 생성해야합니다.
그렇지 않으면 위의 에러 메시지와 함께 컴파일 에러가 나타납니다.</p>
<h2 id="정리">정리</h2>
<p>this() 키워드를 알아봤다. this.와 키워드만 같지 아예 다른 기능을 한다는 것을 알 수 있다.</p>
<ul>
<li><p>this.
메서드에서 멤버변수를 지정할때 사용하는 키워드이다.
<code>this.변수명</code> 은 &quot;나는 멤버 변수야!&quot;라는 의미이다.</p>
</li>
<li><p>this()</p>
</li>
</ul>
<p>A생성자를 실행할때 B생성자의 기능 사용이 필수인 경우,
A생성자 안에 호출을 시키는 것이다.
당연하지만 다른 곳에서 B생성자를 호출한다면, B생성자는 따로 실행 할 수도 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[getter/setter 사용의 이유를 코드를 통해 이해하자 (+this. 까지)]]></title>
            <link>https://velog.io/@haha_hoho/gettersetter-%EC%82%AC%EC%9A%A9%EC%9D%98-%EC%9D%B4%EC%9C%A0%EB%A5%BC-%EC%BD%94%EB%93%9C%EB%A5%BC-%ED%86%B5%ED%95%B4-%EC%9D%B4%ED%95%B4%ED%95%98%EC%9E%90-this.-%EA%B9%8C%EC%A7%80</link>
            <guid>https://velog.io/@haha_hoho/gettersetter-%EC%82%AC%EC%9A%A9%EC%9D%98-%EC%9D%B4%EC%9C%A0%EB%A5%BC-%EC%BD%94%EB%93%9C%EB%A5%BC-%ED%86%B5%ED%95%B4-%EC%9D%B4%ED%95%B4%ED%95%98%EC%9E%90-this.-%EA%B9%8C%EC%A7%80</guid>
            <pubDate>Thu, 04 Apr 2024 00:30:45 GMT</pubDate>
            <description><![CDATA[<p>캡슐화(Encapsulation)에 대해 정리를 하면서 <strong>접근 제한자</strong>에 대해 공부했다. 접근 제한자, 4가지에 대해 배웠다. 
<a href="https://velog.io/@haha_hoho/OOP-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%8A%B9%EC%A7%95-%EC%BA%A1%EC%8A%90%ED%99%94Encapsulation">OOP 캡슐화 정리</a></p>
<p>가장 마지막에 등장한 pravite는 <strong>같은 클래스가 아닌 곳에서는 찾을 수 없는데</strong> 이는 은닉화와 관력이 있었다.</p>
<blockquote>
<p><strong>정보 은닉</strong>
객체 내부의 정보에 대하여 외부에서 임의로 변경하거나 접근하는 것을 막는 행위</p>
</blockquote>
<p>자동차 클래스가 있다고 가정해보자.</p>
<pre><code class="language-java">package pack1;

public class Car {
    private int speed;
    public String irum;
    private double weight;

    public Car() { //생성자 (초기화 담당)
        irum = &quot;홍길동&quot;;
        speed = 10;
    }

    public void showData() { //메서드
        System.out.println(&quot;이름은 &quot; + irum + &quot;, 속도는 &quot; + speed);
    }
}</code></pre>
<p>위와 같은 코드에서 speed는 같은 클래스 안에서만 사용이 가능하다. 즉, 다른 클래스에서 정의한 main 메서드에서는 speed라는 멤버 변수는 찾을 수 없다.</p>
<p><strong>main 메서드</strong>를 만들고 실행해보자.</p>
<pre><code class="language-java">package pack1;

public class CarMain {

    public static void main(String[] args) {
        //Car 객체를 만들기
        Car tom = new Car();
        //tom 객체변수를 통해 speed 불러오기
        System.out.println(tom.speed);
    }
}</code></pre>
<blockquote>
<p><strong>에러 메시지</strong>
Unresolved compilation problem: 
    The field Car.speed is not visible</p>
</blockquote>
<p>private로 은닉화된 변수 speed는 다른 클래스인 main변수에서 사용할 수 없다.</p>
<h4 id="외부-클래스에서-private-불러오는-방법">외부 클래스에서 private 불러오는 방법</h4>
<p>private 멤버 변수를 사용하는 public한 클래스를 만들어 주면 된다!</p>
<pre><code class="language-java">package pack1;

public class Car {
    private int speed;
    public String irum;
    private double weight;

    public Car() { //생성자 (초기화 담당)
        irum = &quot;홍길동&quot;;
        speed = 10;
    }

    public void showData() { //메서드
        System.out.println(&quot;이름은 &quot; + irum + &quot;, 속도는 &quot; + speed);
    }

    public void abcd(int s) { // private 멤버값을 외부에서 접근하기 위한 메소드
        speed = s;
    }
}
</code></pre>
<p>이렇게 Car 클래스에 public을 사용하여 speed에 접근할 수 있도록 해주면 main에서 가져올 수 있다.</p>
<pre><code class="language-java">package pack1;

public class CarMain {

    public static void main(String[] args) {
        //Car 객체를 만들기
        Car tom = new Car();
        tom.abcd(20);
        tom.showData();
    }
}</code></pre>
<blockquote>
<p><strong>결과</strong>
이름은 홍길동, 속도는 20</p>
</blockquote>
<p>이렇게 외부에서 접근할때, 비밀번호를 줄 수 있다.</p>
<h3 id="getter와-setter">getter와 setter</h3>
<p>위처럼 그냥 클래스에서 메서드를 만들 수 있다. 하지만 이렇게 된다면 일관성있는 값에 접근하는 메서드명을 지칭하는데 혼란을 줄 수도 있다.</p>
<p>이에 따라 특정 값을 메서드를 통해 접근하여 값을 넣어줄때(setter)와 값을 받아올때(getter)일관된 메서드명을 사용할 것이다.</p>
<p>getter와 setter를 사용한다면 <strong>자동화</strong>가 된다다는 장점이 있다.</p>
<p>(우리는 위에 정의한 abcd 메서드를 getter와 setter로 정의할 것이다.)</p>
<pre><code class="language-java">package pack1;

public class Car {
    private int speed;
    public String irum;
    private double weight;

    public Car() { //생성자 (초기화 담당)
        irum = &quot;홍길동&quot;;
        speed = 10;
    }

    public void showData() { //메서드
        System.out.println(&quot;이름은 &quot; + irum + &quot;, 속도는 &quot; + speed);
    }

//    public void abcd(int s) { // private 멤버값을 외부에서 접근하기 위한 메소드
//        speed = s;
//    }

    public void setSpeed(int s) {
        speed = s; 
        //return; //생략 가능
    }
    public int getSpeed() { 
        return speed;
    }

}
</code></pre>
<p>위와 같이</p>
<ul>
<li><p><strong>setter</strong>
setter는 초기화를 시켜주는 메서드이다.
main에서 받은 변수를 멤버변수에 초기화를 시켜주는 역할을 한다.
setter는 보통 변환해주는 클래스가 아니기에 void로 선언이된다. 때문에 return을 생략할 수 있다.</p>
</li>
<li><p><strong>getter</strong>
초기화된 멤버변수 speed가 getter을 통해서 main으로 나간다.</p>
</li>
</ul>
<hr>
<h2 id="this">this.</h2>
<p>바로 위의 코드를 보면 <strong>setter의 매개변수</strong>를 보자.
<code>int s</code>를 파라미터로 가져온다. 이 파라미터는 <strong>해당 메서드에서 내에서만 사용되는 지역변수</strong>이다.
즉, 이 변수 자체는 클래스의 멤버 변수와는 관계가 없다.</p>
<pre><code class="language-java">public void setSpeed(int s) {
        speed = s; 
        //return; //생략 가능
}</code></pre>
<p>위의 값에서 setter 코드만 가져왔다.
이 경우 Java는 speed 변수를 setSpeed 메서드 내부에서 찾는다. 내부에 원하는 변수를 찾지 못하면 <strong>그 다음으로 멤버 변수를 찾는다.</strong></p>
<p>하지만 개발자 잘 알아보기 위해서 매개변수를 해당 클래스의 멤버 변수와 동일한 명칭을 사용할때가 있다.</p>
<pre><code class="language-java">public void setSpeed(int speed) {
        speed = speed; 
}</code></pre>
<p>이와 같은 경우, java는 내부에 speed라는 변수가 있기에 자기 자신에게 값을 넣는 것이다. Java는 구분하기 못하는 것!
즉, 멤버 변수에 초기화기 되지 않는다.
이때 사용하는 키워드가 <strong>this.</strong>이다.
Java에게 this.변수명으로 붙은 변수는 <strong>멤버변수</strong>라고 알려주는 것이다.</p>
<pre><code class="language-java">public void setSpeed(int speed) {
        this.speed = speed; 
}</code></pre>
<p>java가 this를 구분해서 값을 멤버변수에 초기화한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[OOP 객체지향 특징 -캡슐화(Encapsulation)]]></title>
            <link>https://velog.io/@haha_hoho/OOP-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%8A%B9%EC%A7%95-%EC%BA%A1%EC%8A%90%ED%99%94Encapsulation</link>
            <guid>https://velog.io/@haha_hoho/OOP-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%8A%B9%EC%A7%95-%EC%BA%A1%EC%8A%90%ED%99%94Encapsulation</guid>
            <pubDate>Wed, 03 Apr 2024 10:37:56 GMT</pubDate>
            <description><![CDATA[<p>이전 OOP를 공부하면서 각각 조금 더 깊게 공부해야한다는 생각이 들었다.
<a href="https://velog.io/@haha_hoho/Java-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8DOOP%EC%9D%B4%EB%9E%80">OOP의 전반적인 정리</a></p>
<p>위의 글은 전반적인 내용을 다루고 있어서 각 중요한 개념들을 자세하게 코드로 알아보려고 한다.</p>
<h1 id="캡슐화">캡슐화</h1>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/faf24aa7-9745-4114-953f-9c7575944593/image.png" alt=""></p>
<p>상세한 내부 구현을 숨기므로써 의도와 목적에 맞게 프로그램이 상호작용하도록 유도하는 역할을 한다.</p>
<ul>
<li>객체에 선언된 내부 변수와 메소드를 하나로 패키징하는 특징을 가지고 있다.</li>
</ul>
<p>-묶는다는 것은 응집도와 독립성을 높이므로 </p>
<h1 id="캡슐화-1">캡슐화</h1>
<p>Java는 접근제어자를 통해 객체의 캡슐화 및 은닉화를 할 수 있다.</p>
<pre><code class="language-java">package my;

public class Jjanggu {
    public String name;
    protected int age;
    String zip;
    private int weight;
}
</code></pre>
<ul>
<li>public : 같은 프로젝트 내에서 유효하다. 패키지가 달라도 된다.</li>
<li>protected : 같은 프로젝트 내에서 유효하다. 패키지가 다른 경우, 자식 클래스만 유효</li>
<li>default : 같은 패키지 내에서만 유효</li>
<li>private : 현재 클래스 내에서만 유효, 다른 클래스에서는 참조 불가</li>
</ul>
<h2 id="public">public</h2>
<p>개방적인 접근제어자이다. 특별한 제약 조건없이 같은 프로젝트 안에 있는 클래스 어디에서나 호출이 가능하다.</p>
<pre><code class="language-java">package my;

public class Jjanggu {
    public String name;
}</code></pre>
<p>즉, public 접근 제어자는 외부 접근이 가능하기 때문에 정보 은닉이 이뤄지지 않는다.</p>
<h2 id="protected">protected</h2>
<p>상속과 연관이 있는 접근 제어자이다.(상속을 배우고 난 후 배우는 것이 좋다.)
해당 객체를 상속받은 객체만 접근할 수 있다.
자식 객체에서 부모 객체의 protected 객체에 접근할 수 있다.</p>
<p><strong>부모 객체의 멤버 변수와 메소드의 접근 권한의 일부를 승계받는다.</strong></p>
<h2 id="default">default</h2>
<p>별다른 접근제어자를 <strong>지정하지 않았다면 default 제어자가 기본으로 적용</strong>된다.</p>
<pre><code class="language-java">package my;

public class Jjanggu {
    default String zip;
    // String zip;
}</code></pre>
<p>동일한 패키지에 내에서만 사용이 가능하다. 위의 코드에서 설명하자면 package명이 my인 곳에서는 사용이 가능하다.
패키지가 다를 경우, 불러오는 곳에서 해당 변수, 메서드를 찾지 못한다.</p>
<h2 id="private">private</h2>
<p>오로지 같은 클래스 내부에서만 사용이 가능하다.
다른 클래스에서 private로 선언된 변수, 메서드는 찾지 못한다. 은닉화를 위한 접근제어자이다.
내부의 메소드나 변수를 은닉하여 프로그램 의도에 맞춰 흘러가도록 유도한다.</p>
<pre><code class="language-java">package my;

public class Jjanggu {
    private int weight;
}</code></pre>
<h3 id="정리">정리</h3>
<p>객체가 의미를 갖기 위해서는 의도에 적절한 접근제어자를 사용하여 개방/폐쇄가 필요하다.</p>
<p>사용자들이 프로그램을 사용할때 개발자 혹은 해당 이해관계자가 원하는 방식대로 흘러가게 해줄 수 있으며 *<em>직접 접근을 막아 *</em>데이터 손실을 방지할 수 있다.</p>
<hr>
<p>private로 변수와 메서드를 은닉화하여 보안성을 높였지만 아무 변화를 주지않고 사용한다면 final을 키워드를 사용하면 된다.</p>
<p>조금 더 생각해보면 &#39;접근 제어자&#39;이다.
private로 선언된 변수와 메서드는 제약을 조금 강하게 주는 것이다.</p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/f93ed941-9892-4006-b96f-bbd3d225fa33/image.png" alt="">
개발자를 자동차 정비사로 비유하곤 한다.</p>
<p>정비사(개발자)들이 모든 부품(메서드)을 직접 만들줄 알아야 정비를 할 수있는 것은 아니다.(부품을 잘 이해하고 있다면 당연히 시너지 효과는 클 것이다.)</p>
<p>정비사는 자동차 &#39;부품&#39;의 기능과 종류를 알고 있으면 된다. 각 독립된 부품을 가지고 하나의 자동차(객체)를 만들면 된다.
<strong>부품을 사용하는 방법을 알고 사용할 수 있어야한다.</strong>
하지만 엔진이 망가져서 자동차가 퍼졌다면 엔진과 관련된 부품부터 확인하며 엔진을 교체하면 된다.</p>
<p>즉, 내부의 동작은 안으로 숨기고 사용자에겐 그 부품의 사용법만 노출하면 된다.</p>
<p>보안성을 높이면서 생성자를 호출하며 사용할 수 있는 <strong>&#39;적절한&#39;</strong> 방법이 <strong>getter와 setter</strong>이다.</p>
<p>getter와 setter를 설명하려니 this.까지 설명해야해서 다음 포스팅에서 진행하겠다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Class를 선언할때 메모리 구조를 살펴보기]]></title>
            <link>https://velog.io/@haha_hoho/Class%EB%A5%BC-%EC%84%A0%EC%96%B8%ED%95%A0%EB%95%8C-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0%EB%A5%BC-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@haha_hoho/Class%EB%A5%BC-%EC%84%A0%EC%96%B8%ED%95%A0%EB%95%8C-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0%EB%A5%BC-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Wed, 03 Apr 2024 00:27:41 GMT</pubDate>
            <description><![CDATA[<h1 id="운영체제-속-메모리-구조">운영체제 속 메모리 구조</h1>
<p>운영체제(OS)에서 자바 프로그램이 실행될때,OS가 JVM에 할당하는 메모리 영역이 있다.</p>
<h2 id="1-기억장치-storage-device">1. 기억장치 (storage Device)</h2>
<p>기억 장치에 대해 깊게 알아보는 글이 아니기에
대표적인 기억장치들을 언급하고 나가려고 한다.</p>
<h3 id="0-cpu">0) CPU</h3>
<p>기억 장치는 아니다..
<strong>중앙처리장치</strong>라고 하며 컴퓨터의 두뇌와 같은 장치를 말한다. 데이터의 연산 해석, 처리하는 역할을 맡는다.</p>
<h3 id="1-보조기억장치hddhard-disk-drive">1) 보조기억장치(HDD;hard disk drive..)</h3>
<p>자료를 저장하는 대용량 기억장치이다.
<strong>보조 기억 장치는 전원이 나가도 휘발성으로 사라지지 않고 영구적으로 저장</strong>할 수 있는 기억 장치이다.</p>
<h3 id="2-주기억-장치ram-or-rom-">2) 주기억 장치(RAM or ROM ..)</h3>
<p>중앙처리장치인 CPU와 직접적으로 정보를 교환하는 기억장치이다.
전원이이 꺼지면 저장된 데이터가 손실된다.</p>
<h3 id="3-캐시기억장치">3) 캐시기억장치</h3>
<p>CPU랑 주기억장치 간의 속도 차이를 매우기 위해 사용되는 메모리</p>
<h3 id="4레지스터">4)레지스터</h3>
<p>CPU의 처리와 관련해서 일시적으로 데이터를 저장하는 저장 장치이다. <strong>CPU 내</strong>의 임시 저장 장치이다.</p>
<hr>
<h1 id="프로그램-실행">프로그램 실행</h1>
<p>참조) <a href="https://mundol-colynn.tistory.com/171">https://mundol-colynn.tistory.com/171</a>
<img src="https://velog.velcdn.com/images/haha_hoho/post/4cb37f37-b1a5-46c6-b35c-9c22e9f7d7ed/image.png" alt=""></p>
<h2 id="진행-과정">/<em>진행 과정</em>/</h2>
<p>Java 프로그램이 보조 기억장치에 있다가 실행을 하면 주기억 장치(RAM)로 올라오게 된다. 이를 <strong>로드한다</strong>라고 말하며 이 과정을 <strong>로딩(roding)</strong>이다.</p>
<p>로딩이 완료되면 프로그램은 <strong>실행중인 상태</strong>가 되는데 이를 <strong>프로세스</strong>라고 한다.
이 프로세스들을 관리하는 <strong>장치를 프로세서(CPU)라고 한다.</strong></p>
<hr>
<blockquote>
<p>Java 순서</p>
</blockquote>
<p>1) 개발자가 코딩을 하면 .java 파일이 생성된다.
2) .java파일이 자바 컴파일러(javac)에 의해 .class파일(바이트 코드)로 컴파일된다.
3) .class 파일은 JVM의 ClassLoader에 의해 Runtime data Area에 로드된다.
4) Runtime Data Area에 로드된 파일(.class)들은 Execution Engine을 통해 해석된다.
5) 해석된 .class는 <strong>Runtime data Area의 각 영역에 배치되어 수행</strong>한다.</p>
<hr>
<p>프로그램이 실행되면 JVM은 OS로부터 메모리를 할당받고, 메모리를 목적에 따라 여러 영역으로 나누어 관리한다.</p>
<h1 id="메모리-영역">메모리 영역</h1>
<h2 id="runtime-data-area">Runtime data Area</h2>
<p>Runtime data Area영역은 크게 5가지로 구분된다.
그 중 Java의 메모리 구조에 가장 많이 언급되는 3(4; 코드영역)가지 영역을 정리하려고 한다.</p>
<p><strong>Heap영역, Stack영역, Static 영역(Method,Data영역(+BSS)), Code 영역</strong>
<img src="https://velog.velcdn.com/images/haha_hoho/post/636eb6bf-cec9-4b61-af39-278358633afe/image.png" alt=""></p>
<h3 id="static-영역method--databss">Static 영역(Method / data(+BSS))</h3>
<p>[File Size와 관계가 있다.]
JVM이 동작해서 클래스가 로딩될 때 생성되는 영역이다.
즉, main이 끝날때까지 살아있는 메모리 영역이다.
&#39;static&#39;키워드가 붙은 변수나 메서드의 정보를 저장하는 영역이다.</p>
<ul>
<li>전역 변수 (global)와 정적 변수가 할당된다.</li>
<li>초기화된 데이터가 할당되는 영역이다.</li>
<li>BSS(Block Stated Symbol)영역은 초기화가 안된 데이터가 할당되는 영역이다.</li>
</ul>
<h3 id="heap-영역">Heap 영역</h3>
<p>[Runtime 결정]
사용자가 원하는 시점에서 변수를 할당하고 해제할 수 있는 영역이다.
즉, 프로그래머가 할당 혹은 해제하는 메모리 영역이다.
데이터의 크기가 확실하지 않을 경우 사용하며
<strong>낮은 주소(0x00000000)에서 높은 주소(0xffffffff)의 방향</strong>으로 할당한다.
동적 변수가 할당된다.
Java의 GC(가비지 컬렉터)가 일하는 공간이다.</p>
<p><strong>유일하게 런타임때 크기가 결정된다.</strong></p>
<h3 id="stack-영역">Stack 영역</h3>
<p>[컴파일 시간 결정]
<strong>스택 영역에 저장되는 함수의 호출 정보를 스택 프레임(Stack frame)</strong>이라고 한다.
함수의 호출이 완료되면 소멸(해제)된다.
함수 호출시 생성되는 지역변수(local)와 매개변수 (Argument)가 저장되는 영역이다.
CPU에 의해서 관리되고 최적화되어 속도가 매우 빠르다.
<strong>컴파일 타임에 크기가 결정된다.</strong>
컴파일 타임에 결정되기 댸문에 무한히 할당할 수 없다.(메모리 크기 제한)</p>
<h3 id="code-영역">Code 영역</h3>
<p>컴파일이 완료된 코드(0,1)가 존재하는 영역이다.
컴파일 타임에 결정된다.
CPU가 작업을 수행할 때, code영역의 명령어를 가져가 실행된다.</p>
<p>왜 코드 영역이 런타임이 아닌 컴파일 단계에 결정이 되는 것일까?
프로그램이 실행중에는 코드의 내용이 변하면 안되고 변할 일도 없다.
만약 런타임에 결정된다면 프로그램은 실행중에 메모리를 동적으로 할당해야한다.
이렇게 동적할당을 하면 instruction(명령어들의 집합)을 찾는데 시간이 소요된다.
즉, 메모리에 코드를 통째로 올려 놓는 것이 실행을 더 효율적으로 만든다.</p>
<h2 id="overflow">overflow</h2>
<p>의미 그대로 넘쳐흐른다는 의미를 가지고 있다.</p>
<ul>
<li><p>Stack Overflow 
Stack 영역이 정해진 크기를 넘어가면 에러가 발생한다.</p>
</li>
<li><p>Heap Overflow
heap 영역이 정해진 크기를 넘어가 stack 영역을 넘어가면 heap overflow가 발생한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java, 객체지향 프로그래밍(OOP)이란?]]></title>
            <link>https://velog.io/@haha_hoho/Java-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8DOOP%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@haha_hoho/Java-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8DOOP%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Tue, 02 Apr 2024 09:13:25 GMT</pubDate>
            <description><![CDATA[<h1 id="자바는-클래스로-시작해서-클래스로-끝난다">자바는 클래스로 시작해서 클래스로 끝난다.</h1>
<p>Java는 대표적인 객체지향 프로그밍 언어이다.</p>
<p>객체지향 프로그래밍 언어는 OOP로 명칭하는데 Object - Oriented Programming의 약자이다.</p>
<p>객체지향 프로그래밍의 가장 큰 특징은 자원의 재활용성이다.
프로그램의 <strong>작은 문제들을 해결할 수 있는 기능이 있는 객체를 만든 뒤, 객체들끼리 상호작용</strong>으로 서술하는 방식으로 문제를 해결하는 <strong>상향식(bottom-up)프로그램 작성 기법</strong>이다.</p>
<p>조금 쉽게 풀어보자면, 객체지향 프로그래밍이란 <strong>조립</strong>이라고 생각할 수 있다.
작은 레고(객체)를 적재적소하게 사용하여 프로그램을 만드는 것이다.</p>
<hr>
<h3 id="용어-정리">용어 정리</h3>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/52927e30-be96-44e5-9605-0791eea722ce/image.png" alt=""></p>
<ul>
<li>클래스(Class)
클래스는 객체를 생성하기 위한 <strong>설계도</strong>이다. 객체의 <strong>속성(상태)</strong>이나 <strong>행위(method)</strong> 를 적어두는 것이다.
흔히 붕어빵 틀, 공장으로 많이 비유한다. 자주 사용하는 기능을 클래스로 만들어 놓는다면
의미없는 코드 반복을 하지 않는다.
main아닌 클래스는 &quot;기능 창고&quot;라고 생각하자.<blockquote>
<p>클래스를 왜 만드나요?
무엇보다 강조되어야하는 것은 <strong>자원의 재활용성</strong>이다.</p>
</blockquote>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/3d7c41c6-ff16-4a7d-a83d-d4d2cb7b7cf9/image.png" alt=""></p>
<ul>
<li><p>객체
클래스를 통해 생성된 인스턴스, 실체이다. 메서드와 변수의 묶음이라 표현할 수있다.
실제 프로그램 내에서 메모리에 항당된 상태를 가지고 있으며 실행 가능한 어떤 것을 말한다.</p>
</li>
<li><p><em>클래스에서 정의된 필드와 동일한 속성(상태)와 메서드(행위)를 가진다.*</em></p>
</li>
<li><p>인스턴스
클래스로부터 생성된 객체를 의미하는데,
객체가 메모리에 할당되어 실제로 생성된 상태를 강조할때 사용한다. 해당 클래스와의 관계를 더욱 강조할 때 말한다.</p>
</li>
</ul>
<blockquote>
<p>용어 차이</p>
</blockquote>
<ul>
<li>객체는 클래스의 정의를 통해 메모리에 할당된 구체적인 실체이다.</li>
<li>인스턴스는 객체가 메모리에 할당되어 실제로 생성된 것을 강조할때 사용한다.</li>
</ul>
<ul>
<li><p>메서드
클래스 안에 구현된 행위에 대한 함수이다. 객체의 속성(move(), rightClick()..)을 정의해둔 묶음을 의미한다.
멤버 변수를 이용한다.</p>
</li>
<li><p>멤버변수
클래스의 속성, 특성(데이터)을 의미한다.</p>
</li>
</ul>
<hr>
<hr>
<h2 id="클래스-사용-예시-코드">클래스 사용 예시 코드</h2>
<p>[Ex1Car 클래스]</p>
<pre><code class="language-java">public class Ex1Car {
    int wheel;
    public String irum;

    public Ex1Car() {
        System.out.println(&quot;생성자: 객체 생성시 초기화를 담당. 1회 호출됨&quot;);
        wheel = 4;
    }
}</code></pre>
<p>[Main 클래스]</p>
<pre><code class="language-java">public class Ex1Main {
    public static void main(String[] args) {
    //자동차 객체를 만들고 싶다.
        Ex1Car car1 = new Ex1Car();
        System.out.println(&quot;바퀴 수: &quot;+car1.wheel);
    }
}</code></pre>
<blockquote>
<p>결과값
생성자: 객체 생성시 초기화를 담당. 1회 호출됨
바퀴 수: 4</p>
</blockquote>
<p>어플리케이션의 시작점은 main메서드이다.
위에서 잠시 언급했듯 main메서드가 있는 클래스가 아닌 클래스들은 기능 창고들이다. 스스로 run할 수 없다.</p>
<h3 id="클래스-생성자-constructer">클래스 생성자 (constructer)</h3>
<p>위의 코드 Ex1Car클래스를 살펴보면,
public Ex1Car(){ ... }라는 생성자가 있다.</p>
<h4 id="생성자란">생성자란?</h4>
<p>객체 생성시 <strong>초기화를 담당</strong>한다.
생성자는 <strong>클래스와 이름이 같고 반환값이 없다.</strong>
생성자가 없을 경우, java에서 자동으로 생성자를 만들어준다.
없어도 되는 것은 아니지만 생략이 가능하다.</p>
<h3 id="객체지향-4가지-특징">객체지향 4가지 특징</h3>
<h4 id="1-캡슐화">1. 캡슐화</h4>
<p>캡슐화의 가장 큰 장점은 <strong>정보은닉</strong>이다.
<strong>접근제어자를 통해 원하는 범위를 설정해 정보를 은닉하거나 공개</strong>할 수 있다.</p>
<ul>
<li><strong>public</strong> : 같은 프로젝트 내에서 유효하다. 패키지가 달라도 된다.</li>
<li><strong>protected</strong> : 같은 프로젝트 내에서 유효하다. 패키지가 다른 경우, 자식 클래스만 유효</li>
<li><strong>default</strong> : 같은 패키지 내에서만 유효</li>
<li><strong>private</strong> : 현재 클래스 내에서만 유효, 다른 클래스에서는 참조 불가</li>
</ul>
<h4 id="2-추상화">2. 추상화</h4>
<p>어떠한 클래스의 공통 자원들의 뼈대만을 나타내어(구현x) 상속받아 사용하는 기능이다.
<strong>abstract</strong> 예약어를 사용한다.
클래스 내부에 구현한 클래스로 클래스 내부에서만 사용하기 위해 선언한느 클래스이다.</p>
<h4 id="3-상속성">3. 상속성</h4>
<p><strong>부모 클래스의 특성과 기능을 자식 클래스에서 상속</strong>받아 사용할 수 있게 해주는 기능이다. 이를 통해 캡슐화를 유지하면서 클래스의 재사용성을 높여준다.</p>
<h4 id="4-다형성">4. 다형성</h4>
<p>하나의 함수가 상황에따라 다른 값을 return할 수 있도록 한다.
객체지향 프로그래밍의 꽃(유연성, 재활용성, 유지보수성의 기본)이라고 할 수 있는 특징이다.</p>
<ul>
<li><strong>오버라이딩</strong>
상속받은 기능을 자식 클래스에서 재변경하여 사용하는 방법
기존 것을 덮어버리는 개념이다.(상속의 개념이 기반)</li>
<li><strong>오버로딩</strong>
이름만 동일하고 매개변수의 개수를 다르게 받아 메서드를 다양하게 사용할 수 있게 하는 방법</li>
</ul>
<h2 id="객체-지향-프로그래밍의-장단점">객체 지향 프로그래밍의 장단점</h2>
<h3 id="장점">장점</h3>
<ul>
<li>코드의 재사용성</li>
<li>유지보수성</li>
<li>보안성</li>
<li>확장성<h3 id="단점">단점</h3>
</li>
<li>복잡성, 클래스 및 객체 관리 필요</li>
</ul>
<h2 id="객체-지향-설계-원칙solid">객체 지향 설계 원칙(SOLID)</h2>
<p>객체 지향에 관한 설계 원칙이 5가지가 있다.</p>
<h3 id="srpsingle-responsibility-principle-단일-책임-원칙">SRP(Single Responsibility Principle) 단일 책임 원칙</h3>
<p>클래스는 하나의 책임만 가져야하며, 그 책임(목적)을 변경하는 이유는 하나여야한다.</p>
<h3 id="ocpopenclosed-principle-개방폐쇄-원칙">OCP(Open/Closed Principle) 개방/폐쇄 원칙</h3>
<p>클래스, 모듈, 함수 등 확장에는 열려있어야하고, 수정에는 닫혀있어야 한다.
클래스를 수정해야한다면 그 클래스를 상속하여 수정한다.</p>
<h3 id="lspliskov-substitution-principle-리스코프-치환-원칙">LSP(Liskov Substitution Principle) 리스코프 치환 원칙</h3>
<p>하위 타입은 상위 타입을 대체할 수 있어야한다. 즉, 부모 클래스 객체를 대체하더라도 프로그램의 의미나 동작은 변하지 않아야 한다.</p>
<h3 id="ispinterfae-sefrefation-principle-인터페이스-분리-원칙">ISP(Interfae Sefrefation Principle) 인터페이스 분리 원칙</h3>
<p>클라이언트는 자신이 사용하지 않은 메서드에 의존 관계를 맺으면 안된다.</p>
<h3 id="dipdependency-inversion-principle-의존성-역전-원칙">DIP(Dependency Inversion Principle) 의존성 역전 원칙</h3>
<p>고수준 모듈은 저수준 모듈에 의존해서는 안되며, 두개 모두 추상화에 의존해야한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[이클립스 실행 에러]the eclipse executable launcher was unable to locate its companion shared libray]]></title>
            <link>https://velog.io/@haha_hoho/%EC%9D%B4%ED%81%B4%EB%A6%BD%EC%8A%A4-%EC%8B%A4%ED%96%89-%EC%97%90%EB%9F%ACthe-eclipse-executable-launcher-was-unable-to-locate-its-companion-shared-libray</link>
            <guid>https://velog.io/@haha_hoho/%EC%9D%B4%ED%81%B4%EB%A6%BD%EC%8A%A4-%EC%8B%A4%ED%96%89-%EC%97%90%EB%9F%ACthe-eclipse-executable-launcher-was-unable-to-locate-its-companion-shared-libray</guid>
            <pubDate>Mon, 01 Apr 2024 02:40:30 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/haha_hoho/post/b1a2d07c-990c-4dc8-94c1-9f55c459f0ea/image.png" alt=""></p>
<p>이클립스를 설치하고 바탕화면에서 eclipse를 바로 실행하기 위해
파일을 복사해서 붙여넣었더니, 위와 같은 오류가 떴다.</p>
<p><strong>해석 : 
Eclipse 실행 파일 런처에서 회사 공유 라이브러리를 찾을 수 없습니다</strong></p>
<blockquote>
<p>바탕화면에서 <strong>바로가기</strong>로 설정하면 문제는 해결된다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Scanner 클래스 사용자 입력값 버리는 법(.next()와 .nextLine() 차이)]]></title>
            <link>https://velog.io/@haha_hoho/Scanner-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%9E%85%EB%A0%A5%EA%B0%92-%EB%B2%84%EB%A6%AC%EB%8A%94-%EB%B2%95.next%EC%99%80-.nextLine-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@haha_hoho/Scanner-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%9E%85%EB%A0%A5%EA%B0%92-%EB%B2%84%EB%A6%AC%EB%8A%94-%EB%B2%95.next%EC%99%80-.nextLine-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Mon, 01 Apr 2024 01:39:37 GMT</pubDate>
            <description><![CDATA[<p>문제를 풀면서 Scanner 함수를 이용해 문제를 풀때,
사용자에게 받는 입력값이 2개 이상인 경우, 이전에 받은 입력값이 남아있어 원하는 프로그램이 돌아가지 않을때가 있다.</p>
<p>아래의 문제를 풀때도 같은 일이 있었다.</p>
<p><a href="https://velog.io/@haha_hoho/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%9E%90%EB%B0%94-%EC%9E%85%EB%AC%B8-%EB%AC%B8%EC%A0%9C-%EC%83%81%ED%92%88%EA%B5%AC%EB%A7%A4">https://velog.io/@haha_hoho/김영한의-자바-입문-문제-상품구매</a></p>
<p>위의 문제를 리뷰해보자.
scanner.nextInt();로 값을 받을때 사용자가 값을 입력하고 \n을 누르면
숫자만 변수에 들어가고 <strong>\n값이 남아서 다음 입력값에 그대로 \n만 들어가는 상황이 발생</strong>했다.
이 경우를 위해 문제에서는 <strong>scanner.nextLine();을 사용해서 입력값을 의도적으로 버렸다.</strong></p>
<h1 id="next-vs-nextline">.next() vs .nextLine()</h1>
<ul>
<li><p>.next() : 사용자 입력 갑에서 <strong>스페이스(\n)와 Enter</strong>를 인식해 문자열을 리턴한다.</p>
</li>
<li><p>.nextLint() : <strong>Enter를 인식</strong>하여 문자열을 리턴한다.</p>
</li>
</ul>
<h2 id="nextlint">.nextLint()</h2>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/f48d0947-d171-43ed-97ad-11640a53bd01/image.png" alt=""></p>
<p>이렇게 Enter만 인식해서 띄어쓰기가 가능하다.</p>
<h2 id="next">.next()</h2>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/728fc9d3-6ead-4560-bf53-f4bc4f51a923/image.png" alt=""></p>
<p>이렇게 공백을(\n)을 인식해서 띄어쓰기가 불가능하다.
즉, 공백이 나오기 전의 값만 인식한다.</p>
<p>중요한 것은 위의 문제처럼 <strong>사용자 입력값이 계속 살아있는가?</strong>이다.</p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/52b220bb-947b-424e-b987-6cd3059ef41b/image.png" alt=""></p>
<p><strong>사용자 입력값이 살아있다.</strong>
.nextInt()나 .nextDouble()처럼 사용자 입력값이 살아있으니,
값의 오류가 나지 않도록 nextLine()을 사용해서 입력값을 한번 버려주자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[김영한의 자바 입문 - 문제 ) 상품구매 ]]></title>
            <link>https://velog.io/@haha_hoho/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%9E%90%EB%B0%94-%EC%9E%85%EB%AC%B8-%EB%AC%B8%EC%A0%9C-%EC%83%81%ED%92%88%EA%B5%AC%EB%A7%A4</link>
            <guid>https://velog.io/@haha_hoho/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%9E%90%EB%B0%94-%EC%9E%85%EB%AC%B8-%EB%AC%B8%EC%A0%9C-%EC%83%81%ED%92%88%EA%B5%AC%EB%A7%A4</guid>
            <pubDate>Thu, 28 Mar 2024 05:25:53 GMT</pubDate>
            <description><![CDATA[<h1 id="문제">문제</h1>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/dc13e1ef-6435-4d38-bba5-258ff559039a/image.png" alt=""></p>
<h2 id="실행결과">실행결과</h2>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/96aef73f-5cfd-4fc6-a046-591eea6d5113/image.png" alt=""></p>
<p>나는 switch문을 사용했다.
번호가 정확히 정해져 있기에 case로 나누면 가독성이 올라가기 때문이다.</p>
<h3 id="풀이">풀이</h3>
<h4 id="while-안에-swicth문-풀이">while 안에 swicth문 풀이</h4>
<p>완성 풀이</p>
<pre><code class="language-java">package scanner.ex;
//상품구매
import java.util.Scanner;

public class ScannerWhileEx4 {
    public static void main(String[] args) {
        boolean run = true;
        Scanner scanner = new Scanner(System.in);
        int total = 0;

        while (run) {
            System.out.println(&quot;1:상품입력, 2:결제, 3:프로그램 종료&quot;);
            int option = scanner.nextInt();
            scanner.nextLine();//\n값 버려주기

            switch (option) {
                case 1 -&gt; {
                    System.out.print(&quot;상품명을 입력하세요: &quot;);
                    String name = scanner.nextLine();
                    System.out.print(&quot;상품 가격을 입력하세요: &quot;);
                    int price = scanner.nextInt();
                    System.out.print(&quot;상품 수량을 입력하세요: &quot;);
                    int amount = scanner.nextInt();

                    total += price * amount;
                    System.out.println(&quot;상품명:&quot;+name+&quot; 가격:&quot;+price+&quot; 수량:&quot;+amount+&quot; 합계:&quot;+price*amount);
                }
                case 2 -&gt; {
                    System.out.println(&quot;총비용: &quot; + total);
                    total = 0;
                }
                case 3 -&gt; {
                    System.out.println(&quot;프로그램을 종료합니다.&quot;);
                    run = false;
                    //break;
                }default -&gt; System.out.println(&quot;잘못 입력했습니다.&quot;);
            }
        }
    }
}
</code></pre>
<p>계속 풀리지 않는 문제가 발생했다. switch문은 break; 로 빠져나왔지만 while문을 빠져나오지 않는다는 점이다. break;가 안먹히는 상황이다.</p>
<h4 id="while-문안에-switch문이-있을-경우-발생하는-문제">while 문안에 switch문이 있을 경우, 발생하는 문제</h4>
<p>사용자가 종료를 원할때까지 계속 돌아가야하기 때문에 while문으로 전체 코드를 감싸고 있다. switch문을 사용했는데, <strong>break;문이 안먹히더라</strong>...ㅎ
case문만 빠져나가고 while문은 계속됐다.</p>
<blockquote>
<p>처음 시도한 문제의 코드</p>
</blockquote>
<pre><code class="language-java">package scanner.ex;
//상품구매
import java.util.Scanner;

public class ScannerWhileEx4 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int total = 0;

        while (true) {
            System.out.println(&quot;1:상품입력, 2:결제, 3:프로그램 종료&quot;);
            int option = scanner.nextInt();
            scanner.nextLine();//\n값 버려주기

            switch (option) {
                case 1 -&gt; {
                    System.out.print(&quot;상품명을 입력하세요: &quot;);
                    String name = scanner.nextLine();
                    System.out.print(&quot;상품 가격을 입력하세요: &quot;);
                    int price = scanner.nextInt();
                    System.out.print(&quot;상품 수량을 입력하세요: &quot;);
                    int amount = scanner.nextInt();

                    total += price * amount;
                    System.out.println(&quot;상품명:&quot;+name+&quot; 가격:&quot;+price+&quot; 수량:&quot;+amount+&quot; 합계:&quot;+price*amount);
                }
                case 2 -&gt; {
                    System.out.println(&quot;총비용: &quot; + total);
                    total = 0;
                }
                case 3 -&gt; {
                    System.out.println(&quot;프로그램을 종료합니다.&quot;);
                    break;
                }default -&gt; System.out.println(&quot;잘못 입력했습니다.&quot;);
            }
        }
    }
}
</code></pre>
<blockquote>
<p>(결과)
1:상품입력, 2:결제, 3:프로그램 종료
3
프로그램을 종료합니다.
1:상품입력, 2:결제, 3:프로그램 종료</p>
</blockquote>
<p>이때 든 생각은 2가지였다.</p>
<ol>
<li>사용자 입력값을 전역으로 남기고 while문에 조건을 걸어야하는가?</li>
<li>switch문에서 사용자가 3을입력하면 while문을 false로 만드는 방법이없을까?</li>
</ol>
<p>물론, 나는 아직 코린이라 저렇게 생각을 코드로 호로록 만들지는 못하지만 1번 방법은 김영한 선생님께서 의미없이 전역변수를 만들면 불필요한 메모리가 사용되고 계속 신경쓰면서 코드를 짜야하니, 필요한게 아니면 안만드는게 좋다고 하셨다.!</p>
<p>개인적으로도 2번 방법이 궁금했다. 이게 가능하다면 다음부터 써먹을 수 있지 않을까?하는 날먹..?느낌이라서 찾아보고 싶었다.</p>
<p>(구글링 구글링)</p>
<p>그렇다. 이미 들어온 switch문에서 while의 조건을 바꾸는건 쉽지 않다.
while에 영향을 미치기 위해서는 <strong>전역변수</strong>를 사용해야하는건 어쩔 수 없나보다!</p>
<blockquote>
<p>정리 정리! </p>
</blockquote>
<ol>
<li>전역에 boolean run = true; 라고 설정하고 </li>
<li>while (run)으로 조건을 달아준다. </li>
<li>switch case 3에서 run = false;를 설정해준다.</li>
</ol>
<h4 id="if문-풀이">if문 풀이</h4>
<p>김영한 선생님은 if문으로 문제를 푸셨기에 나도 if문으로 문제를 풀어봤다.</p>
<pre><code class="language-java">package scanner.ex;
//상품구매
import java.util.Scanner;

public class ScannerWhileEx4 {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
        int total = 0;

        while (true) {
            System.out.println(&quot;1:상품입력, 2:결제, 3:프로그램 종료&quot;);
            int option = scanner.nextInt();
            scanner.nextLine();//\n값 버려주기

            if (option == 1) {
                System.out.print(&quot;상품명을 입력하세요: &quot;);
                String name = scanner.nextLine();
                System.out.print(&quot;상품 가격을 입력하세요: &quot;);
                int price = scanner.nextInt();
                System.out.print(&quot;상품 수량을 입력하세요: &quot;);
                int amount = scanner.nextInt();

                total += price * amount;
                System.out.println(&quot;상품명:&quot; + name + &quot; 가격:&quot; + price + &quot; 수량:&quot; + amount + &quot; 합계:&quot; + price * amount);
            } else if (option == 2) {
                System.out.println(&quot;총비용: &quot; + total);
                total = 0;
            } else if (option == 3) {
                System.out.println(&quot;프로그램을 종료합니다.&quot;);
                break;
            } else {
                System.out.println(&quot;잘못 입력했습니다.&quot;);
            }
        }
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[JAVA 정수형 데이터 타입과 ASCII코드(16진수)]]></title>
            <link>https://velog.io/@haha_hoho/JAVA-%EC%A0%95%EC%88%98%ED%98%95-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EA%B3%BC-ASCII%EC%BD%94%EB%93%9C</link>
            <guid>https://velog.io/@haha_hoho/JAVA-%EC%A0%95%EC%88%98%ED%98%95-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EA%B3%BC-ASCII%EC%BD%94%EB%93%9C</guid>
            <pubDate>Wed, 27 Mar 2024 09:26:06 GMT</pubDate>
            <description><![CDATA[<h1 id="데이터-타입">데이터 타입</h1>
<p>java는 변수를 입력할때 변수 타입을 함께 선언합니다.
java는 타입에 맞춰 메모리를 할당합니다.</p>
<h2 id="데이터의-크기">데이터의 크기</h2>
<p>대단한 일을 척척 진행하지만, 사실 이 안에서는 1,0으로 기록하고 데이터를 주고 받습니다. 스위치를 생각하면 됩니다.</p>
<p>가장 <strong>작은 단위인 bit</strong>는 <strong>0 또는 1로만 표현</strong>할 수 있습니다.</p>
<p>단 2가지의 표현법을 가진 <strong>bit를 8개로 묶어놓은 단위를 byte</strong>라고 합니다.
1byte는 8bit의 공간을 의미합니다.</p>
<h3 id="정수형-데이터-타입과-메모리">정수형 데이터 타입과 메모리</h3>
<p>정수형 데이터 타입은 <strong>byte , short, int, long</strong>이 있습니다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/c0d6e7a5-2071-4b72-8105-1bb02338f82d/image.png" alt=""></p>
<p>코드로 더 정확하게 알아보자.
<strong>대전제 : 정수가 들어오면 int형으로 자동 형변환이 된다.</strong></p>
<h4 id="byte-타입">byte 타입</h4>
<pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        byte i = 1;
        System.out.println(i);
        System.out.println(Byte.MAX_VALUE);
        System.out.println(Byte.MIN_VALUE);
    }
}</code></pre>
<blockquote>
<p>결과
1
127
-128</p>
</blockquote>
<h4 id="short-타입">short 타입</h4>
<pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        short i = 12312;
        System.out.println(i);
        System.out.println(&quot;short타입 최대값: &quot;+Short.MAX_VALUE);
        System.out.println(&quot;short타입 최소값: &quot;+Short.MIN_VALUE);
    }
}</code></pre>
<blockquote>
<p>결과
12312
short타입 최대값: 32767
short타입 최소값: -32768</p>
</blockquote>
<h4 id="int-타입">int 타입</h4>
<pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        int i = 12312;
        System.out.println(i);
        System.out.println(&quot;int타입 최대값: &quot;+Integer.MAX_VALUE);
        System.out.println(&quot;int타입 최소값: &quot;+Integer.MIN_VALUE);
    }
}</code></pre>
<blockquote>
<p>결과
12312
int타입 최대값: 2147483647
int타입 최소값: -2147483648</p>
</blockquote>
<p>보통 정수타입은 int형을 많이 사용한다.
때문에 대략적으로 int형의 범위를 알아야하는데 <strong><em>+-21억</em></strong>이다.</p>
<h4 id="long-타입">long 타입</h4>
<pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        long i = 12312L;
        System.out.println(i);
        System.out.println(&quot;long타입 최대값: &quot;+Long.MAX_VALUE);
        System.out.println(&quot;long타입 최소값: &quot;+Long.MIN_VALUE);
    }
}</code></pre>
<blockquote>
<p>결과
12312
long타입 최대값: 9223372036854775807
long타입 최소값: -9223372036854775808</p>
</blockquote>
<h2 id="ascii-코드">ASCII 코드</h2>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/ddf80d76-1fba-4f6a-b099-abbffdb6083f/image.png" alt=""></p>
<p>ASCII코드를 알려면 2진수와 16진수를 알고 넘어가야 한다.</p>
<h3 id="2진수-16진수-변환">2진수 16진수 변환</h3>
<p>일반적으로 10진수를 사용하지만 컴퓨터 안에서는 2진수 혹은 16진수를 많이 사용합니다.
위에서 말했듯 컴퓨터의 가장 작은 단위인 bit는 스위치 전원과 같이 0과 1로만 표현할 수 있습니다.
bit하면 <strong>경우의 수</strong>를 먼저 떠올리자.</p>
<ul>
<li>4bit(16)의 자리
1bit : 1
2bit : 2
3bit : 4
4bit : 8
예를 들어 1001 &gt; 8+0+0+1 =9 이다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/7c8edfd7-7f18-42ca-b9a9-8817363fea8e/image.png" alt=""></p>
<blockquote>
<p><strong>4bit는 16진수의 한자리 수이다.</strong></p>
</blockquote>
<p>컴퓨터에 16진수로 된 표현들을 보면 0xf 이런 식으로 되어있다.
(참고) 앞쪽에 0x라고 붙인 것은 프리픽스라고 하는데 16진수를 나타내는 것이다.</p>
<p>우리는 이제 반대로 유추할 수 있다.
<strong>0xf4</strong>
16진수를 표현했구나 &gt; 2자리 수이네? &gt; 8bit를 사용하는 것 같다.
16진수 표기가 사용되는 예로는 색상(RGB),메모리 값, 컴퓨터 하드웨어 주소 표현 등이 있습니다.</p>
<p>다시 위에 아스키 코드표를 보자.
<img src="https://velog.velcdn.com/images/haha_hoho/post/ddf80d76-1fba-4f6a-b099-abbffdb6083f/image.png" alt=""></p>
<p>컴퓨터/통신 장비에서 문자나 기호를 숫자로 표현하는 표준화된 방법을 뜻한다.
표준화는 <strong>일관성 유지</strong>를 위해서 등장한다.
표준을 만들어 어느 제조회사에서든 같은 표현 문자를 보내는 것입니다.</p>
<h3 id="코드로-아스키-코드-10진수로-출력">코드로 아스키 코드 10진수로 출력</h3>
<pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        System.out.println(&quot;문자형 char &quot;);

        char c = &#39;A&#39;;
        System.out.println(&quot;char의 10진수: &quot;+(int)c);
    }
}</code></pre>
<blockquote>
<p>결과
문자형 char 
char의 10진수 :65</p>
</blockquote>
<h3 id="10진수로-아스키-코드-출력">10진수로 아스키 코드 출력</h3>
<pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        System.out.println(&quot;하이&quot;  +(char)13 + &quot;하이&quot;);
    }
}</code></pre>
<blockquote>
<p>결과
하이
하이</p>
</blockquote>
<h3 id="16진수-10진수로-변환">16진수 10진수로 변환</h3>
<pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        System.out.println(&quot;-&quot;+0xf4+ &quot;-&quot;);
    }
}</code></pre>
<blockquote>
<p>결과
-244-</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바란?]]></title>
            <link>https://velog.io/@haha_hoho/%EC%9E%90%EB%B0%94%EB%9E%80</link>
            <guid>https://velog.io/@haha_hoho/%EC%9E%90%EB%B0%94%EB%9E%80</guid>
            <pubDate>Wed, 20 Mar 2024 02:06:13 GMT</pubDate>
            <description><![CDATA[<h1 id="자바의-표준-스펙">자바의 표준 스펙</h1>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/08fd2fa7-ba7b-43f2-96c5-b48bfeae41e4/image.png" alt=""></p>
<blockquote>
<p><strong>자바 표준 스펙</strong></p>
</blockquote>
<ul>
<li>자바의 설계도이며 문서이다.</li>
<li>스펙을 기반으로 여러 회사에서 실제 작동하는 자바를 만든다.(오라클 open JDK, Eclipse ..)</li>
<li>자바 표준 스펙은 자바 커뮤니티 프로세스(JCP)를 통해 관리된다.</li>
</ul>
<blockquote>
<p><strong>다양한 자바 구현</strong></p>
</blockquote>
<ul>
<li>여러 회사에서 스펙을 맞춰 식제 작동하는 자바 프로그램을 개발한다.</li>
<li>장단점이 각각 존재한다. 예) Amazon Corretto는 AWS에 최적화 되어있다.</li>
<li>각 회사들은 대부분 다양한 OS에서 작동하는 버전의 자바도 함께 제공한다.</li>
</ul>
<p><strong><em>자바 구현들은 모두 표준 스펙을 맞도록 개발되어 있다.</em></strong></p>
<h1 id="컴파일-실행">컴파일 실행</h1>
<p>자바 프로그램은 컴파일과 실행 단계를 거친다.</p>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/521b9138-6687-4b71-ad51-d0eeedd24422/image.png" alt=""></p>
<ol>
<li><p>java가 컴파일러를 사용해서 소스 코드를 컴파일한다.</p>
<ul>
<li>.java &gt; .class 파일이 생성된다.</li>
<li>자바 소스 코드를 바이트 코드로 변환하며 자바 가상 머신에서 더 빠르게 실행될 수 있게 최적화하고 문법 오류도 검출한다.</li>
</ul>
</li>
<li><p>자바프로그램을 실행한다.</p>
<ul>
<li>java라는 프로그램을 사용한다.</li>
<li>자바 가상 머신(JVM)이 실행되면서 프로그램이 작동한다.
(JVM이 .class파일을 읽어서 실행한다.)</li>
</ul>
</li>
</ol>
<h1 id="ide와-자바">IDE와 자바</h1>
<h2 id="인텔리-제이intellij를-통한-자바">인텔리 제이(intellij)를 통한 자바</h2>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/76c4408f-b407-4773-86dc-3b285da94ebb/image.png" alt=""></p>
<ul>
<li>인텔리제이는 내부에 자바를 편리하게 설치하고 관리할 수 있는 기능을 제공한다.</li>
<li>인텔리제이를 통해 자바를 편리하게 다운로드 받고 실행할 수 있다. (OS를 직접 설치해도 된다.)</li>
</ul>
<h2 id="intellij를-통한-자바-컴파일-실행-과정">intellij를 통한 자바 컴파일, 실행 과정</h2>
<p>위의 컴파일 과정들을 intellij에서 자동으로 해준다.</p>
<h3 id="컴파일">컴파일</h3>
<p>자바 코드를 컴파일하려면 javac 프로그램을 직접 사용해야하는데, 인텔리제이가 자바 코드를 실행할 때 이 과정을 자동으로 처리해준다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/072d45ac-5154-4b3f-b6f5-f929914872bf/image.png" alt="">
소스코드로 보이지만, 파일명을 자세히 보면 .class라는 것을 알 수 있다.
원래 컴파일된 파일은 숫자로 보여 사람이 읽을 수 없게 보인다.
(위의 사진에서 .class파일인데 읽을 수있는것은 인텔리제이가 디컴파일해서 그렇다.)
<img src="https://velog.velcdn.com/images/haha_hoho/post/4aa47211-4198-480c-be17-0c053983f511/image.png" alt=""></p>
<h3 id="실행">실행</h3>
<p>자바를 실행하려면 java라는 프로그램을 사용해야한다.
이때 컴파일된 .class 파일을 지정해주면 된다. (이때 확장자는 제외되고 실행된다.)</p>
<p>인텔리제이에서는 자바 코드를 실행하면 컴파일과 실행을 모두 한번에 처리한다.
인텔리제이 덕분에 매우 편리하게 자바 프로그램을 개발하고, 학습할 수 있다.</p>
<h1 id="자바와-운영체제-독립성">자바와 운영체제 독립성</h1>
<p>일반적인 프로그램은 각잔 운영체제에 맞는 명령어들로 구성되어 있기때문에 해당 명령어는 다른 OS와 호환되지 않는다.
Window 프로그램 &gt; Window 운영체제에서만 돌아감</p>
<p>java는 모든 OS에서 실행할 수 있다.
자바 개발자는 특정 OS에 맞춰 개발하지 않아도 된다. 자바 개발자는 자바에만 맞춰 개발하면된다. 컴파일된 자바 파일은 모든 자바 환경에서 실행할 수 있다.</p>
<h2 id="자바-개발과-운영-환경">자바 개발과 운영 환경</h2>
<p> <img src="https://velog.velcdn.com/images/haha_hoho/post/ba3fee7c-ca4f-47ad-9215-cbcc91945429/image.png" alt=""></p>
<blockquote>
<p>자바의 운영체제 독립성 덕분에 각각의환경에 맞춰 자바를 설치하는 것이 가능하다. </p>
</blockquote>
<h1 id="gcgarbage-collection">GC(Garbage Collection)</h1>
<p>Java에는 특별한 메모리 관리 기법이 있는데 바로, 가비지 컬렉션(Garbage collection)이다.
C와 C++같은 언어에서는 개발자가 직접 메모리를 할당하고 해제하는 방식을 사용했다.
물론 이 방식이 효율적일 수 있어도 메모리 누수나 해제되지 않은 메모리에 대한 접근 등의 문제를 일으킬 수 있는 위험성도 내포하고 있다.</p>
<h2 id="가비지-컬렉션garbage-collection">가비지 컬렉션(Garbage collection)</h2>
<p>자동으로 메모리를 관리를 해주는 부분으로 프로그램이 동적으로 할당한 메모리 중 필요없어진 부분을 자동으로 해제하는 프로세스를 말한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MVC와 템플릿 엔진]]></title>
            <link>https://velog.io/@haha_hoho/MVC%EC%99%80-%ED%85%9C%ED%94%8C%EB%A6%BF-%EC%97%94%EC%A7%84</link>
            <guid>https://velog.io/@haha_hoho/MVC%EC%99%80-%ED%85%9C%ED%94%8C%EB%A6%BF-%EC%97%94%EC%A7%84</guid>
            <pubDate>Sat, 09 Mar 2024 14:27:54 GMT</pubDate>
            <description><![CDATA[<h1 id="mvc구조">MVC구조</h1>
<blockquote>
<p>코드</p>
</blockquote>
<pre><code class="language-html">&lt;!DOCTYPE HTML&gt;
&lt;html xmlns:th=&quot;http://www.thymeleaf.org&quot;&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;hello &#39; +${name}&quot;&gt; hello! empty&lt;!--타임리프 장점:서버없이 열수 있음--&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-java">package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class Hellocontroller {

    /*웹 브라우저 주소 전달값 (http://localhost:8080/hello-mvc)*/
    @GetMapping(&quot;hello-mvc&quot;)
    public String helloMVC(@RequestParam(&quot;name&quot;) String name, Model model){
        model.addAttribute(&quot;name&quot;,name);
        return &quot;hello-template&quot;;
        /*return 값인 html 파일을 찾아간다.*/
    }
}</code></pre>
<h2 id="requestparam">RequestParam</h2>
<p>이번에는 RequestParam 어노테이션을 사용했다.
@RequestParam을 사용하게 되면 url에서 &quot;?&quot;이후에 key=value 형식으로 값을 줄 수있다.
<img src="https://velog.velcdn.com/images/haha_hoho/post/87c437f5-3a86-400b-8e45-b6ad23ee4023/image.png" alt="">
코드를 보면 name이라는 key에 spring이라는 값을 넣어 요청하는 것이다.</p>
<h1 id="전체-진행과정">전체 진행과정</h1>
<p><img src="https://velog.velcdn.com/images/haha_hoho/post/a126999f-d837-4592-8a1c-406721c2fba7/image.png" alt=""></p>
<blockquote>
<p>과정</p>
</blockquote>
<ol>
<li>웹 브라우저에서 localhost:8080/hello-mvc 주소를 <strong>톰켓</strong>에게 넘긴다.</li>
<li>내장 톰켓 서버는 <strong>스프링 컨테이너</strong>에서 helloController에 맵핑이 되어있는 것을 찾는다.</li>
<li>이때 return값을 hello-template으로 돌려주고 model에 데이터를 저장해서 넣어준다. (name:spring)</li>
<li>화면과 관련된 viewResolver(veiw를 찾아주고 연결)가 templates/hello-template.html을 찾아서 Thymeleaf 템플릿 엔진에 처리하게 넘긴다.</li>
<li>동적인 작업, 즉 변환을 시킨 HTML 파일을 웹 브라우저에 넘긴다.</li>
</ol>
]]></description>
        </item>
    </channel>
</rss>