<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hanjoon_10.log</title>
        <link>https://velog.io/</link>
        <description>:)</description>
        <lastBuildDate>Tue, 02 Nov 2021 03:40:29 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hanjoon_10.log</title>
            <url>https://images.velog.io/images/hanjoon_10/profile/1f0346de-09ea-4f35-8a81-de619eb939e8/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hanjoon_10.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hanjoon_10" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[SQL - Join]]></title>
            <link>https://velog.io/@hanjoon_10/SQL-Join</link>
            <guid>https://velog.io/@hanjoon_10/SQL-Join</guid>
            <pubDate>Tue, 02 Nov 2021 03:40:29 GMT</pubDate>
            <description><![CDATA[<h2 id="🚀-join">🚀 Join</h2>
<ul>
<li>공통된 column을 기준으로 여러 테이블을 합친다.</li>
</ul>
<p><img src="https://images.velog.io/images/hanjoon_10/post/8b056dc3-f557-45de-ad35-3831b92d420f/Join.png" alt=""></p>
<h2 id="🚀-inner-join">🚀 Inner Join</h2>
<ul>
<li>교집합<pre><code>SELECT * FROM 기준테이블
INNER JOIN 붙일테이블 ON join_기준열</code></pre><img src="https://blog.kakaocdn.net/dn/rRTnM/btqKkOBMnJd/O41imfeKal1yYVST0kt6l0/img.png" alt=""></li>
</ul>
<h2 id="🚀-left-join">🚀 Left Join</h2>
<ul>
<li>왼쪽 데이터를 기준으로 붙이기<pre><code>SELECT * FROM 기준테이블
LEFT JOIN 붙일테이블 ON join_기준열</code></pre><img src="https://blog.kakaocdn.net/dn/cZ8WIC/btqKlVACPVE/z5dKCH0UqrklKVg6njt41K/img.png" alt=""></li>
</ul>
<h2 id="🚀-right-join">🚀 Right Join</h2>
<ul>
<li>오른쪽 데이터를 기준으로 붙이기<pre><code>SELECT * FROM 기준테이블
RIGHT JOIN 붙일테이블 ON join_기준열</code></pre><img src="https://blog.kakaocdn.net/dn/zzUK1/btqKgENIXIM/oPZr0mhgIiAY1dZr8COh1k/img.png" alt=""><h2 id="🚀-outer-join">🚀 Outer Join</h2>
</li>
<li>데이터가 없는 부분은 null로 가져온다.</li>
<li>FULL OUTER JOIN : 전체 합치기</li>
<li>LEFT OUTER JOIN = LEFT JOIN</li>
<li>RIGHT OUTER JOIN = RIGHT JOIN<pre><code>SELECT * FROM 기준테이블
OUTER JOIN 붙일테이블 ON join_기준열</code></pre><img src="https://blog.kakaocdn.net/dn/Pjgmq/btqKmo3G8bK/CRoYG5IjNTAi6TcIti4QL0/img.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Program & Process & Thread]]></title>
            <link>https://velog.io/@hanjoon_10/Program-Process-Thread</link>
            <guid>https://velog.io/@hanjoon_10/Program-Process-Thread</guid>
            <pubDate>Thu, 21 Oct 2021 10:35:54 GMT</pubDate>
            <description><![CDATA[<h2 id="🚀-program--process--thread">🚀 Program &amp; Process &amp; Thread</h2>
<h4 id="🔥-프로그램--파일-시스템에-존재하는-실행파일-정적인-개념으로-컴터에-저장된-실행파일들을-지칭">🔥 프로그램 – 파일 시스템에 존재하는 실행파일, 정적인 개념으로 컴터에 저장된 실행파일들을 지칭</h4>
<h4 id="🔥-프로세스--메모리에-올라와-실행되고-있는-프로그램의-인스턴스-동적인-개념으로-실행된-프로그램을-지칭">🔥 프로세스 – 메모리에 올라와 실행되고 있는 프로그램의 인스턴스, 동적인 개념으로 실행된 프로그램을 지칭</h4>
<h4 id="🔥-쓰레드--프로세스-내에서-할당-받은-자원을-이용해-동작하는-실행-단위">🔥 쓰레드 – 프로세스 내에서 할당 받은 자원을 이용해 동작하는 실행 단위</h4>
<h4 id="📍-프로세스-vs-쓰레드">📍 프로세스 vs. 쓰레드</h4>
<p><strong>프로세스</strong></p>
<ul>
<li>운영체제로부터 독립된 메모리 영역을 할당 받는다.</li>
<li>프로세스들은 독립적이기 때문에 통신하기 위해 IPC를 사용</li>
<li>최소 1개의 쓰레드를 갖고 있다.</li>
</ul>
<p><strong>쓰레드</strong></p>
<ul>
<li>프로세스 내에서 Stack만 따로 할당 받고 Code, Data, Heap 영역은 공유</li>
<li>프로세스의 자원을 공유하기 때문에 다른 쓰레드에 의한 결과를 즉시 확인 할 수 있다.</li>
<li>프로세스 내에 존재하며 프로세스가 할당받은 자원을 이용해 실행된다.</li>
</ul>
<h4 id="📍-멀티-프로세스-vs-멀티-쓰레드">📍 멀티 프로세스 vs. 멀티 쓰레드</h4>
<p><strong>멀티 프로세스</strong> – 하나의 프로그램을 여러 개의 프로세스로 구성해서 각 프로세스가 1개의 작업을 처리하도록 하는 것</p>
<ul>
<li>1 개의 프로세스가 죽어도 자식 프로세스 이외의 다른 프로세스들은 계속 실행</li>
<li>Context Switching을 위한 오버헤드(캐시 초기화, 인터럽)가 발생</li>
<li>프로세스가 각각 독립적인 메모리를 할당 받았기 때문에 통신하는 것이 어렵</li>
</ul>
<p><strong>멀티 쓰레드</strong> – 하나의 프로그램을 여러 개의 쓰레드로 구성해서 각 쓰레드가 1 개의 작업을 처리하도록 하는 것</p>
<ul>
<li>프로세스를 위해 자원을 할당하는 시스템콜이나 Context Switching의 오버헤드를 줄일 수 있다.</li>
<li>쓰레드는 메모리를 공유하기 때문에, 통신이 쉽고 자원을 효율적으로 사용할 수 있다.</li>
<li>하나의 쓰레드에 문제가 생기면 전체 프로세스가 영향을 받는다.</li>
<li>여러 쓰레드가 하나의 자원에 동시에 접근하는 경우 동기화 문제가 발생할 수 있다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Combinations vs. permutations vs. product]]></title>
            <link>https://velog.io/@hanjoon_10/Combinations-vs.-permutations-vs.-product</link>
            <guid>https://velog.io/@hanjoon_10/Combinations-vs.-permutations-vs.-product</guid>
            <pubDate>Tue, 12 Oct 2021 02:24:49 GMT</pubDate>
            <description><![CDATA[<h2 id="🚀-리스트의-모든-조합-구하기">🚀 리스트의 모든 조합 구하기</h2>
<h3 id="🔥-product">🔥 product</h3>
<p>📍 두 개 이상의 리스트에서 모든 조합을 계산해야 한다면, product를 사용</p>
<pre><code>from itertools import product
items = [[&#39;a&#39;, &#39;b&#39;, &#39;c,&#39;], [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;], [&#39;!&#39;, &#39;@&#39;, &#39;#&#39;]]
list(product(*items))
# [(&#39;a&#39;, &#39;1&#39;, &#39;!&#39;), (&#39;a&#39;, &#39;1&#39;, &#39;@&#39;), (&#39;a&#39;, &#39;1&#39;, &#39;#&#39;), (&#39;a&#39;, &#39;2&#39;, &#39;!&#39;), (&#39;a&#39;, &#39;2&#39;, &#39;@&#39;), (&#39;a&#39;, &#39;2&#39;, &#39;#&#39;), (&#39;a&#39;, &#39;3&#39;, &#39;!&#39;), (&#39;a&#39;, &#39;3&#39;, &#39;@&#39;), (&#39;a&#39;, &#39;3&#39;, &#39;#&#39;), (&#39;a&#39;, &#39;4&#39;, &#39;!&#39;), (&#39;a&#39;, &#39;4&#39;, &#39;@&#39;), (&#39;a&#39;, &#39;4&#39;, &#39;#&#39;), (&#39;b&#39;, &#39;1&#39;, &#39;!&#39;), (&#39;b&#39;, &#39;1&#39;, &#39;@&#39;), (&#39;b&#39;, &#39;1&#39;, &#39;#&#39;), (&#39;b&#39;, &#39;2&#39;, &#39;!&#39;), (&#39;b&#39;, &#39;2&#39;, &#39;@&#39;), (&#39;b&#39;, &#39;2&#39;, &#39;#&#39;), (&#39;b&#39;, &#39;3&#39;, &#39;!&#39;), (&#39;b&#39;, &#39;3&#39;, &#39;@&#39;), (&#39;b&#39;, &#39;3&#39;, &#39;#&#39;), (&#39;b&#39;, &#39;4&#39;, &#39;!&#39;), (&#39;b&#39;, &#39;4&#39;, &#39;@&#39;), (&#39;b&#39;, &#39;4&#39;, &#39;#&#39;), (&#39;c,&#39;, &#39;1&#39;, &#39;!&#39;), (&#39;c,&#39;, &#39;1&#39;, &#39;@&#39;), (&#39;c,&#39;, &#39;1&#39;, &#39;#&#39;), (&#39;c,&#39;, &#39;2&#39;, &#39;!&#39;), (&#39;c,&#39;, &#39;2&#39;, &#39;@&#39;), (&#39;c,&#39;, &#39;2&#39;, &#39;#&#39;), (&#39;c,&#39;, &#39;3&#39;, &#39;!&#39;), (&#39;c,&#39;, &#39;3&#39;, &#39;@&#39;), (&#39;c,&#39;, &#39;3&#39;, &#39;#&#39;), (&#39;c,&#39;, &#39;4&#39;, &#39;!&#39;), (&#39;c,&#39;, &#39;4&#39;, &#39;@&#39;), (&#39;c,&#39;, &#39;4&#39;, &#39;#&#39;)]

</code></pre><h3 id="🔥-permutations">🔥 permutations</h3>
<p>📍 하나의 리스트에서 모든 조합을 계산해야 한다면, permuations를 사용</p>
<pre><code>items = [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;]

from itertools import permutations
list(permutations(items, 2))
# [(&#39;1&#39;, &#39;2&#39;), (&#39;1&#39;, &#39;3&#39;), (&#39;1&#39;, &#39;4&#39;), (&#39;1&#39;, &#39;5&#39;), (&#39;2&#39;, &#39;1&#39;), (&#39;2&#39;, &#39;3&#39;), (&#39;2&#39;, &#39;4&#39;), (&#39;2&#39;, &#39;5&#39;), (&#39;3&#39;, &#39;1&#39;), (&#39;3&#39;, &#39;2&#39;), (&#39;3&#39;, &#39;4&#39;), (&#39;3&#39;, &#39;5&#39;), (&#39;4&#39;, &#39;1&#39;), (&#39;4&#39;, &#39;2&#39;), (&#39;4&#39;, &#39;3&#39;), (&#39;4&#39;, &#39;5&#39;), (&#39;5&#39;, &#39;1&#39;), (&#39;5&#39;, &#39;2&#39;), (&#39;5&#39;, &#39;3&#39;), (&#39;5&#39;, &#39;4&#39;)]</code></pre><h3 id="🔥-combinations">🔥 combinations</h3>
<p>📍 하나의 리스트에서 모든 조합을 계산해야 한다면, combinations을 사용</p>
<pre><code>items = [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;]

from itertools import combinations
list(combinations(items, 2))
# [(&#39;1&#39;, &#39;2&#39;), (&#39;1&#39;, &#39;3&#39;), (&#39;1&#39;, &#39;4&#39;), (&#39;1&#39;, &#39;5&#39;), (&#39;2&#39;, &#39;3&#39;), (&#39;2&#39;, &#39;4&#39;), (&#39;2&#39;, &#39;5&#39;), (&#39;3&#39;, &#39;4&#39;), (&#39;3&#39;, &#39;5&#39;), (&#39;4&#39;, &#39;5&#39;)]</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[Django Method]]></title>
            <link>https://velog.io/@hanjoon_10/Django-Method</link>
            <guid>https://velog.io/@hanjoon_10/Django-Method</guid>
            <pubDate>Fri, 08 Oct 2021 03:51:42 GMT</pubDate>
            <description><![CDATA[<h2 id="🚀-자주-쓰는-methods">🚀 자주 쓰는 methods</h2>
<ul>
<li>all()    - 테이블 모든 데이터 셋 가져오기</li>
<li>filter() - 특정 조건에 부합하는 데이터셋 가져오기</li>
<li>exclude() - 특정 조건을 제외한 데이터셋 가져오기</li>
<li>get()- 특정 조건에 부합하는 1개의 데이터 가져오기</li>
<li>count() - 가져올 데이터의 개수 가져오기</li>
<li>first() - 첫번째 데이터 가져오기</li>
<li>last() - 가장 마지막 데이터 가져오기</li>
<li>exists() - 데이터 유무에 대한 결과(True, False)를 가져오기</li>
<li>order_by() - 특정 필드 순서대로 정렬</li>
</ul>
<h2 id="🚀-queryset-api">🚀 QuerySet API</h2>
<h3 id="🔥-methods-that-return-new-querysets">🔥 Methods that return new QuerySets</h3>
<ul>
<li>filter()</li>
<li>exclude()</li>
<li>annotate()</li>
<li>alias()</li>
<li>order_by()</li>
<li>reverse()</li>
<li>distinct()</li>
<li>values()</li>
<li>values_list()</li>
<li>dates()</li>
<li>datetimes()</li>
<li>none()</li>
<li>all()</li>
<li>union()</li>
<li>intersection()</li>
<li>difference()</li>
<li>select_related()</li>
<li>prefetch_related()</li>
<li>extra()</li>
<li>defer()</li>
<li>only()</li>
<li>using()</li>
<li>select_for_update()</li>
<li>raw()<h3 id="🔥-operators-that-return-new-querysets">🔥 Operators that return new QuerySets</h3>
</li>
<li>AND (&amp;)</li>
<li>OR (|)<h3 id="🔥-methods-that-do-not-return-querysets">🔥 Methods that do not return QuerySets</h3>
</li>
<li>get()</li>
<li>create()</li>
<li>get_or_create()</li>
<li>update_or_create()</li>
<li>bulk_create()</li>
<li>bulk_update()</li>
<li>count()</li>
<li>in_bulk()</li>
<li>iterator()<ul>
<li>With server-side cursors</li>
<li>Without server-side cursors</li>
</ul>
</li>
<li>latest()</li>
<li>earliest()</li>
<li>first()</li>
<li>last()</li>
<li>aggregate()</li>
<li>exists()</li>
<li>update()<ul>
<li>Ordered queryset</li>
</ul>
</li>
<li>delete()</li>
<li>as_manager()</li>
<li>explain()<h3 id="🔥-field-lookups">🔥 Field lookups</h3>
</li>
<li>exact</li>
<li>iexact</li>
<li>contains</li>
<li>icontains</li>
<li>in</li>
<li>gt</li>
<li>gte</li>
<li>lt</li>
<li>lte</li>
<li>startswith</li>
<li>istartswith</li>
<li>endswith</li>
<li>iendswith</li>
<li>range</li>
<li>date</li>
<li>year</li>
<li>iso_year</li>
<li>month</li>
<li>day</li>
<li>week</li>
<li>week_day</li>
<li>iso_week_day</li>
<li>quarter</li>
<li>time</li>
<li>hour</li>
<li>minute</li>
<li>second</li>
<li>isnull</li>
<li>regex</li>
<li>iregex<h3 id="🔥-aggregation-functions">🔥 Aggregation functions</h3>
</li>
<li>expressions</li>
<li>output_field</li>
<li>filter</li>
<li>**extra</li>
<li>Avg</li>
<li>Count</li>
<li>Max</li>
<li>Min</li>
<li>StdDev</li>
<li>Sum</li>
<li>Variance</li>
</ul>
<h2 id="🚀-query-related-tools">🚀 Query-related tools</h2>
<ul>
<li>Q() objects</li>
<li>Prefetch() objects</li>
<li>prefetch_related_objects()</li>
<li>FilteredRelation() objects</li>
</ul>
<p>참고: <a href="https://docs.djangoproject.com/en/3.2/ref/models/querysets/">https://docs.djangoproject.com/en/3.2/ref/models/querysets/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[OOP vs. PP]]></title>
            <link>https://velog.io/@hanjoon_10/OOP-vs.-PP</link>
            <guid>https://velog.io/@hanjoon_10/OOP-vs.-PP</guid>
            <pubDate>Wed, 06 Oct 2021 08:32:39 GMT</pubDate>
            <description><![CDATA[<h2 id="🚀-oop">🚀 OOP</h2>
<h3 id="🔥-객체지향object-oriented-programming">🔥 객체지향(Object Oriented Programming)</h3>
<p><strong>정의</strong></p>
<ul>
<li>객체들이 서로 유기적으로 동작하는 프로그래밍 이론</li>
</ul>
<p><strong>특징</strong></p>
<ul>
<li>추상화 : 객체의 공통된 특징을 파악해 정의해 놓은 설계 기법</li>
<li>캡슐화: 외부에 노출할필요 없는 정보는 은닉</li>
<li>상속: 부모클래스가 자식 클래스에게 속성 물려주기</li>
<li>다형성: 같은 형태이지만 다른 기능을 하는것</li>
</ul>
<p><strong>장점</strong></p>
<ul>
<li>코드의 재활용성, 가독성, 디버깅 용이성 높음</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li>절차지향보다 느린 처리속도</li>
<li>설계에 많은 시간소요</li>
</ul>
<p><strong>대표 언어</strong></p>
<ul>
<li>python</li>
<li>javascript</li>
</ul>
<p><strong>5가지 원칙</strong></p>
<ul>
<li>SRP(Single Responsibility Principle) 
단일 책임 원칙: 클래스는 단 하나의 목적을 가져야 하며, 클래스 변경하는 이유는 단 하나의 이유</li>
<li>OCP(Open-Closed Principle) 
개방 폐쇠 원칙: 클래스는 확장에는 열려있고, 변경에는 닫혀있다</li>
<li>LSP(Liskov Substitution Principle) 
리스코프 치환 원칙: 상위 타입의 객체를 하위 타입으로 바꾸어도 프로그램은 일관되게 동작해야 된다</li>
<li>ISP(Interface Segregation Principle) 
인터페이스 분리 원칙: 클라이언트는 이용하지 않는 메소드에 의존하지 않도록 인터페이스를 분리해야 된다</li>
<li>DIP(Dependency Inversion Principle) 
의존 역전 법칙: 클라이언트는 추상화에 의존해야 하며, 구체화에 의존해선 안된다</li>
</ul>
<h2 id="🚀-pp">🚀 PP</h2>
<h3 id="🔥-절차지향procedural-programming">🔥 절차지향(Procedural Programming)</h3>
<p><strong>반대개념</strong></p>
<ul>
<li>절자지향 프로그래밍</li>
</ul>
<p><strong>장점</strong></p>
<ul>
<li>컴퓨터의 처리구조와 유사해 실행속도가 빠름</li>
</ul>
<p><strong>단점</strong></p>
<ul>
<li>실행순서가 정해져있어 코드의 순서가 바뀌면 동일한 결과 보장이 어려움</li>
<li>유지보수와 디버깅이 어려움</li>
</ul>
<p><strong>대표언어</strong></p>
<ul>
<li>c언어</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[NoSQL]]></title>
            <link>https://velog.io/@hanjoon_10/NoSQL</link>
            <guid>https://velog.io/@hanjoon_10/NoSQL</guid>
            <pubDate>Wed, 29 Sep 2021 03:36:23 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-nosql-장단점">🚀 NoSQL 장/단점</h3>
<ul>
<li>NoSQL 장점<ul>
<li>데이터간의 관계를 정의하지 않음 (테이블간의 관계 (join)이 불필요)</li>
<li>RDBMS 보다 복잡도가 떨어져, 훨씬 대용량의 데이터를 저장 관리 할 수 있음</li>
<li>테이블에 스키마가 정해져있지 않아 데이터 자장이 비교적 자유로움</li>
<li>많은양의 데이터를 저장&amp;처리 할 수 있음</li>
</ul>
</li>
<li>NoSQL 단점<ul>
<li>Key값에 대한 입/출력만 지원</li>
<li>스키마가 정해져 있지 않아, 데이터에 대한 규격화가 되어있지 않음</li>
<li>Data를 Update하는데 비교적 느림</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Codekata #3]]></title>
            <link>https://velog.io/@hanjoon_10/Codekata-3</link>
            <guid>https://velog.io/@hanjoon_10/Codekata-3</guid>
            <pubDate>Sun, 25 Jul 2021 14:54:59 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-문제">🚀 문제</h3>
<p>재귀를 사용하여 팩토리얼(factorial)을 구하는 함수를 구현해주세요. 팩토리얼이란 1에서부터 n까지의 정수를 모두 곱한것을 말합니다.</p>
<p>1! = 1 2! = 1 2 5! = 1 2 3 4 * 5</p>
<h3 id="🔥-풀이">🔥 풀이</h3>
<p><img src="https://images.velog.io/images/hanjoon_10/post/4762523f-aeda-4922-9859-5ee415065d46/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-26%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.05.55.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Codekata #2]]></title>
            <link>https://velog.io/@hanjoon_10/Codekata-2</link>
            <guid>https://velog.io/@hanjoon_10/Codekata-2</guid>
            <pubDate>Sun, 25 Jul 2021 14:54:45 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-문제">🚀 문제</h3>
<p>주어진 숫자 배열에서, 0을 배열의 마지막쪽으로 이동시켜주세요. 원래 있던 숫자의 순서는 바꾸지 말아주세요.</p>
<p>새로운 배열을 생성해서는 안 됩니다.</p>
<p>Input: [0, 1, 0, 3, 12]
Output: [1, 3, 12, 0, 0]</p>
<h3 id="🔥-풀이">🔥 풀이<img src="https://images.velog.io/images/hanjoon_10/post/6357352a-494a-43a6-9a90-70a59a60047b/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-26%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.04.06.png" alt=""></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[Codekata #1]]></title>
            <link>https://velog.io/@hanjoon_10/Codekata</link>
            <guid>https://velog.io/@hanjoon_10/Codekata</guid>
            <pubDate>Sun, 25 Jul 2021 14:54:26 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-문제">🚀 문제</h3>
<p>양수로 이루어진 m x n 그리드를 인자로 드립니다. 상단 왼쪽에서 시작하여, 하단 오른쪽까지 가는 길의 요소를 다 더했을 때,가장 작은 합을 찾아서 return 해주세요.</p>
<p>한 지점에서 우측이나 아래로만 이동할 수 있습니다.
[1, 3, 1]
[1, 5, 1]
[4, 2, 1]</p>
<p>Output: 7</p>
<p>1→3→1→1→1 의 합이 제일 작음</p>
<h3 id="🔥-풀이">🔥 풀이</h3>
<p><img src="https://images.velog.io/images/hanjoon_10/post/f82eb66f-5061-4297-886f-769732335b4d/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-26%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.00.47.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dr.Mozzarella]]></title>
            <link>https://velog.io/@hanjoon_10/Dr.Mozzarella-pm1a8zuz</link>
            <guid>https://velog.io/@hanjoon_10/Dr.Mozzarella-pm1a8zuz</guid>
            <pubDate>Sun, 18 Jul 2021 15:09:28 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-drjart-프로젝트">🚀 Dr.jart+ 프로젝트</h3>
<h4 id="📍-내가-맡은-파트">📍 내가 맡은 파트</h4>
<ul>
<li>Sigup &amp; Signin</li>
<li>User Validation (Decorator)</li>
<li>Product Detail
<img src="https://images.velog.io/images/hanjoon_10/post/1d9a4d4c-9fef-4d51-a2ee-84cec5163331/image.png" alt=""></li>
</ul>
<h4 id="🧀-front--back">🧀 Front &amp; Back</h4>
<ul>
<li>FE: 박정훈, 이종민, 황소미</li>
<li>BE: 김한준, 안희수, 이동명</li>
</ul>
<h4 id="🔥-문제점">🔥 문제점</h4>
<p>처음 모델링을 작성 후 프론트와 회의를 할 수록 모델링을 계속 수정해나가는 경우가 힘들었던 부분이었다. 모델링을 할때 우리의 &#39;갓&#39;경훈 멘토님의 조언을 들었다면 더 쉽게 모델링을 작성하고 수정도 적었겠지만 그의 말을 듣지 않은게 뒤늦은 후회로 다가왔다.🙃</p>
<h4 id="🔥-어려웠던-부분">🔥 어려웠던 부분</h4>
<p>제품 상세페이지에서 추천 제품과 비교 제품의 데이터를 처리하는 과정에서 어려운 부분이 있었다.
추천 제품의 경우, 같은 우유 카테고리이지만 다른 스타일의 치즈를 추천해야했고 비교 제품의 경우, 같은 우유 카테고리와 같은 스타일의 치즈이지만 다른 나라의 치즈 제품을 추천해야했다.
우유는 3가지의 카테고리, 스타일은 4가지의 카테고리, 나라는 6가지의 카테고리로 Many to Many 관계를 갖고 있었기 때문에 필터링과 예외처리를 하는 과정이 어려웠다.</p>
<h4 id="🔥-마무리">🔥 마무리</h4>
<p>개인 프로젝트가 아닌 팀 프로젝트를 하면서 백엔드 뿐만 아니라 프론트와 함께 회의와 소통을 통해 동료들끼리의 협업을 배울 수 있는 정말 큰 기회였다. 서로의 의견을 고수하기보다는 프로젝트의 완성도와 목표를 위해 본인의 의견을 양보하고 같이 맞춰나간 팀원들에게 감사한다. </p>
<p>정훈님, 종민님, 소미님, 동명님, 희수님 감사합니다-!!!</p>
<p>2주라는 짧은 기간동안의 프로젝트였기 때문에 여러 문제점과 어려운 점이 있었지만 우리에게는 그가 있었다. </p>
<blockquote>
<p><del>이동명</del> 🤔
<strong><em>갓동명</em></strong> 👍</p>
</blockquote>
<p>갓동명이 없었더라면 내 코드는 과연 살아남을 수 있었을까??
갓동명이 없었더라면 내 Product detail API는 완성될 수 있었을까?</p>
<p>내가 부족한 것이 많아 프로젝트 기간 내내 동명님 옆에 붙어서 이것 저것 물어보며 동명님의 시간을 뺏고 귀찮게 했지만 항상 친절하고 자세하게 알려주신 동명님에게 다시 한 번 감사의 인사를 전하고 싶다.
2차 프로젝트에도 그와 함께 하고 싶다.
다시 한 번 외친다 그의 이름 ⚡️ 갓동명⚡️</p>
<p>그럼 이만!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS]]></title>
            <link>https://velog.io/@hanjoon_10/AWS</link>
            <guid>https://velog.io/@hanjoon_10/AWS</guid>
            <pubDate>Sun, 18 Jul 2021 13:36:47 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-amazon-web-service">🚀 Amazon Web Service</h3>
<p>🔥 클라우드 서비스. 유저가 직접 서버를 구입하고 설치할 필요 없이 AWS상에서 서버를 구축하고 사용</p>
<h4 id="ec2">EC2</h4>
<ul>
<li>Elastic Compute Cloud</li>
<li>AWS 상에서 사용하는 서버</li>
</ul>
<h4 id="security-group">Security Group</h4>
<ul>
<li>EC2 인스턴스에 대한 네트워크 트래픽을 제어하는 가상 방화벽 역할</li>
<li>security group 설정을 해줘야 EC2 인스턴스에 HTTP, SSH 접속이 가능</li>
</ul>
<h4 id="rds-relational-database-servcie">RDS (Relational Database Servcie)</h4>
<ul>
<li>AWS database 서비스 </li>
<li>RDS를 사용하면 사용자가 직접 서버를 생성해서 데이터 베이스를 설치하고 설정하고 관리 하지 않아도 된다</li>
<li>비용은 더 저렴 💰</li>
</ul>
<h4 id="load-balancer">Load Balancer</h4>
<ul>
<li>HTTP 요청이 많을때 여러 서버로 분산</li>
</ul>
<h4 id="route-53">Route 53</h4>
<ul>
<li>AWS의 DNS (Domain Name System) 서비스
  -DNS: 네트워크에서 도메인이나 호스트 네임을 숫자로 되어 있는 IP 주소로 해석해 주는 TCP/IP 네트워크 서비스</li>
<li>API시스템을 실제 도메인과 연결</li>
</ul>
<h4 id="aws-s3">AWS s3</h4>
<ul>
<li>AWS Simple Strong Service(3S)</li>
<li>파일을 쉽게 저장할 수 있는 공간을 제공</li>
<li>파일마다 고유 주소를 부여해서 웹에서 쉽게 읽을 수 있다</li>
<li>이미지를 저장하고 사이트에서 렌더링 해주는데 사용</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Decorator]]></title>
            <link>https://velog.io/@hanjoon_10/Decorator</link>
            <guid>https://velog.io/@hanjoon_10/Decorator</guid>
            <pubDate>Tue, 13 Jul 2021 14:31:22 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-decorator">🚀 Decorator</h3>
<p>독립적인 HTTP 통신 때문에 페이지가 넘어갈때 마다 새로운 인증을 해줘야 한다.
새로운 페이지에서 인증을 해야하지만 인증 코드가 모든 코드에 붙으면 코드가 복잡해지고 길어진다. 코드의 가독성과 간결화를 위해 인증 구현후 데코레이터를 사용하는 것이 좋다</p>
<p><img src="https://images.velog.io/images/hanjoon_10/post/1ad24441-f1cc-4ea5-9fd7-f2f0a54e0592/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-12%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.56.54.png" alt=""></p>
<pre><code>🔥
import jwt        #토근 생성, encode/decode
import json        #request로 받는 데이터 json

🔥
from .models import Account        #로그인에 필요한 유저 정보가 담긴 models
from django.http import JsonResponse    #토큰 및 유저 확인 후 보낼 response 메세지를 JsonResponse</code></pre><p><img src="https://images.velog.io/images/hanjoon_10/post/4097f686-af5d-4a2a-af92-bc8c54c2a91e/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-12%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.54.35.png" alt=""></p>
<ul>
<li>전송된 HTTP 요청에서 &quot;AUTHORIZATION&quot; 값을 읽은 후 Access Token을 얻음</li>
</ul>
<p><img src="https://images.velog.io/images/hanjoon_10/post/01364781-6c2b-4360-90fb-46f6b8b00b98/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-12%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.54.55.png" alt=""></p>
<ul>
<li><p>JWT를 암호화할때 사용한 SECRET_KEY와 Hash_algorithm을 사용하여 token을 복호화후 payload변수에 할당</p>
</li>
<li><p>복호화한 JWT의 사용자 이름을 변수에 할당 후 이후에 비교할 사용자 이름과 비교할 때 사용</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Sorting the dictionaries in a list]]></title>
            <link>https://velog.io/@hanjoon_10/Sorting-the-dictionaries-in-a-list</link>
            <guid>https://velog.io/@hanjoon_10/Sorting-the-dictionaries-in-a-list</guid>
            <pubDate>Sun, 11 Jul 2021 12:47:52 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-리스트안에-있는-딕셔너리-정렬">🚀 리스트안에 있는 딕셔너리 정렬</h3>
<h4 id="🔥-sorted--lambda">🔥 sorted() + lambda</h4>
<ul>
<li>iterable 자리에는 dict, list, str 가능</li>
<li>key는 요소를 비교할때 사용되는 기준을 정하는 함수</li>
<li>Reverse = Ture, 내림차순
Reverse = False, 오름차순<pre><code>soreted(iterable, key=None, reverse=false)</code></pre><ul>
<li>dictionary case
<img src="https://images.velog.io/images/hanjoon_10/post/106d7267-f957-462c-ac4b-687680de7011/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-07-11%20%EC%98%A4%ED%9B%84%208.58.30.png" alt=""></li>
</ul>
</li>
</ul>
<ul>
<li>tuple case
<img src="https://images.velog.io/images/hanjoon_10/post/ef3b6731-c9cf-416d-94fb-dc43dc63979a/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-07-11%20%EC%98%A4%ED%9B%84%209.12.54.png" alt=""></li>
</ul>
<h4 id="🔥-sorted--itemgetter">🔥 sorted() + itemgetter</h4>
<p><img src="https://images.velog.io/images/hanjoon_10/post/df2b8fa1-614f-4241-90b7-44a6be8eed7c/%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202021-07-11%20%EC%98%A4%ED%9B%84%209.46.13.png" alt="">
reverse를 사용하면 lambda를 사용했을 때 와 같이 역으로 정렬 가능</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git 명령어 정리]]></title>
            <link>https://velog.io/@hanjoon_10/Git-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@hanjoon_10/Git-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Fri, 09 Jul 2021 14:56:55 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-git-명령어">🚀 git 명령어</h3>
<h4 id="🔥">🔥</h4>
<h4 id="git-init--깃-초기화">git init : 깃 초기화</h4>
<h4 id="git-add-특정파일명--특정파일을-스테이징-하기">git add 특정파일명 : 특정파일을 스테이징 하기</h4>
<h4 id="git-add---전체-파일-스테이징-하기">git add . : 전체 파일 스테이징 하기</h4>
<h4 id="git-commit--m-메세지-내용--메세지와-함께-커밋하기">git commit -m &quot;메세지 내용&quot; : 메세지와 함께 커밋하기</h4>
<h4 id="git-commit--am-메세지-내용--스테이징과-커밋을-메세지와-함께-올리기">git commit -am &quot;메세지 내용&quot; : 스테이징과 커밋을 메세지와 함께 올리기</h4>
<h4 id="git-commit---amend--방금-커밋한-메세지-수정하기">git commit --amend : 방금 커밋한 메세지 수정하기</h4>
<h4 id="git-branch--브랜치-확인">git branch : 브랜치 확인</h4>
<h4 id="git-branch-브랜치이름--브랜치이름으로-브랜치-만들기">git branch 브랜치이름 : &#39;브랜치이름&#39;으로 브랜치 만들기</h4>
<h4 id="git-branch--d-삭제할브랜치이름--브랜치-삭제마스터-브랜치에서-해야한다">git branch -d 삭제할브랜치이름 : 브랜치 삭제(마스터 브랜치에서 해야한다.)</h4>
<h4 id="git-checkout-브랜치이름--브랜치이름으로-브랜치-이동">git checkout 브랜치이름 : &#39;브랜치이름&#39;으로 브랜치 이동</h4>
<h4 id="git-remote-add-origin-원격저장소주소--원격-저장소에-연결">git remote add origin 원격저장소주소 : 원격 저장소에 연결</h4>
<h4 id="git-push--원격-저장소에-올리기">git push : 원격 저장소에 올리기</h4>
<h4 id="git-clone-원격저장소주소-지역저장소디렉토리--원격저장소-가져오기">git clone 원격저장소주소 지역저장소디렉토리 : 원격저장소 가져오기</h4>
<h4 id="📍">📍</h4>
<h4 id="git-status--깃-상태-확인">git status : 깃 상태 확인</h4>
<h4 id="git-stash--지금-하던-작업을-임시로-저장하기">git stash : 지금 하던 작업을 임시로 저장하기</h4>
<h4 id="git-stash-list--stash-목록-확인하기">git stash list : stash 목록 확인하기</h4>
<h4 id="git-stash-apply--git-stash로-저장했던-작업-가져오기">git stash apply : git stash로 저장했던 작업 가져오기</h4>
<h4 id="git-stash-drop--stash-제거하기">git stash drop : stash 제거하기</h4>
<h4 id="git-stash-clear--임시로-저장했던-stash-모두-제거">git stash clear : 임시로 저장했던 stash 모두 제거</h4>
<h4 id="git-stash-show--p--git-apply--r--실수로-잘못-stash-한거-되돌리기">git stash show -p | git apply -R : 실수로 잘못 stash 한거 되돌리기</h4>
<h4 id="git-config---global-username-유저-이름--깃-사용자-이름-설정">git config --global user.name &quot;유저 이름&quot; : 깃 사용자 이름 설정</h4>
<h4 id="git-config---global-useremail-이메일-주소--깃-사용자-이메일-설정">git config --global user.email &quot;이메일 주소&quot; : 깃 사용자 이메일 설정</h4>
<h4 id="git-config---global-coreeditor-vim--커밋-편집에디터를-vim으로-변경하기">git config --global core.editor &quot;vim&quot; : 커밋 편집에디터를 vim으로 변경하기</h4>
<h4 id="git-log-브랜치1-브랜치2--브랜치1과-브랜치2사이의-차이점-보기">git log 브랜치1 ..브랜치2 : 브랜치1과 브랜치2사이의 차이점 보기</h4>
<h4 id="git-merge-병합할브랜치이름--브랜치-병합">git merge 병합할브랜치이름 : 브랜치 병합</h4>
<h4 id="git-log--커밋-기록-보기">git log : 커밋 기록 보기</h4>
<h4 id="git-log---stat--커밋-기록을-커밋에-관련괸-파일과-함께-보기">git log --stat : 커밋 기록을 커밋에 관련괸 파일과 함께 보기</h4>
<h4 id="git-log---oneline--로그를-한줄로-표기">git log --oneline : 로그를 한줄로 표기</h4>
<h4 id="git-log---oneline---branches--각-브랜치의-커밋을-확인">git log --oneline --branches : 각 브랜치의 커밋을 확인</h4>
<h4 id="git-log---oneline---branches---graph--그래프-형식으로-표현">git log --oneline --branches --graph : 그래프 형식으로 표현</h4>
<h4 id="git-diff--깃-변경-내용-확인">git diff : 깃 변경 내용 확인</h4>
<h4 id="git-checkout---파일이름--작업트리에서-수정한-파일-되돌리기">git checkout --파일이름 : 작업트리에서 수정한 파일 되돌리기</h4>
<h4 id="git-reset-head-파일이름--스테이징-취소">git reset HEAD 파일이름 : 스테이징 취소</h4>
<h4 id="git-reset-head--최신-커밋-취소">git reset HEAD^ : 최신 커밋 취소</h4>
<h4 id="git-reset-커밋해시--특정-커밋으로-되돌리기">git reset 커밋해시 : 특정 커밋으로 되돌리기</h4>
<h4 id="git-remote--v--원격-저장소에-잘-연결되었는지-확인">git remote -v : 원격 저장소에 잘 연결되었는지 확인</h4>
<h4 id="git-push--u-origin-master--지역-저장소의-브랜치를-원격-저장소의-마스터-브랜치와-연결-한번만-하면됨">git push -u origin master : 지역 저장소의 브랜치를 원격 저장소의 마스터 브랜치와 연결 (한번만 하면됨)</h4>
<h4 id="git-pull-origin-master--원격-저장소의-내용을-지역-저장소의-마스터브랜치로-가져오기">git pull origin master : 원격 저장소의 내용을 지역 저장소의 마스터브랜치로 가져오기</h4>
<h4 id="git-fetch--원격-저장소의-브랜치-변화-정보만-가져오기">git fetch : 원격 저장소의 브랜치 변화 정보만 가져오기</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[bcrypt & jwt]]></title>
            <link>https://velog.io/@hanjoon_10/bcrypt-jwt</link>
            <guid>https://velog.io/@hanjoon_10/bcrypt-jwt</guid>
            <pubDate>Fri, 09 Jul 2021 14:40:47 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-비밀번호-암호화">🚀 비밀번호 암호화</h3>
<p>🔥 <strong>암호화시 반드시 bytes화</strong>
bycrypt는 str데이터가 아닌 Bytes데이터를 암호화</p>
<p><strong>📍 encode</strong>: &nbsp; str -&gt; bytes
<strong>📍 decode</strong>: &nbsp; bytes -&gt; str
**문자규격 = &#39;utf-8&#39;</p>
<p><img src="https://images.velog.io/images/hanjoon_10/post/032b9f6f-adcd-49c7-8d6d-e5d9a41ee4f4/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-29%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.52.15.png" alt=""> <img src="https://images.velog.io/images/hanjoon_10/post/302d2ffc-d1bc-4c87-8dbe-235174e38a98/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-29%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.57.22.png" alt="">클래스 타입은 당연히 bytes</p>
<p><img src="https://images.velog.io/images/hanjoon_10/post/7d524f0c-dcee-469c-8423-1b64c23a3d13/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-29%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.51.59.png" alt=""></p>
<p>비밀번호 암호화 작업 확인
<img src="https://images.velog.io/images/hanjoon_10/post/be39f46d-8528-4348-a7f1-1a151148982a/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-29%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.03.48.png" alt="">
bcrypt.checkpw()
(입력받은 패스워드, 저장된 암호화 패스워드) 순서
둘 다 타입은 Bytes</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Signup & Login]]></title>
            <link>https://velog.io/@hanjoon_10/Signup-Login</link>
            <guid>https://velog.io/@hanjoon_10/Signup-Login</guid>
            <pubDate>Sun, 04 Jul 2021 01:32:24 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-signup">🚀 Signup</h3>
