<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>tiger_front_end.log</title>
        <link>https://velog.io/</link>
        <description>ui/ux에 중점을 두고 고객의 니즈를 기술적으로 해결하는것을 좋아하는 개발자입니다</description>
        <lastBuildDate>Sat, 24 Feb 2024 13:44:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>tiger_front_end.log</title>
            <url>https://velog.velcdn.com/images/tiger_front_end/profile/823fbe45-ceaa-43bb-88c4-b4adeb3c5882/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. tiger_front_end.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/tiger_front_end" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Mutable or Immutable 프로그래밍]]></title>
            <link>https://velog.io/@tiger_front_end/Mutable-or-Immutable-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@tiger_front_end/Mutable-or-Immutable-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Sat, 24 Feb 2024 13:44:48 GMT</pubDate>
            <description><![CDATA[<h4 id="immutable과-mutable-개발자들의-선택">Immutable과 Mutable: 개발자들의 선택</h4>
<p>뮤터블과 이뮤터블 프로그래밍 방식은 개발자들 사이에서 논쟁의 여지가 있는 주제 중 하나입니다. 어떤 방식이 더 좋다고 일반화할 수는 없지만, 개인적인 의도가 중요하다.</p>
<p>개인적으로 Immutable한 코드를 선호하는편이다. 처음에는 Mutable한 방식이 편리해 보였지만, 코드가 길어지고 새로운 기능이 추가되며 종속성이 복잡해질수록 원본 데이터를 직접 수정하는 것이 오류를 발생시킬 수 있다는 것을 깨달았는데 작은 프로젝트에서는 Mutable한 코드가 더 편리할 수 있지만, 대규모 프로젝트나 다수의 개발자가 협업하는 경우에는 Immutable한 프로그래밍이 더 많은 장점을 가질 수 있다고 생각한다. 상태 변화를 추적하기 쉽고 예측 가능하며, 함수형 프로그래밍과도 잘 어울리는데, 그래서 더 선호하는 편이다.</p>
<p>프로그래밍을 처음 배울 때는 뮤터블과 이뮤터블의 차이를 몰랐지만, 최근에 이 부분에 대해 상당히 꽃혀있고 이 방법이 안정적이고 유연하며 오류를 줄일 수 있는 방법이라고 확신하고있다. 프로그래밍은 공부할 것이 많지만, 더 나은 코드와 client를 위해 노력하며, 좋은 환경을 만들기 위해 노력할것같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript - 호이스팅(Hoisting)]]></title>
            <link>https://velog.io/@tiger_front_end/Javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85Hoisting</link>
            <guid>https://velog.io/@tiger_front_end/Javascript-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85Hoisting</guid>
            <pubDate>Tue, 20 Feb 2024 14:03:32 GMT</pubDate>
            <description><![CDATA[<h4 id="호이스팅이란-무엇인지-이해해보자">호이스팅이란 무엇인지 이해해보자</h4>
<p>호이스팅이란 자바스크립트의 특징중 하나이고 자바스크립트에서 호이스팅은 변수 및 함수 선언이 코드 실행 전에 메모리에 끌어올려지는 현상을 설명한다. 다들 설명을 전문용어를 쓰며 복잡하게 설명하는데 정말 간단하다 코드를 예로 보자</p>
<pre><code>console.log(x); // undefined
let x = 5;
</code></pre><p>위의 코드에서 var x = 5;라는 선언은 실제로 코드 내에서 그 위치에 있지만, 자바스크립트 엔진은 이를 변수를 선언한 위치의 맨 위로 끌어올려 호이스팅합니다 변수가 있는것으로 확인되지만 
콘솔이 변수지정전에 실행되어 x의 값이 초기화 된것입니다. 아주쉽죠?</p>
<p>함수도 같습니다 </p>
<pre><code>foo(); // &quot;Hello, world!&quot;

function foo() {
  console.log(&quot;Hello, world!&quot;);
}
</code></pre><p>위의 코드에서 foo() 함수 호출은 선언된 위치보다 앞서 있지만, 함수 선언 자체가 호이스팅되어 최상단으로 끌어올려지므로 호출이 가능합니다. 어떻게보면 족보없는 언어같이 보이지만 편리하다고 막쓰면 코드의 가독성이 나빠지고 예측 가능성에 영향을 미칠수 있어서 이러한 동작을 이해하고 코드를 작성하는것이 좋습니다.</p>
<p>그리고 개인적으로는 var보다 let/const를 선호하는편인데 var는 중복해서 선언하는것이 가능해서 이로 인해 변수 중복 선언으로 인한 예기치 못한 동작을 할수있기 때문입니다. 이러한 특징은 var가 함수 스코프를 가지고 있기 때문에 발생합니다 ES6(ES2015)부터는 let과 const 키워드가 추가되었는데, 이들은 블록 스코프를 가지고 있어 중복 선언을 허용하지 않습니다. 이로 인해 변수 중복 선언으로 인한 예기치 못한 동작을 방지할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[virtual DOM 동작과 원리]]></title>
            <link>https://velog.io/@tiger_front_end/virtual-DOM-%EB%8F%99%EC%9E%91%EA%B3%BC-%EC%9B%90%EB%A6%AC</link>
            <guid>https://velog.io/@tiger_front_end/virtual-DOM-%EB%8F%99%EC%9E%91%EA%B3%BC-%EC%9B%90%EB%A6%AC</guid>
            <pubDate>Mon, 12 Feb 2024 12:22:29 GMT</pubDate>
            <description><![CDATA[<p>프론트엔드 개발에서는 일반적으로 직접적인 DOM 조작을 피하는 것이 권장됩니다. 그 이유를 이해하기 위해서는 DOM(Document Object Model)에 대한 이해가 필요합니다. DOM은 문서의 구조를 표현하는 트리 모델로, HTML 문서의 요소(element)들을 표현합니다.</p>
<p>직접적인 DOM 조작은 다음과 같은 이유로 지양되어야 합니다.</p>
<p>성능 문제: DOM 조작은 브라우저의 레이아웃 계산과 리페인트를 유발할 수 있습니다. 특히 대규모 애플리케이션에서는 이러한 작업이 성능에 부담을 줄 수 있습니다.</p>
<p>유지보수의 어려움: 직접 DOM을 조작하는 코드는 복잡하고 이해하기 어려울 수 있습니다. 또한 DOM 구조가 변경될 때마다 코드도 변경되어야 하므로 유지보수가 어려워집니다.</p>
<p>크로스 브라우징 문제: 각 브라우저는 DOM 조작에 대해 서로 다른 방식을 지원할 수 있습니다. 이로 인해 크로스 브라우징 이슈가 발생할 수 있습니다.</p>
<p>보안 취약점: 사용자 입력에 따라 동적으로 DOM을 조작하는 경우 XSS(Cross-Site Scripting) 공격에 취약해질 수 있습니다.</p>
<p>따라서, 현대의 프론트엔드 개발에서는 상태(state)와 뷰(view)를 분리하여 상태 관리 라이브러리 또는 프레임워크를 사용하여 상태를 관리하고, 이를 통해 자동으로 DOM을 업데이트하는 방식을 선호합니다. 이러한 방식은 성능을 최적화하고 유지보수성을 높이며, 보안 문제를 방지하는 데 도움이 됩니다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/e906d7ad-f3db-4119-8a3b-2ddac5aea7de/image.gif" alt=""></p>
<p>과거에는 SPA 프레임워크가 흔하지 않았으며, 대부분의 웹 애플리케이션은 서버 측 렌더링(SSR)을 사용하여 HTML을 동적으로 생성하여 브라우저에 전달했습니다. 그래서 클라이언트 측에서는 DOM 조작보다는 HTML을 다시 로드하는 것이 일반적이었습니다.</p>
<p>이전에는 jQuery가 많이 사용되었습니다. jQuery는 DOM 조작을 단순화하고 편리하게 만들어 주었기 때문에 개발자들이 DOM 조작을 더 쉽게 할 수 있었습니다. 그래서 많은 퍼블리셔들이 jQuery를 즐겨 사용했던 것 같습니다.</p>
<p>그러나 jQuery를 사용하면서도 DOM 조작이 성능에 부정적인 영향을 미치는 것을 인지하지 못한 경우가 많았습니다. 실제로 DOM을 조작하면 브라우저가 레이아웃을 다시 계산하고 리페인트를 수행해야 하므로 성능이 저하될 수 있습니다. 특히 요소의 스타일이 변경될 때마다 브라우저는 레이아웃을 다시 계산하고 리페인트를 수행해야 하므로 이러한 작업은 브라우저에 부하를 줄 수 있고 성능 저하로 이어질 수 있습니다.</p>
<p>이러한 이유로 SPA 프레임워크가 등장하면서 가상 DOM을 사용하여 성능을 최적화하고 DOM 조작을 최소화하는 것이 중요해졌습니다. 가상 DOM은 상태 변경 시 변경된 부분만을 실제 DOM에 반영하여 성능을 최적화하는 방법으로, 이를 통해 전체적인 웹 애플리케이션의 성능과 사용자 경험을 향상시킵니다. 이를 통해 개발자들은 DOM 조작을 직접 처리하는 것보다 더욱 효율적으로 웹 애플리케이션을 개발할 수 있게 되었습니다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/313681f3-8afa-4024-b80a-018a0fbe5efb/image.webp" alt=""></p>
<p>SPA 프레임워크에서 사용되는 가상 DOM은 메모리에 저장되며, 상태가 변경되면 이전 가상 DOM과 현재 가상 DOM을 비교하여 변경된 부분만을 찾아 실제 DOM에 반영합니다. 이를 통해 DOM 조작으로 인한 성능 문제를 효과적으로 해결하고, 유지보수성과 개발 효율성을 향상시킵니다. 따라서, 매번 전체 렌더링을 다시 수행할 필요가 없어지는 것이죠. 이는 작은 변경 사항이 있더라도 처음부터 모든 요소를 다시 렌더링할 필요가 없게 됨을 의미합니다. 이렇게 함으로써, DOM 조작을 최소화하고 프레임워크가 가상 DOM을 관리하도록 함으로써 성능을 최적화할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS-EC2 nodejs express server연동하기]]></title>
            <link>https://velog.io/@tiger_front_end/AWS-EC2-nodejs-express-server%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tiger_front_end/AWS-EC2-nodejs-express-server%EC%97%B0%EB%8F%99%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 02 Feb 2024 02:11:42 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/46c46e53-2ff7-4cfd-82e6-0690e6fb1e1f/image.png" alt=""></p>
<h4 id="aws란">AWS란?</h4>
<p>AWS(Amazon Web Service)라고 하는 클라우드 서비스를 이용해 서버컴퓨터를 대여해서 사용할수있다.
이번 포스팅에서는 EC2서버를 생성해서 내 개인 프로젝트와 연동하는것까지 설정해보려고한다.</p>
<h4 id="1-aws-회원가입">1. AWS 회원가입</h4>
<p><a href="https://aws.amazon.com/ko/">https://aws.amazon.com/ko/</a> 회원가입을 먼저해준다.
회원가입할때 필요한건 신용카드가 필요하다.
첫가입시 프리티어(무료)혜택으로 1년간 일부서비스를 이용할수있다.
프리티어 조건을 벗어나게되면 요금이 청구되게 될것이니 주의하자.</p>
<h4 id="2-ec2-인스턴스-생성">2. EC2 인스턴스 생성</h4>
<p>EC2는 원격으로 연결할수있는 컴퓨터를 대여할수있다고 설명했다<br>(프리 티어에서 1대의 컴퓨터로 월 750시간까지 무료로 사용할 수 있다.)</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/4bcaf278-b5f5-4b20-ba0d-af9cab0c0bfa/image.png" alt=""></p>
<ol>
<li>리전을 서울로 선택해준다.</li>
<li>AWS 사이트 상단에 있는 검색창에서 EC2를 검색한다.</li>
<li>EC2 대시보드에 먼저 들어간다.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/15a313b9-17f7-406c-8c61-b797d37277d7/image.png" alt=""></p>
<p>인스턴스 시작을 눌러준다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/4b7b7c8c-035e-42f4-a68b-a2b354b08f05/image.png" alt=""></p>
<p>이런 화면이 나올것이다. 이름은 본인이 지어주고싶은 이름으로 지어준다.
그리고 내가 빌릴 컴퓨터의 운영체제를 고른다 보통 ubuntu로 많이들하지만
찾아보니 red hat이 주로 기업에서 중요한 워크로드와 애플리케이션을 지원하는 서버 운영체제로 사용 된다길래 본인은 red hat으로 진행했다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/5553d44c-b637-4645-8a0c-13f60689282d/image.png" alt=""></p>
<p>성능 사양을 선택한다. 프리 티어에서는 t2.micro만 사용가능하므로 이를 선택하고 세부 정보 구성을 선택한다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/54572956-019d-455f-8266-b7304582459c/image.png" alt=""></p>
<p>그리고 바로 아래에 키페어를 생성한다 이건 내 서버컴퓨터에 ssh로 접속할때 쓰는 인증키와 같다
공인인증서라고 생각하면 이해하기쉽다. (ssh는 우리 로컬컴퓨터에서 cmd로 컴퓨터에 명령을 내릴수있는것과 같다 서버에 원격으로 접속해서 명령을 내리는것이다.) pem키는 절대 유출되면 안된다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/9b396c49-516a-4676-8184-97eb20f74627/image.png" alt=""></p>
<p>키페어 이름은 간단하게 짓는게 좋다. 개인적으로 기억하기 편하거나 용도에 맞는 네이밍을 권장한다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/db8dd44a-61b7-42ef-99f5-f28bdf142a38/image.png" alt=""></p>
<p>그리고 보안그룹에서 Allow SSH traffic from 이것은 체크가 되어있을것이다
아래 http트래픽과 https트래픽은 체크가 되어있지 않을텐데 체크해준다.
웹 서버를 생성할 때 HTTPS 트래픽을 허용하는 것은 보안 및 개인정보 보호 측면에서 중요한 결정이다.</p>
<p>그리고 고급세부정보는 설정할게 없으니 PASS 인스턴스 시작을 눌러준다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/04923ae1-c9a2-43c1-9340-935352fe898c/image.png" alt=""></p>
<p>그럼 이렇게 쨘 하고 내 서버컴퓨터가 생기게 된것이다.
그럼 우리는 뭘해야할까 우리가 구축해놓은 server파일과 db를 연동시켜야하는일이 남았다.
db는 rds로 세팅했기때문에 다음포스팅에서 다루도록 하겠다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/a09aed9a-ea2a-4e52-8179-b90ffaaa64bc/image.png" alt=""></p>
<p>추가로 탄력적ip를 생성해서 연결시켜준다. 이것을 안하면 내 서버 컴퓨터의 ip가 바뀌기때문에
피곤해질수도있다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/8470faea-b936-4481-9d4a-51385099c935/image.png" alt=""></p>
<p>할당된 ip를 선택하고 작업 -&gt; 탄력적 ip 주소 연결을 선택한다.
인스턴스 목록에서 생성한 EC2 인스턴스를 선택하고 연결을 선택한다.
이렇게 설정하고나면 이제 서버컴퓨터의 ip가 고정된것이다.
그럼 서버컴퓨터에 ssh로 접속을 해보자</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/6afb44a3-f66e-493b-b65a-5caa46158f74/image.png" alt=""></p>
<p>여기서 연결을 눌러준다 </p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/f8d9ac01-323f-477c-9776-a2968c5c31ad/image.png" alt=""></p>
<p>그럼 이런 화면이 보일것이다 여기서 ssh클라이언트로 들어가면 내 로컬 cmd에서 접속할수있는 예가 나온다 저것을 복사해준다.그리고 아까 만들어뒀던 pem키 세팅후 
복사붙여넣고 접속해준다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/8003c2d9-d2b9-4ae0-941d-05b56456c1fe/image.png" alt=""></p>
<p>짠 연결이 되었는데 여기까지 잘 따라왔으면 이제 로컬에서 내가 서버를 테스팅한 환경을 서버컴퓨터에도 똑같이 만들어줘야한다. npm과 nodejs 설치후 버전 체크를하고 본인은 express로 서버를 만들었기때문에 설치해준다. 로컬에서 설치했던 익스텐션과 프레임워크를 다설치해줘야한다 그래야 
내가 테스팅했던 화면과 같이 나오기 때문이다. git도 같이 설치해주길 바란다.</p>
<p>깃클론을 통해 (본인은 백엔드파일을 깃허브에 올려놨다.) 서버컴퓨터에 내파일들을 다운로드 받고
실행시켜주도록하자</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/d7038f8d-e8d0-4752-94a4-8b4344912d43/image.png" alt=""></p>
<p>짜잔 그럼 서버컴퓨터에 내웹서버를 실행시킬수있게 된것이다.</p>
<p>다음포스팅에서는 rds로 mysql과 연동해서 내 db를 구성할수있게 해보자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[mysql 설치하기]]></title>
            <link>https://velog.io/@tiger_front_end/mysql-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tiger_front_end/mysql-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 23 Jan 2024 12:18:16 GMT</pubDate>
            <description><![CDATA[<p>데이터베이스 중에서 MySQL을</p>
<p>다운로드 및 설치하는 방법을 알아보려합니다.</p>
<h4 id="다운로드-link">다운로드 link</h4>
<p><a href="https://dev.mysql.com/downloads/installer/">https://dev.mysql.com/downloads/installer/</a></p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/e407cf64-67ee-4083-b137-19c256137e33/image.png" alt=""></p>
<p>Download 버튼을 클릭합니다.
다운로드한 installer를 실행하고</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/8ec54f32-4343-4d47-90b0-f966c02603c1/image.png" alt=""></p>
<p>설치유형목록입니다 저희는 custom으로 필요한부문만 설치하려고합니다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/1cd3888b-4b5b-4857-95d4-88cd6719e108/image.png" alt=""></p>
<p>[MySQL Servers] – [MySQL Server] – [MySQL Server 8.0] – [MySQL Server 8.0.33 – X64]</p>
<p>[Applications] – [MySQL Workbench] – [MySQL Workbench 8.0] – [MySQL Workbench 8.0.33 – X64]</p>
<p>[Documentation] – [Samples and Examples] – [Samples and Examples 8.0] – [Samples and Examples 8.0.33 – X86]</p>
<p>이렇게 추가하고 next를 눌러줍니다.
Installation 목록을 보면 추가한 항목을 확인가능합니다.
설치가 완료되면 Execute버튼이 next버튼으로 변경됩니다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/6202ac8a-8125-45f4-b4a3-bdc98de90e26/image.png" alt=""></p>
<p>기본상태가 이렇게 체크되어있고 port번호를 기억하는게 포인트입니다.
매우중요합니다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/64c0de5d-d052-4275-a9d1-a35cb131cae3/image.png" alt=""></p>
<p>Accounts and Roles 에서는 root(관리자)의 비밀번호를 설정해줍니다.
마음대로 만들어도좋지만 기억하기 좋은거로 하세요.
MySQL User Accounts에서 Root 외의 사용자를 추가할 수 있습니다.
쭉쭉 next 버튼으로 넘어가고 </p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/8120c8d0-f385-4ae0-a3b4-9f251d156655/image.png" alt=""></p>
<p>Connect To Server에 연결할 서버가 보이고 root가 입력되어있습니다.
비밀번호를 앞서 설정했던 것으로 입력하고 check버튼을 클릭하면
초록색바안에 Connection succeeded로 변경됩니다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/65ebcc68-c70e-4825-b2e9-350d86236c44/image.png" alt=""></p>
<p>Status를 보면 모두 완료된 것이 확인됩니다. next 버튼을 클릭합니다.
여기까지 진행이 되었다면,
MySQL DB서버가 설치 완료 된 상태입니다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/75cccb68-77ab-48c0-9479-1ae8b5b2b37f/image.png" alt=""></p>
<p>Workbench 는 MySQL 서버를 관리 및 사용을 편리하게 해주는 툴입니다.
다음 포스팅에서는 node.js와 연결시키는 부분을 다뤄보겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[data structures - recursion(재귀)]]></title>
            <link>https://velog.io/@tiger_front_end/data-structures-recursion%EC%9E%AC%EA%B7%80</link>
            <guid>https://velog.io/@tiger_front_end/data-structures-recursion%EC%9E%AC%EA%B7%80</guid>
            <pubDate>Mon, 22 Jan 2024 13:09:00 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>재귀함수에대해서</p>
</blockquote>
<p>재귀함수가 뭔데? 
재귀.. 프로그래밍 공부한지 시간이 좀지났지만 아직도 재귀를 쓰는게
어색하다 어색하다라고 해야할까 기본적인 팩토리얼함수나,피보나치 수열로 연습을
해보아도 다른부분에서 응용해서 만들려고하면 억소리와함께 손가락이 멈춘다 열심히 내머릿속으로
만들어보지만 vscode 디버그로 stack을 보면서 해도 아직도 쉽지않다
마치 재귀함수같다 그래서 재귀함수가 뭔데? 
자기 자신을 참조하는 함수이다(여기서 자기자신을 참조한다는것은) 함수내에서
한번더 본인을 호출한다는것이다 그래서 종료 조건을 잘생각해서 작성해야한다 아니면
stack overflow에 빠지게 된다 무한으로 호출해 메모리가 초과되는것이다.</p>
<p>간단하게 누적합을 구하는 재귀함수로 설명해보겠다</p>
<pre><code>function recursion(n){
    if(n === 1) return n 
    //n이 1일 경우, 1을 반환합니다. 이것은 재귀 호출의 종료 조건입니다.
    return n + recursion(n-1)
    // recursion함수안에서 자기자신을 호출하고 맨마지막 n이1과같을때 n을(값1) 반환해주면
    // 자료구조 stack과 같다 선입후출로 recursion(n-1) 이부분이 1이되는것이다 그럼 이전
    //함수에서 n과 합해 계속 값이 누적되게 된다.
}</code></pre><p>종료 조건 설정이 중요하고 재귀 함수는 무한 루프에 빠질 수 있기 때문에 항상 종료 조건을 설정을 고민해야한다.
스택 오버플로우(Stack Overflow) 주의: 재귀 호출이 너무 많이 발생하면 스택이 넘치는 문제가 발생할수있어서 이를 방지하기 위해 반복문이나 꼬리 재귀 최적화를 고려할수도 있다.
성능 고려: 재귀 함수의 성능은 반복문에 비해 부담이 있을 수 있는데 특히 깊은 재귀 호출이 많은 경우 성능에 영향을 줄 수 있다.</p>
<pre><code>// 팩토리얼 계산하는 재귀 함수
function factorial(n) {
  // 종료 조건: 0 또는 1일 때 1을 반환
  if (n === 0 || n === 1) {
    return 1;
  } else {
    // 재귀 호출: n! = n * (n-1)!
    return n * factorial(n - 1);
  }
}

// 예시: 5! 계산
let result = factorial(5);
console.log(result); // 출력: 120
</code></pre><p>설명을 아무리 잘해도 직접 꼭 디버깅해서 stack부분을 확인하여 어떻게 호출되는지
꼭 확인해야한다 재귀함수로 구현할수있는것은 반복문으로 만들수도있다 허나 다뤄야하는
값이 크지않을때 간결하고 가독성이좋게 쓸수있어서 좋다 (또한 간지난다)</p>
<p>dfs에서 재귀함수로 구동하는 부분이 많기때문에 꼭 알고 넘어가야하는 부분이기도하다.
허나 아직도 쉽지않다 절망의 계곡(Valley of Despair)에 빠졌다가, 깨달음의 언덕(Slope of Englightenment)를 지나는중인것같지만 아직 시원찮다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2024 카카오 채용 연계형 겨울 인턴십 코딩테스트 2번 - 문제풀이]]></title>
            <link>https://velog.io/@tiger_front_end/2024-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EC%B1%84%EC%9A%A9-%EC%97%B0%EA%B3%84%ED%98%95-%EA%B2%A8%EC%9A%B8-%EC%9D%B8%ED%84%B4%EC%8B%AD-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-2%EB%B2%88-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
            <guid>https://velog.io/@tiger_front_end/2024-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EC%B1%84%EC%9A%A9-%EC%97%B0%EA%B3%84%ED%98%95-%EA%B2%A8%EC%9A%B8-%EC%9D%B8%ED%84%B4%EC%8B%AD-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-2%EB%B2%88-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</guid>
            <pubDate>Thu, 18 Jan 2024 10:48:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>도넛과 막대 그래프</p>
