<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>frozen_land</title>
        <link>https://velog.io/</link>
        <description>:)</description>
        <lastBuildDate>Mon, 19 May 2025 12:40:04 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>frozen_land</title>
            <url>https://velog.velcdn.com/images/frozen_land/profile/3c9879aa-33a2-4ca6-b8f9-73487d0a077b/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. frozen_land. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/frozen_land" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[CRA (Create React App)]]></title>
            <link>https://velog.io/@frozen_land/CRA-Create-React-App</link>
            <guid>https://velog.io/@frozen_land/CRA-Create-React-App</guid>
            <pubDate>Mon, 19 May 2025 12:40:04 GMT</pubDate>
            <description><![CDATA[<p>React의 개발환경 설정을 간단하게 대신 해주는 것 ➡️ 설정 없이도 개발 가능</p>
<h2 id="cpa의-설정">CPA의 설정</h2>
<ul>
<li>Webpack : 모듈 번들러 설정(entry, output, loader, plugin 등)</li>
<li>Babel</li>
<li>ESLint</li>
<li>PostCSS</li>
<li>Fast Refresh</li>
<li>환경 변수</li>
<li>개발 서버</li>
<li>파일 구조</li>
</ul>
<h2 id="단점">단점</h2>
<ul>
<li>추상화된 설정값을 수정하기 번거로움(Webpack, Babel 등)</li>
<li>SSR을 제공하지 않아, 추가적인 설정이 필요 </li>
</ul>
<h2 id="ssrserver-side-rendering">SSR(Server-Side Rendering)</h2>
<p>React 컴포넌트를 서버에서 HTML로 렌더링한 뒤 브라우저에 전달하는 방식
사용자가 서버에 접속하면, 서버에서 이미 렌더링된 HTML을 만들어서 보여준다.</p>
<h3 id="⚙️-cra에서-ssr을-구현하려면-필요한-설정">⚙️ CRA에서 SSR을 구현하려면 필요한 설정</h3>
<ol>
<li>ReacDOM.render() → ReactDOM.hydrate() 변경 → 서버가 HTML 전달했다고 알려주는 역할</li>
<li>서버 생성(예: Express, Node.js 기반 서버) → 사용자에게 보내줘야 함</li>
<li>Webpack 설정을 <strong>eject</strong> 해서 설정을 직접 수정 → 서버 렌더링 가능</li>
<li>라우팅 조정(React Router 설정 주의) → 서버도 경로를 인식하고 페이지를 그려야 함</li>
<li>데이터 불러오기 → 필요한 데이터를 서버에서 미리 가져오기 → 빈 화면 보이지 않도록</li>
</ol>
<p>❗️ Next.js 같은 SSR 프레임워크를 사용하는 것이 더 효율적</p>
<blockquote>
<p><code>npm run eject</code> : CRA 내부에 있는 <strong>추상화된 Webpack, Babel 등 설정 파일들</strong> 을 프로젝트 밖으로 꺼내서 직접 수정 가능하도록 하는 작업</p>
</blockquote>
<h3 id="❗️오류-발생">❗️오류 발생</h3>
<blockquote>
<p><code>npx create-react-app react-app</code> 으로 설치 중 오류 발생하여 설치가 되지 않음
해결 방법</p>
</blockquote>
<ol>
<li>npm 캐시 클리어 <code>npm cache clean --force</code></li>
<li>npx 캐시 디렉토리 삭제 <code>rm -rf ~/.npm/_npx</code>
후 다시 실행 시 Happy Hacking! 뜨면 설치 성공</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[최단 경로(Shortest Path)]]></title>
            <link>https://velog.io/@frozen_land/%EC%B5%9C%EB%8B%A8-%EA%B2%BD%EB%A1%9CShortest-Path</link>
            <guid>https://velog.io/@frozen_land/%EC%B5%9C%EB%8B%A8-%EA%B2%BD%EB%A1%9CShortest-Path</guid>
            <pubDate>Fri, 25 Apr 2025 07:42:27 GMT</pubDate>
            <description><![CDATA[<p>가중 그래프에서 구성하는 간선 간 가중치 합이 최소가 되도록 최단 경로를 찾는 알고리즘</p>
<h2 id="최단-경로-알고리즘-유형">최단 경로 알고리즘 유형</h2>
<ul>
<li>Dijkstra 알고리즘 : 단일 최단 경로 <strong>최소 비용</strong> 산출</li>
<li>A* 알고리즘 : <strong>휴리스틱 방법</strong> 사용한 탐색</li>
<li>Bellman-Ford 알고리즘 : <strong>음수 가중치</strong> 허용한 비용 산출</li>
<li>Floyd-Warshall : <strong>동적 계획법</strong> 기반 고차원 기법</li>
</ul>
<hr>
<h1 id="dijkstra-알고리즘">Dijkstra 알고리즘</h1>
<p>그래프에서 출발점과 도착점 사이의 최단 거리를 구하는 알고리즘</p>
<p>보통 단일 정점 간 최단 경로 산출 시 사용, 도로 교통망이나 OSPF 등의 네트워크 라우팅 프로토콜에 널리 이용
<img src="https://velog.velcdn.com/images/frozen_land/post/bed64edf-8835-4338-ab30-7eb3f58bacec/image.png" alt=""></p>
<h2 id="구현-메서드method">구현 메서드(method)</h2>
<ul>
<li>정점/간선 추가 : <code>ShortestPath.addVertex()</code> , <code>ShortestPath.addEdge()</code></li>
<li>다익스트라 알고리즘 : <code>ShortestPath._extractMin()</code> , <code>ShortestPath.dijkstra()</code></li>
</ul>
<pre><code class="language-jsx">// shortestPath() : edge object 객체 저장을 위한 생성자
// key : vertex
// value : list 형태로 연결된 vertex를 표현하여 edge 연결

function ShortestPath() {
  this.edges = {};
}

// addVertex() : 정점 추가(간성 비용 표시를 위해 object 형태로 저장)
ShortestPath.prototype.addVertex = function (vertex) {
  this.edges[vertex] = {};
};

// addEdge : 간선 추가
ShortestPath.prototype.addEdge = function (srcVertex, dstVertex, weight) {
  this.edges[srcVertex][dstVertex] = weight;
};

// _extractMin() : 최단 거리 노드 탐색
ShortestPath.prototype._extractMin = function (queue, dist) {
  let minDistance = Number.POSITIVE_INFINITY;
  let minVertex = null;

  for (let vertex in queue) {
    if (dist[vertex] &lt;= minDistance) {
      minDistance = dist[vertex];
      minVertex = vertex;
    }
  }
  return minVertex;
};

// dijkstra() : 다익스트라 최단 경로 탐색
ShortestPath.prototype.dijkstra = function (start) {
  let queue = {};
  let dist = {};

  for (let vertex in this.edges) {
    dist[vertex] = Number.POSITIVE_INFINITY;
    queue[vertex] = this.edges[vertex]; // edge에 연결되어 있는 간선 정보까지 넣어준다
  }

  dist[start] = 0;
  while (Object.keys(queue).length != 0) {
    let u = this._extractMin(queue, dist);
    delete queue[u];
    for (let neighbor in this.edges[u]) {
      let alt = dist[u] + this.edges[u][neighbor];
      if (alt &lt; dist[neighbor]) dist[neighbor] = alt;
    }
  }

  for (let vertex in this.edges) {
    if (dist[vertex] === Number.POSITIVE_INFINITY) delete dist[vertex];
  }

  return dist;
};

let path = new ShortestPath();
path.addVertex(&quot;A&quot;);
path.addVertex(&quot;B&quot;);
path.addVertex(&quot;C&quot;);
path.addVertex(&quot;D&quot;);
path.addVertex(&quot;E&quot;);

path.addEdge(&quot;A&quot;, &quot;B&quot;, 10);
path.addEdge(&quot;A&quot;, &quot;C&quot;, 3);
path.addEdge(&quot;B&quot;, &quot;C&quot;, 1);
path.addEdge(&quot;B&quot;, &quot;D&quot;, 2);
path.addEdge(&quot;C&quot;, &quot;B&quot;, 4);
path.addEdge(&quot;C&quot;, &quot;D&quot;, 8);
path.addEdge(&quot;C&quot;, &quot;E&quot;, 2);
path.addEdge(&quot;D&quot;, &quot;E&quot;, 7);
path.addEdge(&quot;E&quot;, &quot;D&quot;, 9);

console.log(path);
console.log(path.dijkstra(&quot;A&quot;));
console.log(path.dijkstra(&quot;B&quot;));
console.log(path.dijkstra(&quot;C&quot;));

-----------------------------------------------------------
OUTPUT
ShortestPath {
  edges: {
    A: { B: 10, C: 3 },
    B: { C: 1, D: 2 },
    C: { B: 4, D: 8, E: 2 },
    D: { E: 7 },
    E: { D: 9 }
  }
}
{ A: 0, B: 7, C: 3, D: 9, E: 5 }
{ B: 0, C: 1, D: 2, E: 3 }
{ B: 4, C: 0, D: 6, E: 2 }</code></pre>
<h1 id="floyd-warshall-알고리즘">Floyd-Warshall 알고리즘</h1>
<p><strong>동적 계획법</strong>을 활용해, 그래프에서 <strong>가능한 모든 정점 쌍에 대해 최단 거리</strong>를 구하는 알고리즘</p>
<p>음의 가중치가 있어도 사용 가능하며, 만은 수의 간선으로 이루어져 있는 밀집 그래프(Dense Graph)에 사용 적합</p>
<ul>
<li>2차원 Object 형태로 만든다</li>
</ul>
<h2 id="구현-메서드method-1">구현 메서드(method)</h2>
<ul>
<li>정점/간선 추가 : <code>ShortestPath.addVertex()</code> , <code>ShortestPath.addEdge()</code></li>
<li>다익스트라 알고리즘 : <code>ShortestPath.floydWarshall()</code></li>
</ul>
<pre><code class="language-jsx">// shortestPath() : edge object 객체 저장을 위한 생성자
// key : vertex
// value : list 형태로 연결된 vertex를 표현하여 edge 연결

function ShortestPath() {
  this.edges = {};
}

// addVertex() : 정점 추가(간성 비용 표시를 위해 object 형태로 저장)
ShortestPath.prototype.addVertex = function (vertex) {
  this.edges[vertex] = {};
};

// addEdge : 간선 추가
ShortestPath.prototype.addEdge = function (srcVertex, dstVertex, weight) {
  this.edges[srcVertex][dstVertex] = weight;
};

// _extractMin() : 최단 거리 노드 탐색
ShortestPath.prototype._extractMin = function (queue, dist) {
  let minDistance = Number.POSITIVE_INFINITY;
  let minVertex = null;

  for (let vertex in queue) {
    if (dist[vertex] &lt;= minDistance) {
      minDistance = dist[vertex];
      minVertex = vertex;
    }
  }
  return minVertex;
};

// floydWarshell() : 플로이드-워셜 최단 경로 탐색
ShortestPath.prototype.floydWarshall = function () {
  let dist = {};
  for (let srcVertex in this.edges) {
    dist[srcVertex] = {};
    for (let dstVertex in this.edges) {
      if (srcVertex === dstVertex) dist[srcVertex][dstVertex] = 0;
      else dist[srcVertex][dstVertex] = Number.POSITIVE_INFINITY;
    }
  }

  for (let srcVertex in this.edges) {
    for (let dstVertex in this.edges[srcVertex]) {
      dist[srcVertex][dstVertex] = this.edges[srcVertex][dstVertex];
    }
  }

  // 업데이트 되는 부분
  for (let minVertex in this.edges) {
    for (let srcVertex in this.edges) {
      for (let dstVertex in this.edges) {
        dist[srcVertex][dstVertex] = Math.min(
          dist[srcVertex][dstVertex],
          dist[srcVertex][minVertex] + dist[minVertex][dstVertex]
        );
      }
    }
  }

  for (let srcVertex in this.edges) {
    for (let dstVertex in this.edges) {
      if (dist[srcVertex][dstVertex] === Number.POSITIVE_INFINITY)
        delete dist[srcVertex][dstVertex];
    }
  }

  return dist;
};

let path = new ShortestPath();
path.addVertex(&quot;A&quot;);
path.addVertex(&quot;B&quot;);
path.addVertex(&quot;C&quot;);
path.addVertex(&quot;D&quot;);
path.addVertex(&quot;E&quot;);

path.addEdge(&quot;A&quot;, &quot;B&quot;, 10);
path.addEdge(&quot;A&quot;, &quot;C&quot;, 3);
path.addEdge(&quot;B&quot;, &quot;C&quot;, 1);
path.addEdge(&quot;B&quot;, &quot;D&quot;, 2);
path.addEdge(&quot;C&quot;, &quot;B&quot;, 4);
path.addEdge(&quot;C&quot;, &quot;D&quot;, 8);
path.addEdge(&quot;C&quot;, &quot;E&quot;, 2);
path.addEdge(&quot;D&quot;, &quot;E&quot;, 7);
path.addEdge(&quot;E&quot;, &quot;D&quot;, 9);

console.log(path);
console.log(path.floydWarshall());

-----------------------------------------------------------
OUTPUT
ShortestPath {
  edges: {
    A: { B: 10, C: 3 },
    B: { C: 1, D: 2 },
    C: { B: 4, D: 8, E: 2 },
    D: { E: 7 },
    E: { D: 9 }
  }
}
{
  A: { A: 0, B: 7, C: 3, D: 9, E: 5 },
  B: { B: 0, C: 1, D: 2, E: 3 },
  C: { B: 4, C: 0, D: 6, E: 2 },
  D: { D: 0, E: 7 },
  E: { D: 9, E: 0 }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] 힙(Heap)]]></title>
            <link>https://velog.io/@frozen_land/%ED%9E%99Heap</link>
            <guid>https://velog.io/@frozen_land/%ED%9E%99Heap</guid>
            <pubDate>Fri, 25 Apr 2025 00:40:33 GMT</pubDate>
            <description><![CDATA[<p>최댓값 혹은 최솟값을 빠르게 찾기 위해 완전이진트리 형태로 연산을 수행하는 자료구조</p>
<h2 id="힙-대표-속성">힙 대표 속성</h2>
<ul>
<li>정렬 : 각 노드의 값은 자식 노드가 가진 값보다 작거나 혹은 큰 순서대로 정렬</li>
<li>형태 : 트리의 형태는 완전이진트리(complete binary tree) 모양</li>
</ul>
<h2 id="힙-종류">힙 종류</h2>
<ul>
<li>최소 힙(Min Heap) : 부모 노드의 값이 자식 노드의 값보다, 작거나 같은 완전 이진 트리</li>
<li>최대 힙(Max Heap) : 부모 노드의 값이 자식 노드의 값보다, 크거나 같은 완전 이진 트리
<img src="https://velog.velcdn.com/images/frozen_land/post/c88e4a00-c4ed-45ab-a345-5f82f3ea6764/image.png" alt=""></li>
</ul>
<h2 id="힙-구현">힙 구현</h2>
<ul>
<li>완전 이진 트리 성질을 만족하기 때문에 1차원 배열로 표현 가능</li>
<li>현재 노드 : N, 부모 노드 : (N-1)/2, 왼쪽 자식 노드 : (N<em>2)+1, 오른쪽 자식 노드 : (N</em>2)+2</li>
</ul>
<h2 id="구현-메서드method">구현 메서드(method)</h2>
<ul>
<li>노드 위치 계산 : <code>Heap.parentIndex()</code>, <code>Heap.leftChildIndex()</code>, <code>Heap.rightChildIndex()</code></li>
<li>노드 값 확인 : <code>Heap.parent()</code>, <code>Heap.leftChild()</code>, <code>Heap.rightChild()</code></li>
<li>노드 추가/삭제(추출) : <code>Heap.insert()</code>, <code>Heap.bubbleUp()</code>, <code>Heap.extract()</code>, <code>Heap.bubbleDown()</code></li>
</ul>
<h3 id="최소힙">최소힙</h3>
<pre><code class="language-jsx">// 최소 힙(MinHeap)
// Heap() : 배열 내 요소를 저장하기 위한 생성자
function Heap() {
  this.items = [];
}

// swap() : 배열 내 두 요소 위치 변경
Heap.prototype.swap = function (index1, index2) {
  let tmp = this.items[index1];
  this.items[index1] = this.items[index2];
  this.items[index2] = tmp;
};

// parentIndex() : 부모 노드의 위치 반환
Heap.prototype.parentIndex = function (index) {
  return Math.floor((index - 1) / 2);
};

// leftChildIndex() : 왼쪽 자식 노드의 위치 반환
Heap.prototype.leftChildIndex = function (index) {
  return index * 2 + 1;
};

// rightChildIndex() : 오른쪽 자식 노드의 위치 반환
Heap.prototype.rightChildIndex = function (index) {
  return index * 2 + 2;
};

// parent() : 부모 노드의 요소값 반환
Heap.prototype.parent = function (index) {
  return this.items[this.parentIndex(index)];
};

// leftChild() : 왼쪽 자식 노드의 요소 값 반환
Heap.prototype.leftChild = function (index) {
  return this.items[this.leftChildIndex(index)];
};

// rightChild() : 오른족 자식 노드의 요소 값 반환
Heap.prototype.rightChild = function (index) {
  return this.items[this.rightChildIndex(index)];
};

// peak() : 현재 정렬된 최소/최대 요소값 반환
Heap.prototype.peak = function () {
  return this.items[0];
};

// size() : 현재 배열 내 크기 반환
Heap.prototype.size = function () {
  return this.items.length;
};

// insert() : 신규 노드 추가
Heap.prototype.insert = function (item) {
  this.items[this.size()] = item;
  this.bubbleUp();
};

// bubbleUp() : 추가된 노드 위치 정렬
Heap.prototype.bubbleUp = function () {
  let index = this.size() - 1;
  // 부모 노드와 비교하면서 정렬
  // 부모가 있는지부터 확인
  while (this.parent(index) &amp;&amp; this.parent(index) &gt; this.items[index]) {
    this.swap(this.parentIndex(index), index);
    index = this.parentIndex(index);
  }
};

// extract() : root 노드 반환 및 삭제
Heap.prototype.extract = function () {
  let item = this.items[0];
  this.items[0] = this.items[this.size() - 1];
  this.items.pop(); // 배열의 마지막 요소를 없애 준다.
  this.bubbleDown();
  return item;
};

// bubbleDown() : 대체된 root 노드 위치 정렬 -&gt; 위에서 부터 수행(root 부터) -&gt; 내려가면서 왼쪽 오른쪽 노드 둘다 확인
Heap.prototype.bubbleDown = function () {
  let index = 0;
  while (
    this.leftChild(index) &amp;&amp;
    (this.leftChild(index) &lt; this.items[index] ||
      this.rightChild(index) &lt; this.items[index])
  ) {
    let childIndex = this.leftChildIndex(index);
    if (
      this.rightChild(index) &amp;&amp;
      this.rightChild(index) &lt; this.items[childIndex]
    ) {
      childIndex = this.rightChildIndex(index);
    }
    this.swap(childIndex, index);
    index = childIndex;
  }
};

let minHeap = new Heap();
minHeap.insert(90);
minHeap.insert(15);
minHeap.insert(10);
minHeap.insert(7);
minHeap.insert(12);
minHeap.insert(2);
minHeap.insert(8);
minHeap.insert(3);
// console.log(minHeap);
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
// console.log(minHeap);

----------------------------------------------------------
OUTPUT
2
3
7
8
10
12
15
90</code></pre>
<h3 id="최대값">최대값</h3>
<p>최소값 <code>bubbleUp()</code>, <code>bubbleDown()</code> 코드에 있는 조건문의 부등호를 반대로 바꾸면 된다</p>
<pre><code class="language-jsx">// 최대 힙(MaxHeap)
// Heap() : 배열 내 요소를 저장하기 위한 생성자
function Heap() {
  this.items = [];
}

// swap() : 배열 내 두 요소 위치 변경
Heap.prototype.swap = function (index1, index2) {
  let tmp = this.items[index1];
  this.items[index1] = this.items[index2];
  this.items[index2] = tmp;
};

// parentIndex() : 부모 노드의 위치 반환
Heap.prototype.parentIndex = function (index) {
  return Math.floor((index - 1) / 2);
};

// leftChildIndex() : 왼쪽 자식 노드의 위치 반환
Heap.prototype.leftChildIndex = function (index) {
  return index * 2 + 1;
};

// rightChildIndex() : 오른쪽 자식 노드의 위치 반환
Heap.prototype.rightChildIndex = function (index) {
  return index * 2 + 2;
};

// parent() : 부모 노드의 요소값 반환
Heap.prototype.parent = function (index) {
  return this.items[this.parentIndex(index)];
};

// leftChild() : 왼쪽 자식 노드의 요소 값 반환
Heap.prototype.leftChild = function (index) {
  return this.items[this.leftChildIndex(index)];
};

// rightChild() : 오른족 자식 노드의 요소 값 반환
Heap.prototype.rightChild = function (index) {
  return this.items[this.rightChildIndex(index)];
};

// peak() : 현재 정렬된 최소/최대 요소값 반환
Heap.prototype.peak = function () {
  return this.items[0];
};

// size() : 현재 배열 내 크기 반환
Heap.prototype.size = function () {
  return this.items.length;
};

// insert() : 신규 노드 추가
Heap.prototype.insert = function (item) {
  this.items[this.size()] = item;
  this.bubbleUp();
};

// bubbleUp() : 추가된 노드 위치 정렬
Heap.prototype.bubbleUp = function () {
  let index = this.size() - 1;
  // 부모 노드와 비교하면서 정렬
  // 부모가 있는지부터 확인
  while (this.parent(index) &amp;&amp; this.parent(index) &lt; this.items[index]) {
    this.swap(this.parentIndex(index), index);
    index = this.parentIndex(index);
  }
};

// extract() : root 노드 반환 및 삭제
Heap.prototype.extract = function () {
  let item = this.items[0];
  this.items[0] = this.items[this.size() - 1];
  this.items.pop(); // 배열의 마지막 요소를 없애 준다.
  this.bubbleDown();
  return item;
};

// bubbleDown() : 대체된 root 노드 위치 정렬 -&gt; 위에서 부터 수행(root 부터) -&gt; 내려가면서 왼쪽 오른쪽 노드 둘다 확인
Heap.prototype.bubbleDown = function () {
  let index = 0;
  while (
    this.leftChild(index) &amp;&amp;
    (this.leftChild(index) &gt; this.items[index] ||
      this.rightChild(index) &gt; this.items[index])
  ) {
    let childIndex = this.leftChildIndex(index);
    if (
      this.rightChild(index) &amp;&amp;
      this.rightChild(index) &gt; this.items[childIndex]
    ) {
      childIndex = this.rightChildIndex(index);
    }
    this.swap(childIndex, index);
    index = childIndex;
  }
};

let minHeap = new Heap();
minHeap.insert(90);
minHeap.insert(15);
minHeap.insert(10);
minHeap.insert(7);
minHeap.insert(12);
minHeap.insert(2);
minHeap.insert(8);
minHeap.insert(3);
// console.log(minHeap);
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
console.log(minHeap.extract());
// console.log(minHeap);

----------------------------------------------------------
OUTPUT
90
15
12
10
8
7
3
2</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자료구조] DFS/BFS]]></title>
            <link>https://velog.io/@frozen_land/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-DFSBFS</link>
            <guid>https://velog.io/@frozen_land/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-DFSBFS</guid>
            <pubDate>Thu, 24 Apr 2025 14:28:58 GMT</pubDate>
            <description><![CDATA[<h1 id="dfsdepth-first-search--깊이-우선-탐색">DFS(Depth First Search) : 깊이 우선 탐색</h1>
<p>트리나 그래프 등에서 하나의 노드를 최대한 <strong>깊게</strong> 들어가면서 해를 찾는 탐색 기법
<img src="https://velog.velcdn.com/images/frozen_land/post/2322bdbf-544f-4acb-812b-5b3697cfdf1a/image.png" alt=""></p>
<h2 id="장점">장점</h2>
<p>인접한 후보 노드만 기억하면 되므로 적은 기억공간 소요</p>
<p>노트가 깊은 단계에 있을 경우 빠르게 정답 산출</p>
<h2 id="단점">단점</h2>
<p>선택한 경로가 답이 아닐 경우 불필요한 탐색 가능</p>
<p>최단 경로 구할 시 찾은 해가 정답이 아닐 경우 발생 ⇒ BFS</p>
<h2 id="구현-메서드method">구현 메서드(method)</h2>
<ul>
<li>재귀를 이용한 탐색 : <code>Graph.dfsRecursiveVisit()</code></li>
</ul>
<pre><code>function Graph() {
  this.edge = {};
  this.visited = {};
}

// addVertex() : 정점(vertex) 추가
Graph.prototype.addVertex = function (v) {
  this.edge[v] = [];
  this.visited[v] = false;
};

// addEdge() : 간선(edge) 추가
Graph.prototype.addEdge = function (v1, v2) {
  this.edge[v1].push(v2); // v1 -&gt; v2
};

// print() : 현재 Graph에 연결 상태 출력
Graph.prototype.print = function () {
  for (let vertex in this.edge) {
    let neighbors = this.edge[vertex];
    if (neighbors.length === 0) continue;
    process.stdout.write(`${vertex} -&gt; `);

    for (let j = 0; j &lt; neighbors.length; j++) {
      process.stdout.write(`${neighbors[j]} `);
    }
    console.log(&quot;&quot;);
  }
};

//dfs() : DFS 탐색
Graph.prototype.dfs = function (startVertex) {
  this._dfsRecursiveVisit(startVertex);
};

//_dfsRecursiveVisit() : 재귀를 이용한 DFS 탐색
Graph.prototype._dfsRecursiveVisit = function (vertex) {
  // 1. 종료 조건

  if (this.visited[vertex]) {
    return;
  }

  // 2. 재귀 호출을 하면서 수행해야할 코드
  this.visited[vertex] = true;
  console.log(`visit &quot;${vertex}&quot;`);

  let neighbors = this.edge[vertex];
  for (let i = 0; i &lt; neighbors.length; i++) {
    this._dfsRecursiveVisit(neighbors[i]);
  }
};

let graph = new Graph();
let vertices = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;, &quot;G&quot;, &quot;H&quot;, &quot;I&quot;];
for (let i = 0; i &lt; vertices.length; i++) {
  graph.addVertex(vertices[i]);
}

graph.addEdge(&quot;A&quot;, &quot;B&quot;);
graph.addEdge(&quot;A&quot;, &quot;C&quot;);
graph.addEdge(&quot;A&quot;, &quot;D&quot;);
graph.addEdge(&quot;C&quot;, &quot;G&quot;);
graph.addEdge(&quot;D&quot;, &quot;G&quot;);
graph.addEdge(&quot;D&quot;, &quot;H&quot;);
graph.addEdge(&quot;B&quot;, &quot;E&quot;);
graph.addEdge(&quot;B&quot;, &quot;F&quot;);
graph.addEdge(&quot;E&quot;, &quot;I&quot;);
graph.print();
console.log(&quot;&quot;);

graph.dfs(&quot;A&quot;);

------------------------------------------------------------------------
OUTPUT
A -&gt; B C D 
B -&gt; E F 
C -&gt; G 
D -&gt; G H 
E -&gt; I 

visit &quot;A&quot;
visit &quot;B&quot;
visit &quot;E&quot;
visit &quot;I&quot;
visit &quot;F&quot;
visit &quot;C&quot;
visit &quot;G&quot;
visit &quot;D&quot;
visit &quot;H&quot;</code></pre><ul>
<li>스택을 이용한 탐색 : <code>Graph.dfsLoopVisit()</code></li>
</ul>
<pre><code class="language-jsx">import { Stack } from &quot;./stack3.mjs&quot;;
function Graph() {
  this.edge = {};
  this.visited = {};
}

// addVertex() : 정점(vertex) 추가
Graph.prototype.addVertex = function (v) {
  this.edge[v] = [];
  this.visited[v] = false;
};

// addEdge() : 간선(edge) 추가
Graph.prototype.addEdge = function (v1, v2) {
  this.edge[v1].push(v2); // v1 -&gt; v2
};

// print() : 현재 Graph에 연결 상태 출력
Graph.prototype.print = function () {
  for (let vertex in this.edge) {
    let neighbors = this.edge[vertex];
    if (neighbors.length === 0) continue;
    process.stdout.write(`${vertex} -&gt; `);

    for (let j = 0; j &lt; neighbors.length; j++) {
      process.stdout.write(`${neighbors[j]} `);
    }
    console.log(&quot;&quot;);
  }
};

//dfs() : DFS 탐색
Graph.prototype.dfs = function (startVertex) {
  this._dfsLoopVisit(startVertex);
};

//_dfsLoopVisit() : 스택를 이용한 DFS 탐색
Graph.prototype._dfsLoopVisit = function (vertex) {
  let stack = new Stack();
  stack.push(vertex);

  // 스택이 빌때까지 반복
  while (!stack.isEmpty()) {
    let vertex = stack.pop();
    // 방문했는지 확인
    if (this.visited[vertex]) {
      continue;
    }
    this.visited[vertex] = true;
    console.log(`visit &quot;${vertex}&quot;`);

    let neighbors = this.edge[vertex];
    for (let i = neighbors.length - 1; i &gt;= 0; i--) {
      stack.push(neighbors[i]);
    }
  }
};

let graph = new Graph();
let vertices = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;, &quot;G&quot;, &quot;H&quot;, &quot;I&quot;];
for (let i = 0; i &lt; vertices.length; i++) {
  graph.addVertex(vertices[i]);
}