<p><img src="https://images.velog.io/images/hanjoon_10/post/d808b23b-e943-4212-8624-32e21cc63b42/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-04%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2010.10.52.png" alt=""></p>
<p>HTTP에서 Json body 형식으로 데이터를 받기 때문에 load 또한 Json 형식으로 해야 서로 말이 통한다</p>
<p><img src="https://images.velog.io/images/hanjoon_10/post/5cb9d368-75cc-4fdc-865f-18a5fb5ff5da/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.12.52.png" alt=""></p>
<p>이메일 체크에서 처음 썼던 코드 
이렇게 되면 이메일 형식이 아닌 그냥 &quot;@&quot;와 &quot;.&quot;만 들어가면 통과가 가능하다
ex) abcd.com@gmail
이걸 보안하기 위해서 이메일 정규식을 사용</p>
<p><img src="https://images.velog.io/images/hanjoon_10/post/49337196-1162-4f1a-be2f-82b2bc8a111a/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.16.04.png" alt="">
패스워드 생성에서 처음 사용했던 코드
형식적으로 비밀번호 생성은 가능하지만 문자 또는 숫자 반복과 특수문자 사용등을 안해도 비밀번호가 생성되기때문에 보안에 취약하다
그래서 패스워드 정규식을 사용 </p>
<h3 id="🚀-login">🚀 Login</h3>
<p><img src="https://images.velog.io/images/hanjoon_10/post/c0e1915c-2cf3-4cf2-acd6-6864818b4f42/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-07-04%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2010.11.10.png" alt=""></p>
<p><img src="https://images.velog.io/images/hanjoon_10/post/a2afa0af-e643-4d56-a3bf-c8fefbb41819/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.31.48.png" alt="">
처음 사용했던 패스워드 코드
문제점: &nbsp; a아이디의 비밀번호가 아닌     db에 들어있는 비밀번호만 입력해도 패스
ex) a아이디 + b아이디의 비밀번호 = 패스 </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Django QuerySet API]]></title>
            <link>https://velog.io/@hanjoon_10/Django-QuerySet-API</link>
            <guid>https://velog.io/@hanjoon_10/Django-QuerySet-API</guid>
            <pubDate>Mon, 28 Jun 2021 15:01:26 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-queryset">🚀 QuerySet</h3>