</blockquote>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/258711">https://school.programmers.co.kr/learn/courses/30/lessons/258711</a></p>
<p>루트노드번호,도넛그래프갯수,막대그래프갯수,8자그래프갯수를 반환해줘야하는 문제였다.
 막대그래프부분 이해하는데만 한참걸렸다 실제 코테에서는 이문제를 풀다가 시간을 다써서 끝이났다.
 지문이 길어지니 참 이해하기 어려웠는데 루트노드를 찾는 조건은 들어오는 간선은 없고 나가는 간선만 2개이상이면서 최대 간선을 보유하고 있는 노드가 루트노드의 조건이고
 막대 그래프는 나가는 간선은 없고 들어오는 간선은 없거나 1개일때or 1개 이상이 될수도있다.
 8자 그래프는 나가는 간선 2개 들어오는 간선 2개 의 조건을 맞춰주면 8자 그래프라고 얘기할수있는 것이다. 도넛그래프는.. 이것을 한참이해하려고 했으나 아직도 잘 이해가 가지않는다 다른 문제풀이들을 보니 전체 그래프갯수에서 - (막대그래프갯수 + 8자그래프갯수)로 구하더라 좀 어이가없었다 ㅎㅎ..</p>
<p>코드를 보자</p>
<pre><code>function solution(edges) {
  let answer = new Array(4).fill(0)
  let graph = {}
  for (const [a,b] of edges) {
    if(!graph[a]){
      graph[a] = [0,0] // 각 노드에서 in-degree, out-degree 를 저장해줄 용도이다
    }
    if(!graph[b]){
      graph[b] = [0,0] // 각 노드에서 in-degree, out-degree 를 저장해줄 용도이다
    }
    graph[a][0]++ // in-degree를 카운트해준다
    graph[b][1]++ // out-degree를 카운트해준다
  }
  for (const key in graph) {
    if(graph[key][0] &gt;= 2 &amp;&amp; graph[key][1] === 0){
      answer[0] = Math.max(answer[0],key)
      // in-degree가 2개이상이면서 out-degree가 0개이다 그중에 in-degree가 가장많은 노드를 선택한다
    }
  }
  let total = graph[answer[0]][0] // 나중에 도넛그래프의 갯수를 구하기위해 변수로 저장해뒀다
  for (const [a,b] of edges) {
    if(a !== answer[0])continue
    graph[b][1]-- 
    // 여기서 중요하다 막대그래프 조건이 가장애매했는데 루트노드에서
      // in-degree를 graph에서 다 제거해준다 그러니 막대그래프를 찾을수 있었다.
  }
  for (const key in graph) {
    if(graph[key][0] === 0 &amp;&amp; graph[key][1] &gt;= 0){ // 막대그래프이다 
      answer[2]++
    }else if(graph[key][0] === 2 &amp;&amp; graph[key][1] === 2){ // 8자그래프이다 
      answer[3]++ 
    }
  }
  answer[1] = total - (answer[2]+answer[3]) 
  // 그래프의 총갯수 - (막대그래프 + 8자그래프) 이렇게 하면 나머지가 도넛그래프가 되는것이다.
  return answer 
}</code></pre><p>알고리즘 공부하면서 느끼는점은 나만빼고 다 똑똑한것같다 ㅎㅎ </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[data structures - Dijkstra 알고리즘]]></title>
            <link>https://velog.io/@tiger_front_end/data-structures-Dijkstra-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
            <guid>https://velog.io/@tiger_front_end/data-structures-Dijkstra-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</guid>
            <pubDate>Wed, 17 Jan 2024 12:22:12 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>다익스트라(Dijkstra) 알고리즘이 뭘까?</p>
