<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>15_hwukjunwoo.log</title>
        <link>https://velog.io/</link>
        <description>미래 개발자</description>
        <lastBuildDate>Wed, 24 Feb 2021 16:38:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>15_hwukjunwoo.log</title>
            <url>https://images.velog.io/images/15_hwukjunwoo/profile/522b3c48-2ebd-48f8-b420-d4d255e8827b/KakaoTalk_Photo_2021-01-05-22-35-36.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 15_hwukjunwoo.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/15_hwukjunwoo" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[SQL. 첫걸음]]></title>
            <link>https://velog.io/@15_hwukjunwoo/SQL.-%EC%B2%AB%EA%B1%B8%EC%9D%8C</link>
            <guid>https://velog.io/@15_hwukjunwoo/SQL.-%EC%B2%AB%EA%B1%B8%EC%9D%8C</guid>
            <pubDate>Wed, 24 Feb 2021 16:38:54 GMT</pubDate>
            <description><![CDATA[<h2 id="1강-데이터-베이스">1강 데이터 베이스</h2>
<blockquote>
<p>데이터는 컴퓨터안에 기록되어있는 숫자<br>—&gt; 이 데이터를 집합한곳이 Database이다.</p>
</blockquote>
<blockquote>
<h4 id="데이터베이스-관리-시스템dbms">데이터베이스 관리 시스템(DBMS)</h4>
</blockquote>
<ol>
<li><strong>생산성</strong> : 검색, 추가, 삭제, 갱신 같은 기능 탑제</li>
<li><strong>기능성</strong> : 복수유저 요청, 대용량 데이터, 고속검색 기능</li>
<li><strong>신뢰성</strong> : 동시에 성능 향상 --&gt; Scalability(<strong>확장성</strong>) &amp; Load balancing(<strong>부하 분산</strong>) == <strong>클러스터 구성, 스케일 아웃</strong></li>
</ol>
<p>--&gt; 다른 저장 장치로 Export 반대로 Import할수있다. (부분백업도 가능하다)</p>
<blockquote>
<h4 id="db를-조작하는-언어--sql">DB를 조작하는 언어 : SQL</h4>
<p>Relational Database Management System 관계형이다.(SQL를 사용가능한건 관계형밖에없다)0</p>
</blockquote>
<blockquote>
<h4 id="sql-명령의-종류">SQL 명령의 종류</h4>
</blockquote>
<ol>
<li>DML: <strong>M</strong>:Manipulation(조작) 새로 추가, 삭제, 갱신 등 조작할때</li>
<li>DDL: <strong>D</strong>:Definition(정의) 데이터를 관리하는 DB객체를 만들거나 삭제하는 명령어</li>
<li>DCL: <strong>C</strong>:Control(제어) Transaction을 제어하는 명령과 데이터 접근권한을 제어</li>
</ol>
<h2 id="2강-다양한-데이터베이스">2강 다양한 데이터베이스</h2>
<blockquote>
<h4 id="데이터베이스-종류">데이터베이스 종류</h4>
</blockquote>
<ol>
<li>계층형: 데이터저장을 폴더와 파일 등의 계층구조 (요즘 채택잘안됨)</li>
<li>관계형: 관계 대수(relational algebra) 것에 착안하여 고안한 데이터베이스다.(표형식 데이터)</li>
<li>객체지향: 자바나 C++를 객체지향언어라고 합니다. 객체를 중심으로하는 언어.</li>
<li>XML: 태그를 이용해 마크업 문서를 작성(SQL명령을 사용할수 X, 검색할때 XQuery라는 전문명령어 사용 </li>
<li>키-밸류 스토어: 키와 대응하는 값을 저장(조합은 연상배열 이나 해시테이블) </li>
</ol>
<ul>
<li>NoSQL(not only SQL) - 열 지향 데이터베이스</li>
<li>연상배열 (Associative array): 자료구조하나로 키하나와 값하나가 연관되어 있으며 키를 통해 연관되는 값을 얻을수있습니다.(딕셔너리,맵)이렇게많이 부릅니다.</li>
</ul>
<blockquote>
<h4 id="rdbms-사용-시스템">RDBMS 사용 시스템</h4>
<p>메인프레임은 대부분 RDBMS를 사용한다고 해도 과언이 아니다. 
하지만 요즘들어 <strong>다운사이징</strong>으로 인해 소형 워크스테이션으로 대체된것입니다.
인프라는 당연히 <strong>인터넷</strong></p>
</blockquote>
<blockquote>
<h4 id="데이터베이스-제품">데이터베이스 제품</h4>
</blockquote>
<ol>
<li>Oracle: 표준이라고해도 문제없을 정도로 유명합니다. 유닉스 워크스테이션 중심</li>
<li>DB2: IBM이 개발했고 IBM컴퓨터에서만 구동되었다. 이후 플랫폼을 옮겼지만 확대할수없었다.</li>
<li>SQL Server: 마이크로소프트가 개발/ 윈도우 플랫폼에서만 동작</li>
<li>PostgreSQL: 오픈소스 커뮤니티 개발/ 버클리 캠퍼스에서 탄생/ 실험적인 기능+독특한 구조 포함</li>
<li>MySQL: 오픈소스/ 처음에는 <strong>경량</strong> 데이터베이스라는 점 강조(기능 최소화) 하지만 기능 확장</li>
<li>SQLite: 오픈소스/ 휴대전화용/ 임베디드 시스템에 쓰이는 RDBMS.</li>
</ol>
<blockquote>
<h4 id="sql의-방언과-표준화">SQL의 방언과 표준화</h4>
<p>RDBMS는 처음부터 SQL 명령어를 이용해 DB를 조작하도록 설계된만큼 SQL를 사용할수없다.
기능 확장이 이루어지는 과정에서 비슷한 조작을 실행하더라도 서로 다른 명령어가 필요한 상황</p>
</blockquote>
<ul>
<li>*<em>키워드 생략 *</em>- 데이터를 삭제할때 오라클이나 SQL Server는 from을 생략 하지만 다른곳에는 생략할경우 에러발생.</li>
<li><strong>외부 결합</strong> - 하는 방법은 &quot;LEFT JOIN&quot;이다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[전화번호 목록]]></title>
            <link>https://velog.io/@15_hwukjunwoo/%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D</link>
            <guid>https://velog.io/@15_hwukjunwoo/%EC%A0%84%ED%99%94%EB%B2%88%ED%98%B8-%EB%AA%A9%EB%A1%9D</guid>
            <pubDate>Wed, 24 Feb 2021 16:27:40 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h4 id="문제-설명">문제 설명</h4>
<p>전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.
구조대 : 119
박준영 : 97 674 223
지영석 : 11 9552 4421</p>
</blockquote>
<p>입출력 예제</p>
<table>
<thead>
<tr>
<th align="left">phone_book</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="left">[119, 97674223, 1195524421]</td>
<td align="center">false</td>
</tr>
<tr>
<td align="left">[123,456,789]</td>
<td align="center">true</td>
</tr>
<tr>
<td align="left">[12,123,1235,567,88]</td>
<td align="center">false</td>
</tr>
</tbody></table>
<blockquote>
<pre><code>def solution(phone_book):
    answer = True
    phone_book.sort()
    for p1, p2 in zip(phone_book, phone_book[1:]):
        if p2.startswith(p1):
            return False
    return answer</code></pre></blockquote>
<pre><code>Ideal 정답</code></pre><p>def solution(phoneBook):
    phoneBook = sorted(phoneBook)
    for p1, p2 in zip(phoneBook, phoneBook[1:]):
        if p2.startswith(p1):
            return False
    return True
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[완주하지 못한 선수]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Coding-Test1</link>
            <guid>https://velog.io/@15_hwukjunwoo/Coding-Test1</guid>
            <pubDate>Wed, 24 Feb 2021 15:21:10 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h4 id="문제-설명">문제 설명</h4>
<p>수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.
마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>마라톤 경기에 참여한 선수의 수는 1명 이상 100,000명 이하입니다.</li>
<li>completion의 길이는 participant의 길이보다 1 작습니다.</li>
<li>참가자의 이름은 1개 이상 20개 이하의 알파벳 소문자로 이루어져 있습니다.</li>
<li>참가자 중에는 동명이인이 있을 수 있습니다.</li>
</ul>
<table>
<thead>
<tr>
<th align="left">participant</th>
<th align="center">completion</th>
<th align="right">return</th>
</tr>
</thead>
<tbody><tr>
<td align="left">[leo, kiki, eden]</td>
<td align="center">[eden, kiki]</td>
<td align="right">leo</td>
</tr>
<tr>
<td align="left">[marina, josipa, nikola, vinko, filipa]</td>
<td align="center">[josipa, filipa, marina, nikola]</td>
<td align="right">vinko</td>
</tr>
<tr>
<td align="left">[mislav, stanko, mislav, ana]</td>
<td align="center">[stanko, ana, mislav]</td>
<td align="right">mislav</td>
</tr>
</tbody></table>
<blockquote>
<pre><code>def solution(participant, completion):
    participant.sort()
    completion.sort()
    for p,c in zip(participant, completion):
        if p != c:
            return p
    return participant.pop()</code></pre></blockquote>
<pre><code>IDEAL한 정답</code></pre><p>import collections
def solution(participant, completion):
    answer = collections.Counter(participant) - collections.Counter(completion)
    return list(answer.keys())[0]</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[1차 프로젝트 (My Dongmyo Trip)]]></title>
            <link>https://velog.io/@15_hwukjunwoo/1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-My-Dongmyo-Trip</link>
            <guid>https://velog.io/@15_hwukjunwoo/1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-My-Dongmyo-Trip</guid>
            <pubDate>Mon, 15 Feb 2021 04:02:56 GMT</pubDate>
            <description><![CDATA[<h2 id="⛩-dm-friends--동묘앞-프렌즈-">⛩ DM Friends ( 동묘앞 프렌즈 )</h2>
<p><a href="https://store.kakaofriends.com/kr/index">카카오 프렌즈샵</a> 사이트
소개: 카카오프렌즈는 일상의 즐거움이 가득한 카카오프렌즈 캐릭터 상품들을 다양하게 만나는 공간입니다.</p>
<h3 id="👨👩👧👦-팀원">👨‍👩‍👧‍👦 팀원</h3>
<ul>
<li>세계 최고의 거리. 스포티(sporty)함과 캐주얼의 경계를 넘나드는 과감한 믹스매치 정신을 본받기위해 동묘앞 프렌즈가 모였다!</li>
<li>Front-end: 임대호, 임태진, 김해인, 한채빈</li>
<li>Back-end: 우혁준, 이승연(PM), 유하람<h3 id="📅-개발-기간">📅 개발 기간</h3>
기간: 2020.12.14 ~ 2020.12.24 (11일)<h3 id="🧑💻-적용-기술">🧑‍💻 적용 기술</h3>
</li>
<li>Front-end: React.js(Class), React-router, SASS</li>
<li>Back-end: Python, Django, MySQL, Request, Pyjwt, Bcrypt, CORS-headers, Git, Github<h3 id="💁♀️-구현-기능">💁‍♀️ 구현 기능</h3>
</li>
<li>프로젝트 초기 세팅</li>
<li>Data Modeling</li>
<li>회원가입, 로그인, 이메일 인증 구현</li>
<li>게시글 &amp; 댓글 좋아요/ 취소 기능 구현</li>
<li>데코레이터 구현<h3 id="🎥-영상">🎥 영상</h3>
<a href="https://www.youtube.com/watch?v=r2SD8_ePyOI&amp;feature=youtu.be">클로닝 동영상</a></li>
</ul>
<h3 id="💰-기억에-남는-코드">💰 기억에 남는 코드</h3>
<p>이 코드라기 보다 왜 이부분이 기억에 많이 남는 이유는 팀원들에게 미안해서이다. 처음에 모델링할때 생각을 깊게하지않고 그냥 이메일인증번호는 테이블안에 추가하면 되겠지 생각했다. 그런데 이메일 인증을 하려고했을때 테이블이 하나가 더 필요하다는걸 깨달았다. 왜냐하면 인증번호를 받고 그뒤에 입력을 안하거나 인증번호를 잊어버렸거나 하면 계속 테이블 row가 생성이 되는것이였다. 그래서 테이블을 생성하고 거기에 인증번호를 임시저장하고 그 인증번호가 맞으면 인증번호를 delete하고 다음 단계로 넘어가게 설계를 했다. 미안하게 내가 깃헙에 수정된 부분이 머지되고 그룹 멤버들에게 피해가 갔다. 데이터 클로링을 할수없어 데이터를 하나하나 넣었는데 그걸 다 지우고 시작해야했다. 그 밑에는 잘 나온 결과 물이다. 
<img src="https://images.velog.io/images/15_hwukjunwoo/post/8c5c0790-17be-4a30-a607-abbce424b147/image.png" alt=""><img src="https://images.velog.io/images/15_hwukjunwoo/post/79bfdc99-476a-4f43-8444-a20e8b31b1b1/image.png" alt="">
회원가입 페이지에서 이메일 인증을 구현하는 부분이다.
<img src="https://images.velog.io/images/15_hwukjunwoo/post/a163ac09-8b4f-4bed-9189-2b29803cf618/20210214125725334.gif" alt=""></p>
<h3 id="🗣️-프로젝트-소감">🗣️ 프로젝트 소감</h3>
<ul>
<li>2주간 멤버들과 한 공간에서 합숙을 하면서 코딩을 할수있어서 너무 좋았다. (새벽까지하는 멤버들과 버그가 생겼을때 함께 해결할수있는 멤버들 최고~)</li>
<li>비록 부족한 실력으로  완성된 결과물은 완벽 할 수 없지만 끝까지 노력해서 다들 만족 할 수 있는 결과가 나와서 행복했다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[3 Months......]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Late-Bloomer</link>
            <guid>https://velog.io/@15_hwukjunwoo/Late-Bloomer</guid>
            <pubDate>Sat, 13 Feb 2021 20:26:44 GMT</pubDate>
            <description><![CDATA[<h2 id="1-the-beginning">1. The Beginning</h2>
<p>나에게 2020년은 <strong>예측 불가</strong>에 해이다.
코로나로 인해 계획이 틀어졌다.
2019년말에 퇴사를 하고 Computer Science 석사과정을 준비했고 2020년 8월부터 대학원에 갈예정이였다. 하지만 나는 한국에 돌아왔다.... <img src="https://images.velog.io/images/15_hwukjunwoo/post/011c8f56-5e4e-4b52-8e34-a85c9d4c0adb/image.png" alt=""></p>
<h3 id="개발을-시작한-계기">*개발을 시작한 계기?</h3>
<p>대학 때 나는 Business Management를 공부하다가 학교 선배가 운영하는 Entrepreneurship Club 초대를 받아 가게 되었다. 너무 유익한 시간이었지만 나는 나름 반성하는 시간이 됐다. 그 이유는 나도 대학 들어왔을 때 온라인쇼핑몰에 관심이 많아 <strong>&quot;하고 싶다&quot;</strong> 생각만 하고 있었는데 나보다 어린 친구들이 벌써 판매까지 하고 있었다. 한동안 충격에 클럽에 참석하지 못했다. 몇 주 뒤 선배에게 연락이 왔고 선배와 얘기를 할 수 있는 기회가 있었다. 그때 나는 메이저에 대한 고민을 하고 있을 때였다. 선배는 많은 조언을 했고 선배의 메이저(Computer Information System)를 추천해줬고 군대를 다녀온 뒤 메이저를 바꿨다. 개발에 관심도 없다가 처음에 C언어를 배우는데 힘든 시간이었지만 로직을 짜고 결과값이 나올 때 행복감이 너무 좋았다. 하지만 문제는 내가 학교 과제로만 만족했다. 공부를 열심히 했지만 그뒤에 사이드로 알고리즘이나 이론에 대해서 더 공부하지 않았다. 한마디로 개발자에 준비가 되지 않았다. 그 결과 나는 졸업을 할 때에는 Python을 제외한 나머지 언어는 자신감이 없었다. 나 자신을 돌아보게 되면서 퇴사를 하고 내 실력을 쌓아야 겠다고 생각을 했다. 그래서 다시 공부하기로 <strong>결심</strong>을 했고 위코드 선택하게 되었다.</p>
<h3 id="위코드-프로젝트">*위코드 프로젝트?</h3>
<p>프로젝트 선택 과정은 먼저 개개인이 2개의 클로닝 사이트와 선택한 이유에 대해서 발표를 한다. 그다음 멘토님들이 많은 사이트를 추려서 실력에 맞게 리스트 뽑아주시면 우리는 투표를 통해 팀이되는 방식이었다. 나는 castify라는 핸드폰 E-commerce 사이트를 선택했다. 왜? <a href="https://www.casetify.com/ko_KR/">casetify</a>는 프런트와 백엔드 둘다 구현해야하는 기능이 너무 많았고 도전적이였다. 다행히 동기들에 반응들도 좋았고 기대했지만 <del>다행이도</del> casetify는 리스트에도 오르지도못했다. 멘토님이 casetify는 구현해야할게 너무많고 foundation만 공부한 실력으로는 진행하기에 너무 <del>빡세다고</del> 힘들다고 하셨다. 1차프로젝트를 진행하면서 진짜 안하길 너무 다행이라고 생각을했다. 
위코드에서 가장 좋았던 순간은 1차 2차 프로젝트하는때 라고 말할수있다. 왜냐하면 통금없이 멤버들이랑 같이 합숙하면 코딩할수있어서 너무 행복했다. 프로젝트를 하면서 제일 많이 했던 말은 &quot;이게 왜 안되지?&quot;와 &quot;이게 왜 되지?&quot;라는 말이었다. 그리고 컴퓨터는 거짓말을 하지않는다는것 항상 내가 틀려서 에러가 발생하는것이다. 비록 시간이 부족하여 욕심부려 하려고했던것은 못했지만 다들 노력하고 할수있는데까지 했다는것을 잘 알아기에 다들 만족했다. 좋은 팀원들과 원만한 커뮤니케이션를 갖아서 좋은 결과물이 나온것같다. </p>
<h3 id="개발자로서-시작의-단계에서-느낀-점들">*개발자로서 시작의 단계에서 느낀 점들</h3>
<p>마지막 인턴쉽을 하면서 느낀점들이 너무 많았다. 전에 멘토님들이 말씀하셨던 말들이 몸으로 와닿았기 시작했다. <strong>개발자는 끝없이 배워야한다</strong>. 팀원 총 다섯명과 수지 상현에 위치한 <strong>술담화</strong>라는 회사에 가게됬어다. 첫 실무를 맛볼시간이여서 엄청 설렜고 한편으로는 걱정이되었다. (과연 도움이 될까...?) 첫 미팅때 담당자분이 장고가 아닌 노드애기를 하셨고 우리는 장고와 노드를 둘다 하고싶다고 말씀드렸다. 담당자님은 좋아하셨고 우리또한 할만하다고 생각했다.(ㅠㅠ) 문제는 추가 수정사항이 매주 미팅마다 계속 생겼다. 그래서인지 노드는 차차 잊어갔고 결국 노드로 결과물을 만들지 못했다. 비록 노드로 결과물을 만들지 못했지만 회사코드를 보면서 노드를 뿌시려고 Node.js 교과서라는 책을 샀다. 이번 프로젝트를 통해서 개발자는 배워야 생존할수있다는 것을 더 느끼게 되었고 개발은 어려웠고  지금도 어렵고 앞으로도 어려울것같다.</p>
<h3 id="짧은-기간이지만-위코드에서-훈련-받고-배울-수-있었던-것들">*짧은 기간이지만 위코드에서 훈련 받고 배울 수 있었던 것들</h3>
<p>위코드에서 많은것을 훈련받고 배웠지만 지금 돌아보면 멘토님들이 많이 보여주신것 같다. </p>
<h4 id="커뮤니케이션">커뮤니케이션</h4>
<ul>
<li>많은 개발경험은 없지만 프로젝트 &amp; 기업협업을 하면서 더 더욱 커뮤니케이션의 중요성을 알게됬다. 결과적으로 <strong>&quot;커뮤니케이션 많을수록 좋고 불필요한 커뮤니케이션은 없다.&quot;</strong><h4 id="개발자로서의-습관">개발자로서의 습관</h4>
</li>
<li>개으르지말기, 스스로 공부하기(평생), 작은것이라도 배운 것이있으면 기록하기.<h4 id="백엔드-언어-라이브러리">백엔드 언어, 라이브러리</h4>
</li>
<li>사전 스터디에서 html, css, python의 기초를 개인적으로 공부했고, 위코드 2개월 동안 Django, Mysql 를 공부했습니다.<h4 id="프로젝트">프로젝트</h4>
</li>
<li>실제 웹페이지를 클론하는 방식으로 코딩하는 프로젝트를 진행하였으며 프론트엔드, 백엔드 여러 사람들과 합숙하며 한곳에서 좋은 분위기속에 진행했습니다.<h4 id="기업협업">기업협업</h4>
</li>
<li>기업협업에서는 우리가 경험해지못한 관리자 페이지에서 MD들이 프로덕트를 진열할 수 있는 관리도구를 설계하는거였다. 기업에서 Node.js랑 Sequelize를 사용하라고하셨서 새로운 기술스택을 접할수있게되었다.</li>
</ul>
<blockquote>
<h3 id="수료하고-느낀-점">수료하고 느낀 점?</h3>
<p><img src="https://images.velog.io/images/15_hwukjunwoo/post/e6eb3cd4-7b63-46c3-a358-86fa29d0864c/image.png" alt=""></p>
</blockquote>
<h3 id="앞으로-어떤-개발자로-성장하고-싶은지">*앞으로 어떤 개발자로 성장하고 싶은지</h3>
<p>이번에 위코드를 다니면서 멘토님들에게 기술면에서 배운것은 많지만 제일 많이 느끼고 배운거는 멘토님들에 긍정에너지였다. 위코드에 있으면서 아침부터 저녁까지 함께 보내면서 항상 웃어주시고 친절하게 대답해주셨다. 그 분위기때문인지 거리감을 두지않고 다가가서 물어보고 얘기할수있게 된거같다. 남에게 좋은 인상을 줄수있는 겸손한 개발자로 성장해야겠다고 생각을했다. </p>
<blockquote>
<p><strong><em>&quot;우리는 누구나 남이 나를 좋아하기 바란다. 자신이 뛰어난 지식을 자랑하는 듯한 인상을 주는 태도는 결코 남의 호감을 얻지 못한다. 남이 나를 좋아하도록 하는 비결은 상대방의 기분을 유쾌하게 해주는 점에 있다.&quot;<br>-로렌스 굴드-</em></strong></p>
</blockquote>
<h2 id="2-2021년-계획">2. 2021년 계획</h2>
<p>쌓고 싶은 기술들은 산더미인데, 하루는 24시간 뿐이라 선택과 집중이 필요하다.</p>
<h4 id="기본기">*기본기?</h4>
<p>무엇을 배울때 기본부터 배운다 그다음 기본을 바탕으로 지식을 익히고 쌓는다. 어렸을때부터 아버지가 축대를 잘쌓아야 나중에 문제가 없다고 하셨다. 빨리 성장하고 싶은 욕심은 굴뚝같지만 기본기를 다지고 가야 멀리갈수있다고 생각한다. 나무가 자라는데 오래걸리듯이 뿌리가 깊고 굵은 나무로 성장할것이다. </p>
<blockquote>
<p><strong>&quot;Late Bloomer&quot;</strong> </p>
</blockquote>
<ul>
<li>a person whose talents or capabilities are not visible to others until later than usual.&quot; </li>
</ul>
<p>나는  2021년 데이터베이스, 장고, 그리고 알고리즘을 더 신중하게 공부할것이다. 그리고 스터디 멤버들과 함께 주니어 개발자로 취업할것이다. </p>
<p>생일까지 챙겨준 동기들~~ 15기여서 너무 감사하다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/2385157f-c81b-4ffa-a6dc-3fea4eaa1c2d/IMG_6098.JPG" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Node 1 - Exercise]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Node-1-Exercise</link>
            <guid>https://velog.io/@15_hwukjunwoo/Node-1-Exercise</guid>
            <pubDate>Sun, 31 Jan 2021 02:33:35 GMT</pubDate>
            <description><![CDATA[<p>express middleware, next()
settimeout함수 sleep</p>
<h2 id="초기로-해야할것">초기로 해야할것</h2>
<p>$ touch server.js
$ npm init -y
$ npm i express sequelize sequelize-cli mysql2
$ npm i -D nodemon (D=&gt;stands for dependencies (바로바로 저장되고 바로실행된다.))
$ npx sequelize init (Don&#39;t need migration and seeders)</p>
<ul>
<li>open workbench 
-DROP DATABASE IF EXISTS 데이터베이스 이름;
-CREATE DATABASE 데이터베이스 이름;
config setting change password</li>
</ul>
<h2 id="1-데이터베이스-모델링">1. 데이터베이스 모델링</h2>
<h4 id="데이터베이스-생성하기">데이터베이스 생성하기</h4>
<ol>
<li>mysql -u root -p 그리고 비밀번호</li>
<li>create database 데이터베이스이름 character set utf8mb4 collate utf8mb4_general_ci;</li>
<li>create user &#39;사용자이름&#39;@&#39;localhost&#39; identified by &#39;비밀번호&#39;; //사용자생성</li>
<li>grant all privileges on 데이터베이스이름.* to 사용자이름@localhost; //사용자 데이터베이스에 권한주기</li>
</ol>
<h4 id="테이블-생성하기migration">테이블 생성하기(Migration)<img src="https://images.velog.io/images/15_hwukjunwoo/post/734e1f0a-97f5-4a1f-a5f0-4d205b2ca49c/image.png" alt=""></h4>
<ol>
<li>dbdiagram.io 에서 ERD이름.sql 확장자 파일 내보내기</li>
<li>ERD이름.sql 파일 수정하기<pre><code>DROP TABLE IF EXISTS users, articles, comments;
</code></pre></li>
</ol>
<p>CREATE TABLE <code>users</code> (
  <code>id</code> int PRIMARY KEY AUTO_INCREMENT,
  <code>email</code> varchar(100) UNIQUE NOT NULL,
  <code>password</code> varchar(200) NOT NULL,
  <code>status</code> ENUM (&#39;ACTIVE&#39;, &#39;INACTIVE&#39;) NOT NULL DEFAULT &quot;ACTIVE&quot;, 
  <code>created_at</code> datetime DEFAULT CURRENT_TIMESTAMP, 
  <code>updated_at</code> datetime ON UPDATE CURRENT_TIMESTAMP, # 수정된 부분
  <code>deleted_at</code> datetime DEFAULT null
);
CREATE TABLE <code>articles</code> (
  <code>id</code> int PRIMARY KEY AUTO_INCREMENT,
  <code>user_id</code> int NOT NULL,
  <code>title</code> varchar(200) NOT NULL,
  <code>body</code> varchar(2000) NOT NULL,
  <code>status</code> ENUM (&#39;DRAFT&#39;, &#39;PUBLISHED&#39;, &#39;DELETED&#39;) NOT NULL DEFAULT &quot;DRAFT&quot;,
  <code>created_at</code> datetime DEFAULT CURRENT_TIMESTAMP,
  <code>updated_at</code> datetime ON UPDATE CURRENT_TIMESTAMP,
  <code>deleted_at</code> datetime DEFAULT null
);
CREATE TABLE <code>comments</code> (
  <code>id</code> int PRIMARY KEY AUTO_INCREMENT,
  <code>article_id</code> int NOT NULL,
  <code>user_id</code> int NOT NULL,
  <code>body</code> varchar(1000) NOT NULL,
  <code>created_at</code> datetime DEFAULT CURRENT_TIMESTAMP,
  <code>updated_at</code> datetime ON UPDATE CURRENT_TIMESTAMP,
  <code>deleted_at</code> datetime DEFAULT null
);</p>
<h1 id="외래키-설정하는-부분">외래키 설정하는 부분</h1>
<p>ALTER TABLE <code>articles</code> ADD FOREIGN KEY (<code>user_id</code>) REFERENCES <code>users</code> (<code>id</code>);
ALTER TABLE <code>comments</code> ADD FOREIGN KEY (<code>article_id</code>) REFERENCES <code>articles</code> (<code>id</code>);
ALTER TABLE <code>comments</code> ADD FOREIGN KEY (<code>user_id</code>) REFERENCES <code>users</code> (<code>id</code>);</p>
<pre><code>3.ERD이름.sql 파일을 MySQL 데이터베이스에 마이그레이션 하기
- mysql -u 사용자이름 -p 데이터베이스이름 &lt; ERD이름.sql 
4. 데이터베이스에 접속해서 테이블이 잘 생성되었는지 확인하기
- mysql -u 사용자이름 -p; use 데이터베이스이름; show tables;

## Sequelize ORM
#### Installing
- $ npm install --save sequelize
- $ npm install --save mysql2
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Schema]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Schema</link>
            <guid>https://velog.io/@15_hwukjunwoo/Schema</guid>
            <pubDate>Sat, 30 Jan 2021 15:02:56 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="스키마란">스키마란?</h2>
</blockquote>
<ul>
<li>데이터베이스의 <strong>구조</strong>와 <strong>제약조건</strong>에 관해 <strong>전반적인 명세</strong>를 기술한것</li>
<li>좀 더 자세히 설명하면 <strong>개체의 특성을 나타내는 속성(Attribute)</strong>, <strong>속성들의 집합으로 이루어진 개체(Entity)</strong>, <strong>개체 사이에 존재하는 관계(Relation)</strong>에 대한 정의와 이들이 <strong>유지해야할 제약조건들</strong>을 기술한 것<h3 id="스키마-특징">#스키마 특징</h3>
1) 스키마는 데이터 사전(Data Dictionary)에 저장
2) 현실 세계의 특정한 한 부분의 표현으로서 특정 데이터 모델을 이용해서 만들어지게 됩니다.
3) 시간에 따라 불변인 특성을 갖습니다.
4) 데이터의 구조적 특성을 의미한다.
5) 인스턴스에 의해 규정된다.
<em>*데이터 사전 : 시스템 전체에서 나타나는 데이터 항목들에 대한 정보를 지정한 중앙 저장소로, 이 정보에는 항목을 참조하는데 사용되는 식별자, 항목에 대한 엔티티의 구성요소, 항목이 저장되는 곳, 항목을 참조하는 곳 등을 포함</em></li>
</ul>
<blockquote>
<h2 id="스키마-종류">스키마 종류</h2>
</blockquote>
<h3 id="1-개념-스키마--전체적인-뷰">1) 개념 스키마 === 전체적인 뷰</h3>
<ul>
<li>조직체 전체를 관장하는 입장에서 DB를 정의한 것 따라서 조직의 모든 응용시스템에서 필요로 하는 개체 관계, 그리고 제약조건들이 포함되어있다. DB를 효율적으로 관리하는데 필요한 접근권한, 보안정책, 무결성 규칙등에 관한 사항들도 추가적으로 포함된다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/4c55dc1a-a60b-466d-857e-e8c47bc8330a/image.png" alt=""><h3 id="개념-스키마-특징">#개념 스키마 특징</h3>
</li>
<li><strong>데이터 베이스의 전체적인 논리적 구조</strong></li>
<li>데이터 베이스에 실제로 어떤 데이터가 저장되었으며 데이터간의 관계는 어떻게 되는가</li>
<li>모든 응용프로그램이나 사용자들이 필요로하는 데이터를 종합한 조직전체의 데이터베이스</li>
<li>개체간의 관계와 제약조건 명시</li>
<li>데이터 베이스의 접근 권한 보안 및 무결성 규칙에 관한 명세를 정의</li>
<li>기관이나 조직체의 관점에서 데이터베이스를 정의</li>
<li>데이터베이스 관리자 (DBA)에 의해 구성
<em>* 데이터 베이스당 하나만 존재</em><h3 id="2-내부-스키마">2) 내부 스키마</h3>
</li>
<li><strong>물리적인 저장장치 입장에서 DB가 저장되는 방법을 기술한 것</strong></li>
<li>구체적으로 개념 스키마를 디스크 기억장치에 물리적으로 구현하기 위한 방법을 기술한 것으로서 주된 내용은 실제로 저장될 <strong>내부레코드 형식</strong>, <strong>내부레코드의 물리적 순서</strong>, <strong>인덱스의 유/무</strong> 등에 관한 것입니다.</li>
<li>그러나 DB는 내부 스키마에 의해서 곧바로 구현되는 것이 아니라 내부 스키마에 기술한 내용에 따라 <strong>운영체제의 파일시스템에 의해 물리적 저장장치</strong>에 기록됩니다.</li>
<li><strong>실무적으로 내부스키마에 의해 DB의 실행 속도가 결정적으로 영향</strong>을 받기 때문에 DB의 구축목적에 따라 내부 스키마를 결정해야할 필요가 있습니다.<h3 id="내부-스키마-특징">#내부 스키마 특징</h3>
</li>
<li>데이터 베이스의 물리적 저장구조를 정의</li>
<li>디스크에는 어떤 구조로 저장할 것인가</li>
<li>데이터의 실제 저장방법을 기술</li>
<li>물리적인 저장장치와 밀접한 계층</li>
<li>시스템 프로그래머나 시스템 설계자가 보는 관점의 스키마<h3 id="3-외부스키마--서브-스키마--사용자-뷰">3) 외부스키마 = 서브 스키마--사용자 뷰</h3>
</li>
<li>사용자나 응용 프로그래머가 개인의 입장에서 필요한 데이터베이스의 논리적 구조를 정의<h3 id="외부-스키마-특징">#외부 스키마 특징</h3>
</li>
<li>실세계에 존재하는 데이터들을 어떤 형식, 구조, 배치 화면을 통해 사용자에게 보여줄 것인가</li>
<li>전체 데이터 베이스의 한 논리적 부분 -&gt; 서브 스키마</li>
<li>하나의 데이터베이스에는 여러 개의 외부스키마가 존재가능 &amp; 하나의 외부스키마를 여러 개의 응용프로그램이나 사용자가 공용 가능</li>
<li>같은 데이터베이스에 대해서도 서로 다른 관점을 정의할 수 있도록 허용</li>
<li>일반 사용자는 질의어를 이용 DB를 쉽게 사용</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS(Amazon Web Service)]]></title>
            <link>https://velog.io/@15_hwukjunwoo/AWSAmazon-Web-Service</link>
            <guid>https://velog.io/@15_hwukjunwoo/AWSAmazon-Web-Service</guid>
            <pubDate>Sat, 30 Jan 2021 14:33:20 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="aws란">AWS란?</h2>
