<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Minho Lee</title>
    <description>The latest articles on DEV Community by Minho Lee (@devamos).</description>
    <link>https://dev.to/devamos</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F823884%2F3562df6a-70b0-4ff2-99b9-c7a7d712f448.jpeg</url>
      <title>DEV Community: Minho Lee</title>
      <link>https://dev.to/devamos</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devamos"/>
    <language>en</language>
    <item>
      <title>[ Database ] - SQLAlchemy "or_" function</title>
      <dc:creator>Minho Lee</dc:creator>
      <pubDate>Fri, 01 Apr 2022 10:17:00 +0000</pubDate>
      <link>https://dev.to/devamos/-database-sqlalchemy-or-function-3925</link>
      <guid>https://dev.to/devamos/-database-sqlalchemy-or-function-3925</guid>
      <description>&lt;p&gt;진행중인 프로젝트에서 이번에 검색 기능을 추가하기로 했다.&lt;br&gt;
쉽게 상품이 있는데, 한글과 영어로 된 이름이 모두 상품 테이블에 각 컬럼별로 존재한다.&lt;/p&gt;

&lt;p&gt;보통 검색기능을 구현할 때, sql에서는 like 구문으로, orm는 종류가 다양하지만 보통 like나 filter와 같은 메소드로 값을 전달해서 데이터를 추출하곤 한다.&lt;/p&gt;

&lt;p&gt;하지만 내가 오늘 구현하고 싶었던 기능은, 어떠한 키워드로 검색을 했을 때&lt;br&gt;
한글 이름과 영어 이름 컬럼에서 모두 해당 키워드가 존재하는지 검색 후 값을 가져오고 싶었다.&lt;/p&gt;

&lt;p&gt;상품 모델을 &lt;code&gt;Product&lt;/code&gt;라 하고, 필드명이 &lt;code&gt;name&lt;/code&gt;이라고 하나만 존재하고,&lt;br&gt;
상품의 이름으로 검색을 하고싶다면 우리는 orm을 다음과 같이 작성할 수 있다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# "db" is "&amp;lt;class 'sqlalchemy.orm.session.Session'&amp;gt;"
# "name" is variable from Query Parameter
&lt;/span&gt;
&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"%&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;그런데 만약, name이라는 하나의 컬럼이 아닌, 한국어와 영어로 이름을 모두 가지고 있는 상품이라면 컬럼은 &lt;code&gt;kor&lt;/code&gt;,&lt;code&gt;eng&lt;/code&gt;로 나뉠 수 있고 한 번에 두 가지의 컬럼을 모두 검색하고 싶다면 다음과 같이 sqlalchemy에서 or_이라는 함수를 가져와 사용하면 된다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# "db" is "&amp;lt;class 'sqlalchemy.orm.session.Session'&amp;gt;"
# "name" is variable from Query Parameter
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;or_&lt;/span&gt;

&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;or_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"%&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"%&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;이렇게 해주면 "나이키" 와 "Nike"이라는 이름을 가진 상품이 있을 때,&lt;br&gt;
Query Parameter에 name으로 "이", "나이", "i", "ik", "ike" 등등&lt;br&gt;
한글과 영어로 구분지을 필요 없이 검색을 할 수 있다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;물론 검색 필터로 &lt;strong&gt;&lt;code&gt;f"%{name}%"&lt;/code&gt;&lt;/strong&gt;이라고 주었기 때문에 가능한 것이다.&lt;br&gt;
서비스에 따라 &lt;strong&gt;&lt;code&gt;%&lt;/code&gt;&lt;/strong&gt;를 잘 활용하도록 하자.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;만약에 일본어의 이름도 추가하고 싶어서 jp라는 컬럼까지 추가했고, 해당 컬럼까지 조회하고 싶다면 or_ 함수에 &lt;strong&gt;&lt;code&gt;Product.jp.like(f"%{name}%")&lt;/code&gt;&lt;/strong&gt; 인자를 추가해주면 된다.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# "db" is "&amp;lt;class 'sqlalchemy.orm.session.Session'&amp;gt;"
# "name" is variable from Query Parameter
&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;or_&lt;/span&gt;