</blockquote>
<p>다익스트라 알고리즘은 네트워크에서 한 노드에서 다른 노드로 가는 가장 짧은 경로를 찾는 알고리즘입니다. 1956년에 에츠허르 다익스트라에 의해 개발되었으며, 그래프 이론에서 중요한 위치를 차지합니다. 이 알고리즘은 양의 가중치를 가진 간선들을 포함하는 그래프에서 최단 경로 문제를 해결하는데 사용되고 인공위성 GPS 소프트웨어 등에서 가장 많이 사용되는 알고리즘이다.
다이나믹 프로그래밍에 속하며 “최단 거리가 여러 개의 최단 거리”로 이루어져 있기 때문이다. 즉, 하나의 최단 거리를 구할 때, 이전까지 구했던 최단 거리 정보를 그대로 사용한다는 것입니다.</p>
<p>다익스트라 알고리즘 작동 방식
다음은 다익스트라 알고리즘이 어떻게 작동하는지에 대한 간단한 설명입니다.</p>
<p>1) 시작 노드를 설정합니다.
2) 시작 노드에서 각 노드까지의 거리를 추정합니다. 시작 노드의 경우 0으로, 다른 모든 노드의 경우 무한대로 설정합니다.
3) 미방문 노드 집합에서 최단 거리를 가진 노드를 선택합니다.
4) 해당 노드를 방문하고, 그 이웃 노드들의 거리를 업데이트 합니다.
5) 모든 노드를 방문할 때까지 이 과정을 반복합니다.</p>
<pre><code>function dijkstra(graph, start) {
  let distances = {};
  for (let vertex in graph) {
    distances[vertex] = Infinity;
  }
  distances[start] = 0;

  let queue = new PriorityQueue();
  queue.enqueue(start, 0);

  while (!queue.isEmpty()) {
    let shortestDistanceVertex = queue.dequeue().element;
    for (let neighbor in graph[shortestDistanceVertex]) {
      let distanceThroughVertex = distances[shortestDistanceVertex] + graph[shortestDistanceVertex][neighbor];
      if (distanceThroughVertex &lt; distances[neighbor]) {
        distances[neighbor] = distanceThroughVertex;
        queue.enqueue(neighbor, distances[neighbor]);
      }
    }
  }
  return distances;
}
</code></pre><p>우선 순위 큐를 사용하여 미방문 노드 중에서 가장 거리가 짧은 노드를 선택하고, 그 노드의 이웃 노드들의 거리를 업데이트하는 방식으로 작동합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ssr(server side rendering) 과 csr(client side rendering)의 차이점]]></title>
            <link>https://velog.io/@tiger_front_end/ssrserver-side-rendering-%EA%B3%BC-spasingle-page-application%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90</link>
            <guid>https://velog.io/@tiger_front_end/ssrserver-side-rendering-%EA%B3%BC-spasingle-page-application%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90</guid>
            <pubDate>Tue, 16 Jan 2024 06:11:26 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>SSR(server side rendering)이란 무엇일까</p>
