<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>cong_.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sun, 27 Mar 2022 10:27:33 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>cong_.log</title>
            <url>https://images.velog.io/images/cong_/profile/277cf5dc-bbf7-4278-a144-ded11dde6f64/KakaoTalk_Photo_2021-04-17-22-55-45.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. cong_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/cong_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2022.03.27 TIL]]></title>
            <link>https://velog.io/@cong_/2022.03.27-TIL</link>
            <guid>https://velog.io/@cong_/2022.03.27-TIL</guid>
            <pubDate>Sun, 27 Mar 2022 10:27:33 GMT</pubDate>
            <description><![CDATA[<p>0.Token
1.WebAssembly</p>
<h2 id="token">Token</h2>
<p>토큰 기반 시스템은 stateless 이다. 즉 상태를 유지하지 않는다해서 무상태라고 한다.</p>
<p>이 시스템은 사용자의 인증 정보를 서버나 세션에 담지 않는다. </p>
<p>세션이 존재하지 않아 사용자들의 로그인 유무에 관계없이 서버를 손쉽게 확장할 수 있다. </p>
<p>토큰 기반 시스템의 구현 방식은 시스템마다 크고 작은 차이가 있지만, 대략적으로 보면 아래와 같다.</p>
<ol>
<li>사용자가 ID 와 PW 로 로그인을 한다.</li>
<li>서버측에서 해당 계정 정보를 검증한다.</li>
<li>계정 정보가 정확하다면, 서버측에서 사용자에게 <strong>signed</strong> 토큰을 발급해준다.
(여기서 <strong>signed</strong>의 의미는 해탕 토큰이 서버에서 정상적으로 발급된 토큰임을 증명하는 <strong>signature</strong>를 지니고 있다는 말이다.)</li>
<li>클라이언트 측에서 전달받은 토큰을 저장해두고, 서버에 요청할 때 마다 해탕 토큰을 함께 서버에 전달한다.</li>
<li>서버는 토큰을 검증하고 요청에 응답한다.</li>
</ol>
<h3 id="토큰의-장점">토큰의 장점</h3>
<p><strong>무상태(Stateless)와 확장성(Scalability)</strong>
client side 에 토큰을 저장하기때문에 완전한 무상태(Stateless)이며,서버를 확장하기에 매우 적합한 환경을 제공한다. </p>
<p>세션을 서버측에 저장하고 있고, 여러대의 서버를 사용하여 사용자의 요청을 분산해두었다고 가정해보자. 어떤 한 사용자가 로그인하기 위해서는 처음에 로그인했었던 서버로 요청을 보내도록 설정을 해주어야지만, 사용자에게 결과값을 전달할 수 있다. 하지만, 토큰을 사용하게 된다면 어떤 서버로 사용자가 요청하여도 결과값을 받는데에 무관하다. </p>
<p><strong>보안성</strong>
클라이언트가 토큰을 통해 서버로 요청을 보낼 때, 더 이상 쿠키를 전달하지 않음으로 쿠키를 사용함으로 인해 발생하는 취약점이 사라진다. 하지만, 토큰을 사용하는 환경에서도 취약점이 존재할 수 있으니 언제나 대비해야 한다.</p>
<p><strong>확장성(Extensibility)</strong>
여기서 말하는 확장성(Extensibility)은 앞서 말한 확장성(Scalability)과는 다른 개념이다.
Scalability 은 서버를 확장하는걸 의미하는 반면, Extensibility 는 로그인 정보가 사용되는 분야를 확장하는 것을 의미한다. 토큰을 사용하여 다른 서비스에서도 권한을 공유할 수 있다. 예를 들어 어떤 브라우저에서는 Facebook, LinkedIn, Github, Google 계정으로 로그인 할 수 있다. 토큰 기반 시스템에서는 토큰에 선택적인 권한만 부여하여 발급을 할 수 있다. </p>
<h2 id="webassembly">WebAssembly</h2>
<p>웹 어셈블리는 C, C++ 과 같은 프로그래밍 언어를 컴파일해서 브라우저의 종류에 상관없이 빠르게 실행되는 바이너리형식(0과 1로 이루어진 형식)으로 바꿔주는 기술을 말한다.</p>
<p>일반적으로 웹 어플리케이션을 개발할 때 사용하는 언어는 html, css, js이며 이중 js는 동적인 부분을 개발한다. 최근에는 js의 속도가 빨라졌지만, 아직 C, C++ 과 같은 언어들에 비해 느리다.</p>
<p>기존의 개발은 js로 개발하다보니 게임이나 동영상 편집기 등과 같은 고성능의 어플리케이션은 브라우저에서 동작하는데 어려움이 있다. </p>
<p>웹 어셈블리는 웹 플랫폼에서 이전에는 불가능했던 클라이언트 응용 프로그램을 사용해 웹에서 여러 언어로 작성되 코드를 네이티브에 가까우 속도로 실행되는 길을 제공한다.</p>
<p>웹 어셈블리 모듈은 웹앱으로 가져와서 js를 통해 사용할 수 있게 할 수 있다. js 프레임워크는 웹 어셈블리를 사용해서 대규모 성능 이점과 새로운 기능을 제공하면서 웹 개발자가 쉽게 기능을 사용할 수 있도록 할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022.03.20 TIL]]></title>
            <link>https://velog.io/@cong_/2022.03.20-TIL</link>
            <guid>https://velog.io/@cong_/2022.03.20-TIL</guid>
            <pubDate>Sun, 20 Mar 2022 08:00:35 GMT</pubDate>
            <description><![CDATA[<h3 id="동기synchronous-비동기asynchronous">동기(synchronous) 비동기(asynchronous)</h3>
<p>동기와 비동기를 나누는 가장 큰 차이점은 <strong>실행순서</strong>이다.</p>
<p>동기식은 요청을 보낸 후 해당하는 응답을 받아야지만 다음으로 넘어갈 수 있는 실행방식이며, 반대로 비동기식은 요청을 보낸 후 응답과 관계없이 다음 동작을 실행 할 수 있는 실행방식이다.</p>
<h3 id="비동식-방식을-처리하는-방법들">비동식 방식을 처리하는 방법들</h3>
<p>callback(), promise, async/await 사용하는 이유는 비동기적 방식을 처리하는 방법들을 사용하지 않는다면 콜백 함수의 과정이 끝나기 전에 다음 프로세스로 진행될 수 있기때문이다. </p>
<p>예를 들어 동영상 파일을 불러와 웹에 띄어줄려고 하는데 여기서 비디오 파일을 불러오는 작업이 완료되지 않았는데 다음 프로세스로 넘어가 화면에 동영상 파일을 띄어주려한다면,</p>
<p>비동기식 처리 방식을 사용하지 않았을때, 비디오 파일을 불러오는중.. -&gt; 다음 프로세스 실행 -&gt; 비디오 출력 -&gt; 에러</p>
<p>비동기식 처리 방식을 사용했을 때, 비디오파일을 불러오는중.. -&gt; 비디오 파일을 모두다 불러옴 -&gt; 다음 프로세스 실행 -&gt; 비디오 정상 출력</p>
<h3 id="promise">Promise</h3>
<p>Promise를 정의할때에 인자값으로 <strong>resolve,reject</strong> 전달한다. 
안에서 resolve는 값을 전달할때에, reject는 에러를 전달할 때에 사용되며, promise 수행은 promise 객체를 담은 변수에 then을 사용하여 전달 받은 data는 콘솔창에 출력하여 확인해볼 수 있다. then은 작업수행이 완료되면 실행하게 된다.</p>
<pre><code>const promiseData = new Promise((req, rej) =&gt; {
    res(&quot;sending data&quot;);
 });
 promiseData.then(data =&gt; {
     console.log(data);
 });</code></pre><p>promise 에러는 앞서 설명했던것 처럼 reject 반환을 통해 사용할 수 있다.</p>
<pre><code>const promiseFun = () =&gt; {
    const promiseData = new Promise((res,rej) =&gt; {
        const num = 2;
        if(num === 2)
            res.(&quot;sending data&quot;);
        else
            rej(&quot;error Fun1&quot;);
     });
     return promiseData;
};
const promiseFun2 = () =&gt; {
    const promiseData = new Promise((res,rej) =&gt; {
        const num = 3;
        if(num === 3)
            res.(&quot;sending data2&quot;);
        else
            rej(&quot;error Fun2&quot;);
     });
     return promiseData;
};

promiseFun()
    .then(data =&gt; {
        console.log(data);
        return promiseFun2();
    })
    .then(data =&gt; {
        console.log(data);
    })
    .catch(error =&gt; {
        console.log(error);
    });</code></pre><p>위와 같이 조건문에 의해 에러를 반환해야 할 때에 <strong>return 값으로 reject를 반환</strong> 하면 된다. 그리고 promise 수행 부분에 catch를 사용하면 첫번째 then()에서 에러가 났을 시 그 이후 then은 실행되지 않고 catch 문으로 넘어가서 error문을 반환하게 된다. </p>
<h3 id="async--await">async / await</h3>
<p>async/await는 promise 객체를 반환한다. 따라서 promise 객체에서 사용했던 then을 사용할 수 있다. </p>
<pre><code>const asyncFun = async () =&gt; {
    return &quot;This is async test&quot;;
};

async asyncFun() =&gt; {
    return &quot;This is async test&quot;;
}; </code></pre><p>함수 선언은 위와 같이 두가지 종류로 선언할 수 있다.
async는 함수를 promise 로 return 하는 함수로 만든다. 
앞서 promise 에서 값을 전달 할때에는 resolve를 통해 전달 했었다. 반면async/await는 return 으로 값을 전달한다.</p>
<pre><code>const asyncFun = async () =&gt; {
    return &quot;This is async return data&quot;;
};

asyncFun.then(data =&gt; {
    console.log(data);
});</code></pre><p>await는 비동기 처리 방식을 위한 실행 완료까지 기다리게 하는 함수이다.</p>
<pre><code>const delayFun = sec =&gt; {
    const promiseData = new Promise((res,rej) =&gt; {
        setTilmeout(() =&gt; {
            res(console.log(&quot;Start in&quot; + sec + &quot;sec.&quot; );
         }, sec * 1000);
     });
     return promiseData;
};

const asyncFun = async () =&gt; {
    delayFun(3);
    return &quot;async.&quot;;
};

asyncFun().then(result =&gt; {
    console.log(result);
});</code></pre><blockquote>
<p> await 사용전 결과 값 : 
    async.
    Start in 3 sec.</p>
</blockquote>
<pre><code>const delayFun = sec =&gt; {
    const promiseData = new Promise((res,rej) =&gt; {
        setTilmeout(() =&gt; {
            res(console.log(&quot;Start in&quot; + sec + &quot;sec.&quot; );
         }, sec * 1000);
     });
     return promiseData;
};

const asyncFun = async () =&gt; {
    await delayFun(3);
    return &quot;async.&quot;;
};

asyncFun().then(result =&gt; {
    console.log(result);
});</code></pre><blockquote>
<p> await 사용후 결과 값 : 
    Start in 3 sec.
    async.</p>
</blockquote>
<p><a href="https://studyingych.tistory.com/63">참고 블로그</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022.1.25 TIL]]></title>
            <link>https://velog.io/@cong_/2022.1.25-TIL</link>
            <guid>https://velog.io/@cong_/2022.1.25-TIL</guid>
            <pubDate>Tue, 25 Jan 2022 09:07:43 GMT</pubDate>
            <description><![CDATA[<ol start="0">
<li>Styled Component</li>
<li>React Query</li>
<li>React Helmet</li>
</ol>
<h3 id="styled-component">Styled Component</h3>
<p><strong>styled-comoponent 란?</strong> </p>
<p>Javascript 파일내에서 CSS를 사용할 수 있게 해주는 대표적인 CSS-in-JS라이브러리로 React프레임워크를 주요 대상으로 한 라이브러리이다.</p>
<p>styled-component 는 css의 클래스 네임 중복 사용 시 생기는 버그 방지와 구조적으로 컴포넌트와 스타일이 묶여있어 관리에 용이하다.</p>
<p><strong>styled-component 사용</strong></p>
<pre><code>import React from &quot;react&quot;;
import styled from &quot;styled-component&quot;;

const Container = styled.div`
    color: white;
    background-color: grey;
    p{
        font-size: 24px;
    }
    &amp;:hover{
        color: blue;
    }
`;

function App() {
    return (
        &lt;Container&gt;
            &lt;p&gt;Hello&lt;/p&gt;
        &lt;/Container&gt;
    )
}

export default App</code></pre><p>기본적으로 위 코드와 같이 사용되며, styled-component는 props를 활용할 수 있다.</p>
<p><strong>styled-component의 props 사용</strong></p>
<pre><code>import React from &quot;react&quot;;
import styled from &quot;styled-component&quot;;

const Container = styled.div`
    color: ${(props) =&gt; props.color || &quot;white&quot;};
    background-color: grey;
    p{
        font-size: 24px;
    }
    &amp;:hover{
        color: blue;
    }
`;

function App() {
    return (
        &lt;Container&gt;
            &lt;p&gt;Hello&lt;/p&gt;
        &lt;/Container&gt;
    )
}

export default App</code></pre><p>color에 대한 props가 존재할 시 해당 색상을 출력하고 없을 시 흰색으로 출력할 수 있다.</p>
<h3 id="react-query">React Query</h3>
<p><strong>react-query 란?</strong></p>
<p>서버의 값을 클라이언트에 가져오거나, 캐싱, 값 업데이트, 에러핸들링 등 비동기 과정을 더욱 편하게 하는데 사용되는 라이브러리이다. </p>
<p>react-query 는 아래와 같은 장점이 있다.</p>
<p>✅ 간결한 fetch 로직</p>
<p>기존의 데이터 fetch에는 로딩 상태 관리, 페칭한 데이터 관리 등을 위해 여러 훅을 사용했으나, react-query를 사용하면 간결하게 fetch 로직을 작성할 수 있다. </p>
<p>✅ fetcher 함수를 따로 분리하여 컴포넌트로 만들 수 있다.</p>
<p>✅ casing(데이터를 캐시에 저장) 을 하기 때문에, 데이터 손실을 방지할 수 있다.</p>
<h3 id="react-helmet">React Helmet</h3>
<p>웹 문서의 헤더 값을 변경할 때 사용하는 리액트 컴포넌트이다. React를 사용할 때에는 컴포넌트에 head 태그를 직접 지정하는게 어려우나 react-helmet을 사용하면 변경이 쉽다. </p>
<p><strong>react-helmet 사용</strong></p>
<pre><code>import React from &quot;react&quot;;
import { Helmet } from &quot;react-helmet&quot;;

function App (){
    return(
        &lt;div&gt;
            &lt;Helmet&gt;
                &lt;title&gt;사이트 제목&lt;/title&gt;
            &lt;/Helmet&gt;
        &lt;/div&gt;
    )
}
export default App</code></pre><p>위와 같이 코드를 적용하면 웹 문서의 title이 변경되어 출력되는 것을 확인할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022.1.24 TIL]]></title>
            <link>https://velog.io/@cong_/2022.1.24-TIL</link>
            <guid>https://velog.io/@cong_/2022.1.24-TIL</guid>
            <pubDate>Mon, 24 Jan 2022 08:24:31 GMT</pubDate>
            <description><![CDATA[<p>0.browser에서 Object keys 값 출력하는 방법
1.browser에서 Object values 값 출력하는 방법
2.Join()사용
3.Map()사용</p>
<h3 id="browser에서-object-keys-값만-출력하는-방법">browser에서 Object keys 값만 출력하는 방법</h3>
<p>예제 소스 </p>
<pre><code>function learn(){

  var info = { name: &quot;한이&quot;, gender: &quot;남성&quot;, eyecolor: &quot;검정색&quot;, age: &quot;28&quot; };

  console.log(info);
}</code></pre><ol>
<li><p>console.log() 함수로 부터 info가 브라우저 콘솔 창에 아래와 같이 출력된다.
<img src="https://images.velog.io/images/cong_/post/b2b0f4c2-9407-4279-982a-e0e7d81e8b8e/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-24%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.08.06.png" alt=""></p>
</li>
<li><p>브라우저 콘솔창에서 마우스 우클릭으로 출력물을 클릭한다.
<img src="https://images.velog.io/images/cong_/post/e8c160da-2be5-46e9-a095-d02a7dc06bfa/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-24%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.13.35.png" alt=""></p>
</li>
<li><p>&#39;전역 변수로 Object 저장&#39; 을 클릭한다. 클릭 후 아래 이미지와 같이 출력된다.
<img src="https://images.velog.io/images/cong_/post/aac4b912-0f36-4147-ac1e-e332c0b225d3/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-24%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.15.50.png" alt=""></p>
</li>
<li><p>브라우저 콘솔창에서 <code>Object.keys(temp1)</code> 입력하면 객체의 key값만 출력이 가능하다.
<img src="https://images.velog.io/images/cong_/post/bc0132e3-6416-41d1-9be4-32c9caf378ec/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-24%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.17.46.png" alt=""></p>
</li>
</ol>
<h3 id="browser에서-object-values-값-출력하는-방법">browser에서 Object values 값 출력하는 방법</h3>
<p>브라우저 콘솔창에서 <code>Object.values(temp1)</code> 입력하면 객체의 key값만 출력이 가능하다.
<img src="https://images.velog.io/images/cong_/post/1ddf8416-d881-458e-beef-b5aa2e2f8340/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-24%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.20.18.png" alt=""></p>
<h3 id="join사용">Join()사용</h3>
<p><code>Object.values(temp1).join()</code>
<code>Object.keys(temp1).join()</code> 
위와 같이 join()을 붙이게되면 값이 list 형식으로 출력되지 않고 string 으로 출력된다.
<img src="https://images.velog.io/images/cong_/post/d3344782-7356-41bf-9888-454eb7dc5f73/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-24%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.33.24.png" alt=""></p>
<h3 id="map사용">Map()사용</h3>
<p><code>Object.values(temp1).map(v =&gt; typeof v)</code> 
<code>Object.values(temp1).map(v =&gt; typeof v).join()</code> 
map() 을 활용하여 value 의 list 형식의 타입을 구할 수 있으며, .join()을 더하면 string 형식의 타입을 구할 수 있다.
<img src="https://images.velog.io/images/cong_/post/5245fe4e-b392-4c98-a6a5-692f7892e808/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-24%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.28.49.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022.1.19 TIL]]></title>
            <link>https://velog.io/@cong_/2022.1.19-TIL</link>
            <guid>https://velog.io/@cong_/2022.1.19-TIL</guid>
            <pubDate>Thu, 20 Jan 2022 06:37:11 GMT</pubDate>
            <description><![CDATA[<p>0.TypeScript의 Interface 사용
1.TypeScript의 Synthetic Event 사용</p>
<h3 id="typescript-interface-사용">TypeScript Interface 사용</h3>
<pre><code>import styled from&quot;styled-component&quot;;

const Container = styled.div``;

interface CircleProps = {
    bgColor:string;
};

function Circle({bgColor}:CircleProps) {
    return &lt;Container bgColor={bgColor} /&gt;
}
</code></pre><blockquote>
</blockquote>
<pre><code>function Circle({bgColor}:CircleProps) {
    return &lt;Container bgColor={bgColor} /&gt;
}</code></pre><p>여기서 Container 태그 안의 bgColor에 빨간 밑줄이 생긴다. 
TypeScript가 봤을 때 Container component가 어떤 props도 받고있지 않기 때문이다.
따라서 TypeScript에게 bgColor를 styled-component에게도 보낼것이라고 알려주어야한다.</p>
<pre><code>interface ContainerProps = {
    bgColor:String;
};

const Container = styled.div&lt;ContainerProps /&gt;``;</code></pre><blockquote>
<p>위와 같이 Container에 대한 interface를 하나더 선언해 주고 Container에게 알려주면 된다.
여기서 ContainerProps와 CircleProps는 하나의 props를 받는 다는 점에서 서로 같은 interface라고 할 수 있다.</p>
</blockquote>
<h3 id="typescript의-synthetic-event-사용">TypeScript의 Synthetic Event 사용</h3>
<pre><code>function APP(){
    const onClick = (event.FormEvent&lt;HTMLButtonElement&gt;) =&gt;{};
    return (
        &lt;form&gt;
            &lt;button onClick={onClick}&gt;click here&lt;/button&gt;
        &lt;/form&gt;
    );
};</code></pre><blockquote>
<p>위 코드에서 <code>event.FormEvent&lt;HTMLButtonElement&gt;</code> 는 react 이벤트이다. 이는 종류가 다양하기 때문에 사용시 필요에 맞게 <a href="https://ko.reactjs.org/docs/events.html#gatsby-focus-wrapper">Synthetic Event</a> React 공홈 Synthetic Event 문서에서 찾아보면 좋겠다.</p>
</blockquote>
<p>React 공홈 Synthetic Event 문서에 들어가보면 아래 이미지와 같이 합성 이벤트의 종류를 확인해볼 수 있다.
<img src="https://images.velog.io/images/cong_/post/1c3a9093-7ab8-4285-9c85-1f1813df0912/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-20%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%203.34.31.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022.1.18 TIL]]></title>
            <link>https://velog.io/@cong_/2022.1.18-TIL</link>
            <guid>https://velog.io/@cong_/2022.1.18-TIL</guid>
            <pubDate>Tue, 18 Jan 2022 08:45:49 GMT</pubDate>
            <description><![CDATA[<p>0.TypeScript
1.TypeScript 와 JavaScript 비교
2.TypeScript 설치하기</p>
<h3 id="typescript">TypeScript</h3>
<p>JavaScript 기반의 언어이며 문법이 동일하다. JavaScript 언어에서 새로운 기능을 살짝 추가한 언어라고 보면 좋을것 같다.</p>
<p><strong>TypeScript 언어는 strongly-typed 이다.</strong> 즉, 프로그래밍 언어가 작동하기 전에 변수의 type을 확인한다. 반면 JavaScript 언어는 strongly-typed 이 아니다.</p>
<h3 id="typescript-와-javascript-비교">TypeScript 와 JavaScript 비교</h3>
<p>JavaScript 언어는 함수에 정의된 변수의 타입을 지정해 주지 않아도 plus()가 실행된다.</p>
<p><del><em>(브라우저 개발자 도구의 콘솔창에서 실행한 이미지이다.)</em></del>
<img src="https://images.velog.io/images/cong_/post/0fda7103-41cd-4541-9f31-06458cb30132/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-18%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.45.20.png" alt=""></p>
<p>반면 TypeScript 는 함수에 정의된 변수의 타입을 지정해주어야한다. 변수의 타입을 지정해 주지않으면 실행 전에 에러문이 발생한다. 더불어 변수 타입 지정함으로써 타입이 달라도 에러문이 발생한다. </p>
<p><del><em>(아래 이미지는 TypeScript 공식 홈페이지의 play ground 테스트 화면이다.)</em></del></p>
<p><img src="https://images.velog.io/images/cong_/post/666c65e7-25ea-44d4-8c46-5ee8864bb11c/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-18%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.30.43.png" alt=""></p>
<h3 id="typescript-설치하기">TypeScript 설치하기</h3>
<p><a href="https://create-react-app.dev/docs/adding-typescript/">create-react-app dev 공홈</a></p>
<p>JavaScript 기반 React 사용은 터미널에서 <code>~$ npx create-react-app 프로젝트 이름</code> 으로 React 프로젝트를 만들어 사용한다. 
TypeScript 기반 React 사용은 터미널에서  <code>~$ npx create-react-app 프로젝트 이름 --template typescript</code> 으로 React 프로젝트를 만들어 사용하면 된다.</p>
<blockquote>
<p>❗️JavaScript 기반 React 프로젝트 생성 후, TypeScript 기반으로 변경하고 싶을 때❗️
1️⃣ <strong>에디터 터미널에서 아래 명령어로 설치한다.</strong></p>
</blockquote>
<pre><code>npm install --save typescript @types/node @types/react @types/react-dom @types/jest</code></pre><hr>
<p>2️⃣ <strong>react-app-env.d.ts 파일을 ./src/ 아래에 생성해 준다.</strong></p>
<hr>
<p>3️⃣ <strong>react-app-env.d.ts 파일에 아래 내용을 추가해 준다.</strong></p>
<pre><code>/// &lt;reference types=&quot;react-scripts&quot; /&gt;</code></pre><hr>
<p>4️⃣ <strong>tsconfig.json 파일을 ./ 아래에 생성해 준다.</strong></p>
<hr>
<p>5️⃣ <strong>tsconfig.json 파일에 아래 내용을 추가해 준다.</strong></p>
<pre><code>{
  &quot;compilerOptions&quot;: {
    &quot;target&quot;: &quot;es5&quot;,
    &quot;lib&quot;: [
      &quot;dom&quot;,
      &quot;dom.iterable&quot;,
      &quot;esnext&quot;
    ],
    &quot;allowJs&quot;: true,
    &quot;skipLibCheck&quot;: true,
    &quot;esModuleInterop&quot;: true,
    &quot;allowSyntheticDefaultImports&quot;: true,
    &quot;strict&quot;: true,
    &quot;forceConsistentCasingInFileNames&quot;: true,
    &quot;noFallthroughCasesInSwitch&quot;: true,
    &quot;module&quot;: &quot;esnext&quot;,
    &quot;moduleResolution&quot;: &quot;node&quot;,
    &quot;resolveJsonModule&quot;: true,
    &quot;isolatedModules&quot;: true,
    &quot;noEmit&quot;: true,
    &quot;jsx&quot;: &quot;react-jsx&quot;
  },
  &quot;include&quot;: [
    &quot;src&quot;
  ]
}</code></pre><hr>
<p>6️⃣ <strong>.js확장자 파일을 .tsx로 수정해 준다.</strong>
(TypeScript의 확장자는 .ts이지만, React 안에서는 .tsx 확장자를 사용한다.)</p>
<hr>
<p>7️⃣ ** 라이브러리  에러가 나는 경우는 TypeScript 기반 라이브러리를 재설치해 준다.**
라이브러리 에러가 나는 경우가 발생하는데, 이는 JavaScirpt 기반으로 설치되었기때문에 TypeScript 가 이해하지 못하는것이다. 에러가 발생한 라이브러리에 마우스를 가져가면 TypeScript 기반 설치 명령어를 알려주니 그대로 복사해서 터미널에서 설치해주면 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2022.1.15 TIL]]></title>
            <link>https://velog.io/@cong_/2022.1.15-TIL</link>
            <guid>https://velog.io/@cong_/2022.1.15-TIL</guid>
            <pubDate>Sat, 15 Jan 2022 08:06:37 GMT</pubDate>
            <description><![CDATA[<p>0.sticky속성
1.sticky속성 적용하기</p>
<h3 id="sticky-속성">Sticky 속성</h3>
<p>sticky속성 사용 시, position속성과 top, bottom, left, right와 같은 위치 속성 두가지는 필수로 설정해주어야한다.</p>
<pre><code>.sticky{
    position:sticky;
    top:0px;
}</code></pre><p>sticky 속성은 부모 요소 안에서만 sticky를 적용하여야하며, 부모 요소중에 overflow:auto, overflow:hidden, overflow:scroll속성과 함께 사용할 수 없으며, IE에서는 지원하지 않는다.</p>
<h3 id="sticky-속성-적용하기">Sticky 속성 적용하기</h3>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;style&gt;
        nav{
            width: 100%;
            height: 60px;
            position: fixed;
            top:0;
            background-color: grey;
            text-align: center;
            font-size:20px;
            font-weight: bold;
            z-index: 9999;
        }
        .content{
            width: 100%;
            height: 300vh;
            margin-top: 65px;
            text-align: center;
            font-size: 20px;
            font-weight: bold;
        }
        .left_content{
            width: 69%;
            height:100vh;
            float:left;
            position:sticky;
            top:65px;
            border: 4px solid rgba(0, 14, 30, 0.671);
        }
        .right_content{
            width: 29%;
            height:200vh;
            float: right;
            position:sticky;
            top:65px;
            border: 4px solid rgba(0, 48, 60, 0.582);
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;nav&gt;Nav Bar&lt;/nav&gt;
    &lt;div class=&quot;content&quot;&gt;
        &lt;div class=&quot;left_content&quot;&gt;
            Left Content
        &lt;/div&gt;
        &lt;div class=&quot;right_content&quot;&gt;
            Right Content
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p>1.스크롤 start
<img src="https://images.velog.io/images/cong_/post/a2bfcc2b-9f45-42fb-8a3a-358deaecdadb/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.04.01.png" alt="">
2.스크롤 middle
<img src="https://images.velog.io/images/cong_/post/c8c4a63a-1a91-451a-b117-a3b6b18a6c85/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.04.23.png" alt="">
3.스크롤 end
<img src="https://images.velog.io/images/cong_/post/dd12280d-a860-4912-9118-7237192b1659/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202022-01-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.04.47.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[알고리즘 [위장]]]></title>
            <link>https://velog.io/@cong_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9C%84%EC%9E%A5</link>
            <guid>https://velog.io/@cong_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9C%84%EC%9E%A5</guid>
            <pubDate>Tue, 28 Dec 2021 07:06:07 GMT</pubDate>
            <description><![CDATA[<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42578">프로그래머스_위장</a></p>
<pre><code>def solution(clothes):
    answer = 1
    closet = {} #dictionary 선언

    for cloth in clothes:
        #dictionary에 key가 존재하면, 해당 key에 value 추가
        if cloth[1] in closet.keys(): 
            closet[cloth[1]].append(cloth[0])

        #dictionary에 key가 존재하지 않는다면, dictionary 추가
        else:
            closet[cloth[1]] = [cloth[0]]

    for value in closet.values():
        answer *= len(value) + 1

return answer - 1</code></pre><p>문제 해결 포인트가 해시였지만, 어떻게 풀어야 할지 몰라 다른 사람의 문제 풀이를 참고하여 해결하였다. </p>
<p>먼저 매개변수로 입력 받은 clothes 문자열을 순회하며, closet에 같은 옷 종류의 옷끼리 묶어 정리한다. closet에 옷 종류가 있다면 append로 값을 추가하고, closet에 옷 종류가 없다면 리스트를 추가하는 방식으로! </p>
<p>다음으로 정리된 closet을 가지고 경우의 수를 구하면된다. 
경우의 수는 종유별로 옷을 0개 혹은 1개 입는다. 각 종류별로 입을 수 있는 옷의 개수에 안입는 경우 1을 더하여 그 값들을 모두 곱하면 값을 구할 수 있다. </p>
<p>이때 아무것도 안입으면 안되므로 아무것도 안입는 경우 1을 빼면 문제의 정답을 구할 수 있다.</p>
<p>참고 : <a href="https://latte-is-horse.tistory.com/140">https://latte-is-horse.tistory.com/140</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021.12.28 TIL]]></title>
            <link>https://velog.io/@cong_/2021.12.28-TIL</link>
            <guid>https://velog.io/@cong_/2021.12.28-TIL</guid>
            <pubDate>Tue, 28 Dec 2021 06:16:12 GMT</pubDate>
            <description><![CDATA[<p>0.python Dictionary란?
1.Dictionary 선언
2.Dictionary 출력
3.Dictionary 추가 &amp; 삭제
4.Dictionary keys() &amp; values() 사용</p>
<h3 id="python-dictionary란">python Dictionary란?</h3>
<p>python의 Dictionary는 자료형이다. 
DB(Data Base)처럼 key와 value를 묶어 사용할 수 있기때문에 편리하다.
단, 중복과 순서가 없기 때문에 index나 slice는 사용할 수 없다.</p>
<h3 id="dictionary-선언">Dictionary 선언</h3>
<p>Dictionary의 선언은 {} 중괄호를 사용한다.
key와 value 쌍들이 {}로 둘러싸이고, 각각의 요소는 key : value 형태이며, 콤마(,)로 구분한다.</p>
<pre><code>A = {&quot;yellowhat&quot;:&quot;headgear&quot;, &quot;bluesunglasses&quot;:&quot;eyewear&quot;, &quot;green_turban&quot;:&quot;headgear&quot;}

B = {0:&quot;headgear&quot;, 1:&quot;eyewear&quot;, 2:&quot;face&quot;}

C = {&quot;a&quot;:[1,2,3,4], &quot;b&quot;:[5,6,7], &quot;c&quot;:[8,9,10]}

D = {&quot;a&quot;:(1,2,3,4), &quot;b&quot;:(5,6,7), &quot;c&quot;:(8,9,10)}</code></pre><p>value에는 숫자, 문자, 문자열, 리스트, 튜플이 올 수 있지만, Key에는 list,dict 등과 같이 내용이 바뀔 수 있는 객체는 사용할 수 없다.</p>
<h3 id="dictionary-출력">Dictionary 출력</h3>
<pre><code>B = {0:&quot;headgear&quot;, 1:&quot;eyewear&quot;, 2:&quot;face&quot;}

C = {&quot;a&quot;:[1,2,3,4], &quot;b&quot;:[5,6,7], &quot;c&quot;:[8,9,10]}

print(B[0])
print(C[b])</code></pre><p>Dictionary 출력은 print함수에 key값을 넣어주면 그에 해당하는 value가 출력된다.
그러나 코드를 작성한 사람이 아니면 어떤 key가 Dictionary로 선언되었는지 모르기때문에 선언되지 않은 key를 출력하게 되면 프로그램 오류가 날것이다. </p>
<p>따라서 직접적으로 key값을 주어 출력하는 것보다는 <strong>get()함수</strong>를 사용하여 출력하는 것을 권장한다.</p>
<pre><code>B = {0:&quot;headgear&quot;, 1:&quot;eyewear&quot;, 2:&quot;face&quot;}

C = {&quot;a&quot;:[1,2,3,4], &quot;b&quot;:[5,6,7], &quot;c&quot;:[8,9,10]}

print(B.get(0))
print(C.get(&quot;b&quot;))</code></pre><p>get()함수는 선언된 Dictionary에서 출력하고자는 key가 있으면, 그에 해당하는 value를 출력해준다. 출력하고자 하는 key가 없을 경우에는 오류가 아닌 None을 출력한다.</p>
<h3 id="dictionary-추가삭제">Dictionary 추가&amp;삭제</h3>
<pre><code>B = {0:&quot;headgear&quot;, 1:&quot;eyewear&quot;, 2:&quot;face&quot;}

C = {&quot;a&quot;:[1,2,3,4], &quot;b&quot;:[5,6,7], &quot;c&quot;:[8,9,10]}

B[3] = &quot;bottom&quot; 
C[&quot;a&quot;] = [5,6]

del B[0]
del C[a]</code></pre><p>사전객체[키] = 값 으로 데이터를 추가할 수 있으며, del()함수로 데이터 삭제가 가능하다.</p>
<h3 id="dictionary-keys--values-사용">Dictionary keys() &amp; values() 사용</h3>
<pre><code>B = {0:&quot;headgear&quot;, 1:&quot;eyewear&quot;, 2:&quot;face&quot;}

C = {&quot;a&quot;:[1,2,3,4], &quot;b&quot;:[5,6,7], &quot;c&quot;:[8,9,10]}

print(B.keys())
print(list(B.keys()))

print(C.values())
print(list(C.values()))</code></pre><p>keys(), values()를 활용하여 바로 해당 출력값을 받아 볼 수 있으나, list로 형변환 하여 확인하면 보다 익숙한 형태의 출력값을 볼 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021.12.08 TIL]]></title>
            <link>https://velog.io/@cong_/2021.12.08-TIL</link>
            <guid>https://velog.io/@cong_/2021.12.08-TIL</guid>
            <pubDate>Thu, 09 Dec 2021 08:04:45 GMT</pubDate>
            <description><![CDATA[<p>0.Interactive Web
1.data attribute
2.fetch()
3.getUserMedia()</p>
<h3 id="interactive-web">Interactive Web</h3>
<p>클라이언트와 서버 사이에서 일방적으로 정보를 받는데에 그치지 않고, 접속자가 페이지안에서 상호작용과 데이터를 교류하는 동적인 웹페이지를 말하며, 상호작용 및 데이터 교류를 하는데 있어 url변화 없이 페이지 변화가 일어난다. </p>
<p>Interactive Web으로 구현된 대표적인 사례는 Apple 공식 홈페이지이다.
<a href="https://www.apple.com/kr/iphone-13/">Apple</a></p>
<blockquote>
<p><strong>동적 웹페이지</strong>
:클라이언트 요청에 대해서 서버는 사용자에 따라 각각 다른 내용을 제공한다.
즉, 사용자가 URL을 통해 서버에 웹페이지를 요청했을 때, 서버는 사용자에 맞는 HTML문서를 생성하여 클라이언트에게 응답한다. (EX)쇼핑몰 찜 list, 최근본 상품, 추천 상품 등
<strong>정적 웹페이지</strong>
:클라이언트 요청에 대해서 항상 같은 내용을 제공한다.
즉, 사용자가 URL을 통해 서버에 웹페이지를 요청했을 때, 서버 안에서 이미 만들어져있는 HTML문서를 클라이언트에게 응답한다. (EX)회사 소개, 개인 소개 등</p>
</blockquote>
<h3 id="data-attribute데이터-속성">Data Attribute(데이터 속성)</h3>
<p>&#39;data-&#39;로 시작하는 속성을 말하며, 이는 특정 데이터를 DOM요소에 저장하기 위한 목적으로 사용된다. 데이터 속성 사용 시, 브라우저는 데이터 속성에 대해 어떠한 영향도 주지않기 때문에 개발자는 DOM요소에 특정한 데이터를 저장하고 싶은 경우 자유롭게 사용이 가능하다.
&#39;data-&#39;로 시작하는 속성은 모두 사용이 가능하며, 화면에 보이지 않게 데이터를 요소에 담을 수 있는 장점을 가지고 있다.</p>
<blockquote>
<p><strong>DOM</strong>
DOM(Document Object Model)를 직역하면 문서 객체 모델이다. 
문서 객체란 html문서의 태그들을 Javascript가 이용할 수 있는 객체로 만드는 것을 문서 객체라한다. 모델은 모형, 주형, 모듈이라는 의미를 가지고 있으며 여기서는 인식하는 방식으로 해석할 수 있다. 따라서 DOM은 웹 브라우저가 HTML페이지를 인식하는 방식을 의미한다. </p>
</blockquote>
<h3 id="fetch">fetch()</h3>
<p>원격 API호출할 때에 client단에서 직접 HTTP통신을 하는데 있어 복잡하여 request, axios,jQuery와 같은 library를 가장 많이 사용하였으나, 현재는 브라우저에서 fetch()함수를 제공함으로써 보다 쉽게 호출할 수 있게 되었다고 한다. </p>
<p>fetch()는 서버와의 비동기 요청방식으로 다양한 주문 전송, 사용자 정보 읽기, 서버에서 최신 변경분 가져오기 등 다양한 일을 페이지 새로고침없이 수행할 수 있다. </p>
<blockquote>
<p>fetch(url,[Opations]) 
url : 접근하고자 하는 url
options :
method(사용할 메소드 선택. GET, POST, PUT, DELETE)
headers(헤더에 전달할 값)
body(바디에 전달할 값)
mode(설정 값)
credentials(자격 증명을 위한 옵션 설정)
cache(캐쉬 사용여부)</p>
</blockquote>
<h3 id="getusermedia">getUserMedia()</h3>
<p>사용자에게 미디어 입력 장치 사용 권한을 요청하며, 사용자가 수락하면 요청한 미디어 종류의 트랙을 포함한 MediaStream을 반환한다.
사용자가 권한 요청을 거부하거나 일치하는 유형의 미디어를 사용 할 수 없는 경우,NonAllowedError와 NotFoundError로 거부된다.</p>
<blockquote>
<p>MediaStream는 미디어 콘텐츠의 스트림을 나타낸다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021.12.07 TIL]]></title>
            <link>https://velog.io/@cong_/2021.12.07-TIL</link>
            <guid>https://velog.io/@cong_/2021.12.07-TIL</guid>
            <pubDate>Wed, 08 Dec 2021 06:25:50 GMT</pubDate>
            <description><![CDATA[<p>0.querySelector()
1.querySelectorAll()
2.getElementById()
3.keydown 이벤트</p>
<h3 id="queryselector">querySelector()</h3>
<p>지정된 선택자와 일치하는 도큐먼트의 첫번째 요소(element)를 반환한다. 일치하는 요소가 없으면 null을 반환한다.</p>
<h3 id="queryselectorall">querySelectorAll()</h3>
<p>지정된 셀렉터 그룹에 일치하는 도큐먼트의 element list를 나타낸다. 즉 NodeList를 반환한다.
지정된 셀렉터가 없는 경우에는 비어있는 NodeList로 반환된다. </p>
<blockquote>
<p><strong>NodeList가 배열은 아니다</strong>
대표적으로 length 속성을 가지며,forEach()함수를 사용하여 반복할 수 있다.
Array.from()을 사용하여 Arry로 변환도 가능하다.그러나 일부 오래된 브라우저에서는 forEach(),Array.from()을 사용할 수 없다. </p>
</blockquote>
<h3 id="getelementbyid">getElementById()</h3>
<p>주어진 문자열과 일치하는 id 속성을 가진 요소를 찾고, 이를 나타내는 요소 객체를 반환한다.
단 id는 문서 내에서 유일해야 한다. 때문에 특정 요소를 빠르게 찾을 때 유용하다. </p>
<h3 id="keydown-이벤트">keydown 이벤트</h3>
<p>키보드의 키가 눌렸을 때 발생하는 이벤트이다.
keydown 이벤트는 키보드의 키에 의해 발생하는 이벤트로 단축키를 만들 수 있다. 
어떤 키가 눌려졌는지 확인하는 방법으로는 아래와 같이 확인해볼 수 있으며, 키값에 따른 <a href="https://blog.munilive.com/posts/keyboard-keycode-value.html">키코드</a>가 있기에 이를 활용하면 좋을것 같다.</p>
<pre><code>const handleKeyborad = (event) =&gt; {
  console.log(&quot;kedown : &quot;, event.code);
};
window.addEventListener(&quot;keydown&quot;, handleKeyborad);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[2021.12.06 TIL]]></title>
            <link>https://velog.io/@cong_/2021.12.06-TIL</link>
            <guid>https://velog.io/@cong_/2021.12.06-TIL</guid>
            <pubDate>Wed, 08 Dec 2021 05:28:05 GMT</pubDate>
            <description><![CDATA[<p>0.loadedmetadata 이벤트
1.loadeddata 이벤트
2.toISOString 함수</p>
<h3 id="loadedmetadata-이벤트">loadedmetadata 이벤트</h3>
<p>메타데이터가 로드 된 시점에 발생하는 이벤드이다.
미디어의 재생 시간, 해상도 등의 정보가 로드되었을 때를 말한다.</p>
<blockquote>
<p><strong>metadata</strong>
메타데이터는 사전적 의미로 &#39;데이터에 대한 데이터&#39; 또는 &#39;다른 데이터를 설명해 주는 데이터&#39;라고 한다. 조금 더 나아가 <strong>메타데이터란 상위 레벨에서 하위 레벨의 데이터를 설명하는 정보를 담은 데이터</strong>라고 한다.
비디오를 예를 들어 설명하자면, 
<strong>상위 레벨</strong> : 
    A.mp4
    B.mp4
    C.mp4
<strong>하위 레벨</strong> : 
    A.mp4 의 제목, 
    A.mp4 의 작성자,
    A.mp4 의 파일 크기,
    A.mp4 의 파일 생성 일자,
    A.mp4 의 파일 생성 시간,
    A.mp4 의 파일 생성 위치,
    A.mp4 의 파일 수정 일자,
    A.mp4 의 파일 수정 시간 등이라 볼 수 있겠다. </p>
</blockquote>
<h3 id="loadeddata-이벤트">loadeddata 이벤트</h3>
<p>미디어의 첫 번째 프레임이 로딩이 완료된 시점에 발생하는 이벤트이다.
미디어에 대해 최초로 현재 재생 위치에 대한 데이터가 로드되었을 때를 의미한다. </p>
<blockquote>
<p><strong>loadedmetadata VS loadeddata</strong>
loadedmetadata는 미디어에 대한 데이터 로딩이 전체적으로 완료된것. 
loadeddata는 미디어에 대해 데이터가 최초로 로딩이 된 즉 전체적으로 완료되지 못한것.</p>
</blockquote>
<h3 id="toisostring-함수">toISOString() 함수</h3>
<p>toISOString() 함수는 단순화한 확장 ISO형식의 문자열을 반환한다. 
반환값은 언제나 24글자 또는 27글자(YYYY-MM-DDTHH:mm:ss.sssz 또는 ±YYYY-MM-DDTHH:mm:ss.sssz)이다. 
Date객체는 한국 표준 시간을 반환하는 반면에, toISOString() 함수는 UTC시간을 기준으로 반환하기 때문에 데이터 포맷 작업이 필요하다.  </p>
<blockquote>
<p>ISO형식은 국제표준화 기구에서 공표한 날짜와 시간 관련데이터 교환을 다루는 국제표준을 말한다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021.12.03 TIL]]></title>
            <link>https://velog.io/@cong_/2021.12.03-TIL</link>
            <guid>https://velog.io/@cong_/2021.12.03-TIL</guid>
            <pubDate>Sun, 05 Dec 2021 11:22:18 GMT</pubDate>
            <description><![CDATA[<p>0.CSS
1.SASS(SCSS)
4.CSS속성</p>
<h3 id="css">CSS</h3>
<p>CSS(Cascading Style Sheets)는 HTML 문서의 스타일을 구현하는 스타일 시트 언어이다.
HTML로부터 디자인적인 요소를 분리해 정의할 수 있으며, 잘 정의 된 css는 서로 다른 여러 웹 페이지에 적용할 수 있다. </p>
<h3 id="sass">SASS</h3>
<p>SASS(Syntactically Awesome Style Sheets)는 프로젝트 규모가 커지면 CSS는 불가피하게 가독성이 떨어지는 등 유지보수의 어려움을 주는 요소가 된다. 코드의 재활용성을 올리고, 가독성을 올리는 등 CSS에서 보이던 단점을 보완하고, 개발의 효율을 올리기 위해 등장한 개념이 SASS/SCSS라고 한다.</p>
<p>SASS는 CSS의 {} 블록이 아닌 들여쓰기 감지를 핵심특성으로 갖는 구문을 가리켰으나, SCSS라는 CSS 구문과 완벽하게 호환이 되도록 중괄호를 사용함으로써 SASS와 CSS 사이의 차이를 좁히는 방향으로 변화되어 왔다.
현재 SASS구문과 SCSS구문을 모두 사용가능하며, 동등한 기능을 갖고 있어 원하는 구문을 사용하면된다.</p>
<p>(SASS및 SCSS를 사용하기 위해서는 별도의 loader가 필요하다.)</p>
<p>SASS와 SCSS의 구문차이점을 아래 코드로 살펴보면 좀 더 이해하기 쉬울것 같다.</p>
<p>Sass</p>
<pre><code>/**Sass Syntax**/

nav
  ul
    margin: 0
    padding: 0
    list-style: none

  li
    display: inline-block

  a
    display: block
    padding: 6px 12px
    text-decoration: none</code></pre><p>Scss</p>
<pre><code>nav {
  ul {
    margin: 0;
    padding: 0;
    list-style: none;
  }

  li { display: inline-block; }

  a {
    display: block;
    padding: 6px 12px;
    text-decoration: none;
  }
}</code></pre><h3 id="css속성">CSS속성</h3>
<p><strong>opacity</strong>
요소의 불투명도를 설정하는 속성이다. 불투명도는 요소 뒤쪽에 컨텐츠가 숨겨지는 정도로, 투명도의 반대이다.
opacity는 요소의 내용을 포함해 모든 곳에 영향을 주지만 자식 요소가 상속하지는 않는다. 
(자식 요소를 불투명하게 유지하고 싶다면 background 속성을 대신 사용하는것이 좋다.)</p>
<p><strong>apperance</strong>
운영 체제의 테마를 기반으로 플렛폼에 기본 스타일을 사용하여 요소를 표시하는데 사용된다. </p>
<p><strong>all:unset</strong>
button, input, span 등 스타일을 적용하기 위해서 각 브라우저마다 기본으로 적용되어 있는 style을 초기화 시키는 속성이다.</p>
<p><strong>rgb &amp; rgba 차이점</strong>
RGB는 빨강, 녹색 및 파랑에 대한 데이터를 포함하는 3 채널 형식이다.
RGBA는 빨강, 녹색, 파랑 및 알파에 대한 데이터를 포함하는 4 채널 형식이다.(alpha는 투명도)
(RGBA는 색상을 투명/불투명하게 만드는 것 외에는 알파 채널을 하용하지 않는다.)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021.12.2 TIL]]></title>
            <link>https://velog.io/@cong_/2021.12.2-TIL-v3ph8vww</link>
            <guid>https://velog.io/@cong_/2021.12.2-TIL-v3ph8vww</guid>
            <pubDate>Sun, 05 Dec 2021 09:39:06 GMT</pubDate>
            <description><![CDATA[<p>0.Webpack개념
1.Webpack등장배경
2.Webpack사용이유
3.Webpack-cli란?
4.Webpack의 Loader란?</p>
<h2 id="webpack">Webpack</h2>
<h3 id="webpack-이란">Webpack 이란?</h3>
<p>웹팩은 모듈번들러이다. 모듈번들러는 여러개의 파일을 하나의 파일로 묶어주는 라이브러리를 말한다.</p>
<p><img src="https://images.velog.io/images/cong_/post/3bf29580-be70-49cf-b005-0af3e4d96089/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-12-05%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.34.47.png" alt=""></p>
<p>위 그림은 Webpack의 첫 페이지에 등장하는 그림이다. 위의 그림을 보면 모듈 번들러가 무엇인지 유추가 가능하다. Webpack 모듈 번들러는 파일의 종속성을 스스로 파악하며, 종속성이 있어 서로 엮여 있는 파일을 하나의 파일로 묶어주는 역할을 한다. </p>
<h3 id="webpack-등장배경">Webpack 등장배경</h3>
<p>서버에서 처리하는 로직을 JS(JavaScript)로 구현하는 부분이 많아지면서 웹 서비스 개발에서 JS로 작성하는 코드의 양도 늘어났다. 코드의 양이 많아지면 코드의 유지보수가 쉽도록 코드를 모듈로 나누어 관리하는 모듈 시스템이 필요하지만 JS는 언어 자체가 지원하는 모듈 시스템은 없다. 모듈번들러 등장 전에 JS는 각각의 파일을 모듈처럼 분리시켜 html파일에서 script 태그로 불러오는 방식으로 모듈화 하였다. </p>
<p>이와 같은 모듈화는,</p>
<p>   •html에서 JS파일을 불러들이는 순서가 중요해지며.
   •JS파일을 각각의 파일로 나눠도 모두 글로벌 변수(전역 변수)로 생성되어 Scop에러 발생.
   •다른 사람의 코드를 그대로 가져오기 힘든 문제가 있었다.</p>
<p>이러한 문제들로 JS를 범용화하기 위한 모듈번들러가 등장하기 시작했다. 그중 하나가 Webpack이다.</p>
<h3 id="webpack-사용-이유">Webpack 사용 이유</h3>
<p>Webpack과 같은 유사한 작업을 하는 도구들 중에는 Browserify, Grunt, Gulp 등이 있다.</p>
<p>그렇다면 왜 위 도구들보다 Webpack이 나은지 그리고 무슨 차이가 있을까? </p>
<p>기존에도 웹 개발 생산성을 높이기 위해 Grunt, Gulp와 같은 도구들로 개발 라이프 사이클을 줄일 수 있었지만 그에 더 나아가 Webpack은 모듈 의존성까지 관리해주는 특징이 있다.</p>
<p>기존 Task Runner인 Grunt, Gulp는 오로지 리소스들에 대한 툴로 사용되며 dependency grapch에 대한 개념은 없었다. Webpack은 Package Bundler이며 Gulp는 Task Runnder이다. </p>
<blockquote>
</blockquote>
<p>Package Bundler(의존성,종속성을 가진 애플리케이션 모듈을 정적인 소스로 재생산)
Task Runner(반복 가능한 특정 작업을 자동화)</p>
<p>다시 말해, Task Runnder는 그저 미리 정의해 놓은 어떠한 작업을 실행하는 것이고 Package Bundler는 말 그대로 소스들을 하나의 패키지화 하는 것이다. Grunt와 Gulp는 일련의 태스크를 정의하고 실행하면 번들링도 할 수 있는 도구이지만, Webpack은 애초부터 의존성 관리까지 포함한 번들링을 위해 나온 도구이다. </p>
<blockquote>
<p>연필을 계속해서 뾰족하게 깎다보니 제법 이도 쑤실 수 있게 된것이 Gulp, Grunt이고 청음부터 이쑤시개라고 이름 달고 나온것이 웹팩이다. </p>
</blockquote>
<p>참조: <a href="https://webclub.tistory.com/635">https://webclub.tistory.com/635</a></p>
<h3 id="webpack-cli란">Webpack-cli란?</h3>
<p>터미널에서 webpack커맨드를 실행할 수 있게 해주는 커맨드 라인 도구이다.</p>
<h3 id="webpack의-loader란">Webpack의 Loader란?</h3>
<p>Loader는 모듈을 입력 받아 처리하는 과정과 관련된 속성을 의미한다. 
웹팩의 의존성 그래프를 완성시키는 과정에서 의존 관계를 갖는 다양한 타입의 모듈들을 입력받고 처리하는 역할을한다. 모듈을 입력받아 해설할 때 JS파일이나 Json파일을 기본 모듈로 보며, 만약 다른 파일을 모듈로 불러와서 사용하게 될 경우, loader라는 요소를 설정해야 그 파일들을 모듈로 불러와서 번들링 할 수 있다. </p>
<p>Webpack Loader의 종류
• CSS Loader
• Sass Loader
• Style Loader
• File Loader
• URL Loader</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021.12.2 TIL]]></title>
            <link>https://velog.io/@cong_/2021.12.2-TIL</link>
            <guid>https://velog.io/@cong_/2021.12.2-TIL</guid>
            <pubDate>Sun, 05 Dec 2021 08:03:19 GMT</pubDate>
            <description><![CDATA[<h3 id="mongoose의-populate">Mongoose의 populate</h3>
<blockquote>
<p>mongoose는 NoSQL(Not Only Structured Query)의 대표적인 DB(Data Base)이다.
즉, 비관계형 데이터베이스의 대표적인 DB이다. </p>
</blockquote>
<p>그러나 mongoDB를 사용하다보면 컬렉션의 특정 데이터를 기반으로 다른 컬렉션의 데이터를 참조하는 상황이 발생한다. 이때 등장한게 populate()이다. </p>
<p><strong>populate은 SQL의 join과 같은 기능</strong> 을 한다. </p>
<p>쇼핑몰에 사용되는 DB를 생각해보자, 
하나의 테이블에는 고객ID와 고객주소지가 있고, 다른 테이블에는 고객들이 현재까지 주문한 상품정보와 해당 상품을 주문한 고객ID가 저장되어 있다.</p>
<p><img src="https://images.velog.io/images/cong_/post/a2bcaf2b-e215-46d9-a0b7-ccd0d49a8ac5/table.png" alt=""></p>
<p>배송을 위해서는 고객들이 주문한 상품 정보와, 고객의 주소지를 알아야 한다. 이때 두 컬렉션을 활용하여 데이터를 얻어야하는데, 처음부터 컬렉션 하나만 생성하여 데이터를 모두 넣거나, 두 컬렉션에 동일한 주소지 데이터를 추가하면 되지 않을까 하는 생각이 들 수 있다. 그러나 앞서 말한 방법으로 진행하게되면 컬렉션의 컬럼이 너무 많아져 보기에도 좋지 않고, 속도에도 영향을 미치게 된다. 또한 두 테이블 모두에 주소지 데이터를 넣어버린다면 현재의 문제는 해결 되겠지만, 추후에도 계속해서 다른 필드 참조를 위해 칼럼을 추가하고 데이터를 추가하는 일을 반복하다 보면, 비슷한 문제가 계속 발생할것이다. 컬럼 추가로 인해 중복된 데이터가 테이블에 있다면 데이터 업데이트를 하는데에도 상당한 불편함을 감수해야 할 것이다.</p>
<p>이럴때 사용하는 연산이 Join연산이며, mongoDB에서는 populate()을 사용한다. Join 연산은 하나 이상의 칼럼이 공유(현재 상황에서는 고객ID)되어 있을 때, 다른 테이블의 데이터 검색을 할 수 있게 되어 하나의 테이블처럼 검색을 할 수 있게 해주는 쿼리 문법이다. </p>
<p><strong>populate 사용</strong></p>
<p>User 스키마</p>
<pre><code>import mongoose from &quot;mongoose&quot;;

const UserSchema = new mongoose.Schema({
     userId: { type: String, required: true},
      userAddress: { type: String, required: true},
});

const User = mongoose.model(&quot;User&quot;, UserSchema);

export default User;</code></pre><p>OderInfo 스키마</p>
<pre><code>import mongoose from &quot;mongoose&quot;;

const OrderInfoSchema = new mongoose.Schema({
     userId: { type: String, required: true},
      productInfo: { type: String, required: true},
    userAdress:{
        type: mongoose.Schema.Types.ObjectId,
        required: true,
        ref:&quot;User&quot;,
    },
});

const OrderInfo = mongoose.model(&quot;OrderInfo&quot;, OrderInfoSchema);

export default OrderInfo;</code></pre><p>위과 같이 Join을 원하는 컬렉션의 type에 mongoose.Schema.Types.ObjectId 정의해주고 ref에 Join하려는 컬렉션의 이름을 작성하여 스키마를 생성해주면 Join을 위한 준비는 완료된다.</p>
<p>join된 컬렉션의 데이터 조회를 위해서는 populate()을 활용하여 작성한다.
OrderInfo에 find로 쿼리를 날린 다음에, User컬렉션 필드의 자세한 정보를 알기 위해서 아래와 같이 작성하면 데이터를 얻을 수 있다. 데이터 확인을 위해서는 변수에 해당 코드를 담아 콘솔로 찍어보면 확인해 볼 수 있다.</p>
<pre><code>OrderInfo.findOne({ _id: userId }).populate(&quot;User&quot;); 
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[2021.11.29 TIL]]></title>
            <link>https://velog.io/@cong_/2021.11.29-TIL</link>
            <guid>https://velog.io/@cong_/2021.11.29-TIL</guid>
            <pubDate>Mon, 29 Nov 2021 08:07:22 GMT</pubDate>
            <description><![CDATA[<p>0.cookie
1.session</p>
<p>기본적으로 HTTP 프로토콜 환경은 비연결성(Connectionless), 비상태성(Stateless)의 특징을 가지고 있다. 이는 서버의 자원을 절약하기 위해 모든 클라이언트의 요청마다 연결과 해제의 과정을 거치기때문에 서버와 클라이언트의 연결상태는 유지되지 않고, 상태 정보가 저장되지 않는다. 따라서 서버는 같은 사용자의 요청에도 매번 새로운 사용자로 인식하기 때문에 클라이언트가 누구인지 확인 하는 과정을 거쳐야한다. 이를 보완하기 위해서 쿠키와 세션을 사용한다. </p>
<blockquote>
<p><strong>Connectionless</strong>
클라이언트가 서버에게 요청 후 응답을 받으면 그 연결을 끊어버리는 특징.
HTTP는 먼저 클라이언트가 Request를 서버에 보내면, 서버는 클라이언트에게 요청에 맞는 Response를 보내고 접속을 끊는 특성이 있다.</p>
</blockquote>
<blockquote>
<p><strong>Stateless</strong>
통신이 끝나면 상태를 유지하지 않는 특징.
연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 사용자의 상태 정보를 유지하지 않는 특성이 있다. 예를 들어 사용자가 쇼핑몰에서 옷을 구매하려고 로그인을 시도했음에도, 페이지를 이동할 때 마다 계속 로그인을 해야한다.</p>
</blockquote>
<h3 id="쿠키">쿠키</h3>
<p>-쿠키는 웹 사이트 접속 시 웹브라우저에 생성되는 임시 데이터 파일이다. </p>
<p>-쿠키의 데이터 형태는 Key와 Value로 구성되고 String 형태로 이루어져 있다. </p>
<p>-쿠키는 서버를 대신해서 사용자 정보를 웹 브라우저(웹 브라우저를 이용하고 있는 컴퓨터)에 저장하고, 사용자가 요청할 때 그정보를 함께 서버로 보내 사용자를 식별할 수 있게 해준다. </p>
<p>-쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request시에 Request Header를 넣어서 자동으로 서버에 전송한다. </p>
<blockquote>
<p><strong>쿠키 종류</strong>
<strong>Session cookie</strong>
보통 만료시간(Expire Date) 설정하고 메모리에만 저장되며 브라우저 종료 시 쿠키를 삭제.
<strong>Persistent cookie</strong>
장시간 유지되는 쿠키, 파일로 저장되어 브라우저 종료와 관계없이 사용.
<strong>Secure cookie</strong>
HTTPS에서만 사용, 쿠키 정보가 암호화 되어 전송.
<strong>Third-Paty cookie</strong>
방문한 도메인과 다른 도메인의 쿠키, 보통 광고 베너 등을 관리할 때 유입 경로를 추적하기 위해 사용.</p>
</blockquote>
<h3 id="세션">세션</h3>
<p>-세션은 쿠키를 기반하고 있지만, 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리 세션은 서버 측에서 관리한다.</p>
<p>-서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때 까지 인증상태를 유지한다.</p>
<p>-물론 접속 시간에 제한을 두어 일정 시간 응답이 없다면 정보가 유지되지 않게 설정이 가능하다. </p>
<p>-사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질 수록 서버 메모리를 많이 차지하게 된다.</p>
<p>-즉 동시접속자 수가 많은 웹 사이트인 경우 서버에 과부하를 주게 되므로 성능 저하의 요인이된다.</p>
<p>-클라이언트가 서버에 Request를 보내면, 해당 서버의 엔진이 클라이언트에게 유일한 ID를 부여하는데 이것이 세션 ID이다.</p>
<h3 id="쿠키와-세션의-동작-방식">쿠키와 세션의 동작 방식</h3>
<p><img src="https://images.velog.io/images/cong_/post/cf6e26d0-1dbe-4182-80b1-6a3cc31c1288/cookie%20and%20session.png" alt=""></p>
<p>1.클라이언트가 서버로 페이지를 요청 
2.서버에서 쿠키 및 세션 생성 후, HTTP 헤더에 쿠키를 포함하여 응답
3.쿠키 만료 기간 전까지 클라이언트 쿠키 보관
4.서버에 페이지 재요청 시, HTTP헤더에 쿠키 포함하여 요청
5.서버에서 쿠키를 읽어 세션ID를 확인 및 클라이언트 요청에 응답</p>
<p>참고1: <a href="https://interconnection.tistory.com/74">https://interconnection.tistory.com/74</a>
참고2: <a href="https://devuna.tistory.com/23">https://devuna.tistory.com/23</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2021.11.24 TIL]]></title>
            <link>https://velog.io/@cong_/2021.11.24-TIL</link>
            <guid>https://velog.io/@cong_/2021.11.24-TIL</guid>
            <pubDate>Wed, 24 Nov 2021 06:39:54 GMT</pubDate>
            <description><![CDATA[<p>0.NoSQL
1.Mongoose
2.MongoDB
3.문서 지향 데이터베이스 </p>
<blockquote>
<p>MongoDB는 NoSQL의 대표적인 데이터베이스이다.</p>
</blockquote>
<p><strong>관계형 데이터베이스의 한계</strong>
관계형 데이터베이스(RDBMS:Relational Database Management System) 는 애플리케이션에 사용된 것 중 오랫동안 가장 지배적인 유형의 데이터베이스(DB:DataBase)였다.
그러나 웹 출현과 더불어 RDB의 한계가 점점 더 문제로 드러나게 되었다. 
큰 규모의 데이터와 사용자를 대상으로 하려면 대용량 데이터 읽기/쓰기 작업, 빠른 응답시간, 높은 가용성이 지원되어야했으나 이러한 요구 사항은 RDB로 실현하기 어려웠다.
또한, 과거에 RDB의 성능이 저하되면 더많은 CPU, 메모리 추가, 더 빠른 저장 장치를 장착함으로써 문제를 해결했으나 이런 방식은 비용이 비싸고 임시방편일 뿐이였다. 결국 DB설계자는 비정규화를 통해 DB Schema를 재설계 해야했다.</p>
<h3 id="nosql의-등장">NoSQL의 등장</h3>
<p>NoSQL(Not Only SQL)은 웹 시장이 발전함에 따라 데이터의 발생량이 증가했고, 사용자가 요구하고 저장하는 데이터가 일관적이지 않아졌기 때문에 RDB의 한계를 해결하기 위해 등장하게되었다.</p>
<p>▪️ NoSQL은 <strong>확장성</strong>에 용이하다. 
필요에 따라 서버를 추가하는 작업이 이루어지는데, RDB에서는 단일 DB 시스템을 구동하는 여러 서버를 관리하기 위해 DB 소프트웨어가 필요하여 복잡성과 운영 비용이 증가할 수 있다. 반면 NoSQL은 애초에 클러스터 하나에서 서버를 여러개 이용하도록 설계되어 새로운 서버를 추가/제거할 때 NoSQL DBMS는 사용 가능한 새 서버를 사용하도록 조정한다.</p>
<p>▪️ NoSQL은 <strong>비용</strong> 저렴한편이다.
주요 NoSQL DB들은 오픈 소스 형태로 제공되며 대부분 오픈 소스 개발자는 자신의 소프트웨어를 사용하는데 비용을 매기지 않는다. </p>
<p>▪️ NoSQL은 <strong>유연성</strong>이 좋다.
RDB는 관계형 데이터 모델을 사용해 해결 가능한 문제의 범위 내에서는 유연한 편이지만, DB설계자는 프로젝트를 시작할 때 애플리케이션 지원에 필요한 모든 테이블과 컬럼을 파악해야 할 뿐만 아니라 대부분의 테이블에 값이 채워져있어야한다.
반면 NoSQL 데이터베이스는 고정된 테이블 구조가 필요하지 않다. 즉, 데이터베이스 설계를 변경하지 않고도 필요한 새로운 속성을 동적으로 추가할 수 있다.</p>
<p>▪️ NoSQL은 <strong>가용성</strong>이 좋다.
저렴한 비용으로 서버를 여러개 이용할 수 있도록 설계되어있다. 서버 하나가 중지되거나 서비스를 일시 중지해야할 경우 클러스터 내 다른 서버가 작업량 전체를 떠맡을 수 있다. 단, 성능은 다소 저하될지라도 애플리케이션이 중단되지는 않는다.</p>
<p>참고 : <a href="https://velog.io/@hanblueblue/NoSQL%EA%B3%BC-%EC%97%AD%EC%82%AC">https://velog.io/@hanblueblue/NoSQL%EA%B3%BC-%EC%97%AD%EC%82%AC</a></p>
<blockquote>
<p>Mongoose는 객체 모델링 도구, MogoDB는 인스턴스 상호작용을 위한 드라이버.</p>
</blockquote>
<h3 id="mongoose">Mongoose</h3>
<p>Mongoose는 NoSQL데이터베이스의 대표적인 MongoDB를 지원하는 Node의 확장 모듈이다.
주된 역할로는 Node.js와 MogoDB를 연결해주는 ODM(Object Document Mapping)이다.
(ODM은 객체와 문서를 1대 1로 매칭해주는것을 뜻한다.)
MongoDB의 ODM은 다양하지만 위와 같은 역할때문에 Mongoose가 가장 유명하다. </p>
<h3 id="mongodb">MongoDB</h3>
<p>MongoDB는 문서지향 NoSQL데이터베이스 시스템이다. MongoDB에서는 데이터가 Document로 불리며, 데이터의 집합을 Collection(RDB에서는 Table)이라 한다. 스키마 제약 없이 자유롭고 BJSON(Binary JSON)형태로 각 문서가 저장되며 배열이나 날짜 등 기존 RDBMS에서 지원하지 않던 형태로 저장할 수 있기 때문에 Join 사용 없이 문서에 좀 더 이해하기 쉬운 형태 그대로 정보를 저장 할 수 있다는것이 특징이다. </p>
<p>특히 MongoDB는 문서지향 데이터베이스로, 객체지향 프로그래밍과 잘 맞고 JSON을 사용할 때 유용하다. JS(JavaScript)를 기반으로 하는 Node.js와 호환이 매우 좋아, Node.js에서 가장 많이 사용되는 DB이다.</p>
<p>참고: <a href="https://edu.goorm.io/learn/lecture/557/%ED%95%9C-%EB%88%88%EC%97%90-%EB%81%9D%EB%82%B4%EB%8A%94-node-js/lesson/174384/mongodb%EB%9E%80">https://edu.goorm.io/learn/lecture/557/%ED%95%9C-%EB%88%88%EC%97%90-%EB%81%9D%EB%82%B4%EB%8A%94-node-js/lesson/174384/mongodb%EB%9E%80</a></p>
<blockquote>
<p>문서지향 데이터베이스는 관계형 데이터배이스와 대조되며, NoSQL의 종류 중 하나이다.</p>
</blockquote>
<h3 id="문서지향-데이터베이스">문서지향 데이터베이스</h3>
<p>문서지향 데이터베이스는 XMl, JSON과 같은 문서 데이터 저장에 특화된 자료 구조이며, NoSQL의 종류 중 하나이다. NoSQL에는 Key-Value DB(키-벨류형),Columnar DB(컬럼 지향형), Document DB(문서 지향형), Grapth DB(그래프형) 등 이 있다. 각 종류에 따라 적합한 DB가 있는데, MongoDB는 NoSQL의 문서지향 데이터베이스에 알맞는 DB이다.</p>
<p>문서지향 데이터베이스는 관계형 데이터베이스와 강하게 대조되는 특징을 가지고 있으며, 
관계형 데이터베이스는 일반적으로 프로그래머사 정의한 별도의 테이블에 데이터를 저장하며 다인 객체는 여러 테이블에 분산될 수 있다.
문서지향 데이터베이스는 주어진 개체에 대란 모든 정보를 데이터베이스의 단일 인스턴스에 저장하며 저장된 모든 개체는 서로 다를 수 있다. 이는 데이터베이스에 데이터를 로드하는 동안 개체 관계형 매칭이 필요하지 않다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 타겟 넘버]]></title>
            <link>https://velog.io/@cong_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84</link>
            <guid>https://velog.io/@cong_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%ED%83%80%EA%B2%9F-%EB%84%98%EB%B2%84</guid>
            <pubDate>Tue, 23 Nov 2021 02:57:52 GMT</pubDate>
            <description><![CDATA[<p><a href="https://programmers.co.kr/learn/courses/30/lessons/43165">프로그래머스_타겟 넘버</a></p>
<p>문제 풀이에 앞서 DFS와 BFS를 살펴보면 좋다.</p>
<p>살펴보기에 앞서 그래프에 대해 간단히 살펴보자. </p>
<p><strong>그래프</strong> 
정점(node)과 그 정점을 연결하는 간선(edge)으로 이루어진 자료구조의 일종을 말한다.
더 나아가 그래프를 탐색한다는 것은 하나의 정점으로부터 시작하여 차례대로 모든 정점들을 한 번씩 방문하는 것을 말한다.</p>
<p><strong>DFS</strong>
Depth First Search, 깊이 우선 탐색</p>
<p>깊이 우선 탐색은 루트 노드에서 시작하여 다음 분기로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방식을 말한다. 
(주로 스택 혹은 재귀호출을 통해 그래프를 순회하는 방법이다.)</p>
<p><strong>BFS</strong>
Breadth First Search, 너비 우선 탐색</p>
<p>너비 우선 탐색은 루트노드에서 시작하여 인점한 노드를 먼저 탐색하는 방법으로 시작 정점으로부터 가까운 정점을 먼저 방문하고 멀리 떨어져 있는 정점을 나중에 방문하는 순회 방식이다.
(주로 큐를 이용하여 그래프를 순회하는 방법이다.)</p>
<p><img src="https://images.velog.io/images/cong_/post/b885bd4f-571c-4281-8799-7a77e5525f24/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-11-22%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%207.09.58.png" alt="">
                        출처 <a href="https://namu.wiki/w/BFS">https://namu.wiki/w/BFS</a></p>
<p><strong>DFS를 이용한 풀이</strong></p>
<pre><code>def solution(numbers, target):
    answer = 0
    answer += DFS(numbers, target, 0)
    return answer
def DFS(numbers, target, depth):
    answer = 0
    if depth == len(numbers):
        if sum(numbers) == target:
            return 1
        else: return 0
    else:
        answer += DFS(numbers, target, depth + 1)
        numbers[depth] *= -1
        answer += DFS(numbers, target, depth + 1)
        return answer</code></pre><p>완전 탐색을 위해 루트 노드에서 마지막 노드 즉 최종 노드에 도착했다면 numbers를 모두 더한 값을 목표 값과 비교하여 문제를 해결하였다.</p>
<p><strong>BFS를 이용한 풀이</strong></p>
<pre><code>def solution(numbers, target):
    answer = 0
    Arr = [0]
    for num in numbers:
        tmp = []
        for arrNum in Arr:
            tmp.append(arrNum + num)
            tmp.append(arrNum - num)
         Arr = tmp
     for arrNum in Arr:
         if arrNum == target:
            answer += 1
     return answer</code></pre><p>루트노드와 인접한 노드를 먼저 탐색하기 위해 numbers의 값을 더하고 뺀경우를 큐에 저장함으로써 모든 계산 결과 값이 담기게 된다. 이를 target과 비교하여 문제를 해결하였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 더 맵게]]></title>
            <link>https://velog.io/@cong_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%8D%94-%EB%A7%B5%EA%B2%8C</link>
            <guid>https://velog.io/@cong_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%8D%94-%EB%A7%B5%EA%B2%8C</guid>
            <pubDate>Fri, 19 Nov 2021 08:03:15 GMT</pubDate>
            <description><![CDATA[<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42626">프로그래머스_더 맵게</a></p>
<p>heap에 대해 잘 알고 있다면 빠르게 해결가능한 문제! </p>
<p>python에서 heap사용을 위해 알아야 하는것, </p>
<ol>
<li><p>import heapq 선언
import 해주어야 heap 사용이 가능하기때문에 문제 풀이시 꼭 선언해 주어야한다.</p>
</li>
<li><p>pop 및 push 하는 방법</p>
</li>
</ol>
<p>heapq.heappush(heap, item)
: item 값을 heap으로 푸시한다.</p>
<p>heapq.heappop(heap)
: heap에서 가장 작은 항목을 팝하고 반환한다.</p>
<p>heapq.heappushpop(heap, item)
: 힙에 item을 푸시한 다음, heap에서 가장 작은 항목을 팝하고 반환한다.</p>
<p>heap사용 시, 가작 작은 값을 꺼내야하기 때문에 .sort()를 처음에는 해줬으나, heapq.heappop()함수 자체가 가장 작은 항목을 반환하기때문에 정렬할 필요가 없다.</p>
<pre><code>import heapq

def solution(scoville, K):
    answer = 0

    heapq.heapify(scoville)

    while(scoville[0] &gt; K):
        try:
            mix = heapq.heappop(scoville) + (heapq.heappop(scoville) * 2)
        except:
            return -1
        heapq.heappush(scoville, mix)
        answer += 1

     return answer</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘] 124 나라의 숫자]]></title>
            <link>https://velog.io/@cong_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-124-%EB%82%98%EB%9D%BC%EC%9D%98-%EC%88%AB%EC%9E%90</link>
            <guid>https://velog.io/@cong_/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-124-%EB%82%98%EB%9D%BC%EC%9D%98-%EC%88%AB%EC%9E%90</guid>
            <pubDate>Fri, 19 Nov 2021 07:30:37 GMT</pubDate>
            <description><![CDATA[<p><a href="https://programmers.co.kr/learn/courses/30/lessons/12899">프로그래머스_123나라의 숫자</a></p>
<p>3진법을 활용한 문제라는 것을 빠르게 캐치한다면 문제 없이 바르게 풀 수 있는 문제다. </p>
<p>평소 2진법 8진법 10진법 16진법만 알고 들었던 터라 규칙을 찾기에 조금 어려웠던거 같다. </p>
<p>일반 3진법과 124나라의 3진법을 비교해보면 아래와 같다. </p>
<p><strong>1.반복의 차이점</strong>
일반 3진법 : 0, 1, 2, 10, 11, 12, 20, 21, 22, 30, 31, 32 ...
124나라의 3진법 : 1, 2, 4, 11, 12, 14, 21, 22, 24, 31, 32, 34 ...  </p>
<p>나열하고 보면 일반 3진법은 일의 자리가 0, 1, 2 로 반복되며, 124나라의 3진법은 일의 자리가 1, 2, 4 로 반복되고 있음을 알 수 있다. </p>
<p><strong>2.0대신 4를 사용</strong>
위의 반복의 차이점을 살펴보면, 
    3진법은 0,1,2 
    124 나라의 3진법은 1,2,4 
124 나라의 3진법은 0을 사용하지 않음을 알 수 있다. 즉, 0대신 4를 사용함을 알 수 있다.</p>
<p>그럼 이를 어떻게 맞춰줄 수 있을까 ??</p>
<p>*<em>주어진 10진수를 124나라의 진수법으로 변환을 할 때, 3으로 나누어 떨어진다면 그 몫을 하나 낮추어서 나머지가 3이 되도록 만들어주는 것이다. *</em></p>
<p>숫자 5
5를 3으로 나누게 되면 몫이 1이되고 나머지가 2가 된다.(나머지가 &quot;2&quot;)
여기서 나누어 떨어지지 않았으므로 몫을 가지고 그대로 계산을 한다. 
몫인 1을 3으로 나누게 되면 몫이 0이되고 나머지가 1이 된다.(나머지가 &quot;1&quot;)
따라서 나머지를 추가해주면 &quot;12&quot;로 숫자&quot;5&quot;는 124나라의 3진법 계산으로 &quot;12&quot;가 된다.</p>
<p>숫자 9
9를 3으로 나누게 되면 몫이 3이 되고 나머지가 0이 된다.
여기서 나누어 떨어졌으므로 나머지는 &quot;0&quot;대신 &quot;4&quot;를 사용한다.(나머지가 &quot;4&quot;)
그리고 몫을 하나 감소시켜준다. 
몫인 2를 3으로 나누게 되면 몫이 0이되고 나머지가 &quot;2&quot;가 된다.(나머지가 &quot;2&quot;)
따라서 나머지를 추가해주면 &quot;24&quot;로 숫자&quot;9&quot;는 124나라의 3진법 계산으로 &quot;24&quot;가 된다.</p>
<pre><code>def solution(n):
    answer = &#39;&#39;
    nArray = [&#39;1&#39;, &#39;2&#39;, &#39;4&#39;]

    while (n &gt; 0):
        n -= 1
        answer = str(nArray[n % 3]) + answer
        n = n // 3

    return answer</code></pre>]]></description>
        </item>
    </channel>
</rss>