<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hee_ya.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sun, 04 May 2025 04:24:14 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. hee_ya.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hee_ya" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Set 인터페이스 정리]]></title>
            <link>https://velog.io/@hee_ya/Set-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@hee_ya/Set-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 04 May 2025 04:24:14 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-set-인터페이스란">📌 Set 인터페이스란?</h2>
<ul>
<li>순서가 중요하지 않은 요소를 다룰 때 주로 사용</li>
<li><code>Collection</code> 인터페이스의 하위 인터페이스</li>
<li><strong>중복을 허용하지 않음</strong></li>
<li>각 요소의 <strong>고유성</strong> 보장</li>
<li><code>null</code> 값 저장 가능 (단, 하나만)</li>
</ul>
<blockquote>
<p>요소의 정렬 여부는 구현체에 따라 다름:</p>
</blockquote>
<table>
<thead>
<tr>
<th>구현체</th>
<th>특징</th>
</tr>
</thead>
<tbody><tr>
<td><code>HashSet</code></td>
<td>순서 보장 X</td>
</tr>
<tr>
<td><code>LinkedHashSet</code></td>
<td><strong>삽입 순서</strong> 유지</td>
</tr>
<tr>
<td><code>TreeSet</code></td>
<td>자동 정렬 (오름차순 기본)</td>
</tr>
</tbody></table>
<hr>
<h2 id="🔷-주요-메소드">🔷 주요 메소드</h2>
<table>
<thead>
<tr>
<th>메소드</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>add(E e)</code></td>
<td>요소 추가 (이미 존재하면 추가 X)</td>
</tr>
<tr>
<td><code>remove(Object o)</code></td>
<td>요소 제거</td>
</tr>
<tr>
<td><code>contains(Object o)</code></td>
<td>존재 여부 확인</td>
</tr>
<tr>
<td><code>size()</code></td>
<td>요소 개수 반환</td>
</tr>
<tr>
<td><code>isEmpty()</code></td>
<td>비어 있는지 확인</td>
</tr>
<tr>
<td><code>clear()</code></td>
<td>모든 요소 제거</td>
</tr>
</tbody></table>
<hr>
<h2 id="📌-hashset">📌 HashSet</h2>
<ul>
<li><code>Set</code> 인터페이스의 대표 구현체</li>
<li>내부적으로 <strong>HashMap</strong>을 기반으로 동작</li>
<li><strong>순서 보장 X</strong></li>
<li><strong>중복 허용 X</strong>, <code>null</code> 저장 가능</li>
<li>해시 함수를 이용해 빠른 접근 (평균 시간 복잡도: O(1))</li>
</ul>
<h3 id="🔷-동작-원리">🔷 동작 원리</h3>
<ol>
<li><p><strong>hashCode() 값 계산</strong></p>
<ul>
<li>요소의 해시값을 이용해 배열의 인덱스를 결정</li>
<li>예: 배열 길이 5 → <code>hashCode % 5</code>로 저장 위치 결정</li>
</ul>
</li>
<li><p><strong>해시 충돌(Collision) 처리</strong></p>
<ul>
<li>같은 해시값 → 같은 버킷</li>
<li>Java 7까지는 <code>LinkedList</code>, Java 8부터는 일정 개수 초과 시 <strong>Red-Black Tree</strong>로 변환</li>
</ul>
</li>
<li><p><strong>equals()로 중복 여부 확인</strong></p>
<ul>
<li>해시값이 같더라도 <code>equals()</code>로 비교하여 <strong>정확한 중복 여부 판별</strong></li>
</ul>
</li>
<li><p><strong>저장</strong></p>
<ul>
<li><code>add()</code> 메소드는 내부적으로 <code>HashMap.put()</code> 사용</li>
</ul>
</li>
</ol>
<h3 id="💻-예제-코드">💻 예제 코드</h3>
<pre><code class="language-java">import java.util.HashSet;

public class Main {
    public static void main(String[] args) {
        HashSet&lt;String&gt; set = new HashSet&lt;&gt;();
        set.add(&quot;apple&quot;);
        set.add(&quot;banana&quot;);
        set.add(&quot;apple&quot;); // 중복 무시
        System.out.println(set); // [banana, apple] (순서 보장 X)
    }
}</code></pre>
<h3 id="🔷-hashset에서-객체를-저장할-때hashcode와-equals를-재정의해야-하는-이유">🔷 HashSet에서 객체를 저장할 때hashCode()와 equals()를 재정의해야 하는 이유</h3>
<p>Java에서 <code>HashSet</code>, <code>HashMap</code>, <code>Hashtable</code>과 같은 <strong>해시 기반 컬렉션</strong>은 객체를 저장하거나 검색할 때 내부적으로 <code>hashCode()</code>와 <code>equals()</code> 메소드를 사용</p>
<p>이 메소드들을 제대로 <strong>재정의하지 않으면</strong>, 중복 체크나 검색이 제대로 동작하지 않아 <strong>예상치 못한 결과</strong>를 낳을 수 있습니다.</p>
<hr>
<h4 id="🔶-hash-기반-컬렉션의-동작-원리">🔶 Hash 기반 컬렉션의 동작 원리</h4>
<ol>
<li><strong>객체의 <code>hashCode()</code>를 호출</strong>해서 저장할 <strong>버킷(bucket)</strong> 위치를 찾음</li>
<li>해당 버킷에 데이터가 존재하면, <strong><code>equals()</code>를 호출</strong>해서 <strong>동일 객체인지 비교</strong><ul>
<li><code>equals()</code> 결과가 true → 중복으로 판단하고 추가하지 않음</li>
<li>false → 같은 버킷에 저장 (해시 충돌 처리)</li>
</ul>
</li>
</ol>
<hr>
<h4 id="⚠️-재정의를-안-하면-생기는-문제">⚠️ 재정의를 안 하면 생기는 문제</h4>
<h5 id="❌-hashcode를-재정의하지-않은-경우">❌ <code>hashCode()</code>를 재정의하지 않은 경우</h5>
<pre><code class="language-java">class Person {
    String name;

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

    @Override
    public boolean equals(Object o) {
        if (o instanceof Person) {
            return this.name.equals(((Person) o).name);
        }
        return false;
    }

    // hashCode()를 재정의하지 않음
}

