<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>사막여유</title>
    <link>https://opencv-master.tistory.com/</link>
    <description>개발자 및 투자자의 일상 공유 블로그입니다.</description>
    <language>ko</language>
    <pubDate>Sun, 12 Apr 2026 11:18:16 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>사막여유</managingEditor>
    <image>
      <title>사막여유</title>
      <url>https://tistory1.daumcdn.net/tistory/5338409/attach/e8c4d96891684c8a9a9ff0b93664f81c</url>
      <link>https://opencv-master.tistory.com</link>
    </image>
    <item>
      <title>Program/딥러닝ObjectDetection - TensorRT</title>
      <link>https://opencv-master.tistory.com/199</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;Tensor RT&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NVIDIA에서 만든 프레임워크&lt;/li&gt;
&lt;li&gt;NVIDIA GPU 최적화 기술&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Advantages of Tensor RT&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;C++과 Pyhton을 API레벨에서 지원하므로 CUDA를 잘 모르는 DeepLearning 개발자들도&amp;nbsp;&lt;br /&gt;쉽게 사용할 수 있따.&lt;/li&gt;
&lt;li&gt;Lantency, ThroughPut을 쉽게 향상&lt;/li&gt;
&lt;li&gt;다양한 Layer 및 연산에 대해 Customization할 수 있는 방법론을 제공&lt;/li&gt;
&lt;li&gt;Latency (시간단위)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;작업을 처리하는데 걸리는 시간&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Throughput (일단위)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단위시간(초)당 처리하는 작업의 수&lt;/li&gt;
&lt;li&gt;일초당 몇장의 이미지를 처리할 수 있는지&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Work Flow&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DNd5L/btsOE4ymBTg/yoK7199f5L1yhYoXKwfaj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DNd5L/btsOE4ymBTg/yoK7199f5L1yhYoXKwfaj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DNd5L/btsOE4ymBTg/yoK7199f5L1yhYoXKwfaj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDNd5L%2FbtsOE4ymBTg%2FyoK7199f5L1yhYoXKwfaj0%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;975&quot; height=&quot;275&quot; data-origin-width=&quot;975&quot; data-origin-height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Optimizer
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NVIDIA GPU연산에 적합한 최적화 기법들을 사용해 훈련된 딥러닝 모델을 최적화 하는 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Engine
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배포할 NVIDIA GPU에 따라 최적의 연산을 수행할 수 있도록 도와주는 역할&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;딥러닝 가속화 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cxDaVS/btsOENRaxec/ES9zdRPONeVUA7q8DTOKM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cxDaVS/btsOENRaxec/ES9zdRPONeVUA7q8DTOKM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cxDaVS/btsOENRaxec/ES9zdRPONeVUA7q8DTOKM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcxDaVS%2FbtsOENRaxec%2FES9zdRPONeVUA7q8DTOKM0%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;822&quot; height=&quot;427&quot; data-origin-width=&quot;822&quot; data-origin-height=&quot;427&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;위 5가지의 방법으로 딥러닝의 경량화 및 가속화가 가능하다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Quantization &amp;amp; Precision Calibration&lt;/li&gt;
&lt;li&gt;Graph Optimization&lt;/li&gt;
&lt;li&gt;Kernel Auto-Tuning&lt;/li&gt;
&lt;li&gt;Dynamic Tensor Memonry&lt;/li&gt;
&lt;li&gt;Multi-Stream Execution&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;ONNX ( Open Neural Network Exchange )&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpLwSV/btsOD22p1DH/0pZSCaMyoEdDFqzIQlrpe1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpLwSV/btsOD22p1DH/0pZSCaMyoEdDFqzIQlrpe1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpLwSV/btsOD22p1DH/0pZSCaMyoEdDFqzIQlrpe1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpLwSV%2FbtsOD22p1DH%2F0pZSCaMyoEdDFqzIQlrpe1%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;948&quot; height=&quot;438&quot; data-origin-width=&quot;948&quot; data-origin-height=&quot;438&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ONNX는 인공지능 모델을 표준형식으로 표현하고, 서로다른 딥러닝 프레임워크간에&amp;nbsp;&lt;br /&gt;모델의 변환 및 공유를 지원&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Program/딥러닝</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/199</guid>
      <comments>https://opencv-master.tistory.com/199#entry199comment</comments>
      <pubDate>Tue, 17 Jun 2025 08:33:49 +0900</pubDate>
    </item>
    <item>
      <title>ObjectDetection - NMS</title>
      <link>https://opencv-master.tistory.com/198</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;NMS ( Non - Maximum Suppression )&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;최종 박스 하나를 찾는 것&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;동작순서&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;검출된 Bounding Box 중, Confidence_threshold보다 작으면 제거&lt;/li&gt;
