<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>kimmin_aaa.log</title>
        <link>https://velog.io/</link>
        <description>천천이 꾸준히</description>
        <lastBuildDate>Thu, 08 Jan 2026 08:09:03 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>kimmin_aaa.log</title>
            <url>https://velog.velcdn.com/images/kimmin_ah/profile/92d6008b-8b64-487c-9490-45331235826b/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. kimmin_aaa.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/kimmin_ah" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[프로그래머스 - 문자열 내 p와 y의 개수
]]></title>
            <link>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%82%B4-p%EC%99%80-y%EC%9D%98-%EA%B0%9C%EC%88%98</link>
            <guid>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%82%B4-p%EC%99%80-y%EC%9D%98-%EA%B0%9C%EC%88%98</guid>
            <pubDate>Thu, 08 Jan 2026 08:09:03 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡문제 설명
대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 &#39;p&#39;의 개수와 &#39;y&#39;의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. &#39;p&#39;, &#39;y&#39; 모두 하나도 없는 경우는 항상 True를 리턴합니다. 단, 개수를 비교할 때 대문자와 소문자는 구별하지 않습니다.
예를 들어 s가 &quot;pPoooyY&quot;면 true를 return하고 &quot;Pyy&quot;라면 false를 return합니다.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<p>문자열 s의 길이 : 50 이하의 자연수
문자열 s는 알파벳으로만 이루어져 있습니다.</p>
<br/>
<br/>


<h3 id="🧾제출한-코드">🧾제출한 코드</h3>
<pre><code>class Solution {
    boolean solution(String s) {
        s = s.toLowerCase(); // 대소문자 통일함

        int pCount = 0;
        int yCount = 0;

        for (char c : s.toCharArray()) {
            if (c == &#39;p&#39;) pCount++;
            else if (c == &#39;y&#39;) yCount++;
        }

        return pCount == yCount;
    }
}</code></pre><p>대소문자 구분 안 하니까 소문자로 변환한 뒤 p, y 개수만 세서 비교하면 끝이다.
toLowerCase() 메서드는 문자열 s 안에 있는 모든 알파벳을 소문자로 바꿔서 새로운 문자열을 만들어준다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 -각도기]]></title>
            <link>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B0%81%EB%8F%84%EA%B8%B0</link>
            <guid>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B0%81%EB%8F%84%EA%B8%B0</guid>
            <pubDate>Fri, 04 Apr 2025 08:00:05 GMT</pubDate>
            <description><![CDATA[<br/>


<blockquote>
<p>💡문제 설명
각에서 0도 초과 90도 미만은 예각, 90도는 직각, 90도 초과 180도 미만은 둔각 180도는 평각으로 분류합니다. 각 angle이 매개변수로 주어질 때 예각일 때 1, 직각일 때 2, 둔각일 때 3, 평각일 때 4를 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<br/>

<h4 id="예를들어">예를들어</h4>
<ul>
<li><p>주어진 angle : <code>70</code>
result 값 : <code>1</code></p>
</li>
<li><p>주어진 angle : <code>91</code>
result 값 : <code>3</code></p>
</li>
<li><p>주어진 angle : <code>180</code>
result 값 : <code>4</code></p>
</li>
</ul>
<p><br/><br/></p>
<h3 id="🧾제출한-코드">🧾제출한 코드</h3>
<pre><code class="language-java">
class Solution {
    public int solution(int angle) {
        int answer = 0;

        if (angle &lt; 90) {
            answer = 1; 
        } else if (angle == 90) {
            answer = 2; 
        } else if (angle &lt; 180) {
            answer = 3; 
        } else {
            answer = 4; 
        }

        return answer;
    }
} </code></pre>
<p><br/><br/></p>
<h3 id="🔨개선한-코드">🔨개선한 코드</h3>
<pre><code class="language-java">//개선한 코드 

if (angle &lt; 1 || angle &gt; 180) {
    throw new IllegalArgumentException(&quot;각도는 1 이상 180 이하만.&quot;);
}

return answer;</code></pre>
<p>입력값 angle은 1 이상 180 이하의 정수일 것으로 문제에 암시돼어 있지만  예상치 못한 값이 들어올 수도 있기 때문에 → 입력 유효성 검사를 추가해주는 게 좋다.
<code>IllegalArgumentException</code>은 자바에서는 메서드 인자(파라미터)가 허용된 범위를 벗어났을 때 이 예외를 자주 사용한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코테 풀고 기록하자]]></title>
            <link>https://velog.io/@kimmin_ah/%EC%BD%94%ED%85%8C-%ED%92%80%EA%B3%A0-%EA%B8%B0%EB%A1%9D-%ED%95%98%EC%9E%90</link>
            <guid>https://velog.io/@kimmin_ah/%EC%BD%94%ED%85%8C-%ED%92%80%EA%B3%A0-%EA%B8%B0%EB%A1%9D-%ED%95%98%EC%9E%90</guid>
            <pubDate>Fri, 04 Apr 2025 07:19:43 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/2f5025ef-56ab-4d1c-9804-ad99fe68442b/image.png" alt="">