public class Main {
    public static void main(String[] args) {
        HashSet&lt;Person&gt; set = new HashSet&lt;&gt;();
        set.add(new Person(&quot;Alice&quot;));
        set.add(new Person(&quot;Alice&quot;)); // 서로 다른 객체지만 equals는 true → hashCode는 달라서 다른 버킷에 저장됨
        System.out.println(set.size()); // 출력: 2
    }
}</code></pre>
<h5 id="✅--재정의-한-경우">✅  재정의 한 경우</h5>
<pre><code class="language-java">class Person {
    String name;

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

    @Override
    public boolean equals(Object o) {
        if (o instanceof Person) {
            return this.name.equals(((Person) o).name);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return name.hashCode(); // 문자열의 hashCode 사용
    }
}

public class Main {
    public static void main(String[] args) {
        HashSet&lt;Person&gt; set = new HashSet&lt;&gt;();
        set.add(new Person(&quot;Alice&quot;));
        set.add(new Person(&quot;Alice&quot;)); // equals와 hashCode 모두 같음 → 중복으로 인식
        System.out.println(set.size()); // 출력: 1
    }
}</code></pre>
<hr>
<h2 id="📌-treeset">📌 TreeSet</h2>
<ul>
<li><code>Set</code> 인터페이스를 구현한 클래스 중 하나로 <strong>중복을 허용하지 않으며</strong>, 요소를 <strong>자동 정렬</strong>함</li>
<li>내부적으로 <code>TreeMap</code>을 기반으로 동작</li>
<li><strong>이진 탐색 트리(Binary Search Tree)</strong>의 일종인 <strong>Red-Black Tree</strong> 구조를 사용</li>
<li>기본 정렬은 오름차순</li>
<li>사용자 정의 정렬을 위해 <code>Comparator</code> 사용 가능</li>
<li>성능: <strong>검색, 삽입, 삭제 O(log N)</strong></li>
</ul>
<h3 id="🔷-특징">🔷 특징</h3>
<ul>
<li>중복 X, 정렬 O, 순서 O (정렬된 순서)</li>
<li>삽입과 삭제가 많고, 정렬이 필요한 경우에 적합</li>
</ul>
<h3 id="💻-예제-코드-1">💻 예제 코드</h3>
<pre><code class="language-java">import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        TreeSet&lt;Integer&gt; set = new TreeSet&lt;&gt;();
        set.add(30);
        set.add(10);
        set.add(20);
        System.out.println(set); // [10, 20, 30] (자동 오름차순 정렬)
    }
}</code></pre>
<hr>
<h2 id="📌-linkedhashset">📌 LinkedHashSet</h2>
<ul>
<li><code>Set</code> 인터페이스를 구현한 클래스 중 하나</li>
<li><strong>중복을 허용하지 않으면서 삽입 순서를 유지</strong>함</li>
<li>내부적으로 <code>LinkedHashMap</code>을 기반으로 동작</li>
<li><strong>정렬 기능은 없음</strong> (순서만 유지, TreeSet과 다름)</li>
</ul>
<h3 id="🔷-특징-1">🔷 특징</h3>
<ul>
<li>중복 X, 순서 O, 정렬 X</li>
<li>순서를 유지하고 싶지만 정렬은 필요 없는 경우에 적합</li>
</ul>
<h3 id="💻-예제-코드-2">💻 예제 코드</h3>
<pre><code class="language-java">import java.util.LinkedHashSet;