&lt;li&gt;Confidence Score를 기준으로 내림차순 정렬&lt;/li&gt;
&lt;li&gt;모든 박스 순차적으로 실행&lt;br /&gt;가장 높은 Confidence Score의 Bounding Box와 동일한 Class면서&amp;nbsp;&lt;br /&gt;iou_threshold이상인 Bounding Box는 제거&lt;/li&gt;
&lt;li&gt;남은 Bounding Box 선택&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;115&quot; data-origin-height=&quot;160&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ce7PCt/btsOv4MSrPe/HmZKGH9nFsEokNtChwz610/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ce7PCt/btsOv4MSrPe/HmZKGH9nFsEokNtChwz610/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ce7PCt/btsOv4MSrPe/HmZKGH9nFsEokNtChwz610/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fce7PCt%2FbtsOv4MSrPe%2FHmZKGH9nFsEokNtChwz610%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;115&quot; height=&quot;160&quot; data-origin-width=&quot;115&quot; data-origin-height=&quot;160&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와같이 class1(새)과 겹치는 부분이 많은데 같은 클래스라면 삭제한다.&lt;br /&gt;즉, 가장 확률이 높은 박스 하나만 남기고 제거한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #090909; text-align: start;&quot;&gt;threshold가 너무 낮으면 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #090909; text-align: start;&quot;&gt;조금만 겹쳐도 같은 클래스에 비슷한 위치라고 판단되어 박스가 모두 삭제되며 검출이 누락될 수 있고 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #090909; text-align: start;&quot;&gt;너무 높으면 중복 박스가 많이 남아 결과가 지저분해질 수 있기 때문에 적절한 Iou_threshold값이 중요하다. &lt;/span&gt;&lt;/p&gt;</description>
      <category>Program/딥러닝</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/198</guid>
      <comments>https://opencv-master.tistory.com/198#entry198comment</comments>
      <pubDate>Wed, 11 Jun 2025 08:13:59 +0900</pubDate>
    </item>
    <item>
      <title>Object Detection 알고리즘 정의 및 종류와 성능지표</title>
      <link>https://opencv-master.tistory.com/197</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;Object Detection&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지내의 모든 object에 대해 classification과 Localization을 수행&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;활용&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도로 cctv, 제품의 공정불량, 백화점 cctv&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;종류&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.원스테이지&lt;br /&gt;&amp;nbsp;- 백본에서 한번에 물체의 위치와 종류를 분류&lt;br /&gt;&amp;nbsp;- YOLO, SSD..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 투스테이지&lt;br /&gt;&amp;nbsp;- 백본에서 물체의 위치를 판단하고 무엇인지 분류&lt;br /&gt;&amp;nbsp;- RCNN, FastRCNN, RFCN, MaskRCNN..&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;주요 용어 정리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Bounding Box&lt;br /&gt;&amp;nbsp;- 이미지내에서 물체 전체를 가득차게 그린 가장 작은 직사각형을 의미&lt;br /&gt;2. Confidence Score&lt;br /&gt;&amp;nbsp;- 이미지 내에서 찾은 Bounding Box안에 물체가 있을 확률&lt;br /&gt;3. Sliding Window&lt;br /&gt;&amp;nbsp;- 이미지 내에서 적당한 영역을 정하여, 영역을 이동시키면서 알고리즘을 적용하는 방식&lt;br /&gt;4. Anchor Box&lt;br /&gt;&amp;nbsp;- 특정 사이즈나 비율로 미리 정의된 Box&lt;br /&gt;5. NMS&lt;br /&gt;&amp;nbsp;- 검출된 Bounding Box 중에서, 비슷한 위치에 있거나 Object일 확률이 낮은 Box들을 제거하고, 가장 적합한 Box를 찾는 것&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;Confusion Matrix&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;288&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bSITir/btsOttfPhvO/UAPOINGnn6ocj2U2k7ZKUk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bSITir/btsOttfPhvO/UAPOINGnn6ocj2U2k7ZKUk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bSITir/btsOttfPhvO/UAPOINGnn6ocj2U2k7ZKUk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbSITir%2FbtsOttfPhvO%2FUAPOINGnn6ocj2U2k7ZKUk%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;890&quot; height=&quot;288&quot; data-origin-width=&quot;890&quot; data-origin-height=&quot;288&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;True : 맞았다&lt;br /&gt;False : 틀렸다&lt;br /&gt;Positive : 맞았다고 예측했다&lt;br /&gt;Negative : 틀렸다고 예측했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Accuracy : 맞는 부분을 맞다고 정확하게 맞춘 확률&lt;br /&gt;Recall : 재현율&lt;/p&gt;</description>
      <category>Program/딥러닝</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/197</guid>
      <comments>https://opencv-master.tistory.com/197#entry197comment</comments>
      <pubDate>Tue, 10 Jun 2025 08:26:45 +0900</pubDate>
    </item>
    <item>
      <title>PRINCIPLES(원칙)</title>
      <link>https://opencv-master.tistory.com/196</link>
      <description>&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;PRINCIPLES (원칙)&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t7ShY/btsOtf1yttq/0k7Zx08NdEcSLKuOM6x8L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t7ShY/btsOtf1yttq/0k7Zx08NdEcSLKuOM6x8L1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t7ShY/btsOtf1yttq/0k7Zx08NdEcSLKuOM6x8L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft7ShY%2FbtsOtf1yttq%2F0k7Zx08NdEcSLKuOM6x8L1%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;461&quot; height=&quot;166&quot; data-origin-width=&quot;461&quot; data-origin-height=&quot;166&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;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;b&gt;계기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Priciple 원칙이라는 책은 사실 예전에 알게되었던 책이었다.&lt;br /&gt;한창 투자를 공부할 때 알게된 '레이 달리오'가 쓴 책이라는 것만 알고있었고 어떤 내용이고 왜 이 책을 썼는지는 알지 못했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세히는 기억이 안나지만 최근 유튜브에서 '원칙'이라는 책이 알고리즘으로 뜨게됐고&lt;br /&gt;그때도 단순히 레이 달리오라는 유명한 투자자가 쓴 책이고 책제목 그대로 '원칙'에 입각해 무언가를 하는데 도움이&lt;br /&gt;될 수 있겠구나 라는 생각으로 구매한 책이기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1년전 친구를 도와주면서 시작하게 된 사업이 어느덧 개발이 완료가 되었고&amp;nbsp;&lt;br /&gt;이제는 그 분야에서 파생된 다른 분야에 대한 사업을 시작하게 되었는데&amp;nbsp;&lt;br /&gt;개발을 할 때나 문화, 방향에 대한 결정을 할 때 어떤 기준으로 어떻게 결정하는 것이 가장&lt;br /&gt;효율적일까 라는 생각을 하던 중 뜬 알고리즘이라서 큰 흥미를 느끼고 구매했던 것 같다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;느낀점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 한번 필요한 부분만 읽고 제대로 이해되지 않는 부분을 이해하고싶어서&lt;br /&gt;제 2부 '인생의 원칙'부터 다시 읽기 시작하고 2시간동안 '카페꼼마'에서 읽은 내용과 그에대한 나의 생각을 정리해본다.&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;1. 배움&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'실패를 긴 관점에서 보면 나는 실패를 극복할 것이고, 대부분의 배움이 실패의 원인에 대해 곰곰이 생각해 보는 것에서 나온다는 것을 알고있다.'&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 사실 실패에 대해서 굉장히 긍정적으로 생각한다. 그리고 지금까지 실패한것은 없다고 생각하기도한다.&lt;br /&gt;지금 진행하고 있는 프로젝트를 생각해보면 어떤 아이디어가 생각이 나서 시도를 했지만 그 아이디어가 프로젝트의 문제점을 해결하지 못한 경우가 대부분이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 당연하게도 인디언 기우제처럼 문제가 해결될 때 까지 다양한 시도를 해봐야하는데 그 전까지는 문제점을 해결하지 못할수밖에 없기 때문이다.&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;u&gt;&lt;b&gt;중간에 포기를 하기 전까지는 실패는 실패가 아닌 과정일 뿐이고 이 과정을 복기해보며 어떤 부분들이 잘못되었는지 생각하고 다른 방법을 시도해 보는 것 자체가 배움 ( Learning ) 이라고 보는 관점은 나와 관점을 같이한다.&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2. 극단적 투명함&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이 책에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;'극단적 투명함', '극단적 개방', '극단적 진실' 과 같은 단어를 많이 언급하는데 그 중 하나의 키워드이다.&lt;br /&gt;처음 책을 읽었을 때에는 극단적 투명함은 단순히 &lt;u&gt;&lt;b&gt;'무엇을 알고 무엇을 모르는지를 확실히 하여 비판이 있더라도 그것을 알리고자 하는 것'인줄 알았다.&lt;/b&gt;&lt;/u&gt;&lt;/p&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 우려되는 것은 요즘 세상에 내가 생각하는 것을 그대로 가감없이 전달하게 될 경우에 어떤 비판을 받게될지 모른다.&lt;br /&gt;요즘엔 인플루언서의 한마디에도 나락에가거나 그로인해 자살까지 가는 경우도 수없이 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 레이 달리오는 이러한 비판이 처음에는 무섭기 때문에 극단적 투명함을 실천하기 어렵지만 이 방식이 자신이 경험해보았을 때 가장 효율적이고 좋은 방법이었다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 생각해본다면 다른 관점으로 세상을 바라보는게 아닐까 싶다.&amp;nbsp;&lt;br /&gt;만약 내가 생각하는 것을 가감없이 말한다고 했을 때 받는 비판 자체를 수용하면서 이렇게 생각하지 않는 사람들이 있다는 것을 인식하는 계기로 생각할수도있지 않을까 라는 생각을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 잘못이해를 하고있는것인지 레이달리오가 말하고자하는 것은 다른 의미였는지 확인하고자 &quot;Gemini&quot;와 토론을 한 결과는 아래과 같다.&lt;/p&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;p data-sourcepos=&quot;3:1-3:24&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. '극단적 투명성'의 정의로 시작&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;5:1-8:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;5:1-5:42&quot;&gt;우리의 토론은 '극단적 투명성'이 무엇인지 정의하는 것에서 시작했습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;6:1-6:111&quot;&gt;이는 단순히 정보를 공개하는 것을 넘어, &lt;b&gt;조직의 공동 목표를 위해 개인의 감정이나 체면보다 '진실'을 우선시하여 거의 모든 생각과 비판을 공개적으로 공유하는 문화적 원칙&lt;/b&gt;이라고 정의했습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;7:1-8:0&quot;&gt;궁극적인 목표는 직급이나 개인의 자아(Ego)에 구애받지 않고 최고의 아이디어가 승리하는 **'아이디어 메리토크라시(Idea Meritocracy)'**를 구현하는 것임을 확인했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;9:1-9:29&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. '가감 없는 생각의 전달'로 이해의 심화&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;11:1-13:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;11:1-11:74&quot;&gt;사용자님께서는 책을 읽으며, 이 원칙의 핵심이 **'자신의 생각을 가감 없이 상대방에게 전달하는 것'**에 있음을 파악하셨습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;12:1-13:0&quot;&gt;이는 단순히 사실을 공유하는 차원을 넘어, 상대방에 대한 평가나 의견까지도 솔직하게 드러내어 조직 내 '숨겨진 불일치'나 오해를 제거하는 과정이라는 점에 동의했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;14:1-14:37&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 적용 범위에 대한 핵심적 발견: '닫힌 시스템'의 원칙&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;16:1-18:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;16:1-16:132&quot;&gt;사용자님께서는 이 원칙을 불특정 다수인 '대중'에게 적용할 경우 엄청난 비판에 직면할 것이라는 점을 지적하며, 이것이 &lt;b&gt;'공동의 목표를 가진 동료'라는 특정 집단 내에서만 유효한 것이 아닌가&lt;/b&gt; 하는 핵심적인 통찰을 제시하셨습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;17:1-18:0&quot;&gt;우리는 이 의견에 동의하며, 극단적 투명성은 **'공동의 목표', '상호 신뢰', '합의된 규칙'**이 존재하는 '닫힌 시스템(Closed System)'에서만 작동하는 원칙이라는 결론을 내렸습니다. 길거리에서의 무례한 참견과 수술실에서의 직설적 소통의 비유를 통해 이 차이를 명확히 했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-sourcepos=&quot;19:1-19:32&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. 개념의 확장: '방법론'에서 '철학적 태도'로&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;21:1-26:0&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;21:1-21:115&quot;&gt;마지막으로, 사용자님께서는 한 단계 더 나아가 새로운 관점을 제시했습니다. 대중의 비판을 '결론 도출'이 아닌, **'나와 다른 생각이 존재함을 인식하는 계기'**로 삼을 수도 있지 않냐는 것이었습니다.&lt;/li&gt;
