<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>환영합니당 :&gt;</title>
        <link>https://velog.io/</link>
        <description>Web Frontend Engineer 👷</description>
        <lastBuildDate>Sat, 19 Oct 2024 06:28:29 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>환영합니당 :&gt;</title>
            <url>https://velog.velcdn.com/images/kr-younghoon/profile/ef73638a-c264-4afe-a3e6-8957fedb5cd5/image.JPEG</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 환영합니당 :&gt;. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/kr-younghoon" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[회고 톺아보기]]></title>
            <link>https://velog.io/@kr-younghoon/%ED%9A%8C%EA%B3%A0-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@kr-younghoon/%ED%9A%8C%EA%B3%A0-%ED%86%BA%EC%95%84%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Sat, 19 Oct 2024 06:28:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>다양한 글들을 참고하였습니다. 아래에 출처를 밝힙니다.</p>
</blockquote>
<p>우리는 다양한 프로젝트와 수많은 일정들을 통해 다양한 경험과 성장을 하게 되요.
그 속에서 기록하는 습관의 중요성은 항상 필요하다고 매순간마다 느끼죠.
취업의 과정에서도 중요하겠지만, 개인의 성장 속에서 분주함 속에서 
바라보지 못했던 것들도 다시 되새길 수 있는 순간이라고 생각해요.</p>
<p>오늘 함께 회고 라는 개념을 자체를 알아보며, 
또 어떤 방향으로 하면 좋을지 생각해보면서 회고를 습관화해봐요.</p>
<h1 id="retrospective-회고-🙄">Retrospective. 회고. 🙄.</h1>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/d5bd7d9e-d5aa-4c71-8993-5fb61116dec0/image.png" alt="">
<img src="https://velog.velcdn.com/images/kr-younghoon/post/0546f604-3bc3-48c2-a31e-0fd4aaf04fe3/image.png" alt="">
돌아보는 것. 지난 일을 돌이켜 생각하는 것. 또 예술가가 인생에서 해온 작업을 보여주는 쇼 라는 뜻도 가지고 있네요. 뒤를 의미하는 &#39;retro&#39;, 본다는 의미의 &#39;spectare&#39;가 합쳐져 뒤를 돌아보는 뜻을 가지고 있는 것 같아요.</p>
<h1 id="회고의-목적-💫">회고의 목적 💫</h1>
<p>아무래도 뒤를 돌아본다는 것은 앞으로 내가 나아가기 위한 방향을 정하기 위함인거 같아요.
내가 어느 부분에서 부족했고, 잘했기 때문에 나의 다음 Step을 정하는 것이라고 생각해요.</p>
<p>그렇기 때문에 자신의 특정한 이벤트의 회고가 될수도 있고, 팀, 프로젝트, 개인 분기마다도 정해서 작성을 하는 것 같아요. 나의 다음 Step이라고 이야기도 했지만, 팀의 다음 Step이 될수도 있는것 같아요.
<img src="https://velog.velcdn.com/images/kr-younghoon/post/3b44ada1-72e7-45bb-8856-66598dc60dbb/image.png" alt="실리콘밸리 10+년, 한국 IT 용어가 어려워요 : (5) “회고”, “부검”-Chaesang
">
예전엔 Review라고 부르며 회고했던게 흥미로워요.</p>
<h1 id="회고의-종류">회고의 종류</h1>
<p>그래서 어떤 목표이냐에 따라, 누구와 하느냐에 따라 다양한 전략을 가지고 회고를 진행하는게 좋아요.
함께 3LS , ORID , PTK 등에 대해서 알아봐요.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[💫 react-query 도입기]]></title>
            <link>https://velog.io/@kr-younghoon/react-query-%EB%8F%84%EC%9E%85%EA%B8%B0</link>
            <guid>https://velog.io/@kr-younghoon/react-query-%EB%8F%84%EC%9E%85%EA%B8%B0</guid>
            <pubDate>Sun, 06 Oct 2024 12:18:49 GMT</pubDate>
            <description><![CDATA[<h2 id="문제">문제</h2>
<p>현재 프로젝트에서 직접 fetch를 통해 통신하면서 데이터를 처리하고 있다.</p>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/c7c9ea2d-fb6a-414b-ae6e-31082b078248/image.png" alt=""></p>
<p>하지만 이 방식의 경우 다수 반복되는 요청과 최신 데이터를 받아오지 못하고, 받아오려면 최신 페이지로 새로고침 되는 등의 문제들이 발생하고 있다.</p>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/7166a803-9d65-4eaa-a533-78587ce70a93/image.png" alt="">
작성버튼을 누르면 최신으로 바로 되지 않는 문제가 있었다. 낙관적 업데이트, useEffect를 이용한 수동갱신을 해볼까 하다가 차라리 react-query를 도입해보면 어떨까 고민해보고 있습니다.</p>
<p>이글에서는 react-query를 도입해보기 위해 react-query가 무엇인지, 또 어떻게 사용하는지 정리해보도록 하겠습니다.</p>
<h2 id="react-query-란"><code>React-query</code> 란?</h2>
<p>리액트 쿼리는 애플리케이션에서 서버 상태를 불러오고, 캐싱하며, 지속적으로 동기화하고 업데이트 하는 작업을 도와주는 라이브러리입니다. 리액트 쿼리를 사용하면 서버 상태와 클라이언트 상태를 분리하여 관리할 수 있어 React 애플리케이션의 성능, 확장성, 유지 보수성을 향상시킬 수 있습니다. 더불어 서버 상태를 관리하며 마주하는 다양한 문제들을 효과적으로 해결할 수 있습니다.</p>
<p>장점은 데이터 캐싱 및 최적화, 자동 재요청 및 실시간 업데이트, 에러 처리 및 재시도, 중복 요청 방지, 확장성과 유연성 등이 있겠습니다.</p>
<p>자세한 것들은 공식 문서를 확인해주세요.</p>
<h2 id="queryclientprovider-설정">QueryClientProvider 설정</h2>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/f2a92165-a0f6-4a7d-ac77-7467e8652038/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로젝트로 배우는 React & Next 마스터리 클래스 완강]]></title>
            <link>https://velog.io/@kr-younghoon/%EC%99%84%EA%B0%95-1</link>
            <guid>https://velog.io/@kr-younghoon/%EC%99%84%EA%B0%95-1</guid>
            <pubDate>Thu, 11 Jul 2024 18:39:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/5ce05d55-154e-4ead-b1cc-c760deda6de1/image.png" alt=""></p>