</blockquote>
<ul>
<li>#클라우드 서비스 </li>
<li>#유저가 직접 서버를 구입하고 설치할필요없이 AWS로 서버구축<h4 id="클라우드-서비스란">클라우드 서비스란?</h4>
</li>
<li>서버 등의 인프라스트럭쳐를 필요한대로 on demand(주문형)로 사용할수있는 서비스</li>
</ul>
<blockquote>
<h3 id="웹서비스-배포를-위한-aws-필수개념">웹서비스 배포를 위한 AWS 필수개념</h3>
</blockquote>
<h2 id="ec2-elastic-compute-cloud">EC2 (Elastic Compute Cloud)</h2>
<ul>
<li>쉽게 말해 한대의 컴퓨터를 <strong>생성 및 삭제</strong>한다는 개념이다. </li>
<li>실제로 <strong>광범위한 작업</strong>들을 EC2를 통해 작업 할 수 있다. </li>
<li>다만 물리적이아니라 <strong>인프라(데이터 센터)</strong>에 만들어지기때문에 네트워크를 통해 제어한다.</li>
<li>또한 <strong>instance(인스턴스)</strong>는 컴퓨터 하나를 의미한다.</li>
<li>AWS 상에서 사용하는 서버 <strong>EC2 서버에 API</strong>를 배포한다.</li>
<li>AWS에서 제공하는 서비스중에 웹서버 역활을 할수있는 서비스는 EC2밖에 없다.</li>
<li>다양한 사양옵션을 제공한다. t2.nano (CPU 1, 0.5 GB memory) 부터 x1.32xlarge (CPI 128, 1952 GB)<h2 id="security-group">Security Group</h2>
</li>
<li>EC2 인스턴스에 대한 <strong>네트워크 트래픽</strong>을 제어하는 <strong>가상 방화벽</strong> 역활을 한다.</li>
<li>즉 <strong>security group 설정을 해줘야</strong> EC2 인스턴스에 <strong>HTTP와 SSH 접속</strong>이 가능하다.<h2 id="rds-relational-database-service">RDS (Relational Database Service)</h2>
</li>
<li><strong>database</strong>를 쉽게 <strong>운영</strong>할수있는 서비스</li>
<li>RDS를 사용하면 사용자가 직접 서버를 생성해서 데이터 베이스를 설치하고 설정하고 관리 하지 않아도 된다.</li>
<li>그러면서 동시에 <strong>비용도 더 저렴</strong>하다. 사용자가 직접 데이터 베이스를 설치하고 운영하는 것보다 RDS를 사용하는것이 더 저렴함. 즉, RDS를 사용 하지 않을 이유가 거의 없다.</li>
<li>백업, 리플리케이션과 같은 것을 아마존 인프라가 자동으로 제공한다.<h2 id="load-balancer">Load Balancer</h2>
</li>
<li>로드 발란서는 <strong>HTTP 요청들을 여러 서버에 분산할때</strong> 사용된다.</li>
<li>HTTP 요청이 많을때는 서버 하나만으로 모두 처리 하기 힘들기 때문에 서버 수를 늘리는것이 일반적이다. 그럼으로 여러 서버를 실행하고 로드발런서가 HTTP 요청들을 서버들에 분산 해주는 형태로 시스템이 구성된다.<h2 id="route-53">Route 53</h2>
</li>
<li>AWS의 <strong>DNS 서비스</strong>.</li>
<li>API 시스템을 실제 <strong>도메인과 연결 시키주는 기능</strong>을 제공한다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/0a4ce33c-1f31-4319-8844-203a517c40b0/image.png" alt=""><h2 id="aws-s3">AWS S3</h2>
</li>
<li>AWS S3(Simple Storage Service)는 이름 그대로 <strong>파일을 쉽게 저장할 수 있는 공간을 제공</strong>하는 서비스.</li>
<li>파일을 저장 할 수 있을 뿐만이 아니라 <strong>파일마다 고유 주소를 부여</strong>해주기 때문에 S3에 저장한 파일을 웹상에서 쉽게 읽어들일수 있다.</li>
<li>주로 사이트상의 <strong>이미지</strong>들을 저장하고 사이트에서 읽어들여 렌더링 해주는데 사용한다.</li>
<li>1바이트 ~ 5테라 바이트의 단일 파일을 저장하는 것이 가능하다.</li>
</ul>
<blockquote>
<h2 id="rds-사용방법">RDS 사용방법</h2>
</blockquote>
<ol>
<li>RDS 서비스를 선택한다.</li>
<li>먼저 MySQL 설정 파일을 만들어야 한다. 직접 안만들어도 default 설정 파일이 있지만 utf-8 인코딩 설정을 해줘야 한국어가 저장 가능하다. 먼저 &quot;Parameters groups&quot; 페이지로 가자.</li>
<li>&quot;Create parameter group&quot; 옵션을 선택하자.</li>
<li>&quot;Parameter group&quot; 설정 파일을 생성하자. Group name과 Description은 자유롭게 정하면 된다. &quot;Paramter group family&quot;는 생성하는 데이터 베이스와 버전에 맞게 지정해야 한다. 우리의 경우 mysql5.7 데이터베이스를 생성할 예정이니 &quot;mysql5.7&quot;로 하자.</li>
<li>방금 생성한 설정 파일을 수정 하자.</li>
<li>우리가 설정할 parameters는 다음과 같다.
type <strong>chracter_set</strong> on the searchbar</li>
</ol>
<p><strong>utf8mb4로 변경</strong>
type <strong>collation **
**utf8mb4_general_ci로 변경</strong>
7. 이제 MySQL 데이터 베이스를 새로 생성하자
8. MySQL을엔진으로 선택하자. &quot;Only enable iptions eligible for RDS Free Usage Tier&quot; option을 체크해서 무료로 사용할 수 있는 사양이 자동으로 선택되도록 하자.
9. DB 세부사항 설정을 하자. 거의 대부분 default 값 그대로 두면 된다. 맨 아래 settings 섹션에서 master username과 비밀번호 그리고 데이테베이스 이름만 설정하면 된다.
10. 고급설정 페이지로 넘어가자. 먼저 Publc accessability 옵션을 yes로 설장하자. 그리고 Database options 세션에 &quot;DB parameter group&quot;을 방금 생성한 파라미터 설정 파일로 변경해주자. 나머지는 default 값 그대로 하면 된다. 끝나면 &quot;Create database&quot; 버튼을 눌루면 마무리 된다.
11. 이제 &quot;Instances&quot; 페이지에 가서 방금 생성한 데이터 베이스 대쉬보드 페이지로 가자. 참고로 데이터 베이스가 사용 준비되기 까지 몇분 이상 소요 될 수 있다.
12. 먼저 Endpoint를 확인하자. 이 주소로 database에 접속 할 수 있다. 그리고 Security groups링크를 클릭하하자.
13. Security group 설정을 변경하여 어디서든 접속이 가능하게 하자. 원래는 데이터베이스를 이렇게 어디서든 접속 가능하게 열어놓으면 안된다. 해킹의 위험이 있다.
14. 생성된 데이터베이스에 접속한후 데이터베이스와 테이블들을 생성하자.
<code>mysql -h temptest.cj5v1k6zfree.ap-northeast-2.rds.amazonaws.com -u root -p</code></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Project Architecture]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Project-Architecture</link>
            <guid>https://velog.io/@15_hwukjunwoo/Project-Architecture</guid>
            <pubDate>Tue, 19 Jan 2021 08:22:50 GMT</pubDate>
            <description><![CDATA[<h2 id="-1-why-do-we-modularize-our-applications"># 1. Why do we modularize our applications?</h2>
<ul>
<li><strong>확장성(extensibility)</strong><ul>
<li>확장성을 고려하지 않은 코드는 시스템의 규모가 커질수록 문제가 생길 확률이 높다</li>
</ul>
</li>
<li><strong>재사용성(reusability)</strong><ul>
<li>반복되는 로직을 함수로 분리하는 코드상의 재사용성 뿐만 아니라, 우리가 설계한 구조가 재사용 되어야 한다.</li>
</ul>
</li>
<li><strong>유지-보수 가능성(maintability)</strong><ul>
<li>여러 로직이 뒤엉켜 있는 코드는 유지 보수가 안된다.  </li>
</ul>
</li>
<li><strong>가독성(readability)</strong></li>
<li>어려운 로직 일수록 더 가독성이 높아야 한다. 어려운 로직을 쉽고 간단하게 구현하는 것이 좋은 코드다. </li>
<li>프로젝트의 구조 또한 한 눈에 그려져야 한다.</li>
<li><strong>테스트 가능성(testability)</strong><ul>
<li>테스트를 하기 쉬운 코드는 모듈화가 잘 되어 있고, 한 가지 역할만 하는 함수 단위의 코드를 의미한다.</li>
<li>프로젝트의 구조도 추상화가 잘 되어있고, 역할이 잘 나뉘어 있는 구조가 테스트하기 쉬운 구조다.</li>
</ul>
</li>
</ul>
<h2 id="2-mvc-pattern">2. MVC Pattern</h2>
<p><img src="https://images.velog.io/images/15_hwukjunwoo/post/3f1c4f38-83cf-4378-96b9-274071bfe4a2/image.png" alt=""></p>
<h3 id="mvc-pattern-의-장점">MVC Pattern 의 장점</h3>
<ul>
<li><p><strong>염려의 분리 (Seperation of Concerns)</strong></p>
<ul>
<li>유저 인터페이스와 관련된 부분은 모두 View 에 의해서 관리되고, 모든 데이터와 관련된 로직은 Model 에 의해서 관리되며 오로지 Controller 에 의해서 Model 에 접근할 수 있게 됩니다. 각각의 레이어가 하는 역할이 명확 합니다.</li>
</ul>
</li>
<li><p><strong>동시적인 개발 (Simultaneous Development)</strong></p>
<ul>
<li>세개의 레이어로 역할이 나뉘어져 있기 때문에 동시다발적인 개발이 가능합니다. 역할분담에 용이하며 협업이 가능한 프로젝트를 구성할 수 있습니다.</li>
</ul>
</li>
<li><p><strong>수정의 용이함 (Ease of Modification)</strong></p>
<ul>
<li>다른 레이어에 영향을 주지 않고 문제가 있는 로직을 찾아서 문제를 해결할 수 있습니다.</li>
</ul>
</li>
<li><p><strong>테스트-주도 개발(Test Driven Development)</strong></p>
<ul>
<li>각각의 레이어, 그리고 그 레이어 속에 속한 각각의 모듈을 테스트 하기 좋습니다.</li>
</ul>
</li>
</ul>
<h2 id="3-nodejs-project-layering">3. Node.js Project Layering</h2>
<p><img src="https://images.velog.io/images/15_hwukjunwoo/post/ed361f3d-bc75-45f9-a3fd-afc1ae9d45c5/image.png" alt="">
<strong>Route, Controller, Service, Model</strong> 각각의 레이어가 하나의 폴더이자 역할을 의미 합니다. 
Route - url, endpoint 함수가 실행될수있는 길
Controller - req, res 제어하는곳
Service - 요청이 유효하다 데이터베이스에 접근하는 로직</p>
<ol>
<li>큰 박스에서 작은 박스로 갈 수록 더 데이터를 다루는 로직(데이터베이스 접근하는 로직)에 근접하게 됩니다.</li>
<li>또한, 각각의 레이어는 <strong>오로지</strong> 바로 아래에 있는 레이어에만 의존하게 됩니다. <ul>
<li>Route → Controller</li>
<li>Controller → Service</li>
<li>Service → Model  </li>
</ul>
</li>
</ol>
<p>즉 다음과 같은 상황에서 유연하게 대처할 수 있다는 의미 입니다. 
때때로, 서비스를 구현하다가 RDBMS(관계형 데이터 베이스) → NoSQL(ex. mongoDB) 로 이전하는 경우가 있는데, Route와 Controller 의 로직은 전혀 바뀌지 않은채로 데이터를 다루는 Service 와 Model 의 로직만 변경 해 주면 됩니다. </p>
<p>아래의 코드는 지난 시간에 살펴보았던 User API 로직을 위에서 설명한 
Route → Controller → Service → Model 레이어로 나누었을 때의 코드 입니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Express]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Express</link>
            <guid>https://velog.io/@15_hwukjunwoo/Express</guid>
            <pubDate>Mon, 18 Jan 2021 15:40:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h2 id="express란">Express란?</h2>
</blockquote>
<ul>
<li>is fast, unopinionated, minimalist web framework for node.js</li>
<li>라우팅 과 로직의 모듈화 를 위해 사용 됩니다</li>
<li>웹서버를 만들때 편리한 기능을 제공하는 프레임워크 입니다. Express가 없다면 오로지 node.js의 내장모듈인 http를 사용해서 생성하고 http 요청을 처리하는 함수를 구현해야합니다.</li>
</ul>
<h4 id="-withoutexpressjs">* withoutExpress.js</h4>
<pre><code>const http = require(&#39;http&#39;) // 1

const server = http.createServer((req, res) =&gt; { // 2
  console.log(&#39;request received&#39;)

  res.setHeader(&#39;Content-Type&#39;, &#39;application/json&#39;) // 3
  res.end(JSON.stringify({ message: &quot;http server without express&quot; })) // 4 ,5
});

server.listen(3000, () =&gt; { console.log(&#39;server is learning on PORT 3000&#39;)}) // 6</code></pre><ol>
<li>Node.js 내장 <code>http</code> 모듈을 가져와서 아래에서 사용할 수 있도록 변수에 담는 코드</li>
<li><code>http.createServer</code> 는 콜백함수를 받는다. 이 콜백함수의 첫번째 인자는 http request 의 정보가 담겨있는 객체, 두번째 인자는 http response 객체다. 서버에 요청이 들어오면 이 콜백함수가 실행되는 꼴이다.</li>
<li>요청에 대한 응답의 header 를 <code>application/json</code> 형태로 세팅한다.</li>
<li><code>res.end</code> 함수를 통해서 요청에 대한 응답을 마무리 한다. 이 함수의 인자로 넘겨주는 값이 클라이언트가 받는 응답이 된다.</li>
<li>The JSON. <strong>stringify method</strong> converts a JavaScript value into a JSON string. It is typically used to convert JavaScript arrays or objects to JSON, although it can also be used with simple data types like strings and numbers.</li>
<li><code>server</code> 는 앞서 생성한 서버를 의미하고 이 서버 객체의 <code>listen</code> 함수는 인자로 포트 번호와 콜백함수를 받습니다. 포트번호로 서버를 연다는 의미이며, 서버가 실행될 때의 로직을 콜백함수 안에서 처리할 수 있습니다. 보통 서버가 켜져있다는 로그 메시지를 남깁니다.
<img src="https://images.velog.io/images/15_hwukjunwoo/post/90c6efa5-dbfd-42fb-b0f4-d2fdc6acea15/image.png" alt=""></li>
</ol>
<ul>
<li>$brew install httpie</li>
<li>$http localhost: 3000
<img src="https://images.velog.io/images/15_hwukjunwoo/post/32f61989-9e3b-43d4-8b11-e175f813bd2a/image.png" alt="">
점점 더 규모가 커지므로 해당 자원에 대해 다른함수(로직)을 실행하도록 하는것이 <strong>라운팅</strong> 이라고 한다.
<img src="https://images.velog.io/images/15_hwukjunwoo/post/2fb96fe0-f35a-4410-ac77-e215f077a85b/image.png" alt=""><img src="https://images.velog.io/images/15_hwukjunwoo/post/a43ec4ef-4ed9-4c31-ae76-0429cedbdd2b/image.png" alt="">보이는 바와 같이 라우팅을 직접 request 객체에서 url과 method 에 따라서 조건문으로 분기해서 다른 로직<strong>(handleSignUp, handleLogin, sendPosts)</strong>을 처리해 주어야 합니다. 그래서 이불편함을 해결하기위해 Express 프레임워크가 있습니다.
<img src="https://images.velog.io/images/15_hwukjunwoo/post/e68873c2-2281-4ad8-9f02-7895025f7d78/image.png" alt=""></li>
<li>Express 모듈을 임포트 한 후 함수를 실행해서 app 이란 변수에 담는 것이 컨벤션 입니다.클라이언트의 요청을 처리하는 http server application 이라고 볼 수 있는 것이죠. </li>
</ul>
<ol>
<li>요청을 받을 http method로 함수를 app 에 붙인다.</li>
<li>요청을 받을 endpoint url 을 string 으로 첫번째 인자에 넣는다.</li>
<li>두번째 인자는 요청과 응답을 인자로 받는 콜백함수이다. </li>
</ol>
<p><strong>즉, 각각의 메소드와 엔드포인트에 대해 처리하는(핸들링) 함수가 된다.</strong>
<img src="https://images.velog.io/images/15_hwukjunwoo/post/c8450d48-2cf7-48e9-a88c-2b56f1eba8ef/image.png" alt="">Express 없이 서버를 구현한 코드와 비교해 봤을 때, 아직은 크게 와닿지 않을 수도 있지만</p>
<ul>
<li>조건문으로 <strong>라우팅</strong>을 처리했던 것이 간편 해 졌고</li>
<li>각각의 요청을 처리하는 <strong>함수의 분리</strong>로 인해</li>
</ul>
<p>직관적으로 코드를 설계할 수 있다는 장점을 가지고 있습니다.</p>
<h3 id="express-middleware란">Express Middleware란?</h3>
<ul>
<li>요청 오브젝트(req), 응답 오브젝트 (res), 그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수 대한 액세스 권한을 갖는 함수입니다. 그 다음의 미들웨어 함수는 일반적으로 next라는 이름의 변수로 표시됩니다.</li>
<li>미들웨어 함수가 요청-응답 주기를 종료하지 않는 경우에는 next()를 호출하여 그 다음 미들웨어 함수에 제어를 전달해야 합니다. 그렇지 않으면 해당 요청은 정지된 채로 방치됩니다.<h4 id="애플리케이션-레벨-미들웨어">애플리케이션 레벨 미들웨어</h4>
</li>
<li>app.use() 및 app.METHOD() 함수를 이용해 애플리케이션 미들웨어를 앱 오브젝트의 인스턴스에 바인드. METHOD는 미들웨어 함수가 처리하는 요청(GET, PUT 또는 POST 등)의 소문자로 된 HTTP 메소드입니다.<h4 id="라우터-레벨-미들웨어">라우터 레벨 미들웨어</h4>
</li>
<li>a middleware function with no mount path. This code is executed for every request to the router</li>
<li>Router객체를 이용해 router.use() 및 router.METHOD() 함수를 사용하여 라우터 레벨 미들웨어를 로드할 수 있다.</li>
<li>Router 객체는 그 자체가 미들웨어처럼 움직이므로 app.use()의 인수(argument)로 사용될 수 있고 또한 다른 router의 use() 메서드에서 사용될 수 있다<h4 id="오류-처리-미들웨어">오류 처리 미들웨어</h4>
</li>
<li>에러 핸들링을 하는 미들웨어는 4개의 인자를 사용해서 정의하도록 한다. (err, req, res, next) 단순히 에러 핸들링 미들웨어는 에러를 다루기 위한 미들웨어이다.<h4 id="서드-파티-미들웨어">서드 파티 미들웨어</h4>
</li>
<li>기능적으로 express app에 미들웨어를 추가하기 위해 서드 파티 미들웨어 사용을 권고한다. </li>
<li>Node.js 모듈을 사용하고 싶다면 application 레벨이든 router 레벨이든 로드해서 사용하면 된다. npm에서 install 가능하다.<h3 id="next함수란">next()함수란?</h3>
</li>
<li>indicating the next middleware function</li>
<li>현재 라우터에서 판단하지 않고 다음 라우터로 넘기겠다. 단 조심해야할건 next에 파라메터를 넣게 되는순간 무조건 에러로 간다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Node Lecture]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Node</link>
            <guid>https://velog.io/@15_hwukjunwoo/Node</guid>
            <pubDate>Mon, 18 Jan 2021 07:10:36 GMT</pubDate>
            <description><![CDATA[<h3 id="how-nodejs-works">How Node.js works</h3>
<ul>
<li>간단하게 노드란 <strong>비동기</strong>(Asynchronous) <strong>이벤트-기반</strong>(event-driven) JavaScript 런타임 환경입니다.<h4 id="비동기asynchronous란">비동기(Asynchronous)란?</h4>
</li>
<li>프로그램의 다른 부분(기능 또는 함수)들이 서로 방해(blocking)하지 않고 동시에 일어날 수 있음. 기다리지않아서 좋다.</li>
</ul>
<h4 id="비동기-이벤트-기반event-driven란">비동기 이벤트-기반(Event-Driven)란?</h4>
<ul>
<li>노드가 비동기적으로 이벤트를 처리한다는 것은 앞선 클라이언트의 요청이 끝나기 전에 다음 클라이언트의 요청을 받는다는 의미입니다. </li>
<li>노드 환경에서 이벤트는 하나의 요청과 같다고 볼 수 있습니다. 여기서의 요청은 백엔드 서버를 구현 할 우리에게 하나의 HTTP Request와 같다고 보셔도 무방합니다.</li>
<li><strong>노드 입장에서 이벤트는 프론트엔드(클라이언트)에서 받는 요청입니다.</strong> <h4 id="싱글-스레드single-thread란">싱글 스레드(Single-Thread)란?</h4>
</li>
<li>client의 요청을 비동기적으로 수행하는 노드의 핵심 요소
<img src="https://images.velog.io/images/15_hwukjunwoo/post/3cc5aa82-63ce-4aa2-8481-c7b62a3c404e/image.png" alt=""><h4 id="자바스크립트는-단일-스레드-기반으로-비동기로-동작하나요">자바스크립트는 단일 스레드 기반으로 비동기로 동작하나요?</h4>
</li>
<li>네. 자바스크립트는 비동기로 동작하기 때문에 단일 스레드에도 불구하고 동시에 많은 작업을 수행합니다. 하지만 자바스크립트 언어 자체가 비동기 동작을 지원하는 것은 아닙니다.</li>
<li><strong>비동기로 동작하는 핵심요소는 자바스크립트 언어가 아니라 브라우저가 가지고 있습니다. (Node에서는 libuv 라이브러리 등)</strong></li>
</ul>
<p>브라우저는 <strong>Web APIs, Event Table, Callback Queue, Event Loop</strong> 등으로 구성되며 자바스크립트 코드가 실행될 때 브라우저와의 동작은 아래 그림으로 표현할 수 있습니다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/d6688bba-4057-44e2-8bc6-9df4e462198e/image.png" alt="">
<strong>callback</strong>: 함수다. 내가 원하는때에 실행시킨다. arr.map(<strong>(el) =&gt; el+1</strong>)
<strong>Heap</strong>: 메모리 할당이 발생하는 곳
<strong>Call Stack</strong> : 실행된 코드의 환경을 저장하는 자료구조, 함수 호출 시 Call Stack에 push 됩니다. </p>
<pre><code>setTimeout(function exec() {
  console.log(&#39;second&#39;)
}, 1000);</code></pre><p><strong>Web APIs</strong>: setTimeout이 Call Stack에 들어와 실행되면 Browser API인 timer를 호출합니다. DOM, AJAX, setTimeout 등 브라우저가 제공하는 API
<strong>Callback Queue, Event Loop, Event Table(그림엔 없음)</strong> 은 아래에서 설명하겠습니다.</p>
<h2 id="javascript-런타임-환경-feat-chrome-v8-엔진">JavaScript 런타임 환경 (feat. Chrome V8 엔진)</h2>
<ul>
<li>JavaScript 로 짜여진 소스코드를 CPU가 이해할 수 있는 기계어(ex. 0과 1로 이루어진 bytecode)로 변환시키고 또한 프로그램의 메모리를 관리하는 시스템 </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[es6] arrow function (미완성)]]></title>
            <link>https://velog.io/@15_hwukjunwoo/es6-arrow-function-%EB%AF%B8%EC%99%84%EC%84%B1</link>
            <guid>https://velog.io/@15_hwukjunwoo/es6-arrow-function-%EB%AF%B8%EC%99%84%EC%84%B1</guid>
            <pubDate>Mon, 18 Jan 2021 06:52:23 GMT</pubDate>
            <description><![CDATA[<h2 id="1-es6--ecma-script-2015">1. ES6 = ECMA Script 2015</h2>
<ul>
<li>ES는 ECMA Script의 줄임말입니다. ECMA Script는 JavaScript를 표준화 시키려고 탄생했습니다.<strong>(ECMAScript</strong> (or <strong>ES</strong>) is a scripting-language specification standardized by Ecma International)</li>
<li><strong>ES6에서는 function이라는 키워드가 빠지고 소괄호만 남았습니다. 그리고 =&gt;(arrow) 가 추가되었습니다.</strong><pre><code>//ES5
function getName() {}
//ES6
const getName = () =&gt; {}</code></pre>function(함수)는 변수에 저장할 수 있는 하나의 식입니다.<pre><code>//ES5
const getName = function(name) {}
//ES6
const getName = (name) =&gt; {} // 인자가 두 개일 때는 생략할 수 없습니다.
const getName = name =&gt; {} //인자가 하나일 때는 소괄호 생략이 가능합니다.</code></pre><pre><code>//ES5
function hi(text) {
text += &#39;하세요&#39;;
return text;
}
//ES6
const hi = text =&gt; { 
text += &#39;하세요&#39;;
return text 
};</code></pre><pre><code>//ES5
function getName(name) {
return name;
}
//ES6
const hi = name =&gt; { return name };
const hi = name =&gt; name; //만약 함수가 실행내용이 딱히 없이 return만 한다면 return 키워드와 중괄호가 생략가능합니다</code></pre>중괄호와 return문이 생략될 경우, 화살표 오른쪽에는 리턴될 <strong>&quot;값&quot;</strong>만 쓰여야 합니다. 다른 코드가 들어가면 안됩니다.<h2 id="template-literals-string-method">template literals, string method</h2>
</li>
<li>이제 back tick으로도 string을 감쌀 수 있습니다. (``)</li>
<li>Another advantage of using backticks is that they allow a string to span multiple lines: <code>let guestList = `Guests:* John* Pete* Mary`;</code></li>
<li>그리고 back tick 으로 감싸면 그 안에 변수를 넣어서 표현할 수 있습니다. 변수를 사용하려면 ${} 으로 변수를 감싸줘야 합니다.
<code>const hi = `안녕하세요. 저는 ${name} 입니다.`;</code></li>
<li>break line \n</li>
<li>template literal에서는 string을 입력한대로 개행이 됩니다.<h2 id="string-method">string method</h2>
<pre><code>const email = &#39;yealee.kim87@gmail.com&#39;;
console.log(email.startsWith(&#39;ye&#39;));
console.log(email.endsWith(&#39;com&#39;));
console.log(email.includes(&#39;@gmail&#39;));
&#39;#&#39;.repeat(3); //특정 문자열을 반복하고 싶으면 repeat 함수를 쓰면 됩니다</code></pre><h2 id="array-methods">array methods</h2>
</li>
<li>callback 함수란, 인자로 전달되는 함수라고 생각하시면 됩니다.<h3 id="arraymap">Array.map()</h3>
</li>
<li>map 메서드는 배열을 반복해주는데, callback 함수에서 return한 값으로 매(each) 요소를 수정해줍니다.</li>
<li>map 메서드의 return값은 수정된 값으로 다시 생성된 배열입니다.<pre><code>const arr = [1, 2, 3];
const squares = arr.map(x =&gt; x * x);
// map함수에 인자로 넘어간 함수를 원래대로 표현하면 아래와같다.
const squares = arr.map(function (x) { 
return x * x;
});</code></pre><h3 id="-arrayforeach"># Array.forEach()</h3>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript part 3]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Javascript-part-3</link>
            <guid>https://velog.io/@15_hwukjunwoo/Javascript-part-3</guid>
            <pubDate>Sat, 16 Jan 2021 17:20:36 GMT</pubDate>
            <description><![CDATA[<h2 id="날짜와-시간date">날짜와 시간(Date)</h2>
<blockquote>
<p>날짜 및 시간 함수로 new Date();</p>
</blockquote>
<pre><code>var rightNow = new Date(); console.log(rightNow);
//2021-01-16T11:34:02.529Z</code></pre><pre><code>let rightNow = new Date();

let year = rightNow.getFullYear();
let month = rightNow.getMonth()+1;
let date = rightNow.getDate();
let currentHour = rightNow.getHours();
let currentMin = rightNow.getMinutes();

let day = new Date(); //숫자로 출력이된다.
let weekday = new Array(7);
weekday[0] = &quot;일&quot;; weekday[1] = &quot;월&quot;; weekday[2] = &quot;화&quot;;
weekday[3] = &quot;수&quot;; weekday[4] = &quot;목&quot;; weekday[5] = &quot;금&quot;; weekday[6] = &quot;토&quot;;
let day = weekday[d.getDay()];

console.log(year+&quot;년 &quot;+month+&quot;월 &quot;+date+&quot;일 &quot;+day+&quot;요일 &quot; +currentHour+&quot;시 &quot;+currentMin+&quot;분&quot;)</code></pre><blockquote>
<h3 id="get-날짜-함수">get 날짜 함수</h3>
</blockquote>
<ul>
<li>get 날짜함수는 날짜 데이터에서 필요한 형식만 갖고 오는 함수 입니다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/c6da5fc2-672b-41de-9ff0-76b66ff45a2c/image.png" alt=""></li>
</ul>
<blockquote>
<h3 id="gettime">getTime();</h3>
</blockquote>
<ul>
<li>getTime 메서드로 날짜의 밀리초 표현하고 있습니다. 기준은 1970년 1월 1일이다.</li>
<li>1970년 1월 1일로부터 1564563605026 밀리초가 지났다는 의미입니다. </li>
<li>값이 작을수록 과거입니다.<pre><code>let time = rightNow.getTime();</code></pre></li>
</ul>
<blockquote>
<h3 id="set-날짜-함수">set 날짜 함수</h3>
<p>set 날짜함수는 날짜 데이터의 <em>원하는 형식만 다른 값으로 교체 *</em>하는 함수입니다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/0a94f607-149e-436c-92a7-2130437ac3dc/image.png" alt=""></p>
</blockquote>
<blockquote>
<h3 id="return-age">return Age</h3>
</blockquote>
<ul>
<li>앞서 말한 만으로 계산한 나이를 구하는 함수인 getWesternAge 함수를 구현해 봅시다.</li>
<li>이 함수는 birthday 라는 인자를 받고 이 birthday는 Date 객체입니다. birthday라는 인자를 넣었을 때, 현재를 기준으로 만으로 계산한 나이를 리턴 해주도록 구현해 봅시다. birthday는 string이 아닌 Date 객체라는 걸 명심하세요 :)</li>
<li>예를 들어, 오늘이 2021년 1월 16일이고, birthday 값이 다음과 같다면: <code>1991-07-25T00:45:06.562Z</code></li>
<li>리턴 값은 30 이 되어야 합니다.<pre><code>function getWesternAge(birthday) {
let birth = new Date(birthday);
let birthYear = birth.getFullYear(); // 생일년도
let today = new Date(); // 오늘날짜
let todayYear = today.getFullYear(); // 오늘년도
let age = todayYear - birthYear ; // 오늘년도 - 생일년도 = 나이 
birth.setFullYear(todayYear); // 생년월일 객체의 연도를 오늘 날짜 객체의 연도로 변경
if( today &gt; birth) { // 같은 연도가 된 객체를 비교하여 월일이 지났는지 여부 판단
  age; // 생일이 지났으면 나이
} else {
  age--; // 생일이 안지났으면 나이
}
return age;
}</code></pre></li>
</ul>
<h2 id="number-파헤치기">Number 파헤치기</h2>
<pre><code>function getRandomNumber (min, max) {
  return Math.floor((Math.random() * (max - min+1))+min);
}
console.log(getRandomNumber(5,40))</code></pre><blockquote>
<h2 id="object">object</h2>
</blockquote>
<ul>
<li>객체는 {}(중괄호)로 감싸져 있고, </li>
<li>콜론으로 구분된 이름/값 쌍들이  </li>
<li>쉼표로 분리된 목록의 형태입니다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/01610076-7691-4d3e-a001-bf304e4e8954/image.png" alt=""></li>
</ul>
<ol>
<li>마침표(.) 연산자를 사용하며, 접근하려는 객체명은 왼쪽에, 프로퍼티명은 오른쪽에 위치합니다.</li>
<li>대괄호([])를 사용하여, 접근하려는 객체명은 왼쪽에, 프로퍼티명은 쌍따옴표(&quot;&quot;)와 함께 대괄호 안에 작성합니다.<pre><code>let plan1 = {   
name: &quot;Basic&quot;
};
console.log(plan1.name);
console.log(plan1[&quot;name&quot;]);</code></pre><pre><code>let salesArr =  [[&quot;20190401&quot;, 34], [&quot;20190402&quot;, 23], [&quot;20190403&quot;, 29]];
let reviewArr = [[&quot;20190328&quot;, 3], [&quot;20190401&quot;, 0], [&quot;20190403&quot;, 1]];
let likeArr =   [[&quot;20190328&quot;, 98], [&quot;20190401&quot;, 102], [&quot;20190403&quot;, 125]];
function getData(salesArr, reviewArr, likeArr) {
let sumSales = 0;
let sumReviews = 0;
let sumLikes = 0;
for (let i=0; i&lt;salesArr.length; i++) {
 sumSales += salesArr[i][1];
}
for (let i=0; i&lt;reviewArr.length; i++) {
sumReviews += reviewArr[i][1];
}
for (let i=0; i&lt;likeArr.length; i++) {
 sumLikes += likeArr[i][1];
}
let objData = {};
objData.sumAmount = sumSales;
objData.sumReview = sumReviews;
objData.sumLike = sumLikes;
return objData;
}
console.log(getData(salesArr, reviewArr, likeArr));</code></pre><h3 id="object-추가정보">object 추가정보</h3>
</li>
</ol>
<ul>
<li>객체는 다른 데이터 타입(텍스트, 숫자, 배열 등..)처럼 변수에 저장할 수 있습니다. {} 만 사용하면 되는데요, 이렇게 {} 으로 생긴 모양의 객체를 <strong>object literal</strong>(객체 리터럴)이라고 부릅니다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/d2702952-fe60-4770-891d-231d1f472a9d/image.png" alt=""></li>
<li>사실 키만 알고 있으면 <strong>dot(.)</strong> 으로 접근하는 것이 제일 편합니다. dot(.)은 키로 바로 접근할 때 사용하는 것입니다. dot으로 접근할 때는 따옴표 없이 키를 바로 써줘야 합니다. 그런데 <strong>[] 대괄호</strong>로 접근할 수도 있었죠!</li>
</ul>
<blockquote>
<h2 id="scope">Scope</h2>
</blockquote>
<ul>
<li>JavaScript에서 scope이란, &#39;변수가 어디까지 쓰일 수 있는지&#39;의 범위를 의미합니다.<h2 id="block">Block</h2>
</li>
<li>중괄호({}, curly brace)로 감싸진 것을 block이라고 합니다.</li>
<li>{}(block)내부에서 정의된 변수는 local(지역) 변수라고 부릅니다.<h2 id="global전역-scope">Global(전역) Scope</h2>
</li>
<li>global scope에서 만든 변수를 global variable(전역변수)라고 합니다. 코드 어디서든 접근 가능해서 변수값을 확인할 수 있습니다.</li>
<li>scope(tightly scoping)의 변수는 코드 품질을 올려줍니다</li>
</ul>
<h2 id="class">class</h2>
<ul>
<li>객체지향 프로그래밍의 핵심입니다. 객체지향 프로그래밍이란, 프로그램을 객체들로 구성하고, 객체들 간에 서로 상호작용하도록 작성하는 방법입니다.</li>
<li>getPrice 에서 this.price로 price키에 접근할수있다.<h3 id="1-생성자constructor">1. 생성자(Constructor)</h3>
</li>
<li>객체(object)의 설계도인 클래스(class)는 문법이 비슷합니다.</li>
<li>둘의 가장 큰 차이는 cunstructor 라는 생성자 함수입니다.</li>
</ul>
<p>class는 새로운 instance를 생성할 때마다 constructor()메서드를 호출합니다.</p>
<pre><code>class Car {
  constructor(name, price) {
    this.name = name;
    this.price = price;
  }
}</code></pre><ul>
<li>Car는 class이름입니다. 항상 대문자로 시작하고, CamelCase로 작성해야 합니다.</li>
<li>Car class의 instance를 생성할때마다 constructor메서드가 호출됩니다.</li>
<li>constructor()메서드는 name, price 2개의 argument(인자)를 받습니다.</li>
<li>constructor()메서드에 this 키워드를 사용했습니다. class의 실행범위(context)에서 this는 해당 instance를 의미합니다.</li>
<li>constructor()에서 인자로 넘어오는 name과 price를 사용해 Car instance의 name, price 프로퍼티에 값을 할당했습니다.</li>
<li>이렇게 클래스 내에서 name, price와 같이 변경 가능한 상태값이자 class내의 컨텍스트에서 어느 곳에서나 사용할 수 있는 변수를 &#39;멤버 변수&#39;라고 부릅니다.</li>
<li>멤버 변수는 &#39;this&#39; 키워드로 접근합니다.<h3 id="2-인스턴스instance">2. 인스턴스(Instance)</h3>
class로 객체를 생성하는 과정을 &#39;인스턴스화&#39;라고 부릅니다.
<code>const morning = new Car(&#39;Morning&#39;, 2000000);</code></li>
<li>인스턴스는 Class 이름에 new를 붙여서 생성합니다.</li>
<li>클래스 이름 우측에 () 괄호를 열고 닫고, 내부에는 constructor에서 필요한 정보를 인자로 넘겨줍니다.</li>
<li>Car클래스의 instance를 morning이라는 변수에 저장했습니다.</li>
<li>다시 한 번! Car 클래스의 새로운 instance를 생성하려면 new 키워드가 필요합니다. new키워드는 constructor() 메서드를 호출하고 새로운 instance를 return해줍니다.</li>
<li>&#39;Morning&#39;이라는 String과 2000000이라는 Number를 Car 생성자에 넘겨주었고, name, price 프로퍼티에 각자의 값이 할당되었습니다.<h3 id="3-메서드methods">3. 메서드(Methods)</h3>
</li>
<li>객체가 프로퍼티 값으로 갖고 있는 것을 <strong>메서드</strong>라고 부릅니다.</li>
<li>Class의 method는 Object(객체)의 문법과 똑같습니다.</li>
<li>다만 객체는 프로퍼티마다 comma(,)로 구분해줘야 했지만, 클래스는 그렇지 않습니다.</li>
<li>Car 객체에 changeDepartment 메서드를 추가했습니다.<pre><code>class Car {
constructor(name, price) {
  this.name = name;
  this.price = price;
  this.department = &quot;선릉지점&quot;;
}
applyDiscount(discount) {  
  return this.price * discount;   
}
changeDepartment(departmentName) {
  this.department = departmentName;
}
}</code></pre>MyMath라는 class를 생성해주세요.
constructor에서는 숫자 2개를 인자로 받아 프로퍼티로 저장합니다.
총 4개의 메서드를 구현해주세요.</li>
<li>getNumber: 두 개의 숫자가 무엇인지 배열로 반환하는 메서드 ex) [1, 2]</li>
<li>add: 두 개의 숫자를 더하는 메서드</li>
<li>substract: 두 개의 숫자를 빼는 메서드</li>
<li>multiply: 두 개의 숫자를 곱하는 메서드<pre><code>class MyMath{
  constructor(num1, num2){
  this.num1 = num1;
  this.num2 = num2;
  }
  getNumber(){
      return [this.num1, this.num2]
  }
  add(){
      return this.num1 + this.num2
  }
  subtract(){
      return this.num1 - this.num2
  }
  multiply(){
      return this.num1 * this.num2
  }  
}</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript part2]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Javascript-part2</link>
            <guid>https://velog.io/@15_hwukjunwoo/Javascript-part2</guid>
            <pubDate>Fri, 15 Jan 2021 09:29:27 GMT</pubDate>
            <description><![CDATA[<h2 id="매개변수parameter와-인자argument">매개변수(parameter)와 인자(argument)</h2>
<h4 id="매개변수란">매개변수란?</h4>
<ul>
<li>함수를 정의하면서, 함수 선언식의 괄호&#39;()&#39;안에 어떤 변수명을 쓰면, 우리는 그걸 매개변수 라고 부릅니다. 매개변수는 그 이름처럼 실제로 함수 안쪽에서 변수와 같은 역할을 하게 됩니다. 함수가 호출될 때, 값을 전달받게 되면, 매개변수에 값이 정의됩니다.<h4 id="인자란">인자란?</h4>
</li>
<li>어떤 함수를 호출하면서, 호출문의 괄호 안에 어떤 값 또는 값이 정의된 변수를 쓰면, 우리는 그걸 인자 라고 부릅니다. 함수에서 매개변수를 적어둔 상태라면, 호출시 인자로 전달한 값은 매개변수를 통해 사용 가능하게 됩니다.</li>
</ul>
<h2 id="function함수---여러-인자">Function(함수) - 여러 인자</h2>
<pre><code>function alertSuccess(month, name) {
  alert(month + &quot;월의 당첨자는 &quot; + name + &quot;입니다.&quot;);
}
alertSuccess(&quot;3&quot;, &quot;김개발&quot;);</code></pre><p>인자를 세개 받습니다.</p>
<ul>
<li>첫번째 인자는 년도에 해당하는 숫자입니다.</li>
<li>두번째 인자는 월에 해당하는 숫자입니다.</li>
<li>세번째 인자는 일에 해당하는 숫자입니다.<pre><code>function meetAt(year, month, date) {
if (date) return year + &#39;/&#39; + month + &#39;/&#39; + date;
if (month) return year + &#39;년 &#39; + month + &#39;월&#39;;
if (year) return year + &#39;년&#39;;
}</code></pre><h2 id="function함수---데이터-반환하기2">Function(함수) - 데이터 반환하기(2)</h2>
<h4 id="return-함수-정의">return 함수 정의</h4>
</li>
<li>return이라는 것은 함수를 호출했을 때, 함수가 값을 반환한다는 뜻입니다.<pre><code>function consoleSuccess(month, name) {   
console.log(month, name); 
}  
</code></pre></li>
</ul>
<p>let result = consoleSuccess(&quot;3&quot;, &quot;김개발&quot;);
console.log(&quot;consoleSuccess 호출 값은&quot; + result);</p>
<pre><code>위에 상황을 돌렸을때 result 값이 undefined 나옵니다. 왜냐하면 함수에 리턴을 하지않아 저장되지않았다.
1. getTotal 이라는 이름의 함수를 만들어주세요. 가격정보 2개를 인자로 받습니다.
2. 인자이름은 원하는대로 지어주셔도 됩니다.
3. getTotal 함수에서 인자로 받은 가격으로 각각 calculateTotal 함수를 호출해주세요. 그리고 그 결과값을 더해서 반환해주세요.</code></pre><p>function getTax(price) {
  return price * 0.1;
}
function calculateTotal(price) {
  return price + getTax(price);
}
function getTotal(price1, price2){
  return calculateTotal(price1) + calculateTotal(price2) 
}</p>
<pre><code>## Array (배열)
- 몇천 몇만개 변수를 만들지않고 하나의 변수에 모든 데이터를 갖고 있을수있다. 배열을 통해서 그리고 배열은 대괄호로 감싸져 있다.

배열이 담긴 arr 변수에 접근하여 getElement 함수가 &quot;array&quot; 라는 문자열을 return 할 수 있도록 해주세요.</code></pre><p>function getElement() {
  let arr = [3, [4, [&quot;array&quot;, 9], 2+3], [0]];
  return arr[1][1][0]
}
getElement()</p>
<pre><code>
addFirstAndLast 함수에 주어진 인자 myArray 의 첫번째 element와 마지막 element의 값을 더한 값을 리턴해주세요.
만일 myArray에 한 개의 요소만 있다면 해당 요소의 값을 리턴해 주시고 요소가 없는 비어있는 array라면 0을 리턴해주세요.</code></pre><p>function addFirstAndLast(myArray) {
  if(myArray.length &gt;= 2){
    return myArray[0]+myArray[myArray.length-1];
  }
  else if(myArray.length == 1){
    return myArray[0];
  }
  else if(myArray.length === 0){
    return 0;
  }
}</p>
<pre><code>
## for문
- for 반복문을 사용하면, 짧게 줄일 수 있습니다![](https://images.velog.io/images/15_hwukjunwoo/post/42001c53-4574-42c3-b2c4-efa06ef29b58/image.png)</code></pre><p>for (반복조건) {
   //반복조건이 맞으면 실행할 코드
}</p>
<pre><code>findSmallestElement 의 arr 인자는 숫자 값으로만 이루어진 array 입니다. array 의 값들 중 가장 작은 값을 리턴해주세요.</code></pre><p>function findSmallestElement(arr){
  if(arr.length === 0) {
    return 0; 
  } else { 
    let min = arr[0];// 변수 min에 배열의 아무 값을 임의로 설정. (가상의 최솟값)
    for (i = 0 ; i &lt; arr.length; i++) {
      console.log(arr[i])
      if (arr[i] &lt; min ) {
        min = arr[i];
      } 
    } return min;<br>  }
}</p>
<pre><code>## 배열 조작하기
#### 요소추가/수정
- 요소를 하나씩 추가할수있습니다.
- 원하는 위치에 마음대로 요소를 할당할수있다.</code></pre><p>let day = [&#39;m&#39;, &#39;s&#39;, &#39;w&#39;, &#39;t&#39;];
day[1] = &#39;t&#39;;
day[4] = &#39;f&#39;;
day[5] = &#39;s&#39;;</p>
<pre><code>[ &#39;m&#39;, &#39;t&#39;, &#39;w&#39;, &#39;t&#39;, &#39;f&#39;, &#39;s&#39; ]
#### push/unshift함수
- push 와 unshift 요소를 추가해주는 함수입니다.
- push는 array의 마지막 부분, 즉 꼬리에 요소들을 추가하고,
- unshift는 array의 맨 앞부분, 즉 머리 부분에 요소를 추가합니다.
#### pop/shift함수
- pop함수를 사용하면 마지막 요소가 제거되고, 마지막 요소의 값을 반환합니다.
- pop는 array의 마지막 부분, 즉 꼬리에 요소들을 제거하고,
- shift는 array의 맨 앞부분, 즉 머리 부분에 요소를 제거합니다.![](https://images.velog.io/images/15_hwukjunwoo/post/466dcbfa-1e1f-47b6-92ee-a2753ccda18e/image.png)

array의 요소들 중 10과 같거나 작은 값의 element들은 result의 맨 앞으로,10보다 큰 값의 요소들은 result의 맨 뒤로 재구성된 배열을 리턴해주세요.</code></pre><p>//[1, 20, 10, 5, 100]
function divideArrayInHalf(array) {
  let result = [];
  for(let i = array.length-1; i &gt;= 0; i--){
    if (array[i] &lt;= 10){
      result.unshift(array[i]);
    }else{
      result.push(array[i])
    }
  }
  return result;
}
//[1, 10, 5, 100, 20]</p>
<pre><code>## 데이터 타입
- JavaScript에 있는 6가지 데이터 타입을 알아보겠습니다.
undefined, null, boolean (true/false), 숫자, 문자열, 객체 (object)

#### typeof연산자
- typeof 연산자를 통해 이 값, 이 변수는 무슨 데이터 타입인지 알 수 있습니다. 

#### console.log(typeof []);
- 배열의 type을 확인해보면 &quot;object&quot;입니다. 
왜냐하면 사실 배열은 확장된 객체이기 때문입니다. 
일단 typeof로 배열을 확인하면 &quot;object&quot;라고 나오는 것만 기억하시고 넘어가시면 됩니다.

#### undefined
- undefined라는 값은 var, let, const를 사용해서 변수를 정의할 때,
초기화 하지 않았다면 변수에는 undefined가 할당됩니다.

#### null 
- null 이라는 데이터 타입이 object로 반환되는 것이 헷갈릴 수 있지만, null은 빈 객체를 참조하고 있어서 그렇습니다.

#### 객체(Object)
- 객체는 키와 값의 조합으로 이루어진 데이터입니다. 중괄호로 감싸진 key-value 쌍의 형태를 갖습니다. ex. { key: value }

## String 파헤치기!
- 쌍따옴표든, 홑따옴표든 모두 String형 값에 사용합니다.
- String의 대소문자가 구분됩니다.</code></pre><p>let upperLastName = lastName.toUpperCase();
let lowerLastName = lastName.toLowerCase();</p>
<pre><code></code></pre><p>let info = &quot;JavaScript는 프로래밍 언어이다.&quot;;
let firstChar = info.indexOf(&quot;프로래밍&quot;); 
console.log(info, firstChar); // firstChar = 12</p>
<p>if (firstChar !== -1) { //firstChar이 -1이 아니면
  info = info.slice(0, firstChar) + &quot;프로그래밍&quot; + info.slice(firstChar+4, info.length); 
} // 멀쩡한 부분만 슬라이스해서 빼와서 프로그래밍 언어만 추가했다.
console.log(info);</p>
<pre><code>slice(잘릴 시작위치, 잘릴 끝위치)
이럴 경우에 밑에처럼 replace를 써도 될꺼같다.</code></pre><p>info = info.replace(&quot;프로래밍&quot;,&quot;프로그래밍&quot;)</p>
<pre><code></code></pre><p>function sliceCityFromAddress(address){</p>
<p>let first = address.indexOf(&quot; &quot;);
let si = address.indexOf(&#39;시&#39;);</p>
<p>if (first &lt; si) { //si가 더숫자가 크면 도를 내비두고 si만 잘라서 프린트한다.
 return address.slice(0,first) + address.slice(si+1, address.length) 
 } else { //first가 더 클경우
   return address.slice(si+2, address.length)
 }<br>}</p>
<pre><code>## String, Number의 변환
- 컴퓨터가 +의 양쪽을 보고, 하나라도 String이 있으면 문자열로서 합쳐줍니다.
- 그런데 -라면, String의 마이너스는 존재 하지 않으므로 양쪽의 값을 모두 숫자로 변환해서 계산해줍니다.

nationalPensionRemainingYearCount 함수를 구현해주세요. nationalPensionRemainingYearCount 는 age_string 이라 input을 받습니다. age_string은 나이 값인데 string형 값으로 되어 있습니다.</code></pre><p>function nationalPensionRemainingYearCount(age_string) {
  let numberAge = Number(age_string);
  let pension = 65-numberAge;
  return &quot;앞으로 &quot;+pension+&quot;년 남으셨습니다&quot;
}
nationalPensionRemainingYearCount(20);
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript(수정)]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Javascript%EC%88%98%EC%A0%95</link>
            <guid>https://velog.io/@15_hwukjunwoo/Javascript%EC%88%98%EC%A0%95</guid>
            <pubDate>Wed, 13 Jan 2021 15:36:30 GMT</pubDate>
            <description><![CDATA[<p>Javascript is a high-level object-oriented, multi-paradigm programming language.</p>
<ul>
<li><strong>programming language</strong>: instruct computer to do things</li>
<li><strong>object-oriented</strong>: based on objects for storing most kinds of data</li>
<li><strong>multi-paradigm</strong>: we can use different styles of programming</li>
<li><strong>high-level</strong>: we dont have to worry about complex stuff like memory management.<img src="https://images.velog.io/images/15_hwukjunwoo/post/7f9ded54-f91b-4a7f-8ff6-c3831e403d04/image.png" alt=""><img src="https://images.velog.io/images/15_hwukjunwoo/post/54babe93-e7ef-411b-80ac-0f6546352810/image.png" alt=""></li>
</ul>
<p>40+2+32
why is this result not showing in console?</p>
<ul>
<li>because the console is just the environment that was build to execute small pieces of code and then show result imediately. It does not show operation in code by default. So we have to use console.log(40+2+32);</li>
</ul>
<p>Data Type:</p>
<ol>
<li>number: floating point numbers</li>
<li>string: sequence of characters</li>
<li>boolean: logical type that can only be true or false</li>
<li>undefined: value taken by a variable that is not yet defined</li>
<li>null: also mean empty value</li>
<li>symbol(ES2015): value that is unique and cannot be changed</li>
<li>bigInt(ES2020): larger integers than the number type can hold</li>
</ol>
<p>const -  it creates variable that cannot be assigned/ immutable variable
const birthyear = 1990 birthyear cannot be change only the ages.</p>
<p>console.log(firstName+ &#39; &#39;+lastName)</p>
<p>map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환합니다</p>
<p>map method  - loop over array/ make brand new array
filter method - filter for original array new filtered array.</p>
<p>promise : an object that is used as a placeholder for the future result of an asynchronous operation.</p>
<p><img src="https://images.velog.io/images/15_hwukjunwoo/post/21e9f7f1-0e78-4b77-a4c3-84b906a21295/image.png" alt=""><img src="https://images.velog.io/images/15_hwukjunwoo/post/f2da8a5a-70f8-48ae-9f76-c6b854c4c2d0/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript part 1 ]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Javascript-part-1</link>
            <guid>https://velog.io/@15_hwukjunwoo/Javascript-part-1</guid>
            <pubDate>Wed, 13 Jan 2021 15:36:16 GMT</pubDate>
            <description><![CDATA[<h4 id="variables변수">Variables(변수)</h4>
<ul>
<li>변수이름, 함수이름 등 <strong>camelCase(카멜케이스)</strong> 방식으로 쓸 것.</li>
</ul>
<p><strong>let</strong> ----&gt; 키워드를 사용하면 변수값을 수정할수 있고 (예를 들어 나이)
-------&gt; 키워드의 역할은 &quot;변수&quot;를 생성하는 것입니다.
<strong>const</strong> -&gt; 키워드를 사용한 변수는 수정할 수가 없습니다. (출생년도)
<strong>var</strong> ----&gt; 위에처럼 구분할 필요없다.</p>
<h4 id="function함수">Function(함수)</h4>
<ul>
<li>하나의 특정한 작업을 수행하도록 설계된 독립적인 블록입니다.</li>
<li>함수를 정의만 하고 호출하지 않으면 실행되지 않습니다.</li>
<li>함수를 호출하는 형태는 아래와 같이 함수 이름에 괄호()를 여닫아주면 됩니다.</li>
<li>반환을 생략하면 undefined라는 값을 반환합니다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/2c411154-e4f2-43c8-b91f-fd20dc0d749f/image.png" alt=""><h4 id="매개변수parameter와-인자argument">매개변수(parameter)와 인자(argument)</h4>
함수는 어떻게 외부의 값을 받을까요?<pre><code>function getName(name) { //name === parameter
return name + &#39;님&#39;;
}
const result1 = getName(&#39;개발자&#39;); //개발자 ===argument</code></pre>&#39;개발자&#39;와 같은 실질적인 값을 argument(인자)라고 합니다.
정의된 함수의 소괄호 내부에 지금까지와는 달리 &#39;name&#39;이라는 단어가 들어 있습니다.이처럼 함수 이름 옆 소괄호 자리에 적혀 있는 단어는 매개변수, parameter라고 부릅니다. 외부로부터 들어오는 값을 담아 함수 내부에서 사용하도록 하는 변수의 역할을 합니다. 앞서 parameter는 &#39;자리&#39; 혹은 &#39;변수의 이름&#39;이라고 말씀드렸습니다. 반면, argument는 그 자리에 들어갈 구체적인 값을 뜻합니다.<h4 id="math-expression">Math expression</h4>
<pre><code>let num = 1;
let newNum = num++;
console.log(num);
console.log(newNum);</code></pre>let newNum = num++;
위의 한 줄짜리 코드에서 일어나는 과정을 스텝별로 보면</li>
</ul>
<ol>
<li>newNum 변수에 num변수를 할당해서 newNum에 1이 할당 되었고,</li>
<li>그 후 num++; 가 실행되어 변수 num이 2가 되었습니다.<h4 id="텍스트-문자열의-연결">텍스트 문자열의 연결</h4>
&quot;&quot;(쌍따옴표)로 감싸져 있기때문에 컴퓨터는 숫자라고 인식하지 않습니다.
alert(&quot;2 더하기 2는 &quot; + 2 + 2); 하면 &quot;2더하기 2는 22&quot; 가 나온다.
alert(&quot;2 더하기 2는 &quot; + (2 + 2)); 하면 &quot;2더하기 2는 4&quot; 가 나온다.<h4 id="if문">if문<img src="https://images.velog.io/images/15_hwukjunwoo/post/6cec0d04-119c-4ffc-a113-3454b457cc59/image.png" alt=""><img src="https://images.velog.io/images/15_hwukjunwoo/post/cae75a97-acf7-4413-a09a-2b0369491a70/image.png" alt=""></h4>
</li>
</ol>
<h4 id="비교연산자">비교연산자</h4>
<p>===는 값과 타입이 같은지를 비교하는 equality operator(동등 비교 연산자)입니다.
!==를 사용해서 서로 &#39;같지 않음&#39;을 비교할 수도 있습니다.
==는 동등 비교연산자(equality operator)입니다.
차이점은 ===는 엄격한(identity/strict) 비교연산자 이고,
==는 느슨한 비교연산자 입니다.
예를 들어</p>
<pre><code>if (&quot;3&quot; == 3) {
  return true;
}</code></pre><p>//문자열 vs 숫자</p>
<pre><code>if (&quot;3&quot; === 3) {
  return false;
}</code></pre><h4 id="논리-연산자logical-operators">논리 연산자(Logical Operators)</h4>
<p>const answer = prompt(&quot;어디사세요?&quot;); //alert처럼 창이 뜬다 그다음에 입력박스도 뜬다.</p>
<p>바로 &quot;또는(or)&quot; 이라는 논리 연산자를 사용하는 것입니다.
&quot;또는(or)&quot;에 해당하는 JavaScript 연산자는 || 입니다. (shift + )</p>
<p>어떤 조건 하나만 맞으면 되는 것이 아니라 모두 충족해야할 때 사용하는 &quot;그리고(and)&quot; 연산자인 &amp;&amp;를 보겠습니다.</p>
<pre><code>function rockPaperScissors(player1, player2) {
  var result;

  if ( player1 === &quot;가위&quot; &amp;&amp; (player2 === &quot;보&quot; || player2 == &quot;가위&quot;) ) {
    result = &quot;player1&quot; 
  } else if (player1 === &quot;바위&quot; &amp;&amp; (player2 === &quot;가위&quot; || player2 == &quot;바위&quot;)) {
    result = &quot;player1&quot;
  } else if (player1 === &quot;보&quot; &amp;&amp; (player2 === &quot;바위&quot; || player2 == &quot;보&quot;)) {
    result = &quot;player1&quot;
  } else {
    result = &quot;player2&quot;
  }

  return result
}</code></pre><h4 id="function함수---데이터-받기">Function(함수) - 데이터 받기</h4>
<pre><code>function alertSuccess(name) {   
  alert(name + &quot;님 로그인 성공!&quot;); 
}
alertSuccess(&quot;김워크&quot;);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[myDongMyoTrip (2차 프로젝트)]]></title>
            <link>https://velog.io/@15_hwukjunwoo/myDongMyoTrip-2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@15_hwukjunwoo/myDongMyoTrip-2%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Sat, 09 Jan 2021 16:26:39 GMT</pubDate>
            <description><![CDATA[<h3 id="프로젝트-소개--2020122720210108">&gt; 프로젝트 소개  (2020.12.27~2021.01.08)</h3>
<ul>
<li>[마이리얼트립] <a href="https://www.myrealtrip.com/">https://www.myrealtrip.com/</a> 기업 소개: 마이리얼트립은 여행을 떠나기 위해 필요한 모든 것을 쉽고, 빠르게 검색하고 예약할 수 있는 국내 최고의 자유여행 플랫폼입니다. 항공권, 숙박, 에어텔 상품을 비롯하여 전세계 680여개 도시 20,000여개의 현지 투어&amp;티켓 상품을 제공하고 있습니다.</li>
<li>myrealtrip 사이트를 클로닝했다. 팀이름이 마이동묘트립인 이유는 코로나로 인해 프로젝트 기간동안 팀이랑 합숙을 했고 다같이 동묘에어비엔비에서 했다. 그래서 마이리얼트립에서 마이동묘트립으로 수정을했다.<h4 id="front-end-기술-스택-김해인pm👩-이하영👩-안미현👩">Front-End 기술 스택 (김해인(PM)👩‍, 이하영👩‍, 안미현👩‍)</h4>
</li>
<li>React.js, React-router, Styled-Components<h4 id="back-end-기술-스택-우혁준👦-이주형👦">Back-End 기술 스택 (우혁준👦, 이주형👦)</h4>
</li>
<li>Django, Python, MySQL, jwt, bcrypt, AWS, 데이터베이스 모델링<h4 id="협업도구">협업도구</h4>
</li>
<li>Git, Github / Slack / Trello</li>
</ul>
<h3 id="기술소개">&gt; 기술소개</h3>
<h4 id="trello">Trello:</h4>
<ul>
<li>대학교에서부터 사용했던 Trello지만 위코드에서 왜 Trello가 중요하진 설명한 후에 더 와닿아서 더 열심히 썼다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/c385691d-eb7e-4279-880a-ec91cee75cad/image.png" alt=""><h4 id="aquerytool">AqueryTool:</h4>
</li>
<li>모델링은 진짜 끝도 없는거 같다. 1차 프로젝트때처럼 어느정도하면 되겠다했던 나였는데 어느순간 수정할께 너무 많아졌다.ㅠㅠ 이래서 탄탄한 모델링이 제일 중요하다는것을 알것같았다. 결국 마지막까지 수정한결과물이다!!<img src="https://images.velog.io/images/15_hwukjunwoo/post/ead13b72-d66e-4849-9760-944a9b5d9c0e/myDongMyoTrip_20210110_01_19.png" alt=""><h4 id="github">Github:</h4>
<img src="https://images.velog.io/images/15_hwukjunwoo/post/87040a07-fff7-45b8-9832-2fd382109f43/image.png" alt=""></li>
</ul>
<h3 id="내가썼던-코드들">내가썼던 코드들:</h3>
<h4 id="restful-api">RESTful API:</h4>
<ul>
<li>1차 프로젝트때 사용못해본 RESTful API 구현할수있었다. 
숙소 리스트는 path parameter로 구현하였고 숙소 상세 페이지는 query string parameter로 구현하였다.
제품 상세페이지 path parameter도 솔직히 너무 쉬운 개념으로 accommodation/1, accommodation/2 이렇게 숙소 아이디마다 부여되기 때문에 번호만 입력하면 출력된다.<img src="https://images.velog.io/images/15_hwukjunwoo/post/619f6e7d-5763-41e1-a8c7-bbc3d8c72a64/image.png" alt=""><h4 id="숙소-상세-페이지-api">숙소 상세 페이지 API:</h4>
<code>def get(self, request, accommodation_id) get(id=accommodation_id)</code>와 같이 path parameter를 선언해 RESTful API를 구현했다. 밑에 보시다시피 상세페이지에 너무 많은 정보가 있었지만 나누지않고 그것을 한번에 출력할수있게 했다. <code>select_related와 prefetch_related</code>를 사용해 쿼리를 줄이는 정참조, 역참조 방법을 사용했습니다<blockquote>
<p><img src="https://images.velog.io/images/15_hwukjunwoo/post/17eba1ae-92e4-4ba5-9e40-44767618be89/image.png" alt=""><img src="https://images.velog.io/images/15_hwukjunwoo/post/04f1d8af-9f64-4413-a09c-35055d277a1b/image.png" alt=""><img src="https://images.velog.io/images/15_hwukjunwoo/post/e1fa8e5b-b9cc-4451-b22a-e827bdef6ad6/image.png" alt=""></p>
</blockquote>
</li>
</ul>
<h4 id="숙소-리스트-페이지-api">숙소 리스트 페이지 API:</h4>
<ul>
<li>getlist를 사용한 AccommodationListView에 구현했습니다. Q객체사용해서 조건을 걸어서 여러 데이터를 가져올수있다는것도 배웠습니다. <code>In 절은 좌변이다</code><blockquote>
<p><img src="https://images.velog.io/images/15_hwukjunwoo/post/d3177d0f-7e60-4c02-bed0-0ee97f0a1f3b/image.png" alt=""><img src="https://images.velog.io/images/15_hwukjunwoo/post/b23a4592-02f9-4a8e-b6ea-76e4f3ed488c/image.png" alt=""></p>
</blockquote>
</li>
</ul>
<h3 id="프로젝트-느낌점">&gt; 프로젝트 느낌점</h3>
<h4 id="소통">소통</h4>
<ul>
<li>항상 프로젝트가 끝나갈때나 프런트 분들과 맞춰보려고할때면 격는 일인데 &quot;아~ 소통만했으면&quot; 그래서 끝나고나면 소통을 많이하고 나눴으면 하는생각을 갖곤 한다. 협업하는것에 소통이 왜 첫번째인지 알수있었다. 우리가 처음에 프로젝트를 시작하면서 모델링으로 프로젝트에 스케치를한다 하지만 그 스케치는 완벽할수가 없다. 그래서 같이 협업을 할때 처음에는 동그라미 모양이였다면 하다보면서 파트너와 애기도하고하면서 점점 그 동그라미를 깍고깍아 다이아가 되어가는것같다. 근데 그 과정에 제일 중요한건 소통인것 같다.<h4 id="소통은-많을수록좋고-소통에-지나친건없다"><code>&quot;소통은 많을수록좋고 소통에 지나친건없다.&quot;</code></h4>
<h4 id="좋았던점">좋았던점:</h4>
</li>
<li>솔직히 좋았던 점을 말하기에는 너무많아서 힘들것같고 간단히 설명을 드리면 일단 우리팀이 배려심이 너무 좋았다. 예를 들어 밥을 먹고 뒷처리하는것도 다 알아서 해주고 너나할꺼없이 열심히 깔끔히 해주신것과 그리고 공부할수있는 분위기를 만들어주셔서 너무 감사했다. 그리고 다같이 한곳에서 합숙을 해서 너무 좋고 가족같았다.<h4 id="아쉬웠던점">아쉬웠던점:</h4>
</li>
<li>팀에 도움이 많이 못되고 내가 혼자하는것에 비중을 너무 많이쏟았다. ㅠㅠ 팀원들 미안해요<del>~</del></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Docker]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Docker-%EC%88%98%EC%A0%95</link>
            <guid>https://velog.io/@15_hwukjunwoo/Docker-%EC%88%98%EC%A0%95</guid>
            <pubDate>Thu, 07 Jan 2021 18:48:55 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>비싼 서버 컴퓨터를 놀리고 있고 서비스를 늘리때 마다 서버에 비용 투자를 하기에는 부담이 큽니다. 그래서 가상화 기술이 등장합니다. 도커도 <strong>가상화기술</strong> 중 하나이다.</p>
</blockquote>
<blockquote>
<p><img src="https://images.velog.io/images/15_hwukjunwoo/post/d473d7db-66f0-482e-8482-68ffd74fc545/image.png" alt=""> 차이점은 하이퍼바이저와 같은 지나친  간섭의 유무(시간차이다).</p>
</blockquote>
<p>Docker 같은 컨테이너 가상화 기술은 hypervisor 가상화와 다르게 OS의 커널 위의 유저 공간(user space)에서 실행된데요</p>
<p>container는 충돌할 가능성이있다? 
-&gt; 같이 프로세서를 이용하면 그럴수있다.</p>
<blockquote>
<p>Docker는?
컨테이너 가상화 기술이자 회사명/ 많은 사용량으로 컨테이너 가상화 기술의 대명사처럼 사용되고있습니다.
요즘 오픈소스 컨테이너 가상화 기술도 많이있습니다.
도커 엔진 = 도커 데몬
컨테이너는 이미지를 기반해 만들어진것이다.
이미지로 컨테이너를 만들어준다.</p>
</blockquote>
<blockquote>
<p>Docker container는?</p>
</blockquote>
<ul>
<li>도커의 전체적인 모습을 카세트 플레이어로 비유</li>
<li>토커 이미지는 카세트 테이프입니다.</li>
<li>도커 데몬(서버)은 카세트 플레이어입니다.</li>
<li>이미지인 카세트 테이프를 카세트 플레이어에서 재생하는 동작 그리고 그로인해 나오는 결과물이 바로 컨테이너입니다.</li>
<li>이것은 무엇을 의미할까요? 바로 어떤 컴퓨터 혹은 서버에서 도커만 설치되어 있다면 이미지를 가지고 실행할수있다는 의미입니다. </li>
<li>컨테이너는 영원할까요? 그렇지 않습니다. 단일 프로세서(process)로서 동작하고 프로세스의 작업이 종료되면 컨테이너도 종료됩니다. 마치 음악 재생이 끝나면 종료되는것과 마찬가지로.</li>
</ul>
<p><img src="https://images.velog.io/images/15_hwukjunwoo/post/b16f681a-fb00-4609-a183-345c21d211c6/image.png" alt=""></p>
<pre><code>        daemon port        container이름</code></pre><p>docker run -d -p 8000:8000 --name docker_train
 hwukjunwoo/docker_train:0.1</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[python library faker]]></title>
            <link>https://velog.io/@15_hwukjunwoo/python-library-faker</link>
            <guid>https://velog.io/@15_hwukjunwoo/python-library-faker</guid>
            <pubDate>Mon, 04 Jan 2021 02:42:32 GMT</pubDate>
            <description><![CDATA[<h3 id="fake-data">fake data</h3>
<ul>
<li>프로젝트를 하면서 초반에 fake data를 이용해 많은 정보를 가져다가 활용을 많이했다.</li>
</ul>
<p><img src="https://images.velog.io/images/15_hwukjunwoo/post/072f8934-0e7c-4bcf-ac65-d5f75e8d41c5/image.png" alt="">폴더 생성<img src="https://images.velog.io/images/15_hwukjunwoo/post/4484c5da-d15d-4720-ad19-49d62a154a3f/image.png" alt=""><img src="https://images.velog.io/images/15_hwukjunwoo/post/bb3ee6a3-304c-4e2f-b837-f1bb435cf057/image.png" alt=""></p>
<p><a href="https://faker.readthedocs.io/en/master/locales/ko_KR.html#faker-providers-address">https://faker.readthedocs.io/en/master/locales/ko_KR.html#faker-providers-address</a></p>
<p><a href="https://github.com/fzaninotto/Faker">https://github.com/fzaninotto/Faker</a></p>
<p><a href="http://zetcode.com/python/faker/">http://zetcode.com/python/faker/</a></p>
<p><a href="https://faker.readthedocs.io/en/latest/providers.html">https://faker.readthedocs.io/en/latest/providers.html</a>
<a href="https://www.geeksforgeeks.org/python-faker-library/">https://www.geeksforgeeks.org/python-faker-library/</a>
<a href="http://zetcode.com/python/faker/">http://zetcode.com/python/faker/</a></p>
<p>영상:
<a href="https://www.youtube.com/watch?v=yaAwz9P4hTM">https://www.youtube.com/watch?v=yaAwz9P4hTM</a>
<a href="https://www.youtube.com/watch?v=bW2uTvvqTg4">https://www.youtube.com/watch?v=bW2uTvvqTg4</a>
annotation
<a href="https://raccoonyy.github.io/django-annotate-and-aggregate-like-as-excel/">https://raccoonyy.github.io/django-annotate-and-aggregate-like-as-excel/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Error (추가)]]></title>
            <link>https://velog.io/@15_hwukjunwoo/Error-%EC%B6%94%EA%B0%80</link>
            <guid>https://velog.io/@15_hwukjunwoo/Error-%EC%B6%94%EA%B0%80</guid>
            <pubDate>Sun, 03 Jan 2021 18:14:30 GMT</pubDate>
            <description><![CDATA[<pre><code>remote: error: GH006: Protected branch update failed for refs/heads/main.
remote: error: At least 6 approving reviews are required by reviewers with write access.
To https://github.com/wecode-bootcamp-korea/15-2nd-myDongMyoTrip-backend.git
 ! [remote rejected] main -&gt; main (protected branch hook declined)
error: failed to push some refs to &#39;https://github.com/wecode-bootcamp-korea/15-2nd-myDongMyoTrip-backend.git&#39;</code></pre><p>이런상황에 쳐해있을때</p>
]]></description>
        </item>
    </channel>
</rss>