기본기 다지기 프로젝트 들어간다 
듬성듬성 풀었던 문제들 처음부터 다시 풀고 기록 꼼꼼하게 하기 스타또
<del>사실 코테 시리즈 썸네일용 게시물임</del></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 -특정 문자 제거하기 (+StringBuilder)]]></title>
            <link>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4</link>
            <guid>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4</guid>
            <pubDate>Fri, 04 Apr 2025 06:31:38 GMT</pubDate>
            <description><![CDATA[<br/>


<blockquote>
<p>💡문제 설명
문자열 my_string과 문자 letter이 매개변수로 주어집니다. my_string에서 letter를 제거한 문자열을 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<br/>

<h4 id="예를들어">예를들어</h4>
<ul>
<li><p>주어진 my_string 문자열 : <code>abcdef</code>
letter : <code>f</code>
return 값 : <code>abcde</code></p>
</li>
<li><p>주어진 my_string 문자열 : <code>BCBdbe</code>
letter : <code>B</code>
return 값 : <code>Cdbe</code>
<br/><br/></p>
<br/>
### 🧾기존 작성한 코드 -에러

</li>
</ul>
<p>처음엔 letter이랑 비교한 후 같은 문자면 StringBuffer의 deleteCharAt() 함수로 삭제하면 되겠다 해서 다음과 같은 코드를 작성했다.</p>
<pre><code class="language-java">class Solution {
    public String solution(String my_string, String letter) {
        String answer = &quot;&quot;;

        StringBuffer sb = new StringBuffer(my_string);

        for(int i=0; i&lt;=my_string.length()-1; i++){
            if(my_string.charAt(i) == letter.charAt(0)){
                sb.deleteCharAt(i);
            }
        }
        answer = sb.toString();

        return answer;
    }
} </code></pre>
<br/>
첫번째 예제는 통과 했지만 두번째 예제에서 결과가 `Cdbe` 가 아닌 `CBbe` 가 나와서 실패했다. 
왜 B가 삭제되는게 아니라 엉뚱한 d가 삭제됐나 했더니 문자 삭제는 sb 객체에서 이루어지지만 for문과 if문에서는 아무생각 없이 my_string으로 letter와 비교를 하고있었기 때문이였다. 

<p>즉, 이미 sb객체에서는 제일 처음 B가 삭제되었지만 my_string에서는 B가 삭제되지 않은 상태이기 때문에 인덱스가 달라진다. 예제2에서 오류가 난것도 첫번째 B가 삭제되면서 인덱스가 달라졌고 두번째 B자리에 있던 d가 삭제된 것이다. </p>
<p><br/><br/></p>
<h3 id="🧾기존-작성한-코드2--에러">🧾기존 작성한 코드2 -에러</h3>
<p>sb를 삭제하면 당연히 기존의 my_string 문자열과 달라지므로 sb객체의 문자열과 letter를 비교하도록 수정 해준다. </p>
<pre><code class="language-java">class Solution {
    public String solution(String my_string, String letter) {
        String answer = &quot;&quot;;

        StringBuffer sb = new StringBuffer(my_string);

        for(int i=0; i&lt;=sb.length()-1; i++){
            if(sb.charAt(i) == letter.charAt(0)){
                sb.deleteCharAt(i);
            }
        }
        answer = sb.toString();

        return answer;
    }
} </code></pre>
<p>실행 결과 예제 두개는 통과 하였지만 제출하니 테스트 20개 중 두개가 실패하였다. sb 객체안에 문자가 삭제 될때마다 인덱스가 앞으로 밀려서 조건문에 걸리지 않는 문자가 생기기 때문이다. 통과했던 예제 같은 경우에는 운좋게 조건문에 걸리지 않는 문자가 삭제해야하는 문자가 아니라서 에러가 나지 않은것이다. </p>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/29bb433d-e0a0-4127-9aeb-1abfeb7104fc/image.png" alt=""></p>
<p><code>C</code>나 <code>d</code>자리에 삭제해야할 문자열 <code>B</code>가 있었으면 이 예제도 에러난다. </p>
<p><br/><br/></p>
<h3 id="🧾제출한-코드--통과">🧾제출한 코드 -통과</h3>
<pre><code class="language-java">
class Solution {
    public String solution(String my_string, String letter) {
        String answer = &quot;&quot;;

        StringBuffer sb = new StringBuffer(my_string);

        for(int i=0; i&lt;sb.length(); i++){
            if(sb.charAt(i) == letter.charAt(0)){
                sb.deleteCharAt(i);
                i--;   //문자를 삭제한다면 인덱스는 1을 줄여줌
            }
        }
        answer = sb.toString();

        return answer;
    }
} </code></pre>
<p>문자를 삭제한 후에 뒤에있던 문자들이 앞으로 한칸씩 밀려서 문제가 발생하므로 조건문에서 문자가 삭제된다면 i를 -1시켜서 밀려진 문자를 건너뛰지 않게 조정한다. </p>
<p><br/><br/></p>
<h3 id="🔨개선한-코드a">🔨개선한 코드A</h3>
<pre><code class="language-java">//기존 코드 
StringBuffer sb = new StringBuffer(my_string); 


//개선한 코드
StringBuilder sb = new StringBuilder(my_string);

</code></pre>
<p>StringBuffer는 멀티스레드 환경에서 효율이 좋지만, 단일스레드이니까 더 가벼운 StringBuilder가 적절하다. 실제로 성능을 비교해보니 StringBuffer를 사용했을때보다 실행시간이 더 단축되었다. </p>
<br/>

<h3 id="stringbuffer와-stringbuilder-성능-비교">StringBuffer와 StringBuilder 성능 비교</h3>
<p>🔻반복문을 사용한 코드로 StringBuffer와 StringBilder의 성능 비교해보기 
<img src="https://velog.velcdn.com/images/kimmin_ah/post/a5c25a2b-f6bb-4e51-a92b-31adbfa08695/image.png" alt=""></p>
<br/>

<h3 id="-stringbuilder">+) StringBuilder?</h3>
<p>StringBuilder는 어제 작성했던 StringBuffer와 마찬가지로 Java에서 가변 문자열을 다루기 위한 클래스이다. 즉, 문자열을 만들고 나서도 내용을 자유롭게 수정할 수 있다.</p>
<br/>

<h4 id="💡stringbuilder의-주요-메서드stringbuffer와-같다">💡StringBuilder의 주요 메서드(StringBuffer와 같다)</h4>
<table>
<thead>
<tr>
<th align="left"><center>메서드</center></th>
<th align="right"><center>설명</center></th>
</tr>
</thead>
<tbody><tr>
<td align="left"><center>append(String s)</center></td>
<td align="right"><center>문자열 추가</center></td>
</tr>
<tr>
<td align="left"><center>insert(int offset, String s)</center></td>
<td align="right"><center>특정 위치에 문자열 삽입</center></td>
</tr>
<tr>
<td align="left"><center>replace(int start, int end, String s)</center></td>
<td align="right"><center>특정 범위 문자열 대체</center></td>
</tr>
<tr>
<td align="left"><center>delete(int start, int end)</center></td>
<td align="right"><center>특정 범위 문자열 삭제</center></td>
</tr>
<tr>
<td align="left"><center>reverse()</center></td>
<td align="right"><center>문자열 뒤집기</center></td>
</tr>
<tr>
<td align="left"><center>toString()</center></td>
<td align="right"><center>StringBuffer → String 변환</center></td>
</tr>
</tbody></table>
<br/>
<br/>



<blockquote>
<p>StringBuffer와 StringBuilder는 <strong>동기화</strong> 때문에 성능에 차이가 발생한다. StringBuffer는 모든 메서드가 동기화 되어있기 때문에 여러 쓰레드가 동시에 접근했을때 순서를 보장해준다. 하지만 순서를 보장하기위해 락(lock)기능이 있기 때문에 성능은 느려진다.  반면에 StringBuilder는 동기화가 없고 락 없이 바로 실행되기 때문에 실행 속도가 더 빠르다. StringBuilder 자체가 락이 필요 없는 단일쓰레드를 성능 낭비 없이 더 빠르게 실행시키기 위해 Java5 부터 만들어졌다. 
때문에 단일 쓰레드에서는 StringBuilder를, 멀티쓰레드에서는 StringBuffer를 사용하는게 좋다. </p>
</blockquote>
<br/>
<br/>



<h3 id="🔨개선한-코드b">🔨개선한 코드B</h3>
<pre><code class="language-java">//기존 코드 
for(int i=0; i&lt;sb.length(); i++){
            if(sb.charAt(i) == letter.charAt(0)){
                sb.deleteCharAt(i);
                i--;   
            }
}
answer = sb.toString(); 



//개선한 코드
answer = my_string.replace(letter, &quot;&quot;);
</code></pre>
<br/>

<p>반복문을 돌 필요 없이 자바의 <code>replace()</code> 함수에 &quot;&quot;을 넣으면 그냥 간단하게 삭제할 수 있다...
코드도 훨씬 간결해졌고 StringBuilder로 직접 삭제한 것과 동일한 효과를 준다.</p>
<br/>

]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 - 뒤집힌 문자열 (+StringBuffer)
]]></title>
            <link>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%92%A4%EC%A7%91%ED%9E%8C-%EB%AC%B8%EC%9E%90%EC%97%B4</link>
            <guid>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%92%A4%EC%A7%91%ED%9E%8C-%EB%AC%B8%EC%9E%90%EC%97%B4</guid>
            <pubDate>Wed, 02 Apr 2025 08:13:17 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡문제 설명
문자열 my_string이 매개변수로 주어집니다. my_string을 거꾸로 뒤집은 문자열을 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<br/>

<h4 id="예를들어">예를들어</h4>
<ul>
<li>주어진 my_string 문자열 : jaron
return 값 : noraj<br/>




</li>
</ul>
<h3 id="🧾제출한-코드">🧾제출한 코드</h3>
<pre><code class="language-java">
class Solution {
    public String solution(String my_string) {
        String answer = &quot;&quot;;

        for(int i=my_string.length()-1; i&gt;=0; i--){  //주어진 문자열을 역순으로 순회
            answer += my_string.charAt(i);
        }

        return answer;
    }
}</code></pre>
<p>문자열을 역순으로 출력하기위해 for문으로 주어진 문자열의 마지막 인덱스부터 0번째 인덱스까지 반복문을 돌린다. 인덱스에 해당하는 문자를 charAt()함수로 얻어 answer문자열에 더한 후 return한다.</p>
<br/>

<h3 id="🔨개선할-부분">🔨개선할 부분</h3>
<pre><code class="language-java">//기존 코드 
for(int i=my_string.length()-1; i&gt;=0; i--){
   answer += my_string.charAt(i);
} 

//개선한 코드
StringBuffer sb = new StringBuffer(my_string);
answer = sb.reverse().toString();
</code></pre>
<br/>

<p>for문으로 풀었더니 성능이 너무 떨어졌다. 다른 방법을 찾아보다가 String Buffer 클래스에 reverse()함수를 쓸 수 있다는걸 알게되었다. </p>
<p>개선된 코드 첫번째 줄이 주어진 문자열을 새로운 StringBuffer객체로 생성한 코드이다.
두번째 줄은 StringBuffer의 reverse()함수로 문자열을 뒤집은 후 반환하기위해 다시 String형으로 변환한 것이다. </p>
<br/>

<h3 id="-stringbuffer란">+) StringBuffer란?</h3>
<p>StrinfBuffer란 문자열을 다룰때 String보다 더 효율적으로 다룰 수 있는 클래스이다. StringBuffer 클래스에는 문자열을 다룰때 유용한 메서드들이 많다. </p>
<h4 id="💡stringbuffer의-주요-메서드">💡StringBuffer의 주요 메서드</h4>
<table>
<thead>
<tr>
<th align="left"><center>메서드</center></th>
<th align="right"><center>설명</center></th>
</tr>
</thead>
<tbody><tr>
<td align="left"><center>append(String s)</center></td>
<td align="right"><center>문자열 추가</center></td>
</tr>
<tr>
<td align="left"><center>insert(int offset, String s)</center></td>
<td align="right"><center>특정 위치에 문자열 삽입</center></td>
</tr>
<tr>
<td align="left"><center>replace(int start, int end, String s)</center></td>
<td align="right"><center>특정 범위 문자열 대체</center></td>
</tr>
<tr>
<td align="left"><center>delete(int start, int end)</center></td>
<td align="right"><center>특정 범위 문자열 삭제</center></td>
</tr>
<tr>
<td align="left"><center>reverse()</center></td>
<td align="right"><center>문자열 뒤집기</center></td>
</tr>
<tr>
<td align="left"><center>toString()</center></td>
<td align="right"><center>StringBuffer → String 변환</center></td>
</tr>
</tbody></table>
<br/>
<br/>
<br/>