&lt;li data-sourcepos=&quot;22:1-24:86&quot;&gt;이에 대해 우리는 레이 달리오의 '방법론'과 사용자님의 '철학적 관점'을 구분했습니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-sourcepos=&quot;23:5-24:86&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-sourcepos=&quot;23:5-23:76&quot;&gt;&lt;b&gt;달리오의 방법:&lt;/b&gt; 조직 내에서 '최선의 결론'이라는 **의견 수렴(Convergence)**을 목표로 하는 전투적 도구.&lt;/li&gt;
&lt;li data-sourcepos=&quot;24:5-24:86&quot;&gt;&lt;b&gt;사용자님의 관점:&lt;/b&gt; 개인이 세상의 **다양성을 이해(Divergence Recognition)**하고 지적으로 성숙하기 위한 철학적 태도.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-sourcepos=&quot;25:1-26:0&quot;&gt;결론적으로, 사용자님의 관점은 달리오가 직접 설계한 방법은 아닐지라도, '자신이 틀릴 수 있음을 인정하고 현실을 있는 그대로 파악하라'는 그의 근본 철학과 깊이 맞닿아 있다는 점을 확인하며 토론을 마무리했습니다.&lt;/li&gt;
&lt;/ul&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;2번에 대한 결론은 내가 생각한 방식도 근본적인 철학과는 그 뜻을 같이하지만 레이달리오가 말한 부분과는 약간의 차이가 존재한다는 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&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;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. 자연의 진화&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이 부분을 처음 읽을 때에는 별생각없이 읽고 넘어갔었지만 다시 정독해보니 참 통찰력이 있는 저자의 생각이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;&quot;자연은 개인이 아니라 전체를 위해 최적화되어 있다.&quot;&lt;br /&gt;&quot;&lt;/b&gt;&lt;/u&gt;인간은 다른 동물들과 비교해 아주 영리하지만, 전체 자연과 비교하면 바위에서 자라는 이끼 정도의 지능을 가지고있을 뿐이다. 우리는 우주에 있는 사물들과 생물들은 말할 필요도 없고, 모기 한 마리도 만들어낼 능력이 없다. &lt;b&gt;&lt;/b&gt;&lt;u&gt;&lt;b&gt;그래서 자연이 나보다 더 똑똑하다는 전제를 받아들이고, 자연을 통해 현실의 작용 법칙을 배우려고 한다.&quot;&lt;br /&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 내용을 정리하면 &lt;u&gt;&lt;b&gt;&quot;자연은 개인이 아닌 모두(전체)를 위하는 것으로 최적화 되어있으니 우리는 개인이 아닌 전체를 위해 생각해야 한다.&quot;&lt;/b&gt;&lt;/u&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;만약 자연이 개인에게 최적화 되어있다면 공동체라는 것은 만들어지지 못했을것이고 인류라는 문명자체도 만들어질 수 없었을 것이다. 또한 지구 자체가 모두, 전체에 대한 조화를 이루어가며 살아갈 수 있도록 구성되어있기 때문에 전체로 최적화되어있다는 말은 당연한 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3. 완벽함&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;진화의 관점에서 보면 완벽함이라는 것은 존재하지 않는다는 것을 알 수 있다. 완벽함은 지속되는 적응의 과정을 촉진시키는 것이 목표이다,&lt;br /&gt;우리가 실수를 숨기고 완벽한 척하는 것보다 불완전함을 발견하고 대응하는 것이 더 합리적이다. 당신은 실수로부터 매우 귀중한 교훈을 배우고, 계속해서 발전해 성공을 위한 만반의 준비를 갖추게 될 것이다&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;&lt;u&gt;&lt;b&gt;&quot;세상에 완벽함은 없다. 그런데 '완벽함'이라는 단어는 왜 존재하는가? 위 내용에 답이 있다. 완벽함은 그 단어의 의미 자체를 위해 존재하는 것이 아닌 지속되는 적응의 과정을 촉진시키기 위해 존재하는 단어이다&quot;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;4. No Pain, No Gain&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 목표를 달성해도 그 행복이 오래가지 않는다는 것을 알기 때문에&amp;nbsp;&lt;u&gt;&lt;b&gt;목표를 목표하는 것이 아닌 목표를 향하는 그 과정 자체에서의 사소한 행복을 추구하는 것을 목표로해야&quot;&lt;/b&gt;&lt;/u&gt;더 오래 갈 수 있을 것 같다는 생각을 한다.&lt;/p&gt;</description>
      <category>독서</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/196</guid>
      <comments>https://opencv-master.tistory.com/196#entry196comment</comments>
      <pubDate>Sat, 7 Jun 2025 21:01:38 +0900</pubDate>
    </item>
    <item>
      <title>주니어 개발자와의 협업에 대한 생각</title>
      <link>https://opencv-master.tistory.com/195</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5Bi1C/btsLOER216Q/CxPkK23slX4JtKNSk7fiiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5Bi1C/btsLOER216Q/CxPkK23slX4JtKNSk7fiiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5Bi1C/btsLOER216Q/CxPkK23slX4JtKNSk7fiiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5Bi1C%2FbtsLOER216Q%2FCxPkK23slX4JtKNSk7fiiK%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;489&quot; height=&quot;394&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;394&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;b&gt;어떻게하면 주니어 개발자를 효과적으로 매니징하면서 프로젝트의 품질과 팀의 생산성을 높일 수 있을까?&lt;/b&gt;를 고민하며&lt;br /&gt;작성한 글로 다른 분들께도 도움이 되었으면 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 관리직이 직면한 현실적 고민&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 Vision과 Motor 구조 설계에 4~5년 경험이 있는 개발자였습니다. 그런데 올해 사업을 준비하면서 제 주요 업무는 &lt;b&gt;투자 유치&lt;/b&gt;와 관련된 비개발 업무로 이동했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 개발의 주요 부분을 &lt;b&gt;2년차 주니어 개발자&lt;/b&gt;에게 위임해야 하는 상황에 놓였고, 곧 몇 가지 현실적인 문제에 직면하게 되었습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;주요 문제:&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;주니어 개발자가 &lt;b&gt;구상된 기능&lt;/b&gt;을 제대로 구현하기 어려운 경우가 발생함.&lt;/li&gt;