&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;or_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;kor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"%&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"%&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;like&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s"&gt;"%&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;%"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nb"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>database</category>
      <category>sql</category>
      <category>sqlalchemy</category>
      <category>python</category>
    </item>
    <item>
      <title>[ Database ] - Session Object of SQLAlchemy</title>
      <dc:creator>Minho Lee</dc:creator>
      <pubDate>Thu, 24 Mar 2022 14:59:30 +0000</pubDate>
      <link>https://dev.to/devamos/-database-session-object-of-sqlalchemy-586</link>
      <guid>https://dev.to/devamos/-database-session-object-of-sqlalchemy-586</guid>
      <description>&lt;h1&gt;
  
  
  Session Object of SQLALchmey
&lt;/h1&gt;

&lt;p&gt;SQLAlchemy에 Query Object를 다루는 Session Object가 있다.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mUZSvfgB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lw192t89lc2uq3c79ic.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mUZSvfgB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lw192t89lc2uq3c79ic.jpg" alt="Image description" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;쉽게 보자면 다음과 같다.&lt;/p&gt;

&lt;p&gt;Session 객체에는 쉽게는 add와 commit, 사실 flush라는 함수도 존재한다.&lt;/p&gt;

&lt;p&gt;그림을 보면 알겠지만, add를 한다고 해서 DB에 실제로 영향이 가진 않는다.&lt;/p&gt;

&lt;p&gt;정확히는 commit이 일어나야 실제로 DB에 변화가 일어나고,&lt;br&gt;
기본적으로 옵션을 주지 않으면, commit만 해도 flush는 commit과 함께 일어난다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Editing now&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>sqlalchemy</category>
      <category>python</category>
    </item>
    <item>
      <title>[ Network ] - Cookie &amp; Session</title>
      <dc:creator>Minho Lee</dc:creator>
      <pubDate>Tue, 22 Mar 2022 14:59:23 +0000</pubDate>
      <link>https://dev.to/devamos/-network-cookie-session-d99</link>
      <guid>https://dev.to/devamos/-network-cookie-session-d99</guid>
      <description>&lt;p&gt;사실 개발을 하다 보면 저절로 알게 되는 파트인듯하다.&lt;/p&gt;

&lt;p&gt;하지만 두루뭉실하게 알고 지나가는 경우가 많고,&lt;br&gt;
최근에는 기술 면접도 대비를 해야 해서 이렇게 글로 남겨보려고 한다.&lt;/p&gt;

&lt;p&gt;먼저 쿠키와 세션에 대해 알기 전에, HTTP 프로토콜에 특징을 알아야 한다.&lt;br&gt;
그래야 &lt;strong&gt;왜 쿠키와 세션을 사용하는지&lt;/strong&gt; 알 수 있기 때문이다.&lt;/p&gt;




&lt;h1&gt;
  
  
  HTTP 프로토콜의 특징
&lt;/h1&gt;

&lt;h4&gt;
  
  
  1. Connectionless(비연결지향)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;클라이언트가 요청을 한 후, 응답을 받으면 그 연결을 끊어버리는 특징. HTTP 프로토콜은 Client가 요청을 보내고, 서버에서 응답을 보낸 후 접속을 끊어버린다.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Stateless(상태정보 유지 안함)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;통신이 끝나면 상태를 유지하지 않는 특징이다.
연결을 끊는 순간 Client와 서버의 통신이 끝나고, 상태 정보는 유지하지 않는 특징이  있다.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;위 두 가지 공통적인 특징으로 보아 HTTP 프로토콜은 한 번의 요청이 끝나면 접속을 끊으며 상태를 유지하지 않는다.&lt;/p&gt;

&lt;p&gt;즉, 한 번의 요청이 발생한 후 다시 백지가 된다고 생각하면 편할 것 같다.&lt;br&gt;
이러한 이유 때문에, 우리는 쿠키와 세션을 사용한다.&lt;/p&gt;




&lt;h1&gt;
  
  
  🍪 Cookie
&lt;/h1&gt;