</blockquote>
<p>SSR(Server Side Rendering)은, 사용자가 웹사이트에 접속하면 브라우저가 서버에 페이지를 요청하고, 서버는 필요한 데이터를 가져와 HTML과 JavaScript 코드를 렌더링하여 브라우저에 전달하는 방식을 말합니다. 이 방식의 장점은 초기 렌더링 속도가 빠르고 SEO에 유리하다는 점입니다. 하지만 단점으로는 JavaScript 파일이 완전히 로딩되기 전까지는 사용자의 입력에 응답할 수 없어 상호작용에 딜레이가 발생하며, 새로운 컨텐츠를 불러올 때마다 새로고침이 필요하고 이로 인해 화면 깜박임이 발생할 수 있습니다.</p>
<blockquote>
<p>CSR(client side rendering)란 무엇일까</p>
</blockquote>
<p>CSR(Client Side Rendering)은, 초기에 웹 어플리케이션에 필요한 정적 리소스를 모두 다운로드하고, 이후에는 새로운 페이지 요청이 있을 때 필요한 데이터만 받아와 필요한 부분만 갱신하는 방식입니다. 이 방식의 장점은 화면의 필요한 부분만 데이터를 받아서 렌더링해주기 때문에 효율적이고 속도가 빠르며, 사용자에게 더 나은 사용성을 제공한다는 점입니다. 하지만 단점으로는 화면을 처음 로딩할 때 모든 정보를 서버에 요청해야 하기 때문에 로딩 속도가 다소 걸릴 수 있으며, SEO에 불리하고 DOM 조작이 빈번하게 일어나기 때문에 브라우저 성능이 느려질 수 있습니다.
하지만 코드분할을 하거나,프리로딩,프리페칭을 통해 CSR방식에서도 초기 로딩속도를 개선할수는 있다. 하지만 최적화기법은 프로젝트의 복잡성이 높아지기때문에 요구에 따라 적절히 선택해야한다.</p>
<p>어떤 렌더링 방식을 선택할지는 프로젝트의 특성에 따라 달라집니다. 데이터가 자주 바뀌지 않고 단순한 정보를 제공하는 페이지라면 CSR 방식을, 데이터가 빈번하게 바뀌는 경우에는 SSR 방식이 유리합니다. 최근에는 Next.js와 같은 프레임워크를 통해 CSR과 SSR을 혼합하여 사용할 수 있는 방법도 인기를 얻고 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[data structures - 순열]]></title>
            <link>https://velog.io/@tiger_front_end/data-structures-%EC%88%9C%EC%97%B4</link>
            <guid>https://velog.io/@tiger_front_end/data-structures-%EC%88%9C%EC%97%B4</guid>
            <pubDate>Mon, 15 Jan 2024 14:14:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>순열이란?</p>