<h4 id="🤔왜-stringbuffer가-성능향상에-좋을까">🤔왜 StringBuffer가 성능향상에 좋을까</h4>
<p>🔻반복문을 사용한 코드와 StringBuffer를 사용한 코드의 결과 비교
<img src="https://velog.velcdn.com/images/kimmin_ah/post/8192a6c0-43c6-4919-9b20-2bca6dfbe317/image.png" alt=""></p>
<blockquote>
<p>StrinfBuffer는 문자열을 다룰때 &quot;기존에 생성했던 객체&quot;에서 문자열을 수정하기 때문에 메모리를 낭비하지 않는다. 반면에 String형은 불변 객체이기 때문에 &quot;수정을 할때마다 새로운 객체&quot;를 계속 생성하기 때문에 성능이 많이 차이나는 것이다. </p>
</blockquote>
<br/>
<br/>

<p>예를들어 String형이 동작하는 법을 알아보기위해 str 문자열에 문자열을 더하는 코드를 다음과 같이 작성하면</p>
<pre><code class="language-java">String str = &quot;Hello&quot;;  //새로운 Hello 객체 생성
str += &quot; World&quot;;       //새로운 Hello World 객체 생성
str += &quot;!&quot;;            //새로운 Hello World! 객체 생성
System.out.println(str);</code></pre>
<p>Hello라는 문자열 객체가 한번 생성되고, Hello World라는 객체가 또 한번 생성되고,  Hello World!라는 새로운 객체가 또 생성된다. </p>
<p>➡️ 때문에 문자열을 수정할때마다 메모리 낭비가 되고 처리 속도도 늦어지는 것이다. </p>
<br/>
<br/>
<br/>

<p>하지만 StringBuffer는 변경 가능한 객체이기 때문에 <strong>한번 객체를 생성하면 같은 객체에서 문자열을 수정</strong>할 수 있다. 같은 예시로 코드를 작성해보면</p>
<pre><code class="language-java">StringBuffer sb = new StringBuffer(&quot;Hello&quot;);  //Hello객체 생성
sb.append(&quot; World&quot;);                          //기존 Hello객체에 World를 추가 
sb.append(&quot;!&quot;);                               //기존 Hello World객체에 !를 추가 
System.out.println(sb.toString());
</code></pre>
<p>StringBuffer는 문자열을 추가할때마다 객체가 생성되는것이 아닌 기존의 객체(sb)에 append()함수의 인자로 받은 문자열만 추가한다. </p>
<p>➡️ 때문에 메모리를 낭비할 일도 없고 처리속도도 빠르다.</p>
<br/>
<br/>
<br/>

<p><strong>🌟 이렇게 기존의 객체에서 수정이 가능한 이유는 StringBuffer가 내부적으로 문자열을 char[] 배열에 저장하고 관리하기 때문이다. &quot;Hello World!&quot;라는 문자열을 한자리씩 char형으로 배열에 저장하기 때문에 새로운 객체를 만들지 않고도 추가, 삽입, 삭제, 대체, 뒤집기 등 문자열 조작이 가능하다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 - 피자 나눠 먹기(3)]]></title>
            <link>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%94%BC%EC%9E%90-%EB%82%98%EB%88%A0-%EB%A8%B9%EA%B8%B03</link>
            <guid>https://velog.io/@kimmin_ah/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%94%BC%EC%9E%90-%EB%82%98%EB%88%A0-%EB%A8%B9%EA%B8%B03</guid>
            <pubDate>Wed, 02 Apr 2025 06:19:43 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡문제 설명
머쓱이네 피자가게는 피자를 두 조각에서 열 조각까지 원하는 조각 수로 잘라줍니다. 피자 조각 수 slice와 피자를 먹는 사람의 수 n이 매개변수로 주어질 때, n명의 사람이 최소 한 조각 이상 피자를 먹으려면 최소 몇 판의 피자를 시켜야 하는지를 return 하도록 solution 함수를 완성해보세요.</p>
</blockquote>
<br/>

<h4 id="예를들어">예를들어</h4>
<ul>
<li><p>10명이 7조각으로 자른 피자를 한 조각 이상씩 먹으려면 최소 2판을 시켜야 한다.</p>
</li>
<li><p>12명이 4조각으로 자른 피자를 한 조각 이상씩 먹으려면 최소 3판을 시켜야 한다.</p>
<br/>




</li>
</ul>
<br/>

<pre><code class="language-java">//제출 코드
class Solution {
    public int solution(int slice, int n) {
        int answer = 0;

        double divisionResult = (double)n/(double)slice;
        answer = (int)Math.ceil(divisionResult);

        return answer;
    }
}</code></pre>
<br/>

<h3 id="🔨개선할-부분">🔨개선할 부분</h3>
<pre><code class="language-java">double divisionResult = (double)n/(double)slice; //기존 코드 

double divisionResult = (double)n/slice; //불필요한 형변환 제거한 코드.
</code></pre>
<p>자바에서 정수 나눗셈은 몫만 반환한다. 딱 나누어 떨어지지 않고 소수점이 있어도 무시해버리기 때문에 소수점을 얻기 위해서는 정수/정수 가 아니라 실수/실수로 형변환을 해주어야한다. n과 slice 둘 다 형변환을 하였지만 둘중 하나만 실수로 바꾸어주어도 자동으로 실수연산이 된다. 
<br/></p>
<h4 id="-float이-아닌-double을-쓴-이유">+) float이 아닌 double을 쓴 이유</h4>
<p>double형이 더 쓰기 편하고 더 정밀하기 때문이다. float을 사용하려면 (float)을 붙이거나 f를 붙여야한다.
하지만 double은 바로 쓸 수 있다. </p>
<pre><code class="language-java">float a = 3.14; // 오류 발생! (double을 float에 넣으려면 3.14f로 써야 함)
double b = 3.14; // 정상 작동</code></pre>
<p>그리고 double형은 소숫점 이하 14<del>15자리, float은 6</del>7자리를 계산하므로 더 정밀하다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[PCCE 기출문제] 2번 / 각도 합치기
]]></title>
            <link>https://velog.io/@kimmin_ah/PCCE-%EA%B8%B0%EC%B6%9C%EB%AC%B8%EC%A0%9C-2%EB%B2%88-%EA%B0%81%EB%8F%84-%ED%95%A9%EC%B9%98%EA%B8%B0</link>
            <guid>https://velog.io/@kimmin_ah/PCCE-%EA%B8%B0%EC%B6%9C%EB%AC%B8%EC%A0%9C-2%EB%B2%88-%EA%B0%81%EB%8F%84-%ED%95%A9%EC%B9%98%EA%B8%B0</guid>
            <pubDate>Fri, 07 Mar 2025 05:34:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>💡문제 설명
일반적으로 두 선분이 이루는 각도는 한 바퀴를 360도로 하여 표현합니다. 따라서 각도에 360의 배수를 더하거나 빼더라도 같은 각을 의미합니다. 예를 들면, 30도와 390도는 같은 각도입니다.
주어진 코드는 각도를 나타내는 두 정수 angle1과 angle2가 주어질 때, 이 두 각의 합을 0도 이상 360도 미만으로 출력하는 코드입니다. 코드가 올바르게 작동하도록 한 줄을 수정해 주세요.</p>
</blockquote>
<br/>

<h4 id="예를들어">예를들어</h4>
<p>angle1은 280, angle2는 485를 입력받았을때 
두 변수의 합은 765도이고, 765를 720을 빼면 45도이므로 45를 출력해야한다. 
<br/></p>
<br/>

<p>🕷️디버깅(Debugging)은 이미 완성된 코드에서 버그를 찾아 수정하는 문제 타입이다. 1줄만 수정하여 버그를 고쳐야한다.</p>
<pre><code class="language-java">//문제 코드

import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int angle1 = sc.nextInt();
        int angle2 = sc.nextInt();

        int sum_angle = angle1 + angle2;
        System.out.println(sum_angle);
    }
}</code></pre>
<br/>

<pre><code class="language-java">//제출 코드

