<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>glenn_syj.log</title>
        <link>https://velog.io/</link>
        <description>제가 좋아하는 것은 도가 아니라 기입니다</description>
        <lastBuildDate>Mon, 15 Jan 2024 11:30:50 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>glenn_syj.log</title>
            <url>https://velog.velcdn.com/images/glenn_syj/profile/8691cc2d-169c-4670-a19f-fc550a1b630c/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. glenn_syj.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/glenn_syj" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[큐: 큐 인터페이스와 활용]]></title>
            <link>https://velog.io/@glenn_syj/%ED%81%90-%ED%81%90-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%99%80-%ED%99%9C%EC%9A%A9</link>
            <guid>https://velog.io/@glenn_syj/%ED%81%90-%ED%81%90-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%99%80-%ED%99%9C%EC%9A%A9</guid>
            <pubDate>Mon, 15 Jan 2024 11:30:50 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p><strong>최초 작성일(yy/mm/dd): 24/01/15 최초 작성</strong></p>
<h3 id="학습-목표">학습 목표</h3>
<ol>
<li>자바8에서의 큐 이용법을 학습한다.</li>
<li>큐가 어떤 상황에서 활용되는지 간략하게 살펴본다.</li>
</ol>
<h3 id="학습-상황">학습 상황</h3>
<ul>
<li>자바에 내장된 큐 클래스를 이용할 때의 주의사항을 기억하고, Problem Solving 시에 효율적이고 적절하게 쓸 필요가 있다.</li>
</ul>
<h2 id="스택-javautilqueue">스택: Java.util.Queue</h2>
<h3 id="큐-인터페이스-뜯어보기">큐 인터페이스 뜯어보기</h3>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 1. Java.util.Queue의 상속과 설명</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/2cab391e-a936-4caa-8bdf-af9dca13d1fb/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: geeksforgeeks.com </p></td>
</tr>
</tbody></table>
<p><strong>큐와 상속</strong></p>
<p>큐는 Collection 프레임워크를 직접적으로 상속하고 있습니다. 그런데 큐는 기본 Collection에 더해 삽입하고, 제거하고, 확인하는 추가적인 연산을 갖고 있습니다. </p>
<p>두 연산은 연산이 실패했을 때 (1) 에러를 내보내느냐 (2) 다른 값(null, false)을 내보내느냐에 따라 나뉩니다.</p>
<p>Collection에서 상속 받은 좌측 메서드는 에러를, 추가된 우측 메서드는 특정한 값을 내보냅니다. 이는 용량이 고정된 큐(capacity-fixed queue)을 위해 고안되었습니다. Java 8 공식 문서를 살펴보면 그 이유를 알 수 있습니다.</p>
<p><strong>큐 메서드</strong> </p>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 2. Java.util.Queue의 메서드</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/06172bf3-69c5-42f6-8b0f-9ab3101b7fd3/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: geeksforgeeks.com </p></td>
</tr>
</tbody></table>
<ul>
<li>add(E e)</li>
</ul>
<pre><code>용량 제한을 넘어서지 않는다면, 요소를 큐에 추가합니다. 성공하면 true를 반환하고, 요소가 들어갈 공간이 없다면 IllegalStateException 에러를 띄웁니다.</code></pre><ul>
<li><p>element()</p>
<p>  큐의 head에 있는 값을 가져오지만, 제거하지는 않습니다.</p>
</li>
<li><p>offer(E e)</p>
<p>  용량 제한을 넘어서지 않는다면, 요소를 큐에 추가합니다. 성공하면 true를 반환하고, 실패하면 false를 반환합니다.</p>
</li>
<li><p>peek()</p>
<p>  큐의 head에 있는 값을 가져오지만, 제거하지는 않습니다. 큐가 비어있다면 에러를 띄우는 대신 null을 반환합니다.</p>
</li>
<li><p>poll()</p>
<p>  큐의 head에 있는 값을 가져오고 제거합니다. 만약 큐가 비어있다면 null을 반환합니다.</p>
</li>
<li><p>remove()</p>
<p>  큐의 head에 있는 값을 가져오고 제거합니다. 실패한다면 에러를 띄웁니다. </p>
</li>
<li><p>clear()</p>
<p>  큐를 초기화합니다.</p>
</li>
</ul>
<p><strong>왜 큐는 메서드가 추가되었는가?</strong></p>
<p>크기가 고정된 큐를 떠올려 봅시다. </p>
<p>만약 큐가 가득 차 있어 자료 삽입에 실패하는 상황이 일반적일 때, 에러를 매번 띄운다면 성능이 저하될 것입니다. </p>
<p>마찬가지로 큐가 비어 있어 자료 삭제에 실패하는 상황이 일반적이라면, 수고롭게 매 번 에러를 띄울 필요가 없습니다. </p>
<p>⇒ offer(E e), poll(), peek()은 모두 실패를 가정하는 상황에서 유용하게 쓰입니다. </p>
<h3 id="큐의-장점과-단점">큐의 장점과 단점</h3>
<p><strong>큐의 장점</strong></p>
<p>큐는 대용량의 데이터를 효율적이고 간편히 관리할 수 있습니다.</p>
<p>여러 사용자가 동시에 이용하는 서비스를 관리하기에 유용합니다.</p>
<p>데이터의 순서가 유지되는 작업에서 편리합니다.</p>
<p>순서를 유지해야 하는 다른 데이터 구조를 구현할 때 쓰입니다.</p>
<p><strong>큐의 단점</strong></p>
<p>head나 rear가 아니라 큐의 중간 위치 기준 요소 삽입이나 삭제는 시간이 오래 걸립니다.</p>
<p>크기가 고정되어 있으면 새로운 요소가 삽입될 수 없습니다.</p>
<p>또한, 기본 큐에서 새로운 요소는 기존 요소가 삭제될 때에만 추가될 수 있습니다.</p>
<p>검색 역시 O(N) 시간복잡도를 가집니다.</p>
<h2 id="큐-어디에-쓰일까">큐: 어디에 쓰일까?</h2>
<h3 id="자바에서-큐-이용하기">자바에서 큐 이용하기</h3>
<pre><code class="language-java">import java.util.LinkedList;
import java.util.Queue;

Queue&lt;Integer&gt; queue = new LinkedList&lt;&gt;();
Queue&lt;String&gt; queue = new LinkedList&lt;&gt;();</code></pre>
<h3 id="큐의-활용">큐의 활용</h3>
<p><strong>멀티 프로그래밍 / 업무 스케쥴링</strong></p>
<p>여러 프로그램이 메인 메모리에서 돌아갈 때, 큐를 이용할 수 있습니다. 프로세스는 우선 순위에 따라 역시 우선 순위가 다른 여러 큐에 나뉘어집니다.</p>
<p><strong>LRU 캐시(LRU Cache)</strong></p>
<p>LRU 캐시(Least Recently Used Cache)는 메모리가 가득차 있을 때, 최근에 쓰이지 않은 데이터부터 제거합니다. 우선순위 큐나 일반 큐를 LRU 캐시 구현에 이용할 수는 있으나, 효율적이라고는 말 할 수 없습니다. 사실 LRU 캐시에는 이중연결리스트와 해시맵이 일반적으로 쓰입니다.</p>
<p><strong>네트워크</strong></p>
<table>
<thead>
<tr>
<th align="center"><b> *<em>Fig 3. FIFO 큐잉과 우선순위 큐잉 *</em> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/09e10cf7-400f-4c7d-9278-ee0d5f42b307/image.png" width="100%" height="100%"> <img src="https://velog.velcdn.com/images/glenn_syj/post/e3c29c6f-36c5-4e23-8683-be76a7306fae/image.png" width="80%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: geeksforgeeks.com </p></td>
</tr>
</tbody></table>
<p>라우터나 스위치와 같은 네트워크 장비에서 큐가 이용됩니다. 특히 큐는 패킷 큐잉(packet queueing)에서 유용하게 쓰이는데, 대표적으로 FIFO 큐잉이나 우선순위 큐잉이 있습니다.</p>
<p>⇒ 큐는 우선순위 혹은 FIFO에 따라, 전송 작업이나 데이터 순서를 유지하는 작업에서 유용하게 쓰임을 알 수 있습니다.</p>
<h2 id="참고-자료">참고 자료</h2>
<ul>
<li><a href="https://www.geeksforgeeks.org/difference-between-poll-and-remove-method-of-queue-interface-in-java/">https://www.geeksforgeeks.org/difference-between-poll-and-remove-method-of-queue-interface-in-java/</a></li>
<li><a href="https://www.geeksforgeeks.org/time-and-space-complexity-analysis-of-queue-operations/">https://www.geeksforgeeks.org/time-and-space-complexity-analysis-of-queue-operations/</a></li>
<li><a href="https://stackoverflow.com/questions/2193450/why-java-provides-two-methods-to-remove-element-from-queue">https://stackoverflow.com/questions/2193450/why-java-provides-two-methods-to-remove- element-from-queue</a></li>
<li><a href="https://cbselibrary.com/advantages-and-disadvantages-of-queue/">https://cbselibrary.com/advantages-and-disadvantages-of-queue/</a></li>
<li><a href="https://www.geeksforgeeks.org/lru-cache-implementation/">https://www.geeksforgeeks.org/lru-cache-implementation/</a></li>
</ul>
<p>  → LRU 캐시에 관한 글입니다.</p>
<ul>
<li><p><a href="https://www.geeksforgeeks.org/packet-queuing-and-dropping-in-routers/">https://www.geeksforgeeks.org/packet-queuing-and-dropping-in-routers/</a></p>
<p>  → 패킷 큐잉에 관한 글입니다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[큐: 기본 개념과 구현]]></title>
            <link>https://velog.io/@glenn_syj/%ED%81%90-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EA%B5%AC%ED%98%84</link>
            <guid>https://velog.io/@glenn_syj/%ED%81%90-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EA%B5%AC%ED%98%84</guid>
            <pubDate>Wed, 10 Jan 2024 12:19:11 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p><strong>최초 작성일(yy/mm/dd): 24/01/10 최초 작성</strong></p>
<h3 id="학습-목표">학습 목표</h3>
<ol>
<li>큐의 기본적인 개념과 연산, 쓰임을 이해한다.</li>
<li>자바의 제네릭을 이용해 큐 자료구조를 구현해본다.</li>
</ol>
<h3 id="학습-상황">학습 상황</h3>
<ul>
<li>큐를 이해하고 어떤 상황에서 쓰일지 고민해볼 필요가 있었다.</li>
<li>삼성 SW 역량테스트 B형에 대비해, 구현 과정에서도 java.util 내 자료구조 ArrayList 등을 이용하지 않는다.</li>
</ul>
<h2 id="큐-기본-개념">큐: 기본 개념</h2>
<h3 id="큐queue란-무엇인가">큐(Queue)란 무엇인가?</h3>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 1. 큐의 기본 구조</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/fc4e0677-c45a-4dc4-a24f-463e69dc4e89/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: geeksforgeeks.com </p></td>
</tr>
</tbody></table>
<p><strong>큐의 개념</strong></p>
<p>큐는 한 쪽 끝에서는 삽입(enqueue)이 이루어지고, 다른 한 쪽 끝에서는 삭제(dequeue)가 이루어지는 자료구조를 의미합니다. 양쪽 끝에 모두 접근할 수 있지만, 실행할 수 있는 연산은 다릅니다.</p>
<p>따라서 <strong>FIFO</strong>(First In, First out), 즉 먼저 들어간 요소가 먼저 나오게 됩니다. 이는 티켓 줄서는 것과 비슷합니다.</p>
<p>가장 앞에 있는(=순서가 가장 빠른) 요소를 가리키는 포인트는 <strong>front(head)</strong>, 가장 뒤에 있는(=순서가 가장 느린) 요소를 가리키는 포인터는 <strong>rear(tail)</strong>로 부를 수 있습니다. </p>
<p><strong>큐의 종류</strong></p>
<ol>
<li><p>원형 큐</p>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 2. 원형 큐의 기본 구조와 동작</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/209e9082-8cc9-4e9f-b6b9-0479553be500/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: geeksforgeeks.com </p></td>
</tr>
</tbody></table>
<p> 큐의 마지막 위치가 다시 처음 위치에 연결되어 원처럼 이어지는 큐입니다. ‘링 버퍼’(Ring Buffer)라고도 불립니다. 메모리 관리, traffic system, CPU 스케쥴링에서 쓰입니다. 원형 큐는 다른 글에서 자세하게 살펴보겠습니다.</p>
</li>
<li><p>입력 제한 큐</p>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 3. 입력 제한 큐의 기본 구조</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/3040ef35-cc46-4d21-b2b0-da171f0f5276/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: geeksforgeeks.com </p></td>
</tr>
</tbody></table>
<p> 입력 제한 큐에서, 한 쪽 끝은 삽입과 삭제 모두 가능하지만, 한 쪽 끝(head)은 삭제만 가능합니다. 이는 (1) FIFO 순서로 정렬되지만 (2) 최근에 삽입된 자료를 삭제할 필요가 있는 경우에 쓰입니다. </p>
</li>
<li><p>출력 제한 큐</p>
</li>
</ol>
<pre><code>|&lt;b&gt; **Fig 4. 출력 제한 큐의 기본 구조** &lt;/b&gt; |</code></pre><p>   | :-: |
   | <img src="https://velog.velcdn.com/images/glenn_syj/post/9cb22b99-5176-469d-8916-4eb293ab12ae/image.png" width="100%" height="100%"> |
   | <p style="text-align: center;"> 출처: geeksforgeeks.com </p>|</p>
<pre><code>출력 제한 큐에서는 양 쪽 끝 모두 삽입은 가능하지만, 삭제는 한 쪽(head)에서만 가능합니다. 우선순위에 따라 가장 앞(head)의 input을 먼저 실행해야 하는 경우에, 출력 제한 큐는 유용합니다. </code></pre><ol start="4">
<li><p>더블-엔디드-큐 (데크)</p>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 5. 데크의 기본 구조</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/014b2e32-454c-4e7c-972c-2279dd3a4a55/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: geeksforgeeks.com </p></td>
</tr>
</tbody></table>
<p> 데크는 양 쪽 끝 모두에서 삽입과 삭제가 이루어지는 자료구조입니다. 따라서 지난 번 스택 자료구조에서 살펴보았듯, Deque를 이용해 스택 역시 구현할 수 있습니다. 게다가 데크 자료구조는 O(1)에 시계방향 및 반시계방향으로 input을 회전시킬 수도 있습니다.</p>
</li>
<li><p>우선순위 큐</p>
<p> 우선순위 큐는 각 input마다 우선순위가 적용되는 큐입니다. 정렬 순서에 따라, 오름차순 혹은 내림차순으로 적용될 수 있습니다. 자세한 내용은 <strong>힙</strong> 자료구조를 학습한 이후에 따로 정리할 예정입니다.</p>
</li>
</ol>
<h3 id="큐의-기본-연산">큐의 기본 연산</h3>
<pre><code>💡 아래의 내용과 관련해, 기본적으로 FIFO를 따르는 Queue의 기본 연산입니다.</code></pre><p><strong>enqueue(E)</strong></p>
<p>새로운 요소를 큐의 rear(tail)에 추가합니다. capacity 제한이 있다면, 큐가 가득 차 있는지 이전에 검사해야 합니다.</p>
<p><strong>dequeue()</strong></p>
<p>큐의 front(head)에 있는 요소를 제거합니다. 큐가 비어 있는지 이전에 검사해야 합니다.</p>
<p>배열로 큐를 구현하는 경우에, 제거되지 않은 기존 요소들의 인덱스가 앞당겨져야 하므로 O(N)의 시간복잡도를 가집니다. </p>
<p><strong>isEmpty()</strong></p>
<p>큐가 현재 비어있는지 검사하고, boolean 값을 반환합니다.</p>
<p><strong>peek()</strong></p>
<p>큐의 front(head)에 저장된 요소를 반환합니다.</p>
<p><strong>size()</strong></p>
<p>현재 큐에 들어있는 요소 개수를 반환합니다.</p>
<h2 id="큐-구현-자바">큐 구현: 자바</h2>
<h3 id="배열을-이용한-큐">배열을 이용한 큐</h3>
<pre><code class="language-java"> /* 코드는 수정될 수 있으며,
    참고한 코드는 참고자료 항목에 작성해두었습니다.
    코드는 수정될 수 있습니다.

        최초 작성일(yy/mm/dd): 2024/01/10    
    최종 수정일(yy/mm/dd): 2024/01/10 */

class ArrayQueue&lt;T&gt; {

    private int rear;
    private int front; // In fact, 0 or -1 is always assigned in array- implementation
    public T[] elements;

    public ArrayQueue(int initialCapacity) {
        elements = (T[]) new Object[initialCapacity];
        rear = -1;
        front = 0;
    }