&lt;h4&gt;
  
  
  1️⃣ 쿠키란?
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;쿠키란, 클라이언트(브라우저) 로컬에 저장되는 작은 데이터 파일이다.&lt;/li&gt;
&lt;li&gt;쿠키의 만료일이 없다면, 브라우저의 탭을 닫거나 종료해도 쿠키는 사라지지 않는다.&lt;/li&gt;
&lt;li&gt;쿠키는 클라이언트의 상태 정보를 로컬에 저장했다가 참조한다.&lt;/li&gt;
&lt;li&gt;하나의 클라이언트당 300개의 쿠키 저장이 가능하다. 각 도메인당 20개의 쿠키를 가질 수 있고, 쿠키 하나의 크기는 4KB이다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  2️⃣ 쿠키의 구성 요소
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;이름&lt;/strong&gt; : 각각의 쿠키를 구별하기 위해 사용되는 이름&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;값&lt;/strong&gt; : 쿠키에서 가지고 있어야 할 값&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;유효시간&lt;/strong&gt; : 말 그대로 쿠키의 유효시간&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;도메인&lt;/strong&gt; : 쿠키를 전송할 도메인&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;경로&lt;/strong&gt; : 쿠키를 전송할 요청 경로&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3️⃣ 쿠키는 어떻게 동작하는가?
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;클라이언트에서 서버로 요청&lt;/li&gt;
&lt;li&gt;서버에서 쿠키 생성&lt;/li&gt;
&lt;li&gt;서버가 클라이언트에게 응답을 할 때, HTTP 헤더에 생성한 쿠키를 담아 응답&lt;/li&gt;
&lt;li&gt;서버에게서 받은 쿠키를 클라이언트(로컬)에 저장&lt;/li&gt;
&lt;li&gt;해당 서버에게 다른 요청을 보낼 때, 쿠키가 사용자의 로컬에 존재한다면, 해당 쿠키를 헤더에 담아 요청&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  4️⃣ 쿠키의 사용 예시
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;사이트에 방문 시, 아이디 및 비밀번호 자동 입력&lt;/li&gt;
&lt;li&gt;팝업창의 "오늘 이 창을 다시 보지 않기" 체크&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  💾 Session
&lt;/h1&gt;

&lt;h4&gt;
  
  
  1️⃣ 세션이란?
&lt;/h4&gt;

&lt;p&gt;일정 시간동안 동일한 사용자로 부터 들어오는 요청을 하나의 상태로 보고, 그 상태를 일정 시간동안 유지시켜주는 기술이다.&lt;/p&gt;

&lt;p&gt;여기서의 &lt;strong&gt;&lt;code&gt;일정 시간&lt;/code&gt;&lt;/strong&gt;이란, 사용자가 브라우저를 통해서 서버에 접속한 시점부터, 브라우저를 종료하여 연결을 끝내는 시점을 말한다.&lt;/p&gt;

&lt;p&gt;다시 말해, 사용자가 서버에 접속한 상태를 하나의 상태 단위로 보고, 그것을 &lt;strong&gt;&lt;code&gt;세션&lt;/code&gt;&lt;/strong&gt;이라고 한다.&lt;/p&gt;

&lt;h4&gt;
  
  
  2️⃣ 세션의 특징
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;웹 서버에&lt;/strong&gt; 웹 컨테이너의 상태를 유지하기 위한 &lt;strong&gt;정보를 저장한다.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;클라이언트(로컬)가 아닌 웹 서버에 저장되는 쿠키&lt;/li&gt;
&lt;li&gt;세션을 브라우저를 종료했거나 웹 서버에서 세션을 삭제했을 때만 삭제가 된다. 쿠키보다 보안에 좋다.&lt;/li&gt;
&lt;li&gt;쿠키는 총 300개, 도메인당 20개를 저장할 수 있었는데, 세션은 웹 서버에서 허용하는 한 제한 없이 저장이 가능하다.&lt;/li&gt;
&lt;li&gt;각 클라이언트에게 고유한 Session ID를 부여한다.
이 Session ID로 각 클라이언트를 구분하는 것이다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  3️⃣ 세션의 동작 순서
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;클라이언트가 서버에 접속 시 Session ID를 발급 받는다.&lt;/li&gt;
&lt;li&gt;클라이언트는 서버로부터 발급받은 Session ID에 대해 쿠키를 이용하여 저장한다. 이 때, 서버도 해당 Session ID를 서버에서 쿠키를 이용해 갖고 있는다. 그래서 서버에서 저장하는 쿠키라고 하는 것이다.&lt;/li&gt;
&lt;li&gt;클라이언트는 서버에 요청을 보낼 때, 가지고 있던 쿠키의 Session ID를 같이 보낸다.&lt;/li&gt;
&lt;li&gt;서버는 Session ID를 받아서 클라이언트 정보를 가져와 사용한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  4️⃣ 세션의 사용 예시
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;로그인 같이 보안상 중요한 작업을 수행할 때 사용&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  쿠키와 세션의 차이
&lt;/h1&gt;

