<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>점을 찍어가며</title>
    <link>https://wonstudy.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 5 Jul 2026 04:14:29 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>JiWonSon</managingEditor>
    <image>
      <title>점을 찍어가며</title>
      <url>https://tistory1.daumcdn.net/tistory/4297823/attach/c8586d37756e4293b189f83bdc0c60b1</url>
      <link>https://wonstudy.tistory.com</link>
    </image>
    <item>
      <title>[Python] GIL</title>
      <link>https://wonstudy.tistory.com/71</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1)GIL이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GIL은 파이썬 인터프리터에 한 갱의 Thread가 하나의 바이트 코드를 실행할 수 있도록 걸어두는 Lock이다.&lt;br /&gt;하나의 Thread는 파이썬 인터프리터의 모든 자원을 사용하나, 다른 사용할 수 없도록 Lock을 걸어둔다는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시)&lt;/p&gt;
&lt;pre id=&quot;code_1695198223324&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import threading
x = 0
 
def foo():
    global x
    for _ in range(1000000):
        x += 1
 
def bar():
    global x
    for _ in range(1000000):
        x += 1
 
thread1 = threading.Thread(target=foo)
thread2 = threading.Thread(target=bar)
 
thread1.start()
thread2.start()
 
thread1.join()
thread2.join()
print(x)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 x라는 공유된 변수에 thread1과 thread2가 동시에 접근해서 1씩 더하는 코드이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 제각각이겠지만 2000000이 출력되어야 하는데 위 출력 결과는 1310848값이 출력된다.&lt;br /&gt;이는 공유도니 변수에 두 쓰레드가 동시에 접근하면서 발생된 문제이다.&lt;br /&gt;x += 1은 x=x_1이 축약된 문장인데, 우항의 x에 값을 대입하는 과정 중 다른 쓰레드가 값을 변경하면 이후 좌변의 x에 값을 대입할 땐 중간결과가 무시된다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;요약하자면,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) Thread1 : x값 조회중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;Thread2 : 다른 작업중&lt;br /&gt;2) Thread1 : x값 1더함&lt;br /&gt;&amp;nbsp; &amp;nbsp; Thread2 : x 값 조회&lt;br /&gt;3) Thread1 : x 값 할당&lt;br /&gt;&amp;nbsp; &amp;nbsp; Thread2 : x 값 1더함&lt;br /&gt;4) Thread1: 다른 작업중&lt;br /&gt;&amp;nbsp; &amp;nbsp; Thread2:&amp;nbsp; x 값 할당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이렇다.&lt;br /&gt;즉, 여러 쓰레드가 하나의 공유 자원이 동시에 접근하면서 발생하는 문제를 race condition(경쟁상태)라고 하며, 이 문제를 해결하기 위해 Mutex의 방안이 있다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&amp;nbsp;Mutex는 이렇게 공유 자원에 하나의 쓰레드만 진입하며 작업을 처리할 수 있도록 만들어진 lock 개념이다. 간단히 비유하자면 한 사람만 이용할 수 있는 공중화장실은 출입문의 잠금장치를 열어야 이용이 가능하며 사람들은 줄 따위 서지 않고 호시탐탐 출입문을 노리고 있는 상황을 가정하자. 이용하고자 대기 중인 여러 사람이 Thread이고 화장실 시설이 resource, 화장실 출입문이 mutex, 화장실 출입문의 잠금장치가 lock이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2)파이썬은 멀티쓰레드 언어인가&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;* 싱글스레드언어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드가 하나인 언어로 javascript가 대표적이다.&lt;br /&gt;파이썬도 병렬 처리를 위한 쓰레드를 갖고있긴하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;운영체제가 cpu에 파이썬 스레드의 job을 할당하려면 커널레벨스레드(Native Thread)와 파이썬의 스레드를 1:1로 매핑시켜야하는데, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;파이썬은 GIL이라는 lock때문에 커널레벨 스레드는 파이썬의 하나의 프로세스와 매핑된다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;코드상의 로직은 동시에 진행되는것 같지만 하나의 cpu가 빠르게 왔다갔다하면서 스레드를 처리한다고 생각하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파이썬은 멀티스레드언어로 불리기보다는 싱글스레드언어, 싱글코어 언어 등 동시에 하나의 CPU만 사용하는 언어로 불린다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;파이썬은 GIL때문에 하나의 프로세스가 동시에 하나의 코어밖에 사용하지 못하는 언어이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;* 멀티스레드언어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스레드가 여러개인 언어로 java, c# 등이 있다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;멀티스레드언어는 운영체제가 스레드의 작업을 여러개의 cpu에 직접 할당할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3) CPU 사용량&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를들어 8개의 스레드를 만들어 작업한다 가정하면,&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;멀티스레드 언어는 8개 코어를 비슷하게 사용하고&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;싱글스레드 언어(파이썬)는 하나의 코어만 사용해서 1개의 코어의 사용량만 올라가고 아래와 같은 결과가 나온다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 멀티쓰레드 환경&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;390&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDqNwf/btsuQkojEHp/NFW0KtfrInQq7QazB0gaZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDqNwf/btsuQkojEHp/NFW0KtfrInQq7QazB0gaZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDqNwf/btsuQkojEHp/NFW0KtfrInQq7QazB0gaZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDqNwf%2FbtsuQkojEHp%2FNFW0KtfrInQq7QazB0gaZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;239&quot; height=&quot;390&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;390&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/S9jOJ/btsu0GwNrcT/2YIO2KlcwI3StmfZq5nBXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/S9jOJ/btsu0GwNrcT/2YIO2KlcwI3StmfZq5nBXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/S9jOJ/btsu0GwNrcT/2YIO2KlcwI3StmfZq5nBXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FS9jOJ%2Fbtsu0GwNrcT%2F2YIO2KlcwI3StmfZq5nBXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;387&quot; height=&quot;267&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 싱글쓰레드 환경&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;333&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqxUex/btsu0p9ItWp/sXf9wZwzXLCCn8dG5vOig1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqxUex/btsu0p9ItWp/sXf9wZwzXLCCn8dG5vOig1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqxUex/btsu0p9ItWp/sXf9wZwzXLCCn8dG5vOig1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqxUex%2Fbtsu0p9ItWp%2FsXf9wZwzXLCCn8dG5vOig1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;250&quot; height=&quot;333&quot; data-origin-width=&quot;676&quot; data-origin-height=&quot;333&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;716&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beFRKc/btsuPND4tke/2zikZu858E6GHWnp8wn121/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beFRKc/btsuPND4tke/2zikZu858E6GHWnp8wn121/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beFRKc/btsuPND4tke/2zikZu858E6GHWnp8wn121/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeFRKc%2FbtsuPND4tke%2F2zikZu858E6GHWnp8wn121%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;405&quot; height=&quot;280&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;716&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제는 여러 종류의 인터럽트를 걸며 하나의 프로세스를 위해 일하더라도&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;여러 코어를 사용하여 작업을 처리한다. CPU 사용량에서 c#(멀티쓰레드 환경)이 우위를 점하는데,&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;c#으로 작성한 프로그램에서는 cpu사용량이 평균적으로 60~70이 나왔고&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;python으로 작성한 프로그램에서는 cpu사용량이 평균적으로 40~50이 나왔다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;(동일한 일을 하는데 CPU사용량이 높다는건 상대적으로 빠르게 일을 처리한다고 볼 수 있다.)&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4) cpu사용량이 생각과 다르게 나온 이유&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;운영체제가 cpu는 하나의 프로세스를 위해 일을 하더라도 여러 코어로 왔다갔다 하며 일을 하게 된다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;파이썬은 GIL(Global Interpreter Lock)이 존재하며 동시에 하나의 코어에서만 일을 하는 언어이다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이 말은 즉, 빠르게 여러개의 코어를 왔다갔다하는 방식으로 cpu를 사용한다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;스레드를 아무리 쪼개봐야 cpu를 동시에 사용하지 못한다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;(운영체제에는 여러가지 프로세스가 돌고있고 인터럽트들가 발생하고 커널의 레디큐에 있는 작업들은 잠시 CPU를 쓰고 timeout interrupt에 걸리는데 이때 운영체제의 스케줄링 방식이 하나의 코어에만 계속 요청을 하지는 않는다.)&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;c#, java등의 스레드는 여러개의 커널레벨 스레드를 사용하므로 운영체제가 여러개의 CPU에 스케줄링 한다.&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이론상 8개의 코어에 동일한작업이 하나씩 할당 돼야 하지만 운영체제는 이미 많은 프로세스가 돌아가고있고 운영체제의 복잡한 스케줄링기법에 따라 스케줄링 되고 컨텍스트 스위칭이 일어날 것이다.(CPU의 6번과 8번 스레드는 상대적으로 놀고있다)&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #555555; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그래도 여러 CPU에 스케줄링하니 동시에 CPU를 사용할수 있어 CPU사용량도 높게나올뿐만 아니라 스레드는 공유하는 영역이 많아 캐시 데이터를 많이 사용할수 있어 그래프가 훨씬 평온한것을 확인할 수 있다.(아래측(python)은 그래프가 요동친다.)&lt;/p&gt;</description>
      <category>개발언어/Python</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/71</guid>
      <comments>https://wonstudy.tistory.com/71#entry71comment</comments>
      <pubDate>Wed, 20 Sep 2023 17:40:54 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] 빌드 관리 도구</title>
      <link>https://wonstudy.tistory.com/70</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 빌드 관리 도구?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 빌드는 소스코드가 적혀있는 파일을 컴퓨터에서 실행할 수 있는 독립적인 형태로 변환하는 과정을 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 .java, .xml, properties 등의 파일을 jvm이나 톰캣같은 was서버가 인식할 수 있도록 변환해주는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 관리 도구는 소스 코드가 빌드 하는 과정에서 여러가지 외부 라이브러리를 사용하는데, 빌드 관리 도구는 사용자가 관리할 필요 없이 필요한 라이브러리들을 자동으로 관리해주는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크게 Ant, Maven, Gradle 세 가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 관리 도구의 과정은 아래와 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;종속성 다운로드&amp;nbsp;&lt;/li&gt;