</blockquote>
<p>서로 다른  n개의 원소에서 r(단,0&lt;r≤n일 때)개를 중복없이 순서를 고려하여 선택하거나 나열하거나 하는 것을 순열(permutation)이라고 한다.
순열은 초등학교 때부터 알게 모르게 써왔던 수학 개념 중 하나다 
서로 다른 n개 중에 r개를 선택하는 경우의 수 (순서O, 중복X)
예1) 예1) 5명을 3줄로 세우는 방법
예2) 서로 다른 4명 중 반장, 부반장을 뽑는 방법</p>
<p>재귀 함수를 이용한 순열</p>
<pre><code>let getPermutation = (arr,selectnum)=&gt;{
    const result = []; // 결과를 담을 배열
    if (selectnum === 1){ // 순열의 길이가 1이면 각 원소를 배열로 반환
        arr.map((v)=&gt;[v]);
    }
    arr.forEach((fixed, index, origin)=&gt;{ // 각 원소에 대해 순열 생성
        const rest = [...origin.slice(0, index), ...origin.slice(index + 1)]; // 고정 원소를 제외한 나머지 원소들
        const permutation = getPermutation(rest, selectnum - 1); // 나머지 원소들에 대해 순열 생성
        const fixed_permutation = permutation.map((v)=&gt;[fixed, ...v]); // 고정 원소와 나머지 원소들의 순열을 결합
        result.push(...fixed_permutation);
    });
    return result;
}</code></pre><p>순열은 중복을 허용하며 모든 경의 수를 조합할 수 있다.</p>
<p>예를 들어 1,2,3과 1,3,2를 다른것으로 취급한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[react github 배포시 경로 오류]]></title>
            <link>https://velog.io/@tiger_front_end/react-github-%EB%B0%B0%ED%8F%AC%EC%8B%9C-%EA%B2%BD%EB%A1%9C-%EC%98%A4%EB%A5%98</link>
            <guid>https://velog.io/@tiger_front_end/react-github-%EB%B0%B0%ED%8F%AC%EC%8B%9C-%EA%B2%BD%EB%A1%9C-%EC%98%A4%EB%A5%98</guid>
            <pubDate>Fri, 12 Jan 2024 13:33:32 GMT</pubDate>
            <description><![CDATA[<p>포트폴리오 만들던 도중 잘나오는지 확인좀 해보려고 
깃허브에 올리고 주소를 확인했는데
얼라리 빌드후 내파일들이 경로가틀렸는지 불러오지않는것이다</p>
<p>알아보니 SPA가 홈페이지를 설정하면 GitHub Pages는 기본적으로 서브디렉터리에서 앱을 호스팅해서 이로 인해 라우팅이 제대로 작동하지 않았던 것이였다.</p>
<p>방법은 두가지가 있었고</p>
<ol>
<li><p>package.json 으로 들어가 추가시켜준다.</p>
<pre><code>&quot;homepage&quot;: &quot;.&quot;</code></pre></li>
<li><p>BrowserRouter 대신 HashRouter 사용하는것이다. React Router의 BrowserRouter는 HTML5 히스토리 API를 사용하여 브라우저의 URL을 조작합니다 그러나 GitHub Pages와 같이 서브디렉터리에서 호스팅할 때 문제가 될 수 있기때문에 대신 HashRouter를 사용하면 해결될 수 있다.</p>
<pre><code>import { HashRouter as Router, Route, Routes } from &quot;react-router-dom&quot;;</code></pre></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[data structures - 투포인터]]></title>
            <link>https://velog.io/@tiger_front_end/data-structures-%ED%88%AC%ED%8F%AC%EC%9D%B8%ED%84%B0</link>
            <guid>https://velog.io/@tiger_front_end/data-structures-%ED%88%AC%ED%8F%AC%EC%9D%B8%ED%84%B0</guid>
            <pubDate>Wed, 10 Jan 2024 14:01:37 GMT</pubDate>
            <description><![CDATA[<p>투 포인터 알고리즘(Two Pointers Algorithm)은 배열이나 리스트에서 두 개의 포인터를 사용하여 원하는 결과를 얻는 데 사용되는 알고리즘입니다. 주로 정렬된 배열이나 리스트에서 특정한 조건을 만족하는 부분집합을 찾는 데 효과적으로 사용됩니다. 이 알고리즘은 일반적으로 배열의 양 끝에서 시작하여 서로 다가가는 방식으로 동작합니다.</p>
<p>투 포인터 알고리즘의 핵심 아이디어는 두 개의 포인터를 조작하여 원하는 조건에 도달하거나 조건을 만족하는 결과를 찾는 것입니다.</p>
<pre><code>function twoSum(arr, target) {
  let left = 0;               // 배열의 시작 지점
  let right = arr.length - 1;  // 배열의 끝 지점

  while (left &lt; right) {
    let sum = arr[left] + arr[right];

    if (sum === target) {
      return [arr[left], arr[right]];  // 합이 타겟과 일치하는 경우
    } else if (sum &lt; target) {
      left++;  // 합이 타겟보다 작으면 왼쪽 포인터를 오른쪽으로 이동
    } else {
      right--; // 합이 타겟보다 크면 오른쪽 포인터를 왼쪽으로 이동
    }
  }

  return []; // 찾을 수 없는 경우
}

const arr = [2, 7, 11, 15];
const target = 9;

console.log(twoSum(arr, target)); // 출력: [2, 7]</code></pre><p>두 포인터를 배열의 양 끝에서 시작하여 합이 target과 일치하는지 확인합니다. 만약 합이 작다면 왼쪽 포인터를 오른쪽으로 이동하고, 합이 크다면 오른쪽 포인터를 왼쪽으로 이동합니다. 이런 식으로 포인터들이 서로 다가가면서 원하는 조건을 찾을 수 있습니다.</p>
<p>투 포인터 알고리즘은 배열이나 리스트에서 서로 다른 두 요소를 조작해가면서 특정한 패턴을 찾는 경우에 효과적으로 사용됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2024 카카오 채용 연계형 겨울 인턴십 코딩테스트 1번 - 문제풀이]]></title>
            <link>https://velog.io/@tiger_front_end/2024-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EC%B1%84%EC%9A%A9-%EC%97%B0%EA%B3%84%ED%98%95-%EA%B2%A8%EC%9A%B8-%EC%9D%B8%ED%84%B4%EC%8B%AD-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-1%EB%B2%88-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</link>
            <guid>https://velog.io/@tiger_front_end/2024-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EC%B1%84%EC%9A%A9-%EC%97%B0%EA%B3%84%ED%98%95-%EA%B2%A8%EC%9A%B8-%EC%9D%B8%ED%84%B4%EC%8B%AD-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-1%EB%B2%88-%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4</guid>
            <pubDate>Mon, 08 Jan 2024 04:01:33 GMT</pubDate>
            <description><![CDATA[<h4 id="가장-많이-받은-선물">가장 많이 받은 선물</h4>
<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/258712">https://school.programmers.co.kr/learn/courses/30/lessons/258712</a></p>
<p>이라는 문제였고 딕셔너리를 얼마나 알고있는지에 대한 문제였던것같다.
(본인)이 문해력이 좀 부족한편이기때문에 조금헷갈리게 지문이 길어지면 상당히 
골머리를 썩히는 편이다 긴 지문에서 가장 주목을 해야할부분은 이부분이였다.</p>
<blockquote>
<ol>
<li>두 사람이 선물을 주고받은 기록이 있다면, 이번 달까지 두 사람 사이에 더 많은 선물을 준 사람이 다음 달에 선물을 하나 받습니다.</li>
<li>두 사람이 선물을 주고받은 기록이 하나도 없거나 주고받은 수가 같다면, 선물 지수가 더 큰 사람이 선물 지수가 더 작은 사람에게 선물을 하나 받습니다.</li>
</ol>
</blockquote>
<p>여기서 조건문쓰고 고치는데 한참이나 걸렸다 다시 풀어보니 왜그랬는지... 
<img src="https://velog.velcdn.com/images/tiger_front_end/post/5d575aac-062b-4914-ac23-20015bf92b1e/image.png" alt=""><img src="https://velog.velcdn.com/images/tiger_front_end/post/d94466bd-1915-413f-aca5-2990522b6ac9/image.png" alt=""></p>
<p>이렇게 자료형을 정리하는게 우선이였다. </p>
<pre><code> let answer = {}
  let statistic = {}
  let idxStatistic = {}
  for (const name of friends) {
    answer[name] = 0
    statistic[name] = 0
    idxStatistic[name] = {}
    for (const sub of friends) {
      if(name !== sub){
        idxStatistic[name][sub] = 0
      }
    }
  }
  for (const cur of gifts) {
    let [from,to] = cur.split(&#39; &#39;)
    statistic[from] = statistic[from]+1
    statistic[to] = statistic[to]-1
    idxStatistic[from][to] = idxStatistic[from][to]+1
  }</code></pre><p>answer는 최종 선물을 받기 위해 만들어둔 객체이고 statistic은 객체 두 개를 이용해 각 친구들에게 준 갯수를 정리해둔 객체이다. 선물을 받으면 --연산, 선물을 주면 ++연산을 해주었다. 코딩테스트 때는 내가 조건문을 잘못 썼기에 check라는 객체를 추가로 만들었었는데(중복 계산을 피하기 위해 한 번 비교한 것은 체크를 해주기 위해 만들었었다.) 그리고 객체가 배열보다 더 가벼운 메모리를 사용하기 때문에 객체를 사용했고, 뭐 배열을 써도 상관은 없다. 차이가 작기 때문에 크게 신경쓸 정도는 아니기 때문이다. 성능 및 메모리 최적화에 중점을 둘 때만 이러한 차이가 중요해진다. 코딩테스트는 통과하는 게 목적이기 때문에 다시 풀어보니 조건문을 내가 잘못 쓴 것이었다 ㅎㅎ..</p>
<pre><code>let a = [&quot;muzi&quot;, &quot;ryan&quot;, &quot;frodo&quot;, &quot;neo&quot;]
let b = [&quot;muzi frodo&quot;, &quot;muzi frodo&quot;, &quot;ryan muzi&quot;, &quot;ryan muzi&quot;, &quot;ryan muzi&quot;, &quot;frodo muzi&quot;, &quot;frodo ryan&quot;, &quot;neo muzi&quot;]
function solution(friends, gifts) {
  let answer = {}
  let statistic = {}
  let idxStatistic = {}
  for (const name of friends) {
    answer[name] = 0
    statistic[name] = 0
    idxStatistic[name] = {}
    for (const sub of friends) {
      if(name !== sub){
        idxStatistic[name][sub] = 0
      }
    }
  }
  for (const cur of gifts) {
    let [from,to] = cur.split(&#39; &#39;)
    statistic[from] = statistic[from]+1
    statistic[to] = statistic[to]-1
    idxStatistic[from][to] = idxStatistic[from][to]+1
  }
  for (const from in idxStatistic) {
    for (const to in idxStatistic[from]) {
      if(idxStatistic[from][to] === 0 &amp;&amp; idxStatistic[to][from] === 0 || idxStatistic[from][to] === idxStatistic[to][from]){
        if(statistic[from] &gt; statistic[to]){
          answer[from] = answer[from]+1
        }
      }else{
        if(idxStatistic[from][to] &lt; idxStatistic[to][from]){
          answer[to] = answer[to]+1
        }else if(idxStatistic[to][from] &gt; idxStatistic[from][to]){
          answer[from] = answer[from]+1
        }
      }
    }
  }
  answer = Math.max(...Object.values(answer))
  return answer
}</code></pre><p>이게 최종코드이고 하단에 이중포문에서 한참시간을 보냈던것같다
이어서 2번문제도 포스팅 해보겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[(2024 카카오 채용 연계형 겨울 인턴십) 코딩테스트 후기]]></title>
            <link>https://velog.io/@tiger_front_end/2024-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EC%B1%84%EC%9A%A9-%EC%97%B0%EA%B3%84%ED%98%95-%EA%B2%A8%EC%9A%B8-%EC%9D%B8%ED%84%B4%EC%8B%AD-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@tiger_front_end/2024-%EC%B9%B4%EC%B9%B4%EC%98%A4-%EC%B1%84%EC%9A%A9-%EC%97%B0%EA%B3%84%ED%98%95-%EA%B2%A8%EC%9A%B8-%EC%9D%B8%ED%84%B4%EC%8B%AD-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Fri, 05 Jan 2024 12:53:35 GMT</pubDate>
            <description><![CDATA[<p>자료구조는 개뿔 아무것도 모르는 상태에서 data structure 공부를 시작했다. 나중에 알게 되었다. 공부를 시작한 지 얼마 안 돼 내가 아무 것도 모르는 상태였단 것을ㅎㅎ. 프론트엔드 라고 하기에는 애매한 경력 4년 7개월을 가지고 무엇이든 할 수 있다는 다짐으로 공부를 시작했다. 부트캠프.. 국비.. 많이 고민했다. 퇴사하기 6개월 전부터 고민을 했는데 결국 내가 몸소 겪어서 느낀 건 공부는 스스로 해야 한다는 결론이었다. 그래도 프로그래밍에 무지한 상태였기 때문에 가이드가 필요해서 결국 과외를 하기로 마음먹었다.</p>
<p>경력 기간 동안 나름 개발자분들에게 굴려진 상태라 내가 개발에 대해서 많이 아는 것처럼 생각했던 것일까. 프로그래밍은 생각보다 어려웠다. 어려우면서 내가 논리적인 성격이라고 생각했는데 마치 그게 아닌 것처럼 느껴졌다. 개발 공부를 해봤으면 이런 소리 다들 한 번 들어봤을 것이다. 컴퓨터는 거짓말을 하지 않는다. 그렇다. 나는 너무 감성적인 것이었다ㅎㅎ.</p>
<p>경력 동안 써왔던 언어가 JavaScript였기에 자연스레 나의 주력 언어가 되었다. 웹 개발자에게는 찰떡인 언어지만 요즘은 살짝 후회되긴 한다. 후회되면서 살짝 좋기도 하다. 변태인가..</p>
<ol>
<li>인터프리터 (runtime에 오류가 발생할 때까지 확인 불가)</li>
<li>AST(Abstract Syntax Tree)로 구분 분석이 어려움. (소스 코드 구조 분석이 안되서 변변한 에디터가 없음)</li>
<li>가변형 자료구조(명확하지 않음)
요즘은 TypeScript를 쓴다고 하는데 아직까지 내가 그 정도 수준이라고는 생각은 안 해봤다. 프로그래머스에는 LeetCode와 다르게 example이 나오지 않기 때문에 더욱 스트레스를 받았다. 간혹 로직이 맞아도 타입 때문에 틀리는 경우가 있었기 때문이다. 정말 이럴 때 키보드를 부셔버리고 싶을 때도 있었다.</li>
</ol>
<p>그렇게 겨울이 올 때쯤 11월이었다. 알고리즘 공부한 지 어언 9개월째... 카카오 채용 연계형 겨울 인턴십을 한다는 것을 봐버린 것이다. 무의식적으로 지원해버렸다. 아직 내가 알고 있는 지식으로는 부족할 것이라고 생각했지만 기대해보며ㅎㅎ</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/359528b1-e7ec-473e-ac5e-dfe2f5185438/image.png" alt=""></p>
<p>메일이 날라온 후로부터 쿵쾅댔다. 알고리즘 공부하면서 진짜 꼴도 보기 싫은 날도 있었고, 사실 내가 수포자에 가까웠기 때문에 알고리즘에서 수학 공식처럼 수식이나 올 때마다 머리가 아득했었다. 그래서 공부하는 게 좀 루즈했었는데, 내가 꿈에 그리던 회사의 코딩테스트를 보게 되었기 때문에 굉장히 흥분되어 마치 연습만 하다 링위에 처음 올라온 초짜 격투기 선수처럼 기대에 부풀어 있었다.</p>
<p>백준 실버 2를 달성하고 딕셔너리 문제들, (DFS, BFS), Dijkstra 문제, 투 포인터, (구간 합) Prefix Sum, 뭐 요정도 간단하게 아는 상태였기 때문에 자신감이 차올라 있는 상태였기 때문이다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/f4215e1a-ac40-4d37-9c3a-8a3c6f8e9263/image.png" alt=""></p>
<p>2주 뒤에 코딩 테스트를 보게 되었는데.. 생각보다 떨리더라(긴장을 잘하는 편이다). 총 5시간 동안 시험을 봤다. 그냥 말하자면 죽쒔다. 1번 문제는 예상했지만 구현 문제였다. 하지만 내가 조건문을 제대로 몰랐던 걸까, 딕셔너리랑 친하지 않았던 것일까 푸는 데 2시간은 걸렸던 것 같다. 지문이 길어지니 헷갈렸다. 풀고 나니 참 간단한데 헷갈렸다. 최근에 프로그래머스에 올라왔기 때문에 다시 풀어보고 포스팅을 할 예정이다.</p>
<p>2번 문제는 그래프 순회 문제였다. 여기서부터 말리기 시작했다. 1번 문제를 난 빨리 풀 거라고 예상했는데 2시간 이상 잡아먹었기 때문에 멘탈이 흔들렸다. 마치 1라운드에서 개털린 선수처럼 헉헉대고 있었다. 총 3종류의 그래프를 찾아야 하고 조건에 맞는 그래프를 체크해 카운트를 하고 return해야 하는 문제였다. 정신을 다잡고 2번 문제를 푸는데 유니온-파인드에 대해서 정확히 이해는 하지 못했지만 웬지 사이클이 없는 그래프도 찾아야 하고 있는 그래프도 찾아야 하고 유니온-파인드로 풀 수 있을 것 같았지만 유니온-파인드로 1시간 정도 끙끙대다가 그때 알았다. 내가 유니온-파인드를 모르는구나 ^^ 순회하려면 DFS라는 생각이 들었기 때문에 코드를 코치고 끙끙대다가 DFS를 두 번 쓰면서 순회하는 감을 잡았을 때 1시간 정도 남았던 것 같다. 다른 문제도 봐야지 하고 3, 4, 5 번을 봤는데 3, 4번은(사실 그럴 시간도 없었지만) 제대로 보지 못했다. 대충 봤는데 5번 문제만 머리에 들어와서 봤는데 dynamic programming 문제였다. 어려웠다. DP 문제도 난이도 낮은 문제를 풀어봐서 별거 아니겠거니 했는데 이것도 내가 제대로 알고 있는 게 아니었다 ㅎㅎ..</p>
<p>그렇게 5시간을 다 쓰고 멘탈이 나간 상태에서 시험 종료를 누르고 나왔다. 사실 내심 기대했지만 처참한 것 같아 나에게 실망이 컸다. 2.5솔은 해야 통과한다는 소리가 팽배했기 때문에 그런데 카카오 코딩테스트로 나의 level 체크가 정확하게 되었다라고나 할까. 공부 방식이 뭔가 바뀌었다. 점점 집요해지는 것 같기도 하고 카카오 인턴 코테로 인해서 알게된 게 많았다.</p>
<h4 id="내가-공부할-방향과-ide디버깅능력이-중요하단것-그리고-코테경험을-통해-긴장을-낮추기">내가 공부할 방향과, ide디버깅능력이 중요하단것, 그리고 코테경험을 통해 긴장을 낮추기.</h4>
<p>이정도인것같다 이후로도 몇군데 코테를 봤지만 떨어졌다 다음 기회가 올때는 꼭 잡으리라 마음먹고 공부를 하고있다. 내가생각하는거 보다 훨씬더 많이 노력해보자🍔</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[data structures - 프림 알고리즘 ( Prim's algorithm )]]></title>
            <link>https://velog.io/@tiger_front_end/data-structures-%ED%94%84%EB%A6%BC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Prims-algorithm</link>
            <guid>https://velog.io/@tiger_front_end/data-structures-%ED%94%84%EB%A6%BC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Prims-algorithm</guid>
            <pubDate>Fri, 05 Jan 2024 03:15:48 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/007a21cd-feb8-450a-ba20-e6b6119a24ae/image.png" alt=""></p>
<h4 id="프림알고리즘이란-무엇인가">프림알고리즘이란 무엇인가?</h4>
<p>크루스칼 알고리즘과 같이 minimum spanning tree 를 찾는 알고리즘이다
보통 우선순위 큐를 사용한다. 크루스칼 알고리즘과 같은 용도이지만, 응용 상황에서 두 알고리즘의 효율성이 달라질 수 있기 때문에 둘 모두 알아두는 것이 좋다.</p>
<p>단계별로 표현하자면 </p>
<ol>
<li>그래프를 연결되어있는 node와 cost(가중치)순으로 만들어준다 그리고 가중치 기준으로 정렬해준다.</li>
<li>우선순위큐를 만들어주고 시작노드를 넣어준다(순서상관이 없다 아무거나 넣어주면 된다)</li>
<li>방문한 노드를 체크해줄수있게 visitTable을 만들어준다.</li>
<li>우선순위큐가 빌때까지 순회하면서 방문하지 않은곳을 방문체크를 해준다. (cost값은 기호에 맞게 사용한다 문제 상황이 다르기때문에..)</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[data structures - 백트래킹(Backtracking)]]></title>
            <link>https://velog.io/@tiger_front_end/data-structures-%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9Backtracking-82p4e8pu</link>
            <guid>https://velog.io/@tiger_front_end/data-structures-%EB%B0%B1%ED%8A%B8%EB%9E%98%ED%82%B9Backtracking-82p4e8pu</guid>
            <pubDate>Wed, 03 Jan 2024 10:59:44 GMT</pubDate>
            <description><![CDATA[<h4 id="백트래킹backtracking-이란">백트래킹(Backtracking) 이란?</h4>
<p>백트래킹은 주로 조합(combination) 및 순열(permutation)과 같은 문제를 해결하기 위한 알고리즘 기법 중 하나이다. 이 기법은 가능한 모든 해를 탐색하면서 원하는 해를 찾아내는 데 사용된다.</p>
<h4 id="백트래킹의-개념">백트래킹의 개념:</h4>
<p>백트래킹은 &#39;퇴각 검색&#39; 또는 &#39;다시 돌아가기&#39;라고도 한다
문제의 해를 찾을 때, 현재 시점에서 가능한 모든 후보를 확인하다가 더 이상 나아갈 수 없으면 이전 단계로 돌아가서 다른 후보를 탐색한다 이 과정을 반복하면서 최종적으로 원하는 해를 찾는다. 여기서 상당히 머리에 쥐가나기 시작한다
DFS도 재귀적으로 구현을 할수있고 백트래킹도 재귀적인개념인데 간단하게 말하면, DFS는 그래프 또는 트리를 탐색하는 일반적인 알고리즘이고, 백트래킹은 해를 찾아가면서 특정 제약 조건을 만족하는 경우에만 계속 진행하는 알고리즘 이다 DFS에 백트래킹이 포함되게 만들수도 있는데 이것은 좀더 공부를 해봐야할것같다.</p>
<pre><code>function backtrackingCombination(arr, selected, start, M) {
  if (selected.length === M) {
    console.log(selected);
    return;
  }

  for (let i = start; i &lt; arr.length; i++) {
    selected.push(arr[i]);
    backtrackingCombination(arr, selected, i + 1, M);
    selected.pop();  // 백트래킹: 이전 선택 상태로 돌아감
  }
}

const N = 5;  // 1부터 N까지의 자연수
const M = 3;  // 조합의 크기
const numbers = Array.from({ length: N }, (_, index) =&gt; index + 1);

backtrackingCombination(numbers, [], 0, M);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[(기초) git에 내 작업물올리기]]></title>
            <link>https://velog.io/@tiger_front_end/%EA%B8%B0%EC%B4%88-git%EC%97%90-%EB%82%B4-%EC%9E%91%EC%97%85%EB%AC%BC%EC%98%AC%EB%A6%AC%EA%B8%B0</link>
            <guid>https://velog.io/@tiger_front_end/%EA%B8%B0%EC%B4%88-git%EC%97%90-%EB%82%B4-%EC%9E%91%EC%97%85%EB%AC%BC%EC%98%AC%EB%A6%AC%EA%B8%B0</guid>
            <pubDate>Wed, 03 Jan 2024 10:46:00 GMT</pubDate>
            <description><![CDATA[<p>Git에서 작업물을 올리는 전체 과정은 다음과 같다</p>
<h4 id="1-로컬-저장소에서-변경사항-확인">1. 로컬 저장소에서 변경사항 확인:</h4>
<pre><code>git status</code></pre><p>변경된 파일이나 새 파일이 있는지 확인합니다.</p>
<h4 id="2-변경-사항-스테이징-staging">2. 변경 사항 스테이징 (Staging):</h4>
<pre><code>git add .</code></pre><p>변경된 모든 파일을 스테이징 영역에 추가합니다. 만약 특정 파일만 스테이징하려면 
git add 파일이름을 사용하면된다.</p>
<h4 id="3-로컬-저장소에-변경사항-커밋-commit">3. 로컬 저장소에 변경사항 커밋 (Commit):</h4>
<pre><code>git commit -m &quot;커밋 메시지&quot;</code></pre><p>스테이징 영역에 있는 변경 사항을 로컬 저장소에 커밋합니다.</p>
<h4 id="4-원격-저장소에-변경사항-푸시-push">4. 원격 저장소에 변경사항 푸시 (Push):</h4>
<pre><code>git push origin 브랜치이름</code></pre><p>원격 저장소에 로컬 저장소의 변경 사항을 업로드합니다. &quot;브랜치이름&quot;은 현재 작업 중인 브랜치의 이름입니다.</p>
<p>전체적인 작업순서..</p>
<pre><code>git status         # 변경사항 확인
git add .          # 변경 사항 스테이징
git commit -m &quot;커밋 메시지&quot;   # 로컬 저장소에 변경사항 커밋
git push origin 브랜치이름   # 원격 저장소에 변경사항 푸시</code></pre><p>이렇게 하면 작업한 내용이 로컬 저장소에서 원격 저장소로 업로드됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[data structures - 크루스칼 알고리즘 (Kruskal Algorithm)]]></title>
            <link>https://velog.io/@tiger_front_end/data-structures-%ED%81%AC%EB%A3%A8%EC%8A%A4%EC%B9%BC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Kruskal-Algorithm</link>
            <guid>https://velog.io/@tiger_front_end/data-structures-%ED%81%AC%EB%A3%A8%EC%8A%A4%EC%B9%BC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-Kruskal-Algorithm</guid>
            <pubDate>Sat, 30 Dec 2023 12:08:13 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>Algorithm</strong></p>
</blockquote>
<p>greedy알고리즘 에 속하며 union-find와 연관이있어서 대장찾기에대해서 이해해야 크루스칼에대해서</p>
<p>이해가 가능한것같다 비전공자인 내게는 그래프라는게 이해하는데 한참 걸렸다 내가 아는건 차트밖에없었으니</p>
<p>그냥 단순하게 그래프=차트 라고 머릿속에 박혀있어서 이 개념을 깨고 이해하는데 애좀 먹었다. </p>
<p>신장 트리 중에서 최소 비용으로 만들 수 있는 신장 트리를 찾는 알고리즘을 &#39;최소 신장 트리 알고리즘&#39;이라고 하는데, </p>
<p>대표적인 최소 신장 트리 알고리즘으로는 <strong>크루스칼 알고리즘</strong>이 있다.</p>
<p>크루스칼 알고리즘을 사용하면 가장 적은 비용으로 모든 노드를 연결할 수 있다.</p>
<p>크루스칼 알고리즘은 대표적인 최소 신장 트리 알고리즘이다.</p>
<h4 id="최소신장-트리가-뭘까-minimum-spanning-tree">최소신장 트리가 뭘까? (minimum spanning tree)</h4>
<p>신장트리란 어떤 그래프가있을때 각 노드를 모두 포함하면서 싸이클이 존재하지 않는 그래프를 의미한다. </p>
<p>-&gt; 이때 모든 노드를 포함하며 서로 연결되어있지만 사이클이 존재하지않는 조건은</p>
<p>트리의 성립조건이기도하다 트리와 그래프가 따로 있는게 아닌 그래프 분류안에</p>
<p>트리가 있기때문이다. 싸이클이 없이 모든노드를 이을수만있다면 그것이 곧 spanning tree 인것이다.</p>
<p>따라서 최소 신장트리는 간선의 가중치가 있을때 각 노드를 포함하면서 싸이클이 없는 그래프인데 각 간선들의</p>
<p>총합이 가장 작은 트리를 지칭하는것이다.</p>
<h4 id="동작-원리를-알아보자">동작 원리를 알아보자</h4>
<p>다른 블로그들을 봤지만 이해하기 힘들어서 문제를 풀어보면서 감이왔는데</p>
<p>보통 그래프를 나타날때는 인접행렬이나 인접리스트로 표현하게되는데</p>
<p>개인적으로 인접리스트가 좀더 편하기 때문에 인접리스트로 설명하겠다.</p>
<p>인접리스트로 그래프를 표현하면 보통 이런식으로 표현이 될것이다 </p>
<pre><code>[
  [from,to,cost],
  [from,to,cost],
  [from,to,cost],
  [from,to,cost]
]</code></pre><p>여기서 중요한과정인 cost 기준으로 <strong>오름차순 정렬</strong>이 필요하다.</p>
<p>그런후 그래프를 순회하면서 find(from) === find(to)로 연결이 되어있는지 확인해주고 </p>
<p>연결이 되어있지않으면 union으로 합쳐준후 cost를 저장해준다.</p>
<p>이해하고나니 그렇게 어렵진않은데 개고생을 좀 한것같다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/c9e7449d-6f46-4f64-af72-e6f5aa9e1b2d/image.jpg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[맨하탄 거리(Manhattan Distance)]]></title>
            <link>https://velog.io/@tiger_front_end/%EB%A7%A8%ED%95%98%ED%83%84-%EA%B1%B0%EB%A6%ACManhattan-Distance</link>
            <guid>https://velog.io/@tiger_front_end/%EB%A7%A8%ED%95%98%ED%83%84-%EA%B1%B0%EB%A6%ACManhattan-Distance</guid>
            <pubDate>Fri, 29 Dec 2023 07:15:58 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/a5085964-dd87-4aa7-8391-27c9274689da/image.png" alt="">
맨허튼 거리(Manhattan Distance) 는 2차원 평면 공간에서 두 점 p 와 q 사이의 거리를 측정하는 방법 중 하나로, 두 점 사이의 수평 및 수직 이동 거리의 합으로 정의된다. 
수식 = ∣p1−q1∣+∣p2−q2∣ 이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[선형구조 - 큐(Queue), 스택(Stack), 덱(Deque) 이해하기]]></title>
            <link>https://velog.io/@tiger_front_end/%EC%84%A0%ED%98%95%EA%B5%AC%EC%A1%B0-%ED%81%90Queue-%EC%8A%A4%ED%83%9DStack-%EB%8D%B1Deque-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tiger_front_end/%EC%84%A0%ED%98%95%EA%B5%AC%EC%A1%B0-%ED%81%90Queue-%EC%8A%A4%ED%83%9DStack-%EB%8D%B1Deque-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 26 Dec 2023 12:16:25 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/1f667feb-18b4-4e7e-9ea3-303190a72660/image.png" alt=""></p>
<h4 id="선형-구조linear-structure란">선형 구조(Linear Structure)란?</h4>
<p>데이터를 저장하기 위한 기본적인 형태로 데이터가 &#39;일렬로 나열&#39;되어 있을 뿐만 아니라 데이터 간에 순서가 있는 구조를 의미합니다.</p>
<h4 id="그럼-비-선형구조nonlinear-란-무엇일까">그럼 비 선형구조(NonLinear) 란 무엇일까?</h4>
<p>그래프(트리)가 비선형 구조에 속합니다.</p>
<h4 id="stack-은-무엇인가">Stack 은 무엇인가?</h4>
<p>데이터를 일시적으로 쌓아두기 위한 자료구조 중 하나이며, 후입선출(LIFO, Last-In-First-Out)의 특성을 가지는 구조를 의미합니다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/863d2170-6add-4472-b18a-f9a6796f8553/image.png" alt=""></p>
<p>이렇게 stack 안에 자료가 쌓이되고 가장 마지막에 쌓인 자료가 먼저 나가게 되는 자료형이다.</p>
<h4 id="queue-는-무엇인가">Queue 는 무엇인가?</h4>
<p>데이터를 일시적으로 쌓아두기 위한 자료구조 중 하나이며, 선입선출(FIFO, First-In-First-Out)의 특성을 가지는 구조를 의미합니다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/a7f7b7fc-61f3-43ac-9429-1726a75aed85/image.png" alt=""></p>
<p>이렇게 qeueu 안에 자료가 쌓이고 먼저 들어간 자료가 먼저 나가게되는 자료형이다.</p>
<h4 id="deque-은-무엇인가">Deque 은 무엇인가?</h4>
<p>queue는 front에서만 삭제하고, end에서만 삽입하는데, deque는 front와 end에서 삭제와 삽입이 모두 가능하다.
deque의 양 끝을 가리키는 포인터 2개를 갖는다.</p>
<p><img src="https://velog.velcdn.com/images/tiger_front_end/post/c154a402-6665-4e54-85ed-5dc4f56a34f5/image.png" alt=""></p>
<p>stack과 queue의 종합선물세트 정도 쯤으로 이해하면된다.
앞뒤에서 삭제 삽입이 가능하며 앞과 뒤에서 삽입, 삭제가 자주 일어나는 경우
데이터의 개수가 가변적일때 사용한다.</p>
]]></description>
        </item>
    </channel>
</rss>