&lt;p&gt;쿠키와 세션의 차이점 중에서 제일 중요한 몇가지만 나눠보려고 한다.&lt;/p&gt;

&lt;h4&gt;
  
  
  1️⃣ 저장 위치
&lt;/h4&gt;

&lt;p&gt;쿠키는 클라이언트의 로컬에 저장되고, 세션은 서버에 저장이 된다.&lt;/p&gt;

&lt;p&gt;이 말은 다시 말해, 쿠키는 클라이언트의 리소스를 사용하게 되고, 세션은 서버의 리소스를 사용하게 된다.&lt;/p&gt;

&lt;p&gt;이따 뒤에서도 설명을 하겠지만, 세션은 서버측에서 관리를 하기에 보안에 좋다.&lt;/p&gt;

&lt;p&gt;그렇다면 세션만 사용하면 될텐데 왜 쿠키를 사용할까?&lt;/p&gt;

&lt;p&gt;위에도 언급했듯, 세션은 서버의 자원을 사용한다. 따라서 많은 클라이언트가 요청을 하여 무분별하게 세션을 만들다보면 서버의 메모리가 감당이 안되어 서버의 속도가 느려질 수도 있고, 잘못하면 다운이 될 수도 있다.&lt;/p&gt;

&lt;p&gt;이러한 차원에서 쿠키가 존재하며 필요한 이유이다.&lt;/p&gt;

&lt;h4&gt;
  
  
  2️⃣ 속도
&lt;/h4&gt;

&lt;p&gt;쿠키는 클라이언트에서 바로 서버에게 보낸다.&lt;br&gt;
하지만 세션의 방식은, 서버가 Session ID를 받으면 서버 내에서 저장해뒀던 쿠키를 이용해 처리가 필요하기 때문에 속도적인 측면에서는 쿠키를 사용하는 것이 더 빠르다.&lt;/p&gt;

&lt;p&gt;얼마나 속도 차이가 나는지는 아직 공부가 더 필요하다.&lt;/p&gt;

&lt;h4&gt;
  
  
  3️⃣ 보안
&lt;/h4&gt;

&lt;p&gt;쿠키는 클라이언트가 보관을 하지만, 세션은 서버가 관리를 하기에,&lt;br&gt;
보안적인 측면으로는 세션이 더 우수하다.&lt;/p&gt;

</description>
      <category>network</category>
      <category>http</category>
      <category>cookie</category>
      <category>session</category>
    </item>
    <item>
      <title>[ Data Structure ] - Stack &amp; Queue</title>
      <dc:creator>Minho Lee</dc:creator>
      <pubDate>Sun, 20 Mar 2022 14:58:51 +0000</pubDate>
      <link>https://dev.to/devamos/stack-queue-54c2</link>
      <guid>https://dev.to/devamos/stack-queue-54c2</guid>
      <description>&lt;p&gt;스택과 큐를 들어가기에 앞서, 자료구조에 대해 알아야 한다.&lt;/p&gt;

&lt;h1&gt;
  
  
  자료구조
&lt;/h1&gt;

&lt;p&gt;자료구조의 정의는 인터넷에 널리고 널렸다.&lt;/p&gt;

&lt;p&gt;내가 생각하는 자료구조는, &lt;strong&gt;"섹시하게 데이터를 다루는 방법"&lt;/strong&gt;이다.&lt;/p&gt;