<pre><code>전달받은 모델의 객체목록
데이터베이스로부터 데이터를 읽고 필터를 걸거나 정렬할 수 있다</code></pre><p><strong>📍 Model Method 종류</strong></p>
<pre><code>all()
filter()
exclude()    
values()
values_list()
get()    
create()
count()        
exists()        
update()    
delete()      
first()    
last()</code></pre><p>…</p>
<p><strong>📍 QuesrySet을 반환하는 경우</strong></p>
<pre><code>&lt;QuerySet [&lt;Category: Category object(1)&gt;, &lt;Category: Category object (2)&gt;]&gt;</code></pre><p><strong>📍 그렇지 않은 경우</strong></p>
<pre><code>&lt;Category: Category object (1)&gt;, 9, True…</code></pre><p><strong>🔥 Methods That Don’t Return QuerySets</strong></p>
<p>Create()</p>
<ul>
<li>Table에 데이터를 추가 해주는 method. 생성된 인스턴스를 반환
<img src="https://images.velog.io/images/hanjoon_10/post/1e490e46-9369-46be-930a-98514dbbbfae/image.png" alt=""></li>
</ul>
<p>get() </p>
<ul>
<li>지정된 조회 매개 변수와 일치하는 인스턴스를 반환</li>
</ul>
<p><img src="https://images.velog.io/images/hanjoon_10/post/ae345d09-fba5-4589-a25e-f442a789f183/image.png" alt=""></p>
<p>update()</p>
<ul>
<li>지정된 필드에 대해 업데이트 쿼리를 수행하고 일치하는 행 수를 반환
<img src="https://images.velog.io/images/hanjoon_10/post/69ee3bf3-7289-470c-91ab-170af078e05b/image.png" alt=""></li>
</ul>
<p>delete()</p>
<ul>
<li>QuerySet의 모든행에 대해 SQL 삭제 쿼리를 수행하고 삭제 된 개체수와 개체 유형별 삭제횟수가 있는 dictionary를 반환
<img src="https://images.velog.io/images/hanjoon_10/post/4323a2bc-795b-4b46-aa65-2ede2df47bea/image.png" alt=""></li>
</ul>
<p>save()</p>
<ul>
<li>Insert 와 Update를 수행하는 method 
단일 객체에 대해서 업데이트를 수행할 때 사용
<img src="https://images.velog.io/images/hanjoon_10/post/c9086bed-80ab-47fc-b85a-5c0250490cae/image.png" alt=""></li>
</ul>
<p>exists()</p>
<ul>
<li>filter와 함께 사용
filter 조건에 맞는 데이터가 있는지 조회
True or False
<img src="https://images.velog.io/images/hanjoon_10/post/b3c01e70-845c-4e04-be35-c8b2a0cf667d/image.png" alt=""></li>
</ul>
<p>count()
get_or_create()<br>bulk_create()<br>first()<br>last()<br>aggregate()</p>
<p><strong>🔥 Methods That Return QuesrySets</strong></p>
<p>all()</p>
<ul>
<li><p>한 테이블의 모든 레코드를 가져오려면 all()method
QuerySet을 반환 각각 인스턴스 포함</p>
<p>  In  : Category.objects.all()
  Out : &lt;QuerySet [&lt;Category: Category object (2)&gt;, &lt;Category: Category object (3)&gt;, &lt;Category: Category object (4)&gt;, &lt;Category: Category object (5)&gt;, &lt;Category: Category object (6)&gt;, &lt;Category: Category object (7)&gt;]&gt;</p>
