<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>daydream_03.log</title>
        <link>https://velog.io/</link>
        <description>Slow and steady wins the race</description>
        <lastBuildDate>Fri, 08 Apr 2022 09:27:50 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>daydream_03.log</title>
            <url>https://images.velog.io/images/daydream_03/profile/f9e8a145-c050-49a7-b5a8-0f1b54ee95e0/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. daydream_03.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/daydream_03" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Process, Thread 개념 정리]]></title>
            <link>https://velog.io/@daydream_03/Process-Thread-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@daydream_03/Process-Thread-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 08 Apr 2022 09:27:50 GMT</pubDate>
            <description><![CDATA[<h3 id="중요-키워드">중요 키워드</h3>
<ol>
<li><p>실행단위
CPU core에 한 순간에 하나씩(one at a time) 적재되어 실행되는 단위
Process와 Thread를 <strong>모두 포괄</strong>한다</p>
</li>
<li><p>프로세스
하나의 스레드만 갖고 있다면 단일 스레드 프로세스</p>
</li>
<li><p>동시성
한 순간에 여러가지 X
짧은 전환으로 여러가지 일을 동시에 처리하는 것처럼 <strong>보이는 것</strong></p>
</li>
</ol>
<h3 id="프로세스">프로세스</h3>
<p>프로그램은 단순히 코드가 구현된 파일일 뿐이다.(= 피자 레시피)
피자 레시피로 피자를 만들듯이 프로그램을 실행해 사용할 수 있도록 <strong>메모리에 적재된 것</strong>이 프로세스이다.</p>
<h4 id="프로그램이-프로세스가-되는-과정">프로그램이 프로세스가 되는 과정</h4>
<ol>
<li><p>프로세스가 필요로 하는 자원이 메모리에 올라간다.
메모리에는 code, data, heap, stack 영역이 있다.</p>
</li>
<li><p>프로세스 정보를 담고 있는 PCB 블럭이 프로세스 생성과 함께 만들어진다.
<img src="https://velog.velcdn.com/cloudflare/daydream_03/8ee5eaa1-22e0-4524-aa44-0143089a0758/image.png" alt=""></p>
</li>
</ol>
<h4 id="여러가지-프로그램을-동시에-실행하면-일어나는-일">여러가지 프로그램을 동시에 실행하면 일어나는 일</h4>
<p>코드 치려고 VSCode 실행, 
코드 치면서 음악 들으려고 Youtube Music 실행,
메신저로 Slack 실행,..... 어떻게 동작하는지??</p>
<h4 id="컨텍스트-스위칭">컨텍스트 스위칭</h4>
<p>2개의 프로세스를 예시로 든 <strong>컨텍스트 스위칭</strong>의 예시
<img src="https://velog.velcdn.com/cloudflare/daydream_03/b3d30e12-3d76-4541-950b-235e597af774/image.png" alt="">
각 프로세스가 짧은 전환주기를 갖고 실행, 준비 상태를 오가며 메모리 적재, 보관을 반복한다
이렇게 동작하는 <u>프로세스를 경량화</u>한 것이 <strong>스레드</strong>이다.</p>
<h3 id="스레드">스레드</h3>
<p>*<em>한 프로세스 내에서 구분지어진 실행단위이다.
*</em><img src=https://velog.velcdn.com/cloudflare/daydream_03/4f14764c-ad4c-4e99-b1cb-e9bba78027ae/image.png width=80%></p>
<p>한 개의 프로세스 안에 다수의 스레드가 있을 때,
스레드는 code, data, heap 영역을 <strong>공통된 자원으로 사용</strong>한다.
공유되는 자원이 있기 때문에 컨텍스트 스위칭에서도 모든 것을 넣고 뺄 필요가 사라진다.</p>
<p>&lt;예시&gt;
악기 연주실을 대여해 이용한 후 다음 팀을 위해 자리를 비워줄 때,
컨텍스트 스위칭은 모든 악기와 장비를 다 빼내고 다음 팀이 다시 모든 악기와 장비를 들여오는 식이다.
하지만 스레드의 경우 설치된 악기와 장비는 그대로 두고, 직접 휴대하는 악기(기타)만 가지고 들어와 연결해 사용하는 식</p>
<h3 id="multi-process-multi-thread">Multi-process, Multi-thread</h3>
<p>두 가지 모두 <strong>한 어플리케이션에 대한 처리방식</strong>의 일종이다.
<img src="https://velog.velcdn.com/cloudflare/daydream_03/3625a9e4-5059-431b-b337-7f34682158a9/image.png" alt="">
멀티 프로세스는 <strong>두 사람이 각기 다른 공간에서 작업</strong>하는 것과 같다.</p>
<ul>
<li>독립적으로 분리되어 있어 동기화가 필요없지만, 서로 대화하려면 각자 있던 회의실에서 나와서 대화(IPC)해야하므로 소모적이다.</li>
<li>구글 크롬의 멀티탭 기능은 heavy하지만, 한 탭이 문제가 생겨도 다른 탭들이 영향을 받지 않는 등 강력한 기능을 제공한다.</li>
</ul>
<p>멀티 스레드는 <strong>두 사람이 같은 공간에서 작업</strong>하는 것과 같다.</p>
<ul>
<li>통신이 용이하여 비용이 절감되지만, 긴밀하게 연결되어 있으므로 공유되는 자원 관리가 필요하다.</li>
<li>인터넷 익스플로어의 멀티탭 기능은 한 탭이 문제가 생기면 모든 탭이 종료된다.(지금은 안써서 모르겠지만 예전에는 그랬다..)</li>
</ul>
<h3 id="multi-core">Multi-core</h3>
<p>멀티코어는 멀티 프로세스, 멀티 스레드와 달리 하드웨어 측면에 가깝다.
<img src="https://velog.velcdn.com/cloudflare/daydream_03/c890f157-1ed7-407f-86db-7d5a60a4b802/image.png" alt=""></p>
<h4 id="동시성concurrency">동시성(Concurrency)</h4>
<p>짧은 시간에 cpu의 시간을 분할해 여러 실행단위를 번갈아 실행하면서 마치 동시에 실행되는 것처럼 보이게 하는 것</p>
<h4 id="병렬처리parallelism">병렬처리(Parallelism)</h4>
<p><strong>물리적으로</strong> 여러 코어를 두고 다수의 실행단위를 동시에 처리할 수 있게 하는 것</p>
<h3 id="reference">Reference</h3>
<blockquote>
<p><a href="https://www.youtube.com/watch?v=1grtWKqTn50&amp;list=PLgXGHBqgT2TvpJ_p9L_yZKPifgdBOzdVH&amp;index=57">우아한테크코스 테코톡</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터 링크 계층 (2-2)]]></title>
            <link>https://velog.io/@daydream_03/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A7%81%ED%81%AC-%EA%B3%84%EC%B8%B5-2-2</link>
            <guid>https://velog.io/@daydream_03/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A7%81%ED%81%AC-%EA%B3%84%EC%B8%B5-2-2</guid>
            <pubDate>Mon, 21 Mar 2022 07:52:17 GMT</pubDate>
            <description><![CDATA[<h2 id="스위치">스위치</h2>
<h3 id="mac-주소-테이블">MAC 주소 테이블</h3>
<blockquote>
<ul>
<li>스위치 내부에는 MAC 주소 테이블 (혹은 브리지 테이블)이 있는데,</li>
</ul>
</blockquote>
<ul>
<li>스위치의 <strong>포트 번호</strong>와 해당 포트에 연결된 컴퓨터의 <strong>MAC 주소</strong>가 등록된 <strong>데이터베이스</strong>와 같다.</li>
</ul>
<h4 id="mac-주소-학습-기능">MAC 주소 학습 기능</h4>
<blockquote>
<ol>
<li>MAC 주소 테이블은 아무 것도 등록되어 있지 않은 상태에서</li>
<li>컴퓨터에서 목적지 MAC 주소가 추가된 <strong>프레임</strong> 데이터를 전송하면</li>
<li>MAC 주소 테이블을 먼저 확인하는데, 이 때 출발지 MAC 주소가 등록되어 있지 않으면</li>
<li>MAC 주소를 포트 번호와 함께 등록한다.</li>
</ol>
</blockquote>
<h4 id="플러딩flooding">플러딩(Flooding)</h4>
<blockquote>
<p>스위치가 수신 포트 이외의 <strong>모든 포트에서 데이터를 송신</strong>하는 것을 지칭.</p>
</blockquote>
<ol>
<li>컴퓨터 1에서 스위치를 통해 컴퓨터 3으로 데이터를 전송할 때</li>
<li>컴퓨터 1의 MAC 주소는 주소 학습 기능에 의해 테이블에 등록되지만,</li>
<li>컴퓨터 3의 목적지 MAC 주소는 테이블에 등록되어 있지 않아 스위치는 송신 포트 1번을 제외한 <strong>모든 포트</strong>에 프레임을 전송한다.</li>
</ol>
<h4 id="mac-주소-필터링">MAC 주소 필터링</h4>
<blockquote>
<p>스위치가 MAC 주소를 기준으로 <strong>목적지를 선택</strong>하는 것.</p>
</blockquote>
<ol>
<li>플러딩과 반대로 목적지 MAC 주소가 테이블에 등록되어 있다면,</li>
<li>스위치는 컴퓨터 1에서 송신된 프레임을 컴퓨터 3에만 전송한다.</li>
</ol>
<h2 id="케이블-구조">케이블 구조</h2>
<h3 id="전이중-통신과-반이중-통신">전이중 통신과 반이중 통신</h3>
<blockquote>
<p><strong>전이중 통신</strong> : 데이터의 송수신이 <strong>동시에</strong> 일어남 (ex: 크로스 케이블, 스위치)
<strong>반이중 통신</strong> : <u>회선 하나로</u> 송신과 수신이 <strong>번갈아가며</strong> 일어남 (ex: 허브)</p>
</blockquote>
<p>따라서 반이중 통신은 데이터를 동시에 전송 시 <strong>충돌</strong>이 발생한다.</p>
<h3 id="충돌-도메인">충돌 도메인</h3>
<blockquote>
<p>충돌이 발생할 때 <strong>그 영향이 미치는 범위</strong>를 지칭
<strong>허브</strong>의 경우
허브에 연결되어 있는 <strong>컴퓨터 전체</strong>가 충돌 도메인이 된다</p>
</blockquote>
<h2 id="arpaddress-resolution-protocol">ARP(Address Resolution Protocol)</h2>
<blockquote>
<p>목적지 컴퓨터의 <strong>IP 주소를 이용해 MAC 주소를 찾는</strong> 프로토콜. 
IP 주소를 물리 주소인 MAC 주소로 변환하는데 사용한다.</p>
</blockquote>
<p>출발지 컴퓨터가 목적지 주소를 모를 경우 이를 알아내기 위해 네트워크에 브로드캐스트를 하는데, 이를 <strong>ARP 요청(request)</strong>라 칭함.</p>
<blockquote>
</blockquote>
<p>이 요청에 대해 지정된 IP주소를 갖는 컴퓨터만 MAC주소를 응답으로 보내는데, 이를 <strong>ARP 응답(reply)</strong>라고 한다.</p>
<blockquote>
</blockquote>
<p><strong>ARP 테이블</strong>이란
출발지 컴퓨터가 MAC 주소를 얻은 후에 메모리에 보관하는 <u>MAC 주소와 IP 주소의</u> <strong>매핑 정보</strong>를 말한다.</p>
<blockquote>
</blockquote>
<p>IP 주소가 변경되면 MAC 주소도 함께 변경되므로 <strong>ARP 테이블은 보존기간을 ARP 캐시로 지정</strong>하여, 보존기간이 만료되면 삭제 후 다시 ARP 요청을 한다.</p>
<h2 id="이더넷">이더넷</h2>
<h3 id="규격">규격</h3>
<blockquote>
<p>이더넷 규격 예시:
<strong>10BASE-T</strong> </p>
</blockquote>
<p>10 : 통신속도(Mbps)
Base : BASEBAND 전송 방식. (펄스 신호에 의한 디지털 전송 방식)
T : 케이블 종류</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터 링크 계층 (1-2)]]></title>
            <link>https://velog.io/@daydream_03/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A7%81%ED%81%AC-%EA%B3%84%EC%B8%B5</link>
            <guid>https://velog.io/@daydream_03/%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%A7%81%ED%81%AC-%EA%B3%84%EC%B8%B5</guid>
            <pubDate>Mon, 14 Mar 2022 06:45:01 GMT</pubDate>
            <description><![CDATA[<h2 id="데이터-링크-계층">데이터 링크 계층</h2>
<h3 id="역할">역할</h3>
<blockquote>
<p>네트워크 장비 간 신호를 주고받는 규칙을 정한다.
그 중 일반적으로 많이 사용되는 것이 <strong>이더넷</strong>이다</p>
</blockquote>
<h3 id="이더넷">이더넷</h3>
<blockquote>
<p>랜에서 데이터를 주고받기 위한 규칙이다.
<strong>CSMA/CD</strong> 방식을 사용해 <u>여러 컴퓨터가 동시에 데이터를 전송할 경우</u> <strong>충돌</strong>의 발생을 방지한다.</p>
</blockquote>
<h3 id="csmacd">CSMA/CD</h3>
<blockquote>
<p>Carrier Sense Multiple Access with Collision Detection.</p>
</blockquote>
<ul>
<li>CS : 데이터를 보내려고 하는 컴퓨터가 케이블에 신호가 흐르고 있는지 확인하는 규칙</li>
<li>MA : 케이블에 데이터가 흐르고 있지 않으면 데이터를 보내는 규칙</li>
<li>CD : 충돌이 발생하고 있는지 확인하는 규칙</li>
</ul>
<h2 id="mac-주소의-구조">MAC 주소의 구조</h2>
<h3 id="mac-주소란">MAC 주소란?</h3>
<blockquote>
<p>Media Access Control Address.
비트열(0과 1)을 전기 신호로 변환하는 랜 카드가 제조될 때 새겨지는 <strong>물리 주소</strong>로, <strong>전 세계에서 유일한 번호</strong>이다.</p>
</blockquote>
<h3 id="mac-주소를-사용한-통신">MAC 주소를 사용한 통신</h3>
<blockquote>
<p>데이터 링크계층에서 데이터에 붙이는 헤더는 <strong>이더넷 헤더</strong>와 <strong>트레일러</strong>이다.</p>
</blockquote>
<h3 id="이더넷-헤더의-구조">이더넷 헤더의 구조</h3>
<blockquote>
</blockquote>
<table>
<thead>
<tr>
<th align="center">목적지 MAC 주소(6바이트)</th>
<th align="center">출발지 MAC 주소(6바이트)</th>
<th align="left">유형(2바이트)</th>
</tr>
</thead>
<tbody><tr>
<td align="center">총 14 바이트로 구성</td>
<td align="center"></td>
<td align="left"></td>
</tr>
<tr>
<td align="center">** 유형**이란?</td>
<td align="center"></td>
<td align="left"></td>
</tr>
<tr>
<td align="center"><strong>프로토콜 종류를 식별하는 번호</strong>를 포함한다</td>
<td align="center"></td>
<td align="left"></td>
</tr>
</tbody></table>
<h3 id="트레일러">트레일러</h3>
<blockquote>
<p><strong>FCS</strong>(Frame Check Sequence)라고도 한다.
데이터 전송 도중 오류가 발생하는지 확인하는 용도로 사용.</p>
</blockquote>
<h3 id="프레임">프레임</h3>
<blockquote>
<p><strong>이더넷 헤더</strong>와 <strong>트레일러</strong>가 추가된 데이터를 뜻함.
네트워크를 통해 프레임이 전송됨.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 물리계층]]></title>
            <link>https://velog.io/@daydream_03/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EB%AC%BC%EB%A6%AC%EA%B3%84%EC%B8%B5</link>
            <guid>https://velog.io/@daydream_03/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EB%AC%BC%EB%A6%AC%EA%B3%84%EC%B8%B5</guid>
            <pubDate>Fri, 11 Mar 2022 11:11:44 GMT</pubDate>
            <description><![CDATA[<h2 id="물리-계층의-역할">물리 계층의 역할</h2>
<blockquote>
<p>컴퓨터와 네트워크 장비를 연결하고, 0과 1로 이루어진 데이터를 전기신호로 변환해줌
이 때 0과 1의 정보는 컴퓨터 내부의 <strong>랜 카드</strong>로 전송되고 랜 카드는 이를 전기 신호로 변환한다</p>
</blockquote>
<h2 id="네트워크-전송-매체-케이블">네트워크 전송 매체: 케이블</h2>
<h3 id="전송매체">전송매체</h3>
<blockquote>
<ul>
<li>데이터가 흐르는 물리적인 선로</li>
</ul>
</blockquote>
<ul>
<li>유선과 무선으로 나뉜다<ul>
<li>유선 : 트위스트 페어 케이블, 광케이블</li>
<li>무선 : 라디오파, 마이크로파, 적외선</li>
</ul>
</li>
</ul>
<h3 id="트위스트-페어-케이블twisted-pair-cable">트위스트 페어 케이블(twisted pair cable)</h3>
<blockquote>
<p>UTP케이블과 STP 케이블로 나뉜다</p>
</blockquote>
<h4 id="utp-케이블">UTP 케이블</h4>
<ul>
<li>구리 선 8개를 2개씩 꼬아 만든 4쌍의 전선</li>
<li>가격이 저렴하지만 <strong>실드</strong>로 보호되어 있지 않아 노이즈의 영향을 받기 쉽다<h4 id="stp-케이블">STP 케이블</h4>
</li>
<li>전선을 실드로 보호한 케이블</li>
<li>비싸지만 노이즈의 영향을 적게 받는다</li>
</ul>
<h3 id="다이렉트-케이블-크로스-케이블">다이렉트 케이블, 크로스 케이블</h3>
<h4 id="다이렉트-케이블">다이렉트 케이블</h4>
<blockquote>
<p>구리 선 8개를 <strong>같은 순서</strong>로 연결한 케이블
컴퓨터와 스위치 연결에 사용</p>
</blockquote>
<h4 id="크로스-케이블">크로스 케이블</h4>
<blockquote>
<p><strong>1번</strong>과 <strong>2번</strong> 구리 선을 다른 쪽 커넥터의 <strong>3번</strong>과 <strong>6번</strong>에 연결한 케이블
컴퓨터 간 랜 케이블로 직접 연결 시 사용</p>
</blockquote>
<h2 id="리피터와-허브">리피터와 허브</h2>
<h3 id="리피터">리피터</h3>
<blockquote>
<p>전기 신호 전송 시 거리가 멀어지면 감쇠하는 신호를 <strong>증폭</strong>하여 전달하는 <strong>신호 중계 장치</strong>
일대일 통신만 가능</p>
</blockquote>
<h3 id="허브">허브</h3>
<blockquote>
<p>리피터와 마찬가지로 <strong>전기 신호를 정형, 증폭하는 기능</strong>을 담당
여러 개의 <strong>포트</strong>를 가지고 있어 여러 대의 컴퓨터와 통신이 가능
수신한 데이터를 모든 포트로 전송하는 단점이 있다. 이를 보완한 것이 <strong>스위치</strong>이다</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[기업협업 회고록]]></title>
            <link>https://velog.io/@daydream_03/%EA%B8%B0%EC%97%85%ED%98%91%EC%97%85-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@daydream_03/%EA%B8%B0%EC%97%85%ED%98%91%EC%97%85-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Wed, 09 Mar 2022 18:32:29 GMT</pubDate>
            <description><![CDATA[<p>오늘은 기업협업 기간 중 틈틈히 작성해두었지만 마무리짓지 못하여 임시 글에 오랜 기간 잠들어있던 기업협업 회고록을 마무리짓고자 합니다.</p>
<h2 id="얼리슬로스란-회사를-택한-이유">얼리슬로스란 회사를 택한 이유</h2>
<p>기업협업을 앞두고 내가 회사를 선택하는데 적용한 기준은 이러했다. 
<strong>첫째, 회사가 운영하고 있는 서비스와 관련이 있는 주제의 프로젝트일 것.
둘째, 현업에서 일하는 개발자의 삶이 어떠한지 직접 부딪혀보고 온전히 체험해볼 수 있을 것.
**
그리고 얼리슬로스를 택한 이유는 오직 딱 한 가지.
얼리슬로스라는 회사와 우리가 함께 하게 될 프로젝트에 대해 **정성껏 작성된 소개글</strong> 때문이었다. (나중에 알게 되었지만 대표님이 직접 작성하셨다고...)
해당글은 나의 니즈에 정확히 부합했고, 무엇보다도 <strong>전문 PM분과 일해볼 수 있다</strong>는 기대감에 나는 고민없이 얼리슬로스에 지원하게 되었다.</p>
<h2 id="프로젝트를-수행하며-느낀-점">프로젝트를 수행하며 느낀 점</h2>
<h3 id="기획을-완벽하게-이해하는건-생각보다-어렵다">기획을 완벽하게 이해하는건 생각보다 어렵다</h3>
<img src=https://images.velog.io/images/daydream_03/post/87362f7e-ac69-43d8-9ec9-81b22fbc3dbb/image.png width=20%>

<p>생애 처음으로 개발자로서 프로젝트 기획서를 받아보고 이후 미팅에도 참여하면서 느낀 점은 <strong>기획을 완벽하게 이해하는 것이 생각보다 어렵다</strong>는 것이었다.
이전 위코드에서 진행했던 프로젝트에서 직접 웹사이트 기능을 정의, 기획하고 구현할 때 기획 상의 miss로 인해 시간적 여유가 있었음에도 불구하고 비회원용 장바구니를 구현하지 못한 적이 있었다.
과거의 실수에서 배운 점을 토대로 기획서를 찬찬히 뜯어보았고, 프로젝트의 기반이 되는 얼리슬로스의 서비스 또한 직접 사용해보고 의문점은 PM분과 직접 소통하며 기획을 완벽히 이해하고자 노력하였다.</p>
<p><strong>하지만.. **
개발에 착수하게 되면서 디테일한 부분에서 1) 기획서에서 언급되지 않아 구체적인 논의가 필요했거나 2) 내가 기획서를 잘못 이해했거나 3) 둘 다 해당하는 경우가 발생하기 시작했다!
단언컨대 이번 프로젝트에서 PM분을 가장 귀찮게 한 건 나라고 자신있게 말할 수 있을 정도로, 궁금한 점이 생길 때마다 정리하여 질문하고, 컨펌받고, 때로는 협의하면서 **개발의 방향성이 기획과 일치하도록</strong> 지속적으로 수정해나갔다.
그 결과 PM분한테서 프로젝트에 대한 이해도가 굉장히 높다는 긍정적인 피드백을 받는 수준까지 올라가게 되었고, 팀원들 사이에서도 각자 프로젝트에 대한 이해도가 달라 의견이 분분할 때에 <strong>PM분을 대신하여 설명하고 방향을 제시할 수 있었던 점</strong>이 고무적이었다.
이 자리를 빌어 저의 계속되는 질문공세에도 성실하고 친절하게 답변해주신 PM분께 감사를 표합니다. ( ͡• ͜ʖ ͡• )</p>
<h3 id="누구나-개발일정을-지키고-싶다-blocker를-만나기-전까진">누구나 개발일정을 지키고 싶다. Blocker를 만나기 전까진...</h3>
<img src=https://images.velog.io/images/daydream_03/post/f5ffc032-274c-4ff7-be64-edd53dd957d3/image.png width=10%>