&lt;li&gt;필요한 기능만 구두로 전달하고 &quot;알아서 해봐&quot;라는 방식의 위임은 시간을 벌 수 있지만 &lt;br /&gt;오히려 혼란과 비효율을 초래할 수 있음.&lt;/li&gt;
&lt;li&gt;기술 부채와 코드 품질 문제로 시간이 지날수록 프로젝트의 방향성이 흐려짐&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 무분별한 위임의 부작용&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 내가 지금 너무 바빠서 개발에 신경을 쓸수 없기 때문에 일단 위임이 좋을거라고 생각할 수 있습니다.&lt;br /&gt;그런데 지금까지의 경험상 주니어 개발자에게 업무를 맡기게되었을 때 초기엔 책임감과 사명감에 수행하면서 성실히 보고서도 작성합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 &lt;b&gt;시간이 지날수록 아래와같은 문제들이 드러날 수 밖에 없었습니다.&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;기술 부채가 쌓인다&lt;/b&gt;: 유지보수와 확장이 어려운 코드가 늘어납니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로젝트의 방향성 흐려짐&lt;/b&gt;: 시스템 설계의 일관성이 무너지면서 프로젝트의 전반적인 품질 저하.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;저품질 코드 증가&lt;/b&gt;: 단순히 기능 구현에만 초점을 맞춘 코드가 프로젝트에 누적됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 결국 내가 모든걸 개발하고 몇가지 남은 부스러기 코드들만 주니어 개발자에게 맡겨야하는건가? 라는 생각이 들었지만 이 모든 문제는 다른 사업의 위임처럼 개발 프로세스를 체계적으로 만들어놓으면 해결할 수 있지않을까? 라는 생각으로 전환할 수 있었습니다.&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/X0CYr/btsLPN8fMD3/scNwnfSYcfHzAlUdXY3DQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/X0CYr/btsLPN8fMD3/scNwnfSYcfHzAlUdXY3DQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/X0CYr/btsLPN8fMD3/scNwnfSYcfHzAlUdXY3DQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FX0CYr%2FbtsLPN8fMD3%2FscNwnfSYcfHzAlUdXY3DQk%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;806&quot; height=&quot;452&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;511&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 직접 해보고 그걸 바로 매니저를 뽑아서 바로 넘기는건가? 라고 하면 그건 아니었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOVTGU/btsLQpFQCdq/Dyk6itkZh7UZkQoXcDsP3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOVTGU/btsLQpFQCdq/Dyk6itkZh7UZkQoXcDsP3K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOVTGU/btsLQpFQCdq/Dyk6itkZh7UZkQoXcDsP3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOVTGU%2FbtsLQpFQCdq%2FDyk6itkZh7UZkQoXcDsP3K%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;518&quot; height=&quot;470&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와같은 과정을 거친 이후에 매니저님을 뽑아서 위임을 진행했습니다. &lt;br /&gt;문서 하나만 보면 바로 업무에 투입될 수 있도록 한 것이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이런 생각이 들 수 있습니다. &lt;br /&gt;이건 지식 노동이 아니고 몸쓰는 일이니까 매뉴얼화가 가능하지... 그런데 개발자들은 지식노동자들이고&lt;br /&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;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Example)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;현장 노동자분들&lt;/b&gt;&lt;/u&gt;은 처음 업무에 투입되었을 때 어떻게 일을 할까요?&lt;br /&gt;제가 만약 숙소청소 업무에 투입되었다면 일단 아래와 같은 생각을 처음에 하게 될 것 같습니다.&lt;br /&gt;( 업무에 관심이 있다는 가정입니다. 업무에 관심이 없다면 &quot; 그냥 가서 청소하면 되지~ &quot;라고 생각할테니까요&amp;nbsp; )&lt;br /&gt;&lt;br /&gt;&amp;nbsp;- 내가 이 숙소에서 어떤 청소를 하면되지? 모든 청소를 세세하게 다하는건가? 아니면 일부분만 하면되나?&lt;br /&gt;&amp;nbsp;- 내가 숙소에 들어가서 어떤 순서로 일을 해야하지?&lt;br /&gt;&amp;nbsp;- 내가 숙소에 들어가서 가장 먼저 해야 할일은 뭐지?&lt;br /&gt;&amp;nbsp;- 내가 어떤걸 준비해서 가야하지? 만약 도구들이 있다면 어떤 도구를 사용해서 해야하지?&lt;br /&gt;&amp;nbsp;- 청소를 하다보니까 이런 문제가 이런상황에서는 어떻게 해야하지?&lt;br /&gt;&amp;nbsp;- 청소가 다 끝났을 때는 그냥 가면 되는건가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 이러한 내용들을 저를 고용한 사람한테 물어보게 되겠죠.&lt;br /&gt;&lt;b&gt;&quot;이런 궁금한 사항들이 있는데 이것들에 대해서 좀 알려주세요&quot;&lt;br /&gt;그럼 그 고용주는 저에게 위 질문에 대해서 생각하고 알려주느라 시간과 집중력이 흐려질겁니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 &lt;b&gt;이럴 때 고용주가 아래와같은 메뉴얼을 주면 제 질문에 대답하느라고 시간과 집중력을 소모하지는 않겠죠&lt;/b&gt;.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;585&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dXglzp/btsLP8LgKUg/EHKGIryhM0uO98e7A4U4Hk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dXglzp/btsLP8LgKUg/EHKGIryhM0uO98e7A4U4Hk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dXglzp/btsLP8LgKUg/EHKGIryhM0uO98e7A4U4Hk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdXglzp%2FbtsLP8LgKUg%2FEHKGIryhM0uO98e7A4U4Hk%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;852&quot; height=&quot;585&quot; data-origin-width=&quot;852&quot; data-origin-height=&quot;585&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; 방식을&amp;nbsp;&lt;u&gt;&lt;b&gt;지식노동자분들&lt;/b&gt;&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;&amp;nbsp;- 내가 이 숙소에서 어떤 청소를 하면되지? 모든 청소를 세세하게 다하는건가? 아니면 일부분만 하면되나?&lt;br /&gt;&amp;nbsp; &amp;nbsp;▶ 내가 이 회사에 들어가서 어떤 업무를 하는거지? 개발자가 나밖에 없으니 모든 프로그램을 다 만들어야하는건가?&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 아니면 이미 만들어진 프로그램에서 기능만 추가하는건가?&lt;br /&gt;&amp;nbsp;- 내가 숙소에 들어가서 가장 먼저 해야 할일은 뭐지?&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;▶ &lt;span&gt;내가 이 회사에 들어가서 가장 먼저 해야 할 일은 뭐지? &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;프로그램을 처음부터 만들어아하는건가?&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 아니면 Vision이나&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Motion제어만 하는건가?... &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;- 내가 어떤걸 준비해서 가야하지? 만약 도구들이 있다면 어떤 도구를 사용해서 해야하지?&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;▶&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;내가 이 회사에 들어가기 전에 알아야 할건 뭐지? 이 회사에서 어떤 프레임웍과 툴을 사용하고 있을까?&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 협업툴도 사용하고있나? Github를 사용하고 있나?&lt;br /&gt;&amp;nbsp;- 청소를 하다보니까 이런 문제가 이런상황에서는 어떻게 해야하지?&lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp;▶&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;그럼 이때 회사 입사 전 아래와 같이 그 회사가 만들어놓은 문서들을 공유해준다면&amp;nbsp;&lt;br /&gt;무엇을 준비해야할지, 그리고 누구에게 연락해야할지 등등 회사에 직접 연락할일은 없겠죠?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcBbdt/btsLQBzCgOC/hBc2JvwQVnQCJgtNg4vliK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcBbdt/btsLQBzCgOC/hBc2JvwQVnQCJgtNg4vliK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcBbdt/btsLQBzCgOC/hBc2JvwQVnQCJgtNg4vliK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcBbdt%2FbtsLQBzCgOC%2FhBc2JvwQVnQCJgtNg4vliK%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;1301&quot; height=&quot;717&quot; data-origin-width=&quot;1301&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1236&quot; data-origin-height=&quot;707&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctltJz/btsLQSufMYr/WGEe6am1yDwd3kSW3dzgXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctltJz/btsLQSufMYr/WGEe6am1yDwd3kSW3dzgXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctltJz/btsLQSufMYr/WGEe6am1yDwd3kSW3dzgXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctltJz%2FbtsLQSufMYr%2FWGEe6am1yDwd3kSW3dzgXK%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;1236&quot; height=&quot;707&quot; data-origin-width=&quot;1236&quot; data-origin-height=&quot;707&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;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;&lt;b&gt;그리고 회사에 입사한 뒤에는 아래 작성한 방식들을 따르면 충분히 혼자 일을 할수 있는 능력까지 갖출 수 있을겁니다.&lt;/b&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;h3 data-ke-size=&quot;size23&quot;&gt;3. 주니어 개발자와의 효율적인 협업 전략&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;프로세스 만들기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 입사한 주니어 개발자에게 내가 최대한 개발에 관여하지 않고 업무를 맡기려면 어떻게 해야할까요?&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;멘토링을 받으면서 들었던 한 가지 조언이 뇌리에 남습니다.&lt;br /&gt;&lt;b&gt;&amp;ldquo;미국 상위 10%는 어떻게 나머지 90%를 이끌어가는가? 답은 체계적인 프로세스에 있다.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;즉, 나보다 업무를 모르는 다른 사람들을 위해서 체계적인 프로세스를 만들어서 전달해줘야합니다.&lt;br /&gt;&lt;/b&gt;이것의 핵심 관점은 &quot;내가 일을 잘할 수 있는 방법&quot;을 생각하는게 아니고 &quot; 팀원이 일을 더 잘할 수 있는 환경을 만드는 방법&quot;을 생각하는 관점입니다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그럼 이 프로세스를 만들기 위해서는 어떤 방법을 사용하고 어떤 생각을 해야할까요&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;b&gt;명확하고 구체적인 지침&lt;/b&gt;: 명확한 지시와 구체적인 작업 목표를 요구합니다.&lt;/li&gt;
&lt;li style=&quot;list-style-type: disc; color: #000000;&quot;&gt;&lt;b&gt;시스템 일관성&lt;/b&gt;: 프로세스는 알고리즘처럼 반복 가능하고 일관되게 설계되어야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;의사결정 미리하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;명확하고 구체적인 지침과 일관성 있는 시스템을 만들기 위해 우리는 의사결정을 미리하는 문사화를 사용해야합니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발 과정에서 가장 시간이 많이 소요되는 것은 코딩이 아니라 &lt;b&gt;의사결정&lt;/b&gt;입니다.&lt;br /&gt;주니어 개발자는 특히 불확실성에서 오는 고민으로 많은 시간을 낭비합니다.&lt;br /&gt;이를 해결하기 위해 &lt;b&gt;문서화 과정에서 핵심적인 의사결정을 선제적으로 기록&lt;/b&gt;해야 합니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;구체적인 문서 작성 예시:&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;모호한 문서&lt;/b&gt;:
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;- Vision 검사 기능 구현 &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;- 데이터 수집 최적화 &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;- Motion 제어 오류 처리 추가 &lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;명확한 문서&lt;/b&gt;:
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&lt;b&gt;&lt;span&gt;- Vision 검사 기능 구현&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;&amp;gt; OpenCV를 사용하여 흑백 이미지를 기반으로 물체 경계선을 검출. &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;gt; 경계선 검출 정확도 95% 이상을 목표로 조명 보정 알고리즘 추가. &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;gt; 검사 주기: 2초 내 완료.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt;&lt;b&gt; - 데이터 수집 최적화&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;gt; FASTECH 모터 라이브러리를 사용하여 모터 속도와 위치 데이터를 10ms 간격으로 수집. &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;gt; 수집된 데이터는 CSV 형식으로 로컬 저장소에 저장하며, 1시간마다 서버로 전송. &lt;br /&gt;&amp;nbsp; &amp;nbsp;&amp;gt; 데이터 누락 방지를 위해 100개의 데이터 버퍼링 처리 후 일괄 저장.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span&gt; &lt;b&gt;- Motion 제어 오류 처리 추가 &lt;/b&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 통신&amp;nbsp;장애&amp;nbsp;발생&amp;nbsp;시&amp;nbsp;최대&amp;nbsp;3회&amp;nbsp;재시도,&amp;nbsp;재시도&amp;nbsp;간격&amp;nbsp;1초. &lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 지정&amp;nbsp;위치&amp;nbsp;오차가&amp;nbsp;&amp;plusmn;0.05mm를&amp;nbsp;초과하면&amp;nbsp;보정&amp;nbsp;루틴&amp;nbsp;실행. &lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 모터&amp;nbsp;과부하&amp;nbsp;시&amp;nbsp;알림&amp;nbsp;로그를&amp;nbsp;생성하고&amp;nbsp;동작&amp;nbsp;중지&amp;nbsp;후&amp;nbsp;재가동.&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;업무지시 명확하게 하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;사장학개론&quot;을 집필한 김승호 회장님의 말을 빌려오자면 업무 지시는 위에 말한 것과 같이 &lt;b&gt;명확성&lt;/b&gt;과 &lt;b&gt;데드라인&lt;/b&gt;을 반드시 포함해야 합니다.&lt;br /&gt;&lt;br /&gt;다음은 잘못된 예시와 올바른 예시를 통해 살펴보겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;잘못된 예:&lt;/b&gt; &quot;아까 그 문서 처리해줘요.&quot;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;올바른 예:&lt;/b&gt; &quot;오전에 받은 API 명세서를 검토해서, 오후 3시까지 피드백 주세요.&quot;&lt;/li&gt;
&lt;/ul&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;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 체계적인 문서 기반 개발 프로세스 구축&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;그럼 실제 어떤 문서를 작성해야 개발을 위임할 수 있을지 살펴보겠습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;SRS (Software Requirements Specification)&lt;/b&gt;: 시스템 요구사항 정의서. &lt;b&gt;프로그램의 핵심 기능&lt;/b&gt;과 &lt;b&gt;제약사항&lt;/b&gt; 명시.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SDD (Software Design Document)&lt;/b&gt;: 시스템 설계 문서. &lt;b&gt;주요 컴포넌트 간 상호작용 정의&lt;/b&gt;.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Tech Spec (Technical Specification)&lt;/b&gt;: &lt;b&gt;세부 기술 구현 명세서&lt;/b&gt;. 기술 스택과 구현 방식 구체화.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;411&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcEc2P/btsLOKkkUQA/2kKPlXUqKLf5h6oz1ocJEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcEc2P/btsLOKkkUQA/2kKPlXUqKLf5h6oz1ocJEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcEc2P/btsLOKkkUQA/2kKPlXUqKLf5h6oz1ocJEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcEc2P%2FbtsLOKkkUQA%2F2kKPlXUqKLf5h6oz1ocJEK%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;634&quot; height=&quot;311&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;411&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;br /&gt;위 문서를 보는 방법을 모를 것이기 때문에 이 부분은 직접 알려주며 진행하는게 좋지않을까 싶습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 예시를 들었던 청소업무를 하는 현장 노동자가 최신 청소기 사용법을 몰라서 일을 못하고 있으면&lt;br /&gt;가서 알려주면 되듯이요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 만약 복사/붙여넣기만 하는 업무라고 했어도 기존에 만들어 놓은 프로그램이 탄탄하고 체계적으로 만들어져있다 라고 한다면 기능만 추가되는 것이기 때문에 문제될만한건 없을 것 같습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;5. 주간 업무 프로세스 설계&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SRS, SDD를 보고어떠한 기능들을 자신이 추가해야하고 어떻게 만들어야하는지 &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;모두 숙지했다면&lt;br /&gt;이미 개발이 진행되고 있다고 하더라도 SRS만 보고 어떤 기능들이 필요할지에 대해서 하루동안 구체적으로 설계해보라는&lt;br /&gt;지시를 통해 프로젝트에 대해 깊이 생각해보는 훈련을 시켜봅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&quot;너가 이 프로젝트를 맡은 팀장이라고 한다면 그리고 고객이 (대표가) 이런 설비, 로봇, 프로그램을 만들고싶다고 이야기 했을 때 너는 이 프로젝트가 얼마나 걸릴 것 같고, 이 프로젝트를 진행하기 위해서는 어떤 기능들이 필요하다고 생각하는지 작성해봐&quot;&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;* 여기서 중요한점은 전체적인 기능설계시에는 디자인패턴이나 언어의 특성을 세세하게 고려하지 말고 &lt;/b&gt;&lt;b&gt;&lt;span&gt;이 프로젝트가 현실화 되기 위해서는 어떤 기능들이 필요할지 브레인스토밍 하는 형식으로 나열하고 필요없는 기능들은 제거해나가며 프로젝트의 방향성을 확립시키는게 중요할 것 입니다. *&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이후에는 실제로 작성한 문서를 기반으로해서 왜 이렇게 생각했는지를 시간을내어 들어주고 어떤 부분이 부족한지 &lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;일주일정도는 투자해서 코칭해줍니다.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;시간이 없고 월급이 그냥 나가는 것처럼 마음이 아프더라도 이러한 과정을 거쳐야 생각하는 훈련을 할 수 있고&amp;nbsp;&lt;br /&gt;실제 이 프로젝트를 진행하면서 잘못된 방향으로 나가는 것을 막을 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;그리고 마지막으로 직접 설계한 기능들을 직접 구현하기 전에 절대 코드를 먼저 작성하지 않고&amp;nbsp;&lt;br /&gt;Tech Spec을 작성하게 하여 업무를 진행시킵니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요일주요 업무&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;월요일&lt;/td&gt;
&lt;td&gt;Tech Spec 작성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;화요일&lt;/td&gt;
&lt;td&gt;Tech Spec 리뷰 및 수정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;수요일&lt;/td&gt;
&lt;td&gt;핵심 코드 작성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;목-금요일&lt;/td&gt;
&lt;td&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;b&gt;1개월간 반복된 결과:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주니어 개발자의 설계 능력 및 Tech Spec 작성 역량 향상.&lt;/li&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;h3 data-ke-size=&quot;size23&quot;&gt;6. 마무리 성공적인 협업을 위한 전제 조건&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 조건들이 뒷받침되지 않으면, 어떤 프로세스도 효과를 발휘할 수 없습니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;충실한 기본 문서&lt;/b&gt;: SRS와 SDD는 상세히 작성되어야 하며, 지속적으로 업데이트되어야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;시간 투자&lt;/b&gt;: 리뷰 및 피드백에 충분한 시간을 할애해야 합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;일관된 프로세스 유지&lt;/b&gt;: 프로세스는 예외 없이 지켜져야 하며, 필요 시 개선이 이루어져야 합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;</description>
      <category>Program/생각</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/195</guid>
      <comments>https://opencv-master.tistory.com/195#entry195comment</comments>
      <pubDate>Tue, 14 Jan 2025 23:36:01 +0900</pubDate>
    </item>
    <item>
      <title>C# 프로젝트 Error 정리</title>
      <link>https://opencv-master.tistory.com/194</link>
      <description>&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;style2&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. OpencvSharp 로드 에러&lt;/b&gt;&lt;span style=&quot;background-color: #262624; color: #e5e5e2; text-align: start;&quot;&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #262624; color: #e5e5e2; text-align: start;&quot;&gt;System.TypeInitializationException: 'The type initializer for 'OpenCvSharp.Internal.NativeMethods' threw an exception.'&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #262624; color: #e5e5e2; text-align: start;&quot;&gt;DllNotFoundException: Unable to load DLL 'OpenCvSharpExtern' or one of its dependencies: &lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #262624; color: #e5e5e2; text-align: start;&quot;&gt;지정된 모듈을 찾을 수 없습니다. (0x8007007E)&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 alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKBil5/btsLFWZOr4w/lbanEt06GUggA5S3oPYCn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKBil5/btsLFWZOr4w/lbanEt06GUggA5S3oPYCn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKBil5/btsLFWZOr4w/lbanEt06GUggA5S3oPYCn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKBil5%2FbtsLFWZOr4w%2FlbanEt06GUggA5S3oPYCn0%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;154&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;154&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;Any CPU는 프로그램이 32비트(x86)와 64비트(x64) 환경 모두에서 실행될 수 있도록 하는 설정입니다.&lt;br /&gt;하지만 OpenCvSharp의 경우 네이티브 DLL(C++로 작성된)을 사용하기 때문에 문제가 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 이유:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;OpenCvSharp는 네이티브 코드를 포함하고 있어서, 32비트용 DLL과 64비트용 DLL이 따로 존재합니다&lt;/li&gt;