&lt;p&gt;그 방법중에 스택과 큐가 존재하는 것이다.&lt;/p&gt;

&lt;p&gt;자료구조는 서비스나 어플리케이션에서 필요한 데이터를 메모리에 어떻게 구조적으로 잘 정리해서 담아주고 관리하고, 최종적으로 가장 효율적인 방식으로 필요한 데이터에&lt;br&gt;
빠르게 접근하고 추가, 수정, 삭제할 수 있도록 도와준다.&lt;/p&gt;

&lt;p&gt;Stack(스택)과 Queue(큐)는 &lt;strong&gt;ADT&lt;/strong&gt; 라고도 불린다.&lt;/p&gt;

&lt;h1&gt;
  
  
  ADT
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;ADT(Abstract Data Type), 추상적 자료구조.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;ADT는 자료구조의 한 형태인데,&lt;/strong&gt; 자료구조의 방법이 코드로 정의 된 것이 아니라 그 구조의 행동 양식만 정의된 것을 뜻 한다.&lt;/p&gt;

&lt;p&gt;실제로 존재하지 않지만, 규칙을 제공한다.&lt;br&gt;
덕분에 자료를 좀 더 구조적으로 생각할 수 있다.&lt;/p&gt;

&lt;p&gt;스택과 큐가 그러하다.&lt;/p&gt;

&lt;p&gt;큐와 스택은 배열 위에 어떤 규칙을 설정한 모습이다.&lt;/p&gt;

&lt;h1&gt;
  
  
  Queue
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Kz1I26iS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2o6tufatvhrtw1q2ddzl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Kz1I26iS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2o6tufatvhrtw1q2ddzl.png" alt="Image description" width="525" height="449"&gt;&lt;/a&gt;&lt;br&gt;
큐의 사전적 의미는 &lt;strong&gt;줄&lt;/strong&gt; 또는 &lt;strong&gt;줄을 서서 기다리를 것&lt;/strong&gt;을 의미한다고 한다.&lt;/p&gt;

&lt;p&gt;따라서 일상생활에서 놀이동산에서 줄을 서서 기다리는 것, 은행에서 먼저 온 사람의 업무를 창구에서 처리하는 것과 같이 선입선출인 &lt;strong&gt;FIFO(First In, First Out)방식&lt;/strong&gt;이다.&lt;/p&gt;

&lt;p&gt;큐는 한쪽 끝에서 추가가, 다른 쪽 끝에서는 삭제가 발생한다.&lt;/p&gt;

&lt;h4&gt;
  
  
  Queue - Front
&lt;/h4&gt;

&lt;p&gt;삭제 연산이 수행되는 곳을 프론트(Front)라고 한다.&lt;br&gt;
이때, Front에서 수행되는 &lt;strong&gt;삭제 연산을 디큐(dnQueue)&lt;/strong&gt;라고 한다.&lt;/p&gt;

&lt;h4&gt;
  
  
  Queue - Rear
&lt;/h4&gt;

&lt;p&gt;삽입 연산이 수행되는 곳을 리어(Rear)라고 한다.&lt;br&gt;
이때, Rear에서 수행되는 &lt;strong&gt;삽입 연산을 인큐(enQueue)&lt;/strong&gt;라고 한다.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;큐의 데이터들은 Rear로 들어와 Front로 나가고,&lt;br&gt;
Front에 있는 데이터는 가장 먼저 들어온 데이터고,&lt;br&gt;
Rear에 있는 데이터는 가장 늦게 들어온 데이터이다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Queue - Ex)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;프로세스 관리&lt;/li&gt;
&lt;li&gt;BFS(너비 우선 탐색) 구현&lt;/li&gt;
&lt;li&gt;은행 업무&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Stack
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aUBMOHhP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vkgfctkwveb072hnlqtt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aUBMOHhP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vkgfctkwveb072hnlqtt.png" alt="Image description" width="478" height="443"&gt;&lt;/a&gt;&lt;br&gt;
스택은 &lt;strong&gt;쌓아 올린다&lt;/strong&gt; 라는 의미를 가지고 있다.&lt;/p&gt;