import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int angle1 = sc.nextInt();
        int angle2 = sc.nextInt();

        int sum_angle = angle1 + angle2;
        System.out.println(sum_angle%360);  //수정
    }
}</code></pre>
<p>처음에는 두 수의 합이 360을 넘을 수 있으니 삼항연산자를 쓰려고 하였으나 그냥 두 변수를 더한 값에 %360을 해주면 360으로 나눌 수 없을때까지 나누어주는 역할을 하므로 제일 마지막 줄을 sum_angle%360 으로 고쳐주면 된다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[쿠버네티스(Kubernetes)를 많이 쓰게 된 과정]]></title>
            <link>https://velog.io/@kimmin_ah/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4Kubernetes%EB%A5%BC-%EB%A7%8E%EC%9D%B4-%EC%93%B0%EA%B2%8C-%EB%90%9C-%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@kimmin_ah/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4Kubernetes%EB%A5%BC-%EB%A7%8E%EC%9D%B4-%EC%93%B0%EA%B2%8C-%EB%90%9C-%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Thu, 27 Feb 2025 11:39:17 GMT</pubDate>
            <description><![CDATA[<br/>




<h3 id="기존의-모놀리션-애플리케이션">기존의 모놀리션 애플리케이션</h3>
<p>몇년 전까지만 해도 대부분의 애플리케이션은 거대한 모놀리식 애플리케이션이였다. 
때문에 모든 기능이 하나의 프로젝트로 개발, 배포되며 전체 애플리케이션을 한번에 빌드하고 배포하여야했다. 
초기 개발 속도는 빨랐지만 코드가 복잡해짐 + 기능 수정이 다른 기능에도 영향을 미치는 경우가 많아져 유지보수도 어려워지고 확장성 또한 낮아졌다. </p>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/3474427a-f764-44a1-bef2-644759e5b926/image.png" alt="">
🔺위 사진은 <strong>모놀리션 애플리케이션</strong>의 아키택처 구조이다. </p>
<ul>
<li>User Interface : 입력 폼 같은 사용자가 직접 보는 화면.</li>
<li>Business Layer : 애플리케이션의 핵심 기능을 처리하는 부분.</li>
<li>Data Interface : DB 내용을 조회해서 정보를 가져오는 부분. </li>
</ul>
<p>이라고 보면 된다. 
<br/></p>
<h3 id="단점을-개선하기위해-마이크로서비스-등장">단점을 개선하기위해 마이크로서비스 등장</h3>
<p>이러한 모놀리식 애플리케이션은 점차 <strong>마이크로서비스</strong>라는 작고 독립적으로 실행 가능한 구성요소로 쪼개졌다. </p>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/abe3f7d2-ffb2-486c-a33f-37baf123382d/image.png" alt="">
마이크로서비스 아키텍처 구조 : </p>
<ul>
<li>Microservice UI : 사용자가 보는 화면</li>
<li>Microservice : 각 기능이 분리된 독립적인 서비스</li>
<li>Database : 각 마이크로서비스가 가지는 개별적인 DB</li>
</ul>
<p>🔺그림을 보면 알 수 있듯이 마이크로서비스는 서비스 단위로 서로 분리되어있기 때문에 개별적으로 개발, 배치, 업데이트, 확장 할 수 있다. 따라서 급변하는 비즈니스 요구사항대로 자주, 신속하게 변경이 가능해졌다. 
때문에 많은 대규모 서비스들이 모놀리식 구조에서 마이크로서비스 구조로 전환했지만 곧 마이크로서비스 운영에도 문제가 발생했다.
<br/></p>
<h3 id="마이크로서비스의-문제---도커로-개선">마이크로서비스의 문제 -&gt; 도커로 개선</h3>
<p>독립적인 서비스 개수가 늘어나면서 배포 및 관리가 어려워졌으며, 각 서비스가 독립적으로 실행되어야하기 때문에 컨테이너 실행환경이 필요해졌다. </p>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/fccf0850-74e2-4dac-a525-622edae4176f/image.png" alt=""></p>
<p>--&gt; 컨테이너 기반으로 마이크로서비스를 배포하고 관리하는 <strong>Docker</strong>가 등장하였다. 이로인해 개발자가 로컬에서 도커 컨테이너를 실행해보고, 동일한 환경을 서버에서도 실행할 수 있게 되었다.  </p>
<p>하지만 서비스를 독립적으로 실행시키기 위해 등장한 컨테이너가 또 점점 많아지면서 문제가 생겼고, 특히 대규모 서비스에서 관리가 복잡해졌다. </p>
<br/>

<h3 id="도커의-문제---쿠버네티스로-개선">도커의 문제 -&gt; 쿠버네티스로 개선</h3>
<p>기존 컨테이너 기반 운영의 문제: </p>
<ul>
<li>컨테이너를 자동으로 배포하고 관리하는 기능이 필요했다.</li>
<li>크래픽이 많아지면 자동으로 컨테이너를 늘리고, 줄어들면 축소해야했다. </li>
<li>여러개의 컨테이너를 하나의 클라스터로 묶어 관리할 필요가 있었다. </li>
</ul>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/0ce29694-744a-40c8-9239-e63928b8b540/image.png" alt=""></p>
<h4 id="---이러한-필요성-때문에-쿠버네티스kubernetes가-등장하였다">--&gt; 이러한 필요성 때문에 <strong>쿠버네티스(Kubernetes)</strong>가 등장하였다.</h4>
<blockquote>
<p>쿠버네티스는 컨테이너를 자동으로 배포, 확장, 로드밸런싱하는 기능을 제공하며, 장애가 난 컨테이너가 있으면 자동으로 재시작하고, 트래픽이 증가할때는 자동으로 컨테이너 개수를 조절하기도하며, 여러 서버에 걸쳐 컨테이너를 효율적으로 배포해준다. </p>
</blockquote>
<p><br/><br/></p>
<p>이러한 이점 덕에 넷플릭스, 우버 등등 대규모 기업들이 수천개의 마이크로서비스를 쿠버네티스로 관리하기 시작했고, 
최종적으로는 마이크로서비스 아키텍처 + 쿠버네티스 조합이 표준이 되었다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[LAN, WAN, 방화벽, DMZ 개념 정리 해보자]]></title>
            <link>https://velog.io/@kimmin_ah/LAN-WAN-%EB%B0%A9%ED%99%94%EB%B2%BD-DMZ</link>
            <guid>https://velog.io/@kimmin_ah/LAN-WAN-%EB%B0%A9%ED%99%94%EB%B2%BD-DMZ</guid>
            <pubDate>Sun, 23 Feb 2025 07:39:11 GMT</pubDate>
            <description><![CDATA[<p>외/내부망에 대해 찾아보다가 딱 개념만 아는것 같아서 좀 더 자세히 머리에 담기위해 포스팅 해본다. 
<br/></p>
<blockquote>
<p>✏️ 랜(LAN) : Local Area Network의 약자로 건물 안이나 특정 지역을 범위로 하는 네트워크를 의미한다. 사설 IP를 사용한 건물이나 사무실같은 제한된 곳에서 연결된 네트워크이다.  --&gt;내부망
✏️ 왠(WAN) : Wide Area Network의 약자로 지리적으로 넓은 범위에 구축되어있는 네트워크이다.  공인 IP를 사용하여 인터넷을 통해 연결되며 회사 본사와 전국 지사를 연결하는 네트워크라고 볼 수 있다. --&gt;외부망
✨외부망과 내부망 사이에는 방화벽이 존재한다. </p>
</blockquote>
<br/>

<blockquote>
<p>방화벽이란?
네트워크 트래픽을 모니터링하고 제어하는 네트워크 보안 시스템이다. 
내부 네트워크와 외부 네트워크 간의 장벽을 구성하여 서로 다른 네트워크를 지나는 데이터를 허용 및 거부, 검열, 수정하는 역할을 수행하는 소프트웨어 또는 소프트웨어를 구동시키는 하드웨어 장치를 말한다. </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/c19dbc4a-f41c-4297-b311-1abd9280fb0d/image.png" alt=""></p>
<p>🔺사진과 같은 구조로 서버나 데이터를 노리는 대상으로부터 정보를 보호할 수 있다. 
<br/>
내부망, 외부망을 찾아보다보면 DMZ라는 단어를 자주 볼 수 있는데, <strong>DMZ란 외부에 서비스 제공 시, 내부 자원을 보호하기위해 내부망과 외부망 사이에서 접근제한을 수행하는 영역</strong>이라고 한다. </p>
<p>엥 방화벽이랑 똑같은거 아닌가? 싶어서 더 찾아보니 
DMZ는 주로 기업이 외부에 공개해야하는 서버를 두는 공간으로, 외부에서 접근해야하는 서버(웹서버, 메일 서버)를 안전하게 운영하면서 내부 네트워크를 보호하기위해 사용된다고 한다. </p>
<p>방화벽을 이용해 DMZ를 구성하는것이 일반적이며, DMZ = 방화벽 이 아니라 &quot;방화벽과 함께 사용하는 내부 네트워크를 보호하기위한 중간 네트워크 영역&quot;이다. </p>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/cacb131c-292c-48e3-9833-0d11fcd59109/image.png" alt="">
🔺DMZ구조</p>
<p>가정과 같은 외부에서 접근해야하는 서버가 없는 경우에는 DMZ영역이 필요없다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리눅스 기본 명령어]]></title>
            <link>https://velog.io/@kimmin_ah/%EB%A6%AC%EB%88%85%EC%8A%A4-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4</link>
            <guid>https://velog.io/@kimmin_ah/%EB%A6%AC%EB%88%85%EC%8A%A4-%EA%B8%B0%EB%B3%B8-%EB%AA%85%EB%A0%B9%EC%96%B4</guid>
            <pubDate>Fri, 21 Feb 2025 04:18:21 GMT</pubDate>
            <description><![CDATA[<h4 id="🌟--ls--list의-약자로-해당-디랙토리에-있는-파일의-목록을-나열하는-명령">🌟  ls : List의 약자로 해당 디랙토리에 있는 파일의 목록을 나열하는 명령.</h4>
<pre><code>ls
ls -a  → 현재 디렉토리의 숨김파일을 포함한 목록
ls -al → 현재 디렉토리의 숨김파일을 포함한 자세한 파일 목록</code></pre><br/>

<h4 id="🌟-cd--change-directory의-약자로-디렉터리를-이동하는-명령">🌟 cd : Change Directory의 약자로 디렉터리를 이동하는 명령.</h4>
<pre><code>cd → 현재 사용자의 홈 디렉터리로 이동
cd .. → 바로 상위의 디렉터리로 이동</code></pre><br/>

<h4 id="🌟-pwd--print-working-directory의-약자로-현재-디렉터리의-전체-경로를-화면에-표시">🌟 pwd : Print Working Directory의 약자로 현재 디렉터리의 전체 경로를 화면에 표시.</h4>
<pre><code>pwd    → 현재 작업 중인 디렉터리의 경로를 출력</code></pre><br/>

<h4 id="🌟-mkdir--make-directory의-약자로-새로운-디렉터리를-생성-생성된-디렉터리는-명령을-실행한-사용자의-소유가-된다">🌟 mkdir : MaKe DIRectory의 약자로 새로운 디렉터리를 생성. 생성된 디렉터리는 명령을 실행한 사용자의 소유가 된다.</h4>
<pre><code>mkdir test   → test라는 디렉터리 생성</code></pre><br/>

<h4 id="🌟-touch--크기가-0인-새-파일을-생성하거나-생성된-파일이-존재한다면-파일의-최종-수정-시간을-변경">🌟 touch : 크기가 0인 새 파일을 생성하거나 생성된 파일이 존재한다면 파일의 최종 수정 시간을 변경.</h4>
<pre><code>touch fileA → 만든 test디렉터리 안에 fileA라는 파일 생성</code></pre><br/>

<h4 id="🌟-cp--copy의-약자로-파일이나-디렉터리를-복사">🌟 cp : CoPy의 약자로 파일이나 디렉터리를 복사.</h4>
<pre><code>cp abc.txt cba.txt     → abc.txt를 cba.txt라는 이름으로 바꿔서 복사
ex) cp kimmina/test/fileA kimmina/test2/cpFile  → test디렌터리에 있는 fileA를 test2 디렉터리에 cpFile이름으로 복사 
cp -r abc cda         → 디렉터리 복사</code></pre><br/>

<h4 id="🌟-chmod--change-mode의-약자로-선택한-파일의-권한을-관리">🌟 chmod : change mode의 약자로 선택한 파일의 권한을 관리.</h4>
<pre><code>chmod 777 fileA   →fileA의 사용자,그룹,기타 rwx권한을 모두 허용해라</code></pre><br/>

<blockquote>
<p>권한관리 명령어 : 
리눅스는 사용자rwx 그룹rwx 기타사용자rwx 권한 정보가 있으며 여기서 rwx는 r(읽기)w(쓰기)x(실행)를 나타낸다. 
만약 내가 생성한 fileA에 대해 사용자, 그룹, 기타 사용자가 모두 읽기, 쓰기, 실행을 할 수있도록 권한을 부여하고 싶다면 chmod 명령어를 777로 입력하면 된다.</p>
</blockquote>
<br/>

<h4 id="💡-777이-모든-권한-허용인-이유">💡 777이 모든 권한 허용인 이유</h4>
<p>첫번째 7이 사용자, 두번째 7이 그룹, 세번째 7이 기타의 rwx권한을 나타낸것인데 
rwx는 각각 r=4, w=2, x=1의 값을 가진다. 
사용자에게 읽기, 쓰기, 실행 권한을 주고싶다면 4+2+1을 더한값인 7을 명령어로 입력해주면 권한이 부여된다.
만약 기타 사용자에게 읽기와 실행 권한만 부여하고싶다면 4+1인 5를 입력하면 되고 chmod 775 fileA 라고 입력하면 된다. </p>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/23edcdd2-8dec-4dae-82a9-20e967a2bea2/image.png" alt=""></p>
<p>🔺ls -al 명령어를 입력해 자세한 정보를 조회해보면 파일마다의 권한도 확인할 수 있다. 사진을 보면 fileA는 사용자가 읽기 권한, 그룹은 쓰기 권한, 기타 사용자는 실행 권한만 있다. 
fileB는 사용자-읽기, 쓰기 / 그룹-읽기,실행 / 기타-실행 권한이 부여되어있음을 알 수 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리눅스(Linux) 시작하기 ]]></title>
            <link>https://velog.io/@kimmin_ah/Temp-Title-d7ihv2w0</link>
            <guid>https://velog.io/@kimmin_ah/Temp-Title-d7ihv2w0</guid>
            <pubDate>Thu, 20 Feb 2025 04:16:28 GMT</pubDate>
            <description><![CDATA[<br/>

<h2 id="리눅스란">리눅스란?</h2>
<blockquote>
</blockquote>
<p>리눅스(Linux)는 오픈소스 운영체제이다. 1991년에 리누스 토르발스(Linus Torvalds)가 개발을 시작한 리눅스는 무료로 사용할 수 있으며, 전 세계 개발자들이 협력하여 지속적으로 개선되고 있다.</p>
<p><br/><br/></p>
<h2 id="리눅스-설치하기">리눅스 설치하기</h2>
<p>리눅스는 여러 가지 방법으로 설치할 수 있다. 
나는 리눅스 배포판의 Ubuntu ISO 이미지 파일을 다운로드한 후 VMware 가상 머신을 설치하고, 그 가상머신 안에서 아까 받은 ISO 파일을 연결하여 리눅스를 설치했다. 
+) 가상 머신에는 VMware, VirtualBox등이 있는데 운영체제 안에서 다른 운영체제를 실행할 수 있도록 해주는 프로그램이다. </p>
<p>즉 실제 내 컴퓨터에 리눅스를 설치한게 아니라 가상머신안에 리눅스를 설치한 개념이 되는것!</p>
<p>이제 설치해보자</p>
<ol>
<li>Ubuntu iso 다운
<a href="https://ubuntu.com/download/desktop">https://ubuntu.com/download/desktop</a>
<img src="https://velog.velcdn.com/images/kimmin_ah/post/05a511f5-0dd3-425c-b34b-043dc208f7c0/image.png" alt=""></li>
</ol>
<p><br/><br/></p>
<ol start="2">
<li>아래 블로그 참고해서 VMWare WorkStation Player 다운(새로운 Virtual Machine 생성할때 첫번째에 다운받은 iso넣기)
<a href="https://ckang.tistory.com/78">https://ckang.tistory.com/78</a></li>
</ol>
<p>🔻잘 설치되어 실행된 화면
<img src="https://velog.velcdn.com/images/kimmin_ah/post/5a9fe78d-de96-4174-ab5e-341ad8e1f5b3/image.png" alt=""></p>
<br/>

<p>🔻 앱표시에 terminal 검색 후 실행
<img src="https://velog.velcdn.com/images/kimmin_ah/post/f8864720-b42d-4364-bab2-f98f6461c5ce/image.png" alt=""></p>
<br/>

<p>🔻 이제 명령어 입력 가능
<img src="https://velog.velcdn.com/images/kimmin_ah/post/8fdaea46-f4ac-4aa9-9093-bdf9f3a37351/image.png" alt=""></p>
<p>*나는 GUI를 다운받아서 그래픽 화면이 뜨지만 CLI를 다운받으면 터미널이 뜸.
각각 장단점이 있다고하는데 GUI는 세밀함이 떨어져서 개발자는 CLI와 친해지는게 더 좋다고 함. 하지만 난 아직 초보니까 GUI쓸거임</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[On-Premise란? (Cloud와의 차이)]]></title>
            <link>https://velog.io/@kimmin_ah/On-Premise%EB%9E%80-Cloud%EC%99%80%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@kimmin_ah/On-Premise%EB%9E%80-Cloud%EC%99%80%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Wed, 19 Feb 2025 15:05:50 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/37d50ef2-9934-4673-8e31-47b533dafb0f/image.png" alt=""></p>