<p>이정환님의 프로젝트로 배우는 리액트와 넥스트 마스터리 클래스를 완강했다.</p>
<p>프로젝트를 통해 빠르게 흡수할 수 있었지만, 이후 어떻게 또 잘 써먹어야 할지 기대가 되는 배움이었다.</p>
<p>특히 장표를 통해 깊고 쉽게 알려주셔서 재밌게 들을 수 있는 강의였다. 이후 8월에 Next.js 강의가 나온다는데 가격이 싸다면.. 들어보는 걸로.. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[알고리즘의 효율 분석]]></title>
            <link>https://velog.io/@kr-younghoon/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%98-%ED%9A%A8%EC%9C%A8-%EB%B6%84%EC%84%9D</link>
            <guid>https://velog.io/@kr-younghoon/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%EC%9D%98-%ED%9A%A8%EC%9C%A8-%EB%B6%84%EC%84%9D</guid>
            <pubDate>Wed, 10 Jul 2024 10:55:20 GMT</pubDate>
            <description><![CDATA[<h1 id="01-시간-복잡도란">01 시간 복잡도란?</h1>
<p><code>시간복잡도(time complexity)</code>란? 알고리즘의 성능을 나타내는 지표로, 입력 크기에 대한 연산 횟수의 상한을 의미합니다. 시간 복잡도는 낮으면 낮을수록 좋습니다. 예를 들어, 어떤 문제를 해결하는 알고리즘 A,B,C가 있을 때 시간 복잡도가 가장 낮은 알고리즘이 A라면 A를 사용하는게 좋다.</p>
<h2 id="1차원-배열-검색하기">1차원 배열 검색하기</h2>
<p>1차원 배열에 값이 있을 때 특정 값을 배열의 맨 앞에서 순서대로 검색한다고 해보자. 이 때 연산 횟수가 가장 적을때와 많을 때는 언제일까?</p>
<p>가장 적은 경우는 검색 시작 위에 찾는 값이 바로 있는 경우일 것이고, 많은 경우는 찾는 값이 아예 없거나 가장 마지막에 위치하는 경우일 것이다.</p>
<h2 id="알고리즘-수행-시간을-측정하는-방법">알고리즘 수행 시간을 측정하는 방법</h2>
<p>알고리즘 수행시간 측정 방법으로는 절대 시간을 측정하는 방법과 시간 복잡도를 측정하는 방법이 있습니다.</p>
<h3 id="절대-시간을-측정하는-방법">절대 시간을 측정하는 방법</h3>
<p>배열에서 검색하는 프로그램을 작성한 다음에 프로그램을 실행하여 결과가 나올 때까지의 시간을 측정하면 됩니다.</p>
<p>그러나 이 방법은 프로그램을 실행하는 환경에 따라 달라질 수 있기에 코테에서 잘 활용하지 않습니다.</p>
<h3 id="시간-복잡도를-측정하는-방법">시간 복잡도를 측정하는 방법</h3>
<p>시간 복잡도는 알고리즘이 시작한 순간부터 결괏값이 나올 때까지의 연산 횟수를 나타냅니다.</p>
<p>그리고 시간 복잡도를 측정한결과는 다음과 같이 최선(best), 보통(normal), 최악(worst)의 경우로 나눕니다.</p>
<p>앞에서 설명한 ‘1차원 배열 검색하기’ 알고리즘 처럼 특정한 입력 크기에 따른 연산 횟수로 시간 복잡도를 이야기 하는 것은 특정 상황에 한한 것이므로 무의미합니다.</p>
<p>코딩 테스트에서 알고리즘의 성능을 측정할 떈 2가지가 중요합니다.</p>
<p><strong><em>첫째, 최악의 경우를 고려하라</em></strong></p>
<p>코딩테스트에서는 아주 다양한 조합으로 입력값을 넣어 여러분의 코드를 평가합니다. 그 중에는 최악의 입력값도 있을 겁니다. 그러나 우리는 최악의 경우를 기준으로 시간 복잡도를 분석해야 합니다.</p>
<p><strong><em>둘째, 알고리즘 성능은 정확한 연산 횟수가 아닌 추이를 활용한다.</em></strong></p>
<p>우리가 확인하는 것은 정확한 연산 횟수는 아니다. 내 알고리즘이 제한 시간 안에 수행될 수 있을지를 파악해야한다. 따라서 우리는 숫자 하나하나를 고려하여 구한 정확한 연산 횟수가 아닌, 추이를 활용해 성능을 측정합니다.</p>
<p>코딩 테스트에서 알고리즘의 성능을 측정할 때, 연산 횟수의 추이만 알고 있어도 성능을 충분히 가늠할 수 있고, 정확한 연산 횟수를 구할 때보다 빠르다는 장점이 있습니다. 이런 방식으로 충분히 큰 입력값 N에 따른 연산 횟수의 추이를 활용하여 시간 복잡도를 표현하는 방법을 <code>점근적 표기법</code>이라고 합니다.</p>
<p>그리고 코딩 테스트에서 모든 경우의 수에서 알고리즘이 문제를 처리하는 것을 고려해야 하므로 시간 복잡도는 최악의 경우를 가정하여 이야기하는 것이 일반적입니다.</p>
<h2 id="최악의-경우-시간-복잡도를-표현하는-빅오-표기법big-o-notation">최악의 경우 시간 복잡도를 표현하는 빅오 표기법(Big-O notation)</h2>
<p>최악의 경우에 대하여 시간 복잡도를 표현하는 방법은 무엇이 있을까요? 가장 많이 사용하는 점근적 표기법은 상한선을 활용하는 방법입니다. 이 표기법을 <code>빅오 표기법</code>이라고 합니다.</p>
<p>어떤 프로그램의 연산 횟수가 f(x)라고 할 때 함수의 최고차항을 남기고 계수를 지워 O(…)와 같이 표기하면 됩니다. 예를 들어 어떤 프로그램의 연산 횟수가 <code>f(x) = 2x^2 + 3x + 5</code> 라면 시간 복잡도를 O(x^2)과 같이 표현하면 됩니다. </p>
<blockquote>
<p>상한선은 빅오 표기법, 하한선은 빅 오메가 표기법으로 표시합니다.</p>
</blockquote>
<table>
<thead>
<tr>
<th>수식</th>
<th>빅오표기</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>3x^2 + 5x + 6</td>
<td>O(x^2)</td>
<td>다항함수로 구성되어 있으므로 최고차항 x^2만 남습니다.</td>
</tr>
<tr>
<td>x + log x</td>
<td>O(x)</td>
<td>다항함수와 로그함수로 구성되어 있으므로 증가폭이 더 낮은 로그함수는 사라지고 다항함수만 남습니다.</td>
</tr>
<tr>
<td>2^x + 10x^5 + 5x^2</td>
<td>O(2^x)</td>
<td>지수함수는 다항함수보다 빠르게 증가하므로 지수함수만 남습니다.</td>
</tr>
<tr>
<td>5x^2 - 6x</td>
<td>O(x^2)</td>
<td>최고차항 x^2만 남습니다.</td>
</tr>
</tbody></table>
<h3 id="그나저나-왜-이렇게-표기할까">그나저나 왜 이렇게 표기할까?</h3>
<p>빅오 표기법으로 최악의 시간 복잡도를 표기하는 방법 자체가 어렵지는 않습니다. 그런데 이 식은 어디서 나온걸까요? 아래 예시 코드를 확인해보자.</p>
<pre><code class="language-jsx">function solution(n) { 
    let count = 0;
    // 반복문 1 : n^2번 연산 수행
    for (let i = 0; i &lt; n; i += 1) {
        for (let j = 0; j &lt; n; j += 1) {
            count += 1;
        }
    }

    // 반복문 2 : n번 연산 수행
    for (let k = 0; k &lt; n; k += 1) {
        count += 1;
    }

    // 반복문 3 : 2n번 연산 수행
    for (let i = 0; i &lt; 2 * n; i += 1) {
        count += 1;
    }

    // 반복문 4 : 5번 연산 수행
    for (let i = 0; i &lt; 5; i += 1) {
        count += 1;
    }

    console.log(count); //  59(n이 6일 때, 6^2 + 6 + 2 * 6 + 5 = 59)
}

solution(6); // 함수 호출</code></pre>
<p>solution() 함수는 주석 영역별로 각각 n^2, n + 2n, 5번의 증가 연산을 하며 결괏값은 곧 연산 횟수를 의미합니다. 지금의 경우 solution(6)을 호출하면, 6^2 + 6 + 2 * 6 + 5, 즉, 연산횟수는 59입니다. 이때 solution()함수는 식으로 다음과 같이 표현할 수 있습니다.</p>
<p>$$
f(x) = x^2 + 3x + 5
$$</p>
<p>이때 다음을 만족하는 C가 있으면 f(x)의 최악의 시간 복잡도는 O(g(x))라고 쓰는 겁니다.</p>
<ul>
<li>특정 x 시점 이후부터 항상 f(x) ≤ C* g(x)를 만족.</li>
<li>C는 상수.</li>
</ul>
<p>→ 이게 뭔소릴까. </p>
<p>쉽게 말해 g(x)에 상수 C를 곱했을 때 특정 시점부터 f(x)를 넘어서는지 여부를 보면 됩니다. </p>
<h3 id="c는-2-gx는-x2일때의-그래프-예시">C는 2, g(x)는 x^2일때의 그래프 예시.</h3>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/e30d614f-d29a-4fdc-aaf9-b703ef333395/image.png" alt=""></p>
<p>(이미지 출처: <a href="https://wikidocs.net/222560">https://wikidocs.net/222560</a>)</p>
<p>그래프를 보면 대략 x = 4부터 항상 2x^2가 f(x)를 넘으므로 위 공식을 만족합니다. 하지만 위 공식을 만족하는 g(x)는 하나만 있을까요? </p>
<p>“g(x) = x, C = 50인 경우 x에 값을 몇개 넣어보니 f(x)보다 값이 크네…? 그렇다면 시간 복잡도는 O(x)라고 해도 되는 것아닐까?”</p>
<p>→ 조금만 생각해보면 아니라는 걸 알 수 있습니다. 왜냐면, 50x는 대략 x = 47에서 다시 역전되기 때문이죠. 이런 이유로 f(x) = x^2 + 3x + 5의 시간 복잡도는 O(x^2)라고 쓸수있습니다.</p>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/dc3e827e-d14a-4f5d-89c9-5775e674504e/image.png" alt=""></p>
<h3 id="빅오-표기법을-쉽게-쓸-때는-왜-최고차항만-남기고-계수를-지울까">빅오 표기법을 쉽게 쓸 때는 왜 최고차항만 남기고 계수를 지울까?</h3>
<p>앞서 빅오표기법은 다음과 같이 f(x)의 최고차항만 남기고 계수를 지워 O(…)와 같이 쓸수있다고 했습니다. 어떻게 이렇게 되는지 설명해드림.</p>
<ul>
<li>f(x) = x^2 + 3x + 5 에서 최고 차항인 x^2만 남김</li>
<li>x^2는 앞의 계수가 1이므로 제거할 것이 없음</li>
<li>시간 복잡도는 O(x^2)</li>
</ul>
<p><strong>(이후 다양한 함수의 시간 복잡도를 비교한 예시는 생략한다.)</strong></p>
<p>→ 우리가 시간복잡도에서 구하는 것은 상한의 정확한 값이 아니라 ‘이 정도 될 것이다’의 파악하는 추이이기에 우리가 우선적으로 파악해야할 것은 상한을 구하는 목적인 알고리즘의 성능을 가늠할 수 있는 가장 의미 있는 상한을 구하는 게 중요합니다.</p>
<h2 id="시간-복잡도를-코딩-테스트에-활용하는-방법">시간 복잡도를 코딩 테스트에 활용하는 방법</h2>
<p>시간 복잡도를 표현하는 방법이 빅오 표기법이라는 것은 알았는데 어떻게 활용해야할까? 코딩테스트 문제에는 제한 시간이 있으므로 문제를 분석한 후에 빅오 표기법을 활용해서 해당 알고리즘을 적용했을 때 제한 시간 내에 출력 값이 나올 수 있을지 확인해 볼 수 있습니다. 그러면 문제 조건에 맞지 않는 알고리즘을 적용하느라 낭비하는 시간을 줄일 수 있습니다.</p>
<p>코딩테스트의 문제들은 출제자가 의도한 로직을 구현했다면 대부분의 코드를 정답 처리할 수 있도록 채점 시간을 충분히 여유있게 지정합니다. 따라서 연산 횟수를 1000-3000만 정도로 고려해서 시간 복잡도를 생각하면 됩니다. 예를 들어 제한 시간이 1초인 문제는 연산 횟수가 3000만이 넘는 알고리즘은 사용하면 안됩니다. 제한 시간이 1초인 문제에 각 시간 복잡도 별로 허용할 수 있는 최대 연산 횟수는 다음과 같이 생각하면 됩니다.</p>
<blockquote>
<p>언어별로 성능은 다를 수 있으나, 특정 언어가 유리하거나 불리하면 안되기에 언어에 따른 성능차이를 고려하진 않아도 됩니다.</p>
</blockquote>
<p>시간 복잡도별 최대 연산 횟수를 기계처럼 외울 필요는 없습니다. 표를 보면 연산 횟수의 간격이 매우 큽니다. 그 이유는 여러분이 구현한 코드의 시간복잡도가 문제에서 요구하는 성능을 만족하면 모두 통과할 수 있도록 충분히 여유를 두기 때문입니다. ‘이 정도 되는구나’ 감을 잡으면 되고, 다른 책에서는 O(N)이면 1000만이라고 했는데, 왜 여기선 1000만 ~ 2000만이라고 하는지 고민하기보다는, ‘대략 데이터가 1000만개 정도면 O(N)을 사용해야 하는구나’ 감을 익히는 식으로 학습하는 걸 추천합니다.</p>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/bd2eb604-32f8-46f0-96b2-8cc89675f74a/image.png" alt=""></p>
<p>맨 처음 우리가 살펴본 배열에서 검색하기 방식을 보면 하나하나 짚어가며 찾는 방식은 시간복잡도가 O(N)입니다. O(N)이 허용하는 연산 횟수는 1000만이므로 데이터 개수가 1000만개 이하면 이 알고리즘을 사용해도 됩니다. 바로 이렇게 시간 복잡도를 활용하여 문제가 제시하는 제한 시간을 초과하는 알고리즘을 제거하면 됩니다.</p>
<h1 id="02--시간-복잡도-계산해보기">02  시간 복잡도 계산해보기</h1>
<p>시간 복잡도를 실전으로 계산해보자. 몇 가지 상황을 보며, 시간 복잡도를 계산하는 방법을 익혀두면 다른 문제를 풀 때도 시간 복잡도를 수월하게 계산해볼 수 있을 것이다.</p>
<ol>
<li>문제 정의 부터 시작해서 </li>
<li>연산 횟수를 측정한 후</li>
<li>시간 복잡도를 분석하는</li>
</ol>
<p>순서로 공부를 해보자.</p>
<h2 id="별-찍기-문제">별 찍기 문제</h2>
<p>별 찍기 문제는 숫자 N을 입력받으면 N번째 줄 까지 별을 1개부터 N개까지 늘려가며 출력하라는 것입니다. </p>
<h3 id="푸는-과정">푸는 과정</h3>
<p>우선 연산 횟수를 구합니다. 지금은 출력 자체가 연산입니다. 1번째 줄은 1번 연산, 2번째 줄은 2번 연산, … , N번째 줄은 N번 연산합니다.</p>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/7c7bc355-246b-4476-ac6f-efcdf967bcb2/image.png" alt=""></p>
<p>결국 연산 횟수는 f(N)는 다음과 같습니다. 빅오 표기법으로는 O(N^2)이라고 할 수 있겠습니다.</p>
<p>$$
f(N) = 1 + 2 + ... + N = \frac{N(N+1)}{2}
$$</p>
<h2 id="박테리아-수명-문제">박테리아 수명 문제</h2>
<p>초기 박테리아 세포 개수가 N일 때 해마다 세포 개수가 이전 세포 개수의 반으로 준다면 언제 모든 박테리아가 죽을지 계산해야 합니다.</p>
<h3 id="푸는-과정-1">푸는 과정</h3>
<p>예를 들어 N이 16인 경우, 모든 박테리아는 5년이면 소멸합니다.</p>
<p>현재 박테리아 수가 N이라면, 1년 뒤 박테리아 수는 ½ * N이라고 할 수 있습니다. Y년 후의 박테리아의 수는 (½)^Y * N입니다. </p>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/bc34f461-1b54-4164-b758-4fe451368787/image.png" alt=""></p>
<p>그러면 박테리아의 소멸 시기는 (½)Y<em>N의 값이 최초로 1보다 작아질 때입니다. 수식으로는 (½)Y</em>N &lt;= 1인 Y를 찾으면 됩니다. 이 수식은 다음과 같이 정리할 수 있습니다.</p>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/56f3eebe-2314-4b37-abd3-a1663417ec3e/image.png" alt=""></p>
<p>이를 통해 이 알고리즘은 O(logN)의 시간 복잡도를 가진다는 것을 알 수 있습니다.</p>
<blockquote>
<p>앞으로 문제를 풀 때 특정 값을 계속 반으로 줄이는 동작을 한다면 시간 복잡도를 O(log N)이라 생각하면 됩니다. 시간 복잡도가 O(log N)인 문제들은 이후 정렬이나 이진 트리를 공부하면서 다시 보겠습니다.</p>
</blockquote>
<p>지금까지 빅오 표기법으로 알고리즘의 효율을 분석하는 방법을 분석하는 방법을 공부했습니다. 코딩 테스트에서 시간 복잡도를 이해하고 분석하는 것은 매우 중요합니다.</p>
<h1 id="리마인드">리마인드</h1>
<ul>
<li>입력 크기에 따른 연산 횟수의 추이를 활용해서 시간 복잡도를 표현하는 방법을 점근적 표기법이라고 합니다.</li>
<li>시간 복잡도를 빅오 표기법으로 나타내려면 데이터 개수 N 에 대해 연산 횟수를 일반화한 후 최고차항을 남기고 개수 N에 대해 연산 횟수를 일반화한 후 최고 차항을 남기고 계수를 제거하면 됩니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CH2 타입시스템_러닝타입스크립트]]></title>
            <link>https://velog.io/@kr-younghoon/CH2-%ED%83%80%EC%9E%85%EC%8B%9C%EC%8A%A4%ED%85%9C</link>
            <guid>https://velog.io/@kr-younghoon/CH2-%ED%83%80%EC%9E%85%EC%8B%9C%EC%8A%A4%ED%85%9C</guid>
            <pubDate>Mon, 08 Jul 2024 19:09:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>자바스크립트의 힘은 유연함에서 나옵니다. 그 유연함을 조심하세요!</p>
</blockquote>
<p>2장에서 타입 검사기가 실제로 어떻게 작동하는지 알아보자.</p>
<h1 id="21-타입의-종류">2.1 타입의 종류</h1>
<p><code>타입</code>은 자바스크립트에서 다루는 값의 형태에 대한 <strong>설명</strong>이다.</p>
<p>형태란? 값에 존재하는 속성과 메서드 그리고 내장되어 있는 <code>typeof</code> 연산자가 설명하는 것을 의미한다.</p>
<h3 id="예시-코드">예시 코드</h3>
<pre><code class="language-jsx">let singer = &quot;Aretha&quot;;</code></pre>
<p>예를 들어 다음과 같이 초깃값이 ‘Aretha`인 변수를 생성할 경우, 타입스크립트는 singer 변수가 문자열 타입임을 유추할 수 있다.</p>
<p>타입스크립트의 가장 기본적인 타입은 JS의 일곱가지 기본 원시 타입(primitive type) 동일합니다.</p>
<h2 id="타입스크립트는-다음-원시타입을-다음과-같이-분류한다">타입스크립트는 다음 원시타입을 다음과 같이 분류한다.</h2>
<ul>
<li>null → null;</li>
<li>undefined → undefined;</li>
<li>boolean → true;</li>
<li>string → “Louise”;</li>
<li>number → “1337”;</li>
<li>bigint → “1337n”;</li>
<li>symbol → Symbol(”Franklin”);</li>
</ul>
<p>타입스크립트는 계산된 초깃값을 갖는 변수의 타입을 유추할 수 있을 만큼 똑똑하다. 
(JS 삼항연산자를 가지고 해당 삼항연산자 변수의 타입을 string으로 유추하는 정보상자에 대한 예시를 책에서 제시했다.)</p>
<blockquote>
<p>자바스크립트에서 객체와 원시 타입 간의 차이점을 떠올려보세요. Boolean과 Number와 같은 객체는 각 원싯값을 감싸는 객체입니다. 타입스크립트에서는 일반적으로 boolean과 number처럼 소문자로 참조하는 것이 모범 사례입니다.</p>
</blockquote>
<h2 id="211-타입-시스템">2.1.1 타입 시스템</h2>
<p>타입 시스템(type system)은 프로그래밍 언어가 프로그램에서 가질 수 있는 타입을 이해하는 방법에 대한 규칙 집합이다.</p>
<p>기본적으로 타입스크립트의 타입 시스템은 다음과 같이 작동한다.</p>
<ol>
<li>코드를 읽고 존재하는 모든 타입과 값을 이해합니다.</li>
<li>각 값이 초기 선언에서 가질 수 있는 타입을 확인합니다.</li>
<li>각 값이 추후 코드에서 어떻게 사용될 수 있는지 모든 방법을 확인합니다.</li>
<li>값의 사용법이 타입과 일치하지 않으면 사용자에게 오류를 표시합니다.</li>
</ol>
<h3 id="타입-추론-과정-자세히-살펴보기">타입 추론 과정 자세히 살펴보기</h3>
<p>타입스크립트가 멤버 속성을 함수로 잘못 호출해 타입 오류가 발생하는 코드입니다.</p>
<pre><code class="language-jsx">let firstName = &quot;Whitney&quot;;
firstName.length();
//        ~~~~~~~~~
// Error: This expression is not callable.
//    Type &#39;Number&#39; has no call signatures</code></pre>
<p>타입스크립트는 다음과 같은 순서로 오류를 표시한다.</p>
<ol>
<li>코드를 읽고 firstName 이라는 변수를 이해한다.</li>
<li>초깃값이 “Whitney” 이므로 firstName이 String 타입이라고 결론짓습니다.</li>
<li>firstName의 .length 멤버를 함수처럼 호출하는 코드를 확인합니다.</li>
<li>string의 .length 멤버는 함수가 아닌 숫자라는 오류를 표시합니다. 즉, 함수처럼 호출 할 수 없습니다.</li>
</ol>
<p>타입스크립트의 타입 시스템에 대한 이해는 타입스크립트 코드를 이해하는 데 중요한 기술이다.</p>
<h2 id="212-오류-종류">2.1.2 오류 종류</h2>
<p>타입스크립트를 작성하는 동안 가장 자주 접하게 되는 오류 두 가지는 다음과 같다.</p>
<ul>
<li>구문 오류 : 타입스크립트가 자바스크립트로 변환되는 것을 차단한 경우</li>
<li>타입 오류 : 타입 검사기에 따라 일치하지 않는 것이 감지된 경우</li>
</ul>
<p>둘 사이의 차이점은 중요하다. 자세히 알아보자.</p>
<h3 id="구문-오류">구문 오류</h3>
<p>구문 오류는 타입스크립트가 코드로 이해할 수 없는 잘못된 구문을 감지할 때 발생.</p>
<p>이는 타입 스크립트가 타입스크립트 파일에서 자바스크립트 파일을 올바르게 생성할 수 없도록 차단한다.</p>
<p>물론 TS 코드를 JS 코드로 변환하는데 사용하는 도구와 설정에 따라 JS 코드를 얻을 수 있다. 하지만 결과가 우리의 예상과 상당히 다를수도 있다.</p>
<p>다음 타입스크립트에서는 예기치 않은 let 에 대한 구문 오류가 발생합니다.</p>
<pre><code class="language-jsx">let let wat;
//      ~~~
// Error: &#39;,&#39; expected.</code></pre>
<p>타입스크립트 컴파일러 버전에 따라 컴파일된 자바스크립트 결과는 다음과 같다.</p>
<pre><code class="language-jsx">let let, wat;</code></pre>
<blockquote>
<p>타입스크립트는 구문 오류와는 상관없이 자바스크립트 코드를 출력하기 위해 최선을 다하지만, 여러분이 원하는 출력 결과가 아닐 수 있습니다. 따라서 출력된 자바스크립트를 실행하기 전에 구문 오류를 수정하는 것이 좋습니다.</p>
</blockquote>
<h3 id="타입-오류">타입 오류</h3>
<p>타입 오류는 타입스크립트의 타입 검사기가 프로그램의 타입에서 오류를 감지했을 때 발생합니다. 오류가 발생했다고 해서 타입스크립트 구문이 자바스크립트로 변환되는 것을 차단하지 않습니다.하지만 코드가 실행되면 무언가 충돌하거나 예기치 않게 작동할 수 있음을 나타냅니다.</p>
<p>타입스크립트는 타입 오류가 있음에도 불구하고 JS 코드를 출력할 수 있지만, 출력된 JS 코드가 원하는 대로 실행되지 않을 가능성이 있다는 신호를 타입 오류로 알려줍니다. 자바스크립트를 실행하기 전에 타입 오류를 확인하고 발견된 문제를 먼저 해결하는 것이 가장 좋습니다.</p>
<blockquote>
<p>어떤 프로젝트는 구문 오류 뿐 아니라 모든 타입스크립트 타입 오류가 수정될 때까지 코드 실행을 차단하기도 합니다. 필자를 포함한 많은 개발자는 이 방식이 성가시고 불필요하다고 생각합니다. 대부분의 프로젝트는 13장에서 살펴볼 구성 옵션과 tsconfig.json 파일을 사용해 차단하지 않도록 설정합니다.</p>
</blockquote>
<h1 id="22-할당-가능성">2.2 할당 가능성</h1>
<p>타입스크립트는 변수의 초깃값을 읽고 해당 변수가 허용되는 타입을 결정합니다. 나중에 해당 변수에 새로운 값이 할당되면, 새롭게 할당된 값의 타입이 변수의 타입과 동일한지 확인합니다.</p>
<p>타입스크립트 변수에 동일한 타입의 다른 값이 할당될 때는 문제가 없습니다. </p>
<p>예를 들어 변수가 처음에 string 값이면 나중에 다른 string 값을 할당하는 것은 문제가 되지 않습니다.</p>
<pre><code class="language-jsx">let firstName = &quot;Carole&quot;;
firstName = &quot;Joan&quot;;</code></pre>
<p>하지만 TS 변수에 다른 타입의 값이 할당되면 타입 오류가 발생합니다.</p>
<p>예를 들어 처음에는 string 값으로 변수를 선언한 다음 나중에 boolean 값을 넣을 수 없습니다.</p>
<pre><code class="language-jsx">let lastName = &quot;King&quot;;
lastName = true;
// ~~~~~
// Error : Type &#39;boolean&#39; is not assignable to type &#39;string&#39;.</code></pre>
<p>타입스크립트에서 함수 호출이나 변수에 값을 제공할 수 있을지 여부를 확인하는 것을 <code>할당가능성(assignability)</code>라고 합니다.</p>
<p>즉, 전달된 값이 예상된 타입으로 할당 가능한지 여부를 확인합니다.</p>
<p>할당가능성은 이번장 이후 더 복잡한 객체를 비교할 때 더 중요한 용어가 됩니다.</p>
<h2 id="221-할당-가능성-오류-이해하기">2.2.1 할당 가능성 오류 이해하기</h2>
<p><code>Type ... is not assignable to type ..</code> 형태의 오류는 타입스크립트 코드를 작성할 때 만나게 되는 가장 일반적 오류 중 하나이다.</p>
<p>해당 오류 메시지에서 언급된 첫번째 type은 코드에서 변수에 할당하려고 시도하는 값이다. 두번째 type 은 첫번째 타입, 즉, 값이 할당되는 변수이다.</p>
<p>예를 들어, 이전 코드 스니펫에서 lastName = true를 작성할 때 boolean 타입인 true 값을 string 타입인 변수 lastName에 할당하려고 했다.</p>
<p>책을 읽으면서 점점 복잡한 할당 가능성 문제를 보게 될 것입니다. 그리고 실제 타입과 예상된 타입 간에 보고된 차이점을 이해하려면 주의 깊게 읽어야 합니다. → 실제 타입과 예상된 타입 간에 차이점을 이해.</p>
<h1 id="23-타입-애너테이션">2.3 타입 애너테이션</h1>
<p>때로는 변수에 타입스크립트가 읽어야 할 초깃값이 없는 경우도 있다. 타입스크립트는 나중에 사용할 변수의 초기 타입을 파악하려고 시도하지 않는다.
그리고 기본적으로 변수를 암묵적인 <code>any</code> 타입으로 간주한다. 변수는 세상 모든 것이 될 수 있음을 나타낸다.</p>
<p>초기 타입을 유추할 수 없는 변수는 <code>진화하는 any</code> 라고 부른다. 특정 타입을 강제하는 대신 새로운 값이 할당될 때마다 변수 타입에 대한 이해를 발전시킨다.</p>
<h3 id="예시-코드-1">예시 코드</h3>
<pre><code class="language-jsx">let rocker; // type: any
rocker = &quot;Joan Jett&quot; // type: str

rocker.toUpperCase(); // OK

rocker = 19.58; // type : number
rocker.toPrecision(1); // OK

rocker.toUpperCase();
//     ~~~~~~~~~~~~~
// Error: &#39;toUpperCase&#39; does not exist on type &#39;number&#39;.</code></pre>
<p>예시 코드를 보면 진화하는 any 변수 rocker 에 처음에는 문자열이 할당되는데, toUpperCase() 같은 str 메서드를 갖는 것을 의미하지만, 다음엔 number 타입으로 진화되는 것을 확인할 수 있다.
TS 는 number 타입으로 진화한 변수가 toUpperCase() 메서드를 호출하는 것을 포착했다. 그러나 변수가 str 타입에서 num 타입으로 진화된것이 처음부터 의도된 것인지 알수없습니다.</p>
<p>일반적으로 any 타입을 사용해 any 타입으로 진화하는 것을 허용하게 되면 타입스크립트의 타입 검사 목작을 부분적으로 쓸모없게 만듭니다. 타입스크립트는 값이 어떤 타입인지 알고 있을 때 가장 잘 작동합니다. any 타입을 가진 값에는 타입 스크립트의 타임(타입?) 검사 기능을 잘 적용할 수 없습니다. 검사를 위해 알려진 타입이 없기 때문입니다.</p>
<p>타입 스크립트는 초깃값을 할당하지 않고 변수 타입을 선언할 수 있는 구문인 타입 어노테이션(type annotation)을 제공합니다. 타입 어노테이션은 변수 이름 뒤에 배치되며 콜론(:)과 타입 이름을 차례로 기재합니다. 이런 식으로요</p>
<h3 id="예시-코드-2">예시 코드</h3>
<pre><code class="language-jsx">let rocker: string;
rocker = &quot;Joan Jett&quot;;</code></pre>
<p>이러한 타입 어노테이션은 타입스크립트에만 존재하며 런타임 코드에 영향을 주지도 않고, 유효한 JS 구문도 아닙니다. tsc 명령어를 실행해 TS 소스 코드를 JS로 컴파일하면 해당 코드가 삭제됩니다. 예를 들어 앞의 예제는 다음 JS 코드로 컴파일됩니다.</p>
<pre><code class="language-jsx">// 출력된 .js 파일
let rocker;
rocker = &quot;Joan Jett&quot;;</code></pre>
<p>변수에 타입 어노테이션으로 정의한 타입 외의 값을 할당하면 타입 오류가 발생합니다.</p>
<h2 id="231-불필요한-타입-어노테이션">2.3.1 불필요한 타입 어노테이션</h2>
<p>타입 어노테이션은 타입 스크립트가 자체적으로 수집할 수 없는 정보를 타입스크립트에 제공할 수 있습니다. 타입을 즉시 유추할 수 있는 변수에도 타입 어노테이션을 사용할 수 있습니다. 하지만 TS가 아직 알지 못하는 것은 알려주지 못합니다.</p>
<p>다음 코드에서 str 타입 어노테이션은 중복입니다. 타입스크립트가 이미 firstName 이 str 타입임을 유추할 수 있기 때문입니다.</p>
<h3 id="예시코드">예시코드</h3>
<pre><code class="language-jsx">let firstName: string = &quot;Tina&quot;; // 타입 시스템은 변경되지 않음.</code></pre>
<p>초깃값이 있는 변수에 타입 어노테이션을 추가하면 타입스크립트는 변수에 할당된 값의 타입이 일치하는지 확인합니다.</p>
<p>다음 firstName은 string 타입으로 선언되었지만, number 값인 42로 초기화되었습니다.</p>
<h3 id="예시코드-1">예시코드</h3>
<pre><code class="language-jsx">let firstName: string = 42;
//  ~~~~~~~~~
// Error: Type &#39;number&#39; is not assignable to type &#39;string&#39;.</code></pre>
<p>보통 아무것도 변하지 않는 변수에는 타입 어노테이션을 추가하지 않기를 선호합니다 .타입 어노테이션은 수동으로 작성하는 일은 번거롭습니다. 특히 타입이 변경되거나 복잡한 타입일 때 더욱 그렇습니다. </p>
<p>코드를 명확하게 문서화하거나 실수로 변수 타입이 변경되지 않도록 타입스크립트를 보호하기 위해 변수에 명시적으로 타입 어노테이션을 포함하는 것이 경우에 따라서는 유용할 수 있습니다.</p>
<h1 id="24-타입-형태">2.4 타입 형태</h1>
<p>타입스크립트는 벼눗에 할당된 값이 원래 타입과 일치하는지 확인하는 것 이상을 수행합니다.</p>
<p>타입스크립트는 객체에 어떤 멤버 속성이 존재하는지 알고 있습니다.</p>
<h3 id="코드-예시">코드 예시</h3>
<pre><code class="language-jsx">let rapper = &quot;Queen Latifah&quot;;
rapper.length; // OK</code></pre>
<p>str 타입의 rapper 변수를 선언한다고 가정합니다. 나중에 rapper 변수를 사용할 때 TS가 str 타입에서 사용 가능한 작업만을 허용한다.</p>
<p>TS 가 str 타입에서 작동하는지 알 수 없는 작업은 허용되지 않는다.</p>
<pre><code class="language-jsx">rapper.push(&#39;!&#39;);
//     ~~~~
// Error: Property &#39;Push&#39; does not exist on type &#39;String&#39;</code></pre>
<p>타입은 더 복잡한 형태, 특히 객체일수도 있다. 다음 스니펫에서 타입스크립트는 cher 객체에 middleName 키가 없다는 것을 알고 오류를 표시합니다.</p>
<pre><code class="language-jsx">let cher = {
    firstName: &quot;Cherilyn&quot;,
    lastName: &quot;Sarkisian&quot;,
};

cher.middleName;
//   ~~~~~~~~~~
// Error: Property &#39;middleName&#39; does not exist on type
// &#39;{ firstName: string; lastName: string; }&#39;.</code></pre>
<p>TS는 객체의 형태에 대한 이해를 바탕으로 할당 가능성뿐만 아니라 객체 사용과 관련된 문제도 알려줍니다.</p>
<h2 id="241-모듈">2.4.1 모듈</h2>
<p>JS는 비교적 최근까지 서로 다른 파일에 작성된 코드를 공유하는 방법과 관련도니 사양을 제공하지 않습니다.</p>
<p>ECMA Script 2015 에는 파일간에 가져오고(import) 내보내는(export) 구문을 표준화하기 위해 ECMA Script Modules(ESM)를 추가되었스빈다.</p>
<pre><code class="language-jsx">import { value } from &#39;./values&#39;;

export const doubled = value * 2;</code></pre>
<p>ECMA 스크립트 사양과 일치시키기 위해 명명법을 사용합니다.</p>
<ul>
<li>모듈. export , import 가 있는 파일</li>
<li>스크립트. 모듈이 아닌 모든 파일</li>
</ul>
<p>TS 는 최신 모듈 파일을 기존파일과 함께 실행할 수 있습니다.</p>
<p>모듈 파일에 선언된 모든 것은 해당 파일에서 명시한 export 문에서 내보내지 않는 한 모듈 파일에서만 사용할 수 있습니다.</p>
<p>한 모듈에서 다른 파일에 선언된 변수와 동일한 이름으로 선언된 변수는 다른 파일의 변수를 가져오지 않는 한 이름 충돌로 간주하지 않습니다.</p>
<p>(예시생략. 모듈 선언은 전역 스코프로써 변수 선언과 겹치지 않게 간주된다.)</p>
<blockquote>
<p>TS는 CJS와 같은 이전 모듈을 사용해서 작성된 TS 파일의 import, export 형태는 인식하지 못합니다. 타입 스크립트는 일반적으로 CJS 스타일의 require 함수에서는 반환된 값을 any 타입으로 인식합니다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[CH1 JS에서 TS로_러닝타입스크립트]]></title>
            <link>https://velog.io/@kr-younghoon/CH1-JS%EC%97%90%EC%84%9C-TS%EB%A1%9C</link>
            <guid>https://velog.io/@kr-younghoon/CH1-JS%EC%97%90%EC%84%9C-TS%EB%A1%9C</guid>
            <pubDate>Sat, 29 Jun 2024 17:25:11 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>오늘 날 자바스크립트는 수십 년 전의 아름다운 웹 브라우저를 지원합니다.</p>
</blockquote>
<p>타입스크립트를 이야기하기 전에 타입스크립트의 시발점인 JS부터 살펴보겠습니다.</p>
<h1 id="11-자바스크립트의-역사">1.1 자바스크립트의 역사</h1>
<p>자바스크립트는 별난 특성이 있지만 웹 애플리케이션과 인터넷의 놀라운 성장을 가능하게 만들었습니다.</p>
<blockquote>
<p>만약 제게 완벽한 프로그래밍 언어를 제시한다면, 저는 사용자가 한 명도 없는 언어를 보여주겠습니다. </p>
</blockquote>
<ul>
<li>아네르스 하일스베르, TSConf, 2019<blockquote>
</blockquote>
</li>
</ul>
<h1 id="12-바닐라-자바스크립트의-함정">1.2 바닐라 자바스크립트의 함정</h1>
<p>바닐라(Vanilla) : 중요한 언어 확장이나 프레임워크 없이 JS를 사용하는 것을 <code>바닐라</code> 라고 부릅니다. 순수한 자바스크립트를 의미합니다.</p>
<h2 id="121-값-비싼-자유">1.2.1 값 비싼 자유</h2>
<p>자바스크립트를 사용하는 개발자들의 가장 큰 불만은 핵심 기능에 있었다. 자바스크립트는 사실상 코드를 구성하는 방법에 제한이 없습니다.  이러한 자유 덕분에 프로젝트를 자바스크립트로 시작하면 매우 재미있습니다.</p>
<h3 id="자바스크립트-타입-자유도에-따른-코드-예시">자바스크립트 타입 자유도에 따른 코드 예시.</h3>
<pre><code class="language-jsx">function paintPainting (painter, painting) {
    return painter
        .prepare()
        .paint(painting, painter.ownMaterials)
        .finish();
}</code></pre>
<p>코드 베이스(소프트웨어 구성요소를 빌드할 때 사용하는 소스 코드의 전체 집합)에 대한 이해가 있거나, 함수가 반환되어야 하는지 기억하고 있거나, painting이 문자열이라고 추측할 수 도 있다.</p>
<p>그러나 앞선 가정이 정확하더라도 나중에 코드가 수정된다면 이 가정은 무효가 될 수 도 있다.</p>
<p>다른 언어는 컴파일러가 충돌할 수 있다고 판단하면 코드 실행을 거부할 수 있다. 하지만 자바스크립트처럼 충돌 가능성을 먼저 확인하지 않고 코드를 실행하는 동적 타입언어는 그렇지 않습니다.</p>
<p>결국 코드의 자유는 자바스크립트를 재미있게 만들기도 하지만, 우리의 코드를 안전하게 실행할 때 상당한 고통을 안겨준다.</p>
<h2 id="122-부족한-문서">1.2.2 부족한 문서</h2>
<p>자바스크립트 언어 사양에는 함수의 매개변수, 함수 반환, 변수 또는 다른 구성요소의 의미를 설명하는 표준화된 내용이 없다.</p>
<p>따라서 많은 개발자가 블록 주석으로 함수와 변수를 설명하는 JSDoc 표준을 채택했다. </p>
<pre><code class="language-jsx"> /**
    * Performs a painter painting a particular painting.
    *
    * @param {Painting} painter
    * @param {string} painting
    * @returns {booleen} Whether the painter painted the painting.
    */

function paintPainting(painter, painting) { /*...*/ }
</code></pre>
<p>JSDoc 에는 다음과 같은 주요 문제로 인해 규모가 있는 코드베이스에서 사용하기 불편합니다.</p>
<ul>
<li>JSDoc 설명이 코드가 잘못되는 것을 막을 수 없습니다.</li>
<li>JSDoc 설명이 이전에는 정확했더라도 코드 리팩터링 중에 생긴 변경사항과 관련된 현재 유효하지 않은 JSDoc 주석을 모두 찾기란 어렵습니다.</li>
<li>복잡한 객체를 설명할 때는 다루기 어렵고 장황해서 타입과 그 관계를 정의하려면 다수의 독립형 주석이 필요합니다.</li>
</ul>
<h2 id="123-부족한-개발자-도구">1.2.3 부족한 개발자 도구</h2>
<p>자바스크립트는 타입을 식별하는 내장된 방법을 제공하지 않고, 코드가 JSDoc 주석에서 쉽게 분리되기 때문에 코드베이스에 대한 대규모 변경을 자동화하거나 통찰력을 얻기가 매우 어렵습니다.</p>
<p>자바스크립트 개발자는 C#이나 자바와 같은 타입이 지정된 언어에서 클래스 멤버 이름을 변경하거나 인수의 타입이 선언된 곳으로 바로 이동할 수 있는 기능을 보고 놀란다.</p>
<p>→ 해석이 조금 이상한거 같다.</p>
<h1 id="13-타입스크립트">1.3 타입스크립트</h1>
<p>타입스크립트는 2010년대 초 마이크로소프트 내부에서 만들어진 후 2012년에 출시 및 오픈소스화 되었다.</p>
<p>타입스크립트는 네가지로 설명된다.</p>
<ol>
<li>프로그래밍 언어 : 자바스크립트의 모든 구문과, 타입을 정의하고 사용하기 위한 새로운 타입스크립트 고유 구문이 포함된 언어</li>
<li>타입 검사기 : 자바스크립트 및 타입스크립트로 작성된 일련의 파일에서 생성된 모든 구성 요소(변수, 함수 등)를 이해하고, 잘못 구성된 부분을 알려주는 프로그램</li>
<li>컴파일러 : 타입 검사기를 실행하고 문제를 보고한 후 이에 대응되는 자바스크립트 코드를 생성하는 프로그램</li>
<li>언어 서비스 : 타입 검사기를 사용해 VSC와 같은 편집기에 개발자에게 유용한 유틸리티 제공법을 알려주는 프로그램</li>
</ol>
<h1 id="14-타입스크립트-플레이그라운드에서-시작하기">1.4 타입스크립트 플레이그라운드에서 시작하기</h1>
<p><a href="https://typescriptlang.org/ko/play">https://typescriptlang.org/ko/play</a></p>
<p><img src="https://prod-files-secure.s3.us-west-2.amazonaws.com/e5709b6e-fbb0-4259-9ca5-fd5707753f36/784b3cb1-abc6-46ac-aa6e-3ac96348309c/Untitled.png" alt="Untitled"></p>
<p>이 책에서 사용하는 대부분의 스니펫은 의도적으로 작고 독립적이게 만들었으므로 직접 플레이그라운드에 입력하며 재미 삼아 가지고 놀 수 있습니다.</p>
<h2 id="141-타입스크립트-실전">1.4.1 타입스크립트 실전</h2>
<pre><code class="language-jsx">const firstName = &quot;Georgia&quot;;
const nameLength = firstName.length();
//                           ~~~~~~~~
// Error: This expression is not callable</code></pre>
<p>이 코드에 타입스크립트 타입 검사기를 실행하면, 문자열의 길이 프로퍼티가 함수가 아니라 숫자라는 지식을 활용해 오류를 알려준다.</p>
<h2 id="142-제한을-통한-자유">1.4.2 제한을 통한 자유</h2>
<p>타입스크립트를 사용하면 매개변수와 변수에 제공되는 값의 타입을 지정할 수 있다. 일부 개발자는 처음에 특정 영역(Scope?)이 제한적으로 작동하는 방법을 코드에 명시적으로 작성해야한다고 생각한다. </p>
<p>하지만 저자는 이런 식의 “제한”은 실제로 바람직하다고 생각한다고 한다. 코드를 지정한 방법으로만 사용하도록 제한한다면, 타입스크립트는 코드의 한 영역을 변경하더라도 이 코드를 사용하는 다른 코드 영역이 멈추지 않는다는 확신을 줄 수 있다.</p>
<h3 id="예시--함수의-매개변수-개수를-변경했을-경우--변경된-함수를-호출하는-코드를-업데이트-하지-않았을-때">예시 : 함수의 매개변수 개수를 변경했을 경우,  변경된 함수를 호출하는 코드를 업데이트 하지 않았을 때.</h3>
<p>sayMyName 함수의 매개변수가 두개에서 하나로 변경되었지만, 함수를 호출하는 코드는 여전히 두개의 문자열을 사용해 TS 에러가 발생한다.</p>
<pre><code class="language-jsx">// 이전 코드: sayMyName(firstName, lastNameName) { ...
function sayMyName(fullName) {
    console.log(&#39;You acting kind of shady, ain&#39;t callin&#39; me ${fullNmae}&#39;);
}

sayMyName(&quot;Beyoncé&quot;, &quot;Knowles&quot;);
//
// Error : Expected 1 argument, but got 2.</code></pre>
<p>이 코드는 JS에서 오류 없이 실행되지만, 결과가 예상하는 것과 다르다. (두번째 Knowles는 결과값에서 제외된다.)</p>
<p>잘못된 수의 인수를 사용해서 함수를 호출하는 것은 타입 스크립트가 제한하는 자바스크립트가 가진 일종의 근시안적인 자유이다.</p>
<h2 id="143-정확한-문서화">1.4.3 정확한 문서화</h2>
<p>앞서 다뤘던 paintPainting 함수의 타입스크립트 버전을 살펴보자.</p>
<p>타입을 문서화하기 위한 타입스크립트 구문을 아직 살펴보지 않았지만, 코드를 문서화하는 타입스크립트의 정밀함을 다음 예제로 살펴보자.</p>
<pre><code class="language-jsx">interface Painter {
    finish(): boolean;
    ownMaterials: Material[];
    paint(painting: string, materials: Material[]): boolean;
}

function paintPainting(painter: Painter: String): boolean { /* ... */ }</code></pre>
<p>이 코드를 처음읽은 타입스크립트 개발자라면 Painter에 적어도 세 가지 속성이 있고, 그 중 두 가지는 메서드 라는 것을 이해할 것이다.</p>
<p>타입스크립트는 구문을 적용해 객체의 형태(shape)를 설명하고, 우수하고 강력한 시스템을 이용해 객체가 어떻게 보이는지 설명한다.</p>
<h2 id="144-더-강력한-개발자-도구">1.4.4 더 강력한 개발자 도구</h2>
<p>VSC 같은 편집기에서 타입스크립트로 코드를 작성하면 편집기는 타입스크립트를 더 깊이 이해합니다.(?)</p>
<p>이 이해를 바탕으로 편집기는 우리가 작성한 코드에 똑똑한 제안을 표시한다. (개발할 때 유용함.)</p>
<h3 id="vsc-자동-완성-기능">VSC 자동 완성 기능</h3>
<p>VSC 에는 자동완성 기능이 코드를 제안하는 것이 있다. </p>
<p>(생략)</p>
<h2 id="145-구문-컴파일하기">1.4.5 구문 컴파일하기</h2>
<p>타입스크립트 컴파일러에 타입스크립트 구문을 입력하면 타입을 검사한 후 작성된 코드에 해당하는 자바스크립트를 내보낸다.(emit)</p>
<p>편의상 컴파일러는 최신 자바스크립트 구문이나 이전 ECMA스크립트에 상응하는 코드로 컴파일할 수 도 있습니다.</p>
<h1 id="15-로컬에서-시작하기">1.5 로컬에서 시작하기</h1>
<pre><code class="language-jsx">npm i -g typescript</code></pre>
<h2 id="151-로컬에서-실행하기">1.5.1 로컬에서 실행하기</h2>
<pre><code class="language-jsx">tsc --init</code></pre>
<p>tsconfig 파일의 옵션 은 13장 ‘구성 옵션’에서 가볍게 살펴볼 예정.</p>
<p>하지만 중요한 특징은 tsc를 실행해 폴더의 모든 파일을 컴파일하도록 지시할 수 있고, 타입 스크립트가 모든 구성 옵션에 대해서 tsconfig.json을 참조할 수 있다는 것이다.</p>
<h3 id="실습2-indexts-파일-추가">실습2. index.ts 파일 추가</h3>
<p><img src="https://prod-files-secure.s3.us-west-2.amazonaws.com/e5709b6e-fbb0-4259-9ca5-fd5707753f36/e7d64069-61ef-4482-b6bb-5e053e9f2c07/Untitled.png" alt="Untitled"></p>
<p>이렇게 작성시 에러가 뜬다.</p>
<pre><code class="language-jsx">[{
&quot;resource&quot;: &quot;/Users/younghoon/Code/type/index.ts&quot;,
&quot;owner&quot;: &quot;typescript&quot;,
&quot;code&quot;: &quot;2339&quot;,
&quot;severity&quot;: 8,
&quot;message&quot;: &quot;&#39;Console&#39; 형식에 &#39;blub&#39; 속성이 없습니다.&quot;,
&quot;source&quot;: &quot;ts&quot;,
&quot;startLineNumber&quot;: 1,
&quot;startColumn&quot;: 9,
&quot;endLineNumber&quot;: 1,
&quot;endColumn&quot;: 13
}]</code></pre>
<p>실제로 blub는 console에 존재하지 않지만, <code>tsc index.ts</code> 를 하면 <code>index.js</code>를 생성한다.</p>
<blockquote>
<p>매우 중요한 개념이다. 비록 코드에 타입 오류가 있었지만, 구문은 여전히 완벽하게 유효하다.
타입스크립트 컴파일러는 타입 오류와는 상관없이 입력 파일로부터 자바스크립트를 계속 생성한다.</p>
</blockquote>
<h2 id="152-편집기-기능">1.5.2 편집기 기능</h2>
<p>tsconfig.json 파일 생성할 때의 또 다른 이점은 편집기에서 특정 폴더를 열었을 때, 편집기가 이제 해당 폴더를 타입스크립트 프로젝트로 인식한다는 것이다.</p>
<p>예를 들어 VSC에서 폴더를 열면 타입스크립트 코드를 분석하는 데 사용하는 설정은 해당 폴더의 tsconfig.json을 따르게 된다.</p>
<h1 id="16-타입스크립트에-대한-오해">1.6 타입스크립트에 대한 오해</h1>
<p>타입스크립트가 얼마나 훌륭한지 알았으니, 이제 타입스크립트의 몇 가지 제약에 대해 알아봅시다.(모든 도구는 어떤 영역에서 탁월하지만, 다른 영역에서는 한계가 있다.)</p>
<h2 id="161-잘못된-코드-해결책">1.6.1 잘못된 코드 해결책</h2>
<p>타입스크립트는 자바스크립트 코드를 구조화하는 데 도움이 되지만, 타입 안정성 강화를 제외하고는 해당 구조가 어떻게 보여야 하는지에 대해서 어떤 것도 강요되지 않는다. (개굳특징)</p>
<p>타입스크립트는 특정 대상만을 위한 독단적인 프레임워크가 아닌 모든 개발자가 사용할 수 있는 프로그래밍 언어이며, 자바스크립트에서 사용했던 아키텍쳐 패턴 중 무엇이든 사용해서 코드를 작성할 수 있고, 타입스크립트가 이를 지원한다.</p>
<p>타입스크립트는 클래스나 함수 사용 여부와 같은 코드 스타일 의견을 강요하지 않으며, 앵귤러, 리액트 등의 특정 애플리케이션 프레임워크와도 연관되어 있지 않다.</p>
<h2 id="162-자바스크립트로의-확장">1.6.2 자바스크립트로의 확장</h2>
<p>타입스크립트의 설계 목표는 다음과 같이 명시되어 있습니다.</p>
<ul>
<li>현재와 미래의 ECMA 스크립트 제안에 맞춘다.</li>
<li>모든 자바스크립트 코드의 런타임 동작을 유지한다.</li>
</ul>
<p>타입스크립트는 자바스크립트의 동작방식을 전혀 변경하지 않는다. 타입스크립트 개발자들은 자바스크립트에 추가하지 않기 위해 노력했습니다. 이런 작업은 ECMA 스크립트 자체에서 작업 하는 기술 위원회인 TC39의 영역입니다.</p>
<h2 id="163-자바스크립트보다-느림">1.6.3 자바스크립트보다 느림</h2>
<p>타입스크립트는 코드를 빌드하는데 시간이 조금 더 걸린다. </p>
<p>타입스크립트 코드는 브라우저나 Node와 같은 환경에서 실행되기 전 자바스크립트로 컴파일된다. 빌드 파이프라인은 대부분 성능 저하를 무시하도록 설정됩니다. 코드에서 발생할 수 있는 오류를 분석하는 느린 타입 스크립트 기능은 실행 가능한 애플리케이션 코드 파일을 생성하는 것과는 분리된 채로 수행됩니다.</p>
<h2 id="164-진화가-끝남">1.6.4 진화가 끝남</h2>
<p>웹의 진화는 끝나지 않았고, 타입스크립트도 마찬가지이다. 웹 커뮤니티는 타입스크립트의 버그 수정과 기능 추가를 지속적으로 요청하고 있다.</p>
<p>타입스크립트의 기본 원칙은 거의 변함이 없겠지만, 오류메시지, 더 멋진 기능 그리고 편집기와의 통합은 시간이 지남에 따라 개선될 것이다.</p>
<h1 id="17-마치며">1.7 마치며</h1>
<p>자바스크립트의 주요 약점과 타입스크립트가 작동하는 방식, 타입스크립트를 시작하는 방법에 대해 알아봤었다.</p>
<ul>
<li>자바스크립트의 간략한 역사</li>
<li>자바스크립트의 함정 : 값 비싼 자유, 부족한 문서, 부족한 개발자 도구</li>
<li>프로그래밍 언어, 타입 검사기, 컴파일러 및 언어 서비스 역할을 하는 타입스크립트</li>
<li>타입스크립트의 장점 : 제한을 통한 자유로움, 정확한 문서화, 강력한 개발자 도구</li>
<li>타입스크립트 플레이그라운드 및 컴퓨터에서 로컬로 타입스크립트 코드 작성하기</li>
<li>타입스크립트에 대한 오해 : 잘못된 코드 해결책, 자바스크립트로의 확장, 자바스크립트보다 느림, 진화가 끝남.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[02장 자바스크립트란?_모던JS딥다이브]]></title>
            <link>https://velog.io/@kr-younghoon/02%EC%9E%A5-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%9E%80</link>
            <guid>https://velog.io/@kr-younghoon/02%EC%9E%A5-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%9E%80</guid>
            <pubDate>Thu, 27 Jun 2024 14:27:09 GMT</pubDate>
            <description><![CDATA[<h1 id="21-자바스크립트의-탄생">2.1 자바스크립트의 탄생</h1>
<p>90%나 되는 점유율로 웹 브라우저 시장을 점령한 넷스케이프 커뮤니케이션즈는 웹페이지의 보조적인 기능을 수행하기 위해 경량 프로그래밍 언어를 도입하기로 결정. 그것이 브렌던 아이크가 개발한 자바스크립트이다.</p>
<p>이후 내비게이터 2에 탑재되었고, 모카로 명명. 그러다가 라이브스크립트로 이름이 바뀌었다가 자바스크립트로 변경. 그리하여, 모든 브라우저의 표준 프로그래밍 언어로 자리 잡았다.</p>
<p>그러나 자바스크립트가 순탄하게 성장한 것은 아니다. 자바스크립트가 탄생한 뒤 파생 버전인 JScript가 출시되어 위기를 맞는다.</p>
<h1 id="22-자바스크립트의-표준화">2.2 자바스크립트의 표준화</h1>
<p>JScript와 자바스크립트가 표준화되지 못하고 적당히 호환되었다는 것이다. 이로 인해 브라우저에 따라 웹페이지가 정상적으로 동작하지 않는 크로스 브라우징 이슈가 발생하기 시작했고, 결과적으로 모든 브라우저에서 정상적으로 동작하는 웹페이지를 개발하기가 무척 어려워졌다. 이에 자바스크립트의 파편화를 방지하고 모든 브라우저에서 정상적으로 동작하는 표준화된 자바스크립트의 필요성이 대두되기 시작했다. 이를 위해 컴퓨터 시스템의 표준을 관리하는 비영리 표준화 기구인 ECMA 인터내셔널에 자바스크립트의 표준화를 요청한다.</p>
<p>상표권 문제로 자바스크립트는 ECMA Script로 명명되었다. → 근데 왜 자바스크립트 라고 부름..?</p>
<h1 id="23-자바스크립트-성장의-역사">2.3 자바스크립트 성장의 역사</h1>
<p>초창기 자바스크립트는 웹 페이지의 보조적인 기능을 수행하기 위해 한정적인 용도로 사용되었다. 이 시기에 대부분의 로직은 주로 웹 서버에서 실행되었고, 브라우저는 서버로부터 전달받은 HTML과 CSS 를 단순히 렌더링하는 수준이었다.</p>
<blockquote>
<p><strong>렌더링(Rendering)</strong>
렌더링이란 HTML, CSS, 자바스크립트로 작성된 문서를 해석해서 브라우저에 시각적으로 출력하는 것을 말한다. 때로는 서버에서 데이터를 HTML로 변환해서 브라우저에게 전달하는 과정(SSR)을 가리키기도 한다. 브라우저가 HTML, CSS, JS를 로드하고 파싱해서 렌더링하는 과정은 38장 “브라우저의 렌더링 과정”에서 자세히 살펴볼 것이다.</p>
</blockquote>
<h2 id="231-ajax">2.3.1 Ajax</h2>
<p>1999년, 자바스크립트를 이용해 서버와 브라우저가 비동기 방식으로 데이터를 교환할 수 있는 통신 기능인 Ajax(Asynchronous Javascript and XML)가 XMLHttpRequest 라는 이름으로 등장했다.</p>
<h3 id="이전-렌더링-방식">이전 렌더링 방식</h3>
<p>이전의 웹페이지는 html 태그로 시작해서 html 태그로 끝나는 완전한 HTML 코드를 서버로부터 전송받아 웹페이지 전체를 렌더링하는 방식으로 동작했다. 따라서 화면이 전환되면 서버로부터 새로운 HTML을 전송받아 웹페이지 전체를 처음부터 다시 렌더링했다.</p>
<p>이러한 방식은 변경할 필요가 없는 부분까지 포함된 HTML 코드를 서버로부터 다시 전송받기 때문에 불필요한 데이터 통신이 발생하고 변경할 필요가 없는 부분까지 렌더링했기에 성능면에서 불리하다. 이로 인해 화면이 전환되면 화면이 순간적으로 깜박이는 현상이 발생하며, 이는 어쩔 수 없는 웹 페이지의 한계로 받아들여졌다.</p>
<h3 id="ajax의-등장">Ajax의 등장</h3>
<p>웹 페이지의 변경할 필요가 없는 부분을 다시 렌더링하지 않고, 서버로부터 필요한 데이터만 전송받아 한정적으로 렌더링 하는 방식이 가능해졌다.</p>
<p>이로써 웹 브라우저에서도 데스크톱 애플리케이션과 유사한 빠른 성능과 부드러운 화면 전환이 가능해졌다.</p>
<h2 id="232-jquery">2.3.2 jQuery</h2>
<p>jQuery의 등장으로 다소 번거롭고 논란이 있던 DOM을 더욱 쉽게 제어 할 수 있게 되었고, 크로스 브라우징 이슈도 어느정도 해결되었다.</p>
<h2 id="233-v8-자바스크립트-엔진">2.3.3 V8 자바스크립트 엔진</h2>
<p>구글 맵스를 통해 프로그래밍 언어로써의 가능성이 확인 되고 자바스크립트로 웹 애플리케이션을 구축하려는 시도가 늘며, 더욱 빠르게 동작하는 자바스크립트 엔진이 필요했다.</p>
<p>2008년 등장한 구글의 v8 자바스크립트 엔진은 이러한 요구에 부합하는 빠른 성능을 보여주었다. </p>
<p>v8 자바스크립트의 등장으로 자바스크립트는 데스크톱 애플리케이션과 유사한 사용자 경험을 제공할 수 있는 웹 애플리케이션 프로그래밍 언어로 정착하게 되었다.</p>
<h2 id="234-nodejs">2.3.4 Node.js</h2>
<p>Node.js는 브라우저의 자바스크립트 엔진에서만 동작하던 자바스크립트를 브라우저 이외의 환경에서도 동작할 수 있도록 자바스크립트 엔진을 브라우저에서 독립시킨 자바스크립트 실행 환경이다. Node.js는 다양한 플랫폼에 적용할 수 있지만, SSA(Server side app)개발에 주로 사용되며, 이에 필요한 모듈, 파일 시스템, HTTP 등 빌트인 API를 제공한다.</p>
<p>Nodejs는 자바스크립트 엔진을 기반으로 하므로 nodejs 환경에서 동작하는 앱은 자바스크립트를 사용해 개발.</p>
<p>프&amp;백 영역에서 js를 사용할 수 있다는 동형성(isomorphic)은 별도의 언어를 학습하기 위한 시간을 덜 수 있다는 장점이 있다.</p>
<blockquote>
<p>동형성?</p>
</blockquote>
<p>nodejs는 비동기 io 를 지원하며 단일 스레드 이벤트 루프 기반으로 동작함으로써 요청 처리 성능이 좋다. 따라서 nodejs 는 데이터를 실시간으로 처리하기 위해 Io가 빈번하게 발생하는 spa에 적합하다. 하지만 cpu 사용률이 높은 앱에는 권장하진 않는다.</p>
<h2 id="235-spa-프레임워크">2.3.5 SPA 프레임워크</h2>
<p>모던 웹 앱은 데스크톱 앱과 비교해도 손색없는 성능과 ux를 제공하는 것이 필수가 되었고, 더불어 개발 규모와 복잡도도 상승했다.</p>
<p>이전의 개발 방식으로는 복잡해진 개발 과정을 수행하기 어려워졌고, 이러한 필요에 따라 많은 패턴과 라이브러리가 출현. 개발에 많은 도움을 주었지만 변경에 유연하면서 확장하기 쉬운 애플리케이션 아키텍쳐의 구축을 어렵게 했고, 필연적으로 프레임워크가 등장하게 되었다.</p>
<p>이러한 요구에 발맞춰 CBD(Component based development) 방법론을 기반으로 하는 SPA가 대중화되며 앵귤러, 리액트, 뷰, 스벨트 등 다양한 spa 프레임워크/라이브러리가 또한 많은 사용층을 확보하고 있다.</p>
<h1 id="24-자바스크립트와-ecmascript">2.4 자바스크립트와 ECMAScript</h1>
<p>ECMAScript는 자바스크립트의 표준 사양인 ECMA-262를 말하며, 프로그래밍 언어의 값, 타입, 객체와 프로퍼티, 함수, 표준 빌트인 객체(Standard built-in object)등 핵심 문법을 규종한다. 각 브라우저 제조사는 ECMAScript 사양을 준수해서 브라우저에 내장되는 자바스크립트 엔진을 구현.</p>
<p>자바스크립트는 일반적으로 프로그래밍 언어로서 기본 뼈대를 이루는 ECMAScript와 브라우저가 별도 지원하는 클라이언트 사이드 Web API, 즉 돔 , 봄, 캔버스, 엑스엠엘에이치티티피리퀘스트, 펫치, 리퀘스트애니메이션프레임, 에스브이쥐, 웹스토리지, 웹 컴포넌트, 웹 워커 등을 아우르는 개념이다.</p>
<p>→ 자바스크립트 안에 ECMAScript가 있다. 😮 둘이 뭔 차이지 싶었는데 이제야 알았다.</p>
<h1 id="25-자바스크립트의-특징">2.5 자바스크립트의 특징</h1>
<p>자바스크립트는 HTML, CSS와 함께 웹을 구성하는 요소 중 하나로 웹 브라우저에서 동작하는 유일한 프로그래밍 언어다.</p>
<p>다른 프로그래밍 언어에서 많은 영향을 받았다. 기본문법은 C, 자바와 유사하고, Self에서는 프로토타입 기반 상속을, Scheme에서는 일급 함수의 개념을 차용했다.</p>
<p>자바스크립트는 개발자가 별도의 컴파일 작업을 수행하지 않는 인터프리터 언어이다. 컴파일러 언어와 비교하자면 아래와 같다.</p>
<table>
<thead>
<tr>
<th>컴파일러 언어</th>
<th>인터프리터 언어</th>
</tr>
</thead>
<tbody><tr>
<td>코드가 실행되기 전 단계인 컴파일 타임에 소스코드 전체를 한번에 머신 코드로 변환한 후 실행한다.</td>
<td>코드가 실행되는 단계인 런타임에 문 단위로 한 줄씩 중간 코드인 바이트 코드로 변환한 후 실행한다.</td>
</tr>
<tr>
<td>실행 파일을 생성한다.</td>
<td>실행 파일을 생성하지 않는다.</td>
</tr>
<tr>
<td>컴파일 단계와 실행 단계가 분리되어 있다. 명시적 컴파일 단계를 거치고 명시적으로 실행 파일을 실행한다.</td>
<td>인터프리터 단계와 실행 단계가 분리 되어 있지 않다. 인터프리터는 한줄씩 바이트코드로 변환하고 즉시 실행한다.</td>
</tr>
<tr>
<td>실행에 앞서 컴파일은 단 한번 수행한다.</td>
<td>코드가 실행될 때마다 인터프리트 과정이 반복 수행된다.</td>
</tr>
<tr>
<td>컴파일과 실행 단계가 분리되어 있으므로 코드 실행 속도가 빠르다.</td>
<td>인터프리트 단계와 실행 단계가 분리 되어 있지 않고 반복 수행되므로 코드 실행 속도가 느리다.</td>
</tr>
</tbody></table>
<p>하지만 대부분의 모던 브라우저에서 사용되는 인터프리터는 전통적 컴파일러 언어처럼 명시적인 컴파일 단계를 거치지는 않지만, 복잡한 과정을 거치며 일부 소스코드를 컴파일하고 실행한다.</p>
<p>이를 통해 인터프리터 언어의 장점인 동적 기능 지원을 살리면서 실행 속도가 느리다는 단점을 극복한다. 따라서 현재는 컴파일러와 인터프리터의 기술적 구분이 점차 모호해져 가는 추세다. 하지만 자바스크립트는 런타임에 컴파일 되며 실행 파일이 생성되지 않고, 인터프리터의 도움 없이 실행할 수 없기 때문에 컴파일러 언어라고 할 수 없다.</p>
<h3 id="멀티-패러다임-프로그래밍-언어">멀티 패러다임 프로그래밍 언어</h3>
<p>자바스크립트는 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어다.</p>
<p>비록 다른 객체지향 언어와의 차이점에 대한 논쟁이 있긴 하지만, 자바스크립트는 강력한 객체지향 프로그래밍 능력을 지니고 있다. 간혹 클래스, 상속, 정보 은닉을 위한 키워드가 없어서 객체지향 언어가 아니라고 오해하는 경우가 있지만, 자바스크립트는 클래스 기반 객체지향 언어보다 효율적이면서 강력한 프로토타입 기반의 객체지향 언어다.</p>
<h1 id="26-es6-브라우저-지원-현황">2.6 ES6 브라우저 지원 현황</h1>
<p>IE 를 제외한 대부분 모던 브라우저는 ES6를 지원하지만 100% 지원하진 않는다.</p>
<p>따라서 브라우저에서 아직 지원하지 않는 최신 기능을 사용하거나 IE 나 구형브라우저를 고려해야한느 상황이면 Babel 같은 트랜스파일러를 사용해 ES6 이상의 사양으로 구현한 소스 코드를 ES5 이하의 사양으로 다운그레이드 할 필요가 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[01장 프로그래밍_모던JS딥다이브]]></title>
            <link>https://velog.io/@kr-younghoon/01%EC%9E%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@kr-younghoon/01%EC%9E%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Wed, 26 Jun 2024 07:45:29 GMT</pubDate>
            <description><![CDATA[<h1 id="11-프로그래밍이란">1.1 프로그래밍이란?</h1>
<p>프로그래밍이란? 컴퓨터에게 실행을 요구하는 일종의 커뮤니케이션.</p>
<blockquote>
<p><strong>프로그래밍에 앞서 해결해야 할 문제(요구사항)를 명확히 이해한 후 적절한 문제 해결 방안을 정의할 필요가 있다.</strong></p>
</blockquote>
<p>이때 요구 되는 것이 <code>문제 해결 능력</code> 이다.  대부분의 문제는 복잡하며 명확하지 않을 수 도 있다.</p>
<p>따라서 문제를 명확히 이해하는 것이 우선되어야 하며 복잡함을 단순하게 분해(decomposition)하고 
자료를 정리하고 구분(Modeling)해야 하며 순서에 맞게 행위를 배열해야 한다.</p>
<p>다시 정리해서, 프로그래밍이란, 0과 1 밖에 모르는 기계가 실행할 수 있을 정도로 정확하고 상세하게 요구사항을 설명하는 작업이며, 그 결과물이 바로 코드이다. 우리는 문제 해결 방안을 고려할 때 컴퓨터의 입장에서 문제를 바라봐야 한다. 이 때 필요한 것이 Computional thinking(컴퓨팅 사고)이다. 문제 해결 능력은 직감과 직관의 영역인데, 이는 문제를 바라보는 <strong>우리의 사고와 경험에 영향</strong>을 받는다. </p>
<p>사람의 일반적인 사고 방식은 매우 포괄적이며, 실생활에서 경함하는 익숙한 사항에 대해 당연시하는 안이한 인식이 있다. wow.</p>
<p>예를 들어 “걷다”라는 기능을 디자인하려면 판단해야하는 상태와 그 상태를 판단하는 시기, 그리고 판단 기준을 정의해야 하며, 이를 바탕으로 분해한 처리(process)의 실행 여부를 결정한다. 예를 들어, 장애물이란 무엇(크기, 움직임 등)인지, 어떤 범위 내에 있는 것인지 명확히 수치화해서 정의해야 한다.</p>
<h1 id="12-프로그래밍-언어">1.2 프로그래밍 언어</h1>
<h2 id="기계어-컴파일러-인터프리터">기계어, 컴파일러, 인터프리터</h2>
<p>문제 해결 능력을 바탕을 정의된 문제 해결 방안은 컴퓨터에게 전달되어야 한다. 명령을 수행해야하는 주체는 컴퓨터. 따라서 사람이 이해할 수 있는 자연어가 아니라 컴퓨터가 이해할 수 있는 언어, 즉 <code>기계어(machine code)</code>로 명령을 전달해야 한다.</p>
<p>하지만 사람이 기계어를 이해해서 기계어로 직접 명령을 전달하는 것은 어렵다. 가장 유용한 대안은 사람이 이해할 수 있는 약속된 구문(Syntax), 문법으로 구성된 <code>프로그래밍 언어</code>를 사용해 프로그램을 작성 후 컴퓨터가 이해할 수 있는 기계어로 변환하는 일종의 변역기를 이용하는 것이다. 이 일종의 번역기를 컴파일러(Compiler) 혹은 인터프리터(interpreter)라고 한다.</p>
<h2 id="자연어와-인공어">자연어와 인공어</h2>
<p>언어는 자신의 생각을 상대에게 전달할 수 있는 방법. 언어는 자연어와 인공어로 구분한다.</p>
<p>프로그래밍 언어란? 컴퓨터와의 대화에 사용되는 일종의 표현 수단.  사람과 컴퓨터 모두가 이해할 수 있는 약속된 형태의 인공어 이다.</p>
<pre><code class="language-jsx">console.log(&#39;Hello world&#39;);</code></pre>
<p>프로그래밍은 프로그래밍 언어를 사용해 컴퓨터에게 실행을 요구하는 일종의 커뮤니케이션. 프로그래밍 언어는 구문(syntax)과 의미(semantics)의 조합으로 표현된다.</p>
<h1 id="13-구문과-의미">1.3 구문과 의미</h1>
<h2 id="프로그래밍은-문법적으로만-중요한-것은-아니다">프로그래밍은 문법적으로만 중요한 것은 아니다.</h2>
<p>프로그래밍 학습은 언어의, 문법을 배우는 것부터 시작한다. 하지만 문법을 잘 안다고 해서 외국어를 잘한다고 말할 수 없다.</p>
<p>외국어를 잘하는 것은 화자의 말이나 문장을 이해하고 문맥에 따른 적절한 어휘 선택, 그리고 순차적으로 결론을 향해 나아가는 문장 구성이 필요하다.</p>
<p>즉 문법에 맞는 문장을 구성하는 것은 물론 의미(semantics)를 가지고 있어야 언어의 역할을 충분히 수행할 수 있다.</p>
<blockquote>
<p>Colorless green ideas sleep furiously - 노엄 촘스키(Noem Chomsky)</p>
</blockquote>
<p>노엄 촘스키는 위 문장을 통해 언어의 의미는 문맥에 있는 것이지 문법에 있는 것이 아니라는 점을 지적했다. 위의 문장은 문법적으로 문제가 없지만, 의미가 없다. 프로그래밍도 마찬가지다.</p>
<pre><code class="language-jsx">const number = &#39;string&#39;;
console.log(number * number); // NaN</code></pre>
<p>자바스크립트 변수에는 어떠한 타입의 값도 할당할 수 있다. 따라서 위 예제가 문법적으론 문자가 없다. 하지만 의미적으로 옳지 않다.</p>
<p>number라는 이름의 변수에 문자열이 할당 되어 있기 떄문이다. number라는 변수에는 숫자를 할당하는 것이 옳다.</p>
<h2 id="결론">결론</h2>
<p>문제 해결 능력을 통해 만들어낸 해결 방안은 프로그래밍 언어의 문법을 사용해 표현한다.</p>
<p>작성된 코드는 해결방안의 구체적 구현물이다. 이것은 프로그래밍 언어의 문법에 부합하는 것은 물론이고 수행하고자 하는 바를 정확히 수행하는 것. 즉 요구사항이 실현(문제가 해결)되어야 의미가 있다.</p>
<p>프로그래밍 언어가 제공하는 문법을 적절히 사용하여 변수를 통해 값을 저장하고 참조하며 연산자로 값을 연산, 평가하고 조건문과 반복문에 의한 흐름 제어로 코드의 실행 순서를 제어하고 함수로 재사용 가능한 문의 집합을 만들며 객체, 배열 등으로 자료를 구조화한다.</p>
<p>결국 프로그래밍은 요구사항의 집합을 분석해서 적절한 자료구조와 함수의 집합으로 변환한 후, 그 흐름을 제어하는 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SOLID]]></title>
            <link>https://velog.io/@kr-younghoon/SOLID</link>
            <guid>https://velog.io/@kr-younghoon/SOLID</guid>
            <pubDate>Mon, 17 Jun 2024 14:28:41 GMT</pubDate>
            <description><![CDATA[<p><a href="https://fe-developers.kakaoent.com/2023/230330-frontend-solid/">https://fe-developers.kakaoent.com/2023/230330-frontend-solid/</a></p>
<p><a href="https://ykss.netlify.app/translation/write_solid_react_hooks/?utm_source=substack&amp;utm_medium=email">https://ykss.netlify.app/translation/write_solid_react_hooks/?utm_source=substack&amp;utm_medium=email</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[맥북환경 셋팅 정리글]]></title>
            <link>https://velog.io/@kr-younghoon/%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EC%85%8B%ED%8C%85-%EC%A0%95%EB%A6%AC%EA%B8%80</link>
            <guid>https://velog.io/@kr-younghoon/%EA%B0%9C%EB%B0%9C%ED%99%98%EA%B2%BD-%EC%85%8B%ED%8C%85-%EC%A0%95%EB%A6%AC%EA%B8%80</guid>
            <pubDate>Mon, 10 Jun 2024 02:33:58 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>생각보다 개발을 편하게 하려면 extension이라든지, 패키지라던지 셋팅해야하는게 많다. 사실 무지성으로 깔아놓고 써보니까 편하다고 느낀게 너무 많지만, 너무 많이 무지성으로 깔아버려서 이후에 그게 사라지고 나서 소중함을 너무 깨달아버린 나머지. 바쁘지 않다면, 하나하나 정리해서 기록해둘까 한다.</p>
</blockquote>
<h3 id="vsc-extension">vsc extension</h3>
<h4 id="테마-개추천">테마 개추천</h4>
<blockquote>
<p><a href="https://vscodethemes.com/?type=dark&amp;page=5">vscodethemes</a> 사이트가 있다. 여기서 테마를 찾아볼 수 있다.</p>
</blockquote>
<ul>
<li>Pitch black</li>
<li>Seti black</li>
</ul>
<h4 id="code-spell-check240610-설치">Code Spell Check(240610 설치)</h4>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/36a10e00-d14b-4547-968e-fd657d17e3dc/image.png" alt="">
철자 오류를 감지하고 수정하는 데 도움이 되는 도구. 여러 언어를 지원하며, 코드 주석, 문자열 및 일반 텍스트에서 철자 오류를 찾아낸다.</p>
<ul>
<li>사용후기 : 아직 사용 안해봄</li>
<li>써본후기 : 그닥? 아직 효과를 못봤고. 생각보다 미니미 하게 들어가있다.
vsc 밑에 미니미하게 들어가있어서 오잉했다. 오타나면 요런식으로 알람을 준다.
<img src="https://velog.velcdn.com/images/kr-younghoon/post/a6f243ea-6a5c-422f-8ed7-a5454702962c/image.png" alt=""></li>
</ul>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/293dbd7d-7b82-47bc-9f0b-2e61642ed85b/image.png" alt=""></p>
<h2 id="p10k-config">p10k config</h2>
<ul>
<li>TO-DO :  p10k.zsh 에서 사진 속 4개를 수정하면 된다. <code>code ~/.p10k.zsh</code>치셈</li>
</ul>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/6a5938f2-cc45-425f-aca1-884bef1835b6/image.png" alt=""></p>
<ul>
<li>So... 자유롭게 커스터마이징 하면 된다.
<img src="https://velog.velcdn.com/images/kr-younghoon/post/0bf049fa-1df5-4e8a-9779-91664b1cea0a/image.png" alt=""></li>
</ul>
<p>문제점이 내가 하도 셋팅을 많이 바꿔서 기본 bash하고 zsh하고 같이 나오는 느낌이다.
<img src="https://velog.velcdn.com/images/kr-younghoon/post/c6a13504-3da5-4c18-a5b5-d73cbed132fb/image.png" alt="">
이렇게 세줄 나오는게 굉장히 거슬린다. 허허. 나중에 갈아엎으리.</p>
<h3 id="zshrc-config">zshrc config</h3>
<pre><code> younghoon🦖🚀 &gt; cat ~/.zshrc
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
if [[ -r &quot;${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh&quot; ]]; then
  source &quot;${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh&quot;
fi

# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:$HOME/.local/bin:/usr/local/bin:$PATH

# Path to your oh-my-zsh installation.
export ZSH=&quot;$HOME/.oh-my-zsh&quot;

# Set name of the theme to load --- if set to &quot;random&quot;, it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See https://github.com/ohmyzsh/ohmyzsh/wiki/Themes
ZSH_THEME=&quot;powerlevel10k/powerlevel10k&quot;

# Set list of themes to pick from when loading at random
# Setting this variable when ZSH_THEME=random will cause zsh to load
# a theme from this variable instead of looking in $ZSH/themes/
# If set to an empty array, this variable will have no effect.
# ZSH_THEME_RANDOM_CANDIDATES=( &quot;robbyrussell&quot; &quot;agnoster&quot; )

# Uncomment the following line to use case-sensitive completion.
# CASE_SENSITIVE=&quot;true&quot;

# Uncomment the following line to use hyphen-insensitive completion.
# Case-sensitive completion must be off. _ and - will be interchangeable.
# HYPHEN_INSENSITIVE=&quot;true&quot;

# Uncomment one of the following lines to change the auto-update behavior
# zstyle &#39;:omz:update&#39; mode disabled  # disable automatic updates
# zstyle &#39;:omz:update&#39; mode auto      # update automatically without asking
# zstyle &#39;:omz:update&#39; mode reminder  # just remind me to update when it&#39;s time

# Uncomment the following line to change how often to auto-update (in days).
# zstyle &#39;:omz:update&#39; frequency 13

# Uncomment the following line if pasting URLs and other text is messed up.
# DISABLE_MAGIC_FUNCTIONS=&quot;true&quot;

# Uncomment the following line to disable colors in ls.
# DISABLE_LS_COLORS=&quot;true&quot;

# Uncomment the following line to disable auto-setting terminal title.
# DISABLE_AUTO_TITLE=&quot;true&quot;

# Uncomment the following line to enable command auto-correction.
# ENABLE_CORRECTION=&quot;true&quot;

# Uncomment the following line to display red dots whilst waiting for completion.
# You can also set it to another string to have that shown instead of the default red dots.
# e.g. COMPLETION_WAITING_DOTS=&quot;%F{yellow}waiting...%f&quot;
# Caution: this setting can cause issues with multiline prompts in zsh &lt; 5.7.1 (see #5765)
# COMPLETION_WAITING_DOTS=&quot;true&quot;

# Uncomment the following line if you want to disable marking untracked files
# under VCS as dirty. This makes repository status check for large repositories
# much, much faster.
# DISABLE_UNTRACKED_FILES_DIRTY=&quot;true&quot;

# Uncomment the following line if you want to change the command execution time
# stamp shown in the history command output.
# You can set one of the optional three formats:
# &quot;mm/dd/yyyy&quot;|&quot;dd.mm.yyyy&quot;|&quot;yyyy-mm-dd&quot;
# or set a custom format using the strftime function format specifications,
# see &#39;man strftime&#39; for details.
# HIST_STAMPS=&quot;mm/dd/yyyy&quot;

# Would you like to use another custom folder than $ZSH/custom?
# ZSH_CUSTOM=/path/to/new-custom-folder

# Which plugins would you like to load?
# Standard plugins can be found in $ZSH/plugins/
# Custom plugins may be added to $ZSH_CUSTOM/plugins/
# Example format: plugins=(rails git textmate ruby lighthouse)
# Add wisely, as too many plugins slow down shell startup.
plugins=(
  git
  fasd
  zsh-syntax-highlighting
)

source $ZSH/oh-my-zsh.sh

# User configuration

# export MANPATH=&quot;/usr/local/man:$MANPATH&quot;

# You may need to manually set your language environment
# export LANG=en_US.UTF-8

# Preferred editor for local and remote sessions
# if [[ -n $SSH_CONNECTION ]]; then
#   export EDITOR=&#39;vim&#39;
# else
#   export EDITOR=&#39;mvim&#39;
# fi

# Compilation flags
# export ARCHFLAGS=&quot;-arch x86_64&quot;

# Set personal aliases, overriding those provided by oh-my-zsh libs,
# plugins, and themes. Aliases can be placed here, though oh-my-zsh
# users are encouraged to define aliases within the ZSH_CUSTOM folder.
# For a full list of active aliases, run `alias`.
#
# Example aliases
# alias zshconfig=&quot;mate ~/.zshrc&quot;
# alias ohmyzsh=&quot;mate ~/.oh-my-zsh&quot;

# fpath+=/Users/younghoon/.zsh/pure
# autoload -U promptinit; promptinit
# prompt pure

export NVM_DIR=&quot;$HOME/.nvm&quot;
[ -s &quot;/opt/homebrew/opt/nvm/nvm.sh&quot; ] &amp;&amp; \. &quot;/opt/homebrew/opt/nvm/nvm.sh&quot;  # This loads nvm
[ -s &quot;/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm&quot; ] &amp;&amp; \. &quot;/opt/homebrew/opt/nvm/etc/bash_completion.d/nvm&quot;  # This loads nvm bash_completion

source /opt/homebrew/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
source /Users/younghoon/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
source /opt/homebrew/share/zsh-autosuggestions/zsh-autosuggestions.zsh
source /Users/younghoon/.oh-my-zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh</code></pre><h1 id="0703-맥북-갈아엎음">0703 맥북 갈아엎음.</h1>
<ul>
<li>[Mac 한글 키보드에서 항상 원화(₩)대신 백틱(`) 입력되게 하기](<a href="https://www.korecmblog.com/blog/backtick-fix">https://www.korecmblog.com/blog/backtick-fix</a>)</li>
<li><a href="https://taek.dev/etc/mac-initial-setup/">맥북셋팅관련글1</a>
요즘  문득 VSC 에 에러가 많다는 걸 느낀다.</li>
</ul>
<h1 id="0723-zsh-셋팅-중-단축키">0723 zsh 셋팅 중 단축키</h1>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/5727bca7-e4a7-4321-a242-adfb57430b2b/image.png" alt=""></p>
<h1 id="0926-💽-개발하는데-유용한-vscode-확장팩---유료-ide-못지않게-❗">0926 💽 개발하는데 유용한 VSCode 확장팩 - 유료 IDE 못지않게 ❗</h1>
<p><a href="https://inpa.tistory.com/entry/VS-Code-%E2%8F%B1%EF%B8%8F-%EC%BD%94%EB%94%A9%EC%97%90-%EC%9C%A0%EC%9A%A9%ED%95%9C-%EB%8F%84%EA%B5%AC-%EC%B6%94%EC%B2%9C">출처: https://inpa.tistory.com/entry/VS-Code-⏱️-코딩에-유용한-도구-추천 Inpa Dev 👨‍💻:티스토리</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스택과 큐.]]></title>
            <link>https://velog.io/@kr-younghoon/%EC%8A%A4%ED%83%9D%EA%B3%BC-%ED%81%90</link>
            <guid>https://velog.io/@kr-younghoon/%EC%8A%A4%ED%83%9D%EA%B3%BC-%ED%81%90</guid>
            <pubDate>Mon, 22 Apr 2024 16:46:46 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>👷🏻‍♂️ 오늘부터 알고리즘 공부를 시작한다.
그 첫번째 과정으로 스택 큐를 공부한다. </p>
</blockquote>
<blockquote>
<p>크래프톤 정글에서 했던 경험이 있지만, 허허. 인간은 망각의 동물.. 다시! 🥲</p>
</blockquote>
<h4 id="출처">출처</h4>
<ul>
<li><a href="https://helloworldjavascript.net/pages/282-data-structures.html">Hello World JavaScript - 큐, 스택, 트리</a></li>
</ul>
<hr>
<h3 id="배우기-앞서">배우기 앞서..</h3>
<p>어떤 데이터의 구체적인 구현 방식은 생략한 채, 데이터의 추상적 형태와 그 데이터를 다루는 방법만을 정해놓은 것을 가지고 Abstract Data Type(ADT) 혹은 추상 자료형이라고 부른다. 이 챕터에서는 널리 사용되는 ADT인 큐, 스택을 정리해보겠습니다.</p>
<h2 id="큐queue">큐(Queue)</h2>
<p>큐는 다음과 같은 성질을 갖는 자료형이다.</p>
<ul>
<li>데이터를 집어넣을 수 있는 <a href="https://jud00.tistory.com/entry/Data-Structure-%EC%84%A0%ED%98%95Linear-%EB%B9%84%EC%84%A0%ED%98%95NonLinear-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0">선형(linear) 자료형</a>이다.</li>
<li>먼저 집어넣은 데이터가 먼저 나온다. 이 특징을 FIFO(First In First Out), 선입선출이라고 부릅니다.</li>
<li>데이터를 집어넣는 enqueue, 데이터를 추출하는 dequeue 등의 작업을 할 수 있습니다.(스택과 큐의 차이점..?)
<img src="https://velog.velcdn.com/images/kr-younghoon/post/230f0696-7071-453a-9834-564bae7bf68e/image.png" alt="">
JavaScript에서는 배열을 이용해서 간단하게 큐를 구현할 수 있습니다.<pre><code>class Queue {
  constructor() {
      this._arr = [];
  }
  enqueue(item) {
      this._arr.push(item);
  }
  dequeue() {
      return this._arr.shift();
  }
}
</code></pre></li>
</ul>
<p>const queue = new Queue();
queue.enqueue(1);
queue.enqueue(2);
queue.enqueue(3);
queue.dequeue();</p>
<pre><code>큐는 **순서대로 처리해야 하는 작업을 임시로 저장해두는 버퍼(buffer)**로서 많이 사용됩니다.

## 스택(Stack)
스택은 다음과 같은 성질을 갖는 자료형입니다.
- 데이터를 집어넣을 수 있는 [선형(linear) 자료형](https://jud00.tistory.com/entry/Data-Structure-%EC%84%A0%ED%98%95Linear-%EB%B9%84%EC%84%A0%ED%98%95NonLinear-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0)이다.
- 나중에 집어넣은 데이터가 먼저 나옵니다. 이 특징을 LIFO(Last In, First Out)이라고 부릅니다.
- 데이터를 집어넣는 push, 데이터를 추출하는 pop, 맨 나중에 집어넣은 데이터를 확인하는 peek 등의 작업을 할 수 있습니다.
![](https://velog.velcdn.com/images/kr-younghoon/post/74ea9673-fdc2-489d-af16-0b75fb12c790/image.png)
JavaScript에서는 배열을 이용해서 간단하게 스택을 구현할 수 있습니다.</code></pre><p>class Stack {
    constructor() {
        this._arr = [];
    }
    push(item) {
        this._arr.push(item);
    }
    pop() {
        return this._arr.pop();
    }
    peek() {
        return this._arr[this._arr.length - 1];
    }
}</p>
<p>const stack = new Stack();
stack.push(1);
stack.push(2);
stack.push(3);
stack.pop(); // 3</p>
<pre><code>스택은 서로 관계가 있는 여러 작업을 연달아 수행하면서 **이전의 작업 내용을 저장해 둘 필요가 있을 때** 널리 사용됩니다.
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[3-Tier Architecture(3계층 구조)]]></title>
            <link>https://velog.io/@kr-younghoon/3-Tier-Architecture3%EA%B3%84%EC%B8%B5-%EA%B5%AC%EC%A1%B0</link>
            <guid>https://velog.io/@kr-younghoon/3-Tier-Architecture3%EA%B3%84%EC%B8%B5-%EA%B5%AC%EC%A1%B0</guid>
            <pubDate>Sun, 21 Apr 2024 18:35:20 GMT</pubDate>
            <description><![CDATA[<h3 id="3계층-구조3-tier-architecture란">3계층 구조(3-Tier Architecture)란?</h3>
<p>3계층 구조는 3가지의 레벨을 나눠, 논리적이나 물리적으로 시스템을 구성하는 것을 말한다.</p>
<p>이 구조를 쉽게 접할 수 있는 웹 서버 기준으로 Web Server(Frontend) - Web Application Server(WAS, Backend) - DB를 예로 들 수 있다.(삼계층은 기능이나 목적에 따라 구성되는 요소가 다양하다.)</p>
<p>3계층 애플리케이션은 모든 통신이 서로의 계층을 통과하면서 발생하게 된다. 예를 들어 프레젠테이션 계층에서 직접적으로 데이터 계층과의 통신은 금지 되어 있다.
<img src="https://velog.velcdn.com/images/kr-younghoon/post/fd858c1f-6b42-47dd-8855-099c77e6571d/image.png" alt=""></p>
<h3 id="프레젠테이션-계층-presentation-tier">프레젠테이션 계층 (Presentation Tier)</h3>
<blockquote>
<p>주요 목적 : 정보를 표시하고 사용자로부터 정보를 수집하는 것.</p>
</blockquote>
<p>사용자가 직접 마주하게 되는 계층이다. 따라서 주로 사용자 인터페이스(인터넷 브라우저 등)를 지원하며 이 계층은 GUI 또는 프론트엔드(front-end) 라고도 부른다. 그러므로 이 계층에서는 사용자 인터페이스와 관계없는 데이터를 처리하는 로직은 포함하지 않는다. 주로 웹 서버를 예시로 들 수 있고, HTML, Javascript, CSS 등이 이 계층에 해당 된다.</p>
<h3 id="어플리케이션-계층-application-tier">어플리케이션 계층 (Application Tier)</h3>
<blockquote>
<p>이 계층에서는 특정 비즈니스 규칙 세트인 비즈니스 논리를 사용하여 프리젠테이션 계층에서 수집된 정보가 처리된다.</p>
</blockquote>
<p>이 계층에서는 (프레젠테이션 계층) 요청되는 정보를 어떠한 규칙을 바탕으로 처리하고 가공하는 것들을 담당한다. (동적인 데이터 제공!) 비즈니스 로직 계층 또는 트랜잭션 계층 이라고도 한다. 첫 번째 계층에서 이 계층을 바라볼 때에는 서버처럼 동작하고(응답), 세 번째 계층의 프로그램에 대해서는 마치 클라이언트처럼 행동한다.(요청)</p>
<p>따라서 이 계층은 미들웨어(Middleware) 또는 백엔드(back-end)라고도 불린다. 이 계층에서는 프레젠테이션코드 (예를 들면 HTML, CSS)나 데이터 관리를 위한 코드는 포함하지 않는다. 주로 PHP, Java 등이 이 계층에 해당한다.</p>
<h3 id="데이터-계층-data-tier">데이터 계층 (Data Tier)</h3>
<blockquote>
<p>애플리케이션이 처리하는 정보가 저장 및 관리 되는 곳이다.</p>
</blockquote>
<p>데이터 계층은 데이터베이스와 데이터베이스에 접근하여 데이터를 읽거나 쓰는 것을 관리하는 것을 포함한다.</p>
<p>주로 DBMS (Database Management System)이 이 계층에 해당된다. 데이터 계층 <strong>또한</strong> 백엔드(back-end)라고도 부른다. 주로 MySQL, MongoDB 등이 이 계층에 해당된다.</p>
<h3 id="3계층-구조의-장점---단점">3계층 구조의 장점 /  단점</h3>
<h4 id="장점">장점</h4>
<p>각 계층이 분리되어 있어 업무 분담이 가능해지므로 업무 효율성이 증가할 수 있다. 또한 여러 대의 서버로 나누어 각 계층이 동작하므로 서버의 부하를 줄여줄 수도 있으며, 경우에 따라 합리적인 스케일업(서버의 성능 업그레이드)이 가능하다.</p>
<h4 id="단점">단점</h4>
<p>1계층으로만 사용하는 것 대비 관리가 더 필요하고, 장애가 발생하는 포인트가 더 늘어날 수 있다는 점을 생각해두어야 한다.</p>
<p>따라서 비용이 그만큼 많이 발생하게 되므로 서비스 규모 및 사용자 증가에 따라 계층 구조를 설계 및 고려해야 한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Load Balancing 에 대해..]]></title>
            <link>https://velog.io/@kr-younghoon/Load-Balancing-%EC%97%90-%EB%8C%80%ED%95%B4</link>
            <guid>https://velog.io/@kr-younghoon/Load-Balancing-%EC%97%90-%EB%8C%80%ED%95%B4</guid>
            <pubDate>Sun, 21 Apr 2024 17:04:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>클라우드 관리 중간고사를 준비하며 가볍게 나마 로드 밸런싱을 다뤄봅니다.</p>
</blockquote>
<blockquote>
<p>로드밸런싱은 지난 <code>크래프톤 정글 과정 중 AWS Immersion Day</code> 때 배운 적이 있었습니다.</p>
</blockquote>
<p>출처</p>
<ul>
<li><a href="https://velog.io/@yanghl98/OS%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A1%9C%EB%93%9C%EB%B0%B8%EB%9F%B0%EC%8B%B1-Load-Balancing-%EC%A0%95%EC%9D%98-%EC%A2%85%EB%A5%98-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98">흶님의 벨로그 - [Network/네트워크] 로드밸런싱 (Load Balancing) - 정의, 종류, 알고리즘</a></li>
<li><a href="https://aws.amazon.com/ko/what-is/load-balancing/">AWS - 로드 밸런싱이란 무엇인가요?</a></li>
</ul>
<hr>
<h3 id="로드-밸런싱load-balancing">로드 밸런싱(Load Balancing)</h3>
<h4 id="정의">정의</h4>
<ul>
<li>네트워크 또는 서버에 가해지는 로드(혹은 트래픽)를 분산 해주는 기술.</li>
<li>중앙처리장치 혹은 저장장치와 같은 <strong>컴퓨터 자원들에게 작업을 나눠주는 것</strong>을 의미한다.</li>
</ul>
<h3 id="load-balancing-의-필요성-">Load Balancing 의 필요성 ?</h3>
<p>로드 밸런싱은 여러 대의 서버를 두고 서비스를 제공하는 분산 처리 시스템에서 필요한 기술이다.</p>
<p>서비스의 제공 초기 단계라면 적은 수의 클라이언트로 인해 서버 한 대로 요청에 응답하는 것이 가능하다. 하지만 사업의 규모가 확장되고, 클라이언트의 수가 늘어나게 되면 기존 서버 만으로는 정상적인 서비스가 불가능하게 된다. 증가한 트래픽에 대처할 수 있느 방법은 크게 2가지이다.</p>
<h4 id="1-scale---up">1. Scale - up</h4>
<p>서버 자체의 성능을 확장하는 것이다.
비유하자면 CPU가 i3인 컴퓨터를 I7으로 업그레이드 하는 것과 같다. 이렇게 하게 된다면 단점이 확실하다. 트래픽은 항상 오르락 내리락하기에 항상 성능이 좋은 서버를 두고 있다면 안전하겠지만, 비용적인 측면에서 어려움이 있겠다.</p>
<h4 id="2-scale---out">2. Scale - out</h4>
<p>기존 서버와 동일하거나 낮은 성능의 서버를 두 대 이상 증설하여 운영하는 것을 의미한다. CPU 가 i3 인 컴퓨터를 여러 대 추가 구입해 운영하는 것에 비유할 수 있다. </p>
<p>이 경우에 여러대의 서버로 트래픽을 균등하게 분산시켜주는 로드 밸런싱이 반드시 필요하겠다.</p>
<h3 id="로드-밸런서load-balancer">로드 밸런서(Load Balancer)</h3>
<h4 id="정의-1">정의</h4>
<ul>
<li>로드밸런싱 기술을 제공하는 서비스 또는 장치</li>
<li>클라이언트와 네트워크 트래픽이 집중되는 서버들 또는 네트워크 허브 사이에 위치한다.<h4 id="종류">종류</h4>
<blockquote>
<p>L4 로드 밸런싱과 , L7 로드 밸런싱이 있는데 이부분은 생략한다. 로드를 어느 단에서 분산하느냐의 차이가 있다.</p>
</blockquote>
</li>
</ul>
<h3 id="로드-밸런싱-알고리즘load-balancing-algorithm">로드 밸런싱 알고리즘(Load Balancing Algorithm)</h3>
<h4 id="종류-1">종류</h4>
<h5 id="1-라운드로빈-방식round-robin-method">1. 라운드로빈 방식(Round Robin Method)</h5>
<ul>
<li>서버에 들어온 요청을 순서대로 돌아가며 배정하는 방식</li>
<li>클라이언트의 요청을 순서대로 분배하기 때문에 여러 대의 서버가 동일한 스펙을 갖고 있고, 서버와의 연결(세션)이 오래 지속되지 않는 경우에 활용하기 적합하다.</li>
</ul>
<h5 id="2-가중-라운드로빈-방식weighted-round-robin-method">2. 가중 라운드로빈 방식(Weighted Round Robin Method)</h5>
<ul>
<li>각각의 서버마다 가중치를 매기고 가중치가 높은 서버에 클라이언트 요청을 우선적으로 배분하는 방식이다.</li>
<li>주로 서버의 트래픽 처리 능력이 상이한 경우 사용되는 부하 분산 방식이다. 예를 들어 A 서버가 가중치 5 를 갖고 B 서버가 가중치 2를 갖는다면, 로드 밸런서는 라운드로빈 방식으로 A 서버에 5개 B 서버에 2개의 요청을 전달한다.<blockquote>
<p>이외에도 IP 해시 방식, 최소 연결방식, 최소 리스폰 타임이 있지만, 수업에서 다루지 않았기에 생략한다.</p>
</blockquote>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[React-router-dom v6]]></title>
            <link>https://velog.io/@kr-younghoon/React-router-dom-v6</link>
            <guid>https://velog.io/@kr-younghoon/React-router-dom-v6</guid>
            <pubDate>Tue, 02 Apr 2024 05:09:20 GMT</pubDate>
            <description><![CDATA[<ul>
<li><a href="https://reactrouter.com/en/6.22.3">공식문서</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[상태관리]]></title>
            <link>https://velog.io/@kr-younghoon/%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@kr-younghoon/%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Wed, 27 Mar 2024 17:03:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>State: A Component&#39;s Memory</p>
</blockquote>
<ul>
<li>리액트 공식문서에서는 <code>State</code>를 컴포넌트의 메모리라고 설명하고 있다.</li>
<li>리액트의 상태관리는 무엇이며, 어떤 것 때문에 하는 것일까?</li>
</ul>
<blockquote>
<ul>
<li>이전 프로젝트 <code>크리스마스 편지 프로젝트</code>에서 전역상태 관리를 위해 Redux를 사용해 본적이 있다. 그를 통해 이해했지만, 다시 한번 Zustand를 써보기 위해 그때는 급해서 사용했지만, 정리하려고 한다.</li>
</ul>
</blockquote>
<ul>
<li>리액트의 상태관리가 무엇인지 또 어떤 것들이 있는지, 등등을 함께 알아보자!</li>
</ul>
<hr>
<h2 id="state">State?</h2>
<blockquote>
<p>🤔 React에서는 props와 state라는 객체를 가지고 데이터를 다루게 됩니다. 두 객체 모두 View 를 렌더링하는데 사용되는 데이터를 가지고 있다는 공통점을 가지고 있습니다. 그 중 저희는 state에 대해서 알아보겠습니다!</p>
</blockquote>
<p>상태(State)란 <strong>UI에 반영하기 위해 유지해야 할 값</strong>이다.
리액트에서는 컴포넌트에 저장한 데이터(상태)가 변경되면 그에 따라 <strong>UI가 자동으로 갱신</strong>된다.</p>
<blockquote>
<p>🚨 따라서 리액트를 사용하면서 상태값을 효율적으로 관리하고 상태값에 따라 화면이 불필요하게 업데이트되지 않도록 주의해야 합니다. 👀</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/ad86ebb9-7ece-44cf-9479-d986b4a25e3a/image.png" alt=""></p>
<p>상태는 두 가지로 구분할 수 있는데 <code>지역상태</code>와 <code>전역상태</code>이다. 지역상태의 경우 <code>useState</code> 같이 컴포넌트 내에서 훅을 사용하는 것이다.</p>
<p>리액트는 위 사진과 같이 단방향의 특성을 지니기 때문에 상위 컴포넌트로 state를 전달할 수 없고, props로 하위 컴포넌트로 전달할 수 있다.</p>
<p>전역상태는 <strong>어떤 흐름에 얽매이지 않고, 전역에서 사용가능한 상태</strong>를 말한다.</p>
<h5 id="참고자료출처">참고자료(출처)</h5>
<ul>
<li><a href="https://jjongbin.tistory.com/entry/React-%EC%A0%84%EC%97%AD-%EC%83%81%ED%83%9C-%EA%B4%80%EB%A6%AC">개발종빈 - [React]전역상태 관리 맛보기</a></li>
</ul>
<hr>
<p>(이후 계속.. Zustand와 그리고 리액트 전역 상태관리 라이브러리에 대해 알아보자..!)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹 스토리지(localStorage, sessionStorage)]]></title>
            <link>https://velog.io/@kr-younghoon/%EC%9B%B9%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80</link>
            <guid>https://velog.io/@kr-younghoon/%EC%9B%B9%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80</guid>
            <pubDate>Thu, 21 Mar 2024 09:06:13 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://www.daleseo.com/js-web-storage/">DaleSeo님의 &quot;[자바스크립트]웹 스토리지(localStorage, sessionStorage) 사용법&quot;</a> 글을 그냥 베꼈다고 할 수 있습니다. </p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/a96027ac-2b5b-46c6-b2cd-dcd9086e14e0/image.png" width=50% middle>
