<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>ʕっ•ﻌ•ʔっ</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 14 Jan 2021 01:49:10 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>ʕっ•ﻌ•ʔっ</title>
            <url>https://images.velog.io/images/woohyun_park/profile/314295ea-72ee-425a-b359-7a5b07cf84f8/KakaoTalk_20201217_050352335.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. ʕっ•ﻌ•ʔっ. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/woohyun_park" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[컨퍼런스] SOSCON 2020: 아트를 만드는 오픈소스]]></title>
            <link>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-SOSCON-2020-%EC%95%84%ED%8A%B8%EB%A5%BC-%EB%A7%8C%EB%93%9C%EB%8A%94-%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4</link>
            <guid>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-SOSCON-2020-%EC%95%84%ED%8A%B8%EB%A5%BC-%EB%A7%8C%EB%93%9C%EB%8A%94-%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4</guid>
            <pubDate>Thu, 14 Jan 2021 01:49:10 GMT</pubDate>
            <description><![CDATA[<h3 id="✔-크리에이티브-코딩">✔ 크리에이티브 코딩</h3>
<blockquote>
<p>얼마 전 우연히 유튜브 알고리즘을 통해서 인터렉티브 디벨로퍼 김종민님의 인터렉티브 코딩 작업을 보았다. 그리고 이번에도 우연히 삼성 오픈소스 컨퍼런스에서 박소선님의 발표를 보게 되었다. </p>
</blockquote>
<p>크리에이티브 코딩, 알고리드믹 아트, 컴퓨테이셔널 아트 등 미술 및 디자인의 분야를 코딩과 접목시키려는 시도들이 많이 이루어지고 있는 것이 놀라웠고, 평소에 다양한 분야의 예술에 관심이 많은 나로써도 예술과 내가 배우고 있는 기술들을 접목시키면 훨씬 다양한 경험을 제공할 수 있겠구나라는 생각을 가지게 될 수 있었다.</p>
<h3 id="✔-크리에이티브-코딩-라이브러리">✔ 크리에이티브 코딩 라이브러리</h3>
<blockquote>
<p>크리에이티브 코딩을 제공하는 라이브러리를 소개한다.</p>
</blockquote>
<ul>
<li>p5.js<blockquote>
<blockquote>
</blockquote>
<p>우리는 &#39;고고한&#39; 개발자가 아닙니다. 상대가 이미 어떠한 것을 알고 있을거라 섣불리 가정하거나 모든 사람이 반드시 알아야 할 지식이 있다고 생각하지 않습니다.</p>
</blockquote>
참고할만한 자료: p5.js 공식 문서, kadenze.com 튜토리얼, The Coding Train 유튜버 교수, Nature of Code 책 등</li>
<li>three.js</li>
<li>ml5</li>
</ul>
<h3 id="✔-크리에이티브-코딩을-활용하는-분야">✔ 크리에이티브 코딩을 활용하는 분야</h3>
<blockquote>
<ul>
<li>기업: 나이키, 애플, 젠틀몬스터, 삼성, 뉴욕타임즈, 아디다스, IBM</li>
</ul>
</blockquote>
<ul>
<li>전시: TeamLab, 부천b39, 아트센터 나비, 미국 ARTECHOUSE 갤러리, 독일 Kraftwerk</li>
<li>연구: Google Creative Lab, BMW designworks, Facebook, Microsoft, MIT Media Lab, TouchDesigner, Rebel9, onformative, d&#39;strict, field.io, I M Fine, dot-mill, ART + COM</li>
</ul>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<blockquote>
<ul>
<li><a href="https://www.soscon.net/Session/Section/15">아트를 만드는 오픈소스</a></li>
</ul>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] SASS/SCSS]]></title>
            <link>https://velog.io/@woohyun_park/CSS-SASSSCSS</link>
            <guid>https://velog.io/@woohyun_park/CSS-SASSSCSS</guid>
            <pubDate>Wed, 13 Jan 2021 14:41:44 GMT</pubDate>
            <description><![CDATA[<h3 id="✔-css-전처리기">✔ CSS 전처리기</h3>
<blockquote>
<p>CSS 전처리기는 자신만의 특별한 syntax를 가지고 CSS를 생성하도록 도와주는 프로그램으로써, mixin, nesting selector, inheritance selector 등등을 제공함으로써 CSS 구조를 가독성있고 유지보수하기 좋도록 도와준다.
ㅤ
<code>SASS</code>, <code>LESS</code>, <code>Stylus</code>, <code>PostCSS</code> 등 여러가지가 있지만, 여기서는 가장 널리 사용되는 <code>SASS</code>에 대해서 공부해본다.</p>
</blockquote>
<h3 id="✔-sassscss">✔ SASS/SCSS</h3>
<blockquote>
<p>SASS는 Syntactically Awesome Style Sheets의 줄임말이며, SCSS는 Sassy CSS의 줄임말이다. SCSS는 SASS의 모든 기원을 지능하면서 CSS 구문과 완전히 호환되도록 만들어져, 훨씬 사용에 편리하다. 따라서 SCSS를 배워보도록 하자.
ㅤ
참고로 SASS/SCSS 자체로는 브라우저에 적용할 수 없고, 컴파일러를 통해 CSS파일로 컴파일해야만 브라우저에서 동작한다.</p>
</blockquote>
<h3 id="✔-설치-및-컴파일">✔ 설치 및 컴파일</h3>
<blockquote>
<p><code>npm install -g node-sass</code>: npm 모듈로 node-sass를 설치
<code>node-sass style.scss style.css</code>: style.scss 파일을 style.css로 컴파일
<code>node-sass -w style.scss style.css</code>: style.scss가 변경되었을 때 자동으로 style.css로 컴파일</p>
</blockquote>
<pre><code>
### ✔ Nesting
&gt;부모요소를 반복적으로 기술하지 않고 사용이 가능하다. 
```CSS
// CSS
.header{
  width: 100%;
}
.header div{
  height: 100%;
}
.header div:hover{
  margin: 10%;
}
ㅤ
// SCSS
.header{
  width: 100%;
  div{
    height: 100%;
    &amp;:hover{
      margin: 10%;
    }
  }
}</code></pre><h3 id="✔-변수">✔ $변수</h3>
<blockquote>
<p><code>$</code>를 사용해서 공통된 속성들을 재활용 할 수 있다.</p>
</blockquote>
<pre><code class="language-CSS">$header-color: #d9d9d9;
ㅤ
.header{
  color: $header-color;
}</code></pre>
<h3 id="✔-mixin">✔ @mixin</h3>
<blockquote>
<p><code>@mixin</code>을 사용하여 공통된 속성의 묶음을 재활용 할 수 있다.</p>
</blockquote>
<pre><code class="language-CSS">@mixin header-style{
  width: 100%;
  height: 100%;
}
ㅤ
.header{
  @include header-style;
}</code></pre>
<h3 id="✔-import">✔ @import</h3>
<blockquote>
<p><code>@import</code>를 통해 CSS 파일을 가져올 수 있다.</p>
</blockquote>
<pre><code class="language-CSS">@import &#39;header.scss&#39;</code></pre>
<h3 id="✔-if">✔ @if</h3>
<blockquote>
<p><code>@if</code>로 조건 분기가 가능하다.</p>
</blockquote>
<pre><code class="language-CSS">$theme: wave;
ㅤ
header{
  @if $theme == wave{
    color: blue;
  } @else if $theme == grass{
    color: green;
  } @else {
    color: white;
  }
}</code></pre>
<h3 id="✔-for">✔ @for</h3>
<blockquote>
<p><code>@for</code>로 반복문 사용이 가능하다</p>
</blockquote>
<pre><code class="language-CSS">@for $i from 0 through 3{
  .block-#{$i}{
    width: 30% * $i;
  }
}</code></pre>
<h3 id="✔-적용">✔ 적용</h3>
<blockquote>
<p>myPage 프로젝트에 적용시켜 보았다.</p>
</blockquote>
<pre><code class="language-CSS">$theme__color--normal: #d9d9d9;
$font__hover--weight: 700;
...
@mixin font-style{
  font-family: &#39;Roboto&#39;, &#39;Nanum Gothic&#39;, sans-serif;
  font-size: 15px;
}
...
input{
  &amp;[type=submit]{
    @include font-style;
    background: none;
    border: none;
    padding: 0;
    &amp;:hover{
      font-weight: $font__hover--weight;
    }
  }
}
...</code></pre>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<blockquote>
<ul>
<li><a href="https://jinminkim-50502.medium.com/css-preprocessor-sass-scss-25dc8329f867">SASS/SCSS (전처리기)</a></li>
</ul>
</blockquote>
<ul>
<li><a href="https://sass-lang.com/">SASS 공식 사이트</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Project] myPage - BEM 적용 및 리팩토링]]></title>
            <link>https://velog.io/@woohyun_park/Project-myPage-BEM-%EC%A0%81%EC%9A%A9-%EB%B0%8F-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81</link>
            <guid>https://velog.io/@woohyun_park/Project-myPage-BEM-%EC%A0%81%EC%9A%A9-%EB%B0%8F-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81</guid>
            <pubDate>Wed, 13 Jan 2021 11:19:04 GMT</pubDate>
            <description><![CDATA[<h2 id="➕-bem-적용-및-리팩토링-21113">➕ BEM 적용 및 리팩토링 (21.1.13)</h2>
<p>myPage 프로젝트에 BEM을 적용하고 리팩토링하는 과정을 기록한다.</p>
<h3 id="✔-change-1-bem-적용">✔ Change 1: BEM 적용</h3>
<blockquote>
<h4 id="문제점">문제점</h4>
<p>제멋대로인 class와 id 값들때문에 코드의 가독성이 현저하게 떨어졌다.</p>
</blockquote>
<h4 id="해결방안">해결방안</h4>
<p>CSS를 직관적으로 네이밍해주는 BEM을 적용하여 코드의 가독성을 높였다.</p>
<pre><code class="language-html">&lt;div class=&quot;container&quot;&gt;
  &lt;div class=&quot;top&quot;&gt;
  &lt;div class=&quot;left&quot;&gt;
    &lt;a class=&quot;left__menu&quot;&gt;
    &lt;a class=&quot;left__menu&quot;&gt;
    ...
  &lt;div class=&quot;middle&quot;&gt;
    &lt;a class=&quot;middle__a&quot;&gt;
    &lt;a class=&quot;middle__a&quot;&gt;
    ...
  &lt;div class=&quot;right&quot;&gt;
    &lt;img class=&quot;right__icon--instagram&quot;&gt;
    &lt;img class=&quot;right__icon--velog&quot;&gt;
    ...
  &lt;div class=&quot;bottom&quot;&gt;</code></pre>
<blockquote>
<h4 id="문제점-2">문제점 2</h4>
</blockquote>
<ul>
<li>a 태그 속에 있는 값을 가져오기 위한 방법이 필요했다.</li>
<li>시도 1: <code>text()</code> 이용
JQuery를 이용하면 <code>text()</code>라는 메소드로 a 태그 속 문자열을 가져오는 것이 가능했다. 하지만 나는 아직 JQuery를 사용하여 구현한 것이 아니므로 해당 메소드는 사용이 불가능했다.<h4 id="해결방안-2">해결방안 2</h4>
</li>
<li><code>innerText</code>라는 값을 통해 불러올 수 있었다.<pre><code class="language-javascript">while(i &lt; left__menus.length){
left__menus[i].innerText
...</code></pre>
</li>
</ul>
<blockquote>
<h4 id="문제점-3">문제점 3</h4>
</blockquote>
<ul>
<li><code>&lt;input type=&quot;file&gt;&quot;</code>을 꾸며줄 수 있는 방법이 필요했다.<h4 id="해결방안-3">해결방안 3</h4>
</li>
<li><code>&lt;label&gt;</code> 태그로 감싸주고, <code>&lt;input&gt;</code>을 <code>display: none</code>으로 설정. <code>&lt;label&gt;</code>을 꾸밈으로써 해결</li>
<li>하지만 어떤 파일이 올라갔는지 볼 수 없는 단점이 존재 -&gt; JQuery 스크립트로 구현 가능하지만 여기서는 구현 X<pre><code class="language-javascript">//html
&lt;label class=&quot;middle__file&quot;&gt;file
&lt;input type=&quot;file&quot; name=&quot;file&quot; accept=&quot;image/*&quot;&gt;
&lt;/label&gt;
//css
.middle__file:hover{
font-weight: 700;
//hover시 커서를 pointer로 변경
cursor: pointer;
}</code></pre>
</li>
</ul>
<h3 id="✔-change-2-리팩토링">✔ Change 2: 리팩토링</h3>
<blockquote>
<h4 id="문제점-1">문제점</h4>
</blockquote>
<ul>
<li><code>main.js</code>에 너무 많은 코드들로 가독성이 현저히 떨어졌다<h4 id="해결방안-1">해결방안</h4>
</li>
<li><code>main.js</code>의 코드들을 각각 <code>db.js</code>, <code>theme.js</code>, <code>topic.js</code>로 분리함으로써 <code>main.js</code>의 가독성을 높였다. 그 과정에서 기존에 중복되던 코드를 제거하고 반복문을 통해 재사용성 또한 높였다.<pre><code class="language-javascript">//main.js
if(pathname === &#39;/&#39;){
  if(folder === undefined){
    topic.home(request, response);
  } else{
    topic.page(request, response);
  }
} else if(pathname === &#39;/style&#39;){
  topic.style(request, response);
} else if(pathname === &#39;/create&#39;){
  topic.create(request, response);
} else if(pathname === &#39;/create_process&#39;){
  topic.create_process(request, response);
} else if(pathname === &#39;/update&#39;){
  topic.update(request, response);
} else if(pathname === &#39;/update_process&#39;){
  topic.update_process(request, response);
} else if(pathname === &#39;/delete_process&#39;){
  topic.delete_process(request, response);
} else{
  response.writeHead(404);
  response.end(&#39;Not Found&#39;);
}
...
//db.js
let mysql = require(&#39;mysql&#39;);
let db = mysql.createConnection({
host    : &#39;&#39;,
user    : &#39;&#39;,
password: &#39;&#39;,
database: &#39;&#39;,
charset : &#39;&#39;
});
db.connect();
module.exports = db;
//theme.js
function theme(){
let theme = $(&quot;.middle__theme&quot;).getAttribute(&quot;value&quot;);
if(theme == &#39;wave&#39;){
  let newTheme = &#39;normal&#39;
  createTheme(newTheme, &#39;#d9d9d9&#39;, &#39;black&#39;);
} else{
  let newTheme = &#39;wave&#39;
  createTheme(newTheme, &#39;#3b5998&#39;, &#39;#d9d9d9&#39;);
}
}
...
//topic.js
exports.home = function(request, response){
let _url = request.url;
let queryData = url.parse(_url, true).query;
let theme = queryData.theme;
db.query(&#39;select * from list&#39;, function (err, tempMenus){
  if(err){throw err;}
  let menus = template.getMenus(tempMenus, theme);
  html = template.home(menus, theme);
  response.writeHead(200);
  response.end(html);
});
}
...</code></pre>
</li>
</ul>
<h3 id="✔-최종-변경사항">✔ 최종 변경사항</h3>
<blockquote>
<ul>
<li>HTML BEM 사용하여 정리</li>
</ul>
</blockquote>
<ul>
<li>JS 파일 분할을 통한 리팩토링</li>
</ul>
<h3 id="✔-추가할-기능">✔ 추가할 기능</h3>
<blockquote>
<ul>
<li>페이지 구현</li>
</ul>
</blockquote>
<ul>
<li>로그인 구현</li>
<li><strong>반응형 웹페이지 디벨롭</strong></li>
<li><strong>JQuery 사용방법</strong></li>
</ul>
<h3 id="✔-finished-21113">✔ Finished (21.1.13)</h3>
<blockquote>
<p>현재까지 작업한 myPage의 구성을 깔끔하게 정리했다. 아직 부족함이 많겠지만 깔끔해진 코드를 보니 내 마음도 깔끔해지는 것 같다. 이제 웹페이지 기능구현 및 디자인 쪽으로 더 공부를 해보아야겠다. JQuery 사용법도 배워보고, 도중에 필요하다고 생각될 때 페이지와 로그인 또한 구현해보려고 한다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] BEM 방법론]]></title>
            <link>https://velog.io/@woohyun_park/CSS-BEM-%EB%B0%A9%EB%B2%95%EB%A1%A0</link>
            <guid>https://velog.io/@woohyun_park/CSS-BEM-%EB%B0%A9%EB%B2%95%EB%A1%A0</guid>
            <pubDate>Wed, 13 Jan 2021 09:18:36 GMT</pubDate>
            <description><![CDATA[<h3 id="✔-bem-방법론이란">✔ BEM 방법론이란?</h3>
<p>BEM 방법론이란 CSS를 효율적으로 작성할 수 있도록 도와주는 규칙이다. 쉬운 유지보수, 코드의 재사용, 확장성, 직관적인 네이밍을 목표로 한다. </p>
<p>B(Block), E(Element), M(Modifier)로 구조를 나누어서 클래스 이름을 적용해 주는 것이 기본적인 규칙이다.</p>
<h3 id="✔-block">✔ Block</h3>
<ul>
<li>요소를 담고 있는 컨테이너</li>
<li>클래스의 어근을 형성하고 맨 앞에 위치 (e.g. class=&quot;header&quot;)</li>
</ul>
<h3 id="✔-element">✔ Element</h3>
<ul>
<li>블럭 속의 조각들</li>
<li><code>__</code>로 연결하여 블럭 다음에 위치</li>
</ul>
<h3 id="✔-modifier">✔ Modifier</h3>
<ul>
<li>특정 요소의 기능 또는 스타일을 수정</li>
<li>요소 또는 블럭 다음에 <code>--</code>으로 연결하여 표시</li>
<li>반복되는 클래스를 만들거나 같은 스타일을 반복하지 않는다.
(e.g. @extend를 활용하거나 상속을 받을 수 있도록 구조 정리)</li>
<li>boolean type과 key-value type으로 정리<ul>
<li>boolean type: <code>form__button--disabled</code></li>
<li>key-value type: <code>form__butto--color-red</code></li>
</ul>
</li>
</ul>
<h3 id="✔-결론">✔ 결론</h3>
<ul>
<li><code>block__element--modifier</code>의 형태를 가진다.</li>
<li>각 태그에 하나의 클래스만을 사용해야 한다.</li>
<li>클래스만을 활용하여 구조화하는 방법이다.</li>
</ul>
<p>실제로 내 홈페이지를 BEM 방법론을 활용해 변경해보니 훨씬 코드의 가독성이 및 유지보수가 용이한 것을 확인할 수 있었다.</p>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://sangcho.tistory.com/entry/BEM%EB%B0%A9%EB%B2%95%EB%A1%A0">BEM방법론</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[컨퍼런스] DEVIEW 2020: 외국어가 읽힌다 딱! (파파고 이미지 번역)]]></title>
            <link>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-DEVIEW-2020-%EC%99%B8%EA%B5%AD%EC%96%B4%EA%B0%80-%EC%9D%BD%ED%9E%8C%EB%8B%A4-%EB%94%B1-%ED%8C%8C%ED%8C%8C%EA%B3%A0-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%B2%88%EC%97%AD</link>
            <guid>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-DEVIEW-2020-%EC%99%B8%EA%B5%AD%EC%96%B4%EA%B0%80-%EC%9D%BD%ED%9E%8C%EB%8B%A4-%EB%94%B1-%ED%8C%8C%ED%8C%8C%EA%B3%A0-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EB%B2%88%EC%97%AD</guid>
            <pubDate>Wed, 13 Jan 2021 03:54:20 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-파파고-이미지-번역">👌 파파고 이미지 번역</h2>
<p>파파고가 이미지 번역을 구현하는 방법을 알아본다</p>
<h3 id="✔-기존-번역-방법">✔ 기존 번역 방법</h3>
<ol>
<li>문자 인식 (OCR)
문자 검출 -&gt; 문자 인식</li>
<li>단어 그룹화
관련 단어를 사람이 묶고 룰 기반으로 단어를 정렬</li>
<li>기계 번역 (MT)</li>
</ol>
<h3 id="✔-파파고-이미지-번역-방법">✔ 파파고 이미지 번역 방법</h3>
<ol>
<li>문자 인식</li>
<li>단어 그룹화
구글 이미지 번역이 이미 존재하지만, 구글 번역은 한 줄 단위로 묶기 때문에 의미적으로 번역이 부정확한 문제점이 있었다. 따라서 문단 단위로 묶는 번역이 필요할 경우, 문단 단위로 묶어서 번역을 더 자연스럽게 해보려고 했다. 그리고 계층적 텍스트 구조화의 필요성을 깨닳았다. 단어 - 라인 - 블록의 파이프라인을 가지도록 구조화를 시켰다.</li>
</ol>
<p>텍스트 계층화 모델에 사용된 방법은</p>
<ul>
<li>Anchor Box 기반: 네모난 형태를 추출</li>
<li>Segmentation 기반: 다각형으로 형태를 추출</li>
<li>Graph 기반: 관계를 중점적으로 추출</li>
</ul>
<p>중  Segmentation이 가장 알맞다고 판단하여 Sementation 기반의 문자 검출기를 사용하였고, 이를 통해 단어 - 라인 - 블록을 성공적으로 구분해 낼 수 있었다.</p>
<ol start="3">
<li>기계 번역</li>
<li>텍스트 에디팅
텍스트 에디팅은 번역 결과를 실시간으로 이미지에 출력하여 보여주는 기능을 뜻한다. 이는 이미지에 인페인팅 기술 (객체를 자연스럽게 지우는 컴퓨터 비전 기술)를 적용한 후에 번역 결과를 출력해줌으로써 활용 가능하다. 그 과정은 이러하다<ol>
<li>배경색과 글자색 추출: 배경색과 글자색을 추출하고, 배경색은 최빈값으로, 글자색은 배경색과 대비가 가장 선명한 색으로 설정한다.</li>
<li>인페인팅을 통해 배경을 자연스럽게 제거한다.</li>
<li>알맞은 번역 결과를 써 넣는다. 이때, 번역 결과가 기존 텍스트가 있던 자리에 보기 좋게 들어갈 수 있도록 폰트의 크기와 줄바꿈 등을 자동으로 조절한다.</li>
</ol>
</li>
</ol>
<p>이러한 과정을 통해 파파고 번역의 단어 정렬 성능과 이미지 번역 성능 모두 기존의 번역기들을 뛰어넘는 결과를 도출했다.</p>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://tv.naver.com/v/16969172/list/657024">외국어가 읽힌다 딱! (파파고 이미지 번역)</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[MySQL] 접속 에러 EEROR 2003 (HY000): Can't connect to MySQL server on 'localhost' (10061)]]></title>
            <link>https://velog.io/@woohyun_park/MySQL-%EC%A0%91%EC%86%8D-%EC%97%90%EB%9F%AC-EEROR-2003-HY000-Cant-connect-to-MySQL-server-on-localhost-10061</link>
            <guid>https://velog.io/@woohyun_park/MySQL-%EC%A0%91%EC%86%8D-%EC%97%90%EB%9F%AC-EEROR-2003-HY000-Cant-connect-to-MySQL-server-on-localhost-10061</guid>
            <pubDate>Tue, 12 Jan 2021 15:28:11 GMT</pubDate>
            <description><![CDATA[<h3 id="✔-접속-에러-eeror-2003-hy000-cant-connect-to-mysql-server-on-localhost-10061">✔ 접속 에러 EEROR 2003 (HY000): Can&#39;t connect to MySQL server on &#39;localhost&#39; (10061)</h3>
<p>MySQL 서버가 실행되고 있지 않은 경우에 뜨는 에러 메세지. MySQL 서버를 시작해주면 정상적으로 동작한다.</p>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://hoon93.tistory.com/9">MySQL 접속 에러 / EEROR 2003 (HY000): Can&#39;t connect to MySQL server on &#39;localhost&#39; (10061)</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[MySQL/Project] myPage - 데이터베이스]]></title>
            <link>https://velog.io/@woohyun_park/MySQLProject-myPage-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4</link>
            <guid>https://velog.io/@woohyun_park/MySQLProject-myPage-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4</guid>
            <pubDate>Mon, 11 Jan 2021 15:12:14 GMT</pubDate>
            <description><![CDATA[<h2 id="➕-mysql-데이터베이스">➕ MySQL 데이터베이스</h2>
<p>myPage 프로젝트를 MySQL 데이터베이스 기반으로 변경하는 과정을 기록한다.</p>
<h3 id="✔-update-1-21111">✔ Update 1 (21.1.11)</h3>
<h4 id="변경점">변경점</h4>
<ul>
<li>모든 탭을 파일 기반이 아닌 MySQL 데이터베이스 기반으로 변경. 단, 이미지는 포함하지 않고 텍스트만 이동</li>
</ul>
<h4 id="변경방법">변경방법</h4>
<pre><code>//mysql 모듈 설정
let mysql = require(&#39;mysql&#39;);
let db = mysql.createConnection({
  host    : &#39;localhost&#39;,
  user    : &#39;root&#39;,
  password: &#39;111111&#39;,
  database: &#39;test&#39;
});

//db와 연결
db.connect();

//MySQL를 명령어 사용, 데이터를 추출
db.query(MySQL 명령어(e.g. &#39;SELECT * FROM table&#39;), function(error, results, fields){
  //&#39;table[i].열&#39;의 형식으로 값을 추출할 수 있다.
});</code></pre><h4 id="개선방안">개선방안</h4>
<ul>
<li><del>이미지를 MySQL 데이터베이스에 저장하는 방법</del></li>
<li><del>이모티콘을 MySQL 데이터베이스에 깨지지 않게 저장하는 방법</del></li>
</ul>
<h3 id="✔-update-2-21112">✔ Update 2 (21.1.12)</h3>
<h4 id="--모든-탭에-cud-기능을-추가">- 모든 탭에 CUD 기능을 추가</h4>
<h4 id="--데이터베이스에서-경로를-읽어오는-방식으로-이미지-구현">- 데이터베이스에서 경로를 읽어오는 방식으로 이미지 구현</h4>
<ul>
<li>Blob 포맷으로 저장하는 방법이 있으나, Blob의 경우 메모리를 약 30%정도 더 많이 사용하므로 파일의 경로를 데이터베이스에 저장하고, 경로를 데이터베이스에서 불러오는 식으로 구현<h4 id="--데이터베이스에-이모지-저장을-구현">- 데이터베이스에 이모지 저장을 구현</h4>
</li>
</ul>
<ol>
<li>데이터베이스를 utf8mb4로 생성 또는 변경<pre><code class="language-mysql">ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
CREATE DATABASE database_name DEFAULT CHARSET = utf8mb4 DEFAULT COLLATE = utf8mb4_unicode_ci;</code></pre>
</li>
<li>Connection을 생성할 때 <code>charset</code>을 <code>utf8mb4</code>로 설정<pre><code class="language-javascript">let db = mysql.createConnection({
host    : &#39;localhost&#39;,
user    : &#39;root&#39;,
password: &#39;zxcvZXCV&#39;,
database: &#39;myPage&#39;,
charset : &#39;utf8mb4&#39;
});</code></pre>
</li>
</ol>
<h4 id="개선방안-1">개선방안</h4>
<ul>
<li>페이지 구현</li>
<li>로그인 구현</li>
</ul>
<h3 id="✔-finished-21112">✔ Finished (21.1.12)</h3>
<p>이모티콘이 안되서 하루종일 삽질했는데, 다음날 보니 한줄만 추가하면 되는 것이었다... 너무나 허무하지만 프로그래밍이 원래 그런 것이라... 그래도 구현 하고나니 후련하다. 이제 페이지와 로그인도 구현해보자!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[node.js/MySQL] MySQL 모듈 사용법]]></title>
            <link>https://velog.io/@woohyun_park/node.jsMySQL-MySQL-%EB%AA%A8%EB%93%88-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@woohyun_park/node.jsMySQL-MySQL-%EB%AA%A8%EB%93%88-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Mon, 11 Jan 2021 13:39:07 GMT</pubDate>
            <description><![CDATA[<h3 id="✔-설치">✔ 설치</h3>
<p><code>npm install -S mysql</code>을 이용하여 mysql 모듈을 설치한다</p>
<h3 id="✔-사용">✔ 사용</h3>
<pre><code>let mysql = require(&#39;mysql&#39;);
let db = mysql.createConnection({
  host : &#39;localhost&#39;,
  user : &#39;root&#39;,
  password : &#39;111111&#39;,
  database : &#39;test&#39;
});

db.connect();

db.query(MySQL 명령어(e.g. &#39;SELECT * FROM table&#39;), function(error, results, fields){
  //&#39;table[i].열&#39;의 형식으로 값을 추출할 수 있다.
});

db.end();</code></pre><h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://opentutorials.org/module/3560">생활코딩: Node.js - MySQL</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[MySQL] Problem? 데이터베이스에 이모티콘 입력하기]]></title>
            <link>https://velog.io/@woohyun_park/MySQL-%EC%9D%B4%EB%AA%A8%ED%8B%B0%EC%BD%98-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@woohyun_park/MySQL-%EC%9D%B4%EB%AA%A8%ED%8B%B0%EC%BD%98-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Mon, 11 Jan 2021 11:39:20 GMT</pubDate>
            <description><![CDATA[<h3 id="✔-문제점">✔ 문제점</h3>
<p>MySQL Database에 이모티콘을 넣으려고 하자 입력이 되지 않는 문제가 발생했다.</p>
<pre><code class="language-MySQL">//해당 문장을 입력
INSERT INTO `guest` VALUES (3, &#39;Hello&#39;,&#39;😇💙&#39;,NOW(),&#39;박우현&#39;);
//아래와 같이 출력되며 정상적으로 입력이 실핼 X
mysql&gt; INSERT INTO `guest` VALUES (3, &#39;Hello&#39;,&#39;��&#39;,NOW(),&#39;박우현&#39;);
    &#39;&gt;</code></pre>
<h3 id="✔-시도">✔ 시도</h3>
<ol>
<li>데이터의 타입을 <code>blob</code>으로 바꾸어 보았으나 정상적으로 동작하지 않았다.
```
//기존</li>
</ol>
<p>+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int         | NO   | PRI | NULL    | auto_increment |
| title       | varchar(30) | NO   |     | NULL    |                |
| description | text        | YES  |     | NULL    |                |
| created     | datetime    | NO   |     | NULL    |                |
| author      | varchar(30) | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+</p>
<p>ALTER TABLE guest MODIFY description blob;
//변경 후
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | int         | NO   | PRI | NULL    | auto_increment |
| title       | varchar(30) | NO   |     | NULL    |                |
| description | blob        | YES  |     | NULL    |                |
| created     | datetime    | NO   |     | NULL    |                |
| author      | varchar(30) | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+</p>
<pre><code>
2. 데이터베이스의 인코딩을 utf8mb4로 변경하였으나 정상적으로 동작하지 않았다.</code></pre><p>ALTER DATABASE guest CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;</p>
<pre><code>
3. `my.cnf`, 또는 `my.ini`의 설정을 변경하라고 해서 찾아보았지만 해당 파일들이 존재하지 않았다.</code></pre><p>//cmd창에 입력
mysqld --help --verbose</p>
<p>//결과
...
Default options are read from the following files in the given order:
C:\WINDOWS\my.ini C:\WINDOWS\my.cnf C:\my.ini C:\my.cnf C:\Program Files\MySQL\MySQL Server 8.0\my.ini C:\Program Files\MySQL\MySQL Server 8.0\my.cnf
...</p>
<p>//해당 디렉토리를 모두 찾아보았으나 아무런 파일도 존재하지 않았다.</p>
<pre><code>
4. `show variables like &#39;c%&#39;`를 이용해 utf8임을 확인하였다.</code></pre><p>mysql&gt; show variables like &#39;c%&#39;;
+----------------------------------------------+---------------------------------------------------------+
| Variable_name                                | Value                                                   |
+----------------------------------------------+---------------------------------------------------------+
| caching_sha2_password_auto_generate_rsa_keys | ON                                                      |
| caching_sha2_password_private_key_path       | private_key.pem                                         |
| caching_sha2_password_public_key_path        | public_key.pem                                          |
| character_set_client                         | utf8mb4                                                 |
| character_set_connection                     | utf8mb4                                                 |
| character_set_database                       | utf8mb4                                                 |
| character_set_filesystem                     | binary                                                  |
| character_set_results                        | utf8mb4                                                 |
| character_set_server                         | utf8mb4                                                 |
| character_set_system                         | utf8                                                    |
| character_sets_dir                           | C:\Program Files\MySQL\MySQL Server 8.0\share\charsets\ |
| check_proxy_users                            | OFF                                                     |
| collation_connection                         | utf8mb4_0900_ai_ci                                      |
| collation_database                           | utf8mb4_unicode_ci                                      |
| collation_server                             | utf8mb4_0900_ai_ci                                      |
| completion_type                              | NO_CHAIN                                                |
| concurrent_insert                            | AUTO                                                    |
| connect_timeout                              | 10                                                      |
| core_file                                    | OFF                                                     |
| create_admin_listener_thread                 | OFF                                                     |
| cte_max_recursion_depth                      | 1000                                                    |
+----------------------------------------------+---------------------------------------------------------+</p>
<pre><code>
### ✔ 해결방안
콘솔에 ��와 같이 출력되는 것으로 보아 콘솔의 문제인가 싶다.</code></pre><p>mysql&gt; INSERT INTO <code>guest</code> VALUES (3, &#39;Hello&#39;,&#39;��&#39;,NOW(),&#39;박우현&#39;);</p>
<p>```</p>
<p>아시는 고수님들 도와주세요...ㅠㅠ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[인터넷] 도메인, DNS 그리고 DDNS]]></title>
            <link>https://velog.io/@woohyun_park/%EC%9D%B8%ED%84%B0%EB%84%B7-%EB%8F%84%EB%A9%94%EC%9D%B8-DNS-%EA%B7%B8%EB%A6%AC%EA%B3%A0-DDNS</link>
            <guid>https://velog.io/@woohyun_park/%EC%9D%B8%ED%84%B0%EB%84%B7-%EB%8F%84%EB%A9%94%EC%9D%B8-DNS-%EA%B7%B8%EB%A6%AC%EA%B3%A0-DDNS</guid>
            <pubDate>Mon, 11 Jan 2021 06:03:19 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-도메인-dns-그리고-ddns">👌 도메인, DNS, 그리고 DDNS</h2>
<p>인터넷을 하다보면 자주 듣는 말들인 도메인, DNS, 그리고 DDNS에 대해 알아본다.</p>
<h3 id="✔-도메인이란">✔ 도메인이란?</h3>
<p>도메인이란 IP주소를 일정한 규칙에 따라 의미있는 문자형태로 표현한 것을 말하는데, 예를 들자면 google.com 또는 naver.com과 같은 것들을 의미한다.</p>
<p>사이트가 담고있는 정보와는 전혀 연관성이 없는 숫자로만 이루어진 IP 주소는 기억하기 어려운데, 이 IP 주소를 도메인에 링크해줌으로써 쉽게 외우고 접속할 수 있도록 도와주는 것이다.</p>
<h3 id="✔-dns">✔ DNS?</h3>
<p>이렇다면 어떻게 IP 주소와 도메인을 연결해주는가? 답은 바로 DNS에 있다. DNS는 Domain Name System으로, DNS 서버를 통해서 숫자로 이루어진 IP 주소와 일정한 형식을 가진 도메인을 링크시켜 주는 일을 한다. 이를 통해 편리하게 웹 사이트를 이용할 수 있다.</p>
<h3 id="✔-dns의-작동원리">✔ DNS의 작동원리</h3>
<p><img src="https://images.velog.io/images/woohyun_park/post/961eca67-6b99-443a-8a4b-3fb6492fab5e/image.png" alt="">
DNS는 기본적으로 재귀적으로 작동한다. 이를 순서대로 표현해보자면,</p>
<ol>
<li>PC에 <a href="http://www.naver.com%EC%9D%B4%EB%9D%BC%EB%8A%94">www.naver.com이라는</a> 도메인 주소를 입력한다</li>
<li>PC가 Local DNS에 <a href="http://www.naver.com%EC%97%90">www.naver.com에</a> 대한 IP 주소를 요청한다</li>
<li>Local DNS에 요청된 도메인에 해당하는 IP 주소가 있다면 PC로 응답을 전송한다. 그렇지 않다면 다른 DNS 서버들과 통신을 시작한다.</li>
<li>Local DNS가 Root DNS에 해당 도메인에 대한 IP 주소를 요청한다.</li>
<li>Root DNS에서 com 도메인을 관리하는 com DNS와 통신을 하라는 응답을 보낸다.</li>
<li>Local DNS는 다시 com DNS와 통신을 시작하고, naver.com DNS로 요청을 전송한다.</li>
<li>naver.com DNS에서 IP를 찾으면, Local DNS로 응답한다.</li>
<li>Local DNS는 IP 주소를 PC로 전달한다.</li>
</ol>
<h3 id="✔-ddns">✔ DDNS?</h3>
<p>기본적으로 DNS는 정적 IP에 대해 동작한다. 따라서 서버 A의 아이피주소가 바뀌면 도메인은 동작하지 않게 된다. 따라서 서버 A의 아이피주소가 변경되더라도 자동으로 갱신 후 재등록 할 수 있도록 도와주는 것이 Dynamic DNS, DDNS라고 할 수 있다.</p>
<p>대부분의 가정에서 사용하는 ipTime 공유기에서도 DDNS 설정을 손쉽게 해 줄 수 있는데, 특수기능 - DDNS설정에 들어가면 손쉽게 도메인과 사용자ID(이메일)만 입력함으로써 DDNS를 생성해 줄 수 있다.</p>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://ykarma1996.tistory.com/19">도메인? DNS? 무슨 말인가요?</a></li>
<li><a href="https://ykarma1996.tistory.com/20">DDNS란 무엇일까</a></li>
<li><a href="https://ijbgo.tistory.com/27#:~:text=DNS%EB%9E%80&amp;text=DNS%20%EC%84%9C%EB%B2%84%EB%8A%94%20%EC%9D%B4%EB%A6%84%EC%97%90,%EC%9A%94%EC%B2%AD%EC%9D%84%20%EC%BF%BC%EB%A6%AC%EB%9D%BC%EA%B3%A0%20%ED%95%9C%EB%8B%A4.">DNS 동작원리</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[인터넷/Project] myPage - 포트포워딩]]></title>
            <link>https://velog.io/@woohyun_park/%EC%9D%B8%ED%84%B0%EB%84%B7Project-myPage-%ED%8F%AC%ED%8A%B8%ED%8F%AC%EC%9B%8C%EB%94%A9</link>
            <guid>https://velog.io/@woohyun_park/%EC%9D%B8%ED%84%B0%EB%84%B7Project-myPage-%ED%8F%AC%ED%8A%B8%ED%8F%AC%EC%9B%8C%EB%94%A9</guid>
            <pubDate>Fri, 08 Jan 2021 08:03:39 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-쉽고-간단한-포트포워딩">👌 쉽고 간단한 포트포워딩</h2>
<p>인터넷 상의 컴퓨터를 내 컴퓨터로 연결하도록 설정해주는 포트포워딩에 대해 알아본다.</p>
<h3 id="✔-사설-네트워크">✔ 사설 네트워크</h3>
<p>인터넷을 사용하기 위해서는 IP 주소가 있어야 한다. 현재 우리가 대부분 사용하고 있는 IPv4 아이피 체계는 0~255까지의 숫자 4개로 구성되며, 2의 32제곱인 약 42억개의 주소만 할당할 수 있다. 전 세계적으로 폭발적으로 IP 주소에 대한 수요가 증가하게 되면서 IP 주소 또한 부족해졌고, 따라서 별도의 공용 네트워크가 아닌 사설 네트워크를 구축하여 하나의 공용 IP를 여러개의 장비들에서 나눠 사용할수 있도록 하는 공유기를 보편적으로 사용하게 되었다. 공유기는 NAT(Network Address Translation)을 통해 공용 네트워크와 사설 네트워크를 연결해주게 된다.</p>
<p>*공용 네트워크 (WAN): Wide Area Network의 줄임말로, 전세계적으로 네트워크에 접속할 수 있는 네트워크를 말함. 공용 IP 주소(Public IP Address)가 할당됨.
*사설 네트워크 (LAN): Local Area Network의 줄임말로, 한정된 지역에서 개인이 사용하는 장치들이 연결된 내부 네트워크를 말함. 사설 IP 주소(Private IP Address)가 할당됨.</p>
<h3 id="✔-포트포워딩">✔ 포트포워딩</h3>
<p>공유기를 사용하는 경우, 외부에서 공유기까지는 공용 IP 주소로 쉽게 접근 가능하지만, 공유기에 연결된 디바이스까지 접속하기 위해서는 사설 IP 주소와 포트가 필요한데, 이를 전달해주는 역할을 하는 것이 포트포워딩이다.</p>
<p>간단하게 말하면 외부에서 공용 IP 주소 외부 포트로 신호를 보내면, 공유기가 해당 신호를 사설 IP 주소 내부 포트로 전달해 주는것을 포트포워딩이라고 한다.</p>
<p>대부분의 가정에서 사용하는 ipTime을 예로 들면, 고급설정 - NAT/라우터 관리 - 포트포워드 설정에서 서비스하고자 하는 컴퓨터의 IP 주소를 내부 IP 주소로 설정하고, 외부 포트와 내부 포트 또한 알맞게 설정해주면 간단하게 홈서버를 배포할 수 있다.</p>
<h3 id="✔-nat과-브릿지">✔ NAT과 브릿지</h3>
<p>하지만 네트워크 - SK 모뎀 - ipTime 공유기 - 디바이스의 순서로 서비스되는 우리집에서는 공유기의 포트포워딩 설정만으로는 서비스가 불가능했다. ipTime 공유기의 사설 네트워크 안에서는 포트포워딩이 정상적으로 이루어졌지만, 공용 네트워크에서 접속할때에는 SK 모뎀에서 신호를 잃어버리게 된다.</p>
<p>따라서 해결방법은 SK 모뎀에서 ipTime 공유기로 포트포워딩을 해서 2중으로 포트포워딩을 하는 방법과 SK 모뎀의 설정값을 브릿지로 변경하여 주는 방법이 있었다.</p>
<p>첫번째 방법은 따로 설명할 필요 없이 포트포워딩을 2번 해주는 방식이고, 두번째 방법은 SK 모뎀의 공유기 기능을 삭제하고 ip를 분배해주는 역할로써 존재하게 하는 것이다. </p>
<p>무슨 말이냐면 SK 모뎀은 초기 설정상 NAT, 즉 사설 네트워크를 한번 만들고 ipTime 공유기를 통해 다시 한번 사설 네트워크를 만들도록 되어있는데, 그렇게 되면 포트포워딩이 2번 필요해진다.</p>
<p>따라서 SK 모뎀의 NAT 기능을 브릿지로 변경해주어, 공유기가 아닌 공용 IP 주소를 전달만 해주는 방식으로 변경해주면 사설 네트워크를 ipTime 한번만 거치게 되어 포트포워딩이 1번만 필요하게 된다.</p>
<h3 id="✔-mypage-서비스">✔ myPage 서비스</h3>
<p>처음에는 왜 안되지 하고 애를 많이 먹었지만, 알고보면 사실 복잡한 문제는 아니었다. 포트포워딩을 통해 손쉽게 내 프로젝트를 배포할 수 있었고, 내가 서버를 켜놓는 동안에는 친구들이나 가족들이 댓글을 달 수 있어서 매우 뿌듯했다.</p>
<p><img src="https://images.velog.io/images/woohyun_park/post/e54d66ab-78f3-441b-9259-ee83d29d5879/image.png" alt=""></p>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://lamanus.kr/59">포트 포워딩이란?</a></li>
<li><a href="https://paststory.tistory.com/211">SKB 기가공유기 H514G 브릿지 모드 설정하는 방법</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[컨퍼런스] SOSCON 2020: 「2019 삼성 주니어SW창작대회」수상작 및 Bixby Capsule 개발 경험담]]></title>
            <link>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-SOSCON-2020-%E3%80%8C2019-%EC%82%BC%EC%84%B1-%EC%A3%BC%EB%8B%88%EC%96%B4SW%EC%B0%BD%EC%9E%91%EB%8C%80%ED%9A%8C%E3%80%8D%EC%88%98%EC%83%81%EC%9E%91-%EB%B0%8F-Bixby-Capsule-%EA%B0%9C%EB%B0%9C-%EA%B2%BD%ED%97%98%EB%8B%B4</link>
            <guid>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-SOSCON-2020-%E3%80%8C2019-%EC%82%BC%EC%84%B1-%EC%A3%BC%EB%8B%88%EC%96%B4SW%EC%B0%BD%EC%9E%91%EB%8C%80%ED%9A%8C%E3%80%8D%EC%88%98%EC%83%81%EC%9E%91-%EB%B0%8F-Bixby-Capsule-%EA%B0%9C%EB%B0%9C-%EA%B2%BD%ED%97%98%EB%8B%B4</guid>
            <pubDate>Fri, 08 Jan 2021 01:51:31 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-sw로-만드는-더-나은-세상">👌 SW로 만드는 더 나은 세상</h2>
<p>대전 대신고등학교 2학년 Reinventor 동아리가 꿈꾸는 더 나은 세상에 대해 알아본다.</p>
<h3 id="✔-노인-복지-플랫폼-all-new">✔ 노인 복지 플랫폼 ALL NEW</h3>
<p>스마트폰 사용이 미숙한 노약자 및 취약계층을 위해 제작된 사이트가 작은 글씨, 복잡한 UI를 가지고 있어 불편함이 생긴다는 것을 인지하고, 큰 글씨와 단순한 UI 속에 많은 행사 및 일자리 정보들을 한눈에 보기 쉽게 알려줄 수 있으면 좋지 않을까라는 생각아래 탄생한 어플리케이션이다.</p>
<p>노인관련 행사 및 데이터를 API와 직접 요청을 통해 수집하고, flask와 java를 사용하여 어플리케이션을 구현하였다. 음성인식 및 읽어주기 기능을 도입해 노인분들의 접근성을 높였으며, UI 디자인시에는 큰 글씨와 단순한 구성으로 가독성과 접근성을 극대화하였다.</p>
<h3 id="✔-bixby-sdk-기반-마스크-알리미">✔ Bixby SDK 기반 마스크 알리미</h3>
<p>빅스비는 음성으로 손쉽게 제어가 가능하다는 생각과 공적 마스크 재고상황을 알려주자는 생각이 맞물려 빅스비를 기반으로 한 마스크 알리미를 개발하였다. 공적마스크알리미API를 사용하여, &#39;주변 마스크 위치 알려줘&#39;라고 한마디를 하면 실시간으로 재고가 있는 약국의 위치와 생년월일에 따른 구입가능여부를 보기쉽게 알려준다.</p>
<p>비록 공적마스크알리미API가 서비스를 종료함에 따라서 애플리케이션의 서비스도 종료되었지만, 오픈소스를 통해 Bixby를 학습하는 과정에서 많은것을 배웠다고 한다.</p>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://www.soscon.net/Session/Section/12">사회에 기여하는 SW 개발 경험 소개
「2019 삼성 주니어SW창작대회」수상작 및 Bixby Capsule 개발 경험담</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[MySQL] MySQL 사용법]]></title>
            <link>https://velog.io/@woohyun_park/MySQL-MySQL-%EC%82%AC%EC%9A%A9%EB%B2%95</link>
            <guid>https://velog.io/@woohyun_park/MySQL-MySQL-%EC%82%AC%EC%9A%A9%EB%B2%95</guid>
            <pubDate>Thu, 07 Jan 2021 13:15:39 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-mysql이란">👌 MySQL이란?</h2>
<p>My Structured Query Language의 약자로 가장 널리 사용되고 있는 관계형 데이터베이스 중 하나이다. 관계형 데이터베이스는 서로 관계를 맺는 여러 테이블에 항목을 나누어 저장하고 필요한 부분을 추출해서 사용하는 데이터베이스 관리 시스템이다.</p>
<p><code>mysql -uA -p</code>: A라는 유저의 로그인창을 띄운다.
<code>CREATE DATABASE A</code>: A라는 데이터베이스를 생성한다.
<code>DROP DATABASE A</code>: A라는 데이터베이스를 제거한다.
<code>SHOW DATABASES</code>: 존재하는 데이터베이스들을 보여준다.
<code>SHOW TABLES</code>: 존재하는 테이블들을 보여준다
<code>DESC A</code>: A라는 테이블의 구조를 보여준다.
<code>USE A</code>: A라는 데이터베이스에 접속한다.</p>
<p><code>CREATE TABLE A()</code>: A라는 테이블을 생성한다.</p>
<pre><code class="language-mysql">CREATE TABLE A(
 //최대 11자리의 int값을 가지고, NULL일수 없으며, 자동으로 증가하는 id라는 이름의 column
 id INT(11) NOT NULL AUTO_INCREMENT,
 //최대 100자리의 char값을 가지고, NULL일수 없는 title이라는 이름의 column
 title VARCHAR(100) NOT NULL,
 //text값을 가지고, NULL일수 있는 description이라는 이름의 column
 description TEXT NULL,
 //datetime값을 가지고, NULL일수 없는 created라는 이름의 column
 created DATETIME NOT NULL,
 //id를 PRIMARY KEY값으로 지정
 PRIMARY KEY(id)
);</code></pre>
<p><code>RENAME TABLE a TO b</code>: 테이블 a의 이름을 b로 변경한다</p>
<p><code>INSERT INTO test(a, b, c) VALUES(&#39;A&#39;, &#39;B&#39;, &#39;NOW()&#39;)</code>: test이라는 테이블에 a=A, b=B, c=현재시간 을 가진 row를 삽입한다.</p>
<p><code>SELECT * FROM test</code>: test라는 테이블을 선택한다.
<code>SELECT a, b, c FROM test</code>: test에서 a, b, c column을 선택한다.
<code>SELECT * FROM test WHERE a=&#39;A&#39;</code>: test에서 a column의 값이 a인 데이타만 선택한다.
<code>SELECT * FROM test ORDER BY a DESC LIMIT 2</code>: test에서 a column을 기준으로 큰 값 순으로 최소 2까지 선택한다.
<code>SELECT a AS aa FROM test</code>: test에서 a라는 column을 aa로 이름을 바꾸어 선택한다.</p>
<p><code>SELECT * FROM table LEFT JOIN a ON table.a.id = a.id</code>: table의 a.id값을 a의 id값과 연동해 선택한다.</p>
<p><code>UPDATE test SET a=&#39;A&#39; b=&#39;B&#39; WHERE id=2</code>: test에서 id가 2인 데이터의 a를 A로, b를 B로 설정한다.</p>
<p><code>DELETE FROM test WHERE id = 2</code>: id가 2인 데이터를 test에서 삭제한다.
<code>DELETE FROM test WHERE id in (1,2,3)</code>: id가 1,2,3인 데이터를 test에서 삭제한다.
<code>DELETE FROM test WHERE id &gt; 3</code>: id가 3 초과인 데이터를 test에서 삭제한다.</p>
<p><code>ALTER TABLE test AUTO_INCREMENT = startValue</code>: test의 AUTO_INCREMENT 시작값을 startValue로 바꾼다.
<code>ALTER TABLE test ADD COLUMN column VARCHAR(15)</code>: test에 column이라는 VARCHAR(15)의 속성을 가진 열을 추가한다.</p>
<p><code>\! clear</code>: 콘솔을 클리어한다.</p>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://opentutorials.org/course/3161">생활코딩: DATABASE2 - MySQL</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[node.js] 글 수정과 삭제]]></title>
            <link>https://velog.io/@woohyun_park/node.js-%EA%B8%80-%EC%88%98%EC%A0%95%EA%B3%BC-%EC%82%AD%EC%A0%9C</link>
            <guid>https://velog.io/@woohyun_park/node.js-%EA%B8%80-%EC%88%98%EC%A0%95%EA%B3%BC-%EC%82%AD%EC%A0%9C</guid>
            <pubDate>Thu, 07 Jan 2021 12:29:35 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-글-수정과-삭제">👌 글 수정과 삭제</h2>
<p>node.js에서 글을 수정하고 삭제하는 방법을 알아본다.</p>
<h3 id="✔-글-수정">✔ 글 수정</h3>
<ul>
<li><p><code>pathname === &#39;/update&#39;</code>:
기존 파일에서 수정할 수 있도록 <code>fs.readfile</code>을 통해 기존 파일의 <code>title</code>과 <code>description</code>을 불러온다. 수정된 데이터를 전송할때는, 만약 <code>title</code> 값이 수정될 경우를 대비해서, <code>fileName</code> 또한 <code>type=&#39;hidden&#39;</code>으로 전송해준다</p>
<pre><code class="language-javascript">...
&lt;form action=&quot;/update_process&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;
&lt;input type=&quot;hidden&quot; name=&quot;fileName&quot; value=&quot;${title}&quot;&gt;
...</code></pre>
</li>
<li><p><code>pathname === &#39;/update_process&#39;</code>:
<code>enctype=&#39;multipart/form-data&#39;</code>를 사용하므로 formidable을 사용하여 전송된 값을 받아주었다. 전송된 값을 바탕으로 <code>fs.rename(oldpath, newpath)</code>와 <code>fs.writeFile(path, description, callback)</code>을 이용해서 기존 파일을 재설정하고 파일을 새롭게 만들어 주었다.</p>
<pre><code class="language-javascript">let form = new formidable.IncomingForm();
form.parse(request, function(err, fields, files){
  let fileName = fields.fileName;
  let folder = fields.folder;
  ...
  fs.rename(oldpath, newpath, function(err){
    fs.writeFile(newpath, description, &#39;utf8&#39;, function(err){
      fs.rename(oldpathImg, newpathImg, function(err){
        ...</code></pre>
</li>
</ul>
<h3 id="✔-글-삭제">✔ 글 삭제</h3>
<ul>
<li><code>pathname === &#39;/delete_process&#39;</code>:
post 방식으로 전송된 데이터들을 받은 후 <code>fs.unlink(path, callback)</code>를 이용해서 파일을 삭제해 주었다.<pre><code class="language-javascript">...
request.on(&#39;data&#39;, function(data){
body = body + data;
})
request.on(&#39;end&#39;, function(){
let post = qs.parse(body);
let title = post.title;
...
fs.unlink(`./tab/${folder}/data/${title}`, function(error){
  fs.unlink(`./tab/${folder}/img/${title}.png`, function(error){
    ...</code></pre>
</li>
</ul>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://youtu.be/Q6MQ5bi7HFY">생활코딩 Node.js: App 제작 - 글수정 - 수정된 내용 저장</a></li>
<li><a href="https://youtu.be/RDj4Hns1Qnk">생활코딩 Node.js: App 제작 - 글삭제 기능 완성</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[컨퍼런스] DEVIEW 2020: 그래서, 네이버내비가 주는 길은 뭐가 다른데]]></title>
            <link>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-%EA%B7%B8%EB%9E%98%EC%84%9C-%EB%84%A4%EC%9D%B4%EB%B2%84%EB%82%B4%EB%B9%84%EA%B0%80-%EC%A3%BC%EB%8A%94-%EA%B8%B8%EC%9D%80-%EB%AD%90%EA%B0%80-%EB%8B%A4%EB%A5%B8%EB%8D%B0</link>
            <guid>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-%EA%B7%B8%EB%9E%98%EC%84%9C-%EB%84%A4%EC%9D%B4%EB%B2%84%EB%82%B4%EB%B9%84%EA%B0%80-%EC%A3%BC%EB%8A%94-%EA%B8%B8%EC%9D%80-%EB%AD%90%EA%B0%80-%EB%8B%A4%EB%A5%B8%EB%8D%B0</guid>
            <pubDate>Thu, 07 Jan 2021 04:23:31 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-네이버내비">👌 네이버내비</h2>
<p>네이버내비가 경로를 추천해주는 방법에 대해서 알아본다.</p>
<h3 id="✔-기존-경로-제공-방법">✔ 기존 경로 제공 방법</h3>
<p>기본적으로 경로 제공 방법은 다음과 같은 순서를 따른다</p>
<ol>
<li>출발지, 목적지, 탐색옵션 설정</li>
<li>길찾기 서버 + 도로네트워크 데이터 + 교통정보를 분석</li>
<li>경로 제공</li>
</ol>
<p>기존에는 이러한 과정에서 가중치를 두는 방식으로 경로를 제공했다. 이를테면 가장빠른(시간), 무료우선(요금), 큰길우선 또는 이륜차 우선(도로 종류)에 가중치를 주는 방식으로 말이다.</p>
<h3 id="✔-다양한-경로를-제공할수는-없을까">✔ 다양한 경로를 제공할수는 없을까?</h3>
<p>기존 방식은 최적화된 도로에서 크게 벗어나지 않는 여러개의 경로를 제공하였다. 이를테면 내비게이션은 강남과 강북을 지나는 길로 성수대교를 꼭 지나치게 하고 나머지 세세한 경로만 바꾸는 식이다.</p>
<p>하지만 사용자들은 자신이 익숙한 길이나 동호대교, 또는 영동대교를 선택했을때의 가능성도 궁금해한다. 고속도로에서도 마찬가지이다. 이 고속도로를 추천해 주는데, 내가 익숙한 다른 고속도로는 어떨지와 같은 것들을 궁금해한다는 것이다.</p>
<h3 id="✔-양방향-알고리즘의-활용">✔ 양방향 알고리즘의 활용</h3>
<p>로드 네트워크 데이터는 양방향의 양수가중치를 갖는 비정형 그래프 데이터이다. 이에 사용 가능한 다익스트라 알고리즘은 최적의 경로를 찾는데에는 적합하지만, 다양한 경로를 제공하는데에는 적합하지 못하다. 따라서 다익스트라 알고리즘을 기반으로 양방향 A* 알고리즘을 추가로 채택해 다양성을 높였다.</p>
<p>양방향 알고리즘의 과정은 1. 정방향 확장과 역방향 확장을 통해 후보링크를 생성, 2. 다수의 후보링크로 후보 경로를 생성하는 과정을 거친다.</p>
<p>그 과정 중 고려해야 할 것은, 후보링크가 최적화된 경로와 일정 이상의 비용차이가 발생하게 되면 대안경로로 부적합하다는 것이며, 이 과정에서 링크의 세부속성, 출발지/목적지까지의 거리, 확장시의 비용, 인접링크와의 연결성 등을 고려한다.</p>
<p>각각 후보링크들은 유사도(경로간 중복률, 중복링크의 특성, 도로네트워크 속성 등을 고려)를 기준으로 클러스터링 한 후, 각각의 클러스터들을 비용순으로 정렬하면 유의미한 다양한 경로 제공이 가능하다.</p>
<p>이를 통해 네이버내비는 경로의 다양성을 208% 상승시키고, 응답시간또한 77% 상승시킬 수 있었다.</p>
<h3 id="✔-발전-가능성">✔ 발전 가능성</h3>
<p>네이버내비가 앞으로 나아가야 할 길은 다음과 같다.</p>
<ul>
<li>정확한 소요시간 제공: 실시간 궤적정보 수집과 수집된 궤적정보를 도로에 매칭하는 것으로 실시간 교통정보를 정확히 생성해 내는것이 첫번째 과제이다. </li>
</ul>
<p>또한 소요시간을 제공하는 데에는 실시간교통정보와 예측교통정보를 조합해서 사용하는데, 가중치를 얼마나 둘 것인지에 대한 의사결정 또한 발전시켜 나가야 할 것이다.</p>
<ul>
<li><p>정체 전파: 사고나 어떠한 원인으로 인해 정체가 있을 때 해당 정체가 어떤 흐름으로 전파되는지에 대한 분석을 해나간다.</p>
</li>
<li><p>경로에 대한 개인화: 개인의 시간, 요금, 도로 등에 대한 선호도에 따라서 경로를 개인화해서 제공하는 것이 내비게이션의 미래일 것이다.</p>
</li>
</ul>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://tv.naver.com/v/16971870">그래서, 네이버내비가 주는 길은 뭐가 다른데</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[컨퍼런스] NHN Forward 2020: Welcome to JAMstack]]></title>
            <link>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-NHN-Forward-2020-Welcome-to-JAMstack</link>
            <guid>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-NHN-Forward-2020-Welcome-to-JAMstack</guid>
            <pubDate>Wed, 06 Jan 2021 00:48:23 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-jamstack">👌 JAMstack</h2>
<p>프런트엔드 개발자가 웹 애플리케이션 구성부터 개발, 배포까지 가능하게 하는, 새롭게 떠오르는 JAMstack에 대해 알아본다.</p>
<h3 id="✔-전통적-웹-vs-serverless-웹">✔ 전통적 웹 vs Serverless 웹</h3>
<p>전통적인 웹의 경우에는 <code>DB - App Server - Web Server - Browser</code>의 경로를 통해 운영된다. 하지만 최근 가상의 클라우드 환경에 서버를 두고 운영하는 serverless 웹이 만들어지면서 웹의 생태계가 급변하고 있다. Serverless 웹의 운영경로는 <code>Storage (FaunaDB, DynamoDB 등) - Cloud Function - API Gateway - Browser</code>로, 서버 운영 및 유지보수가 필요없고 개발에만 집중할 수 있는 환경을 제공해준다.</p>
<h3 id="✔-jamstack의-출현">✔ JAMstack의 출현</h3>
<p>JAMstack의 JAM은 JavaScript, API, Markup을 뜻하는 말로, 동적인 요소, 서버 또는 DB, 그리고 문서 내용의 시각적 표현을 각각 중추적으로 담당하게 된다. JAMstack은 정적 사이트 생성기로 페이지를 사전 생성하여 제공하게 되는데,</p>
<p>따라서 다음과 같은 장점이 있다.</p>
<ul>
<li>높은 안정성: 정적으로 사이트를 생성하므로 공격에 노출이 적다.</li>
<li>높은 신속성: 페이지로 미리 생성되어 있어 렌더링에 걸리는 시간이 적다.</li>
<li>높은 확장성 및 경제성: 정적인 페이지만 생성하면 되므로 확장하기 용이하고 정적인 사이트를 호스팅해주는 곳은 매우 경제적이다.</li>
<li>높은 자동성: 정적인 사이트만 수정하여 업로드하면 되므로 자동화하기 용이하다.</li>
</ul>
<p>하지만 다음과 같은 단점도 존재한다</p>
<ul>
<li>제한적 빌드 속도: 대량의 페이지를 빌드하기 위해서는 시간이 오래 걸린다.</li>
<li>동적 컨텐츠의 한계: JavaScript와 API를 사용하여 동적 컨텐츠를 다루어야 하는데, 이는 근본적인 해결책이 아니며 효율적이지 못하다.</li>
</ul>
<p>이러한 단점을 극복하기 위하여 점진적 빌드라는 방식이 새롭게 생겨났다. 점진적 빌드란 변경시에 모두 재빌드하는것이 아니라, 변경에 필요한 부분만 새로 빌드함으로써 빌드의 효율성과 신속성을 높이는 것을 말한다. 아직 실험적인 단계라서 JAMstack이 프론트엔드의 미래라고 확답할수는 없지만, 계속해서 눈여겨보아야 할 기술임은 분명하다.</p>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://forward.nhn.com/session/20">Welcome to JAMstack</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Project] myPage - CRUD]]></title>
            <link>https://velog.io/@woohyun_park/Project-myPage-CRUD</link>
            <guid>https://velog.io/@woohyun_park/Project-myPage-CRUD</guid>
            <pubDate>Tue, 05 Jan 2021 17:55:47 GMT</pubDate>
            <description><![CDATA[<h2 id="➕-crud-추가">➕ CRUD 추가</h2>
<p>myPage 프로젝트에 CRUD를 추가하는 과정을 기록한다.</p>
<h3 id="✔-challenge-1-2115">✔ Challenge 1 (21.1.5)</h3>
<h4 id="문제점">문제점</h4>
<p>게시글에 이미지를 업로드하고 다운로드하기 위해서는 <code>enctype=&quot;multipart/form-data&quot;</code>를 사용해야 했는데, 해당 타입으로 암호화하자 텍스트가 제대로 파싱되지 않았다.</p>
<h4 id="시도-1">시도 1</h4>
<p>따라서 텍스트를 먼저 업로드하고, 이미지 업로드 창으로 넘어가도록 하였다. 하지만 이미지를 업로드하는데에도 알맞은 변수들을 지정해 줘야 해서 이미지를 저장하는데 필요한 변수들만 새롭게 입력하도록 했다.</p>
<p>쿼리스트링에 <code>folder</code>과 <code>title</code> 값이 이상한 모양으로 전송되는 것을 확인했고, 알맞게 parsing을 해줌으로써 <code>folder</code>과 <code>title</code>을 추출하려고 시도했다. 하지만 request가 비동기적 방법이여서인지, 두 변수가 제대로 입력되지 않았다</p>
<pre><code class="language-JavaScript">...
request.on(&#39;end&#39;, function(){
  let post = qs.parse(body, &#39;name=&quot;&#39;, &#39;&quot;\r\n\r\n&#39;);
  folder = post.folder.split(&#39;\r\n&#39;)[0];
  title = post.title.split(&#39;\r\n&#39;)[0];
})
let form = new formidable.IncomingForm();
form.parse(request, function(err, fields, files){
  ...
}
...</code></pre>
<h4 id="시도-2">시도 2</h4>
<p>사실 텍스트, 즉 폼의 값들은 <code>fields</code>에 저장되어 있던 것이었다. 따라서 단순히 <code>fields</code>에 있는 <code>form</code> 변수들을 참조하는 것으로 게시물 생성을 구현할 수 있었다.</p>
<pre><code class="language-javascript">else if(pathname === &#39;/create_process&#39;){
  let form = new formidable.IncomingForm();
  form.parse(request, function(err, fields, files){
    let folder = fields.folder;
    let title = fields.title;
    let description = fields.description;
    let oldpath = files.file.path;
    let imgType = files.file.type.split(&#39;/&#39;)[1];
    let newpath = `./tab/${folder}/img/${title}.${imgType}`;
    fs.rename(oldpath, newpath, function(err){
      fs.writeFile(`./tab/${folder}/data/${title}`, description, &#39;utf8&#39;, function(err){
        response.writeHead(302, {&#39;Location&#39;: `/?id=${folder}&amp;theme=${theme}`});
        response.end();
      });
    });
  });
}</code></pre>
<h4 id="참고-사이트">참고 사이트</h4>
<ul>
<li><a href="https://yanguelna-programmer.tistory.com/37">Node.js 파일 업로드하기</a></li>
<li><a href="https://behonestar.tistory.com/103">querysting을 통한 form-data 파싱</a></li>
</ul>
<h3 id="✔-update-1-2116">✔ Update 1 (21.1.6)</h3>
<h4 id="변경점">변경점</h4>
<ul>
<li><code>update</code>와 <code>delete</code> 분기</li>
<li><code>home</code>에서는 <code>create</code>, <code>update</code>, <code>delete</code> 버튼 보이지 않도록 수정</li>
<li><code>id(folder)</code> 값을 <code>hidden</code>으로 전송하도록 수정</li>
<li><code>insight</code> 탭에서는 <code>column</code>이 3개가 아닌 2개로 나오도록 수정</li>
</ul>
<h4 id="변경방법">변경방법</h4>
<p><code>update</code>의 경우 <code>fs.rename(oldpath, newpath, callback)</code>으로 기존 파일을 rename하고, <code>fs.writeFile(newpath, description, callback)</code>으로 새롭게 파일을 덮어씌우는 방식으로 작업</p>
<pre><code class="language-javascript">...
fs.rename(oldpathText, newpathText, function(err){
  fs.writeFile(newpathText, description, &#39;utf8&#39;, function(err){
    fs.rename(oldpathImg, newpathImg, function(err){
      ...</code></pre>
<p><code>delete</code>의 경우 <code>fs.unlink(path, callback)</code>을 이용해서 데이터와 이미지를 모두 삭제</p>
<pre><code class="language-javascript">...
fs.unlink(`./tab/${folder}/data/${title}`, function(error){
  fs.unlink(`./tab/${folder}/img/${title}.png`, function(error){
    ...</code></pre>
<h4 id="문제점-및-개선방안">문제점 및 개선방안</h4>
<ul>
<li><del><code>update</code>와 <code>remove</code>시 이미지의 확장자를 png로 한정했다. 이미지의 확장자를. 가져오는 방법을 찾아볼 것.</del></li>
<li><del><code>update</code>시 이미지 변경이 불가하다. 해결방안을 모색해 볼 것.</del></li>
<li>포스트들을 표시할 때 <code>column</code>을 이용하니까 가로로 차곡차곡 쌓이지 않고 문단처럼 왼쪽부터 채워나간다. 포스트가 많아지면 <code>flexbox</code>를 사용하여 리팩토링 하는것도 고민해 볼 사항. 또한 페이지를 추가해도 좋겠다.</li>
</ul>
<p>+21.1.11: MySQL로 변경중이므로, MySQL로 이미지를 가져오는 방법을 찾아볼 것.</p>
<h3 id="✔-update-2-2117">✔ Update 2 (21.1.7)</h3>
<h4 id="변경점-1">변경점</h4>
<ul>
<li><p>모듈을 사용해 function과 변수 정리:</p>
<pre><code class="language-javascript">let template = require(&#39;./lib/template.js&#39;);
...
//main.js에서 template.js 모듈을 불러와서 사용</code></pre>
</li>
<li><p><code>&lt;form&gt;</code>에 css 적용:</p>
<pre><code class="language-javascript">input[type=text]{
//포커스시 발생하는 효과 제거
outline-style: none;
//둥근 모서리를 3px로
border-radius: 3px;
}</code></pre>
</li>
<li><p><code>&lt;input&gt;</code> 자동완성 해제:</p>
<pre><code class="language-javascript">//자동완성을 off로 설정
&lt;input type=&quot;text&quot; name=&quot;title&quot; autocomplete=&#39;off&#39;&gt;</code></pre>
</li>
<li><p>보안 강화:</p>
<pre><code class="language-javascript">//sanitize-html을 이용해 &lt;script&gt; 실행을 차단
let sanitizeHtml = require(&#39;sanitize-html&#39;);
...
let sanitizeTitle = sanitizeHtml(title);
</code></pre>
</li>
</ul>
<p>//parse를 이용해 허용되지 않은 디렉토리를 서치하는것을 보안
<code>let filteredTitle = parse.parse(title).base</code>
fs.readdir(<code>./tab/${filteredTitle}/data</code>, function(error, tempTextlist){
  ...</p>
<p>```</p>
<h3 id="✔-finished-2117">✔ Finished (21.1.7)</h3>
<p>MyPage 프로젝트에 CRUD를 모두 구현했다. 하지만 아직도 nodejs 서버를 어떻게 구현하고 배포하는지를 잘 모르겠다. 프론트앤드를 목표를 하고 있지만, 서버쪽도 조금은 배워놓는게 좋을 것 같고, 동적으로 이 프로젝트를 배포해보고 싶기 때문에 서버쪽 공부가 필요해 보인다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[node.js] 파일 생성과 리다이렉션]]></title>
            <link>https://velog.io/@woohyun_park/node.js-%ED%8C%8C%EC%9D%BC-%EC%83%9D%EC%84%B1%EA%B3%BC-%EB%A6%AC%EB%8B%A4%EC%9D%B4%EB%A0%89%EC%85%98</link>
            <guid>https://velog.io/@woohyun_park/node.js-%ED%8C%8C%EC%9D%BC-%EC%83%9D%EC%84%B1%EA%B3%BC-%EB%A6%AC%EB%8B%A4%EC%9D%B4%EB%A0%89%EC%85%98</guid>
            <pubDate>Tue, 05 Jan 2021 17:12:26 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-파일-생성과-리다이렉션">👌 파일 생성과 리다이렉션</h2>
<p>node.js에서 파일 생성과 리다이렉션 하는 방법을 알아본다</p>
<h3 id="✔-파일-생성">✔ 파일 생성</h3>
<ul>
<li><code>fs</code>의 메소드 중 하나인 <code>writeFile</code>을 이용하면 파일을 생성할 수 있다.</li>
<li><code>response.writeHead(302)</code>를 이용하면 리다이렉션이 가능하다.<pre><code class="language-javascript">...
fs.writeFile(`data/${title}`, description, &#39;utf8&#39;, function(err){ //파일생성
response.writeHead(302, {Location: `/?id=${title}`}); //리다이렉션
response.end();
})
...</code></pre>
</li>
</ul>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://www.youtube.com/watch?v=dBZDJloj9xk">생활코딩 Node.js: App 제작 - 파일생성과 리다이렉션</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[node.js] POST 방식 데이터 송수신]]></title>
            <link>https://velog.io/@woohyun_park/node.js-POST-%EB%B0%A9%EC%8B%9D-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%86%A1%EC%88%98%EC%8B%A0</link>
            <guid>https://velog.io/@woohyun_park/node.js-POST-%EB%B0%A9%EC%8B%9D-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%86%A1%EC%88%98%EC%8B%A0</guid>
            <pubDate>Tue, 05 Jan 2021 17:08:09 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-post-방식">👌 POST 방식</h2>