<blockquote>
<p>온프레미스(On-Premise) : 기업이 자체적으로 서버, 네트워크, 스토리지 등의 IT 인프라를 구축하고 운영하는 방식. 쉽게 말해, 클라우드처럼 외부 서비스 제공업체의 서버를 빌리는 것이 아니라, 직접 물리적인 장비를 구매해서 관리하는 방식이다.</p>
</blockquote>
<br/>

<h3 id="✨온프레미스-vs-클라우드">✨온프레미스 vs. 클라우드</h3>
<table>
<thead>
<tr>
<th align="center">제목1</th>
<th align="center">온프레미스(On-Premise)</th>
<th align="center">클라우드(Cloud)</th>
</tr>
</thead>
<tbody><tr>
<td align="center">서버 위치</td>
<td align="center">기업 내부(사내 데이터센터)</td>
<td align="center">AWS, GCP, Azure 같은 외부 업체</td>
</tr>
<tr>
<td align="center">초기 비용</td>
<td align="center">서버, 네트워크 장비 구매 비용 高</td>
<td align="center">초기 비용 적음(구독형, 종량제)</td>
</tr>
<tr>
<td align="center">운영 관리</td>
<td align="center">기업이 직접 유지보수 및 운영</td>
<td align="center">클라우드 제공업체가 관리</td>
</tr>
<tr>
<td align="center">보안</td>
<td align="center">물리적으로 보호 가능하지만, 직접 보안 관리 필요</td>
<td align="center">보안 패치는 제공업체가 지원</td>
</tr>
<tr>
<td align="center">확장성</td>
<td align="center">장비 추가 필요(시간 &amp; 비용 소요)</td>
<td align="center">빠른 확장 가능</td>
</tr>
<tr>
<td align="center">유지보수</td>
<td align="center">직접 서버 관리해야 함</td>
<td align="center">클라우드 업체가 관리</td>
</tr>
</tbody></table>
<br/>
<br/>