</p>

<blockquote>
<p>개발자 도구 창에서 확인 해볼 수 있는 로컬 스토리와 세션 스토리지가 무엇인지 살펴보자</p>
</blockquote>
<hr>
<h3 id="내가-왜-필요했더라-🤔">내가 왜 필요했더라... 🤔</h3>
<p>졸업 작품 중 JWT에 대한 정보를 찾던 도중 로그인 성공시에 토큰을 localStorage에 저장하는 코드를 확인했다. 이 localStorage는 어떻게 쓰이고, 어떻게 써야하는지 알아보고 싶어졌다.</p>
<h4 id="jwt에서-localstorage가-쓰이는-예시를-간단하게-알아보자">JWT에서 localStorage가 쓰이는 예시를 간단하게 알아보자.</h4>
<p>로그인 요청시 사용자 정보를 axios.post()방식으로 전달한다.
서버에서 유효한 로그인 정보일 경우 jwt를 발급하여 응답 헤더에 적재하여 전달하면,
해당 응답 헤더 정보를 LocalStorage에 저장한다.</p>
<p>&lt;관련 코드&gt;</p>
<pre><code>const handleLogin = async () =&gt; {
  if(memberId !== &quot;&quot; &amp;&amp; memberPass !== &quot;&quot;){ //member 정보가 미입력 상태면 함수 발동 x
    await axios.post(&#39;/api/client/login/member&#39;, {
      memberId: memberId,
      memberPass: memberPass
    }).then((response) =&gt; { //응답결과 정상적으로 넘어온 경우 아래 로직 수행
      alert(&quot;로그인 성공&quot;);

      localStorage.setItem(&quot;accessToken&quot;, response.headers.accesstoken); // 토큰 저장

      window.location.href=&quot;/&quot;; //메인페이지로 이동
    }).catch((err) =&gt; { //서버에서 에러가 발생한 경우 경고창 알림
      alert(err.response.data.detail);
      });
  } else{
    alert(&quot;ID 혹은 비밀번호를 입력하세요.&quot;); // member 정보 미입력 시 알림
  }
}</code></pre><p>뭐 저렇게 <code>localStorage.setItem</code>으로 토큰이 저장된다고 한다.
과연 localStorage는 무엇이며, 어떻게 쓰이는지 알아보도록 하자</p>
<hr>
<h3 id="웹-스토리지web-storage">웹 스토리지(Web Storage)??</h3>
<p>웹 스토리지(Web Storage)는 서버가 아닌, 클라이언트에 데이터를 저장할 수 있도록 지원하는 HTML5의 기능입니다. 데이터의 유실성이 중요하지 않다면 보통 서버에 저장하지 않는다. 그래서 웹 스토리지를 사용한다. 웹 스토리지와 쿠키의 기능 자체는 유사하지만, 쿠키는 약 4KB 까지 밖에 저장 공간을 이용하지 못하는 반면에 웹 스토리지는 약 5MB 까지의 저장 공간을 이용할 수 있습니다.</p>
<p>자세한 웹 스토리지의 최신 스펙은 <a href="https://www.w3.org/TR/webstorage/">https://www.w3.org/TR/webstorage/</a>에서 확인할 수 있다.</p>
<p>오늘은 쿠키의 기능이 아닌 웹 스토리지만 알아보도록 하자.</p>
<h3 id="로컬-스토리지local-storage-그리고-세션-스토리지sessiong-storage">로컬 스토리지(Local Storage) 그리고 세션 스토리지(Sessiong Storage)</h3>
<p>웹 스토리지(Web Storage)에는 로컬 스토리지(localStorage)와 세션 스토리지(SessionStorage)가 있습니다. 두 개의 매커니즘의 차이점은 <strong>얼마나 오래 보존되냐</strong>입니다. </p>
<p>세션 스토리지는 웹 페이지의 세션이 끝날 때 저장된 데이터가 지워지는 반면, 로컬 스토리지는 웹페이지 세션이 종료되더라도 데이터가 지워지지 않습니다. </p>
<p>다시 말해, 브라우저에서 같은 웹 사이트를 여러 탭이나 창에 띄우면, 여러 개의 세션 스토리지에 데이터가 서로 격리되어 저장되며, 각 탭이나 창이 닫힐 때 저장해 둔 데이터도 함께 소멸됩니다.</p>
<p>로컬 스토리지는 여러 탭이나 창 간에 데이터가 서로 공유되며 탭이나 창을 닫아도 데이터는 브라우저에 그대로 남습니다.</p>
<ul>
<li><em>아하! 그래서 로그인 토큰을 세션 스토리지가 아닌 로컬 스토리지에 저장하나 봅니다!</em></li>
</ul>
<p>하지만 이러한 <strong>로컬 스토리지의 데이터 영속성(persistence)</strong> 어디까지나 계속해서 동일한 컴퓨터에서 동일한 브라우저를 사용할때만 해당합니다.</p>
<blockquote>
<p><code>영속성(persistence)</code>은 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는(비휘발성,non-volatile) 데이터의 특성을 이야기합니다.</p>
</blockquote>
<p>즉 같은 컴퓨터에서 다른 브라우저를 사용하거나, 다른 컴퓨터에서 같은 브라우저를 사용하는 경우, 서로 다른 두 개의 로컬 스토리지에 데이터가 저장됩니다.</p>
<h4 id="정리하자면">정리하자면,,</h4>
<p>로컬 스토리지와 세션 스토리지의 공통점은 두 기술 모두 데이터를 브라우저 상에서 저장한다는 것이며, <strong>자바스크립트 API가 완전히 동일한 형태</strong>입니다. 따라서 로컬 스토리지 기준으로만 예시를 알려준다고 한다. 세션 스토리지를 사용할 때는 예제 코드의 localStorage 부분을 SessionStorage로 대체하면 됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[성장]]></title>
            <link>https://velog.io/@kr-younghoon/%EC%84%B1%EC%9E%A5</link>
            <guid>https://velog.io/@kr-younghoon/%EC%84%B1%EC%9E%A5</guid>
            <pubDate>Tue, 19 Mar 2024 02:59:28 GMT</pubDate>
            <description><![CDATA[<ul>
<li>RxJS 에 대한 글 
<a href="https://yozm.wishket.com/magazine/detail/1753/">RxJS</a></li>
</ul>
<h3 id="프로젝트-구조-관련">프로젝트 구조 관련</h3>
<blockquote>
<p>최근 계속 프로젝트 구조 설계에 대한 고민을 계속 해왔다.
여전히 무엇이 좋은지 모르겠지만, 다양한 프로젝트를 통해서 계속해서 고민해볼 예정.</p>
</blockquote>
<ul>
<li>FSD
<a href="https://emewjin.github.io/feature-sliced-design/">기능 분할 설계</a></li>
</ul>
<ul>
<li>리액트 프로젝트의 좋은 구조에 대해
<a href="https://velog.io/@kennys/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%97%90%EC%84%9C-%EC%A2%8B%EC%9D%80-%EA%B5%AC%EC%A1%B0%EB%9E%80?utm_source=oneoneone">리액트 프로젝트 구조</a></li>
</ul>
<h2 id="궁금해요-궁금해">궁금해요 궁금해</h2>
<blockquote>
<p>곧 쓰게 될 araboja 포스팅. 얼른 글을 쓰고 싶다. 호호</p>
</blockquote>
<ul>
<li>vanilla-extract</li>
<li>Yarn berry vs Yarn vs NPM</li>
</ul>
<h2 id="읽어보자">읽어보자</h2>
<blockquote>
<p>세상엔 나를 자극하는 글들이 너무 많다.</p>
</blockquote>
<ul>
<li><p><a href="https://blog.stackademic.com/we-forgot-frontend-basics-2f9a1c4dabaa">We Forgot Frontend Basics!!!</a>
최근 인스타그램에서 역시 기초가 중요하다는 글들을 많이 보는 중이다. 이에 공감하고 자바스크립트에 대한 공부 욕구가 차고 넘친다. 그러다가 이 글을 발견했다. 다른걸 공부하고 있기에 나중에 보고 정리하리라.</p>
</li>
<li><p><a href="https://www.joshwcomeau.com/react/server-components/">?</a></p>
</li>
<li><p><a href="https://vanilla-extract.style/">vanilla-extract</a></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Styled Component]]></title>
            <link>https://velog.io/@kr-younghoon/Styled-Component-Emotion</link>
            <guid>https://velog.io/@kr-younghoon/Styled-Component-Emotion</guid>
            <pubDate>Wed, 13 Mar 2024 08:42:11 GMT</pubDate>
            <description><![CDATA[<h1 id="styled-component">Styled Component</h1>
<ul>
<li><a href="https://www.daleseo.com/react-styled-components/">참고자료-달서.스타일컴포넌트.블로그</a></li>
</ul>
<h2 id="패키지-설치">패키지 설치</h2>
<pre><code>$ npm i styled-components</code></pre><ul>
<li>설치할 수 있다. 설치 후엔 package.json에서 확인할 수 있다.</li>
</ul>
<h2 id="기본-문법">기본 문법</h2>
<p>먼저 위에서 설치한 <code>styled-components</code>패키지에서 <code>styled</code>함수를 임포트합니다.
<code>styled</code>는 Styled Components을 사용하려면 요놈을 써야한다.</p>
<p>기본 문법은 HTML 엘리먼트나 React 컴포넌트 중 어떤 것을 스타일링 하느냐에 따라 살짝 다르다.
그렇지만 나는 React 컴포넌트에 적용할 예정이므로 React 컴포넌트에 쓰는 법만 적어놔야지 ㅎ~</p>
<blockquote>
<p>React 컴포넌트를 스타일링 할 때는 해당 컴포넌트를 임포트 후 인자로 해당 컴포넌트를 넘기면 된다.</p>
</blockquote>
<pre><code>import styled from &quot;styled-components&quot;;
import Button from &quot;./Button&quot;;

styled(Button)`
// &lt;Button&gt; React 컴포넌트에 스타일 정의
`;</code></pre><p>이 문법은 ES6의 태그드 템플릿 리터럴을 사용해서 스타일을 정의합니다.
그리고 <code>styled</code>함수는 결국 해당 스타일이 적용된 리액트 컴포넌트를 리턴합니다.</p>
<pre><code>import styled from &#39;styled-components&#39;;

styled.button`
    font-size: 1rem;
`;</code></pre><p>이렇게 작성된 스타일드 컴포넌트로 작성된 자바스크립트 코드는 아래와 같습니다.</p>
<pre><code>button {
    font-size: 1rem;
}</code></pre><p>진짜 장점.</p>
<ul>
<li>각 완전히 격리된 스타일을 적용할 수 있다.</li>
<li>항상 css 적용하면서 불편했던 점이 개선되었다. 호호</li>
</ul>
<h2 id="고정-스타일링">고정 스타일링</h2>
<blockquote>
<p>위에서 배운 Styled Components 문법을 이용해, 간단하게 React로 작성된 버튼 커포넌트를 스타일링 해보자.</p>
</blockquote>
<p><code>styled</code>함수가 리턴하는 것은 위에서 설명드린 것처럼 React 컴포넌트이기 때문에 JSX를 통해 자유롭게 사용할 수 있습니다.</p>
<pre><code>import React from &quot;react&quot;;
import styled from &quot;styled-components&quot;;

const StyledButton = styled.button`
    padding: 6px 12px;
    border-radius: 8px;
    font-size: 1rem;
    line-height: 1.5;
    border: 1px solid lightgray;
    color: gray;
    background: white;
`;

function Button({ children }) {
    return &lt;StyledButton&gt;{children}&lt;/StyledButton&gt;;
}</code></pre><p>React 컴포넌트에서 다음과 같이 사용할 수 있다.</p>
<pre><code>import Button from &quot;./Button&quot;;
&lt;Button&gt;Default Button&lt;/Button&gt;;</code></pre><p>styled-components이 적용되었는지 확인하는 법은
브라우저에서 소스 보기를 해서 다음과 같이 &lt;button&gt; html 엘리먼트에
Styled Components가 자동으로 생성해준 클래스 이름이 적용되었음을 알 수 있습니다.</p>
<pre><code>&lt;button class=&quot;sc-kgAjT beQCgz&quot;&gt;Default Button&lt;/button&gt;</code></pre><p>내부 스타일시트를 확인해보면 클래스 선택자(class selector)로 적용된 스타일이 위에서 styled Components로 삽입한 스타일과 동일함을 알 수 있다.</p>
<pre><code>.beQCgz {
  padding: 6px 12px;
  border-radius: 8px;
  font-size: 1rem;
  line-height: 1.5;
  border: 1px solid lightgray;
  color: gray;
  background: white;
}</code></pre><h2 id="가변-스타일링-1">가변 스타일링 1</h2>
<blockquote>
<p>Styled Components는 React 컴포넌트에 넘어온 props에 따라 다른 스타일을 적용하는 기능을 제공합니다. Tagged Template Literals을 사용하기 떄문에 함수도 문자열 안에 포함시킬 수 있다는 점을 이용하는데요.</p>
</blockquote>
<p>예를 들어, 버튼의 글자색과 배경색을 props에 따라 바뀌도록 위에서 작성한 예제 코드를 변경해보자.
자바스크립트의 <code>||</code> 연산자를 사용하여 props가 넘어오지 않은 경우, 기존에 정의한 기본 색상이 그대로 유지되도록 합니다.</p>
<pre><code>import React from &quot;react&quot;;
import styled from &quot;styled-components&quot;;

const StyledButton = styled.button`
  padding: 6px 12px;
  border-radius: 8px;
  font-size: 1rem;
  line-height: 1.5;
  border: 1px solid lightgray;

  color: ${(props) =&gt; props.color || &quot;gray&quot;};
  background: ${(props) =&gt; props.background || &quot;white&quot;};
`;

function Button({ children, color, background }) {
  return (
    &lt;StyledButton color={color} background={background} Î&gt;
      {children}
    &lt;/StyledButton&gt;
  );
}</code></pre><p>여기서 주의할 점은 <code>&lt;Button/&gt;</code>에 넘어온 color와 background prop을 <StyledButton/>컴포넌트로 넘겨줘야 한다는 것입니다. 
(그러지 않을 경우, <StyledBUtton/> 컴포넌트가 해당 prop을 인식할리가 없겠죠?)</p>
<p>자, 이제 다음과 같이 버튼을 사용하면 핑크 배경에 초록 글자를 갖도록 스타일된 버튼을 만들 수 있습니다.</p>
<pre><code>import Button from &quot;./Button&quot;;
&lt;Button color=&quot;green&quot; background=&quot;pink&quot;&gt;
    Green Button
&lt;/Button&gt;</code></pre><h2 id="가변-스타일링-2">가변 스타일링 2</h2>
<blockquote>
<p>prop에 따라 바꾸고 싶은 CSS 속성이 위와 같이 하나가 아니라 여러 개일 경우가 있습니다. 이럴 경우, Styled Components에서 제공하는 css 함수를 사용해서 여러 개의 CSS 속성을 묶어서 정의할 수 있습니다.</p>
</blockquote>
<p>예를 들어, Primary prop이 넘어온 경우, 글자색을 흰색, 배경색과 경계색은 남색으로 변경하고 싶다면 다음과 같이 예제 코드를 수정할 수 있습니다. 이번에는 자바스크립트의 &amp;&amp; 연산자를 사용해서, primary prop이 존재하는 경우에만 css 로 정의된 스타일이 적용되도록 하였습니다.</p>
<pre><code>import React from &#39;react&#39;;
import styled, { css } from &#39;styled-components&#39;;

const StyleButton = styled.button`
    padding: 6px 12px;
    border-radius: 8px;
    font-size: 1rem;
    line-height: 1.5;
    border: 1px solid lightgray;

    ${(props) =&gt;
        props.primary &amp;&amp;
        css`
            color: white;
            background: navy;
            border-color: navy;
          `}
    `;  

 function Button({ children, ...props}) {
     return &lt;StyledButton {...props}&gt;{children}&lt;/StyledButton&gt;;
 }</code></pre><p>참고로 넘겨야할 prop값이 많아질 경우, 위와 같이 <code>...props</code>구문을 사용해서 children 외에 모든 prop을 간편하게 전달 할 수 있습니다.</p>
<p>자, 이제 다음과 같이 하나의 prop 만으로 여러가지 css 속성이 한번에 적용된 버튼을 얻을 수 있습니다.</p>
<pre><code>import Button from &#39;./Button&#39;;
&lt;Button primary&gt; Primary Button &lt;/Button&gt;;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Yarn 설치 및 사용]]></title>
            <link>https://velog.io/@kr-younghoon/Yarn-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9</link>
            <guid>https://velog.io/@kr-younghoon/Yarn-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%82%AC%EC%9A%A9</guid>
            <pubDate>Tue, 12 Mar 2024 06:49:14 GMT</pubDate>
            <description><![CDATA[<p>(<a href="https://heropy.blog/2017/11/25/yarn/">https://heropy.blog/2017/11/25/yarn/</a>)</p>
<h2 id="yarn-설치">Yarn 설치</h2>
<hr>
<h3 id="homebrew">Homebrew</h3>
<pre><code>$ brew install yarn
$ brew install yarn --without-node 
# NVM 같은 버전 관리 툴을 사용한다면 Node 설치를 제외해야한다.</code></pre><h2 id="yarn-사용법">Yarn 사용법</h2>
<ul>
<li>초기화 : 프로젝트를 시작할 때 초기화를 하려면(package.json을 생성)<pre><code>$ yarn init</code></pre></li>
<li><code>package.json</code>으로부터 의존성 모듈을 설치한다면?<pre><code>$ yarn
# or 
$ yarn install</code></pre></li>
<li>의존성 모듈을 설치하려면?<pre><code>$ yarn add [package]
$ yarn add [package]@[version]
$ yarn add [package]@[tag]</code></pre></li>
<li><code>devDependencies</code>, <code>peerDependencies</code>, <code>optionalDependencies</code>와 같은 다른 범주의 의존성을 추가하려면<pre><code>$ yarn upgrade [package]
$ yarn upgrade [package]@[version]
$ yarn upgrade [package]@[tag]</code></pre></li>
<li>의존성 모듈을 업그레이드하려면<pre><code>$ yarn upgrade [package]
$ yarn upgrade [package]@[version]
$ yarn upgrade [package]@[tag]</code></pre></li>
<li>의존성 모듈을 제거하려면<pre><code>$ yarn remove [package]</code></pre></li>
</ul>
<h2 id="yarnlock">yarn.lock</h2>
<hr>
<p><code>Yarn.lock</code>파일은 설치된 모듈의 버전을 저장해 어디서나 같은 버전과 구조의 의존성을 가지게 합니다.
Yarn에서는 자동으로 yarn install 때마다 yarn.lock이 생성됩니다.
<code>package-lock.json</code>와 비슷한 기능을 한다고 생각하면 됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[NPM, NPX, Yarn]]></title>
            <link>https://velog.io/@kr-younghoon/NPM-NPX-Yarn</link>
            <guid>https://velog.io/@kr-younghoon/NPM-NPX-Yarn</guid>
            <pubDate>Tue, 12 Mar 2024 06:20:26 GMT</pubDate>
            <description><![CDATA[<h3 id="npm">NPM</h3>
<blockquote>
<p>Node Package Manager, 노드 패키지 관리자.</p>
</blockquote>
<ul>
<li>JS로 작성되어 있다.</li>
<li>node.js를 설치하면 시스템에 설치된다.</li>
<li>Node 프로젝트의 필수 패키지 및 모듈은  <code>npm install</code>을 통해서 설치된다.</li>
</ul>
<h3 id="npxnode-package-execute">NPX(Node Package execute)</h3>
<blockquote>
<p>자바스크립트 패키지 관리 모듈, npm과는 다르다!</p>
</blockquote>
<ul>
<li>npm v5.2.0 에서 추가되어 기본 패키지로 제공 되었다.</li>
<li>npx는 npm 레지스트리에 있는 패키지를 더 쉽게 설치하고 관리하도록 도와주는 CLI 이다.</li>
<li>npm은 그 자체로 어떤 패키지로 “실행”하지 않는다.</li>
</ul>
<h4 id="npx는-왜-등장했을까-">NPX는 왜 등장했을까 ?</h4>
<ul>
<li>의존성 라이브러리 들이 전역이나 로컬에 설치된 채 관리가 되면 어떤 문제가 있을까?</li>
<li><ul>
<li>만약 패키지가 업데이트 된다면?</li>
</ul>
</li>
<li><ul>
<li>전역으로 , 로컬로 각각 관리되고 있는 패키지를 하나하나 업데이트하면 굉장히 번거울 것이다. 이러한 문제를 해결할 수 있는 것이 npx.</li>
</ul>
</li>
</ul>
<p>결론적으로 둘은 동일하지 않고, npm 은 패키지 관리자이며 전역적이며, npx는 패키지 실행자이며, 일회성에 가깝다.</p>
<p><img src="https://velog.velcdn.com/images/kr-younghoon/post/f7a05256-4990-4689-b02c-297227879446/image.png" alt=""></p>
<p>출처 : (<a href="https://youngmin.hashnode.dev/npm-npx?source=more_series_bottom_blogs">https://youngmin.hashnode.dev/npm-npx?source=more_series_bottom_blogs</a>)
출처 : (<a href="https://80000coding.oopy.io/3adce195-8c34-4e0a-b1fe-5c44b0768bad">https://80000coding.oopy.io/3adce195-8c34-4e0a-b1fe-5c44b0768bad</a>)</p>
<h3 id="yarn">Yarn</h3>
<blockquote>
<p>npm의 단점. 속도, 안정성, 보안성.</p>
</blockquote>
<p>yarn은 기본적으로 npm의 단점을 느꼈기 때문에 이를 향상시키기 위해 만들어진 매니징 툴이다.</p>
<h4 id="속도">속도</h4>
<p>yarn은 다운받은 패키지 데이터를 캐시(cache)에 저장하며, 중복된 데이터는 다운로드하지 않고, 캐시에 저장된 파일을 활용함으로써, npm에 비해 패키지 설치속도가 매우 빠르다.</p>
<h4 id="안정성과-보안성">안정성과 보안성.</h4>
<p>npm 은 패키지가 설치될때 자동으로 코드와 의존성을 실행하게 했다.</p>
<p>반면, yarn은 yarn.lock 이나 package.json으로 부터 설치만 하면, yarn.lock 은 모든 디바이스에서 같은 패키지를 설치하는 것을 보장하기 때문에 버전의 차이로 인한 버그를 방지할 수 있다.</p>
<p>yarn 로그는 깨끗하고 시각적으로 구별 가능하며 간단하다.
이해를 돕기 위해 트리 형식으로 정렬된다.</p>
<p>npm은 거대한 커뮤니티, 접근성으로 인한 편리성과 확장성이라는 큰 장점을 가지고 있다.</p>
<p>출처 : (<a href="https://youngmin.hashnode.dev/npm-yarn">https://youngmin.hashnode.dev/npm-yarn</a>)</p>
]]></description>
        </item>
    </channel>
</rss>