    public boolean isEmpty() {
        return (front &gt; rear);
    }

    public boolean isFull() {
        return (rear == elements.length - 1);
    }

    public void enqueue(T theElement) {
        if (isFull()) {
            throw new IllegalStateException(&quot;Queue is full&quot;);
        } else {
            rear++;
            elements[rear] = theElement;
        }   
    }

    public void dequeue() {
        if (isEmpty()) {
            throw new IllegalStateException(&quot;Queue is empty&quot;);
        } else {
            T temp;
            for (int index = 0; index &lt; rear; index++) { // array impl: O(N)
                temp = elements[index + 1];
                elements[index] = temp;
            }
            elements[rear] = null;
            rear--;
        }
    }

    public T peek() {
        if (isEmpty()) {
            throw new IllegalStateException(&quot;Queue is empty&quot;);
        } else {
            return elements[front];
        }
    }

    public void printElements() { // custom method for printing the queue
        for (int i = front; i &lt;= rear; i++) {
            System.out.println(elements[i]);
        }
    }

}</code></pre>
<h3 id="연결리스트를-이용한-큐">연결리스트를 이용한 큐</h3>
<pre><code class="language-java"> /* 코드는 수정될 수 있으며,
    참고한 코드는 참고자료 항목에 작성해두었습니다.
    코드는 수정될 수 있습니다.

        최초 작성일(yy/mm/dd): 2024/01/10    
    최종 수정일(yy/mm/dd): 2024/01/10 */

class LinkedQueue&lt;T&gt; {

    private int size;
    private Node&lt;T&gt; front;
    private Node&lt;T&gt; rear;
    private static int DEFAULT_CAPACITY = 100;
    private int capacity;

    private static class Node&lt;T&gt; {
        T data;
        Node next;

        Node(T data) {
            this.data = data;
            this.next = null;
        }
    }

    public LinkedQueue() {
        this.front = null;
        this.rear = null;
        this.size = 0;
        this.capacity = DEFAULT_CAPACITY;
    }

    public LinkedQueue(int initialCapacity) {
        this.front = null;
        this.rear = null;
        this.size = 0;
        this.capacity = initialCapacity;
    }

    public boolean isEmpty() {
        return (size == 0);
    }

    public boolean isFull() {
        return (size == capacity);
    }

    public void enqueue(T theElement) {
        if (isFull()) {
            throw new IllegalStateException(&quot;Queue is full&quot;);
        } else if (isEmpty()) {
            front = rear = new Node(theElement);
        } else {
            rear.next = new Node(theElement);
            rear = rear.next;
        }
        size++;
    }

    public void dequeue() {
        if (isEmpty()) {
            throw new IllegalStateException(&quot;Queue is empty&quot;);
        } else {
            front = front.next;
            size--;
        }
    }

    public T peek() {
        if (isEmpty()) {
            throw new IllegalStateException(&quot;Queue is empty&quot;);
        } else {
            return front.data;
        }
    }

    public void printElements() { // custom method for printing the queue
        Node tmp = front;
        while (tmp != null) {
            System.out.println(tmp.data);
            tmp = tmp.next;
        }
    }

}</code></pre>
<h2 id="참고-자료">참고 자료</h2>
<ul>
<li><a href="https://www.geeksforgeeks.org/queue-data-structure/">https://www.geeksforgeeks.org/queue-data-structure/</a></li>
<li><a href="https://www.geeksforgeeks.org/different-types-of-queues-and-its-applications/">https://www.geeksforgeeks.org/different-types-of-queues-and-its-applications/</a></li>
<li><a href="https://www.geeksforgeeks.org/how-to-implement-queue-in-java-using-array-and-generics/">https://www.geeksforgeeks.org/how-to-implement-queue-in-java-using-array-and-generics/</a></li>
<li><a href="https://www.geeksforgeeks.org/different-types-of-queues-and-its-applications/">https://www.geeksforgeeks.org/different-types-of-queues-and-its-applications/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[스택: 스택 클래스와 활용]]></title>
            <link>https://velog.io/@glenn_syj/%EC%8A%A4%ED%83%9D-%EC%8A%A4%ED%83%9D-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%ED%99%9C%EC%9A%A9</link>
            <guid>https://velog.io/@glenn_syj/%EC%8A%A4%ED%83%9D-%EC%8A%A4%ED%83%9D-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%ED%99%9C%EC%9A%A9</guid>
            <pubDate>Sun, 07 Jan 2024 08:10:41 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p><strong>최초 작성일(yy/mm/dd): 24/01/07 최초 작성</strong></p>
<h3 id="학습-목표">학습 목표</h3>
<ol>
<li>자바8에서의 스택 이용법과 주의사항을 학습한다.</li>
<li>스택이 어떤 상황에서 활용되는지 간략하게 살펴본다.</li>
</ol>
<h3 id="학습-상황">학습 상황</h3>
<ul>
<li>자바에 내장된 스택 클래스를 이용할 때의 주의사항을 기억하고, Problem Solving 시에 효율적이고 적절하게 쓸 필요가 있다.</li>
</ul>
<h2 id="스택-javautilstack">스택: Java.util.Stack</h2>
<h3 id="스택-클래스-뜯어보기">스택 클래스 뜯어보기</h3>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 1. Java.util.Stack의 상속 순서와 설명</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/39684d3c-1b8d-4aec-9781-370ac5a511c3/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: docs.oracle.com </p></td>
</tr>
</tbody></table>
<ul>
<li>스택과 상속 </br>
스택 클래스까지의 상속 관계를 살펴보자면, Object → AbstractCollections → AbstractList → Vector → Stack 순으로 상속됩니다.</li>
</ul>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 2. java.util.Stack이 상속받은 메소드</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/616c809e-f813-4c3c-881a-d12af697e0a9/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: docs.oracle.com </p></td>
</tr>
</tbody></table>
<p>  특히 Vector에서 직접적으로 상속된 메소드가 많다는 점이 눈에 띕니다. 따라서 스택 클래스와 관련해서는 Vector를 유심히 살펴봐야 합니다.</p>
<ul>
<li>스택 클래스의 단점</li>
</ul>
<p> 문서 마지막에서는 스택 클래스를 사용하는 개선된 방식으로 <strong>ArrayDeque</strong>의 이용을 권장합니다. 이는 Vector 클래스가 가진 결점 때문입니다.</p>
<ol>
<li><p>배열과 같은 방식으로 접근되고 사용될 수 있음</p>
<p>Random Access 방식의 접근은 물론, add와 같은 메소드 역시 특정 인덱스에 요소를 추가할 수 있다는 점에서 스택이 가진 구조와 배치됩니다.</p>
</li>
</ol>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 3. java.util.Stack의 기본 메소드</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/e93e9d4c-aece-44c9-b43f-f0e5bc08b629/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: docs.oracle.com </p></td>
</tr>
</tbody></table>
<p>  일례로, search 메소드가 대표적입니다. 스택 자료구조에서 Random Access 방식의 search는 어울리지 않습니다.</p>
<ol start="2">
<li><p>동기화(synchronization)로 인한 성능 및 동시성 저하</p>
<p>벡터 클래스에서는 get(), set() 등 메소드에 동기화가 적용됩니다. 동기화는 사용중인 스레드 이외에서의 접근을 막아 동시성을 저하합니다. </p>
<p>   또한, 락 오버헤드(Lock Overhead)로 인한 비용으로 성능 역시 저하됩니다.</p>
</li>
</ol>
<ul>
<li><p>자바에서 스택 이용</p>
<pre><code class="language-java">  Deque&lt;E&gt; stack = new ArrayDeque&lt;E&gt;();</code></pre>
<p>Vector에서 비롯된 Stack의 문제점이 개선되었고, search() 메소드는 이용할 수 없습니다. </p>
<p>그러나 Problem Solving에서 search() 메소드가 급히 필요하거나 구현 시간이 부족하다면, <strong>권장되지 않겠지만</strong> Stack 클래스를 이용할 수 있지 않을까요?</p>
</li>
</ul>
<h2 id="스택-어디에-쓰일까">스택: 어디에 쓰일까?</h2>
<h3 id="스택의-활용">스택의 활용</h3>
<ul>
<li><p>Postfix/Prefix conversion</p>
</li>
<li><p>되돌아가기 및 취소(Redo-undo) 기능</p>
</li>
<li><p>스택 메모리</p>
<p>  지역 변수, 매개 변수, 반환 주소(return address)가 저장되는 메모리입니다. 주로 primitive type의 지역변수, 매개변수가 저장됩니다.</p>
<p>  ↔ 전역 변수는 Static 메모리에 저장됩니다. </p>
</li>
<li><p>문자열 역순</p>
</li>
<li><p>함수 호출</p>
<p>  메소드가 호출되면 필요한 크기만큼 메모리를 할당받고, 수행이 끝나면 메모리를 반환합니다. 최상단 메소드가 실행중인 메소드이며, 스택의 bottom-up 순서는 호출된 순서입니다.</p>
</li>
</ul>
<p>⇒ Problem Solving만이 아니라, JVM이나 메모리 구조와 관련된 주제도 많다는 점이 보입니다. </p>
<h2 id="참고-자료">참고 자료</h2>
<ul>
<li><p><a href="https://stackoverflow.com/questions/1386275/why-is-java-vector-and-stack-class-considered-obsolete-or-deprecated">https://stackoverflow.com/questions/1386275/why-is-java-vector-and-stack-class-considered-obsolete-or-deprecated</a></p>
</li>
<li><p><a href="https://brunch.co.kr/@kd4/156">https://brunch.co.kr/@kd4/156</a>
<a href="https://didrlgus.github.io/java/05-post/">https://didrlgus.github.io/java/05-post/</a>
 → synchronization에 대해 엿볼 수 있는 글입니다.</p>
</li>
<li><p><a href="https://hyeyoo.com/79">https://hyeyoo.com/79</a></p>
<p>  → Lock에 관해 정리해주신 글입니다.</p>
</li>
<li><p><a href="https://baddotrobot.com/blog/2013/01/10/stack-vs-deque/">https://baddotrobot.com/blog/2013/01/10/stack-vs-deque/</a></p>
<p>  → stack interface에서 제한을 통해 스택을 구현하는 법에 대해 소개하는 글들입니다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[스택: 기본 개념과 구현 ]]></title>
            <link>https://velog.io/@glenn_syj/%EC%8A%A4%ED%83%9D-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EA%B5%AC%ED%98%84</link>
            <guid>https://velog.io/@glenn_syj/%EC%8A%A4%ED%83%9D-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EA%B5%AC%ED%98%84</guid>
            <pubDate>Sat, 06 Jan 2024 12:54:01 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p><strong>최초 작성일: 10/23 최초 작성</strong></p>
<h3 id="학습-목표">학습 목표</h3>
<ol>
<li>스택의 기본적인 개념과 연산을 이해한다.</li>
<li>자바의 제네릭을 이용해 스택 자료구조를 구현해본다.</li>
</ol>
<h3 id="학습-상황">학습 상황</h3>
<ul>
<li>단순히 자바에 있는 스택 클래스가 아니라, 그러한 스택 클래스가 어떻게 만들어지는지 고민해본다.</li>
<li>삼성 SW 역량테스트 B형에 대비해, 구현 과정에서도 stack interface를 implement하지 않는다.</li>
</ul>
<h2 id="스택-기본-개념">스택: 기본 개념</h2>
<h3 id="스택stack이란-무엇인가">스택(Stack)이란 무엇인가?</h3>
<ul>
<li><p>스택은 선입후출(LIFO, Last In First Out)이자 후입선출(FILO, First In Last Out)을 특징으로 합니다.</p>
<ul>
<li><p>쉽게 생각해서: 식당 내 티슈통과 같은 방식으로 쓰이는 자료구조라고 생각하면 됩니다.     </p>
<br/>

<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 1. 스택의 기본 구조</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/2eb7b305-2f40-4eb3-9c08-c9f944b5afed/image.png" width="100%" height="100%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: geeksforgeeks.com </p></td>
</tr>
</tbody></table>
<br/>
</li>
<li><p>따라서, 포인터가 항상 스택의 <strong>최상위</strong>에(즉, 가장 나중에 들어온 대상에) 있습니다.</p>
</li>
</ul>
</li>
<li><p>스택의 종류</p>
<ol>
<li><p>고정 크기 스택(Fixed Size Stack)</p>
<p> 말 그대로, 스택이 크기가 자바 배열처럼 고정되어 있다고 보면 편합니다. 스택이 가득 차 있다면 오버플로우를, 스택이 비어있다면 언더플로우를 고려해야 합니다. </p>
</li>
<li><p>동적 크기 스택(Dynamic Size Stack)</p>
<p> 요소의 추가나 삭제에 따라 스택의 크기가 줄어들거나 늘어날 수 있습니다. 연결 리스트(linked list)를 이용해 구현할 수 있습니다.</p>
</li>
</ol>
</li>
</ul>
<h3 id="스택의-기본-연산">스택의 기본 연산</h3>
<pre><code>💡 스택에서 최상위 요소가 항상 가장 나중에 들어온 요소임을 고려하면 이해가 쉽습니다.
</code></pre><ul>
<li><p>push()</p>
<ul>
<li>요소를 스택에 넣습니다. 따라서, 가장 나중에 들어온 요소가 최상위에 위치하게 됩니다.</li>
<li>스택이 가득 차 있다면, 요소가 더 넣을 수 없음을 감안해야 합니다.</li>
</ul>
</li>
<li><p>pop()</p>
<ul>
<li>요소를 스택에서 제거합니다. 따라서, 최상위 요소가 제거됩니다.</li>
<li>스택이 비어있다면, 요소를 더 뺄 수 없음을 감안해야 합니다.</li>
</ul>
</li>
<li><p>peek()</p>
<ul>
<li>스택의 최상위 요소를 반환합니다.</li>
<li>비어있을 때의 반환값을 고려해야 합니다.</li>
</ul>
</li>
<li><p>isEmpty()</p>
<ul>
<li>스택이 비어있는지 확인하며, boolean 값을 반환합니다.</li>
</ul>
</li>
<li><p>size()</p>
<ul>
<li>스택의 크기를 반환합니다.</li>
</ul>
</li>
</ul>
<h3 id="복잡도">복잡도</h3>
<ul>
<li><p>push(), pop(), top(), isEmpty(), size() 모두: O(1)</p>
<ul>
<li>순회나 검색을 거치지 않으므로 O(1)의 시간 복잡도를 가집니다.</li>
</ul>
</li>
</ul>
<h2 id="스택-구현-자바">스택 구현: 자바</h2>
<h3 id="배열을-이용한-스택">배열을 이용한 스택</h3>
<pre><code class="language-java"> /* 코드는 수정될 수 있으며,
    참고한 코드는 참고자료 항목에 작성해두었습니다.
    코드는 수정될 수 있습니다.

    최초 작성일(yy/mm/dd): 2024/01/06    
    최종 수정일(yy/mm/dd): 2024/01/06 */

class ArrayStack&lt;T&gt; {
    private T[] elements;
    private int top;

    public ArrayStack(int initialCapacity) {
        elements = (T[]) new Object[initialCapacity];
        top = -1;
    }

    public boolean isEmpty() {
        return (top == -1);
    }

    public boolean isFull() {
        return (top == elements.length-1);
    }

    public void push(T theElement) {
        if (isFull()) {
            throw new IllegalStateException(&quot;Stack is full&quot;);
        } else {
            top++;
            elements[top] = theElement;
        }
    }

    public T pop() {
        if (isEmpty()) {
            throw new IllegalStateException(&quot;Stack is empty&quot;);
        } else {
            T removedElement = elements[top];
            elements[top] = null;
            top--;
            return removedElement;
        }
    }

    public T peek() {
        if (isEmpty()) return null;
        return elements[top];
    }

    public int size() {
        return top+1;
    }
}
</code></pre>
<h3 id="연결-리스트를-이용한-스택">연결 리스트를 이용한 스택</h3>
<pre><code class="language-java"> /* 코드는 수정될 수 있으며,
    참고한 코드는 참고자료 항목에 작성해두었습니다.
    코드는 수정될 수 있습니다.

    최초 작성일(yy/mm/dd): 2024/01/06
    최종 수정일(yy/mm/dd): 2024/01/06 */

class ListStack&lt;T&gt; {

    private Node&lt;T&gt; top;
    private int size;

    private static class Node&lt;T&gt; {

        T data;
        Node next;

        Node(T data) {
            this.data = data;
            this.next = null;
        }
    }

    public ListStack() { 
        this.top = null;
        this.size = 0;
    }

    public boolean isEmpty() { return size == 0; }

    public void push(T theElement) {
        Node&lt;T&gt; newNode = new Node&lt;&gt;(theElement);
        newNode.next = top;
        top = newNode;
        size++;
    }