&lt;p&gt;책을 쌓는 것처럼 쌓아올리는 형태의 자료구조이다.&lt;br&gt;
따라서 위 사진처럼, 정해진 한 방향으로만 쌓을 수 있고&lt;br&gt;
그 곳을 통해서만 데이터에 접근이 가능하다.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stack - Top
&lt;/h4&gt;

&lt;p&gt;큐는 들어오고 나가는 방향이 다르지만,&lt;br&gt;
스택은 한 방향에서 들어오고 나간다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;이를 Top이라 한다.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;방향이 하나라,&lt;br&gt;
가장 먼저 들어온 데이터는 맨 마지막에 나가게 되고,&lt;br&gt;
가장 늦게 들어온 데이터가 가장 먼저 나가게 된다.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;따라서 후입선출인 &lt;strong&gt;LIFO(Last In, First Out)방식&lt;/strong&gt;을 따른다.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stack - Ex)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;웹 브라우저 방문기록(뒤로가기)&lt;/li&gt;
&lt;li&gt;실행 취소(Undo)&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>algorithms</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>[ Python ] - Iterator &amp; Generator</title>
      <dc:creator>Minho Lee</dc:creator>
      <pubDate>Thu, 10 Mar 2022 06:38:57 +0000</pubDate>
      <link>https://dev.to/devamos/python-iteratorwa-generator-g61</link>
      <guid>https://dev.to/devamos/python-iteratorwa-generator-g61</guid>
      <description>&lt;p&gt;최근에 &lt;strong&gt;Iterable, Iterator, Generator&lt;/strong&gt;에 대해 공부를 했는데,&lt;br&gt;
도대체 어떻게 정리를 하고 글을 써야 할지 몰라서 거의 일주일은 미룬 것 같다.&lt;/p&gt;

&lt;p&gt;그런데 이렇게 미루다 간 평생 못쓸 것 같아 일단 두서없이 쓰더라고 일단 그냥 써보려고 한다.&lt;/p&gt;

&lt;p&gt;쓰다 보면 내가 어느 부분을 잘 알고 어느 부분을 잘 모르는지 알 거라 생각했다.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Iterable&lt;/strong&gt; : 반복이 가능한 모든 객체를 의미한다.&lt;br&gt;
쉽게 말해, for in 구문에서 in 뒤에 올 수 있는 모든 값은 Iterable 하다고 할 수 있다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Iterator&lt;/strong&gt; : 요소가 여러 개인 데이터 타입에서 각 요소를 하나씩 꺼내어 어떠한 처리를 수행할 수 있도록 도와주는 &lt;strong&gt;객체&lt;/strong&gt;이다.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Generator&lt;/strong&gt; : Iterator의 한 종류이다. 하나의 요소를 꺼내려고 할 때마다 요소 Generator를 수행한다. Python에서는 주로 yield 문으로 구현한다.&lt;/p&gt;

&lt;p&gt;Generator는 모든 데이터를 가지고 와서 사용하지 않는다. 그때그때 yield에 의해 하나씩 가져와서 사용한다. 그래서 메모리의 효율성이 좋다는 것이다.&lt;/p&gt;

&lt;p&gt;뭔 소리인가? 일단 코드부터 살펴보자.&lt;/p&gt;



&lt;h2&gt;
  
  
  메모리 크기 비교
&lt;/h2&gt;

&lt;p&gt;하나는 List Comprehension을 이용해 10만의 크기를 가진 리스트를 생성, 남은 하나는 Generator 객체를 만들 것이다.&lt;/p&gt;

&lt;h3&gt;
  
  
  size.py
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="c1"&gt;# Function Version
&lt;/span&gt;&lt;span class="n"&gt;my_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_list&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getsizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_list&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bytes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Generator Version
&lt;/span&gt;&lt;span class="n"&gt;my_gen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_gen&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getsizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_gen&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bytes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&amp;lt;class &lt;span class="s1"&gt;'list'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 800984 bytes
&amp;lt;class &lt;span class="s1"&gt;'generator'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 112 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;크기가 1일 땐, 88과 112로 my_list가 더 작다.&lt;br&gt;
하지만 크기가 커질수록 점점 차이가 나며, 위처럼 크기가 10만이라면 my_list의 크기는 800984 bytes가 나오게 된다.&lt;/p&gt;