&lt;li&gt;Any CPU 설정에서는 실행 환경에 따라 32비트/64비트 중 하나를 선택하게 되는데, 이 때:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;64비트 Windows에서 Any CPU로 실행하면 기본적으로 64비트로 실행됨&lt;/li&gt;
&lt;li&gt;하지만 이 경우 프로그램이 실행될 때까지 어떤 버전의 DLL을 로드할지 결정되지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;OpenCvSharp의 네이티브 DLL은 빌드 시점에 명확하게 어떤 버전(32비트/64비트)을 사용할지 알아야 함&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;x64로 명시적으로 지정하면 빌드 시점에 64비트 DLL을 사용하도록 확실히 결정됨&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;u&gt;&lt;b&gt;Any CPU를 사용하면 런타임에 결정되기 때문에 네이티브 DLL 로딩에 문제가 발생할 수 있음&lt;/b&gt;&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlfA2E/btsLHNAgbji/wAJ1foK3cOt1PBE4OWUcS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlfA2E/btsLHNAgbji/wAJ1foK3cOt1PBE4OWUcS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlfA2E/btsLHNAgbji/wAJ1foK3cOt1PBE4OWUcS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdlfA2E%2FbtsLHNAgbji%2FwAJ1foK3cOt1PBE4OWUcS0%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;1015&quot; height=&quot;92&quot; data-origin-width=&quot;1015&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Program/C#</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/194</guid>
      <comments>https://opencv-master.tistory.com/194#entry194comment</comments>
      <pubDate>Wed, 8 Jan 2025 16:06:37 +0900</pubDate>
    </item>
    <item>
      <title>장비/설비 모듈 설계 (1)</title>
      <link>https://opencv-master.tistory.com/193</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/com11M/btsLrcVilZY/yKSOFR2X4wPX4QRSTFfJp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/com11M/btsLrcVilZY/yKSOFR2X4wPX4QRSTFfJp1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/com11M/btsLrcVilZY/yKSOFR2X4wPX4QRSTFfJp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcom11M%2FbtsLrcVilZY%2FyKSOFR2X4wPX4QRSTFfJp1%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;296&quot; height=&quot;360&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;360&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;FA(Factory Automation) 장비와 설비 개발에서는 &lt;b&gt;모듈 구성&lt;/b&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;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. FA 장비의 모듈 구성&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FA 장비는 기본적으로 다양한 기능별로 구분된 모듈로 구성됩니다.&lt;br /&gt;제가 경험한 대부분의 설비들은 아래와 같은 주요 모듈로 나뉘었습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;VISION 모듈&lt;/b&gt;: 카메라와 검사 라이브러리 및 딥러닝등을 이용해 제품이나 공정을 검사.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;MOTOR 모듈&lt;/b&gt;: 모터 제어 (이동, 보간, 축 상태 수집) 등의 작업 수행.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DIO 모듈&lt;/b&gt;: 디지털 입출력을 관리하여 센서 데이터 수집 및 장비 제어.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NETWORK 모듈&lt;/b&gt;: 데이터 송수신 및 외부 시스템(PC,센서)과 통신.&lt;/li&gt;
&lt;li&gt;이 외 기타 모듈 ( Log, File ... )&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈화는 기능별 책임을 분리하여 유지보수성을 높이고, 새로운 기능을 추가할 때 기존 시스템에 미치는 영향을&lt;br /&gt;최소화하여 독립성, 재사용성을 높이는데 핵심적인 역할을 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;2. 시퀀스 기반 설계란?&lt;/b&gt;&lt;/h2&gt;
&lt;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;단계적으로 정의&lt;/b&gt;하고, 각 단계가 완료되면 다음 단계로 넘어가는 방식으로 동작합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;시퀀스 기반 설계의 특징&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;순차적 진행&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예: START 버튼 클릭 &amp;rarr; HOME 동작 &amp;rarr; VISION 검사 &amp;rarr; 작업 완료.&lt;/li&gt;
&lt;li&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;202&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt0Egr/btsLp4X3OHM/hzhaAnzN9hQZo4PzuCZG90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt0Egr/btsLp4X3OHM/hzhaAnzN9hQZo4PzuCZG90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt0Egr/btsLp4X3OHM/hzhaAnzN9hQZo4PzuCZG90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt0Egr%2FbtsLp4X3OHM%2FhzhaAnzN9hQZo4PzuCZG90%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;768&quot; height=&quot;202&quot; data-origin-width=&quot;768&quot; data-origin-height=&quot;202&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;단순한 흐름&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;작업 순서가 고정적이기 때문에 구현과 디버깅이 간단.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;직관적 설계&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;작업 순서가 명확하게 드러나 누구나 쉽게 이해 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;실제 코드 예시&lt;/h3&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// 1. 모터를 홈 위치로 이동
await MotorMoveHome();
Console.WriteLine(&quot;Motor homing initiated...&quot;);