<h3 id="✨온프레미스를-사용하는-이유">✨온프레미스를 사용하는 이유</h3>
<ol>
<li>보안 및 데이터 보호 🔐
: 금융, 정부, 의료 등 민감한 데이터를 다루는 기업은 보안 문제로 인해 온프레미스를 선호한다고함.</li>
<li>맞춤형 인프라 구축 가능 🏗️
: 클라우드보다 세부적인 설정과 최적화가 가능함.</li>
<li>장기적인 비용 절감 💰
: 초기 비용은 높지만, 장기적으로 보면 클라우드의 구독 비용보다 저렴할 수도 있음.</li>
<li>법적 규제 준수 📜
: 일부 산업에서는 데이터를 외부 클라우드에 저장하는 것이 법적으로 제한될 수도 있음.</li>
</ol>
<br/>

<h3 id="✨온프레미스-vs-클라우드-뭐가-좋을까">✨온프레미스 vs. 클라우드 뭐가 좋을까?</h3>
<p>스타트업, 빠른 확장이 필요한 기업이다. → 클라우드
보안이 중요한 금융, 공공기관이다. → 온프레미스
하이브리드 방식(온프레미스 + 클라우드)을 선택하는 경우도 많다고 함</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[쿠버네티스(Kubernetes)란?]]></title>
            <link>https://velog.io/@kimmin_ah/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4Kubernetes%EB%9E%80</link>
            <guid>https://velog.io/@kimmin_ah/%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4Kubernetes%EB%9E%80</guid>
            <pubDate>Wed, 19 Feb 2025 14:50:52 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/4e3bc192-8dce-43fd-be30-acf075c0a923/image.png" alt=""></p>
<br/>

<blockquote>
<p>쿠버네티스(Kubernetes, 줄여서 K8s) :  컨테이너화된 애플리케이션을 자동으로 배포, 확장, 관리해주는 오픈소스 오케스트레이션 플랫폼이다. 원래 Google이 개발했고, 현재는 <strong>Cloud Native Computing Foundation(CNCF)</strong>에서 관리한다.</p>
</blockquote>
<p>*참고로 쿠버네티스는 그리스어로 선박의 핸들 장치를 의미한다. 
<br/></p>
<h3 id="✨쿠버네티스의-핵심-개념">✨쿠버네티스의 핵심 개념</h3>
<h4 id="🔹pod">🔹Pod</h4>
<p>컨테이너를 감싸는 가장 작은 배포 단위
하나의 Pod 안에 여러 개의 컨테이너가 함께 실행될 수도 있음</p>
<h4 id="🔹node">🔹Node</h4>
<p>쿠버네티스 클러스터 내에서 애플리케이션을 실행하는 실제(물리) 또는 가상 머신</p>
<h4 id="🔹cluster">🔹Cluster</h4>
<p>여러 개의 Node로 구성된 쿠버네티스 환경</p>
<h4 id="🔹deployment">🔹Deployment</h4>
<p>애플리케이션의 배포 및 업데이트를 자동화
원하는 상태를 정의하면 쿠버네티스가 이를 유지</p>
<h4 id="🔹service">🔹Service</h4>
<p>외부 또는 내부에서 Pod에 접근할 수 있도록 네트워크 연결을 제공</p>
<h4 id="🔹ingress">🔹Ingress</h4>
<p>외부에서 클러스터 내부의 서비스에 접근할 수 있도록 트래픽을 라우팅</p>
<h4 id="🔹configmap--secret">🔹ConfigMap &amp; Secret</h4>
<p>환경 변수 및 민감한 정보를 안전하게 관리</p>
<br/>
<br/>

<h3 id="✨쿠버네티스의-주요-기능">✨쿠버네티스의 주요 기능</h3>
<p>✅ 자동화된 배포 및 롤백
✅ 수평적 확장(오토스케일링)
✅ 자동 복구(Self-healing)
✅ 로드 밸런싱 및 서비스 디스커버리
✅ 보안 및 네트워크 관리</p>
<p><br/><br/></p>
<h3 id="✨그래서-쿠버네티스를-왜-사용할까">✨그래서 쿠버네티스를 왜 사용할까?</h3>
<ol>
<li>컨테이너 기반 애플리케이션을 효율적으로 운영할 수 있다.</li>
<li>트래픽 증가 시 자동으로 확장 가능하다.</li>
<li>장애 발생 시 자동으로 복구할 수 있다.</li>
<li>클라우드 환경(AWS, GCP, Azure)과 쉽게 연동 가능하다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[비동기 HTTP 통신을 위한 방법]]></title>
            <link>https://velog.io/@kimmin_ah/Axios%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@kimmin_ah/Axios%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Wed, 12 Feb 2025 10:28:05 GMT</pubDate>
            <description><![CDATA[<p>프로젝트를 하다보면 클라이언트와 서버간의 비동기 HTTP 통신을 할 일이 생긴다. 나는 이번 프로젝트에서 내내 axios만 사용했는데 fetch API를 사용하는 방법도 있어서 차이도 공부할 겸 포스팅해본다. 
<br/></p>
<h1 id="axios란">axios란?</h1>
<blockquote>
<p>axios는 Promise API를 활용하는 HTTP 비동기 통신 라이브러리이며, Spring Boot API와 쉽게 통신 할 수 있다. </p>
</blockquote>
<br/>


<h4 id="사용법-">사용법 :</h4>
<pre><code class="language-java">axios.get(&quot;https://api.example.com/data&quot;)
  .then(response =&gt; console.log(response.data))  // 자동 JSON 변환
  .catch(error =&gt; console.error(error));</code></pre>
<br/>

<h1 id="fetch-api란">Fetch API란?</h1>
<blockquote>
<p>자바스크립트의  bulit-in 라이브러리이며 일반적으로 API를 연동하기위해 사용하던 방식이다. </p>
</blockquote>
<br/>

<h4 id="사용법--1">사용법 :</h4>
<pre><code class="language-java">fetch(&quot;https://api.example.com/data&quot;)
  .then(response =&gt; response.json())  // JSON 변환 필요
  .then(data =&gt; console.log(data))
  .catch(error =&gt; console.error(error));</code></pre>
<p><br/><br/>
찾아보면 두개 다 좋은 방식이지만 Axios가 조금 더 선호도가 높은것을 알 수 있다. </p>
<h3 id="fetch보다-axios를-더-많이-사용하는-이유">Fetch보다 Axios를 더 많이 사용하는 이유</h3>
<ul>
<li>자동으로 json 데이터 변환 (fetch는 .json()호출 필요)</li>
<li>요청 및 응답 인터셉터 지원  (fetch는 직접 then처리 필요)</li>
<li>cancelToken으로 간단하게 요청 취소 가능 (fetch는 AbortController 필요)</li>
</ul>
<p>등등.. fetch API보다 axois가 기능이 더 풍부하고 사용하기 편리한듯 하다.
<br/><br/><br/><br/></p>
<h3 id="참고-ajax와-axios의-관계">참고) AJAX와 Axios의 관계</h3>
<h1 id="ajax란">AJAX란?</h1>
<blockquote>
</blockquote>
<p> Asynchronous Javascript And XML의 약자이며 비동기적으로 서버와 데이터를 교환할 수 있다. 
XMLHttpRequest객체를 통해서 서버에 request, response 처리를 한다. 
 +)jQuery라이브러리의 ajax함수를 사용하면 복잡한 Ajax기법을 더 쉽게 사용할 수 있다. </p>
<h3 id="ajax와-axios의-관계">AJAX와 Axios의 관계</h3>
<p>Axios는 내부적으로 AJAX를 기반으로 동작하지만, 더 편리한 기능을 제공하는 라이브러리이다.
즉 AJAX를 더 쉽게 쓰기위해 Axios를 쓰는 것</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ffmpeg.dll이 없어 코드 실행을 진행할 수 없습니다. 시스템 오류]]></title>
            <link>https://velog.io/@kimmin_ah/ffmpeg.dll%EC%9D%B4-%EC%97%86%EC%96%B4-%EC%BD%94%EB%93%9C-%EC%8B%A4%ED%96%89%EC%9D%84-%EC%A7%84%ED%96%89%ED%95%A0-%EC%88%98-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4.-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%98%A4%EB%A5%98</link>
            <guid>https://velog.io/@kimmin_ah/ffmpeg.dll%EC%9D%B4-%EC%97%86%EC%96%B4-%EC%BD%94%EB%93%9C-%EC%8B%A4%ED%96%89%EC%9D%84-%EC%A7%84%ED%96%89%ED%95%A0-%EC%88%98-%EC%97%86%EC%8A%B5%EB%8B%88%EB%8B%A4.-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%98%A4%EB%A5%98</guid>
            <pubDate>Tue, 11 Feb 2025 13:52:56 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/ddb717f1-0465-43a1-8273-8d3d375b7d98/image.png" alt=""></p>