&lt;p&gt;my_gen의 크기는 크기가 몇이든 항상 112 bytes이다.&lt;br&gt;
10만의 크기를 기준으로 약 8,000배의 차이가 난다.&lt;/p&gt;

&lt;p&gt;위에 Generator는 모든 데이터를 가지고 오지 않는다고 했는데, 위 예제를 한 번 더 보면 my_list라는 변수에는 크기가 10만 개인 리스트가 메모리에 올라가 있다.&lt;/p&gt;

&lt;p&gt;하지만 my_gen이라는 변수는 Generator 객체이다. 이미 10만 개의 크기를 갖고 있는 것이 아니라 그때그때 하나씩 가져와서 쓰는 친구이다.&lt;/p&gt;

&lt;p&gt;위에서도 언급했지만, Generator는 Iterator의 한 종류이고, Iterator는 요소를 하나씩 꺼내어 어떠한 작업을 수행할 수 있도록 도와준다.&lt;/p&gt;

&lt;p&gt;그리고 예를 들어 일반적인 for 문은 모든 요소를 다 돌아야지만 작업이 끝나고 다른 작업을 할 수 있는데, Generator는 한 번 yield로 반환 후, 다른 작업을 할 수 있다.&lt;/p&gt;



&lt;h2&gt;
  
  
  속도 비교
&lt;/h2&gt;

&lt;p&gt;10만 개의 크기를 가진 피보나치수열을 리스트로 생성 후, 하나씩 총 10만 번을 출력하는 코드를 작성하려고 한다.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;하나는 일반 함수로 10만 개의 크기를 가진 피보나치수열을 리스트로 생성할 것이고 for 문을 통해 출력한다.&lt;/li&gt;
&lt;li&gt;하나는 Generator를 이용할 것이다.&lt;/li&gt;
&lt;li&gt;모든 출력은 pass로 대체한다.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  time.py
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="c1"&gt;# Function Version
&lt;/span&gt;&lt;span class="n"&gt;start_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;


&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="n"&gt;end_func&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Function time = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end_func&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="c1"&gt;# Generator Version
&lt;/span&gt;&lt;span class="n"&gt;start_gen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
        &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;


&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;fibonacci&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="n"&gt;end_gen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Generator time = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end_gen&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start_gen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Function &lt;span class="nb"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  0.3048691749572754
Generator &lt;span class="nb"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  0.13507723808288574
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;위 예제를 통해 알 수 있듯이, 속도에 있어서 큰 차이를 보인다. 100만 개의 크기도 테스트를 해봤는데, 크기가 클수록 더 차이게 크게 난다.&lt;/p&gt;

&lt;p&gt;왜 속도의 차이가 날까?&lt;/p&gt;

&lt;p&gt;일반적인 방법으로는 하나하나 리스트에 담고 마지막에 for 문을 돌려가며 출력을 한다.&lt;/p&gt;

&lt;p&gt;하지만 Generator를 이용하면 list에 담지 않아도 된다.&lt;br&gt;
굳이 어느 메모리에 리스트를 올려두지 않아도 Generator가 하나하나씩 가져와서 출력을 하기 때문이다.&lt;/p&gt;

&lt;h2&gt;
  
  
  정리
&lt;/h2&gt;

&lt;p&gt;Generator를 이용하면 메모리를 효율적으로 사용할 수 있다.&lt;br&gt;
물론 항상 그런 것은 아니다.&lt;/p&gt;

&lt;p&gt;그리고 DB Session과 같이 많이 반복되거나 끝이 없는 작업을 할 때 Generator를 사용하면 매우 좋을 것 같다.&lt;/p&gt;

&lt;p&gt;아직 많이 부족하다. 하지만 항상 생각하고 더 좋은 코드를 짜려고 노력해야 더 좋은 개발자가 될 수 있다.&lt;/p&gt;

</description>
      <category>python</category>
      <category>computerscience</category>
      <category>algorithms</category>
    </item>
  </channel>
</rss>