graph.addEdge(&quot;A&quot;, &quot;B&quot;);
graph.addEdge(&quot;A&quot;, &quot;C&quot;);
graph.addEdge(&quot;A&quot;, &quot;D&quot;);
graph.addEdge(&quot;C&quot;, &quot;G&quot;);
graph.addEdge(&quot;D&quot;, &quot;G&quot;);
graph.addEdge(&quot;D&quot;, &quot;H&quot;);
graph.addEdge(&quot;B&quot;, &quot;E&quot;);
graph.addEdge(&quot;B&quot;, &quot;F&quot;);
graph.addEdge(&quot;E&quot;, &quot;I&quot;);
graph.print();
console.log(&quot;&quot;);

graph.dfs(&quot;A&quot;);

------------------------------------------------------------------------
OUTPUT
A -&gt; B C D 
B -&gt; E F 
C -&gt; G 
D -&gt; G H 
E -&gt; I 

visit &quot;A&quot;
visit &quot;B&quot;
visit &quot;E&quot;
visit &quot;I&quot;
visit &quot;F&quot;
visit &quot;C&quot;
visit &quot;G&quot;
visit &quot;D&quot;
visit &quot;H&quot;</code></pre>
<hr>
<h1 id="bfsbreadth-first-search--너비-우선-탐색">BFS(Breadth First Search) : 너비 우선 탐색</h1>
<p>트리나 그래프 등에서 <strong>인접한 노드를 우선 방문</strong>하면서 <strong>넓게</strong> 움직이며 해를 찾는 탐색 기법</p>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/870ee440-ae29-4454-aa82-c9fe82c74cd3/image.png" alt=""></p>
<h2 id="장점-1">장점</h2>
<ul>
<li>최단 경로 탐색에서 구한 해가 정답임을 보장</li>
</ul>
<h2 id="단점-1">단점</h2>
<ul>
<li>경로가 매우 길어질 경우, 탐색 범위가 증가하면서 DFS보다 많은 기억 공간이 필요</li>
</ul>
<h2 id="구현-메서드method-1">구현 메서드(method)</h2>
<ul>
<li>큐를 이용한 탐색 : <code>Graph.bfs()</code> , <code>Graph._bfsLoopVisit()</code></li>
</ul>
<pre><code>import { Queue } from &quot;./queue3.mjs&quot;;

function Graph() {
  this.edge = {};
  this.visited = {};
}

// addVertex() : 정점(vertex) 추가
Graph.prototype.addVertex = function (v) {
  this.edge[v] = [];
  this.visited[v] = false;
};

// addEdge() : 간선(edge) 추가
Graph.prototype.addEdge = function (v1, v2) {
  this.edge[v1].push(v2); // v1 -&gt; v2
};

// print() : 현재 Graph에 연결 상태 출력
Graph.prototype.print = function () {
  for (let vertex in this.edge) {
    let neighbors = this.edge[vertex];
    if (neighbors.length === 0) continue;
    process.stdout.write(`${vertex} -&gt; `);

    for (let j = 0; j &lt; neighbors.length; j++) {
      process.stdout.write(`${neighbors[j]} `);
    }
    console.log(&quot;&quot;);
  }
};

// bfs() : BFS 탐색
Graph.prototype.bfs = function (startVertex) {
  this._bfsLoopVisit(startVertex);
};

// _bfsLoopVisit() : 큐를 이용한 BFS 탐색
Graph.prototype._bfsLoopVisit = function (vertex) {
  let queue = new Queue();
  queue.enqueue(vertex);

  while (!queue.isEmpty()) {
    let vertex = queue.dequeue();
    if (this.visited[vertex]) {
      continue;
    }

    this.visited[vertex] = true;
    console.log(`visit &quot;${vertex}&quot;`);

    let neighbors = this.edge[vertex];
    for (let i = 0; i &lt; neighbors.length; i++) {
      queue.enqueue(neighbors[i]);
    }
  }
};

let graph = new Graph();
let vertices = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;, &quot;G&quot;, &quot;H&quot;, &quot;I&quot;];
for (let i = 0; i &lt; vertices.length; i++) {
  graph.addVertex(vertices[i]);
}

graph.addEdge(&quot;A&quot;, &quot;B&quot;);
graph.addEdge(&quot;A&quot;, &quot;C&quot;);
graph.addEdge(&quot;A&quot;, &quot;D&quot;);
graph.addEdge(&quot;C&quot;, &quot;G&quot;);
graph.addEdge(&quot;D&quot;, &quot;G&quot;);
graph.addEdge(&quot;D&quot;, &quot;H&quot;);
graph.addEdge(&quot;B&quot;, &quot;E&quot;);
graph.addEdge(&quot;B&quot;, &quot;F&quot;);
graph.addEdge(&quot;E&quot;, &quot;I&quot;);
graph.print();
console.log(&quot;&quot;);

graph.bfs(&quot;A&quot;);

------------------------------------------------------------------------
OUTPUT
A -&gt; B C D 
B -&gt; E F 
C -&gt; G 
D -&gt; G H 
E -&gt; I 

visit &quot;A&quot;
visit &quot;B&quot;
visit &quot;C&quot;
visit &quot;D&quot;
visit &quot;E&quot;
visit &quot;F&quot;
visit &quot;G&quot;
visit &quot;H&quot;
visit &quot;I&quot;</code></pre><ul>
<li>최단 경로 탐색 : <code>Graph.shortestPath()</code> , <code>Graph._bfsShortestPath()</code> , <code>Graph._from_to_path()</code></li>
</ul>
<pre><code class="language-jsx">import { Queue } from &quot;./queue3.mjs&quot;;
import { Stack } from &quot;./stack3.mjs&quot;;

function Graph() {
  this.edge = {};
  this.visited = {};
}

// addVertex() : 정점(vertex) 추가
Graph.prototype.addVertex = function (v) {
  this.edge[v] = [];
  this.visited[v] = false;
};

// addEdge() : 간선(edge) 추가
Graph.prototype.addEdge = function (v1, v2) {
  this.edge[v1].push(v2); // v1 -&gt; v2
};

// print() : 현재 Graph에 연결 상태 출력
Graph.prototype.print = function () {
  for (let vertex in this.edge) {
    let neighbors = this.edge[vertex];
    if (neighbors.length === 0) continue;
    process.stdout.write(`${vertex} -&gt; `);

    for (let j = 0; j &lt; neighbors.length; j++) {
      process.stdout.write(`${neighbors[j]} `);
    }
    console.log(&quot;&quot;);
  }
};

// bfs() : BFS 탐색
Graph.prototype.bfs = function (startVertex) {
  this._bfsLoopVisit(startVertex);
};

// _bfsLoopVisit() : 큐를 이용한 BFS 탐색
Graph.prototype._bfsLoopVisit = function (vertex) {
  let queue = new Queue();
  queue.enqueue(vertex);

  while (!queue.isEmpty()) {
    let vertex = queue.dequeue();
    if (this.visited[vertex]) {
      continue;
    }

    this.visited[vertex] = true;
    console.log(`visit &quot;${vertex}&quot;`);

    let neighbors = this.edge[vertex];
    for (let i = 0; i &lt; neighbors.length; i++) {
      queue.enqueue(neighbors[i]);
    }
  }
};

// _bfsShortestPath() : 다른 정점 간 최단 경로 비용 산출
Graph.prototype._bfsShortestPath = function (vertex) {
  let queue = new Queue();
  queue.enqueue(vertex);

  let distance = {};
  let pre_visit = {};
  for (let vertex in this.edge) {
    distance[vertex] = 0;
    pre_visit[vertex] = null;
  }

  while (!queue.isEmpty()) {
    let vertex = queue.dequeue();

    this.visited[vertex] = true;
    console.log(`visit &quot;${vertex}&quot;`);

    let neighbors = this.edge[vertex];
    for (let i = 0; i &lt; neighbors.length; i++) {
      if (!this.visited[neighbors[i]]) {
        distance[neighbors[i]] = distance[vertex] + 1;
        pre_visit[neighbors[i]] = vertex;
        queue.enqueue(neighbors[i]);
      }
    }
  }

  return { distance, pre_visit };
};

// _from_to_path() : from 정점에서 to 정점으로 최단 경로 출력
Graph.prototype._from_to_path = function (pre_visit, from, to) {
  let stack = new Stack();

  for (let v = to; v !== from; v = pre_visit[v]) {
    stack.push(v);
  }
  stack.push(from);

  while (!stack.isEmpty()) {
    let v = stack.pop();
    process.stdout.write(`${v} =&gt; `);
  }
  console.log(&quot;end&quot;);
};

// shortestPath() : 다른 정점 간 최단 경로 탐색
Graph.prototype.shortestPath = function (startVertex) {
  let result = this._bfsShortestPath(startVertex);

  console.log(result.distance);
  console.log(result.pre_visit);

  for (let vertex in this.edge) {
    if (vertex === startVertex) continue;
    this._from_to_path(result.pre_visit, startVertex, vertex);
  }
};

let graph = new Graph();
let vertices = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;, &quot;D&quot;, &quot;E&quot;, &quot;F&quot;, &quot;G&quot;, &quot;H&quot;, &quot;I&quot;];
for (let i = 0; i &lt; vertices.length; i++) {
  graph.addVertex(vertices[i]);
}

graph.addEdge(&quot;A&quot;, &quot;B&quot;);
graph.addEdge(&quot;A&quot;, &quot;C&quot;);
graph.addEdge(&quot;A&quot;, &quot;D&quot;);
graph.addEdge(&quot;C&quot;, &quot;G&quot;);
graph.addEdge(&quot;D&quot;, &quot;G&quot;);
graph.addEdge(&quot;D&quot;, &quot;H&quot;);
graph.addEdge(&quot;B&quot;, &quot;E&quot;);
graph.addEdge(&quot;B&quot;, &quot;F&quot;);
graph.addEdge(&quot;E&quot;, &quot;I&quot;);
graph.print();
console.log(&quot;&quot;);

graph.shortestPath(&quot;A&quot;);

------------------------------------------------------------------------
OUTPUT
A -&gt; B C D 
B -&gt; E F 
C -&gt; G 
D -&gt; G H 
E -&gt; I 

