<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>현록의 기록저장소</title>
    <link>https://ydeer.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sat, 20 Jun 2026 07:22:32 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>현록</managingEditor>
    <image>
      <title>현록의 기록저장소</title>
      <url>https://tistory1.daumcdn.net/tistory/3088939/attach/704d4b927bc94a56a03cc0bc4d7592e3</url>
      <link>https://ydeer.tistory.com</link>
    </image>
    <item>
      <title>Http Status Code</title>
      <link>https://ydeer.tistory.com/332</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTTP/Reference/Status&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://developer.mozilla.org/ko/docs/Web/HTTP/Reference/Status&lt;/a&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;1xx&quot;&gt;&lt;b&gt;[1XX] 정보 응답&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;2xx&quot;&gt;&lt;b&gt;[2XX]&amp;nbsp;성공&amp;nbsp;응답&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;200&quot;&gt;200: OK&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;201&quot;&gt;201:&amp;nbsp;Created&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;204&quot;&gt;204:&amp;nbsp;No&amp;nbsp;Content&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;3xx&quot;&gt;&lt;b&gt;[3XX]&amp;nbsp;리다이렉션&amp;nbsp;메시지:&amp;nbsp;Response&amp;nbsp;Header&amp;nbsp;의&amp;nbsp;Location&amp;nbsp;으로&amp;nbsp;자동&amp;nbsp;이동&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;301&quot;&gt;301:&amp;nbsp;Moved&amp;nbsp;Permanently&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;302&quot;&gt;302: Found&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;303&quot;&gt;303: See Other&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;304&quot;&gt;304: Not Modified&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;307&quot;&gt;307: Temporary Redirect&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;308&quot;&gt;308: Permanent Redirect&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;4xx&quot;&gt;&lt;b&gt;[4XX]&amp;nbsp;클라이언트&amp;nbsp;에러&amp;nbsp;응답&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;400&quot;&gt;400: Bad Request&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;401&quot;&gt;401: Unauthorized&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;403&quot;&gt;403: Forbidden&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;404&quot;&gt;404: Not Found&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;5xx&quot;&gt;&lt;b&gt;[5XX]&amp;nbsp;서버&amp;nbsp;에러&amp;nbsp;응답&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;500&quot;&gt;500: Internal Sever Error&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;501&quot;&gt;501: Not Implemented&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;502&quot;&gt;502: Bad Gateway&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;503&quot;&gt;503: Service Unavailable&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 id=&quot;1xx&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[1XX] 정보 응답&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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 id=&quot;2xx&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[2XX]&amp;nbsp;성공&amp;nbsp;응답&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;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;200&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;200:&amp;nbsp;OK&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;
&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;201&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;201:&amp;nbsp;Created&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ그 결과로 새로운 리소스가 생성됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍResponse Header 의 Location에 해당 리소스를 확인할 수 있는 path 를 넣어줌.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　Location:&amp;nbsp;/members/101&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;202&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;202:&amp;nbsp;Accepted&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍex) 배치에 요청 접수. 1시간 후 배치 프로세스가 처리.&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;204&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;204:&amp;nbsp;No&amp;nbsp;Content&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍResponse Body 는 null.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 id=&quot;3xx&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;[3XX] 리다이렉션 메시지: Response Header 의 Location 으로 자동 이동&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;301&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;301:&amp;nbsp;Moved&amp;nbsp;Permanently&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ(may)&amp;nbsp;Request&amp;nbsp;Method&amp;nbsp;가&amp;nbsp;GET&amp;nbsp;으로&amp;nbsp;변하면서&amp;nbsp;리다이렉션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ (may)&amp;nbsp;본문이&amp;nbsp;제거될&amp;nbsp;수도&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;may&amp;nbsp;변함:&amp;nbsp;302,&amp;nbsp;변함:&amp;nbsp;303,&amp;nbsp;must&amp;nbsp;유지:&amp;nbsp;307)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(영구 - may 변함: 301, 변함: -, must 유지: 308)&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;302&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;302:&amp;nbsp;Found&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ(may) Request Method 가 GET 으로 변하면서 리다이렉션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ(may) 본문이 제거될 수도 있음.&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;may&amp;nbsp;변함:&amp;nbsp;302,&amp;nbsp;변함:&amp;nbsp;303,&amp;nbsp;must&amp;nbsp;유지:&amp;nbsp;307)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(영구&amp;nbsp;-&amp;nbsp;may&amp;nbsp;변함:&amp;nbsp;301,&amp;nbsp;변함:&amp;nbsp;-,&amp;nbsp;must&amp;nbsp;유지:&amp;nbsp;308)&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;303&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;303:&amp;nbsp;See&amp;nbsp;Other&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ(?) Request Method 가 GET 으로 변하면서 리다이렉션.&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;-&amp;nbsp;may&amp;nbsp;변함:&amp;nbsp;302,&amp;nbsp;변함:&amp;nbsp;303,&amp;nbsp;must&amp;nbsp;유지:&amp;nbsp;307)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(영구 - may 변함: 301, 변함: -, must 유지: 308)&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;304&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;304:&amp;nbsp;Not&amp;nbsp;Modified&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;목적으로&amp;nbsp;사용.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ 클라이언트에게&amp;nbsp;로컬&amp;nbsp;리소스를&amp;nbsp;그대로&amp;nbsp;사용하라고&amp;nbsp;알려주는&amp;nbsp;메시지.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ Response&amp;nbsp;Body&amp;nbsp;가&amp;nbsp;null&amp;nbsp;이어야&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ Response&amp;nbsp;Header&amp;nbsp;에&amp;nbsp;캐시&amp;nbsp;관련&amp;nbsp;정보&amp;nbsp;담아서&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 id=&quot;307&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;307:&amp;nbsp;Temporary&amp;nbsp;Redirect&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ(must) Request Method 가 기존과 동일하게 유지하면서 리다이렉션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ(must) 본문이 제거되지 않고 유지.&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;may&amp;nbsp;변함:&amp;nbsp;302,&amp;nbsp;변함:&amp;nbsp;303,&amp;nbsp;must&amp;nbsp;유지:&amp;nbsp;307)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(영구 - may 변함: 301, 변함: -, must 유지: 308)&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;308&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;308:&amp;nbsp;Permanent&amp;nbsp;Redirect&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ(must) Request Method 가 기존과 동일하게 유지하면서 리다이렉션.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ(must) 본문이 제거되지 않고 유지.&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;may&amp;nbsp;변함:&amp;nbsp;302,&amp;nbsp;변함:&amp;nbsp;303,&amp;nbsp;must&amp;nbsp;유지:&amp;nbsp;307)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(영구 - may 변함: 301, 변함: -, must 유지: 308)&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;4xx&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[4XX]&amp;nbsp;클라이언트&amp;nbsp;에러&amp;nbsp;응답&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;
&lt;p id=&quot;400&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;400:&amp;nbsp;Bad&amp;nbsp;Request&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ요청 파라미터가 잘못되거나, API 스펙에 맞지 않거나.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ동일한 Request 로는 계속해서 같은 응답일 뿐.&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;401&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;401:&amp;nbsp;Unauthorized&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ로그인 필요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ인증(Authenticate) 되지 않음.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍResponse Header 의 WWW-Authentication 에 인증 방법을 설명.&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;403&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;403:&amp;nbsp;Forbidden&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ로그인 했지만 권한 불충분.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ해당 유저에게 인가(Authorize) 되지 않음.&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;404&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;404:&amp;nbsp;Not&amp;nbsp;Found&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;/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;　아예 해당 페이지의 존재 여부도 가리고자 404 로 주기도 함.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;5xx&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[5XX]&amp;nbsp;서버&amp;nbsp;에러&amp;nbsp;응답&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;
&lt;p id=&quot;500&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;500:&amp;nbsp;Internal&amp;nbsp;Sever&amp;nbsp;Error&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;내부&amp;nbsp;문제로&amp;nbsp;오류&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 id=&quot;501&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;501:&amp;nbsp;Not&amp;nbsp;Implemented&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;ㆍRequest Method-URI 에 대해 서버가 구현하고 있지 않음.&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;502&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;502:&amp;nbsp;Bad&amp;nbsp;Gateway&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;/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;503&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;503:&amp;nbsp;Service&amp;nbsp;Unavailable&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ일시적인 과부하 또는 예정된 작업으로 잠시 요청 처리 불가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍResponse Header 의 Retry-After 에 얼마 뒤 복구되는지 알려줄 수 있음.&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;</description>
      <category>Study/기타</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/332</guid>
      <comments>https://ydeer.tistory.com/332#entry332comment</comments>
      <pubDate>Sun, 14 Sep 2025 21:14:40 +0900</pubDate>
    </item>
    <item>
      <title>inputPass 사전저장문 입력기</title>
      <link>https://ydeer.tistory.com/328</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;inputPass.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTIms0/btsC6TXzUP6/kG7ZOedcFILtLSM8ykrfH1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTIms0/btsC6TXzUP6/kG7ZOedcFILtLSM8ykrfH1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTIms0/btsC6TXzUP6/kG7ZOedcFILtLSM8ykrfH1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bTIms0/btsC6TXzUP6/kG7ZOedcFILtLSM8ykrfH1/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;300&quot; height=&quot;230&quot; data-filename=&quot;inputPass.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/EX1Hz/btsHxGynfQ5/jLMZX0m312hTKrzGhgNgjk/inputPass.exe?attach=1&amp;amp;knm=tfile.exe&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;inputPass.exe&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.85MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구동환경:&amp;nbsp;Windows&amp;nbsp;32bit,64bit.&amp;nbsp;98&amp;nbsp;이상&amp;nbsp;모든&amp;nbsp;Windows&amp;nbsp;GUI&amp;nbsp;운영체제에서&amp;nbsp;돌아갈&amp;nbsp;것으로&amp;nbsp;예상.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발언어:&amp;nbsp;Autohotkey&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;inputPass.exe 옆에 inputPass.txt를 생성합니다.&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;pre id=&quot;code_1704726272561&quot; class=&quot;prettyprint lang-cpp cpp&quot; data-ke-language=&quot;cpp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;홍길동 IP
192.168.0.172
강우주 IP
192.168.0.241&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;p data-ke-size=&quot;size16&quot;&gt;입력칸에 커서를 활성상태로 두고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키보드의 [왼쪽Ctrl키]를 누른채로 마우스의 [휠버튼]을 누르면 마우스 위치에 메뉴가 뜹니다.&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;이 상태로 왼쪽 Ctrl키만 손에서 떼고(휠버튼은 누르고 있는 채로)&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;포인터가 메뉴 밖에 있거나, Ctrl을 다시 누른 상태를 유지하면 휠버튼을 떼어도 입력이 되지 않고 취소됩니다.&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;inputPass.txt 파일의 내용을 수정한다고 해서 프로그램의 메뉴가 동적으로 바뀌진 않으며,&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;</description>
      <category>Programs/release</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/328</guid>
      <comments>https://ydeer.tistory.com/328#entry328comment</comments>
      <pubDate>Tue, 9 Jan 2024 00:10:08 +0900</pubDate>
    </item>
    <item>
      <title>컨테이너에서 로그나 파일을 생성할 수 없는 문제</title>
      <link>https://ydeer.tistory.com/325</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;개요&quot;&gt;[개요]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;문제1&quot;&gt;[volume mount의 문제]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;해결1&quot;&gt;[volume mount의 문제 해결]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;문제2&quot;&gt;[실행과 상대 경로의 문제]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;해결2&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;Docker container cannot make log file&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;개요&quot; 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;특히 &lt;span class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;에서 &lt;span class=&quot;code-span code-r&quot;&gt;USER ~&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;문제1&quot; data-ke-size=&quot;size16&quot;&gt;[volume mount의 문제]&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 class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;과 &lt;span class=&quot;code-span&quot;&gt;docker-compose.yml&lt;/span&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;span class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;FROM&amp;nbsp;ubuntu&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;RUN&amp;nbsp;mkdir&amp;nbsp;/mybind&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;RUN&amp;nbsp;adduser&amp;nbsp;user001&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;RUN chown -R user001:user001 /mybind&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;USER&amp;nbsp;user001&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;RUN&amp;nbsp;touch&amp;nbsp;/mybind/a&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;RUN&amp;nbsp;touch&amp;nbsp;/mybind/b&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;RUN&amp;nbsp;touch&amp;nbsp;/mybind/c&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;ENTRYPOINT&amp;nbsp;[&amp;nbsp;&quot;bin/bash&quot;,&amp;nbsp;&quot;-c&quot;,&amp;nbsp;&quot;while&amp;nbsp;true;&amp;nbsp;do&amp;nbsp;touch&amp;nbsp;/mybind/d;&amp;nbsp;touch&amp;nbsp;/mybind/e;&amp;nbsp;touch&amp;nbsp;/mybind/f;&amp;nbsp;sleep&amp;nbsp;1;&amp;nbsp;done;&quot;&amp;nbsp;]&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 처음 root가 &lt;span class=&quot;code-span&quot;&gt;/mybind&lt;/span&gt; 디렉터리를 만들어주고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;user001이라는 유저를 생성해준 후,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;/mybind&lt;/span&gt; 디렉터리의 소유권을 user001이 가지도록 해주고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;user001로 유저 전환을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 &lt;span class=&quot;code-span&quot;&gt;/mybind&lt;/span&gt;에 a,b,c 파일을 생성한 후,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제는 d,e,f 파일을 1초마다 생성하는 반복 스크립트를 무한히 동작하게 된다.&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 class=&quot;code-span&quot;&gt;docker-compose.yml&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;services:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;bind-test:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;build:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;context:&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;dockerfile:&amp;nbsp;./Dockerfile&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;no_cache:&amp;nbsp;true&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;image: image-bind-test&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;container_name:&amp;nbsp;cont-bind-test&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;volumes:&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;./bind-with-container:/mybind&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stdin_open:&amp;nbsp;true&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tty:&amp;nbsp;true&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hostname:&amp;nbsp;bind-test&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호스트의 &lt;span class=&quot;code-span&quot;&gt;./bind-with-container&lt;/span&gt; 디렉터리를 컨테이너의 &lt;span class=&quot;code-span&quot;&gt;/mybind&lt;/span&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;(여기선 docker compose로 실행하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;docker run ~ &lt;span class=&quot;code-r&quot;&gt;-v ./bind-with-container:/mybind&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;&amp;nbsp;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;ls&amp;nbsp;-alR&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;.:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;16&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;2&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:38&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;20:39&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;270&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:15&amp;nbsp;docker-compose.yml&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;280&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:34&amp;nbsp;Dockerfile&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호스트의 유저는 desktop이라는 이름이고, 본 디렉터리에는 위 예시 파일만 있을 뿐이다.&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;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;docker&amp;nbsp;compose&amp;nbsp;up&amp;nbsp;-d&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[+]&amp;nbsp;Running&amp;nbsp;1/1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;✔&amp;nbsp;Container&amp;nbsp;cont-bind-test&amp;nbsp;&amp;nbsp;Started&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.0s&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;ls&amp;nbsp;-alR&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;.:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;20&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;20:39&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;bind-with-container&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;270&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:15&amp;nbsp;docker-compose.yml&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;280&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:34&amp;nbsp;Dockerfile&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;./bind-with-container&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;8&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;volume mount 설정대로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;./bind-with-container&lt;/span&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;펼치기: a,b,c가 없는 이유&quot; data-text-less=&quot;접기: a,b,c가 없는 이유&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 volume bind mount는&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;host -&amp;gt; container의 방향으로만 진행하기 때문에,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;에서 명시한 &lt;span class=&quot;code-span code-r&quot;&gt;RUN touch /mybind/a&lt;/span&gt; 들은 실제론 실행되어서 만들어졌으나&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;volume bind 과정에서 host의 디렉터리가 덮어쓰면서 사라진 것이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아쉽게도 반대 방향의 복사를 시작시 자동으로 해올 순 없다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;bind 시점이 &lt;span class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;의 마지막 줄 이후의 시점이기 때문.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;컨테이너의 파일을 가져오고 싶다면,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;덮어씌워지지 않게 다른 곳을 bind해서&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;내부로 들어가 원하는 파일들을 bind된 곳으로 이동시킨 후,&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;host에서 파일을 가진 채 해당 파일들을 덮어쓸 수 있도록 bind를 설정하는 것 밖에는...&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;그럼 d,e,f는 왜 없을까??&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;docker&amp;nbsp;logs&amp;nbsp;cont-bind-test&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;touch:&amp;nbsp;cannot&amp;nbsp;touch&amp;nbsp;'/mybind/d':&amp;nbsp;Permission&amp;nbsp;denied&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;touch:&amp;nbsp;cannot&amp;nbsp;touch&amp;nbsp;'/mybind/e':&amp;nbsp;Permission&amp;nbsp;denied&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;touch:&amp;nbsp;cannot&amp;nbsp;touch&amp;nbsp;'/mybind/f':&amp;nbsp;Permission&amp;nbsp;denied&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;touch:&amp;nbsp;cannot&amp;nbsp;touch&amp;nbsp;'/mybind/d':&amp;nbsp;Permission&amp;nbsp;denied&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;touch:&amp;nbsp;cannot&amp;nbsp;touch&amp;nbsp;'/mybind/e':&amp;nbsp;Permission&amp;nbsp;denied&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;touch:&amp;nbsp;cannot&amp;nbsp;touch&amp;nbsp;'/mybind/f':&amp;nbsp;Permission&amp;nbsp;denied&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;음... 무한히 1초마다 파일 생성은 시도하는데, 권한 문제가 발생한다.&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;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;docker&amp;nbsp;exec&amp;nbsp;-it&amp;nbsp;cont-bind-test&amp;nbsp;/bin/bash&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;user001@bind-test:/$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;ls&amp;nbsp;-al&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;64&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:35&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:35&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:35&amp;nbsp;.dockerenv&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;bin&amp;nbsp;-&amp;gt;&amp;nbsp;usr/bin&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Apr&amp;nbsp;18&amp;nbsp;&amp;nbsp;2022&amp;nbsp;boot&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;5&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;360&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:39&amp;nbsp;dev&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:35&amp;nbsp;etc&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Apr&amp;nbsp;18&amp;nbsp;&amp;nbsp;2022&amp;nbsp;home&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;lib&amp;nbsp;-&amp;gt;&amp;nbsp;usr/lib&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;lib32&amp;nbsp;-&amp;gt;&amp;nbsp;usr/lib32&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;lib64&amp;nbsp;-&amp;gt;&amp;nbsp;usr/lib64&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;10&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;libx32&amp;nbsp;-&amp;gt;&amp;nbsp;usr/libx32&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;media&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;mnt&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;root&amp;nbsp;root&lt;/span&gt;&amp;nbsp;4096&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:39&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;mybind&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;opt&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;dr-xr-xr-x&amp;nbsp;368&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:39&amp;nbsp;proc&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwx------&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:12&amp;nbsp;root&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;5&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:12&amp;nbsp;run&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;sbin&amp;nbsp;-&amp;gt;&amp;nbsp;usr/sbin&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;srv&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;dr-xr-xr-x&amp;nbsp;&amp;nbsp;13&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:39&amp;nbsp;sys&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxrwt&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:12&amp;nbsp;tmp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;14&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;usr&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:12&amp;nbsp;var&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;user001@bind-test:/$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;exit&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;exit&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;/mybind&lt;/span&gt; 디렉터리의 소유자가 &lt;span class=&quot;code-span&quot;&gt;root:root&lt;/span&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;span class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;에서 분명 &lt;span class=&quot;code-span code-r&quot;&gt;RUN chown -R user001:user001 /mybind&lt;/span&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;span class=&quot;code-span&quot;&gt;./bind-with-container&lt;/span&gt; 디렉터리를 만들어주던 것을 위에서 봤었다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;ls&amp;nbsp;-alR&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;.:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;20&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;20:39&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;bind-with-container&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;270&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:15&amp;nbsp;docker-compose.yml&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;280&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:34&amp;nbsp;Dockerfile&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;./bind-with-container&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;8&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 desktop 계정으로 docker 명령어를 실행했지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디렉터리를 자동으로 만들 때 root가 만든 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;id&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;uid=1000(desktop)&amp;nbsp;gid=1000(desktop)&amp;nbsp;groups=1000(desktop)&lt;/span&gt;,4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;122(lpadmin),135(lxd),136(sambashare),&lt;span style=&quot;color: #ee2323;&quot;&gt;999(docker)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;desktop에 docker(999) 그룹을 추가해줬어서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딱히 &lt;span class=&quot;code-span&quot;&gt;sudo docker ~&lt;/span&gt; 한 것이 아닌데도.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;어쨌든 docker가 자동으로 만들 때 root가 디렉터리를 만들게 된다.&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;color: #ee2323;&quot;&gt;사실 volume mount를 할 때,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;host의 디렉터리 소유권 (uid, gid)가 그대로 컨테이너에 전파된다.&lt;/span&gt;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$ &lt;span style=&quot;color: #ffffff;&quot;&gt;sudo su&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;root@vm:/home/desktop/Docker/bind-test#&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;id&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;uid=0(root)&amp;nbsp;gid=0(root)&amp;nbsp;groups=0(root)&lt;/span&gt;&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;root의 uid, gid가 각각 0이라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너에도 0:0으로 소유권을 덮어버리는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너에도 0은 root이기 때문에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;/mybind&lt;/span&gt;의 소유권이 0:0인 root:root로 덮어써진 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 volume 마운트를 하지 않고 컨테이너를 만들면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;에 &lt;span class=&quot;code-span code-r&quot;&gt;RUN chown -R user001:user001 /mybind&lt;/span&gt; 한 대로 user001 소유의 디렉터리로 나온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;host의 원본 디렉터리 소유 유저의 uid가 컨테이너 유저의 uid와 같으면 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;uid를 맞출 수 없는 상황도 있다. 그럼 gid를 맞추면 된다.&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;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;해결1&quot; data-ke-size=&quot;size16&quot;&gt;[volume mount의 문제 해결]&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;컨테이너에서 처음으로 adduser를 별다른 옵션없이 수행했으므로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;user001의 uid는 1000일 것이다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;docker&amp;nbsp;exec&amp;nbsp;-it&amp;nbsp;cont-bind-test&amp;nbsp;/bin/bash&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;user001@bind-test:/$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;id&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;uid=1000(user001)&amp;nbsp;gid=1000(user001)&amp;nbsp;groups=1000(user001)&lt;/span&gt;&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;host의 uid도 좋게도 1000으로 일치하는 상황이다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;id&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;uid=1000(desktop)&amp;nbsp;gid=1000(desktop)&amp;nbsp;groups=1000(desktop)&lt;/span&gt;,4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;122(lpadmin),135(lxd),136(sambashare),999(docker)&lt;/span&gt;&lt;/p&gt;&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;
&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;하지만 host의 uid가 2003 같은 상황이라면??&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;에서 유저생성시 &lt;span class=&quot;code-span code-r&quot;&gt;RUN adduser -u 2003 user001&lt;/span&gt; 처럼 uid를 지정해서 생성해준다.&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;뭐 어떻게 해도 uid를 맞추기는 힘든 상황이다?? (혹은 여러 소유권이 다른 여러 디렉터리를 마운트해야한다거나)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 host의 원본 디렉터리의 그룹소유권을 통일 시켜주고 해당 gid로 그룹을 맞춰주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gid가 4002라고 하면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;에서 먼저 &lt;span class=&quot;code-span code-r&quot;&gt;RUN addgroup -g 4002 group001&lt;/span&gt;로 gid가 같은 그룹을 생성.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 &lt;span class=&quot;code-span code-r&quot;&gt;RUN adduser -G 4002 user001&lt;/span&gt; (g는 기본그룹을 수정하지만, G는 기본그룹에 추가되도록)로 추가 그룹을 설정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저 생성 후에 &lt;span class=&quot;code-span code-r&quot;&gt;RUN addgroup -g 4002 user001&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 class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;을 수정하고 다시 컨테이너를 만들어야한다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$ &lt;span style=&quot;color: #ffffff;&quot;&gt;docker stop cont-bind-test&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;cont-bind-test&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$ &lt;span style=&quot;color: #ffffff;&quot;&gt;docker rm cont-bind-test&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;cont-bind-test&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$ &lt;span style=&quot;color: #ffffff;&quot;&gt;docker rmi image-bind-test&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Untagged: image-bind-test:latest&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Deleted: sha256:61f81705fd4fe64c647d9160517983facd615d231aec3b267a3e3464c3ee8738 &lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;이미 uid나 gid가 같다면 그냥 정지만 해두고 해결 후 재실행하자.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$ &lt;span style=&quot;color: #ffffff;&quot;&gt;docker stop cont-bind-test&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;cont-bind-test&lt;/span&gt;&lt;/p&gt;&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;
&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;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$ &lt;span style=&quot;color: #ffffff;&quot;&gt;sudo chown -R desktop:desktop ./bind-with-container&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;ls&amp;nbsp;-alR&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;.:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;20&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;20:39&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;desktop&amp;nbsp;desktop&lt;/span&gt;&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;bind-with-container&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;270&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:15&amp;nbsp;docker-compose.yml&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;280&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:34&amp;nbsp;Dockerfile&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;./bind-with-container&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;8&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;desktop&amp;nbsp;desktop&lt;/span&gt;&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;host의 컨테이너 소유권을 수정해주고, 다시 컨테이너를 실행하자.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;docker&amp;nbsp;compose&amp;nbsp;up&amp;nbsp;-d&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[+]&amp;nbsp;Running&amp;nbsp;1/1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;✔&amp;nbsp;Container&amp;nbsp;cont-bind-test&amp;nbsp;&amp;nbsp;Started&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.0s&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;ls&amp;nbsp;-alR&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;.:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;20&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;20:39&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;desktop&amp;nbsp;desktop&lt;/span&gt;&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:41&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;bind-with-container&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;270&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:15&amp;nbsp;docker-compose.yml&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rw-rw-r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;280&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:34&amp;nbsp;Dockerfile&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;span style=&quot;color: #f6e199;&quot;&gt;./bind-with-container&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;8&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;desktop&amp;nbsp;desktop&lt;/span&gt;&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:41&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxr-x&amp;nbsp;3&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;4096&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:39&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;-rw-r--r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:41&amp;nbsp;d&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;-rw-r--r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:41&amp;nbsp;e&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;-rw-r--r--&amp;nbsp;1&amp;nbsp;desktop&amp;nbsp;desktop&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;11월&amp;nbsp;11&amp;nbsp;21:41&amp;nbsp;f&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;d,e,f 파일이 잘 생성되었다.&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;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;desktop@vm:~/Docker/bind-test$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;docker&amp;nbsp;exec&amp;nbsp;-it&amp;nbsp;cont-bind-test&amp;nbsp;/bin/bash&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;user001@bind-test:/$&amp;nbsp;&lt;span style=&quot;color: #ffffff;&quot;&gt;ls&amp;nbsp;-al&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;64&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:35&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:35&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:35&amp;nbsp;.dockerenv&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;bin&amp;nbsp;-&amp;gt;&amp;nbsp;usr/bin&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Apr&amp;nbsp;18&amp;nbsp;&amp;nbsp;2022&amp;nbsp;boot&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;5&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;360&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:41&amp;nbsp;dev&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:35&amp;nbsp;etc&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Apr&amp;nbsp;18&amp;nbsp;&amp;nbsp;2022&amp;nbsp;home&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;lib&amp;nbsp;-&amp;gt;&amp;nbsp;usr/lib&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;lib32&amp;nbsp;-&amp;gt;&amp;nbsp;usr/lib32&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;lib64&amp;nbsp;-&amp;gt;&amp;nbsp;usr/lib64&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;libx32&amp;nbsp;-&amp;gt;&amp;nbsp;usr/libx32&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;media&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;mnt&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;user001&amp;nbsp;user001&lt;/span&gt;&amp;nbsp;4096&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:41&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;mybind&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;opt&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;dr-xr-xr-x&amp;nbsp;366&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:41&amp;nbsp;proc&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwx------&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:12&amp;nbsp;root&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;5&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:12&amp;nbsp;run&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;lrwxrwxrwx&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;sbin&amp;nbsp;-&amp;gt;&amp;nbsp;usr/sbin&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;srv&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;dr-xr-xr-x&amp;nbsp;&amp;nbsp;13&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&amp;nbsp;Nov&amp;nbsp;11&amp;nbsp;12:41&amp;nbsp;sys&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxrwxrwt&amp;nbsp;&amp;nbsp;&amp;nbsp;2&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:12&amp;nbsp;tmp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;14&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:08&amp;nbsp;usr&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4096&amp;nbsp;Oct&amp;nbsp;&amp;nbsp;4&amp;nbsp;02:12&amp;nbsp;var&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너의 &lt;span class=&quot;code-span&quot;&gt;/mybind&lt;/span&gt; 디렉터리의 소유권을 보면 원하는 대로 유지되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(사실은 원하는 목표의 uid:gid로 덮어쓴거지만)&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;문제2&quot; 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;여기선 java의 .jar 파일로 예시를 들겠습니다.(뭐 go lang이든 python이든...)&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;.jar 파일을 생성해주세요.&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;그리고 터미널의 위치를 변경하여 그곳에서 .jar파일을 실행해줍니다.(&lt;span class=&quot;code-span&quot;&gt;java -jar ~.jar ~&lt;/span&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;일부러 위치를 변경하여 그곳에서 다시 .jar파일을 실행해보세요.&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;span class=&quot;code-span&quot;&gt;Dockerfile&lt;/span&gt;에서 &lt;span class=&quot;code-span code-r&quot;&gt;USER ubuntu001&lt;/span&gt; 이후,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span code-r&quot;&gt;WORKDIR ~&lt;/span&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;user001의 권한을 갖는 &lt;span class=&quot;code-span&quot;&gt;/mybind&lt;/span&gt;로 이동해서 컨테이너가 빌드 파일을 실행한다면 하위 디렉터리도 만들고 파일도 제대로 생성하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span code-r&quot;&gt;WORKDIR /mybind&lt;/span&gt;가 없다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;root:root권한인 &lt;span class=&quot;code-span&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;해결2&quot; 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;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;해결1&quot;&gt;[volume mount의 문제 해결]&lt;/span&gt;이 된 상태라면 이번 문제는 딱히 어렵지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;CMD/ENTRYPOINT [ ~ ]&lt;/span&gt; 이전에 user001이 권한을 가진 곳으로 &lt;span class=&quot;code-span code-r&quot;&gt;WORKDIR ~&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;</description>
      <category>Study/Docker</category>
      <category>Docker</category>
      <category>mount</category>
      <category>Volume</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/325</guid>
      <comments>https://ydeer.tistory.com/325#entry325comment</comments>
      <pubDate>Sat, 11 Nov 2023 22:53:58 +0900</pubDate>
    </item>
    <item>
      <title>MongoDB 기초</title>
      <link>https://ydeer.tistory.com/323</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이전 포스트에서 mongosh로 MongoDB Shell로 접속한 후의 상황에서 이어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ydeer.tistory.com/322&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[Study/MongoDB] - Docker Compose로 MongoDB 환경 세팅&lt;/a&gt;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;blackdeer@Mac&amp;nbsp;mongodb&amp;nbsp;%&lt;/span&gt;&amp;nbsp;docker&amp;nbsp;exec&amp;nbsp;-it&amp;nbsp;&amp;nbsp;&amp;nbsp;mongodb&amp;nbsp;&amp;nbsp;&amp;nbsp;/bin/bash&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;root@mongodb:/#&lt;/span&gt;&amp;nbsp;mongo&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;bash:&amp;nbsp;mongo:&amp;nbsp;command&amp;nbsp;not&amp;nbsp;found&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;root@mongodb:/#&lt;/span&gt; &lt;span style=&quot;color: #ffff00;&quot;&gt;mongosh&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-u root&amp;nbsp;&amp;nbsp;&amp;nbsp;-p example&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Current&amp;nbsp;Mongosh&amp;nbsp;Log&amp;nbsp;ID:&amp;nbsp;64afa30efd5fb964295551f8 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Connecting&amp;nbsp;to:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongodb://&amp;lt;credentials&amp;gt;@127.0.0.1:27017/?directConnection=true&amp;amp;serverSelectionTimeoutMS=2000&amp;amp;appName=mongosh+1.10.1 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Using&amp;nbsp;MongoDB:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6.0.7 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Using&amp;nbsp;Mongosh:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.10.1 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;For&amp;nbsp;mongosh&amp;nbsp;info&amp;nbsp;see:&amp;nbsp;https://docs.mongodb.com/mongodb-shell/&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;------ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;The&amp;nbsp;server&amp;nbsp;generated&amp;nbsp;these&amp;nbsp;startup&amp;nbsp;warnings&amp;nbsp;when&amp;nbsp;booting &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;2023-07-13T07:01:43.903+00:00:&amp;nbsp;vm.max_map_count&amp;nbsp;is&amp;nbsp;too&amp;nbsp;low &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;------ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test&amp;gt;&lt;/span&gt;&amp;nbsp;show&amp;nbsp;databases&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;admin&amp;nbsp;&amp;nbsp;&amp;nbsp;100.00&amp;nbsp;KiB &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;config&amp;nbsp;&amp;nbsp;&amp;nbsp;60.00&amp;nbsp;KiB &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;local&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;72.00&amp;nbsp;KiB&lt;/span&gt;&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDB의 용어와 비교하자면 다음과 같다&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 400px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style6&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center; background-color: #1b711d; border-right: 1px solid white;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;RDB&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; background-color: #1b711d;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;MongoDB&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;p&gt;Database&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;p&gt;Database&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;p&gt;Table&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;p&gt;Collection&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;p&gt;Column&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;p&gt;Field&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;p&gt;Row&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;p&gt;Document&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDB는 &lt;b&gt;Table&lt;/b&gt;에 Column설정을 하고 데이터들을 Row 형태로 저장할텐데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Document형 NoSQL인 MongoDB는 &lt;b&gt;Collection&lt;/b&gt;에 json형식의 Document를 저장한다.&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;json문서가 데이터이며 내부 &lt;b&gt;키(Field)&lt;/b&gt;들이 RDB의 &lt;b&gt;Column&lt;/b&gt;과 &lt;u&gt;닮았다&lt;/u&gt;고 할 수 있는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDB처럼 Table 생성시 정한 Column들만 사용할 수 있는 것이 아니라&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;u&gt;그래서 하위 항목으로 갈 수록(Column, Row) 용어를 1:1로 완벽하게 매칭시킬 순 없다.&lt;/u&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;(그리고 이 수치는 RDB에서 얼마나 JOIN을 하는지, 데이터 디자인이 어떤지에 따라서도 달리지기 때문에&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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 class=&quot;code-span&quot;&gt;use 데이터베이스명&lt;/span&gt;으로 데이터베이스를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 정확하게는 현재 사용할 db를 선택하는 것이다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test&amp;gt;&lt;/span&gt; show databases&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;admin&amp;nbsp;&amp;nbsp;&amp;nbsp;100.00&amp;nbsp;KiB&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;config&amp;nbsp;&amp;nbsp;&amp;nbsp;72.00&amp;nbsp;KiB&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;local&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;72.00&amp;nbsp;KiB&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test&amp;gt;&lt;/span&gt; use test01&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;switched&amp;nbsp;to&amp;nbsp;db&amp;nbsp;test01&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;span style=&quot;color: #ffff00;&quot;&gt;test01&lt;/span&gt;&amp;gt;&lt;/span&gt; show dbs&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;admin&amp;nbsp;&amp;nbsp;&amp;nbsp;100.00&amp;nbsp;KiB&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;config&amp;nbsp;&amp;nbsp;&amp;nbsp;72.00&amp;nbsp;KiB&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;local&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;72.00 KiB&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 쉘 앞만 test에서 우리가 생성한 데이터베이스명(test01)으로 바뀌었을 뿐 데이터베이스는 아직 만들어지지 않은 것 같다.&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;MongoDB에서는 실제로 document나 collection을 생성해야만 DB가 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원문: MongoDB only creates the database when you first store data in that database. This data could be a collection or a document.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;a href=&quot;https://www.mongodb.com/basics/create-database&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.mongodb.com/basics/create-database&lt;/a&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;Mongo Express의 GUI를 통해서 database를 생성해도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부에는 delete_me 라는 이름의 빈 collection이 포함된 채로 database가 생성되게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;collection을 생성해보자&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.createCollection(&lt;span style=&quot;color: #409d00;&quot;&gt;'book'&lt;/span&gt;)&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;{&amp;nbsp;ok:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;1&lt;/span&gt;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;show&amp;nbsp;databases&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;admin&amp;nbsp;&amp;nbsp;&amp;nbsp;100.00&amp;nbsp;KiB &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;config&amp;nbsp;&amp;nbsp;108.00&amp;nbsp;KiB &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;local&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;72.00&amp;nbsp;KiB &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8.00&amp;nbsp;KiB&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제는 database가 생성된 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 collection 안에 문서를 저장해보자&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.book.find()&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.book.insertOne({&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;author&quot;&lt;/span&gt;: &lt;span style=&quot;color: #409d00;&quot;&gt;&quot;Kim&quot;&lt;/span&gt;,&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;title&quot;&lt;/span&gt;: &lt;span style=&quot;color: #409d00;&quot;&gt;&quot;Easy&amp;nbsp;Cooking&quot;&lt;/span&gt;})&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;acknowledged:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;true&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;insertedId:&amp;nbsp;ObjectId(&quot;64afe579952fbf5c1d6a917d&quot;) &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.book.insertMany([{&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;author&quot;&lt;/span&gt;: &lt;span style=&quot;color: #409d00;&quot;&gt;&quot;Park&quot;&lt;/span&gt;,&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;title&quot;&lt;/span&gt;: &lt;span style=&quot;color: #409d00;&quot;&gt;&quot;Chemical&amp;nbsp;Science&quot;&lt;/span&gt;,&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;publisher&quot;&lt;/span&gt;: &lt;span style=&quot;color: #409d00;&quot;&gt;&quot;Han-sam&quot;&lt;/span&gt;}, {&lt;span style=&quot;color: #f3c000;&quot;&gt;author&lt;/span&gt;: &lt;span style=&quot;color: #409d00;&quot;&gt;&quot;Lee&quot;&lt;/span&gt;, &lt;span style=&quot;color: #f3c000;&quot;&gt;title&lt;/span&gt;: &lt;span style=&quot;color: #409d00;&quot;&gt;&quot;Cat&amp;nbsp;Holic&quot;&lt;/span&gt;}])&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;acknowledged:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;true&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;insertedIds:&amp;nbsp;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'0'&lt;/span&gt;:&amp;nbsp;ObjectId(&quot;64afe58e952fbf5c1d6a917e&quot;), &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'1'&lt;/span&gt;:&amp;nbsp;ObjectId(&quot;64afe58e952fbf5c1d6a917f&quot;) &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;} &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.book.find()&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_id:&amp;nbsp;ObjectId(&quot;64afe579952fbf5c1d6a917d&quot;), &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;author:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Kim'&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Easy&amp;nbsp;Cooking' &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;}, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_id:&amp;nbsp;ObjectId(&quot;64afe58e952fbf5c1d6a917e&quot;), &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;author:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Park'&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Chemical&amp;nbsp;Science'&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp; &amp;nbsp; publisher: &lt;span style=&quot;color: #409d00;&quot;&gt;'Han-sam' &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;}, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_id:&amp;nbsp;ObjectId(&quot;64afe58e952fbf5c1d6a917f&quot;), &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;author:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Lee'&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Cat&amp;nbsp;Holic' &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;} &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;]&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;json형식으로 작성한 문구를 하나씩 혹은 여러개를 저장할 수 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;collection을 만들 때 RDB처럼 column을 정해둔 것이 아니기에&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.book.updateOne({&lt;span style=&quot;color: #f3c000;&quot;&gt;_id&lt;/span&gt;:&amp;nbsp;ObjectId(&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;64afe58e952fbf5c1d6a917f&quot;&lt;/span&gt;)},&amp;nbsp;{&lt;span style=&quot;color: #f3c000;&quot;&gt;$set&lt;/span&gt;:&amp;nbsp;{&lt;span style=&quot;color: #f3c000;&quot;&gt;author&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;Kim&quot;&lt;/span&gt;}})&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;acknowledged:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;true&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;insertedId:&amp;nbsp;null, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;matchedCount:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;1&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;modifiedCount:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;1&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;upsertedCount:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;0 &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.book.find({&lt;span style=&quot;color: #f3c000;&quot;&gt;author&lt;/span&gt;: &lt;span style=&quot;color: #409d00;&quot;&gt;'Kim'&lt;/span&gt;})&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_id:&amp;nbsp;ObjectId(&quot;64afe579952fbf5c1d6a917d&quot;), &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;author:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Kim'&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Easy&amp;nbsp;Cooking' &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;}, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_id:&amp;nbsp;ObjectId(&quot;64afe58e952fbf5c1d6a917f&quot;), &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;author:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Kim'&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Cat&amp;nbsp;Holic' &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;} &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;]&lt;/span&gt;&lt;/p&gt;&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;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.book.deleteOne({&lt;span style=&quot;color: #f3c000;&quot;&gt;_id&lt;/span&gt;:&amp;nbsp;ObjectId(&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;64afe579952fbf5c1d6a917d&quot;&lt;/span&gt;)})&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;{&amp;nbsp;acknowledged:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;true&lt;/span&gt;,&amp;nbsp;deletedCount:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;1&lt;/span&gt;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.book.find({&lt;span style=&quot;color: #f3c000;&quot;&gt;author&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #009a87;&quot;&gt;&quot;Kim&quot;&lt;/span&gt;})&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;{ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_id:&amp;nbsp;ObjectId(&quot;64afe58e952fbf5c1d6a917f&quot;), &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;author:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Kim'&lt;/span&gt;, &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;title:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'Cat&amp;nbsp;Holic' &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;} &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;]&lt;/span&gt;&lt;/p&gt;&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;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;collection의 삭제&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.book.drop()&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #f3c000;&quot;&gt;true&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;show&amp;nbsp;dbs&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;admin&amp;nbsp;&amp;nbsp;&amp;nbsp;100.00&amp;nbsp;KiB &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;config&amp;nbsp;&amp;nbsp;108.00&amp;nbsp;KiB &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;local&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;72.00&amp;nbsp;KiB&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;database에 남은 collection이 하나도 없기 때문에 database도 지워진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여전히 test01 db를 사용하는 상태이기 때문에 collection을 추가하면 바로 database와 함께 collection이 생성될 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;database의 삭제&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.dropDatabase()&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;{&amp;nbsp;ok:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;1&lt;/span&gt;,&amp;nbsp;dropped:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'test01'&lt;/span&gt;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;db.dropDatabase()&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;{&amp;nbsp;ok:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;1&lt;/span&gt;,&amp;nbsp;dropped:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;'test01'&lt;/span&gt;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;database 내부의 collection이나 document들 모두와 함께 지울 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MongoDB의 유저 생성은 admin database에 기록된다&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test01&amp;gt;&lt;/span&gt;&amp;nbsp;use&amp;nbsp;admin&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;switched&amp;nbsp;to&amp;nbsp;db&amp;nbsp;admin&lt;/span&gt;&lt;/p&gt;&lt;p&gt;　&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;admin&amp;gt;&lt;/span&gt;&amp;nbsp;db.createUser({&lt;span style=&quot;color: #f3c000;&quot;&gt;user&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;user01&quot;&lt;/span&gt;,&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;pwd&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;123456&quot;&lt;/span&gt;,&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;roles&lt;/span&gt;:&amp;nbsp;[{&lt;span style=&quot;color: #f3c000;&quot;&gt;role&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;readWrite&quot;&lt;/span&gt;,&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;db&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;&quot;test01&quot;&lt;/span&gt;}]})&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;{&amp;nbsp;ok:&amp;nbsp;&lt;span style=&quot;color: #f3c000;&quot;&gt;1&lt;/span&gt;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;976&quot; data-origin-height=&quot;781&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCc1CD/btsnxC3dJie/4kr0jyKSHPBSreVlruNpD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCc1CD/btsnxC3dJie/4kr0jyKSHPBSreVlruNpD0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCc1CD/btsnxC3dJie/4kr0jyKSHPBSreVlruNpD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCc1CD%2FbtsnxC3dJie%2F4kr0jyKSHPBSreVlruNpD0%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;976&quot; height=&quot;781&quot; data-origin-width=&quot;976&quot; data-origin-height=&quot;781&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위는 Mongo Express에서 확인한 화면(admin&amp;gt;system.users)&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;a href=&quot;https://www.mongodb.com/docs/v6.0/tutorial/create-users/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.mongodb.com/docs/v6.0/tutorial/create-users/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.mongodb.com/docs/v6.0/tutorial/manage-users-and-roles/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.mongodb.com/docs/v6.0/tutorial/manage-users-and-roles/&lt;/a&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서 중 기초 부분&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.mongodb.com/basics&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.mongodb.com/basics&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1689260786924&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Beginners Guide: MongoDB Basics&quot; data-og-description=&quot;Learn the basics of MongoDB and some of the key concepts.&quot; data-og-host=&quot;www.mongodb.com&quot; data-og-source-url=&quot;https://www.mongodb.com/basics&quot; data-og-url=&quot;https://www.mongodb.com/basics&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/WapFV/hyTjRt9yod/qhJXK0gim94SKCzdyHaXKK/img.png?width=1200&amp;amp;height=601&amp;amp;face=0_0_1200_601,https://scrap.kakaocdn.net/dn/6SMew/hyTixjL310/n6p34zhUmABMedkaY2k171/img.png?width=1079&amp;amp;height=536&amp;amp;face=0_0_1079_536&quot;&gt;&lt;a href=&quot;https://www.mongodb.com/basics&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.mongodb.com/basics&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/WapFV/hyTjRt9yod/qhJXK0gim94SKCzdyHaXKK/img.png?width=1200&amp;amp;height=601&amp;amp;face=0_0_1200_601,https://scrap.kakaocdn.net/dn/6SMew/hyTixjL310/n6p34zhUmABMedkaY2k171/img.png?width=1079&amp;amp;height=536&amp;amp;face=0_0_1079_536');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Beginners Guide: MongoDB Basics&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn the basics of MongoDB and some of the key concepts.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.mongodb.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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>Study/MongoDB</category>
      <category>mongodb</category>
      <category>NoSQL</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/323</guid>
      <comments>https://ydeer.tistory.com/323#entry323comment</comments>
      <pubDate>Thu, 13 Jul 2023 20:37:23 +0900</pubDate>
    </item>
    <item>
      <title>Docker Compose로 MongoDB 환경 세팅</title>
      <link>https://ydeer.tistory.com/322</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 docker-compose.yml 내용&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;&lt;span style=&quot;color: #7ee787;&quot;&gt;services&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;mongodb&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;image&lt;/span&gt;:&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;mongo&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;container_name&lt;/span&gt;:&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;mongodb&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;ports&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;27017:27017&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;environment&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;MONGO_INITDB_ROOT_USERNAME=root&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;MONGO_INITDB_ROOT_PASSWORD=example&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;volumes&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;./data/db:/data/db&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;networks&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;network-mongo&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;hostname&lt;/span&gt;:&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;mongodb&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;#&amp;nbsp;----------------------------------------&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;mongo-express&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;depends_on&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;mongodb&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;image&lt;/span&gt;:&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;mongo-express&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;container_name&lt;/span&gt;:&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;mongo-express&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;ports&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;27117:8081&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;environment&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;PORT=8081&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;ME_CONFIG_MONGODB_PORT=27017&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;ME_CONFIG_MONGODB_SERVER=mongodb&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;ME_CONFIG_MONGODB_ADMINUSERNAME=root&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;ME_CONFIG_MONGODB_ADMINPASSWORD=example&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;ME_CONFIG_MONGODB_URL=mongodb://root:example@mongodb:27017/&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;networks&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;network-mongo&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;hostname&lt;/span&gt;:&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;mongo-express&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;#&amp;nbsp;----------------------------------------&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #8b949e;&quot;&gt;#&amp;nbsp;========================================&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #7ee787;&quot;&gt;networks&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;network-mongo&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #7ee787;&quot;&gt;driver&lt;/span&gt;:&lt;span style=&quot;color: #a5d6ff;&quot;&gt;&amp;nbsp;bridge&lt;/span&gt;&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Compose 명령을 실행하면 최신 이미지를 받아 컨테이너를 구성한다&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;blackdeer@Mac&amp;nbsp;mongodb&amp;nbsp;%&lt;/span&gt;&amp;nbsp;docker-compose&amp;nbsp;up&amp;nbsp;-d&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[+]&amp;nbsp;Running&amp;nbsp;19/19 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;✔&amp;nbsp;mongo-express&amp;nbsp;8&amp;nbsp;layers&amp;nbsp;[⣿⣿⣿⣿⣿⣿⣿⣿]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0B/0B&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Pulled&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;21.8s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;6a428f9f83b0&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.7s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;f2b1fb32259e&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;12.0s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;40888f2a0a1f&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;12.2s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;4e3cc9ce09be&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;12.2s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;eaa1898f3899&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;12.3s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;ab4078090382&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;18.2s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;ae780a42c79e&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;18.2s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;e60224d64a04&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;18.2s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;✔&amp;nbsp;mongodb&amp;nbsp;9&amp;nbsp;layers&amp;nbsp;[⣿⣿⣿⣿⣿⣿⣿⣿⣿]&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0B/0B&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Pulled&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;36.8s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;9d19ee268e0d&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10.4s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;84c1327991fa&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;10.4s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;1feec59ecd14&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11.0s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;3af7480eaf55&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11.1s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;d7524ee16ced&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11.1s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;f4742175eefc&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11.2s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;9d688a8d9c18&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;11.2s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;b24ebfb25f44&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;33.1s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;✔&amp;nbsp;0ee52198e640&amp;nbsp;Pull&amp;nbsp;complete&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;33.2s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;[+]&amp;nbsp;Running&amp;nbsp;3/3 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;✔&amp;nbsp;Network&amp;nbsp;mongodb_network-mongo&amp;nbsp;&amp;nbsp;Created&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.0s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;✔&amp;nbsp;Container&amp;nbsp;mongodb&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Started&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.3s &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;✔ Container mongo-express&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Started&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0.5s&lt;/span&gt;&lt;/p&gt;&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;
&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;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;blackdeer@Mac&amp;nbsp;mongodb&amp;nbsp;%&lt;/span&gt;&amp;nbsp;docker&amp;nbsp;exec&amp;nbsp;-it&amp;nbsp;&amp;nbsp;&amp;nbsp;mongodb&amp;nbsp;&amp;nbsp;&amp;nbsp;/bin/bash&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;root@mongodb:/#&lt;/span&gt;&amp;nbsp;mongo&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;bash:&amp;nbsp;mongo:&amp;nbsp;command&amp;nbsp;not&amp;nbsp;found&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;root@mongodb:/#&lt;/span&gt; &lt;span style=&quot;color: #ffff00;&quot;&gt;mongosh&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;-u root&amp;nbsp;&amp;nbsp;&amp;nbsp;-p example&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Current&amp;nbsp;Mongosh&amp;nbsp;Log&amp;nbsp;ID:&amp;nbsp;64afa30efd5fb964295551f8 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Connecting&amp;nbsp;to:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mongodb://&amp;lt;credentials&amp;gt;@127.0.0.1:27017/?directConnection=true&amp;amp;serverSelectionTimeoutMS=2000&amp;amp;appName=mongosh+1.10.1 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Using&amp;nbsp;MongoDB:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6.0.7 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Using&amp;nbsp;Mongosh:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.10.1 &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;For&amp;nbsp;mongosh&amp;nbsp;info&amp;nbsp;see:&amp;nbsp;https://docs.mongodb.com/mongodb-shell/&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;------ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;The&amp;nbsp;server&amp;nbsp;generated&amp;nbsp;these&amp;nbsp;startup&amp;nbsp;warnings&amp;nbsp;when&amp;nbsp;booting &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;2023-07-13T07:01:43.903+00:00:&amp;nbsp;vm.max_map_count&amp;nbsp;is&amp;nbsp;too&amp;nbsp;low &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;------ &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;test&amp;gt;&lt;/span&gt;&amp;nbsp;show&amp;nbsp;databases&amp;nbsp;&lt;span class=&quot;cmdCursor&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;admin&amp;nbsp;&amp;nbsp;&amp;nbsp;100.00&amp;nbsp;KiB &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;config&amp;nbsp;&amp;nbsp;&amp;nbsp;60.00&amp;nbsp;KiB &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;local&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;72.00&amp;nbsp;KiB&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MongoDB 6.0부터는 mongo 명령이 아닌 mongosh 명령으로 쉘을 실행한다.&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;mongosh 접속 관련 문서는 여기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.mongodb.com/docs/mongodb-shell/connect/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.mongodb.com/docs/mongodb-shell/connect/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1689658911533&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Connect to a Deployment &amp;mdash; MongoDB Shell&quot; data-og-description=&quot;Docs Home &amp;rarr; MongoDB Shell This page shows how to use the MongoDB Shell to connect to a MongoDB deployment.To use the MongoDB Shell, you must have a MongoDB deployment to connect to.You can use the MongoDB Shell to connect to MongoDB version 4.2 or greate&quot; data-og-host=&quot;www.mongodb.com&quot; data-og-source-url=&quot;https://www.mongodb.com/docs/mongodb-shell/connect/&quot; data-og-url=&quot;https://www.mongodb.com/docs/mongodb-shell/connect/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/boJbgC/hyTlbOAyqy/t8eiTtyXxSy8Ryko6gh8aK/img.png?width=1200&amp;amp;height=601&amp;amp;face=0_0_1200_601,https://scrap.kakaocdn.net/dn/bEVaFO/hyTmo6CtWu/y3JXjJK45uKvk0xQR8I291/img.png?width=1200&amp;amp;height=601&amp;amp;face=0_0_1200_601&quot;&gt;&lt;a href=&quot;https://www.mongodb.com/docs/mongodb-shell/connect/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.mongodb.com/docs/mongodb-shell/connect/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/boJbgC/hyTlbOAyqy/t8eiTtyXxSy8Ryko6gh8aK/img.png?width=1200&amp;amp;height=601&amp;amp;face=0_0_1200_601,https://scrap.kakaocdn.net/dn/bEVaFO/hyTmo6CtWu/y3JXjJK45uKvk0xQR8I291/img.png?width=1200&amp;amp;height=601&amp;amp;face=0_0_1200_601');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Connect to a Deployment &amp;mdash; MongoDB Shell&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Docs Home &amp;rarr; MongoDB Shell This page shows how to use the MongoDB Shell to connect to a MongoDB deployment.To use the MongoDB Shell, you must have a MongoDB deployment to connect to.You can use the MongoDB Shell to connect to MongoDB version 4.2 or greate&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.mongodb.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;웹브라우저로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;http://localhost:27117/&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(위는 도커 컨테이너가 localhost에서 돌아가고 있을 때의 예시)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 접근하면 Mongo Express의 GUI로 DB를 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(docker-compose.yml에서 mongo-express의 내부 8081포트를 외부 27117로 포워딩했었다)&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;</description>
      <category>Study/MongoDB</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/322</guid>
      <comments>https://ydeer.tistory.com/322#entry322comment</comments>
      <pubDate>Thu, 13 Jul 2023 16:42:56 +0900</pubDate>
    </item>
    <item>
      <title>iOS ChatGPT 단축어</title>
      <link>https://ydeer.tistory.com/321</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 ChatGPT를 이용하기 위한 계정이 필요합니다.&lt;br&gt;&lt;a href=&quot;https://platform.openai.com/&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://platform.openai.com/&lt;/span&gt;&lt;/a&gt;&lt;br&gt;에서 회원가입을 한 후(이미 사용하고 있었다면 그냥 로그인),&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;a href=&quot;https://platform.openai.com/account/api-keys&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://platform.openai.com/account/api-keys&lt;/span&gt;&lt;/a&gt;&lt;br&gt;여기로 들어가서 API key를 생성합니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;690&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MIo31/btsfjJEdpVa/Vmb0mm4kSZ5bJJAIzENBRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MIo31/btsfjJEdpVa/Vmb0mm4kSZ5bJJAIzENBRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MIo31/btsfjJEdpVa/Vmb0mm4kSZ5bJJAIzENBRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMIo31%2FbtsfjJEdpVa%2FVmb0mm4kSZ5bJJAIzENBRk%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;508&quot; height=&quot;690&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;690&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 버튼을 눌러 키를 생성합니다.&lt;br&gt;&lt;u&gt;&lt;b&gt;키는 한 번 보여준 후 다시는 공개하지 않으니, 잘 복사해둡니다.&lt;/b&gt;&lt;/u&gt;&lt;br&gt;잊어버렸다면 다시 생성하면되지만...&lt;br&gt;&amp;nbsp;&lt;br&gt;그리고 단축어를 복제받은 애플기기(iOS/iPad OS/Mac)에서&lt;br&gt;위 키를 복사한 상태로 진행합니다.&lt;br&gt;그래야 아래 복제 단계에서 키를 입력하기 수월합니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;iOS/iPad OS/Mac 등 &lt;b&gt;애플 기기에서 아래의 단축어 공유 링크를 클릭&lt;/b&gt;하여 단축어를 복제받습니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;background-color: #006dd7;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;①&lt;/span&gt;&lt;/span&gt; [텍스트 직접 입력형 + 취소 전까지 반복]&lt;br&gt;&lt;span style=&quot;background-color: #006dd7;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;직접 눌러서&lt;/b&gt;&lt;/span&gt;&lt;/span&gt; 사용에 추천&lt;br&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/8758a78c9dc84adc9aa5ab4bc8917971&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://www.icloud.com/shortcuts/8758a78c9dc84adc9aa5ab4bc8917971&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;background-color: #8a3db6;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;②&lt;/span&gt;&lt;/span&gt; [음성 받아 넘김형 + 취소 전까지 반복]&lt;br&gt;&lt;span style=&quot;background-color: #8a3db6;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;Siri&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;에 추천 (Siri야, 단축어이름)&lt;br&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/f033d9fe68e2486e9d8cb1707e6cdc64&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://www.icloud.com/shortcuts/f033d9fe68e2486e9d8cb1707e6cdc64&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;background-color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;③&lt;/span&gt;&lt;/span&gt; [음성 받아 넘김형 + 한 번만 실행]&lt;br&gt;&lt;span style=&quot;background-color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;Apple Watch&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;에 추천 (Apple Watch에서 단축어앱을 실행하여 직접 눌러서 사용에 추천)&lt;br&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/610fbcc06c2d4a0fb2482eca52b33110&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://www.icloud.com/shortcuts/610fbcc06c2d4a0fb2482eca52b33110&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;복제받을 때 두 가지를 설정하도록 되어있습니다.&lt;br&gt;ㆍ하나는 위에서 작성한 API key입니다. 복사해두었으니 붙여넣으면 됩니다.&lt;br&gt;ㆍ두번째는 temperature인데, 0.0~2.0의 값으로,&lt;br&gt;　0.0에 가까울 수록 정확한 답만을 할 뿐, 부정확한 정보는 아예 걸러버리며,&lt;br&gt;　2.0에 가까울 수록 사람처럼 답하려고 하며, 조금 부정확하더라도 제공해주려고 합니다.&lt;br&gt;　기본값은 1.0입니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;이렇게 생성한 단축어들은 모두 ChatGPT로 넘기고 응답을 받아야 하므로&lt;br&gt;권한 동의가 최초 실행시에 한 번 뜹니다.&lt;br&gt;항상 허용해주면 됩니다.&lt;br&gt;&lt;br&gt;&lt;br&gt;위 셋 모두 현재 시간, 질문, 응답을 하나로 묶어 메모앱에 기록하는 로그 기능이 있습니다.&lt;br&gt;이런 기능들은 입맛에 맞게 수정하거나 삭제하시면 됩니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;Siri에게 음성으로 묻기에는 &lt;span style=&quot;background-color: #8a3db6;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;②&lt;/span&gt;&lt;/span&gt;가 제일 적합합니다.(음성으로 넘기고, 반복해서 물어볼 수 있기 때문)&lt;br&gt;&lt;span style=&quot;background-color: #8a3db6;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;②&lt;/span&gt;&lt;/span&gt;의 이름을 '알려줘'라고 지정해둔다면,&lt;br&gt;&quot;Siri야, 알려줘&quot;의 발화문을 Siri가 들었을 때 실행되어 음성을 받아 ChatGPT로 넘기고 응답을 받아 읽어줍니다.&lt;br&gt;(Siri로 실행했을 때는 응답을 읽어줍니다)&lt;br&gt;(잠금상태가 아닐 때는 자연스럽게 반복되지만, 잠금 상태에서는 로그를 메모에 작성하려고 잠금 해제를 하려고 합니다.&lt;br&gt;이런 부분이 싫다면 로그 작성 부분을 지우시면 됩니다.)&lt;br&gt;①과 &lt;span style=&quot;background-color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;③&lt;/span&gt;&lt;/span&gt;은 Siri로 실행되지 않을 법한 이름으로 지정해두시면 Siri의 혼선을 피할 수 있습니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;background-color: #006dd7;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;①&lt;/span&gt;&lt;/span&gt;은 텍스트를 직접 입력하기에 음성 받아쓰기의 부정확함을 피할 수 있습니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;background-color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;③&lt;/span&gt;&lt;/span&gt;은 Apple Watch의 음성 받아쓰기는 어차피 '완료'를 누르기 까지는 음성 종료를 인식하지 않으며,&lt;br&gt;응답 결과를 직접 닫기도 해야하기에,&lt;br&gt;반복형이라 종료시에 취소를 눌러야 하는 형태가 아니라&lt;br&gt;그냥 한 번만 실행되게 하였습니다.&lt;br&gt;&lt;span style=&quot;background-color: #006dd7;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;①&lt;/span&gt;&lt;/span&gt;과 &lt;span style=&quot;background-color: #8a3db6;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;②&lt;/span&gt;&lt;/span&gt;는 &lt;b&gt;Apple Watch에서 보기&lt;/b&gt;를 꺼주시고, &lt;span style=&quot;background-color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;③&lt;/span&gt;&lt;/span&gt;만 켜주시면 혼잡해지지 않습니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;609&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bo9FN0/btsfjJxudUK/O5oDbSK4xQkMvSoKhwiJxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bo9FN0/btsfjJxudUK/O5oDbSK4xQkMvSoKhwiJxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bo9FN0/btsfjJxudUK/O5oDbSK4xQkMvSoKhwiJxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbo9FN0%2FbtsfjJxudUK%2FO5oDbSK4xQkMvSoKhwiJxk%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;562&quot; height=&quot;609&quot; data-origin-width=&quot;562&quot; data-origin-height=&quot;609&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;위의 단축어들은 가장 기본적인 request로 작성했습니다.&lt;br&gt;REST API의 다른 옵션들은 아래의 링크 문서에서 확인&lt;br&gt;&lt;a href=&quot;https://platform.openai.com/docs/api-reference/completions/create&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://platform.openai.com/docs/api-reference/completions/create&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Programs/etc</category>
      <category>ChatGPT</category>
      <category>IOS</category>
      <category>단축어</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/321</guid>
      <comments>https://ydeer.tistory.com/321#entry321comment</comments>
      <pubDate>Mon, 15 May 2023 15:40:15 +0900</pubDate>
    </item>
    <item>
      <title>[Lv4] 징검다리 - 이분탐색(BS)</title>
      <link>https://ydeer.tistory.com/320</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;출발지점부터 distance만큼 떨어진 곳에 도착지점이 있습니다.&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;예를 들어, 도착지점이 25만큼 떨어져 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바위가 [2, 14, 11, 21, 17] 지점에 놓여있을 때 바위 2개를 제거하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출발지점, 도착지점, 바위 간의 거리가 아래와 같습니다.&lt;/p&gt;
&lt;table style=&quot;text-align: left; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style6&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;background-color: #1b711d; border-right: 1px solid white;&quot;&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;제거한 바위의 위치&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #1b711d; border-right: 1px solid white;&quot;&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;각 바위 사이의 거리&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #1b711d;&quot;&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;거리의 최솟값&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;[21, 17]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[2, 9, 3, 11]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;[2, 21]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[11, 3, 3, 8]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;[2, 11]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[14, 3, 4, 4]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;3&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;[11, 21]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[2, 12, 3, 8]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;[2, 14]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[11, 6, 4, 4]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 구한 거리의 최솟값 중에 가장 큰 값은 4입니다.&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;출발지점부터 도착지점까지의 거리 distance,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바위들이 있는 위치를 담은 배열 rocks,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제거할 바위의 수 n이 매개변수로 주어질 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바위를 n개 제거한 뒤 각 지점 사이의 거리의 최솟값 중에 가장 큰 값을 return 하도록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;solution 함수를 작성해주세요.&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;제한사항&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ도착지점까지의 거리 distance는 1 이상 1,000,000,000 이하입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ바위는 1개 이상 50,000개 이하가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍn 은 1 이상&amp;nbsp;바위의 개수&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;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;text-align: left; 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;background-color: #1b711d; border-right: 1px solid white;&quot;&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;distance&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #1b711d; border-right: 1px solid white;&quot;&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;rocks&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #1b711d; border-right: 1px solid white;&quot;&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;n&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #1b711d;&quot;&gt;&lt;p&gt;&lt;b&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;return&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;p&gt;25&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;[2, 14, 11, 21, 17]&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;2&lt;/p&gt;&lt;/td&gt;
&lt;td&gt;&lt;p&gt;4&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ제한사항의 1항에서 10억의 숫자를 보고 이진 탐색의 힌트를 얻는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ각 바위 사이의 거리를 벌리는 것이다. '거리'를 대상으로 푼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ주어지는 배열 rocks는 정렬된 상태가 아니다. 거리를 구하기 위해 먼저 rocks 배열을 정렬하고 시작한다.&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;span style=&quot;background-color: #f6e199;&quot;&gt;(8) &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;돌&lt;/span&gt;&lt;/b&gt; (8) 돌 (12) 돌 (13) 돌 (8) &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;돌&lt;/b&gt;&lt;/span&gt; (8) 돌 (14) 돌 (19)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;빨간 돌&lt;/span&gt;&lt;/b&gt;도 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;파란 돌&lt;/b&gt;&lt;/span&gt;도 양 옆의 간격이 8씩으로, 8도 같고, 8+8=16도 동일하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;어느 돌을 선택하느냐에 따라 다음 번에 영향을 주고,&lt;/u&gt; 바위의 수는 최대 5만 개에 거리는 10억.&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;이분 탐색에서 뭘 기준으로 삼는가&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;b&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;바위의 왼쪽 간격이 이 기준치 이하라면 제거한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(왼쪽 간격을 보면, 반복문에서 가장 마지막 간격은 검토 대상에서 제외된다. 이 간격은 바위 기준 오른쪽 distance와의 간격이라)&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;바위를 n보다 더 많이 제거했다면 기준치가 높은 것이니 내려야한다(더 적게 부수도록. &lt;span class=&quot;code-span&quot;&gt;high = mid&lt;/span&gt;).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바위를 n보다 더 적게 제거했다면 기준치가 낮은 것이니 높여야한다(더 많이 부수도록. &lt;span class=&quot;code-span&quot;&gt;low = mid&lt;/span&gt;).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바위를 n만큼 딱 부수었어도 기준치는 높여본다. n보다 초과하지는 않지만 n만큼인 선에서 최대한 제거하도록 기준치를 높인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(우리가 이분 탐색하면서 찾는 것이 n이 아니며, 바위를 제거하는 기준임. 또한 최종 정답이 이 기준도 아닌 것도 기억)&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;이분 탐색시 맨 처음 low ~ high 값은 무엇이겠는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;기준치로 간격을 판정&lt;/b&gt;한다고 했으니 이것도 &lt;b&gt;간격&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 바위를 제거했다면 간격이 최대가 되고, 이 값은 distance와 일치한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;0 ~ distance&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이분 탐색을 하면서 바위를 제거하는 횟수가 n이면서 바위를 부수는 기준이 한 곳으로 수렴할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 최종 제출 답이 이 기준이 아니라 n만큼 제거했을 때의 경우들 중에서&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;간격들은 최대 50002개가 될 수 있으니, 이 간격들을 훑는 때도 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 n이 3이라고 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이분 탐색에서 어떤 기준으로 바위들을 모두 제거했을 때, &lt;b&gt;제거한 수가 3보다 더 많을 때(4 이상인 때)의 간격들은 딱히 도움이 안된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n보다 더 많이 제거할 수 있다면 그냥 다 제거해서 최대 간격도 나올테니...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이분 탐색시 &lt;b&gt;제거하는 수가 n과 같아질 때&lt;/b&gt; 간격의 최솟값을 구한다. 그리고 n보다 높아질 땐 더 이상 진행하지 않고 바로 기준치를 낮추는 다음 루프를 진행해도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;n보다 더 적게 제거한 상황은 어떨까?&lt;/b&gt;(기준치가 낮아서 모든 간격을 훑었지만 n보다 적게 제거하고 끝난 상태)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이분 탐색으로 기준치를 시험해보는 과정에서 기준치가 낮다는 것을 안 것과 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;별개로&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우는 확실히 n보다 더 적게 제거하고도 간격을 많이 벌린 훌륭한 경우이다. 여기서 부족한 수 만큼 더 제거한다면 최소 간격은 더 벌어질 수 있다! 그러니 이 때의 간격 중 최솟값도 저장해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 최솟값을 저장하는 때는 &lt;b&gt;'n과 일치하게 제거했을 때'&lt;/b&gt;와 &lt;b&gt;'n보다 적게 제거하고도 모든 간격을 훑게 되었을 때'&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;
&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;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;(2)&lt;sub&gt;0&lt;/sub&gt;&lt;/b&gt;&lt;/span&gt; (4)&lt;sub&gt;1&lt;/sub&gt; (8)&lt;sub&gt;2&lt;/sub&gt; (4)&lt;sub&gt;3&lt;/sub&gt; (7)&lt;sub&gt;4&lt;/sub&gt; (2)&lt;sub&gt;5&lt;/sub&gt; (12)&lt;sub&gt;6&lt;/sub&gt; (8)&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인 배열을 보자(아래 첨자로 index 표기). &lt;span style=&quot;color: #ee2323;&quot;&gt;기준치가 7&lt;/span&gt;인 상황.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 처음에는 &lt;span style=&quot;color: #006dd7;&quot;&gt;0번 index(값:2)&lt;/span&gt;를 오른쪽과 합칠지 말지 결정할 것이다(바위로 생각하면 0번과 1번 사이의 바위가 제거되어 양 간격이 합쳐지는 상황)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;2&lt;/span&gt;는 &lt;span style=&quot;color: #ee2323;&quot;&gt;7&lt;/span&gt;보다 작으니, 합쳐지면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;(-)&lt;sub&gt;0&lt;/sub&gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;(6)&lt;sub&gt;1&lt;/sub&gt;&lt;/b&gt;&lt;/span&gt; (8)&lt;sub&gt;2&lt;/sub&gt; (4)&lt;sub&gt;3&lt;/sub&gt; (7)&lt;sub&gt;4&lt;/sub&gt; (2)&lt;sub&gt;5&lt;/sub&gt; (12)&lt;sub&gt;6&lt;/sub&gt; (8)&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;합쳐진다면 index가 증가하고(이번엔 &lt;span style=&quot;color: #006dd7;&quot;&gt;1번 index(값:6 =2+4)&lt;/span&gt;를 보게되니), 제거될 값이 다음 검토시에 합쳐지도록 기억만 하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;6&lt;/span&gt;(=2+4)도&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;7&lt;/span&gt;보다 작으니 합쳐질 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;(-)&lt;sub&gt;0&lt;/sub&gt; (-)&lt;sub&gt;1&lt;/sub&gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;(14)&lt;sub&gt;2&lt;/sub&gt;&lt;/b&gt;&lt;/span&gt; (4)&lt;sub&gt;3&lt;/sub&gt; (7)&lt;sub&gt;4&lt;/sub&gt; (2)&lt;sub&gt;5&lt;/sub&gt; (12)&lt;sub&gt;6&lt;/sub&gt; (8)&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에도 index도 증가하고(이번엔 &lt;span style=&quot;color: #006dd7;&quot;&gt;2번 index(값:14 =2+4+8)&lt;/span&gt;를 보게되니), 제거된 값도 합쳐졌다.(배열에 값을 변화시키면 다시 원복하거나 원본을 복제받거나 해야하니, 그냥 sum용 변수에 합치도록 한다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;14&lt;/span&gt;(=2+4+8)는&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;7&lt;/span&gt;보다 크니, &lt;b&gt;합쳐지지 않는다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;(-)&lt;sub&gt;0&lt;/sub&gt; (-)&lt;sub&gt;1&lt;/sub&gt; (14)&lt;sub&gt;2&lt;/sub&gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;(4)&lt;sub&gt;3&lt;/sub&gt;&lt;/b&gt;&lt;/span&gt; (7)&lt;sub&gt;4&lt;/sub&gt; (2)&lt;sub&gt;5&lt;/sub&gt; (12)&lt;sub&gt;6&lt;/sub&gt; (8)&lt;sub&gt;7&lt;/sub&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 index만 증가하고(이번엔 &lt;span style=&quot;color: #006dd7;&quot;&gt;3번 index(값:4)&lt;/span&gt;를 보게되니), 검토하는 값은 &lt;span style=&quot;color: #006dd7;&quot;&gt;3번 index&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;바위를 제거할 때(간격이 합쳐질 때)는 index증가, 다음 번 검토시에 합친 값이 검토되도록 값을 저장.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바위를 제거하지 않을 때(넘길 때)는 index만 증가, 검토시에 같이 검토하던 값을 0으로.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(즉, index는 항상 증가. 검토시 같이 보는 값에 누적하거나 초기화하거나.)&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;u&gt;시간복잡도를 늘리지 않을 수 있다.&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;span style=&quot;color: #006dd7;&quot;&gt;min&lt;/span&gt;은 이번 이분 탐색에서의 간격 중 최솟값. &lt;span style=&quot;color: #ee2323;&quot;&gt;result&lt;/span&gt;는 전체 케이스에서 최솟값들 중 최댓값)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 바위를 제거한 수가 n을 넘기지 않은 때라면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;바위를 제거하지 않을 때엔&lt;/b&gt; 넘어가면서 기존 값을 &lt;span style=&quot;color: #006dd7;&quot;&gt;min&lt;/span&gt;과 비교하여 기록.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;바위를 제거할 땐&lt;/b&gt; 계속 변할 값(더 누적될 수도 있는)이니 당장 신경쓰지 않아도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;하지만 제거하는 수가 n이 된 순간&lt;/b&gt;에는 더 이상의 제거는 의미가 없으니,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n이 된 순간에 현재 검토하던 값과 그 뒤로의 간격들을 끝까지 모두 훑으면서 값들을 &lt;span style=&quot;color: #006dd7;&quot;&gt;min&lt;/span&gt;과 비교하여 기록.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 훑은 후, 이 &lt;span style=&quot;color: #006dd7;&quot;&gt;min&lt;/span&gt;이 &lt;span style=&quot;color: #ee2323;&quot;&gt;result&lt;/span&gt;와 비교하여 그보다 크다면 기록 후 이분 탐색을 다시 하도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;n보다 적게 바위를 제거하고도 모든 간격을 훑은 경우&lt;/b&gt;라면, &lt;b&gt;'마지막 간격'&lt;/b&gt;만 한 번 더 &lt;span style=&quot;color: #006dd7;&quot;&gt;min&lt;/span&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;span style=&quot;color: #006dd7;&quot;&gt;min&lt;/span&gt;이 &lt;span style=&quot;color: #ee2323;&quot;&gt;result&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;이렇게 이분 탐색에서 low ~ high가 한 곳으로 수렴한 상황에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그동안 매 회 &lt;span style=&quot;color: #006dd7;&quot;&gt;min&lt;/span&gt;들 중 최댓값을 기록한 &lt;span style=&quot;color: #ee2323;&quot;&gt;result&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바위를 n개 제거하는 모든 경우를 훑어서 올바른 &lt;span style=&quot;color: #ee2323;&quot;&gt;result&lt;/span&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;</description>
      <category>Problem Solving/programmers</category>
      <category>binary search</category>
      <category>binarySearch</category>
      <category>BS</category>
      <category>이분탐색</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/320</guid>
      <comments>https://ydeer.tistory.com/320#entry320comment</comments>
      <pubDate>Mon, 17 Apr 2023 14:38:57 +0900</pubDate>
    </item>
    <item>
      <title>다운로드 파일 hash check용 certutil bat</title>
      <link>https://ydeer.tistory.com/319</link>
      <description>&lt;pre id=&quot;code_1685766578431&quot; class=&quot;prettyprint lang-bsh bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@echo off
echo %1
For /F Delims^= %%G In ('certutil -hashfile %1 MD5 ^| FindStr /VRC:&quot;[^a-f 0-9]&quot;') Do Set &quot;md5=%%G&quot;
echo.
echo    MD5: %md5%
For /F Delims^= %%G In ('certutil -hashfile %1 SHA1 ^| FindStr /VRC:&quot;[^a-f 0-9]&quot;') Do Set &quot;sha1=%%G&quot;
echo.
echo   SHA1: %sha1%
For /F Delims^= %%G In ('certutil -hashfile %1 SHA256 ^| FindStr /VRC:&quot;[^a-f 0-9]&quot;') Do Set &quot;sha256=%%G&quot;
echo.
echo SHA256: %sha256%
For /F Delims^= %%G In ('certutil -hashfile %1 SHA512 ^| FindStr /VRC:&quot;[^a-f 0-9]&quot;') Do Set &quot;sha512=%%G&quot;
echo.
echo SHA512: %sha512%
For /F Delims^= %%G In ('certutil -hashfile %1 MD2 ^| FindStr /VRC:&quot;[^a-f 0-9]&quot;') Do Set &quot;md2=%%G&quot;
echo.
echo    MD2: %md2%
For /F Delims^= %%G In ('certutil -hashfile %1 MD4 ^| FindStr /VRC:&quot;[^a-f 0-9]&quot;') Do Set &quot;md4=%%G&quot;
echo.
echo    MD4: %md4%
For /F Delims^= %%G In ('certutil -hashfile %1 SHA384 ^| FindStr /VRC:&quot;[^a-f 0-9]&quot;') Do Set &quot;sha384=%%G&quot;
echo.
echo SHA384: %sha384%
echo.
pause&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성한 .bat 아이콘 위에 파일을 드래그앤드롭으로 실행&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(분석하려는 파일의 용량이 클 수록 오래 걸리기 때문에(특히 MD2),&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 hash algorithm만 남기고 제거해도 됨)&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>Programs/help</category>
      <category>Bat</category>
      <category>certutil</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/319</guid>
      <comments>https://ydeer.tistory.com/319#entry319comment</comments>
      <pubDate>Mon, 6 Mar 2023 12:13:17 +0900</pubDate>
    </item>
    <item>
      <title>TransNOCR 1.8.0 업데이트 후기</title>
      <link>https://ydeer.tistory.com/318</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 플로팅 번역의 폰트 관련하여 받은 요청사항이 있어서 해당 기능을 중점으로 수정했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;rotation.gif&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;223&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IXJWX/btr1p1EmEPz/rgYFneMTU3JUttoK6xq6fK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IXJWX/btr1p1EmEPz/rgYFneMTU3JUttoK6xq6fK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IXJWX/btr1p1EmEPz/rgYFneMTU3JUttoK6xq6fK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/IXJWX/btr1p1EmEPz/rgYFneMTU3JUttoK6xq6fK/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;397&quot; height=&quot;223&quot; data-filename=&quot;rotation.gif&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;223&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;/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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0374.PNG&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;1760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNz4zt/btr1I8vhYRx/BlI7xkS178RLaAeeb5iLa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNz4zt/btr1I8vhYRx/BlI7xkS178RLaAeeb5iLa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNz4zt/btr1I8vhYRx/BlI7xkS178RLaAeeb5iLa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNz4zt%2Fbtr1I8vhYRx%2FBlI7xkS178RLaAeeb5iLa1%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;1640&quot; height=&quot;1760&quot; data-filename=&quot;IMG_0374.PNG&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;1760&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, Google Vision OCR이 항상 네 꼭지점을 동일한 순서대로만 주지 않고 가끔씩 뒤틀려 주기도 해서&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;그래서 직각일 때는 가로/세로 중 긴 것으로만 판단하여 0˚, 270˚로만 출력.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세로가 가로가 되고 가로가 세로가 되는 버그보다는 낫다고 판단하여...ㅠ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_0375.PNG&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;2020&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjN2JY/btr1Kxn20bc/cbSBubblemgy96okBLV7H0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjN2JY/btr1Kxn20bc/cbSBubblemgy96okBLV7H0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjN2JY/btr1Kxn20bc/cbSBubblemgy96okBLV7H0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjN2JY%2Fbtr1Kxn20bc%2FcbSBubblemgy96okBLV7H0%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;1640&quot; height=&quot;2020&quot; data-filename=&quot;IMG_0375.PNG&quot; data-origin-width=&quot;1640&quot; data-origin-height=&quot;2020&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;/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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로그램은 개발 키를 사용하는 특성상 일반인들이 설치하기에도 좀 번거로운 부분이 있는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중 jre도 그렇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java를 다루기 전에는 jre가 필요한 3D 모델링 프로그램을 사용할 때 이걸 왜 경로에 둬야하는지도 모르겠던 경험이 있으니,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 분들이 계실 것이라 생각했고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차라리 Windows에 더 친화적인 Qt로 포팅(이래봤자 새로 짜는 것이지만)해보려고 했는데...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;qt01.png&quot; data-origin-width=&quot;937&quot; data-origin-height=&quot;1022&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IQJul/btr1nxDExpH/vWsLus102ALpvCoJcnWs71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IQJul/btr1nxDExpH/vWsLus102ALpvCoJcnWs71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IQJul/btr1nxDExpH/vWsLus102ALpvCoJcnWs71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIQJul%2Fbtr1nxDExpH%2FvWsLus102ALpvCoJcnWs71%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;937&quot; height=&quot;1022&quot; data-filename=&quot;qt01.png&quot; data-origin-width=&quot;937&quot; data-origin-height=&quot;1022&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;qt02.png&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;799&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mwJ62/btr1fOzeILi/fe87lFjSKPMdjMchsWCbOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mwJ62/btr1fOzeILi/fe87lFjSKPMdjMchsWCbOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mwJ62/btr1fOzeILi/fe87lFjSKPMdjMchsWCbOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmwJ62%2Fbtr1fOzeILi%2Ffe87lFjSKPMdjMchsWCbOK%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;529&quot; height=&quot;799&quot; data-filename=&quot;qt02.png&quot; data-origin-width=&quot;529&quot; data-origin-height=&quot;799&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OCR까지는 잘 진행이 되었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외에 사용했던 라이브러리가 Java에는 있으나 C++에는 없는 것들이 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 Google 라이브러리는 공식 문서에 C++은 없고(그래도 Github에서 googleapis 검색하면 vision은 찾을 수 있음. vcpkg에도 있고),&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Google Drive나 Sheets는 모두 중단된 프로젝트에 Deprecated 코드들이라 어차피 새로 짜야하고...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C++로 웹드라이버는 영 아닌가?? 웹드라이버도 없고...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴거면 그냥 Dart에 Flutter로 하는게 아예 더 빠를 듯ㅎ&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;첨에 qmake도 삽질했다가, CMake로 갈아엎고, vcpkg도 써보고...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배운건 있지만 결국 끝까진 가지 못한 상태ㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용하는 기능들이 모두 REST API였다면 별 문제도 아니었겠지만, 그렇지 않다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 Google쪽은 gRPC나 자체 규격들이라ㅠ&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;그래도 Qt는 qml로 Model/View에 Binding을 하는게 역시 편했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Xamarin 때도 yaml로 나눠둔게 편했었는데.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한참 Qt로 짜다가 Java 버전을 업데이트한건데, 그러다보니 새삼 Model/View가 참 편했구나 싶더라...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 Java로 GUI 프로그램 짜는게 맞나 싶기도 하다. 이건 만들 때부터 그랬긴 했는데, 필요한 기능들이 쓰기 좋게 펼쳐져 있던지라...ㅠ&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;C++에 대한 사랑으로 괜히 Qt로 방향을 잡았나 싶더라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 Xamarin으로 갔으면 .Net Framework를 썼을테니 라이브러리가 그나마 더 있었을 거고(Google 라이브러리도 C#은 있다).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아니면 Dart에 Flutter를 갔어야했나ㅎㅎ&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>Diary</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/318</guid>
      <comments>https://ydeer.tistory.com/318#entry318comment</comments>
      <pubDate>Thu, 2 Mar 2023 18:17:26 +0900</pubDate>
    </item>
    <item>
      <title>AWS CodeDeploy에서 대상을 AutoScaling으로 했을 때 발생할 수 있는 문제들</title>
      <link>https://ydeer.tistory.com/317</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: 그저 간단한 Code Deploy 설정&quot; data-text-less=&quot;닫기: 그저 간단한 Code Deploy 설정&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.png&quot; data-origin-width=&quot;1131&quot; data-origin-height=&quot;398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dBCuWO/btrYzZ3fTpA/BIGgUKzlAedbqzyJDOKMgk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dBCuWO/btrYzZ3fTpA/BIGgUKzlAedbqzyJDOKMgk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dBCuWO/btrYzZ3fTpA/BIGgUKzlAedbqzyJDOKMgk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdBCuWO%2FbtrYzZ3fTpA%2FBIGgUKzlAedbqzyJDOKMgk%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;1131&quot; height=&quot;398&quot; data-filename=&quot;01.png&quot; data-origin-width=&quot;1131&quot; data-origin-height=&quot;398&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/neufb/btrYBdmq4RL/Xw0EydhOOdoubhnosMZutk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/neufb/btrYBdmq4RL/Xw0EydhOOdoubhnosMZutk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/neufb/btrYBdmq4RL/Xw0EydhOOdoubhnosMZutk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fneufb%2FbtrYBdmq4RL%2FXw0EydhOOdoubhnosMZutk%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;508&quot; height=&quot;454&quot; data-filename=&quot;02.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.png&quot; data-origin-width=&quot;857&quot; data-origin-height=&quot;708&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kOHcQ/btrYzmdAux0/9ZBDtkzLHUPrwbv0naAf51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kOHcQ/btrYzmdAux0/9ZBDtkzLHUPrwbv0naAf51/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kOHcQ/btrYzmdAux0/9ZBDtkzLHUPrwbv0naAf51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkOHcQ%2FbtrYzmdAux0%2F9ZBDtkzLHUPrwbv0naAf51%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;857&quot; height=&quot;708&quot; data-filename=&quot;03.png&quot; data-origin-width=&quot;857&quot; data-origin-height=&quot;708&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.png&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;2528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/soUtg/btrYwnqBY8K/K59lmtZ8BVjvTqMNNuSGsk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/soUtg/btrYwnqBY8K/K59lmtZ8BVjvTqMNNuSGsk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/soUtg/btrYwnqBY8K/K59lmtZ8BVjvTqMNNuSGsk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsoUtg%2FbtrYwnqBY8K%2FK59lmtZ8BVjvTqMNNuSGsk%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;695&quot; height=&quot;2528&quot; data-filename=&quot;04.png&quot; data-origin-width=&quot;695&quot; data-origin-height=&quot;2528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; background-color: #ffe1e8;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;The&amp;nbsp;IAM&amp;nbsp;role&amp;nbsp;arn:aws:iam::????????????:role/롤네임&amp;nbsp;does&amp;nbsp;not&amp;nbsp;give&amp;nbsp;you&amp;nbsp;permission&amp;nbsp;to&amp;nbsp;perform&amp;nbsp;operations&amp;nbsp;in&amp;nbsp;the&amp;nbsp;following&amp;nbsp;AWS&amp;nbsp;service:&amp;nbsp;AmazonAutoScaling. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Contact&amp;nbsp;your&amp;nbsp;AWS&amp;nbsp;administrator&amp;nbsp;if&amp;nbsp;you&amp;nbsp;need&amp;nbsp;help. &lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;If&amp;nbsp;you&amp;nbsp;ar&amp;nbsp;AWS&amp;nbsp;administrator,&amp;nbsp;you&amp;nbsp;can&amp;nbsp;grant&amp;nbsp;permissions&amp;nbsp;to&amp;nbsp;your&amp;nbsp;users&amp;nbsp;or&amp;nbsp;groups&amp;nbsp;by&amp;nbsp;creating&amp;nbsp;IAM&amp;nbsp;policies.&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 문서: &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/getting-started-create-service-role.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/getting-started-create-service-role.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Code Deploy 배포 그룹의 대상이 EC2 Auto Scaling 그룹이라면, 권한이 더 필요하다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.png&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;640&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OIIHE/btrYydhbIZ2/x9HE5qWYFKqHg4cTTXXnk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OIIHE/btrYydhbIZ2/x9HE5qWYFKqHg4cTTXXnk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OIIHE/btrYydhbIZ2/x9HE5qWYFKqHg4cTTXXnk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOIIHE%2FbtrYydhbIZ2%2Fx9HE5qWYFKqHg4cTTXXnk0%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;839&quot; height=&quot;640&quot; data-filename=&quot;05.png&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;640&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'Code Deploy 배포 그룹'의 서비스 역할에 필요했던 AWSCodeDeployRole 정책 외에도&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;0&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%; background-color: #ffe1e8;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;The following validation error occurred: Target group not attached to the Auto Scaling group (Service: AmazonAutoScaling; Status Code: 400; Error Code: ValidationError; Request ID: ????????-????-????-????-????????????; Proxy: null)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'Code Deploy 배포 그룹'의 배포 유형을 블루/그린(Blue/Green)으로 했을 때 나타날 수 있는 오류이다.&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;미안하지만 아직 해결법을 찾지 못했다.&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;Auto Scaling 그룹으로 가보면 Code Deploy가 만든 그룹이 그대로 남아있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본의 로드 밸런서 대상 그룹(Target Group)에 연결하지 못한 채 배포가 진행되지 못하고 캔슬된다.&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;누군가는 Auto Scaling 그룹의 크기 조정 정책이 '대상당 Application Load Balancer 요청 수'인 상태에서 오류가 발생해서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'평균 CPU 사용률'로 돌렸더니 되었다고 하는데... 시도해보았지만 되진 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;a href=&quot;https://stackoverflow.com/questions/72963563/i-got-target-group-not-attached-to-the-auto-scaling-group-error-while-doing-blue&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/72963563/i-got-target-group-not-attached-to-the-auto-scaling-group-error-while-doing-blue&lt;/a&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;a href=&quot;https://cvortmann.medium.com/fixing-aws-codedeploy-issue-where-auto-scaling-group-is-not-attached-to-target-group-5822d1a577e2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://cvortmann.medium.com/fixing-aws-codedeploy-issue-where-auto-scaling-group-is-not-attached-to-target-group-5822d1a577e2&lt;/a&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>Study/AWS</category>
      <category>Autoscaling</category>
      <category>aws</category>
      <category>CodeDeploy</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/317</guid>
      <comments>https://ydeer.tistory.com/317#entry317comment</comments>
      <pubDate>Wed, 8 Feb 2023 23:37:57 +0900</pubDate>
    </item>
    <item>
      <title>AWS EC2 Auto Scaling</title>
      <link>https://ydeer.tistory.com/316</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;구성&quot;&gt;[구성]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;준비&quot;&gt;[준비]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;설정&quot;&gt;[설정]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;확인&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;구성&quot; 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;인터넷 ━ (AWS) Application Load Balancer ━ (AWS) [ EC2 Auto Scaling ]&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;준비&quot; 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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드 밸런서의 대상 그룹을 준비&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: 로드 밸런서의 대상 그룹을 준비&quot; data-text-less=&quot;닫기: 로드 밸런서의 대상 그룹을 준비&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03_ELB_Target.png&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;515&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VJHpV/btrYy9L0c34/yBOKDW4gXo69JxIZO3tQG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VJHpV/btrYy9L0c34/yBOKDW4gXo69JxIZO3tQG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VJHpV/btrYy9L0c34/yBOKDW4gXo69JxIZO3tQG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVJHpV%2FbtrYy9L0c34%2FyBOKDW4gXo69JxIZO3tQG1%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;1149&quot; height=&quot;515&quot; data-filename=&quot;03_ELB_Target.png&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;515&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04_ELB_Target.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;2912&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkv48N/btrYAQYWGGn/smNcq7BuPEnCuZK4hYljKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkv48N/btrYAQYWGGn/smNcq7BuPEnCuZK4hYljKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkv48N/btrYAQYWGGn/smNcq7BuPEnCuZK4hYljKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdkv48N%2FbtrYAQYWGGn%2FsmNcq7BuPEnCuZK4hYljKK%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;680&quot; height=&quot;2912&quot; data-filename=&quot;04_ELB_Target.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;2912&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05_ELB_Target.png&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;1076&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vlQF2/btrYARQ30oA/PZUWCyiFKgzKbdAgfEvSN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vlQF2/btrYARQ30oA/PZUWCyiFKgzKbdAgfEvSN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vlQF2/btrYARQ30oA/PZUWCyiFKgzKbdAgfEvSN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvlQF2%2FbtrYARQ30oA%2FPZUWCyiFKgzKbdAgfEvSN0%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;983&quot; height=&quot;1076&quot; data-filename=&quot;05_ELB_Target.png&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;1076&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;대상인 Auto Scaling 그룹을 나중에 만드니 비워두고 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Auto Scaling 그룹을 생성할 때 연결지어주면 된다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: 로드 밸런서 준비&quot; data-text-less=&quot;닫기: 로드 밸런서 준비&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06_ELB.png&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;865&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/G5wwI/btrYzFKsNOE/9IOctHsqsc24idt2pTN5C1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/G5wwI/btrYzFKsNOE/9IOctHsqsc24idt2pTN5C1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/G5wwI/btrYzFKsNOE/9IOctHsqsc24idt2pTN5C1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG5wwI%2FbtrYzFKsNOE%2F9IOctHsqsc24idt2pTN5C1%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;1270&quot; height=&quot;865&quot; data-filename=&quot;06_ELB.png&quot; data-origin-width=&quot;1270&quot; data-origin-height=&quot;865&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07_ELB.png&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;994&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EPtMK/btrYvmZrZBI/gRK54CT1rOZL4rC8OVrhc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EPtMK/btrYvmZrZBI/gRK54CT1rOZL4rC8OVrhc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EPtMK/btrYvmZrZBI/gRK54CT1rOZL4rC8OVrhc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEPtMK%2FbtrYvmZrZBI%2FgRK54CT1rOZL4rC8OVrhc0%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;776&quot; height=&quot;994&quot; data-filename=&quot;07_ELB.png&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;994&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08_ELB.png&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;4017&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yv6CD/btrYyUah42X/6zuZJxnRXP1JyBBJ7OoYYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yv6CD/btrYyUah42X/6zuZJxnRXP1JyBBJ7OoYYk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yv6CD/btrYyUah42X/6zuZJxnRXP1JyBBJ7OoYYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyv6CD%2FbtrYyUah42X%2F6zuZJxnRXP1JyBBJ7OoYYk%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;1005&quot; height=&quot;4017&quot; data-filename=&quot;08_ELB.png&quot; data-origin-width=&quot;1005&quot; data-origin-height=&quot;4017&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;설정&quot; 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;EC2 인스턴스의 자동 생성을 위한 시작 템플릿 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Auto Scaling 그룹 생성&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 인스턴스의 자동 생성을 위한 시작 템플릿 생성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01_EC2_Template.png&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;865&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tnHPL/btrYzlFo2lL/aINy4KI6wt79LArKAFJ7MK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tnHPL/btrYzlFo2lL/aINy4KI6wt79LArKAFJ7MK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tnHPL/btrYzlFo2lL/aINy4KI6wt79LArKAFJ7MK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtnHPL%2FbtrYzlFo2lL%2FaINy4KI6wt79LArKAFJ7MK%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;1176&quot; height=&quot;865&quot; data-filename=&quot;01_EC2_Template.png&quot; data-origin-width=&quot;1176&quot; data-origin-height=&quot;865&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02_EC2_Template.png&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;6039&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdUscE/btrYBxLu3k2/ApxelshKnGO9dV0q1UjmU1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdUscE/btrYBxLu3k2/ApxelshKnGO9dV0q1UjmU1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdUscE/btrYBxLu3k2/ApxelshKnGO9dV0q1UjmU1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdUscE%2FbtrYBxLu3k2%2FApxelshKnGO9dV0q1UjmU1%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;1261&quot; height=&quot;6039&quot; data-filename=&quot;02_EC2_Template.png&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;6039&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 인스턴스를 만들 때처럼 원하는 대로 설정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 예제에서는 Auto Scaling 그룹에 Code Deploy까지 연계할 예정이라 해당 정책이 포함된 Role을 부여했고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 데이터에는 CodeDeploy Agent도 설치하도록 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 jdk 설치와 S3 버킷으로부터 애플리케이션을 내려받아 서비스로 등록 및 실행까지 하도록 했다.&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;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;#!/bin/bash&lt;/p&gt;&lt;p&gt;yum&amp;nbsp;update&amp;nbsp;-y&lt;/p&gt;&lt;p&gt;yum&amp;nbsp;install&amp;nbsp;-y&amp;nbsp;ruby&lt;/p&gt;&lt;p&gt;yum&amp;nbsp;install&amp;nbsp;-y&amp;nbsp;wget&lt;/p&gt;&lt;p&gt;yum&amp;nbsp;install&amp;nbsp;-y&amp;nbsp;java-17-amazon-corretto.x86_64&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;#&amp;nbsp;/opt/codedeploy-agent/bin/codedeploy-agent&amp;nbsp;stop&lt;/p&gt;&lt;p&gt;#&amp;nbsp;yum&amp;nbsp;erase&amp;nbsp;codedeploy-agent&amp;nbsp;-y&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;cd&amp;nbsp;/home/ec2-user&lt;/p&gt;&lt;p&gt;wget&amp;nbsp;https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install&lt;/p&gt;&lt;p&gt;chmod&amp;nbsp;+x&amp;nbsp;./install&lt;/p&gt;&lt;p&gt;sudo&amp;nbsp;./install&amp;nbsp;auto&lt;/p&gt;&lt;p&gt;rm&amp;nbsp;./install&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;aws&amp;nbsp;s3&amp;nbsp;cp&amp;nbsp;--region&amp;nbsp;ap-northeast-2&amp;nbsp;s3://s3-blackdeer/codedeploy/github/simple-http-rest/build.zip&amp;nbsp;/home/ec2-user/spring-simple-http-rest/build.zip&lt;/p&gt;&lt;p&gt;unzip&amp;nbsp;-o&amp;nbsp;/home/ec2-user/spring-simple-http-rest/build.zip&amp;nbsp;-d&amp;nbsp;/home/ec2-user/spring-simple-http-rest&lt;/p&gt;&lt;p&gt;rm&amp;nbsp;/home/ec2-user/spring-simple-http-rest/build.zip&lt;/p&gt;&lt;p&gt;chown&amp;nbsp;-R&amp;nbsp;ec2-user:ec2-user&amp;nbsp;/home/ec2-user/spring-simple-http-rest&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;aws&amp;nbsp;s3&amp;nbsp;cp&amp;nbsp;--region&amp;nbsp;ap-northeast-2&amp;nbsp;s3://s3-blackdeer/codedeploy/github/simple-http-rest/spring-simple-http-rest.service&amp;nbsp;/lib/systemd/system/spring-simple-http-rest.service&lt;/p&gt;&lt;p&gt;chmod&amp;nbsp;644&amp;nbsp;/lib/systemd/system/spring-simple-http-rest.service&lt;/p&gt;&lt;p&gt;systemctl&amp;nbsp;daemon-reload&lt;/p&gt;&lt;p&gt;systemctl&amp;nbsp;enable&amp;nbsp;spring-simple-http-rest&lt;/p&gt;&lt;p&gt;service&amp;nbsp;spring-simple-http-rest&amp;nbsp;start&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 서비스 등록에 사용한 spring-simple-http-rest.service&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #ffc9af;&quot;&gt;Unit&lt;/span&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;]&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;Description&lt;/span&gt;=Spring&amp;nbsp;Boot&amp;nbsp;Application&amp;nbsp;for&amp;nbsp;Simple&amp;nbsp;Http&amp;nbsp;REST&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;ConditionFileNotEmpty&lt;/span&gt;=/home/ec2-user/spring-simple-http-rest/build/libs/simple-http-rest-1.0.0.war&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #ffc9af;&quot;&gt;Service&lt;/span&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;]&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;ExecStart&lt;/span&gt;=/bin/java&amp;nbsp;-jar&amp;nbsp;/home/ec2-user/spring-simple-http-rest/build/libs/simple-http-rest-1.0.0.war&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;Restart&lt;/span&gt;=on-failure&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;RestartPreventExitStatus&lt;/span&gt;=9&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;User&lt;/span&gt;=ec2-user&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;Group&lt;/span&gt;=ec2-user&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;[&lt;/span&gt;&lt;span style=&quot;color: #ffc9af;&quot;&gt;Install&lt;/span&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;]&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;WantedBy&lt;/span&gt;=multi-user.target&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Auto&amp;nbsp;Scaling&amp;nbsp;그룹&amp;nbsp;생성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;09_AS.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;865&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUdrAN/btrYwobDpF1/fkEbv3ijdh48wngbY1n8Ak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUdrAN/btrYwobDpF1/fkEbv3ijdh48wngbY1n8Ak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUdrAN/btrYwobDpF1/fkEbv3ijdh48wngbY1n8Ak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUdrAN%2FbtrYwobDpF1%2FfkEbv3ijdh48wngbY1n8Ak%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;1440&quot; height=&quot;865&quot; data-filename=&quot;09_AS.png&quot; data-origin-width=&quot;1440&quot; data-origin-height=&quot;865&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10_AS.png&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;1311&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HiDKU/btrYvl0ty76/TFlOi3h1QBajukKm4jmSNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HiDKU/btrYvl0ty76/TFlOi3h1QBajukKm4jmSNk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HiDKU/btrYvl0ty76/TFlOi3h1QBajukKm4jmSNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHiDKU%2FbtrYvl0ty76%2FTFlOi3h1QBajukKm4jmSNk%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;774&quot; height=&quot;1311&quot; data-filename=&quot;10_AS.png&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;1311&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;11_AS.png&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;1292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWSyIO/btrYzmdgebO/F3dcGHs5daq4AHCLeKEnc0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWSyIO/btrYzmdgebO/F3dcGHs5daq4AHCLeKEnc0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWSyIO/btrYzmdgebO/F3dcGHs5daq4AHCLeKEnc0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWSyIO%2FbtrYzmdgebO%2FF3dcGHs5daq4AHCLeKEnc0%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;774&quot; height=&quot;1292&quot; data-filename=&quot;11_AS.png&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;1292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;12_AS.png&quot; data-origin-width=&quot;638&quot; data-origin-height=&quot;1630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/puv1I/btrYwnX3ri4/1QKqeXMQz3wT9A0k1bm9A1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/puv1I/btrYwnX3ri4/1QKqeXMQz3wT9A0k1bm9A1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/puv1I/btrYwnX3ri4/1QKqeXMQz3wT9A0k1bm9A1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpuv1I%2FbtrYwnX3ri4%2F1QKqeXMQz3wT9A0k1bm9A1%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;638&quot; height=&quot;1630&quot; data-filename=&quot;12_AS.png&quot; data-origin-width=&quot;638&quot; data-origin-height=&quot;1630&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;ㆍAuto Scaling에서는 EC2 인스턴스 자체의 CPU나 네트워크 등 머신에 대한 상태 확인을 기본으로 하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　로드 밸런서 사용시에는 대상 그룹의 상태 확인도 Auto Scaling의 상태 확인에 포함할지 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　(준비 과정에서 로드 밸런서 대상 그룹에서는 애플리케이션의 API 응답여부를 척도로 설정했었다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 예시에서는 선택 사항은 많이 넘겼다. 필요하면 사용하도록 한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;13_AS.png&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;1602&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oEmpR/btrYvmrxK61/itg3wmibY7KmZelsZ0HkL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oEmpR/btrYvmrxK61/itg3wmibY7KmZelsZ0HkL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oEmpR/btrYvmrxK61/itg3wmibY7KmZelsZ0HkL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoEmpR%2FbtrYvmrxK61%2Fitg3wmibY7KmZelsZ0HkL0%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;648&quot; height=&quot;1602&quot; data-filename=&quot;13_AS.png&quot; data-origin-width=&quot;648&quot; data-origin-height=&quot;1602&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ예시에서는 로드 밸런서가 EC2 인스턴스로 요청을 분배할 때,&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;14_AS.png&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;1184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBdGmw/btrYzqmmktO/Jqeh46J26m3LLqepSyCvk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBdGmw/btrYzqmmktO/Jqeh46J26m3LLqepSyCvk1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBdGmw/btrYzqmmktO/Jqeh46J26m3LLqepSyCvk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBdGmw%2FbtrYzqmmktO%2FJqeh46J26m3LLqepSyCvk1%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;655&quot; height=&quot;1184&quot; data-filename=&quot;14_AS.png&quot; data-origin-width=&quot;655&quot; data-origin-height=&quot;1184&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;확인&quot; 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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.png&quot; data-origin-width=&quot;1829&quot; data-origin-height=&quot;875&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8Zo4Q/btrYydumbky/EIKAuUt2TKXx8XUbmptick/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8Zo4Q/btrYydumbky/EIKAuUt2TKXx8XUbmptick/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8Zo4Q/btrYydumbky/EIKAuUt2TKXx8XUbmptick/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8Zo4Q%2FbtrYydumbky%2FEIKAuUt2TKXx8XUbmptick%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;1829&quot; height=&quot;875&quot; data-filename=&quot;01.png&quot; data-origin-width=&quot;1829&quot; data-origin-height=&quot;875&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 Auto Scaling 그룹에서 작동하고 있는 인스턴스들의 상태를 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최소 1대를 설정했기에 Auto Scaling 그룹이 생성되자마자 EC2 인스턴스 1대를 생성한 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.png&quot; data-origin-width=&quot;1870&quot; data-origin-height=&quot;875&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clJD5F/btrYsOu8BcX/5eKejbhDnk5SDdK9KaBEwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clJD5F/btrYsOu8BcX/5eKejbhDnk5SDdK9KaBEwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clJD5F/btrYsOu8BcX/5eKejbhDnk5SDdK9KaBEwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclJD5F%2FbtrYsOu8BcX%2F5eKejbhDnk5SDdK9KaBEwK%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;1870&quot; height=&quot;875&quot; data-filename=&quot;02.png&quot; data-origin-width=&quot;1870&quot; data-origin-height=&quot;875&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결한 로드 밸런서의 대상 그룹에서도 해당 EC2 인스턴스가 연결되어 애플리케이션을 제대로 실행하고 있는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(준비&amp;nbsp;과정에서&amp;nbsp;로드&amp;nbsp;밸런서&amp;nbsp;대상&amp;nbsp;그룹에서는&amp;nbsp;애플리케이션의&amp;nbsp;API&amp;nbsp;응답여부를&amp;nbsp;척도로&amp;nbsp;설정했었다.)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.png&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CaTLv/btrYzELwiPk/nqTOHMvkrZB849M6lMqzI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CaTLv/btrYzELwiPk/nqTOHMvkrZB849M6lMqzI1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CaTLv/btrYzELwiPk/nqTOHMvkrZB849M6lMqzI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCaTLv%2FbtrYzELwiPk%2FnqTOHMvkrZB849M6lMqzI1%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;811&quot; height=&quot;757&quot; data-filename=&quot;03.png&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드 밸런서로 애플리케이션의 API를 사용했을 때 응답을 받을 수 있었다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 로드 밸런서에 많은 API Call을 줘서 기대한대로 EC2 인스턴스가 늘어나는지 볼 것이다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;blackdeer@Mac&amp;nbsp;~&amp;nbsp;%&lt;/span&gt;&amp;nbsp;ab&amp;nbsp;-n&amp;nbsp;20000&amp;nbsp;-c&amp;nbsp;20&amp;nbsp;-m&amp;nbsp;POST&amp;nbsp;http://elb-spring-simple-http-rest-??????????.ap-northeast-2.elb.amazonaws.com:80/simple/info&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;This&amp;nbsp;is&amp;nbsp;ApacheBench,&amp;nbsp;Version&amp;nbsp;2.3&amp;nbsp;&amp;lt;$Revision:&amp;nbsp;1901567&amp;nbsp;$&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Copyright&amp;nbsp;1996&amp;nbsp;Adam&amp;nbsp;Twiss,&amp;nbsp;Zeus&amp;nbsp;Technology&amp;nbsp;Ltd,&amp;nbsp;http://www.zeustech.net/&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Licensed&amp;nbsp;to&amp;nbsp;The&amp;nbsp;Apache&amp;nbsp;Software&amp;nbsp;Foundation,&amp;nbsp;http://www.apache.org/&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Benchmarking&amp;nbsp;elb-spring-simple-http-rest-??????????.ap-northeast-2.elb.amazonaws.com&amp;nbsp;(be&amp;nbsp;patient)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;2000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;4000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;6000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;8000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;10000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;12000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;14000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;16000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;18000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Completed&amp;nbsp;20000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Finished&amp;nbsp;20000&amp;nbsp;requests&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Server&amp;nbsp;Software:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Server&amp;nbsp;Hostname:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elb-spring-simple-http-rest-??????????.ap-northeast-2.elb.amazonaws.com&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Server&amp;nbsp;Port:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;80&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Document&amp;nbsp;Path:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/simple/info&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Document&amp;nbsp;Length:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;742&amp;nbsp;bytes&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Concurrency&amp;nbsp;Level:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;20&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Time&amp;nbsp;taken&amp;nbsp;for&amp;nbsp;tests:&amp;nbsp;&amp;nbsp;&amp;nbsp;197.915&amp;nbsp;seconds&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Complete&amp;nbsp;requests:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;20000&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Failed&amp;nbsp;requests:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Total&amp;nbsp;transferred:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;17520000&amp;nbsp;bytes&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;HTML&amp;nbsp;transferred:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;14840000&amp;nbsp;bytes&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Requests&amp;nbsp;per&amp;nbsp;second:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;101.05&amp;nbsp;[#/sec]&amp;nbsp;(mean)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Time&amp;nbsp;per&amp;nbsp;request:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;197.915&amp;nbsp;[ms]&amp;nbsp;(mean)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Time&amp;nbsp;per&amp;nbsp;request:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9.896&amp;nbsp;[ms]&amp;nbsp;(mean,&amp;nbsp;across&amp;nbsp;all&amp;nbsp;concurrent&amp;nbsp;requests)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Transfer&amp;nbsp;rate:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;86.45&amp;nbsp;[Kbytes/sec]&amp;nbsp;received&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Connection&amp;nbsp;Times&amp;nbsp;(ms)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;min&amp;nbsp;&amp;nbsp;mean[+/-sd]&amp;nbsp;median&amp;nbsp;&amp;nbsp;&amp;nbsp;max&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Connect:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;85&amp;nbsp;&amp;nbsp;&amp;nbsp;99&amp;nbsp;&amp;nbsp;&amp;nbsp;6.0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;201&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Processing:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;85&amp;nbsp;&amp;nbsp;&amp;nbsp;99&amp;nbsp;&amp;nbsp;10.9&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;403&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Waiting:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;85&amp;nbsp;&amp;nbsp;&amp;nbsp;98&amp;nbsp;&amp;nbsp;&amp;nbsp;6.1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;100&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;250&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Total:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;170&amp;nbsp;&amp;nbsp;198&amp;nbsp;&amp;nbsp;13.7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;200&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;503&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Percentage&amp;nbsp;of&amp;nbsp;the&amp;nbsp;requests&amp;nbsp;served&amp;nbsp;within&amp;nbsp;a&amp;nbsp;certain&amp;nbsp;time&amp;nbsp;(ms)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;50%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;200&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;66%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;200&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;75%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;201&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;80%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;201&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;90%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;202&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;95%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;203&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;98%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;209&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;99%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;246&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;100%&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;503&amp;nbsp;(longest&amp;nbsp;request)&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동시에 20개의 클라이언트로 총 20000회의 요청을 주었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;08.png&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;538&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0DTIz/btrYAmcyMkJ/6JU9aJD1DS8rzJRzwDpGo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0DTIz/btrYAmcyMkJ/6JU9aJD1DS8rzJRzwDpGo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0DTIz/btrYAmcyMkJ/6JU9aJD1DS8rzJRzwDpGo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0DTIz%2FbtrYAmcyMkJ%2F6JU9aJD1DS8rzJRzwDpGo1%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;892&quot; height=&quot;538&quot; data-filename=&quot;08.png&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;538&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 설정한 값은 분당 60회이니 아주 낮은 값이었지만... 확실한 결과를 위해 과하게 주었다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.gif&quot; data-origin-width=&quot;1753&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/deofDf/btrYsP1UWho/ppP58qjHRVDWUNCKyKswX1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/deofDf/btrYsP1UWho/ppP58qjHRVDWUNCKyKswX1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/deofDf/btrYsP1UWho/ppP58qjHRVDWUNCKyKswX1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/deofDf/btrYsP1UWho/ppP58qjHRVDWUNCKyKswX1/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;1753&quot; height=&quot;318&quot; data-filename=&quot;04.gif&quot; data-origin-width=&quot;1753&quot; data-origin-height=&quot;318&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;인스턴스 수명 주기를 보면 Pending으로 생성하고 InService로 구동되는 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06.gif&quot; data-origin-width=&quot;1793&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2CjsM/btrYvmd1cgF/QRpeg3BPKwGXhoZ6xDL3DK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2CjsM/btrYvmd1cgF/QRpeg3BPKwGXhoZ6xDL3DK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2CjsM/btrYvmd1cgF/QRpeg3BPKwGXhoZ6xDL3DK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/2CjsM/btrYvmd1cgF/QRpeg3BPKwGXhoZ6xDL3DK/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;1793&quot; height=&quot;319&quot; data-filename=&quot;06.gif&quot; data-origin-width=&quot;1793&quot; data-origin-height=&quot;319&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대상 그룹에서도 InService된 EC2 인스턴스는 이제 ELB의 상태 확인을 받게 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07.gif&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dB5piq/btrYwobF9uN/JiLpvPTgOKWCs2wVKrv0tk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dB5piq/btrYwobF9uN/JiLpvPTgOKWCs2wVKrv0tk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dB5piq/btrYwobF9uN/JiLpvPTgOKWCs2wVKrv0tk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/dB5piq/btrYwobF9uN/JiLpvPTgOKWCs2wVKrv0tk/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;811&quot; height=&quot;757&quot; data-filename=&quot;07.gif&quot; data-origin-width=&quot;811&quot; data-origin-height=&quot;757&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로드 밸런서로 요청을 보내서 다른 EC2 인스턴스로 요청들을 넘겨주는 것을 확인했다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 요청을 보내지 않고 기다려본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정책에 따라 인스턴스당 요청 수가 줄어들면서 이제 EC2 인스턴스들을 줄이는 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;09.gif&quot; data-origin-width=&quot;1753&quot; data-origin-height=&quot;318&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DHDEZ/btrYAai1yql/UhKemEHvZwqdtHmA6emCY0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DHDEZ/btrYAai1yql/UhKemEHvZwqdtHmA6emCY0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DHDEZ/btrYAai1yql/UhKemEHvZwqdtHmA6emCY0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/DHDEZ/btrYAai1yql/UhKemEHvZwqdtHmA6emCY0/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;1753&quot; height=&quot;318&quot; data-filename=&quot;09.gif&quot; data-origin-width=&quot;1753&quot; data-origin-height=&quot;318&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terminating되면서 EC2 인스턴스들을 제거한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10.gif&quot; data-origin-width=&quot;1793&quot; data-origin-height=&quot;319&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjdqWL/btrYza5aqLd/t8aPiSDvtrXPmnKKKElOM1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjdqWL/btrYza5aqLd/t8aPiSDvtrXPmnKKKElOM1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjdqWL/btrYza5aqLd/t8aPiSDvtrXPmnKKKElOM1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cjdqWL/btrYza5aqLd/t8aPiSDvtrXPmnKKKElOM1/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;1793&quot; height=&quot;319&quot; data-filename=&quot;10.gif&quot; data-origin-width=&quot;1793&quot; data-origin-height=&quot;319&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/AWS</category>
      <category>Autoscaling</category>
      <category>aws</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/316</guid>
      <comments>https://ydeer.tistory.com/316#entry316comment</comments>
      <pubDate>Wed, 8 Feb 2023 18:23:28 +0900</pubDate>
    </item>
    <item>
      <title>AWS CodeDeploy와 Github Action으로 자동 배포 설정</title>
      <link>https://ydeer.tistory.com/315</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;workflow&quot;&gt;[Workflow]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;준비사항&quot;&gt;[준비사항]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;설정&quot;&gt;[설정]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;확인&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;workflow&quot; data-ke-size=&quot;size16&quot;&gt;[Workflow]&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;Workflow는 다음과 같다.&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;Github의 특정 branch에 코드 &lt;span class=&quot;code-span&quot;&gt;push&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;darr;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gradle이나 maven 등으로 &lt;span class=&quot;code-span&quot;&gt;build&lt;/span&gt;(test를 포함하고 있다면 수행)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;darr;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 결과물(jar, war, ...)과 배포 설정(appspec.yml) 등을 압축하여 &lt;span class=&quot;code-span&quot;&gt;AWS S3&lt;/span&gt; 버킷에 업로드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;darr;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;AWS CodeDeploy&lt;/span&gt; 서비스에 설정한 대로 배포 요청(배포 생성)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;darr;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;AWS EC2&lt;/span&gt;에서는 설치했던 AWS CodeDeploy Agent가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS S3 버킷에서 배포본을 받고 압축을 푼 후, 압축 파일 내부의 appspec.yml에 정의된대로 스크립트를 실행&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;준비사항&quot; 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;AWS IAM Role에서 AWS EC2가 AWS CodeDeployAgent를 사용하기 위한 역할(Role)을 생성한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: IAM Role - AmazonEC2RoleforAWSCodeDeploy 생성&quot; data-text-less=&quot;닫기: IAM Role - AmazonEC2RoleforAWSCodeDeploy 생성&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01_IAM_Role.png&quot; data-origin-width=&quot;1208&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/569m7/btrYjCHjTI7/P5BXEb7jcXvMe19ESjUDNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/569m7/btrYjCHjTI7/P5BXEb7jcXvMe19ESjUDNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/569m7/btrYjCHjTI7/P5BXEb7jcXvMe19ESjUDNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F569m7%2FbtrYjCHjTI7%2FP5BXEb7jcXvMe19ESjUDNK%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;1208&quot; height=&quot;412&quot; data-filename=&quot;01_IAM_Role.png&quot; data-origin-width=&quot;1208&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02_IAM_Role.png&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;718&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kVhP4/btrYieUyFPe/xtIhwui5G20icvi2TT0RKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kVhP4/btrYieUyFPe/xtIhwui5G20icvi2TT0RKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kVhP4/btrYieUyFPe/xtIhwui5G20icvi2TT0RKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkVhP4%2FbtrYieUyFPe%2FxtIhwui5G20icvi2TT0RKK%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;1838&quot; height=&quot;718&quot; data-filename=&quot;02_IAM_Role.png&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;718&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03_IAM_Role.png&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;1391&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rRLz5/btrYjWlehyL/uNFlDPMrWJuG8epSkF91a0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rRLz5/btrYjWlehyL/uNFlDPMrWJuG8epSkF91a0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rRLz5/btrYjWlehyL/uNFlDPMrWJuG8epSkF91a0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrRLz5%2FbtrYjWlehyL%2FuNFlDPMrWJuG8epSkF91a0%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;1838&quot; height=&quot;1391&quot; data-filename=&quot;03_IAM_Role.png&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;1391&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04_IAM_Role.png&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;1428&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bI74ND/btrYlvAH1i7/1EYTfogkdAUkBS5GI5GcJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bI74ND/btrYlvAH1i7/1EYTfogkdAUkBS5GI5GcJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bI74ND/btrYlvAH1i7/1EYTfogkdAUkBS5GI5GcJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbI74ND%2FbtrYlvAH1i7%2F1EYTfogkdAUkBS5GI5GcJK%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;939&quot; height=&quot;1428&quot; data-filename=&quot;04_IAM_Role.png&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;1428&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;AWS IAM Role에서 AWS CodeDeploy 서비스를 위한 역할(Role)을 생성한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: IAM Role - AWSCodeDeploy 생성&quot; data-text-less=&quot;닫기: IAM Role - AWSCodeDeploy 생성&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01_IAM_Role.png&quot; data-origin-width=&quot;1208&quot; data-origin-height=&quot;412&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/569m7/btrYjCHjTI7/P5BXEb7jcXvMe19ESjUDNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/569m7/btrYjCHjTI7/P5BXEb7jcXvMe19ESjUDNK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/569m7/btrYjCHjTI7/P5BXEb7jcXvMe19ESjUDNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F569m7%2FbtrYjCHjTI7%2FP5BXEb7jcXvMe19ESjUDNK%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;1208&quot; height=&quot;412&quot; data-filename=&quot;01_IAM_Role.png&quot; data-origin-width=&quot;1208&quot; data-origin-height=&quot;412&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05_IAM_Role.png&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byy6Ry/btrYj1GO9Be/wr03pJanXUn5iOdfjgsphk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byy6Ry/btrYj1GO9Be/wr03pJanXUn5iOdfjgsphk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byy6Ry/btrYj1GO9Be/wr03pJanXUn5iOdfjgsphk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbyy6Ry%2FbtrYj1GO9Be%2Fwr03pJanXUn5iOdfjgsphk%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;1838&quot; height=&quot;848&quot; data-filename=&quot;05_IAM_Role.png&quot; data-origin-width=&quot;1838&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;06_IAM_Role.png&quot; data-origin-width=&quot;1082&quot; data-origin-height=&quot;1156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOCmUH/btrYeYxSBFJ/EDjHSO6zvq2QkvmtmDTCA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOCmUH/btrYeYxSBFJ/EDjHSO6zvq2QkvmtmDTCA1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOCmUH/btrYeYxSBFJ/EDjHSO6zvq2QkvmtmDTCA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOCmUH%2FbtrYeYxSBFJ%2FEDjHSO6zvq2QkvmtmDTCA1%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;1082&quot; height=&quot;1156&quot; data-filename=&quot;06_IAM_Role.png&quot; data-origin-width=&quot;1082&quot; data-origin-height=&quot;1156&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;07_IAM_Role.png&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;1433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FiHza/btrYmyjChug/FTCHhMItnkK7sNa2Y8gCQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FiHza/btrYmyjChug/FTCHhMItnkK7sNa2Y8gCQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FiHza/btrYmyjChug/FTCHhMItnkK7sNa2Y8gCQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFiHza%2FbtrYmyjChug%2FFTCHhMItnkK7sNa2Y8gCQ0%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;955&quot; height=&quot;1433&quot; data-filename=&quot;07_IAM_Role.png&quot; data-origin-width=&quot;955&quot; data-origin-height=&quot;1433&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;AWS IAM User에서 Github Action이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;S3에 압축파일을 업로드하고, AWS CodeDeploy 서비스에 배포 요청을 할 수 있는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;권한을 부여한 사용자를 생성하고, 액세스 키(ID, SECRET)를 발급한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: IAM User 생성&quot; data-text-less=&quot;닫기: IAM User 생성&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;09_IAM_User.png&quot; data-origin-width=&quot;1879&quot; data-origin-height=&quot;370&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/deMIn8/btrYlzwjeMm/akaAQwOS1XN9NRNRfTeLO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/deMIn8/btrYlzwjeMm/akaAQwOS1XN9NRNRfTeLO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/deMIn8/btrYlzwjeMm/akaAQwOS1XN9NRNRfTeLO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdeMIn8%2FbtrYlzwjeMm%2FakaAQwOS1XN9NRNRfTeLO0%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;1879&quot; height=&quot;370&quot; data-filename=&quot;09_IAM_User.png&quot; data-origin-width=&quot;1879&quot; data-origin-height=&quot;370&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10_IAM_User.png&quot; data-origin-width=&quot;1123&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWqpSp/btrYj17Wr05/abcdRxM59BrKBKDipeAoWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWqpSp/btrYj17Wr05/abcdRxM59BrKBKDipeAoWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWqpSp/btrYj17Wr05/abcdRxM59BrKBKDipeAoWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWqpSp%2FbtrYj17Wr05%2FabcdRxM59BrKBKDipeAoWK%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;1123&quot; height=&quot;500&quot; data-filename=&quot;10_IAM_User.png&quot; data-origin-width=&quot;1123&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;11_IAM_User.png&quot; data-origin-width=&quot;1310&quot; data-origin-height=&quot;1553&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/otTP3/btrYeZQ4v7V/SZqVgtKV7jakAXS1wcqWa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/otTP3/btrYeZQ4v7V/SZqVgtKV7jakAXS1wcqWa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/otTP3/btrYeZQ4v7V/SZqVgtKV7jakAXS1wcqWa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FotTP3%2FbtrYeZQ4v7V%2FSZqVgtKV7jakAXS1wcqWa0%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;1310&quot; height=&quot;1553&quot; data-filename=&quot;11_IAM_User.png&quot; data-origin-width=&quot;1310&quot; data-origin-height=&quot;1553&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 예시에서 사용하는 최소 정책은 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(작성하려면 S3 버킷과 CodeDeploy 애플리케이션 및 배포 그룹 생성을 먼저 하고 리소스를 지정할 수 있다)&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;{&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Version&quot;:&amp;nbsp;&quot;2012-10-17&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Statement&quot;:&amp;nbsp;[&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Sid&quot;:&amp;nbsp;&quot;VisualEditor0&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Effect&quot;:&amp;nbsp;&quot;Allow&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Action&quot;:&amp;nbsp;[&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;s3:PutObject&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;codedeploy:CreateDeployment&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;codedeploy:GetApplicationRevision&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;codedeploy:RegisterApplicationRevision&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;codedeploy:GetDeploymentConfig&quot;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;],&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;Resource&quot;:&amp;nbsp;[&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;arn:aws:codedeploy:ap-northeast-2:&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;1290????7149&lt;/span&gt;:deploymentconfig:CodeDeployDefault.OneAtATime&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;arn:aws:codedeploy:ap-northeast-2:&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;1290????7149&lt;/span&gt;:application:&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;CODEDEPLOY애플리케이션이름&lt;/span&gt;&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;arn:aws:codedeploy:ap-northeast-2:&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;1290????7149&lt;/span&gt;:deploymentgroup:&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;CODEDEPLOY애플리케이션이름&lt;/span&gt;/&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;배포그룹이름&lt;/span&gt;&quot;,&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&quot;arn:aws:s3:::&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;S3버킷이름&lt;/span&gt;/&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;디렉터리명...&lt;/span&gt;/&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;파일명&lt;/span&gt;&quot;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;12_IAM_User.png&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PJQpC/btrYiWlYVbY/2xhFPrLFMk4o5ZwHrbFMX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PJQpC/btrYiWlYVbY/2xhFPrLFMk4o5ZwHrbFMX0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PJQpC/btrYiWlYVbY/2xhFPrLFMk4o5ZwHrbFMX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPJQpC%2FbtrYiWlYVbY%2F2xhFPrLFMk4o5ZwHrbFMX0%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;895&quot; height=&quot;868&quot; data-filename=&quot;12_IAM_User.png&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;13_IAM_User.png&quot; data-origin-width=&quot;1463&quot; data-origin-height=&quot;369&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVdLVh/btrYjmEMcmH/BDTHdIWVz9JS6DzVbGO6h1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVdLVh/btrYjmEMcmH/BDTHdIWVz9JS6DzVbGO6h1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVdLVh/btrYjmEMcmH/BDTHdIWVz9JS6DzVbGO6h1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVdLVh%2FbtrYjmEMcmH%2FBDTHdIWVz9JS6DzVbGO6h1%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;1463&quot; height=&quot;369&quot; data-filename=&quot;13_IAM_User.png&quot; data-origin-width=&quot;1463&quot; data-origin-height=&quot;369&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;IAM User가 생성된 것을 확인할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;14_IAM_User.png&quot; data-origin-width=&quot;1653&quot; data-origin-height=&quot;1277&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Zyh8d/btrYjXxFD4p/x6K30ci6qV43bg7PaLois1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zyh8d/btrYjXxFD4p/x6K30ci6qV43bg7PaLois1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zyh8d/btrYjXxFD4p/x6K30ci6qV43bg7PaLois1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZyh8d%2FbtrYjXxFD4p%2Fx6K30ci6qV43bg7PaLois1%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;1653&quot; height=&quot;1277&quot; data-filename=&quot;14_IAM_User.png&quot; data-origin-width=&quot;1653&quot; data-origin-height=&quot;1277&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 사용자를 선택하고, '보안 자격 증명' 탭으로 가서 '액세스 키 만들기'로 진입한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;15_IAM_User.png&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;1018&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IkVLe/btrYjmY57cY/gFyf5P6xQHx4Y1kGHz9BSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IkVLe/btrYjmY57cY/gFyf5P6xQHx4Y1kGHz9BSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IkVLe/btrYjmY57cY/gFyf5P6xQHx4Y1kGHz9BSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIkVLe%2FbtrYjmY57cY%2FgFyf5P6xQHx4Y1kGHz9BSK%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;1048&quot; height=&quot;1018&quot; data-filename=&quot;15_IAM_User.png&quot; data-origin-width=&quot;1048&quot; data-origin-height=&quot;1018&quot;/&gt;&lt;/span&gt;&lt;/figure&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;16_IAM_User.png&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/em9YKG/btrYiU2WXpp/4E1BQewFKsxK8cQiNS67yK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/em9YKG/btrYiU2WXpp/4E1BQewFKsxK8cQiNS67yK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/em9YKG/btrYiU2WXpp/4E1BQewFKsxK8cQiNS67yK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fem9YKG%2FbtrYiU2WXpp%2F4E1BQewFKsxK8cQiNS67yK%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;1001&quot; height=&quot;372&quot; data-filename=&quot;16_IAM_User.png&quot; data-origin-width=&quot;1001&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;설명 태그는 선택 사항이다. 필요하면 사용한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;17_IAM_User.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;730&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nfiRA/btrYhbcD2UW/BBQgHEeXk8L8ycvQKOUCs1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nfiRA/btrYhbcD2UW/BBQgHEeXk8L8ycvQKOUCs1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nfiRA/btrYhbcD2UW/BBQgHEeXk8L8ycvQKOUCs1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnfiRA%2FbtrYhbcD2UW%2FBBQgHEeXk8L8ycvQKOUCs1%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;1000&quot; height=&quot;730&quot; data-filename=&quot;17_IAM_User.png&quot; data-origin-width=&quot;1000&quot; data-origin-height=&quot;730&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;위의 알림대로 이 페이지를 벗어나면 다시는 비밀 액세스 키는 볼 수 없으니,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'.csv 파일 다운로드'를 통해 안전한 곳에 저장해둔다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;위의 액세스 키를 Github의 자동 배포를 수행하려는 Repository의 설정에서 Secrets에 저장해둔다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: Github Repository Secrets 설정&quot; data-text-less=&quot;닫기: Github Repository Secrets 설정&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;18_Github_Secret.png&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;927&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eulkek/btrYhbDHlvG/Rz2CfvopzQSXUtz9cWRT40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eulkek/btrYhbDHlvG/Rz2CfvopzQSXUtz9cWRT40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eulkek/btrYhbDHlvG/Rz2CfvopzQSXUtz9cWRT40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Feulkek%2FbtrYhbDHlvG%2FRz2CfvopzQSXUtz9cWRT40%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;1149&quot; height=&quot;927&quot; data-filename=&quot;18_Github_Secret.png&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;927&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;Github에서 배포하려는 Repository의 설정 탭으로 가서,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Security &amp;gt; Secrets and variables &amp;gt; Actions 항목에서 secret 생성으로 진입한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;19_Github_Secret.png&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;305&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bU0hii/btrYje7N2nf/n7FTilLdivHe3xwFZWrxd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bU0hii/btrYje7N2nf/n7FTilLdivHe3xwFZWrxd0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bU0hii/btrYje7N2nf/n7FTilLdivHe3xwFZWrxd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbU0hii%2FbtrYje7N2nf%2Fn7FTilLdivHe3xwFZWrxd0%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;553&quot; height=&quot;305&quot; data-filename=&quot;19_Github_Secret.png&quot; data-origin-width=&quot;553&quot; data-origin-height=&quot;305&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;20_Github_Secret.png&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d7gyb2/btrYkKx5itc/INfQVaiDSVKpKycw1otkJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d7gyb2/btrYkKx5itc/INfQVaiDSVKpKycw1otkJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d7gyb2/btrYkKx5itc/INfQVaiDSVKpKycw1otkJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd7gyb2%2FbtrYkKx5itc%2FINfQVaiDSVKpKycw1otkJ0%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;797&quot; height=&quot;456&quot; data-filename=&quot;20_Github_Secret.png&quot; data-origin-width=&quot;797&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;발급받았던 액세스 키와 비밀 액세스 키 쌍을 각각 따로 저장한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;AWS S3 서비스에서 S3 버킷을 생성한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: S3 버킷 생성&quot; data-text-less=&quot;닫기: S3 버킷 생성&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;21_S3.png&quot; data-origin-width=&quot;1285&quot; data-origin-height=&quot;420&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnvBbR/btrYf1uncwX/dpX2CZaW81u62u5Gc3iSkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnvBbR/btrYf1uncwX/dpX2CZaW81u62u5Gc3iSkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnvBbR/btrYf1uncwX/dpX2CZaW81u62u5Gc3iSkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnvBbR%2FbtrYf1uncwX%2FdpX2CZaW81u62u5Gc3iSkK%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;1285&quot; height=&quot;420&quot; data-filename=&quot;21_S3.png&quot; data-origin-width=&quot;1285&quot; data-origin-height=&quot;420&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;22_S3.png&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;2529&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdnV69/btrYid88mAs/fhZiEpgY7XKrWZi6I4PXCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdnV69/btrYid88mAs/fhZiEpgY7XKrWZi6I4PXCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdnV69/btrYid88mAs/fhZiEpgY7XKrWZi6I4PXCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdnV69%2FbtrYid88mAs%2FfhZiEpgY7XKrWZi6I4PXCK%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;895&quot; height=&quot;2529&quot; data-filename=&quot;22_S3.png&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;2529&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;23_S3.png&quot; data-origin-width=&quot;1729&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7vVmp/btrYchdnjXj/62iI5SRy8kWWfM6i4nYv2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7vVmp/btrYchdnjXj/62iI5SRy8kWWfM6i4nYv2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7vVmp/btrYchdnjXj/62iI5SRy8kWWfM6i4nYv2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7vVmp%2FbtrYchdnjXj%2F62iI5SRy8kWWfM6i4nYv2k%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;1729&quot; height=&quot;580&quot; data-filename=&quot;23_S3.png&quot; data-origin-width=&quot;1729&quot; data-origin-height=&quot;580&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;버킷의 root(/) 디렉터리에 업로드할 것이 아니라면, '폴더 만들기'를 통해 원하는 위치 구조를 만들어둔다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;24_S3.png&quot; data-origin-width=&quot;1159&quot; data-origin-height=&quot;826&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/co05mO/btrYj1fM9Dy/UK6ynSUaSSHlzOIM6yy2xk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/co05mO/btrYj1fM9Dy/UK6ynSUaSSHlzOIM6yy2xk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/co05mO/btrYj1fM9Dy/UK6ynSUaSSHlzOIM6yy2xk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fco05mO%2FbtrYj1fM9Dy%2FUK6ynSUaSSHlzOIM6yy2xk%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;1159&quot; height=&quot;826&quot; data-filename=&quot;24_S3.png&quot; data-origin-width=&quot;1159&quot; data-origin-height=&quot;826&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;AWS EC2 서비스에서 EC2 인스턴스를 생성한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: EC2 인스턴스 생성&quot; data-text-less=&quot;닫기: EC2 인스턴스 생성&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;25_EC2.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;535&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/usO5n/btrYidONY8w/KykOYqF9ha2FXZOY6cYYdK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/usO5n/btrYidONY8w/KykOYqF9ha2FXZOY6cYYdK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/usO5n/btrYidONY8w/KykOYqF9ha2FXZOY6cYYdK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FusO5n%2FbtrYidONY8w%2FKykOYqF9ha2FXZOY6cYYdK%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;1920&quot; height=&quot;535&quot; data-filename=&quot;25_EC2.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;535&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;26_EC2.png&quot; data-origin-width=&quot;1253&quot; data-origin-height=&quot;5172&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lCCGb/btrYjXdq4rf/efZeIWm9kCsPsKrAkQ4pAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lCCGb/btrYjXdq4rf/efZeIWm9kCsPsKrAkQ4pAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lCCGb/btrYjXdq4rf/efZeIWm9kCsPsKrAkQ4pAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlCCGb%2FbtrYjXdq4rf%2FefZeIWm9kCsPsKrAkQ4pAk%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;1253&quot; height=&quot;5172&quot; data-filename=&quot;26_EC2.png&quot; data-origin-width=&quot;1253&quot; data-origin-height=&quot;5172&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ위에서 생성했던 Role 중 AmazonEC2RoleForAWSCodeDeploy 정책이 연결된 Role을 선택해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍEC2가 생성되면 접속해서 AWS CodeDeploy agent를 설치해야하는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　사용자 데이터에 명령어들을 입력해두면 인스턴스 생성시 해당 명령어들을 수행해준다.&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;#!/bin/bash&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;sudo&amp;nbsp;yum&amp;nbsp;update&amp;nbsp;-y&lt;/p&gt;&lt;p&gt;sudo&amp;nbsp;yum&amp;nbsp;install&amp;nbsp;-y&amp;nbsp;ruby&lt;/p&gt;&lt;p&gt;sudo&amp;nbsp;yum&amp;nbsp;install&amp;nbsp;-y&amp;nbsp;wget&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;/opt/codedeploy-agent/bin/codedeploy-agent&amp;nbsp;stop&lt;/p&gt;&lt;p&gt;yum&amp;nbsp;erase&amp;nbsp;codedeploy-agent&amp;nbsp;-y&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;cd&amp;nbsp;/home/ec2-user&lt;/p&gt;&lt;p&gt;wget&amp;nbsp;https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install&lt;/p&gt;&lt;p&gt;chmod&amp;nbsp;+x&amp;nbsp;./install&lt;/p&gt;&lt;p&gt;sudo&amp;nbsp;./install&amp;nbsp;auto&lt;/p&gt;&lt;p&gt;rm&amp;nbsp;./install&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/codedeploy-agent-operations-install-linux.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ &lt;a href=&quot;https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/resource-kit.html#resource-kit-bucket-names&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/resource-kit.html#resource-kit-bucket-names&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;27_EC2.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCfMZS/btrYjXEqhYY/wcSnQT9rfzEKKX5BGm0QrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCfMZS/btrYjXEqhYY/wcSnQT9rfzEKKX5BGm0QrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCfMZS/btrYjXEqhYY/wcSnQT9rfzEKKX5BGm0QrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCfMZS%2FbtrYjXEqhYY%2FwcSnQT9rfzEKKX5BGm0QrK%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;1920&quot; height=&quot;547&quot; data-filename=&quot;27_EC2.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;547&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;만약 기존 사용 중인 EC2 인스턴스라면, 우클릭 메뉴에서 IAM Role을 수정할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;28_EC2.png&quot; data-origin-width=&quot;879&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oJrl6/btrYjfewlDA/7pQchVh9XisdlENXqzIBoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oJrl6/btrYjfewlDA/7pQchVh9XisdlENXqzIBoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oJrl6/btrYjfewlDA/7pQchVh9XisdlENXqzIBoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoJrl6%2FbtrYjfewlDA%2F7pQchVh9XisdlENXqzIBoK%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;879&quot; height=&quot;410&quot; data-filename=&quot;28_EC2.png&quot; data-origin-width=&quot;879&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 아무 Role도 없었다면 생성했던 Role을 선택하면 되지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 Role이 존재한다면 기존 Role에 AmazonEC2RoleForAWSCodeDeploy 정책을 추가하거나 합친 형태의 Role을 추가로 생성해야할 수 있다.&lt;/p&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;29_EC2.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;547&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/O7JsJ/btrYj2yZA4t/q5GCYi1Eqkw1SIoWckCVnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/O7JsJ/btrYj2yZA4t/q5GCYi1Eqkw1SIoWckCVnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/O7JsJ/btrYj2yZA4t/q5GCYi1Eqkw1SIoWckCVnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FO7JsJ%2FbtrYj2yZA4t%2Fq5GCYi1Eqkw1SIoWckCVnK%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;1920&quot; height=&quot;547&quot; data-filename=&quot;29_EC2.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;547&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;IAM Role을 수정했다면, 재부팅을 해야 올바르게 적용된다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;[ec2-user@ip-***-**-**-**&amp;nbsp;~]$&lt;/span&gt;&amp;nbsp;sudo&amp;nbsp;service&amp;nbsp;codedeploy-agent&amp;nbsp;status&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;The&amp;nbsp;AWS&amp;nbsp;CodeDeploy&amp;nbsp;agent&amp;nbsp;is&amp;nbsp;running&amp;nbsp;as&amp;nbsp;PID&amp;nbsp;3468&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 인스턴스로 접속하여 AWS CodeDeploy agent가 설치되어 실행 중인지 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치가 안됐다면 위의 사용자 데이터에 열거했던 명령어들을 입력해보고, 서비스 start로 실행하고 status로 확인한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;AWS CodeDeploy 서비스에서 CodeDeploy 애플리케이션을 생성하고, 배포 그룹을 생성한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;열기: CodeDepeloy 애플리케이션 및 배포 그룹 생성&quot; data-text-less=&quot;닫기: CodeDepeloy 애플리케이션 및 배포 그룹 생성&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;30_CodeDeploy.png&quot; data-origin-width=&quot;1138&quot; data-origin-height=&quot;390&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vpCeE/btrYjX5viZf/1OgcHFXa0l5RQBsge2P0nk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vpCeE/btrYjX5viZf/1OgcHFXa0l5RQBsge2P0nk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vpCeE/btrYjX5viZf/1OgcHFXa0l5RQBsge2P0nk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvpCeE%2FbtrYjX5viZf%2F1OgcHFXa0l5RQBsge2P0nk%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;1138&quot; height=&quot;390&quot; data-filename=&quot;30_CodeDeploy.png&quot; data-origin-width=&quot;1138&quot; data-origin-height=&quot;390&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;31_CodeDeploy.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qYJ4I/btrYjCtMBYE/TmSyrbJl3YF08A8mj44bW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qYJ4I/btrYjCtMBYE/TmSyrbJl3YF08A8mj44bW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qYJ4I/btrYjCtMBYE/TmSyrbJl3YF08A8mj44bW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqYJ4I%2FbtrYjCtMBYE%2FTmSyrbJl3YF08A8mj44bW1%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;537&quot; height=&quot;500&quot; data-filename=&quot;31_CodeDeploy.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;32_CodeDeploy.png&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;780&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN3oFT/btrYfZJ78jN/2ChMd5yVOlOIeGgk6Mh2kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN3oFT/btrYfZJ78jN/2ChMd5yVOlOIeGgk6Mh2kK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN3oFT/btrYfZJ78jN/2ChMd5yVOlOIeGgk6Mh2kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN3oFT%2FbtrYfZJ78jN%2F2ChMd5yVOlOIeGgk6Mh2kK%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;921&quot; height=&quot;780&quot; data-filename=&quot;32_CodeDeploy.png&quot; data-origin-width=&quot;921&quot; data-origin-height=&quot;780&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;배포 그룹을 생성해야한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;33_CodeDeploy.png&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;2757&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/P7LRi/btrYchdnDg4/p9xf3lREWDf0m79B8nM0Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/P7LRi/btrYchdnDg4/p9xf3lREWDf0m79B8nM0Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/P7LRi/btrYchdnDg4/p9xf3lREWDf0m79B8nM0Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FP7LRi%2FbtrYchdnDg4%2Fp9xf3lREWDf0m79B8nM0Ck%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;977&quot; height=&quot;2757&quot; data-filename=&quot;33_CodeDeploy.png&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;2757&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;34_CodeDeploy.png&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mudfe/btrYjfllxpi/7K6ObJZRQY18ICLNUYfYN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mudfe/btrYjfllxpi/7K6ObJZRQY18ICLNUYfYN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mudfe/btrYjfllxpi/7K6ObJZRQY18ICLNUYfYN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fmudfe%2FbtrYjfllxpi%2F7K6ObJZRQY18ICLNUYfYN1%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;1267&quot; height=&quot;582&quot; data-filename=&quot;34_CodeDeploy.png&quot; data-origin-width=&quot;1267&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션의 배포 그룹을 확인해보면 생성한 배포 그룹을 볼 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;35_CodeDeploy.png&quot; data-origin-width=&quot;1235&quot; data-origin-height=&quot;637&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhzQ4I/btrYmxZkJyi/x7RhgIcXHtwiKpuaFC14tk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhzQ4I/btrYmxZkJyi/x7RhgIcXHtwiKpuaFC14tk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhzQ4I/btrYmxZkJyi/x7RhgIcXHtwiKpuaFC14tk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhzQ4I%2FbtrYmxZkJyi%2Fx7RhgIcXHtwiKpuaFC14tk%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;1235&quot; height=&quot;637&quot; data-filename=&quot;35_CodeDeploy.png&quot; data-origin-width=&quot;1235&quot; data-origin-height=&quot;637&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 배포 그룹을 선택해서 '배포 생성'을 하면 배포 이벤트를 생성할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;36_CodeDeploy.png&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;747&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVPS0r/btrYhbw2pcG/woKmcNTxd6vClta0v0s6B0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVPS0r/btrYhbw2pcG/woKmcNTxd6vClta0v0s6B0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVPS0r/btrYhbw2pcG/woKmcNTxd6vClta0v0s6B0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVPS0r%2FbtrYhbw2pcG%2FwoKmcNTxd6vClta0v0s6B0%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;895&quot; height=&quot;747&quot; data-filename=&quot;36_CodeDeploy.png&quot; data-origin-width=&quot;895&quot; data-origin-height=&quot;747&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;자동 배포와는 관련 없이,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 S3 버킷에 업로드한 압축파일이나 Github의 Commit ID를 바탕으로 프로젝트를 내려받아 수행할 수 있는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 자동 배포 부분이 아니므로 여기서는 다루지 않겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(직접 배포를 생성하더라도 EC2 대상들에 대해서는 일괄적으로 배포 스크립트를 수행하니,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CI/CD pipeline과는 관련 없지만 배포부터는 자동화라 각각 인스턴스에 수동으로 접속하여 수행할 때의 실수는 줄일 수 있다.)&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;설정&quot; 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;span class=&quot;code-span&quot;&gt;appspec.yml&lt;/span&gt; 파일을 &lt;span&gt;git 프로젝트의 root(/) 디렉터리에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;생성한다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;version&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;0.0&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;os&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;linux&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;files&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;#&amp;nbsp;-&amp;nbsp;source:&amp;nbsp;&amp;nbsp;/&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&amp;nbsp;&amp;nbsp;#&amp;nbsp;&amp;nbsp;&amp;nbsp;destination:&amp;nbsp;/home/ec2-user/spring-simple-http-rest&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;source&lt;/span&gt;:&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;/build/libs&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;destination&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;/home/ec2-user/spring-simple-http-rest/build/libs&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;source&lt;/span&gt;:&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;/.aws/aws-codedeploy-scripts&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;destination&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;/home/ec2-user/spring-simple-http-rest/.aws/aws-codedeploy-scripts&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;file_exists_behavior&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;OVERWRITE&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;permissions&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;object&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;/&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;pattern&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;&quot;**&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;owner&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;ec2-user&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;group&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;ec2-user&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;hooks&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;AfterInstall&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;location&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;./.aws/aws-codedeploy-scripts/stop.sh&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;timeout&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;30&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;runas&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;ec2-user&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;ApplicationStart&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;location&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;./.aws/aws-codedeploy-scripts/start.sh&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;timeout&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;60&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;runas&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;ec2-user&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ &lt;a href=&quot;https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ files 섹션&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍsource: 압축파일 기준으로 압축을 풀 디렉터리/파일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍdestination: EC2 인스턴스 기준으로 설치가 될 디렉터리/파일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　※ &lt;a href=&quot;https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-files.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-files.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁhooks 섹션&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ배포 lifecycle의 각 event에 실행할 스크립트 파일을 설정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ이 스크립트 파일은 기존에 존재하든, 이번 배포 압축 파일에 포함되든 둘 다 가능하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　기존에 존재하는 스크립트 파일이 아니라면 AfterInstall 이벤트부터 사용 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　BeforeInstall에서는 압축을 풀기 전이라 해당 스크립트 파일을 찾지 못하고 이후 과정은 캔슬되어 전체 배포 과정을 실패로 마감한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　※ &lt;a href=&quot;https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 이 &lt;span class=&quot;code-span&quot;&gt;appspec.yml&lt;/span&gt;은 압축 파일의 root(/)에 포함되어야 AWS CodeDeploy agent가 이를 토대로 작업들을 수행하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　OS에 설치될 필요는 없는 파일이니, files 섹션에서 &lt;span class=&quot;code-span&quot;&gt;appspec.yml&lt;/span&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포가 수행될 때 실행될 스크립트파일(&lt;span class=&quot;code-span&quot;&gt;*.sh&lt;/span&gt;)들을 &lt;span&gt;git 프로젝트의 원하는 디렉터리에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&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;stop.sh&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;#sudo&amp;nbsp;systemctl&amp;nbsp;stop&amp;nbsp;springserver&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;PID&lt;/span&gt;=$(ps&amp;nbsp;-ef&amp;nbsp;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;|&lt;/span&gt;&amp;nbsp;grep&amp;nbsp;-v&amp;nbsp;grep&amp;nbsp;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;|&lt;/span&gt;&amp;nbsp;grep&amp;nbsp;'java&amp;nbsp;-jar&amp;nbsp;/home/ec2-user/spring-simple-http-rest/build/libs/simple-http-rest-1.0.0.war'&amp;nbsp;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;|&lt;/span&gt;&amp;nbsp;awk&amp;nbsp;'{print&amp;nbsp;$2}')&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;if&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;[&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;-n&lt;/span&gt;&amp;nbsp;&quot;&lt;span style=&quot;color: #9feec3;&quot;&gt;$PID&lt;/span&gt;&quot;&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;then&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;kill&amp;nbsp;-9&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;$PID&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sleep&amp;nbsp;10&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;fi&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;start.sh&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;#sudo&amp;nbsp;systemctl&amp;nbsp;start&amp;nbsp;springserver&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;nohup&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;java&amp;nbsp;-jar&amp;nbsp;/home/ec2-user/spring-simple-http-rest/build/libs/simple-http-rest-1.0.0.war&lt;/span&gt;&amp;nbsp;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;1&amp;gt;/dev/null&amp;nbsp;2&amp;gt;&amp;amp;1&lt;/span&gt;&amp;nbsp;&amp;amp;&lt;/span&gt;&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;appspec.yml&lt;/span&gt;과 &lt;span class=&quot;code-span&quot;&gt;스크립트들&lt;/span&gt;을 작성한 커밋들을 master branch에 push하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Github에서 repository로 들어가서 Github Action을 생성한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;37_GithubAction.png&quot; data-origin-width=&quot;1278&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MvGZz/btrYjfewPXJ/FyOQgVInggYRblkve3KVWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MvGZz/btrYjfewPXJ/FyOQgVInggYRblkve3KVWk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MvGZz/btrYjfewPXJ/FyOQgVInggYRblkve3KVWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMvGZz%2FbtrYjfewPXJ%2FFyOQgVInggYRblkve3KVWk%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;1278&quot; height=&quot;426&quot; data-filename=&quot;37_GithubAction.png&quot; data-origin-width=&quot;1278&quot; data-origin-height=&quot;426&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;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;#&amp;nbsp;This&amp;nbsp;workflow&amp;nbsp;uses&amp;nbsp;actions&amp;nbsp;that&amp;nbsp;are&amp;nbsp;not&amp;nbsp;certified&amp;nbsp;by&amp;nbsp;GitHub.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;#&amp;nbsp;They&amp;nbsp;are&amp;nbsp;provided&amp;nbsp;by&amp;nbsp;a&amp;nbsp;third-party&amp;nbsp;and&amp;nbsp;are&amp;nbsp;governed&amp;nbsp;by&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;#&amp;nbsp;separate&amp;nbsp;terms&amp;nbsp;of&amp;nbsp;service,&amp;nbsp;privacy&amp;nbsp;policy,&amp;nbsp;and&amp;nbsp;support&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;#&amp;nbsp;documentation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;#&amp;nbsp;This&amp;nbsp;workflow&amp;nbsp;will&amp;nbsp;build&amp;nbsp;a&amp;nbsp;Java&amp;nbsp;project&amp;nbsp;with&amp;nbsp;Gradle&amp;nbsp;and&amp;nbsp;cache/restore&amp;nbsp;any&amp;nbsp;dependencies&amp;nbsp;to&amp;nbsp;improve&amp;nbsp;the&amp;nbsp;workflow&amp;nbsp;execution&amp;nbsp;time&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;#&amp;nbsp;For&amp;nbsp;more&amp;nbsp;information&amp;nbsp;see:&amp;nbsp;https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;name&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;Java&amp;nbsp;CI&amp;nbsp;with&amp;nbsp;Gradle&amp;nbsp;and&amp;nbsp;CD&amp;nbsp;by&amp;nbsp;AWS&amp;nbsp;CodeDeploy&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;on&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;push&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;branches&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;[&amp;nbsp;&quot;main&quot;&amp;nbsp;]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;pull_request&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;branches&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;[&amp;nbsp;&quot;main&quot;&amp;nbsp;]&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;permissions&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;contents&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;read&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;jobs&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;ci-and-cd&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;runs-on&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;ubuntu-latest&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;steps&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;uses&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;actions/checkout@v3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;name&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;Set&amp;nbsp;up&amp;nbsp;JDK&amp;nbsp;17&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;uses&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;actions/setup-java@v3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;with&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;java-version&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;'17'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;distribution&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;'corretto'&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;name&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;Run&amp;nbsp;chmod&amp;nbsp;to&amp;nbsp;make&amp;nbsp;gradlew&amp;nbsp;executable&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;run&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;chmod&amp;nbsp;+x&amp;nbsp;./gradlew&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;name&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;Build&amp;nbsp;with&amp;nbsp;Gradle&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;uses&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;with&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;arguments&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;build&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;name&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;Make&amp;nbsp;zip&amp;nbsp;File&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;run&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;zip&amp;nbsp;-r&amp;nbsp;./build.zip&amp;nbsp;./build/libs/simple-http-rest-1.0.0.war&amp;nbsp;./appspec.yml&amp;nbsp;./.aws/aws-codedeploy-scripts&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #666666;&quot;&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;run:&amp;nbsp;zip&amp;nbsp;-r&amp;nbsp;./build.zip&amp;nbsp;./build/libs/*.war&amp;nbsp;./appspec.yml&amp;nbsp;./.aws/aws-codedeploy-scripts&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;name&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;Configure&amp;nbsp;AWS&amp;nbsp;credentials&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;uses&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;aws-actions/configure-aws-credentials@v1&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;with&lt;/span&gt;:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;aws-access-key-id&lt;/span&gt;: &lt;span style=&quot;color: #99cefa;&quot;&gt;${{ secrets.AWS_CD_ID }}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;aws-secret-access-key&lt;/span&gt;: &lt;span style=&quot;color: #99cefa;&quot;&gt;${{ secrets.AWS_CD_SECRET }}&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;aws-region&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;ap-northeast-2&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;name&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;Upload&amp;nbsp;to&amp;nbsp;S3&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;run&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;aws&amp;nbsp;s3&amp;nbsp;cp&amp;nbsp;--region&amp;nbsp;ap-northeast-2&amp;nbsp;./build.zip&amp;nbsp;s3://s3-cd-blackdeer/spring-simple-http-rest/build.zip&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;-&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;name&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;AWS&amp;nbsp;CodeDeploy&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9feec3;&quot;&gt;run&lt;/span&gt;:&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;aws&amp;nbsp;deploy&amp;nbsp;create-deployment&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;--application-name&amp;nbsp;test-spring-simple-rest&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;--deployment-group-name&amp;nbsp;cd-deploy-group-spring-simple-http-rest&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;--deployment-config-name&amp;nbsp;CodeDeployDefault.OneAtATime&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #99cefa;&quot;&gt;--s3-location&amp;nbsp;bucket=s3-cd-blackdeer,bundleType=zip,key=spring-simple-http-rest/build.zip&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'main' branch에 push나 pr이 완료되면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gradle로 빌드 후,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빌드 파일(&lt;span class=&quot;code-span&quot;&gt;*.war&lt;/span&gt;)과 &lt;span class=&quot;code-span&quot;&gt;appspec.yml&lt;/span&gt;, 스크립트 파일들(&lt;span class=&quot;code-span&quot;&gt;*.sh&lt;/span&gt;)을 압축하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 압축 파일을 AWS S3 버킷에 업로드 한 후,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS CodeDeploy 서비스에 배포를 요청한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ &lt;a href=&quot;https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ &lt;a href=&quot;https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/cli/latest/reference/s3/cp.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ &lt;a href=&quot;https://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.aws.amazon.com/cli/latest/reference/deploy/create-deployment.html&lt;/a&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;AWS S3 버킷에 압축 파일 업로드와 AWS CodeDeploy 요청에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS Credential이 필요하며, 그래서 IAM User와 액세스 키를 발급했던 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Repository의 Secrets에 저장했던 ID와 SECRET을 여기에서 사용한다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;확인&quot; 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;Github Action을 작성한 커밋 이후로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;main branch에 push될 때마다 해당 작업이 수행될 것이다.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;38_GithubAction.png&quot; data-origin-width=&quot;1489&quot; data-origin-height=&quot;1109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XO0fG/btrYkLRjFF9/7Li7kpEqbfrtCXhG3SxkP0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XO0fG/btrYkLRjFF9/7Li7kpEqbfrtCXhG3SxkP0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XO0fG/btrYkLRjFF9/7Li7kpEqbfrtCXhG3SxkP0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXO0fG%2FbtrYkLRjFF9%2F7Li7kpEqbfrtCXhG3SxkP0%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;1489&quot; height=&quot;1109&quot; data-filename=&quot;38_GithubAction.png&quot; data-origin-width=&quot;1489&quot; data-origin-height=&quot;1109&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Repository의 Actions 탭에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진행 상태와 결과 및 로그 등을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;re-run도 가능하다.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;39_S3.png&quot; data-origin-width=&quot;1449&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwjTW8/btrYjl0a5RP/MEtQCHeRqzk5VhLKc3ZewK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwjTW8/btrYjl0a5RP/MEtQCHeRqzk5VhLKc3ZewK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwjTW8/btrYjl0a5RP/MEtQCHeRqzk5VhLKc3ZewK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdwjTW8%2FbtrYjl0a5RP%2FMEtQCHeRqzk5VhLKc3ZewK%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;1449&quot; height=&quot;478&quot; data-filename=&quot;39_S3.png&quot; data-origin-width=&quot;1449&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;S3 버킷의 지정한 경로에 압축 파일이 업로드된 것도 확인할 수 있다.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;40_CodeDeploy.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnmQyi/btrYjDTQJjI/QR1Sz9gH6HHFk4BtZ21mK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnmQyi/btrYjDTQJjI/QR1Sz9gH6HHFk4BtZ21mK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnmQyi/btrYjDTQJjI/QR1Sz9gH6HHFk4BtZ21mK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnmQyi%2FbtrYjDTQJjI%2FQR1Sz9gH6HHFk4BtZ21mK1%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;1588&quot; height=&quot;778&quot; data-filename=&quot;40_CodeDeploy.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;778&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CodeDeploy의 애플리케이션이나 배포 그룹에서는 요청된 배포 내역을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;41_CodeDeploy.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;1034&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K1Kai/btrYj2y0L8Q/if0nVgUeRL7uV1MWD15maK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K1Kai/btrYj2y0L8Q/if0nVgUeRL7uV1MWD15maK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K1Kai/btrYj2y0L8Q/if0nVgUeRL7uV1MWD15maK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK1Kai%2FbtrYj2y0L8Q%2Fif0nVgUeRL7uV1MWD15maK%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;1588&quot; height=&quot;1034&quot; data-filename=&quot;41_CodeDeploy.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;1034&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 배포 ID를 누르면 인스턴스별 진행 정도나 가장 최근 이벤트 등을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 'View events'를 누르면 더 상세한 lifecycle 위치를 알 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;42_CodeDeploy.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;1029&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Esxwt/btrYmuaszZP/azC4Mdo2ad3esJzCMUBZjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Esxwt/btrYmuaszZP/azC4Mdo2ad3esJzCMUBZjK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Esxwt/btrYmuaszZP/azC4Mdo2ad3esJzCMUBZjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEsxwt%2FbtrYmuaszZP%2FazC4Mdo2ad3esJzCMUBZjK%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;1588&quot; height=&quot;1029&quot; data-filename=&quot;42_CodeDeploy.png&quot; data-origin-width=&quot;1588&quot; data-origin-height=&quot;1029&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 인스턴스에서는 해당 머신에 대해 더 자세한 로그를 뒤져볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;/var/log/aws/codedeploy-agent/codedeploy-agent.log&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;</description>
      <category>Study/AWS</category>
      <category>aws</category>
      <category>CodeDeploy</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/315</guid>
      <comments>https://ydeer.tistory.com/315#entry315comment</comments>
      <pubDate>Sat, 4 Feb 2023 16:46:05 +0900</pubDate>
    </item>
    <item>
      <title>원클릭 모니터변경 종결 (다중모니터,해상도,주사율,배율,회전,위치,...)</title>
      <link>https://ydeer.tistory.com/314</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;서론&quot;&gt;[서론]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;소개&quot;&gt;[소개]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;사용법&quot;&gt;[사용법]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;추가팁&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;서론&quot; 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;div&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/WudKIuSsiaY&quot; width=&quot;300&quot; height=&quot;225&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;&lt;/div&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;PC에 모니터를 3개나 연결해보면서 원하는 모니터 그룹만 켜두는 것이 Windows 기본 기능으로는 어려웠고(레지스트리를 변경해두어도...),&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 복귀시켰을 때 원래 위치나 해상도 등이 다른 현상이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 MSDN을 뒤지면서 또 Windows API를 삽질해보고 있었는데, 강력한 툴을 발견하여 또 소개한다.&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;Nir Sofer라는 분이 만드신 Freeware이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.nirsoft.net/utils/multi_monitor_tool.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.nirsoft.net/utils/multi_monitor_tool.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675414882308&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Enable/disable/configure multiple monitors on Windows&quot; data-og-description=&quot;&amp;nbsp; &amp;nbsp; MultiMonitorTool v2.00 - Enable/disable/configure multiple monitors on Windows Copyright (c) 2012 - 2023 Nir Sofer See Also ControlMyMonitor - View and modify the settings of your monitor (brightness, contrast, sharpness, input source, and more...) M&quot; data-og-host=&quot;www.nirsoft.net&quot; data-og-source-url=&quot;https://www.nirsoft.net/utils/multi_monitor_tool.html&quot; data-og-url=&quot;https://www.nirsoft.net/utils/multi_monitor_tool.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/OtziI/hyRtRYEpf7/9Tk4ESK0SNU8u6g1uUiCoK/img.png?width=616&amp;amp;height=390&amp;amp;face=0_0_616_390,https://scrap.kakaocdn.net/dn/w3DAT/hyRt1UwQ9h/KSKL7CgCeUtIonAmsziwB0/img.jpg?width=1014&amp;amp;height=760&amp;amp;face=0_0_1014_760&quot;&gt;&lt;a href=&quot;https://www.nirsoft.net/utils/multi_monitor_tool.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.nirsoft.net/utils/multi_monitor_tool.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/OtziI/hyRtRYEpf7/9Tk4ESK0SNU8u6g1uUiCoK/img.png?width=616&amp;amp;height=390&amp;amp;face=0_0_616_390,https://scrap.kakaocdn.net/dn/w3DAT/hyRt1UwQ9h/KSKL7CgCeUtIonAmsziwB0/img.jpg?width=1014&amp;amp;height=760&amp;amp;face=0_0_1014_760');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Enable/disable/configure multiple monitors on Windows&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; MultiMonitorTool v2.00 - Enable/disable/configure multiple monitors on Windows Copyright (c) 2012 - 2023 Nir Sofer See Also ControlMyMonitor - View and modify the settings of your monitor (brightness, contrast, sharpness, input source, and more...) M&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.nirsoft.net&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;a href=&quot;https://www.nirsoft.net/utils/multimonitortool.zip&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.nirsoft.net/utils/multimonitortool.zip&lt;/a&gt; (32bit)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.nirsoft.net/utils/multimonitortool-x64.zip&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.nirsoft.net/utils/multimonitortool-x64.zip&lt;/a&gt; (64bit)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백업용으로도 함께 올려두겠음.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bfPDal/btrX2ZClDmt/3cDPbJ2JfR5ot6XMvg4Ob0/multimonitortool.zip?attach=1&amp;amp;knm=tfile.zip&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;multimonitortool.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.20MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/EKOxB/btrX32eeiJd/DhkJGnrX12Mj6MOxwCQnp1/multimonitortool-x64.zip?attach=1&amp;amp;knm=tfile.zip&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;multimonitortool-x64.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.22MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인의 Windows가 64비트 운영체제라면 아래의 x64를 권장하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;32비트라면 위의 것을 받으면 된다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;소개&quot; 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;압축을 풀고 MultiMonitorTool.exe를 실행해보자.&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;02.png&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wCv6c/btrX1w82I57/9rB4qQ1mjXBaoo5KIqcu70/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wCv6c/btrX1w82I57/9rB4qQ1mjXBaoo5KIqcu70/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wCv6c/btrX1w82I57/9rB4qQ1mjXBaoo5KIqcu70/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwCv6c%2FbtrX1w82I57%2F9rB4qQ1mjXBaoo5KIqcu70%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;626&quot; height=&quot;473&quot; data-filename=&quot;02.png&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PC에 연결된 모니터들이 뜨며, 우클릭해보면 여러 가지 설정을 할 수 있다.&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;span class=&quot;winlogo&quot;&gt;&lt;/span&gt;]+[i]에서 디스플레이 설정을 통해 설정하는 것이 편할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;03.png&quot; data-origin-width=&quot;1194&quot; data-origin-height=&quot;984&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ROQtG/btrX1w2f7nu/TbRVW5FeZSDrVfkER2aKH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ROQtG/btrX1w2f7nu/TbRVW5FeZSDrVfkER2aKH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ROQtG/btrX1w2f7nu/TbRVW5FeZSDrVfkER2aKH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FROQtG%2FbtrX1w2f7nu%2FTbRVW5FeZSDrVfkER2aKH1%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;494&quot; data-filename=&quot;03.png&quot; data-origin-width=&quot;1194&quot; data-origin-height=&quot;984&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[&lt;span class=&quot;winlogo&quot;&gt;&lt;/span&gt;]+[i]의 디스플레이 설정에서도 모두 설정 가능한 항목들이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 존재하지 않는 해상도는 역시나 설정할 수 없으니, 없는 해상도의 추가는 아래의 포스트를 참고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ydeer.tistory.com/176&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[PC원격제어/help] - 해상도 추가하기&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675415989282&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;해상도 추가하기&quot; data-og-description=&quot;[PC원격제어/help] - 원클릭 해상도 변경 원클릭 해상도 변경하기에서, 해상도 목록에 없는 해상도는 당장 사용할 수 없었습니다. 이제, 목록에 없는 해상도를 추가해봅시다. 저는 NVIDIA계열 그래픽&quot; data-og-host=&quot;ydeer.tistory.com&quot; data-og-source-url=&quot;https://ydeer.tistory.com/176&quot; data-og-url=&quot;https://ydeer.tistory.com/176&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bPCZ4N/hyRvlX7zb2/TvWzNAFd2ZUap4osK9qHi1/img.png?width=611&amp;amp;height=492&amp;amp;face=0_0_611_492,https://scrap.kakaocdn.net/dn/zOE2g/hyRtUA4Fgo/tpWrUuaVt49UdtYQrYHXs1/img.png?width=611&amp;amp;height=492&amp;amp;face=0_0_611_492,https://scrap.kakaocdn.net/dn/ho1ZN/hyRtXEw5un/7k3nApTYi3yUXNSC0IXgM0/img.png?width=960&amp;amp;height=711&amp;amp;face=0_0_960_711&quot;&gt;&lt;a href=&quot;https://ydeer.tistory.com/176&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ydeer.tistory.com/176&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bPCZ4N/hyRvlX7zb2/TvWzNAFd2ZUap4osK9qHi1/img.png?width=611&amp;amp;height=492&amp;amp;face=0_0_611_492,https://scrap.kakaocdn.net/dn/zOE2g/hyRtUA4Fgo/tpWrUuaVt49UdtYQrYHXs1/img.png?width=611&amp;amp;height=492&amp;amp;face=0_0_611_492,https://scrap.kakaocdn.net/dn/ho1ZN/hyRtXEw5un/7k3nApTYi3yUXNSC0IXgM0/img.png?width=960&amp;amp;height=711&amp;amp;face=0_0_960_711');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;해상도 추가하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[PC원격제어/help] - 원클릭 해상도 변경 원클릭 해상도 변경하기에서, 해상도 목록에 없는 해상도는 당장 사용할 수 없었습니다. 이제, 목록에 없는 해상도를 추가해봅시다. 저는 NVIDIA계열 그래픽&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ydeer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;사용법&quot; 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;h2 data-ke-size=&quot;size26&quot;&gt;중요한 건 이런 설정들을 하는 부분이 아니라, &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;원클릭으로 원하는 상태를 오가는 것이다.&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 원하는 전체 상태별로 저장(cfg)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. cfg마다 bat 파일 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 이제 그냥 bat 파일 실행만 하면 끝&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;04.png&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bslBYn/btrX2mR7wrx/zz8KuKhmE1lDSBJGDIY8Wk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bslBYn/btrX2mR7wrx/zz8KuKhmE1lDSBJGDIY8Wk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bslBYn/btrX2mR7wrx/zz8KuKhmE1lDSBJGDIY8Wk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbslBYn%2FbtrX2mR7wrx%2Fzz8KuKhmE1lDSBJGDIY8Wk%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;626&quot; height=&quot;473&quot; data-filename=&quot;04.png&quot; data-origin-width=&quot;626&quot; data-origin-height=&quot;473&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;위의 메뉴를 통해 현재 상태를 파일로 저장한다. (이게 cfg파일)&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 원하는 상태들마다 cfg파일로 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(ex: 모두 켜진 상태, 하나만 켜진 상태, 둘이 켜졌으나 두번째는 세로로 회전한 상태, ...)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;이제 bat 파일을 작성해보자.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모장을 열어서(※ [&lt;span class=&quot;winlogo&quot;&gt;&lt;/span&gt;]+[R] &amp;rarr; &quot;notepad&quot; &amp;rarr; 확인), 아래의 예시처럼 작성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1675416173080&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@echo off
&quot;D:\Utilities\multimonitortool-x64\MultiMonitorTool.exe&quot;   /LoadConfig   &quot;D:\Utilities\multimonitortool-x64\Only_PC.cfg&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;&quot;exe프로그램의_절대경로&quot;&amp;nbsp; &amp;nbsp; &amp;nbsp;/LoadConfig&amp;nbsp; &amp;nbsp; &amp;nbsp;&quot;저장한_cfg파일의_절대경로&quot;&lt;/span&gt; 는 본인 상황에 맞게 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 폴더 이름 등에 공백이 들어갈 수 있어서 큰따옴표(&quot;)로 묶은 것이다.&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;만약 위처럼 적는게 어렵다면, exe프로그램과 cfg파일과 bat파일을 모두 같은 폴더 안에 둔다는 가정 하에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;MultiMonitorTool.exe&amp;nbsp; &amp;nbsp;/LoadConfig&amp;nbsp; &amp;nbsp;cfg파일이름.cfg&lt;/span&gt; 라고 상대경로로 적는 것 만으로도 간단하게 작성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cfg파일 이름에 공백이 들어간다면 위 예시처럼 큰따옴표(&quot;)로 묶거나, 아예 공백을 뺀 이름으로 수정한다.&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;이걸 아무이름.bat 이름으로 저장한다(이름은 cfg파일과 통일하는 것이 구분하기 쉽다).&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;05.png&quot; data-origin-width=&quot;609&quot; data-origin-height=&quot;117&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oYX6t/btrX18UaABH/ij0MhF5UmvuXGxfkYG9KQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oYX6t/btrX18UaABH/ij0MhF5UmvuXGxfkYG9KQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oYX6t/btrX18UaABH/ij0MhF5UmvuXGxfkYG9KQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoYX6t%2FbtrX18UaABH%2Fij0MhF5UmvuXGxfkYG9KQ0%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;609&quot; height=&quot;117&quot; data-filename=&quot;05.png&quot; data-origin-width=&quot;609&quot; data-origin-height=&quot;117&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저장시 파일 형식이 텍스트 문서(*.txt)라면 이름을 ~.bat으로 지정했어도 ~.txt로 텍스트 문서로 저장될 수도 있다.&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;이 ~.bat 파일들을 ~.cfg 파일마다 작성해준다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;b&gt;작성한 ~.bat 파일을 실행하기만 해도 원하는 상태로 전환된다.&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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;추가팁&quot; 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;이 bat파일을 우클릭하여 바로 가기를 생성한 후, 원하는 곳마다 두어 편리하게 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 맨 위 사용예 영상에서의 Windows 10의 타일 메뉴는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C(윈도우설치드라이브):\Users\로그온한사용자\AppData\Roaming\Microsoft\Windows\Start Menu\Programs에 두면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;00.png&quot; data-origin-width=&quot;930&quot; data-origin-height=&quot;426&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nkWMZ/btrX15wnM8n/61ttxjKjutzOmlc8QxFd9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nkWMZ/btrX15wnM8n/61ttxjKjutzOmlc8QxFd9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nkWMZ/btrX15wnM8n/61ttxjKjutzOmlc8QxFd9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnkWMZ%2FbtrX15wnM8n%2F61ttxjKjutzOmlc8QxFd9k%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;930&quot; height=&quot;426&quot; data-filename=&quot;00.png&quot; data-origin-width=&quot;930&quot; data-origin-height=&quot;426&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;01.png&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnGc0z/btrX3rZL9St/QRu4klQLbYvY8d0euu7fpK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnGc0z/btrX3rZL9St/QRu4klQLbYvY8d0euu7fpK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnGc0z/btrX3rZL9St/QRu4klQLbYvY8d0euu7fpK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnGc0z%2FbtrX3rZL9St%2FQRu4klQLbYvY8d0euu7fpK%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;684&quot; height=&quot;540&quot; data-filename=&quot;01.png&quot; data-origin-width=&quot;684&quot; data-origin-height=&quot;540&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;/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>PC원격제어/help</category>
      <category>다중모니터</category>
      <category>모니터</category>
      <category>주사율</category>
      <category>해상도</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/314</guid>
      <comments>https://ydeer.tistory.com/314#entry314comment</comments>
      <pubDate>Fri, 3 Feb 2023 18:07:12 +0900</pubDate>
    </item>
    <item>
      <title>AWS ALB(Application Load Balancer) 기초</title>
      <link>https://ydeer.tistory.com/313</link>
      <description>&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_01.png&quot; data-origin-width=&quot;1675&quot; data-origin-height=&quot;415&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/90vfg/btrXYqnIeWy/vW6PSgYCSed6gXpTAB9xoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/90vfg/btrXYqnIeWy/vW6PSgYCSed6gXpTAB9xoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/90vfg/btrXYqnIeWy/vW6PSgYCSed6gXpTAB9xoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F90vfg%2FbtrXYqnIeWy%2FvW6PSgYCSed6gXpTAB9xoK%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;1675&quot; height=&quot;415&quot; data-filename=&quot;_01.png&quot; data-origin-width=&quot;1675&quot; data-origin-height=&quot;415&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;EC2 &amp;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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_02.png&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;875&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLOuqy/btrX2mRoP0K/6l7KIY6TDPWdeU8reITxv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLOuqy/btrX2mRoP0K/6l7KIY6TDPWdeU8reITxv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLOuqy/btrX2mRoP0K/6l7KIY6TDPWdeU8reITxv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLOuqy%2FbtrX2mRoP0K%2F6l7KIY6TDPWdeU8reITxv1%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;1002&quot; height=&quot;875&quot; data-filename=&quot;_02.png&quot; data-origin-width=&quot;1002&quot; data-origin-height=&quot;875&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Application Load Balancer 선택&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_03.png&quot; data-origin-width=&quot;1160&quot; data-origin-height=&quot;3179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg1FFo/btrX1yrwl7K/LN53KKR64xpeYjwl12k08k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg1FFo/btrX1yrwl7K/LN53KKR64xpeYjwl12k08k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg1FFo/btrX1yrwl7K/LN53KKR64xpeYjwl12k08k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg1FFo%2FbtrX1yrwl7K%2FLN53KKR64xpeYjwl12k08k%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;1160&quot; height=&quot;3179&quot; data-filename=&quot;_03.png&quot; data-origin-width=&quot;1160&quot; data-origin-height=&quot;3179&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;/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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;펼치기: 대상 그룹 생성&quot; data-text-less=&quot;접기: 대상 그룹 생성&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_04.png&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;2746&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rAgGL/btrXZRyEitm/zk26FGUdrtcnSQBilyyeaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rAgGL/btrXZRyEitm/zk26FGUdrtcnSQBilyyeaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rAgGL/btrXZRyEitm/zk26FGUdrtcnSQBilyyeaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrAgGL%2FbtrXZRyEitm%2Fzk26FGUdrtcnSQBilyyeaK%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;1162&quot; height=&quot;2746&quot; data-filename=&quot;_04.png&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;2746&quot;/&gt;&lt;/span&gt;&lt;/figure&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;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_05.png&quot; data-origin-width=&quot;1582&quot; data-origin-height=&quot;1022&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bC6tQE/btrX01OtZta/67bC6uhFAydoV4Nmx5m2f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bC6tQE/btrX01OtZta/67bC6uhFAydoV4Nmx5m2f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bC6tQE/btrX01OtZta/67bC6uhFAydoV4Nmx5m2f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbC6tQE%2FbtrX01OtZta%2F67bC6uhFAydoV4Nmx5m2f1%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;1582&quot; height=&quot;1022&quot; data-filename=&quot;_05.png&quot; data-origin-width=&quot;1582&quot; data-origin-height=&quot;1022&quot;/&gt;&lt;/span&gt;&lt;/figure&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;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_06.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/m7NEG/btrXXyM53jG/qAfDwS3LbmRPAqhhQtD4MK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/m7NEG/btrXXyM53jG/qAfDwS3LbmRPAqhhQtD4MK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/m7NEG/btrXXyM53jG/qAfDwS3LbmRPAqhhQtD4MK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fm7NEG%2FbtrXXyM53jG%2FqAfDwS3LbmRPAqhhQtD4MK%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;1400&quot; height=&quot;422&quot; data-filename=&quot;_06.png&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;

&lt;p data-ke-size=&quot;size16&quot;&gt;아래에 추가된 대상과 포트들을 확인하고 대상 그룹을 생성한다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_07.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;290&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWo2Bt/btrX1AbQiYH/kW4kNgBQumuIuoWu6fkZbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWo2Bt/btrX1AbQiYH/kW4kNgBQumuIuoWu6fkZbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWo2Bt/btrX1AbQiYH/kW4kNgBQumuIuoWu6fkZbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWo2Bt%2FbtrX1AbQiYH%2FkW4kNgBQumuIuoWu6fkZbk%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;1920&quot; height=&quot;290&quot; data-filename=&quot;_07.png&quot; data-origin-width=&quot;1920&quot; data-origin-height=&quot;290&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;&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_08.png&quot; data-origin-width=&quot;1863&quot; data-origin-height=&quot;899&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ym2c7/btrXYrAbyIb/l43iFK1L2oYkVaYQQabkvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ym2c7/btrXYrAbyIb/l43iFK1L2oYkVaYQQabkvK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ym2c7/btrXYrAbyIb/l43iFK1L2oYkVaYQQabkvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fym2c7%2FbtrXYrAbyIb%2Fl43iFK1L2oYkVaYQQabkvK%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;1863&quot; height=&quot;899&quot; data-filename=&quot;_08.png&quot; data-origin-width=&quot;1863&quot; data-origin-height=&quot;899&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;&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_09.png&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;740&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QCwDk/btrX2pm2o6S/n6G86cMddfR6TPEyWKjQH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QCwDk/btrX2pm2o6S/n6G86cMddfR6TPEyWKjQH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QCwDk/btrX2pm2o6S/n6G86cMddfR6TPEyWKjQH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQCwDk%2FbtrX2pm2o6S%2Fn6G86cMddfR6TPEyWKjQH1%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;784&quot; height=&quot;740&quot; data-filename=&quot;_09.png&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;740&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;uarr;위는 EC2에 직접 요청한 결과이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;darr;아래는 로드 밸런서에 요청하여 로드 밸런서가 EC2로 전달하고 받은 요청을 전달해준 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;_10.png&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;740&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZ7YkF/btrX0LLHG06/betGkOtqUTihilyeSK8ufK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZ7YkF/btrX0LLHG06/betGkOtqUTihilyeSK8ufK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZ7YkF/btrX0LLHG06/betGkOtqUTihilyeSK8ufK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZ7YkF%2FbtrX0LLHG06%2FbetGkOtqUTihilyeSK8ufK%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;784&quot; height=&quot;740&quot; data-filename=&quot;_10.png&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;740&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;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/AWS</category>
      <category>ALB</category>
      <category>aws</category>
      <category>Load Balancer</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/313</guid>
      <comments>https://ydeer.tistory.com/313#entry313comment</comments>
      <pubDate>Fri, 3 Feb 2023 15:47:30 +0900</pubDate>
    </item>
    <item>
      <title>NGINX 오픈소스 버전에 upstream health check 모듈 추가</title>
      <link>https://ydeer.tistory.com/312</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;개요&quot;&gt;[개요]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;설치&quot;&gt;[설치]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;설정&quot;&gt;[설정]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;실행&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;개요&quot; 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;NGINX는 점유율 1위(2022년 5월 기준)의 웹서버로, 비동기식 처리 방식으로 로드밸런싱이 가능하다.&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;a href=&quot;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675171631282&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;HTTP Health Checks | NGINX Plus&quot; data-og-description=&quot;HTTP Health Checks Monitor the health of HTTP servers in an upstream group by sending periodic health checks, including customizable active health checks in NGINX Plus. Introduction NGINX and NGINX Plus can continually test your upstream servers, avoid the&quot; data-og-host=&quot;docs.nginx.com&quot; data-og-source-url=&quot;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/&quot; data-og-url=&quot;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bwkbrF/hyRsfxUlUt/7hZe7lBUMPPdZw2b3SMmwK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/idAX5/hyRstv7xdp/DIAP3phyhpElzSjAEXXkR0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.nginx.com/nginx/admin-guide/load-balancer/http-health-check/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bwkbrF/hyRsfxUlUt/7hZe7lBUMPPdZw2b3SMmwK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/idAX5/hyRstv7xdp/DIAP3phyhpElzSjAEXXkR0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HTTP Health Checks | NGINX Plus&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;HTTP Health Checks Monitor the health of HTTP servers in an upstream group by sending periodic health checks, including customizable active health checks in NGINX Plus. Introduction NGINX and NGINX Plus can continually test your upstream servers, avoid the&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.nginx.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들어온 요청을 뒷단(upstream) 중 하나로 전달하고 응답을 받아와서 넘겨주는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로직에 따라 서버를 선택하지만, 그 서버가 살아있는지 지속적으로 health check하는 기능은 NGINX Plus(commercial 버전. 구독료 버전)에만 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오픈소스 버전에도 제공하는 옵션은 각 서버에 &lt;span class=&quot;code-span&quot;&gt;max_fails&lt;/span&gt;(기본값 1회), &lt;span class=&quot;code-span&quot;&gt;fail_timeout&lt;/span&gt;(기본값 10초) 을 지정하는 것 밖에 없다.&lt;/p&gt;
&lt;pre id=&quot;code_1675212699115&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;upstream spring-simple-rest {
    least_conn;
    server nginx-spring-01:8091 max_fails=1 fail_timeout=3s;
    server nginx-spring-02:8092 max_fails=1 fail_timeout=3s;
    server nginx-spring-03:8093 max_fails=1 fail_timeout=3s;
}&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;특정 API가 평균 소요시간이 길다면 &lt;span class=&quot;code-span&quot;&gt;fail_timeout&lt;/span&gt;은 그보다 길어야할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정에 따라 다르지만, 뒷단이 죽어있어도 &lt;span class=&quot;code-span&quot;&gt;fail_timeout&lt;/span&gt;만큼 기다린 후에야 다른 쪽으로 요청을 넘기기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 &lt;span class=&quot;code-span&quot;&gt;fail_timeout&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 시간마다 개별적으로 health check를 하고, 뒷단들의 상태를 갖고 있어서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요청이 들어오면 살아있는 쪽들만 후보로 하면, upstream 중 일부에 장애가 있을 때 불필요한 지연을 없앨 수 있다.&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;그런데 이 기능이 NGINX Plus에만 제공되고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 오픈소스 모듈을 설치 가능하니, 가장 많이 사용하는 upstream health check 모듈을 설치하여 사용해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/yaoweibin/nginx_upstream_check_module&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/yaoweibin/nginx_upstream_check_module&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675172473524&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - yaoweibin/nginx_upstream_check_module: Health checks upstreams for nginx&quot; data-og-description=&quot;Health checks upstreams for nginx. Contribute to yaoweibin/nginx_upstream_check_module development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/yaoweibin/nginx_upstream_check_module&quot; data-og-url=&quot;https://github.com/yaoweibin/nginx_upstream_check_module&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://github.com/yaoweibin/nginx_upstream_check_module&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/yaoweibin/nginx_upstream_check_module&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - yaoweibin/nginx_upstream_check_module: Health checks upstreams for nginx&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Health checks upstreams for nginx. Contribute to yaoweibin/nginx_upstream_check_module development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;설치&quot; 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;위의 오픈소스 모듈 git 프로젝트(&lt;a href=&quot;https://github.com/yaoweibin/nginx_upstream_check_module&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/yaoweibin/nginx_upstream_check_module&lt;/a&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;오픈소스 모듈의 버전 업이 NGINX에 비해 원활하지 않은 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NGINX가 너무 상위 버전이라면 아직 이 모듈이 적용되는 범위를 벗어날 수 있으니, 이를 참고하여 NGINX 역시 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://nginx.org/download/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://nginx.org/download/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675212870899&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Index of /download/&quot; data-og-description=&quot;&quot; data-og-host=&quot;nginx.org&quot; data-og-source-url=&quot;https://nginx.org/download/&quot; data-og-url=&quot;https://nginx.org/download/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://nginx.org/download/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://nginx.org/download/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Index of /download/&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;nginx.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NGINX의 압축도 풀어둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;patch&lt;/span&gt; 명령어로 풀어둔 NGINX들에 패치를 할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ patch 명령어는 Docker 이미지류에는 어디에도 존재하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　Docker가 이미 레이어 타입이기 때문.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　다른 Linux/Unix에서 패치 후 디렉터리들을 COPY하는 방식으로 사용하자.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;~ %&lt;/span&gt; cd nginx-1.20.1&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;nginx-1.20.1 %&lt;/span&gt; patch -p1 &amp;lt; ~/Downloads/nginx_upstream_check_module/check_1.20.1+.patch&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;patching&amp;nbsp;file&amp;nbsp;'src/http/modules/ngx_http_upstream_hash_module.c'&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;patching&amp;nbsp;file&amp;nbsp;'src/http/modules/ngx_http_upstream_ip_hash_module.c'&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;patching&amp;nbsp;file&amp;nbsp;'src/http/modules/ngx_http_upstream_least_conn_module.c'&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;patching&amp;nbsp;file&amp;nbsp;'src/http/ngx_http_upstream_round_robin.c'&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;patching&amp;nbsp;file&amp;nbsp;'src/http/ngx_http_upstream_round_robin.h'&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nginx 디렉터리 내부에 ./src/http/...에 위 파일들이 수정된 것을 수정된 날짜나 내용등을 통해 확인할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이대로 컴파일 후 빌드할텐데, c로 작성된 프로그램이니 c 컴파일러가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 여기서부터의 과정을 Docker 방식으로 하고 싶다면, 과정 아래에 Dockerfile로 간략하게 수록했으니 참고.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;nginx-1.20.1 %&lt;/span&gt; ./configure&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: dashed 1px gray;&quot;&gt;&amp;nbsp;--add-module=~/Downloads/nginx_upstream_check_module&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;Configuration&amp;nbsp;summary&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;+&amp;nbsp;using&amp;nbsp;system&amp;nbsp;PCRE&amp;nbsp;library&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;+&amp;nbsp;OpenSSL&amp;nbsp;library&amp;nbsp;is&amp;nbsp;not&amp;nbsp;used&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;+&amp;nbsp;using&amp;nbsp;system&amp;nbsp;zlib&amp;nbsp;library&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;path&amp;nbsp;prefix:&amp;nbsp;&quot;/usr/local/nginx&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;binary&amp;nbsp;file:&amp;nbsp;&quot;/usr/local/nginx/sbin/nginx&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;modules&amp;nbsp;path:&amp;nbsp;&quot;/usr/local/nginx/modules&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;configuration&amp;nbsp;prefix:&amp;nbsp;&quot;/usr/local/nginx/conf&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;configuration&amp;nbsp;file:&amp;nbsp;&quot;/usr/local/nginx/conf/nginx.conf&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;pid&amp;nbsp;file:&amp;nbsp;&quot;/usr/local/nginx/logs/nginx.pid&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;error&amp;nbsp;log&amp;nbsp;file:&amp;nbsp;&quot;/usr/local/nginx/logs/error.log&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;http&amp;nbsp;access&amp;nbsp;log&amp;nbsp;file:&amp;nbsp;&quot;/usr/local/nginx/logs/access.log&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;http&amp;nbsp;client&amp;nbsp;request&amp;nbsp;body&amp;nbsp;temporary&amp;nbsp;files:&amp;nbsp;&quot;client_body_temp&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;http&amp;nbsp;proxy&amp;nbsp;temporary&amp;nbsp;files:&amp;nbsp;&quot;proxy_temp&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;http&amp;nbsp;fastcgi&amp;nbsp;temporary&amp;nbsp;files:&amp;nbsp;&quot;fastcgi_temp&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;http&amp;nbsp;uwsgi&amp;nbsp;temporary&amp;nbsp;files:&amp;nbsp;&quot;uwsgi_temp&quot;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;nginx&amp;nbsp;http&amp;nbsp;scgi&amp;nbsp;temporary&amp;nbsp;files:&amp;nbsp;&quot;scgi_temp&quot;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 &lt;span class=&quot;code-span&quot;&gt;nginx/configure&lt;/span&gt;에 &lt;span class=&quot;code-span&quot;&gt;--add-module&lt;/span&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;※ 전체 설치 경로 시작(NGINX_PREFIX)의 기본값은 &lt;span class=&quot;code-span&quot;&gt;/usr/local/nginx&lt;/span&gt;인데, &lt;span class=&quot;code-span&quot;&gt;--prefix=경로&lt;/span&gt; 옵션을 주어 전체 설치 경로를 지정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　다른 옵션은 &lt;a href=&quot;https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.nginx.com/nginx/admin-guide/installing-nginx/installing-nginx-open-source/&lt;/a&gt;의 Configuring NGINX Paths에서 확인.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 빌드와 설치를 진행한다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;nginx-1.20.1 %&lt;/span&gt; make&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;...&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;...&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;nginx-1.20.1 %&lt;/span&gt; make install&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;...&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;...&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류 없이 설치되었다면 설치 경로를 확인해본다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;%&lt;/span&gt; ls -al /usr/local/nginx&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;4&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;11&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;352&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:52&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;4096&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:27&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwx------&amp;nbsp;&amp;nbsp;2&amp;nbsp;nobody&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;64&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:52&amp;nbsp;client_body_temp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;18&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;576&amp;nbsp;Feb&amp;nbsp;&amp;nbsp;1&amp;nbsp;00:49&amp;nbsp;conf&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwx------&amp;nbsp;&amp;nbsp;2&amp;nbsp;nobody&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;64&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:52&amp;nbsp;fastcgi_temp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;4&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;128&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;html&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;5&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;160&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;13:10&amp;nbsp;logs&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwx------&amp;nbsp;&amp;nbsp;2&amp;nbsp;nobody&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;64&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:52&amp;nbsp;proxy_temp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;&amp;nbsp;3&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;96&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;sbin&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwx------&amp;nbsp;&amp;nbsp;2&amp;nbsp;nobody&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;64&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:52&amp;nbsp;scgi_temp&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwx------&amp;nbsp;&amp;nbsp;2&amp;nbsp;nobody&amp;nbsp;root&amp;nbsp;&amp;nbsp;&amp;nbsp;64&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:52&amp;nbsp;uwsgi_temp&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행할 프로그램은 &lt;span class=&quot;code-span&quot;&gt;./sbin/nginx&lt;/span&gt; 이다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;%&lt;/span&gt; /usr/local/nginx/sbin/nginx&amp;nbsp;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;-V&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;nginx&amp;nbsp;version:&amp;nbsp;nginx/1.20.1&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;built&amp;nbsp;by&amp;nbsp;gcc&amp;nbsp;12.2.0&amp;nbsp;(GCC)&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;configure&amp;nbsp;arguments:&amp;nbsp;--add-module=/nginx_upstream_check_module&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-V 옵션으로 실행시키면 버전 확인과 빌드 설정시 지정했던 옵션 등을 확인할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;./configure&lt;/span&gt;, &lt;span class=&quot;code-span&quot;&gt;make&lt;/span&gt;, &lt;span class=&quot;code-span&quot;&gt;make install&lt;/span&gt;의 &lt;span class=&quot;code-span code-b&quot;&gt;Dockerfile&lt;/span&gt; 예시를 수록한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;c 컴파일러로 gcc 이미지를 사용했다.(예시의 이미지는 용량이 무려 1.27 GB이니, 가벼운 c 컴파일러 수록 이미지를 찾아보는 것을 추천)&lt;/p&gt;
&lt;pre id=&quot;code_1675215152698&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM gcc:12.2.0

COPY --chown=0:0 --chmod=775 ./nginx-1.20.1 /nginx-1.20.1
COPY --chown=0:0 --chmod=775 ./nginx_upstream_check_module /nginx_upstream_check_module
WORKDIR /nginx-1.20.1
RUN [ &quot;./configure&quot;, &quot;--add-module=/nginx_upstream_check_module&quot; ]
RUN [ &quot;make&quot; ]
RUN [ &quot;make&quot;, &quot;install&quot; ]

WORKDIR /
ENTRYPOINT [ &quot;bin/bash&quot; ]

EXPOSE 8081&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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;설정&quot; 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;설치한 nginx의 conf 디렉터리(&lt;span class=&quot;code-span&quot;&gt;/usr/local/nginx/conf&lt;/span&gt;)를 확인해보자.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;%&lt;/span&gt; ls -al /usr/local/nginx/conf&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;total&amp;nbsp;76&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;18&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;576&amp;nbsp;Feb&amp;nbsp;&amp;nbsp;1&amp;nbsp;00:49&amp;nbsp;.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;drwxr-xr-x&amp;nbsp;11&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;352&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:52&amp;nbsp;..&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;1077&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;fastcgi.conf&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;1077&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;fastcgi.conf.default&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;1007&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;fastcgi_params&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;1007&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;fastcgi_params.default&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;2837&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;koi-utf&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;2223&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;koi-win&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;5231&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;mime.types&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1 root root 5231 Jan 31 12:24 mime.types.default&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1 root root 2656&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;nginx.conf&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;2656&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;nginx.conf.default&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;636&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;scgi_params&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;636&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;scgi_params.default&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;664&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;uwsgi_params&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1&amp;nbsp;root&amp;nbsp;root&amp;nbsp;&amp;nbsp;664&amp;nbsp;Jan&amp;nbsp;31&amp;nbsp;12:24&amp;nbsp;uwsgi_params.default&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;-rwxr-xr-x&amp;nbsp;&amp;nbsp;1 root root 3610 Jan 31 12:24 win-utf&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 &lt;span class=&quot;code-span&quot;&gt;nginx.conf&lt;/span&gt; 파일을 수정해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;http {}&lt;/span&gt; 블록 내부 맨 아래에 &lt;span class=&quot;code-span&quot;&gt;include &lt;span class=&quot;code-b&quot;&gt;my.conf&lt;/span&gt;;&lt;/span&gt; 한 줄만 추가해주자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 빠져나온 후, &lt;span class=&quot;code-span&quot;&gt;my.conf&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;아래는 모듈을 설치하지 않은 my.conf 예시이다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;server_tokens&amp;nbsp;off;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;upstream&amp;nbsp;spring-simple-rest&amp;nbsp;{&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;least_conn;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server&amp;nbsp;nginx-spring-01:8091&amp;nbsp;max_fails=1&amp;nbsp;fail_timeout=3s;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server&amp;nbsp;nginx-spring-02:8092&amp;nbsp;max_fails=1&amp;nbsp;fail_timeout=3s;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server&amp;nbsp;nginx-spring-03:8093&amp;nbsp;max_fails=1&amp;nbsp;fail_timeout=3s;&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;server&amp;nbsp;{&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 8081;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;server_name&amp;nbsp;*;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location&amp;nbsp;/&amp;nbsp;{&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass&amp;nbsp;http://spring-simple-rest;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_http_version&amp;nbsp;1.1;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header&amp;nbsp;Host&amp;nbsp;$http_host;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;proxy_set_header&amp;nbsp;X-Real-IP&amp;nbsp;$remote_addr;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;proxy_set_header&amp;nbsp;X-Forwarded-For&amp;nbsp;$proxy_add_x_forwarded_for;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;proxy_set_header&amp;nbsp;X-Forwarded-Proto&amp;nbsp;$scheme;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_redirect&amp;nbsp;off;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 모듈을 설치하여 upstream health check를 하는 my.conf의 예시이다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;server_tokens&amp;nbsp;off;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;upstream&amp;nbsp;spring-simple-rest&amp;nbsp;{&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;least_conn;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server&amp;nbsp;nginx-spring-01:8091&amp;nbsp;max_fails=1&amp;nbsp;fail_timeout=3s;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server&amp;nbsp;nginx-spring-02:8092&amp;nbsp;max_fails=1&amp;nbsp;fail_timeout=3s;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server&amp;nbsp;nginx-spring-03:8093&amp;nbsp;max_fails=1&amp;nbsp;fail_timeout=3s;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;check interval=1000 rise=1 fall=4 timeout=200 type=http;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;check_http_send&amp;nbsp;&quot;HEAD&amp;nbsp;/simple/healthcheck&amp;nbsp;HTTP/1.0\r\n\r\n&quot;;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;check_http_expect_alive&amp;nbsp;http_2xx&amp;nbsp;http_3xx;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;server&amp;nbsp;{&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;listen 8081;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;#&amp;nbsp;server_name&amp;nbsp;*;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location&amp;nbsp;/&amp;nbsp;{&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_pass&amp;nbsp;http://spring-simple-rest;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_http_version&amp;nbsp;1.1;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_set_header&amp;nbsp;Host&amp;nbsp;$http_host;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;proxy_set_header&amp;nbsp;X-Real-IP&amp;nbsp;$remote_addr;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;proxy_set_header&amp;nbsp;X-Forwarded-For&amp;nbsp;$proxy_add_x_forwarded_for;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;proxy_set_header&amp;nbsp;X-Forwarded-Proto&amp;nbsp;$scheme;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;proxy_redirect&amp;nbsp;off;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/p&gt;&lt;p&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;location&amp;nbsp;=&amp;nbsp;/nginx_status&amp;nbsp;{&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;check_status;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #99cefa;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;/p&gt;&lt;p&gt;}&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;upstream&lt;/span&gt; 부분에 &lt;span class=&quot;code-span code-b&quot;&gt;check&lt;/span&gt;로 시작하는 3줄과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;server { ..., &lt;span class=&quot;code-b&quot;&gt;location = /nginx_status {}&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;check interval=&lt;span class=&quot;code-b&quot;&gt;1000&lt;/span&gt; rise=&lt;span class=&quot;code-b&quot;&gt;1&lt;/span&gt; fall=&lt;span class=&quot;code-b&quot;&gt;4&lt;/span&gt; timeout=&lt;span class=&quot;code-b&quot;&gt;200&lt;/span&gt; type=&lt;span class=&quot;code-b&quot;&gt;http&lt;/span&gt;;&lt;/span&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;span class=&quot;code-span&quot;&gt;check_http_send &lt;span class=&quot;code-b&quot;&gt;&quot;HEAD /simple/healthcheck HTTP/1.0\r\n\r\n&quot;&lt;/span&gt;;&lt;/span&gt; 로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　체크 request method, api 주소 등을 지정할 수 있다. 예시에서는 &lt;span class=&quot;code-span&quot;&gt;HEAD&lt;/span&gt; 방식으로 &lt;span class=&quot;code-span&quot;&gt;http://nginx-spring-01:8091/simple/healthcheck&lt;/span&gt; 등으로 API Call로 응답을 확인할 것이다.&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 class=&quot;code-span&quot;&gt;check_http_expect_alive &lt;span class=&quot;code-b&quot;&gt;http_2xx http_3xx&lt;/span&gt;;&lt;/span&gt; 로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　성공 판단 요청의 http status code를 지정할 수 있다.&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;server 블록 중 아래 &lt;span class=&quot;code-span&quot;&gt;check_status;&lt;/span&gt; 부분은 listen 포트(예시에서는 8081)의 해당 경로(예시에서는 &lt;span class=&quot;code-span&quot;&gt;./nginx_status&lt;/span&gt;)로 접속하면 upstream 들의 상태를 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;healthcheck.png&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baKzGj/btrXLqGBr8V/I4TZ8XNRCuk1590KKzoYY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baKzGj/btrXLqGBr8V/I4TZ8XNRCuk1590KKzoYY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baKzGj/btrXLqGBr8V/I4TZ8XNRCuk1590KKzoYY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaKzGj%2FbtrXLqGBr8V%2FI4TZ8XNRCuk1590KKzoYY1%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;743&quot; height=&quot;307&quot; data-filename=&quot;healthcheck.png&quot; data-origin-width=&quot;743&quot; data-origin-height=&quot;307&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 data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/yaoweibin/nginx_upstream_check_module#readme&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/yaoweibin/nginx_upstream_check_module#readme&lt;/a&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;실행&quot; 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;nginx 서버 실행은 그냥 옵션 없이 실행하면 된다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;%&lt;/span&gt; /usr/local/nginx/sbin/nginx&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행하여 upstream 서버 중 일부를 끄고 켜보면서 확인해본다.&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;참고로 stop, reload 등은 &lt;span class=&quot;code-span&quot;&gt;-s&lt;/span&gt; 옵션으로 가능하다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;%&lt;/span&gt; /usr/local/nginx/sbin/nginx&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: dashed 1px gray;&quot;&gt; &lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;-s&lt;/span&gt; stop|reload|...&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/NGINX</category>
      <category>nginx</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/312</guid>
      <comments>https://ydeer.tistory.com/312#entry312comment</comments>
      <pubDate>Tue, 31 Jan 2023 22:42:13 +0900</pubDate>
    </item>
    <item>
      <title>Kafka 설정</title>
      <link>https://ydeer.tistory.com/311</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&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;a href=&quot;https://github.com/BlackdeerY/docker-kafka-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/BlackdeerY/docker-kafka-example&lt;/a&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;기본 openjdk 환경에 ZooKeeper, Kafka 쌩 파일에 설정 파일만으로 가동하고 테스트하는 예시를 두었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Docker Compose 사용)&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Kafka 공식 문서&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;a href=&quot;https://kafka.apache.org/documentation/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674642293335&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Apache Kafka&quot; data-og-description=&quot;Apache Kafka: A Distributed Streaming Platform.&quot; data-og-host=&quot;kafka.apache.org&quot; data-og-source-url=&quot;https://kafka.apache.org/documentation/&quot; data-og-url=&quot;https://kafka.apache.org/documentation/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/r59qA/hyRoB1Nupj/kLGj65LOHRB3s53Trrv9KK/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200&quot;&gt;&lt;a href=&quot;https://kafka.apache.org/documentation/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kafka.apache.org/documentation/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/r59qA/hyRoB1Nupj/kLGj65LOHRB3s53Trrv9KK/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Apache Kafka&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Apache Kafka: A Distributed Streaming Platform.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kafka.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Broker 설정 - server.properties&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 class=&quot;code-span&quot;&gt;auto.create.topics.enable&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;true&lt;/span&gt;이다. &lt;span class=&quot;code-span code-b&quot;&gt;false&lt;/span&gt;로 명시해주지 않으면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　　　　　해당 토픽으로 produce될 때 메시지를 거부하지 않고 자동으로 토픽을 생성한다.&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;a href=&quot;https://kafka.apache.org/documentation/#brokerconfigs_auto.create.topics.enable&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#brokerconfigs_auto.create.topics.enable&lt;/a&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 class=&quot;code-span&quot;&gt;num.partitions&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;1&lt;/span&gt;이다. 토픽 생성시 파티션 수를 지정하지 않았을 때 이 값으로 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#brokerconfigs_num.partitions&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#brokerconfigs_num.partitions&lt;/a&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 class=&quot;code-span&quot;&gt;default.replication.factor&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;1&lt;/span&gt;이다. 토픽 생성시 복제 수를 지정하지 않았을 때 이 값으로 생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#brokerconfigs_default.replication.factor&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#brokerconfigs_default.replication.factor&lt;/a&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 class=&quot;code-span&quot;&gt;log.cleaner.enable&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;true&lt;/span&gt;이다. 닫힌 세그먼트가 특정 시간이 경과하거나 특정 용량이 되었을 때 처리할지의 여부를 정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#brokerconfigs_log.cleaner.enable&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#brokerconfigs_log.cleaner.enable&lt;/a&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 class=&quot;code-span&quot;&gt;log.cleanup.policy&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;delete&lt;/span&gt;이다. { &lt;span class=&quot;code-span code-b&quot;&gt;compact&lt;/span&gt;, &lt;span class=&quot;code-span code-b&quot;&gt;delete&lt;/span&gt;&amp;nbsp;} 중에서 값을 선택하여 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　&lt;span class=&quot;code-span&quot;&gt;log.cleaner.enable=&lt;span class=&quot;code-span code-b&quot;&gt;true&lt;/span&gt;&lt;/span&gt;일 때 처리할 파일의 처리 방법을 결정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　&lt;span class=&quot;code-span code-b&quot;&gt;delete&lt;/span&gt;면 파일을 지우고, &lt;span class=&quot;code-span code-b&quot;&gt;compact&lt;/span&gt;면 파일을 압축한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#brokerconfigs_log.cleanup.policy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#brokerconfigs_log.cleanup.policy&lt;/a&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 class=&quot;code-span&quot;&gt;replica.lag.time.max.ms&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;30000&lt;/span&gt;(30초)이다. 0 이상의 long 값을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　　　　만약 Follower가 이 시간까지도 복제 요청을 보내지 않거나, 마지막 offset까지 가져가지 않는다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　　　　Leader는 Follower가 ISR 상태가 아니라고 판단한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#brokerconfigs_replica.lag.time.max.ms&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#brokerconfigs_replica.lag.time.max.ms&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Broker 설정 - 환경변수&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 class=&quot;code-span&quot;&gt;server.properties&lt;/span&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;span class=&quot;consolas&quot;&gt;KAFKA_BROKER_ID&lt;/span&gt; == &lt;span class=&quot;code-span&quot;&gt;broker.id&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;consolas&quot;&gt;KAFKA_ADVERTISED_LISTENERS&lt;/span&gt; == &lt;span class=&quot;code-span&quot;&gt;advertised.listeners&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;consolas&quot;&gt;KAFKA_ZOOKEEPER_CONNECT&lt;/span&gt; == &lt;span class=&quot;code-span&quot;&gt;zookeeper.connect&lt;/span&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;※ ZooKeepr의 &lt;span class=&quot;code-span&quot;&gt;myid&lt;/span&gt;나 &lt;span class=&quot;code-span&quot;&gt;zoo.cfg&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 class=&quot;consolas&quot;&gt;ZOOKEEPER_SERVER_ID&lt;/span&gt; == &lt;span class=&quot;code-span&quot;&gt;myid&lt;/span&gt;파일&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;consolas&quot;&gt;ZOOKEEPER_CLIENT_PORT&lt;/span&gt; == &lt;span class=&quot;code-span&quot;&gt;clientPort&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;consolas&quot;&gt;ZOOKEEPER_TICK_TIME&lt;/span&gt; == &lt;span class=&quot;code-span&quot;&gt;tickTime&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;consolas&quot;&gt;ZOOKEEPER_INIT_LIMIT&lt;/span&gt; == &lt;span class=&quot;code-span&quot;&gt;initLimit&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;consolas&quot;&gt;ZOOKEEPER_SYNC_LIMIT&lt;/span&gt; == &lt;span class=&quot;code-span&quot;&gt;syncLimit&lt;/span&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Producer 설정&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 class=&quot;code-span&quot;&gt;acks&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;all&lt;/span&gt;이다. { &lt;span class=&quot;code-span code-b&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;code-span code-b&quot;&gt;1&lt;/span&gt;, &lt;span class=&quot;code-span code-b&quot;&gt;all&lt;/span&gt; == &lt;span class=&quot;code-span code-b&quot;&gt;-1&lt;/span&gt;&amp;nbsp;} 중에서 값을 선택하여 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　&lt;span class=&quot;code-span code-b&quot;&gt;0&lt;/span&gt;이면 파티션에 제대로 전달되었는지 여부를 확인하지 않는다. 그러므로 &lt;span class=&quot;code-span&quot;&gt;retries&lt;/span&gt;로 설정한 실패시 재수행 횟수 역시 실패 여부를 알 수 없으니 수행하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　&lt;span class=&quot;code-span code-b&quot;&gt;1&lt;/span&gt;이면 파티션의 Leader에게만 기록되었는지를 확인한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　&lt;span class=&quot;code-span code-b&quot;&gt;all&lt;/span&gt;(== &lt;span class=&quot;code-span code-b&quot;&gt;-1&lt;/span&gt;)이면 파티션의 Leader 외에 Follower들까지 모두 복제하고 ISR이 형성되었는지 확인한다.&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;a href=&quot;https://kafka.apache.org/documentation/#producerconfigs_acks&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#producerconfigs_acks&lt;/a&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 class=&quot;code-span&quot;&gt;retries&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;2147483647&lt;/span&gt;이다. [ &lt;span class=&quot;code-span code-b&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;code-span code-b&quot;&gt;2147483647&lt;/span&gt;&amp;nbsp;] 범위의 값을 선택하여 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　acks 옵션이 0이 아니여서 전송 실패 여부를 알 수 있을 때, 실패시 메시지의 재전송 횟수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　횟수만큼 메시지를 다 보내기 전에 &lt;span class=&quot;code-span&quot;&gt;delivery.timeout.ms&lt;/span&gt; 시간이 경과하면 재전송을 중단한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　보통 이 값을 수정하기 보다는 &lt;span class=&quot;code-span&quot;&gt;delivery.timeout.ms&lt;/span&gt; 옵션을 조절하여 재전송을 제어하는 것을 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　(Users&amp;nbsp;should&amp;nbsp;generally&amp;nbsp;prefer&amp;nbsp;to&amp;nbsp;leave&amp;nbsp;this&amp;nbsp;config&amp;nbsp;unset&amp;nbsp;and&amp;nbsp;instead&amp;nbsp;use&amp;nbsp;&lt;span class=&quot;code-span&quot;&gt;delivery.timeout.ms&lt;/span&gt;&amp;nbsp;to&amp;nbsp;control&amp;nbsp;retry&amp;nbsp;behavior.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#producerconfigs_retries&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#producerconfigs_retries&lt;/a&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 class=&quot;code-span&quot;&gt;delivery.timeout.ms&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;120000&lt;/span&gt;(2분)이다. 0 이상의 int 값을 사용할 수 있다.&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;span class=&quot;code-span&quot;&gt;request.timeout.ms&lt;/span&gt; 와 &lt;span class=&quot;code-span&quot;&gt;linger.ms&lt;/span&gt; 의 합보다 이상이어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#producerconfigs_delivery.timeout.ms&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#producerconfigs_delivery.timeout.ms&lt;/a&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 class=&quot;code-span&quot;&gt;linger.ms&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;0&lt;/span&gt;이다. 0 이상의 long 값을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　Producer는&amp;nbsp;Broker로&amp;nbsp;request할&amp;nbsp;때,&amp;nbsp;생성한&amp;nbsp;레코드들을&amp;nbsp;그룹지어&amp;nbsp;단일&amp;nbsp;batch&amp;nbsp;request로&amp;nbsp;보낼&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　일반적으론&amp;nbsp;부하&amp;nbsp;상태(여러&amp;nbsp;레코드들마다&amp;nbsp;전송되는&amp;nbsp;것보다&amp;nbsp;한꺼번에&amp;nbsp;전송되는&amp;nbsp;것이&amp;nbsp;빠를&amp;nbsp;때)에만&amp;nbsp;일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　하지만&amp;nbsp;몇몇&amp;nbsp;상황에서는&amp;nbsp;적당한&amp;nbsp;부하이더라도&amp;nbsp;request&amp;nbsp;수를&amp;nbsp;줄이고자&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　이&amp;nbsp;설정은&amp;nbsp;작은&amp;nbsp;인위적인&amp;nbsp;지연을&amp;nbsp;발생시켜,&amp;nbsp;레코드들이&amp;nbsp;함께&amp;nbsp;묶여서&amp;nbsp;request될&amp;nbsp;수&amp;nbsp;있도록&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　이것은&amp;nbsp;TCP의&amp;nbsp;Nagle&amp;nbsp;알고리즘과&amp;nbsp;유사하다고&amp;nbsp;생각될&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　이&amp;nbsp;설정은&amp;nbsp;일괄처리(batch)에&amp;nbsp;대한&amp;nbsp;상한을&amp;nbsp;제공하는&amp;nbsp;것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　만약&amp;nbsp;레코드가&amp;nbsp;&lt;span class=&quot;code-span&quot;&gt;batch.size&lt;/span&gt;&amp;nbsp;이상이라면&amp;nbsp;이&amp;nbsp;설정과는&amp;nbsp;상관&amp;nbsp;없이&amp;nbsp;바로&amp;nbsp;보내겠지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　그&amp;nbsp;미만이라면&amp;nbsp;함께&amp;nbsp;보내기&amp;nbsp;위해&amp;nbsp;다른&amp;nbsp;레코드들이&amp;nbsp;발생하길&amp;nbsp;기다린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　기본값은&amp;nbsp;0이라&amp;nbsp;설정이&amp;nbsp;없으면&amp;nbsp;즉시&amp;nbsp;보낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　예를&amp;nbsp;들어&amp;nbsp;5ms로&amp;nbsp;설정하면,&amp;nbsp;부하가&amp;nbsp;없는&amp;nbsp;상황에서도&amp;nbsp;5ms의&amp;nbsp;지연을&amp;nbsp;추가하게&amp;nbsp;되지만&amp;nbsp;request&amp;nbsp;수는&amp;nbsp;줄이는&amp;nbsp;효과를&amp;nbsp;기대할&amp;nbsp;수&amp;nbsp;있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#producerconfigs_linger.ms&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#producerconfigs_linger.ms&lt;/a&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 class=&quot;code-span&quot;&gt;batch.size&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;16384&lt;/span&gt;(bytes)이다. 0 이상의 int 값을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　Producer는 여러 레코드를 함께 request하여 적은 수의 요청으로 많은 레코드를 처리하려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　이는 클라이언트와 서버 모두 성능에 도움이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　이 설정은 기본 batch의 bytes 크기를 제어한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　이 크기보다 큰 레코드는 함께 묶어서 처리하려고 하지 않고 즉시 보낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　Broker에 전송된 요청들에는 여러 batch가 있으며(Producer나 Topic이 하나는 아니니까),&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　각각은 파티션에 보낼 데이터를 갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　batch 크기가 작으면 개별적이고 한번에 처리할 양은 줄어든다(0이면 완전히 batch가 비활성화되어 개별 레코드로만).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　매우 큰 batch 크기는 많은 레코드들을 예상하여 그만큼의 버퍼를 할당해야하므로, 메모리를 좀 더 낭비할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#producerconfigs_batch.size&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#producerconfigs_batch.size&lt;/a&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 class=&quot;code-span&quot;&gt;request.timeout.ms&lt;/span&gt;:&amp;nbsp;기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;30000&lt;/span&gt;(30초)이다. 0 이상의 int 값을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　이 설정은 Producer가 Broker로 보낸 메시지의 응답을 기다리는 최대 시간이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　이 시간 안에 응답이 오지 않으면 Producer는 필요한 경우(&lt;span class=&quot;code-span&quot;&gt;retries&lt;/span&gt;가 설정된 경우) 요청을 다시 보내며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　&lt;span class=&quot;code-span&quot;&gt;retries&lt;/span&gt; 만큼 보냈거나, delivery.timeout.ms 만큼의 시간이 경과해버리면 최종 실패한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　&lt;span class=&quot;code-span&quot;&gt;acks=&lt;span class=&quot;code-b&quot;&gt;all&lt;/span&gt;&lt;/span&gt;(== &lt;span class=&quot;code-span code-b&quot;&gt;-1&lt;/span&gt;)이라 Broker가 ISR 형성까지한 후 응답을 보내는 경우도 있으니,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　불필요한 재시도와 중복 가능성을 줄이기 위해 Broker의 &lt;span class=&quot;code-span&quot;&gt;replica.lag.time.max.ms&lt;/span&gt; 보다 커야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#producerconfigs_request.timeout.ms&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#producerconfigs_request.timeout.ms&lt;/a&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Consumer 설정&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 class=&quot;code-span&quot;&gt;allow.auto.create.topics&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;true&lt;/span&gt;이다. boolean(true/false)을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　　　　브로커의 설정이 &lt;span class=&quot;code-span&quot;&gt;auto.create.topics.enable=&lt;span class=&quot;code-b&quot;&gt;true&lt;/span&gt;&lt;/span&gt;인 경우에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　　　　없는 토픽을 consume하려고 하면 해당 토픽을 자동으로 생성 요청한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　　　　버전 0.11.0 미만의 브로커를 사용한다면, consumer에서는 이 설정을 필히 false로 해두어야 해당 상황에서 안전하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#consumerconfigs_allow.auto.create.topics&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#consumerconfigs_allow.auto.create.topics&lt;/a&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 class=&quot;code-span&quot;&gt;auto.offset.reset&lt;/span&gt;: 기본값은 &lt;span class=&quot;code-span code-b&quot;&gt;latest&lt;/span&gt;이다. { &lt;span class=&quot;code-span code-b&quot;&gt;latest&lt;/span&gt;, &lt;span class=&quot;code-span code-b&quot;&gt;earliest&lt;/span&gt;, &lt;span class=&quot;code-span code-b&quot;&gt;none&lt;/span&gt; } 중에서 값을 선택하여 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　Consumer가 초기에 offest이 없거나 읽던 offset이 Broker에서 삭제된 경우,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　offset값을 어떻게 재구성할지에 대한 설정이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　&lt;span class=&quot;code-span code-b&quot;&gt;latest&lt;/span&gt;면 Topic Partition의 가장 최근(이제부터 발생하는)부터 가져오려고 하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　&lt;span class=&quot;code-span code-b&quot;&gt;earliest&lt;/span&gt;면 Topic Partition 중 Broker에 존재하는(아직 열려있는) 데이터 중 가장 오래된 것부터 가져오기 시작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　&lt;span class=&quot;code-span code-b&quot;&gt;none&lt;/span&gt;이면 Consumer에서 exception이 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　&lt;a href=&quot;https://kafka.apache.org/documentation/#consumerconfigs_auto.offset.reset&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/#consumerconfigs_auto.offset.reset&lt;/a&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>Study/Kafka</category>
      <category>Kafka</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/311</guid>
      <comments>https://ydeer.tistory.com/311#entry311comment</comments>
      <pubDate>Wed, 25 Jan 2023 19:23:24 +0900</pubDate>
    </item>
    <item>
      <title>Kafka 기본 개념 및 용어</title>
      <link>https://ydeer.tistory.com/310</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Kafka의 정말 기본 개념&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Kafka.png&quot; data-origin-width=&quot;205&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xxdJ8/btrWCpDL6ZO/aLu7MRGK7tSJjThgKCsYO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xxdJ8/btrWCpDL6ZO/aLu7MRGK7tSJjThgKCsYO1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xxdJ8/btrWCpDL6ZO/aLu7MRGK7tSJjThgKCsYO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxxdJ8%2FbtrWCpDL6ZO%2FaLu7MRGK7tSJjThgKCsYO1%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;205&quot; height=&quot;93&quot; data-filename=&quot;Kafka.png&quot; data-origin-width=&quot;205&quot; data-origin-height=&quot;93&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kafka는 데이터 처리를 위한 플랫폼이다.&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;div class=&quot;flex&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;570&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nKtkI/btrWCGZqbK6/K4V2Bs4HKrJ4Gz9rUZvgZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nKtkI/btrWCGZqbK6/K4V2Bs4HKrJ4Gz9rUZvgZk/img.png&quot; data-alt=&quot;출처:　https://www.confluent.io/blog/event-streaming-platform-1/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nKtkI/btrWCGZqbK6/K4V2Bs4HKrJ4Gz9rUZvgZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnKtkI%2FbtrWCGZqbK6%2FK4V2Bs4HKrJ4Gz9rUZvgZk%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;570&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;570&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처:　https://www.confluent.io/blog/event-streaming-platform-1/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FB4Ql/btrWGemPUGt/7CegkqKxlJbMq8IP7o0gO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FB4Ql/btrWGemPUGt/7CegkqKxlJbMq8IP7o0gO0/img.png&quot; data-alt=&quot;출처:　https://www.confluent.io/blog/event-streaming-platform-2/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FB4Ql/btrWGemPUGt/7CegkqKxlJbMq8IP7o0gO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFB4Ql%2FbtrWGemPUGt%2F7CegkqKxlJbMq8IP7o0gO0%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;260&quot; height=&quot;258&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처:　https://www.confluent.io/blog/event-streaming-platform-2/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kafka는 느슨하게 결합되어 있기에,&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;div class=&quot;flex&quot;&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ccbdf/btrWHoCQGeV/Ff6QFeJcqQjG0Lv8Z17ub0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ccbdf/btrWHoCQGeV/Ff6QFeJcqQjG0Lv8Z17ub0/img.png&quot; data-alt=&quot;출처:　https://www.confluent.io/blog/event-streaming-platform-1/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ccbdf/btrWHoCQGeV/Ff6QFeJcqQjG0Lv8Z17ub0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCcbdf%2FbtrWHoCQGeV%2FFf6QFeJcqQjG0Lv8Z17ub0%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;456&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;778&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처:　https://www.confluent.io/blog/event-streaming-platform-1/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E8aWj/btrWCdQ7g1h/yk3kIZpsFKCIJiqDKkhXNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E8aWj/btrWCdQ7g1h/yk3kIZpsFKCIJiqDKkhXNK/img.png&quot; data-alt=&quot;출처:　https://www.confluent.io/blog/event-streaming-platform-2/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E8aWj/btrWCdQ7g1h/yk3kIZpsFKCIJiqDKkhXNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE8aWj%2FbtrWCdQ7g1h%2Fyk3kIZpsFKCIJiqDKkhXNK%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;260&quot; height=&quot;280&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처:　https://www.confluent.io/blog/event-streaming-platform-2/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Kafka는 이벤트 브로커 (※ 이 부분은 하나의 견해인지 잘 모르겠다. 나도 이 모두를 사용해본 것이 아니라...)&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;Redis, MQTT가 메시지 브로커라면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kafka, AWS Kinesis는 이벤트 브로커이다.&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;이벤트 브로커는 당장의 메시지 전달 뿐 아니라, 지난 메시지 역시 그로 인한 이벤트 발생이든 재처리든 할 수 있다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ZooKeeper는 또 뭐야??&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ZooKeeper.png&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;162&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tqBe3/btrWCVaXmsj/a55WzLGG9K9SVxg5T01a61/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tqBe3/btrWCVaXmsj/a55WzLGG9K9SVxg5T01a61/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tqBe3/btrWCVaXmsj/a55WzLGG9K9SVxg5T01a61/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtqBe3%2FbtrWCVaXmsj%2Fa55WzLGG9K9SVxg5T01a61%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;300&quot; height=&quot;162&quot; data-filename=&quot;ZooKeeper.png&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;162&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;apache Kafka는 apache ZooKeeper와 연동하여 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 의존성을 향후에는 없애겠다고 했으나, 현재에는 그렇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Kafka 3.3에서는 ZooKeeper 없이 Kafka 독자적으로 가능하도록 KRaft를 옵션으로 탑재하고 있으며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;향후 4에서는 제거할 계획이라고 한다.)&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;ZooKeeper는 &lt;b&gt;분산 애플리케이션을 관리하는 코디네이터&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;Kafka만을 위한 것이 아니라&lt;/u&gt; 그보다 먼저 존재해왔던 프로젝트로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빅데이터 생태계에 동물형 심볼을 갖는 애플리케이션들이 많고, 이들의 사육사(ZooKeeper)격으로 만들어졌다.&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;ZooKeeper는 Kafka 브로커들(서버들)의 메타 데이터를 관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kafka는 멀티 브로커가 가능하며, 브로커 ID, 컨트롤러 ID 등의 데이터를 ZooKeeper가 관리해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지의 저장은 Kafka 내부에 적재된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZooKeeper는 Kafka 서버들의 정보를 관리하는 것이고, 둘을 혼동하면 곤란하다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그래도 ZooKeeper에 대해 간단히..&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1107&quot; data-origin-height=&quot;709&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7XnHO/btrWCIiDSPe/cZTwUmrKm5cM7BN4S433O0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7XnHO/btrWCIiDSPe/cZTwUmrKm5cM7BN4S433O0/img.png&quot; data-alt=&quot;출처:&amp;amp;amp;nbsp;https://hadooptechblog.wordpress.com/2015/12/29/introduction-to-apache-zookeeper/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7XnHO/btrWCIiDSPe/cZTwUmrKm5cM7BN4S433O0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7XnHO%2FbtrWCIiDSPe%2FcZTwUmrKm5cM7BN4S433O0%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;709&quot; data-origin-width=&quot;1107&quot; data-origin-height=&quot;709&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처:&amp;amp;nbsp;https://hadooptechblog.wordpress.com/2015/12/29/introduction-to-apache-zookeeper/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZooKeeper 역시 단일로 실행되기보다는 스스로도 멀티 클러스터 환경으로 구성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 여러 클러스터들이 앙상블(Ensemble)을 이룬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정에서 (묶인 클러스터들의 총 갯수) / 2 + 1 이 서로 통신이 되고 있어야 ZooKeeper를 이용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분산 시스템에서 이러한 최소 필요 수를 쿼럼(Quorum)이라고 한다.&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/2181 로 다른 애플리케이션(ex. Kafka. 주키퍼 입장에선 클라이언트.)이 ZooKeeper를 이용하며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tcp/2888 로 ZooKeeper의 클러스터들끼리 동기화를 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tcp/3888 은 ZooKeeper의 클러스터들끼리의 leader/follower 선출에 사용한다.&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;ZooKeeper끼리는 설정으로 서로의 주소와 포트를 알고 있어야하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZooKeeper를 이용하는 애플리케이션들(ex. Kafka. 주키퍼 입장에선 클라이언트.)은 서로를 알 필요 없이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZooKeeper가 분산된 애플리케이션들을 연결시켜주며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션은 설정에서 ZooKeeper 하나만 알아도 ZooKeeper들은 메타 데이터들을 스스로 동기화를 하는 점이 장점이다.&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;ZooKeeper와 애플리케이션이 같은 머신에서 돌 수 없는 것은 아니나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ZooKeeper는 메모리에서 데이터들을 처리하고 있으므로,&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Kafka 용어&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;※ Pub/Sub, Broker, Topic 등 메시지 브로커의 기본 공통 개념은 생략&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;※ 데이터의 저장: 데이터는 Kafka를 실행하는 머신의 설정한 디렉터리에 bytes 형태의 파일로 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　그러므로 producer&amp;rarr;Kafka 에는 직렬화, Kafka&amp;rarr;consumer 에는 역직렬화가 수행된다.&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;ㆍSegment 파일: bytes들은 파일들(&lt;span class=&quot;code-span&quot;&gt;00000000000000000000&lt;span class=&quot;code-b&quot;&gt;.index&lt;/span&gt;, 00000000000000000000&lt;span class=&quot;code-b&quot;&gt;.log&lt;/span&gt;, 00000000000000000000&lt;span class=&quot;code-b&quot;&gt;.timeindex&lt;/span&gt;&lt;/span&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;ㆍController(컨트롤러): 멀티 브로커 환경에서, 브로커 1대는 컨트롤러 기능을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　컨트롤러는 각 브로커들에게 담당 파티션을 할당하며, 브로커들이 정상 동작하는지 모니터링 및 관리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　누가 컨트롤러인지는 메타 데이터이므로, ZooKeeper에 저장된다.&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;ㆍOffset(오프셋): 토픽으로 들어온 메시지는 순서대로 오프셋이 매겨진다.&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;ㆍPartition(파티션): 한 토픽은 여러 파티션으로 나뉠 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　파티션의 수는 브로커의 수에 제한받지 않는다(하나의 브로커가 여러 파티션을 가질 수 있다. &lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;img_partition&quot;&gt;섹션 맨 아래 무지개색 이미지&lt;/span&gt; 참고.).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　Producer의 Partitioner에 따라 레코드들이 분배되는데, 기본으로는 UniformStickyPartitioner를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　UniformStickyPartitioner는 레코드에 Key를 주어, Key-Value 쌍의 형태를 사용하면 Key로 Hash 계산을 하여 파티션에 분배하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　Key가 null이면 Round-Robbin으로 레코드들을 파티션들에 분배한다.&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;ㆍConsumer Group: 컨슈머 그룹은 한 토픽으로부터 데이터를 가져온다.&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;ㆍConsumer: 컨슈머는 자신이 속한 그룹이 가져올 토픽에 대하여, 그 토픽의 파티션으로부터 데이터를 가져온다.&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;ㆍRebalance(리밸런스): 컨슈머 그룹 내부의 특정 컨슈머에 장애가 발생하면, 컨슈머들은 담당 파티션들을 다시 조정한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_consumer-groups.png&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;588&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RNfSN/btrXarfGjg3/K7WbHkIJ4E2xET2HovcdUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RNfSN/btrXarfGjg3/K7WbHkIJ4E2xET2HovcdUk/img.png&quot; data-alt=&quot;출처:　https://ibm-cloud-architecture.github.io/refarch-eda/technology/kafka-consumers/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RNfSN/btrXarfGjg3/K7WbHkIJ4E2xET2HovcdUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRNfSN%2FbtrXarfGjg3%2FK7WbHkIJ4E2xET2HovcdUk%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;343&quot; data-filename=&quot;edited_consumer-groups.png&quot; data-origin-width=&quot;1201&quot; data-origin-height=&quot;588&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처:　https://ibm-cloud-architecture.github.io/refarch-eda/technology/kafka-consumers/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍReplication(복제): 토픽의 파티션은 안전을 위해 다른 브로커들에게 복제되도록 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　복제 수는 최대로는 브로커의 수만큼이 되도록 설정할 수 있다(그 넘어서는 브로커가 더 없으니 할 수 없는 것.. &lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;img_partition&quot;&gt;바로 아래 이미지&lt;/span&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;　　　　　　　　　leader 파티션은 Kafka 클라이언트(프로듀서, 컨슈머)와 데이터를 주고 받으며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　follower 파티션은 leader 파티션으로부터 레코드를 지속 복제한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　만약 leader 파티션에 장애가 발생하면, 나머지 follower들끼리 새로 leader를 선출한다.&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;ㆍISR(In-Sync Replica): 특정 파티션의 leader, follower에서 레코드가 모두 복제되어 동기화(sync)가 맞는 상태.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　만약 ISR이 아닌 상태에서 장애가 발생했다면, &lt;span class=&quot;code-span&quot;&gt;unclean.leader.election.enable=&lt;/span&gt; 설정에 따라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　&lt;span class=&quot;code-span code-b&quot;&gt;true&lt;/span&gt;면 sync 상관 없이 바로 follower들 중에 새로 leader를 선출하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　　　　　　　　　&lt;span class=&quot;code-span code-b&quot;&gt;false&lt;/span&gt;면 leader가 살아날 때까지 대기한다. 즉, 그동안은 해당 파티션은 사용불가가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: gray;&quot;&gt;%&lt;/span&gt; kafka-topics.sh&amp;nbsp; &amp;nbsp;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;--describe&lt;/span&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: 1px dashed gray;&quot;&gt; --bootstrap-server kafka-01:9092,kafka-03:9092 &lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;Topic:&amp;nbsp;mytest&amp;nbsp;&amp;nbsp;&amp;nbsp;TopicId:&amp;nbsp;H0tGCsUcQDOFqD_-8C9bEQ&amp;nbsp;PartitionCount:&amp;nbsp;7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ReplicationFactor:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Configs:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest&amp;nbsp;&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;1&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest&amp;nbsp;&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;0&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest&amp;nbsp;&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;2&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest&amp;nbsp;&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;1&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest&amp;nbsp;&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;0&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest&amp;nbsp;&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;2&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest&amp;nbsp;&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;6&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;1&lt;/p&gt;&lt;p&gt;Topic:&amp;nbsp;mytest3&amp;nbsp;&amp;nbsp;TopicId:&amp;nbsp;7krfA2U1SjmmZKUWZFEW_w&amp;nbsp;PartitionCount:&amp;nbsp;7&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ReplicationFactor:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Configs:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest3&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;2,1&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;2,1&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest3&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;1,0&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;1,0&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest3&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;0,2&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;0,2&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest3&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;3&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;2,0&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;2,0&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest3&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;4&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;1&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;1,2&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;1,2&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest3&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;5&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;0&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;0,1&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;0,1&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Topic:&amp;nbsp;mytest3&amp;nbsp;&amp;nbsp;Partition:&amp;nbsp;6&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Leader:&amp;nbsp;2&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Replicas:&amp;nbsp;2,1&amp;nbsp;&amp;nbsp;&amp;nbsp;Isr:&amp;nbsp;2,1&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div id=&quot;img_partition&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;kafka.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blkT7l/btrW56qhQiD/I1hyLmVvnvaKzvIC3TfDk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blkT7l/btrW56qhQiD/I1hyLmVvnvaKzvIC3TfDk1/img.png&quot; data-alt=&quot;위 조회 중 mytest3 기준으로 작성한 이미지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blkT7l/btrW56qhQiD/I1hyLmVvnvaKzvIC3TfDk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblkT7l%2FbtrW56qhQiD%2FI1hyLmVvnvaKzvIC3TfDk1%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;1280&quot; height=&quot;720&quot; data-filename=&quot;kafka.png&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;위 조회 중 mytest3 기준으로 작성한 이미지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div id=&quot;img_dir&quot;&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;kafka-dir.png&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KPL7A/btrW4E1cyce/FMoKYKBiAKTKnFb4OXmF51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KPL7A/btrW4E1cyce/FMoKYKBiAKTKnFb4OXmF51/img.png&quot; data-alt=&quot;각각 kafka 머신의 디렉터리 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KPL7A/btrW4E1cyce/FMoKYKBiAKTKnFb4OXmF51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKPL7A%2FbtrW4E1cyce%2FFMoKYKBiAKTKnFb4OXmF51%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;672&quot; height=&quot;280&quot; data-filename=&quot;kafka-dir.png&quot; data-origin-width=&quot;672&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;각각 kafka 머신의 디렉터리 상태&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&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;a href=&quot;https://github.com/BlackdeerY/docker-kafka-example&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/BlackdeerY/docker-kafka-example&lt;/a&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;기본 openjdk 환경에 ZooKeeper, Kafka 쌩 파일에 설정 파일만으로 가동하고 테스트하는 예시를 두었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Docker Compose 사용)&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Kafka 공식 문서&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;a href=&quot;https://kafka.apache.org/documentation/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kafka.apache.org/documentation/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1674642293335&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Apache Kafka&quot; data-og-description=&quot;Apache Kafka: A Distributed Streaming Platform.&quot; data-og-host=&quot;kafka.apache.org&quot; data-og-source-url=&quot;https://kafka.apache.org/documentation/&quot; data-og-url=&quot;https://kafka.apache.org/documentation/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/r59qA/hyRoB1Nupj/kLGj65LOHRB3s53Trrv9KK/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200&quot;&gt;&lt;a href=&quot;https://kafka.apache.org/documentation/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kafka.apache.org/documentation/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/r59qA/hyRoB1Nupj/kLGj65LOHRB3s53Trrv9KK/img.png?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Apache Kafka&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Apache Kafka: A Distributed Streaming Platform.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kafka.apache.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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>Study/Kafka</category>
      <category>Kafka</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/310</guid>
      <comments>https://ydeer.tistory.com/310#entry310comment</comments>
      <pubDate>Wed, 18 Jan 2023 10:38:12 +0900</pubDate>
    </item>
    <item>
      <title>Docker Compose 사용 (docker-compose.yml)</title>
      <link>https://ydeer.tistory.com/309</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;처음 Docker를 배우는 사람들은 막막할 수도 있다.&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;a href=&quot;https://ydeer.tistory.com/308&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[Study/Docker] - Dockerfile 작성 (Dockerfile로 배포)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 Dockerfile 작성에서는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브러리의 이미지에서 컨테이너를 생성하여 가상 OS를 사용하는 작업을 넘어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이미지에서 원하는 작업을 하도록 짠 Dockerfile을 통해&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;그러기 위해 docker run 명령을 수행했다. 필요에 따라 옵션을 주었고.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;docker build&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;--no-cache&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;-t 생성될이미지명:태그&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;Dockerfile경로&lt;/p&gt;&lt;p&gt;docker image prune&amp;nbsp; &lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;--filter&lt;/span&gt;&amp;nbsp; label=stage=forbuild&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;docker run&amp;nbsp; &amp;nbsp;-d&amp;nbsp; &amp;nbsp;-it&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;-p 28090:8090&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;--name 생성될컨테이너명&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;생성한이미지명&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이 run도 원하는 옵션을 미리 짜두고 자동화할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분이 Docker Compose이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Compose가 단순히 실행 부분만을 맡는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;여러 컨테이너들을 순서에 맞게 실행시키고, 각 컨테이너들을 이어주고 통합적으로 실행되도록 하는 것&lt;/b&gt;이 Docker Compose다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 컴퓨터에서 여러 프로그램들을 돌리기도 하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 컴퓨터마다 프로그램들이 돌아가는(DB 따로, 메시징서버 따로, ...) 상황도 많지 않나.&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;이런 Container Orchestration에는 Docker Compose 외에도 Kubernetes[쿠버네티스]라는 프레임워크도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Compose가 docker를 설치한 &lt;b&gt;하나의 Host&lt;/b&gt;에서 돌아가는 여러 컨테이너들을 관리한다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubernetes는 여러 머신들이 갖는 컨테이너들을 관리한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/What-is-Kubernetes-vs-Docker-Compose-How-these-DevOps-tools-compare&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/What-is-Kubernetes-vs-Docker-Compose-How-these-DevOps-tools-compare&lt;/a&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker-compose.yml&lt;/p&gt;
&lt;pre id=&quot;code_1672798172813&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;services:
  myproject:
    build:
      context: .
      no_cache: true
      # tags:
        # - &quot;myprojectimagedouble&quot;
        # - &quot;myprojectimagetriple:v.1.0.0&quot;
    image: myprojectimage
    ports:
      - &quot;28090:8090&quot;
    container_name: myprojectcontainer
  git:
    image: bitnami/git:latest
    depends_on:
      - myproject
    container_name: mygitcontainer
    volumes:
      - &quot;./restdocs:/restdocs&quot;
    command: git clone https://github.com/BlackdeerY/restdocs-maven.git restdocs&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시에는 v2부터 동작하는 옵션들도 다수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v2부터는 기본적으로 buildkit을 사용하니, 중간 이미지들은 남지 않고, 실행에 필요한 이미지만 남게 된다.&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;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;docker compose up -d&lt;/p&gt;&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;
&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;yml에 지정가능한 사항들을 모두 다룰 생각으로 적은 글이 아니어서, 해당 사항은 아래의 공식문서를 참고.&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;Docker Desktop 환경&lt;/b&gt;에서 &lt;span style=&quot;color: #ee2323;&quot; class=&quot;code-span&quot;&gt;ERROR [internal] load metadata for docker.io/library/...&lt;/span&gt; 에러를 낸다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;code-span&quot;&gt;~/.docker/config.json&lt;/span&gt;에서 &lt;span class=&quot;code-span&quot;&gt;&quot;credStore&quot;: &quot;desktop&quot;,&lt;/span&gt; 부분을 &lt;span class=&quot;code-span&quot;&gt;&quot;credStore&quot;: &quot;&quot;,&lt;/span&gt;로 수정하고 &lt;b&gt;Docker Desktop을 재시작&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;※ build &amp;gt; tags 옵션으로 결과 이미지의 복제본들을 둘 수 있다. IMAGE ID는 같으나 다른 이름으로 다수 존재하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　용량이 함께 늘어나는 것은 아니고, 원본은 IMAGE ID이고, 다른 이름과 태그는 모두 심볼릭링크로 이해하면 좋다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker Compose 공식문서는 아래&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.docker.com/compose/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.docker.com/compose/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1672798329467&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Overview&quot; data-og-description=&quot; &quot; data-og-host=&quot;docs.docker.com&quot; data-og-source-url=&quot;https://docs.docker.com/compose/&quot; data-og-url=&quot;https://docs.docker.com/compose/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cO3Lhh/hyQ8ZCm6ph/IPxqvnKr5WrbLler1HyPjK/img.png?width=129&amp;amp;height=128&amp;amp;face=0_0_129_128,https://scrap.kakaocdn.net/dn/dhgiwX/hyRax5iUDs/MUmSKOJVtxHSrOL3b3xk81/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500&quot;&gt;&lt;a href=&quot;https://docs.docker.com/compose/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.docker.com/compose/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cO3Lhh/hyQ8ZCm6ph/IPxqvnKr5WrbLler1HyPjK/img.png?width=129&amp;amp;height=128&amp;amp;face=0_0_129_128,https://scrap.kakaocdn.net/dn/dhgiwX/hyRax5iUDs/MUmSKOJVtxHSrOL3b3xk81/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.docker.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.docker.com/compose/compose-file/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.docker.com/compose/compose-file/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1672798339069&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Compose specification&quot; data-og-description=&quot; &quot; data-og-host=&quot;docs.docker.com&quot; data-og-source-url=&quot;https://docs.docker.com/compose/compose-file/&quot; data-og-url=&quot;https://docs.docker.com/compose/compose-file/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/AGq1A/hyQ8ZvArDw/AAHbfQ7j7B48hIBqGUiEN0/img.png?width=129&amp;amp;height=128&amp;amp;face=0_0_129_128,https://scrap.kakaocdn.net/dn/6Tk3R/hyRaGHWNhL/FhJIab4ouGpcfGS6NbOCok/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500&quot;&gt;&lt;a href=&quot;https://docs.docker.com/compose/compose-file/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.docker.com/compose/compose-file/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/AGq1A/hyQ8ZvArDw/AAHbfQ7j7B48hIBqGUiEN0/img.png?width=129&amp;amp;height=128&amp;amp;face=0_0_129_128,https://scrap.kakaocdn.net/dn/6Tk3R/hyRaGHWNhL/FhJIab4ouGpcfGS6NbOCok/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Compose specification&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.docker.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.docker.com/build/bake/compose-file/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.docker.com/build/bake/compose-file/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1672879462489&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Building from Compose file&quot; data-og-description=&quot; &quot; data-og-host=&quot;docs.docker.com&quot; data-og-source-url=&quot;https://docs.docker.com/build/bake/compose-file/&quot; data-og-url=&quot;https://docs.docker.com/build/bake/compose-file/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/baZl0U/hyQ8RSpxTS/8wI8dMpDKbEV6lqfKT9Ry0/img.png?width=129&amp;amp;height=128&amp;amp;face=0_0_129_128,https://scrap.kakaocdn.net/dn/bHx439/hyQ8SqcYO8/E8XdbZCwUuziKCjfnhb7O0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500&quot;&gt;&lt;a href=&quot;https://docs.docker.com/build/bake/compose-file/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.docker.com/build/bake/compose-file/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/baZl0U/hyQ8RSpxTS/8wI8dMpDKbEV6lqfKT9Ry0/img.png?width=129&amp;amp;height=128&amp;amp;face=0_0_129_128,https://scrap.kakaocdn.net/dn/bHx439/hyQ8SqcYO8/E8XdbZCwUuziKCjfnhb7O0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Building from Compose file&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.docker.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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>Study/Docker</category>
      <category>Docker</category>
      <category>docker-compose</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/309</guid>
      <comments>https://ydeer.tistory.com/309#entry309comment</comments>
      <pubDate>Wed, 4 Jan 2023 10:22:10 +0900</pubDate>
    </item>
    <item>
      <title>Dockerfile 작성 (Dockerfile로 배포)</title>
      <link>https://ydeer.tistory.com/308</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Docker의 계층(Layer)형 구조와 가상화에 대한 이론 내용을 깨우쳤다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Docker를 제대로 응용할 차례다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 본 Docker의 명령어들은 라이브러리에서 원하는 이미지를 내려받고, 실행해보는 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Dockerfile을 작성함으로써, 내가 원하는 레이어들을 쌓은 최종이미지를 빌드하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker로 프로젝트를 배포하는 예제를 볼 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Dockerfile 작성(이미지 빌드)이 왜 프로젝트 배포로 이어지는 것인지는 &lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;ex02&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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 class=&quot;btn-mv&quot; data-ke-size=&quot;size16&quot; data-ke-mvto=&quot;ex01&quot;&gt;[첫 번째 예시]&lt;/p&gt;
&lt;table class=&quot;descTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;1. 이미 빌드된 파일을 바로 구동환경에서 실행&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구동환경에 맞는 빌드된 파일을 준비해놨으니, 빌드과정이 없어 시간이 대폭 줄어든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 해당 파일을 Dockerfile과 함께 제공할 수 있어야한다.&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 class=&quot;btn-mv&quot; data-ke-size=&quot;size16&quot; data-ke-mvto=&quot;ex02&quot;&gt;[두 번째 예시]&lt;/p&gt;
&lt;table class=&quot;descTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;1. git으로 공개 프로젝트를 내려받고&lt;/p&gt;&lt;p&gt;2. 빌드이미지에서 빌드하고&lt;/p&gt;&lt;p&gt;3. 빌드한 파일을 구동환경에서 실행&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 단계마다 다른 이미지에서 작업을 수행하도록 할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1단계에서는 내려받는 것만을,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2단계에서는 빌드만을,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3단계에서는 실행만을 담당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종이미지는 3단계만 가지면 되므로, 1과 2의 내용은 최종 구동환경에 포함되지 않으니 용량을 줄일 수 있다.&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 class=&quot;btn-mv&quot; data-ke-size=&quot;size16&quot; data-ke-mvto=&quot;ex03&quot;&gt;[세 번째 예시]&lt;/p&gt;
&lt;table class=&quot;descTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;1. 하나의 최종 구동환경 이미지에서 wget, unzip, git, gradle을 설치(리눅스 yum, apt-get 등)&lt;/p&gt;&lt;p&gt;2. wget, unzip 등으로 yum 및 apt-get에 없는 프로그램들을 설치&lt;/p&gt;&lt;p&gt;3. 환경변수 설정&lt;/p&gt;&lt;p&gt;4. 프로젝트를 내려받고&lt;/p&gt;&lt;p&gt;5. 빌드하고&lt;/p&gt;&lt;p&gt;6. 실행&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 한 번 하고 버리면 될 내려받기나 빌드한 후에도 남는 빌드 프로그램들이 최종 이미지에 포함되므로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;용량이 쓸데없이 커진다.&lt;/b&gt;&lt;/span&gt; 그렇지만 내가 필요한 프로그램이 공개된 이미지에 없을 수 있으니, &lt;b&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;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;ex01&quot; data-ke-size=&quot;size16&quot;&gt;[첫 번째 예시]&lt;/p&gt;
&lt;table class=&quot;descTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;1. 이미 빌드된 파일을 바로 구동환경에서 실행&lt;/p&gt;&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;
&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;Dockerfile&lt;/p&gt;
&lt;pre id=&quot;code_1672738291675&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM amazoncorretto:8u352
LABEL stage=forbuild
COPY ./myproject.war /myproject
WORKDIR /myproject
EXPOSE 8090
ENTRYPOINT [ &quot;java&quot;, &quot;-jar&quot;, &quot;/myproject/myproject.war&quot; ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker 명령&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;docker build&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;--no-cache&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;-t 생성될이미지명:태그&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;Dockerfile경로&lt;/p&gt;&lt;p&gt;docker image prune&amp;nbsp; &lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;--filter&lt;/span&gt;&amp;nbsp; label=stage=forbuild&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;docker run&amp;nbsp; &amp;nbsp;-d&amp;nbsp; &amp;nbsp;-it&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;-p 28090:8090 &lt;/span&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;--name 생성될컨테이너명&amp;nbsp; &lt;/span&gt;&amp;nbsp; 생성한이미지명&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ docker build할 때에 줄마다 레이어 및 캐시를 형성하는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　같은 Dockerfile을 또 build할 때에, 명령줄만 비교하고 그 내용이 가리키는 파일까지는 비교해주진 않으니,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　(로컬 파일이든 wget이나 curl이든 git이든...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　필요에 따라 캐시 사용을 하지 않도록 함 (&lt;span class=&quot;code-span&quot;&gt;--no-cache&lt;/span&gt; 옵션).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;※ 만약 &lt;b&gt;Docker Desktop 환경&lt;/b&gt;에서 &lt;span style=&quot;color: #ee2323;&quot; class=&quot;code-span&quot;&gt;ERROR [internal] load metadata for docker.io/library/...&lt;/span&gt; 에러를 낸다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;code-span&quot;&gt;~/.docker/config.json&lt;/span&gt;에서 &lt;span class=&quot;code-span&quot;&gt;&quot;credStore&quot;: &quot;desktop&quot;,&lt;/span&gt; 부분을 &lt;span class=&quot;code-span&quot;&gt;&quot;credStore&quot;: &quot;&quot;,&lt;/span&gt;로 수정하고 &lt;b&gt;Docker Desktop을 재시작&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;FROM 이후 한 줄 마다 레이어로 중간 이미지(intermediate image)가 생성된 채 남게 되는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부여했던 LABEL를 필터(&lt;span class=&quot;code-span&quot;&gt;--filter&lt;/span&gt; 옵션)로 사용하여 &lt;span class=&quot;code-span&quot;&gt;docker image prune&lt;/span&gt; 명령어로 중간 이미지들을 모두 삭제해줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;buildkit을 사용한다면&lt;/b&gt; FROM 이미지든 중간 이미지든 모두 캐시로 관리하고 이미지로 남기지 않으므로,&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시의 Dockerfile의 명령어들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;FROM&lt;/span&gt;&amp;nbsp; &amp;nbsp;작업할_이미지&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;LABEL&lt;/span&gt;&amp;nbsp; &amp;nbsp;라벨명&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;COPY&lt;/span&gt;&amp;nbsp; &amp;nbsp;source&amp;nbsp; &amp;nbsp;destination&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;WORKDIR&lt;/span&gt;&amp;nbsp; &amp;nbsp;이미지에서_cd될_곳&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;EXPOSE&lt;/span&gt;&amp;nbsp; &amp;nbsp;외부로_노출될_포트&lt;/span&gt;: -P 옵션으로 컨테이너를 생성하면 해당 포트는 무작위로 배정됨.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;ENTRYPOINT&lt;/span&gt;&amp;nbsp; &amp;nbsp;생성된_컨테이너에서_실행될_명령&lt;/span&gt;: CMD와는 달리, 컨테이너 생성시 명령을 지정하더라도 이 명령이 실행됨.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;ex02&quot; data-ke-size=&quot;size16&quot;&gt;[두 번째 예시]&lt;/p&gt;
&lt;table class=&quot;descTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;1. git으로 공개 프로젝트를 내려받고&lt;/p&gt;&lt;p&gt;2. 빌드이미지에서 빌드하고&lt;/p&gt;&lt;p&gt;3. 빌드한 파일을 구동환경에서 실행&lt;/p&gt;&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;
&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;Dockerfile&lt;/p&gt;
&lt;pre id=&quot;code_1672747363988&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM bitnami/git:latest
LABEL stage=forbuild
RUN [ &quot;git&quot;, &quot;clone&quot;, &quot;https://github.com/BlackdeerY/restdocs-maven.git&quot;, &quot;myproject&quot; ]

FROM maven:3.8.7-openjdk-18
LABEL stage=forbuild
COPY --from=0 /myproject /myproject
WORKDIR /myproject
RUN [ &quot;mvn&quot;, &quot;package&quot; ]

FROM amazoncorretto:8u352
LABEL stage=forbuild
COPY --from=1 /myproject/target/restdocs-maven-0.0.1-SNAPSHOT.war /myproject/myproject.war
WORKDIR /myproject
EXPOSE 8090
ENTRYPOINT [ &quot;java&quot;, &quot;-jar&quot;, &quot;/myproject/myproject.war&quot; ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker 명령&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;docker build&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;--no-cache&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;-t 생성될이미지명:태그&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;Dockerfile경로&lt;/p&gt;&lt;p&gt;docker image prune&amp;nbsp; &lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;--filter&lt;/span&gt;&amp;nbsp; label=stage=forbuild&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;docker run&amp;nbsp; &amp;nbsp;-d&amp;nbsp; &amp;nbsp;-it&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;-p 28090:8090&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;--name 생성될컨테이너명&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;생성한이미지명&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시의 추가된 Dockerfile의 명령어들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;COPY&lt;/span&gt;&amp;nbsp; &amp;nbsp;&lt;span class=&quot;code-b&quot;&gt;--from=이전이미지번호&lt;/span&gt;&amp;nbsp; &amp;nbsp;source&amp;nbsp; &amp;nbsp;destination&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;/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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;a href=&quot;http://localhost:28090/docs/v.1.0.0.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://localhost:28090/docs/v.1.0.0.html&lt;/a&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;(위 예시에서의 Restdocs 문서)&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;사용자가 docker를 설치한 후라면&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;ex03&quot; data-ke-size=&quot;size16&quot;&gt;[세 번째 예시] (비효율적이지만 명령어 예시)&lt;/p&gt;
&lt;table class=&quot;descTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;1. 하나의 최종 구동환경 이미지에서 wget, unzip, git, gradle을 설치(리눅스 yum, apt-get 등)&lt;/p&gt;&lt;p&gt;2. wget, unzip 등으로 yum 및 apt-get에 없는 프로그램들을 설치&lt;/p&gt;&lt;p&gt;3. 환경변수 설정&lt;/p&gt;&lt;p&gt;4. 프로젝트를 내려받고&lt;/p&gt;&lt;p&gt;5. 빌드하고&lt;/p&gt;&lt;p&gt;6. 실행&lt;/p&gt;&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;
&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;Dockerfile&lt;/p&gt;
&lt;pre id=&quot;code_1672750272335&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM amazoncorretto:8u352
LABEL stage=forbuild

RUN yum install wget -y
RUN yum install unzip -y
RUN yum install git -y

RUN wget https://services.gradle.org/distributions/gradle-7.6-bin.zip -P /tmp
RUN unzip -d /opt/gradle -oq /tmp/gradle-7.6-bin.zip
RUN rm /tmp/gradle-7.6-bin.zip
ENV PATH /opt/gradle/gradle-7.6/bin:$PATH

RUN [ &quot;git&quot;, &quot;clone&quot;, &quot;https://github.com/BlackdeerY/restdocs-maven.git&quot;, &quot;restdocs&quot; ]

WORKDIR /restdocs
RUN [ &quot;gradle&quot;, &quot;jar&quot; ]

EXPOSE 8090
ENTRYPOINT [ &quot;java&quot;, &quot;-jar&quot;, &quot;/restdocs/build/libs/restdocs-maven-0.0.1-SNAPSHOT.war&quot; ]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker 명령&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;docker build&amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;--no-cache&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;-t 생성될이미지명:태그&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;Dockerfile경로&lt;/p&gt;&lt;p&gt;docker image prune&amp;nbsp; &lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;&lt;span style=&quot;color: #f6e199;&quot;&gt;--filter&lt;/span&gt;&amp;nbsp; label=stage=forbuild&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;docker run&amp;nbsp; &amp;nbsp;-d&amp;nbsp; &amp;nbsp;-it&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;-p 28090:8090&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;&lt;span style=&quot;border: 1px gray dotted;&quot;&gt;&amp;nbsp;--name 생성될컨테이너명&amp;nbsp;&lt;/span&gt;&amp;nbsp; &amp;nbsp;생성한이미지명&lt;/p&gt;&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시의 추가된 Dockerfile의 명령어들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;ENV&lt;/span&gt;&amp;nbsp; &amp;nbsp;key&amp;nbsp; &amp;nbsp;value&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dockerfile 공식 문서는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.docker.com/engine/reference/builder/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.docker.com/engine/reference/builder/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1672755824362&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Dockerfile reference&quot; data-og-description=&quot; &quot; data-og-host=&quot;docs.docker.com&quot; data-og-source-url=&quot;https://docs.docker.com/engine/reference/builder/&quot; data-og-url=&quot;https://docs.docker.com/engine/reference/builder/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/AD7b6/hyQ87mBCFi/YkZidnEwH0lobayWKAsJFk/img.png?width=129&amp;amp;height=128&amp;amp;face=0_0_129_128,https://scrap.kakaocdn.net/dn/eRIci/hyQ8U1RrVa/cuEPHTDO2kjO957pwRz0P0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500&quot;&gt;&lt;a href=&quot;https://docs.docker.com/engine/reference/builder/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.docker.com/engine/reference/builder/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/AD7b6/hyQ87mBCFi/YkZidnEwH0lobayWKAsJFk/img.png?width=129&amp;amp;height=128&amp;amp;face=0_0_129_128,https://scrap.kakaocdn.net/dn/eRIci/hyQ8U1RrVa/cuEPHTDO2kjO957pwRz0P0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Dockerfile reference&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.docker.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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>Study/Docker</category>
      <category>Docker</category>
      <category>dockerfile</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/308</guid>
      <comments>https://ydeer.tistory.com/308#entry308comment</comments>
      <pubDate>Tue, 3 Jan 2023 18:36:40 +0900</pubDate>
    </item>
    <item>
      <title>원클릭 마우스 정확도 향상 끄기</title>
      <link>https://ydeer.tistory.com/304</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/msDTb/btrMK2bJMzf/F8QZCfCKJN86kNDxB0LXvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/msDTb/btrMK2bJMzf/F8QZCfCKJN86kNDxB0LXvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/msDTb/btrMK2bJMzf/F8QZCfCKJN86kNDxB0LXvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmsDTb%2FbtrMK2bJMzf%2FF8QZCfCKJN86kNDxB0LXvk%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;465&quot; height=&quot;518&quot; data-origin-width=&quot;465&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Moonlight를 포함한 몇몇 원격 프로그램 중에는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Host에 가상 키보드를 세팅하면서 마우스의 '포인터 정확도 향상'을 항상 켜버리는 프로그램들이 있다.&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;원격 Client에서 제어할 때는 모르다가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 직접 Host에 앉아서 제어할 때는 마우스가 뭔가 달라졌단게 느껴질 것이다.&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;개인 컴퓨터에서 항상 켜두고 사용하는 도구 프로그램에 마우스 정확도 향상 끄기와 US 키보드 제거 등을 탑재해두고 있었으나,&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;왜인지 적용이 안되서, 난 이 방법은 못 써서 아예 함수를 실행하는 쪽을 선택했었다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/cVTpQY/btrMEtikHdu/KiwWhhMOc7RFkCxthrcNa0/MouseNoCorrection.7z?attach=1&amp;amp;knm=tfile.7z&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;MouseNoCorrection.7z&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;압축 파일의 두 파일(MouseNoCorrection.ps1, MouseNoCorrection.bat)을 &lt;b&gt;한 폴더에 두고,&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;bat파일만 실행&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;/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;(MouseNoCorrection.bat)&lt;/p&gt;
&lt;pre id=&quot;code_1663745662109&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@echo off
Powershell.exe -noprofile -executionpolicy bypass -file MouseNoCorrection.ps1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(MouseNoCorrection.ps1)&lt;/p&gt;
&lt;pre id=&quot;code_1663745691320&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Function MouseNoCorrection { 
$pinvokeCode = @&quot; 
using System; 
using System.Runtime.InteropServices; 
using Microsoft.Win32;
namespace MyMouse { 
    public class MouseCorrection { 
        [DllImport(&quot;user32.dll&quot;)]
        private static extern int SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);

        public static void SetNoCorrection() { 
            int[] mouseParams = new int[3];
            SystemParametersInfo(0x0003, 0x0000, GCHandle.Alloc(mouseParams, GCHandleType.Pinned).AddrOfPinnedObject(), 0x0000);
            mouseParams[2] = 0;
            SystemParametersInfo(0x0004, 0x0000, GCHandle.Alloc(mouseParams, GCHandleType.Pinned).AddrOfPinnedObject(), 0x0002);
        } 
    } 
} 
&quot;@ 
Add-Type $pinvokeCode -ErrorAction SilentlyContinue 
[MyMouse.MouseCorrection]::SetNoCorrection() 
} 
 
MouseNoCorrection&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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bat파일의 바로가기를 만들어서 응용하는 방식은 아래 포스트 마지막 부분 참고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ydeer.tistory.com/102&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ydeer.tistory.com/102&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1663745802440&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;원클릭 해상도 변경 (주사율(Hz) 추가, 모니터 지정 추가)&quot; data-og-description=&quot;컴퓨터의 해상도를 클릭 한 번으로 변경하는 방법입니다. 질문 댓글이 달린 김에 백업 겸 정리해둡니다. 윈도우 타일메뉴에 다음과 같이 설치해서 언제든 가로/세로 와 해상도를 바꿀 수 있습니&quot; data-og-host=&quot;ydeer.tistory.com&quot; data-og-source-url=&quot;https://ydeer.tistory.com/102&quot; data-og-url=&quot;https://ydeer.tistory.com/102&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bVN9xU/hyPRfsRjvj/19UVmlUsQHJWFtZENJ6msk/img.png?width=204&amp;amp;height=204&amp;amp;face=0_0_204_204,https://scrap.kakaocdn.net/dn/hB38C/hyPSY35dU2/Xodb1YjcXKQi2ToSgRgT80/img.png?width=204&amp;amp;height=204&amp;amp;face=0_0_204_204,https://scrap.kakaocdn.net/dn/b9IrkX/hyPSRcONzv/DfoOgpxHgJd9jYXkrfOroK/img.png?width=888&amp;amp;height=600&amp;amp;face=0_0_888_600&quot;&gt;&lt;a href=&quot;https://ydeer.tistory.com/102&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ydeer.tistory.com/102&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bVN9xU/hyPRfsRjvj/19UVmlUsQHJWFtZENJ6msk/img.png?width=204&amp;amp;height=204&amp;amp;face=0_0_204_204,https://scrap.kakaocdn.net/dn/hB38C/hyPSY35dU2/Xodb1YjcXKQi2ToSgRgT80/img.png?width=204&amp;amp;height=204&amp;amp;face=0_0_204_204,https://scrap.kakaocdn.net/dn/b9IrkX/hyPSRcONzv/DfoOgpxHgJd9jYXkrfOroK/img.png?width=888&amp;amp;height=600&amp;amp;face=0_0_888_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;원클릭 해상도 변경 (주사율(Hz) 추가, 모니터 지정 추가)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;컴퓨터의 해상도를 클릭 한 번으로 변경하는 방법입니다. 질문 댓글이 달린 김에 백업 겸 정리해둡니다. 윈도우 타일메뉴에 다음과 같이 설치해서 언제든 가로/세로 와 해상도를 바꿀 수 있습니&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ydeer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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>PC원격제어/help</category>
      <category>마우스</category>
      <category>마우스정확도</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/304</guid>
      <comments>https://ydeer.tistory.com/304#entry304comment</comments>
      <pubDate>Wed, 21 Sep 2022 16:37:26 +0900</pubDate>
    </item>
    <item>
      <title>Java - volatile 키워드, synchronized 키워드</title>
      <link>https://ydeer.tistory.com/300</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Modifier.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/Modifier.html&lt;/a&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: ObjectTest.java)&quot; data-text-less=&quot;(코드 접기: ObjectTest.java)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1659865717180&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package testvolatile;

public abstract class ObjectTest {
    public abstract int getInteger();
    public abstract void setInteger(int integer);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: ObjectTestVolatile.java)&quot; data-text-less=&quot;(코드 접기: ObjectTestVolatile.java)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1659865735891&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package testvolatile;

public class ObjectTestVolatile extends ObjectTest {
    private volatile int integer;

    public ObjectTestVolatile() {
        super();
        this.integer = 0;
    }

    @Override
    public int getInteger() {
        return integer;
    }

    @Override
    public void setInteger(int integer) {
        this.integer = integer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: ObjectTestSync.java)&quot; data-text-less=&quot;(코드 접기: ObjectTestSync.java)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1659865755862&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package testvolatile;

public class ObjectTestSync extends ObjectTest  {
    private int integer;

    public ObjectTestSync() {
        super();
        this.integer = 0;
    }

    @Override
    public synchronized int getInteger() {
        return integer;
    }

    @Override
    public synchronized void setInteger(int integer) {
        this.integer = integer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: ObjectTestAtomic.java)&quot; data-text-less=&quot;(코드 접기: ObjectTestAtomic.java)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1659865772442&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package testvolatile;

import java.util.concurrent.atomic.AtomicInteger;

public class ObjectTestAtomic extends ObjectTest  {
    private AtomicInteger integer;

    public ObjectTestAtomic() {
        super();
        this.integer = new AtomicInteger(0);
    }

    @Override
    public int getInteger() {
        return integer.get();
    }

    @Override
    public void setInteger(int integer) {
        this.integer.set(integer);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: TestMain.java)&quot; data-text-less=&quot;(코드 접기: TestMain.java)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1659863630056&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;package testvolatile;

import java.util.concurrent.atomic.AtomicBoolean;

public class TestMain {
    boolean bool = true;
    volatile boolean volatileBool = true;
    AtomicBoolean atomicBoolean = new AtomicBoolean(true);

    public void test() {
        new Thread(() -&amp;gt; {
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
            }
            bool = false;
            System.out.println(String.format(&quot;non-volatile: %s&quot;, bool));
        }).start();
        new Thread(() -&amp;gt; {
            while (bool) {
                // 아무 명령도 없는 경우에, bool을 갱신하지 않고 캐시 그대로 사용해서 종료되지 않음
            }
            System.out.println(&quot;non-volatile 종료됨&quot;);
        }).start();
        new Thread(() -&amp;gt; {
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
            }
            volatileBool = false;
            System.out.println(String.format(&quot;volatile: %s&quot;, volatileBool));
        }).start();
        new Thread(() -&amp;gt; {
            while (volatileBool) {
                // 아무 명령도 없는 경우에도.
            }
            System.out.println(&quot;volatile 종료됨&quot;);
        }).start();
        new Thread(() -&amp;gt; {
            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
            }
            atomicBoolean.set(false);
            System.out.println(String.format(&quot;atomicBoolean: %s&quot;, atomicBoolean.get()));
        }).start();
        new Thread(() -&amp;gt; {
            while (atomicBoolean.get()) {
                // 아무 명령도 없는 경우에도.
            }
            System.out.println(&quot;atomicBoolean 종료됨&quot;);
        }).start();
    }

    public static void main(String[] args) {
        TestMain testMain = new TestMain();
        testMain.test();

        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
        }
        System.out.println(&quot;--------------------------------------------------&quot;);






        ObjectTestVolatile objectTestVolatile = new ObjectTestVolatile();
        for (int i = 0; i &amp;lt; 200; ++i) {
            new Thread(() -&amp;gt; {
                objectTestVolatile.setInteger(objectTestVolatile.getInteger() + 1);
                System.out.println(String.format(&quot;%10s: %03d&quot;, &quot;volatile&quot;, objectTestVolatile.getInteger()));
            }).start();
        }
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
        }
        System.out.println(&quot;--------------------------------------------------&quot;);



        ObjectTestSync objectTestSync01 = new ObjectTestSync();
        for (int i = 0; i &amp;lt; 200; ++i) {
            new Thread(() -&amp;gt; {
                objectTestSync01.setInteger(objectTestSync01.getInteger() + 1);
                System.out.println(String.format(&quot;%10s: %03d&quot;, &quot;sync&quot;, objectTestSync01.getInteger()));
            }).start();
        }
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
        }
        System.out.println(&quot;--------------------------------------------------&quot;);



        ObjectTestSync objectTestSync02 = new ObjectTestSync();
        for (int i = 0; i &amp;lt; 200; ++i) {
            new Thread(() -&amp;gt; {
                synchronized (objectTestSync02) {
                    objectTestSync02.setInteger(objectTestSync02.getInteger() + 1);
                    System.out.println(String.format(&quot;%10s: %03d&quot;, &quot;sync-block&quot;, objectTestSync02.getInteger()));
                }
            }).start();
        }
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
        }
        System.out.println(&quot;--------------------------------------------------&quot;);



        ObjectTestAtomic objectTestAtomic = new ObjectTestAtomic();
        for (int i = 0; i &amp;lt; 200; ++i) {
            new Thread(() -&amp;gt; {
                objectTestAtomic.setInteger(objectTestAtomic.getInteger() + 1);
                System.out.println(String.format(&quot;%10s: %03d&quot;, &quot;atomic&quot;, objectTestAtomic.getInteger()));
            }).start();
        }
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
        }
        System.out.println(&quot;--------------------------------------------------&quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(출력 보기)&quot; data-text-less=&quot;(출력 접기)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;atomicBoolean&amp;nbsp;종료됨&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;color: #9feec3;&quot;&gt;volatile 종료됨&amp;nbsp; &amp;nbsp; &lt;span style=&quot;color: #ffc1c8;&quot;&gt;(non-volatile 종료됨은 출력되지 않았고, 쓰레드도 계속 도는 상황!)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;non-volatile:&amp;nbsp;false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;atomicBoolean:&amp;nbsp;false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;volatile:&amp;nbsp;false&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;--------------------------------------------------&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;volatile:&amp;nbsp;002&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;003&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;001&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;004&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;005&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;006&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;volatile:&amp;nbsp;008&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;009&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;..........&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;197&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;198&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;199&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;volatile:&amp;nbsp;200&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;--------------------------------------------------&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;sync:&amp;nbsp;003&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sync:&amp;nbsp;005&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sync:&amp;nbsp;002&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sync:&amp;nbsp;005&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sync:&amp;nbsp;001&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sync:&amp;nbsp;006&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sync:&amp;nbsp;007&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;sync:&amp;nbsp;009&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;..........&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;sync:&amp;nbsp;118&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sync:&amp;nbsp;178&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sync:&amp;nbsp;176&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;sync:&amp;nbsp;174&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;--------------------------------------------------&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;001&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;002&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;003&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;004&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;005&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;006&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;007&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;008&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;..........&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;197&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;198&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;199&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;sync-block:&amp;nbsp;200&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;--------------------------------------------------&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;001&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;002&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;003&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;atomic:&amp;nbsp;005&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;atomic:&amp;nbsp;004&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;006&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;007&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;008&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;..........&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;193&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;194&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;atomic:&amp;nbsp;196&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;color: #ee2323;&quot;&gt;atomic:&amp;nbsp;196&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;197&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;198&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;199&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;atomic:&amp;nbsp;200&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;&lt;span&gt;--------------------------------------------------&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ코드로 보면 &quot;non-volatile 종료됨&quot;이 출력되어야할 것 같지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;while&lt;/span&gt; (bool)&lt;/span&gt;에서 &lt;span class=&quot;code-span&quot;&gt;bool&lt;/span&gt;을 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;캐시에 둔 값만 사용해서&lt;/b&gt;&lt;/span&gt; 계속 &lt;span class=&quot;code-span code-r&quot;&gt;true&lt;/span&gt;로 사용하여 종료되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ반면 &lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;while&lt;/span&gt; (volatileBool)&lt;/span&gt;은 &lt;span class=&quot;code-span&quot;&gt;volatileBool&lt;/span&gt;을 메인 메모리에 두기 때문에, 정상적으로 종료된다. (volatile&amp;nbsp;종료됨)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;while&lt;/span&gt; (bool)&lt;/span&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;span class=&quot;code-span code-r&quot;&gt;volatile&lt;/span&gt; 키워드는 변수를 메인 메모리에 저장할 뿐, 그렇다고 thread-safe한 결과를 내진 않는다.&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;span class=&quot;code-span code-r&quot;&gt;volatile&lt;/span&gt;이 multi-thread 상황에서 각자의 캐시간 값 차이를 없앨 수 있는 수단 중 하나일 뿐,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　그 순서를 보장해주진 않는다. &lt;b&gt;순서는 lock의 개념으로 가야한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　multi-thread 상황 때문에 둘을 한 범주에 두고 생각해버릴 수 있다.&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 class=&quot;code-span code-r&quot;&gt;volatile&lt;/span&gt; 멤버 변수를 둔 개체라도, multi-thread에서 순서는 보장 되지 않는 것을 결과로 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;getter()&lt;/span&gt;와 &lt;span class=&quot;code-span&quot;&gt;setter()&lt;/span&gt;가 synchronized 메서드라도,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-b&quot;&gt;System&lt;/span&gt;.out.println()&lt;/span&gt;이 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;synchronized 메서드가 아니기 때문에,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;b&gt;출력에서 순서가 보장되지 않는다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;b&gt;(사용하는 모든 메서드가 동일한 개체에 synchronized여야 순서를 보장받을 수 있다.)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;&lt;span class=&quot;code-r&quot;&gt;synchronized&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;ㆍAtomicWrapper 클래스를 역시 내부에 &lt;span class=&quot;code-span code-r&quot;&gt;volatile&lt;/span&gt; 키워드를 사용하여 thread별 캐시간 값 차이를 없앨을 뿐,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　&lt;b&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;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ여러 Thread에서 동시에 접근하는 변수라면, &lt;span class=&quot;code-span code-r&quot;&gt;volatile&lt;/span&gt; 키워드를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍvolatile 변수라도 자체적으로 lock을 해주는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　multi-thread에서 순서를 보장하려면 &lt;span class=&quot;code-span code-r&quot;&gt;synchronized&lt;/span&gt; 키워드나 &lt;a href=&quot;https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/Semaphore.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span class=&quot;code-span code-b&quot;&gt;Semaphore&lt;/span&gt; 클래스&lt;/a&gt;가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ한 mutex에 묶인 synchronized가 아니라면, 그 사이에는 synchronized 되지 않은 채 진행되므로,&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;</description>
      <category>Study/Java</category>
      <category>java</category>
      <category>synchronized</category>
      <category>volatile</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/300</guid>
      <comments>https://ydeer.tistory.com/300#entry300comment</comments>
      <pubDate>Sun, 7 Aug 2022 18:53:24 +0900</pubDate>
    </item>
    <item>
      <title>ssh-keygen 명령어로 SSH키 쌍 생성</title>
      <link>https://ydeer.tistory.com/298</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;접속&quot;&gt;[SSH 접속과 키 쌍]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;옵션확인&quot;&gt;[옵션 확인]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;기본사용&quot;&gt;[옵션 없이 사용]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;옵션사용&quot;&gt;[옵션 사용]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;정보확인&quot;&gt;[키 파일로부터 정보 확인]&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;공개키복구&quot;&gt;[public key 복구]&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;접속&quot; data-ke-size=&quot;size16&quot;&gt;[SSH 접속과 키 쌍]&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;SSH에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;private key는 권한자를 의미하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;public key는 해당 권한자에게 허용하겠다는 의미이다.&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;SSH Host에서는 authorized_key 리스트에 public key들을 수록하여,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 public key와 쌍을 이루는 private key를 가진 권한자에게 접속을 허용하기로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Client에서는 private key를 이용하여 Host에 접속한다.&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;ㆍHost: public key 보유&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍClient: private key 사용&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;옵션확인&quot; 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;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;% &lt;span style=&quot;color: #ffffff;&quot;&gt;ssh-keygen &lt;span class=&quot;cmdO&quot;&gt;--help&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로 옵션을 확인하면 된다. (&lt;a href=&quot;https://www.freebsd.org/cgi/man.cgi?query=ssh-keygen&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.freebsd.org/cgi/man.cgi?query=ssh-keygen&lt;/a&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;기본사용&quot; 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;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;% &lt;span style=&quot;color: #ffffff;&quot;&gt;ssh-keygen&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;Generating&amp;nbsp;public/private&amp;nbsp;rsa&amp;nbsp;key&amp;nbsp;pair.&lt;/p&gt;&lt;p&gt;Enter file in which to save the key (/Users/blackdeer/.ssh/id_rsa): &lt;span style=&quot;color: #ffffff;&quot;&gt;/Users/blackdeer/.ssh/test01&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Enter passphrase (empty for no passphrase): &lt;span style=&quot;color: #ffffff;&quot;&gt;숨겨진입력&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Enter same passphrase again: &lt;span style=&quot;color: #ffffff;&quot;&gt;숨겨진입력&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;green&quot;&gt;Your identification has been saved in /Users/blackdeer/.ssh/test01&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;green&quot;&gt;Your public key has been saved in /Users/blackdeer/.ssh/test01.pub&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The&amp;nbsp;key&amp;nbsp;fingerprint&amp;nbsp;is:&lt;/p&gt;&lt;p&gt;SHA256:avOfU8xcBulhus7IR9wD25S4oDikFF17S5gm23ZFu04&amp;nbsp;blackdeer@Mac.local&lt;/p&gt;&lt;p&gt;The&amp;nbsp;key's&amp;nbsp;randomart&amp;nbsp;image&amp;nbsp;is:&lt;/p&gt;&lt;p&gt;+---[RSA&amp;nbsp;3072]----+&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;.&amp;nbsp;..&amp;nbsp;&amp;nbsp;&amp;nbsp;.&amp;nbsp;&amp;nbsp;.&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;.&amp;nbsp;.&amp;nbsp;&amp;nbsp;+&amp;nbsp;.&amp;nbsp;.=&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;..&amp;nbsp;=&amp;nbsp;o&amp;nbsp;o=&amp;nbsp;+&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;.&amp;nbsp;.=&amp;nbsp;o.o+.+&amp;nbsp;o&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;.&amp;nbsp;o..o.SoE%&amp;nbsp;o&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;.&amp;nbsp;o..o&amp;nbsp;o*&amp;nbsp;O&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.+.&amp;nbsp;=..&amp;nbsp;.&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&amp;nbsp;oo&amp;nbsp;=.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.oo.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;+----[SHA256]-----+&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;-t 타입&lt;/span&gt; 옵션으로 타입을 지정해주지 않으면, 기본적으로 RSA방식의 키를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;-b 길이&lt;/span&gt; 옵션으로 길이를 지정해주지 않으면, 기본적으로 3072 Bits의 키를 생성한다. (2022년 07월 기준)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　(※ NIST에서 권장하는 길이 - 2002년: 1024 Bits, 2015년: 2048 Bits, ...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;-f 저장경로&lt;/span&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;　이 때는 ~(/Users/로그온한사용자)의 단축 형식이 통하지 않으니, &lt;b&gt;절대경로로 적어준다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;-N 암호&lt;/span&gt; 옵션으로 암호(passphrase)를 지정하지 않으면, 키 생성시 사용할 암호를 물어본다. (Enter passphrase)&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;span class=&quot;code-span&quot;&gt;-E 지문해시유형&lt;/span&gt; 옵션으로 지문 생성의 해시 유형을 지정하지 않으면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　기본적으로 SHA256으로 생성한다. &lt;span class=&quot;code-span&quot;&gt;-E sha256&lt;/span&gt;, &lt;span class=&quot;code-span&quot;&gt;-E md5&lt;/span&gt;로 지정 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;span class=&quot;code-span&quot;&gt;-C 코멘트&lt;/span&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;ㆍ키는 private key, public key 쌍으로 생성되며, public key의 뒤에는 .pub이 붙는다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;옵션사용&quot; 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;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;% &lt;span style=&quot;color: #ffffff;&quot;&gt;ssh-keygen &lt;span class=&quot;cmdO&quot;&gt;-t rsa&lt;/span&gt; &lt;span class=&quot;cmdO&quot;&gt;-b 4096&lt;/span&gt; &lt;span class=&quot;cmdO&quot;&gt;-f ~/.ssh/test02&lt;/span&gt; &lt;span class=&quot;cmdO&quot;&gt;-C &quot;코멘트: 예시를 위해 생성&quot;&lt;/span&gt; &lt;span class=&quot;cmdO&quot;&gt;-N &quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;Generating&amp;nbsp;public/private&amp;nbsp;rsa&amp;nbsp;key&amp;nbsp;pair.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;green&quot;&gt;Your&amp;nbsp;identification&amp;nbsp;has&amp;nbsp;been&amp;nbsp;saved&amp;nbsp;in&amp;nbsp;/Users/blackdeer/.ssh/test02&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;green&quot;&gt;Your&amp;nbsp;public&amp;nbsp;key&amp;nbsp;has&amp;nbsp;been&amp;nbsp;saved&amp;nbsp;in&amp;nbsp;/Users/blackdeer/.ssh/test02.pub&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The&amp;nbsp;key&amp;nbsp;fingerprint&amp;nbsp;is:&lt;/p&gt;&lt;p&gt;SHA256:RqvdvvVWdpZJyygyLocNj8TgakvTnaqcKpDrduzB6Co&amp;nbsp;코멘트:&amp;nbsp;예시를&amp;nbsp;위해&amp;nbsp;생성&lt;/p&gt;&lt;p&gt;The&amp;nbsp;key's&amp;nbsp;randomart&amp;nbsp;image&amp;nbsp;is:&lt;/p&gt;&lt;p&gt;+---[RSA&amp;nbsp;4096]----+&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&amp;nbsp;.&amp;nbsp;.&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|&amp;nbsp;.&amp;nbsp;&amp;nbsp;.&amp;nbsp;o&amp;nbsp;S&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;+&amp;nbsp;+|&lt;/p&gt;&lt;p&gt;|o&amp;nbsp;o&amp;nbsp;...B.+&amp;nbsp;.&amp;nbsp;.&amp;nbsp;==|&lt;/p&gt;&lt;p&gt;|.o.=..ooO&amp;nbsp;+&amp;nbsp;o&amp;nbsp;&amp;nbsp;+.|&lt;/p&gt;&lt;p&gt;|E.o=+&amp;nbsp;.+&amp;nbsp;*&amp;nbsp;.&amp;nbsp;..&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;|B+=*o.&amp;nbsp;&amp;nbsp;o&amp;nbsp;o.&amp;nbsp;..&amp;nbsp;&amp;nbsp;|&lt;/p&gt;&lt;p&gt;+----[SHA256]-----+&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵션들을 지정해서 별다른 대화문 없이 생성했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(옵션들의 설명은 위의 &lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;기본사용&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;정보확인&quot; 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;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;% &lt;span style=&quot;color: #ffffff;&quot;&gt;ssh-keygen &lt;span class=&quot;cmdO yellow shadow&quot;&gt;-l&lt;/span&gt; &lt;span class=&quot;cmdO&quot;&gt;-f ~/.ssh/test02&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;4096 SHA256:RqvdvvVWdpZJyygyLocNj8TgakvTnaqcKpDrduzB6Co 코멘트:&amp;nbsp;예시를&amp;nbsp;위해&amp;nbsp;생성 (RSA)&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;code-span&quot;&gt;-l&lt;/span&gt; 옵션으로&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ키의 암호화 방식(위의 예시에선 (RSA))&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ키의 Bits 길이(위의 예시에선 4096)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ지문의 해시 유형(위의 예시에선 SHA256)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ지문(위의 예시에선 RqvdvvVWdpZJyygyLocNj8TgakvTnaqcKpDrduzB6Co)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ코멘트(위의 예시에선 &quot;코멘트: 예시를 위해 생성&quot;)&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;공개키복구&quot; data-ke-size=&quot;size16&quot;&gt;[public key 복구]&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;public key로 private key를 알아낼 순 없지만(비대칭 키 암호화의 의의),&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;private key로 public key는 언제든 복구할 수 있다.&lt;/p&gt;
&lt;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;% &lt;span style=&quot;color: #ffffff;&quot;&gt;ssh-keygen &lt;span class=&quot;cmdO yellow shadow&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;cmdO&quot;&gt;-f ~/.ssh/test02&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;Enter passphrase: &lt;span style=&quot;color: #ffffff;&quot;&gt;숨겨진입력&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;p&gt;ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDGMOjJebCj8EGU2CFbO68ufFg0CP4iAVwR55AOSBt6gEgkixIoD9pw7qhcb0wTMtn2EzF/F7LCXD9ElT2Q9Bg4WlH02RBkMpzgTSFdO54dSCi3BO45RTMwW0HJDX5pFLANdRwpbbShg8blclQZSNANZQwt8cTnIWRswgerVlCclsMnkYJvFf2BCaXO/uZuUGEh/0vADqSPGb1XeHFPS+Qg4NPBjYOEuTz4btvPARgE0YbYF6cPbUXHWn8QEdUE/T/0SY7Z0V5ueJl78PqLkn+tdaTG7tZnEORaNVkYMSxLtLeLMDTWcBInj74C+5wjzZMtYj+xDy2377cTQyW1jlZ1en4S2rxMvX0BZcOpTknp20bcbj6zyAQISw+Ol+YcfJsFXebiAMsG6/2zhAHF1A2wkOtOUd2E9MzGQZ2P2EM+CnkxDptFXe7Mz4aIr0SSeIeJoq5x32mp1WGBPt2Uzfjrh826EBn2dW2bx3pQsfm8tBluegbqvc2ImKZGbPKgOntBVTPQWsBF6yuCypVV6wFgHUvxMk0cu62N+KdDuueZVEWmROACapXisgAbd6WNg6WXlu6mni+SOeNfruBZDFnDonLwU6AyKDshn0Xdj2e8z8GBzjY27PvRkmXlvq3SYa/Ab0zEmkAl06dTlettjNl9hay4P6+0NZnSBuGyw4W9Aw== 코멘트: 예시를 위해 생성&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(만약 키 생성시 암호(passphrase)를 지정했다면, 암호를 입력해야한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table class=&quot;cmd&quot; style=&quot;border-collapse: collapse; width: max-content;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: max-content;&quot;&gt;&lt;p&gt;% &lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;span class=&quot;cmdO&quot;&gt;ssh-keygen -y -f ~/.ssh/test02&lt;/span&gt; &lt;span class=&quot;cmdO&quot;&gt;&lt;span class=&quot;yellow shadow&quot;&gt;&amp;gt;&lt;/span&gt; ~/.ssh/test02.pub&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;cursor&quot;&gt;_&lt;/span&gt;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span class=&quot;code-span&quot;&gt;-y&lt;/span&gt; 옵션의 출력은 기본적으로 stdout이므로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 명령어 &lt;span class=&quot;code-span&quot;&gt;&amp;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;</description>
      <category>Study/기타</category>
      <category>RSA</category>
      <category>ssh-keygen</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/298</guid>
      <comments>https://ydeer.tistory.com/298#entry298comment</comments>
      <pubDate>Sun, 31 Jul 2022 11:13:48 +0900</pubDate>
    </item>
    <item>
      <title>CP1300 크레딧카드 인쇄 팁</title>
      <link>https://ydeer.tistory.com/291</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Cannon 셀피 포토프린터 CP1300&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크레딧카드 사이즈(54&amp;times;86mm: KC-36IP, KF-18IF) 인쇄 팁&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;psd파일로 &lt;b&gt;300dpi 54mm*85mm&lt;/b&gt;를 만들면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;638*1004 픽셀&lt;/b&gt;의 문서가 만들어진다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;안전 범위상으로 1mm미만 정도의 오차만 두도록 하여 여백을 두려면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;b&gt;좌에 2.8mm 추가(&amp;larr;),&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;b&gt;우에 3.2mm 추가(&amp;rarr;),&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;b&gt;상에 2.6mm 추가(&amp;uarr;),&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆍ&lt;b&gt;하에 3.4mm 추가(&amp;darr;)&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;span style=&quot;letter-spacing: 0px;&quot;&gt;보통 카드가 85.5mm라, 붙인 후 아래 쪽 0.5mm를 잘라낼 거라면, 상 2.5mm/하 3.5mm 후 아래를 잘래내면 됨.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;　(여백이 비뚤어질 수 있으니, 안전하게 그냥 2.6/3.4로 이미지 약간을 날리는 선택도 있고... 이건 해보고 판단)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;ㆍ인쇄할 때, 용지는 출력방향(&amp;darr;)이 아닌, 반대방향인&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;삽입구(&amp;uarr;)에 밀착&lt;/b&gt;시킨다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포토샵용 좌우상하 캔버스 크기 수정 액션(매크로) 파일도 아래에 첨부.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/VVVJd/btrFYvTQnYT/Ckx7DhHZ0Jk4IWro6pon9K/Margin_CP1300_CreditCardSize.atn?attach=1&amp;amp;knm=tfile.atn&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;Margin_CP1300_CreditCardSize.atn&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/0VwDM/btrG8ILv44x/Ae4OBUw2QxZuemYi2ll42K/Margin_CP1300_CreditCardSize_Cut.atn?attach=1&amp;amp;knm=tfile.atn&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;Margin_CP1300_CreditCardSize_Cut.atn&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;액션을 불러오는 방법은&lt;br /&gt;&lt;a href=&quot;https://helpx.adobe.com/kr/photoshop/using/playing-actions.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://helpx.adobe.com/kr/photoshop/using/playing-actions.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은 &quot;포토샵 액션 불러오기&quot; 검색&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>CP1300</category>
      <category>KC-36IP</category>
      <category>KF-18IF</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/291</guid>
      <comments>https://ydeer.tistory.com/291#entry291comment</comments>
      <pubDate>Tue, 28 Jun 2022 18:56:04 +0900</pubDate>
    </item>
    <item>
      <title>기본 알고리듬</title>
      <link>https://ydeer.tistory.com/289</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;[이동용 목차] (항목 클릭)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;소수&quot;&gt;소수(Prime Number)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　＊&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;소수란&quot;&gt;소수란&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　＊&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;에라토스테네스의체&quot;&gt;소수 판별 - 에라토스테네스의 체 (Sieve of Eratosthenes)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;최대공약수&quot;&gt;최대공약수(greastest&amp;nbsp;common&amp;nbsp;divisor,&amp;nbsp;GCD)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　＊&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;유클리드호제법&quot;&gt;유클리드 호제법 (Euclidean algorithm)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　＊&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;n개최대공약수&quot;&gt; 개의 수의 공통 최대공약수&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;최소공배수&quot;&gt;최소공배수(least&amp;nbsp;common&amp;nbsp;multiple,&amp;nbsp;LCM)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　＊&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;n개최소공배수&quot;&gt; 개의 수의 공통 최소공배수&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;이진탐색&quot;&gt;이진 탐색 (Binary Search)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;버블정렬&quot;&gt;버블 정렬 (Bubble Sort)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;선택정렬&quot;&gt;선택 정렬 (Selection Sort)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　＊&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;선택정렬-기본&quot;&gt;기본&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　＊&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;선택정렬-개선1&quot;&gt;개선 1: 순회할 때 최소와 최대를 동시에&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　＊&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;선택정렬-개선2&quot;&gt;개선 2: 같은 최솟값은 한꺼번에&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;삽입정렬&quot;&gt;삽입 정렬 (Insertion Sort)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;퀵정렬&quot;&gt;퀵 정렬 (Quick Sort)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;합병정렬&quot;&gt;합병 정렬 (Merge Sort)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ㆁ&lt;span class=&quot;btn-mv&quot; data-ke-mvto=&quot;힙정렬&quot;&gt;힙 정렬 (Heap Sort)&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;소수&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ소수(Prime Number)&lt;/p&gt;
&lt;p id=&quot;소수란&quot; data-ke-size=&quot;size16&quot;&gt;　＊소수란&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;b&gt;1보다 큰 자연수 중,&lt;/b&gt; 1과 자기 자신만을 약수로 갖는 수 (1과 자기 자신으로만 나머지가 0으로 나눠 떨어지는 수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍex) 2, 3, 5, 7, 11, 13, 17, 19, 23, 31, 37, 41, ...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ짝수는 모두 2의 배수이기 때문에, 2를 제외하고는 모두 홀수이다. 하지만 2는 소수에 포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ유클리드의 정리 (Euclid's theorem)에 의하면, 소수는 무한히 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ반대의 개념은 합성수(Composite Number)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Prime_number&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Prime_number&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%86%8C%EC%88%98_(%EC%88%98%EB%A1%A0)&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/소수_(수론)&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Euclid%27s_theorem&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Euclid's_theorem&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%9C%A0%ED%81%B4%EB%A6%AC%EB%93%9C%EC%9D%98_%EC%A0%95%EB%A6%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/유클리드의_정리&lt;/a&gt;&lt;/p&gt;
&lt;p id=&quot;에라토스테네스의체&quot; data-ke-size=&quot;size16&quot;&gt;　＊에라토스테네스의 체 (Sieve of Eratosthenes)&lt;/p&gt;
&lt;p class=&quot;customm customm2&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Sieve_of_Eratosthenes_animation.gif&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;369&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y3z4M/btrHK0Kngl2/LdOToP0ywrL9Ps74LQm89K/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y3z4M/btrHK0Kngl2/LdOToP0ywrL9Ps74LQm89K/img.gif&quot; data-alt=&quot;https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y3z4M/btrHK0Kngl2/LdOToP0ywrL9Ps74LQm89K/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/y3z4M/btrHK0Kngl2/LdOToP0ywrL9Ps74LQm89K/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;445&quot; height=&quot;369&quot; data-filename=&quot;Sieve_of_Eratosthenes_animation.gif&quot; data-origin-width=&quot;445&quot; data-origin-height=&quot;369&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes&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;a href=&quot;https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/에라토스테네스의_체&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 에라토스테네스의 체)&quot; data-text-less=&quot;(코드 접기: 에라토스테네스의 체)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1658281728294&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int[] getPrimeNumbersBySieveOfEratosthenes(int max) {
    // boolean은 false로 초기화되므로, '소수가 아니다'의 false는 '소수이다'로 시작.
    boolean[] isNotPrimeNumber = new boolean[max];
    isNotPrimeNumber[0] = true;    // 1은 소수가 아님
    for (int i = 2; i * i &amp;lt;= max; ++i) {
        for (int j = i * i; j &amp;lt;= max; j += i) {    // i * 2 부터 시작이 아니라, i * i 부터 시작. i * i 이전의 i의 배수들은 이전 과정에서 체크되었음.
            isNotPrimeNumber[j - 1] = true;    // 자기 자신을 제외한, 자신의 배수들은 모두 소수가 아님.
        }
    }
    // 소수들의 갯수
    int count = 0;
    for (int i = 0; i &amp;lt; isNotPrimeNumber.length; ++i) {
        if (isNotPrimeNumber[i] == false) {
            ++count;
        }
    }
    // 소수들을 담아 반환할 int[] 배열
    int[] primeNumbers = new int[count];
    int index = 0;
    for (int i = 0; i &amp;lt; isNotPrimeNumber.length &amp;amp;&amp;amp; index &amp;lt; count; ++i) {
        if (isNotPrimeNumber[i] == false) {
            primeNumbers[index++] = i + 1;
        }
    }
    return primeNumbers;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 에라토스테네스의 체 - 갯수와 항목들 구하는 함수 따로)&quot; data-text-less=&quot;(코드 접기: 에라토스테네스의 체 - 갯수와 항목들 구하는 함수 따로)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1658281748918&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;private boolean[] getBooleanArrayMeansNotPrimeNumbers(int max) {
    // boolean은 false로 초기화되므로, '소수가 아니다'의 false는 '소수이다'로 시작.
    boolean[] isNotPrimeNumber = new boolean[max];
    isNotPrimeNumber[0] = true;    // 1은 소수가 아님
    for (int i = 2; i * i &amp;lt;= max; ++i) {
        for (int j = i * i; j &amp;lt;= max; j += i) {    // i * 2 부터 시작이 아니라, i * i 부터 시작. i * i 이전의 i의 배수들은 이전 과정에서 체크되었음.
            isNotPrimeNumber[j - 1] = true;    // 자기 자신을 제외한, 자신의 배수들은 모두 소수가 아님.
        }
    }
    return isNotPrimeNumber;
}

public int getCountOfPrimeNumbers(int max) {
    return getCountOfPrimeNumbers(max, getBooleanArrayMeansNotPrimeNumbers(max));
}

private int getCountOfPrimeNumbers(int max, boolean[] isNotPrimeNumber) {
    // 소수들의 갯수
    int count = 0;
    for (int i = 0; i &amp;lt; isNotPrimeNumber.length; ++i) {
        if (isNotPrimeNumber[i] == false) {
            ++count;
        }
    }
    return count;
}

public int[] getIntegerArrayMeansPrimeNumbers(int max) {
    boolean[] isNotPrimeNumber = getBooleanArrayMeansNotPrimeNumbers(max);
    int count = getCountOfPrimeNumbers(max, isNotPrimeNumber);

    // 소수들을 담아 반환할 int[] 배열
    int[] primeNumbers = new int[max];
    int index = 0;
    for (int i = 0; i &amp;lt; isNotPrimeNumber.length &amp;amp;&amp;amp; index &amp;lt; count; ++i) {
        if (isNotPrimeNumber[i] == false) {
            primeNumbers[index++] = i + 1;
        }
    }
    return primeNumbers;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;최대공약수&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ최대공약수(greastest common divisor, GCD)&lt;/p&gt;
&lt;p id=&quot;유클리드호제법&quot; data-ke-size=&quot;size16&quot;&gt;　＊유클리드 호제법 (Euclidean algorithm)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ서로 호(互), 나눌 제(除). &lt;b&gt;두 개&lt;/b&gt;의 양의 정수간의 최대공약수를 구함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;span style=&quot;color: #ee2323;&quot;&gt; &lt;/span&gt;와 &lt;span style=&quot;color: #006dd7;&quot;&gt; &lt;/span&gt;의 최대공약수는,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　&lt;span style=&quot;color: #ee2323;&quot;&gt; &lt;/span&gt; = &lt;span style=&quot;color: #006dd7; background-color: #f6e199;&quot;&gt; &lt;/span&gt;*&lt;span style=&quot;background-color: #c1bef9;&quot;&gt; &lt;/span&gt; + &lt;u&gt;&lt;span style=&quot;color: #409d00;&quot;&gt; &lt;/span&gt;&lt;/u&gt;　(&lt;u&gt; &lt;/u&gt;은  미만의 &lt;b&gt;나머지&lt;/b&gt; 형태)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　 &lt;span style=&quot;color: #006dd7;&quot;&gt;↙&lt;/span&gt;　 &lt;span style=&quot;color: #409d00;&quot;&gt;↙&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　&lt;span style=&quot;color: #006dd7;&quot;&gt; &lt;/span&gt; = &lt;span style=&quot;color: #409d00; background-color: #f6e199;&quot;&gt; &lt;/span&gt;*&lt;span style=&quot;background-color: #c1bef9;&quot;&gt; &lt;/span&gt; + &lt;u&gt;&lt;span style=&quot;color: #f89009;&quot;&gt; &lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　 &lt;span style=&quot;color: #409d00;&quot;&gt;↙&lt;/span&gt;　 &lt;span style=&quot;color: #f89009;&quot;&gt;↙&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　&lt;span style=&quot;color: #409d00;&quot;&gt; &lt;/span&gt; = &lt;span style=&quot;color: #f89009; background-color: #f6e199;&quot;&gt; &lt;/span&gt;*&lt;span style=&quot;background-color: #c1bef9;&quot;&gt; &lt;/span&gt; + &lt;u&gt;&lt;span style=&quot;color: #a6bc00;&quot;&gt; &lt;/span&gt;&lt;/u&gt;...　를 반복하다가, &lt;b&gt;&lt;u&gt;상수항(나머지)이&lt;/u&gt;&amp;nbsp;없을 때&lt;/b&gt;의 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;계수&lt;/b&gt;&lt;/span&gt;가 최대공약수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ570 = 36&amp;times;15 + 30&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　&amp;nbsp; 36 = 30&amp;times;1 + 6&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　&amp;nbsp; 30 =&amp;nbsp; &amp;nbsp;6&amp;times;5&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　&amp;rarr; &amp;there4; 6&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Euclidean_algorithm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Euclidean_algorithm&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%9C%A0%ED%81%B4%EB%A6%AC%EB%93%9C_%ED%98%B8%EC%A0%9C%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/유클리드_호제법&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://namu.wiki/w/%EC%9C%A0%ED%81%B4%EB%A6%AC%EB%93%9C%20%ED%98%B8%EC%A0%9C%EB%B2%95&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://namu.wiki/w/유클리드 호제법&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 유클리드 호제법을 이용한 두 수의 최대공약수)&quot; data-text-less=&quot;(코드 접기: 유클리드 호제법을 이용한 두 수의 최대공약수)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1655875937072&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int getGCDbyEuclideanAlgorithm(int number1, int number2) {
    if (number1 == number2) {
        return number1;
    }
    int big = 0;
    int small = 0;
    if (number1 &amp;gt; number2) {
        big = number1;
        small = number2;
    } else {
        big = number2;
        small = number1;
    }
    while (true) {
        int residue = big % small;
        if (residue == 0) {
            return small;
        } else {
            big = small;
            small = residue;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p id=&quot;n개최대공약수&quot; data-ke-size=&quot;size16&quot;&gt;　＊ 개의 수를 소인수분해하여, 각 수의 소수들 중 &lt;b&gt;공통되는 부분들만 가장 큰 형태&lt;/b&gt;로.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ소수는 아니지만, 최소 1은 공통될 수 있으니, 구하려던 수들이 서로소라면 최대공약수는 1이된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ60 = &lt;span style=&quot;color: #ee2323;&quot;&gt;2&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&amp;times;&lt;span style=&quot;color: #409d00;&quot;&gt;3&lt;/span&gt;&amp;times;&lt;span style=&quot;color: #8a3db6;&quot;&gt;5&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　24 = &lt;span style=&quot;color: #ee2323;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/span&gt;&amp;times;&lt;span style=&quot;color: #409d00;&quot;&gt;3&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　20 = &lt;span style=&quot;color: #ee2323;&quot;&gt;2&lt;sup&gt;2&lt;/sup&gt;&lt;/span&gt;&amp;times;&lt;span style=&quot;color: #8a3db6;&quot;&gt;5&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　&amp;rarr; &amp;there4; 2&lt;sup&gt;2&lt;/sup&gt; = 4&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 소인수분해를 이용한 여러 수의 최대공약수)&quot; data-text-less=&quot;(코드 접기: 소인수분해를 이용한 여러 수의 최대공약수)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1655875956287&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int getGCD(int[] numbers) {
    if (numbers.length == 1) {
        return numbers[0];
    }
    int answer = 1;
    HashMap&amp;lt;Integer, Integer&amp;gt;[] primeNumbers = new HashMap[numbers.length];    // 각각의 소인수분해 결과를 &amp;lt;Key: 밑, Value: 지수&amp;gt; 형태로 담음
    for (int i = 0; i &amp;lt; numbers.length; ++i) {
        primeNumbers[i] = new HashMap&amp;lt;&amp;gt;();
        int thisNumber = numbers[i];
        int divisor = 2;
        while (thisNumber &amp;gt; 1) {
            if (thisNumber % divisor == 0) {
                if (primeNumbers[i].containsKey(divisor)) {
                    primeNumbers[i].put(divisor, primeNumbers[i].get(divisor) + 1);
                } else {
                    primeNumbers[i].put(divisor, 1);
                }
                thisNumber /= divisor;
            } else {
                ++divisor;
            }
        }
    }
    loop1:
    for (Integer primeNumber : primeNumbers[0].keySet()) {    // 공통되어야 하므로, 아무 결과를 하나로 기준으로 해도 됨.
        for (int i = 1; i &amp;lt; numbers.length; ++i) {
            if (primeNumbers[i].containsKey(primeNumber) == false) {    // 소수를 공통으로 지니지 않으면 해당 소수는 결과에 포함되지 않음.
                continue loop1;
            }
        }
        int maxCommonPower = primeNumbers[0].get(primeNumber);    // 지수는 Value들 중의 최소값으로.
        for (int i = 1; i &amp;lt; numbers.length; ++i) {
            int power = primeNumbers[i].get(primeNumber);
            if (power &amp;lt; maxCommonPower) {
                maxCommonPower = power;
            }
        }
        for (int i = 0; i &amp;lt; maxCommonPower; ++i) {
            answer *= primeNumber;
        }
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;최소공배수&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ최소공배수(least common multiple, LCM)&lt;/p&gt;
&lt;p id=&quot;n개최소공배수&quot; data-ke-size=&quot;size16&quot;&gt;　＊ 개의 수를 소인수분해하여, 각 수의 소수들은 &lt;b&gt;모두 포함&lt;/b&gt;하되, &lt;b&gt;승수는 가장 높도록&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ60 = 2&lt;sup&gt;2&lt;/sup&gt;&amp;times;3&amp;times;5&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　37 = 37&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　24 = 2&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/span&gt;&amp;times;3&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　　&amp;rarr; &amp;there4; 2&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;sup&gt;3&lt;/sup&gt;&lt;/span&gt;&amp;times;3&amp;times;5&amp;times;37 = 4440&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://ydeer.tistory.com/36&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[Lv2] N개의 최소공배수 (https://ydeer.tistory.com/36)&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 소인수분해를 이용한 여러 수의 최소공배수)&quot; data-text-less=&quot;(코드 접기: 소인수분해를 이용한 여러 수의 최소공배수)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1655875967679&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int getLCM(int[] numbers) {
    if (numbers.length == 1) {
        return numbers[0];
    }
    int answer = 1;
    HashMap&amp;lt;Integer, Integer&amp;gt;[] primeNumbers = new HashMap[numbers.length];    // 각각의 소인수분해 결과를 &amp;lt;Key: 밑, Value: 지수&amp;gt; 형태로 담음
    for (int i = 0; i &amp;lt; numbers.length; ++i) {
        primeNumbers[i] = new HashMap&amp;lt;&amp;gt;();
        int thisNumber = numbers[i];
        int divisor = 2;
        while (thisNumber &amp;gt; 1) {
            if (thisNumber % divisor == 0) {
                if (primeNumbers[i].containsKey(divisor) == true) {    // 이미 존재하면, 기존보다 +1승.
                    primeNumbers[i].put(divisor, primeNumbers[i].get(divisor) + 1);
                } else {
                    primeNumbers[i].put(divisor, 1);    // 최초라면 1번째 등장이니 1승.
                }
                thisNumber /= divisor;
            } else {
                ++divisor;
            }
        }
    }
    HashMap&amp;lt;Integer, Integer&amp;gt; results = new HashMap&amp;lt;&amp;gt;();    // 결과를 &amp;lt;Key: 밑, Value: 지수&amp;gt; 형태로 저장해 둠. 지수가 점점 커질 수 있으니 저장하면서 진행.
    for (int i = 0; i &amp;lt; numbers.length; ++i) {    // 소인수분해 결과 중 소수(밑. Key)는 어쨌든 다 사용.
        for (Integer base : primeNumbers[i].keySet()) {
            int thisPower = primeNumbers[i].get(base);
            if (results.containsKey(base) == true) {    // 이미 결과에 밑(Key)이 있었으면, 큰 지수(Value) 계산 후 저장.
                int resultsPower = results.get(base);
                if (thisPower &amp;gt; resultsPower) {
                    results.put(base, thisPower);
                }
            } else {    // 최초라면 우선 그냥 저장(소수는 어쨌든 다 사용).
                results.put(base, thisPower);
            }
        }
    }
    for (Integer base : results.keySet()) {
        for (int i = 0; i &amp;lt; results.get(base); ++i) {
            answer *= base;
        }
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;이진탐색&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ이진 탐색 (Binary Search)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Binary_search_algorithm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Binary_search_algorithm&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84_%EA%B2%80%EC%83%89_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/이진_검색_알고리즘&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://namu.wiki/w/%EC%9D%B4%EC%A7%84%20%ED%83%90%EC%83%89&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://namu.wiki/w/이진 탐색&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 이진 탐색)&quot; data-text-less=&quot;(코드 접기: 이진 탐색)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1657768533498&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int binarySearchRecursive(int integers[], int target) {
    return binarySearchRecursiveCore(integers, 0, integers.length - 1, target);
}

private int binarySearchRecursiveCore(int integers[], int indexStart, int indexEnd, int target) {
    if (indexStart &amp;gt; indexEnd) {
        return -1;
    } else {
        int indexMiddle = (indexStart + indexEnd) / 2;
        if (integers[indexMiddle] == target) {
            return indexMiddle;
        } else if (integers[indexMiddle] &amp;lt; target) {
            return binarySearchRecursiveCore(integers, indexMiddle + 1, indexEnd, target);
        } else {
            return binarySearchRecursiveCore(integers, indexStart, indexMiddle - 1, target);
        }
    }
}

public int binarySearchLoop(int integers[], int target) {
    int indexStart = 0;
    int indexEnd = integers.length - 1;

    while (indexStart &amp;lt;= indexEnd) {
        int indexMiddle = (indexStart + indexEnd) / 2;
        if (integers[indexMiddle] == target) {
            return indexMiddle;
        } else if (integers[indexMiddle] &amp;lt; target) {
            indexStart = indexMiddle + 1;
        } else {
            indexEnd = indexMiddle - 1;
        }
    }
    return -1;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;버블정렬&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ버블 정렬 (Bubble Sort)&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Bubble_sort_animation.gif&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zqKI0/btrHwkWnYUW/RLSggHxBj9FurbJ2XZKPK0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zqKI0/btrHwkWnYUW/RLSggHxBj9FurbJ2XZKPK0/img.gif&quot; data-alt=&quot;https://en.wikipedia.org/wiki/Bubble_sort&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zqKI0/btrHwkWnYUW/RLSggHxBj9FurbJ2XZKPK0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/zqKI0/btrHwkWnYUW/RLSggHxBj9FurbJ2XZKPK0/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;280&quot; height=&quot;237&quot; data-filename=&quot;Bubble_sort_animation.gif&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/Bubble_sort&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;220px-Bubblesort-edited-color.svg.png&quot; data-origin-width=&quot;220&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b82GVZ/btrHp2QXHv6/FCKUAWSAKyftvUmhGfIqk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b82GVZ/btrHp2QXHv6/FCKUAWSAKyftvUmhGfIqk0/img.png&quot; data-alt=&quot;Cortesi, Aldo (27 April 2007). &amp;quot;Visualising Sorting Algorithms&amp;quot;. Retrieved 16 March 2017.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b82GVZ/btrHp2QXHv6/FCKUAWSAKyftvUmhGfIqk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb82GVZ%2FbtrHp2QXHv6%2FFCKUAWSAKyftvUmhGfIqk0%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;220&quot; height=&quot;183&quot; data-filename=&quot;220px-Bubblesort-edited-color.svg.png&quot; data-origin-width=&quot;220&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Cortesi, Aldo (27 April 2007). &quot;Visualising Sorting Algorithms&quot;. Retrieved 16 March 2017.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Bubble-sort-example-300px.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDlS9H/btrHp2wyCUY/seLEkcMWcUbwKtdyKlCexk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDlS9H/btrHp2wyCUY/seLEkcMWcUbwKtdyKlCexk/img.gif&quot; data-alt=&quot;https://en.wikipedia.org/wiki/Bubble_sort&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDlS9H/btrHp2wyCUY/seLEkcMWcUbwKtdyKlCexk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bDlS9H/btrHp2wyCUY/seLEkcMWcUbwKtdyKlCexk/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;300&quot; height=&quot;180&quot; data-filename=&quot;Bubble-sort-example-300px.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/Bubble_sort&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EA%B1%B0%ED%92%88_%EC%A0%95%EB%A0%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/거품_정렬&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Bubble_sort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Bubble_sort&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://namu.wiki/w/%EC%A0%95%EB%A0%AC%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98?from=%EB%B2%84%EB%B8%94%20%EC%A0%95%EB%A0%AC#s-2.1.1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://namu.wiki/w/정렬&amp;nbsp;알고리즘?from=버블&amp;nbsp;정렬#s-2.1.1&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ시간 복잡도:  ( &lt;sup&gt;2&lt;/sup&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ공간 복잡도:  (1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ안정성: 보장 됨 (O)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 버블 정렬)&quot; data-text-less=&quot;(코드 접기: 버블 정렬)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1658031562486&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void bubbleSort(int[] integers) {
    for (int i = 0; i &amp;lt; integers.length - 1; ++i) {
        for (int j = 0; j &amp;lt; integers.length - 1 - i; ++j) {
            if (integers[j] &amp;gt; integers[j + 1]) {
                int temp = integers[j];
                integers[j] = integers[j + 1];
                integers[j + 1] = temp;
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;선택정렬&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ선택 정렬 (Selection Sort)&lt;/p&gt;
&lt;p id=&quot;선택정렬-기본&quot; data-ke-size=&quot;size16&quot;&gt;　＊기본&lt;/p&gt;
&lt;p class=&quot;customm customm2&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Selection_sort_animation.gif&quot; data-origin-width=&quot;288&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MBhgf/btrHuTYUFSd/rwko6oBZtW4bcZINKW9rj1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MBhgf/btrHuTYUFSd/rwko6oBZtW4bcZINKW9rj1/img.gif&quot; data-alt=&quot;https://ko.wikipedia.org/wiki/선택_정렬&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MBhgf/btrHuTYUFSd/rwko6oBZtW4bcZINKW9rj1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/MBhgf/btrHuTYUFSd/rwko6oBZtW4bcZINKW9rj1/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;288&quot; height=&quot;288&quot; data-filename=&quot;Selection_sort_animation.gif&quot; data-origin-width=&quot;288&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://ko.wikipedia.org/wiki/선택_정렬&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p class=&quot;customm customm2&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Selection-Sort-Animation.gif&quot; data-origin-width=&quot;100&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNOeSb/btrHp2KklES/c3lDWIo6Nk1cVAGWhOlJC1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNOeSb/btrHp2KklES/c3lDWIo6Nk1cVAGWhOlJC1/img.gif&quot; data-alt=&quot;https://ko.wikipedia.org/wiki/선택_정렬&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNOeSb/btrHp2KklES/c3lDWIo6Nk1cVAGWhOlJC1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cNOeSb/btrHp2KklES/c3lDWIo6Nk1cVAGWhOlJC1/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;100&quot; height=&quot;371&quot; data-filename=&quot;Selection-Sort-Animation.gif&quot; data-origin-width=&quot;100&quot; data-origin-height=&quot;371&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://ko.wikipedia.org/wiki/선택_정렬&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Selection_sort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Selection_sort&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%84%A0%ED%83%9D_%EC%A0%95%EB%A0%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/선택_정렬&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ&lt;a href=&quot;https://namu.wiki/w/%EC%A0%95%EB%A0%AC%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98?from=%EC%84%A0%ED%83%9D%20%EC%A0%95%EB%A0%AC#s-2.1.2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://namu.wiki/w/정렬 알고리듬?from=선택 정렬#s-2.1.2&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ시간 복잡도:  ( &lt;sup&gt;2&lt;/sup&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ공간 복잡도:  (1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ안정성: 보장 안 됨 (X)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 선택 정렬 - 기본)&quot; data-text-less=&quot;(코드 접기: 선택 정렬 - 기본)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1658047457517&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void selectionSort(int[] integers) {
    for (int i = 0; i &amp;lt; integers.length - 1; ++i) {
        int indexMin = i;
     // for (int j = i + 1; j &amp;lt; integers.length; ++j) {
        for (int j = i;     j &amp;lt; integers.length; ++j) {
            if (integers[indexMin] &amp;gt; integers[j]) {
                indexMin = j;
            }
        }
     // if (indexMin != i) {
            int temp = integers[i];
            integers[i] = integers[indexMin];
            integers[indexMin] = temp;
     // }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p id=&quot;선택정렬-개선1&quot; data-ke-size=&quot;size16&quot;&gt;　＊개선 1: 순회할&amp;nbsp;때&amp;nbsp;최소와&amp;nbsp;최대를&amp;nbsp;동시에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ약간의 효율성을 높일 뿐, 2중 반복문이므로 시간복잡도는 여전히  ( &lt;sup&gt;2&lt;/sup&gt;)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 선택 정렬 - 개선 1: 순회할 때 최소와 최대를 동시에)&quot; data-text-less=&quot;(코드 접기: 선택 정렬 - 개선 1: 순회할 때 최소와 최대를 동시에)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1658065586583&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void selectionSortSimultaneous(int[] integers) {
    // 양 끝에 동시에 자리 잡으므로
    // 시작 위치를 n-1 까지가 아닌,
    // 절반(총 요소 수 짝수) 혹은 절반+1(총 요소 수 홀수) 까지로 줄일 수 있다.
    // 약간의 효율성을 높일 뿐, 시간복잡도는 여전히  ( ^2)이다.
    for (int i = 0; i &amp;lt;= integers.length / 2; ++i) {
        int indexMin = i;
        int indexMax = integers.length - 1 - i;
        // 확정된 양 끝이 한 칸씩 줄어든다.
        for (int j = i; j &amp;lt; integers.length - i; ++j) {
            if (integers[indexMin] &amp;gt; integers[j]) {
                indexMin = j;
            }
            if (integers[indexMax] &amp;lt; integers[j]) {
                indexMax = j;
            }
        }
        if (indexMin != i) {
            int temp = integers[i];
            integers[i] = integers[indexMin];
            integers[indexMin] = temp;
            // 만약 최솟값이 자리를 잡았는데(위 if (indexMin != i) 반복문이 실행된 지금),
            // 이번 최솟값 위치(i)의 값이 최댓값이었다면, 바뀐 index(최댓값이 옮겨진)로 indexMax를 갱신해준다.
            if (indexMax == i) {
                indexMax = indexMin;
            }
        }
        if (indexMax != integers.length - 1 - i) {
            int temp = integers[integers.length - 1 - i];
            integers[integers.length - 1 - i] = integers[indexMax];
            integers[indexMax] = temp;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p id=&quot;선택정렬-개선2&quot; data-ke-size=&quot;size16&quot;&gt;　＊개선 2: 같은&amp;nbsp;최솟값은&amp;nbsp;한꺼번에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　　ㆍ약간의 효율성을 높일 뿐, 2중 반복문이므로 시간복잡도는 여전히  ( &lt;sup&gt;2&lt;/sup&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;　　　총 요소 수와 같은 칸의 배열을 만들어두면 공간복잡도가  (1)에서  ( )으로 증가하고,&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;삽입정렬&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ삽입 정렬 (Insertion Sort)&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Insertion_sort_animation.gif&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;237&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GK49A/btrHAGTFHto/GR7fJgkxtZOprxhMnkUnU1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GK49A/btrHAGTFHto/GR7fJgkxtZOprxhMnkUnU1/img.gif&quot; data-alt=&quot;https://ko.wikipedia.org/wiki/삽입_정렬&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GK49A/btrHAGTFHto/GR7fJgkxtZOprxhMnkUnU1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/GK49A/btrHAGTFHto/GR7fJgkxtZOprxhMnkUnU1/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;280&quot; height=&quot;237&quot; data-filename=&quot;Insertion_sort_animation.gif&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;237&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://ko.wikipedia.org/wiki/삽입_정렬&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Insertion_sort.gif&quot; data-origin-width=&quot;193&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tNw2J/btrHvoNerEF/8KD1IpE7YQjYIU92QDapc1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tNw2J/btrHvoNerEF/8KD1IpE7YQjYIU92QDapc1/img.gif&quot; data-alt=&quot;https://en.wikipedia.org/wiki/Insertion_sort&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tNw2J/btrHvoNerEF/8KD1IpE7YQjYIU92QDapc1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/tNw2J/btrHvoNerEF/8KD1IpE7YQjYIU92QDapc1/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;193&quot; height=&quot;302&quot; data-filename=&quot;Insertion_sort.gif&quot; data-origin-width=&quot;193&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/Insertion_sort&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Insertion-sort-example-300px.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DgFMy/btrHzoZ18jt/FGMhTrdefknbKG1cjgEiqk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DgFMy/btrHzoZ18jt/FGMhTrdefknbKG1cjgEiqk/img.gif&quot; data-alt=&quot;https://ko.wikipedia.org/wiki/삽입_정렬&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DgFMy/btrHzoZ18jt/FGMhTrdefknbKG1cjgEiqk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/DgFMy/btrHzoZ18jt/FGMhTrdefknbKG1cjgEiqk/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;300&quot; height=&quot;180&quot; data-filename=&quot;Insertion-sort-example-300px.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://ko.wikipedia.org/wiki/삽입_정렬&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Insertion_sort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Insertion_sort&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%82%BD%EC%9E%85_%EC%A0%95%EB%A0%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/삽입_정렬&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://namu.wiki/w/%EC%A0%95%EB%A0%AC%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98?from=%EC%82%BD%EC%9E%85%20%EC%A0%95%EB%A0%AC#s-2.1.3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://namu.wiki/w/정렬 알고리즘?from=삽입 정렬#s-2.1.3&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ시간 복잡도:  ( &lt;sup&gt;2&lt;/sup&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ공간 복잡도:  (1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ안정성: 보장 됨 (O)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 삽입 정렬)&quot; data-text-less=&quot;(코드 접기: 삽입 정렬)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1658126619316&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void insertionSort(int[] integers) {
 // for (int i = 1; i &amp;lt; integers.length; ++i) {
    for (int i = 0; i &amp;lt; integers.length; ++i) {
        int index = i;
        while (true) {
            if (index == 0) {
                break;
            }
            if (integers[index] &amp;lt; integers[index - 1]) {
                int temp = integers[index - 1];
                integers[index - 1] = integers[index];
                integers[index] = temp;
                --index;
            } else {
                break;
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;퀵정렬&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ퀵 정렬 (Quick Sort)&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;220px-Sorting_quicksort_anim.gif&quot; data-origin-width=&quot;220&quot; data-origin-height=&quot;168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pEJPG/btrHzpZv7ON/Yu4E9Xy7t7GNz10tjEW7x0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pEJPG/btrHzpZv7ON/Yu4E9Xy7t7GNz10tjEW7x0/img.gif&quot; data-alt=&quot;https://en.wikipedia.org/wiki/Quicksort&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pEJPG/btrHzpZv7ON/Yu4E9Xy7t7GNz10tjEW7x0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/pEJPG/btrHzpZv7ON/Yu4E9Xy7t7GNz10tjEW7x0/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;220&quot; height=&quot;168&quot; data-filename=&quot;220px-Sorting_quicksort_anim.gif&quot; data-origin-width=&quot;220&quot; data-origin-height=&quot;168&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/Quicksort&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Quicksort-example.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XQgMI/btrHEdbYvus/Kk75AW2jrjcpvWKkXhIEF1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XQgMI/btrHEdbYvus/Kk75AW2jrjcpvWKkXhIEF1/img.gif&quot; data-alt=&quot;https://en.wikipedia.org/wiki/Quicksort&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XQgMI/btrHEdbYvus/Kk75AW2jrjcpvWKkXhIEF1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/XQgMI/btrHEdbYvus/Kk75AW2jrjcpvWKkXhIEF1/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;300&quot; height=&quot;180&quot; data-filename=&quot;Quicksort-example.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/Quicksort&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Quicksort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Quicksort&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%ED%80%B5_%EC%A0%95%EB%A0%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/퀵_정렬&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://namu.wiki/w/%EC%A0%95%EB%A0%AC%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98?from=%ED%80%B5%20%EC%A0%95%EB%A0%AC#s-2.2.3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://namu.wiki/w/정렬&amp;nbsp;알고리즘?from=퀵&amp;nbsp;정렬#s-2.2.3&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ시간 복잡도 - 평균:  ( &amp;middot;log ), 최악:  ( &lt;sup&gt;2&lt;/sup&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ공간 복잡도:  (log )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ안정성: 보장 안 됨 (X)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 퀵 정렬)&quot; data-text-less=&quot;(코드 접기: 퀵 정렬)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1658146984170&quot; class=&quot;prettyprint lang-csharp csharp&quot; data-ke-language=&quot;csharp&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void quickSortRecursive(int[] integers) {
    quickSortRecursiveCore(integers, 0, integers.length - 1);
}

private void quickSortRecursiveCore(int[] integers, int indexLeft, int indexRight) {
    if (indexLeft &amp;gt;= indexRight) {
        return;
    }
    int pivotValue = integers[indexRight];
    int indexWillBeFixed = indexLeft;
    for (int i = indexLeft; i &amp;lt; indexRight; ++i) {
        if (integers[i] &amp;lt; pivotValue) {
         // if (indexWillBeFixed != i) {
                int temp = integers[i];
                integers[i] = integers[indexWillBeFixed];
                integers[indexWillBeFixed] = temp;
         // }
            ++indexWillBeFixed;
        }
    }
 // if (indexWillBeFixed != indexRight) {
        integers[indexRight] = integers[indexWillBeFixed];
        integers[indexWillBeFixed] = pivotValue;
 // }
    quickSortRecursiveCore(integers, indexLeft, indexWillBeFixed - 1);
    quickSortRecursiveCore(integers, indexWillBeFixed + 1, indexRight);
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;합병정렬&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ합병 정렬 (Merge Sort)&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Merge-sort-example-300px.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c48VhL/btrHHkhvt1g/DQE5T9MIVf4gPRnv6tpZW1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c48VhL/btrHHkhvt1g/DQE5T9MIVf4gPRnv6tpZW1/img.gif&quot; data-alt=&quot;https://ko.wikipedia.org/wiki/합병_정렬&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c48VhL/btrHHkhvt1g/DQE5T9MIVf4gPRnv6tpZW1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/c48VhL/btrHHkhvt1g/DQE5T9MIVf4gPRnv6tpZW1/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;300&quot; height=&quot;180&quot; data-filename=&quot;Merge-sort-example-300px.gif&quot; data-origin-width=&quot;300&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://ko.wikipedia.org/wiki/합병_정렬&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Merge_sort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Merge_sort&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%ED%95%A9%EB%B3%91_%EC%A0%95%EB%A0%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/합병_정렬&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://namu.wiki/w/%EC%A0%95%EB%A0%AC%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98?from=%ED%95%A9%EB%B3%91%20%EC%A0%95%EB%A0%AC#s-2.2.1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://namu.wiki/w/정렬&amp;nbsp;알고리즘?from=합병&amp;nbsp;정렬#s-2.2.1&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ시간 복잡도:  ( &amp;middot;log )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ공간 복잡도:  ( )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ안정성: 보장 됨 (O)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 합병 정렬)&quot; data-text-less=&quot;(코드 접기: 합병 정렬)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1658192518037&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public void mergeSortRecursive(int[] integers) {
    if (integers.length &amp;gt; 1) {
        int[] arrayNextLeft = new int[integers.length / 2];
        int[] arrayNextRight = new int [integers.length - integers.length / 2];
        for (int i = 0; i &amp;lt; integers.length; ++i) {
            if (i &amp;lt; arrayNextLeft.length) {
                arrayNextLeft[i] = integers[i];
            } else {
                arrayNextRight[i - arrayNextLeft.length] = integers[i];
            }
        }
        mergeSortRecursiveCore(integers, arrayNextLeft, arrayNextRight);
    }
}

private void mergeSortRecursiveCore(final int[] arrayOrigin, final int[] arrayLeft, final int[] arrayRight) {
    if (arrayLeft.length &amp;gt; 1) {
        int[] arrayNextLeft = new int[arrayLeft.length / 2];
        int[] arrayNextRight = new int [arrayLeft.length - arrayLeft.length / 2];
        for (int i = 0; i &amp;lt; arrayLeft.length; ++i) {
            if (i &amp;lt; arrayNextLeft.length) {
                arrayNextLeft[i] = arrayLeft[i];
            } else {
                arrayNextRight[i - arrayNextLeft.length] = arrayLeft[i];
            }
        }
        mergeSortRecursiveCore(arrayLeft, arrayNextLeft, arrayNextRight);
    }
    if (arrayRight.length &amp;gt; 1) {
        int[] arrayNextLeft = new int[arrayRight.length / 2];
        int[] arrayNextRight = new int [arrayRight.length - arrayRight.length / 2];
        for (int i = 0; i &amp;lt; arrayRight.length; ++i) {
            if (i &amp;lt; arrayNextLeft.length) {
                arrayNextLeft[i] = arrayRight[i];
            } else {
                arrayNextRight[i - arrayNextLeft.length] = arrayRight[i];
            }
        }
        mergeSortRecursiveCore(arrayRight, arrayNextLeft, arrayNextRight);
    }
    // 재귀 결과로 arrayLeft와 arrayRight는 각각 정렬된 상태
    // (각각 아래 정렬을 먼저 적용 받은 상태)
    int indexLeft = 0;
    int indexRight = 0;
    for (int i = 0; i &amp;lt; arrayOrigin.length; ++i) {
        if (indexLeft &amp;gt;= arrayLeft.length) {
            arrayOrigin[i] = arrayRight[indexRight++];
        } else if (indexRight &amp;gt;= arrayRight.length) {
            arrayOrigin[i] = arrayLeft[indexLeft++];
        } else {
            if (arrayLeft[indexLeft] &amp;lt;= arrayRight[indexRight]) {
                arrayOrigin[i] = arrayLeft[indexLeft++];
            } else {
                arrayOrigin[i] = arrayRight[indexRight++];
            }
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p id=&quot;힙정렬&quot; data-ke-size=&quot;size16&quot;&gt;ㆁ힙 정렬 (Heap Sort)&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Sorting_heapsort_anim.gif&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5e1Kt/btrHIf2G81D/p0Ii9qrVpe6hwLV2PE3FzK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5e1Kt/btrHIf2G81D/p0Ii9qrVpe6hwLV2PE3FzK/img.gif&quot; data-alt=&quot;https://en.wikipedia.org/wiki/Heapsort&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5e1Kt/btrHIf2G81D/p0Ii9qrVpe6hwLV2PE3FzK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/c5e1Kt/btrHIf2G81D/p0Ii9qrVpe6hwLV2PE3FzK/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;280&quot; height=&quot;214&quot; data-filename=&quot;Sorting_heapsort_anim.gif&quot; data-origin-width=&quot;280&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/Heapsort&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p class=&quot;customm customm1&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Heapsort-example.gif&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nU6GJ/btrHFQvEGQZ/heSwYkuAjDoTgpGHjXSdJk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nU6GJ/btrHFQvEGQZ/heSwYkuAjDoTgpGHjXSdJk/img.gif&quot; data-alt=&quot;https://en.wikipedia.org/wiki/Heapsort&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nU6GJ/btrHFQvEGQZ/heSwYkuAjDoTgpGHjXSdJk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/nU6GJ/btrHFQvEGQZ/heSwYkuAjDoTgpGHjXSdJk/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;350&quot; height=&quot;280&quot; data-filename=&quot;Heapsort-example.gif&quot; data-origin-width=&quot;350&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://en.wikipedia.org/wiki/Heapsort&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://en.wikipedia.org/wiki/Heapsort&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://en.wikipedia.org/wiki/Heapsort&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://ko.wikipedia.org/wiki/%ED%9E%99_%EC%A0%95%EB%A0%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.wikipedia.org/wiki/힙_정렬&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ&lt;a href=&quot;https://namu.wiki/w/%EC%A0%95%EB%A0%AC%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98?from=%ED%9E%99%20%EC%A0%95%EB%A0%AC#s-2.2.2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://namu.wiki/w/정렬&amp;nbsp;알고리즘?from=힙&amp;nbsp;정렬#s-2.2.2&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ시간 복잡도:  ( &amp;middot;log )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ공간 복잡도:  (1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　ㆍ안정성: 보장 안 됨 (X)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;(코드 보기: 힙 정렬)&quot; data-text-less=&quot;(코드 접기: 힙 정렬)&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1658218596435&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Node {
    public Node(int data) {
        this.data = data;
    }

    private int data;
    private Node parent;
    private Node leftChild;
    private Node rightChild;

    public void changeNodeData(Node other) {
        int temp = this.data;
        this.data = other.data;
        other.data = temp;
    }
}

class Heap {
    private Node rootNode;

    private void addNode(Node node) {
        if (rootNode == null) {
            rootNode = node;
        } else {
            Node parent = getNodeToAdoptNext(rootNode);
            if (parent.leftChild == null) {
                parent.leftChild = node;
            } else {
                parent.rightChild = node;
            }
            node.parent = parent;
            sortBranchFromChild(node);
        }
    }

    private void setNodesFromArrays(int[] integers) {
        rootNode = null;
        for (int i = 0; i &amp;lt; integers.length; ++i) {
            addNode(new Node(integers[i]));
        }
    }

    private void sortBranchFromChild(Node node) {
        if (node.parent == null) {
            return;
        }
        if (node.parent.data &amp;lt; node.data) {
            node.changeNodeData(node.parent);
            sortBranchFromChild(node.parent);
        }
    }

    private int popMax() {
        int result = rootNode.data;
        Node endNode = getEndNode(rootNode);
        if (endNode == rootNode) {
            rootNode = null;
        } else {
            Node endsParent = endNode.parent;
            if (endsParent.leftChild == endNode) {
                endsParent.leftChild = null;
            } else {
                endsParent.rightChild = null;
            }
            endNode.parent = null;
            endNode.changeNodeData(rootNode);
            sortHeapFromParent(rootNode);
        }
        return result;
    }

    private void sortHeapFromParent(Node parentNode) {
        if (parentNode.leftChild == null &amp;amp;&amp;amp; parentNode.rightChild == null) {
            return;
        } else if (parentNode.leftChild != null &amp;amp;&amp;amp; parentNode.rightChild != null) {
            if (parentNode.data &amp;lt; parentNode.leftChild.data &amp;amp;&amp;amp; parentNode.data &amp;lt; parentNode.rightChild.data) {
                if (parentNode.leftChild.data == parentNode.rightChild.data) {
                    parentNode.changeNodeData(parentNode.leftChild);
                    sortHeapFromParent(parentNode.leftChild);
                } else if (parentNode.leftChild.data &amp;gt; parentNode.rightChild.data) {
                    parentNode.changeNodeData(parentNode.leftChild);
                    sortHeapFromParent(parentNode.leftChild);
                } else {
                    parentNode.changeNodeData(parentNode.rightChild);
                    sortHeapFromParent(parentNode.rightChild);
                }
            } else if (parentNode.data &amp;lt; parentNode.leftChild.data) {
                parentNode.changeNodeData(parentNode.leftChild);
                sortHeapFromParent(parentNode.leftChild);
            } else if (parentNode.data &amp;lt; parentNode.rightChild.data) {
                parentNode.changeNodeData(parentNode.rightChild);
                sortHeapFromParent(parentNode.rightChild);
            }
        } else if (parentNode.leftChild != null) {
            if (parentNode.data &amp;lt; parentNode.leftChild.data) {
                parentNode.changeNodeData(parentNode.leftChild);
                sortHeapFromParent(parentNode.leftChild);
            }
        } else {
            if (parentNode.data &amp;lt; parentNode.rightChild.data) {
                parentNode.changeNodeData(parentNode.rightChild);
                sortHeapFromParent(parentNode.rightChild);
            }
        }
    }

    private Node getEndNode(Node parentNode) {
        if (parentNode.leftChild == null &amp;amp;&amp;amp; parentNode.rightChild == null) {
            return parentNode;
        } else if (parentNode.leftChild != null &amp;amp;&amp;amp; parentNode.rightChild != null) {
            Node leftEnd = getEndNode(parentNode.leftChild);
            Node rightEnd = getEndNode(parentNode.rightChild);
            Node leftParent = leftEnd.parent;
            int leftDepth = 1;
            while (leftParent.parent != null) {
                leftParent = leftParent.parent;
                ++leftDepth;
            }
            Node rightParent = rightEnd.parent;
            int rightDepth = 1;
            while (rightParent.parent != null) {
                rightParent = rightParent.parent;
                ++rightDepth;
            }
            if (leftDepth == rightDepth) {
                return rightEnd;
            } else if (leftDepth &amp;lt; rightDepth) {
                return rightEnd;
            } else {
                return leftEnd;
            }
        } else if (parentNode.leftChild != null) {
            return getEndNode(parentNode.leftChild);
        } else {
            return getEndNode(parentNode.rightChild);
        }
    }

    private Node getNodeToAdoptNext(Node parentNode){
        if (parentNode.leftChild != null &amp;amp;&amp;amp; parentNode.rightChild != null) {
            Node leftEnd = getNodeToAdoptNext(parentNode.leftChild);
            Node rightEnd = getNodeToAdoptNext(parentNode.rightChild);
            Node leftParent = leftEnd.parent;
            int leftDepth = 1;
            while (leftParent.parent != null) {
                leftParent = leftParent.parent;
                ++leftDepth;
            }
            Node rightParent = rightEnd.parent;
            int rightDepth = 1;
            while (rightParent.parent != null) {
                rightParent = rightParent.parent;
                ++rightDepth;
            }
            if (leftDepth == rightDepth) {
                return leftEnd;
            } else if (leftDepth &amp;lt; rightDepth) {
                return leftEnd;
            } else {
                return rightEnd;
            }
        } else {
            return parentNode;
        }
    }
}

public void heapSort(int[] integers) {
    Heap heap = new Heap();
    heap.setNodesFromArrays(integers);
    for (int i = integers.length - 1; i &amp;gt;= 0; --i) {
        integers[i] = heap.popMax();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&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>Study/Algorithm &amp;amp; Data Structure</category>
      <category>소수</category>
      <category>알고리듬</category>
      <category>정렬</category>
      <category>최대공약수</category>
      <category>최소공배수</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/289</guid>
      <comments>https://ydeer.tistory.com/289#entry289comment</comments>
      <pubDate>Wed, 22 Jun 2022 13:14:51 +0900</pubDate>
    </item>
    <item>
      <title>원클릭 배율(DPI) 변경</title>
      <link>https://ydeer.tistory.com/284</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ydeer.tistory.com/314&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[PC원격제어/help] - 원클릭 모니터변경 종결 (다중모니터,해상도,주사율,배율,회전,위치,...)&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675418375505&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;원클릭 모니터변경 종결 (다중모니터,해상도,주사율,배율,회전,위치,...)&quot; data-og-description=&quot;[서론 및 소개] [사용법] [서론 및 소개] 원격 제어를 애용하면서 그동안 사용했던 모니터 설정 방법을 공유했었다. PC에 모니터를 3개나 연결해보면서 원하는 모니터 그룹만 켜두는 것이 Windows 기&quot; data-og-host=&quot;ydeer.tistory.com&quot; data-og-source-url=&quot;https://ydeer.tistory.com/314&quot; data-og-url=&quot;https://ydeer.tistory.com/314&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vpz7s/hyRtTa751z/WgWyZbzrzBureZS2FgI0T1/img.png?width=626&amp;amp;height=473&amp;amp;face=0_0_626_473,https://scrap.kakaocdn.net/dn/edsR4O/hyRtToEt6m/whHCkZZs6Kms8zkxjnPCck/img.png?width=626&amp;amp;height=473&amp;amp;face=0_0_626_473,https://scrap.kakaocdn.net/dn/baTgur/hyRvnIq5iM/FKZednoCx9zPOzs90RoFX0/img.png?width=1194&amp;amp;height=984&amp;amp;face=0_0_1194_984&quot;&gt;&lt;a href=&quot;https://ydeer.tistory.com/314&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ydeer.tistory.com/314&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vpz7s/hyRtTa751z/WgWyZbzrzBureZS2FgI0T1/img.png?width=626&amp;amp;height=473&amp;amp;face=0_0_626_473,https://scrap.kakaocdn.net/dn/edsR4O/hyRtToEt6m/whHCkZZs6Kms8zkxjnPCck/img.png?width=626&amp;amp;height=473&amp;amp;face=0_0_626_473,https://scrap.kakaocdn.net/dn/baTgur/hyRvnIq5iM/FKZednoCx9zPOzs90RoFX0/img.png?width=1194&amp;amp;height=984&amp;amp;face=0_0_1194_984');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;원클릭 모니터변경 종결 (다중모니터,해상도,주사율,배율,회전,위치,...)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[서론 및 소개] [사용법] [서론 및 소개] 원격 제어를 애용하면서 그동안 사용했던 모니터 설정 방법을 공유했었다. PC에 모니터를 3개나 연결해보면서 원하는 모니터 그룹만 켜두는 것이 Windows 기&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ydeer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위&amp;nbsp;포스트에서&amp;nbsp;소개한&amp;nbsp;기능이&amp;nbsp;더&amp;nbsp;강력하므로,&amp;nbsp;위의&amp;nbsp;포스트를&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;제목 없음-1 사본.png&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;752&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FXxKO/btrDy0A8QlQ/HUrzjeoO6YUibHNULpofmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FXxKO/btrDy0A8QlQ/HUrzjeoO6YUibHNULpofmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FXxKO/btrDy0A8QlQ/HUrzjeoO6YUibHNULpofmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFXxKO%2FbtrDy0A8QlQ%2FHUrzjeoO6YUibHNULpofmk%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;724&quot; height=&quot;752&quot; data-filename=&quot;제목 없음-1 사본.png&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;752&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디스플레이 설정의 &quot;&lt;b&gt;텍스트, 앱 및 기타 항목의 크기 변경&lt;/b&gt;&quot; 부분을 원클릭으로 수정하는 파일들입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DPI라고도 부르는 부분입니다.&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 8~10까지는 동작 확인했으며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Microsoft 문서에서 &lt;b&gt;사용하지 않도록&lt;/b&gt; 권장하는 기능이라 향후 Windows 버전에 따라 작동하지 않을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-systemparametersinfoa&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;b&gt;SPI_SETLOGICALDPIOVERRIDE(=0x009F)&lt;/b&gt;는 Do not use로 되어있습니다.)&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;문서를 뒤져도 다른 버전의 DPI 세팅 기능은 없는 것 같고...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 지금의 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;주모니터만&lt;/span&gt; 수정할 수 있는 것 외에 다른 모니터는 수정이 안됩니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주모니터 외의 다른 모니터의 DPI를 원클릭으로 수정하길 원하는건... 저도 잘 모르겠습니다.ㅠ&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;사실 DPI는 설정에서 바꾼다고 하더라도&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 기능은 아래 개발자분의 코드와 위의 MSDN을 참고하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;a href=&quot;https://youtu.be/wA1Geom1NiA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://youtu.be/wA1Geom1NiA&lt;/a&gt;)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=wA1Geom1NiA&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/CIzy2/hyOzJIWrai/4WJMtYpPorxLSZg22b8381/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/wA1Geom1NiA&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에 설명드릴 사용법이 난해하실 분을 위해,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 아래에 Sample.zip을 첨부하니, 그걸 바로 사용하셔도 됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해상도&amp;nbsp;조절을&amp;nbsp;위해&amp;nbsp;윈도우&amp;nbsp;기본&amp;nbsp;내장&amp;nbsp;PowerShell과&amp;nbsp;cmd명령구문을&amp;nbsp;사용할겁니다.&lt;br /&gt;먼저, &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;아래 파일을 다운 받거나,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bqzrjP/btrDttEltlj/k98PQsh5C2WiBuPp8S2c5K/Set-DPI.ps1?attach=1&amp;amp;knm=tfile.ps1&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;Set-DPI.ps1&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빈 메모장을 연 후, 아래와 같이 입력하고, UTF-8로 &lt;b&gt;Set-DPI.ps1&lt;/b&gt; 라는 이름으로 파일을 저장합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1653902107215&quot; class=&quot;prettyprint lang-cpp c++ cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;Function Set-DPI { 
param ( 
[Parameter(Mandatory=$true, 
           Position = 0)] 
[int] 
$scaling
) 
$pinvokeCode = @&quot; 
using System; 
using System.Runtime.InteropServices; 
namespace DPI
{ 
    public class SetDPI
    { 
        [DllImport(&quot;user32.dll&quot;, EntryPoint = &quot;SystemParametersInfo&quot;)]
        public static extern bool SystemParametersInfo(
            uint uiAction,
            uint uiParam,
            uint pvParam,
            uint fWinIni);
    } 
} 
&quot;@ 
Add-Type $pinvokeCode -ErrorAction SilentlyContinue 
[DPI.SetDPI]::SystemParametersInfo(0x009F,$scaling,$null,1) 
}&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;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;아래 파일도 다운받거나,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/kC790/btrDyGwbAKc/yYUSXtbbMmG35HLOaF9S8K/DPI_100.ps1?attach=1&amp;amp;knm=tfile.ps1&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;DPI_100.ps1&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/kRMXX/btrDy1GQGnX/ZMKvxZMxwa5mIZMqqIhOFK/DPI_125.ps1?attach=1&amp;amp;knm=tfile.ps1&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;DPI_125.ps1&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/QCuq0/btrDzlE3VqI/4sPcGK3O42AVICjLVGg7S1/DPI_150.ps1?attach=1&amp;amp;knm=tfile.ps1&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;DPI_150.ps1&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bxYODl/btrDynjktDu/vrXjkOYbAqBjo9KIWs1171/DPI_175.ps1?attach=1&amp;amp;knm=tfile.ps1&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;DPI_175.ps1&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빈&amp;nbsp;메모장을&amp;nbsp;열고&amp;nbsp;아래와&amp;nbsp;같이&amp;nbsp;적습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1653902223385&quot; class=&quot;prettyprint lang-cpp c++ cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;. $PSScriptRoot\Set-DPI.ps1

Set-DPI 0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(100%는 0,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;125%는 1,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;150%는 2,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;175%는 3)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 원하는 UTF-8로 &lt;b&gt;파일명.ps&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;b&gt;Set-DPI.ps1 과 같은 곳&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;color: #006dd7;&quot;&gt;&lt;b&gt;아래 파일도 다운받거나,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/su4Y2/btrDxnYea1R/zV9LpXCMLXY1lk4Q0gsJgk/DPI_100.bat?attach=1&amp;amp;knm=tfile.bat&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;DPI_100.bat&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/csnbSt/btrDyxlDQGU/kDs3NeAxILzQlfImyBqwb0/DPI_125.bat?attach=1&amp;amp;knm=tfile.bat&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;DPI_125.bat&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/bhAUES/btrDAjto8JB/iAv9jWeIZtKukpUZlV1U30/DPI_150.bat?attach=1&amp;amp;knm=tfile.bat&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;DPI_150.bat&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/DqQKe/btrDyn4INSJ/ZpuJZPkduT72KkdjSB5tFK/DPI_175.bat?attach=1&amp;amp;knm=tfile.bat&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;DPI_175.bat&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빈 메모장을 열고 아래와 같이 접습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1653902392499&quot; class=&quot;prettyprint lang-cpp c++ cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;@echo off
Powershell.exe -noprofile -executionpolicy bypass -file DPI_100.ps1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막의 &quot;DPI_100.ps1&quot; 부분이 위에서 작성한 파일명과 일치하도록 해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것도 아까의 &lt;b&gt;ps1 파일들과 같은 곳&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;그리고 이 bat파일을 실행하기만 하면 주모니터의 DPI가 바뀝니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;윈도우 시작 메뉴에 두고 싶으시면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bat파일의 바로가기를&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C(윈도우설치드라이브):\Users\로그온한사용자\AppData\Roaming\Microsoft\Windows\Start&amp;nbsp;Menu\Programs&lt;br /&gt;에 만들어주고, 모든 앱 보기 상태에서 타일 메뉴에 등록을 하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&lt;a title=&quot;원클릭 해상도 포스트 링크&quot; href=&quot;https://ydeer.tistory.com/102&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;원클릭 해상도 포스트 참고&lt;/a&gt;)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;ps1 파일들은 그대로 내버려두고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;bat 파일을 입맛에 맞게 수정하면 됩니다.&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;pre id=&quot;code_1653903415744&quot; class=&quot;prettyprint lang-cpp c++ cpp&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;cpp&quot;&gt;&lt;code&gt;@echo off
D:\~~~\display.exe /device:1 /rotate:0
timeout 2
Powershell.exe -noprofile -executionpolicy bypass -file 1280_960.ps1
Powershell.exe -noprofile -executionpolicy bypass -file DPI_125.ps1&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;해상도를 바꾸는 ps1을 실행한 후 곧바로 배율을 바꾸는 ps1도 실행합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(회전이 완료되어야 가로모드에 맞는 해상도를 선택할 수 있으므로, 2초 기다리는 부분 있음)&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;원하시는 대로 bat을 작성하시길 바랍니다 :D&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;fileblock&quot; data-ke-align=&quot;alignCenter&quot;&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/b4MOps/btrDywAgUps/cvoEoxxAANqMZfOXpQAjK0/Sample.zip?attach=1&amp;amp;knm=tfile.zip&quot; class=&quot;&quot;&gt;
    &lt;div class=&quot;image&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;desc&quot;&gt;&lt;div class=&quot;filename&quot;&gt;&lt;span class=&quot;name&quot;&gt;Sample.zip&lt;/span&gt;&lt;/div&gt;
&lt;div class=&quot;size&quot;&gt;0.00MB&lt;/div&gt;
&lt;/div&gt;
  &lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; 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;</description>
      <category>PC원격제어/help</category>
      <category>Bat</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/284</guid>
      <comments>https://ydeer.tistory.com/284#entry284comment</comments>
      <pubDate>Mon, 30 May 2022 18:23:44 +0900</pubDate>
    </item>
    <item>
      <title>이미지로 보는 Git 개념서</title>
      <link>https://ydeer.tistory.com/279</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blackdeery.github.io/guide/git/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blackdeery.github.io/guide/git/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640161367666&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;이미지로 보는 Git 개념서 - 현록&quot; data-og-description=&quot;이미지로 보는 Git 개념서 - 현록&quot; data-og-host=&quot;blackdeery.github.io&quot; data-og-source-url=&quot;https://blackdeery.github.io/guide/git/&quot; data-og-url=&quot;https://blackdeery.github.io/guide/git/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bfZ2q4/hyMOjD0Npb/YcpataCrxepM7VaUByz4UK/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://blackdeery.github.io/guide/git/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blackdeery.github.io/guide/git/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bfZ2q4/hyMOjD0Npb/YcpataCrxepM7VaUByz4UK/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;이미지로 보는 Git 개념서 - 현록&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미지로 보는 Git 개념서 - 현록&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blackdeery.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차의 편의성을 위해 Tistory가 아닌 웹페이지에 작성하였습니다.&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;Git을 반드시 CLI로 할 필요는 없다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GUI에서는 &lt;a href=&quot;https://www.sourcetreeapp.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Sourcetree&lt;/a&gt;를 비롯한 좋은 툴이 있습니다.(저는 Sourcetree를 애용합니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Visual Studio, intelliJ 등에도 기능이 내장되어 있습니다.&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;CLI든 GUI든 개념만 잡히면 사용하는 것은 어렵지 않은데,&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;&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://backlog.com/git-tutorial/kr/contents/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://backlog.com/git-tutorial/kr/contents/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640161525667&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;누구나 쉽게 이해할 수 있는 Git 입문~버전 관리를 완벽하게 이용해보자~ | Backlog&quot; data-og-description=&quot;누구나 쉽게 알 수 있는 Git에 입문하신 것을 환영합니다. Git을 사용해 버전 관리를 할 수 있도록 함께 공부해봅시다!&quot; data-og-host=&quot;backlog.com&quot; data-og-source-url=&quot;https://backlog.com/git-tutorial/kr/contents/&quot; data-og-url=&quot;https://backlog.com/git-guide/kr/contents/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://backlog.com/git-tutorial/kr/contents/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://backlog.com/git-tutorial/kr/contents/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;누구나 쉽게 이해할 수 있는 Git 입문~버전 관리를 완벽하게 이용해보자~ | Backlog&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;누구나 쉽게 알 수 있는 Git에 입문하신 것을 환영합니다. Git을 사용해 버전 관리를 할 수 있도록 함께 공부해봅시다!&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;backlog.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;a href=&quot;https://git-scm.com/doc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://git-scm.com/doc&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1640161546763&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Git - Documentation&quot; data-og-description=&quot;Documentation Reference The official and comprehensive man pages that are included in the Git package itself. Quick reference guides: GitHub Cheat Sheet | Visual Git Cheat Sheet Book Videos Length: 05:59 Length: 04:26 What is Git? Length: 08:15 Length: 05:&quot; data-og-host=&quot;git-scm.com&quot; data-og-source-url=&quot;https://git-scm.com/doc&quot; data-og-url=&quot;https://git-scm.com/doc&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://git-scm.com/doc&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://git-scm.com/doc&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Git - Documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Documentation Reference The official and comprehensive man pages that are included in the Git package itself. Quick reference guides: GitHub Cheat Sheet | Visual Git Cheat Sheet Book Videos Length: 05:59 Length: 04:26 What is Git? Length: 08:15 Length: 05:&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;git-scm.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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>Study/Git</category>
      <category>git</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/279</guid>
      <comments>https://ydeer.tistory.com/279#entry279comment</comments>
      <pubDate>Wed, 22 Dec 2021 17:24:14 +0900</pubDate>
    </item>
    <item>
      <title>Tistory Replace</title>
      <link>https://ydeer.tistory.com/271</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;티스토리 에디터에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;html로 편집해도 기본모드로 전환하면 html을 멋대로 박살내버리는걸 이겨버리기 위해&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;a href=&quot;https://blackdeery.github.io/tistory_replace/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blackdeery.github.io/tistory_replace/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1621260509437&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Tistory Replace - 현록&quot; data-og-description=&quot;Tistory Replace - 현록&quot; data-og-host=&quot;blackdeery.github.io&quot; data-og-source-url=&quot;https://blackdeery.github.io/tistory_replace/&quot; data-og-url=&quot;https://blackdeery.github.io/tistory_replace/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/d7uZ7L/hyKe1sOGJp/EPFoG0vbziqJRQteB4Dya0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/YNHEs/hyKe5vcVxE/VEStikwxIiYz15r4EcCuI0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://blackdeery.github.io/tistory_replace/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://blackdeery.github.io/tistory_replace/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/d7uZ7L/hyKe1sOGJp/EPFoG0vbziqJRQteB4Dya0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/YNHEs/hyKe5vcVxE/VEStikwxIiYz15r4EcCuI0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Tistory Replace - 현록&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Tistory Replace - 현록&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;blackdeery.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&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;</description>
      <category>Programs/release</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/271</guid>
      <comments>https://ydeer.tistory.com/271#entry271comment</comments>
      <pubDate>Mon, 17 May 2021 23:10:53 +0900</pubDate>
    </item>
    <item>
      <title>마트휴일 AI 스피커가 말해주기 (Google Action)</title>
      <link>https://ydeer.tistory.com/270</link>
      <description>&lt;p&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/5Ku3_rgrsAo&quot; width=&quot;560&quot; height=&quot;315&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;구글 홈 미니에 음성으로 마트휴일을 물어볼 수 있도록 Google Action 프로젝트를 생성했다.&lt;/p&gt;
&lt;p&gt;(배포하지 않고 가족만 테스터로 초대하여 사용 중이다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;모바일 앱에서는 음성으로 물으면 텍스트와 음성으로 답해주고, 타이핑하면 그냥 텍스트로만 보여준다.&lt;/p&gt;
&lt;p&gt;아마 디스플레이가 있는 구글 네스트 허브 역시 마찬가지일 듯 싶다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;젊은 세대는 그냥 바로 모바일 지도 앱을 열어서 해당 점포가 휴점인지 보겠지만,&lt;/p&gt;
&lt;p&gt;어머니는 좀 느리고 불편해하셔서 &lt;b&gt;말로 편하게 알 수 있도록 하기 위해&lt;/b&gt; 만들었다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래서 부모님 댁 근처의 백화점 및 마트만 구성했으며,&lt;/p&gt;
&lt;p&gt;&quot;홈플러스 울산남구점&quot;처럼 묻는 것이 아니라,&lt;/p&gt;
&lt;p&gt;그냥 &quot;홈플러스&quot; 정도의 &lt;b&gt;최소한의 질문으로 동작하도록&lt;/b&gt; 하였다.&lt;/p&gt;
&lt;p&gt;그래서 노브랜드는 엄청 지점이 많아졌는데, 어머니가 잘 다니시지 않는 관계로 우선 저대로 두었다.&lt;/p&gt;
&lt;p&gt;(나중에 여쭤보고 다니신다면 다니시는 곳만 나오게 하든가 해야겠다.)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;홈서버에서 매일 오전 11시에&lt;/p&gt;
&lt;p&gt;백화점이나 마트의 API를 이용하거나, 웹 크롤러로 휴점일 내용을 긁어서 저장해두는 것을 &lt;b&gt;cron&lt;/b&gt;으로 하고 있고,&lt;/p&gt;
&lt;p&gt;Google Action Project에서는 특정 브랜드를 물을 때, 홈서버의 &lt;b&gt;HTTPS REST Controller&lt;/b&gt;를 통해 정보를 가져와 말해준다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Actions on Google Project&lt;/p&gt;
&lt;p&gt;- Platform: All Google Assistant Device(Speaker, Text)&lt;/p&gt;
&lt;p&gt;- Framework: Spring Boot 2.4.5&lt;/p&gt;
&lt;p&gt;- Language: Java 1.8&lt;/p&gt;
&lt;p&gt;- Web Crawler: Selenium&lt;/p&gt;
&lt;p&gt;- IDE: IntelliJ IDEA&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;물론 REST API로 만들었기 때문에 가족용 모바일 웹페이지에도 사용 중&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-filename=&quot;RPReplay_Final1620708028.gif&quot; data-origin-width=&quot;295&quot; data-origin-height=&quot;585&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwxqan/btq4DjuTi2P/VmsFVbRu1yPPGskwvnCiX0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwxqan/btq4DjuTi2P/VmsFVbRu1yPPGskwvnCiX0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwxqan/btq4DjuTi2P/VmsFVbRu1yPPGskwvnCiX0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bwxqan/btq4DjuTi2P/VmsFVbRu1yPPGskwvnCiX0/img.gif&quot; data-filename=&quot;RPReplay_Final1620708028.gif&quot; data-origin-width=&quot;295&quot; data-origin-height=&quot;585&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Diary</category>
      <category>ai speaker</category>
      <category>IOT</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/270</guid>
      <comments>https://ydeer.tistory.com/270#entry270comment</comments>
      <pubDate>Tue, 11 May 2021 02:04:19 +0900</pubDate>
    </item>
    <item>
      <title>iOS 단축어, Siri로 Smartthings 기기 제어 (REST API)</title>
      <link>https://ydeer.tistory.com/269</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;- 본 포스트에서는 Smartthings 기기를 iOS/iPadOS의 단축어 또는 Siri로 제어하는 옵션을 추가하는 내용에 대해 다룹니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Google Assistant를 이용한 구글홈 기기 제어와는 달리, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;잠금 상태 및 AppleWatch 및 HomePod에서도 사용 가능합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 응용으로 자동화(Rule)를 제어할 수도 있으나, 여기에 대해서 다루진 않겠습니다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://account.smartthings.com/tokens&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://account.smartthings.com/tokens&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저, 위의 링크를 클릭하여 Smartthings를 사용하고 있는 계정으로 로그인합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;st01.gif&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0DcU2/btq4q3sQLD2/zBg5vqd7HmskbTwe7lmNTK/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0DcU2/btq4q3sQLD2/zBg5vqd7HmskbTwe7lmNTK/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0DcU2/btq4q3sQLD2/zBg5vqd7HmskbTwe7lmNTK/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/c0DcU2/btq4q3sQLD2/zBg5vqd7HmskbTwe7lmNTK/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;707&quot; height=&quot;362&quot; data-filename=&quot;st01.gif&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새 토큰 만들기를 누릅니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;st02.png&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;880&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/D4l6D/btq4uIOOkIr/WjKV4CEA5HCbUTN0kOnnE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/D4l6D/btq4uIOOkIr/WjKV4CEA5HCbUTN0kOnnE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/D4l6D/btq4uIOOkIr/WjKV4CEA5HCbUTN0kOnnE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FD4l6D%2Fbtq4uIOOkIr%2FWjKV4CEA5HCbUTN0kOnnE1%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;692&quot; height=&quot;880&quot; data-filename=&quot;st02.png&quot; data-origin-width=&quot;692&quot; data-origin-height=&quot;880&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;/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;모든 디바이스 표시, 모든 디바이스 제어&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모든 디바이스 표시(&lt;i&gt;l:devices&lt;/i&gt;)&lt;/b&gt;만을 갖는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&quot;조회용 토큰&quot;&lt;/b&gt;&lt;/span&gt;을 하나 발급하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;모든 디바이스 제어(&lt;i&gt;x:devices:*&lt;/i&gt;)&lt;/b&gt;만을 갖는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&quot;제어용 토큰&quot;&lt;/b&gt;&lt;/span&gt;을 하나 발급합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;st03.gif&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;655&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eOpexA/btq4t4K5x30/thor1uZRPH87ADXkv1klk1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eOpexA/btq4t4K5x30/thor1uZRPH87ADXkv1klk1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eOpexA/btq4t4K5x30/thor1uZRPH87ADXkv1klk1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/eOpexA/btq4t4K5x30/thor1uZRPH87ADXkv1klk1/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;707&quot; height=&quot;655&quot; data-filename=&quot;st03.gif&quot; data-origin-width=&quot;707&quot; data-origin-height=&quot;655&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;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 이 토큰을 갖고 Smartthings의 REST API를 사용할겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.smartthings.com/docs/api/public/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developer.smartthings.com/docs/api/public/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 포스트에서 다루는 내용 외에도 많은 기능을 제공하고 있으니, 살펴보시는 것도 좋습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;&quot;조회용 토큰&quot;&lt;/b&gt;&lt;/span&gt;(모든 디바이스 표시(&lt;i&gt;l:devices&lt;/i&gt;))을&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://blackdeery.github.io/st_helper/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://blackdeery.github.io/st_helper/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에 들어가서 붙여넣은 후, &lt;b&gt;장치 조회&lt;/b&gt;를 누릅니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 필요한건 &lt;b&gt;deviceId&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;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&quot;제어용 토큰&quot;&lt;/b&gt;&lt;/span&gt;(모든 디바이스 제어(&lt;i&gt;x:devices:*&lt;/i&gt;))과 &lt;b&gt;deviceId들&lt;/b&gt;을 iOS 단축어를 만들 때 사용해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- macOS이고 메모에서 서로 iCloud 연동을 사용한다면, 메모앱에 붙여넣어주면 iOS의 메모앱에서 복사하기 편합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- macOS이고 서로 HandOff를 사용한다면, mac에서 복사한 항목을 그대로 iOS에서 붙여넣기 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- iOS라면 바로 붙여넣어 사용할 수 있도록 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 그 외 OS라면 &lt;a href=&quot;https://www.icloud.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/&lt;/a&gt;로 접속하여, 메모에 붙여넣은 후, iOS에 메모앱에서 복사합니다. (메모앱에서 iCloud 사용 필요)&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;장치 요소&lt;/b&gt;들을 볼 수 있는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;switch를 갖고 있으면 on/off가 가능하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;thermostatHeatingSetpoint를 갖고 있으면 난방기의 온도 설정이 가능하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fanSpeed를 갖고 있으면 풍속을 1~3단계 조절이 가능하고, ...&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;(본 포스트에서는 일부 capability만 제공합니다.)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;curl&amp;nbsp;-X&amp;nbsp;&quot;GET&quot;&amp;nbsp;&quot;https://api.smartthings.com/v1/capabilities/&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;이름&lt;/span&gt;/&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;버전&lt;/span&gt;&quot;&amp;nbsp;-H&amp;nbsp;&quot;Authorization:&amp;nbsp;Bearer&amp;nbsp;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;토큰&lt;/span&gt;&quot;&amp;nbsp;-H&amp;nbsp;&quot;Content-Type:&amp;nbsp;application/json;&amp;nbsp;charset=utf-8&quot;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령으로 capability의 조회가 가능합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 예시처럼 필요한 항목을 채워넣어 줍니다.&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; 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: 100%;&quot;&gt;&lt;p&gt;curl&amp;nbsp;-X&amp;nbsp;&quot;GET&quot;&amp;nbsp;&quot;https://api.smartthings.com/v1/capabilities/&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;thermostatHeatingSetpoint&lt;/span&gt;/&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;1&lt;/span&gt;&quot;&amp;nbsp;-H&amp;nbsp;&quot;Authorization:&amp;nbsp;Bearer&amp;nbsp;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;********-****-****-****-************&lt;/span&gt;&quot;&amp;nbsp;-H&amp;nbsp;&quot;Content-Type:&amp;nbsp;application/json;&amp;nbsp;charset=utf-8&quot;&lt;/p&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 통해 얻은 상세정보를 갖고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 링크의 문서 양식과 대조하여 원하는 항목을 채워넣어 JSON을 형성하면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://smartthings.developer.samsung.com/docs/devices/smartthings-schema/smartthings-schema-reference.html#Command&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://smartthings.developer.samsung.com/docs/devices/smartthings-schema/smartthings-schema-reference.html#Command&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iPhone/iPad에서 아래의 링크들로 접속하여, 단축어 견본을 내려받습니다.&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;switch를 갖는 기기의 &lt;b&gt;켜기(on)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/24431bc923b948999c4d8159d5ddb3ec&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/shortcuts/24431bc923b948999c4d8159d5ddb3ec&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축어를 가져올 때, &lt;b&gt;deviceId&lt;/b&gt;와 &lt;b&gt;토큰&lt;/b&gt;을 입력해주시면 양식이 완성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(텍스트 on 대신 off로 수정 가능.)&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;switch를 갖는 기기의 &lt;b&gt;끄기(off)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/201fad930fb94ffda6a3eddf2e9453db&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/shortcuts/201fad930fb94ffda6a3eddf2e9453db&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축어를 가져올 때,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;deviceId&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;토큰&lt;/b&gt;을 입력해주시면 양식이 완성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(텍스트 off 대신 on으로 수정 가능.)&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;thermostatMode를 갖는 기기의 &lt;b&gt;난방모드(heat)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/ef6db3ba8cc74a27ba5acecb4d3992ec&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/shortcuts/ef6db3ba8cc74a27ba5acecb4d3992ec&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축어를 가져올 때,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;deviceId&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;토큰&lt;/b&gt;을 입력해주시면 양식이 완성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(텍스트 heat 대신 다른 모드 수정 가능.&amp;nbsp;하지만&amp;nbsp;기기에서&amp;nbsp;모든&amp;nbsp;동작을&amp;nbsp;지원하지&amp;nbsp;않을&amp;nbsp;수도&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;thermostatMode를 갖는 기기의 &lt;b&gt;외출모드(eco)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/2c6a71b15bf94f05ad7dbcc5fb62a0b3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/shortcuts/2c6a71b15bf94f05ad7dbcc5fb62a0b3&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축어를 가져올 때,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;deviceId&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;토큰&lt;/b&gt;을 입력해주시면 양식이 완성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(텍스트 eco 대신 다른 모드 수정 가능.&amp;nbsp;하지만&amp;nbsp;기기에서&amp;nbsp;모든&amp;nbsp;동작을&amp;nbsp;지원하지&amp;nbsp;않을&amp;nbsp;수도&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;thermostatHeatingSetpoint를 갖는 기기의 &lt;b&gt;목표 온도 설정(setHeatingSetpoint)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/01d39c1b63ba4c7e91f871f76d0075d3&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/shortcuts/01d39c1b63ba4c7e91f871f76d0075d3&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축어를 가져올 때, &lt;b&gt;deviceId&lt;/b&gt;와 &lt;b&gt;토큰&lt;/b&gt;과 &lt;b&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;fanSpeed를 갖는 기기의 &lt;b&gt;풍속 설정(setFanSpeed) - 강풍(3)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/cd8dbbac078d4cf2a99ae8c5485d4e6e&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/shortcuts/cd8dbbac078d4cf2a99ae8c5485d4e6e&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축어를 가져올 때,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;deviceId&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;토큰&lt;/b&gt;을 입력해주시면 양식이 완성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(숫자 3 대신 1~3의 숫자로 수정하여 풍속 수정 가능.)&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;valve를 갖는 기기의 &lt;b&gt;밸브 잠그기(close)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/dc1d54866f014a82be96f4b405ff43b9&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/shortcuts/dc1d54866f014a82be96f4b405ff43b9&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축어를 가져올 때,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;deviceId&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;토큰&lt;/b&gt;을 입력해주시면 양식이 완성됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(텍스트 close 대신 open으로 수정 가능. 하지만 기기에서 모든 동작을 지원하지 않을 수도 있음.)&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;elevatorCall을 갖는 기기의 &lt;b&gt;엘리베이터 호출(call)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/5bc64ca53a8a4daca04f660dc5e6ac48&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/shortcuts/5bc64ca53a8a4daca04f660dc5e6ac48&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단축어를 가져올 때,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;deviceId&lt;/b&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;토큰&lt;/b&gt;을 입력해주시면 양식이 완성됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 내려받은 단축어를 수정할겁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(Siri용 문구 설정 및 추가 옵션)&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;IMG_1138.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzIc2/btq4sp3sYbW/DrHUjK4UyqvRg2JcYbjW9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzIc2/btq4sp3sYbW/DrHUjK4UyqvRg2JcYbjW9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzIc2/btq4sp3sYbW/DrHUjK4UyqvRg2JcYbjW9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkzIc2%2Fbtq4sp3sYbW%2FDrHUjK4UyqvRg2JcYbjW9K%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;375&quot; height=&quot;811&quot; data-filename=&quot;IMG_1138.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오른쪽 위의 &lt;span style=&quot;line-height: 3rem; width: 3rem; background-color: #3b82f6; border-radius: 50%; display: inline-block;&quot;&gt;&lt;span style=&quot;height: 0.5rem; width: 0.5rem; background-color: #000000; border-radius: 50%; display: inline-block; margin-left: 0.55rem; margin-right: 0.1rem;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;height: 0.5rem; width: 0.5rem; background-color: #000000; border-radius: 50%; display: inline-block; margin-left: 0.1rem; margin-right: 0.1rem;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;height: 0.5rem; width: 0.5rem; background-color: #000000; border-radius: 50%; display: inline-block; margin-left: 0.1rem; margin-right: 0.1rem;&quot;&gt;&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&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthContent&quot; data-filename=&quot;IMG_1137.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/usWNz/btq4z1Ux96G/1kJNz3kKG9d2SiamiLTjE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/usWNz/btq4z1Ux96G/1kJNz3kKG9d2SiamiLTjE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/usWNz/btq4z1Ux96G/1kJNz3kKG9d2SiamiLTjE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FusWNz%2Fbtq4z1Ux96G%2F1kJNz3kKG9d2SiamiLTjE0%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;375&quot; height=&quot;811&quot; data-filename=&quot;IMG_1137.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&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;Siri야, [제목]&lt;/b&gt;으로 불릴 수 있도록 해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;단, &quot;거실 전등 켜줘&quot; 같은 보편적인 내용은 Siri가 애플홈을 우선적으로 인식하려고 하기 때문에,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;라이언 전등 켜줘&quot; 같이 &lt;b&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;- 홈 화면에 앱 버튼처럼 단축 버튼을 만드시려면 &quot;홈 화면에 추가&quot;를 눌러서 추가하시면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Apple Watch의 단축어에서 목록에 뜨게 하려면, Apple Watch에서 보기를 켜줍니다.&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>IoT</category>
      <category>IOS</category>
      <category>IOT</category>
      <category>Siri</category>
      <category>smartthings</category>
      <category>단축어</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/269</guid>
      <comments>https://ydeer.tistory.com/269#entry269comment</comments>
      <pubDate>Sun, 9 May 2021 19:18:03 +0900</pubDate>
    </item>
    <item>
      <title>iOS 단축어, Siri로 구글홈 기기 제어 (Google Assistant)</title>
      <link>https://ydeer.tistory.com/268</link>
      <description>&lt;p&gt;- 본 포스트에서는 구글홈 기기를 iOS/iPadOS의 단축어 또는 Siri로 제어하는 옵션을 추가하는 내용에 대해 다룹니다.&lt;/p&gt;
&lt;p&gt;- &lt;b&gt;App Store에서 Google의 Assistant 앱을 다운받아, 직접 특정 문구를 전달시켜서 제어&lt;/b&gt;합니다.&lt;/p&gt;
&lt;p&gt;- 이런 이유로 iPhone/iPad의 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;잠금이 해제된 상태에서만 가능&lt;/b&gt;&lt;/span&gt;합니다.&lt;/p&gt;
&lt;p&gt;- 같은 이유로 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;AppleWatch의 단축어에서는 눌러도 실행할 수 없습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;　(미러링된 iPhone에서 앱을 실행시켜야 하는 구조이나, 워치에서는 그럴 수 없기 때문)&lt;/p&gt;
&lt;p&gt;- 해당 IoT 기기가 Samsung의 Smartthings에 연동가능하다면,&lt;/p&gt;
&lt;p&gt;　아래의 링크를 참조하여, Smartthings용으로 생성해두면 잠금상태이건 워치에서건 가능합니다.&lt;/p&gt;
&lt;p&gt;　&lt;a href=&quot;https://ydeer.tistory.com/269&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;[IoT] - iOS 단축어, Siri로 Smartthings 기기 제어 (REST API)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;　(Smartthings는 REST API를 지원하지만, Google은 그렇지 않음)&lt;/p&gt;
&lt;p&gt;　(Smartthings에서 보이스 어시스턴트로 Google Assistant를 추가하면, Google Home에서도 Smartthings 기기가 나타남)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-filename=&quot;IMG_1126.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boakHk/btq4qzL5mrc/KBY0wT2gMllfbjrGSxmF91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boakHk/btq4qzL5mrc/KBY0wT2gMllfbjrGSxmF91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boakHk/btq4qzL5mrc/KBY0wT2gMllfbjrGSxmF91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboakHk%2Fbtq4qzL5mrc%2FKBY0wT2gMllfbjrGSxmF91%2Fimg.png&quot; data-filename=&quot;IMG_1126.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;먼저 App Store에서 Google의 Assistant 앱을 내려받습니다.&lt;/p&gt;
&lt;p&gt;assistant로 검색하시면 됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;a href=&quot;https://www.icloud.com/shortcuts/d83088bffead47e2970eac43f0b1af08&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.icloud.com/shortcuts/d83088bffead47e2970eac43f0b1af08&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;iPhone/iPad에서 위의 링크로 접속하여, 단축어 견본을 내려받습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;내려받을 때 어떤 문구를 Google Assistant에 보내어 제어할지 묻습니다.&lt;/p&gt;
&lt;p&gt;입력해주시면 되고,&lt;/p&gt;
&lt;p&gt;입력하지 않고 넘어갔어도 수정 가능합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-filename=&quot;IMG_1127.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bqrZMQ/btq4qAEgUXz/TEDyyOsN0PE7Hm17v78fz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bqrZMQ/btq4qAEgUXz/TEDyyOsN0PE7Hm17v78fz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bqrZMQ/btq4qAEgUXz/TEDyyOsN0PE7Hm17v78fz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqrZMQ%2Fbtq4qAEgUXz%2FTEDyyOsN0PE7Hm17v78fz1%2Fimg.png&quot; data-filename=&quot;IMG_1127.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;단축어의 구성은 간단합니다.&lt;/p&gt;
&lt;p&gt;question에 Google Assistant에게 전달할 문구가 들어갑니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이제 오른쪽 위의 &lt;span style=&quot;line-height: 3rem; width: 3rem; background-color: #3b82f6; border-radius: 50%; display: inline-block;&quot;&gt;&lt;span style=&quot;height: 0.5rem; width: 0.5rem; background-color: #000000; border-radius: 50%; display: inline-block; margin-left: 0.55rem; margin-right: 0.1rem;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;height: 0.5rem; width: 0.5rem; background-color: #000000; border-radius: 50%; display: inline-block; margin-left: 0.1rem; margin-right: 0.1rem;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;height: 0.5rem; width: 0.5rem; background-color: #000000; border-radius: 50%; display: inline-block; margin-left: 0.1rem; margin-right: 0.1rem;&quot;&gt;&lt;/span&gt;&lt;/span&gt;을 눌러, 세부 사항 수정으로 넘어갑니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-filename=&quot;IMG_1128.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQAIvV/btq4p79Yd6i/GBnyQlQ5SARK8EnK0xkkHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQAIvV/btq4p79Yd6i/GBnyQlQ5SARK8EnK0xkkHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQAIvV/btq4p79Yd6i/GBnyQlQ5SARK8EnK0xkkHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQAIvV%2Fbtq4p79Yd6i%2FGBnyQlQ5SARK8EnK0xkkHk%2Fimg.png&quot; data-filename=&quot;IMG_1128.png&quot; data-origin-width=&quot;375&quot; data-origin-height=&quot;811&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;google_assistant-ex를 수정합니다.&lt;/p&gt;
&lt;p&gt;해당 내용은 &lt;b&gt;Siri야, [제목]&lt;/b&gt;으로 불릴 수 있도록 해줍니다.&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;단, &quot;거실 전등 켜줘&quot; 같은 보편적인 내용은 Siri가 애플홈을 우선적으로 인식하려고 하기 때문에,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&quot;라이언 전등 켜줘&quot; 같이 &lt;b&gt;앞에 특정한 단어들을 고려&lt;/b&gt;해보시기 바랍니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- 홈 화면에 앱 버튼처럼 단축 버튼을 만드시려면 &quot;홈 화면에 추가&quot;를 눌러서 추가하시면 됩니다.&lt;/p&gt;
&lt;p&gt;- 맨 위에서 언급했듯이, 어차피 Apple Watch에서는 사용할 수 없습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IoT</category>
      <category>google assistant</category>
      <category>Google Home</category>
      <category>IOS</category>
      <category>IOT</category>
      <category>Siri</category>
      <category>단축어</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/268</guid>
      <comments>https://ydeer.tistory.com/268#entry268comment</comments>
      <pubDate>Sun, 9 May 2021 13:40:29 +0900</pubDate>
    </item>
    <item>
      <title>DuckDNS, Let's Encrypt</title>
      <link>https://ydeer.tistory.com/267</link>
      <description>&lt;p&gt;[DuckDNS 5분마다 자동갱신]&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.duckdns.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.duckdns.org/&lt;/a&gt;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;%&lt;/span&gt;&amp;nbsp;crontab -e&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;*/5 * * * * &lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;i&gt;sh파일경로&lt;/i&gt;&lt;/span&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;sh파일내용&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;echo url=&quot;https://www.duckdns.org/update?domains=&lt;i&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;도메인앞부분&lt;/span&gt;&lt;/i&gt;&amp;amp;token=&lt;i&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;토큰&lt;/span&gt;&lt;/i&gt;&amp;amp;ip=&quot; | curl -k -o &lt;span style=&quot;background-color: #99cefa; color: #000000;&quot;&gt;~/duckdns/duck.log&lt;/span&gt; -K -&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;로그파일 내용은, 갱신에 성공하면 OK, 실패하면 KO.&lt;/p&gt;
&lt;p&gt;(요청이 잦아서인지 가끔 502 Bad Gateway가 뜨기도 하는데,&lt;/p&gt;
&lt;p&gt;DuckDNS의 install부분에서 5분마다를 지침으로 하고 있어서 그대로 따름)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;[Let's Encrypt]&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;%&lt;/span&gt; brew install certbot&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;%&lt;/span&gt; sudo certbot certonly -a standalone -d &lt;i&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;도메인&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p&gt;매월 1일 새벽3시 갱신요청 및 pkcs12 인증서 생성&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;%&lt;/span&gt; sudo crontab -e&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;0 18 1 * * &lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;i&gt;sh파일경로&lt;/i&gt;&lt;/span&gt; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;sh파일내용&lt;/p&gt;
&lt;table class=&quot;cmdTable&quot; style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 100%;&quot;&gt;
&lt;p&gt;/usr/local/bin/certbot&amp;nbsp;renew&lt;/p&gt;
&lt;p&gt;/usr/bin/openssl pkcs12 -export -in /etc/letsencrypt/live/&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;i&gt;도메인&lt;/i&gt;&lt;/span&gt;/fullchain.pem -inkey /etc/letsencrypt/live/&lt;i&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;도메인&lt;/span&gt;&lt;/i&gt;/privkey.pem -out &lt;i&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;파일명.p12&lt;/span&gt;&lt;/i&gt; -name bootalias -CAfile /etc/letsencrypt/live/&lt;i&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;도메인&lt;/span&gt;&lt;/i&gt;/chain.pem -caname root -passin pass:&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;&lt;i&gt;비밀번호&lt;/i&gt;&lt;/span&gt; -passout pass:&lt;i&gt;&lt;span style=&quot;background-color: #f6e199; color: #000000;&quot;&gt;비밀번호&lt;/span&gt;&lt;/i&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Study/Linux／Unix／OSX</category>
      <category>DuckDNS</category>
      <category>letsencrypt</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/267</guid>
      <comments>https://ydeer.tistory.com/267#entry267comment</comments>
      <pubDate>Tue, 4 May 2021 16:31:04 +0900</pubDate>
    </item>
    <item>
      <title>[Lv3] 기둥과 보 설치</title>
      <link>https://ydeer.tistory.com/265</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/60061&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/60061&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1619078553416&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 기둥과 보 설치&quot; data-og-description=&quot;5 [[1,0,0,1],[1,1,1,1],[2,1,0,1],[2,2,1,1],[5,0,0,1],[5,1,0,1],[4,2,1,1],[3,2,1,1]] [[1,0,0],[1,1,1],[2,1,0],[2,2,1],[3,2,1],[4,2,1],[5,0,0],[5,1,0]] 5 [[0,0,0,1],[2,0,0,1],[4,0,0,1],[0,1,1,1],[1,1,1,1],[2,1,1,1],[3,1,1,1],[2,0,0,0],[1,1,1,0],[2,2,0,1]] [[&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60061&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60061&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cwKMIU/hyJXMpkAH3/KBT2br5xfOLUkEid1tdlQK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/ddJpbw/hyJXVfvNYA/1I9KzwczUqGErsdHppj0y1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cmvHbz/hyJXQechZB/ZkkExp1259mAYy0zXybTuk/img.jpg?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/60061&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60061&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cwKMIU/hyJXMpkAH3/KBT2br5xfOLUkEid1tdlQK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/ddJpbw/hyJXVfvNYA/1I9KzwczUqGErsdHppj0y1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cmvHbz/hyJXQechZB/ZkkExp1259mAYy0zXybTuk/img.jpg?width=1200&amp;amp;height=1200&amp;amp;face=0_0_1200_1200');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 기둥과 보 설치&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;5 [[1,0,0,1],[1,1,1,1],[2,1,0,1],[2,2,1,1],[5,0,0,1],[5,1,0,1],[4,2,1,1],[3,2,1,1]] [[1,0,0],[1,1,1],[2,1,0],[2,2,1],[3,2,1],[4,2,1],[5,0,0],[5,1,0]] 5 [[0,0,0,1],[2,0,0,1],[4,0,0,1],[0,1,1,1],[1,1,1,1],[2,1,1,1],[3,1,1,1],[2,0,0,0],[1,1,1,0],[2,2,0,1]] [[&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;빙하가 깨지면서 스노우타운에 떠내려 온&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&quot;죠르디&quot;&lt;/b&gt;는 인생 2막을 위해 주택 건축사업에 뛰어들기로 결심하였습니다.&lt;/p&gt;
&lt;p&gt;&quot;죠르디&quot;는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;기둥과 보&lt;/b&gt;를 이용하여 벽면 구조물을 자동으로 세우는 로봇을 개발할 계획인데,&lt;/p&gt;
&lt;p&gt;그에 앞서 로봇의 동작을 시뮬레이션 할 수 있는 프로그램을 만들고 있습니다.&lt;/p&gt;
&lt;p&gt;프로그램은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;2차원 가상 벽면&lt;/b&gt;에 기둥과 보를 이용한 구조물을 설치할 수 있는데,&lt;/p&gt;
&lt;p&gt;기둥과 보는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;길이가 1인 선분&lt;/b&gt;으로 표현되며 다음과 같은 규칙을 가지고 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;기둥은 바닥 위에 있거나 보의 한쪽 끝 부분 위에 있거나, 또는 다른 기둥 위에 있어야 합니다.&lt;/li&gt;
&lt;li&gt;보는 한쪽 끝 부분이 기둥 위에 있거나, 또는 양쪽 끝 부분이 다른 보와 동시에 연결되어 있어야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;단, 바닥은 벽면의 맨 아래 지면을 말합니다.&lt;/p&gt;
&lt;p&gt;2차원 벽면은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;n x n&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;크기 정사각 격자 형태이며, 각 격자는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;1 x 1&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;크기입니다. 맨 처음 벽면은 비어있는 상태입니다.&lt;/p&gt;
&lt;p&gt;기둥과 보는 격자선의 교차점에 걸치지 않고, 격자 칸의 각 변에 정확히 일치하도록 설치할 수 있습니다.&lt;/p&gt;
&lt;p&gt;다음은 기둥과 보를 설치해 구조물을 만든 예시입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qehMI/btq3gbx8pVs/2wM38KJjMPdVvcWGs38Fu0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qehMI/btq3gbx8pVs/2wM38KJjMPdVvcWGs38Fu0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qehMI/btq3gbx8pVs/2wM38KJjMPdVvcWGs38Fu0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqehMI%2Fbtq3gbx8pVs%2F2wM38KJjMPdVvcWGs38Fu0%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;예를 들어, 위 그림은 다음 순서에 따라 구조물을 만들었습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;(1, 0)에서 위쪽으로 기둥을 하나 설치 후, (1, 1)에서 오른쪽으로 보를 하나 만듭니다.&lt;/li&gt;
&lt;li&gt;(2, 1)에서 위쪽으로 기둥을 하나 설치 후, (2, 2)에서 오른쪽으로 보를 하나 만듭니다.&lt;/li&gt;
&lt;li&gt;(5, 0)에서 위쪽으로 기둥을 하나 설치 후, (5, 1)에서 위쪽으로 기둥을 하나 더 설치합니다.&lt;/li&gt;
&lt;li&gt;(4, 2)에서 오른쪽으로 보를 설치 후, (3, 2)에서 오른쪽으로 보를 설치합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;만약 (4, 2)에서 오른쪽으로 보를 먼저 설치하지 않고,&lt;/p&gt;
&lt;p&gt;(3, 2)에서 오른쪽으로 보를 설치하려 한다면 2번 규칙에 맞지 않으므로 설치가 되지 않습니다.&lt;/p&gt;
&lt;p&gt;기둥과 보를 삭제하는 기능도 있는데 기둥과 보를 삭제한 후에 남은 기둥과 보들 또한 위 규칙을 만족해야 합니다.&lt;/p&gt;
&lt;p&gt;만약, 작업을 수행한 결과가 조건을 만족하지 않는다면 해당 작업은 무시됩니다.&lt;/p&gt;
&lt;p&gt;벽면의 크기 n, 기둥과 보를 설치하거나 삭제하는 작업이 순서대로 담긴 2차원 배열 build_frame이 매개변수로 주어질 때,&lt;/p&gt;
&lt;p&gt;모든 명령어를 수행한 후 구조물의 상태를 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;h3&gt;제한사항&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;n은 5 이상 100 이하인 자연수입니다.&lt;/li&gt;
&lt;li&gt;build_frame의 세로(행) 길이는 1 이상 1,000 이하입니다.&lt;/li&gt;
&lt;li&gt;build_frame의 가로(열) 길이는 4입니다.&lt;/li&gt;
&lt;li&gt;build_frame의 원소는 [x, y, a, b]형태입니다.
&lt;ul&gt;
&lt;li&gt;x, y는 기둥, 보를 설치 또는 삭제할 교차점의 좌표이며, [가로 좌표, 세로 좌표] 형태입니다.&lt;/li&gt;
&lt;li&gt;a는 설치 또는 삭제할 구조물의 종류를 나타내며, 0은 기둥, 1은 보를 나타냅니다.&lt;/li&gt;
&lt;li&gt;b는 구조물을 설치할 지, 혹은 삭제할 지를 나타내며 0은 삭제, 1은 설치를 나타냅니다.&lt;/li&gt;
&lt;li&gt;벽면을 벗어나게 기둥, 보를 설치하는 경우는 없습니다.&lt;/li&gt;
&lt;li&gt;바닥에 보를 설치 하는 경우는 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;구조물은 교차점 좌표를 기준으로 보는 오른쪽, 기둥은 위쪽 방향으로 설치 또는 삭제합니다.&lt;/li&gt;
&lt;li&gt;구조물이 겹치도록 설치하는 경우와, 없는 구조물을 삭제하는 경우는 입력으로 주어지지 않습니다.&lt;/li&gt;
&lt;li&gt;최종 구조물의 상태는 아래 규칙에 맞춰 return 해주세요.
&lt;ul&gt;
&lt;li&gt;return 하는 배열은 가로(열) 길이가 3인 2차원 배열로, 각 구조물의 좌표를 담고있어야 합니다.&lt;/li&gt;
&lt;li&gt;return 하는 배열의 원소는 [x, y, a] 형식입니다.&lt;/li&gt;
&lt;li&gt;x, y는 기둥, 보의 교차점 좌표이며, [가로 좌표, 세로 좌표] 형태입니다.&lt;/li&gt;
&lt;li&gt;기둥, 보는 교차점 좌표를 기준으로 오른쪽, 또는 위쪽 방향으로 설치되어 있음을 나타냅니다.&lt;/li&gt;
&lt;li&gt;a는 구조물의 종류를 나타내며, 0은 기둥, 1은 보를 나타냅니다.&lt;/li&gt;
&lt;li&gt;return 하는 배열은 x좌표 기준으로 오름차순 정렬하며, x좌표가 같을 경우 y좌표 기준으로 오름차순 정렬해주세요.&lt;/li&gt;
&lt;li&gt;x, y좌표가 모두 같은 경우 기둥이 보보다 앞에 오면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;입출력 예&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;build_frame&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[[1,0,0,1],[1,1,1,1],[2,1,0,1],[2,2,1,1],[5,0,0,1],[5,1,0,1],[4,2,1,1],[3,2,1,1]]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[[1,0,0],[1,1,1],[2,1,0],[2,2,1],[3,2,1],[4,2,1],[5,0,0],[5,1,0]]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[[0,0,0,1],[2,0,0,1],[4,0,0,1],[0,1,1,1],[1,1,1,1],[2,1,1,1],[3,1,1,1],[2,0,0,0],[1,1,1,0],[2,2,0,1]]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[[0,0,0],[0,1,1],[1,1,1],[2,1,1],[3,1,1],[4,0,0]]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;입출력 예에 대한 설명&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문제의 예시와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;여덟 번째 작업을 수행 후 아래와 같은 구조물 만들어집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXFpX7/btq3gi5aJei/XqJL29jABp8NyI3uMuuNRK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXFpX7/btq3gi5aJei/XqJL29jABp8NyI3uMuuNRK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXFpX7/btq3gi5aJei/XqJL29jABp8NyI3uMuuNRK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXFpX7%2Fbtq3gi5aJei%2FXqJL29jABp8NyI3uMuuNRK%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;아홉 번째 작업의 경우, (1, 1)에서 오른쪽에 있는 보를 삭제하면 (2, 1)에서 오른쪽에 있는 보는 조건을 만족하지 않으므로 무시됩니다.&lt;/p&gt;
&lt;p&gt;열 번째 작업의 경우, (2, 2)에서 위쪽 방향으로 기둥을 세울 경우 조건을 만족하지 않으므로 무시됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1619078641836&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;
import java.util.Comparator;

class Solution {
    public int[][] solution(int n, int[][] build_frame) {
        boolean printLog = false;
        ++n;
        int[][] map = new int[n][n];
        int count = 0;
        for (int i = 0; i &amp;lt; build_frame.length; ++i) {
            int x = build_frame[i][0];
            int y = build_frame[i][1];
            boolean isPillar = build_frame[i][2] == 0;
            boolean isCreate = build_frame[i][3] == 1;
            if (printLog) System.out.print(String.format(&quot;%d, %d에 %s을 %s&quot;, x, y, isPillar ? &quot;기둥&quot; : &quot;보&quot;, isCreate ? &quot;설치&quot; : &quot;삭제&quot;));
            if (isCreate == false) {
                if (isPillar) {
                    if (map[x][y] % 2 != 1) {
                        if (printLog) System.out.println(&quot;- 지울 기둥이 없어서 삭제 실패.&quot;);
                        continue;
                    }
                    if (y + 1 &amp;lt; n) {
                        boolean able = true;
                        if (map[x][y + 1] % 2 == 1) {
                            able = false;
                            if (printLog) System.out.print(&quot;- [지울 기둥 위에 기둥이 있는데,]&quot;);
                            if (x - 1 &amp;gt;= 0 &amp;amp;&amp;amp; map[x - 1][y + 1] &amp;gt;= 2) {
                                if (printLog) System.out.print(&quot;+(대신 지울 기둥 왼편 보가 있어서 지탱 가능하고)&quot;);
                                able = true;
                            }
                            if (able == false &amp;amp;&amp;amp; map[x][y + 1] &amp;gt;= 2) {
                                if (printLog) System.out.print(&quot;+(대신 지울 기둥 오른편 보가 있어서 지탱 가능하고)&quot;);
                                able = true;
                            }
                        }
                        if (able == true &amp;amp;&amp;amp; map[x][y + 1] &amp;gt;= 2) {
                            able = false;
                            if (printLog) System.out.print(&quot;- [지울 기둥 위에 오른쪽으로 보가 있는데,]&quot;);
                            if (x + 1 &amp;lt; n &amp;amp;&amp;amp; map[x + 1][y] % 2 == 1) {
                                if (printLog) System.out.print(&quot;+(이 오른쪽 보는 바로 오른편 아래에 기둥이 있어서)&quot;);
                                able = true;
                            }
                            if (able == false &amp;amp;&amp;amp; x - 1 &amp;gt;= 0 &amp;amp;&amp;amp; map[x - 1][y + 1] &amp;gt;= 2 &amp;amp;&amp;amp; x + 1 &amp;lt; n &amp;amp;&amp;amp; map[x + 1][y + 1] &amp;gt;= 2) {
                                if (printLog) System.out.print(&quot;+(이 오른쪽 보는 양쪽에 다른 보가 있어서)&quot;);
                                able = true;
                            }
                        }
                        if (able == true &amp;amp;&amp;amp; x - 1 &amp;gt;= 0 &amp;amp;&amp;amp; map[x - 1][y + 1] &amp;gt;= 2) {
                            able = false;
                            if (printLog) System.out.print(&quot;- [지울 기둥 위에 왼쪽부터 보가 있는데,]&quot;);
                            if (map[x - 1][y] % 2 == 1) {
                                if (printLog) System.out.print(&quot;+(이 왼쪽 보는 바로 아래에 기둥이 있어서)&quot;);
                                able = true;
                            }
                            if (able == false &amp;amp;&amp;amp; x - 2 &amp;gt;= 0 &amp;amp;&amp;amp; map[x - 2][y + 1] &amp;gt;= 2 &amp;amp;&amp;amp; map[x][y + 1] &amp;gt;= 2) {
                                if (printLog) System.out.print(&quot;+(이 왼쪽 보는 양쪽에 다른 보가 있어서)&quot;);
                                able = true;
                            }
                        }
                        if (able == true) {
                            if (printLog) System.out.println(&quot;- 기둥 삭제 성공.&quot;);
                            map[x][y] -= 1;
                            --count;
                        } else {
                            if (printLog) System.out.println(&quot;- 기둥 삭제 실패.&quot;);
                            continue;
                        }
                    } else {
                        if (printLog) System.out.println(&quot;- 기둥 삭제 성공.&quot;);
                        map[x][y] -= 1;
                        --count;
                    }
                } else {
                    if (map[x][y] &amp;lt; 2) {
                        if (printLog) System.out.println(&quot;- 지울 보가 없어서 삭제 실패.&quot;);
                        continue;
                    }
                    boolean able = true;
                    if (map[x][y] % 2 == 1) {
                        able = false;
                        if (printLog) System.out.print(&quot;- [지울 보 위에 기둥이 있는데,]&quot;);
                        if (x - 1 &amp;gt;= 0 &amp;amp;&amp;amp; map[x - 1][y] &amp;gt;= 2) {
                            if (printLog) System.out.print(&quot;+(지울 보 왼편엔 다른 보가 있고)&quot;);
                            able = true;
                        }
                        if (able == false &amp;amp;&amp;amp; map[x][y - 1] % 2 == 1) {
                            if (printLog) System.out.print(&quot;+(지울 보 아래엔 기둥도 있고)&quot;);
                            able = true;
                        }
                    }
                    if (able == true &amp;amp;&amp;amp; x + 1 &amp;lt; n &amp;amp;&amp;amp; map[x + 1][y] % 2 == 1) {
                        able = false;
                        if (printLog) System.out.print(&quot;- [지울 보 오른편 위에 기둥이 있는데,]&quot;);
                        if (map[x + 1][y] &amp;gt;= 2) {
                            if (printLog) System.out.print(&quot;+(그 기둥 아래엔 다른 보가 있고)&quot;);
                            able = true;
                        }
                        if (able == false &amp;amp;&amp;amp; map[x + 1][y - 1] % 2 == 1) {
                            if (printLog) System.out.print(&quot;+(그 기둥 아래엔 기둥도 있고)&quot;);
                            able = true;
                        }
                    }
                    if (able == true &amp;amp;&amp;amp; x - 1 &amp;gt;= 0 &amp;amp;&amp;amp; map[x - 1][y] &amp;gt;= 2) {
                        able = false;
                        if (printLog) System.out.print(&quot;- [지울 보 왼편에 다른 보가 있는데,]&quot;);
                        if (map[x][y - 1] % 2 == 1) {
                            if (printLog) System.out.print(&quot;+(지울 보 아래의 기둥이 왼편 보를 받칠 수 있고)&quot;);
                            able = true;
                        }
                        if (able == false &amp;amp;&amp;amp; map[x - 1][y - 1] % 2 == 1) {
                            if (printLog) System.out.print(&quot;+(왼편 보 아래의 기둥이 왼편 보를 받칠 수 있고)&quot;);
                            able = true;
                        }
                    }
                    if (able == true &amp;amp;&amp;amp; x + 1 &amp;lt; n &amp;amp;&amp;amp; map[x + 1][y] &amp;gt;= 2) {
                        able = false;
                        if (printLog) System.out.print(&quot;- [지울 보 오른편에 다른 보가 있는데,]&quot;);
                        if (map[x + 1][y - 1] % 2 == 1) {
                            if (printLog) System.out.print(&quot;+(오른편 보 아래의 기둥이 오른편 보를 받칠 수 있고)&quot;);
                            able = true;
                        }
                        if (able == false &amp;amp;&amp;amp; x + 2 &amp;lt; n &amp;amp;&amp;amp; map[x + 2][y - 1] % 2 == 1) {
                            if (printLog) System.out.print(&quot;+(오른편 보 보다 오른쪽 아래의 기둥이 오른편 보를 받칠 수 있고)&quot;);
                            able = true;
                        }
                    }
                    if (able == true) {
                        if (printLog) System.out.println(&quot;- 보 삭제 성공.&quot;);
                        map[x][y] -= 2;
                        --count;
                    } else {
                        if (printLog) System.out.println(&quot;- 보 삭제 실패.&quot;);
                        continue;
                    }
                }
            } else {
                if (isPillar) {
                    if (map[x][y] % 2 == 1) {
                        if (printLog) System.out.println(&quot;- 이미 기둥이 있어서 짓기 실패.&quot;);
                        continue;
                    }
                    if (y == 0) {
                        if (printLog) System.out.println(&quot;- 기둥 짓기 성공.&quot;);
                        map[x][y] += 1;
                        ++count;
                    } else {
                        if ((map[x][y - 1] % 2 == 1) || (map[x][y] &amp;gt;= 2) || (x - 1 &amp;gt;= 0 &amp;amp;&amp;amp; map[x - 1][y] &amp;gt;= 2)) {
                            if (printLog) System.out.println(&quot;- 기둥 짓기 성공.&quot;);
                            map[x][y] += 1;
                            ++count;
                        } else {
                            if (printLog) System.out.println(&quot;- 조건미달로 기둥 짓기 실패.&quot;);
                        }
                    }
                } else {
                    if (map[x][y] &amp;gt;= 2) {
                        if (printLog) System.out.println(&quot;- 이미 보가 있어서 짓기 실패.&quot;);
                        continue;
                    }
                    if ((map[x][y - 1] % 2 == 1) || (x + 1 &amp;lt; n &amp;amp;&amp;amp; map[x + 1][y - 1] % 2 == 1) || ((x + 1 &amp;lt; n &amp;amp;&amp;amp; map[x + 1][y] &amp;gt;= 2) &amp;amp;&amp;amp; (x - 1 &amp;gt;= 0 &amp;amp;&amp;amp; map[x - 1][y] &amp;gt;= 2))) {
                        if (printLog) System.out.println(&quot;- 보 짓기 성공.&quot;);
                        map[x][y] += 2;
                        ++count;
                    } else {
                        if (printLog) System.out.println(&quot;- 조건미달로 보 짓기 실패.&quot;);
                    }
                }
            }
        }
        int[][] answer = new int[count][];
        int index = 0;
        for (int x = 0; x &amp;lt; n; ++x) {
            for (int y = 0; y &amp;lt; n; ++y) {
                if (map[x][y] % 2 == 1) {
                    answer[index++] = new int[] { x, y, 0 };
                }
                if (map[x][y] &amp;gt;= 2) {
                    answer[index++] = new int[] { x, y, 1 };
                }
            }
        }
        Comparator&amp;lt;int[]&amp;gt; comparator = new Comparator&amp;lt;int[]&amp;gt;() {
            @Override
            public int compare(int[] o1, int[] o2) {
                if (o1[0] == o2[0]) {
                    if (o1[1] == o2[1]) {
                        return o1[2] - o2[2];
                    } else {
                        return o1[1] - o2[1];
                    }
                } else {
                    return o1[0] - o2[0];
                }
            }
        };
        Arrays.sort(answer, comparator);
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level3</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/265</guid>
      <comments>https://ydeer.tistory.com/265#entry265comment</comments>
      <pubDate>Thu, 22 Apr 2021 17:04:45 +0900</pubDate>
    </item>
    <item>
      <title>[Lv3] 불량 사용자</title>
      <link>https://ydeer.tistory.com/264</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/64064&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/64064&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1619020552366&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 불량 사용자&quot; data-og-description=&quot;개발팀 내에서 이벤트 개발을 담당하고 있는 &amp;quot;무지&amp;quot;는 최근 진행된 카카오이모티콘 이벤트에 비정상적인 방법으로 당첨을 시도한 응모자들을 발견하였습니다. 이런 응모자들을 따로 모아 불량 &quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/64064&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/64064&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dVIieA/hyJX0AxUio/FmR7YcGjKyVv3S7RN7fGF0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/b1GOl2/hyJWrmcOVW/n3ptYG7prP29H9YNfeXda0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/64064&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/64064&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dVIieA/hyJX0AxUio/FmR7YcGjKyVv3S7RN7fGF0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/b1GOl2/hyJWrmcOVW/n3ptYG7prP29H9YNfeXda0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 불량 사용자&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;개발팀 내에서 이벤트 개발을 담당하고 있는 &quot;무지&quot;는 최근 진행된 카카오이모티콘 이벤트에 비정상적인 방법으로 당첨을 시도한 응모자들을 발견하였습니다. 이런 응모자들을 따로 모아 불량&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;개발팀 내에서 이벤트 개발을 담당하고 있는 &quot;무지&quot;는&lt;/p&gt;
&lt;p&gt;최근 진행된 카카오이모티콘 이벤트에 비정상적인 방법으로 당첨을 시도한 응모자들을 발견하였습니다.&lt;/p&gt;
&lt;p&gt;이런 응모자들을 따로 모아&lt;span&gt;&amp;nbsp;&lt;/span&gt;불량 사용자라는 이름으로 목록을 만들어서&lt;/p&gt;
&lt;p&gt;당첨 처리 시 제외하도록 이벤트 당첨자 담당자인 &quot;프로도&quot; 에게 전달하려고 합니다.&lt;/p&gt;
&lt;p&gt;이 때 개인정보 보호을 위해 사용자 아이디 중 일부 문자를 '*' 문자로 가려서 전달했습니다.&lt;/p&gt;
&lt;p&gt;가리고자 하는 문자 하나에 '*' 문자 하나를 사용하였고 아이디 당 최소 하나 이상의 '*' 문자를 사용하였습니다.&lt;/p&gt;
&lt;p&gt;&quot;무지&quot;와 &quot;프로도&quot;는 불량 사용자 목록에 매핑된 응모자 아이디를&lt;span&gt;&amp;nbsp;&lt;/span&gt;제재 아이디&lt;span&gt;&amp;nbsp;&lt;/span&gt;라고 부르기로 하였습니다.&lt;/p&gt;
&lt;p&gt;예를 들어, 이벤트에 응모한 전체 사용자 아이디 목록이 다음과 같다면&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;응모자 아이디&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;fradi&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;crodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;abc123&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodoc&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;다음과 같이 불량 사용자 아이디 목록이 전달된 경우,&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;불량 사용자&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;fr*d*&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;abc1**&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;불량 사용자에 매핑되어 당첨에서 제외되어야 야 할 제재 아이디 목록은 다음과 같이 두 가지 경우가 있을 수 있습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;제재 아이디&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;abc123&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;제재 아이디&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;fradi&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;abc123&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;이벤트 응모자 아이디 목록이 담긴 배열 user_id와 불량 사용자 아이디 목록이 담긴 배열 banned_id가 매개변수로 주어질 때,&lt;/p&gt;
&lt;p&gt;당첨에서 제외되어야 할 제재 아이디 목록은 몇가지 경우의 수가 가능한 지 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;[제한사항]&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;user_id 배열의 크기는 1 이상 8 이하입니다.&lt;/li&gt;
&lt;li&gt;user_id 배열 각 원소들의 값은 길이가 1 이상 8 이하인 문자열입니다.
&lt;ul&gt;
&lt;li&gt;응모한 사용자 아이디들은 서로 중복되지 않습니다.&lt;/li&gt;
&lt;li&gt;응모한 사용자 아이디는 알파벳 소문자와 숫자로만으로 구성되어 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;banned_id 배열의 크기는 1 이상 user_id 배열의 크기 이하입니다.&lt;/li&gt;
&lt;li&gt;banned_id 배열 각 원소들의 값은 길이가 1 이상 8 이하인 문자열입니다.
&lt;ul&gt;
&lt;li&gt;불량 사용자 아이디는 알파벳 소문자와 숫자, 가리기 위한 문자 '*' 로만 이루어져 있습니다.&lt;/li&gt;
&lt;li&gt;불량 사용자 아이디는 '*' 문자를 하나 이상 포함하고 있습니다.&lt;/li&gt;
&lt;li&gt;불량 사용자 아이디 하나는 응모자 아이디 중 하나에 해당하고 같은 응모자 아이디가 중복해서 제재 아이디 목록에 들어가는 경우는 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;제재 아이디 목록들을 구했을 때 아이디들이 나열된 순서와 관계없이 아이디 목록의 내용이 동일하다면 같은 것으로 처리하여 하나로 세면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;[입출력 예]&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;user_id&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;banned_id&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;[&quot;frodo&quot;, &quot;fradi&quot;, &quot;crodo&quot;, &quot;abc123&quot;, &quot;frodoc&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;fr*d*&quot;, &quot;abc1**&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;[&quot;frodo&quot;, &quot;fradi&quot;, &quot;crodo&quot;, &quot;abc123&quot;, &quot;frodoc&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;*rodo&quot;, &quot;*rodo&quot;, &quot;******&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;[&quot;frodo&quot;, &quot;fradi&quot;, &quot;crodo&quot;, &quot;abc123&quot;, &quot;frodoc&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;fr*d*&quot;, &quot;*rodo&quot;, &quot;******&quot;, &quot;******&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예에 대한 설명&lt;/b&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문제 설명과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;다음과 같이 두 가지 경우가 있습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;제재 아이디&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;crodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;abc123&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;제재 아이디&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;crodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodoc&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #3&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;다음과 같이 세 가지 경우가 있습니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;제재 아이디&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;crodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;abc123&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodoc&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;제재 아이디&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;fradi&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;crodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;abc123&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodoc&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;제재 아이디&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;fradi&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodo&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;abc123&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;frodoc&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1619020732236&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Solution {
    public void calc(HashSet&amp;lt;Integer&amp;gt; set, ArrayList&amp;lt;Integer&amp;gt;[] variations, int[] selected, int index) {
        if (index &amp;gt;= variations.length) {
            Arrays.sort(selected);
            int hash = 0;
            for (int i = 0; i &amp;lt; selected.length; ++i) {
                hash += selected[i] * Math.pow(10, i);
            }
            set.add(hash);
            return;
        }
        for (Integer able : variations[index]) {
            boolean isAble = true;
            for (int i = 0; i &amp;lt; index; ++i) {
                if (able == selected[i]) {
                    isAble = false;
                    break;
                }
            }
            if (isAble == true) {
                int[] newSelected = selected.clone();
                newSelected[index] = able;
                calc(set, variations, newSelected, index + 1);
            }
        }
    }

    public int solution(String[] user_id, String[] banned_id) {
        ArrayList&amp;lt;Integer&amp;gt;[] ables = new ArrayList[banned_id.length];
        for (int i = 0; i &amp;lt; banned_id.length; ++i) {
            ables[i] = new ArrayList&amp;lt;&amp;gt;(user_id.length);
            String regex = banned_id[i].replaceAll(&quot;\\*&quot;, &quot;\\.&quot;);
            regex = String.format(&quot;^%s$&quot;, regex);
            for (int j = 0; j &amp;lt; user_id.length; ++j) {
                Matcher matcher = Pattern.compile(regex).matcher(user_id[j]);
                if (matcher.find()) {
                    ables[i].add(j);
                }
            }
        }
        HashSet&amp;lt;Integer&amp;gt; alreadyDone = new HashSet&amp;lt;&amp;gt;(ables.length);
        while (true) {
            boolean isAllDone = true;
            for (int i = 0; i &amp;lt; ables.length; ++i) {
                if (ables[i] != null &amp;amp;&amp;amp; ables[i].size() == 1) {
                    isAllDone = false;
                    alreadyDone.add(i);
                    for (int j = 0; j &amp;lt; ables.length; ++j) {
                        if (j == i) {
                            continue;
                        }
                        if (ables[j] != null) {
                            ables[j].remove(Integer.valueOf(ables[i].get(0)));
                        }
                    }
                    ables[i] = null;
                }
            }
            for (int i = 0; i &amp;lt; ables.length; ++i) {
                if (ables[i] != null) {
                    ArrayList&amp;lt;Integer&amp;gt; sames = new ArrayList&amp;lt;&amp;gt;(ables[i].size());
                    sames.add(i);
                    for (int j = 0; j &amp;lt; ables.length; ++j) {
                        if (j == i) {
                            continue;
                        }
                        if (ables[j] != null &amp;amp;&amp;amp; ables[j].size() == ables[i].size() &amp;amp;&amp;amp; ables[j].containsAll(ables[i])) {
                            sames.add(j);
                        }
                    }
                    if (sames.size() == ables[i].size()) {
                        isAllDone = false;
                        int[] willDel = ables[i].stream().mapToInt(Integer::intValue).toArray();
                        for (Integer index : sames) {
                            alreadyDone.add(index);
                            ables[index] = null;
                        }
                        for (int j = 0; j &amp;lt; ables.length; ++j) {
                            if (ables[j] != null) {
                                for (int k = 0; k &amp;lt; willDel.length; ++k) {
                                    ables[j].remove(Integer.valueOf(willDel[k]));
                                }
                            }
                        }
                    }
                }
            }
            if (isAllDone == true) {
                break;
            }
        }
        if (alreadyDone.size() == ables.length) {
            return 1;
        }
        ArrayList&amp;lt;Integer&amp;gt;[] variations = new ArrayList[ables.length - alreadyDone.size()];
        int index = 0;
        for (int i = 0; i &amp;lt; ables.length; ++i) {
            if (ables[i] != null) {
                variations[index++] = ables[i];
            }
        }
        HashSet&amp;lt;Integer&amp;gt; set = new HashSet&amp;lt;&amp;gt;();
        int[] selected = new int[variations.length];
        calc(set, variations, selected, 0);
        return set.size();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level3</category>
      <category>programmers</category>
      <category>regex</category>
      <category>정규표현식</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/264</guid>
      <comments>https://ydeer.tistory.com/264#entry264comment</comments>
      <pubDate>Thu, 22 Apr 2021 01:01:50 +0900</pubDate>
    </item>
    <item>
      <title>[Lv3] 추석 트래픽</title>
      <link>https://ydeer.tistory.com/263</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17676&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/17676&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618997692722&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - [1차] 추석 트래픽&quot; data-og-description=&quot;입력: [ &amp;quot;2016-09-15 20:59:57.421 0.351s&amp;quot;, &amp;quot;2016-09-15 20:59:58.233 1.181s&amp;quot;, &amp;quot;2016-09-15 20:59:58.299 0.8s&amp;quot;, &amp;quot;2016-09-15 20:59:58.688 1.041s&amp;quot;, &amp;quot;2016-09-15 20:59:59.591 1.412s&amp;quot;, &amp;quot;2016-09-15 21:00:00.464 1.466s&amp;quot;, &amp;quot;2016-09-15 21:00:00.741 1.581s&amp;quot;, &amp;quot;2016-09-1&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17676&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17676&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/tDBKX/hyJWyFrtwI/mPj2V0fQBA8IxuUfxw2nuK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/btB4Bs/hyJWr0E5Ks/Fi0JRj22IBcZKxhlefKrFk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/d4wP0h/hyJWxsZHIv/FDwM631PwFiXZvpbGmAyd0/img.png?width=393&amp;amp;height=285&amp;amp;face=0_0_393_285&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17676&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17676&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/tDBKX/hyJWyFrtwI/mPj2V0fQBA8IxuUfxw2nuK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/btB4Bs/hyJWr0E5Ks/Fi0JRj22IBcZKxhlefKrFk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/d4wP0h/hyJWxsZHIv/FDwM631PwFiXZvpbGmAyd0/img.png?width=393&amp;amp;height=285&amp;amp;face=0_0_393_285');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - [1차] 추석 트래픽&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;입력: [ &quot;2016-09-15 20:59:57.421 0.351s&quot;, &quot;2016-09-15 20:59:58.233 1.181s&quot;, &quot;2016-09-15 20:59:58.299 0.8s&quot;, &quot;2016-09-15 20:59:58.688 1.041s&quot;, &quot;2016-09-15 20:59:59.591 1.412s&quot;, &quot;2016-09-15 21:00:00.464 1.466s&quot;, &quot;2016-09-15 21:00:00.741 1.581s&quot;, &quot;2016-09-1&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;h2&gt;추석 트래픽&lt;/h2&gt;
&lt;p&gt;이번 추석에도 시스템 장애가 없는 명절을 보내고 싶은 어피치는 서버를 증설해야 할지 고민이다.&lt;/p&gt;
&lt;p&gt;장애 대비용 서버 증설 여부를 결정하기 위해&lt;/p&gt;
&lt;p&gt;작년 추석 기간인 9월 15일 로그 데이터를 분석한 후 초당 최대 처리량을 계산해보기로 했다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;초당 최대 처리량&lt;/b&gt;은 요청의 응답 완료 여부에 관계없이&lt;/p&gt;
&lt;p&gt;임의 시간부터 1초(=1,000밀리초)간 처리하는 요청의 최대 개수를 의미한다.&lt;/p&gt;
&lt;h3&gt;입력 형식&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;solution&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수에 전달되는&lt;span&gt;&amp;nbsp;&lt;/span&gt;lines&lt;span&gt;&amp;nbsp;&lt;/span&gt;배열은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;N&lt;/b&gt;(1 ≦&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;N&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;≦ 2,000)개의 로그 문자열로 되어 있으며, 각 로그 문자열마다 요청에 대한 응답완료시간&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;S&lt;/b&gt;와 처리시간&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;T&lt;/b&gt;가 공백으로 구분되어 있다.&lt;/li&gt;
&lt;li&gt;응답완료시간&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;S&lt;/b&gt;는 작년 추석인 2016년 9월 15일만 포함하여 고정 길이&lt;span&gt;&amp;nbsp;&lt;/span&gt;2016-09-15 hh:mm:ss.sss&lt;span&gt;&amp;nbsp;&lt;/span&gt;형식으로 되어 있다.&lt;/li&gt;
&lt;li&gt;처리시간&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;T&lt;/b&gt;는&lt;span&gt;&amp;nbsp;&lt;/span&gt;0.1s,&lt;span&gt;&amp;nbsp;&lt;/span&gt;0.312s,&lt;span&gt;&amp;nbsp;&lt;/span&gt;2s&lt;span&gt;&amp;nbsp;&lt;/span&gt;와 같이 최대 소수점 셋째 자리까지 기록하며 뒤에는 초 단위를 의미하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;s로 끝난다.&lt;/li&gt;
&lt;li&gt;예를 들어, 로그 문자열&lt;span&gt;&amp;nbsp;&lt;/span&gt;2016-09-15 03:10:33.020 0.011s은 &quot;2016년 9월 15일 오전 3시 10분&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;33.010초&lt;/b&gt;&quot;부터 &quot;2016년 9월 15일 오전 3시 10분&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;33.020초&lt;/b&gt;&quot;까지 &quot;&lt;b&gt;0.011초&lt;/b&gt;&quot; 동안 처리된 요청을 의미한다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;(처리시간은 시작시간과 끝시간을 포함)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;서버에는 타임아웃이 3초로 적용되어 있기 때문에 처리시간은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;0.001 ≦ T ≦ 3.000&lt;/b&gt;이다.&lt;/li&gt;
&lt;li&gt;lines&lt;span&gt;&amp;nbsp;&lt;/span&gt;배열은 응답완료시간&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;S&lt;/b&gt;를 기준으로 오름차순 정렬되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;출력 형식&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;solution&lt;span&gt;&amp;nbsp;&lt;/span&gt;함수에서는 로그 데이터&lt;span&gt;&amp;nbsp;&lt;/span&gt;lines&lt;span&gt;&amp;nbsp;&lt;/span&gt;배열에 대해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;초당 최대 처리량&lt;/b&gt;을 리턴한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;입출력 예제&lt;/h3&gt;
&lt;p&gt;예제1&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;입력: [&quot;2016-09-15 01:00:04.001 2.0s&quot;,]&lt;/li&gt;
&lt;li&gt;&quot;2016-09-15 01:00:07.000 2s&quot;&lt;/li&gt;
&lt;li&gt;출력: 1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;예제2&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;입력: [&quot;2016-09-15 01:00:04.002 2.0s&quot;,]&lt;/li&gt;
&lt;li&gt;&quot;2016-09-15 01:00:07.000 2s&quot;&lt;/li&gt;
&lt;li&gt;출력: 2&lt;/li&gt;
&lt;li&gt;설명: 처리시간은 시작시간과 끝시간을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;포함&lt;/b&gt;하므로첫 번째 로그는&lt;span&gt;&amp;nbsp;&lt;/span&gt;01:00:02.003 ~ 01:00:04.002에서 2초 동안 처리되었으며,따라서, 첫 번째 로그가 끝나는 시점과 두 번째 로그가 시작하는 시점의 구간인&lt;span&gt;&amp;nbsp;&lt;/span&gt;01:00:04.002 ~ 01:00:05.001&lt;span&gt;&amp;nbsp;&lt;/span&gt;1초 동안 최대 2개가 된다.&lt;/li&gt;
&lt;li&gt;두 번째 로그는&lt;span&gt;&amp;nbsp;&lt;/span&gt;01:00:05.001 ~ 01:00:07.000에서 2초 동안 처리된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;예제3&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;입력: [&quot;2016-09-15 20:59:57.421 0.351s&quot;,&quot;2016-09-15 20:59:58.299 0.8s&quot;,&quot;2016-09-15 20:59:59.591 1.412s&quot;,&quot;2016-09-15 21:00:00.741 1.581s&quot;,&quot;2016-09-15 21:00:00.966 0.381s&quot;,]&lt;/li&gt;
&lt;li&gt;&quot;2016-09-15 21:00:02.066 2.62s&quot;&lt;/li&gt;
&lt;li&gt;&quot;2016-09-15 21:00:00.748 2.31s&quot;,&lt;/li&gt;
&lt;li&gt;&quot;2016-09-15 21:00:00.464 1.466s&quot;,&lt;/li&gt;
&lt;li&gt;&quot;2016-09-15 20:59:58.688 1.041s&quot;,&lt;/li&gt;
&lt;li&gt;&quot;2016-09-15 20:59:58.233 1.181s&quot;,&lt;/li&gt;
&lt;li&gt;출력: 7&lt;/li&gt;
&lt;li&gt;설명: 아래 타임라인 그림에서 빨간색으로 표시된 1초 각 구간의 처리량을 구해보면&lt;span&gt;&amp;nbsp;&lt;/span&gt;(1)은 4개,&lt;span&gt;&amp;nbsp;&lt;/span&gt;(2)는 7개,&lt;span&gt;&amp;nbsp;&lt;/span&gt;(3)는 2개임을 알 수 있다. 따라서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;초당 최대 처리량&lt;/b&gt;은 7이 되며, 동일한 최대 처리량을 갖는 1초 구간은 여러 개 존재할 수 있으므로 이 문제에서는 구간이 아닌 개수만 출력한다.
&lt;div&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBRqAY/btq26pq8g7o/JsrllTIKuT8jkmyiRXGuWK/img.png&quot; /&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618997770103&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Solution {
    public int[] timestampToNumbers(String timestamp) {
        int[] result = new int[2];
        int hour = (timestamp.charAt(11) - '0') * 10 + (timestamp.charAt(12) - '0');
        int min = (timestamp.charAt(14) - '0') * 10 + (timestamp.charAt(15) - '0');
        int millsec = (timestamp.charAt(17) - '0') * 10000 + (timestamp.charAt(18) - '0') * 1000 + (timestamp.charAt(20) - '0') * 100 + (timestamp.charAt(21) - '0') * 10  + (timestamp.charAt(22) - '0');
        Matcher matcher = Pattern.compile(&quot;(\\d+\\.\\d{1,3}s)|(\\d+s)&quot;).matcher(timestamp);
        matcher.find();
        String work = matcher.group();
        int indexDot = work.indexOf('.');
        int timeWork = 0;
        if (indexDot == -1) {
            timeWork = Integer.parseInt(work.substring(0, work.length() - 1)) * 1000;
        } else {
            timeWork = Integer.parseInt(work.substring(0, indexDot)) * 1000;
            timeWork += Integer.parseInt(work.substring(indexDot + 1, work.length() - 1));
        }
        result[1] = millsec + min * 60000 + hour * 3600000;
        result[0] = result[1] - timeWork + 1;
        return result;
    }

    public String NumberToTimestamp(int number) {
        int hour = number / 3600000;
        number %= 3600000;
        int min = number / 60000;
        number %= 60000;
        int sec = number / 1000;
        number %= 1000;
        return String.format(&quot;%02d:%02d:%02d.%03d&quot;, hour, min, sec, number);
    }

    public int solution(String[] lines) {
        Comparator&amp;lt;int[]&amp;gt; comparator = new Comparator&amp;lt;int[]&amp;gt;() {
            @Override
            public int compare(int[] o1, int[] o2) {
                if (o1[0] == o2[0]) {
                    return o1[1] - o2[1];
                } else {
                    return o1[0] - o2[0];
                }
            }
        };
        int[][] logs = new int[lines.length][];
        for (int i = 0; i &amp;lt; lines.length; ++i) {
            logs[i] = timestampToNumbers(lines[i]);
        }
        Arrays.sort(logs, comparator);
//        System.out.println(&quot;----------&quot;);
//        for (int i = 0; i &amp;lt; logs.length; ++i) {
//            System.out.println(String.format(&quot;%s ~ %s&quot;, NumberToTimestamp(logs[i][0]), NumberToTimestamp(logs[i][1])));
//        }
//        System.out.println(&quot;----------&quot;);
        int answer = 0;
        int timeStart = logs[0][0];
        int timeComplete = 0;
        for (int i = 0; i &amp;lt; logs.length; ++i) {
            if (logs[i][1] &amp;gt; timeComplete) {
                timeComplete = logs[i][1];
            }
        }
        if (timeComplete &amp;lt; timeStart + 1000) {
            timeComplete = timeStart + 1000;
        }
        HashSet&amp;lt;Integer&amp;gt; set = new HashSet&amp;lt;&amp;gt;(logs.length);
        int indexNext = 0;
        while (true) {
            if (set.isEmpty()) {
                timeStart = logs[indexNext][0];
                set.add(indexNext);
                ++indexNext;
                while (indexNext &amp;lt; logs.length) {
                    if (logs[indexNext][0] &amp;gt;= timeStart &amp;amp;&amp;amp; logs[indexNext][0] &amp;lt; timeStart + 1000) {
                        set.add(indexNext);
                        ++indexNext;
                    } else {
                        break;
                    }
                }
            } else {
                int startNext = logs[indexNext][0];
                int endFirst = Integer.MAX_VALUE;
                for (Integer index : set) {
                    if (logs[index][1] &amp;lt; endFirst) {
                        endFirst = logs[index][1];
                    }
                }
                if (endFirst &amp;lt;= startNext - 1000) {
                    int[] array = set.stream().mapToInt(Integer::intValue).toArray();
                    for (int i = 0; i &amp;lt; array.length; ++i) {
                        if (logs[array[i]][1] == endFirst) {
                            set.remove(array[i]);
                        }
                    }
                    timeStart = endFirst;
                }
                if (endFirst &amp;gt;= startNext - 1000) {
                    while (indexNext &amp;lt; logs.length) {
                        if (logs[indexNext][0] == startNext) {
                            set.add(indexNext);
                            ++indexNext;
                        } else {
                            break;
                        }
                    }
                    timeStart = startNext - 1000;
                }
            }
            if (set.size() &amp;gt; answer) {
                answer = set.size();
            }
            if (indexNext &amp;gt;= logs.length) {
                break;
            }
        }
//            System.out.println(String.format(&quot;[%s ~ %s]: %d&quot;, NumberToTimestamp(timeStart), NumberToTimestamp(timeStart + 1000), count));
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level3</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/263</guid>
      <comments>https://ydeer.tistory.com/263#entry263comment</comments>
      <pubDate>Wed, 21 Apr 2021 18:36:35 +0900</pubDate>
    </item>
    <item>
      <title>[Lv3] 순위</title>
      <link>https://ydeer.tistory.com/262</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/49191&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/49191&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618904066235&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 순위&quot; data-og-description=&quot;5 [[4, 3], [4, 2], [3, 2], [1, 2], [2, 5]] 2&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/49191&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/49191&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bUL1Kn/hyJWD7as2x/dFtTYpmyi4tM2nLqYeyslk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/lEclK/hyJWAihDaI/ykjIfDbdd6gC5WiulizRc0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/49191&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/49191&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bUL1Kn/hyJWD7as2x/dFtTYpmyi4tM2nLqYeyslk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/lEclK/hyJWAihDaI/ykjIfDbdd6gC5WiulizRc0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 순위&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;5 [[4, 3], [4, 2], [3, 2], [1, 2], [2, 5]] 2&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;n명의 권투선수가 권투 대회에 참여했고 각각 1번부터 n번까지 번호를 받았습니다.&lt;/p&gt;
&lt;p&gt;권투 경기는 1대1 방식으로 진행이 되고, 만약 A 선수가 B 선수보다 실력이 좋다면 A 선수는 B 선수를 항상 이깁니다.&lt;/p&gt;
&lt;p&gt;심판은 주어진 경기 결과를 가지고 선수들의 순위를 매기려 합니다.&lt;/p&gt;
&lt;p&gt;하지만 몇몇 경기 결과를 분실하여 정확하게 순위를 매길 수 없습니다.&lt;/p&gt;
&lt;p&gt;선수의 수 n, 경기 결과를 담은 2차원 배열 results가 매개변수로 주어질 때&lt;/p&gt;
&lt;p&gt;정확하게 순위를 매길 수 있는 선수의 수를 return 하도록 solution 함수를 작성해주세요.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;제한사항&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;선수의 수는 1명 이상 100명 이하입니다.&lt;/li&gt;
&lt;li&gt;경기 결과는 1개 이상 4,500개 이하입니다.&lt;/li&gt;
&lt;li&gt;results 배열 각 행 [A, B]는 A 선수가 B 선수를 이겼다는 의미입니다.&lt;/li&gt;
&lt;li&gt;모든 경기 결과에는 모순이 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;results&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;return&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[[4, 3], [4, 2], [3, 2], [1, 2], [2, 5]]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;2번 선수는 [1, 3, 4] 선수에게 패배했고 5번 선수에게 승리했기 때문에 4위입니다.&lt;/p&gt;
&lt;p&gt;5번 선수는 4위인 2번 선수에게 패배했기 때문에 5위입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618904122867&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int solution(int n, int[][] results) {
    int[][] scores = new int[n][n];
    for (int i = 0; i &amp;lt; results.length; ++i) {
        scores[results[i][0] - 1][results[i][1] - 1] = 1;
        scores[results[i][1] - 1][results[i][0] - 1] = -1;
    }
    for (int i = 0; i &amp;lt; scores.length; ++i) {
        for (int j = 0; j &amp;lt; scores.length; ++j) {
            if (j == i) {
                continue;
            }
            if (scores[i][j] != 0) {
                for (int k = 0; k &amp;lt; scores.length; ++k) {
                    if (k == j) {
                        continue;
                    }
                    if (scores[i][k] == scores[i][j] * -1) {
                        scores[k][j] = scores[i][j];
                    }
                }
            }
        }
    }
    int answer = 0;
    for (int i = 0; i &amp;lt; scores.length; ++i) {
        int countZero = 0;
        for (int j = 0; j &amp;lt; scores.length; ++j) {
            if (scores[i][j] == 0) {
                ++countZero;
            }
        }
        if (countZero == 1) {
            ++answer;
        }
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level3</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/262</guid>
      <comments>https://ydeer.tistory.com/262#entry262comment</comments>
      <pubDate>Tue, 20 Apr 2021 16:40:27 +0900</pubDate>
    </item>
    <item>
      <title>[Lv3] 셔틀버스</title>
      <link>https://ydeer.tistory.com/261</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17678&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/17678&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618853462149&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - [1차] 셔틀버스&quot; data-og-description=&quot;10 60 45 [&amp;quot;23:59&amp;quot;,&amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;, &amp;quot;23:59&amp;quot;] &amp;quot;18:00&amp;quot;&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17678&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17678&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mATcx/hyJWyRJdvG/OyUIB3i8wCMz3i3oeS9vRK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bfRvQU/hyJWDMgKxC/KLG1KhaBWhBHaW9tu2C5TK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17678&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17678&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mATcx/hyJWyRJdvG/OyUIB3i8wCMz3i3oeS9vRK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bfRvQU/hyJWDMgKxC/KLG1KhaBWhBHaW9tu2C5TK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - [1차] 셔틀버스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;10 60 45 [&quot;23:59&quot;,&quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;] &quot;18:00&quot;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;h2&gt;셔틀버스&lt;/h2&gt;
&lt;p&gt;카카오에서는 무료 셔틀버스를 운행하기 때문에 판교역에서 편하게 사무실로 올 수 있다.&lt;/p&gt;
&lt;p&gt;카카오의 직원은 서로를 '크루'라고 부르는데, 아침마다 많은 크루들이 이 셔틀을 이용하여 출근한다.&lt;/p&gt;
&lt;p&gt;이 문제에서는 편의를 위해 셔틀은 다음과 같은 규칙으로 운행한다고 가정하자.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;셔틀은&lt;span&gt;&amp;nbsp;&lt;/span&gt;09:00부터 총&lt;span&gt;&amp;nbsp;&lt;/span&gt;n회&lt;span&gt;&amp;nbsp;&lt;/span&gt;t분 간격으로 역에 도착하며, 하나의 셔틀에는 최대&lt;span&gt;&amp;nbsp;&lt;/span&gt;m명의 승객이 탈 수 있다.&lt;/li&gt;
&lt;li&gt;셔틀은 도착했을 때 도착한 순간에 대기열에 선 크루까지 포함해서 대기 순서대로 태우고 바로 출발한다.&lt;/li&gt;
&lt;li&gt;예를 들어&lt;span&gt;&amp;nbsp;&lt;/span&gt;09:00에 도착한 셔틀은 자리가 있다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;09:00에 줄을 선 크루도 탈 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;일찍 나와서 셔틀을 기다리는 것이 귀찮았던 콘은, 일주일간의 집요한 관찰 끝에 어떤 크루가 몇 시에 셔틀 대기열에 도착하는지 알아냈다.&lt;/p&gt;
&lt;p&gt;콘이 셔틀을 타고 사무실로 갈 수 있는 도착 시각 중 제일 늦은 시각을 구하여라.&lt;/p&gt;
&lt;p&gt;단, 콘은 게으르기 때문에 같은 시각에 도착한 크루 중 대기열에서 제일 뒤에 선다.&lt;/p&gt;
&lt;p&gt;또한, 모든 크루는 잠을 자야 하므로&lt;span&gt;&amp;nbsp;&lt;/span&gt;23:59에 집에 돌아간다. 따라서 어떤 크루도 다음날 셔틀을 타는 일은 없다.&lt;/p&gt;
&lt;h3&gt;입력 형식&lt;/h3&gt;
&lt;p&gt;셔틀 운행 횟수&lt;span&gt;&amp;nbsp;&lt;/span&gt;n, 셔틀 운행 간격&lt;span&gt;&amp;nbsp;&lt;/span&gt;t, 한 셔틀에 탈 수 있는 최대 크루 수&lt;span&gt;&amp;nbsp;&lt;/span&gt;m,&lt;/p&gt;
&lt;p&gt;크루가 대기열에 도착하는 시각을 모은 배열&lt;span&gt;&amp;nbsp;&lt;/span&gt;timetable이 입력으로 주어진다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;0 ＜&lt;span&gt;&amp;nbsp;&lt;/span&gt;n&lt;span&gt;&amp;nbsp;&lt;/span&gt;≦ 10&lt;/li&gt;
&lt;li&gt;0 ＜&lt;span&gt;&amp;nbsp;&lt;/span&gt;t&lt;span&gt;&amp;nbsp;&lt;/span&gt;≦ 60&lt;/li&gt;
&lt;li&gt;0 ＜&lt;span&gt;&amp;nbsp;&lt;/span&gt;m&lt;span&gt;&amp;nbsp;&lt;/span&gt;≦ 45&lt;/li&gt;
&lt;li&gt;timetable은 최소 길이 1이고 최대 길이 2000인 배열로, 하루 동안 크루가 대기열에 도착하는 시각이&lt;span&gt;&amp;nbsp;&lt;/span&gt;HH:MM&lt;span&gt;&amp;nbsp;&lt;/span&gt;형식으로 이루어져 있다.&lt;/li&gt;
&lt;li&gt;크루의 도착 시각&lt;span&gt;&amp;nbsp;&lt;/span&gt;HH:MM은&lt;span&gt;&amp;nbsp;&lt;/span&gt;00:01에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;23:59&lt;span&gt;&amp;nbsp;&lt;/span&gt;사이이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;출력 형식&lt;/h3&gt;
&lt;p&gt;콘이 무사히 셔틀을 타고 사무실로 갈 수 있는 제일 늦은 도착 시각을 출력한다.&lt;/p&gt;
&lt;p&gt;도착 시각은&lt;span&gt;&amp;nbsp;&lt;/span&gt;HH:MM&lt;span&gt;&amp;nbsp;&lt;/span&gt;형식이며,&lt;span&gt;&amp;nbsp;&lt;/span&gt;00:00에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;23:59&lt;span&gt;&amp;nbsp;&lt;/span&gt;사이의 값이 될 수 있다.&lt;/p&gt;
&lt;h3&gt;입출력 예제&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;t&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;m&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;timetable&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;answer&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;08:00&quot;, &quot;08:01&quot;, &quot;08:02&quot;, &quot;08:03&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;09:00&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;10&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;09:10&quot;, &quot;09:09&quot;, &quot;08:00&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;09:09&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;09:00&quot;, &quot;09:00&quot;, &quot;09:00&quot;, &quot;09:00&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;08:59&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;00:01&quot;, &quot;00:01&quot;, &quot;00:01&quot;, &quot;00:01&quot;, &quot;00:01&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;00:00&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;23:59&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;09:00&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;10&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;60&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;45&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;23:59&quot;,&quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;, &quot;23:59&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;18:00&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618853559671&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

class Solution {
    public int timestampToMinutes(String timestamp) {
        int minute = (timestamp.charAt(3) - '0') * 10 + (timestamp.charAt(4) - '0');
        int hour = (timestamp.charAt(0) - '0') * 10 + timestamp.charAt(1) - '0';
        return hour * 60 + minute;
    }

    public String minutesToTimestamp(int minutes) {
        int hour = minutes / 60;
        int minute = minutes % 60;
        return String.format(&quot;%02d:%02d&quot;, hour, minute);
    }

    public String solution(int n, int t, int m, String[] timetable) {
        Comparator&amp;lt;String&amp;gt; comparator = new Comparator&amp;lt;String&amp;gt;() {
            @Override
            public int compare(String o1, String o2) {
                return timestampToMinutes(o1) - timestampToMinutes(o2);
            }
        };
        Arrays.sort(timetable, comparator);
        ArrayList&amp;lt;Integer&amp;gt;[] peoples = new ArrayList[n];
        for (int i = 0; i &amp;lt; n; ++i) {
            peoples[i] = new ArrayList&amp;lt;&amp;gt;(m);
        }
        int index = 0;
        for (int i = 0; i &amp;lt; timetable.length; ++i) {
            if (index &amp;gt;= n) {
                break;
            }
            int pickMinutes = timestampToMinutes(timetable[i]);
            int timeNow = 60 * 9 + t * index;
            if (pickMinutes &amp;lt;= timeNow) {
                if (peoples[index].size() &amp;lt; m) {
                    peoples[index].add(pickMinutes);
                } else {
                    ++index;
                    --i;
                }
            } else {
                ++index;
                --i;
            }
        }
        int[] ables = new int[n];
        for (int i = 0; i &amp;lt; n; ++i) {
            if (peoples[i].size() &amp;lt; m) {
                ables[i] = 60 * 9 + t * i;
            } else {
                int able = -1;
                int prev = 0;
                for (int j = 0; j &amp;lt; peoples[i].size(); ++j) {
                    int now = peoples[i].get(j);
                    if (now &amp;gt; prev) {
                        able = now - 1;
                    }
                    prev = now;
                }
                ables[i] = able;
            }
        }
        for (int i = n - 1; i &amp;gt;= 0; --i) {
            if (ables[i] != -1) {
                return minutesToTimestamp(ables[i]);
            }
        }
        return null;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level3</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/261</guid>
      <comments>https://ydeer.tistory.com/261#entry261comment</comments>
      <pubDate>Tue, 20 Apr 2021 02:33:22 +0900</pubDate>
    </item>
    <item>
      <title>[Lv3] 입국심사</title>
      <link>https://ydeer.tistory.com/260</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/43238&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/43238&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618828418563&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 입국심사&quot; data-og-description=&quot;n명이 입국심사를 위해 줄을 서서 기다리고 있습니다. 각 입국심사대에 있는 심사관마다 심사하는데 걸리는 시간은 다릅니다. 처음에 모든 심사대는 비어있습니다. 한 심사대에서는 동시에 한 &quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/43238&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/43238&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bxGntZ/hyJWuhg4cs/bSnzyblf6th1qoMswLorB1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bCKng0/hyJUSxipeI/KtksZ3cvdl99xoNKgWYQsK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/43238&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/43238&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bxGntZ/hyJWuhg4cs/bSnzyblf6th1qoMswLorB1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bCKng0/hyJUSxipeI/KtksZ3cvdl99xoNKgWYQsK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 입국심사&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;n명이 입국심사를 위해 줄을 서서 기다리고 있습니다. 각 입국심사대에 있는 심사관마다 심사하는데 걸리는 시간은 다릅니다. 처음에 모든 심사대는 비어있습니다. 한 심사대에서는 동시에 한&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;n명이 입국심사를 위해 줄을 서서 기다리고 있습니다.&lt;/p&gt;
&lt;p&gt;각 입국심사대에 있는 심사관마다 심사하는데 걸리는 시간은 다릅니다.&lt;/p&gt;
&lt;p&gt;처음에 모든 심사대는 비어있습니다. 한 심사대에서는 동시에 한 명만 심사를 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;가장 앞에 서 있는 사람은 비어 있는 심사대로 가서 심사를 받을 수 있습니다.&lt;/p&gt;
&lt;p&gt;하지만 더 빨리 끝나는 심사대가 있으면 기다렸다가 그곳으로 가서 심사를 받을 수도 있습니다.&lt;/p&gt;
&lt;p&gt;모든 사람이 심사를 받는데 걸리는 시간을 최소로 하고 싶습니다.&lt;/p&gt;
&lt;p&gt;입국심사를 기다리는 사람 수 n,&lt;/p&gt;
&lt;p&gt;각 심사관이 한 명을 심사하는데 걸리는 시간이 담긴 배열 times가매개변수로 주어질 때,&lt;/p&gt;
&lt;p&gt;모든 사람이 심사를 받는데 걸리는 시간의 최솟값을 return 하도록 solution 함수를 작성해주세요.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;제한사항&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;입국심사를 기다리는 사람은 1명 이상 1,000,000,000명 이하입니다.&lt;/li&gt;
&lt;li&gt;각 심사관이 한 명을 심사하는데 걸리는 시간은 1분 이상 1,000,000,000분 이하입니다.&lt;/li&gt;
&lt;li&gt;심사관은 1명 이상 100,000명 이하입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;times&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;return&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;6&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[7, 10]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;28&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;가장 첫 두 사람은 바로 심사를 받으러 갑니다.&lt;/p&gt;
&lt;p&gt;7분이 되었을 때, 첫 번째 심사대가 비고 3번째 사람이 심사를 받습니다.&lt;/p&gt;
&lt;p&gt;10분이 되었을 때, 두 번째 심사대가 비고 4번째 사람이 심사를 받습니다.&lt;/p&gt;
&lt;p&gt;14분이 되었을 때, 첫 번째 심사대가 비고 5번째 사람이 심사를 받습니다.&lt;/p&gt;
&lt;p&gt;20분이 되었을 때, 두 번째 심사대가 비지만 6번째 사람이 그곳에서 심사를 받지 않고&lt;/p&gt;
&lt;p&gt;1분을 더 기다린 후에 첫 번째 심사대에서 심사를 받으면 28분에 모든 사람의 심사가 끝납니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618828481022&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

class Solution {
    public long solution(int n, int[] times) {
        Arrays.sort(times);
        if (n == 1) {
            return times[0];
        }
        long start = times[0];
        long end = (long) n * times[times.length - 1];
        while (true) {
            if (start == end) {
                break;
            }
            long mid = (start + end) / 2;
            long loopAnswer = 0L;
            for (int i = 0; i &amp;lt; times.length; ++i) {
                loopAnswer += (mid / times[i]);
            }
            if (loopAnswer &amp;lt; n) {
                start = mid + 1;
            } else {
                end = mid;
            }
        }
        return start;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level3</category>
      <category>programmers</category>
      <category>이분탐색</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/260</guid>
      <comments>https://ydeer.tistory.com/260#entry260comment</comments>
      <pubDate>Mon, 19 Apr 2021 19:34:58 +0900</pubDate>
    </item>
    <item>
      <title>[Lv2] 뉴스 클러스터링</title>
      <link>https://ydeer.tistory.com/259</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17677&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/17677&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618389514367&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - [1차] 뉴스 클러스터링&quot; data-og-description=&quot;뉴스 클러스터링 여러 언론사에서 쏟아지는 뉴스, 특히 속보성 뉴스를 보면 비슷비슷한 제목의 기사가 많아 정작 필요한 기사를 찾기가 어렵다. Daum 뉴스의 개발 업무를 맡게 된 신입사원 튜브&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17677&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17677&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bvNOr8/hyJTIM12qG/1hCacHAk9tYwOuyHldZfg1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/GDWyd/hyJSjH6BRp/iqlAiaXTMWgNKVviXoUHy0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17677&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17677&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bvNOr8/hyJTIM12qG/1hCacHAk9tYwOuyHldZfg1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/GDWyd/hyJSjH6BRp/iqlAiaXTMWgNKVviXoUHy0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - [1차] 뉴스 클러스터링&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;뉴스 클러스터링 여러 언론사에서 쏟아지는 뉴스, 특히 속보성 뉴스를 보면 비슷비슷한 제목의 기사가 많아 정작 필요한 기사를 찾기가 어렵다. Daum 뉴스의 개발 업무를 맡게 된 신입사원 튜브&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;h2&gt;뉴스 클러스터링&lt;/h2&gt;
&lt;p&gt;여러 언론사에서 쏟아지는 뉴스, 특히 속보성 뉴스를 보면 비슷비슷한 제목의 기사가 많아 정작 필요한 기사를 찾기가 어렵다.&lt;/p&gt;
&lt;p&gt;Daum 뉴스의 개발 업무를 맡게 된 신입사원 튜브는 사용자들이 편리하게 다양한 뉴스를 찾아볼 수 있도록 문제점을 개선하는 업무를 맡게 되었다.&lt;/p&gt;
&lt;p&gt;개발의 방향을 잡기 위해 튜브는 우선 최근 화제가 되고 있는 &quot;카카오 신입 개발자 공채&quot; 관련 기사를 검색해보았다.&lt;/p&gt;
&lt;ul&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;li&gt;카카오, 신입 공채.. &quot;코딩 실력만 본다&quot;&lt;/li&gt;
&lt;li&gt;카카오 &quot;코딩 능력만으로 2018 신입 개발자 뽑는다&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;기사의 제목을 기준으로 &quot;블라인드 전형&quot;에 주목하는 기사와 &quot;코딩 테스트&quot;에 주목하는 기사로 나뉘는 걸 발견했다.&lt;/p&gt;
&lt;p&gt;튜브는 이들을 각각 묶어서 보여주면 카카오 공채 관련 기사를 찾아보는 사용자에게 유용할 듯싶었다.&lt;/p&gt;
&lt;p&gt;유사한 기사를 묶는 기준을 정하기 위해서 논문과 자료를 조사하던 튜브는 &quot;자카드 유사도&quot;라는 방법을 찾아냈다.&lt;/p&gt;
&lt;p&gt;자카드 유사도는 집합 간의 유사도를 검사하는 여러 방법 중의 하나로 알려져 있다.&lt;/p&gt;
&lt;p&gt;두 집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A,&lt;span&gt;&amp;nbsp;&lt;/span&gt;B&lt;span&gt;&amp;nbsp;&lt;/span&gt;사이의 자카드 유사도&lt;span&gt;&amp;nbsp;&lt;/span&gt;J(A, B)는 두 집합의 교집합 크기를 두 집합의 합집합 크기로 나눈 값으로 정의된다.&lt;/p&gt;
&lt;p&gt;예를 들어 집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A&lt;span&gt;&amp;nbsp;&lt;/span&gt;= {1, 2, 3}, 집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;B&lt;span&gt;&amp;nbsp;&lt;/span&gt;= {2, 3, 4}라고 할 때, 교집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A &amp;cap; B&lt;span&gt;&amp;nbsp;&lt;/span&gt;= {2, 3}, 합집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A &amp;cup; B&lt;span&gt;&amp;nbsp;&lt;/span&gt;= {1, 2, 3, 4}이 되므로,&lt;/p&gt;
&lt;p&gt;집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A,&lt;span&gt;&amp;nbsp;&lt;/span&gt;B&lt;span&gt;&amp;nbsp;&lt;/span&gt;사이의 자카드 유사도&lt;span&gt;&amp;nbsp;&lt;/span&gt;J(A, B)&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 2/4 = 0.5가 된다.&lt;/p&gt;
&lt;p&gt;집합 A와 집합 B가 모두 공집합일 경우에는 나눗셈이 정의되지 않으니 따로&lt;span&gt;&amp;nbsp;&lt;/span&gt;J(A, B)&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 1로 정의한다.&lt;/p&gt;
&lt;p&gt;자카드 유사도는 원소의 중복을 허용하는 다중집합에 대해서 확장할 수 있다.&lt;/p&gt;
&lt;p&gt;다중집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A는 원소 &quot;1&quot;을 3개 가지고 있고,&lt;/p&gt;
&lt;p&gt;다중집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;B는 원소 &quot;1&quot;을 5개 가지고 있다고 하자.&lt;/p&gt;
&lt;p&gt;이 다중집합의 교집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A &amp;cap; B는 원소 &quot;1&quot;을 min(3, 5)인 3개, 합집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A &amp;cup; B는 원소 &quot;1&quot;을 max(3, 5)인 5개 가지게 된다.&lt;/p&gt;
&lt;p&gt;다중집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A&lt;span&gt;&amp;nbsp;&lt;/span&gt;= {1, 1, 2, 2, 3}, 다중집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;B&lt;span&gt;&amp;nbsp;&lt;/span&gt;= {1, 2, 2, 4, 5}라고 하면,&lt;/p&gt;
&lt;p&gt;교집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A &amp;cap; B&lt;span&gt;&amp;nbsp;&lt;/span&gt;= {1, 2, 2}, 합집합&lt;span&gt;&amp;nbsp;&lt;/span&gt;A &amp;cup; B&lt;span&gt;&amp;nbsp;&lt;/span&gt;= {1, 1, 2, 2, 3, 4, 5}가 되므로, 자카드 유사도&lt;span&gt;&amp;nbsp;&lt;/span&gt;J(A, B)&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 3/7, 약 0.42가 된다.&lt;/p&gt;
&lt;p&gt;이를 이용하여 문자열 사이의 유사도를 계산하는데 이용할 수 있다. 문자열 &quot;FRANCE&quot;와 &quot;FRENCH&quot;가 주어졌을 때,&lt;/p&gt;
&lt;p&gt;이를 두 글자씩 끊어서 다중집합을 만들 수 있다.&lt;/p&gt;
&lt;p&gt;각각 {FR, RA, AN, NC, CE}, {FR, RE, EN, NC, CH}가 되며, 교집합은 {FR, NC},&lt;/p&gt;
&lt;p&gt;합집합은 {FR, RA, AN, NC, CE, RE, EN, CH}가 되므로,&lt;/p&gt;
&lt;p&gt;두 문자열 사이의 자카드 유사도&lt;span&gt;&amp;nbsp;&lt;/span&gt;J(&quot;FRANCE&quot;, &quot;FRENCH&quot;)&lt;span&gt;&amp;nbsp;&lt;/span&gt;= 2/8 = 0.25가 된다.&lt;/p&gt;
&lt;h3&gt;입력 형식&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;입력으로는&lt;span&gt;&amp;nbsp;&lt;/span&gt;str1과&lt;span&gt;&amp;nbsp;&lt;/span&gt;str2의 두 문자열이 들어온다. 각 문자열의 길이는 2 이상, 1,000 이하이다.&lt;/li&gt;
&lt;li&gt;입력으로 들어온 문자열은 두 글자씩 끊어서 다중집합의 원소로 만든다. 이때 영문자로 된 글자 쌍만 유효하고, 기타 공백이나 숫자, 특수 문자가 들어있는 경우는 그 글자 쌍을 버린다. 예를 들어 &quot;ab+&quot;가 입력으로 들어오면, &quot;ab&quot;만 다중집합의 원소로 삼고, &quot;b+&quot;는 버린다.&lt;/li&gt;
&lt;li&gt;다중집합 원소 사이를 비교할 때, 대문자와 소문자의 차이는 무시한다. &quot;AB&quot;와 &quot;Ab&quot;, &quot;ab&quot;는 같은 원소로 취급한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;출력 형식&lt;/h3&gt;
&lt;p&gt;입력으로 들어온 두 문자열의 자카드 유사도를 출력한다.&lt;/p&gt;
&lt;p&gt;유사도 값은 0에서 1 사이의 실수이므로, 이를 다루기 쉽도록 65536을 곱한 후에 소수점 아래를 버리고 정수부만 출력한다.&lt;/p&gt;
&lt;h3&gt;예제 입출력&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;str1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;str2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;answer&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;FRANCE&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;french&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;16384&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;handshake&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;shake hands&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;65536&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;aa1+aa2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;AAAA12&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;43690&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;E=M*C^2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;e=m*c^2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;65536&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618389652684&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Collections;

class Solution {
    public int solution(String str1, String str2) {
        ArrayList&amp;lt;String&amp;gt; list1 = new ArrayList&amp;lt;&amp;gt;(str1.length() - 1);
        ArrayList&amp;lt;String&amp;gt; list2 = new ArrayList&amp;lt;&amp;gt;(str2.length() - 1);
        char[] chars1 = str1.toUpperCase().toCharArray();
        char[] chars2 = str2.toUpperCase().toCharArray();
        for (int i = 0; i &amp;lt; chars1.length - 1; ++i) {
            if (chars1[i] &amp;gt;= 'A' &amp;amp;&amp;amp; chars1[i] &amp;lt;= 'Z' &amp;amp;&amp;amp; chars1[i + 1] &amp;gt;= 'A' &amp;amp;&amp;amp; chars1[i + 1] &amp;lt;= 'Z') {
                list1.add(String.format(&quot;%c%c&quot;, chars1[i], chars1[i + 1]));
            }
        }
        for (int i = 0; i &amp;lt; chars2.length - 1; ++i) {
            if (chars2[i] &amp;gt;= 'A' &amp;amp;&amp;amp; chars2[i] &amp;lt;= 'Z' &amp;amp;&amp;amp; chars2[i + 1] &amp;gt;= 'A' &amp;amp;&amp;amp; chars2[i + 1] &amp;lt;= 'Z') {
                list2.add(String.format(&quot;%c%c&quot;, chars2[i], chars2[i + 1]));
            }
        }
        if (list1.isEmpty() &amp;amp;&amp;amp; list2.isEmpty()) {
            return 65536;
        }
        Collections.sort(list1);
        Collections.sort(list2);
        String[] strings1 = list1.toArray(new String[list1.size()]);
        String[] strings2 = list2.toArray(new String[list2.size()]);
//        System.out.println(Arrays.toString(strings1));
//        System.out.println(Arrays.toString(strings2));
        String[] small = null;
        String[] big = null;
        if (strings1.length &amp;lt;= strings2.length) {
            small = strings1;
            big = strings2;
        } else {
            small = strings2;
            big = strings1;
        }
        ArrayList&amp;lt;String&amp;gt; intersection = new ArrayList&amp;lt;&amp;gt;(small.length);
        int indexSmall = 0;
        int indexBig = 0;
        while (indexSmall &amp;lt; small.length &amp;amp;&amp;amp; indexBig &amp;lt; big.length) {
            int resultCompare = big[indexBig].compareTo(small[indexSmall]);
//            System.out.println(String.format(&quot;%d - %s / %s&quot;, resultCompare, small[indexSmall], big[indexBig]));
            if (resultCompare == 0) {
                intersection.add(small[indexSmall]);
                ++indexSmall;
                ++indexBig;
            } else if (resultCompare &amp;lt; 0) {
                ++indexBig;
            } else {
                ++indexSmall;
            }
        }
        indexSmall = 0;
        indexBig = 0;
        int indexIntersection = 0;
        ArrayList&amp;lt;String&amp;gt; union = new ArrayList&amp;lt;&amp;gt;(list1.size() + list2.size());
        while (true) {
            if (indexSmall &amp;lt; small.length &amp;amp;&amp;amp; indexBig &amp;lt; big.length) {
                int resultCompare = big[indexBig].compareTo(small[indexSmall]);
                if (resultCompare == 0) {
                    String stringSame = big[indexBig];
                    while (indexIntersection &amp;lt; intersection.size()) {
                        String stringIntersection = intersection.get(indexIntersection);
                        if (stringSame.equals(stringIntersection)) {
                            ++indexIntersection;
                        } else {
                            break;
                        }
                    }
                    int countInSmall = 0;
                    while (indexSmall &amp;lt; small.length) {
                        if (small[indexSmall].equals(stringSame) == false) {
                            break;
                        }
                        ++indexSmall;
                        ++countInSmall;
                    }
                    int countInBig = 0;
                    while (indexBig &amp;lt; big.length) {
                        if (big[indexBig].equals(stringSame) == false) {
                            break;
                        }
                        ++indexBig;
                        ++countInBig;
                    }
                    for (int i = 0; i &amp;lt; Math.max(countInSmall, countInBig); ++i) {
                        union.add(stringSame);
                    }
                } else if (resultCompare &amp;lt; 0) {
                    union.add(big[indexBig++]);
                } else {
                    union.add(small[indexSmall++]);
                }
            } else if (indexSmall &amp;lt; small.length) {
                union.add(small[indexSmall++]);
            } else if (indexBig &amp;lt; big.length) {
                union.add(big[indexBig++]);
            } else {
                break;
            }
        }
//        System.out.print(String.format(&quot;교집합: %d - [&quot;, intersection.size()));
//        for (String str : intersection) {
//            System.out.print(String.format(&quot;%s, &quot;, str));
//        }
//        System.out.println(&quot;]&quot;);
//        System.out.print(String.format(&quot;합집합: %d - [&quot;, union.size()));
//        for (String str : union) {
//            System.out.print(String.format(&quot;%s, &quot;, str));
//        }
//        System.out.println(&quot;]&quot;);
        return (int) ((double) intersection.size() / union.size() * 65536);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>LEVEL2</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/259</guid>
      <comments>https://ydeer.tistory.com/259#entry259comment</comments>
      <pubDate>Wed, 14 Apr 2021 17:41:53 +0900</pubDate>
    </item>
    <item>
      <title>[Lv2] 튜플</title>
      <link>https://ydeer.tistory.com/258</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/64065&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/64065&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618383933421&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 튜플&quot; data-og-description=&quot;&amp;quot;{{2},{2,1},{2,1,3},{2,1,3,4}}&amp;quot; [2, 1, 3, 4] &amp;quot;{{1,2,3},{2,1},{1,2,4,3},{2}}&amp;quot; [2, 1, 3, 4] &amp;quot;{{4,2,3},{3},{2,3,4,1},{2,3}}&amp;quot; [3, 2, 4, 1]&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/64065&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/64065&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/2b3yz/hyJSg5EJRx/sZzOsfgQ5SMsPt6W5EW3S1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/NSoym/hyJSb4lwt2/DUyL2fn4DPkAB7NeL0LQGK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/64065&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/64065&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/2b3yz/hyJSg5EJRx/sZzOsfgQ5SMsPt6W5EW3S1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/NSoym/hyJSb4lwt2/DUyL2fn4DPkAB7NeL0LQGK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 튜플&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&quot;{{2},{2,1},{2,1,3},{2,1,3,4}}&quot; [2, 1, 3, 4] &quot;{{1,2,3},{2,1},{1,2,4,3},{2}}&quot; [2, 1, 3, 4] &quot;{{4,2,3},{3},{2,3,4,1},{2,3}}&quot; [3, 2, 4, 1]&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;셀수있는 수량의 순서있는 열거 또는 어떤 순서를 따르는 요소들의 모음을 튜플(tuple)이라고 합니다.&lt;/p&gt;
&lt;p&gt;n개의 요소를 가진 튜플을 n-튜플(n-tuple)이라고 하며, 다음과 같이 표현할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;(a1, a2, a3, ..., an)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;튜플은 다음과 같은 성질을 가지고 있습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;중복된 원소가 있을 수 있습니다. ex : (2, 3, 1, 2)&lt;/li&gt;
&lt;li&gt;원소에 정해진 순서가 있으며, 원소의 순서가 다르면 서로 다른 튜플입니다. ex : (1, 2, 3) &amp;ne; (1, 3, 2)&lt;/li&gt;
&lt;li&gt;튜플의 원소 개수는 유한합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;원소의 개수가 n개이고,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;&lt;b&gt;중복되는 원소가 없는&lt;/b&gt;&lt;/u&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;튜플&lt;span&gt;&amp;nbsp;&lt;/span&gt;(a1, a2, a3, ..., an)이 주어질 때(단, a1, a2, ..., an은 자연수),&lt;/p&gt;
&lt;p&gt;이는 다음과 같이 집합 기호 '{', '}'를 이용해 표현할 수 있습니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;{{a1}, {a1, a2}, {a1, a2, a3}, {a1, a2, a3, a4}, ... {a1, a2, a3, a4, ..., an}}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;예를 들어 튜플이 (2, 1, 3, 4)인 경우 이는&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;{{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;와 같이 표현할 수 있습니다. 이때, 집합은 원소의 순서가 바뀌어도 상관없으므로&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;{{2}, {2, 1}, {2, 1, 3}, {2, 1, 3, 4}}&lt;/li&gt;
&lt;li&gt;{{2, 1, 3, 4}, {2}, {2, 1, 3}, {2, 1}}&lt;/li&gt;
&lt;li&gt;{{1, 2, 3}, {2, 1}, {1, 2, 4, 3}, {2}}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;는 모두 같은 튜플 (2, 1, 3, 4)를 나타냅니다.&lt;/p&gt;
&lt;p&gt;특정 튜플을 표현하는 집합이 담긴 문자열 s가 매개변수로 주어질 때,&lt;/p&gt;
&lt;p&gt;s가 표현하는 튜플을 배열에 담아 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;[제한사항]&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;s의 길이는 5 이상 1,000,000 이하입니다.&lt;/li&gt;
&lt;li&gt;s는 숫자와 '{', '}', ',' 로만 이루어져 있습니다.&lt;/li&gt;
&lt;li&gt;숫자가 0으로 시작하는 경우는 없습니다.&lt;/li&gt;
&lt;li&gt;s는 항상 중복되는 원소가 없는 튜플을 올바르게 표현하고 있습니다.&lt;/li&gt;
&lt;li&gt;s가 표현하는 튜플의 원소는 1 이상 100,000 이하인 자연수입니다.&lt;/li&gt;
&lt;li&gt;return 하는 배열의 길이가 1 이상 500 이하인 경우만 입력으로 주어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;[입출력 예]&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;s&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;{{2},{2,1},{2,1,3},{2,1,3,4}}&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[2, 1, 3, 4]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;{{1,2,3},{2,1},{1,2,4,3},{2}}&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[2, 1, 3, 4]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;{{20,111},{111}}&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[111, 20]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;{{123}}&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[123]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;{{4,2,3},{3},{2,3,4,1},{2,3}}&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[3, 2, 4, 1]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예에 대한 설명&lt;/b&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문제 예시와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문제 예시와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #3&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;(111, 20)을 집합 기호를 이용해 표현하면 {{111}, {111,20}}이 되며, 이는 {{20,111},{111}}과 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #4&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;(123)을 집합 기호를 이용해 표현하면 {{123}} 입니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #5&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;(3, 2, 4, 1)을 집합 기호를 이용해 표현하면 {{3},{3,2},{3,2,4},{3,2,4,1}}이 되며, 이는 {{4,2,3},{3},{2,3,4,1},{2,3}}과 같습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618384011399&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;
import java.util.Comparator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Solution {
    public int[] solution(String s) {
        String regex = &quot;\\{((\\d+\\,*)+)\\}&quot;;
        Matcher matcher = Pattern.compile(regex).matcher(s);
        int count = 0;
        while (matcher.find()) {
            ++count;
        }
        matcher.reset();
        if (count == 1) {
            matcher.find();
            return new int[] { Integer.parseInt(matcher.group(1)) };
        }
        String[] strings = new String[count];
        for (int i = 0; i &amp;lt; count; ++i) {
            matcher.find();
            strings[i] = matcher.group(1);
        }
        Comparator&amp;lt;String&amp;gt; comparator = new Comparator&amp;lt;String&amp;gt;() {
            @Override
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        };
        Arrays.sort(strings, comparator);
        int[] answer = new int[count];
        regex = &quot;\\d+&quot;;
        for (int i = 0; i &amp;lt; count; ++i) {
            matcher = Pattern.compile(regex).matcher(strings[i]);
            loop2:
            for (int j = 0; j &amp;lt;= i; ++j) {
                matcher.find();
                int number = Integer.parseInt(matcher.group());
                if (i == 0) {
                    answer[0] = number;
                    break;
                }
                for (int k = 0; k &amp;lt; i; ++k) {
                    if (number == answer[k]) {
                        continue loop2;
                    }
                }
                answer[i] = number;
            }
        }
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>LEVEL2</category>
      <category>programmers</category>
      <category>regex</category>
      <category>정규표현식</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/258</guid>
      <comments>https://ydeer.tistory.com/258#entry258comment</comments>
      <pubDate>Wed, 14 Apr 2021 16:07:06 +0900</pubDate>
    </item>
    <item>
      <title>[Lv2] 문자열 압축</title>
      <link>https://ydeer.tistory.com/257</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/60057&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/60057&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618303722824&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 문자열 압축&quot; data-og-description=&quot;데이터 처리 전문가가 되고 싶은 &amp;quot;어피치&amp;quot;는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60057&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60057&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cF5fds/hyJSbbo03c/pLlS0FOyot1AOwyi6Uvwe1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/fMz6u/hyJSou2InW/6EKb6VWfbUqeaVkh6Gv1d0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/60057&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60057&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cF5fds/hyJSbbo03c/pLlS0FOyot1AOwyi6Uvwe1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/fMz6u/hyJSou2InW/6EKb6VWfbUqeaVkh6Gv1d0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 문자열 압축&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;데이터 처리 전문가가 되고 싶은 &quot;어피치&quot;는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다. 최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데, 문&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;데이터 처리 전문가가 되고 싶은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&quot;어피치&quot;&lt;/b&gt;는 문자열을 압축하는 방법에 대해 공부를 하고 있습니다.&lt;/p&gt;
&lt;p&gt;최근에 대량의 데이터 처리를 위한 간단한 비손실 압축 방법에 대해 공부를 하고 있는데,&lt;/p&gt;
&lt;p&gt;문자열에서 같은 값이 연속해서 나타나는 것을 그 문자의 개수와 반복되는 값으로 표현하여&lt;/p&gt;
&lt;p&gt;더 짧은 문자열로 줄여서 표현하는 알고리즘을 공부하고 있습니다.&lt;/p&gt;
&lt;p&gt;간단한 예로 &quot;aabbaccc&quot;의 경우 &quot;2a2ba3c&quot;(문자가 반복되지 않아 한번만 나타난 경우 1은 생략함)와 같이&lt;/p&gt;
&lt;p&gt;표현할 수 있는데, 이러한 방식은 반복되는 문자가 적은 경우 압축률이 낮다는 단점이 있습니다.&lt;/p&gt;
&lt;p&gt;예를 들면, &quot;abcabcdede&quot;와 같은 문자열은 전혀 압축되지 않습니다.&lt;/p&gt;
&lt;p&gt;&quot;어피치&quot;는 이러한 단점을 해결하기 위해 문자열을 1개 이상의 단위로 잘라서 압축하여&lt;/p&gt;
&lt;p&gt;더 짧은 문자열로 표현할 수 있는지 방법을 찾아보려고 합니다.&lt;/p&gt;
&lt;p&gt;예를 들어, &quot;ababcdcdababcdcd&quot;의 경우 문자를 1개 단위로 자르면 전혀 압축되지 않지만,&lt;/p&gt;
&lt;p&gt;2개 단위로 잘라서 압축한다면 &quot;2ab2cd2ab2cd&quot;로 표현할 수 있습니다.&lt;/p&gt;
&lt;p&gt;다른 방법으로 8개 단위로 잘라서 압축한다면 &quot;2ababcdcd&quot;로 표현할 수 있으며,&lt;/p&gt;
&lt;p&gt;이때가 가장 짧게 압축하여 표현할 수 있는 방법입니다.&lt;/p&gt;
&lt;p&gt;다른 예로, &quot;abcabcdede&quot;와 같은 경우, 문자를 2개 단위로 잘라서 압축하면 &quot;abcabc2de&quot;가 되지만,&lt;/p&gt;
&lt;p&gt;3개 단위로 자른다면 &quot;2abcdede&quot;가 되어 3개 단위가 가장 짧은 압축 방법이 됩니다.&lt;/p&gt;
&lt;p&gt;이때 3개 단위로 자르고 마지막에 남는 문자열은 그대로 붙여주면 됩니다.&lt;/p&gt;
&lt;p&gt;압축할 문자열 s가 매개변수로 주어질 때,&lt;/p&gt;
&lt;p&gt;위에 설명한 방법으로 1개 이상 단위로 문자열을 잘라 압축하여 표현한 문자열 중 가장 짧은 것의 길이를 return 하도록&lt;/p&gt;
&lt;p&gt;solution 함수를 완성해주세요.&lt;/p&gt;
&lt;h3&gt;제한사항&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;s의 길이는 1 이상 1,000 이하입니다.&lt;/li&gt;
&lt;li&gt;s는 알파벳 소문자로만 이루어져 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;s&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;aabbaccc&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;7&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;ababcdcdababcdcd&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;9&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;abcabcdede&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;8&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;abcabcabcabcdededededede&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;14&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;xababcdcdababcdcd&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;17&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;입출력 예에 대한 설명&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문자열을 1개 단위로 잘라 압축했을 때 가장 짧습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문자열을 8개 단위로 잘라 압축했을 때 가장 짧습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #3&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문자열을 3개 단위로 잘라 압축했을 때 가장 짧습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #4&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문자열을 2개 단위로 자르면 &quot;abcabcabcabc6de&quot; 가 됩니다.&lt;/p&gt;
&lt;p&gt;문자열을 3개 단위로 자르면 &quot;4abcdededededede&quot; 가 됩니다.&lt;/p&gt;
&lt;p&gt;문자열을 4개 단위로 자르면 &quot;abcabcabcabc3dede&quot; 가 됩니다.&lt;/p&gt;
&lt;p&gt;문자열을 6개 단위로 자를 경우 &quot;2abcabc2dedede&quot;가 되며, 이때의 길이가 14로 가장 짧습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #5&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문자열은 제일 앞부터 정해진 길이만큼 잘라야 합니다.&lt;/p&gt;
&lt;p&gt;따라서 주어진 문자열을 x / ababcdcd / ababcdcd 로 자르는 것은 불가능 합니다.&lt;/p&gt;
&lt;p&gt;이 경우 어떻게 문자열을 잘라도 압축되지 않으므로 가장 짧은 길이는 17이 됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618303772798&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int solution(String s) {
    System.out.println(String.format(&quot;[000] %s: %d&quot;, s, s.length()));
    int answer = s.length();
    for (int i = 1; i &amp;lt;= s.length() / 2; ++i) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int j = 0; j &amp;lt; s.length(); ++j) {
            int endIndex = j + i;
            if (endIndex &amp;gt; s.length()) {
                System.out.printf(String.format(&quot;(%s)&quot;, s.substring(j)));
                stringBuilder.append(s.substring(j));
                break;
            } else {
                String piece = s.substring(j, j + i);
                for (int k = endIndex; k &amp;lt; s.length(); k += i) {
                    if (k + i &amp;gt; s.length()) {
                        break;
                    }
                    if (s.substring(k, k + i).equals(piece) == true) {
                        endIndex = k + i;
                    } else {
                        break;
                    }
                }
                int repeat = (endIndex - j) / i;
                if (repeat &amp;gt; 1) {
                    stringBuilder.append(repeat);
                    System.out.printf(String.format(&quot;{%d%s}&quot;, repeat, piece));
                } else {
                    System.out.printf(String.format(&quot;[%s]&quot;, piece));
                }
                stringBuilder.append(piece);
                j = endIndex - 1;
            }
        }
        int length = stringBuilder.length();
//            if (length &amp;gt; 0 &amp;amp;&amp;amp; length &amp;lt; answer) {
        if (length &amp;gt; 0) {
            System.out.println(String.format(&quot; - [%03d] %s: %d&quot;, i, stringBuilder.toString(), stringBuilder.length()));
            if (length &amp;lt; answer) {
                answer = length;
            }
        }
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>LEVEL2</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/257</guid>
      <comments>https://ydeer.tistory.com/257#entry257comment</comments>
      <pubDate>Tue, 13 Apr 2021 17:50:50 +0900</pubDate>
    </item>
    <item>
      <title>[Lv1] 3진법 뒤집기</title>
      <link>https://ydeer.tistory.com/256</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/68935&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/68935&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618297007474&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 3진법 뒤집기&quot; data-og-description=&quot;자연수 n이 매개변수로 주어집니다. n을 3진법 상에서 앞뒤로 뒤집은 후, 이를 다시 10진법으로 표현한 수를 return 하도록 solution 함수를 완성해주세요. 제한사항 n은 1 이상 100,000,000 이하인 자연수&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/68935&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/68935&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/GLAdQ/hyJSai9iqM/kkskfW0KO4jFgEjVghgee0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/tp3t3/hyJSelxoXi/6nUk8snix8rMXEl1g9FRI1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/68935&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/68935&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/GLAdQ/hyJSai9iqM/kkskfW0KO4jFgEjVghgee0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/tp3t3/hyJSelxoXi/6nUk8snix8rMXEl1g9FRI1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 3진법 뒤집기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;자연수 n이 매개변수로 주어집니다. n을 3진법 상에서 앞뒤로 뒤집은 후, 이를 다시 10진법으로 표현한 수를 return 하도록 solution 함수를 완성해주세요. 제한사항 n은 1 이상 100,000,000 이하인 자연수&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;자연수 n이 매개변수로 주어집니다. n을 3진법 상에서 앞뒤로 뒤집은 후, 이를 다시 10진법으로 표현한 수를 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;제한사항&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;n은 1 이상 100,000,000 이하인 자연수입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;45&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;7&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;125&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;229&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;입출력 예 #1&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;답을 도출하는 과정은 다음과 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n (10진법)&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;n (3진법)&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;앞뒤 반전(3진법)&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;10진법으로 표현&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;45&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1200&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;0021&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;7&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;따라서 7을 return 해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;입출력 예 #2&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;답을 도출하는 과정은 다음과 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n (10진법)&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;n (3진법)&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;앞뒤 반전(3진법)&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;10진법으로 표현&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;125&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;11122&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;22111&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;229&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;따라서 229를 return 해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618297107019&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int solution(int n) {
    StringBuilder stringBuilder = new StringBuilder();
    while (n &amp;gt; 2) {
        stringBuilder.append(n % 3);
        n /= 3;
    }
    if (n &amp;gt; 0) {
        stringBuilder.append(n);
    }
    char[] array = stringBuilder.reverse().toString().toCharArray();
    int answer = 0;
    for (int i = 0; i &amp;lt; array.length; ++i) {
        answer += (Math.pow(3, i) * (array[i] - '0'));
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level1</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/256</guid>
      <comments>https://ydeer.tistory.com/256#entry256comment</comments>
      <pubDate>Tue, 13 Apr 2021 15:58:43 +0900</pubDate>
    </item>
    <item>
      <title>[Lv1] 키패드 누르기</title>
      <link>https://ydeer.tistory.com/255</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/67256&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618295807264&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 키패드 누르기&quot; data-og-description=&quot;[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] &amp;quot;right&amp;quot; &amp;quot;LRLLLRLLRRL&amp;quot; [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] &amp;quot;left&amp;quot; &amp;quot;LRLLRRLLLRR&amp;quot; [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] &amp;quot;right&amp;quot; &amp;quot;LLRLLRLLRL&amp;quot;&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/CNvXX/hyJSbI5BJJ/mN0c0R4dLjldU7Ae8VNSUK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/gDcuj/hyJSiBsioR/kwFNwb9P1SWFjkS58bovN1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/dV4NWM/hyJSboMJE8/jTArDi8KXUdPQ1P9k8vJmK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/67256&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/CNvXX/hyJSbI5BJJ/mN0c0R4dLjldU7Ae8VNSUK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/gDcuj/hyJSiBsioR/kwFNwb9P1SWFjkS58bovN1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/dV4NWM/hyJSboMJE8/jTArDi8KXUdPQ1P9k8vJmK/img.png?width=1000&amp;amp;height=1000&amp;amp;face=0_0_1000_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 키패드 누르기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5] &quot;right&quot; &quot;LRLLLRLLRRL&quot; [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2] &quot;left&quot; &quot;LRLLRRLLLRR&quot; [1, 2, 3, 4, 5, 6, 7, 8, 9, 0] &quot;right&quot; &quot;LLRLLRLLRL&quot;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;스마트폰 전화 키패드의 각 칸에 다음과 같이 숫자들이 적혀 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EiT00/btq2qw5pqd6/43kLzUYsihGQNfRv8pC9Qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EiT00/btq2qw5pqd6/43kLzUYsihGQNfRv8pC9Qk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EiT00/btq2qw5pqd6/43kLzUYsihGQNfRv8pC9Qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEiT00%2Fbtq2qw5pqd6%2F43kLzUYsihGQNfRv8pC9Qk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;이 전화 키패드에서 왼손과 오른손의 엄지손가락만을 이용해서 숫자만을 입력하려고 합니다.&lt;/p&gt;
&lt;p&gt;맨 처음 왼손 엄지손가락은&lt;span&gt;&amp;nbsp;&lt;/span&gt;*&lt;span&gt;&amp;nbsp;&lt;/span&gt;키패드에 오른손 엄지손가락은&lt;span&gt;&amp;nbsp;&lt;/span&gt;#&lt;span&gt;&amp;nbsp;&lt;/span&gt;키패드 위치에서 시작하며, 엄지손가락을 사용하는 규칙은 다음과 같습니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;엄지손가락은 상하좌우 4가지 방향으로만 이동할 수 있으며 키패드 이동 한 칸은 거리로 1에 해당합니다.&lt;/li&gt;
&lt;li&gt;왼쪽 열의 3개의 숫자&lt;span&gt;&amp;nbsp;&lt;/span&gt;1,&lt;span&gt;&amp;nbsp;&lt;/span&gt;4,&lt;span&gt;&amp;nbsp;&lt;/span&gt;7을 입력할 때는 왼손 엄지손가락을 사용합니다.&lt;/li&gt;
&lt;li&gt;오른쪽 열의 3개의 숫자&lt;span&gt;&amp;nbsp;&lt;/span&gt;3,&lt;span&gt;&amp;nbsp;&lt;/span&gt;6,&lt;span&gt;&amp;nbsp;&lt;/span&gt;9를 입력할 때는 오른손 엄지손가락을 사용합니다.&lt;/li&gt;
&lt;li&gt;가운데 열의 4개의 숫자&lt;span&gt;&amp;nbsp;&lt;/span&gt;2,&lt;span&gt;&amp;nbsp;&lt;/span&gt;5,&lt;span&gt;&amp;nbsp;&lt;/span&gt;8,&lt;span&gt;&amp;nbsp;&lt;/span&gt;0을 입력할 때는 두 엄지손가락의 현재 키패드의 위치에서 더 가까운 엄지손가락을 사용합니다.4-1. 만약 두 엄지손가락의 거리가 같다면, 오른손잡이는 오른손 엄지손가락, 왼손잡이는 왼손 엄지손가락을 사용합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;순서대로 누를 번호가 담긴 배열 numbers, 왼손잡이인지 오른손잡이인 지를 나타내는 문자열 hand가 매개변수로 주어질 때,&lt;/p&gt;
&lt;p&gt;각 번호를 누른 엄지손가락이 왼손인 지 오른손인 지를 나타내는 연속된 문자열 형태로 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;[제한사항]&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;numbers 배열의 크기는 1 이상 1,000 이하입니다.&lt;/li&gt;
&lt;li&gt;numbers 배열 원소의 값은 0 이상 9 이하인 정수입니다.&lt;/li&gt;
&lt;li&gt;hand는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;left&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;또는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;right&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;입니다.
&lt;ul&gt;
&lt;li&gt;&quot;left&quot;는 왼손잡이,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;right&quot;는 오른손잡이를 의미합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;왼손 엄지손가락을 사용한 경우는&lt;span&gt;&amp;nbsp;&lt;/span&gt;L, 오른손 엄지손가락을 사용한 경우는&lt;span&gt;&amp;nbsp;&lt;/span&gt;R을 순서대로 이어붙여 문자열 형태로 return 해주세요.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;numbers&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;hand&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;[1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;right&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;LRLLLRLLRRL&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;[7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;left&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;LRLLRRLLLRR&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;right&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;LLRLLRLLRL&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예에 대한 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;순서대로 눌러야 할 번호가 [1, 3, 4, 5, 8, 2, 1, 4, 5, 9, 5]이고, 오른손잡이입니다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;왼손 위치&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;오른손 위치&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;눌러야 할 숫자&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;사용한 손&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;설명&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;*&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;#&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;L&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1은 왼손으로 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;#&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;R&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3은 오른손으로 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;L&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;4는 왼손으로 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;L&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;왼손 거리는 1, 오른손 거리는 2이므로 왼손으로 5를 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;8&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;L&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;왼손 거리는 1, 오른손 거리는 3이므로 왼손으로 8을 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;8&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;R&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;왼손 거리는 2, 오른손 거리는 1이므로 오른손으로 2를 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;8&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;L&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1은 왼손으로 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;L&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;4는 왼손으로 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;R&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;왼손 거리와 오른손 거리가 1로 같으므로, 오른손으로 5를 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;9&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;R&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;9는 오른손으로 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;9&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;L&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;왼손 거리는 1, 오른손 거리는 2이므로 왼손으로 5를 누릅니다.&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;9&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;-&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;-&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;따라서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;LRLLLRLLRRL&quot;를 return 합니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;왼손잡이가 [7, 0, 8, 2, 8, 3, 1, 5, 7, 6, 2]를 순서대로 누르면 사용한 손은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;LRLLRRLLLRR&quot;이 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #3&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;오른손잡이가 [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]를 순서대로 누르면 사용한 손은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;LLRLLRLLRL&quot;이 됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618296030667&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public String solution(int[] numbers, String hand) {
    int[] leftHandPosition = new int[] { 3, 0 };
    int[] rightHandPosition = new int[] { 3, 2 };
    StringBuilder stringBuilder = new StringBuilder();
    for (int i = 0; i &amp;lt; numbers.length; ++i) {
        switch (numbers[i]) {
            case 1:
                leftHandPosition[0] = 0;
                leftHandPosition[1] = 0;
                stringBuilder.append('L');
                break;
            case 4:
                leftHandPosition[0] = 1;
                leftHandPosition[1] = 0;
                stringBuilder.append('L');
                break;
            case 7:
                leftHandPosition[0] = 2;
                leftHandPosition[1] = 0;
                stringBuilder.append('L');
                break;
            case 3:
                rightHandPosition[0] = 0;
                rightHandPosition[1] = 2;
                stringBuilder.append('R');
                break;
            case 6:
                rightHandPosition[0] = 1;
                rightHandPosition[1] = 2;
                stringBuilder.append('R');
                break;
            case 9:
                rightHandPosition[0] = 2;
                rightHandPosition[1] = 2;
                stringBuilder.append('R');
                break;
            default: {
                int y = 0;
                switch (numbers[i]) {
                    case 5:
                        y = 1;
                        break;
                    case 8:
                        y = 2;
                        break;
                    case 0:
                        y = 3;
                        break;
                }
                int farFromLeft = (1 - leftHandPosition[1]) + Math.abs(y - leftHandPosition[0]);
                int farFromRight = (rightHandPosition[1] - 1) + Math.abs(y - rightHandPosition[0]);
                if (farFromLeft &amp;lt; farFromRight) {
                    leftHandPosition[0] = y;
                    leftHandPosition[1] = 1;
                    stringBuilder.append('L');
                } else if (farFromRight &amp;lt; farFromLeft) {
                    rightHandPosition[0] = y;
                    rightHandPosition[1] = 1;
                    stringBuilder.append('R');
                } else if (hand.equals(&quot;right&quot;)) {
                    rightHandPosition[0] = y;
                    rightHandPosition[1] = 1;
                    stringBuilder.append('R');
                } else {
                    leftHandPosition[0] = y;
                    leftHandPosition[1] = 1;
                    stringBuilder.append('L');
                }
                break;
            }
        }
    }
    return stringBuilder.toString();
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level1</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/255</guid>
      <comments>https://ydeer.tistory.com/255#entry255comment</comments>
      <pubDate>Tue, 13 Apr 2021 15:41:04 +0900</pubDate>
    </item>
    <item>
      <title>[Lv1] 다트 게임</title>
      <link>https://ydeer.tistory.com/254</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17682&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/17682&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618294141394&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - [1차] 다트 게임&quot; data-og-description=&quot;&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17682&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17682&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/beWfwp/hyJSkMAKN1/kIBFBMyNrRuKCBkKb4Wd00/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bYaryi/hyJQEMI4vi/fVKlpvkwmJbvXBBo5O2250/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/L3M1G/hyJSaQJGvv/42MMXCCJPYgKXkYTfhFLKK/img.png?width=300&amp;amp;height=400&amp;amp;face=116_216_207_315&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17682&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17682&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/beWfwp/hyJSkMAKN1/kIBFBMyNrRuKCBkKb4Wd00/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bYaryi/hyJQEMI4vi/fVKlpvkwmJbvXBBo5O2250/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/L3M1G/hyJSaQJGvv/42MMXCCJPYgKXkYTfhFLKK/img.png?width=300&amp;amp;height=400&amp;amp;face=116_216_207_315');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - [1차] 다트 게임&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;h2&gt;다트 게임&lt;/h2&gt;
&lt;p&gt;카카오톡 게임별의 하반기 신규 서비스로 다트 게임을 출시하기로 했다.&lt;/p&gt;
&lt;p&gt;다트 게임은 다트판에 다트를 세 차례 던져 그 점수의 합계로 실력을 겨루는 게임으로, 모두가 간단히 즐길 수 있다.&lt;/p&gt;
&lt;p&gt;갓 입사한 무지는 코딩 실력을 인정받아 게임의 핵심 부분인 점수 계산 로직을 맡게 되었다.&lt;/p&gt;
&lt;p&gt;다트 게임의 점수 계산 로직은 아래와 같다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;다트 게임은 총 3번의 기회로 구성된다.&lt;/li&gt;
&lt;li&gt;각 기회마다 얻을 수 있는 점수는 0점에서 10점까지이다.&lt;/li&gt;
&lt;li&gt;점수와 함께 Single(S), Double(D), Triple(T) 영역이 존재하고 각 영역 당첨 시점수에서 1제곱, 2제곱, 3제곱 (점수1&lt;span&gt;&amp;nbsp;&lt;/span&gt;, 점수2&lt;span&gt;&amp;nbsp;&lt;/span&gt;, 점수3&lt;span&gt;&amp;nbsp;&lt;/span&gt;)으로 계산된다.&lt;/li&gt;
&lt;li&gt;옵션으로 스타상(*) , 아차상(#)이 존재하며 스타상(*) 당첨 시 해당 점수와 바로 전에 얻은 점수를 각 2배로 만든다. 아차상(#) 당첨 시 해당 점수는 마이너스된다.&lt;/li&gt;
&lt;li&gt;스타상(*)은 첫 번째 기회에서도 나올 수 있다. 이 경우 첫 번째 스타상(*)의 점수만 2배가 된다. (예제 4번 참고)&lt;/li&gt;
&lt;li&gt;스타상(*)의 효과는 다른 스타상(*)의 효과와 중첩될 수 있다. 이 경우 중첩된 스타상(*) 점수는 4배가 된다. (예제 4번 참고)&lt;/li&gt;
&lt;li&gt;스타상(*)의 효과는 아차상(#)의 효과와 중첩될 수 있다. 이 경우 중첩된 아차상(#)의 점수는 -2배가 된다. (예제 5번 참고)&lt;/li&gt;
&lt;li&gt;Single(S), Double(D), Triple(T)은 점수마다 하나씩 존재한다.&lt;/li&gt;
&lt;li&gt;스타상(*), 아차상(#)은 점수마다 둘 중 하나만 존재할 수 있으며, 존재하지 않을 수도 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;0~10의 정수와 문자 S, D, T, *, #로 구성된 문자열이 입력될 시 총점수를 반환하는 함수를 작성하라.&lt;/p&gt;
&lt;h3&gt;입력 형식&lt;/h3&gt;
&lt;p&gt;&quot;점수|보너스|[옵션]&quot;으로 이루어진 문자열 3세트.&lt;/p&gt;
&lt;p&gt;예)&lt;span&gt;&amp;nbsp;&lt;/span&gt;1S2D*3T&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;점수는 0에서 10 사이의 정수이다.&lt;/li&gt;
&lt;li&gt;보너스는 S, D, T 중 하나이다.&lt;/li&gt;
&lt;li&gt;옵선은 *이나 # 중 하나이며, 없을 수도 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;출력 형식&lt;/h3&gt;
&lt;p&gt;3번의 기회에서 얻은 점수 합계에 해당하는 정수값을 출력한다.&lt;/p&gt;
&lt;p&gt;예) 37&lt;/p&gt;
&lt;h3&gt;입출력 예제&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; border-right: 1px solid white;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;text-align: center; border-right: 1px solid white;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;dartResult&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;text-align: center; border-right: 1px solid white;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;answer&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1S2D*3T&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;37&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;11&lt;span&gt;&amp;nbsp;&lt;/span&gt;* 2 + 22&lt;span&gt;&amp;nbsp;&lt;/span&gt;* 2 + 33&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1D2S#10S&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;9&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;12&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ 21&lt;span&gt;&amp;nbsp;&lt;/span&gt;* (-1) + 101&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1D2S0T&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;12&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ 21&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ 03&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1S*2T*3S&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;23&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;11&lt;span&gt;&amp;nbsp;&lt;/span&gt;* 2 * 2 + 23&lt;span&gt;&amp;nbsp;&lt;/span&gt;* 2 + 31&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1D#2S*3S&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;12&lt;span&gt;&amp;nbsp;&lt;/span&gt;* (-1) * 2 + 21&lt;span&gt;&amp;nbsp;&lt;/span&gt;* 2 + 31&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;6&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1T2D3D#&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;-4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;13&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ 22&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ 32&lt;span&gt;&amp;nbsp;&lt;/span&gt;* (-1)&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;7&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1D2S3T*&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;59&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;12&lt;span&gt;&amp;nbsp;&lt;/span&gt;+ 21&lt;span&gt;&amp;nbsp;&lt;/span&gt;* 2 + 33&lt;span&gt;&amp;nbsp;&lt;/span&gt;* 2&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618294209740&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Solution {
    public int solution(String dartResult) {
        String regex = &quot;(10)|(\\d)&quot;;
        Matcher m = Pattern.compile(regex).matcher(dartResult);
        int[] scores = new int[3];
        int[] bonuses = new int[3];
        int[] options = new int[3];
        for (int i = 0; i &amp;lt; 3; ++i) {
            m.find();
            scores[i] = Integer.parseInt(m.group());
            switch (dartResult.charAt(m.end())) {
                case 'S':
                    bonuses[i] = 1;
                    break;
                case 'D':
                    bonuses[i] = 2;
                    break;
                case 'T':
                    bonuses[i] = 3;
                    break;
            }
            int optionIndex = m.end() + 1;
            if (optionIndex &amp;lt; dartResult.length()) {
                switch (dartResult.charAt(optionIndex)) {
                    case '*':
                        options[i] = 1;
                        break;
                    case '#':
                        options[i] = -1;
                        break;
                    default:
                        break;
                }
            }
        }
        int answer = 0;
        for (int i = 2; i &amp;gt;= 0; --i) {
            scores[i] = (int) Math.pow(scores[i], bonuses[i]);
        }
        for (int i = 2; i &amp;gt;= 0; --i) {
            if (options[i] == 1) {
                scores[i] *= 2;
                if (i &amp;gt; 0) {
                    scores[i - 1] *= 2;
                }
            } else if (options[i] == -1) {
                scores[i] *= -1;
            }
            answer += scores[i];
        }
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level1</category>
      <category>programmers</category>
      <category>regex</category>
      <category>정규표현식</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/254</guid>
      <comments>https://ydeer.tistory.com/254#entry254comment</comments>
      <pubDate>Tue, 13 Apr 2021 15:11:09 +0900</pubDate>
    </item>
    <item>
      <title>[Lv1] 비밀지도</title>
      <link>https://ydeer.tistory.com/253</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17681&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/17681&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618292308589&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - [1차] 비밀지도&quot; data-og-description=&quot;비밀지도 네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17681&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17681&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ioeRm/hyJSlETcDP/2Ftqus5f2xMMII1WsmNba0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/BW7wf/hyJSey0vfb/k4kkUPZaLXaJlnAQpldpVk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cdaMYI/hyJSi9euhM/Vy0brFsIbp1uDFZN7i1PWK/img.png?width=449&amp;amp;height=707&amp;amp;face=0_0_449_707&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/17681&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/17681&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ioeRm/hyJSlETcDP/2Ftqus5f2xMMII1WsmNba0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/BW7wf/hyJSey0vfb/k4kkUPZaLXaJlnAQpldpVk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cdaMYI/hyJSi9euhM/Vy0brFsIbp1uDFZN7i1PWK/img.png?width=449&amp;amp;height=707&amp;amp;face=0_0_449_707');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - [1차] 비밀지도&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;비밀지도 네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;h2&gt;비밀지도&lt;/h2&gt;
&lt;p&gt;네오는 평소 프로도가 비상금을 숨겨놓는 장소를 알려줄 비밀지도를 손에 넣었다. 그런데 이 비밀지도는 숫자로 암호화되어 있어 위치를 확인하기 위해서는 암호를 해독해야 한다. 다행히 지도 암호를 해독할 방법을 적어놓은 메모도 함께 발견했다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;지도는 한 변의 길이가&lt;span&gt;&amp;nbsp;&lt;/span&gt;n인 정사각형 배열 형태로, 각 칸은 &quot;공백&quot;(&quot; &quot;) 또는 &quot;벽&quot;(&quot;#&quot;) 두 종류로 이루어져 있다.&lt;/li&gt;
&lt;li&gt;전체 지도는 두 장의 지도를 겹쳐서 얻을 수 있다. 각각 &quot;지도 1&quot;과 &quot;지도 2&quot;라고 하자. 지도 1 또는 지도 2 중 어느 하나라도 벽인 부분은 전체 지도에서도 벽이다. 지도 1과 지도 2에서 모두 공백인 부분은 전체 지도에서도 공백이다.&lt;/li&gt;
&lt;li&gt;&quot;지도 1&quot;과 &quot;지도 2&quot;는 각각 정수 배열로 암호화되어 있다.&lt;/li&gt;
&lt;li&gt;암호화된 배열은 지도의 각 가로줄에서 벽 부분을&lt;span&gt;&amp;nbsp;&lt;/span&gt;1, 공백 부분을&lt;span&gt;&amp;nbsp;&lt;/span&gt;0으로 부호화했을 때 얻어지는 이진수에 해당하는 값의 배열이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3Wb2V/btq2yaMUwNf/54ZBODVUpeyJLWxxmQzFsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3Wb2V/btq2yaMUwNf/54ZBODVUpeyJLWxxmQzFsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3Wb2V/btq2yaMUwNf/54ZBODVUpeyJLWxxmQzFsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3Wb2V%2Fbtq2yaMUwNf%2F54ZBODVUpeyJLWxxmQzFsK%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;네오가 프로도의 비상금을 손에 넣을 수 있도록, 비밀지도의 암호를 해독하는 작업을 도와줄 프로그램을 작성하라.&lt;/p&gt;
&lt;h3&gt;입력 형식&lt;/h3&gt;
&lt;p&gt;입력으로 지도의 한 변 크기&lt;span&gt;&amp;nbsp;&lt;/span&gt;n&lt;span&gt;&amp;nbsp;&lt;/span&gt;과 2개의 정수 배열&lt;span&gt;&amp;nbsp;&lt;/span&gt;arr1,&lt;span&gt;&amp;nbsp;&lt;/span&gt;arr2가 들어온다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 ≦&lt;span&gt;&amp;nbsp;&lt;/span&gt;n&lt;span&gt;&amp;nbsp;&lt;/span&gt;≦ 16&lt;/li&gt;
&lt;li&gt;arr1,&lt;span&gt;&amp;nbsp;&lt;/span&gt;arr2는 길이&lt;span&gt;&amp;nbsp;&lt;/span&gt;n인 정수 배열로 주어진다.&lt;/li&gt;
&lt;li&gt;정수 배열의 각 원소&lt;span&gt;&amp;nbsp;&lt;/span&gt;x를 이진수로 변환했을 때의 길이는&lt;span&gt;&amp;nbsp;&lt;/span&gt;n&lt;span&gt;&amp;nbsp;&lt;/span&gt;이하이다. 즉, 0 ≦&lt;span&gt;&amp;nbsp;&lt;/span&gt;x&lt;span&gt;&amp;nbsp;&lt;/span&gt;≦ 2n&lt;span&gt;&amp;nbsp;&lt;/span&gt;- 1을 만족한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;출력 형식&lt;/h3&gt;
&lt;p&gt;원래의 비밀지도를 해독하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;'#',&lt;span&gt;&amp;nbsp;&lt;/span&gt;공백으로 구성된 문자열 배열로 출력하라.&lt;/p&gt;
&lt;h3&gt;입출력 예제&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; border-right: 1px white solid;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;매개변수&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;값&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;arr1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[9, 20, 28, 18, 11]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;arr2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[30, 1, 21, 17, 28]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;출력&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;#####&quot;,&quot;# # #&quot;, &quot;### #&quot;, &quot;# ##&quot;, &quot;#####&quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: center; border-right: 1px white solid;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;매개변수&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;text-align: center;&quot;&gt;
&lt;p&gt;&lt;span style=&quot;color: #ffffff;&quot;&gt;&lt;b&gt;값&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;6&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;arr1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[46, 33, 33 ,22, 31, 50]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;arr2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[27 ,56, 19, 14, 14, 10]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;출력&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[&quot;######&quot;, &quot;### #&quot;, &quot;## ##&quot;, &quot; #### &quot;, &quot; #####&quot;, &quot;### # &quot;]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618292388994&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public static char[] intToBits(int number, int size) {
        StringBuilder stringBuilder = new StringBuilder();
        while (number &amp;gt; 1) {
            if (number % 2 == 0) {
                stringBuilder.append('0');
            } else {
                stringBuilder.append('1');
            }
            number /= 2;
            --size;
        }
        if (number == 1) {
            stringBuilder.append('1');
            --size;
        }
        for (int i = 0; i &amp;lt; size; ++i) {
            stringBuilder.append('0');
        }
        return stringBuilder.reverse().toString().toCharArray();
    }
    
    public String twoCharsToString(char[] arr1, char[] arr2) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i &amp;lt; arr1.length; ++i) {
            if (arr1[i] == '1') {
                stringBuilder.append('#');
            } else if (arr2[i] == '1') {
                stringBuilder.append('#');
            } else {
                stringBuilder.append(' ');
            }
        }
        return stringBuilder.toString();
    }
    
    public String[] solution(int n, int[] arr1, int[] arr2) {
        String[] answer = new String[n];
        for (int i = 0; i &amp;lt; n; ++i) {
            answer[i] = twoCharsToString(intToBits(arr1[i], n), intToBits(arr2[i], n));
        }
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level1</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/253</guid>
      <comments>https://ydeer.tistory.com/253#entry253comment</comments>
      <pubDate>Tue, 13 Apr 2021 14:40:23 +0900</pubDate>
    </item>
    <item>
      <title>[Lv1] 크레인 인형뽑기 게임</title>
      <link>https://ydeer.tistory.com/252</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/64061&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/64061&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618290124961&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 크레인 인형뽑기 게임&quot; data-og-description=&quot;[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/64061&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/64061&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b4pwFF/hyJSldNRMj/gruoGCjIM9P1p4MXafSHlK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cor904/hyJSgXRT3S/Sn6iGiF3V9EIt4GLQkWp31/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cI4xTz/hyJSj77p2n/I7ZGK7RSO7IC6Nv031SDI1/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/64061&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/64061&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b4pwFF/hyJSldNRMj/gruoGCjIM9P1p4MXafSHlK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cor904/hyJSgXRT3S/Sn6iGiF3V9EIt4GLQkWp31/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cI4xTz/hyJSj77p2n/I7ZGK7RSO7IC6Nv031SDI1/img.png?width=500&amp;amp;height=500&amp;amp;face=0_0_500_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 크레인 인형뽑기 게임&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]] [1,5,3,5,1,2,1,4] 4&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;게임개발자인 &quot;죠르디&quot;는 크레인 인형뽑기 기계를 모바일 게임으로 만들려고 합니다.&lt;/p&gt;
&lt;p&gt;&quot;죠르디&quot;는 게임의 재미를 높이기 위해 화면 구성과 규칙을 다음과 같이 게임 로직에 반영하려고 합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yklIb/btq2uWBu30O/LolB8R6BVOo0VHw9TkUaH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yklIb/btq2uWBu30O/LolB8R6BVOo0VHw9TkUaH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yklIb/btq2uWBu30O/LolB8R6BVOo0VHw9TkUaH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyklIb%2Fbtq2uWBu30O%2FLolB8R6BVOo0VHw9TkUaH1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;게임 화면은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&quot;1 x 1&quot;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;크기의 칸들로 이루어진&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&quot;N x N&quot;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;크기의 정사각 격자이며 위쪽에는 크레인이 있고&lt;/p&gt;
&lt;p&gt;오른쪽에는 바구니가 있습니다. (위 그림은 &quot;5 x 5&quot; 크기의 예시입니다).&lt;/p&gt;
&lt;p&gt;각 격자 칸에는 다양한 인형이 들어 있으며 인형이 없는 칸은 빈칸입니다.&lt;/p&gt;
&lt;p&gt;모든 인형은 &quot;1 x 1&quot; 크기의 격자 한 칸을 차지하며&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;격자의 가장 아래 칸부터 차곡차곡 쌓여 있습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;게임 사용자는 크레인을 좌우로 움직여서 멈춘 위치에서 가장 위에 있는 인형을 집어 올릴 수 있습니다.&lt;/p&gt;
&lt;p&gt;집어 올린 인형은 바구니에 쌓이게 되는 데, 이때 바구니의 가장 아래 칸부터 인형이 순서대로 쌓이게 됩니다.&lt;/p&gt;
&lt;p&gt;다음 그림은 [1번, 5번, 3번] 위치에서 순서대로 인형을 집어 올려 바구니에 담은 모습입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cho9yy/btq2lpS2WTU/lNtcBM0S7xPsKu8R4au750/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cho9yy/btq2lpS2WTU/lNtcBM0S7xPsKu8R4au750/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cho9yy/btq2lpS2WTU/lNtcBM0S7xPsKu8R4au750/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcho9yy%2Fbtq2lpS2WTU%2FlNtcBM0S7xPsKu8R4au750%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;만약 같은 모양의 인형 두 개가 바구니에 연속해서 쌓이게 되면 두 인형은 터뜨려지면서 바구니에서 사라지게 됩니다.&lt;/p&gt;
&lt;p&gt;위 상태에서 이어서 [5번] 위치에서 인형을 집어 바구니에 쌓으면 같은 모양 인형&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;두 개&lt;/b&gt;가 없어집니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B2pFe/btq2u2aIJfO/LNnOVT3cxFdSW3aRAj47jk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B2pFe/btq2u2aIJfO/LNnOVT3cxFdSW3aRAj47jk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B2pFe/btq2u2aIJfO/LNnOVT3cxFdSW3aRAj47jk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/B2pFe/btq2u2aIJfO/LNnOVT3cxFdSW3aRAj47jk/img.gif&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;크레인 작동 시 인형이 집어지지 않는 경우는 없으나 만약 인형이 없는 곳에서 크레인을 작동시키는 경우에는&lt;/p&gt;
&lt;p&gt;아무런 일도 일어나지 않습니다. 또한 바구니는 모든 인형이 들어갈 수 있을 만큼 충분히 크다고 가정합니다.&lt;/p&gt;
&lt;p&gt;(그림에서는 화면표시 제약으로 5칸만으로 표현하였음)&lt;/p&gt;
&lt;p&gt;게임 화면의 격자의 상태가 담긴 2차원 배열 board와&lt;/p&gt;
&lt;p&gt;인형을 집기 위해 크레인을 작동시킨 위치가 담긴 배열 moves가 매개변수로 주어질 때,&lt;/p&gt;
&lt;p&gt;크레인을 모두 작동시킨 후 터트려져 사라진 인형의 개수를 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;[제한사항]&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;board 배열은 2차원 배열로 크기는 &quot;5 x 5&quot; 이상 &quot;30 x 30&quot; 이하입니다.&lt;/li&gt;
&lt;li&gt;board의 각 칸에는 0 이상 100 이하인 정수가 담겨있습니다.
&lt;ul&gt;
&lt;li&gt;0은 빈 칸을 나타냅니다.&lt;/li&gt;
&lt;li&gt;1 ~ 100의 각 숫자는 각기 다른 인형의 모양을 의미하며 같은 숫자는 같은 모양의 인형을 나타냅니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;moves 배열의 크기는 1 이상 1,000 이하입니다.&lt;/li&gt;
&lt;li&gt;moves 배열 각 원소들의 값은 1 이상이며 board 배열의 가로 크기 이하인 자연수입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;board&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;moves&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;[[0,0,0,0,0],[0,0,1,0,3],[0,2,5,0,1],[4,2,4,4,2],[3,5,1,3,1]]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[1,5,3,5,1,2,1,4]&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예에 대한 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;인형의 처음 상태는 문제에 주어진 예시와 같습니다.&lt;/p&gt;
&lt;p&gt;크레인이 [1, 5, 3, 5, 1, 2, 1, 4] 번 위치에서 차례대로 인형을 집어서 바구니에 옮겨 담은 후,&lt;/p&gt;
&lt;p&gt;상태는 아래 그림과 같으며 바구니에 담는 과정에서 터트려져 사라진 인형은 4개 입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SRa0k/btq2plo2SJn/mjqcppH8Nikp44e7QvSF31/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SRa0k/btq2plo2SJn/mjqcppH8Nikp44e7QvSF31/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SRa0k/btq2plo2SJn/mjqcppH8Nikp44e7QvSF31/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSRa0k%2Fbtq2plo2SJn%2FmjqcppH8Nikp44e7QvSF31%2Fimg.jpg&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618290214059&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Stack;

class Solution {
    public int solution(int[][] board, int[] moves) {
        int answer = 0;
        Stack&amp;lt;Integer&amp;gt; stack = new Stack&amp;lt;&amp;gt;();
        for (int i = 0 ; i &amp;lt; moves.length; ++i) {
            for (int j = 0; j &amp;lt; board.length; ++j) {
                if (board[j][moves[i] - 1] != 0) {
                    int target = board[j][moves[i] - 1];
                    board[j][moves[i] - 1] = 0;
                    if (stack.isEmpty() == false) {
                        int prev = stack.peek();
                        if (prev == target) {
                            stack.pop();
                            answer += 2;
                            break;
                        }
                    }
                    stack.push(target);
                    break;
                }
            }
        }
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level1</category>
      <category>programmers</category>
      <category>stack</category>
      <category>스택</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/252</guid>
      <comments>https://ydeer.tistory.com/252#entry252comment</comments>
      <pubDate>Tue, 13 Apr 2021 14:04:19 +0900</pubDate>
    </item>
    <item>
      <title>[Lv2] 이진 변환 반복하기</title>
      <link>https://ydeer.tistory.com/251</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/70129&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/70129&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618225407727&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 이진 변환 반복하기&quot; data-og-description=&quot;&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/70129&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/70129&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cFWpMt/hyJQOg3GHx/R6c5BltOc9AZVpVimX9Uuk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bMJfml/hyJQPmJc22/SyT6ImActkVAmtAmTLNs30/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/70129&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/70129&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cFWpMt/hyJQOg3GHx/R6c5BltOc9AZVpVimX9Uuk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bMJfml/hyJQPmJc22/SyT6ImActkVAmtAmTLNs30/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 이진 변환 반복하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;0과 1로 이루어진 어떤 문자열 x에 대한 이진 변환을 다음과 같이 정의합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;x의 모든 0을 제거합니다.&lt;/li&gt;
&lt;li&gt;x의 길이를 c라고 하면, x를 &quot;c를 2진법으로 표현한 문자열&quot;로 바꿉니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;예를 들어,&lt;span&gt;&amp;nbsp;&lt;/span&gt;x = &quot;0111010&quot;이라면, x에 이진 변환을 가하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;x = &quot;0111010&quot; -&amp;gt; &quot;1111&quot; -&amp;gt; &quot;100&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;이 됩니다.&lt;/p&gt;
&lt;p&gt;0과 1로 이루어진 문자열 s가 매개변수로 주어집니다. s가 &quot;1&quot;이 될 때까지 계속해서 s에 이진 변환을 가했을 때, 이진 변환의 횟수와 변환 과정에서 제거된 모든 0의 개수를 각각 배열에 담아 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;제한사항&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;s의 길이는 1 이상 150,000 이하입니다.&lt;/li&gt;
&lt;li&gt;s에는 '1'이 최소 하나 이상 포함되어 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;s&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;110010101001&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[3,8]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;01110&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[3,3]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;1111111&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[4,1]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;입출력 예 #1&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;110010101001&quot;이 &quot;1&quot;이 될 때까지 이진 변환을 가하는 과정은 다음과 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 80px;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;회차&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;이진 변환 이전&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;제거할 0의 개수&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;0 제거 후 길이&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;이진 변환 결과&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;&quot;110010101001&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;6&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;6&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;&quot;110&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;&quot;110&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;&quot;10&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;&quot;10&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;&quot;1&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;3번의 이진 변환을 하는 동안 8개의 0을 제거했으므로,&lt;span&gt;&amp;nbsp;&lt;/span&gt;[3,8]을 return 해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;입출력 예 #2&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;01110&quot;이 &quot;1&quot;이 될 때까지 이진 변환을 가하는 과정은 다음과 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;회차&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;이진 변환 이전&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;제거할 0의 개수&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;0 제거 후 길이&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;이진 변환 결과&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;01110&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;11&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;11&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;10&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;10&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;1&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;3번의 이진 변환을 하는 동안 3개의 0을 제거했으므로,&lt;span&gt;&amp;nbsp;&lt;/span&gt;[3,3]을 return 해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;입출력 예 #3&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;1111111&quot;이 &quot;1&quot;이 될 때까지 이진 변환을 가하는 과정은 다음과 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;회차&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;이진 변환 이전&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;제거할 0의 개수&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;0 제거 후 길이&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;height: 20px;&quot;&gt;
&lt;p&gt;이진 변환 결과&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;1111111&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;7&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;111&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;111&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;11&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;11&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;0&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;10&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;10&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;1&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;4번의 이진 변환을 하는 동안 1개의 0을 제거했으므로,&lt;span&gt;&amp;nbsp;&lt;/span&gt;[4,1]을 return 해야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618225563302&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int[] solution(String s) {
    int[] answer = new int[2];
    while (true) {
        if (s.equals(&quot;1&quot;)) {
            break;
        }
        ++answer[0];
        char[] chars = s.toCharArray();
        int countOne = 0;
        for (int i = 0; i &amp;lt; chars.length; ++i) {
            if (chars[i] == '1') {
                ++countOne;
            }
        }
        answer[1] += (s.length() - countOne);
        StringBuilder stringBuilder = new StringBuilder();
        while (countOne &amp;gt; 1) {
            if (countOne % 2 == 0) {
                stringBuilder.append('0');
            } else {
                stringBuilder.append('1');
            }
            countOne /= 2;
        }
        if (countOne == 1) {
            stringBuilder.append('1');
        }
        s = stringBuilder.reverse().toString();
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>LEVEL2</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/251</guid>
      <comments>https://ydeer.tistory.com/251#entry251comment</comments>
      <pubDate>Mon, 12 Apr 2021 20:06:31 +0900</pubDate>
    </item>
    <item>
      <title>[Lv2] 멀쩡한 사각형</title>
      <link>https://ydeer.tistory.com/250</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/62048&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/62048&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618225166266&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 멀쩡한 사각형&quot; data-og-description=&quot;가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를 격자 선을 &quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/62048&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/62048&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zh8b1/hyJSb9GL4v/jhA3KA8VQimf3c94qg5Wi1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/9sAbD/hyJSaQsoPr/mozKq2KledQmsN7Pil4gGk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/UaZpj/hyJQEll4uY/BLDbMMqKVCriFXR2aNxeM1/img.png?width=412&amp;amp;height=570&amp;amp;face=0_0_412_570&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/62048&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/62048&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zh8b1/hyJSb9GL4v/jhA3KA8VQimf3c94qg5Wi1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/9sAbD/hyJSaQsoPr/mozKq2KledQmsN7Pil4gGk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/UaZpj/hyJQEll4uY/BLDbMMqKVCriFXR2aNxeM1/img.png?width=412&amp;amp;height=570&amp;amp;face=0_0_412_570');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 멀쩡한 사각형&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다. 종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다. 이 종이를 격자 선을&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;가로 길이가 Wcm, 세로 길이가 Hcm인 직사각형 종이가 있습니다.&lt;/p&gt;
&lt;p&gt;종이에는 가로, 세로 방향과 평행하게 격자 형태로 선이 그어져 있으며, 모든 격자칸은 1cm x 1cm 크기입니다.&lt;/p&gt;
&lt;p&gt;이 종이를 격자 선을 따라 1cm &amp;times; 1cm의 정사각형으로 잘라 사용할 예정이었는데,&lt;/p&gt;
&lt;p&gt;누군가가 이 종이를 대각선 꼭지점 2개를 잇는 방향으로 잘라 놓았습니다.&lt;/p&gt;
&lt;p&gt;그러므로 현재 직사각형 종이는 크기가 같은 직각삼각형 2개로 나누어진 상태입니다.&lt;/p&gt;
&lt;p&gt;새로운 종이를 구할 수 없는 상태이기 때문에,&lt;/p&gt;
&lt;p&gt;이 종이에서 원래 종이의 가로, 세로 방향과 평행하게 1cm &amp;times; 1cm로 잘라 사용할 수 있는 만큼만 사용하기로 하였습니다.&lt;/p&gt;
&lt;p&gt;가로의 길이 W와 세로의 길이 H가 주어질 때, 사용할 수 있는 정사각형의 개수를 구하는 solution 함수를 완성해 주세요.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;제한사항&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;W, H : 1억 이하의 자연수&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;W&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;H&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;8&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;12&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;80&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;입출력 예 #1&lt;/p&gt;
&lt;p&gt;가로가 8, 세로가 12인 직사각형을 대각선 방향으로 자르면 총 16개 정사각형을 사용할 수 없게 됩니다.&lt;/p&gt;
&lt;p&gt;원래 직사각형에서는 96개의 정사각형을 만들 수 있었으므로, 96 - 16 = 80 을 반환합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLLQcI/btq2s0Yonxe/9xymkdMt3dMjThXFpGNKlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLLQcI/btq2s0Yonxe/9xymkdMt3dMjThXFpGNKlk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLLQcI/btq2s0Yonxe/9xymkdMt3dMjThXFpGNKlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLLQcI%2Fbtq2s0Yonxe%2F9xymkdMt3dMjThXFpGNKlk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618225288190&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static long solution(int w, int h) {
    int high = Math.max(w, h);
    int low = Math.min(w, h);
    int size_high = 1;
    int size_low = 1;    // 정사각형이면 1:1 비율
    if (high &amp;gt; low) {
        // 정사각형이면 최대공약수는 같은 수인 그 자신, 아니면 구하기
        PriorityQueue&amp;lt;Integer&amp;gt; priorityQueue = new PriorityQueue&amp;lt;&amp;gt;(Collections.reverseOrder());
        for (int i = low; i &amp;gt;= 1; --i) {
            if (low % i == 0) {
                priorityQueue.add(i);
            }
        }
        int commonDivisor = low;
        for (Integer divisor : priorityQueue) {
            if (high % divisor == 0) {
                commonDivisor = divisor;
                break;
            }
        }
        // 직사각형의 축소판의 길이를 구함.
        // 편의상 low를 가로로, high를 세로로 보고, 항상 위로 길쭉한 직사각형을 떠올리기로 함.
        size_high = high / commonDivisor;
        size_low = low / commonDivisor;
    }
    float slope = ((float) size_high) / size_low;    // y = ax + c의 1차 함수 모델에서, y절편(c)이 0인 모델을 떠올려 봄.
    long trash = 0;
    int prevY = 0;
    // size_low는 반드시 size_high보다 작으며(위로 긴 모델),
    // x가 size_low에 도달하면, y역시 size_high에 도달하며, 이는 반드시 정수임.
    // x가 0~1인 구간부터 보기로 하며,
    // 마지막 size_low는 반복문 아래에서 따로 계산한다. (1:1 정사각형 모델도 그냥 반복문 건너뛰고 계산되도록)
    for (int x = 1; x &amp;lt; size_low; ++x) {
        int y = (int) (slope * x);    // y의 소수점 자리를 버린다.
        // 소수점을 버리기 전의 y는 반복문 안에서 반드시 정수가 되지 못한다.
        // 최대공약수 특성상, y가 최초로 정수가 되는 곳은 x의 끝인 size_low이다.
        // (이 구간의 y는 항상 *.*가 된다.)
        // 즉, 이 구간은 y와 prevY의 차이에서 1씩 더하여도 반드시 성립한다.
        // 0.~라서 아직 한 칸을 못 넘었어도 왼쪽과 같은 진척도라 1칸을 차지하고,
        // 1.~라서 한 칸을 넘었어도, 넘은 칸과 이번 소수점 자리 1칸을 차지한다.
        trash += (y - prevY + 1);
        prevY = y;
    }
    // 처음으로 x와 y가 모두 함께 정수가 되는 종료구간.
    // prevY는 이전에서 소수점 자리를 버린채 낮아진 상태이기 때문에,
    // size_high와의 차이는 반드시 넘은 칸과 소수점 자리 모두 포함한다.
    trash += (size_high - prevY);
    // 위는 size_low와 size_high의 축소형 모델이었고,
    // 실제 직사각형은 최대공약수를 곱한만큼이므로, 곱하면 버리는 픽셀 수를 알 수 있다.
    trash *= (low / size_low);
    // 최종적으로 구하고자 하는 값은 모든 픽셀 중 버리는 픽셀 수.
    return ((long) w) * h - trash;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>LEVEL2</category>
      <category>programmers</category>
      <category>기하학</category>
      <category>도형</category>
      <category>수학</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/250</guid>
      <comments>https://ydeer.tistory.com/250#entry250comment</comments>
      <pubDate>Mon, 12 Apr 2021 20:01:34 +0900</pubDate>
    </item>
    <item>
      <title>[Lv2] 삼각 달팽이</title>
      <link>https://ydeer.tistory.com/249</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/68645&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/68645&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618224937253&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 삼각 달팽이&quot; data-og-description=&quot;5 [1,2,12,3,13,11,4,14,15,10,5,6,7,8,9] 6 [1,2,15,3,16,14,4,17,21,13,5,18,19,20,12,6,7,8,9,10,11]&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/68645&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/68645&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eIOLr/hyJSeSSrAX/qLXCklye2IJkLkAaKxfdPk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/NKPKY/hyJQJNI8qG/e7JKHkjtzQHKDJvpI44uyk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/qPHw7/hyJQC8T5L1/QQuAD2zJJr10ff8PozcTB1/img.png?width=1189&amp;amp;height=525&amp;amp;face=0_0_1189_525&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/68645&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/68645&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eIOLr/hyJSeSSrAX/qLXCklye2IJkLkAaKxfdPk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/NKPKY/hyJQJNI8qG/e7JKHkjtzQHKDJvpI44uyk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/qPHw7/hyJQC8T5L1/QQuAD2zJJr10ff8PozcTB1/img.png?width=1189&amp;amp;height=525&amp;amp;face=0_0_1189_525');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 삼각 달팽이&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;5 [1,2,12,3,13,11,4,14,15,10,5,6,7,8,9] 6 [1,2,15,3,16,14,4,17,21,13,5,18,19,20,12,6,7,8,9,10,11]&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;정수 n이 매개변수로 주어집니다.&lt;/p&gt;
&lt;p&gt;다음 그림과 같이 밑변의 길이와 높이가 n인 삼각형에서 맨 위 꼭짓점부터 반시계 방향으로 달팽이 채우기를 진행한 후,&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;첫 행부터 마지막 행까지 모두 순서대로 합친 새로운 배열을 return 하도록 solution 함수를 완성해주세요.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKU2ib/btq2sZ6cj65/TwkUCVhDPo4ibutnuFDZv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKU2ib/btq2sZ6cj65/TwkUCVhDPo4ibutnuFDZv0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKU2ib/btq2sZ6cj65/TwkUCVhDPo4ibutnuFDZv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKU2ib%2Fbtq2sZ6cj65%2FTwkUCVhDPo4ibutnuFDZv0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&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;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;제한사항&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;n은 1 이상 1,000 이하입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;n&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[1,2,9,3,10,8,4,5,6,7]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[1,2,12,3,13,11,4,14,15,10,5,6,7,8,9]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;6&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;[1,2,15,3,16,14,4,17,21,13,5,18,19,20,12,6,7,8,9,10,11]&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;입출력 예 #1&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;문제 예시와 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;입출력 예 #2&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;문제 예시와 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;입출력 예 #3&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;문제 예시와 같습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618225016860&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public int[] solution(int n) {
    int[][] triangle = new int[n][];
    for (int i = 0; i &amp;lt; n; ++i) {
        triangle[i] = new int[i + 1];
        triangle[i][0] = i + 1;
    }
    for (int i = 1; i &amp;lt; n; ++i) {
        triangle[n - 1][i] = n + i;
    }
    int number = n * 2;
    int end = 0;
    for (int i = n; i &amp;gt; 0; --i) {
        end += i;
    }
    int y = n - 1;
    int x = y;
    while (number &amp;lt;= end) {
        while (true) {
            if (triangle[y - 1][x - 1] != 0) {
                break;
            }
            --y;
            --x;
            triangle[y][x] = number++;
        }
        if (number &amp;gt; end) {
            break;
        }
        while (true) {
            if (triangle[y + 1][x] != 0) {
                break;
            }
            ++y;
            triangle[y][x] = number++;
        }
        if (number &amp;gt; end) {
            break;
        }
        while (true) {
            if (triangle[y][x + 1] != 0) {
                break;
            }
            ++x;
            triangle[y][x] = number++;
        }
    }
    int[] answer = new int[end];
    int index = 0;
    for (int i = 0; i &amp;lt; n; ++i) {
        for (int j = 0; j &amp;lt;= i; ++j) {
            answer[index++] = triangle[i][j];
        }
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>LEVEL2</category>
      <category>programmers</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/249</guid>
      <comments>https://ydeer.tistory.com/249#entry249comment</comments>
      <pubDate>Mon, 12 Apr 2021 19:57:07 +0900</pubDate>
    </item>
    <item>
      <title>[Lv2] 괄호 변환</title>
      <link>https://ydeer.tistory.com/248</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/60058&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618224799255&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 괄호 변환&quot; data-og-description=&quot;카카오에 신입 개발자로 입사한 &amp;quot;콘&amp;quot;은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를 &quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/HDAZQ/hyJSptdZCX/yBBCnsCw9Z5kgYP43FYP3K/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/rZfct/hyJSigyCFd/ejR5K5GG59FIRf4b3C4IW0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/60058&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/HDAZQ/hyJSptdZCX/yBBCnsCw9Z5kgYP43FYP3K/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/rZfct/hyJSigyCFd/ejR5K5GG59FIRf4b3C4IW0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 괄호 변환&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;카카오에 신입 개발자로 입사한 &quot;콘&quot;은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;카카오에 신입 개발자로 입사한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&quot;콘&quot;&lt;/b&gt;은 선배 개발자로부터 개발역량 강화를 위해 다른 개발자가 작성한 소스 코드를 분석하여 문제점을 발견하고 수정하라는 업무 과제를 받았습니다. 소스를 컴파일하여 로그를 보니 대부분 소스 코드 내 작성된 괄호가 개수는 맞지만 짝이 맞지 않은 형태로 작성되어 오류가 나는 것을 알게 되었습니다.&lt;/p&gt;
&lt;p&gt;수정해야 할 소스 파일이 너무 많아서 고민하던 &quot;콘&quot;은 소스 코드에 작성된 모든 괄호를 뽑아서 올바른 순서대로 배치된 괄호 문자열을 알려주는 프로그램을 다음과 같이 개발하려고 합니다.&lt;/p&gt;
&lt;h3&gt;용어의 정의&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;'('&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;')'&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;로만 이루어진 문자열이 있을 경우, '(' 의 개수와 ')' 의 개수가 같다면 이를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;균형잡힌 괄호 문자열&lt;/b&gt;이라고 부릅니다.&lt;/p&gt;
&lt;p&gt;그리고 여기에 '('와 ')'의 괄호의 짝도 모두 맞을 경우에는 이를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;올바른 괄호 문자열&lt;/b&gt;이라고 부릅니다.&lt;/p&gt;
&lt;p&gt;예를 들어,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;(()))(&quot;와 같은 문자열은 &quot;균형잡힌 괄호 문자열&quot; 이지만 &quot;올바른 괄호 문자열&quot;은 아닙니다.&lt;/p&gt;
&lt;p&gt;반면에&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;(())()&quot;와 같은 문자열은 &quot;균형잡힌 괄호 문자열&quot; 이면서 동시에 &quot;올바른 괄호 문자열&quot; 입니다.&lt;/p&gt;
&lt;p&gt;'(' 와 ')' 로만 이루어진 문자열 w가 &quot;균형잡힌 괄호 문자열&quot; 이라면 다음과 같은 과정을 통해 &quot;올바른 괄호 문자열&quot;로 변환할 수 있습니다.&lt;/p&gt;
&lt;p class=&quot;hang1&quot;&gt;1. 입력이 빈 문자열인 경우, 빈 문자열을 반환합니다. 2. 문자열 w를 두 &quot;균형잡힌 괄호 문자열&quot; u, v로 분리합니다. 단, u는 &quot;균형잡힌 괄호 문자열&quot;로 더 이상 분리할 수 없어야 하며, v는 빈 문자열이 될 수 있습니다. 3. 문자열 u가 &quot;올바른 괄호 문자열&quot; 이라면 문자열 v에 대해 1단계부터 다시 수행합니다. 3-1. 수행한 결과 문자열을 u에 이어 붙인 후 반환합니다. 4. 문자열 u가 &quot;올바른 괄호 문자열&quot;이 아니라면 아래 과정을 수행합니다. 4-1. 빈 문자열에 첫 번째 문자로 '('를 붙입니다. 4-2. 문자열 v에 대해 1단계부터 재귀적으로 수행한 결과 문자열을 이어 붙입니다. 4-3. ')'를 다시 붙입니다. 4-4. u의 첫 번째와 마지막 문자를 제거하고, 나머지 문자열의 괄호 방향을 뒤집어서 뒤에 붙입니다. 4-5. 생성된 문자열을 반환합니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&quot;균형잡힌 괄호 문자열&quot;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;p가 매개변수로 주어질 때, 주어진 알고리즘을 수행해&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&quot;올바른 괄호 문자열&quot;&lt;/b&gt;로 변환한 결과를 return 하도록 solution 함수를 완성해 주세요.&lt;/p&gt;
&lt;h3&gt;매개변수 설명&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;p는 '(' 와 ')' 로만 이루어진 문자열이며 길이는 2 이상 1,000 이하인 짝수입니다.&lt;/li&gt;
&lt;li&gt;문자열 p를 이루는 '(' 와 ')' 의 개수는 항상 같습니다.&lt;/li&gt;
&lt;li&gt;만약 p가 이미 &quot;올바른 괄호 문자열&quot;이라면 그대로 return 하면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;h3&gt;입출력 예&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;p&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;(()())()&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;(()())()&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;)(&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;()&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&quot;()))((()&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;()(())()&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;입출력 예에 대한 설명&lt;/h3&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;이미 &quot;올바른 괄호 문자열&quot; 입니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;두 문자열 u, v로 분리합니다.
&lt;ul&gt;
&lt;li&gt;u =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;)(&quot;&lt;/li&gt;
&lt;li&gt;v =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;u가 &quot;올바른 괄호 문자열&quot;이 아니므로 다음과 같이 새로운 문자열을 만듭니다.
&lt;ul&gt;
&lt;li&gt;v에 대해 1단계부터 재귀적으로 수행하면 빈 문자열이 반환됩니다.&lt;/li&gt;
&lt;li&gt;u의 앞뒤 문자를 제거하고, 나머지 문자의 괄호 방향을 뒤집으면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;&quot;이 됩니다.&lt;/li&gt;
&lt;li&gt;따라서 생성되는 문자열은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;(&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;)&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;&quot;이며, 최종적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;()&quot;로 변환됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #3&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;두 문자열 u, v로 분리합니다.
&lt;ul&gt;
&lt;li&gt;u =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;()&quot;&lt;/li&gt;
&lt;li&gt;v =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;))((()&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;문자열 u가 &quot;올바른 괄호 문자열&quot;이므로 그대로 두고, v에 대해 재귀적으로 수행합니다.&lt;/li&gt;
&lt;li&gt;다시 두 문자열 u, v로 분리합니다.
&lt;ul&gt;
&lt;li&gt;u =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;))((&quot;&lt;/li&gt;
&lt;li&gt;v =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;()&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;u가 &quot;올바른 괄호 문자열&quot;이 아니므로 다음과 같이 새로운 문자열을 만듭니다.
&lt;ul&gt;
&lt;li&gt;v에 대해 1단계부터 재귀적으로 수행하면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;()&quot;이 반환됩니다.&lt;/li&gt;
&lt;li&gt;u의 앞뒤 문자를 제거하고, 나머지 문자의 괄호 방향을 뒤집으면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;()&quot;이 됩니다.&lt;/li&gt;
&lt;li&gt;따라서 생성되는 문자열은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;(&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;()&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;)&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;()&quot;이며, 최종적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;(())()&quot;를 반환합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;처음에 그대로 둔 문자열에 반환된 문자열을 이어 붙이면&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;()&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;(())()&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;=&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;()(())()&quot;가 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618224843223&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public String solution(String p) {
        StringBuilder stringBuilder = new StringBuilder();
        int index = 0;
        int openClose = 0;
        int count = 0;
        int secondStartIndex = -1;
        while (index &amp;lt; p.length()) {
            if (p.charAt(index) == '(') {
                ++count;
                ++openClose;
            } else {
                --openClose;
            }
            if (openClose == 0) {
                secondStartIndex = index + 1;
                break;
            }
            ++index;
        }
        boolean isFirstPerfect = true;
        index = 0;
        openClose = 0;
        while (index &amp;lt; secondStartIndex) {
            if (p.charAt(index) == '(') {
                ++openClose;
            } else {
                --openClose;
            }
            if (openClose &amp;lt; 0) {
                isFirstPerfect = false;
                break;
            }
            ++index;
        }
        if (isFirstPerfect == true) {
            stringBuilder.append(p, 0, secondStartIndex);
            if (secondStartIndex &amp;lt; p.length()) {
                stringBuilder.append(solution(p.substring(secondStartIndex)));
            }
            return stringBuilder.toString();
        } else {
            stringBuilder.append('(');
            if (secondStartIndex &amp;lt; p.length()) {
                stringBuilder.append(solution(p.substring(secondStartIndex)));
            }
            stringBuilder.append(')');
            index = 1;
            while (index &amp;lt; secondStartIndex - 1) {
                if (p.charAt(index) == '(') {
                    stringBuilder.append(')');
                } else {
                    stringBuilder.append('(');
                }
                ++index;
            }
            return stringBuilder.toString();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>LEVEL2</category>
      <category>programmers</category>
      <category>문자열</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/248</guid>
      <comments>https://ydeer.tistory.com/248#entry248comment</comments>
      <pubDate>Mon, 12 Apr 2021 19:54:23 +0900</pubDate>
    </item>
    <item>
      <title>[Lv1] 신규 아이디 추천</title>
      <link>https://ydeer.tistory.com/247</link>
      <description>&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/72410&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;programmers.co.kr/learn/courses/30/lessons/72410&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1618224604315&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 신규 아이디 추천&quot; data-og-description=&quot;카카오에 입사한 신입 개발자 네오는 &amp;quot;카카오계정개발팀&amp;quot;에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. &amp;quot;네오&amp;quot;에게 주어진 첫 업무는 새로 &quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/72410&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/72410&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cEmPKB/hyJQNWTiOF/pOPKTTEKH3Lx0lfo2z7CVk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cftrZR/hyJSldohqt/m0EZ50f90DTJW0O3CqykZ1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/72410&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/72410&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cEmPKB/hyJQNWTiOF/pOPKTTEKH3Lx0lfo2z7CVk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/cftrZR/hyJSldohqt/m0EZ50f90DTJW0O3CqykZ1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 신규 아이디 추천&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;카카오에 입사한 신입 개발자 네오는 &quot;카카오계정개발팀&quot;에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. &quot;네오&quot;에게 주어진 첫 업무는 새로&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;카카오에 입사한 신입 개발자&lt;span&gt;&amp;nbsp;&lt;/span&gt;네오는 &quot;카카오계정개발팀&quot;에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. &quot;네오&quot;에게 주어진 첫 업무는 새로 가입하는 유저들이 카카오 아이디 규칙에 맞지 않는 아이디를 입력했을 때, 입력된 아이디와 유사하면서 규칙에 맞는 아이디를 추천해주는 프로그램을 개발하는 것입니다.&lt;/p&gt;
&lt;p&gt;다음은 카카오 아이디의 규칙입니다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;아이디의 길이는 3자 이상 15자 이하여야 합니다.&lt;/li&gt;
&lt;li&gt;아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;단, 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&quot;네오&quot;는 다음과 같이 7단계의 순차적인 처리 과정을 통해 신규 유저가 입력한 아이디가 카카오 아이디 규칙에 맞는 지 검사하고 규칙에 맞지 않은 경우 규칙에 맞는 새로운 아이디를 추천해 주려고 합니다.&lt;/p&gt;
&lt;p&gt;신규 유저가 입력한 아이디가&lt;span&gt;&amp;nbsp;&lt;/span&gt;new_id&lt;span&gt;&amp;nbsp;&lt;/span&gt;라고 한다면,&lt;/p&gt;
&lt;p&gt;1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다. 2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다. 3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다. 4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다. 5단계 new_id가 빈 문자열이라면, new_id에 &quot;a&quot;를 대입합니다. 6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다. 만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다. 7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.&lt;/p&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;예를 들어, new_id 값이 &quot;...!@BaT#*..y.abcdefghijklm&quot; 라면, 위 7단계를 거치고 나면 new_id는 아래와 같이 변경됩니다.&lt;/p&gt;
&lt;p&gt;1단계 대문자 'B'와 'T'가 소문자 'b'와 't'로 바뀌었습니다.&lt;/p&gt;
&lt;p&gt;&quot;...!@BaT#*..y.abcdefghijklm&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;...!@bat#*..y.abcdefghijklm&quot;&lt;/p&gt;
&lt;p&gt;2단계 '!', '@', '#', '*' 문자가 제거되었습니다.&lt;/p&gt;
&lt;p&gt;&quot;...!@bat#*..y.abcdefghijklm&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;...bat..y.abcdefghijklm&quot;&lt;/p&gt;
&lt;p&gt;3단계 '...'와 '..' 가 '.'로 바뀌었습니다.&lt;/p&gt;
&lt;p&gt;&quot;...bat..y.abcdefghijklm&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;.bat.y.abcdefghijklm&quot;&lt;/p&gt;
&lt;p&gt;4단계 아이디의 처음에 위치한 '.'가 제거되었습니다.&lt;/p&gt;
&lt;p&gt;&quot;.bat.y.abcdefghijklm&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;bat.y.abcdefghijklm&quot;&lt;/p&gt;
&lt;p&gt;5단계 아이디가 빈 문자열이 아니므로 변화가 없습니다.&lt;/p&gt;
&lt;p&gt;&quot;bat.y.abcdefghijklm&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;bat.y.abcdefghijklm&quot;&lt;/p&gt;
&lt;p&gt;6단계 아이디의 길이가 16자 이상이므로, 처음 15자를 제외한 나머지 문자들이 제거되었습니다.&lt;/p&gt;
&lt;p&gt;&quot;bat.y.abcdefghijklm&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;bat.y.abcdefghi&quot;&lt;/p&gt;
&lt;p&gt;7단계 아이디의 길이가 2자 이하가 아니므로 변화가 없습니다.&lt;/p&gt;
&lt;p&gt;&quot;bat.y.abcdefghi&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;bat.y.abcdefghi&quot;&lt;/p&gt;
&lt;p&gt;따라서 신규 유저가 입력한 new_id가 &quot;...!@BaT#*..y.abcdefghijklm&quot;일 때, 네오의 프로그램이 추천하는 새로운 아이디는 &quot;bat.y.abcdefghi&quot; 입니다.&lt;/p&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;[문제]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, &quot;네오&quot;가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;[제한사항]&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;new_id는 길이 1 이상 1,000 이하인 문자열입니다.&lt;/p&gt;
&lt;p&gt;new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있습니다.&lt;/p&gt;
&lt;p&gt;new_id에 나타날 수 있는 특수문자는&lt;span&gt;&amp;nbsp;&lt;/span&gt;-_.~!@#$%^&amp;amp;*()=+[{]}:?,&amp;lt;&amp;gt;/&lt;span&gt;&amp;nbsp;&lt;/span&gt;로 한정됩니다.&lt;/p&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;[입출력 예]&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;no&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;new_id&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;result&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;예1&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;...!@BaT#*..y.abcdefghijklm&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;bat.y.abcdefghi&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;예2&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;z-+.^.&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;z--&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;예3&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;=.=&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;aaa&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;예4&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;123_.def&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;123_.def&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;예5&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;abcdefghijklmn.p&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&quot;abcdefghijklmn&quot;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;입출력 예에 대한 설명&lt;/b&gt;&lt;/p&gt;
&lt;hr style=&quot;box-sizing: content-box; height: 0px; overflow: visible; margin: 1.5rem 0px; border-width: 0.0625rem 0px 0px; border-color: #172334; border-image: initial; border-style: solid initial initial initial;&quot; /&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;문제의 예시와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;7단계를 거치는 동안 new_id가 변화하는 과정은 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;1단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;2단계&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;z-+.^.&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;z-..&quot;&lt;/p&gt;
&lt;p&gt;3단계&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;z-..&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;z-.&quot;&lt;/p&gt;
&lt;p&gt;4단계&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;z-.&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;z-&quot;&lt;/p&gt;
&lt;p&gt;5단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;6단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;7단계&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;z-&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;z--&quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #3&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;7단계를 거치는 동안 new_id가 변화하는 과정은 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;1단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;2단계&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;=.=&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;.&quot;&lt;/p&gt;
&lt;p&gt;3단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;4단계&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;.&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;(new_id가 빈 문자열이 되었습니다.)&lt;/p&gt;
&lt;p&gt;5단계&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;a&quot;&lt;/p&gt;
&lt;p&gt;6단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;7단계&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;a&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;aaa&quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #4&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;1단계에서 7단계까지 거치는 동안 new_id(&quot;123_.def&quot;)는 변하지 않습니다. 즉, new_id가 처음부터 카카오의 아이디 규칙에 맞습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;입출력 예 #5&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;1단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;2단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;3단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;4단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;5단계 변화 없습니다.&lt;/p&gt;
&lt;p&gt;6단계&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;abcdefghijklmn.p&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;abcdefghijklmn.&quot;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;rarr;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;abcdefghijklmn&quot;&lt;/p&gt;
&lt;p&gt;7단계 변화 없습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;pre id=&quot;code_1618224718283&quot; class=&quot;prettyprint lang-java java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public String solution(String new_id) {
        String answer = new_id.toLowerCase();
        answer = answer.replaceAll(&quot;[^a-z0-9-_.]&quot;, &quot;&quot;);
        answer = answer.replaceAll(&quot;\\.{2,}&quot;, &quot;.&quot;);
        answer = answer.replaceAll(&quot;^\\.|\\.$&quot;, &quot;&quot;);
        if (answer.equals(&quot;&quot;)) {
            answer = &quot;a&quot;;
        } else if (answer.length() &amp;gt; 15) {
            answer = answer.substring(0, 15);
            answer = answer.replaceAll(&quot;\\.$&quot;, &quot;&quot;);
        }
        while (answer.length() &amp;lt; 3) {
            answer = answer + answer.substring(answer.length() - 1);
        }
        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Problem Solving/programmers</category>
      <category>level1</category>
      <category>programmers</category>
      <category>regex</category>
      <category>정규표현식</category>
      <author>현록</author>
      <guid isPermaLink="true">https://ydeer.tistory.com/247</guid>
      <comments>https://ydeer.tistory.com/247#entry247comment</comments>
      <pubDate>Mon, 12 Apr 2021 19:52:05 +0900</pubDate>
    </item>
  </channel>
</rss>