<p>프로젝트에 있어 핵심이라 할 수 있는 <strong>POP3를 통한 이메일 파싱</strong>을 담당하게 되면서 <strong>매순간마다 문제에 부딪히고 해결하는 과정의 연속</strong>을 경험했다.
내가 구현한 내용을 포인트 별로 정리하고 나름대로 느낀 점을 토대로 개발일지를 작성해보았다.</p>
<ol>
<li>POP3 이메일 sync하기<ul>
<li>처음이라 다소 생소했던 POP3 개념에 대해 학습하고 인터넷에 올라온 여러 개의 예제 코드를 분석하였다. 
예제 코드들을 분석할 때 매줄마다 print를 찍어가며 각 줄이 어떤 의미를 갖고 어떤 용도로 사용되었는지 파악하고나니, 불필요한 부분은 제하고 효율 좋게 로직을 구현할 수 있었다.</li>
</ul>
</li>
<li>이메일 파싱<ul>
<li>텍스트 추출에는 <strong>정규표현식</strong>이 최고인 것 같다. 일일히 iterate하지 않고 조건만 잘 설정해주면 되고 성능도 뛰어나다. </li>
<li><em>regex101.com*</em>은 앞으로도 매우 자주 방문할 웹사이트가 될 것 같다. 강추! 또 강추!</li>
</ul>
</li>
<li>추출한 텍스트를 데이터베이스에 저장</li>
<li>위 과정을 일정 시간 간격을 두고 반복 (예: 10분)<ul>
<li>time 모듈에서 sleep 메서드로 구현했다. <code>__name__</code> 내부에 위치시켜 해당 함수가 호출되면 
POP3 서버에서 이메일 sync → 정규표현식으로 이메일 파싱 → 파싱된 내용을 변수에 담아 django ORM으로 데이터베이스에 저장 → 600초 타이머 시작 → 앞선 과정 반복이 되게끔 구현하였다</li>
</ul>
</li>
<li>Blocker 발생<ul>
<li>POP3의 원리에 의하면 POP3 서버로부터 메일을 다운 받아 열게되면 서버에서는 메일을 삭제한다.</li>
<li>따라서 10분으로 설정한 타이머가 돌아가는 동안 <strong>새로 수신된 이메일들만</strong> 다음 회차에서 로직이 실행될 때 파싱되어 데이터베이스에 저장될 거라 생각했다.</li>
<li><strong>그러나</strong> 로직을 반복해서 호출, 실행할 때마다 이미 읽어들인 메일들이 남아있어 <strong>데이터베이스에 계속 중복으로 저장</strong>이 되고 있었다.</li>
</ul>
<ol start="6">
<li>Blocker 해결 과정<ul>
<li>공식문서에서 pop3의 dele() 메서드를 발견하였고, 사용해 보았지만 blocker 해결이 되지 않았다.</li>
<li>그러던 와중에 역시 공식문서에서 POP3로부터 연결을 종료하여야 한다는 구문이 눈에 띄었다.</li>
<li><strong>quit()</strong> 메서드를 사용해 POP3 서버에 연결했던 connection을 끊었다가 재로그인하여 메일 파싱을 시도해보니 Blocker가 해결되었음을 확인!</li>
<li>기존의 로직은 POP3 접속 상태를 유지한 상태에서 계속 메일을 불러오는 방식이었다면,
새로운 로직은 POP3 접속 → 이메일 파싱 → DB 저장 → POP3 연결 해제 → 600초 후 로그인 → 반복으로 수정</li>
</ul>
</li>
</ol>
</li>
</ol>
<p>Blocker를 해결하는데에 나는 장장 이틀 가량의 시간을 모니터와 씨름하면서 보내야했다.
프론트엔드 측에 빨리 API를 구현해줘야한다는 생각에 압도되어 때때로 조바심이 나기도 했지만, 최대한 이런 <strong>스트레스를 긍정적으로 승화</strong>시키고자 노력했다.
특히 나는 얼리슬로스 사옥 옥상에 올라가 시원한 겨울 바람을 쐐며 정신을 환기시키는 걸 유독 좋아했는데, 실제로 Blocker를 해결한 단서도 사옥 옥상에서 핸드폰으로 검색하다가 발견했었다. (광화문 광장 + 경복궁 + 청와대 + 인왕산이 한눈에 들어오는 전경은 정말 죽여준다...)</p>
<h2 id="지난-한-달을-회상하며">지난 한 달을 회상하며...</h2>
<p><img src="https://images.velog.io/images/daydream_03/post/9a5390b9-ddf3-4714-a1fb-9d2e9c2201db/image.png" alt=""></p>
<p>얼리슬로스에서 보낸 한 달이라는 시간은 감사함이 넘치는 시간이었다. 
<strong>긍정적인 분위기에서 열정적인 마인드</strong>로 일하는 사람들.
친밀하지만 또 <strong>서로를 존중</strong>하는 조직문화.
기획 미팅 때 개발팀 전원이 참석해 모두가 동일한 이해도를 갖고 개발을 시작하기 위해 열띤 토론을 펼치며 <strong>소통하는 개발문화</strong> 등등...
앞으로 내가 일하게 될 회사를 정함에 있어 얼리슬로스는 여러모로 <strong>좋은 기준</strong>이 될 수 있을 거라는 확신이 들었다.</p>
<p>또한 개발자로서의 성장에 있어서도 얼리슬로스는 크나큰 도움이 되었다.
그동안 내 마음 한구석에는 <strong>&quot;미숙하지만 개발자로서 첫 발을 내딛게 되는건데 과연 잘할 수 있을까?&quot;</strong> 라는 의문이 남아있었고, 또 그 해답을 이 곳에서 찾을 수 있었다.
얼리슬로스의 개발자 분들께서는 나의 성장을 위해 여러모로 가이드를 제시해 주셨지만 결코 정답을 던져주진 않으셨다. 그게 절대로 도움이 될 순 없기 때문이다.
주어진 가이드를 토대로 나의 역량을 총동원한 결과, 나는 <strong>온전히 나의 힘으로</strong> 프로젝트가 기획한 1, 2차 목표를 모두 달성할 수 있었다.</p>
<p><strong>한 가지 유일하게 아쉬운 점</strong>을 꼽으라고 한다면 아직 개발자로서 미숙한 나로 인해 얼리슬로스 개발팀장이신 Z님께 많은 걸 물어보고 또 얻어가지 못했던 것. (실제로 Z님은 프로젝트 개발 외에도 이거 공부하고 정리한 거 제출하세요~ 하면서 가볍게 툭툭 던져주셨는데, 정말정말 유익한 것들 뿐이었다)
그렇지만 얼리슬로스는 나에게 한없이 좋은 기억으로 남아있기에 앞으로도 지속적으로 관계를 이어나가고 싶다.</p>
<p>*<em>와신상담(臥薪嘗膽). 
*</em>장작 위에 누워 쓴 쓸개를 맛보며 목표를 이루기 위해 노력함을 일컫는 사자성어다.
기업협업은 나에게 내가 아직 모든 방면에서 얼마나 부족하고 갈 길이 먼지 뼈저리게 느끼게 해주는 자극제가 되었다.
이를 동기 삼아 앞으로의 취준 그리고 그 이후의 과정 속에서도 끊임없이 나를 채찍질하며 성장하는 그런 개발자가 되어야겠다고 다짐해본다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 기본 규칙]]></title>
            <link>https://velog.io/@daydream_03/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</link>
            <guid>https://velog.io/@daydream_03/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</guid>
            <pubDate>Mon, 07 Mar 2022 08:45:27 GMT</pubDate>
            <description><![CDATA[<h2 id="프로토콜">프로토콜</h2>
<p>컴퓨터 간 정보를 주고받을 때의 통신 방법에 대한 <strong>규칙</strong> 혹은 <strong>표준</strong></p>
<h2 id="osi-모델--open-system-interconnection">OSI 모델 : Open System Interconnection</h2>
<p>국제표준화기구(ISO)가 정의한 국제 통신 표준 규약</p>
<h3 id="osi-모델의-7계층">OSI 모델의 7계층</h3>
<table>
<thead>
<tr>
<th align="center">계층</th>
<th align="center">이름</th>
<th align="left">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">7계층</td>
<td align="center">응용 계층(Application Layer)</td>
<td align="left">이메일&amp;파일 전송, 웹사이트 조회 등 애플리케이션에 대한 서비스 제공</td>
</tr>
<tr>
<td align="center">6계층</td>
<td align="center">표현 계층(Presentation Layer)</td>
<td align="left">문자코드, 압축, 암호화 등의 데이터 변환</td>
</tr>
<tr>
<td align="center">5계층</td>
<td align="center">세션 계층(Session Layer)</td>
<td align="left">세션 체결, 통신 방직을 결정</td>
</tr>
<tr>
<td align="center">4계층</td>
<td align="center">전송 계층(Transport Layer)</td>
<td align="left">신뢰가능한 통신 구현</td>
</tr>
<tr>
<td align="center">3계층</td>
<td align="center">네트워크 계층(Network Layer)</td>
<td align="left">다른 네트워크와의 통신경로 설정 및 논리주소 결정</td>
</tr>
<tr>
<td align="center">2계층</td>
<td align="center">데이터 링크 계층(Data Link Layer)</td>
<td align="left">네트워크 기기 간 데이터 전송 및 물리주소 결정</td>
</tr>
<tr>
<td align="center">1계층</td>
<td align="center">물리 계층(Physical Layer)</td>
<td align="left">시스템 간 물리적 연결과 전기 신호의 변환 및 제어</td>
</tr>
</tbody></table>
<p>데이터 송신 측은 &quot;응-표-세-전-네-데-물&quot; 순서로, 수신 측은 그 역순으로 계층을 거쳐 데이터를 주고 받는다</p>
<h3 id="tcpip-모델">TCP/IP 모델</h3>
<p>기존 OSI 모델에서 현재는 TCP/IP 모델을 사용함</p>
<ul>
<li>응용 계층 (응용+표현+세션)</li>
<li>전송 계층</li>
<li>인터넷 계층 (네트워크)</li>
<li>네트워크 접속 계층 (데이터 링크 + 물리)</li>
</ul>
<p>로 구성되어 있다</p>
<h2 id="캡슐화역캡슐화">캡슐화/역캡슐화</h2>
<img src=https://images.velog.io/images/daydream_03/post/06d10a60-702b-4434-ad74-1630a7fcbe6a/image.png width=40%>

<h3 id="캡슐화">캡슐화</h3>
<p>컴퓨터 통신에서 상위 계층의 통신 프로토콜 정보(<strong>헤더</strong>)를 데이터에 추가하여 하위 계층으로 전송하는 기술</p>
<p>1) 응용 계층 : 웹 사이트에 접속하기 위한 요청 데이터를 만든다
2) 전송 계층 : <u>신뢰가능한 통신</u>이 이루어지도록 <strong>전송 계층 헤더</strong>를 붙인다
3) 네트워크 계층 : <u>다른 네트워크와 통신</u>을 위해 <strong>네트워크 계층 헤더</strong>를 추가한다
4) 데이터 링크 계층 : <u>물리적인 통신 채널 연결</u>을 위해 데이터 링크 계층 <strong>헤더</strong>와 <strong>트레일러</strong>를 추가한다
5) 데이터는 최종적으로 <strong>전기 신호</strong>로 변환되어 수신 측으로 이동한다</p>
<h3 id="역캡슐화">역캡슐화</h3>
<p>상위 계층에 통신 프로토콜에서 하위 계층에서 추가한 정보와 데이터를 분리하는 기술</p>
<p>1)-5)의 역순으로 헤더와 트레일러를 제거하여 최종적으로 웹 사이트 요청 데이터를 전달 받는다</p>
<h3 id="헤더">헤더</h3>
<p>저장 혹은 전송되는 데이터의 맨 앞에 위치하는 <strong>추가적인 정보 데이터</strong>
데이터의 내용이나 성격을 식별 또는 제어한다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[네트워크 용어 정리]]></title>
            <link>https://velog.io/@daydream_03/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@daydream_03/%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 07 Mar 2022 04:17:30 GMT</pubDate>
            <description><![CDATA[<p>네트워크</p>
<blockquote>
<p>컴퓨터를 두 대 이상 연결하여 상호 간 데이터 전송이 가능한 통신망</p>
</blockquote>
<p>인터넷</p>
<blockquote>
<p>TCP/IP 프로토콜을 사용하는 세계 최대 규모의 네트워크. 전 세계의 컴퓨터를 연결하는 거대한 통신망.</p>
</blockquote>
<p>패킷</p>
<blockquote>
<p>네트워크 통신에 사용되는 분할된 데이터 조각.
네트워크에서 전송하는 데이터의 기본 단위.</p>
</blockquote>
<p>비트</p>
<blockquote>
<p>정보의 최소 단위. 0과 1로 나타냄.</p>
</blockquote>
<p>바이트</p>
<blockquote>
<p>컴퓨터의 정보량 단위. 8비트 = 1바이트</p>
</blockquote>
<p>Local Area Network(LAN)</p>
<blockquote>
<p>가까운 거리 내 특정한 지역을 범위로 하는 네트워크. ex) 집, 사무실, 학교 등</p>
</blockquote>
<p>Wide Area Network(WAN)</p>
<blockquote>
<p>랜을 하나로 묶는 거대한 네트워크.
특정 도시, 국가, 대륙 같이 넓은 범위를 연결함.</p>
</blockquote>
<p>Internet Service Provider(ISP)</p>
<blockquote>
<p>인터넷 접속수단을 제공하는 사업자. ex) KT, U+, SK브로드밴드</p>
</blockquote>
<p>서버</p>
<blockquote>
<p>컴퓨터 네트워크에서 다른 컴퓨터에 서비스를 제공하기 위한 컴퓨터 또는 프로그램.</p>
</blockquote>
<ul>
<li>클라이언트 : 서버에서 보내주는 정보 서비스를 받거나 요구하는 측의 컴퓨터 또는 프로그램 (서버 &lt;=&gt; 클라이언트)</li>
</ul>
<p>DeMilitarized Zone(DMZ)</p>
<blockquote>
<p>네트워크 구성 중 외부 네트워크와 내부 네트워크 사이에 위치한 중간 지대(서브넷).
네트워크의 보안 영역으로써 외부에서 내부 네트워크로 침투하는 공격을 막는 역할을 담당.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[기본 용어 정리]]></title>
            <link>https://velog.io/@daydream_03/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8DOOP</link>
            <guid>https://velog.io/@daydream_03/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8DOOP</guid>
            <pubDate>Mon, 07 Mar 2022 01:48:11 GMT</pubDate>
            <description><![CDATA[<p>파이썬에서 클래스와 메소드를 기반으로 하는 객체지향 프로그래밍에 대해 학습한 내용을 정리하여 다뤄볼 예정입니다</p>
<h4 id="class">Class</h4>
<blockquote>
<p><strong>설계도</strong>
집단에 속하는 속성과 행위를 변수와 메소드로 정의한 것</p>
</blockquote>
<h4 id="instanceobject">Instance(object)</h4>
<blockquote>
<p>** 설계도 **를 토대로 실제 메모리에 할당된 것.
실제 프로그램에서 사용되는 데이터</p>
</blockquote>
<blockquote>
<p>하나의 class에서 생성된 복수의 instance는 각각 ** 독립적 **이다</p>
</blockquote>
<h2 id="oop-원칙">OOP 원칙</h2>
<h4 id="캡슐화-encapsulation">캡슐화 (Encapsulation)</h4>
<blockquote>
<p>객체(object)의 속성과 행위를 하나로 묶고, 구현된 일부를 은닉</p>
</blockquote>
<h4 id="추상화-abstraction">추상화 (Abstraction)</h4>
<blockquote>
<p>불필요한 정보는 숨기고, 필요한 정보만 표현</p>
</blockquote>
<h4 id="상속-inheritance">상속 (Inheritance)</h4>
<blockquote>
<ul>
<li>부모 class의 속성과 행위를 그대로 상속받되 부분수정이 가능하다</li>
</ul>
</blockquote>
<ul>
<li>자식 class만의 추가적인 속성과 행위를 정의할 수 있다</li>
</ul>
<h4 id="다형성-polymorphism">다형성 (Polymorphism)</h4>
<blockquote>
<p>여러 형태를 가질 수 있다 (예: 기계부품)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Venv, Linter, Formatter 요약정리]]></title>
            <link>https://velog.io/@daydream_03/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%B4%88%EA%B8%B0%EC%84%B8%ED%8C%85-%EC%9A%94%EC%95%BD%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@daydream_03/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%B4%88%EA%B8%B0%EC%84%B8%ED%8C%85-%EC%9A%94%EC%95%BD%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 02 Mar 2022 02:17:06 GMT</pubDate>
            <description><![CDATA[<p>오늘은 vscode에서 작업 전에 세팅하면 좋을 여러 가지 주제를 간략하게 다뤄보겠습니다.</p>
<h2 id="가상환경-venv">가상환경 Venv</h2>
<p><strong>왜 필요한가</strong>
프로젝트 별로 사용하는 패키지의 버전이 항상 같을 수 없으므로,
각 프로젝트마다 가상환경을 구성해 그 안에 패키지들을 분리하여 설치, 관리</p>
<h3 id="venv">venv</h3>
<p>파이썬 3.5부터 지원되는 가볍게 쓰기 좋은 가상환경입니다</p>
<p><strong>가상환경 생성</strong></p>
<ol>
<li>터미널 상에서 프로젝트 디렉토리로 이동합니다</li>
<li>python -m venv .venv</li>
</ol>
<ul>
<li><code>.venv</code>라는 이름의 가상환경을 프로젝트 디렉토리 안에 생성하는 명령어입니다</li>
<li>프로젝트 디렉토리를 확인해보면 .venv 라는 폴더가 생성되었음을 확인할 수 있습니다
<img src="https://images.velog.io/images/daydream_03/post/8d08ecd3-6641-47a6-a1d6-525f2a480a5c/image.png" alt=""></li>
</ul>
<p><strong>가상환경 활성화</strong>
프로젝트 디렉토리 내에서 다음 명령어를 입력합니다
<code>source ./.venv/bin/activate</code>
비활성화는 <code>deactivate</code> 를 입력합니다.</p>
<p><strong>VScode 추가설정</strong></p>
<ol>
<li>터미널에서 <code>which python</code>을 입력하여 뜨는 결과창을 복사합니다
<img src="https://images.velog.io/images/daydream_03/post/6e68c09b-706a-45b3-bb9f-05884949b3d5/image.png" alt=""></li>
<li>VScode 좌측 하단에 다음과 같은 버튼을 클릭합니다
<img src="https://images.velog.io/images/daydream_03/post/f166aee7-8e3d-4fc9-800a-aabf4da374f6/image.png" alt=""></li>
<li>Select interpreter 창이 팝업되는데, 여기에 1번 단계에서 복사한 파이썬 경로를 붙여넣기해 입력해줍니다.</li>
</ol>
<p>이후 개발을 진행하며 설치하는 모든 패키지들은 가상환경이 활성화된 상태에서 설치를 진행합니다</p>
<h2 id="linter와-formatter">Linter와 Formatter</h2>
<p><strong>왜 필요한가</strong>
python에는 PEP8이라는 개발자 간의 약속된 코드 컨벤션이 있습니다
이러한 컨벤션을 준수하여 협업을 원활하게 함과 동시에 가독성 또한 높이기 위해 Linter와 Formatter를 사용합니다</p>
<h4 id="formatter">Formatter</h4>
<ol>
<li>VScode에서 <code>command + ,</code> 를 입력합니다</li>
<li>설정 창에서 format을 검색하여 다음과 같이 설정합니다
<img src="https://images.velog.io/images/daydream_03/post/09dedbea-37bf-458e-9133-b0c2cd3eea0c/image.png" alt=""></li>
<li>이후 작성한 코드를 저장할 시 창이 하나 팝업되는데, 여기서 필자는 <code>use black</code> 을 눌러 black이라는 formatter를 사용하겠습니다</li>
</ol>
<h4 id="linter">Linter</h4>
<ol>
<li>VScode에서 <code>command + shift + P</code>를 입력해 설정창을 띄웁니다</li>
<li><code>Python: Select Linter</code>를 입력합니다</li>
<li>여기서 필자는 <code>flake8</code>을 사용하겠습니다. 설치가 되어있지 않다면 추가로 뜨는 팝업 창에서 설치를 진행합니다</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스: 최소공배수, 최대공약수]]></title>
            <link>https://velog.io/@daydream_03/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B5%9C%EC%86%8C%EA%B3%B5%EB%B0%B0%EC%88%98-%EC%B5%9C%EB%8C%80%EA%B3%B5%EC%95%BD%EC%88%98</link>
            <guid>https://velog.io/@daydream_03/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B5%9C%EC%86%8C%EA%B3%B5%EB%B0%B0%EC%88%98-%EC%B5%9C%EB%8C%80%EA%B3%B5%EC%95%BD%EC%88%98</guid>
            <pubDate>Fri, 28 Jan 2022 01:14:49 GMT</pubDate>
            <description><![CDATA[<ol>
<li>두 수(n, m)를 입력받아 최소공배수와 최대공약수를 구하는 문제이다.</li>
<li>알고리즘 공부 중에 재귀함수를 접하게 되면서 <strong>유클리드 호제법</strong>을 이용해 최대공약수를 구하는 법을 알고 있었다. <ul>
<li>유클리드 호제법과 이를 이용한 최대공약수 구하기는 <a href="https://velog.io/@daydream_03/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9E%AC%EA%B7%80%ED%95%A8%EC%88%98">여기에서</a></li>
</ul>
</li>
<li>최소공배수는 두 수의 곱을 최대공약수로 나눈 수이다.<pre><code class="language-python">def gcd(n, m):
 if max(n, m) % min(n, m) == 0:
     return min(n, m)
 else:
     return gcd(min(n,m), max(n, m)%min(n, m))
</code></pre>
</li>
</ol>
<p>def solution(n, m):
    return [gcd(n, m), n*m/gcd(n, m)]</p>
<p>```</p>
<ul>
<li>오늘의 에러<ul>
<li>최대공약수(gcd)를 재귀호출하는 줄에서 첫번째 인수로 <code>min(n, m)</code>이 아닌 <code>max(n, m)</code>을 넣어 일부 문제에서 오답이 나왔다. 유클리드 호제법은 두 수가 서로 나누어 떨어지지 않을 때 그 <strong>나머지</strong>와 <strong>작은 수</strong>로 다시 나누기를 반복함을 기억하자</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Algorithm: 괄호 검사]]></title>
            <link>https://velog.io/@daydream_03/Algorithm-%EA%B4%84%ED%98%B8-%EA%B2%80%EC%82%AC</link>
            <guid>https://velog.io/@daydream_03/Algorithm-%EA%B4%84%ED%98%B8-%EA%B2%80%EC%82%AC</guid>
            <pubDate>Thu, 27 Jan 2022 13:31:04 GMT</pubDate>
            <description><![CDATA[<p>stack을 이용한 괄호 검사</p>
<pre><code class="language-python">def is_valid(string):
    left = [&#39;(&#39;, &#39;{&#39;, &#39;[&#39;]
    right = [&#39;)&#39;, &#39;}&#39;, &#39;]&#39;]
    stack = []

    for i in string:
        if i in left:
            stack.append(i)
    elif i in right:
            if len(stack) == 0:  #괄호는 반드시 왼쪽에서 열리므로
        return False
        if left.index(stack.pop()) != right.index(i):
                return False
    return len(stack) == 0    #stack이 비워졌다 = 검사통과</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조(Python)]]></title>
            <link>https://velog.io/@daydream_03/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0Python</link>
            <guid>https://velog.io/@daydream_03/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0Python</guid>
            <pubDate>Thu, 27 Jan 2022 11:46:56 GMT</pubDate>
            <description><![CDATA[<h2 id="사용자-정의-함수">사용자 정의 함수</h2>
<ul>
<li><p><strong>인수(argument)</strong>: 함수를 호출할 때 전달되는 필요한 정보</p>
</li>
<li><p><strong>매개변수(parameter)</strong>: 함수 헤더에 정의된, 함수 호출 시 인수가 전달되는 곳</p>
</li>
<li><p><strong>디폴트 인수(default argument)</strong>: 함수 호출 시 인수가 생략되면 기본 값으로 사용되는 인수</p>
</li>
<li><p><strong>키워드 인수(keyword argument)</strong>: 매개변수 이름에 <strong>직접</strong> 값을 지정하여 호출하는 인수. </p>
<ul>
<li>키워드 인수를 사용하면 함수 호출 시 인수의 순서를 변경 가능하다.</li>
</ul>
</li>
</ul>
<h2 id="✔️-변수의-범위">✔️ 변수의 범위</h2>
<blockquote>
<ol>
<li>내장 범위(built-in scope) : 언어의 일부로 정의된 변수와 리터럴들. 프로그램의 <strong>어디에서나</strong> 쓸 수 있다.</li>
<li>전역 범위(global scope) : 소스 파일 맨 위(함수나 클래스 밖)에서 생성된 변수. 프로그램 <strong>어디에서나</strong> 쓸 수 있다.</li>
<li>지역 범위(local scope) : 함수나 클래스의 멤버함수(메소드) 안에서 생성된 변수. 그 안에서만 사용. ex) 함수의 매개변수</li>
<li>인스턴스 범위(instance scope) : 클래스의 데이터 멤버로 생성된 변수들. 해당 클래스 내 다른 함수들에서 쓸 수 있다.</li>
</ol>
</blockquote>
<h2 id="✔️-모듈">✔️ 모듈</h2>
<blockquote>
<p><code>from module_A import *</code> → 모듈 A의 모든 식별자를 사용 
<code>from module_B import a, b</code> → 모듈 B의 a, b 식별자를 사용
많은 모듈을 사용할 경우 식별자가 중복될 수 있으므로 식별자는 가급적 선택적으로 사용하자.</p>
</blockquote>
<h2 id="✔️-클래스">✔️ 클래스</h2>
<blockquote>
<p><strong>클래스</strong>를 <strong>실체화(instance)</strong>한 것이 <strong>객체(object)</strong>이다.
클래스의 <strong>속성(attribute)</strong>은 <strong>메소드(method)</strong>에 의해 정의된다
    * <strong>메소드</strong>: 클래스 안의 함수를 지칭</p>
</blockquote>
<ul>
<li><p><strong><code>__init__</code> 메소드(생성자)</strong></p>
<ul>
<li>클래스가 실체화될 때 <strong>자동으로</strong> 호출된다.</li>
<li>객체에서 사용할 데이터를 정의하고 초기화하는 역할.</li>
<li><strong>모든 메소드</strong>는 첫 번째 인수(argument)로 항상 <strong>self</strong>를 받아주며, 여기서의 self는 실체화된 <strong>객체(object)</strong>를 가리킨다.<pre><code class="language-python">class Car:
  def __init__(self, color, speed=0):    #생성자 메소드
       self.color = color           #데이터 멤버 color 정의 및 초기화
       self.speed = speed           #데이터 멤버 speed 정의 및 초기화</code></pre>
<ul>
<li>self가 붙지 않은 모든 변수들은 멤버 변수가 아닌 지역변수 혹은 전역변수이다.</li>
</ul>
</li>
</ul>
</li>
<li><p>객체 생성하기</p>
<pre><code class="language-python">car1 = Car(&#39;black&#39;, 0)    # 검정색, 속도 0
car2 = Car(&#39;red&#39;, 120)    # 빨간색, 속도 120
car3 = Car(&#39;green&#39;)        # 초록색, 속도 0(디폴트 인수)</code></pre>
</li>
<li><p>객체에 대한 연산</p>
<pre><code class="language-python"> class Car:
     # ...
     def speedUp(self) : self.speed += 10
     def speedDown(self) : self.speed -= 10</code></pre>
<pre><code class="language-python"> car2.speedDown()    #car2 속도 10 감속
 car3.speedUp()        #car3 속도 10 가속

### 연산자 중복(operator overloading)
&gt;- 사용자가 의한 클래스의 객체들에게 표준 연산자를 적용 가능하다
```python
def isEqual(self, carB):
   if self.color == carB.color:
       return True
   else: return False</code></pre>
<pre><code class="language-python">car4 = Car(&#39;red&#39;)
print(car1.isEqual(car4))    # False
print(car2.isEqual(car4))    # True</code></pre>
<ul>
<li>자동차 클래스 내에서 <code>__eq__</code>라는 메소드를 정의하면 ==연산자로 바로 비교 가능함<pre><code class="language-python">def __eq__(self, carB):
 return self.color == carB.color</code></pre>
</li>
<li>Car 객체 문자열(str)로 변환하기 : <strong><code>__str__</code></strong>메소드<pre><code class="language-python">def __str__(self):
 return &quot;color = %s, speed = %d&quot; % (self.color, self.speed)
print(&quot;[car3]&quot;, car3)        # [car3] color = green, speed = 0</code></pre>
</li>
</ul>
<h3 id="상속">상속</h3>
<p>기존에 정의된 클래스로부터 멤버를 추가해 새로운 클래스를 간편하게 만드는 것을 지칭
** 기본(base) 클래스 ** : 부모 클래스
** 파생(derived) 클래스 ** : 자식 클래스</p>
<blockquote>
<ul>
<li>클래스의 상속</li>
</ul>
</blockquote>
<ul>
<li>Car 클래스를 상속하는 SuperCar 클래스</li>
<li>color와 speed는 *<em>다시 정의하지 않음 *</em>(self.color, self.speed는 부모 클래스의 생성자 호출로 해결)</li>
<li>자식 클래스에서 부모를 부르는 함수 super()<pre><code class="language-python">class SuperCar(Car):    #Car 상속
def __init__(self, color, speed=0, Turbo=True):
   super().__init__(color, speed)    #부모(Car) 클래스의 생성자 호출
   self.Turbo = Turbo    #터보모드 변수 생성 및 초기화</code></pre>
</li>
</ul>
</li>
<li><p>자식 클래스 객체 생성하기</p>
<pre><code class="language-python"> s1 = SuperCar(&quot;Gold&quot;, 0, True)    #골드, 속도 0, 터보모드 on
 s2 = SuperCar(&quot;White&quot;, 0, False)    #흰색, 속도 0, 터보모드 off</code></pre>
</li>
<li><p>메소드의 재정의(overriding)</p>
<pre><code class="language-python">  def setTurbo(self, Turbo=True):    #터보모드를 on/off하는 메소드
      self.Turbo= Turbo</code></pre>
<ul>
<li>터보 모드가 on이면 급속히 가속(+50)한다고 가정하면, 부모의 speedUp()함수는 터보 모드가 꺼진 경우로 볼 수 있다.<pre><code class="language-python">def speedUp(self):    #SuperCar의 SpeedUp 메소드 재정의
  if self.Turbo:
      self.speed += 50
  else:
      super().speedUp()  #일반 자동차의 가속 메소드</code></pre>
</li>
<li>speedUp() 함수는 부모 클래스에 이미 정의되어 있지만, 자식에서 내용을 변경해 다시 <strong>재정의(overriding)</strong>하였다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[EC2 - RDS 연동 gunicorn 배포]]></title>
            <link>https://velog.io/@daydream_03/EC2-RDS-%EC%97%B0%EB%8F%99-gunicorn-%EB%B0%B0%ED%8F%AC</link>
            <guid>https://velog.io/@daydream_03/EC2-RDS-%EC%97%B0%EB%8F%99-gunicorn-%EB%B0%B0%ED%8F%AC</guid>
            <pubDate>Wed, 26 Jan 2022 10:35:03 GMT</pubDate>
            <description><![CDATA[<ul>
<li>터미널에서 pem 파일이 있는 디렉토리로 이동<ul>
<li>ssh -i <code>pem파일명.pem</code> ubuntu@<code>ec2 ip주소</code></li>
</ul>
</li>
<li>개발환경 설정하기(왜냐? 우분투 환경이므로)<ul>
<li>우분투-리눅스형 미니콘다 설치 : wget <code>링크주소</code></li>
<li>실행권한 주기 : chmod +x Miniconda3-latest-Linux-x86_64.sh(파일명은 ls로 확인)</li>
<li>미니콘다 실행 : ./Miniconda3-latest-Linux-x86_64.sh</li>
<li>모두 다 yes</li>
<li>bash 쉘 스크립트 설정 : source .bashrc</li>
<li>패키지 업그레이드 : sudo apt-get update, sudo apt-get upgrade</li>
<li>gcc 설치(MySQL 설치 간 오류 예방) : sudo apt-get install gcc</li>
<li>MySQL 설치 : sudo apt-get install libmysqlclient-dev</li>
</ul>
</li>
<li>가상환경 생성<ul>
<li>conda create -n project python=3.7</li>
<li>conda activate project</li>
<li>git clone <code>깃헙 repository 주소</code></li>
<li>requirement.txt 확인 : cat requirements.txt</li>
<li>필수 프로그램 일괄 설치 : pip install -r requirements.txt</li>
</ul>
</li>
<li>퍼블릭 IP 확인하기<ul>
<li>AWS EC2에 들어가 IPv4 퍼블릭 IP 확인</li>
<li>settings.py<ul>
<li>ALLOWED_HOSTS 에 퍼블릭 IP 추가(&#39;*&#39;, &#39;<code>퍼블릭 IP</code>&#39;, &#39;<code>퍼블릭 IP:8000</code>&#39;)<ul>
<li>my_settings.py 생성 : vi my settings.py</li>
</ul>
</li>
</ul>
</li>
<li>DATABASES, SECRET_KEY 설정</li>
<li>DATABASES 내의 &#39;HOST&#39;는 RDS 엔드포인트, &#39;NAME&#39;, &#39;PASSWORD&#39; 모두 RDS 관련 내용이 들어간다!</li>
</ul>
</li>
<li>퍼블릭 IP를 이용해 서버 동작시키기<ul>
<li>python maanage.py runserver 0:8000</li>
</ul>
</li>
</ul>
<p>** 중요 ** 장고의 manage.py runserver 명령어는 단일 쓰레드로 동작하여 개발및 테스트로는 적당하다.
<strong>그러나</strong> request가 많은 운영환경에서는 적합하지 않으므로 멀티 스레드를 지원하는 <strong>gunicorn</strong>을 사용한다</p>
<h2 id="wasweb-application-server-gunicorn">WAS(Web Application Server) gunicorn</h2>
<p>장고의 웹 애플리케이션을 돌려주는 역할</p>
<p>설치하기</p>
<ul>
<li>pip install gunicorn</li>
</ul>
<p>서버 가동하기</p>
<ul>
<li>nohup gunicorn --bind=0.0.0.0:8000 <code>app이름</code>.wsgi &amp;<ul>
<li>ssh 세션이 끊어져도 서버를 동작시키기 위해 nohup 커맨드를 사용</li>
</ul>
</li>
<li>ps -ef | grep python<ul>
<li>서버가 백그라운드에서 동작하고 있는지 확인하는 명령어. <strong>pid를 확인 가능하다</strong><ul>
<li>kill <code>pid</code></li>
<li>EC2에서 계속 동작하고 있는 서버를 종료시키는 명령어</li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS: RDS]]></title>
            <link>https://velog.io/@daydream_03/AWS-RDS</link>
            <guid>https://velog.io/@daydream_03/AWS-RDS</guid>
            <pubDate>Wed, 26 Jan 2022 10:05:48 GMT</pubDate>
            <description><![CDATA[<p>파라미터 그룹 생성</p>
<ul>
<li>그룹 패밀리 : mysql5.7 (기획된 버젼에 맞게)</li>
<li>그룹 이름 : 아무거나</li>
<li>설명 : 그냥 설명</li>
</ul>
<p>생성된 파라미터 그룹 선택 후 편집</p>
<ul>
<li>파라미터 필터링 &gt; character_set 검색 &gt; 항목들 값에 utf8mb4 설정<ul>
<li>utf8mb4 는 이모티콘 저장이 가능하다(utf8과의 차이점)</li>
<li>파라미터 필터링  &gt; collate 검색 &gt; collation_connection은 utf8mb4_general_ci, _server는 utf8mb4_unicode_ci로 설정</li>
</ul>
</li>
</ul>
<p>데이터베이스 생성</p>
<ul>
<li><p>표준 생성 &gt; 엔진 옵션: MySQL &gt; 버전은 기본값? &gt; 템플릿: 프리 티어</p>
</li>
<li><p>DB 인스턴스 식별자 : 임의로 생성(ex: test_database)</p>
</li>
<li><p>자격증명 설정: 마스터 사용자 이름(root), 마스터 암호</p>
</li>
<li><p>DB 인스턴스 크기 : 프리티어는 선택권이 없다</p>
</li>
<li><p>스토리지</p>
<ul>
<li>범용, 20GB, 스토리지 자동 조정 활성화 uncheck(20GB 다 차면 자동으로 용량 올려주는 기능)</li>
</ul>
</li>
<li><p>연결 : Default VPC</p>
</li>
<li><p>추가 연결 구성</p>
<ul>
<li>서브넷 그룹 default-vpc-d644bcbc</li>
<li>퍼블릿 액세스 가능 : 예</li>
<li>VPC 보안 그룹 : 새로 생성 &gt; 보안 그룹 이름(test_rules), 가용영역(ap-northeast-2a), 데이터베이스 포트(3306) <ul>
<li>3306는 MySQL의 기본 통신 포트</li>
<li>데이터베이스 인증 &gt; 암호 인증</li>
</ul>
</li>
</ul>
</li>
<li><p>추가 구성</p>
<ul>
<li>초기 데이터베이스 이름(임의)</li>
<li><strong>DB 파라미터 그룹</strong> ( 아까 생성한 거!!!!)</li>
<li>백업 : 자동백업 활성화 uncheck</li>
<li>모니터링 uncheck</li>
<li>삭제 방지 활성화 check</li>
</ul>
</li>
<li><p>생성</p>
</li>
</ul>
<p>데이터베이스</p>
<ul>
<li>보안 그룹 설정<ul>
<li>inbound : 나한테 들어오는 통신(특정 ip로만 DB에 접근 가능하게 설정하는 것)</li>
<li>outbound : 내가 내보내는 통신<ul>
<li>보안그룹 정책 편집</li>
<li>인바운드 규칙 편집 : 무관으로 설정하면 전 세계 어디서든 나의 MySQL root 계정과 비밀번호를 가지고 있으면 접속할 수 있다.</li>
<li>EC2와 RDS 연동 시 EC2 서버의 ip도 등록해줘야 한다!!</li>
</ul>
</li>
</ul>
</li>
<li>엔드포인트</li>
</ul>
<p>터미널</p>
<ul>
<li>mysql -h <code>RDS 엔드포인트</code> -u root -p<ul>
<li>-h는 호스트를 의미</li>
<li>AWS 상의 데이터 베스로 접속</li>
</ul>
</li>
<li>create database gamsung character set utf8mb4 collate utf8mb4_general_ci;<ul>
<li>gamsung 이라는 DB 생성</li>
</ul>
</li>
<li>RDS 종료(exit)</li>
<li>mysqldump -u root -p gamsung &gt; gamsung.sql<ul>
<li>gamsung이라는 DB의 데이터를 gamsung.sql이라는 파일로 dump 뜬 것</li>
</ul>
</li>
<li>mysqldump -h <code>RDS 엔드포인트</code> -u root -p siren &lt; siren.sql<ul>
<li>이전 단계에서 dump한 데이터를 AWS RDS상에 생성된 gamsung이라는 DB에 밀어넣은 것</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조(Python)]]></title>
            <link>https://velog.io/@daydream_03/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%9A%A9%EC%96%B4%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@daydream_03/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%9A%A9%EC%96%B4%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 26 Jan 2022 08:26:56 GMT</pubDate>
            <description><![CDATA[<h2 id="자료형-리터럴-변수">자료형, 리터럴, 변수</h2>
<h3 id="✔️-식별자">✔️ 식별자</h3>
<blockquote>
<p>어떤 대상을 유일하게 구별할 수 있는 이름을 지칭</p>
</blockquote>
<ul>
<li>캐멀 케이스 : 대문자로 시작 → ** 클래스 **</li>
<li>스네이크 케이스 : 소문자로 시작 → ** 함수 *<em>(괄호 x), *</em> 변수 **(괄호 o)</li>
</ul>
<h3 id="✔️-리터럴literal과-자료형data-type">✔️ 리터럴(literal)과 자료형(data type)</h3>
<blockquote>
<p><strong>리터럴</strong>: &#39;asdf&#39;와 같이 문자열 그 자체가 값을 나타내는 것을 의미
<strong>자료형</strong>: 리터럴의 형태를 의미</p>
</blockquote>
<h3 id="✔️-변수">✔️ 변수</h3>
<blockquote>
<p>데이터를 담는 공간
C 언어는 <code>int number</code>와 같이 사전에 변수를 선언하고 메모리 공간을 확보 후 사용한다
<strong>그러나</strong> 파이썬에서는 <code>number=132</code>에서 변수 number가 생성되고, 그 변수가 리터럴 132에 의해 만들어진 정수(int) 객체를 참조하는 형식이다</p>
</blockquote>
<h2 id="입출력-함수">입출력 함수</h2>
<h3 id="✔️-input">✔️ input()</h3>
<blockquote>
<p>input() 함수는 항상 결과가 ** 문자열 **이다.</p>
</blockquote>
<h3 id="✔️-print">✔️ print()</h3>
<blockquote>
<p>print 함수는 호출 때마다 <strong>라인피드(line feed)</strong>가 발생한다.
이를 방지하려면 <strong>키워드 인수</strong>인 <code>end=&quot; &quot;</code>를 뒤에 붙여주면 된다. 예) <code>print(&quot;hello&quot;, end=&quot; &quot;)</code></p>
</blockquote>
<h2 id="컬렉션-자료형">컬렉션 자료형</h2>
<h3 id="✔️-문자열">✔️ 문자열</h3>
<blockquote>
<ul>
<li>두 개의 문자열을 + 연산자를 써서 연결할 수 있다</li>
</ul>
</blockquote>
<ul>
<li>문자열의 각 문자들을 인덱스 연산자로 접근할 수 있다</li>
<li>문자열에 %를 사용해 포맷된 문자열을 만들 수 있다<ul>
<li>예)<code>msg = &quot;취미=%s, 나이=%d, 학점=%f&quot; % (hobby, age, score)</code></li>
</ul>
</li>
<li>참고할 만한 메소드<ul>
<li><code>s.strip([chars\])</code> 공백이나 선택된 문자 chars를 문자열에서 제거</li>
<li><code>s.split([separator], [chars])</code> 공백이나 separator로 주어진 문자로 문자열을 분리함. 문자열의 리스트를 반환함</li>
</ul>
</li>
</ul>
<h3 id="✔️-리스트">✔️ 리스트</h3>
<blockquote>
<ul>
<li>리스트의 메소드</li>
</ul>
</blockquote>
<ul>
<li>a.append(item)</li>
<li>a.extend(b)</li>
<li>a.count(item)</li>
<li>a.index(item, [시작], [종료]) → 리스트에서 항목 item을 찾아 가장 작은 인덱스를 반환. 탐색의 시작/종료 위치 지정도 가능함.</li>
<li>a.insert(position, item) </li>
<li>a.pop(position)</li>
<li>a.remove(item)</li>
<li>a.reverse()</li>
<li>a.sort([key], [reverse]) → 항목을 정렬</li>
</ul>
<h3 id="✔️-튜플">✔️ 튜플</h3>
<blockquote>
<ul>
<li>리스트와 동일하지만, 크기나 값을 <strong>변경할 수 없다</strong></li>
</ul>
</blockquote>
<ul>
<li>따라서 메모리 측면에서 <strong>효율적</strong>이다</li>
</ul>
<h3 id="✔️-딕셔너리">✔️ 딕셔너리</h3>
<blockquote>
<ul>
<li>map 이라는 사전에 항목 추가하기</li>
</ul>
</blockquote>
<ul>
<li><p>map[&#39;key&#39;] = &#39;value&#39;</p>
</li>
<li><p>map.update({&#39;key1&#39; : &#39;value1&#39;, &#39;key2&#39; : &#39;value2&#39;})</p>
<ul>
<li>in 연산자로 사전 검사하기</li>
<li>print(&#39;key&#39; in map) </li>
<li>in 연산자는 리스트, 튜플에서 <strong>순차탐색</strong>을 이용하지만, 딕셔너리에서는 <strong>해싱</strong>을 참조한다</li>
</ul>
<h3 id="✔️-집합set">✔️ 집합(set)</h3>
<blockquote>
<ul>
<li>리스트와의 차이점</li>
</ul>
</blockquote>
<ul>
<li>원소 중복 허용 x</li>
<li>순서가 없다</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조와 알고리즘]]></title>
            <link>https://velog.io/@daydream_03/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
            <guid>https://velog.io/@daydream_03/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%EC%99%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</guid>
            <pubDate>Wed, 26 Jan 2022 05:17:56 GMT</pubDate>
            <description><![CDATA[<h3 id="✓-자료구조">✓ <strong>자료구조</strong></h3>
<blockquote>
<p>자료들을 정리하고 조직화하는 구조를 지칭</p>
</blockquote>
<ul>
<li>단순 자료구조</li>
<li>복합 자료구조(ex: 컨테이너)<ul>
<li>선형(linear) 자료구조 : 항목들을 ** 순서적 **으로 나열하여 저장
ex: 스택, 큐, 덱, 리스트<ul>
<li>비선형(non-linear) 자료구조 : 트리(계층 구조), 힙(우선순위 큐), 이진 탐색트리 &amp; AVL트리(탐색), 그래프(복잡한 연결관계 표현)
<img src="https://images.velog.io/images/daydream_03/post/9e746537-6ad6-4ebd-b775-dd13da41d211/image.png" alt=""></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="✓-알고리즘">✓ <strong>알고리즘</strong></h3>
<blockquote>
<p>문제를 해결하는 절차</p>
</blockquote>
<ul>
<li>알고리즘 기술 방법<ul>
<li>자연어(영어, 한국어) : 편리, 의미가 애매</li>
<li>** 흐름도(flow chart) ** : 알고리즘이 복잡하면 보기 어려움</li>
<li>** 유사 코드(pseudo-code) ** : 자연어보단 체계적, 프로그래밍 언어보단 덜 엄격함</li>
<li>프로그래밍 언어(C, Java, Python)</li>
</ul>
</li>
</ul>
<h3 id="✓-추상-자료형abstract-data-type-adt">✓ 추상 자료형(Abstract Data Type, ADT)</h3>
<blockquote>
<p>추상적으로 정의한 자료형</p>
</blockquote>
<ul>
<li>어떤 <strong>자료들</strong>과 자료에 가해지는 <strong>연산</strong>들을 구체적으로 표시<ul>
<li>데이터: 가방(Bag)</li>
<li>연산: insert(), remove(), contains(), count(), etc...<ul>
<li>ADT는 구현에 관한 세부사항을 감추고 사용자에게 간단한 <strong>인터페이스</strong>만 제공 
⚡️ Why? 사용자는 굳이 내부를 뜯어보고 구현원리를 알 필요가 X
→ <strong>정보은닉</strong>의 기본 개념    </li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Barracks 중간 발표]]></title>
            <link>https://velog.io/@daydream_03/Barracks-%EC%A4%91%EA%B0%84-%EB%B0%9C%ED%91%9C</link>
            <guid>https://velog.io/@daydream_03/Barracks-%EC%A4%91%EA%B0%84-%EB%B0%9C%ED%91%9C</guid>
            <pubDate>Sun, 16 Jan 2022 14:40:37 GMT</pubDate>
            <description><![CDATA[<h2 id="meeting">Meeting</h2>
<h3 id="1-sprint">1. Sprint</h3>
<ul>
<li><p>오늘의 집 커뮤니티에 중점을 두고 계획</p>
</li>
<li><p>백엔드 필수 구현사항</p>
<ul>
<li><strong>소셜 로그인</strong></li>
<li>커뮤니티(POST)</li>
<li>커뮤니티(GET)<h3 id="2-daily-standup">2. Daily Standup</h3>
<img src="https://images.velog.io/images/daydream_03/post/1d15d40e-9c8b-4664-bf93-44cdb0fca402/image.png" alt=""><h3 id="3-retrospective">3. Retrospective</h3>
</li>
</ul>
</li>
<li><p>한 주간 진행/완료사항 공유</p>
</li>
<li><p>Blocker 발생 시 적극적인 공유로 일정 조율을 통해 유연하게 대처</p>
</li>
<li><p>차주 진행계획 공유</p>
</li>
</ul>
<h2 id="trello">Trello</h2>
<p><img src="https://images.velog.io/images/daydream_03/post/29c2afb5-4ff5-439c-bb11-2e8b79884ef5/image.png" alt=""></p>
<h2 id="blocker">Blocker</h2>
<ul>
<li>AWS S3 작업 간 IAM유저에게 발급되는 Secret Access Key에 문제가 있어 문제를 해결하기까지 이틀 가량 소요</li>
<li>git rebase 과정 중에 VSCode 상에서 표시되는 변경내용을 잘못 덮어씌워 브랜치 초기화하여 해결</li>
</ul>
<h2 id="잘한-점">잘한 점</h2>
<ul>
<li>프론트-백 사이 원활한 소통을 위해 쉬운 단어들 위주로 알기 쉽게 풀어 설명하며 소통한 점</li>
<li>기획 단계부터 프론트와 백 모두 충분한 상의를 거쳐 합의점을 도출한 것 + Figma와 같은 별도의 툴을 사용해 해당 내용을 가시화한 것</li>
<li>기능정의서를 통해 구현해야할 분야와 기능을 계층으로 분리하여 한 눈에 알아볼 수 있게 한 것
<img src="https://images.velog.io/images/daydream_03/post/024d0b03-c238-4ce8-b509-87195e96ffe9/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[SignatureDoesNotMatch 오류 해결방법]]></title>
            <link>https://velog.io/@daydream_03/SignatureDoesNotMatch-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0%ED%95%9C-%EC%8D%B0</link>
            <guid>https://velog.io/@daydream_03/SignatureDoesNotMatch-%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0%ED%95%9C-%EC%8D%B0</guid>
            <pubDate>Sun, 16 Jan 2022 12:50:51 GMT</pubDate>
            <description><![CDATA[<h3 id="현상">현상</h3>
<p>이번 프로젝트에서 맡게된 역할 중 AWS S3 스토리지를 생성 및 액세스하려는 과정 중에 겪은 오류이다.
공식 문서대로 모든 것을 세팅하고 이미지를 업로드하려고 보니 SignatureDoesNotMatch 오류를 만났다.
<img src="https://images.velog.io/images/daydream_03/post/7e8a2882-98dd-4f1d-96c2-9bbd92747d06/image.png" alt=""></p>
<p>이 오류로 인해 프로젝트 개발기간 중 하루+@를 온전히 troubleshooting으로 날리게 되는데....</p>
<h3 id="원인">원인</h3>
<p>문제의 원인은 정말 황당하게도 AWS S3를 사용하기 위해 등록한 IAM 사용자에게 AWS가 발급해주는 Secret Access Key에 있었다.
AWS에서 IAM유저를 생성하면 발급해주는 Secret Access Key에 &#39;/&#39;나 &#39;%&#39;와 같은 특수문자가 들어있을 경우에 해당 오류가 발생한다는 것이다.
<img src="https://images.velog.io/images/daydream_03/post/4b3fcf92-cd3f-4e0c-8402-36317db3bba3/image.png" alt="">AWS에 등록한 유저에게 AWS가 발급해주는 키에 문제가 있다니 정말 상상도 못했다..</p>
<h3 id="해결책">해결책</h3>
<p>해결책은 간단하다. 그냥 IAM유저를 계속 만들어내면 된다. 언제까지? Secret Access Key에 특수문자가 없을 때까지 ㅎㅎ <img src="https://images.velog.io/images/daydream_03/post/45126b76-47f8-4b99-9e1b-2e42cda347e8/image.png" alt=""></p>
<h3 id="마치며">마치며...</h3>
<p>이번 에러는 가뜩이나 촉박한 프로젝트 개발 일정 중 나로 하여금 가장 오랜 기간동안 블로커로 작용했다. 하나 둘 결과물을 만들어내는 팀원들을 보며 조바심이 들기 시작했고, 결국 쫓기듯이 디버깅을 하기 시작했다.</p>
<p>그럼에도 문제를 해결할 수 없었던 이유는 코드의 어느 한 부분을 고쳤을 때 또다른 에러를 마주하게 될 경우, 새롭게 발생하는 에러를 해결하는 쪽으로 깊게 파고들지 못하고 다시 원점으로 회귀해 코드의 다른 부분을 수정하는 방향으로 나아갔기 때문이었다. 무릇 개발자란 에러를 두려워하지 않고 경우에 따라선 깊이 탐색하는 능력 또한 요구된다고 느꼈다.</p>
<p>아울러 이틀 넘게 그저 내 코드에게 문제가 있을거라 생각하며 애꿎은 코드만 뜯어고치고 있던 내게 함께 둘러앉아 문제의 원인과 그 해결책까지 찾아준 동기 아영님과 그 해결법을 기록해둔 인터넷 어느 한 블로그의 이름모를 주인분께 압도적 감사와 무한한 존경을 보냅니다...</p>
<blockquote>
<p><strong>Reference</strong>
<a href="https://lynlab.co.kr/blog/52">https://lynlab.co.kr/blog/52</a></p>
</blockquote>
<p><img src="https://images.velog.io/images/daydream_03/post/0cdebce2-24ce-45bb-82f5-d3eeddef4e9d/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Software Testing]]></title>
            <link>https://velog.io/@daydream_03/Software-Testing</link>
            <guid>https://velog.io/@daydream_03/Software-Testing</guid>
            <pubDate>Sun, 16 Jan 2022 12:09:12 GMT</pubDate>
            <description><![CDATA[<h2 id="software-testing이란">Software Testing이란?</h2>
<p>코드를 작성 후 기대하는 결과에 도달하는지 혹은 그렇지 못하는지 확인하는 절차
<img src="https://images.velog.io/images/daydream_03/post/fa875989-839e-4dab-89a7-10640c0a49e2/image.png" alt=""></p>
<p>Build product <strong>Right</strong> vs Build <strong>Right</strong> product</p>
<h2 id="why-bother-to-test">Why Bother to Test?</h2>
<ul>
<li>결함의 식별 및 사전 방지를 통한 시간 절약</li>
<li>테스트 중 얻은 인사이트를 바탕으로 구조 및 품질 개선</li>
<li>확장성을 고려한 개발이 가능</li>
</ul>
<h3 id="manual-testing">Manual Testing</h3>
<p>사람이 직접 테스트하는 방식</p>
<ul>
<li>불안정성이 항상 존재</li>
<li>인력소모와 비용이 크다</li>
<li><strong>테스트 속도</strong>가 느리다</li>
</ul>
<h3 id="automation-testing">Automation Testing</h3>
<p>자동화 방식</p>
<ul>
<li>안정성 향상</li>
<li>인력을 감축하고 비용이 감소한다</li>
<li>테스트 속도가 빠르다</li>
<li>확장성이 높다</li>
</ul>
<h2 id="시스템-테스트-전략-3가지">시스템 테스트 전략 3가지</h2>
<h4 id="end-to-ende2e-tests">End-to-End(E2E) Tests</h4>
<p>전체적인 Flow(ex. 브라우저 상 클릭 후 생기는 변화에 대한 검증)</p>
<h4 id="integration-tests통합-테스트">Integration Tests(통합 테스트)</h4>
<p>모듈 간의 호환성 검증(ex. 웹페이지 혹은 Postman을 통한 API 호출 시 올바르게 동작하는지 확인)</p>
<h4 id="unit-tests단위-테스트">Unit Tests(단위 테스트)</h4>
<p>독립적으로 진행되는 가장 작은 단위의 테스트(ex. 하나의 기능 또는 메소드)</p>
<ul>
<li>테스트의 복잡도는 단위 &gt; 통합 &gt; E2E 순으로 증가한다</li>
<li>구글에서 제안하는 단위, 통합, E2E 테스트의 비율은 각각 7:2:1이다</li>
</ul>
<h4 id="단위-테스트-작성의-필요성">단위 테스트 작성의 필요성</h4>
<ul>
<li>문제를 빠르게 파악할 수 있다</li>
<li>시간과 비용 절감</li>
<li>리팩토링 시 안정성 확보
(테스트 코드만 봐도 코드의 목적과 용도를 알 수 있다)</li>
<li>코드에 대한 문서로 활용</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Django ORM 최적화]]></title>
            <link>https://velog.io/@daydream_03/Django-ORM-%EC%B5%9C%EC%A0%81%ED%99%94</link>
            <guid>https://velog.io/@daydream_03/Django-ORM-%EC%B5%9C%EC%A0%81%ED%99%94</guid>
            <pubDate>Sun, 16 Jan 2022 12:08:53 GMT</pubDate>
            <description><![CDATA[<p>QuerySet API의 특징과 동작원리
API가 부하를 받았을 때성능을 향상시키는 방법</p>
<p>select_related, prefetch_related로 N+1 문제를 해결</p>
<h3 id="lazy-loading지연-로딩">Lazy Loading(지연 로딩)</h3>
<p>프로그래밍 전반적으로 있는 개념(장고에만 있지 않음)
함수를 호출했다고 해서 바로 응답하는 것이 아닌, 필요한 때에 값을 리턴해 줌</p>
<p>queryset = Publisher.objects.all()
all 함수를 실행해도 쿼리를 호출하지 않는다.
실제로 queryset은 query라는 속성 안에 SQL문을 저장해놓는다.</p>
<p>queryset2 = queryset.exclude(id=2).annotate(count=Count(&#39;book&#39;))
queryset2도 마찬가지로 queryset에 계속 chainning하여 SQL문을 저장한다.</p>
<p>실제로 db를 호출하는 시점은
slicing, iteration, repr(), len(), list(), book()... 등을 사용했을 때이다</p>
<p>원하는 색깔을 얻기 위해 파레트에 주어진 물감을 섞어두었다가 도화지에 칠하는 느낌..?</p>
<h3 id="caching캐싱">Caching(캐싱)</h3>
<p>list(queryset2)
queryset2[0]
queryset2[0]
queryset2[0]
의 코드는 사실 db를 1번만 호출한다</p>
<p>why? 장고의 내부적 기능인 &quot;캐싱&quot;이기 때문</p>
<p>for문을 돌리고 난 뒤에는 장고가 db를 호출하면서 _result_cache에 저장해서 그 결과를 활용하는 것을 볼 수 있다.
추가로 len(), list() 등등의 경우처럼 쿼리셋이 평가될 때 캐싱을 활용할 수 있다.</p>
<p>반대로
queryset2[0]
queryset2[0]
queryset2[0]
list(queryset2)
위의 코드는 db를 4번 호출한다</p>
<h3 id="select_related">Select_Related</h3>
<h4 id="n1-problems정참조">N+1 Problems(정참조)</h4>
<p>queryset=Book.objects.all()
books =[]
for book in queryset:
books.append({
    &#39;id&#39;: book.id,
    &#39;name&#39;: book.name,
    &#39;publisher&#39;: book.publisher.name
})</p>
<h4 id="해결방법">해결방법</h4>
<p>queryset = Book.objects.all().select_related(&quot;publisher&quot;)
books = []
for book in queryset:</p>
<p>정참조 관계에 있는 데이터는 select_related를 활용하자</p>
<h3 id="prefetch_related">Prefetch_Related</h3>
<h4 id="n1-problems역참조">N+1 Problems(역참조)</h4>
<p>queryset=Store.objects.all()
stores =[]
for store in queryset:
stores.append({
    &#39;id&#39;: store.id,
    &#39;name&#39;: store.name,
    &#39;books&#39;: book
})</p>
<h4 id="해결방법-1">해결방법</h4>
<p>queryset = Store.objects.all().prefetch_related(&quot;books&quot;)</p>
]]></description>
        </item>
    </channel>
</rss>