<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>pingu-.log</title>
        <link>https://velog.io/</link>
        <description>느낀대로 적자</description>
        <lastBuildDate>Wed, 09 Nov 2022 10:07:28 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>pingu-.log</title>
            <url>https://images.velog.io/images/pingu-/profile/9d5f4e31-9d72-4765-b093-0d4be15e3950/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. pingu-.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/pingu-" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[python 프로젝트 생성]]></title>
            <link>https://velog.io/@pingu-/%E3%85%87-dgubgjah</link>
            <guid>https://velog.io/@pingu-/%E3%85%87-dgubgjah</guid>
            <pubDate>Wed, 09 Nov 2022 10:07:28 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>$ django-admin startproject [생성될이름]</p>
</blockquote>
<blockquote>
<p>project/
&emsp;&emsp;ㄴmanage.py
&emsp;&emsp;ㄴproject/
&emsp;&emsp;&emsp;ㄴ<strong>init</strong>.py
&emsp;&emsp;&emsp;ㄴsettings.py
&emsp;&emsp;&emsp;ㄴurls.py
&emsp;&emsp;&emsp;ㄴasgi.py
&emsp;&emsp;&emsp;ㄴwsgi.py</p>
</blockquote>
<ul>
<li>manage.py: Django 프로젝트와 다양한 방법으로 상호작용 하는 커맨드라인의 유틸리티 이다.</li>
<li>project/ 디렉토리 내부에는 프로젝트를 위한 실제 Python 패키지들이 저장된다. 이 디렉토리 내의 이름을 이용하여, (project.urls 와 같은 식으로) 프로젝트의 어디서나 Python 패키지들을 임포트할 수 있다.</li>
<li>project/<strong>init</strong>.py: Python으로 하여금 이 디렉토리를 패키지처럼 다루라고 알려주는 용도의 단순한 빈 파일이다.</li>
<li>project/settings.py: 현재 Django 프로젝트의 환경 및 구성을 저장합니다. Django settings에서 환경 설정이 어떻게 동작하는지 확인할 수 있다.</li>
<li>project/urls.py: 현재 Django project 의 URL 선언을 저장합니다. Django 로 작성된 사이트의 “목차” 라고 할 수 있다.</li>
<li>project/asgi.py: 현재 프로젝트를 서비스하기 위한 ASGI-호환 웹 서버의 진입점이다.</li>
<li>project/wsgi.py: 현재 프로젝트를 서비스하기 위한 WSGI 호환 웹 서버의 진입점이다.</li>
</ul>
<blockquote>
<p>$ python manage.py runserver</p>
</blockquote>
<blockquote>
<p>$ python manage.py startapp polls</p>
</blockquote>
<blockquote>
<p>polls/
&emsp;&emsp;ㄴ<strong>init</strong>.py
&emsp;&emsp;ㄴadmin.py
&emsp;&emsp;ㄴapps.py
&emsp;&emsp;ㄴmigrations/
&emsp;&emsp;&emsp;ㄴ<strong>init</strong>.py
&emsp;&emsp;ㄴmodels.py
&emsp;&emsp;ㄴtests.py
&emsp;&emsp;ㄴviews.py</p>
</blockquote>
<p><code>polls/views.py</code></p>
<pre><code class="language-python">from django.http import HttpResponse


