<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jeonsangmin_.log</title>
        <link>https://velog.io/</link>
        <description>sangmin's velog</description>
        <lastBuildDate>Thu, 09 Jan 2025 19:35:53 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jeonsangmin_.log</title>
            <url>https://velog.velcdn.com/images/jeonsangmin_/profile/c61e25c8-32b8-4f83-9527-9b9d1fa1a3cb/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jeonsangmin_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jeonsangmin_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[자바스크립트 변수의 호이스팅]]></title>
            <link>https://velog.io/@jeonsangmin_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B3%80%EC%88%98%EC%9D%98-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85</link>
            <guid>https://velog.io/@jeonsangmin_/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B3%80%EC%88%98%EC%9D%98-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85</guid>
            <pubDate>Thu, 09 Jan 2025 19:35:53 GMT</pubDate>
            <description><![CDATA[<p>ES6 이후로 변수 식별자로 var, let, const를 사용하게 되었다.
특히 var는 레거시한 키워드가 되버렸고 현재는 let과 const를 주로 사용하는데</p>
<p>왜 var가 레거시가 되었는지 생각해보면 호이스팅의 문제라고 생각한다.</p>
<p>여기서 궁금한건 변수의 호이스팅인데,
<em>var는 호이스팅을 일으키지만 let, const는 호이스팅이 일어나지 않는 것이라 생각하고 있었다.</em></p>
<p>허나 이는 잘못된 생각이였고 변수의 선언은 호이스팅이 일어나고 뿐만 아니라 키워드를 사용해서 선언하는 모든 식별자(변수, 함수, 클래스 등)은 호이스팅이 된다는 것이다.</p>
<p>우선 호이스팅이 무엇인지 알아보자.</p>
<blockquote>
<p>🔎 <strong>호이스팅 : 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징</strong></p>
<pre><code>console.log(score); // undefined

var score; //변수 선언</code></pre></blockquote>
<p>예시는 var로 설명했지만 let, const 또한 호이스팅은 일어난다 다만 var의 경우 에러없이 undefined로 표시되지만 let과 const는 ReferenceError를 띄우게 된다.</p>
<pre><code>console.log(score); // ReferenceError: Cannot access &#39;score&#39; before initialization

let score;</code></pre><p>위 같은 상황(호이스팅)이 발생하는 이유는 변수 선언과 할당의 실행 시점이 다르기 때문인데
자바스크립트 엔진은 소스코드를 순차적으로 실행되는 런타임 이전에 선언문이 실행되기 때문이고
할당문은 런타임에 실행된다.</p>
<p>보통 변수의 선언과 할당을 한번에 쓰고 있었기 때문에 </p>
<pre><code>let score = 100; // score 선언과 100 할당</code></pre><p>선언과 할당의 실행시점을 고려하지 않았었다.
하지만 자바스크립트 엔진은 소스코드를 순차적으로 실행되는 런타임 이전에 모든 선언문을 실행시킨다는 것이다.</p>
<p>그러므로 var, let, const는 모두 호이스팅이 발생하게 되는 것이다</p>
<p>근데 여기서 왜 var는 undefined이고 let과 const는 ReferenceError가 발생하는 것일까?</p>
<p>그 이유는 var는 선언과 즉시 undefined로 초기화를 한다는 것이다.
즉, 선언과 즉시 재할당을 하게되는 것이고 let과 const는 호이스팅은 되었지만 초기화가 이루어지지 않았기 때문에 ReferenceError가 발생하게 되는 것이다.</p>
<h3 id="🔑결론">🔑결론</h3>
<p><strong>1. 변수를 사용하기 위해선 var, let, const 식별자를 통해 선언과 할당으로 이루어진다. 
2. 선언은 메모리 공간을 확보하고 그 공간을 식별자로 구별한다.
3. 할당은 확보된 메모리 공간에 값을 초기화 시킨다.
4. var의 경우 선언과 동시에 undefined로 초기화가 이루어진다.
5. let, const는 선언을 했을 때 초기화가 이루어지지 않고 할당을 통해 초기화가 된다.
*const는 선언만 할 순 없다 (선언과 동시에 할당 필요)</strong></p>
<p>즉, &#39;var는 호이스팅을 일으키고 let, const는 호이스팅을 일으키지 않는다&#39;가 아니라 호이스팅 자체는 자바스크립트 엔진의 고유 특징이고 var를 사용 시 의도와 다르게 undefined로 덮어 쓰일 수 있고 디버깅을 찾기 어렵기 때문에 ES6 이후로 let, const 사용이 권장된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코드잇 중급 팀 프로젝트 회고]]></title>
            <link>https://velog.io/@jeonsangmin_/%EC%BD%94%EB%93%9C%EC%9E%87-%EC%A4%91%EA%B8%89-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@jeonsangmin_/%EC%BD%94%EB%93%9C%EC%9E%87-%EC%A4%91%EA%B8%89-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Mon, 02 Dec 2024 13:51:46 GMT</pubDate>
            <description><![CDATA[<p>4명이서 한팀이 되어 코드잇 중급 프로젝트 중
&quot;wikid&quot;를 진행 하였다.</p>
<p><a href="https://9-3-wikied.vercel.app/">https://9-3-wikied.vercel.app/</a> 배포 서비스
<a href="https://github.com/junjeeong/Wikied">https://github.com/junjeeong/Wikied</a> 깃허브 주소</p>
<p>&quot;wikid&quot;는 남들이 만드는 나만의 위키 페이지로 위키피디아를 모티브로 만든 프로젝트라고 할 수 있다.</p>
<p>깔끔한 디자인과 다양한 사람들과 소통할 수 있는 플랫폼이라고 생각되 선택하게 되었고 유저 기능에 대해서도 처음 도전해 볼 수 있는 과제였다.</p>
<p>개인적으로 두번째 팀프로젝트에서는 &#39;팀원의 코드를 완벽히 이해해보자&#39;라는 의지를 다지기도 했다.</p>
<h3 id="중급-프로젝트에서-나의-역할과-기여한-점"><strong>중급 프로젝트에서 &#39;나&#39;의 역할과 기여한 점</strong></h3>
<p>팀원으로서 의견을 주고 받고 작업을 공유 하였다.</p>
<blockquote>
<p>🔷Button 공통 컴포넌트 구현
    앱 여러곳에 사용되는 버튼을 많은 추상화를 통해 단 하나의 공통 버튼을 만들어 공유하였다. 하지만 너무 많은 추상화가 되어 있다보니 사용하는데에 많은 프랍스와 분기처리가 많아졌고 오히려 버튼의 사용이 불편해지기까지 하였다. 분기처리되는 부분을 여러파일로 나누면서
    FilledButton, OutlineButton, LandingButton 으로 나누면서 적당한 추상화가 오히려 도움이 된다는 것을 알았다.</p>
</blockquote>
<blockquote>
<p>🔷DropDown 공통 컴포넌트 구현
    버튼 공통 컴포넌트를 만든 이후, 드랍 다운도 만들게 되었는데 현재 사용처에 맞게 나눠 제작하였고 최대한 공통 드랍다운만 사용하면 드랍다운 메뉴, 드랍다운 메뉴의 비지니스 로직까지 구현해 놓아 가져다 쓰기만 하면 되게끔 만들었다. 이 또한 쉽게 사용할수 있다는 장점이 있지만 작업이 끝나고 보니 재사용성은 굉장히 떨어질 수 밖에 없는 구조라는걸 알게 되었다.</p>
</blockquote>
<blockquote>
<p>🔷Zustand 전역 상태관리 구현
    클라이언트 상태 관리에 대해 많이 알게되는 작업 이였다.
    상태란 변수인데 브라우저 메모리에 저장되어 컴포넌트가 리랜더링 되어도 유지된다는 기본적인 것부터 contextAPI, 리코일, 리덕스, 조타이 등 많은 전역 상태관리가 있다는 것. 그중 Zustand를 사용했는데 상태와 액션함수를 중앙 스토어에서 정의하여 전역에서 쉽게 사용할 수 있다는게 좋은 기술이고 필수적이라고 생각이 들었다.</p>
</blockquote>
<blockquote>
<p>🔷게시판(&#39;/boards&#39;) 페이지구현
    게시글 목록을 보여주고 정렬 기능(드랍다운), 쿼리스트링을 이용한 추가 데이터 불러오기(페이지 네이션), 검색 기능(서치인풋) 등 미리 만들어둔 공통 컴포넌트를 이용해서 조각조각 블럭 쌓듯 페이지 기능을 구현하였다. 내가 만든 컴포넌트 뿐아니라 팀원이 만든 공통 컴포넌트를 사용하니 잘 만들어진 부분, 아쉬운 부분이 눈에 들어오기 시작했다.</p>
</blockquote>
<blockquote>
<p>🔷게시판 상세(&#39;/boards/[id]&#39;) 페이지 구현
    게시판 페이지와 마찬가지로 공통 컴포넌트를 사용하면서 페이지를 제작하였고 페이지가 랜더링되는 방식을 생각하며 게시판 페이지는 SSG로 구현하였지만 상세페이지는 동적라우팅이되어 CSR로 구현되었다.</p>
</blockquote>
<h3 id="중급-프로젝트를-통해-새롭게-배운-것">중급 프로젝트를 통해 새롭게 배운 것</h3>
<p>기술적인 부분으로는</p>
<ol>
<li>유저 기능</li>
<li>프록시 서버 구축 방법</li>
<li>페이지 랜더링 방식 (SSR, SSG, CSR)</li>
<li>공통 컴포넌트의 추상화</li>
<li>전역 상태관리</li>
</ol>
<p>소프트 스킬로는</p>
<ol>
<li>코어타임 활용 방식</li>
<li>팀원의 작업을 이해하려는 자세</li>
</ol>
<p>특히 코어타임을 최소화 하고 개인 작업 시간을 극대화 하는 시간이라고만 생각했던 나에게 팀과 소통하고 작업 내용을 깊이 공유하면서 배움의 시간을 갖게한다는 다른 관점의 코어타임이 있다는 것을 알게 되었고,</p>
<p>기존 알고 있는 방식의 장점도 있지만 새로 알게된 방식도 굉장한 메리트가 있다라는 걸 깨달았다.</p>
<h3 id="아쉬웠던-점과-그것을-보완할-방법">아쉬웠던 점과 그것을 보완할 방법</h3>
<p>팀원 모두 프로젝트 기간 내 많은 시간과 노력을 들여 작업에 몰두 했는데
제출 마지막 날 새벽까지 버그 수정, 배포 과정이 있었다.</p>
<p>프로젝트를 더 완벽히 만들려는 자세도 있지만 기간 산정이 부족하다고 느꼈고 초기 작업에서 유저플로우, api 스웨거 확인 작업 등 사전 작업이 있었다면 프로젝트 전반적인 이해와 함께 속도가 더 나지 않았을까라는 생각이 든다.</p>
<p>프로젝트가 커질수록 빠른 작업 시작보다는 전반적으로 어떻게 흘러가는지 두루두루 체크하는 것이 더 빠른 지름길이라고 생각한다.</p>
<h3 id="중급-프로젝트-사용-스택">중급 프로젝트 사용 스택</h3>
<p>✔ HTML, CSS, JS 
✔ React
✔ Next.js (Page router)
✔ Git, GitHub, 피그마, 노션
✔ Zustand,
✔ Vercel,
✔ Tailwind,
✔ ESLint, 프리티어</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코드잇 기초 팀 프로젝트 회고]]></title>
            <link>https://velog.io/@jeonsangmin_/%EC%BD%94%EB%93%9C%EC%9E%87-%EA%B8%B0%EC%B4%88-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@jeonsangmin_/%EC%BD%94%EB%93%9C%EC%9E%87-%EA%B8%B0%EC%B4%88-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Thu, 24 Oct 2024 17:28:08 GMT</pubDate>
            <description><![CDATA[<h2 id="첫-프로젝트를-들어가며">첫 프로젝트를 들어가며..</h2>
<p>생애 첫 팀 프로젝트를 코드잇 기초 프로젝트로 진행했다
거진 2주라는 시간과 프로젝트가 처음인 5인이 모여 시작하였다😱</p>
<p>시작부터 무엇을 해야하는지 막막하였고, 
아는것 모르는것 모두 끌어모아 뭐부터 해야할지 하나씩 던져보면서 진행 되었다</p>
<p>우선 5개의 미션 중 끝마칠 수 있는 난이도?와 가장 마음에 드는 UI를 선택하였다. (피그마를 보더라도 보는 눈이 없으니 선택하기도 어려웠다..)</p>
<h2 id="사용한-기술-스택">사용한 기술 스택</h2>
<p>기본적인 스택은 정해져 있었다</p>
<p>프론트앤드 </p>
<ul>
<li>HTML, CSS, JS =&gt; React</li>
</ul>
<p>협업 기능</p>
<ul>
<li>Git, GitHub, 피그마, 노션, 게더타운</li>
</ul>
<p>그 외</p>
<ul>
<li>ESLint, 프리티어</li>
</ul>
<p>라이브러리의 경우 어떤 라이브러리가 존재하는지, 언제 사용해야하는지 감이 잡히지 않아 사용하지 못했다.</p>
<h2 id="프로젝트-내용">프로젝트 내용</h2>
<p>프로젝트가 정해지고 팀원끼리 가장 먼저한것은 피그마를 보면서 명세서와 페이지가 어떤식으로 연결되어 있는지였다.</p>
<p>명세서를 보면서 기본적인 요구사항을 파악하고
페이지에서 하는 기능들을 정리 할 수 있었다.</p>
<p>기본적으로 아이디를 입력하면 아이디에 대한 페이지가 생성되고
누구나 접근하여 글을 남길 수 있고 답글을 쓸 수 있다.</p>
<p>즉, 서로가 서로에게 방명록을 남기고 답을 받을 수 있는 어플리케이션이다.</p>
<h3 id="상세-기능-리스트">상세 기능 리스트</h3>
<p>✔ ID 생성하고 로컬스토리지에 저장
✔ 목록조회를 위해 페이지네이션 기능, 정렬 기능
✅ SNS에 공유 기능
✔ 답변의 상태를 표시
✔ 좋아요/싫어요 기능
✅ 무한스크롤
✔ 글 작성을 위한 모달 구현
✅ 여러 알림을 위한 토스트 기능
✔ 질문 목록 조회
✅ 질문 삭제/ 전체 삭제
✔ 답변 거절
✔ 답변 작성 및 등록</p>
<p>노션을 활용해 구현해야할 기능들을 회의를 통해 정리하였고
깃허브의 이슈관리, 보드를 통해 더 확실히 할 일을 나눌 수 있었다</p>
<p>구현해야할 기능들을 살펴보면
UI를 구현하거나 API 요청을하고 그 데이터들을 어떻게 보여줄 것인가.
이것이 전부였던것 같다.</p>
<p>다만 보여주는 방식이 다양하다보니 그 방식들의 원리를 알아가는게 핵심이라고 생각된다.</p>
<h2 id="보완해야할-점">보완해야할 점</h2>
<p><strong>구현 실력</strong>
프로젝트 당시에는 기능 구현에 급급했기 때문에
내가 맡은 기능이 아니면 PR이 올라와도 꼼꼼하게 보지 못하고
이해를 못하고 넘긴 부분이 많았다.</p>
<p>팀미팅을 통해서 프로젝트의 큰 흐름은 알고 있었지만 다음에 내가 구현해야하거나 비슷한 작업을 한다면 막막할 것 같은 느낌이다.</p>
<p>또한 코드 자체가 눈에 익지 않아서 인지 굉장히 어려운 책을 보는 느낌인데
꾸준히 여러 코드를 보면서 눈에 익히는 것도 중요한 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Next.js SSR 방식]]></title>
            <link>https://velog.io/@jeonsangmin_/Next.js-SSR-%EB%B0%A9%EC%8B%9D</link>
            <guid>https://velog.io/@jeonsangmin_/Next.js-SSR-%EB%B0%A9%EC%8B%9D</guid>
            <pubDate>Mon, 23 Sep 2024 17:08:25 GMT</pubDate>
            <description><![CDATA[<p>리액트만 사용하면 CSR 방식으로 초기 랜더링이 느리다는 단점이 있다.
이를 보안하기 위해 Next.js의 SSR 방식을 사용하면 단점을 극복하고
더 좋은 웹서비스 환경을 만들 수 있다.</p>
<h3 id="csr---request-발생">CSR - Request 발생,</h3>
<ol>
<li>서버에서 index.html (빈 껍데기) 브라우저로 전달</li>
<li>브라우저 빈 화면 랜더링</li>
<li>서버에서 JS 번들링 파일 브라우저로 전달</li>
<li>브라우저에서 JS 실행</li>
<li>컨텐츠 랜더링 ⚡FCP</li>
</ol>
<p>![React CSR]
(<a href="https://velog.velcdn.com/images/jpy1030/post/851e7279-e2af-44e9-acdd-5cf304efcfad/image.png">https://velog.velcdn.com/images/jpy1030/post/851e7279-e2af-44e9-acdd-5cf304efcfad/image.png</a>) -출처 이정환 강사님 Next.js 강의</p>
<h3 id="ssr---request-발생">SSR - Request 발생,</h3>
<ol>
<li>서버에서 JS 실행</li>
<li>랜더링 된 HTML 브라우저(클라이언트) 전달</li>
<li>브라우저 컨텐츠 랜더링 ⚡FCP</li>
<li>서버에서 JS 번들링 파일 브라우저에게 전달</li>
<li>컨텐츠가 동작 가능하게 하이드레이션</li>
<li>상호작용 가능 ⚡TTI</li>
</ol>
<p><img src="https://velog.velcdn.com/images/jeonsangmin_/post/33f49f47-afb5-4f79-8514-c295c131b075/image.png" alt="Next SSR"> -출처 이정환 강사님 Next.js 강의</p>
<p>FCP(First Contentful Paint)
브라우저에서 컨텐츠 랜더링이 되는 시간을 뜻하는데
이 속도가 SSR이 CSR보다 빠르기 때문에 유저에게 좋은 UX를 선보일 수 있다.</p>
<p>하지만 SSR에도 문제가 하나 있는데
컨텐츠 랜더링이 되었어도 아직은 상호작용은 불가하다.
단순히 HTML만 랜더링 되었기 때문이고 서버에서 JS 번들링 파일을
브라우저에게 주면 브라우저에서 랜더링 된 HTML에 JS파일을 입혀
상호작용 할 수 있게 해주는 하이드레이션을 진행한다.</p>
<p>이 작업이 끝나야 실질적으로 유저가 웹서비스를 사용할 수 있다.</p>
<p>상호작용이 가능한 시점을 TTI라 하며 FCP와 TTI의 간격을 줄이기 위해
리액트 서버 컴퍼넌트를 이용하여 JS 번들링할 컴퍼넌트를 경량화 하여
번들링 시간을 줄이고 하이드레이션 시간도 줄일 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Next.js 사용하는 이유]]></title>
            <link>https://velog.io/@jeonsangmin_/Next.js-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@jeonsangmin_/Next.js-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Fri, 20 Sep 2024 05:26:03 GMT</pubDate>
            <description><![CDATA[<p>지금까지 리액트로 개발을 진행해 왔다.
다음 스텝으로 Next.js를 배우게 되는데</p>
<p>리액트와 Next.js의 차이점이 무엇인지 알아보자.</p>
<p>우선 리액트는 SPA(Single Page Application)이고, CSR(Client Side Rendering)으로 페이지를 구현한다.</p>
<p>SPA로 인해 부드러운 화면 이동을 할 수 있지만 
CSR로 인해 현재 페이지에 사용하지 않지만 앱에 필요한 모든 컴포넌트를 다운로드 하기 때문에
첫 로딩 시간이 오래 걸린다. 이로 인해 유저 경험을 헤칠 수 있다.</p>
<p>Next.js는 CSR이 아닌 SSR 방식으로 서버에서 랜더링하여 페이지를 받아오게 된다.
이로 인해 첫 로딩 시간이 빠르고, 만들어진 페이지를 받기 때문에 SEO에도 유리하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TypeScript 기본]]></title>
            <link>https://velog.io/@jeonsangmin_/TypeScript-%EA%B8%B0%EB%B3%B8</link>
            <guid>https://velog.io/@jeonsangmin_/TypeScript-%EA%B8%B0%EB%B3%B8</guid>
            <pubDate>Fri, 13 Sep 2024 18:19:22 GMT</pubDate>
            <description><![CDATA[<h2 id="javsscript-와-typescript의-차이는-무엇일까"><strong>JavsScript 와 TypeScript의 차이는 무엇일까?</strong></h2>
<p>JS에 추가적인 문법을 더한 것이 TS 이다.
추가적인 문법이란 타입을 지정하는 문법이라고 볼 수 있다.</p>
<p>JS는 컴파일 언어가 아닌 인터프리터 언어이기 때문에
실행 전에는 오류를 미리 검사하지 않는다.
실행하면서 오류가 발생하는 런타임 오류가 발생하기 때문에 사전에 에러를 해결하지 못하면
배포 중 사용 시 에러가 나타날 수도 있기에 조심해야한다.</p>
<p>에러 중에서도 타입 에러가 자주 발생 할 수 있는데
그 이유는 JS가 동적 타이핑 언어이기 때문이다.
변수의 자료형을 자유롭게 변경이 가능하여 개발할때는 편하게 코드를 작성할 수 있지만
타입관련 실수가 잦을 수 있고 실수가 발생했을 때 오류를 발견하기 어렵다.</p>
<p>**타입에러에 관련하여 문제를 해결하기 위해 나온 언어가 TS이다.</p>
<ol>
<li>변수에 정적 타이핑을 지원</li>
<li>배포하기 전에 타입 체크**</li>
</ol>
<h2 id="typescript는-어떻게-동작-할까"><strong>TypeScript는 어떻게 동작 할까?</strong></h2>
<p>TS를 컴파일하여 JS를 만들고 JS를 실행한다.
TS는 실제 프로젝트를 실행할 때는 사용하지 않는다.
그 이유는 브라우저 혹은 node.js는 TS를 읽지 못하고 JS를 읽을 수 있기 때문이다.</p>
<p>타입을 명확하게 작성하기 위해 TS를 이용하고 컴파일하여 JS를 생성하는데
웹 서비스 상에서는 &#39;컴파일&#39;을 &#39;트랜스파일&#39;이라고 한다.</p>
<p>트랜스파일을 진행하면서 타입을 체크하여 에러가 있을 시 알려준다.
트랜스 파일을 진행하는 프로그램을 TSC(타입스크립트 컴파일러)라고 한다.</p>
<p>트랜스 파일 진행 시 JS의 어떤 버전으로 바꿀지는
tsconfig.json파일에서 JS버전을 지정할 수 있다.</p>
<p><strong>정리하면 TS - tsc -&gt; JS - node -&gt; 프로젝트 실행</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[cs 면접 질문 ]]></title>
            <link>https://velog.io/@jeonsangmin_/cs-%EB%A9%B4%EC%A0%91-%EC%A7%88%EB%AC%B8</link>
            <guid>https://velog.io/@jeonsangmin_/cs-%EB%A9%B4%EC%A0%91-%EC%A7%88%EB%AC%B8</guid>
            <pubDate>Mon, 02 Sep 2024 01:46:19 GMT</pubDate>
            <description><![CDATA[<h1 id="cs-면접-질문">CS 면접 질문</h1>
<h2 id="1-wwwnavercom-을-주소창에-입력하면-어떻게-될까요">1. <a href="http://www.naver.com">www.naver.com</a> 을 주소창에 입력하면 어떻게 될까요?</h2>
<p>(네트워크 관련)</p>
<p>“주소창에 url을 입력하면 ui에 네이버화면이 로딩됩니다.” 라고 말하면 안됩니다.</p>
<p>입력 후 일련의 과정을 설명해야 합니다.</p>
<p>만약 화면이 랜더링이 안될 때 어디에 문제가 있는지 역추적을 할 수 있어야 하기 때문에 과정을 아는 것이 중요.</p>
<p><strong>네이버 주소를 입력하면 입력된 주소가 실제로 어떤 컴퓨터에 연결되어 있는지 알아내기 위해 DNS 서버에 질의를 보냅니다. DNS 서버는 도메인에 해당하는 IP 주소를 찾아 브라우저에 알려줍니다.</strong></p>
<p><strong>브라우저는 DNS로 받은 IP 주소를 이용하여 해당 서버(네이버)와 TCP 연결을 요청합니다.</strong></p>
<p><strong>연결이 된다는 것은 클라이언트와 서버가 데이터를 주고 받을 수 있게 됩니다.</strong></p>
<p><strong>브라우저는 서버에 HTTP 요청을 보냅니다.</strong></p>
<p> <strong>이 요청은 네이버 홈페이지의 HTML 문서를 보내달라는 요청입니다.</strong></p>
<p><strong>받은 HTML 문서를 랜더링하여 웹페이지를 화면에 표시합니다.</strong></p>
<p><strong>간단히 요약하면 네이버 주소를 입력하면 DNS를 통해 IP 주소를 찾고, TCP 연결을 통해 서버와 통신하여 HTML 문서를 받아와 브라우저가 화면에 랜더링하는 과정을 거치게 됩니다.</strong></p>
<h2 id="2-쿠키-로컬-스토리지-세션-스토리지에-대해-설명해주세요">2. 쿠키, 로컬 스토리지, 세션 스토리지에 대해 설명해주세요</h2>
<p>(운영체제, 메모리 관련)</p>
<p>우선 공통적으로 쿠키, 로컬 스토리지, 세션 스토리지는 웹 애플리케이션에서 사용자 정보를 저장하기 위해 사용되는 메커니즘이며 모두 클라이언트에서 저장합니다.</p>
<p>쿠키는 서버가 클라이언트에 보내는 작은 크기의 텍스트 파일로, 클라이언트는 이를 저장 후</p>
<p>다음 요청 시 서버로 다시 보냅니다.</p>
<p>특히, 로그인 상태 유지에 쓰이며 유효 기간은 서버에서 설정 됩니다.</p>
<p>로컬 스토리지는 데이터를 영구적으로 저장하는 메커니즘입니다.</p>
<p>브라우저 종료 후에도 데이터가 유지되며 쿠키보다 많은 양의 데이터를 저장할 수 있습니다.</p>
<p>사용자의 설정 저장 혹은 장바구니 정보 저장 등에 쓰입니다.</p>
<p>세션 스토리지는 데이터를 임시로 저장하는 메커니즘입니다.</p>
<p>브라우저 탭을 닫으면 데이터가 삭제됩니다.</p>
<p>페이지 간에 데이터를 전달 혹은 검색 결과와 같은 임시 데이터를 저장합니다.</p>
<p><strong>즉, 쿠키는 서버와 클라이언트 간의 상태를 유지하는 간단한 설정에 쓰이고,</strong> </p>
<p><strong>로컬스토리지는 자주 변경하지 않는 장기간 데이터를 저장 할 때,</strong></p>
<p><strong>세션 스토리지는 특정 세션 동안만 사용해야 할 데이터를 저장할 때 사용합니다.</strong></p>
<h2 id="3-오버로딩과-오버라이딩에-대해-설명해-주세요">3. 오버로딩과 오버라이딩에 대해 설명해 주세요</h2>
<p>(객체지향 프로그래밍 관련)</p>
<p>오버로딩과 오버라이딩은 객체지향 프로그래밍에서 자주 사용되는 개념으로, 메서드를 다양하게 활용하는 방법입니다.</p>
<p>우선 <strong>오버로딩은 같은 이름의 메서드를 여러개 정의하는 것을 말합니다.</strong></p>
<p><strong>메서드의 이름은 같지만 매개변수의 개수나 타입이 달라야합니다.</strong></p>
<p>add라는 메서드가 있을 때, 매개 변수로 정수형, 실수형 등 여러개의 메소드를 정의 할 수 있습니다.</p>
<p>오버로딩의 장점은 코드의 재사용성을 높이고 가독성을 향상시킵니다.</p>
<p><strong>오버라이딩은 상위 클래스의 매서드를 하위 클래스에서 재정의하는 것을 말합니다.</strong></p>
<p>‘동물’이라는 상위 클래스에서 ‘소리’라는 메서드를 정의 한다면</p>
<p>이를 상속받는 ‘고양이’라는 하위 클래스에서 ‘소리’ 메서드를 오버라이딩하여 ‘야옹’이라는 소리를 출력하도록 구현할 수 있습니다.</p>
<p>오버라이딩의 장점은 클래스 상속 관계에서 특정 메서드의 기능을 변경할 수 있다는 점입니다. </p>
<p><strong>즉, 오버로딩은 같은 이름의 메서드를 매개변수의 차이로 구분하여 사용하는 방법이고</strong></p>
<p><strong>오버라이딩은 상위 클래스의 메서드를 하위 클래스에서 재정의하여 다형성을 구현하는 방법입니다.</strong></p>
<h2 id="4-프로세스와-스레드에-대해-설명해-주세요">4. 프로세스와 스레드에 대해 설명해 주세요</h2>
<p>(운영체제 관련)</p>
<p>프로세스는 실행중인 프로그램은 의미하며</p>
<p>스레드는 프로세스 내 실행 단위를 의미합니다.</p>
<p>각 프로세스는 독립적인 메모리 공간을 가지며, 운영체제는 프로세스 간의 자원 접근을 분리합니다.</p>
<p>하나의 프로세스가 실패해도 다른 프로세스에는 영향을 미치지 않습니다.</p>
<p>스레드는 프로세스 내에서 여러 스레드, 멀티스레드로 존재 가능하며 메모리와 자원을 공유합니다.</p>
<p>이를 통해 스레드 간의 통신이 빠르고 효율적이지만, 하나의 스레드가 문제를 일으킬 경우 같은 프로세스 내의 다른 스레드에도 영향을 미칠 수 있습니다.</p>
<p><strong>요약하면 프로세스는 자원(메모리와  CPU)을 프로세스마다 할당받아서 사용하는데</strong></p>
<p><strong>스레드는 프로세스 안에서 다른 스레드와 자원(메모리와 CPU)을 공유해서 사용합니다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[5.3.1] 그래프 ~ [5.3.2] 트리]]></title>
            <link>https://velog.io/@jeonsangmin_/5.3.1-%EA%B7%B8%EB%9E%98%ED%94%84-5.3.2-%ED%8A%B8%EB%A6%AC</link>
            <guid>https://velog.io/@jeonsangmin_/5.3.1-%EA%B7%B8%EB%9E%98%ED%94%84-5.3.2-%ED%8A%B8%EB%A6%AC</guid>
            <pubDate>Wed, 21 Aug 2024 14:53:01 GMT</pubDate>
            <description><![CDATA[<p>비선형 자료 구조란
일렬로 나열하지 않고 자료 순서나 관계가 복잡한 구조를 말하며</p>
<p>일반적으로 그래프, 트리를 말한다. </p>
<h2 id="그래프">그래프</h2>
<p><strong>정점과 간선으로 이루어진 자료 구조</strong></p>
<p>정점(vertex): 위치라는 개념. (node 라고도 부름)
간선(edge): 위치 간의 관계. 즉, 노드를 연결하는 선 (link, branch 라고도 부름)</p>
<p> 단반향 간선과 양방향 간선이 있다.</p>
<p>가중치(Weight): 간선의 크기 또는 두 노드를 연결하는 데 필요한 비용을 나타내는 값</p>
<h2 id="🔷-트리란">🔷 트리란</h2>
<p>✔ 그래프 중 하나 (정점과 간선으로 이루어짐)
✔ 트리 구조로 배열된 일종의 계층적 데이터의 집합
✔ 연결된 비순환 무방향 그래프의 한 형태</p>
<p>즉, 특정 조건을 만족하는 그래프라고 볼 수 있다.</p>
<p><img src="https://blog.kakaocdn.net/dn/eeoNuG/btq1Eo7t7Xk/0bPk7BzhiruKSsgtiubvK0/img.png" alt="트리"></p>
<h2 id="🔷-트리-특성">🔷 트리 특성</h2>
<p>🔹 트리의 구성
루트 노드, 내부 노드, 리프 노드</p>
<p>루트 노드 : 트리의 최상단에 있는 노드, 트리의 시작점
내부 노드 : 자식 노드를 가지는 노드 (= 부모 노드)
리프 노드 : 자식 노드가 없는 노드 (= 외부 노드)</p>
<p>🔹 DOM트리와 비슷하게 부모, 자식, 형제 관계를 가진다.
🔹 <code>간선의 수(E) = 노드 수(V) - 1</code>
<img src="https://i.namu.wiki/i/8pViDtKiYxEmcz1zj2WHZEpLHeu4q4n1bAjOOTvA4rLde3d-miR4lbCeFRjhzuTV1SLW5vFdg81Q6vb6fm1I9Q.webp" alt="트리 높이와 레벨"></p>
<blockquote>
<p>🔹 트리의 높이와 레벨
    깊이 : 루트 노드에서 해당 노드까지 경로의 간선 수
    높이 : (루트)노드에서 리프 노드까지의 가장 긴 경로의 간선 수
    레벨 : 노드와 루트 노드 사이의 경로의 간선 수 
    서브 트리 : 트리 내의 하위 집합 또는 부분집합</p>
</blockquote>
<p> 🔹 트리 종류
 이진 트리, 이진 탐색 트리, AVL 트리, 레드 블랙 트리</p>
<h3 id="📌이진-트리">📌이진 트리</h3>
<p>자식의 노드 수가 두 개 이하인 트리 (최대 2개)
왼쪽 자식 노드 (left child) / 오른쪽 자식 노드 (right child)</p>
<img src= "https://velog.velcdn.com/images/jeonsangmin_/post/bd094d85-90a3-439f-be28-b0cb27e26676/image.png" width="50%">

<p>🔶<strong>형태에 따른 이진 트리의 종류</strong></p>
<p>🔸정이진 트리(full binary tree): 
모든 노드는 자식 노드가 없거나 두개인 트리
🔸완전 이진 트리(complete binary tree):
마지막 레벨을 제외한 모든 레벨에서 노드가 빠짐없이 채워져 있고
마지막 레벨은 왼쪽부터 빠짐없이 노드가 채워져있는 트리
🔸변질 이진 트리(degenerate binary tree):
모든 부모 노드는 하나의 자식 노드만 가지는 트리
🔸포화 이진 트리(perfect binary tree):
모든 레벨에서 노드가 빠짐없이 채워져 있는 트리
🔸균형 이진 트리(balanced binary tree):
모든 노드에서 왼쪽 서브 트리와 오른쪽 서브 트리의 높이 차이가
최대 1인 트리</p>
<p><img src="https://velog.velcdn.com/images/youhyeoneee/post/8d70f900-6d58-423b-8c6f-391a065712ac/image.png" alt="이진 트리 종류"></p>
<h3 id="📌이진-탐색-트리bst-binary-search-tree">📌이진 탐색 트리(BST, binary search tree)</h3>
<div style="display: flex">

<img src= "https://velog.velcdn.com/images/jeonsangmin_/post/715a46db-2266-4703-af27-7e464c150bb6/image.png" width="50%">

<p>모든 노드의 왼쪽 서브 트리는
해당 노드의 값보다 작은 값들만 가지고
모든 노드의 오른쪽 서브 트리는
해당 노드의 값보다 큰 값들만 가진다
<br/>
  이진 탐색 트리의 최소 값
   -&gt; 트리의 가장 왼쪽에 존재
<br/>
  이진 탐색 트리의 최대 값
   -&gt;트리의 가장 오른쪽에 존재</p>
</div>

<blockquote>
<p><strong>⚡이진 탐색 트리의 시간 복잡도 (* N = 트리의 노드 수)</strong></p>
<p>일반적인 경우는 트리의 노드가 균형을 맞춰서 퍼저있는 상태로
평균 O(logN) 의 삽입, 삭제, 검색 시간 복잡도를 가진다.</p>
<p>최악의 경우는 노드가 선형적으로 구성되어 노드의 수만큼 순회를 해야할 경우로 O(N) 의 삽입, 삭제, 검색 시간 복잡도를 가진다.</p>
</blockquote>
<h3 id="📌avl-트리">📌AVL 트리</h3>
<p>✔ 이진 탐색 트리(BST)의 한 종류
✔ 스스로 균형을 잡는 트리 / O(N)  -&gt; O(logN)
✔ balance factor를 통해 균형 유지</p>
<pre><code>balance factor는 트리의 모든 노드들의 
왼쪽, 오른쪽 서브트리의 높이를 -1, 0, 1 값만 가지게 하는 것
즉, BF(x) 은 { -1, 0, 1 } 집합을 가지게 한다.</code></pre><p>삽입 혹은 삭제 과정이 생기면 balance factor이 높이를 감지하고
균형이 안맞으면 이진 탐색 트리 기준에는 맞게, 선형적인 부분은 없애는 방향으로 트리 일부를 회전시키며 균형을 잡는다.
<img src="https://blog.kakaocdn.net/dn/blxsRD/btq21CW9Fw3/WOk8F74J254K1pczckskEK/img.png" alt="AVL 트리"></p>
<h3 id="📌레드-블랙-트리">📌레드 블랙 트리</h3>
<p>✔ 이진 탐색 트리(BST)의 한 종류
✔ 스스로 균형을 잡는 트리 / O(N)  -&gt; O(logN)
✔ 모든 노드는 red 혹은 black
✔ 루트 노드는 black
✔ red의 자식 노드는 black
✔ 임의의 노드에서 자손 nil 노드들 까지 가는 경로들의 black 수는 같다
(자기 자신은 카운트 제외)</p>
<pre><code>💡nil 노드란?
-존재하지 않음을 의미하는 노드
-자식이 없을 때 자식을 nil노드로 표기
-값이 있는 노드와 동등하게 취급
-RB트리에서 리프 노드는 nil 노드</code></pre><p><img src="https://velog.velcdn.com/images/kku64r/post/02fd3f93-505c-4952-943c-d7d68692fcf6/image.jpg" alt="레드블랙트리"></p>
<blockquote>
<p>✔ red의 자식 노드는 black
✔ 임의의 노드에서 자손 nil 노드들 까지 가는 경로들의 black 수는 같다
(자기 자신은 카운트 제외)</p>
<p>노드가 삽입 혹은 삭제 될 때 이 두가지 조건을 지키기 위해서 수정이 일어나다 보면 자연스럽게 균형잡힌 트리 구조가 된다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS-in-JS(feat.styled-components)]]></title>
            <link>https://velog.io/@jeonsangmin_/CSS-in-JSfeat.styled-components</link>
            <guid>https://velog.io/@jeonsangmin_/CSS-in-JSfeat.styled-components</guid>
            <pubDate>Wed, 21 Aug 2024 09:48:59 GMT</pubDate>
            <description><![CDATA[<p>리액트 전에 순수 자바스크립트만 사용할 때에는
HTML에 CSS 파일을 Link하여 사용하였다.</p>
<p>리액트을 사용하면서 컴포넌트가 많아지면서 CSS을 잘 관리하고자
Module.css 과 styled-components 같은 방법들을 알게 되었고</p>
<p>두 방법 모두 class명이 중복될 수 있는 문제를 방지시켜준다.</p>
<p>그 중 Javascript 파일 혹은 JSX 파일 내에서 CSS를 사용할 수 있게 해주는
CSS-in-JS 을 알아보자.</p>
<h2 id="css-in-js">CSS-in-JS</h2>
<p>style을 JavaScript 코드 안에서 작성하는 방식.</p>
<p>컴포넌트 단위로 style을 관리하기 때문에 class명이 겹칠일이 없다.</p>
<p>styled-components는 CSS-in-JS 방식 중의 하나인 라이브러리이다.
특히, React와 함께 많이 사용되며, 템플릿 리터럴을 사용해 style 작성.</p>
<h3 id="설치-방법">설치 방법</h3>
<blockquote>
<p> 1) styled-componenets 설치 
    npm install styled-components</p>
<p> 2) component 파일에 적용
 import styled from &#39;styled-components&#39;;</p>
</blockquote>
<h3 id="사용-방법">사용 방법</h3>
<pre><code> const 컴포넌트 = styled.HTML태그`
    css 속성: 속성 값;
 `;</code></pre><pre><code>예시)
import styled from &quot;styled-components&quot;;

const Title = styled.h1`
  background-color: #ededed;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  font-weight: 700;
`;

function Test() {
  return (
    &lt;div&gt;
      &lt;Title&gt;안녕 Styled Components!&lt;/Title&gt;
    &lt;/div&gt;
  );
}

export default Test;</code></pre><h3 id="네스팅">네스팅</h3>
<p>CSS 규칙 안에서 CSS 규칙을 만드는 것</p>
<pre><code>예시)
import styled from &quot;styled-components&quot;;
import nailImg from &#39;./nail.png&#39;;

const Title = styled.h1`
  background-color: #ededed;
  font-size: 16px;
  font-weight: 700;

  &amp;:hover {
      background-color: #463770;
  }

  ${Icon} {
    margin-right: 4px;
  }

`;

function Test() {
  return (
    &lt;div&gt;
      &lt;Title&gt;안녕 Styled Components!
          &lt;Icon src={nailImg} alt=&quot;nail icon&quot;/&gt;
      &lt;/Title&gt;
    &lt;/div&gt;
  );
}

export default Test;</code></pre><ol>
<li>&amp;선택자를 통해서 hover를 추가하였다.</li>
<li>컴포넌트 선택자를 통해서 자손 컴퍼넌트 Icon의 css를 추가하였다.</li>
</ol>
<h3 id="props-활용">Props 활용</h3>
<pre><code>let 컴포넌트 = styled.HTML태그`
    font-size: 25px;
    color: ${ props =&gt; props.색상 }
`;</code></pre><p> color가 다른 HTML태그를 여러개 만들고 싶을 때 props를 만들어서 개별적용
color가 다른 HTML태그를 여러개 만들고 싶을 때, 개별적용할 속성을 props로 만든다
Ex) &lt;컴포넌트 color=&quot;red&quot;&gt; HTML태그 내용 &lt;/컴포넌트&gt;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드의 전반적인 개략도]]></title>
            <link>https://velog.io/@jeonsangmin_/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%9D%98-%EC%A0%84%EB%B0%98%EC%A0%81%EC%9D%B8-%EA%B0%9C%EB%9E%B5%EB%8F%84</link>
            <guid>https://velog.io/@jeonsangmin_/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C%EC%9D%98-%EC%A0%84%EB%B0%98%EC%A0%81%EC%9D%B8-%EA%B0%9C%EB%9E%B5%EB%8F%84</guid>
            <pubDate>Sun, 18 Aug 2024 15:56:53 GMT</pubDate>
            <description><![CDATA[<div style="font-size:14px">
이 글을 쓰는 이유는 '나' 자신이 프론트앤드 개발자가 되기위해
알아야하는 전반적인 지식, 정보를 정리하기 위함이다.

<p>프론트앤드가 무엇을 하는지, 기본적인 기술 스택은 무엇인지라는 큰 틀부터 각 기술 스택의 요약 등을 정리 할 생각이다.</p>
<p>큰 틀을 알고 있어야지 나의 역량, 실력 등을 틀에 빗대어 판단 할 수 있을 것이라 본다.</p>
</div>

<h2 id="📌프론트앤드-개발자는-무슨-일을-할까">📌프론트앤드 개발자는 무슨 일을 할까?</h2>
<p>기본적으로 프론트앤드 개발자는 웹 개발자다.
웹(WWW, wolrd wide web) 자체의 목적은 데이터 전달이며
웹 개발은 데이터를 잘 전달하기 위함이다.</p>
<p><img src="https://velog.velcdn.com/images/jeonsangmin_/post/35c5f701-df64-433b-bf0a-546c78b620ba/image.png" alt="프론트앤드 전반적인 역할">
출처:유뷰트 투더제이</p>
<p>위 그림에서 보이듯이 프론트앤드는 백엔드에 API를 통해 
데이터를 요청하고 JSON 형식 등으로 데이터를 받게 된다.</p>
<p>받은 데이터를 클라이언트(유저)에게 UI를 통해 보여주는 역할이다</p>
<p>유저가 원하는 정보가 같다면 더욱 보기 좋고 친숙한 화면,
검색에 상위 포지션을 갖게하는 것, 누구나 쉽게 이용할 수 있도록 하는것,
자연스런 화면 송출, 빠른 데이터 처리 등이 사용자에게 선택을 받을 것이다.</p>
<p>그것을 알기위해 프론트앤드의 여러 기술 스택을 알고자 한다.</p>
<h2 id="📌프론트앤드-기술-스택">📌프론트앤드 기술 스택</h2>
<p>기술 스택을 정리한 기준은 내가 배워왔고 배우려고하는 기술들의 나열이다.
분명 이 스택들이 전부도 아니고 추후 트랜드가 바뀌어 새로운 기술이 나올 수 도 있다는 점을 생각해야한다.
그러므로 현재 배우는 언어들의 장단점을 잘 파악하는 것이 중요하다고 본다.</p>
<p>(각각의 기술이 어떤 느낌인지 정말 간단하고 짧게 요약한다.)</p>
<p>🔹HTML - 웹 페이지를 구축하는 뼈대라고 볼 수 있다</p>
<p>  ✔ SEO, 검색엔진 최적화를 신경써야한다
  -&gt; 시멘틱 태그,</p>
<p>  ✔ 접근성 (누구나 쉽게 이용 가능하게 만듦)</p>
<p>🔹CSS - 뼈대에 스타일을 줘서 꾸미는 것</p>
<p>  ✔ 올바른 class, id 작명
  ✔ css가 겹치지 않게 필요한 속성만 사용</p>
<p>🔹JavaScript - 뼈대를 동작하게 하는 것</p>
<p> ✔ 각 태그들의 대표적인 속성들을 알고 있어야함
 ✔ 어떤 이벤트들이 있는지 알아야함
 ✔ 이벤트 핸들러로 어떻게 구현할지 생각 할 줄 알아야함
 ✔ 데이터를 요청하는 방법 </p>
<p>🔹React - HTML, CSS, JS 를 한 공간에 나누어서 만드는 것</p>
<p> ✔ 컴포넌트를 어떻게 나눌지 알아야함
 ✔ 어떤 것을 state로 지정해야할지 알아야함
 ✔ 자식, 자손 컴포넌트에게 props를 내려서 사용할 줄 알아야 함</p>
<p>🔹Node.js - JS를 서버 측에서도 실행 시킬 수 있게하는 런타임 환경
🔹Next.js - React 기반의 SSR을 위한 프레임워크
🔹TypeScript - Type을 정해서 사용하는 JS.
🔹 React native - 모바일 앱에서도 개발 가능하게 하는 것</p>
<p>🔹git - 프로젝트의 버전관리 및 협업을 위한 툴
🔹CS (자료구조, 운영체제, 네트워크, 데이터베이스, 디자인패턴)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[4.6 조인의 종류 ~ 4.7 조인의 수행원리]]></title>
            <link>https://velog.io/@jeonsangmin_/4.6-%EC%A1%B0%EC%9D%B8%EC%9D%98-%EC%A2%85%EB%A5%98-4.7-%EC%A1%B0%EC%9D%B8%EC%9D%98-%EC%88%98%ED%96%89%EC%9B%90%EB%A6%AC</link>
            <guid>https://velog.io/@jeonsangmin_/4.6-%EC%A1%B0%EC%9D%B8%EC%9D%98-%EC%A2%85%EB%A5%98-4.7-%EC%A1%B0%EC%9D%B8%EC%9D%98-%EC%88%98%ED%96%89%EC%9B%90%EB%A6%AC</guid>
            <pubDate>Sun, 18 Aug 2024 05:09:00 GMT</pubDate>
            <description><![CDATA[<p>관계형 DB는 데이터 관리를 하기위해 정규화 과정을 거치는데 이 데이터들을 합친 결과를 얻고 싶을 때 조인을 사용한다.</p>
<p><em><strong>조인이란 두 개이상의 테이블을 하나의 집합으로 만드는 연산이다</strong></em>.</p>
<p>3개의 테이블을 하나의 집합으로 만든다면
A, B를 먼저 조인하고 그 결과와 C를 조인하는 과정을 거친다.</p>
<p>이런 테이블을 합치는 과정을
관계형에서는 Join 이라하며,
비관계형에서는 LookUp 이라한다.</p>
<p>비관계형의 LookUp 쿼리는 Join 연산보다 성능이 떨어지기 때문에
(성능이 떨어지거나 지원을 하지 않는다. 조인 없이 효율적으로 쿼리 할수 있도록 설계 됨)
관계형에서의 Join만 다뤄보도록 하겠다.</p>
<h2 id="조인의-종류">조인의 종류</h2>
<p><img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSjjSaO4gK_WnSXVWzr7-Iwn6xiT_BXzEflRw&s" alt="조인 종류"></p>
<h3 id="📌inner-join">📌Inner Join</h3>
<p>내부 조인은 두 테이블 간에 교집합을 의미
(Inner를 생략하고 Join만 쓸 수 있다.)</p>
<pre><code>SELECT * FROM TableA A
(INNER) JOIN TableB B ON
A.key = B.key</code></pre><pre><code>✔ SELECT: 데이터 조회를 위한 명령문
✔ *: 만족하는 모든 요소
✔ FROM: 기본 테이블 지정
✔ TableA: 기본 테이블
✔ A: TaleA의 별칭
✔ INNER JOIN: 조인의 종류 중 하나
✔ TableB: 조인 될 테이블
✔ B: TableB의 별칭
✔ ON: 어떤 조건으로? (Join condition)
✔ A.Key = B.key : A의 키값과 B의 키값이 같은 조건</code></pre><p>*다양한 연산자 가능( = , &gt; , &lt; , != )
*null 값을 가지는 튜플(tuple)은 result table에 포함되지 못한다.</p>
<h3 id="📌outer-join">📌Outer Join</h3>
<p>두 테이블에서 Join condition을 만족하지 않는 튜플들도 result table에 포함하는 join
(null 값을 가져도 포함될 수 있다.)
*다양한 연산자 가능( = , &gt; , &lt; , != )</p>
<p>예시) EMPLOYEE라는 TableA와 DEPARTMENT라는 TableB 가 있을때
A의 dept_id와 B의 id의 같은 값을 조인해보자</p>
<p><img src="https://velog.velcdn.com/images/jeonsangmin_/post/d8e1877e-3471-46e5-a556-29195dd5fa2b/image.png" alt=""></p>
<h4 id="left-outer-join">LEFT [OUTER] JOIN</h4>
<p>SELECT * FROM TableA A
LEFT OUTER JOIN TableB B ON
A.key = B.key</p>
<p><img src="https://velog.velcdn.com/images/jeonsangmin_/post/d9d50d2f-0891-449c-a8f8-a5d38cec2a27/image.png" alt=""></p>
<p>RIGHT [OUTER] JOIN</p>
<p>SELECT * FROM TableA A
RIGHT OUTER JOIN TableB B ON
A.key = B.key</p>
<p><img src="https://velog.velcdn.com/images/jeonsangmin_/post/babac5e3-2eae-4798-a5c6-4871ee05e22d/image.png" alt=""></p>
<p>FULL [OUTER] JOIN</p>
<p>SELECT * FROM TableA A
FULL OUTER JOIN TableB B ON
A.key = B.key</p>
<p><img src="https://velog.velcdn.com/images/jeonsangmin_/post/9e6b4dc1-6d70-4897-a1ea-8c6ef825dc42/image.png" alt=""></p>
<h3 id="📌cross-join">📌Cross Join</h3>
<p>중첩 for문 처럼 각각의 튜플을 모든 타 테이블의 튜플에 매칭 시키는 것 </p>
<h3 id="📌natural-join">📌Natural Join</h3>
<p>같은 속성을 합쳐서 join 하는 경우 (속성은 같은데 속성 값들이 다르다면 빈 테이블이 결과값이 된다.)</p>
<h3 id="📌self-join">📌Self Join</h3>
<p>table이 자기 자신에게 join하는 경우</p>
<p><strong>=&gt; 조인의 종류는 inner, outer, cross, natural, self 가 있다.</strong></p>
<h2 id="조인의-수행-원리">조인의 수행 원리</h2>
<h3 id="nljnested-loop-join">NLJ(Nested Loop Join)</h3>
<p>☑ 중첩된 반복문과 유사한 방식으로 조인을 수행
☑ 반복문 외부에 있는 테이블을 선행 테이블 또는 외부테이블(Outer Table)이라 함
☑ 반복문 내부에 있는 테이블을 후행 테이블 또는 내부테이블(Inner Table)이라 함
☑ 선행 테이블의 조건을 만족하는 행을 추출하여 후행 테이블에 조인을 수행
☑ (조건을 만족하는 행이 적은 선행 테이블을 선택해야 전체 일량을 줄일 수 있다)
☑ 랜덤 방식으로 데이터를 엑세스</p>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F252B804C57CBCE5924" alt="NL 조인"></p>
<h4 id="특징">특징</h4>
<p>✅절차적이며, 프로그래밍에서 FOR, WHILE문 과 같은 구조로 수행된다.</p>
<p>✅선행테이블은 풀스캔하므로, 선행테이블의 크기가 작을수록 유리하다
(So. 두 테이블의 크기 차이가 있는 경우, 유리하게 사용될 수 있는 방법임)</p>
<p>✅후행테이블에 대해서는 반드시 인덱스가 존재해야 NL 조인이 가능하다.</p>
<p>✅랜덤 액세스 방식으로 데이터를 읽는다.-&gt; 처리 범위가 좁은 것이 유리하다.</p>
<p>이런 여러가지 특징을 종합할 때, NL 조인은 소량의 데이터를 주로 처리하거나 부분범위처리가 가능한 온라인 트랜잭션 환경에 적합한 조인 방식이라고 할 수 있다.</p>
<h3 id="smjsort-merge-join">SMJ(Sort Merge Join)</h3>
<p>☑ 조인 컬럼을 기준으로 데이터를 정렬하여 조인을 수행합니다. </p>
<p>☑ 후행 테이블의 적절한 인덱스가 없어도 가능</p>
<p>☑ 스캔 방식 ( &lt;-&gt; NL : 랜덤 엑세스 방식)
=&gt; 대용량의 테이블들을 조인 가능</p>
<p><img src="https://velog.velcdn.com/images/eunhye_/post/60b80d9f-e301-4943-9ca8-a8b37a89a93a/image.png" alt="Sort Merge Join"></p>
<h4 id="특징-1">특징</h4>
<p>✅인덱스가 없어도 가능한 조인법</p>
<p>✅조인할 테이블이 이미 정렬되어 있을 때 유리</p>
<p>✅조인 조건식이 등차(=)조건이 아닐 때도 가능</p>
<p>✅두 테이블의 사이즈가 비슷한경우에 유리하며, 사이즈 차이가 큰 경우에는 불리하고, 비효율적인 방법이다.</p>
<h3 id="hash-join">HASH JOIN</h3>
<p>☑ Hash Join은 해싱 기법을 이용하여 조인을 수행합니다. </p>
<p>☑ 조인될 두 테이블 중 하나를 해시 테이블로 선정하여 (빌드 단계)
조인될 테이블의 조인 키 값을 Hash 알고리즘으로 비교하여 매치되는 결과값을 얻는 방식입니다. (프로브 단계)</p>
<p>☑ HASH JOIN은  &#39;=&#39; 비교를 통한 조인에서만 사용될 수 있습니다. </p>
<p>☑ 주로 많은 양의 데이터를 조인해야 하는 경우에 주로 사용됩니다.</p>
<p><img src="https://velog.velcdn.com/images/eunhye_/post/377d8aa3-819c-4a0c-82c8-cd51723b60d3/image.png" alt="Hash Join"></p>
<h4 id="특징-2">특징</h4>
<p>✅ 조인 칼럼의 인덱스를 사용하지 않기 때문에 조인 칼럼의 인덱스가 존재하지 않을 경우데도 사용할 수 있는 기법이다.</p>
<p>✅ 해쉬 함수를 이용하여 조인을 수행하기 때문에 &#39;=&#39;로 수행하는 조인에서만 사용가능 합니다.</p>
<p>✅ 대용량 테이블에 유리</p>
<p>✅ 테이블을 한번씩만 읽게 되어 성능에 유리 ( &lt;-&gt; NLJ)</p>
<h2 id="정리-조인의-종류와-수행-원리알고리즘-매칭">정리, 조인의 종류와 수행 원리(알고리즘) 매칭</h2>
<ol>
<li><p>INNER JOIN: 
NLJ, Sort-Merge Join, Hash Join</p>
</li>
<li><p>OUTER JOIN: 
NLJ, Sort-Merge Join, Hash Join</p>
</li>
<li><p>CROSS JOIN: 
주로 NLJ로 수행되며, 모든 가능한 조합을 생성합니다.</p>
</li>
<li><p>NATURAL JOIN: 
INNER JOIN의 일종으로 NLJ, Sort-Merge Join, Hash Join을 사용합니다.</p>
</li>
<li><p>SELF JOIN: 
테이블을 두 번 조인하는 방식으로 NLJ, Sort-Merge Join, Hash Join을 사용할 수 있습니다.</p>
</li>
</ol>
<p>각 조인 알고리즘은 특정 상황에 따라 최적화 될 수 있으며, 조인의 종류에 따라 선택 된다.</p>
<p>실행 계획을 보면 어떤 알고리즘이 쓰이고 있는지 알 수 있고
내가 생각한 최적화 방법이 아니라면
오라클 힌트를 사용하여 다른 알고리즘으로 유도할 수 있다.
(다시 실행 계획을 살펴 보고 알고리즘이 바뀌었는지 확인 할 수 있다.)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSR, SSR, SSG]]></title>
            <link>https://velog.io/@jeonsangmin_/CSR-SSR-SSG</link>
            <guid>https://velog.io/@jeonsangmin_/CSR-SSR-SSG</guid>
            <pubDate>Fri, 16 Aug 2024 03:21:33 GMT</pubDate>
            <description><![CDATA[<p>CSR, SSR, SSG 셋 모두 랜더링에 관한 방식이다.</p>
<pre><code>CSR(Client Side Rendering): 클라이언트 측, 랜더링
SSR(Server Side Rendering): 서버 측, 랜더링
SSG(Static Site Generation): 서버 측, 만들어진 랜더링</code></pre><p>정말 간단하게 단어 풀이와 요약을 보면
어디에서 랜더링을 하느냐, 언제 랜더링을 하느냐로 3가지로 나뉜다.</p>
<p>좀 더 구체적으로 하나씩 알아보자</p>
<h2 id="spa--mpa">SPA &amp; MPA</h2>
<p>갑자기 3가지 랜더링 얘기 중 다른 단어가 나왔는데
SPA와 MPA을 알아야 3가지 랜더링 방식을 깊이 있게 알 수 있다.</p>
<h3 id="☑-spasingle-page-applicaiton">☑ SPA(Single Page Applicaiton)</h3>
<p><strong>하나의 페이지 안에서 화면이 바뀌거나 이동하는 것</strong>
웹 어플리케이션에 필요한 모든 정적 리소스를 최초 한번에 다운로드 하고,
그 이후에 요청이 있을 때 페이지 갱신에 필요한 데이터만 받아서 페이지를 구성한다.</p>
<p>리소스를 다운받아 클라이언트 쪽에서 랜더링 하기 때문에 CSR 랜더링 방식이 사용된다.</p>
<p>장점 : 부드러운 화면 이동(화면 깜빡임 없음)
단점 : 초기 랜더링 시 필요한 리소스가 상대적으로 많아 로딩시간이 길어질 수 있다.</p>
<h3 id="☑-mpamulti-page-application">☑ MPA(Multi Page Application)</h3>
<p><strong>여러개의 페이지를 구성하여 화면이 바뀔때마다 다른 페이지를 보여주는 것</strong>
페이지 갱신이 필요 할때, 서버에 요청하여 랜더링 된 HTML을 받게 된다.</p>
<p>서버에서 랜더링을 하기 때문에 SSR 방식이 사용된다.</p>
<p>장점 : 초기 진입 시 로딩이 빠르다. 또한 SEO 검색엔진 최적화에 유리하다
단점 : 페이지 이동 혹은 새로고침 시, 전체 페이지를 다시 받아온다. (화면 깜빡임 생김)</p>
<h2 id="csr-ssr-ssg">CSR, SSR, SSG</h2>
<p>SPA 혹은 MPA 에서 3가지 랜더링 방식이 자연스럽게 쓰이고 있는데
서로의 장점으로 단점을 보완 할 수 있다.</p>
<p>SPA을 구성하되 CSR을 사용하면 초기 랜더링 시간이 길어 질 수 있기에
SSR 방식으로 초기 랜더링을 하여 검색엔진 최적화(SEO)에 유리하게 하며 동시에 로딩 시간도 빠르게 할 수 있다. 그 이후 다시 CSR 방식을 사용하여 화면이 이동 될 때에 부드럽게 화면을 전환하게 만드는 방법이 있다.
만약 초기에 받아오는 데이터가 자주 바뀌는 데이터가 아니라면 SSG 방식으로 대체해도 무방할 것이라 본다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React Life Cycle]]></title>
            <link>https://velog.io/@jeonsangmin_/React-Life-Cycle</link>
            <guid>https://velog.io/@jeonsangmin_/React-Life-Cycle</guid>
            <pubDate>Fri, 16 Aug 2024 02:14:18 GMT</pubDate>
            <description><![CDATA[<p>리액트를 사용하다보면 Life Cycle(생명주기)라는 말을 자주 듣게 된다.
중요한 개념이니까 자주 나오는 것 같으니 알아보도록 하자.</p>
<h2 id="✔누구의-생명-주기인가">✔누구의 생명 주기인가</h2>
<p>컴포넌트의 생명 주기를 말하며, 모든 리액트 컴포넌트는 생명주기가 존재한다</p>
<p>컴포넌트가 <strong>생성되고 업데이트되고 제거되는 3가지 과정을 생명 주기</strong>라 한다</p>
<pre><code>생성: 마운팅(Mounting)
업데이트: 업데이팅(Updating)
제거: 언마운팅(Unmounting)</code></pre><p>각각의 과정이 어떤 과정인지 알아보자.</p>
<h3 id="📌마운팅mounting">📌마운팅(Mounting)</h3>
<p>컴포넌트가 탄생하는 순간
화면에 처음 렌더링 되는 순간</p>
<p>ex. &quot;A 컴포넌트가 Mount 되었다&quot; =&gt; A 컴포넌트가 화면에 처음으로 렌더링 되었다.</p>
<h3 id="📌업데이팅updating">📌업데이팅(Updating)</h3>
<p>컴포넌트가 다시 렌더링 되는 순간
리렌더링 될 때를 의미</p>
<p>ex. &quot;A 컴포넌트가 업데이트 되었다&quot; =&gt; A 컴포넌트가 리렌더링 되었다.</p>
<h3 id="📌언마운팅unmounting">📌언마운팅(Unmounting)</h3>
<p>컴포넌트가 회면에서 사라지는 순간
렌더링에서 제외 되는 순간을 의미</p>
<p>ex. &quot;A 컴포넌트가 언마운트 되었다&quot; =&gt; A 컴포넌트가 화면에서 사라졌다.</p>
<h2 id="✔왜-생명주기를-가지는가">✔왜 생명주기를 가지는가?</h2>
<p>리액트는 컴포넌트로 이루어져 있다.
컴포넌트을 효율적으로 관리 하기 위해 개발자가 라이프사이클을 설계해 두었다.</p>
<p>컴포넌트를 효율적으로 관리한다는 것은
자원 관리, 상태 관리, 성능 최적화, 사용자 경험 향상을 위함이다.</p>
<blockquote>
<p>💡자원 관리 : 컴포넌트가 생성 되거나 소멸 될때, 이벤트 리스너 등록/해제 혹은 네트워크 요청/취소 등을 통해 메모리를 관리
💡상태 관리 : 컴포넌트가 업데이트 될 때 (리랜더링) , 새로운 props를 기반으로 로직을 처리 할 수 있다
💡성능 최적화 : 컴포넌트가 다시 랜더링 될 필요가 없는 경우를 감지 -&gt; 불필요한 랜더링을 방지
💡사용자 경험 향상 : 애니메이션, 데이터 로드, 사용자 인러택션 기능을 올바른 시점에 실행되도록 보장</p>
</blockquote>
<h2 id="✔알면-뭐가-좋은지">✔알면 뭐가 좋은지?</h2>
<p>컴포넌트의 Life Cycle을 잘 이해하고 있다면 
우리가 원하는 타이밍에 컴퍼넌트에게 어떠한 작업을 시킬 수 있다.</p>
<p>ex. 마운트 타이밍에 네트워크 데이터를 불러오는 작업
    업데이트 타이밍에 어떤 값이 변경되었는지 콘솔 출력
    언마운트 타이밍에 컴포넌트가 사용했던 메모리 정리</p>
<p>불필요한 리랜더링을 방지할 수 있다.</p>
<h2 id="✔어디에-쓸-수-있는-개념인지">✔어디에 쓸 수 있는 개념인지?</h2>
<p> 함수 리액트에서 useEffect() Hook으로 컴포넌트의 life Cycle을 제어 할 수 있다.</p>
<p>클래스 컴포넌트로 life Cycle을 제어해 왔지만 요새 추세는 함수형 컴포넌트로 제어를 하기에 함수형 컴포넌트의 life Cycle 제어하는 방법만을 소개해 두었다. </p>
<h3 id="마운트"><strong>마운트</strong></h3>
<pre><code> useEffect (() =&gt; {
  console.log(&quot;mount&quot;);
 }, []);</code></pre><p>컴포넌트의 첫 랜더링 이후 useEffect의 첫번째 아규먼트인 콜백함수가 실행 된다.
이후 빈 배열이기 때문에  state 값이 변해도 더 이상 작동하지 않는다.</p>
<p>컴포넌트가 마운트 될 때 -&gt; 콜백 함수 실행(원하는 작업 적용)</p>
<h3 id="업데이트"><strong>업데이트</strong></h3>
<pre><code> useEffect (() =&gt; {
  console.log(&quot;update&quot;);
 });</code></pre><p>컴포넌트가 랜더링 될 때마다 useEffect()의 아규먼트인 콜백 함수가 실행 된다.
첫 번째 랜더링에서 실행 없이 리랜더링 될 때에만 콜백 함수를 실행하고 싶다면
레퍼런스 객체와 조건문을 사용해서 구현 할 수 있다.</p>
<pre><code>const isMount = useRef(false);

 useEffect (() =&gt; {
 if(!isMount.current) {
     isMount.current = true;
     return;
 }
   console.log(&quot;update&quot;);
 });</code></pre><p>컴포넌트 업데이트 단계에서만 콘솔 출력이 일어남</p>
<h3 id="언마운트">언마운트</h3>
<pre><code> useEffect (() =&gt; {
     console.log(&quot;mount&quot;)

   return () =&gt; {
       console.log(&quot;unmount&quot;);
   };
 }, []);</code></pre><p>useEffect() 안의 return문을 클린업, 정리함수라고 불리는데
useEffect 함수가 끝날 때 실행이 된다.</p>
<p>컴포넌트가 mount 될 때(첫 랜더링) &quot;mount&quot;가 출력되고
컴포넌트가 unmount 될 때(랜더링에서 사라짐) &quot;unmount&quot;가 출력된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React의 Key]]></title>
            <link>https://velog.io/@jeonsangmin_/React%EC%9D%98-Key</link>
            <guid>https://velog.io/@jeonsangmin_/React%EC%9D%98-Key</guid>
            <pubDate>Fri, 09 Aug 2024 17:49:14 GMT</pubDate>
            <description><![CDATA[<p>배열을 랜더링 할때 
키를 지정하지 않거나
키를 지정하더라도 배열의 인덱스같이 데이터를 구분할수 없는
고유하지 않은 값으로 키를 지정하면 
랜더링이 잘못될수있다.</p>
<p>랜더링이 잘못된다는건
특정 요소에 변경사항이 생긴 후, 배열의 순서가 바뀐다면
특정 요소의 변경사항이 다른 요소에게 영향을 미칠 수 있다는 것.</p>
<p>이것때문에 키를 지정해 두어서 요소를 구분할수있어야한다.</p>
<p>정리하면,</p>
<ol>
<li>효율적인 업데이트</li>
</ol>
<p>각 요소가 고유한 값을 가지기 때문에 이전 상태와 새로운 상태를 식별할 수 있다.</p>
<ol start="2">
<li>일관된 컴포넌트 상태 유지</li>
</ol>
<p>요소들의 순서의 변경이 생겨도 추적하기가 용이하다.</p>
<ol start="3">
<li>리액트의 경고 메세지를 방지</li>
</ol>
<p>키를 안쓰면 리액트에서 경고메세지를 보낸다..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Virtual DOM ]]></title>
            <link>https://velog.io/@jeonsangmin_/Virtual-DOM</link>
            <guid>https://velog.io/@jeonsangmin_/Virtual-DOM</guid>
            <pubDate>Fri, 09 Aug 2024 17:33:09 GMT</pubDate>
            <description><![CDATA[<p>React를 사용하면 장점으로 Virtual DOM이 있다.
Virtual DOM 이 무엇이고 어떤점이 장점인지 알아보자.</p>
<blockquote>
<p>💡Virtual : 가상의
💡DOM : Document Object Model, 문서 객체 모델</p>
</blockquote>
<p>DOM은 HTML의 모든 요소를 뜻하며
Javascript는 DOM을 이용해 HTML의 요소에 접근한다. </p>
<p>접근하여 이벤트를 만들고 이벤트가 발생하면
DOM 요소에 변경사항이 생기기 때문에 브라우저는 해당 변경 사항을
즉시 랜더링한다.</p>
<p>(변경 사항에는 요소를 추가, 삭제, 속성 변경이 있다)</p>
<h2 id="dom-뭐가-문제지">DOM, 뭐가 문제지?</h2>
<p>DOM 조작은 비교적 무겁다고 하는데 무거운 이유는 다음과 같다</p>
<p>브라우저가 DOM 트리를 탐색하고, 변경 사항을 반영하기 위해
Reflow와 Repaint를 처리하는 과정이 비교적 길기 때문이다.</p>
<blockquote>
<p>💡Reflow(레이아웃 계산): DOM에서 요소의 위치나 크기와 관련된 스타일을 변경하면, 브라우저는 모든 요소의 레이아웃을 다시 계산한다.
이 과정이 Reflow이며 문서의 크기와 복잡성에 따라서 시간도 비용도 커진다.</p>
</blockquote>
<blockquote>
<p>💡Repaint(화면 다시 그리기): 요소의 색상, 글꼴 등 스타일이 변경되면 브라우저는 해당 요소를 다시 그려야 한다. Reflow 보다는 비용이 적지만, 자주 발생하면 역시 성능에 영향을 미칠 수 있다.</p>
</blockquote>
<p>변경 사항을 바로 업데이트하지 않고 모았다가 한번에 수정한다면
위와 같은 처리 시간과 비용이 비약적으로 줄어들 것이다.</p>
<p><strong>이런 방식을 자동으로 해주는 것이 Virtual DOM을 활용한 리액트라고 볼 수 있다.</strong></p>
<h2 id="virtual-dom은-어떻게-랜더링-할까">Virtual DOM은 어떻게 랜더링 할까?</h2>
<p>Virtual DOM 이란
실제 DOM을 카피한 가상 DOM이라 생각하면 된다.</p>
<p>변경사항이 생기면 실제 DOM을 수정하기 전에 가상 DOM에 먼저 반영해본다.</p>
<p>가상 DOM에 변경사항들이 모이면 한번에 실제 DOM으로 변경사항을 보내고
실제 DOM은 한번의 수정이 일어나게 된다.</p>
<p>리액트는 컴포넌트의 상태(state)나 속성(props)이 변경되기만 하면 가상돔에 변경사항을 효율적으로 계산하고, 이로 인해 불필요한 DOM 조작이 줄어들게 된다.</p>
<p>이런 이점으로 대규모 프로젝트에서는 가상돔을 쓰는 리액트가 효율적이라 볼 수 있다.</p>
<p>추가로 가상돔은 리액트에서 가장 널리 알려져 있지만 리액트 뿐만아니라 다른 프레임워크, 라이브러리에서도 가상돔이 쓰인다.
Ex) Vue.js , Snabbdom, Inferno, Mithril, Preact</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[3.3.6] 스레드와 멀티스레딩 ~ [3.4] CPU 스케줄링 알고리즘]]></title>
            <link>https://velog.io/@jeonsangmin_/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C</link>
            <guid>https://velog.io/@jeonsangmin_/%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4%EC%99%80-%EC%8A%A4%EB%A0%88%EB%93%9C</guid>
            <pubDate>Thu, 08 Aug 2024 13:19:58 GMT</pubDate>
            <description><![CDATA[<h2 id="336-스레드와-멀티스레딩">3.3.6 스레드와 멀티스레딩</h2>
<h3 id="📙스레드">📙스레드</h3>
<p>스레드는 프로세스의 실행 가능한 가장 작은 단위입니다.
프로세스는 최소 한개 부터 여러개의 스레드를 가질 수 있습니다.
<img src="https://images.velog.io/images/dust_potato/post/c1a4beb3-2967-4d49-947e-07e592080859/image.png" alt="멀티스레드 메모리">
여러 스레드를 가질때에는 코드, 데이터, 힙은 공유하고
스택 영역을 각각 생성하여 스레드 간의 독립성을 유지합니다.</p>
<h3 id="📙멀티스레딩">📙멀티스레딩</h3>
<p>프로세스안에 스레드가 하나라면 작업을 하나씩 진행해야합니다.</p>
<p>여러 작업을 동시에 하고 싶다면 스레드가 하나이기 때문에
여러개의 프로세스를 사용하면 되는데 몇가지 아쉬운 점이 있습니다.</p>
<ol>
<li>프로세스의 컨텍스트 스위칭은 무겁다</li>
<li>프로세스끼리 데이터 공유가 까다롭다</li>
<li>듀얼 코어의 등장</li>
</ol>
<p>위의 문제로 스레드라는 개념이 나왔고
하나의 프로세스 안에 여러개의 스레드를 두어서 작업을 동시에 처리하도록 만들었습니다.</p>
<p>이로써 프로세스간의 이동이 아닌 프로세스 내의 이동으로 해결 가능.
-&gt;같은 프로세스의 스레드들끼리의 컨텍스트 스위칭이 가볍다
-&gt;스레드들은 자신들이 속한 프로세스의 메모리 영역을 공유</p>
<p>즉, 멀티스레딩은 프로세스 내 작업을 멀티스레드로 처리하는 기법입니다.</p>
<h2 id="337-공유-자원과-임계-영역">3.3.7 공유 자원과 임계 영역</h2>
<h3 id="📘공유-자원">📘공유 자원</h3>
<p><strong>✔공유 자원(shared resource)</strong>은 시스템 안에서 각 프로세스/스레드가 함께 접근할 수 있는 자원이나 변수를 의미합니다.
자원의 예는 모니터, 프린터, 메모리, 파일, 데이터 등이 있습니다.</p>
<p><strong>✔경쟁 상태(race condition)</strong>은 공유 자원을 두 개 이상의 프로세스가 동시에 읽거나 쓰는 상황입니다.
동시에 데이터를 조작할때, 타이밍이나 접근 순서에 따라 결괏값이 달라질 수 있습니다.</p>
<h3 id="📘임계-영역">📘임계 영역</h3>
<p>임계 영역(critical section)은 경쟁상태로 인해 결과가 달라지는 코드 영역입니다.</p>
<p>임계 영역을 해결하기 위한 방법은 <strong><em>뮤텍스, 세마포어, 모니터</em></strong> 3가지 입니다.
3가지 방법은 모두 상호 배제, 한정 대기, 융통성이란 조건을 만족합니다.</p>
<p>이 방법에 토대가 되는 메커니즘은 잠금(lock)입니다.</p>
<pre><code>lock을 사용하는 대표적인 프로그래밍 언어는 주로 
멀티스레딩 또는 병렬 처리를 지원하는 언어들 입니다.
Java, C++, C#, Python, Go, Rust, Ruby 등이 있습니다.
*언어마다 lock의 형태는 다름</code></pre><blockquote>
<p>💡상호 배제(mutual exclustion)
한 프로세스가 임계 영역에 들어갔을 때 다른 프로세스는 들어갈 수 없다
💡한정 대기(bounded waiting)
특정 프로세스가 영원히 임계 영역에 들어가지 못하면 안 된다
💡융통성(progress)
만약 어떠한 프로세스도 임계 영역을 사용하지 않는다면 임계 영역 외부의 어떠한 프로세스도 들어갈 수 있으며 이 때 프로세스끼리 서로 방해하지 않는다.</p>
</blockquote>
<h3 id="1-뮤텍스">1. 뮤텍스</h3>
<p> 뮤택스(mutex)는 프로세스/스레드가 공유 자원을 lock()을 통해 잠금 설정하고 사용한 후에는 unlock()을 통해 잠금 해제하는 객체입니다.</p>
<p>잠금이 설정되면 다른 프로세스/스레드는 접근 불가.
해제 시, 접근 가능</p>
<p>뮤텍스는 잠금 또는 잠금 해제라는 상태만을 가집니다.
<img src="https://blog.kakaocdn.net/dn/cvk7nh/btrjvSw2BoX/Zfh0o0VsZrMmAOi6PxLvg0/img.png" alt="뮤텍스"></p>
<h3 id="2-세마포어">2. 세마포어</h3>
<p>세마포어(semaphore)는 일반화된 뮤텍스입니다.
코드 구조가 정형화 되어있다고 볼 수 있고
간단한 정수 값과 두가지 함수 (wait, signal)로 공유 자원에 대한 접근을 처리합니다.
 P(wait)연산 : 세마포어의 값을 감소시키고, 값이 0 이하이면 대기
 V(signal)연산 : 세마포어의 값을 증가시키고, 대기 중인 프로세스가 있으면 이를 깨워 실행.
 <img src="https://blog.kakaocdn.net/dn/cYZOiu/btrjvrzaimS/QtooHYav5Sj1JpT9yTtb1K/img.png" alt="세마포어"></p>
<p> 📌 바이너리 세마포어
 정수 값 0,1만 가지는 세마포어.
 구현의 유사성으로 인해 뮤텍스는 바이너리 세마포어라고 할 수 있지만
 (잠금 == 0 / 해제 ==1)
 뮤텍스는 락을 가진 자만 락을 해제 할 수 있지만 세마모어는 아닙니다.</p>
<p> 뮤텍스가 강한 자물쇠라면 세마포어는 약한 자물쇠라고 할 수 있습니다.</p>
<p> 📌 카운팅 세마포어
 여러 개의 값을 가지는 세마포어, 여러 자원에 대한 접근을 제어하는데 사용 됩니다.</p>
<h3 id="3-모니터">3. 모니터</h3>
<p>모니터는 둘 이상의 프로세스/스레드가 공유 자원에 안전하게 접근할 수 있도록 공유 자원을 숨기고 해당 접근에 대해 인터페이스만 제공합니다.
<img src="https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTf65iuWdGloTV0hHrVD8_rrNg7gIev6BT1zg&s" alt="모니터">
모니터는 모니터큐를 통해 공유 자원에 대한 작업들을 순차적으로 처리합니다.</p>
<p>모니터는 세마포어보다 구현하기 쉽고, 상호 배제(하나만 들어갈 수 있는 것)는 자동인 반면 세마포어는 상호 배제를 명시적을 구현이 필요합니다.</p>
<h2 id="338-교착-상태">3.3.8 교착 상태</h2>
<p>교착 상태(deadlock)는 두 개 이상의 프로세스들이 서로가 가진 자원을 기다리며 중단된 상태입니다.
<img src="https://velog.velcdn.com/images/jeonsangmin_/post/e9368b29-a038-4a3e-aab1-244fec530ea1/image.png" alt=""></p>
<h3 id="원인">원인</h3>
<p>✔상호 배제: 리소스를 공유해서 사용할 수 없다
✔점유 대기: 프로세스가 이미 하나 이상의 리소스를 취득한 상태에서 다른 프로세스가 사용하고 있는 리소스를 추가로 기다린다.
✔비선점: 리소스 반환은 오직 그 리소스를 취득한 프로세스만 할 수 있다.
✔환형 대기: 프로세스들이 순환 형태로 서로의 리소스를 기다린다.</p>
<p><strong>🤬4가지 조건이 갖춰지면 데드락, 교착상태가 발생한다.</strong></p>
<h3 id="해결-방법">해결 방법</h3>
<p>OS의 데드락 해결 방법</p>
<ol>
<li>데드락 방지 - 네 가지 조건 중 하나가 충족되지 않게 시스템을 디자인</li>
<li>데드락 회피 - 데드락이 발생할 것 같은 상황을 회피하는 것(은행원 알고리즘 사용)</li>
<li>데드락 감지와 복구 - 데드락을 허용하고 데드락이 발생하면 복구하는 전략 (한 개씩 프로세스를 종료)</li>
<li>데드락 무시 - 아.몰.랑 시전 사용자가 작업을 종료하게한다.
(4가지 방법 모두 속 시원하게 해결하지는 않는다.🤢)</li>
</ol>
<blockquote>
<p>💡은행원 알고리즘:리소스 요청을 허락해줬을 때 데드락 발생할 가능성이 있으면, 리소스를 할당해도 안전할 때 까지 계속 요청을 거절하는 알고리즘</p>
</blockquote>
<h2 id="34-cpu-스케줄링-알고리즘">3.4 CPU 스케줄링 알고리즘</h2>
<p><img src="https://velog.velcdn.com/images/wn8624/post/16d49933-2c80-422c-9894-325fc1c5484c/image.png" alt="프로세스 상태">
<strong>스케줄러</strong>는 CPU가 쉬지 않고 일하게 하기 위해 실행할 프로세스를 선택하는 역할을 합니다</p>
<p>실행 중인 프로세스가 종료, 중단, 대기 상태로 가게되면 CPU가 비워있게 되는데 이때, 비어있지 않게 바로 이어서 다른 프로세스가 실행되어야 합니다.</p>
<p>그럼 어떤 프로세스가 실행되어야 할까요.
이것을 정해 주는 것이 스케줄러라고 합니다.</p>
<p>ready 단계에 있는 프로세스들을 모아둔 것이 레디큐이며
프로세스들이 실행 대기 중입니다</p>
<p>레디큐의 프로세스들중 스케줄러가 프로세스를 선택</p>
<p><strong>디스패쳐</strong>는 스케줄러가 선택한 프로세스를 실제로 cpu에 실행 되도록하는것</p>
<ol>
<li>컨텍스트 스위칭 (커널 모드에서 실행됨)</li>
<li>user mode로 바꿔주는것</li>
<li>적절한 위치로 프로세스를 이동</li>
</ol>
<p>(스케줄러와 디스패쳐를 같게 보는 관점도 있으니 두루 알고계시면 좋을 것 같습니다.)</p>
<p><img src="https://velog.velcdn.com/images/hyoon1129/post/22282c3d-3844-4e72-a47d-9100d72efe6b/image.png" alt="CPU스케줄링"></p>
<h3 id="341-비선점형-방식">3.4.1 비선점형 방식</h3>
<p>프로세스가 종료, I/O 작업, 양보 (자발적) 준비단계로감
프로세스가 자발적으로 실행중에서 다른 상태로 넘어가는것을
비선점형 방식이라함</p>
<p>신사적, 협력적(프로세스가 스스로 양보), 느린 응답성</p>
<p>강제적으로 프로세스를 중지하는게 아니라서 프로세스가 자발적으로 멈출때까지 기다리기 때문에 느린 응답성</p>
<h4 id="📝fcfsfirst-come-first-served">📝FCFS(first-come, first-served)</h4>
<p>먼저 도착한 순서대로 처리</p>
<h4 id="📝sjfshortest-job-first">📝SJF(shortest-job-first)</h4>
<p>프로세스의 다음 CPU burst(실행 시간)가 가장 짧은 프로세스부터 실행</p>
<h4 id="📝우선순위">📝우선순위</h4>
<p>우선순위가 높은 순서부터 처리</p>
<p>(우선순위는 도착 순서의 역순이 될수도,
실행 시간이 긴 것 부터가 될 수 있다.)</p>
<p>처리 도중 우선순위가 먼저인 프로세스가 생긴다면
비선점형은 일단 하던 프로세스는 마무리 될 때까지 기다리고
선점형은 우선순위가 먼저인 프로세스를 실행시킨다.</p>
<h3 id="342-선점형-방식">3.4.2 선점형 방식</h3>
<p>비선점형 방식을 기본적으로 행합니다.
추가적으로 프로세스가 끝나지 않았을때도 개입하는 것
실행 중인 프로세스를 ready 상태 (레디큐)로 보내는 것</p>
<p>프로세스가 충분히 cpu를 다 쓰지 않았음에도
다른 프로세스를 실행 시키기 위해 현재 프로세스를 강제로 중단.</p>
<p>적극적, 강제적, 빠른 응답성</p>
<h4 id="📝라운드-로빈rr-round-robin">📝라운드 로빈(RR, Round Robin)</h4>
<p>time slice로 나눠진 CPU time을 번갈아가며 실행
Ex)
Process1 = 10ms
Process2 = 6ms
Process3 = 3ms</p>
<p>time slice = 4ms 
 =&gt; P1 (10 - 4) / P2 ( 6 - 4 ) / P3 ( 3 - 3 ) / P1 ( 6 -4 ) ~</p>
<p> time slice가 길어지면 FCFS가 되고 짧아질수록 컨텍스트 스위칭이 잦아지는 현상 발생합니다.</p>
<h4 id="📝srfshortest-remaining-time-first">📝SRF(Shortest Remaining Time First)</h4>
<p>실행 시간이 짧은 프로세스 부터 수행하는데
수행 도중 더 짧은 프로세스가 들어오면 현재 프로세스를 중지 후
실행 시간이 더 짤은 프로세스를 수행하는 알고리즘</p>
<h4 id="📝다단계-큐">📝다단계 큐</h4>
<p>프로세스들을 그룹화해서 그룹마다 큐를 두는 방식</p>
<p>어떤 큐를 먼저 실행시킬지와
각 큐들을 어떤 순서로 실행시킬지 정해야합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTTP 메소드]]></title>
            <link>https://velog.io/@jeonsangmin_/HTTP-%EB%A9%94%EC%86%8C%EB%93%9C</link>
            <guid>https://velog.io/@jeonsangmin_/HTTP-%EB%A9%94%EC%86%8C%EB%93%9C</guid>
            <pubDate>Thu, 01 Aug 2024 17:22:10 GMT</pubDate>
            <description><![CDATA[<div style="font-size:14px">
웹서버에 어떤 동작을 요청할때 자바스크립트로는
async/await 문법과 fetch API를 사용하여 HTTP 요청을 했고
HTTP 메소드를 지정하여 어떤 작업을 요청할지 정할 수 있다.
</div>

<pre><code>async function fetchData() {
  try {
    const response = await fetch(&#39;https://api.example.com/data&#39;, {
      method: &#39;POST&#39;, // POST 메소드 사용
      headers: {
        &#39;Content-Type&#39;: &#39;application/json&#39;
      },
      body: JSON.stringify({
        name: &#39;홍길동&#39;,
        age: 30
      })
    });

    if (!response.ok) {
      throw new Error(&#39;Network response was not ok&#39;);
    }

    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(&#39;There has been a problem with your fetch operation:&#39;, error);
  }
}

fetchData();</code></pre><div style="font-size:14px">
위 코드는 POST 메소드를 사용한 예시이며
POST 이외에도 중요하고 다양한 메소드들이 있다 
</div>

<h3 id="📌http-메소드method란">📌HTTP 메소드(Method)란?</h3>
<p>HTTP 메소드는 클라이언트가 웹 서버에게 어떤 종류의 동작을 원하는지를 나타내는 방법이다.
각 메소드는 특정한 종류의 작업을 수행하도록 설계되었다.</p>
<h3 id="📌주요-http-메소드">📌주요 HTTP 메소드</h3>
<h4 id="📑get">📑GET</h4>
<p>서버에게 정보를 요청
쿼리 파라미터를 통해 정보 필터링 가능
캐싱이 가능하며, 안전한 메소드
예시) 웹 페이지 조회, 이미지 다운로드</p>
<pre><code>💡캐싱(Caching)
자주 사용되는 데이터를 미리 저장해두었다가, 다시 필요할 때 빠르게 가져다 쓰는 기술</code></pre><h4 id="📑post">📑POST</h4>
<p>서버에 새로운 데이터를 제출
데이터는 요청 본문(request body)에 포함된다
캐싱이 불가능하며, 안전하지 않은 메소드(상태를 변경하기 때문)
예시) 회원 가입, 게시글 작성, 파일 업로드</p>
<h4 id="📑put">📑PUT</h4>
<p>특정 URL에 대응하는 리소스 전체 내용을 갱신(Update)하는데 사용
요청 본문에 새로운 데이터를 표함하여 기존 정보를 완전히 대체한다
캐싱이 불가능, 안전하지 않은 메소드
예시) 문서 수정</p>
<h4 id="📑delete">📑DELETE</h4>
<p>특정 리소스를 삭제한다
캐싱이 불가능, 안전하지 않은 메소드
예시) 게시글 삭제</p>
<h4 id="📑patch">📑PATCH</h4>
<p>특정 리소스의 일부를 수정
PUT메소드는 리소스 전체를, PATCH메소드는 리소스 부분적으로 수정
캐싱이 불가능, 안전하지 않은 메소드
예시) 프로필 사진 변경</p>
<h3 id="📌추가적인-메소드">📌추가적인 메소드</h3>
<ul>
<li>HEAD : GET 메소드와 비슷하지만, 응답 본문 대신 헤더만 반환.</li>
<li>OPTIONS : 서버가 지원하는 HTTP 메소드를 확인하는 메소드</li>
<li>CONNECT : HTTP 프로토콜을 통해 TCP 터널을 생성</li>
<li>TRACE : 요청 메세지를 그대로 서버로 보내고, 서버는 받은 메세지를 그대로 클라이언트로 반환</li>
</ul>
<h3 id="⚡결론">⚡결론</h3>
<p>HTTP 메소드는 웹 개발에서 중요한 개념이다.
서버에게 원하는 리소스를 요청, 추가, 수정, 삭제 등을 할 수 있기에
메소드들의 특징과 용도를 이해하고 적절히 사용하도록 하자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[렉시컬 스코프(Lexical scope)]]></title>
            <link>https://velog.io/@jeonsangmin_/%EB%A0%89%EC%8B%9C%EC%BB%AC-%EC%8A%A4%EC%BD%94%ED%94%84Lexical-scope</link>
            <guid>https://velog.io/@jeonsangmin_/%EB%A0%89%EC%8B%9C%EC%BB%AC-%EC%8A%A4%EC%BD%94%ED%94%84Lexical-scope</guid>
            <pubDate>Thu, 01 Aug 2024 16:30:48 GMT</pubDate>
            <description><![CDATA[<div style="font-size:15px">
  클로져를 배우기전 알아야할 개념!
  렉시컬 스코프를 알아보자 

<p>  (아직 클로져를 하나도 모르지만..오히려 좋은건가?)</p>
<p>  렉시컬 스코프를 직역하면 어휘 범위?라고 되는데
  감이 잘 오지 않는다.
  정적 스코프라고도 한다. 왜 정적 스코프지..?</p>
</div>

<h2 id="📌렉시컬-스코프란">📌렉시컬 스코프란</h2>
<p>함수가 선언된 위치에 따라 상위 스코프가 결정되는 것을 말한다.
쉽게 말해, 함수가 어디서 쓰여졌는지에 따라 어떤 변수에 접근할 수 있는지가 결정된다는 의미.</p>
<p>간단히 퀴즈를 통해 알아보자</p>
<pre><code>const x = 1;

function foo() {
  const x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // 출력값은 ?
bar(); // 출력값은 ?</code></pre><p>함수 foo와 함수 bar를 출력값은 어떻게 될 것인가?
위 퀴즈의 핵심 질문은 함수를 호출 위치 또는 선언 위치 중 어느것이 스코프를 결정하냐는 것이다.</p>
<p> ✔ <strong>함수를 어디서 호출했는가? -&gt; 동적 스코프</strong>
 ✔ <strong>함수를 어디서 정의했는가? -&gt; 정적 스코프(렉시컬 스코프)</strong></p>
<p>자바스크립트는 렉시컬 스코프를 따르므로 함수를 어디서 정의했는가에 스코프를 결정한다.
두 출력값 모두 1로 출력된다.</p>
<hr>
<p>아래 추가 예시를 봐보자.</p>
<pre><code>function outer() {
  let outerVar = &#39;외부 변수&#39;;

  function inner() {
    let innerVar = &#39;내부 변수&#39;;
    console.log(outerVar); // 외부 변수에 접근 가능
    console.log(innerVar);
  }

  inner();
}

outer();</code></pre><h3 id="📖렉시컬-스코프-관점에서-본다면">📖렉시컬 스코프 관점에서 본다면</h3>
<p>inner 함수는 outer 함수 내부에 선언되었으므로,
outer 함수의 변수인 outerVar에 접근할 수 있습니다.</p>
<p>반대로, outer 함수는 inner 함수의 변수인 innerVar에 접근할 수 없습니다.</p>
<h3 id="📖블록-스코프-관점에서-본다면">📖블록 스코프 관점에서 본다면</h3>
<p>outerVar와 innerVar는 각각 let 키워드로 선언되었으므로, 블록 스코프를 가진다
outerVar는 outer 함수의 블록 내에서만 유효.
innerVar는 inner 함수의 블록 내에서만 유효.</p>
<blockquote>
<p>💡<strong>렉시컬 스코프와 블록 스코프의 차이</strong>
블록 스코프 : let 과 const 키워드로 선언된 변수는 코드블록({}) 내에서만 유효
렉시컬 스코프 : 함수의 선언 위치에 따라 스코프가 결정</p>
</blockquote>
<h2 id="📌렉시컬-스코프-핵심">📌렉시컬 스코프 핵심</h2>
<ul>
<li>함수의 선언 위치가 스코프를 결정</li>
<li>내부 함수는 외부 함수의 변수에 접근 가능</li>
<li>외부 함수는 내부 함수의 변수에 접근 불가능
(*자바스크립트 엔진이 스코프체인을 통해 변수를 찾기 때문에)</li>
</ul>
<h2 id="📌정리">📌정리</h2>
<p>렉시컬 스코프는 자바스크립트에서 변수의 유효범위를 결정하는 중요한 개념.
함수가 선언된 위치에 따라 어떤 변수에 접근할 수 있는지 정해지며,
이를 이해하면 더욱 효율적이고 안정적인 자바스크립트 코드를 작성할 수 있다.</p>
<hr>
<div style="font-size:70%">
추가로..
모든 함수는 렉시컬 스코프를 가지며
특히 '클로저'는 렉시컬 스코프를 기반으로하여, 외부 함수의 변수를 기억하고 외부 함수가 끝난 후에도 그 변수에 접근할 수 있는 함수를 의미.

<p>장점에는 데이터 은닉(외부에서 접근할 수 없는 변수 생성), 상태 유지(다양한 패턴 구현 가능), 모듈 패턴(코드의 모듈화) 등 있으며</p>
<p>예시로는 모듈 패턴, 이벤트 핸들러, 콜백 함수, 커링 등이 있다</p>
<p>클로저는 추후 자세히 다뤄보도록 하자😅</p>
</div>]]></description>
        </item>
        <item>
            <title><![CDATA[2.3 네트워크 기기]]></title>
            <link>https://velog.io/@jeonsangmin_/2.3-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EA%B8%B0</link>
            <guid>https://velog.io/@jeonsangmin_/2.3-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EA%B8%B0%EA%B8%B0</guid>
            <pubDate>Sat, 27 Jul 2024 08:35:14 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-네트워크-기기의-처리-범위">📌 네트워크 기기의 처리 범위</h2>
<p>네트워크 기기는 계층별로 처리 범위를 나눌 수 있습니다.
<img src="https://velog.velcdn.com/images/euisuk-chung/post/f0f32d9b-3285-4d4b-aaf4-b717b7c4e8e5/image.png" alt="계층 모델"></p>
<p>계층 별 사용되는 기기는 아래와 같이 나눌 수 있습니다.</p>
<pre><code>- 애플리케이션 계층 : L7 스위치
- 전송 계층 : L4 스위치
- 인터넷 계층 : L3 스위치, 라우터
- 데이터 링크 계층 : L2 스위치, 브리지, NIC
- 물리 계층 : 허브, 리피터, AP</code></pre><p>상위 계층을 처리하는 기기는 하위 계층을 처리할 수 있지만 그 반대는 불가합니다.</p>
<p>💡<strong>스위치란</strong> 
스위치는 여러 장비를 연결하고 데이터 통신을 중재하며 목적지가 연결된 포트로만 전기 신호를 보내 
데이터를 전송하는 통신 네트워크 장비</p>
<h2 id="📌-데이터-이동의-개략도">📌 데이터 이동의 개략도</h2>
<p><img src="https://blog.kakaocdn.net/dn/b2IZ2f/btqMNwL96LX/CwHP2NuLE8TWBrELIoDzNk/img.png" alt=""></p>
<h2 id="span-stylecolorgreen📌-애플리케이션-계층을-처리하는-기기span"><span style="color:green">📌 애플리케이션 계층을 처리하는 기기</span></h2>
<pre><code>[7 계층]
애플리케이션 기반 트래픽 관리 및 로드 밸런싱</code></pre><h4 id="📖-l7-스위치">📖 L7 스위치</h4>
<ul>
<li><p>트래픽 관리: 웹사이트를 운영하는 서버가 여러 대 있을 때, 어떤 서버가 어떤 요청을 처리할지 결정합니다. 사용자의 요청을 여러 서버에 분산시켜서 웹사이트가 빨리 로드되도록 합니다.</p>
<ul>
<li><p>보안 강화: 악성 트래픽을 차단하거나 웹 애플리케이션 방화벽을 통해 웹사이트를 보호합니다.</p>
</li>
<li><p>애플리케이션 최적화: 웹사이트나 앱의 성능을 개선하는 데 도움을 주고 데이터 전송을 효율적으로 처리합니다.</p>
</li>
</ul>
</li>
</ul>
<p>💡로드 밸런싱은 네트워크 트래픽을 여러 서버나 경로로 분산하여 효율성과 신뢰성을 향상시키는 기술</p>
<h2 id="span-stylecolorgreen📌-전송-계층을-처리하는-기기span"><span style="color:green">📌 전송 계층을 처리하는 기기</span></h2>
<pre><code>[4 계층]
 포트 번호 기반 트래픽 관리</code></pre><h4 id="📖-l4-스위치">📖 L4 스위치</h4>
<p>전송 계층에서 작동하며, TCP/UDP 포트 번호를 기반으로 트래픽을 관리하고 로드 밸런싱을 수행합니다. 
데이터 트래픽을 더 효율적으로 분산시키기 위해 사용됩니다.</p>
<p>※ L7 L4 스위치 차이점
L7 스위치가 더 많은 정보로 (URL 경로, 쿠키 값 등) 세분화 된 트래픽 관리 가능</p>
<p>※ L7 L4 스위치 공통점
헬스 체크 (정상, 비정상 서버 판별)
L7 스위치 - 애플리케이션 레벨에서 HTTP 응답 상태나 콘텐츠를 확인하여 헬스 체크를 수행합니다. 
L4 스위치 - TCP 핸드셰이크나 UDP 응답 여부를 확인하여 헬스 체크를 수행합니다.</p>
<h2 id="span-stylecolorgreen📌-인터넷-계층을-처리하는-기기span"><span style="color:green">📌 인터넷 계층을 처리하는 기기</span></h2>
<pre><code>[3 계층]
IP 주소 기반 데이터 라우팅</code></pre><h4 id="📖-l3-스위치">📖 L3 스위치</h4>
<p>주로 대규모 LAN 환경에서 사용되며, IP 주소를 기반으로 트래픽을 전달하고 라우팅합니다.</p>
<p>L3 스위치 = L2 스위치 + 라우팅 기능</p>
<h4 id="📖-라우터-router">📖 라우터 (router)</h4>
<p>여러 개의 네트워크를 연결, 분할, 구분시켜주는 역할</p>
<p>라우터는 IP 주소를 기반으로 네트워크 간의 트래픽을 라우팅합니다.</p>
<p>※ L3 스위치 / 라우터 차이점
주요 기능 : 스위칭 + 라우팅 / 라우팅
사용 환경 : LAN / WAN
라우팅 복잡도 : 상대적으로 간단 / 복잡</p>
<p>💡라우팅이란
다른 네트워크에 존재하는 장치끼리 서로 데이터를 주고받을 때 패킷 소모를 최소화하고 
경로를 최적화하여 최소 경로로 패킷을 포워딩</p>
<p><img src="https://velog.velcdn.com/images/jeonsangmin_/post/bef8b275-2dda-4a4c-8e30-d1b2fe6fa61f/image.jpg" alt=""></p>
<h2 id="span-stylecolorgreen📌-데이터-링크-계층을-처리하는-기기span"><span style="color:green">📌 데이터 링크 계층을 처리하는 기기</span></h2>
<pre><code>[2 계층]
- 맥(MAC) 주소를 가지고 통신 (MAC 주소를 읽고 송신자, 수신자를 판단 할 수 있음)
- 네트워크의 물리적 연결을 통해 데이터 프레임의 전송과 오류 감지를 관리합니다. </code></pre><h4 id="📖-l2-스위치">📖 L2 스위치</h4>
<p>데이터 링크 계층에서 가장 일반적으로 사용되는 장비입니다. 
스위치는 MAC 주소를 기반으로 데이터 프레임을 포워딩합니다.</p>
<p>-IP 주소를 이해하지 못해 IP 주소를 기반으로 라우팅은 불가능
-단순히 패킷의 MAC 주소를 읽어 스위칭하는 역할
-목적지가 MAC 주소 테이블에 없다면 전체 포트에 전달
-MAC 주소 테이블의 주소는 일정 시간 이후 삭제하는 기능 있음</p>
<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzatOq%2FbtrPQxaMbVW%2FoKvKHb0aUJ8k9J8kKF1AWK%2Fimg.png" alt="L2 스위치"></p>
<h4 id="📖-브리지-bridge">📖 브리지 (bridge)</h4>
<p>LAN 연결: 두 개의 근거리 통신망(LAN)을 상호 접속할 수 있도록 하는 통신망 연결 장치
충돌 방지: 각 LAN의 트래픽을 분리하여 충돌 발생 가능성을 줄입니다.
MAC 학습: 연결된 장치들의 MAC 주소를 학습하여, 목적지 MAC 주소에 맞는 세그먼트로만 프레임을 전달합니다.</p>
<h4 id="📖-nic-network-interface-card--lan-카드">📖 NIC (Network InterFace Card) = LAN 카드</h4>
<p>컴퓨터와 네트워크 연결: 컴퓨터를 네트워크에 연결해주는 하드웨어 장치입니다.
데이터 전송: 컴퓨터 내부의 데이터를 네트워크로 보내고, 네트워크에서 받은 데이터를 컴퓨터로 가져옵니다.
MAC 주소: 각 NIC는 고유한 MAC 주소를 가지고 있어 네트워크 상에서 다른 장치와 구분됩니다.</p>
<h2 id="span-stylecolorgreen📌-물리-계층을-처리하는-기기-span"><span style="color:green">📌 물리 계층을 처리하는 기기 </span></h2>
<pre><code>[1 계층]
역할 : 비트형태의 신호(2진수)와 전기적 신호를 서로 변환하는 역할</code></pre><h4 id="📖-리피터--허브">📖 리피터 &amp; 허브</h4>
<p>들어오는 약해진 신호 정도를 <strong>증폭</strong>하여 다른 쪽으로 전달하는 장치
이를 통해 패킷이 더 멀리 갈 수 있다</p>
<p>-리피터
 Port의 개수 : 2개
 한쪽 Port로 전달받은 신호를 재생 시켜 반대쪽 포트로 전달 함</p>
<p>-허브
 Port의 개수 : 여러개
 한쪽 Port로 전달바은 신호를 나머지 모든 포트로 전달 함
 신호를 <strong>복사, 증폭하여 플로딩</strong>(flooding, 제어되지 않고 나머지 모든 포트로 데이터가 흘러넘침)</p>
<p> 다수의 포트를 이용하여 장비의 연결을 집중시키는 집선 장비로 사용함
 *집선 장비 : 선을 집중해서 모아주는 장비</p>
<p> <img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUtEfC%2FbtrPRAklGGQ%2FLDraUdpb25RKHBrBmF71U1%2Fimg.png" alt="허브&amp;리피터"></p>
<p>하지만 현재는 L2 스위치와 광케이블이 보급됨에 따라 잘 쓰이지 않는 장치 (유물 급)</p>
<h4 id="📖-ap">📖 AP</h4>
<p>패킷을 복사하는 기기</p>
<p>AP에 유선 LAN을 연결한 후 다른 장치에서 무선 LAN 기술(와이파이 등)을 사용하여 무선 네트워크를 연결 할 수 있다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이벤트 주의!(feat. 캡쳐링, 버블링)]]></title>
            <link>https://velog.io/@jeonsangmin_/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%A3%BC%EC%9D%98feat.-%EC%BA%A1%EC%B3%90%EB%A7%81-%EB%B2%84%EB%B8%94%EB%A7%81</link>
            <guid>https://velog.io/@jeonsangmin_/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EC%A3%BC%EC%9D%98feat.-%EC%BA%A1%EC%B3%90%EB%A7%81-%EB%B2%84%EB%B8%94%EB%A7%81</guid>
            <pubDate>Fri, 26 Jul 2024 12:18:09 GMT</pubDate>
            <description><![CDATA[<pre><code>// html 구조

&lt;div id=&quot;ancestor&quot;&gt;
    &lt;div id=&quot;parent&quot;&gt;
           &lt;div id=&quot;child&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt; </code></pre><pre><code>// javascript 구조

ancestor.addEventListener(&quot;click&quot;, (e) =&gt; {
  console.log(&#39;ancestor clicked&#39;);
})

parent.addEventListener(&quot;click&quot;, (e) =&gt; {
  console.log(&#39;parent clicked&#39;);
})

child.addEventListener(&quot;click&quot;, (e) =&gt; {
  console.log(&#39;child clicked&#39;);
})</code></pre><p>위 코드를 작성하면 무슨일이 일어날까</p>
<ol>
<li><p>조상 요소 클릭 -&gt; 조상 요소 이벤트 발생</p>
</li>
<li><p>부모 요소 클릭 -&gt; 부모 요소 이벤트 발생 &amp; 조상 요소 이벤트 발생</p>
</li>
<li><p>자식 요소 클릭 -&gt; 자식 요소 이벤트 발생 &amp; 부모 요소 이벤트 발생 &amp; 조상 요소 이벤트 발생</p>
</li>
</ol>
<p>자식 요소만 이벤트 발생을 원했지만 부모, 조상 요소까지 이벤트가 발생했다.
이때 자식 요소를 &#39;타겟&#39; 요소라 하고
부모, 조상 요소까지 이벤트가 전파 된 것을 &#39;버블링&#39;이라고 한다.</p>
<p><em>단, 이벤트가 전파되는 조건은 같은 이벤트일 경우다</em></p>
<p><img src="https://velog.velcdn.com/images/mochafreddo/post/8656fcd2-a2f0-416d-99d7-0dbe4eb61b17/image.svg" alt="버블링">
위 그림처럼 타겟 요소부터 부모, 조상이어지면서 DOM구조의 최상단까지 버블링이 진행된다.</p>
<p>반대로 타겟 요소에 이벤트가 발생했을 때,
DOM구조의 시작 요소인 window부터 타겟 요소까지 이벤트가 전파되는 것을 &#39;캡처링&#39;이라 한다.</p>
<p>다만 캡처링은 실무에서 크게 쓰이지는 않지만 발생했을 때의 원인을 알아야하기 때문에 알고는 있어야한다.</p>
<p>이벤트 코드를 보면 핸들링, 핸들러, 캡처링 사용 유무 순으로 인자값을 가진다.</p>
<pre><code>element.addEventListener(&#39;click&#39;, (e) =&gt; { ... }, true);
element.addEventListener(&#39;click&#39;, (e) =&gt; { ... }, {capture: true});</code></pre><p>이벤트 코드의 3번째 인자값은 선택이며, 없을 시 캡처링은 false 값을 버블링은 true 값을 가진다.
즉, 버블링은 디폴트 값으로 항상 진행 된다고 보면 된다.</p>
<p>만약 버블링을 막고 싶다면 이벤트 코드 마지막에 멈추는 코드를 추가적으로 작성하면 된다.
하지만 버블링이 막힌 타겟 요소는 부모 이상의 요소에서 추가적인 다른 이벤트를 발생하고 싶을 때
영역이 잡히지 않으니 추천하지 않는다.</p>
<pre><code>element.addEventListener(&quot;click&quot;, (e) =&gt; {
  //동작 코드
  e.stopPropagation() // 이벤트 전파 방지
})</code></pre><p>버블링이나 캡처링을 막기 위해서는 코드를 작성할 때 미리 설계를 잘해야 한다.
실제로 버블링이 쉽게 생기지는 않는다.</p>
<p>반대로 버블링이 필요한 경우도 있다.</p>
<p>예를 들면 리스트와 세부사항이 있을 때, 세부 사항 각각에 이벤트를 작성하기에는 중복되는 코드가 많아지기 때문에 부모 요소인 리스트에 이벤트를 위임 시켜 하나의 이벤트로 세부 사항 모두에게 이벤트를 동작하게 만들 수 있다.</p>
<pre><code>list.addEventListener(&#39;click&#39;, function(e) {
    if (e.target.classList.contains(&#39;item&#39;)) {
        e.target.classList.toggle(&#39;done&#39;);
    }
});</code></pre><p>위임을 했을 때 리스트를 선택하게 되면 전체 영역의 이벤트가 발생하기 때문에 조건문을 통해
세부 사항 요소만 작동하게 만들어 줘야 한다.</p>
<p>이벤트 위임의 장점은 코드를 줄일 수 있고, 성능 또한 좋아진다는 점이다.</p>
<h3 id="요약">요약</h3>
<blockquote>
<ol>
<li>이벤트 발생 시, 상위로 올라가면서 같은 이벤트가 전파된다 (버블링)</li>
<li>반대의 경우, 최상단 window부터 타겟까지 이벤트가 발생한다 (캡처링)</li>
<li>이를 통해 이벤트 위임이 가능하다.</li>
</ol>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>