public class Main {
    public static void main(String[] args) {
        LinkedHashSet&lt;String&gt; set = new LinkedHashSet&lt;&gt;();
        set.add(&quot;B&quot;);
        set.add(&quot;A&quot;);
        set.add(&quot;C&quot;);
        System.out.println(set); // [B, A, C] - 입력한 순서 그대로 출력
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[ArrayList와 LinkedList 정리]]></title>
            <link>https://velog.io/@hee_ya/ArrayList%EC%99%80-LinkedList-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@hee_ya/ArrayList%EC%99%80-LinkedList-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sat, 03 May 2025 14:41:16 GMT</pubDate>
            <description><![CDATA[<p>Java에서 <strong>순서가 있는 데이터 집합</strong>을 다룰 때 가장 많이 사용하는 인터페이스는 <code>List</code>입니다. 이 글에서는 <code>List</code> 인터페이스의 개념부터 주요 구현 클래스인 <code>ArrayList</code>, <code>LinkedList</code>, <code>Vector</code>까지 정리해보겠습니다.</p>
<hr>
<h2 id="📌-list-인터페이스란">📌 List 인터페이스란?</h2>
<ul>
<li><code>Collection</code> 인터페이스의 <strong>하위 인터페이스</strong></li>
<li><strong>중복된 요소</strong>를 저장할 수 있음</li>
<li><strong>요소의 삽입 순서를 유지</strong></li>
<li>인덱스를 사용하여 요소에 접근 가능</li>
<li>저장된 데이터의 양에 따라 <strong>자동으로 크기가 조절</strong></li>
</ul>
<hr>
<h2 id="📌-주요-메서드">📌 주요 메서드</h2>
<table>
<thead>
<tr>
<th>메서드</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>add(E e)</code></td>
<td>리스트 끝에 요소 추가</td>
</tr>
<tr>
<td><code>add(int index, E element)</code></td>
<td>특정 위치에 요소 삽입</td>
</tr>
<tr>
<td><code>remove(int index)</code></td>
<td>특정 인덱스의 요소 삭제</td>
</tr>
<tr>
<td><code>get(int index)</code></td>
<td>특정 인덱스의 요소 반환</td>
</tr>
<tr>
<td><code>set(int index, E element)</code></td>
<td>특정 인덱스의 요소 수정</td>
</tr>
<tr>
<td><code>indexOf(Object o)</code></td>
<td>주어진 요소가 처음 등장하는 인덱스 반환</td>
</tr>
<tr>
<td><code>subList(int fromIndex, int toIndex)</code></td>
<td>지정된 범위의 부분 리스트 반환</td>
</tr>
</tbody></table>
<hr>
<h2 id="📌-주요-구현체">📌 주요 구현체</h2>
<h3 id="1-arraylist">1. ArrayList</h3>
<ul>
<li>내부적으로 <strong>배열</strong>을 기반으로 구현</li>
<li>요소 접근 속도가 빠름 (O(1))</li>
<li>삽입/삭제는 느릴 수 있음 (중간 요소 이동 필요)</li>
</ul>
<h3 id="2-linkedlist">2. LinkedList</h3>
<ul>
<li><strong>노드(Node)</strong> 기반으로 구현 (연결 리스트)</li>
<li>요소 삽입/삭제가 빠름 (특히 앞/뒤)</li>
<li>요소 접근은 느림 (O(N))</li>
</ul>
<h3 id="3-vector">3. Vector</h3>
<ul>
<li><code>ArrayList</code>와 유사하지만, <strong>동기화(synchronized)</strong> 지원  </li>
<li>멀티스레드 환경에서 안전하지만 성능 저하 우려</li>
</ul>
<hr>
<h2 id="📌-arraylist">📌 ArrayList</h2>
<h3 id="🔍-특징">🔍 특징</h3>
<ul>
<li>내부적으로 <strong>동적 배열</strong>을 사용</li>
<li>처음에는 일정 크기로 시작, 꽉 차면 크기를 자동 확장</li>
<li><strong>중복 요소 허용</strong>, <strong>삽입 순서 유지</strong></li>
</ul>
<h3 id="✅-장점">✅ 장점</h3>
<ul>
<li><strong>빠른 접근 속도</strong> → O(1)</li>
<li>자동 크기 확장</li>
<li>인덱스를 통한 직관적인 요소 접근</li>
</ul>
<h3 id="❌-단점">❌ 단점</h3>
<ul>
<li>중간 요소 삭제 시 <strong>모든 요소를 이동해야 함</strong> → O(N)</li>
</ul>
<h3 id="💻-예제-코드">💻 예제 코드</h3>
<pre><code class="language-java">import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList&lt;String&gt; list = new ArrayList&lt;&gt;();
        list.add(&quot;Apple&quot;);
        list.add(&quot;Banana&quot;);
        list.add(1, &quot;Orange&quot;); // 인덱스 1에 삽입
        list.remove(&quot;Banana&quot;); // Banana 삭제
        System.out.println(list.get(0)); // Apple
        System.out.println(list); // [Apple, Orange]
    }
}</code></pre>
<hr>
<h2 id="📌-linkedlist">📌 LinkedList</h2>
<h3 id="🔍-특징-1">🔍 특징</h3>
<ul>
<li><code>LinkedList</code>는 자료구조인 <strong>연결 리스트(Linked List)</strong>를 기반으로 구현된 <code>List</code>의 구현체입니다.</li>
<li>각 요소는 <strong>노드(Node)</strong>로 구성되며, 데이터와 <strong>다음 노드에 대한 참조(링크)</strong>를 포함합니다.</li>
<li><strong>순차적인 인덱스를 사용하는 배열과 달리</strong>, 메모리 공간이 연속적이지 않아도 되며, 삽입 및 삭제에 유리합니다.</li>
</ul>
<h3 id="✅-장점-1">✅ 장점</h3>
<ul>
<li><strong>빠른 삽입/삭제</strong><br>리스트 앞이나 뒤에서의 삽입/삭제는 O(1)의 시간 복잡도를 가짐</li>
<li><strong>동적 크기 조정</strong><br>배열처럼 크기를 미리 지정할 필요가 없음</li>
<li><strong>양방향 연결 리스트</strong><br>앞뒤 요소 탐색이 모두 가능 (<code>LinkedList</code>는 <code>Doubly Linked List</code>)</li>
</ul>
<h3 id="❌-단점-1">❌ 단점</h3>
<ul>
<li><strong>느린 요소 접근 속도</strong><br>인덱스를 사용해 접근할 경우, 처음부터 순차 탐색해야 하므로 O(N)</li>
<li><strong>더 많은 메모리 사용</strong><br>각 노드가 데이터와 함께 이전/다음 노드 참조 정보를 함께 저장</li>
</ul>
<h3 id="💻-예제-코드-1">💻 예제 코드</h3>
<pre><code class="language-java">import java.util.LinkedList;

public class Main {
    public static void main(String[] args) {
        LinkedList&lt;String&gt; list = new LinkedList&lt;&gt;();
        list.add(&quot;Dog&quot;);
        list.add(&quot;Cat&quot;);
        list.addFirst(&quot;Tiger&quot;); // 맨 앞에 삽입
        list.removeLast();      // 맨 뒤 요소 삭제
        System.out.println(list); // [Tiger, Dog]
    }
}</code></pre>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java 문법 정리]]></title>
            <link>https://velog.io/@hee_ya/Java-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@hee_ya/Java-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 09 Mar 2025 08:38:46 GMT</pubDate>
            <description><![CDATA[<h2 id="1-변수와-자료형">1. 변수와 자료형</h2>
<ul>
<li><p>변수 : 데이터를 저장하기 위한 메모리 공간</p>
</li>
<li><p>상수 </p>
<ul>
<li>상수는 최초 초기화 후 값을 재정의 할 수 없음</li>
<li>static final 키워드 사용</li>
</ul>
</li>
<li><p>변수명 규칙</p>
<ul>
<li>대소문자 구분</li>
<li>길이제한 없음</li>
<li>숫자로 시작할 수 없음</li>
<li>특수문자는 &quot;_, $&quot; 만 허용</li>
<li>변수명에 공백 X</li>
<li>예약어 사용 금지</li>
</ul>
</li>
<li><p>기본 자료형</p>
<ul>
<li>정수형 : byte, short, int, long</li>
<li>실수형 : float, double</li>
<li>논리형 : boolean</li>
<li>문자형 : char (한 개로 이루어진 문자)</li>
</ul>
</li>
<li><p>래퍼런스 타입(Reference Type) : 자바에서 변수에 저장되는 값이 기본 자료형의 값이 아닌, 객체나 주소(참조)인 데이터 타입이며,실제 데이터는 힙(Heap) 메모리 공간에 저장된다.</p>
<ul>
<li>String, Array, Class, Interface, Object, Enum, 사용자 정의 객체 등</li>
<li>박싱 (boxing) : 기본 자료형의 값을 래퍼런스 타입으로 변환하는 과정</li>
<li>언박싱 (unboxing) : 반대로 래퍼런스 타입을 기본 자료형으로 변환하는 과정</li>
<li>Java5 이후부터는 명시적으로 변환하지 않아도 자동 변환되는 오토박싱과 오토언박싱을 지원함</li>
</ul>
</li>
<li><p>기본 자료형과 래퍼런스 타입의 차이점</p>
</li>
</ul>
<table>
<thead>
<tr>
<th><strong>특징</strong></th>
<th><strong>기본 자료형 (Primitive Types)</strong></th>
<th><strong>래퍼런스 타입 (Reference Types)</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>저장 값</strong></td>
<td>값 자체</td>
<td>객체의 메모리 주소 (참조)</td>
</tr>
<tr>
<td><strong>메모리 위치</strong></td>
<td>스택 (Stack)</td>
<td>힙 (Heap)</td>
</tr>
<tr>
<td><strong>크기</strong></td>
<td>고정 크기</td>
<td>객체 크기는 가변적, 참조는 일정 크기</td>
</tr>
<tr>
<td><strong>값 변경</strong></td>
<td>다른 변수에 할당하면 값만 복사</td>
<td>객체를 참조하면 값이 공유될 수 있음</td>
</tr>
<tr>
<td><strong>예시</strong></td>
<td><code>int</code>, <code>boolean</code>, <code>char</code>, <code>float</code></td>
<td><code>String</code>, <code>Array</code>, <code>Object</code>, <code>Class</code></td>
</tr>
</tbody></table>
<h2 id="2-연산자">2. 연산자</h2>
<ul>
<li>연산자 : 프로그램에서 연산을 위해 사용하는 기호를 연산자(Operator)라고 한다. 자바에서 사용하는 <strong>연산자(Operators)</strong>는 크게 <strong>산술 연산자</strong>, <strong>비교 연산자</strong>, <strong>논리 연산자</strong>, <strong>대입 연산자</strong>, <strong>비트 연산자</strong> 등 여러 종류로 나눌 수 있다</li>
</ul>
<h3 id="2-1-산술-연산자-arithmetic-operators">2-1. 산술 연산자 (Arithmetic Operators)</h3>
<p>산술 연산자는 수학적인 계산을 수행할 때 사용된다.</p>
<table>
<thead>
<tr>
<th>연산자</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>+</code></td>
<td>덧셈</td>
<td><code>a + b</code></td>
</tr>
<tr>
<td><code>-</code></td>
<td>뺄셈</td>
<td><code>a - b</code></td>
</tr>
<tr>
<td><code>*</code></td>
<td>곱셈</td>
<td><code>a * b</code></td>
</tr>
<tr>
<td><code>/</code></td>
<td>나눗셈</td>
<td><code>a / b</code></td>
</tr>
<tr>
<td><code>%</code></td>
<td>나머지(모듈러)</td>
<td><code>a % b</code></td>
</tr>
</tbody></table>
<h3 id="2-2-비교-연산자-comparison-operators">2-2. 비교 연산자 (Comparison Operators)</h3>
<p>비교 연산자는 두 값을 비교하고, 결과를 <strong>불리언</strong> 값 (<code>true</code> 또는 <code>false</code>)으로 반환한다.</p>
<table>
<thead>
<tr>
<th>연산자</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>==</code></td>
<td>두 값이 같으면 <code>true</code> 반환</td>
<td><code>a == b</code></td>
</tr>
<tr>
<td><code>!=</code></td>
<td>두 값이 다르면 <code>true</code> 반환</td>
<td><code>a != b</code></td>
</tr>
<tr>
<td><code>&gt;</code></td>
<td>왼쪽 값이 더 크면 <code>true</code></td>
<td><code>a &gt; b</code></td>
</tr>
<tr>
<td><code>&lt;</code></td>
<td>왼쪽 값이 더 작으면 <code>true</code></td>
<td><code>a &lt; b</code></td>
</tr>
<tr>
<td><code>&gt;=</code></td>
<td>왼쪽 값이 크거나 같으면 <code>true</code></td>
<td><code>a &gt;= b</code></td>
</tr>
<tr>
<td><code>&lt;=</code></td>
<td>왼쪽 값이 작거나 같으면 <code>true</code></td>
<td><code>a &lt;= b</code></td>
</tr>
</tbody></table>
<h3 id="2-3-논리-연산자-logical-operators">2-3. 논리 연산자 (Logical Operators)</h3>
<p>논리 연산자는 두 개 이상의 조건을 결합하여 결과를 <code>true</code> 또는 <code>false</code>로 반환한다.</p>
<table>
<thead>
<tr>
<th>연산자</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>&amp;&amp;</code></td>
<td>AND 연산 (두 조건이 모두 <code>true</code>일 때 <code>true</code>)</td>
<td><code>a &gt; 0 &amp;&amp; b &lt; 10</code></td>
</tr>
<tr>
<td>`</td>
<td></td>
<td>`</td>
</tr>
<tr>
<td><code>!</code></td>
<td>NOT 연산 (조건이 <code>true</code>면 <code>false</code>로, <code>false</code>면 <code>true</code>로 바꿈)</td>
<td><code>!a</code></td>
</tr>
</tbody></table>
<h3 id="2-4-대입-연산자-assignment-operators">2-4. 대입 연산자 (Assignment Operators)</h3>
<p>대입 연산자는 변수에 값을 할당하는 데 사용된다.</p>
<table>
<thead>
<tr>
<th>연산자</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>=</code></td>
<td>오른쪽 값을 왼쪽 변수에 할당</td>
<td><code>a = b</code></td>
</tr>
<tr>
<td><code>+=</code></td>
<td>더한 값을 대입</td>
<td><code>a += b</code> (a = a + b)</td>
</tr>
<tr>
<td><code>-=</code></td>
<td>뺀 값을 대입</td>
<td><code>a -= b</code> (a = a - b)</td>
</tr>
<tr>
<td><code>*=</code></td>
<td>곱한 값을 대입</td>
<td><code>a *= b</code> (a = a * b)</td>
</tr>
<tr>
<td><code>/=</code></td>
<td>나눈 값을 대입</td>
<td><code>a /= b</code> (a = a / b)</td>
</tr>
<tr>
<td><code>%=</code></td>
<td>나머지 값을 대입</td>
<td><code>a %= b</code> (a = a % b)</td>
</tr>
</tbody></table>
<h3 id="2-5-비트-연산자-bitwise-operators">2-5. 비트 연산자 (Bitwise Operators)</h3>
<p>비트 연산자는 이진수 단위로 비트 연산을 수행한다.</p>
<table>
<thead>
<tr>
<th>연산자</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>&amp;</code></td>
<td>비트 AND 연산</td>
<td><code>a &amp; b</code></td>
</tr>
<tr>
<td>`</td>
<td>`</td>
<td>비트 OR 연산</td>
</tr>
<tr>
<td><code>^</code></td>
<td>비트 XOR 연산</td>
<td><code>a ^ b</code></td>
</tr>
<tr>
<td><code>~</code></td>
<td>비트 NOT 연산 (비트 반전)</td>
<td><code>~a</code></td>
</tr>
<tr>
<td><code>&lt;&lt;</code></td>
<td>왼쪽으로 비트 시프트</td>
<td><code>a &lt;&lt; 2</code></td>
</tr>
<tr>
<td><code>&gt;&gt;</code></td>
<td>오른쪽으로 비트 시프트</td>
<td><code>a &gt;&gt; 2</code></td>
</tr>
</tbody></table>
<h3 id="2-6-증감-연산자-increment-and-decrement-operators">2-6. 증감 연산자 (Increment and Decrement Operators)</h3>
<p>증감 연산자는 변수를 1만큼 증가시키거나 감소시킬 때 사용된다.</p>
<table>
<thead>
<tr>
<th>연산자</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>++</code></td>
<td>1만큼 증가 (후위/전위)</td>
<td><code>a++</code>, <code>++a</code></td>
</tr>
<tr>
<td><code>--</code></td>
<td>1만큼 감소 (후위/전위)</td>
<td><code>a--</code>, <code>--a</code></td>
</tr>
</tbody></table>
<h3 id="2-7-삼항-연산자-ternary-operator">2-7. 삼항 연산자 (Ternary Operator)</h3>
<p>삼항 연산자는 조건에 따라 두 값을 선택하는 간단한 조건문이다.</p>
<table>
<thead>
<tr>
<th>연산자</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><code>? :</code></td>
<td>조건식이 <code>true</code>이면 첫 번째 값, <code>false</code>이면 두 번째 값 반환</td>
<td>`a &gt; b</td>
</tr>
</tbody></table>
<h2 id="3-조건문">3. 조건문</h2>
<p>조건문은 프로그램의 흐름을 제어하고 특정 조건에 따라 다른 코드를 실행하게 해주는 구문을 말한다.</p>
<h3 id="3-1-if문">3-1. if문</h3>
<p><code>if</code> 문은 주어진 조건이 <code>true</code>일 때 특정 코드를 실행한다. 조건이 <code>false</code>일 경우에는 실행되지 않는다.</p>
<pre><code class="language-java">if (조건) {
    // 조건이 true일 때 실행되는 코드
}</code></pre>
<h3 id="3-2-else-if-문">3-2. else if 문</h3>
<p><code>else if</code> 문은 여러 개의 조건을 검사하고, 그 중 첫 번째로 참인 조건을 실행한다. 모든 조건이 거짓일 경우, <code>else</code> 블록이 실행된다.</p>
<pre><code class="language-java">if (조건1) {
    // 조건1이 true일 때 실행되는 코드
} else if (조건2) {
    // 조건2가 true일 때 실행되는 코드
} else {
    // 모든 조건이 false일 때 실행되는 코드
} </code></pre>
<h3 id="3-3-switch-문">3-3. switch 문</h3>
<p><code>switch</code> 문은 여러 가지 조건 중에서 하나를 선택하는데 유용한 조건문이다. <code>switch</code> 문은 조건이 여러 개일 때 더 깔끔하게 작성할 수 있다.</p>
<pre><code class="language-java">switch (변수) {
    case 값1:
        // 변수의 값이 값1일 때 실행되는 코드
        break;
    case 값2:
        // 변수의 값이 값2일 때 실행되는 코드
        break;
    default:
        // 변수의 값이 어떤 case와도 일치하지 않을 때 실행되는 코드
}</code></pre>
<h3 id="3-4-break-continue">3-4. break, continue</h3>
<ul>
<li>break: 반복문에서 조건을 만족하면 즉시 반복을 종료하여 벗어난다.</li>
<li>continue: 반복문에서 조건을 만족하면 해당 반복을 건너뛰고 다음 반복으로 넘어간다.</li>
</ul>
<h2 id="4-반복문">4. 반복문</h2>
<p>반복문은 특정 조건이 참일 동안 특정 코드 블록을 반복적으로 실행한다.</p>
<h3 id="4-1-for-문">4-1. for 문</h3>
<p><code>for</code>문은 중복된 코드를 특정 횟수만큼 반복할 때 사용한다. <code>(초기값, 조건값, 증감식)</code>으로 구성되어 있다.</p>
<pre><code class="language-java">for (int i = 0; i &lt; 5; i++) {
    System.out.println(&quot;i : &quot; + i);
}</code></pre>
<h3 id="4-2-while-문">4-2. while 문</h3>
<p><code>while</code>문은 주어진 조건이 <code>true</code>일 때 계속 반복한다. 반복 전에 조건을 먼저 검사하고 조건이 <code>false</code>이면 반복문을 종료한다.</p>
<pre><code class="language-java">int i = 0;
while (i &lt; 5) {
    System.out.println(&quot;i : &quot; + i);
    i++;
}</code></pre>
<h3 id="4-3-do-while-문">4-3. do-while 문</h3>
<p><code>do-while</code>문은 반목문을 최소 한번 실행한 후 조건을 검사한다. 즉, 조건이 <code>false</code>일지라도 코드 블록이 한번은 실행된다.</p>
<pre><code class="language-java">int i = 0;
do {
    System.out.println(&quot;i의 값: &quot; + i);
    i++;
} while (i &lt; 5);</code></pre>
<h2 id="5-배열">5. 배열</h2>
<p>배열은 동일한 데이터 타입의 값을 여러 개 저장할 수 있는 데이터 구조이다. 자바에서 배열은 고정 크기를 가지며, 인덱스를 통해 배열의 각 요소에 접근할 수 있다.</p>
<h3 id="5-1-배열-선언">5-1. 배열 선언</h3>
<p>배열을 선언할 때는 배열의 데이터 타입을 먼저 지정하고, 그 뒤에 대괄호 <code>[]</code>를 붙여 배열임을 명시합니다.</p>
<pre><code class="language-java">타입[] 배열명;
// ex
int[] numbers;
String[] names;</code></pre>
<h3 id="5-2-배열-생성">5-2. 배열 생성</h3>
<p>배열의 크기는 생성시에 지정되며, 배열 크기는 고정되어 변경할 수 없다.</p>
<pre><code class="language-java">배열명 = new 타입[크기];
// ex
numbers = new int[5];  // 크기가 5인 정수형 배열 생성
names = new String[3]; // 크기가 3인 문자열 배열 생성</code></pre>
<h3 id="5-3-배열-초기화">5-3. 배열 초기화</h3>
<p>배열을 선언과 동시에 값을 초기화 할 수 있다. 배열을 초기화할 때는 대괄호 안에 값을 넣는다.</p>
<pre><code class="language-java">타입[] 배열명 = {값1, 값2, 값3, ...};
// ex
int[] numbers = {1, 2, 3, 4, 5};  // 크기가 5인 배열 초기화
String[] names = {&quot;John&quot;, &quot;Jane&quot;, &quot;Tom&quot;};  // 크기가 3인 배열 초기화</code></pre>
<h3 id="5-4-배열-값-접근">5-4. 배열 값 접근</h3>
<p>배열 값은 인덱스를 사용하여 접근한다. 배열의 인덱스는 0부터 시작한다.</p>
<pre><code class="language-java">int[] numbers = {1, 2, 3, 4, 5};
System.out.println(numbers[0]);  // 첫 번째 요소 출력 -&gt; 1
System.out.println(numbers[3]);  // 네 번째 요소 출력 -&gt; 4</code></pre>
<h3 id="5-5-다차원-배열">5-5. 다차원 배열</h3>
<pre><code class="language-java">타입[][] 배열명;
배열명 = new 타입[행의 수][열의 수];

// ex
int[][] matrix = new int[3][3];  // 3x3 배열 생성
matrix[0][0] = 1;  // 첫 번째 행 첫 번째 열에 값 1 할당
matrix[2][2] = 9;  // 세 번째 행 세 번째 열에 값 9 할당</code></pre>
<h2 id="6-클래스-class">6. 클래스 (Class)</h2>
<p>객체를 생성하기 위한 설계도로 변수, 생성자와 메소드로 구성되어있다. 객체 지향 프로그래밍(OOP)의 기본 단위이며, 클래스를 사용하여 객체를 생성하고 해당 객체가 수행할 동작을 정의할 수 있다.</p>
<ul>
<li><p>클래스가 필요한 이유</p>
<ul>
<li>데이터 관리의 효율성</li>
<li>코드의 재사용성</li>
<li>데이터 보호 (캡슐화)</li>
<li>코드의 구조화</li>
</ul>
</li>
</ul>
<h3 id="6-1-클래스-선언">6-1. 클래스 선언</h3>
<p>클래스를 선언할 때는 <code>class</code> 키워드를 사용하여 클래스 이름 지정한다. 클래스 이름은 각 단어의 첫 글자를 대문자(파스칼 케이스)로 사용한다. </p>
<pre><code class="language-java">public class 클래스명 {
    // 필드 (변수)
    // 메서드
}</code></pre>
<h3 id="6-2-클래스의-변수">6-2. 클래스의 변수</h3>
<ul>
<li><p>인스턴스 변수</p>
<ul>
<li>객체마다 가지는 고유한 값</li>
<li>객체 생성 시에만 사용 가능</li>
</ul>
</li>
<li><p>static 변수</p>
<ul>
<li>모든 객체가 공유하는 값</li>
<li>객체 생성 없이도 사용 가능</li>
</ul>
</li>
<li><p>상수</p>
<ul>
<li>한 번 값이 정해지면 변경 불가능</li>
<li>보통 static과 함께 사용</li>
</ul>
</li>
</ul>
<h3 id="6-3-생성자">6-3. 생성자</h3>
<ul>
<li><p>생성자</p>
<ul>
<li>객체가 생성될 때 자동으로 호출되는 특별한 메소드</li>
<li>객체의 초기화를 담당</li>
<li>클래스명과 동일한 이름을 가짐</li>
</ul>
</li>
<li><p>기본 생성자</p>
<ul>
<li>클래스에 생성자가 없으면 자동으로 생성</li>
</ul>
</li>
<li><p>매개변수가 있는 생성자</p>
<ul>
<li><p>객체 생성시 초기값을 전달 받음</p>
<pre><code class="language-java">public class Car {
// 필드 (변수)

// 1. 기본 생성자
public Car() {}

// 2. 매개변수가 있는 생성자
public Car(String modelName, int price){
this.modelName = modelName;
this.price = price;
}
}</code></pre>
<h3 id="6-4-메소드">6-4. 메소드</h3>
</li>
</ul>
</li>
<li><p>인스턴스 메소드</p>
<ul>
<li>객체를 생성해야만 사용할 수 있는 메소드</li>
</ul>
</li>
<li><p>static 메소드</p>
<ul>
<li><p>객체 생성 없이 클래스만으로도 호출 가능한 메소드</p>
</li>
<li><p>인스턴스 변수를 사용할 수 없음</p>
<pre><code class="language-java">public class Car {
String modelName;
int price;

// 1. 인스턴스 메소드
void printPrice(String modelName, int price){
  System.out.println(modelName + &quot;의 가격은 &quot; + price + &quot;원 입니다&quot;.
}
// 2. static 메소드
static void printPrice(String modelName, int price){
  System.out.println(modelName + &quot;의 가격은 &quot; + price + &quot;원 입니다&quot;.
}
}</code></pre>
<h3 id="6-5-객체-생성">6-5. 객체 생성</h3>
<p>클래스를 정의한 후 <code>new</code> 키워드를 사용하여 객체를 생성할 수 있다. 각 객체는 독립적인 메모리 공간을 가지면 같은 클래스로 만들어도 서로 다른 객체는 독립적이다.</p>
<pre><code class="language-java">클래스명 객체명 = new 클래스명();
// ex
Car myCar = new Car(); </code></pre>
</li>
</ul>
</li>
</ul>
<h3 id="6-6-접근제어자">6-6. 접근제어자</h3>
<h4 id="6-6-1-클래스의-접근제어자">6-6-1. 클래스의 접근제어자</h4>
<p>클래스를 정의할 때 <code>public</code> 와 <code>deafult</code> 두 가지 접근제어자를 사용할 수 있다.</p>
<ul>
<li><code>public</code> : <code>public</code> 을 사용하면, 모든 클래스에서 이 패키지 상관없이 클래스에 접근이 가능함 </li>
<li><code>default</code> : 같은 패키지 안에 클래스만 접근이 가능함</li>
</ul>
<h4 id="6-6-2-클래스-멤버의-접근제어자">6-6-2. 클래스 멤버의 접근제어자</h4>
<ul>
<li><code>public</code> 멤버 : 모든 클래스에서 접근 가능 </li>
<li><code>private</code> 멤버 : 같은 클래스안에 있는 멤버만 접근 가능</li>
<li><code>protected</code> 멤버 : 같은 패키지 안의 멤버, 다른 패키지의 자식 클래스 멤버만 접근 가능</li>
<li><code>default</code> 멤버 : 같은 패키지 안에 클래스 멤버만 접근이 가능함</li>
</ul>
<h2 id="7-상속">7. 상속</h2>
<p>부모 클래스의 기능을 자식 클래스가 물려받아 코드를 재사용하고 확장할 수 있는 개념이다. 객체지향의 핵심 기법으로 코드의 재사용성을 높이고 상속을 통해 클래스 간의 계층적 구조를 설계할 수 있다.</p>
<pre><code class="language-java">public class Animal {
}

public class Dog extends Animal{
}</code></pre>
<h3 id="7-1-super와-this-키워드">7-1. super와 this 키워드</h3>
<p><code>super</code> 키워드를 통해 부모 클래스의 기능을 참조할 수 있다. 만약 생성자에서 호출할 때는 가장 먼저 호출해야한다. </p>
<pre><code class="language-java">public class Animal {
    Streing name;

    Animal(String name){
        this.name = name;
    }
}

public class Dog extends Animal{
    String breed;

    Dog(String name, String breed){
        super(name); // 부모 생성자 호출
        this.breed = breed;
    }
}</code></pre>
<p><code>this</code> 키워드는 자기 자신의 멤버(필드 , 메소드)를 참조할 때 사용한다.</p>
<pre><code class="language-java">public class Animal {
    Streing name;

    // 기본 생성자
    Animal(){
        this(&quot;하늘이&quot;); // 다른 생성자 호출
    }

    // 생성자
    Animal(String name){
        this.name = name;
    }
}</code></pre>
<h3 id="7-2-메소드-오버로딩-method-overloading">7-2. 메소드 오버로딩 (Method Overloading)</h3>
<p>메소드 오버로딩은 같은 클래스 내에서 같은 이름의 메소드를 여러 개 정의하는 것이다. 매개변수의 타입, 개수, 순서를 다르게 하여 구분할 수 있다.</p>
<pre><code class="language-java">class Calculator{
    int add(int a, int b){
        return a + b;
    }
    double add(double a, double b){
        return a + b;
    }
}</code></pre>
<h3 id="7-3-메소드-오버라이딩-method-overriding">7-3. 메소드 오버라이딩 (Method Overriding)</h3>
<p>메소드 오버라이딩은 부모 클래스의 메소드를 자식 클래스에서 재정의하는 것을 말한다. 부모의 메소드를 자식 클래스에 맞게 수정해서 사용한다.</p>
<pre><code class="language-java">public class Animal {
    void sound(){
        System.out.println(&quot;동물 소리&quot;);
    }
}

public class Dog extends Animal{
    @Override
    void sound(){
        System.out.println(&quot;멍멍!&quot;);
    }
}</code></pre>
<h2 id="8-다형성-polymorphism">8. 다형성 (Polymorphism)</h2>
<p>다형성은 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 말한다. 다형성을 활용하면 부모 타입 참조 변수로 자식 객체를 참조할 수 있다.</p>
<ul>
<li><p>장점</p>
<ul>
<li>코드의 유연성 증가</li>
<li>재사용성 향상</li>
<li>유지보수 용이</li>
</ul>
</li>
</ul>
<pre><code class="language-java">public class Animal {
    void sound(){
        System.out.println(&quot;동물 소리&quot;);
    }
}

public class Dog extends Animal{
    @Override
    void sound(){
        System.out.println(&quot;멍멍!&quot;);
    }
}

public class Main{
    public static void main(String[] args){
        Animal dog = new Dog(); // 개 객체를 동물 타입으로 참조
    }</code></pre>
<h3 id="8-1-업캐스팅-upcasting">8-1. 업캐스팅 (Upcasting)</h3>
<p>객체의 업캐스팅은 자식 객체를 부모 타입으로 변환하는 것을 말한다. 업캐스팅은 자동으로 변환된다. (묵시적 형변환)</p>
<pre><code class="language-java">Animal dog = new Dog(); </code></pre>
<h3 id="8-2-다운캐스팅-downcasting">8-2. 다운캐스팅 (Downcasting)</h3>
<p>객체의 다운캐스팅은 부모 타입을 자식 타입으로 변환하는 것을 말한다. 이 경우에는 명시적 형변환이 필요하다.</p>
<pre><code class="language-java">Animal animal = new Dog(); 
Dog dog = (Dog) animal;</code></pre>
<h2 id="9-추상-클래스-abstract-class">9. 추상 클래스 (Abstract Class)</h2>
<ul>
<li>추상은 객체의 공통 특징이나 속성을 추출하는 개념을 말한다. </li>
<li>추상화하는 과정은 복잡한 것을 단순화 하는 것이라고 볼 수 있다.</li>
<li>추상 클래스는 <code>abstract</code> 키우더를 사용해 생성할 수있다.</li>
<li>내부에는 생성자, 필드, 일반 메소드, 추상 메소드가 포함될 수 있다.</li>
<li><code>new</code> 연산자로 객체를 생성할 수 없으며 자식 클래스에서 추상 클래스의 기능을 필수로 구현해야 한다.</li>
</ul>
<h3 id="9-1-추상-메소드">9-1. 추상 메소드</h3>
<ul>
<li>추상 메소드는 추상 클래스를 상속 받은 자식 클래스가 필수로 구현해야하는 메소드이다.</li>
<li>공통 동작은 추상 클래스에서 직접 구현하며, 자식 클래스마다 세부 구현이 달라질 수 있으면 추상 메소드로 선언한다.</li>
</ul>
<h2 id="10-인터페이스-interface">10. 인터페이스 (Interface)</h2>
<p>객체의 동작을 표준화하는 기법을 인터페이스라고 한다. 추상 메소드와 상수만 가질 수 있다. <code>interface</code> 키워드로 인터페이스를 만들고 구현 클래스에 <code>implements</code> 키워드로 구현하고 싶은 인터페이스를 선언한다. </p>
<h4 id="인터페이스를-사용하는-이유">인터페이스를 사용하는 이유</h4>
<ul>
<li>표준화<ul>
<li>개발에 필요한 기본 틀 제공</li>
<li>개발자들 간의 일관성 있는 개발 가능</li>
</ul>
</li>
<li>다형성 구현<ul>
<li>하나의 인터페이스로 다양한 구현이 가능</li>
<li>객체 교체가 쉬움</li>
</ul>
</li>
<li>개발 독립성<ul>
<li>인터페이스만 정의되면 개발 시작 가능</li>
<li>다른 팀/개발자와 동시 개발 가능</li>
</ul>
</li>
<li>유연성<ul>
<li>기존 코드 변경 없이 새로운 기능 추가 가능<ul>
<li>독립적인 기능 구현 가능</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="language-java">public interface 인터페이스 이름{
    // 상수
    // 추상 메소드
    // default 메소드
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Java에 대해서 알아보자!]]></title>
            <link>https://velog.io/@hee_ya/Java%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@hee_ya/Java%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Sun, 09 Mar 2025 05:56:22 GMT</pubDate>
            <description><![CDATA[<p> <img src="https://velog.velcdn.com/images/hee_ya/post/4758b59f-940a-44ac-aae2-de35213e9e4b/image.png" alt="자바 로고"></p>
<h1 id="🔥-java의-역사">🔥 Java의 역사</h1>
<p>Java는 1991년 Sun Microsystems의 제임스 고슬링과 그의 팀이 개발한 프로그래밍 언어로 처음에 &quot;Oak(오크)&quot;라고 불렸다. Oak는 초기에 가전제품을 제어할 수 있는 언어로 개발되었지만, 1990년대 중반 인터넷의 급격한 성장으로 웹과 네트워크에서 실행 가능한 프로그래밍 언어로 방향을 바꾸게 되었다. 이후 1995년에 Java 1.0을 정식 출시했다.</p>
<br>
<br>

<h1 id="java의-장단점">Java의 장단점</h1>
<h2 id="장점">장점</h2>
<h3 id="1️⃣-플랫폼-독립성-write-once-run-anywhere">1️⃣ 플랫폼 독립성 (Write Once, Run Anywhere)</h3>
<pre><code>Java 프로그램은 JVM(Java Virtual Machine) 위에서 실행되므로, 운영체제(OS)에 상관없이 실행 가능함</code></pre><h3 id="2️⃣-객체지향-프로그래밍-object-oriented-programing-oop-지원">2️⃣ 객체지향 프로그래밍 (Object-Oriented Programing, OOP) 지원</h3>
<pre><code>캡슐화, 상속, 다형성, 추상화 같은 OOP 개념을 지원하여 코드의 재사용성과 유지보수가 뛰어남</code></pre><h3 id="3️⃣-메모리-자동-관리-garbage-collection-gc">3️⃣ 메모리 자동 관리 (Garbage Collection, GC)</h3>
<pre><code>Java의 가비지 컬렉터가 자동으로 메모리를 관리하여 개발자가 직접 메모리에 관여하지 않아도 됨</code></pre><h3 id="4️⃣-멀티스레딩-지원">4️⃣ 멀티스레딩 지원</h3>
<pre><code>Java는 멀티스레딩(Multithreading)을 지원하여 여러 작업을 동시에 실행 가능함</code></pre><h3 id="5️⃣-방대한-라이브러리와-프레임워크-지원">5️⃣ 방대한 라이브러리와 프레임워크 지원</h3>
<pre><code>Java는 다양한 라이브러리와 프레임워크(Spring, Hibernate, Apache Kafka 등)을 제공하여 개발 속도를 높일 수 있음</code></pre><br>

<h2 id="단점">단점</h2>
<h3 id="1️⃣-실행-속도가-느림">1️⃣ 실행 속도가 느림</h3>
<pre><code>Java는 JVM 위에서 실행되기 때문에 C, C++ 같은 네이티브 언어보다 속도가 느릴 수 있음.
하지만 JIT(Just-In-Time) 컴파일러와 GraalVM 같은 기술로 성능을 점점 개선하고 있음.</code></pre><h3 id="2️⃣-코드-작성">2️⃣ 코드 작성</h3>
<pre><code>Java는 문법이 비교적 길어서 Python 같은 언어보다 코드 작성이 번거로움</code></pre><h3 id="3️⃣-로우레벨-지원-부족">3️⃣ 로우레벨 지원 부족</h3>
<pre><code>하드웨어 직접 제어와 운영체제 수준의 프로그래밍이 어려움</code></pre><br>
<br>

<h1 id="java의-실행-및-개발-환경">Java의 실행 및 개발 환경</h1>
<table>
<thead>
<tr>
<th><strong>비교 항목</strong></th>
<th><strong>JDK (개발 도구)</strong></th>
<th><strong>JRE (실행 환경)</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>포함 관계</strong></td>
<td>JRE 포함</td>
<td>JRE 자체</td>
</tr>
<tr>
<td><strong>역할</strong></td>
<td>자바 프로그램 개발 &amp; 실행</td>
<td>자바 프로그램 실행만 가능</td>
</tr>
<tr>
<td><strong>주요 구성 요소</strong></td>
<td>JRE + 컴파일러(<code>javac</code>), 디버거(<code>jdb</code>), Javadoc, JAR 도구 등</td>
<td>JVM, 표준 라이브러리, 런타임 유틸리티</td>
</tr>
<tr>
<td><strong>사용 대상</strong></td>
<td>개발자 (개발 &amp; 실행)</td>
<td>일반 사용자 (실행만)</td>
</tr>
</tbody></table>
<br>
<br>


<h1 id="java의-동작-방식">Java의 동작 방식</h1>
<p><img src="https://velog.velcdn.com/images/hee_ya/post/5eccd6bd-5dcd-46cb-945d-95ddd48cf122/image.png" alt=""></p>
<blockquote>
</blockquote>
<ol>
<li>Java 컴파일러가 소스 코드를 바이트 코드(.class)로 변환됨</li>
<li>바이트 코드가 JVM(Java Virtual Machine)에 의해 메모리에 로드됨</li>
<li>JVM의 인터프리터(Interpreter) 또는 JIT(Just-In-Time)컴파일러가 바이트 코드를 실행</li>
<li>프로그램 실행이 끝나면 JVM이 할당된 메모리를 정리한 뒤 종료</li>
</ol>
<br>
<br>
]]></description>
        </item>
    </channel>
</rss>