&lt;li&gt;소스코드를 바이너리 코드로 컴파일&lt;/li&gt;
&lt;li&gt;바이너리 코드 패키징&lt;/li&gt;
&lt;li&gt;테스트 실행&lt;/li&gt;
&lt;li&gt;시스템에 배포&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. Maven&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(1) maven이란?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- Maven은 Java용 프로젝트 관리 도구로써, Lifecycle 관리 목적 빌드 도구이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;프로젝트를 진행할 때, 단순히 내가 작성한 코드로만 개발하는 것이 아니라 여러 라이브러리를 활용해서 개발할 때가 많다. 이 때 사용되는 라이브러리들의 수가 너무 많아지면 관리하는 일이 힘든데, Maven은 이러한 문제를 해결할 수 있다. Maven은 내가 사용할 라이브러리 뿐만 아니라 해당 라이브러리가 작동하는데 필요한 다른 라이브러리까지 다운로드해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Maven은 필요한 라이브러리를 전부 pom.xml에 정의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 플러그인을 통한 재사용 : Maven은 빌드에 대한 대부분의 책임을 플러그인에 위임한다. 플러그인들은 Maven저장소에 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2) maven 빌드 과정&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csuM4b/btsplPVeaEL/FQUhSgBDayevj05lAKJNy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csuM4b/btsplPVeaEL/FQUhSgBDayevj05lAKJNy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csuM4b/btsplPVeaEL/FQUhSgBDayevj05lAKJNy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsuM4b%2FbtsplPVeaEL%2FFQUhSgBDayevj05lAKJNy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;569&quot; height=&quot;332&quot; data-origin-width=&quot;569&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f8f9fa; color: #212529; text-align: left;&quot;&gt;* clean - validate - compile - test - package - verify - install - site - deploy ( 위에서 말한 과정과 같다)&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;Clean&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 이전 빌드에서 생성된 파일들을 삭제하는 단계&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;Validate&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 프로젝트가 올바른지 확인하고 필요한 모든 정보를 사용할 수 있는 지 확인하는 단계&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;Compile&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 프로젝트의 소스코드를 컴파일하는 단계&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;Test&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 유닛(단위) 테스트를 수행하는 단계&lt;b&gt;(테스트 실패시 빌드 실패로 처리, 스킵 가능)&lt;/b&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;Package&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 실제 컴파일된 소스 코드와 리소스들을 jar등의 배포를 위한 패키지로 만드는 단계&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;Verify&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 통합테스트 결과에 대한 검사를 실행하여 품질 기준을 충족하는지 확인하는 단계&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;Install&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 패키지를 로컬 저장소에 설치하는 단계&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;Site&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 프로젝트 문서를 생성하는 단계&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;Deploy&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 만들어진 Package를 원격 저장소에 release하는 단계&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(3) maven설정 파일인 pom.xml (Project Object Model) 의 주요 기능&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;프로젝트 정보&amp;nbsp;&lt;/li&gt;
&lt;li&gt;빌드 설정&lt;/li&gt;
&lt;li&gt;빌드 환경&lt;/li&gt;
&lt;li&gt;pom 연관 정보&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. Gradle&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(1) Gradle이란?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Maven을 대체할 수 있는 프로젝트 구성 관리 및 빌드 관리 도구이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 빌드 속도가 Maven에 비해 10~100배 가량 빠르다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;332&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bipRDl/btspkLFMmlN/XDnu4ywmKG7vLjeJakSK31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bipRDl/btspkLFMmlN/XDnu4ywmKG7vLjeJakSK31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bipRDl/btspkLFMmlN/XDnu4ywmKG7vLjeJakSK31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbipRDl%2FbtspkLFMmlN%2FXDnu4ywmKG7vLjeJakSK31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;332&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;332&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스프링부트와 안드로이드에서 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Java, C/C++, Python 등의 언어를 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- maven은 xml로 라이브러리를 정의하고 활용하지만, gradle은 별도 스크립트를 작성한다. 이 스크립트는 groovy script를 기반으로 구축되어 있으며, xml과 달리 변수 선언, if, else, for 등의 로직이 구현가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2) gradle 빌드 과정&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; background-color: #ffffff; color: #000000; text-align: left;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;초기화(initialization) :&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;빌드 대상 프로젝트를 결정하고 각각에 대한 Project객체를 생성한다. settings.gradle 파일에서 프로젝트 구성한다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;구성(Configuration) :&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;빌드 대상이 되는 모든 프로젝트의 빌드 스크립트를 실행한다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: decimal;&quot;&gt;&lt;b&gt;실행(Execution) :&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;구성 단계에서 생성하고 설정된 프로젝트의 태스크 중에 실행 대상을 결정한다. gradle 명령행에서 지정한 태스크 이름 인자와 현재 디렉토리를 기반으로 태스크를 결정하여 선택된 태스크들을 실행한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(3) gradle 설정 파일&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- build.gradle : 빌드에 대한 모든 기능을 정의함. 환경 설정, 빌드 방법, 라이브러리 정보 등 프로젝트 관리 환경을 구성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- setting.gradle : 프로젝트 구성을 설정할 때 작성, 프로젝트간의 의존성, 멀티 프로젝트 시 작성한다. 프로젝트가 하나일 경우 생략 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;의존성이 늘어날 수록 품질의 차이가 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;maven은 멀티 프로젝트 환경에서 특정 설정을 다른 모듈에서 사용하려면 상속을 받아야 하지만, gradle은 설정 주입 방식을 사용한다. 따라서 멀티 프로젝트일 경우 gradle이 더 적합한 방식이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 프로젝트 상황에 따라 빌드 도구를 잘 선택해야 한다.&lt;/p&gt;</description>
      <category>FrameWork/Spring</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/70</guid>
      <comments>https://wonstudy.tistory.com/70#entry70comment</comments>
      <pubDate>Mon, 31 Jul 2023 11:34:32 +0900</pubDate>
    </item>
    <item>
      <title>[Docker] Docker 동작 원리</title>
      <link>https://wonstudy.tistory.com/69</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. Docker의 구조&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물리서버 &amp;gt; 리눅스 운영체제 &amp;gt; 도커 엔진 &amp;gt; 컨테이너&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpdJZf/btsnoHDJ8Wd/qvCUMrR1yH0AdeIyHgDBHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpdJZf/btsnoHDJ8Wd/qvCUMrR1yH0AdeIyHgDBHk/img.png&quot; data-alt=&quot;출처 : 그림과 실습으로 배우는 도커&amp;amp;amp;쿠버네티스 -오가사와라 시게타카&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpdJZf/btsnoHDJ8Wd/qvCUMrR1yH0AdeIyHgDBHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpdJZf%2FbtsnoHDJ8Wd%2FqvCUMrR1yH0AdeIyHgDBHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;240&quot; data-origin-width=&quot;384&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 그림과 실습으로 배우는 도커&amp;amp;쿠버네티스 -오가사와라 시게타카&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도커와 컨테이너는 서버에서 사용되며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림과 같이 운영체제 위에 도커가 위치해있다. 또, 그 도커 위에 컨테이너가 위치해있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 컨테이너 안에는 어떤 구조로 되어있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 컨테이너는 '리눅스 운영체제 비슷한 무언가'가 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본래 운영체제는 '커널'과 '그 외 주변 부분'으로 이루어져있는데, 이 컨테이너 안에 '그 외 주변 부분'이 들어있는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 도커와 컨테이너는 완전히 분리되어 있어서 밑바탕인 리눅스 운영체제의 주변 부분이 컨테이너 속 프로그램 명령을 직접적으로 전달을 주고 받을 수 없다. 무조건 도커 엔진을 커져야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이처럼 그 외 주변 부분만 컨테이너가 담고 있고, 커널은 밑바탕에 있는 것들을 빌려 쓰는 형태이기 때문에 도커는 '가볍다'는 특징을 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 도커는 '리눅스' 운영체제에서만 동작할 수 있으므로, Windows, MacOS에서는 Hypervisor를 설치하여 VM으로 리눅스 운영체제를 생헝하여 설치하는 등 도커를 실행하는데 필요한 리눅스 운영체제가 꼭 필요하다. (아래 그림 참조)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;223&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bB2xzJ/btsnpGj86YX/WBKX0meJtARO0kwMTNTB3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bB2xzJ/btsnpGj86YX/WBKX0meJtARO0kwMTNTB3K/img.png&quot; data-alt=&quot;출처 : 그림과 실습으로 배우는 도커&amp;amp;amp;쿠버네티스 -오가사와라 시게타카&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bB2xzJ/btsnpGj86YX/WBKX0meJtARO0kwMTNTB3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbB2xzJ%2FbtsnpGj86YX%2FWBKX0meJtARO0kwMTNTB3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;432&quot; height=&quot;223&quot; data-origin-width=&quot;432&quot; data-origin-height=&quot;223&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 그림과 실습으로 배우는 도커&amp;amp;쿠버네티스 -오가사와라 시게타카&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. Docker 허브와 이미지, 컨테이너&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도커 이미지 :&amp;nbsp; 컨테이너를 만드는 틀&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도커 허브 : 인터넷 상에 도커 이미지를 모아놓은 곳&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구체적으로, 이미지는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 컨테이너의 설계도 역할을 담당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이미지를 사용하면 컨테이너를 여러개 생성하는 것이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 이미지로 컨테이너를 생성하는 것이 가능하고, 컨테이너로 이미지를 생성하는 것이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 컨테이너는 도커 엔진만 설치되어 있으면 구동이 가능하여 다른 서버에 도커 엔진을 설치하고 새로운 도커 엔진에 이미지를 올리면 똑같은 컨테이너를 생성할 수 있다. (아래 그림 참조)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;223&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkygZv/btsnj8v0OcV/v2HpaiL9mQwTarjpzOUSpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkygZv/btsnj8v0OcV/v2HpaiL9mQwTarjpzOUSpk/img.png&quot; data-alt=&quot;출처 : 그림과 실습으로 배우는 도커&amp;amp;amp;쿠버네티스 -오가사와라 시게타카&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkygZv/btsnj8v0OcV/v2HpaiL9mQwTarjpzOUSpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkygZv%2Fbtsnj8v0OcV%2Fv2HpaiL9mQwTarjpzOUSpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;512&quot; height=&quot;223&quot; data-origin-width=&quot;512&quot; data-origin-height=&quot;223&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 그림과 실습으로 배우는 도커&amp;amp;쿠버네티스 -오가사와라 시게타카&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 공개된 컨테이너 이미지가 모여 있는 '도커 허브'란 곳에서 원하는 컨테이너 이미지를 다운받을 수 있으며, 누구든지 이미지를 등록하고 사람들과 공유할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 도커 허브에서는 리눅스 배포판들의 버전별 이미지를 포함하여, 소프트웨어 회사에서 제공하는 공식 컨테이너 이미지(Apach, MYSQL, ...)도 다운할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 도커를 사용하여 각각의 소프트웨어를 구성하여 구축한 예시 (한 컨테이너에 모두 집어넣거나, 별도의 컨테이너로 구성할 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;258&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YBcLZ/btsnjckMkXp/xKK9HiBRQgNU610HKUyLzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YBcLZ/btsnjckMkXp/xKK9HiBRQgNU610HKUyLzK/img.png&quot; data-alt=&quot;출처 : 그림과 실습으로 배우는 도커&amp;amp;amp;쿠버네티스 -오가사와라 시게타카&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YBcLZ/btsnjckMkXp/xKK9HiBRQgNU610HKUyLzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYBcLZ%2FbtsnjckMkXp%2FxKK9HiBRQgNU610HKUyLzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;525&quot; height=&quot;258&quot; data-origin-width=&quot;525&quot; data-origin-height=&quot;258&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 : 그림과 실습으로 배우는 도커&amp;amp;쿠버네티스 -오가사와라 시게타카&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 도커를 사용할 때 '한 컨테이너에 한 프로그램'이라는 원칙이 있다. 보안과 유지 관리 측면에서 유리하기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;i) 운영체제? 소프트웨어나 프로그램의 명령을 하드웨어에 전달하는 역할&lt;/p&gt;</description>
      <category>DevOps/Docker</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/69</guid>
      <comments>https://wonstudy.tistory.com/69#entry69comment</comments>
      <pubDate>Wed, 12 Jul 2023 17:56:15 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크] 동기화 예제</title>
      <link>https://wonstudy.tistory.com/68</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 사용자모드와 커널 모드&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1.1) 사용자 주소 공간과 커널 주소 공간을 분리하는 이유는?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운영체제는 컴퓨터 전체 메모리를 사용자 공간과 커널 공간으로 나누는데 사용자 공간은 응용 프로그램을 탑재하고 사용되는 공간이고, 커널 공간은 디바이스 드라이버를 포함하여 커널 코드가 탑재된다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이유는&lt;u&gt; 커널 공간에 있는 코드와 데이터를 보호하기 위해 분리한다.&lt;/u&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1-2) 사용자 모드, 커널 모드가 구체적으로 뭔데?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 모드에서 응용프로그램 코드가 실행되고, 커널 모드에서 커널 코드가 실행된다.&lt;br /&gt;둘을 나누는 이유는 데이터에 접근하기 어렵게 만드는 것이다.&lt;br /&gt;또한, 사용자 공간은 분리되지만, 커널 공간은 공유된다는 특징이 있다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 동기화 기법&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-1) 유저 모드 동기화&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #666666; text-align: left;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;커널의 힘을 빌리지 않는(커널 코드가 실행되지 않는) 동기화 기법&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;성능상의 이점, 기능상의 제한(라이브러리를 이용)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;종류&lt;/span&gt;&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;크리티컬 섹션 기반 동기화&lt;/b&gt;&lt;br /&gt;- 메모리 접근 동기화에 사용. 임계영역 객체(Key)를 만들고 초기화해야 함(반드시 거쳐야 하는 과정)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;인터락 함수 기반 동기화&lt;/b&gt;&lt;br /&gt;- 메모리 접근 동기화에 사용. 함수 내부적으로 한 순간에 하나의 스레드에 의해서만 실행되도록 동기화. 전역으로 선언된 변수 하나의 접근 방식을 동기화하는 것이 목적일 경우 사용&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-2) 커널 모드 동기화&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #666666; text-align: left;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;커널에서 제공하는 동기화 기능을 활용하는 방법&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;커널 모드로의 변경이 필요하므로 성능 저하, 다양한 기능 활용 가능&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기능상 우수, 속도 떨어짐&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;각 프로세스들 안의 스레드들끼리의 동기화도 가능&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;종류&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;뮤텍스 기반의 동기화&lt;/b&gt;&lt;br /&gt;- 메모리 접근 동기화에 사용. 키의 취득과 반납이 이루어짐&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;세마포어 기반의 동기화&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 메모리 접근 동기화에 사용. 카운트를 셈&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;이름 있는 뮤텍스 기반의 동기화&lt;/b&gt;&lt;br /&gt;- 프로세스간 동기화에 사용. 프로세스 동기화를 하기 위해서 뮤텍스를 동기화해야 하는데 커널 오브젝트는 각각 프로세스에 독립적이므로 뮤텍스에 이름 붙여서 접근&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: inherit; color: #666666;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;이벤트 기반의 동기화&lt;/b&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 실행순서 동기화에 사용&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[뮤텍스]&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;164&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBvDUe/btr5nMp65vz/MXN7NCtTah0YMUn9mZB4l0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBvDUe/btr5nMp65vz/MXN7NCtTah0YMUn9mZB4l0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBvDUe/btr5nMp65vz/MXN7NCtTah0YMUn9mZB4l0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBvDUe%2Fbtr5nMp65vz%2FMXN7NCtTah0YMUn9mZB4l0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;164&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;164&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[세마포어]&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYm6yh/btr5pyqJZfx/MeLhEOEKkTcYjs4Sr3hedk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYm6yh/btr5pyqJZfx/MeLhEOEKkTcYjs4Sr3hedk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYm6yh/btr5pyqJZfx/MeLhEOEKkTcYjs4Sr3hedk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYm6yh%2Fbtr5pyqJZfx%2FMeLhEOEKkTcYjs4Sr3hedk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;650&quot; height=&quot;287&quot; data-origin-width=&quot;650&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Computer science/네트워크</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/68</guid>
      <comments>https://wonstudy.tistory.com/68#entry68comment</comments>
      <pubDate>Wed, 22 Mar 2023 17:56:42 +0900</pubDate>
    </item>
    <item>
      <title>[Design Pattern] 템플릿 메소드 패턴</title>
      <link>https://wonstudy.tistory.com/67</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 템플릿 메소드 패턴이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #000000;&quot;&gt;&amp;nbsp;알고리즘의 골격을 정의한다. 템플릿 메소드를 사용하면 알고리즘의 일부 단계를 서브클래스에서 구현할 수 있으며, 알고리즘 구조는 그대로 유지하면서 알고리즘의 특정 단계를 서브클래스에서 재정의할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #000000;&quot;&gt;&quot;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;알고리즘의 틀을 만들기 위한 패턴&quot;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #fcfcfc;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;2. 예시&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #fcfcfc; color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;1) 커피와 홍차가 만들어지는 법 비교해보기&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677976907998&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. 커피 만드는 법