def index(request):
    return HttpResponse(&quot;Hello, world. You&#39;re at the polls index.&quot;)</code></pre>
<blockquote>
<p>뷰를 호출하려면 이와 연결된 URL 이 있어야 하는데, 이를 위해 URLconf가 사용된다.
polls 디렉토리에서 URLconf를 생성하려면, urls.py라는 파일을 생성해야 한다.</p>
</blockquote>
<p><code>polls/urls.py</code></p>
<pre><code class="language-python">from django.urls import path

from . import views

urlpatterns = [
    path(&#39;&#39;, views.index, name=&#39;index&#39;),
]</code></pre>
<p><code>project/urls.py</code></p>
<pre><code class="language-python">from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path(&#39;polls/&#39;, include(&#39;polls.urls&#39;)),
    path(&#39;admin/&#39;, admin.site.urls),
]</code></pre>
<blockquote>
<p>include()를 사용하면  URL의 그 시점까지 일치하는 부분을 잘라내고, 남은 문자열 부분을 후속 처리를 위해 include 된 URLconf로 전달한다.</p>
</blockquote>
<blockquote>
<p>path(&#39;route&#39;,view,[keyword],[name])</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[모의면접]]></title>
            <link>https://velog.io/@pingu-/%EB%AA%A8%EC%9D%98%EB%A9%B4%EC%A0%91</link>
            <guid>https://velog.io/@pingu-/%EB%AA%A8%EC%9D%98%EB%A9%B4%EC%A0%91</guid>
            <pubDate>Mon, 05 Sep 2022 00:25:13 GMT</pubDate>
            <description><![CDATA[<h1 id="리액트의-내부-작동-원리를-재조정reconciliation-개념과-함께-설명하세요">리액트의 내부 작동 원리를 재조정(Reconciliation) 개념과 함께 설명하세요.</h1>
<blockquote>
</blockquote>
<p>실제로 DOM을 제어하지 않고 중간에 가상의 virtual DOM을 두어 virtual DOM이 변경이 될 때, 실제 DOM을 변경하도록 설계한다. 이 작업을 Reconciliation (virtual DOM과 DOM을 비교해 DOM을 갱신하는 작업) 이라고 한다
이 때 virtual DOM을 갱신하는 방법은 setState() 메서드를 호출하는 방법과, Redux의 경우처럼 store가 변하면 다시 최상위 컴포넌트의 render() 함수를 호출해서 갱신하는 2가지 방법이 있다</p>
<h1 id="virtual-dom이-무엇인가요-virtual-dom이-좋은-이유에-대해서-설명하세요">virtual DOM이 무엇인가요? virtual DOM이 좋은 이유에 대해서 설명하세요.</h1>
<blockquote>
</blockquote>
<p>Virtual DOM은 실제 DOM 변화를 최소화 시켜주는 역할을 한다
virtualDOM을 이용하는 이유는 효율성 때문입니다. virtualDOM을 활용하면 실제 DOM을 직접 바꾸는 것보다 시간 복잡도가 현저히 낮아진다
Virtual DOM은 뷰에 변화가 있다면, 그 변화가 실제 DOM에 적용되기 전에 Virtual DOM에 적용시키고 최종 결과만 실제 DOM에 전달한다</p>
<h1 id="리액트에-있는-라이프사이클과-각-라이프사이클의-역할을-설명하세요">리액트에 있는 라이프사이클과 각 라이프사이클의 역할을 설명하세요.</h1>
<blockquote>
<p><img src="https://velog.velcdn.com/images/pingu-/post/1274a745-6624-48ab-994f-158fa3501608/image.png" alt="">
componentDidMount() 는 최초로 컴포넌트 객체가 생성될 때 한 번 수행
componentDidUpdate() 는 컴포넌트의 속성 값 또는 상태값이 변경되면 호출
componentWillUnmount() 는 이 컴포넌트가 소멸될 때 호출
render() 는 초기에 화면에 그려줄 때, 그리고 업데이트가 될 때 호출</p>
</blockquote>
<h1 id="리액트-라우터같은-client-side-routing-에-대해서-설명하세요">리액트 라우터같은 Client Side Routing 에 대해서 설명하세요.</h1>
<blockquote>
<p>웹 페이지의 렌더링이 클라이언트 (브라우저) 측에서 일어나는 것이다
서버와 클라이언트 간의 데이터 트래픽이 감소하고 렌더링이 한번만 있기 때문에 페이지 이동이 빠르다는 장점이 있지만,
SEO(검색최적화) 사용에는 SSR 방식에 비해 활용도가 낮다는 단점이 있다
보안 관련해서는 쿠키에 사용자 정보를 저장해야 해서 위험 요소가 될 수 있다</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[firebase CRUD]]></title>
            <link>https://velog.io/@pingu-/firebase-CRUD</link>
            <guid>https://velog.io/@pingu-/firebase-CRUD</guid>
            <pubDate>Thu, 01 Sep 2022 10:54:14 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-jsx">//firebase.js

import { initializeApp } from &quot;firebase/app&quot;;
import { getFirestore } from &quot;firebase/firestore&quot;;
import { getAuth } from &quot;firebase/auth&quot;;

const firebaseConfig = {
    ...
};

const app = initializeApp(firebaseConfig);
export const db = getFirestore(app)
export const auth = getAuth()</code></pre>
<h1 id="create">Create</h1>
<blockquote>
<p>collection 추가 ( setDoc, doc)</p>
</blockquote>
<ul>
<li>하위 문서 이름이 비어있으면 오류남</li>
<li>collection and 하위 문서 이름이 중복될때는 덮어씌어짐</li>
</ul>
<pre><code class="language-jsx">//app.js
import { db } from &#39;./firebase&#39;
import { doc, setDoc } from &quot;firebase/firestore&quot;;

    await setDoc(doc(db, &quot;collection 이름&quot;,&quot;하위 문서 이름&quot;), {
      name: &quot;Los Angele&quot;,
      state: &quot;C&quot;,
      country: &quot;US&quot;
    });

    await setDoc(doc(db, &quot;cities&quot;,&quot;LA&quot;), {
      name: &quot;Los Angele&quot;,
      state: &quot;C&quot;,
      country: &quot;US&quot;
    });</code></pre>
<blockquote>
<p>하위 문서 추가 ( addDoc, collection )</p>
</blockquote>
<ul>
<li>하위문서 이름이 상관없을때 사용</li>
</ul>
<pre><code class="language-jsx">//app.js
import { db } from &#39;./firebase&#39;
import { addDoc, collection } from &quot;firebase/firestore&quot;;

    await addDoc(collection(db, &quot;cities&quot;), {
      name: &quot;Los Angele&quot;,
      state: &quot;C&quot;,
      country: &quot;US&quot;
    });</code></pre>
<h1 id="read">Read</h1>
<blockquote>
<p>collection에 있는 값들을 전부 불러온다 ( getDocs, collection )</p>
</blockquote>
<ul>
<li>forEach를 써서 자료를 하나하나 불러와야 한다</li>
</ul>
<pre><code class="language-jsx">import { db } from &#39;./firebase&#39;
import { getDocs, collection } from &quot;firebase/firestore&quot;;
      let list = [];
      try {
        const querySnapshot = await getDocs(collection(db, &quot;users&quot;));
        querySnapshot.forEach((doc) =&gt; {
          list.push({ id: doc.id, ...doc.data() });
        });
        setData(list);
</code></pre>
<h1 id="update">Update</h1>
<blockquote>
<p>덮어씌우지 않고 특정값만 변경 ( updateDoc, doc )</p>
</blockquote>
<pre><code class="language-jsx">import { db } from &#39;./firebase&#39;
import { doc, updateDoc } from &quot;firebase/firestore&quot;;

    await updateDoc(doc(db, &quot;cities&quot;, &quot;LA&quot;), {
      name: &quot;Busan&quot;,
    });</code></pre>
<h1 id="delete">Delete</h1>
<blockquote>
<p>특정 id값을 삭제한다</p>
</blockquote>
<pre><code class="language-jsx">import { db } from &#39;./firebase&#39;
import { doc, deleteDoc } from &quot;firebase/firestore&quot;;

 await deleteDoc(doc(db, &quot;cities&quot;, id));
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[모의면접 1주차]]></title>
            <link>https://velog.io/@pingu-/%EB%AA%A8%EC%9D%98%EB%A9%B4%EC%A0%91-1%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@pingu-/%EB%AA%A8%EC%9D%98%EB%A9%B4%EC%A0%91-1%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Sun, 28 Aug 2022 14:23:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Q. 일반적으로 CSS <code>&lt;link&gt;</code> 태그를 <code>&lt;head&gt;&lt;/head&gt;</code> 태그 사이에 위치시키는 이유는?</p>
</blockquote>
<ul>
<li>HTML을 파싱하는 중간에 <code>&lt;link&gt;</code> 를 만나면 <code>&lt;link&gt;</code> 파싱은 병렬적으로 수행되어 HTML 파싱과 동시에 진행된다.</li>
<li>따라서 <code>&lt;head&gt;</code> 태그 안에 CSS <code>&lt;link&gt;</code> 를 삽입하면, HTML과 CSS가 병렬적으로 파싱되어 CSSOM을 더 빠르게 완성할 수 있다. 따라서 사이트에 렌더링 되는 시간도 빨라진다.</li>
<li><code>&lt;link&gt;</code> 를 HTML 중간이나 마지막에 삽입하면, <code>&lt;link&gt;</code> 이전의 요소들을 렌더링하다가 <link> 를 만난 후에 CSSOM을 생성하고, 여기에 맞춰 다시 렌더링을 한다. 이렇게 되면 첫번째 렌더링을 할 때 사용자에게 스타일되지 않은 HTML 요소를 보여주게 되어 UX에 좋지 않고, 두번째 렌더링을 할 때 HTML 요소들이 재렌더링 되기 때문에 낭비가 심하다. 또한 <code>&lt;link&gt;</code> 의 삽입이 늦어진 만큼 CSSOM 생성도 늦춰져 렌더링 완료 시간이 늦춰진다.</li>
</ul>
<blockquote>
<p>Q. JS <code>&lt;script&gt;</code> 태그를 <code>&lt;body&gt;</code>태그가 끝나기 직전에 위치시키는 이유는?</p>
</blockquote>
<ul>
<li>브라우저는 <code>&lt;script&gt;</code> 태그를 만나면 HTML 파싱을 잠시 멈추고, <code>&lt;script&gt;</code> 를 다운로드하고 실행한다(Parsing Blocking). 이 경우, 사용자에게 화면이 보여지기까지 시간이 늦어진다.</li>
</ul>
<blockquote>
<p>Q. <code>&lt;script&gt; &lt;script async&gt; &lt;script defer&gt;</code> 태그들의 차이점은 무엇인가?</p>
</blockquote>
<ul>
<li><code>&lt;script&gt;</code> 태그를 만나면 파싱을 멈추고 스크립트를 다운받은 후 에 실행.</li>
<li><code>&lt;async&gt;</code> 태그를 만나면 파싱을 유지한채로 스크립트를 다운받은 후 실행될때 파싱이 멈춤.</li>
<li><code>&lt;defer&gt;</code> 태그를 만나면 파싱을 유지한채로 스크립트를 다운받은 후 실행될때도 파싱이 멈추지 않음</li>
</ul>
<blockquote>
<p>Q. 시맨틱 태그(sementic tag) 에 대해 설명하세요.</p>
</blockquote>
<ul>
<li>자신의 목적과 의미를 브라우저와 개발자에게 명확하게 설명하는 태그를 말한다.</li>
</ul>
<blockquote>
<p>Q. 웹팩과 바벨의 역할에 대해서 설명하세요.</p>
</blockquote>
<ul>
<li>웹팩은 자바스크립트 어플리케이션을 위한 정적 모듈 번들러이다.<ul>
<li>웹페이지에서 자바스크립트 파일을 여러번 다운로드 받지 않게 하기 위해</li>
<li>모듈 단위로 개발할 수 있게</li>
</ul>
</li>
<li>바벨은 자바스크립트 트랜스파일러이다<ul>
<li>구형 웹 브라우저에서도 사용할 수 있게 하기 위해</li>
</ul>
</li>
</ul>
<blockquote>
<p>Q. event.preventDefault() 의 역할</p>
</blockquote>
<ul>
<li>기본으로 정의된 이벤트를 작동하지 못하게 하는 메서드</li>
</ul>
<blockquote>
<p>Q. intersection Observer API가 무엇인지 설명하세요.</p>
</blockquote>
<ul>
<li>Intersection Observer API는 타겟 요소와 상위 요소 또는 최상위 document 의 viewport사이의 intersection 내의 변화를 비동기적으로 관찰하는 방법</li>
<li>페이지가 스크롤 되는 도중에 발생하는 이미지나 다른 컨텐츠의 지연 로딩</li>
<li>스크롤 시에, 더 많은 컨텐츠가 로드 및 렌더링되어 사용자가 페이지를 이동하지 않아도 되게 하는 infinite-scroll 을 구현</li>
<li>광고 수익을 계산하기 위한 용도로 광고의 가시성 보고</li>
<li>사용자에게 결과가 표시되는 여부에 따라 작업이나 애니메이션을 수행할 지 여부를 결정</li>
</ul>
<blockquote>
<p>Q. 이벤트 위임</p>
</blockquote>
<ul>
<li>엘리먼트마다 핸들러를 할당하지 않고, 엘리먼트의 공통 조상에 이벤트 핸들러를 단 하나만 할당해도 여러 요소를 한꺼번에 다룰 수 있는 방법을 말함</li>
</ul>
<blockquote>
<p>Q. 이벤트 버블링</p>
</blockquote>
<ul>
<li>특정 화면 요소에서 이벤트가 발생했을 때 해당 이벤트가 더 상위의 화면 요소들로 전달되어 가는 특성을 의미함</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[DOM 조작 방법 ]]></title>
            <link>https://velog.io/@pingu-/DOM-%EC%A1%B0%EC%9E%91-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@pingu-/DOM-%EC%A1%B0%EC%9E%91-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 23 Aug 2022 03:42:34 GMT</pubDate>
            <description><![CDATA[<h1 id="create">Create</h1>
<pre><code class="language-jsx">document.createElement(&#39;div&#39;)
&lt;div&gt;&lt;/div&gt;</code></pre>
<ul>
<li>위와 같이 하게 되면 div 태그가 생성된다</li>
</ul>
<pre><code class="language-jsx">const divTag = document.createElement(&#39;div&#39;)</code></pre>
<p>변수에 담을수도 있다</p>
<h1 id="append">Append</h1>
<ul>
<li>생성된 div태그를 body에 적용시키자</li>
</ul>
<pre><code class="language-jsx">document.body.append(divTag)</code></pre>
<h1 id="read">Read</h1>
<ul>
<li>클래스가 tweet인 html을 불러오자<pre><code class="language-jsx">const oneTweet = document.querySelector(&#39;.tweet&#39;)</code></pre>
</li>
<li>클래스가 tweet인 모든 html을 불러오자<pre><code class="language-jsx">const tweets = document.querySelectorAll(&#39;.tweet&#39;)</code></pre>
</li>
<li>기존의 부모요소에 자식요소로 넣어보자<pre><code class="language-jsx">const container = document.querySelector(&#39;#container&#39;)
const tweetDiv = document.createElement(&#39;div&#39;)
container.append(tweetDiv)</code></pre>
</li>
<li>querySelector 와 같은 getElementById 도 사용 가능하다<pre><code class="language-jsx">const getOneTweet = document.getElementById(&#39;container&#39;)
const queryOneTweet = document.querySelector(&#39;#container&#39;)
console.log(getOneTweet === queryOneTweet) // true</code></pre>
</li>
</ul>
<h1 id="update">Update</h1>
<ul>
<li>div 태그 안에 text를 넣어보자</li>
</ul>
<pre><code class="language-jsx">console.log(divTag) // &lt;div&gt;&lt;/div&gt;
divTag.textContent = &#39;hello&#39;
console.log(divTag) // &lt;div&gt;hello&lt;/div&gt;</code></pre>
<ul>
<li>div 태그에 class를 넣어보자</li>
</ul>
<pre><code class="language-jsx">divTag.classList.add(&#39;tweet&#39;)
console.log(divTag) // &lt;div class=&quot;tweet&quot;&gt;hello&lt;/div&gt;</code></pre>
<h1 id="delete">Delete</h1>
<ul>
<li>태그를 지워보자<pre><code class="language-jsx">divTag.remove() </code></pre>
</li>
<li>자식 요소들을 모두 지워보자<pre><code class="language-jsx">document.querySelector(&#39;#container&#39;).innerHTML = &#39;&#39;;</code></pre>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[cors 정리]]></title>
            <link>https://velog.io/@pingu-/cors-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@pingu-/cors-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sat, 28 May 2022 06:42:13 GMT</pubDate>
            <description><![CDATA[<h1 id="corscross-origin-resource-sharing">CORS(Cross Origin Resource Sharing)</h1>
<blockquote>
<p>CORS 정책은 우리가 가져오는 리소스들이 안전한지 검사하는 관문이다.</p>
</blockquote>
<ul>
<li><p>주로 아래의 오류가 cors의 에러다
<img src="https://velog.velcdn.com/images/pingu-/post/ec42a524-b42f-47ea-b6c2-90a36f946791/image.png" alt=""></p>
</li>
<li><p>HTML : 기본적으로 Cross-Origin 정책을 따름</p>
<ul>
<li>link 태그에서 다른 origin의 css 등의 리소스에 접근하는 것이 가능</li>
<li>img 태그등에서 다른 리소스에 접근하는 것이 가능</li>
</ul>
</li>
<li><p>XMLHttpRequest, Fetch API 등 script 태그 내 : 기본적으로 Same-Origin 정책을 따름</p>
<ul>
<li>자바스크립트는 서로 다른 도메인에 대한 요청을 보안상 제한한다. (브라우저 기본 설정은 하나의 서버 연결만 허용)</li>
<li>이러한 정책을 Same-Origin-Policy라고 한다.</li>
</ul>
</li>
</ul>
<h1 id="출처-origin">출처 (Origin)</h1>
<blockquote>
<p>출처는 Protolcol 과 Host 그리고 Port까지 모두 합친 것을 의미한다.</p>
</blockquote>
<ul>
<li><code>console.log(location.origin)</code> 을 이용하면 Location 객체가 가지고 있는 origin 프로퍼티에 접근하여 현재 출처를 알아낼 수도 있다.</li>
</ul>
<h1 id="cross-origin--same-origin">Cross Origin / Same Origin</h1>
<p>웹에는 SOP(Same Origin Policy)와 CORS(Cross Origin Resurce Sharing) 두가지 정책이 있다.
 </p>
<h2 id="sop-same-origin-policy-동일-출처-정책">SOP (Same-Origin Policy) &lt;동일 출처 정책&gt;</h2>
<ul>
<li>SOP는 &quot;같은 출처에서만 리소스를 공유할 수 있다&quot;라는 규칙을 가진 정책이다.</li>
<li>두개의 출처를 비교하는 방법은 URL의 구성요소 중 Protocol, Host, Port 이 세가지가 동일한지 확인하면 된다.</li>
<li>즉 같은 프로토콜, 호스트, 포트를 사용한다면 다른 요소는 다르더라도 같은 출처로 인정된다. 반대로 리소스가 자신의 출처와 다를경우 브라우저는 교차출처 요청을 실행한다.</li>
<li>프로토콜, 포트, 호스트중 하나라도 일치하지 않으면 Cross Origin 이라고 한다.</li>
</ul>
<h2 id="cors-cross-origin-resource-sharing-교차-출처-리소스-공유">CORS (Cross-Origin Resource Sharing) &lt;교차 출처 리소스 공유&gt;</h2>
<ul>
<li>추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제다.</li>
</ul>
<p><a href="https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F#thankYou">참고</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[디바운싱과 쓰로틀링]]></title>
            <link>https://velog.io/@pingu-/%EB%94%94%EB%B0%94%EC%9A%B4%EC%8B%B1%EA%B3%BC-%EC%93%B0%EB%A1%9C%ED%8B%80%EB%A7%81</link>
            <guid>https://velog.io/@pingu-/%EB%94%94%EB%B0%94%EC%9A%B4%EC%8B%B1%EA%B3%BC-%EC%93%B0%EB%A1%9C%ED%8B%80%EB%A7%81</guid>
            <pubDate>Wed, 25 May 2022 13:57:00 GMT</pubDate>
            <description><![CDATA[<h1 id="디바운싱debouncing">디바운싱(debouncing)</h1>
<blockquote>
<p>연이어 호출되는 함수들 중 마지막 함수(또는 제일 처음)만 호출하도록 하는 것</p>
</blockquote>
<ul>
<li><p>주로 ajax 검색에 자주 쓰임</p>
</li>
<li><p>예로 실시간 검색을 할때 사용자가 원하는 단어를 다 입력하기전에 입력할때 마다 ajax 요청을 보내게 되면 유료api였을때 큰 비용이 들게 된다.</p>
</li>
<li><p>비용뿐만 아니라 사용자의 경험과 서버에게도 부담이 되어 좋은 방향은 아니다.</p>
<pre><code class="language-jsx">const [timer, setTimer] = useState(0)

const changeValue = (e) =&gt; {
  if (timer) {
    clearTimeout(timer)
  }
  const delay = setTimeout(async () =&gt; {
    try {
      await axios.get(`api요청`)
    } catch (err) {
      console.log(err)
    }
  }, 300);
  setTimer(delay)
}</code></pre>
</li>
</ul>
<h1 id="쓰로틀링throttling">쓰로틀링(throttling)</h1>
<blockquote>
<p>마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것</p>
</blockquote>
<ul>
<li>주로 스크롤을 내릴 때 사용 됨</li>
<li>스크롤을 올리거나 내릴 때 이벤트가 많이 발생하기때문에 복잡한 작업을 자주 실행하게 된다면 스크롤 할때마다 렉이 심해지기 때문에 쓰로틀링을 걸어 일정시간에 한번만 제한을 두는 역할을 한다.</li>
<li>디바운싱과 비슷하게 코드를 작성하면 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[sequelize-cli를 통한 model생성]]></title>
            <link>https://velog.io/@pingu-/sequelize-cli%EB%A5%BC-%ED%86%B5%ED%95%9C-model%EC%83%9D%EC%84%B1</link>
            <guid>https://velog.io/@pingu-/sequelize-cli%EB%A5%BC-%ED%86%B5%ED%95%9C-model%EC%83%9D%EC%84%B1</guid>
            <pubDate>Tue, 24 May 2022 04:14:36 GMT</pubDate>
            <description><![CDATA[<h1 id="sequelize">sequelize</h1>
<ul>
<li>시퀄라이즈를 시작하기 앞서 npm을 통해 설치를 해주어야 한다
<code>npm i sequelize sequelize-cli mysql2</code></li>
<li>init을 통해 sequelize 초기 세팅을 시작한다
<code>npx sequelize init</code></li>
<li>위 명령을 하게 되면 몇가지의 폴더가 생긴다</li>
<li>이제 user 모델을 생성하자<ul>
<li>아래 명령을 입력하게 되면 <code>model</code> 폴더에 js파일이 생성된다.
<code>npx sequelize model:generate --name User --attributes username:string nickname:string password:string</code></li>
</ul>
</li>
<li>이제 마이그레이션을 통해 데이터베이스에 생성하자
<code>npx sequelize db:migrate</code></li>
<li>이렇게 까지 하게 되면 <code>mysql</code>에 모델을 생성하여 마이그레이션까지 되었다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[express 초기 설정]]></title>
            <link>https://velog.io/@pingu-/express-%EC%B4%88%EA%B8%B0-%EC%84%A4%EC%A0%95</link>
            <guid>https://velog.io/@pingu-/express-%EC%B4%88%EA%B8%B0-%EC%84%A4%EC%A0%95</guid>
            <pubDate>Sun, 22 May 2022 14:48:09 GMT</pubDate>
            <description><![CDATA[<h1 id="express">express</h1>
<p>express.js는 node.js를 빠르고 쉽게 이용할 수 있게 해주는 프레임워크 입니다.</p>
<ul>
<li><p>package.json 생성하기
<code>npm init</code></p>
</li>
<li><p>express.js 설치하기
<code>npm install express</code></p>
</li>
<li><p>출력 하기</p>
<ul>
<li>package.json에 아래 코드를 추가해야 한다<pre><code>&quot;scripts&quot;: {
&quot;start&quot;: &quot;node index.js&quot;
...
}</code></pre></li>
</ul>
</li>
<li><p>index.js 파일을 생성 후 아래 코드를 입력</p>
<pre><code>import express from &#39;express&#39;; //난 commonJS 대신 module을 사용하기 떄문에 require말고 import로 사용한다.
const app = express();
app.get(&#39;/&#39;, (req, res) =&gt; {
res.send(&#39;Hello World!&#39;)
})</code></pre></li>
<li><p>require 대신 react처럼 import/export 사용하는 법</p>
<ul>
<li>package.json에 타입 추가<pre><code>{
&quot;type&quot;:&quot;module&quot;,
}</code></pre></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Route 53 구축]]></title>
            <link>https://velog.io/@pingu-/Route-53-%EA%B5%AC%EC%B6%95</link>
            <guid>https://velog.io/@pingu-/Route-53-%EA%B5%AC%EC%B6%95</guid>
            <pubDate>Sat, 21 May 2022 14:11:18 GMT</pubDate>
            <description><![CDATA[<h1 id="route-53">Route 53</h1>
<ul>
<li>aws에서 제공하는 도메인 라우팅 서비스이다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/pingu-/post/6024e81a-ff7f-45bf-9770-d105ccaa00fe/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/a89a8af7-9c50-4913-81e3-8c157ed728c6/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/741e9fce-b51c-4435-b495-ddff7c82986f/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/b0fd14df-d7ef-45e4-9d61-5800aa77becd/image.png" alt=""></p>
<p>백주소를 설정하는중</p>
<p>서버주소를 결정하는곳이다</p>
<p>트래픽 라우팅 대상을 나의 로드밸런서를 설정해주자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/e8fff150-eb5b-49f6-adff-33093a9c98ec/image.png" alt=""></p>
<p>프론트도 해주자</p>
<p>끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CloudFront 구축]]></title>
            <link>https://velog.io/@pingu-/CloudFront-%EA%B5%AC%EC%B6%95</link>
            <guid>https://velog.io/@pingu-/CloudFront-%EA%B5%AC%EC%B6%95</guid>
            <pubDate>Thu, 19 May 2022 13:52:00 GMT</pubDate>
            <description><![CDATA[<h1 id="cloudfront">CloudFront</h1>
<ul>
<li>CloudFront는 AWS에서 제공하는 CDN 서비스이며 캐싱을 통해 사용자에게 좀 더 빠른 전송 속도를 제공함을 목적하는 서비스이다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/pingu-/post/6df220b6-320b-4e9a-8407-ae68c8c55255/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/1c00b176-c84d-4115-8ee8-6f0671fe0eb8/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/161e825d-c94d-4fa6-94ac-44d864d49c58/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/b88feaad-4505-44de-867b-bb34cdd5f9e3/image.png" alt=""></p>
<p>선택사항이라 써있지만 필수이다</p>
<p>둘다 설정해주자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/7ee7184a-371b-4acb-8610-cb9d58401d05/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/7aabd8e9-518c-4552-a32b-768dc6ef2af4/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/7686616d-e41f-4d63-bf58-41b61c7280a0/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/54a230c6-3937-4e23-aee0-ffcffd10f360/image.png" alt=""></p>
<p>403이랑 404도 똑같이 2개 설정해주자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/359366d9-4226-4f82-a0fe-813f2dca94e0/image.png" alt=""></p>
<hr>
<hr>
<p>끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Load Balancer]]></title>
            <link>https://velog.io/@pingu-/Load-Balancer</link>
            <guid>https://velog.io/@pingu-/Load-Balancer</guid>
            <pubDate>Wed, 18 May 2022 11:21:19 GMT</pubDate>
            <description><![CDATA[<h1 id="load-balancer">Load Balancer</h1>
<ul>
<li>이번엔 부하분산 또는 로드 밸런싱은 컴퓨터 네트워크 기술의 일종으로 둘 혹은 셋이상의 중앙처리장치 혹은 저장장치와 같은 컴퓨터 자원들에게 작업을 나누는 것을 의미하는 로드 밸런서를 구현해보겠다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/pingu-/post/2d3f9689-00d4-4484-af91-daa11e6214f6/image.png" alt=""></p>
<p>ec2로 와서 대상 그룹을 설정해주자</p>
<p>대상 그룹은 내 컴퓨터의 포트로 설정해주겠다는 느낌이다</p>
<p>정확한 내용을 알게되면 다시 수정하겠다</p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/4049b01e-ce93-4574-9e17-be240df8fe9e/image.png" alt=""></p>
<p>이름을 적어주고</p>
<p>구축한 서버 포트를 적어주자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/13419c21-7006-4f45-a608-faf25745bd5e/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/004d0d15-9e54-4fa8-9d22-bd9808a9b4fb/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/51f761ec-4ef6-4ffd-9600-15e09705040a/image.png" alt=""></p>
<p>로드밸런서로 와서 생성하자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/ef11faad-99f1-45a4-9576-78ec6a99ca27/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/ef1c8db0-f986-45c6-b98e-8df1c3ed027a/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/0b06e82a-7567-4597-821c-a25c7f168645/image.png" alt=""></p>
<p>전부다 체크하자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/06647b49-e529-4f04-8338-a351adb328f5/image.png" alt=""></p>
<p>서버설정이 담긴 보안그룹을 넣자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/99e44f96-a5e1-40db-9b32-225bda26f836/image.png" alt=""></p>
<p>http와 https를 위와같이 설정해주자</p>
<p>두 포트로 들어와도 내 서버포트로 라우팅 해주겠다는 뜻인거 같다</p>
<p>이것도 정확히 알게되면 다시 수정하겠다</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/dd50f9f3-68e4-4df8-91c3-63dd7cac3122/image.png" alt=""></p>
<p>내 인증서를 넣어주자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/097f4386-30f7-4774-ac26-4a0dcbc10223/image.png" alt=""></p>
<p>끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Certificate Manager 인증서 관리]]></title>
            <link>https://velog.io/@pingu-/Certificate-Manager-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EA%B4%80%EB%A6%AC</link>
            <guid>https://velog.io/@pingu-/Certificate-Manager-%EC%9D%B8%EC%A6%9D%EC%84%9C-%EA%B4%80%EB%A6%AC</guid>
            <pubDate>Mon, 16 May 2022 14:08:11 GMT</pubDate>
            <description><![CDATA[<h1 id="certificate-manager">Certificate Manager</h1>
<h2 id="도메인을-이미-구매했다는-전제하에-시작함">도메인을 이미 구매했다는 전제하에 시작함</h2>
<ul>
<li>https 구축을 위한 인증서 발급 및 인증서를 사용할 수 있게 도와주는 Certificate Manager를 다루겠다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/pingu-/post/cf5db398-a9ab-4a9f-a06d-508aa121dc6f/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/d839b9ac-59a9-4964-a6c1-8635bb9235a9/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/3552322f-b093-49f2-a1b8-0f33c57a795c/image.png" alt=""></p>
<p>이 인증서에 다른 이름 추가를 눌러</p>
<p>도메인은 본인이 등록한 도메인과</p>
<p>앞에 *. 을 붙여서 총 2개를 등록한다</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/b159d839-41bc-4a8c-82d5-59f3de30b6b3/image.png" alt=""></p>
<p>태그 제거 누르고 요청 </p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/64c090a2-b4c1-4c5f-bb8b-1492c294bb4f/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/78729da7-f3ba-4147-b26b-28e7cfe151d2/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/51fac7b0-0d8f-402a-b55e-10b4fb2cd4ed/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/30763b5d-75f2-401d-af60-919dd5bbcf78/image.png" alt=""></p>
<p>발급됨이 될때까지 기다리자</p>
<p>인증서는 이제 끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[RDS 구축]]></title>
            <link>https://velog.io/@pingu-/RDS-%EA%B5%AC%EC%B6%95</link>
            <guid>https://velog.io/@pingu-/RDS-%EA%B5%AC%EC%B6%95</guid>
            <pubDate>Sat, 14 May 2022 09:55:40 GMT</pubDate>
            <description><![CDATA[<h1 id="rds">RDS</h1>
<p>데이터베이스를 관리하는 RDS를 구축해보자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/e7802a1b-29fc-4df9-a76b-41da9e2970d7/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/0ee211bd-2714-49f4-94a2-c3f548ef116d/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/adda355e-f109-4640-bcc2-c9fa07771dcb/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/2a152396-5024-4f16-a3fb-f43864ee6ba1/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/1ac65f9a-fa2e-4c41-aebb-33cb32d1c52e/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/6cc18e46-578e-46d8-b0e2-0ed906d16f38/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/5b9e5e07-ff1b-4c95-9530-3ac87c1cd574/image.png" alt=""></p>
<p>사용 가능으로 바뀔때까지 기다리자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/d3cb3539-27da-4687-8b74-a4203bd62f49/image.png" alt=""></p>
<p>기다리는동안 데이터베이스랑 연결한 보안그룹을 설정해주자 </p>
<p>ec2에 들어가 보안그룹에서 설정하자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/bdf9336c-47d3-4d7a-861e-79ae88e88016/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/305f2ff9-2a60-4c04-9595-e9c1653fe0af/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/d4bb2263-8f62-434a-9348-8a6192f25196/image.png" alt=""></p>
<p>다시 데이터베이스로 돌아와서 클릭</p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/cef75794-59d9-4394-a30e-192b58450f01/image.png" alt=""></p>
<hr>
<hr>
<p>위 엔드포인트를 복사하여 </p>
<pre><code class="language-jsx">mysql -u [데이터베이스 생성할때 지은 마스터이름] --host [복사한 엔드포인트 주소] -P [포트번호] -p</code></pre>
<p>ec2에서 말고 내 컴퓨터에서 위 명령어를 사용해서 RDS에 접속해보자</p>
<p>비밀번호 입력창이 뜨면 데이터베이스 생성할때 만든 마스터 비밀번호를 입력하자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/8e8df1d3-9232-43fb-b855-b1277e8fea08/image.png" alt=""></p>
<p>ec2의 서버설정으로 가서 호스트를 데이터베이스의 엔드포인트 주소로 변경해주자</p>
<p>들어온김에 터미널을 꺼도 서버가 유지될수있게 pm2를 설치해주자</p>
<pre><code class="language-jsx">npm install pm2 -g</code></pre>
<pre><code class="language-jsx">pm2 start index.js</code></pre>
<pre><code class="language-jsx">pm2 ls</code></pre>
<p>이렇게 했을때 에러가 나있다면 </p>
<p>관리자 권한이 없어서 에러가 나는 문제다 </p>
<p>그땐 authbind를 설치해주자</p>
<pre><code class="language-jsx">sudo apt-get update</code></pre>
<pre><code class="language-jsx">sudo apt-get install authbind</code></pre>
<pre><code class="language-jsx">sudo touch /etc/authbind/byport/80</code></pre>
<pre><code class="language-jsx">sudo chown ubuntu /etc/authbind/byport/80</code></pre>
<pre><code class="language-jsx">sudo chmod 755 /etc/authbind/byport/80</code></pre>
<pre><code class="language-jsx">authbind --deep pm2 update</code></pre>
<ul>
<li>authbind의 설치를 완료한 뒤, 먼저 &#39;pm2 ls&#39; 명령어를 통해 어떤 프로그램이 PM2의 프로세스 리스트에 등록되어 있는지 확인한다.</li>
<li>&#39;app&#39; 프로세스가 리스트에 있다면 &#39;pm2 delete app.js&#39; 명령어를 통해 프로세스를 삭제 할 수 있다.</li>
<li>authbind 설치 전에 실행되고 있던 프로세스에는 관리자 권한을 부여하지 못하기 때문이다.</li>
<li>PM2에 관리자 권한을 부여하기 위해서는 &#39;authbind --deep&#39; 명령어를 앞에 추가해야 한다.</li>
<li>&#39;authbind --deep pm2 start app.js&#39; 명령어를 통해 서버를 다시 실행하면 이번에는 문제없이 작동할 것이다.</li>
</ul>
<p>끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[S3 구축]]></title>
            <link>https://velog.io/@pingu-/S3</link>
            <guid>https://velog.io/@pingu-/S3</guid>
            <pubDate>Fri, 13 May 2022 12:27:15 GMT</pubDate>
            <description><![CDATA[<h1 id="s3">S3</h1>
<p>이번엔 프론트엔드에서 빌드한 파일을 담는 버킷인 S3를 구축해보자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/77c1e009-ca00-462b-830a-143ecba67fab/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/d8ad7806-db44-4991-b3fd-f9520b6fba29/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/093fb477-1b75-4cfc-a6a4-3e29c2875c26/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/0242bcbb-a949-4783-a6b0-1f5fcaa549f7/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/afafdf5c-7605-493a-9697-1e29db1e20b7/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/47bc53dd-9220-45fa-be73-9a92a93d7c8b/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/25479493-3071-4017-895d-c214344c26bf/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/468b1f87-1bb4-4878-93a7-8fd2ed7dead0/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/8c3e40a1-1bd4-4afc-bd38-eef90e18015c/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/20c2a78c-2bd3-4665-bcd3-27b030ce3b84/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/33c1fbf9-7822-4243-9ae3-6110bb28e0d6/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/cebdf349-8106-4d2f-93ad-95fc60ff8419/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/6eb5753b-0a0c-4f7e-bc4e-867bc9902361/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/0ab227c4-6741-4aa3-8c5b-9ae18fdbe4ab/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/a75e5138-315e-4ed5-a520-a5215070d9e2/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/d8b35854-0489-4ac1-8bab-2fc95b765e06/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/d9ae8a9a-266a-4f39-b1b1-4f44929e69ea/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/4a28348c-f937-4d46-9000-3d2ad9880356/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/c3f120f2-f871-4284-8a61-f7c782fc5db4/image.png" alt=""></p>
<p>빌드 전에 서버 api 주소를 바꿔주고 빌드하자</p>
<p>끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[EC2 구축]]></title>
            <link>https://velog.io/@pingu-/EC2-%EA%B5%AC%EC%B6%95</link>
            <guid>https://velog.io/@pingu-/EC2-%EA%B5%AC%EC%B6%95</guid>
            <pubDate>Wed, 11 May 2022 10:31:56 GMT</pubDate>
            <description><![CDATA[<h1 id="ec2">EC2</h1>
<p>컴퓨터를 대여해서 작성한 서버 코드를 넣어둘 EC2를 구축해보자</p>
<img src="https://velog.velcdn.com/images/pingu-/post/4f1710a5-ffc2-4244-9154-adb402dea3fc/image.png" width="50%" />


<p>현재 나의 서버 구현 상태이다 </p>
<p>스택은 node.js + express + typeorm 을 사용했다
<img src="https://velog.velcdn.com/images/pingu-/post/ffbf5d25-8348-498a-bf4f-4c22f87f8cf9/image.png" width="30%" /></p>
<p>모두 미국 동부 (버지니아 북부)에서 생성했음<img src="https://velog.velcdn.com/images/pingu-/post/4d110070-b04f-4c8c-8ebd-9c2c8c3bc466/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/cf87410d-e2e7-4ca1-879e-4de7598ac982/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/9e6736e0-e027-4646-ba5f-9149951061b6/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/734ef681-713a-43fb-a966-40f108fd1865/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/55937342-cd88-4612-878c-2f389ff133cb/image.png" alt=""></p>
<p>이제 인스턴스 보기를 눌러 인스턴스에서 ec2가 대기중에서 실행 중으로 켜질때 까지 기다리자</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/ae976b16-534e-439e-a255-49987adf895c/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/e41ab28e-24bd-4702-80d3-36fce82e1e56/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/6809eea3-145b-4fe2-bec2-6152706bb217/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/9d20377d-b0be-46ed-8eea-72b3a47d2800/image.png" alt=""></p>
<hr>
<hr>
<p><img src="https://velog.velcdn.com/images/pingu-/post/c251e444-a7ee-4281-8607-e3b7dd5c6c29/image.png" alt=""></p>
<p>규칙 추가를 눌러서 http, https와 내 서버 포트까지 추가해주고 규칙 저장</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/8c89f096-7dd4-4607-868b-2c6f1eea637f/image.png" alt=""></p>
<p>체크후 연결 클릭</p>
<p><img src="https://velog.velcdn.com/images/pingu-/post/4d15245f-c7f6-40cd-a39f-30920517095f/image.png" alt=""></p>
<p>1번 표시된 명령어를 터미널을 키고 인스턴스 생성할때 만든 키페어의 위치에서 사용해준다</p>
<p>그 후 2번표시의 명령어를 키페어의 위치에서 사용하게되면 주르륵 글씨가 올라오면서 중간에 뭘 묻는데 yes로 입력해주고 넘기면 ec2 우분투 가상컴퓨터에 접속이 완료가 되었다</p>
<p>ubuntu@ip-(ec2ip):~$</p>
<p>이런식으로 뜬다</p>
<pre><code class="language-jsx">wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash</code></pre>
<p>위 명령어로 nvm 설치후 터미널을 껏다 킨다</p>
<pre><code class="language-jsx">nvm list</code></pre>
<p>위 명령어로 node 버전을 찾은후 nvm install (버전) 으로 받는다</p>
<pre><code class="language-jsx">sudo apt-get install git</code></pre>
<pre><code class="language-jsx">sudo apt-get update</code></pre>
<pre><code class="language-jsx">git clone</code></pre>
<p>끝</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[require와 import 차이]]></title>
            <link>https://velog.io/@pingu-/require%EC%99%80-import-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@pingu-/require%EC%99%80-import-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Mon, 09 May 2022 14:39:50 GMT</pubDate>
            <description><![CDATA[<h1 id="require과-import의-차이">require과 import의 차이</h1>
<p>원래 기존까지는 Node.js 개발 환경에서 모듈을 불러올 때 기존의 자바스크립트가 지원하는 방식대로 require / exports 를 사용했다. 그러나 React나 Vue를 쓴 코드에서는 import react from &#39;react&#39;와 같이 모듈을 export로 정의하고 import로 불러오는 코드들을 볼 수 있었다.</p>
<p>require / exports 는 기존까지 Node.js에서 사용되던 CommonJs 모듈 방식으로, module.exports 객체에 모듈 전체를 치환하여 내보내고, require을 통해 해당 모듈을 불러오는 방식이다. 따라서 CommonJs 모듈 방식으로는 전체 모듈을 다 불러오게 되고, 불필요한 모듈이 로드되기도 하고 모듈 내에서 어떤 부분을 사용했는지도 확인할 수 없다.</p>
<p>때문에 ES6(ECMA2015)부터는 import / export 라는 방식으로 모듈을 불러오고 내보낸다. ES 모듈의 import는 require과는 다르게</p>
<p>import {name} from &#39;module&#39;
과 같이 모듈내에 정의된 특정한 부분만을 불러올 수 있다.</p>
<p>자세한 import와 export에 대한 설명은 링크로 대체한다.</p>
<p>다른 ES6 문법들, 이를테면 let이나 const, arrow function 등이 Node.js 상에서 정상적으로 작동하기 때문에, ES 모듈도 당연히 불러올 수 있을 거라고 생각했지만, Node.js에서 import를 사용하니 ES 모듈을 불러올 수 없다는 오류가 발생했다.</p>
<p>여러 자료들을 찾아본 결과, Node.js가 최신 자바스크립트 문법들은 지원하지만, 모듈 시스템으로 CommonJs를 채택했기 때문에 ES 모듈 시스템은 사용할 수 없다고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[회고]]></title>
            <link>https://velog.io/@pingu-/%ED%9A%8C%EA%B3%A0-y91pmn6d</link>
            <guid>https://velog.io/@pingu-/%ED%9A%8C%EA%B3%A0-y91pmn6d</guid>
            <pubDate>Sun, 08 May 2022 14:07:51 GMT</pubDate>
            <description><![CDATA[<h1 id="nest">nest</h1>
<p>nest는 나중에 연습삼아 하는것으로 결정했다.
express를 확실하게 배워야 그 토대로 nest를 파생시켜 나갈 수 있는데
express를 겉핥기로 배웠더니 nest도 생각보다 어렵게 느껴졌다.
아무래도 타입스크립트가 갑자기 더해져서 크게 다가온것처럼 보인다.
지금 하고 있는 개인 프로젝트를 express로 변환시켜야겠다.</p>
<h1 id="알고리즘">알고리즘</h1>
<p>여전히 2레벨은 뜨문뜨문으로 풀린다.
이래서 취업할때 알고리즘을 풀수 있을지 미지수다..</p>
<blockquote>
<p>취업때문에 불안한 마음이 크다
이력서를 넣어도 연락이 없으니 이력서가 문제인가 학력이 문제인가 포트폴리오가 문제인가 
심란하다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터 전송 코드 시스템]]></title>
            <link>https://velog.io/@pingu-/d</link>
            <guid>https://velog.io/@pingu-/d</guid>
            <pubDate>Fri, 06 May 2022 14:56:01 GMT</pubDate>
            <description><![CDATA[<h1 id="프레임">프레임</h1>
<h2 id="개념">개념</h2>
<ul>
<li>데이터 통신망에서 하나의 블록 또는 패킷으로 전송되는 정보의 단위</li>
<li>데이터 프레임은 망의 데이터 링크층 프로토콜에 의하여 정의되며 망 노드 간의 매체(선로)상에서만 존재함 </li>
<li>프레임은 다른 layer들에서는 다른 형식을 취하고, 데이터는 데이터 프레임의 시작 및 끝 제어 정보 사이에 위치함</li>
<li>프레임은 내부 정보를 표현하는 방식에 따라 문자 프레임과 비트 프레임으로 나눔<h2 id="문자-프레임">문자 프레임</h2>
</li>
<li>문자 프레임은 프레임의 내용이 문자로만 구성</li>
<li>8비트 단위(또는 ASCII 문자 코드)의 고정 크기로 동작</li>
<li>문자 프레임은 프레임의 내용이 문자로만 구성</li>
<li>프레임구분<ul>
<li>프레임의 시작과 끝에 특수 문자를 사용하여 구분하는데 시작에는 DLE/STX가 나오고 끝에는 DLE/ETX를 두어 프레임을 다른 정보와 구분</li>
<li>하지만 데이터 안에도 DLE/STX나 DLE/ETX 와 같은 동일 명령어가 포함되어 있을 수 있어 데이터를 읽는 과정에서 혼선을 일으킬 수 있음<ul>
<li>이러한 문제를 해결하기 위해 문자 스터핑이라는 기법을 사용 </li>
</ul>
</li>
<li>문자 스터핑은 데이터에 DLE가 존재하면 강제로 DLE를 추가하는 작업을 한다. <ul>
<li>DLE가 두 개가 연달아 나오게 되기 때문에 특수 문자로 인식하지 않는다. </li>
<li>수신측에서 두 개의 DLE가 나오면 뒤에 있는 DLE를 제거하여 데이터를 읽는다. <h2 id="프레임-구조">프레임 구조</h2>
</li>
</ul>
</li>
</ul>
</li>
<li>프레임 구조<ul>
<li>프레임의 시작과 끝에 특수 문자 사용 <ul>
<li>시작 : DLE / STX</li>
<li>끝 : DLE / ETX</li>
</ul>
</li>
<li>전송 데이터에 특수 문자가 포함되면 혼선이 발생 
<img src="https://velog.velcdn.com/images/pingu-/post/7c659029-acb2-40bc-8967-aa4df117a41e/image.png" alt=""><center>문자 프레임 구조</center></li>
</ul>
</li>
<li>문자 스터핑Character Stuffing<ul>
<li>문자 프레임의 전송 과정에서 제어 문자를 추가하는 기능
<img src="https://velog.velcdn.com/images/pingu-/post/04f010a5-274d-4af5-9380-b157d14b6cee/image.png" alt=""><center>문자 스터핑 구조</center>


</li>
</ul>
</li>
</ul>
<ul>
<li>전송 데이터가 DLE 문자를 포함하면 뒤에 DLE 문자 하나를 강제 추가</li>
<li>데이터에 DLE 문자가 두 번 연속 있으면 하나의 DLE 문자 삭제 </li>
<li>비트 프레임Bit Frame <ul>
<li>프레임의 시작과 끝 위치에 플래그라는 특수하게 정의된 비트 패턴(01111110)을 사용해 프레임 단위를 구분</li>
</ul>
</li>
<li>비트 프레임의 구조<ul>
<li>데이터 전송 전에 프레임의 좌우에 플래그를 추가, 수신 호스트는 이 플래그를 제거해 전송 데이터와 필요한 제어 정보를 상위 계층 전달
<img src="https://velog.velcdn.com/images/pingu-/post/c1656ca3-ab66-4b37-aabf-3d6f6f3794d4/image.png" alt=""><center>비트 프레임 구조</center>


</li>
</ul>
</li>
</ul>
<ul>
<li>비트 스터핑Bit Stuffing 알고리즘<ul>
<li>전송 데이터에 플래그 패턴이 포함되면 혼선이 발생</li>
<li>송신 호스트 : 전송 데이터가  1이 연속해서 5번 발생하면 강제로 0을 추가</li>
<li>수신 호스트 : 송신 과정에 추가된 0을 제거하여 원래의 데이터를 상위 계층 전달
<img src="https://velog.velcdn.com/images/pingu-/post/923b05eb-42c1-47c0-86b0-a9f76a376103/image.png" alt=""><center>비트 스터핑 구조</center>
# 다항 코드 
## 개념</li>
</ul>
</li>
<li>다항코드는 CRC로 알려졌는데 현재의 통신 프로토콜에서 가장 많이 사용하는 오류 검출 방법</li>
<li>다항코드는 다항식을 형태를 기반으로 오류를 검출하는 방법<h2 id="오류를-극복하는-방법">오류를 극복하는 방법</h2>
</li>
<li>전송 프레임에 오류 검출 코드를 넣어 수신 호스트가 전송 과정의 오류를 검출</li>
<li>순방향 오류 복구FEC, Forward Error Correction  : 오류 복구 코드를 사용해 수신 호스트가 오류 복구 기능을 수행하는 방식<h2 id="오류-검출">오류 검출</h2>
</li>
<li>역방향 오류 복구BEC, Backward Error Correction (ARQAutomatic Repeat reQuest 방식)<ul>
<li>재전송 방식을 이용해 오류 복구(네트워크에서 일반적으로 사용)</li>
</ul>
</li>
<li>패리티Parity 비트<ul>
<li>1 바이트(8비트) = 7 비트 ASCII 코드 + 1 패리티 비트-</li>
<li>짝수 패리티 : 데이터 끝에 패리티 비트를 추가해 전체 1의 개수를 짝수로 만듦</li>
<li>홀수 패리티 : 1의 개수를 홀수로 만드는 것</li>
<li>송신 호스트와 수신 호스트는 동일한 패리티 방식을 사용해야 함
<img src="https://velog.velcdn.com/images/pingu-/post/f940ed34-5fd3-4f5a-a206-8a513adb7bd8/image.png" alt=""><center>parity bit 구조</center>


</li>
</ul>
</li>
</ul>
<h2 id="다항-코드-polynomial-code">다항 코드 Polynomial Code</h2>
<ul>
<li>블록 검사<ul>
<li>짝수개의 비트가 깨지는 오류를 검출</li>
<li>수평, 수직 방향 모두에 패리티 비트를 지정
<img src="https://velog.velcdn.com/images/pingu-/post/8d6326ee-a8b7-4b23-96ad-25b9f50cfdd2/image.png" alt=""><center>블록 검사</center>
## 생성 다항식(CRCCyclic Redundancy Code)</li>
</ul>
</li>
<li>CRC 처리과정: 송신측</li>
</ul>
<ol>
<li>임의의 CRC 발생코드를 선정</li>
<li>CRC 발생코드의 최고차 차수만큼 원래 데이터의 뒤에 ‘0’을 붙임 </li>
<li>확장데이터(=원래 데이터+데이터 뒤에 붙인 ‘0’)을 modul0-2 연산을 사용-CRC 발생코드로 나눔</li>
<li>나머지가 ‘0’이면 확장 데이터를 그대로 전송함</li>
<li>나머지가 ‘0’이 아니면 원래데이터에 나머지를 붙여 전송함</li>
</ol>
<ul>
<li>CRC 처리과정: 송신측</li>
</ul>
<ol>
<li>수신 장치는 수신된 코드를 동일한 CRC 발생코드로 나눔</li>
<li>나머지가 ‘0’이면 오류가 발생하지 않은 것이고, 만약 나머지가 ‘0’이 아니면 전송과정에서 오류가 발생한 것으로 판단</li>
</ol>
<ul>
<li>CRC 처리과정에서 MODULO-2 연산사용</li>
<li>이때 mod-2 연산은 EX-OR 연산
<img src="https://velog.velcdn.com/images/pingu-/post/24f50704-f101-4045-a7ae-00079a4fc6a2/image.png" alt=""></li>
<li>CRC 예<ul>
<li>CRC 발생코드를 P(X)를 아래와 같이 설정
<img src="https://velog.velcdn.com/images/pingu-/post/a9975c05-a722-4c07-a2c9-c1e96bab896b/image.png" alt=""></li>
</ul>
</li>
<li>CRC 발생코드가 ‘1101’처럼 주어지고 주어지기도 하고 좌측처럼 다항식으로 주어지기도 함</li>
<li>만약 다항식으로 주어지면 위의 예처럼 2진 코드로 변환해야 함</li>
<li>전송할 데이터가 G(X)가 ‘110010’이라고 하면, CRC 발생코드의 최고차 차수가 3이므로 G(x) 뒤에 ‘0’을 3개 붙여서 확장 데이터 ‘110010000’을 만듦
<img src="https://velog.velcdn.com/images/pingu-/post/d7343560-18f7-4d06-b409-d0d7ce17dfd6/image.png" alt=""></li>
<li>이제 확장 데이터를 CRC 발생코드 ‘1101’로 나누는데 이때 앞에서 말한 modulo-2연산을 이용함
<img src="https://velog.velcdn.com/images/pingu-/post/e2cc4308-8e9e-4ee7-bf30-76bba4c0091d/image.png" alt=""></li>
<li>나머지 비트수는 CRC 발생코드의 최고차 차스와 같음</li>
<li>정보(데이터) ‘110010’에 CRC ‘100’을 붙인 ‘110010100’ 이 전송되는 전송코드임</li>
<li>이제 수신측에서 전송 데이터 오류가 있는 지 알아보면 수신된 코드를 동일한 CRC 발생코드로 나눔
<img src="https://velog.velcdn.com/images/pingu-/post/c3afd305-6356-4b0e-bbb7-d206fc336dd4/image.png" alt=""></li>
<li>나머지가 ’0‘입니다. 즉, 오류가 없습니다.</li>
</ul>
<p>이미지 출처- 배움사이버교육 (신은섭 교수)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MVC 패턴]]></title>
            <link>https://velog.io/@pingu-/MVC-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@pingu-/MVC-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Wed, 04 May 2022 14:27:30 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/pingu-/post/ec6f9408-e3ae-43a6-9b44-81a5b4054771/image.png" alt=""></p>
<h1 id="mvc-패턴이란">MVC 패턴이란?</h1>
<blockquote>
<p>MVC란, Model View Controller의 약자로 소프트웨어 공학에서 사용되는 소프트웨어 디자인 패턴이며 애플리케이션을 세가지 역할로 구분한 개발 방법론이다. </p>
</blockquote>
<ul>
<li>Model: 데이터를 가지고 있거나 데이터베이스로부터 받아온 값들을 Controller와 교류한다.</li>
<li>View: 사용자에게 보여지는 부분(UI)이고 Controller와 교류한다.</li>
<li>Controller: View와 Model에게서 액션과 인풋값을 받고 가공하여 교류한다.</li>
<li>이렇게 각자의 역할을 분리함으로서 유지 보수를 용이하게 하고 프로그램의 확장성과 유연성을 높일 수 있다.</li>
</ul>
<h2 id="장점">장점</h2>
<ul>
<li>애플리케이션 확장성, 유연성증가</li>
<li>각자의 목적에 맞는 분리된 코드를 통해 중복 최소화<h2 id="단점">단점</h2>
</li>
<li>View와 Model의 의존성으로 인해 구조가 복잡해질 수 있다.</li>
<li>Model은 다수의 View를 가질 수 있고 반대로 Controller를 통해 한 View에 연결되는 Model도 여러개가 될 수 있다.</li>
<li>이런 관계는 View와 Model의 의존성을 높이게 된다. 좋은 설계로 의존성을 줄일 수는 있겠지만
Controller에 다수의 Model과 View가 연결되는 복잡한 상황이 유발 되는 상황을 피하기는 쉽지않다.</li>
<li>결국, MVC 규모가 비대해지고 복잡해지며 새 기능을 추가할 때마다 의존성을 일일이 해결해야 하는 상황이 오게 된다.
이런 형태의 MVC를 MassiveViewController라고 부른다. MVC의 한계를 표현하는 용어이기도 하다.</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>