<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>edan_3000.log</title>
        <link>https://velog.io/</link>
        <description>즐겁게 코딩하는 하루 🌇🌆</description>
        <lastBuildDate>Tue, 11 Jan 2022 10:27:09 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. edan_3000.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/edan_3000" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[DB] Transaction Isolation Level (트랜잭션 고립 수준)]]></title>
            <link>https://velog.io/@edan_3000/DB-Transaction-Isolation-Level-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B3%A0%EB%A6%BD-%EC%88%98%EC%A4%80</link>
            <guid>https://velog.io/@edan_3000/DB-Transaction-Isolation-Level-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EA%B3%A0%EB%A6%BD-%EC%88%98%EC%A4%80</guid>
            <pubDate>Tue, 11 Jan 2022 10:27:09 GMT</pubDate>
            <description><![CDATA[<h2 id="transaction-isolation-level">Transaction Isolation Level</h2>
<p>Concurrency control에서는 상황3을 다뤘다.</p>
<blockquote>
<p>상황3 은 T1, T2가 모두 쓰기를 할 때</p>
</blockquote>
<p>하지만 Transaction Isolation Level에서는 상황2를 다룬다.</p>
<blockquote>
<p>T1 읽기, T2 쓰기</p>
</blockquote>
<p>상황2 에서 <code>Lock</code>을 사용하여 해결하는 것도 가능하나, 두 트랜잭션의 동시 진행 정도를 과도하게 막기 때문에 Performance issue가 발생한다.
이를 완하하기 위해 다른 방법을 찾을 필요가 있어 Isolation level이 있다.</p>
<h2 id="read-error">Read Error</h2>
<ul>
<li>트랜잭션1이 읽기, 트랜잭션2가 쓰기인 시나리오에서 트랜잭션1의 읽기 도중 문제가 발생한다.</li>
</ul>
<p><strong>아래 모든 시나리오는 T1-read T2-write로 생각한다.</strong></p>
<h3 id="dirty-read">Dirty read</h3>
<p>T1, T2가 동시에 실행한다. T1은 T2가 변경한 데이터를 읽어와야 하는데, T2가 작업 중 철회를 하게 되었다.</p>
<h3 id="문제-발생">문제 발생</h3>
<p>T2가 변경한 데이터를 T1이 읽은 후 어떤 이슈로 인해 T2가 스스로 철회를 하였다. 철회를 하면 T2가 한 작업은 rollback이 된다. T1은 T2가 정상적으로 종료하지 않은 상태에서 변경한 데이터를 보고 작업하게 된 것이다.</p>
<table>
<thead>
<tr>
<th>T1</th>
<th>T2</th>
</tr>
</thead>
<tbody><tr>
<td>읽기</td>
<td>쓰기</td>
</tr>
<tr>
<td>START TRANSACTION ISOLATION LEVEL READ <BR>UNCOMMITTED; <BR> USE DB_NAME <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1;</td>
<td>-</td>
</tr>
<tr>
<td>-</td>
<td>START TRANSACTION ISOLATION LEVEL READ <BR>COMMITTED;<BR> START TRANSACTION;  <BR> USE DB_NAME <BR><BR> UPDATE Book <BR> SET price = price + 100 <BR> WHERE bookid = 1; <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1; <BR><BR> COMMIT;</td>
</tr>
<tr>
<td>SELECT * <BR> FROM Book <BR> WHERE bookid = 1;</td>
<td>-</td>
</tr>
<tr>
<td>-</td>
<td>ROLLBACK;</td>
</tr>
<tr>
<td>SELECT * <BR> FROM Book <BR> WHERE bookid = 1; <BR><BR> COMMIT;</td>
<td>-</td>
</tr>
</tbody></table>
<h3 id="non-repeatable-read">Non-Repeatable read</h3>
<p>T1이 읽고, T2가 Update를 하고, T1이 다시 한 번 데이터를 읽을 때 생기는 문제이다. 즉, T1이 읽기 작업을 다시 한번 반복할 경우 이전의 결과가 반복되지 않는 현상을 Non-Repeatable read라고 한다.</p>
<h3 id="문제-발생-1">문제 발생</h3>
<p>T1이 데이터를 읽고 작업하던 중 T2가 데이터를 변경하였다. T1은 변경한 데이터를 보고 다시 한 번 작업을 하였다. Dirty read와 다르게 T2가 정상 종료하고 commit을 하였기 때문에 틀린 데이터는 아니다. 하지만 T1입장에서 같은 SQL문이 다른 결과를 도출한다.</p>
<table>
<thead>
<tr>
<th>T1</th>
<th>T2</th>
</tr>
</thead>
<tbody><tr>
<td>읽기</td>
<td>쓰기</td>
</tr>
<tr>
<td>START TRANSACTION ISOLATION LEVEL READ <BR>UNCOMMITTED; <BR> USE DB_NAME <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1;</td>
<td>-</td>
</tr>
<tr>
<td>-</td>
<td>START TRANSACTION ISOLATION LEVEL READ <BR>COMMITTED;<BR> START TRANSACTION;  <BR> USE DB_NAME <BR><BR> UPDATE Book <BR> SET price = price + 100 <BR> WHERE bookid = 1; <BR><BR> COMMIT; <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1;</td>
</tr>
<tr>
<td>SELECT * <BR> FROM Book <BR> WHERE bookid = 1; <BR><BR> COMMIT;</td>
<td>-</td>
</tr>
</tbody></table>
<h3 id="phantom-read">Phantom read</h3>
<p>T1이 데이터를 읽고, T2가 Update를 하고, T1이 다시 한번 데이터를 읽을 때 생기는 문제이다. T1이 읽기 작업을 다시 반복 했을 경우 이전에 없던 데이터가 나타나는 현상이다.</p>
<h3 id="문제-발생-2">문제 발생</h3>
<p>T1이 T2가 새로운 데이터를 삽입한 사실을 모르고 작업한다고 가정하자. T2가 commit을 하였기 때문에 틀린 데이터는 아니다. 그러나 T1입장에서 새로운 데이터가 반영되어 Non-Repeatable read와 비슷하지만 없던 데이터가 삽입되기 때문에 다르게 구분한다.</p>
<table>
<thead>
<tr>
<th>T1</th>
<th>T2</th>
</tr>
</thead>
<tbody><tr>
<td>읽기</td>
<td>쓰기</td>
</tr>
<tr>
<td>START TRANSACTION ISOLATION LEVEL READ <BR>UNCOMMITTED; <BR> USE DB_NAME <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1;</td>
<td>-</td>
</tr>
<tr>
<td>-</td>
<td>START TRANSACTION ISOLATION LEVEL READ <BR>COMMITTED;<BR> START TRANSACTION;  <BR> USE DB_NAME <BR><BR> UPDATE Book <BR> SET price = price + 100 <BR> INSERT INTO Book VALUES (3, &#39;NAME&#39;, &#39;CORE JAVASCRIPT&#39;) <BR> WHERE bookid = 1; <BR><BR> COMMIT; <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1;</td>
</tr>
<tr>
<td>SELECT * <BR> FROM Book <BR> WHERE bookid = 1; <BR><BR> COMMIT;</td>
<td>-</td>
</tr>
</tbody></table>
<h2 id="isolation-level-command">Isolation Level Command</h2>
<p>앞 3가지 문제를 해결하려면 당연히 <code>Lock</code>을 사용해야 한다. 
DBMS는 LOCK보다 완화된 방법으로 문제 해결를 위한 명령어를 제공한다.</p>
<table>
<thead>
<tr>
<th>Isolation Level</th>
<th>-</th>
<th>Dirty read</th>
<th>Non-Repeatable read</th>
<th>Phantom read</th>
</tr>
</thead>
<tbody><tr>
<td>READ UNCOMMITTED</td>
<td>-</td>
<td>가능</td>
<td>가능</td>
<td>가능</td>
</tr>
<tr>
<td>READ COMMITTED</td>
<td>-</td>
<td>불가능</td>
<td>가능</td>
<td>가능</td>
</tr>
<tr>
<td>REPEATABLE READ</td>
<td>-</td>
<td>불가능</td>
<td>불가능</td>
<td>가능</td>
</tr>
<tr>
<td>SERIALIZABLE</td>
<td>-</td>
<td>불가능</td>
<td>불가능</td>
<td>불가능</td>
</tr>
</tbody></table>
<h3 id="read-uncommitted-level--0">READ UNCOMMITTED (LEVEL = 0)</h3>
<p>고립수준이 가장 낮은 명령어로, 자신의 데이터에 아무런 공유락을 걸지 않는다. 또한 다른 트랜잭션에 공유락과 배타락이 걸린 데이터를 대기하지 않고 읽는다. 심지어 commit하지 않은 데이터도 읽을 수 있다. 
특징으로 SELECT Query에 되는 테이블에 대해 락을 설정하지 않은 것과 같다.</p>
<table>
<thead>
<tr>
<th>모드</th>
<th>READ UNCOMMITTED</th>
</tr>
</thead>
<tbody><tr>
<td>LOCK</td>
<td>SELECT 문 - 공유락 걸지 않음 <BR> UPDATE 문 - 배타락 설정 <BR> 다른 트랜잭션의 공유락과 배타락이 걸린 데이터를 읽음</td>
</tr>
<tr>
<td>SQL문</td>
<td>SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED</td>
</tr>
<tr>
<td>문제점</td>
<td>Dirty read, Non-Repeatable read, Phantom read</td>
</tr>
</tbody></table>
<h3 id="read-committed-level--1">READ COMMITTED (LEVEL = 1)</h3>
<p>dirty read를 피하기 위해 자신의 데이터를 읽는 동안 공유락을 걸지만 트랜잭션이 끝나기 전에 해지가능하다. 다른 트랜잭션 데이터는 락 호환성 규칙에 따라야 한다.</p>
<table>
<thead>
<tr>
<th>모드</th>
<th>READ COMMITTED</th>
</tr>
</thead>
<tbody><tr>
<td>LOCK</td>
<td>SELECT 문 - 공유락을 걸고 끝나면 바로 해지 <BR> UPDATE 문 - 배타락 설정 <BR> 다른 트랜잭션이 설정한 공유락은 읽지만 배타락은 읽지 못함</td>
</tr>
<tr>
<td>SQL문</td>
<td>SET TRANSACTION ISOLATION LEVEL READ COMMITTED</td>
</tr>
<tr>
<td>문제점</td>
<td>Non-Repeatable read, Phantom read</td>
</tr>
</tbody></table>
<h3 id="repeatable-read-level--2">REPEATABLE READ (LEVEL = 2)</h3>
<p>자신의 데이터에 설정된 공유락과 배타락을 트랜잭션이 종료할 때까지 유지하여 다른 트랜잭션이 자신의 데이터를 갱신 할 수 없도록 한다. 다른 데이터는 락 호환성 규칙에 따라야 한다.
다른 Isolation level에 비해 데이터의 concurrency(동시성)이 낮아 특별한 상황이 아니라면 사용하지 않는 것이 좋다.</p>
<table>
<thead>
<tr>
<th>모드</th>
<th>REPEATABLE READ</th>
</tr>
</thead>
<tbody><tr>
<td>LOCK</td>
<td>SELECT 문 - 공유락을 걸고 트랜잭션 끝까지 유지 <BR> UPDATE 문 - 배타락 설정 <BR> 다른 트랜잭션이 설정한 공유락은 읽지만 배타락은 읽지 못함</td>
</tr>
<tr>
<td>SQL문</td>
<td>SET TRANSACTION ISOLATION LEVEL REPEATABLE READ</td>
</tr>
<tr>
<td>문제점</td>
<td>Phantom read</td>
</tr>
</tbody></table>
<h3 id="serializable-level--3">SERIALIZABLE (LEVEL = 3)</h3>
<p>고립 수준이 가장 높은 명령어로, 실행 중인 트랜잭션은 다른 트랜잭션으로부터 완벽하게 분리된다.
데이터 집합에 범위를 지어 잠금을 설정할 수 있기 때문에 다른 사용자가 데이터를 변경하려고 할 때 트랜잭션을 완벽하게 분리 할 수 있다. 
Isolation level 중 제한이 가장 심하고, 데이터의 동시성도 낮다. 
특징으로 SELECT Query에 대상이 되는 테이블에 미리 배타락을 설정한 것과 같은 효과를 낸다.</p>
<table>
<thead>
<tr>
<th>모드</th>
<th>SERIALIZABLE</th>
</tr>
</thead>
<tbody><tr>
<td>LOCK</td>
<td>SELECT 문 - 공유락을 걸고 트랜잭션 끝까지 유지 <BR> UPDATE 문 - 배타락 설정 <BR> 다른 트랜잭션이 설정한 공유락은 읽지만 배타락은 읽지 못함 <BR> 인덱스에 공유락을 설정하여 다른 트랜잭션의 INSERT문이 금지됨</td>
</tr>
<tr>
<td>SQL문</td>
<td>SET TRANSACTION ISOLATION LEVEL SERIALIZABLE</td>
</tr>
<tr>
<td>문제점</td>
<td>-</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] Transaction Concurrency control (동시성 제어)]]></title>
            <link>https://velog.io/@edan_3000/DB-Transaction-Concurrency-control-%EB%8F%99%EC%8B%9C%EC%84%B1-%EC%A0%9C%EC%96%B4</link>
            <guid>https://velog.io/@edan_3000/DB-Transaction-Concurrency-control-%EB%8F%99%EC%8B%9C%EC%84%B1-%EC%A0%9C%EC%96%B4</guid>
            <pubDate>Tue, 11 Jan 2022 10:25:32 GMT</pubDate>
            <description><![CDATA[<h2 id="concurrency-control">Concurrency control</h2>
<ul>
<li>트랜잭션이 동시에 수행 될 때, 일관성을 해치지 않도록 트랜잭션의 데이터 접근을 제어하는 DBMS의 기능을 동시성 제어(Concurrency control)이라고 한다.</li>
</ul>
<h2 id="동시성-제어-시나리오">동시성 제어 시나리오</h2>
<table>
<thead>
<tr>
<th>상황</th>
<th>트랜잭션1</th>
<th>트랜잭션2</th>
</tr>
</thead>
<tbody><tr>
<td>상황1</td>
<td>읽기</td>
<td>읽기</td>
</tr>
<tr>
<td>상황2</td>
<td>읽기</td>
<td>쓰기</td>
</tr>
<tr>
<td>상황3</td>
<td>쓰기</td>
<td>쓰기</td>
</tr>
</tbody></table>
<blockquote>
<p>읽기만 한다면 크게 문제가 없지만 문제는 상황2, 상황3에서 나타난다.
상황2는 Isoltion level에서 다루고 <strong>동시성 제어에서는 상황3</strong>을 살펴보자</p>
</blockquote>
<h2 id="갱신손실-문제">갱신손실 문제</h2>
<p>갱신손실(lost update) 문제는 두 개의 트랜잭션이 한 개의 데이터를동시에 갱신할 때 발생한다.</p>
<h3 id="작업-설명">작업 설명</h3>
<ol>
<li>T1(트랜잭션1)은 예금을 인출하는 작업</li>
<li>T2(트랜잭션2)는 입금하는 작업</li>
<li>T1은 계좌 X에서 100을 뺀다.</li>
<li>T2는 계좌 X에 100을 더한다.</li>
<li>X에 기본 1000값이 있다고 가정한다.</li>
</ol>
<h3 id="시나리오--두-개의-트랜잭션이-동시에-작업을-진행">시나리오 : 두 개의 트랜잭션이 동시에 작업을 진행</h3>
<table>
<thead>
<tr>
<th>T1</th>
<th>T2</th>
<th>버퍼 값</th>
<th>Index</th>
</tr>
</thead>
<tbody><tr>
<td>A = read_item(X);<br> A = A - 100</td>
<td>-</td>
<td>X = 1000</td>
<td>1</td>
</tr>
<tr>
<td>-</td>
<td>B = read_item(X);<br> B = B + 100</td>
<td>X = 1000</td>
<td>2</td>
</tr>
<tr>
<td>write_item(A -&gt; X);</td>
<td>-</td>
<td>X = 900</td>
<td>3</td>
</tr>
<tr>
<td>-</td>
<td>write_item(B -&gt; X);</td>
<td>X = 1100</td>
<td>4</td>
</tr>
</tbody></table>
<p>일관성이 깨진 것을 알 수 있다.
원인은 Index2에서 X 값을 읽어온 T2는 T1이 갱신을 준비 중인 데이터를 읽어와 작업을 진행한다.
그리고 Index3 에서 T1이 기록한 데이터를 무시하고 다시 한 번 끼어들어 Index4에서 X 값을 갱신한다.</p>
<h2 id="해결">해결</h2>
<p>갱신손실 문제를 해결하려면 상대방의 트랜잭션이 데이터를 사용하는지 여부를 알 수 있는 규칙이 필요하다. 즉, 자신이 데이터를 수정 중이라는 사실을 알리면 된다.
알리는 방식으로 락(Lock)이라는 잠금장치를 사용한다.</p>
<h2 id="lock">Lock</h2>
<p>락은 자신이 사용할 데이터를 잠그면 다른 트랜잭션은 잠금이 풀릴 때까지 wait 해야한다.
이로써 X에 대한 갱신을 순차적으로 진행할 수 있고, 갱신손실 문제를 해결할 수 있다.</p>
<h3 id="시나리오--use-locking">시나리오 : Use Locking</h3>
<table>
<thead>
<tr>
<th>T1</th>
<th>T2</th>
<th>버퍼 값</th>
<th>Index</th>
</tr>
</thead>
<tbody><tr>
<td>LOCK(X) A = read_item(X); <br> A = A - 100</td>
<td>-</td>
<td>X = 1000</td>
<td>1</td>
</tr>
<tr>
<td>-</td>
<td>LOCK(X) <br> (wait... 대기)</td>
<td>X = 1000</td>
<td>2</td>
</tr>
<tr>
<td>write_item(A -&gt; X); <br> UNLOCK(X);</td>
<td>-</td>
<td>X = 900</td>
<td>3</td>
</tr>
<tr>
<td>-</td>
<td>B = read_item(X); <br> B = B + 100 <br> write_item(B -&gt; X); <br> UNLOCK(X);</td>
<td>X = 1100</td>
<td>4</td>
</tr>
</tbody></table>
<h2 id="작업설명--하나의-데이터에-두-트랜잭션을-접근하여-갱신하는-작업">작업설명 : 하나의 데이터에 두 트랜잭션을 접근하여 갱신하는 작업</h2>
<table>
<thead>
<tr>
<th>T1</th>
<th>T2</th>
</tr>
</thead>
<tbody><tr>
<td>START TRANSACTION; <BR> USE DB_NAME <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1; <BR><BR> UPDATE Book <BR> SET price = 7100 <BR> WHERE bookid = 1; <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1; <BR><BR> COMMIT;</td>
<td>START TRANSACTION; <BR> USE DB_NAME <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1; <BR><BR> UPDATE Book <BR> SET price = price + 100 <BR> WHERE bookid = 1; <BR><BR> SELECT * <BR> FROM Book <BR> WHERE bookid = 1; <BR><BR> COMMIT;</td>
</tr>
</tbody></table>
<h2 id="데드락">데드락</h2>
<p>두 개 이상의 트랜잭션이 각각 자신의 데이터에 대해 락을 획득하고 상대방 데이터에 대해 락을 요청하면 무한 대기 상태에 빠진다.
이러한 현상을 데드락 or 교착상태 라고 한다.</p>
<h3 id="데드락-해결">데드락 해결</h3>
<p>데드락이 발생하면 일반적으로 작업중인 트랜잭션 중 하나를 강제 중지 시킨다. 그 결과 나머지 트랜잭션은 정상적으로 실행된다. 이 때 중지시키는 트랜잭션에서 변경한 데이터는 원래 상태로 rollback한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[DB] Transaction]]></title>
            <link>https://velog.io/@edan_3000/DB-Transaction</link>
            <guid>https://velog.io/@edan_3000/DB-Transaction</guid>
            <pubDate>Tue, 11 Jan 2022 10:24:47 GMT</pubDate>
            <description><![CDATA[<h1 id="트랜잭션">트랜잭션</h1>
<p>DBMS가 데이터 베이스를 다룰 때 사용하는 작업 단위</p>
<ul>
<li><p>ACID 성질</p>
</li>
<li><p>원자성(Atomicity) : 트랜잭션에 포함된 작업은 전부 수행되거나 아니면 전부 수행되지 않아야 한다.</p>
<ul>
<li>어중간한 일이 없어야 한다. all of nothing</li>
<li>TCL : COMMIT, ROLLBACK은 트랜잭션 제어 명령어</li>
<li>SAVE : SAVEPOINT를 이용해 트랜잭션이 길어질 경우 중간에 값을 저장하는 역할</li>
</ul>
</li>
<li><p>일관성(Consistency) : 트랜잭션을 수행하기 전, 수행한 후 데이터베이스는 항상 일관된 상태를 유지해야 한다.</p>
<ul>
<li>예 판매자 계좌 10만원 구매자 계좌 10만원 인 경우 계좌이체 시 트랜잭션이 실행 중일 때, 판매자계좌 + 구매자계좌 = (20만원x 19만원o)으로 나오게 된다. (일관성 없는 상태)</li>
</ul>
</li>
<li><p>독립성(Isolation) : 수행 중인 트랜잭션에 다른 트랜잭션이 끼어들어 변경 중인 데이터 값을 훼손하는 일이 없어야 한다.</p>
<ul>
<li>트랜잭션이 동시에 수행 될 때, 상호 간섭, 데이터 충돌이 일어나지 않는 현상을 독립성이라고 한다.</li>
<li>독립성을 유지하기 위해 변경 중인 임시 데이터를 다른 트랜잭션이 읽거나 쓰려고 할 때 제어하는 작업이 필요 (동시성 제어)</li>
</ul>
</li>
<li><p>지속성(Durability) : 수행을 성공적으로 완료한 후에도 트랜잭션은 영구히 저장되어야 한다. 저장된 DB는 저장 직후 어느 때나 발생할 수 있는 장애 오류에 영향을 받지 않아야 한다.</p>
<ul>
<li>부분완료 : 트랜잭션이 완료 되었지만, 변경 된 내용이 DB에 기록되었는지 확실하지 않는 상태이다. 이 상태에서 DBMMS가 최종적으로 변경 내용을 DB에 commit 해야 완료 상태가 된다. DBMS가 변경 내용을 DB에 기록하지 못하면 실패 tkdxork ehlsek.</li>
<li>실패 : 트랜잭션을 중간에 중단하였거나 부분완료 상태에서 변경 내용을 데이터베이스에 저장하지 못한 상태를 말한다. 실패 상태에서 DBMS는 트랜잭션이 수행한 작업을 모두 원상복구 시킨다.</li>
</ul>
</li>
</ul>
<pre><code class="language-sql">BEGIN
    UPDATE accounts
    SET balance = balance - 10000
    WHERE user = &#39;구매자&#39;;

    UPDATE accounts
    SET balance = balance + 10000
    WHERE user = &#39;판매자&#39;;
END</code></pre>
<h2 id="예상되는-오류">예상되는 오류</h2>
<ul>
<li>구매자의 계좌 돈 출근 된 뒤 DB 다운</li>
<li>구매자의 계좌에서 돈 출금하지 않았는데, 판매자에게 돈이 입금된다.</li>
<li>출금도 입금도 되지 않는다.</li>
</ul>
<p>중간에 오류가 발생되는 것 때문에 모두 수행되거나 모두 수행되지 않아야 한다.</p>
<pre><code class="language-sql">START TRANSACTION
/* 판매자 계좌 읽어오기 */ - 1
/* 구매자 계좌 읽어오기 */ - 2
/* 잔고 확인 */

/* 구매자 인출 */ - 3
UPDATE accounts
SET balance = balance - 10000
WHERE user = &#39;구매자&#39;;

/* 판매자 입금 */ - 4
UPDATE accounts
SET balance = balance + 10000
WHERE user = &#39;판매자&#39;;

COMMIT /* 부분완료 */
/* 구매자 계좌 기록 */ -5
/* 판매자 계좌 기록 */ -6</code></pre>
<h2 id="트랜잭션이-동시에-발생하게-되면">트랜잭션이 동시에 발생하게 되면?</h2>
<p>lock 이라는 것을 이용하여 트랜잭션이 다루는 데이터를 다른 트랜잭션이 접근하지 못하도록 막아 대기 상태로 만든다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript]  DataType]]></title>
            <link>https://velog.io/@edan_3000/javascriptdatatype</link>
            <guid>https://velog.io/@edan_3000/javascriptdatatype</guid>
            <pubDate>Fri, 03 Dec 2021 10:57:35 GMT</pubDate>
            <description><![CDATA[<h1 id="데이터타입">데이터타입</h1>
<h2 id="데이터타입의-종류-기본형-참조형">데이터타입의 종류 기본형 참조형</h2>
<ul>
<li><p>기본형</p>
<pre><code class="language-js">let num = 1; // num &gt;&gt;&gt; 1
let str = &#39;abcdefg&#39;; // str &gt;&gt;&gt; abcdefg
let bool = true; // bool &gt;&gt;&gt; true;
let nothing = undefined; // nothing &gt;&gt;&gt; undefined
let nothing2 = null; // nothing2 &gt;&gt;&gt; null </code></pre>
</li>
<li><p>참조형</p>
<pre><code class="language-js">let list = [1,2,3,4,5]; // 배열
let dict = {f : &#39;apple&#39;, b : [true, false], n : 123} //객체
function (...) {...} // 함수</code></pre>
</li>
</ul>
<p><code>기본형</code>은 값이 담긴 주솟값을 바로 복제합니다. 반면 <code>참조형</code>은 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제한다는 점이 차이점 입니다.</p>
<blockquote>
<p>이 내용은 예시로 알아보는게 이해가 빠릅니다.</p>
</blockquote>
<p>데이터타입을 알아가는 과정에서는 <code>식별자</code>와 <code>변수</code>를 구분하여 생각해야 합니다.
<code>변수</code>는 <strong>변할 수 있는 무언가</strong>라고 하며 여기서 <code>무언가</code>는 <strong>데이터</strong>를 말합니다. 식별자는 어떤 데이터를 식별하는데 사용하는 이름, 즉 <strong>변수명</strong>입니다.</p>
<p>&nbsp;</p>
<hr>
<h2 id="변수선언">변수선언</h2>
<p>변수명을 지어주고, 값을 10으로 할당해 줬다고 생각해보자.
변수명은 <code>변수 영역</code>에, 할당한 값<code>10</code>은 데이터 영역에 주소값으로 데이터가 저장된다.</p>
<p><img src="https://cdn.discordapp.com/attachments/900659683822555199/916235720266498058/unknown.png" alt=""></p>
<ol>
<li>처음 변수 영역에 빈 메모리 공간 확보</li>
<li>확보한 공간에 식별자를 지정</li>
<li>데이터 영역에 빈 메모리 공간 확보</li>
<li>확보한 공간에 데이터 값 저장</li>
<li>변수 영역에서 식별자의 주소값을 검색한다.</li>
<li>검색한 식별자의 값을 데이터 영역의 주소값으로 저장한다.</li>
</ol>
<blockquote>
<p>기본 변수로 할당 되는 경우 이런 원리로 진행 됩니다.</p>
</blockquote>
<p>&nbsp;</p>
<p>하지만 데이터가 <strong>재할당</strong> 된다면? 어떻게 진행 될까요?
식별자에 할당값을 다른 값을 <code>20</code>으로 <strong>재할당</strong>했다고 가정해 보자
<img src="https://cdn.discordapp.com/attachments/900659683822555199/916237238013157396/unknown.png" alt=""></p>
<ol>
<li>처음 변수 영역에 빈 메모리 공간 확보</li>
<li>확보한 공간에 식별자를 지정</li>
<li>데이터 영역에 빈 메모리 공간 확보</li>
<li>확보한 공간에 데이터 값 저장</li>
<li>변수 영역에서 식별자의 주소값을 검색한다.</li>
<li>검색한 식별자의 값을 데이터 영역의 주소값으로 저장한다.</li>
</ol>
<p>5번 까지는 같지만 아래 몇가지 경우가 더 생긴다.
7. 데이터 영역에 빈공간을 다시 확보한다.
8. 확보한 영역에 데이터 값을 <code>20</code>으로 저장한다.
9. 변수 영역에 식별자를 검색한다.
10. 검색한 식별자의 값을 데이터값 <code>20</code>의 값의 주소값으로 저장한다.</p>
<p>이런 로직으로 기본형 타입의 데이터를 할당합니다.</p>
<p>&nbsp;</p>
<p>그렇다면 참조형 데이터 타입은 어떻게 저장 될까?
<img src="https://cdn.discordapp.com/attachments/900659683822555199/916238715028914196/unknown.png" alt=""></p>
<p>참조형 데이터는 <code>객체 변수 영역</code>이 존재 합니다. 객체 변수 영역에 각 프로퍼티를 저장하고, 이 주소값을 데이터 영역에 참조하여 변수에 할당하는 형태로 데이터가 저장 되는 방식입니다.</p>
<ol>
<li>처음 변수 영역에 빈 메모리 공간 확보</li>
<li>확보한 공간에 식별자를 지정</li>
<li>데이터 영역에 빈 메모리 공간 확보</li>
<li>객체 변수 영역에 빈 메모리 공간 확보</li>
<li>객체 값안에 변수명을 객체 변수 영역에 할당</li>
<li>데이터 영역에 빈공간 확보</li>
<li>확보 된 데이터 영역 공간에 객체 변수 값을 저장
...</li>
</ol>
<p>참조형 데이터 타입은 객체 변수 영역이 하나 더 확보 된 것이지, 크게 바뀐 것이 없다.</p>
<p>이로써 기본적인 데이터가 어떻게 저장되는지 알아보았습니다...!</p>
<p align='center'>
<img src='https://media.discordapp.net/attachments/900659683822555199/916241073947414538/images.png' width='100%'>
</p>

<p>&nbsp;</p>
<hr>
<h2 id="불변값-가변값">불변값 가변값</h2>
<p>말의 의미로 불변값이란 변하지 않는 값인데, <code>재할당하면 바뀌자 않나?</code> 라고 생각할 수도 있습니다.
<code>불변값</code>을 판단 할 때는 <strong>데이터 영역의 메모리</strong>를 말합니다.
재할당을 하면 그 주소값에 데이터를 바꾸는 것이 아닌, 다시 공간을 확보하고 재할당한 값을 저장하는 것을 말합니다.
기존의 값은 지워지지 않았으므로, 불변성이라고 합니다.</p>
<p>&nbsp;</p>
<p><img src="https://cdn.discordapp.com/attachments/900659683822555199/916244478510104616/unknown.png" alt=""></p>
<p>기존에 10이 저장되어 있었다면, 10을 다시 쓸때는 데이터 영역의 값을 다시 확보하는 것이 아닌, 기존에 값이 있는지 부터 찾고 있다면 재활용합니다.</p>
<p>그렇다면 가변값을 어떻게 바뀌는지 알아봅시다.
<img src="https://cdn.discordapp.com/attachments/900659683822555199/916246643349782599/unknown.png" alt=""></p>
<p>위 그림을 예시로 들자면, 원래 객체변수영역에 7002 주소값의 값으로 있는 주소는 @5005 였는데, 값을 변경해서 @5006으로 바뀌었습니다.
하지만, 변수명 obj에 값의 주소값은 @5003은 그대로 바뀌지 않았습니다.
즉 <strong>객체변수영역의 데이터 값의 주소값만 바뀌었고</strong>, 데이터 영역의 객체영역값의 주소값은 변하지 않았습니다.</p>
<p>이렇게 데이터 영역의 주소값은 변하지 않았지만, 객체 영역의 값은 변한 것을 <code>가변값</code>이라고 합니다.</p>
<blockquote>
<p>배열의 변수 영역도 따로 존재한다고 생각하면 되고, 객체 영역처럼, 배열 영역도 데이터 영역에 주소값으로 저장된다고 생각하면 됩니다.</p>
</blockquote>
<p>&nbsp;</p>
<hr>
<h2 id="가비지-컬렉팅">가비지 컬렉팅</h2>
<p>그럼 10을 안쓴다면 이 메모리 공간은 손해라고 생각할 수도 있습니다.
다른 언어는 일정한 생명주기를 가지지만, JS는 <code>쓸모가 없어졌을 때 자동으로 해체</code>합니다.</p>
<p>그렇다면 JS는 메모리가 필요가 없다는 것을 어떻게 알까요?
바로 <code>가비지 컬렉션</code>이라는 메모리 관리 방법을 사용해서 알 수 있습니다.
<code>가비지 컬렉션</code>이란, 가비지 컬렉터들이 메모리 할당을 추적하고, 만약 <strong>더이상 쓰지 않는 메모리라면 판단하여 메모리를 해체하는 프로세스</strong>를 말합니다.</p>
<p>&nbsp;</p>
<hr>
<h2 id="객체복사">객체복사</h2>
<p>객체 복사는 일반적으로 같은 객체 영역을 바라봅니다.
아래의 예시로 이해해 봅시다.</p>
<pre><code class="language-js">let obj = { name : &#39;kim&#39;, age : 20}
let obj2 = obj</code></pre>
<p><img src="https://cdn.discordapp.com/attachments/900659683822555199/916250336170221578/unknown.png" alt=""></p>
<p>위와 같은 코드를 이해해 보자면, obj2는 obj와 같은 데이터 영역의 값을 할당 됩니다.</p>
<pre><code class="language-js">obj === obj2 // ture
obj[name] = &#39;park&#39;;
console.log(obj2[name]) // park</code></pre>
<p>즉 같은 데이터 영역을 보기 때문에 하나의 변수값이 달라지면 다른 객체까지 영향을 미칩니다.</p>
<p>그렇다면 불변 객체를 만드는 법은 뭘까요?</p>
<p>&nbsp;</p>
<hr>
<h2 id="불변객체">불변객체</h2>
<p>아래 코드를 보면, 여전히 같은 객체 영역주솔르 보고 있다는 것을 알 수 있다.</p>
<pre><code class="language-js">// 객체의 가변성에 따른 문제점
let user = {
    name : &#39;abc&#39;,
    age : 19
};

const changeName = (user, newName) =&gt; {
    let newUser = user; // user 와 같은 객체 영역을 보고 있음
    newUser.name = newName;
    return newUser; // 같은 객체 영역을 보고 있는 것을 return 한 것이다.
}

let user2 = changeName(user, &#39;bbb&#39;); // 결국 같은 객체 영역

if (user !== user2) {
    console.log(&#39;유저 정보 변경&#39;)
}

console.log(user.name, user2.name); // bbb bbb
console.log(user === user2) // true</code></pre>
<p>결국 <code>return</code>값이 user 값이다. 즉, user와 같은 객체 영역 값이 있으므로, 불변 객체라고 생각 할 수 없다.</p>
<p>해결하기 위해서는 <code>user</code>를 할당해주는 것이 아닌, <code>return</code> 자체를 객체를 보내주면 된다.</p>
<pre><code class="language-js">// 가변성 문제 해결 방법
let user = {
    name : &#39;abc&#39;,
    age : 19
};

const changeName = (user, newName) =&gt; {
    return {
        name : newName,
        age: user.age
    };
};

let user2 = changeName(user, &#39;test&#39;);


if (user !== user2) {
    console.log(&#39;유저 정보 변경&#39;)
}

console.log(user.name, user2.name); // abc test
console.log(user === user2) // false</code></pre>
<p>&nbsp;</p>
<hr>
<h2 id="얕은복사-깊은복사">얕은복사 깊은복사</h2>
<p><code>얕은 복사</code>는 바로 아래 단계의 값만 복사하는 방법이고, <code>깊은 복사</code>는 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법입니다.</p>
<p>우선 얕은복사부터 알아보겠습니다.</p>
<pre><code class="language-js">// 중첩된 객체에 대한 얕은 복사
let user = {
    name : &#39;abc&#39;,
    urls : {
        blog : &#39;https://blog.com&#39;,
        portfolio : &#39;https://github.com&#39;
    }
};

const copyObj = (target) =&gt; {
    let result = {};
    for (let key in target) {
        result[key] = target[key]
    }
    return result;
}

let user2 = copyObj(user);
user2.name = &#39;test&#39;;

console.log(user.name, user2.name); // abc test

user.urls.blog = &#39;https://github.io&#39;;

console.log(user.urls.blog, user2.urls.blog) //https://github.io https://github.io
console.log(user.urls.blog === user2.urls.blog) // true</code></pre>
<p><code>copyObj</code>는 얕은 복사만 수행했습니다. 중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때, 그 주솟값만 복사한다는 의미입니다.</p>
<p>데이터 타입인 <code>user.name</code>은 값이 바뀌지만, 한단계 더 들어간 <code>user.urls</code>는 객체영역의 주소를 그대로 복사한 것이여서 원본과 사본을 어떤 것을 바꾸던 둘 다 영양을 미치게 됩니다.</p>
<p>그렇다면 깊은 복사는 어떻게 되는 것일까요?</p>
<pre><code class="language-js">// 중첩 객체에 대한 깊은 복사
let user2 = copyObj(user);
user2.urls = copyObj(user.urls);</code></pre>
<p>내부적으로 중첩된 객체를 한번 더 copy해주면 문제를 해결 할 수 있습니다..
이런 원리로 깊은 복사를 수행하는 함수 코드는 아래와 같습니다.</p>
<pre><code class="language-js">let copyDeepObj = function(target) {
    let result = {}
    if (typeof target === &#39;object&#39; &amp;&amp; target !== null) {
        for (let key in target) {
            result[key] = copyDeepObj(target[key]);
        }
    } else {
        result = target;
    }

    return result;
}</code></pre>
<p>target이 객체인 경우만 돌며, 내부 프로퍼티를 순회할 때, 함수적으로 재귀적으로 호출합니다.</p>
<p>&nbsp;</p>
<hr>
<h2 id="json-활용한-깊은-복사">JSON 활용한 깊은 복사</h2>
<p>JSON을 활용하여 간단하게 깊은 복사가 가능합니다. </p>
<pre><code class="language-js">let copyObjJSON = function(target) {
    return JSON.parse(JSON.stringify(target));
}</code></pre>
<p>JSON stringify를 왜 사용하는지 잘 몰랐으나 공부를 하면서 알게 되었습니다.</p>
<p>&nbsp;</p>
<hr>
<h2 id="spread-operartor">spread operartor</h2>
<p>&nbsp;</p>
<hr>
<h2 id="undefined와-null">undefined와 null</h2>
<p>JS에서 값이 없다는 것을 나타내는 것으로는 크게 <code>undefined</code>와 <code>null</code>이 있습니다.
하지만 이 둘은 사용목적도 다르고, 의미하는 것도 다릅니다.</p>
<p><code>undefined</code>의 정확한 의미는 <strong>값이 없음</strong>을 의미합니다.</p>
<pre><code class="language-js">let arr = [];
arr.length = 3;
console.log(arr); // [ &lt;3 empty items&gt; ]
let arr2 = [];
arr = [undefined, undefined, undefined];</code></pre>
<p>정말 배열 안에 아무것도 없다면 <code>empty</code>가 출력 됩니다. 하지만 JS에서는 사용자가 명시적으로 <code>undefined</code>를 할당하지 않는 이상, JS가 반환하는 <code>undefined</code>는 어딘가 저장된 값이 아니라, <strong>아직 존재하지 않는 프로퍼티에 접근했음</strong>을 의미합니다.</p>
<p>따라서 JS에서는 명시적으로 없는 값을 넣어주려면, <code>undefined</code>보다 <code>null</code>을 사용하는게 맞습니다.</p>
<p><code>null</code>의 타입은 객체와 같은 <code>object</code>타입이므로, <code>null</code>을 확인하기 위해서는 <code>==</code> 동등연산자가 아닌 <code>===</code> 일치연산자로 확인을 해야 구분이 가능합니다.</p>
<blockquote>
<p>흔히 var는 값을 초기화 시켜주면서 undefined로 값이 초기화 된다고 알고 있지만, 엄밀히 말해서는 아닙니다.
정확히는 <strong>아무것도 할당하지 않고 끝내고 변수에 접근 할 때, undefined를 반환</strong>해주는 것입니다.</p>
</blockquote>
<p>&nbsp;</p>
<hr>
<h2 id="referance">Referance</h2>
<p>그림 참고
<a href="https://velog.io/@solmii/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%ED%95%98">solmii.velog</a></p>
<p>자료 참고
코어 스크립트 - 저자 정재남</p>
<blockquote>
<p>정말 많이 참고 했습니다. 감사합니다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TypeScript] function type]]></title>
            <link>https://velog.io/@edan_3000/TypeScript-function-type</link>
            <guid>https://velog.io/@edan_3000/TypeScript-function-type</guid>
            <pubDate>Wed, 27 Oct 2021 09:49:46 GMT</pubDate>
            <description><![CDATA[<h1 id="typescript-function">TypeScript Function</h1>
<p>기본적인 JavaScript function type</p>
<pre><code class="language-js">function add (x, y) {
  return x + y;
}</code></pre>
<h2 id="typing-the-function">Typing the function</h2>
<p>위 예시에서 TypeScript의 방식으로 작성하자면</p>
<pre><code class="language-ts">function add (x: number, y: number): number {
  return x + y;
}</code></pre>
<h2 id="함수타입-작성하는-방법-중-하나">함수타입 작성하는 방법 중 하나</h2>
<p>함수의 타입은 매개변수 타입과 반환 타입 두가지가 있다.
가독성을 위한 코드는 이렇게도 쓸 수 있다.</p>
<pre><code class="language-ts">let myAdd: (x: number, y: number) =&gt; number = function(x: number, y: number): number {
  return x + y;
}</code></pre>
<p><code>=&gt;</code>를 통해 반환타입을 설정해 준다.
함수를 반환하지 않는다면 <code>void</code> 를 사용하면 된다.</p>
<blockquote>
<p>이렇게 작성하는게 가독성을 높이는 코드일까?</p>
</blockquote>
<h2 id="타입추론-inferring-the-types">타입추론 (inferring the types)</h2>
<p>typescript는 방정식의 한쪽만 타입이 있더라도 타입을 알 수 있다.</p>
<pre><code class="language-ts">// myAdd는 전체 함수 타입을 가집니다
let myAdd = function(x: number, y: number): number { return  x + y; };
// function 에 선언된 값이 리턴타입

// 매개변수 x 와 y는 number 타입을 가집니다
let myAdd: (baseValue: number, increment: number) =&gt; number =
    function(x, y) { return x + y; };

// 반대로 왼쪽에 타입을 선언해주고 함수를 선언 할 수 있다.</code></pre>
<h2 id="선택적-매개변수--기본-매개변수optional-and-default-parameter">선택적 매개변수 &amp; 기본 매개변수(Optional and Default Parameter)</h2>
<p>선택적 매개변수는 전에 포스팅 했듯이 타입뒤에 <code>?</code>를 써주면 된다.</p>
<pre><code class="language-ts">function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + &quot; &quot; + lastName;
    else
        return firstName;
}

let result1 = buildName(&quot;Bob&quot;);                  // 지금은 바르게 동작
let result2 = buildName(&quot;Bob&quot;, &quot;Adams&quot;, &quot;Sr.&quot;);  // 오류, 너무 많은 매개변수
let result3 = buildName(&quot;Bob&quot;, &quot;Adams&quot;);         // 정확함</code></pre>
<p>매개변수는 값을 정해 두고 사용할 수도 있다.</p>
<pre><code class="language-ts">function buildName(firstName: string, lastName = &quot;Smith&quot;) {
    return firstName + &quot; &quot; + lastName;
}

let result1 = buildName(&quot;Bob&quot;);                  // 올바르게 동작, &quot;Bob Smith&quot; 반환
let result2 = buildName(&quot;Bob&quot;, undefined);       // 여전히 동작, 역시 &quot;Bob Smith&quot; 반환
let result3 = buildName(&quot;Bob&quot;, &quot;Adams&quot;, &quot;Sr.&quot;);  // 오류, 너무 많은 매개변수
let result4 = buildName(&quot;Bob&quot;, &quot;Adams&quot;);         // 정확함</code></pre>
<h2 id="나머지-매개변수-rest-parameters">나머지 매개변수 (Rest Parameters)</h2>
<p>파라미터하나에 나머지 모든 변수를 다 넣어서 나마지 매개변수 형식으로 사용할 수 있다.</p>
<pre><code class="language-ts">function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + &quot; &quot; + restOfName.join(&quot; &quot;);
}

// employeeName 은 &quot;Joseph Samuel Lucas MacKinzie&quot; 가 될것입니다.
let employeeName = buildName(&quot;Joseph&quot;, &quot;Samuel&quot;, &quot;Lucas&quot;, &quot;MacKinzie&quot;);</code></pre>
<h2 id="this-매개변수">this 매개변수</h2>
<pre><code class="language-ts">function f(this: void) {
    // 독립형 함수에서 `this`를 사용할 수 없는 것을 확인함
}</code></pre>
<h2 id="콜백에서-this-매개변수">콜백에서 this 매개변수</h2>
<p>콜백을 일반 함수처럼 호출하므로 <code>this</code>는 <code>undefined</code>가 된다. 일부 작업에서는 this 매개변수를 콜백 오류를 막는데 사용할 수 있다.</p>
<pre><code class="language-ts">interface UIElement {
    addClickListener(onclick: (this: void, e: Event) =&gt; void): void;
}

class Handler {
    info: string;
    onClickGood = (e: Event) =&gt; { this.info = e.message }
}</code></pre>
<h2 id="오버로드">오버로드</h2>
<p>이해 안됌...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TypeScript] Interface 개념정리]]></title>
            <link>https://velog.io/@edan_3000/TypeScript-Interface-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@edan_3000/TypeScript-Interface-%EA%B0%9C%EB%85%90%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 26 Oct 2021 09:49:05 GMT</pubDate>
            <description><![CDATA[<h1 id="first-interface">First Interface</h1>
<h2 id="interface-가장-기초적인-선언과-사용-방식">interface 가장 기초적인 선언과 사용 방식</h2>
<pre><code class="language-ts">interface Car {
  name:  string;
}
function printCar (carObj: Car) {
  console.log(carObj.name);
}

let myObj = {size:10, label: &#39;Size 10 Object&#39;};
printLabel(myObj);</code></pre>
<h2 id="optional-properties">Optional Properties</h2>
<p>타입 선언을 할때, 뒤에 <code>?</code>를 사용하여 타입을 선언해준다. <code>any</code>타입과 비슷하게 사용할 수 있다. 즉, 타입을 선언하지 않아도 사용할 수 있다.</p>
<pre><code class="language-ts">interface Car {
  name?: string;
  price?: number;
}

function buyCar (userCar: Car): {name: string; carNumber: number} {
  let bmw = {name: &#39;audio&#39;, carNumber: 1};
  if (userCar.name) {
    bmw.name = userCar.name;
  }

  return bmw;
}</code></pre>
<h2 id="readonly-properties">Readonly Properties</h2>
<p>타입을 선언 할 때, 앞에 <code>readonly</code>를 넣어준다.</p>
<pre><code class="language-ts">interface Point {
    readonly x: number;
    readonly y: number;
}</code></pre>
<blockquote>
<p>읽기 전용타입으로 선언한 경우 값을 변경 해 줄 수 없다.</p>
</blockquote>
<h2 id="readonly-vs-const">Readonly vs Const</h2>
<p>변수는 const를 사용하고 프로퍼티는 readonly를 사용</p>
<h2 id="excess-property-checks">Excess Property Checks</h2>
<pre><code class="language-ts">interface Car {
  name?: string;
  price?: number;
}

function buyCar (userCar: Car): {name: string; carNumber: number} {

}

let myCar = buyCar({names: &#39;audio&#39;, color: &#39;red&#39;});</code></pre>
<p>이렇게 선언을 할 경우 <code>초과 프로퍼티 검사 (excess property checking)</code>를 받는다.
이것을 해결하기 위해 <code>타입 단언</code>을 해주면 된다.</p>
<pre><code class="language-ts">let myCar = buyCar({name: &#39;audio&#39;, color: &#39;red&#39;} as buyCar);</code></pre>
<h2 id="function-types">Function Types</h2>
<pre><code class="language-ts">interface Car {
  (name: string, price: number): boolean;
}

let carInfo = Car;
const myCar = function (n: string, p: number): boolean {
  let answer = n.search(&#39;bmw&#39;);
  return answer &gt; -1;
}</code></pre>
<h2 id="indexable-types">Indexable Types</h2>
<p>Interface를 인덱스로 기술 할 수 있다.</p>
<pre><code class="language-ts">interface Car {
  [index: number]: string;
}

let carNames = Car;
carNames = [&#39;BMW&#39;, &#39;AUDIO&#39;];

let bmw: string = carNames[0];</code></pre>
<h2 id="class-types">Class Types</h2>
<p>class에서도 interface를 적용 시킬 수 있다.</p>
<pre><code class="language-ts">interface CarInterface {
  name: string;
}

class Car implements CarInterface {
  name: string = &#39;bmw&#39;;
  constructor(price: number, color: string) {}
}</code></pre>
<h2 id="클래스의-스태틱과-인스턴스의-차이점">클래스의 스태틱과 인스턴스의 차이점</h2>
<p>이해가 잘 되지 않는다...</p>
<h2 id="extending-interfaces">Extending Interfaces</h2>
<p>interface를 확장하여 여러개를 사용할 수 있다.</p>
<pre><code class="language-ts">interface Carinterface {
  carName: string;
}

interface Foodinterface {
  foodName: string;
}

interface Carfood extends Carinterface, Foodinterface {
  price: number;
}

let carandfood = {} as Carfood;
carandfood.carName = &#39;bmw&#39;;
carandfood.foodName = &#39;banana&#39;;
carandfood.price = 9999999999999;</code></pre>
<h2 id="hybrid-types">Hybrid Types</h2>
<p>유동적으로 사용하는 타입?</p>
<pre><code class="language-ts">interface Carinterface {
  carName: string;
  reset(); void;
}

function carName (): Carinterface {
  let car = (function (price: number) {}) as Carinterface; // 이부분을 하이브리드라고 말하는 듯
  car.carName = &#39;bmw&#39;;
  car.reset = function () {};
  return car;
}

let C = carName();
C.name = &#39;audio&#39;;
C(10000000);
c.reset();</code></pre>
<h2 id="interfaces-extending-classes">Interfaces Extending Classes</h2>
<p>클레스 상속과 비슷한 개념으로 interface는 기초 클래스의 private과 protected 멤버도 상속받습니다.
(뜻 이해 불가...)</p>
<pre><code class="language-ts">class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select() { }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TypeScript] 기본타입]]></title>
            <link>https://velog.io/@edan_3000/TypeScript-%EA%B8%B0%EB%B3%B8%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@edan_3000/TypeScript-%EA%B8%B0%EB%B3%B8%ED%83%80%EC%9E%85</guid>
            <pubDate>Fri, 22 Oct 2021 09:14:10 GMT</pubDate>
            <description><![CDATA[<h1 id="typescript-기본타입">TypeScript 기본타입</h1>
<h2 id="문자열-숫자-배열-객체-튜플">문자열, 숫자, 배열, 객체, 튜플</h2>
<p>TS 기본 타입 설정</p>
<pre><code class="language-ts">// 문자열
let car: string = &#39;bmw&#39;;

// 숫자
let age: number = 30;
// boolean
let isCar: boolean = true;

// 숫자 배열
let arr: number[] = [1,2,3];
let arr2: Array&lt;number&gt; = [1,2,3];

//문자열 배열
let arr3: string[] = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];

// 객체
let obj: object = {name : &#39;test&#39;, age: 13};

// 튜플
let b: [string, number];
b = [&#39;z&#39;, 1];
// b = [1, &#39;z&#39;]; //error

b[0].toLowerCase();
// b[1].toLowerCase(); // error</code></pre>
<h2 id="열거enum">열거(enum)</h2>
<p>열거로 집합체로 사용 할 수 있다.</p>
<pre><code class="language-ts">// enum 선언
enum User {Kim, Park, Choi}
let a: User = User.Kim;

// 값 설정
enum User2 {Kim = 19, Park = 20}
let userage: User2 = User2.Park;

// User 집합에 바로 접근
let username: string = User[2];

// enum: 비슷한 값끼리 묶을 때
enum Os {
    Window = 3,
    Ios = 10,
    Android
}

console.log(Os[10]); // &quot;Ios&quot;
console.log(Os[&#39;Ios&#39;]); //10


enum Os2 {
    Window = &#39;window&#39;,
    Ios = &#39;Ios&#39;,
    Android = &#39;Android&#39;
}

일반 객체 형태랑 같음
const Os2 = {
    Window = &#39;window&#39;,
    Ios = &#39;Ios&#39;,
    Android = &#39;Android&#39;
}

let myOs: Os;
myOs = Os.Android;</code></pre>
<h2 id="any">Any</h2>
<p>알지 못하는 타입을 표현할 때 주로 쓴다.</p>
<pre><code class="language-ts">let kimcoding: any = &#39;kimMan&#39;;</code></pre>
<h2 id="void-never">Void, Never</h2>
<p>void: 아무것도 반환하지 않을 때
never: 에러 반환하거나 무한루프일 경우</p>
<pre><code class="language-ts">const test = () =&gt; {
    let hi: string = &#39;hi&#39;;
    return hi;
}

const test1 = (): void =&gt; {
    console.log(&#39;test&#39;);
}

const test2 = (): never =&gt; {
    throw new Error();
}

const test3 = (): never =&gt; {
    while (true) {
        // do something..
    }
}</code></pre>
<h2 id="null-undefined">null, undefined</h2>
<pre><code class="language-ts">// null, undefined
let nullTest:null = null;
let undefinedTest:undefined = undefined;</code></pre>
<h2 id="object">Object</h2>
<pre><code class="language-ts">declare function car(name: string | price: number| obj: object): void;

car(42) // good
car(&#39;bmw&#39;) // good

car(null) // error
car(false) // error
car(undefined) // error</code></pre>
<h2 id="타입-선언">타입 선언</h2>
<p>TypeScript를 JSX와 함께 사용할 때는 as-스타일 허용</p>
<pre><code class="language-ts">// 일반적인 스타일
let car: any = &#39;bmw&#39;;
let carLength: number = (&lt;string&gt;car).length;

// as 스타일
let str: any = &#39;test string&#39;;
let strLength: number = (str as string).length;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TypeScript] TS for functional Programmers]]></title>
            <link>https://velog.io/@edan_3000/TypeScript-TS-for-functional-Programmers</link>
            <guid>https://velog.io/@edan_3000/TypeScript-TS-for-functional-Programmers</guid>
            <pubDate>Thu, 21 Oct 2021 10:49:01 GMT</pubDate>
            <description><![CDATA[<h2 id="내장-타입">내장 타입</h2>
<p>TS 내장 타입
JavaScript 와 동일한 원시 타입이 기본적으로 내장되어 있다.</p>
<ul>
<li>number</li>
<li>string</li>
<li>boolean</li>
<li>symbol</li>
<li>null</li>
<li>undefined</li>
<li>object</li>
</ul>
<p>&nbsp;</p>
<h2 id="ts-추가된-타입">TS 추가된 타입</h2>
<table>
<thead>
<tr>
<th>타입</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>unknow</td>
<td>최상위 타입</td>
</tr>
<tr>
<td>never</td>
<td>하위 타입</td>
</tr>
<tr>
<td>객체 리터럴</td>
<td>{property: Type}</td>
</tr>
<tr>
<td>void</td>
<td>return 타입으로 사용 하기 위함</td>
</tr>
<tr>
<td>T[]</td>
<td>수정 가능한 배열 === Array<T>로 사용 가능</td>
</tr>
<tr>
<td>[a, b]</td>
<td>고정된 길이지만 수정이 가능한 튜플</td>
</tr>
<tr>
<td>function( t: T) =&gt; {}</td>
<td>함수</td>
</tr>
</tbody></table>
<p>예시.1</p>
<pre><code class="language-ts">// void, never =&gt; void: 아무것도 반환하지 않을 때 || never: 에러 반환하거나 무한루프일 경우
const test = () =&gt; {
    let hi: string = &#39;hi&#39;;
    return hi;
}

const test1 = (): void =&gt; {
    console.log(&#39;test&#39;);
}

const test2 = (): never =&gt; {
    throw new Error();
}

const test3 = (): never =&gt; {
    while (true) {
        // do something..
    }
}</code></pre>
<h2 id="객체-리터럴">객체 리터럴</h2>
<p>객체 리터럴은 중괄호({...}) 내에 0개 이상의 프로퍼티를 정의하여 값을 생성하는 표기법</p>
<p>예시.2 객체 리터럴 타입 구문</p>
<pre><code class="language-ts">let test: { number: number, test2: object[] } = {number: 2, test2: []};&#39;</code></pre>
<h3 id="property">property</h3>
<p>프로퍼티란 객체의 상태를 나타내는 값(데이터)이며 키(key)과 값(value)으로 구성</p>
<pre><code class="language-ts">let obj = {
  car: &#39;bmw&#39;,
  price: 1000000000,
  ...
}</code></pre>
<p>더 공부할 주제 : property 접근, property 값 갱신/생성/삭제</p>
<h3 id="method">Method</h3>
<pre><code class="language-ts">let solution = {
  name: &#39;tester&#39;;
  sayName(): function() { // 메소드
    console.log(`hi ${this.name}`)
  }
}</code></pre>
<p>예시.3 함수타입의 매겨변수 타입 설정</p>
<pre><code class="language-ts">// 함수 구문의 매개변수 타입 설정
const test = (a: number, b: number) =&gt; {
    return a + b;
}</code></pre>
<h2 id="점진적-타이핑">점진적 타이핑</h2>
<p>TS의 표현식의 타입을 알 수 없을때마다 <code>any</code> 타입 사용</p>
<pre><code class="language-ts">const anyTest = [];
anyTest.push(1);
anyTest.push(&#39;hi&#39;);
anyTest.push({...});</code></pre>
<h2 id="구조적인-타이핑">구조적인 타이핑</h2>
<pre><code class="language-ts">let o = { x: &quot;hi&quot;, extra: 1 }; // 성공
let o2: { x: string } = o; // 성공</code></pre>
<p>이 타입은 필수 프로퍼티가 모두 있고 해당 프로퍼티에 할당 가능한 타입이 있으므로 { x : string } 에 할당할 수 있다.</p>
<h2 id="유니언unions">유니언(Unions)</h2>
<pre><code class="language-ts">function logText(text: string | number) {
  // ...
}</code></pre>
<h2 id="교집합">교집합</h2>
<pre><code class="language-ts">type Test = { a: number} &amp; { b: string};</code></pre>
<h2 id="타입-추론">타입 추론</h2>
<p>공부 필요</p>
<h2 id="타입-별칭">타입 별칭</h2>
<pre><code class="language-ts">type User = [string, number];
let user1: User = [&#39;김코딩&#39;, 19];</code></pre>
<h2 id="판별-유니온">판별 유니온</h2>
<pre><code class="language-ts">type Shape =
  | { kind: &quot;circle&quot;; radius: number }
  | { kind: &quot;square&quot;; x: number }
  | { kind: &quot;triangle&quot;; x: number; y: number };

function area(s: Shape) {
  if (s.kind === &quot;circle&quot;) {
    return Math.PI * s.radius * s.radius;
  } else if (s.kind === &quot;square&quot;) {
    return s.x * s.x;
  } else {
    return (s.x * s.y) / 2;
  }
}</code></pre>
<h2 id="타입-매겨변수">타입 매겨변수</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] 비동기]]></title>
            <link>https://velog.io/@edan_3000/Async</link>
            <guid>https://velog.io/@edan_3000/Async</guid>
            <pubDate>Tue, 22 Jun 2021 14:30:34 GMT</pubDate>
            <description><![CDATA[<h2 id="비동기-공부-목표"><strong>비동기 공부 목표</strong></h2>
<ul>
<li>blocking 개념</li>
<li>동기적 개념(synchronous)</li>
<li>non - blockin / 비동기 개념 (asynchronous)</li>
<li>비동기적으로 작동하는 기능<ul>
<li>로딩창 / 인터넷 서버 요청 후 응답 기다림 / 큰 용량 파일을 로딩</li>
</ul>
</li>
<li>callback / promise의 장점 단점</li>
<li>promise 패턴 공부<ul>
<li>resolve, reject 의미 then/catch 와의 관계</li>
<li>promise 인자 넘기는 법/세가지 상태/<code>promise.all</code> 이해</li>
</ul>
</li>
<li><code>async/await</code> 작동 원리</li>
</ul>
<hr>
<h3 id="비동기"><strong>비동기</strong></h3>
<p>간단히 동기와 비동기의 차이점을 설명하자면, 동기는 <code>전화</code>라고 생각할 수 있고, 비동기는 <code>문자</code>라고 생각할 수 있다. 전화는 당장 일을 멈추고 전화를 받아야 한다. 하지만 문자는 시간이 얼마나 걸리던 미룰수가 있다. 
즉, 요청과 동시에 벌어지는 일은 <code>동기</code> 요청과 동시에 벌어지지 않은 일은 <code>비동기</code>라고 생각하면 쉽다.</p>
<p>비동기의 흐름을 알아야 한다.
비동기의 흐름은 크게 3가지가 있다.</p>
<ul>
<li>callback</li>
<li>promise</li>
<li>async/await 
3가지의 문법을 이용하여 구현할 수 있어야 한다.</li>
</ul>
<p>대표적인 비동기 예시로는 유튜브 동영상이다.</p>
<h3 id="callback-함수"><strong>callback 함수</strong></h3>
<p>차근 차근 알아보자</p>
<blockquote>
<ol>
<li>JavaScript is Synchronous.
JavaScript는 기본적으로 동기적인 아이다. 따라서 순차적으로 실행되는게 맞다.</li>
</ol>
</blockquote>
<blockquote>
<ol start="2">
<li>Execute the code block in order after hoisting.
호이스팅이 된 이후 부터 코드가 작성된 순서에 맞춰서 순차적으로 진행된다.</li>
</ol>
</blockquote>
<blockquote>
<ol start="3">
<li>Hoisting : var 변수, function declaration(함수선언)들이 제일 위로 올라가서 코드가 나타나는 순간부터 실행된다.</li>
</ol>
</blockquote>
<blockquote>
<p><code>setTimeout()</code> : web API로 지정한 시간이 지나면 callback 함수를 호출하는 것 // 뒤에 시간은 웹 브라우저 시간으로 작성된다. 1000 msec = 1sec</p>
</blockquote>
<h4 id="그럼-callback-함수는"><strong>그럼 callback 함수는?</strong></h4>
<pre><code class="language-js">setTimeout(function () {
  console.log(&#39;Hello World)
}, 1000);</code></pre>
<blockquote>
<p><code>setTimeout</code> 우리가 만든 함수 파라미터 인자로 /// (끊고 생각) 우리가 만든 함수를 전달해 준다. 지정된 시간 후에 실행 함수를 실행시켜줘 라는 것을 <code>callback</code>이라고 한다.</p>
</blockquote>
<p>고차 함수는 다른 함수의 인자를 전달 받을 수 있다. 또한, 리턴도 가능하다.
<code>caller</code>는 callback 함수를 전달 받는 함수로 함수 내부에서 <code>callback</code>함수를 호출하여 사용할 수 있다.</p>
<blockquote>
<p>callback 함수는 asynchrnous를 순차적으로 제하기 위해 만든 것</p>
</blockquote>
<pre><code class="language-js">// 순차적으로 실행이 안된다.
const print = (string) =&gt; {
  setTime (() =&gt; {
    console.log(string))
  }, Math.floor(Math.random() * 100) + 1
  )
}
const printall = () =&gt; {
  print(&#39;a&#39;)
  print(&#39;b&#39;)
  print(&#39;c&#39;)
}</code></pre>
<pre><code class="language-js">// callback 함수
const print = (string, callback) =&gt; {
  setTime (() =&gt; {
    console.log(string))
    callback()
  }, Math.floor(Math.random() * 100) + 1
  )
}
const printall = () =&gt; {
  print(&#39;a&#39;, () =&gt;  {
    print(&#39;b&#39;, () =&gt; {
      print(&#39;c&#39;,() =&gt; {
      })
    })
  })
}</code></pre>
<h4 id="동기-callback-함수-구현"><strong>동기 callback 함수 구현</strong></h4>
<pre><code class="language-js">console.log(&#39;a&#39;);
setTimeout(() =&gt; console.log(&#39;b&#39;), 1000); 
console.log(&#39;c&#39;);

function printSynchronous (print) {
  print();
}

printSynchronous (() =&gt; console.log(&#39;hello&#39;))
// 출력결과
// a
// c
// hello
// b</code></pre>
<h4 id="비동기-callback-함수-구현"><strong>비동기 callback 함수 구현</strong></h4>
<pre><code class="language-js">function printAsynchronous (print, timeout) {
  setTimeout(print, timeout);
}
printAsynchronous(() =&gt; console.log(&#39;async callback&#39;), 2000);

// 출력 결과
// a
// c
// hello
// b
// async callback</code></pre>
<hr>
<h3 id="underbar"><strong>underbar</strong></h3>
<p>직접 구현해보는 프로젝트를 했다.
간단한 개념은 쉬웠으나, deep한 기능을 구현하는것은 쉽지 않았다.</p>
<hr>
<h3 id="promise"><strong>promise</strong></h3>
<p>callback으로 하드코딩을 하면 가독성도 떨어지고, 비즈니스 모델 성능도 좋지 않아진다. 또한 디버깅시 어디서 버그가 났는지 찾기가 힘들어 진다. 이를 위해 <code>promise</code>를 사용한다.</p>
<blockquote>
<p><code>promise</code> : JS에서 제공하는 비동기를 간편하게 해결하기 위한 Object이다.</p>
</blockquote>
<blockquote>
<ol>
<li>Promise is a JavaScript object for asynchronous operation.
<code>상태</code> : pending  -&gt; fulfilled or rejected
<code>Producer / Consumer</code></li>
</ol>
</blockquote>
<blockquote>
<p>Producer (제공자)
new Promise가 인스턴스로 만들어 지는 순간, 자동적으로 executor가 실행된다.</p>
</blockquote>
<pre><code class="language-js">// Promise에 있는 callback 함수 2개 
// 1. resolve : 기능 정상 실행 후 마지막 데이터 전달
// 2. reject : 기능 실행하다가 문제 발생시 호출
const promise = new Promise((resolve, reject)=&gt; { 
  // 무거운 업무  &gt;&gt;&gt; 영상 등 용량이 큰 데이터 (network, read files)
  console.log(&#39;doing something...&#39;);
  setTimeout(() =&gt; {
    // 주석 풀면서 사용해 보면 쉽다!
    // resolve(&#39;ellie&#39;);
    // reject(new Error(&#39;no network&#39;));
  }, 2000);
}); </code></pre>
<h4 id="알-수-있는-사실"><strong>알 수 있는 사실</strong></h4>
<blockquote>
<p>Promise를 만든 순간 executer가 바로 만들어지며, 네트워크를 같이 수행한다.
사용자가 요구하는 순간 네트워크가 실행되므로 적절한 기능에 사용해야 한다.</p>
</blockquote>
<blockquote>
<p>Consumer
then, catch, finally</p>
</blockquote>
<pre><code class="language-js">// 값이 정상적으로 수행 된다면 value는 resolve의 값인 &#39;ellie&#39;가 들어올 것이다
promise.then((value) =&gt; {
  //우리가 원하는 callback 함수 실행
  console.log(value);
})

promise
    .then((value) =&gt; {
        console.log(value);
})
    .catch((error) =&gt; {
        console.log(error);
    })
    .finally(() =&gt; {
        console.log(&#39;finally&#39;);
    })</code></pre>
<h3 id="promise-chaining"><strong>Promise chaining</strong></h3>
<pre><code class="language-js">const fetchNumber = new Promise((resolve, reject) =&gt; {
    setTimeout(() =&gt; {
        resolve(1);
    }, 1000);
})

// then은 값을 전달해도 되고 다른 promise를 전달해도 된다.

fetchNumber
  .then(num =&gt; num * 2)
  .then(num =&gt; num * 3)
  .then(num =&gt; {
    return new Promise((resolve, reject) =&gt; {
      setTimeout(() =&gt; {
        resolve(num - 1);
      }, 1000);
    })
  })
  .then(num =&gt; {
      console.log(num);
  })</code></pre>
<h3 id="error-handling"><strong>Error Handling</strong></h3>
<pre><code class="language-js">const getHen = () =&gt; 
    new Promise ((resolve, reject) =&gt; {
        setTimeout(() =&gt; resolve(&#39;닭&#39;), 1000);
    });
const getEgg = hen =&gt; 
    new Promise ((resolve, reject) =&gt; {
        setTimeout(() =&gt; reject(new Error(`${hen} =&gt; egg`)), 1000);
    });

const cook = egg =&gt; 
    new Promise ((resolve, reject) =&gt; {
        setTimeout(() =&gt; resolve(`${egg} =&gt; 계란후라이`), 1000);
    });


getHen()
  .then(hen =&gt; getEgg(hen))
  .catch(error =&gt; {
      return &#39;빵&#39;;
  })
  .then(egg =&gt; cook(egg))
  .then(meal =&gt; console.log(meal));</code></pre>
<hr>
<h3 id="asyncawait"><strong>async/await</strong></h3>
<p><code>promise</code>에서 작성했던 then, catch가 많아지면 난잡해 질 수 있는 것을 좀더 보기 편하게 만들어주기 위함이다.</p>
<blockquote>
<p>async</p>
</blockquote>
<pre><code class="language-js">// 1. async
async function fetchUser() {
    // do network reqeust in 10 secs...
    return &#39;kimcoding&#39;;
}

const user = fetchUser();
user.then(console.log)
console.log(user);</code></pre>
<blockquote>
<p>await</p>
</blockquote>
<pre><code class="language-js">// 2.await
function delay(ms) {
    return new Promise (resolve =&gt; setTimeout(resolve, ms));
}

async function getApple() {
    await delay(1000);
    return &#39;사과&#39;;
}

async function getBanana() {
    await delay(2000);
    return &#39;바나나&#39;;
}

function getBananaNon() {
    return delay(3000)
    .then(() =&gt; &#39;바나나&#39;)
}

function basketFruits() {
    return getApple().then(apple =&gt; {
        return getBanana().then(banana =&gt; `${apple} + ${banana}`)
    })
}

// 병렬로 된다
async function basketFruits() {
    const applePromise = getApple();
    const bananaPromise = getBanana();
    const apple = await applePromise;
    const banana = await bananaPromise;
    return `${apple} + ${banana}`
}

basketFruits().then(console.log);</code></pre>
<blockquote>
<p>그 밖에 유용한 API</p>
</blockquote>
<pre><code class="language-js">// 3. userful Promise APIs

// all API
function basketFruits() {
    return Promise.all([getApple(), getBanana()])
    .then(fruits =&gt; fruits.join(&#39; + &#39;))
}

basketFruits().then(console.log);

// race API
function basketPickOnlyOne () {
    return Promise.race([getApple(), getBanana()]);
}
basketPickOnlyOne().then(console.log)</code></pre>
<h2 id="referance">Referance</h2>
<p><a href="https://www.youtube.com/watch?v=s1vpVCrT8f4">드림코딩 엘리님 - callback</a>
<a href="https://www.youtube.com/watch?v=JB_yU6Oe2eE">드림코딩 엘리님 - promise</a>
<a href="https://www.youtube.com/watch?v=aoQSOZfz3vQ">드림코딩 엘리님 - async/await</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] 자료구조 개념]]></title>
            <link>https://velog.io/@edan_3000/DataStructure</link>
            <guid>https://velog.io/@edan_3000/DataStructure</guid>
            <pubDate>Tue, 22 Jun 2021 14:28:43 GMT</pubDate>
            <description><![CDATA[<h2 id="자료구조-공부-목표"><strong>자료구조 공부 목표</strong></h2>
<ul>
<li>자료구조 개념 및 설명</li>
<li>stack, queue, tree, graph 개념 이해<ul>
<li>기본 개념과 구조를 파악 및 목적을 이해</li>
<li>상황에 맞는 자료구조를 떠올릴 수 있다.</li>
</ul>
</li>
<li>tree 및 graph 탐색 기법 이해<ul>
<li>BST 이해</li>
<li>BFS, DFS 개념 이해</li>
</ul>
</li>
</ul>
<h3 id="자료구조란"><strong>자료구조란?</strong></h3>
<p>쉽게 말해 <strong>데이터들의 구조</strong>이다.
수많은 데이터들을 어떻게 저장하고, 어떻게 위치를 새우냐에 따라 사용하는 방법이 다를 것이다.</p>
<p><code>데이터</code> : 문자, 숫자, 그림, 영상 등 다양한 정보의 집합</p>
<h3 id="자료구조-종류"><strong>자료구조 종류</strong></h3>
<h4 id="자료구조"><strong>자료구조</strong></h4>
<ul>
<li><p>단순구조</p>
<ul>
<li>정수 / 실수</li>
<li>문자 / 문자열</li>
<li>2진수</li>
</ul>
</li>
<li><p>선형구조 (선 모양으로 생긴 자료 구조)</p>
<ul>
<li>리스트(배열)</li>
<li>연결 리스트<ul>
<li>단순 / 이중 / 원형</li>
</ul>
</li>
<li>덱 / 스텍 / 큐</li>
</ul>
</li>
<li><p>비선형구조</p>
<ul>
<li>트리<ul>
<li>일반 트리 / 이진 트리</li>
</ul>
</li>
<li>그래프<ul>
<li>방향 그래프 / 무방향 그래프</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="stack"><strong>STACK</strong></h2>
<p>데이터를 순서대로 쌓는 자료구조
스텍을 쉽게 설명하기 위해서 엘리베이터에 들어가는 사람들로 이해하면 쉽다.</p>
<p>엘리베이터에 먼저 탄 사람이 나중에 탄 사람보다 반드시 늦게 나와야 한다는 조건 하에
엘리베이터에 사람들이 들어가면 나중에 타는 사람부터 빠져나와야 처음 탄 사람이 엘리베이터에서 내릴 수 있다.</p>
<h3 id="스텍의-개념">스텍의 개념</h3>
<p>스텍은 FILO 특징을 가지고 있다.</p>
<blockquote>
<p><code>FILO</code> : First In Last Out 먼저 들어간 input값은 마지막에 나온다.</p>
</blockquote>
<p>스텍과 정확히 반대 되는 개념이 <strong>Queue</strong>이다.</p>
<h2 id="queue"><strong>QUEUE</strong></h2>
<p>큐는 지하철 개찰구를 생각하면 쉽다.
앞사람이 개찰구로 들어가야만 다음사람이 들어갈 수 있다.</p>
<h3 id="큐이-개념">큐이 개념</h3>
<p>큐는 FIFO OR LILO 특징을 가지고 있다.</p>
<blockquote>
<p><code>FIFO</code> : First in First out 먼저 들어간 input값은 먼저 출력 된다.</p>
</blockquote>
<hr>
<h3 id="새롭게-알아-가는-것">새롭게 알아 가는 것</h3>
<p>데이터를 장치들이 주고 받을 때, 장치 사이에 존재하는 속도, 시간 등의 차이를 극복하기 위해 임시 기억 장치에 Queue 형태로 사용합니다. 이것을 통틀어 <strong>버퍼(Buffer)</strong> 라고 합니다.</p>
<hr>
<h2 id="graph"><strong>GRAPH</strong></h2>
<p>자료구조에서 그래프는 비선형구조로 순서가 없고, 서로 복잡하게 연결되어 있는 자료구조 이다.</p>
<p><code>정점</code> : 하나의 점을 정점이라고 말한다.
<code>간선</code> : 점과 점을 이어주는 선을 간선이라고 한다.</p>
<h3 id="트리-용어"><strong>트리 용어</strong></h3>
<p><code>무방향 그래프</code>
<code>진입차수 / 진출차수</code>
<code>인접</code>
<code>자기루프</code>
<code>사이클</code></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] 재귀]]></title>
            <link>https://velog.io/@edan_3000/recursion</link>
            <guid>https://velog.io/@edan_3000/recursion</guid>
            <pubDate>Tue, 22 Jun 2021 14:26:26 GMT</pubDate>
            <description><![CDATA[<h2 id="재귀-공부-목표"><strong>재귀 공부 목표</strong></h2>
<ul>
<li><p>재귀적 사고</p>
<ul>
<li>쪼개어 생각하기</li>
<li>함수 자신의 재귀적 호출</li>
<li>탈출 조건</li>
</ul>
</li>
<li><p>재귀 활용(트리 구조)</p>
<ul>
<li>트리 구조 </li>
<li>json 구조</li>
<li>dom 구조</li>
</ul>
</li>
</ul>
<hr>
<h3 id="재귀-함수"><strong>재귀 함수</strong></h3>
<ul>
<li>재귀란?</li>
<li>재귀 함수 언제 사용해?</li>
<li>재귀 함수 사용 연습</li>
</ul>
<h3 id="문제를-쪼개서-생각하기">문제를 쪼개서 생각하기</h3>
<p>하나의 배열이 있고, 그 배열의 합을 구하는 함수를 만든다고 가정하자</p>
<p>내가 생각한 공식은 반복문 이었다.</p>
<pre><code class="language-js">arr = [1, 2, 3, 4, 5]

let sum = 0
for (let i = 0; i &lt; arr.length; i++) {
    sum += arr[i]
}
console.log(sum);</code></pre>
<p>하지만 반복문 없이 단순히 arr의 원자의 합을 구한다고 생각해 보자
한번에 합을 계산하는 것보다 하나씩 쪼개서 계산하는게 더 쉬울 것이다.</p>
<pre><code class="language-js">[1] sum = 1
[1, 2] sum = 3
[1, 2, 3] sum = 6
[1, 2, 3, 4] sum = 10
[1, 2, 3, 4, 5] sum = 15</code></pre>
<p>즉 원자 하나에서 다른 하나를 더해가는 과정이다.</p>
<pre><code class="language-js">1
1 + 2
1 + 2 + 3
1 + 2 + 3 + 4
1 + 2 + 3 + 4 + 5</code></pre>
<h3 id="그렇다면-재귀는-언제-쓰일까"><strong>그렇다면 재귀는 언제 쓰일까?</strong></h3>
<p><strong>저렇게 반복문으로 계산하면 되지 왜 재귀를 써?</strong> 라고 생각 할 수도 있다.</p>
<p>하지만 반복문이 <strong>4중 5중</strong> 으로 엄청나게 많아 진다면 <strong>시간 복잡도가 증가</strong>하고, 코드의 효율은 떨어질 것이다.</p>
<p>재귀의 예로 하노이의 탑을 많이 든다. 한번 찾아보고 직접 반복문으로 구현을 해보는 것은</p>
<p> <strong>추천드리지 않는다.</strong></p>
<h3 id="재귀적-사고"><strong>재귀적 사고</strong></h3>
<ol>
<li>가장 단순하게 정의하기<ul>
<li>가장 작은 단위를 먼저 생각합니다 ex) sum 1 = 1</li>
</ul>
</li>
<li>가장 단순하게 정의한 것에서 그 부분만 해결하기<ul>
<li>ex) sum = sum + el</li>
</ul>
</li>
<li>다음 경우의 수를 합쳐서 생각하기<ul>
<li>ex) function sum을 다음 수를 생각하여 구하기</li>
</ul>
</li>
<li>마지막 결과까지 해결하기</li>
<li>코드 구현하기</li>
</ol>
<h3 id="재귀의-문제로-재귀-구현하기--팩토리얼-문제">재귀의 문제로 재귀 구현하기 &gt;&gt;&gt; 팩토리얼 문제</h3>
<p><code>팩토리얼</code></p>
<pre><code class="language-js">function factorial (n) {
    if (n === 1) {
        return 1
    }
    return n * factorial(n - 1)
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] 객체 지향 프로그래밍(OOP)]]></title>
            <link>https://velog.io/@edan_3000/OOP</link>
            <guid>https://velog.io/@edan_3000/OOP</guid>
            <pubDate>Tue, 22 Jun 2021 14:24:56 GMT</pubDate>
            <description><![CDATA[<h2 id="oop-공부-목표객체-지향-프로그래밍"><strong>OOP 공부 목표(객체 지향 프로그래밍)</strong></h2>
<ul>
<li><p>클래스 개념 이해 / 인스턴스 개념 이해</p>
<ul>
<li>new 사용법</li>
<li>class 사용법</li>
<li>추상화 / 현실을 바탕으로 메소드, 속성 디자인</li>
</ul>
</li>
<li><p>OOP(객체 지향 프로그래밍)</p>
<ul>
<li>다형성</li>
<li>캡슐화</li>
<li>상속</li>
<li>추상화</li>
</ul>
</li>
<li><p>프로토 타입 개념 이해</p>
</li>
<li><p>상속 개념 이해</p>
<ul>
<li>클래스 상속 원리 이해</li>
<li>Prototype chain 이해</li>
<li>상속 관계 현실 세계 모델을 코드로 작성</li>
</ul>
</li>
</ul>
<hr>
<h3 id="class-모듈화"><strong>Class 모듈화</strong></h3>
<blockquote>
<p>앞서 필요한 개념
객체 개념 // 클로저 개념 // 객체 다루기</p>
</blockquote>
<h4 id="메소드-호출-실습하기"><strong>메소드 호출 실습하기</strong></h4>
<p>메소드 호출 방식에서는 <code>화살표 함수</code>를 쓰지 않습니다. 이유는 <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions#%EB%B0%94%EC%9D%B8%EB%94%A9_%EB%90%98%EC%A7%80_%EC%95%8A%EC%9D%80_this">mdn</a>을 잠초</p>
<pre><code class="language-js">let makeModule = {
    value1 : 1,
    add : function() {
        this.value1++;
    },
    minus: function() {
        this.value1--;
    },
    mutiplication: function() {
        this.value1 * 2;
    }
}

makeModule.add() // 2
makeModule.minus() // 1
makeModule.mutiplication() // 2
makeModule.mutiplication() // 4</code></pre>
<h4 id="클로저-이용해-객체-생성"><strong>클로저 이용해 객체 생성</strong></h4>
<pre><code class="language-js">function makeModule () {
    return {
        value1 : 1,
        add : function() {
        this.value1++;
        },
        minus: function() {
            this.value1--;
        },
        mutiplication: function() {
            this.value1 * 2;
        }
    }
}

let module1 = makeModule()

module1.add() // 2
module1.minus()  // 1

let module2 = makeModule()

module2.mutiplication() // 2
module2.add() // 3
module2.mutiplication() // 6
</code></pre>
<blockquote>
<p>module1 과 module2는 서로 영향을 미치지 않는다.</p>
</blockquote>
<hr>
<h3 id="class-vs-인스턴스"><strong>Class VS 인스턴스</strong></h3>
<blockquote>
<p>제일 설명하기 좋은 모델은 붕어빵이라고 생각합니다.</p>
</blockquote>
<p><code>Class</code> : 붕어빵을 만드는 모든 기계 // 붕어빵 틀, 가스레인지 등등
<code>인스턴스</code> : 슈크림 붕아빵, 팥 붕어빵, 미니 붕어빵 등등</p>
<pre><code class="language-js">//클래스
function FishBread (앙금) {
}

// 인스턴스
let chouBread = new FishBread(chou); // 슈크림 붕어빵
let redbeanBread = new FishBread(redbean) // 팥 붕어빵
let miniBread = new FishBread(mini) // 미니 붕어빵</code></pre>
<h4 id="es6에서는-class라는-키워드로-정의할-수도-있다"><strong>ES6</strong>에서는 class라는 키워드로 정의할 수도 있다.</h4>
<pre><code class="language-js">class FishBread {
    constructor (앙금, 이름, 가격) {
        // 인스턴스 만들시 실행도는 코드
    }
}

let chouBread = new FishBread(chou, &#39;슈크림 붕어빵&#39;, 1500); // 슈크림 붕어빵
let redbeanBread = new FishBread(redbean, &#39;팥 붕어빵&#39;, 1000) // 팥 붕어빵
let miniBread = new FishBread(mini, &#39;미니 붕어빵&#39;, 500) // 미니 붕어빵</code></pre>
<p><code>constructor</code> </p>
<ul>
<li>생성자라고 하며 생성자는 <code>return</code> 을 해주지 않는다.</li>
<li>인스턴스가 초기화 될 시 실행되는 생성자 함수</li>
</ul>
<blockquote>
<p>이렇게 생성된 인스턴스는 <code>Class FishBread</code>의 속성과 메소드를 갖는다.
<code>속성</code> : 앙금, 이름, 가격 등등 // 하나를 만들기 위해 필요한 재료
<code>메소드</code> : 틀모양, 불세기, 굽는 시간 등등 // 어떤 붕어빵이든 모든 다 적용됨</p>
</blockquote>
<h4 id="this"><strong>this</strong></h4>
<pre><code class="language-js">class FishBread {
    constructor(앙금, 이름, 가격) {
        // 인스턴스의 앙금 객체 = 인스턴스의 파라미터 앙금
        this.앙금 = 앙금; 
        // 인스턴스의 이름 객체 = 인스턴스의 파라미터 이름
        this.이름 = 이름; 
        // 인스턴스의 가격 객체 = 인스턴스의 파라미터 가격
        this.가격 = 가격; 
    }
}</code></pre>
<p>ES6 를 공부하다보면 항상 <code>this</code> 란 <strong>녀석</strong>이 등장한다.</p>
<p><code>this</code> : 간단히 설명하자면 인스턴스의 객체를 의미한다.
파라미터로 넘어온 값을 인스턴스 생성시 지정하는 defualt 값이며, 만들어진 인스턴스에 앙금, 이름, 가격을 만들어주는 변수를 선언해 준 것이다!</p>
<hr>
<h3 id="oop객체-지향-프로그래밍"><strong>OOP</strong>(객체 지향 프로그래밍)</h3>
<p><code>Class</code> 의 구성 요소로는 크게 두가지가 있다.</p>
<ul>
<li><code>속성</code> // Attrubute</li>
<li><code>메소드</code> // Methods</li>
</ul>
<h4 id="캡슐화-encapsulation"><strong>캡슐화</strong> (Encapsulation)</h4>
<ul>
<li>기능을 하나의 단위로 만들어 놓은 것</li>
<li>동작은 노출 시킴</li>
</ul>
<h4 id="상속-inheritance"><strong>상속</strong> (Inheritance)</h4>
<ul>
<li>부모 클래스의 특징을 자식 클래스가 물려 받는 것</li>
<li>식물 &gt;&gt;&gt; 나무 // 동물 &gt;&gt;&gt; 호랑이</li>
</ul>
<h4 id="추상화-abstraction"><strong>추상화</strong> (Abstraction)</h4>
<ul>
<li>내부 구조는 복잡하나 실제로 우리가 보는 부분은 단순하게 만든다는 개념</li>
<li>핸드폰을 볼때 스크린 하나 밖에 안보이며, 터치가 되고, 양 옆에는 버튼이 존재하지만 내부적으로는 여러 프로그램 및 기능이 있어야 한다.</li>
</ul>
<h4 id="다형성-polymorphsim--개념-이해-부족"><strong>다형성</strong> (Polymorphsim) // 개념 이해 부족..</h4>
<h4 id="oop의-장점"><strong>OOP의 장점</strong></h4>
<p><code>캡슐화</code> : 재사용성 높인다
<code>추상화</code> : 코드를 단순화 시킨다.
<code>상속</code> : 필요한 코드만 사용한다 &gt;&gt;&gt; 재사용성을 높인다.
<code>다형성</code> : 조건문 사용 대신 객체 특성의 맞게 달리 작성한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 항해일지 D - 28⛵️]]></title>
            <link>https://velog.io/@edan_3000/d28202106</link>
            <guid>https://velog.io/@edan_3000/d28202106</guid>
            <pubDate>Tue, 22 Jun 2021 14:23:34 GMT</pubDate>
            <description><![CDATA[<h4 id="코드스테이츠-full-30기-section-2-28일">코드스테이츠 Full 30기 Section #2 28일</h4>
<h2 id="비동기-고차함수">비동기, 고차함수</h2>
<h2 id="오늘-할-일😊📅">오늘 할 일😊📅</h2>
<ul>
<li>동기 / 비동기 개념 이해</li>
<li>callback / promise / async|await 개념 및 사용</li>
<li>비동기 호출</li>
<li>fs 모듈</li>
<li>API 공부</li>
<li>1일 1github</li>
</ul>
<h2 id="오늘-완료-한-일-☑️💯">오늘 완료 한 일 ☑️💯</h2>
<ul>
<li><input checked="" disabled="" type="checkbox"> 동기 / 비동기 개념 이해</li>
<li><input checked="" disabled="" type="checkbox"> callback / promise / async|await 개념 및 사용</li>
<li><input checked="" disabled="" type="checkbox"> 비동기 호출</li>
</ul>
<h2 id="부족한-것❗️">부족한 것❗️</h2>
<ul>
<li><input disabled="" type="checkbox"> fs 모듈 이해</li>
<li><input disabled="" type="checkbox"> API 공부</li>
</ul>
<h2 id="내일-해야-할-것😎">내일 해야 할 것😎</h2>
<ul>
<li>fs 모듈 이해</li>
<li>API 공부</li>
<li>네트워크 공부</li>
<li>1일 1github</li>
</ul>
<h2 id="done-😃">DONE! 😃</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 항해일지 D - 27⛵️]]></title>
            <link>https://velog.io/@edan_3000/d27202106</link>
            <guid>https://velog.io/@edan_3000/d27202106</guid>
            <pubDate>Tue, 22 Jun 2021 14:23:06 GMT</pubDate>
            <description><![CDATA[<h4 id="코드스테이츠-full-30기-section-2-27일">코드스테이츠 Full 30기 Section #2 27일</h4>
<h2 id="비동기-고차함수">비동기, 고차함수</h2>
<h2 id="오늘-할-일😊📅">오늘 할 일😊📅</h2>
<ul>
<li>forEach, map, filter, reduce 공부</li>
<li>callback 개념 이해</li>
<li>1일 1github</li>
</ul>
<h2 id="오늘-완료-한-일-☑️💯">오늘 완료 한 일 ☑️💯</h2>
<ul>
<li><input checked="" disabled="" type="checkbox"> 고차함수 개념 및 이해</li>
</ul>
<h2 id="부족한-것❗️">부족한 것❗️</h2>
<ul>
<li><input disabled="" type="checkbox"> callback 개념 이해</li>
</ul>
<h2 id="내일-해야-할-것😎">내일 해야 할 것😎</h2>
<ul>
<li>callback 이해</li>
<li>비동기 이해</li>
<li>1일 1github</li>
</ul>
<h2 id="done-😃">DONE! 😃</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 항해일지 D - 26⛵️]]></title>
            <link>https://velog.io/@edan_3000/d26202106</link>
            <guid>https://velog.io/@edan_3000/d26202106</guid>
            <pubDate>Tue, 22 Jun 2021 14:22:06 GMT</pubDate>
            <description><![CDATA[<h4 id="코드스테이츠-full-30기-section-2-26일">코드스테이츠 Full 30기 Section #2 26일</h4>
<h2 id="트리-그래프-dfs-bfs-bst">트리, 그래프, DFS, BFS, BST</h2>
<h2 id="오늘-할-일😊📅">오늘 할 일😊📅</h2>
<ul>
<li>트리 개념 이해 / 트리 구현하기</li>
<li>그래프 개념 이해 / 그래프 구현하기</li>
<li>DFS 개념이해 / DFS 구현하기</li>
<li>BFS 개념이해 / BFS 구현하기</li>
<li>응용문제 풀어보기</li>
<li>인접행렬 이해하기</li>
<li>BST 개념 이해 및 구현</li>
<li>1일 1github</li>
</ul>
<h2 id="오늘-완료-한-일-☑️💯">오늘 완료 한 일 ☑️💯</h2>
<ul>
<li><input checked="" disabled="" type="checkbox"> 트리, 그래프 DFS, BFS, BST 개념이해</li>
<li><input checked="" disabled="" type="checkbox"> 인접행렬 이해</li>
<li><input checked="" disabled="" type="checkbox"> 인접행렬 응용문제 풀기, BFS DFS 알고리즘 문제 풀기 BUT 이해 부족</li>
</ul>
<h2 id="부족한-것❗️">부족한 것❗️</h2>
<ul>
<li><input disabled="" type="checkbox"> 트리, 그래프 DFS, BFS, BST 구현하기</li>
<li><input disabled="" type="checkbox"> 1일 1github</li>
</ul>
<h2 id="내일-해야-할-것😎">내일 해야 할 것😎</h2>
<ul>
<li>Linked-list</li>
<li>Hash Table</li>
<li>부족한 것 구현하기</li>
<li>1일 1github</li>
</ul>
<h2 id="done-😃">DONE! 😃</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 항해일지 D - 25⛵️]]></title>
            <link>https://velog.io/@edan_3000/d25202106</link>
            <guid>https://velog.io/@edan_3000/d25202106</guid>
            <pubDate>Tue, 22 Jun 2021 14:20:51 GMT</pubDate>
            <description><![CDATA[<h4 id="코드스테이츠-full-30기-section-2-25일">코드스테이츠 Full 30기 Section #2 25일</h4>
<h2 id="스택-큐">스택, 큐</h2>
<h2 id="오늘-할-일😊📅">오늘 할 일😊📅</h2>
<ul>
<li>스택 개념 이해</li>
<li>스택 응용문제 풀기</li>
<li>큐 개념 이해</li>
<li>큐 응용문제 풀기 일률문제 / 버퍼 문제</li>
<li>1일 1github</li>
</ul>
<h2 id="오늘-완료-한-일-☑️💯">오늘 완료 한 일 ☑️💯</h2>
<ul>
<li><input checked="" disabled="" type="checkbox"> 스택 개념 이해</li>
<li><input checked="" disabled="" type="checkbox"> 스택 응용문제 풀기</li>
<li><input checked="" disabled="" type="checkbox"> 큐 개념 이해</li>
<li><input checked="" disabled="" type="checkbox"> 큐 응용문제 풀기 일률문제</li>
</ul>
<h2 id="부족한-것❗️">부족한 것❗️</h2>
<ul>
<li><input disabled="" type="checkbox"> 큐 응용문제 풀기 버퍼문제</li>
<li><input disabled="" type="checkbox"> 1일 1github</li>
</ul>
<h2 id="내일-해야-할-것😎">내일 해야 할 것😎</h2>
<ul>
<li>그래프, 트리, DFS BFS, BST 개념 이해</li>
<li>구현</li>
<li>1일 1github</li>
</ul>
<h2 id="done-😃">DONE! 😃</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 항해일지 D - 24⛵️]]></title>
            <link>https://velog.io/@edan_3000/d24202106</link>
            <guid>https://velog.io/@edan_3000/d24202106</guid>
            <pubDate>Tue, 22 Jun 2021 14:19:54 GMT</pubDate>
            <description><![CDATA[<h4 id="코드스테이츠-full-30기-section-2-24일">코드스테이츠 Full 30기 Section #2 24일</h4>
<h2 id="재귀--json">재귀 &gt;&gt;&gt; JSON</h2>
<h2 id="오늘-할-일😊📅">오늘 할 일😊📅</h2>
<ul>
<li>재귀 JSON 개념 이해</li>
<li>재귀 개념 확실히 이해</li>
<li>꼬리재귀 공부 / 하노이의 탑 재귀 공부</li>
<li>재귀 tree 공부</li>
<li>재귀 함수의 메모리 사용량 간의 관계</li>
<li>조합 재귀함수</li>
<li>1일 1github</li>
</ul>
<h2 id="오늘-완료-한-일-☑️💯">오늘 완료 한 일 ☑️💯</h2>
<ul>
<li><input checked="" disabled="" type="checkbox"> 재귀 JSON 개념 이해</li>
<li><input checked="" disabled="" type="checkbox"> 꼬리 재귀 &gt;&gt;&gt; 피보나치 구현</li>
<li><input checked="" disabled="" type="checkbox"> 꼬리재귀와 상관되어있는 재귀 함수의 메모리 사용량 관계 이해</li>
<li><input checked="" disabled="" type="checkbox"> 1일 1github</li>
</ul>
<h2 id="부족한-것❗️">부족한 것❗️</h2>
<ul>
<li><input disabled="" type="checkbox"> 재귀 DFS 개념 이해</li>
<li><input disabled="" type="checkbox"> 하노이탑 재귀</li>
<li><input disabled="" type="checkbox"> 재귀 tree</li>
</ul>
<h2 id="내일-해야-할-것😎">내일 해야 할 것😎</h2>
<ul>
<li>조합 재귀함수</li>
<li>DFS 재귀 개념 이해</li>
<li>DFS 재귀 구현하기</li>
<li>1일 1github</li>
</ul>
<h2 id="done-😃">DONE! 😃</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 항해일지 D - 23⛵️]]></title>
            <link>https://velog.io/@edan_3000/d23202106</link>
            <guid>https://velog.io/@edan_3000/d23202106</guid>
            <pubDate>Tue, 22 Jun 2021 14:17:43 GMT</pubDate>
            <description><![CDATA[<h4 id="코드스테이츠-full-30기-section-2-23일">코드스테이츠 Full 30기 Section #2 23일</h4>
<h2 id="재귀">재귀</h2>
<h2 id="오늘-할-일😊📅">오늘 할 일😊📅</h2>
<ul>
<li>prototype 개념 이해</li>
<li>재귀 개념 이해</li>
<li>1일 1github</li>
</ul>
<h2 id="오늘-완료-한-일-☑️💯">오늘 완료 한 일 ☑️💯</h2>
<ul>
<li><input checked="" disabled="" type="checkbox"> 재귀 15문제 반복 풀기</li>
<li><input checked="" disabled="" type="checkbox"> 재귀 이해</li>
</ul>
<h2 id="부족한-것❗️">부족한 것❗️</h2>
<ul>
<li><input disabled="" type="checkbox"> 구현 문제 부족</li>
<li><input disabled="" type="checkbox"> 반복문 재귀 개념 아직 부족</li>
<li><input disabled="" type="checkbox"> 1일 1github</li>
</ul>
<h2 id="내일-해야-할-것😎">내일 해야 할 것😎</h2>
<ul>
<li>꼬리재귀 공부</li>
<li>재귀 tree 공부</li>
<li>1일 1github</li>
</ul>
<h2 id="done-😃">DONE! 😃</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 항해일지 D - 22⛵️]]></title>
            <link>https://velog.io/@edan_3000/d22202106</link>
            <guid>https://velog.io/@edan_3000/d22202106</guid>
            <pubDate>Tue, 22 Jun 2021 14:16:13 GMT</pubDate>
            <description><![CDATA[<h4 id="코드스테이츠-full-30기-section-2-22일">코드스테이츠 Full 30기 Section #2 22일</h4>
<h2 id="oop">OOP</h2>
<h2 id="오늘-할-일😊📅">오늘 할 일😊📅</h2>
<ul>
<li>Class 개념 이해</li>
<li>constructor 개념 이해</li>
<li>instence 개념 이해</li>
<li>prototype 개념 이해</li>
<li>객체 지향 프로그래밍 개념 이해</li>
<li>1일 1github</li>
</ul>
<h2 id="오늘-완료-한-일-☑️💯">오늘 완료 한 일 ☑️💯</h2>
<ul>
<li><input checked="" disabled="" type="checkbox"> Class 기본 개념 이해</li>
<li><input checked="" disabled="" type="checkbox"> 부모 자식 만드는법 이해</li>
<li><input checked="" disabled="" type="checkbox"> instence 기본 개념 이해</li>
<li><input checked="" disabled="" type="checkbox"> 객체 지향 프로그래밍이 어떤 것인지 틀 이해</li>
<li><input checked="" disabled="" type="checkbox"> 1일 1github</li>
</ul>
<h2 id="부족한-것❗️">부족한 것❗️</h2>
<ul>
<li><input disabled="" type="checkbox"> deep한 부분은 아직 잘 모르겠다.</li>
<li><input disabled="" type="checkbox"> prototype 이해 부족</li>
</ul>
<h2 id="내일-해야-할-것😎">내일 해야 할 것😎</h2>
<ul>
<li>prototype 이해 하기</li>
<li>1일 1github</li>
</ul>
<h2 id="done-😃">DONE! 😃</h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL 항해일지 D - 21⛵️]]></title>
            <link>https://velog.io/@edan_3000/d21202106</link>
            <guid>https://velog.io/@edan_3000/d21202106</guid>
            <pubDate>Tue, 22 Jun 2021 14:14:45 GMT</pubDate>
            <description><![CDATA[<h4 id="코드스테이츠-full-30기-section-1-21일">코드스테이츠 Full 30기 Section #1 21일</h4>
<h2 id="react-3--state--props">React #3 &gt;&gt;&gt; state / props</h2>
<h2 id="오늘-할-일😊📅">오늘 할 일😊📅</h2>
<ul>
<li>react state / props 개념 이해</li>
<li>sate / props react에서 구현하여 기능 만들어 보기</li>
<li>react 이벤트 처리 공부</li>
<li>props 구조분해할당 공부</li>
<li>1일 1github</li>
</ul>
<h2 id="오늘-완료-한-일-☑️💯">오늘 완료 한 일 ☑️💯</h2>
<ul>
<li><input checked="" disabled="" type="checkbox"> state / props 기본 개념 이해</li>
<li><input checked="" disabled="" type="checkbox"> Delete / Add / onClick 이벤트 / onChange 작은 프로젝트 만들기</li>
<li><input checked="" disabled="" type="checkbox"> 1일 1github</li>
</ul>
<h2 id="부족한-것❗️">부족한 것❗️</h2>
<ul>
<li><input disabled="" type="checkbox"> DOM 지식 부족 / AddEventListener</li>
<li><input disabled="" type="checkbox"> 알고리즘 공부</li>
</ul>
<h2 id="내일-해야-할-것😎">내일 해야 할 것😎</h2>
<ul>
<li>react HA 공부</li>
<li>1일 1github</li>
<li>SPA // Router 확실히 이해</li>
</ul>
<h2 id="done-😃">DONE! 😃</h2>
]]></description>
        </item>
    </channel>
</rss>