<p>어제까지도 잘 실행되던 vsCode가 사진처럼 에러창이 뜨면서 실행되지 않았다. 
찾아보니 응용 프로그램에 결함이 있거나, ffmpeg.dll이(가) PC에 존재하는 악성 소프트웨어에 의해 삭제, 잘못된 장소에 위치, 손상되었거나,  Windows 레지스트리가 손상되었거나 해서 ffmpeg.dll 파일을 찾지 못한다는 것이였다. 
<del>갑자기 왜..</del></p>
<p>처음엔 망한건가 싶었는데 그냥 vsCode새로 깔아서 실행시키니 해결됐다. </p>
<ol>
<li>제어판 - 프로그램 및 기능 - vsCode 삭제</li>
<li><a href="https://code.visualstudio.com/">https://code.visualstudio.com/</a> 에서 vsCode다시 다운받은 후 실행</li>
</ol>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/92240903-b9bf-4a72-8ebf-9ce458941c20/image.png" alt="">
아주 말끔하게 실행된다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ProductController 코드 개선]]></title>
            <link>https://velog.io/@kimmin_ah/productController-%EC%BD%94%EB%93%9C-%EA%B0%9C%EC%84%A0</link>
            <guid>https://velog.io/@kimmin_ah/productController-%EC%BD%94%EB%93%9C-%EA%B0%9C%EC%84%A0</guid>
            <pubDate>Thu, 16 Jan 2025 03:22:59 GMT</pubDate>
            <description><![CDATA[<p> 원래는 상품을 먼저 저장하고 id를 받아와 컨트롤러에서 서비스를 한번 더 호출하여 상세이미지들을 저장하였다. 
<img src="https://velog.velcdn.com/images/kimmin_ah/post/6ba9faf8-203e-456c-9301-0b8c316a6894/image.png" alt="">
<img src="https://velog.velcdn.com/images/kimmin_ah/post/975212dc-dd5b-49a3-874e-102218762456/image.png" alt=""></p>
<p>컨트롤러에서 너무 많은 처리를 한다는 생각이 들어서 
개선 1 ) 컨트롤러는 요청처리와 응답 생성에만 집중할 수 있도록 saveProductWithImages 메서드를 서비스 계층에 위임한다. 
<img src="https://velog.velcdn.com/images/kimmin_ah/post/8d516f08-0b2f-4915-8bb7-fb48ea1602e7/image.png" alt="">
<img src="https://velog.velcdn.com/images/kimmin_ah/post/0fc02d26-78ac-40fb-ac6f-96ed12b42001/image.png" alt="">
이렇게하면 컨트롤러는 이미지를 파싱후 저장할 파일 경로만 생성하는 역할을하고 저장로직은 Service단에서 saveProductWithImages 메서드를 통해 처리된다. </p>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/5989c65d-5347-49c6-a6ff-e36d8358850b/image.png" alt="">
위는 서비스에서 트렌젝션 적용한 코드</p>
<p>개선 2) @RequestParam말고 @RequestPart애노테이션을 사용하면 더 좋아진다는것 같은데 이건 팀원이랑 이야기해보고 다시 결정합니다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[boot에서 이미지 저장하기]]></title>
            <link>https://velog.io/@kimmin_ah/boot%EC%97%90%EC%84%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%A0%80%EC%9E%A5%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@kimmin_ah/boot%EC%97%90%EC%84%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%A0%80%EC%9E%A5%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 16 Jan 2025 03:21:43 GMT</pubDate>
            <description><![CDATA[<p>화면에서 등록하기 버튼을 누르면 onChangeButton함수가 실행되어 객체가 전송될 수 있게 하려던 중
백단으로 넘어가는게 안되서 작성한다.
<img src="https://velog.velcdn.com/images/kimmin_ah/post/6d13a8ec-1ba7-40cf-bfdd-74654009c1a7/image.png" alt=""></p>
<br/>


<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/ebeaa9c5-1006-466b-94fa-2a1856a6ec34/image.png" alt="">
onChangeButton함수와 비동기로 post요청을 보내는 axios이다.
<br/>
<br/>
<img src="https://velog.velcdn.com/images/kimmin_ah/post/be51002b-d6fa-4d8d-92f6-385fa626341e/image.png" alt=""></p>
<p>원래는 수정하기 버튼을 누르면 객체가 json형태로 로그로 출력된 후 백으로 넘어가야하는데 자꾸 에러가 났다. </p>
<p>
http://localhost:8989/product' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
<p/>

<br/>
Error fetching data: AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}]]></description>
        </item>
        <item>
            <title><![CDATA[react, spring boot로 이미지 여러장 저장하기]]></title>
            <link>https://velog.io/@kimmin_ah/%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%A0%80%EC%9E%A5%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@kimmin_ah/%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%A0%80%EC%9E%A5%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 15 Jan 2025 14:40:00 GMT</pubDate>
            <description><![CDATA[<p>상품을 등록하는 기능을 구현할때 여러장의 사진이 같이 저장되도록 구현해야했다. 
리액트로 앞단에서 json형태의 문자열으로 서버로 post해주고 product테이블과 productImages테이블에 저장했다. </p>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/edc99b2c-e9ed-421f-babc-d37042bea333/image.png" alt="">
사진의 [등록하기] 버튼을 클릭하면 onChangeButton함수가 실행되고 상품을 저장하는데 필요한 정보(상품 이름, 카테고리, 한줄설명, 상세설명, 썸네일 이미지, 상세이미지들)를 updateObj라는 객체로 만들어서 묶어준다. 객체형태로 데이터를 보내게되면 서버와 클라이언트 간의 데이터 전달 구조가 명확해지고, 어떤 데이터를 주고받는지 파악하기 쉬워진다. </p>
<pre><code>
const onChangeButton = e =&gt; {
        const updatedObj = {
            productName: title,
            productCategory: kind,
            shortDescription: shortDesc,
            detailedDescription: details,
            thumbnailImage: mainImg.name, // 파일 이름 설정
            imageUrl : imgList.map(img =&gt; img.originFile.name) 
        };
        const updatedList =
            kind === &#39;kiosk&#39;
                ? [...kioskList, updatedObj]
                : kind === &#39;cctv&#39;
                ? [...cctvList, updatedObj]
                : [...otherList, updatedObj];
            kind === &#39;kiosk&#39;
                ? setKioskList(updatedList)
                : kind === &#39;cctv&#39;
                ? setCctvList(updatedList)
                : setOtherList(updatedList);

        post(updatedObj, mainImg, imgList); // 파일 객체를 전달
    };</code></pre><p>등록할 때 선택한 카테고리가 어떤건지 검사한 후 kind에 저장, post함수의 인자로 만들었던 updateObj, mainImg, imgList를 담는다. 세개를 따로 담는 이유는 FormData에 따로 추가로 해줄것이기 때문이다.</p>
<br/>
<br/>

<pre><code>const post = (data, file, imageFiles) =&gt; {  
        const formData = new FormData();
        formData.append(&#39;product&#39;, JSON.stringify(data)); // JSON 데이터를 추가
        formData.append(&#39;upfile&#39;, file); // 파일 추가 (업로드할 파일 객체 전달)
        //formData.append(&#39;images&#39;, file);

        // 상세 이미지 파일을 반복문으로 추가
        imageFiles.forEach((imageFile) =&gt; {
            if (imageFile.originFile) {
                formData.append(&#39;images&#39;, imageFile.originFile); // 각 파일을 &#39;images&#39; 키로 추가
            }
        });

        axios
            .post(&#39;http://localhost:8989/product/save&#39;, formData, {
                headers: {
                    &#39;Content-Type&#39;: &#39;multipart/form-data&#39;,
                },
            })
            .then(response =&gt; {
                console.log(&#39;Response:&#39;, response.data);
            })
            .catch(error =&gt; {
                if (error.response) {
                    console.error(&#39;Server Error:&#39;, error.response.data);
                } else {
                    console.error(&#39;Error:&#39;, error.message);
                }
            });
    };</code></pre><p>post함수에서 세가지 인자를 받아서 FormData객체를 만들어서 .append로 저장할 수 있다. js가 제공하는 FormData객체는 폼데이터를 쉽게 다룰수 있게 해주기 때문에 서버에 전송할때 유용하다.  상세이미지는 여러장이 들어가기 때문에 반복문으로 하나씩 넣어준다. </p>
<ul>
<li>FormData는 기본적으로 문자열이나 파일데이터를 처리한다. 객체형태인 updatedObj는 처리할 수 없기 때문에 json 문자열으로 변환시키기 위해서JSON.stringify(data) 처리를 해주고 파일데이터인 upfile과 images는 그대로 넘겨준다. </li>
</ul>
<p>axios로 비동기 post요청을 보내고나면 Controller가 요청을 보낸 url대로 매핑해 save메서드를 실행시킨다 
<img src="https://velog.velcdn.com/images/kimmin_ah/post/a23c101b-02fa-4f9e-af98-89c09b954f2e/image.png" alt="">
앞단에서 상품정보를 json형태를 띈 문자열로 보냈기 때문에 @RequestParam으로 받을 수 있다. 그리고  ObjectMapper()객체를 이용해 다시 객체로 파싱한 후 썸네일 이미지도 저장한다. <br/>
썸네일 이미지는 한장이기 때문에 saveFile메서드로, 상세이미지는 여러장이기 때문에 배열형태인 saveImages메서드로 저장한다. 
*이때 썸네일 이미지는 product테이블에 들어가야하고 상세보기 이미지는 productImages테이블에 들어가야한다. (erd사진 참고)
<img src="https://velog.velcdn.com/images/kimmin_ah/post/bf1fd6bf-72f9-4332-b9a5-b1978ade8cbf/image.png" alt="">
상세보기 이미지를 저장할때는 1. 이미지 아이디, 2. 경로, 3. 순서, 4. 상품아이디가 필요하다. 
상품의 아이디는 DB에 상품이 저장될 때 부여받게끔 GENERATED BY DEFAULT AS IDENTITY로 생성했기 때문에 상품 저장을 먼저 하여 productId를 부여받은 뒤 상세보기 이미지를 저장해야한다. 
<br/>
<br/>
<br/>
<br/>
이렇게 내가 짠 코드를 자세하게 작성해보니 필요없는 코드들도 발견할 수 있어서 좋은것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[키오스크 상담 사이트 시작]]></title>
            <link>https://velog.io/@kimmin_ah/%E3%85%87%E3%85%87%E3%85%87</link>
            <guid>https://velog.io/@kimmin_ah/%E3%85%87%E3%85%87%E3%85%87</guid>
            <pubDate>Tue, 14 Jan 2025 03:02:11 GMT</pubDate>
            <description><![CDATA[<p>학원이 끝나고 코테만 풀고 있다가 프로젝트 제안을 받았다. 공부가 더 필요했던 리액트를 사용한다 그래서 잘됐다 싶었다. 한달동안하는 작은 프로젝트가 될 것 같지만 열심히 해봐야겠다. 
<br/></p>
<p>현재까지 진행상황
spring boot와 react, oracle까지 연동이 된 상태이고 
백단은 카테고리별 상품조회, 추가 기능까지 구현되었다. 리액트도 처음 써보고 부트도 아직 익숙치 않아서 생각보다 오래 걸린것 같다. 
<img src="https://velog.velcdn.com/images/kimmin_ah/post/3449d071-561f-4fc3-b85e-2617a51da028/image.png" alt="상품 조회 페이지">
<img src="https://velog.velcdn.com/images/kimmin_ah/post/24ce85ec-b708-43c0-a744-aac564d95260/image.png" alt="">
특히나 리액트로 저 상세이미지 사진을 여러장 업로드하는 화면을 만든다고 좀 애썼다. 나중에 어떻게 짠건지도 적어봐야겠다.</p>
<p><img src="https://velog.velcdn.com/images/kimmin_ah/post/a445f1ca-c389-4f93-bc4a-f9a1fb9478e2/image.png" alt="">
이건 erd짠거!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[클래스와 객체_5]]></title>
            <link>https://velog.io/@kimmin_ah/%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EA%B0%9D%EC%B2%B45</link>
            <guid>https://velog.io/@kimmin_ah/%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EA%B0%9D%EC%B2%B45</guid>
            <pubDate>Tue, 14 Jan 2025 02:47:52 GMT</pubDate>
            <description><![CDATA[<p>this에 대해 자세히 알아보자</p>
<p>​</p>
<ul>
<li>this 가 하는 일</li>
</ul>
<p>자신의 인스턴스의 메모리를 가리킴</p>
<p>생성자에서 다른 생성자를 호출함</p>
<p>자신의 주소를 반환함</p>
<p>*참고로 이클립스에서 멤버변수는 다 파란색으로 표시 됨</p>
<p>​</p>
<p>-자신의 인스턴스의 메모리를 가리키는 this</p>
<pre><code>class Birthday{
    int day;   //멤버변수
    int month;
    int year;

    public void setYear(int year){
        this.year = year;     //여기서 this를 써야하는 이유 : this를 써야 멤버변수 year로 인식함
    }
    public void printThis() {
        System.out.println(this);    
    }
}</code></pre><p>주의할 점은 this.year 이 아니라 그냥 year로 쓰게 되면 파라미터 year로 인식된다. </p>
<p>​</p>
<p>​</p>
<p>​</p>
<ul>
<li>생성자에서 다른 생성자를 호출하는 this </li>
</ul>
<p>객체가 생성될 때 초기화 작업( 멤버변수 셋팅) 할 때 생성자에서 다른 생성자를 호출 할 때 this를 쓸 수 있다. </p>
<p>*여기서 생성자는 public Persin() {}</p>
<pre><code>class Person{
    String name;
    int age;

    public Person() {
        this(&quot;이름없음&quot;, 1);   //초기화
    }

    public Person(String name, int age) {
        this.name = name; 
        this.age = age;
    }
}

public class CallAnotherConst {
    public static void main(String[] args) {
        Person p1 = new Person();
        System.out.println(p1.name);
    }
}</code></pre><p> 예를들어 p1에 name = &quot;이름없음&quot;, age = 1  이라는 기본값 넣고싶음.</p>
<p>이때 Person() 생성자에서  Person(String name, int age) 생성자를 this로 호출하여 초기화를 한다는 뜻이다. </p>
<p>this쓰고 맞는 인자값을 괄호에 넣는다면 알아서 맞는 생성자와 매핑 시켜준다. </p>
<p>주의할 점은 &quot;생성자에서 생성자를 호출하는 this&quot;를 쓸 때는 생성자와 this사이에 다른 코드를 넣을 수 없다. </p>
<p>(Person() 생성자에서 다른 생성자를 호출 했을때 호출 한 생성자를 돌고 나서 Person() 생성자의 인스턴스가 생성되는데 다른 초기화가 이루어져 에러 발생할 수 있기 때문에 인듯 )</p>
<p>​</p>
<p>​</p>
<p>_ 자신의 주소를 반환하는 this</p>
<pre><code>class Person{
    String name;
    int age;

    public Person() {
        this(&quot;이름없음&quot;, 1);   //초기화
    }

    public Person(String name, int age) {
        this.name = name; 
        this.age = age;
    }

    public Person returnSelf() {
        return this;
    }
}
public (자신 클래스명) (메소드 이름)() {

        return this;

    }</code></pre><p>이렇게 하면 된다. 
[출처] 13. 클래스와 객체_5|작성자 콩꼼</p>
]]></description>
        </item>
    </channel>
</rss>