<p>POST 방식으로 데이터를 송수신하는 방법을 알아본다.</p>
<h3 id="✔-데이터-송신">✔ 데이터 송신</h3>
<ul>
<li><code>form</code> 태그의 속성값 중 하나인 <code>method</code>를 사용하면 <code>form</code>의 데이터를 <code>post</code> 방식으로 송신할 수 있다.<pre><code class="language-html">&lt;form action=&quot;/create_process&quot; method=&quot;post&quot;&gt;
&lt;input type=&quot;text&quot; name=&quot;title&quot;&gt;
&lt;textarea name=&quot;description&quot;&gt;&lt;/textarea&gt;
&lt;input type=&quot;submit&quot;&gt;
&lt;/form&gt;</code></pre>
</li>
</ul>
<h3 id="✔-데이터-수신">✔ 데이터 수신</h3>
<ul>
<li><code>pathname === &#39;/create_process&#39;</code>로 분기한 후, <code>request.on</code>을 이용해 데이터를 받아온다<pre><code class="language-javascript">...
else if(pathname === &#39;/create_process&#39;){
var body = &#39;&#39;;
request.on(&#39;data&#39;, function(data){
  body = body + data;
});
request.on(&#39;end&#39;, function(){
  var post = qs.parse(body);
  var title = post.title;
  var description = post.description
  });
