<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Eyeeshot BloG</title>
    <link>https://eyeeshot.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 17 May 2026 21:13:19 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>eyeeshot</managingEditor>
    <image>
      <title>Eyeeshot BloG</title>
      <url>https://t1.daumcdn.net/cfile/tistory/152A8B3A4D86E93E09</url>
      <link>https://eyeeshot.tistory.com</link>
    </image>
    <item>
      <title>Mac wifi 비번 확인하기</title>
      <link>https://eyeeshot.tistory.com/49</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;security&amp;nbsp;find-generic-password&amp;nbsp;-ga&amp;nbsp;&amp;lt;SSID&amp;gt;&amp;nbsp;|&amp;nbsp;grep&amp;nbsp;password&lt;/p&gt;</description>
      <category>ETC</category>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/49</guid>
      <comments>https://eyeeshot.tistory.com/49#entry49comment</comments>
      <pubDate>Fri, 14 Apr 2023 11:41:47 +0900</pubDate>
    </item>
    <item>
      <title>깨끗한 코드</title>
      <link>https://eyeeshot.tistory.com/48</link>
      <description>&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot; data-ccp-parastyle-defn=&quot;{&amp;quot;ObjectId&amp;quot;:&amp;quot;0c44df34-e8e2-47c4-9c65-01d7a700a25e|6&amp;quot;,&amp;quot;ClassId&amp;quot;:1073872969,&amp;quot;Properties&amp;quot;:[469775450,&amp;quot;티몬 제목1&amp;quot;,201340122,&amp;quot;2&amp;quot;,134234082,&amp;quot;true&amp;quot;,134233614,&amp;quot;true&amp;quot;,469778129,&amp;quot;1&amp;quot;,335572020,&amp;quot;1&amp;quot;,134224900,&amp;quot;true&amp;quot;,201342446,&amp;quot;0&amp;quot;,201342447,&amp;quot;4&amp;quot;,201342448,&amp;quot;2&amp;quot;,201342449,&amp;quot;0&amp;quot;,469777841,&amp;quot;맑은 고딕&amp;quot;,469777842,&amp;quot;Times New Roman&amp;quot;,469777843,&amp;quot;맑은 고딕&amp;quot;,469777844,&amp;quot;맑은 고딕&amp;quot;,201341986,&amp;quot;0&amp;quot;,469769226,&amp;quot;맑은 고딕,Times New Roman&amp;quot;,335551500,&amp;quot;12602624&amp;quot;,268442635,&amp;quot;32&amp;quot;,335559740,&amp;quot;259&amp;quot;,201341983,&amp;quot;0&amp;quot;,335559739,&amp;quot;0&amp;quot;,335559738,&amp;quot;40&amp;quot;,335551550,&amp;quot;1&amp;quot;,335551620,&amp;quot;1&amp;quot;,335560102,&amp;quot;1&amp;quot;,134245417,&amp;quot;false&amp;quot;,134245418,&amp;quot;true&amp;quot;,469777929,&amp;quot;티몬 제목1 Char&amp;quot;,469778324,&amp;quot;Normal&amp;quot;]}&quot; data-ccp-parastyle-linked-defn=&quot;{&amp;quot;ObjectId&amp;quot;:&amp;quot;0c44df34-e8e2-47c4-9c65-01d7a700a25e|8&amp;quot;,&amp;quot;ClassId&amp;quot;:1073872969,&amp;quot;Properties&amp;quot;:[469775450,&amp;quot;티몬 제목1 Char&amp;quot;,201340122,&amp;quot;1&amp;quot;,134233614,&amp;quot;true&amp;quot;,469778129,&amp;quot;1Char&amp;quot;,335572020,&amp;quot;1&amp;quot;,134231262,&amp;quot;true&amp;quot;,134224900,&amp;quot;true&amp;quot;,134224901,&amp;quot;false&amp;quot;,201340374,&amp;quot;0&amp;quot;,201342446,&amp;quot;0&amp;quot;,201342447,&amp;quot;4&amp;quot;,201342448,&amp;quot;2&amp;quot;,201342449,&amp;quot;0&amp;quot;,469777841,&amp;quot;맑은 고딕&amp;quot;,469777842,&amp;quot;Times New Roman&amp;quot;,469777843,&amp;quot;맑은 고딕&amp;quot;,469777844,&amp;quot;맑은 고딕&amp;quot;,201341986,&amp;quot;0&amp;quot;,469769226,&amp;quot;맑은 고딕,Times New Roman&amp;quot;,335551500,&amp;quot;12602624&amp;quot;,268442635,&amp;quot;32&amp;quot;,134233111,&amp;quot;false&amp;quot;,335559705,&amp;quot;1042&amp;quot;,335551547,&amp;quot;1033&amp;quot;,469777929,&amp;quot;티몬 제목1&amp;quot;,469778324,&amp;quot;Default Paragraph Font&amp;quot;]}&quot;&gt;나쁜 코드&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;80년대 &lt;/span&gt;&lt;span&gt;후반&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;킬러&lt;/span&gt;&lt;span&gt; 앱 &lt;/span&gt;&lt;span&gt;하나를&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;구현한&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;회사가&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;있었다&lt;/span&gt;&lt;span&gt;. &lt;/span&gt;&lt;span&gt;제품은&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;커다란&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;인기를&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;얻으며&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;수많은&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;전문가가&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;구매해&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;사용했다&lt;/span&gt;&lt;span&gt;. &lt;/span&gt;&lt;span&gt;그런데&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;제품&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;출시&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;주기가&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;점점&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;늘어지다&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;고 프로그램의 시동 시간도 길어지고 프로그램이 죽는 횟수도 늘어나다&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;사용자가 줄어들어 &lt;/span&gt;&lt;span&gt;결국 회사가 &lt;/span&gt;&lt;span&gt;망했다.&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 20여년 &lt;/span&gt;&lt;span&gt;지난&lt;/span&gt;&lt;span&gt; 후 그 &lt;/span&gt;&lt;span&gt;회사&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;초창기&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;직원을&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;우연히&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;만나&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;물어보니&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;원인은&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;출시가&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;바빠&lt;/span&gt;&lt;span&gt; 코드를 마구 &lt;/span&gt;&lt;span&gt;짰고&lt;/span&gt;&lt;span&gt;, 기능을 &lt;/span&gt;&lt;span&gt;추가할&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;수록&lt;/span&gt;&lt;span&gt; 코드는 엉망이 되었고 결국 감당이 불가능한 수준에 이르러&lt;/span&gt;&lt;span&gt; 회사가 망하게 된&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;것이다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 프로그래머라면 누구나 나쁜 코드로 고생하거나 &lt;/span&gt;&lt;span&gt;나쁜코드&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;를&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;생성해본&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;적이&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;있을&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;것이다&lt;/span&gt;&lt;span&gt;. 우리는 나쁜 코드를 생성하고 나중에 꼭 손보겠다고 생각한다. 또한 &lt;/span&gt;&lt;span&gt;돌아간다는 사실에 안도감을 느끼며 &lt;/span&gt;&lt;span&gt;안돌아&lt;/span&gt;&lt;span&gt; 가는 프로그램보다 돌아가는 쓰레기 좋다고 스스로를 위로 한 경험도 &lt;/span&gt;&lt;span&gt;있을 것이다&lt;/span&gt;&lt;span&gt;. 우리는 &lt;/span&gt;&lt;span&gt;르블랑의&lt;/span&gt;&lt;span&gt; 법칙을 몰랐다. 나중은 결코 오지 않는다.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;나쁜 코드로 치르는 대가&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;나쁜 코드는 개발 속도를 크게 떨어뜨린다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 나쁜 코드가 쌓일수록 팀 생산성은 떨어진다. 마침내 0에 근접한다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 생산성이 떨어지면 관리층은 복&lt;/span&gt;&lt;span&gt;구&lt;/span&gt;&lt;span&gt;를&lt;/span&gt;&lt;span&gt; 시도한다. 인력추가로. 하지만 새 인력은 생산성을 높여야 한다는 압박에 &lt;/span&gt;&lt;span&gt;나쁜 코드를&lt;/span&gt;&lt;span&gt; 더 많이 양산한다. 그래서 &lt;/span&gt;&lt;span&gt;더&lt;/span&gt;&lt;span&gt;더욱 떨어져 거의 0이 된다.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;원대한 재설계의 꿈&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;나쁜 코드가 많은 코드로 더 이상 일하지 못하는 상태가&lt;/span&gt;&lt;span&gt; 재설계를 하게 된다. &lt;/span&gt;&lt;span&gt;새로운 타이거 팀이 구성되고 새로운 프로젝트이기 &lt;/span&gt;&lt;span&gt;때&lt;/span&gt;&lt;span&gt;문에&lt;/span&gt;&lt;span&gt; 유능하고 똑똑한 사람의 지원을 넣고 나머지는 계속해서 시스템을 유지보수&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;한다. &lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 타이거 팀은 운영에서 변경되는 부분을 합쳐 새 시스템을 만들어야 &lt;/span&gt;&lt;span&gt;되기 때문에&lt;/span&gt;&lt;span&gt; 최고 10&lt;/span&gt;&lt;span&gt;년 걸리는 경우도 보았다고&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;한다. &lt;/span&gt;&lt;span&gt;결국 새로운 팀이 &lt;/span&gt;&lt;span&gt;새로운&lt;/span&gt;&lt;span&gt; 재설계를 들어가도 기존 시스템 기능 + 신규 기능까지 하려면 계속적으로 시간이 소모된다. 결국 코드를 &lt;/span&gt;&lt;span&gt;작성할 때마다&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;깨끗한&lt;/span&gt;&lt;span&gt; 코드를 만드는 노력이 비용을 &lt;/span&gt;&lt;span&gt;절감하는 방법.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;태도&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;간단한 업무라고 예상한 업무가 몇 &lt;/span&gt;&lt;span&gt;주동안&lt;/span&gt;&lt;span&gt; 늘어진 경험이 있는가? &lt;/span&gt;&lt;span&gt;한줄만&lt;/span&gt;&lt;span&gt; 고치면 &lt;/span&gt;&lt;span&gt;될 거라&lt;/span&gt;&lt;span&gt; 예상했지만 &lt;/span&gt;&lt;span&gt;나쁜 코드로&lt;/span&gt;&lt;span&gt; 인하여 결국 많은 코드를 수정하는 경험들을 보통 한다. 나쁜 코드는 왜 생길까&lt;/span&gt;&lt;span&gt;? 여러가지 이유가 있지만 결국 &lt;/span&gt;&lt;span&gt;나쁜 코드를&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;만드는 것도&lt;/span&gt;&lt;span&gt; 코드를 작성하는 본인이 되는 경우가 많다. &lt;/span&gt;&lt;span&gt;어느 환자가 수술 전에 손을 씻지 말라고 요구한다. 시간이 너무 걸리니까 확실히 환자는 상사다 하지만 의사는 단호하게 거부한다. 이유는 질병과 감염의 위험은 환자보다 의사가 더 잘 아니까. 환자 말을 그대로 따르는 &lt;/span&gt;&lt;span&gt;행동은 전문가 답지 못하다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 좋은 코드를 사수하는 일은 바로 우리 프로그래머들의 책임이다.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;원초적 난제&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;나쁜 코드는&lt;/span&gt;&lt;span&gt; 업무속도를 낮춘다. 그런데 모든 프로그래머가 기한을 맞추려면 나쁜 코드를 양산할 &lt;/span&gt;&lt;span&gt;수밖에&lt;/span&gt;&lt;span&gt; 없다고 느낀다.&amp;nbsp; 나쁜 코드를 양산하면 기한을 맞&lt;/span&gt;&lt;span&gt;추지 못한다. 기한을 맞추는 유일한 방법은 언제나 코드를 최대한 깨끗하게 유지하는 습관이다.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;깨끗한 코드라는 예술?&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;꺠끗한&lt;/span&gt;&lt;span&gt; 코드를 어떻게 작성할까? 그림을 그리는 행위와 &lt;/span&gt;&lt;span&gt;비슷&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 청결이라는 힘겹게 습득한 감각을 활용해 자잘한 기법들을 적용하는 절제와 규율이 필요.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;깨끗한 &lt;/span&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;코드란&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;?&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;비야네&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;스트롭스트룹&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;( C++&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; 창시자이자 The C++ &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Programming&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Language&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; 저자)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;비야네는&lt;/span&gt;&lt;span&gt; 우아하고 효율적인 코드를 좋아한다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 깨끗한 코드는 보는 사람에게 즐거움을 선사해야 한다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 나쁜 코드는 나쁜 코드를 유혹한다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 세세한 사항까지 &lt;/span&gt;&lt;span&gt;꼼꼼&lt;/span&gt;&lt;span&gt;하게 신경 쓰라.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 깨끗한 코드는 한가지에 집중한다. 주변 상황에 현혹되거나 오염되지 않는 채 한길만 걷는다.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;그래디&lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; 부치 (&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Object&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Oriented&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Analysis&lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; and &lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Design&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;with&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Application&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; 저자)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;깨끗한 코드는 단순하고 직접적이다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 깨끗한 코드는 잘 쓴 문장처럼 읽힌다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 깨끗한 코드는 결코 설계자의 의도를 숨기지 않는다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 오히려 &lt;/span&gt;&lt;span&gt;명쾌한&lt;/span&gt;&lt;span&gt; 추상화와 단순한 제어문으로 가득하다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;코드는 추측이 아니라 사실에 기반해야 한다.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;&amp;lsquo;큰(Big)&amp;rsquo; &lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;데이브&lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; 토마스 (OTI 창립자이자 이클립스 전략의 대부)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;깨끗한 코드는 작성자가 아닌 사람도 읽기 쉽고 고치기 쉽다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 깨끗한 코드에는 의미 있는 이름이 붙는다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 특정 목적을 달성하는 방법은 하나만 제공한다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 의존성은 최소이며 각 의존성을 명확히 정의한다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 테스트 케이스가 없는 코드는 깨끗한 코드가 아니다.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;마이클 &lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;페더스&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Working&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Effectively&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;with&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Legacy&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Code&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; 저자)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;깨끗한 코드의 특징은 모두를 아우르는 특징이 하나 있다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 고치려고 살펴봐도 딱히 손 댈 곳이 없다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;깨&lt;/span&gt;&lt;span&gt;끗한&lt;/span&gt;&lt;span&gt; 코드는 주의 깊게 작성한 코드.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;론 &lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;제프리스&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; (&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Extreme&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Programming&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Intalled&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; 와 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Extreme&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Programming&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;Adventure&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;in&lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; C# &lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;저자&lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;중복을 피하라.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 한 기능만 수행하라.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 제대로 표현하라.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 작게 &lt;/span&gt;&lt;span&gt;추&lt;/span&gt;&lt;span&gt;상&lt;/span&gt;&lt;span&gt;화하라&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #4472c4;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;워드 &lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;커닝햄&lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; (위키 창시자, 피트 창시자, &lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt;익스트림&lt;/span&gt;&lt;span data-ccp-charstyle=&quot;Intense Reference&quot;&gt; 프로그래밍 공동 창시자)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #4472c4;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;코드가 그 문제를 풀기 위한 언어처럼 보인다면 아름다운 코드라 불러도 되겠다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 깨끗한 코드는 읽으면서 &lt;/span&gt;&lt;span&gt;놀&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;날&lt;/span&gt;&lt;span&gt; 일이 없어야 한다.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;우리는 저자다&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Javadoc&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; 에서 @author 필드는 저자를 소개한다. 코드를&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;작성할 때는&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;자신이 저자라는 사실을 기억해야한다.&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;보이스카우트 규칙&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;시간이 지나도 언제나 깨끗하게 유지해야 한다.&lt;/span&gt;&lt;span&gt; 시간이 지날수록 코드가 좋아지는 프로젝트에서 작업한다고 상상해봐라.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #004dc0;&quot; data-contrast=&quot;none&quot;&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt;프리퀄과&lt;/span&gt;&lt;span data-ccp-parastyle=&quot;티몬 제목1&quot;&gt; 원칙&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #004dc0;&quot; data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559738&amp;quot;:40,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;SRP (The &lt;/span&gt;&lt;span&gt;Single&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Reponsibility&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Principle&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;) :&lt;/span&gt;&lt;span&gt; 단일 책임의 원칙 클래스에는 한 가지, 단 한 가지 변경 이유만 존재해야 한다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;OCP (The &lt;/span&gt;&lt;span&gt;Open&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Closed&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Principle&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;) :&lt;/span&gt;&lt;span&gt; 개방 폐쇄의 원칙 클래스는 확장에 &lt;/span&gt;&lt;span&gt;열려있어야하며&lt;/span&gt;&lt;span&gt;, 변경에 &lt;/span&gt;&lt;span&gt;닫혀있어야&lt;/span&gt;&lt;span&gt; 한다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;LSP (The &lt;/span&gt;&lt;span&gt;Liskov&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Substitution&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Principle&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;) :&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;리스코프의&lt;/span&gt;&lt;span&gt; 치환 법칙 상속받은 클래스는 기초 클래스를 대체할 수 있어야 한다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;DIP (The &lt;/span&gt;&lt;span&gt;Dependency&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Inversion&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Principle&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;) :&lt;/span&gt;&lt;span&gt; 의존 역전의 법칙 추상화에 &lt;/span&gt;&lt;span&gt;의존해야하며&lt;/span&gt;&lt;span&gt;, 구체화에 의존하면 안된다.&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;ISP (The &lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Segregation&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;Principle&lt;/span&gt;&lt;/span&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;span&gt;) :&lt;/span&gt;&lt;span&gt; 인터페이스 분리 원칙 클라이언트에 밀접하게 작게 쪼개진 인터페이스를 유지한다.&lt;/span&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span data-contrast=&quot;auto&quot;&gt;&lt;/span&gt;&lt;span data-ccp-props=&quot;{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6,&amp;quot;335559739&amp;quot;:160,&amp;quot;335559740&amp;quot;:259}&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;</description>
      <category>STUDY/CleanCode</category>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/48</guid>
      <comments>https://eyeeshot.tistory.com/48#entry48comment</comments>
      <pubDate>Mon, 22 Aug 2022 19:01:59 +0900</pubDate>
    </item>
    <item>
      <title>작심 3일</title>
      <link>https://eyeeshot.tistory.com/47</link>
      <description>&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;업무를 하며 업무에 관련된 부분은 회사 wiki 에 정리하는 습관은 있는데 재사용을 위한 내 개인적인 기록은 또 2년동안 거의 없는듯하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하려고했던 토이프로젝트는 벌써 3~4년이 되어가고... 다시또 조금한것이라도 정리를 계속 해보려고 노력해봐야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이글이 또 1~2년후에 저때 또 객기부렸구나가 아니라 좀더 변화된 모습의 글로 비추어지도록 노력해봐야곘다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이글은 그냥 앞으로다 다시한번의 다짐이다.&lt;/p&gt;</description>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/47</guid>
      <comments>https://eyeeshot.tistory.com/47#entry47comment</comments>
      <pubDate>Thu, 12 May 2022 12:10:36 +0900</pubDate>
    </item>
    <item>
      <title>Python Docker Image Create</title>
      <link>https://eyeeshot.tistory.com/45</link>
      <description>&lt;p&gt;새로운 python 어플리케이션을 구동하기 위해서 항상 관련 라이브어리를 설치하고 설정하고 하는것은 비효율적이다.&lt;/p&gt;
&lt;p&gt;Docker는 어플리케이션을 신속하게 구축, 테스트 및 배포할수 있는 소프트웨어 플랫폼이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;python 을 테스트 및 개발하기위해 docker를 활용하여 생성해 보겠다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;우선 docker를 사용하기 위해서는 Docker를 설치 해야한다.&lt;/p&gt;
&lt;p&gt;환경별로 docker 설치방법은 &lt;a href=&quot;https://docs.docker.com/engine/install/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt; 에서 확인하고 설치하면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;docker가 설치 되어있으면 아래 명령어를 실행시키면 docker image를 docker hub에서 받아서 실행시킨다.&lt;/p&gt;
&lt;pre id=&quot;code_1611635923787&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker run -it python:3&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2021-01-26 오후 1.44.24.png&quot; data-origin-width=&quot;494&quot; data-origin-height=&quot;199&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UAXrr/btqUL9B8I2S/H60UB3B3OK4jCUsv4hUG4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UAXrr/btqUL9B8I2S/H60UB3B3OK4jCUsv4hUG4K/img.png&quot; data-alt=&quot;명령어를 실행하면 local에 image가 없기때문에 hub에서 다운받게 된다. 버전을 따로 기입안했기때문에 lastest로 받게됩니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UAXrr/btqUL9B8I2S/H60UB3B3OK4jCUsv4hUG4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUAXrr%2FbtqUL9B8I2S%2FH60UB3B3OK4jCUsv4hUG4K%2Fimg.png&quot; data-filename=&quot;스크린샷 2021-01-26 오후 1.44.24.png&quot; data-origin-width=&quot;494&quot; data-origin-height=&quot;199&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;figcaption&gt;명령어를 실행하면 local에 image가 없기때문에 hub에서 다운받게 된다. 버전을 따로 기입안했기때문에 lastest로 받게됩니다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷 2021-01-26 오후 1.46.24.png&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;64&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QSIUs/btqUGUeFbm6/eVCLmlB9zyE1RKDKh7rwAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QSIUs/btqUGUeFbm6/eVCLmlB9zyE1RKDKh7rwAK/img.png&quot; data-alt=&quot;이미지가 이미 있을경우는 위 그림처럼 바로 실행이 된다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QSIUs/btqUGUeFbm6/eVCLmlB9zyE1RKDKh7rwAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQSIUs%2FbtqUGUeFbm6%2FeVCLmlB9zyE1RKDKh7rwAK%2Fimg.png&quot; data-filename=&quot;스크린샷 2021-01-26 오후 1.46.24.png&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;64&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;figcaption&gt;이미지가 이미 있을경우는 위 그림처럼 바로 실행이 된다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1611636539736&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker run -it python:3 bash

#결과

root@c0f596673d25:/#&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위명령어를 치면 python 이미지의 터널링으로 접속할수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;환경변수를 넣는 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1611636711230&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker run -it --env CONF_PATH=eyeeshot python:3 bash

#bash 후 확인.
root@c0f596673d25:/# echo $CONF_PATH
eyeeshot
root@c0f596673d25:/#&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;디렉터리 연결 방법&lt;/p&gt;
&lt;pre id=&quot;code_1611637656483&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ ls ./sample
requirements.txt  test.py

#결과
$ docker run -it --volume `pwd`/sample:/sample python:3 bash
root@ee20e3d16632:/# ls /sample
requirements.txt  test.py
root@ee20e3d16632:/#&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;docker 실행 하는 위치에서 sample 폴더를 만든후 그안에 requirements.txt 와 test.py 생성한후 연결해보면 이미지 안에도 같은 파일이 확인되는것을 볼수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위와같이 python 어플리케이션 실행시 필요한 의존 패키지와 파일들을 연결하여 docker image로 테스트 해볼수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;하지만 항상 저렇게 명령어를 다 붙여서 하는것 비효율 적이다. 따라서 Dockerfile을 작성하여 만들면 편하게 사용할수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Dockerfile&lt;/p&gt;
&lt;pre id=&quot;code_1611638026232&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FROM python:3.8-alpine
LABEL maintainer=&quot;eyeeshot@gmail.com&quot;

WORKDIR /app

ADD ./sample /app/
RUN pip install -r requirements.txt

CMD [&quot;python&quot;,&quot;app.py&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위 도커 파일을 만든후 아래 명령어를 실행하면 이미지가 생성된다.&lt;/p&gt;
&lt;pre id=&quot;code_1611638086363&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker build -t my-python .
$ docker images
REPOSITORY                    TAG                 IMAGE ID            CREATED             SIZE
my-python                     latest              e1adc20df7cb        5 seconds ago       903MB&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위와 같이하면 images가 생성된것을 볼수 있을것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1611639190818&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ docker run -d -p 8000:5000 my-python&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;위 명령어를치면 docker가 정상적으로 뜬것을 확인할수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1611888147981&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#
$ curl localhost:8000
Hello, world! $&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;curl 로 정상적으로 flask가 동작하는것을 확인할수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;해당소스는 아래 git에서 받을수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/eyeeshot/flask-docker&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;github.com/eyeeshot/flask-docker&lt;/a&gt;&lt;/p&gt;</description>
      <category>Tech</category>
      <category>docker</category>
      <category>Flask</category>
      <category>python</category>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/45</guid>
      <comments>https://eyeeshot.tistory.com/45#entry45comment</comments>
      <pubDate>Fri, 29 Jan 2021 11:54:14 +0900</pubDate>
    </item>
    <item>
      <title>심볼릭 링크</title>
      <link>https://eyeeshot.tistory.com/44</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;심볼릭 링크(symbolic link)&amp;nbsp;란?&lt;/b&gt;&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 폴더에 있는 파일을 해당 디렉토리에서 사용하는 것과 같은 효과를 내는 링크이다.&amp;nbsp; 윈도우의 바로가기와 비슷한 개념&amp;nbsp;&lt;/li&gt;
&lt;li&gt;폴더나 파일 둘다 사용 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1611882415011&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ln -s [대상 원본 파일] [새로 만들 파일 이름]
 
#예제 volume1/docker 에 있는것을 현제위치에 docker로 심볼릭링크
ln -s /volume1/docker/ docker
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Tech</category>
      <category>ln</category>
      <category>symbolic link</category>
      <category>심볼릭링크</category>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/44</guid>
      <comments>https://eyeeshot.tistory.com/44#entry44comment</comments>
      <pubDate>Fri, 29 Jan 2021 10:07:31 +0900</pubDate>
    </item>
    <item>
      <title>AWS IoT Core Job</title>
      <link>https://eyeeshot.tistory.com/43</link>
      <description>&lt;p&gt;1. AWS IoT Jobs 란?&lt;br /&gt;2. AWS IoT Jobs 전제조건.&lt;br /&gt;3. Jobs 디바이스와 작업.&lt;br /&gt;4.&amp;nbsp; 작업 생성&lt;/p&gt;
&lt;h2&gt;1. AWS IoT Jobs 란?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;AWS IoT 작업 서비스는 AWS IoT에 연결되는 하나 이상의 디바이스로 전송된 후 실행되는 원격 작업 세트를 정의하는 데 사용.&lt;/li&gt;
&lt;li&gt;주된 목적은 소프트웨어 또는 펌웨어 업데이트를 디바이스에게 알리는데 사용.&lt;/li&gt;
&lt;li&gt;작업 문서란 AWS IoT Job 생성시 대상이 되는 디바이스로 전송되는 문서.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. AWS IoT Jobs 전제조건&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;작업을 생성시 작업문서는 Amazon S3 버킷의 파일 링크 또는 생성시 본문에 입력할수 있습니다.&lt;/li&gt;
&lt;li&gt;AWS 계정에 속한 사물 및 사물 그룹이 대상이 됩니다. 따라서 사물 및 사물 그룹이 있어야합니다.&lt;/li&gt;
&lt;li&gt;작업 생성을 위해&amp;nbsp;IAM 권한 필요&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;Version&quot;: &quot;2012-10-17&quot;,
  &quot;Statement&quot;: [
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: [
        &quot;s3:ListBucket&quot;,
        &quot;s3:ListAllMyBuckets&quot;,
        &quot;s3:CreateBucket&quot;,
        &quot;s3:PutBucketVersioning&quot;,
        &quot;s3:GetBucketLocation&quot;,
        &quot;s3:GetObjectVersion&quot;,
        &quot;s3:GetObject&quot;,
        &quot;s3:PutObject&quot;,
        &quot;s3:ListBucketVersions&quot;
      ],
      &quot;Resource&quot;: [
        &quot;arn:aws:s3:::{{RESOURCE}}&quot;,
        &quot;arn:aws:s3:::us-east-1-greengrass-updates/*&quot;,
        &quot;arn:aws:s3:::us-west-2-greengrass-updates/*&quot;,
        &quot;arn:aws:s3:::ap-northeast-1-greengrass-updates/*&quot;,
        &quot;arn:aws:s3:::ap-northeast-2-greengrass-updates/*&quot;,
        &quot;arn:aws:s3:::ap-southeast-2-greengrass-updates/*&quot;,
        &quot;arn:aws:s3:::eu-central-1-greengrass-updates/*&quot;,
        &quot;arn:aws:s3:::eu-west-1-greengrass-updates/*&quot;
      ]
    },
    {
      &quot;Action&quot;: [
        &quot;greengrass:CreateSoftwareUpdateJob&quot;
      ],
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Resource&quot;: &quot;*&quot;
    },
    {
      &quot;Effect&quot;: &quot;Allow&quot;,
      &quot;Action&quot;: [
        &quot;iot:*&quot;,
        &quot;iam:GetRole&quot;,
        &quot;iam:PassRole&quot;,
        &quot;iam:ListRoles&quot;,
        &quot;signer:GetSigningProfile&quot;,
        &quot;signer:StartSigningJob&quot;,
        &quot;signer:DescribeSigningJob&quot;
      ],
      &quot;Resource&quot;: &quot;*&quot;
    }
  ]
}&lt;/code&gt;&lt;/pre&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/Bebka/btqUUpY569p/nkc4719dS0Rl9ksg7gvmvk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Bebka/btqUUpY569p/nkc4719dS0Rl9ksg7gvmvk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Bebka/btqUUpY569p/nkc4719dS0Rl9ksg7gvmvk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/Bebka/btqUUpY569p/nkc4719dS0Rl9ksg7gvmvk/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;h2&gt;3. AWS IoT Jobs 디바이스와 작업&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;작업을 생성하기전 디바이스는 AWS IoT Core에 연결되어있어야 한다.&lt;/li&gt;
&lt;li&gt;작업을 실행하기할 대상 디바이스는 프로그래밍을 사전에 준비해야 한다.&lt;/li&gt;
&lt;li&gt;대상이 되는 디바이스는 아래의 토픽을 구독하고 있어야합니다.
&lt;ul&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/notify(또는&amp;nbsp;$aws/things/{디바이스이름}/jobs/notify-next)&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/get/accepted&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/get/rejected&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/{jobId}/get/accepted&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/{jobId}/get/rejected&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;디바이스 워크 플로우는 크게 두가지로 나눠질수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;&amp;nbsp;Get the next Job
&lt;ol&gt;
&lt;li&gt;다비아스가 처음 온라인에 연결되면 해당 디바이스의 notify-next 토픽을 구독해야합니다.&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/{작업ID}/get 토픽에 메시지를 게시합니다.&lt;/li&gt;
&lt;li&gt;$next에 저장된 모든 상태를 포함하여 다음 작업, 작업 문서 및 기타 세부 정보를 가져옵니다.statusDetails&amp;nbsp;작업 문서에 코드 파일 서명이 있는 경우 작업 요청을 진행하기 전에 서명을 확인해야 합니다.&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/{작업ID}/update 토픽에 메시지를 게시합니다. 또는 이번 단계와 이전 단계를 단일 호출로 결합하고 싶다면 디바이스에서&amp;nbsp;$aws/things/{디바이스이름}/jobs/start-next 토픽에 메시지를 게시하셔도 좋습니다.&lt;/li&gt;
&lt;li&gt;(선택 사항)&amp;nbsp;$aws/things/{디바이스이름}/jobs/{작업ID}/update&amp;nbsp;또는&amp;nbsp;$aws/things/{디바이스이름}/jobs/start-next&amp;nbsp;를 호출하면&amp;nbsp;stepTimeoutInMinutes에 대한 값을 설정하여 단계 타이머를 추가할 수 있습니다.&lt;/li&gt;
&lt;li&gt;작업 진행 상황이 변화될때마다 상태를 변경하려면&amp;nbsp;$aws/things/{디바이스이름}/jobs/{작업ID}/update 토픽에 메시지를 게시합니다.&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/{작업ID}/get&amp;nbsp;토픽에 메시지를 게시하면서 작업 실행을 계속 모니터링합니다. 작업 실행이 삭제되면 ResourceNotFoundException를 반환합니다.&lt;/li&gt;
&lt;li&gt;작업이 완료되면&amp;nbsp;$aws/things/{디바이스이름}/jobs/{작업ID}/update 토픽에 메시지를 게시하여 작업 상태를 업데이트하고 성공 또는 실패 여부를 보고합니다.&lt;/li&gt;
&lt;li&gt;이번 작업의 실행 상태는 종료 상태로 바뀌었기 때문에 다음에 실행할 수 있는 작업(있는 경우)도 바뀝니다. 그러고 나서 디바이스에게도 다음 대기 중인 작업 실행이 바뀌었다는 알림 메시지가 수신됩니다. 이때는 디바이스가 2번으로에서 설명한 대로 계속 진행되어야 합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Pick from available jobs
&lt;ol&gt;
&lt;li&gt;디바이스가 처음 온라인에 연결되면 해당 사물의&amp;nbsp;notify&amp;nbsp;주제를 구독해야 합니다.&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/get&amp;nbsp;토픽에 메시지를 게시하여&amp;nbsp;대기 중인 작업 실행 목록을 가져옵니다.&lt;/li&gt;
&lt;li&gt;목록에 작업 실행이 다수인 경우에는 하나를 선택합니다.&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/{작업ID}/get 토픽에 메시지를 게시합니다.&amp;nbsp;statusDetails&amp;nbsp;작업 문서에 코드 파일 서명이 있는 경우 작업 요청을 진행하기 전에 서명을 확인해야 합니다.&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/{작업ID}/update 토픽에 메시지를 게시합니다.&amp;nbsp;이 명령에서&amp;nbsp;includeJobDocument&amp;nbsp;필드가&amp;nbsp;true로 설정되어 있으면 디바이스가 이전 단계를 건너뛰고 이번 단계에서 작업 문서를 가져올 수 있습니다.&lt;/li&gt;
&lt;li&gt;선택적으로,&amp;nbsp;$aws/things/{디바이스이름}/jobs/{작업ID}/update 토픽에 메시지를 게시하면&amp;nbsp;stepTimeoutInMinutes에 대한 값을 설정하여 단계 타이머를 추가할 수 있습니다.&lt;/li&gt;
&lt;li&gt;작업 진행 상황이 변화될때마다 상태를 변경하려면&amp;nbsp;$aws/things/{디바이스이름}/jobs/{작업ID}/update 토픽에 메시지를 게시합니다.&lt;/li&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/{작업ID}/get&amp;nbsp;토픽에 메시지를 게시하면서 작업 실행을 계속 모니터링합니다. 작업 실행이 삭제되면 ResourceNotFoundException를 반환합니다.&lt;/li&gt;
&lt;li&gt;작업이 완료되면&amp;nbsp;$aws/things/{디바이스이름}/jobs/{작업ID}/update 토픽에 메시지를 게시하여 작업 상태를 업데이트하고 성공 또는 실패 여부를 보고합니다.&lt;/li&gt;
&lt;li&gt;이번 작업의 실행 상태는 종료 상태로 바뀌었기 때문에 다음에 실행할 수 있는 작업(있는 경우)도 바뀝니다. 그러고 나서 디바이스에게도 다음 대기 중인 작업 실행이 바뀌었다는 알림 메시지가 수신됩니다. 이때는 디바이스가 2번으로에서 설명한 대로 계속 진행되어야 합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;디바이스에서 AWS IoT로 MQTT 통신 예제&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 269px;&quot;&gt;게시할 토픽&lt;/td&gt;
&lt;td style=&quot;width: 269px;&quot;&gt;내용&lt;/td&gt;
&lt;td style=&quot;width: 270px;&quot;&gt;요청 payload example&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 269px;&quot;&gt;
&lt;p&gt;$aws/things/{디바이스이름}/jobs/{작업ID}/get&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 269px;&quot;&gt;
&lt;ul&gt;
&lt;li&gt;clientToken : 선택 사항입니다. 요청과 응답의 연관성을 나타낼때 사용하는 클라이언트 토큰입니다. 여기에 임의 값을 입력하면 응답에 반영됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 270px;&quot;&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{&amp;nbsp;&quot;clientToken&quot;:&amp;nbsp;&quot;string&quot;&amp;nbsp;}&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 269px;&quot;&gt;
&lt;p&gt;$aws/things/{디바이스이름}/jobs/{작업ID}/update&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 269px;&quot;&gt;
&lt;ul&gt;
&lt;li&gt;status : 새로운 작업 실행 상태(IN_PROGRESS, FAILED, SUCCEEDED 또는 REJECTED) 이 명령은 업데이트 할 때 마다 지정해야 합니다.&lt;/li&gt;
&lt;li&gt;statusDetails : 작업 실행 상태를 설명하는 이름-값 페어의 모음입니다. 지정하지 않으면&amp;nbsp;statusDetails가 바뀌지않습니다.&lt;/li&gt;
&lt;li&gt;expectedVersio : 예상되는 현재 작업 실행 버전입니다. 작업 실행은 업데이트할 때마다 버전이 일정하게 증가합니다. AWS IoT 작업 서비스에 저장된 작업 실행 버전이 일치하지 않으면 VersionMismatch 오류와 함께 업데이트가 거부되고, 현재 작업 실행 상태에 대한 데이터가 포함된 ErrorResponse 반환됩니다.&lt;/li&gt;
&lt;li&gt;executionNumber :&amp;nbsp;선택 사항입니다. 디바이스에서 작업 실행을 식별하기 위한 숫자입니다. 지정하지 않으면 최신 작업 실행이 사용됩니다.&lt;/li&gt;
&lt;li&gt;includeJobExecutionState :&amp;nbsp;선택 사항입니다. 이 명령을 추가하여&amp;nbsp;true로 설정하면 응답에&amp;nbsp;JobExecutionState&amp;nbsp;필드가 포함됩니다. 기본값은&amp;nbsp;false입니다.&lt;/li&gt;
&lt;li&gt;includeJobDocument :&amp;nbsp;선택 사항입니다. 이 명령을 추가하여&amp;nbsp;true로 설정하면 응답에&amp;nbsp;JobDocument가 포함됩니다. 기본값은&amp;nbsp;false입니다.&lt;/li&gt;
&lt;li&gt;stepTimeoutInMinutes : 이 디바이스가 이 작업 실행을 마쳐야 하는 시간을 지정합니다. 이 타이머가 완료하기 전에 또는 타이머가 재설정되면(UpdateJobExecution를 다시 호출하고, 상태를&amp;nbsp;IN_PROGRESS로 설정하고, 이 필드에 새 제한 시간 값을 지정하여) 작업 실행 상태는&amp;nbsp;TIMED_OUT로 설정됩니다. 이 제한 시간을 설정 또는 재설정해도 작업이 생성되었을 때 지정했을 수도 있는 작업 실행 제한 시간에는 영향을 주지 않습니다(CreateJob와 함께&amp;nbsp;timeoutConfig&amp;nbsp;사용).&lt;/li&gt;
&lt;li&gt;clientToken :&amp;nbsp;요청과 응답의 연관성을 나타낼 때 사용하는 클라이언트 토큰입니다. 여기에 임의 값을 입력하면 응답에 반영됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 270px;&quot;&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
&quot;status&quot;: &quot;job-execution-state&quot;,
&quot;statusDetails&quot;: { 
    &quot;string&quot;: &quot;string&quot;
    ...
},
&quot;expectedVersion&quot;: &quot;number&quot;,
&quot;executionNumber&quot;: long,
&quot;includeJobExecutionState&quot;: boolean,
&quot;includeJobDocument&quot;: boolean,
&quot;stepTimeoutInMinutes&quot;: long,
&quot;clientToken&quot;: &quot;string&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 269px;&quot;&gt;
&lt;p&gt;&amp;nbsp;$aws/things/{디바이스이름}/jobs/start-next&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 269px;&quot;&gt;
&lt;ul&gt;
&lt;li&gt;statusDetails :&amp;nbsp;작업 실행 상태를 설명하는 이름-값 페어의 모음입니다. 지정하지 않으면&amp;nbsp;statusDetails가 바뀌지 않습니다.&lt;/li&gt;
&lt;li&gt;stepTimeOutInMinutes :&amp;nbsp;이 디바이스가 이 작업 실행을 마쳐야 하는 시간을 지정합니다. 이 타이머가 완료하기 전에 또는 타이머가 재설정되면(UpdateJobExecution를 호출하고, 상태를&amp;nbsp;IN_PROGRESS에 설정하고, 새로운 제한 시간 값을 필드&amp;nbsp;stepTimeoutInMinutes에 지정하여) 작업 실행 상태는&amp;nbsp;TIMED_OUT로 설정됩니다. 이 제한 시간을 설정해도 작업이 생성될 때 지정했을 수도 있는 작업 실행 제한 시간에는 영향을 주지 않습니다(CreateJob&amp;nbsp;필드를 사용하는&amp;nbsp;timeoutConfig).&lt;/li&gt;
&lt;li&gt;clientToken :&amp;nbsp;&lt;/li&gt;
&lt;li&gt;메시지 브로커는 특정 구독 없이&amp;nbsp;$aws/things/{디바이스이름}/jobs/start-next/accepted&amp;nbsp;및&amp;nbsp;$aws/things/{디바이스이름}/jobs/start-next/rejected를 게시합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td style=&quot;width: 270px;&quot;&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{ 
&quot;statusDetails&quot;: {
    &quot;string&quot;: &quot;job-execution-state&quot;
    ...
},
&quot;stepTimeoutInMinutes&quot;: long,
&quot;clientToken&quot;: &quot;string&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;AWS IoT 에서 디바이스로 MQTT 통신 예제&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;구독할 토픽&lt;/td&gt;
&lt;td&gt;내용&lt;/td&gt;
&lt;td&gt;응답 payload example&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;$aws/things/{디바이스이름}/jobs/notify&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;br /&gt;대기 중인 사물의 작업 실행 목록에 작업이 추가되거나 제거되었을 때 혹은 목록의 첫 번째 작업 실행이 바뀌었을때 대상 디바이스에게 토픽으로 메시지 게시합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;timestamp&quot; : 10011,
  &quot;jobs&quot; : {
    &quot;IN_PROGRESS&quot; : [ {
      &quot;jobId&quot; : &quot;other-job&quot;,
      &quot;queuedAt&quot; : 10003,
      &quot;lastUpdatedAt&quot; : 10009,
      &quot;executionNumber&quot; : 1,
      &quot;versionNumber&quot; : 1
    } ],
    &quot;QUEUED&quot; : [ {
      &quot;jobId&quot; : &quot;this-job&quot;,
      &quot;queuedAt&quot; : 10011,
      &quot;lastUpdatedAt&quot; : 10011,
      &quot;executionNumber&quot; : 1,
      &quot;versionNumber&quot; : 0
    } ]
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;$aws/things/{디바이스이름}/jobs/notify-next&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;대기 중인 사물의 작업 실행 목록에 작업이 추가되거나 제거되었을 때 혹은 목록의 첫 번째 작업 실행이 바뀌었을때 대상 디바이스에게 토픽으로 메시지 게시합니다.&lt;/td&gt;
&lt;td&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;timestamp&quot; : 10011,
  &quot;execution&quot; : {
    &quot;jobId&quot; : &quot;other-job&quot;,
    &quot;status&quot; : &quot;IN_PROGRESS&quot;,
    &quot;queuedAt&quot; : 10009,
    &quot;lastUpdatedAt&quot; : 10009,
    &quot;versionNumber&quot; : 1,
    &quot;executionNumber&quot; : 1,
    &quot;jobDocument&quot; : {&quot;c&quot;:&quot;d&quot;}
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;$aws/things/{디바이스이름}/jobs/get/accepted&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&amp;nbsp;$aws/things/{디바이스이름}/jobs/get 토픽에 메시지를 게시하면 종료 상태가 아닌 사물의 모든 작업 목록을 가져옵니다.
&lt;ul&gt;
&lt;li&gt;inProgressJobs : IN_PROGRESS 상태인 jobs 목록입니다.&lt;/li&gt;
&lt;li&gt;queuedJobs : QUEUED 상태인 Jobs 목록입니다.&lt;/li&gt;
&lt;li&gt;clientToken : 요청과 응답의 연관성을 나타낼 때 사용하는 클라이언트 토큰입니다.&lt;/li&gt;
&lt;li&gt;timestamp : 메시지가 전송된 이후 경과 시간(초) 입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
&quot;inProgressJobs&quot; : [ JobExecutionSummary ... ], 
&quot;queuedJobs&quot; : [ JobExecutionSummary ... ],
&quot;timestamp&quot; : 1489096425069,
&quot;clientToken&quot; : &quot;client-001&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;$aws/things/{디바이스이름}/jobs/get/rejected&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&amp;nbsp;$aws/things/{디바이스이름}/jobs/get 토픽에 메시지를 게시하면 요청이 잘못된경우 error respone 으로 반환된다&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;code :
&lt;ul&gt;
&lt;li&gt;InvalidTopic : 요청이 API로 매핑되어 있지 않은 AWS IoT 작업 서비스 네임스페이스의 주제로 전송되었습니다.&lt;/li&gt;
&lt;li&gt;InvalidJson :&amp;nbsp;요청 내용이 유효한 UTF-8-인코딩 JSON으로 해석되지 않습니다.&lt;/li&gt;
&lt;li&gt;InvalidRequest :&amp;nbsp;요청 내용이 잘못되었습니다.&amp;nbsp;요청에 잘못된 상태 세부 정보가 포함되어 있으면 이 코드가 반환됩니다. 메시지에는 오류에 대한 세부 정보가 포함됩니다.&lt;/li&gt;
&lt;li&gt;InvalidStateTransition :&amp;nbsp;작업 실행의 현재 상태로 인해 작업 실행을 잘못된 상태로 변경하려는 업데이트 시도입니다. (ex: SUCCEEDED 에서 IN_PROGRESS로 변경하려는 시도) 이때는 오류 메시지 본문에 executionState 필드도 포함됩니다.&lt;/li&gt;
&lt;li&gt;ResourceNotFound : 요청 주제에서 지정한 JobExecution이 존재하지 않습니다.&lt;/li&gt;
&lt;li&gt;VersionMismatch :&amp;nbsp;요청에서 지정한 예상 버전이 AWS IoT 작업 서비스의 작업 실행 버전과 일치하지 않습니다. 이때는 오류 메시지 본문에&amp;nbsp;executionState&amp;nbsp;필드도 포함됩니다.&lt;/li&gt;
&lt;li&gt;InternalError : 요청을 처리하는 도중 내부 오류가 발생했습니다.&lt;/li&gt;
&lt;li&gt;RequestThrottled :&amp;nbsp;요청에 병목 현상이 발생했습니다.&lt;/li&gt;
&lt;li&gt;TerminalStateReached :&amp;nbsp;종료 상태의 작업에서 작업을 설명하는 명령을 실행했을 때 발생합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;message : 오류메시지 문자열입니다.&lt;/li&gt;
&lt;li&gt;clientToken :&amp;nbsp;요청과 응답의 연관성을 나타내는 임의 문자열입니다.&lt;/li&gt;
&lt;li&gt;timestamp : epoch 이후 경과 시간(초)입니다&lt;/li&gt;
&lt;li&gt;executionState :&amp;nbsp;이 필드는&amp;nbsp;code&amp;nbsp;필드에&amp;nbsp;InvalidStateTransition&amp;nbsp;또는&amp;nbsp;VersionMismatch&amp;nbsp;값이 있을 때만 포함됩니다. 따라서 이러한 경우에는 현재 작업 실행 상태에 대한 데이터를 가져오기 위해 별도의&amp;nbsp;DescribeJobExecution&amp;nbsp;요청을 수행할 필요가 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;code&quot;: &quot;ErrorCode&quot;,
    &quot;message&quot;: &quot;string&quot;,
    &quot;clientToken&quot;: &quot;string&quot;,
    &quot;timestamp&quot;: timestamp,
    &quot;executionState&quot;: JobExecutionState
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;$aws/things/{디바이스이름}/jobs/{jobId}/get/accepted&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;$aws/things/thingName/jobs/jobId/get 토픽에 메시지를 게시하면&lt;/span&gt;&amp;nbsp;반환되는 내용&lt;/li&gt;
&lt;li&gt;execution
&lt;ul&gt;
&lt;li&gt;jobId :&amp;nbsp;작업 생성 시 할당한 고유 식별자입니다.&lt;/li&gt;
&lt;li&gt;thingName : 작업을 실행 중인 사물의 이름입니다.&lt;/li&gt;
&lt;li&gt;jobDocument : 작업 문서의 내용입니다.&lt;/li&gt;
&lt;li&gt;status :&amp;nbsp;작업 실행의 상태입니다. 다음 중 하나일 수 있습니다. QUEUED, IN_PROGRESS, FAILED, SUCCEEDED, CANCELED, TIMED_OUT, REJECTED 또는 REMOVED.&lt;/li&gt;
&lt;li&gt;statusDetails : 작업 실행 상태를 설명하는 이름-값 페어의 모음입니다.&lt;/li&gt;
&lt;li&gt;queuedAt :&amp;nbsp;작업 실행이 대기 상태로 전환된 epoch 이후 경과 시간(초)입니다.&lt;/li&gt;
&lt;li&gt;startedAt :&amp;nbsp;작업 실행이 시작된 epoch 이후 경과 시간(초)입니다.&lt;/li&gt;
&lt;li&gt;lastUpdatedAt :&amp;nbsp;작업 실행이 마지막으로 업데이트된 epoch 이후 경과 시간(초)입니다.&lt;/li&gt;
&lt;li&gt;versionNumber :&amp;nbsp;작업 실행 버전입니다. 작업 실행 버전은 디바이스에서 업데이트될 때마다 일정하게 증가합니다.&lt;/li&gt;
&lt;li&gt;executionNumber :&amp;nbsp;디바이스에서 작업 실행을 식별하기 위한 숫자입니다. 나중에는 작업 실행 정보를 반환하거나 업데이트하는 명령에 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
&quot;execution&quot; : {
    &quot;jobId&quot; : &quot;string&quot;,
    &quot;thingName&quot; : &quot;string&quot;,
    &quot;jobDocument&quot; : &quot;string&quot;,
    &quot;status&quot;: &quot;QUEUED|IN_PROGRESS|FAILED|SUCCEEDED|CANCELED|TIMED_OUT|REJECTED|REMOVED&quot;,
    &quot;statusDetails&quot;: {
        &quot;string&quot;: &quot;string&quot;
    },
    &quot;queuedAt&quot; : &quot;timestamp&quot;,
    &quot;startedAt&quot; : &quot;timestamp&quot;,
    &quot;lastUpdatedAt&quot; : &quot;timestamp&quot;,
    &quot;versionNumber&quot; : &quot;number&quot;,
    &quot;executionNumber&quot;: long
},
&quot;timestamp&quot;: &quot;timestamp&quot;,
&quot;clientToken&quot;: &quot;string&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;$aws/things/{디바이스이름}/jobs/{jobId}/get/rejected&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;ul&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/{작업ID}/update 의 요청이 잘못된경우 error respone 으로 반환된다&lt;/li&gt;
&lt;li&gt;code :
&lt;ul&gt;
&lt;li&gt;InvalidTopic : 요청이 API로 매핑되어 있지 않은 AWS IoT 작업 서비스 네임스페이스의 주제로 전송되었습니다.&lt;/li&gt;
&lt;li&gt;InvalidJson :&amp;nbsp;요청 내용이 유효한 UTF-8-인코딩 JSON으로 해석되지 않습니다.&lt;/li&gt;
&lt;li&gt;InvalidRequest :&amp;nbsp;요청 내용이 잘못되었습니다.&amp;nbsp;요청에 잘못된 상태 세부 정보가 포함되어 있으면 이 코드가 반환됩니다. 메시지에는 오류에 대한 세부 정보가 포함됩니다.&lt;/li&gt;
&lt;li&gt;InvalidStateTransition :&amp;nbsp;작업 실행의 현재 상태로 인해 작업 실행을 잘못된 상태로 변경하려는 업데이트 시도입니다. (ex: SUCCEEDED 에서 IN_PROGRESS로 변경하려는 시도) 이때는 오류 메시지 본문에 executionState 필드도 포함됩니다.&lt;/li&gt;
&lt;li&gt;ResourceNotFound : 요청 주제에서 지정한 JobExecution이 존재하지 않습니다.&lt;/li&gt;
&lt;li&gt;VersionMismatch :&amp;nbsp;요청에서 지정한 예상 버전이 AWS IoT 작업 서비스의 작업 실행 버전과 일치하지 않습니다. 이때는 오류 메시지 본문에&amp;nbsp;executionState&amp;nbsp;필드도 포함됩니다.&lt;/li&gt;
&lt;li&gt;InternalError : 요청을 처리하는 도중 내부 오류가 발생했습니다.&lt;/li&gt;
&lt;li&gt;RequestThrottled :&amp;nbsp;요청에 병목 현상이 발생했습니다.&lt;/li&gt;
&lt;li&gt;TerminalStateReached :&amp;nbsp;종료 상태의 작업에서 작업을 설명하는 명령을 실행했을 때 발생합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;message : 오류메시지 문자열입니다.&lt;/li&gt;
&lt;li&gt;clientToken :&amp;nbsp;요청과 응답의 연관성을 나타내는 임의 문자열입니다.&lt;/li&gt;
&lt;li&gt;timestamp : epoch 이후 경과 시간(초)입니다&lt;/li&gt;
&lt;li&gt;executionState :&amp;nbsp;이 필드는&amp;nbsp;code&amp;nbsp;필드에&amp;nbsp;InvalidStateTransition&amp;nbsp;또는&amp;nbsp;VersionMismatch&amp;nbsp;값이 있을 때만 포함됩니다. 따라서 이러한 경우에는 현재 작업 실행 상태에 대한 데이터를 가져오기 위해 별도의&amp;nbsp;DescribeJobExecution&amp;nbsp;요청을 수행할 필요가 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;code&quot;: &quot;ErrorCode&quot;,
    &quot;message&quot;: &quot;string&quot;,
    &quot;clientToken&quot;: &quot;string&quot;,
    &quot;timestamp&quot;: timestamp,
    &quot;executionState&quot;: JobExecutionState
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&amp;nbsp;$aws/things/thingName/jobs/start-next/accepted&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;ul&gt;
&lt;li&gt;execution
&lt;ul&gt;
&lt;li&gt;jobId :&amp;nbsp;작업 생성 시 할당한 고유 식별자입니다.&lt;/li&gt;
&lt;li&gt;thingName : 작업을 실행 중인 사물의 이름입니다.&lt;/li&gt;
&lt;li&gt;jobDocument : 작업 문서의 내용입니다.&lt;/li&gt;
&lt;li&gt;status :&amp;nbsp;작업 실행의 상태입니다. 다음 중 하나일 수 있습니다. QUEUED, IN_PROGRESS, FAILED, SUCCEEDED, CANCELED, TIMED_OUT, REJECTED 또는 REMOVED.&lt;/li&gt;
&lt;li&gt;statusDetails : 작업 실행 상태를 설명하는 이름-값 페어의 모음입니다.&lt;/li&gt;
&lt;li&gt;queuedAt :&amp;nbsp;작업 실행이 대기 상태로 전환된 epoch 이후 경과 시간(초)입니다.&lt;/li&gt;
&lt;li&gt;startedAt :&amp;nbsp;작업 실행이 시작된 epoch 이후 경과 시간(초)입니다.&lt;/li&gt;
&lt;li&gt;lastUpdatedAt :&amp;nbsp;작업 실행이 마지막으로 업데이트된 epoch 이후 경과 시간(초)입니다.&lt;/li&gt;
&lt;li&gt;versionNumber :&amp;nbsp;작업 실행 버전입니다. 작업 실행 버전은 디바이스에서 업데이트될 때마다 일정하게 증가합니다.&lt;/li&gt;
&lt;li&gt;executionNumber :&amp;nbsp;디바이스에서 작업 실행을 식별하기 위한 숫자입니다. 나중에는 작업 실행 정보를 반환하거나 업데이트하는 명령에 사용할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
&quot;execution&quot; : {
    &quot;jobId&quot; : &quot;022&quot;,
    &quot;thingName&quot; : &quot;MyThing&quot;,
    &quot;jobDocument&quot; : &quot;&amp;lt; contents of job document &amp;gt;&quot;,
    &quot;status&quot; : &quot;IN_PROGRESS&quot;,
    &quot;queuedAt&quot; : 1489096123309,
    &quot;lastUpdatedAt&quot; : 1489096123309,
    &quot;versionNumber&quot; : 1,
    &quot;executionNumber&quot; : 1234567890
},
&quot;clientToken&quot; : &quot;client-1&quot;,
&quot;timestamp&quot; : 1489088524284,
}&lt;/code&gt;&lt;/pre&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;$aws/things/thingName/jobs/start-next/rejected&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;ul&gt;
&lt;li&gt;$aws/things/{디바이스이름}/jobs/start-next&amp;nbsp;의 요청이 잘못된경우 error respone 으로 반환된다&lt;/li&gt;
&lt;li&gt;code :
&lt;ul&gt;
&lt;li&gt;InvalidTopic : 요청이 API로 매핑되어 있지 않은 AWS IoT 작업 서비스 네임스페이스의 주제로 전송되었습니다.&lt;/li&gt;
&lt;li&gt;InvalidJson :&amp;nbsp;요청 내용이 유효한 UTF-8-인코딩 JSON으로 해석되지 않습니다.&lt;/li&gt;
&lt;li&gt;InvalidRequest :&amp;nbsp;요청 내용이 잘못되었습니다.&amp;nbsp;요청에 잘못된 상태 세부 정보가 포함되어 있으면 이 코드가 반환됩니다. 메시지에는 오류에 대한 세부 정보가 포함됩니다.&lt;/li&gt;
&lt;li&gt;InvalidStateTransition :&amp;nbsp;작업 실행의 현재 상태로 인해 작업 실행을 잘못된 상태로 변경하려는 업데이트 시도입니다. (ex: SUCCEEDED 에서 IN_PROGRESS로 변경하려는 시도) 이때는 오류 메시지 본문에 executionState 필드도 포함됩니다.&lt;/li&gt;
&lt;li&gt;ResourceNotFound : 요청 주제에서 지정한 JobExecution이 존재하지 않습니다.&lt;/li&gt;
&lt;li&gt;VersionMismatch :&amp;nbsp;요청에서 지정한 예상 버전이 AWS IoT 작업 서비스의 작업 실행 버전과 일치하지 않습니다. 이때는 오류 메시지 본문에&amp;nbsp;executionState&amp;nbsp;필드도 포함됩니다.&lt;/li&gt;
&lt;li&gt;InternalError : 요청을 처리하는 도중 내부 오류가 발생했습니다.&lt;/li&gt;
&lt;li&gt;RequestThrottled :&amp;nbsp;요청에 병목 현상이 발생했습니다.&lt;/li&gt;
&lt;li&gt;TerminalStateReached :&amp;nbsp;종료 상태의 작업에서 작업을 설명하는 명령을 실행했을 때 발생합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;message : 오류메시지 문자열입니다.&lt;/li&gt;
&lt;li&gt;clientToken :&amp;nbsp;요청과 응답의 연관성을 나타내는 임의 문자열입니다.&lt;/li&gt;
&lt;li&gt;timestamp : epoch 이후 경과 시간(초)입니다&lt;/li&gt;
&lt;li&gt;executionState :&amp;nbsp;이 필드는&amp;nbsp;code&amp;nbsp;필드에&amp;nbsp;InvalidStateTransition&amp;nbsp;또는&amp;nbsp;VersionMismatch&amp;nbsp;값이 있을 때만 포함됩니다. 따라서 이러한 경우에는 현재 작업 실행 상태에 대한 데이터를 가져오기 위해 별도의&amp;nbsp;DescribeJobExecution&amp;nbsp;요청을 수행할 필요가 없습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;pre id=&quot;code_1611732800234&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
    &quot;code&quot;: &quot;ErrorCode&quot;,
    &quot;message&quot;: &quot;string&quot;,
    &quot;clientToken&quot;: &quot;string&quot;,
    &quot;timestamp&quot;: timestamp,
    &quot;executionState&quot;: JobExecutionState
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;4. 작업 생성&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;3번 디바이스의 작업을 할 준비가 되어 있어야한다.&lt;/li&gt;
&lt;li&gt;Custom Job
&lt;ul&gt;
&lt;li&gt;AWS 코어에서는 작업파일을 추가하기 위해서는 S3에 별도로 업로드 후 그 파일을 선택해야함.&lt;/li&gt;
&lt;li&gt;작업 문서 : 디바이스가 수행할 원격 작업을 정의한 JSON 문서.
&lt;ul&gt;
&lt;li&gt;작업을 생성하려면 반드시 작업 문서가 있어야 함.&lt;/li&gt;
&lt;li&gt;작업 문서는 S3 버킷에 저장되거나, 작업 생성 요청시 인라인으로 포함될 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Document&amp;nbsp;
&lt;ul&gt;
&lt;li&gt;작업 생성시 인라인으로 들어갈때 사용하는 Param&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Document Source&amp;nbsp;
&lt;ul&gt;
&lt;li&gt;작업 생성시 S3 버킷에 저장되어있는 작업문서 위치&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pre-signed URL : 디바이스가 작업 문서 자체에 포함된 데이터(URL)에 한시적으로 접근할 수 있도록 사용할 수 있는 기능.
&lt;ul&gt;
&lt;li&gt;보안 향상을 위해 사용할 수 있는 선택적 기능.&lt;/li&gt;
&lt;li&gt;대상 데이터(펌웨어 등)는 반드시 S3에 저장된 후 자리 표시자 링크를 작업 문서에 추가하여 사용
&lt;ul&gt;
&lt;li&gt;이는 Pre-signed URL이 S3의 기능이기 때문.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;작업문서의 예약어 aws:iot:s3-presigned-url 이 있는경우 동작.&lt;br /&gt;ex)&amp;nbsp;
&lt;p&gt;${aws:iot:s3-presigned-url:&lt;a href=&quot;https://s3.amazonaws.com/bucket/key&quot;&gt;https://s3.amazonaws.com/bucket/key&lt;/a&gt;}&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Code Signing : 작업 문서에 반드시 Code-sign용 자리 표시자가 포함되어 있어야 한다.
&lt;ul&gt;
&lt;li&gt;Signing을 위해선 Signing Profile이 생성되어야 한다.
&lt;ul&gt;
&lt;li&gt;Signing Profile을 생성하려면 ACM에 signing용 Certificate가 import 되어 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;작업문서의 예약어 aws:iot:code-sign-signature 가 있는경우 동작&lt;br /&gt;ex )
&lt;p&gt;${aws:iot:code-sign-signature:s3://&amp;lt;region&amp;gt;.&amp;lt;my-s3-bucket&amp;gt;/&amp;lt;my-code-file&amp;gt;@&amp;lt;code-file-version-id&amp;gt;}&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech</category>
      <category>AWS</category>
      <category>iot</category>
      <category>Job</category>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/43</guid>
      <comments>https://eyeeshot.tistory.com/43#entry43comment</comments>
      <pubDate>Wed, 27 Jan 2021 16:54:27 +0900</pubDate>
    </item>
    <item>
      <title>Python Docker 이미지 생성 주의점!</title>
      <link>https://eyeeshot.tistory.com/42</link>
      <description>&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Alpine을 사용하면 Python Docker 빌드 속도가 50 배 더 느려질 수 있습니다.&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;한줄 정리 하면.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;단순히 ubuntu 와 alpine 을 비교했을떄는 alpine이 빌드속도나 이미지 용량이 적지만.&lt;/p&gt;
&lt;p&gt;python aplication 을 위한 package 등을 설치할때는 빌드속도나 이미지 용량이 올라간다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;요약 하자면 파이썬 라이브러리들은 보통&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Wheel&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;포맷을 사용하는 데 Alpine 리눅스는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Wheel&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;포맷을 지원하지 않기 때문에 소스 코드를 내려받아 직접 컴파일해야할 경우가 있기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Base &lt;span style=&quot;color: #333333;&quot;&gt;image&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Time &lt;span style=&quot;color: #333333;&quot;&gt;to build&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Image &lt;/span&gt;size&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Research &lt;span style=&quot;color: #333333;&quot;&gt;required&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;python:3.8-slim&lt;/td&gt;
&lt;td&gt;30 seconds&lt;/td&gt;
&lt;td&gt;363MB&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;python:3.8-alpine&lt;/td&gt;
&lt;td&gt;1557 seconds&lt;/td&gt;
&lt;td&gt;851MB&lt;/td&gt;
&lt;td&gt;Yes&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;
&lt;p&gt;자세한 사항은 아래 링크를 참고 하면 될것같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;출처 :&amp;nbsp;&lt;a href=&quot;https://pythonspeed.com/articles/alpine-docker-python/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;pythonspeed.com/articles/alpine-docker-python/&lt;/a&gt;&lt;/p&gt;</description>
      <category>Tech</category>
      <category>alpine</category>
      <category>docker</category>
      <category>python</category>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/42</guid>
      <comments>https://eyeeshot.tistory.com/42#entry42comment</comments>
      <pubDate>Tue, 26 Jan 2021 11:40:58 +0900</pubDate>
    </item>
    <item>
      <title>Docker 환경변수 설정</title>
      <link>https://eyeeshot.tistory.com/40</link>
      <description>&lt;p&gt;Docker 환경변수 설정하는방법은 아래와 같이 두가지이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1. Param 설정으로 적용하는 방법&lt;/p&gt;
&lt;pre id=&quot;code_1610959325079&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run -e &quot;ENV=foo&quot; ubuntu /bin/bash&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2. env 파일을 만들어 적용하는 방법&lt;/p&gt;
&lt;pre id=&quot;code_1610959356855&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;docker run --env-file ./.env ubuntu /bin/bash&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;.env&lt;/p&gt;
&lt;pre id=&quot;code_1610959394224&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 주석!
HOST=1.1.1.1
PATH=/home/eyeeshot&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;만약 둘다 설정할경우는 --env-file 다음 -e / --env 처리가 됨.&lt;/p&gt;
&lt;p&gt;따라서 --env-file 로 적용한 변수를 또 적용할경우 -e 적용한것으로 적용하게됨.&lt;/p&gt;</description>
      <category>Tech</category>
      <category>docker</category>
      <category>env</category>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/40</guid>
      <comments>https://eyeeshot.tistory.com/40#entry40comment</comments>
      <pubDate>Mon, 18 Jan 2021 17:44:51 +0900</pubDate>
    </item>
    <item>
      <title>ssh 파일전송 scp</title>
      <link>https://eyeeshot.tistory.com/39</link>
      <description>&lt;p&gt;ssh로 파일을 전송할수 있다.&lt;/p&gt;
&lt;p&gt;아래와 같은 방법을 사용하면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1610956791811&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;scp {전송할 파일} {id@server IP}:{저장될 경로}
ex) scp ./a.txt eyeeshot@123.123.123.123:/home/file

#포트를 사용할경우
 -p {ssh포트번호} 옵션을 추가
ex) scp -p 1414 ./a.txt eyeeshot@123.123.123.123:/home/file&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Tech</category>
      <category>scp</category>
      <category>SSH</category>
      <category>파일전송</category>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/39</guid>
      <comments>https://eyeeshot.tistory.com/39#entry39comment</comments>
      <pubDate>Mon, 18 Jan 2021 17:00:11 +0900</pubDate>
    </item>
    <item>
      <title>Git remote url change</title>
      <link>https://eyeeshot.tistory.com/38</link>
      <description>&lt;pre id=&quot;code_1610956067433&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;#현재 remote url 확인
git remote -v

#change remote url
git remote set-url origin https://github.com/~~~~~~

#바뀐지 다시 확인
git remote -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Tech</category>
      <category>change</category>
      <category>GIT</category>
      <category>remote</category>
      <author>eyeeshot</author>
      <guid isPermaLink="true">https://eyeeshot.tistory.com/38</guid>
      <comments>https://eyeeshot.tistory.com/38#entry38comment</comments>
      <pubDate>Mon, 18 Jan 2021 16:49:13 +0900</pubDate>
    </item>
  </channel>
</rss>