<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Reyna.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 19 Dec 2022 03:05:23 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Reyna.log</title>
            <url>https://velog.velcdn.com/images/sena-22/profile/1e3f8234-dc74-4dc5-a0c0-1c9ca08bb641/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Reyna.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sena-22" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[해시(Hash)]]></title>
            <link>https://velog.io/@sena-22/%ED%95%B4%EC%8B%9CHash</link>
            <guid>https://velog.io/@sena-22/%ED%95%B4%EC%8B%9CHash</guid>
            <pubDate>Mon, 19 Dec 2022 03:05:23 GMT</pubDate>
            <description><![CDATA[<h1 id="해시hash">해시(Hash)</h1>
<p>해시는 <code>key-value</code>를 쌍으로 데이터를 저장하는 자료구조이다. <strong>Space-Time trade off(시간-공간)</strong>의 대표적인 알고리즘에 속한다.</p>
<blockquote>
<p><strong>Space-Time trade off(시간-공간)</strong>
기존의  배열과 다른 별도의 리스트 공간을 만들어 빠른 알고리즘을 구현하는 방법. 즉 시간을 빠르게 하기 위해서 많은 공간을 사용하는 알고리즘이다. 기수 정렬, 해시, B-tree 등이 이 방식을 사용한다.  </p>
</blockquote>
<p><code>key</code> 값이 배열의 인덱스로 저장되기 때문에 검색과 저장이 빠르게 일어나게 된다. 
특정 데이터가 저장되는 인덱스가 그 데이터만의 고유한 위치이기 때문에 삽입 시 다른 데이터의 사이에 끼어들거나 삭제 시 다른 데이터로 채울 필요가 없으므로 삽입과 삭제 시 데이터의 이동이 없도록 만들어진 구조이다.  </p>
<h2 id="해시의-사용-용도">해시의 사용 용도</h2>
<p>해시는 주로 해시 테이블, 암호화, 데이터 축약 등에 사용된다.</p>
<h1 id="해시-테이블">해시 테이블</h1>
<p><img src="https://velog.velcdn.com/images/sena-22/post/cf6d68c1-13a8-4517-b15f-e86d869343ec/image.png" alt=""></p>
<p>해시테이블은 데이터를 입력받아 해시함수를 사용하여 주소를 만들고 그 주소에 데이터를 담는 방식으로 작동한다.</p>
<h1 id="해시-함수">해시 함수</h1>
<p>해시 테이블을 만들 때 인덱스로 사용할 고유한 숫자값을 만드는 함수.</p>
<h2 id="해시-함수를-구하는-방법">해시 함수를 구하는 방법</h2>
<h3 id="1-나눗셈법division-method">1. 나눗셈법(division method)</h3>
<p>숫자로 된 키를  해시 테이블의 크기 m으로 나눈 <strong>나머지</strong>를 해시값으로 변환하는 방법
간단하면서 빠른 연산이 장점이다. </p>
<blockquote>
<p>주소 = 입력값  % 테이블 크기</p>
</blockquote>
<p>일반적으로 나눗셈법으로 해시 함수를 구현할 때 테이블의 크기를 소수(Prime Number)로 정하는 것이 좋다고 알려져 있다. </p>
<h3 id="2-자릿수-접기digit-folding">2. 자릿수 접기(digit folding)</h3>
<p>나눗셈법은 충돌을 일으킬 가능성이 높기 때문에 충돌이 일어날 가능성을 줄인 자릿수 접기 방법을 사용하기도 한다. 
자릿수 접기는 종이를 접듯이 숫자를 일정한 크기 이하의 수로 만드는 방법이다.</p>
<blockquote>
<p>7891242 = 7+8+9+1+2+4+2
78+91+24+2 = 195</p>
</blockquote>
<p>위와 같이 각 자릿수를 더해 해시 값을 만드는 방법을 말한다. 문자열의 경우 각 요소를 아스키코드로 바꾸고 이 값들을 각각 더해서 접으면 문자열을 해시 테이블 내의 주소로 바꿀 수 있다. </p>
<h1 id="충돌">충돌</h1>
<p>해시 함수가 서로 다른 입력값에 대해 동일한 해시 테이블 주소를 반환하는 것을 말한다. 충돌을 해결하는 방법에는 크게 두 가지가 있다. </p>
<h2 id="해시-함수에서-충돌-처리-방법">해시 함수에서 충돌 처리 방법</h2>
<h3 id="1-개별-체이닝">1. 개별 체이닝</h3>
<p>해당 인덱스에 값이 있으면 그 뒤에 중첩해서 연결시키는 방법이다. 개별 체이닝을 사용하면 테이블의 길이보다 더 많은 데이터를 저장할 수 있다. </p>
<p>체이닝의 경우 최악의 경우 한 버킷에 모든 데이터가 들어 있어 시간복잡도가 O(n)이 될 수 있다.</p>
<h3 id="2-선형-탐색">2. 선형 탐색</h3>
<p>해시 함수가 반환한 주소에 이미 다른 데이터가 있을 때, 자리가 있으면  데이터를 다음 주소로 이동하며 비어 있는 주소에 입력하는 방식이다. 
만약 모든 주소에 데이터가 있을 경우 해시 테이블을 늘리는 리사이징을 진행한 후에 다시 입력한다. 
선형 탐색법은 최대 테이블의 길이만큼만 저장할 수 있다. </p>
<p><img src="https://velog.velcdn.com/images/sena-22/post/90883f3c-d188-4887-a744-7bea645738e8/image.png" alt=""></p>
<h1 id="해시의-시간-복잡도">해시의 시간 복잡도</h1>
<p>데이터를 검색할 때 <code>key</code>와 <code>value</code>가 한 쌍으로 존재하고, key 값이 배열의 인덱스로 변환되기 때문에 검색과 저장의 평균적인 시간 복잡도가 O(1)이 된다. </p>
<h1 id="자바스크립트에서-해시-테이블-구현하기">자바스크립트에서 해시 테이블 구현하기</h1>
<h3 id="해시-함수-생성">해시 함수 생성</h3>
<pre><code class="language-javascript">
function hashStringToInt(s, tableSize) { 
  let hash = 17;

  for (let i = 0; i &lt; s.length; i++) {
    hash = (13 * hash * s.charCodeAt(i)) % tableSize;
  }
  return hash;
}</code></pre>
<ul>
<li>키로 들어온 문자열(s)를 반복문을 돌면서 하나씩 charCode로 변환한다. </li>
<li>hash에 17을 할당한 것은 효율적인 키 분산을 위해서이다. </li>
</ul>
<blockquote>
<p> <strong>charCodeAt() 메서드는 주어진 인덱스에 대한 UTF-16 코드를 나타내는 0부터 65535 사이의 정수를 반환합니다.</strong>
<a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt">https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt</a></p>
</blockquote>
<h3 id="해시-테이블-생성">해시 테이블 생성</h3>
<pre><code class="language-javascript">
class HashTable {
  table = new Array(71);

//key, value를 받아 테이블에 넣어주는 메서드
  setItem = (key, value) =&gt; {
    //해시 함수가 반환하는 해시 값이 인덱스가 된다.
    const idx = hashStringToInt(key, this.table.length);
    //해당 인덱스에 할당
    this.table[idx] = value;
  };

//key를 받아 해당하는 값을 불러오는 메서드
  getItem = (key) =&gt; {
    const idx = hashStringToInt(key, this.table.length);
    return this.table[idx];
  };
}</code></pre>
<pre><code class="language-javascript">const myTable = new HashTable();
myTable.setItem(&#39;firstName&#39;, &#39;k&#39;);
myTable.getItem(&#39;firstName&#39;);

console.log(myTable.getItem(&#39;firstName&#39;)); //k

</code></pre>
<p><img src="https://velog.velcdn.com/images/sena-22/post/6a67d78e-e642-42c0-bab7-c5e19fbb55ac/image.png" alt=""></p>
<h1 id="해시-맵">해시 맵</h1>
<h2 id="map-객체">Map 객체</h2>
<p>키와 값의 쌍으로 이루어진 데이터 구조</p>
<h2 id="객체와의-차이점">객체와의 차이점</h2>
<table>
<thead>
<tr>
<th>구분</th>
<th>객체</th>
<th>Map 객체</th>
</tr>
</thead>
<tbody><tr>
<td>키로 사용할 수 있는 값</td>
<td>문자열 또는 심벌 값</td>
<td>객체를 포함한 모든 값</td>
</tr>
<tr>
<td>이터러블</td>
<td>X</td>
<td>O</td>
</tr>
<tr>
<td>요소 개수 확인</td>
<td>Object.keys(obj).length</td>
<td>map.size()</td>
</tr>
</tbody></table>
<ul>
<li>Map 객체는 이터러블이므로 for...of 문으로 순회가 가능하다.</li>
</ul>
<h2 id="map을-사용하여-해시맵-구현">Map을 사용하여 해시맵 구현</h2>
<pre><code class="language-javascript">//생성
const hashMap = new Map();

//요소 취득
hashMap.set(&#39;1&#39;,700);
hashMap.set(&#39;2&#39;,[1,2,3]);

console.log(hashMap); //Map(2) {&#39;1&#39; =&gt; 700, &#39;2&#39; =&gt; Array(3)}

//값 얻기
hashMap.get(&#39;1&#39;);

//요소 존재 여부 확인
hashMap.has(&#39;1&#39;); //boolean

//요소 탐색
for (let [key,value] of hashMap) {
  console.log(key + &#39; = &#39; + value)
}


//요소 삭제
hashMap.delete(&#39;1&#39;); //boolean

//요소 일괄 삭제
hashMap.clear(); //undefined 반환
</code></pre>
<p><img src="https://velog.velcdn.com/images/sena-22/post/c1b5488f-1ac5-4e17-8d6c-e617fd96ae4f/image.jpeg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sena-22/post/f0680747-e022-4a9f-b391-562177254bdb/image.jpeg" alt=""></p>
<blockquote>
<p>참고
<a href="https://dbehdrhs.tistory.com/70">https://dbehdrhs.tistory.com/70</a>
<a href="https://ratsgo.github.io/data%20structure&amp;algorithm/2017/10/25/hash/">https://ratsgo.github.io/data%20structure&amp;algorithm/2017/10/25/hash/</a>
<a href="https://www.geeksforgeeks.org/hashing-data-structure/">https://www.geeksforgeeks.org/hashing-data-structure/</a>
<a href="https://eunjinii.tistory.com/87">https://eunjinii.tistory.com/87</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 타겟 넘버 (javascript) ]]></title>
            <link>https://velog.io/@sena-22/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84</link>
            <guid>https://velog.io/@sena-22/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84</guid>
            <pubDate>Thu, 15 Dec 2022 13:59:39 GMT</pubDate>
            <description><![CDATA[<h2 id="🤔-문제">🤔 문제</h2>
<p>n개의 음이 아닌 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만드는 방법의 수 구하기</p>
<h2 id="제한사항">제한사항</h2>
<p>주어지는 숫자의 개수는 2개 이상 20개 이하입니다.
각 숫자는 1 이상 50 이하인 자연수입니다.
타겟 넘버는 1 이상 1000 이하인 자연수입니다.</p>
<h2 id="입출력-예시">입출력 예시</h2>
<table>
<thead>
<tr>
<th>numbers</th>
<th>target</th>
<th>return</th>
</tr>
</thead>
<tbody><tr>
<td>[1,1,1,1,1]</td>
<td>3</td>
<td>5</td>
</tr>
<tr>
<td>[4,1,2,1]</td>
<td>4</td>
<td>2</td>
</tr>
</tbody></table>
<h2 id="의사코드">의사코드</h2>
<blockquote>
<ol>
<li>타겟과 일치하는 배열의 개수를 담을 변수를 선언한다.</li>
<li>dfs 함수를 만든다</li>
<li>함수는 깊이를 나타내는 인덱스와 합계를 입력받아,  만약 배열의 길이와 인덱스가 같으면 (제일 끝까지 내려갔으면) 합계와 타겟이 일치하는지 비교한다. 만약 합계와 타겟이 일치하면 1번에서 선언한 변수에 1을 더해준다.</li>
<li>일치하지 않으면 그냥 리턴한다.</li>
<li>재귀함수를 사용하여 인덱스를 1씩 내려가면서 배열[인덱스] 만큼의 숫자를 더해준다. 재귀를 돌다가 깊이가 배열의 길이와 일치하면 리턴한다.</li>
<li>리턴된 경우 그 다음줄로 내려가 배열[인덱스]만큼의 숫자를 빼준다. 
이때 깊이가 다시 일치하면 아예 리턴, 일치하지 않으면 다시 5번으로 돌아가 더해준다.</li>
<li>재귀가 모두 끝나면 1번의 변수를 리턴한다. </li>
</ol>
</blockquote>
<h2 id="제출한-답">제출한 답</h2>
<pre><code class="language-javascript">
function solution(numbers, target) {
    let count = 0;

    dfs(0,0);

    function dfs(index, sum) {
       if (index === numbers.length) {  //여기서 index는 깊이를 의미. length와 깊이가 같아질 때까지 계속 내려감
         if (sum === target) {
            count++;
         }

         return;
       }

        dfs(index + 1 ,sum + numbers[index]); // 5까지 내려갔다가 리턴되면서 아래 코드 실행
        dfs(index + 1, sum - numbers[index]); // 다시 내려감
    }

    return count;
    }</code></pre>
<blockquote>
<p><code>solution([1,1,1,1], 2)</code> 인 경우, 이런 식으로 전개가 될 것이다.
<img src="https://velog.velcdn.com/images/sena-22/post/280af1ba-fd2b-4e05-9f9d-1abb7a97add6/image.png" alt=""></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[2022.12.14] 자료구조(Data Structure)]]></title>
            <link>https://velog.io/@sena-22/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0Data-Structure</link>
            <guid>https://velog.io/@sena-22/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0Data-Structure</guid>
            <pubDate>Wed, 14 Dec 2022 07:04:20 GMT</pubDate>
            <description><![CDATA[<h2 id="자료구조란">자료구조란?</h2>
<p>여러 <strong>데이터의 묶음을 저장하고 사용하는 방법</strong>을 정의한 것을 말한다. </p>
<blockquote>
<p><strong>데이터</strong>는 문자, 소리, 숫자, 그림 등 <strong>실생활을 구성하고 있는 모든 값</strong>으로, 분석하고 정리해서 활용하지 않으면 무의미하다. 데이터를 정리할 때는 데이터의 특징을 잘 파악해서 체계적으로 정리한 후에 저장해두어야 활용하기 유리하다. </p>
</blockquote>
<h3 id="자료구조의-특징">자료구조의 특징</h3>
<p>자료구조의 특징으로는 효율성, 추상화, 재사용성 등이 있다.</p>
<p><strong>효율성</strong></p>
<ul>
<li>상황과 목적에 맞게 적절한 자료구조를 선택함으로써 효율적인 데이터 관리가 가능해짐</li>
</ul>
<p><strong>추상화</strong></p>
<ul>
<li>복잡한 자료, 모듈, 시스템으로부터 중요한 개념만을 추려낸다.</li>
</ul>
<p><strong>재사용성</strong></p>
<ul>
<li>자료구조를 사용해 데이터를 처리할 경우 해당 자료구조의 인터페이스만 이용하여 데이터를 처리하도록 함으로써, 모듈화가 가능해진다.</li>
</ul>
<h3 id="자료구조의-종류">자료구조의 종류</h3>
<p>자료구조는 단순구조, 파일구조, 선형구조, 비선형구조로 나뉜다. 이 중에 자주 쓰이는 선형 구조와 비선형구조를 더 자세히 들여다보면, <strong>선형구조</strong>에는 배열, 스택, 큐, 연결 리스트 등이 있고, <strong>비선형구조</strong>에는 트리와 그래프가 있다. </p>
<h3 id="자주-등장하는-자료구조">자주 등장하는 자료구조</h3>
<p>Stack, Queue, Tree, Graph</p>
<h3 id="자료구조를-알아두면-좋은-점">자료구조를 알아두면 좋은 점</h3>
<p>자료구조는 특정 상황에 놓인 문제를 해결하는 데에 특화되어 있다. 따라서 자료구조를 다양하게 알아두면 다양한 상황에서 어떤 자료구조를 사용해야 할지, 어떻게 적용해야 할지 알 수 있고, 적합한 자료구조를 빠르고 정확하게 적용해서 문제 해결을 할 수 있다. </p>
<blockquote>
<p>💡 <strong>자료 구조를 시각적으로 나타낸 사이트</strong>
<a href="https://visualgo.net/en">https://visualgo.net/en</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[BFS와 DFS]]></title>
            <link>https://velog.io/@sena-22/BFS%EC%99%80-DFS</link>
            <guid>https://velog.io/@sena-22/BFS%EC%99%80-DFS</guid>
            <pubDate>Tue, 13 Dec 2022 12:53:27 GMT</pubDate>
            <description><![CDATA[<p>BFS와 DFS는 트리나 그래프 등의 <strong>비선형 구조</strong>를 무차별 탐색할 때 사용한다. 여기서 무차별 탐색이란 가능한 경우의 수를 전부 시도한다는 의미이다. 거리, 지도 탐색 등에 많이 사용된다. </p>
<h1 id="bfs-breadth-first-search-넓이-우선-검색">BFS (Breadth-First Search) 넓이 우선 검색</h1>
<p>BFS는 넓이 우선 검색으로, 같은 depth를 모두 확인한 후에 내려가서 다시 검색한다.자식 노드를 전부 방문하고 그 뒤에 후손 노드를 방문하는 식이다. 
큐를 이용해서 구현한다. </p>
<pre><code class="language-javascript">const  BFS = (graph, start) =&gt; {
        const visited = []; //방문한 노드
          const queue = []; //탐색 예정 노드

          queue.push(start);

          while(queue.length !==0){
              const node = queue.shift(); // 선입선출
              if(!visited.includes(node)){
                visited.push(node);
                queue.push(...graph[node]);
            }
        }
      return visited;
    }</code></pre>
<h1 id="dfs-depth-first-search-깊이-우선-검색">DFS (Depth-First Search) 깊이 우선 검색</h1>
<p>DFS는 깊이 우선 검색으로, 자식 노드를 끝까지 탐색한 후에 다시 되돌아가서 그 옆 노드를 검색한다. 스택을 이용해서 구현하며, 재귀를 사용하면 더 간단하게 구현 가능하다. </p>
<pre><code class="language-javascript">    const  DFS = (graph, start) =&gt; {
        const visited = []; //방문한 노드
          const stack = []; //탐색 예정 노드

          stack.push(start);

          while(stack.length !==0){
              const node = stack.pop(); // 후입선출
              if(!visited.includes(node)){
                visited.push(node);
                stack.push(...graph[node].reverse());
            }
        }
      return visited;
    }</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[힙 정렬 (Heap Sort)]]></title>
            <link>https://velog.io/@sena-22/%ED%9E%99-%EC%A0%95%EB%A0%ACheap-sort</link>
            <guid>https://velog.io/@sena-22/%ED%9E%99-%EC%A0%95%EB%A0%ACheap-sort</guid>
            <pubDate>Wed, 07 Dec 2022 08:11:04 GMT</pubDate>
            <description><![CDATA[<h3 id="heap">Heap</h3>
<p>힙은 완전 이진 트리의 일종으로 <strong>최댓값, 최솟값을 쉽게 추출</strong>할 수 있고, <strong>중복값을 허용</strong>한다는 특징을 가진다. </p>
<p>힙 정렬을 이해하기 위해서는 먼저 <strong>이진 트리</strong>와 <strong>완전 이진 트리</strong>에 대해 알아야 한다. </p>
<h3 id="이진-트리">이진 트리</h3>
<p>컴퓨터가 데이터를 표현할 때 데이터를 각 노드에 담은 뒤 노드를 두 개씩 이어붙이는 구조를 말하며, 모든 노드의 <strong>자식 노드가 2개 이하</strong>이다. (데이터의 구조가 나무와 닮았다고 해서 트리 구조라고 부른다.)</p>
<h3 id="완전-이진-트리">완전 이진 트리</h3>
<p>데이터가 <strong>왼쪽부터</strong> 빽빽하게 들어가는 이진 트리를 말한다. </p>
<h3 id="힙-생성-알고리즘">힙 생성 알고리즘</h3>
<p>힙 정렬을 수행하기 위해서는 <strong>힙 생성 알고리즘(Heapify Algorithm)</strong>을 사용한다. 힙 생성 알고리즘은 특정한 &#39;하나의 노드&#39;에 대해 수행하는 것으로, <strong>하나의 노드를 제외하고 최대 힙이 구성되어 있는 상태</strong>라고 가정한다. 특정 노드 때문에 힙이 붕괴되어 있다면, 그 노드의 자식 값 중에서 큰 값을 자기 자신으로 바꾼다. 이 과정을 자식이 없을 때까지 반복한다. 
<img src="https://velog.velcdn.com/images/sena-22/post/9dd2d171-d5b2-4729-8ec8-f9cdc86eafe4/image.jpeg" alt=""></p>
<blockquote>
<p>위 이미지의 경우 부모 노드인 5보다 자식 노드인 7이 커서 힙에 붕괴가 일어났으므로 둘을 바꿔준다. </p>
</blockquote>
<p>힙 생성 알고리즘의 시간 복잡도는 <strong>O(log N)</strong>이다. </p>
<blockquote>
<p>** 힙의 종류**</p>
</blockquote>
<ol>
<li>최대 힙(max heap)
부모 노드의 키 값이 자식 노드의 키 값보다 크거나 같은 완전 이진 트리</li>
<li>최소 힙(min heap)
부모 노드의 키 값이 자식 노드의 키 값보다 작거나 같은 완전 이진 트리</li>
</ol>
<h3 id="힙-정렬-과정">힙 정렬 과정</h3>
<p>기본적으로 완전 이진 트리를 표현하는 방법은 다음과 같이 그대로 배열에 담는 것이다. </p>
<p><img src="https://velog.velcdn.com/images/sena-22/post/4dbf8edb-24a1-4430-a7a6-85a093bf3c6c/image.png" alt=""></p>
<p>이 상태에서 힙 생성 알고리즘을 실행하면 힙 구조가 될 때까지 알고리즘이 실행된다.  </p>
<p><img src="https://velog.velcdn.com/images/sena-22/post/56a40baf-b8c9-4564-928f-2f5e432c8063/image.jpeg" alt=""></p>
<p>힙 구조가 만들어지면 가장 큰 값인 루트 노드의 값과, 배열의 마지막 값을 교환한다. 가장 큰 값은 배열의 맨 뒤로 가서 정렬이 완료된 것이므로 제외하고, 나머지 배열로 다시 힙 생성 알고리즘을 수행한다. (만약 최소 힙을 구현하려면 반대로 가장 작은 값이 위에 오도록 한다)
이 과정을 모든 값이 정렬될 때까지 반복하면 정렬이 끝나게 된다.
<strong>힙 정렬</strong>은 힙 생성 알고리즘의 시간 복잡도인 logN이 전체 원소의 개수 n만큼 반복되므로 <strong>O(nlogn)</strong>의 시간 복잡도를 가진다. </p>
<h3 id="힙-정렬-구현">힙 정렬 구현</h3>
<blockquote>
<ol>
<li>전체 트리 구조를 힙 구조로 바꾼다</li>
<li>크기를 줄여가며 반복적으로 힙을 구성한다.(이때 루트 노드와 마지막 노드를 바꾼다)</li>
</ol>
</blockquote>
<blockquote>
<p><strong>부모 노드와 자식 노드의 관계</strong>
부모의 인덱스 = (자식 인덱스) /2
왼쪽 노드의 인덱스 = 부모 인덱스 * 2
오른쪽 노드의 인덱스 = 부모 인덱스 * 2 + 1</p>
</blockquote>
<pre><code class="language-javascript">function heapSort(arr) {
  //1. 전체 트리 구조를 최대 힙 구조로 바꾼다
  for (let i = 1; i &lt; arr.length; i++) {
    let c = i;
    do {
      let root = Math.floor((c - 1) / 2);
      if (arr[root] &lt; arr[c]) {
        //자식 노드가 부모 노드보다 크면
        [arr[root], arr[c]] = [arr[c], arr[root]]; //swap
      }
      c = root; //자식이 부모로 이동
    } while (c &gt;= 0);
  }
  //2. 크기를 줄여가며 반복적으로 힙을 구성한다
  for (let i = arr.length - 1; i &gt;= 0; i--) {
    //루트 노드와 가장 마지막 노드를 swap
    [arr[0], arr[i]] = [arr[i], arr[0]];
    let root = 0;
    let c = 1;
    do {
      c = Math.floor(2 * root + 1); //c는 루트의 자식
      //자식 중에 더 큰 값을 찾는다.
      if (arr[c] &lt; arr[c + 1] &amp;&amp; c &lt; i - 1) {
        //c가 범위를 벗어나지 않도록 방지
        c++; //오른쪽 값이 더 크면 c를 오른쪽으로 이동(왼쪽 오른쪽 중 더 큰 값이 c가 되도록 함)
      }
      //루트보다 자식이 크면 교환
      if (arr[root] &lt; arr[c] &amp;&amp; c &lt; i) {
        [arr[root], arr[c]] = [arr[c], arr[root]];
      }
      root = c; //c를 루트로 이동시킨다.
    } while (c &lt; i);
  }
  return arr;
}

console.log(heapSort([1, 18, 397, 5123, 321, 2135, 534]));
</code></pre>
<blockquote>
<p>참고 
<a href="https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Data%20Structure/Heap.md">https://github.com/gyoogle/tech-interview-for-developer/blob/master/Computer%20Science/Data%20Structure/Heap.md</a>
<a href="https://www.youtube.com/watch?v=iyl9bfp_8ag">https://www.youtube.com/watch?v=iyl9bfp_8ag</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[퀵 정렬(Quick Sort)]]></title>
            <link>https://velog.io/@sena-22/%ED%80%B5-%EC%A0%95%EB%A0%ACQuick-Sort</link>
            <guid>https://velog.io/@sena-22/%ED%80%B5-%EC%A0%95%EB%A0%ACQuick-Sort</guid>
            <pubDate>Tue, 06 Dec 2022 13:23:53 GMT</pubDate>
            <description><![CDATA[<h2 id="퀵-정렬quick-sort이란">퀵 정렬(Quick Sort)이란?</h2>
<p>기준값(<code>pivot</code>)을 선정해 해당 값보다 작은 데이터와 큰 데이터로 분류하는 것을 반복해 정렬하는 알고리즘이다. </p>
<h2 id="퀵-정렬-과정">퀵 정렬 과정</h2>
<ol>
<li>데이터를 분할하는 pivot을 설정한다. 이 경우 <code>pivot</code>의 위치는 임의로 설정해도 된다.</li>
<li><code>pivot</code>을 기준으로 데이터를 2개의 집합으로 분리한다.</li>
</ol>
<ul>
<li>이때 <code>pivot</code>의 왼쪽에는<code>pivot</code>보다 작은 수, 오른쪽에는 큰 수를 놓는다. </li>
</ul>
<ol start="3">
<li>분리 집합에서 다시 <code>pivot</code> 을 선정한다.</li>
<li>분리 집합이 1개 이하가 될 때까지 위의 과정을 반복한다. </li>
</ol>
<h2 id="퀵-정렬의-시간-복잡도">퀵 정렬의 시간 복잡도</h2>
<p>평균적인 시간 복잡도는 O(nlogn)이고, 최악의 경우 O(n^2)이다.</p>
<h2 id="코드">코드</h2>
<pre><code class="language-javascript">function quickSort(arr) {

  //base case
  if(arr.length &lt; 2) return arr;

  const pivot = [arr[0]]
  const left = [];
  const right = [];

   for (let i = 1; i &lt; arr.length; i++) {
    if (arr[i] &lt; pivot) {
      left.push(arr[i]);
    } else if (arr[i] &gt; pivot) {
      right.push(arr[i]);
    } else {
      pivot.push(arr[i]);
    }
  }
return quickSort(left).concat(pivot, quickSort(right));
}

</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[합병 정렬(merge sort)]]></title>
            <link>https://velog.io/@sena-22/%ED%95%A9%EB%B3%91-%EC%A0%95%EB%A0%ACmerge-sort</link>
            <guid>https://velog.io/@sena-22/%ED%95%A9%EB%B3%91-%EC%A0%95%EB%A0%ACmerge-sort</guid>
            <pubDate>Tue, 06 Dec 2022 12:43:50 GMT</pubDate>
            <description><![CDATA[<h2 id="합병-정렬이란">합병 정렬이란?</h2>
<p>분할 정복 방식을 사용해 데이터를 <strong>분할</strong>하고, 분할한 배열을 <strong>정렬하며 합치는</strong> 알고리즘 </p>
<blockquote>
<p>*<em>분할 정복법(Divide and Conquer)? *</em></p>
</blockquote>
<ul>
<li>주어진 문제를 작은 사례로 나누고(Divide), 각각의 문제들을 해결해서 정복(Conquer)하는 방법이다. 이때 작은 사례가 문제를 해결할 만큼 충분히 작지 않으면 재귀를 사용하여 다시 나누고 정복하는 과정을 반복한다. </li>
<li>정복이라는 단어가 사용되는 게 특이해서 검색해보았는데 나폴레옹이 아우스터리츠 전투에서 오스트리아와 러시아 연합군을 물리치기 위해 중앙으로 들어가 적을 둘로 갈라놓고 개별적으로 싸워 이긴 사례에서 따왔다고 한다..</li>
</ul>
<h2 id="합병-정렬의-과정">합병 정렬의 과정</h2>
<ol>
<li>분할 : 입력 받은 배열을 반으로 나눈다.</li>
<li>정복 : 나누어진 배열이 충분히 작아질 때까지 재귀 호출하여 나누고, 정렬한다.</li>
<li>결합 : 정렬된 배열들을 하나의 배열에 병합한다.<h2 id="합병-정렬의-특징">합병 정렬의 특징</h2>
</li>
</ol>
<ul>
<li>적은 시간 복잡도를 가진다. </li>
<li>동일한 값에 대해 기존의 순서가 유지되는 <strong>안정 정렬</strong>이다.</li>
<li>추가적인 리스트를 필요로 하므로 메모리를 차지한다.</li>
</ul>
<h2 id="합병-정렬의-시간-복잡도">합병 정렬의 시간 복잡도</h2>
<p>O(nlogn)의 시간 복잡도를 가지고 있다. </p>
<h2 id="의사코드">의사코드</h2>
<pre><code class="language-javascript">function merge(left,right) {

  빈 배열을 선언한다

  left, right에 값이 존재하는 동안 반복문을 돌린다
  만약 left의 첫 번째 인덱스와 right의 첫 번째 인덱스를 비교해서
  작은 수를 빈 배열에 넣는다

  만약 left나 right 중 하나에만 값이 존재할 경우
  배열의 마지막에 그 값을 넣어준다

  배열을 리턴해준다(이 값이 mergeSort의 리턴값이 될 것이다)
}

function mergeSort(arr) {

  //base case 
  만약 배열의 길이가 1보다 작으면 바로 리턴한다.

  //recursive case
  중간값을 구한다(나누어떨어지지 않으면 내림) Math.floor(arr.length/2)
  중간값을 기준으로 left와 right로 나눈다.
  left와 right를 각각 mergeSort로 재귀호출한다. 만약 배열의 길이가 1보다 작으면  리턴될 것이다
  리턴 값을 merge 함수로 병합한다.
}</code></pre>
<h2 id="코드">코드</h2>
<pre><code class="language-javascript">function merge(left, right) {
  const sorted = [];
  while(left.length &amp;&amp; right.length){
   if(left[0] &lt; right[0]){
    sorted.push(left.shift()); //left[0]이 작을 때 
   } else {
    sorted.push(right.shift()); //right[0]이 작을 때
   }
 }
  return [...sorted,...left,...right];

}

function mergeSort(arr) {
  //base case 
  if(arr.length &lt;= 1) return arr;

  //recursive case
  const mid = Math.floor(arr.length /2);
  const left = arr.slice(0, mid);
  const right = arr.slice(mid);

  return merge(mergeSort(left),mergeSort(right));
}
</code></pre>
<blockquote>
<p>left나 right 중에 남은 숫자는 마지막에 붙는다. </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sena-22/post/a5bbc3e4-8dba-4b56-8673-6536e4061c38/image.jpeg" alt=""></p>
<p>```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 카드 슬라이더 만들기(1)]]></title>
            <link>https://velog.io/@sena-22/React-%EC%B9%B4%EB%93%9C-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%8D%94-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@sena-22/React-%EC%B9%B4%EB%93%9C-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%8D%94-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sat, 03 Dec 2022 01:32:20 GMT</pubDate>
            <description><![CDATA[<p>저번 주와 마찬가지로 <code>javascript</code>로 만들어진 카드 슬라이더를 리액트로 클론해보았다. 오늘은 navigation 기능까지 구현했다. </p>
<blockquote>
<p> <strong>참고</strong> <br><strong><a href="https://wsss.tistory.com/1582">https://wsss.tistory.com/1582</a></strong></p>
</blockquote>
<blockquote>
<p><strong>Swiper API 
<a href="https://swiperjs.com/react">https://swiperjs.com/react</a></strong></p>
</blockquote>
<p>!codesandbox[swiperreul-sayonghan-kadeu-seulraideo-yeonseub-6986mq?fontsize=14&amp;hidenavigation=1&amp;theme=dark]</p>
<h2 id="1-swiper-라이브러리-설치">1. Swiper 라이브러리 설치</h2>
<p>우선 Swiper라는 라이브러리를 사용할 것이므로 설치해주어야 한다.</p>
<blockquote>
<p><code>npm i swiper</code></p>
</blockquote>
<h2 id="2-import">2. import</h2>
<p><code>Swiper.jsx</code>라는 컴포넌트를 만들어 <code>Swiper</code>와 <code>SwiperSlide</code>를 가져왔다.</p>
<pre><code class="language-javascript">import { Swiper, SwiperSlide } from &#39;swiper/react&#39;;
import &#39;swiper/css&#39;; //css는 이렇게 가져온다.
</code></pre>
<h2 id="3-기본-틀-만들기">3. 기본 틀 만들기</h2>
<p>컴포넌트의 리턴 값으로 Swiper와 SwiperSlide를 넣어주었다. 이렇게 하면 화면에는 Slide 1이 떠있고, 슬라이드를 밀면 순서대로 2, 3으로 변한다. 3에서 오른쪽으로 밀어도 1로 되돌아가지는 않았다. </p>
<pre><code class="language-jsx">   &lt;Swiper&gt;
      &lt;SwiperSlide&gt;Slide 1&lt;/SwiperSlide&gt;
      &lt;SwiperSlide&gt;Slide 2&lt;/SwiperSlide&gt;
      &lt;SwiperSlide&gt;Slide 3&lt;/SwiperSlide&gt;
    &lt;/Swiper&gt;</code></pre>
<h2 id="4-기본-css-설정">4. 기본 CSS 설정</h2>
<p>앱의 배경은 기본 CSS를 사용하고, SwiperContainer 부터는 styled-conponents를 사용해서 작성했다.</p>
<pre><code class="language-javascript">//styles.css
* {
  box-sizing: border-box;
  width: 100%;
  margin: 0;
  padding: 0;
  height: 100%;
}

.App {
  font-family: &quot;Montserrat&quot;, sans-serif;
  margin: 0;
  width: 100%;
  height: 100vh;

  background: linear-gradient(
    45deg,
    rgb(153, 205, 227) 30%,
    rgb(139, 163, 209) 40%,
    rgb(123, 122, 191),
    rgb(104, 82, 173),
    rgb(81, 39, 155) 60%
  );
  background-size: 200% 200%;
  animation: gradient 15s ease infinite;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  padding: 32px;
}
//배경 이미지 위치가 계속 바뀌는 애니메이션
@keyframes gradient {
  0% {
    background-position: 0% 50%;
  }
  50% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0% 50%;
  }
}
</code></pre>
<blockquote>
<p><strong>leaner-gradient</strong>
<a href="https://www.notion.so/leaner-gradient-b4762372a40140ca9753e5ebecfc8bf8">https://www.notion.so/leaner-gradient-b4762372a40140ca9753e5ebecfc8bf8</a> </p>
</blockquote>
<blockquote>
<p><strong>색상 추천 사이트</strong> 
<a href="http://khroma.co/generator/">http://khroma.co/generator/</a>  마음에 드는 색을 선택하면 추천해준다!
<a href="https://webgradients.com/">https://webgradients.com/</a> gradient 사이트</p>
</blockquote>
<pre><code class="language-css">const StyledSwiperContainer = styled.div`
  /* width: 100%;
  height: 100%; */
  background: linear-gradient(
    270deg,
    rgba(247, 249, 255, 1) 0%,
    rgba(242, 246, 255, 1) 100%
  );
  position: relative;
  max-width: 420px;
  max-height: 420px;
  border-radius: 10px;
`;

const StyledSwiper = styled(Swiper)`
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  z-index: 1;
  position: relative;
`;</code></pre>
<pre><code class="language-jsx">//styeld-components를 적용해서 리턴 값도 바뀌었다.
 &lt;StyledSwiperContainer&gt;
      &lt;StyledSwiper&gt;
        &lt;SwiperSlide&gt;Slide 1&lt;/SwiperSlide&gt;
        &lt;SwiperSlide&gt;Slide 2&lt;/SwiperSlide&gt;
        &lt;SwiperSlide&gt;Slide 3&lt;/SwiperSlide&gt;
      &lt;/StyledSwiper&gt;
    &lt;/StyledSwiperContainer&gt;</code></pre>
<h2 id="5-slideritem-component-만들기">5. SliderItem Component 만들기</h2>
<p>하나의 슬라이드를 나타내기 위한 컴포넌트를 만들었다. 슬라이드마다 이미지와 제목이 다르므로 상위 컴포넌트인 <code>SwiperContainer</code>에서 <code>props</code>로 <code>title</code>과 <code>src</code>를 받아왔다. 지금은 내용을 동일하게 설정했지만, 내용도 바꾸려면 받아와야 한다. </p>
<pre><code class="language-jsx">//SliderItem.jsx
const Slideritem = ({ title, src }) =&gt; {
  return (
    &lt;SliderItemContainer&gt;
      &lt;SliderImageWrapper&gt;
        &lt;img className=&quot;slider-image&quot; src={src} alt=&quot;SliderImg&quot; /&gt;
      &lt;/SliderImageWrapper&gt;
      &lt;SliderItemContent&gt;
        &lt;Title&gt;{title}&lt;/Title&gt;
        &lt;Content&gt;
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
          eiusmod tempor incididunt ut labore
        &lt;/Content&gt;
      &lt;/SliderItemContent&gt;
    &lt;/SliderItemContainer&gt;
  );
};

export default Slideritem;
</code></pre>
<p>각 요소마다 css도 적용해주었다. </p>
<pre><code class="language-css">//SliderItem.jsx
const SliderItemContainer = styled.div`
  width: 100%;
  height: 100%;
  border-radius: 10px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  cursor: grab;
`;

const SliderItemContent = styled.div`
  padding: 32px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: 0.4s;
`;

const SliderImageWrapper = styled.div`
  height: 300px;
  width: 100%;
  overflow: hidden;

  &gt; img {
    width: 100%;
    height: 100%;

    /* cover : 대체 콘텐츠의 가로세로비 유지 &amp; 요소 콘텐츠박스를 가득 채움 */
    object-fit: cover;
    transition: 0.2s;
  }
`;

const Title = styled.h1`
  margin: 0;
  font-weight: bold;
  font-size: 24px;
  /* 행간조절 */
  line-height: 32px;
  color: #26384e;
  transform: translateY(20px);
  transition: all 0.4s ease;
  transition-delay: 0.2s;
  overflow: hidden;
  max-width: 100%;
  /* ellipsis &#39;...&#39; */
  text-overflow: ellipsis;
  /* 공백처리 방법. nowrap은 줄바꿈은 1개의 공백으로 바꾸고, 자동 줄바꿈은 지원하지 않음 */
  white-space: nowrap;

  /* 가로 520px까지 작게 */
  @media screen and (max-width: 520px) {
    &amp; {
      font-size: 16px;
      line-height: 24px;
    }
  }
`;

const Content = styled.p`
  font-size: 16px;
  line-height: 24px;
  color: #889db8;
  transform: translateY(20px);
  transition: all 0.4s ease;
  transition-delay: 0.3s;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;

  @media screen and (max-width: 520px) {
    &amp; {
      font-size: 14px;
      line-height: 20px;
    }
  }
`;</code></pre>
<p><code>SwiperContainer</code>에서 불러온 후 <code>map</code> 함수를 이용해서 <code>SwiperSlide</code> 컴포넌트 안에 <code>Slideritem</code>이 나타날 수 있도록 만들었다. 그리고 <code>items</code>라는 변수를 선언해서 제목과 이미지를 할당하고 <code>Slideritem</code>으로 내려주었다. </p>
<pre><code class="language-javascript">//SwiperContainer;jsx
const items = [
  {
    title: &quot;Postcards From Italy&quot;,
    src:
      &quot;https://images.unsplash.com/photo-1498307833015-e7b400441eb8?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&amp;ixlib=rb-1.2.1&amp;auto=format&amp;fit=crop&amp;w=2600&amp;q=80&quot;
  },
  {
    title: &quot;Bunker&quot;,
    src:
      &quot;https://images.unsplash.com/photo-1491900177661-4e1cd2d7cce2?ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&amp;ixlib=rb-1.2.1&amp;auto=format&amp;fit=crop&amp;w=2250&amp;q=80&quot;
  },
  {
    title: &quot;Small Mountain&quot;,
    src:
      &quot;https://images.unsplash.com/photo-1482192505345-5655af888cc4?ixlib=rb-1.2.1&amp;ixid=MXwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHw%3D&amp;auto=format&amp;fit=crop&amp;w=2600&amp;q=80&quot;
  }
];

//return 
 {items.map((item, idx) =&gt; {
              return (
                &lt;SwiperSlide key={idx}&gt;
                  &lt;Slideritem title={item.title} src={item.src} /&gt;
                &lt;/SwiperSlide&gt;
              );
            })}</code></pre>
<blockquote>
<p>레퍼런스에는 슬라이드 방법이 세 가지로 구현되어 있었다.</p>
</blockquote>
<ol>
<li>Navigation </li>
<li>Pagination</li>
<li>Mouse Wheel
모두 모듈을 사용한 것으로 <code>import</code> 해와야 한다.</li>
</ol>
<h2 id="6-navigation-기능">6. Navigation 기능</h2>
<blockquote>
<p>Swiper 공식 문서 
<a href="https://swiperjs.com/swiper-api#navigation">https://swiperjs.com/swiper-api#navigation</a>
참고
<a href="https://joyful-development.tistory.com/35">https://joyful-development.tistory.com/35</a>
<a href="https://velog.io/@sohee-k/React-TypeScript-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-Swiper-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0image-slider-library">https://velog.io/@sohee-k/React-TypeScript-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-Swiper-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0image-slider-library</a></p>
</blockquote>
<p>(swiper는 8.4.5 버전을 사용했다)</p>
<p>공식문서에는 <strong>Navigation</strong> 사용 방법이 아래와 같이 나와있다.</p>
<pre><code class="language-javascript">const swiper = new Swiper(&#39;.swiper&#39;, {
  navigation: {
    nextEl: &#39;.swiper-button-next&#39;, //className을 적어주었다
    prevEl: &#39;.swiper-button-prev&#39;,
  },
});</code></pre>
<p>하지만 <code>className</code>을 사용하는 방법은 렌더링되는 컴포넌트에서 잘 작동하지 않아서 <code>useRef</code>를 사용했다. </p>
<pre><code class="language-javascript">//SwiperContainer.jsx
import SwipeCore, { Navigation } from &quot;swiper&quot;;
import &quot;swiper/css/navigation&quot;;

//컴포넌트 안에서 Navigation을 불러온다. 
SwipeCore.use([Navigation]);

const prevRef = useRef(null);
  const nextRef = useRef(null);

  const [swiperSetting, setSwiperSetting] = useState(null);

  useEffect(() =&gt; {
    if (!swiperSetting) {
      const settings = {
        navigation: {
          prevEl: prevRef.current, 
          nextEl: nextRef.current 
        },
        onBeforeInit: (swiper) =&gt; {
          // 초기설정
          swiper.params.navigation.prevEl = prevRef.current;
          swiper.params.navigation.nextEl = nextRef.current;
        }
      };
      setSwiperSetting(settings);
    }
  }, [swiperSetting]);</code></pre>
<h3 id="useeffect를-사용한-이유"><code>useEffect</code>를 사용한 이유</h3>
<p><code>prevRef</code>와 <code>nextRef</code>에 저장되는 값 때문이다. 만약 <code>settings</code>를 그냥 선언하면 초깃값에 <code>null</code>이 들어간 채로 <code>settings</code>가 선언될 수 있다. 따라서 <code>useEffect</code>를 사용해서 컴포넌트를 렌더링할 때  <code>settings</code>가 선언되어야 값이 잘 들어갈 것이다. </p>
<h3 id="return">return</h3>
<pre><code class="language-javscript">//SwiperContainer.jsx
  &lt;StyledNavigations&gt;
      &lt;button  className=&quot;swiper-button-prev&quot; ref={prevRef}&gt;
            Prev
      &lt;/button&gt;
      &lt;button className=&quot;swiper-button-prev&quot; ref={nextRef}&gt;
            Next
      &lt;/button&gt;
  &lt;/StyledNavigations&gt;</code></pre>
<blockquote>
<p>🤔 </p>
</blockquote>
<ol>
<li><code>className=&quot;swiper-button-prev&quot;</code> 를 사용하지 않았는데 제거하면 위치가 바뀐다.. 아직 이유를 못 찾았다.</li>
<li>레퍼런스에는 <code>StyledNavigations</code>의 <code>top</code>이 100%로 설정되어 있는데 똑같이 설정하면 화면 밑으로 나간다..</li>
<li>버튼 위치가 오른쪽으로 가지 않았다.</li>
<li>제일 앞 페이지인 경우 맨 뒤로 이동하도록(반대도) 구현이 덜 되었다. </li>
<li>className에 &#39;swiper-slide-active&#39;를 설정하면 css를 적용할 수 있다는데 리액트 컴포넌트에서는 지원하지 않는다고 한다..</li>
</ol>
<h2 id="css">css</h2>
<pre><code class="language-css">const StyledNavigations = styled.div`
  position: absolute;
  display: flex;
  top: 55%;
  justify-content: flex-end;
  width: 100%;
  padding-top: 8px;

  &gt; button {
    background-color: transparent;
    border: none;
    cursor: pointer;
    outline: none;
    color: #fff;
    position: relative;
    margin-left: 4px;

    /* 마우스 올리면 밑줄 생성 */
    &amp;:before {
      content: &quot;&quot;;
      position: absolute;
      background-color: #fff;
      height: 1px;
      width: 0;
      left: 0;
      /* top: 50%;
      transform: translatey(-50%); */
      bottom: -1px;
      transition: 0.2s;
    }

    &amp;:hover:before {
      width: 100%;
    }
    //너비가 520px이하가 되면 보이지 않는다.
    @media screen and (max-width: 520px) {
      &amp;:hover:before,
      &amp;:hover:before {
        display: none;
      }
    }

    /* &lt; &gt;모양 없애기 */
    ::after {
      display: none;
    }
  }
`;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[버블 정렬(bubble sort)]]></title>
            <link>https://velog.io/@sena-22/%EB%B2%84%EB%B8%94-%EC%A0%95%EB%A0%ACbubble-sort</link>
            <guid>https://velog.io/@sena-22/%EB%B2%84%EB%B8%94-%EC%A0%95%EB%A0%ACbubble-sort</guid>
            <pubDate>Wed, 30 Nov 2022 11:24:14 GMT</pubDate>
            <description><![CDATA[<h1 id="버블-정렬">버블 정렬</h1>
<p>버블 정렬은 <strong>두 인접한 데이터의 크기를 비교해 정렬</strong>하는 방법이다.</p>
<blockquote>
<p><strong>버블 정렬 과정</strong></p>
</blockquote>
<ol>
<li>비교 연산이 필요한 루프 범위 설정</li>
<li>인접한 데이터 값을 비교</li>
<li>swap 조건에 부합하면 swap</li>
<li>반복문이 끝날 때까지 2~3번 반복</li>
<li>정렬 영역을 설정한다. 다음 루프에서 이 영역은 제외</li>
<li>비교 대상이 없을 때까지 반복</li>
</ol>
<blockquote>
<p>만약 특정 루프의 전체 영역에서 swap이 일어나지 않았다면 바로 종료한다. </p>
</blockquote>
<pre><code class="language-javascript">function bubbleSort(arr) {
      let swapped;
  for (let i=0; i&lt;arr.length; i++) {
           swapped = false; // 바깥 반복을 돌 때마다 false로 초기화
    for (let j=0; j&lt;arr.length;j++) {
        if(arr[j]&gt;arr[j+1]){ //뒤의 요소가 앞의 요소보다 작으면 
          [arr[j],arr[j+1]] = [arr[j+1],arr[j]] //swap
          swapped = true; //swap이 한 번이라도 일어났다면 true가 된다.
        }

    }
    if(!swapped) return arr;
  }
  return arr; //모든 정렬이 끝난 배열 반환
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[삽입  정렬(Insertion Sort)]]></title>
            <link>https://velog.io/@sena-22/%EC%82%BD%EC%9E%85-%EC%A0%95%EB%A0%ACInsertion-Sort</link>
            <guid>https://velog.io/@sena-22/%EC%82%BD%EC%9E%85-%EC%A0%95%EB%A0%ACInsertion-Sort</guid>
            <pubDate>Wed, 30 Nov 2022 11:01:18 GMT</pubDate>
            <description><![CDATA[<h1 id="삽입-정렬이란">삽입 정렬이란?</h1>
<p>삽입 정렬은 <strong>이미 정렬된 데이터 범위에 아직 정렬이 안 된 데이터를 적절한 위치에 삽입</strong>시켜 정렬하는 알고리즘이다.</p>
<p>삽입 정렬은 시간 복잡도가 O(n^2)이지만 구현이 쉽다. </p>
<blockquote>
<p><strong>삽입 정렬의 과정</strong></p>
</blockquote>
<ol>
<li>현재 인덱스에 있는 데이터를 선택</li>
<li>현재 선택한 데이터가 정렬된 데이터 범위 중에서 삽입될 위치를 탐색</li>
<li>삽입 위치와 현재 선택한 데이터를 swap 해주고 index++ </li>
<li>전체 데이터의 크기만큼 인덱스가 커질 때까지(선택할 데이터가 없을 때까지) 반복</li>
</ol>
<pre><code class="language-javascript">function insertSort(arr) {
  for (let i = 1; i &lt; arr.length; i++) { // [5,4,3,2,1]
    let insert_point = i - 1; //0
    let insert_value = arr[i]; //4

    while (insert_point &gt;= 0 &amp;&amp; arr[insert_point] &gt; insert_value) { //0  5&gt;4
      arr[insert_point + 1] = arr[insert_point]; //arr[1]=arr[0] //[5,5,3,2,1]
      insert_point--; //-1
    }
    arr[insert_point + 1] = insert_value; //arr[0]=4 [4,5,3,2,1]
  }
  return arr;
}</code></pre>
<p>insert_value에 arr[i]를 담아두었다가 삽입할 위치를 탐색한 후에 넣어준다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[선택 정렬(selection sort)]]></title>
            <link>https://velog.io/@sena-22/%EC%84%A0%ED%83%9D-%EC%A0%95%EB%A0%ACselection-sort</link>
            <guid>https://velog.io/@sena-22/%EC%84%A0%ED%83%9D-%EC%A0%95%EB%A0%ACselection-sort</guid>
            <pubDate>Tue, 29 Nov 2022 12:48:21 GMT</pubDate>
            <description><![CDATA[<h1 id="선택-정렬이란">선택 정렬이란?</h1>
<p>대상 데이터에서 <strong>최솟값 (혹은 최댓값)</strong>을 찾고, <strong>남은 정렬의 가장 앞에 있는 데이터와 교환</strong>하는 알고리즘을 가진 정렬이다. </p>
<p>선택 정렬은 구현 방법이 복잡하고, 시간 복잡도도 O(n^2)로 비효율적이기 때문에 자주 사용하지는 않는다. </p>
<blockquote>
<p><strong>선택 정렬의 과정</strong></p>
</blockquote>
<ol>
<li>남은 정렬 부분에서 최솟값(혹은 최댓값)을 찾는다. </li>
<li>남은 정렬에서 가장 앞에 있는 데이터와 선택된 데이터를 교체한다.</li>
<li>가장 앞에 있는 데이터의  위치를 변경해서(index++) 남은 정렬 부분의 범위를 줄이다.</li>
<li>전체 데이터 크기만큼 인덱스가 커질 때까지 (남은 정렬 부분이 없어질 때까지) 반복한다.
(이때 마지막 요소는 자동 정렬되므로 반복 횟수는 n-1이다.)</li>
</ol>
<p>이를 코드로 구현하면 다음과 같다. </p>
<pre><code class="language-javascript">  1. arr의 길이-1 만큼 반복문을 돌린다.
  2. 최솟값의 인덱스를 담을 변수를 선언하여 i를 할당한다.
  3. j를 i+1 ~ 리스트 길이만큼 반복문을 돌린다. 
  4. 만약 arr[j]가 arr[minIdx]보다 작다면 최솟값 인덱스에 j를 저장한다.
  5. 만약 최솟값 인덱스가 다른 값(j)으로 바뀌었다면 arr[i]와 arr[j]를 swap 해준다 </code></pre>
<hr>

<pre><code class="language-javascript">function selectionSort(arr) { 
  for (let i=0; i&lt;arr.length-1; i++) {  
    let minIdx = i  

    for (let j=i+1; j&lt;arr.length;j++) { 
     if(arr[j]&lt;arr[minIdx]){ 
       minIdx = j; //남은 정렬에서 최솟값의 인덱스를 찾는 과정 
       }
  }

 if(minIdx !== i ) {
    //가장 앞의 데이터(arr[i])와 선택된 데이터(arr[minIdx])교체  
   [arr[i], arr[minIdx]] = [arr[minIdx],arr[i]];
 }
  }
    return arr;
}</code></pre>
<blockquote>
<p>예제   <a href="https://www.acmicpc.net/problem/1427">https://www.acmicpc.net/problem/1427</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[2022.11.26] ::before, ::after]]></title>
            <link>https://velog.io/@sena-22/2022.11.26-before-after</link>
            <guid>https://velog.io/@sena-22/2022.11.26-before-after</guid>
            <pubDate>Sat, 26 Nov 2022 13:27:39 GMT</pubDate>
            <description><![CDATA[<h1 id="before">::before</h1>
<p>선택한 요소 앞에 가상 콘텐츠 삽입</p>
<h1 id="after">::after</h1>
<p>선택한 요소 뒤에 가상 콘텐츠 삽입</p>
<h1 id="content">content</h1>
<p>before와 after를 쓸 때 같이 사용하는 익명 대체 요소로, HTML에는 존재하지 않고 CSS에만 존재하는 가짜 요소이다. 따라서 javascript로 제어하기는 어렵다. </p>
<pre><code class="language-jsx">
  &amp;:before,
  &amp;:after {
    content: &quot;&quot;;
    position: absolute;
  }
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] sidebar 만들기]]></title>
            <link>https://velog.io/@sena-22/React-sidebar1</link>
            <guid>https://velog.io/@sena-22/React-sidebar1</guid>
            <pubDate>Sat, 26 Nov 2022 06:42:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>참고
<a href="https://wsss.tistory.com/124">https://wsss.tistory.com/124</a></p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/sena-22/post/de848009-2c62-4d26-8133-ced5c4de5fb1/image.gif" alt=""></p>
<p>메뉴 버튼을 클릭하면 버튼 모양이 X로 바뀌고 왼쪽에서 메뉴가 튕겨져 나오는 사이드바를 클론해보았다. 
HTML, CSS, JS로 구현되어 있는 코드를 React와 styled-component로 바꾸면서 Bar와 Menu를 컴포넌트로 만들어 분리했고, 상태는 App에서 관리하여 Close 버튼을 클릭하면 Active로 상태를 변경하여 버튼 모양이 바뀌고 사이드바가 나올 수 있도록 만들었다.  </p>
<p>!codesandbox[keulrighamyeon-saideu-menyu-jelri-seutailro-naogi-nebigeisyeon-wluujq?fontsize=14&amp;hidenavigation=1&amp;theme=dark]</p>
<blockquote>
<p>webkit은 벤더프리픽스 중에 하나로, 해당 기능이 포함되지 않은 이전 버전의 웹 브라우저에서도 사용할 수 있도록 붙이는 접미사이다. 
주요 웹 브라우저가 사용하는 벤더 프리픽스는 다음과 같다. </p>
</blockquote>
<ul>
<li>webkit-transform  (크롬, 사파리)</li>
<li>moz-transform     (파이어폭스)</li>
<li>ms-transform       (익스플로러)</li>
<li>o-transform         (오페라)</li>
</ul>
<p><a href="https://velog.io/@sena-22/2022.11.26-before-after">https://velog.io/@sena-22/2022.11.26-before-after</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 올바른 괄호 (javascript)]]></title>
            <link>https://velog.io/@sena-22/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Javascript-%EC%98%AC%EB%B0%94%EB%A5%B8-%EA%B4%84%ED%98%B8</link>
            <guid>https://velog.io/@sena-22/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Javascript-%EC%98%AC%EB%B0%94%EB%A5%B8-%EA%B4%84%ED%98%B8</guid>
            <pubDate>Thu, 24 Nov 2022 15:22:33 GMT</pubDate>
            <description><![CDATA[<h2 id="🤔-문제">🤔 문제</h2>
<p>주어진 문자열이 올바른 괄호로 이루어져있는지 여부를 리턴</p>
<blockquote>
<p>올바른 괄호란?</p>
</blockquote>
<ul>
<li>열림 괄호(&#39;(&#39;)가 없이 닫힌 괄호(&#39;)&#39;)가 나오면 올바르지 않은 괄호</li>
<li>열린 괄호는 반드시 짝지어서 닫혀야 함</li>
</ul>
<h2 id="제한사항">제한사항</h2>
<p>문자열 s의 길이 : 100,000 이하의 자연수
문자열 s는 &#39;(&#39; 또는 &#39;)&#39; 로만 이루어져 있습니다.</p>
<h2 id="입출력-예시">입출력 예시</h2>
<table>
<thead>
<tr>
<th>입력</th>
<th>출력</th>
</tr>
</thead>
<tbody><tr>
<td>&quot;()()&quot;</td>
<td>true</td>
</tr>
<tr>
<td>&quot;)()(&quot;</td>
<td>false</td>
</tr>
</tbody></table>
<h2 id="의사코드">의사코드</h2>
<blockquote>
<ol>
<li>만약 배열의 첫번째 요소가 닫힘 괄호이면 =&gt; <code>false</code> 리턴</li>
<li><code>open</code>,<code>close</code> 변수 선언(초기값 0)</li>
<li>주어진 문자열의 길이만큼 반복문을 돌리면서</li>
<li>배열의 <code>i</code> 번째 요소가 열림 괄호이면 <code>open</code>에 1을 더해주고,</li>
<li>아니라면 <code>close</code>에 1을 더해준다</li>
<li>만약 <code>open</code>의 개수보다 <code>close</code>의 개수가 많다면 열리지 않았는데 닫힌 것이므로 <code>false</code>를 리턴한다</li>
<li>반복이 끝나고 <code>open</code>과 <code>close</code>가 같다면 <code>true</code> 리턴, 아니라면 <code>false</code>를 리턴한다. </li>
</ol>
</blockquote>
<h2 id="제출한-답">제출한 답</h2>
<pre><code class="language-javascript">function solution(s){  
     if (s[0] === &#39;)&#39;) return false;

        let open = 0;
        let close = 0;

    for (let i=0; i&lt;s.length;i++){ 
      s[i] === &#39;(&#39; ?  open++ :  close++;
       if(open &lt; close) return false;
    }
    if (open === close ) return true;
    return false;
}</code></pre>
<h2 id="다른-풀이">다른 풀이</h2>
<blockquote>
<p>변수를 count 하나만 선언하고 <code>(</code> 일때 더해주고 <code>)</code>일때 빼주는 풀이도 있다. 이 경우 중간에 count가 음수가 될 경우 <code>false</code>를 리턴해주는 방식으로 풀면 된다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 같은 숫자는 싫어 (javascript)]]></title>
            <link>https://velog.io/@sena-22/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Javascript-%EA%B0%99%EC%9D%80-%EC%88%AB%EC%9E%90%EB%8A%94-%EC%8B%AB%EC%96%B4</link>
            <guid>https://velog.io/@sena-22/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Javascript-%EA%B0%99%EC%9D%80-%EC%88%AB%EC%9E%90%EB%8A%94-%EC%8B%AB%EC%96%B4</guid>
            <pubDate>Thu, 24 Nov 2022 15:08:42 GMT</pubDate>
            <description><![CDATA[<h2 id="🤔-문제">🤔 문제</h2>
<p>주어진 배열에서 연속으로 나오는 숫자를 하나만 남기고 제거하고 남은 수들을 리턴하는 함수 만들기</p>
<h2 id="제한사항">제한사항</h2>
<p>배열 arr의 크기 : 1,000,000 이하의 자연수
배열 arr의 원소의 크기 : 0보다 크거나 같고 9보다 작거나 같은 정수</p>
<h2 id="입출력-예시">입출력 예시</h2>
<table>
<thead>
<tr>
<th>입력</th>
<th>출력</th>
</tr>
</thead>
<tbody><tr>
<td>[1,1,3,3,0,1,1]</td>
<td>[1,3,0,1]</td>
</tr>
<tr>
<td>[4,4,4,3,3]</td>
<td>[4,3]</td>
</tr>
</tbody></table>
<h2 id="의사코드">의사코드</h2>
<blockquote>
</blockquote>
<ol>
<li>빈 배열을 선언해준다.</li>
<li>주어진 배열을 순회하면서 =&gt; <code>for</code> 문 사용</li>
<li>배열의 <code>i</code>번째 수와 <code>i+1</code>번째 수를 비교해서 같지 않은 경우에만 빈 배열에 <code>push</code> 해준다.</li>
<li>새로운 배열을 리턴한다.</li>
</ol>
<h2 id="제출한-답">제출한 답</h2>
<pre><code class="language-javascript">function solution(arr)
{
  let answer = [];

  for (let i=0; i&lt;arr.length;i++)  { 
      if (arr[i] !== arr[i+1])  answer.push(arr[i])
  }      
    return answer;
}</code></pre>
<h2 id="다른-풀이">다른 풀이</h2>
<pre><code class="language-javascript">function solution(arr)
{
    return arr.filter((val,index) =&gt; val != arr[index+1]);
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Stack과 Queue]]></title>
            <link>https://velog.io/@sena-22/Stack%EA%B3%BC-Queue</link>
            <guid>https://velog.io/@sena-22/Stack%EA%B3%BC-Queue</guid>
            <pubDate>Tue, 22 Nov 2022 14:14:52 GMT</pubDate>
            <description><![CDATA[<h1 id="stack">Stack</h1>
<ul>
<li>입력과 출력이 하나의 방향에서 일어나는 <strong>후입선출(LIFO)</strong>로 이루어지는 자료구조를 말한다. 즉 가장 최근에 넣은 데이터가 가장 먼저 나온다. </li>
<li>Stack에 데이터를 넣는 것을 <code>PUSH</code>, 데이터를 꺼내는 것을 <code>POP</code>이라고 한다.</li>
<li>데이터는 하나씩만 넣고 뺄 수 있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sena-22/post/f1ae1192-74ee-4139-bed0-b62f667cc8ea/image.png" alt="">
<img src="https://velog.velcdn.com/images/sena-22/post/6b349a11-53a9-4bc9-8278-ce62d72b0c03/image.png" alt=""></p>
<blockquote>
<p><a href="https://www.tutorialspoint.com/data_structures_algorithms/stack_algorithm.htm">https://www.tutorialspoint.com/data_structures_algorithms/stack_algorithm.htm</a></p>
</blockquote>
<h2 id="stack-overflow와-stack-underflow">Stack Overflow와 Stack Underflow</h2>
<hr>
<ul>
<li><code>Stack Overflow</code> : 스택이 가득 차 있는데 데이터를 넣으려고 할 때 발생한다. </li>
<li><code>Stack Underflow</code> : 빈 스택에서 데이터를 꺼내려고 하는 경우에 발생한다. </li>
<li>큐에서도 같은 경우 오버플로와 언더플로가 발생한다.</li>
</ul>
<h2 id="stack의-활용-예시">Stack의 활용 예시</h2>
<hr>
<p>스택의 특징인  후입선출(LIFO)을 활용하여 여러 분야에서 활용할 수 있다. </p>
<ul>
<li>웹 브라우저 방문기록 (뒤로 가기) : 가장 나중에 열린 페이지부터 다시 보여준다.</li>
<li>역순 문자열 만들기 : 가장 나중에 입력된 문자부터 출력한다.</li>
<li>실행 취소 (undo) : 가장 나중에 실행된 것부터 실행을 취소한다.</li>
<li>깊이 우선 탐색(DFS) : 후보 중에 가장 늦게 추가된 것부터 탐색하는 방법</li>
<li>백트래킹 종류의 코딩 테스트</li>
</ul>
<blockquote>
<p>💡 <strong>백트래킹(backtracking)</strong>이란? : 해를 찾는 도중 해가 아니어서 막히면, 되돌아가서 다시 해를 찾아가는 기법</p>
</blockquote>
<h3 id="예제">예제</h3>
<blockquote>
<p>💡 <a href="https://www.acmicpc.net/problem/1874">https://www.acmicpc.net/problem/1874</a> 스택으로 수열 만들기</p>
</blockquote>
<h1 id="queue">Queue</h1>
<ul>
<li>입력과 출력이 반대 방향에서 일어나는 <strong>선입선출(FIFO)</strong>로 이루어지는 자료구조를 말한다. </li>
<li>Queue에 데이터를 넣는 것을 <code>enqueue</code>, 데이터를 꺼내는 것을 <code>dequeue</code>라고 한다.</li>
<li>스택과 마찬가지로 데이터는 하나씩만 넣고 뺄 수 있다. </li>
</ul>
<h2 id="queue의-활용-예시">Queue의 활용 예시</h2>
<hr>
<p>Queue는 주로 데이터가 입력된 시간 순서대로 처리해야 할 필요가 있는 상황에 이용한다.</p>
<ul>
<li>우선순위가 같은 작업 예약 (프린터의 인쇄 대기열)</li>
<li>선입선출이 필요한 대기열 : 은행 업무, 티켓 카운터, 콜센터 고객 대기시간…</li>
<li>너비 우선 탐색(BFS, Breadth-First Search) 구현 : 후보 정점 중에 가장 먼저 후보에 추가된 것부터 선택한다.</li>
<li>캐시 구현, 버퍼,  실시간 비디오 스트리밍: 스트리밍에서 다운로드 된 데이터가 비디오를 재생하기에 충분하지 않으면 큐에 순서대로 모아 두었다가 충분한 양이 되면 비디오를 복원해서 재생함</li>
</ul>
<h3 id="예제-1">예제</h3>
<blockquote>
<p>💡 <a href="https://www.acmicpc.net/problem/2164">https://www.acmicpc.net/problem/2164</a> 카드2</p>
</blockquote>
<p><code>Queue</code>는 자바스크립트의 내장 메서드인 <code>shift()</code>로도 비슷한 기능을 수행할 수 있다. <code>shift()</code> 메서드는 배열의 가장 앞의 원소부터 제거하기 때문이다. 하지만 이 경우 나머지 배열의 원소들을 매번 한 칸씩 앞으로 당겨주는 재정렬을 수행하기 때문에 O(n)의 시간 복잡도를 가지게 되어 위 예제같은 경우에는 적합하지 않다. 따라서 JS의 Class를 이용하여 <code>Linked List</code>를 활용한<code>Queue</code>를 구현하여야 한다. </p>
<h3 id="참고">참고</h3>
<blockquote>
<p><a href="https://velog.io/@longroadhome/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-JS%EB%A1%9C-%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94-.%ED%81%90-Queue">https://velog.io/@longroadhome/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-JS%EB%A1%9C-%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94-.%ED%81%90-Queue</a>
(JS로 구현하는 큐 (Queue)
<a href="https://ghost4551.tistory.com/133">https://ghost4551.tistory.com/133</a> (Queue 구현 및 시간 복잡도)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[시간복잡도(Time Complexity)]]></title>
            <link>https://velog.io/@sena-22/%EC%8B%9C%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84Time-Complexity</link>
            <guid>https://velog.io/@sena-22/%EC%8B%9C%EA%B0%84%EB%B3%B5%EC%9E%A1%EB%8F%84Time-Complexity</guid>
            <pubDate>Tue, 22 Nov 2022 13:26:21 GMT</pubDate>
            <description><![CDATA[<h1 id="🧐-시간복잡도란">🧐 시간복잡도란?</h1>
<p><strong>알고리즘의 실행 시간을 표현하는 것</strong>을 말한다. 
여기서 실행 시간이란 통상적으로 쓰이는 시분초 개념이 아니라, 함수나 알고리즘 수행에 필요한 스텝 수를 의미한다. (실행 환경마다 성능이 다르기 때문에 시간을 초(seconds)나 밀리초(milliseconds)로 표현하면 편차가 커질 수 있기 때문이라고 한다.)
시간 복잡도는 보통 <strong>점근 표기법</strong>으로 표현한다. </p>
<blockquote>
<p><strong>점근적  분석(asymptotic analysis)</strong>
임의의 함수가 N → ♾️ 일 때 어떤 단순한 형태에 근접해지는지 분석하는 것을 의미한다(점근이란 점점 가까워진다는 의미이다)
쉽게 생각하면 <strong>입력의 크기가 충분히 큰 경우에 대한 분석</strong>을 의미한다. 크기가 작은 문제에서는 비효율적인 알고리즘을 사용해도 무방하기 때문이다. </p>
</blockquote>
<blockquote>
<p>*<em>점근 표기법(asymptotic notation) *</em> 
점근적 분석을 통해 실행시간을 단순하게 표현한 표기법</p>
</blockquote>
<br>

<p>시간 복잡도를 표현하는 점근 표기법은 크게 세 종류로 나눌 수 있다.</p>
<h1 id="🔸-점근-표기법의-유형">🔸 점근 표기법의 유형</h1>
<h2 id="big-ω-표기법">Big-Ω 표기법</h2>
<p>최선일 때의 연산 횟수를 나타내며, <strong>점근적 하한선(Asymptotic lower bound)</strong>을 의미한다. </p>
<h2 id="big-θ-표기법">Big Θ-표기법</h2>
<p>보통일 때의 연산 횟수를 나타낸다. <strong>점근적 상한과 하한의 교집합(Asymptotic tighter bound)</strong>이라고 한다. </p>
<h2 id="big-o-표기법">Big-O 표기법</h2>
<p>최악일 때의 연산 횟수를 나타낸 것으로, <strong>점근적 상한선(Asymptotic upper bound)</strong>을 의미한다. 최소한 보장되는 성능을 표기하기 때문에 일반적으로 많이 사용하며, 다양한 케이스가 존재하는 코딩 테스트에서도 Big-O 표기법을 기준으로 실행 시간을 계산하는 것이 좋다.</p>
<h1 id="🔸-big-o-표기법의-특징">🔸 Big-O 표기법의 특징</h1>
<ol>
<li>상수, 계수는 제외한다.</li>
</ol>
<ul>
<li>for문이 1개일 때와 3개일 때 연산 횟수는 N과 3N으로 3배 차이가 나지만 코딩 테스트에서 상수를 무시하기 때문에 시간 복잡도는 O(n)이다.</li>
</ul>
<ol start="2">
<li>가장 많이 중첩된 반복문의 수행 횟수가 시간 복잡도의 기준이 된다.</li>
</ol>
<ul>
<li>이중 for문이 있을 경우 일반 for문이 10개가 있어도 이중 for문이 시간 복잡도의 기준이 되기 때문에 O($n^2$)이 된다.</li>
</ul>
<h1 id="🔸-big-o-표기법의-종류">🔸 Big-O 표기법의 종류</h1>
<blockquote>
<p>*<em>실행 속도 *</em>
<code>O(1)</code> &lt; <code>O(log N)</code> &lt; <code>O(N)</code> &lt; <code>O(N log N)</code> &lt; <code>O(N^2)</code> &lt; <code>O(2^N)</code>
<img src="https://velog.velcdn.com/images/sena-22/post/c7e2c3ae-2046-475a-a694-e3358ec335a7/image.png" alt=""><a href="https://www.freecodecamp.org/news/big-o-cheat-sheet-time-complexity-chart/">https://www.freecodecamp.org/news/big-o-cheat-sheet-time-complexity-chart/</a></p>
</blockquote>
<h2 id="1-o1-best">1. O(1) (Best)</h2>
<ul>
<li>일정한 복잡도를 가지며 입력값이 증가해도 시간이 늘어나지 않는다</li>
<li>Stack의 push,pop, 배열의 인덱스를 찾을 때</li>
</ul>
<h2 id="2-olog-n-good">2. O(log n) (Good)</h2>
<ul>
<li>로그 복잡도. O(1) 다음으로 빠른 시간 복잡도를 가진다(시간이 덜 걸린다는 의미..). 매번 입력값이 절반으로 줄어들 때 로그 복잡도를 가진다고 한다.</li>
<li>이진탐색트리</li>
</ul>
<h2 id="3-on-fair">3. O(n) (Fair)</h2>
<ul>
<li>선형 복잡도. 입력값이 증가하면 시간도 같은 비율로 증가한다.</li>
<li>for 문</li>
</ul>
<h2 id="4-on-log-n-bad">4. O(n log n) (Bad)</h2>
<ul>
<li><p>O(N)의 알고리즘과 O(log N)의 알고리즘이 중첩된 형태</p>
</li>
<li><p>퀵 / 병합 / 힙</p>
<h2 id="5-on2--o2n-worst">5. O($n^2$) &amp; O($2^n$) (Worst)</h2>
<ul>
<li>O($n^2$) : 2차 복잡도. 입력값이 증가하면서 시간이 n^2의 비율로 증가한다. (이중 for문)</li>
<li>O($2^n$) : 기하급수적 복잡도. (피보나치 수를 구하는 알고리즘)</li>
</ul>
<h2 id="데이터-크기에-따라-예상되는-시간-복잡도">데이터 크기에 따라 예상되는 시간 복잡도</h2>
</li>
</ul>
<table>
<thead>
<tr>
<th align="left">데이터 크기 제한</th>
<th align="center">예상되는시간 복잡도</th>
</tr>
</thead>
<tbody><tr>
<td align="left">n ≤ 1,000,000</td>
<td align="center">O(n) or O (logn)</td>
</tr>
<tr>
<td align="left">n ≤ 10,000</td>
<td align="center">O(n^2)</td>
</tr>
<tr>
<td align="left">n ≤ 500</td>
<td align="center">O(n^3)</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[2022.11.21] 브라우저의 렌더링 과정]]></title>
            <link>https://velog.io/@sena-22/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%A0%8C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@sena-22/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%A0%8C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Mon, 21 Nov 2022 11:09:00 GMT</pubDate>
            <description><![CDATA[<h1 id="🔸-브라우저란">🔸 브라우저란?</h1>
<p>선택한 자원을 서버에게 요청하고, 전송받은 자원을 화면에 표시하여 열람할 수 있게 해주는 GUI 기반의 소프트웨어 프로그램을 말한다. 
쉽게 말하면 웹 서버와 통신해서 웹사이트의 다양한 컨텐츠를 볼 수 있도록 지원해주는 프로그램을 말한다.<br>여기서 자원이란 HTML, CSS, javascript 등을 말한다.</p>
<h1 id="🔸-브라우저의-구조">🔸 브라우저의 구조</h1>
<p><img src="https://velog.velcdn.com/images/sena-22/post/5f95e791-a086-4cb8-94bb-3e001ec57ba2/image.png" alt=""></p>
<h2 id="사용자-인터페이스ui">사용자 인터페이스(UI)</h2>
<p>주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분을 말한다. </p>
<h2 id="브라우저-엔진레이아웃-엔진">브라우저 엔진(레이아웃 엔진)</h2>
<ul>
<li>사용자 인터페이스와 렌더링 엔진 사이의 동작을 제어한다. </li>
</ul>
<h2 id="렌더링-엔진">렌더링 엔진</h2>
<ul>
<li>요청한 콘텐츠를 표시. HTML, CSS 등을 파싱하여 화면에 그려준다.</li>
<li>보통 브라우저 엔진과 하나로 본다.</li>
</ul>
<h2 id="자바스크립트-해석기엔진">자바스크립트 해석기(엔진)</h2>
<p>자바스크립트 코드를 해석하고 실행한다. 브라우저마다 엔진이 탑재되어 있다.</p>
<h3 id="구글-크롬-v8-엔진의-구조">구글 크롬 V8 엔진의 구조</h3>
<p><img src="https://velog.velcdn.com/images/sena-22/post/fbe7ce28-0ca6-42f6-87f3-5985c2144289/image.png" alt=""></p>
<p><strong>힙 메모리(Heap Memory)</strong></p>
<ul>
<li>동적 메모리 할당에 사용되는 자료구조</li>
<li>객체나 동적 메모리를 저장한다</li>
</ul>
<p><strong>콜 스택(Call Stack)</strong></p>
<ul>
<li>프로그램 상에서 우리가 어디에 있는지 기록하는 자료구조</li>
<li>자바스크립트는 싱글 스레드 기반의 언어이기 때문에 콜스택이 하나이다.</li>
<li>후입 선출 구조를 가진다.</li>
<li>콜 스택에 쌓이는 데이터 하나하나를 <strong>스택 프레임</strong>이라고 부른다.</li>
<li>콜 스택의 메모리 공간을 넘어버리면 <strong>스택 오버플로</strong>가 발생한다.</li>
<li>스택 추적<ul>
<li>브라우저의 콘솔 로그에서 에러가 어디에서  발생되었는지 추적할 수 있다.</li>
</ul>
</li>
</ul>
<h2 id="ui-백엔드">UI 백엔드</h2>
<ul>
<li>렌더링 엔진이 분석한 렌더 트리를 브라우저에 그리는 역할.</li>
<li>OS 사용자 인터페이스 체계를 사용한다.</li>
</ul>
<h2 id="자료-저장소">자료 저장소</h2>
<h3 id="웹-스토리지의-특징">웹 스토리지의 특징</h3>
<ul>
<li>웹 브라우저가 직접 데이터를 저장할 수 있게 해준다</li>
<li>사용자 측에서 많은 정보를 안전하게 저장할 수 있게 해준다</li>
<li>데이터가 클라이언트에만 존재해서 트래픽 비용을 줄여준다</li>
<li>오리진마다 하나씩 존재한다</li>
</ul>
<aside>
💡 origin : 도메인 + 프로토콜로  이루어진 식별자

</aside>

<h3 id="웹-스토리지-종류">웹 스토리지 종류</h3>
<ul>
<li>로컬 스토리지 : 보관 기한이 없는 데이터를 저장. 도메인만 같으면 전역으로 데이터 공유 가능</li>
<li>세션 스토리지 : 하나의 세션만을 위한 데이터 저장. 브라우저 탭이나 창을 닫으면  사라진다.</li>
</ul>
<h3 id="웹-스토리지-문법">웹 스토리지 문법</h3>
<ul>
<li><code>window.localStorage</code> : 만료 날짜가 없는 데이터를 저장할 때 사용</li>
<li><code>window.sessionStorage</code> : 세션이 있는 데이터를 저장할 때 사용</li>
</ul>
<pre><code class="language-javascript">//window 객체에 있는 Storage 객체를 통해 확인
//해당 객체가 존재하지 않으면 undefined 반환, 객체가 존재하면 function 반환

if(typeof(Storage) !== &quot;undefined&quot;) {

    //web storage를 위한  코드

} else {

 //web storage를 지원하지 않는 브라우저를 위한 안내 부분

}</code></pre>
<h3 id="웹-스토리지를-활용한-기능">웹 스토리지를 활용한 기능</h3>
<ul>
<li>복구 및 백업 관련 기능에 주로 사용된다.</li>
<li>블로그 글을 작성하다가 사용자가 창을 벗어난 경우 관련 내용 복구 &amp; 백업</li>
<li>사용자가 입력 폼에 입력하던 중 페이지에서 벗어난 경우 복구 &amp; 백업</li>
<li>현재 읽은 글의 히스토리 저장</li>
</ul>
<h1 id="🔸-브라우저의-렌더링">🔸 브라우저의 렌더링</h1>
<p>브라우저의 렌더링이란 HTML, CSS, Javascript 등 개발자가 작성한 문서가 브라우저에서 출력되는 과정을 의미한다. </p>
<h2 id="1-사용자가-브라우저를-통해-웹-사이트에-접속한다">1. 사용자가 브라우저를 통해 웹 사이트에 접속한다.</h2>
<p>브라우저 검색창에 주소를 치고 엔터를 누르면 먼저 입력한 텍스트가 검색어인지, url 주소인지 확인한다. </p>
<p>만약 url 주소이면 브라우저 엔진이 네트워크 호출을 수행한다.</p>
<h2 id="2-네트워크를-호출한다">2. 네트워크를 호출한다.</h2>
<p>2.1. DNS 서버에서 <strong>IP 주소를 찾는다</strong>. </p>
<p>URL 주소 중에 도메인 네임을 검색해서 해당 도메인 네임에 해당하는 IP주소를 찾아준다. </p>
<p>2.2. HTTP 통신</p>
<p>브라우저는 IP 주소로 HTTP 요청을 보낸다. 요청을 받은 서버는 해당 데이터를 사용하여 HTTP 응답 메시지를 생성하여 HTTP 응답을 보낸다.</p>
<h2 id="3-렌더링">3. 렌더링</h2>
<p><img src="https://velog.velcdn.com/images/sena-22/post/875018a6-9650-4ec9-82d5-1dee381f3623/image.png" alt=""></p>
<blockquote>
</blockquote>
<ol>
<li>렌더링 엔진이  HTML을 파싱하여 DOM 트리 생성</li>
<li>CSS 파일과 함께 포함된 스타일 요소를 파싱하여 CSSOM 트리 생성</li>
<li>1, 2번을 결합하여 렌더 트리 구축</li>
<li>레이아웃 과정을 통해 어디에 배치할 지 결정</li>
<li>UI 백엔드에서 렌더트리를 화면에 그린다.(paint)</li>
</ol>
<h2 id="파싱parsing">파싱(Parsing)</h2>
<p>프로그래밍 언어로 작성된 파일을 실행시키기 위해 구문 분석(syntax analysis)을 하는 단계</p>
<ul>
<li><strong>문서 파싱(document parsing)</strong><ul>
<li>브라우저가 코드를 이해하고 사용할 수 있는 구조로 변환하는 것</li>
<li>렌더링 과정에서는 HTML 파일로 DOM 트리를 구축하고 CSS 파일로 CSSOM 트리를 만드는 것을 파싱한다고 표현한다.</li>
</ul>
</li>
</ul>
<h2 id="dom-tree">DOM Tree</h2>
<ul>
<li>HTML 문서의 요소들의 중첩 관계를 기반으로 노드들을 트리 구조로 구성한 것</li>
<li>Document Object Model</li>
</ul>
<h2 id="cssom-tree">CSSOM Tree</h2>
<ul>
<li>파싱 중 <code>&lt;link&gt;</code>, <code>&lt;style&gt;</code> 태그를 만났을 때 파싱을 멈추고 해당 리소스 파일을 서버로 요청, 리소스를 받아  파싱해 만든 트리를 CSSOM이라고 한다.</li>
<li>CSSOM 트리를 구축하고 나면 다시 html 파일의 파싱을 진행한다.</li>
</ul>
<h2 id="render-tree">Render Tree</h2>
<ul>
<li>DOM Tree와 CSSOM Tree를 합쳐서 렌더 트리를 만든다.</li>
</ul>
<p>(이를 Attachment)라고 한다. </p>
<ul>
<li>보여지는 화면을 그리기 때문에 보이지 않는 요소들은 포함시키지 않는다.</li>
<li><code>&lt;meta&gt;</code> 태그나 <code>display:none</code> 등의 태그나 요소는 제외한다.</li>
</ul>
<h2 id="레이아웃">레이아웃</h2>
<ul>
<li>렌더 트리를 기반으로 HTML 요소의 레이아웃을 계산하여 브라우저 화면 어디에 배치할 지 결정하는 과정</li>
<li>이때 모든 값은 px 값으로 변환된다.</li>
</ul>
<h2 id="페인팅">페인팅</h2>
<ul>
<li>브라우저가 레이아웃에서 결정된 대로 그림을 그리기 시작한다.</li>
<li>브라우저화면은 픽셀이라고 하는 점으로 구성되어  있는데, 이 픽셀들을 결정된 정보로 채워나가는 과정이 페인팅이다.</li>
</ul>
<h1 id="🔸-리플로우와-리페인트">🔸 리플로우와 리페인트</h1>
<hr>
<ul>
<li>웹 인터렉션으로 인해 렌더링 과정의 레이아웃을 반복해 수행하는 것을 리플로우, 페인트 과정을 반복해 수행하는 것을 리페인트라고 한다.</li>
<li>DOM은 변경될 때마다 리플로우와 리페인트를 다시 하기때문에 각각 CPU와 GPU를 많이 차지해 프레임 드랍을 유발한다.</li>
<li>브라우저의 과부화로 인해 프레임 수가 줄어들면 렌더링 엔진이 인식할 수 없고, 이는 UX에 좋지 않기 때문에 최적화를 고려해야 한다.</li>
</ul>
<h2 id="최적화-방법">최적화 방법</h2>
<h3 id="불필요한-레이아웃-줄이기">불필요한 레이아웃 줄이기</h3>
<ul>
<li>리플로우 시 리페인트는 필연적으로 일어나므로 리페인트만 발생하는 속성을 사용하는 것이 좋다.</li>
<li>리플로우가 일어나는 속성(위치, 너비와 관련된 속성들)</li>
<li>이 속성을 피해 <code>transform</code>의 <code>translate</code>를 사용하면 위치 이동이 가능하고 리페인트만 발생하기 때문에 프레임  수 유지를 기대할 수 있다.</li>
<li>리페인트가 일어나는 속성 : <code>background</code>, <code>box-shadow</code>, <code>color</code> …</li>
<li>리페인트가 일어나지 않게 해주는 <code>opacity</code> 속성도 있다. <code>visibility</code>/ <code>display</code> 보다 <code>opacity</code>가 성능 개선에 도움이 된다.</li>
</ul>
<h3 id="영향을-주는-노드-줄이기">영향을 주는 노드 줄이기</h3>
<ul>
<li>JavaScript + CSS를 조합한 애니메이션이 많거나, 레이아웃 변화가 많은 요소의 경우 <code>position</code>을 <code>absolute</code> 또는 <code>fixed</code>를 사용해주면 영향을 받는 주변 노드들을 줄일 수 있다.  <code>fixed</code>와 같이 영향을 받는 노드가 전혀 없는 경우 리플로우 과정이 필요 없기 때문에 리페인트 연산 비용만 들일 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[2022.10.27] 프로퍼티 어트리뷰트 ]]></title>
            <link>https://velog.io/@sena-22/2022.10.27-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0-%EC%96%B4%ED%8A%B8%EB%A6%AC%EB%B7%B0%ED%8A%B8</link>
            <guid>https://velog.io/@sena-22/2022.10.27-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0-%EC%96%B4%ED%8A%B8%EB%A6%AC%EB%B7%B0%ED%8A%B8</guid>
            <pubDate>Wed, 26 Oct 2022 21:54:46 GMT</pubDate>
            <description><![CDATA[<h1 id="1-내부-슬롯-내부-메서드">1. 내부 슬롯, 내부 메서드</h1>
<h2 id="내부-슬롯-내부-메서드">내부 슬롯, 내부 메서드?</h2>
<ul>
<li>자바스크립트 엔진의 내부 로직으로, <code>이중 대괄호([[ ]])</code>로 감싼 것들을 말한다. </li>
<li>보통은 접근이 불가능하다. 하지만 일부의 내부 슬롯과 메서드들은 간접적으로 접근할 수 있다.</li>
<li>예를 들어, <code>[[Prototype]]</code> 내부 슬롯의 경우, <code>__proto__</code>로 접근이 가능하다. </li>
</ul>
<h1 id="2-프로퍼티-어트리뷰트">2. 프로퍼티 어트리뷰트</h1>
<ul>
<li>JS 엔진이 관리하는 meta-property를 말한다.</li>
<li>프로퍼티 생성 시 자동으로 정의되며, 프로퍼티의 상태를 나타낸다. </li>
<li><code>Object.getOwnPropertyDescriptor</code> 메서드로 간접적으로 확인이 가능하다.</li>
</ul>
<h3 id="objectgetownpropertydescriptor객체의-참조-프로퍼티-키">Object.getOwnPropertyDescriptor(객체의 참조, &#39;프로퍼티 키&#39;)</h3>
<p><img src="https://velog.velcdn.com/images/sena-22/post/fdcc88ac-48f1-43bf-9866-16deb4450a85/image.jpeg" alt=""></p>
<p>-<code>Object.getOwnPropertyDescriptor</code>는 하나의 프로퍼티에 대해서만 프로퍼티 디스크립터 객체를 반환하지만, <code>Object.getOwnPropertyDescriptors</code>를 사용하면 모든 프로퍼티의 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터를 반환한다. </p>
<blockquote>
<p><code>Object.getOwnPropertyDescriptor</code> 메서드를 사용하면 디스크립터 객체를 반환하는데, 이 객체는 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 제공한다. </p>
</blockquote>
<h1 id="3-데이터-프로퍼티와-접근자-프로퍼티">3. 데이터 프로퍼티와 접근자 프로퍼티</h1>
<h2 id="데이터-프로퍼티">데이터 프로퍼티</h2>
<ul>
<li>키와 값으로 구성된 일반 프로퍼티<h3 id="데이터-프로퍼티의-프로퍼티-어트리뷰트">데이터 프로퍼티의 프로퍼티 어트리뷰트</h3>
</li>
</ul>
<ol>
<li>[[Value]]</li>
</ol>
<ul>
<li>프로퍼티 키를 통해 값에 접근했을 때 반환되는 값</li>
</ul>
<ol start="2">
<li>[[Writable]]</li>
</ol>
<ul>
<li>프로퍼티 값의 변경 여부를 나타낸다(boolean)</li>
<li><code>false</code>인 경우, 읽기 전용이다.</li>
</ul>
<ol start="3">
<li>[[Enumerable]]</li>
</ol>
<ul>
<li>프로퍼티의 열거 가능 여부를 나타낸다</li>
<li><code>false</code>인 경우, for...in 문이나 Object.keys 등으로 열거할 수 없다. </li>
</ul>
<ol start="4">
<li>[[Configurable]]</li>
</ol>
<ul>
<li>프로퍼티의 재정의 가능 여부</li>
<li><code>false</code>인 경우 프로퍼티 삭제, 프로퍼티 어트리뷰트 값을 변경할 수 없다.
([[Writable]]이 <code>true</code>인 경우 <code>Value</code> 변경, [[Writable]]을 <code>false</code>로 변경할 수는 있다.</li>
</ul>
<h2 id="접근자-프로퍼티">접근자 프로퍼티</h2>
<ul>
<li>접근자 함수(다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출)로 구성된 프로퍼티</li>
</ul>
<h3 id="접근자-프로퍼티의-프로퍼티-어트리뷰트">접근자 프로퍼티의 프로퍼티 어트리뷰트</h3>
<ol>
<li>[[GEt]]</li>
</ol>
<ul>
<li>데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수</li>
<li>접근자 프로퍼티 키로 프로퍼티 값에 접근하면 getter 함수가 호출되고, 그 결과가 프로퍼티 값으로 반환된다. </li>
</ul>
<ol start="2">
<li>[[Set]]</li>
</ol>
<ul>
<li>데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수</li>
<li>접근자 프로퍼티 키로 프로퍼티 값을 저장하면, setter 함수가 호출되고, 그 결과가 프로퍼티 값으로 저장된다. </li>
</ul>
<ol start="3">
<li>[[Enumerable]]</li>
<li>[[Configurable]]</li>
</ol>
<ul>
<li>3, 4번은 데이터 프로퍼티 어트리뷰트와 동일하다. </li>
</ul>
<blockquote>
<p>Deep Dive 16장 참고</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[2022.10.26] 함수(2) - 함수의 호출]]></title>
            <link>https://velog.io/@sena-22/2022.10.26-%ED%95%A8%EC%88%982-%ED%95%A8%EC%88%98%EC%9D%98-%ED%98%B8%EC%B6%9C</link>
            <guid>https://velog.io/@sena-22/2022.10.26-%ED%95%A8%EC%88%982-%ED%95%A8%EC%88%98%EC%9D%98-%ED%98%B8%EC%B6%9C</guid>
            <pubDate>Tue, 25 Oct 2022 21:11:51 GMT</pubDate>
            <description><![CDATA[<h1 id="함수의-호출">함수의 호출</h1>
<blockquote>
<p>함수를 가리키는 식별자 (인수1,  인수2)의 형태로 함수를 호출 할 수 있다. </p>
</blockquote>
<ol>
<li><p>함수가 호출된다.</p>
</li>
<li><p>함수 몸체 내에서 매개변수가 생성되고 <code>undefined</code>로 초기화된다.</p>
</li>
<li><p>매개변수에 인수가 순서대로 할당된다. </p>
</li>
</ol>
<h2 id="인수의-조건">인수의 조건</h2>
<ul>
<li>인수는 값으로 평가될 수 있는 표현식이어야 한다. </li>
</ul>
<h2 id="매개변수와-인수-개수가-다를-경우">매개변수와 인수 개수가 다를 경우?</h2>
<h3 id="1--매개변수-개수--인수-개수">1 . 매개변수 개수 &gt; 인수 개수</h3>
<ul>
<li>인수가 부족하면 <code>undefined</code>로 초기화된 상태 그대로 실행되게 된다.</li>
</ul>
<pre><code class="language-javascript">function add(x,y) {
  return x + y;
}

console.log((5)); 
//5 + undefined =&gt; NaN</code></pre>
<h3 id="2-매개변수-개수--인수-개수">2. 매개변수 개수 &lt; 인수 개수</h3>
<ul>
<li>인수가 남으면 무시한다!</li>
<li>남은 인수는 없어지는 건 아니고 <code>arguments</code> 객체의 <code>프로퍼티</code>로 보관된다고 한다. </li>
</ul>
<h2 id="인수의-타입-문제">인수의 타입 문제</h2>
<ul>
<li>함수를 정의할 때 타입을 지정할 수 없으므로 나중에 인수로 의도하지 않은 타입이 들어올 경우 문제가 된다. 따라서 함수를 정의할 때 함수몸체에서 <code>typeof</code> 등을 활용하여 적절한 타입의 인수가 전달되었는지 확인할 필요가 있다.</li>
</ul>
<h2 id="매개변수-기본값">매개변수 기본값</h2>
<ul>
<li>함수를 선언할 때 기본값을 사용하면 인수가 전달되지 않았을 때, undefined를 전달했을 때 기본값이 적용된다.</li>
</ul>
<pre><code class="language-javascript">function add(a=0, b=0) {
  return a + b;
}

console.log(add(1)); //1
//만약 기본값을 사용하지 않으면 NaN이 리턴된다. </code></pre>
<h2 id="반환문">반환문</h2>
<blockquote>
<p>반환문은 <code>return</code> 키워드와 <code>표현식(반환값)</code>으로 구성된다. </p>
</blockquote>
<h3 id="반환문의-역할">반환문의 역할</h3>
<ol>
<li>함수의 실행을 중단하고, 함수를 빠져나간다.</li>
</ol>
<ul>
<li>반환문 이후의 문들은 실행되지 않는다.</li>
<li><code>return</code> 키워드 뒤에 줄바꿈을 하고 반환값을 입력하면? 세미콜론이 자동으로 삽입되어 반환값이 무시된다.</li>
</ul>
<ol start="2">
<li>return 키워드 뒤에 오는 표현식을 평가하여 반환한다. </li>
</ol>
<ul>
<li>표현식이 없다면 <code>undefined</code>가 반환될 것이다. </li>
</ul>
<pre><code class="language-javascript">function add(a,b) {
    return;
}

console.log(add()); //undefined
console.log(add(1)); //undefine</code></pre>
]]></description>
        </item>
    </channel>
</rss>