<p>  In  : for category in Category.objects.all()</p>
<pre><code>              print(category.name)</code></pre><p>  #아래와 같이 인스턴스들이 담겨 있는 QuerySet이 반환되기 때문에, 모든 속성에 접근해서 데이터를 관리할 수 있습니다.
  Out : 티</p>
<pre><code>브루드커리
브루드커피
콜드브루
콜드브루</code></pre></li>
</ul>
<p>filter()&amp;exclude()    </p>
<ul>
<li>테이블의 특정 레코드를 가져오기 위한 method
filter(**kwargs): 키워드 인자로 주어진 lookup 조건에 일치하는 레코드들의 QuerySet을 반환
<img src="https://images.velog.io/images/hanjoon_10/post/d0e6bd8e-e02b-44bc-8f4c-3099f007859c/image.png" alt=""></li>
</ul>
<p>values()</p>
<ul>
<li><p>iterable로 사용될 때 모델 인스턴스가 아닌 dictionary을 포함하는 QuerySet을 반환합니다.
<img src="https://images.velog.io/images/hanjoon_10/post/4288a311-6bf1-43f1-8827-9096df72e492/image.png" alt=""></p>
<p>  In  : Category.objects.filter(name=&#39;브루드커피&#39;).values()
  Out : &lt;QuerySet [{&#39;id&#39;: 3, &#39;name&#39;: &#39;브루드커피&#39;, &#39;created_at&#39;: datetime.datetime(2020, 9, 8, 5, 43, 30, 4068, tzinfo=<UTC>), &#39;updated_at&#39;: datetime.datetime(2020, 9, 8, 5, 43, 30, 21801, tzinfo=<UTC>)}, {&#39;id&#39;: 4, &#39;name&#39;: &#39;브루드커피&#39;, &#39;created_at&#39;: datetime.datetime(2020, 9, 8, 5, 43, 30, 4068, tzinfo=<UTC>), &#39;updated_at&#39;: datetime.datetime(2020, 9, 8, 5, 43, 30, 21801, tzinfo=<UTC>)}]&gt;</p>
</li>
</ul>
<p>values_list()</p>
<ul>
<li><p>values_list() method는 dictionary를 반환하는 대신 반복 될 때 튜플을 반환</p>
<p>  In  : Category.objects.filter(name=&#39;브루드커피&#39;).values_list()
  Out : &lt;QuerySet [(3, &#39;브루드커피&#39;, datetime.datetime(2020, 9, 8, 5, 43, 30, 4068, tzinfo=<UTC>), datetime.datetime(2020, 9, 8, 5, 43, 30, 21801, tzinfo=<UTC>)), (4, &#39;브루드커피&#39;, datetime.datetime(2020, 9, 8, 5, 43, 30, 4068, tzinfo=<UTC>), datetime.datetime(2020, 9, 8, 5, 43, 30, 21801, tzinfo=<UTC>))]&gt;</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Authentication & Authorization]]></title>
            <link>https://velog.io/@hanjoon_10/Authentication-Authorization</link>
            <guid>https://velog.io/@hanjoon_10/Authentication-Authorization</guid>
            <pubDate>Mon, 28 Jun 2021 10:53:10 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-authentication-인증">🚀 Authentication (인증)</h3>
<p>유저의 identification을 확인하는 절차 (회원가입 &amp; 로그인)</p>
<p>📍 비밀번호 암호화</p>
<ul>
<li>단방향 해쉬 함수 (One-way hash function)</li>
<li>원본 메세지를 변환하여 암호화된 다이제스트(digest)를 생성</li>
<li>암호화된 메세지로부터 원본 메세지를 구할 수 없기 때문에 단방향성(one-way)</li>
</ul>
<p>📍 단방향 해쉬 함수의 취약점을 보안하기 위한 2가지 방법</p>
<ul>
<li><p><strong>Salting</strong>: 실제 비밀번호 이외에 추가적으로 랜덤 데이터를 더해서 해쉬값을 계산하는 방법</p>
</li>
<li><p><strong>Key-Stretching</strong>: 해쉬를 반복하는 것. 단방향 해쉬값을 계산 후 그 해쉬값을 다시 해쉬하고 다시 해쉬하는 방법</p>
</li>
</ul>
<p><img src="https://images.velog.io/images/hanjoon_10/post/e28c2dbc-b99b-4999-944b-6fb11ad7e553/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%205.36.45.png" alt=""></p>
<p>📍 <strong>Bcrypt</strong>: Salting &amp; Key Stretching 대표적 라이브러리 </p>
<p><img src="https://images.velog.io/images/hanjoon_10/post/5c787ee6-b9cb-42bb-84a9-64f73717265c/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.35.20.png" alt=""></p>
<p>📍 <strong>JWT</strong> (JSON Web Tokens): 유저 정보를 담은 JSON 데이터를 암호화해서 클라이언트와 서버간에 주고 받는것</p>
<p><img src="https://images.velog.io/images/hanjoon_10/post/f0a9d0ce-1b93-4040-bfa9-f95bc85a9921/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-28%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.51.13.png" alt=""></p>
<ul>
<li>헤더에는 토큰의 타입과 해쉬알고리즘 정보가 들어감</li>
<li>내용에는 exp와 같은 만료시간을 공개</li>
</ul>
<h3 id="🚀authorization-인가">🚀Authorization (인가)</h3>
<p>유저가 요청하는 request를 실행할 수 있는 권한이 있는지 확인하는 절차</p>
<p>access_token을 통해 권한을 확인 할 수 있다</p>
<p>📍 <strong>Authorization step</strong></p>
<ol>
<li>Authentication 절차를 통해 <code>access token</code>을 생성한다. <code>access token</code>에는 유저 정보를 확인할 수 있는 정보가 들어가 있어야 한다 (예를 들어 user id).</li>
<li>유저가 request를 보낼때 <code>access token</code>을 첨부해서 보낸다.</li>
<li>서버에서는 유저가 보낸 <code>access token</code>을 복호화 한다.</li>
<li>복호화된 데이터를 통해 user id를 얻는다.</li>
<li>user id를 사용해서 database에서 해당 유저의 권한(permission)을 확인하다.</li>
<li>유저가 충분한 권한을 가지고 있으면 해당 요청을 처리한다.</li>
<li>유저가 권한을 가지고 있지 않으면 Unauthorized Response(401) 혹은 다른 에러 코드를 보낸다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CRUD]]></title>
            <link>https://velog.io/@hanjoon_10/CRUD</link>
            <guid>https://velog.io/@hanjoon_10/CRUD</guid>
            <pubDate>Sat, 26 Jun 2021 07:27:43 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-client----server----database">🚀 Client &lt;--&gt; Server &lt;--&gt; Database</h3>
<h4 id="📍cleint----server">📍Cleint &lt;--&gt; Server</h4>
<pre><code>https://velog.io/@hanjoon_10/HTTP</code></pre><h4 id="📍server----database">📍Server &lt;--&gt; Database</h4>
<pre><code>1. models.py
2. views.py
3. urls.py</code></pre><ul>
<li><p>model.spy
Client의 요청
데이터를 HTTP body에 담아서 HTTP Method 요청을 보낸다</p>
</li>
<li><p>views.py
views.py(class형) or views.py(함수형)<br>class형 view를 이용해서 HTTP Method 요청을 처리한고 DATABSE 테이블에 데이터를 저장한 다음 결과를 반환한다</p>
</li>
<li><p>urls.py
HTTP Method 요청에 포함된 body에서 데이터를 꺼내온다</p>
</li>
</ul>
<p>🔥 작성하기전 문장으로 정리를 하는게 좋다! 
🔥 순서는 models, views, urls 순서</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[참조&역참조]]></title>
            <link>https://velog.io/@hanjoon_10/Django-C.R.U.D</link>
            <guid>https://velog.io/@hanjoon_10/Django-C.R.U.D</guid>
            <pubDate>Sat, 26 Jun 2021 07:27:31 GMT</pubDate>
            <description><![CDATA[<h3 id="🚀-one-to-many">🚀 One to Many</h3>
<p><img src="https://images.velog.io/images/hanjoon_10/post/921075b8-b4cd-44ec-8dba-905f37194c4a/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-23%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.00.47.png" alt=""></p>
<h3 id="🚀-many-to-many">🚀 Many to Many</h3>
<p><img src="https://images.velog.io/images/hanjoon_10/post/d69f981e-12a0-4bd0-a1e9-f5e4bef25dfc/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-06-23%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.01.18.png" alt=""></p>
<h4 id="📍-참조">📍 참조</h4>
<pre><code>model에 선언해둔 변수 이름으로 접근
a.(변수)
ex) a.movies</code></pre><h4 id="📍-역참조">📍 역참조</h4>
<pre><code>_set으로 접근
m.(클래스 이름)_set
m.actor_set</code></pre><p>One to Many는 _set설정을 사용해서 역참조 가능
Many to Many는 쿼리문을 간결하게 만들어 코드 또한 간결해진다.</p>
]]></description>
        </item>
    </channel>
</rss>