// 2. 홈 위치 확인
bool bIsHomeComplete = await CheckHomeComplete();
if (bIsHomeComplete)
{
    // 3. 비전 검사를 시작
    Console.WriteLine(&quot;Home complete. Starting vision inspection...&quot;);
    await VisionInspection();

    // 4. 목표 위치로 이동
    Console.WriteLine(&quot;Moving motor to target position...&quot;);
    await MotorMoveToTarget();
}
else
{
    // 오류 발생 시 처리
    Console.WriteLine(&quot;Error: Home not complete.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식은 대부분의 장비에서 효과적으로 사용될 만큼 직관적이고 간단합니다.&lt;br /&gt;다만, &lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;시퀀스를 큰 틀 안에서 체계적으로 관리하고 전환 상태를 명시적으로 표현하기 위해 상태 머신(State Machine)을 도입할 수도 있습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 상태 머신(State Machine) 도입&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시퀀스 기반 설계를 조금 더 유연하게 만들고 싶다면, &lt;b&gt;상태 머신(State Machine)&lt;/b&gt; 방식을 도입해볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상태 머신은 시스템을 여러 &lt;b&gt;&quot;상태(State)&quot;&lt;/b&gt;로 정의하고, 각 상태에서 수행할 작업과 상태 간 전환 조건을 명시적으로 관리합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;상태 머신의 구조&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;상태(State)&lt;/b&gt;: Idle(대기상태), Ready(준비완료상태), Processing(작업상태), Error(에러상태) 등.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;전환(Transition)&lt;/b&gt;: 한 상태에서 다른 상태로 넘어가는 규칙.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이벤트(Event)&lt;/b&gt;: 상태 전환을 유발하는 트리거.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;471&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d8nteK/btsLrNHDilo/qAUOArdcOjG0kjcysLBkQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d8nteK/btsLrNHDilo/qAUOArdcOjG0kjcysLBkQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d8nteK/btsLrNHDilo/qAUOArdcOjG0kjcysLBkQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd8nteK%2FbtsLrNHDilo%2FqAUOArdcOjG0kjcysLBkQK%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;580&quot; height=&quot;471&quot; data-origin-width=&quot;804&quot; data-origin-height=&quot;471&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;상태 머신 적용 방식&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시퀀스 기반 설계를 상태 머신의 틀 안에 넣어, 각 상태에서 기존의 시퀀스를 실행하도록 변경할 수 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;상태 머신 코드 예시&lt;/h4&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;private async Task HomeState()
{
    var homeHandler = new HomeStateHandler();
    try
    {
        await homeHandler.ExecuteAsync(); // Home 관련 작업 실행
        _currentState = State.Processing; // 다음 상태로 전환
    }
    catch
    {
        _currentState = State.Error; // 오류 발생 시 Error 상태로 전환
    }
}

private async Task ProcessingState()
{
    var processingHandler = new ProcessingStateHandler();
    try
    {
        await processingHandler.ExecuteAsync(); // Processing 작업 실행
        _currentState = State.Idle; // 완료 후 Idle 상태로 전환
    }
    catch
    {
        _currentState = State.Error;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;시퀀스와 상태 머신의 조합&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 시퀀스 로직은 각 상태(HomeState, ProcessingState)의 작업으로 캡슐화.&lt;/li&gt;
&lt;li&gt;상태 머신은 상태 전환과 전체 흐름을 관리.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;259&quot; data-origin-height=&quot;302&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hhh6n/btsLsAHMyXF/HiGkvWV6OM66gfpumc4Kj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hhh6n/btsLsAHMyXF/HiGkvWV6OM66gfpumc4Kj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hhh6n/btsLsAHMyXF/HiGkvWV6OM66gfpumc4Kj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHhh6n%2FbtsLsAHMyXF%2FHiGkvWV6OM66gfpumc4Kj0%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;259&quot; height=&quot;302&quot; data-origin-width=&quot;259&quot; data-origin-height=&quot;302&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. 상태 머신 도입의 장점&lt;/b&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;유연성&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;작업 순서가 고정되지 않아, 상황에 따라 다른 흐름으로 전환 가능.&lt;/li&gt;
&lt;li&gt;예: 오류 발생 시 Error 상태로 전환 후 복구.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;확장성&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새로운 상태나 작업 추가 시 기존 구조를 크게 변경할 필요 없음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;가독성&lt;/b&gt;:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전체 상태와 흐름이 명확히 드러나, 새로운 개발자도 쉽게 이해 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 FA 장비/설비 개발에서 &lt;b&gt;시퀀스 기반 설계&lt;/b&gt;의 효과적인 사용 방법과 이를 &lt;b&gt;상태 머신&lt;/b&gt;으로 발전시키는 간략한 방법을 살펴봤습니다. 상태 머신은 시퀀스의 효율성을 유지하면서도 더 큰 유연성과 확장성을 제공하는 설계 방식이라고 생각해서 한번 작성해봤습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 글에서는 상태 머신 설계를 실제 프로젝트에 적용할 때의 구체적인 사례와 코드 구조를 소개하겠습니다.&lt;br /&gt;FA 장비 개발자로서 시스템을 더 유연하고 확장 가능하게 만드는 데 이 글이 도움이 되었길 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;감사합니다.&lt;/p&gt;</description>
      <category>Program/Design</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/193</guid>
      <comments>https://opencv-master.tistory.com/193#entry193comment</comments>
      <pubDate>Sat, 21 Dec 2024 12:44:43 +0900</pubDate>
    </item>
    <item>
      <title>C# netDxf 라이브러리 (1)</title>
      <link>https://opencv-master.tistory.com/192</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;312&quot; data-origin-height=&quot;416&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgaibT/btsLj9Q2pQV/Q7TbrOoP77dIb19UUAE8u0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgaibT/btsLj9Q2pQV/Q7TbrOoP77dIb19UUAE8u0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgaibT/btsLj9Q2pQV/Q7TbrOoP77dIb19UUAE8u0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdgaibT%2FbtsLj9Q2pQV%2FQ7TbrOoP77dIb19UUAE8u0%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;312&quot; height=&quot;416&quot; data-origin-width=&quot;312&quot; data-origin-height=&quot;416&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;오늘은 C#의 Nuget 패키지 중 하나인 netDxf 라이브러리에 대해 알아보려 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 프로젝트에서 dwg 도면을 읽어와야하는게 메인이기 때문에 가장 많이 사용하는 라이브러리 중 하나이기도 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 netDxf 라이브러리에 대한 목차입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;netDxf 라이브러리 시작하기&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;netDxf란?
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;라이브러리 소개&lt;/li&gt;
&lt;li&gt;주요 특징&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;기본 사용법
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;NuGet 패키지 설치&lt;/li&gt;
&lt;li&gt;DXF 파일 생성하기&lt;/li&gt;
&lt;li&gt;DXF 파일 읽기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;실전 활용
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 도면에 도형 추가하기 (선, 원, 폴리라인)&lt;/li&gt;
&lt;li&gt;레이어 관리&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;기존 도면에 도형 추가하기&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; 텍스트 추가하기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;netDxf란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;netDxf는 AutoCAD DXF 파일을 읽고 쓸 수 있게 해주는 오픈소스 .NET 라이브러리입니다. &lt;br /&gt;이 라이브러리를 사용하면 복잡한 DXF 파일 포맷을 이해하지 않아도 손쉽게 CAD 파일을 다룰 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 특징을 살펴보면:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DXF 파일 읽기/쓰기 지원&lt;/li&gt;
&lt;li&gt;2D/3D 도형 요소 생성&lt;/li&gt;
&lt;li&gt;레이어, 선 스타일, 문자 스타일 관리&lt;/li&gt;
&lt;li&gt;가벼운 크기와 빠른 성능&lt;/li&gt;
&lt;li&gt;.NET Framework 4.5 이상 지원&lt;/li&gt;
&lt;/ul&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;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;NuGet 패키지 설치&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Visual Studio의 NuGet 패키지 관리자를 통해 쉽게 설치할 수 있습니다.&lt;/p&gt;
&lt;div&gt;
&lt;div style=&quot;background-color: #282c34; color: #abb2bf; text-align: left;&quot;&gt;
&lt;pre id=&quot;code_1734306058270&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Install-Package netDxf&lt;/code&gt;&lt;/pre&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;또는 프로젝트 파일에 직접 패키지 참조를 추가할 수도 있습니다&lt;/p&gt;
&lt;pre id=&quot;code_1734306069730&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;PackageReference Include=&quot;netDxf&quot; Version=&quot;2022.11.2&quot; /&amp;gt;&lt;/code&gt;&lt;/pre&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;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DXF 파일 생성하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 도면을 생성하는 예제를 살펴보겠습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1734306114178&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using netDxf;
using netDxf.Entities;
using netDxf.Header;

// 새로운 DXF 문서 생성
DxfDocument doc = new DxfDocument();

// 직선 그리기
Line line = new Line(new Vector2(0, 0), new Vector2(100, 100));
doc.AddEntity(line);

// 원 그리기
Circle circle = new Circle(new Vector2(50, 50), 30);
doc.AddEntity(circle);

// 파일로 저장
doc.Save(&quot;example.dxf&quot;);&lt;/code&gt;&lt;/pre&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;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DXF 파일 읽기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 DXF 파일을 읽어오는 방법도 간단합니다&lt;/p&gt;
&lt;pre id=&quot;code_1734306397414&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DxfDocument doc = DxfDocument.Load(&quot;existing.dxf&quot;);

// 모든 선 엔터티 가져오기
var lines = doc.Lines;
foreach (Line line in lines)
{
    Console.WriteLine($&quot;시작점: ({line.StartPoint.X}, {line.StartPoint.Y})&quot;);
    Console.WriteLine($&quot;끝점: ({line.EndPoint.X}, {line.EndPoint.Y})&quot;);
}&lt;/code&gt;&lt;/pre&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;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;도형 그리기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 도형을 그리는 예제를 살펴보겠습니다&lt;/p&gt;
&lt;pre id=&quot;code_1734306474530&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 폴리라인 그리기
List&amp;lt;Vector2&amp;gt; vertices = new List&amp;lt;Vector2&amp;gt;
{
    new Vector2(0, 0),
    new Vector2(10, 10),
    new Vector2(20, 0),
    new Vector2(30, 10)
};

Polyline polyline = new Polyline(vertices);
doc.AddEntity(polyline);

// 호(Arc) 그리기
Arc arc = new Arc(new Vector2(0, 0), 50, 0, 180);
doc.AddEntity(arc);&lt;/code&gt;&lt;/pre&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;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;레이어 관리&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도면의 레이어를 관리하는 방법입니다&lt;/p&gt;
&lt;pre id=&quot;code_1734306501136&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 새 레이어 생성
Layer layer = new Layer(&quot;MyLayer&quot;);
layer.Color = AciColor.Red;
doc.Layers.Add(layer);

// 레이어에 엔터티 추가
Line newLine = new Line(new Vector2(0, 0), new Vector2(100, 100));
newLine.Layer = layer;
doc.AddEntity(newLine);&lt;/code&gt;&lt;/pre&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;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;텍스트 추가하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도면에 텍스트를 추가하는 방법입니다&lt;/p&gt;
&lt;pre id=&quot;code_1734306522752&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 텍스트 스타일 생성
TextStyle style = new TextStyle(&quot;Arial&quot;);
doc.TextStyles.Add(style);

// 텍스트 추가
Text text = new Text(&quot;Hello CAD!&quot;, new Vector2(0, 0), 10, style);
doc.AddEntity(text);&lt;/code&gt;&lt;/pre&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;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;netDxf 라이브러리를 사용하면 CAD 파일을 쉽게 다룰 수 있습니다. 특히 자동화된 도면 생성이나 기존 도면의 수정이 필요한 경우에 매우 유용합니다. 실제 프로젝트에서는 이보다 더 복잡한 작업들이 필요할 수 있지만, 이 기본적인 예제들을 응용하면 대부분의 작업을 수행할 수 있을 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 블로그 글에는 실제 Dxf 정보를 활용하여 PictureBox에 표시해보고 실제 활용해보는 방법에 대해서 설명해보겠습니다 :)&lt;/p&gt;</description>
      <category>Program/C#</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/192</guid>
      <comments>https://opencv-master.tistory.com/192#entry192comment</comments>
      <pubDate>Mon, 16 Dec 2024 08:55:13 +0900</pubDate>
    </item>
    <item>
      <title>C# 유닛(단위)테스트(2)</title>
      <link>https://opencv-master.tistory.com/191</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;229&quot; data-origin-height=&quot;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2RghS/btsLdz9U4AK/gJw4txKwp1FxHk9rkokQyk/tfile.dat&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2RghS/btsLdz9U4AK/gJw4txKwp1FxHk9rkokQyk/tfile.dat&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2RghS/btsLdz9U4AK/gJw4txKwp1FxHk9rkokQyk/tfile.dat&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2RghS%2FbtsLdz9U4AK%2FgJw4txKwp1FxHk9rkokQyk%2Ftfile.dat&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;229&quot; height=&quot;304&quot; data-origin-width=&quot;229&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기존 프로젝트에서 유닛 테스트 추가하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 유닛(단위)테스트(1)에서는 유닛 테스트 작성 방법에 대해 알아보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://opencv-master.tistory.com/190&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://opencv-master.tistory.com/190&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1733755871669&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;C# 유닛(단위)테스트(1)&quot; data-og-description=&quot;오늘은 C#에서의 유닛(단위) 테스트에 대해 알아보려 합니다.&amp;nbsp;C#에서 유닛(단위) 테스트란?유닛 테스트(Unit Test)는 프로그램의 작은 조각(주로 클래스나 메서드)이 올바르게 작동하는지 검증하는 &quot; data-og-host=&quot;opencv-master.tistory.com&quot; data-og-source-url=&quot;https://opencv-master.tistory.com/190&quot; data-og-url=&quot;https://opencv-master.tistory.com/190&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/y1qoP/hyXKog5dqN/fkXQ5PaqhOQhREcWbm1pY0/img.png?width=229&amp;amp;height=304&amp;amp;face=0_0_229_304,https://scrap.kakaocdn.net/dn/bgUTG4/hyXKog5dr4/xp2RTyU4SNbRMTIkg0LZx0/img.png?width=229&amp;amp;height=304&amp;amp;face=0_0_229_304,https://scrap.kakaocdn.net/dn/bEQ0uo/hyXKkZ3Bge/fdHRk4tKrYDx0s7I7cfnW0/img.jpg?width=740&amp;amp;height=462&amp;amp;face=261_197_458_413&quot;&gt;&lt;a href=&quot;https://opencv-master.tistory.com/190&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://opencv-master.tistory.com/190&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/y1qoP/hyXKog5dqN/fkXQ5PaqhOQhREcWbm1pY0/img.png?width=229&amp;amp;height=304&amp;amp;face=0_0_229_304,https://scrap.kakaocdn.net/dn/bgUTG4/hyXKog5dr4/xp2RTyU4SNbRMTIkg0LZx0/img.png?width=229&amp;amp;height=304&amp;amp;face=0_0_229_304,https://scrap.kakaocdn.net/dn/bEQ0uo/hyXKkZ3Bge/fdHRk4tKrYDx0s7I7cfnW0/img.jpg?width=740&amp;amp;height=462&amp;amp;face=261_197_458_413');&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;C# 유닛(단위)테스트(1)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;오늘은 C#에서의 유닛(단위) 테스트에 대해 알아보려 합니다.&amp;nbsp;C#에서 유닛(단위) 테스트란?유닛 테스트(Unit Test)는 프로그램의 작은 조각(주로 클래스나 메서드)이 올바르게 작동하는지 검증하는&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;opencv-master.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;이번에는 이미 존재하는 프로젝트에 유닛 테스트를 추가하는 방법을 단계별로 살펴보겠습니다.&lt;br /&gt;기존 프로젝트에서 유닛 테스트를 작성하려면 &lt;b&gt;&lt;u&gt;테스트 프로젝트를 새로 생성하여 기존 프로젝트를 참조하는 방식으로 진행하는 것이 가장 좋은 방법입니다.&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 테스트 프로젝트를 분리해야 할까?&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;독립성 보장&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유닛 테스트는 프로덕션 코드와 별도로 독립적으로 실행되어야 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;코드 관리 용이성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 코드를 별도로 분리하면 프로젝트 구조가 깔끔해지고, 유지보수가 쉬워집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;코드 품질 검증&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 프로젝트를 통해 변경된 코드의 영향을 쉽게 검증할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기존 프로젝트에 유닛 테스트 추가하는 방법&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 테스트 프로젝트 생성하기&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Visual Studio&lt;/b&gt;에서 &lt;b&gt;솔루션 탐색기&lt;/b&gt;를 열고, 프로젝트의 솔루션 이름을 우클릭.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;추가 &amp;gt; 새 프로젝트&lt;/b&gt;를 선택.&lt;/li&gt;
&lt;li&gt;**&quot;단위 테스트 프로젝트(MSTest)&quot;**를 검색하고 선택.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로젝트 이름은 보통 ProjectName.Tests로 설정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;테스트 프로젝트가 기존 솔루션에 추가됩니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uk2ew/btsLbwAgvgQ/QMjs4vJi0KogCujxBrw6A0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uk2ew/btsLbwAgvgQ/QMjs4vJi0KogCujxBrw6A0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uk2ew/btsLbwAgvgQ/QMjs4vJi0KogCujxBrw6A0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuk2ew%2FbtsLbwAgvgQ%2FQMjs4vJi0KogCujxBrw6A0%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;484&quot; height=&quot;522&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;682&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VsMWE/btsLcrkRwNS/2YBIYGzWr3hvDBTeoRkrT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VsMWE/btsLcrkRwNS/2YBIYGzWr3hvDBTeoRkrT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VsMWE/btsLcrkRwNS/2YBIYGzWr3hvDBTeoRkrT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVsMWE%2FbtsLcrkRwNS%2F2YBIYGzWr3hvDBTeoRkrT1%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;491&quot; height=&quot;327&quot; data-origin-width=&quot;1023&quot; data-origin-height=&quot;682&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. 기존 프로젝트 참조 추가하기&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;새로 생성한 &lt;b&gt;테스트 프로젝트&lt;/b&gt;를 우클릭하고, &lt;b&gt;참조 추가&lt;/b&gt;를 선택.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;프로젝트 &amp;gt; 솔루션&lt;/b&gt; 탭에서 기존 프로젝트를 선택 후 &lt;b&gt;확인&lt;/b&gt; 클릭.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이렇게 하면 테스트 프로젝트에서 기존 프로젝트의 클래스와 메서드에 접근할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 테스트 클래스 작성하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 프로젝트에 테스트 클래스를 생성하고, 기존 프로젝트의 코드를 테스트합니다.&lt;br /&gt;테스트 코드는 [TestClass]와 [TestMethod] 어트리뷰트를 사용해 작성합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733756192163&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Microsoft.VisualStudio.TestTools.UnitTesting;
using MyExistingProject; // 기존 프로젝트 네임스페이스

[TestClass]
public class ExistingClassTests
{
    [TestMethod]
    public void SomeMethod_ValidInput_ReturnsExpectedResult()
    {
        // Arrange
        var obj = new ExistingClass(); // 기존 클래스 인스턴스 생성
        string input = &quot;Hello&quot;;

        // Act
        string result = obj.SomeMethod(input);

        // Assert
        Assert.AreEqual(&quot;HELLO&quot;, result); // 기대값과 결과값 비교
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 테스트 실행하기&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Visual Studio 메뉴에서 &lt;b&gt;테스트 &amp;gt; 모든 테스트 실행&lt;/b&gt;을 클릭.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;테스트 탐색기(Test Explorer)&lt;/b&gt; 창에서 테스트 결과를 확인합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;녹색&lt;/b&gt;: 성공&lt;/li&gt;
&lt;li&gt;&lt;b&gt;빨간색&lt;/b&gt;: 실패&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;프로젝트 구조 예시&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 프로젝트를 추가하면 프로젝트 구조는 다음과 같이 정리됩니다:&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733756221941&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Solution
├── MyExistingProject
│   ├── Class1.cs
│   ├── Class2.cs
├── MyExistingProject.Tests
    ├── Class1Tests.cs
    ├── Class2Tests.cs&lt;/code&gt;&lt;/pre&gt;
&lt;/div&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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;추가로 알아둘 점&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;테스트 프로젝트와 기존 프로젝트의 네임스페이스 충돌 방지&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 코드에서 기존 프로젝트의 클래스와 메서드를 사용할 때 네임스페이스를 명시해야 합니다.&lt;/li&gt;
&lt;li&gt;예: using MyExistingProject;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;모의 객체(Mock) 사용&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 대상 메서드가 외부 의존성을 포함할 경우, &lt;b&gt;Mocking 프레임워크&lt;/b&gt;를 사용하여 테스트를 간소화할 수 있습니다.&lt;/li&gt;
&lt;li&gt;예: Moq, NSubstitute 등.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;기존 프로젝트에서 테스트 코드 작성 예시: MSTest 기반&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;기능 코드: 기존 프로젝트&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733756244176&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;namespace MyExistingProject
{
    public class Calculator
    {
        public int Add(int a, int b) =&amp;gt; a + b;

        public int Divide(int a, int b)
        {
            if (b == 0) throw new DivideByZeroException();
            return a / b;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 코드: 테스트 프로젝트&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733756250778&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Microsoft.VisualStudio.TestTools.UnitTesting;
using MyExistingProject;

[TestClass]
public class CalculatorTests
{
    [TestMethod]
    public void Add_ValidInputs_ReturnsCorrectSum()
    {
        // Arrange
        var calculator = new Calculator();

        // Act
        int result = calculator.Add(3, 5);

        // Assert
        Assert.AreEqual(8, result);
    }

    [TestMethod]
    [ExpectedException(typeof(DivideByZeroException))]
    public void Divide_ByZero_ThrowsDivideByZeroException()
    {
        // Arrange
        var calculator = new Calculator();

        // Act
        calculator.Divide(10, 0);

        // Assert
        // ExpectedException으로 예외 발생 확인
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 프로젝트에서 유닛 테스트를 추가하려면 별도의 테스트 프로젝트를 생성한 뒤, 기존 프로젝트를 참조하여 테스트를 작성합니다.&lt;br /&gt;이 과정은 초기에는 번거로워 보일 수 있지만, 코드 품질 유지 및 버그 예방에 매우 유용하며, 팀 협업에도 큰 도움이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Program/C#</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/191</guid>
      <comments>https://opencv-master.tistory.com/191#entry191comment</comments>
      <pubDate>Mon, 9 Dec 2024 23:59:06 +0900</pubDate>
    </item>
    <item>
      <title>C# 유닛(단위)테스트(1)</title>
      <link>https://opencv-master.tistory.com/190</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;229&quot; data-origin-height=&quot;304&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/z9329/btsLcqGeL4B/vhYMevyktgFm6ZOHcFwDaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/z9329/btsLcqGeL4B/vhYMevyktgFm6ZOHcFwDaK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/z9329/btsLcqGeL4B/vhYMevyktgFm6ZOHcFwDaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fz9329%2FbtsLcqGeL4B%2FvhYMevyktgFm6ZOHcFwDaK%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;229&quot; height=&quot;304&quot; data-origin-width=&quot;229&quot; data-origin-height=&quot;304&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;오늘은 C#에서의 유닛(단위) 테스트에 대해 알아보려 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;C#에서 유닛(단위) 테스트란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유닛 테스트(Unit Test)는 프로그램의 작은 조각(주로 클래스나 메서드)이 올바르게 작동하는지 검증하는 과정입니다. &quot;유닛(Unit)&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;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;유닛 테스트의 종류&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;수동 테스트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사람이 직접 입력 값을 넣고 결과를 확인하는 방식.&lt;/li&gt;
&lt;li&gt;단점: 반복 작업이 많아 시간이 오래 걸림.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;자동화 테스트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 코드를 작성하여 자동으로 테스트를 수행.&lt;/li&gt;
&lt;li&gt;장점: 반복적으로 실행 가능하고, 실수 확률이 적음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;C#에서 유닛 테스트의 방식&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;C#에서는 주로 다음과 같은 유닛 테스트 프레임워크를 사용합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;MSTest&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Microsoft에서 제공하는 기본 유닛 테스트 프레임워크.&lt;/li&gt;
&lt;li&gt;Visual Studio와 통합이 잘 되어 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;xUnit&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간결한 문법과 확장성이 뛰어난 유닛 테스트 프레임워크.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;NUnit&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;강력한 기능과 다양한 어트리뷰트를 제공하는 프레임워크.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;유닛 테스트를 어떻게 사용하는가?&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 대상 클래스&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1733755336446&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 클래스&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 MSTest를 사용한 테스트 코드의 예입니다.&lt;/p&gt;
&lt;pre id=&quot;code_1733755344084&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class CalculatorTests
{
    [TestMethod]
    public void Add_ValidInputs_ReturnsCorrectSum()
    {
        // Arrange
        var calculator = new Calculator();
        int a = 3, b = 5;

        // Act
        int result = calculator.Add(a, b);

        // Assert
        Assert.AreEqual(8, result); // 기대값: 8
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;테스트 코드 작성 방법 (3A 원칙)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드는 다음의 **3A 패턴(Arrange, Act, Assert)**을 따릅니다:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;Arrange (준비)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트에 필요한 데이터를 준비.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Act (실행)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테스트 대상 메서드 호출.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Assert (검증)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기대값과 실제 결과를 비교.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Visual Studio에서 MSTest로 유닛 테스트 실행하기&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;b&gt;테스트 프로젝트 생성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Visual Studio에서 &lt;b&gt;새 프로젝트&lt;/b&gt; &amp;gt; &lt;b&gt;단위 테스트 프로젝트(MSTest)&lt;/b&gt; 선택.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;테스트 클래스 작성&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[TestClass] 어트리뷰트를 붙여 테스트 클래스 선언.&lt;/li&gt;
&lt;li&gt;[TestMethod] 어트리뷰트를 붙여 테스트 메서드 선언.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;테스트 실행&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Visual Studio 상단 메뉴에서 &lt;b&gt;테스트&lt;/b&gt; &amp;gt; &lt;b&gt;모든 테스트 실행&lt;/b&gt; 클릭.&lt;/li&gt;
&lt;li&gt;테스트 결과는 테스트 탐색기에서 확인 가능.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MSTest 예시: 모듈 테스트 작성&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 대상 클래스&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733755359229&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class LaneDetector
{
    public string DetectLaneType(byte[] image)
    {
        if (image == null || image.Length == 0)
            throw new ArgumentException(&quot;Invalid image data&quot;);

        return &quot;Solid&quot;; // 예시로 '실선' 반환
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MSTest 기반 테스트 코드&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1733755366235&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;using Microsoft.VisualStudio.TestTools.UnitTesting;

[TestClass]
public class LaneDetectorTests
{
    [TestMethod]
    public void DetectLaneType_ValidImage_ReturnsLaneType()
    {
        // Arrange
        var laneDetector = new LaneDetector();
        byte[] image = new byte[] { 255, 128, 64 };

        // Act
        string laneType = laneDetector.DetectLaneType(image);

        // Assert
        Assert.AreEqual(&quot;Solid&quot;, laneType);
    }

    [TestMethod]
    [ExpectedException(typeof(ArgumentException))]
    public void DetectLaneType_InvalidImage_ThrowsArgumentException()
    {
        // Arrange
        var laneDetector = new LaneDetector();
        byte[] invalidImage = null;

        // Act
        laneDetector.DetectLaneType(invalidImage);

        // Assert
        // ExpectedException으로 예외 발생 확인
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;테스트 코드의 장점&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;코드 품질 향상: 버그를 사전에 방지.&lt;/li&gt;
&lt;li&gt;유지보수 편리: 코드 수정 후에도 기존 기능 검증 가능.&lt;/li&gt;
&lt;li&gt;협업 효율성: 코드 동작을 명확히 설명하는 문서 역할.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSTest는 Visual Studio와 통합되어 간단히 테스트 코드를 작성하고 실행할 수 있어 개발 초기에 유용하게 활용할 수 있습니다.&amp;nbsp;&lt;/p&gt;</description>
      <category>Program/C#</category>
      <author>사막여유</author>
      <guid isPermaLink="true">https://opencv-master.tistory.com/190</guid>
      <comments>https://opencv-master.tistory.com/190#entry190comment</comments>
      <pubDate>Mon, 9 Dec 2024 23:50:24 +0900</pubDate>
    </item>
  </channel>
</rss>