...
}
...</code></pre>
</li>
</ul>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://www.youtube.com/watch?v=WMX5zcalAM0">생활코딩 Node.js: App 제작 - POST 방식으로 전송된 데이터 받기</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[인사이트] M1칩의 현실과 미래]]></title>
            <link>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-M1%EC%B9%A9%EC%9D%98-%ED%98%84%EC%8B%A4%EA%B3%BC-%EB%AF%B8%EB%9E%98</link>
            <guid>https://velog.io/@woohyun_park/%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4-M1%EC%B9%A9%EC%9D%98-%ED%98%84%EC%8B%A4%EA%B3%BC-%EB%AF%B8%EB%9E%98</guid>
            <pubDate>Tue, 05 Jan 2021 10:43:38 GMT</pubDate>
            <description><![CDATA[<h2 id="👌-혁신적인-m1칩">👌 혁신적인 M1칩</h2>
<p>지난해 11월 10일 애플이 새롭게 발표한 애플 실리콘 M1칩은 엄청난 성능과 가능성을 보여주면서 애플이 향후 PC업계를 뒤흔들 준비를 하고 있다는 것을 보여주었다. 오늘은 그 놀라운 M1칩에 대해서 알아본다.</p>
<h3 id="✔-m1칩의-특징">✔ M1칩의 특징</h3>
<ul>
<li>M1은 성능과 기능, 그리고 전력 효율을 끌어올린 제품</li>
<li>M1은 맥을 위한 최초의 시스템온칩(SoC)이다. SoC는 대형 실리콘 패키지에 여러가지 칩들을 집약한 시스템으로, CPU, GPU, 메모리, IO컨트롤러 보안 등을 모두 결합하여 간결하고 효율적이다.</li>
<li>M1은 통합 메모리 아키텍처(UMA)로, SoC칩의 모든 기술이 메모리 복사 없이 같은 데이터에 접근을 가능캐 함으로써 성능과 전력효율이 비약적으로 상승되었다.</li>
<li>8코어 CPU로 4개의 고효율 코어와 4개의 고성능 코어를 사용한다. 가벼운 작업에는 전력 소모량을 낮추고, 복잡한 작업에는 8코어를 전부 사용해 최고의 연산 속도를 자랑한다.</li>
<li>8코어 GPU로 최강의 그래픽 처리속도를 자랑한다.</li>
<li>뉴럴 엔진을 통해 머신러닝, 영상 분석, 음성 인식 등의 분야에서 최고의 연산 속도를 자랑한다.</li>
</ul>
<h3 id="✔-m1칩이-빠른-이유">✔ M1칩이 빠른 이유</h3>
<p>M1칩은 앞서 서술했다시피 SoC으로, 대형 패키지에 여러가지 칩들을 탑재한 시스템이다. 또한 UMA(Unified Memory Architecture)를 통해 메모리를 공유하면서 여러가지 칩들이 메모리를 복사 없이 사용할 수 있게 되면서 성능과 전력 효율이 비약적으로 상승하게 된다.</p>
<p>다른 제조사들이 SoC방식을 채택하기 어려운 이유는, 각각 제조사들이 특화된 칩들을 따로따로 제작하기 때문에 회사를 합병하거나 하지 않는 이상 이해관계의 충돌이 필연적으로 발생하게 된다. 하지만 애플은 그들이 모든 걸 다 만드므로 그런 걱정을 할 필요가 없다.</p>
<p>또한 M1은 CPU의 속도를 비약적으로 향상시켰는데, 일반적으로 CPU의 속도를 향상시키는 방식에는 두가지가 있다. 순차적으로 더 빠르게 실행시키는 것과, 더 많은 명령을 병렬로 실행하는 방법. 하지만 전자의 경우 클럭 주파수를 더 이상 높이기 어렵게 되어 사실상 현재로서는 불가능하고, 후자를 더 발전시킴으로써 속도를 향상시킬 수 있다. </p>
<p>이러한 병렬실행은 더 많은 CPU코어를 넣거나, 비순차 실행 (Out-of-Order Execution)을 통해 명령을 실행함으로써 속도를 향상시킬 수 있다. 비순차 실행은 여러개의 명령어들을 분석해서 서로간에 의존성이 있는지를 알아냄으로써, 의존성이 없는 명령들을 병렬로 실행할 수 있는데, M1칩은 이러한 OoO 실행을 통해 엄청난 속도를 자랑한다.</p>
<p>M1칩이 다른 회사들의 OoO 실행보다 뛰어난 이유는, 기본적으로 인텔/AMD 코어의 4개의 코드 디코더보다 훨씬 빠른 8개의 디코더가 장착되어 있고, 명령어를 사용하는 방식또한 다르다. 인텔/AMD는 x86을 사용하여, 명령어의 길이가 1~15바이트로 유동적인 반면, 애플의 경우 고정 사이즈인 RISC를 사용한다. 따라서 x86은 디코딩을 할 때 실제로 명령어를 분석 한 후에 잘라서 디코더로 넘겨야 하지만, RISC는 분석을 건너뛰고 잘라서 디코더로 넘기면 된다. 따라서 애플은 디코더를 추가하기도 쉽고, 처리과정 또한 훨씬 더 효율적이다.</p>
<h3 id="✔-m1칩이-미칠-영향">✔ M1칩이 미칠 영향</h3>
<ul>
<li>모바일과 데스크탑 경험의 합체
스마트폰 중심으로 발전하던 앱 및 컨텐츠 시장이, 맥OS에서도 많은 iOS의 앱들을 실행시킬 수 있게 되면서 모바일과 데스크탑 경험이 점차 융합되는 모습을 볼 수 있을 것이다. 더욱 더 다채로운 경험을 가능케 하는 맥의 경쟁력이 높아질 가능성이 무궁무진하다.</li>
<li>애플 왕국의 확장
모바일과 데스크탑 경험이 합체되면서 개발자들은 하나만 개발하면 모바일과 데스크탑에 동일하게 적용할 수 있기 때문에 애플의 컨텐츠는 더욱 더 방대해지고 경쟁력있어질 것이다.</li>
<li>경쟁력있는 가격의 고성능 컴퓨터
기존 맥북 프로 이상의 성능을 내면서 가격은 전과 동일한 M1칩을 장착한 맥북 에어는 경쟁력이 있을 수 있다. </li>
<li>AMD/Intel의 돌파구 확보 시급
SoC 설계를 위한 비즈니스 모델이 없고, x86 명령어들이 레거시가 되어 성능 개선에 발목을 잡게 되었다. 이 회사들이 살아남기 위해서 돌파구 확보가 시급한 상황이다.</li>
</ul>
<h3 id="👍-참고-사이트">👍 참고 사이트</h3>
<ul>
<li><a href="https://www.apple.com/kr/newsroom/2020/11/apple-unleashes-m1/">Apple, M1칩을 공개하다</a></li>
<li><a href="https://happist.com/576689/m1-%EC%B9%A9-%EC%A0%81%EC%9A%A9-%EB%A7%A5%EB%B6%81%EC%9D%98-%EC%86%8C%EB%B9%84%EC%9E%90-%EC%98%81%ED%96%A5-%EC%84%B8%EA%B0%80%EC%A7%80">인텔과 결별한 애플 M1칩 적용 맥북이 소비자를 흔들 세가지 요소</a></li>
<li><a href="https://news.hada.io/topic?id=3315">Apple M1칩은 왜 그렇게 빠를까?</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>