    public T pop() {
        if (isEmpty()) {
            throw new IllegalStateException(&quot;Stack is empty&quot;);
        }

        T removedElement = top.data;
        top = top.next;
        size--;
        return removedElement;
    }

    public T peek() {
        if (isEmpty()) {
            throw new IllegalStateException(&quot;Stack is empty&quot;);
        }
        return top.data;
    }

    public int size() {
        return size;
    }

}</code></pre>
<h2 id="참고-자료">참고 자료</h2>
<ul>
<li><a href="https://www.geeksforgeeks.org/stack-data-structure/">https://www.geeksforgeeks.org/stack-data-structure/</a></li>
<li><a href="https://gist.github.com/mcrumm/11388910">https://gist.github.com/mcrumm/11388910</a></li>
<li><a href="https://perfectacle.github.io/2017/08/05/stack-making/">https://perfectacle.github.io/2017/08/05/stack-making/</a></li>
<li><a href="https://medium.com/javarevisited/how-to-implement-a-generic-data-structure-in-java-2523b5c4d3ff">https://medium.com/javarevisited/how-to-implement-a-generic-data-structure-in-java-2523b5c4d3ff</a></li>
<li><a href="https://medium.com/javarevisited/how-to-implement-a-generic-data-structure-in-java-2523b5c4d3ff">https://medium.com/javarevisited/how-to-implement-a-generic-data-structure-in-java-2523b5c4d3ff</a></li>
<li><a href="https://www.geeksforgeeks.org/implement-a-stack-using-singly-linked-list/">https://www.geeksforgeeks.org/implement-a-stack-using-singly-linked-list/</a></li>
<li><a href="https://viterbi-web.usc.edu/~adamchik/15-121/lectures/Stacks%20and%20Queues/code/ListStack.java">https://viterbi-web.usc.edu/~adamchik/15-121/lectures/Stacks and Queues/code/ListStack.java</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[7. Recycler View의 기본 개념과 생명 주기]]></title>
            <link>https://velog.io/@glenn_syj/7.-Recycler-View%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%83%9D%EB%AA%85-%EC%A3%BC%EA%B8%B0</link>
            <guid>https://velog.io/@glenn_syj/7.-Recycler-View%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%83%9D%EB%AA%85-%EC%A3%BC%EA%B8%B0</guid>
            <pubDate>Fri, 24 Nov 2023 04:20:53 GMT</pubDate>
            <description><![CDATA[<h2 id="recyclerview의-기본-개념과-생명-주기">RecyclerView의 기본 개념과 생명 주기</h2>
<p><strong>작성일</strong> 23/11/24 최초 작성.</p>
<h3 id="들어가며">들어가며</h3>
<p><strong>학습 목표</strong></p>
<ol>
<li>RecyclerView의 각 생명 주기가 어떤 역할을 하는지 살펴본다.</li>
<li>각 생명 주기에 따라 주의할 점을 살펴본다.</li>
</ol>
<p><strong>학습 상황</strong></p>
<ol>
<li>RecyclerView를 이용해 틱택토 게임을 구현하는 과제가 있었다.</li>
<li>이후 ViewPager2 역시 RecyclerView에 기반함을 알게 되었다.</li>
</ol>
<h3 id="recyclerview란">RecyclerView란?</h3>
<p><strong>RecyclerView의 개념</strong></p>
<ul>
<li>RecyclerView는 리스트나 그리드와 같이 구조화된 데이터, 즉 같은 형식을 갖춘 여러 항목을 나타내는 컨테이너다.</li>
</ul>
<p><strong>RecyclerView의 특징</strong></p>
<ul>
<li><p>ViewHolder 사용: 화면에 표시되는 아이템의 뷰를 재활용할 수 있다. 따라서 성능 향상과 메모리 절약에 도움이 된다.</p>
</li>
<li><p>LayoutManager 사용: 레이아웃 매니저를 이용해 아이템의 배치 방법을 결정한다.</p>
</li>
<li><p>ItemDecoration: 항목 간에 간격이나 구분선을 넣기 위해 Item Decoration을 이용할 수 있다.</p>
</li>
<li><p>ItemAnimator: 아이템 추가, 제거, 또는 변경 시 애니메이션을 제공한다.</p>
</li>
<li><p>Clickable: 각 아이템은 클릭 가능하며, RecyclerView는 클릭 및 롱클릭 이벤트를 처리할 수 있다. (RecyclerView.Adapter에 setOnItemClickListener, setOnItemLongClickListener 메서드 이용)</p>
</li>
<li><p>동적 데이터 처리: RecyclerView에 연결된 어댑터의 데이터가 변경될 때, 이를 알려주면 RecyclerView는 뷰를 업데이트한다.</p>
</li>
</ul>
<h3 id="recyclerview의-생명주기">RecyclerView의 생명주기</h3>
<p><strong>생명주기가 중요한 이유</strong></p>
<ul>
<li><p>ViewHolder 패턴을 재활용할 때, 불필요한 뷰들이 메모리에 남아 메모리 누수로 이어질 수 있다.</p>
</li>
<li><p>onViewRecycled() 메서드를 활용해, 뷰가 재사용되기 전에 이전에 할당된 리소스들을 제거하지 않으면 메모리 누수로 이어질 수 있다.</p>
</li>
<li><p>또한, 스크롤 성능 확보와 동적 데이터 처리를 위해서도 생명 주기를 잘 다루어야 한다.</p>
</li>
</ul>
<p><strong>생명주기들</strong></p>
<ul>
<li><p>onCreateViewHolder</p>
<ul>
<li>RecyclerView가 처음 생성될 때, ViewHolder를 생성하는 단계로, ViewHolder를 초기화하고 레이아웃을 inflate한다.</li>
</ul>
</li>
<li><p>onBindViewHolder()</p>
<ul>
<li>RecyclerView가 화면에 보이는 항목을 업데이트하는 단계로, viewHolder에 데이터가 연결된다.</li>
</ul>
</li>
<li><p>getItemCount()</p>
<ul>
<li>RecyclerView에 표시될 아이템의 개수를 반환하는 단계다.</li>
</ul>
</li>
<li><p>onAttachedToRecyclerView()</p>
<ul>
<li>RecyclerView가 화면에 표시될 때 호출되는 단계로, RecyclerView와 연결된 작업을 수행할 수 있다.</li>
</ul>
</li>
<li><p>onDetachedFromRecyclerView()</p>
<ul>
<li>RecyclerView가 화면에서 제거될 때 호출되는 단계로, RecyclerView와 관련된 정리 작업을 수행할 수 있다.</li>
</ul>
</li>
<li><p>onViewRecycled()</p>
<ul>
<li>화면에서 사라진 ViewHolder가 재사용될 때 호출되는 단계로, 이전에 바인딩된 데이터나 리소스를 해제하는 작업을 수행할 수 있다.c</li>
</ul>
</li>
</ul>
<h3 id="참고-문헌">참고 문헌</h3>
<ul>
<li><p><a href="https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView">https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView</a></p>
</li>
<li><p><a href="https://developer.android.com/guide/topics/ui/layout/recyclerview-custom?hl=ko">https://developer.android.com/guide/topics/ui/layout/recyclerview-custom?hl=ko</a></p>
</li>
<li><p>chatGPT</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[ALG 1. 점근적 표기법]]></title>
            <link>https://velog.io/@glenn_syj/ALG-1.-%EC%A0%90%EA%B7%BC%EC%A0%81-%ED%91%9C%EA%B8%B0%EB%B2%95</link>
            <guid>https://velog.io/@glenn_syj/ALG-1.-%EC%A0%90%EA%B7%BC%EC%A0%81-%ED%91%9C%EA%B8%B0%EB%B2%95</guid>
            <pubDate>Mon, 23 Oct 2023 08:30:57 GMT</pubDate>
            <description><![CDATA[<h2 id="점근적-표기법">점근적 표기법</h2>
<p><strong>작성일</strong> 10/23 최초 작성.</p>
<h3 id="들어가며">들어가며</h3>
<p><strong>학습 목표</strong></p>
<ol>
<li>점근적 표기법의 개념과 종류, 그 특징을 살펴본다.</li>
<li>점근적 표기법의 장점과 한계를 살펴본다.</li>
</ol>
<p><strong>학습 상황</strong></p>
<ul>
<li>알고리즘을 순차적으로 학습하며, 점근적 표기법이 가지는 장점과 한계가 궁금해졌다.</li>
</ul>
<h3 id="점근적-표기법이란">점근적 표기법이란?</h3>
<p><strong>점근적 표기법의 개념</strong></p>
<ul>
<li>점근적 표기법(asymptotic notation)은 알고리즘 분석과 성능 측정에 이용하는 표기법이다. 주로 시간 복잡도와 공간 복잡도를 함수 형태로 표현한다.</li>
</ul>
<ul>
<li>왜 ‘점근적’인가?
: 입력의 크기가 아주 커지는 경우에서 알고리즘의 동작을 설명하기 위함이다. 즉, 입력값의 크기에 따른 함수와 그 함수가 얼마나 빠르게 커지는 지(성장률, rate of growth)를 살펴보기 위해서다. </li>
</ul>
<p><strong>점근적 표기법의 종류와 특징</strong></p>
<ol>
<li><p>빅-오 표기법</p>
<ul>
<li><p>빅-오(big-O) 표기법은 점근적 상한선을 나타낸다. 즉, 알고리즘에서 최악의 경우를 나타낸다.</p>
</li>
<li><p>f(n) = O(g(n)) 은 점근적 증가율이 g(n)을 넘지 않는 모든 함수들의 집합이다. 즉, g(n) 내 최고차항의 차수가 k일 때, 최고차항의 차수가 k 이하인 함수 f(n)은 모두 O(g(n))이다.</p>
</li>
<li><p>O(g(n)) = {f(n): 모든 n ≥ n0, 양의 상수 c 존재, c * g(n) ≤ f(n)}</p>
</li>
</ul>
</li>
</ol>
<ol start="2">
<li><p>빅-오메가 표기법</p>
<ul>
<li><p>빅-오메가(big-Ω) 표기법은 점근적 하한선을 나타낸다. 즉, 알고리즘에서 최선의 경우를 나타낸다. </p>
</li>
<li><p>f(n) = Ω(g(n)) 은 점근적 증가율이 g(n)을 넘는 모든 함수들의 집합이다. 즉, g(n) 내 최고차항의 차수가 k일 때, 최고차항의 차수가 k 이상인 함수 f(n)은 모두 Ω(g(n))이다.</p>
</li>
<li><p>Ω(g(n)) = {f(n): 모든 n ≥ n0, 양의 상수 c 존재, c * g(n) ≥ f(n)}</p>
</li>
</ul>
</li>
<li><p>빅-세타 표기법</p>
<ul>
<li><p>빅-세타(big-Θ) 표기법은 점근적 상한선과 점근적 하한선의 교집합을 나타낸다. 즉, 알고리즘은 빅-세타 표기법의 함수 범위 내에서 동작한다.</p>
</li>
<li><p>Θ(g(n))은 O(g(n))과  Ω(g(n))에 모두 속하는 함수들의 집합이다.</p>
</li>
<li><p>Θ(g(n)) = {f(n): 모든 n ≥ n0, 양의 상수 c1, c2 존재, c1 * g(n) ≤ f(n) ≤ c2 * g(n)}</p>
</li>
</ul>
</li>
</ol>
<p>+) 리틀-오, 리틀-오메가 표기법</p>
<ul>
<li><p>리틀-오, 리틀-오메가 표기법은 각각의 ‘빅’ 표기법과 비슷하나, 함수 집합에 해당 표기법 내 함수 g(n)과 최고 차항의 차수가 같은 함수는 포함되지 않는다. </p>
</li>
<li><p>이들은 각각 표기법의 ‘여유있는 상한’과 ‘여유있는 하한’을 의미한다. 점근적 의미에서 더 작거나, 더 커서 g(n)을 압도하거나 g(n)에 압도당하는 함수들의 집합이다.</p>
</li>
</ul>
<h3 id="점근적-표기법의-장점과-한계">점근적 표기법의 장점과 한계</h3>
<p><strong>점근적 표기법의 장점</strong></p>
<ul>
<li>효율성
: 점근적 표기법은 크기가 큰 입력에서, 알고리즘의 성능을 간편하게 비교할 수 있게 만든다.</li>
</ul>
<p><strong>점근적 표기법의 한계</strong></p>
<ul>
<li>외부 요소 무시
: 점근적 표기법은 입력 크기에 따른 성능만을 고려하기에, 다양한 조건 하에서의 실제 환경에서는 알고리즘 성능이 다르게 나올 수가 있다.</li>
</ul>
<h3 id="참고-자료">참고 자료</h3>
<p>문병로 (2013), ”쉽게 배우는 알고리즘“: 한빛아카데미.
칸 아카데미 <a href="https://ko.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/asymptotic-notation">https://ko.khanacademy.org/computing/computer-science/algorithms/asymptotic-notation/a/asymptotic-notation</a> </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ALG 0. 알고리즘 공부를 재개하다]]></title>
            <link>https://velog.io/@glenn_syj/ALG-0.-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B3%B5%EB%B6%80%EB%A5%BC-%EC%9E%AC%EA%B0%9C%ED%95%98%EB%8B%A4</link>
            <guid>https://velog.io/@glenn_syj/ALG-0.-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B3%B5%EB%B6%80%EB%A5%BC-%EC%9E%AC%EA%B0%9C%ED%95%98%EB%8B%A4</guid>
            <pubDate>Sun, 22 Oct 2023 07:29:52 GMT</pubDate>
            <description><![CDATA[<h2 id="알고리즘-공부를-재개하다">알고리즘 공부를 재개하다</h2>
<h3 id="들어가며">들어가며</h3>
<p><strong>문제상황</strong></p>
<ul>
<li><p>코딩테스트를 준비하며 틈틈이 기본적인 알고리즘을 공부해왔다. 그러나 졸업논문 준비, 와플스튜디오 과제 등으로 알고리즘을 공부하는 시간이 감소했다.</p>
<ul>
<li>이론을 공부하고 문제 풀이에서 사용하고 구현해보는 만큼이나, 글로써 기록을 남기고 쉽게 설명하는 연습이 필요하다.</li>
</ul>
</li>
<li><p>특히, 와플 스튜디오 프로젝트를 위해서라도 더욱 깔끔한 코드를 작성할 필요가 있다. 어떠한 코드는 언제 어디에서 분기해야 하는가? 어떠한 코드를 더욱 효율적으로 짤 순 없을까?</p>
<ul>
<li>이러한 고민은 특히 대량의 데이터를 다루거나 기기의 자원을 많이 써야하는 상황에서 필수적이다.</li>
</ul>
</li>
</ul>
<p><strong>학습 목표</strong></p>
<ol>
<li>코딩테스트에서 빈출되는 알고리즘을 학습하고, 백준이나 LeetCode 등 문제풀이에 사용해본다.</li>
<li>가능하다면 실제 업무에서의 활용성과 예시 역시도 고려해본다.</li>
<li>보충 학습 및 심화 학습으로 해당 코드를 응용해본다.</li>
</ol>
<h3 id="어떻게-공부할-것인가">어떻게 공부할 것인가?</h3>
<p><strong>학습 자료</strong></p>
<ul>
<li>Wikipedia, GeeksForGeeks 등의 웹사이트는 물론, Coursera 등의 동영상 강의를 활용한다. chatGPT와 알고리즘 서적 역시 이용한다.</li>
</ul>
<p><strong>학습 방식</strong></p>
<ul>
<li><p>psuedo code와 함께 Java/Kotlin 코드로 알고리즘을 구현한다. 알고리즘 구현 과정에서 알고리즘 내부 혹은 언어 내에서 주의해야 할 부분을 살펴본다.</p>
</li>
<li><p>더 나아간다면, 코딩테스트와 관련해서는 알고리즘 순서도를 작성하는 연습까지도 도전해본다.</p>
</li>
</ul>
<h3 id="과제와-프로젝트">과제와 프로젝트</h3>
<p><strong>학습 과제</strong></p>
<ul>
<li>과제는 웹사이트, 강의, 알고리즘 서적 내의 연습 문제 풀이나 chatGPT를 활용한 심화/보충 학습을 필수로 한다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[6. Adapter의 기본 개념과 응용]]></title>
            <link>https://velog.io/@glenn_syj/6.-Adapter%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%9D%91%EC%9A%A9</link>
            <guid>https://velog.io/@glenn_syj/6.-Adapter%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%9D%91%EC%9A%A9</guid>
            <pubDate>Thu, 12 Oct 2023 09:44:25 GMT</pubDate>
            <description><![CDATA[<h2 id="adapter의-기본-개념과-응용">Adapter의 기본 개념과 응용</h2>
<h3 id="들어가며">들어가며</h3>
<p><strong>학습 목표</strong></p>
<ol>
<li>Adapter의 기본적인 개념, 특징, 사용법, 주의사항을 숙지한다.</li>
<li>Adapter 클래스를 목적에 맞게 커스터마이징하는 방법을 살펴본다.</li>
</ol>
<p><strong>학습 상황</strong></p>
<ol>
<li>Adapter를 이용해서 틱택토 게임을 구현한다.</li>
<li>메인 게임 보드와 RecyclerView 내 게임 내역을 각기 다른 커스텀 어댑터 클래스를 이용해 구현해야 했다.</li>
</ol>
<h3 id="adapter란">Adapter란?</h3>
<p><strong>Adapter의 개념</strong></p>
<ul>
<li><p>Adapter는 중개자 역할을 수행하는 객체로, 데이터와 UI 요소 사이의 인터페이스 역할을 한다.</p>
</li>
<li><p>Adapter는 데이터를 UI 요소로 변환하여 표시하거나, UI 요소에서 사용자 입력을 데이터로 변환한다.</p>
</li>
<li><p>주로 ListView, RecyclerView, Spinner 및 GridView 등에서 쓰인다.</p>
</li>
</ul>
<p><strong>Adapter의 특징</strong></p>
<ul>
<li><p>데이터 소스 연결</p>
<p>Adapter는 데이터 소스 (배열, 목록, 데이터베이스)와 UI 요소 (리스트 아이템, 뷰 홀더) 간의 연결을 담당</p>
</li>
<li><p>재사용성</p>
<p>Adapter는 UI 요소의 재사용을 관리하며, 데이터카 스크롤될 때 UI 요소를 효율적으로 재사용한다. 이는 메모리 및 성능 향상에 도움이 된다.</p>
</li>
<li><p>데이터와 뷰 결합</p>
<p>Adapter는 데이터를 뷰에 바인딩하고 UI 요소를 데이터와 연결하여 데이터의 시각적 표현을 제공한다.</p>
</li>
</ul>
<p><strong>Adapter 사용법</strong></p>
<ol>
<li><p>데이터 소스를 설정한다. 이는 View에 표시하려는 내용이다.</p>
</li>
<li><p>Adapter 클래스를 사용하여 데이터를 UI 요소로 변환하고, UI 요소를 레이아웃 파일과 연결한다.</p>
</li>
<li><p>Activity에서 AdapterView에 Adapter와 (RecyclerView라면) LayoutManager를 설정한다.</p>
</li>
<li><p>Adapter에 대한 이벤트 처리 및 사용자 입력 처리를 설정한다.</p>
</li>
</ol>
<p><strong>Adapter 사용 시 주의사항</strong></p>
<ul>
<li><p>성능 최적화
Adapter는 UI에서 재사용되므로 데이터를 효율적으로 처리하고, 불필요한 객체 생성을 피해야 한다.</p>
</li>
<li><p>데이터 업데이트
데이터가 동적으로 변경되면 Adapter에 변경 사항을 알려야 한다.</p>
<ul>
<li>notifyDataSetChanged(), notifyItemChanged(position: Int), notifyItemInserted(position: Int), notifyItemRemoved(position: Int),
notifyItemRangeChanged(positionStart: Int, itemCount: Int) 등을 이용한다.</li>
</ul>
</li>
<li><p>뷰 홀더
뷰 홀더 패턴을 구현하여 뷰의 재사용을 최적화해야 한다</p>
</li>
<li><p>Null 체크
null 예외를 방지하기 위해 null 체크 수행</p>
</li>
<li><p>쓰레드
데이터 업데이트나 UI 업데이트는 메인 스레드에서 수행되어야 한다.</p>
</li>
</ul>
<h3 id="adapter-응용-커스텀-어댑터">Adapter 응용: 커스텀 어댑터</h3>
<p><strong>Adapter 클래스 커스터마이즈</strong></p>
<ol>
<li><p>Adapter 상속</p>
<ul>
<li>‘BaseAdapter’, ‘ArrayAdapter’, ‘RecyclerView.Adapter’ 등의 어댑터 클래스 중 하나를 상속한다.</li>
</ul>
</li>
<li><p>상속되는 추상 클래스에 필수적인 메서드 구현</p>
<ul>
<li>BaseAdapter를 상속해서 커스텀 어댑터를 만들 수 있다. 필수적으로 구현해야 하는 메서드는 다음과 같다.<ul>
<li>getCount(): 몇 개의 항목을 표시해야 하는 지, 데이터의 총 개수를 반환한다.</li>
<li>getItem(position: Int): 특정 위치에 잇는 데이터 항목을 반환한다.</li>
<li>getItemId(position: Int): 특정 위치에 있는 데이터 항목의 고유 ID를 반환한다.</li>
<li>getView(position: Int, convertView: View, parent: ViewGroup)이다.
→  각 데이터 아이템을 렌더링해서 View 객체로 반환한다. 여기에서 convertView는 재사용할 레이아웃 요소를 의미한다.
→ convertView는 재활용 가능한 뷰 객체로, 이전 화면에 나타난 뷰 중 재사용 가능한 뷰를 나타낸다. </li>
</ul>
</li>
</ul>
</li>
</ol>
<ul>
<li><p>ArrayAdapter는 BaseAdapter를 상속한 클래스로, 다음 메서드를 추가적으로 구현해야 한다.</p>
<ul>
<li><p>constructor(context: Context, resource: Int, objects: List<T>)</p>
<p>  Adapter를 초기화하는 생성자로 context는 액티비티 또는 컨텍스트, resourece는 각항목을 나타내는 레이아웃 리소스 ID, object는 리스트다.</p>
</li>
</ul>
</li>
</ul>
<ul>
<li>RecyclerView.Adapter에서는 뷰 홀더 패턴을 사용하는데, onCreateViewHolder 메서드 및 onBindViewHolder 메서드를 사용해 뷰 홀더를 생성하고 데이터를 바인딩한다.</li>
</ul>
<ol start="3">
<li><p>뷰 홀더 클래스 정의</p>
<ul>
<li>뷰 홀더 클래스를 내부 클래스로 정의하고, 해당 클래스에 뷰에 대한 참조를 저장한다.</li>
</ul>
</li>
<li><p>데이터 업데이트 메서드  및 이벤트 처리 추가</p>
<ul>
<li>Adapter 내에 데이터를 업데이트 하는 메서드를 추가하고, 이를 호출해 데이터를 업데이트하면 변경 사항을 반영한다. 이는 이벤트 처리를 통해 이루어질 수도 있다.</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[5. 뷰 바인딩의 개념, 특징, 그리고 한계]]></title>
            <link>https://velog.io/@glenn_syj/5.-%EB%B7%B0-%EB%B0%94%EC%9D%B8%EB%94%A9%EC%9D%98-%EA%B0%9C%EB%85%90-%ED%8A%B9%EC%A7%95-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%ED%95%9C%EA%B3%84</link>
            <guid>https://velog.io/@glenn_syj/5.-%EB%B7%B0-%EB%B0%94%EC%9D%B8%EB%94%A9%EC%9D%98-%EA%B0%9C%EB%85%90-%ED%8A%B9%EC%A7%95-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%ED%95%9C%EA%B3%84</guid>
            <pubDate>Wed, 11 Oct 2023 17:19:54 GMT</pubDate>
            <description><![CDATA[<h2 id="뷰-바인딩의-개념-특징-그리고-한계">뷰 바인딩의 개념, 특징, 그리고 한계</h2>
<h3 id="들어가며">들어가며</h3>
<p>** 학습 목표 **</p>
<ol>
<li>뷰 바인딩 개념과 사용법에 대해서 알아본다.</li>
<li>findViewById와의 차이점에 대해 알아본다.</li>
<li>뷰 바인딩의 한계에 대해 알아본다.</li>
</ol>
<p>** 학습 상황**</p>
<ol>
<li>1차 과제에서 주로 썼던 findViewById()는 비용이 크다.</li>
<li>뷰 바인딩을 이용해서 Tic Tac Toe 앱을 구현해야 했다.</li>
</ol>
<h3 id="뷰-바인딩이란">뷰 바인딩이란?</h3>
<p>** 뷰 바인딩 개념 **</p>
<ul>
<li><p>뷰 바인딩은 XML 레이아웃 파일의 결합 클래스를 생성하고, 해당 인스턴스에서 레이아웃 내 ID가 있는 뷰를 직접 참조할 수 있는 방식이다.</p>
</li>
<li><p>즉, 레이아웃 파일에서 정의한 UI 요소를 자바/코틀린 코드와 바인딩하여 더욱 효과적으로 조작하는 데 도움이 된다.</p>
</li>
</ul>
<p><strong>뷰 바인딩 사용법</strong></p>
<pre><code class="language-kotlin">android {
    buildFeatures {
        viewBinding = true
    }
}</code></pre>
<ul>
<li><p>build.gradle (app) 내에 위 코드를 추가하면, 뷰 바인딩을 이용할 수 있음.</p>
</li>
<li><p>뷰 바인딩에서는 바인딩 클래스가 자동으로 생성되기에, 해당 레이아웃 파일을 무시하려면 viewBindingIgnore = “true”를 레이아웃 파일의 루트 뷰에 추가하면 된다.</p>
</li>
<li><p>뷰 바인딩 과정</p>
<ol>
<li>inflate() 메서드 호출 시 활동에서 사용할 결합 클래스 인스턴스 생성</li>
<li>getRoot() 메서드를 호출하거나 Kotlin 속성 구문을 사용해서 루트 뷰를 가져옴</li>
<li>루트 뷰를 setContentVIew()에 전달</li>
</ol>
</li>
</ul>
<h3 id="findviewbyid와의-차이점">findViewById와의 차이점</h3>
<p><strong>findViewById의 한계</strong></p>
<ul>
<li><p>Null Safety가 보장되지 않음</p>
<p>해당하는 뷰를 찾지 못하면, null 값을 반환하므로 NPE 에러가 발생한다. 따라서 개발자는 null check를 명시적으로 수행해야 한다.</p>
</li>
</ul>
<ul>
<li><p>Type Safety가 보장되지 않음</p>
<p>findViewById는 뷰를 캐스팅해야 하므로, 타입 안정성이 떨어진다. 또한, ClassCastException 에러가 발생할 수 있다.</p>
</li>
<li><p>속도가 느리다</p>
<p>findViewById는 뷰 계층 구조에서 뷰를 검색하는 작업을 수행한다. 따라서 레이아웃이 복잡하고 계층 구조가 깊을 수록 검색 시간이 증가한다.</p>
</li>
</ul>
<p><strong>뷰 바인딩의 장점</strong></p>
<ul>
<li><p>Null Safety 지원</p>
<p>뷰 바인딩은 컴파일 과정에서 레이아웃 요소에 대해 뷰를 직접 참조하므로, 유효하지 않은 뷰 ID에 접근하여 NPE(Null pointer Exception)이 발생하는 경우가 없다.</p>
</li>
<li><p>Type Safety 지원</p>
<p>각 바인딩 클래스에 있는 필드 유형은 XML 파일에서 참조하는 뷰와 일치. 클래스 변환 예외 발생하지 않음.</p>
</li>
<li><p>비교적 빠른 속도</p>
<p>뷰 바인딩은 미리 생성된 바인딩 클래스를 이용하므로, findViewById에 비해 효율적이다.</p>
</li>
</ul>
<h3 id="뷰-바인딩의-한계">뷰 바인딩의 한계</h3>
<p>*<em>UI와 데이터
*</em></p>
<ul>
<li><p>뷰 바인딩은 UI 요소에서 타입 안정성에 중점을 두나, 데이터-UI 간 상호작용에는 약하다.</p>
</li>
<li><p>즉, 데이터 처리와 비즈니스 로직 처리에는 적합하지 않다.</p>
<p>  → 이를 위해서는 데이터 바인딩을 이용하거나, VIewModel &amp; LIveData, RxJava 등의 라이브러리를 이용해야 한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[4. 텍스트 크기: dp, sp 그리고 pt]]></title>
            <link>https://velog.io/@glenn_syj/4.-%ED%85%8D%EC%8A%A4%ED%8A%B8-%ED%81%AC%EA%B8%B0-dp-sp-%EA%B7%B8%EB%A6%AC%EA%B3%A0-pt</link>
            <guid>https://velog.io/@glenn_syj/4.-%ED%85%8D%EC%8A%A4%ED%8A%B8-%ED%81%AC%EA%B8%B0-dp-sp-%EA%B7%B8%EB%A6%AC%EA%B3%A0-pt</guid>
            <pubDate>Fri, 29 Sep 2023 05:08:20 GMT</pubDate>
            <description><![CDATA[<h2 id="텍스트-크기-dp-sp-그리고-pt">텍스트 크기: dp, sp 그리고 pt</h2>
<h3 id="들어가며">들어가며</h3>
<p><strong>학습 목표</strong></p>
<ol>
<li>텍스트 크기 단위 dp와 sp의 특징을 알아본다.</li>
<li>pt 단위는 왜 쓰지 않는지 살펴본다.</li>
</ol>
<p><strong>학습 상황</strong></p>
<ul>
<li>텍스트 크기를 늘리면서 익숙한 단위인 pt를 쓴 부분에 코드 리뷰를 받았다. (dp, sp, pt를 모두 섞어썼다.)</li>
</ul>
<h3 id="dp와-sp">dp와 sp</h3>
<p><strong>dp (density-independent pixel)</strong></p>
<ul>
<li><p>dp는 밀도 독립형 픽셀으로, 휴대폰 화면의 픽셀 밀도와 관련있다. </p>
</li>
<li><p>디스플레이의 밀도(DPI, Dots Per Inch)에 따라 텍스트 크기가 조정된다.</p>
<ul>
<li>고밀도 화면에서는 텍스트가 더 작게, 저밀도 화면에서는 텍스트가 더 크게 나타난다.</li>
</ul>
</li>
<li><p>서로 다른 여러 디바이스에서 디자인의 실제 크기를 보존해, 일관된 텍스트 크기를 유지하는 데 유용하다. (=<strong>밀도 독립성</strong>)</p>
</li>
<li><p>텍스트보다는 주로 레이아웃 크기에서 dp를 사용해 뷰가 두 화면에서 동일한 크기로 표시되도록 한다.</p>
</li>
</ul>
<p><strong>sp (scale-independent pixel)</strong></p>
<ul>
<li><p>sp는 확장 가능 픽셀으로, 기본적으로 dp와 같은 크기지만 사용자의 글꼴 크기 설정에 영향을 받는다.</p>
</li>
<li><p>글꼴 크기를 크게 하면 sp 지정 텍스트도 커지고, 글꼴 크기를 작게 하면 sp 지정 텍스트도 작아진다.</p>
</li>
<li><p>밀도 독립성과 글꼴 크기 조정을 보장해, 사용자에게 유연성을 제공하고 접근성을 개선할 수 있다.</p>
</li>
<li><p>안드로이드 개발자 문서에서는 텍스트 크기 정의에 sp를 써야한다고 말한다. (레이아웃에는 sp를 써서는 안된다.) </p>
</li>
</ul>
<h3 id="pt">pt</h3>
<p><strong>pt가 권장되지 않는 이유</strong></p>
<ul>
<li><p>pt는 밀도 독립적이지도, 장치 독립적이지도 않다.</p>
<ul>
<li>같은 크기의 두 화면에서도 픽셀 수가 다를 수 있다.</li>
</ul>
</li>
</ul>
<table>
<thead>
<tr>
<th align="center"><b> <strong>Fig 1. 화면 크기와 픽셀 밀도</strong> </b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/b3fa8294-9636-442a-8649-926998f06d11/image.png" width="50%" height="50%"></td>
</tr>
<tr>
<td align="center"><p style="text-align: center;"> 출처: <a href="https://developer.android.com/training/multiscreen/screendensities?hl=ko">https://developer.android.com/training/multiscreen/screendensities?hl=ko</a> </p></td>
</tr>
</tbody></table>
<ul>
<li>pt는 사용자가 글꼴 크기 조정에 영향을 받지 않아, 유연성과 접근성을 제공할 수 없다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[3. exported 속성과 기능]]></title>
            <link>https://velog.io/@glenn_syj/3.-exported-%EC%86%8D%EC%84%B1%EA%B3%BC-%EA%B8%B0%EB%8A%A5</link>
            <guid>https://velog.io/@glenn_syj/3.-exported-%EC%86%8D%EC%84%B1%EA%B3%BC-%EA%B8%B0%EB%8A%A5</guid>
            <pubDate>Thu, 28 Sep 2023 16:28:30 GMT</pubDate>
            <description><![CDATA[<h2 id="exported-속성과-기능">exported 속성과 기능</h2>
<h3 id="들어가며">들어가며</h3>
<p><strong>학습목표</strong></p>
<ol>
<li><em>AndroidManifest.xml</em> 파일 내, exported 속성의 기능을 살펴본다. </li>
<li>해당 값이 true 혹은 false일 경우를 비교한다.</li>
<li>intent 혹은 intent-filter와 exported 속성이 맺는 관계를 살펴본다.</li>
</ol>
<p><strong>상황</strong></p>
<ul>
<li><p>새로운 화면을 구현하기 위해 액티비티를 추가할 때, 빌드 시 <em>AndroidManifest.xml</em> 내 오류가 떴다.</p>
</li>
<li><p>오류를 해결하기 위해 추가한 xml코드는 아래와 같다.</p>
</li>
</ul>
<pre><code class="language-XML">&lt;activity
            android:name=&quot;.LoginActivity&quot;
            android:exported=&quot;true&quot;&gt;</code></pre>
<h3 id="exported-속성이란-무엇인가">exported 속성이란 무엇인가?</h3>
<p><strong>exported 속성의 역할</strong></p>
<ul>
<li><p>exported 속성은 <em>AndroidManifest.xml</em> 파일에서 액티비티를 정의할 때 사용된다.</p>
</li>
<li><p>특히, 해당 액티비티가 다른 어플리케이션의 구성요소에서 접근할 수 있는지 여부를 결정한다.</p>
</li>
</ul>
<p><strong>exported 속성과 값</strong></p>
<ul>
<li>exported=&quot;false&quot;<ul>
<li>intent-filter가 없는 경우, exported 속성의 기본값은 <strong>false</strong>다.</li>
<li>해당 액티비티는 다른 앱에서 직접적으로 접근할 수 없고, 아래 항목에서만 접근할 수 있다.</li>
</ul>
</li>
</ul>
<pre><code>1. 같은 애플리케이션의 구성요소
2. 사용자 ID가 같은 애플리케이션
3. 권한이 있는 시스템 구성요소</code></pre><ul>
<li><p>exported=&quot;true&quot;</p>
<ul>
<li><p>intent-filter가 있는 경우에 사용한다.</p>
</li>
<li><p>다른 앱에서 직접적으로 접근할 수 있으며, 명시적 인텐트에서 해당 액티비티의 클래스 이름을 사용하여 호출할 수 있다.</p>
</li>
</ul>
</li>
</ul>
<h3 id="intent와-exported-속성">intent와 exported 속성</h3>
<p><strong>명시적 인텐트를 통한 호출</strong></p>
<pre><code class="language-kotlin">val intent = Intent()
intent.component = ComponentName(&quot;com.example.otherapp&quot;, &quot;com.example.otherapp.LoginActivity&quot;)
startActivity(intent)</code></pre>
<ul>
<li>다른 앱에서 명시적 인텐트를 이용하여 LoginActivity를 호출할 수 있다.</li>
</ul>
<p><strong>위험성</strong></p>
<ul>
<li><p>다른 앱의 개발자가 구성요소 이름을 알아낸다면, 다른 앱이 해당 앱의 구성요소를 실행시킬 수 있다. </p>
</li>
<li><p>따라서 보안 메커니즘, 권한 관리, 외부 앱에서의 액세스에 유의해야 한다.</p>
</li>
<li><p>안드로이드 개발자 문서에서는 외부 앱으로부터 접근을 막기 위해, 다음과 같은 방식을 제시한다.</p>
<blockquote>
<p>자신의 앱만 구성 요소를 시작하는 것이 중요할 경우 매니페스트에 인텐트 필터를 선언하지 마세요. 그 대신 해당 구성 요소에 대해 exported 특성을 &quot;false&quot;로 설정하세요.</p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2. Intent와 Intent-filter의 역할]]></title>
            <link>https://velog.io/@glenn_syj/2.-Intent%EC%99%80-Intent-filter%EC%9D%98-%EC%97%AD%ED%95%A0</link>
            <guid>https://velog.io/@glenn_syj/2.-Intent%EC%99%80-Intent-filter%EC%9D%98-%EC%97%AD%ED%95%A0</guid>
            <pubDate>Tue, 26 Sep 2023 06:08:44 GMT</pubDate>
            <description><![CDATA[<h2 id="intent와-intent-filter의-역할">Intent와 Intent-filter의 역할</h2>
<h3 id="들어가며">들어가며</h3>
<p><strong>학습목표</strong></p>
<ol>
<li>Intent가 하는 역할을 살펴본다.</li>
<li>Intent와 Intent-filter가 맺는 관계를 살펴본다.</li>
<li><em>AndroidManifest.xml</em> 에서, Intent-filter 부분을 살펴본다.</li>
</ol>
<p>** 상황 **</p>
<ul>
<li>특정 버튼을 클릭하면, 다른 Activity로 화면이 넘어가고 값이 전달되는 로직을 구성해야 했다.</li>
<li>아래의 XML 코드가 어떤 기능을 하는지 살펴보아야 했다.</li>
</ul>
<pre><code class="language-XML">&lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
&lt;/intent-filter&gt;</code></pre>
<h3 id="intent란-무엇인가">Intent란 무엇인가?</h3>
<p><strong>Intent의 기능</strong></p>
<ul>
<li>Intent는 액티비티, 서비스, Broadcast Receiver, 콘텐츠 제공자라는 앱 컴포넌트 간 작업을 요청하거나 수행하며, 데이터를 전달하는 데 쓰인다.</li>
<li>안드로이드 개발자 문서에서는 크게 (1) 액티비티 시작 (2) 서비스 시작 (3) 브로드캐스트 전달 이라는 세 사례로 쓰임을 나눈다.</li>
</ul>
<p><strong>Intent의 형식</strong></p>
<ul>
<li>Intent 객체는 작업을 수행할 구성 요소 판별에 필요한 정보를 담고 있다. </li>
</ul>
<ul>
<li>Intent 객체는 (1) Action (2) Data (3) Category (4) Component Name (5) Extras (6) Flags 로 구성되어 있다.<ul>
<li>Action은 수행하려는 작업을 나타낸다.</li>
<li>Data는 작업과 관련된 데이터로, 주로 Uri(Uniform Resource Information) 객체가 쓰인다.</li>
<li>Category는 해당 액티비티가 어떤 종류의 카테고리에 속하는 지 지정한다. </li>
<li><strong>Extras는 Intent 내 키-값 쌍의 추가 정보를 다른 컴포넌트에 전달할 수 있게 해준다.</strong><ul>
<li>putExtra() 메서드로 키-값 쌍을 추가하거나, Bundle 객체를 Intent에 putExtra()로 삽입할 수 있다.</li>
<li>키-값 쌍을 전달 받는 컴포넌트는 getExtra() 메서드를 이용할 수 있다. </li>
</ul>
</li>
<li>Flags는 Intent 동작을 제어하는 데 사용된다.</li>
</ul>
</li>
</ul>
<p><strong>Intent의 유형</strong></p>
<ul>
<li>명시적 인텐트는 액티비티나 서비스의 클래스 이름을 명확하게 드러낸다.<ul>
<li>화면 전환에 쓰이는 방식은 명시적 인텐트다.</li>
</ul>
</li>
</ul>
<ul>
<li>암시적 인텐트는 시스템에 수행할 특정 작업을 요청하면, 시스템이 해당 작업을 처리할 수 있는 다른 구성요소를 찾아서 처리하도록 한다.</li>
</ul>
<p><strong>대표 예시</strong></p>
<pre><code class="language-kotlin">import android.content.Intent

// 액티비티 간 이동을 위한 명시적 Intent 생성 예제
val intent = Intent(this, TargetActivity::class.java)
startActivity(intent)

// 웹페이지 열기를 위한 암시적 Intent 생성 예제
val webPageUri = Uri.parse(&quot;http://www.example.com&quot;)
val webIntent = Intent(Intent.ACTION_VIEW, webPageUri)
startActivity(webIntent)</code></pre>
<ul>
<li>명시적 인텐트에서 this는 현재 액티비티를 나타내고, TargetActivity는 이동할 목표 액티비티를 의미한다.</li>
</ul>
<ul>
<li>암시적 인텐트에서 Intent.ACTION_VIEW는 웹페이지를 여는 액션을 의미하고, Uri.parse()는 URL을 Uri로 변환하여 인텐트에 포함시킨다.</li>
</ul>
<h3 id="intent-filter란-무엇인가">Intent-filter란 무엇인가?</h3>
<p><strong>Intent-filter의 역할</strong></p>
<ul>
<li>Intent-filter는 안드로이드 매니페스트 파일 내에서 정의되어,  앱의 컴포넌트가 어떤 인텐트를 수신하고 처리할 것인지를 알려준다. 이는 곧 암시적 인텐트다. </li>
</ul>
<ul>
<li>시스템은 액션, 데이터, 카테고리에 따라 인텐트를 인텐트 필터에 비교한다. 모두 통과해야만 해당 인텐트가 컴포넌트에 전달된다.</li>
</ul>
<ul>
<li>Intent 내의 모든 카테고리가 인텐트 필터에 선언된 카테고리에 속해야 한다. 카테고리가 없는 인텐트는 필터에 무관하게 비교를 통과한다. </li>
</ul>
<h3 id="xml-코드-이해">XML 코드 이해</h3>
<p><strong>intent-filter 내 코드 살펴보기</strong></p>
<pre><code class="language-XML">&lt;intent-filter&gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;

                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
&lt;/intent-filter&gt;</code></pre>
<ul>
<li>ACTION_MAIN 액션은 주요 진입지점인 동시에 어떤 인텐트 데이터도 기대하지 않음을 나타낸다.</li>
</ul>
<ul>
<li>CATEGORY_LAUNCHER 카테고리는 해당 액티비티의 아이콘이 시스템의 앱 시작 관리자에 배치됨을 나타낸다.</li>
</ul>
<ul>
<li>&lt;action&gt;, &lt;data&gt;, &lt;category&gt;는 각각 허용된 인텐트 작업, 데이터 유형, 인텐트 카테고리를 선언한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[1. Android를 배우다]]></title>
            <link>https://velog.io/@glenn_syj/1-Android%EB%A5%BC-%EB%B0%B0%EC%9A%B0%EB%8B%A4</link>
            <guid>https://velog.io/@glenn_syj/1-Android%EB%A5%BC-%EB%B0%B0%EC%9A%B0%EB%8B%A4</guid>
            <pubDate>Sun, 24 Sep 2023 17:14:38 GMT</pubDate>
            <description><![CDATA[<h2 id="android를-배우다">Android를 배우다</h2>
<h3 id="1-들어가며">1. 들어가며</h3>
<ul>
<li><p>와플스튜디오 21.5기에 합격하여, Android 세미나를 듣고 있다. 스프링을 혼자서 공부하며, 함께 리액트/안드로이드를 배워두고 싶었다.</p>
<ul>
<li>새로운 분야를 탐색하는 동시에, 이후 특정 웹/어플리케이션에서 DB를 효율적으로 연동하거나 관리하는 데 필요한 지식을 얻기를 기대한다.</li>
</ul>
</li>
<li><p>공부에 크게 도움이 되는 방향으로 코드 리뷰를 해주셔서 감사하다. 비록 간단해보일지라도, 코딩 컨벤션 자체는 물론 코딩 테스트 준비에서도 적용되는 중요한 리뷰들이 많다. </p>
</li>
<li><p>여전히 진행중이지만 (1) 코드 리뷰를 받았거나, (2) 프로젝트 진행 중 기록해두면 유용한 내용을 기록한다.</p>
</li>
</ul>
<h3 id="2-어떻게-공부할-것인가">2. 어떻게 공부할 것인가?</h3>
<ul>
<li><p>학습 과정에서 chatGPT를 최대한 많이 자주 사용하려고 한다. 적절한 질문으로 얻어낸 정보에 기반해서 Android Developer 공식 문서를 포함해, 여러 문서를 참고한다. </p>
</li>
<li><p>코틀린 안드로이드를 공부하며 프로젝트를 진행한다. 자바를 공부해왔기 때문에, 코틀린이 더욱 효율적으로 느껴지기도 한다. 코틀린에 걸맞는 방식을 고민하고 이용한다.</p>
</li>
<li><p>비록 아직은 적극적으로 활용하진 않지만, 단순 질문만이 아니라 공유하면 좋을 내용도 슬랙 잡담방에 공유해보려고 한다.</p>
</li>
</ul>
<h3 id="3-과제와-프로젝트">3. 과제와 프로젝트</h3>
<ul>
<li><p>과제는 Git을 이용해 fork &amp; pull request를 이용한다. 과제 제출에서 브랜치를 이용하듯, 개인 프로젝트에서도 브랜치를 이용해 기능을 분리해서 구현해본다.</p>
</li>
<li><p>개인 프로젝트로는 &quot;오늘공부&quot; 앱을 간단하게 만들어보려고 한다. &quot;오늘공부&quot;는 친구들과 각자 공부를 이어나가며, 당일에 배웠던 내용을 간단하게 기록하여 복습하는 어플리케이션이다.</p>
<ul>
<li>연속 공부 일수, 최대 공부 일수, 프로필 등의 기능과 함께 레이아웃을 계획하고 구현해본다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2023.08 solved.ac 후기]]></title>
            <link>https://velog.io/@glenn_syj/2023.08-solved.ac-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@glenn_syj/2023.08-solved.ac-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sun, 03 Sep 2023 08:15:03 GMT</pubDate>
            <description><![CDATA[<h3 id="2023년-8월의-solvedac-기록">2023년 8월의 Solved.ac 기록</h3>
<img src="https://velog.velcdn.com/images/glenn_syj/post/5683bb96-a889-4444-8004-75c03a36fa8d/image.png" width="60%" height="60%">
<img src="https://velog.velcdn.com/images/glenn_syj/post/cab208f3-4146-4712-8807-e00d143e4247/image.png" width="80%" height="80%">

<h4 id="달성-기록과-공부-계획">달성 기록과 공부 계획</h4>
<ul>
<li><p>골드 5를 달성했다.  </p>
<ul>
<li>&quot;어떻게 잘 풀 것인가?&quot; 하는 질문과 함께 &quot;어떻게든 푼다&quot;는 마인드셋의 중간에 있다.</li>
<li>Dynamic Programming, Tree/Heap를 더 탄탄히 할 필요가 있다.</li>
<li>이제 한 달 간 복습과 함께 백트래킹, 그리디 알고리즘, DFS, BFS, 그래프 이론을 공부한다.</li>
</ul>
</li>
</ul>
<h4 id="짧은-후기">짧은 후기</h4>
<ul>
<li><p>8월은 본격적으로 정렬 알고리즘부터 다시 살펴보며 자바로 구현하고, 문제를 풀어보는 시간을 가지겠다.</p>
<ul>
<li>내가 잘 알고 있는지 손코딩을 해보기도 하는데, pseudo code와 다른 맛이 있어서 재밌다.</li>
</ul>
</li>
<li><p>다른 풀이를 찾아보면서, 새로 알게된 점을 꾸준히 정리할 필요가 있다. 내 풀이에서 부족한 점 역시 반성해야 한다.</p>
<ul>
<li>이전에 풀었던 문제 역시 코드를 더 쉽게 설명할 수 있도록 글을 써본다.</li>
<li>제대로 객체지향적인 코드를 짜본다.</li>
</ul>
</li>
</ul>
<h4 id="다음-목표">다음 목표</h4>
<ul>
<li><p>9월에는 골드3 이상에 진입한다. </p>
<ul>
<li>티어보다 공부 밀도에 집중한다.</li>
<li>&#39;와플 스튜디오&#39;에 합격했기에 9월부터는 안드로이드 세미나도 듣고, 개인적으로 스프링 공부도 시작해야 하므로 PS는 복습과 구현에 초점을 둬본다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[2023.07 Solved.ac 후기]]></title>
            <link>https://velog.io/@glenn_syj/2023.07-Solved.ac-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@glenn_syj/2023.07-Solved.ac-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Tue, 01 Aug 2023 10:35:36 GMT</pubDate>
            <description><![CDATA[<h3 id="2023년-7월의-solvedac-기록">2023년 7월의 Solved.ac 기록</h3>
<img src="https://velog.velcdn.com/images/glenn_syj/post/4677538d-a2b2-4957-89c2-f9d6007a4410/image.png" width="60%" height="60%">

<img src="https://velog.velcdn.com/images/glenn_syj/post/447f64b8-972e-4873-b055-6c3376d0ea81/image.png" width="80%" height="80%">


<ul>
<li><p>Python으로 풀던 계정이 있었으나, Java를 공부하기 위해 새로 계정을 만들었다. </p>
<ul>
<li>정적 타이핑 언어의 불편함과 편안함을 함께 느끼고 있다.</li>
<li>파이썬에서는 트릭으로 풀어서 유야무야 넘어갔던 곳을 다시 제대로 볼 수 있다.</li>
</ul>
</li>
<li><p>잔디를 심던 도중, 휴가 겸 여행을 다녀 와서 streak이 깨졌다.</p>
</li>
<li><p>8월은 본격적으로 정렬 알고리즘부터 다시 살펴보며 자바로 구현하고, 문제를 풀어보는 시간을 가지겠다.</p>
<ul>
<li>내가 잘 알고 있는지 손코딩을 해보기도 하는데, pseudo code와 다른 맛이 있어서 재밌다.</li>
</ul>
</li>
<li><p>다른 풀이를 찾아보면서, 새로 알게된 점을 꾸준히 정리할 필요가 있다. 내 풀이에서 부족한 점 역시 반성해야 한다.</p>
<ul>
<li>이전에 풀었던 문제 역시 코드를 더 쉽게 설명할 수 있도록 글을 써본다.</li>
<li>제대로 객체지향적인 코드를 짜본다.</li>
</ul>
</li>
<li><p>8월에는 골드5 이상에 진입한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바의 정석 2장 (1) 변수 (2) 변수의 타입]]></title>
            <link>https://velog.io/@glenn_syj/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-2%EC%9E%A5-1-%EB%B3%80%EC%88%98-2-%EB%B3%80%EC%88%98%EC%9D%98-%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@glenn_syj/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-2%EC%9E%A5-1-%EB%B3%80%EC%88%98-2-%EB%B3%80%EC%88%98%EC%9D%98-%ED%83%80%EC%9E%85</guid>
            <pubDate>Thu, 06 Apr 2023 09:15:09 GMT</pubDate>
            <description><![CDATA[<h2 id="1-변수">1. 변수</h2>
<h3 id="11-변수란">1.1 변수란?</h3>
<p><strong>변수 개념</strong></p>
<p>값을 저장할 수 있는 메모리 상의 공간 → “단 하나의 값”</p>
<h3 id="12-변수의-선언과-초기화">1.2 변수의 선언과 초기화</h3>
<p><strong>변수의 초기화</strong></p>
<ul>
<li><p>int age; — 변수 타입과 변수 이름</p>
</li>
<li><p>초기화(initialization)</p>
<p>  메모리는 여러 프로그램이 공유하는 자원이므로 전에 다른 프로그램에 의해 저장된 ‘알 수 없는 값(쓰레기값, garbage value)’이 남아있을 수 있기 때문</p>
</li>
<li><p>대입 연산자 ‘=’을 사용</p>
<p>  지역 변수는 사용되기 전에 초기화를 반드시 해야하지만, 클래스 변수와 인스턴스 변수는 초기화 생략 가능</p>
</li>
<li><p>초기화는 변수를 사용하기 전에 처음으로 값을 저장하는 것</p>
</li>
</ul>
<p><strong>두 변수의 값 교환하기</strong></p>
<pre><code class="language-java">int x = 10;
int y = 20;
int tmp;</code></pre>
<ul>
<li>tmp를 임시 저장소로 사용</li>
</ul>
<h3 id="13-변수의-명명규칙">1.3 변수의 명명규칙</h3>
<p><strong>식별자</strong></p>
<ul>
<li><p>식별자(identifier): 프로그래밍에서 사용하는 모든 이름 → 서로 구분될 수 있어야 함</p>
</li>
<li><p>명명 규칙</p>
<ol>
<li><p>대소문자가 구분되며, 길이에 제한이 없다</p>
</li>
<li><p>예약어를 사용해서는 안 된다 (구문 사용 단어)</p>
</li>
<li><p>숫자로 시작해서는 안 된다</p>
</li>
<li><p>특수문자는 ‘_’와 ‘$’만을 허용한다.</p>
</li>
</ol>
</li>
<li><p>코딩 컨벤션</p>
<ol>
<li><p>클래스 이름의 첫 글자는 항상 대문자로 한다</p>
<p> → 변수와 메서드의 이름 첫 글자는 항상 소문자로 한다</p>
</li>
<li><p>여러 단어로 이루어진 이름은 단어의 첫 글자를 대문자로 한다</p>
<p> ex) lastIndexOf, StringBuffer</p>
</li>
<li><p>상수의 이름은 모두 대문자로 한다. 여러 단어로 이루어진 경우 ‘_’로 구분한다</p>
<p> ex) PI, MAX_NUMBER</p>
</li>
</ol>
</li>
<li><p>‘의미 있는 이름’ ← 변수의 선언문에 주석으로 정보를 주는 것도 좋다</p>
</li>
</ul>
<h2 id="2-변수의-타입">2. 변수의 타입</h2>
<p><strong>자료형</strong></p>
<ul>
<li><p>자료형(data type): 값이 저장될 크기와 저장형식을 정의</p>
<p>  → 문자형, 정수형, 실수형, …</p>
</li>
</ul>
<p><strong>기본형과 참조형</strong></p>
<ul>
<li>기본형 변수: 실제 값(data)을 저장 ↔ 참조형 변수: 값이 저장된 주소(memory address)를 값으로 가짐</li>
<li>자바는 참조형 변수 간의 연산을 할 수 없으므로 연산에 사용 되는 건 모두 기본형 변수<ol>
<li>기본형: 논리형, 문자형, 정수형, 실수형</li>
<li>참조형: 나머지 타입</li>
</ol>
</li>
<li>새로운 클래스 — 새로운 참조형 (변수의 타입으로 클래스 이름 사용)
→ 참조형 변수는 null 또는 객체의 주소를 값으로 가짐
→ 참조형은 항상 ‘객체의 주소’를 저장하므로 ‘type’ (&gt; ‘data type’)</li>
</ul>
<h3 id="21-기본형primitive-type">2.1 기본형(primitive type)</h3>
<p><strong>논리형, 문자형, 정수형, 실수형</strong></p>
<ul>
<li>int → CPU가 가장 효율적으로 처리할 수 있는 타입</li>
<li>byte, short → 효율적인 실행보다 메모리 절약</li>
</ul>
<p><strong>기본 자료형의 종류와 크기</strong></p>
<table>
<thead>
<tr>
<th align="center"><b> Fig 1. Java 기본 자료형의 값 범위 및 크기</b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/c9236e83-8b6e-44e3-97b3-c018f184db69/image.jpeg" alt="Java 기본 자료형의 종류와 크기"></td>
</tr>
</tbody></table>
<p><strong>각 타입의 변수가 저장할 수 있는 값의 범위</strong></p>
<ul>
<li><p>정수형의 경우, ‘-2^(n-1) ~ 2^(n-1)-1’ (n은 비트수)를 범위로 가짐</p>
</li>
<li><p>실수형은 정수형과 저장형식이 달라 같은 크기라도 훨씬 큰 값을 표현 가능</p>
<p>  → 그러나 오차가 발생할 수 있음 (정밀도가 높을수록 오차범위 줄어듦)</p>
<p>  → float: 정밀도 7자리, double: 정밀도 15자리</p>
<p>  → 10진수로 정밀도 X 자리의 수를 오차 없이 저장할 수 있다</p>
</li>
</ul>
<h3 id="22-상수와-리터럴-constant-and-literal">2.2 상수와 리터럴 (constant and literal)</h3>
<p><strong>상수</strong></p>
<ul>
<li>상수(constant): 한 번 값을 저장하면 다른 값으로 변경할 수 없음 + 선언과 동시에 초기화</li>
</ul>
<p><strong>리터럴</strong></p>
<ul>
<li>그 자체로 값을 의미하는 것 ← 변수에 값을 대입할 때, 대입하는 바로 그 값이 리터럴</li>
</ul>
<p><strong>상수가 필요한 이유</strong></p>
<ul>
<li>리터럴에 ‘의미있는 이름’을 붙여서 코드의 이해와 수정을 쉽게 만든다</li>
</ul>
<p><strong>리터럴의 타입과 접미사</strong></p>
<table>
<thead>
<tr>
<th align="center"><b> Fig 2. 타입 종류에 따른 리터럴과 접미사</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/9285b1d0-7874-470a-903a-777461232166/image.jpeg" alt="타입 종류에 따른 리터럴과 접미사"></td>
</tr>
<tr>
<td align="center">- 변수의 타입은 저장될 ‘값의 타입’에 의해 결정됨</td>
</tr>
<tr>
<td align="center">- JDK1.7부터 정수형 리터럴의 중간에 구분자 ‘_’를 넣을 수 있게 되어서 큰 숫자를 편하게 읽을 수 있게 됨</td>
</tr>
</tbody></table>
<pre><code class="language-java">long big = 100_000_000_000L;
long hex = 0xFFFF_FFFF_FFFF_FFFL;
float pi = 3.14f; // float pi = 3.14; &lt;- Error!
double rate = 1.618d;</code></pre>
<ul>
<li><p>접두사 ‘0x’, ‘0X’: 16진수 / ‘0’: 8진수</p>
</li>
<li><p>실수형 리터럴인데, 접미사가 없으면 double 타입 리터럴</p>
</li>
<li><p>소수점이나 10의 제곱을 나타내는 기호 E 혹은 e, 접미사 f, F, d, D를 포함하면 실수형 리터럴</p>
</li>
<li><p>잘 쓰이지는 않지만, 기호 p를 이용해 실수 리터럴을 16진 지수형태로 표현 가능</p>
<p>  → p는 2의 제곱을 의미: p의 왼쪽에는 16진수, 오른쪽에는 10진 정수</p>
</li>
</ul>
<p><strong>타입의 불일치</strong></p>
<pre><code class="language-java">int i = &#39;A&#39;;
long l = 123;
double d = 3.14f;

int i = 0x123456789; // 에러. int값 범위 넘음
float f = 3.14; // 에러. float 범위 &lt; double 범위</code></pre>
<ul>
<li><p>타입이 달라도 저장범위가 넓은 타입에 좁은 타입의 값을 저장하는 것은 허용됨</p>
<p>  → 그러나 리터럴의 값이 변수의 타입을 넘어서간, 리터럴의 타입이 범위가 더 넓으면 에러</p>
<p>  → byte와 short 타입은 리터럴 따로 존재 X: 범위 내에서 int 타입의 리터럴 사용</p>
</li>
<li><p>double 타입은 float 타입의 변수에 저장할 수 없음</p>
</li>
</ul>
<p><strong>문자 리터럴과 문자열 리터럴</strong></p>
<pre><code class="language-java">String str = &quot;&quot;; // OK. 내용이 없는 빈 문자열
char   ch  = &#39;&#39;; // 에러. &#39;&#39; 안에 반드시 하나 필요
char   ch  = &#39; &#39;; // OK. 공백 문자로 변수 초기화.</code></pre>
<ul>
<li><p>문자 리터럴 = 문자 하나, 문자열 = 문자 둘 이상</p>
<p>  → 문자열 리터럴은 “”안에 아무런 문자 넣지 않는 것 허용(empty string)</p>
<p>  → 반면, 문자 리터럴은 ‘’안에 하나의 문자가 있어야 함.</p>
</li>
<li><p>원래 스트링은 클래스이므로 객체 생성 연산자 new를 사용해야 하지만, 특별히 위 표현 허용</p>
</li>
<li><p>추가적으로, 스트링은 덧셈연산자를 이용해 문자열 결합 가능 (왼쪽 → 오른쪽 진행)</p>
<p>  피연산자중 어느 한 쪽이 String 이면 나머지 한 쪽을 먼저 String으로 변환한 다음 두 String 결합</p>
<p>  → 기본형 타입의 값을 문자열로 변환할 때는 아무런 내용도 없는 빈 문자열을 더하기</p>
</li>
</ul>
<h3 id="23-형식화된-출력---printf">2.3 형식화된 출력 - printf()</h3>
<p><strong>println()과 printf()의 차이</strong></p>
<ul>
<li><p>println()은 사용하기엔 편하지만 변수의 값을 그대로 출력 → 값을 변환하지 않고는 출력 X</p>
<p>  ↔ printf()는 지시자(specifier)를 통해 변수의 값을 여러가지 형식으로 변환하여 출력</p>
<p>  → 정수형 변수에 저장된 값을 십진수로 변형할 때는 %d를 사용</p>
<p>  → 출력될 값과 지시자의 개수 및 순서는 일치해야 함</p>
</li>
<li><p>printf()는 줄바꿈을 하지 않는다 → 지시자 %n을 따로 넣어줘야 한다 (\n보다 안전)</p>
</li>
</ul>
<p><strong>printf()의 지시자</strong></p>
<table>
<thead>
<tr>
<th align="center"><b> Fig 3. printf() 지시자</b></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/deebc506-ec8e-432e-86fc-3d7df942ccc4/image.jpeg" alt=""></td>
</tr>
</tbody></table>
<ul>
<li><p>정수를 출력할 때는 지시자 %d를 사용하는데, 출력될 값이 차지할 공간을 숫자로 지정 가능</p>
<p>  → 간격 맞춰 출력할 때 필수</p>
</li>
<li><p>정수 출력 예시</p>
<ol>
<li><p>‘%5d’ → 5자리 차지, 우측 정렬, 나머지 빈 공간</p>
</li>
<li><p>‘%-5d’ → 5자리 차지, 좌측 정렬, 나머지 빈 공간</p>
</li>
<li><p>‘%0d’ → 5자리 차지, 우측 정렬, 나머지 0</p>
</li>
<li><p>지시자 ‘%x’와 ‘%o’에 ‘#’을 사용하면 접두사 ‘0x’와 ‘0’이 각각 붙는다</p>
<p> → 그리고 ‘%X”는 16진수 사용 접두사와 영문자를 대문자로 출력한다</p>
</li>
</ol>
</li>
<li><p>10진수를 2진수로 출력해주는 지시자는 없기에, 정수를 2진 문자열로 변환해주는 ‘Integer.toBinarySTring(int i)’를 사용해야 한다</p>
<p>  → 정수를 2진수로 변환해서 문자열로 반환하므로 지시자 ‘%s’를 사용</p>
</li>
<li><p>C언어에서는 char 타입의 값을 지시자 ‘%d’로 출력할 수 있지만, 자바에서는 허용되지 않는다</p>
<pre><code class="language-java">  System.out.printf(&quot;c=%c, %d %n&quot;, c, (int)c); // 형변환이 꼭 필요하다</code></pre>
<p>  → int 타입으로 형변환해야만 ‘%d’로 출력할 수 있다.</p>
</li>
<li><p>%f는 기본적으로 소수점 아래 6자리까지만 출력. 따라서 소수점 아래 7자리에서 반올림.</p>
<pre><code class="language-java">  System.out.printf(&quot;d = %14.10f%n&quot;, d); 
  // 전체 14자리 중 소수점 아래 10자리, 소수점 아래 빈 자리는 모두 0, 정수의 빈자리는 공백
  System.out.printf(&quot;d = %014.10f%n&quot;, d); 
  // 전체 14자리 중 소수점 아래 10자리, 소수점 아래와 정수부 양쪽 빈자리를 모두 0으로 채움</code></pre>
<p>  → 소수점 아래의 자리수를 지정할 수도 있다</p>
</li>
<li><p>지시자 ‘%s’도 숫자를 추가하면 원하는 만큼의 출력 공간 확보 혹은 문자열 일부 출력 가능</p>
<p>  ‘%’ : 포맷 문자열 시작</p>
<p>  ‘.’ 왼쪽의 수: 필드의 최소 너비 지정</p>
<p>  ‘.n’: 최대 문자열 길이 지정 (n=숫자)</p>
<p>  ‘s’: 문자열</p>
<pre><code class="language-java">  System.out.printf(&quot;[%s]%n&quot;,    url); // 문자열의 길이만큼 출력공간 확보
  System.out.printf(&quot;[%20s]%n&quot;,  url); // 최소 20글자 출력공간 확보. (우측 정렬)
  System.out.printf(&quot;[%-20s]%n&quot;, url); // 최소 20글자 출력공간 확보. (좌측 정렬)
  System.out.printf(&quot;[%.8s]%n&quot;,  url); // 왼쪽에서 8글자만 출력
  System.out.printf(&quot;[%8.8s]%n&quot;, url); // 오른쪽에서 8글자만 출력
</code></pre>
</li>
</ul>
<h3 id="24-화면에서-입력받기---scanner">2.4 화면에서 입력받기 - Scanner</h3>
<p><strong>Scanner 클래스 이용 전</strong></p>
<ul>
<li><p>최신 방법은 JDK 1.6 부터 추가된 Console 클래스를 이용</p>
<p>  → IDE에서 잘 동작하지 않으므로 Scanner 클래스 이용</p>
</li>
</ul>
<p><strong>Scanner 클래스 이용 과정</strong></p>
<pre><code class="language-java">import java.util.*

Scanner scanner = new Scanner(System.in); // Scanner 클래스의 객체를 생성
String input = scanner.nextLine(); // 입력 받은 내용을 input에 저장
int num = Integer.parseInt(input); // 입력받은 내용을 input 타입의 값으로 변환

// 입력받은 문자열을 숫자로 변환하려면 Integer.parseInt() 이용 (string -&gt; int)
// 입력받은 문자열을 정수로 변환하려면 Float.parseFloat() 이용 (string -&gt; float)</code></pre>
<ul>
<li><p>사실 스캐너 클래스에는 nextInt()나 nextFloat()와 같이 변환 없이 숫자로 바로 입력받을 수 있는 메서드도 있음</p>
<pre><code class="language-java">  import java.util.*;

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

          System.out.print(&quot;두자리 정수를 하나 입력해주세요.&gt;&quot;);
          String input = scanner.nextLine();
          int num = Integer.parseInt(input); // 입력받은 문자열을 숫자로 변환

          System.out.println(&quot;입력내용 :&quot;+input);
          System.out.printf(&quot;num=%d%n&quot;, num);
          }
  }</code></pre>
<p>  → 그러나 연속적으로 값을 입력 받아 사용하기에 까다롭다</p>
<p>  → 모든 값을 nextLine()으로 입력받아 적절히 변환하는 게 낫다</p>
<p>  → 숫자가 아닌 문자 또는 기호를 입력하면, 에러 발생 (공백 입력 주의!)</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[오브젝트 1장 객체, 설계 (2) 무엇이 문제인가]]></title>
            <link>https://velog.io/@glenn_syj/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-1%EC%9E%A5-%EA%B0%9D%EC%B2%B4-%EC%84%A4%EA%B3%84-2-%EB%AC%B4%EC%97%87%EC%9D%B4-%EB%AC%B8%EC%A0%9C%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@glenn_syj/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-1%EC%9E%A5-%EA%B0%9D%EC%B2%B4-%EC%84%A4%EA%B3%84-2-%EB%AC%B4%EC%97%87%EC%9D%B4-%EB%AC%B8%EC%A0%9C%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Wed, 05 Apr 2023 06:02:51 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p><strong>글과 관련해</strong></p>
<ul>
<li>코드 내에서 쓰이는 주석은 제가 추가로 단 것입니다.</li>
<li>모든 코드는 해당 책에서 참고했습니다.</li>
<li>&#39;나가며&#39; 파트는 저 스스로 던져보는 질문입니다.</li>
</ul>
<p><strong>선요약 및 정리</strong></p>
<ul>
<li>지난 시간에는 티켓 판매라는 일에 관련된 여러 클래스를 구현해보았습니다. 이번 시간에는 지난 시간에 짠 코드의 문제점을 살펴봅니다.</li>
<li>1장 (2)에서 중심 내용은 1장 (1)에서 짠 코드가 변경 용이성과 의사소통이라는 목적을 만족하지 못한다는 것입니다. 이는 객체의 의존성과도 크게 연관됩니다.</li>
<li>제가 보기에, 객체에 적절한 의존성을 부여하는 방법으로 그 자신이 포함하는 &#39;인스턴스 변수&#39;에 관련된 행위는 내부에서 처리하는 것입니다. 다른 객체는 해당 객체에게 명령하거나, 권한을 주거나, 요청을 하는 식으로 소통할 수 있다고 생각합니다.</li>
</ul>
<hr>
<h2 id="ch-01-객체-설계-2">Ch 01. 객체, 설계 (2)</h2>
<h3 id="02-무엇이-문제인가">02. 무엇이 문제인가</h3>
<p><strong>로버트 마틴, &quot;클린 소프트웨어: 애자일 원칙과 패턴, 그리고 실천 방법&quot;</strong></p>
<ul>
<li>모듈: 클래스나 패키지, 라이브러리와 같이 프로그램을 구성하는 임의의 요소</li>
<li>모든 모듈은 (1) <u>제대로 실행돼야 하고</u>, (2) <u>변경이 용이해야 하며</u>, (3) <u>이해하기 쉬워야 한다</u>
→ (1) 앞서 작성한 프로그램은 필요 기능을 오류 없이 수행
→ ~(2), ~(3) 그러나 변경 용이성과 의사소통이라는 목적은 만족 X</li>
</ul>
<p><strong>예상을 빗나가는 코드</strong></p>
<pre><code class="language-java">public class Theater {
  private TicketSeller ticketSeller;

  public Theater(TicketSeller ticketSeller) {
    this.ticketSeller = ticketSeller;
  }

  public void enter(Audience audience) {
    if (audience.getBag().hasInvitation()) {
        Ticket ticket = ticketSeller.getTicketOffice().getTIcket();
        audience.getBag().setTicket(ticket);
      // 허락 없이 audience의 ticket 에 접근
      } else { 
        Ticket ticket = ticketSeller.getTicketOffice().getTicket();
        audience.getBag().minusAmount(ticket.getFee());
      // 허락 없이 audience의 amount에 접근
        ticketSeller.getTicketOffice.plusAmount(ticket.getFee());
      // 허락 없이 ticketSeller에 접근해 ticketOffice 내 현금 접근                
      audience.getBag().setTicket(ticket);
      // 허락 없이 audience의 ticket에 접근
      }
  }
}   </code></pre>
<ul>
<li>관람객과 판매원이 소극장의 통제를 받는 수동적인 존재로 그려짐
  → 소극장이 허락 없이 티켓과 현금에 접근 가능</li>
<li>또한 코드를 이해하기 위해서 여러 세부적인 내용(Bag과 을 한꺼번에 기억하고 있어야함</li>
<li>가장 심각한 문제: Audience와 TicketSeller를 변경할 경우 Theater도 함께 변경해야 함</li>
</ul>
<p><strong>변경에 취약한 코드</strong></p>
<ul>
<li>객체 사이의 의존성(dependency)와 관련된 문제
  → 어떤 객체가 변경될 때 그 객체에게 의존하는 다른 객체도 함께 변경될 수 있다
  → 필요한 최소한의 의존성만 유지하고 불필요한 의존성을 제거</li>
<li>결합도(coupling)이 높다: 객체 사이의 의존성이 과하다</li>
<li>현재 구현된 코드에서는 Theater가 다른 클래스에 과도하게 의존하고 있다
→ 관람객이 가방이 없거나, 결제를 신용카드로 해야하는 경우?</li>
</ul>
<hr>
<h2 id="나가며">나가며</h2>
<p><strong>더 나아가기</strong></p>
<ul>
<li><p>의존성이란 정확히 무엇이고, 어느 정도의 의존성이 가장 적절한가? (물론 case by case겠지만)</p>
<ol>
<li><p>그렇다면 위 Theater은 어떤 정도까지 변화해야 하는가?
→ Theater가 관람객과 매표원-매표소를 &#39;직접&#39; 들여다 보는 대신, 관련된 명령을 내리거나 접근 권한을 주면 어떨까?
(실제로도 소극장은 오히려 규칙/명령을 내리거나 권한을 부여하는 존재가 아닌가?)</p>
</li>
<li><p>Audience 역시 단순히 &#39;가방&#39;을 들고 있는 것에서 그치지 않고, 나름의 합당한 행동을 해야하지 않을까?
→ 예를 들면 &#39;티켓&#39;을 구매하거나 요청하며, 돈을 지불하는 것은 관객의 역할이다.
→ 매표원 역시 &#39;티켓&#39;을 &#39;현금&#39;으로 교환하고, 그러한 &#39;현금&#39;을 매표소에 넣거나 &#39;티켓&#39;을 매표소에서 빼오는 역할을 해야할 것이다.</p>
</li>
</ol>
</li>
<li><p>의존성에 대한 논의들 찾아보기
→ 일단 위 두 질문에서, 나름대로 정리해보자면 객체는 &#39;자신이 할 수 있는 만큼&#39;은 자신 내에서 처리해야 한다.  </p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[오브젝트 1장 - 객체, 설계 (1) 티켓 판매 어플리케이션 구현]]></title>
            <link>https://velog.io/@glenn_syj/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-1%EC%9E%A5-%EA%B0%9D%EC%B2%B4-%EC%84%A4%EA%B3%84-1-%ED%8B%B0%EC%BC%93-%ED%8C%90%EB%A7%A4-%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EA%B5%AC%ED%98%84</link>
            <guid>https://velog.io/@glenn_syj/%EC%98%A4%EB%B8%8C%EC%A0%9D%ED%8A%B8-1%EC%9E%A5-%EA%B0%9D%EC%B2%B4-%EC%84%A4%EA%B3%84-1-%ED%8B%B0%EC%BC%93-%ED%8C%90%EB%A7%A4-%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EA%B5%AC%ED%98%84</guid>
            <pubDate>Mon, 03 Apr 2023 06:43:56 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p><strong>글과 관련해</strong></p>
<ul>
<li>코드 내에서 쓰이는 주석은 제가 추가로 단 것입니다.</li>
<li>모든 코드는 최하단 참고문헌에서 참고했습니다.</li>
</ul>
<p><strong>선요약 및 정리</strong></p>
<ul>
<li>오브젝트의 부제는 &quot;코드로 이해하는 객체지향 설계&quot;입니다. 저자는 이론보다도 실무가 우선한다고 밝히며, 코드를 중심으로 &#39;객체 지향&#39;에 관해 살펴보기를 권합니다.</li>
<li>1장 (1)에서는, 티켓 판매 애플리케이션이라는 예시를 들며, 각 객체가 갖는 속성(인스턴수 변수)과 기능(메서드)에 기반해 객체들을 구현합니다.</li>
<li>제가 보기에, 중점은 단순히 구현에 있는 것이 아니라, 각 객체들이 서로 맺고 있는 관계를 살펴보는 것에 있습니다.</li>
</ul>
<hr>
<h2 id="ch-01-객체-설계-1">Ch 01. 객체, 설계 (1)</h2>
<p><strong>객체 지향에 있어 실무와 이론</strong></p>
<ul>
<li>로버트 L 글래스; &quot;이론이 먼저일까 실무가 먼저일까?&quot;</li>
</ul>
<ul>
<li>어떤 분야든 초기 단계: 아무것도 없는 상태
→ 이론을 정립하기보다는 실무를 관찰한 결과를 바탕으로 이론을 정립하는 것이 최선</li>
</ul>
<h3 id="01-티켓-판매-애플리케이션-구현하기">01. 티켓 판매 애플리케이션 구현하기</h3>
<p><strong>기본 원리</strong></p>
<ul>
<li>추첨을 통해 선정된 관람객에게 공연을 무료로 관람할 수 있는 초대장 발송</li>
</ul>
<ul>
<li>이벤트에 당첨된 관람객과 그렇지 못한 관람객은 다른 방식으로 입장시켜야 한다</li>
</ul>
<p><strong>초대장 구현</strong></p>
<pre><code class="language-java">    public class Invitation { // 초대 일자를 인스턴수 변수로 포함
      private LocalDateTime when;
   } </code></pre>
<ul>
<li>티켓에는 공연의 날짜가 적혀 있어야 합니다.</li>
</ul>
<p><strong>티켓 구현</strong></p>
<pre><code class="language-java">    public class Ticket {
      private Long fee; // 클래스 내부에서만 접근

      public Long getFee() { // 클래스 외부에서 값 이용 가능
        return fee;
      }
  }</code></pre>
<ul>
<li>공연 관람은 티켓이 있어야만 가능합니다.</li>
</ul>
<p>** 가방 구현 **</p>
<pre><code class="language-java">    public class Bag {
        private Long amount;
        private Invitation invitation;
        private Ticket ticket;

      public boolean hasInvitation() { // 초대장 소지 여부
        return invitation != null;
      }

      public boolean hasTicket() { // 티켓 소지 여부
        return ticket != null;
      }

      public void setTicket(Ticket ticket) { // 티켓 설정
          this.ticket = ticket;
      }

      public void minusAmount(Long amount) { // 현금 감소
          this.amount -= amount;
      }

      public void plusAmount(Long amount) { // 현금 증가
          this.amount += amount;
      }
    }</code></pre>
<ul>
<li><p>관람객이 소지품을 넣어두는 Bag 클래스는 현금(amount), 초대장(invitation), 티켓(ticket)을 인스턴스 변수로 포함합니다.</p>
</li>
<li><p>이벤트 당첨자는 티켓으로 교환할 초대장을 가지고 있고, 미당첨자는 현금을 보유합니다. 티켓을 구매하거나 초대장과 교환하기 전, 초기 상태에는 두 가지 경우가 있습니다.</p>
<ol>
<li>초대장이 있고, 현금도 있다. (이후 현금 양 상관 X)</li>
<li>초대장은 없고, 현금은 있다. (이후 현금 양 상관 O)</li>
</ol>
</li>
</ul>
<p>** Bag 클래스에 생성자 추가 **</p>
<pre><code class="language-java">    public class Bag {
        public Bag(long amount) { // 초대장 없음
          this(null, amount);
        }

      public Bag(Invitation invitation, long amount) { // 초대장 있음
        this.invitation = invitation;
        this.amount = amount;
        }
    } </code></pre>
<ul>
<li>Bag의 인스턴스를 생성하는 시점에, 방금 살펴본 제약을 강제할 수 있도록 생성자를 추가합니다.</li>
</ul>
<p><strong>관람객 구현</strong></p>
<pre><code class="language-java">    public class Audience { // 관람객은 가방을 소지
        private Bag bag;

        public Audience(Bag bag) {
          this.bag = bag;
        }

        public Bag getBag() { // 외부에서 bag에 접근
          return bag;
        }
    }</code></pre>
<ul>
<li>관람객은 가방을 소지하고 있다.</li>
</ul>
<p><strong>매표소 구현</strong>  </p>
<pre><code class="language-java">    public class TicketOffice {
        private Long amount;
        private List&lt;Ticket&gt; tickets = new ArrayList&lt;&gt;();

        public TicketOffice(Long amount, Ticket ... tickets) {
          this.amount = amount;
          this.tickets.addAll(Arrays.asList(tickets));
        }

        public Ticket getTicket() { // 티켓을 주면서, 하나 제거
          return tickets.remove(0);
        }

        public void minusAmount(Long amount) { // 현금 감소
          this.amount -= amount;
        }

        public void plusAmount(Long amount) { // 현금 증가
      this.amount += amount;
        }
    }</code></pre>
<ul>
<li>매표소에는 티켓과 금액이 보관되어 있다. 매표소는 자원을 보관하는 곳이다.  </li>
</ul>
<p>** 매표원 구현 **</p>
<pre><code class="language-java">    public class TicketSeller {
        private TicketOffice ticketOffice;

        public TicketSeller(TicketOffice ticketOffice) {
          this.ticketOffice = ticketOffice;
        }

        public TicketOffice getTicketOffice() {
        return ticektOffice;
        }
    }</code></pre>
<ul>
<li>매표원은 매표소에서 티켓을 교환해주거나 판매하는 역할을 한다. 즉, 매표소에 접근할 수 있어야 한다. </li>
</ul>
<p><strong>소극장 구현</strong></p>
<pre><code class="language-java">    public class Theater {
        private TicketSeller ticketSeller;

        public Theater(TicketSeller ticketSeller) {
          this.ticketSeller = ticketSeller;
        }

        public void enter(Audience audience) {
          if (audience.getBag().hasInvitation()) { // 초대장 O, 교환
            Ticket ticket = ticketSeller.getTicketOffice().getTIcket();
            audience.getBag().setTicket(ticket);
          } else { // 초대장 X, 현금 받고 티켓 주기
            Ticket ticket = ticketSeller.getTicektOffice().getTicket();
            audience.getBag().minusAmount(ticekt.getFee());
            ticketSeller.getTicketOffice.plusAmount(ticket.getFee());                
          audience.getBag().setTicket(ticket);
          }
        }
    }</code></pre>
<ul>
<li>소극장은 관람객의 가방 안에 초대장이 들어 있는지를 조건으로, 만약 아니라면 현금이 충분한지를 조건으로 입장 여부를 결정한다<br>
1.  초대장이 있다면: 
이벤트에 당첨된 관람객 
→ 티켓을 관람객의 가방 안에 넣어줌
 2. 초대장이 없다면: 
티켓을 판매해야 함 
→ 관람객 금액 차감 후 매표소 금액 증가

</li>
</ul>
<p>** 그러나 **</p>
<ul>
<li>위 프로그램은 문제점을 가지고 있다. (2장에서 계속)</li>
</ul>
<hr>
<h2 id="나가며">나가며</h2>
<p>** 질문들 **</p>
<ul>
<li>만약 각 객체들이 스스로 숨기는 것 없이 쓰인다면, 왜 객체를 나누어야 하는가? 이런 경우에는 소극장 안에 다 넣는 것과 큰 차이가 없지 않나?<ol>
<li>소극장과 매표원</li>
<li>소극장과 관람객의 가방</li>
</ol>
</li>
</ul>
<ul>
<li>매표소와 매표원을 &#39;자동 매표 기계&#39;라고 생각하면 더 간단해지지 않을까? 혹은 &#39;자동 매표 기계&#39;로 했을 때 문제점은 무엇일까?
지금 생각나는 단점은, 클래스가 하나 더 줄어든다는 점에 비해서 1. 자원 저장 및 2. 티켓 교환 (자원 분배) 이라는 두 기능이 분리되지 않아 오히려 더욱 복잡한 구조를 만들 수 있다는 점이다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바의 정석 1장: 자바 시작 전]]></title>
            <link>https://velog.io/@glenn_syj/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-1%EC%9E%A5-%EC%9E%90%EB%B0%94-%EC%8B%9C%EC%9E%91-%EC%A0%84</link>
            <guid>https://velog.io/@glenn_syj/%EC%9E%90%EB%B0%94%EC%9D%98-%EC%A0%95%EC%84%9D-1%EC%9E%A5-%EC%9E%90%EB%B0%94-%EC%8B%9C%EC%9E%91-%EC%A0%84</guid>
            <pubDate>Thu, 30 Mar 2023 16:23:11 GMT</pubDate>
            <description><![CDATA[<h2 id="1-자바">1. 자바</h2>
<h3 id="11-자바란">1.1 자바란?</h3>
<p><strong>자바의 특징</strong></p>
<ul>
<li>운영체제에 독립적 → 프로그램 변경 없이도 실행 가능</li>
<li>클래스 라이브러리를 통해 프로그래밍에 필요한 요소 기본 제공</li>
</ul>
<h3 id="12-자바의-역사">1.2 자바의 역사</h3>
<ul>
<li>C++의 장점을 도입하고 단점을 보완 (1996년 1월 탄생)</li>
</ul>
<h3 id="13-자바-언어의-특징">1.3 자바 언어의 특징</h3>
<ol>
<li><p>운영체제에 독립적임</p>
<p> 프로그램은 운영체제나 하드웨어가 아닌 JVM과 통신
 → JVM은 운영체제에게 변환하여 전달</p>
</li>
<li><p>객체지향언어임</p>
<p>상속, 캡슐화, 다양성이 잘 적용됨</p>
</li>
<li><p>비교적 배우기 쉬움</p>
<p> 연산자, 기본구문 from C++, 객체지향관련 from smalltalk</p>
</li>
<li><p>자동 메모리 관리</p>
<p> 따로 메모리 관리 필요성이 없음</p>
</li>
<li><p>네트워크와 분산처리 지원</p>
<p> Java API를 통해 쉽게 네트워크 관련 프로그램 개발 가능</p>
</li>
<li><p>멀티 쓰레드 지원</p>
<p> 시스템과 관계 없이 구현 가능하며, 관련 라이브러리 제공.</p>
<p> → 스케쥴링을 자바 인터프리터가 담당</p>
</li>
<li><p>동적 로딩 지원</p>
<p> 여러 개의 클래스는 실행 시가 아니라 필요한 시점에 로딩</p>
<p> 일부 클래스가 변경되어도 전체 애플리케이션 재 컴파일 필요 없음</p>
</li>
</ol>
<h3 id="14-jvmjava-virtual-machine">1.4 JVM(Java Virtual Machine)</h3>
<ul>
<li>JVM은 Java virtual machine의 준말.</li>
</ul>
<p><strong>일반 애플리케이션</strong></p>
<ul>
<li>OS만 거치고 하드웨어로 전달 → App: OS 종속적</li>
</ul>
<p><strong>Java 애플리케이션</strong></p>
<ul>
<li>JVM을 거치고, JVM이 OS 단을 거친다 → App: OS 및 하드웨어 독립적 (단, JVM: OS 종속적)</li>
</ul>
<h2 id="2-자바개발환경-구축하기">2. 자바개발환경 구축하기</h2>
<h3 id="21-자바-개발도구jdk-설치하기">2.1 자바 개발도구(JDK) 설치하기</h3>
<ul>
<li>JDK(Java Development Kit) 설치가 필요 
→ <a href="http://java.sun.com">http://java.sun.com</a>  (불가능)
→ <a href="https://www.oracle.com/java/technologies/downloads/">https://www.oracle.com/java/technologies/downloads/</a></li>
</ul>
<p><strong>주요 실행 파일들</strong></p>
<ul>
<li>javac.exe: 자바 컴파일러 → c: … &gt;javac 파일명.java</li>
<li>java.exe: 자바 인터프리터 → c: … &gt;java 파일명</li>
<li>javap.exe: 역어셈블러 → c: … &gt;javap 파일명 &gt; 파일명.java
(‘-c’ 옵션: 바이트코드로 컴파일된 내용도 확인 가능)</li>
<li>javadoc.exe: 자동 문서 생성기 (Java API 형식의 문서) 
→ c: … &gt;javadoc 파일명.java</li>
<li>jar.exe: 압축 프로그램 (실행 관련, 클래스 파일 → jar)
→ c:.. &gt;jar cvf 파일명.jar 클래스명1.class 클래스명2.class (압축)
→ c:.. &gt;jar xvf 파일명.jar (압축 풀기)</li>
</ul>
<h3 id="22-java-api-문서-설치하기">2.2 Java API 문서 설치하기</h3>
<ul>
<li><a href="http://java.sun.com">http://java.sun.com</a> 에서 다운로드 가능
→ 현재는 <a href="https://docs.oracle.com/javase/7/docs/api/">https://docs.oracle.com/javase/7/docs/api/</a></li>
</ul>
<h2 id="3-자바로-프로그램-작성하기">3. 자바로 프로그램 작성하기</h2>
<h3 id="31-hellojava">3.1 Hello.java</h3>
<ul>
<li>eclipse, IntelliJ 등 고급 개발도구 사용 추천</li>
</ul>
<p><strong>주의점</strong></p>
<ul>
<li><p>모든 코드는 반드시 클래스 안에 존재해야 함</p>
<pre><code class="language-java">class 클래스이름 { // w/ public class: 소스 파일을 클래스 이름과 동일하게 해야 함
  public static void main(String[] args) // main 메서드의 선언부
  {
      // 실행될 문장들
  }
}</code></pre>
</li>
<li><p>괄호: 메서드의 시작과 끝</p>
</li>
<li><p>하나의 소스파일에 하나의 클래스만을 정의하는 것이 보통 → 둘 이상도 가능</p>
</li>
<li><p>소스 파일의 이름은 public class의 이름과 일치 해야 한다
→ 소스 파일 내에 public class가 없을 때?
→ 소스 파일의 이름은 어떤 클래스의 이름도 상관없음 </p>
</li>
</ul>
<h3 id="32-자주-발생하는-에러와-해결방법">3.2 자주 발생하는 에러와 해결방법</h3>
<p><strong>대표적 예시들</strong></p>
<ol>
<li><p>cannot find symbol 또는 cannot resolve symbol</p>
<p> 변수나 메서드가 선언되지 않았거나, 그 이름을 잘못 사용한 경우</p>
</li>
<li><p>‘;’ expected</p>
<p> 모든 문장의 끝에 붙여야 할 ‘;’ 가 없음</p>
</li>
<li><p>Exception in thread “main” java.lang.NoSuchMethodError: main</p>
<p> main 메서드가 없거나 입력 시 잘못되어 인식하지 못할 때</p>
</li>
<li><p>Exception in thread “main” java.lang.NoClassDefFoundError: 클래스명</p>
<p> 클래스를 인식하지 못할 때 → 이상이 없다면 클래스패스의 설정 재확인</p>
</li>
<li><p>illegal start of expression</p>
<p> 문법적 오류</p>
</li>
<li><p>class, interface, or enum expected</p>
<p> 키워드가 없다는 뜻이나, 괄호가 짝이 맞지 않는 경우</p>
</li>
</ol>
<p><strong>에러 발생 시 순서도</strong></p>
<ol>
<li>에러 메시지 + 해당 라인 및 주변 살펴보기</li>
<li>기본적 부분 재확인</li>
<li>의심 부분 주석 처리하거나 따로 떼어내서 처리</li>
</ol>
<h3 id="33-자바프로그램-실행과정">3.3 자바프로그램 실행과정</h3>
<p><strong>내부적 진행 순서</strong></p>
<ol>
<li>클래스 (파일) 로드</li>
<li>클래스 파일 검사 → 파일 형식, 악성코드</li>
<li>지정된 클래스에서 main (String[] args) 호출</li>
</ol>
<h3 id="34-주석">3.4 주석</h3>
<p><strong>주석의 역할</strong></p>
<ul>
<li>프로그램 코드에 대한 설명과 프로그램 정보 제공</li>
</ul>
<p><strong>주석의 종류</strong></p>
<ol>
<li>범위 주석: ‘/<em>’와 ‘</em>/’ 사이 내용을 주석</li>
<li>한 줄 주석: ‘//’부터 라인 끝까지를 주석</li>
</ol>
<h3 id="35-이-책으로-공부하는-방법">3.5 이 책으로 공부하는 방법</h3>
<p><strong>연습문제</strong> </p>
<ul>
<li><a href="https://codechobo.tistory.com/1">https://codechobo.tistory.com/1</a></li>
</ul>
<hr>
<h2 id="참고-및-탐구">참고 및 탐구</h2>
<h3 id="references">References</h3>
<p>남궁성. &quot;자바를 시작하기 전에.&quot; <em>Java의 정석</em>. 도우, 2016.</p>
<h3 id="공부할-주제">공부할 주제</h3>
<ul>
<li>따로 Java의 역사를 공부하며 C/C++ 와의 차이를 기술<ul>
<li>완료 링크: (미완)</li>
</ul>
</li>
<li>&#39;public static void main(String[] args)&#39;와 관련해, 메서드 선언에 관한 공부<ul>
<li>완료 링크: (미완)</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 3. 비트 필드의 개념과 사용, 문제점]]></title>
            <link>https://velog.io/@glenn_syj/JAVA-3.-%EB%B9%84%ED%8A%B8-%ED%95%84%EB%93%9C%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%82%AC%EC%9A%A9-%EB%AC%B8%EC%A0%9C%EC%A0%90</link>
            <guid>https://velog.io/@glenn_syj/JAVA-3.-%EB%B9%84%ED%8A%B8-%ED%95%84%EB%93%9C%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%82%AC%EC%9A%A9-%EB%AC%B8%EC%A0%9C%EC%A0%90</guid>
            <pubDate>Mon, 27 Mar 2023 05:36:32 GMT</pubDate>
            <description><![CDATA[<h2 id="비트필드의-개념과-기능-문제점">비트필드의 개념과 기능, 문제점</h2>
<h3 id="비트필드의-기본-개념과-특징">비트필드의 기본 개념과 특징</h3>
<p><strong>비트필드 기본 개념</strong></p>
<p>비트 필드는 메모리를 절약하기 위한 도구로 쓰였습니다. 비트 필드는 참-거짓 값을 여럿 결합해서 하나의 바이트로 만들어, 메모리를 절약합니다. 이 참-거짓들이 하나의 비트 필드로 묶이는 셈입니다. </p>
<p>특히 C/C++에서 정수형 저장에는 16비트가 필요한 것에 반해, 저장에는 1~2비트만 필요한 경우가 있습니다. 이러한 이유에서, 비트필드는 낮은 값을 갖는 정수 변수가 많을 프로그램일 때, 메모리 소비를 줄일 수 있습니다.</p>
<p><strong>비트 필드 예시와 설명</strong></p>
<pre><code class="language-java">// Code 1.
package oracle.hcj.constants;
public class Car {
 public final static int POWER_WINDOWS = 1;
 public final static int POWER_LOCKS = 2;
 public final static int SNOW_TIRES = 4;
 public final static int STANDARD_TIRES = 8;
 public final static int CRUISE_CONTROL = 16;
 public final static int CD_PLAYER = 32;
 public final static int AIR_CONDITIONING = 64;
 private int options;
 public Car( ) {
 }
 public void setOptions(final int options) {
 this.options = options;
 }
 public int getOptions( ) {
 return this.options;
 }
}</code></pre>
<table>
<thead>
<tr>
<th align="center">Fig 1. Options in &#39;Car&#39;</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><img src="https://velog.velcdn.com/images/glenn_syj/post/cdd2080f-a1d1-47b6-819e-51782786268d/image.gif" alt=""></td>
</tr>
</tbody></table>
<p>위 예시에서 비트필드는 여러 옵션을 가질 수 있는데, 이런 옵션들은 정수형으로 비트 필드에 저장됩니다. </p>
<p>바이트 내 비트가 2의 제곱수로 커지기 때문에, 항상 2의 배수를 값으로 가지게 될 겁니다. 그래서 비트 필드는 다른 상수와 구분하기가 쉽습니다. </p>
<p>각 비트마다 1(참) 혹은 0(거짓)으로 해당 옵션의 유무를 나타내게 됩니다.</p>
<p><strong>비트 필드와 비트 어레이 차이</strong></p>
<p>그러나 비트 필드는 비트 어레이와 차이점이 있습니다.</p>
<ol>
<li><p>비트 어레이</p>
<p>정수 타입보다 크기가 크고, 정수로 인덱스된 많은 비트의 집합을 저장하는 데 쓰입니다. </p>
</li>
<li><p>비트 필드</p>
<p>크기가 워드의 크기를 넘지 않습니다. 
여기에서 워드는 명령어나 연산을 통해 저장 장치에서 옮길 수 있는 데이터 단위이자, 한 명령어로 실행될 수 있는 데이터 처리 단위입니다.</p>
</li>
</ol>
<h3 id="비트-필드의-사용과-문제점">비트 필드의 사용과 문제점</h3>
<p><strong>비트 필드의 사용</strong></p>
<ol>
<li><p>비트 필드의 대체</p>
<p>비트 필드는 논리 연산자를 이용해서도 만들 수 있습니다. 각 옵션에 할당된 수가 2의 제곱수임을 고려하면, <strong>OR</strong> 연산을 이용해 나온 합이 차가 갖는 옵션을 알려준다고도 할 수 있습니다. 어떤 수든 해당하는 비트 조합은 하나인 까닭입니다. 혹은 <strong>XOR</strong> 연산을 이용해, 쉽게 옵션을 제거할 수도 있습니다.</p>
</li>
<li><p>비트 필드의 비교</p>
<p>논리 연산자로 비트 필드를 비교할 수 있습니다. 위의 예시에서 <strong>AND</strong> 연산자를 이용해, 두 피연산자의 비트를 비교할 수 있습니다. 만약 결과값이 1이라면, 차는 해당 옵션을 가지고 있다고 생각할 수 있습니다.</p>
</li>
</ol>
<p>** 비트 필드의 문제점 **</p>
<p>Java에서 비트필드는 JDK 내 리플렉션(reflection)에서의 기능들과 연관됩니다. 리플렉션은 필드, 클래스, 생성자, 혹은 메소드에서 제어자(modifier)를 저장하기 위해 사용됩니다. 그러나 비트 필드는 아래와 같은 문제점이 있습니다.</p>
<ol>
<li><p>상호 배제성 (mutual exclusivity)</p>
<p>위 예시에서, 차는 standard tire와 snow tire 둘 중 하나만 가질 수 있습니다. 만약 두 타이어 모두에 비트를 둔다면, 데이터가 오염될 수 있습니다.</p>
</li>
<li><p>제한된 확장성 (limited expandability)</p>
<p>만약 차에 새로운 옵션이 몇 백 개 추가된다면, 한 정수형 안에는 모든 비트를 담을 수가 없습니다. 만약 코드를 바꿀 수 있다해도, 기본적인 객체 지향에서의 캡슐화를 어기게 됩니다.</p>
</li>
<li><p>부적절한 캡슐화 (improper encapsulation)</p>
<p>캡슐화의 근본 원리 중 하나는 클래스 사용자로부터 객체를 숨기는 것입니다. 반면, 비트 필드는 내부 구현을 사용자에게 드러냅니다.</p>
<p>또한, 여러 옵션을 비트 필드 하나에 귀속시키므로, 인터페이스가 어지러워 집니다. 어떤 옵션을 가지고 있는지 확인하기 위해서는 다른 옵션을 확인할 필요가 없어야 합니다.</p>
<p>대안으로는, 차 클래스 안에 상호 배제적이지 않은 옵션을 세트로 둘 수 있습니다.</p>
</li>
</ol>
<h3 id="references">References</h3>
<p>[Code 1. , Fig 1.]
<a href="http://underpop.online.fr/j/java/hardcore-java/hardcorejv-chp-7-sect-2.html">http://underpop.online.fr/j/java/hardcore-java/hardcorejv-chp-7-sect-2.html</a></p>
<p><a href="https://en.m.wikipedia.org/wiki/Bit_field">https://en.m.wikipedia.org/wiki/Bit_field</a>
<a href="https://ko.m.wikipedia.org/wiki/%EC%9B%8C%EB%93%9C_(%EC%BB%B4%ED%93%A8%ED%8C%85)">https://ko.m.wikipedia.org/wiki/워드_(컴퓨팅)</a></p>
]]></description>
        </item>
    </channel>
</rss>