visit &quot;A&quot;
visit &quot;B&quot;
visit &quot;C&quot;
visit &quot;D&quot;
visit &quot;E&quot;
visit &quot;F&quot;
visit &quot;G&quot;
visit &quot;G&quot;
visit &quot;H&quot;
visit &quot;I&quot;
{ A: 0, B: 1, C: 1, D: 1, E: 2, F: 2, G: 2, H: 2, I: 3 }
{
  A: null,
  B: &#39;A&#39;,
  C: &#39;A&#39;,
  D: &#39;A&#39;,
  E: &#39;B&#39;,
  F: &#39;B&#39;,
  G: &#39;D&#39;,
  H: &#39;D&#39;,
  I: &#39;E&#39;
}
A =&gt; B =&gt; end
A =&gt; C =&gt; end
A =&gt; D =&gt; end
A =&gt; B =&gt; E =&gt; end
A =&gt; B =&gt; F =&gt; end
A =&gt; D =&gt; G =&gt; end
A =&gt; D =&gt; H =&gt; end
A =&gt; B =&gt; E =&gt; I =&gt; end</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[트리(Tree)]]></title>
            <link>https://velog.io/@frozen_land/%ED%8A%B8%EB%A6%ACTree</link>
            <guid>https://velog.io/@frozen_land/%ED%8A%B8%EB%A6%ACTree</guid>
            <pubDate>Wed, 23 Apr 2025 07:08:25 GMT</pubDate>
            <description><![CDATA[<p>그래프의 일종으로 <strong>두 노드 사이의 하나의 간선만 연결</strong>되어 있는 <strong>최소 연결과 계층 형태</strong>의 비선형 자료 구조
<img src="https://velog.velcdn.com/images/frozen_land/post/3f58f5ba-6ed8-4c8a-be24-b455e2180b46/image.png" alt=""></p>
<h2 id="트리의-구조-및-용어">트리의 구조 및 용어</h2>
<ul>
<li><p>노드 (node) : 하나 이상의 값을 갖는 객체 단위</p>
</li>
<li><p>간선(Edge) : 두 노드를 연결하는 선</p>
</li>
<li><p>루트 노드(Root Node) : 부모가 없는 최상위 노트 → 시작 위치</p>
</li>
<li><p>단말 노드(Leaf Node) : 자식이 없는 노드</p>
</li>
<li><p>부모 노트(Parent node) : 특정 Sub-Tree 내에서 상위 노드</p>
</li>
<li><p>자식 노트(Child node) : 특정 Sub-Tree 내에서의 하위 노트</p>
<ul>
<li><strong>Sub-Tree</strong> : Parent node - Child node 를 묶음(표에서 5, 3, 6의 묶음을 말한다)</li>
</ul>
</li>
<li><p>형제(Sibling) : 부모가 없는 최상위 노드</p>
</li>
</ul>
<hr>
<h1 id="트리-특징">트리 특징</h1>
<h2 id="주요-특징">주요 특징</h2>
<p>‘최소 연결 트리’로 불림, 계층 모델, 방향 비순환 그래프(DAG: Directed Acyclic Graph) 한 종류</p>
<h2 id="트리-종류">트리 종류</h2>
<ul>
<li>이진 트리</li>
<li>이진 탐색 트리</li>
<li>AVL 트리</li>
<li>힙(Heap)
<img src="https://velog.velcdn.com/images/frozen_land/post/f3c9444e-cb41-4a71-87e7-076a4c523af8/image.png" alt=""></li>
<li>노트 크기(Size) : 자신을 포함한 모든 자손 노드의 개수</li>
<li>노드 깊이(Depth) : 루트에서 특정 노드에 도달하기 위한 간선의 개수</li>
<li>노드 레벨(level) : 트리의 특정 깊이를 가지는 노드의 집합 → 루트 기준으로 Level 0인 경우도 있다.</li>
<li>노드 차수(degree) : 노드가 지닌 가지의 수</li>
<li>트리 차수(tree degree) : 트리의 최대 차수</li>
<li>트리 높이(height) : 루트 노드에서 가장 깊숙이 있는 노드의 깊이</li>
</ul>
<h1 id="트리-순회">트리 순회</h1>
<p>트리 구조에서 각각의 <strong>노드를 정확히 한 번씩</strong> 체계적인 방법으로 <strong>방문</strong>하는 과정</p>
<h2 id="필요-용어">필요 용어</h2>
<ul>
<li>N(Node) : 해당 노드를 방문</li>
<li>L(Left) : 왼쪽 서브 트리로 이동</li>
<li>R(Right) : 오른쪽 서브 트리로 이동</li>
</ul>
<h2 id="순회-방식">순회 방식</h2>
<ul>
<li>전위 순회 (Pre-order) : <strong>N</strong> - L - R</li>
<li>중위 순회 (In-order) : L - <strong>N</strong> - R</li>
<li>후위 순회 (Post-order) : L - R - <strong>N</strong></li>
<li>층별 순회 (Level-order) : 낮은 Level부터 순차적으로 순회(Level 0 → Level N)</li>
</ul>
<h3 id="전위-순회pre-order">전위 순회(Pre-order)</h3>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/50711bd8-dddf-43be-a8ba-f4d835cb0cc9/image.png" alt=""></p>
<ul>
<li>전위 순회 방법 : <strong>N</strong> - L - R<ol>
<li>노드를 방문</li>
<li>왼쪽 서브 트리를 전위 순회</li>
<li>오른쪽 서브 트리를 전위 순회</li>
</ol>
</li>
<li>방문 순서 : F → B → A → D → C → E → G → I → H</li>
<li>의사 코드(pseudo-code)</li>
</ul>
<pre><code class="language-jsx">preorder(node)
print node.value
if node.left != null then preoder(node.left)
if node.right != null then preoder(node.right)</code></pre>
<h3 id="중위-순회in-order">중위 순회(In-order)</h3>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/5e118b79-13ab-4a4c-88f0-70869a84bd72/image.png" alt=""></p>
<ul>
<li>중위 순회 방법 : L - <strong>N</strong> - R<ol>
<li>왼쪽 서브 트리를 중위 순회</li>
<li>현재 노드를 방문</li>
<li>오른쪽 서브 트리를 중위 순회</li>
</ol>
</li>
<li>방문 순서 : A → B → C → D → E → F → G → H → I</li>
<li>의사 코드(pseudo-code)</li>
</ul>
<pre><code class="language-jsx">inorder(node)
if node.left != null then inorder(node.left)
print node.value
if node.right != null then inorder(node.right)</code></pre>
<h3 id="층별-순회level-order">층별 순회(Level-order)</h3>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/f40ccf4a-6114-4381-bb89-a7bca1dc618b/image.png" alt=""></p>
<ul>
<li>층별 순회 방법 : 낮은 Level부터 순차적으로 순회(Level 0 → Level N)<ol>
<li>root 노드 방문</li>
<li>Level 증가</li>
<li>왼쪽에서 오른쪽 순으로 방문</li>
</ol>
</li>
<li>방문 순서 : F → B → G → A → D → I → C → E → H</li>
<li>의사 코드(pseudo-code)</li>
</ul>
<pre><code class="language-jsx">levelorder(node)
q.enqueue(root)
while noe q.empty do
    node := q.denqueue()
    print node.value
    if node.left != null then enqueue(node.left)
    if node.right != null then enqueue(node.right)</code></pre>
<h3 id="후위-순회post-order">후위 순회(Post-order)</h3>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/52d74dd7-0486-4053-a103-78607c7bad26/image.png" alt=""></p>
<ul>
<li>후위 순회 방법 : L - R - <strong>N</strong><ol>
<li>왼쪽 서브 트리를 후위 순회</li>
<li>오른쪽 서브 트리를 후위 순회</li>
<li>현재 노드 방문</li>
</ol>
</li>
<li>방문 순서 : A → C→ E → D → B → H→ I → G → F</li>
<li>의사 코드(pseudo-code)</li>
</ul>
<pre><code class="language-jsx">postorder(node)
if node.left != null then postorder(node.left)
if node.right != null then postorder(node.right)
print node.value</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[해시테이블]]></title>
            <link>https://velog.io/@frozen_land/%ED%95%B4%EC%8B%9C%ED%85%8C%EC%9D%B4%EB%B8%94</link>
            <guid>https://velog.io/@frozen_land/%ED%95%B4%EC%8B%9C%ED%85%8C%EC%9D%B4%EB%B8%94</guid>
            <pubDate>Wed, 23 Apr 2025 00:44:41 GMT</pubDate>
            <description><![CDATA[<h2 id="해시함수hash-function">해시함수(Hash Function)</h2>
<ul>
<li>임의의 길이의 데이터를 <strong>고정된 길이의 데이터로 매핑</strong>하는 함수</li>
<li>해시 함수 특성<ul>
<li>압축성 : 다양한 가변 길이의 입력에 대해 고정된 크기의 결과값을 반환하는 성질</li>
<li>효율성 : 어떤 입력 값에 대해서도 많은 자원과 시간이 소요되지 않고 처리되는 성질</li>
<li><strong>저항성</strong> : 결과값을 바탕으로 <strong>입력 값을 찾는 것이 불가능</strong>한 성질
<img src="https://velog.velcdn.com/images/frozen_land/post/d51ff6dc-69f3-492e-894b-c1c485f04409/image.png" alt=""></li>
</ul>
</li>
</ul>
<hr>
<h2 id="해시테이블hash-table">해시테이블(Hash Table)</h2>
<ul>
<li>Hash 함수를 사용하여 평균 O(1) 시간 복잡도로 특정 값을 신속하게 찾는 자료구조</li>
<li>충돌(Collision) 해결 방법<ul>
<li>해시 함수 변경 : 더 큰 숫자의 공간과 Modulat 산술 값을 이용해 충돌 최소화</li>
<li>자료 구조 확장 : Open Addressing Method (선형 조사법, 이중해시), Close Adreesing Method(체이닝)</li>
</ul>
</li>
<li>구현 메서드(Method)<pre><code class="language-jsx">// 배열에 대한 크기 지정
const HASH_SIZE = 37;
</code></pre>
</li>
</ul>
<p>// Element() : Key, Value 저장을 위한 생성자
function Element(key, value) {
  this.key = key;
  this.value = value;
}</p>
<p>// HashTable() : 생성자
function HashTable() {
  this.table = new Array(HASH_SIZE);
  this.length = 0;
}</p>
<p>// hashCode() : 해시 함수
HashTable.prototype.hashCode = function (key) {
  let hash = 0;
  for (let i = 0; i &lt; key.length; i++) {
    // 누적 저장
    hash += key.charCodeAt(i);
  }</p>
<p>  return hash % HASH_SIZE; // 37이내의 숫자로 변환
};</p>
<p>let ht = new HashTable();
console.log(ht);</p>
<p>console.log(ht.hashCode(&quot;Ana&quot;));
console.log(ht.hashCode(&quot;Sue&quot;));
console.log(ht.hashCode(&quot;Paul&quot;));</p>
<hr>
<p>OUTPUT
HashTable { table: [ &lt;37 empty items&gt; ], length: 0 }
13
5
32</p>
<pre><code>
- 객체 초기화 : `HashTable.clear()`
- 객체 크기 반환 : `HashTable.size()`
- 전체 데이터 반환 : `HashTable.getBuffer()`
- 전체 데이터 출력 : `HashTable.print()`
</code></pre><p>// 배열에 대한 크기 지정
const HASH_SIZE = 37;</p>
<p>// Element() : Key, Value 저장을 위한 생성자
function Element(key, value) {
  this.key = key;
  this.value = value;
}</p>
<p>// HashTable() : 생성자
function HashTable() {
  this.table = new Array(HASH_SIZE);
  this.length = 0;
}</p>
<p>// hashCode() : 해시 함수
HashTable.prototype.hashCode = function (key) {
  let hash = 0;
  for (let i = 0; i &lt; key.length; i++) {
    // 누적 저장
    hash += key.charCodeAt(i);
  }</p>
<p>  return hash % HASH_SIZE; // 인덱스 값으로 사용
};</p>
<p>// clear() : 초기화
HashTable.prototype.clear = function () {
  this.table = new Array(HASH_SIZE);
  this.length = 0;
};</p>
<p>// size() : 크기 변환
HashTable.prototype.size = function () {
  return this.length;
};</p>
<p>// getBuffer() : 데이터 셋 반환
HashTable.prototype.getBuffer = function () {
  let array = [];
  for (let i = 0; i &lt; this.table.length; i++) {
    if (this.table[i]) {
      array.push(this.table[i]);
    }
  }</p>
<p>  return array;
};</p>
<p>// print() : 데이터 셋 출력
HashTable.prototype.print = function () {
  for (let i = 0; i &lt; this.table.length; i++) {
    if (this.table[i]) {
      console.log(i + &quot; -&gt; &quot; + this.table[i].key + &quot; : &quot; + this.table[i].value);
    }
  }
};</p>
<p>let ht = new HashTable();</p>
<p>ht.put(&quot;Ana&quot;, 172);
ht.put(&quot;Sue&quot;, 163);
ht.put(&quot;Paul&quot;, 190);</p>
<p>console.log(&quot;&quot;);
ht.print();
console.log(ht.getBuffer());</p>
<p>console.log(ht.size());</p>
<p>ht.clear();
console.log(ht);</p>
<hr>
<p>OUTPUT
key : Ana -&gt; index : 13
key : Sue -&gt; index : 5
key : Paul -&gt; index : 32</p>
<p>5 -&gt; Sue : 163
13 -&gt; Ana : 172
32 -&gt; Paul : 190
[
  Element { key: &#39;Sue&#39;, value: 163 },
  Element { key: &#39;Ana&#39;, value: 172 },
  Element { key: &#39;Paul&#39;, value: 190 }
]
3
HashTable { table: [ &lt;37 empty items&gt; ], length: 0 }</p>
<pre><code>
- 데이터 추가 : `HashTable.put()`
- 데이터 삭제 : `HashTable.remove()`
- 데이터 반환 : `HashTable.get()`
</code></pre><p>// 배열에 대한 크기 지정
const HASH_SIZE = 37;</p>
<p>// Element() : Key, Value 저장을 위한 생성자
function Element(key, value) {
  this.key = key;
  this.value = value;
}</p>
<p>// HashTable() : 생성자
function HashTable() {
  this.table = new Array(HASH_SIZE);
  this.length = 0;
}</p>
<p>// hashCode() : 해시 함수
HashTable.prototype.hashCode = function (key) {
  let hash = 0;
  for (let i = 0; i &lt; key.length; i++) {
    // 누적 저장
    hash += key.charCodeAt(i);
  }</p>
<p>  return hash % HASH_SIZE; // 인덱스 값으로 사용
};</p>
<p>// put() : 데이터 추가
HashTable.prototype.put = function (key, value) {
  let index = this.hashCode(key);
  console.log(<code>key : ${key} -&gt; index : ${index}</code>);</p>
<p>  // 추가하려는 인덱스에 값이 있을 경우
  if (this.table[index] !== undefined) {
    return false;
  }</p>
<p>  // 값 추가
  this.table[index] = new Element(key, value);
  this.length++;</p>
<p>  return true;
};</p>
<p>// get() : 데이터 조회
HashTable.prototype.get = function (key) {
  return this.table[this.hashCode(key)];
};</p>
<p>// remove() : 데이터 삭제
HashTable.prototype.remove = function (key) {
  let element = this.table[this.hashCode(key)];</p>
<p>  // 값이 있을 경우 삭제
  if (element !== undefined) {
    delete this.table[this.hashCode(key)];
    this.length--;
  }</p>
<p>  return element;
};</p>
<p>let ht = new HashTable();</p>
<p>ht.put(&quot;Ana&quot;, 172);
ht.put(&quot;Sue&quot;, 163);
ht.put(&quot;Paul&quot;, 190);</p>
<p>console.log(ht);</p>
<p>console.log(ht.get(&quot;Paul&quot;));
console.log(ht.remove(&quot;Paul&quot;));</p>
<p>console.log(ht.get(&quot;Paul&quot;));
console.log(ht.remove(&quot;Paul&quot;));</p>
<p>console.log(ht);</p>
<hr>
<p>OUTPUT
key : Ana -&gt; index : 13
key : Sue -&gt; index : 5
key : Paul -&gt; index : 32 → 각자 해당 인덱스 위치로 이동</p>
<p>HashTable {
  table: [
    &lt;5 empty items&gt;,
    Element { key: &#39;Sue&#39;, value: 163 },
    &lt;7 empty items&gt;,
    Element { key: &#39;Ana&#39;, value: 172 },
    &lt;18 empty items&gt;,
    Element { key: &#39;Paul&#39;, value: 190 },
    &lt;4 empty items&gt;
  ],
  length: 3
}</p>
<p>Element { key: &#39;Paul&#39;, value: 190 }
Element { key: &#39;Paul&#39;, value: 190 }</p>
<p>undefined → Paul 을 지웠으니 undefined로 출력되는게 맞다.
undefined → 지울 Paul이 없으니 undefined로 출력되는게 맞다.</p>
<p>HashTable {
  table: [
    &lt;5 empty items&gt;,
    Element { key: &#39;Sue&#39;, value: 163 },
    &lt;7 empty items&gt;,
    Element { key: &#39;Ana&#39;, value: 172 },
    &lt;23 empty items&gt;
  ],
  length: 2
}</p>
<pre><code>
### 충돌 문제(use djb2)

![](https://velog.velcdn.com/images/frozen_land/post/bfd391cf-b341-49f2-bac0-68be3ee1b5e1/image.png)


인덱스 값이 중복되어 충돌 발생 → djb2 코드 사용하여 해결
```jsx
// djb2 hash size
const HASH_SIZE = 1013;

// Element() : Key, Value 저장을 위한 생성자
function Element(key, value) {
  this.key = key;
  this.value = value;
}

// HashTable() : 생성자
function HashTable() {
  this.table = new Array(HASH_SIZE);
  this.length = 0;
}

// hashCode() : 해시 함수
HashTable.prototype.hashCode = function (key) {
  // djb2 hash function
  let hash = 5381; // seed
  for (let i = 0; i &lt; key.length; i++) {
    // 누적 저장
    hash = hash * 33 + key.charCodeAt(i);
  }

  return hash % HASH_SIZE; // 인덱스 값으로 사용
};

let ht = new HashTable();

ht.put(&quot;Ana&quot;, 172);
ht.put(&quot;Donnie&quot;, 183);
ht.put(&quot;Sue&quot;, 163);
ht.put(&quot;Jamie&quot;, 168);
ht.put(&quot;Paul&quot;, 190);

console.log(&quot;&quot;);
console.log(ht.size());
ht.print();

------------------------------------------------------------------------
OUTPUT
key : Ana -&gt; index : 925
key : Donnie -&gt; index : 278
key : Sue -&gt; index : 502
key : Jamie -&gt; index : 962
key : Paul -&gt; index : 54

5
54 -&gt; Paul : 190
278 -&gt; Donnie : 183
502 -&gt; Sue : 163
925 -&gt; Ana : 172
962 -&gt; Jamie : 168</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[우선순위 큐(Priority Queue)]]></title>
            <link>https://velog.io/@frozen_land/%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84-%ED%81%90Priority-Queue</link>
            <guid>https://velog.io/@frozen_land/%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84-%ED%81%90Priority-Queue</guid>
            <pubDate>Mon, 21 Apr 2025 16:29:41 GMT</pubDate>
            <description><![CDATA[<h2 id="우선순위-큐priority-queue">우선순위 큐(Priority Queue)</h2>
<ul>
<li><p><strong>우선순위를 고려</strong>하여 먼저 넣은 데이터가 먼저 나오는 <strong>FIFO(First In First Out)</strong> 기반의 선형 자료 구조</p>
</li>
<li><p>우선순위 정렬 방식 : <strong>배열 기반</strong>, 연결리스트 기반, 힙(Heap) 기반 등의 정렬 방식 존재</p>
</li>
<li><p>구현 메서드 (method)</p>
<ul>
<li><p>데이터 전체 획득 : <code>PriotiyQueue.getBuffer()</code></p>
</li>
<li><p>데이터 비어있는지 확인 : <code>PriotiyQueue.isEmpty()</code></p>
<pre><code class="language-jsx">// Element() : 데이터와 우선수위를 저장하기 위한 생성자 함수
function Element(data, priority) {
this.data = data;
this.priority = priority;
}

// priorityQueue() : Element 관리를 위한 생성자 함수
function PriorityQueue() {
this.array = [];
}

//getBuffer () : 객체 내 데이터 셋 반환
PriorityQueue.prototype.getBuffer = function () {
return this.array.map((element) =&gt; element.data);
};

//isEmpty() : 객체 내 데이터 존재 여부 파악
PriorityQueue.prototype.isEmpty = function () {
return this.array.length === 0;
};

console.log(Object.getOwnPropertyDescriptors(Element.prototype));
console.log(Object.getOwnPropertyDescriptors(PriorityQueue.prototype));
</code></pre>
</li>
</ul>
<hr>
<p>  OUTPUT
  {</p>
<pre><code>constructor: {
  value: [Function: Element],
  writable: true,
  enumerable: false,
  configurable: true
}</code></pre><p>  }
  {</p>
<pre><code>constructor: {
  value: [Function: PriorityQueue],
  writable: true,
  enumerable: false,
  configurable: true
},
getBuffer: {
  value: [Function (anonymous)],
  writable: true,
  enumerable: true,
  configurable: true
},
isEmpty: {
  value: [Function (anonymous)],
  writable: true,
  enumerable: true,
  configurable: true
}</code></pre><p>  }</p>
<pre><code>
  - 데이터 추가 : `PriotiyQueue.enqueue()`
  - 데이터 삭제 : `PriotiyQueue.dequeue()`
</code></pre><p>  // Element() : 데이터와 우선수위를 저장하기 위한 생성자 함수
  function Element(data, priority) {</p>
<pre><code>this.data = data;
this.priority = priority;</code></pre><p>  }</p>
<p>  // priorityQueue() : Element 관리를 위한 생성자 함수
  function PriorityQueue() {</p>
<pre><code>this.array = [];</code></pre><p>  }</p>
<p>  //getBuffer () : 객체 내 데이터 셋 반환
  PriorityQueue.prototype.getBuffer = function () {</p>
<pre><code>return this.array.map((element) =&gt; element.data);</code></pre><p>  };</p>
<p>  //isEmpty() : 객체 내 데이터 존재 여부 파악
  PriorityQueue.prototype.isEmpty = function () {</p>
<pre><code>return this.array.length === 0;</code></pre><p>  };</p>
<p>  // enqueue () : 데이터 추가
  PriorityQueue.prototype.enqueue = function (data, priority) {</p>
<pre><code>let element = new Element(data, priority);
let added = false;

for (let i = 0; i &lt; this.array.length; i++) {
  if (element.priority &lt; this.array[i].priority) {
    this.array.splice(i, 0, element); // (i번째에, 삭제없이, element 추가)
    added = true;
    break;
  }
}

if (!added) {
  this.array.push(element);
}

return this.array.length;</code></pre><p>  };</p>
<p>  // dequeue () : 데이터 삭제
  PriorityQueue.prototype.dequeue = function () {</p>
<pre><code>return this.array.shift();</code></pre><p>  };</p>
<p>  let pq = new PriorityQueue();
  pq.enqueue(&quot;Alice&quot;, 1);
  pq.enqueue(&quot;bob&quot;, 2);</p>
<p>  console.log(pq);</p>
<p>  pq.enqueue(&quot;Tom&quot;, 1);
  pq.enqueue(&quot;John&quot;, 3);</p>
<p>  console.log(pq);</p>
<p>  console.log(&quot;dequeue : &quot;, pq.dequeue());
  console.log(&quot;dequeue : &quot;, pq.dequeue());</p>
<p>  console.log(pq);</p>
<hr>
<p>  OUTPUT
  PriorityQueue {</p>
<pre><code>array: [
  Element { data: &#39;Alice&#39;, priority: 1 },
  Element { data: &#39;bob&#39;, priority: 2 }
]</code></pre><p>  }
  PriorityQueue {</p>
<pre><code>array: [
  Element { data: &#39;Alice&#39;, priority: 1 },
  Element { data: &#39;Tom&#39;, priority: 1 },
  Element { data: &#39;bob&#39;, priority: 2 },
  Element { data: &#39;John&#39;, priority: 3 }
]</code></pre><p>  }
  dequeue : Element { data: &#39;Alice&#39;, priority: 1 }
  dequeue : Element { data: &#39;Tom&#39;, priority: 1 }
  PriorityQueue {</p>
<pre><code>array: [
  Element { data: &#39;bob&#39;, priority: 2 },
  Element { data: &#39;John&#39;, priority: 3 }
]</code></pre><p>  }</p>
<pre><code>
  - 첫번째 데이터 : `PriotiyQueue.front()`
  - 데이터 사이즈 : `PriotiyQueue.size()`
  - 전체 삭제 : `PriotiyQueue.clear()`

  ```jsx
  // front() : 가장 첫 데이터 반환
  PriorityQueue.prototype.front = function () {
    return this.array.length === 0 ? undefined : this.array[0];
  };
  // size() : 큐 내 데이터 개수 확인
  PriorityQueue.prototype.size = function () {
    return this.array.length;
  };
  // clear() : 큐 초기화
  PriorityQueue.prototype.clear = function () {
    return (this.array = []);
  };</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[스택+큐]]></title>
            <link>https://velog.io/@frozen_land/%EC%8A%A4%ED%83%9D%ED%81%90</link>
            <guid>https://velog.io/@frozen_land/%EC%8A%A4%ED%83%9D%ED%81%90</guid>
            <pubDate>Mon, 21 Apr 2025 08:18:57 GMT</pubDate>
            <description><![CDATA[<h2 id="스택stack">스택(Stack)</h2>
<ul>
<li>나중에 넣은 데이터가 먼저 나오는 <strong>LIFO(Last In First Out)</strong> 기반의 선형 자료 구조
<img src="https://velog.velcdn.com/images/frozen_land/post/94276211-7eab-4d55-b1b2-e61044530863/image.png" alt=""></li>
</ul>
<ul>
<li><p>구현 메서드(method)</p>
<ul>
<li><p>데이터 전체 획득 : <code>Stack.getBuffer()</code></p>
</li>
<li><p>비어있는지 확인 : <code>Stack.isEmpty()</code></p>
<pre><code class="language-jsx">// Stack() : 생성자 함수
function Stack(array) {
this.array = array ? array : [];
}

// getBuffer() : 객체 내 데이터 셋 반환 (값만 복사)
Stack.prototype.getBuffer = function () {
return this.array.slice();
};
// isEmpty() : 객체 내 데이터 O/X
Stack.prototype.isEmpty = function () {
return this.array.length === 0; // 비어있으면 O , 데이터가 있으면 X
};

let stack = new Stack([1, 2, 3]);
console.log(stack);

let data = stack.getBuffer();
console.log(data);
console.log(data === stack.array); 
// ⬆️ 완벽하게 일치하였으면 true 지만 배열의 값만 복사해와서 다르므로 false
console.log(stack.isEmpty());
console.log(Object.getOwnPropertyDescriptors(Stack.prototype));
</code></pre>
</li>
</ul>
<hr>
<p>  OUTPUT
  Stack { array: [ 1, 2, 3 ] }
  [ 1, 2, 3 ]
  false ➡️ 완벽하게 일치하였으면 true 지만 배열의 값만 복사해와서 다르므로 False
  false
  {</p>
<pre><code>constructor: {
  value: [Function: Stack],
  writable: true,
  enumerable: false,
  configurable: true
},
getBuffer: {
  value: [Function (anonymous)],
  writable: true,
  enumerable: true,
  configurable: true
},
isEmpty: {
  value: [Function (anonymous)],
  writable: true,
  enumerable: true,
  configurable: true
}</code></pre><p>  }</p>
<pre><code>
  - 추가 : `Stack.push()`
  - 삭제 `Stack.pop()`
  - 마지막 데이터 조회 : `Stack.peak()`
  - 크기 확인 : `Stack.size()`

  ```jsx
  // Stack() : 생성자 함수
  function Stack(array) {
    this.array = array ? array : [];
  }

  // push() : 데이터 추가
  Stack.prototype.push = function (element) {
    return this.array.push(element);
  };

  // pop() : 데이터 삭제
  Stack.prototype.pop = function () {
    return this.array.pop();
  };

  //peak() : 가장 끝 데이터 반환
  Stack.prototype.peak = function () {
    return this.array[this.array.length - 1];
  };

  // size() : 스택 내 데이터 개수 확인
  Stack.prototype.size = function () {
    return this.array.length;
  };

  let stack = new Stack([1, 2]);
  console.log(stack);
  stack.push(3);
  console.log(&quot;push : &quot;, stack);
  console.log(&quot;pop : &quot;, stack.pop());
  console.log(&quot;pop : &quot;, stack.pop());
  console.log(&quot;peak : &quot;, stack.peak());
  console.log(&quot;size : &quot;, stack.size());
  console.log(stack);

  ------------------------------------------------------------------------
  OUTPUT
  Stack { array: [ 1, 2 ] }
  push :  Stack { array: [ 1, 2, 3 ] }
  pop :  3
  pop :  2
  peak :  1
  size :  1
  Stack { array: [ 1 ] }</code></pre><ul>
<li><p>데이터 위치 : <code>Stack.indexOf()</code></p>
</li>
<li><p>존재 여부 확인 : <code>Stack.includes(</code></p>
<pre><code>// Stack() : 생성자 함수
function Stack(array) {
this.array = array ? array : [];
}

// indexOf() : 매개변수로 넘어온 element 위치 확인
Stack.prototype.indexOf = function (element, position = 0) {
for (let i = position; i &lt; this.array.length; i++) {
  if (element === this.array[i]) return i;
}
return -1;
// return this.array.indexOf(element, position);
};

// includes() : 데이터 존재 여부 확인
Stack.prototype.includes = function (element, position = 0) {
for (let i = position; i &lt; this.array.length; i++) {
  if (element === this.array[i]) return true;
}

return false;
};

let stack = new Stack([1, 2, 3]);
console.log(&quot;indexOf : &quot;, stack.indexOf(1));
console.log(&quot;indexOf : &quot;, stack.indexOf(1, 2));
console.log(&quot;includes : &quot;, stack.includes(1));
console.log(&quot;includes : &quot;, stack.includes(1, 2));
console.log(&quot;includes : &quot;, stack.includes(5)); // 없는 값
</code></pre></li>
</ul>
<hr>
<p>  OUTPUT
  indexOf :  0
  indexOf :  -1
  includes :  true
  includes :  false
  includes :  false</p>
<pre><code>
</code></pre></li>
</ul>
<hr>
<h2 id="큐queue">큐(Queue)</h2>
<ul>
<li><p>먼저 넣은 데이터가 먼저 나오는 <strong>FIFO(First In First Out)</strong> 기반의 선형 자료 구조
<img src="https://velog.velcdn.com/images/frozen_land/post/049b0810-e34d-4aa2-9b71-a3944da852a9/image.png" alt=""></p>
</li>
<li><p>구현 메서드(method)</p>
<ul>
<li><p>데이터 전체 획득 : <code>Queue.getBuffer()</code></p>
</li>
<li><p>데이터 비어 있는지 확인 : <code>Queue.isEmpty()</code></p>
<pre><code class="language-jsx">// Queue() : 생섬자 함수로 초기 데이터 설정
function Queue(array) {
this.array = array ? array : [];
}

// getBuffer() : 객체 내 데이터 셋 반환
Queue.prototype.getBuffer = function () {
return this.array.slice();
};

// isEmpty() : 객체 내 데이터 O/X
Queue.prototype.isEmpty = function () {
return this.array.length === 0;
};

let queue = new Queue([1, 2, 3]);
console.log(queue);

let data = queue.getBuffer();
console.log(data);
console.log(data === queue.array);
console.log(queue.isEmpty());
console.log(Object.getOwnPropertyDescriptors(Queue.prototype));
</code></pre>
</li>
</ul>
<hr>
<p>  OUTPUT
  Queue { array: [ 1, 2, 3 ] }
  [ 1, 2, 3 ]
  false
  false
  {</p>
<pre><code>constructor: {
  value: [Function: Queue],
  writable: true,
  enumerable: false,
  configurable: true
},
getBuffer: {
  value: [Function (anonymous)],
  writable: true,
  enumerable: true,
  configurable: true
},
isEmpty: {
  value: [Function (anonymous)],
  writable: true,
  enumerable: true,
  configurable: true
}</code></pre><p>  }</p>
<pre><code>
  - 데이터 추가 : `Queue.enqueue()`
  - 데이터 삭제 : `Queue.dequeue()`

  ```jsx
  // Queue() : 생섬자 함수로 초기 데이터 설정
  function Queue(array) {
    this.array = array ? array : [];
  }

  // enqueue() : 데이터 추가
  Queue.prototype.enqueue = function (element) {
    return this.array.push(element);
  };
  // dequeue() : 데이터 삭제
  Queue.prototype.dequeue = function () {
    return this.array.shift();
  };

  let queue = new Queue([1, 2, 3]);
  console.log(queue);

  queue.enqueue(3);
  queue.enqueue(4);
  console.log(&quot;enqueue : &quot;, queue);

  queue.dequeue();
  console.log(&quot;dequeue : &quot;, queue);

  ------------------------------------------------------------------------
  OUTPUT
  Queue { array: [ 1, 2, 3 ] }
  enqueue :  Queue { array: [ 1, 2, 3, 3, 4 ] }
  dequeue :  Queue { array: [ 2, 3, 3, 4 ] }</code></pre><ul>
<li><p>첫번째 데이터 : <code>Queue.front()</code></p>
</li>
<li><p>데이터 사이즈 : <code>Queue.size()</code></p>
</li>
<li><p>전체 삭제 : <code>Queue.clear()</code></p>
<pre><code>// Queue() : 생섬자 함수로 초기 데이터 설정
function Queue(array) {
this.array = array ? array : [];
}

// front() : 가장 첫 데이터 반환
Queue.prototype.front = function () {
return this.array.length === 0 ? undefined : this.array[0];
};
// size() : 큐 내 데이터 개수 확인
Queue.prototype.size = function () {
return this.array.length;
};
// clear() : 큐 초기화
Queue.prototype.clear = function () {
return (this.array = []);
};

let queue = new Queue([1, 2, 3, 4]);
queue.dequeue();
console.log(&quot;front : &quot;, queue.front());
console.log(queue); // 첫번째 데이터를 반환을 하고 배열 내에 삭제되지는 않음

console.log(&quot;size : &quot;, queue.size());
queue.clear();
console.log(queue);
</code></pre></li>
</ul>
<hr>
<p>  OUTPUT
  front :  2
  Queue { array: [ 2, 3, 4 ] }
  size :  3
  Queue { array: [] }</p>
<pre><code>
</code></pre></li>
</ul>
<h3 id="큐-최적화">큐 최적화</h3>
<ul>
<li>방식 개선 : enqueue/dequeue 방식을 push/shift 에서 index 로 변경(shift는 O(n), index는 O(1))
<img src="https://velog.velcdn.com/images/frozen_land/post/acd499bf-9559-4984-8076-ad56fcca0f18/image.png" alt=""></li>
</ul>
<pre><code class="language-jsx">// Queue() : 생섬자 함수로 초기 데이터 설정
function Queue(array) {
  this.array = array ? array : [];
  this.tail = array ? array.length : [];
  this.head = 0;
}

// enqueue() : 데이터 추가
Queue.prototype.enqueue = function (element) {
  // return this.array.push(element);
  return (this.array[this.tail++] = element);
};
// dequeue() : 데이터 삭제
Queue.prototype.dequeue = function () {
  if (this.tail === this.head) return undefined;

  let element = this.array[this.head];
  delete this.array[this.head++];

  return element;
};

let queue = new Queue([1, 2]);
console.log(queue);

queue.enqueue(3);
queue.enqueue(4);
console.log(&quot;enqueue : &quot;, queue);

console.log(queue.dequeue());
console.log(queue.dequeue());
console.log(&quot;dequeue : &quot;, queue);

------------------------------------------------------------------------
OUTPUT
Queue { array: [ 1, 2 ], tail: 2, head: 0 }
enqueue :  Queue { array: [ 1, 2, 3, 4 ], tail: 4, head: 0 }
1
2
dequeue :  Queue { array: [ &lt;2 empty items&gt;, 3, 4 ], tail: 4, head: 2 }</code></pre>
<img src="https://velog.velcdn.com/images/frozen_land/post/a157116a-160c-4267-8575-e9191dd75aea/image.png">

<ul>
<li>처음 작성한 enqueue, dequeue 보다 최적화된 코드가 수행이 더 빠르다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로토타입+연결 리스트]]></title>
            <link>https://velog.io/@frozen_land/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@frozen_land/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Thu, 17 Apr 2025 08:15:50 GMT</pubDate>
            <description><![CDATA[<h2 id="프로토타입-prototype">프로토타입 (prototype)</h2>
<ul>
<li>어떠한 객체가 만들어지기 위해 객체의 모태가 되는 원형</li>
<li>자바스크립트는 일반적인 객체 지향 언어와는 다르게, 프로토타입을 이용한 복사(Cloning)을 통해 새로운 객체 생성</li>
<li>일반적인 객체 생성 방식 : 속성은 생성자, 메서드는 프로토타입에서 정의</li>
</ul>
<pre><code class="language-jsx">// 생성자에서 속성 정의
function Test (a,b) {
    //속성 정의
}

// 첫 메소드 정의
Test.prototype.x = function() { ... };

// 두번째 메소드 정의
Test.prototype.y = function() { ... };

//객체 생성
let test = new Test(1,2);</code></pre>
<p>예시</p>
<pre><code class="language-jsx">// 생성자에서 속성 정의
function Person (name, age) {
    //속성 정의
    this.name = name;
    this.age = age;
}

// prototype을 이용한 person 메서드 정의
Person.prototype.isAudlt = function() { 
    return this.age &gt; 18;
 };

//객체 생성
const p1 = new Person(&quot;bob&quot;, 26);
const p2 = new Person(&quot;alice&quot;, 18);

console.log(p1)
console.log(p2)

console.log(p1.isAudlt());
console.log(p2.isAudlt());

--------------------------------------------
OUTPUT
Person { name: &#39;bob&#39;, age: 26 }
Person { name: &#39;alice&#39;, age: 18 }
true
false</code></pre>
<h2 id="연결-리스트linked-list">연결 리스트(Linked List)</h2>
<ul>
<li><p>각 노드가 데이토와 포인터를 가지며, 한 줄로 연결되어 있는 방식으로 데이터를 저장하는 자료 구조</p>
</li>
<li><p>구현 메서드(method)</p>
<ul>
<li><code>LinkedList()</code> : head와 length를 가지고 있는 객체</li>
<li>노드 개수 / 비어있는지 확인 / 노드 출력 :<ul>
<li><code>LinkedList.size()</code> : 연결 리스트 내 노드 개수 확인</li>
<li><code>LinkedList.isEmpty()</code> : 객체 내 노드 존재 여부 파악(true/false)</li>
<li><code>LinkedList.printNode()</code> : 노드 출력</li>
</ul>
</li>
</ul>
<hr>
<ul>
<li>노드 추가<ul>
<li><code>LinkedList.append()</code> : 연결 리스트 가장 끝에 노드 추가</li>
<li><code>LinkedList.insert()</code> : position 위치에 노드 추가</li>
</ul>
</li>
<li>노드 삭제<ul>
<li>LinkedList.remove()` : value 데이터를 찾아 노드 삭제</li>
<li><code>LinkedList.removeAt()</code> : position 위치 노드 삭제</li>
</ul>
</li>
<li>데이터 위치 확인<ul>
<li><code>LinkedList.index()</code> : value 값을 갖는 노드 위치 반환</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/ec0449f0-559f-43c7-b16e-2d758eb511c7/image.png" alt=""></p>
<ul>
<li>맨 앞 Node = HEAD</li>
<li>맨 마지막 Node의 주소는 Null값이 들어간다</li>
</ul>
<p>head → null → 노드1 생성</p>
<p>head → 생성한 노드1 → null → 노드 생성</p>
<p>head → 생성한 노드1 → 생성한 노드2 → null</p>
<hr>
<p>작성한 코드</p>
<pre><code class="language-jsx">// Node() : data와 point를 가지고 있는 객체
function Node(data){
    this.data = data;
    this.next = null;
}

// LinkedList() : head와 length를 가지고 있는 객체
function LinkedList(){
    this.head = null;
    this.length = 0;
}

//size() : 연결 리스트 내 노드 개수 확인
LinkedList.prototype.size = function () {
    return this.length;
}

// isEmpty() : 객체 내 노드 존재 여부 파악(true/false)
LinkedList.prototype.isEmpty = function () {
    return this.length === 0;
}

// printNode() : 노드 출력
LinkedList.prototype.printNode = function() {
    for(let node = this.head ; node != null ; node = node.next){
        process.stdout.write(`${node.data} -&gt; `);
    }
    console.log(&quot;null&quot;)
}

//append() : 연결 리스트 가장 끝에 노드 추가
LinkedList.prototype.append = function(value) {
    let node = new Node(value);
    let current = this.head;

    if(this.head === null){
        this.head = node;
    } else{
        while(current.next != null){
            current = current.next;
        }
        current.next = node;
    }

    this.length++;
}

// insert() : position 위치에 노드 추가
LinkedList.prototype.insert = function(value, position = 0) {
    if(position &lt; 0 || position &gt; this.length){
        return false;
    }

    let node = new Node(value),
    current = this.head,
    index = 0,
    prev;

    if(position === 0){
        node.next = current;
        this.head = node;
    } else{
        while(index++ &lt; position){
            prev = current;
            current = current.next;
        }

        node.next = current;
        prev.next = node;
    }
    this.length++;
    return true;
}

// remove() : value 데이터를 찾아 노드 삭제
LinkedList.prototype.remove = function(value){
    let current = this.head,
    prev = current;

    while(current.data != value &amp;&amp; current.next != null){
        prev = current;
        current = current.next;
    }

    if(current.data != value){
        return null;
    }

    if(current === this.head){
        this.head = current.next;
    } else{
        prev.next = current.next;
    }

    this.length--;

    return current.data;
}

// removeAt() : position 위치 노드 삭제
LinkedList.prototype.removeAt = function (position = 0){
    if(position &lt; 0 || position &gt;= this.length){
        return null;
    }

    let current = this.head,
    index = 0,
    prev;

    if(position == 0){
        this.head = current.next;
    } else{
        while(index ++ &lt; position){
            prev = current;
            current = current.next;
        }
        prev.next = current.next;
    }
    this.length--;

    return current.data;
}

// index() : value 값을 갖는 노드 위치 반환
LinkedList.prototype.indexOf = function(value){
    let current = this.head,
    index = 0;

    while (current != null){
        if(current.data === value){
            return index;
        }

        index++;
        current = current.next;
    }

    return -1;
}

// remove2 = indexOf + removeAt = reomove
LinkedList.prototype.remove2 = function(value){
    let index = this.indexOf(value);
    return this. removeAt(index);
}

let ll = new LinkedList();

ll.insert(1);
ll.insert(10);
ll.insert(100);

ll.insert(2,1);
ll.insert(3,3)
ll.printNode();

console.log(ll.removeAt(1000));
console.log(ll.removeAt(1));
console.log(ll.removeAt(2));
console.log(ll.removeAt(100));

console.log(ll.remove2(1000));
ll.printNode();
console.log(ll.remove2(1));
ll.printNode();
console.log(ll.remove2(2));
ll.printNode();
console.log(ll.remove2(100));
ll.printNode();
console.log(ll.size());

--------------------------------------------
100 -&gt; 2 -&gt; 10 -&gt; 3 -&gt; 1 -&gt; null
null
2
3
null
null
100 -&gt; 10 -&gt; 1 -&gt; null
1
100 -&gt; 10 -&gt; null
null
100 -&gt; 10 -&gt; null
100
10 -&gt; null
1

-1이 안나와서 오류난거 찾고 고칠 예정</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[📚 수학 기본 이론]]></title>
            <link>https://velog.io/@frozen_land/%EC%88%98%ED%95%99-%EA%B8%B0%EB%B3%B8-%EC%9D%B4%EB%A1%A0</link>
            <guid>https://velog.io/@frozen_land/%EC%88%98%ED%95%99-%EA%B8%B0%EB%B3%B8-%EC%9D%B4%EB%A1%A0</guid>
            <pubDate>Wed, 16 Apr 2025 06:25:29 GMT</pubDate>
            <description><![CDATA[<h2 id="📊-알고리즘-복잡도">📊 알고리즘 복잡도</h2>
<h3 id="📈-알고리즘-성능-평가-지표">📈 알고리즘 성능 평가 지표</h3>
<ul>
<li>정확성</li>
<li>작업량</li>
<li>메모리 사용량</li>
<li>최족성</li>
<li>효율성<ul>
<li><strong>시간 복잡도</strong></li>
<li>공간 복잡도</li>
</ul>
</li>
</ul>
<hr>
<h2 id="⏱️-시간-복잡도">⏱️ 시간 복잡도</h2>
<ul>
<li><p>입력 크기의 값에 대해 단위 연산을 몇 번 수행하는지 계산하여, 알고리즘의 수행 시간을 평가하는 방법</p>
</li>
<li><p>3가지 점근적 표현범</p>
<ul>
<li><p>O(빅오) : <strong>최악의 상황</strong>을 고려하여 성능 측정결과표현
```js
function big_O(n){
  let sum = 0;
  sum = n *2;
  return sum;
}
3 -&gt; O(1)</p>
<p>function big_O(arr, n){
  let sum = 0;
  for(let i = 0 ; i &lt; n; i++){</p>
<pre><code>  sum+= arr[i];</code></pre><p>  }
  return sum;
}
n+2 -&gt; O(N)</p>
<p>function big_O(arr, n){
  let sum = 0;
  for(let i = 0 ; i &lt; n; i++){</p>
<pre><code>  for(let j = 0; j &lt; n ; j++){
      sum+= arr[i][j];
  }</code></pre><p>  }
  return sum;
}
n²+2 -&gt; O(N²)
n의 크기가 커질 수록 느려진다</p>
<p>function big_O(arr, n){
  let sum = 0;
  for(let i = 0 ; i &lt; n; i*=2){</p>
<pre><code>  sum+=2</code></pre><p>  }
  return sum;
}
n/2+2 -&gt; O(logN)</p>
</li>
<li><p>병합 정렬, 분할 정복할 때 logN이 많이 나온다</p>
</li>
<li><p>logN 많으면 많을 수록 특정 이상 값이 안올라간다</p>
</li>
<li><p>N 보다 빠른 알고리즘을 가지고있다.
```</p>
</li>
<li><p>θ(세타) : <strong>평균</strong>적인 경우에서의 성능 측정결과표현</p>
</li>
<li><p>Ω(오메가) : <strong>최선의 상황</strong>일 때의 성능 측정결과표현</p>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="🔢-경우의-수">🔢 경우의 수</h2>
<ul>
<li>어떤 사건 혹은 일이 일어날 수 있는 경우의 가짓수를 수로 표현</li>
<li>완전 탐색으로 경우의 수를 푸는 알고리즘<ul>
<li>순열</li>
<li>조합</li>
<li>중복 순열</li>
</ul>
</li>
</ul>
<h3 id="🔁-순열permutation">🔁 순열(Permutation)</h3>
<p>서로 다른 n개의 원소 중에서 r개를 중복 없이 골라 <strong>순서에 상관 있게</strong> 나열하는 경우의 수(nPr)
<img src="https://velog.velcdn.com/images/frozen_land/post/d9401bc6-452a-4639-9b56-5d55b57cb1f4/image.png" alt=""></p>
<h4 id="🧩-3개의-알파벳으로-단어를-만드는-경우의-수">🧩 3개의 알파벳으로 단어를 만드는 경우의 수</h4>
<pre><code class="language-js">let input = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;];
let count = 0;

// s: 지금 바꿀 위치(=고정할 자리), r : 마지막 고정할 자리 (여기선 2 → 0~2까지 총 3개 자리 고정)
function permutation(arr, s, r){
    // 1. 재귀함수를 멈춰야할 조건
    if(s == r){
        count++;
        console.log(arr.join(&quot; &quot;));
        return;
    }
    // 2. 재귀를 돌변서 변경되어야 될 부분/메인로직
    for(let i = s; i &lt; arr.length ; i++){
        [arr[s], arr[i]] = [arr[i], arr[s]]; // swap
        permutation(arr, s+1, r); // 요소 선택시 재귀함수 호출
        [arr[s], arr[i]] = [arr[i], arr[s]]; // swap 원상복구
    }

    /**
     s  r
     0  2   i=0 [&quot;a&quot;,]
     1  2   i=1 [&quot;a&quot;,&quot;b&quot;, ]
     2  2   [&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]
     ...
     1  2   i=2 [&quot;a&quot;,&quot;c&quot;,]
     2  2   [&quot;a&quot;,&quot;c&quot;,&quot;b&quot;]
     1  2   i=2 [&quot;a&quot;,&quot;b&quot;,]
     ...
     0  2   i=1 [&quot;b&quot;,&quot;a&quot;,&quot;c&quot;]
     ...
     0  2   i=0 [&quot;c&quot;,]
     */
}

permutation(input, 0, 2);
console.log(count)

--------------------------------------------------
OUTPUT
a b c
a c b
b a c
b c a
c b a
c a b
6</code></pre>
<hr>
<h3 id="🤝-조합combination">🤝 조합(Combination)</h3>
<p>서로 다른 n개의 원소중에서 r개를 중복 없이 골라 <strong>순서에 상관 없이</strong> 나열하는 경우의 수(nCr)
<img src="https://velog.velcdn.com/images/frozen_land/post/9ff7f606-6c1d-4cbf-986c-7aa64378236a/image.png" alt=""></p>
<h4 id="🃏-4개의-숫자-카드에서-2개를-뽑는-경우의-수">🃏 4개의 숫자 카드에서 2개를 뽑는 경우의 수</h4>
<ul>
<li>for문<pre><code class="language-js">let input = [1,2,3,4]; // 4C2
let count = 0;
</code></pre>
</li>
</ul>
<p>function combination(arr){
    // for -&gt; 뽑는 갯수 ==&gt; r ==&gt; 2
    for(let i = 0; i &lt; arr.length; i++){
        for(let j = i + 1; j&lt;arr.length; j++){
            count++;
            console.log(arr[i],arr[j])
        }
    }
}</p>
<p>combination(input, 0, 2);
console.log(count)</p>
<hr>
<p>OUTPUT
1 2
1 3
1 4
2 3
2 4
3 4
6</p>
<pre><code>- 재귀 함수
```js
let input = [1,2,3,4]; // 4C2
let output = [];
let count = 0;

function combination(arr, data, s, idx, r){
    if(s == r){
        count++;
        console.log(data)
        return;
    }
    for(let i = idx; arr.length - i &gt;= r - s ; i++){
        data[s] = arr[i]
        combination(arr, data, s + 1, i + 1, r)
    }
}

combination(input, output, 0, 0, 2);
console.log(count)

--------------------------------------------------
OUTPUT
[ 1, 2 ]
[ 1, 3 ]
[ 1, 4 ]
[ 2, 3 ]
[ 2, 4 ]
[ 3, 4 ]
6
</code></pre><hr>
<h2 id="🧮-점화식">🧮 점화식</h2>
<p>점화식(재귀식)이란 수열에서 이웃하는 두개의 항 사이에 성립하는 관계를 나타낸 관계식</p>
<ul>
<li>등차수열 : F(n) = F(n-1)+a     // a : 고정된 상수<pre><code class="language-js">//등차 수열 - for 문
let result;
</code></pre>
</li>
</ul>
<p>function forloop(s, t, number){
    let acc = 0;</p>
<pre><code>for(let i = 1; i &lt;=number ; i++){
    if( i == 1) {
        acc += s;
    } else{
        acc += t;
    }
    console.log(i, acc)
}
return acc;</code></pre><p>};</p>
<p>result = forloop(3, 2, 5)
console.log(result)</p>
<hr>
<p>OUTPUT
1 3
2 5
3 7
4 9
5 11
11</p>
<hr>
<hr>
<p>//등차 수열 - 재귀 함수
let result;</p>
<p>function recursive(s, t, number){
    // 멈출 조간
    if( number == 1){
        return s;
    }</p>
<pre><code>// 반복할 코드
return recursive(s, t, number-1) + t;</code></pre><p>};</p>
<p>result = recursive(3, 2, 5)
console.log(result)</p>
<hr>
<p>OUTPUT
11</p>
<p>number : 5 recursive(s, t, 4) + 2 =&gt; 9+2 =&gt; 11
number : 4 recursive(s, t, 3) + 2 =&gt; 7+2 =&gt; 9
number : 3 recursive(s, t, 2) + 2 =&gt; 5+2 =&gt; 7
number : 2 recursive(s, t, 1) + 2 =&gt; 3+2 =&gt; 5
number : 1 recursive(s, t, 1) + 2 =&gt; 3</p>
<pre><code>- 등비수열 : F(n) = F(n-1)*a

    ⇒ 등차수열 공식에서 `+ → *`로 바꾸면된다.

- 팩토리얼 : F(n) = F(n-1)*n
```js
    let reuslt;

    function recursive(number){
        if(number == 1){
            return number;
        }
        return recursive(number-1)*number;
    }

    reuslt = recursive(5);
    console.log(reuslt)

    --------------------------------------------------
    OUTPUT
    120
    5! = 5 X 4 X 3 X 2 X 1

    --------------------------------------------------
    --------------------------------------------------
    let reuslt;

    function recursive(number){
      let hap = 1;
      for( let i = 1 ; i &lt;= number; i++){
        hap *= i;
      }
      return hap;
    }

    reuslt = recursive(5);
    console.log(reuslt)

    --------------------------------------------------
    OUTPUT
    120</code></pre><ul>
<li><p>피보나치 수열 : F(n) = F(n-1)+F(n-2)</p>
<pre><code class="language-js">let reuslt;

function recursive(number){
  if(number == 1|| number == 0){
    return number;
  }

  return recursive(number - 1)+(number -2);
}

reuslt = recursive(5);
console.log(reuslt)

  --------------------------------------------------
OUTPUT
5

f(5) = f(4) + f(3) =&gt; 2 + 3 = 5
f(4) = f(3) + f(2) =&gt; 1 + 2 = 3
f(3) = f(2) + f(1) =&gt; 1 + 1 = 2
f(2) = f(1) + f(0) =&gt; 1 + 0 = 1
f(1) = 1
f(0) = 0</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[📦 배열이란?]]></title>
            <link>https://velog.io/@frozen_land/%EB%B0%B0%EC%97%B4%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@frozen_land/%EB%B0%B0%EC%97%B4%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Tue, 15 Apr 2025 11:13:41 GMT</pubDate>
            <description><![CDATA[<h1 id="📦-배열이란">📦 배열이란?</h1>
<ul>
<li>여러 <strong>값(Entity)</strong> 을 순차적으로 나열한 <strong>자료구조</strong></li>
<li>배열 내 각 값은 <strong>요소(element)</strong> 라고 하며, <strong>인덱스(index)</strong>를 통해 접근</li>
</ul>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/528773d2-e9c3-436b-a703-2d48198b2a2a/image.png" alt=""></p>
<hr>
<h2 id="🛠️-대표-속성과-메서드">🛠️ 대표 속성과 메서드</h2>
<h3 id="✔️-배열-크기-및-배열-여부-확인">✔️ 배열 크기 및 배열 여부 확인</h3>
<ul>
<li><code>Array.length</code></li>
<li><code>Array.isArray(value)</code></li>
</ul>
<h3 id="✔️-배열-추가삭제">✔️ 배열 추가/삭제</h3>
<ul>
<li><code>push()</code>, <code>pop()</code></li>
<li><code>shift()</code>, <code>unshift()</code></li>
<li><code>splice()</code>, <code>slice()</code></li>
</ul>
<h3 id="✔️-배열-탐색">✔️ 배열 탐색</h3>
<ul>
<li><code>indexOf()</code>, <code>lastIndexOf()</code></li>
<li><code>includes()</code></li>
</ul>
<h3 id="✔️-배열-변형-callback-미사용">✔️ 배열 변형 (callback 미사용)</h3>
<ul>
<li><code>sort()</code>, <code>reverse()</code>, <code>join()</code></li>
</ul>
<hr>
<h2 id="📌-배열-선언-접근-속성">📌 배열 선언, 접근, 속성</h2>
<h3 id="✅-선언">✅ 선언</h3>
<p>&quot;new Array()&quot; 혹은 &quot;[]&quot;를 통해 선언하며, 사이즈 혹은 값을 입력하여 초기화도 가능</p>
<pre><code class="language-js">  let arr_1 = new Array(10);
  let arr_2 = [];

  console.log(arr_1);
  console.log(arr_2);

  let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;];
  console.log(fruits);</code></pre>
<img src="https://velog.velcdn.com/images/frozen_land/post/9b16ccec-67af-40eb-89aa-3f0a5e11713e/image.png">

<h3 id="✅-접근">✅ 접근</h3>
<p>&quot;Array[index]&quot; 를 통해 index를 통하여 O(1) 접근</p>
<pre><code class="language-js">  console.log(fruits[0]); // apple
  console.log(fruits[1]); // orange
  console.log(fruits[2]); // melon</code></pre>
<h3 id="✅-길이-확인">✅ 길이 확인</h3>
<p>&quot;Array.length&quot; 를 통해 배열 요소의 개수 확인 가능</p>
<pre><code class="language-js">  console.log(fruits.length); // 3</code></pre>
<h3 id="✅-값-변경">✅ 값 변경</h3>
<pre><code class="language-js">fruits[1] = &quot;kiwi&quot;; 
console.log(fruits); // [&quot;apple&quot;, &quot;kiwi&quot;, &quot;melon&quot;]</code></pre>
<hr>
<h2 id="🧬-배열의-실체-해시-기반-객체">🧬 배열의 실체 (해시 기반 객체)</h2>
<ul>
<li><p>자바스크립트에서 배열은 일반 배열이 아닌 <strong>Hash 기반의 객체</strong></p>
</li>
<li><p>메모리는 <strong>비연속적인 희소 배열(sparse array)</strong> 형태로 구성됨</p>
<pre><code class="language-js">let nums = [];

nums[0] = &quot;one&quot;;
nums[1] = &quot;two&quot;;

console.log(nums.length);
console.log(nums);</code></pre>
<img src="https://velog.velcdn.com/images/frozen_land/post/81dd6124-8053-4ba7-8fe8-7d7587ea8994/image.png">

<pre><code class="language-js">let nums = [];

nums[0] = &quot;one&quot;;
nums[1] = &quot;two&quot;;

nums[&quot;once&quot;] = &quot;once&quot;;
nums[&quot;twice&quot;] = &quot;twice&quot;;

console.log(nums.length);
console.log(nums);

console.log(Object.getOwnPropertyDescriptors(nums));</code></pre>
<img src="https://velog.velcdn.com/images/frozen_land/post/ee3962fb-093e-4b88-8999-e1143026fa13/image.png">

</li>
</ul>
<blockquote>
<p>nums[0], nums[1] 은 배열의 인덱스를 채운 것이고
nums[&quot;once&quot;], nums[&quot;twice&quot;] 은 객체 속성(키)를 추가한 것이다.
그래서 길이가 2인것 은 배열의 인덱스를 가르키고 비연속적인 희소 배열로 생성된 걸 알 수 있다</p>
</blockquote>
<hr>
<h2 id="🔍-배열-타입-확인">🔍 배열 타입 확인</h2>
<ul>
<li><p><code>Array.isArray(value)</code></p>
<pre><code class="language-js">let num = 123.456;
let str = &quot;here i am&quot;;
let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;];

console.log(Array.isArray(num)); //false
console.log(Array.isArray(str)); //false
console.log(Array.isArray(fruits)); // true</code></pre>
</li>
</ul>
<h2 id="❌-배열-일부-요소-삭제">❌ 배열 일부 요소 삭제</h2>
<ul>
<li><p><code>delete array[index]</code>
➡️ 요소를 삭제를 해도 배열 사이즈가 그대로인 문제점이 있다</p>
<pre><code class="language-js">let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;];

console.log(fruits);
console.log(fruits.length);

delete fruits[1];

console.log(fruits);
console.log(fruits.length);</code></pre>
<img src="https://velog.velcdn.com/images/frozen_land/post/738bd392-f5e2-4308-81bc-63cc86656ed8/image.png">

</li>
</ul>
<h2 id="🔁-배열-추가삭제">🔁 배열 추가/삭제</h2>
<h3 id="🔸-lifo-last-in-first-out---back">🔸 LIFO (Last-In First-Out) - Back</h3>
<ul>
<li><p><code>Array.push(element) // 추가</code></p>
</li>
<li><p><code>Array.pop() // 삭제</code></p>
<pre><code class="language-js">let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;];

fruits.push(&quot;watermelon&quot;);
console.log(fruits); // [ &#39;apple&#39;, &#39;orange&#39;, &#39;melon&#39;, &#39;watermelon&#39;]
console.log(fruits.length); // 4

fruits.pop();
console.log(fruits); // [ &#39;apple&#39;, &#39;orange&#39;, &#39;melon&#39; ]
console.log(fruits.length); // 3
</code></pre>
</li>
</ul>
<h3 id="🔸-lifo-last-in-first-out---front">🔸 LIFO (Last-In First-Out) - Front</h3>
<ul>
<li><p><code>Array.unshift(element)  // 추가</code></p>
</li>
<li><p><code>Array.shift() // 삭제</code></p>
<pre><code class="language-js">let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;];

fruits.unshift(&quot;watermelon&quot;);
console.log(fruits); // [ &#39;watermelon&#39;, &#39;apple&#39;, &#39;orange&#39;, &#39;melon&#39; ]
console.log(fruits.length); // 4

fruits.shift();
console.log(fruits); // [ &#39;apple&#39;, &#39;orange&#39;, &#39;melon&#39; ]
console.log(fruits.length); // 3
</code></pre>
</li>
</ul>
<h2 id="✂️-배열-요소-삭제삽입">✂️ 배열 요소 삭제/삽입</h2>
<h3 id="✔️-arraysliceindexdeletecount-elem1---elemn">✔️ Array.slice(index[,deleteCount, elem1, ... , elemN])</h3>
<pre><code class="language-js">  let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;];
  let ret;

  ret = fruits.splice(1); 
  console.log(ret); // [ &#39;orange&#39;, &#39;melon&#39; ]
  console.log(fruits); // [ &#39;apple&#39; ]

  fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;, &quot;strawberry&quot;];
  ret = fruits.splice(1, 1);
  console.log(ret); // [ &#39;orange&#39; ]
  console.log(fruits); // [ &#39;apple&#39;, &#39;melon&#39;, &#39;strawberry&#39; ]

  ret = fruits.splice(1, 1, &quot;mango&quot;, &quot;kiwi&quot;); // melon 위치에 &quot;mango&quot;, &quot;kiwi&quot;가
  console.log(ret); // [ &#39;melon&#39; ]
  console.log(fruits); // [ &#39;apple&#39;, &#39;mango&#39;, &#39;kiwi&#39;, &#39;strawberry&#39; ]</code></pre>
<h3 id="✔️-slicestart-end---원본-유지">✔️ slice(start, end) - 원본 유지</h3>
<pre><code class="language-js">let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;];

console.log(fruits.slice(1)); // [ &#39;orange&#39;, &#39;melon&#39; ]
console.log(fruits); // [ &#39;apple&#39;, &#39;orange&#39;, &#39;melon&#39; ]

console.log(fruits.slice(1, 2)); // [ &#39;orange&#39; ]
console.log(fruits.slice(-2)); // [ &#39;orange&#39;, &#39;melon&#39; ]
</code></pre>
<h3 id="✔️-arrayconcatarg1-arg2">✔️ Array.concat(arg1, arg2)</h3>
<pre><code class="language-js">let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;];
let fruits_add = [&quot;cherry&quot;, &quot;banana&quot;];

console.log(fruits.concat(fruits_add)); // [ &#39;apple&#39;, &#39;orange&#39;, &#39;melon&#39;, &#39;cherry&#39;, &#39;banana&#39; ]
console.log(fruits); // [ &#39;apple&#39;, &#39;orange&#39;, &#39;melon&#39; ]
</code></pre>
<hr>
<h2 id="🔁-배열-반복문">🔁 배열 반복문</h2>
<ul>
<li>다양한 반복문 문법을 통해 배열 요소에 접근 가능</li>
<li>반복문 문법
  •    <code>for + length</code>: <strong>index</strong> 접근
  •    <code>for...of</code>: <strong>element</strong> 접근
  •    <code>for...in</code>: <strong>key(index)</strong> 접근<pre><code class="language-js">let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;melon&quot;];
</code></pre>
</li>
</ul>
<p>for (let i = 0; i &lt; fruits.length; i++) {
  console.log(fruits[i]);
  // apple
  // orange
  // melon
}</p>
<p>for (let fruit of fruits) {
  console.log(fruit);
  // apple
  // orange
  // melon
}</p>
<p>for (let key in fruits) {
  console.log(key);
  // 0
  // 1
  // 2
  console.log(fruits[key]);
  // apple
  // orange
  // melon
}</p>
<pre><code>---
## 🔍 배열 탐색
- index탐색(앞에서부터) : `Array.indexOf(item, from)`
- index탐색(뒤에서부터) : `Array.lastIndexOf(item, from)`
- 값 포함 여부 확인(true/fasle) : `Array.includes(item,from)`
```js
let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;banana&quot;, &quot;orange&quot;, &quot;melon&quot;];

console.log(fruits.indexOf(&quot;orange&quot;)); // 1
console.log(fruits.indexOf(&quot;Orange&quot;)); // -1 : 배열 내에 없다
console.log(fruits.indexOf(&quot;orange&quot;, 2)); // 3

console.log(fruits.lastIndexOf(&quot;orange&quot;)); // 3
console.log(fruits.lastIndexOf(&quot;orange&quot;, -3)); // 1
console.log(fruits.lastIndexOf(&quot;orange&quot;, 0)); // -1

console.log(fruits.includes(&quot;banana&quot;)); // true
console.log(fruits.includes(&quot;watermelon&quot;)); // false
console.log(fruits.includes(&quot;Banana&quot;)); // false
</code></pre><h2 id="🔃-배열-정렬--반전">🔃 배열 정렬 / 반전</h2>
<p>➡️ sort()와 reverse()는 원본 배열 자체를 변경함</p>
<ul>
<li>배열 정렬 : <code>Array.sort()</code></li>
<li>배열 반전 : <code>Array.reverse()</code><pre><code class="language-js">let nums = [1, -1, 4, 5, 2, 0];
</code></pre>
</li>
</ul>
<p>console.log(nums.sort()); // [ -1, 0, 1, 2, 4, 5 ] 오름차순으로 정렬한 nums를
console.log(nums.reverse()); // [ 5, 4, 2, 1, 0, -1 ] 반전시킨 형태
console.log(nums); // [ 5, 4, 2, 1, 0, -1 ]</p>
<p>let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;banana&quot;, &quot;melon&quot;];</p>
<p>console.log(fruits.sort()); // [ &#39;apple&#39;, &#39;banana&#39;, &#39;melon&#39;, &#39;orange&#39; ]
console.log(fruits.reverse()); // [ &#39;orange&#39;, &#39;melon&#39;, &#39;banana&#39;, &#39;apple&#39; ]
console.log(fruits); // [ &#39;orange&#39;, &#39;melon&#39;, &#39;banana&#39;, &#39;apple&#39; ]</p>
<pre><code>
## 🔄 배열 변환
➡️ 원본 데이터에 영향을 미친다.
- 배열 값을 문자열로 변환 : `Array.join(separator)`
```js
let fruits = [&quot;apple&quot;, &quot;orange&quot;, &quot;banana&quot;, &quot;melon&quot;];
let str = fruits.join();
console.log(str); // apple,orange,banana,melon ➡️ &quot;,&quot;가 기본값

let str_separator = fruits.join(&quot;;&quot;);
console.log(str_separator); // apple;orange;banana;melon
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[🧠 자바스크립트 자료형(Data Type)]]></title>
            <link>https://velog.io/@frozen_land/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9E%90%EB%A3%8C%ED%98%95Data-Type</link>
            <guid>https://velog.io/@frozen_land/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9E%90%EB%A3%8C%ED%98%95Data-Type</guid>
            <pubDate>Mon, 14 Apr 2025 14:16:06 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-자료형이란">📌 자료형이란?</h2>
<ul>
<li><strong>데이터의 종류</strong></li>
<li>자바스크립트는 총 <strong>7개의 기본 타입(6개의 원시타입 + 1개의 객체 타입)</strong>을 가지고 있습니다.</li>
</ul>
<hr>
<h2 id="🔹-원시-타입-primitive-type">🔹 원시 타입 (Primitive Type)</h2>
<table>
<thead>
<tr>
<th>타입</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>boolean</strong></td>
<td><code>true</code> / <code>false</code> (조건문, 논리 판단 기준)</td>
</tr>
<tr>
<td><strong>null</strong></td>
<td>&quot;없음&quot;을 의미하는 값 (개발자가 명시적으로 지정)</td>
</tr>
<tr>
<td><strong>undefined</strong></td>
<td>값이 할당되지 않은 변수의 기본 값</td>
</tr>
<tr>
<td><strong>number</strong></td>
<td>정수, 실수 등 숫자형</td>
</tr>
<tr>
<td><strong>string</strong></td>
<td>텍스트 데이터</td>
</tr>
<tr>
<td><strong>symbol</strong></td>
<td>고유한 식별자를 만들 때 사용 (ES6)</td>
</tr>
<tr>
<td><strong>BigInt</strong></td>
<td>매우 큰 정수를 표현할 수 있는 타입 (<code>123n</code> 형식)</td>
</tr>
</tbody></table>
<h2 id="🔸-객체-타입-object-type">🔸 객체 타입 (Object Type)</h2>
<ul>
<li>두 개 이상의 복잡한 개체를 저장하는 데 사용</li>
<li>{} 중괄호로 생성하며, key-value 쌍으로 구성</li>
<li>다수의 원시자료형을 포함하거나 복잡한 개체(Entity)를 표현할 수 있는 자료형</li>
<li>접근은 objecy.key형태로 표현</li>
<li>변수를 <strong>주소값</strong>에 넣어서 저장</li>
</ul>
<pre><code class="language-js">let user = {
  name : &quot;John&quot;,
  age : 27
}</code></pre>
<h3 id="✅-객체-접근">✅ 객체 접근</h3>
<pre><code class="language-js">console.log(user.name); -&gt; OUTPUT : John
-&gt; user라는 위치에서 name이라는 번지를 찾는다</code></pre>
<h3 id="✅-객체-추가">✅ 객체 추가</h3>
<pre><code class="language-js">user.weight = 72;</code></pre>
<h3 id="✅-객체-삭제">✅ 객체 삭제</h3>
<pre><code class="language-js">delete user.weight;</code></pre>
<h3 id="⚠️-객체-복사-시-문제점">⚠️ 객체 복사 시 문제점</h3>
<ul>
<li>객체는 <strong>주소값을 참조</strong>하므로, 복사 후 값을 변경하면 <strong>원본도 함께 변경됨</strong></li>
</ul>
<h3 id="👏🏻-복사-문제점-해결-방안">👏🏻 복사 문제점 해결 방안</h3>
<h4 id="✅-얕은-복사shallow-copy">✅ 얕은 복사(Shallow Copy)</h4>
<ul>
<li>내부 객체는 <strong>참조만</strong> 복사되므로 한 단계까지만 복사<ul>
<li>for 문</li>
<li>Object.assign(복사할 곳, 복사할 값)</li>
<li>spread 연산자</li>
<li>❗ 중첩 객체가 있을 경우 내부까지 복사되지 않음<h4 id="✅-깊은-복사-deep-copy">✅ 깊은 복사 (Deep Copy)</h4>
</li>
</ul>
</li>
<li>내부 객체까지 <strong>완전히 복사</strong></li>
<li>재귀 함수</li>
<li>JSON.parse(JSON.stringify(obj)) (단점: 함수/심볼 누락) ➡️ 서버와 데이터를 주고받을때 주로 사용</li>
</ul>
<hr>
<h2 id="📏-자료형-확인-방법">📏 자료형 확인 방법</h2>
<pre><code class="language-js">typeof 123; // &quot;number&quot;
typeof null; // &quot;object&quot; ❗ (자바스크립트 설계상 버그)
typeof undefined; // &quot;undefined&quot;
typeof {} // &quot;object&quot;
typeof [] // &quot;object&quot;
typeof (() =&gt; {}) // &quot;function&quot;</code></pre>
<blockquote>
<p>❗ typeof null은 “object”로 나오는 <strong>역사적 버그</strong>입니다.
배열과 객체는 모두 &quot;object&quot;로 나오므로 주의!</p>
</blockquote>
<hr>
<h2 id="🔄-형-변환-type-conversion">🔄 형 변환 (Type Conversion)</h2>
<ul>
<li>느슨한 타입 언어 혹은 동적 타입 언어로 변수의 자료형은 명시적으로 선언할 필요가 없는 언어</li>
</ul>
<h3 id="✔️-암묵적-형-변환-자동">✔️ 암묵적 형 변환 (자동)</h3>
<p>자바스크립트는 동적 타입 언어이므로 상황에 따라 자동으로 형 변환을 수행</p>
<pre><code class="language-js">&quot;5&quot; * 2    // 10 (string → number)
true + 1   // 2  (boolean → number)</code></pre>
<h3 id="✔️-명시적-형-변환-강제">✔️ 명시적 형 변환 (강제)</h3>
<h4 id="🔡-문자열로-변환--string">🔡 문자열로 변환 : String()</h4>
<pre><code class="language-js">String(123); // &quot;123&quot;
123 + &quot;&quot;;     // &quot;123&quot; (암묵적)</code></pre>
<p>으로 형변환</p>
<h4 id="🔢-문자열로-변환--number">🔢 문자열로 변환 : Number()</h4>
<ul>
<li>parseInt() -&gt; 정수 변환</li>
<li>parseFloat -&gt; 실수 변환
```js
Number(&quot;123&quot;);      // 123
parseInt(&quot;123.45&quot;); // 123
parseFloat(&quot;123.45&quot;); // 123.45</li>
<li>&quot;123&quot;;              // 123 (단항 연산자)<pre><code></code></pre></li>
</ul>
<h4 id="❗️-boolean으로-변환--boolean">❗️ Boolean으로 변환 : Boolean()</h4>
<ul>
<li>False 가 나오는 값 : 빈 문자열 , NaN, Null, undefined<pre><code class="language-js">Boolean(&quot;hello&quot;); // true
Boolean(&quot;&quot;);      // false</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[🍪 쿠키(Cookie)]]></title>
            <link>https://velog.io/@frozen_land/%EC%BF%A0%ED%82%A4Cookie</link>
            <guid>https://velog.io/@frozen_land/%EC%BF%A0%ED%82%A4Cookie</guid>
            <pubDate>Tue, 08 Apr 2025 14:50:26 GMT</pubDate>
            <description><![CDATA[<h2 id="🍪-쿠키cookie란">🍪 쿠키(Cookie)란?</h2>
<p>브라우저에 저장되는 <strong>작은 크기의 문자열 데이터</strong>입니다.<br>웹 서버와 클라이언트(브라우저) 간의 상태 유지를 위한 수단으로 사용됩니다.  </p>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/c4ac0155-b776-4cc8-a6da-07a7b7a3aec1/image.png" alt=""></p>
<h3 id="📝-쿠키-용도">📝 쿠키 용도</h3>
<p>• 로그인 유지 (자동 로그인 기능)
• 사용자 맞춤 설정 저장 (다크모드 등)
• 장바구니 정보 유지
• 방문 횟수 기록</p>
<hr>
<h3 id="🧾-쿠키-구성-요소">🧾 쿠키 구성 요소</h3>
<table>
<thead>
<tr>
<th>속성</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>Name</strong></td>
<td>쿠키의 키 (예: <code>user</code>)</td>
</tr>
<tr>
<td><strong>Value</strong></td>
<td>쿠키의 값 (예: <code>wonji</code>)</td>
</tr>
<tr>
<td><strong>Domain</strong></td>
<td>쿠키가 유효한 도메인</td>
</tr>
<tr>
<td><strong>Path</strong></td>
<td>쿠키가 접근 가능한 경로</td>
</tr>
<tr>
<td><strong>Expires / Max-Age</strong></td>
<td>쿠키의 만료일 / 유효 기간</td>
</tr>
<tr>
<td><strong>HttpOnly</strong></td>
<td>자바스크립트에서 접근 불가능, <strong>보안 강화용</strong></td>
</tr>
<tr>
<td><strong>Secure</strong></td>
<td>HTTPS 환경에서만 전송 가능</td>
</tr>
</tbody></table>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/8769d7b7-a01c-420f-a6c6-45e428fc773e/image.png" alt=""></p>
<hr>
<h2 id="✍️-쿠키-사용-방법">✍️ 쿠키 사용 방법</h2>
<h3 id="1️⃣-쿠키-쓰기">1️⃣ 쿠키 쓰기</h3>
<h4 id="🔹-클라이언트-측-쿠키-생성-javascript">🔹 클라이언트 측 쿠키 생성 (JavaScript)</h4>
<pre><code class="language-js">document.cookie = &quot;name=wonji; path=/; max-age=3600&quot;;</code></pre>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/8ef399f6-ac10-4da9-b89e-e3030d07963a/image.png" alt=""></p>
<h4 id="🔹-서버-측-쿠키-생성-예시">🔹 서버 측 쿠키 생성 (예시)</h4>
<pre><code class="language-js">response.setHeader(&quot;Set-Cookie&quot;, &quot;name=wonji; path=/; max-age=3600&quot;);</code></pre>
<blockquote>
<p>서버에서 Set-Cookie 헤더를 사용하여 클라이언트에 쿠키 전송</p>
</blockquote>
<h3 id="🔍-쿠키-접근-읽기">🔍 쿠키 접근 (읽기)</h3>
<pre><code class="language-js">document.cookie</code></pre>
<p><img src="https://velog.velcdn.com/images/frozen_land/post/e2c4df8c-d172-4281-921e-29330b0b97bb/image.png" alt=""></p>
<blockquote>
<p>현재 페이지에서 사용 가능한 모든 쿠키를 문자열 형태로 반환합니다.</p>
</blockquote>
<h3 id="❌-쿠키-삭제">❌ 쿠키 삭제</h3>
<pre><code class="language-js">// 쿠키 만료시켜서 삭제
document.cookie = &quot;max-age=0&quot;</code></pre>
<blockquote>
<p>max-age=0 또는 expires=과거 날짜로 설정하면 해당 쿠키 삭제됨</p>
</blockquote>
<h3 id="📤-쿠키-전송-요청-시-포함">📤 쿠키 전송 (요청 시 포함)</h3>
<pre><code class="language-js">// 쿠키를 포함하여 서버에 요청 전송
fetch(URL,{
  credentials : &#39;include&#39;;
});</code></pre>
<blockquote>
<p>credentials: &#39;include&#39; 설정 시, 쿠키를 요청 헤더에 자동으로 포함</p>
</blockquote>
<hr>
<h3 id="📍-쿠키-vs-세션-차이점">📍 쿠키 vs 세션 차이점</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>쿠키 (Cookie)</th>
<th>세션 (Session)</th>
</tr>
</thead>
<tbody><tr>
<td><strong>저장 위치</strong></td>
<td>클라이언트(브라우저)</td>
<td>서버</td>
</tr>
<tr>
<td><strong>보안성</strong></td>
<td>낮음 (브라우저에 저장되므로 노출 위험 있음)</td>
<td>비교적 높음 (서버에서 관리)</td>
</tr>
<tr>
<td><strong>만료 시점</strong></td>
<td>클라이언트가 설정한 <code>expires</code> / <code>max-age</code> 기준</td>
<td>서버에서 설정한 시간 또는 브라우저 종료 시</td>
</tr>
<tr>
<td><strong>저장 용량</strong></td>
<td>약 4KB 제한</td>
<td>용량 제한 없음 (서버 용량에 따라 다름)</td>
</tr>
<tr>
<td><strong>속도</strong></td>
<td>서버에 접근하지 않으므로 빠름</td>
<td>서버에 접근해야 하므로 비교적 느림</td>
</tr>
<tr>
<td><strong>사용 목적</strong></td>
<td>로그인 유지, 사용자 설정, 장바구니 등</td>
<td>로그인 상태 유지, 사용자 인증 정보 저장 등</td>
</tr>
<tr>
<td><strong>유지 방식</strong></td>
<td>클라이언트가 모든 요청에 쿠키를 자동 전송</td>
<td>클라이언트는 세션 ID만 저장하고 서버가 데이터 보관</td>
</tr>
</tbody></table>
<blockquote>
<p>💡 일반적으로 <strong>보안이 중요한 정보는 세션</strong>,  
<strong>간단한 사용자 설정 정보는 쿠키</strong>에 저장하는 것이 좋습니다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[🧩 자바스크립트 모듈 시스템 정리]]></title>
            <link>https://velog.io/@frozen_land/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%AA%A8%EB%93%88-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@frozen_land/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%AA%A8%EB%93%88-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 07 Apr 2025 14:25:42 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-모듈이란">📌 모듈이란?</h2>
<blockquote>
<p><strong>모듈(Module)</strong>은 하나의 큰 프로그램을 구성하는 <strong>독립된 파일 단위</strong>입니다.<br>여러 파일로 어플리케이션을 분리하고, <strong>각각의 파일을 모듈</strong>이라 부릅니다.</p>
</blockquote>
<ul>
<li>코드 재사용을 높이고  </li>
<li>유지보수를 쉽게 하며  </li>
<li>전역 스코프 오염을 방지합니다.</li>
</ul>
<hr>
<h2 id="✅-모듈-사용하는-방법">✅ 모듈 사용하는 방법</h2>
<p>배열에 다양한 동물 이름을 담고, 각 동물에 맞는 울음소리를 출력하는 예제를 통해 알아볼게요.</p>
<hr>
<h3 id="1-📤-모듈-내보내기-export">1. 📤 모듈 내보내기 (export)</h3>
<p><code>example1.mjs</code></p>
<pre><code class="language-js">// 강아지 울음소리
export const dog = () =&gt; {
  return &quot;bow-wow&quot;;
};</code></pre>
<p><code>example2.mjs</code></p>
<pre><code class="language-js">// 고양이 울음소리
export const cat = () =&gt; {
  return &quot;meow&quot;;
};</code></pre>
<h3 id="2-📥-모듈-가져오기-import">2. 📥 모듈 가져오기 (import)</h3>
<pre><code class="language-js">import { dog } from &quot;./example1.mjs&quot;;
import { cat } from &quot;./example2.mjs&quot;;</code></pre>
<h3 id="3-🛡️-모듈-시스템의-장점">3. 🛡️ 모듈 시스템의 장점</h3>
<p>•    내보내지 않은 변수/함수는 외부에서 접근 불가
•    캡슐화를 통해 외부로부터 자원 보호
•    코드 충돌 방지</p>
<h3 id="4-💻-전체-예제-코드">4. 💻 전체 예제 코드</h3>
<pre><code class="language-js">import { dog } from &quot;./example1.mjs&quot;;
import { cat } from &quot;./example2.mjs&quot;;

const animals = [&quot;dog&quot;, &quot;cat&quot;, &quot;rabbit&quot;, &quot;cow&quot;, &quot;bird&quot;];

animals.forEach((animal) =&gt; {
  if (animal === &quot;dog&quot;) {
    console.log(`${animal} is `, dog());
  } else if (animal === &quot;cat&quot;) {
    console.log(`${animal} is `, cat());
  } else {
    console.log(`${animal} is search plz`);
  }
});</code></pre>
<hr>
<h2 id="🖨️-출력-결과">🖨️ 출력 결과</h2>
<img src="https://velog.velcdn.com/images/frozen_land/post/d4ca50cd-853d-458e-a65c-e92a9e7a5bc3/image.png">

<hr>
<h2 id="✚-추가-내용">✚ 추가 내용</h2>
<h3 id="📄-mjs-확장자란">📄 <code>.mjs</code> 확장자란?</h3>
<blockquote>
<p><code>.mjs</code>는 <strong>&quot;module JavaScript&quot;</strong>의 줄임말로,<br><strong>ES6 모듈을 사용하고 있다는 것을 명시하는 파일 확장자</strong>입니다.</p>
</blockquote>
<h3 id="✅-사용-이유">✅ 사용 이유</h3>
<ul>
<li>브라우저 또는 Node.js에서 해당 파일이 <strong>모듈 형식</strong>이라는 걸 명확히 하기 위해 사용합니다.</li>
<li>특히 <strong>Node.js</strong>에서는 <code>.js</code> 확장자만으로는 모듈인지 스크립트인지 구분이 어려워 <code>.mjs</code>를 사용합니다.</li>
</ul>
<h3 id="✅-예시">✅ 예시</h3>
<pre><code class="language-bash">node example.mjs</code></pre>
<blockquote>
<p>.html 없이도 터미널에서 직접 실행이 가능하며 모듈을 사용할 수 있습니다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[📖 Javascript 란?]]></title>
            <link>https://velog.io/@frozen_land/Javascript-%EB%9E%80</link>
            <guid>https://velog.io/@frozen_land/Javascript-%EB%9E%80</guid>
            <pubDate>Mon, 17 Mar 2025 10:46:56 GMT</pubDate>
            <description><![CDATA[<h2 id="🚀-자바스크립트javascript란">🚀 자바스크립트(JavaScript)란?</h2>
<ul>
<li><strong>객체 기반의 스크립트 프로그래밍 언어</strong></li>
<li><strong>웹 페이지에 생동감을 불어넣기 위해</strong> 만들어진 프로그래밍 언어</li>
<li>자바스크립트로 작성한 프로그램을 <strong>스크립트(script)</strong> 라고 함</li>
<li><strong>웹페이지의 HTML 안에 작성 가능</strong>하며, 페이지가 로드될 때 자동 실행됨</li>
</ul>
<hr>
<h2 id="📌-자바스크립트의-특징">📌 자바스크립트의 특징</h2>
<h3 id="✅-브라우저에서-자바스크립트로-할-수-있는-일">✅ 브라우저에서 자바스크립트로 할 수 있는 일</h3>
<ul>
<li>페이지에 새로운 HTML을 추가하거나 <strong>기존 HTML 및 스타일 수정</strong></li>
<li><strong>사용자의 행동</strong> (마우스 클릭, 키보드 입력 등)에 반응하기</li>
<li>네트워크를 통해 원격 서버에 요청을 보내거나, 파일 다운로드 및 업로드하기</li>
<li><strong>쿠키</strong>를 가져오거나 설정하기, 사용자에게 질문을 건네거나 메시지를 보여주기</li>
<li><strong>클라이언트 측에 데이터 저장</strong>하기 (로컬 스토리지)</li>
</ul>
<h3 id="❌-브라우저에서-자바스크립트로-할-수-없는-일">❌ 브라우저에서 자바스크립트로 할 수 없는 일</h3>
<ul>
<li>웹페이지 내 스크립트는 <strong>디스크에 저장된 임의의 파일을 읽거나 실행하는 것이 제한됨</strong><blockquote>
<p>카메라나 마이크 같은 디바이스와 상호 작용하려면 <strong>사용자의 명시적인 허가</strong>가 필요함</p>
</blockquote>
</li>
<li><strong>브라우저 내 다른 탭과 창의 정보 접근 불가</strong><blockquote>
<p>단, 자바스크립트로 새 창을 열 경우 예외가 적용되지만, <strong>도메인, 프로토콜, 포트가 다르면 접근 불가</strong></p>
</blockquote>
</li>
<li>자바스크립트는 서버와 쉽게 정보를 주고받을 수 있지만, <strong>타 사이트나 도메인의 데이터 접근은 불가능</strong><blockquote>
<p>원격 서버에서 <strong>명확하게 승인(CORS 설정)</strong> 해야 함</p>
</blockquote>
</li>
</ul>
<hr>
<h2 id="📜-자바스크립트의-배경">📜 자바스크립트의 배경</h2>
<p>자바스크립트는 <strong>빠르게 개발되고, 개방적이며, 많은 사람들이 사용할 수 있도록 설계됨</strong><br>다양한 언어의 장점을 결합하여 만들어짐  </p>
<table>
<thead>
<tr>
<th>기여한 언어</th>
<th>특징</th>
</tr>
</thead>
<tbody><tr>
<td><strong>자바(Java)</strong></td>
<td>문법 구조</td>
</tr>
<tr>
<td><strong>스키마(Scheme)</strong></td>
<td>일급 객체, 클로저</td>
</tr>
<tr>
<td><strong>하이퍼토크(HyperTalk)</strong></td>
<td>브라우저 이벤트 처리</td>
</tr>
<tr>
<td><strong>펄(Pearl), 파이썬(Python)</strong></td>
<td>문자열, 배열, 정규표현식</td>
</tr>
<tr>
<td><strong>셀프(Self)</strong></td>
<td>프로토타입 확장</td>
</tr>
<tr>
<td><strong>오크(Oak)</strong></td>
<td>함수</td>
</tr>
</tbody></table>
<hr>
<h2 id="🎯-ecmascript와-javascript">🎯 ECMAScript와 JavaScript</h2>
<p><strong>JavaScript는 프로그래밍 언어이고, ECMAScript(ES)는 JavaScript의 명세(표준)</strong>  </p>
<table>
<thead>
<tr>
<th>용어</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong>JavaScript</strong></td>
<td>프로그래밍 언어</td>
</tr>
<tr>
<td><strong>ECMAScript</strong></td>
<td>JavaScript의 표준 명세</td>
</tr>
<tr>
<td><strong>TC39</strong></td>
<td>ECMAScript 표준을 관리하는 조직</td>
</tr>
<tr>
<td><strong>Babel</strong></td>
<td>최신 JavaScript를 하위 버전에서도 사용할 수 있도록 변환하는 도구</td>
</tr>
</tbody></table>
<h3 id="🔹-ecmascript-버전">🔹 ECMAScript 버전</h3>
<ul>
<li><strong>ES1, ES2, ES3...</strong> 최신 버전으로 발전 중</li>
<li>ES6(ES2015) 이후 화살표 함수, <code>let</code>, <code>const</code>, <code>Promise</code> 등 추가됨</li>
</ul>
<hr>
<h2 id="🌍-자바스크립트-everywhere">🌍 자바스크립트 Everywhere</h2>
<table>
<thead>
<tr>
<th>분야</th>
<th>기술</th>
</tr>
</thead>
<tbody><tr>
<td><strong>브라우저</strong></td>
<td>IE, Chrome, Firefox (V8 엔진)</td>
</tr>
<tr>
<td><strong>서버</strong></td>
<td>Node.js</td>
</tr>
<tr>
<td><strong>패키지 매니저</strong></td>
<td>npm</td>
</tr>
<tr>
<td><strong>AJAX</strong></td>
<td>비동기 데이터 요청</td>
</tr>
<tr>
<td><strong>라이브러리</strong></td>
<td>jQuery, JSON, React</td>
</tr>
</tbody></table>
<h3 id="⚡-v8-엔진--nodejs">⚡ V8 엔진 &amp; Node.js</h3>
<ul>
<li><strong>V8 엔진</strong> : Google Chrome에서 사용하는 JavaScript 엔진  </li>
<li><strong>Node.js</strong> : Chrome V8 엔진을 기반으로 한 JavaScript 런타임 ➡️ 자바스크립트를 실행시켜줄 수 있는 환경 ➡️ <strong>환경을</strong> 통해서 서버를 구축 <pre><code class="language-javascript">console.log(&quot;Hello, Node.js!&quot;);</code></pre>
</li>
</ul>
<h3 id="📲-javascript의-활용">📲 JavaScript의 활용</h3>
<ul>
<li>Facebook 앱 : React로 개발됨</li>
<li>Electron : 자바스크립트를 사용해 데스크탑 애플리케이션 개발 가능</li>
<li>VSCode, Slack, Notion 모두 Electron 기반</li>
<li>개발자 도구(F12)에서 자바스크립트 코드 확인 가능</li>
</ul>
<h3 id="🚀-크로스-플랫폼-개발-가능">🚀 크로스 플랫폼 개발 가능</h3>
<ul>
<li>HTML + CSS + JavaScript 활용 → 다양한 플랫폼에서 사용 가능</li>
<li>React Native : 모바일 앱 개발</li>
<li>Electron : 데스크탑 앱 개발 (Windows, Mac 지원)</li>
<li>Node.js : 서버 개발</li>
</ul>
<hr>
<h4 id="📚-참고-문헌">📚 참고 문헌</h4>
<p><a href="https://ko.javascript.info/intro">🔗 JAVASCRIPT.INFO</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTML] 텍스트 요소 02]]></title>
            <link>https://velog.io/@frozen_land/HTML-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%9A%94%EC%86%8C-02</link>
            <guid>https://velog.io/@frozen_land/HTML-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%9A%94%EC%86%8C-02</guid>
            <pubDate>Wed, 05 Mar 2025 06:30:50 GMT</pubDate>
            <description><![CDATA[<h1 id="✨-formatting-텍스트-형식">✨ Formatting (텍스트 형식)</h1>
<h2 id="📌-굵은-글씨-요소--b-strong">📌 굵은 글씨 요소 : <code>&lt;b&gt;</code>, <code>&lt;strong&gt;</code></h2>
<p>독자의 주의를 요소의 콘텐츠로 끌기 위한 용도로 사용하며, 특정 부분만 굵게 표시합니다.</p>
<pre><code>&lt;p&gt;
    This article describes several
    &lt;b class=&quot;keywords&quot;&gt;text-level&lt;/b&gt; elements. It explains their usage in an
    &lt;strong&gt;HTML&lt;/strong&gt; document.
&lt;/p&gt;</code></pre><p><img src="https://velog.velcdn.com/images/frozen_land/post/352f6841-0115-4eb0-8439-5d6539d81a98/image.png" alt=""></p>
<blockquote>
<p>💡 <code>&lt;b&gt;</code>, <code>&lt;strong&gt;</code> 차이점</p>
</blockquote>
<ul>
<li><code>&lt;b&gt;</code> : 특별한 중요성을 가지고 있지는 않지만 굵게 표시한 부분에 사용</li>
<li><code>&lt;strong&gt;</code> : 중요한 의미를 강조할 때 사용</li>
</ul>
<hr>
<h2 id="📌-기울임-글씨-요소-i-em">📌 기울임 글씨 요소 :<code>&lt;i&gt;</code>, <code>&lt;em&gt;</code></h2>
<p>• 일반적으로 기울임꼴(Italic)로 표시됩니다.</p>
<pre><code>&lt;p&gt;I looked at it and thought &lt;i&gt;This can&#39;t be real!&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;Get out of bed &lt;em&gt;now&lt;/em&gt;!&lt;/p&gt;</code></pre><p><img src="https://velog.velcdn.com/images/frozen_land/post/86725894-f7a8-45a9-af2d-2454e9b5b380/image.png" alt=""></p>
<blockquote>
<p>💡 <code>&lt;i&gt;</code>, <code>&lt;em&gt;</code> 차이점</p>
</blockquote>
<ul>
<li><code>&lt;i&gt;</code> : 기술 용어, 외국어 구절, 등장인물의 생각 등에 사용</li>
<li><code>&lt;em&gt;</code> : 문장에서 강조할 부분을 나타낼 때 사용</li>
</ul>
<hr>
<h1 id="🔗-하이퍼링크-hyperlink">🔗 하이퍼링크 (Hyperlink)</h1>
<h2 id="📌-a-태그-앵커-태그">📌 <code>&lt;a&gt;</code> 태그 (앵커 태그)</h2>
<p>HTML <code>&lt;a&gt;</code> 요소는 href 속성을 사용해 <strong>다른 웹 페이지, 파일, 이메일, 전화번호 등으로 연결하는 하이퍼링크</strong>를 만듭니다.</p>
<pre><code>&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://example.com&quot;&gt;Website&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;mailto:m.bluth@example.com&quot;&gt;Email&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;tel:+123456789&quot;&gt;Phone&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</code></pre><p><img src="https://velog.velcdn.com/images/frozen_land/post/c41af66c-4809-4d88-82a0-7275014d14c7/image.png" alt=""></p>
<h2 id="📌-a-태그-속성">📌 <code>&lt;a&gt;</code> 태그 속성</h2>
<table>
<thead>
<tr>
<th>속성</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><strong><code>href</code></strong></td>
<td>링크할 URL을 지정</td>
</tr>
<tr>
<td><strong><code>target</code></strong></td>
<td>링크가 열릴 위치 지정</td>
</tr>
</tbody></table>
<h3 id="🔹-href-속성-절대경로-vs-상대경로">🔹 href 속성 (절대경로 vs 상대경로)</h3>
<p>• <strong>절대경로 (Absolute Path)</strong>
전체 URL을 포함하여 특정 리소스에 접근하는 방식입니다.
<code>&lt;a href=&quot;https://www.example.com/about.html&quot;&gt;About Page&lt;/a&gt;</code>
✅ 어느 위치에서든 접근 가능하지만, URL이 길어질 수 있음</p>
<p>• <strong>상대경로 (Relative Path)</strong>
현재 문서를 기준으로 다른 페이지를 연결하는 방식입니다.
➡️ 같은 도메인 내에서만 접근 가능
<code>&lt;a href=&quot;/about.html&quot;&gt;About Page&lt;/a&gt;</code>
✅ 같은 사이트 내에서 관리하기 편리하며, URL이 짧아짐</p>
<h3 id="🔹-target-속성-새-창에서-열기">🔹 <code>target</code> 속성 (새 창에서 열기)</h3>
<table>
<thead>
<tr>
<th>속성 값</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>_self</code></td>
<td>현재 창에서 열기 (기본값)</td>
</tr>
<tr>
<td><code>_blank</code></td>
<td>새 창(새 탭)에서 열기</td>
</tr>
<tr>
<td><code>_parent</code></td>
<td>부모 프레임에서 열기</td>
</tr>
<tr>
<td><code>_top</code></td>
<td>최상위 프레임에서 열기</td>
</tr>
</tbody></table>
<hr>
<h2 id="🏷️-엔티티-entity">🏷️ 엔티티 (Entity)</h2>
<p>HTML 엔티티는 특수문자나 예약된 기호를 표현할 때 사용됩니다.
각 엔티티는 <strong>”&amp;”</strong>로 시작하고 <strong>”;”</strong>로 끝납니다.</p>
<table>
<thead>
<tr>
<th>문자</th>
<th>엔터티 코드</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>&amp;</code></td>
<td><code>&amp;amp;</code></td>
<td>앰퍼샌드 (&amp;)</td>
</tr>
<tr>
<td><code>&lt;</code></td>
<td><code>&amp;lt;</code></td>
<td>태그 시작 기호 (&lt;)</td>
</tr>
<tr>
<td><code>&gt;</code></td>
<td><code>&amp;gt;</code></td>
<td>태그 끝 기호 (&gt;)</td>
</tr>
<tr>
<td><code>&quot;</code></td>
<td><code>&amp;quot;</code></td>
<td>큰따옴표 (&quot;)</td>
</tr>
<tr>
<td><code></code></td>
<td><code>&amp;nbsp;</code></td>
<td>공백 (Non-breaking space)</td>
</tr>
<tr>
<td><code>–</code></td>
<td><code>&amp;ndash;</code></td>
<td>엔 대시 (-)</td>
</tr>
<tr>
<td><code>—</code></td>
<td><code>&amp;mdash;</code></td>
<td>앰 대시 (—)</td>
</tr>
<tr>
<td><code>©</code></td>
<td><code>&amp;copy;</code></td>
<td>저작권 기호 (©)</td>
</tr>
<tr>
<td><code>®</code></td>
<td><code>&amp;reg;</code></td>
<td>등록 상표 (®)</td>
</tr>
<tr>
<td><code>™</code></td>
<td><code>&amp;trade;</code></td>
<td>상표 기호 (™)</td>
</tr>
<tr>
<td><code>≈</code></td>
<td><code>&amp;asymp;</code></td>
<td>거의 같은 기호 (≈)</td>
</tr>
<tr>
<td><code>≠</code></td>
<td><code>&amp;ne;</code></td>
<td>같지 않음 (≠)</td>
</tr>
<tr>
<td><code>£</code></td>
<td><code>&amp;pound;</code></td>
<td>파운드 (£)</td>
</tr>
<tr>
<td><code>€</code></td>
<td><code>&amp;euro;</code></td>
<td>유로 (€)</td>
</tr>
<tr>
<td><code>°</code></td>
<td><code>&amp;deg;</code></td>
<td>도 (°)</td>
</tr>
<tr>
<td>✅ HTML 엔티티는 특수 문자 입력이 어려운 경우나 HTML에서 예약된 문자를 사용할 때 유용합니다.</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<hr>
<h3 id="📚-참고-문헌">📚 참고 문헌</h3>
<p>🔗 <a href="https://developer.mozilla.org/ko/docs/Web/HTML/Element/a">MDN Web Docs: Anchor elements</a><br>🔗 <a href="https://developer.mozilla.org/en-US/docs/Glossary/Entity">MDN Web Docs: HTML Entities</a>  </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[HTML] 텍스트 요소 01]]></title>
            <link>https://velog.io/@frozen_land/HTML-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%9A%94%EC%86%8C-01</link>
            <guid>https://velog.io/@frozen_land/HTML-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EC%9A%94%EC%86%8C-01</guid>
            <pubDate>Wed, 05 Mar 2025 05:26:59 GMT</pubDate>
            <description><![CDATA[<h1 id="✨-구문-콘텐츠-정리">✨ 구문 콘텐츠 정리</h1>
<h2 id="📌-제목--h1---h6">📌 제목 : <code>&lt;h1&gt; - &lt;h6&gt;</code></h2>
<p>HTML <code>&lt;h1&gt; - &lt;h6&gt;</code> 요소는 <strong>6단계의 구획 제목</strong>을 나타냅니다.  </p>
<ul>
<li><code>&lt;h1&gt;</code>이 가장 중요하고 <code>&lt;h6&gt;</code>이 가장 덜 중요한 제목입니다.  </li>
<li>웹 브라우저는 제목의 정보를 활용해 <strong>자동으로 목차를 생성</strong>할 수 있습니다.  </li>
</ul>
<pre><code>&lt;h1&gt;제목 1&lt;/h1&gt;
&lt;h2&gt;제목 2&lt;/h2&gt;
&lt;h3&gt;제목 3&lt;/h3&gt;
&lt;h4&gt;제목 4&lt;/h4&gt;
&lt;h5&gt;제목 5&lt;/h5&gt;
&lt;h6&gt;제목 6&lt;/h6&gt;</code></pre><p><img src="https://velog.velcdn.com/images/frozen_land/post/3658f747-1796-4232-af46-8e504e9b899c/image.png" alt=""></p>
<h3 id="💡-참고사항">💡 참고사항</h3>
<p>•    글자 크기를 조절하려고 <code>&lt;h1&gt;</code>을 사용하지 말 것 → 대신 CSS의 font-size 사용
•    <code>&lt;h1&gt;</code>은 페이지당 하나만 사용 (웹 접근성 향상)
•    <code>&lt;h1&gt;</code>부터 순차적으로 사용해야 웹 표준에 적합</p>
<blockquote>
<p>두 개의 제목을 가진 책이나, 여러 개의 이름을 가진 영화는 볼 수 없는 것 처럼 !</p>
</blockquote>
<hr>
<h2 id="📌-본문--pp문단">📌 본문 : <code>&lt;p&gt;&lt;/p&gt;</code>(문단)</h2>
<p>HTML <code>&lt;p&gt;</code> 요소는 <strong>하나의 문단(문장들의 집합)</strong>을 나타냅니다.</p>
<pre><code>&lt;p&gt;첫 번째 문단입니다.
    첫 번째 문단입니다.
    첫 번째 문단입니다.
    첫 번째 문단입니다.&lt;/p&gt;
&lt;p&gt;두 번째 문단입니다.
    두 번째 문단입니다.
    두 번째 문단입니다.
    두 번째 문단입니다.&lt;/p&gt;  </code></pre><p>✅ 문단은 블록 레벨 요소이며, 닫는 태그 <code>&lt;/p&gt;</code> 이전에 다른 블록 요소가 분석되면 자동으로 닫힙니다.
✅ 줄바꿈이 자동으로 적용되지 않습니다!
<img src="https://velog.velcdn.com/images/frozen_land/post/345b7550-6329-4d50-95e2-5e1d7a5a09cb/image.png" alt=""></p>
<hr>
<h1 id="🟡-빈-요소">🟡 빈 요소</h1>
<h2 id="📌-본문--br-줄바꿈">📌 본문 : <code>&lt;br&gt;</code> (줄바꿈)</h2>
<p>HTML <code>&lt;br&gt;</code> 요소는 <strong>줄바꿈(Line Break)</strong>을 생성합니다.</p>
<pre><code>&lt;p&gt;
  O’er all the hilltops&lt;br /&gt;
  Is quiet now,&lt;br /&gt;
  In all the treetops&lt;br /&gt;
  Hearest thou&lt;br /&gt;
  Hardly a breath;&lt;br /&gt;
  The birds are asleep in the trees:&lt;br /&gt;
  Wait, soon like these&lt;br /&gt;
  Thou too shalt rest.
&lt;/p&gt;</code></pre><p>✅ <code>&lt;br&gt;</code> 요소는 여는 태그만 작성하면 됩니다!
✅ <code>&lt;br&gt;</code>을 사용한 만큼 줄바꿈이 적용됩니다.
<img src="https://velog.velcdn.com/images/frozen_land/post/61bd966f-57c1-4714-a1f6-8d8f4d237954/image.png" alt=""></p>
<blockquote>
<p>⚠️ <code>&lt;br&gt;</code>을 문단 간 여백을 줄 때 사용하지 마세요!
→ CSS의 margin 속성을 활용하세요.</p>
</blockquote>
<h2 id="📌-본문--hr-구분선">📌 본문 : <code>&lt;hr&gt;</code> (구분선)</h2>
<p>HTML <code>&lt;hr&gt;</code> 요소는 <strong>콘텐츠의 주제 변경이나 장면 전환</strong>을 나타냅니다.</p>
<pre><code>&lt;p&gt;§1: The first rule of Fight Club is: You do not talk about Fight Club.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;§2: The second rule of Fight Club is: Always bring cupcakes.&lt;/p&gt;</code></pre><p>✅ 화면 너비만큼 선이 출력됩니다.
<img src="https://velog.velcdn.com/images/frozen_land/post/adba18e0-fec4-4c4f-a738-7fa566ddf6e7/image.png" alt=""></p>
<hr>
<h1 id="🟢-인용-요소">🟢 인용 요소</h1>
<ul>
<li>출처 텍스트는 <code>&lt;cite&gt;</code> 요소로 제공 ➡️ 출력되지는 않는다.</li>
</ul>
<h2 id="📌-본문--blockquoteblockquote-긴-인용문">📌 본문 : <code>&lt;blockquote&gt;&lt;/blockquote&gt;</code> (긴 인용문)</h2>
<p>HTML <code>&lt;blockquote&gt;</code> 요소는 긴 인용문을 표현합니다.</p>
<pre><code>&lt;blockquote cite=&quot;https://www.huxley.net/bnw/four.html&quot;&gt;
    &lt;p&gt;Words can be like X-rays, if you use them properly—they’ll go through anything. You read and you’re pierced.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;—Aldous Huxley, &lt;cite&gt;Brave New World&lt;/cite&gt;&lt;/p&gt;</code></pre><p>✅ 기본적으로 들여쓰기가 적용됩니다.
✅ 출처는 <code>&lt;cite&gt;</code> 요소로 제공할 수 있습니다.
<img src="https://velog.velcdn.com/images/frozen_land/post/37bba8a9-7a02-486b-8e14-295aecaddfac/image.png" alt=""></p>
<blockquote>
<p>⚠️ <code>&lt;p&gt;</code> 태그 안에 <code>&lt;blockquote&gt;</code> 태그를 사용하면 안 됩니다!</p>
</blockquote>
<pre><code>&lt;p&gt;
    &lt;blockquote&gt;
        Avian carriers can provide high delay, low throughput, and low altitude
        service.
    &lt;/blockquote&gt;
&lt;/p&gt;</code></pre><p>HTML 구조상 자동으로 <code>&lt;p&gt;</code>가 닫히기 때문입니다.
그래서 HTML 상으로는 </p>
<pre><code>&lt;p&gt;&lt;/p&gt;
    &lt;blockquote&gt;
        Avian carriers can provide high delay, low throughput, and low altitude
        service.
    &lt;/blockquote&gt;
&lt;/p&gt;</code></pre><p>이렇게 되어있어서 HTML에서 인식을 못해서 잘못된 코드이다.</p>
<h2 id="📌-본문--qq-짧은-인용문">📌 본문 : <code>&lt;q&gt;&lt;/q&gt;</code> (짧은 인용문)</h2>
<p>HTML <code>&lt;q&gt;</code> 요소는 짧은 인용문을 표현할 때 사용됩니다.
•    브라우저에서 자동으로 따옴표(“ ”)를 추가합니다.</p>
<pre><code>&lt;p&gt;
    Mozilla 재단의 웹사이트에 따르면,
    &lt;q cite=&quot;https://www.mozilla.org/en-US/about/history/details/&quot;&gt;
    Firefox 1.0 은 2004년 처음 공개되어 큰 성공을 거두었습니다.&lt;/q&gt;
&lt;/p&gt;</code></pre><p>✅ 줄바꿈 없이 간단한 인용문에 적합합니다.
<img src="https://velog.velcdn.com/images/frozen_land/post/9fe8a85a-f9a6-41f6-a87d-44f76c3c244f/image.png" alt=""></p>
<hr>
<h1 id="🟠-미리-서식-정의된-텍스트-요소">🟠 미리 서식 정의된 텍스트 요소</h1>
<h2 id="📌-본문--prepre-미리-서식화된-텍스트">📌 본문 : <code>&lt;pre&gt;&lt;/pre&gt;</code> (미리 서식화된 텍스트)</h2>
<p>HTML <code>&lt;pre&gt;</code> 요소는 HTML 문서에서 작성한 그대로 표현합니다.</p>
<pre><code>&lt;pre&gt;
  L          TE
    A       A
      C    V
       R A
       DOU
       LOU
      REUSE
      QUE TU
      PORTES
    ET QUI T&#39;
    ORNE O CI
     VILISÉ
    OTE-  TU VEUX
     LA    BIEN
    SI      RESPI
            RER       - Apollinaire
&lt;/pre&gt;</code></pre><p>✅ 고정폭 글꼴이 사용됩니다.
✅ 공백과 줄바꿈이 그대로 유지됩니다.
<img src="https://velog.velcdn.com/images/frozen_land/post/1f465ede-49c5-4a61-882b-d1625f5843fe/image.png" alt=""></p>
<blockquote>
<p>고정폭 글꼴이란?</p>
</blockquote>
<pre><code>&lt;pre&gt;IIII&lt;/pre&gt;
&lt;p&gt;IIII&lt;/p&gt;</code></pre><p>•    일반 <code>&lt;p&gt;</code> 태그에서는 가변폭 글꼴을 사용합니다.
✅ <code>&lt;pre&gt;</code>를 사용하면 글자가 동일한 간격으로 정렬됩니다.
<img src="https://velog.velcdn.com/images/frozen_land/post/0969b726-0dea-46ba-af0a-e24765109773/image.png" alt=""></p>
<hr>
<h4 id="📚-참고-문헌">📚 참고 문헌</h4>
<p><a href="https://developer.mozilla.org/ko/docs/Web/HTML/Element/Heading_Elements">🔗 MDN Web Docs: Heading Elements</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[📖 Markup / Markdown 언어란?]]></title>
            <link>https://velog.io/@frozen_land/Markup-Markdown-%EC%96%B8%EC%96%B4%EB%9E%80</link>
            <guid>https://velog.io/@frozen_land/Markup-Markdown-%EC%96%B8%EC%96%B4%EB%9E%80</guid>
            <pubDate>Tue, 04 Mar 2025 09:14:24 GMT</pubDate>
            <description><![CDATA[<h1 id="🌟-markup이란">🌟 Markup이란?</h1>
<p><strong>마크업(Markup)</strong>은 <strong>텍스트를 구조화하고 의미를 부여하기 위해 고안된 언어</strong>입니다.<br>일반적인 문서에서 텍스트 자체뿐만 아니라, 문서의 <strong>서식(스타일), 의미(구조), 데이터 속성</strong> 등을 표현할 수 있어요.  </p>
<blockquote>
<p>📌 <strong>HTML, XML, LaTeX, Markdown 등이 마크업 언어의 대표적인 예시!</strong>  </p>
</blockquote>
<hr>
<h2 id="✨-markup-언어의-종류">✨ Markup 언어의 종류</h2>
<p>마크업 언어는 표현 방식에 따라 크게 <strong>3가지 유형</strong>으로 나뉩니다.  </p>
<table>
<thead>
<tr>
<th>유형</th>
<th>설명</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td><strong>표현적 마크업</strong><br>(Presentational Markup)</td>
<td>문서의 <strong>스타일(형태, 외관)</strong>을 지정하는 마크업</td>
<td><code>&lt;b&gt;</code>, <code>&lt;i&gt;</code>, <code>&lt;font&gt;</code></td>
</tr>
<tr>
<td><strong>순차적 마크업</strong><br>(Procedural Markup)</td>
<td>문서의 순서나 처리를 제어하는 명령형 마크업</td>
<td>LaTeX의 <code>\section{}</code></td>
</tr>
<tr>
<td><strong>설명적 마크업</strong><br>(Descriptive Markup)</td>
<td>문서의 <strong>구조와 의미를 설명</strong>하는 마크업</td>
<td><code>&lt;h1&gt;</code>, <code>&lt;p&gt;</code>, <code>&lt;table&gt;</code></td>
</tr>
</tbody></table>
<p>💡 <strong>설명적 마크업이 가장 널리 사용되며, 현대적인 HTML 문서 작성에서 중요한 역할을 해요!</strong>  </p>
<hr>
<h1 id="🌟-markdown이란">🌟 Markdown이란?</h1>
<p><strong>Markdown(마크다운)</strong>은 <strong>일반 텍스트 기반의 경량 마크업 언어</strong>입니다.<br>HTML 같은 복잡한 문법 없이, 간단한 기호로 문서의 서식을 지정할 수 있어요.</p>
<h2 id="✨-markdown의-장점과-단점">✨ Markdown의 장점과 단점</h2>
<h3 id="✅-장점">✅ 장점</h3>
<ul>
<li>문법이 간결하고 배우기 쉽다  </li>
<li>다양한 플랫폼에서 지원  </li>
<li>용량이 작고 빠르게 렌더링 가능  </li>
<li>다양한 형태로 변환 가능 (HTML, PDF 등)  </li>
</ul>
<h3 id="❌-단점">❌ 단점</h3>
<ul>
<li>HTML의 모든 기능을 대체하지 못한다  </li>
<li>표준이 없어서 환경에 따라 다르게 표현될 수 있음  </li>
<li>이미지 삽입 시 경로를 수동으로 입력해야 함 </li>
</ul>
<h2 id="📌-주요-사용처">📌 주요 사용처</h2>
<ul>
<li><strong>GitHub</strong> (README.md 문서 작성)  </li>
<li><strong>블로그</strong> (Velog, Notion, Tistory 등)  </li>
<li><strong>위키 문서</strong> (Wikipedia, GitBook)  </li>
</ul>
<h3 id="🔹-markdown-문법-예시">🔹 Markdown 문법 예시</h3>
<pre><code class="language-markdown"># 큰 제목
## 작은 제목
**굵은 글씨**  
_이탤릭체_  
[네이버로 이동](https://naver.com)</code></pre>
<hr>
<h1 id="✅-markup-vs-markdown-비교-정리">✅ Markup vs Markdown 비교 정리</h1>
<table>
<thead>
<tr>
<th>비교 항목</th>
<th>Markup (마크업)</th>
<th>Markdown (마크다운)</th>
</tr>
</thead>
<tbody><tr>
<td><strong>정의</strong></td>
<td>문서의 구조와 의미를 정의하는 언어</td>
<td>간단한 서식 지정을 위한 경량 마크업 언어</td>
</tr>
<tr>
<td><strong>예시</strong></td>
<td>HTML, XML, LaTeX</td>
<td>Markdown (.md 파일)</td>
</tr>
<tr>
<td><strong>목적</strong></td>
<td>문서의 스타일, 의미, 구조를 정의</td>
<td>가볍고 쉽게 문서를 작성</td>
</tr>
<tr>
<td><strong>복잡도</strong></td>
<td>상대적으로 복잡함</td>
<td>매우 간단함</td>
</tr>
<tr>
<td><strong>사용 환경</strong></td>
<td>웹 페이지 제작, 데이터 구조화</td>
<td>GitHub, 블로그, 문서 작성</td>
</tr>
</tbody></table>
<hr>
<h2 id="🎯-한-줄-요약">🎯 한 줄 요약</h2>
<blockquote>
<p><strong>Markup</strong>은 문서의 구조를 정의하는 일반적인 개념이고,<br><strong>Markdown</strong>은 간단한 문법으로 문서를 서식화할 수 있는 <strong>경량 마크업 언어</strong>입니다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 📖 React Hooks]]></title>
            <link>https://velog.io/@frozen_land/React-React-Hooks</link>
            <guid>https://velog.io/@frozen_land/React-React-Hooks</guid>
            <pubDate>Sun, 05 Jan 2025 17:45:37 GMT</pubDate>
            <description><![CDATA[<h2 id="📍-react-hooks란">📍 React Hooks란?</h2>
<blockquote>
<p>클래스 컴포넌트의 기능을 함수 컴포넌트에서도 이용할 수 있는 React의 특수한 기능들을 함수 컴포넌트에서도 사용할 수 있도록 도와주는 메서드들
(함수 컴포넌트에서도 클래스 컴포넌트의 기능을 마치 낚아채듯이(hook) 가져와서 사용할 수 있게 해준다)</p>
</blockquote>
<h2 id="📍-react-hooks-종류">📍 React Hooks 종류</h2>
<ol>
<li>useState ➡️ State 라는 기능을 낚아채오는 Hook</li>
<li>useRef ➡️ Reference 라는 기능을 낚아채오는 Hook</li>
<li>useEffect</li>
<li>useReducer
등등</li>
</ol>
<h2 id="📍-react-hooks-특징">📍 React Hooks 특징</h2>
<ul>
<li>React Hooks에는 이름 앞에 <strong>use라는 접두사가 붙는 특징</strong>이 있다.</li>
<li>컴포넌트 내부에서만 호출 가능</li>
<li>조건문, 반복문 내부에서는 호출 불가</li>
<li>use 라는 접두사를 이용해서 직접 나만의 새로운 Hook인 Custom Hook을 만들 수 있다.</li>
</ul>
<h2 id="📍-예시">📍 예시</h2>
<ol>
<li>HookExam 파일 생성<pre><code>HookExam.jsx
</code></pre></li>
</ol>
<p>const HookExam = () =&gt; {
    return <div>HookExam</div>;
};</p>
<p>export default HookExam;</p>
<pre><code>
2. App.jsx에서 호출</code></pre><p>App.jsx</p>
<p>import &quot;./App.css&quot;;
import Register from &quot;./components/Register&quot;;
import HookExam from &quot;./components/HookExcam&quot;;</p>
<p>function App() {
  return (
    &lt;&gt;
      <HookExam/>
    &lt;/&gt;
  );
}</p>
<p>export default App;</p>
<pre><code>&lt;img src=&quot;https://velog.velcdn.com/images/frozen_land/post/0052ffea-1a5b-4899-aef3-ea130ee837e3/image.png&quot;&gt;

---

## 📍 3가지 hook 관련된 팁
### 1. 함수 컴포넌트, 커스텀 훅, React 함수 내부에서만 호출 가능
&lt;img src=&quot;https://velog.velcdn.com/images/frozen_land/post/c1e9b102-abe2-405f-a064-0a6818f41da1/image.png&quot; width=&quot;40%&quot;&gt;
이렇게 작성하면 state가 외부에 있어서 오류 표시가 떠야하는데 오류가 안떠서 당황 ;;
혹시 몰라서 브라우저 콘솔창 확인했더니 
&lt;img src=&quot;https://velog.velcdn.com/images/frozen_land/post/defa4e9b-0844-48f5-980a-4b14dcd85e5d/image.png&quot;&gt;

`Invalid hook call. Hooks can only be called inside of the body of a function component.`
후 ~ 이제 마음이 편안해진다.
오류를 해결하기 위해서는 `const state = useState();` 를 함수 컴포넌트 안에 넣어주면 된다.</code></pre><p>import { useState } from &quot;react&quot;;</p>
<p>const HookExam = () =&gt; {
    const state = useState();</p>
<pre><code>return &lt;div&gt;HookExam&lt;/div&gt;;</code></pre><p>};</p>
<p>export default HookExam;</p>
<pre><code>
### 2. 조건부로 호출될 수 없다.
&gt; 조건부로 호출 : 조건문이나 반복문 내부에서 hook이 호출된다.

#### 왜?
: React가 내부적으로 컴포넌트들을 호출해서 화면에 렌더링할 때 이런 조건문과 반복문 내부에서 hook을 호출하게되면 서로 다른 hook들의 호출 순서가 엉망이 되어버리는 현상이 발생 ➡️ **내부적인 오류가 발생**

### 3. 나만의 훅(Custom Hook)을 직접 만들 수 있다.</code></pre><p>const HookExam = () =&gt; {
    const [input,setInput] = useState(&quot;&quot;);</p>
<pre><code>const onChange = (e) =&gt;{
    setInput(e.target.value);
}

const state = useState();

return (
    &lt;div&gt;
        &lt;input value={input} onChange={onChange}/&gt;
    &lt;/div&gt;
);</code></pre><p>};</p>
<pre><code>위의 내용을 custom hook로 만들어보기 !
</code></pre><p>import { useState } from &quot;react&quot;;</p>
<p>function useInput() {
    const [input, setInput] = useState(&quot;&quot;);</p>
<pre><code>const onChange = (e) =&gt; {
    setInput(e.target.value);
}

return [input, onChange];</code></pre><p>}</p>
<p>const HookExam = () =&gt; {
    const [input, onChange] = useInput();
    const [input2, onChange2] = useInput();</p>
<pre><code>return (
    &lt;div&gt;
        &lt;input value={input} onChange={onChange}/&gt;
        &lt;input value={input2} onChange={onChange2}/&gt;
    &lt;/div&gt;
);</code></pre><p>};</p>
<p>export default HookExam;</p>
<pre><code>
그냥 함수 앞에 **use만 붙이면 custom hook이 완성**된다.
(근데 use대신 get을 써도 오류가 안나,,, react 레퍼런스 보면 되는게 맞을 것 같기도하고 아닌 것 같기도 하고,,, help.....)

---

## 📍 Custom Hooks 보관 방법
&gt;보통 scr 디렉토리 아래에 Hooks 라는 별도의 폴더를 만들고 여기에 Hook의 이름으로 보관한다.

&lt;img src=&quot;https://velog.velcdn.com/images/frozen_land/post/d6b3d1dc-176d-40e6-a15a-5b7302c0160d/image.png&quot;&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[✅ January To-Do]]></title>
            <link>https://velog.io/@frozen_land/January-To-Do</link>
            <guid>https://velog.io/@frozen_land/January-To-Do</guid>
            <pubDate>Thu, 02 Jan 2025 13:22:45 GMT</pubDate>
            <description><![CDATA[<img src="https://velog.velcdn.com/images/frozen_land/post/8e0e4ad9-a063-41ea-84a4-9dc49724121d/image.jpeg" width="30%">

<h2 id="✍🏻-작성법">✍🏻 작성법</h2>
<ol>
<li>❎ : <strong>실천하지않았다.</strong> / ✅ : <strong>실천했다.</strong></li>
<li><strong>📍 Life</strong> : 잊지 말고 해야할 일만 작성</li>
<li><strong>📍 Study</strong> : 내가 할 수 있을만큼의 양만 작성
💫 (프로젝트 3시간 + 작성한 코드 공부 2시간 + 개인 공부 2시간)</li>
<li>💭 <strong><em>How do you feel today</em></strong> : 오늘 내가 느낀점 작성</li>
</ol>
<hr>
<h2 id="🏂-january-🏂">🏂 January 🏂</h2>
<table>
<thead>
<tr>
<th align="center">일</th>
<th align="center">월</th>
<th align="center">화</th>
<th align="center">수</th>
<th align="center">목</th>
<th align="center">금</th>
<th align="center">토</th>
</tr>
</thead>
<tbody><tr>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center">1</td>
<td align="center">2</td>
<td align="center">3</td>
<td align="center">4</td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center">🧧</td>
<td align="center">🧧</td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">5</td>
<td align="center">6</td>
<td align="center">7</td>
<td align="center">8</td>
<td align="center">9</td>
<td align="center">10</td>
<td align="center">11</td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">12</td>
<td align="center">13</td>
<td align="center">14</td>
<td align="center">15</td>
<td align="center">16</td>
<td align="center">17</td>
<td align="center">18</td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center">🏂</td>
</tr>
<tr>
<td align="center">19</td>
<td align="center">20</td>
<td align="center">21</td>
<td align="center">22</td>
<td align="center">23</td>
<td align="center">24</td>
<td align="center">25</td>
</tr>
<tr>
<td align="center">🏂</td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center">26</td>
<td align="center">27</td>
<td align="center">28</td>
<td align="center">29</td>
<td align="center">30</td>
<td align="center">31</td>
<td align="center"></td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<h2 id="🗓️-20250103">🗓️ 2025/01/03</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 월 지출 정리하기
❎ 빨래통 새로 구입하기 ➡️ 돈이 없으니깐 굳이? 라는 생각이 들었다.
✅ 일기 쓰기</p>
<p>📍 <strong><em>Study</em></strong>
✅ 프로젝트용 코드 PR 올리기
✅ 프로젝트용 코드 계획 세우기</p>
<hr>
<h2 id="🗓️-20250104">🗓️ 2025/01/04</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
✅ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ API 설계하기
❎ 설계한 API 공부하기
❎ React 강의 듣고 정리하기
❎ TypeScript 강의 듣고 정리하기</p>
<hr>
<h2 id="🗓️-20250105">🗓️ 2025/01/05</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
✅ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ 설계한 API 공부하기
✅ <a href="https://velog.io/@frozen_land/React-React-Hooks">React 강의 듣고 정리하기</a>
❎ TypeScript 강의 듣고 정리하기</p>
<p>💭 <strong><em>How do you feel today</em></strong>
어제보다 할 일을 한 개 더했다:) 내일은 3-4개 달성해야지!</p>
<hr>
<h2 id="🗓️-20250106">🗓️ 2025/01/06</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
✅ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ 멘토링
✅ 멘토링 기록 정리하기</p>
<p>💭 <strong><em>How do you feel today</em></strong>
멘토링을 할 때마다 느끼는 건데 내가 잘하고 있는건지 잘 모르겠다</p>
<hr>
<h2 id="🗓️-20250107">🗓️ 2025/01/07</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
✅ 유산균 + 종합 영양제 챙겨먹기
✅ 집안일하기</p>
<p>📍 <strong><em>Study</em></strong>
✅ <a href="https://github.com/daily-emotion/wiki/wiki/1%EC%9B%94-6%EC%A3%BC%EC%B0%A8-MENTORING(01.06)">멘토링 기록 최종 정리</a>
✅ 프로젝트 PR에 달린 commit 처리하기
✅ 4주차 개발기록 작성하기
✅ 프로젝트 일기 생성 구현하기 ➡️ 소요시간 : 일주일?
✅ 상태관리, API 테스트하는 법 찾아보기 ➡️ Jest로 테스트중
✅ 공부용 프로젝트 초기 설정하기
✅ React_Study Github readme 정리하기</p>
<p>💭 <strong><em>How do you feel today</em></strong>
새벽 2시에 강제 기상해서 열심히 살았🐓....</p>
<hr>
<h2 id="🗓️-20250108">🗓️ 2025/01/08</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
✅ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
❎ 프로젝트 일기 생성 구현하기 ➡️ 소요시간 : 일주일?</p>
<hr>
<h2 id="🗓️-20250109">🗓️ 2025/01/09</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
❎ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ 프로젝트 일기 생성 구현하기 ➡️ 소요시간 : 일주일?</p>
<hr>
<h2 id="🗓️-20250110">🗓️ 2025/01/10</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
❎ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ 프로젝트 일기 생성 구현하기 ➡️ 소요시간 : 일주일?</p>
<blockquote>
<p>구현 완료한 부분</p>
</blockquote>
<ul>
<li>날짜 선택 시 제목에 있는 날짜가 선택한 날짜로 변경됨</li>
<li>태그를 추가할 수 있는 모달 및 모달에서 선택한 내용 갖고오고 삭제 가능</li>
<li>사진 추가영역에 react-dropzone 라이브러리로 구현</li>
</ul>
<hr>
<h2 id="🗓️-20250113">🗓️ 2025/01/13</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
❎ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
🔺 한입강의 기초부분 강의 다 듣기
✅ 프로젝트 일기 생성에 API 연결하기</p>
<hr>
<h2 id="🗓️-20250114">🗓️ 2025/01/14</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
✅ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
❎ 한입강의 기초부분 강의 다 듣기
✅ 프로젝트 일기 조회페이지 생성 및 API 연결하기</p>
<hr>
<h2 id="🗓️-20250115">🗓️ 2025/01/15</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
❎ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
❎ 한입강의 기초부분 강의 다 듣기
✅ 프로젝트 일기 수정 페이지 구상
➡️ 생성/조회/수정 페이지를 각각 만들고 path가 동일하니 Router를 따로 만들어서 원하는 URL로 이동 유도할 예정</p>
<hr>
<h2 id="🗓️-20250116">🗓️ 2025/01/16</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
❎ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ [한입강의] 콜백함수까지 듣기
✅ 일기 수정 페이지 구현 및 API 연동하기</p>
<hr>
<h2 id="🗓️-20250117">🗓️ 2025/01/17</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
✅ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ 생성/조회/수정 별로 URL 이동하게끔 구현
➡️ Mock 데이터를 만들고나서 해야하는데 Mock 데이터 구현에 시간이 걸릴 예정
✅ 내가 작성한 코드 직접 쓰면서 공부하기
✅ [한입강의] 배열까지 강의 듣기</p>
<hr>
<h2 id="🗓️-20250120">🗓️ 2025/01/20</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
❎ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
🔺 생성/조회/수정 별로 URL 이동하게끔 구현 (중단)
➡️ create, view, update 코드 안에서 계속 수정이 이루어져서 추후 진행
✅ 내가 작성한 코드 직접 쓰면서 공부하기 (create)
✅ [한입강의] truthy &amp; falsy 한 값 강의 듣기</p>
<p>💭 <strong><em>How do you feel today</em></strong>
잘하고 있는지 하나도 모르겠다</p>
<hr>
<h2 id="🗓️-20250121">🗓️ 2025/01/21</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
❎ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ 자바스크립트 실전 강의 [원시타입 VS 객체타입] 듣기</p>
<hr>
<h2 id="🗓️-20250122">🗓️ 2025/01/22</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
✅ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ 프론트엔드서버 배포하는 법 공부하기
✅ post API 배포값으로 조회페이지 띄울 수 있게 하기</p>
<hr>
<h2 id="🗓️-20250123---27">🗓️ 2025/01/23 - 27</h2>
<p>📍 <strong><em>Life</em></strong>
✅ 일기 쓰기
✅ 유산균 + 종합 영양제 챙겨먹기</p>
<p>📍 <strong><em>Study</em></strong>
✅ 프론트엔드 환경 분리하기</p>
<hr>
<h2 id="🗓️-20250128">🗓️ 2025/01/28</h2>
<p>📍 <strong><em>Life</em></strong>
❎ 일기 쓰기
❎ 1월 블로그 작성하기</p>
<p>📍 <strong><em>Study</em></strong>
❎ 백엔드에 보낼 이미지가 있을 경우 이미지를 format 하는 방법 찾아보고 구현해보기</p>
<hr>
]]></description>
        </item>
    </channel>
</rss>