1) 물을 끓인다.

2) 끓는 물에 커피를 우려낸다.

3) 커피를 컵에 따른다.

4) 설탕과 우유를 추가한다.



2. 홍차 만드는 법

1) 물을 끓인다.

2) 끓는 물에 차를 우려낸다.

3) 차를 컵에 따른다.

4) 설탕을 추가한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;여기서 음료를 준비하는 단계는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;u&gt;물 끓이기 &amp;rarr; 우리기 &amp;rarr; 컵에 붓기 &amp;rarr; 첨가물 추가하기&lt;/u&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;순으로 이루어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;아래 클래스를 보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677977027835&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Coffee {

	void prepareRecipe() {

		boilWater();

		brewCoffeeGrinds();

		pourInCup();

		addSugarAndMilk();

	}

	public void boilWater() {

		System.out.println(&quot;물 끓이는 중&quot;);

	}

	public void breqCoffeeGrinds() {

		System.out.println(&quot;필터를 통해 커피를 우려내는 중&quot;);

	}

	public void pourInCup() {

		System.out.println(&quot;컵에 따르는 중&quot;);

	}

	public void addSugarAndMilk() {

		System.out.println(&quot;설탕과 우유를 추가하는 중&quot;);

	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1677977062156&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Tea {

	void prepareRecipe() {

		boilWater();

		steepTeaBag();

		pourInCup();

		addSugar();

	}

	public void boilWater() {

		System.out.println(&quot;물 끓이는 중&quot;);

	}

	public void steepTeaBag() {

		System.out.println(&quot;차를 우려내는 중&quot;);

	}

	public void pourInCup() {

		System.out.println(&quot;컵에 따르는 중&quot;);

	}

	public void addLemon() {

		System.out.println(&quot;설탕을 추가하는 중&quot;);

	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;코드가 중복되어 있다. 클래스가&amp;nbsp; 거의 동일하니까, 공통 부분은 추상화 시켜 클래스를 만들어 보자.&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt; 알고리즘의 각 단계는 템플릿 메소드 안에서 메소드로 표현된다. 어떤 메소드는 이 클래스에서, 어떤 메소드는 서브클래스에서 처리되기도 하는데, 서브클래스에서 구현해야 하는 경우에는 메소드를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;abstract&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;로 선언하도록 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;총제적으로 본다면 서로 다른 메소드를 사용하지만, 둘은 서로 별로 다르지 않다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;템플릿 메소드 패턴을 적용해보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677977403519&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public abstract class CaffeineBeverage {

	final void prepareRecipe() {

		boilWater();

		brew();

		pourInCup();

		addcondiments();

	}

	abstract void brew();

	abstract void addcondiments();

	void boilWater() {

		System.out.println(&quot;물 끓이는 중&quot;);

	}

	void pourInCup() {

		System.out.println(&quot;컵에 따르는 중&quot;);

	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677977491281&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Coffee extends CaffeineBeverage {

	@Override
	void brew() {

		System.out.println(&quot;필터를 통해 커피를 우려내는 중&quot;);

	}

	@Override
	public void addCondiments() {

		System.out.println(&quot;설탕과 우유를 추가하는 중&quot;);

	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677977512184&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Tea extends CaffeineBeverage {

	@Override
	void brew() {

		System.out.println(&quot;차를 우려내는 중&quot;);

	}

	@Override
	public void addCondiments() {

		System.out.println(&quot;설탕을 추가하는 중&quot;);

	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차를 만들어 보자!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677977608068&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. Tea 객체를 만들고.

Tea myTea = new Tea();



2. 템플릿 메소드를 호출한다.

myTea.prepareRecipe(); 카페인 음료를 만들기 위한 알고리즘이 돌아간다.



3. 물을 끓인다.

boilWater(); 이 단계는 CaffeineBeverage 에서 처리된다.



4. 이제 차를 우려낸다. 

brew(); 이방법은 서브클래스만 알고있다.



5. 차를 컵에 따른다.

pourInCup(); 이 단계도 공통적인 부분이기 때문에 Caffeinebeverage 에서 맡아서 처리된다.



6. 마지막으로 첨가물을 추가한다.

addCondiments(); 첨가물은 음료마다 다르기때문에 서브클래스에서 처리된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 템플릿 메소드 패턴에서는 알고리즘의 각 단계들을 정의하고, 그 중 몇 개는 서브클래스에 의해 알고리즘을 구체화하여 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 후크(hook) ?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;추상 클래스에서 선언된, 아무 코드도 들어가지 않은 메소드이다. 필요한 경우에만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;구현 클래스에서&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;오버라이드해 입맛에 맞게 수정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1677977761897&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public abstract class CaffeinBeverageWithHook {
    final void prepareRecipe() {
        boilWater();
        brew();
        pourInCup();
        if (customerWantsCondiments()) {
            addCondiments();        
        }
    }
    
    abstract void brew();
    
    abstract void addCondiments();
    
    void boilWater() {
        // ...
    }
    
    void pourInCup() {
        // ...
    }
    
    // 이 메소드가 서브클래스에서 필요에 따라 오버라이드할 수 있는 메소드 이므로 &quot;후크&quot;임
    boolean customerWantsCondiments() {
        return true;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&amp;nbsp;prepareRecipe에서 손님이 첨가물을 넣어 달라고 했을 때만&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #666666;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(customerWantsCondiments가 true를 리턴할 때만)&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;첨가물을 추가하도록 코드를 수정했다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;customerWantsCondiments&lt;/b&gt;는 true만 리턴하는 기본적인 후크 메소드이다. customerWantsCondiments는 필요한 경우에만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;서브클래스에서&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;오버라이드해 첨가물을 추가할지 여부를 입력받는 코드로 수정하여 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 후크와 추상 메소드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;추상 메소드&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;span&gt;서브클래스가 알고리즘 특정 단계를&amp;nbsp;반드시&amp;nbsp;&lt;/span&gt;&lt;span&gt;제공해야 할 때&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;후크&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;서브클래스가 알고리즘 특정 단계를 &lt;/span&gt;선택적으로&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;제공해야 할&lt;/span&gt;&amp;nbsp;때&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Design Pattern</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/67</guid>
      <comments>https://wonstudy.tistory.com/67#entry67comment</comments>
      <pubDate>Sun, 5 Mar 2023 09:59:25 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크]Https 동작과정 ( SSL, TLS, 대칭키, 공개키,CA)</title>
      <link>https://wonstudy.tistory.com/65</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1.HTTPS?&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1-1. 정의&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTPS는 기존 HTTP레이어에서 SSl 또는 TLS프로토콜을 얹어 평문 데이터를 암호화하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호화, 인증, 무결성 보장을 통해 더 안전히 만들어 주는 프로토콜이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1-2. 목적&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL이나 TLS와 같은 프로토콜을 사용하여 인증서를 통해 메시지를 암호화하고, 통신하고자 하는 상대방이 맞는 지 인증하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.SSL과 TLS&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;SSL(Secure Sockets Layer)는 TLS(Transport Layer Security)의 과거 명칭이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, TLS는 SSL을 보다 안전하고, 프로토콜을 더 정확하고 안정성 높이도록 하기 위해 고안되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구체적으로는 TCP,UDP와 같은 일반적인 인터넷 통신에 안전한 Layer(계층)을 추가하는 것이다. 이 기술을 웹 서버에 적용한 것이 우리가 흔히 부르는 SSL/TLS 인증서 라고 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 대칭키, 공개키&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1-1. 대칭키&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대칭키 암호화 방식은 하나의 키로 평문을 암호화하고 다시 암호문을 원래의 평문으로 복호화할 때 사용하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명칭 그대로 키를 단 하나만 사용하는 것, 키가 대칭인 것이 특징이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 암호화 헀던 키가 노출되면 암호가 해제된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1-2. 공개키&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공개키 암호화 방식은 공개키, 개인키 두 개의 키를 한 쌍으로 각각 암호화/복호화에 사용하는 것이다. 일반적으로 공개키로 암호화한 것을 개인키로 복호화한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 공개키가 노출되어도 개인키가 없으면 암호를 해제할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*&amp;nbsp; 공개키 방식은 클라이언트와 서버가 서로 인증하려고 교환하기 위한 키를 암호화하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;대칭키 방식은 서로 인증한 후 메시지를 암호화해서 지속적으로 전송한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. CA 인증기관 (Certificate authority)&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;공개키 방식은 해당 Public Key가 진짜인지 확인 할 수 없다. 따라서 Public Key가 진짜임을 증명해주는 제 3자 기관을 CA라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CA는 아무 기업이나 할 수 있는 것이 아니고 신뢰성이 엄격하게 공인된 기업들만이 참여할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SSL을 통해서 암호화된 통신을 제공하려면 CA를 통해서 인증서를 구입해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 CA가 Public Key라고 인증한 인증서를 SSL인증서라 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. CA 인증과정&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;1-서버---인증-서명-요청서csr-생성&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1. 서버에서 인증 서명 요청서(CSR) 생성&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1-1) Server에서 Public Key와 Private Key를 쌍으로 생성한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;1-2) Server에서 인증 서명 요청서(CRS)를 만든다. (SHA256 같은 해쉬 알고리즘으로 해쉬 수행한다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;2-ca---ssl-인증서-발급&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;2. CA - SSL 인증서 발급&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;3-서버---ssl-인증서를-받음&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;3. 서버 - SSL 인증서 받음&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;4-클라이언트---ssl-handshake의-첫-번째-단계--client-hello&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;4.&amp;nbsp;클라이언트 - SSL Handshake 첫번째 요청&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;4-1) Client가 요청을 하게 되면, 가장 먼저 Server에 3-Way Handshake를 통해 연결을 시도한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&amp;rarr; ex) 브라우저 주소창에서&amp;nbsp;&lt;a href=&quot;http://blog.naver.com&quot;&gt;http://.naver.com&lt;/a&gt;을 치면, HTTP는 TCP의 일종이니 TCP 연결을 위한 3-Way Handshake를 먼저 수행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;4-2) 3-Way Handshake를 연결이 완료되면, 클라이언트가&amp;nbsp;Client Hello&amp;nbsp;단계를 수행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;HTTPS&lt;/b&gt;를 사용하는 것을 알게 된 클라이언트는&amp;nbsp;Client Hello&amp;nbsp;단계에서 밑의 정보를 보낸다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;5-서버---ssl-handshake의-두-번째-단계--server-hello&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;5.&amp;nbsp;서버 - SSL HandShake 두번째 요청&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;5-1) Client가 보내온 Client Hello 패킷을 받아, 밑의 정보를 Client에게 응답한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;- 브라우저가 지원하는 &lt;b&gt;암호화&lt;/b&gt; 방식중에서 하나를 선택해 클라이언트로 전달&lt;/span&gt;&lt;span style=&quot;&quot;&gt;- 서버가 자신의 &lt;b&gt;ssl인증서&lt;/b&gt;를 클라이언트로 전달&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;6-클라이언트---ssl-handshake의-세-번째-단계--premaster-secret-생성&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;6.&amp;nbsp;클라이언트 - SSL HandShake의 세 번째 단계 :&amp;nbsp;Premaster Secret&amp;nbsp;생성&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;6-1) 클라이언트는 서버의 SSL 인증서가 믿을만한지 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Client가 SSL 인증서(CA의 Private_key로 &lt;span&gt;해쉬(서버정보)&lt;/span&gt;)를 CA의 Public Key로 디코딩해본다. 그러면 해쉬(서버정보)의 값을 얻을 수 있다. 그리고 서버에 대한 정보를 Hash화 해서 서로 일치하는 지 체크한다. 이를 통해 SSL 인증서가 위조 됐는 지 여부를 체크할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;브라우저 내부에 CA의 Public Key가 저장되어 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;7-서버클라이언트---ssl-handshake-종료--https-통신-시작&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;7. 서버/클라이언트 - SSL HandShake 종료 &amp;amp; HTTPS 통신 시작한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Computer science/네트워크</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/65</guid>
      <comments>https://wonstudy.tistory.com/65#entry65comment</comments>
      <pubDate>Mon, 20 Feb 2023 17:58:43 +0900</pubDate>
    </item>
    <item>
      <title>[Design Pttern] 데코레이터 패턴</title>
      <link>https://wonstudy.tistory.com/64</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 데코레이터 패턴?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데코레이터 패턴으로 객체에 추가 요소를 동적으로 더할 수 있는 패턴이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데코레이터를 사용하면 서브클래스를 만들 때보다 훨 씬 유연하게 기능을 확장할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;627&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cegO8H/btrX2XTfGnp/Y2Te1Kwklj9kYsAd5FAGzk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cegO8H/btrX2XTfGnp/Y2Te1Kwklj9kYsAd5FAGzk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cegO8H/btrX2XTfGnp/Y2Te1Kwklj9kYsAd5FAGzk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcegO8H%2FbtrX2XTfGnp%2FY2Te1Kwklj9kYsAd5FAGzk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;433&quot; height=&quot;351&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;627&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[역할]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Component :&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;실질적인 인스턴스를 컨트롤하는 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ConcreteComponent :&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Component의 실질적인 인스턴스의 부분으로 책임의 주체의 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Decorator :&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Component와 ConcreteDecorator를 동일시 하도록 해주는 역할&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ConcreteDecoreator :&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;실질적인 장식 인스턴스 및 정의이며 추가된 책임의 주체&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 데코레이터 패턴의 장단점&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 기존 코드를 수정하지 않고도 데코레이터 패턴을 통해 행동을 확장시킬 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 구성과 위임을 통해서 실행중에 새로운 행동을 추가할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1.&lt;/b&gt; 의미없는 객체들이 너무 많이 추가될 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;2.&lt;/b&gt; 데코레이터를 너무 많이 사용하면 코드가 필요 이상으로 복잡해질 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 데코레이터를 이용한 주문시스템 클래스 구성도&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1066&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y03NN/btrX6ihxeyB/NslSduhHRLc9CPn5aRCbk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y03NN/btrX6ihxeyB/NslSduhHRLc9CPn5aRCbk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y03NN/btrX6ihxeyB/NslSduhHRLc9CPn5aRCbk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy03NN%2FbtrX6ihxeyB%2FNslSduhHRLc9CPn5aRCbk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;729&quot; height=&quot;607&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1066&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 제일 상단의 Beverage는 구성요소를 나타내는 Component 추상 클래스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- HoustBlend, DarkRoast, Decaf, Espresso는 커피 종류마다의 구성요소를 나타내는 구상 클래스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Milk, Mocha, Soy, Whip은 각각의 첨가물을 나타내는 데코레이터이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 데코레이터를 사용해 주문시스템 구현&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[&lt;span style=&quot;color: #000000;&quot;&gt;추상 구성요소&lt;/span&gt;] &lt;span style=&quot;color: #000000;&quot;&gt;Beverage&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1675556429157&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public abstract class Beverage {
	String description = &quot;제목 없음&quot;;

	public String getDescription() {
		return description;
	}

	public abstract double cost();
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1675556522997&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Beverage 클래스를 확장
public abstract class CondimentDecorator extends Beverage { 
	Beverage beverage;

	public abstract String getDescription();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Beverage 객체가 들어갈 자리에 들어갈 수 있어야 한다. 따라서 Beverage 클래스를 확장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 모든 첨가물 데코레이터에서 getDescription() 메소드를 새로 구현하기 위해서 추상 메소드로 선언한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[구상 구성요소] Espresso, Decaf&lt;/p&gt;
&lt;pre id=&quot;code_1675556588495&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Espresso extends Beverage {
	
	public Espresso() {
		description = &quot;에스프레소&quot;;
	}
	
	public double cost() {
		return 1.99;
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1675556667795&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Decaf extends Beverage {
	
	public Espresso() {
		description = &quot;디카페인 커피&quot;;
	}
	
	public double cost() {
		return 1.05;
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[구상 데코레이터]&lt;/p&gt;
&lt;pre id=&quot;code_1675556744792&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Mocha extends CondimentDecorator {
	
	// 감싸고자 하는 객체를 받음
	public Mocha(Beverage beverage) {
		// 감싸고자 하는 음료를 저장
		this.beverage = beverage; 
	}

	public String getDescription() {
		return beverage.getDescription() + &quot;, 모카&quot;;
	}

	public double cost() {
		return beverage.cost() + .20;
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데코레이터는 감싸고자하는 음료를 저장하기 위한 인스턴스가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[주문 테스트 코드]&lt;/p&gt;
&lt;pre id=&quot;code_1675556855965&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class StarbuzzCoffee {
	
	public static void main(String args[]) {
		Beverage beverage = new Espresso();
		beverage = new Mocha(beverage); // Mocha로 감싼다
		beverage = new Mocha(beverage); // Mocha로 감싼다
		
                Beverage beverage2 = new Decaf();
                beverage2 = new Whip(beverage2); // Whip으로 감싼다

		System.out.println(beverage.getDescription() + &quot; $&quot; + beverage.cost());
		// 에스프레소 커피, 모카, 모카 $1.99
		System.out.println(beverage2.getDescription() + &quot; $&quot; + beverage.cost());
		// 디카페인 커피, 휘핑크림 $2.49
	}
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Design Pattern</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/64</guid>
      <comments>https://wonstudy.tistory.com/64#entry64comment</comments>
      <pubDate>Sun, 5 Feb 2023 09:41:44 +0900</pubDate>
    </item>
    <item>
      <title>[네트워크] Streaming service</title>
      <link>https://wonstudy.tistory.com/63</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 스트리밍 서비스?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 음악이나 동영상 등의 멀티미디어 파일을 전송, 재생하는 방식으로 서비스를 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 파일을 다운로드하는 것과 더불어 재생함으로써 기다리는 시간을 줄일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex) 왓챠, 유튜브, 넷플릭스 등등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 스트리밍 프로토콜?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 스트리밍 프로토콜이란 위 서비스를 위해 데이터를 전달하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.1 종류&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) Progressive Download&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 웹 서버로부터 동영상을 다운로드하면서 파일이 도착하는 대로 재생해주는 방식이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;257&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZz2TK/btrX2oCZNp0/bOPJHwuyUKKcYEQySKkkMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZz2TK/btrX2oCZNp0/bOPJHwuyUKKcYEQySKkkMK/img.png&quot; data-alt=&quot;@ 출처 :&amp;amp;amp;nbsp;https://abt.net/multimedia.php&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZz2TK/btrX2oCZNp0/bOPJHwuyUKKcYEQySKkkMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZz2TK%2FbtrX2oCZNp0%2FbOPJHwuyUKKcYEQySKkkMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;257&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;257&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;@ 출처 :&amp;amp;nbsp;https://abt.net/multimedia.php&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[장점]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 웹 서버에 업로드 후 클라이언트 쪽에 URL만 알려주면 되므로, 구현이 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[단점]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 전체 파일을 가져오는 방식으로 유료 서비스에 적용하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 시청한 만큼의 용량이 아닌 다운로드 한 만큼의 네트워크 트래픽을 사용하므로, 네트워크 사용량이 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다운로드 시작 중에는 비디오 품질을 변경할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[예시]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- VOD(Video On Demand 주문형 비디오)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영상 등 멀티미디어 데이터를 서버에 저장해두고, 원하는 때에 원하는 서비스를 제공 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2)RTMP,&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;RSTP&lt;/b&gt; 스트리밍&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 웹폴더에 있는 파일을 다운받아 진행하는 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서버는 미디어 파일을 몇 초 단위로 단편화 시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클라이언트는 단편하된 미디어 파일들을 받아 연속된 미디어 스트림으로 조합하여 재생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RTMP (Real Time Messaging Protocol)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ndash; 실시간 메시지 전송 프로토콜이다.&lt;br /&gt;&amp;ndash; 어도비 시스템즈 (Adobe Systems) 사의 독점 컴퓨터 통신 규약이다.&lt;br /&gt;&amp;ndash; 오디오, 비디오 및 기타 데이터를 인터넷을 통해 스트리밍 할때 사용한다.&lt;br /&gt;&amp;ndash; 포트번호 1935번을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;RTSP (Real Time Streaming Protocol)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;ndash; IETF (Internet Engineering Task Force) 가 1998년에 개발한 통신 규약이다.&lt;br /&gt;&amp;ndash; 스트리밍 데이터를 제어하기 위한 방법을 제공한다.&lt;br /&gt;&amp;ndash; 오디오, 비디오 등 멀티미디어 데이터를 포함하는 미디어 서버를 원격 조작하기 위한 프로토콜이다.&lt;br /&gt;&amp;ndash; 명령어는 Play, Pause 와 같이 VCR 동작하고 비슷하며, 시간 정보를 바탕으로 서버에 접근한다.&lt;br /&gt;&amp;ndash; 실제 미디어 스트리밍 데이터를 전송하지 않고, RTP 규약을 사용하여 전송 계층으로 실제 오디오/비디오 데이터를 전송한다.&lt;br /&gt;&amp;ndash; RTSP 규약은 HTTP 규약하고 비교해 볼 때, 문법이나 동작은 비슷하지만, HTTP가 무상태형 (Stateless) 인 반면 RTSP 는 상태형 (Stateful) 규약이다.&lt;br /&gt;&amp;ndash; 포트번호는 554번을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RWb1d/btrX4jU0fA7/jWFdgBWgRKV4lQwH6TAjE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RWb1d/btrX4jU0fA7/jWFdgBWgRKV4lQwH6TAjE0/img.png&quot; data-alt=&quot;https://abt.net/multimedia.php&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RWb1d/btrX4jU0fA7/jWFdgBWgRKV4lQwH6TAjE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRWb1d%2FbtrX4jU0fA7%2FjWFdgBWgRKV4lQwH6TAjE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;300&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://abt.net/multimedia.php&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[장점]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서버 파일을 몇 초단위로 단편화 시키므로 Progressive Download 보다 트래픽을 줄 일 수 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[단점]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일반적인 MP4 파일에서 동작하지 않는다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) Adaptive HTTP 스트리밍&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RSTP/RTMP 와 Progressive Download의 장점을 결합한 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- 넷플릭스나 유튜브 동영상을 시청할 때 처음에는 해상도가 좋지 않다가 점점 해상도가 좋아지는 것을 경험했던 적이 있을 것이다. 처음에는 사용자의 네트워크 상태를 판단할 수 없으니 낮은 해상도의 콘텐츠 조각을 내려주다가 네트워크의 품질이 식별되면 그에 따른 해상도로 내려주는 전략을 선택했을 것으로 짐작해볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;- Adaptive 하게 스트리밍을 하게 되면 서비스를 제공하는 서버의 트래픽을 관리할 수 있는 이점이 있는 것은 물론 사용자 입장에서도 네트워크 데이터 사용을 줄일 수 있는 장점이 있고 버퍼링 없는 동영상 시청이 가능하게 된다. 버퍼링을 감수하고라도 고해상도로 보고자 하는 유저들에게는 UI를 통한 선택권을 줄 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;256&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjbING/btrX3tYa453/g7PKKsCH50Qit1Bb8Ww4KK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjbING/btrX3tYa453/g7PKKsCH50Qit1Bb8Ww4KK/img.png&quot; data-alt=&quot;https://abt.net/multimedia.php&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjbING/btrX3tYa453/g7PKKsCH50Qit1Bb8Ww4KK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjbING%2FbtrX3tYa453%2Fg7PKKsCH50Qit1Bb8Ww4KK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;256&quot; data-origin-width=&quot;599&quot; data-origin-height=&quot;256&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://abt.net/multimedia.php&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[장점]&lt;br /&gt;- 네트워크 트래픽의 부하 분산 , 트래픽 감소&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[단점]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 표준화가 부족하다. 각 공급자(ms, apple, adobe) 마다 서로의 프로토콜이 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 단편화 된 파일간의 변환 툴이 아직까지는 일반화 되지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[예시]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- YouTube : 원래는 Progressive Download 방식으로 구현되었지만, 현재는 Adaptive Http Streaming 방식으로 서비스하고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LlO8Z/btrX2pvclKT/DAeGiKxSoYshVyVe2uYvdk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LlO8Z/btrX2pvclKT/DAeGiKxSoYshVyVe2uYvdk/img.gif&quot; data-alt=&quot;https://www.netmanias.com/ko/post/blog/5819/google-http-adaptive-streaming-http-progressive-download-ott-video-streaming-youtube/youtube-switched-to-chunking-and-adaptive-streaming&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LlO8Z/btrX2pvclKT/DAeGiKxSoYshVyVe2uYvdk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/LlO8Z/btrX2pvclKT/DAeGiKxSoYshVyVe2uYvdk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;700&quot; height=&quot;550&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://www.netmanias.com/ko/post/blog/5819/google-http-adaptive-streaming-http-progressive-download-ott-video-streaming-youtube/youtube-switched-to-chunking-and-adaptive-streaming&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;br /&gt;&lt;b&gt;3. FTP&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.1정의&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;- File Transfer Protocol로, 인터넷 상의 한 컴퓨터에서 다른 컴퓨터로 원하는 파일을 전송할 수 있는 TCP/IP 응용 프로토콜이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.2 FTP 포트의 사용과 명령&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프로토콜 : TCP&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용 포트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;20번 - 서버와 클라이언트 간에 데이터 전송 용도의 포트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;21번 - 클라이언트에서 서버로 보내는 명령을 제어하는 용도의 포트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트 접속 명령 FTP :&amp;nbsp;[접속지 주소]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 익명 사용자가 FTP 사이트의 특정 디렉터리에 파일을 업로드하려면, 쓰기/사용 권한을 부여받아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다른 응용 프로토콜과 달리 FTP 서버는 21번만 열린 상태에서 클라이언트가 접속되길 기다린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;자료를 전송할 떄는 20번 포트를 사용하고, 21번 포트가&amp;nbsp;동작이 불가능하면 접속을 할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;21번 접속이 가능하고 20번 포트가 동작하지 않으면 접속은 되지만 자료 전송을 할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;송수신할 때&amp;nbsp;포트를 2개쓰므로&amp;nbsp;다소 비효율적인 면이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.3 FTP의 특징&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서로 다른 시스템 사이에서 동작되고, 하나의 시스템 사용자들로부터 운영 시스템과는 관계없이 다른 종류의 시스템과 연결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- FTP 클라이언트는 대화식으로 클라이언트보다 상위 계층 요소 기술이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 텍스트 명령어 중심의 인터페이스에서 동작하며, 제한된 파일 형식과 파일 구조를 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 접속에는 계정 접속과 익명 접속 두 가지가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;계정 접속은 FTP 서버에 로그인하기 위한 계정이 필요하고, 익명 접속은 다수가 로그인할 때 Anonymous FTP라는 계정이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 로컬 시스템과, 원격 시스템간의 파일 전송 프로토콜 기능을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Telnet, Rlogin, Rsh와 같은 원격 접속 프로토콜은 파일 전송이 불가능하기 때문에 서버 대 호스트간의 파일 전송을 위해 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 파일 전송 형태는 파일 특성에 따라 이진 형태와 텍스트 형태로 구성된다. 전송 파일에 따라 모드를 구분해야 한다.&lt;/p&gt;</description>
      <category>Computer science/네트워크</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/63</guid>
      <comments>https://wonstudy.tistory.com/63#entry63comment</comments>
      <pubDate>Sat, 4 Feb 2023 09:29:51 +0900</pubDate>
    </item>
    <item>
      <title>[Oracle] 프로시저, 사용자 정의 함수, 트리거</title>
      <link>https://wonstudy.tistory.com/62</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 절차형 SQL이란?&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;I) 개념&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;SQL도 일반 프로그램 언어와 유사하게 절차 지향적인 프로그램이 가능하도록 하는 트랜잭션 언어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;II) 종류&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1) 프로시저&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일련의 쿼리들을 하나의 함수처럼 실행하기 위한 쿼리의 집합&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2) 사용자 정의함수 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일련의 SQL 처리를 수행하고 수행 결과를 단일 값으로 반환할 수 있는 절차형 SQL&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3) 트리거&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/b&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 시스템에서 CURD 이벤트가 발생할 때마다 관련 작업이 자동으로 수행되는 절차형 SQL&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;III) 특징&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 단일 SQL 문장으로 실행하기 어려운 연속적인 작업을 처리하는데 적합하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DBMS 내부에서 직접 처리하기 때문에 일반적으로 입출력 데이터가 적다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;IV) 필수 구성 요소&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DECLARE(선언) : 대상의 이름 및 변수등을 선언&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- BEGIN(시작)&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;: 실행 시 시점, 프로시저, 사용자 정의 함수가 실행되는 시작점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- END(끝)&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; : 실행 시 종점, 프로시저, 사용자 정의 함수가 실행되는 종료점이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 프로시저&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;I) 프로시저 문법&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1673828298697&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE [OR REPLACE] PROCEDURE 프로시저명
(파라미터명 [IN|OUT|INOUT] 데이터타입, ... )
IS
     변수선언
BEGIN
     명령어;
[COMMIT|ROLLBACK]
END;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;II) 프로시저 호출 예시&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1673828589548&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SQL&amp;gt;EXECUTE p_DEPT_insert(10, 'dev', 'seoul', :rslt);

SQL&amp;gt; print rslt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) EXECUTE 구문을 이용해 정의한 프로시저를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 프로시저의 OUT변수인 rslt를 print할 때, DEPTNO(10)가 이미 존재한다면 이미 등록된 부서번호라 출력될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;반대로 없다면 입력 완료로 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;III) 프로시저 호출 특징&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 외부 호출을 통해 실행된다. ex) 응용 프로그램에서 호출, 내부 스케쥴러 배치 작업 중 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SQL 명령어를 활용하여 작성된 프로시저를 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SQL TOOL을 사용하지 않고 다른 프로시저에서 호출 시에는 별도 명령어 없이 &quot;@프로시저명&quot; 또는 프로시저 명칭만 사용하여 호출이 가능하다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 사용자 정의 함수&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;I) 사용자 정의 함수 호출 예시&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1673828965301&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 사용자 정의 함수 결과 값을 데이터 질의어에 활용
SQL&amp;gt; SELECT [사용자정의 함수명](매개변수1, 매개변수2, ...)
            FROM 테이블명;
            
# 사용자 정의 함수 결과 값을 데이터 조작어에 활용
SQL&amp;gt; UPDATE [테이블명]SET [필드명] =
            [사용자정의함수](매개변수1...)WHERE 조건..;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;II) 사용자 정의 함수 특징&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 연산 처리 결과를 단일 값으로 반환할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 사용자 정의 함수의 호출을 통해 실행되며, 반환되는 값을 CRUD에 재이용하는 것이 일반적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 트리거&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;I) 트리거 문법&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1673829455715&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE [OR REPLACE] TRIGGER '트리거 이름'()
   [BEFORE|AFTER] 유형 ON 테이블명
   [FOR EACH ROW]
BEGIN
END;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;II) 트리거 호출 예시&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1673830933145&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DELETE TRIGGER TNAME ON INSERTION OF 갱신:
(UPDATE 회원
  SET 회원, 적립액 = 회원, 적립액 + (갱신.가격 * 갱신.적립비율)
  WHERE 갱신.회원번호 = 회원.회원번호);&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;III) 트리거 특징&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- CRUD 이벤트가 발 생할 때마다 관련 작업이 자동으로 수행되는 절차형 SQL이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일반적으로 이벤트와 관련된 테이블에 데이터 삽입, 추가, 삭제 작업을 자동으로 실행시키는데 활용되나, 데이터의 무결성 유지, 로그 메세지 출력 등의 처리를 위해 사용하기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 프로시저와 트리거 차이점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;프로시저&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;트리거&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;- CREATE 프로시저&amp;nbsp; 문법 사용&lt;br /&gt;- EXECUTE 명령어로 실행&lt;br /&gt;- COMMIT, ROLLBACK 가능&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;- CREATE 트리거 문법 사용&lt;br /&gt;- 생성 후 자동 실행&lt;br /&gt;- COMMIT, ROLLBACK 불가능&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Database/Oracle</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/62</guid>
      <comments>https://wonstudy.tistory.com/62#entry62comment</comments>
      <pubDate>Mon, 16 Jan 2023 09:18:53 +0900</pubDate>
    </item>
    <item>
      <title>[Design Pattern] MVC패턴</title>
      <link>https://wonstudy.tistory.com/61</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. MVC패턴이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Model + View + Controller를 합친 용어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Model : 어플리케이션에서 사용되는 데이터와 그 데이터를 처리하는 부분&lt;/li&gt;
&lt;li&gt;View : 사용자에서 보여지는 UI 부분&lt;/li&gt;
&lt;li&gt;Controller : 사용자의 입력을 받고 처리하는 부분&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. MVC패턴의 흐름&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클라이언트가 입력하여 요청 (ex. 저장버튼 클릭)&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;서버에 데이터를 요청, Controller에 요청한다.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Controller에서 사용자에게 받은 데이터를 처리하기 위해 로직을 수행한다. Controller는 필요한 데이터들을 Model과 주고 받음&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Controller는 View에게 결과를 전달한다. 사용자에게 화면 결과를 보여줌&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. MVC패턴 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1673311942010&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//Controller 모델을 통해 데이터를 받아 View로 보낸다
Class Users{
    function getProfile(id) {
       profile = this.UserModel.getProfile(id)
       renderView('user/profile', profile);
    }
}

//Model 데이터를 가져온다
Class UserModel{
    function getProfile(id){
       data = this.db.get('select * from users where id = id')
       return data;
    }
}

//View 받은 데이터를 사용자에게 보여준다.
&amp;lt;h1&amp;gt;{{profile.name}}&amp;lt;/h1&amp;gt;
&amp;lt;ul&amp;gt;
   &amp;lt;li&amp;gt;Email: {{profile.email}}&amp;lt;/li&amp;gt;
   &amp;lt;li&amp;gt;Phone: {{profile.Phone}}&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. MVC패턴의 장단점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;장점&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단순하고 직관적&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;기능 별로 코드를 분리하여 유연하고 확장하기 쉽다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단점&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 패턴을 사용하기 위한 클래스, 기능들이 많이 필요하다. 복잡한 설계가 될 수 있음&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;Model과 View의 완벽한 분리가 어렵다. =&amp;gt; Model과 View의 의존성이 높아 패턴이 모호해짐.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;의존성이 높다면, 각각 독립적이지 않아 코드 하나를 수정하려면 여러 부분을 수정해야한다는 큰 단점이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;++&amp;nbsp; Spring MVC 모델 흐름&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1229&quot; data-origin-height=&quot;689&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdB69I/btrVF8psj6W/hNkhEaP4JtjitThzfDq8Vk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdB69I/btrVF8psj6W/hNkhEaP4JtjitThzfDq8Vk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdB69I/btrVF8psj6W/hNkhEaP4JtjitThzfDq8Vk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdB69I%2FbtrVF8psj6W%2FhNkhEaP4JtjitThzfDq8Vk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1229&quot; height=&quot;689&quot; data-origin-width=&quot;1229&quot; data-origin-height=&quot;689&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Design Pattern</category>
      <author>JiWonSon</author>
      <guid isPermaLink="true">https://wonstudy.tistory.com/61</guid>
      <comments>https://wonstudy.tistory.com/61#entry61comment</comments>
      <pubDate>Mon, 9 Jan 2023 18:21:02 +0900</pubDate>
    </item>
  </channel>
</rss>