<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발왕 양선규</title>
    <link>https://yskisking.tistory.com/</link>
    <description>개발, 금융, 사업/경영 등 다양한 분야의 솔직한 기록을 남깁니다.</description>
    <language>ko</language>
    <pubDate>Mon, 15 Jun 2026 02:10:59 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>양선규</managingEditor>
    <image>
      <title>개발왕 양선규</title>
      <url>https://tistory1.daumcdn.net/tistory/5450102/attach/18472d3518a2495c963275ca091e87f5</url>
      <link>https://yskisking.tistory.com</link>
    </image>
    <item>
      <title>[Seedle] 0. 가치를 심다, 씨들(Seedle)</title>
      <link>https://yskisking.tistory.com/377</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;인생 첫 사업을 시작했다. 사실 사업이라기엔 아직 거창할 지도 모른다. 그저 아이디어를 떠올리고, 프로토타입을 만들었을 뿐이다. 예전엔 코딩하는 게 너무 재밌었으나, 사업가 입장에서의 개발은 생각보다 지루한 작업이라고 느껴졌다. 왜냐하면 경영을 위해 신경써야 할 수많은 것들 중에서 개발은 극히 일부이니 말이다. 특히 설계문서를 그대로 클로드 코드에게 맡기고 엔터, 검수, 엔터, 검수 하는 작업은 생각보다 집중력을 엄청나게 흐트러뜨리는 작업이었다. 클로드가 작업을 수행하는, 짧게는 1~2분에서 길면 20~30분 동안 나는 좁은 방 안을 붕붕 떠다녔다. 그 시간에 책을 읽으니 조금 나았지만, 두 작업을 번갈아 하는 것이 영 즐겁진 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 이 블로그에 나의 사업 일지를 작성하려고 한다. 개발 일지가 아니라 사업 일지다. 물론 개발 내용도 가끔 올라가겠지만, 내가 씨들을 어떻게 키워나가는지 또는 어떻게 말아먹었는지를 상세히 기록하고 누구나 참고할 수 있게 할 것이다(여기엔 미래의 나도 포함이다).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;씨들이 한번에 성공할 것이라 기대하지 않는다. 그렇다고 해서 이미 망한 사업인 것 마냥 대충 휘둘러댈 생각도 없다. 이것은 아마도 내 수많은 실패 중 하나가 될 테지만, 진정으로 몰입해 본 경험만이 실패를 실패가 아니라 작은 성공으로 만들어 줄 것이란 걸 나는 안다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=====&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;어떤 문제를 발견했는가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 AI시대이며, 누구나 창업할 수 있는 대(&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;大)&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;/span&gt;창업 시대다. 개발자가 아닌 사람도 프롬프트 몇 줄로 제품을 만들고, 디자이너가 아닌 사람도 디자인을 한다. 기존에 사람이 해야 했던 수많은 반복작업들, 그리고 특별한 전문성이 필요했던 일들은 대부분 AI가 수행할 수 있다. 즉, 이것은 많은 인력 없이도 1인 창업 또는 소규모 창업이 가능하다는 것을 의미한다. 그리고 실제로 그렇게 되고 있다. &lt;b&gt;매일매일 새로운 제품이 쏟아져 나온다&lt;/b&gt;. 아이디어만 있으면 누구나 제품을 만들 수 있다. 그것도 아주 쉽게!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 그렇게 만들어진 수많은 제품과 아이디어는, 본인만 알거나 주변 소수의 사람에게만 알려지고 잊혀진다. TV에 나오는 가수나 연예인들은 그들의 분야에서 상위 1%이지만, 우리가 보는 연예인은 그들이 전부이며 &lt;b&gt;나머지 99%는 존재조차 알려지지 않는다&lt;/b&gt;. 그 99% 중에 도대체 얼마나 많은 재능인들이 있을 것인가? 발견되지 못한 원석들 말이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 이론은 여기에 기초한다. 아무리 훌륭한 제품을 만들었더라도, 소비자들이 그 제품의 존재조차 모른다면 아무런 소용이 없다. 즉 어떻게든 존재를 알려야 한다. 그럼 어떻게 알릴 것인가? 고객을 유치하려면 광고나 홍보를 해야 할 텐데, 현재 한국의 &lt;b&gt;광고 시장은 연예인과 마찬가지로 매우 극단적으로 나뉘어져 있다&lt;/b&gt;. 첫번째는 대형 플랫폼에 거액을 주고 광고를 거는 것, 두번째는 인스타, 블로그, 영업 등이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전자는 매우 큰 돈이 든다. 이제 막 사업을 시작하는 사람에게 돈이 있을 리 만무하다. 만약 있다고 하더라도, 거액을 들여 광고 효과를 보지 못한다면 그것또한 엄청난 리스크이다. 가장 효과적이지만, 가장 비싸고 가장 위험하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후자는 돈이 전혀 들지 않는다. 시간만 있으면 된다. 그러나 꾸준해야 하며, 수동적이고, 지속하기 힘들다. 리스크가 없지만, 그만큼 기대 효과도 낮다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 현재 우리는 제품을 알리기 위해서:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 거액의 돈을 들이거나&lt;br /&gt;2.매우 귀찮고 아무 효과도 없을지도 모르는 일을 해야 하는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것은 분명한&amp;nbsp;&lt;b&gt;광고 시장의 양극화 문제&lt;/b&gt;이며, &lt;b&gt;좋은 제품을 만들어도 알릴 방법이 없다&lt;/b&gt;는 의미가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;어떻게 해결할 것인가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 문제는 두가지였다. 첫번째는 돈이 많이 든다는 것, 두번째는 귀찮고 기대 효과가 낮다는 것이다. 그래서 나는 광고에 &lt;b&gt;돈이 들지 않으며, 매우 쉬운 방법&lt;/b&gt;을 제공하기로 했다. 돈이 들지 않고 쉽기까지 하다면, 하지 않을 이유가 없지 않겠는가? 설령 효과가 낮다고 한들, 광고를 게재한다고 해서 그들이 손해 보는 건 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 내가 고안한 것은 &lt;b&gt;광고 플랫폼&lt;/b&gt;이다. 이것은 직장인이든, 1인 기업가든, 스타트업이든 그 누구라도 제품 광고를 무료로 올릴 수 있다. 귀찮은 사업자 인증 같은 건 필요 없다. 그저 텍스트 몇 줄과 이미지 몇 장이면 된다. 또한 대형 플랫폼에 거금을 내거나, 블로그 또는 인스타에 귀찮게 매일 글을 올리지 않아도 된다. 무료로 쉽게 광고를 올릴 수 있으니 올리지 않을 이유가 없고, &quot;일단 올려보자&quot;가 가능해지며, 거기서 뜻밖의 기회를 찾을 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;씨들(Seedle) - 나의 첫 브랜드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 세상에 드러나지 않은 수많은 제품과 가치들, 그것을 &quot;씨앗&quot;이라고 정의했다. 씨앗은 영어로 Seed이고, 비슷한 어감의 예쁜 단어를 찾아 보니 Seedle로 정하게 되었다. 전체적인 어감이 부드러우면서도, 한국어로 씨들(씨앗들) 이라는 뜻도 되고, &quot;씨&quot;라는 발음이 강해 사람들에게 기억되기 쉽다는 장점이 있다. 꼭꼭 숨어있는 씨들을 찾아 세상에 심어 꽃 피우게 하는 것, 그게 씨들의 스토리이며 방향성이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;어떻게 만들 것인가?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;SaaS 웹 서비스&lt;/b&gt; 형태로 만들 것이다. 가장 무난하고, 접근하기 쉬운 형태라고 생각한다. 핵심 요소인 &quot;무료로 쉽게 광고를 게재한다&quot;는 철학은 반드시 유지할 것이며, 현재 기획한 수익 구조는 광고이다. 솔직히 기술적으로 만들기 어려운 부분은 없다. 필요한 핵심 기능은 광고 게재, 조회, 추천, 랭킹 정도일 것이며 일반적인 커뮤니티와 철학만 다를 뿐 기술적으로 다를 것은 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선은 핵심 기능만을 제공할 생각이지만 추후 사용자가 모인다면, 사업가들이 모이는 플랫폼인 만큼 사업가 네트워크를 만들면 어떨까 한다. 이들은 서로 사업에 대한 인사이트를 공유하고 얻어갈 수 있게 될 것이며, 이렇게 구축된 네트워크는 기술 중심 서비스가 아닌 씨들에게 있어 견고한 해자가 되어줄 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예상되는 문제점과 해결 방안&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무료 사이트인 만큼 품질 관리가 핵심이다. 아무런 제재도 하지 않고 방치한다면, 불법 사이트처럼 불건전한 글이 난무할 가능성이 높다. 그 누구도 불법 사이트에 자신의 제품을 홍보하고 싶지 않을 것이다. 따라서 나는 &lt;b&gt;진입장벽은 낮되, 신뢰도는 유지하는 전략&lt;/b&gt;을 펼쳐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 씨들은 소셜 로그인을 강제하여 디지털 실명제를 실현할 것이다. 본인의 이름을 걸고 더러운 글을 게시할 사람은 별로 없다. 또한 AI 필터를 도입해 불건전 게시글을 1차 필터링하고, 신고제를 도입해 누적 신고를 받은 사람은 제재할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;가장 큰 고민과, 풀어야 할 숙제들&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 고민이다. 지금 생각으로는, 홍보만 잘 된다면 유입이 분명히 있을 것이라 생각한다. 왜냐면 무료고, 비슷한 플랫폼이 한국에 없으며, 자신의 제품을 쉽게 홍보할 유일한 수단이니까! 하지만 이건 매우 희망적인 생각이고, 정말 놀라울 만큼 아무도 관심이 없을지도 모른다. 만약 그렇게 되면 나는 어떻게 해야 할까? 어떻게 초기 고객들을 유치해야 할까? 이벤트를 생각해 보긴 했지만, 내겐 이벤트를 개최할 자금도 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 고민은 내가 가지지 못한 능력이다. 그건 바로 프론트엔드 개발, 디자인, 마케팅, 광고 등이다. 프론트엔드 개발은 어떻게든 AI 로 하고 있긴 하지만, 디자인/마케팅/광고 이런 쪽은 정말 문외한이고 재능도 없다. 씨들은 기술력이 아니라 무료 광고라는 컨셉으로 먹고 사는 서비스이기에, 이러한 세일즈 영역이 매우 중요하다. 뭐 어쩌겠나, 책을 읽든 유튜브 강의를 보고 따라하든 해야 할 일이다. 개발만 죽어라 하다가 사업을 하려니, 내가 회사라는 것이 어떻게 돌아가는지에 대해 전혀 모르고 있었다는 생각만 계속해서 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;씨들 개발 현황&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;880&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ldgCt/dJMcah5TeMF/2rTnpWci2KXbqBhHe1P5Bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ldgCt/dJMcah5TeMF/2rTnpWci2KXbqBhHe1P5Bk/img.png&quot; data-alt=&quot;씨들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ldgCt/dJMcah5TeMF/2rTnpWci2KXbqBhHe1P5Bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FldgCt%2FdJMcah5TeMF%2F2rTnpWci2KXbqBhHe1P5Bk%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;640&quot; height=&quot;737&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;880&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;씨들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 로그인, 제품 게시/조회, 댓글/대댓글, 최신순/인기순 정렬 등의 최소 기능을 가진 MVP를 만들어둔 상태다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=====&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;가치를 심다, 씨들(Seedle)&lt;/i&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>사업/씨들(Seedle)</category>
      <category>AI</category>
      <category>Seedle</category>
      <category>광고 플랫폼</category>
      <category>무료 광고</category>
      <category>무료 광고 사이트</category>
      <category>사업</category>
      <category>서비스</category>
      <category>스타트업</category>
      <category>씨들</category>
      <category>씨들(Seedle)</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/377</guid>
      <comments>https://yskisking.tistory.com/377#entry377comment</comments>
      <pubDate>Sun, 14 Jun 2026 21:24:55 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 슈퍼노멀: 재능 없는 자도 강제로 성공시키는 가장 직접적인 사업 방법론</title>
      <link>https://yskisking.tistory.com/376</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슈퍼노멀3.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rHqZR/dJMb99NlLsl/HqXdEC3RnVtMGDKQf48QBK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rHqZR/dJMb99NlLsl/HqXdEC3RnVtMGDKQf48QBK/img.jpg&quot; data-alt=&quot;슈퍼노멀 (커버O)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rHqZR/dJMb99NlLsl/HqXdEC3RnVtMGDKQf48QBK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrHqZR%2FdJMb99NlLsl%2FHqXdEC3RnVtMGDKQf48QBK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;585&quot; height=&quot;780&quot; data-filename=&quot;슈퍼노멀3.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;슈퍼노멀 (커버O)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;슈퍼노멀2.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUKgl6/dJMcabxEhoG/Qz8V3kDIRxYUFF79UpXYck/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUKgl6/dJMcabxEhoG/Qz8V3kDIRxYUFF79UpXYck/img.jpg&quot; data-alt=&quot;슈퍼노멀 (커버X)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUKgl6/dJMcabxEhoG/Qz8V3kDIRxYUFF79UpXYck/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUKgl6%2FdJMcabxEhoG%2FQz8V3kDIRxYUFF79UpXYck%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;585&quot; height=&quot;780&quot; data-filename=&quot;슈퍼노멀2.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;슈퍼노멀 (커버X)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;총평: ★★★★★ (5/5점)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재능이 없더라도, 금수저가 아니더라도 누구나 꾸준히 실천만 하면 반드시 성공할 수 있는 &quot;슈퍼노멀&quot; 프로세스. 이는 몇 단계로 이루어진 간단한 방법론이며, 내가 읽은 그 어떤 책 보다도 직접적인 실행 방법을 알려주는 책이었다. &quot;부의 추월차선&quot;은 독자에게 왜 사업을 시작해야 하는지를 알려주고 기회를 주는 책이었다면, 슈퍼노멀은 그것을 실제로 어떻게 실행해야 하는지를 담고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모방과 분해로 시작하여 실력과 운의 영역을 나누고, 어떤 노력을 어디에 부어야 하는지, 어떻게 하면 가장 높은 확률로 성공에 도달할 수 있는지를 담고 있는 이 책은, 무엇부터 해야 할지도 몰랐던 나에게 있어 지금 당장이라도 사업을 시작할 수 있겠다는 영감을 주었다. 슈퍼노멀 프로세스는 단언컨대 그 누구라도, 초등학생이라도 지금 당장 실행할 수 있는 매우 직접적이고 심지어 쉬운 사업 방법론이다. 이 책을 읽고 나서 당신에게 남는 것은, 머릿속에 있는 그 생각을 당장 실행하는 일 뿐일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;도서 정보&lt;/h2&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;제목: 슈퍼노멀&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;출판사: 웅진지식하우스&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;지은이: 주언규&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;분량: 255p&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;난이도(Easy / Normal / Hard): &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Easy&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;추천 여부(Yes / No): &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;Yes&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;&quot;&gt;==========&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;고찰&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;대단한 재능도 없고, 금수저도 아니지만 성공하고 싶은가? 그렇다면 &quot;슈퍼노멀 프로세스&quot;를 따라가라. 이것은 재능 없는 그 누구라도 따라할 수 있는 아주 쉽고 간단한 방법론이다. 당신과 비슷한 재능을 가진 돌연변이를 모방하라. 프로세스를 분해하고, 실력의 영역과 운의 영역으로 나눠라. 실력의 영역엔 당신의 노력을 아낌없이 붓고, 운의 영역은 최소한의 자원을 들여 최대한 많이 도전하라. 그 과정에서 만나는 실패는 실패가 아니라 성공을 향한 &quot;작은 성공&quot;이며, 그것이 쌓일수록 당신은 성공에 가까워진다. 한 번에 모든 걸 걸지 마라. 꾸준히 도전하고, 실패하고, 실력을 키워라. 그렇게 아집스럽게 성공에 다가가라.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&quot;슈퍼노멀이란?&quot;&lt;/span&gt;&lt;/blockquote&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;을 뜻한다. 정규분포표 상에서 얇긴 하지만 가장 얇진 않은, 평범함의 범주에 있지만 그들 중 가장 뛰어난 이들을 말한다. 이들은 이재용 회장이나 젠슨 황처럼 완전한 &quot;슈퍼&quot;는 아니지만, 그 어떤 일반인이 봐도 성공했다고 보여지는 이들을 뜻한다. 이 기준은 사람마다 다르겠지만, 저자는 자산이 수십억~수백억 정도인 사람을 지칭하는 것으로 보인다. &quot;슈퍼&quot;가 되기 위해선 엄청난 재능이나 능력이 반드시 필요하지만, 슈퍼노멀은 그 누구라도 노력한다면 도달할 수 있다. 그리고 그것을 가능케 하는 것이 슈퍼노멀 프로세스다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;1단계: 모방 (돌연변이를 발견한다)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당신이 사업을 시작하지 못하는 이유는 무엇인가? 재능이 없어서인가? 시간이 없나? 그 이유가 무엇이든 그건 중요치 않다. 당신은 당신과 비슷한 한계를 가진, 그러면서도 엄청난 성과를 낸 &quot;돌연변이&quot;를 찾아야 한다. 재능이 없어도 직장에 다니며 시간을 쪼개 엄청난 성과를 낸 돌연변이를 어떻게든 찾아내고, 그를 모방해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떻게 모방하는가? 나와 비슷한 조건을 갖춘 이 사람이, 도대체 어떤 점이 달라서 이런 성과를 냈는지를 눈에 불을 켜고 찾아야 한다. 유튜브로 예를 들면 제목이 특이하거나, 썸네일이 눈에 띄거나, 편집을 잘했다거나 등의 차이점이 있을 수 있다. 뭐가 어찌 되었든 간에 성과에 대한 이유는 반드시 있다. 내가 그 사람에 비해 뭐가 부족한지, 이 사람의 차별점은 도대체 무엇인지를 어떻게든 찾아낸다. 그리고 그것을 모방하되, 완전히 같게 하지 말고 약간의 차별점을 부여하라. 예컨대 돌연변이의 작품이 &quot;분당에서 집값이 폭락한 아파트&quot; 였다면 지역을 강남으로 바꿔서 영상을 만드는 식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완전히 처음부터 모든 걸 혼자서 공부하고 해내려면 매우 오랜 시간이 걸리겠지만, 이미 성과를 증명한 돌연변이를 모방하는 것은 매우 쉽고, 심지어 효과적이다. 굳이 비효율적인 방법을 사용할 필요가 없다. 모방을 통해 시장에 빠르게 스며들고, 약간의 차별화를 통해 개인의 경쟁력을 갖추면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;우리는 공포를 느끼는 방향을 바꿔야 한다&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 무엇이든 도전하고, 부딪히고, 실패해 봐야 한다. 아무것도 하지 않으면 아무것도 변하지 않는다. 지금 당신이 꼴찌라면, 앞으로도 계속 꼴찌일 것이다. 도전하라. 실패는 &quot;작은 성공&quot;이고, 그 자체만으로 성공에 가까워질 수 있다. 실패하는 것 보다 아무것도 시도하지 않는것이 더 큰 리스크다. &lt;span&gt;우리는 실패에 공포를 느낄 것이 아니라, 아무것도 시도하지 않고 하루가 지나가는 것에 공포를 느껴야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;2단계: 분해 (운과 실력을 분해한다)&lt;/span&gt;&lt;/blockquote&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&gt;돌연변이를 찾았는가? 모방해 보았는가? 그렇다면 이제 분해할 차례다. 당신이 원하는 그 일에 대한 첫 단계부터 마지막 단계까지의 프로세스를 최대한 세세히 나열하라. &quot;이게 뭐가 중요하겠어?&quot;싶은 부분도 아주 낱낱이 말이다. 그러고 나서 &quot;실력의 영역&quot;과 &quot;운의 영역&quot;으로 구분하라. 예컨대 실력의 영역이란 팔씨름처럼 실력이 성공 여부를 가르는 영역을 말하고, 운의 영역이란 로또처럼 운이 성공 여부를 가르는 영역을 말한다. 만약 운의 영역에서 성공하겠다고 열심히 공부하거나 학습한다면 엄청난 시간 낭비일 것이다. 그러한 노력은 실력의 영역에 퍼부어야 한다.&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&gt;나는 무언가를 이루고자 할 때 올바른 방향으로 노력을 해야 한다고 믿어왔다. 즉 &quot;효율적인 노력&quot;을 해야 한다는 것이다. 예를 들어 근육의 크기를 키우고 싶은데 매일 런닝머신을 3시간씩 뛴다면 그만큼 무의미한 노력도 없을 것이다. 죽을 만큼 힘들겠지만, 목표에 가까워질 수는 없다. 나의 이 생각과 저자가 언급한 &quot;분해&quot;는 완전히 같진 않으나 비슷한 맥락을 갖고 있는 듯 보인다. 인간이 투자할 수 있는 시간과 노력은 한정되어 있다. 그 자원을, 가장 비용 효율적인 곳에 투자하는 것은 매우 당연하며 중요하다. 그렇기에 그것을 위한 준비과정인 &quot;분해&quot;는 반드시 필요한 단계이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;3단계: 실력의 영역을 정복한다&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI로 아무리 많은 서비스를 양산한다고 해도, 제품으로 인정받을 최소한의 실력조차 없다면 그것은 무의미하다. 최소한 소비자에게 인정받을 정도의 퀄리티는 되어야 도전하는 의미가 있다. 코딩으로 예를 들면, 최소한의 코딩 실력이 있어야 웹이든 어플이든 오류 없이 서비스되는 제품을 만들 수 있을 것이다. 물론 이제는 AI가 코딩을 해주니 AI를 공부해야 하려나? 어쨌든 최소한의 퀄리티를 이끌어낼 실력은 반드시 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 운의 영역을 실력으로 정복하겠다고 시간을 투자하면 안 된다. 예를 들어 영업을 해야 하는데 제안서 잘 쓰는 법을 논문 쓰듯 연구하고 있으면 성과가 나오겠는가? 영업은 최대한 많은 사람을 만나는 게 가장 중요하고, 고빈도 전략이 필요하므로 실력의 영역보단 운의 영역에 가깝다. 기가 막힌 제안서를 써 봐야, 결국 고객이 필요로 하지 않으면 아무 소용이 없는 것이다. 반대로, 우리의 제품이 필요했던 고객에겐 특별히 노력하지 않아도 계약을 따낼 수 있다. 따라서 일단 고객을 많이 만나 봐야 하는데, 방에 틀어박혀 글쓰기 연구만 하고 있다면 그만큼 무의미한 일도 없을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 한 가지 중요한 게 있다. 실력을 극한으로 끌어올리겠다고 아무런 도전도 하지 않으면 안 된다. 개발로 예를 들면 개발 실력이 수익을 좌우하지 않는다. 유튜브 영상의 경우도 완전히 발로 찍은 것 같은 영상이 엄청난 조회수를 기록하기도 한다. 지금 당장 중요한 것은 실력을 극한으로 올리는 게 아니라, &quot;최소한의 실력&quot;을 갖추었으면 일단 결과물을 시장에 내보이는 것이다. 혼자서 재야의 고수처럼 몰두하는 것 보다, 일단 제품을 내놓고 고객의 피드백을 받는 것이 훨씬 낫다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;4단계: 빈도를 극단적으로 높인다 (운의 영역)&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 아는 성공한 사람들은, 대부분 수많은 실패를 겪으며 성장해 그 자리까지 올라갔다. 그들의 자서전을 보면 아주 힘든 시절을 이겨낸 내용이 클리셰처럼 담겨 있다. 내가 나중에 자서전을 쓴다면 나도 그럴 것 같다. 어쨌든 단 한 번에 성공한 사람은 없다는 것이다. 세계 50대 고전 음악의 목록엔 베토벤의 작품이 5곡 들어있다. 그런데 베토벤이 평생 쓴 곡은 무려 650곡이다. 집계된 게 이 정도이니 실제론 훨씬 많을 것이다. 희대의 천재 베토벤도 무려 650번을 도전해 겨우 5번 성공했다. 그렇다면 우리는? 평범한 노멀인 우리가 한 번의 실패를 두려워해서야 되겠는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운의 영역은 고빈도 전략으로 정복해야 한다. 즉 최대한 많이 시도해서, 성공을 위한 트리거가 될 사건을 만날 확률을 수학적으로 높이는 것이다. 아무리 낮은 확률이라도 여러 번 도전하면 한번은 성공하지 않겠는가? 자, 그러면 여기서 의문이 생긴다. 사업에 실패했는데 다시 도전하는 건 &quot;부의 매트리스&quot;를 가진 부자들이나 가능한 일이다. 그들이야 돈이 많으니 여러 번 실패해도 괜찮지만, 우리는 한번 실패하면 인생이 끝장날 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 어떻게 해야 하는가? 한 번의 도전에 들어가는 비용을 줄이는 것이다. 전 재산을 걸고 50%확률로 성공하거나 실패하는 게임이 있다면, 나는 절대 하지 않을 것이다. 그러나 전 재산이 아니라 단돈 만 원으로 게임을 할 수 있다면? 나는 그 게임을 계속 할 것이다. 성공할 때까지 말이다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이것이 어떻게 가능한가? 옛날에야 사업을 한번 시작할 때 전 재산을 투자해 인생을 걸고 해야 했지만, 인터넷과 SNS가 발달한 지금, 특히 AI까지 발달한 지금은 그야말로 거의 무(無) 리스크로 사업에 도전할 수 있다. 앞으로는 더욱 더 그럴 것이다. 유튜브 영상을 찍어 올리든, 인스타그램에 피드를 올리든, 또는 웹 사이트나 어플을 개발해 출시하든 시간만 투자하면 도전할 수 있는 사업이 얼마든지 있다. 빠르게 도전하고, 빠르게 실패하자. 심지어 반복되는 실패에서의 소중한 경험은 갈수록 내 성공 확률을 높여줄 것이다. 어렵지 않다. 계속해서 도전하면 언젠가 성공한다. 리스크를 줄이고, 고빈도 전략을 적극적으로 활용하자.&lt;/p&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;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;슈퍼노멀, 그 이상으로..&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;끝없는 도전 끝에 슈퍼노멀이 된 당신. 이젠 어떻게 해야 할까? 단순히 돌연변이를 모방하고, 프로세스를 만들고, 그것을 반복하는 것만으로는 분명 언젠가 한계에 부딪힌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째로, 이젠 전문가가 필요할 때이다. 우리 회사의 병목 또는 막혀버린 창의성을 뚫어주고 새로운 시각으로 사업을 바라보는 전문가 말이다. 자문을 받거나, 또는 경력직 직원으로 고용할 수도 있다. 슈퍼노멀 프로세스의 초창기엔 내가 만든 프로세스를 철저히 똑같이 실행해줄 성실한 사람이 필요했다면, 이젠 내가 가지지 못한 전문성을 가진 인재가 필요할 때이다. 그는 조직을 새로운 시각으로 바라보고 병목 현상을 해결해 줄 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째로, 네트워크를 구축할 때이다. 사업의 한계를 결정짓는 가장 중요한 요소는 네트워크라고 해도 과언이 아니다. 이를 위해서는 내가 잘되면 그들이 잘되고, 그들이 잘되면 내가 잘되는 선순환 구조를 만들어야 한다. 새로운 영감과 기회를 제공하고 정보가 원활히 공유되는, 그러면서도 같은 목적을 가진 사람들끼리의 네트워크를 만들면 내 영향력과 그들의 영향력이 함께 증가할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 저자는 &quot;인생은 팀플레이&quot;라는 프로젝트를 만들었고 팀을 이루어 협업하게 했다. 또한 좋은 결과물을 낸 사람을 본인의 채널에 출연시켰고, 그렇게 저자 본인과 출연자, 그리고 네트워크를 함께 성장시켰다. 그들이 그들의 목적을 이루기 위해 노력하면 네트워크가 커지고, 내 영향력도 증가한다. 서로가 서로에게 도움이 되는 일석이조 구조인 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;빨리 가려면 혼자 가고, 멀리 가려면 함께 가라&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혼자서는 빨리 갈 수 있다. 그러나 결코 멀리 가지는 못 한다. 인간은 절대로 완벽할 수 없으며, 잘 하는 게 있다면 못 하는 것도 분명히 있다. 따라서 훌륭한 조직을 구축하기 위해선, 나에게 없는 능력은 타인을 통해 채워야 한다. 그렇게 조직은 점점 탄탄해지며, 더욱 멀리 갈 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사업을 시작하는 사람에게 있어 매우 직접적으로 도움이 되는 내용이라 좋았다. 저자는 본인 피셜 아주 평범한 사람이다. 또한, 슈퍼노멀이지만 아직 &quot;슈퍼&quot;는 아니다. 그러나 그가 완벽한 사람이 아니기에 이 책은 더욱 가치있다. 너무 뛰어난 사람은, 본인이 그것을 어떻게 잘 하는지 모른다. 노래를 잘 하는 사람에게 &quot;어떻게 그런 고음을 내냐&quot;고 물어보면 보통 이런 식이다. &quot;그냥 하면 되는데?&quot;, &quot;입을 크게 벌려&quot; 등. 오히려 재능이 뛰어나기 때문에 잘 하기 위해서 노력해 본 적이 없고, 그렇기에 남들에게 알려줄 것이 없는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 특별한 재능이 없었던 사람이 썼기에 오히려 가치있다. 주언규라는 사람은 평범한 재능을 가지고도 슈퍼노멀이 되었고, 그 방법을 독자들에게 생생히 전달했다. 그리고 그는 앞으로도 더욱 발전하려는 듯 보인다. 월급 160만원으로 사회생활을 시작하여 악착같이 그 자리까지 올라간 주언규 씨에게 경의를 표하며, 그의 겸손에 경의를 표한다. 또한 피 터지게 도전해서 얻어낸, 그토록 아깝고 소중한 경험을 아낌없이 나눠준 점에 대하여 다시 한 번 경의를 표한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>독서/자기계발(사업, 경영)</category>
      <category>사업</category>
      <category>성공하는법</category>
      <category>슈퍼노멀</category>
      <category>슈퍼노멀 독후감</category>
      <category>슈퍼노멀 리뷰</category>
      <category>슈퍼노멀 주언규</category>
      <category>슈퍼노멀 프로세스</category>
      <category>슈퍼노멀 후기</category>
      <category>주언규</category>
      <category>주언규 신사임당</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/376</guid>
      <comments>https://yskisking.tistory.com/376#entry376comment</comments>
      <pubDate>Thu, 4 Jun 2026 22:41:19 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] (술술 읽히는) 군주론: 살기 위해 죽이는 것은 정말로 나쁜가? - 군주론은 생존론이다</title>
      <link>https://yskisking.tistory.com/375</link>
      <description>&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ejbB9c/dJMcaarYH4G/V7rfQeuxmbhPKAE5RlOJyK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ejbB9c/dJMcaarYH4G/V7rfQeuxmbhPKAE5RlOJyK/img.jpg&quot; data-alt=&quot;군주론 (커버O)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ejbB9c/dJMcaarYH4G/V7rfQeuxmbhPKAE5RlOJyK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FejbB9c%2FdJMcaarYH4G%2FV7rfQeuxmbhPKAE5RlOJyK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;560&quot; height=&quot;747&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;군주론 (커버O)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yWpkp/dJMcageDBGR/q5xcz4ClmR1nfaFtgiXadk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yWpkp/dJMcageDBGR/q5xcz4ClmR1nfaFtgiXadk/img.jpg&quot; data-alt=&quot;군주론 (커버X)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yWpkp/dJMcageDBGR/q5xcz4ClmR1nfaFtgiXadk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyWpkp%2FdJMcageDBGR%2Fq5xcz4ClmR1nfaFtgiXadk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;557&quot; height=&quot;743&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;군주론 (커버X)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;총평: ★★★★★ (5/5점)&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;니콜로 마키아벨리가, 피렌체 공화국의 요직에 복귀하기 위해 자신의 군주에게 바친 책. 군주는 권력을 위해 악(배신, 악행, 학살 등)을 저지를 필요도 있다는 지극히 현실적인 주장 때문에, 한때 교황청에서 금서로 지정되기도 하였다(금서로 지정해 놓고 자기들끼리 돌려 읽었다고 한다). 군주가 권력을 유지하고 국가를 안정적으로 운영함에 있어 필요한 자세나 방법들을, 성악설에 근간해 매우 현실적인 관점에서 풀어냈다. 그러나 저자는 백성에게 자비나 관용이 아예 필요 없다고 말하지 않는다. 권력을 유지하고 국가를 안정적으로 운영함에 있어, 선과 더불어 악도 필요하다면 행해야 한다는 뜻에 가깝다.&lt;br&gt;&amp;nbsp;&lt;br&gt;군주론은 불편할 수 있는 진실을 솔직하게 풀어냈다는 점에서 높은 점수를 주었다. 이렇게 직설적인 내용은 필시 누군가의 불편함을 초래하기에, 사회적으로 매장당하거나 오해를 사기 쉬운데도 지극히 현실적인 관점에서 설득력 있게 풀어냈다. 이 책이 명저로 꼽히는 건 불편함을 넘어설 정도의 실용적 내용이 책에 담겨 있기 때문이라고 생각한다. 항상 선한 군주는 필시 권력을 잃는다. 군주는 그 자리를 유지하기 위해 필요하다면 악행이라도 저지를 수 있어야 한다. 그것이 군주 자신에게도, 군주가 관리하는 조직의 번영에도 유리한 길이기 때문이다. 만약 선만으로 조직을 이끌 수 있다고 주장하는 자가 있다면 그는 위선자이거나, 자신을 그렇게 포장하여 백성의 민심을 사 군주의 자리를 노리는 인간일 것이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;군주론이 조금 더 극단적으로 느껴지는 이유는 시대적 배경의 차이일 것이다. 1500년대 이탈리아 반도에선 전쟁이 매우 흔했다. 침략하고, 영토를 빼앗고, 반란을 일으키고, 권력을 빼앗는 것 말이다. 권력을 잃는다는 것은 곧 죽음을 의미했다. 빼앗지 않으면 뺏긴다. 죽이지 않으면 죽는다. 그런 사실 때문에 현대의 우리가 읽기엔 조금 과하거나 맞지 않다고 느껴질 수도 있지만, 형태만 달라졌지 지금도 보이지 않는 전쟁은 계속되고 있다. 인간이란 동물이 조직 생활을 하도록 설계된 이상, 군주론은 시대 무관하게 통하는 이론일 것이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;==========&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;도서 정보&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;제목: 술술 읽히는 군주론&lt;br&gt;출판사: HCbooks&lt;br&gt;지은이: 니콜로 마키아벨리 (Niccolo Machiavelli)&lt;br&gt;분량: 235p&lt;br&gt;&amp;nbsp;&lt;br&gt;난이도(Easy / Normal / Hard): &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Easy&lt;/b&gt;&lt;/span&gt;&lt;br&gt;추천 여부(Yes / No): &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Yes&lt;/b&gt;&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #333333;&quot;&gt;==========&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;고찰&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;군주 본인과 국가의 생존 관점에서, 조직을 어떻게 이끌어야 하는지 매우 솔직하게 풀어냈다. 일부는 조금 과하거나 잔인하게 느껴질 수도 있겠지만, 나에겐 생존을 위해 불가피한 선택으로 보였다. 죽이지 않으면 죽는다. 빼앗지 않으면 빼앗긴다. 인간에게 있어, 아니 모든 생명체에게 있어 자기 자신의 목숨이 1순위인 이상, 군주론이 명저라는 사실은 시간이 지나도 변함없을 것이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(친절하게 대하거나, 말살하거나)&lt;/span&gt;&lt;br&gt;군주는 권력을 위협하는 세력을 아예 자기 편으로 만들거나, 확실히 처단해야 한다. 중요한 점은 처단을 실행할 때, 애매한 행동으로 복수당할 여지를 만들면 안 된다는 것이다. 예컨대 두려움을 각인시켜 복수는 꿈도 못 꾸게 하거나, 아예 재기 불가능하게 말살시켜 버려야 한다. 물론 말살은 꼭 필요한 경우에만 행해야 하며, 이유 없이 피를 보는 군주는 곧 미움을 사고 미움은 권력을 잃게 하기에 신중해야 한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(군주는 권력을 유지하는 것이 1순위이다)&lt;/span&gt;&lt;br&gt;군주는 권력을 유지하는 것이 1순위이다. 권력을 잃는다는 것은 곧 죽음을 의미하며, 이를 위해선 필요하다면 비도덕적인 수단도 사용할 줄 알아야 한다. 또한 군주는 모두를 만족시키려고 하면 반드시 권력을 잃게 되는데, 그 이유는 인간은 모두 다르기에 모두를 만족시키는 것이란 불가능하며, 이것을 이루겠다고 애매한 태도를 취하게 되면 오히려 모두에게 미움받고 경멸당하기 때문이다. 따라서 군주는 자신의 권력 유지에 도움이 되는 자들을 우선적으로 챙겨야 하는데, 예를 들어 군(병사들)의 힘이 강한 국가라면 군에게 좋은 처우를 해야 하고, 백성의 힘이 강하다면 백성에게 좋은 처우를 해야 한다. 모두를 만족시키는 건 불가능하다. 실제로 현 정치에서도 특정 정당이나 성향을 가진 정치인들이 그렇지 않은 자들보다 압도적으로 많이 당선되는 것을 볼 수 있다. 이도 저도 아닌 군주는 누구에게도 사랑받지 못한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(군주는 인자하게 &quot;보여야&quot; 한다)&lt;/span&gt;&lt;br&gt;백성들이 보기에 군주에게 필요한 역량은 인자함, 자비, 베품, 관용일 것이다. 백성에게 베풀며 그들의 삶을 평안하고 호화롭게 해주는 군주라야 올바른 군주라고 할 수 있을 것이다. 그러나 그것은 불가능하다. 백성에게 계속해서 베풀면 국고는 거덜난다. 그러면 세수를 늘릴 수밖에 없는데, 처음엔 베풀다가 갑자기 재산을 빼앗아 가면 백성은 오히려 반발심을 느낀다. 그런 말 많이 들어 보지 않았는가? 10번 잘하다가 한 번 못하면 욕먹고, 10번 못하다가 1번 잘하면 칭찬받는다는 말 말이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;심지어 인간은 자신에게 이득을 안겨준 자는 금방 잊으며, 반복되는 호의를 당연하게 생각하는 경향이 있다. 따라서 군주는 인자한 것처럼, 자비로운 것처럼 &quot;보여야&quot;할 필요가 있다. 그런 이미지를 만들되, 실제로는 국가의 안녕을 위해 냉정하게 운영할 줄 알아야 한다. 이로 인해 받을 미움은, 가능하다면 여론을 꾸며내 다른 사람에게 넘길 필요마저도 있다. 군주는 언제나 두렵고, 인자하고, 능력 있으며, 고결한 존재로 보여야 한다. 이로 인해 국가가 안정적으로 운영된다면, 백성은 군주를 오히려 더 존경할 것이다. 베풀기만 하는 군주는 존재할 수 없다. 그렇기에, 그렇게 보이는 것이 더 중요하다. 어차피 군주의 실제 모습이나 성향은 군주의 최측근을 제외하고는 백성이 알 길 조차 없다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(인간은 과거의 일보다 현재의 일에 몰두한다)&lt;/span&gt;&lt;br&gt;인간은 현재 자신의 삶이 안락하다면 군주가 누구든 아무래도 상관없어한다. 군주가 자신들을 불행하게 한다면 반란을 도모할 것이고, 무력으로 권력을 빼앗은 매우 비도덕적인 군주라 할 지라도 자신들에게 도움이 된다면 반드시 지지할 것이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(군주는 &quot;선&quot;만으로는 반드시 파멸한다)&lt;/span&gt;&lt;br&gt;군주가 &quot;선&quot;만 추구할 경우, 그렇지 않은 사람들에 의해 반드시 몰락한다. 군주는 필요에 의해 선 또는 악을 적절히 행할 수 있어야 한다. 그렇기에 악을 행해야만 권력을 지킬 수 있는 상황이 온다면, 반드시 그리해야 한다. 만약 모든 사람이 선하다면 이 전제는 잘못되었겠지만, 인간은 근본적으로 악하기 때문에 이는 성립할 수 있다. 이건 생존이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(군주는 두려움을 받되 미움받아선 안된다)&lt;/span&gt;&lt;br&gt;군주는 완전히 선할 필요가 없지만, 미움을 받는 것은 가능하다면 피해야 한다. 즉 군주는 두려움의 대상이 될 필요가 있지만, 미움받는 대상이 되어선 안된다. 어려워 보이지만 이는 양립 가능한 요소다. 예를 들어, 백성이 법을 어기거나 죄를 저질렀을 때 강력한 처벌을 하지만, 평소에 나쁜 행위를 하지 않는 경우에 가능하다(&lt;span style=&quot;color: #333333;&quot;&gt;백성의 재산을 빼앗거나 세금을 과하게 물리는 등)&lt;/span&gt;. 인간은 두려움을 느끼는 존재에겐 복수할 생각을 못 하지만, 미워하는 존재에겐 반드시 복수하기 때문이다. 특히 자신의 재산이나 가족을 빼앗은 경우엔 더욱 그렇다. 만약 누군가 굳게 마음을 먹는다면, 제아무리 군주라 할 지라도 화살을 피할 수는 없다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(군주의 능력을 판단하려면, 그의 최측근을 보라)&lt;/span&gt;&lt;br&gt;인재를 등용하기 위해선 인재를 보는 눈이 필요하다. 또한, 인간은 본능적으로 자신보다 능력 있는 리더를 따른다. 만약 군주 측근에 뛰어난 자가 있다면, 군주는 그보다 더 뛰어날 확률이 높다. 또한 인간은 끼리끼리 어울리는 경향이 있다. 외향적인 사람들은 외향적인 사람끼리, 조용한 사람은 조용한 사람끼리 만나는 것처럼 말이다. 이러한 현상은 현대 사회에서도 흔하게 관찰되며, 이는 인간이 비슷한 존재에게 편안함을 느끼도록 설계되었기 때문이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(시대에 맞는 능력을 타고난 자가 승자이다)&lt;/span&gt;&lt;br&gt;대담함이 필요한 시기엔 대담한 자가 성공하며, 신중함이 필요한 시기엔 신중한 자가 성공한다. 시대적 상황에 맞는 적절한 재능을 타고난 자가 성공을 이룬다는 뜻이다. 그러나 마키아벨리는 선택해야 한다면 신중하기보단 대담한 편이 낫다고 주장한다. 아무것도 하지 않으면 아무것도 바뀌지 않기 때문이다. 무언가라도 시도한 자가 변화를 만들며, 이는 현시대에도 통용되는 이론이다. 끊임없이 도전하고 실패로부터 배우는 자는 성공에 가까워지지만, 아무것도 하지 않는 자는 아무것도 변화시킬 수 없다. &lt;span style=&quot;color: #666666;&quot;&gt;(어제와 똑같이 살면서 다른 내일을 꿈꾸는 것은 정신병 초기증세이다 - 알버트 아인슈타인)&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;==========&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;(술술 읽히는) 군주론인 만큼 정말로 술술 읽히지만, 시대적 배경이나 인물에 대한 설명이 전무해 이해하기 어려운 부분이 있다. 그러나 배경을 몰라도 맥락을 보면 충분히 이해할 수 있기 때문에 큰 문제는 없었다. 예전에 벽돌책 &quot;국부론&quot; 에 도전하다가 200페이지 쯤 읽고 포기했던 기억이 너무나도 생생히 남아 있어 군주론은 조금 쉬운 버전으로 골라 봤는데, 더 두껍고 상세했어도 좋았을 것 같다. 시대적 배경이 다르기에 현대에 직접 적용하기 어려운 부분도 있지만, 전반적으론 어느 시대에서나 통용되는 군주의 자세를 잘 풀어냈다고 생각한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;사실 난 생존을 위해서라면 다소 냉정한 판단도 할 줄 알아야 한다는 생각을 자주 하기에 군주론이 크게 충격적이지는 않았다. 다소 잔인한 부분을 읽으면서도, &quot;본인이 살려면 저렇게라도 해야지&quot; 라는 식으로 오히려 공감했던 것 같다. 정말로 군주론을 읽어야 할 사람은 나같은 사람이 아니라, 마음씨가 아주 고와 개미 한 마리도 죽이지 못 하는 사람이나, 경쟁이 두려워 피하는 사람, 또는 온실 속의 화초처럼 평안한 환경에서만 지내온 사람일 것이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;군주론은 &lt;b&gt;생존론&lt;/b&gt;이다. 죽이지 않으면, 죽는다. 살기 위해 죽이는 것은 정말로 나쁜가? 당신은 &quot;적&quot;을 위해 목숨을 내놓을 텐가?&lt;/p&gt;</description>
      <category>독서/자기계발(사업, 경영)</category>
      <category>군주론</category>
      <category>군주론 리뷰</category>
      <category>군주론 비판</category>
      <category>군주론 생존론</category>
      <category>군주론 후기</category>
      <category>니콜로 마키아벨리</category>
      <category>독후감</category>
      <category>리더십</category>
      <category>마키아벨리</category>
      <category>생존론</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/375</guid>
      <comments>https://yskisking.tistory.com/375#entry375comment</comments>
      <pubDate>Mon, 1 Jun 2026 18:33:20 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 리더십 불변의 법칙: 영향력 있는 리더가 되기 위한 21가지 법칙</title>
      <link>https://yskisking.tistory.com/374</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;리더십 불변의 법칙.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6FKjN/dJMcafmsVRB/1G0NY4193SHLnX07USUilk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6FKjN/dJMcafmsVRB/1G0NY4193SHLnX07USUilk/img.jpg&quot; data-alt=&quot;리더십 불변의 법칙&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6FKjN/dJMcafmsVRB/1G0NY4193SHLnX07USUilk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6FKjN%2FdJMcafmsVRB%2F1G0NY4193SHLnX07USUilk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;522&quot; height=&quot;696&quot; data-filename=&quot;리더십 불변의 법칙.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;리더십 불변의 법칙&lt;/figcaption&gt;
&lt;/figure&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;총평: ★★★★★ (5/5점)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리더십 대가 존 맥스웰이 정의한 리더십 법칙 21가지를 정리한 책. 리더십이란 것은 단순히 나의 이득을 위하여 권위를 유지하고 아랫사람을 따르게 하는 능력이라 생각했던 내 생각을 부수고 넓혀주었다. 그는 목사 출신으로서 봉사, 헌신, 신앙을 강조하고 있기에 봉사에 관심이 없던 내 생각와 충돌하는 듯 했으나, 그것을 주장하는 근거가 매우 타당했기 때문에 받아들일 수 밖에 없었다. 그의 주장은 단순히 봉사만 하라는 것이 아니라, 진정한 리더십을 얻기 위해선 그것이 필요하다는 것에 가깝다. 짧게 정리하면 내 성공의 수준은 내 주변에 있는 사람의 수준에 의해 정의(제한)되며, 능력 있는 사람을 데려오기 위해선 나 자신이 더 능력 있는 리더가 되어야 하며, 그들에게 모범을 보이고 성장시켜 조직의 성과를 끌어올리고, 최후엔 그것을 승계하여 유산을 남김으로써 사람들에게 평가받고 그들의 마음에 영원히 남는다는 흐름이다. 즉 타인을 위해 봉사하는 것이 진정한 리더이며, 오히려 그렇게 하는 것이 본인을 더 훌륭한 리더로 만든다고 주장한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 돈을 많이 벌기 위한 목적으로 리더십 책을 찾은 나로써는 생각지도 못한 깨달음을 많이 얻었다. 특히 마지막 유산의 법칙에서 독자에게 &quot;당신은 무엇을 남기고 싶은가?&quot;를 물었을 때, 나는 한참을 생각했지만 아무런 대답도 할 수 없었다. 이 책에서 일관적으로 주장하는 것 중 하나는 &quot;누구나 훈련을 통해 훌륭한 리더가 될 수 있다&quot;이다. 21가지 법칙을 완벽히 수행하는 사람은 없으며(저자 본인마저도), 자신의 리더십 능력을 꾸준히 키우되 부족한 부분은 다른 사람을 통해 채울 수 있다고 주장한다. 내가 봐도 실제로 가능하다고 느껴지며, 각 법칙을 실천할 수 있는 방법까지 제공하기에 더욱 좋은 책이라 평가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;도서 정보&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제목: 리더십 불변의 법칙&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출판사: 비즈니스북스&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지은이: 존 맥스웰 (John C. Maxwell)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분량: 400p&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난이도(Easy / Normal / Hard): &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Easy&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추천 여부(Yes / No): &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;Yes&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;/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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 존 맥스웰이 정의한 리더십 법칙은 총 &lt;b&gt;21가지&lt;/b&gt;다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;1. 한계의 법칙&lt;/li&gt;
&lt;li&gt;2. 영향력의 법칙&lt;/li&gt;
&lt;li&gt;3. 과정의 법칙&lt;/li&gt;
&lt;li&gt;4. 항해의 법칙&lt;/li&gt;
&lt;li&gt;5. 덧셈의 법칙&lt;/li&gt;
&lt;li&gt;6. 신뢰의 법칙&lt;/li&gt;
&lt;li&gt;7. 존경의 법칙&lt;/li&gt;
&lt;li&gt;8. 직관의 법칙&lt;/li&gt;
&lt;li&gt;9. 끌어당김의 법칙&lt;/li&gt;
&lt;li&gt;10. 관계의 법칙&lt;/li&gt;
&lt;li&gt;11. 이너서클의 법칙&lt;/li&gt;
&lt;li&gt;12. 권한위임의 법칙&lt;/li&gt;
&lt;li&gt;13. 모범의 법칙&lt;/li&gt;
&lt;li&gt;14. 수용의 법칙&lt;/li&gt;
&lt;li&gt;15. 승리의 법칙&lt;/li&gt;
&lt;li&gt;16. 모멘텀의 법칙&lt;/li&gt;
&lt;li&gt;17. 우선순위의 법칙&lt;/li&gt;
&lt;li&gt;18. 희생의 법칙&lt;/li&gt;
&lt;li&gt;19. 타이밍의 법칙&lt;/li&gt;
&lt;li&gt;20. 곱셈의 법칙&lt;/li&gt;
&lt;li&gt;21. 유산의 법칙&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;1. 한계의 법칙 - &lt;b&gt;리더십 역량이 한계를 결정한다&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공 수준은 (리더십 역량 * 능력)으로 정의된다. 즉, 능력이 8이어도 리더십 역량이 1이라면 8만큼밖에 성공할 수 없고, 능력이 5여도 리더십 역량이 10이라면 50만큼 성공할 수 있다는 논리이다. 이것이 성립하는 이유는 개인의 능력만으로는 큰 영향력을 발휘할 수 없기 때문이다. 뛰어난 리더십으로 사람들을 이끌어 자신의 영향력을 극대화해야 성공 수준이 올라가며, 능력이 다소 떨어지더라도 높은 리더십을 발휘하면 충분히 성공 수준을 끌어 올릴 수 있다. 생각해보면 그 어떤 성공한 기업이나 조직도 혼자 굴러가지 않는다. 리더십은 나의 영향력에 직접 관여하며, 이것은 성공 수준으로 직결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;2. 영향력의 법칙 - &lt;b&gt;리더십은 영향력 그 자체다&lt;/b&gt;&lt;/h4&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;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;3. 과정의 법칙 - &lt;b&gt;리더를 만드는 것은 사건이 아니라 과정이다&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리더십은 하루아침에 계발되지 않는다. 매일매일 노력해도 조금도 변하지 않는 것 처럼 보이기도 한다. 리더십은 분명히 학습할 수 있는 기술이지만, 빠른 시간 안에 늘지 않는다. 그러나 어느 순간 돌아보면 이미 충분히 성장해 있을 것이다. 심지어 리더십은 복리로 증가한다. 투자에서는 복리 효과를 누리기 위해 최소 7년~10년 정도의 저수익 구간을 거쳐야 하는데, 리더십도 마찬가지란 뜻이다. 꾸준한 노력의 과정이 리더십을 만들며, 그 결실인 사건(결과)는 단순히 그것을 확인하는 과정에 지나지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;5. 덧셈의 법칙 - &lt;b&gt;리더는 사람들에게 가치를 더한다&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;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;11. 이너서클의 법칙 - &lt;b&gt;나와 가장 가까운 사람들의 수준이 내 성공의 한계를 결정한다&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;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;12. 권한위임의 법칙 - &lt;b&gt;리더는 권한을 위임할수록 성장한다&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;p data-ke-size=&quot;size16&quot;&gt;이런 상황이 발생하는 이유는 두려움 때문이다. 본인만의 기술이나 권력을 타인에게 위임하면 자신의 권력이 없어진다고 생각한다. 그러나 이것은 하나만 알고 둘은 모르는 것이다. 언제까지 모든 일을 혼자 처리할 수 있다고 생각하는가? 본인의 기술을 알려주고, 충분히 가르쳤다고 생각되면 권한을 위임하라. 그리고 위임받은 사람이 또 다른 사람에게 위임하게 하도록 하라. 이것은 본인의 권력을 깎아먹는 행위가 아니라, 오히려 본인의 영향력을 2중 3중으로 전파하는 행위이다. 부가적인 효과로는 권한을 위임받은 사람은 책임감이 생겨 일에 더욱 열중하고 잠재력을 발휘할 수 있게 된다. 그러면 본인의 역량이 상승하고, 결과적으론 조직과 리더에 대한 충성심도 올라간다. 이를 통해 리더는 더 큰 그림을 그릴 수 있으며, 정말로 중요한 일에 몰두할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;14. 수용의 법칙 - &lt;b&gt;사람들은 비전보다 리더를 먼저 받아들인다&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번 영향력의 법칙과 비슷하지만 조금 다르다. 사람들은 리더의 능력이나 비전을 보고 따르지 않는다. 그럼 무엇을 보는가? 바로 &quot;리더&quot; 그 자체다. 사람은 리더라는 사람 자체를 수용해야 리더의 비전을 따른다. 그것을 위해선 먼저 사람들에게 모범을 보이고, 관심을 가지고, 신뢰를 쌓으며, 그들이 성장할 수 있게 도와야 한다. 능력은 말할 필요도 없다. 사람들은 리더가 자신을 진심으로 존중하고 가치를 준다고 느끼면 비전과는 관계없이 리더를 따른다. 비전에 의문을 가질 지언정 최소한 리더 자체를 부정하지는 않는다. 내 능력이 어떻고, 내 비전이 어떻고 하며 보잘 것 없는 권위를 이용해 강제로 따르게 하는 게 아니라 먼저 나라는 사람, 리더 자체를 수용하게 하라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;20. 곱셈의 법칙 - &lt;b&gt;조직을 성장시키려면 다른 리더를 양성하라&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀에 구성원을 1명 데려오면 1명만큼의 재능 또는 노력을 얻는다. 그러나 리더를 1명 데려오면 당사자뿐만 아니라 그가 영향력을 발휘하는 모든 사람의 재능과 노력을 얻을 수 있다. 그러나 뛰어난 리더를 데려오기란 어렵다. 우선 내가 그 리더보다 뛰어나야 하는 것이 첫번째다. 또한 능력 있는 구성원을 구하는 것부터가 어려운데, 거기에 뛰어난 리더이기까지 하려면 일단 절대적인 수 자체가 적다. 심지어 리더는 창업자 성향이 있어서 독자적인 사업을 할 확률이 높고, 그를 데려오기 위해선 내가 가진 능력과 비전이 뛰어나고 그에게 줄 수 있는 가치가 많다는 걸 입증해야 한다. 그러나 뛰어난 리더를 영입하는 데 성공하고 그에게 꾸준한 가치를 부여한다면, 그는 나를 떠나지 않을 것이고 훌륭한 동반자가 되어줄 것이다. 즉 곱셈의 법칙이라는 것은, 나라는 한 사람의 리더가 끼칠 수 있는 영향력의 한계를 넘어, 다른 리더를 양성함으로써 내 영향력을 곱셈으로 넓히는 방법이라고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;21. 유산의 법칙 - &lt;b&gt;위대한 리더는 세상에 승계자를 남긴다&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;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;정리하고 보니 더욱 좋은 책이었다는 게 느껴진다. 이 책이 더욱 위대한 이유는 이 법칙들은 어느 시대에서든, 어느 조직에서든 공통적으로 적용되는 법칙이라는 점이다. 리더십은 단순히 기업가에게만 적용되는 것이 아니라 가족, 친구, 어떠한 조직에서든 적용된다. 어떤 조직에서든 초기에 사람들은 본능적으로 리더를 찾는다. 여기서 리더란 리더십 능력이 가장 뛰어난 사람이다. (암묵적으로)리더가 정해졌다면 구성원들은 리더를 따르거나, 조직을 떠난다. 그리고 조직에서 리더의 말이나 행동은 더욱 높은 영향력을 갖는다. 그의 말이나 행동이 옳기 때문이라기보다는, 그가 &quot;리더&quot;이기 때문이다. 생물학적 &quot;서열&quot;이라고 표현해도 비슷하려나 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 아직 팀이나 조직을 이끄는 리더는 아니다. 정확히는 아직 그런 권위를 가지고 있지 않다. 그러나 이젠 누구를 만나든, 어떤 조직에서든 이 법칙들을 적용하려고 노력할 것이다. 그것이 내가 훗날 리더가 되기 위한 훈련이고, 과정의 법칙에서 언급했듯 리더는 한순간에 완성되는 게 아니니까. 이번에 배운 21가지 법칙은 내 인간관계와 성공을 향한 여정에서 다방면으로 도움이 될 것이다.&lt;/p&gt;</description>
      <category>독서/자기계발(사업, 경영)</category>
      <category>21가치 리더십 불변의 법칙</category>
      <category>경영</category>
      <category>독후감</category>
      <category>리더</category>
      <category>리더십</category>
      <category>리더십 불변의 법칙</category>
      <category>리더십 책</category>
      <category>사업</category>
      <category>자기계발</category>
      <category>존 맥스웰</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/374</guid>
      <comments>https://yskisking.tistory.com/374#entry374comment</comments>
      <pubDate>Tue, 26 May 2026 21:12:06 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 슈독(SHOE DOG): 위대한 기업가 필 나이트의 자서전 - 수많은 슈독들과 함께 지금의 나이키를 만들다</title>
      <link>https://yskisking.tistory.com/373</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2026-05-17-17-39-26 001.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MumDr/dJMcaaFmD4H/3OgpfTlNMAKdzS7SaX0cek/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MumDr/dJMcaaFmD4H/3OgpfTlNMAKdzS7SaX0cek/img.jpg&quot; data-alt=&quot;슈독 (커버 포함)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MumDr/dJMcaaFmD4H/3OgpfTlNMAKdzS7SaX0cek/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMumDr%2FdJMcaaFmD4H%2F3OgpfTlNMAKdzS7SaX0cek%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;549&quot; height=&quot;732&quot; data-filename=&quot;KakaoTalk_Photo_2026-05-17-17-39-26 001.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;슈독 (커버 포함)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2026-05-17-17-39-26 002.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d2yjYS/dJMcagFAbhV/3yARmpVpSWJo9QpKsPzm4k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d2yjYS/dJMcagFAbhV/3yARmpVpSWJo9QpKsPzm4k/img.jpg&quot; data-alt=&quot;슈독 (커버 제거)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d2yjYS/dJMcagFAbhV/3yARmpVpSWJo9QpKsPzm4k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd2yjYS%2FdJMcagFAbhV%2F3yARmpVpSWJo9QpKsPzm4k%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;549&quot; height=&quot;732&quot; data-filename=&quot;KakaoTalk_Photo_2026-05-17-17-39-26 002.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;슈독 (커버 제거)&lt;/figcaption&gt;
&lt;/figure&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;총평:&amp;nbsp;★★★★★ (5/5점)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위대한 기업가의 인생을 생생하게 체험할 수 있는 책. 필 나이트가 사업을 시작하게 된 계기와, 도중에 만난 수많은 문제들과 이를 해결한 과정들, 그리고 나이키의 성공에 필수적이었던 수많은 슈독들에 대한 이야기를 몰입감 있게 풀어낸다. 책의 마지막 챕터인 &quot;해질녘&quot;에서는, 마치 내가 직접 필 나이트가 되어 그의 방 안락의자에 누워 인생을 회고하는 듯 한 착각을 불러 일으키는 듯 했다. 위대한 인물의 삶을 간접적으로 체험할 수 있다는 것은 도대체 얼마나 높은 가치를 갖는가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 필 나이트의 자서전이자 회고이며, 나이키의 역사이며 정신이고, 꿈과 행복의 의미를 알려주는 교육서이며, 그에게 도움을 준 수많은 사람들을 향한 감사이자, 길을 걷는 수많은 사람들을 위한 봉사이다. 나는 이 책을 사업을 하는 사람, 하려는 사람, 또는 전혀 관심이 없을지도 모르는 남녀노소 누구에게나 추천한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;도서 정보&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제목: 슈독(SHOE DOG)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출판사: 사회평론&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지은이: 필 나이트 (Phil Hampson Knight)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분량: 553p&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난이도(Easy / Normal / Hard): &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;Easy&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추천 여부(Yes / No): &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;Yes&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;/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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 재미있다. 잘 쓰여진 소설을 읽는 것 처럼 말이다. 전혀 지루함이 없고, 마치 내가 필 나이트 본인이 된 것처럼 몰입해서 읽게 된다. 다 읽고 나서는 약간의 여운도 남았으며, 그것만으로도 5점을 줄 가치가 있다.&lt;/p&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: #666666;&quot;&gt;(자수성가 창업가의 단순한 자서전이 아니라, 수많은 사람과 세상에 전하는 감사)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위대한 기업의 시작이 아버지께 빌린 50달러였다는 얘기라던가, &quot;슈독&quot;이 진정한 기업가 정신을 보여주는 책이고 기업가의 필독서라던가 하는 자극적인 마케팅 문구들은 이 책을 완전히 잘못 소개하고 있다. 이 책은 감사를 전하는 책이며, 자신이 세상에게 진 빚을 갚는 책이다. 필 나이트는 자신이 평생토록 신세진 수많은 사람들에 대한 감사를, 자서전의 형태로 사회에 환원한다. 길을 걷는 사람들이 마주칠 수많은 문제를, 좀 더 쉽게 해결할 수 있도록 돕기 위해서 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그는 자서전에서 단 한번도 자신이 잘 해서 뭔가를 해냈다는 말을 하지 않는다. 그는 집행자였다. 자신이 정한 방향 대로 계속해서 나아가지만, 끊임없이 부딪히고 흔들렸다. 그럴 때 마다 그를 도운 건 수많은 슈독들이었다. 문제가 발생할 때마다 그는 누군가를 믿었고, 그 문제를 맡겼고, 믿고 기다려주었다. 그의 이러한 행위는 매번 문제를 해결케 했다. 그는 자서전 내내 누군가에게 감사하고 있었다. 감사하고, 감사하며, 책이 끝날 때 까지 감사해 했다. 어쩌면 이것이 그가 가진 기업가로서의 최고의 재능인지도 모른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(슈독의 의미)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;슈독&quot;은 어떤 의미일까? 단순하게는 신발에 미친 사람, 신발에 푹 빠진 사람일 것이다. 나는 필 나이트 본인이 슈독일 거라 생각했다. 그러나 그는 단순한 의미의 슈독은 아니었다. 그런 슈독은 그의 육상 코치이자 동업자인 바우어만 코치, 존슨, 또는 지암피에트로일 것이다. 필 나이트는 세상에 큰 영향을 끼치고 싶어 하는 도전적이자 반항적 기질의 인물이었고, 그것은 일본 오니쓰카(현 아식스)에서 타이거를 수입해 미국 시장에 판매하는 것으로 시작되었다. 그러나 그건 그의 &quot;미친 생각&quot;을 실현하기 위한 수단이었지, 그가 신발 자체에 미쳐 있는 것은 아니었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그는 책에서 가장 중요하다고 볼 수 있는 제목을 슈독이라 지었다. 이는 자신이 신세 진 수많은 슈독들에 대한 감사의 표현일 수도 있고, 또는 필 나이트가 슈독을 다르게 정의하는 것일 수도 있다. 만약 그렇다면 그가 생각하는 슈독의 의미는 &quot;무언가에 미친 사람&quot;일 것이다. 그러면 필 나이트 본인은 슈독이고, 자기 자신과 동료들, 그리고 세상의 수많은 사람들도 슈독이 될 수 있으며, 나도 슈독이 될 수 있다. 작가는 슈독이라는 단어가 좀 더 넓은 의미로 세상에 전달되기를 바라지 않았을까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(행복이 돈 자체에 있을까?)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;나이키의 첫 주식 공모가 끝나고 그에게 무려 1억 7800만 달러라는 돈이 생겼을 때, 그는 그다지 기뻐하지 않았다. 블루 리본 스포츠를 창업한 이후 약 16년 동안, 빚과 현금 사이에서 줄타기를 하며 파산의 위기에 수도 없이 빠졌었음에도 말이다. 이는 애초에 그의 목적이 돈이 아니었기 때문이었을까, 아니면 돈 자체가 행복을 의미하지 않기 때문일까?&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;&quot;&gt;그는 주식 공모가 끝났을 때 자신은 아무것도 변하지 않았는데 돈이 생겼다 라고 했다. 여기서 말하는 &quot;아무것도 변하지 않았음&quot;은 자신의 경영 능력, 신발에 대한 지식, 스스로가 느끼는 행복이나 만족감, 일에 대한 열정, 가족과의 관계 등 여러 가지를 의미할 것이다. 그는 이런 거금을 손에 쥔 바로 다음 날, 회사에 가장 일찍 출근해 일을 시작했다. 아무것도 변하지 않았는데 돈이 생겼고, 돈이 생겼는데 아무것도 변하지 않았다. 그에겐 결승선이 없었다. 아니, 어쩌면 결승선은 그 어디에도 존재하지 않을지도 모른다.&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;&quot;&gt;필 나이트만큼은 아니지만 엄청난 거금이 생긴 그의 동료들도, 그와 마찬가지로 돈이 생겼다고 크게 달라지지 않았다. 다만 변한 게 딱 하나 있다. 바로 돈에 얽매이지 않게 된 것, 즉 자유가 생겼다는 것이다. 그들은 이제 빚에 허덕이지 않으며, 밥을 굶지 않기 위해 매일매일 출근할 필요가 없다. 자선 사업에 뛰어들기도 하고, 자동차 따위가 아닌 경비행기를 타고 다니기도 하며, 자신만의 도서관을 짓고 시키지도 않은 도서 분류를 하며 사람들에게 24시간 개방하기도 했다. 즉 그들에게는 하기 싫은 것을 하지 않을 자유와, 하고 싶은 것을 할 자유가 생겼다. 아마도 소중한 사람과 함께할 자유도 말이다.&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;&quot;&gt;돈 자체가 행복은 아니다. 하지만 충분한 돈은 자유를 가져다 준다. 나는 지속되는 자유가 행복을 가져다 준다고 생각한다. 무언가에 얽매일 필요가 없는 마음의 평안과, 소소한 일상의 행복들 말이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;(사업가로서 배워야 할 점)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;그가 가진 최대의 능력은 크게 2가지라고 생각한다. 첫번째는 &quot;미친 생각(아이디어)&quot;을 실제로 시도하고 멈추지 않을 용기. 두번째는 그의 인적 자원 관리 능력이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;아이디어는 누구나 생각할 수 있다. 그러나 그것을 실제로 실행할 때 본인의 것이 된다. 필 나이트는 주저 없이 아이디어를 실행했고, 끝없이 밀어붙여 나이키를 성공으로 이끌었다. 있지도 않은 블루 리본이라는 회사를 오니쓰카 회의실에서 즉석으로 지어내거나, 기타미의 서류를 훔친 것처럼 가끔은 엉뚱하거나 도전적인 행동도 했다. 이것은 바보같지만, 분명 필요하다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 버트페이스도 인상적이다. 버트페이스는 일종의 임원 회의였는데, 그의 동료들과 함께 회사의 문제에 대해 토론하는 자리였다. 그런데 일반적인 회의와는 다르게 서로 비난과 조롱이 난무했으며, 격식이라고는 찾아볼 수 없는 자리였다. 서로 수치스러운 별명을 지어주고 놀리며 공격했다. 걸을 수 없어 휠체어를 타고 다니는 우델의 별명이 웨이트(Weight, 덤벨이나 바벨 같은)였으니 말 다 했다. 왜 웨이트 였냐면 계단을 오르내릴 때 휠체어와 함께 들어줘야 하니까. 그럼에도 불구하고 그들은 서로 어떠한 상처도 받지 않았다. 그런 회의는 당시에 그 어떤 회사에서도 찾아볼 수 없는 문화였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그랬기 때문에 버트페이스에서는 수많은 창의적인 의견이 나왔다. 서로 아무 거리낌 없이 멍청해 보이는 아이디어를 내세웠고, 서로를 비판했다. 그곳은 단순한 조롱의 장이 아니라, 엄청난 아이디어 창고였다. 버트페이스는 나이키가 가진 특별한 방향성이자, 필 나이트가 주도한 혁신이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;인적 자원 관리 능력은 사실 자서전에 직접적으로 쓰여 있지는 않았다. 그러나 그와 함께한 동료들은 하나같이 나이키에 충성했으며, 필 나이트를 완전히 믿고 따랐다. 필 나이트가 어떻게 그들을 충성하게 만든 건지는 자세히 나와있지 않다. 하지만 분명히 그에겐 그런 능력이 있었을 것이다. 본인이 인지하든, 인지하지 못 하든 말이다. 그의 동료들은 마치 자신의 일인 것처럼 최선을 다했다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;또한 그는 문제를 마주할 때마다 항상 누군가를 찾아가 도움을 받았다. 그가 온전히 혼자만의 힘으로 해결한 문제는 거의 없다. 항상 도움을 구했고, 누군가를 만났다. 그렇게 문제는 해결되었으며, 그의 아군이 계속해서 늘어났다. 만약 필 나이트가 밉상이었다면(말투, 센스, 성격 등 여러 방면에서) 그들이 나이트를 도와줬을까? 능력 있는 사람을 소개시켜 줬을까? 절대 아닐 것이다. 그에겐 그도 모르는 리더십이 있었을 것이다. 남들이 자신을 믿고 따르게 하는 리더십 말이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;기대와는 달랐던 부분&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 이 책을 골랐던 이유는 사업의 성공 방법을 알고 싶었기 때문이다. 나에겐 생생한 성공 레퍼런스가 필요했다. 필 나이트가 얼마나 힘든 환경에서, 얼마나 혹독한 문제들을 만났고 어떻게 해결했는지, 그에겐 도대체 어떤 특별함이 있었는지를 알고 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아버지께 빌린 50달러로 사업을 시작하여 트렁크에 신발을 싣고 팔러 다녔다는 이야기를 보고, 나는 그가 굉장히 불우한 환경에서 자수성가한 인물인 줄 알았다. 그리고 그에겐 그 상황을 타파할 특별한 재능이 있을 거라 기대했다. 그러니까 나는, 그가 좀 더 힘든 환경을 이겨낸 줄 알았고 더 많은 난관을 만났을 줄 알았다. 아니 그렇게 기대했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 그는 상당히 유복한 가정에서 자랐다. 그의 아버지는 변호사였으며, 그가 살던 오리건 주에서 저명한 인물이었다. 1950~60년대에 필 나이트는 오리건 대학교를 졸업하고 스탠퍼드 대학교에서 MBA 석사 과정을 밟았다. 심지어 그가 사업을 시작하기 전 세계 여행을 떠날 때, 아버지께 세계 여행 비용까지 지원받았다(이 세계 여행에서 일본을 방문해 오니쓰카를 만나 계약했다). 미국인의 90%가 비행기를 타보지도 않았던 시기에, 세계 여행 비용을 고민 없이 지원해줄 수 있는 반박의 여지가 없을 상류층 집안이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그는 엘리트 코스를 밟았고, 특히 사업 초기엔 아버지의 지원을 톡톡히 받았다. 책의 소개엔 빌린 50달러로 사업을 시작했다고 하지만, 50달러는 그가 오니쓰카에게서 첫 신발 샘플을 구매하기 위한 대금이었을 뿐이다. 그가 바우어만 코치와 사업을 시작할 때 각각 500달러씩 투자하기로 했는데, 이때 투자한 500달러도 아버지께 빌린 것이었다. 또한 사업 초기에 오니쓰카의 신발을 수입해 올 때도 아버지에게 수차례 돈을 빌렸다. 즉, 그의 사업은 아버지의 지원이 없었다면 시작도 못 했을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 그의 사업은 &quot;이래도 되나?&quot; 싶을 정도로 승승장구였다. 누군가 나에게 &quot;그의 사업이 성공한 이유는 무엇입니까?&quot; 라고 물으면, 초반에 수입했던 오니쓰카 신발의 품질이 좋았다 라고 밖에 말하지 못하겠다. 그러니까, 필 나이트만의 엄청난 특별함이나 위기 대처 능력 때문에 성공했다고 볼 수 있는 부분을 찾을 수 없었다. 블루 리본 초창기, 타이거를 수입해 판매할 때는 오니쓰카에서 물건을 떼다 팔았을 뿐이다. 또한 영업이나 소매점 운영은 존슨, 우델, 다른 영업사원들이 했고, 법적 대처는 자쿠아 변호사나 스트라세 등이 했으며, 제품 개발은 바우어만 코치, 존슨 등이 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블루 리본과 나이키는 분명 크고 작은 문제를 많이 만나긴 했지만, 그 어떤 위기 상황에도 매출이 줄어드는 일은 없었다. 매년 2배씩 성장했으니까 말이다. 또한 문제의 상당수는 필 나이트가 &quot;지금 성장을 멈추면 안 된다&quot;라는 생각에 현금을 확보하지 않고 끊임없이 무리한 금액을 대출해 사업 확장을 시도했기 때문에 발생했던 일이었다. 그는 문제를 방지할 수도 있었다. 진짜 생각지도 못한 위기라고 한다면, &quot;미국판매가격&quot; 사건에서 2500만 달러의 세금 고지서가 날아왔을 때 정도일까?&lt;/p&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, 고의로 숨긴 것이라면 이해가 된다. 그가 자기 자랑을 즐기는 성격으로 보이지는 않기 때문이다. 책 전반적으로 본인에 대한 칭찬은 없고 동료에 대한 칭찬과 감사뿐이다. 그는 일부러 나이키 성공의 공을 동료들에게 돌린 것일지도 모른다. 그가 좀 더 자기 자랑을 하는 성격이었다면 어땠을까?&lt;/p&gt;</description>
      <category>독서/자기계발(사업, 경영)</category>
      <category>SHOE DOG</category>
      <category>나이키</category>
      <category>나이키 설립자</category>
      <category>나이키 창업가</category>
      <category>독후감</category>
      <category>사업</category>
      <category>슈독</category>
      <category>슈독(SHOE DOG)</category>
      <category>필 나이트</category>
      <category>필 나이트 자서전</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/373</guid>
      <comments>https://yskisking.tistory.com/373#entry373comment</comments>
      <pubDate>Sun, 17 May 2026 20:15:53 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 부의 추월차선: 부자가 되고 싶은 당신은, 왜 그렇지 않은 자들과 똑같이 사는가?</title>
      <link>https://yskisking.tistory.com/372</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;부의추월차선.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rxeAM/dJMcaffv1l1/4Sm7YkAibaN8Km11vI28oK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rxeAM/dJMcaffv1l1/4Sm7YkAibaN8Km11vI28oK/img.jpg&quot; data-alt=&quot;부의 추월차선&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rxeAM/dJMcaffv1l1/4Sm7YkAibaN8Km11vI28oK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrxeAM%2FdJMcaffv1l1%2F4Sm7YkAibaN8Km11vI28oK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;552&quot; height=&quot;736&quot; data-filename=&quot;부의추월차선.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;부의 추월차선&lt;/figcaption&gt;
&lt;/figure&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;총평: ★★★★★ + ★ (6/5점)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 단순한 지식 이상의 가치를 지니며, 부자가 되는 상세한 방법을 가르쳐 주는 동시에 실제로 그 방법을 실행하고 싶게 만든다. 방법이 있는지도 몰랐던 자에게는 새로운 시야를, 알긴 알았지만 도전할 용기가 없던 자에게는 용기와 확신을 준다. 대부분의 인간은 부자가 되고 싶어하지만 여러 가지 이유로 시도조차 하지 않는다. 최악의 경우에는 돈에 대한 부정적 인식이 생겨 부자를 질투하거나, 방어기제로 인해 돈 자체를 악이라고 규정하기도 하며 그럴수록 부자가 될 가능성은 한없이 0에 가까워진다. 시도조차 해보지 않고 삶을 마감하는 것은 도대체 얼마나 초라한 일인가? 저자는 다양한 환경, 재능, 운, 또는 모종의 이유로 생긴 돈에 대한 부정적 인식과 핑계로 인하여 꿈을 마음속에 꽁꽁 숨긴 채 죽어가는 수많은 사람들에게 꿈에 도전할 기회를 부여한다. 자신이 직접 걸었던, &quot;부의 추월차선&quot;으로 안내하면서.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제목: 부의 추월차선&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출판사: 토트출판사&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지은이: 엠제이 드마코 (MJ DeMarco)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분량: 389p&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난이도(Easy / Normal / Hard): &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;Easy&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추천 여부(Yes / No): &lt;b&gt;&lt;span style=&quot;color: #409d00;&quot;&gt;Yes&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: #000000;&quot;&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;span style=&quot;color: #000000;&quot;&gt;고찰&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;흡입력이 대단한 책. 이 책을 읽고 있으면, 마치 이미 부자가 된 것 같은 기분에 휩싸인다. 내가 읽었던 모든 책들 중 가장 재미있게 읽은 책이며, 더 읽고 싶어서 손이 근질거릴 정도였다. 그래, 마치 판타지 소설을 읽는 것 같은 느낌일까? 그러나 이 책이 판타지 소설과 다른 점은 고작 상상 따위가 아닌 실화이고, 내가 그 주인공이 될 수 있다는 점이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;구매 당시, 난 이 책이 베스트셀러인지 몰랐다. 그저 국가에서 받은 지원금 유효기간이 다해 사라질까 봐, 동네 작은 서점에 급하게 달려가 산 4권의 책 중 하나였을 뿐이다. 책의 종류가 적어 선택권조차 없었으며, &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;제목과 자극적인 마케팅 문구를 보고선 &quot;자아도취에 쩔어 작성한 흔하디 흔한 책&quot;일 거라고도 생각했다. 별로 기대하지 않았기에, 4권 중 마지막으로 펼친 책이기도 하다.&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p 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: #666666; text-align: start;&quot;&gt;(6장: 부자처럼 보이는 것과 진짜 부자인 것의 차이)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;그러나 책을 펼치고 그런 생각은 곧 사라졌다. 저자는 &quot;부의 3요소&quot;를 자유, 관계, 건강 이라고 정의한다. 부를 이룬다는 것은 이 3가지를 충족한다는 의미인 것이다. &quot;돈&quot;이 많다고 해서 부자는 아니다. 돈을 부의 3요소 중 가장 중요한 &quot;자유&quot;를 얻는 데 있어 필수적인데, 자유를 얻을 경우 나머지 2가지 요소인 관계와 건강도 얻을 확률이 매우 높아진다. 즉 돈 자체가 부는 아니지만 부의 3요소를 만족하기 위한 가장 중요한 조건이라는 것이다.&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;돈만 있으면 행복할 것 같은가? 장담컨대, 한 달에 1억원을 벌고 매일 12시간을 일하는 사업가보다 한 달에 천만원을 벌고 하루에 4시간만 일하는 사람이 훨씬 행복할 것이다. 전자는 &quot;돈&quot;은 많지만 자유가 없으며, 가족(관계)과 함께할 시간이 없고, 과로로 인해 건강도 잃을 확률도 높다. &lt;span style=&quot;text-align: start;&quot;&gt;인간의 행복은 돈 자체에서 오지 않는다. 내가 일하고 싶을 때 일하고 쉬고 싶을 때 쉴 수 있는 자유와, 사랑하는 사람과 함께하는 소중한 시간과, 그것을 누릴 건강이 갖춰질 때 비로소 인간은 행복하며, 부를 이뤘다고 말할 수 있는 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;6장을 읽고 나도 부에 대한 정의를 조금 다르게 생각해 보게 되었다. 기존의 난 통제받고 싶지 않았고, 남의 밑에 있거나 아쉬운 소리를 하는 게 싫었고, 모두가 부러워할 무언가를(돈, 명예, 자동차 등) 얻고 싶었고, 내가 남들보다 뛰어나다는 걸 인정받고 싶었으며, 그걸 벤틀리라는 자동차로 현실화하여 증명하고 싶었다. 뭔가 목표가 있긴 했지만 명확히 정의하긴 어려웠는데, 결국 내가 원하는 건 &quot;자유&quot;였다는 것을 깨달았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;(12장: 당신이 부의 길이라고 믿었던 것들의 함정)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에 내가 알고 있던 부를 향한 방법들은 다음과 같다. 내재가치를 상승시켜 연봉을 올리고(학위, 경력, 자격증 등), 회사에서 더 많은 월급을 받고, 그걸 투자해서 20년간 복리의 마법을 거치면 부자가 될 수 있다는 것이었다. 지금부터 20년이면 50살이고, 그 때 벤틀리를 탈 수 있다면 나쁘지 않을 거라 생각했다. 그래서 난 어떻게든 좋은 회사에 들어가고 싶었고, 개발자로서 개발 실력을 올리려 했고, 자격증을 땄고, 대학원도 가려고 했다. 이 모든 것들은 나의 내재가치를 끌어올려 더 좋은 회사에 들어가 더 많은 연봉을 받기 위함이었다. 저자는 이를 &quot;서행차선&quot; 이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 말이다. 경력을 쌓고 자격증을 따고 석사 학위를 받으면, 내 연봉이 얼마나 오를까? 10%? 20%? 20%가 올랐다고 해보자. 내가 투자한 몇 년의 시간이 연봉 20%와 맞바꾸어 진다면 만족할 것인가? 그럼 무엇이 바뀌는가? 벤틀리를 살 수 있나? 가족과 함께할 시간이 늘었는가? 아니다. 나는 여전히 주 5일을 일하고 2일을 쉴 것이다. 심지어 내재가치를 올리기 위해 투자한, 퇴근 후와 주말의 시간에 대한 기회비용은 어떡할 것인가? 내가 20년간 죽어라 일하고 은퇴했을 때, 후회 없는 20년을 보냈다고 자신있게 말할 수 있나? 그동안 빼앗긴 자유와, 꿈에 도전하지 않음에 대한 자괴감은 어떡할 것인가? 나는 그때 정말로 행복할까? &lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;(하루에 8시간씩 열심히 일하다 보면 결국엔 사장이 되어 하루 12시간씩 일하게 될 것이다. - 로버트 프로스트)&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;연봉과 투자소득은 내가 통제할 수 없는 수단이다. 가장 큰 문제는 두 가지 모두 &quot;시간&quot;을 필요로 한다는 것이다. 내 연봉은 시간당 급여 * 근무시간으로 계산된다. 나에게 주어진 시간은 하루 24시간이고 내가 늘리거나 통제할 수 없으며, 시간당 급여 또한 회사가 올려 주기를 희망할 뿐이다. 투자는 또 어떤가? 장기 투자와 복리의 핵심은 바로 &quot;시간&quot;이다. 복리의 마법은 시간 위에 유효하며, 최소 20년 이상이 걸린다. 인간의 수명이 무한하지 않은 이상 이것도 통제할 수 없는 것이다. 심지어 이자율도, 수익률도, 내가 투자한 회사의 흥망성쇠도, 펀드 매니저도 내가 통제할 수 없다. 내 수익을 전부 남에게 맡겨 버리는 것이다. 그저 맡겨놓고, 소중한 자유 시간을 버리며, 내 소득이 늘기를 희망한다.&lt;/p&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 내가 가진 시간 중 최대한 많은 시간이 행복하기를 희망하지, 은퇴 후 일부만 행복하기를 희망하지 않는다. 난 특별함을 원하고, 더 큰 행복을 원한다. 내 부를 이뤄줄 수동적 소득을 창출할 시스템을 구축하기 위해 나는 응당 내 젊음을 투자할 의향이 있고, 그렇게 될 수 있다고 믿는다. 진정으로 내가 원하는 것은 직장이 아니라 그곳에 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;(24장: 가중평균 의사결정 매트릭스)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;저자는 어릴 적 아이스크림 가게 앞에서 우연히 자동차 한 대를 보았다. 그 차는 바로 &quot;람보르기니 카운타크&quot;였으며, 방에 차 사진을 잔뜩 걸어 놓을 정도로 원했던 그의 드림카였다. 그때 다가왔던 차 주인. 그는 젊은 남자였고 20대 중반 정도였다. 너무 젊었기 때문에 아이는 그의 직업이 금수저거나 운동선수 정도일 거라 생각했지만, 그는 발명가였다. 발명가 말이다. 금수저나 유명한 운동선수가 아니어도, 젊은 나이에 불경스러울 정도로 멋진 자동차를 탈 수 있다는 사실을 아이는 깨달았다. 엠제이 드마코의 추월차선을 향한 여정은 그때부터 시작되었다.&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;&quot;&gt;아주 흔한 이야기이다. 남자아이가 자동차를 보고 그 차를 사고 싶다는 꿈을 갖는 것 말이다. 나도 거대한 BMW 7시리즈를 처음 보았을 때 부자가 되고야 말겠다는 꿈이 생겼다. 지금은 벤틀리로 바뀌었지만, 7시리즈를 처음 봤던 그 순간의 짜릿함 만큼은 아직도 생생히 남아있다. 그러나 흔한 이야기는 여기까지이다. &quot;사고 싶다&quot;에서 머무는 것과, &quot;반드시 사겠다&quot;로 이어져 실제로 실행하는 것은 하늘과 땅 차이다. 꿈을 갖는 것은 누구나 할 수 있으며, 대부분의 사람은 여기서 그친다.&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;&quot;&gt;정말로 사고 싶은가? 그렇다면 &quot;사고 싶다&quot;가 아니라 산다, 살 수 있다 여야 한다. 저자는 이것을 지각 선택과 행동 선택이라고 정의한다. 쉬운 예를 들자면 &quot;사람은 생각하는 대로 살아간다&quot;이다. 스스로의 생각이 사고 싶다는 희망에 묶여 있다면, 스스로 한계를 정한 것이고 이미 포기한 것이나 다름없다(지각 선택). 산다 또는 반드시 산다, 살 수 있다 따위여야 인간은 비로소 자신이 만든 한계에서 벗어나 실제로 행한다. 지각 선택에 의해 실제 행동이 좌우되는 것이다(행동 선택).&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;&quot;&gt;이 부분은 내가 굉장히 공감하는 부분이다. 자신이 가진 꿈을 24시간 내내 &quot;뇌&quot;라는 메모리에 올려 두고 절대 내리지 말아야 한다. 그럴수록 믿음은 더욱 강해지며, 실제로 꿈을 이루기 위한 계획을 세우고 행동하게 된다. 실제로 나도 &quot;벤틀리&quot;라는 꿈을 이룰 수 있다고 아주 강하게 믿으며, 실제로 가까워지고 있고, 이번에 &quot;부의 추월차선&quot;이라는 책을 통해 다시 한번 큰 폭으로 가까워졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;&lt;span style=&quot;color: #666666; text-align: start;&quot;&gt;(25장: 역풍으로 작용하는 사람들에게 등을 돌려라)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&quot;남들이 모두 맞다고 할 때, 아니라고 말할 수 있어야 한다&quot; 라는 말 들어 보았는가? 난 이 말에 굉장히 공감한다. 비논리적으로 들릴 수도 있겠지만, 남들과 다르게 살아야 부자가 될 수 있다. 대다수의 사람은 평범하다. 부자는 소수이며, 그렇기에 특별하다. 부자와 일반인의 마인드가 같을까? 같은 상황이 주어졌을 때, 그에 대한 판단이 같을까? 당연히 다르다. 대다수 사람과 똑같이 행동하면, 대다수 사람처럼 살게 된다. 너무나도 당연한 논리다. 부자가 되기 위해선 가끔 특별한 선택을 해야 한다. 그 선택이 당신을 미친 사람처럼 보이게 할 지라도 말이다. 그들은 말할 것이다. &quot;너는 미쳤어&quot;. 당신이 성공하면 그들은 말할 것이다. &quot;믿고 있었어&quot;.&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;&quot;&gt; 저자도 라이트 형제의 예를 들며 이 주제에 대하여 이야기한다&lt;span style=&quot;text-align: start;&quot;&gt;. 비행기가 발명되기 전, 인간이 하늘을 난다는 것은 너무나 당연하게 불가능한 것이었다. 이야기할 가치가 없을 정도로 말이다. 여기엔 기술적인 어려움도 있었겠지만, 그것이 절대 불가능하다고 믿는 아주 강력한 사회적 중력이 역풍으로 작용했기에 더욱 어려웠다. 그들이 어떻게 되었는가? 결국 최초로 비행기를 발명했고, 오늘날까지도 회자되는 전설적인 인물들이 되었다. 규모의 차이는 있겠으나 이것은 우리가 가려는 부자의 길과 크게 다르지 않다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;우리는 역풍&lt;span style=&quot;text-align: start;&quot;&gt;&amp;ndash;&lt;span style=&quot;color: #666666;&quot;&gt;당신을 이해하지 못하는 친구들과 가족들, 부는 다른 사람의 이야기일 뿐이라 말하는 사람들, 당신이 처한 환경 등&lt;/span&gt;&amp;ndash;&lt;/span&gt;으로부터 등을 돌려야 한다. 토요일 밤마다 술에 취해 정신을 잃는 마이크와 함께하겠는가? 쇼핑몰에서 도둑질하다 걸리고, 돈 많은 남자를 만나 시집갈 궁리만 하는 친구 루시와 함께하겠는가? 이들은 당신에게 있어 순풍인가, 역풍인가? 역풍에서 등을 돌려라. 역풍에서 벗어나라. 환경을 바꿔라. 관계를 바꿔라. 그것은 당신이 통제할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;비판적 시각&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;일반적인 대중들의 시각과는 완전히 다른 관점에서 이야기를 풀어 나가기 때문에, 당연히 비판도 많을 수밖에 없다. 이 책에 감명받은 나도 그러한 비판에 어느 정도 동의하는 바이지만, 그렇다고 이 책이 거짓을 말한다고 생각하지는 않는다. 간혹 비판을 넘어 무분별한 &quot;비난&quot;을 하는 글들도 많이 봤는데, 그들은 굉장히 불쌍한 존재들이다. 자신이 만든 한계에 갇혀, 부자들을 물어뜯으며 자신을 위로하고, 아무런 시도조차 하지 않은 채 죽을 때까지 부를 얻을 수 없을 테니.&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;b&gt;비판 1: 직업과 직업을 가진 사람들을 비하&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자는 &quot;직업은 한심하다&quot;라며 회사에 고용되어 주 5일을 일하는 사람들을 한심하다고 칭했으며, 실제로 그렇게 생각하는 것 처럼 보인다. 이건 명백한 잘못이 맞다. 꿈을 이루기 위해 미친 듯이 노력하고 결국 이뤄 낸 사람 입장에서는, 꿈을 가졌는데도 아무런 시도도 하지 않고 흘러가는 대로 사는 사람들이 한심하게 보일지도 모르겠다. 표현을 조금만 순화하면 어땠을까 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비판 2: 사업 리스크에 대한 언급이 없음&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자는 책에서 단 한번도 &quot;무조건 성공한다&quot;라고 직접 말한 적 없다. 그저 길을 안내할 뿐이다. 그러나 그의 확신에 찬 문체들이, 마치 그가 이 책을 따라하는 사람들은 모두 부자가 될 수 있다고 말하는 것처럼 느껴지기도 한다. 책에는 사업 리스크에 대한 내용이 없는데, 이럴 경우 일부 사람들이 &quot;무조건 사업을 하는 게 맞다&quot; 또는 &quot;사업만이 정답이다&quot; 라고 오해할 수 있다. 이는 실제로 일부 사람을 위험에 처하게 할 수 있는 부분이고, 비판받을 만 한 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 나는 반대 의견도 있는 게, 이 책의 진정한 가치는 &quot;꿈에 도전할 용기와 기회를 부여&quot;하는 데 있다고 생각한다. 만약 이 책이 사업에 대한 리스크를 구체적으로 언급하며, 직업과 사업 중에 정답이 없다는 주장을 펼치는 위선자 같은 책이었다면 이 책은 절대 이렇게 성공할 수 없었을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비판 3: 엠제이 드마코는 &quot;운&quot;으로 성공했다?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엠제이 드마코가 그의 인터넷 사업으로 대박을 터트린 시점은 1995년~2000년 사이의 &quot;닷컴버블&quot; 이었다. 따라서 누군가는 그의 성공은 단순히 &quot;운&quot;이며, 그의 조언은 누구나 할 수 있는 조언이고 타이밍이 좋았을 뿐이라고 하기도 한다. 이건 정말 기가 차는 비판인데, 난 이걸 정면으로 반박하고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;닷컴버블에 사업을 한 사람은 한 사람도 빠짐없이 모두 성공했는가? 정말로 &quot;운&quot;때문에 성공했고 그 &quot;운&quot; 이라는 게 닷컴버블 이라는 시대적 배경이었다면 그 때 사업을 한 사람은 모두 부자가 되었어야 한다. 또, 경쟁은 어떤가? 그가 사업을 시작할 때, 아무런 경쟁자가 없었을까? 어느 시대든, 어떤 사업이든 어떤 직종이든 반드시 경쟁자가 있다. 그는 어떤 부분에서든 경쟁자 중 가장 뛰어났기에 그런 성공을 거둔 것이다. 그는 끝없이 도전했고, 열심히 공부했고, 경쟁자를 이겼으며, 기회를 잡았다. 그래 뭐, 조금 양보해서 운이 좋았다고 치자. 운 없이 성공한 사람이 있긴 한가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 &quot;2026년에 사업으로 성공하는 것 보다 닷컴버블에 성공하는 것이 훨씬 쉬웠다&quot; 라고 한다면, 솔직히 아주 틀린 말은 아니다. 경제성장기엔 더 성공하기 쉽고 기회가 많은 것도 사실이니까. 그런데 말이다. 그럼 책의 내용도 &quot;거짓&quot;이라고 말할 수 있나? 이 책은 아무런 가치가 없는 종이쪼가리인가? 그렇지 않다면, 엠제이 드마코가 당신이 말하는 &quot;운&quot;으로 성공했다고 한들 당신이 이 책을 비판할 이유가 없는 것 아닌가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 부자가 되는 방법은 아주 단순하다고 생각한다. 마치 공부를 잘하는 방법과 같다. 수업 시간에 졸지 않고, 예습 복습을 철저히 하며, 책상에 엉덩이를 붙이고 하루에 12시간씩 문제집을 풀고, 이해가 되지 않는 것은 이해될 때까지 공부하면 된다. 방법이야 모르는 사람이 없다. 부자가 되는 방법도 마찬가지다. 물론 공부를 잘 하는 방법보다는 조금 복잡하겠지만 꾸준히 독서를 하고, 아이디어를 떠올리고, 그걸 직접 실행하고, 성공할 때까지 도전하면 된다. 리스크까지 관리할 수 있다면 더욱 좋고!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 부자가 되는 법은 &quot;마인드&quot;와 &quot;실행&quot;에 달렸다고 생각한다. 만약 부자가 되는 방법이 수학 올림피아드 문제처럼 아주 복잡하고 어려운 것이었다면 사람들은 이 책을 사지도 않았을 거고, 사서 읽더라도 이해하지도 못 했을 것이며 비판도 못 했을 것이다. &quot;부의 추월차선&quot;은 분명히 부로 향하는 좋은 정보와 새로운 시야를 제공하지만, 조금은 당연하게 느껴지는 이야기를 반복적으로 하기도 한다. 그래서 읽기 쉽고, 비판/비난하기도 쉽다. 일부 대중은 본인이 부자가 아닌 이유가, 본인이 시도조차 하지 않았기 때문이라는 걸 스스로 아주 잘 알고 있기 때문에 더욱 격분하며 비난하는 것 처럼 보이기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책의 진짜 가치는 &quot;꿈(부)에 도전할 용기와 기회&quot;를 부여하는 것이다. 방법은 어렵지 않다. 아이디어가 떠올랐다면 바로 실행하라. 실패했다면 다시 도전하면 된다. 실패에서 배워나가며 꿈을 향해 달려라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당신이 정말로 두려워 하는 것은 무엇인가? 사업에 실패하여 전 재산을 잃는 것인가? 아니면 나이 들어 허름한 병실에 누운 채로 &quot;왜 난 도전하지 않았을까&quot;라고 후회하며 눈감는 것인가?&lt;/p&gt;</description>
      <category>독서/자기계발(사업, 경영)</category>
      <category>독후감</category>
      <category>부의 3요소</category>
      <category>부의 추월차선</category>
      <category>부의 추월차선 리뷰</category>
      <category>부의 추월차선 비판</category>
      <category>부의 추월차선 후기</category>
      <category>부자 되는 방법</category>
      <category>사업</category>
      <category>엠제이 드마코</category>
      <category>창업</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/372</guid>
      <comments>https://yskisking.tistory.com/372#entry372comment</comments>
      <pubDate>Sat, 9 May 2026 21:06:47 +0900</pubDate>
    </item>
    <item>
      <title>개발왕 양선규 크래프톤 정글 인터뷰 출연하다 (유튜브: Jungle Dev Club)</title>
      <link>https://yskisking.tistory.com/371</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;981&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2nURG/dJMcacppKVn/hTBcJe52JJ3NTwDDzbX8mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2nURG/dJMcacppKVn/hTBcJe52JJ3NTwDDzbX8mk/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2nURG/dJMcacppKVn/hTBcJe52JJ3NTwDDzbX8mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2nURG%2FdJMcacppKVn%2FhTBcJe52JJ3NTwDDzbX8mk%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;981&quot; height=&quot;552&quot; data-origin-width=&quot;981&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크래프톤 정글 수료생 커뮤니티(유튜브 Jungle Dev Club)의 정글 인터뷰에 출연하게 되었다. 정글은 나를 개발자로 성장하게 해준 첫 번째 관문이자 훈련소였다. 나는 정글의 커리큘럼에 공감하고 실제로 그곳에서 많은 것을 얻어 왔기 때문에 정글에 대한 자부심이 있다. AI가 대신 코드를 짜는 지금 시대에, 도구가 아니라 CS를 깊게 파고드는 정글의 위상이 갈수록 높아지고 있다고 생각하던 차에 때마침 기회가 생겨 인터뷰를 하게 되었다.&lt;/p&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;990&quot; data-origin-height=&quot;559&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBJwlF/dJMcadPkckr/DB4qBiGh6aKlAt1FMRE941/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBJwlF/dJMcadPkckr/DB4qBiGh6aKlAt1FMRE941/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBJwlF/dJMcadPkckr/DB4qBiGh6aKlAt1FMRE941/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBJwlF%2FdJMcadPkckr%2FDB4qBiGh6aKlAt1FMRE941%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;990&quot; height=&quot;559&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;559&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/v3SsP/dJMcaf7t2a1/QtWyBvrcMNUjptBp9Tbmu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/v3SsP/dJMcaf7t2a1/QtWyBvrcMNUjptBp9Tbmu0/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/v3SsP/dJMcaf7t2a1/QtWyBvrcMNUjptBp9Tbmu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fv3SsP%2FdJMcaf7t2a1%2FQtWyBvrcMNUjptBp9Tbmu0%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;985&quot; height=&quot;558&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오랜 취업준비를 겪고 회사 생활을 하느라 정글에 대한 기억이 많이 잊혀진 상태였기에, 생생한 인터뷰를 위해 기억을 되짚는 시간이 필요했다. 다행히도 개발왕 양선규 블로그에 정글 당시 내 심정과 공부 내용을 적은 TIL과 회고들이 잔뜩 있었기에, 해당 글들을 읽음으로써 쉽게 기억을 떠올릴 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 보니 내가 잊고 있었던 &quot;정글에서 얻은 것들&quot;이 다시 기억나기 시작했다. CS 지식은 너무 당연하니 논외로 하고, 개인적으로 가장 큰 건 &quot;몰입 경험&quot;이었다. 나는 주에 100시간씩 5개월이라는 살인적인 스케줄을 인생에서 소화해 본 적이 없었기에 그걸 내가 버틸 수 있는지, 실제로 가능하긴 한 건지가 의문이었다. 기존의 나는 공부할 때 몸이 피로하거나 집중이 안 되거나, 무리한 것 같으면 잠을 자거나 쉬는 시간을 늘리곤 했다. 하지만 그게 내 신체의 최대 효율을 뽑아낸 건지는 확실치 않았으며 그걸 실험해 볼 기회도 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 그 실험을 정글에서 할 수 있었다. 초반 1개월정도는 심리적/신체적으로 정말 너무 힘들었는데, 점점 체력 관리 노하우가 생기고 적응이 되다 보니 어느새 익숙하게 버텨지더라. 나라는 인간은 잠 자는 시간만 빼고 365일 공부만 해도 멀쩡한 사람이었던 것이다. 이 깨달음은 정글 이후 내가 바쁠 때, 힘들 때 굉장한 도움이 되었다. &quot;정글보단 안 힘든데?&quot; &quot;정글은 이것보다 힘들었는데 멀쩡했잖아.&quot; 등으로 생각할 수 있었고, 흔들리지 않고 일이든 공부든 할 수 있는 원동력이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;팀장으로서 나만무 프로젝트와 크래프톤 정글을 마무리하며: &lt;a href=&quot;https://yskisking.shop/251&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/251&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777537510889&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;[크래프톤 정글 5기] 팀장으로서 나만무 프로젝트, 그리고 정글을 마무리하며..&quot; data-og-description=&quot;https://poke-code.com&amp;nbsp;드디어 나만무 프로젝트가 끝이 났다. 나만무 기간 하루하루가 정말 너무나도 힘들었기에 도중에는 시간이 너무 느리게 가는 느낌이었지만, 막상 발표를 마치고 나니 이게 끝&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/251&quot; data-og-url=&quot;https://yskisking.shop/251&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/34XYW/dJMb8Rj5ikE/2s388hXktI6wJ7rPza7BjK/img.png?width=800&amp;amp;height=428&amp;amp;face=0_0_800_428,https://scrap.kakaocdn.net/dn/cwgtwc/dJMb85vSjFW/N5fLYgYzRRHBkNGCLdmo1K/img.png?width=800&amp;amp;height=428&amp;amp;face=0_0_800_428,https://scrap.kakaocdn.net/dn/bZh8Tt/dJMb8U8WUVP/XDx1xqb5mG7aehjtN2rnrK/img.png?width=1901&amp;amp;height=1041&amp;amp;face=0_0_1901_1041&quot;&gt;&lt;a href=&quot;https://yskisking.shop/251&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/251&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/34XYW/dJMb8Rj5ikE/2s388hXktI6wJ7rPza7BjK/img.png?width=800&amp;amp;height=428&amp;amp;face=0_0_800_428,https://scrap.kakaocdn.net/dn/cwgtwc/dJMb85vSjFW/N5fLYgYzRRHBkNGCLdmo1K/img.png?width=800&amp;amp;height=428&amp;amp;face=0_0_800_428,https://scrap.kakaocdn.net/dn/bZh8Tt/dJMb8U8WUVP/XDx1xqb5mG7aehjtN2rnrK/img.png?width=1901&amp;amp;height=1041&amp;amp;face=0_0_1901_1041');&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;[크래프톤 정글 5기] 팀장으로서 나만무 프로젝트, 그리고 정글을 마무리하며..&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://poke-code.com&amp;nbsp;드디어 나만무 프로젝트가 끝이 났다. 나만무 기간 하루하루가 정말 너무나도 힘들었기에 도중에는 시간이 너무 느리게 가는 느낌이었지만, 막상 발표를 마치고 나니 이게 끝&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;556&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biQ4fG/dJMcahK2i4u/yaTZKscXOGLVRvrOHMr3o0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biQ4fG/dJMcahK2i4u/yaTZKscXOGLVRvrOHMr3o0/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 4&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biQ4fG/dJMcahK2i4u/yaTZKscXOGLVRvrOHMr3o0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiQ4fG%2FdJMcahK2i4u%2FyaTZKscXOGLVRvrOHMr3o0%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;984&quot; height=&quot;556&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;556&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 4&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;익숙하지 않은 C언어, 익숙하지 않은 자료구조, 익숙하지 않은 운영체제 PintOS. 모든 것이 낯선 환경에서 거대한 코드베이스를 가진 PintOS가 내뱉는 알 수 없는 오류를 스택트레이스 하나하나 훑어가며 디버깅 하는 과정들. 그 과정이 있었기에 난 정글 이후 취업한 메멘토AI에서도, KIDB에서도(아주 잠깐이었지만) 지금의 에이비스에서도 두려움 없이 코드를 파헤칠 수 있게 되었다. 정글에서의 대부분은 누군가 가르쳐 주는 사람 없이 스스로 공부하고 헤쳐나가는 과정이었기 때문에, 정답을 보지 않고도 특정 문제를 파고들고 원인을 추론하여 해결해낼 수 있는 능력이 길러졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정글 당시 최신 버전이 GPT4? 였었고, 그마저도 유료였어서 GPT 3.5만 사용했던 것으로 기억한다. 클로드 코드같은 것도 없었고 직접 복사 붙여넣기해가며 물어보며 활용했었다. 나는 정글 시기가 AI가 아직 날개를 펼치지 못했던 시점이라는 것에 감사한다. AI가 있긴 했지만, 그때까진 만능이 아니었고 환각도 심했기에 인간이 스스로 생각할 기회가 남아있었다(AI가 아예 없었더라면 더 좋았을 것 같다). 정글은 일터가 아니라 공부하고 성장하는 곳이기 때문에, 빠르게 결과를 생산해내는 것이 아닌 스스로 생각하고, 인지하고, 추론하는 &quot;과정&quot;이 매우 중요하다고 생각한다. 난 기초 체력을 확실히 기를 수 있었고, 그렇기에 일찍 정글에 간 것에 감사한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vfcWZ/dJMcacXeDha/AffkK984sFHhKTYzutueTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vfcWZ/dJMcacXeDha/AffkK984sFHhKTYzutueTK/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vfcWZ/dJMcacXeDha/AffkK984sFHhKTYzutueTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvfcWZ%2FdJMcacXeDha%2FAffkK984sFHhKTYzutueTK%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;985&quot; height=&quot;550&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 5&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;554&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpOh0k/dJMb997idNa/1pqGPjdvq0AGcSSTjGrgD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpOh0k/dJMb997idNa/1pqGPjdvq0AGcSSTjGrgD0/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 6&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpOh0k/dJMb997idNa/1pqGPjdvq0AGcSSTjGrgD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpOh0k%2FdJMb997idNa%2F1pqGPjdvq0AGcSSTjGrgD0%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;990&quot; height=&quot;554&quot; data-origin-width=&quot;990&quot; data-origin-height=&quot;554&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 6&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;어떤 기술을 써 봤냐는 건 누구나 할 수 있다&quot; 라는 말을 내 입으로 하게 될 줄은 몰랐다. 그러나 그건 &quot;기술을 왜, 어떻게 썼고 얼마나 개선되었냐를 수치로 써라&quot; 같은 뻔한 의미가 아니었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 말하고자 했던 건 AI로 인해 특정 기술에 대한 진입장벽이 거의 zero에 가까워졌기 때문에, 이제는 AI의 대답이 옳은지, 틀린지, 적용해도 되는지, 리스크는 어떤지에 대해 비판적으로 생각할 수 있는 능력이 매우 중요해졌고 그 중심에는 CS가 있다 라는 의미였다.&lt;/p&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~3년 전에만 해도 취업을 빠르게 하는 과정은 아니었다. 개발자로서의 기초 체력과 스스로 생각하고 발전할 수 있는 능력을 키워주는 과정이었지, 도구를 익혀서 빠르게 취업하는 타 부트캠프하고는 거리가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 이젠 전세가 뒤집힌 것 같다. 도구 사용법을 가르치던 기존 부트캠프의 가치는 상대적으로 낮아졌고, 스스로 생각하는 능력을 길러주는 정글의 가치가 올라갔다. AI가 발전함에 따라, 정글은 이제 개발 기초 체력과 더불어 실제 취업에도 유의미한 도움이 되는 과정이 된 것이다.&lt;/p&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;977&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/N4755/dJMcai4aO9z/xWUC8Oy4GyKQMnmQhASnO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/N4755/dJMcai4aO9z/xWUC8Oy4GyKQMnmQhASnO1/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 7&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/N4755/dJMcai4aO9z/xWUC8Oy4GyKQMnmQhASnO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FN4755%2FdJMcai4aO9z%2FxWUC8Oy4GyKQMnmQhASnO1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;977&quot; height=&quot;550&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 7&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;981&quot; data-origin-height=&quot;549&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAgn6F/dJMcaa6doxh/4px5Ll72GBOfAHWk8tRXYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAgn6F/dJMcaa6doxh/4px5Ll72GBOfAHWk8tRXYK/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 8&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAgn6F/dJMcaa6doxh/4px5Ll72GBOfAHWk8tRXYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAgn6F%2FdJMcaa6doxh%2F4px5Ll72GBOfAHWk8tRXYK%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;981&quot; height=&quot;549&quot; data-origin-width=&quot;981&quot; data-origin-height=&quot;549&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 8&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 회사에 지원하기 전 내 이력서는, 어떤 기술을 써보고 무엇을 구현했냐에 초점이 잡혀 있었다. 즉, 특정 문제에 대한 깊은 고민이 빠져 있었다. 당시 서류를 200개 이상 냈던 시점이었지만 도저히 원하는 기업에 서류가 붙지를 않았다. 여기서 말하는 &quot;원하는 기업&quot;이라는 건 직무가 백엔드 엔지니어고, 연봉이 3000 이상이며, 기술 또는 개발 문화가 좋은 기업이었다. 쉽게 말해서 &quot;백엔드 개발을 할 수 있으면서도, 큰 하자가 없는 회사&quot; 정도였다. 내가 눈이 높은가? 아니, 높지 않다. 그럼에도 불구하고 도저히 괜찮은 회사에 합격할 수 없었다. 그 때 생각했다. &quot;내가 부족하구나.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그때 내 이력서 합격률을 2배 이상 올려준 MSA 프로젝트를 시작했다. 개인 프로젝트였고, 1달 간 약 300시간을 투자하여 진행되었다. 백엔드 JD에서 자주 보이는 키워드인 MSA, Message Queue, Redis, gRPC등을 전부 직접 활용해보고 이력서에 추가하자 라는 취지였다. 그런데, 그냥 단순히 사용해 보기만 하는 건 누구나 할 수 있다. 나는 뭔가 특별함을 추가해야만 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 나는 Flask/Go 를 활용한 MSA 환경을 구축하고, 4가지 병목 (CPU Bound, I/O Bound, 통신 프로토콜, DB Bound)을 직접 정의했다. 더미 데이터를 100만 건 넣고, K6로 가짜 트래픽을 만들고, 병목 개선 전/후 성능을 측정하고 Grafana/Prometheus로 시각화 했으며, 성능이 개선된 이유를 CS 관점에서 상세하게 분석하고 잘 정리하여 이력서와 포트폴리오에 실었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 프로젝트 이후로 서류 합격률은 3%에서 7% 이상으로 올랐으며(심지어 이때부턴 마음에 드는 기업에만 지원했음에도), 이후의 모든 면접은 MSA 프로젝트에 대한 이야기로만 시작되고 끝났다. 기존엔 면접을 한달에 1~2개 보던 것이 일주일에 2~3개로 늘어났고, 머지않아 취업에 성공할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 내가 말하고자 하는 건 이거다. 현재/앞으로의 취업에는 &quot;특정 문제를 깊게 파본 경험&quot;과 그걸 가능케 하는 CS기초가 중요하다는 것, 그리고 그걸 할 수 있는 곳이 정글이라는 것.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSA 프로젝트 CPU Bound 실험: &lt;a href=&quot;https://yskisking.shop/363&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/363&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1777537200165&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;[msa-perf-lab] CPU Bound 작업 성능 비교: Flask 자체 연산 vs Go 위임 - 멀티스레드 병렬 처리의 효율성 증&quot; data-og-description=&quot;저번 시간엔 RabbitMQ 비동기 처리를 통해, Flask의 I/O Bound 병목점을 해결해 보았다. 응답시간은 약 500배 차이가 났었고, 처리량 및 드랍률도 RPS가 증가할수록 격차가 심해졌다. 이번 시간엔 Flask의 &quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/363&quot; data-og-url=&quot;https://yskisking.shop/363&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bg2v9P/dJMb8TCcZBB/6qtVjAdKifMwyEqUKKYgWk/img.png?width=800&amp;amp;height=250&amp;amp;face=0_0_800_250,https://scrap.kakaocdn.net/dn/3D2Td/dJMb87NZRst/39tG3l4LAJDHoIDhVuMit1/img.png?width=800&amp;amp;height=250&amp;amp;face=0_0_800_250,https://scrap.kakaocdn.net/dn/XzPcr/dJMb84qbYtL/qpe7uB1KmZxUdy5NPSk9I0/img.png?width=1255&amp;amp;height=389&amp;amp;face=0_0_1255_389&quot;&gt;&lt;a href=&quot;https://yskisking.shop/363&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/363&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bg2v9P/dJMb8TCcZBB/6qtVjAdKifMwyEqUKKYgWk/img.png?width=800&amp;amp;height=250&amp;amp;face=0_0_800_250,https://scrap.kakaocdn.net/dn/3D2Td/dJMb87NZRst/39tG3l4LAJDHoIDhVuMit1/img.png?width=800&amp;amp;height=250&amp;amp;face=0_0_800_250,https://scrap.kakaocdn.net/dn/XzPcr/dJMb84qbYtL/qpe7uB1KmZxUdy5NPSk9I0/img.png?width=1255&amp;amp;height=389&amp;amp;face=0_0_1255_389');&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;[msa-perf-lab] CPU Bound 작업 성능 비교: Flask 자체 연산 vs Go 위임 - 멀티스레드 병렬 처리의 효율성 증&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;저번 시간엔 RabbitMQ 비동기 처리를 통해, Flask의 I/O Bound 병목점을 해결해 보았다. 응답시간은 약 500배 차이가 났었고, 처리량 및 드랍률도 RPS가 증가할수록 격차가 심해졌다. 이번 시간엔 Flask의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r4MZH/dJMcagrN1AC/YdKWrtk9q6G1F18Z2kghSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r4MZH/dJMcagrN1AC/YdKWrtk9q6G1F18Z2kghSK/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 9&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r4MZH/dJMcagrN1AC/YdKWrtk9q6G1F18Z2kghSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr4MZH%2FdJMcagrN1AC%2FYdKWrtk9q6G1F18Z2kghSK%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;980&quot; height=&quot;551&quot; data-origin-width=&quot;980&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 9&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAmP6h/dJMcafTZl1s/KwQrw44N4e7trOxDfMkB3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAmP6h/dJMcafTZl1s/KwQrw44N4e7trOxDfMkB3k/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 10&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAmP6h/dJMcafTZl1s/KwQrw44N4e7trOxDfMkB3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAmP6h%2FdJMcafTZl1s%2FKwQrw44N4e7trOxDfMkB3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;977&quot; height=&quot;550&quot; data-origin-width=&quot;977&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 10&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금 대부분의 신입 개발자 지망생들은 서류를 수십~수백 개씩 넣으며 수많은 탈락을 맛보고 있을 것이며, &quot;난 재능이 없나&quot; &quot;난 개발자가 아닌가&quot;라고 생각하고 있을 것이다. 나도 그런 적이 있었고. 그러나 그건 본인 탓이 아닐 확률이 높다. 채용 시장은 IMF 때보다도 위축되어 있고, 그것은 학벌/경력 상관없이 모두에게 똑같이 적용된다. 모두가 절망을 맛보고 있다는 것이다. 그럼 모두에게 재능이 없는가? 모두가 부족한가? 절대 아니다. 몇년 전이었으면 진작 취업 하고도 남았을 사람들이다. 시장이 문제인 거지, 본인이 문제가 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 어쩌겠는가? 우리가 시장을 이길 수는 없다. 회사는 결국 &quot;가장 뛰어난 1인&quot;을 뽑는다. 뛰어남의 기준은 모든 회사가 다르며(실력, 경력, 학벌, 인성과 태도 등), 수많은 서류를 넣고 면접을 보다가, 우연찮게 특정 면접관에게 &quot;가장 뛰어난 1인&quot;으로 비춰진다면 그때 합격하는 것이다. 그 언젠가 올 기회를 위해 우리는 항상 준비하고, 발전해야 한다. 매일매일 꾸준히 아주 조금씩, 어제보다 조금씩만 발전하다 보면 노력 끝에 주어진 기회를 잡는 날이 분명히 올 것이다. 물론, 멈추면 끝이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근엔 &quot;AI가 일자리를 다 대체할 텐데, 개발자며 취업이며 무슨 소용이냐&quot; 라는 견해를 갖는 사람도 가끔 봤다. 물론 실제로 그렇게 될 수도 있고, 미래엔 일을 하고 있다는 것 자체가 굉장한 특별함이 될 지도 모른다. 그런데 난 이렇게 생각한다. 약간 철학적인 견해일 수도 있겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성공의 기준도 상대적, 행복의 기준도 상대적이다. 일반적으로 통용되는 상대적의 기준은 &quot;나&quot;와 &quot;나를 제외한 나머지 사람&quot;이다. 즉 내가 다른 사람보다 뛰어난 위치에 있다면 성공한 것이고 그게 행복으로 연결될 가능성이 높다. 성공과 행복은 절대적인 기준으로 정해지지 않는다. 고려, 조선시대에는 부의 상징이 말(馬) 이었다. 지금도 그런가? 전혀 아니다. 지금은 4억짜리 벤틀리 정도가 당시의 명마와 비교될 것이다. 즉, &quot;동시대를 살아가는 다른 사람들에 비해 내가 더 높은 위치에 있는가?&quot;가 상대적인 성공의 기준일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 최악의 상황을 가정해서 먼 미래에 전 세계 인구가 100명이고, AI 때문에 최상위 1명을 제외한 나머지 99명의 인간이 2026년에 비해 비루한 삶을 산다고 해도, 본인이 99명 중 10등이라면 그건 성공한 삶일 수 있고, 실제로 그렇게 인식될 수 있으며, 실제로 행복할 수도 있다. 결국 우리가 경쟁해야 할 상대는 AI가 아니라 다른 사람, 즉 타인이다. 이건 역사적으로 단 한번도 변하지 않았다. AI가 얼마나 발전하든, 일자리를 뺏든 말든, 결국 우리 모두는 타인과의 경쟁에서 이겨야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AI가 모든 노동을 대체하는 것은, 언제인지 모를 뿐 반드시 일어날 일이다. 개발자는 순서가 조금 빨리 온 것 뿐이다. 우리는 그저, 변화를 받아들이고 지금 할 수 있는 최선을 다하면 되는 것이다.&lt;/p&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;983&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dp70SV/dJMcabjL5or/Aboee5YFZfcpOiz21GEzP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dp70SV/dJMcabjL5or/Aboee5YFZfcpOiz21GEzP1/img.png&quot; data-alt=&quot;크래프톤 정글 인터뷰 11&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dp70SV/dJMcabjL5or/Aboee5YFZfcpOiz21GEzP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdp70SV%2FdJMcabjL5or%2FAboee5YFZfcpOiz21GEzP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;983&quot; height=&quot;552&quot; data-origin-width=&quot;983&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;크래프톤 정글 인터뷰 11&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=====&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터뷰 링크(유튜브): &lt;a href=&quot;https://www.youtube.com/watch?v=quWvu-AFJhI&amp;amp;t=9s&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=quWvu-AFJhI&amp;amp;t=9s&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=quWvu-AFJhI&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/dqRirn/dJMb9jgAB8p/wjKUh5qx0OqdqotlRInLU0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=586_228_638_286,https://scrap.kakaocdn.net/dn/XEcDO/dJMb9fZyDzg/GCJYPlhqCwfMNDfAAtGUok/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=586_228_638_286,https://scrap.kakaocdn.net/dn/Ur50f/dJMb9efhiiH/uCqk3cF2CHavkSlB8Rqft0/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=586_228_638_286&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-title=&quot;Jungle Dev Club | 크래프톤 정글&quot; data-original-url=&quot;&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/quWvu-AFJhI&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>업적</category>
      <category>AI</category>
      <category>CS</category>
      <category>Jungle Dev Club</category>
      <category>개발자</category>
      <category>개발자 취업</category>
      <category>신입 개발자 취업</category>
      <category>정글</category>
      <category>정글 인터뷰</category>
      <category>크래프톤 정글</category>
      <category>크래프톤 정글 5기</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/371</guid>
      <comments>https://yskisking.tistory.com/371#entry371comment</comments>
      <pubDate>Thu, 30 Apr 2026 17:22:52 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 세금을 알아야 부가 보인다: 다양한 절세 방법을 정리한 책 + 상속/증여세에 관한 개인적 고찰</title>
      <link>https://yskisking.tistory.com/370</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2026-04-22-17-42-46.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTepe0/dJMcahxpd5G/Fks8TnHdNt4XNWxIy7KbWK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTepe0/dJMcahxpd5G/Fks8TnHdNt4XNWxIy7KbWK/img.jpg&quot; data-alt=&quot;세금을 알아야 부가 보인다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTepe0/dJMcahxpd5G/Fks8TnHdNt4XNWxIy7KbWK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTepe0%2FdJMcahxpd5G%2FFks8TnHdNt4XNWxIy7KbWK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;533&quot; height=&quot;711&quot; data-filename=&quot;KakaoTalk_Photo_2026-04-22-17-42-46.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;세금을 알아야 부가 보인다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;총평: ★★★☆☆ (3점)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;국가에 속한 국민이라면 절대 피할 수 없는 &quot;세금&quot;을 어떻게 절약할 수 있을지 안내하는 도서이다. 세금에 대한 기초적인 지식이 있으며, 실제로 상속/증여/사업/근로소득 등에 대한 절세가 필요한 상황에 처해 있는 사람에게 유용한 책일 듯 하다. &quot;세금이란 무엇인가?&quot; 부터 시작하는 완전한 초심자용 책은 아니지만, 세금 지식이 전무하다고 해서 읽기 불가능한 정도는 아니다. 이 책은 현직 세무사가 집필한 만큼, 실제 세법을 근거로 자주 일어나는 상황을 예시로 들어 혼란스럽지 않고 신뢰성 있게 설명한다. 그러나 개인적으로 1장 ~ 2장(상속/증여, 양도) 부분에서는, 절세 팁 보다는 &quot;세법을 읽어주는&quot; 듯한 느낌이 강하게 들어 몰입도가 다소 떨어졌다. 3장 ~ 5장(사업, 근로, 세금 상식) 부분에서는 조금 더 와닿는 예시들이 등장하여 그런 느낌은 덜 했다. 전반적으로 읽기 편한 책은 아니었지만 한번 쯤 읽어두면 인생에서 절세가 필요한 순간을 만났을 때 이 책의 내용이 떠올라 도움이 되지 않을까 싶다. 만약 절세가 아니라 세금 자체에 대한 지식이 필요한 사람이라면 다른 책을 찾는 걸 권한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;도서 정보&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제목: 세금을 알아야 부가 보인다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출판사: 청림출판&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지은이: 이동기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분량: 342p&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난이도(Easy / Normal / Hard): &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;Normal&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추천 여부(Yes / No): &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;No&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;/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;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 세금에 대해서는 완전한 문외한이었다. 월급을 받으면 &quot;세금&quot;을 떼고 통장에 입금시켜 준다는 사실과, 연초에 연말정산이라는 걸 한다는 것(뭔지는 모름), 주식 투자 수익금의 일부를 제하고 통장에 입금된다는 사실 정도를 제외하고는 말이다. 돈을 많이 벌고 싶은 나로써는 돈을 모으는 것 뿐만 아니라 돈을 절약하는 것 또한 중요하다고 생각했고, 그 중 하나인 세금과 절세에 대해 공부해 보고자 이 책을 선택했다. 이 책을 선택한 이유는 마침 내가 세금 공부의 필요성을 느끼던 시기에, 고속 버스를 기다리고자 우연히 들어간 대형 서점에서, 매우 적절한 제목의 책이 내 눈에 띄었고, 몇 페이지 넘겨 확인한 책 구성이 마음에 들었기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 순서대로 상속, 증여, 양도, 사업, 근로소득에 절세에 대해 설명하고 마지막으로 세금 상식을 이야기하며 마무리한다. 세금과 세금 관련 용어에 관한 설명은 따로 없지만 모르는 단어는 직접 찾아가면서 읽으니 충분히 무리 없이 읽을 수 있었다. 저자는 책 전반적으로 &quot;세금을 성실히 신고하고 납부하는 것이 가장 효율적인 절세&quot;라는 점을 일관적으로 주장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 사람이 세금을 항상 똑같이 내는 건 아니다. 일반적으로 소득이 높을 수록 더 높은 세금을 내며, 본인의 상황에 따라 여러가지 소득/세액공제 혜택을 잘 찾아서 누릴 수도 있다. 만약 세금을 내기 힘든 상황이라면 납부기한을 연장할 수도 있으며, 근로소득의 경우 연말정산에 제대로 반영되지 않은 소득이나 공제 항목은 5월 종합소득세 신고 시기에 추가로 신고할 수도 있다. 탈세를 위해 고의적으로 실제 소득에 비해 소득신고를 낮게 하거나 빼먹는 경우 오히려 엄청난 가산세를 물거나 징역에 갈 수도 있으니 주의해야 한다. 특히 요즘엔 국세청의 세무조사 시스템이 매우 선진화 되었다고 하니, 고의적 탈세는 갈수록 쉽게 적발될 것이며 절세 전략을 연구하거나 세무사를 고용하는 것이 훨씬 나은 길일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책을 읽고 나는 모든 세법이나 절세 전략을 외운 건 아니지만, 앞으로의 인생에 있어 모든 형태의 소득이나 지출이 생길 때 세금을 고려할 수 있게 되었다. 정말 다양한 상황에서 세금을 내야 하고, 정말 다양한 절세 전략이 있다는 걸 이해했다. 예를 들어 지금 같았으면 근로 또는 사업소득을 얻었을 때 &quot;아싸, 돈 벌었다!&quot; 하고 끝냈다가 가산세를 물 일을, &quot;소득 신고는? 공제 혜택은 있나? 어떻게 절세할 수 있지?&quot; 라는 쪽으로 생각할 수 있게 되었다. 4점이라기엔 애매하고 2점은 아닌 것 같아서 3점을 주었고, 괜찮은 책이지만 &quot;이 책을 특별히 추천하고 싶냐&quot;는 아니기에 No를 주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=====&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;상속세와 증여세는 어째서 존재해야 하는가&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책을 읽으며 가장 크게 느낀 점은, 모든 소득과 지출, 즉 돈이 오가는 모든 곳에는 반드시 세금이 붙으며 &quot;이렇게까지?&quot; 할 정도로 다양하게, 그것도 꽤 많은 돈을 세금으로 떼 간다는 점이다. 특히 소득세나 증여/상속세 같은 경우 누진세 형식으로 금액이 올라갈 수록 더 많은 세금을 매기는데, 소득세는 최대 45%, 증여/상속세는 무려 최대 50% 라는 세금을 매긴다. 소득세야 뭐 본인이 최초로 번 돈이고, 소득이 높은 사람은 세금을 많이 내도 생활에 문제가 되지 않으니 그럴 수 있다 생각하지만, 이미 소득세를 낸 자산을 자식 등에게 증여하거나 상속할 때도 엄청난 세금을 매긴다는 게 굉장히 의아했다. &quot;이중과세&quot;라는 단어가 여기에 쓰이는 단어는 아니겠지만, 이것이야말로 이중과세 아닌가? 이중을 넘어 세대가 바뀔 때마다 삼중 사중 과세가 되는데 말이다. 차라리 &quot;보유세&quot; 형태라면 모를까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유가증권, 부동산, 현금 등 거의 모든 형태의 자산에 대해 세금을 매긴다. 부의 대물림을 막기 위해서인가? 라고 생각해 봤는데, 그렇다면 어째서인가? 부의 대물림이 잘못되었기에 막는 것인가? 라고 던져봤을 때 그건 아니라고 판단했다. 개인이 노력해서 번 돈을, 사랑하는 자식한테 주는 것이 대체 무엇이 잘못되었단 말인가? 이건 절대 잘못되지 않았다. 오히려 지극히 정상이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 내린 결론은 &quot;국가는 하나의 공동체이고, 국가는 개인이 아니라 국민 모두의 이익을 위해 행동하기 때문&quot; 이었다. 대부분의 인간은 태어나자마자 국적을 받고 해당 국가의 복지와 혜택, 인프라, 교육 등을 톡톡히 누리며 살아간다. 태어나서 국적을 부여받는 순간부터 평등한 기회를 부여받고 성장하고, 훗날 본인이 받은 혜택을 본인의 소득/자산 수준에 따라 크고 작은 &quot;세금&quot;이라는 형태로 국가에 돌려준다. 아무런 조건 없이 혜택을 누리는 대신, 내 소득이 생겼을 때 &quot;세금&quot;으로 환원하도록 하나의 약속을 한 셈인 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 여기서 증여/상속세를 통해 부의 대물림을 막는 이유는 그것 자체가 잘못되어서가 아니라, 부가 한 곳으로 몰려 국가라는 공동체가 흔들리지 않게 하기 위함이다. 민주주의든 공산주의든 사회주의든 간에, 그 모토는 &quot;모든 국민의 행복&quot;이고 역사적으로 그래 왔다. 실태가 그렇든 그렇지 않든 말이다. 증여/상속세를 통해 과도하게 몰린 부를 사회에 환원하고, 그 부가 다시 국민에게 평등한 기회를 부여하고.. 그렇게 반복된다. 만약 증여/상속세가 존재하지 않았다면, 단순 세수의 부족을 떠나 세대를 거듭할수록 부가 극소수에게 몰리면서 국가는 공동체로서의 의미를 잃게 될 것이다. 딱 그 즈음이지 않을까? 새로운 국가가 건국되는 시점 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 상속/증여세에 관해 개인적으로 추론해본 생각이었다. 어쨌든 우리는 부자들에게 감사해야 할 일이다. 같은 기회를 제공받아서, 개인의 노력으로 부자가 되었고, 엄청난 양의 세금을 내고, 그것이 다수를 위한 복지에 쓰이고 있다. 음 그런데... 유의미한 소비력을 갖는 국민이 많아야 경제가 돌아가고 부자들도 더 부자가 된다는 점을 생각하면, 뭐 부자들이 그렇게 완전히 희생하는 건 아닐 수도 있겠다. 실제로 경제에 있어 복지는 매우 중요하고, 서민이 있어야 부자가 있는 거니까. 무인도에서 금덩이로 뭘 하겠는가?&lt;/p&gt;</description>
      <category>독서/경제 &amp;amp; 금융 &amp;amp; 재테크</category>
      <category>독후감</category>
      <category>부의 대물림</category>
      <category>상속세</category>
      <category>세금</category>
      <category>세금을 알아야 부가 보인다</category>
      <category>소득세</category>
      <category>연말정산</category>
      <category>원천징수</category>
      <category>절세</category>
      <category>증여세</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/370</guid>
      <comments>https://yskisking.tistory.com/370#entry370comment</comments>
      <pubDate>Wed, 22 Apr 2026 20:28:53 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 미국주식 처음공부: 주식 입문자 도서 추천, 초보자 시각에 맞게 잘 정리된 책</title>
      <link>https://yskisking.tistory.com/369</link>
      <description>&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;666&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dkN9pt/dJMcacCdQO9/TtjEgUaGGkNlXlrcltfuzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dkN9pt/dJMcacCdQO9/TtjEgUaGGkNlXlrcltfuzK/img.png&quot; data-alt=&quot;미국주식 처음공부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dkN9pt/dJMcacCdQO9/TtjEgUaGGkNlXlrcltfuzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdkN9pt%2FdJMcacCdQO9%2FTtjEgUaGGkNlXlrcltfuzK%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;448&quot; height=&quot;597&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;666&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;미국주식 처음공부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;총평: ★★★★☆ (4점)&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;주식/미국주식 투자를 처음 시작하는 사람에게 적합한 도서. 미국주식 입문자를 타겟팅하고 있으며 주식, ETF, 배당주 등이 무엇인지, 리스크는 어떻게 최소화할 지, 주식 투자에 임하는 마음가짐이나 매매 타이밍, 좋은 주식 선별법, 포트폴리오 관리법 등 입문자에게 필요한 다양한 정보를 넓고 얕게 제공한다. 어렵지 않게 쓰여 있어 읽기 쉬우며, 상대적으로 안전하고 정석적인 투자를 기준으로 설명하기에 누구든지 이 책으로 주식을 시작하면 꽤나 괜찮은 발판으로 삼을 수 있을 것이라 생각한다. 5점이 아닌 이유는 주식에 대한 완전히 새로운 시각이나 견해같은 저자만의 특별한 고유성이 보이지는 않았고, 비슷한 수준의 좋은 책이 많이 있을 거라 생각하기 때문이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;==========&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;도서 정보&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;제목: 미국주식 처음공부&lt;br&gt;출판사: 이레미디어&lt;br&gt;지은이: 수미숨, 애나정&lt;br&gt;분량: 412p&lt;br&gt;&amp;nbsp;&lt;br&gt;난이도(Easy&lt;span style=&quot;color: #409d00;&quot;&gt;&amp;nbsp;&lt;/span&gt;/ Normal / Hard):&amp;nbsp;&lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Easy&lt;/b&gt;&lt;/span&gt;&lt;br&gt;추천 여부(Yes / No): &lt;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt;Yes&lt;/b&gt;&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;==========&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;고찰&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;자본주의나 거시경제 같은 큰 틀은 가볍게 공부했으나, 정작 내 곁에 가장 가까이 있는 주식에 대해 공부한 적이 없었기에 도전해본 책이다. 이 책 이전엔 &quot;브라질에 비가 내리면 스타벅스 주식을 사라&quot; 라는 책을 읽었는데, 생각보다 겹치는 내용이 많아서 금방 읽을 수 있었다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&quot;미국주식&quot; 이라는 주제를 가지고 있지만, 국내주식을 타겟팅하는 사람이 봐도 손색이 없을 만큼 주식에 대한 전반적인 내용을 다룬다. 이 책은 &quot;주식투자는 도박인가?&quot; 라는 주제로 투자에 대한 오해를 풀며 시작된다. 이어서 미국 주식이라고 하면 국내 주식보다 어려울 것 같고, 신경쓸 게 많을 것 같은 등 초심자의 두려움을 해소시켜준 후에 왜 미국주식 투자를 해야하는지와 단점은 어떤 것이 있는지에 대한 내용으로 첫번째 챕터가 끝난다.&lt;br&gt;&amp;nbsp;&lt;br&gt;가장 인상적으로 봤던 부분은 투자 방향성에 대한 내용이었다. 저자는 주식 입문자일수록 큰 수익을 얻으려는 시도보다 최대한 돈을 잃지 않는 방향을 수립해야 한다고 말한다. 50% 손실을 복구하기 위해서는 50%가 아니라 100%의 수익을 내야 한다는, 즉 손실 복구에 필요한 수익률이 손실률과 비례하지 않는다는 강력한 예시를 들며 이를 뒷받침한다. 또한 복리의 마법과 이를 뒷받침할 30년 수익률 데이터를 보여주며 투자 20년차부터 복리 수익이 극대화되고, 그 때를 위해 복리 수익이 미미한 초반 구간을 잘 버텨야 한다고 주장한다. 나도 안정적인 투자를 지향하는 사람으로써 굉장히 공감되는 내용이었다. 빨리 부자가 되려면, 빨리 부자가 되려 하면 안 된다.&lt;br&gt;&amp;nbsp;&lt;br&gt;주식의 섹터와 분할매수에 관한 내용들도 인상적이었다. 현재 섹터는 정보기술, 금융, 원자재, 에너지 등 총 11개로 이루어져 있고, 각 섹터마다 경기 흐름에서의 강한 타이밍이 다르며 한번에 큰 손실을 보지 않기 위해서는 다양한 섹터의 주식을 분할매수 해야 한다고 주장한다. 초심자는 &quot;분할매수&quot;라는 단어만 보고 비슷한 섹터의 주식만 (ex: 아마존, 구글, 메타..) 여러 개 사놓고 분할매수 했다고 착각할 수 있는데, 이를 혼동하지 않도록 정확히 짚어준다. 이는 가장 기본적이면서도 매우 중요한 부분이라 생각한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;배당주에 대한 내용은 이 책을 통해서 처음 접했는데, 당장 배당주를 살 생각은 없지만 꽤 도움이 된 것 같다. 특히 &quot;좋은 배당주&quot;를 어떻게 고르는지에 대한 방법이 많이 도움이 되었다. 기업의 최근 수십년 간 배당 지급 이력, 배당 성장 이력 등을 직접 확인하고 투자할 수 있도록 다양한 자료 수집 방법이나 분석 방법까지도 안내해준다. 또한 배당금 수령을 통해 투자의 재미를 느낄 수 있도록 장려하는 방법인 배당 달력을 만든다던가, 배당금으로 생활비 일부를 대체한다던가 하는 소소한 팁들도 제공한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;마지막 챕터에서는 세금에 대해 설명한다. 국내 주식과 미국 주식의 매수/보유/매도 과정에서의 배당소득세, 양도소득세 등은 어떠한지와 이를 절세하는 방법들을 설명한다. 특히 매매차익을 실현하려 할 때, 배우자에게 주식을 증여해 증여세 공제를 통해 양도소득세를 절세하는 방법을 굉장히 인상깊게 봤다. 이 방법은 증여자가 누구인가에 따라서 공제액이 다른데, 배우자는 무려 6억을 공제해주며 직계존속/비속은 5천만원, 기타친족은 1천만원까지 공제받을 수 있다.&lt;br&gt;&amp;nbsp;&lt;br&gt;다만 개인적으로 세금 파트를 읽으며 화가 좀 났다. 무슨 세금을 이렇게까지 많이 떼 가는지... 어휴. 물론 난 아직 세금을 많이 낸 적도 없고, 다양한 복지와 나라의 혜택을 톡톡히 받으며 살고 있으며 세금은 나라 운영에 있어 필수적이란 것을 이해하고 있고 탈세할 생각은 추호도 없으나, 훗날 내가 부자가 되었을 때 납세할 수십억 수백억의 세금이, 나의 피나는 노력에서 온 소중한 돈이라는 것을 생각하면 벌써부터 괜시리 화가 나고 아깝다. 특히 증여세의 경우 30억 이상일 때 무려 50%를 내야 하는데... 너무 심한 거 아닌가 라는 생각이 들면서도, 매번 엄청난 고액을 납세할 전세계 부자들에게 경외를 표한다.&lt;/p&gt;</description>
      <category>독서/경제 &amp;amp; 금융 &amp;amp; 재테크</category>
      <category>etf</category>
      <category>S&amp;amp;P500</category>
      <category>미국주식</category>
      <category>미국주식 입문 책</category>
      <category>미국주식 처음공부</category>
      <category>주식</category>
      <category>주식 입문</category>
      <category>주식 입문 책</category>
      <category>주식투자 방법</category>
      <category>투자</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/369</guid>
      <comments>https://yskisking.tistory.com/369#entry369comment</comments>
      <pubDate>Sun, 1 Mar 2026 19:30:52 +0900</pubDate>
    </item>
    <item>
      <title>[KBS 9시 뉴스 출연] 개발왕 양선규 공중파 출연하다</title>
      <link>https://yskisking.tistory.com/368</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 정말로 감개무량함을 전하며 글을 시작한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;나는 2026년 현대 사회의 사람들이 뉴스를 이렇게나 많이 보는지 이번에 처음 알았다.&lt;br&gt;인터뷰를 진행한 후, 내가 머지않아 KBS 9시 뉴스에 나올 것이란 사실을 부모님 그리고 정말 가까운 지인에게만 말했는데도 불구하고 주변에 모르는 사람이 거의 없게 되었다. 복장을 차려 입었길래 미리 준비한 줄 알았다는 분도 계셨는데, 그것은 인터뷰 당일 아침에 면접을 보고 왔다는 우연이 겹쳤기 때문이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;출연(인터뷰) 내용&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;해당 뉴스는 AI로 인해 취업 시장이 얼어붙고 있고, 특히 전문직/IT 종사자의 일자리가 큰 영향을 받고 있다는 주제였다. 나는 당시 백엔드 개발자 취업준비생이었으며 약 3년동안 취업준비를 해왔던 전문 취준생이었기에 인터뷰 제의를 받게 되었다. 인터뷰 내용은 전공이 무엇이고 취준 기간은 어떻게 되는지, 최근 채용공고 동향은 어떤지, AI가 신입 개발자에게 미치는 영향은 어떤 것인지에 대한 내용을 약 10분-15분 정도 인터뷰했다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2556&quot; data-origin-height=&quot;1179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5ZOF1/dJMcabC88mx/Pp6odYvAyk7vaL4mBJMRR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5ZOF1/dJMcabC88mx/Pp6odYvAyk7vaL4mBJMRR1/img.png&quot; data-alt=&quot;1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5ZOF1/dJMcabC88mx/Pp6odYvAyk7vaL4mBJMRR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5ZOF1%2FdJMcabC88mx%2FPp6odYvAyk7vaL4mBJMRR1%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;2556&quot; height=&quot;1179&quot; data-origin-width=&quot;2556&quot; data-origin-height=&quot;1179&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2556&quot; data-origin-height=&quot;1179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xiwe4/dJMcac9PjPg/o4MzIhKYokaYAVQ2xHJrxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xiwe4/dJMcac9PjPg/o4MzIhKYokaYAVQ2xHJrxK/img.png&quot; data-alt=&quot;2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xiwe4/dJMcac9PjPg/o4MzIhKYokaYAVQ2xHJrxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXiwe4%2FdJMcac9PjPg%2Fo4MzIhKYokaYAVQ2xHJrxK%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;2556&quot; height=&quot;1179&quot; data-origin-width=&quot;2556&quot; data-origin-height=&quot;1179&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;출연(컨택) 계기&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;내가 KBS에 출연한 것을 보고 어떻게 컨택되었는지 묻는 사람이 많았다. 근데 컨택이라고 하기도 애매한, 정말 갑작스러운 인터뷰였다. 나에겐 우연찮게 친분이 생겨 나의 취업 준비에 정말 많은 도움을 주신 대표님이 계신다. 당시 나는 대표님 사무실에 신세지며 취준을 하고 있던 상황이었는데, KBS에서 인터뷰를 목적으로 사무실에 찾아오셨다. 내가 아니라, 대표님을 인터뷰하러 말이다. 그런데 기자분께서 대표님께, &quot;취준생 인터뷰도 진행하고 싶은데, 혹시 주변에 소개해줄 사람이 있냐&quot; 라고 하셨고 대표님은 &quot;바로 저기에 취준생이 있다&quot; 라고 하셨다. 그렇게 제안을 받은 나는 &quot;네 가능하죠 얼굴도 나와도 돼요&quot; 라고 했고 갑작스런 인터뷰가 진행되었다. ㅋㅋㅋㅋㅋㅋㅋ 결국 대표님 덕에 KBS에 출연하게 된 것이다. 감사합니다, 정말로.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2556&quot; data-origin-height=&quot;1179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBLzdF/dJMcacIPta4/EkvkOKkkMvzEMkGLcSMtwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBLzdF/dJMcacIPta4/EkvkOKkkMvzEMkGLcSMtwK/img.png&quot; data-alt=&quot;3&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBLzdF/dJMcacIPta4/EkvkOKkkMvzEMkGLcSMtwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBLzdF%2FdJMcacIPta4%2FEkvkOKkkMvzEMkGLcSMtwK%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;2556&quot; height=&quot;1179&quot; data-origin-width=&quot;2556&quot; data-origin-height=&quot;1179&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;3&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2556&quot; data-origin-height=&quot;1179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzMIRf/dJMcagRZsKm/5qmKV2bGxQX9CkxL4gMpkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzMIRf/dJMcagRZsKm/5qmKV2bGxQX9CkxL4gMpkK/img.png&quot; data-alt=&quot;4&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzMIRf/dJMcagRZsKm/5qmKV2bGxQX9CkxL4gMpkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzMIRf%2FdJMcagRZsKm%2F5qmKV2bGxQX9CkxL4gMpkK%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;2556&quot; height=&quot;1179&quot; data-origin-width=&quot;2556&quot; data-origin-height=&quot;1179&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;4&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;취업이 정말 많이 힘든긴 한가보다. 3년간 취준하며 시장이 정말 차갑다고 느꼈는데, 뉴스에서도 다룰 만큼 다른 사람들 또한 그렇게 느끼는 것 같다. AI와 여타 다른 이유들 때문에 많이 힘들지만, 취업이란 건 아직까지는 우리 대부분이 반드시 해내야 할 일이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;시대는 빠르게 변하고 있고, 변화할 것이며 이는 피할 수 없는 흐름이다. 변화를 두려워하고 피하기보단 정면으로 부딪혀 적응하고, 이겨내고, 이용해보자. 단순히 AI를 사용할 뿐인 &quot;소비자&quot;가 아니라, 자신만의 능력과 고유성을 바탕으로 AI를 수족처럼 부려 무기로 활용하는 &quot;관리자&quot;가 되어보는 건 어떨까.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;뉴스 링크(유튜브)&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://youtube.com/watch?v=6nzWkHeO8uU&amp;amp;si=s-80PbH0AYB3z3_m&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://youtube.com/watch?v=6nzWkHeO8uU&amp;amp;si=s-80PbH0AYB3z3_m&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-host=&quot;youtube&quot; data-video-url=&quot;https://www.youtube.com/watch?v=6nzWkHeO8uU&quot; data-video-thumbnail=&quot;https://blog.kakaocdn.net/dna/cffDPf/dJMb8TB5JLh/AAAAAAAAAAAAAAAAAAAAACdMZC4WcGdeIlImxJre2kSty5QAhegm2obI32oFiy2D/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=lWWL%2Fm2wJDWxVyu5au7n%2Bp1gVWs%3D&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-video-title=&quot;AI가 일자리 위협?…잘 나가던 전문직·IT 취업자 감소 [9시 뉴스] / KBS  2026.02.11.&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/6nzWkHeO8uU&quot; width=&quot;860&quot; height=&quot;484&quot; frameborder=&quot;&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;&lt;figcaption&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;00:16 - 00:34 (19초)&lt;br&gt;00:48 - 00:57 (10초)&lt;br&gt;무려 29초간 공중파를 장악했다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;==========&lt;br&gt;&amp;nbsp;&lt;br&gt;이번엔 갑작스럽게 취업준비생 신분으로 나왔지만, 언젠가는 높은 수준의 기술적/경제적 자문을 받기 위한 목적의 정식 컨택 절차를 거쳐 출연해 보고 싶다. 그렇게 될 수 있도록 늘 그랬듯, 앞으로도 꾸준히 달릴 것이다.&lt;/p&gt;</description>
      <category>업적</category>
      <category>AI 개발자 취업</category>
      <category>AI 일자리</category>
      <category>KBS 9시 뉴스</category>
      <category>KBS 뉴스</category>
      <category>KBS 인터뷰</category>
      <category>공중파 출연</category>
      <category>뉴스</category>
      <category>신입 일자리</category>
      <category>취업준비생</category>
      <category>취업준비생 인터뷰</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/368</guid>
      <comments>https://yskisking.tistory.com/368#entry368comment</comments>
      <pubDate>Fri, 13 Feb 2026 21:58:08 +0900</pubDate>
    </item>
    <item>
      <title>From Cybersecurity to Development, 3 years of desperate struggle to hear &amp;quot;There's nothing more to ask&amp;quot; - Joining AIVIS as a Junior Developer</title>
      <link>https://yskisking.tistory.com/367</link>
      <description>&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;i&gt;I am currently translating my career journey into English to improve my business English skills.&lt;/i&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Right after graduating from university, I took a job in penetration testing and cybersecurity consulting at an cybersecurity company in Seongnam. However, I gave up the job offer and switched my career to becoming a developer.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;After three years of three jobs, two resignations, one declined offer, and about 400 application rejections, I finally heard the ultimate praise in an interview room: &quot;You answered so well that I have nothing more to ask.&quot; This post is a desperate record of those 1,000 days.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;From Cybersecurity to Developer&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In early 2023, after graduating with a degree in cybersecurity, I submitted my resume to AhnLab&amp;mdash;my dream company at the time&amp;mdash;to land a job in penetration testing. Perhaps as a reward for my hard work, I passed the initial screening. However, since it was my first interview ever, I gave clumsy answers along with unearned confidence, and ultimately tasted the bitterness of rejection. The arrogance of taking it for granted that I would pass, combined with the sincere desire to actually succeed, made the pain even deeper.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I had to start looking for other companies. However, there were hardly any major companies hiring entry-level penetration testers. Ultimately, I applied to small cybersecurity firm in Seongnam and was hired. On the train back to my hometown after signing the contract, I stared at the employment agreement with its unsatisfying salary for hours, overcome by a very strange feeling.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Since my top priority was &quot;money&quot; in the long run, I thought it was much better to switch my carrer to development if I couldn't start at a large company. Exactly two days after returning home, I turned down the job offer and switched my carrer path to development.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A post on my reflections after leaving the cybersecurity field: &lt;a href=&quot;https://yskisking.shop/105&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/105&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770112457605&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;탈보안&quot; data-og-description=&quot;탈보안 하기로 했다. 성남의 한 회사에 신입 정보보호 기술 컨설턴트 직무로 취업에 성공하고, 근로계약서까지 썼다.개인적인 생각으로 연봉은 동종업계 신입치곤 높았다. 만족했다.근처에 집&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/105&quot; data-og-url=&quot;https://yskisking.shop/105&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/SfpM3/dJMb84XTY9D/odtdfD64cunNOq5tktWSH1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/kngei/dJMb82MygGf/zj7WgvcOHdKmXn6vq6Lbtk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/VEl2s/dJMb82MygGe/H7RpDOkmooAVxAuUBPdta0/img.jpg?width=248&amp;amp;height=301&amp;amp;face=100_54_154_112&quot;&gt;&lt;a href=&quot;https://yskisking.shop/105&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/105&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/SfpM3/dJMb84XTY9D/odtdfD64cunNOq5tktWSH1/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/kngei/dJMb82MygGf/zj7WgvcOHdKmXn6vq6Lbtk/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/VEl2s/dJMb82MygGe/H7RpDOkmooAVxAuUBPdta0/img.jpg?width=248&amp;amp;height=301&amp;amp;face=100_54_154_112');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;탈보안&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;탈보안 하기로 했다. 성남의 한 회사에 신입 정보보호 기술 컨설턴트 직무로 취업에 성공하고, 근로계약서까지 썼다.개인적인 생각으로 연봉은 동종업계 신입치곤 높았다. 만족했다.근처에 집&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Certifications and Clumsy Coding Studies&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Around June 2023, I was a complete outsider to development, with no idea what algorithms or Spring were. I didn't even know what to study, so I decided to start by getting certifications, which was the area I was most confident in. I aimed for the &quot;Information Processing Engineer&quot; and &quot;SQLD&quot; certifications, which are the representative ones for developers; since I already held a certification in &quot;Information Security&quot;, I was confident I could get them easily. I felt like my momentum would be broken if I tried to get certifications while in the middle of serious dev studies; so I thought, &quot;Let's just get the certifications out of the way quickly first, then dive into development&quot;. Ultimately, I passed both the SQLD and Information Processing Engineer exams in October and November of that year. However, it wasn't as easy as I had expected, and I struggled quite a lot.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Now, the time had finally come for me to truly commit to my development studies. What should I study? Backend? Frontend? What is that? I feel like backend is a better fit, but what should I start with? Spring? Is this the most famous one? But they say, I have to do Java first? ..... With all these unknown keywords flying around, it was difficult for me to even establish a direction for my studies.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I was planning to study Java first, but everyone told me to take Young-han Kim's Spring courses. I heard that they are available for free on Inflearn. Since I had taken a Java class in school, I thought, &quot;Why not try the lecture first?&quot;; so I gave it a shot, but honestly, sincerely, I didn't understand a single thing. Controller, Repository, Annotation... and DTO was also a total shock. I wondered, &quot;Why even put data in there and make things more complicated?&quot; Looking back, the level of my understanding was almost laughable.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;So, I decided to start properly with Java. I finished reading the book &quot;&lt;i&gt;This is Java (이것이 자바다)&lt;/i&gt;&quot; over about a month, and I really struggled with the very last chapter on building a chat room. It was truly great book, and I felt like I had mastered Java now. So, I went back to Young-han Kim's courses. .... It's still very difficult. Maybe I'm not at the right level to take this course yet? So, I decided to study Spring using a book.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I read the book &quot;&lt;i&gt;Becoming a Spring Boot 3 Backend Developer(스프링 부트 3 백엔드 개발자 되기)&lt;/i&gt;&quot; published by Golden Rabbit. Sigh... but this is difficult, too. It was so, so difficult that I found myself just typing along without understanding anything, and I started to think, &quot;Maybe I have no talent for development&quot;. I did finish the book in the end, but hardly anything stayed in my head, and my confidence in development was just eroded. Hmm.. but I'm sure the fact that the book wasn't that great also played a part. I wrote the details in my book review.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Review: &lt;i&gt;This is Java&lt;/i&gt;: &lt;a href=&quot;https://yskisking.shop/140&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/140&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770110338934&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[이것이 자바다 개정판 후기] 이것이 자바다 완독 후기, 자바 교재 추천&quot; data-og-description=&quot;10월 중순부터 읽기 시작한 이것이 자바다 교재를 드디어 완독했다. 자바의 신, 자바의 정석 등등 다른 교재도 고민을 했었지만 난 이것이 자바다를 선택했다. 아직까지 주기적으로 신간이 나오&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/140&quot; data-og-url=&quot;https://yskisking.shop/140&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/M8DZb/dJMb8XkaDqE/PRdOHckV63LF7rmRsPWYn0/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/W8Ok6/dJMb8YpQDFI/fi2k52dNfjoqq8EZTXBcmk/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/sNjkx/dJMb8QL7eKt/jINkK8c8yxUATvSTX6NHX0/img.jpg?width=1080&amp;amp;height=1440&amp;amp;face=0_0_1080_1440&quot;&gt;&lt;a href=&quot;https://yskisking.shop/140&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/140&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/M8DZb/dJMb8XkaDqE/PRdOHckV63LF7rmRsPWYn0/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/W8Ok6/dJMb8YpQDFI/fi2k52dNfjoqq8EZTXBcmk/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/sNjkx/dJMb8QL7eKt/jINkK8c8yxUATvSTX6NHX0/img.jpg?width=1080&amp;amp;height=1440&amp;amp;face=0_0_1080_1440');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[이것이 자바다 개정판 후기] 이것이 자바다 완독 후기, 자바 교재 추천&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;10월 중순부터 읽기 시작한 이것이 자바다 교재를 드디어 완독했다. 자바의 신, 자바의 정석 등등 다른 교재도 고민을 했었지만 난 이것이 자바다를 선택했다. 아직까지 주기적으로 신간이 나오&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&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;Review: &lt;i&gt;Becoming a Spring Boot 3 Backend Developer&lt;/i&gt;: &lt;a href=&quot;https://yskisking.shop/144&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/144&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770110334630&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;[스프링 부트3 백엔드 개발자 되기] 후기, 스프링 부트 교재&quot; data-og-description=&quot;결론부터 말하면, 10점 만점에 4점이다. 스프링 부트를 시작할 다른 사람에게 굳이 추천하고 싶지는 않은 책이다. 책을 끝까지 완독 후 후기를 작성하려 했으나 다른 일정과 겹쳐서 마지막 Git 버&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/144&quot; data-og-url=&quot;https://yskisking.shop/144&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bcQ78P/dJMb9frAGOy/xcPKa0N97A2TTtrgfv1bV1/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/MdtkB/dJMb9kTYcKy/dE7okacZr861OAw6gsGK2K/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/dlGe5p/dJMb9jgsp31/P4tRpog1zKWYeksVU2ikm1/img.jpg?width=1080&amp;amp;height=1440&amp;amp;face=0_0_1080_1440&quot;&gt;&lt;a href=&quot;https://yskisking.shop/144&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/144&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bcQ78P/dJMb9frAGOy/xcPKa0N97A2TTtrgfv1bV1/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/MdtkB/dJMb9kTYcKy/dE7okacZr861OAw6gsGK2K/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/dlGe5p/dJMb9jgsp31/P4tRpog1zKWYeksVU2ikm1/img.jpg?width=1080&amp;amp;height=1440&amp;amp;face=0_0_1080_1440');&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;[스프링 부트3 백엔드 개발자 되기] 후기, 스프링 부트 교재&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;결론부터 말하면, 10점 만점에 4점이다. 스프링 부트를 시작할 다른 사람에게 굳이 추천하고 싶지는 않은 책이다. 책을 끝까지 완독 후 후기를 작성하려 했으나 다른 일정과 겹쳐서 마지막 Git 버&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Coming across Krafton Jungle&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I studied cybersecurity hard, but I realized there was a big gap between that and actual development. Then, I came across Krafton Jungle 5th cohort. It wasn't a typical bootcamp. It was a nerdy yet attractive course that digs deep into CS fundamentals from a Low-Level using C. Even living together for five months and studying 100 hours a week?... I felt like this program was made for me. After five months, I'll have algorithms, CS knowledge, and a portfolio all ready. After a few hours of research, I applied immediately.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The process was: documents, a 1-minute video, a test, and an interview. And I was finally accepted, perhaps because they saw my passion. And so, in March 2024, I entered the Jungle. There were so many great people in the Jungle. People with great backgrounds, people so passionate they didn't sleep, those who were just smart, persistent, or unique... I learned so much just by being around them.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Those five months in the Jungle were incredibly tough. I studied 100 hours a week without a single day off, and I grew like crazy. I was the team leader for the final project, and I learned so much. I'm so greateful to my team for trusting and following me, even though I wasn't perfect. I learned CS, gained project experience, and built teamwork skills, but above all, I think I gained a &quot;developer's mindset&quot;. After spending over 2,000 hours just looking at code, my logical thinking improved and I can read code much faster now. I felt like I built a really strong foundation to become a developer. I have not a single regret about joining the Jungle.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Closing my journey in the Jungle: &lt;a href=&quot;https://yskisking.shop/251&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/251&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770112326709&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;[크래프톤 정글 5기] 팀장으로서 나만무 프로젝트, 그리고 정글을 마무리하며..&quot; data-og-description=&quot;https://poke-code.com&amp;nbsp;드디어 나만무 프로젝트가 끝이 났다. 나만무 기간 하루하루가 정말 너무나도 힘들었기에 도중에는 시간이 너무 느리게 가는 느낌이었지만, 막상 발표를 마치고 나니 이게 끝&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/251&quot; data-og-url=&quot;https://yskisking.shop/251&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bJ7nTr/dJMb9lL6OIj/iS0vmoLjLgfiJltHvcTQ0K/img.png?width=800&amp;amp;height=428&amp;amp;face=0_0_800_428,https://scrap.kakaocdn.net/dn/eMf5w/dJMb8WeuO9U/7IVmr43j4HeARNwICYqXGk/img.png?width=800&amp;amp;height=428&amp;amp;face=0_0_800_428,https://scrap.kakaocdn.net/dn/crOpLc/dJMb8WMkNC6/my0U8xvGGGpQ7cSP6Mke5K/img.png?width=1901&amp;amp;height=1041&amp;amp;face=0_0_1901_1041&quot;&gt;&lt;a href=&quot;https://yskisking.shop/251&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/251&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bJ7nTr/dJMb9lL6OIj/iS0vmoLjLgfiJltHvcTQ0K/img.png?width=800&amp;amp;height=428&amp;amp;face=0_0_800_428,https://scrap.kakaocdn.net/dn/eMf5w/dJMb8WeuO9U/7IVmr43j4HeARNwICYqXGk/img.png?width=800&amp;amp;height=428&amp;amp;face=0_0_800_428,https://scrap.kakaocdn.net/dn/crOpLc/dJMb8WMkNC6/my0U8xvGGGpQ7cSP6Mke5K/img.png?width=1901&amp;amp;height=1041&amp;amp;face=0_0_1901_1041');&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;[크래프톤 정글 5기] 팀장으로서 나만무 프로젝트, 그리고 정글을 마무리하며..&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://poke-code.com&amp;nbsp;드디어 나만무 프로젝트가 끝이 났다. 나만무 기간 하루하루가 정말 너무나도 힘들었기에 도중에는 시간이 너무 느리게 가는 느낌이었지만, 막상 발표를 마치고 나니 이게 끝&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;My first company as a developer: Memento AI&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I completed the Jungle program in August 2024 and joined Memento AI as a conversion-based intern in October 2024. Even without specially refining my resume or having a portfolio, I got the job purely by chance, with great luck, and quite unexpectedly. To the point that even now, I still don't understand why exactly I got hired. It was a job posting introduced by Jungle, and I wonder if the &quot;Jungle&quot; title might have been helpful.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Memento AI was a very aggresive early-stage startup. The company's vision and the CEO's confidence were immense; he openly stated that the work would be busy and assured that rewards would be provided accordingly. I thought it was truly impressive.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Work life was as intense as that confidence. It was standard to start work around 9 AM and leave at 11 PM, and working on weekends was a daily routine. I basically did nothing but code, except for when I was sleeping (but it was manageable because it was less intense than Jungle). The reason I could endure it was that the rewards were clear(salary, lunch/dinner meal plans, etc.), and I was growing so fast that I could actually feel it. When I first joined, I didn't even know directory structures (like MVC patterns, SRP) or what Git conventions were, but I experienced and learned them in no time within the harsh working environment. I handled backend development, infra, and even DB versioning&amp;mdash;it was way more than enough experience for an intern.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Perhaps as a recognition of that passion, I was offered a full-time position just one month into my internship. I was beyond happy. I was filled with hope that staying at this company would help me build my carrer and become a great developer. Even though the workload was intense, it was not a problem at all because I could grow so fast.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Memento AI Job Success Story: &lt;a href=&quot;https://yskisking.shop/289&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/289&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770112438118&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;메멘토AI 채용연계형 인턴 개발자 합격 후기&quot; data-og-description=&quot;얼떨결에 취업을 했다.&amp;nbsp;채용공고가 있는지도 몰랐었고, 정글 동기들 덕에 마감 30분 전에 채용공고를 처음 확인했다.설립된 지 7개월 된 스타트업. 대부분이 개발자로 이루어진 인원 수 40명 규&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/289&quot; data-og-url=&quot;https://yskisking.shop/289&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cZ0WBq/dJMb9jgsqgB/xOBeyKuYIpzO3FKmPbwYHK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/c7PO07/dJMb9eTKR0O/SZLTdHOD3E73cvfrSmFuS0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cLOVLE/dJMb9lk2o8x/GdZq3acdepWuVjxr3zgeP1/img.jpg?width=248&amp;amp;height=301&amp;amp;face=100_54_154_112&quot;&gt;&lt;a href=&quot;https://yskisking.shop/289&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/289&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cZ0WBq/dJMb9jgsqgB/xOBeyKuYIpzO3FKmPbwYHK/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/c7PO07/dJMb9eTKR0O/SZLTdHOD3E73cvfrSmFuS0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cLOVLE/dJMb9lk2o8x/GdZq3acdepWuVjxr3zgeP1/img.jpg?width=248&amp;amp;height=301&amp;amp;face=100_54_154_112');&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;메멘토AI 채용연계형 인턴 개발자 합격 후기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;얼떨결에 취업을 했다.&amp;nbsp;채용공고가 있는지도 몰랐었고, 정글 동기들 덕에 마감 30분 전에 채용공고를 처음 확인했다.설립된 지 7개월 된 스타트업. 대부분이 개발자로 이루어진 인원 수 40명 규&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;My company's closure and my first personal project&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;About three months in, the company went out of business around January 2025. The parent company ordered a sudden shutdown, and dozens of employees became jobless overnight. While some moved to the parent company or found new jobs, I was thrown back into the cold job market. Just when I thought I was finally independent and in control, seeing myself so small again felt so unfair and made me so angry.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;But then, I thought it wasn't so bad. This was because I felt like I was coding without a solid foundation, and I thought I needed time to organize my development knowledge. For once, I wanted to handle everything from full-stack development to deployment by myself and fully understand the entire service flow. I really want to try it with Spring, but I've never used it properly before. So, I decided to study Spring with a proper book this time. I started studying Spring with a book recommended by a peer from Jungle. It was a book written by the author Hongpark.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;But.. it was so strange. The book was too easy. It was such an easy read. Last year, I couldn't understand the Spring book at all, to the point where I even blamed my own talent. The book was so easy to read that it was actually fun. Was it because I had spent five months looking at gruesome low-level code at Jungle? Or was it thanks to my professional experience at Memento AI? Marveling at my improved skills, I finished the book successfully and with great joy. And I immediately started my personal project, &quot;SunCar&quot;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It was a used car trading platform built with Spring boot and Vue.js. Looking back, it was a bit unpolished, but because I focused on learning Spring's architecture and OOP concepts, I believe I built a solid foundation that still helps me today. The zero-downtime deployment I implemented back then is one of the most frequent questions I've received during interviews. I finished reading the book and completed the personal project around May 2025.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Reflections on Memento AI's closure and my resignations: &lt;a href=&quot;https://yskisking.shop/291&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/291&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770112442938&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;메멘토AI의 폐업, 그리고 실직&quot; data-og-description=&quot;메멘토AI는 내 인생 첫 번째 회사이다.&amp;nbsp;인턴으로 취업하여 한 달의 인턴기간을 거치고, 정직원이 되어 한달 반을 일하고 3번의 월급을 채 받지 못했을 때 나는 실직했다. 실력이 형편없어 짤린 &quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/291&quot; data-og-url=&quot;https://yskisking.shop/291&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/5sxNb/dJMb88eVQo3/jrKpPKnk9n1p4KJmj0kegK/img.jpg?width=800&amp;amp;height=598&amp;amp;face=0_0_800_598,https://scrap.kakaocdn.net/dn/bbkiR2/dJMb84p3YBG/ZoQU1mGHQMZOhoGWMdIXH1/img.jpg?width=800&amp;amp;height=598&amp;amp;face=0_0_800_598,https://scrap.kakaocdn.net/dn/t51gH/dJMb86OW2Kn/npPxsh4Yf0BjSBewwHemKK/img.jpg?width=248&amp;amp;height=301&amp;amp;face=100_54_154_112&quot;&gt;&lt;a href=&quot;https://yskisking.shop/291&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/291&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/5sxNb/dJMb88eVQo3/jrKpPKnk9n1p4KJmj0kegK/img.jpg?width=800&amp;amp;height=598&amp;amp;face=0_0_800_598,https://scrap.kakaocdn.net/dn/bbkiR2/dJMb84p3YBG/ZoQU1mGHQMZOhoGWMdIXH1/img.jpg?width=800&amp;amp;height=598&amp;amp;face=0_0_800_598,https://scrap.kakaocdn.net/dn/t51gH/dJMb86OW2Kn/npPxsh4Yf0BjSBewwHemKK/img.jpg?width=248&amp;amp;height=301&amp;amp;face=100_54_154_112');&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;메멘토AI의 폐업, 그리고 실직&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;메멘토AI는 내 인생 첫 번째 회사이다.&amp;nbsp;인턴으로 취업하여 한 달의 인턴기간을 거치고, 정직원이 되어 한달 반을 일하고 3번의 월급을 채 받지 못했을 때 나는 실직했다. 실력이 형편없어 짤린&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Full scale Job Search and Joining KIDB&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I updated my resume and portfolio by adding my personal project and began my job search in earnest. To be honest, since I landed a job at Memento AI after submitting just one resume, I had never faced a real challenge in the job market. In the end, I submitted 60 applications and passed the application screening for Kakao and KIDB.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I failed Kakao's coding test right away because my algorithm skills were quite poor, but I passed both rounds of interview at KIDB, successfully landing my second job as a developer. It was the only place among all my interviews that provided an interview fee, and the interviewers were so polite that they left a very positive impression on me.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KIDB is a brokerage firm that mediates bonds and derivatives. Since I'm very interested in making money, the financial domain wasn't a bad fit, but I hesitated a lot because of rumors that there are fewer development tasks in the finance industry. Truly, a great deal. For a developer, the pros of the finance industry are high salaries, good work-life balance, and job stability, but the downside is that it's difficult to gain experience solving deep technical challenges. Ultimately, I chose &quot;money&quot;, which was my top priority in my life, thinking to myself, &quot;Well, I'm developing to earn money anyway, so let's just go for it,&quot; and decided to show up for work. It was August 2025.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Reflections on Joining KIDB:&amp;nbsp;&lt;a href=&quot;https://yskisking.shop/346&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/346&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770115596704&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;개발자 취업준비 6개월, KIDB 최종 합격 후기와 금융권 선택 이유 + 포트폴리오&quot; data-og-description=&quot;메멘토 AI 3개월 근무 중 폐업에 의해 퇴직하고, 6개월의 취업준비를 거친 후에 드디어 재취업을 했다. 3개월이라는 근무 경험이 있긴 하지만 경력으로 인정받을 정도는 아니기 때문에, 사실상 신&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/346&quot; data-og-url=&quot;https://yskisking.shop/346&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/QpapB/dJMb81GSpcE/CvksnyZlVVyaB59aZQVF6K/img.png?width=800&amp;amp;height=485&amp;amp;face=0_0_800_485,https://scrap.kakaocdn.net/dn/hFs0x/dJMb88FZ7Y9/CwILkTBeJEeklhemD4FK81/img.png?width=800&amp;amp;height=485&amp;amp;face=0_0_800_485,https://scrap.kakaocdn.net/dn/bQ6dS6/dJMb9aKAkzg/CUGjRfOkIOIglKeiF2kMu1/img.png?width=1441&amp;amp;height=874&amp;amp;face=0_0_1441_874&quot;&gt;&lt;a href=&quot;https://yskisking.shop/346&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/346&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/QpapB/dJMb81GSpcE/CvksnyZlVVyaB59aZQVF6K/img.png?width=800&amp;amp;height=485&amp;amp;face=0_0_800_485,https://scrap.kakaocdn.net/dn/hFs0x/dJMb88FZ7Y9/CwILkTBeJEeklhemD4FK81/img.png?width=800&amp;amp;height=485&amp;amp;face=0_0_800_485,https://scrap.kakaocdn.net/dn/bQ6dS6/dJMb9aKAkzg/CUGjRfOkIOIglKeiF2kMu1/img.png?width=1441&amp;amp;height=874&amp;amp;face=0_0_1441_874');&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;개발자 취업준비 6개월, KIDB 최종 합격 후기와 금융권 선택 이유 + 포트폴리오&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;메멘토 AI 3개월 근무 중 폐업에 의해 퇴직하고, 6개월의 취업준비를 거친 후에 드디어 재취업을 했다. 3개월이라는 근무 경험이 있긴 하지만 경력으로 인정받을 정도는 아니기 때문에, 사실상 신&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Quitting KIDB and Starting Over as a Job Seeker&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;My responsibilities at KIDB were somewhat removed from direct development. I was doing IT-related work, but it wasn't the &quot;typical developer&quot; tasks like writing business logic, designing architectures, or optimizing performance. The company itself was wonderful. I could leave work on time every single day, my senior colleagues were very supportive, and the benefits were great&amp;ndash;it was almost the perfect workplace.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;However, I was struggling a lot mentally. Doing work that wasn't development, I spent the whole day daydreaming; I couldn't focus, I felt unnecessarily frustrated, and I desperately wanted to go back to developing. At Memento AI, where I worked on backend development, I was pushed to my physical limits, yet I never once felt unhappy. Rather, it was much closer to happiness. I thought to myself, &quot;This isn't the path for me.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;...Even so, I deeply agonized over whether to quit. When the job market so frozen, I had no idea when I'd be employed again, and since I was pushing 30, I felt that wasting any more time would be risky. So, at first, I started preparing for a job change while still working at the company.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;However, even preparing for the coding tests was difficult. After work and dinner on weekdays, I only had about three hours of free time. Since a single algorithm problem could take over three hours, solving even one problem a day was overwhelming. At this rate, I felt like I wouldn't be able to change jobs even after one or two years. Most of all, what suffered me the most was the crazy anxiety of wanting to return to being a developer as soon as possible. Just sitting at my desk in the office felt like pure torture to me.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Finally, in mid-September 2025, I handed in my resignation with a sincere apology. Honestly, I wouldn't have blamed them if they were annoyed since I was leaving so soon after being hired. I'm still grateful to the director who treated me to a wonderful dinner on my last day, and to my colleagues who cheered me on.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Re-hired...? No, I Turned It Down.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;After the memory of totally bombing the Kakao coding test, I decided to dive into algorithm preparation in earnest. To be honest, I had been preparing, but because I did it so inconsistently out of reluctance, my skills didn't improve. While thinking about how to restore my shattered sense for algorithms, I decided to use books, which is the method that suits me best. I chose the textbook &lt;i&gt;&quot;Becoming a Coding Test Passer(코딩 테스트 합격자 되기)&quot;&lt;/i&gt;, and from then on, I solved algorithm problems every day, hardly missing a single day. As I practiced consistently while being fully aware of the importance of coding tests, my skills improved to the point where I could pass most of them.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Meanwhile, I passed the resume screening for a startup. Perhaps because I prepared so hard, I passed the live coding test, and I received the final offer, maybe because they thought so well of me in the second interview too. But.. I wasn't sure. Their main tech stack was PHP, and they even mentioned that the backend wasn't a priority, which meant I would have to juggle various roles like frontend and planning without a clear team. To me, there were simply too many uncertainties to accept the offer. Plus, the compensation was also unsatisfactory.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Nevertheless, I agonize over whether or not I should actually go to work. However, I had already left KIDB to become a developer, and I felt that leaving another job due to dissatisfaction was absolutely out of the question. So, I declined&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;the offer.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I had a few other interviews as well, but I simply couldn't pass the resume screening for the companies I actually wanted to join. At that moment, I realized my shortcomings all to well. I thought, &quot;Ah, if I want get into the companies I desire, I need to change.&quot;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Review: &lt;i&gt;Becoming a Coding Test Passer&lt;/i&gt;: &lt;a href=&quot;https://yskisking.shop/365&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/365&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770114131965&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[코딩 테스트 합격자 되기] 프로그래머스 기반 코딩 테스트 입문서 후기, 코딩 테스트 입문서 추&quot; data-og-description=&quot;&amp;quot;코딩 테스트 합격자 되기&amp;quot; 교재를 완독했다. 하루에 1문제 ~ 3문제 정도를 푼 결과 완독은 2달 정도 걸렸다. 분량이 700페이지 정도 되기에 이걸 언제 다 읽나 하긴 했지만, 매일 조금씩 늘어가는 &quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/365&quot; data-og-url=&quot;https://yskisking.shop/365&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bPhPwt/dJMb8RjW939/7Q9Tcb0lqhSrUFuo5jZdv1/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/cu3LVM/dJMb8WeuPgE/vltlPl5kYrTZzcXLaDo3PK/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/e216x/dJMb8U8ORKt/9ajwEs8ZJNpNCoyXthdwSk/img.jpg?width=3024&amp;amp;height=4032&amp;amp;face=0_0_3024_4032&quot;&gt;&lt;a href=&quot;https://yskisking.shop/365&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/365&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bPhPwt/dJMb8RjW939/7Q9Tcb0lqhSrUFuo5jZdv1/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/cu3LVM/dJMb8WeuPgE/vltlPl5kYrTZzcXLaDo3PK/img.jpg?width=800&amp;amp;height=1066&amp;amp;face=0_0_800_1066,https://scrap.kakaocdn.net/dn/e216x/dJMb8U8ORKt/9ajwEs8ZJNpNCoyXthdwSk/img.jpg?width=3024&amp;amp;height=4032&amp;amp;face=0_0_3024_4032');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[코딩 테스트 합격자 되기] 프로그래머스 기반 코딩 테스트 입문서 후기, 코딩 테스트 입문서 추&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&quot;코딩 테스트 합격자 되기&quot; 교재를 완독했다. 하루에 1문제 ~ 3문제 정도를 푼 결과 완독은 2달 정도 걸렸다. 분량이 700페이지 정도 되기에 이걸 언제 다 읽나 하긴 했지만, 매일 조금씩 늘어가는&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;More than doubled my resume pass rate: The MSA Project (msa-perf-lab)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;There was absolutely nothing special about my previous resume. I had my certifications, Jungle, Memento AI, Suncar. I thought they were decent enough, but they lacked the unique edge needed to get into the companies I truly wanted as a junior developer.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;So, around November 2025, I decided to create the unique edge. I thought I should add advanced backend technologies frequently seen in recent JDs&amp;ndash;such as MSA, Redis(caching), MQ, gRPC and Prometheus/Grafana&amp;ndash;to my resume. So, how should I include them? Simply using them is something anyone can do. How could I add that unique edge?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I decided to define four types of bottlenecks that can occur in a server. Namely: Communication Protocols, I/O Bound, CPU Bound, and DB Bound. I built a Flask/Go MSA server, implemented four types of bottlenecks, and optimized them. I also measured and compared performance before and after, collected metrics, and displayed them on Grafana. I used InfluxDB and Prometheus for metric collection, conducted in-depth analyses on why the performance improved, and included those findings in my portfolio.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Metrics measured:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Latency(Response Time),&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Throughput,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Drop-Rate(Percentage of dropped requests relative to total requests),&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Memory Usage,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU Usage&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The four types of bottlenecks:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Communication Protocols: Transitioned from REST to gRPC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I/O Bound: Decoupled features like email and notification from business logic and processed them in the background using Message Queue (MQ)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU Bound: Offloaded heavy computational tasks (loops) from the Flask server to a Go server&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB Bound: Switched from a full scan of 1 million records to Redis caching&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The independent variables for each experiment, such as RPS, Payload Size, and Complexity Level, were applied appropriately to suit each experiment. I completed this project by investing over 300 hours in a single month, and I learned a great deal through this experience. It also significantly improved the quality of my resume and portfolio, and it was enough to create the &quot;unique edge as a junior&quot; that I had aimed for.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Actually, after adding the MSA project, the pass rate for resume screening more than doubled, increasing from approximately 3% to 7%. What's more, this increase occurred even thought I applied only to reputable companies with solid compentation and work environments after adding the MSA project. Furthermore, most of my interviews began and ended solely with questions centered around the MSA project. As a result, I went from landing only one interview every few weeks to landing two or three interviews every single week.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A post on the CPU-bound experiment in the msa-perf-lab: &lt;a href=&quot;https://yskisking.shop/363&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/363&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1770115798492&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;[msa-perf-lab] CPU Bound 작업 성능 비교: Flask 자체 연산 vs Go 위임 - 멀티스레드 병렬 처리의 효율성 증&quot; data-og-description=&quot;저번 시간엔 RabbitMQ 비동기 처리를 통해, Flask의 I/O Bound 병목점을 해결해 보았다. 응답시간은 약 500배 차이가 났었고, 처리량 및 드랍률도 RPS가 증가할수록 격차가 심해졌다. 이번 시간엔 Flask의 &quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/363&quot; data-og-url=&quot;https://yskisking.shop/363&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/r8huL/dJMb9aKAkz9/1iHwGdDAkJinMlVE7BjJI1/img.png?width=800&amp;amp;height=250&amp;amp;face=0_0_800_250,https://scrap.kakaocdn.net/dn/iVT5A/dJMb88FZ70A/tR3LQOKLGOkJMrFKIGdlo1/img.png?width=800&amp;amp;height=250&amp;amp;face=0_0_800_250,https://scrap.kakaocdn.net/dn/bSemIH/dJMb83koaFT/iwAwpsmf41H6oiPXjOOKvK/img.png?width=1256&amp;amp;height=394&amp;amp;face=0_0_1256_394&quot;&gt;&lt;a href=&quot;https://yskisking.shop/363&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/363&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/r8huL/dJMb9aKAkz9/1iHwGdDAkJinMlVE7BjJI1/img.png?width=800&amp;amp;height=250&amp;amp;face=0_0_800_250,https://scrap.kakaocdn.net/dn/iVT5A/dJMb88FZ70A/tR3LQOKLGOkJMrFKIGdlo1/img.png?width=800&amp;amp;height=250&amp;amp;face=0_0_800_250,https://scrap.kakaocdn.net/dn/bSemIH/dJMb83koaFT/iwAwpsmf41H6oiPXjOOKvK/img.png?width=1256&amp;amp;height=394&amp;amp;face=0_0_1256_394');&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;[msa-perf-lab] CPU Bound 작업 성능 비교: Flask 자체 연산 vs Go 위임 - 멀티스레드 병렬 처리의 효율성 증&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;저번 시간엔 RabbitMQ 비동기 처리를 통해, Flask의 I/O Bound 병목점을 해결해 보았다. 응답시간은 약 500배 차이가 났었고, 처리량 및 드랍률도 RPS가 증가할수록 격차가 심해졌다. 이번 시간엔 Flask의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Final Job Offer from AIVIS&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I received a call from AIVIS informing me that I had passed the resume screening. The first hurdle consisted of a take-home assignment and a technical interview. Although I cannot disclose the details, I put all my honed skills into the assignment to make it flawless. The interview proceeded regardless of the assignment results, but I gave it my absolute best.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1차면접은 CTO님과의 1:1 면접이었다. 일단 면접관님이 굉장히 젠틀하셔서 좋은 인상을 받고 시작했다. 면접 질문은 엄청나게 어려운 질문은 아니었기에 내가 준비해 왔던 대로 답변을 드렸고, 최고의 극찬을 들었다. '너무 답변을 잘 하셔서, 더 이상 물어볼 게 없네요.'&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 나는 2일 후에 1차면접에 합격했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차면접은 대표님과의 1:1 면접이었다. 1차면접과 공통적으로 느낀 건 두분 다 너무 친절하시고 젠틀하다는 점이었다. 그리고 나는 면접 중 또 하나의 과분한 칭찬을 받았다. 'CTO님께서 2차 면접까지 잘 안 보내시는데, 직접 뵈니 왜 올리신 줄 알겠네요'&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 나는 면접 도중 구두로 오퍼를 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 대학 졸업 직후, 성남의 정보보안 회사 모의해킹 &amp;amp; 보안 컨설팅 직무에 취업했다. 그러나 입사를 포기하고 개발자로 전향했다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그로부터 3년간 총 3번의 취업과 2번의 퇴사, 1번의 입사 포기, 그리고 약 400개의 서류 탈락을 지나온 끝에 나는 면접실에서 최고의 극찬을 들었다. 에이비스 채용과정은 나에게 그저 영광의 연속이었으며, 지난 3년을 인정받고 보상받는 시간이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;내 가치를 알아봐 준 최고의 회사에서, 나는 2월 9일부로 새로운 삶을 시작하게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;====================&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;마무리, 취업준비생들에게 드리고 싶은 말&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리 회사에 대해 많이 알아보았다. 기술적으로도 뛰어났고, 구성원들도 뛰어났다. 너무 좋은 회사다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그런데, 나는 왜 이 회사에서만 이런 특급 칭찬들을 받았을까? 면접은 항상 똑같이 보는데도 말이다. 생각해봐도 잘 모르겠다. 회사의 Fit과 맞기 때문일까?&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;현업 개발자 분에게 조언을 하나 들은 적이 있다. '면접에서 떨어져도, 높은 확률로 너의 부족함은 아닐 것이다'&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 말이 맞는 것 같다. 어느 회사 면접을 보는가에 따라서도 나에 대한 평가가 이렇게 달라지는데, 현 취업준비생 분들도 면접 몇 군데 떨어졌다고 해서 모든 잘못을 본인에게 돌릴 필요는 없는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취업준비할 때 가장 중요한 것은 멘탈을 잡는 것이다. 하지만 '멘탈을 잡아라' 라고 말은 못 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;제일 중요한 거긴 한데, 그게 의식한다고 되는 건 아니니까.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 생각에 가장 중요한 것은 2가지다:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;첫 번째, 반드시 취업할 수 있다고 믿는 것&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;두 번째, 반드시 어제보다 발전할 것 (아주 조금이라도)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고리즘을 풀던, 프로젝트를 하던, 면접 준비를 하던, 이력서를 수정하던 뭐가 됐든 좋다. 올바른 방향으로 꾸준히 나아가면 무엇이든 반드시 이룰 수 있다. 멈추지만 않으면 된다. 모든 취업준비생들을 응원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1405&quot; data-origin-height=&quot;881&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FyyaT/dJMcacoq7qS/AhDUrDLDRu0GRqKzy4g3Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FyyaT/dJMcacoq7qS/AhDUrDLDRu0GRqKzy4g3Ok/img.png&quot; data-alt=&quot;약 400개 서류 탈락 (기업명 모자이크)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FyyaT/dJMcacoq7qS/AhDUrDLDRu0GRqKzy4g3Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFyyaT%2FdJMcacoq7qS%2FAhDUrDLDRu0GRqKzy4g3Ok%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;1405&quot; height=&quot;881&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1405&quot; data-origin-height=&quot;881&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;약 400개 서류 탈락 (기업명 모자이크)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;혹시나 개발자 취업 관련하여 질문이나 토론할 거리가 있으시다면, 자유롭게 댓글 부탁드립니다.&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;====================&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Github: &lt;a href=&quot;https://github.com/YangSunkue&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/YangSunkue&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Linkedin: &lt;a href=&quot;https://www.linkedin.com/in/%EC%84%A0%EA%B7%9C-%EC%96%91-495303337/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.linkedin.com/in/%EC%84%A0%EA%B7%9C-%EC%96%91-495303337/&lt;/a&gt;&lt;/p&gt;</description>
      <category>업적</category>
      <category>AIVIS</category>
      <category>개발자 전향</category>
      <category>개발자 취업</category>
      <category>개발자 취업준비</category>
      <category>개발자 포트폴리오</category>
      <category>개발자 프로젝트</category>
      <category>백엔드 취업</category>
      <category>신입 개발자</category>
      <category>알고리즘</category>
      <category>에이비스</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/367</guid>
      <comments>https://yskisking.tistory.com/367#entry367comment</comments>
      <pubDate>Wed, 4 Feb 2026 14:45:25 +0900</pubDate>
    </item>
    <item>
      <title>보안에서 개발로, 3년의 사투 끝에 '더 물어볼 게 없다'는 말을 듣기까지 - 에이비스(AIVIS) 신입 개발자 취업</title>
      <link>https://yskisking.tistory.com/366</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;나는 대학 졸업 직후, 성남의 정보보안 회사 모의해킹 &amp;amp; 보안 컨설팅 직무에 취업했다. 그러나 입사를 포기하고 개발자로 전향했다.&lt;br /&gt;그로부터 3년간 총 3번의 취업과 2번의 퇴사, 1번의 입사 포기, 그리고 약 400개의 서류 탈락을 지나온 끝에 나는 면접실에서 최고의 극찬을 들었다. '너무 답변을 잘 하셔서, 더 이상 물어볼 게 없네요.' 이 글은 그 1000일간의 처절한 기록이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;정보보안에서 개발자로&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년 초, 나는 정보보안 학과를 졸업하고 모의해킹 직무로 취직하기 위해 당시 나의 꿈의 기업 안랩에 이력서를 넣었다. 열심히 공부했던 보상이었는지 서류에 합격했지만, 인생 첫 면접이었던 나는 면접에서 어설픈 답변과 함께 되지도 않는 자신감을 표출했고 쓰디 쓴 탈락을 맛보았다. 당연히 붙을 줄 알았던 자만심과, 정말로 붙고 싶었던 진심이 나를 더 아프게 했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;다른 회사를 찾아봐야 했다. 그러나 모의해킹 신입을 뽑는 규모 있는 회사는 거의 없었다. 결국 성남의 중소 정보보안 회사에 이력서를 넣고 합격했다. 출근 전 계약서를 먼저 쓰고 본가로 내려오는 기차에서, 성에 차지 않는 연봉이 적힌 근로계약서를 몇 시간동안 들여다보며 나는 굉장히 이상한 기분에 잠겼다. 당시 나의 1순위 목표는 &quot;돈&quot;이었기에(장기적), 첫 취업에 큰 회사로 가지 못 한다면 개발로 전향하는 게 훨씬 낫다고 생각했다. 본가로 내려오고 정확히 2일 뒤 나는 입사를 포기했고 개발자로 전향했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;탈보안할 당시 나의 심경을 쓴 글: &lt;a href=&quot;https://yskisking.shop/105&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://yskisking.shop/105&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;탈보안&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;탈보안 하기로 했다. 성남의 한 회사에 신입 정보보호 기술 컨설턴트 직무로 취업에 성공하고, 근로계약서까지 썼다.개인적인 생각으로 연봉은 동종업계 신입치곤 높았다. 만족했다.근처에 집&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/105&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/SfpM3/dJMb84XTY9D/AAAAAAAAAAAAAAAAAAAAAM4X4ra3DbLgbwYwUbwQHeqyBif4OncpgpUZw-PBvPI4/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=BY9Zr6wiOzu75WEdUfx8VFDthwk%3D&quot; data-og-url=&quot;https://yskisking.shop/105&quot;&gt;&lt;a href=&quot;https://yskisking.shop/105&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/105&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/SfpM3/dJMb84XTY9D/AAAAAAAAAAAAAAAAAAAAAM4X4ra3DbLgbwYwUbwQHeqyBif4OncpgpUZw-PBvPI4/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=BY9Zr6wiOzu75WEdUfx8VFDthwk%3D');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;탈보안&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;탈보안 하기로 했다. 성남의 한 회사에 신입 정보보호 기술 컨설턴트 직무로 취업에 성공하고, 근로계약서까지 썼다.개인적인 생각으로 연봉은 동종업계 신입치곤 높았다. 만족했다.근처에 집&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;자격증 취득과 어설픈 개발 공부&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년 6월 경, 나는 알고리즘이 뭔지 스프링이 뭔지도 모르는 완전한 개발 문외한이었다. 뭘 공부해야 할 지도 모르겠고, 우선 가장 자신있는 분야였던 자격증부터 취득하기로 했다. 개발자 대표 자격증인 정보처리기사와 SQLD를 목표로 했는데 난 정보보안기사 경험이 있었기 때문에 쉽게 딸 수 있을 거라 자신했다. 개발 공부를 본격적으로 하다가 자격증을 따려고 하면 흐름이 깨질 것 같다는 생각에, '아주 빠르게 자격증부터 따고 본격적으로 개발 공부를 하자' 라고 생각했다. 결국 그 해 10월, 11월에 SQLD와 정보처리기사를 합격했다. 근데 절대 생각만큼 쉽지 않았고 엄청 고생했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이제 개발 공부를 시작해야 했다. 뭘 공부하지? 백엔드, 프론트엔드? 그게 뭐지? 백엔드가 더 맞는 거 같은데, 뭐 부터 해야 하지? 스프링? 이게 제일 유명한건가? 근데 JAVA를 먼저 해야 한다고? ..... 등등, 모르는 키워드가 난무했기에 나는 공부 방향성을 잡는 것 조차 어려웠다. JAVA를 먼저 공부하려 했는데, 사람들이 김영한님 Spring 강의를 보랜다. 인프런에서 무료로 들을 수 있다고 한다. 학교에서 JAVA 수업을 듣긴 했으니 강의 먼저 들어볼까? 라는 생각에 들어봤는데 진짜, 진심으로, 단 1도 이해가 되지 않았다. 컨트롤러, 리파지터리, 어노테이션.. 그리고 DTO도 충격적이었다. 왜 굳이 저기에 담아서 더 복잡하게 만들지? 지금 생각하면 웃길 정도의 수준이었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그래서 JAVA 부터 제대로 시작하기로 했다. '이것이 자바다' 라는 책을 약 1달에 걸쳐 완독했는데, 특히 맨 마지막 챕터 채팅방 만드는 부분에서 정말 고생을 많이 했다. 정말 좋은 책이었고, 이제 JAVA는 마스터 한 것 같다. 다시 김영한님 강의를 들었다.&lt;br /&gt;.... 여전히 많이 어렵다. 아직 내가 들을 수준이 아닌걸까? 그래서 Spring을 책으로 공부하기로 했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;골든래빗에서 나온 '스프링 부트3 백엔드 개발자 되기' 라는 책을 읽었다. 아... 근데 이것도 어렵다. 정말 정말 너무 어려워서, 이해도 되지 않은 채 코드만 따라 치고 있는 나를 보며 '난 개발에 재능이 없나' 라고 생각했다. 결국 책을 다 읽긴 했지만 내 머리에 남은 것은 거의 없었고, 개발에 대한 자신감만 깎여 내려갔다. 음.. 하지만 이 책이 별로인 영향도 분명히 있었을 것이다. 자세한 건 책 후기에 써놓았다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이것이 자바다 후기: &lt;a href=&quot;https://yskisking.shop/140&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://yskisking.shop/140&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;[이것이 자바다 개정판 후기] 이것이 자바다 완독 후기, 자바 교재 추천&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;10월 중순부터 읽기 시작한 이것이 자바다 교재를 드디어 완독했다. 자바의 신, 자바의 정석 등등 다른 교재도 고민을 했었지만 난 이것이 자바다를 선택했다. 아직까지 주기적으로 신간이 나오&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/140&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/M8DZb/dJMb8XkaDqE/AAAAAAAAAAAAAAAAAAAAAKvNVdmxlEPYMGb9N-qUUttIbR2N6kx59EvS5JpUq9zA/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=p9xvWhTMXzEU0YX1lvUNI5gB1QE%3D&quot; data-og-url=&quot;https://yskisking.shop/140&quot;&gt;&lt;a href=&quot;https://yskisking.shop/140&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/140&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/M8DZb/dJMb8XkaDqE/AAAAAAAAAAAAAAAAAAAAAKvNVdmxlEPYMGb9N-qUUttIbR2N6kx59EvS5JpUq9zA/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=p9xvWhTMXzEU0YX1lvUNI5gB1QE%3D');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[이것이 자바다 개정판 후기] 이것이 자바다 완독 후기, 자바 교재 추천&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;10월 중순부터 읽기 시작한 이것이 자바다 교재를 드디어 완독했다. 자바의 신, 자바의 정석 등등 다른 교재도 고민을 했었지만 난 이것이 자바다를 선택했다. 아직까지 주기적으로 신간이 나오&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;스프링 부트3 백엔드 개발자 되기 후기: &lt;a href=&quot;https://yskisking.shop/144&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://yskisking.shop/144&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;[스프링 부트3 백엔드 개발자 되기] 후기, 스프링 부트 교재&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;결론부터 말하면, 10점 만점에 4점이다. 스프링 부트를 시작할 다른 사람에게 굳이 추천하고 싶지는 않은 책이다. 책을 끝까지 완독 후 후기를 작성하려 했으나 다른 일정과 겹쳐서 마지막 Git 버&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/144&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/bcQ78P/dJMb9frAGOy/AAAAAAAAAAAAAAAAAAAAAMif7FF_sE55NG4oL6ISCjX6ynmh2HzS8bCYcXbXymle/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=cGWt2%2FsINLAYZDQGCJUUYwLQfgE%3D&quot; data-og-url=&quot;https://yskisking.shop/144&quot;&gt;&lt;a href=&quot;https://yskisking.shop/144&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/144&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/bcQ78P/dJMb9frAGOy/AAAAAAAAAAAAAAAAAAAAAMif7FF_sE55NG4oL6ISCjX6ynmh2HzS8bCYcXbXymle/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=cGWt2%2FsINLAYZDQGCJUUYwLQfgE%3D');&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;[스프링 부트3 백엔드 개발자 되기] 후기, 스프링 부트 교재&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;결론부터 말하면, 10점 만점에 4점이다. 스프링 부트를 시작할 다른 사람에게 굳이 추천하고 싶지는 않은 책이다. 책을 끝까지 완독 후 후기를 작성하려 했으나 다른 일정과 겹쳐서 마지막 Git 버&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;크래프톤 정글을 만나다&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 정보보안을 열심히 공부했지만, 개발과 직접 연결하기엔 많은 거리가 있다는 것을 깨달았다. 그 때 크래프톤 정글 5기를 만났다. 뻔한 부트캠프 과정이 아니라, 컴퓨터공학 기초를 C언어로 Low-Level부터 진득하게 파는 변태적이면서도 매력적인 과정이었다. 심지어 5개월동안 합숙하며 주 100시간씩 공부한다고?... 이건 나를 위한 프로그램이었다. 5개월 뒤에 나는 알고리즘, CS지식, 포트폴리오 모두 준비되어 있을 것이다. 몇 시간 서칭해본 후 즉시 지원했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;전형은 서류 + 1분 자기소개 영상 -&amp;gt; 과제 테스트 -&amp;gt; 면접 -&amp;gt; 합격 순으로 이루어졌고 내 열정을 알아봐 주셨는지 최종합격을 받았다. 그렇게 2024년 3월, 정글에 입소했다. 정글엔 좋은 사람이 너무나 많았다. 학벌이나 경력이 뛰어난 사람, 열정이 넘쳐 잠도 안 자는 사람, 그냥 똑똑한 사람, 집요한 사람, 특이한 사람 등.. 이 사람들과 함께 있는 것 만으로도 간접적으로 배우는 게 굉장히 많았다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;정글에서의 5개월은 정말 힘들었다. 진짜로 쉬는 날 하루 없이 주 100시간을 공부했고, 미친 듯이 성장했다. 최종 팀 프로젝트에서는 내가 팀장을 맡았고 참 많은 것을 배웠다. 부족한 팀장을 믿고 따라와준 팀원들에게 정말 감사하다. 정글에서는 CS도 배우고 프로젝트 경험도 쌓고 협업 능력도 쌓았지만, 무엇보다 가장 많이 배운 건 '개발자스러운 생각 회로' 인 것 같다. 총 2000시간 이상 코드만 보다 보니 논리적으로 사고하는 능력이 길러졌고, 코드를 읽는 속도도 빨라졌다. 개발자가 되기 위한 기초 체력을 정말 탄탄히 쌓았다고 느꼈다. 정글에 간 건 한 점 후회가 없다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;정글을 마무리하며: &lt;a href=&quot;https://yskisking.shop/251&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://yskisking.shop/251&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;[크래프톤 정글 5기] 팀장으로서 나만무 프로젝트, 그리고 정글을 마무리하며..&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;https://poke-code.com&amp;nbsp;드디어 나만무 프로젝트가 끝이 났다. 나만무 기간 하루하루가 정말 너무나도 힘들었기에 도중에는 시간이 너무 느리게 가는 느낌이었지만, 막상 발표를 마치고 나니 이게 끝&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/251&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/bJ7nTr/dJMb9lL6OIj/AAAAAAAAAAAAAAAAAAAAAOSBoKRWEKMb__mGnQjhceIJKMTkC1Epo4nwPVDBkhBX/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=iXBcTunxVS%2FaLxJWPor2Zv39M4I%3D&quot; data-og-url=&quot;https://yskisking.shop/251&quot;&gt;&lt;a href=&quot;https://yskisking.shop/251&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/251&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/bJ7nTr/dJMb9lL6OIj/AAAAAAAAAAAAAAAAAAAAAOSBoKRWEKMb__mGnQjhceIJKMTkC1Epo4nwPVDBkhBX/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=iXBcTunxVS%2FaLxJWPor2Zv39M4I%3D');&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;[크래프톤 정글 5기] 팀장으로서 나만무 프로젝트, 그리고 정글을 마무리하며..&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://poke-code.com&amp;nbsp;드디어 나만무 프로젝트가 끝이 났다. 나만무 기간 하루하루가 정말 너무나도 힘들었기에 도중에는 시간이 너무 느리게 가는 느낌이었지만, 막상 발표를 마치고 나니 이게 끝&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;개발자로서의 첫 회사, 메멘토 AI&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정글을 2024년 8월에 수료하고, 2024년 10월에 메멘토 AI에 채용연계형 인턴으로 입사했다. 특별히 이력서를 다듬지도 않았고 포트폴리오도 없었는데 정말 우연히, 운 좋게, 덜컥 붙어버렸다. 지금 생각해도 대체 왜 붙은 건지 이해가 안 될 정도로 말이다. 정글에서 소개해 준 채용공고였는데 정글 타이틀이 도움이 되었나 싶기도 하고.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;메멘토 AI는 아주 공격적인 초창기 스타트업이었다. 회사의 비전과 대표의 자신감이 엄청났고, 일이 바쁘다는 걸 당당히 밝혔고 그만큼의 보상을 준다고 확언했다. 정말 멋지다고 생각했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;회사 생활은 그 자신감 만큼 정말 빡빡했다. 오전 9시 즈음에 출근해서 밤 11시에 퇴근하는 게 기본이었고 주말 출근도 일상이었다. 그냥 자는 시간만 빼고 코딩만 했다고 봐도 될 정도로 말이다 (근데 정글보단 덜 힘들어서 할만했음). 버틸 수 있었던 이유는 보상이 확실했으며(연봉, 점심/저녁 식대 등), 내가 성장하는 게 느껴질 정도로 빠르게 성장했기 때문이다. 입사 당시 나는 디렉터리 구조도 몰랐고 (MVC패턴, SRP 등) Git 컨벤션이 뭔지도 몰랐는데 혹독한 근무 환경에서 순식간에 경험하고, 배워나갔다. 백엔드 개발 + 인프라 관리 + DB 버전 관리 까지 맡았으니 인턴에겐 정말 과분한 경험이었을 터다.&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;결국 그 열정을 인정받았는지, 나는 인턴 근무 1개월만에 정규직으로 전환되었다. 정말 정말 기뻤다. 이 회사에서 꾸준히 일하면 경력도 쌓이고 훌륭한 개발자가 될 수 있겠다는 희망에 부풀었다. 근무 강도는 높았지만 빠르게 성장할 수 있었기에 전혀 문제가 되지 않았다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;메멘토 AI 취업 후기: &lt;a href=&quot;https://yskisking.shop/289&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://yskisking.shop/289&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;메멘토AI 채용연계형 인턴 개발자 합격 후기&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;얼떨결에 취업을 했다.&amp;nbsp;채용공고가 있는지도 몰랐었고, 정글 동기들 덕에 마감 30분 전에 채용공고를 처음 확인했다.설립된 지 7개월 된 스타트업. 대부분이 개발자로 이루어진 인원 수 40명 규&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/289&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/cZ0WBq/dJMb9jgsqgB/AAAAAAAAAAAAAAAAAAAAAF0zc2waTX2PD6ruvcTyD4una8I-t_0qlsie4eZDB6MI/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=nkI7r3%2FAhVoxvxUL0GiUcEHA3v8%3D&quot; data-og-url=&quot;https://yskisking.shop/289&quot;&gt;&lt;a href=&quot;https://yskisking.shop/289&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/289&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/cZ0WBq/dJMb9jgsqgB/AAAAAAAAAAAAAAAAAAAAAF0zc2waTX2PD6ruvcTyD4una8I-t_0qlsie4eZDB6MI/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=nkI7r3%2FAhVoxvxUL0GiUcEHA3v8%3D');&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;메멘토AI 채용연계형 인턴 개발자 합격 후기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;얼떨결에 취업을 했다.&amp;nbsp;채용공고가 있는지도 몰랐었고, 정글 동기들 덕에 마감 30분 전에 채용공고를 처음 확인했다.설립된 지 7개월 된 스타트업. 대부분이 개발자로 이루어진 인원 수 40명 규&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;회사 폐업과 첫 개인 프로젝트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3개월쯤 근무했을까, 2025년 1월 경 회사가 폐업했다. 모회사 측에서 갑작스러운 사업 중단을 명령했고 하루 아침에 수십명의 근로자들이 백수 신세가 되었다. 그 과정에서 모회사로 옮겨간 사람도, 이직한 사람도 있었지만 난 차가운 취업 시장에 다시 내던져졌다. 드디어 독립하여 스스로 모든 걸 책임질 수 있게 되었다고 생각했는데, 다시 초라해진 내 모습을 보고 너무나도 억울하고 화가 났다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그러나 긍정적으로 생각하기로 했다. 왜냐하면 내 스스로도 개발에 대한 근본 없이 개발하고 있다고 느꼈고, 개발 지식을 정비할 시간이 필요하다 생각했기 때문이다. 한번쯤은 혼자서 풀스택 개발 및 배포까지 수행하며 서비스 흐름을 완전히 이해해보고 싶었다. 근데 Spring으로 해보고 싶긴 한데, 난 아직 Spring을 제대로 해본 적이 없다. 그래서 이번에야말로 제대로 된 책으로 Spring을 공부해보자 생각했다. 정글 동기에게 추천받은 책으로 난 Spring 공부를 시작했다. 홍팍 작가님이 낸 책이었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그런데.. 너무 이상했다. 책이 너무 쉽다. 너무나도 쉽게 잘 읽힌다. 분명 작년에 봤던 스프링 책은 전혀 이해하지 못해서 내 재능을 탓 할 정도였는데. 책이 너무 잘 읽혀서 재미있을 지경이다. 정글에서 끔찍한 Low-Level 코드를 5개월동안 질리도록 봤기 때문일까? 아니면 메멘토AI에서의 실무경력 때문일까? 늘어난 내 실력에 감탄하며, 훌륭히, 즐겁게 책을 완독했다. 그리고 즉시&amp;nbsp;개인 프로젝트 &quot;썬카&quot;를 시작했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Spring Boot + Vus.js 기반의 중고차 거래 플랫폼이었다. 지금 돌아보면 조금 형편없지만, Spring의 개발 구조와 OOP 개념을 열심히 학습하며 개발했기에 현재까지도 도움이 되는 개발 기반을 쌓았다고 생각한다. 이 때 구현했던 무중단 배포는 면접에서도 꽤 많이 받은 질문 중 하나다. 책 완독 및 개인 프로젝트가 끝난 시기는 2025년 5월 경이었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;메멘토 AI 폐업(퇴사) 후기: &lt;a href=&quot;https://yskisking.shop/291&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://yskisking.shop/291&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;메멘토AI의 폐업, 그리고 실직&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;메멘토AI는 내 인생 첫 번째 회사이다.&amp;nbsp;인턴으로 취업하여 한 달의 인턴기간을 거치고, 정직원이 되어 한달 반을 일하고 3번의 월급을 채 받지 못했을 때 나는 실직했다. 실력이 형편없어 짤린 &quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/291&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/5sxNb/dJMb88eVQo3/AAAAAAAAAAAAAAAAAAAAAJsb2ux0mKFyopIP1JR3nJ1W99DxJZVE9Kb0UvBL87IZ/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=lD2po1190cSA1Of%2BMSAoZyD3eEY%3D&quot; data-og-url=&quot;https://yskisking.shop/291&quot;&gt;&lt;a href=&quot;https://yskisking.shop/291&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/291&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/5sxNb/dJMb88eVQo3/AAAAAAAAAAAAAAAAAAAAAJsb2ux0mKFyopIP1JR3nJ1W99DxJZVE9Kb0UvBL87IZ/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=lD2po1190cSA1Of%2BMSAoZyD3eEY%3D');&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;메멘토AI의 폐업, 그리고 실직&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;메멘토AI는 내 인생 첫 번째 회사이다.&amp;nbsp;인턴으로 취업하여 한 달의 인턴기간을 거치고, 정직원이 되어 한달 반을 일하고 3번의 월급을 채 받지 못했을 때 나는 실직했다. 실력이 형편없어 짤린&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;본격적인 서류 제출과 KIDB 취업&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인 프로젝트를 추가해 이력서와 포트폴리오를 만들었고 본격적인 취업에 도전했다. 사실 메멘토 AI 취업할 때도 이력서 1개 내자마자 붙은 거였기에 제대로 부딪혀 본 적도 없었다. 결국 난 60개의 서류를 제출했고, 카카오와 KIDB에 서류합격했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;카카오는 내 알고리즘 실력이 아주 형편없었기에 코테에서 광탈했고, KIDB는 1차와 2차 면접 모두 합격하며 개발자로서 2번째 취업에 성공했다. 내가 면접 본 곳 중 유일하게 면접비를 주는 곳이었고, 면접관분들도 젠틀하여 좋은 인상을 많이 받았다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;KIDB는 채권과 파생상품을 중개하는 회사이다. 나는 돈을 버는 것에 관심이 많기에 금융 도메인이 나쁘진 않았지만, 금융권은 개발 업무가 적다는 소문을 많이 들어 고민을 정말 많이 했다. 정말, 정말로 많이. 개발자로서 금융권의 장단점은 급여가 높고 워라밸이 좋고 안정적이지만, 개발자로서 기술에 대해 고민하는 경험은 하기 어렵다는 점이었다. 결국 나는 내 인생의 1순위 목표였던 &quot;돈&quot;을 선택했고, '그래, 개발도 돈 벌려고 하는 건데 그냥 가자' 라고 생각하여 출근을 결정했다. 2025년 8월이었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;KIDB 취업 후기: &lt;a href=&quot;https://yskisking.shop/346&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://yskisking.shop/346&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;개발자 취업준비 6개월, KIDB 최종 합격 후기와 금융권 선택 이유 + 포트폴리오&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;메멘토 AI 3개월 근무 중 폐업에 의해 퇴직하고, 6개월의 취업준비를 거친 후에 드디어 재취업을 했다. 3개월이라는 근무 경험이 있긴 하지만 경력으로 인정받을 정도는 아니기 때문에, 사실상 신&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/346&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/QpapB/dJMb81GSpcE/AAAAAAAAAAAAAAAAAAAAACFd3P7-SxXwz4XO2hrTeBqo1Kdn4ROewNxmTPACiw3h/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=J3kYKOEi%2BLdDdyXBtaM9np%2FgCvs%3D&quot; data-og-url=&quot;https://yskisking.shop/346&quot;&gt;&lt;a href=&quot;https://yskisking.shop/346&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/346&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/QpapB/dJMb81GSpcE/AAAAAAAAAAAAAAAAAAAAACFd3P7-SxXwz4XO2hrTeBqo1Kdn4ROewNxmTPACiw3h/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=J3kYKOEi%2BLdDdyXBtaM9np%2FgCvs%3D');&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;개발자 취업준비 6개월, KIDB 최종 합격 후기와 금융권 선택 이유 + 포트폴리오&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;메멘토 AI 3개월 근무 중 폐업에 의해 퇴직하고, 6개월의 취업준비를 거친 후에 드디어 재취업을 했다. 3개월이라는 근무 경험이 있긴 하지만 경력으로 인정받을 정도는 아니기 때문에, 사실상 신&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;KIDB 퇴사, 다시 취업준비생으로&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KIDB에서 내가 맡은 업무는 직접적인 개발과는 거리가 조금 있었다. IT 업무를 하긴 했지만 비즈니스 로직을 짜고, 아키텍처를 설계하고, 성능을 개선하고 이런 개발자스러운 업무는 아니었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;회사 자체는 너무 좋았다. 매일 칼퇴근하고, 선배분들도 잘 해주시고, 복지도 좋고.. 직장으로서는 최고다 싶을 정도로 말이다. 하지만 심리적으로 너무 힘들었다. 개발이 아닌 업무를 하고 있으니 하루 종일 딴 생각만 들었고, 집중도 안 되고, 괜히 짜증도 나고... 다시 개발로 돌아가고 싶었다. 백엔드 개발을 하던 메멘토 AI에서는 체력적으로 극한으로 힘들었음에도 불행하다는 생각은 일절 들지 않았다. 오히려 행복에 가까웠다. 나는 생각했다. '이건 내 길이 아니다'&lt;br /&gt;&amp;nbsp;&lt;br /&gt;....그럼에도 불구하고 나는 퇴사를 정말 많이 고민했다. 지금 취업시장은 너무 차갑기에 언제 다시 취업될 지도 모르고, 나이도 30이 다 되어가는 마당에 시간을 더 지체하면 위험하다고 생각했다. 그래서 초반엔 회사에 다니면서 이직 준비를 했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그런데 코딩 테스트 준비 조차도 어려웠다. 평일에 퇴근하고 밥 먹으면 자유시간이 3시간 남짓 되었는데, 알고리즘 문제 하나에 길면 3시간 이상도 붙잡고 있기 때문에 사실상 하루에 한 문제 푸는 것도 버거웠다. 이렇게 가다간 이직은 1년, 2년이 지나도 못할 것 같았다. 특히나 가장 힘들었던 건, 빨리 개발자로 돌아가고 싶다는 미칠 듯한 불안감이었다. 회사에 앉아있는 시간 자체가 나에겐 고문이었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;결국 2025년 9월 중순, 죄송하다는 말과 함께 퇴사 의사를 밝혔다. 사실 기껏 뽑았는데 금방 퇴사 한다고 짜증을 내셔도 나는 할 말이 없는데, 퇴사하는 날 맛있는 저녁을 사주신 이사님께는 아직도 감사하다. 그리고 응원해준 동기들에게도.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;재취업 성공..? 아니, 입사 포기.&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카카오 코딩 테스트에서 광탈했던 기억 때문에, 알고리즘을 본격적으로 준비하기로 했다. 사실 계속 준비하긴 했지만, 너무 하기 싫은 마음에 띄엄띄엄 준비했기에 실력이 영 늘지를 않았었다. 이 부숴져 버린 알고리즘 감각을 어떻게 복구할까 생각 하다가, 역시 나와 가장 잘 맞는 방법인 책을 이용하기로 했다. '코딩 테스트 합격자 되기' 교재를 선택했고, 이때부터 거의 하루도 빼놓지 않고 매일 알고리즘 문제를 풀었다. 코테의 중요성을 인지한 채로 꾸준히 연습하니, 웬만한 코테는 합격할 정도로 실력이 늘게 되었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그러던 중 한 스타트업에 서류합격했다. 열심히 준비했던 덕분인지 라이브코테를 통과했고, 2차 면접에서도 나를 좋게 봐 주셨는지 최종 합격을 받았다. 그러나.. 내가 확신이 없었다. 주력 기술 스택이 php인데다, 백엔드 직무였는데도 '현재 우리 제품은 백엔드가 중요하지 않다'는 말이라던가, 팀이 명확히 정해져 있지 않고 다양한 일 (프론트, 기획 등)을 하게 될 거라는 등, 내가 생각했을 때 불확실한 부분이 너무나도 많았다. 처우도 불만족스러웠고.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그럼에도 불구하고 입사를 할까 말까 정말 많이 고민했다. 그러나, 개발자가 되기 위해 KIDB에서도 퇴사했는데 여기서도 불만족하여 퇴사하는 건 절대 있어선 안 될 일이라 생각해 오퍼레터를 거절했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이외에도 몇 군데 면접을 보긴 했지만, 도저히 원하는 기업에 서류가 붙질 않았다. &lt;span style=&quot;color: #333333;&quot;&gt;이 때 나의 부족함을 뼈저리게 깨달았다. '아, 원하는 기업에 가려면 내가 달라져야 하겠구나'&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;코딩 테스트 합격자 되기 후기: &lt;a href=&quot;https://yskisking.shop/365&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://yskisking.shop/365&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;[코딩 테스트 합격자 되기] 프로그래머스 기반 코딩 테스트 입문서 후기, 코딩 테스트 입문서 추&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;&amp;quot;코딩 테스트 합격자 되기&amp;quot; 교재를 완독했다. 하루에 1문제 ~ 3문제 정도를 푼 결과 완독은 2달 정도 걸렸다. 분량이 700페이지 정도 되기에 이걸 언제 다 읽나 하긴 했지만, 매일 조금씩 늘어가는 &quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/365&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/bPhPwt/dJMb8RjW939/AAAAAAAAAAAAAAAAAAAAAKVQefDzio7nWRdt4pUNCbVHuDtCXqJLDMsBi7RG6atA/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=nyPZzePrs2Dv1QEm2Oo1NGfEyWI%3D&quot; data-og-url=&quot;https://yskisking.shop/365&quot;&gt;&lt;a href=&quot;https://yskisking.shop/365&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/365&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/bPhPwt/dJMb8RjW939/AAAAAAAAAAAAAAAAAAAAAKVQefDzio7nWRdt4pUNCbVHuDtCXqJLDMsBi7RG6atA/img.jpg?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=nyPZzePrs2Dv1QEm2Oo1NGfEyWI%3D');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[코딩 테스트 합격자 되기] 프로그래머스 기반 코딩 테스트 입문서 후기, 코딩 테스트 입문서 추&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&quot;코딩 테스트 합격자 되기&quot; 교재를 완독했다. 하루에 1문제 ~ 3문제 정도를 푼 결과 완독은 2달 정도 걸렸다. 분량이 700페이지 정도 되기에 이걸 언제 다 읽나 하긴 했지만, 매일 조금씩 늘어가는&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;서류 합격률을 2배 이상 올려준, MSA 프로젝트 (msa-perf-lab)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 내 이력서는 특별할 게 하나도 없었다. 자격증, 정글, 메멘토AI, 썬카 정도였는데, 나쁘지 않았다고 생각하지만 신입 개발자로서 원하는 기업에 가기엔 특별함이 부족했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그래서 2025년 11월 경, 직접 특별함을 만들고자 했다. 최근 jd에서 많이 보이는 MSA, Redis(캐싱), MQ, gRPC, Prometheus/Grafana 등 백엔드 고급 기술을 이력서에 넣어야 겠다고 생각했다. 자, 어떻게 넣을까? 단순히 사용해 봤다는 건 누구나 할 수 있다. 어떻게 특별함을 추가할까?&lt;br /&gt;&amp;nbsp;&lt;br /&gt;나는 서버에서 일어날 수 있는 4가지 병목을 정의하기로 했다. 통신 프로토콜, I/O Bound, CPU Bound, DB Bound 이렇게 4가지 말이다. 그리고 Flask/Go MSA 서버를 구축해 이 병목들을 직접 만든 후 최적화했고, 전/후 성능을 측정 및 비교한 후 지표를 수집해 Grafana에 띄웠다. 지표 수집은 InfluxDB, Prometheus로 했으며, 왜 성능이 개선되었는지를 상세히 분석하고 그 내용을 포트폴리오에 실었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;측정 지표:&lt;br /&gt;Latency(응답시간)&lt;br /&gt;Throughput(처리량)&lt;br /&gt;Drop-Rate(총 요청 대비 요청 드랍률)&lt;br /&gt;Memory Usage(메모리 사용량)&lt;br /&gt;CPU Usage(CPU 사용량)&lt;br /&gt;&amp;nbsp;&lt;br /&gt;4가지 병목:&lt;br /&gt;통신 프로토콜: REST -&amp;gt; gRPC 전환&lt;br /&gt;I/O Bound: 메일, 알림 등 기능을 비즈니스 로직에서 분리 및 MQ 백그라운드 처리&lt;br /&gt;CPU Bound: 고부하 연산(반복문) Flask 서버 직접 실행 -&amp;gt; Go 서버 위임&lt;br /&gt;DB Bouond: 데이터 100만 건 Full Scan -&amp;gt; Redis 캐싱&lt;br /&gt;&amp;nbsp;&lt;br /&gt;테스트 별 독립 변수는 RPS(초당 요청 수), Payload Size(데이터 크기), Complexity Level(연산 난이도) 등으로 각 실험에 맞게 적용했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;이 프로젝트는 1달 간 약 300시간 이상을 투자해 완료되었으며, 정말 많은 공부가 되었고, 내 이력서와 포트폴리오 퀄리티를 엄청나게 올려주었으며, 내 목표였던 '신입으로서의 특별함'을 만들기에 충분했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;실제로 msa 프로젝트를 이력서/포트폴리오에 추가한 후 서류합격률은 기존 3% 정도에서 7% 정도로 2배 이상 상승했다. 심지어 나는 msa 프로젝트를 추가한 후엔 정말 가고 싶은, 좋은 기업에만 서류를 넣었는데도 이정도 상승치를 보였다. 또한 대부분의 면접은 msa 프로젝트에 대한 질문만으로 시작되고, 끝났다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그렇게 나는, 몇 주에 겨우 면접 1개 보던 걸 일주일에 두세개씩 보게 되었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;msa-perf-lab CPU Bound 포스팅: &lt;a href=&quot;https://yskisking.shop/363&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://yskisking.shop/363&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;[msa-perf-lab] CPU Bound 작업 성능 비교: Flask 자체 연산 vs Go 위임 - 멀티스레드 병렬 처리의 효율성 증&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;저번 시간엔 RabbitMQ 비동기 처리를 통해, Flask의 I/O Bound 병목점을 해결해 보았다. 응답시간은 약 500배 차이가 났었고, 처리량 및 드랍률도 RPS가 증가할수록 격차가 심해졌다. 이번 시간엔 Flask의 &quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/363&quot; data-og-image=&quot;https://blog.kakaocdn.net/dna/r8huL/dJMb9aKAkz9/AAAAAAAAAAAAAAAAAAAAAJnS2Y_rEvbF88w3PXG19PqhIUV64MwVvAnTdFn3tnbU/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=HijcO5WmtdSEcH4PWwyGdX94vFM%3D&quot; data-og-url=&quot;https://yskisking.shop/363&quot;&gt;&lt;a href=&quot;https://yskisking.shop/363&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/363&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://blog.kakaocdn.net/dna/r8huL/dJMb9aKAkz9/AAAAAAAAAAAAAAAAAAAAAJnS2Y_rEvbF88w3PXG19PqhIUV64MwVvAnTdFn3tnbU/img.png?credential=yqXZFxpELC7KVnFOS48ylbz2pIh7yKj8&amp;amp;expires=1772290799&amp;amp;allow_ip=&amp;amp;allow_referer=&amp;amp;signature=HijcO5WmtdSEcH4PWwyGdX94vFM%3D');&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;[msa-perf-lab] CPU Bound 작업 성능 비교: Flask 자체 연산 vs Go 위임 - 멀티스레드 병렬 처리의 효율성 증&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;저번 시간엔 RabbitMQ 비동기 처리를 통해, Flask의 I/O Bound 병목점을 해결해 보았다. 응답시간은 약 500배 차이가 났었고, 처리량 및 드랍률도 RPS가 증가할수록 격차가 심해졌다. 이번 시간엔 Flask의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;에이비스(AIVIS) 최종합격&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에이비스에서 서류합격했다고 전화가 왔다. 첫 번째 관문은 과제 테스트와 기술면접이었다. 과제 내용은 공개할 수 없지만, 내가 그동안 갈고닦은 기술을 총동원해 빈틈없이 하려고 노력했다. 면접은 과제 합격 여부와 관계없이 진행되었지만 최선을 다했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;1차면접은 CTO님과의 1:1 면접이었다. 일단 면접관님이 굉장히 젠틀하셔서 좋은 인상을 받고 시작했다. 면접 질문은 엄청나게 어려운 질문은 아니었기에 내가 준비해 왔던 대로 답변을 드렸고, 최고의 극찬을 들었다. '너무 답변을 잘 하셔서, 더 이상 물어볼 게 없네요.'&lt;br /&gt;그리고 나는 2일 후에 1차면접에 합격했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;2차면접은 대표님과의 1:1 면접이었다. 1차면접과 공통적으로 느낀 건 두분 다 너무 친절하시고 젠틀하다는 점이었다. 그리고 나는 면접 중 또 하나의 과분한 칭찬을 받았다. 'CTO님께서 2차 면접까지 잘 안 보내시는데, 직접 뵈니 왜 올리신 줄 알겠네요'&lt;br /&gt;그리고 나는 면접 도중 구두로 오퍼를 받았다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;나는 대학 졸업 직후, 성남의 정보보안 회사 모의해킹 &amp;amp; 보안 컨설팅 직무에 취업했다. 그러나 입사를 포기하고 개발자로 전향했다.&lt;br /&gt;그로부터 3년간 총 3번의 취업과 2번의 퇴사, 1번의 입사 포기, 그리고 약 400개의 서류 탈락을 지나온 끝에 나는 면접실에서 최고의 극찬을 들었다. 에이비스 채용과정은 나에게 그저 영광의 연속이었으며, 지난 3년을 인정받고 보상받는 시간이었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;내 가치를 알아봐 준 최고의 회사에서, 나는 2월 9일부로 새로운 삶을 시작하게 되었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;====================&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;마무리, 취업준비생들에게 드리고 싶은 말&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리 회사에 대해 많이 알아보았다. 기술적으로도 뛰어났고, 구성원들도 뛰어났다. 너무 좋은 회사다.&lt;br /&gt;그런데, 나는 왜 이 회사에서만 이런 특급 칭찬들을 받았을까? 면접은 항상 똑같이 보는데도 말이다. 회사의 Fit과 맞기 때문일까?&lt;br /&gt;&amp;nbsp;&lt;br /&gt;현업 개발자 분에게 조언을 하나 들은 적이 있다. '면접에서 떨어져도, 높은 확률로 너의 부족함은 아닐 것이다'&lt;br /&gt;그 말이 맞는 것 같다. 어느 회사 면접을 보는가에 따라서도 나에 대한 평가가 이렇게 달라지는데, 현 취업준비생 분들도 면접 몇 군데 떨어졌다고 해서 모든 잘못을 본인에게 돌릴 필요는 없는 것 같다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;취업준비할 때 가장 중요한 것은 멘탈을 잡는 것이다. 하지만 '멘탈을 잡아라' 라고 말은 못 하겠다.&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt;제일 중요한 거긴 한데, 그게 의식한다고 되는 건 아니니까.&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;내 생각에 가장 중요한 것은 2가지다:&lt;br /&gt;&lt;i&gt;첫 번째, 반드시 취업할 수 있다고 믿는 것&lt;/i&gt;&lt;br /&gt;&lt;i&gt;두 번째, 반드시 어제보다 발전할 것 (아주 조금이라도)&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;알고리즘을 풀던, 프로젝트를 하던, 면접 준비를 하던, 이력서를 수정하던 뭐가 됐든 좋다. 올바른 방향으로 꾸준히 나아가면 무엇이든 반드시 이룰 수 있다. 멈추지만 않으면 된다. 모든 취업준비생들을 응원한다.&lt;br /&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;1405&quot; data-origin-height=&quot;881&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FyyaT/dJMcacoq7qS/AhDUrDLDRu0GRqKzy4g3Ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FyyaT/dJMcacoq7qS/AhDUrDLDRu0GRqKzy4g3Ok/img.png&quot; data-alt=&quot;약 400개 서류 탈락 (기업명 모자이크)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FyyaT/dJMcacoq7qS/AhDUrDLDRu0GRqKzy4g3Ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFyyaT%2FdJMcacoq7qS%2FAhDUrDLDRu0GRqKzy4g3Ok%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;1405&quot; height=&quot;881&quot; data-origin-width=&quot;1405&quot; data-origin-height=&quot;881&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;약 400개 서류 탈락 (기업명 모자이크)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;i&gt;혹시나 개발자 취업 관련하여 질문이나 토론할 거리가 있으시다면, 자유롭게 댓글 부탁드립니다.&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;br /&gt;====================&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;Github: &lt;a href=&quot;https://github.com/YangSunkue&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://github.com/YangSunkue&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;Linkedin: &lt;a href=&quot;https://www.linkedin.com/in/%EC%84%A0%EA%B7%9C-%EC%96%91-495303337/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://www.linkedin.com/in/%EC%84%A0%EA%B7%9C-%EC%96%91-495303337/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <category>업적</category>
      <category>AIVIS</category>
      <category>개발자 전향</category>
      <category>개발자 취업</category>
      <category>개발자 취업준비</category>
      <category>개발자 포트폴리오</category>
      <category>개발자 프로젝트</category>
      <category>백엔드 취업</category>
      <category>신입 개발자</category>
      <category>알고리즘</category>
      <category>에이비스</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/366</guid>
      <comments>https://yskisking.tistory.com/366#entry366comment</comments>
      <pubDate>Tue, 3 Feb 2026 20:59:15 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 코딩 테스트 합격자 되기: 프로그래머스 기반 코딩 테스트 입문서 후기, 코딩 테스트 입문서 추천</title>
      <link>https://yskisking.tistory.com/365</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;코딩테스트.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOZQ4p/dJMcabCARud/P4a2NRExkSOk6KiUx6OKm1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOZQ4p/dJMcabCARud/P4a2NRExkSOk6KiUx6OKm1/img.jpg&quot; data-alt=&quot;코딩 테스트 합격자 되기 표지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOZQ4p/dJMcabCARud/P4a2NRExkSOk6KiUx6OKm1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOZQ4p%2FdJMcabCARud%2FP4a2NRExkSOk6KiUx6OKm1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;536&quot; height=&quot;715&quot; data-filename=&quot;코딩테스트.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;코딩 테스트 합격자 되기 표지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;평점: 3/5&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도서명: 코딩 테스트 합격자 되기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;코딩 테스트 합격자 되기&quot; 교재를 완독했다. 하루에 1문제 ~ 3문제 정도를 푼 결과 완독은 2달 정도 걸렸다. 분량이 700페이지 정도 되기에 이걸 언제 다 읽나 하긴 했지만, 매일 조금씩 늘어가는 스스로를 보니 그렇게 긴 분량도 아니었던 것 처럼 느껴진다.&lt;/p&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;총 100문제&lt;/b&gt;가 담겨 있고, 코딩 테스트에서 중요하게 생각할 점이나 시간 복잡도 계산법 같은 초보자가 놓치기 쉬운 부분을 가장 먼저 짚고 시작한다. 최근 코딩 테스트에서 나오는 빈출 유형들은 대부분 실려 있으나, 이분 탐색 알고리즘이 실려 있지 않다는 것이 조금 아쉽긴 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;고찰&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 책을 읽기 전 나의 기반 지식부터 말하겠다. 1년 전 쯤 크래프톤 정글에서 코테 빈출유형에 대한 공부는 한번 했었지만, 꾸준히 문제를 풀지 않고 듬성듬성 가끔씩만 풀어 왔다. 즉 &lt;b&gt;해당 교재에 존재하는 알고리즘을 전부 1번씩 공부했던 기억은 있으나, 오래되어 잘 활용하지 못하는 수준&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;보통 코딩 테스트를 공부한다고 하면 그래프, DP, 그리디 등 다양한 알고리즘을 직접 찾아 공부하고, 문제도 직접 찾고, 혼자 낑낑대며 푼 후에 다시 까먹는. 그리고 그 과정이 고통스러워 꾸준히 지속하지 못해 실력이 늘지 않는 케이스가 많을 것이다. 나도 비슷했고. 나는 알고리즘 기본도 알고 있었고 코테 공부를 시작한지 시간이 꽤 지났는데도 이렇다 할 실력 상승이 없어 &lt;b&gt;내가 재능이 없나?&lt;/b&gt; 라는 생각을 정말 많이 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 돌아보면 난 마음만 앞섰지, &lt;b&gt;몇 달 이상 꾸준히 코테를 공부한 적이 없었다&lt;/b&gt;. 실력이 늘 리가 없다. 그래서 이 참에 책의 커리큘럼을 그대로 따라가면서, 모호하게 기억나는 알고리즘 기초를 다잡고 꾸준히 문제를 풀어 보기로 했다. 혼자 계획을 하는 것이었다면 어려웠겠으나, 책이 지시하는 대로 따라가기만 하면 됐기 때문에 크게 어렵지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론부터 말하면, &lt;b&gt;확실히 실력이 늘었다&lt;/b&gt;. 왜 늘었는지 생각해 보자면 기존 공부 방식은 특정 유형을 풀었으면 그 다음날엔 다른 유형을 풀었다. 그래서 특정 유형에 익숙해지기 전에 넘어가 버리니 체화될 시간이 부족했다. 또 나의 코드만 보다보니, 다른 사람이 어떻게 코드를 작성하는지 참고하질 못 했다. 혼자 풀고, 혼자 공부하고 스스로에게 갇혀버렸다. 또, 쉬운 문제를 풀면 실력이 늘지 않는다는 말을 어디서 들어서 매번 어려운 문제만 풀다가, 하루 종일 그 문제만 붙잡고 있다가 지쳐 버리던 상황도 많이 발생했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 알고리즘 이론을 우선적으로 설명해 준다. 그리고 쉬운 연습문제부터 몇 문제 풀게 해 해당 알고리즘에 대한 감을 익히게 도와주고, 실전 문제로 넘어가 고도화시키고 체화될 흐름을 만들어 준다. 초심자에게는 매일 다른 유형을 푸는 것 보다, &lt;b&gt;하나의 유형을 제대로 익히고 넘어가는 게 매우 중요&lt;/b&gt;하다고 느꼈다. 또한 책에서 보여주는 &lt;b&gt;모범 사례 코드를 참고할 수 있기 때문에&lt;/b&gt;, 문제를 푼 후에 책의 코드를 보면 이렇게 간단하게 푼다고? 하면서 놀라는 부분도 있었다. 혼자만의 코드에 갇혀 있던 나를 밖으로 꺼내는 순간이었다. 만약 스스로 해결하지 못 하더라도, 각 문제마다 풀이과정이 상세히 적혀 있어 잘 정리된 풀이를 손쉽게 확인할 수 있는 것도 큰 장점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책을 한 줄로 설명하자면 어디부터 어떻게 공부해야 할 지 모르는 &lt;b&gt;입문자에게는 방향성을 제시&lt;/b&gt;해 주고, 실력이 &lt;b&gt;정체된 사람에게는 재정비할 시간&lt;/b&gt;을 준다는 것이다. 특히 나처럼 코테 기본은 알지만 실력이 정체되어 있는 사람들에게 큰 도움이 되지 않을까 싶다. 나는 DP라면 정말 치를 떨었고, 아예 도전해볼 엄두도 못 냈고, 도전해봐도 못 풀었고, 답을 봐도 허망함만 남았는데, 이 교재로 공부하고 나서 프로그래머스 도둑질(DP 레벨4) 문제를 혼자 풀어냈다. 스스로의 벽을 깨부순 순간이었달까... 재능이 없던 게 아니라, 그냥 안/잘못 했던 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨌든 이 책을 추천한다. 프로그래머스 PCCP 자격 준비 교재로도 활용하던데, 난 PCCP는 준비해본 적이 없어 모르겠지만 책을 다 읽은 김에 한번 도전해볼까 한다.&lt;/p&gt;</description>
      <category>독서/IT</category>
      <category>PCCP</category>
      <category>개발자</category>
      <category>알고리즘</category>
      <category>알고리즘 입문서</category>
      <category>코딩 테스트 합격자 되기</category>
      <category>코딩테스트</category>
      <category>코테 교재</category>
      <category>코테 입문서</category>
      <category>코테 책</category>
      <category>파이썬</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/365</guid>
      <comments>https://yskisking.tistory.com/365#entry365comment</comments>
      <pubDate>Wed, 19 Nov 2025 20:41:49 +0900</pubDate>
    </item>
    <item>
      <title>[msa-perf-lab] 캐싱 적용 전후 조회 성능 비교 - 데이터 100만개, Redis, Faker</title>
      <link>https://yskisking.tistory.com/364</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;웹 서비스 요청의 &lt;b&gt;80%는 단순 읽기 작업&lt;/b&gt;이라고 한다. 따라서 개발 속도는 빠르지만, 상대적으로 성능이 떨어지는 Python 기반의 웹 서버를(Flask, Django 등) Gateway로 두고 Core Engine으로 고성능 서버(Go 등)를 활용하는 MSA 방식이 요즘 유행이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Python 기반의 웹 서버는, GIL 제약에 의해 멀티스레드 병렬 처리를 활용하지 못 하지만 I/O 작업에서는 전혀 문제가 없다. I/O 대기시간엔 CPU를 사용하지 않는 데다가, 기다리는 동안 GIL을 놓고 추가 스레드를 생성해 다른 작업을 맡길 수 있기 때문이다. 명시적 비동기 처리를 하지 않더라고 비동기 &quot;처럼&quot; 동작하기 때문에 I/O 작업엔 크게 무리가 없고(그렇다고 더 빠르단 건 아니다), 개발 속도가 빠르다는 장점이 합쳐져 이러한 MSA 방식이 트렌드가 된 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 이러한 Gateway 대상 요청의 약 80%를 차지하는 DB 읽기 작업에 대한 병목을, &lt;b&gt;캐싱을 적용해 해결&lt;/b&gt;해 볼 것이다. 캐싱은 인메모리 DB인 Redis를 활용해 구현할 것이고, Go 서버는 그냥 두고 Gateway인 Flask 서버에서만 작업할 것이다. 데이터는 Faker 라이브러리를 활용해 &lt;b&gt;100만 건&lt;/b&gt;을 넣을 것이고, 인덱스를 누락시켜 100만 건 데이터를 Full Scan 하게 만들어 조회 성능을 고의적으로 조금 떨궈둘 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;측정 데이터는 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;InfluxDB: P95 Latency (응답시간), &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;Throughput (처리량), &lt;/span&gt;Drop rate (총 요청 대비 드랍률)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Node Exporter, Prometheus: 호스트 메모리 사용량&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Prometheus Counter: 캐시 히트율&lt;/i&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;A. 매 요청마다 &lt;b&gt;캐싱 없이 데이터 직접 조회&lt;/b&gt; 후 응답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;B. &lt;b&gt;캐싱 활용&lt;/b&gt;, 캐시 없을 경우 직접 조회, 있을 경우 캐시 응답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;더미 데이터 삽입&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgCGSz/dJMcabP653N/DOD7OuoOcndxK1ctRx5awk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgCGSz/dJMcabP653N/DOD7OuoOcndxK1ctRx5awk/img.png&quot; data-alt=&quot;100만 건 삽입&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgCGSz/dJMcabP653N/DOD7OuoOcndxK1ctRx5awk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgCGSz%2FdJMcabP653N%2FDOD7OuoOcndxK1ctRx5awk%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;644&quot; height=&quot;478&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;100만 건 삽입&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Faker 라이브러리를 활용해 PostgreSQL에 &lt;b&gt;더미 데이터 100만 건&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;캐시 히트율을 높이기 위해 100개의 이메일을 미리 만들고, 100만 건 중 80%(80만건)는 100개 중 한개의 이메일을 사용하도록 구성했다. 만들어진 100개의 이메일은 JSON 파일로 따로 저장해 두고, K6로 트래픽을 발생시킬 때 활용할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;조회 쿼리&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pH7eF/dJMcabvOp3l/hrnMoBQ6kRrg7rN0L3pxuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pH7eF/dJMcabvOp3l/hrnMoBQ6kRrg7rN0L3pxuK/img.png&quot; data-alt=&quot;조회 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pH7eF/dJMcabvOp3l/hrnMoBQ6kRrg7rN0L3pxuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpH7eF%2FdJMcabvOp3l%2FhrnMoBQ6kRrg7rN0L3pxuK%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;745&quot; height=&quot;377&quot; data-origin-width=&quot;745&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;조회 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트에서 조회를 담당해 줄 쿼리이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내용은 아주 간단하다. 입력받은 email과 같은 email을 가진 사용자의 수를 리턴하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리는 간단하지만, 총 데이터가 100만 건이기 때문에 &lt;b&gt;조회 요청이 올 때마다 100만 건을 Full Scan&lt;/b&gt; 해야 하고, 일치하는 이메일을 찾았더라도 해당 이메일을 가진 총 사용자 수를 세야 하기 때문에 &lt;b&gt;항상 일정하게 느리게 동작&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시를 활용하지 않는 요청은 항상 이 함수를 호출할 것이며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시를 활용하는 요청은 캐시가 없을 때만 제한적으로 호출할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;캐싱 구현&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eDwhIs/dJMcachbvqk/V9TAr6EduKGGkruxolG5n1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eDwhIs/dJMcachbvqk/V9TAr6EduKGGkruxolG5n1/img.png&quot; data-alt=&quot;Redis 캐싱 활용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eDwhIs/dJMcachbvqk/V9TAr6EduKGGkruxolG5n1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeDwhIs%2FdJMcachbvqk%2FV9TAr6EduKGGkruxolG5n1%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;665&quot; height=&quot;710&quot; data-origin-width=&quot;665&quot; data-origin-height=&quot;710&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Redis 캐싱 활용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회 요청이 들어왔을 때 함수는 아래와 같이 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시가 존재할 경우: 즉시 캐시 리턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐시가 존재하지 않을 경우: DB조회 후 캐시 등록하고 값 리턴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CACHE_HITS, CACHE_MISSES 상수는, 캐시 히트율을 계산하기 위해 Prometheus에서 정의한 Counter 객체이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&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;i&gt;RPS(초당 요청 수): 30 -&amp;gt; 50 -&amp;gt; 75 -&amp;gt; 100 -&amp;gt; 150 -&amp;gt; 300&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;DURATION(요청 지속시간): 30 고정&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;테스트 대상: P95 Latency, Throughput, Drop rate, Memory Usage, Cache Hit rate&lt;/i&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;RPS를&lt;span&gt; 30&lt;/span&gt;에서 300까지 올리며, &lt;b&gt;no-cache/with-cache 연산을 번갈아가며 진행&lt;/b&gt;할 것이다. with-cache 테스트 후에는 항상 캐시를 삭제한 후 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - P95 Latency&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xYVbp/dJMcafEYQmE/LKPkCkFkCp27TokNq5DeI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xYVbp/dJMcafEYQmE/LKPkCkFkCp27TokNq5DeI1/img.png&quot; data-alt=&quot;P95 Latency (단위: ms)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xYVbp/dJMcafEYQmE/LKPkCkFkCp27TokNq5DeI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxYVbp%2FdJMcafEYQmE%2FLKPkCkFkCp27TokNq5DeI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1261&quot; height=&quot;363&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;P95 Latency (단위: ms)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 54px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;30 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;50 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;75 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;100 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;150 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;300 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;캐싱 X&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;135ms&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;3.277s&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;9.34s&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;10.75s&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;13.725s&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;14.375s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;캐싱 O&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;21.8ms&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;12.2ms&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;11.9ms&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;33.3ms&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;53.9ms&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 18px; text-align: center;&quot;&gt;307ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;30RPS부터 &lt;b&gt;약 6배&lt;/b&gt; 정도의 차이로 시작했다가, 50RPS로 한단계 뛰자 마자 수백 배 이상으로 격차가 벌어졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 차이가 많이 나는 구간은 75RPS인데, &lt;b&gt;약 785배 차이가 난다!!!&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;하지만 난 RPS가 늘어날 수록 기하급수적으로 차이가 벌어질 것이라 생각했는데, 100 RPS부터는 격차가 점점 줄어들고 있다. 왜 그런지 생각을 해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 &lt;b&gt;매 테스트가 끝날 때마다 캐시를 새로 쌓아야 하기 때문&lt;/b&gt;이었다. 캐시가 저장된 상태로 즉시 테스트를 이어가는 게 아닌, 매번 새롭게 캐시를 쌓아야 하기 때문에 캐시를 쌓는 과정에서의 오버헤드가 결과값에 영향을 주는 것이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서, 일단 이대로 진행하고 글 마지막에서&amp;nbsp;&lt;b&gt;캐시를 지우지 않고 최대한 활용하여, 캐싱의 성능 한계를 측정&lt;/b&gt;해 보겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - Throughput&lt;/b&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;1261&quot; data-origin-height=&quot;361&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwXBpI/dJMcacap0sx/EnnV6bdKvGKzkZqX7r7DTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwXBpI/dJMcacap0sx/EnnV6bdKvGKzkZqX7r7DTK/img.png&quot; data-alt=&quot;초당 처리량 (단위: 개)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwXBpI/dJMcacap0sx/EnnV6bdKvGKzkZqX7r7DTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwXBpI%2FdJMcacap0sx%2FEnnV6bdKvGKzkZqX7r7DTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1261&quot; height=&quot;361&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;361&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;초당 처리량 (단위: 개)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 60px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;30 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;50 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;75 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;100 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;150 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;300 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;캐싱 X&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;30개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;42개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;40개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;42개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;38개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;40개&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;캐싱 O&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;30개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;50개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;75개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;100개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;150개&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; height: 20px; text-align: center;&quot;&gt;300개&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;초당 처리량은 30RPS일 땐 둘 다 동일했다가, 50RPS부터는 캐싱 X의 경우 &lt;b&gt;40개 초반 선에서 쭉 정체&lt;/b&gt;되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 캐싱 O의 경우 RPS와 처리량이 똑같이 상승하며 &lt;b&gt;매우 안정적인 모습&lt;/b&gt;을 보이고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - Drop rate&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1254&quot; data-origin-height=&quot;470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bS8sNO/dJMcahiuBL4/IN4miI0e6oWZo0ktUwlKYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bS8sNO/dJMcahiuBL4/IN4miI0e6oWZo0ktUwlKYk/img.png&quot; data-alt=&quot;총 요청 대비 드랍률 (단위: %)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bS8sNO/dJMcahiuBL4/IN4miI0e6oWZo0ktUwlKYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbS8sNO%2FdJMcahiuBL4%2FIN4miI0e6oWZo0ktUwlKYk%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;1254&quot; height=&quot;470&quot; data-origin-width=&quot;1254&quot; data-origin-height=&quot;470&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;총 요청 대비 드랍률 (단위: %)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구분&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;30 RPS&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;50 RPS&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;75 RPS&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;100 RPS&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;150 RPS&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;300 RPS&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;캐싱 X&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;7.71%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;24.5%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;43.2%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;66.2%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;81.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;캐싱 O&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 14.2857%; text-align: center;&quot;&gt;1.1%&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;30 RPS 에서는 둘 다 0%를 기록하며 큰 문제가 없었지만, 캐싱 X의 경우 50 RPS부터 7%의 드랍률을 보이기 시작하더니 &lt;b&gt;75 RPS 부터는 사용하지 못 할 수준으로 드랍률이 상승&lt;/b&gt;해 버렸다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 캐싱 O의 경우 300RPS에서도 드랍률 1.1%를 유지하며 꽤 안정적인 성능을 보였다. &lt;b&gt;(약 80배 차이!!)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 저 1.1%라는 수치도, 초반에 &lt;b&gt;캐시를 수집하는 과정에서 생긴 드랍일 확률이 높다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - Memory Usage &amp;amp; Cache Hit Rate&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1255&quot; data-origin-height=&quot;358&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6EG5e/dJMcahv1PJ4/MMnGwJyDi26IzUqGuX71kK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6EG5e/dJMcahv1PJ4/MMnGwJyDi26IzUqGuX71kK/img.png&quot; data-alt=&quot;메모리 사용량 (단위: %)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6EG5e/dJMcahv1PJ4/MMnGwJyDi26IzUqGuX71kK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6EG5e%2FdJMcahv1PJ4%2FMMnGwJyDi26IzUqGuX71kK%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;1255&quot; height=&quot;358&quot; data-origin-width=&quot;1255&quot; data-origin-height=&quot;358&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메모리 사용량 (단위: %)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래프만 보면 아마 이해하기 어려울 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 테스트는 15:55 ~ 16:03(약 8분)동안 진행되었다. 현재 대시보드는 15:30 ~ 16:25 까지의 메모리 사용량을 담고 있다. 그래프를 보면 35 ~ 43 정도 사이에서 메모리가 계속 왔다 갔다 하는데, 고부하 테스트를 진행한 시간대에도 &lt;b&gt;최대 43~44&lt;/b&gt; 정도의 수치밖에 보이지 않았다. &lt;b&gt;평소 사용량이 30 후반 정도&lt;/b&gt;인 걸 감안하면, Redis를 도입하고 감수해야 하는 &lt;b&gt;메모리 측면에서의 손해가, 별로 크지 않다&lt;/b&gt;는 사실을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Cache Hit Rate를 계산해 보자. 전체 테스트의 평균을 구할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;캐시 히트 수: 85327&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;캐시 미스 수: 3808&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;캐시 히트율: 85327 / (85327 + 3808) -&amp;gt; &lt;b&gt;95.73%&lt;/b&gt;&lt;/i&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;95.73%는 아주 높은 수치에 속하며,&lt;b&gt; 실무에서도 70%이상의 히트율이 나오면 충분&lt;/b&gt;하다고 판단한다. 아무래도 히트율을 좀 높게 잡았다 보니 성능 차이가 더 극명하게 갈렸지만,&lt;b&gt; 캐싱 구현의 복잡성과 도입 리스크에 비해, 극적인 성능 개선이 일어난다는 사실 만큼은 충분히 증명&lt;/b&gt;되었을 것이라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - 미리 캐싱 후 한계 측정 (P95 Latency, Drop rate)&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;300 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;500 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;1000 RPS&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;P95 Latency&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;4.15ms&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;7.33ms&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;1.22s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;Drop rate&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;1.6%&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;12.64%&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;미리 캐싱하지 않았던 아까 실험에서는, 300RPS 기준 Latency 307ms Drop rate 1.1% 였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나&lt;b&gt; 미리 캐싱을 해 두니, 500RPS에서도 이전 300RPS보다 훨씬 빠른 성능&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;1000RPS에서는 병목이 시작되었는지 1.22s, 12.64%라는 결과가 나왔는데, 이마저도 &lt;b&gt;캐싱X 의 50RPS와 비슷한 수준&lt;/b&gt;이다. 즉, 엄청나게 차이가 난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;왜 이렇게 빠를까?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원리는 아주 간단하다. 우선 캐시는 Redis에 key-value 형태(Hash Table 기반)로 저장되기 때문에, 캐시 데이터가 10개든 10억 개든 &lt;b&gt;항상 상수 시간 O(1)에 조회&lt;/b&gt;가 가능하다. 심지어 Redis는 &lt;b&gt;메모리 기반 데이터베이스&lt;/b&gt;이기 때문에, 일반적인 디스크 기반 DB (MySQL, PostgreSQL 등)보다 압도적으로 빠르다. 심지어 DB 조회를 생략하기 때문에 DB 부하가 줄고, 애플리케이션 서버에서 I/O 대기시간도 사라지기 때문에 &lt;b&gt;리소스 절약 효과&lt;/b&gt;도 크다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;-&amp;gt; DB 조회 결과를 매우 빠른 저장소인 Redis에 미리 저장해 두고, 반복적인 조회 요청이 들어올 때 &lt;b&gt;실제 DB 조회를 생략하고 즉시 Redis에서 데이터를 꺼내 응답&lt;/b&gt;하기 때문에 매우 빠른 것이다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-11-17 18.33.47.png&quot; data-origin-width=&quot;199&quot; data-origin-height=&quot;92&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mxYMX/dJMcahv1OBd/IvEYNiWUNl2dXk4mylurG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mxYMX/dJMcahv1OBd/IvEYNiWUNl2dXk4mylurG1/img.png&quot; data-alt=&quot;응답시간 차이&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mxYMX/dJMcahv1OBd/IvEYNiWUNl2dXk4mylurG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmxYMX%2FdJMcahv1OBd%2FIvEYNiWUNl2dXk4mylurG1%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;199&quot; height=&quot;92&quot; data-filename=&quot;스크린샷 2025-11-17 18.33.47.png&quot; data-origin-width=&quot;199&quot; data-origin-height=&quot;92&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;응답시간 차이&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 캐싱 적용 전/후 단일 요청 응답시간은 이런 차이가 난다. (데이터 100만 건 기준)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;캐싱 적용 전: 109.985ms&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;캐싱 적용 후: 2.156ms &lt;b&gt;(약 51배 차이!!!)&lt;/b&gt;&lt;/i&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: #222222; text-align: start;&quot;&gt;==========&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;msa-perf-lab 깃허브:&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/YangSunkue/msa-perf-lab&quot;&gt;https://github.com/YangSunkue/msa-perf-lab&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;==========&lt;/span&gt;&lt;/p&gt;</description>
      <category>Development/[msa-perf-lab] Flask &amp;amp; Go MSA 성능 실험 프로젝트</category>
      <category>DB 조회</category>
      <category>flask</category>
      <category>latency</category>
      <category>MSA</category>
      <category>Prometheus</category>
      <category>Redis</category>
      <category>백엔드</category>
      <category>캐시</category>
      <category>캐싱</category>
      <category>캐싱 구현</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/364</guid>
      <comments>https://yskisking.tistory.com/364#entry364comment</comments>
      <pubDate>Mon, 17 Nov 2025 20:12:48 +0900</pubDate>
    </item>
    <item>
      <title>[msa-perf-lab] CPU Bound 작업 성능 비교: Flask 자체 연산 vs Go 위임 - 멀티스레드 병렬 처리의 효율성 증명</title>
      <link>https://yskisking.tistory.com/363</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;저번 시간엔 RabbitMQ 비동기 처리를 통해, Flask의 I/O Bound 병목점을 해결해 보았다. 응답시간은 약 500배 차이가 났었고, 처리량 및 드랍률도 RPS가 증가할수록 격차가 심해졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 시간엔 Flask의 나머지 대표적 병목인 &lt;b&gt;CPU Bound 작업을 Go에 위임&lt;/b&gt;해 볼 것이다. Flask는 Python의 GIL 한계 때문에 멀티코어 + 병렬 처리의 이점을 전혀 얻을 수 없어, CPU 연산 중엔 GIL을 놓지 못해 완전히 블로킹 되어 성능이 급감한다. 이러한 CPU Bound 작업을 병렬 처리에 특화된 Go에 위임하여, 어느 정도의 성능 향상을 가져오는지를 테스트 할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 방식인 Flask 자체 연산 방식은, CPU 연산을 수행하는 동안 &lt;b&gt;GIL에 묶여 동시에 단 하나의 코어(스레드)만이 활동 &lt;/b&gt;하게 된다. 만약 연산에 10초가 소모된다고 가정하면, Flask 서버는 이 연산을 수행하는 동안 다른 그 어떤 작업도 할 수 없다. 즉 엄청난 병목을 초래한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개선 방식인 Go 위임 방식은, &lt;b&gt;GIL 제한이 없고 멀티스레드 + 멀티코어 + 병렬 처리 + Goroutine의 엄청난 효율성을 전부 활용&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;이전 성능 테스트에서는 K6 + InfluxDB를 활용해 Latency, 처리량, 드랍률을 계산했지만, 이번엔 CPU 사용률도 측정해야 하기 때문에 &lt;b&gt;Node Exporter + Prometheus 조합을 추가해 CPU 사용률을 측정&lt;/b&gt;했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비교 대상은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;A. Flask 서버에서 &lt;b&gt;직접 CPU 집약적 연산&lt;/b&gt; 후 응답&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;B. Flask 서버가 &lt;b&gt;Go 서버에게 CPU 집약적 연산 위임&lt;/b&gt; 후 결과를 받아 응답 (gRPC 통신)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;prometheus 설정&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1226&quot; data-origin-height=&quot;966&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lhhkK/dJMcagX99HQ/slRsgxMRyfmRheWI6Jz9PK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lhhkK/dJMcagX99HQ/slRsgxMRyfmRheWI6Jz9PK/img.png&quot; data-alt=&quot;prometheus.yml&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lhhkK/dJMcagX99HQ/slRsgxMRyfmRheWI6Jz9PK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlhhkK%2FdJMcagX99HQ%2FslRsgxMRyfmRheWI6Jz9PK%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;591&quot; height=&quot;466&quot; data-origin-width=&quot;1226&quot; data-origin-height=&quot;966&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;prometheus.yml&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 cAdvisor를 사용해 Flask/Go 컨테이너별 CPU 사용률을 측정하려고 했으나, 이번엔 Node exporter를 활용하기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1초마다 Node exporter로 CPU, 메모리 등 호스트 데이터를 수집해, 프로메테우스에 저장&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;Latency, Throughput, Drop-rate는 이전 실험에서 그랬듯 K6 + InfluxDB 조합 그대로 측정할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CPU 집약적 연산 함수&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;846&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnulOz/dJMcabbtMTl/GT1uTuUHSxaQur79ju2Wa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnulOz/dJMcabbtMTl/GT1uTuUHSxaQur79ju2Wa1/img.png&quot; data-alt=&quot;연산 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnulOz/dJMcabbtMTl/GT1uTuUHSxaQur79ju2Wa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnulOz%2FdJMcabbtMTl%2FGT1uTuUHSxaQur79ju2Wa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;562&quot; height=&quot;422&quot; data-origin-width=&quot;1128&quot; data-origin-height=&quot;846&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연산 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 실험의 메인이 될, 연산 함수이다. Go 서버 측 연산 함수도 동일하게 구현되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적으로 10만 번 반복하며, 입력받은 level에 따라 연산 횟수를 증가시킨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Level 1 -&amp;gt; 10만번 연산&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Level 10 -&amp;gt; 100만번 연산&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Level 1000 -&amp;gt; 1억번 연산&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 흐름이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&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;i&gt;RPS(초당 요청 수): 50 고정&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;DURATION(요청 지속시간): 30 고정&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;COMPLEXITY_LEVEL(연산 난이도): 1 -&amp;gt; 3 -&amp;gt; 5 -&amp;gt; 10 -&amp;gt; 25&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;테스트 대상: P95 Latency, Throughput, Drop-rate, CPU-Usage&lt;/i&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;1에서 25까지 올리며, Flask/Go 연산을 번갈아가며 진행&lt;/b&gt;할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - P95 Latency&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;386&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cO8wwm/dJMcaaDDQPx/Hui9cAX2JrLcdvz3hCHslk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cO8wwm/dJMcaaDDQPx/Hui9cAX2JrLcdvz3hCHslk/img.png&quot; data-alt=&quot;P95 Latency (단위: ms)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cO8wwm/dJMcaaDDQPx/Hui9cAX2JrLcdvz3hCHslk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcO8wwm%2FdJMcaaDDQPx%2FHui9cAX2JrLcdvz3hCHslk%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;1263&quot; height=&quot;386&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;386&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;P95 Latency (단위: ms)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구분&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 1&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 3&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 5&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 10&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 25&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;Flask&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;30.2ms&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;4.058s&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;6.33s&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;12.222s&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;25.238s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;Go 위임&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;11ms&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;18.5ms&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;11.3ms&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;18.3ms&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;18.1ms&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Level 25(연산량 250만회) 기준 Flask는 25초, Go는 18.1ms로 무려 &lt;b&gt;1394배 차이가 난다!!&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;Flask는 Level 1에서 30.2ms로 나쁘지 않은 속도를 보였지만, &lt;b&gt;Level 3 이후부터는 Second 단위로 100배 이상 급증&lt;/b&gt;했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 Go는 Level 1부터 Level 25까지 거의 비슷한 응답속도를 보였다. 이 정도 레벨에서는 끄떡도 없는 듯 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - Throughput (초당 처리량)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1255&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chgT95/dJMcaiaByw4/WDfidfjxYJDSb3OFzIzwqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chgT95/dJMcaiaByw4/WDfidfjxYJDSb3OFzIzwqk/img.png&quot; data-alt=&quot;Throughput (단위: 개)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chgT95/dJMcaiaByw4/WDfidfjxYJDSb3OFzIzwqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchgT95%2FdJMcaiaByw4%2FWDfidfjxYJDSb3OFzIzwqk%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;1255&quot; height=&quot;389&quot; data-origin-width=&quot;1255&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Throughput (단위: 개)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 60px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구분&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 1&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 3&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 5&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 10&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Level 25&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;Flask&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;50개&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;22개&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;14개&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;8개&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;3개&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;Go 위임&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;50개&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;50개&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;50개&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;50개&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 20px; text-align: center;&quot;&gt;50개&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Level 25 기준 Flask는 3개, Go는 50개로 &lt;b&gt;약 17배 차이&lt;/b&gt;가 나며, Go가 매우 안정적인 것으로 보아 Level을 아주 많이 올려도 50개의 Throughput을 유지할 것으로 예상된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flask는 Level 1에서는 50개의 요청을 전부 처리했지만, &lt;b&gt;Level 3부터는 절반 이하로 떨어지더니 Level 25가 되자 못 써먹을 정도&lt;/b&gt;로 곤두박질 쳤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 Go는 레벨에 관계없이 안정적으로 50개의 요청을 전부 처리해 내는 모습이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - Drop-rate (총 요청 수 대비 드랍률)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/X7IaK/dJMcacOZH2e/qIims9VKrTq8INq323uKmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/X7IaK/dJMcacOZH2e/qIims9VKrTq8INq323uKmk/img.png&quot; data-alt=&quot;Drop-rate (단위: %)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/X7IaK/dJMcacOZH2e/qIims9VKrTq8INq323uKmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FX7IaK%2FdJMcacOZH2e%2FqIims9VKrTq8INq323uKmk%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;1256&quot; height=&quot;394&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Drop-rate (단위: %)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 54px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 1&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 3&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 5&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 10&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 25&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;Flask&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;47.4%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;65.8%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;79.9%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;89.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;Go 위임&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; height: 18px; text-align: center;&quot;&gt;0%&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;이 드랍률이야말로 Go의 안정성을 가장 잘 보여주는 지표가 아닐까 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flask는 Level 1 에서는 안정적이었지만, &lt;b&gt;Level 3에서는 절반, 그 이후론 대부분의 요청을 드랍&lt;/b&gt;하며 GIL이 가진 병렬 처리 제한의 한계를 명백히 보여주었다. 사용할 수 없을 수준이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Go는 Level 25 정도는 전혀 무리가 아니라는 듯이 당당히 &lt;b&gt;드랍률 0%&lt;/b&gt;를 기록했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - CPU-Usage&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DUNpf/dJMcafkEiTT/VS0zEwFHnmwk1wacTf25Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DUNpf/dJMcafkEiTT/VS0zEwFHnmwk1wacTf25Ik/img.png&quot; data-alt=&quot;CPU-Usage (단위: %)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DUNpf/dJMcafkEiTT/VS0zEwFHnmwk1wacTf25Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDUNpf%2FdJMcafkEiTT%2FVS0zEwFHnmwk1wacTf25Ik%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;1260&quot; height=&quot;389&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CPU-Usage (단위: %)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 1&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 3&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 5&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 10&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 25&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;Flask&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;12%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;17%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;16%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;16%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;16%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;Go 위임&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;9%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;11%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;10%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;9%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;10%&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 Flask는 현재 단일 프로세스(워커)로 가동중이기 때문에, GIL 제약에 의해 동시 활동 가능 스레드는 1개이므로 &lt;b&gt;단 1개의 CPU 코어만 활용한다. &lt;/b&gt;내 PC의 총 코어 수는 8개인데, 그 중에 1개만 쓸 수 있으니 이론적으로 Flask의 CPU 사용률 한계는 12.5%이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 12.5%를 초과하는 이유는, Node exporter는 &lt;b&gt;호스트의 CPU 사용률&lt;/b&gt;을 측정하기 때문에 Flask + 브라우저 및 기타 프로그램의 CPU 사용률이 함께 집계되기 때문이다.&lt;/p&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;Flask는 Level 1 에서 12%로 CPU를 전부 활용하지 않았지만, &lt;b&gt;Level 3부터 활용 가능한 CPU를 최대로 활용&lt;/b&gt;하며 고군분투 하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Go는 Level 1 부터 Level 25 까지 일정한 CPU 사용률을 보인다. GO는 GIL 제약이 없기 때문에 8개 코어를 모두 활용할 수 있는데, 전부 활용하게 되면 CPU 사용률이 100%로 찍힌다. 그 말은, &lt;b&gt;이 정도의 연산은 GO에게 CPU를 더 쓸 필요도 없는 가벼운 연산&lt;/b&gt;이라는 뜻이 되겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;이제 Go가 Flask보다 CPU 집약적 연산에 훨씬 강하다는 것은 증명되었다. 그러나, 이쯤 되면 Go의 한계는 어디인지가 궁금해진다. 바로 테스트 해 보자.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - CPU-Usage (Go의 한계 측정)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZjiL0/dJMcacBswOc/8Kusr5JOGk8p3AM9e8Dzr0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZjiL0/dJMcacBswOc/8Kusr5JOGk8p3AM9e8Dzr0/img.png&quot; data-alt=&quot;Go CPU-Usage (단위: %)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZjiL0/dJMcacBswOc/8Kusr5JOGk8p3AM9e8Dzr0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZjiL0%2FdJMcacBswOc%2F8Kusr5JOGk8p3AM9e8Dzr0%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;1257&quot; height=&quot;388&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;388&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Go CPU-Usage (단위: %)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;구분&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 500&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 600&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 700&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 800&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;Level 1000&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;Go 위임&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;58%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;62%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;100%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;100%&lt;/td&gt;
&lt;td style=&quot;width: 16.6667%; text-align: center;&quot;&gt;100%&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;레벨이 확 뛴게 약간 웃길 정도다. 레벨을 조금씩 올리며 병목지점을 찾으려 했는데, 너무 잘 버티는 바람에 한번에 Level 1000으로 올리면서 병목지점을 찾았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Level 500, 600도 Go에게 크게 무리한 작업은 아니었다. &lt;b&gt;Level 600 기준 드랍률은 거의 0%였고, latency도 820ms로 느리긴 하나 충분히 사용 가능한 수준&lt;/b&gt;이었다. 그러나 Level 700부터 CPU 사용률 100%를 찍고 본격적인 병목이 시작되었다. 이정도가 Go의 한계라고 볼 수 있겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 지표는 단순한 CPU 사용량 비교를 넘어서, Go가 멀티스레드 + 멀티코어 + 병렬 처리를 효과적으로 수행해 내고 있다는 증거이기도 하다. Flask는 GIL 제약에 의해 1개의 스레드(코어)만 활용했기에 최대 사용률이 16%정도에서 머물렀으나, Go는 CPU 사용률 100%를 달성하며 &lt;b&gt;CPU의 모든 자원을 활발히 활용하고 있다는 것을 증명&lt;/b&gt;했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;병목이 어디부터 시작되었는가?&quot; 를 기준으로 Flask와 Go를 비교하면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Flask: Level 3 (연산 30만번)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;Go: Level 700 (연산 7000만번)&lt;/i&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;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심지어 Go는 Level 1000일 때, 즉 &lt;b&gt;연산 1억번이 필요한 요청이 초당 50개&lt;/b&gt;씩 들어왔을 때도 드랍률 30%, latency 4s 수준이었다. Flask와 비슷한 수준으로 망하려면 레벨을 어디까지 올려야 할 지 감이 안 잡힌다.&lt;/p&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;MSA 아키텍처의 구성 방법에 따라 성능이 얼마나 차이날 수 있는지를 다시 한 번 증명&lt;/b&gt;했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;파이썬 워커를 코어 수 만큼 늘린다면, 모든 코어를 활용하니 Go와 비슷해지지 않을까?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;...라는 생각을 했어서, 조금 공부해 보았다. 결과부터 말하면, &quot;전혀 그렇지 않다&quot;. 물론 성능이 조금 나아지긴 하겠지만, Go와의 성능차이를 유의미하게 좁히지 못한다. 왜냐?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;워커를 늘린다는 것은, 프로세스를 늘린다는 것이다. 파이썬의 GIL 제약은 프로세스 단위로 전파되기에, 워커 1개 당 1개의 코어를 활용할 수 있어 Go와 얼핏 비슷한 것 처럼 보인다. 그러나 이것은 &lt;b&gt;자원 공유/문맥 전환 관점에서 매우 큰 차이&lt;/b&gt;가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;첫번째 이유&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 Flask가 여러 개의 워커(프로세스)를 다룬다 하더라도, 결국 결과는 Flask에서 집계되어야 한다. 그러기 위해선 프로세스 간 통신 메커니즘(IPC)가 필요하고, 프로세스 간 문맥 전환(Context Swicting)이 필요하다. 문제는 이 &lt;b&gt;두 작업 모두 상당히 큰 오버헤드&lt;/b&gt;를 초래한다는 것이다. 심지어 &lt;b&gt;프로세스 자체도 메모리를 많이 차지&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;두번째 이유&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Go의 &lt;b&gt;M:N 메커니즘과 Goroutine의 엄청난 효율성&lt;/b&gt; 때문이다. Go는 하나의 프로세스 내에서 멀티스레드로 동작하는데, 스레드 간 문맥 전환 비용을 최소화 시키기 위해 더 작은 작업 단위인 Goroutine에 작업을 부여한다. Goroutine은 스레드 생성/전환에 비해 &lt;b&gt;오버헤드가 수십~수천 배 낮다.&lt;/b&gt; 이렇게 양산된 Goroutine들은 각 요청과 1:1로 매핑되며, 이 Goroutine들이 멀티스레드에 적절히 분배되어 매우 효율적인 병렬 처리를 가능하게 한다. 즉 스레드 생성/전환 비용을 Goroutine 생성/전환 비용으로 전환해 극한의 효율을 뿜어내는 것이다.&lt;/p&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;i&gt;-&amp;gt; 따라서 파이썬이 워커를 늘리더라도, Go의 성능을 유의미하게 따라잡지 못 한다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flask와 Go의 CPU Bound, I/O Bound의 효율성 차이를 더 상세히 알아보고 싶다면 아래 글을 참고하라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://yskisking.shop/362&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://yskisking.shop/362&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1763047267713&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;[msa-perf-lab] Python과 Go 비교:  I/O &amp;amp; CPU Bound 작업에서의 동시성 차이 분석 - GIL, Gouroutine, M:N 스케줄링&quot; data-og-description=&quot;MQ 비동기 도입 전/후 테스트를 진행하며, 파이썬의 I/O 작업 처리 방식에 궁금증이 생겼다. 1초가 걸리는 요청을 초당 100개씩 보냈는데도 1초마다 100개를 전부 응답했기 때문이다. 파이썬은 GIL 때&quot; data-og-host=&quot;yskisking.shop&quot; data-og-source-url=&quot;https://yskisking.shop/362&quot; data-og-url=&quot;https://yskisking.shop/362&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/FAMTo/hyZNLVkePv/KWKxTmaMREtqaf6EABBHV0/img.jpg?width=800&amp;amp;height=336&amp;amp;face=0_0_800_336,https://scrap.kakaocdn.net/dn/uTs4t/hyZNYmMDpt/I2lxJyKKmzJah2HIRcxBKk/img.jpg?width=800&amp;amp;height=336&amp;amp;face=0_0_800_336,https://scrap.kakaocdn.net/dn/7cJWe/hyZNEu8EB4/o5zPK4XB8jWIlkDqK5tBx1/img.jpg?width=910&amp;amp;height=383&amp;amp;face=0_0_910_383&quot;&gt;&lt;a href=&quot;https://yskisking.shop/362&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yskisking.shop/362&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/FAMTo/hyZNLVkePv/KWKxTmaMREtqaf6EABBHV0/img.jpg?width=800&amp;amp;height=336&amp;amp;face=0_0_800_336,https://scrap.kakaocdn.net/dn/uTs4t/hyZNYmMDpt/I2lxJyKKmzJah2HIRcxBKk/img.jpg?width=800&amp;amp;height=336&amp;amp;face=0_0_800_336,https://scrap.kakaocdn.net/dn/7cJWe/hyZNEu8EB4/o5zPK4XB8jWIlkDqK5tBx1/img.jpg?width=910&amp;amp;height=383&amp;amp;face=0_0_910_383');&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;[msa-perf-lab] Python과 Go 비교: I/O &amp;amp; CPU Bound 작업에서의 동시성 차이 분석 - GIL, Gouroutine, M:N 스케줄링&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;MQ 비동기 도입 전/후 테스트를 진행하며, 파이썬의 I/O 작업 처리 방식에 궁금증이 생겼다. 1초가 걸리는 요청을 초당 100개씩 보냈는데도 1초마다 100개를 전부 응답했기 때문이다. 파이썬은 GIL 때&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yskisking.shop&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;span style=&quot;color: #222222; text-align: start;&quot;&gt;==========&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;msa-perf-lab 깃허브:&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/YangSunkue/msa-perf-lab&quot;&gt;https://github.com/YangSunkue/msa-perf-lab&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;==========&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;프로젝트를 시작할 땐 이 정도로 깊게 파게 될 줄 몰랐다. 단순히 기술을 써보고, 성능을 테스트하는 수준에서 머무를 줄 알았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;그러나 직접 실험 환경을 구축하고 테스트를 진행하는 동안 의문점들이 끝없이 쏟아졌다. &quot;이건 왜 이렇게 동작하지?&quot;, &quot;원리가 뭐지?&quot;, &quot;이렇게 바꾸면 될 것 같은데?&quot; 등등 말이다. 프로젝트를 진행하며 자연스럽게 다양한 트러블 슈팅을 하고 의문점들을 해결하며 기술에 대한 이해도와 깊이가 많이 증가하는 것 같다.&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: #222222; text-align: start;&quot;&gt;그러나 두려운 건, 깊이가 증가할 수록 더 깊은 곳을 보게 된다는 점이다. 파도 파도 끝이 없다. 계~속 공부해도 계~속 새로운 궁금증이 생길 것 같다. 그러나 그게 내가 개발을 좋아하는 이유니까, 동시에 개발하길 잘 했다는 생각도 든다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Development/[msa-perf-lab] Flask &amp;amp; Go MSA 성능 실험 프로젝트</category>
      <category>CPU Bound</category>
      <category>CPU 집약적 연산</category>
      <category>GiL</category>
      <category>goroutine</category>
      <category>msa 아키텍처</category>
      <category>N:M 스케줄링</category>
      <category>Python Go 성능 비교</category>
      <category>멀티스레드</category>
      <category>백엔드</category>
      <category>병렬 처리</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/363</guid>
      <comments>https://yskisking.tistory.com/363#entry363comment</comments>
      <pubDate>Fri, 14 Nov 2025 00:29:15 +0900</pubDate>
    </item>
    <item>
      <title>[msa-perf-lab] Python과 Go 비교:  I/O &amp;amp; CPU Bound 작업에서의 동시성 차이 분석 - GIL, Gouroutine, M:N 스케줄링</title>
      <link>https://yskisking.tistory.com/362</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;MQ 비동기 도입 전/후 테스트를 진행하며, 파이썬의 I/O 작업 처리 방식에 궁금증이 생겼다. 1초가 걸리는 요청을 초당 100개씩 보냈는데도 1초마다 100개를 전부 응답했기 때문이다. 파이썬은 GIL 때문에 한번에 하나의 작업만 처리하는 걸로 알고 있었는데다가, 내가 &lt;b&gt;비동기 처리를 하지 않았는데도 비동기처럼 동작&lt;/b&gt;하길래 무슨 원리인지 궁금해서 파 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;383&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9rBgr/dJMcagcMtmg/gUy4kukMdG2xPuBbv4ZLuk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9rBgr/dJMcagcMtmg/gUy4kukMdG2xPuBbv4ZLuk/img.jpg&quot; data-alt=&quot;출처: https://medium.com/@mostofameem/goroutine-deep-dive-why-goroutine-is-called-a-light-weight-thread-37d9a93f86e5&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9rBgr/dJMcagcMtmg/gUy4kukMdG2xPuBbv4ZLuk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9rBgr%2FdJMcagcMtmg%2FgUy4kukMdG2xPuBbv4ZLuk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;910&quot; height=&quot;383&quot; data-origin-width=&quot;910&quot; data-origin-height=&quot;383&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://medium.com/@mostofameem/goroutine-deep-dive-why-goroutine-is-called-a-light-weight-thread-37d9a93f86e5&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;GIL(Global Interpreter Lock)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GIL은 Global Interpreter Lock의 약자로서, 간단히 말하면 파이썬에서 하나의 프로세스(워커)가 동시에 하나의 CPU 작업만 실행하게 하는 제약조건이다. 이 제약 때문에 &lt;b&gt;파이썬 코드는 언제나 동시에 단 한개만 실행&lt;/b&gt;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이것이 싱글스레드로 동작한다는 말은 아니다. 필요에 따라 스레드를 추가로 띄워 멀티 스레드로 동작하지만, 동시에 실행되는 스레드가 하나일 뿐이다. 즉, 몇 개의 스레드를 활용 중이든 &lt;b&gt;현재 CPU를 점유한 단 하나의 스레드만 동작하고 나머지는 블로킹(Blocking)&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;GIL을 우회하는 방법은 하나뿐이다. 프로세스(워커)를 여러 개 띄우는 것이다. GIL의 영향범위는 프로세스 내부이기 때문에 다른 프로세스에 간섭할 수 없다. 그러나 이 방식도 한계가 있는게, 프로세스는 CPU 코어 수 만큼만 확장할 수 있다. 하나의 스레드는 동시에 하나의 코어만 점유할 수 있기 때문이다. 게다가 프로세스를 여러 개 띄우면 메모리 낭비로 이어지기도 한다. 즉 이것은 제약을 어느 정도 완화하는 거지, 해결 방법은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;I/O Bound&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;I/O Bound 작업에서의 Python 동작방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기 처리를 하지 않은 상태에서, &lt;b&gt;I/O 작업이 동시에 100개&lt;/b&gt;가 들어왔다고 해 보자(예: 외부 API 호출). 이 때 스레드와 요청은 1:1로 묶여 블로킹 되지만, I/O 대기시간엔 CPU를 점유하지 않기 때문에 자발적으로 GIL을 놓아 다른 스레드를 추가하고 실행될 기회를 준다.&lt;/p&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;gt; 블로킹 -&amp;gt; GIL 놓음 -&amp;gt; 다음 스레드 생성 -&amp;gt; 블로킹 ... 이런 순서다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 &lt;b&gt;OS 스레드는 무거운데다, 문맥 전환 비용이 커서 이것은 절대 효율적인 방식이 아니다&lt;/b&gt;. 요청이 만약 1000개, 10000개 들어온다면? 스레드를 그만큼 많이 띄우게 되어 메모리가 터져버릴 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;I/O Bound 작업에서의 Go 동작방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 Go는 GIL 제약이 없기 때문에 단 하나의 프로세스로 멀티스레드를 활용할 수 있다. 즉, 코어를 전부 활용할 수 있다. Go는 특이하게도 Goroutine 이라는 스레드보다 더 작은 자체 작업 단위를 사용하는데, &lt;b&gt;Goroutine의 오버헤드는 스레드 생성/삭제/문맥전환 비용보다 훨씬 적기 때문에 수십만 개를 띄워도 문제가 없다&lt;/b&gt;. 따라서 하나의 요청 당 하나의 Goroutine을 띄워서, 이것을 멀티스레드에 적절히 분배한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 프로세스 내에서 멀티스레드가 멀티코어를 효율적으로 활용하기 때문에, 이것만으로도 충분히 빠른 성능을 낸다. 그러나 가장 큰 차이를 내는 건 역시 파이썬의 OS 스레드와 Go의 Goroutine 효율 차이이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CPU Bound&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU Bound 작업에서의 Python 동작방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I/O 작업에서는 OS스레드를 무리하게 띄워 어떻게든 처리가 가능했으나, CPU Bound로 넘어오면 다르다. &lt;b&gt;CPU Bound 작업은 연산하는 동안 GIL을 놓지 않기 때문에, 멀티 코어의 병렬 처리 이점을 얻을 수 없으며&lt;/b&gt; 정확히 프로세스(워커) 수 만큼만 동시에 처리할 수 있다. 만약 프로세스가 4개이고 동시 요청 100개가 들어온다면, 4개의 요청만 동시에 처리하고 나머지 96개는 뒤늦게 처리되거나 전부 드랍될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU Bound 작업에서의 Go 동작방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GIL 제약이 없기 때문에 병렬 처리가 가능하다. 요청 수 만큼 Goroutine을 띄우고 연산 작업을 맡기며, 이 Goroutine들을 멀티스레드에 적절하게 할당하여 멀티스레드 + 멀티코어의 성능을 최대한 활용한 병렬 처리를 실현한다(M:N 스케줄링).&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;여러 개 프로세스에서 코어를 하나씩 쓰는 거나(Python), 하나의 프로세스에서 코어를 여러개 쓰는 거나(Go) 결국 코어를 전부 사용한다는 건 같지 않나?&lt;/b&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;가 있다. 각 프로세스는 독립적인 공간을 가지기 때문에 메모리 복사 및 초기화 비용이 크고, 메모리 사용량이 많아진다. 또한 IPC(프로세스간 통신 메커니즘)가 필요한데, 이는 커널 개입이 필요하여 무겁고 느리다. 또한 문맥 전환 시 매우 큰 프로세스 정보를 저장하고 복원해야 하므로, 비용이 높다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 프로세스 내에서 동작하는 스레드/Goroutine은 하나의 메모리 공간을 공유하며, 자원 공유나 전환 비용이 낮다. 또한 Goroutine 전환은 Go 런타임에 자체적으로 이루어지고, OS 스레드 문맥 전환보다 훨씬 가볍기 때문에 효율적이다.&lt;/p&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;i&gt;-&amp;gt; 즉, 멀티프로세스(Python)에서는 자원 공유/문맥 전환 오버헤드가 Go에 비해 훨씬 높기 때문에 비효율적이다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Go의 M:N 스케줄링&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.5891%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;구분&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 42.4031%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;M (Goroutine)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 46.0077%; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;N (OS 스레드)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.5891%; text-align: center;&quot;&gt;역할&lt;/td&gt;
&lt;td style=&quot;width: 42.4031%; text-align: center;&quot;&gt;작업 단위 (가벼움, 수많은 요청)&lt;/td&gt;
&lt;td style=&quot;width: 46.0077%; text-align: center;&quot;&gt;실행 단위 (무거움, CPU 코어 수와 비슷한 수준으로 관리)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 11.5891%; text-align: center;&quot;&gt;특징&lt;/td&gt;
&lt;td style=&quot;width: 42.4031%; text-align: center;&quot;&gt;Go 런타임이 관리 &lt;b&gt;(생성/전환 비용 극히 낮음)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 46.0077%; text-align: center;&quot;&gt;OS 커널이 관리 (생성/전환 비용 및 메모리 사용량 높음)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;M개의 Goroutine을 N개의 OS스레드에 유연하게 매핑하여 실행하는,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Go 런타임의 동시성 관리 기법&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;Go는 CPU 코어 수와 같거나 약간 많은 수의 OS 스레드를 N개 생성한다. 이 스레드 위에서 수십만 개의 Goroutine M개를, Go 런타임이 자체적으로 관리하며 실행한다. Goroutine 간 전환이 OS 커널 개입 없이 Go 런타임 내에서 이루어지기 때문에, Python처럼 무거운 &lt;b&gt;OS 스레드를 전환하는 오버헤드를 원천적으로 제거&lt;/b&gt;한다. 또한 Goroutine이 I/O 대기 상태에 들어가면, Go는 해당 스레드를 묶어두지 않고 &lt;b&gt;대기 중인 Goroutine을 제거 후 다른 Goroutine을 즉시 투입&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;i&gt;-&amp;gt; 결론적으로, Go는 무거운 OS 스레드(N)은 CPU 활용에만 전념하게 하고, 수많은 요청(M)은 가벼운 Goroutine으로 처리하여 자원 효율성과 병렬성을 극대화한다.&lt;/i&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: #222222; text-align: start;&quot;&gt;==========&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;msa-perf-lab 깃허브:&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/YangSunkue/msa-perf-lab&quot;&gt;https://github.com/YangSunkue/msa-perf-lab&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;==========&lt;/span&gt;&lt;/p&gt;</description>
      <category>Development/[msa-perf-lab] Flask &amp;amp; Go MSA 성능 실험 프로젝트</category>
      <category>context switching</category>
      <category>CPU Bound</category>
      <category>GiL</category>
      <category>go</category>
      <category>goroutine</category>
      <category>I/O Bound</category>
      <category>M:N 스케줄링</category>
      <category>OS스레드</category>
      <category>Python</category>
      <category>스레드</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/362</guid>
      <comments>https://yskisking.tistory.com/362#entry362comment</comments>
      <pubDate>Wed, 12 Nov 2025 17:48:51 +0900</pubDate>
    </item>
    <item>
      <title>[msa-perf-lab] 메시지 큐(RabbitMQ) 비동기 처리 전후 I/O 작업 성능 테스트</title>
      <link>https://yskisking.tistory.com/361</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 성능 테스트에서는 &lt;b&gt;I/O 바운드 작업에 대한 클라이언트 응답 시간&lt;/b&gt;을, 메시지 큐 비동기 처리 도입 전/후로 테스트 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 -&amp;gt; Flask -&amp;gt; Go(Gin) 흐름으로 사용자 요청이 전달되고, 실제 비즈니스 로직 작업은 항상 Go에서 한다. 이 때, 실제 비즈니스 로직이 아닌 time.sleep() 함수로 대체하여 병목 시간 1초를 시뮬레이션한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 방식인 동기(Sync)방식은, Flask에서 &lt;b&gt;Go에게 직접 요청을 건네고 Go가 1초 후 응답하는 것을 기다렸다가 클라이언트에게 응답&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지 큐 비동기(Async)방식은, Flask에서 RabbitMQ에 &lt;b&gt;메시지를 발행(publish)하고 클라이언트에게 즉시 응답&lt;/b&gt;한다. Go의 컨슈머는 무한 대기 상태로 있다가, 큐에 메시지가 publish되면 자동으로 감지해 해당 태스크를 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉 동기(Sync) 방식은 클라이언트 응답속도가 &lt;b&gt;최소 1초 이상&lt;/b&gt;이 될 것이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시지 큐 비동기(Async) 방식은 클라이언트 응답속도가 &lt;b&gt;ms단위&lt;/b&gt;일 것이다. 큐에 넣고 즉시 응답하니까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예상대로 동작할 지 실제로 테스트 해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Flask 측 동기/비동기 서비스 함수&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;698&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHU0OL/dJMcagX9gbx/o4FcwWKLGWgtUriQA0QKyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHU0OL/dJMcagX9gbx/o4FcwWKLGWgtUriQA0QKyK/img.png&quot; data-alt=&quot;동기/비동기 서비스 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHU0OL/dJMcagX9gbx/o4FcwWKLGWgtUriQA0QKyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHU0OL%2FdJMcagX9gbx%2Fo4FcwWKLGWgtUriQA0QKyK%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;531&quot; height=&quot;698&quot; data-origin-width=&quot;531&quot; data-origin-height=&quot;698&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;동기/비동기 서비스 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flask Gateway에 요청이 오면, 위 둘 중 하나의 함수로 연결된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동기 함수는 Go서버가 1초 뒤에 응답하는 것을 &lt;b&gt;기다렸다가 응답&lt;/b&gt;하는 함수고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비동기 함수는 RabbitMQ에 메시지 발행 후 Go를 기다리지 않고 &lt;b&gt;즉시 응답&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;메시지 발행 함수 (RabbitMQ)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;644&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dSg1ds/dJMcacIdhiL/c5eEtg9pSdxBhJkusYaqk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dSg1ds/dJMcacIdhiL/c5eEtg9pSdxBhJkusYaqk1/img.png&quot; data-alt=&quot;메시지 발행 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dSg1ds/dJMcacIdhiL/c5eEtg9pSdxBhJkusYaqk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdSg1ds%2FdJMcacIdhiL%2Fc5eEtg9pSdxBhJkusYaqk1%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;653&quot; height=&quot;644&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;644&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메시지 발행 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스에서 호출하는 publish_message 함수는 이렇게 구현되어 있다. 이 함수를 호출하면 자동으로 커넥션을 가져오고, 메시지를 publish 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메시징 라이브러리는 Kombu를 활용했는데, 처음에 Pika를 사용하다가 Kombu로 바꿨다. 그 과정은 아래와 같다.&lt;/p&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. Pika 라이브러리 활용, Race Condition 문제 발생&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pika 라이브러리를 활용해 테스트를 진행하였더니 고부하 환경을 버티지 못해 &lt;b&gt;Race Condition 문제&lt;/b&gt;가 발생했고, 스레드 간 커넥션/채널 경합이 일어나며 대부분의 요청이 실패하는(특히 고RPS 환경에서) 문제가 발생했다. 이는 Pika 라이브러리 자체가 내부적으로 &lt;b&gt;Thread-safe하지 않기 때문&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Pika 라이브러리 활용, Race Condition 문제 해결, 커넥션 생성 오버헤드 문제 발생&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 방식은 하나의 커넥션을 공유해서 문제가 발생했기에, 모든 요청이 별개의 커넥션을 생성하여 활용하도록 했다. 결과적으로 Race Condition 문제는 완벽히 사라졌고 요청 성공률 100%를 달성했지만, 응답속도가 동기와 비슷한 수준으로 형편없었다. 이는 &lt;b&gt;모든 요청이 별개의 커넥션을 생성/삭제 할 때 일어나는 오버헤드가 매우 크기 때문&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Kombu 라이브러리 활용, Race Condition + 커넥션 생성 오버헤드 문제 해결 (모든 문제 해결)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Pika 라이브러리의 한계를 느껴, Kombu 라이브러리로 교체했다. Kombu는 내부적으로 &lt;b&gt;커넥션 풀(Connection Pool)을 활용하고, Thread-safe한 특성&lt;/b&gt;을 가지기 때문에 Race Condition 문제에서 자유롭다. 따라서 고부하 환경에 적합한 라이브러리다. 교체 후 Race Condition 및 커넥션 생성 오버헤드 문제가 모두 해결되었고, 원하는 테스트 결과를 얻었다. (결과는 아래에)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Go 서버 메시지 처리 함수&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;473&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqyhPd/dJMcadUEH86/GDk7ihwHRb0pnnvvVAMf1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqyhPd/dJMcadUEH86/GDk7ihwHRb0pnnvvVAMf1k/img.png&quot; data-alt=&quot;메시지 처리 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqyhPd/dJMcadUEH86/GDk7ihwHRb0pnnvvVAMf1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdqyhPd%2FdJMcadUEH86%2FGDk7ihwHRb0pnnvvVAMf1k%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;536&quot; height=&quot;473&quot; data-origin-width=&quot;536&quot; data-origin-height=&quot;473&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;메시지 처리 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Go서버는 stream 형태의 channel(consumer)을 활용해 무한히 대기하다가, 메시지가 발행되면 자동으로 이 함수를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I/O 작업을 실행한 후 Ack(처리 완료 메시지)를 남기는데, Ack는 큐에서 메시지를 삭제해도 된다는 일종의 알림이다.&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;427&quot; data-origin-height=&quot;301&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MjBLP/dJMcagjxGEF/l0JjtQNVhtKmHmCT2pxCZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MjBLP/dJMcagjxGEF/l0JjtQNVhtKmHmCT2pxCZk/img.png&quot; data-alt=&quot;1초 대기 함수&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MjBLP/dJMcagjxGEF/l0JjtQNVhtKmHmCT2pxCZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMjBLP%2FdJMcagjxGEF%2Fl0JjtQNVhtKmHmCT2pxCZk%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;427&quot; height=&quot;301&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;301&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;1초 대기 함수&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1초 대기하는 시뮬레이션 함수이다. 동기/비동기 모두 I/O 작업은 이걸로 대체된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;K6 트래픽 생성 스크립트&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;699&quot; data-origin-height=&quot;481&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cvUtCa/dJMcafkDols/QF2eVpV3ML6hWRyrYo9dL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cvUtCa/dJMcafkDols/QF2eVpV3ML6hWRyrYo9dL0/img.png&quot; data-alt=&quot;스크립트 일부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cvUtCa/dJMcafkDols/QF2eVpV3ML6hWRyrYo9dL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcvUtCa%2FdJMcafkDols%2FQF2eVpV3ML6hWRyrYo9dL0%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;670&quot; height=&quot;461&quot; data-origin-width=&quot;699&quot; data-origin-height=&quot;481&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스크립트 일부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 조건은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RPS(초당 요청 수): 50 ~ 400 (50씩 증가)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DURATION(지속시간): 30s&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;maxVU(최대 가상 사용자 수): 100&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RPS 400일 경우, 30초동안 12000개의 요청이 가는 것이다.&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;625&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IFZcK/dJMcahbGrSD/rCqQSmXT1VN72SRI427RTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IFZcK/dJMcahbGrSD/rCqQSmXT1VN72SRI427RTk/img.png&quot; data-alt=&quot;쉘 스크립트 일부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IFZcK/dJMcahbGrSD/rCqQSmXT1VN72SRI427RTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIFZcK%2FdJMcahbGrSD%2FrCqQSmXT1VN72SRI427RTk%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;625&quot; height=&quot;312&quot; data-origin-width=&quot;625&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;쉘 스크립트 일부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RPS를 증가시키며 동기/비동기 테스트를 모두 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;50sync -&amp;gt; 50async -&amp;gt; 100sync -&amp;gt; 100async ...&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;817&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9T3R3/dJMcaf50vGH/ueyywo0yNpBe78ivUuw4bK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9T3R3/dJMcaf50vGH/ueyywo0yNpBe78ivUuw4bK/img.png&quot; data-alt=&quot;테스트 시작&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9T3R3/dJMcaf50vGH/ueyywo0yNpBe78ivUuw4bK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9T3R3%2FdJMcaf50vGH%2Fueyywo0yNpBe78ivUuw4bK%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;817&quot; height=&quot;322&quot; data-origin-width=&quot;817&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트 시작&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 시작!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - 평균 응답시간(Avg Latency)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cnvWGh/dJMcadmOGVH/Go2YrDsl7XUPKRvhAZPHh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cnvWGh/dJMcadmOGVH/Go2YrDsl7XUPKRvhAZPHh0/img.png&quot; data-alt=&quot;평균 응답시간 (단위: ms)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cnvWGh/dJMcadmOGVH/Go2YrDsl7XUPKRvhAZPHh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcnvWGh%2FdJMcadmOGVH%2FGo2YrDsl7XUPKRvhAZPHh0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1261&quot; height=&quot;454&quot; data-origin-width=&quot;1261&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;평균 응답시간 (단위: ms)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응답시간은 클라이언트가 요청을 보내고 응답을 받기까지의 시간을 의미한다. 왼쪽부터 RPS를 50씩 올려가며, 동기/비동기를 묶어 진행했다.&lt;/p&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;동기는 RPS에 관계없이 평균 1s&lt;/b&gt;,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비동기는 평균 2~4ms&lt;/b&gt; 정도의 응답시간을 보인다. &lt;b&gt;무려 500배 차이가 난다!!!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - P(95) 응답시간 (P95 Latency)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nxBWH/dJMcac9hBQu/soPRG0rkCJ4txyYqMBzGkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nxBWH/dJMcac9hBQu/soPRG0rkCJ4txyYqMBzGkk/img.png&quot; data-alt=&quot;P(95) 응답시간 (단위: ms)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nxBWH/dJMcac9hBQu/soPRG0rkCJ4txyYqMBzGkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnxBWH%2FdJMcac9hBQu%2FsoPRG0rkCJ4txyYqMBzGkk%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;1263&quot; height=&quot;456&quot; data-origin-width=&quot;1263&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;P(95) 응답시간 (단위: ms)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;P95는 전체 요청 중 95%가 해당 값 이하의 응답시간을 가졌다는 의미이다.&lt;/p&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~5ms 정도로 평균값보다 약간 더 높고, 간간히 64ms 까지 튀어있다. 그러나 이 정도는 큰 문제가 없다고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - 처리량 (Throughput)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eSJeVy/dJMcacVKniM/zg5yzjXbmFOPBE0Kz6gU31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eSJeVy/dJMcacVKniM/zg5yzjXbmFOPBE0Kz6gU31/img.png&quot; data-alt=&quot;초당 처리량 (단위: 개)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eSJeVy/dJMcacVKniM/zg5yzjXbmFOPBE0Kz6gU31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeSJeVy%2FdJMcacVKniM%2Fzg5yzjXbmFOPBE0Kz6gU31%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;1257&quot; height=&quot;452&quot; data-origin-width=&quot;1257&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;초당 처리량 (단위: 개)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초당 처리량은 1초동안 몇 개의 요청에 성공 응답을 보냈느냐를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VU를 100으로 제한해 둔 결과, &lt;b&gt;동기는 RPS 100부터 처리량이 100 정도에서 정체&lt;/b&gt;된 반면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비동기는 RPS크기에 따라 처리량이 계속해서 증가&lt;/b&gt;한다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 비동기 방식이 K6에서 세팅해 둔 모든 요청을 안정적으로 받아 처리했다는 뜻이다. 현재 결과를 보니, RPS를 큰 폭으로 올려도 안정적일 것으로 예상된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴 수 밖에 없는 게, 동기 방식은 무조건 1초를 기다려야 응답이 오니 1초에 VU 한 명당 1개밖에 처리할 수 없는 것은 당연하다. 비동기 방식은 1초를 기다릴 필요가 없으니 같은 VU를 가지고도 훨씬 더 많은 요청을 처리할 수 있는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 - 총 요청 대비 드랍률(Drop-rate)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cdHkWd/dJMcadf24zB/jcWp8tHXsDUfzkfw45kG2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cdHkWd/dJMcadf24zB/jcWp8tHXsDUfzkfw45kG2k/img.png&quot; data-alt=&quot;총 요청 대비 드랍률 (단위: %)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cdHkWd/dJMcadf24zB/jcWp8tHXsDUfzkfw45kG2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcdHkWd%2FdJMcadf24zB%2FjcWp8tHXsDUfzkfw45kG2k%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;1258&quot; height=&quot;387&quot; data-origin-width=&quot;1258&quot; data-origin-height=&quot;387&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;총 요청 대비 드랍률 (단위: %)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과를 보면, 동기 드랍률밖에 없다. 왜냐하면, &lt;b&gt;비동기는 단 한 개의 요청도 드랍하지 않았기 때문&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동기 방식은 100RPS 까지는 드랍률 2.97% 정도로 크게 문제가 없는 듯 보였으나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;150RPS 부터 갑자기 34%&lt;/b&gt;로 치솟더니,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;400RPS 에서는 무려 총 요청 중 75%를 드랍&lt;/b&gt;했다. 즉, 예정된 12000개의 요청 중 3000개만 보냈고, 나머지 9000개는 이전 요청 응답을 기다리다가 보내지도 못하고 테스트가 종료된 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흠.. 근데 여기서 든 의문이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;i&gt;VU를 100으로 고정했으니, 당연히 초당 100개만 처리할 수 있는 것 아닌가? 내부 로직을 1초 걸리게 설계해 놓고, RPS는 올리면서 VU를 고정하면 당연히 드랍률이 올라가지.&lt;/i&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;그렇다면.. VU를 RPS 만큼 올리면 동기 방식도 드랍률이 떨어질 것 같은데?&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;뭐 그렇긴 하다. 그러나 그것은 테스트 목적과 어긋나며, 아키텍처 효율성이 아닌 &quot;&lt;b&gt;시스템 자체의 한계&lt;/b&gt;&quot;를 측정하는 꼴이 되어 버린다. 우리가 테스트 해야 할 것은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;같은 조건에서 동기/비동기 방식의 효율 차이&lt;/b&gt;이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;VU 수는 서버 측 스레드 개수로 치환할 수 있다. 왜냐하면 VU 1개가 요청 1개를 보내고 1초 기다리는 동안, 해당 작업을 맡은 스레드도 1초 동안 Blocking 되기 때문이다. 즉,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;요청 1개당 1개의 스레드가 묶인다&lt;/b&gt;. VU가 무한이라고 가정했을 때 RPS가 100이면 초당 100개의 스레드가 묶이고, RPS가 10000이면 초당 10000개의 스레드가 묶인다. &quot;엄청난 비효율&quot; 이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그러나&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;비동기 방식&lt;/b&gt;은 Input/Output 작업을 분리함으로서 훨씬 적은 수의 스레드로 수많은 요청을 처리할 수 있다. 위쪽에서 보았던 평균 응답속도 2ms를 대입하면, 동기 방식(1s)보다&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;500배 많은 요청을 처리할 수 있다&lt;/b&gt;는 뜻이 된다. 물론 코어 서버(Go)에서 실제로 처리하는 데에는 좀 더 많은 시간이 걸리겠지만, 애초에 즉시 처리하지 않아도 되는 로직에 메시지 큐를 적용하는 데다가 Go서버는 병렬/비동기 처리에 특화되어 있으니 그것은 큰 문제가 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;정리 (RPS 400, VU 100, I/O 대기시간 1초 기준)&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 58px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;방식&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;평균 응답시간(Avg Latency)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;초당 처리량(Throughput)&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;총 요청 대비 드랍률(Drop-rate)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 20px; text-align: center;&quot;&gt;동기(Async)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 20px; text-align: center;&quot;&gt;1s (1초)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 20px; text-align: center;&quot;&gt;100 (RPS 100부터 정체)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 20px; text-align: center;&quot;&gt;75%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 18px; text-align: center;&quot;&gt;메시지 큐 비동기(Async)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px; text-align: center;&quot;&gt;2~4ms(0.002~0.004초)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px; text-align: center;&quot;&gt;400 (RPS 수만큼 증가)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px; text-align: center;&quot;&gt;0%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그야말로 엄청난 효율 차이를 보인다. 특히 클라이언트 측 응답 속도가 엄청나게 개선된다는 점이 가장 눈에 띄며, 실제 작업을 Core Engine(Go)에서 처리하니 Gateway 부담이 현저히 줄고, Core Engine은 수평적 확장이 용이하니 확장성 측면에서도 큰 장점을 갖게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 정도면 메시지 큐 적용할 수 있는 모든 곳에 적용하고 싶다는 생각이 들 정도다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;==========&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;msa-perf-lab 깃허브:&lt;/b&gt;&lt;br /&gt;&lt;a href=&quot;https://github.com/YangSunkue/msa-perf-lab&quot;&gt;https://github.com/YangSunkue/msa-perf-lab&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #222222; text-align: start;&quot;&gt;==========&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Go 서버 Task 처리 현황&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;753&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/to18c/dJMcabP4u6q/P0pNs0zlCfJewVws9K3MuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/to18c/dJMcabP4u6q/P0pNs0zlCfJewVws9K3MuK/img.png&quot; data-alt=&quot;매우 훌륭하다&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/to18c/dJMcabP4u6q/P0pNs0zlCfJewVws9K3MuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fto18c%2FdJMcabP4u6q%2FP0pNs0zlCfJewVws9K3MuK%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;753&quot; height=&quot;582&quot; data-origin-width=&quot;753&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;매우 훌륭하다&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Go 서버 로그인데, 오류 하나 없이 완벽하게 처리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간을 보면 전부 같은 시간에 처리되어 있는데(11:58:25), Go 서버에서 메시지 큐 태스크를 &lt;b&gt;비동기 + 병렬&lt;/b&gt;로 잘 처리하고 있다는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Go는 채널의 데이터 공유가 아닌 &quot;통신&quot;특성 덕분에 비동기 문제에 대해 훨씬 안전하다. 따라서 개발자가 비동기 문제를 고민하지 않아도 안전하게 동시성 작업을 할 수 있게 해 준다. 그야말로 혁명이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 테스트에선 동기vs비동기 성능 차이만 측정했지만, 다음엔 Go 서버에서 태스크 처리 실패 시 제어 흐름을 구현해 보려고 한다. DLQ(Dead Letter Queue)를 도입해서 말이다.&lt;/p&gt;</description>
      <category>Development/[msa-perf-lab] Flask &amp;amp; Go MSA 성능 실험 프로젝트</category>
      <category>I/O 작업</category>
      <category>kombu</category>
      <category>MSA</category>
      <category>msa 아키텍처</category>
      <category>msa-perf-lab</category>
      <category>rabbitmq</category>
      <category>Race Condition</category>
      <category>Thread-safe</category>
      <category>메시지 큐</category>
      <category>비동기 처리</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/361</guid>
      <comments>https://yskisking.tistory.com/361#entry361comment</comments>
      <pubDate>Tue, 11 Nov 2025 20:48:51 +0900</pubDate>
    </item>
    <item>
      <title>[msa-perf-lab] REST vs gRPC 성능 비교 및 InfluxDB + Grafana 시각화</title>
      <link>https://yskisking.tistory.com/360</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;드디어 성능 테스트에 필요한 모든 환경을 구축하고, 실제 테스트까지 해 보았다.&lt;br&gt;트래픽 발생은 JS k6라이브러리를 활용했고, 시계열 데이터를 InfluxDB에 담아 Grafana와 연동해 시각화했다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;InfluxDB + Grafana 컨테이너화&lt;/b&gt;&lt;/h4&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;758&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bATXQU/dJMcabbrpMo/IvFKDkOSmO4v1nfZ0ouOgK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bATXQU/dJMcabbrpMo/IvFKDkOSmO4v1nfZ0ouOgK/img.png&quot; data-alt=&quot;docker-compose.influx.yml&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bATXQU/dJMcabbrpMo/IvFKDkOSmO4v1nfZ0ouOgK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbATXQU%2FdJMcabbrpMo%2FIvFKDkOSmO4v1nfZ0ouOgK%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;668&quot; height=&quot;758&quot; data-origin-width=&quot;668&quot; data-origin-height=&quot;758&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;docker-compose.influx.yml&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;InfluxDB와 Grafana를 컨테이너로 올렸다. Docker에 준비된 이미지를 받아와 띄우고 기본 세팅만 하면 되기 때문에 크게 어렵진 않았다.&lt;br&gt;기존 컨테이너 (Flask + Go(Gin) + PostgreSQL)와 하나의 compose 파일로 묶을까 했지만, 네트워크는 공유하되 테스트용 컨테이너는 분리해 관리하는 것이 나을 것 같아 따로 구성했다.&lt;br&gt;&amp;nbsp;&lt;br&gt;InfluxDB, Grafana 세팅은 크게 건드린 건 없고 최대한 가볍게 띄웠다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bc6Q2D/dJMcafkBQOn/HAHtnrJSktqQsilJlNI0x0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bc6Q2D/dJMcafkBQOn/HAHtnrJSktqQsilJlNI0x0/img.png&quot; data-alt=&quot;준비 완료&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bc6Q2D/dJMcafkBQOn/HAHtnrJSktqQsilJlNI0x0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbc6Q2D%2FdJMcafkBQOn%2FHAHtnrJSktqQsilJlNI0x0%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;1116&quot; height=&quot;410&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;준비 완료&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;모든 컨테이너가 띄워졌다. 위부터 순서대로 Grafana, InfluxDB, Flask, PostgreSQL, Gin 이다.&lt;br&gt;위에서 말했듯 Grafana + InfluxDB, Flask + PostgreSQL + Gin을 각각 compose로 묶었다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;k6 코드 작성 (트래픽 생성기)&lt;/b&gt;&lt;/h4&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;945&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cN564p/dJMcai9tvAV/NaidMwiS654g0I2qRyd2J0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cN564p/dJMcai9tvAV/NaidMwiS654g0I2qRyd2J0/img.png&quot; data-alt=&quot;REST 테스트용 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cN564p/dJMcai9tvAV/NaidMwiS654g0I2qRyd2J0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcN564p%2FdJMcai9tvAV%2FNaidMwiS654g0I2qRyd2J0%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;1031&quot; height=&quot;945&quot; data-origin-width=&quot;1031&quot; data-origin-height=&quot;945&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;REST 테스트용 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;자바스크립트 k6 라이브러리를 활용해 트래픽 생성 코드를 작성했다.&lt;br&gt;이게 무슨 코드냐면,&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;i&gt;Flask서버의 /rest/ping 엔드포인트에,&lt;/i&gt;&lt;br&gt;&lt;i&gt;{size: 10} payload를 담은 POST 요청을 보낸다.&lt;/i&gt;&lt;br&gt;&lt;i&gt;1초에 100번, 30초동안.&lt;/i&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;이런 내용이다.&lt;br&gt;Flask가 요청을 받으면 size(byte단위) 크기 랜덤 문자열을 생성하고, 이것을 Gin 서버로 보낸다. Gin은 해당 데이터를 그대로 Flask에게 응답하는데, 이 때 Flask와 Gin의 통신 프로토콜이 REST이다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;335&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5BNBK/dJMcafEUAvf/UaQOQ6PFdpdkO7bj8msGf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5BNBK/dJMcafEUAvf/UaQOQ6PFdpdkO7bj8msGf0/img.png&quot; data-alt=&quot;공격(?) 시작!&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5BNBK/dJMcafEUAvf/UaQOQ6PFdpdkO7bj8msGf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5BNBK%2FdJMcafEUAvf%2FUaQOQ6PFdpdkO7bj8msGf0%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;810&quot; height=&quot;335&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;335&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;공격(?) 시작!&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;명령어를 실행하면 이렇게 공격(?)을 시작하게 된다. WARN 뜬 건 무시해도 된다. 응답속도가 느려서 VU(가상 사용자) 최대수를 찍었다는 경고다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQuDju/dJMcahCJd4I/RkWkVSfKFnkdjfB3I4YcPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQuDju/dJMcahCJd4I/RkWkVSfKFnkdjfB3I4YcPk/img.png&quot; data-alt=&quot;REST 테스트 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQuDju/dJMcahCJd4I/RkWkVSfKFnkdjfB3I4YcPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQuDju%2FdJMcahCJd4I%2FRkWkVSfKFnkdjfB3I4YcPk%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;870&quot; height=&quot;596&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;REST 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;http_req_duration이 평균 &lt;b&gt;응답속도(latency)&lt;/b&gt;라고 보면 된다.&lt;br&gt;즉, 클라이언트(사용자)가 요청해서 응답을 받기까지의 총 지연시간을 의미한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;보면 실패율은 0% (전부 성공)이지만, 평균 응답속도가 무려 2.22초다. 즉 매우 느리다.&lt;br&gt;최대 응답속도는 35초다. 이건 한번 튄 것 같긴 한데, 어쨌든 10byte 페이로드를 포함한 요청을 초당 100번, 30초간 보내는 것은 현재 내 시스템에게 확실히 무리라는 소리다.&lt;br&gt;&amp;nbsp;&lt;br&gt;이번엔 gRPC로 바꿔 테스트를 해보자.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;439&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FQKyu/dJMcag4Tf23/BF4K2GdnEp0MGrrCKiOQW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FQKyu/dJMcag4Tf23/BF4K2GdnEp0MGrrCKiOQW1/img.png&quot; data-alt=&quot;gRPC 테스트 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FQKyu/dJMcag4Tf23/BF4K2GdnEp0MGrrCKiOQW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFQKyu%2FdJMcag4Tf23%2FBF4K2GdnEp0MGrrCKiOQW1%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;876&quot; height=&quot;439&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;439&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;gRPC 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;보이는가? 단위가 바뀌었다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;i&gt;REST: 2.22s&lt;/i&gt;&lt;br&gt;&lt;i&gt;gRPC: 3.33ms &lt;/i&gt;&lt;i&gt;&lt;b&gt;(약 666배 감소!!!!)&lt;/b&gt;&lt;/i&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;정말 말도 안 되는 속도 향상이 이루어졌다. 어떻게 이렇게까지 차이가 날까?&lt;br&gt;&lt;b&gt;원인은 REST와 gRPC의 파싱 비용과 직렬화/역직렬화 비용 차이 때문이다.&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;i&gt;HTTP/1.1 Keep-Alive는 단순히 연결만 재사용할 뿐, 요청은 항상 직렬이다.&lt;/i&gt;&lt;br&gt;&lt;i&gt;그래서 매 요청마다 HTTP의 긴 텍스트 헤더 파싱 + JSON 직렬화/역직렬화 비용을 다시 지불해야 한다.&lt;/i&gt;&lt;br&gt;&lt;i&gt;즉, REST의 고정 오버헤드는 요청 수만큼 그대로 누적된다.&lt;/i&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;i&gt;반면 HTTP/2는 하나의 커넥션에서 수백 개 스트림을 동시에(병렬) 처리할 수 있고, 헤더는 HPACK압축, 메시지는 바이너리 프레임 + Protobuf 기반이므로 파싱, 직렬화 비용 자체가 REST 대비 극단적으로 낮다.&lt;/i&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;i&gt;-&amp;gt; 따라서 작은 payload일 수록 REST의 고정 파싱 비용이 상대적으로 커지며, gRPC는 오버헤드가 0에 가까워 수십~수백 배 까지 차이가 벌어진다.&lt;/i&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 시각화 (payload: 10Byte)&lt;/b&gt;&lt;/h4&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1273&quot; data-origin-height=&quot;454&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xBbvc/dJMcaess9my/MXXPE2PPCAqxCnX8Eqpjq1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xBbvc/dJMcaess9my/MXXPE2PPCAqxCnX8Eqpjq1/img.png&quot; data-alt=&quot;10B기준 응답 시간 그래프&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xBbvc/dJMcaess9my/MXXPE2PPCAqxCnX8Eqpjq1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxBbvc%2FdJMcaess9my%2FMXXPE2PPCAqxCnX8Eqpjq1%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;1273&quot; height=&quot;454&quot; data-origin-width=&quot;1273&quot; data-origin-height=&quot;454&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;10B기준 응답 시간 그래프&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;k6로 수집한 시계열 데이터를 InfluxDB에 넣고, InfluxDB를 Grafana와 연동하여 테스트 결과를 시각화 했다. 하긴 했는데... 속도 차이가 너무 많이 나서, 시각화가 의미가 있나? 싶은 수준이긴 하다. ㅋㅋ&lt;br&gt;&amp;nbsp;&lt;br&gt;초록색 그래프는 REST, 노란색 그래프는 gRPC고 좌측 숫자 단위는 ms이다. REST는 평균적으로 약 2.5s 정도에서 머물다가, 마지막에 20s 정도로 튄 모습이다. 반면 gRPC는 3ms 정도에서 처음부터 끝까지 아주 안정적으로 잘 버티고 있다.&lt;br&gt;&amp;nbsp;&lt;br&gt;그럼 이제 payload를 키워보면 어떻게 될까? 파싱, 직렬화 비용의 비중이 상대적으로 낮아져 REST와 gRPC의 속도 차이가 확연히 줄어들 것 같다. 그래서 해 보았다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테스트 결과 시각화2 (payload: 10B ~ 1MB)&lt;/b&gt;&lt;/h4&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1307&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpCtwF/dJMcabP2ZVX/Z3O5KcEuWQPh6oqxrInk0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpCtwF/dJMcabP2ZVX/Z3O5KcEuWQPh6oqxrInk0k/img.png&quot; data-alt=&quot;평균 응답속도 (단위: Byte)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpCtwF/dJMcabP2ZVX/Z3O5KcEuWQPh6oqxrInk0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpCtwF%2FdJMcabP2ZVX%2FZ3O5KcEuWQPh6oqxrInk0k%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;1143&quot; height=&quot;346&quot; data-origin-width=&quot;1307&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;평균 응답속도 (단위: Byte)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;payload 크기를 10B ~ 1MB까지 10배씩 늘려가며 응답속도(latency)를 확인해 보았다.&lt;br&gt;&amp;nbsp;&lt;br&gt;나는 payload가 커져도 격차는 줄어들 지언정 gRPC가 계속해서 우위일 줄 알았는데, 100KB 부분에서 REST와 응답속도가 비슷해지더니, &lt;b&gt;1MB가 되자 REST보다 2배 이상 느려지는 모습을 발견&lt;/b&gt;했다. (평균 3ms -&amp;gt; 15s 까지 상승)&lt;br&gt;&amp;nbsp;&lt;br&gt;반면 REST는 Payload크기와 무관하게 꾸준히 일정한 응답속도를 보였다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;389&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Xy5hX/dJMcabJhr03/Gt98JchDXfr9ArK6d5KkV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Xy5hX/dJMcabJhr03/Gt98JchDXfr9ArK6d5KkV1/img.png&quot; data-alt=&quot;초당 요청 처리량 (단위: 개수)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Xy5hX/dJMcabJhr03/Gt98JchDXfr9ArK6d5KkV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXy5hX%2FdJMcabJhr03%2FGt98JchDXfr9ArK6d5KkV1%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;1268&quot; height=&quot;389&quot; data-origin-width=&quot;1268&quot; data-origin-height=&quot;389&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;초당 요청 처리량 (단위: 개수)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;이번엔 &lt;b&gt;초당 요청 처리량(RPS)&lt;/b&gt;를 확인해 보았다. 노란색이 REST다! 그래프 우측 정보는 잘못 표기했다.&lt;br&gt;처리량도 마찬가지로 gRPC가 꾸준히 우위에 있다가, 100KB에서 비슷해지더니 &lt;b&gt;1MB가 되자 갑자기 곤두박질 쳤다.&lt;/b&gt; (평균 100 -&amp;gt; 15 까지 하락)&lt;br&gt;&amp;nbsp;&lt;br&gt;반면 REST는 꾸준히 80 정도의 일정한 처리량을 보인다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3A7nU/dJMb995LD59/9ktKkw3Kq8VwaAVqyIQXPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3A7nU/dJMb995LD59/9ktKkw3Kq8VwaAVqyIQXPK/img.png&quot; data-alt=&quot;총 요청 대비 드랍률&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3A7nU/dJMb995LD59/9ktKkw3Kq8VwaAVqyIQXPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3A7nU%2FdJMb995LD59%2F9ktKkw3Kq8VwaAVqyIQXPK%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;1262&quot; height=&quot;395&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;총 요청 대비 드랍률&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;이건 &lt;b&gt;총 요청 대비 드랍률&lt;/b&gt;이다.&lt;br&gt;100의 RPS로 30초 동안 요청을 보냈으니 총 3000번의 요청이 가야 하는데, 그 중에서 서버의 응답이 느렸거나 병목이 생겨 아예 보내지도 못한 요청의 비율이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;즉 grpc 1000000(1MB) 의 경우 무려 &lt;b&gt;3000개 요청 중 83.7%가 요청 전송조차 못 했다&lt;/b&gt;는 뜻이다. gRPC는 10, 100, 1000, 10000(10KB)까지는 드랍률이 0%였다가, 100KB부터 갑자기 드랍률이 REST를 상회하더니 1MB가 되자 드랍률이 하늘을 뚫어버렸다.&lt;br&gt;&amp;nbsp;&lt;br&gt;반면 REST는 payload가 커질수록 오히려 드랍률이 낮아지는 것 같이 보이기도 한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 style=&quot;text-align: center;&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;payload 크기와 무관하게 항상 gRPC의 성능이 더 좋을 것이라는 내 예상과는 달리, 100KB부터 REST와 비슷해지는가 싶더니 1MB가 되자 아예 못 쓸 정도가 되어 버렸다. 반면 REST는 10B ~ 1MB까지 일정한 성능을 보였으며, 오히려 payload가 커질수록 안정적인 모습을 보였다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;왜 payload가 커질수록 gRPC의 성능이 급감할까? 반대로, 왜 REST는 안정적일까?&lt;/b&gt;&lt;/p&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;HTTP/2 기반의 gRPC는 데이터를 작은 프레임 단위로 쪼개서 전송한다.&lt;/i&gt;&lt;br&gt;&lt;i&gt;payload가 작으면 프레임 개수도 적지만, &lt;/i&gt;&lt;i&gt;&lt;b&gt;payload가 커질수록 프레임 개수도 급증&lt;/b&gt;&lt;/i&gt;&lt;i&gt;하게 된다. 이 때, 각 &lt;/i&gt;&lt;i&gt;&lt;b&gt;프레임에 대한 오버헤드는 고정적&lt;/b&gt;&lt;/i&gt;&lt;i&gt;이기 때문에 payload가 커질수록 해당 오버헤드도 똑같이 누적되어 효율이 떨어진다.&lt;/i&gt;&lt;br&gt;&lt;i&gt;여기서 말하는 오버헤드는 흐름 제어를 위한 window size 관리, 프레임 간 우선순위 조정 등의 복잡한 메커니즘들을 포함한다.&lt;/i&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;i&gt;반면 REST는 payload 크기에 관계없이 각 요청이 독립된 TCP 세션에서 동일한 오버헤드를 가지기 때문에 항상 일정한 성능을 보인다.&lt;/i&gt;&lt;br&gt;&lt;i&gt;즉, REST가 payload가 커질수록 빨라진다기보다는, REST는 일정한 성능을 유지하는 반면 &lt;/i&gt;&lt;i&gt;&lt;b&gt;gRPC는 payload가 커짐에 따라 급격히 비효율&lt;/b&gt;&lt;/i&gt;&lt;i&gt;적이 되는 것.&lt;/i&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;i&gt;-&amp;gt; 따라서 저용량(100KB 이하) payload에서는 gRPC가, 대용량에서는 REST가 효율적이다.&lt;/i&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;==========&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;b&gt;msa-perf-lab 깃허브:&lt;/b&gt;&lt;br&gt;&lt;a href=&quot;https://github.com/YangSunkue/msa-perf-lab&quot; target=&quot;_self&quot;&gt;&lt;span&gt;https://github.com/YangSunkue/msa-perf-lab&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;==========&lt;br&gt;&amp;nbsp;&lt;br&gt;테스트도 좋고, 구현도 좋다. 다 좋은데.. Grafana 시각화에서 이렇게 애를 먹을 줄 몰랐다.&lt;br&gt;&amp;nbsp;&lt;br&gt;InfluxQL도 처음이라 익숙하지 않았고, Grafana 사용법도 아예 몰라서 내가 원하는 데이터를 원하는 방식으로 시각화하는 게 정말 너무나도 힘들었다. 특히 드랍률 데이터... k6가 직접 집계하지 않는 데이터라 총 요청량을 계산한 후 드랍개수를 총 요청량으로 나눠야 했는데 (드랍개수 / 총 요청량), 이걸 Grafana에서 구현하는게 정말 힘들어서 하루를 통째로 썼다.&lt;br&gt;&amp;nbsp;&lt;br&gt;요새는 GPT, 클로드 병행해서 써보고 있는데, GPT는 한번 막히기 시작하면 똑같은 말을 반복하거나 해결책이 아닌것을 계속 시도하게 해서 괜히 시간 낭비하게 하는 경향이 있다. 이번에도 GPT때문에 하루를 통째로 날렸고.... 너무 답답해서 클로드로 옮겼는데, 옮긴지 2시간만에 해결했다. 적어도 내가 느끼기엔, 확실히 클로드가 낫다.&lt;br&gt;&amp;nbsp;&lt;br&gt;Grafana를 활용한 시각화는 그냥 뚝딱뚝딱 하면 될 줄 알았는데, msa-perf-lab을 진행하며 가장 많은 시간을 소모했다. 그래도 한번 해 봤으니, 다음 테스트에서는 쉽게 할 수 있을 거라 믿는다.&lt;/p&gt;</description>
      <category>Development/[msa-perf-lab] Flask &amp;amp; Go MSA 성능 실험 프로젝트</category>
      <category>flask</category>
      <category>Gin</category>
      <category>go</category>
      <category>grafana</category>
      <category>gRPC</category>
      <category>influxdb</category>
      <category>MSA</category>
      <category>REST</category>
      <category>백엔드 프로젝트</category>
      <category>성능 테스트</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/360</guid>
      <comments>https://yskisking.tistory.com/360#entry360comment</comments>
      <pubDate>Fri, 7 Nov 2025 02:15:44 +0900</pubDate>
    </item>
    <item>
      <title>[msa-perf-lab] Flask &amp;lt;-&amp;gt; Go(Gin) gRPC 환경 세팅 및 내부 gRPC 통신 테스트</title>
      <link>https://yskisking.tistory.com/359</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;저번 글에서 Flask + PostgreSQL 환경 세팅 및 docker-compose 컨테이너화 까지 진행했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 Go 서버 구현은 넘어가고, Flask &amp;lt;-&amp;gt; Go gRPC 환경 세팅에 대한 내용을 다룰 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;디렉터리 구조&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;376&quot; data-origin-height=&quot;746&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Fviqd/dJMcajUPKQb/FDv64erTkadvdbj15sj6mK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Fviqd/dJMcajUPKQb/FDv64erTkadvdbj15sj6mK/img.png&quot; data-alt=&quot;flask-gateway&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Fviqd/dJMcajUPKQb/FDv64erTkadvdbj15sj6mK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFviqd%2FdJMcajUPKQb%2FFDv64erTkadvdbj15sj6mK%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;347&quot; height=&quot;688&quot; data-origin-width=&quot;376&quot; data-origin-height=&quot;746&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;flask-gateway&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;558&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCcgfN/dJMb99SdtvL/8poH1N9zAIqgPKFqpkF7J1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCcgfN/dJMb99SdtvL/8poH1N9zAIqgPKFqpkF7J1/img.png&quot; data-alt=&quot;gocore&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCcgfN/dJMb99SdtvL/8poH1N9zAIqgPKFqpkF7J1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCcgfN%2FdJMb99SdtvL%2F8poH1N9zAIqgPKFqpkF7J1%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;359&quot; height=&quot;503&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;gocore&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 디렉터리 구조를 좀 손봤다. 작은 프로젝트가 될 거라서 구조는 신경쓰지 않으려고 했는데, 플라스크 기준으로 3가지 통신 방식이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;1. Flask가 요청 받고 직접 응답 (internal)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;2. Flask가 요청 받고 Go에게 Rest로 전달 (rest)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;3. Flask가 요청 받고 Go에게 gRPC로 전달 (grpc)&lt;/i&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;그나마 다행인 건, gRPC 서버(Go)에서는 gRPC 핸들러, 라우터를 구현하지 않아도 된다는 점이었다. 핸들러, 라우터는 Rest만 사용하기에, Service만 Rest, gRPC로 구분하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Go서버: service.proto&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;952&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cAvh2v/dJMcajmZOuW/smttAUMbkJCf1KPvkB4eMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cAvh2v/dJMcajmZOuW/smttAUMbkJCf1KPvkB4eMK/img.png&quot; data-alt=&quot;service.proto&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cAvh2v/dJMcajmZOuW/smttAUMbkJCf1KPvkB4eMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcAvh2v%2FdJMcajmZOuW%2FsmttAUMbkJCf1KPvkB4eMK%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;542&quot; height=&quot;484&quot; data-origin-width=&quot;1066&quot; data-origin-height=&quot;952&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;service.proto&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;service.proto는 gRPC 통신 시 호출할 수 있는 함수를 정의해 놓은 명세서이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CoreService를 정의하고, 그 안에 Ping 함수와 요청/응답 자료형을 명시했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 PingRequest와 PingResponse는 Ping에서 사용하는 자료형을 구체적으로 정의한 것이다. 구조체 형태라고 보면 되고, =1 로 초기화 한 것은 필드 번호를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;gRPC는 JSON 형태가 아닌 프로토콜 버퍼 형태로 전달되는데, 이 때 message 라는 필드명이 날아가는 게 아니라 1 이라는 필드명으로 날아가게 되고, gRPC 클라이언트에서는 1 이라는 필드명을 보고 service.proto파일을 참조해 실제 필드명을 확인하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Go서버: ping_service_grpc.go (함수 구현체)&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1998&quot; data-origin-height=&quot;1042&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgTgLO/dJMcaj8mZfX/BfYDoRSj9FLhTuDRiiJ9K1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgTgLO/dJMcaj8mZfX/BfYDoRSj9FLhTuDRiiJ9K1/img.png&quot; data-alt=&quot;Ping 함수 구현&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgTgLO/dJMcaj8mZfX/BfYDoRSj9FLhTuDRiiJ9K1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgTgLO%2FdJMcaj8mZfX%2FBfYDoRSj9FLhTuDRiiJ9K1%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;1998&quot; height=&quot;1042&quot; data-origin-width=&quot;1998&quot; data-origin-height=&quot;1042&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Ping 함수 구현&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;service.proto에 정의한 Ping 함수를 구현한 것이다. 편리하게도(?) gRPC는 service.proto에 함수를 정의하고 이렇게 구현하기만 하면 통신이 가능하다. 라우터나 핸들러는 구현할 필요 없다. 물론 그 전에 많은 세팅을 해야 하지만 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Flask서버: gRPC 라우터 + 서비스&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;1028&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxTtTu/dJMcagqgTa6/z00vkxlYDEb5rgfsFFlb9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxTtTu/dJMcagqgTa6/z00vkxlYDEb5rgfsFFlb9k/img.png&quot; data-alt=&quot;gRPC 라우터&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxTtTu/dJMcagqgTa6/z00vkxlYDEb5rgfsFFlb9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxTtTu%2FdJMcagqgTa6%2Fz00vkxlYDEb5rgfsFFlb9k%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;671&quot; height=&quot;458&quot; data-origin-width=&quot;1506&quot; data-origin-height=&quot;1028&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;gRPC 라우터&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1584&quot; data-origin-height=&quot;960&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dI64QB/dJMcadmMmD3/vWrvzJpY6FK8BhKB9x9RO1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dI64QB/dJMcadmMmD3/vWrvzJpY6FK8BhKB9x9RO1/img.png&quot; data-alt=&quot;gRPC 서비스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dI64QB/dJMcadmMmD3/vWrvzJpY6FK8BhKB9x9RO1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdI64QB%2FdJMcadmMmD3%2FvWrvzJpY6FK8BhKB9x9RO1%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;696&quot; height=&quot;422&quot; data-origin-width=&quot;1584&quot; data-origin-height=&quot;960&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;gRPC 서비스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flask 측(gRPC 클라이언트) 에서는 이렇게 라우터 + 서비스를 구성하면 된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flask가 게이트웨이 역할을 하고, 요청을 Go서버에 위임해 처리한 후 응답한다. 구체적인 흐름은 이렇다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 요청 (Rest)&lt;b&gt; &amp;lt;-&amp;gt; &lt;/b&gt;(Rest) Flask Gateway (gRPC) &lt;b&gt;&amp;lt;-&amp;gt; &lt;/b&gt;(gRPC) go core&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 요청은 Flask 측에서 즉시 응답하고, 복잡한 연산은 gRPC로 Go에게 위임하여 결과를 받아와 응답하는 형태로 활용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;통신 테스트&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Vfp5K/dJMcaklT8hI/N7RFOvul90LDQUNMv2GkxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vfp5K/dJMcaklT8hI/N7RFOvul90LDQUNMv2GkxK/img.png&quot; data-alt=&quot;docker-compose up --build -d&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vfp5K/dJMcaklT8hI/N7RFOvul90LDQUNMv2GkxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVfp5K%2FdJMcaklT8hI%2FN7RFOvul90LDQUNMv2GkxK%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;592&quot; height=&quot;119&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;docker-compose up --build -d&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 docker compose로 그룹화 한 Flask, Go(Gin), PostgreSQL을 한 번에 띄워준다.&lt;/p&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;782&quot; data-origin-height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w4Z4V/dJMcadmMmsA/jDcyw8uMmTK7jXwLQlDpd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w4Z4V/dJMcadmMmsA/jDcyw8uMmTK7jXwLQlDpd1/img.png&quot; data-alt=&quot;전부 성공&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w4Z4V/dJMcadmMmsA/jDcyw8uMmTK7jXwLQlDpd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw4Z4V%2FdJMcadmMmsA%2FjDcyw8uMmTK7jXwLQlDpd1%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;767&quot; height=&quot;151&quot; data-origin-width=&quot;782&quot; data-origin-height=&quot;154&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;전부 성공&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3가지 통신 방식 전부 성공했다. 순서대로 설명하자면 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(R -&amp;gt; Rest, G -&amp;gt; gRPC)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;curl 127.0.0.1:5001&lt;b&gt;/internal/users:&lt;/b&gt; 사용자 (R) &amp;lt;-&amp;gt; (R) Flask 즉시 응답&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;curl 127.0.0.1:5001&lt;b&gt;/rest/ping:&lt;/b&gt; 사용자 (R) &amp;lt;-&amp;gt; (R) Flask (R) &amp;lt;-&amp;gt; (R) Go&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;curl 127.0.0.1:5001&lt;b&gt;/grpc/ping:&lt;/b&gt; 사용자 (R) &amp;lt;-&amp;gt; (R) Flask (G) &amp;lt;-&amp;gt; (G) Go&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;msa-perf-lab 깃허브:&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/YangSunkue/msa-perf-lab&quot;&gt;https://github.com/YangSunkue/msa-perf-lab&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; 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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이제 Flask + Go, Rest + gRPC 개발환경 세팅이 완전히 끝났다. 역시 환경 세팅이 가장 힘든 것 같다. 별 것 아닌 부분에서 자꾸 시간을 잡아먹을 때가 많으니 말이다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;내일부터는 msa-perf-lab 프로젝트의 본 목표인 성능 테스트를 시작하려고 한다. 가장 먼저 할 것은 Flask &amp;lt;-&amp;gt; Go 내부 통신 시 Rest와 gRPC의 속도 차이 테스트이다.&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #222222; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아마 테스트를 위해선 성능 측정 라이브러리라던가, 더미 데이터를 넣는다던가, 모니터링 또는 시각화 도구를 활용한다던가 해야 할 것 같은데, 대부분 처음 해보는 것들이라 꽤 오래 걸릴지도 모르겠다. 그래도 한 번 세팅해 두면 그 다음 실험부터는 수월하게 진행될 듯 하다.&lt;/p&gt;</description>
      <category>Development/[msa-perf-lab] Flask &amp;amp; Go MSA 성능 실험 프로젝트</category>
      <category>flask</category>
      <category>Gin</category>
      <category>go</category>
      <category>gRPC</category>
      <category>MSA</category>
      <category>Python</category>
      <category>restapi</category>
      <category>개발</category>
      <category>백엔드 프로젝트</category>
      <category>통신 프로토콜</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/359</guid>
      <comments>https://yskisking.tistory.com/359#entry359comment</comments>
      <pubDate>Mon, 3 Nov 2025 20:19:03 +0900</pubDate>
    </item>
    <item>
      <title>[msa-perf-lab] Flask &amp;amp; PostgreSQL 개발환경 세팅 및 컨테이너화, docker-compose 그룹화</title>
      <link>https://yskisking.tistory.com/358</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Flask, PostgreSQL 서버를 띄우고 연동한 후, DockerFile 작성 및 docker-compose로 그룹화했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;디렉터리 구조&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;1016&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rmMcW/dJMcacnQ7V0/XHdmnPkiNAukWxdA3CfeHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rmMcW/dJMcacnQ7V0/XHdmnPkiNAukWxdA3CfeHk/img.png&quot; data-alt=&quot;프로젝트 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rmMcW/dJMcacnQ7V0/XHdmnPkiNAukWxdA3CfeHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrmMcW%2FdJMcacnQ7V0%2FXHdmnPkiNAukWxdA3CfeHk%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;297&quot; height=&quot;533&quot; data-origin-width=&quot;566&quot; data-origin-height=&quot;1016&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로젝트 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 프로젝트는 MSA 아키텍처 및 백엔드 고급 기술들의 성능 측정이 목표이기 때문에, OOP 원칙을 철저히 준수한다거나 프로젝트 구조를 짠다거나 하는 건 전부 패스했다. 사실 코드가 그렇게 많지도 않을 것이다. 프로젝트가 마무리 되면, 디렉터리 구조를 조금 정리하려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;flask-gateway는 플라스크 서버가 저장되는데, 이름 그대로 클라이언트의 요청을 직접 받는 gateway 역할을 수행할 것이다. go-core엔 Go(Gin) 서버가 담길 것이고 이름 그대로 core engine 역할을 맡아 성능 병목이 예상되는 복잡한 연산을 맡을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;docker-compose&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;1112&quot; data-origin-height=&quot;1296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZXRRA/dJMcagKyKej/3qxLpNv3uRB9Ph1l0MVQS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZXRRA/dJMcagKyKej/3qxLpNv3uRB9Ph1l0MVQS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZXRRA/dJMcagKyKej/3qxLpNv3uRB9Ph1l0MVQS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZXRRA%2FdJMcagKyKej%2F3qxLpNv3uRB9Ph1l0MVQS0%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;585&quot; height=&quot;682&quot; data-origin-width=&quot;1112&quot; data-origin-height=&quot;1296&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;Flask, PostgreSQL은 모두 컨테이너화 했으며, docker-compose로 그룹화해 한번에 관리할 수 있도록 구성했다. Dockerfile, docker-compose 모두 처음부터 직접 짜보는 건 처음인데 그렇게 복잡하진 않은 것 같다. 도커 매우 편리하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;route.py&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;1116&quot; data-origin-height=&quot;670&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wmAve/dJMcagKyKf0/VuUiKu8epoYRjxKZZtvt3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wmAve/dJMcagKyKf0/VuUiKu8epoYRjxKZZtvt3k/img.png&quot; data-alt=&quot;route.py&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wmAve/dJMcagKyKf0/VuUiKu8epoYRjxKZZtvt3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwmAve%2FdJMcagKyKf0%2FVuUiKu8epoYRjxKZZtvt3k%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;558&quot; height=&quot;335&quot; data-origin-width=&quot;1116&quot; data-origin-height=&quot;670&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;route.py&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라우터도 정말 소소하게 구성했다. GET /users를 curl 명령어로 호출해 미리 넣어둔 데이터가 응답되는지를 확인했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가동 중인 컨테이너(2개)&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;1041&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rNQT2/dJMcaiVUzXI/cvksJ3mPUBhO0ceKRvDQlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rNQT2/dJMcaiVUzXI/cvksJ3mPUBhO0ceKRvDQlk/img.png&quot; data-alt=&quot;컨테이너 가동 중&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rNQT2/dJMcaiVUzXI/cvksJ3mPUBhO0ceKRvDQlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrNQT2%2FdJMcaiVUzXI%2FcvksJ3mPUBhO0ceKRvDQlk%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;1041&quot; height=&quot;155&quot; data-origin-width=&quot;1041&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;컨테이너 가동 중&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위가 flask, 아래가 postgreSQL 이다. docker-compose up/down으로 문제없이 올라가고 내려간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;msa-perf-lab 깃허브:&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/YangSunkue/msa-perf-lab&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/YangSunkue/msa-perf-lab&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=====&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 개발환경 세팅을 진행해 보았다. 여기까지는 익숙한 작업들이기에 금방금방 했지만, 내일부터 할 Go(Gin) 및 gRPC는 언어도 처음, 프레임워크도 처음, gRPC도 처음이다. 내일부터 조금 힘들어질 것 같지만, Go를 빨리 써보고 싶어서 설레는 부분도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인 프로젝트 &quot;썬카&quot;를 진행할 때도 그랬듯, 블로그에 프로젝트 과정을 그때그때 기록해 놓고 프로젝트가 마무리되면 포트폴리오로 옮길 예정이다. 현재 포트폴리오는 약간 장황한 느낌이 있어서, 핵심적인 것들 위주로 간결하게 수정해 보려고 한다.&lt;/p&gt;</description>
      <category>Development/[msa-perf-lab] Flask &amp;amp; Go MSA 성능 실험 프로젝트</category>
      <category>db연동</category>
      <category>docker</category>
      <category>Docker-compose</category>
      <category>flask</category>
      <category>gRPC</category>
      <category>MSA</category>
      <category>msa 아키텍처</category>
      <category>PostgreSQL</category>
      <category>Python</category>
      <category>컨테이너화</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/358</guid>
      <comments>https://yskisking.tistory.com/358#entry358comment</comments>
      <pubDate>Fri, 31 Oct 2025 18:25:13 +0900</pubDate>
    </item>
    <item>
      <title>[msa-perf-lab] MSA 성능 실험 프로젝트 - Flask &amp;amp; Go(Gin)</title>
      <link>https://yskisking.tistory.com/357</link>
      <description>&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;Flask + Go(Gin) 기반 MSA 아키텍처 성능 실험 프로젝트를 시작한다. 서비스 목적이 아닌 성능 개선 및 측정/검증 프로젝트이며 UI/UX, 도메인, 비즈니스 로직 등을 철저히 제외하고 &lt;b&gt;백엔드 고급 기술 + 성능 개선 및 측정&lt;/b&gt;에 목표를 둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로젝트 목적&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;- 이력서 &amp;amp; 포트폴리오 업그레이드 및 개인 실력 향상&lt;/p&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;- Flask &amp;amp; Go(Gin) MSA 아키텍처 설계 및 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Flask &amp;amp; Go(Gin) 서버 간 Rest/gRPC 성능 측정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Flask 단일 vs Flask &amp;amp; Go 성능 측정 (CPU 집약적 연산, 외부 API 호출, 대용량 데이터 처리 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Docker/Docker compose 활용한 컨테이너 그룹화 및 Kubernetes 연동 컨테이너 오케스트레이션&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- PostgreSQL vs MySQL 쿼리 성능 측정 (SELECT, JOIN, 서브쿼리 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- DB 인덱스 추가 전/후 성능 측정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 메시지 큐 비동기 처리 활용 전/후 클라이언트 응답속도 측정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Redis 캐싱 활용 전/후 성능 측정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Prometheus, Grafana 활용해 측정 결과 시각화&lt;/p&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;언어/프레임워크: Python/Flask, Go/Gin&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;통신 프로토콜: RestAPI + gRPC&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Database: PostgreSQL&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cache: Redis&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Message Queue: RabbitMQ or Kafka&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Infra: Docker/Docker Compose, K8s&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Monitoring: Prometheus + Grafana&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이론적으로 알고 있어도 실제 써먹어볼 일이 없었던 백엔드 고급 기술들. 써본 적 없기에 취업시장에서 어필할 수 없었고,&amp;nbsp; 내 이력서는 특별할 게 없었다. 때문에, 이번 기회에 철저히 구현, 활용, 검증을 거쳐 이력서에 추가할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단 2주 안에 완성하는 게 목표이긴 한데, 대부분 이론적으로만 알지 써본 적 없는 기술들이라 기간 안에 될 지 모르겠다. 기존 프로젝트 &quot;썬카&quot;를 고도화 할까 생각도 해 봤는데, 런칭하지도 않을 프로젝트 비즈니스 로직에 시간을 쏟는 것 보다는 진짜 &quot;기술&quot;에 집중하는 게 나을 거라고 판단했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;722&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmI6iE/dJMcaf5XeXe/lVq4XuMK1eRHZsc0W0z40K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmI6iE/dJMcaf5XeXe/lVq4XuMK1eRHZsc0W0z40K/img.png&quot; data-alt=&quot;출처: https://openupthecloud.com/cloud-engineers-code/golang/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmI6iE/dJMcaf5XeXe/lVq4XuMK1eRHZsc0W0z40K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmI6iE%2FdJMcaf5XeXe%2FlVq4XuMK1eRHZsc0W0z40K%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;708&quot; height=&quot;399&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;722&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://openupthecloud.com/cloud-engineers-code/golang/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Development/[msa-perf-lab] Flask &amp;amp; Go MSA 성능 실험 프로젝트</category>
      <category>flask</category>
      <category>Gin</category>
      <category>go</category>
      <category>golang</category>
      <category>gRPC</category>
      <category>MSA</category>
      <category>msa 아키텍처</category>
      <category>개발자 프로젝트</category>
      <category>백엔드</category>
      <category>백엔드 프로젝트</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/357</guid>
      <comments>https://yskisking.tistory.com/357#entry357comment</comments>
      <pubDate>Fri, 31 Oct 2025 18:04:28 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 브라질에 비가 내리면 스타벅스 주식을 사라: 2번 읽고 싶은 책. 매크로(거시경제 지표)투자 서적 후기 및 추천</title>
      <link>https://yskisking.tistory.com/356</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bAcFDP/dJMb9cuLBcJ/jootwCloQ0WppsHo8buBw1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bAcFDP/dJMb9cuLBcJ/jootwCloQ0WppsHo8buBw1/img.jpg&quot; data-alt=&quot;출처: https://product.kyobobook.co.kr/detail/S000001918169&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bAcFDP/dJMb9cuLBcJ/jootwCloQ0WppsHo8buBw1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbAcFDP%2FdJMb9cuLBcJ%2FjootwCloQ0WppsHo8buBw1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;458&quot; height=&quot;678&quot; data-origin-width=&quot;458&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://product.kyobobook.co.kr/detail/S000001918169&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;평점: 5/5&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도서명: 브라질에 비가 내리면 스타벅스 주식을 사라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;브라질에 비가 내리면 커피콩 수확량이 늘어난다. 따라서 커피의 주원료인 커피콩 가격이 낮아져 마진이 상승하고, 결과적으로 스타벅스 주가의 상승으로 이어질 확률이 높다. 저자는 이와 같은 간단한 예시를 통해, 이 책이 독자에게 무엇을 전달하고 싶은지를 한 줄로 설명하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 기업을 세부적으로 분석해 투자하는 방법(바텀-업)의 반대 방식인, 고용/소비/생산/주택 등 다양한 경제 지표와 정부 정책, 주식시장의 순환 등 다양한 거시적 변수들을 고려한 탑-다운 방식에 대해 중점적으로 설명해 준다. 특정 기업을 상세히 분석 후 투자하는 것은 물론 좋은 방법이지만, 업종별 특성과 거시경제의 흐름에 우선적으로, 그리고 더 많은 영향을 받는 것을 이해한다면 더 좋은 투자를 할 수 있을 것이다. &quot;나무&quot;가 아닌 &quot;숲&quot;을 보고 투자하는 방법으로써 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;고찰&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 이 책을 평가할 정량적 능력이 부족하다고 생각하고, 이 책의 20%도 이해하지 못했다고 생각한다. 그럼에도 불구하고 이 책을 읽고 난 후의 나는, 미국이 금리를 인상하면 미국 경제와 환율 등에 어떤 영향이 있을지를 자연스레 추론하고 있었고, 주택, 자동차 등 업종이 부상하기 시작하면 경제 성장 초반기에 들어선 것이며 슬슬 기술주 쪽에 강점이 올 것이다 라는 것을 예상하고 있었다. 고작 18,000원짜리 책 한권을 읽음으로써 나는 &lt;b&gt;뉴스를 보고, 업종별 주가 흐름을 보고 주식시장을 예상하기 시작&lt;/b&gt;했다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;너무나도 좋은 책이지만, 이제 막 공부를 시작한 초심자에게 추천하기엔 책의 난이도가 조금 있다. 따라서 중급자 이상, 또는 기초 경제 용어들에 대한 이해가 있는 사람에게 추천하고 싶다. 나에게는 조금 어려웠기에 매일매일 조금씩 읽어 완독했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 중간중간 가상의 인물과 상황을 예시로 들면서, 이 책의 내용이 우리의 실생활에 어떻게 적용되는지를 쉽게 알려준다. 완전히 이론적인 내용만 있었다면 &quot;그래서 어떻게 하라는 거야?&quot;라는 생각이 들었을 법도 한데, &lt;b&gt;실제로 있을 만한 상황을 들며 설명&lt;/b&gt;해 주기에 이해가 훨씬 수월했다. 이게 특히 좋았던 이유는, 거시경제를 이론적으로 알고 있다 해도 - 실제 뉴스나 정치 상황을 보며 증시를 빠르게 예상하는 것은 쉬운 일이 아니며, 반복적으로 연습해 숙달해야 하는 부분이기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, &lt;b&gt;주식이 오르내리고 요동치는 것은 우리에게 재난이 아니라 오히려 기회&lt;/b&gt;라는 새로운 시각을 얻게 해 준다. 어떤 업종이 오르고/내릴지를 거시경제 지표를 통해 예상할 수 있다면, 주가가 오르는 것만 기다리는 것이 아니라 내릴 것도 계산해서 공매도하거나, 다른 기회를 노릴 수도 있기 때문이다. 선행지표, 지행지표 등에 대해서도 설명하는데, 쉽게 말해 선행지표는&amp;nbsp; 주가에 반영되기 전에 나오는 지표이고 지행지표는 이미 주가에 반영된 지표이다. 우리는 선행지표를 활용해 증시의 흐름을 좀 더 정량적 관점에서 관찰할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 밖에 인플레이션의 종류와 어떻게 대응해야 하는지, 약세장엔 어떤 스탠스를 취해야 하는지, 매크로 투자의 기본 원칙들과 리스크 관리 방법들에 대해서도 예시를 들어 상세하게 설명해 준다. 이 책에 나온 내용을 완벽하게 이해하고 실천할 수 있다면, 그 사람은 이미 중급 이상의 투자자가 아닐까 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;거시경제는 어떤 종류의 투자를 하는 사람이든 반드시 알아야 할 지표&lt;/b&gt;라고 생각한다. 단순히 &quot;수익을 조금 더 올릴 수 있다&quot; 관점이 아니라, 강세장/약세장 상관없이 어떤 상황에서도 리스크를 줄이고, 안정적인 수익을 낼 수 있는 방법이기 때문이다. &quot;나는 운이 없었어&quot;, &quot;이번엔 시장이 좋지 않았어&quot; 같은 핑계를 대며 흐름에 휩쓸리는 게 아니라, 그 흐름을 역이용해 자신의 힘으로 만들 수 있다는 것은 투자자로서 엄청난 차별점이 될 것이다.&lt;/p&gt;</description>
      <category>독서/경제 &amp;amp; 금융 &amp;amp; 재테크</category>
      <category>거시경제 서적</category>
      <category>거시경제 지표</category>
      <category>매크로 투자</category>
      <category>브라질에 비가 내리면 스타벅스 주식을 사라</category>
      <category>인플레이션</category>
      <category>자본주의</category>
      <category>주식</category>
      <category>채권</category>
      <category>탑다운 투자</category>
      <category>투자</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/356</guid>
      <comments>https://yskisking.tistory.com/356#entry356comment</comments>
      <pubDate>Mon, 27 Oct 2025 13:08:34 +0900</pubDate>
    </item>
    <item>
      <title>웹3.0과 블록체인, 그리고 탈중앙화 금융(DeFi)</title>
      <link>https://yskisking.tistory.com/355</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qMLMV/btsQPoXf2Hn/WYqsvMw4GpiqLfPHkwfgvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qMLMV/btsQPoXf2Hn/WYqsvMw4GpiqLfPHkwfgvk/img.png&quot; data-alt=&quot;출처: https://magazine.securities.miraeasset.com/contents.php?idx=943&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qMLMV/btsQPoXf2Hn/WYqsvMw4GpiqLfPHkwfgvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqMLMV%2FbtsQPoXf2Hn%2FWYqsvMw4GpiqLfPHkwfgvk%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;748&quot; height=&quot;460&quot; data-origin-width=&quot;748&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://magazine.securities.miraeasset.com/contents.php?idx=943&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;1. 웹3.0 (Web3.0)&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;웹3.0은 블록체인 기반의 차세대 인터넷 패러다임을 의미한다. 블록체인을 통한 &lt;b&gt;탈중앙화&lt;/b&gt;(Decentralization)을 통해, 디지털 콘텐츠 자산의 소유권이 플랫폼(유튜브, 네이버 등)이 아닌 사용자에게 귀속된다. 즉, &lt;b&gt;데이터와 자산을 사용자가 직접 통제&lt;/b&gt;하는 자유로운 패러다임이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;아직 연구개발중이고 차세대 웹으로 정착한다는 확신은 없지만, 웹3.0이 실현된다면 중앙 플랫폼에 의존했던 지금까지와는 다르게,좀 더 자유롭고 신뢰성 있는 데이터들이 공유될 것이다. 수익창출 구조도 다양해질 것이며, 사용자 각각의 개성이 부여된 다양한 콘텐츠가 업로드될 것이라 생각한다. 그야말로 &lt;b&gt;혁명&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.1 웹1.0부터 웹3.0까지&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;웹1.0&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;읽기 전용&amp;nbsp; 웹, 1990년대 ~ 2000년 초반&lt;/p&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;웹2.0&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;읽기 + 쓰기 웹, 2000년대 중반 ~ 현재&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -&amp;gt; 플랫폼이 권한을 독점하고, 데이터가 수익구조가 중앙화(구글, 네이버 등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;웹3.0&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;블록체인을 통한 &lt;b&gt;탈중앙화&lt;/b&gt;(Decentralization)로 사용자 소유권을 보장한다. 데이터/콘텐츠/디지털 자산의 소유권이 플랫폼이 아닌 사용자에게 귀속되며, 스마트 컨트랙트 기반으로 &lt;b&gt;신뢰 없는 거래&lt;/b&gt;가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;i&gt;NFT -&amp;gt; 내가 올린 디지털 작품이 블록체인에 등록되어 내 소유로 인정 &lt;/i&gt;&lt;br /&gt;&lt;i&gt; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;DAO -&amp;gt; 특정 조직이 주주 대신 토큰 보유자들에 의해 운영 &lt;/i&gt;&lt;br /&gt;&lt;i&gt; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;탈중앙화&amp;nbsp;금융(DeFi)&amp;nbsp;-&amp;gt;&amp;nbsp;은행&amp;nbsp;대신&amp;nbsp;블록체인&amp;nbsp;프로토콜로&amp;nbsp;대출/예금&amp;nbsp;가능&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;2. 스마트 컨트랙트와 신뢰 없는 거래&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인에서 실행되는 스마트 컨트랙트를 통해, 기존 플랫폼/은행/업체 같은 중앙 기관을 거치치 않는 신뢰 없는 거래가 가능하다. 이는 웹3.0, DeFi 에도 핵심적인 기술이며 &lt;b&gt;블록체인의 고유한 장점이자 특성&lt;/b&gt;이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;2.1 스마트 컨트랙트(Smart Contract)&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인 위에서 &lt;b&gt;특정 조건을 만족하면 자동으로 실행되는 프로그램&lt;/b&gt;이며, 이 덕분에 계약에 대한 이행을 중앙 기관에 의존하지 않아도 된다. 예를 들어 &quot;A가 B에게 100만원을 보내면, B는 A에게 상품을 배송한다&quot;라는 조건을 코드로 등록해 두면, 조건이 충족되는 순간 자동으로 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;2.2 신뢰 없는 거래&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중앙 기관에 대한 신뢰가 요구되지 않는 거래&lt;/b&gt;이며, 스마트 컨트랙트를 통해 실현된다. 기존 방식은 쿠팡, 아마존 같은 플랫폼을 신뢰해야 하고 거길 통해야 했지만, 스마트 컨트랙트 방식은조건이 충족되면 자동으로 코드를 실행한다. 이 거래는 중간에 &lt;b&gt;누가 조작하거나 거부할 수 없으며, 블록체인에 공개&lt;/b&gt;되어 있기에 누구나 확인이 가능해 안전하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;3. DeFi&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인과 스마트 컨트랙트를 기반으로, 은행이나 증권사 같은 &lt;b&gt;중앙 금융기관 없이 이루어지는 금융 시스템&lt;/b&gt;. 대표적으로 예금, 대출, 거래, 파생상품 같은 금융 서비스를 P2P 방식으로 제공하며, 누구나 지갑만 있으면 참여할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.1 DeFi(Decentralized Finance, 탈중앙화 금융)&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 금융을 블록체인으로 재구현한 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 은행 대출 &amp;lt;-&amp;gt; 스마트 컨트랙트 대출&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 증권사에 주식 거래 &amp;lt;-&amp;gt; 탈중앙화 거래소에서 거래&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 보험회사에서 보험 가입 &amp;lt;-&amp;gt; 스마트 컨트랙트로 보험가입&lt;/i&gt;&lt;i&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지갑만 있으면 되므로 신용점수/소득증명 등 특별한 허가가 불필요하며, 모든 거래가 블록체인에 공개되고 조작이 불가하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;3.2 DeFi에서 제공될 수 있는 대표 기능들&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;스테이킹(Staking)&lt;/u&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;채권&lt;/b&gt;과 비슷한 개념이라고 이해하면 된다. 암호화폐를 일정 기간 묶어두고(락업), 유동성이 제한된다. 스테이킹은 네트워크 검증에 참여하는 행위이므로, 검증 노드의 행동에 따라 &lt;b&gt;슬래싱(벌금성 코인 소각) 위험&lt;/b&gt;도 존재한다. 이자는 신규 코인 발행 및 거래 수수료에서 충당되며, 이는 네트워크 보안성에 기여한 대가이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;커스터디(Custody)&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;암호화폐 보관 서비스이다. 내 지갑에 보관하며 개인키를 직접 관리하는 것을 셀프 커스터디라고 하며, 거래소나 전문업체에 보관하는 커스터디 서비스도 존재한다. 셀프 커스터디는 완전한 통제권을 갖지만 &lt;b&gt;개인키 분실 위험&lt;/b&gt;이 있으며, 커스터디 서비스는 편리하지만&lt;b&gt; 해킹 또는 업체 파산 위험&lt;/b&gt;이 있다. 커스터디는 단순히 코인을 보관하는 행위이므로 네트워크 보안에 기여하지 않는다. 따라서 스테이킹처럼 이자를 받을 수 없으며, 오히려 보관료를 내야 하는 경우도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;스테이블코인(Stablecoin)&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가격이 안정된 암호화폐이다. 보통 &lt;b&gt;1달러&lt;/b&gt;에 고정되며, 담보자산(달러, 국채 등)으로 &lt;b&gt;가치가 보장&lt;/b&gt;된다. 결제/송금/가치 저장에 적합하며, 기존 3~7일 걸리던 거래를 단 몇 분 만에 가능하게 하며, 24시간 거래가 가능하기에 현재도 USDT, USDC 같은 스테이블코인이 &lt;b&gt;달러 대체 수단&lt;/b&gt;으로서&amp;nbsp;널리 사용되고 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;DAI(알고리즘 스테이블코인)&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탈중앙화 알고리즘으로 가치 보존이 자동화된 스테이블코인이다. 스마트 컨트랙트 기반으로 자동으로 가격이 조절되며 가격이 오를 경우 추가발행, 내릴 경우 회수해서 소각한다. 블록체인의 &lt;b&gt;탈중앙화라는 비전에 가장 잘 맞는 암호화폐&lt;/b&gt;이지만, 담보가 다른 암호화폐이기 때문에 국채, 달러 등을 담보로 하는 타 스테이블코인보다 &lt;b&gt;위험&lt;/b&gt;하다는 논란이 있다. 탈중앙화를 원하지만 안정성을 포기하는 딜레마의 산물이다. 루나/테라 등과 원리는 비슷하지만, DAI는 &lt;b&gt;과담보&lt;/b&gt;(150%이상 담보)가 의무이기 때문에 그 정도로 위험하진 않다. 그러나 그 담보가 &lt;b&gt;암호화폐&lt;/b&gt;이기 때문에, USDT, USDC 같은 실제 담보를 가진 상품보다는 확실히 위험하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3 DeFi의 위험요소&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;1. 스마트 컨트랙트 버그&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 자체의 &lt;b&gt;오류나 보안 취약점&lt;/b&gt;이 존재할 경우, 해커가 이를 악용해 자금을 탈취하거나 영구적으로 묶일 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;2. 토큰 가격 변동성&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;담보 기반 대출의 경우, &lt;b&gt;담보 토큰의 가격이 급락&lt;/b&gt;하면 담보 가치가 부족해져 자동 청산이 발생해 손실을 입을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;3. 프로토콜 복잡성&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 프로토콜을 조합하는 경우가 많아 구조가 복잡하다. 사용자가 잘못된 지갑 주소로 전송하는 등 &lt;b&gt;잘못된 거래&lt;/b&gt;가 이루어졌을 경우, 자금을 돌이킬 수 없거나 매우 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;4. 규제 불확실성&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각국 정부가 DeFi 서비스에 대한 &lt;b&gt;규제를 강화하거나 금지&lt;/b&gt;할 수 있기 때문에, 서비스 사용이 제한될 수 있으며 이를 예상하기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;그럼에도 불구하고 DeFi가 실현되면 중개 비용 절감, 높은 접근성 및 24시간 운영, 투명성, 그리고 탈중앙화에 의한 자유로운 금융 생태계가 형성될 수 있기에 꾸준히 연구되고 있다. 리스크가 크지만, 위험 요소를 극복하고 성공적으로 실현된다면 기존 금융을 대체하는 획기적인 시스템으로 자리잡게 될 것이다.&lt;/i&gt;&lt;/p&gt;</description>
      <category>경제 &amp;amp; 금융</category>
      <category>blockchain</category>
      <category>defi</category>
      <category>P2P</category>
      <category>smart contract</category>
      <category>web3.0</category>
      <category>블록체인</category>
      <category>스마트 컨트랙트</category>
      <category>웹3.0</category>
      <category>탈중앙화</category>
      <category>탈중앙화 금융</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/355</guid>
      <comments>https://yskisking.tistory.com/355#entry355comment</comments>
      <pubDate>Thu, 25 Sep 2025 22:14:41 +0900</pubDate>
    </item>
    <item>
      <title>블록체인과 암호화폐 - 비트코인과 이더리움의 원리, PoW/PoS</title>
      <link>https://yskisking.tistory.com/354</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;300&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cYcbcG/btsQPYqgYWf/WPmc7dsremeO8wkYKhGnMK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cYcbcG/btsQPYqgYWf/WPmc7dsremeO8wkYKhGnMK/img.jpg&quot; data-alt=&quot;출처: https://www.businesspost.co.kr/BP?command=article_view&amp;amp;amp;num=413298&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cYcbcG/btsQPYqgYWf/WPmc7dsremeO8wkYKhGnMK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcYcbcG%2FbtsQPYqgYWf%2FWPmc7dsremeO8wkYKhGnMK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;300&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;300&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://www.businesspost.co.kr/BP?command=article_view&amp;amp;num=413298&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;1. 블록체인(Blockchain)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거래 기록을 &lt;b&gt;&quot;블록&quot;단위로 묶고, 다른 블록과 암호학적으로 연결&lt;/b&gt;(체인)하여 변조가 불가능하게 만든 구조. 중앙 서버가 없어도 누구나 풀 노드를 띄워서 P2P 방식으로 노드 정보 동기화 후 기록을 공유하고 검증한다. 모두가 공유하되 누구도 마음대로 바꿀 수 없는 &quot;공개 장부&quot;를 만드는 기술이며, 신뢰를 &lt;b&gt;중앙 기관이 아닌 수학적/합의적 구조로 보장&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;노드&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인 네트워크에 참여하는 모든 각 컴퓨터나 프로그램&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;풀 노드&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인 네트워크의 모든 노드들. 일반적인 서버/PC 전력만 사용하여 누구나 풀 노드를 띄울 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.1 블록체인이 중앙서버 없이 운영되는 방법&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1.2 내가 처음 풀 노드를 띄울 때, &quot;어디서&quot; 노드 정보를 받아오나?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그 어떤 피어로부터도 블록체인 데이터(원장)을 내려받을 수 있다&lt;/b&gt;. 첫 피어 접근 방식은 각 블록체인 네트워크 세부 구현 방식에 따라 다르지만, 비트코인의 경우 Bitcoin core 클라이언트 안에 DNS 주소를 하드코딩해 둠으로써 이것을 참고해 피어에 접근한다. 각 노드는 &lt;b&gt;P2P 구조&lt;/b&gt;로 이어져 있으며, 각 피어 간 블록을 주고받으며 전체 원장을 복제한다. (토렌트하고 비슷한 느낌)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;2. 비트코인(BitCoin, BTC)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중앙기관 없이 개인 간 직접 송금이 가능한 암호화폐&lt;/b&gt;. 모든 거래는 블록체인(분산원장)에 기록되고, 채굴자가 &lt;b&gt;작업증명(PoW)&lt;/b&gt;으로 블록을 추가해 보안성을 확보한다. 총 발행량은 2100만 개로 한정되어 있고, 채굴자는 블록 보상으로 새롭게 발행된 비트코인과 거래 수수료를 받는다.&lt;/p&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;PoW(Proof of Work, 작업증명)&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.1 비트코인에서 PoW가 활용되는 방식&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;1. 거래 기록 저장&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 거래가 일어나면, 해당 내역이 트랜잭션으로 네트워크에 전파. 트랜잭션은 각 노드의 메모리 풀(mempool)에 저장된다.&lt;br /&gt;- 채굴자는 원하는(일반적으로 높은 수수료) 트랜잭션을 모아서 블록을 만든다. = PoW 해시 퍼즐을 푼다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (이 때 트랜잭션 간 의존성을 고려하는 게 우선이다) &lt;br /&gt;- 해시 퍼즐을 푸는 과정은 &lt;b&gt;엄청난 비용&lt;/b&gt;이 소모된다. (비싼 장비, 전력) &lt;br /&gt;-&amp;nbsp;퍼즐을&amp;nbsp;풀고&amp;nbsp;만들어진&amp;nbsp;블록은&amp;nbsp;&quot;검증받을&amp;nbsp;준비&quot;가&amp;nbsp;된&amp;nbsp;상태다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;2. 검증&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;만들어진&amp;nbsp;블록의&amp;nbsp;거래&amp;nbsp;유효성을,&amp;nbsp;모든&amp;nbsp;풀&amp;nbsp;노드가&amp;nbsp;독립적으로&amp;nbsp;검증한다.&amp;nbsp;(진짜&amp;nbsp;코인을&amp;nbsp;가지고&amp;nbsp;있는지,&amp;nbsp;이중지불은&amp;nbsp;아닌지&amp;nbsp;등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;3.&amp;nbsp;블록&amp;nbsp;생성&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;검증을&amp;nbsp;통과한&amp;nbsp;블록은&amp;nbsp;기존&amp;nbsp;블록체인의&amp;nbsp;마지막&amp;nbsp;블록&amp;nbsp;뒤에&amp;nbsp;연결된다.&amp;nbsp;이를&amp;nbsp;&lt;b&gt;컨펌&lt;/b&gt;(Confirm)&amp;nbsp;이라&amp;nbsp;한다. &lt;br /&gt;-&amp;nbsp;이&amp;nbsp;때&amp;nbsp;새&amp;nbsp;블록은&amp;nbsp;이전&amp;nbsp;블록의&amp;nbsp;해시값을&amp;nbsp;포함하므로&amp;nbsp;블록&amp;nbsp;하나를&amp;nbsp;조작하려면&amp;nbsp;이후&amp;nbsp;모든&amp;nbsp;블록을&amp;nbsp;다시&amp;nbsp;채굴해야&amp;nbsp;한다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -&amp;gt; 조작이 사실상 불가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;4. 보상&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.2 PoW의 리오그, Orphan/stale 블록&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인은 분산 네트워크이기 때문에, 잠깐 동안은 체인이 갈라지는(Reorg) 현상이 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;u&gt;리오그(Reorg)&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨펌된 블록 순서에 대한 합의가 깨지고 블록이 재구성되는 현상. 일반적으로는 1컨펌 내에서만 발생하기 때문에, 6컨펌 이상을 신뢰의 기준으로 본다.&lt;/p&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;Orphan/stale 블록&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모가 없거나, 리오그로 인해 &lt;b&gt;메인 체인에서 제외된 블록&lt;/b&gt;이다. 두 채굴자가 동시에 블록 생성 시, 잠시 두 체인이 공존하다가 시간이 지나 더 긴 체인이 선택된다. 짧은 쪽 블록은 orphan(stale) 처리되며, 그 안의 거래는 다시 mempool로 돌아가거나 다른 블록에 재포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.3 PoW 방식의 안전성 보장 원리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- PoW 자체의 확률적 안전성과, 경제적 안전성(채굴, mining)이 공존하며, &lt;b&gt;채굴&lt;/b&gt;(mining)에 들어가는 비용이 PoW의 안전성을 보장하는 원리이다.&lt;br /&gt;- 특정 블록을 수정하려면, 이후 모든 블록을 수정해야 하기에 &lt;b&gt;사실상 조작이 불가&lt;/b&gt;하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -&amp;gt; 블록체인 네트워크는 &quot;&lt;b&gt;가장 긴 체인&lt;/b&gt;(누적 작업량 최대)&quot;를 &quot;정본&quot;으로 간주함. &lt;br /&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;/span&gt;따라서 정상 채굴자는 신규 블록만 생성하면 되는데, 공격자는 기존 블록도 같이 생성해야 해서 경쟁 뒤쳐짐&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;/span&gt;심지어 경쟁자가 너무 많아서, 51%이상의 해시파워를 갖지 않는이상 &lt;b&gt;사실상 공격 불가&lt;/b&gt; &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;/span&gt;만약 엄청난 투자금을 들여 51%이상을 얻었다고 해도, 블록 생성만으로는 투자금 복구가 어려우며 &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;/span&gt;&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;b&gt;탐지&lt;/b&gt;될&amp;nbsp;확률&amp;nbsp;높으며, &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;성공했다고&amp;nbsp;해도&amp;nbsp;이걸&amp;nbsp;매도할&amp;nbsp;때&amp;nbsp;가격이&amp;nbsp;폭락할&amp;nbsp;확률&amp;nbsp;높음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;i&gt;투자금도 많이 들고, 공격에 성공해도 이득을 볼 확률이 매우매우 낮다. 그렇게 돈 많은 양반이 굳이 공격할 이유도 없다. &lt;/i&gt;&lt;i&gt;PoS는 스테이킹 + 슬래싱 방식으로 채굴을 대체한다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2.4 어째서 PoW 방식에서는 &quot;채굴(mining)&quot;을 해야 하는가?&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트코인의 해시 풀이, 즉 채굴은 엄청난 전력을 소모하지만 이 계산 자체가 &lt;b&gt;유의미한 값을 도출하지 않는다&lt;/b&gt;. 그러나 공격자 입장에서 채굴이라는 엄청난 비용을 감내하게 함으로써, 이 &lt;b&gt;비용 자체가 공격으로부터의 보호막&lt;/b&gt;이 된다. 즉 채굴이란 것 자체는 무의미하지만, 채굴을 의무화 시키고 비용을 강제하여 보안성이 향상되는 효과를 가져온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;i&gt;그러나 현재 채굴 방식은 막대한 전력 사용으로 비판을 받아오고 있으며, 이더리움의 경우 채굴 대신 스테이킹 + 슬래싱 방식(PoS)를 채택하여 전력 소모를 줄였다.&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;3. 이더리움(Ethereum, ETH)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비트코인을 확장한 블록체인 플랫폼이며, 단순 송금 기능을 넘어 &lt;b&gt;스마트 컨트랙트&lt;/b&gt;를 실행할 수 있다는 것이 특징이다. 네트워크 수수료는 ETH로 지불하며, 발행과 소각이 동시에 이루어져 가치가 조정된다. PoS(지분증명) 으로 보안성을 확보한다.&lt;/p&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;PoS(Proof of Stake, 지분 증명)&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록체인의 합의 알고리즘 중 하나로, 참여자가 가진 &lt;b&gt;코인 지분(스테이킹 수량)에 따라 블록 생성/검증 권한을 부여&lt;/b&gt;하는 방식. 만약 생성/검증 과정에서 악의적인 행동이 검출된다면 슬래싱(slashing) 을 통해 스테이킹 금액이 일부 또는 전부 몰수된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.1 이더리움에서 PoS가 활용되는 방식&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;1.&amp;nbsp;거래&amp;nbsp;기록&amp;nbsp;저장&lt;/u&gt; &lt;br /&gt;- 거래가 일어나면, 해당 내역이 트랜잭션으로 네트워크에 전파. 트랜잭션은 각 노드의 메모리 풀(mempool)에 저장된다.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;2.&amp;nbsp;검증&lt;/u&gt; &lt;br /&gt;- 32ETH 이상을 스테이킹한 계정을 대상으로, 내부 알고리즘에 의해 랜덤으로 &lt;b&gt;제안자&lt;/b&gt;(proposer)&lt;b&gt;와 검증자&lt;/b&gt;(Attestor)를 선정한다.&lt;br /&gt;-&amp;nbsp;제안자는&amp;nbsp;블록을&amp;nbsp;만들고,&amp;nbsp;다수&amp;nbsp;검증자가&amp;nbsp;블록에&amp;nbsp;대한&amp;nbsp;&lt;b&gt;투표&lt;/b&gt;(attestation)을&amp;nbsp;진행하여&amp;nbsp;검증한다. &lt;br /&gt;&lt;br /&gt;&lt;u&gt;3.&amp;nbsp;블록&amp;nbsp;생성&lt;/u&gt; &lt;br /&gt;-&amp;nbsp;검증을&amp;nbsp;통과한&amp;nbsp;블록은&amp;nbsp;기존&amp;nbsp;블록체인의&amp;nbsp;마지막&amp;nbsp;블록&amp;nbsp;뒤에&amp;nbsp;연결된다.&amp;nbsp;이를&amp;nbsp;&lt;b&gt;컨펌&lt;/b&gt;(Confirm)&amp;nbsp;이라&amp;nbsp;한다. &lt;br /&gt;-&amp;nbsp;만약&amp;nbsp;제안/검증&amp;nbsp;과정에서&amp;nbsp;악의적인&amp;nbsp;행동(거래&amp;nbsp;조작,&amp;nbsp;이중&amp;nbsp;서명&amp;nbsp;등)이&amp;nbsp;검출된다면&amp;nbsp;슬래싱(slashing)&amp;nbsp;으로&amp;nbsp;스테이킹&amp;nbsp;금액이&amp;nbsp;&lt;b&gt;일부&amp;nbsp;또는&amp;nbsp;전부&amp;nbsp;몰수&lt;/b&gt;된다. &lt;br /&gt;&lt;br /&gt;&lt;u&gt;4. 보상&lt;/u&gt;&lt;br /&gt;-&amp;nbsp;제안자의&amp;nbsp;블록이&amp;nbsp;성공적으로&amp;nbsp;추가되면,&amp;nbsp;제안자와&amp;nbsp;검증자는&amp;nbsp;&quot;블록&amp;nbsp;보상&quot;으로&amp;nbsp;새&amp;nbsp;이더리움을&amp;nbsp;발행받고,&amp;nbsp;블록&amp;nbsp;내&amp;nbsp;트랜잭션에&amp;nbsp;대한&amp;nbsp;거래&amp;nbsp;수수료를&amp;nbsp;획득한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.2 PoS 방식의 안전성 보장 원리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- PoW의 경우, 채굴에 필요한 막대한 전력이 비용이 보호막&lt;br /&gt;-&amp;nbsp;이더리움은&amp;nbsp;제안자로&amp;nbsp;선정되기&amp;nbsp;위한&amp;nbsp;&lt;b&gt;이더리움&amp;nbsp;스테이크(ETH)에&amp;nbsp;대한&amp;nbsp;보유&amp;nbsp;강제&lt;/b&gt;와,&amp;nbsp;그에&amp;nbsp;대한&amp;nbsp;&lt;b&gt;슬래싱&lt;/b&gt;이&amp;nbsp;보호막이다. &lt;br /&gt;- 채굴과 마찬가지로, 슬래싱 비용이 막대하여 공격할 이유가 없다. &lt;b&gt;공격 효율이 나오지 않는다&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.3 이더리움의 PoW -&amp;gt; PoS 전환 이유&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;nbsp;PoW는&amp;nbsp;&lt;b&gt;막대한&amp;nbsp;전력&amp;nbsp;사용으로&amp;nbsp;비판&lt;/b&gt;을 받아왔기 때문. PoS는 PoW에 비해 전력 소모가 매우 작다.&lt;br /&gt;-&amp;nbsp;PoS의&amp;nbsp;검증자&amp;nbsp;집합이&amp;nbsp;&lt;b&gt;샤딩&amp;nbsp;설계/실현에&amp;nbsp;유리&lt;/b&gt;하기&amp;nbsp;때문&amp;nbsp;(샤딩:&amp;nbsp;블록체인을&amp;nbsp;여러&amp;nbsp;조각으로&amp;nbsp;나눠&amp;nbsp;병렬&amp;nbsp;처리하는&amp;nbsp;것) &lt;br /&gt;-&amp;nbsp;공격&amp;nbsp;비용을&amp;nbsp;전력이&amp;nbsp;아닌&amp;nbsp;ETH로&amp;nbsp;만들어&amp;nbsp;공격&amp;nbsp;비용,&amp;nbsp;&lt;b&gt;패널티를&amp;nbsp;명확&lt;/b&gt;하게&amp;nbsp;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;3.4 무한 발행인 이더리움의 가치유지 방법과 소각&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이더리움은 소각 메커니즘에 의해 가치를 유지하며, 동적으로 변하는 발행량과 소각량에 따라서 &lt;b&gt;인플레이션&amp;nbsp;또는&amp;nbsp;디플레이션&lt;/b&gt; 될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;이더리움의&amp;nbsp;발행&lt;/u&gt; &lt;br /&gt;- ETH의 발행량은 스테이킹된 ETH 규모가 클 수록 증가하며 &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;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;이더리움의&amp;nbsp;소각&lt;/u&gt; &lt;br /&gt;-&amp;nbsp;ETH는&amp;nbsp;자동으로&amp;nbsp;&lt;b&gt;기본&amp;nbsp;수수료(Base&amp;nbsp;Fee)&amp;nbsp;만큼&amp;nbsp;소각&lt;/b&gt;된다.&amp;nbsp;(EIP-1559&amp;nbsp;이후) &lt;br /&gt;- 트랜잭션(거래량)이 늘어날수록, 알고리즘에 의해 거래 당 기본 수수료(Base Fee)가 증가한다.&lt;br /&gt;-&amp;nbsp;기본&amp;nbsp;수수료&amp;nbsp;측정&amp;nbsp;알고리즘은&amp;nbsp;지수적&amp;nbsp;특징을&amp;nbsp;가져서,&amp;nbsp;&lt;b&gt;트랜잭션이&amp;nbsp;많아질수록&amp;nbsp;소각량&amp;nbsp;증가&amp;nbsp;속도가&amp;nbsp;빨라진다.&lt;/b&gt; &lt;br /&gt;-&amp;nbsp;따라서&amp;nbsp;트랜잭션이&amp;nbsp;늘어날수록&amp;nbsp;더욱&amp;nbsp;많은&amp;nbsp;ETH가&amp;nbsp;소각된다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -&amp;gt; 수요가 늘어날수록 공급이 줄어서, 가격이 폭등할 여지가 있다. &lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -&amp;gt; 그러나 공급이 줄어든다는 것은 유동성이 낮아진다는 것을 의미하며, 실거래가 어려워질 수 있다.&lt;/p&gt;</description>
      <category>경제 &amp;amp; 금융</category>
      <category>bitcoin</category>
      <category>blockchain</category>
      <category>ethereum</category>
      <category>POS</category>
      <category>POW</category>
      <category>블록체인</category>
      <category>비트코인</category>
      <category>이더리움</category>
      <category>채굴</category>
      <category>합의 알고리즘</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/354</guid>
      <comments>https://yskisking.tistory.com/354#entry354comment</comments>
      <pubDate>Thu, 25 Sep 2025 18:49:26 +0900</pubDate>
    </item>
    <item>
      <title>About &amp;amp; Contact</title>
      <link>https://yskisking.tistory.com/pages/About-Contact</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;About&amp;nbsp;&amp;amp;&amp;nbsp;Contact &lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;안녕하세요.&amp;nbsp;양선규입니다. &lt;br /&gt;&lt;br /&gt;이&amp;nbsp;블로그는&amp;nbsp;제가&amp;nbsp;공부하고&amp;nbsp;경험한&amp;nbsp;내용을&amp;nbsp;정리하고&amp;nbsp;공유하기&amp;nbsp;위해&amp;nbsp;운영하고&amp;nbsp;있습니다. &lt;br /&gt;주요 주제는 개발, 알고리즘, IT 학습 기록, 금융이며, 개인적인 공부 노트이자 다른 분들과 지식을 나누는 공간입니다. &lt;br /&gt;&lt;br /&gt;모든&amp;nbsp;글은&amp;nbsp;직접&amp;nbsp;작성한&amp;nbsp;오리지널&amp;nbsp;콘텐츠이며,&amp;nbsp;정확한&amp;nbsp;정보를&amp;nbsp;제공하기&amp;nbsp;위해&amp;nbsp;노력하고&amp;nbsp;있습니다. &lt;br /&gt;앞으로도&amp;nbsp;꾸준히&amp;nbsp;성장하는&amp;nbsp;기록을&amp;nbsp;남기겠습니다. &lt;br /&gt;&lt;br /&gt;문의하기: &lt;br /&gt;블로그와&amp;nbsp;관련된&amp;nbsp;문의사항은&amp;nbsp;아래&amp;nbsp;이메일로&amp;nbsp;연락&amp;nbsp;주시면&amp;nbsp;확인&amp;nbsp;후&amp;nbsp;답변드리겠습니다. &lt;br /&gt;&lt;br /&gt;- 이메일: ysk9526@gmail.com&lt;/p&gt;</description>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/pages/About-Contact</guid>
      <pubDate>Tue, 26 Aug 2025 16:55:37 +0900</pubDate>
    </item>
    <item>
      <title>[백준 20922 / Python / 실버1] 겹치는 건 싫어</title>
      <link>https://yskisking.tistory.com/352</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2928&quot; data-origin-height=&quot;1112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bUIAI6/btsPUeBO8oJ/vtFOhMb2fTmadkDkA1A1L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bUIAI6/btsPUeBO8oJ/vtFOhMb2fTmadkDkA1A1L1/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bUIAI6/btsPUeBO8oJ/vtFOhMb2fTmadkDkA1A1L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbUIAI6%2FbtsPUeBO8oJ%2FvtFOhMb2fTmadkDkA1A1L1%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;2928&quot; height=&quot;1112&quot; data-origin-width=&quot;2928&quot; data-origin-height=&quot;1112&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬라이딩 윈도우 or 투 포인터 문제이다. 나는 슬라이딩 윈도우가 익숙하고 더 직관적이라고 생각해서, 슬라이딩 윈도우 방식으로 풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; collections &lt;/span&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; defaultdict&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys.stdin.readline&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;최장 연속 부분 수열 길이 구하기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;같은 정수는 K개 까지 허용&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;N: 제공된 수열 길이&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;K: 같은 정수 허용 상한&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;nums: 제공된 수열&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;num_count: 각 숫자 당 개수 세는 딕셔너리, 기본값 int&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;슬라이딩 윈도우&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;딕셔너리 구조 -&amp;gt; 숫자: 개수&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;-&amp;gt; 특정 숫자가 K개가 넘었다면,&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; left는 특정 숫자 위치까지 진행하며 딕셔너리에서 값을 빼고&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; right는 right + 1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; 부분부터 다시 진행한다&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;N, K &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().split())&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;nums &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().split()))&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;num_count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; defaultdict(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;while&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;and&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; N:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; num_count[nums[right]] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; num_count[nums[right]] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; K: &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 중복 횟수 초과 시&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# left를 하나씩 올리면서 숫자당 개수 줄이기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(left, N &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; num_count[nums[i]] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; nums[i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; nums[right]:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;break&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; left) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(result, count)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(result)&lt;/span&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;N이 10만이기 때문에 완전탐색으로 진행하면 시간복잡도가 O(N^2) 이고 10만 * 10만으로 100억번 연산이 나오기 때문에 문제를 해결할 수 없다. 슬라이딩 윈도우 방식으로 하면 약 O(2N) 정도로, 즉 O(N)에 해결할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방법은 간단하다. defaultdict를 활용해서, 각 숫자 당 카운트를 저장해 두고, right를 1씩 늘려가며 숫자 당 카운트를 집계하며 동시에 count변수로 최장길이를 구한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 만약 특정 숫자 값이 K를 넘어서면, for문이 동작한다. 해당 K 위치까지 left 좌표를 1씩 올려가며, dict에서 숫자들의 카운트를 빼 준다. while문을 써도 되긴 하는데, 나는 무한루프 방어 목적으로 for문을 활용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 코드를 예로 들어 보겠다. 아래와 같은 조건에서, 굵게 표시된 곳까지 진행했고 count는 7이라고 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3 2 5 5 6 4 4&lt;/b&gt; 5 7&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;left = 0, right = 6&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 right가 1 증가하면 5의 카운트가 3이 되고, K:2 보다 커지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3 2 5 5 6 4 4&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;b&gt;&lt;span&gt; 5&lt;/span&gt;&lt;/b&gt;&amp;nbsp;7&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;left = 0, right = 7&lt;/p&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의 카운트가 초과되었으므로, left를 5 다음 자리까지 올려 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3 2 5 &lt;b&gt;5 6 4 4&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;5&lt;/span&gt;&lt;/b&gt;&amp;nbsp;7&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;left = 3, right = 7&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 K를 넘을 때마다 left를 올려 가며 right가 N에 도달할 때까지 진행해주면 된다. count는 직접 하나씩 증가시킬 필요 없이, (right - left) + 1 연산이 현재 수열 길이를 리턴하므로 이걸 활용하면 된다. 근데 사실 count 변수 없이 연산만으로도 짤 수 있긴 한데, 가독성을 위해 count 변수를 명시적으로 사용했다.&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;2884&quot; data-origin-height=&quot;475&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/p7JK9/btsPVjJkguX/kWprFaNFBe5RBLD5K2Q5Qk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/p7JK9/btsPVjJkguX/kWprFaNFBe5RBLD5K2Q5Qk/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/p7JK9/btsPVjJkguX/kWprFaNFBe5RBLD5K2Q5Qk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fp7JK9%2FbtsPVjJkguX%2FkWprFaNFBe5RBLD5K2Q5Qk%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;2884&quot; height=&quot;475&quot; data-origin-width=&quot;2884&quot; data-origin-height=&quot;475&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;푸는데 1시간 조금 넘게 걸렸다. 이젠 문제를 보고 자연스럽게 알고리즘이 떠오를 수준은 되었지만, 여전히 구현력이 부족하다. 머리속에 맴도는 해결방법을 실제 코드로 옮기는 게 아직 좀 느리다. 열심히 반복훈련 하는 수 밖에 없을 것 같다.&lt;/p&gt;</description>
      <category>Algorithm/Sliding Window</category>
      <category>sliding window</category>
      <category>개발</category>
      <category>백준</category>
      <category>백준 20922 겹치는 건 싫어</category>
      <category>백준 20922 파이썬</category>
      <category>슬라이딩 윈도우</category>
      <category>시간복잡도</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/352</guid>
      <comments>https://yskisking.tistory.com/352#entry352comment</comments>
      <pubDate>Mon, 18 Aug 2025 22:35:38 +0900</pubDate>
    </item>
    <item>
      <title>채권이란? - 채권 특징, 채권vs주식, 채권투자와 매수할 채권 선택 방법</title>
      <link>https://yskisking.tistory.com/351</link>
      <description>&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;채권이란?&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채권을 매수하다 -&amp;gt; 돈을 빌려주고 상환일까지 이자를 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채권을 매도하다 -&amp;gt; 돈을 빌리고 상환일까지 투자자에게 이자를 지급한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;채권 투자로 수익을 얻는 방법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채권 1개는 10,000원의 액면가를 가지며, 1000원 단위로 거래할 수 있다. 특정한 옵션이 없는 일반적인 채권은 발행시점에 만기일과 표면이자율이 정해지며, 이를 통해 &lt;b&gt;채권을 매수하기 전 확정수익률을 미리 계산할 수 있다.&lt;/b&gt; 투자하는 시점에 미래의 현금흐름을 확실하게 알 수 있다는 건 채권이 가지는 아주 큰 장점이다. 투자자는 그저 확정수익률이 마음에 든다면 해당 채권을 매수하고 만기일까지 &lt;b&gt;이자&lt;/b&gt;를 받기만 하면 된다. 채권 발행자가 파산하지 않는 이상, 매수시점에 계산된 수익은 확정적으로 들어온다. 수익이 확정이고 위험도도 낮기 때문에 주식처럼 반드시 분산투자를 할 필요성도 적다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 채권은 &lt;b&gt;중도 매도&lt;/b&gt;할 수 있다. 채권 가격은 금리나 회사 경영상태에 따라 계속해서 변동한다. 예를 들어 내가 10000원짜리 채권을 100장 매수했고, 100만원을 투자했다고 가정하자. 이 때 채권 가격이 11000원으로 오를 경우, 채권을 중도 매도하면 110만원을 받게 되고 10만원이라는 &lt;b&gt;매매차익&lt;/b&gt;을 얻을 수 있다. 이렇듯 채권은 이자를 받는 것 뿐만이 아니라, 운이 좋다면 중도 매도를 통해 추가수익을 챙길 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 반대로 말하면 채권 가격이 떨어질 수도 있다는 것이다. 만약 급하게 현금이 필요해 채권을 매도해야 하는데, 내가 매수했던 금액보다 현재 채권 가격이 낮다면 손해를 볼 수도 있다. 따라서 채권을 매수할 땐, 반드시 &lt;b&gt;만기일까지 보유한다는 생각&lt;/b&gt;으로 매수해야 하며, 급하게 매도해야 할 상황을 만들면 안 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 만기일까지 보유한다는 가정 하에, 회사가 파산하는 게 아닌 이상 채권 가격이 오르든 떨어지든 투자자는 채권 매수 시점에 계산된 확정수익률을 반드시 챙길 수 있기에 이것이 큰 문제는 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;세금&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채권에서 나오는 &lt;b&gt;이자는 15.4%의 이자소득세&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;채권의 종류와 신용등급&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사채는 한국의 신용평가사 3사에 의해 신용등급이 부여되며, 신용등급은 회사가 이 채권을 &lt;b&gt;만기일에 상환할 수 있는가?&lt;/b&gt; 가 기준이 된다. 회사채는 이자율이 높지만 국공채에 비해 위험도도 높다. 그러나 신용등급이 (AAA ~ BBB- ) 사이인 채권을 매수한다면 사실상 회사가 파산할 확률은 매우 낮고, 매우 낮은 위험도로 높은 이자를 챙길 수 있다. 그러나 그 미만인 투기등급 채권을 매수하는 것은 하이 리스크 하이 리턴이며, 회사에 대한 깊은 이해가 없다면 투자해선 안 될 것이다. &lt;b&gt;일반적인 개인투자자들은 주로 회사채에 투자한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;713&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uuU13/btsPUiwoQDx/PaGwb66F9VezFT99qJ5Sp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uuU13/btsPUiwoQDx/PaGwb66F9VezFT99qJ5Sp1/img.png&quot; data-alt=&quot;채권 신용등급 금리스프레드, 출처: 한국기업평가&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uuU13/btsPUiwoQDx/PaGwb66F9VezFT99qJ5Sp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuuU13%2FbtsPUiwoQDx%2FPaGwb66F9VezFT99qJ5Sp1%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;1256&quot; height=&quot;713&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;713&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;채권 신용등급 금리스프레드, 출처: 한국기업평가&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 신용등급별 금리 스프레드이다. AAA 부터 BBB-까지는 &lt;b&gt;투자등급&lt;/b&gt;으로써, 만약 회사가 파산했을 경우 국가에서 &lt;b&gt;법정관리&lt;/b&gt; 절차에 들어간다. 즉 회사 파산 위험에 대하여 투자자를 보호해주는 장치들이 존재한다. 그러나 BB+이하, 즉 &lt;b&gt;투기등급&lt;/b&gt;은 그런 절차가 없으며 회사가 파산할 경우 투자자들이 더 큰 손해를 볼 확률이 높다. 따라서 투기등급에는 웬만하면 투자하지 않는 것이 일반적으로 안전한 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 금리는 발행되는 채권에 강제되는 사항은 아니지만, 현재 시장상황을 반영해 계산된 수치이다. 채권의 표면이자율은 이 기준에 따라 조금 높거나 낮게, 또는 같게 발행된다. 회사가 채권을 빨리 팔고 싶다면 이자율을 높일 것이며, 그렇지 않다면 낮출 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;주식 vs 채권&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 주식은 확정수익률 개념이 없으며 오를지, 내릴지 정확히 예측할 수 없다. 거시경제를 살펴보고, 정부 정책을 살펴보고, 업종 상황이나 회사 상황등을 종합적으로 고려해서 오를 것 같은 주식에 투자할 수밖에 없다. 따라서 패닉매도를 하거나 심적으로 불안할 수도 있지만,&lt;b&gt; 채권에 비해 수익률이 높을 수 있다&lt;/b&gt;는 장점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복리의 효과를 톡톡히 누리고 싶은데 시장을 예측하기 어렵거나, 예측하기 위한 공부를 할 자신이 없는 사람이라면 채권에 투자하는 것이 훨씬 좋은 선택일 수 있다. 실제로 주식과 채권의 수익률을 비교해본 자료가 있는데, 채권의 수익률이 절대 적지 않다. &lt;b&gt;오히려 주식을 상회하기도 한다.&lt;/b&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;476&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgmTCs/btsPVlF6PWT/uPP5sw8MBlmWTKDJsZ27xK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgmTCs/btsPVlF6PWT/uPP5sw8MBlmWTKDJsZ27xK/img.png&quot; data-alt=&quot;주식, 채권, 부동산 수익률 비교 출처: https://h21.hani.co.kr/arti/economy/economy/21760.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgmTCs/btsPVlF6PWT/uPP5sw8MBlmWTKDJsZ27xK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgmTCs%2FbtsPVlF6PWT%2FuPP5sw8MBlmWTKDJsZ27xK%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;476&quot; height=&quot;500&quot; data-origin-width=&quot;476&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;주식, 채권, 부동산 수익률 비교 출처: https://h21.hani.co.kr/arti/economy/economy/21760.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 표에서는 주식이 채권을 상회하지만, 위 표에서는 오히려 &lt;b&gt;채권이 주식을 상회&lt;/b&gt;한다. 주식은 올라갔다 내려갔다 하지만, 채권은 떨어지지 않고 우상향 그래프만을 그린다는 점도 주목할 요소다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인이 주식에 자신이 없다면, 그리고 공부할 자신이 없다면 그냥 마음 편하게 신용등급 적절한 회사채에만 투자해도 투자자로서 중간 이상은 무조건 갈 수 있다는 것이다. 또한 투자과정에서 &lt;b&gt;불필요한 마음졸임이나 불안함&lt;/b&gt;을 가지지 않아도 된다는 것도 큰 매력 요소다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;어떤 채권을 매수해야 할까?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채권 매수시점에 확정수익률을 미리 계산할 수 있다고 했다. 우리는 &lt;b&gt;적절한 신용등급(BBB- 이상)과 마음에 드는 확정수익률을 가진 채권을 매수&lt;/b&gt;하면 된다. 이 때 추가로 살펴볼 것은 채권의 만기일(상환일)이다. 만약 앞으로 장기간 현금이 필요할 것 같지 않다면 상환일이 많이 남은 채권을 매수하면 되고, 곧 현금이 필요할 것 같다거나 잘 모르겠다면 상환일이 얼마 남지 않은 채권을 매수하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적으로 채권 자체의 가격을 고려해야 하는데, 사실 &lt;b&gt;채권 가격은 확정수익률에 이미 계산&lt;/b&gt;되어 들어가기 때문에 확정수익률만 신경쓰면 되긴 한다. 그러나 나의 목표가 채권을 상환일까지 보유하는 것이 아닌 중도 매도에 있다면, 가격이 높은 채권은 매수하지 않는 게 좋을 수 있겠다. 그러나 이런 방식은 좋지 않으며, 채권은 만기일까지 보유하는 것을 전제로 투자해야 한다. &lt;b&gt;가격이 오르고 내리고를 예측할 것이라면 채권보다는 주식&lt;/b&gt;을 하는 게 옳다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BBB- 이상 신용등급을 가진 회사가, 내가 채권을 보유한 몇 년 안에(아마 길어도 3년) 파산하여 원금을 상환하지 못할 가능성은 정말 매우 낮다. 그러나 낮다는 것이지 그럴 확률이 없다는 것은 아니다. 따라서 실제 채권을 매수하기 전, 회사 재무제표나 현재 상황 등을 정확히 파악하고 안전하다고 판단될 경우에만 매수해야 할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;text-align: center;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;채권의 옵션&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=====&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채권은 굉장히 매력적인 투자 수단이다. 주식처럼 불안해 할 필요도, 엄청난 공부를 할 필요도 없다. 안전한 회사채를 사서 만기일까지 보유하기만 한다면 누구나 쉽게 복리의 마법을 누릴 수 있으며, 1000원 단위로 매수할 수 있으니 접근성도 좋다.&lt;/p&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;</description>
      <category>경제 &amp;amp; 금융</category>
      <category>bond</category>
      <category>fixed income</category>
      <category>복리</category>
      <category>주식</category>
      <category>채권</category>
      <category>채권 수익률</category>
      <category>채권투자</category>
      <category>표면이자율</category>
      <category>확정수익률</category>
      <category>회사채</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/351</guid>
      <comments>https://yskisking.tistory.com/351#entry351comment</comments>
      <pubDate>Fri, 15 Aug 2025 18:07:22 +0900</pubDate>
    </item>
    <item>
      <title>초보자 시선으로 본 단기금융시장 - 콜, CD, RP부터 파생상품까지</title>
      <link>https://yskisking.tistory.com/350</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sNfji/btsPPCIkfNK/vvN7IYb3Yac1qmJ2gfxe7K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sNfji/btsPPCIkfNK/vvN7IYb3Yac1qmJ2gfxe7K/img.jpg&quot; data-alt=&quot;출처: https://kr.123rf.com/photo_181134885_%EA%B8%88%EC%9C%B5%EC%83%81%ED%92%88-%EC%9D%BC%EB%9F%AC%EC%8A%A4%ED%8A%B8.html&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sNfji/btsPPCIkfNK/vvN7IYb3Yac1qmJ2gfxe7K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsNfji%2FbtsPPCIkfNK%2FvvN7IYb3Yac1qmJ2gfxe7K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;606&quot; height=&quot;606&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;1280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://kr.123rf.com/photo_181134885_%EA%B8%88%EC%9C%B5%EC%83%81%ED%92%88-%EC%9D%BC%EB%9F%AC%EC%8A%A4%ED%8A%B8.html&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국엔 다양한 단기금융상품이 있다. 콜시장부터 파생상품까지, 다양한 조건으로 돈을 빌려주거나 빌리는 상품들이 존재한다. 투자하기 위해서 빌릴 수도 있을 것이고, 한국은행에 예치할 지급준비급을 맞추기 위해 빌릴 수도 있으며, 채권을 상환하기 위해 빌릴 수도 있다. 여유자금이 있다면 현금을 놀리는 것 보다는 최소한으로 보유하고, 대출을 통해 이자를 챙기는 것이 이득일 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;콜시장(Call Market)&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;지급준비제도&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 금융기관은 한국은행에 일정 비율의 자금을 항상 예치하여야 하며, 이를 &lt;b&gt;지급준비금&lt;/b&gt;이라 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 금융기관은 대출을 받아(주로 콜시장) 지급준비금을 맞추거나, 과지급준비금을 대출해줌으로써 이자를 얻는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 금융기관이 가진 자금은 매일 바뀌므로, 매일 지급준비금을 추가로 예치하거나 출금해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;콜론(Call Loan)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자금을 공급하는 것, 여유 자금을 운용하는 행위&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;콜머니(Call Money)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자금을 수요하는 것, 자금을 차입하는 행위&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;콜금리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콜거래에서 적용되는 이자율&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;통화정책 전달경로&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 콜시장은&amp;nbsp;기준금리에&amp;nbsp;&lt;b&gt;가장&amp;nbsp;먼저&amp;nbsp;영향을&amp;nbsp;받는&amp;nbsp;첫번째&amp;nbsp;시장&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 지급준비금은&amp;nbsp;주로&amp;nbsp;콜시장을&amp;nbsp;통해&amp;nbsp;조정되므로,&amp;nbsp;콜시장은&amp;nbsp;&quot;지준시장&quot;으로서&amp;nbsp;중요한&amp;nbsp;기능을&amp;nbsp;수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 한국은행이&amp;nbsp;기준금리를&amp;nbsp;인상할&amp;nbsp;경우,&amp;nbsp;콜금리&amp;nbsp;등&amp;nbsp;단기시장금리는&amp;nbsp;&quot;즉시&amp;nbsp;상승&quot;하며,&amp;nbsp;실물경제&amp;nbsp;까지&amp;nbsp;단계적으로&amp;nbsp;파급된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 한국은행은&amp;nbsp;&quot;공개시장운영&quot;을&amp;nbsp;통해&amp;nbsp;콜금리가&amp;nbsp;한국은행&amp;nbsp;기준금리에서&amp;nbsp;크게&amp;nbsp;벗어나지&amp;nbsp;않도록&amp;nbsp;유도한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;금리 전파 순서: 기준금리 -&amp;gt; 콜금리 -&amp;gt; 단기시장금리(CD, CP) -&amp;gt; 예금/대출금리 -&amp;gt; 장기금리 -&amp;gt; 실물경제&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;환매조건부매매(RP, Repo, Repurchase agreement)&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매입일(purchase date): 증권 매매가 처음 이루어지는 시점&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환매일(repurchase date): 환매가 이루어지는 시점 (매입일에 판 걸 다시 사는 것)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매입가(purchase price): 매입일의 증권 매매가격&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환매가(repurchase price): 환매일의 매매가격&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RP매도: 매입가를 수취하고 증권을 매도하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RP매수: 매입가를 지급하고 증권을 매입하는 것&lt;/p&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;RP의 이중적 성격&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;- 약정기간동안 RP 법적 소유권은 &lt;b&gt;RP 매수자&lt;/b&gt;에게 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- RP&amp;nbsp;매도자&amp;nbsp;파산&amp;nbsp;시&amp;nbsp;RP&amp;nbsp;매수자가&amp;nbsp;대상&amp;nbsp;증권을&amp;nbsp;정산할&amp;nbsp;권리&amp;nbsp;보유&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 매매거래로서의 성격을 갖는다&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경제적 실질 성격: 증권담보 대출&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 증권을 담보로 한 자금 차입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RP 매수자 = 자금 대여자 (돈 빌려주고 증권받기)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RP 매도자 = 자금 차입자 (증권 담보로 돈 빌리기)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환매가 - 매입가 차이 = 대출이자 (할인채 형태)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;증권시가 - 매입가 차이 = 초과담보(haircut)&lt;/p&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;어째서 RP는 이자 + 헤어컷 이라는 이중비용을 부과하는가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;급하게 현금이 필요한 자금수요자들은, 현금 공급자들의 이자+헤어컷이라는 불리한 조건을 받아들일 수밖에 없다. 또한 RP 매도자가 파산할 경우 RP 매수자는 담보채권을 처분해야 하는데, 금리가 상승하여 담보(채권)가치가 하락할 경우 손해를 볼수 있으므로 헤어컷으로 위험을 차단한다.&amp;nbsp;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;양도성예금증서(CD)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은행이 발행하는 정기예금증서에 양도성을 부여한 단기금융상품. 중도해지는 불가하지만 타인에게 양도 가능하다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;CD의 특징&lt;/b&gt;&lt;br /&gt;- 법적으로는 예금이지만, 실질적으론 &lt;b&gt;증권의 특성&lt;/b&gt;을 갖는다.&lt;br /&gt;- 권리 이전/행사를 위해서는 증권을 소지하여야 한다.&lt;br /&gt;- 할인채처럼 할인발행 된다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;타 단기상품이 아닌 CD를 활용하는 이유와 장점?&lt;/b&gt;&lt;br /&gt;은행&amp;nbsp;창구에서&amp;nbsp;손쉽게&amp;nbsp;발행이&amp;nbsp;가능하며,&amp;nbsp;만기일을&amp;nbsp;맞춤설정&amp;nbsp;할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;CD로&amp;nbsp;차입한&amp;nbsp;자금은&amp;nbsp;지급준비금에서&amp;nbsp;제외되어&amp;nbsp;지준&amp;nbsp;부담없이&amp;nbsp;단기자금을&amp;nbsp;빌리기&amp;nbsp;용이하다.&amp;nbsp;또한&amp;nbsp;예금자보호법에&amp;nbsp;따른&amp;nbsp;보호를&amp;nbsp;받을&amp;nbsp;수&amp;nbsp;없기에&amp;nbsp;은행의&amp;nbsp;부담이&amp;nbsp;적으며,&amp;nbsp;지급준비금,&amp;nbsp;예금보험료&amp;nbsp;부담이&amp;nbsp;없어&amp;nbsp;예금보다&amp;nbsp;높은&amp;nbsp;금리를&amp;nbsp;제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;단기사채(Short-term&amp;nbsp;Bond)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CP(기업어음)를&amp;nbsp;전자화하여&amp;nbsp;개선한&amp;nbsp;것이며,&amp;nbsp;장점은&amp;nbsp;유지하고&amp;nbsp;단점은&amp;nbsp;보완했다.&amp;nbsp;전자증권법&amp;nbsp;상&amp;nbsp;요건을&amp;nbsp;갖춘&amp;nbsp;사채권이며,&amp;nbsp;전자적으로만&amp;nbsp;발행/유통되는&amp;nbsp;단기금융상품이다.&lt;/p&gt;
&lt;p 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;- 30일 ~ 1년 단기 상환&lt;br /&gt;- 할인채처럼 할인발행 된다.&lt;br /&gt;-&amp;nbsp;채권/은행대출&amp;nbsp;대비&amp;nbsp;간편하게&amp;nbsp;발행&amp;nbsp;가능하고,&amp;nbsp;무담보,&amp;nbsp;낮은&amp;nbsp;금리를&amp;nbsp;갖는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단기사채 활용 이유?&lt;/b&gt;&lt;br /&gt;CP(기업어음)대비&amp;nbsp;안전하며&amp;nbsp;정보&amp;nbsp;공개,&amp;nbsp;즉시&amp;nbsp;결제라는&amp;nbsp;장점을&amp;nbsp;갖는다.&amp;nbsp;편리하게&amp;nbsp;급전을&amp;nbsp;마련하거나,&amp;nbsp;안전하게&amp;nbsp;단기투자할&amp;nbsp;수&amp;nbsp;있는&amp;nbsp;상품이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;통화안정증권(MSB,&amp;nbsp;Monetary&amp;nbsp;Stabilization&amp;nbsp;Bond)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한국은행이 공개시장운영을 위해 사용하는 수단 중 하나로, 유동성 조절을 위해 발행하는 채권이다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;한국은행이 통화안정증권으로 유동성을 조절하는 방식&lt;/b&gt;&lt;br /&gt;통화안정증권의 금리가 시장 금리에 비해 매력적이므로, 기업들은 통화안정증권을 매수하며 시중의 현금이 한국은행으로 빨려들어간다.&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;시중 유동성이 과다할 때 -&amp;gt; 통화안정증권 발행 (유동성 흡수)&lt;br /&gt;시중&amp;nbsp;유동성이&amp;nbsp;부족할&amp;nbsp;때&amp;nbsp;-&amp;gt;&amp;nbsp;통화안정증권&amp;nbsp;상환&amp;nbsp;(유동성&amp;nbsp;공급)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;한국은행의 공개시장운영 방식들&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;통화안정증권 (중장기, 91일 ~ 3년)&lt;/b&gt;&lt;br /&gt;발행:&amp;nbsp;유동성&amp;nbsp;흡수&amp;nbsp;(돈&amp;nbsp;회수) &lt;br /&gt;상환: 유동성 공급 (돈 풀기)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;RP(환매조건부매매) (단기, 1일 ~ 90일, 주로 1 ~ 3개월)&lt;/b&gt;&lt;br /&gt;RP 매입: 유동성 공급 (돈 풀기)&lt;br /&gt;RP&amp;nbsp;매도:&amp;nbsp;유동성&amp;nbsp;흡수&amp;nbsp;(돈&amp;nbsp;회수) &lt;br /&gt;&lt;br /&gt;&lt;b&gt;통화안정계정 (즉시, 초단기)&lt;/b&gt;&lt;br /&gt;금융기관이 자발적으로 돈을 맡기도록 하는 한국은행 상품. 금리를 조절함으로써 유동성을 조절한다.&lt;br /&gt;금리 높임: 유동성 흡수 -&amp;gt; 금융기관들이 자발적으로 돈 맡김&lt;br /&gt;금리 낮춤: 유동성 공급 -&amp;gt; 금융기관들이 돈 빼고 다른곳에 투자함&lt;br /&gt;&lt;br /&gt;&lt;b&gt;왜 여러가지 방식이 있는가?&lt;/b&gt;&lt;br /&gt;통화안정증권,&amp;nbsp;RP,&amp;nbsp;통화안정계정은&amp;nbsp;각각&amp;nbsp;중장기,&amp;nbsp;단기,&amp;nbsp;초단기의&amp;nbsp;&lt;b&gt;각각&amp;nbsp;다른&amp;nbsp;시간축&lt;/b&gt;을&amp;nbsp;가지며,&amp;nbsp;현재&amp;nbsp;시장&amp;nbsp;상황에&amp;nbsp;따라&amp;nbsp;각&amp;nbsp;방식을&amp;nbsp;적절히&amp;nbsp;활용하여&amp;nbsp;유동성을&amp;nbsp;조절한다.&amp;nbsp;중장기적&amp;nbsp;조절이&amp;nbsp;필요하다면&amp;nbsp;통화안정증권을,&amp;nbsp;갑작스럽게&amp;nbsp;현금이&amp;nbsp;많이&amp;nbsp;풀렸다면&amp;nbsp;통화안정계정으로&amp;nbsp;빠른&amp;nbsp;조치를&amp;nbsp;하는&amp;nbsp;방식이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;자산유동화증권(ABS, Asset-Backed Securities)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유동성이&amp;nbsp;낮은&amp;nbsp;자산(주택담보대출,&amp;nbsp;매출채권,&amp;nbsp;부동산&amp;nbsp;등)을&amp;nbsp;현금화&amp;nbsp;가능한&amp;nbsp;증권으로&amp;nbsp;바꾸는&amp;nbsp;기법 &lt;br /&gt;&lt;br /&gt;&lt;b&gt;ABS 작동 원리&lt;/b&gt;&lt;br /&gt;1. 자산보유자(은행, 기업 등)가 특수목적법인(SPC)에 자산을 매각한다.&lt;br /&gt;2. SPC가 이 자산을 담보로 증권을 발행한다.&lt;br /&gt;3. 투자자들이 증권을 구매한다.&lt;br /&gt;4. 기초자산(담보)에서 나오는 현금흐름으로 투자자에게 원리금을 상환한다.&lt;br /&gt;-&amp;gt; 자산보유자는 자산을 매각하여 즉시 현금을 얻고, 투자자들은 자산에서 나오는 원리금을 챙길 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SPC(Special Purpose Company, 특수목적회사)&lt;/b&gt;&lt;br /&gt;- 자산 현금화를 위한 &lt;b&gt;껍데기 회사&lt;/b&gt;. SPC는 오직 ABS 작업만을 위해 설립된다.&lt;br /&gt;- 자산을 현금화하려는 은행이나 기업이 주도하여 만든다.&lt;br /&gt;-&amp;nbsp;SPC는&amp;nbsp;ABS를&amp;nbsp;한&amp;nbsp;번만&amp;nbsp;발행할&amp;nbsp;수&amp;nbsp;있으므로,&amp;nbsp;자산유동화가&amp;nbsp;발생할&amp;nbsp;때마다&amp;nbsp;별도의&amp;nbsp;SPC를&amp;nbsp;설립해야&amp;nbsp;한다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;SPC를 설립하여 ABS를 발행하면 이득을 얻는 사람들&lt;/b&gt;&lt;br /&gt;- 은행(자산보유자)은 자산 현금화, 규제 회피&lt;br /&gt;- 증권회사는 SPC 설립 수수료, 증권 발행/판매 수수료&lt;br /&gt;- 법무법인은 SPC 설립/운영대행 수수료&lt;br /&gt;- 신용평가회사는 ABS 신용등급 평가 수수료&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;금리선물&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재의 금리를 고정하여, 미래 특정일의 금리에 베팅한다. 쉽게 말하자면 금리가 오를지, 말지에 거는 도박 같은 상품이다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;금리선물 특징&lt;/b&gt;&lt;br /&gt;- &lt;b&gt;레버리지 투자&lt;/b&gt;이며, 저비용으로 빠르고 확실하게 리스크관리가 가능하다.&lt;br /&gt;- 실제로 거래하는 것은 &quot;채권&quot;이지만, 베팅은 &quot;미래 특정일의 금리&quot;에 한다.&lt;br /&gt;&lt;br /&gt;금리가 오르면 -&amp;gt; 채권 및 선물가격 하락&lt;br /&gt;금리가 내리면 -&amp;gt; 채권 및 선물가격 상승&lt;br /&gt;금리선물&amp;nbsp;매수&amp;nbsp;-&amp;gt;&amp;nbsp;금리&amp;nbsp;하락에&amp;nbsp;베팅하는&amp;nbsp;것&amp;nbsp;-&amp;gt;&amp;nbsp;고정금리는&amp;nbsp;금리&amp;nbsp;내려가면&amp;nbsp;이득&amp;nbsp;-&amp;gt;&amp;nbsp;매수&amp;nbsp;표현 &lt;br /&gt;금리선물 매도 -&amp;gt; 금리 상승에 베팅하는 것 -&amp;gt; 고정금리는 금리 올라가면 손해 -&amp;gt; 매도 표현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;금리선물&amp;nbsp;매수는&amp;nbsp;금리&amp;nbsp;하락에&amp;nbsp;베팅,&amp;nbsp;매도는&amp;nbsp;금리&amp;nbsp;상승에&amp;nbsp;베팅한다는&amp;nbsp;표현이다.&amp;nbsp;실제&amp;nbsp;매수,&amp;nbsp;매도의&amp;nbsp;의미가&amp;nbsp;아니다.&lt;/i&gt; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;증거금&lt;/b&gt;&lt;br /&gt;- 금리선물은 레버리지 투자이며, 총 계약가치의 일정 비율 증거금(2~5%)을 내면 운용할 수 있다.&lt;br /&gt;- 일일 정산으로 계약가치와 증거금이 변동되며, 증거금이 부족해지면 추가납입, 늘어나면 환급받을 수 있다.&lt;br /&gt;- 증거금을 채우지 못하면 &lt;b&gt;강제청산&lt;/b&gt;된다.&lt;br /&gt;- 실제 투자 금액(증거금)의 수십배를 얻거나, 잃을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;i&gt;ex)&amp;nbsp;50만원&amp;nbsp;증거금,&amp;nbsp;1000만원&amp;nbsp;계약가치&amp;nbsp;-&amp;gt;&amp;nbsp;50%&amp;nbsp;손해일&amp;nbsp;때&amp;nbsp;원금&amp;nbsp;500만원&amp;nbsp;손해&amp;nbsp;-&amp;gt;&amp;nbsp;50만원만&amp;nbsp;냈지만&amp;nbsp;25만원의&amp;nbsp;20배&amp;nbsp;손해 &lt;/i&gt;&lt;br /&gt;&lt;i&gt;ex)&amp;nbsp;50만원&amp;nbsp;증거금,&amp;nbsp;1000만원&amp;nbsp;계약가치&amp;nbsp;-&amp;gt;&amp;nbsp;50%&amp;nbsp;이득일&amp;nbsp;때&amp;nbsp;원금&amp;nbsp;500만원&amp;nbsp;이득&amp;nbsp;-&amp;gt;&amp;nbsp;50만원만&amp;nbsp;냈지만&amp;nbsp;25만원의&amp;nbsp;20배&amp;nbsp;이득&lt;/i&gt; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;금리선물은 어디에 활용되는가?&lt;/b&gt;&lt;br /&gt;은행,&amp;nbsp;금융기관이&amp;nbsp;금리&amp;nbsp;&lt;b&gt;리스크를&amp;nbsp;헷지&lt;/b&gt;하기&amp;nbsp;위해&amp;nbsp;주로&amp;nbsp;활용한다.&amp;nbsp;예를&amp;nbsp;들어&amp;nbsp;채권을&amp;nbsp;많이&amp;nbsp;보유했는데&amp;nbsp;금리가&amp;nbsp;상승할&amp;nbsp;것&amp;nbsp;같다면&amp;nbsp;금리선물&amp;nbsp;매도를&amp;nbsp;통해&amp;nbsp;채권에서&amp;nbsp;본&amp;nbsp;손해를&amp;nbsp;금리선물로&amp;nbsp;헷지하여&amp;nbsp;리스크를&amp;nbsp;관리한다.&amp;nbsp;그러나&amp;nbsp;레버리지&amp;nbsp;투자이기&amp;nbsp;때문에&amp;nbsp;&lt;b&gt;도박,&amp;nbsp;투기&lt;/b&gt;로도&amp;nbsp;활용될&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;위험도가&amp;nbsp;높은&amp;nbsp;상품이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;통화스왑(Currency Swap, CRS)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서로 다른 통화의 원금 + 이자지금 의무를 교환하며, 만기 시 원금을 재교환하여 원상복구한다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;통화스왑 특징&lt;/b&gt;&lt;br /&gt;- 국내에서는 주로 달러 변동금리와 원화 고정금리를 교환하게 된다.&lt;br /&gt;- 원금 교환은 선택사항이며, 이자지급 의무만 교환해도 된다.&lt;br /&gt;- 환위험/금리위험을 헷지할 수 있다.&lt;br /&gt;- 필요한 통화자금을 쉽게 조달할 수 있다.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;변동금리(달러) 고정금리(원화) 스왑이 공평한 이유?&lt;/b&gt;&lt;br /&gt;변동금리,&amp;nbsp;고정금리&amp;nbsp;모두&amp;nbsp;시장&amp;nbsp;상황에&amp;nbsp;따라&amp;nbsp;이득/손해인&amp;nbsp;상황이&amp;nbsp;있을&amp;nbsp;수&amp;nbsp;있으며,&amp;nbsp;애초에&amp;nbsp;원화&amp;nbsp;고정금리를&amp;nbsp;결정할&amp;nbsp;때&amp;nbsp;달러의&amp;nbsp;미래&amp;nbsp;변동금리&amp;nbsp;예측값과&amp;nbsp;최대한&amp;nbsp;비슷하도록&amp;nbsp;구조를&amp;nbsp;만든다.&amp;nbsp;결과적으론&amp;nbsp;거의&amp;nbsp;공평한&amp;nbsp;거래가&amp;nbsp;된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;=====&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단기금융시장은 일상에서 직접 접하기 어렵지만, 경제의 중심축이 되는 중요한 역할을 한다. 각각의 상품은 돈을 빌려주고 이자를 받거나, 돈을 빌리고 이자를 낸다는 기본 원리에서 다양한 조건들이 붙어 생긴 상품들이며 상환일, 세부조건 등의 차이가 있지만 결국 원리는 비슷하다. 이는 단기금융상품 뿐만이 아니라 대부분의 금융상품에 적용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기준금리가 상승하면 콜시장이 가장 먼저 영향을 받고 이어서 실물경제에까지 전파되는 원리와, 한국은행이 어떻게 공개시장운영을 통해 유동성을 조절하는지를 이해하고, 나아가 정부의 정책이 경제에 어떤 영향을 미치는지를 생각해 보면 더욱 도움이 될 듯 하다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 금융 상품의 원리는 같고, 경제는 확실한 근거에 의해 돌아간다. 입문은 어렵겠으나 원리를 제대로 이해하고 나면 자연스럽게 뉴스를 보고 주식시장이 어떨지 채권은 어떨지, 어디에 투자해야 할 지 등이 연쇄적으로 떠올려질 듯 하다.&lt;/p&gt;</description>
      <category>경제 &amp;amp; 금융</category>
      <category>abs</category>
      <category>cd</category>
      <category>CP</category>
      <category>RP</category>
      <category>경제</category>
      <category>금리</category>
      <category>금리선물</category>
      <category>금융</category>
      <category>단기금융상품</category>
      <category>콜시장</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/350</guid>
      <comments>https://yskisking.tistory.com/350#entry350comment</comments>
      <pubDate>Tue, 12 Aug 2025 09:40:02 +0900</pubDate>
    </item>
    <item>
      <title>개인정보처리방침 및 이용약관</title>
      <link>https://yskisking.tistory.com/pages/%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4%EC%B2%98%EB%A6%AC%EB%B0%A9%EC%B9%A8-%EB%B0%8F-%EC%9D%B4%EC%9A%A9%EC%95%BD%EA%B4%80</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. 개인정보처리방침&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 블로그(이하 &quot;사이트&quot;)는 개인정보보호법 제30조에 따라 이용자의 개인정보를 보호하고 이와 관련한 고충을 신속하고 원활하게 처리할 수 있도록 하기 위하여 다음과 같이 개인정보처리방침을 수립&amp;middot;공개합니다.&lt;/p&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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;본 블로그는 회원가입, 상담, 서비스 신청 등을 위해 개인정보를 직접 수집하지 않습니다.&lt;/li&gt;
&lt;li&gt;Google AdSense 광고 서비스 제공을 위해 다음 정보가 자동으로 수집될 수 있습니다:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쿠키(Cookie) 정보&lt;/li&gt;
&lt;li&gt;접속 IP 주소&lt;/li&gt;
&lt;li&gt;서비스 이용 기록, 접속 로그&lt;/li&gt;
&lt;li&gt;기기 정보 (OS, 브라우저 버전 등)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&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;/li&gt;
&lt;li&gt;쿠키 정보는 브라우저 종료 시 또는 사용자가 직접 삭제할 때까지 보유됩니다.&lt;/li&gt;
&lt;li&gt;접속 로그는 통계 분석 목적으로 최대 1년간 보관 후 삭제됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p 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-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;본 블로그는 이용자의 개인정보를 원칙적으로 외부에 제공하지 않습니다.&lt;/li&gt;
&lt;li&gt;단, Google AdSense 서비스 이용에 따라 Google의 개인정보처리방침이 적용될 수 있습니다.&lt;/li&gt;
&lt;li&gt;자세한 내용: &lt;a href=&quot;https://policies.google.com/privacy&quot;&gt;Google 개인정보처리방침&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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;/li&gt;
&lt;li&gt;개인정보 처리정지 요구 등의 권리를 행사하고자 하실 경우 아래 연락처로 문의해주시기 바랍니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;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;&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;/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;&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;/li&gt;
&lt;li&gt;게시된 정보의 정확성, 신뢰성, 적법성에 대해 보증하지 않으며, 이로 인한 직간접적 손해에 대해 책임을 지지 않습니다.&lt;/li&gt;
&lt;li&gt;외부 링크 사이트의 내용에 대해서는 해당 블로그가 책임집니다.&lt;/li&gt;
&lt;li&gt;특히 투자 및 금융 관련 정보는 참고용이며, 투자 결정은 본인 책임입니다.&lt;/li&gt;
&lt;li&gt;투자로 인한 손실에 대해 어떠한 책임도 지지 않습니다.&lt;/li&gt;
&lt;/ul&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;/li&gt;
&lt;li&gt;중요한 변경사항이 있을 경우 사전 공지하도록 노력합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. 문의 및 연락처&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;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;연락처: ysk9526@gmail.com&lt;/li&gt;
&lt;/ul&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;/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;&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;접수된 문의는 영업일 기준 7일 이내에 답변드리도록 노력합니다.&lt;/li&gt;
&lt;li&gt;개인정보 관련 문의는 우선적으로 처리됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&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;시행일자: 2025년 8월 5일&lt;/li&gt;
&lt;li&gt;최종 수정일: 2025년 8월 5일&lt;/li&gt;
&lt;li&gt;본 처리방침은 시행일자부터 적용되며, 법령 및 방침에 따른 변경내용의 추가, 삭제 및 정정이 있는 경우에는 변경사항의 시행 7일 전부터 공지사항을 통하여 고지할 것입니다.&lt;/li&gt;
&lt;/ul&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;/li&gt;
&lt;li&gt;정보통신망 이용촉진 및 정보보호 등에 관한 법률&lt;/li&gt;
&lt;li&gt;통신비밀보호법&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/pages/%EA%B0%9C%EC%9D%B8%EC%A0%95%EB%B3%B4%EC%B2%98%EB%A6%AC%EB%B0%A9%EC%B9%A8-%EB%B0%8F-%EC%9D%B4%EC%9A%A9%EC%95%BD%EA%B4%80</guid>
      <pubDate>Tue, 5 Aug 2025 22:59:14 +0900</pubDate>
    </item>
    <item>
      <title>[독후감] 채권투자 처음공부: 채권투자 입문서 후기, 채권 입문서 추천</title>
      <link>https://yskisking.tistory.com/348</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_20250804_212228554.jpg&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;1264&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pqe9P/btsPF9fI89Y/tj6yYoTC3pkBgzRqVcOi61/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pqe9P/btsPF9fI89Y/tj6yYoTC3pkBgzRqVcOi61/img.jpg&quot; data-alt=&quot;채권투자 처음공부&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pqe9P/btsPF9fI89Y/tj6yYoTC3pkBgzRqVcOi61/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpqe9P%2FbtsPF9fI89Y%2Ftj6yYoTC3pkBgzRqVcOi61%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;492&quot; height=&quot;600&quot; data-filename=&quot;KakaoTalk_20250804_212228554.jpg&quot; data-origin-width=&quot;1036&quot; data-origin-height=&quot;1264&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;채권투자 처음공부&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;평점: 4/5&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도서명: 채권투자 처음공부&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;국부론&quot;을 읽다가 취업준비에 밀려 멈추고, 금융권에 취업을 하게되어 빠르게 관련 지식을 얻고싶은 마음에 구매한 책이다. 국부론은 앞 부분 조금만 읽었음에도 큰 도움이 되었지만, 읽는 데 시간이 너무 오래 걸리고 지금의 나에겐 조금 더 직관적이고 빠르게 활용할 수 있는 정보가 필요했으니 나중에 읽는 걸로 하기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==========&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 아주 조금 신경 쓰이는 부분은 반복되는 문장이 좀 있다는 점인데, 그 내용이라 함은 &quot;채권투자는 만기까지 보유하는 것을 기본으로 전제하고 투자해야 하며, 그걸 지킨다면 항상 충분한 확정수익률을 챙기며 예상치 못한 손해를 막고, 금리변동으로 인한 채권가격 상승 시 중도매도를 통해 추가 수익을 얻을 수 있다&quot; 인데, 이 내용이 책 전체적으로 여러번 반복된다. 그러나 이 개념은 채권투자의 핵심이고 아주 중요한 개념이라고 생각하기에, 여러번 반복해 강조 효과를 주려는 의도라고 생각하면 문제될 부분은 아니라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 저자는 기본적으로 &quot;안전한 투자&quot;를 권한다. 내 생각에 채권의 가장 큰 장점은 안전성이고, 주식과 차별되는 가장 큰 장점이니만큼 안전한 투자를 강조하는 건 전혀 문제 없다고 생각한다. 다만 본인의 투자성향에 따라 &quot;왜 안전한 투자만 권하지?&quot; 라고 생각할 수도 있을 것 같은데, 나는 저자에게 전적으로 동의하는 입장이다. 미래를 예측할 것이라면 채권이 아니라 주식을 해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 채권의 기본 개념, 여러가지 채권의 종류, 채권투자의 장점과 위험성 등을 모두 다루며, 책만 따라해도 독자가 실제로 채권에 투자할 수 있도록 아주 상세한 가이드를 제공한다. HTS를 통한 실제 채권 거래 방법, HTS 세부 사용법, 확정수익률 계산법 등 책만 보고 따라해도 당장 채권에 투자할 수 있을 정도로 상세하게 제공하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채권과 채권투자에 처음 관심이 생긴 초보자라면 이 책으로 시작하는 것은 전혀 문제가 없다고 생각되며, 매우 추천한다. 분량도 300페이지 정도이고 과하게 어려운 내용이 없어, 충분한 채권 지식을 부담없이 습득할 수 있다. &lt;b&gt;채권 투자 입문서라는 요지에 맞게 매우 잘 구성된 책&lt;/b&gt;이라고 평가한다.&lt;/p&gt;</description>
      <category>독서/경제 &amp;amp; 금융 &amp;amp; 재테크</category>
      <category>경제 도서</category>
      <category>복리</category>
      <category>제태크</category>
      <category>채권</category>
      <category>채권 도서</category>
      <category>채권 입문서</category>
      <category>채권투자</category>
      <category>채권투자 입문서</category>
      <category>채권투자 처음공부</category>
      <category>투자</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/348</guid>
      <comments>https://yskisking.tistory.com/348#entry348comment</comments>
      <pubDate>Mon, 4 Aug 2025 21:41:37 +0900</pubDate>
    </item>
    <item>
      <title>[백준 2075 / Java / 실버3] N번째 큰 수</title>
      <link>https://yskisking.tistory.com/347</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2913&quot; data-origin-height=&quot;1499&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmasbG/btsPxXMZwZy/Rz36cNOhKvEzfnTTypHpE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmasbG/btsPxXMZwZy/Rz36cNOhKvEzfnTTypHpE0/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmasbG/btsPxXMZwZy/Rz36cNOhKvEzfnTTypHpE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmasbG%2FbtsPxXMZwZy%2FRz36cNOhKvEzfnTTypHpE0%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;2913&quot; height=&quot;1499&quot; data-origin-width=&quot;2913&quot; data-origin-height=&quot;1499&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자료구조, 정렬 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리 제한이 걸려 있긴 한데, 메모리를 신경쓰지 않아도 풀리긴 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;난 3가지 방식으로 풀어보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753353685928&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.*;


public class N번째_큰_수_2075 {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		int N = Integer.parseInt(br.readLine());
		int[] table = new int[N*N];
		
		/** 숫자를 하나의 배열로 전부 입력받기 */
		int idx = 0;
		for (int i = 0; i &amp;lt; N; i++) {
			st = new StringTokenizer(br.readLine());
			
			for (int j = 0; j &amp;lt; N; j++) {
				table[idx] = Integer.parseInt(st.nextToken());
				idx++;
			}
		}
		Arrays.sort(table);  // 오름차순 정렬
		
		/** N번째로 큰 수 출력 */
		System.out.println(table[table.length - N]);
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 첫번째 방식, 기본 배열 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간복잡도는 O(N^2logN) 이며, 가장 단순하고 직관적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N*N 크기 하나의 배열에 모든 값을 넣고, 정렬한 후 인덱싱으로 N번째 큰 수를 찾는다. 여기서 &quot;정렬&quot;이 가장 큰 오버헤드를 차지한다. 정렬은 NlogN인데 N^2크기의 배열에 대해서 진행하니까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딱히 복잡한 로직이 없고, 솔직히 이 방식은 너무 간단해서 브론즈 정도로 내려도 될 정도이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753353806087&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.*;


public class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		int N = Integer.parseInt(br.readLine());
		
		/** 우선순위 큐 사용 */
		PriorityQueue&amp;lt;Integer&amp;gt; maxPq = new PriorityQueue&amp;lt;&amp;gt;(Collections.reverseOrder());
		for (int i = 0; i &amp;lt; N; i++) {
			st = new StringTokenizer(br.readLine());
			
			for (int j = 0; j &amp;lt; N; j++) {
				int value = Integer.parseInt(st.nextToken());
				maxPq.offer(value);
			}
		}
		
		/** N번째 큰 수 추출 */
		int result = -1;
		for (int i = 0; i &amp;lt; N; i++) {
			result = maxPq.poll();
		}
		
		System.out.println(result);
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 방식, 우선순위 큐를 활용한 방식이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간복잡도는 기본 배열 방식과 마찬가지로 O(N^2logN) 이다. 일단 메모리는 조금 더 썼지만 시간은 거의 절반으로 줄어들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선순위 큐 방식의 주요 오버헤드는 최대힙 &quot;삽입&quot;연산에서 일어난다. 매 삽입마다 logN 인데, 이게 N^2번 진행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 표면적 시간복잡도는 기본 배열 방식과 같다. 그런데 왜 시간 차이가 이렇게 많이 나나 찾아보니, 기본 배열 방식에서 사용한 Arrays.sort() 메서드가 배열 크기가 커질수록 내부 구조 상 오버헤드가 더 크기 때문이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753353991227&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.*;


public class N번째_큰_수_2075_v2 {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		int N = Integer.parseInt(br.readLine());
		
		/**
		 * 우선순위 큐 사용 (최소 힙)
		 * 
		 * - N^2개 숫자 중 가장 큰 N개의 요소만 힙에 저장
		 * - 힙에 저장된 값 중 가장 작은 값이 N번째 큰 수
		 */
		PriorityQueue&amp;lt;Integer&amp;gt; pq = new PriorityQueue&amp;lt;&amp;gt;();
		for (int i = 0; i &amp;lt; N; i++) {
			st = new StringTokenizer(br.readLine());
			
			for (int j = 0; j &amp;lt; N; j++) {
				int value = Integer.parseInt(st.nextToken());
				
				// N개까지 우선적으로 저장
				if (pq.size() &amp;lt; N) {
					pq.offer(value);
				}
				// 큐 최소값과 value 비교해서 큰 값을 저장
				else if (pq.peek() &amp;lt; value) {
					pq.poll();
					pq.offer(value);
				}
			}
		}
		
		/** 가장 큰 N개의 수 중, 가장 작은 값이 N번째로 큰 값이다 */
		System.out.println(pq.peek());
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 방식, 우선순위 큐를 활용한 최소힙 최적화 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;표면적 시간복잡도는 위 2개 방식과 같다. O(N^2logN) 이다.&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;배열 방식: O(N^2log(N^2)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최대힙 방식: O(N^2log(N^2)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최소힙 최적화: O(N^2logN)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차이가 발생하는 부분은 최소 힙에 저장된 데이터 개수이다. 최적화 방식은 N개만 저장하고, N에 대한 logN 삽입이 일어나지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지 2개 방식은 N^2개를 저장하고 N^2에 대한 logN^2 삽입이 일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 최소힙 최적화 방식은, &quot;공간복잡도&quot; 측면에서 N^2 -&amp;gt; N 으로 개선된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나.. 실제 제출 시 최소힙 방식은 메모리 사용량은 개선되었으나 &lt;b&gt;시간복잡도는 거의 비슷한 수준&lt;/b&gt;을 유지했다. 그 이유는 조건문 비교 연산 때문이다. 최대힙 방식은 조건검사 없이 무조건 offer만 하면 되지만, 최소힙 방식은 if, else if 조건 검사해서 poll, offer 여러 연산을 거치기 때문이다. 이 방식은 데이터 크기가 커질 수록 효율적인 방법이라고 생각되며, 이 문제에서는 엄청난 성능 차이를 거두진 못 했다.&lt;/p&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;2902&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djStR0/btsPyEsq9bw/cheLPcD2xD6uDmbAdaE8OK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djStR0/btsPyEsq9bw/cheLPcD2xD6uDmbAdaE8OK/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djStR0/btsPyEsq9bw/cheLPcD2xD6uDmbAdaE8OK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjStR0%2FbtsPyEsq9bw%2FcheLPcD2xD6uDmbAdaE8OK%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;2902&quot; height=&quot;489&quot; data-origin-width=&quot;2902&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 아래부터 배열 방식, 최대힙 방식, 최소힙 최적화 방식이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 방식인 배열과 마지막 방식인 최소힙 최적화 방식을 비교해 보면, 메모리 사용량과 시간 모두 단축된 것을 알 수 있다.&lt;/p&gt;</description>
      <category>Algorithm/Priority Queue</category>
      <category>java</category>
      <category>Priority Queue</category>
      <category>개발</category>
      <category>백준 2075 Java</category>
      <category>백준 2075 N번째 큰 수</category>
      <category>백준 2075 자바</category>
      <category>알고리즘</category>
      <category>우선순위 큐</category>
      <category>자바</category>
      <category>코딩테스트</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/347</guid>
      <comments>https://yskisking.tistory.com/347#entry347comment</comments>
      <pubDate>Thu, 24 Jul 2025 20:02:25 +0900</pubDate>
    </item>
    <item>
      <title>개발자 취업준비 6개월, KIDB 최종 합격 후기와 금융권 선택 이유 + 포트폴리오</title>
      <link>https://yskisking.tistory.com/346</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;메멘토 AI 3개월 근무 중 폐업에 의해 퇴직하고, 6개월의 취업준비를 거친 후에 드디어 재취업을 했다. 3개월이라는 근무 경험이 있긴 하지만 경력으로 인정받을 정도는 아니기 때문에, 사실상 신입과 큰 차이는 없다.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;KIDB 채용연계형 인턴 합격&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KIDB는 금융중개업 회사로서, &lt;b&gt;채권중개/자금중개 업계 1위&lt;/b&gt;의 인지도를 지키고 있는 근본 있는 회사이다. 나는 자산 증식에 관심이 많아 핀테크 또는 돈을 다루는 도메인에 가고 싶었는데, 결국 순도 100%의 금융권에 오게 되었다. 개발과 더불어 금융에 대한 지식까지 배울 수 있다는 게 큰 메리트다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;전형은 서류 -&amp;gt; 1차면접 -&amp;gt; 2차면접 순으로 진행되었으며, 기술적인 질문보다는 &lt;b&gt;인성/태도&lt;/b&gt; 부분을 주의깊게 보시는 듯 했다. 그걸 빠르게 캐치하고 최대한 겸손하고 예의바른 모습을 보인 것이 내 합격의 이유 아니었을까.. 싶다. 그냥 개인적인 생각이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;1차면접&lt;/b&gt;&lt;br /&gt;1차면접은 시간이 부족하고 면접관4 면접자4 였기 때문에 많은 질문을 받진 못 했지만, 그것과 별개로 면접의 느낌이 굉장히 좋았다. 금융권은 보수적인 문화라는 선입견에 지레 겁을 먹고 갔는데, 면접관님들이 분위기를 굉장히 편하게 해 주셨다. 다들 인상도 좋으셨고, 뭔가 다들 여유가 넘치는 느낌. 1차면접 종료 후 KIDB라는 회사에 대한 호감도가 2배는 올라간 것 같다. 면접자들이 긴장할까 봐 면접 대기시간에 계속 신경써 주시는 분들도 계셨고, 심지어 면접비까지 주셔서.. 회사에 대한 신뢰도, 호감도가 급상승했다. 1차면접 후 이 회사에 꼭 붙고 싶다는 생각이 강하게 들었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;2차면접&lt;/b&gt;&lt;br /&gt;1차면접 결과는 2일 뒤에 문자로 통보되었다. 1차면접 때 기술적인 질문이 많이 나오지 않았던 터라, 난 2차면접은 기술 집중 면접일 줄 알았지만 &lt;b&gt;인성 집중 면접&lt;/b&gt;이었다. 면접관4 면접자3 이었고 좀더 높으신 임원분들이 들어오셨다. 면접 준비할 때 나는 약 80개정도의 상세한 기술질문을 준비해 갔는데, 인성 면접이었기 때문에 거의 써먹질 못 해서 아주 조금 아쉽긴 했다. 하지만 그렇다고 나에게 안 좋은 게 아니었다. 오히려 내가 자신 있는 부분은 인성 면접이었기 때문이다. 인성질문은 자기소개, 지원동기를 제외하고 단 하나도 준비하지 않았지만, &lt;b&gt;솔직하게 가감없이&lt;/b&gt; 평소 내 마인드, 생각대로 말씀드렸다. 매우 긴장되긴 했지만, 뭔가 나의 속내를 털어놓을 수 있는 자리이기도 해서 약간 재미있기도 했다. 내 마인드를 좋게 봐 주실까? 가 궁금하기도 했고. 결과적으로는 붙었고, 좋게 봐주신 것 같아 너무나 감사할 따름이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;합격&lt;/b&gt;&lt;br /&gt;2차면접 후 결과는 &lt;b&gt;바로 다음날 오전에 전화로 통보&lt;/b&gt;되었다. 서류합격, 1차면접 합격때의 기분도 너무나 좋았지만, 전화로 받는 최종합격 통보는 비교도 안 될 만큼 나를 행복하게 했다. 출근일까지는 약 2주정도의 시간이 있어, 여유롭게 준비할 수 있는 점도 좋았다.&lt;br /&gt;2차면접 때 슬쩍 들은 건데, 이번 채용전형에 &lt;b&gt;300명&lt;/b&gt;이 넘는 지원자가 몰렸다고 한다. 당연히 많을 거라 생각은 했지만 직접 들으니 현재 채용시장이 더 실감되었다. 내가 300명 중에 제일 잘 나서 뽑힌 거라고는 절대 생각 안 한다. 그저 꾸준히 열심히 준비했고, 이번 전형에서 운이 조금 좋아 뽑혔을 뿐이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;물론 3개월 근무 후 정규직으로 전환될지는 아직 미지수이다. 그러나 KIDB는 안정적인 회사이고, 면접에서 함께 오래 일할 사람을 원한다고 하셨기 때문에 말 그대로 &quot;채용 연계&quot;, 즉 채용이 &quot;전제&quot;되었다고 생각한다. 또한 난 당연하게도 열심히 일할 것이고, 특별히 문제를 일으키지 않는다면 정규직으로 전환되지 않을까.. 바래본다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;현재 취업 시장은 IMF 때보다도 닫혀있고, 쟁쟁한 경쟁자도 많은데 내가 합격하게 된 것에 감사한다. 물론 한 치의 부끄럼 없이 열심히 준비해오긴 했지만, 노력한다고 해서 항상 결과가 따라오는 건 아니니까 말이다. 심지어 내가 정보보안에서 개발로 전향하며, 그때부터 간절하게 바라왔던 목표 연봉도 달성할 수 있을 것 같아서, 찝찝하거나 아쉬움이 전혀 없는 성공적인 취업이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;취업 준비&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;메멘토AI에서 퇴사한 1월 8일 이후로, 약 &lt;b&gt;6개월&lt;/b&gt;간 취업준비를 했다. 사실 1월은 좀 설렁설렁 했고.. 2월부터 본격적으로 코테 및 개인 프로젝트 &quot;썬카&quot;를 진행하면서 취준을 시작했다. 첫 직장이었던 메멘토AI는, 제대로 준비도 안 하고 이력서 처음 넣은곳에 운 좋게 덜컥 붙었던 것이라서 취준의 끔찍함을 전혀 몰랐다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;개인 프로젝트 썬카&lt;/b&gt;&lt;br /&gt;난 &lt;b&gt;Java Spring&lt;/b&gt; 쪽으로 취업하고 싶었다. 어떤 프레임워크를 사용하던 근본 원리는 같다고 하지만, Spring을 고향으로 삼았을 때 다른 프레임워크에 적응하기가 가장 쉽다고 생각했기 때문이다. 물론 점유율도 매우 높고. 하지만 제대로 된 Spring 프로젝트를 한 적이 없었다. 그래서 개인 프로젝트 &quot;썬카&quot;를 시작했다. CSR + RestAPI 방식으로 할 지 SSR MVC 패턴 방식으로 할지 고민했는데, 실무에서는 전자가 더 많이 활용되기 때문에 Vue.js를 독학해서 RestAPI 방식으로 진행했다. 물론, 백엔드 쪽에 웬만한 로직을 다 넣었고 프론트엔드는 흐름 정도만 파악하려고 했다. 프론트엔드까지 깊게 파기엔 나에게 남은 시간은 많지 않았다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;취업을 위한 포트폴리오였기 때문에 비즈니스나 사용자 관점은 생각하지 않았다. 오로지 백엔드의 &lt;b&gt;설계 능력, 확장성, 유지보수성, 효율적인 로직과 쿼리&lt;/b&gt; 이런 것들만 신경썼다. 그래서 약 3개월간 진행된 썬카 프로젝트는 차량 등록, 조회 기능밖에 없다. 그러나 사용자 입장에서 활용할 수 있는 기능이 아닌, 내부적인 탄탄한 구조를 만들고 프론트엔드에게 다루기 쉬운 데이터를 주는 것이 백엔드의 본질이라 생각했기에 찜찜함은 없었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;클로드를 적극적으로 활용했다. 개인 프로젝트로 모든 설계와 기능을 직접 구현하는 건 처음이었기에 처음부터 완벽한 형태로 구현하는 것이 목적이었다. 그래서 기능 하나를 만들 때마다, 뭔가를 설계할 때마다 클로드에게 전체적인 구현 흐름을 물어본 후 특별히 비효율적이거나 이해되지 않는 부분이 있는지 검토했고, 조목조목 따진 후 내가 납득할 수 있는 형태의 흐름을 만든 후 하나하나 직접 입력하며 코드를 이해했다. 난 서비스를 만드는 게 아니라 포트폴리오를 만드는 것이기 때문에 빠른 개발은 중요하지 않았다. 말하자면 &quot;공부&quot; 였다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;다들 알겠지만, 한번 만들어 봤다고 해서 그게 전부 내 것이 되지는 않는다. 그래서 난 큼직한 기능 하나를 만들 때 마다 그 과정을 전부 블로그에 기록했다. 기능 하나 만드는 데 2일 걸렸다고 하면 &lt;b&gt;블로그 글 쓰는데만 거의 하루&lt;/b&gt;가 걸렸다. 시간이 아깝다는 생각도 들었지만, 이렇게 하지 않으면 다 까먹을 게 뻔했기에 기록을 빼놓지 않았다. 결과적으로, 포트폴리오를 작성하는 시점에 나는 프로젝트 상세 구현내용이 거의 기억나지 않았고, 내가 쓴 글들을 전부 하나하나 읽고 다시 이해한 후 포트폴리오를 작성할 수 있었다. &lt;b&gt;기록하지 않았다면 내 포트폴리오는 백지&lt;/b&gt;였을 것이다. 또한 기록이란 것은 기록하는 시점에서 한번 더 복습과 더불어 내 지식의 맹점을 파악할 수 있으며, 훗날 다시 읽었을 때 마치 어제 구현했던 것처럼 기억이 생생하게 떠오른다. 기록을 하는 것과 안 하는 것은 습득력과 장기기억 관점에서 최소 3배의 차이가 난다고 개인적으로 생각한다. 반드시 구현 직후에 기록해야 한다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;아래는 내 포트폴리오 주소다. 내가 디자인엔 재능이 없어 투박하고 분량이 많다. 약 48페이지 정도이다. 당연히 &lt;b&gt;포폴 길이를 줄이라는 말&lt;/b&gt;을 수십번도 더 들었다. 하지만 그건 &quot;무의미한 내용&quot;을&amp;nbsp; 채워넣어 분량만 늘린 포트폴리오에 해당되는 말이다. 난 모든 개발 과정이 블로그에 상세하게 기록되어 있고, 개발 당시 내가 트러블 슈팅 하면서 든 생각까지 전부 기억하고 있다. 그러니까 분량이 많을 수 밖에 없다. &lt;b&gt;포트폴리오는 나의 개발에 대한 철학, 개발 당시의 의도, 느낀 점, 생각의 흐름 같은 개발자로서의 모든 사고 과정을 최대한 상세히 담아놔야 한다고 생각한다.&lt;/b&gt; 사람마다 관점이 다를 수 있겠지만, 이력서만 간결하게 쓰고 포트폴리오는 상세히 쓰는 게 옳다는 게 내 생각이다. 물론!! 무의미한 텍스트로 분량만 늘리면 안 된다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;양선규 포트폴리오 - (개인 사정에 의해 임시비공개 합니다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;포트폴리오 작성 당시, 참고할 자료가 정말 없더라. 다른 취준생들이 만든 날것의 포트폴리오를 최대한 많이 보고 싶었는데, 공개된 자료가 거의 없었다. 지금 그때의 나와 마찬가지로 답답해 하는 사람들을 위해, 내 포트폴리오를 공개한다. 이건 절대 정답이 아니고 많이 부족하다고 생각하지만, 완벽한 자료만 올릴 것이었다면 개인 블로그가 아니라 수익화 할 수 있는 컨설팅 사이트에 올렸으리라.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;b&gt;본격적인 취업 시도&lt;/b&gt;&lt;br /&gt;5월 말쯤부터 본격적으로 이력서를 제출했다. 나의 목표는 &lt;b&gt;연봉4000&lt;/b&gt; 이었고, 이 목표를 달성할 수 있을 것 같이 보이는 회사라면 도메인에 상관없이 지원했다. 웹 백엔드, 서버, 게임서버, 인프라, 클라우드, DevOps, 핀테크, 금융, 블록체인, AI 등 가릴 것 없이 말이다. 대기업, 중견기업, 스타트업, 중소기업 전부 오로지 연봉이 맞다면 전부 지원했다. 결과는 어떻게 되었을까?&lt;br /&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;1441&quot; data-origin-height=&quot;874&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eBRcjg/btsPuDAQpTY/KRcnZnDKmtftXRwyyD0SjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eBRcjg/btsPuDAQpTY/KRcnZnDKmtftXRwyyD0SjK/img.png&quot; data-alt=&quot;처참한 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eBRcjg/btsPuDAQpTY/KRcnZnDKmtftXRwyyD0SjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeBRcjg%2FbtsPuDAQpTY%2FKRcnZnDKmtftXRwyyD0SjK%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;1441&quot; height=&quot;874&quot; data-origin-width=&quot;1441&quot; data-origin-height=&quot;874&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;처참한 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;결과적으로 난 최종 &lt;b&gt;60개&lt;/b&gt;의 서류를 지원했다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;서류합격(2): 카카오, KIDB&lt;br /&gt;서류탈락(58): 그 외 전부&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;서류 합격률: 3.3%&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br /&gt;솔직히 4000정도는 나 정도면 쉽게 달성하지 않을까? 생각했었다. 근데 그건 나의 오만이었고..^^ 정말 뭐 넣는 곳 마다 다 떨어지니, 초반엔 좀 괜찮았지만 점점 멘탈이 갈려갔다. 처음엔 결과 통보 메일을 두근두근 하면서 열었다면, 후반으로 갈 수록 정말 아무런 기대도 하지 않고 눌렀고, 역시나 서류탈락인 것을 보고 노션을 수정할 뿐이었다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그래서 카카오 서류 붙었을 때 어이가 없었다. 대체 왜..? 어째서? 전산 오류인가, 싶기도 했다. 나 카카오 개발자 되는건가? 라는 기대감이 무색하게 코딩테스트에서 떨어졌다. 어렵더라. 3문제를 1시간 반 안에 풀었어야 했는데, 난이도 자체가 엄청 어렵다기보다 시간이 너무너무 부족했다. 면접 정도는 보고 싶었는데, 굉장히 아쉬웠다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그러나 무의미하지는 않았다. 카카오 서류가 붙었다는 건, 적어도 &lt;b&gt;내 역량이 문제는 아니라는 것&lt;/b&gt;이니까. 채용하려는 회사에 비해 지원자가 너무나도 많아서 힘든 것 뿐이지, 내 역량이 부족한 건 아니라는 방증이었다. 그래서 이 때 자신감을 좀 얻었다. 그리고 다른 취준생 분들도, 본인의 역량이 부족한 게 아니라 그저 개발자 수요와 공급이 너무나도 맞지 않기 때문이란 걸 인지하고 포기하지 않았으면 좋겠다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그래서 난 KIDB가 첫 면접이었고, &lt;b&gt;첫 면접에서 바로 취업에 성공&lt;/b&gt;했다. 지금 시장 특성상 서류합격률은 매우 끔찍하지만, 서류만 붙으면 면접에선 꽤 가능성이 높다고 생각한다. 실제로 취업에 성공한 사람들 대부분이 나와 비슷하게, 대부분의 서류에 떨어지다가 면접 한두번 보고 취업한 경우가 많은 걸로 알고 있다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;음 그리고.. KIDB라는 회사와 나의 역량의 핏이 잘 맞았다고 생각한다. 금융권이니만큼 정보보안이 매우 중요하고, Spring, JSP로 풀스택 개발과 배포/운영 등 모든 IT 업무를 다 하는 직무 특성상 나와 딱 맞았다. 난 정보보안 전공에다가 과거 보안을 중점으로 공부했었고, 메멘토AI에서는 인프라와 DB관리 업무를 맡았으며, 개인 프로젝트에서는 풀스택 개발까지 해봤으니까. 한마디로 이것저것 다 할줄은 아는데 깊이는 부족한, 느낌이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;컴퓨터공학 전공해서 Spring 백엔드만 판 사람과 나의 백엔드 역량이 비교가 될까? 뭐 비교는 돼도 당연히 내가 부족하겠지. 다른 회사들은 나의 이런 넓은 역량 보다 백엔드 역량의 깊이가 더 중요했다면, KIDB는 정보보안 역량과 넓은 지식이 중요했기에 내가 합격했다고 생각한다. 자신의 장점이 무엇인지, 능력이 무엇인지 잘 파악하고 그것에 맞는 회사에 지원하고 잘 어필하는 게 정말 중요한 것 같다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&lt;i&gt;다들 할 수 있다. 정말 힘들겠지만 자신을 믿고, 꾸준히 발전하고, 꾸준히 도전하자.&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;======&lt;br /&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;금융권 선택의 이유&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 돈을 많이 벌고 싶다. 내 목표는 &lt;b&gt;벤틀리&lt;/b&gt;를 타는 것이다.&lt;br /&gt;정확히는 벤틀리를 끌어도 문제없는 재력을 소유하고, 그에 걸맞는 명예를 얻은 후, 벤틀리라는 자동차를 소유함으로써 증명하는 것이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;금융권의 개발 문화는 상대적으로 보수적이기에, 레거시 코드가 많고 최신 기술을 접할 기회가 적다. 망 분리 환경이며, 자유로운 개발은 제한될 수 있다. 이것은 &lt;b&gt;분명한 단점&lt;/b&gt;이다.&lt;br /&gt;그러나 반대로, 금융권만의 보안, 견고함, 안정성은 그 어디를 가서도 배울 수 없다. 또한 기술의 성장은 더디지만 급여가 높고 워라밸이 좋다. 이것은 &lt;b&gt;분명한 장점&lt;/b&gt;이다.&lt;br /&gt;금융권과 비금융권의 장단점은 명확하다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;금융권은 &lt;b&gt;개발자의 무덤&lt;/b&gt;이라는 말을 최근에 많이 들었다. 그 이유는 기술의 성장이 정체되는 것 이라고 한다.&lt;br /&gt;음.. 뭐 틀린 말은 아닌 것 같다. 개발자로 일하는 이유가, 더 멋진 개발을 하기 위해서라면 말이다. 나도 최신기술로, 더 멋진 개발을 하고싶은 욕심이 없지는 않다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;그러나 내 1순위 목표는 &quot;돈&quot;이다. &lt;b&gt;개발은 &quot;돈&quot;을 벌기 위한 수단&lt;/b&gt;이다. 개발에 정이 많이 들었지만, 그렇다고 1순위가 변하진 않는다.&lt;br /&gt;나는 왜 개발자로 일을 하는가? 돈을 많이 벌기 위해서이다. 기술이 정체되는 것은 상관없다. 돈을 많이 벌 수 있다면.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;금융 도메인 지식은 매우 소중하다. 금융 도메인을 가진 개발자는 많지 않으며, 이것은 기술만으로 대체되기 어렵다. 금융권 개발자는 분명한 가치를 지닌다. 처우도 네카라쿠배, 대기업 부럽지 않다. 이직은 금융권 내에서 하면 문제 없으며, 워라밸도 상대적으로 좋다. 그래서 다른 개발자들이 야근할 때, 자기계발에 투자할 시간까지 확보된다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;남는 시간은 어떻게 활용할 수 있는가? 이 시간엔 자유롭게 자기계발을 할 수 있으며, 추가적인 &lt;b&gt;부수입&lt;/b&gt;을 창출할 수 있고(패시브인컴), &lt;b&gt;투자 및 제태크&lt;/b&gt; 공부를 할 수 있고, &lt;b&gt;좋은 투자처&lt;/b&gt;를 알아볼 수 있다. 여기에 일하면서 배운 금융 도메인 지식까지 있으니 더 수월할 것이다. 부자 중에 수입원이 1개인 사람은 없다. 그 수입원을 늘리기 위해 시간은 반드시 필요하다. &quot;시간&quot; 이라는 것은, 우리가 부자가 되기 위해 가장 중요한 자산이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;사람마다 지향점은 다르기에, 기술의 발전을 원하는 사람은 금융권을 기피할 수도 있다. 그러나 &quot;개발을 위한 개발&quot;이 아닌 &quot;돈을 위한 개발&quot;을 하는 사람이라면, 오히려 훨씬 매력적인 선택이라고 생각한다. 개발자로서 죽으면 어떠한가?(사실 죽는 것 까지도 아니다) &lt;b&gt;그 외의 내 인생 전체가 사는데 말이다.&lt;/b&gt; 정말로 개발을 즐긴다면, 취미로라도 개발하면 될 일이다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;내가 굳이 이런 말을 쓰는 것은 &quot;개발자의 무덤&quot; 이라는 키워드에 갇혀 스스로 선택지를 좁히는 사람이 없길 바라서이고, &lt;b&gt;나도 비슷한 고민&lt;/b&gt;을 했었기 때문이다. 개인의 지향점에 따라, 충분히 매력적인 선택이라는 걸 말하고 싶다. 타인의 시선에 흔들리지 말고 소신있는 선택을 하자.&lt;/p&gt;</description>
      <category>업적</category>
      <category>KIDB</category>
      <category>개발자 취업</category>
      <category>개발자 취업 후기</category>
      <category>개발자 취업준비</category>
      <category>개발자 포트폴리오</category>
      <category>금융권 개발자</category>
      <category>금융권 취업</category>
      <category>백엔드</category>
      <category>서류합격률</category>
      <category>정보보안</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/346</guid>
      <comments>https://yskisking.tistory.com/346#entry346comment</comments>
      <pubDate>Wed, 23 Jul 2025 03:27:01 +0900</pubDate>
    </item>
    <item>
      <title>[백준 2304 / Java / 실버2] 창고 다각형</title>
      <link>https://yskisking.tistory.com/345</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2933&quot; data-origin-height=&quot;1493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bTPUSt/btsPurNJ526/bjglD7Dr5JaGkya8mJTa2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bTPUSt/btsPurNJ526/bjglD7Dr5JaGkya8mJTa2k/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bTPUSt/btsPurNJ526/bjglD7Dr5JaGkya8mJTa2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbTPUSt%2FbtsPurNJ526%2FbjglD7Dr5JaGkya8mJTa2k%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;2933&quot; height=&quot;1493&quot; data-origin-width=&quot;2933&quot; data-origin-height=&quot;1493&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 문제를 보고,&amp;nbsp; 이분탐색인가? 그리디인가? 어떤 알고리즘이지? 고민했는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 그냥 구현이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1753172840700&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.*;

public class 창고_다각형_2304 {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;
		
		/**
		 * 가장 작은 창고 면적 구하기
		 * 한번 내려가면 다시 올라오면 안된다
		 * 
		 * 올라가기: 기존 높이로 쭉 진행하며, 높은 걸 만날때마다 올라간다
		 * 내려가기: 가장 높은 곳에 도달했다면, 내려갈 준비를 한다
		 *     1. 남은 기둥 중 가장 높은 높이로 내려간 후 해당 기둥까지 진행한다
		 *     2. 남은 기둥이 없다면 종료한다.
		 */
		
		int N = Integer.parseInt(br.readLine());
		
		/** 기둥들 입력받기 */
		int[][] columns = new int[N][2];
		for (int i = 0; i &amp;lt; N; i++) {
			
			st = new StringTokenizer(br.readLine());
			int location;
			int height;
			
			location = Integer.parseInt(st.nextToken());
			height = Integer.parseInt(st.nextToken());
			
			// [위치, 높이, 인덱스]
			columns[i] = new int[] {location, height, i};
		}
		Arrays.sort(columns, (a, b) -&amp;gt; a[0] - b[0]);  // 위치 순서대로 기둥 정렬
		
		/** 기둥이 1개라면 즉시 종료 */
		if (N == 1) {
			System.out.println(columns[0][1]);
		}
		
		/**
		 * 올라갈때: 기둥높이 * 다음기둥까지의 거리 = 면적
		 * 최고점 왔을때: 올라갈때 값에 추가로 현재기둥높이 더한 후, 내려가기 로직으로 전환
		 * 내려갈때: 다음기둥 없으면 그대로 종료, 있으면 다음기둥높이 * 다음기둥까지의 거리
		 */
		else {
			
			int[] highestColumn = findHighestColumn(columns, 0);  // 최고높이 컬럼(전환점)
			int[] prev = columns[0];  // 이전 기둥
			int result = 0;  // 결과 면적
			
			/** 올라갈 때 */
			for (int i = 1; i &amp;lt; N; i++) {
				
				// 최고 높이 기둥 만났을 경우, 면적 더하고 내려가기 로직으로 전환
				if (columns[i][0] == highestColumn[0]) {
					result += prev[1] * (columns[i][0] - prev[0]);
					result += columns[i][1];  // 최고기둥 자체 높이 추가로 더해야 함
					break;
				}
				
				// 높은 기둥 만났을 경우 면적 더하기
				else if (columns[i][1] &amp;gt;= prev[1]) {
					result += prev[1] * (columns[i][0] - prev[0]);
					prev = new int[] {columns[i][0], columns[i][1], i};
				}
			}
			
			/** 내려갈 때 */
			prev = highestColumn;
			int[] nextColumn = findHighestColumn(columns, prev[2] + 1);
			while (nextColumn != null) {
				
				result += nextColumn[1] * (nextColumn[0] - prev[0]);
				prev = nextColumn;
				nextColumn = findHighestColumn(columns, prev[2] + 1);  // 다음 기둥이 존재하면 계속 내려가기
			}
			System.out.println(result);
		}
	}
	
	/** 지정된 인덱스부터 끝까지 탐색하여, 가장 높은 기둥 정보(위치, 높이, 인덱스)를 리턴하는 함수 */
	private static int[] findHighestColumn(int[][] arr, int idx) {
		
		/** 남은 기둥이 없다면 null 리턴 */
		if (idx &amp;gt;= arr.length) {
			return null;
		}
		
		// 위치, 높이, 인덱스
		int highestColumn[] = new int[] {0, 0, 0};
		for (int i = idx; i &amp;lt; arr.length; i++) {
			
			if (arr[i][1] &amp;gt;= highestColumn[1]) {
				highestColumn[0] = arr[i][0];
				highestColumn[1] = arr[i][1];
				highestColumn[2] = i;
			}
		}
		return highestColumn;
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면적을 계산하는 로직을 파악한 후, 그대로 구현했다. 딱히 대단한 알고리즘은 사용하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N이 최대 1000이라, N^2 복잡도로 구현한다고 해도 100만번 연산이라 매우 여유롭다. 실제로 내 코드도 O(N^2) 이다. findHighestColumn이 한번 호출 당 N의 복잡도를 갖기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, 최고점 기둥을 파악해야 한다. 최고점 기둥을 기준으로 적용되는 로직이 바뀐다. 올라가는 로직, 내려가는 로직을 분리해서 처리해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최고점 기둥을 만날 때 까지, 기둥 순서대로 진행하며 더 높은 기둥을 만나면 해당 높이로 무조건 올라간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최고점 기둥을 만나면, 해당 부분까지만 면적을 구해놓은 후 내려가는 로직으로 전환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내려가는 로직에서는, findHighestColumn 함수를 이용해 남은 기둥 중 가장 높은 기둥을 찾고, 해당 기둥까지의 면적을 계산한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 while문으로 진행하기 때문에 다음 기둥이 없다면 자동으로 루프는 종료되며,&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;구현이다 보니까 여러 데이터를 복잡하게 관리해야 하고 실수할 부분이 많아 좀 헤맸다. 코드 작성 후 이게 풀릴까? 싶은 마음으로 제출해 봤는데 한번에 맞았고..(물론 IDE에서 디버깅은 거침) 다른 사람들 코드도 참고해본 결과, 대단한 알고리즘으로 효율적으로 푸는 문제가 아니라 그냥 구현 문제였다. 내 코드가 틀리지 않았다는 것..&lt;/p&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;2891&quot; data-origin-height=&quot;491&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ujUVR/btsPtmGIzSM/zgnmTn91GtokKCLY4uFYCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ujUVR/btsPtmGIzSM/zgnmTn91GtokKCLY4uFYCk/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ujUVR/btsPtmGIzSM/zgnmTn91GtokKCLY4uFYCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FujUVR%2FbtsPtmGIzSM%2FzgnmTn91GtokKCLY4uFYCk%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;2891&quot; height=&quot;491&quot; data-origin-width=&quot;2891&quot; data-origin-height=&quot;491&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N이 최대 1000으로 작다 보니까 딱히 시간이 많이 걸리지도 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가운데 컴파일 에러는 클래스명 Main으로 안 바꿔서 생긴 오류.&lt;/p&gt;</description>
      <category>Algorithm/Implementation</category>
      <category>java</category>
      <category>개발</category>
      <category>개발자</category>
      <category>구현</category>
      <category>백준 2304 자바</category>
      <category>백준 2304 창고 다각형</category>
      <category>알고리즘</category>
      <category>자바 코테</category>
      <category>창고 다각형</category>
      <category>코딩테스트</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/345</guid>
      <comments>https://yskisking.tistory.com/345#entry345comment</comments>
      <pubDate>Tue, 22 Jul 2025 17:33:32 +0900</pubDate>
    </item>
    <item>
      <title>[백준 1406 / Java / 실버2] 에디터</title>
      <link>https://yskisking.tistory.com/344</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;893&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/24XFA/btsPp2gBYCW/XROJtG6A6uVnxY9TOfNkMk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/24XFA/btsPp2gBYCW/XROJtG6A6uVnxY9TOfNkMk/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/24XFA/btsPp2gBYCW/XROJtG6A6uVnxY9TOfNkMk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F24XFA%2FbtsPp2gBYCW%2FXROJtG6A6uVnxY9TOfNkMk%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;1456&quot; height=&quot;893&quot; data-origin-width=&quot;1456&quot; data-origin-height=&quot;893&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제 자체는 시뮬레이션인데, 시뮬레이션 그대로 구현하면 무조건 시간 초과가 난다. 시간제한이 0.3초고, 삽입/삭제를 직접 수행할 경우 명령어가 50만개라서 50만 * 10만 하면 500억번 연산이라 자료구조를 잘 활용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 ArrayDeque 2개를 활용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1752911172022&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.*;

public class 에디터_1406_v2 {

	static ArrayDeque&amp;lt;Character&amp;gt; left = new ArrayDeque&amp;lt;&amp;gt;();
	static ArrayDeque&amp;lt;Character&amp;gt; right = new ArrayDeque&amp;lt;&amp;gt;();
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		StringTokenizer commands;
		
		/** 초기 문자열 */
		String str = br.readLine();
		for (int i = 0; i &amp;lt; str.length(); i++) {
			left.add(str.charAt(i));
		}
		
		/** 모든 명령어 실행 */
		int M = Integer.parseInt(br.readLine());
		for (int i = 0; i &amp;lt; M; i++) {
			
			commands = new StringTokenizer(br.readLine());
			modifyStr(commands);
		}
		
		/** 결과 출력 */
		for (char c : left) {
			sb.append(c);
		}
		for (char c: right) {
			sb.append(c);
		}
		System.out.println(sb);
	}
	
	/** 명령어에 맞게 문자열을 수정하는 함수 */
	private static void modifyStr(StringTokenizer commands) {
		
		String cmd = commands.nextToken();
		
		// 문자를 커서 왼쪽에 추가
		if (cmd.equals(&quot;P&quot;)) {
			String value = commands.nextToken();
			left.add(value.charAt(0));
		}
		
		// 커서를 왼쪽으로 옮기기
		else if (cmd.equals(&quot;L&quot;)) {
			if (!left.isEmpty()) {
				right.addFirst(left.pollLast());
			}
		}
		
		// 커서를 오른쪽으로 옮기기
		else if (cmd.equals(&quot;D&quot;)) {
			if (!right.isEmpty()) {
				left.add(right.pollFirst());
			}
		}
		
		// 커서 왼쪽에 있는 문자 삭제
		else if (cmd.equals(&quot;B&quot;)) {
			if (!left.isEmpty()) {
				left.pollLast();
			}
		}
	}

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 이 방법이 가장 효율적인 방법이라 생각한다. 직관적이기도 하고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;left, right 스택을 나누어 저장하고, 커서를 옮기는 것을 left, right 요소를 옮기는 것으로 구현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삭제할 때는 left의 tail 또는 right의 head를 지우면 되며, 삽입도 tail 이나 head에 하면 되므로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삽입/삭제는 일반 배열에서 O(N) 이지만 이렇게 하면 O(1)에 수행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1752911296102&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.*;

public class 에디터_1406 {
	
	/** 연결리스트 사용 */
	static List&amp;lt;Character&amp;gt; list = new LinkedList&amp;lt;&amp;gt;();
	static ListIterator&amp;lt;Character&amp;gt; iter = list.listIterator();
	
	public static void main(String[] args) throws Exception {
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer commands;
		
		/** 문자열을 연결리스트에 할당 */
		String str = br.readLine();
		for (int i = 0; i &amp;lt; str.length(); i++) {
			iter.add(str.charAt(i));
		}
		
		/** 명령어 개수만큼 반복 */
		int M = Integer.parseInt(br.readLine());
		for (int i = 0; i &amp;lt; M; i++) {
			
			commands = new StringTokenizer(br.readLine());
			modifyStr(commands);
		}
		
		/** 결과 출력 */
		StringBuilder sb = new StringBuilder();
		for (char c : list) {
			sb.append(c);
		}
		
		System.out.println(sb);
	}
	
	/** 문자열을 조작하고 현재 커서를 반환하는 함수 */
	private static void modifyStr(StringTokenizer commands) {
		
		String cmd = commands.nextToken();
		
		// 커서 왼쪽에 삽입
		if (cmd.equals(&quot;P&quot;)) {
			String value = commands.nextToken();
			iter.add(value.charAt(0));
		}
		
		// 커서를 왼쪽으로 이동
		else if (cmd.equals(&quot;L&quot;)) {
			if (iter.hasPrevious()) {
				iter.previous();
			}
		}
		
		// 커서를 오른쪽으로 이동
		else if (cmd.equals(&quot;D&quot;)) {
			if (iter.hasNext()) {
				iter.next();
			}
		}
		
		// 커서 왼쪽 문자 삭제
		else if (cmd.equals(&quot;B&quot;)) {
			if (iter.hasPrevious()) {
				iter.previous();
				iter.remove();
			}
		}
	}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결리스트와 ListIterator를 활용한 방법으로도 풀어보았다. 커서를 활용하는 이 에디터라는 문제와 완벽하게 호환되는 자료구조이다.&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;그래서 처음엔 ListIterator 로 풀었다가, ArrayDeque를 활용한 스택 2개 방법으로 바꿔서 풀었다. 직관적이고 간단한 방법이 더 좋다고 생각한다.&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;1447&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHEwKe/btsPpj4Fold/SUg5xZocyLlqXLN52OoMaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHEwKe/btsPpj4Fold/SUg5xZocyLlqXLN52OoMaK/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHEwKe/btsPpj4Fold/SUg5xZocyLlqXLN52OoMaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHEwKe%2FbtsPpj4Fold%2FSUg5xZocyLlqXLN52OoMaK%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;1447&quot; height=&quot;232&quot; data-origin-width=&quot;1447&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 아래꺼가 ListIterator, 맨 위에꺼가 ArrayDeque를 활용한 스택 2개 코드다. 미세하게 ListIterator가 더 빠르긴 한데, 빅오 표기법 기준으로 사실상 시간복잡도는 같고 더 직관적이니 스택 방식이 더 나은 것 같다.&lt;/p&gt;</description>
      <category>Algorithm/Stack</category>
      <category>ArrayDeque</category>
      <category>java</category>
      <category>개발</category>
      <category>구현</category>
      <category>백준 1406 에디터</category>
      <category>백준 1406 자바</category>
      <category>스택</category>
      <category>시뮬레이션</category>
      <category>자료구조</category>
      <category>코딩테스트</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/344</guid>
      <comments>https://yskisking.tistory.com/344#entry344comment</comments>
      <pubDate>Sat, 19 Jul 2025 16:51:19 +0900</pubDate>
    </item>
    <item>
      <title>[백준 1003 / Java / 실버3] 피보나치 함수</title>
      <link>https://yskisking.tistory.com/343</link>
      <description>&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1483&quot; data-origin-height=&quot;817&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DJbqX/btsPpdvMQ0l/MJwhFi1HcL0wL5kgTV0oFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DJbqX/btsPpdvMQ0l/MJwhFi1HcL0wL5kgTV0oFk/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DJbqX/btsPpdvMQ0l/MJwhFi1HcL0wL5kgTV0oFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDJbqX%2FbtsPpdvMQ0l%2FMJwhFi1HcL0wL5kgTV0oFk%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;1483&quot; height=&quot;817&quot; data-origin-width=&quot;1483&quot; data-origin-height=&quot;817&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;기본적인 피보나치 함수 문제이다. 일반적으로 재귀 또는 DP 형태로 풀 수 있다.&lt;br&gt;이 문제에서는 시간제한이 0.25초로 짧기 때문에 DP로 풀어야 한다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import java.io.*;

public class Main {
	
	static int zeroResult = 0;
	static int oneResult = 0;
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		int T = Integer.parseInt(br.readLine());
		for (int i = 0; i &amp;lt; T; i++) {
			
			int value = Integer.parseInt(br.readLine());
			fibo(value);
			System.out.printf(&quot;%d %d&quot;, zeroResult, oneResult);
			
			initialization();
		}
	}
	
	private static int fibo(int n) {
		if (n == 0) {
			zeroResult += 1;
			return 0;
		}
		else if (n == 1) {
			oneResult += 1;
			return 1;
		}
		else {
			return fibo(n-1) + fibo(n-2);
		}
	}
	
	private static void initialization() {
		zeroResult = 0;
		oneResult = 0;
	}
}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;첫 번째 시도 코드다. 최대 N이 40이라 0.25초여도 풀리지 않을까? 싶어서 그냥 재귀로 풀어봤는데, 시간초과가 떴다.&lt;br&gt;어쩔수 없이 DP로 풀기로 결정.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;pre data-ke-type=&quot;codeblock&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;import java.io.*;

public class 피보나치_함수_1003 {
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		/**
		 * [ [현재숫자, 0호출횟수, 1호출횟수] ... ]
		 * [ [0, 1, 0], [1, 0, 1], [1, 1, 1] ... ]
		 */
		int[][] fiboTable = new int[41][3];
		fiboTable[0] = new int[] {0, 1, 0};
		fiboTable[1] = new int[] {1, 0, 1};
		
		for (int i = 2; i &amp;lt; fiboTable.length; i++) {
			fiboTable[i] = new int[] {
					fiboTable[i-1][0] + fiboTable[i-2][0],
					fiboTable[i-1][1] + fiboTable[i-2][1],
					fiboTable[i-1][2] + fiboTable[i-2][2]
			};
		}
		
		int T = Integer.parseInt(br.readLine());
		for (int i = 0; i &amp;lt; T; i++) {
			
			int value = Integer.parseInt(br.readLine());
			System.out.printf(&quot;%d %d\n&quot;, fiboTable[value][1], fiboTable[value][2]);
		}
	}
}&lt;/code&gt;&lt;/pre&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;일반적인 피보나치 수열 구하는 문제는 이전값 + 전전값 = 현재값 인데,&lt;br&gt;이 문제에서는 단순 N번째 값을 출력하는 게 아니라 N이라는 값을 출력하기 위해 호출된 0, 1 재귀 횟수를 각각 출력해야 한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;크게 어렵지 않다. 그냥 값 구할 때 0, 1 호출 횟수도 같이 더해주면 끝!&lt;br&gt;&amp;nbsp;&lt;br&gt;fiboTable의 요소는 이렇다. -&amp;gt; [ 현재 값, 0호출횟수, 1호출횟수 ]&lt;br&gt;그래서 이렇게 초기화를 한 후에 -&amp;gt; [[ 0, 1, 0 ], [1, 0, 1]]&lt;br&gt;전부 다 더하면 끝이다. 값이든 호출횟수든 이전값, 전전값을 더하면 똑같이 구할 수 있는 것이다.&lt;br&gt;&amp;nbsp;&lt;br&gt;근데 난 실제 N번째 값까지 함께 구했는데, 그냥 저거 빼고 호출횟수만 더해도 되긴 한다. 그래도 직관성, 가독성을 위해서.. 함께 계산했다.&lt;/p&gt;</description>
      <category>Algorithm/Dynamic Programming</category>
      <category>DP</category>
      <category>java</category>
      <category>개발</category>
      <category>다이나믹 프로그래밍</category>
      <category>백준 1003 자바</category>
      <category>백준 1003 피보나치 함수</category>
      <category>백준 시간초과</category>
      <category>재귀함수</category>
      <category>코딩테스트</category>
      <category>피보나치 수열</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/343</guid>
      <comments>https://yskisking.tistory.com/343#entry343comment</comments>
      <pubDate>Fri, 18 Jul 2025 15:22:59 +0900</pubDate>
    </item>
    <item>
      <title>[백준 11501 / Python / 실버2] 주식: O(N^2) -&amp;gt; O(N)으로 최적화 (그리디)</title>
      <link>https://yskisking.tistory.com/342</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1469&quot; data-origin-height=&quot;714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8ncsS/btsPfHcBb7F/giOM5Pup5vGrkLIHd4kFu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8ncsS/btsPfHcBb7F/giOM5Pup5vGrkLIHd4kFu0/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8ncsS/btsPfHcBb7F/giOM5Pup5vGrkLIHd4kFu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8ncsS%2FbtsPfHcBb7F%2FgiOM5Pup5vGrkLIHd4kFu0%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;1469&quot; height=&quot;714&quot; data-origin-width=&quot;1469&quot; data-origin-height=&quot;714&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리디 문제이다. 살짝 어려웠다. 난 2가지 방식으로 풀었는데, 의문점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys.stdin.readline&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;1. 큰 값 순서대로 정렬&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;2. 현재 가장 큰 값 기준으로, 원본 리스트 역순 순회하며 가장 큰 값 찾기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;3. 찾았다면, 가장 큰 값 포함한 좌측 값 전부 사서 큰값에 팔기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;4. 원본리스트에서 방금 사용된 값을 전부 없애기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;5. 반복&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;현재 가장 큰 값 idx가 while문당 1씩 증가하는데, 이거 좀 비효율이다. 이후에 올 큰값들이 지워지면 쓸모없어지기 때문&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;따라서 가장 큰 값 리스트에서도 값들을 지워주고, 항상 0으로 인덱싱 하면 될 것 같은데 귀찮다.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;[1, 3, 1, 10, 2, 9, 3, 10, 5]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;[10, 9, 5, 3, 2, 1]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; _ &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;())):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; N &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; values &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().split()))&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 중복제거 후 최댓값 순 정렬하기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; sorted_values_set &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(values)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; sorted_values &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;sorted&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(sorted_values_set), &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;reverse&lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #ffab40;&quot;&gt;True&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;) &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 최댓값 리스트&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 원본 리스트가 빌 때까지 진행&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; cur_max_idx &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;while&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; values:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cur_max_idx &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 뒤쪽부터 탐색&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(values) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 최대값 만난 경우 좌측 것들 다 사서 최대값에 팔기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cur_max &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sorted_values[cur_max_idx]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; values[i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; cur_max:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; sell_values &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; values[:i &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 팔고 나서 삭제할 값들&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; values &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; values[i &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:] &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 팔고 남은 값들 (이어서 계산할 애들)&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 이득 계산&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; v &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sell_values:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (cur_max &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; v)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;break&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(result)&lt;/span&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;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 안전하게 최적의 값을 얻을 수 있지만 복잡도가 O(N^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;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys.stdin.readline&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; _ &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;())):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; N &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; values &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().split()))&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; cur_max &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(N &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; values[i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; cur_max:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cur_max &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; values[i]&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (cur_max &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; values[i])&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(result)&lt;/span&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;기존보다 훨씬 간단한 코드다. 시간복잡도는 O(N) 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리스트를 우측부터 단 한번 순회하며 최적의 값을 얻어낸다.슬라이딩도, 복잡한 조건문도, while도 2중 for문도 다 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이론상 완벽하게 원래 코드보다 빠른 상위호환 코드다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒤쪽부터 순회하며 최댓값을 저장해 두고, 해당 값보다 다음 값이 작으면 바로 팔아 버리면 된다. 이렇게 해도 문제가 없다는 걸 처음에는 몰랐었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 결과가 이상하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1446&quot; data-origin-height=&quot;377&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbXJjG/btsPfi5u5rV/yLtowSrh841tmdgsmFIa4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbXJjG/btsPfi5u5rV/yLtowSrh841tmdgsmFIa4k/img.png&quot; data-alt=&quot;왜 O(N)이 더 느리지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbXJjG/btsPfi5u5rV/yLtowSrh841tmdgsmFIa4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbXJjG%2FbtsPfi5u5rV%2FyLtowSrh841tmdgsmFIa4k%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;1446&quot; height=&quot;377&quot; data-origin-width=&quot;1446&quot; data-origin-height=&quot;377&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;왜 O(N)이 더 느리지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번째, 3번째 제출 코드가 O(N) 코드다. 시간이 각각 3256, 3088인데 기존 내 코드보다 비슷하거나 오히려 더 느리다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무리 생각해도 이유를 모르겠다. 기존 내 코드보다 덜어내면 덜어냈지 더 한게 아예 없는데 대체 어째서? 심지어 메모리도 더 먹는다. 테스트 케이스가 특이한 건가....&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨌든, O(N) 코드가 더 효율적인 건 명백하다. 백준 테스트 케이스의 문제 같은데.. 뭐, 어떤 코드가 더 나은 코드인지 파악만 하고 가도록 하자.&lt;/p&gt;</description>
      <category>Algorithm/Greedy</category>
      <category>Greedy</category>
      <category>개발</category>
      <category>그리디</category>
      <category>백준 11501 주식</category>
      <category>백준 11501 파이썬</category>
      <category>알고리즘</category>
      <category>주식</category>
      <category>코딩테스트</category>
      <category>탐욕법</category>
      <category>파이썬</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/342</guid>
      <comments>https://yskisking.tistory.com/342#entry342comment</comments>
      <pubDate>Fri, 11 Jul 2025 22:04:12 +0900</pubDate>
    </item>
    <item>
      <title>[백준 20310 / Python / 실버3] 타노스</title>
      <link>https://yskisking.tistory.com/341</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ovc13/btsO4HD9Ycf/WFLnFzrjgtVi93bay01mb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ovc13/btsO4HD9Ycf/WFLnFzrjgtVi93bay01mb0/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ovc13/btsO4HD9Ycf/WFLnFzrjgtVi93bay01mb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fovc13%2FbtsO4HD9Ycf%2FWFLnFzrjgtVi93bay01mb0%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;1444&quot; height=&quot;505&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;505&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리디 문제이다. 실버 3보다는 좀 더 쉬운 것 같다. 시간복잡도도 고려할 필요 없다. 난 고려하긴 했지만.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys.stdin.readline&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;0이 앞에 최대한 많아야 한다&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;1은 앞부터 지우고&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;0은 뒤부터 지우면 되지않나&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;1. 리스트로 받아서 , 지우지 말고 -1로 교체 (지우는 연산 오버헤드 방지)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;2. 앞부터 -1이 아닐 경우 출력&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;S &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().strip()))&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;0, 1 개수 세기&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 0의 개수, 1의 개수 저장할 리스트&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; num &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; S:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; num &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; count[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; count[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;앞부터 1 지우기&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;deleted_one &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(S)):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; S[i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; S[i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deleted_one &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; deleted_one &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (count[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;break&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;뒤부터 0 지우기&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;deleted_zero &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(S) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; S[i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; S[i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; deleted_zero &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; deleted_zero &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (count[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;break&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;''&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;.join(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;str&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(x) &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; S &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; x &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(result)&lt;/span&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;1과 0을 절반씩 지우되, 그 결과 중 사전순으로 가장 앞에 오는 것을 출력하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 무슨 의미냐면, 결과 중 가장 작은 수를 출력하면 된다는 의미이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞쪽부터 최대한 많은 0이 연속되어야 한다는 뜻이다. 0은 최대한 앞에, 1은 최대한 뒤에 있어야 한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 나는 1은 앞부터, 0은 뒤부터 지우면 이 조건을 만족할 수 있을 거라 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 지울 0과 1의 개수부터 구한 후에 2번의 반복문을 통해 1과 0을 각각 앞부터, 뒤부터 지워 줬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 여기서 실제 리스트를 변경하지 않았다. 지우는 연산 remove 또는 pop함수의 오버헤드 때문에 최악 시간복잡도가 &lt;b&gt;O(N^2)&lt;/b&gt; 까지 갈 수 있기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 실제로 리스트를 변경하지 않고 -1로 변경함으로써 지우는 효과만 내도록 했다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 remove나 pop을 사용했을 때 O(N^2) 에서, 정확히 O(4N)의 시간복잡도로 개선된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지울 0과 1 개수 세기 -&amp;gt; O(N)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1 지우기 -&amp;gt; O(N)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0 지우기 -&amp;gt; O(N)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과 문자열로 변경 -&amp;gt; O(N)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 총 O(4N) 이며, 상수를 제외하면 &lt;b&gt;O(N)&lt;/b&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;1443&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjOM5Z/btsO4h6PO3r/K3rXRsfweZW9naMnHL4KH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjOM5Z/btsO4h6PO3r/K3rXRsfweZW9naMnHL4KH0/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjOM5Z/btsO4h6PO3r/K3rXRsfweZW9naMnHL4KH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjOM5Z%2FbtsO4h6PO3r%2FK3rXRsfweZW9naMnHL4KH0%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;1443&quot; height=&quot;155&quot; data-origin-width=&quot;1443&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제의 입력값 길이는 최대 500으로써, 길이가 길지 않아 O(N^2)도 통과되긴 한다. 그러나 지금 상태로도 N^2 코드에 비해 내 코드가 약 3배 정도 빠르다. 입력 길이가 더 길어진다면 그 차이는 더욱 커질 것이다.&lt;/p&gt;</description>
      <category>Algorithm/Greedy</category>
      <category>Greedy</category>
      <category>개발</category>
      <category>그리디</category>
      <category>문자열</category>
      <category>백준 20310 타노스</category>
      <category>백준 20310 파이썬</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>탐욕법</category>
      <category>파이썬</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/341</guid>
      <comments>https://yskisking.tistory.com/341#entry341comment</comments>
      <pubDate>Fri, 4 Jul 2025 14:43:05 +0900</pubDate>
    </item>
    <item>
      <title>[백준 3758 / Python / 실버2] KCPC</title>
      <link>https://yskisking.tistory.com/340</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;829&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nLwKZ/btsO2zGDXAB/UCJjGj5Y5maJKCciXCrVn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nLwKZ/btsO2zGDXAB/UCJjGj5Y5maJKCciXCrVn1/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nLwKZ/btsO2zGDXAB/UCJjGj5Y5maJKCciXCrVn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnLwKZ%2FbtsO2zGDXAB%2FUCJjGj5Y5maJKCciXCrVn1%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;1474&quot; height=&quot;829&quot; data-origin-width=&quot;1474&quot; data-origin-height=&quot;829&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현, 정렬 문제이다. 입력값이 다양하게 주어져서 헷갈리고, 관리해야 하는 데이터가 많아 헷갈린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 정렬 조건만 제대로 숙지한다면 크게 어렵지 않게 풀 수 있는 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys.stdin.readline&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;k개의 문제를 풀면 0점 ~ 100점 획득함 -&amp;gt; 팀ID/문제번호/점수 저장&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;한 문제를 여러 번 제출하면, 최고점수가 최종점수 -&amp;gt; 제출안하면 0점&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;팀의 점수는 각 문제 최종 점수의 합&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;점수가 동일한 팀이 있을 경우&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;1. 점수가 같으면, 제출 횟수가 적은 팀이 이긴다&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;2. 점수와 제출 횟수가 같으면, 마지막 제출 시간이 빠른 팀이 이긴다&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;정렬 조건: 점수 높은순, 제출횟수 적은순, 제출시간 빠른순&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; _ &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;())):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; n: 팀 개수 (3 &amp;lt;= n)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; k: 문제 개수 (k &amp;lt;= 100)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; team: 나의 팀 (1 &amp;lt;= t &amp;lt;= n)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; m: 로그 개수 (3 &amp;lt;= m &amp;lt;= 10000)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; n, k, my_team, m &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().split())&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 각 팀 점수 계산용 리스트&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# [[문제1점수, 문제2점수, ... 크기는 k + 1] 이걸 n + 1개수만큼 팀별로 할당]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; team_and_score &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; [[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (k &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; _ &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(n &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)] &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 1 based&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 최종 정렬용 리스트 -&amp;gt; 팀별 총합점수, 제출횟수, 마지막 제출시간&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; score_count_time &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; [[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1e9&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)] &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; _ &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(n &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)] &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 1 based&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;로그 입력받기&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; submit &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(m):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cur_team: 팀 id&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; num: 문제 번호&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; score: 획득한 점수&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cur_team, num, score &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().split())&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 각 문제는 더 높은 점수로 갱신&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; team_and_score[cur_team][num] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(team_and_score[cur_team][num], score)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 제출횟수 더하기&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; score_count_time[cur_team][&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 마지막 제출시간 갱신&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; score_count_time[cur_team][&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; submit&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;계산된 팀별 점수를 정렬용 리스트에 할당&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; team &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, n &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; score_count_time[team][&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;sum&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(team_and_score[team])&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; score_count_time[team].append(team) &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 정렬되면 인덱스로 구분되던 팀이 섞이니, 팀 번호를 리스트에 추가해준다&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; 문제 조건대로 정렬&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; 점수 높은순, 제출횟수 적은순, 제출시간 빠른순&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; score_count_time.sort(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;key&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;lambda&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;x&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: (&lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;x[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;], x[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;], x[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;]))&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; rank &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(score_count_time) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 우리 팀 랭킹 출력&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 정렬되면서 패딩 요소는 맨뒤로 밀려남. 따라서 0번인덱스부터 검사&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 순위는 1부터 시작이니, 인덱스 + 1 출력&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; score_count_time[rank][&lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; my_team:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(rank &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;break&lt;/span&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;team_and_score: 팀별 최종 점수를 계산하기 위한 리스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;score_count_time: 팀별 최종점수, 제출횟수, 제출시간을 저장하고 정렬하기 위한 리스트&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 로그를 입력받는 동시에, team_and_score 리스트를 이용해 각 팀의 각 문제에 대한 점수를 max함수를 이용해 지속적으로 갱신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;score_count_time 리스트에는 제출횟수와 제출시간을 실시간으로 업데이트 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 로그를 입력받았다면, team_and_score에 저장된 팀별 점수를 sum()으로 더해서 score_count_time 리스트에 넣어준다. 그러면 문제 정렬 조건인 점수 높은순, 제출횟수 적은순, 제출시간 빠른순에 해당하는 3가지 요소가 하나의 리스트에 전부 들어가게 된다. 단, 여기서 각 요소마다 팀번호를 추가해줘서 정렬 후에도 팀 번호를 잃어버리지 않게 된다. (그냥 정렬하면 순위대로 정렬되지만, 팀 번호는 잃어버린다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 lambda를 활용해서 정렬한 후, 입력받은 team에 대한 순위를 출력해주면 끝.&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;1435&quot; data-origin-height=&quot;194&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dp8AHc/btsO3DHN8PK/IYiD7h7VUMJjDO3lVreuaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dp8AHc/btsO3DHN8PK/IYiD7h7VUMJjDO3lVreuaK/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dp8AHc/btsO3DHN8PK/IYiD7h7VUMJjDO3lVreuaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdp8AHc%2FbtsO3DHN8PK%2FIYiD7h7VUMJjDO3lVreuaK%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;1435&quot; height=&quot;194&quot; data-origin-width=&quot;1435&quot; data-origin-height=&quot;194&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 사람들 풀이도 몇개 봤는데 나름 잘 푼 편에 속한 것 같다. 시간은 거의 제일 빠른 편인 듯.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 한가지 최적화할 게 있다면, 팀 번호와 순위를 매핑하는 딕셔너리를 이용해볼까? 였는데,&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;</description>
      <category>Algorithm/정렬</category>
      <category>lambda</category>
      <category>개발</category>
      <category>구현</category>
      <category>백준 3758 kcpc</category>
      <category>백준 3758 파이썬</category>
      <category>알고리즘</category>
      <category>정렬</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <category>파이썬 람다</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/340</guid>
      <comments>https://yskisking.tistory.com/340#entry340comment</comments>
      <pubDate>Thu, 3 Jul 2025 15:48:59 +0900</pubDate>
    </item>
    <item>
      <title>[백준 2607 / Python / 실버2] 비슷한 단어</title>
      <link>https://yskisking.tistory.com/339</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1538&quot; data-origin-height=&quot;832&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/en8RIW/btsO1WVnaUa/202HGzKBSTqg5qGG0SMfjK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/en8RIW/btsO1WVnaUa/202HGzKBSTqg5qGG0SMfjK/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/en8RIW/btsO1WVnaUa/202HGzKBSTqg5qGG0SMfjK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fen8RIW%2FbtsO1WVnaUa%2F202HGzKBSTqg5qGG0SMfjK%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;1538&quot; height=&quot;832&quot; data-origin-width=&quot;1538&quot; data-origin-height=&quot;832&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현, 문자열 문제이다. 비슷한 단어가 될 수 있는 조건을 정확히 찾으면 쉬운 문제인데, 조건 하나를 빠뜨려서 조금 헤맸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;from&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; collections &lt;/span&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; defaultdict&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys.stdin.readline&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;길이가 2이상 차이나면 제외.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;1. 길이가 1차이나는 경우, 나머지 문자의 개수가 전부 같다면 비슷한 단어이다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;2. 길이가 같은 경우, 모든 문자가 같으면 비슷한 단어이다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;3. 길이가 같은 경우, 하나의 문자가 다르다면 비슷한 단어이다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;-&amp;gt; 이 3가지 외에 만족하는 케이스는 없다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;N &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;ref &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().strip()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;ref_count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; defaultdict(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; key &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; ref:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; ref_count[key] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; _ &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(N &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; word &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().strip()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; diff_len &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;abs&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(ref) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(word))&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; diff_len &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;continue&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; word_count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; defaultdict(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; key &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; word:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; word_count[key] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 모든 문자를 모은 합집합&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; all_chars &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(ref) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(word)&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; diff_count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; char &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; all_chars:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; diff_count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;abs&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(ref_count.get(char, &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; word_count.get(char, &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;))&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; diff_count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;break&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; diff_count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 같은 구성&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;elif&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; diff_count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 같은 구성에 단어 하나만 추가된 것&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;elif&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; diff_count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;and&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; diff_len &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: &amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 길이와 나머지 구성이 같은데 단어 하나만 다른 것&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(result)&lt;/span&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;1. 우선 기준이 될 단어 ref 의 각 문자 당 개수를 세 둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 비교대상 단어 word를 입력받는데, 만약 ref와 word의 len 차이가 2 이상이라면 절대 비슷한 단어가 될 수 없으니 넘어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 비교대상 단어 word 의 각 문자 당 개수도 세 둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. ref와 word에 존재하는 모든 문자를 검사하기 위해, 순회용 문자의 합집합 all_chars를 만들어 둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 이제 all_chars를 순회하면서 각 문자의 개수 차이를 세서 diff_count에 전부 더한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 diff_count가 3 이상이면, 절대로 비슷한 단어가 될 수 없다. 그렇다면 남은 경우의 수는 diff_count가 0, 1, 2일 때이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;diff_count가 0인 경우: 같은 구성 ( 'ABC', 'CBA' )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;diff_count가 1인 경우: 같은 구성인데, 단어 하나가 추가된것 ( 'ABC', 'ABCD' )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;diff_count가 2인 경우: 길이와 구성이 같은데, 단어 하나만 다른 것 ( 'ABC', 'ABG' )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 이 경우 왜 diff_count가 2냐면, C를 word에서 찾고 G를 ref에서 찾기 때문에 단어 한개가 다른데도 diff_count는 2가 추가된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 외에 비슷한 단어가 되는 경우는 없다. 난 diff_count가 2인 경우도 정답이 될 수 있다는 걸 간과해서 좀 헤맸다.&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;1446&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EKNhE/btsO0VCU9Qu/AYo4bNJKN8k2ESsKXmUB30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EKNhE/btsO0VCU9Qu/AYo4bNJKN8k2ESsKXmUB30/img.png&quot; data-alt=&quot;결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EKNhE/btsO0VCU9Qu/AYo4bNJKN8k2ESsKXmUB30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEKNhE%2FbtsO0VCU9Qu%2FAYo4bNJKN8k2ESsKXmUB30%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;1446&quot; height=&quot;320&quot; data-origin-width=&quot;1446&quot; data-origin-height=&quot;320&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Algorithm/Implementation</category>
      <category>implementation</category>
      <category>개발</category>
      <category>구현</category>
      <category>문자열</category>
      <category>백준 2607 비슷한 단어</category>
      <category>백준 2607 파이썬</category>
      <category>비슷한 단어</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/339</guid>
      <comments>https://yskisking.tistory.com/339#entry339comment</comments>
      <pubDate>Wed, 2 Jul 2025 16:55:07 +0900</pubDate>
    </item>
    <item>
      <title>[백준 19941 / Python / 실버3] 햄버거 분배</title>
      <link>https://yskisking.tistory.com/338</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1469&quot; data-origin-height=&quot;866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b732jq/btsOWjjWORC/FNFSt5xu6CqJlU8DrJ8sYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b732jq/btsOWjjWORC/FNFSt5xu6CqJlU8DrJ8sYK/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b732jq/btsOWjjWORC/FNFSt5xu6CqJlU8DrJ8sYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb732jq%2FbtsOWjjWORC%2FFNFSt5xu6CqJlU8DrJ8sYK%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;1469&quot; height=&quot;866&quot; data-origin-width=&quot;1469&quot; data-origin-height=&quot;866&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전통적인 그리디 문제이다. 부분 최적해가 전체 최적해가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;can_eat 함수의 슬라이싱 부분은, 투포인터나 슬라이딩 윈도우 성질도 띈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys.stdin.readline&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;N: 식탁의 길이&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;K: K 이하 거리 햄버거 먹기 가능&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;table: 사람과 햄버거의 위치&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;사람 기준 순서대로 왼쪽이든 오른쪽이든 가장 가까운거 먹으면 될거같은데..? 그리디?&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;K가 최대 10이니 가능할거같다. K &amp;lt;= N이었으면 힘들었을듯.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;햄버거와 사람을 따로 보지 않고, 매핑되는 관계로 간주한다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;왼쪽부터 K범위를 순차 탐색하며, 매핑될 경우 두 요소를 방문처리한다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;can_eat&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;idx&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;K&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 기준 (사람 또는 햄버거)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; point &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; table[idx]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# idx 뒤로 K거리만큼 잘라낸다 (슬라이싱은 인덱스오류 안남)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; sliced_table &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; table[idx &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: idx &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; K &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 거리 내에 있는 햄버거/사람을 찾으면 방문 처리&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(sliced_table)):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; point &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;!=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sliced_table[i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;and&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;not&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; visited[idx &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i]:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; visited[idx &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffab40;&quot;&gt;True&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffab40;&quot;&gt;True&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffab40;&quot;&gt;False&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;N, K &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().split())&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;table &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().strip())&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;visited &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; [&lt;/span&gt;&lt;span style=&quot;color: #ffab40;&quot;&gt;False&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; N&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(N):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 아직 매칭되지 않은 사람/햄버거에 대해 진행&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;not&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; visited[i]:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; visited[i] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffab40;&quot;&gt;True&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; can_eat(i, K):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(result)&lt;/span&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;일단, 나는 사람(P)과 햄버거(H)를 매핑되는 관계로 간주하고 딱히 구분짓지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 visited 리스트를 사용해서 이미 매핑된 사람/햄버거는 방문처리하여 다시 탐색하지 않게 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사람과 햄버거를 구분짓지 않으면, 왼쪽부터, 즉 0번 인덱스부터 차례로 기준점이 되는 것이 가능해진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 각 기준점에서 K거리만큼의 범위만 확인하되, H라면 P를, P라면 H를 찾으면 된다. 요소는 H 또는 P 2개밖에 없기 때문에 != 연산을 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 매핑될 때마다 result를 1씩 추가해 주면 정답을 도출할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간 복잡도는 O(N)이고 정확히는 O(KN) 인데, K의 최대값이 몇이냐에 따라 복잡도가 많이 바뀐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제에서 K는 최대 10이라, 정확히는 O(10N) 이라서 O(N)에 수렴하는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 K의 최대값이 N이었다면 O(N^2)이 되고 4억번 이상의 연산이 필요하여 문제 해결이 어려웠을 것이다.&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;1432&quot; data-origin-height=&quot;148&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bn46X6/btsOZE0rtVU/vcW9NhkBcKjqv3zIUrKQT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bn46X6/btsOZE0rtVU/vcW9NhkBcKjqv3zIUrKQT1/img.png&quot; data-alt=&quot;한 번에 통과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bn46X6/btsOZE0rtVU/vcW9NhkBcKjqv3zIUrKQT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbn46X6%2FbtsOZE0rtVU%2FvcW9NhkBcKjqv3zIUrKQT1%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;1432&quot; height=&quot;148&quot; data-origin-width=&quot;1432&quot; data-origin-height=&quot;148&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한 번에 통과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 번에 통과했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 사람들 제출 내역을 보니, 최근 제출 중에는 내 코드가 가장 빨랐다. 매우 기쁘다.&lt;/p&gt;</description>
      <category>Algorithm/Greedy</category>
      <category>Greedy</category>
      <category>개발</category>
      <category>그리디</category>
      <category>백준 19941 파이썬</category>
      <category>백준 19941 햄버거 분배</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>탐욕법</category>
      <category>파이썬</category>
      <category>햄버거 분배</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/338</guid>
      <comments>https://yskisking.tistory.com/338#entry338comment</comments>
      <pubDate>Mon, 30 Jun 2025 19:53:34 +0900</pubDate>
    </item>
    <item>
      <title>[백준 2512 / Python / 실버2] 예산</title>
      <link>https://yskisking.tistory.com/337</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1457&quot; data-origin-height=&quot;726&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sevDe/btsOVraLVwt/Zq3YoLDVj6DsRxvFPju3i1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sevDe/btsOVraLVwt/Zq3YoLDVj6DsRxvFPju3i1/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sevDe/btsOVraLVwt/Zq3YoLDVj6DsRxvFPju3i1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsevDe%2FbtsOVraLVwt%2FZq3YoLDVj6DsRxvFPju3i1%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;1457&quot; height=&quot;726&quot; data-origin-width=&quot;1457&quot; data-origin-height=&quot;726&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 예산 안에서 요청받은 금액을 배정해 주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예산이 충분하다면 요청받은 대로 전부 다 주면 되지만, 예산이 부족하다면 상한가를 정해서 최대한 많은 예산을 배분해야 한다.&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;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys.stdin.readline&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;1. 모든 요청을 줄 수 있다면 다 준다&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;2. 상한액을 정해서, 상한액 이상인 요청엔 상한액만 준다. 상한액 이하의 요청은 그대로 준다&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;N &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;reqs &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;list&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().split()))&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;budget &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;calc&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;limit&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;arr&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; 상한가를 고려해, 지급해야 할 금액 계산&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; limit: 상한가&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&amp;nbsp; &amp;nbsp; &quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(arr) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; limit_idx &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;while&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; right:&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mid &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; right) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; arr[mid] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; limit:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; mid &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; limit_idx &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; mid&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; mid &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 상한가보다 낮은 좌측 금액 합계 (요청받은 금액 다 줌)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; left_sum &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;sum&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(arr[:limit_idx])&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 상한가보다 높은 우측 금액 합계 (상한가 만큼만 줌)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; right_sum &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; limit &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(arr[limit_idx:])&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 총 금액 리턴&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; left_sum &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; right_sum&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;sum&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(reqs) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; budget:&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;예산이 충분할 경우&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;max&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(reqs))&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #cda48c;&quot;&gt;&quot;&quot;&quot;예산이 부족할 경우, 상한가 기준 이분탐색&quot;&quot;&quot;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; reqs.sort()&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; reqs[&lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;while&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; right:&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# mid는 현재 상한가&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mid &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; right) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; total &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; calc(mid, reqs)&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 예산이 딱 맞는다면 바로 리턴 (최적 상한가)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; total &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;==&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; budget:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; mid&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;break&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;elif&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; total &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; budget:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; right &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; mid &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; left &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; mid &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #757882;&quot;&gt;# 최대한 많은 예산을 써야 하므로 right 출력&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(right)&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째는 &quot;상한가&quot;기준 이분 탐색이다. 최소 상한가는 1이고 최대 상한가는 가장 높은 요청 금액 - 1이다. -1을 하는 이유는 , 가장 높은 요청 금액이 상한가일 경우, 즉 -1을 하지 않은 경우는 예산이 충분할 경우에서 이미 필터링 되기 때문이다. 이분탐색을 진행하며 상한가를 갱신할 때마다, 해당 상한가를 적용할 경우 지급해야 하는 금액은 얼마인지 계산한다. 이것이 두번째 이분탐색 calc() 이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;calc()는 상한가를 기준으로 좌측, 우측을 나누어 좌측 값들은 요청한 금액을 전부 주고, 상한가 이상인 우측 값들은 상한가 만큼만 준다. 사실 이건 calc() 함수로 안 빼고 그냥,&lt;/p&gt;
&lt;pre id=&quot;code_1751044149360&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;for req in reqs:
    if mid &amp;lt; req:
        total += mid
    else:
        total += req&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 반복문 해도 되긴 하다. 근데 좀 비효율적이다. 왜냐하면 모든 요소(N개)에 if 조건문을 전부 적용하며 일일이 더하기 때문이다. 그래서 조금 더 효율적인 total 계산을 위해, 이분탐색을 활용한 calc() 함수를 따로 만들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 방식은 생각보다 성능 차이가 많이 났다. 시간복잡도는 같은 O(NlogN) 인데도, calc() 함수의 유무에 따라 발생하는 total 계산식에서 성능 차이가 발생하는 것 같다.&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-filename=&quot;blob&quot; data-origin-width=&quot;1424&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dhiScY/btsOUxhX7Oc/XctlkjmWcKVe95jccR53f0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dhiScY/btsOUxhX7Oc/XctlkjmWcKVe95jccR53f0/img.png&quot; data-alt=&quot;성능 차이&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dhiScY/btsOUxhX7Oc/XctlkjmWcKVe95jccR53f0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdhiScY%2FbtsOUxhX7Oc%2FXctlkjmWcKVe95jccR53f0%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;1424&quot; height=&quot;489&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1424&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;성능 차이&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스티커로 표기된 제출의 시간은 68ms 인데, 이게 단순 반복문으로 total을 구한 코드이다. 기존 코드가 36ms인걸 감안하면 꽤 차이가 많이 난다. 근데 결국 큰 틀에서는 같은 O(NlogN) 이기 때문에 간결하고 가독성 좋은 코드가 더 낫나 싶기도 하지만, calc() 함수로 로직을 추상화했으니 그 차이도 없는 것 같기도 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 추가해 보자면, calc() 함수가 호출될 때마다 left_sum을 구하기 위해 sum()을 사용해서 O(N)시간이 사용되는데, 이것도 누적 합 테이블 미리 한번 구해놓으면 상수 시간으로 최적화할 수 있긴 한데 이 문제에서는 굳이인것 같다.&lt;/p&gt;</description>
      <category>Algorithm/Binary Search</category>
      <category>binary search</category>
      <category>개발</category>
      <category>백준 2512 예산 파이썬</category>
      <category>백준 2512 파이썬</category>
      <category>백준 예산</category>
      <category>시간복잡도</category>
      <category>알고리즘</category>
      <category>이분 탐색</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/337</guid>
      <comments>https://yskisking.tistory.com/337#entry337comment</comments>
      <pubDate>Sat, 28 Jun 2025 02:10:44 +0900</pubDate>
    </item>
    <item>
      <title>[백준 10431 / Python / 실버5] 줄세우기</title>
      <link>https://yskisking.tistory.com/336</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2970&quot; data-origin-height=&quot;1737&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boP5xP/btsOG91tc8h/VkYC926jCKjNE05nv2irs0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boP5xP/btsOG91tc8h/VkYC926jCKjNE05nv2irs0/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boP5xP/btsOG91tc8h/VkYC926jCKjNE05nv2irs0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboP5xP%2FbtsOG91tc8h%2FVkYC926jCKjNE05nv2irs0%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;2970&quot; height=&quot;1737&quot; data-origin-width=&quot;2970&quot; data-origin-height=&quot;1737&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현, 정렬, 시뮬레이션 문제이다. 모든 학생이 각자 물러선 총 횟수를 구해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4;&quot;&gt;
&lt;div&gt;&lt;span style=&quot;color: #ce93d8;&quot;&gt;import&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; sys.stdin.readline&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #569cd6;&quot;&gt;def&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;binary_search&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;child&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;arr&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; start &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; end &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(arr) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(arr)&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;while&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; start &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;lt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; end:&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mid &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; (start &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; end) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;//&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;2&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;if&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; arr[mid] &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; child:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; mid&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; end &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; mid &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;else&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; start &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; mid &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;return&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(arr) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; result&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;P &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;())&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; _ &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(P):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; number, &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;children &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;map&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #4ec9b0;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;input&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;().split())&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; standing &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; [children[&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;]]&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;for&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; i &lt;/span&gt;&lt;span style=&quot;color: #f48fb1;&quot;&gt;in&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;color: #aeea00;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(children)):&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; count &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; binary_search(children[i], standing)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; result &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;+=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; count&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; idx &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;len&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(standing) &lt;/span&gt;&lt;span style=&quot;color: #ffd54f;&quot;&gt;-&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt; count&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; standing.insert(idx, children[i])&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;&amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style=&quot;color: #ffecb3;&quot;&gt;print&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;(number, result)&lt;/span&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어진 순서대로 아이들을 줄세우되, 아이가 추가될 때마다 뒤쪽 아이들이 뒷걸음 하는 횟수를 전부 더하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, &lt;b&gt;아이가 어떤 위치에 끼어들어야 하는가? 를 구하기 위해 이분 탐색을 활용&lt;/b&gt;했다. binary_search 함수는 뒷걸음 하는 횟수를 리턴하는 함수이다.&lt;/p&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;gt; 뒷걸음 하는 아이의 수&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;줄 길이 - 뒷걸음 하는 아이의 수 -&amp;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;끼어들 좌표를 구한 후, 실제로 끼어들도록 insert 해주는 작업도 잊어선 안된다.&lt;/p&gt;</description>
      <category>Algorithm/Implementation</category>
      <category>개발자</category>
      <category>구현</category>
      <category>백준 10431 줄세우기 파이썬</category>
      <category>백준 10431 파이썬</category>
      <category>백준 줄세우기</category>
      <category>시뮬레이션</category>
      <category>알고리즘</category>
      <category>이분 탐색</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/336</guid>
      <comments>https://yskisking.tistory.com/336#entry336comment</comments>
      <pubDate>Wed, 18 Jun 2025 20:05:04 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 / python / Level 2] 압축</title>
      <link>https://yskisking.tistory.com/335</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;653&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFvH7f/btsOz7XWqp2/6IBx9YhLh6xZGnDgzcSwyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFvH7f/btsOz7XWqp2/6IBx9YhLh6xZGnDgzcSwyk/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFvH7f/btsOz7XWqp2/6IBx9YhLh6xZGnDgzcSwyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFvH7f%2FbtsOz7XWqp2%2F6IBx9YhLh6xZGnDgzcSwyk%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;741&quot; height=&quot;534&quot; data-origin-width=&quot;906&quot; data-origin-height=&quot;653&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2018 KAKAO BLIND RECRUITMENT에 출제된 문제이다. 구현, 문자열 문제이고 문제 조건이 크게 어려운 건 아닌데, 구현 문제다 보니까 디테일한 부분에서의 실수가 없도록 주의해야 하는 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749797451893&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(msg):
    
    &quot;&quot;&quot;인덱스 -&amp;gt; 문자열, 문자열 -&amp;gt; 인덱스 사전 제작&quot;&quot;&quot;
    idx_to_str = [''] + [chr(i) for i in range(ord('A'), ord('Z') + 1)]
    
    str_to_idx = dict()
    for i in range(26):
        char = chr(ord('A') + i)
        str_to_idx[char] = i + 1
        
    &quot;&quot;&quot;메인 로직, 문자열을 전부 압축할 때 까지 반복&quot;&quot;&quot;
    result = []
    i = 0  # 시작 인덱스
    while i &amp;lt; len(msg):
        
        current = msg[i]
        
        # 범위를 1씩 늘려가며 가장 긴 문자열 추출
        j = i + 2
        while j &amp;lt;= len(msg) and msg[i:j] in str_to_idx:
            current = msg[i:j]
            j += 1
        
        # 결과에 인덱스 추가
        result.append(str_to_idx[current])
        
        # 다음 문자가 있다면 사전에 추가
        next_idx = i + len(current)
        if next_idx &amp;lt; len(msg):
            
            new_str = current + msg[next_idx]
            str_to_idx[new_str] = len(idx_to_str)
            idx_to_str.append(new_str)
        
        # 다음 시작 인덱스 갱신
        i = next_idx
    
    return result&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 가장 먼저 사전2개를 제작한다. 인덱스로 문자열을 추출할 수 있는 리스트와, 문자열로 인덱스를 추출할 수 있는 딕셔너리. 미리 사전 2개를 만들어 두면, 메모리는 좀 더 먹겠지만 어떤 방식으로 조회하든 O(1) 시간에 조회할 수 있게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인 로직은 단순하다. 시작, 끝(i, j) 범위를 정해놓고 끝 범위를 1씩 늘려가며 사전에서 해당 문자열이 존재하는지 찾으면 된다. 말했듯 조회 연산은 미리 만들어 둔 사전 덕에 O(1)이기 때문에 큰 부담이 없다. 그렇게 사전에 존재하는 가장 긴 문자열을 찾는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과에 해당 문자열의 인덱스를 저장하고, 더 압축할 다음 문자가 존재한다면 저장한 문자열과 다음 문자를 합쳐 두 사전에 추가해 주면 된다.&lt;/p&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;</description>
      <category>Algorithm/Implementation</category>
      <category>2018 KAKAO BLIND RECRUITMENT</category>
      <category>개발</category>
      <category>구현</category>
      <category>문자열</category>
      <category>알고리즘</category>
      <category>카카오 코딩테스트</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <category>프로그래머스 level 2</category>
      <category>프로그래머스 압축</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/335</guid>
      <comments>https://yskisking.tistory.com/335#entry335comment</comments>
      <pubDate>Fri, 13 Jun 2025 15:57:09 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 / python / Level 2] 프렌즈4블록</title>
      <link>https://yskisking.tistory.com/334</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;654&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SY678/btsOzLffeVg/rMXTU8KuWVJfRXGl1MK8P0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SY678/btsOzLffeVg/rMXTU8KuWVJfRXGl1MK8P0/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SY678/btsOzLffeVg/rMXTU8KuWVJfRXGl1MK8P0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSY678%2FbtsOzLffeVg%2FrMXTU8KuWVJfRXGl1MK8P0%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;1021&quot; height=&quot;654&quot; data-origin-width=&quot;1021&quot; data-origin-height=&quot;654&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2018 KAKAO BLIND RECRUITMENT에 출제된 문제이다. 구현, 시뮬레이션 문제이고 블럭을 떨어뜨리는 로직을 구현하는 것이 핵심이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749742869794&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(m, n, board):
    
    &quot;&quot;&quot;블럭을 제거하는 함수&quot;&quot;&quot;
    def delete_blocks(m, n, board):
        
        # 모든 블럭에 대하여 삭제 조건 검사
        deleted_blocks = set()
        for x in range(m - 1):
            for y in range(n - 1):
                
                point = board[x][y]
                if point == '':
                    continue
                
                # 2*2 영역이 같은 블럭이라면 삭제 블럭 집합에 추가
                if (board[x][y] == board[x+1][y] == board[x][y+1] == board[x+1][y+1] == point):
                    for i in range(2):
                        for j in range(2):
                            deleted_blocks.add((x+i, y+j))
        
        # 블럭 삭제
        for x, y in deleted_blocks:
            board[x][y] = ''
        
        # 삭제한 블럭 개수 리턴
        return len(deleted_blocks)
    
    &quot;&quot;&quot;블럭을 떨어뜨리는 함수&quot;&quot;&quot;
    def drop_blocks(m, n, board):
        
        # 열(Column) 단위로 진행
        for y in range(n):
            
            # 비어있지 않은 모든 블럭을 수집
            blocks = []
            for x in range(m):
                if board[x][y] != '':
                    blocks.append(board[x][y])
                    board[x][y] = ''
            
            # 아래쪽부터 역순으로 배치
            x_idx = m - 1
            while len(blocks) &amp;gt; 0:
                board[x_idx][y] = blocks.pop()
                x_idx -= 1
    
    &quot;&quot;&quot;메인 로직&quot;&quot;&quot;
    # board를 2차원 리스트 형태로 변환
    board = [list(row) for row in board]
    
    result = 0
    while True:
        
        # 더이상 블록을 제거할 수 없다면 종료
        count = delete_blocks(m, n, board)
        if count == 0:
            break
        
        # 제거한 블록 개수 갱신
        result += count
        
        # 블록 떨어뜨리기
        drop_blocks(m, n, board)
    
    return result&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제에 주어진 내용을 그대로 구현하면 된다. &lt;b&gt;완전탐색&lt;/b&gt;을 진행하면 되며, 최대 30 * 30이기 때문에 시간 초과 날 걱정은 없다.&lt;/p&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*2 공간을 전부 다 검사하여 제거한다. 단 제거할 블럭을 &lt;b&gt;검사하는 것과 삭제하는 로직은 분리&lt;/b&gt;해야 한다. 찾자마다 제거해 버리면 여러 공간에 포함된 블럭이 먼저 제거되어 버려 다음 검사되는 블럭은 제거되지 않을 수 있다. 따라서 제거할 블럭을 전부 찾은 후에 제거는 따로 진행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 블럭을 떨어뜨리는 로직을 구현해야 한다. 행이 아닌 열 단위로 진행하되, 열에 존재하는 &lt;b&gt;모든 블럭을 수집 후 가장 아래쪽부터 차례대로 배치&lt;/b&gt;하면 된다. 중력을 구현하는 가장 간단한 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 완성된 제거+떨어뜨리기 2가지를 while문으로 반복하며 제거한 블록의 개수를 세고, 더 이상 제거할 수 없을 때 while문을 종료하면 해결할 수 있다.&lt;/p&gt;</description>
      <category>Algorithm/Implementation</category>
      <category>2018 KAKAO BLIND RECRUITMENT</category>
      <category>구현</category>
      <category>시뮬레이션</category>
      <category>알고리즘</category>
      <category>중력 구현</category>
      <category>카카오 코딩테스트</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <category>프로그래머스 level 2</category>
      <category>프로그래머스 프렌즈4블록</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/334</guid>
      <comments>https://yskisking.tistory.com/334#entry334comment</comments>
      <pubDate>Fri, 13 Jun 2025 00:46:42 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 / python / Level 3] 자물쇠와 열쇠</title>
      <link>https://yskisking.tistory.com/333</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;482&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lCHLF/btsOxCpg4Cz/HWO9YWlZVoKGKVteDGY4n0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lCHLF/btsOxCpg4Cz/HWO9YWlZVoKGKVteDGY4n0/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lCHLF/btsOxCpg4Cz/HWO9YWlZVoKGKVteDGY4n0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlCHLF%2FbtsOxCpg4Cz%2FHWO9YWlZVoKGKVteDGY4n0%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;723&quot; height=&quot;384&quot; data-origin-width=&quot;907&quot; data-origin-height=&quot;482&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2020 KAKAO BLIND RECRUITMENT에 출제된 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구현, 완전탐색 문제이며 보드 확장 아이디어를 떠올리지 못한다면 풀기 까다로울 수 있는 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749634047993&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(key, lock):
    
    &quot;&quot;&quot;
    90도 회전시키는 함수
    자물쇠가 열리는지 확인하는 함수 -&amp;gt; 열쇠를 보드에 적용 + 자물쇠값 모두 1인지 확인 + 열쇠를 보드에서 제거
    
    확장된 보드를 만든다
    자물쇠를 보드 중앙에 배치한다
    열쇠를 4방향으로 회전시키며, 모든 가능한 위치에서 열기 시도한다
    &quot;&quot;&quot;
    
    &quot;&quot;&quot;키를 시계 방향으로 90도 회전하는 함수&quot;&quot;&quot;
    def rotate_key(key):
        return [list(row) for row in zip(*key[::-1])]
    
    &quot;&quot;&quot;자물쇠 해제를 시도하는 함수&quot;&quot;&quot;
    def try_unlock(x, y, M, N, key, board):
        
        # key를 board에 전부 더하기
        for i in range(M):
            for j in range(M):
                board[x + i][y + j] += key[i][j]
        
        # 모든 자물쇠 값이 1인지 확인
        is_unlocked = True
        for i in range(N):
            for j in range(N):
                if board[M + i][M + j] != 1:
                    is_unlocked = False
                    break
            if is_unlocked == False:
                break
        
        # 자물쇠 원상복구
        for i in range(M):
            for j in range(M):
                board[x + i][y + j] -= key[i][j]
        
        return is_unlocked
    
    &quot;&quot;&quot;확장된 보드 만들기&quot;&quot;&quot;
    M = len(key)
    N = len(lock)
    board_size = M + N + M
    board = [[0] * board_size for _ in range(board_size)]
    
    &quot;&quot;&quot;자물쇠를 보드 중앙에 배치&quot;&quot;&quot;
    for i in range(N):
        for j in range(N):
            board[M + i][M + j] = lock[i][j]
    
    &quot;&quot;&quot;메인 로직, 모든 위치에 대하여 열기 시도 * 4방향&quot;&quot;&quot;
    current_key = key
    for _ in range(4):
        
        for x in range(M + N):
            for y in range(M + N):
                if try_unlock(x, y, M, N, current_key, board):
                    return True
                
        current_key = rotate_key(current_key)
    
    return False&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;lock과 key의 크기가 최대 20 * 20으로써, 완전탐색으로 충분히 풀 수 있다. 그러나 어떻게 해야 방향이 변하고 움직이는 열쇠를 자물쇠에 맞게 대입해 볼 수 있는지, 즉 어떻게 해야 모든 경우의 수를 만들 수 있고, 그걸 어떻게 대입하는지에 대한 아이디어가 잘 떠오르지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핵심은 &quot;확장된 보드&quot;이다. (M + N + M) * (M + N + M) 크기의 2차원 배열로 보드를 확장해 준다. 그리고 가운데에 N * N 자물쇠를 두고, 그 주변을 전부 M * M 열쇠 크기로 꽉 채운다.&lt;br /&gt;예를 들어 N = 3, M = 3 일 경우 아래와 같은 모양이 된다.&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-filename=&quot;ㅇㅇㅇㅇ.jpg&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;878&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bnurUv/btsOvustlla/ZipxO4UX21ctANpJqePz2K/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bnurUv/btsOvustlla/ZipxO4UX21ctANpJqePz2K/img.jpg&quot; data-alt=&quot;확장된 보드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bnurUv/btsOvustlla/ZipxO4UX21ctANpJqePz2K/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbnurUv%2FbtsOvustlla%2FZipxO4UX21ctANpJqePz2K%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;549&quot; height=&quot;513&quot; data-filename=&quot;ㅇㅇㅇㅇ.jpg&quot; data-origin-width=&quot;939&quot; data-origin-height=&quot;878&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;확장된 보드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 보드를 확장하고 자물쇠를 보드 가운데 배치하면, 열쇠가 자물쇠 밖으로 빠져나간 상태로 일부만 자물쇠에 걸쳐있는 상태를 구현할 수 있다. 그렇게 자물쇠와 조금이라도 겹치는 모든 경우의 수를 전부 체크해 주면 된다. 이 아이디어만 생각해 낸다면, 나머지 구현은 그렇게까지 복잡하지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 모든 경우의 수를 검사하기만 하면 되는데, 자물쇠와 겹치는 모든 경우의 수는 아래와 같이 정의할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1749636560419&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    &quot;&quot;&quot;모든 위치에 대하여 열기 시도, 4방향 반복&quot;&quot;&quot;
    current_key = key
    for _ in range(4):
        
        for x in range(M + N):
            for y in range(M + N):
    
    # 키 90도 회전
    rotate_key(current_key)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;열쇠의 가장 왼쪽 위 칸을 기준점으로 잡는다. 즉 (x, y)좌표가 현재 열쇠의 가장 왼쪽 위 칸이 되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2중 for문의 기준이 M + N인 이유는, 해당 좌표를 넘어가는 순간 이후의 모든 좌표는 자물쇠와 전혀 겹치지 않기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 반복문을 진행하며 key값을 board에 전부 더해주고, 가운데 lock 위치에 있는 값만을 검사하여 모두 1인지 체크해 주면 된다. 검사한 후엔 다음 검사를 위해 board를 원상복구 해 주어야 한다.&lt;/p&gt;</description>
      <category>Algorithm/Implementation</category>
      <category>2020 KAKAO BLIND RECRUITMENT</category>
      <category>개발</category>
      <category>구현</category>
      <category>알고리즘</category>
      <category>완전탐색</category>
      <category>카카오 코딩테스트</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <category>프로그래머스 level 3</category>
      <category>프로그래머스 자물쇠와 열쇠</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/333</guid>
      <comments>https://yskisking.tistory.com/333#entry333comment</comments>
      <pubDate>Wed, 11 Jun 2025 19:18:47 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 / python / Level 3] 표 병합</title>
      <link>https://yskisking.tistory.com/332</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;517&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EcXKJ/btsOrr3AAP1/m5QyhI0OzAAPM9u4ZDiba0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EcXKJ/btsOrr3AAP1/m5QyhI0OzAAPM9u4ZDiba0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EcXKJ/btsOrr3AAP1/m5QyhI0OzAAPM9u4ZDiba0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEcXKJ%2FbtsOrr3AAP1%2Fm5QyhI0OzAAPM9u4ZDiba0%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;1050&quot; height=&quot;517&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;517&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;1030&quot; data-origin-height=&quot;637&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dXesDH/btsOrvycO4x/kGdv9NyEoj4zuAW0sbgk4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dXesDH/btsOrvycO4x/kGdv9NyEoj4zuAW0sbgk4k/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dXesDH/btsOrvycO4x/kGdv9NyEoj4zuAW0sbgk4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdXesDH%2FbtsOrvycO4x%2FkGdv9NyEoj4zuAW0sbgk4k%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;1030&quot; height=&quot;637&quot; data-origin-width=&quot;1030&quot; data-origin-height=&quot;637&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023 KAKAO BLIND RECRUITMENT에 출제된 문제로써, &lt;b&gt;Union-Find&lt;/b&gt;가 사용되는 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Union-Find는 특정 그룹으로 묶고, 나누고, 그룹을 찾고 하는 것에 특화된 알고리즘이며, 표 병합같은 문제에 딱 맞는 알고리즘이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749299306335&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(commands):

    &quot;&quot;&quot;
    find: 대표를 찾는 함수, 재귀 구현
    union: 병합 함수, merge 구현
    &quot;&quot;&quot;
    
    &quot;&quot;&quot;1차원 리스트 사용, 처음엔 자기 자신이 대표&quot;&quot;&quot;
    parent = [i for i in range(2601)]
    values = [&quot;&quot; for _ in range(2601)]  # 처음엔 전부 빈 값
    
    &quot;&quot;&quot;좌표를 1차원 인덱스로 변환하는 함수&quot;&quot;&quot;
    def get_idx(r, c):
        return r * 51 + c
    
    &quot;&quot;&quot;1차원 인덱스를 좌표로 변환하는 함수&quot;&quot;&quot;
    def get_coordinate(idx):
        return (idx // 51, idx % 51)
        
    &quot;&quot;&quot;
    해당 좌표의 대표를 리턴하는 함수
    대표를 찾는 재귀호출 과정에서 거치는, 모든 좌표의 부모를 대표로 바꾼다
    &quot;&quot;&quot;
    def find(idx):
        if idx != parent[idx]:  # 자기 자신이 대표가 아닐 경우
            parent[idx] = find(parent[idx])
            
        return parent[idx]
    
    &quot;&quot;&quot;병합 함수&quot;&quot;&quot;
    def union(x, y):
        x_root = find(x)
        y_root = find(y)
        
        # 이미 같은 그룹이면 병합하지 않는다
        if x_root == y_root:
            return
        
        if values[y_root] == &quot;&quot;:
            parent[y_root] = x_root
        elif values[x_root] == &quot;&quot;:
            parent[x_root] = y_root
        else:
            parent[y_root] = x_root
    
    &quot;&quot;&quot;메인 로직&quot;&quot;&quot;
    result = []
    for command in commands:
        cmd = command.split()
        
        if len(cmd) == 4:
            &quot;&quot;&quot;UPDATE r c value&quot;&quot;&quot;
            r, c = map(int, cmd[1:3])
            value = cmd[-1]
            
            # 대표의 값을 변경
            root = find(get_idx(r, c))
            values[root] = value
            
        
        elif len(cmd) == 5:
            &quot;&quot;&quot;MERGE r1 c1 r2 c2&quot;&quot;&quot;
            r1, c1, r2, c2 = map(int, cmd[1:])
            idx1 = get_idx(r1, c1)
            idx2 = get_idx(r2, c2)
            
            # 병합
            union(idx1, idx2)
        
        elif cmd[0] == 'UPDATE':
            &quot;&quot;&quot;UPDATE value1 value2&quot;&quot;&quot;
            value1, value2 = cmd[1], cmd[2]
            
            # 대표의 값만 바꾼다
            for i in range(2601):
                if parent[i] == i and values[i] == value1:
                    values[i] = value2
        
        elif cmd[0] == 'UNMERGE':
            &quot;&quot;&quot;UNMERGE r c&quot;&quot;&quot;
            r, c = map(int, cmd[1:])
            origin_idx = get_idx(r, c)
            root_idx = find(origin_idx)
            saved_value = values[root_idx]
            
            # r,c와 같은 그룹의 모든 셀을 독립적으로 바꾸고 값을 지운다
            unmerge_list = []
            for idx in range(2601):
                if root_idx == find(idx):
                    unmerge_list.append(idx)
            
            for idx in unmerge_list:
                parent[idx] = idx
                values[idx] = &quot;&quot;
            
            # 지정 셀만 기존 값 복원
            values[origin_idx] = saved_value
        
        elif cmd[0] == 'PRINT':
            &quot;&quot;&quot;PRINT r c&quot;&quot;&quot;
            r, c = map(int, cmd[1:])
            root_idx = find(get_idx(r, c))
            
            value = values[root_idx]
            if value == '': value = 'EMPTY'
            
            result.append(value)
    
    return result&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제에서 주어진 표의 크기는 50 * 50으로 고정되어 있다. 즉 2차원 배열인데, 편리하게 다루기 위해 1차원 배열로 변경한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차원 -&amp;gt; 1차원 변환 공식은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1749299468767&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;
    2차원 -&amp;gt; 1차원 변환
    크기: 50 * 50
    좌표: (3,4)
    
    0 based
    배열 크기: rows * cols
    1차원 인덱스 변환: r * cols + c
    2차원 인덱스 추적: idx // cols, idx % cols
    -&amp;gt; 2500, 154, (3, 4)
    
    1 based
    배열 크기: (rows + 1) * (cols + 1)
    1차원 인덱스 변환: r * (cols+1) + c
    2차원 인덱스 추적: idx // (cols+1), idx % (cols+1)
    -&amp;gt; 2601, 157, (3, 4)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 1 based가 기준인 문제이다. 따라서 배열 크기는 51 * 51 = 2601 로 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;parent[i]는 i의 부모 인덱스를 의미한다. 만약 parent[i] == i 일 경우, 자기 자신이 대표라는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;values[i]는 i 위치에 있는 값을 의미한다. 우리는 이 문제에서, 대표 위치에만 값을 저장하고 갱신할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;find 함수가 핵심인데, 자기 자신이 대표가 아닐 경우 재귀적으로 parent 를 따라가며 최종 대표를 찾는다. 또한 재귀호출 과정에서 거치는 모든 그룹원들의 parent 값을 대표의 값으로 바꾼다. 즉, 5번 재귀를 거쳐 대표를 한번 찾았다면 그 다음 대표 탐색 과정에서는 5번이 아니라 단 한번 O(1)에 대표를 찾을 수 있다는 뜻이다. 이것을 경로 압축이라고 하며, Union-Find 알고리즘의 핵심이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;union 함수는 병합 함수이다. x, y 두 좌표를 받아서 특정 한 그룹에게 병합한다. 병합은 한 그룹의 대표가 나머지 한 그룹의 대표를 부모로 가짐으로써 이루어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지 명령어 파싱 및 분기처리는 많이 어렵진 않았다. 조건이 많고 복잡해서 구현할 때 실수가 잦을 수 있다는 것 뿐이지, 요구사항 자체가 이해하기 어려운 정도는 아니었다. 문제 요구사항을 잘 읽고 집중해서 구현하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 한 가지 신경써야 할 부분이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749299901862&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; # UNMERGE 로직 일부
 
 # 문제 코드
 	    for idx in range(2601):
            	if root_idx == find(idx):
                    parent[idx] = idx
                    values[idx] = &quot;&quot;
 
 # 통과 코드
            unmerge_list = []
            for idx in range(2601):
                if root_idx == find(idx):
                    unmerge_list.append(idx)
            
            for idx in unmerge_list:
                parent[idx] = idx
                values[idx] = &quot;&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여긴 UNMERGE 코드의 일부인데, 한 그룹을 분쇄시키는 로직이다. 같은 대표를 가진, 즉 같은 그룹의 모든 그룹원들을 독립적으로 만들고 그룹을 해체하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 보면 문제 코드는 그룹원을 찾자마자 독립시키고, 통과 코드는 그룹원을 미리 전부 찾은 후 독립시킨다. 즉 탐색과 독립이 따로다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 보면 별 차이 없어 보이지만, 첫 번째 코드에서 find() 가 문제가 될 수 있다. find()는 대표를 찾는 역할도 하지만, 대표를 찾으면서 거쳐간 그룹원들의 parent를 전부 대표로 수정한다. 얼핏 보면 아무 문제 없어 보일 수 있지만, 탐색 -&amp;gt; 바꾸기 -&amp;gt; 탐색 -&amp;gt; 바꾸기 하는 과정에서 그룹원들의 연관관계가 꼬여 문제가 일어난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3 -&amp;gt; 1 -&amp;gt; 5 -&amp;gt; 7(대표) 관계가 있다고 했을 때,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;parent[1]을 1로 바꿨을 경우, (독립)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;find(3)을 하면 7까지 이어져야 했지만 1은 자기 자신을 가리키므로 7까지 이어지지 못하고 끊어져 버린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 통과 코드처럼, 독립시킬 그룹원을 미리 전부 찾은 후 parent를 바꿔 줘야 예기치 못한 문제가 발생하지 않는다. 이런 점들은 이 문제에서뿐만 아니라, 실무 비즈니스 로직을 작성할 때도 신경써줘야 한다고 생각한다.&lt;/p&gt;</description>
      <category>Algorithm/Union-Find</category>
      <category>2023 KAKAO BLIND RECRUITMENT</category>
      <category>Union-find</category>
      <category>개발</category>
      <category>알고리즘</category>
      <category>유니온파인드</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <category>표 병합</category>
      <category>프로그래머스 level 3</category>
      <category>프로그래머스 표 병합</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/332</guid>
      <comments>https://yskisking.tistory.com/332#entry332comment</comments>
      <pubDate>Sat, 7 Jun 2025 21:44:16 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 / python / Level 3] 양과 늑대</title>
      <link>https://yskisking.tistory.com/331</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfodNR/btsOqF8Rt5D/DtZI5A9gl6NeqdMBBzJM21/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfodNR/btsOqF8Rt5D/DtZI5A9gl6NeqdMBBzJM21/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfodNR/btsOqF8Rt5D/DtZI5A9gl6NeqdMBBzJM21/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfodNR%2FbtsOqF8Rt5D%2FDtZI5A9gl6NeqdMBBzJM21%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;646&quot; height=&quot;230&quot; data-origin-width=&quot;767&quot; data-origin-height=&quot;273&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;773&quot; data-origin-height=&quot;686&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coNxVM/btsOrlWGrvY/oy2NO61jxxaDT1455hFJM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coNxVM/btsOrlWGrvY/oy2NO61jxxaDT1455hFJM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coNxVM/btsOrlWGrvY/oy2NO61jxxaDT1455hFJM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcoNxVM%2FbtsOrlWGrvY%2Foy2NO61jxxaDT1455hFJM0%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;659&quot; height=&quot;585&quot; data-origin-width=&quot;773&quot; data-origin-height=&quot;686&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;766&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/chnAKZ/btsOsWOuFX9/noRBA5TcofKLJ5z5R6K7uK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/chnAKZ/btsOsWOuFX9/noRBA5TcofKLJ5z5R6K7uK/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/chnAKZ/btsOsWOuFX9/noRBA5TcofKLJ5z5R6K7uK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FchnAKZ%2FbtsOsWOuFX9%2FnoRBA5TcofKLJ5z5R6K7uK%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;646&quot; height=&quot;440&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2022 KAKAO BLIND RECRUITMENT 출제 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BFS가 메인이고 상태 관리 로직이 필요하다. 카카오 문제들은 자료구조의 선택에 대해서도 많이 생각하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749205914601&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from collections import defaultdict, deque

def solution(info, edges):
    
    &quot;&quot;&quot;인접 딕셔너리 만들기 (부모 -&amp;gt; 자식 단방향)&quot;&quot;&quot;
    graph = defaultdict(list)
    for parent, child in edges:
        graph[parent].append(child)
    
    &quot;&quot;&quot;큐 기본값 설정&quot;&quot;&quot;
    # list는 삭제/탐색연산 느려서 set 쓴다
    # 어차피 상태관리 visited로 하고 완전탐색이라 순서 상관없기에 set
    queue = deque([(1, 0, set(graph[0]))])
    
    visited = set()
    max_sheep = 1  # 루트 노드는 무조건 양이다. 최소 1마리
    
    &quot;&quot;&quot;메인 BFS 로직&quot;&quot;&quot;
    while queue:
        sheep, wolf, possible = queue.popleft()
        
        # 이미 방문한 상태라면 continue
        state = (sheep, wolf, tuple(sorted(possible)))
        if state in visited:
            continue
        visited.add(state)
        
        # 양 최대 마릿수 갱신
        max_sheep = max(max_sheep, sheep)
        
        # 양, 늑대 노드 나누기
        sheep_nodes = [node for node in possible if info[node] == 0]
        wolf_nodes = [node for node in possible if info[node] == 1]
        
        # 양 노드는 전부 방문
        for node in sheep_nodes:
            new_possible = possible.copy()  # 내용물이 int(불변) 이므로 copy 안전
            new_possible.remove(node)  # 방문할 노드 삭제
            new_possible.update(graph[node])  # 방문 가능 노드 추가 (list여도 update에 의해 각각 set요소로 들어감)
            
            queue.append((sheep + 1, wolf, new_possible))
        
        # 늑대 노드는 안전할 경우 방문
        for node in wolf_nodes:
            if sheep &amp;gt; wolf + 1:
                new_possible = possible.copy()
                new_possible.remove(node)
                new_possible.update(graph[node])
                
                queue.append((sheep, wolf + 1, new_possible))
    
    return max_sheep&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음엔 백트래킹을 생각했지만, 단순 DFS/BFS로는 풀리지 않는다는 걸 알았다. 지금은 방문할 수 없지만 다른 노드를 거치고 돌아와 다시 방문하는 경우의 수도 있기 때문이다. 따라서 단순 완전탐색으로는 풀리지 않고, &lt;b&gt;상태 관리&lt;/b&gt;를 이용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(양의 수, 늑대 수, 방문 가능한 노드들) 을 상태로써 관리한다. &lt;b&gt;기본적으로 BFS&lt;/b&gt;를 진행하되, 인접 노드를 순서대로 방문하는 것이 아니라, queue에 저장된 방문 가능한 노드들을 기준으로 방문한다. 우선 다음 노드가 양이라면 무조건 방문할 수 있고, possible(방문가능 노드 집합)에서 방문할 노드를 지우고 방문할 노드와 연결된(자식) 노드를 possible에 넣는다. 이렇게 하면 노드 방문 순서에 구애받지 않고 현재 방문 가능한 노드만 선택적으로 방문할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;방문 가능 노드&quot; 라는 건 &quot;안전한 노드&quot;를 의미하는 게 아니다. 안전한 노드는 방문해도 양이 잡아먹히지 않는 노드이며, 이것은 양/늑대 노드를 구분하여, 늑대 노드에 대해 sheep &amp;gt; wolf + 1 조건검사를 함으로써 구분한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 visited를 사용하는데, 여기에도 (양의 수, 늑대 수, 방문 가능한 노드들)&amp;nbsp; 즉 &quot;상태&quot;를 넣는다. 이것은 중복된 상태, 중복된 경로 즉 중복된 경우의 수를 다시 검사하지 않게 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 방문 가능 노드를 while문으로 방문하며, 최대 양 마릿수를 계속 갱신해 주면 된다. 뭐랄까.. 하나의 스레드가 탐색하는 느낌보다는 멀티스레드가 각각의 상태를 가지고 동시에 탐색하고 있다고 생각하면 될 것 같다. 막힌 애는 버려지고, 막히지 않은 애는 새로운 상태를 생성하고.&lt;/p&gt;</description>
      <category>Algorithm/BFS</category>
      <category>2022 KAKAO BLIND RECRUITMENT</category>
      <category>BFS</category>
      <category>그래프</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <category>파이썬 deque</category>
      <category>파이썬 set</category>
      <category>프로그래머스 level 3</category>
      <category>프로그래머스 양과 늑대</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/331</guid>
      <comments>https://yskisking.tistory.com/331#entry331comment</comments>
      <pubDate>Fri, 6 Jun 2025 19:39:58 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 / python / Level 3] 불량 사용자</title>
      <link>https://yskisking.tistory.com/330</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;464&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cNRyZD/btsOqSl7nVX/odU06pXdV5yvIKeWrqcXu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cNRyZD/btsOqSl7nVX/odU06pXdV5yvIKeWrqcXu1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cNRyZD/btsOqSl7nVX/odU06pXdV5yvIKeWrqcXu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcNRyZD%2FbtsOqSl7nVX%2FodU06pXdV5yvIKeWrqcXu1%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;968&quot; height=&quot;464&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;464&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;968&quot; data-origin-height=&quot;498&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NhyJ8/btsOrZrc0tC/UXsn2ovahCq1trmHrpfmb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NhyJ8/btsOrZrc0tC/UXsn2ovahCq1trmHrpfmb1/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NhyJ8/btsOrZrc0tC/UXsn2ovahCq1trmHrpfmb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNhyJ8%2FbtsOrZrc0tC%2FUXsn2ovahCq1trmHrpfmb1%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;968&quot; height=&quot;498&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;498&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2019 카카오 개발자 겨울 인턴십에 출제된 백트래킹 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어지는 입력값의 크기가 크지 않아, 완전탐색으로도 풀린다고 들었지만 백트래킹이 정석인 문제라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749115361382&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(user_id, banned_id):
    
    def is_match(user, banned_user):
        if len(user) != len(banned_user):
            return False
        
        for i in range(len(user)):
            if banned_user[i] != '*' and banned_user[i] != user[i]:
                return False
        return True
    
    def back_tracking(depth, selected):
        
        if depth == len(banned_id):
            result_set.add(frozenset(selected))  # 순서가 다른것도 중복으로 인식하도록 frozenset 사용
            return
        
        for user in user_id:
            if user not in selected and is_match(user, banned_id[depth]):
                selected.add(user)
                back_tracking(depth + 1, selected)
                selected.remove(user)
            
            
            
    # set으로 바꿔 중복 제거 (순서만 다른 조합들)
    result_set = set()
    back_tracking(0, set()) # not in 연산 효율성을 위해 set 선택(key로 접근하는 O(1)), 리스트는 O(N)
    
    return len(result_set)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;banned_id의 조건에 일치하는 사용자 조합을 전부 만들어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;banned_id는 user_id 의 길이보다 짧거나 같고, banned_id와 매핑되는 user_id는 1개씩이니 최대 depth는 len(banned_id)로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단 백트래킹 진행 중 순서만 다른 같은 조합이 나올 수 있는데, 이것은 맨 마지막에 set()으로 집합화 시켜서 중복을 제거해주되,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순서만 다른 조합을 같은 요소라고 인식할 수 있도록 result_set에 넣을 때 frozenset()으로 감싸서 넣어준다. frozenset()은 immutable객체로써 set()의 요소로 사용할 수 있고, 순서만 다른 요소를 같은 요소라고 인식하기 때문에 set()으로 중복을 제거하기 용이하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 back_tracking의 2번째 인자인 selected를 set()으로 넣어주고 있는데, 이것은 not in 연산을 빠르게 하기 위해서이다. list를 넣을 경우 not in 조건 검사를 할 때마다 O(N)의 연산이 일어나고, 백트래킹의 재귀 방식 특성 상 해당 조건을 엄청나게 많이 검사하게 된다. 이때 list가 아닌 set을 사용하면, set은 내부적으로 해시 테이블을 사용하기 때문에 O(1) 즉 상수 시간에 탐색할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로, len(result_set)을 리턴함으로써 만들어진 경우의 수 개수를 리턴해주면 된다.&lt;/p&gt;</description>
      <category>2019 카카오 개발자 겨울 인턴십</category>
      <category>DFS</category>
      <category>그래프</category>
      <category>백트래킹</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>파이썬 frozenset</category>
      <category>파이썬 set</category>
      <category>프로그래머스 level 3</category>
      <category>프로그래머스 불량 사용자</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/330</guid>
      <comments>https://yskisking.tistory.com/330#entry330comment</comments>
      <pubDate>Thu, 5 Jun 2025 18:32:00 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 / python / Level 2] 순위 검색</title>
      <link>https://yskisking.tistory.com/329</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Nzqj6/btsOqggbAm4/JeyEtUTKPesf3aKotu4la0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Nzqj6/btsOqggbAm4/JeyEtUTKPesf3aKotu4la0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Nzqj6/btsOqggbAm4/JeyEtUTKPesf3aKotu4la0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNzqj6%2FbtsOqggbAm4%2FJeyEtUTKPesf3aKotu4la0%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;1125&quot; height=&quot;550&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;550&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;1132&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KRR9C/btsOpwREbXq/MmB0FmwU6pWLsDCnnBWDBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KRR9C/btsOpwREbXq/MmB0FmwU6pWLsDCnnBWDBk/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KRR9C/btsOpwREbXq/MmB0FmwU6pWLsDCnnBWDBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKRR9C%2FbtsOpwREbXq%2FMmB0FmwU6pWLsDCnnBWDBk%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;1132&quot; height=&quot;480&quot; data-origin-width=&quot;1132&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2021 KAKAO BLIND RECRUITMENT 출제 문제이다. Level 2이긴 한데 왜 2인지 전혀 모르겠고, 내가 느끼기엔 최소 Level 3이고 백준으로 치면 골드 4이상이 아닌가 싶다. 그냥 개인적 느낌이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순 이분탐색만 사용되는 것이 아니라 해시, 조합, 문자열 파싱 등 다양한 알고리즘이 활용되고 구현요소도 많아서 실수할 부분이 매우 많고 복잡하다. 카카오 문제는 다 이런 거 같다. 하나의 알고리즘만 보는 게 아닌 이런저런 알고리즘을 조합하여 구현처럼 만들어내는 것.. 특히 초보자들에겐 더욱 어려운 것 같다. 나에게도 어렵고.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1749103561731&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from collections import defaultdict
from itertools import product
import bisect

def solution(info, query):
    
    def get_all_combinations(conditions):
        &quot;&quot;&quot;
        무관('-')을 포함한 2^4(16)개의 조합을 만듭니다.
        &quot;&quot;&quot;
        choices = []
        for condition in conditions:
            choices.append([condition, '-'])
        
        # 16개 조합 리턴
        return list(product(*choices))
    
    def parse_query(q):
        &quot;&quot;&quot;
        쿼리를 조건과 코테점수로 나누어 리턴합니다.
        &quot;&quot;&quot;
        parts = q.replace(' and ', ' ').split()
        conditions = tuple(parts[:4])
        target_score = int(parts[-1])
        
        return conditions, target_score
    
    def binary_search(scores, target):
        &quot;&quot;&quot;
        이분 탐색
        scores 리스트에서 target 이상인 요소의 개수를 리턴합니다.
        &quot;&quot;&quot;
        idx = bisect.bisect_left(scores, target)
        return len(scores) - idx
        
    
    &quot;&quot;&quot;모든 쿼리 경우의 수를 key로 가지고, 점수 리스트를 value로 매핑하는 딕셔너리&quot;&quot;&quot;
    score_dict = defaultdict(list)
    
    &quot;&quot;&quot;
    모든 지원자 데이터 전처리
    &quot;-&quot;(무관) 데이터를 포함한 모든 경우의 수를 key로 하는 딕셔너리 생성
    value엔 key조건에 해당하는 지원자의 점수 리스트 할당
    &quot;&quot;&quot;
    for person in info:
        parts = person.split()
        conditions = parts[:4]
        score = int(parts[-1])
        
        # 생성되거나/존재하는 모든 key에 점수 추가
        for combination in get_all_combinations(conditions):
            score_dict[combination].append(score)
    
    &quot;&quot;&quot;이분 탐색을 위한 점수 리스트 정렬&quot;&quot;&quot;
    for key in score_dict:
        score_dict[key].sort()
        
    &quot;&quot;&quot;메인 로직&quot;&quot;&quot;
    result = []
    
    for q in query:
        
        # 쿼리 파싱
        conditions, target_score = parse_query(q)
        
        # 쿼리에 맞는 점수 리스트 가져오기
        scores = score_dict[conditions]
        
        # 이분 탐색으로 target_score 이상인 개수 구하기
        count = binary_search(scores, target_score)
        result.append(count)
        
    return result&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 문제를 읽고 트리 자료구조와 재귀함수를 이용한 접근법을 떠올렸지만, 구현이 너무 복잡해 져서 포기했다. 그래도 데이터를 미리 분류해 두는 접근방법 자체는 일치했으니 그걸로 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 이 문제는, 모든 쿼리에 대해 모든 지원자를 일일이 검토하면 시간 초과가 나온다. 단순하게 계산하여 지원자(50000) * 쿼리(100000) 만 해봐도 바로 50억이 떠버린다. 단순 완전탐색으로는 해결할 수 없다.&lt;/p&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;가 중요하다. 마치 dp 테이블을 만드는 것 처럼 딕셔너리에 미리 데이터를 분류해 둔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 조건(언어, 직무, 경력, 소울푸드)에 무관('-') 까지 포함해 가능한 모든 조합을 만들게 되면, 총 108개의 키를 가진 딕셔너리가 완성된다. 그리고 해당 key의 value로는, 그 조건에 해당하는 지원자들의 코테 점수를 리스트로 저장해둔다. 이러면 해시 테이블 특성 상 데이터에 key로 접근할 수 있게 되어, O(1) 상수 시간에 query에 대한 코테 점수 리스트를 얻을 수 있게 된다. 물론 전처리 단계 자체는 O(N) 이긴 하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 코테 점수 리스트를 얻었다고 해도, 점수를 만족하는 지원자를 찾기 위해서 완전탐색을 하게 되면 또 시간초과가 난다. 예를 들어 모든 조건이 무관인 쿼리가 있다고 하면, 모든 사용자의 코테 점수(50000개)를 전부 탐색해야 한다. 이런 쿼리가 100000개 라면? 50000 * 100000 = 50억 으로 데이터 전처리를 한 것이 의미없게 되고 시간초과가 난다.&lt;/p&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;Q: 10만 (쿼리 수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;N: 5만 (지원자 수)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 할 때:&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간 복잡도는 O(Q * N) -&amp;gt; O(QlogN) 로 개선되고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연산 횟수는 50억 -&amp;gt; 160만번 정도로 줄어들게 된다.&lt;/p&gt;</description>
      <category>Algorithm/Binary Search</category>
      <category>2021 KAKAO BLIND RECRUITMENT</category>
      <category>데이터 전처리</category>
      <category>알고리즘</category>
      <category>이분 탐색</category>
      <category>조합</category>
      <category>코딩테스트</category>
      <category>파이썬 product</category>
      <category>프로그래머스 level 2</category>
      <category>프로그래머스 순위 검색</category>
      <category>해시</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/329</guid>
      <comments>https://yskisking.tistory.com/329#entry329comment</comments>
      <pubDate>Thu, 5 Jun 2025 15:26:06 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 / python / Level 3] 주사위 고르기</title>
      <link>https://yskisking.tistory.com/328</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2517&quot; data-origin-height=&quot;1099&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGCxQv/btsOovjrSZg/p4YoaekOh7Qr9KzQN50wK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGCxQv/btsOovjrSZg/p4YoaekOh7Qr9KzQN50wK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGCxQv/btsOovjrSZg/p4YoaekOh7Qr9KzQN50wK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGCxQv%2FbtsOovjrSZg%2Fp4YoaekOh7Qr9KzQN50wK1%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;2517&quot; height=&quot;1099&quot; data-origin-width=&quot;2517&quot; data-origin-height=&quot;1099&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;2540&quot; data-origin-height=&quot;1062&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/obLJI/btsOm8ihphM/j7usE1pNHTVZdjdnMCYrAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/obLJI/btsOm8ihphM/j7usE1pNHTVZdjdnMCYrAk/img.png&quot; data-alt=&quot;문제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/obLJI/btsOm8ihphM/j7usE1pNHTVZdjdnMCYrAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FobLJI%2FbtsOm8ihphM%2Fj7usE1pNHTVZdjdnMCYrAk%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;2540&quot; height=&quot;1062&quot; data-origin-width=&quot;2540&quot; data-origin-height=&quot;1062&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;문제&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024 KAKAO WINTER INTERNSHIP 3번 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아주 어려운 문제였다. 알고리즘 분류도 애매하다. 완전탐색, 조합, 구현, 이분탐색 정도일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 가지 알고리즘이 복합적으로 쓰이고, 완전탐색 -&amp;gt; 이분탐색 아이디어를 떠올리기도 쉽지 않은 문제였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 Level 3 중에서 가장 어려운 편 아닌가 싶고, 3번 문제로 나온 건 난이도 조절 실패인 것 같다(개인적 의견).&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;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1748953107011&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from itertools import combinations, product

def binary_search(arr, target):
    &quot;&quot;&quot;
    이분 탐색
    정렬된 점수 합 리스트를 받아, target보다 작은 요소의 개수를 반환합니다.
    &quot;&quot;&quot;
    
    start = 0
    end = len(arr) - 1
    result = 0
    
    while start &amp;lt;= end:
        
        mid = (start + end) // 2
        
        if arr[mid] &amp;lt; target:
            result = mid + 1
            start = mid + 1
            
        else:
            end = mid - 1
    
    return result

def get_all_sums(dices):
    &quot;&quot;&quot;
    주사위 리스트를 받아, 정렬된 모든 합 경우의 수 리스트를 리턴합니다.
    순서를 고려하는 product 입니다.
    &quot;&quot;&quot;
    
    result = [sum(scores) for scores in product(*dices)]
    return sorted(result)

def solution(dice):
    &quot;&quot;&quot;
    주사위 고르는 경우의 수 구하기 C(n,r) (combination)
    고른 주사위에 대한 점수 합 각각 구하기(6^r + 6^r) (product)
    이분 탐색으로 A가 이기는 횟수 구하기
    -&amp;gt; A의 모든 합을 순회하며, B합 리스트에 대해 이분 탐색
    &quot;&quot;&quot;
    
    n = len(dice)
    
    # A가 선택한 모든 주사위 인덱스 리스트
    a_all_dices_idx = list(combinations(range(n), n//2))
    
    max_win_count = -1
    best_combination = None
    
    # A가 선택한 모든 주사위 경우의 수에 대해 반복
    for a_dices_idx in a_all_dices_idx:
        
        # B가 선택한 주사위 인덱스
        b_dices_idx = [i for i in range(n) if i not in a_dices_idx]
        
        # 인덱스를 실제 주사위 값으로 변환
        a_dices = [dice[i] for i in a_dices_idx]
        b_dices = [dice[i] for i in b_dices_idx]
        
        # 선택한 주사위로 모든 점수 합 경우의 수 구하기 (각 7776개)
        a_sums = get_all_sums(a_dices)
        b_sums = get_all_sums(b_dices)
        
        # 이분 탐색으로 A의 승리 횟수 구하기
        win_count = 0
        for a_sum in a_sums:
            win_count += binary_search(b_sums, a_sum)
        
        # 승리 횟수 최대값 갱신 및 리턴값 생성
        if win_count &amp;gt; max_win_count:
            max_win_count = win_count
            best_combination = a_dices_idx
    
    return sorted([i + 1 for i in best_combination])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A, B가 점수가 다른 주사위 n 개 중 각각 n / 2 개를 고르고, A가 승리할 확률이 가장 높은 주사위 조합을 고르는 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n은 10 이하이고 주사위는 6개의 면을 가지고 있다. 만약 완전탐색으로 접근할 경우 무조건 시간초과가 난다고 보면 된다. 최대 연산횟수가 약 150억번 정도이기 때문이다.&lt;/p&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개의 조합을 구해야 한다. 문제 해설은 주사위 10개(n = 10) 기준으로 하겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;n = 10&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;r = n // 2 (5)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 주사위 5개를 선택하는 경우의 수: &lt;b&gt;C(n, r) -&amp;gt; 252개&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. A, B가 선택한 주사위에 대한 모든 점수 합 경우의 수: &lt;b&gt;6^r -&amp;gt; 7776개&lt;/b&gt; (A, B 각각이므로 7776 * 2)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, 모든 경우의 수를 일일이 비교할 경우 시간 복잡도는 &lt;b&gt;(C(n, r) * n^2) , 즉 N^2&lt;/b&gt;이 되고, 252 * (7776 * 7776) 이므로 &lt;b&gt;약 150억번&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;따라서 A가 승리하는 횟수를 구하는 부분을 완전탐색이 아닌 &lt;b&gt;이분탐색으로 개선&lt;/b&gt;해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A, B의 점수 합 리스트를 따로 구한 후, A리스트를 순회하며(7776번) B리스트에서 몇 개의 요소가 A의 target보다 작은가를 세면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러면 기존 &lt;b&gt;완전탐색 N^2 -&amp;gt; 이분탐색 NlogN&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;모든 주사위 경우의 수(252)를 반복하되, 그 안에서 해당 주사위로 계산된 점수 합 리스트(7776)를 반복하며 이분탐색을 하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 one based 형태로 주사위 인덱스를 1 더해 리턴해 주면 된다.&lt;/p&gt;</description>
      <category>Algorithm/Binary Search</category>
      <category>2024 kakao winter internship 3번문제</category>
      <category>구현</category>
      <category>알고리즘</category>
      <category>이분 탐색</category>
      <category>조합</category>
      <category>코딩테스트</category>
      <category>파이썬 combination</category>
      <category>파이썬 product</category>
      <category>프로그래머스 level 3</category>
      <category>프로그래머스 주사위 고르기</category>
      <author>양선규</author>
      <guid isPermaLink="true">https://yskisking.tistory.com/328</guid>
      <comments>https://yskisking.tistory.com/328#entry328comment</comments>
      <pubDate>Tue, 3 Jun 2025 21:31:31 +0900</pubDate>
    </item>
  </channel>
</rss>