<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>일단은 내 이야기</title>
    <link>https://kdhyo98.tistory.com/</link>
    <description>Backend 개발자지만 사이드프로젝트 하고싶어.</description>
    <language>ko</language>
    <pubDate>Tue, 21 Jul 2026 20:38:34 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Hyo Kim</managingEditor>
    <image>
      <title>일단은 내 이야기</title>
      <url>https://tistory1.daumcdn.net/tistory/3949735/attach/0d18833a34c44b98b115bf3e98e6fd97</url>
      <link>https://kdhyo98.tistory.com</link>
    </image>
    <item>
      <title>컴퓨터 비전이란? 주요 개념과 과제 정리</title>
      <link>https://kdhyo98.tistory.com/148</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ChatGPT Image 2025년 8월 19일 오후 04_35_24.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tQvmc/btsQAdNXMgo/E96dtWUDrnPtHdORmRgbRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tQvmc/btsQAdNXMgo/E96dtWUDrnPtHdORmRgbRk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tQvmc/btsQAdNXMgo/E96dtWUDrnPtHdORmRgbRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtQvmc%2FbtsQAdNXMgo%2FE96dtWUDrnPtHdORmRgbRk%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;425&quot; height=&quot;425&quot; data-filename=&quot;ChatGPT Image 2025년 8월 19일 오후 04_35_24.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-pm-slice=&quot;0 0 []&quot; data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;heading&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size26&quot;&gt;Computer Vision(컴퓨터 비전)?&lt;/h2&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;Computer + Vision의 합성어로, &lt;b&gt;시각 데이터를 처리&amp;middot;이해하는 분야&lt;/b&gt;를 뜻한다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;카메라와 센서가 인간의 눈 역할을 한다면, 컴퓨터 비전은 이러한 시각 데이터를 처리&amp;middot;해석하는 인지 능력이다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;AI가 컴퓨터에 &lt;b&gt;&amp;ldquo;생각&amp;rdquo;&lt;/b&gt;을 부여한다면,&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;컴퓨터 비전은 컴퓨터가 보고 관찰하며 이해하도록 만드는 기술이라고 할 수 있다.&lt;/p&gt;
&lt;h3 data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;heading&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size23&quot;&gt;컴퓨터 비전의 주요 과제&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;orderedList&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;listItem&quot; data-prosemirror-content-type=&quot;node&quot;&gt;Classification (이미지 분류)&lt;/li&gt;
&lt;li data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;listItem&quot; data-prosemirror-content-type=&quot;node&quot;&gt;Object Detection (객체 탐지)&lt;/li&gt;
&lt;li data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;listItem&quot; data-prosemirror-content-type=&quot;node&quot;&gt;Image Segmentation (이미지 분할)
&lt;ol style=&quot;list-style-type: decimal;&quot; data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;orderedList&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;listItem&quot; data-prosemirror-content-type=&quot;node&quot;&gt;Semantic Segmentation&lt;/li&gt;
&lt;li data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;listItem&quot; data-prosemirror-content-type=&quot;node&quot;&gt;Instance Segmentation&lt;/li&gt;
&lt;li data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;listItem&quot; data-prosemirror-content-type=&quot;node&quot;&gt;Panoptic Segmentation&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;mediaSingle&quot; data-prosemirror-content-type=&quot;node&quot; data-media-vc-wrapper=&quot;true&quot;&gt;
&lt;div data-media-vc-wrapper=&quot;true&quot; data-width-type=&quot;pixel&quot; data-width=&quot;647&quot; data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhaihG/btsQxErKOt6/tJbIKcXvP5vVxt9whpmRmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhaihG/btsQxErKOt6/tJbIKcXvP5vVxt9whpmRmk/img.png&quot; data-alt=&quot;목록&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhaihG/btsQxErKOt6/tJbIKcXvP5vVxt9whpmRmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhaihG%2FbtsQxErKOt6%2FtJbIKcXvP5vVxt9whpmRmk%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;647&quot; height=&quot;268&quot; data-origin-width=&quot;647&quot; data-origin-height=&quot;268&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;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;heading&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size26&quot;&gt;1. Classification (이미지 분류)&lt;/h2&gt;
&lt;div data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;mediaSingle&quot; data-prosemirror-content-type=&quot;node&quot; data-media-vc-wrapper=&quot;true&quot;&gt;
&lt;div data-media-vc-wrapper=&quot;true&quot; data-width-type=&quot;pixel&quot; data-width=&quot;760&quot; data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;800&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8xVlv/btsQybQna5y/L8xk5tTYZKKOg77TGntuxK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8xVlv/btsQybQna5y/L8xk5tTYZKKOg77TGntuxK/img.png&quot; data-alt=&quot;classification&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8xVlv/btsQybQna5y/L8xk5tTYZKKOg77TGntuxK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8xVlv%2FbtsQybQna5y%2FL8xk5tTYZKKOg77TGntuxK%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;1200&quot; height=&quot;800&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;800&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;classification&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 &lt;b&gt;클래스(범주)&lt;/b&gt;별로 분류하는 작업이다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;주로 &lt;b&gt;지도 학습(Supervised Learning)&lt;/b&gt;으로 수행되며,&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;기존 데이터에서 각 클래스 간의 관계를 학습하고&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;새롭게 관측된 이미지가 어느 클래스에 속하는지 스스로 판별한다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;heading&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size26&quot;&gt;2. Object Detection (객체 탐지)&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;1000&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/djbCB0/btsQxbwGaW8/8ufnt304vov9yJANq0GMz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/djbCB0/btsQxbwGaW8/8ufnt304vov9yJANq0GMz0/img.png&quot; data-alt=&quot;object detection&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/djbCB0/btsQxbwGaW8/8ufnt304vov9yJANq0GMz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdjbCB0%2FbtsQxbwGaW8%2F8ufnt304vov9yJANq0GMz0%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;821&quot; height=&quot;547&quot; data-origin-width=&quot;1500&quot; data-origin-height=&quot;1000&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;object detection&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;mediaSingle&quot; data-prosemirror-content-type=&quot;node&quot; data-media-vc-wrapper=&quot;true&quot;&gt;
&lt;div data-media-vc-wrapper=&quot;true&quot; data-width-type=&quot;pixel&quot; data-width=&quot;760&quot; data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;이미지 속 &lt;b&gt;여러 객체의 위치&lt;/b&gt;를 찾고, 동시에 &lt;b&gt;클래스를 분류&lt;/b&gt;하는 작업이다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;주로 &lt;b&gt;바운딩 박스(Bounding Box)&lt;/b&gt;를 이용해 객체의 위치를 표시하고, 각 박스 안의 객체가 무엇인지 분류한다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;heading&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size26&quot;&gt;3. Image Segmentation (이미지 분할)&lt;/h2&gt;
&lt;div data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;mediaSingle&quot; data-prosemirror-content-type=&quot;node&quot; data-media-vc-wrapper=&quot;true&quot;&gt;
&lt;div data-media-vc-wrapper=&quot;true&quot; data-width-type=&quot;pixel&quot; data-width=&quot;653&quot; data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKdBB9/btsQyxlmt8o/0vtopj7mlNQREM6CLxmaW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKdBB9/btsQyxlmt8o/0vtopj7mlNQREM6CLxmaW0/img.png&quot; data-alt=&quot;image segmentation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKdBB9/btsQyxlmt8o/0vtopj7mlNQREM6CLxmaW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKdBB9%2FbtsQyxlmt8o%2F0vtopj7mlNQREM6CLxmaW0%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;462&quot; data-origin-width=&quot;653&quot; data-origin-height=&quot;462&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;image segmentation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 &lt;b&gt;픽셀 단위&lt;/b&gt;로 분석해 &lt;b&gt;관심 객체를 추출&amp;middot;분류&lt;/b&gt;하는 작업이다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;Object Detection이 객체의 &lt;b&gt;대략적 위치&lt;/b&gt;만 알려주는 데 비해,&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;Image Segmentation은 &lt;b&gt;각 픽셀이 어떤 객체에 속하는지&lt;/b&gt;까지 파악해 더 정밀한 위치와 모양 정보를 제공한다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;heading&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size23&quot;&gt;3.1. Image Segmentation 종류&lt;/h3&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Semantic Segmentation&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;1058&quot; data-origin-height=&quot;478&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xtlb2/btsQxD0JvWJ/kiw1iKJWOogY4S8tMfSsx0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xtlb2/btsQxD0JvWJ/kiw1iKJWOogY4S8tMfSsx0/img.png&quot; data-alt=&quot;semantic segmentation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xtlb2/btsQxD0JvWJ/kiw1iKJWOogY4S8tMfSsx0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fxtlb2%2FbtsQxD0JvWJ%2Fkiw1iKJWOogY4S8tMfSsx0%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;1058&quot; height=&quot;478&quot; data-origin-width=&quot;1058&quot; data-origin-height=&quot;478&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;semantic segmentation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;mediaSingle&quot; data-prosemirror-content-type=&quot;node&quot; data-media-vc-wrapper=&quot;true&quot;&gt;
&lt;div data-media-vc-wrapper=&quot;true&quot; data-width-type=&quot;pixel&quot; data-width=&quot;760&quot; data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;이미지를 사람이 이해할 수 있는 &lt;b&gt;의미 단위(클래스)&lt;/b&gt;별로 구분하는 방식이다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;즉, 이미지의 각 픽셀을 사람, 자동차, 비행기 등과 같은 물리적 의미 단위(클래스)로 분류한다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Instance Segmentation&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;640&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZir36/btsQyuvoaMz/AM7snBtDoHekFvMx4vzQO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZir36/btsQyuvoaMz/AM7snBtDoHekFvMx4vzQO0/img.png&quot; data-alt=&quot;instance segmentation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZir36/btsQyuvoaMz/AM7snBtDoHekFvMx4vzQO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZir36%2FbtsQyuvoaMz%2FAM7snBtDoHekFvMx4vzQO0%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;427&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;instance segmentation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;mediaSingle&quot; data-prosemirror-content-type=&quot;node&quot; data-media-vc-wrapper=&quot;true&quot;&gt;
&lt;div data-media-vc-wrapper=&quot;true&quot; data-width-type=&quot;pixel&quot; data-width=&quot;640&quot; data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;시맨틱 세그멘테이션이 클래스별 구분이라면, 인스턴스 세그멘테이션은 &lt;b&gt;개별 객체(인스턴스)&lt;/b&gt;별 구분이다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;같은 클래스(예: 사람)라도 사람1, 사람2, 사람3처럼 각각 다른 인스턴스로 식별해 분리한다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Panoptic Segmentation&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;925&quot; data-origin-height=&quot;512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n5rdu/btsQwiC0MHQ/X7kDEXxFBTPuN6ixSSzZIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n5rdu/btsQwiC0MHQ/X7kDEXxFBTPuN6ixSSzZIk/img.png&quot; data-alt=&quot;panoptic segmentation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n5rdu/btsQwiC0MHQ/X7kDEXxFBTPuN6ixSSzZIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn5rdu%2FbtsQwiC0MHQ%2FX7kDEXxFBTPuN6ixSSzZIk%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;925&quot; height=&quot;512&quot; data-origin-width=&quot;925&quot; data-origin-height=&quot;512&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;panoptic segmentation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;div data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;mediaSingle&quot; data-prosemirror-content-type=&quot;node&quot; data-media-vc-wrapper=&quot;true&quot;&gt;
&lt;div data-media-vc-wrapper=&quot;true&quot; data-width-type=&quot;pixel&quot; data-width=&quot;760&quot; data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;시맨틱 세그멘테이션과 인스턴스 세그멘테이션을 결합한 방식이다.&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;각 픽셀에 &lt;b&gt;클래스(class)&lt;/b&gt;와 &lt;b&gt;인스턴스 ID(instance id)&lt;/b&gt;를 함께 부여하여&lt;/p&gt;
&lt;p data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;paragraph&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size16&quot;&gt;물체와 배경을 모두 인스턴스 단위로 구분한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;bulletList&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;listItem&quot; data-prosemirror-content-type=&quot;node&quot;&gt;인스턴스 세그멘테이션은 주로 물체 인스턴스 구분에 초점을 두고 배경은 신경 쓰지 않는다.&lt;/li&gt;
&lt;li data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;listItem&quot; data-prosemirror-content-type=&quot;node&quot;&gt;시맨틱 세그멘테이션은 배경까지 포함한 클래스 분류가 가능하다.&lt;/li&gt;
&lt;li data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;listItem&quot; data-prosemirror-content-type=&quot;node&quot;&gt;파놉틱 세그멘테이션은 두 방식을 통합해 물체와 배경을 모두 포괄적으로 식별한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;heading&quot; data-prosemirror-content-type=&quot;node&quot; data-ke-size=&quot;size23&quot;&gt;요약&lt;/h3&gt;
&lt;div data-prosemirror-node-block=&quot;true&quot; data-prosemirror-node-name=&quot;mediaSingle&quot; data-prosemirror-content-type=&quot;node&quot; data-media-vc-wrapper=&quot;true&quot;&gt;
&lt;div data-media-vc-wrapper=&quot;true&quot; data-width-type=&quot;pixel&quot; data-width=&quot;760&quot; data-layout=&quot;center&quot; data-node-type=&quot;mediaSingle&quot;&gt;
&lt;div style=&quot;color: #000000;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;686&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjsp8y/btsQwJ8d0by/1vdxhif7rldwe3KTT2kxXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjsp8y/btsQwJ8d0by/1vdxhif7rldwe3KTT2kxXk/img.png&quot; data-alt=&quot;segmentation&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjsp8y/btsQwJ8d0by/1vdxhif7rldwe3KTT2kxXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcjsp8y%2FbtsQwJ8d0by%2F1vdxhif7rldwe3KTT2kxXk%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;686&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;686&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;segmentation&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>AI</category>
      <category>AI</category>
      <category>Classification</category>
      <category>Computer Vision</category>
      <category>image sementation</category>
      <category>instance segmentation</category>
      <category>object detection</category>
      <category>panoptic segmentation</category>
      <category>Semantic segmentation</category>
      <category>컴퓨터비전</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/148</guid>
      <comments>https://kdhyo98.tistory.com/148#entry148comment</comments>
      <pubDate>Fri, 12 Sep 2025 17:17:48 +0900</pubDate>
    </item>
    <item>
      <title>비공개 Github Repository SSH로 clone</title>
      <link>https://kdhyo98.tistory.com/144</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;✨ 서론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GitHub 리포가 비공개일 경우, SSH를 추가해 clone 받는 방법을 정리합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  본론&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. EC2 인스턴스에 SSH 키 생성&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1725972114515&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ssh-keygen -t ed25519 -C &quot;your_email@example.com&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. SSH 에이전트 실행 및 키 추가&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1725972147144&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# SSH 에이전트 시작
eval &quot;$(ssh-agent -s)&quot;

# SSH 키 추가
ssh-add ~/.ssh/id_ed25519&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. GitHub 공개 키 추가&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1725972157945&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 공개 키를 출력
cat ~/.ssh/id_ed25519.pub&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 명령어의 출력값을 복사한 후, GitHub에 로그인하여 아래와 같이 진행합니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;GitHub의 우측 상단에서 &lt;b&gt;Profile Picture&lt;/b&gt;를 클릭하고 &lt;b&gt;Settings&lt;/b&gt;로 이동.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;SSH and GPG keys&lt;/b&gt;로 이동.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;New SSH Key&lt;/b&gt; 버튼을 클릭.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Title&lt;/b&gt;을 입력하고, 복사한 공개 키(id_ed25519.pub)를 &lt;b&gt;Key&lt;/b&gt; 부분에 붙여넣기.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Add SSH key&lt;/b&gt; 클릭.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;GitHub 리포지토리 클론&lt;/b&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. GitHub Clone&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1725972233348&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;git clone git@github.com:your-username/your-repo.git&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;  결론&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;End.&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>AWS</category>
      <category>EC2</category>
      <category>github</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/144</guid>
      <comments>https://kdhyo98.tistory.com/144#entry144comment</comments>
      <pubDate>Tue, 10 Sep 2024 21:44:30 +0900</pubDate>
    </item>
    <item>
      <title>네트워크 인프라 자동화 리뷰</title>
      <link>https://kdhyo98.tistory.com/143</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;480&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nA8EG/btsJepn2bG0/DrJv7VUV0Sip0ukE3MdWN0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nA8EG/btsJepn2bG0/DrJv7VUV0Sip0ukE3MdWN0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nA8EG/btsJepn2bG0/DrJv7VUV0Sip0ukE3MdWN0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnA8EG%2FbtsJepn2bG0%2FDrJv7VUV0Sip0ukE3MdWN0%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;360&quot; height=&quot;480&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;480&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #222222; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;b&gt;저자 :&lt;/b&gt;&lt;span&gt;맷 오스왈트 , 제이슨 에델만 , 크리스티안 아델 , 스콧 S. 로우&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;b&gt;번역 :&lt;/b&gt;&lt;span&gt;이주호&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;b&gt;출간 :&lt;/b&gt;&lt;span&gt;2024-08-10&lt;/span&gt;&lt;/li&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&lt;b&gt;페이지 :&lt;/b&gt;&lt;span&gt;984 쪽&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;리뷰를 신청할 때 책 제목이 흥미로워서 신청했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;막상 받으니 1000 페이지 가량의 두꺼운 책이라 놀랐지만, 필요한 부분만 골라 읽어봤다.&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;이 책은, 제목대로 네트워크 엔지니어가 읽으면 도움이 될 만한 내용이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;백엔드 개발자가 읽기에는 다소 생소한 용어들이 많았지만, &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;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 책은 정말 많은 걸 담으려고 한 게 느껴졌다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;네트워크 엔지니어와 개발자 모두에게 도움이 되고 싶었던 느낌이랄까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기초부터 심화까지 많은 부분을 담으려고 하다보니 1000페이지 가량의 두꺼운 책이 탄생했고, 처음부터 끝까지 보기엔 힘든 책이었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;파이썬, 고 언어의 기초 설명, git 설치 설명과 브랜치 협업 방법부터 TDD 찍먹의 파트 등&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;네트워크 엔지니어에게 이 한 책으로 많은 걸 설명하고 싶었던 게 느껴진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;네트워크 엔지니어를 시작하는 사람에게는 어느정도 학습의 방향을 정해줄 수는 있어보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 책을 한 번 훑고 더 파보고 싶은 부분을 별도로 검색하거나, 해당되는 책을 더 파볼 수 있어 보이고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&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;b&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp; &quot;&lt;/span&gt;&lt;span&gt;한빛미디어&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;나는리뷰어다&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;활동을 위해서 책을 제공받아 작성된 서평입니다&lt;/span&gt;&lt;span&gt;.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>HisStory/나는리뷰어다2024</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/143</guid>
      <comments>https://kdhyo98.tistory.com/143#entry143comment</comments>
      <pubDate>Fri, 23 Aug 2024 17:06:24 +0900</pubDate>
    </item>
    <item>
      <title>개발자를 위한 최소한의 실무 지식 (리뷰)</title>
      <link>https://kdhyo98.tistory.com/142</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;346&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4lkIO/btsESqrDCF2/QXRuFhH48P6pkKv5ZvUnj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4lkIO/btsESqrDCF2/QXRuFhH48P6pkKv5ZvUnj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4lkIO/btsESqrDCF2/QXRuFhH48P6pkKv5ZvUnj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4lkIO%2FbtsESqrDCF2%2FQXRuFhH48P6pkKv5ZvUnj0%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;578&quot; height=&quot;172&quot; data-origin-width=&quot;1164&quot; data-origin-height=&quot;346&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;2023년에 이어 2024년도 한빛미디어의 서평단이 되었다.&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;감사한 마음을 담아 작년보다 더 나은 리뷰를 쓸 수 있도록 노력해야겠다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1522&quot; data-origin-height=&quot;2066&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4OoXi/btsEQcVeC6Y/6GXInBE4gVtC7f23M52Es1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4OoXi/btsEQcVeC6Y/6GXInBE4gVtC7f23M52Es1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4OoXi/btsEQcVeC6Y/6GXInBE4gVtC7f23M52Es1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4OoXi%2FbtsEQcVeC6Y%2F6GXInBE4gVtC7f23M52Es1%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;592&quot; height=&quot;804&quot; data-origin-width=&quot;1522&quot; data-origin-height=&quot;2066&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;한줄평:&lt;span&gt; 실무에서 사용될 다양한 키워드들을 빠르게 습득할 수 있는 책&lt;/span&gt;&lt;/span&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;1726&quot; data-origin-height=&quot;1820&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bstDRN/btsERl5dlSc/gRoyglJcqsOnQnys2uWdR1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bstDRN/btsERl5dlSc/gRoyglJcqsOnQnys2uWdR1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bstDRN/btsERl5dlSc/gRoyglJcqsOnQnys2uWdR1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbstDRN%2FbtsERl5dlSc%2FgRoyglJcqsOnQnys2uWdR1%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;690&quot; height=&quot;728&quot; data-origin-width=&quot;1726&quot; data-origin-height=&quot;1820&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책에서 독자 방향을 취준생 ~ 1~2년 차 신입 개발자로 잡았는데, 개인적으로 취준생 ~ 입사 신입 때 읽기 좋은 책이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부제로도 나와있듯 40가지 핵심 기술에 대해서 설명하다보니, 한 기술에 대해 깊이 설명하기 보다는 핵심을 잘 짚어주는 느낌이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책에서 좋았던 점은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 다양한 분야를 설명한다고 해서 결코 깊이가 얕지 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 다양한 키워드를 짚어준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 용어에 대한 설명이 매력적이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;핵심적인 키워드들을 잘 뽑아서 설명해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이테베이스의 트랜잭션과 인덱스가 왜 기본이고 중요한지를 메모리 / 디스크를 포함해서 설명해주는 게 좋았고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공부할 때는 한 번 듣고 넘어가는 경우도 많았던 옵티마이저 또한 핵심만 뽑아 설명해줘서 이해하기 쉬웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스 뿐 아니라 보안, 자원, 성능, 테스트, 좋은 코드 작성방법, 클라우드 등 정말 다양한 분야에 대해서 한 권에서 설명하다보니&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 분야의 전문 서적보다는 당연히 깊지는 못하지만, 핵심을 잘 짚고, 예시 또한 당연하게 중요하게 생각했던 것들이어서 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zwtA3/btsES8jZ2Bo/YQYe1w4kXPjz9C0ZLxGVC0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zwtA3/btsES8jZ2Bo/YQYe1w4kXPjz9C0ZLxGVC0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zwtA3/btsES8jZ2Bo/YQYe1w4kXPjz9C0ZLxGVC0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzwtA3%2FbtsES8jZ2Bo%2FYQYe1w4kXPjz9C0ZLxGVC0%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;328&quot; height=&quot;524&quot; data-origin-width=&quot;328&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 장점과도 연결이 되는데, 40가지 외에도 책 중간중간 더 깊게 알아볼 만한 용어를 다양하게 알려준 뿐 아니라,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책 부록에서도 독자들이 챕터 별로 더 관심이 있으면 찾아보면 좋을만한 키워드들을 알려준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책을 읽으면서 이 키워드에 대한 설명이 있으면 좋겠는데~ 했던 키워드들이 몇 개가 포함되어 있는 걸 보고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작가가 책 분량에 막혀 넣고 싶은데 못 넣은 키워드들이 많았겠다는 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키워드들만 잘 각인하더라도 책 값은 뽑을 수 있겠다는 생각이 들 정도로 다양한 분야들의 핵심 키워드들을 잘 짚어주는 게 느껴졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;3. 용어에 대한 설명이 매력적이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1412&quot; data-origin-height=&quot;2226&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4RJON/btsEQawlNhL/FyGkWC1IeFYX3pLw8Wpbw0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4RJON/btsEQawlNhL/FyGkWC1IeFYX3pLw8Wpbw0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4RJON/btsEQawlNhL/FyGkWC1IeFYX3pLw8Wpbw0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4RJON%2FbtsEQawlNhL%2FFyGkWC1IeFYX3pLw8Wpbw0%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;414&quot; height=&quot;653&quot; data-origin-width=&quot;1412&quot; data-origin-height=&quot;2226&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;1670&quot; data-origin-height=&quot;1880&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XoL6u/btsENTIC8v2/tISdzl8KPIs9J1PkkBKHe0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XoL6u/btsENTIC8v2/tISdzl8KPIs9J1PkkBKHe0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XoL6u/btsENTIC8v2/tISdzl8KPIs9J1PkkBKHe0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXoL6u%2FbtsENTIC8v2%2FtISdzl8KPIs9J1PkkBKHe0%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;461&quot; height=&quot;519&quot; data-origin-width=&quot;1670&quot; data-origin-height=&quot;1880&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;단어는 그 단어가 어떻게 시작했는지, 왜 탄생했는지, 어떤 의미인지를 알게되면 더 쉽고, 오래 기억한다고 생각한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책에서는 유명한 버그, 스레드를 포함해 그 단어의 어원을 설명해주기 때문에 단순 기술서적보다 흥미를 키우기 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책은 정말 넓은 분야에 대해 담고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 이 책은 실무에 들어가기 전 다양하게 이런 것들을 알아둬야 되는구나를 파악하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;용어, 키워드들에 익숙해져서 실무에서 마주쳐도 덜 당황할 수 있게 해줄 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 읽다보면 본인이 더 관심이 가고, 궁금한 챕터들이 생길 수 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒤 부록과 챕터에서 나온 키워드들을 검색해서 더 깊게 공부 할 수 있도록 길잡이 역할을 해줄 수 있는 책이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;한빛미디어 &amp;lt;나는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;리뷰어&lt;/span&gt;다&amp;gt; 활동을 위해서 책을 제공받아 작성된 서평입니다.&quot;&lt;/b&gt;&lt;/p&gt;</description>
      <category>HisStory/나는리뷰어다2024</category>
      <category>나는리뷰어다</category>
      <category>한빛미디어</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/142</guid>
      <comments>https://kdhyo98.tistory.com/142#entry142comment</comments>
      <pubDate>Wed, 14 Feb 2024 23:08:34 +0900</pubDate>
    </item>
    <item>
      <title>Release의 모든 것 (리뷰)</title>
      <link>https://kdhyo98.tistory.com/141</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;2026&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nlQMF/btsCBMiNqIt/do0yztKQPxgQDZxU3TJUsk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nlQMF/btsCBMiNqIt/do0yztKQPxgQDZxU3TJUsk/img.jpg&quot; data-alt=&quot;Release의 모든 것&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nlQMF/btsCBMiNqIt/do0yztKQPxgQDZxU3TJUsk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnlQMF%2FbtsCBMiNqIt%2Fdo0yztKQPxgQDZxU3TJUsk%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;479&quot; height=&quot;626&quot; data-origin-width=&quot;1550&quot; data-origin-height=&quot;2026&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Release의 모든 것&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;한줄평: 제목을 참 잘 지은 책.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;35년 경력을 가진 선배 개발자가 직접 겪은 다양한 이슈와 과거 큰 이슈들을 이야기해주면서 실제 프로덕트 환경의 무서움을 알려주는 책이다.&lt;/p&gt;
&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;위와 같은 일들이&amp;nbsp;&lt;/span&gt;일어나지 않도록 테스트 코드를 작성하고, 많은 테스트를 통해 방지를 위해 힘을 쓴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 실환경에서는 문제가 저게 다가 아니다.&lt;/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;AWS에 모든 서버를 구축했지만, AWS의 실수로 몇 시간의 장애가 있을 수 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전혀 문제가 없을 것 같은 네트워크조차 문제가 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 외에도 과거에 겪은 다양한 사례로 조심해야 할 안티 패턴과 문제들이 많지만, 모두 완벽히 방지할 수는 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 미리 책에서 알려주는 안정성 패턴을 통해 문제가 발생했을 때 빠르게 인지하고, 해결하기 위한 환경을 갖춤으로써 좀 더 안전한 시스템을 구축하여 많은 시행착오를 줄일 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책의 내용은 소프트웨어 설계를 어떻게 하면 좋을지에 대한 방법과 실제 서비스를 운영하는 노하우를 알려주는 책이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 신입보다는 직접 Release를 준비하는 개발자 혹은 어느 정도 경력있는 사람이 읽었을 때 더 많이 와 닿는 게 많을 것 같고,&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;blockquote style=&quot;background-color: #fcfcfc; color: #666666; text-align: left;&quot; data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;이 잡동사니가 정말로 필요한가?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;필자가 소켓 라이브러리를 이식할 때 그랬던 것 처럼 가능할 때마다 모두 시간을 제한하도록 처리하면 코드가 지나치게 복잡해진다고 생각할 수 있다. 물론 확실히 더 복잡해진다. 코드의 절반은 기능을 제공하는 대신 오류만 처리하고 있음을 알게 될 것이다. 그러나 QA가 아니라 운영을 목표로 한다는 말의 핵심은 부당한 운명의 돌팔매와 화살을 다루는 것이다. 오류 처리 코드가 제대로 작성되었다면 탄력성이 부여된다.&amp;nbsp;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;시스템이 죽지 않으면 아무도 알아채지 못하기 때문에 사용자는 고마워하지 않겠지만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;밤에 마음 편히 잘 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;nbsp;&lt;/span&gt;- P147 발췌&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적인 잡담.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2183&quot; data-origin-height=&quot;1028&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dxBmMn/btsCyI9pz9L/qDPp4dEcRKtoLk38kdX6p0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dxBmMn/btsCyI9pz9L/qDPp4dEcRKtoLk38kdX6p0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dxBmMn/btsCyI9pz9L/qDPp4dEcRKtoLk38kdX6p0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdxBmMn%2FbtsCyI9pz9L%2FqDPp4dEcRKtoLk38kdX6p0%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;675&quot; height=&quot;318&quot; data-origin-width=&quot;2183&quot; data-origin-height=&quot;1028&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;1870&quot; data-origin-height=&quot;868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JHIU6/btsCzrGk23y/sP5DeUIwh5hognTCJMDrK0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JHIU6/btsCzrGk23y/sP5DeUIwh5hognTCJMDrK0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JHIU6/btsCzrGk23y/sP5DeUIwh5hognTCJMDrK0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJHIU6%2FbtsCzrGk23y%2FsP5DeUIwh5hognTCJMDrK0%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;675&quot; height=&quot;313&quot; data-origin-width=&quot;1870&quot; data-origin-height=&quot;868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 테스트를 하면서 겪었던 문제들이 이 책에서 많이 소개되어 놀랐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 일찍 이 책을 봤으면 나도 시행착오를 줄일 수 있었을 텐데 싶은 안타까운 생각과,&lt;/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;&quot;한빛미디어 &amp;lt;나는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;리뷰어&lt;/span&gt;다&amp;gt; 활동을 위해서 책을 제공받아 작성된 서평입니다.&quot;&lt;/b&gt;&lt;/p&gt;</description>
      <category>HisStory/나는리뷰어다2023</category>
      <category>나는리뷰어다</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/141</guid>
      <comments>https://kdhyo98.tistory.com/141#entry141comment</comments>
      <pubDate>Sun, 24 Dec 2023 00:29:00 +0900</pubDate>
    </item>
    <item>
      <title>초보자도 프로처럼 만드는 플러터 앱개발 (리뷰)</title>
      <link>https://kdhyo98.tistory.com/140</link>
      <description>&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;0168B9A0-9EAF-4D31-A9FF-BD499F051C1A_1_201_a.jpeg&quot; data-origin-width=&quot;2451&quot; data-origin-height=&quot;2732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgbENw/btszpzz4teS/M0kKkLsQSu2OvBWKr7rL70/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgbENw/btszpzz4teS/M0kKkLsQSu2OvBWKr7rL70/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgbENw/btszpzz4teS/M0kKkLsQSu2OvBWKr7rL70/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgbENw%2Fbtszpzz4teS%2FM0kKkLsQSu2OvBWKr7rL70%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;575&quot; height=&quot;641&quot; data-filename=&quot;0168B9A0-9EAF-4D31-A9FF-BD499F051C1A_1_201_a.jpeg&quot; data-origin-width=&quot;2451&quot; data-origin-height=&quot;2732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백엔드 개발자로 일을 하면서 앱개발을 한 번도 해본 적은 없지만, 앱 개발을 배워보고 싶다는 생각이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ios, 안드로이드를 별도로 개발하지 않는 기술 중 리액트 네이티브와 플러터 중 뭘 배울까 고민했던 적이 있었는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구글에서 활발하게 지원하고 있는 플러터를 배워보고 싶었고, 마침 이번에 기회가 생겨서 이 책을 읽어봤다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&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;사실 문법만 배운다고 바로 내가 원하는 앱을 만들기는 쉽지 않다.&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2장에서는 문법 설명 이전에 코드를 먼저 따라서 치는 실습이 있어서 흥미를 올릴 수 있어서 좋은 챕터였다.&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;size18&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;2874&quot; data-origin-height=&quot;1848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/U7TnM/btszkn2be5A/JgyEYoymxltRkKq8JJF5ck/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/U7TnM/btszkn2be5A/JgyEYoymxltRkKq8JJF5ck/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/U7TnM/btszkn2be5A/JgyEYoymxltRkKq8JJF5ck/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FU7TnM%2Fbtszkn2be5A%2FJgyEYoymxltRkKq8JJF5ck%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;353&quot; data-origin-width=&quot;2874&quot; data-origin-height=&quot;1848&quot;/&gt;&lt;/span&gt;&lt;/figure&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 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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;A-Z까지&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책의 장점을 뽑자면 정말 초보자를 기준으로 처음부터 마지막까지 알려준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다트의 간단한 기본 문법부터 심지어 프로그램 설치 방법도 어렵지 않게 상세히 설명해주며&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 앱 개발에서 끝이 아닌 앱 등록하는 방법까지 알려준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ios와 안드로이드 두 플랫폼 모두 등록하는 방법을 알려줌으로서 크로스 플랫폼의 장점을 제대로 활용할 수 있게 도와준다.&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;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-filename=&quot;4B8ADBCA-2711-4286-A867-7FF718FE50CE_1_201_a.jpeg&quot; data-origin-width=&quot;2328&quot; data-origin-height=&quot;1445&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9BU2m/btszkaaJi0Y/2LwAdDshB3SUu3KBTpkZwk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9BU2m/btszkaaJi0Y/2LwAdDshB3SUu3KBTpkZwk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9BU2m/btszkaaJi0Y/2LwAdDshB3SUu3KBTpkZwk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9BU2m%2FbtszkaaJi0Y%2F2LwAdDshB3SUu3KBTpkZwk%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;372&quot; height=&quot;231&quot; data-filename=&quot;4B8ADBCA-2711-4286-A867-7FF718FE50CE_1_201_a.jpeg&quot; data-origin-width=&quot;2328&quot; data-origin-height=&quot;1445&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년 9월 초에 출판된 책인 만큼 최신 업데이트된 설명이 있는 건 당연히 기대를 했지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책을 집필하는 시간 또한 있기 때문에 크게는 6개월 정도의 차이는 있을 수 있다고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 이 책에서는 2023년 8월에 업데이트 된 내용까지 짚어주면서 출판 이후 업데이트에 대해 예고를 해주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자신이 사용하는 기술에 최신 업데이트를 꾸준히 알아가는 게 중요하다고 생각하는 입장에서 아주 좋았다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 책을 통해 바로 프로(?)처럼은 어렵겠지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 처음 플러터를 접한 사람들이 앱 배포까지 흥미를 가지면서 여러 프로젝트를 경험해보고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스토어에 올려보는 경험까지 해볼 수 있다는 장점이 크기 때문에 플러터를 처음 배울 계획이라면 이 책을 추천하기 좋은 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;&quot;한빛미디어 &amp;lt;나는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span&gt;리뷰어&lt;/span&gt;다&amp;gt; 활동을 위해서 책을 제공받아 작성된 서평입니다.&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>HisStory/나는리뷰어다2023</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/140</guid>
      <comments>https://kdhyo98.tistory.com/140#entry140comment</comments>
      <pubDate>Sun, 29 Oct 2023 17:32:08 +0900</pubDate>
    </item>
    <item>
      <title>[Toby Spring Reactive Programming] 비동기 RestTemplate과 비동기 MVC/Serlvet (5)</title>
      <link>https://kdhyo98.tistory.com/139</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=ExUfZkh7Puk&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=ExUfZkh7Puk&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;토비님의 유튜브 강의 내용을 정리한 글 입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 style=&quot;background-color: #ffffff; color: #353638; text-align: left;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;본론&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1697864595423&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@RestController
public static class MyController {
    AsyncRestTemplate rt = new AsyncRestTemplate();
    
    @GetMapping(&quot;/rest&quot;)
    public String rest(int idx) {
        return rt.getForEntity(&quot;http://localhost:8081/service?req={req}&quot;, String.class, &quot;hello&quot; + idx);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AsyncRestTemplate을 사용하면, 톰캣 스레드 1개로 처리가 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 백그라운드 스레드가 생성되어 처리하기 때문에 성능상 좋지 못해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring 5에서는 Deprecated됐고, Spring 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;Netty 라이브러리로 클라이언트를 바꿔서 처리하면, 스레드를 만들지 않고도 처리했지만&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;</description>
      <category>JVM/Spring</category>
      <category>reactive</category>
      <category>Toby</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/139</guid>
      <comments>https://kdhyo98.tistory.com/139#entry139comment</comments>
      <pubDate>Sat, 21 Oct 2023 14:08:23 +0900</pubDate>
    </item>
    <item>
      <title>[Toby Spring Reactive Programming] 자바, 스프링의 비동기 (4)</title>
      <link>https://kdhyo98.tistory.com/138</link>
      <description>&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;a href=&quot;https://www.youtube.com/watch?v=aSTuQiPB4Ns&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.youtube.com/watch?v=aSTuQiPB4Ns&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토비님의 유튜브 강의 내용을 정리한 글 입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스프링 컨트롤러 리턴타입에 따른 동작방식&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;#1 Object&lt;/b&gt;&lt;/h4&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;@GetMapping(&quot;/async&quot;)
public String async() throws InterruptedException {
    log.info(&quot;async&quot;);
    Thread.sleep(2000);
    return &quot;hello&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 tomcat thread pool 수인 200개 까지만 동시처리가 가능하다. [&lt;a href=&quot;https://tomcat.apache.org/tomcat-8.5-doc/config/executor.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&lt;/a&gt;]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tomcat.apache.org/tomcat-8.5-doc/config/executor.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://tomcat.apache.org/tomcat-8.5-doc/config/executor.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;#2 Callable&lt;/b&gt;&lt;/h4&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;@GetMapping(&quot;/callable&quot;)
public Callable&amp;lt;String&amp;gt; callable() throws InterruptedException {
    log.info(&quot;callable&quot;);
    return () -&amp;gt; {
        log.info(&quot;async&quot;);
        Thread.sleep(2000);
        return &quot;hello&quot;;
    };
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;http-nio threed는 1~2개로 백그라운드 스레드를 통해 비동기 리턴을 하기 때문에 1000개 동시처리 시 2초에 가깝게 끝이 난다.&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;#3 DeferredResult&lt;/b&gt;&lt;/h4&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;Queue&amp;lt;DeferredResult&amp;lt;String&amp;gt;&amp;gt; results = new ConcurrentLinkedDeque&amp;lt;&amp;gt;();

@GetMapping(&quot;/dr&quot;)
public DeferredResult&amp;lt;String&amp;gt; deferred() throws InterruptedException {
    log.info(&quot;dr&quot;);
    DeferredResult&amp;lt;String&amp;gt; dr = new DeferredResult&amp;lt;String&amp;gt;();
    results.add(dr);
    return dr;
}

@GetMapping(&quot;/dr/count&quot;)
public String drCount() {
    return String.valueOf(results.size());
}

@GetMapping(&quot;/dr/event&quot;)
public String drEvent(String msg) {
    for (DeferredResult&amp;lt;String&amp;gt; dr : results) {
        dr.setResult(&quot;Hello &quot; + msg);
        results.remove(dr);
    }
    return &quot;Ok&quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;/dr API호출 시 바로 응답이 나가는 게 아닌, /dr/event API를 통해 비동기적으로 응답을 보내줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;#4 ResponseBodyEmitter&lt;/b&gt;&lt;/h4&gt;
&lt;pre class=&quot;livescript&quot;&gt;&lt;code&gt;@GetMapping(&quot;emitter&quot;)
public ResponseBodyEmitter emitter() {
    ResponseBodyEmitter emitter = new ResponseBodyEmitter();

    Executors.newSingleThreadExecutor().submit(() -&amp;gt; {

        try {
            for (int i = 1; i &amp;lt;= 50; i++) {
                emitter.send(&quot;&amp;lt;p&amp;gt;Stream &quot; + i + &quot;&amp;lt;/p&amp;gt;&quot;);
                Thread.sleep(2000);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    });
    return emitter;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #080808; text-align: start;&quot;&gt;ResponseBodyEmitter를 먼저 리턴하고, 비동기적으로 send()를 통해 데이터를 넘길 수 있다.&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;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JVM/Spring</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/138</guid>
      <comments>https://kdhyo98.tistory.com/138#entry138comment</comments>
      <pubDate>Tue, 17 Oct 2023 22:02:06 +0900</pubDate>
    </item>
    <item>
      <title>[Toby Spring Reactive Programming] Schedulers (3)</title>
      <link>https://kdhyo98.tistory.com/137</link>
      <description>&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;a href=&quot;https://www.youtube.com/watch?v=Wlqu1xvZCak&quot;&gt;https://www.youtube.com/watch?v=Wlqu1xvZCak&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토비님의 유튜브 강의를 보고 정리한 내용입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;a href=&quot;https://kdhyo98.tistory.com/136&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kdhyo98.tistory.com/136&lt;/a&gt; 이전 코드까지는 모두 main스레드에서 동작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, IO나 큰 계산같은 작업들이 있다면 main스레드가 끝날 때까지 멈추게 되는데,&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;이걸 main이 아닌 다른스레드에 작업을 넘겨 처리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Ractive Streams 구현&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 다 확인할 필요가 없는 경우에는 백그라운드에서 동작을 시켜 main은 다른 이벤트를 받게 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 Flow에서는 subscribeOn, publishOn을 통해 비동기로 동작할 수 있게 한다.&lt;/p&gt;
&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;subsrcibeOn&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;publishOn&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 주로 데이터를 소비가 느릴 때 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 리액티브 스트림의 중간 또는 끝 부분에서 작업을 수행하는 스레드를 변경하는 데 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 연산자의 일부 작업을 다른 스레드에서 실행하게 하고 싶을 때 사용하는 편이다.&lt;/p&gt;
&lt;pre id=&quot;code_1697361279542&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args) throws InterruptedException {
    Flux.range(1, 5)
            .doOnNext(i -&amp;gt; System.out.println(&quot;Value &quot; + i + &quot; on thread &quot; + Thread.currentThread().getName()))
            .subscribeOn(Schedulers.parallel())
            .doOnNext(i -&amp;gt; System.out.println(&quot;Value &quot; + i + &quot; on thread after subscribeOn &quot; + Thread.currentThread().getName()))
            .publishOn(Schedulers.boundedElastic())
            .doOnNext(i -&amp;gt; System.out.println(&quot;Value &quot; + i + &quot; on thread after publishOn &quot; + Thread.currentThread().getName()))
            .subscribe();

    TimeUnit.SECONDS.sleep(30);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Value 1 on thread parallel-1 &lt;br /&gt;Value 1 on thread after subscribeOn parallel-1 &lt;br /&gt;Value 2 on thread parallel-1 &lt;br /&gt;Value 2 on thread after subscribeOn parallel-1 &lt;br /&gt;Value 3 on thread parallel-1 &lt;br /&gt;Value 3 on thread after subscribeOn parallel-1 &lt;br /&gt;Value 4 on thread parallel-1 &lt;br /&gt;Value 4 on thread after subscribeOn parallel-1 &lt;br /&gt;Value 5 on thread parallel-1 &lt;br /&gt;Value 5 on thread after subscribeOn parallel-1 &lt;br /&gt;Value 1 on thread after publishOn boundedElastic-1&lt;br /&gt;Value 2 on thread after publishOn boundedElastic-1 &lt;br /&gt;Value 3 on thread after publishOn boundedElastic-1 &lt;br /&gt;Value 4 on thread after publishOn boundedElastic-1 &lt;br /&gt;Value 5 on thread after publishOn boundedElastic-1&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;만들어보기&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1697361385477&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Slf4j
public class IntervalEx {
    public static void main(String[] args) {
        Publisher&amp;lt;Integer&amp;gt; pub = new Publisher&amp;lt;Integer&amp;gt;() {
            @Override
            public void subscribe(Subscriber&amp;lt;? super Integer&amp;gt; sub) {
                sub.onSubscribe(new Subscription() {

                    @Override
                    public void request(long n) {
                        sub.onNext(1);
                        sub.onNext(2);
                        sub.onNext(3);
                        sub.onNext(4);
                        sub.onNext(5);
                        sub.onComplete();
                    }

                    @Override
                    public void cancel() {
                    }
                });
            }
        };

        Publisher&amp;lt;Integer&amp;gt; subOnPub = new Publisher&amp;lt;Integer&amp;gt;() {
            @Override
            public void subscribe(Subscriber&amp;lt;? super Integer&amp;gt; sub) {
                ExecutorService es = Executors.newSingleThreadExecutor(new CustomizableThreadFactory() {
                    @Override
                    public String getThreadNamePrefix() {
                        return &quot;subOn&quot;;
                    }
                });
                es.execute(() -&amp;gt; pub.subscribe(
                        new Subscriber&amp;lt;Integer&amp;gt;() {
                            @Override
                            public void onSubscribe(Subscription s) {
                                sub.onSubscribe(s);
                            }

                            @Override
                            public void onNext(Integer integer) {
                                sub.onNext(integer);
                            }

                            @Override
                            public void onError(Throwable t) {
                                sub.onError(t);
                            }

                            @Override
                            public void onComplete() {
                                sub.onComplete();
                                es.shutdown();
                            }
                        }
                ));
            }
        };

        Publisher&amp;lt;Integer&amp;gt; pubOnPub = new Publisher&amp;lt;Integer&amp;gt;() {
            @Override
            public void subscribe(Subscriber&amp;lt;? super Integer&amp;gt; sub) {
                subOnPub.subscribe(new Subscriber&amp;lt;Integer&amp;gt;() {
                    ExecutorService es = Executors.newSingleThreadExecutor(new CustomizableThreadFactory() {
                        @Override
                        public String getThreadNamePrefix() {
                            return &quot;pubOn&quot;;
                        }
                    });

                    @Override
                    public void onSubscribe(Subscription s) {
                        sub.onSubscribe(s);
                    }

                    @Override
                    public void onNext(Integer integer) {
                        es.execute(() -&amp;gt; sub.onNext(integer));
                    }

                    @Override
                    public void onError(Throwable t) {
                        es.execute(() -&amp;gt; sub.onError(t));
                        es.shutdown();
                    }

                    @Override
                    public void onComplete() {
                        es.execute(() -&amp;gt; sub.onComplete());
                        es.shutdown();
                    }
                });
            }
        };

        pubOnPub.subscribe(new Subscriber&amp;lt;Integer&amp;gt;() {
            @Override
            public void onSubscribe(Subscription s) {
                log.info(&quot;onSubscribe&quot;);
                s.request(Long.MAX_VALUE);
            }

            @Override
            public void onNext(Integer i) {
                log.info(&quot;onNext:{}&quot;, i);
            }

            @Override
            public void onError(Throwable t) {
                log.info(&quot;onError:{}&quot;, t.toString());
            }

            @Override
            public void onComplete() {
                log.info(&quot;onComplete&quot;);
            }
        });
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;18:16:34.829 [subOn1] INFO three.IntervalEx -- onSubscribe &lt;br /&gt;18:16:34.831 [pubOn1] INFO three.IntervalEx -- onNext:1 &lt;br /&gt;18:16:34.832 [pubOn1] INFO three.IntervalEx -- onNext:2 &lt;br /&gt;18:16:34.832 [pubOn1] INFO three.IntervalEx -- onNext:3 &lt;br /&gt;18:16:34.832 [pubOn1] INFO three.IntervalEx -- onNext:4 &lt;br /&gt;18:16:34.832 [pubOn1] INFO three.IntervalEx -- onNext:5 &lt;br /&gt;18:16:34.832 [pubOn1] INFO three.IntervalEx -- onComplete&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pubOnPub에서 onSubscribe를 제외하고 onNext, onError, onComplete는 pubOn 스레드를 주었기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onSubscribe는 subOnPub에서 만든 subOn 스레드를 타고 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데몬쓰레드(Demon Thread) vs 사용자쓰레드(User Thread)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;맨 처음 Flux예제에서 &lt;b&gt;TimeUnit.SECONDS.sleep(30);&lt;/b&gt; 을 통해 30초 딜레이를 주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 그 부분이 없다면 Flux 구문은 제대로 실행되지 않고 종료될텐데, 직접만든 예제에서는 딜레이가 없어도 정상적으로 끝까지 진행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 이유가 데몬쓰레드와 사용자쓰레드의 차이이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.35658%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 46.589%;&quot;&gt;&lt;b&gt;사용자 쓰레드(User Thread)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 47.0543%;&quot;&gt;&lt;b&gt;데몬 쓰레드(Demon Thread)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.35658%;&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;width: 46.589%;&quot;&gt;- 프로그램의 주요 작업을 수행한다.&lt;br /&gt;- JVM은 모든 사용자 쓰레드가 종료될 때까지 실행을 유지한다.&lt;br /&gt;- 애플리케이션의 시작부터 종료까지 실행될 수 있다.&lt;/td&gt;
&lt;td style=&quot;width: 47.0543%;&quot;&gt;- 백그라운드에서 작업을 수행한다.&lt;br /&gt;- 모든 사용자 쓰레드가 종료되면 자동으로 종료된다.&lt;br /&gt;- 주로 자원을 정리하거나 로깅과 같은 보조 작업에 사용된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 6.35658%;&quot;&gt;단점&lt;/td&gt;
&lt;td style=&quot;width: 46.589%;&quot;&gt;- 프로그램 종료 시 모든 사용자 쓰레드가 종료될 때까지 기다려야 한다.&lt;br /&gt;- 종료를 관리하는 것이 복잡할 수 있다.&lt;/td&gt;
&lt;td style=&quot;width: 47.0543%;&quot;&gt;- 애플리케이션의 주요 작업을 수행하는 데에 적합하지 않다.&lt;br /&gt;- 갑작스럽게 종료될 수 있으므로 주요 작업에 사용하기 어렵다.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액티브 스트림즈의 별도 스레드들이 데몬스레드인 이유는 아마 리소스 관리와 애플리케이션 종료 과정을 단순화하기 위해서로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 비동기 작업이 주 스레드의 종료를 방해하지 않기 위해서 주로 데몬스레드를 사용하는 것 같다.&lt;/p&gt;</description>
      <category>JVM/Spring</category>
      <category>Reactive Streams</category>
      <category>Toby</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/137</guid>
      <comments>https://kdhyo98.tistory.com/137#entry137comment</comments>
      <pubDate>Sun, 15 Oct 2023 18:37:37 +0900</pubDate>
    </item>
    <item>
      <title>[Toby Spring Reactive Programming] Operators (2)</title>
      <link>https://kdhyo98.tistory.com/136</link>
      <description>&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;a href=&quot;https://www.youtube.com/watch?v=DChIxy9g19o&quot;&gt;https://www.youtube.com/watch?v=DChIxy9g19o&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토비님 유튜브 강의를 보고 정리한 내용입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;본론&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Operator&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kdhyo98.tistory.com/135&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kdhyo98.tistory.com/135&lt;/a&gt; 첫 번째 강의에서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Publisher, Subscriber를 하나씩 사용해서 리액티브 스트림즈를 간단하게 알아봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Operator는 기존 Publisher -&amp;gt; Subscriber에서 중간에 연산자를 두어 결과를 변경하거나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10개를 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;Publisher (&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;DataA&lt;/span&gt;&lt;/b&gt;) -&amp;gt; (&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;DataA&lt;/b&gt;&lt;/span&gt;) Operator (&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;DataB&lt;/b&gt;&lt;/span&gt;) -&amp;gt; (&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;DataB&lt;/span&gt;&lt;/b&gt;) Subscriber&amp;nbsp; 느낌이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 8의 스트림을 생각하면 이해하기 쉽다. 스트림의 map, reduce, filter 등 기능을 똑같이 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Operator를 구현하는 실습을 해봤다.&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;pre id=&quot;code_1697297276049&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class PubSub {
    static Logger log = Logger.getLogger(PubSub.class.getName());

    public static void main(String[] args) {
        Publisher&amp;lt;Integer&amp;gt; pub = iterPub(Stream.iterate(1, a -&amp;gt; a + 1).limit(10).collect(Collectors.toList()));
        pub.subscribe(logSub());
    }

    private static Publisher&amp;lt;Integer&amp;gt; iterPub(Iterable&amp;lt;Integer&amp;gt; iter) {
        return new Publisher&amp;lt;&amp;gt;() {
            @Override
            public void subscribe(Subscriber&amp;lt;? super Integer&amp;gt; s) {
                s.onSubscribe(new Subscription() {
                    @Override
                    public void request(long n) {
                        try {
                            iter.forEach(s::onNext);
                            s.onComplete();
                        } catch (Exception e) {
                            s.onError(e);
                        }
                    }
                    @Override
                    public void cancel() {}
                });
            }
        };
    }

    private static &amp;lt;T&amp;gt; Subscriber&amp;lt;T&amp;gt; logSub() {
        return new Subscriber&amp;lt;T&amp;gt;() {
            @Override
            public void onSubscribe(Subscription s) {
                log.info(&quot;onSubscribe: &quot;);
                s.request(Long.MAX_VALUE);
            }
            @Override
            public void onNext(T i) { log.info(&quot;onNext: &quot; + i); }
            @Override
            public void onError(Throwable t) { log.info(&quot;onError: &quot; + t); }
            @Override
            public void onComplete() { log.info(&quot;onComplete&quot;); }
        };
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 구성이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 예시와 거의 동일하고, println() 이 log.info()로 바뀐 정도다.&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;DelegateSub&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1697299177870&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class DelegateSub&amp;lt;T, R&amp;gt; implements Subscriber&amp;lt;T&amp;gt; {

    private final Subscriber sub;

    public DelegateSub(Subscriber&amp;lt;? super R&amp;gt; sub) { this.sub = sub; }

    @Override
    public void onSubscribe(Subscription s) { sub.onSubscribe(s); }

    @Override
    public void onNext(T i) { sub.onNext(i); }

    @Override
    public void onError(Throwable t) { sub.onError(t); }

    @Override
    public void onComplete() { sub.onComplete(); }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Operator에서 사용할 SubScriber다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주 기능은 Publisher에서 구현할거고, DeleagteSub은 다시 넘겨주는 역할을 한다.&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;map&lt;/b&gt;&lt;/h4&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre id=&quot;code_1697299383501&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public static void main(String[] args) {
    Publisher&amp;lt;Integer&amp;gt; pub = iterPub(Stream.iterate(1, a -&amp;gt; a + 1).limit(10).collect(Collectors.toList()));
    Publisher&amp;lt;String&amp;gt; mapPub = mapPub(pub, s -&amp;gt; &quot;[ &quot; + s + &quot; ]&quot;);
    mapPub.subscribe(logSub());
}
private static &amp;lt;T, R&amp;gt; Publisher&amp;lt;R&amp;gt; mapPub(Publisher&amp;lt;T&amp;gt; pub, Function&amp;lt;T, R&amp;gt; f) {
    return new Publisher&amp;lt;R&amp;gt;() {
        @Override
        public void subscribe(Subscriber&amp;lt;? super R&amp;gt; sub) {
            pub.subscribe(new DelegateSub&amp;lt;T, R&amp;gt;(sub) {
                @Override
                public void onNext(T i) {
                    sub.onNext(f.apply(i));
                }
            });
        }
    };
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;iterPub -&amp;gt;[ &lt;b&gt;mapPub -&amp;gt; DelegatorSub&lt;/b&gt; ] -&amp;gt; logSub 흐름으로 진행되고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Operator인 &lt;b&gt;mapPub -&amp;gt; DelegatorSub &lt;/b&gt;를 넣어서 Integer -&amp;gt; String 결과로 바꿔주었다.&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;sumPub&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1697299806560&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args) {
    Publisher&amp;lt;Integer&amp;gt; pub = iterPub(Stream.iterate(1, a -&amp;gt; a + 1).limit(10).collect(Collectors.toList()));
    Publisher&amp;lt;Integer&amp;gt; sumPub = sumPub(pub);
    sumPub.subscribe(logSub());
}

private static Publisher&amp;lt;Integer&amp;gt; sumPub(Publisher&amp;lt;Integer&amp;gt; pub) {
    return new Publisher&amp;lt;Integer&amp;gt;() {
        @Override
        public void subscribe(Subscriber&amp;lt;? super Integer&amp;gt; sub) {
            pub.subscribe(new DelegateSub&amp;lt;Integer, Integer&amp;gt;(sub) {
                Integer sum = 0;

                @Override
                public void onNext(Integer i) {
                    sum += i;
                }

                @Override
                public void onComplete() {
                    sub.onNext(sum);
                    sub.onComplete();
                }
            });
        }
    };
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mapPub과 다르게 DelegateSub의 onNext()에서 logSub의 onNext()를 호출하지 않고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onComplete()에서 호출했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 10개의 데이터를 기존처럼 모두 보내는 게 아닌, 중간 sumPub에서 데이터를 가공해 1번만 보내도록 변경할 수도 있다.&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;reducePub&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1697300085749&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public static void main(String[] args) {
    Publisher&amp;lt;Integer&amp;gt; pub = iterPub(Stream.iterate(1, a -&amp;gt; a + 1).limit(10).collect(Collectors.toList()));
    Publisher&amp;lt;StringBuilder&amp;gt; reducePub = reducePub(pub, new StringBuilder(),
            (a, b) -&amp;gt; a.append(b + &quot;,&quot;));
    reducePub.subscribe(logSub());
}

private static &amp;lt;T, R&amp;gt; Publisher&amp;lt;R&amp;gt; reducePub(Publisher&amp;lt;T&amp;gt; pub, R init, BiFunction&amp;lt;R, T, R&amp;gt; bf) {
    return new Publisher&amp;lt;R&amp;gt;() {
        @Override
        public void subscribe(Subscriber&amp;lt;? super R&amp;gt; sub) {
            pub.subscribe(new DelegateSub&amp;lt;T, R&amp;gt;(sub) {
                R result = init;

                @Override
                public void onNext(T i) {
                    result = bf.apply(result, i);
                }

                @Override
                public void onComplete() {
                    sub.onNext(result);
                    sub.onComplete();
                }
            });
        }
    };
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sumPub과 동일하게 중간에 데이터를 가공해 한 번만 보내지만, reduce 개념을 사용하여&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BiFunction을 받아서 처리하도록 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Reactor&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1697300150580&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class ReactorEx {

    public static void main(String[] args) {
        Flux.&amp;lt;Integer&amp;gt;create(e -&amp;gt; {
                    e.next(1);
                    e.next(2);
                    e.next(3);
                    e.complete();
                }).log()
                .map(s -&amp;gt; s * 10)
                .log()
                .reduce(0, Integer::sum)
                .log()
                .subscribe(System.out::println);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 직접 만들어본 map, reduce와 같은 것들은 직접 만들 필요 없이, Reactor라는 라이브러리에서 이미 다 구현을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 한 번 직접 따라서 만들어보니 Reactor를 해볼 때 좀 더 이해가 잘 될 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Spring Response&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1697300413919&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@SpringBootApplication
public class TobyReactiveApplication {

    @RestController()
    public static class Controller {
        @RequestMapping(&quot;/hello&quot;)
        public Publisher&amp;lt;String&amp;gt; hello(String name) {
            return new Publisher&amp;lt;String&amp;gt;() {
                @Override
                public void subscribe(Subscriber&amp;lt;? super String&amp;gt; s) {
                    s.onSubscribe(new Subscription() {
                        @Override
                        public void request(long n) {
                            s.onNext(&quot;Hello &quot;+ name);
                            s.onComplete();
                        }

                        @Override
                        public void cancel() {

                        }
                    });
                }
            };
        }
    }

    public static void main(String[] args) {
        SpringApplication.run(TobyReactiveApplication.class);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring MVC 핸들러에서는 이미 구현이 되어 있어서 리턴타입이 Publisher인걸 보고 자동으로 맵핑해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onComplete(); 가 호출이 되지 않으면, 무한히 response를 보내기에 .. 꼭 호출해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;onNext()를 여러 번 호출해도 결국 마지막 데이터만 전송되는 걸 확인했다.&lt;/p&gt;</description>
      <category>JVM/Spring</category>
      <category>Reactive Streams</category>
      <category>reactor</category>
      <category>Toby</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/136</guid>
      <comments>https://kdhyo98.tistory.com/136#entry136comment</comments>
      <pubDate>Sun, 15 Oct 2023 01:25:53 +0900</pubDate>
    </item>
    <item>
      <title>[Coroutines] Dispatchers 알아보기</title>
      <link>https://kdhyo98.tistory.com/134</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;예제&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1697175645224&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main(): Unit = runBlocking {
    launch { // #1
        println(&quot;main runBlocking      : I'm working in thread ${Thread.currentThread().name}&quot;)
    }
    launch(Dispatchers.Unconfined) { // #2
        println(&quot;Unconfined            : I'm working in thread ${Thread.currentThread().name}&quot;)
    }
    launch(Dispatchers.Default) { // #3
        println(&quot;Default               : I'm working in thread ${Thread.currentThread().name}&quot;)
    }
    launch(newSingleThreadContext(&quot;MyOwnThread&quot;)) { // #4
        println(&quot;newSingleThreadContext: I'm working in thread ${Thread.currentThread().name}&quot;)
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#1&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;상위 컨텍스트를 상속받는다. 예제에서는 runBlocking의 main 스레드를 실행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#2&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;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#3&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;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#4&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;새로운 스레드를 생성한다. 매우 비싼 리소스로, 실제 애플리케이션에서는 필요하지 않을 때 close() 하거나 최상위 변수에 정의하여 애플리케이션 전체에서 재사용하거나 해야한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Unconfined vs confined dispatcher&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Dispatchers.Unconfined&lt;/b&gt; 는 호출한 스레드에서 코루틴을 시작하지만, 첫 번째 일시중단(&lt;b&gt;suspend&lt;/b&gt;) 지점까지만 시작된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일시중단 함수 후에는 호출된 일시 중단 함수에서 사용했던 스레드에서 코루틴을 재개한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;unconfined dispatche&lt;/b&gt;r는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU 시간을 소비하지 않거나 특정 스레드에 국한된 공유 데이터(ex- UI)를 업데이트하지 않는 코루틴에 적합하다.&lt;/p&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;fun main(): Unit = runBlocking {
    launch(Dispatchers.Unconfined) { // not confined -- will work with main thread
        println(&quot;Unconfined      : I'm working in thread ${Thread.currentThread().name}&quot;)
        delay(500)
        println(&quot;Unconfined      : After delay in thread ${Thread.currentThread().name}&quot;)
    }
    launch { // context of the parent, main runBlocking coroutine
        println(&quot;main runBlocking: I'm working in thread ${Thread.currentThread().name}&quot;)
        delay(1000)
        println(&quot;main runBlocking: After delay in thread ${Thread.currentThread().name}&quot;)
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unconfined : I'm working in thread main &lt;br /&gt;main runBlocking : I'm working in thread main &lt;br /&gt;Unconfined : After delay in thread kotlinx.coroutines.DefaultExecutor &lt;br /&gt;main runBlocking. : After delay in thread main&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 사용하는 방식은 아니고, 나중에 실행하기 위해 코루틴을 디스패치할 필요가 없거나 원치 않는 사이드 이펙트가 발생하는 특정 케이스에 유용할 수 있는 고급 메커니즘.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Default vs IO&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;Default&lt;/i&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;스레드풀의 스레드 수는 CPU 코어 수와 같지만, 최소 2개 이상이다.&lt;/li&gt;
&lt;li&gt;CPU 코어 수에 의해 제한되기 때문에 특정 수의 작업만 병렬 처리가 가능하다.&lt;/li&gt;
&lt;li&gt;Context에 Dispatcher나 ContinuationInterceptor가 지정되지 않은 경우 모든 표준 빌더(launch, async ..)에서 기본으로 사용된다.&lt;/li&gt;
&lt;li&gt;많은 계산이 필요하거나 병렬 처리의 이점을 활용하는 CPU 바운드 작업에 적합하다.&lt;/li&gt;
&lt;li&gt;단기 실행 계산 및 소규모 데이터 처리 작업은 기본 디스패처에서 실행하기에 적합하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&lt;b&gt;IO&lt;/b&gt;&lt;/i&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Default의 스레드풀과 별개의 스레드풀을 사용한다.&lt;/li&gt;
&lt;li&gt;즉, IO 디스패처에서 실행하는 코루틴은 기본 디스패처에서 실행중인 메인 스레드나 다른 코루틴을 Blocking 하지 않는다.&lt;/li&gt;
&lt;li&gt;스레드 수는 64개 또는 시스템에서 사용 가능한 CPU 코어 수 중 더 높은 값으로 설정한다.&lt;/li&gt;
&lt;li&gt;시스템 속성 kotlinx.coroutines.io.parallelism 을 통해서도 병렬작업 수를 설정할 수 있다.&lt;/li&gt;
&lt;li&gt;Default에 비해 많은 스레드가 존재하기 때문에 병렬 Blocking 작업을 실행할 수 있다.&lt;/li&gt;
&lt;li&gt;파일 읽기 및 쓰기, 데이터베이스 쿼리 수행 또는 네트워크 요청과 같은 Block 작업이 포함된 IO 집약적인 작업에 적합하다.&lt;/li&gt;
&lt;li&gt;일반적으로 IO 작업은 CPU 리소스를 많이 소모하지 않지만 완료하는 데 시간이 오래걸릴 수 있다.&lt;/li&gt;
&lt;li&gt;따라서 IO 디스패처의 대규모 스레드 풀에 액세스하면 애플리케이션의 I/O 작업 완료 속도를 높일 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kotlinlang.org/docs/coroutine-context-and-dispatchers.html#unconfined-vs-confined-dispatcher&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kotlinlang.org/docs/coroutine-context-and-dispatchers.html#unconfined-vs-confined-dispatcher&lt;/a&gt;&lt;/p&gt;</description>
      <category>JVM/Kotlin</category>
      <category>Coroutines</category>
      <category>Dispatcher</category>
      <category>Kotlin</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/134</guid>
      <comments>https://kdhyo98.tistory.com/134#entry134comment</comments>
      <pubDate>Fri, 13 Oct 2023 19:01:13 +0900</pubDate>
    </item>
    <item>
      <title>[Toby Spring Reactive Programming] Reactive Streams 시작 (1)</title>
      <link>https://kdhyo98.tistory.com/135</link>
      <description>&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;a href=&quot;https://youtu.be/8fenTR3KOJo&quot;&gt;https://youtu.be/8fenTR3KOJo&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토비의 스프링에 있는 토비님의 라이브 유튜브 강의를 보고 정리한 내용입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;본론&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Iterable vs Observable&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Iterable&lt;/b&gt;&lt;/h4&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public static void main(String[] args) {
    Iterable&amp;lt;Integer&amp;gt; iter = () -&amp;gt; new Iterator&amp;lt;&amp;gt;() {
        int i = 0;
        final static int MAX = 10;

        public boolean hasNext() {
            return i &amp;lt; MAX;
        }

        public Integer next() {
            return ++i;
        }
    };

    iter.forEach(System.out::println);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Iterable 인터페이스를 구현하면, for-each를 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로, Collection을 사용할 때 많이 접한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;Observable&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;static class IntObservable extends Observable implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i &amp;lt;= 10; i++) {
            setChanged(); // 변경되었다는 사실을 알려주는 함수
            notifyObservers(i); // 데이터를 전달하는 함수
        }
    }
}
    
public static void main(String[] args) {
    Observer ob = new Observer() {

        @Override
        public void update(Observable o, Object arg) {
            // main이 아닌 별도 스레드에서 동작한다.
            System.out.println(Thread.currentThread().getName() + &quot; &quot; + arg);
        }
    };

    IntObservable io = new IntObservable();
    io.addObserver(ob);

    ExecutorService es = Executors.newSingleThreadExecutor();

    es.execute(io);

    System.out.println(Thread.currentThread().getName() + &quot; EXIT&quot;);
    es.shutdown();
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java 9부터 Depercated됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Observable&lt;/b&gt; - 이벤트를 발송하는 주체. addObserver를 통해 여러 Observer에 이벤트를 발송할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Observer&lt;/b&gt; - 이벤트를 수신하는 곳. 파라미터로는, Observable - 발송한 곳 / Object - Observable에서 받은 이벤트&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Duality (상대성)&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 94px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 17.0542%; height: 18px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 41.124%; height: 18px;&quot;&gt;&lt;b&gt;Iterable&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 41.8217%; height: 18px;&quot;&gt;&lt;b&gt;Observable&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.0542%; height: 20px;&quot;&gt;event&lt;/td&gt;
&lt;td style=&quot;width: 41.124%; height: 20px;&quot;&gt;Pull&lt;/td&gt;
&lt;td style=&quot;width: 41.8217%; height: 20px;&quot;&gt;Push&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 17.0542%; height: 20px;&quot;&gt;fuction call&lt;/td&gt;
&lt;td style=&quot;width: 41.124%; height: 20px;&quot;&gt;T next()&lt;/td&gt;
&lt;td style=&quot;width: 41.8217%; height: 20px;&quot;&gt;void notifyObservers(T)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 17.0542%; height: 18px;&quot;&gt;return type&lt;/td&gt;
&lt;td style=&quot;width: 41.124%; height: 18px;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;width: 41.8217%; height: 18px;&quot;&gt;X&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기능은 동일하지만, 반대방향을 표현한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Observer 문제점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Complete를 알 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. Error를 알 수 없다.&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;b&gt;그래서 나온 해결책&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ractive Streams - &lt;a href=&quot;https://www.reactive-streams.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.reactive-streams.org/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;non-blocking, backPressure를 이용하여 비동기 스트림 처리의 표준을 제공하는 Java 진영 표준 스펙.&lt;/p&gt;
&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;Publisher&lt;/b&gt; - 구독자의 수요에 따라 구독자에게 데이터를 게시하는 데이터 공급자.&amp;nbsp; (==Observable)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Subscriber&lt;/b&gt; - 데이터의 소비자로서 Publisher를 구독한 후 데이터를 수신할 수 있다. (==Observer)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Subscription&lt;/b&gt; - 발행자(Publisher)와 구독자(Subscriber)사이의 연결을 나타낸다. 이를 통해 구독자는 데이터의 흐름을 제어할 수 있다. (백프레셔 기능) Observer 패턴에서는 이 개념이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Processor&lt;/b&gt; - Publisher, Subscriber 역할을 동시에 수행하는 요소로, 중간에서 데이터를 받고 변환하여 다른 구독자에게 전달한다. Subscription과 동일하게 Observer에는 이런 개념이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java9에서는 &lt;a href=&quot;https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/Flow.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Flow API&lt;/a&gt;로 위 스펙을 추가했고, &lt;a href=&quot;https://github.com/reactive-streams/reactive-streams-jvm&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;reactive-streams&lt;/a&gt;&amp;nbsp;란 라이브러리도 제공하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 설명한 4가지 인터페이스는 거의 동일하게 정의되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;/span&gt;구현체로는 RxJava(ReactiveX), Reactor 등이 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Java9의 FLow API를 이용하여 만들어보기.&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;java&quot; data-ke-language=&quot;java&quot;&gt;&lt;code&gt;public static void main(String[] args) throws InterruptedException {
    Iterable&amp;lt;Integer&amp;gt; itr = Arrays.asList(1, 2, 3, 4, 5);
    ExecutorService es = Executors.newCachedThreadPool();
    
    // Publisher &amp;lt;- Observable
    Publisher p = new Publisher() {
        @Override
        public void subscribe(Subscriber subscriber) {
            Iterator&amp;lt;Integer&amp;gt; it = itr.iterator();
            subscriber.onSubscribe(new Subscription() {
                @Override
                public void request(long n) {
                    es.execute(() -&amp;gt; {
                        int i = 0;
                        try {
                            while (i++ &amp;lt; n) {
                                if (it.hasNext()) {
                                    subscriber.onNext(it.next());
                                } else {
                                    subscriber.onComplete();
                                    break;
                                }
                            }
                        } catch (Exception e) {
                            subscriber.onError(e);
                        }
                    });
                }

                @Override
                public void cancel() {

                }
            });
        }
    };

    // Subscriber &amp;lt;- Observer
    Subscriber&amp;lt;Integer&amp;gt; subscriber = new Subscriber&amp;lt;&amp;gt;() {
        Subscription subscription;

        @Override
        public void onSubscribe(Subscription subscription) {
            System.out.println(&quot;onSubscribe&quot;);
            this.subscription = subscription;
            this.subscription.request(1);
        }

        @Override
        public void onNext(Integer item) {
            System.out.println(Thread.currentThread().getName() + &quot; onNext = &quot; + item);
            this.subscription.request(1);
        }

        @Override
        public void onError(Throwable throwable) {
            System.out.println(&quot;onError = &quot; + throwable);
        }

        @Override
        public void onComplete() {
            System.out.println(&quot;onComplete&quot;);
        }
    };

    p.subscribe(subscriber);
    es.awaitTermination(10, java.util.concurrent.TimeUnit.HOURS);
    es.shutdown();
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;onSubscribe&lt;br /&gt;pool-1-thread-1&amp;nbsp;onNext&amp;nbsp;=&amp;nbsp;1&lt;br /&gt;pool-1-thread-2&amp;nbsp;onNext&amp;nbsp;=&amp;nbsp;2&lt;br /&gt;pool-1-thread-3&amp;nbsp;onNext&amp;nbsp;=&amp;nbsp;3&lt;br /&gt;pool-1-thread-4&amp;nbsp;onNext&amp;nbsp;=&amp;nbsp;4&lt;br /&gt;pool-1-thread-3&amp;nbsp;onNext&amp;nbsp;=&amp;nbsp;5&lt;br /&gt;onComplete&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JVM/Spring</category>
      <category>java</category>
      <category>reactive</category>
      <category>Reactive Streams</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/135</guid>
      <comments>https://kdhyo98.tistory.com/135#entry135comment</comments>
      <pubDate>Fri, 13 Oct 2023 18:23:43 +0900</pubDate>
    </item>
    <item>
      <title>[docker-compose] mysql 셋팅 참고</title>
      <link>https://kdhyo98.tistory.com/133</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;초기 데이터 셋팅&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;volumes:
  - ./mysql/init:/docker-entrypoint-initdb.d&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker-entrypoint-initdb.d에&amp;nbsp;&lt;b&gt;./mysql/init&lt;/b&gt; 디렉토리에 있는 sql 파일을 추가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미지 실행 시 자동으로 해당 SQL 스크립트를 읽어서 세팅한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;command:
  - --skip-character-set-client-handshake
  - --character-set-server=utf8mb4
  - --collation-server=utf8mb4_unicode_ci&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f7f7f8; color: #111827; text-align: left;&quot;&gt;--skip-character-set-client-handshake&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;클라이언트와 관계없이 '--character-set-server'에서 지정한 문자집합을 기본으로 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;이게 없다면, 클라이언트의 시스템 인코딩을 사용하게 되어 OS마다 인코딩이 달라질 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f7f7f8; color: #111827; text-align: left;&quot;&gt;--character-set-server=utf8mb4&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 문자열을 utf8mb4로 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mb3는 이제 사용하지 않는다. mb4는 이모지까지 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f7f7f8; color: #111827; text-align: left;&quot;&gt;--collation-server=utf8mb4_unicode_ci&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자셋 정렬 알고리즘을 지정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8.0부터 기본 collation이 utf8mb4_0900_ai_ci로 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;차이점은, 0900은 악센트도 구분하지 않고, 최신 유니코드 대조 알고리즘을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps</category>
      <category>docker-compose</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/133</guid>
      <comments>https://kdhyo98.tistory.com/133#entry133comment</comments>
      <pubDate>Tue, 26 Sep 2023 18:39:46 +0900</pubDate>
    </item>
    <item>
      <title>보이지 않는 위협 - 사이버 보안</title>
      <link>https://kdhyo98.tistory.com/132</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1994&quot; data-origin-height=&quot;2505&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lXjRQ/btsvfyN4IzG/ifJZbkjdsodTtpURGKbxT0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lXjRQ/btsvfyN4IzG/ifJZbkjdsodTtpURGKbxT0/img.jpg&quot; data-alt=&quot;보이지 않는 위협&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lXjRQ/btsvfyN4IzG/ifJZbkjdsodTtpURGKbxT0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlXjRQ%2FbtsvfyN4IzG%2FifJZbkjdsodTtpURGKbxT0%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;504&quot; height=&quot;633&quot; data-origin-width=&quot;1994&quot; data-origin-height=&quot;2505&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;23년 8월 출간된 즉 한 달전에 나온 책인 만큼&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코로나, 비트코인, 러시아와 우크라이나 전쟁, CHAT GPT 등 최신 이슈를 소재로 하여 책을 풀어가는 게 책 읽는 내내 흥미를 자극시켰다.&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;2110&quot; data-origin-height=&quot;1109&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cN6Bsu/btsvna5Mxuf/VsDNSzVN4dNdOtiYpir7g0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cN6Bsu/btsvna5Mxuf/VsDNSzVN4dNdOtiYpir7g0/img.jpg&quot; data-alt=&quot;보이지 않는 위협&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cN6Bsu/btsvna5Mxuf/VsDNSzVN4dNdOtiYpir7g0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcN6Bsu%2Fbtsvna5Mxuf%2FVsDNSzVN4dNdOtiYpir7g0%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;2110&quot; height=&quot;1109&quot; data-origin-width=&quot;2110&quot; data-origin-height=&quot;1109&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;미국 사례들을 통해 왜 미국이 IT 강국이고, 미국 대통령들이 사이버 보안 지원에 아낌없이 하는지를 설명하는 반면,&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;컴퓨터, 각자 들고 있는 스마트폰, TV를 포함한 가전제품 뿐 아니라 매장의 키오스크, 배, 비행기, 우주선 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리 일상생활과 밀접한 것들을 포함해 모든 것들이 컴퓨터로 이루어져 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크를 통해 모든 컴퓨터들은 통신을 할 수 있으며 하나라도 범죄에 노출이 된다면 연결된 모든 컴퓨터가 보안에 위협을 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 사람들은 안일하게 생각하고 있다. 백신 회사가 알아서 하겠지, 보안담당자가 알아서 하겠지 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른사람이 신경쓰고 각자 모두 신경써야 된다고 지적해주고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책 구절을 빌려 중요한 내용을 공유하고 싶다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;결국 기본이 중요하다.&lt;br /&gt;코로나19 기간 마스크를 쓰고, 손을 자주 씻는 덕에 독감환자가 크게 감소했다고 한다.&lt;br /&gt;결국 위생 관념이 철저하면 감기에 잘 걸리지 않는 평범한 사실이 입증된 셈이다.&lt;br /&gt;&lt;br /&gt;사이버공간 또한 위생이 기본이다.&lt;br /&gt;비싼 백신을 설치하고, 내부망으로 통신하니까 안전하다고 생각하면 안된다.&lt;br /&gt;내 컴퓨터에서 피싱 메일을 클릭하는 순간 나와 네트워크로 연결된 모든 곳이 위협을 받을 수 있다.&lt;br /&gt;만병통치약은 없다.&lt;br /&gt;시스템과 소프트웨어의 취약점을 끊임없이 점검하고, 피싱 메일을 조심하고, 패스워드 관리를 철저히 하는 것이 기본이다.&lt;br /&gt;&lt;br /&gt;항상 최신을 따라가며 업데이트하는 게 좋지 않을 수도 있지만, 최소한 취약점 해결한 업데이트는 항상 받도록 하자.&lt;br /&gt;&lt;br /&gt;나를 아는 게 중요하다.&lt;br /&gt;아주 사소한 잘못된 취약점 하나라도 발견되면 해커에게 당할 수 있다.&lt;br /&gt;모든 걸 막을 수는 없지만 최소한 나를 알고 내가 가장 지켜야하는 것이 무엇인지 알아야&lt;br /&gt;가장 중요한 걸 이중 삼중으로 방화벽을 칠 수 있다.&lt;br /&gt;내가 지켜야하는 게 뭔지도 모른 채 비싼 백신과 보안프로그램들을 아무리 산다한들 나한테 필요가 없다면 쓸모가 없다.&lt;br /&gt;&lt;br /&gt;끊임없이 신기술이 나오는 이 시대에는 더 다양한 방법으로 보안에 노출될 수 있다.&lt;br /&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 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;개발자로 살면서 코드작성에 급급하고 보안을 크게 생각하지 않고 살아왔는데,&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;개발자 뿐 아니라 IT 종사자가 아닌 일반 사무를 보는 사람들도 어렵지 않게 읽을 수 있을 것 같고,&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;한줄평: IT 선배 종사자의 값진 경험과 최신 이슈에 대해 보안적 관점으로 볼 수 있는 계기가 되어서 매우 좋았습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2320&quot; data-origin-height=&quot;871&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/F1Xk3/btsviVa0xkS/uFibPq8oouLZVrzE7OQsZK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/F1Xk3/btsviVa0xkS/uFibPq8oouLZVrzE7OQsZK/img.jpg&quot; data-alt=&quot;당신이 돈을 지불하지 않는다면 당신이 상품입니다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/F1Xk3/btsviVa0xkS/uFibPq8oouLZVrzE7OQsZK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FF1Xk3%2FbtsviVa0xkS%2FuFibPq8oouLZVrzE7OQsZK%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;2320&quot; height=&quot;871&quot; data-origin-width=&quot;2320&quot; data-origin-height=&quot;871&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 개인정보를 상품으로 SNS, 네비, 메신저 등을 사용하고 있었다.&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;s&gt;내 개인정보.. 많이 팔렸을텐데.. 체념하고 앞으로 내 관리 하에 많이 팔고 다녀야겠다..&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&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;&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: start;&quot;&gt; &quot;한빛미디어 &amp;lt;나는 리뷰어다&amp;gt; 활동을 위해서 책을 제공받아 작성된 서평입니다.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>HisStory/나는리뷰어다2023</category>
      <category>나는리뷰어다</category>
      <category>한빛미디어</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/132</guid>
      <comments>https://kdhyo98.tistory.com/132#entry132comment</comments>
      <pubDate>Sun, 24 Sep 2023 20:37:35 +0900</pubDate>
    </item>
    <item>
      <title>[Hibernate] 설정 옵션 목록</title>
      <link>https://kdhyo98.tistory.com/131</link>
      <description>&lt;pre id=&quot;code_1695102645609&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
  jpa:
    properties:
      hibernate:
        query:
          plan_cache_max_size: 1
          plan_parameter_metadata_max_size: 1&lt;/code&gt;&lt;/pre&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; yaml, properties 를 사용해서 하이버네이트 옵션을 주곤 한다.&lt;/p&gt;
&lt;p data-ke-size=&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 AvailableSettings는 hibernate-core에 있는 하이버네이트 옵션을 상수로 표현한 인터페이스다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;615&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caNSLg/btsugikXmlX/8Y6D3AcJaF3kxPsOu9BVS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caNSLg/btsugikXmlX/8Y6D3AcJaF3kxPsOu9BVS1/img.png&quot; data-alt=&quot;AvailableSettings&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caNSLg/btsugikXmlX/8Y6D3AcJaF3kxPsOu9BVS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaNSLg%2FbtsugikXmlX%2F8Y6D3AcJaF3kxPsOu9BVS1%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;628&quot; height=&quot;615&quot; data-origin-width=&quot;628&quot; data-origin-height=&quot;615&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AvailableSettings&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;hibernate-envers 또한 상수로 정의되어 있다. 클래스명 - EnversSettings&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;573&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cw8jiO/btsuGkBJRIw/ZMXemCoRfZrsUZkfyVLQSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cw8jiO/btsuGkBJRIw/ZMXemCoRfZrsUZkfyVLQSk/img.png&quot; data-alt=&quot;EnversSettings&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cw8jiO/btsuGkBJRIw/ZMXemCoRfZrsUZkfyVLQSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcw8jiO%2FbtsuGkBJRIw%2FZMXemCoRfZrsUZkfyVLQSk%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;904&quot; height=&quot;573&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;573&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;EnversSettings&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;hibernate 외에도 별도 옵션을 줄 땐 어떤 옵션들이 있는지, 정의된 클래스가 있는지 종종 찾아볼 것 같다.&lt;/p&gt;</description>
      <category>JVM/JPA</category>
      <category>hibernate</category>
      <category>hibernate-envers</category>
      <category>하이버네이트</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/131</guid>
      <comments>https://kdhyo98.tistory.com/131#entry131comment</comments>
      <pubDate>Tue, 19 Sep 2023 19:00:10 +0900</pubDate>
    </item>
    <item>
      <title>육각형개발자 리뷰 - 핵심 역량 키우기</title>
      <link>https://kdhyo98.tistory.com/130</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oPfsd/btsrDClGVpH/hZTNu7imuOilsp2jd5VAmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oPfsd/btsrDClGVpH/hZTNu7imuOilsp2jd5VAmK/img.png&quot; data-alt=&quot;표지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oPfsd/btsrDClGVpH/hZTNu7imuOilsp2jd5VAmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoPfsd%2FbtsrDClGVpH%2FhZTNu7imuOilsp2jd5VAmK%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;400&quot; height=&quot;582&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;582&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;표지&lt;/figcaption&gt;
&lt;/figure&gt;
&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책 제목부터 표지, 목차가 지금 내 시기에 읽으면 딱 좋겠다는 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저자 또한 내가 재밌게 읽었던 '도메인 주도 개발 시작하기'와 '최범균의 JSP 2.3 웹 프로그래밍 : 기초부터 중급까지'의 저자인 최범균님이었다. 안 읽어볼 이유가 없었고, 기대를 가지고 읽기 시작한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;본론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VA7k6/btsrDerMi7M/Q2BJCFRFr43YkX0xKjo351/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VA7k6/btsrDerMi7M/Q2BJCFRFr43YkX0xKjo351/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VA7k6/btsrDerMi7M/Q2BJCFRFr43YkX0xKjo351/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVA7k6%2FbtsrDerMi7M%2FQ2BJCFRFr43YkX0xKjo351%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;651&quot; height=&quot;488&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&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;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ltbOI/btsrCmqaJVi/06DwJaRn2r7hOOkMjgeZgK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ltbOI/btsrCmqaJVi/06DwJaRn2r7hOOkMjgeZgK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ltbOI/btsrCmqaJVi/06DwJaRn2r7hOOkMjgeZgK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FltbOI%2FbtsrCmqaJVi%2F06DwJaRn2r7hOOkMjgeZgK%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;644&quot; height=&quot;483&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목차를 보면 알겠지만, 단순히 코딩이나 기술서적은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자로 살아가면서 단순 코딩과 기술학습 뿐 아니라 어떤 것들을 잘하고 어떤 것들을 생각하고, 나아가야 하는지를 말하고자 하는 책으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1장 들어가며&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;3024&quot; data-origin-height=&quot;2470&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtez9W/btsrH5nhPUr/wehhAfLwx3wlshkeM6s3lk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtez9W/btsrH5nhPUr/wehhAfLwx3wlshkeM6s3lk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtez9W/btsrH5nhPUr/wehhAfLwx3wlshkeM6s3lk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdtez9W%2FbtsrH5nhPUr%2FwehhAfLwx3wlshkeM6s3lk%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;432&quot; height=&quot;353&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;2470&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 장에서는 저자가 신입때 겪었던 실패들을 이야기 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당시 신입으로서 최선을 다해 열심히 했지만, 프로젝트가 흐지부지 끝나는 경험도 해보고, 현재 돌아봤을 때 어떤 게 문제였는지, 단순 코딩 뿐만 아니라 외적으로 어떤 게 중요한지를 설명해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 회사와 나에게 돈을 벌어주는 기능을 만드는 게 우리의 몫이고, 이건 코딩만으로 해결할 수 없는 부분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 관점에서 개발을 바라봐서 시야가 넓어지는 게 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2장 구현 기술과 학습&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;2989&quot; data-origin-height=&quot;1490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lXBuL/btsrS3ITJw7/YY4nuECu8UMmP4qZqKMnZ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lXBuL/btsrS3ITJw7/YY4nuECu8UMmP4qZqKMnZ1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lXBuL/btsrS3ITJw7/YY4nuECu8UMmP4qZqKMnZ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlXBuL%2FbtsrS3ITJw7%2FYY4nuECu8UMmP4qZqKMnZ1%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;292&quot; data-origin-width=&quot;2989&quot; data-origin-height=&quot;1490&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자로 적어도 1-20년 이상 일하게 될텐데, 개발 시장은 매우 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇 년 전에 핫했던 기술이 소리소문 없이 다른 기술에 밀려 사라지기 태반이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거기에 새로 생기는 기술은 이름 외우기 힘들 정도로 많이 생겨나고, 기존 기술들도 배워야하고, 핫한 기술도 배워보고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 우리는 어떤 기준으로 학습 대상을 골라야할까? 현재 내 상황에서는 어떤 방식으로 학습해야 할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;깊게 이해하지 않고 단순 구현기술만 배우면 왜 위험한지, 왜 새로운 기술을 배워야 하는지, 그렇다고 왜 새로운 기술만을 고집해서 도입하면 안되는지를 설명해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실무에서 내가 공부한 기술을 업무에 어떻게 적용할지, 어떻게 설득해야할지를 생각해볼 수 있어서 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3장 소프트웨어 가치와 비용&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;2521&quot; data-origin-height=&quot;1079&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KqdCA/btsrUsCoXbO/qZmpHVQWN8lhgcRhhfU2P0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KqdCA/btsrUsCoXbO/qZmpHVQWN8lhgcRhhfU2P0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KqdCA/btsrUsCoXbO/qZmpHVQWN8lhgcRhhfU2P0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKqdCA%2FbtsrUsCoXbO%2FqZmpHVQWN8lhgcRhhfU2P0%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;626&quot; height=&quot;268&quot; data-origin-width=&quot;2521&quot; data-origin-height=&quot;1079&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오래된 소프트웨어는 지속적으로 유지보수를 해야하는데, 유지보수를 할 때는 기존 만들 때보다 비용이 더 많이든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간이 지남에 따라 프로젝트가 커지고, 코드도 많아지고, 오래된 코드도 많아진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오래된 코드가 많아지면 많아질 수록 리팩토링에 두려움은 커지고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 오래된 코드가 많아지는 악순환의 반복으로 소프트웨어의 가치가 손실될 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4장 코드 이해&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;2682&quot; data-origin-height=&quot;950&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNvqXX/btsrR0s0Z6D/fs8pQfaLNoLDUbXu4FUksK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNvqXX/btsrR0s0Z6D/fs8pQfaLNoLDUbXu4FUksK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNvqXX/btsrR0s0Z6D/fs8pQfaLNoLDUbXu4FUksK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNvqXX%2FbtsrR0s0Z6D%2Ffs8pQfaLNoLDUbXu4FUksK%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;564&quot; height=&quot;200&quot; data-origin-width=&quot;2682&quot; data-origin-height=&quot;950&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;3024&quot; data-origin-height=&quot;1866&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uGTEu/btsrNm4iX4B/p8DzK4PPTBnDu3tmkOqSjk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uGTEu/btsrNm4iX4B/p8DzK4PPTBnDu3tmkOqSjk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uGTEu/btsrNm4iX4B/p8DzK4PPTBnDu3tmkOqSjk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuGTEu%2FbtsrNm4iX4B%2Fp8DzK4PPTBnDu3tmkOqSjk%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;523&quot; height=&quot;323&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;1866&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;UML을 그리는 시간이 아깝다고 생각했던 시절이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 한 번 그려보고 더 잘 이해가 되는 걸 경험한 이후부터는 의식적으로라도 그려보려고 노력 중이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책에서도 시각적으로 표현하는 게 이해하는 데 얼마나 도움을 주는 지 잘 설명해주고, 책도 추천해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 코드 개선을 위한 리팩터링이 아닌, 이해 목적으로 하는 리팩터링에 대해서도 말해주는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각 못 했던 방법이라 나중에 다른 프로젝트를 진행할 때 해봐야겠다는 생각이 들었다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;5장 응집도와 결합도&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;2729&quot; data-origin-height=&quot;2091&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ym9SR/btsrToNKxPN/KgSAP1zQVrctqqKta6Yit0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ym9SR/btsrToNKxPN/KgSAP1zQVrctqqKta6Yit0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ym9SR/btsrToNKxPN/KgSAP1zQVrctqqKta6Yit0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fym9SR%2FbtsrToNKxPN%2FKgSAP1zQVrctqqKta6Yit0%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;377&quot; data-origin-width=&quot;2729&quot; data-origin-height=&quot;2091&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;응집도를 높이고, 결합도를 낮춰라. 라는 건 많은 리팩터링, 아키텍처, 디자인패턴 등 다양한 곳에서 들을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 코드를 어떻게 수정하면 응집도를 높이고, 결합도를 낮추는 건지 코드 단으로 설명해줘서 이해하기 쉬웠다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;6장 리팩터링&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;2544&quot; data-origin-height=&quot;1540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPnIxH/btsrS49JxjV/0LbQB1eTrgdgohkRsxkXFK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPnIxH/btsrS49JxjV/0LbQB1eTrgdgohkRsxkXFK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPnIxH/btsrS49JxjV/0LbQB1eTrgdgohkRsxkXFK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPnIxH%2FbtsrS49JxjV%2F0LbQB1eTrgdgohkRsxkXFK%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;520&quot; height=&quot;315&quot; data-origin-width=&quot;2544&quot; data-origin-height=&quot;1540&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;2425&quot; data-origin-height=&quot;747&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/de8NM9/btsrZmVO3Ij/rqSGZEaJBO0OxXAv6KBAO0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/de8NM9/btsrZmVO3Ij/rqSGZEaJBO0OxXAv6KBAO0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/de8NM9/btsrZmVO3Ij/rqSGZEaJBO0OxXAv6KBAO0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fde8NM9%2FbtsrZmVO3Ij%2FrqSGZEaJBO0OxXAv6KBAO0%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;477&quot; height=&quot;147&quot; data-origin-width=&quot;2425&quot; data-origin-height=&quot;747&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;2858&quot; data-origin-height=&quot;598&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyS8Z7/btsr0suIIOK/hBfUVZ8jxD0pMGk8OMDPv0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyS8Z7/btsr0suIIOK/hBfUVZ8jxD0pMGk8OMDPv0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyS8Z7/btsr0suIIOK/hBfUVZ8jxD0pMGk8OMDPv0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyS8Z7%2Fbtsr0suIIOK%2FhBfUVZ8jxD0pMGk8OMDPv0%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;507&quot; height=&quot;106&quot; data-origin-width=&quot;2858&quot; data-origin-height=&quot;598&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;집중해서 본 파트였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수많은 레거시는 항상 이유가 있고, 그 상황에 최선이었을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 범인을 찾는 게 아니라 더 좋은 방향으로 나아가기 위해서 일을 하기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;개선할 거리가 있다. 해보자!&quot; 라는 마인드는 참 좋은 마인드라 생각이 들었다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;7장 테스트&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;2904&quot; data-origin-height=&quot;1794&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/db8IaP/btsrYNTHalr/vAXXqUhjDmFuy2rbjcCEr0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/db8IaP/btsrYNTHalr/vAXXqUhjDmFuy2rbjcCEr0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/db8IaP/btsrYNTHalr/vAXXqUhjDmFuy2rbjcCEr0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdb8IaP%2FbtsrYNTHalr%2FvAXXqUhjDmFuy2rbjcCEr0%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;460&quot; height=&quot;284&quot; data-origin-width=&quot;2904&quot; data-origin-height=&quot;1794&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트코드의 중요성은 개발자라면 정말 많이 들어봤을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나 역시 NextStep의 TDD를 배우며 연습했지만, 막상 익숙하지 않으니 실무에서 잘 작성하지 않고 부채마냥 앉고 갈 때가 있다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;8장 아키텍처, 패턴&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;2868&quot; data-origin-height=&quot;920&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FEGCQ/btsslbsGJ77/g7enlY9OZb4oiaUQ6dpl31/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FEGCQ/btsslbsGJ77/g7enlY9OZb4oiaUQ6dpl31/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FEGCQ/btsslbsGJ77/g7enlY9OZb4oiaUQ6dpl31/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFEGCQ%2FbtsslbsGJ77%2Fg7enlY9OZb4oiaUQ6dpl31%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;580&quot; height=&quot;186&quot; data-origin-width=&quot;2868&quot; data-origin-height=&quot;920&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;2977&quot; data-origin-height=&quot;1232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UBYLe/btssgmveyOO/aMkdyf9HZkqJrwpLkoJfk1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UBYLe/btssgmveyOO/aMkdyf9HZkqJrwpLkoJfk1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UBYLe/btssgmveyOO/aMkdyf9HZkqJrwpLkoJfk1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUBYLe%2FbtssgmveyOO%2FaMkdyf9HZkqJrwpLkoJfk1%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;232&quot; data-origin-width=&quot;2977&quot; data-origin-height=&quot;1232&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MSA, DDD, Event Driven 등 다양한 아키텍처가 쏟아져 나오고 있다.&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;b&gt;같은 문제를 해결하려 한다면 복잡한 구조보다 단순한 구조가 더 좋다는 사실을 항상 명심하자.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 회사에서 다양한 아키텍처를 적용하고 있는데, 왜 전환하려 하는지, 단순히 하고 싶어서 더 복잡해지는 건 아닌지, 어떤게 개선되는 지를 항상 생각해보고 작업해야겠다는 생각을 다시 한 번 하게됐다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;9장 업무 관리&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;56A3B816-AF25-4896-9D83-8E8F1AF2F71A_1_102_a.jpeg&quot; data-origin-width=&quot;2747&quot; data-origin-height=&quot;1144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckE3qq/btssilCkEl8/xChtqOIYO5WgUJraNzJzQK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckE3qq/btssilCkEl8/xChtqOIYO5WgUJraNzJzQK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckE3qq/btssilCkEl8/xChtqOIYO5WgUJraNzJzQK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckE3qq%2FbtssilCkEl8%2FxChtqOIYO5WgUJraNzJzQK%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;500&quot; height=&quot;208&quot; data-filename=&quot;56A3B816-AF25-4896-9D83-8E8F1AF2F71A_1_102_a.jpeg&quot; data-origin-width=&quot;2747&quot; data-origin-height=&quot;1144&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;0BEE2895-23E4-4B55-A7B1-CBF86474F637_1_201_a.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;999&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bw96cJ/btsshnAp22j/NWWKEuHzIT4iKCRhDKxxBk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bw96cJ/btsshnAp22j/NWWKEuHzIT4iKCRhDKxxBk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bw96cJ/btsshnAp22j/NWWKEuHzIT4iKCRhDKxxBk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbw96cJ%2FbtsshnAp22j%2FNWWKEuHzIT4iKCRhDKxxBk%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;454&quot; height=&quot;150&quot; data-filename=&quot;0BEE2895-23E4-4B55-A7B1-CBF86474F637_1_201_a.jpeg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;999&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1000B86A-A197-4262-B39A-AD1E5A773F0F_1_201_a.jpeg&quot; data-origin-width=&quot;2896&quot; data-origin-height=&quot;832&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bK2ohj/btssk1KmNLh/VIiSjXRToxRW1csTIe7Db1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bK2ohj/btssk1KmNLh/VIiSjXRToxRW1csTIe7Db1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bK2ohj/btssk1KmNLh/VIiSjXRToxRW1csTIe7Db1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbK2ohj%2Fbtssk1KmNLh%2FVIiSjXRToxRW1csTIe7Db1%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;540&quot; height=&quot;155&quot; data-filename=&quot;1000B86A-A197-4262-B39A-AD1E5A773F0F_1_201_a.jpeg&quot; data-origin-width=&quot;2896&quot; data-origin-height=&quot;832&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3AD6092C-85D4-4DB7-B43A-0702B0B02CC9_1_102_a.jpeg&quot; data-origin-width=&quot;2891&quot; data-origin-height=&quot;1088&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUicj1/btsscFh14bP/ks872XbbFeKKQYcwEpTDHk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUicj1/btsscFh14bP/ks872XbbFeKKQYcwEpTDHk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUicj1/btsscFh14bP/ks872XbbFeKKQYcwEpTDHk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUicj1%2FbtsscFh14bP%2Fks872XbbFeKKQYcwEpTDHk%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;211&quot; data-filename=&quot;3AD6092C-85D4-4DB7-B43A-0702B0B02CC9_1_102_a.jpeg&quot; data-origin-width=&quot;2891&quot; data-origin-height=&quot;1088&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 파트는 하고 싶은 말이 정말 많아서 여러 주제로 글을 썼다지웠다 반복했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 챕터에 다양한 이야기가 있는데 이 파트는 꼭 읽어봤으면 좋겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;신입이 개발 외적으로 어려워하고, 실수하는 부분을 이렇게 해봐라 라고 선배 개발자가 알려준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 거의 다 된건 구현 이상으로 테스트까지 진행하고 있는 상태다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 일을 잘 나누고 일정 산정해보는 연습을 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 안 될 땐 대안을 제시하자.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;10장 정리하고 공유하기&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;65E2C844-4976-417C-98BD-18DE0AF1739A_1_201_a.jpeg&quot; data-origin-width=&quot;2661&quot; data-origin-height=&quot;1827&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZjvlm/btssgrwx2vu/Ev2L5xvlkTNKQw7DdVn8Uk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZjvlm/btssgrwx2vu/Ev2L5xvlkTNKQw7DdVn8Uk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZjvlm/btssgrwx2vu/Ev2L5xvlkTNKQw7DdVn8Uk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZjvlm%2Fbtssgrwx2vu%2FEv2L5xvlkTNKQw7DdVn8Uk%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;475&quot; height=&quot;326&quot; data-filename=&quot;65E2C844-4976-417C-98BD-18DE0AF1739A_1_201_a.jpeg&quot; data-origin-width=&quot;2661&quot; data-origin-height=&quot;1827&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;D1EADEB4-1273-404E-87C9-527030C2C857_1_201_a.jpeg&quot; data-origin-width=&quot;2754&quot; data-origin-height=&quot;1493&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c9rTzS/btssimH0Zia/bJesWNHHLhe0K8GIkr4Yu0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c9rTzS/btssimH0Zia/bJesWNHHLhe0K8GIkr4Yu0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c9rTzS/btssimH0Zia/bJesWNHHLhe0K8GIkr4Yu0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc9rTzS%2FbtssimH0Zia%2FbJesWNHHLhe0K8GIkr4Yu0%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;502&quot; height=&quot;272&quot; data-filename=&quot;D1EADEB4-1273-404E-87C9-527030C2C857_1_201_a.jpeg&quot; data-origin-width=&quot;2754&quot; data-origin-height=&quot;1493&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 하고싶은 걸 있을 때 어필을 잘 하려면 말을 잘 해야하고, 문서를 잘 작성해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 말과 글에서 적은 '잘'은 이쁜 겉치레가 많은 게 아니다. 내가 말하고자 하는 내용을 명확하게 전달하는 것을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 의견을 제대로 전달하기 위해서는 글쓰기와 발표를 조금씩 연습해봐야겠다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;11장 리더와 팔로워&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;502459C6-10D6-464E-94C9-53BEFF9B2FA2_1_102_a.jpeg&quot; data-origin-width=&quot;2209&quot; data-origin-height=&quot;1422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brDJrG/btsshrW7QFE/yVGm5xTtck0vhiZakq3ZP1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brDJrG/btsshrW7QFE/yVGm5xTtck0vhiZakq3ZP1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brDJrG/btsshrW7QFE/yVGm5xTtck0vhiZakq3ZP1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrDJrG%2FbtsshrW7QFE%2FyVGm5xTtck0vhiZakq3ZP1%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;489&quot; height=&quot;315&quot; data-filename=&quot;502459C6-10D6-464E-94C9-53BEFF9B2FA2_1_102_a.jpeg&quot; data-origin-width=&quot;2209&quot; data-origin-height=&quot;1422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;704A2CE6-40DE-4ECA-BA8E-9C3DC7612E99_1_201_a.jpeg&quot; data-origin-width=&quot;2269&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjPJ9F/btssijR3HnY/QrYBDlaaKHjGYeZxpCxnRk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjPJ9F/btssijR3HnY/QrYBDlaaKHjGYeZxpCxnRk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjPJ9F/btssijR3HnY/QrYBDlaaKHjGYeZxpCxnRk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcjPJ9F%2FbtssijR3HnY%2FQrYBDlaaKHjGYeZxpCxnRk%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;486&quot; height=&quot;131&quot; data-filename=&quot;704A2CE6-40DE-4ECA-BA8E-9C3DC7612E99_1_201_a.jpeg&quot; data-origin-width=&quot;2269&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;9C02574F-3BBB-47D5-AF8F-0F2334D1387F_1_201_a.jpeg&quot; data-origin-width=&quot;2644&quot; data-origin-height=&quot;798&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cH7c7Z/btssif9YDOP/SakDisPHwMHONQ8hXCBIA0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cH7c7Z/btssif9YDOP/SakDisPHwMHONQ8hXCBIA0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cH7c7Z/btssif9YDOP/SakDisPHwMHONQ8hXCBIA0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcH7c7Z%2Fbtssif9YDOP%2FSakDisPHwMHONQ8hXCBIA0%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;496&quot; height=&quot;150&quot; data-filename=&quot;9C02574F-3BBB-47D5-AF8F-0F2334D1387F_1_201_a.jpeg&quot; data-origin-width=&quot;2644&quot; data-origin-height=&quot;798&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 중요한건 사람을 어떻게 대하느냐라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같이 일하는 사람들끼리 서로 소통하고, 의견제시하고 조율하고 하면서 프로젝트를 성공시켜야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러기 위해서는 의견을 제시할 줄도 알아야하고, 수용할 줄도 알아야한다. 무조건 내 의견이 맞지도 않고, 무조건 상대 의견이 맞지도 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리더도 팔로워도 서로를 신뢰하고, 존중하자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;1~3년차 정도 되는 주니어 개발자가 읽으면 도움이 된다고 생각한다. (내가 저 연차이기 때문..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책 전반적으로 개발자 != 코더랑 다르다는 걸 상기시켜준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 AI 산업이 ChatGPT를 시작으로 급속도록 달라지고 있는 현재 상황에서 단순히 코딩만 하는 개발자는 미래에 없어질 수 있겠다는 생각이 많이 들고 있었고, 어떤 부분을 발전시키면 좋을까란 생각을 하고 있던 와중에 이 책을 만나 다행이라 생각한다.&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 style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;한빛미디어 &amp;lt;나는 리뷰어다&amp;gt; 활동을 위해서 책을 제공받아 작성된 서평입니다.&quot;&lt;/b&gt;&lt;/p&gt;</description>
      <category>HisStory/나는리뷰어다2023</category>
      <category>나는리뷰어다</category>
      <category>육각형개발자</category>
      <category>한빛미디어</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/130</guid>
      <comments>https://kdhyo98.tistory.com/130#entry130comment</comments>
      <pubDate>Sun, 27 Aug 2023 20:54:05 +0900</pubDate>
    </item>
    <item>
      <title>[java] BigDecimal의 equals 와 compareTo with kotlin</title>
      <link>https://kdhyo98.tistory.com/129</link>
      <description>&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;BigDecimal 을 통해 연산자를 통해 값을 비교하다가 조심해야될 것을 발견했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;결과의 값이 1인지를 확인하려고 했는데, 내 생각과 다르게 false가 나왔다.&lt;/p&gt;
&lt;pre id=&quot;code_1687094985727&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
    val result = BigDecimal(&quot;1.00&quot;)
    println(result == BigDecimal.ONE) // 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;equals의  java doc 확인해보니 아래와 같은 설명이 적혀있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;equals Javadoc&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Compares this BigDecimal with the specified Object for equality. Unlike compareTo, this method considers two BigDecimal objects equal only if they are equal in value and scale (thus 2.0 is not equal to 2.00 when compared by this method). &lt;br /&gt;Params: x &amp;ndash; Object to which this BigDecimal is to be compared. &lt;br /&gt;Returns: true if and only if the specified Object is a BigDecimal whose value and scale are equal to this BigDecimal's. &lt;br /&gt;See Also: compareTo(BigDecimal), hashCode&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;BigDecimal의 equals는 2.0과 2.00을 다르게 판단한다고 적혀있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해서 내가 원하는 1.00, 1 비교는 equals로 하면 안된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분은 BigDecimal을 계산할 때 실수할 여지가 많은 부분으로 조심해서 비교해야될 부분으로 보인다.&lt;/p&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과 1.00, 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;b&gt;compareTo Javadoc&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Compares this BigDecimal with the specified BigDecimal. Two BigDecimal objects that are equal in value but have a different scale (like 2.0 and 2.00) are considered equal by this method. This method is provided in preference to individual methods for each of the six boolean comparison operators (&amp;lt;, ==, &amp;gt;, &amp;gt;=, !=, &amp;lt;=). The suggested idiom for performing these comparisons is: (x.compareTo(y) &amp;lt;op&amp;gt; 0), where &amp;lt;op&amp;gt; is one of the six comparison operators. &lt;br /&gt;Params: val &amp;ndash; BigDecimal to which this BigDecimal is to be compared. &lt;br /&gt;Returns: -1, 0, or 1 as this BigDecimal is numerically less than, equal to, or greater than val.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;compareTo는 소숫점이 다른 2.0과 2.00을 같은 값으로 인지한다.&lt;/p&gt;
&lt;pre id=&quot;code_1687095546492&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
    val result = BigDecimal(&quot;1.00&quot;)
    println(result.compareTo(BigDecimal.ONE)) // 0
}&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;compareTo를 타는 &amp;gt;, &amp;gt;=, &amp;lt;, &amp;lt;= 와 같은 비교 연산자의 경우 사용해도 되지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;==, !== 의 경우 equals를 타기 때문에 대부분의 경우에서는 compareTo()를 통해 0인지를 확인하자.&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;그렇다면 Java는 equals를 왜 2.0, 2.00을 다른 값으로 본 걸까?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stackoverflow에 바로 이해가 가는 예시가 있었다.&lt;/p&gt;
&lt;pre id=&quot;code_1687095885982&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun main() {
    val a = BigDecimal(&quot;2.0&quot;)
    val b = BigDecimal(&quot;2.00&quot;)
    val three = BigDecimal(3)
    
    println(a.divide(three, RoundingMode.HALF_UP)) // 0.7
    println(b.divide(three, RoundingMode.HALF_UP)) // 0.67 
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;등식의 일반적인 규칙은 두 개의 동일한 값을 서로 대입할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 하나의 값을 사용하여 계산을 수행하면 어떤 결과가 나오는 경우 동일한 계산에 같은 값을 대입하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 결과와 동일한 결과가 나와야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 String, Integer, BigDecimal 등과 같은 값인 객체에 적용된다.&lt;/p&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를 대체할 수 없으므로 a.equals(b)는 false여야 한다고 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &amp;zwj;♂️ 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;equals의 정책은 이해가 됐다. 두 값은 엄밀히 따지면 다른 값으로 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 단순 비교를 위해서는 2.0이든 2.00이든, 2.0000이든 동일한 값으로 보고 싶은 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해서 2.0, 2.00을 의식적으로 비교해야 하는 경우가 아니라면, compareTo를 사용해 비교하자.&lt;/p&gt;
&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;a href=&quot;https://stackoverflow.com/questions/14102083/why-is-bigdecimal-equals-specified-to-compare-both-value-and-scale-individually&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/14102083/why-is-bigdecimal-equals-specified-to-compare-both-value-and-scale-individually&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://bugs.openjdk.org/browse/JDK-8261862&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://bugs.openjdk.org/browse/JDK-8261862&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/6787142/bigdecimal-equals-versus-compareto&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/6787142/bigdecimal-equals-versus-compareto&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JVM/Java</category>
      <category>BigDecimal</category>
      <category>CompareTo</category>
      <category>equals</category>
      <category>java</category>
      <category>Kotlin</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/129</guid>
      <comments>https://kdhyo98.tistory.com/129#entry129comment</comments>
      <pubDate>Sun, 18 Jun 2023 23:01:05 +0900</pubDate>
    </item>
    <item>
      <title>[Kafka] kafka.common.InconsistentClusterIdException: The Cluster ID doesn't match stored clusterId Some in meta.properties. The broker is trying to join the wrong cluster. Configured zookeeper.connect may be wrong.</title>
      <link>https://kdhyo98.tistory.com/128</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;브로커 실행 에러&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1681042277030&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kafka.common.InconsistentClusterIdException: The Cluster ID 5O5gujuWTEKjB8VxoS0sRA doesn't match stored clusterId Some(y3v9cswgSTOtIUhYDgdPIg) in meta.properties. The broker is trying to join the wrong cluster. Configured zookeeper.connect may be wrong.
	at kafka.server.KafkaServer.startup(KafkaServer.scala:223)
	at kafka.server.KafkaServerStartable.startup(KafkaServerStartable.scala:44)
	at kafka.Kafka$.main(Kafka.scala:82)
	at kafka.Kafka.main(Kafka.scala)
[2023-04-09 21:06:07,170] INFO shutting down (kafka.server.KafkaServer)
[2023-04-09 21:06:07,171] INFO [ZooKeeperClient Kafka server] Closing. (kafka.zookeeper.ZooKeeperClient)
[2023-04-09 21:06:07,297] INFO Session: 0x10001acd7cc0000 closed (org.apache.zookeeper.ZooKeeper)
[2023-04-09 21:06:07,297] INFO EventThread shut down for session: 0x10001acd7cc0000 (org.apache.zookeeper.ClientCnxn)
[2023-04-09 21:06:07,298] INFO [ZooKeeperClient Kafka server] Closed. (kafka.zookeeper.ZooKeeperClient)
[2023-04-09 21:06:07,302] INFO shut down completed (kafka.server.KafkaServer)
[2023-04-09 21:06:07,302] ERROR Exiting Kafka. (kafka.server.KafkaServerStartable)
[2023-04-09 21:06:07,302] INFO shutting down (kafka.server.KafkaServer)&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;Kafka가 meta.properties에 실패한 클러스터 ID를 저장했기 때문.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;해결 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;config/server.properties log.dirs 위치 파악&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LpB3D/btr892A888U/thxbK4O4OnSoosqBzubZ0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LpB3D/btr892A888U/thxbK4O4OnSoosqBzubZ0k/img.png&quot; data-alt=&quot;server.properties&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LpB3D/btr892A888U/thxbK4O4OnSoosqBzubZ0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLpB3D%2Fbtr892A888U%2FthxbK4O4OnSoosqBzubZ0k%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;533&quot; height=&quot;91&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;server.properties&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;871&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzRr4p/btr8UWBEyXf/bYKuvAtroeCEZJDZvo0aDk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzRr4p/btr8UWBEyXf/bYKuvAtroeCEZJDZvo0aDk/img.png&quot; data-alt=&quot;data dir&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzRr4p/btr8UWBEyXf/bYKuvAtroeCEZJDZvo0aDk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzRr4p%2Fbtr8UWBEyXf%2FbYKuvAtroeCEZJDZvo0aDk%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;871&quot; height=&quot;292&quot; data-origin-width=&quot;871&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;data dir&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 위치에 있는 meta.properties 를 제거해주면 정상 실행된다.&lt;/p&gt;</description>
      <category>Network/Kafka</category>
      <category>apache</category>
      <category>error</category>
      <category>Kafka</category>
      <category>아파치</category>
      <category>에러</category>
      <category>카프카</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/128</guid>
      <comments>https://kdhyo98.tistory.com/128#entry128comment</comments>
      <pubDate>Sun, 9 Apr 2023 21:18:14 +0900</pubDate>
    </item>
    <item>
      <title>[JPA] 트랜잭션 override afterCommit, beforeCommit ...</title>
      <link>https://kdhyo98.tistory.com/127</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;커밋 이전/이후에 추가적인 작업을 진행하고 싶을 때가 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1680851951105&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Transactional
fun test() {
    TransactionSynchronizationManager.registerSynchronization(object : TransactionSynchronizationManager(), TransactionSynchronization {
        override fun afterCommit() {
            // ... 로직
        }
    })
    // ... db 작업 시작
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션 시작하는 메소드 맨 위에 위와 같이&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;i&gt;TransactionSynchronizationManager.registerSynchronization&lt;/i&gt;&lt;/b&gt;를 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TransactionSynchronization 에서 다양한 메소드가 있으니 본인이 필요한 메소드를 오버라이딩해서 원하는대로 맞게 쓰자.&lt;/p&gt;
&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: left;&quot;&gt;&lt;b&gt;TransactionSynchronizationAdapter&lt;/b&gt; 는 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;@Deprecated&lt;/span&gt;&lt;/b&gt; 됐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K15pO/btr8ImOA59U/fGAUbWRUs17wCukXxkMNg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K15pO/btr8ImOA59U/fGAUbWRUs17wCukXxkMNg0/img.png&quot; data-alt=&quot;Method Summary&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K15pO/btr8ImOA59U/fGAUbWRUs17wCukXxkMNg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK15pO%2Fbtr8ImOA59U%2FfGAUbWRUs17wCukXxkMNg0%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;833&quot; height=&quot;309&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;403&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Method Summary&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #080808;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/support/TransactionSynchronization.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/transaction/support/TransactionSynchronization.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>JVM/JPA</category>
      <category>JPA</category>
      <category>Transaction</category>
      <category>transactional</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/127</guid>
      <comments>https://kdhyo98.tistory.com/127#entry127comment</comments>
      <pubDate>Fri, 7 Apr 2023 16:24:55 +0900</pubDate>
    </item>
    <item>
      <title>[Notion] 가상현실(Virtual Reality)의 현재와 미래</title>
      <link>https://kdhyo98.tistory.com/126</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;149&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/PE34w/btr7s3n7tvg/FuP7KBK4GKkSay4QPxIXRK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/PE34w/btr7s3n7tvg/FuP7KBK4GKkSay4QPxIXRK/img.png&quot; data-alt=&quot;Notion AI&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/PE34w/btr7s3n7tvg/FuP7KBK4GKkSay4QPxIXRK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPE34w%2Fbtr7s3n7tvg%2FFuP7KBK4GKkSay4QPxIXRK%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;289&quot; height=&quot;129&quot; data-origin-width=&quot;334&quot; data-origin-height=&quot;149&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Notion AI&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노션 테이블을 만들 일이 있어서 '/'를 쳤다가 블로그 게시물 작성을 해주는 걸 발견했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주제를 적지도 않았는데 혼자 주제를 만들어서 글을 치길래.. 신기해서 블로그에 기록겸 작성한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;소개&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상현실(Virtual Reality)은 현재 기술 분야에서 가장 주목받는 분야 중 하나입니다. 이 기술은 사용자를 현실과 구분되는 가상 세계로 이동시켜 새로운 경험을 제공합니다. 이번 글에서는 가상현실 기술의 현재와 미래에 대해 살펴보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. 가상현실의 현재 상황&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 가상현실 기술은 게임 산업에서 많이 사용되고 있습니다. 헤드셋을 착용하고 다양한 게임을 즐길 수 있으며, 실제로 존재하지 않는 것처럼 보이는 가상 세계에서 놀 수 있습니다. 이 외에도 교육, 의료, 건축 등 다양한 분야에서도 적용되고 있습니다. 하지만 아직은 고가의 가격과 사용자 경험의 한계로 인해 대중화되기에는 어려움이 있습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. 가상현실의 미래 전망&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가상현실 기술은 새로운 혁신을 이룰 가능성이 큽니다. 현재 가격이 비싸지만, 기술의 발전과 함께 저렴해질 것으로 예상됩니다. 또한 가상현실 기술은 AR(증강현실)과 함께 발전할 것으로 예상되며, 이를 통해 실제 세계와 가상 세계가 융합되는 새로운 경험을 제공할 수 있을 것입니다. 또한, 기존의 분야뿐만 아니라 새로운 분야에서도 적용되어 더욱 발전할 것으로 전망됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. 가상현실의 장단점&lt;/h2&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;/p&gt;</description>
      <category>HisStory</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/126</guid>
      <comments>https://kdhyo98.tistory.com/126#entry126comment</comments>
      <pubDate>Sat, 1 Apr 2023 22:41:08 +0900</pubDate>
    </item>
    <item>
      <title>블로그가 조회수가 떡락했다.</title>
      <link>https://kdhyo98.tistory.com/125</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;최근 대부분 회사 관련된 학습을 위주로 하다보니 회사 문서 작성을 위주로 진행하게 되었고, 결과적으로 블로그 글을 거의 작성하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 부분도 큰 문제겠지만..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도메인을 등록한 이후로 급격하게 방문자 수가 줄었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;316&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QjcGb/btr3BwCfS7Z/gE54pI0s7CHZA7qKUebb1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QjcGb/btr3BwCfS7Z/gE54pI0s7CHZA7qKUebb1K/img.png&quot; data-alt=&quot;2023년 01월&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QjcGb/btr3BwCfS7Z/gE54pI0s7CHZA7qKUebb1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQjcGb%2Fbtr3BwCfS7Z%2FgE54pI0s7CHZA7qKUebb1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;296&quot; height=&quot;316&quot; data-origin-width=&quot;296&quot; data-origin-height=&quot;316&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2023년 01월&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HS45l/btr3HoRajH3/Wom7tj9cxcivP4yAkY1Fd0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HS45l/btr3HoRajH3/Wom7tj9cxcivP4yAkY1Fd0/img.png&quot; data-alt=&quot;2023년 02월&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HS45l/btr3HoRajH3/Wom7tj9cxcivP4yAkY1Fd0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHS45l%2Fbtr3HoRajH3%2FWom7tj9cxcivP4yAkY1Fd0%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;245&quot; height=&quot;273&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;2023년 02월&lt;/figcaption&gt;
&lt;/figure&gt;
&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;300 후반 ~ 400 정도였는데, 이제는 100명도 간신히 넘는 수준이 되어버렸다.&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>HisStory</category>
      <category>일상</category>
      <category>티스토리</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/125</guid>
      <comments>https://kdhyo98.tistory.com/125#entry125comment</comments>
      <pubDate>Mon, 13 Mar 2023 22:31:31 +0900</pubDate>
    </item>
    <item>
      <title>GitHub Packages Could not PUT URL Received status code 422 from server: Unprocessable Entity</title>
      <link>https://kdhyo98.tistory.com/124</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;91&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0p5UJ/btrZNu9n7ZD/ixdPmYu7TgExKf1AgM2zrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0p5UJ/btrZNu9n7ZD/ixdPmYu7TgExKf1AgM2zrk/img.png&quot; data-alt=&quot;Error&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0p5UJ/btrZNu9n7ZD/ixdPmYu7TgExKf1AgM2zrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0p5UJ%2FbtrZNu9n7ZD%2FixdPmYu7TgExKf1AgM2zrk%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;1658&quot; height=&quot;91&quot; data-origin-width=&quot;1658&quot; data-origin-height=&quot;91&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Error&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;artifactId 가 대문자가 포함되있을 경우&lt;/li&gt;
&lt;li&gt;다른 리포지토리에 동일한 group-artifactId로 이미 관리 되어있는 경우&lt;/li&gt;
&lt;li&gt;url이 https://maven.pkg.github.com/ 이 아닌 경우&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1676862720269&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Maven deploy fails with status 422 unprocessable entity &amp;middot; Discussion #23474 &amp;middot; community&quot; data-og-description=&quot;I have this repository: GitHub - mikenakis/Bathyscaphe: Deep immutability and thread-safety assessment for Java objects in which both my CI-Workflow and my Release-Workflow work fine. Now I am tryi...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/orgs/community/discussions/23474&quot; data-og-url=&quot;https://github.com/orgs/community/discussions/23474&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/6kSAj/hyRF9SkrWN/xV0bk691BGHAUaI96ePVZk/img.png?width=1200&amp;amp;height=600&amp;amp;face=984_129_1051_202&quot;&gt;&lt;a href=&quot;https://github.com/orgs/community/discussions/23474&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/orgs/community/discussions/23474&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/6kSAj/hyRF9SkrWN/xV0bk691BGHAUaI96ePVZk/img.png?width=1200&amp;amp;height=600&amp;amp;face=984_129_1051_202');&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;Maven deploy fails with status 422 unprocessable entity &amp;middot; Discussion #23474 &amp;middot; community&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;I have this repository: GitHub - mikenakis/Bathyscaphe: Deep immutability and thread-safety assessment for Java objects in which both my CI-Workflow and my Release-Workflow work fine. Now I am tryi...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Error</category>
      <category>github</category>
      <category>githubpackages</category>
      <category>maven</category>
      <category>packages</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/124</guid>
      <comments>https://kdhyo98.tistory.com/124#entry124comment</comments>
      <pubDate>Mon, 20 Feb 2023 12:14:40 +0900</pubDate>
    </item>
    <item>
      <title>NGINX 쿡북 (2판) 리뷰</title>
      <link>https://kdhyo98.tistory.com/123</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;514&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvw45G/btrYYqebYCY/fZRSrUfkevsXK2mc9rDKW0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvw45G/btrYYqebYCY/fZRSrUfkevsXK2mc9rDKW0/img.jpg&quot; data-alt=&quot;nginx 쿡북 2판&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvw45G/btrYYqebYCY/fZRSrUfkevsXK2mc9rDKW0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbvw45G%2FbtrYYqebYCY%2FfZRSrUfkevsXK2mc9rDKW0%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;400&quot; height=&quot;514&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;514&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nginx 쿡북 2판&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;서론&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;개인적으로 NGINX를 제대로 사용해 본 적이 없었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;기껏 해봐야 학생 시절에 ec2에서 node 서버를 띄울 때 설치해서 사용해 본 정도가 다였다.&lt;/span&gt;&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;&lt;span style=&quot;color: #333333;&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;한 번 살펴보고 싶은 생각이 있었는데 이번에 기회가 생겨서 읽게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;책 후기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 책은 나의 니즈에 딱 맞게 NGINX의 다양한 설정, 기능 등 거기에 튜닝까지 한 번 싹 설명해 준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;간단하게 OS 별 설치방법, 도커에서 이미지 다운로드 방법 등 설치방법부터&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;NIGINX에는 어떤 옵션들이 있고, 이 옵션들은 이러한 문제 상황에서 써야 한다고 알려준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;886&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmGK6u/btrYRQzeG8N/nBoCC5upC97zYf7tlKY5E1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmGK6u/btrYRQzeG8N/nBoCC5upC97zYf7tlKY5E1/img.jpg&quot; data-alt=&quot;7장 보안제어&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmGK6u/btrYRQzeG8N/nBoCC5upC97zYf7tlKY5E1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmGK6u%2FbtrYRQzeG8N%2FnBoCC5upC97zYf7tlKY5E1%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;550&quot; height=&quot;550&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;886&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;7장 보안제어&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 책의 장점 중 하나는 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;문제 - 해결 - 논의&lt;/b&gt;&lt;/span&gt; 형태로 책의 구성을 표현한 거라고 생각한다.&lt;/span&gt;&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;&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WW7qQ/btrYTgYfHe6/cvJKZXFLFucdIcB1KmJcrK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WW7qQ/btrYTgYfHe6/cvJKZXFLFucdIcB1KmJcrK/img.jpg&quot; data-alt=&quot;7장 보안 제어&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WW7qQ/btrYTgYfHe6/cvJKZXFLFucdIcB1KmJcrK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWW7qQ%2FbtrYTgYfHe6%2FcvJKZXFLFucdIcB1KmJcrK%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;550&quot; height=&quot;550&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;7장 보안 제어&lt;/figcaption&gt;
&lt;/figure&gt;
&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;&lt;span style=&quot;color: #333333;&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;논의 파트에서는 실무에서 어떤 문제들이 있었고, 이러한 문제를 해결하기 위해 이 설정을 쓴다는 걸 알려주기 때문에&lt;/span&gt;&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;886&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bv7kxi/btrYXi1KFAm/ejiujTocBmxmyxiBEXwXqK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bv7kxi/btrYXi1KFAm/ejiujTocBmxmyxiBEXwXqK/img.jpg&quot; data-alt=&quot;10장 클라우드 환경 배포&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bv7kxi/btrYXi1KFAm/ejiujTocBmxmyxiBEXwXqK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbv7kxi%2FbtrYXi1KFAm%2FejiujTocBmxmyxiBEXwXqK%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;550&quot; height=&quot;550&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;886&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;10장 클라우드 환경 배포&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;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Pvu0r/btrYY76KEHN/JwGTOmKtNeyf6T0ybpDJTk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Pvu0r/btrYY76KEHN/JwGTOmKtNeyf6T0ybpDJTk/img.jpg&quot; data-alt=&quot;11장 컨테이너와 마이크로서비스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Pvu0r/btrYY76KEHN/JwGTOmKtNeyf6T0ybpDJTk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPvu0r%2FbtrYY76KEHN%2FJwGTOmKtNeyf6T0ybpDJTk%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;550&quot; height=&quot;550&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&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;&lt;span style=&quot;color: #333333;&quot;&gt;또 aws랑 도커, 쿠버네티스 등 클라우드 환경과 컨테이너에서도 어떻게 사용할 수 있는지를 알려주기 때문에&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;간단하게 도커나 aws에서 따라 하면서 테스트를 진행해 볼 수도 있었다.&lt;/span&gt;&lt;span style=&quot;color: #333333;&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;나 또한 책을 읽으면서 '오 이건 한 번 따라 해 봐야겠는데?'라는 부분은 &lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;aws에서 NGINX를 설치해서 따라보고 했는데 &lt;/span&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;많은 사람들이&amp;nbsp;&lt;i&gt;&quot;개발에는 정답이 없다&quot;라는&lt;/i&gt; 말을 하지만, 개인적으로 나는 정답에 가까운 해결법은 있다고 생각한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;괜히 우리가 Best Practice를 찾는가? (물론, 무조건적으로 모든 상황에 정답이란 뜻은 아니다.)&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;이 책은 NGINX를 사용할 때 다양한 문제와 상황 속에서 어떤 해결책이 있는지 딱! 딱! 설명해 주기 때문에 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;NGINX를 사용해 본 적이 없는 나지만, 꽤 재미있게 읽었고, 오 이런 것들까지 해줘?? 하는 부분들이 상당히 많았다.&lt;/span&gt;&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;&lt;span style=&quot;color: #333333;&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;244쪽에 115가지 꿀팁을 정말 꾹꾹 담아 넣어 주었다. 그렇다고 내용이 간단하고 쓸모 없는 것들이 아닌&lt;/span&gt;&lt;span style=&quot;color: #333333;&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;정말 실무에서 필요한 순간이 있을 것 같은 것들로 채워져 있었다.&lt;/span&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;NGINX에 관심이 있거나 현재 실무에서 사용 중이라면 한 번쯤 읽어볼 만하다고 생각한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 책의 추천 독자&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;NGINX을 들어봤고, 한 번 훑어보고 싶은 개발자&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;NGINX를 실무에서 사용해야 하는, 사용하고 있는 개발자&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이 책의 부적합한 독자&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;개발을 시작한 지 얼마 되지 않은 취준생&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;or 개발자&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;NGINX을 한 번도 들어보지 못한 취준생 or 개발자&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1676107470776&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;NGINX 쿡북(2판)&quot; data-og-description=&quot;웹 서버 소프트웨어 엔진엑스의 다양한 기능을 익힌다. 문제-해결-논의 형식의 간결한 레시피로 구성되어 있어 필요한 기능을 찾아보기 쉽다.&quot; data-og-host=&quot;hanbit.co.kr&quot; data-og-source-url=&quot;https://hanbit.co.kr/media/books/book_view.html?p_code=B9583925549&quot; data-og-url=&quot;https://hanbit.co.kr/media/books/book_view.html?p_code=B9583925549&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/slaKB/hyRAo8sB8Q/ys6f6XN74xicH0rG19NSh0/img.jpg?width=202&amp;amp;height=260&amp;amp;face=0_0_202_260,https://scrap.kakaocdn.net/dn/oK94q/hyRAoABGdS/vWWfSAUPNJUfaekWGLeSC1/img.jpg?width=400&amp;amp;height=514&amp;amp;face=0_0_400_514,https://scrap.kakaocdn.net/dn/cjklvs/hyRzCHfhUM/F780PKlY0kfSQ4k1Ue7KR1/img.jpg?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200&quot;&gt;&lt;a href=&quot;https://hanbit.co.kr/media/books/book_view.html?p_code=B9583925549&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://hanbit.co.kr/media/books/book_view.html?p_code=B9583925549&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/slaKB/hyRAo8sB8Q/ys6f6XN74xicH0rG19NSh0/img.jpg?width=202&amp;amp;height=260&amp;amp;face=0_0_202_260,https://scrap.kakaocdn.net/dn/oK94q/hyRAoABGdS/vWWfSAUPNJUfaekWGLeSC1/img.jpg?width=400&amp;amp;height=514&amp;amp;face=0_0_400_514,https://scrap.kakaocdn.net/dn/cjklvs/hyRzCHfhUM/F780PKlY0kfSQ4k1Ue7KR1/img.jpg?width=200&amp;amp;height=200&amp;amp;face=0_0_200_200');&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;NGINX 쿡북(2판)&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;hanbit.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;&quot;한빛미디어 &amp;lt;나는 리뷰어다&amp;gt; 활동을 위해서 책을 제공받아 작성된 서평입니다.&quot;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>HisStory/나는리뷰어다2023</category>
      <category>nginx</category>
      <category>나는리뷰어다</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/123</guid>
      <comments>https://kdhyo98.tistory.com/123#entry123comment</comments>
      <pubDate>Sat, 11 Feb 2023 21:24:14 +0900</pubDate>
    </item>
    <item>
      <title>[나는리뷰어다] 2023 리뷰어 선정!</title>
      <link>https://kdhyo98.tistory.com/122</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;553&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/CaYAz/btrX4levcW5/tokMSJpktAK7IcRNPffNZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/CaYAz/btrX4levcW5/tokMSJpktAK7IcRNPffNZK/img.png&quot; data-alt=&quot;나는리뷰어다 2023&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/CaYAz/btrX4levcW5/tokMSJpktAK7IcRNPffNZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCaYAz%2FbtrX4levcW5%2FtokMSJpktAK7IcRNPffNZK%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;845&quot; height=&quot;553&quot; data-origin-width=&quot;845&quot; data-origin-height=&quot;553&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;나는리뷰어다 2023&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매달 책 목록 중 3권을 선택해서 랜덤으로 1권을 보내주시면, 약 2주 동안 책을 읽고 후기를 남겨야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생각보다 기간이 길지 않아 책을 빠르게 빠르게 읽어야 되는 부담감이 있긴 하지만 좋은 기회이라 생각하고 열심히 해볼 생각이다.&lt;/p&gt;
&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;64&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c0lZxO/btrX32sJMh9/2vMcvUIIyARKFGkhHSHha0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c0lZxO/btrX32sJMh9/2vMcvUIIyARKFGkhHSHha0/img.png&quot; data-alt=&quot;우수 리뷰어&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c0lZxO/btrX32sJMh9/2vMcvUIIyARKFGkhHSHha0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc0lZxO%2FbtrX32sJMh9%2F2vMcvUIIyARKFGkhHSHha0%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;439&quot; height=&quot;64&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;64&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;</description>
      <category>HisStory/나는리뷰어다2023</category>
      <category>나는리뷰어2023</category>
      <category>한빛미디어</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/122</guid>
      <comments>https://kdhyo98.tistory.com/122#entry122comment</comments>
      <pubDate>Sat, 4 Feb 2023 17:54:24 +0900</pubDate>
    </item>
    <item>
      <title>[Gradle] 버전 별 Java, Kotlin 호환 버전 확인</title>
      <link>https://kdhyo98.tistory.com/121</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;빌드툴인 gradle 또한 java, kotlin이 호환되는 버전이 버전 별로 달랐다..&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;518&quot; data-origin-height=&quot;619&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xHMGi/btrXSv1OZ3E/aVLy4WVv67PQHvJq4k7urk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xHMGi/btrXSv1OZ3E/aVLy4WVv67PQHvJq4k7urk/img.png&quot; data-alt=&quot;Java&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xHMGi/btrXSv1OZ3E/aVLy4WVv67PQHvJq4k7urk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxHMGi%2FbtrXSv1OZ3E%2FaVLy4WVv67PQHvJq4k7urk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;518&quot; height=&quot;619&quot; data-origin-width=&quot;518&quot; data-origin-height=&quot;619&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Java&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;830&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Kxpio/btrXMSEKeZe/h4A1KEZxp7qtOfD47CPIyk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Kxpio/btrXMSEKeZe/h4A1KEZxp7qtOfD47CPIyk/img.png&quot; data-alt=&quot;Kotlin&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Kxpio/btrXMSEKeZe/h4A1KEZxp7qtOfD47CPIyk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKxpio%2FbtrXMSEKeZe%2Fh4A1KEZxp7qtOfD47CPIyk%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;598&quot; height=&quot;830&quot; data-origin-width=&quot;598&quot; data-origin-height=&quot;830&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Kotlin&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.gradle.org/7.6/userguide/compatibility.html&quot;&gt;https://docs.gradle.org/7.6/userguide/compatibility.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675261297600&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Compatibility Matrix&quot; data-og-description=&quot;Gradle is tested with Android Gradle Plugin 4.1, 4.2, 7.0, 7.1, 7.2, 7.3 and 7.4. Alpha and beta versions may or may not work.&quot; data-og-host=&quot;docs.gradle.org&quot; data-og-source-url=&quot;https://docs.gradle.org/7.6/userguide/compatibility.html&quot; data-og-url=&quot;https://docs.gradle.org/7.6/userguide/compatibility.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.gradle.org/7.6/userguide/compatibility.html&quot; data-source-url=&quot;https://docs.gradle.org/7.6/userguide/compatibility.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('&amp;quot;&amp;quot;');&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;Compatibility Matrix&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Gradle is tested with Android Gradle Plugin 4.1, 4.2, 7.0, 7.1, 7.2, 7.3 and 7.4. Alpha and beta versions may or may not work.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.gradle.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gradle.org/releases/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://gradle.org/releases/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675261322215&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Gradle | Releases&quot; data-og-description=&quot;Find binaries and reference documentation for current and past versions of Gradle.&quot; data-og-host=&quot;gradle.org&quot; data-og-source-url=&quot;https://gradle.org/releases/&quot; data-og-url=&quot;https://gradle.org/releases/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/m6umG/hyRt0T7izG/llatkNQVsT7q0eoExE3UV0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/cqoNIW/hyRslS770c/xI8lljoSNCBbUPhCr9dMR0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400&quot;&gt;&lt;a href=&quot;https://gradle.org/releases/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://gradle.org/releases/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/m6umG/hyRt0T7izG/llatkNQVsT7q0eoExE3UV0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400,https://scrap.kakaocdn.net/dn/cqoNIW/hyRslS770c/xI8lljoSNCBbUPhCr9dMR0/img.png?width=400&amp;amp;height=400&amp;amp;face=0_0_400_400');&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;Gradle | Releases&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Find binaries and reference documentation for current and past versions of Gradle.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;gradle.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;덤으로 6.8버전을 쓴다고 가정했을 때 마이너버전이 몇까지 나왔는지 확인하려면 위 링크에서 확인이 가능합니다.&lt;/p&gt;</description>
      <category>JVM/Java</category>
      <category>gradle</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/121</guid>
      <comments>https://kdhyo98.tistory.com/121#entry121comment</comments>
      <pubDate>Wed, 1 Feb 2023 23:23:04 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] h2 설정</title>
      <link>https://kdhyo98.tistory.com/120</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;OS&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;M1 MAX&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;macOS Ventura 13.2&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;PROJECT&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;java - 11&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kotlin - 1.6.21&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spring - 2.7.8&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;build.gradle.kts&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1674973824378&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
	...
	runtimeOnly(&quot;com.h2database:h2&quot;)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;application.yml&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1674973842374&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
  h2:
    console:
      enabled: true
      path: /h2-console
    datasource:
      url: jdbc:h2:mem:test
      username: sa
      password:
      driverClassName: org.h2.Driver
      platform: h2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;접근 url&lt;/b&gt; - http://localhost:8080/h2-console&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;에러사항&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1121&quot; data-origin-height=&quot;683&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bBlqXV/btrXtToPKPI/xEKyKuSaeKeS0sdH2BX7T1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bBlqXV/btrXtToPKPI/xEKyKuSaeKeS0sdH2BX7T1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bBlqXV/btrXtToPKPI/xEKyKuSaeKeS0sdH2BX7T1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbBlqXV%2FbtrXtToPKPI%2FxEKyKuSaeKeS0sdH2BX7T1%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;1121&quot; height=&quot;683&quot; data-origin-width=&quot;1121&quot; data-origin-height=&quot;683&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;원인&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스가 존재하지 않아서 발생되는 문제입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;H2:1.4.198 버전부터는 보안상의 이유로 데이터베이스 자동생성을 막아두었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널을 통해 h2를 설치하여 수동으로 데이터베이스를 생성해줍니다.&lt;/p&gt;
&lt;pre id=&quot;code_1674978370844&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# h2 설치
$ brew install h2

# h2 web console running - 해당 주소로 접근
$ h2 -web
Web Console server running at http://localhost:8082?key=cb6e18688aedfd770688bcb1278337893504c2834d06e6023e6d3c25346cb1a8 (only local connections)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JVM/Spring</category>
      <category>H2</category>
      <category>Spring</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/120</guid>
      <comments>https://kdhyo98.tistory.com/120#entry120comment</comments>
      <pubDate>Sun, 29 Jan 2023 16:47:29 +0900</pubDate>
    </item>
    <item>
      <title>2022년 회고 副題 - 가장 오래 기억 남을 한 해 Part 1</title>
      <link>https://kdhyo98.tistory.com/119</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  서론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;2268&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MZyYn/btrWkvWUDvg/k9TuBi9PWNa7Q72pu2UKUk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MZyYn/btrWkvWUDvg/k9TuBi9PWNa7Q72pu2UKUk/img.jpg&quot; data-alt=&quot;스위스 쌍무지개&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MZyYn/btrWkvWUDvg/k9TuBi9PWNa7Q72pu2UKUk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMZyYn%2FbtrWkvWUDvg%2Fk9TuBi9PWNa7Q72pu2UKUk%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;686&quot; height=&quot;386&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;2268&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;
&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;- 책 집필 찍먹&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- F-Lab 6개월&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 떨리는 면접 경험&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 나의 두 번째 회사&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  첫 회사 퇴사&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2020.10 입사하여 2022.03을 마지막으로 1년 6개월간의 첫 회사 여정을 마무리하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 첫 회사는 SI, 솔루션 회사였다.&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=k1LFrntx6UM&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/7abdg/hyRhMbEp10/uvBIKghRgMpc2VfMHwI7NK/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=476_48_852_672&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/k1LFrntx6UM&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;많은 사람들이 &quot;SI는 갈 곳이 못 된다.&quot; &quot;너무 힘들고, 발전도 없고, 3D업종이다.&quot;라고 많이 이야기한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 다닌 SI회사는 그래도 좋코딩에 나오는 극한의 SI는 다행히 아니었다.&lt;/p&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년 나를 돌이켜보면 회사 취업한 게 기적이다.&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;졸업 프로젝트를 위해 NodeJS를 잠깐 찍먹 해본 게 전부이고, 제대로 학습하는 방법도 모르고, 뭘 학습해야 하는지도 모르고&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;첫 회사의 기술스택인 Java는 수업 때 만들어본 계산기가 다였고, Spring은 입사 후 처음 만져봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리도 CRUD 사용방법 정도만 아는 수준이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 아무것도 없는 나를 키워서 쓰겠다는 마음(?)으로 뽑아주신 첫 회사에 감사함이 크다.  &amp;zwj;♂️&lt;/p&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;그래도 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;또 배운 게 있으면 나와 내 동기인 친구를 회의실로 불러 알려주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SI 특성상 빨리 만들기 급급한 상황 속에서도 우리가 짠 코드를 직접 리펙토링 하는 걸 보여주시면서 하나하나 리뷰해주시기도 하였다.&lt;/p&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년 10월에 입사해서 2021년까지.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;퇴사 결심&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼에도 2022년 퇴사를 결심하게 된 이유는 다양하다.&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;b&gt;SI 특성상 프로젝트에 애정을 가지기 매우 힘들었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트가 끝나면 해당 프로젝트는 버그가 발생했을 때 수정하는 정도였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, 프로젝트 기간도 매우 타이트하기 때문에 급급하게 만들어 끝내고 새로운 프로젝트를 시작하기 일쑤였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 핑계라면 핑계지만, `&lt;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;/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;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;물류창고 IOT 특성상 현장에서 테스트해야 하는 건 어쩔 수 없지만, 그렇지만, 힘든 것도 어쩔 수 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오랜만에 만나는 친구들은 다들 다크서클이 그득하게 내려왔다, 얼굴빚이 어두워졌다고 이야기했다. 꽤 힘들었다. &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;ㄹㅇ로 진짜로&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;좀 더 깊이 공부해 보고, 공부하는 법을 배우고 싶었다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 말했듯 나는 java와 spring을 회사에서 배워 회사 업무에 바로바로 적용하였다. cs 또한 부족하기는 마찬가지였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다 보니 깊이 있게 알지 못하는 부분이 대부분이었다. 단순히 사용방법 정도 알고 많이 넘어갔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, 회사를 다니면서도 배울 수 있기는 하지만 한계가 보이기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나와 비슷한 연차로 활동하는 다른 개발자들을 보면서 점점 부족함을 많이 느꼈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다고 뭐가 부족하고, 뭐가 급한지를 제대로 알지 못했다. 다 모르는 것 같았다. 막막했다. 어떤 걸 공부해야 발전할 수 있을지.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이대로 연차만 쌓이면 비슷한 연차의 개발자들과의 경쟁력이 매우 부족하겠다는 생각이 커졌고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 번은 제대로 학습하고 다음 연차를 보내고 싶다는 생각을 하게 되었다.&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;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;그렇지만, 팀장님 퇴사 후에는 정말 말로만 듣던 다른 SI처럼 프로젝트만 진행할 것 같다는 느낌을 강하게 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퇴사 전 몇 개월 간은 프로젝트가 한가했기에 여러 시도를 해보려 했지만, 내 노력으로 문화를 바꾸기에는 어려움을 느끼게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, 퇴사하지 않고 이직을 준비하는 것도 방법이었겠지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당시 나에게 이직은 하늘의 별을 따는 것보다 말이 안 될 정도로 내가 부족하다고 느낄 정도로 자존감이 매우 낮았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이직해 봤자 지금과 별반 다르지 않을 것 같았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 나를 점검하고 더 다양한 환경으로 나아갈 시기라고 생각이 들어 2022년 3월을 마지막으로 퇴사하게 되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  책 집필 찍먹&lt;/b&gt;&lt;/h3&gt;
&lt;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;2022년 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;예전부터 책을 내보고 싶다는 생각을 종종 했던 터라 집필 제안을 보았을 땐 무작정 좋았었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 아직 1년 반 밖에 되지 않은 내가, 경력을 떠나서 부족함이 많이 느껴지는 내가 책 집필을 잘할 수 있을지 의문이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주제 또한 내가 함부로 하기엔 매우 어렵고, 깊은 주제였기에 이러한 나의 마음을 담아 아쉽지만 거절을 표하였다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;두 번째 집필 제안&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3개월 뒤인 6월 경 블로그의 다른 글을 보시고 책 집필 제안을 한 번 더 주셨다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2601&quot; data-origin-height=&quot;587&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfm69X/btrWd04Rabv/QigfxjnnvZAZk2u5rvFdHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfm69X/btrWd04Rabv/QigfxjnnvZAZk2u5rvFdHK/img.png&quot; data-alt=&quot;두 번째 제안&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfm69X/btrWd04Rabv/QigfxjnnvZAZk2u5rvFdHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbfm69X%2FbtrWd04Rabv%2FQigfxjnnvZAZk2u5rvFdHK%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;2601&quot; height=&quot;587&quot; data-origin-width=&quot;2601&quot; data-origin-height=&quot;587&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;퇴사 상태로 시간도 많다고 느꼈기에 한 번 도전해 봐도 좋을 것 같다는 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 덥석 물기에는 내가 집필하는 책을 사람들이 살 만큼 내가 전문적일까란 질문을 스스로 계속하게 되었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 사람들에게 자문을 많이 구했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 분들께서 신입이더라도 책 집필하면서 배우는 것이 많을 거고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자 커리어 적으로도, 나에게도 좋은 기회일 거란 이야기를 많이 해주셔서&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;새롭게 배워서 배운 내용을 블로그 글 작성하듯 집필해야 하는 느낌이 매우 강하게 느껴졌다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 내가 집필할 수 있는 주제가 맞을까? 퇴사 후 취준생인 내가 이러한 주제로 책을 쓴다면.. 사람들이 책을 살까..?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퇴사 후 시간이 어느 정도 지난 취준생 신분이었기에 자존감도 좀 낮아진 상태였기에 두려움이 꽤 컸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;덥석 진행하기보다는 편집장님과 미팅을 통해 원하시는 책의 방향을 들은 후에 더 고민을 해보자는 생각으로 미팅을 제안했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;또한, 바로 책 집필로 들어가는 게 아니라 목차를 뽑고, 샘플원고를 작성해 본 후에 편집장님과 나 둘 다 앞으로 더 진행할 수 있을지 생각해 본 후에 계약하는 것이기 때문에 벌써 포기하는 것보다는 진행해 보자는 마음을 먹게 되었다.&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;b&gt;목차 고민&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호기롭게 책 목차를 뽑으려고 했지만, 막상 원하는 목차가 나오지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 큰 문제는 책의 큰 주제를 선정하지 못하고 내가 아는 짤막한 지식들을 욱여넣으려고 했던 게 문제였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연하게 목차를 얼마 뽑지 못한 채 전달하게 되었고, 결국 새롭게 구성하기로 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 고민하는 동안은 작은 나무(목차)를 고민하는 게 아닌 큰 숲(책의 주제)을 많이 고민했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로는 꽤 만족하는 주제가 나왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당시 사이드 프로젝트를 진행하고 있던 터라 내가 프로젝트를 만들면서 고민했던 내용,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 할 때 고민하면 좋을 내용을 주제로 정하였고, 이전보다 비교적 쉽게 목차를 꾸릴 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다행히 편집장님께서도 새롭게 만든 목차를 좋아해 주셨고 샘플원고 작성에 들어갔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&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;책 집필도 중요한 일정이고 편집장님과의 약속이었지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코테준비, 면접 준비, 이력서 수정, 프로젝트 진행 등 취업에 대한 일정에 큰 압박감을 가지고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나를 좋게 봐주시고 제안까지 해주신 편집장님께 죄송하게도 원고 시작도 전부터 계속 일정을 맞추지 못하였고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일정도 늦은 주제에 많은 시간을 투자하지 못한 채 샘플원고를 보내게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취업에 대한 스스로의 압박을 받고 있던 터라 책 집필에 집중하지 못했던 게 가장 큰 원인이었던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;열심히 책 집필에 열정을 쏟아야 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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제안받은 순간부터 기뻤고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책 집필 프로세스를 배울 수 있었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책이 어떻게 나오는지 작가분들이 얼마나 대단한 분들인지 느낄 수 있었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 작성해 본 샘플원고에 감사하게도 하나하나 피드백을 주신 편집장님 덕분에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책은 어떠한 문장으로 이루어져야 하는지도 많이 배울 수 있는 계기였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은.. 회사 적응하고 새롭게 배우는 것이 너무 많고, 내가 부족한 걸 매우 잘 알기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 이러한 계기가 다시 한번 주어진다면 그때는 자신 있는 주제로 최선을 다해 다시 도전해보고 싶다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &amp;zwj;  6개월의 멘토링&lt;/b&gt;&lt;/h3&gt;
&lt;figure id=&quot;og_1673769405441&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;[F-Lab] 2022-02 ~ 2022-09 6개월.2주(?) 멘토링 후기&quot; data-og-description=&quot;  결론 F-Lab을 통해서 좋은 멘토와 멘티를 만날 수 있었고, 의미 있는 시간을 통해 4월~9월 약 6개월의 공백 후 SI 회사에서 내가 원하는 서비스회사로 이직할 수 있게 되었다.   서론 지원 동기&quot; data-og-host=&quot;kdhyo98.tistory.com&quot; data-og-source-url=&quot;https://kdhyo98.tistory.com/109&quot; data-og-url=&quot;https://kdhyo98.tistory.com/109&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/uNzf8/hyRhL4QGe0/7d84lL6ljk1LZhkrgqzk71/img.jpg?width=800&amp;amp;height=445&amp;amp;face=0_0_800_445,https://scrap.kakaocdn.net/dn/byf44R/hyRhJlFmkn/9uKLu6yodgzX1sNj4g4SAk/img.jpg?width=800&amp;amp;height=445&amp;amp;face=0_0_800_445,https://scrap.kakaocdn.net/dn/kaJQv/hyRhQ57Uv1/pelbjhzqp78pzGwVKDLU31/img.png?width=581&amp;amp;height=458&amp;amp;face=0_0_581_458&quot;&gt;&lt;a href=&quot;https://kdhyo98.tistory.com/109&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kdhyo98.tistory.com/109&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/uNzf8/hyRhL4QGe0/7d84lL6ljk1LZhkrgqzk71/img.jpg?width=800&amp;amp;height=445&amp;amp;face=0_0_800_445,https://scrap.kakaocdn.net/dn/byf44R/hyRhJlFmkn/9uKLu6yodgzX1sNj4g4SAk/img.jpg?width=800&amp;amp;height=445&amp;amp;face=0_0_800_445,https://scrap.kakaocdn.net/dn/kaJQv/hyRhQ57Uv1/pelbjhzqp78pzGwVKDLU31/img.png?width=581&amp;amp;height=458&amp;amp;face=0_0_581_458');&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;[F-Lab] 2022-02 ~ 2022-09 6개월.2주(?) 멘토링 후기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;  결론 F-Lab을 통해서 좋은 멘토와 멘티를 만날 수 있었고, 의미 있는 시간을 통해 4월~9월 약 6개월의 공백 후 SI 회사에서 내가 원하는 서비스회사로 이직할 수 있게 되었다.   서론 지원 동기&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kdhyo98.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토링관련해서 후기를 작성했기에 이번 글에서는 F-Lab에 대해서 상세히 적지는 않을 것이다. (궁금하면 봐주세요  )&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;12개월 중 6개월은 F-Lab을 하면서 보냈기에 어찌 보면 2022년은 F-Lab이 나에게 꽤 큰 이벤트기도 하다. (돈도 꽤 썼따..)&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;span style=&quot;color: #ee2323;&quot;&gt;가장 아쉬운 점은 최선을 다했냐고 물어보면 그건 아니었다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 돌아가면 이렇게 하고 싶다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;오프라인 모각코에 참여하여 다른 멘티 분들과 더 친해지기&lt;/li&gt;
&lt;li&gt;프로젝트를 제대로!
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;MVP 계획 잘 세우기&lt;/li&gt;
&lt;li&gt;스프린트 단위로 계획 세우기&lt;/li&gt;
&lt;li&gt;제일 많은 시간 투자하기&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;멘토님께 더욱 적극적으로 질문하고, 귀찮게(?) 하기&lt;/li&gt;
&lt;li&gt;유튜브, 인스타 삭제&lt;/li&gt;
&lt;li&gt;일정과 목표를 계획적, 세부적으로 세워서 실천하기&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 F-Lab 혹은 다른 부트캠프를 시작하시는 분께서 이 글을 본다면 꼭 이야기해 주고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;몇 개월 간의 큰 틀 안에서 시간을 보낼 때 최선을 다해 후회 없는 시간을 보내면 좋겠다.&lt;/b&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  떨리는 면접 경험&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내 처음 목표는 &lt;b&gt;딱 6개 회사만 면접보기&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;850&quot; data-origin-height=&quot;450&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lIoTQ/btrWeXGG7s6/PaBf9nCrPI4vKkfolbEkz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lIoTQ/btrWeXGG7s6/PaBf9nCrPI4vKkfolbEkz1/img.png&quot; data-alt=&quot;경기도 청년 면접수당&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lIoTQ/btrWeXGG7s6/PaBf9nCrPI4vKkfolbEkz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlIoTQ%2FbtrWeXGG7s6%2FPaBf9nCrPI4vKkfolbEkz1%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;637&quot; height=&quot;337&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;450&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;
&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6개의 회사 면접 != 6회 면접수당&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6번의 면접 == 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;다행히도 나를 좋게 봐주시고, 나도 원하는 기업에 붙게 되어 5곳 면접만에 취뽀를 성공할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 6회를 채워 면접수당을 다 받았다!!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;면접 후기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이전 회사도 학교 추천으로 면접을 보았기 때문에 떨리긴 떨렸지만.. 큰 부담감이 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 사회에 나와 스스로 원하는 회사를 처음&lt;span&gt;&amp;nbsp;&lt;/span&gt;지원해 보고&lt;span&gt;&amp;nbsp;&lt;/span&gt;면접을 보게 되었는데.. 매우 매우 매우 떨렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;떨렸던 내 마음과는 다르게 첫 회사부터 면접 경험이 매우 좋았기에 불합격이 아쉽기는 했지만, 덕분에 뒤 면접들을 잘 볼 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;(여기서 한 번 더 F-Lab 멘토님께 정말 감사드리면서 약간의 홍보를 하자면 모의면접 본 경험이 매우 좋았다.)&lt;/s&gt;&lt;/p&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회사이고, 개발자 대우가 좋은 회사, 개발자 채용에 적극적인 회사들은 면접 경험이 다 좋은 편이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접 보기 전까지만 하더라도 잡플래닛 후기를 통해 면접경험이 안 좋다는 후기가 회사마다 다들 있던데..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 면접관 분들 운이 좋았던 것 같기도 하지만, 면접 보기 전부터 괜히 안 좋은 후기로 쫄 필요는 없을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접 후기를 기업 별로 세세하게 적기에는.. 늦었다. 당시 내 감정이 많이 기억나질 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이래서 미리미리 후기를 적어야하는데..  &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;면접 보기 전 과거의 나에게 하고 싶은 말&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;실제 코딩테스트가 그리 어려운 회사는 별로 없다. 코테에 스트레스받지 말자.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;코드를 가독성 좋게 작성하고, 코테가 끝난 후 복기하자.&lt;/li&gt;
&lt;li&gt;내가 짠 코테 코드로 질문 시간이 있는 면접들이 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CS 질문타임이 별도로 구성된 회사들도 많지만, 아닌 회사들도 많다. 보통 질문할 게 없을 때 많이 빠진다.&lt;/li&gt;
&lt;li&gt;CS 학습도 물론 중요하지만, 내 프로젝트를 잘 이해하고 무슨 생각으로 무슨 기술을 선택했는지를 더 고민하자.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CS 질문을 답 못하는 것보다는 내가 한 프로젝트에 대해 답 못하는 게 더 안 좋게 보이지 않을까?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;내가 적은 이력서 한 글자 한 글자 다 대답할 수 있게 준비하자.&lt;/li&gt;
&lt;li&gt;면접을 나도 회사를 파악하고, 나랑 맞는 곳인지 파악하는 커피챗이라고 생각하자. (쫄지말자)&lt;/li&gt;
&lt;li&gt;면접 후 복기는 필수! 꼭 바로 해서 미루지 말자.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  나의 두 번째 회사&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;면접&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이력서를 넣을 때는 잡플래닛이나 블라인드에서 안 좋은 후기가 보여서 약간 걱정을 했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;(이제 와서 생각해 보면 평점 5.0 회사는 없는데 괜한 걱정이었다.. 애플 구글도 안 좋은 후기는 존재하는 걸..)&lt;/s&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;지금의 CTO님과의 면접 경험이 정말 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접 본 회사 중 가장 편안한 분위기로 면접을 이끌어 나아가 주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;압박면접이라고는 단 1g도 찾아볼 수 없었고, 반대로 내 긴장을 풀어주기 위해 노력해 주시는 게 보였다.&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;우리 회사는 하루 8시간 근무시간이 고정되어 있지 않고, 코어타임이 매우 짧은 편이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 시간에 대해 면접을 통해 질문을 드렸고, 답변 주신 게 인상적이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 단순히 8시간 앉아있다고 일이 잘되는 것도 아니고, 본인이 잘되는 시간이 있을 텐데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간을 고정하지 않고 자율성에 맡긴다고 이야기해 주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자의 자율성을 매우 존중해 주는 문화라는 걸 느끼게 되었고, 면접관님들 마인드나 분위기, 아우라가 매우 마음에 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라이브 코딩테스트를 진행할 때는 피드백 요청에도 흔쾌히 피드백 주시면서 어떤 걸 수정하면 좋을지 친절하게 답변해 주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;면접 이후 더욱 합류하고 싶다는 생각이 들었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로 1차 면접 합격과 2차 면접 합격 후 두 번째 회사의 합류할 수 있게 되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;회사를 다니면서&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 회사 다닌 지 3개월 정도 지난 시점이고, 내가 기대했던 기대치가 80%였다면 지금은 110% 정도로 매우 만족한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 기대했던 회사 분위기는 더욱 좋았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수평적인 문화라는 게 정말 말만 그런 게 아니란 걸 느꼈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회의 때 다들 본인 주장을 편하게 이야기하고, 장난도 치면서 화기애애한 분위기며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입사 2~3일 만에 10이 넘는 강의 결제가 슬랙 말 한마디에 되는 걸 보고 진짜 말만 강의지원을 하는 게 아니구나를 느끼고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;피플팀 또한 직원들이 어떤 생각을 가지고 있는지, 불편한 건 없는지 귀 기울여 듣기 위해 노력하시는 게 보이고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 잘 하고 있는지 고민이 들고, 오늘 뭐했지라는 생각으로 마음이 무거울 때면 따뜻한 한마디로 마음의 짐을 조금 내려놓게 해 주시고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 처음 해보는 코드리뷰는 정말 세세하게 하나하나 봐주셔서 매우 감동적이었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주 4 재택은 정말.. 회사원인 나의 삶의 질을 확 늘려주고 자유도를 높여주며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;눈치 없는 반차, 휴가 자가결재 또한 말만 그런 게 아니라 급한 일이 있다면 당일에 올려도 눈치 1도 주지 않는 정말 자유로우며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근무시간은 개발자가 원하는 시간에 편하게 일할 수 있도록 자율성이 보장된 최적의 근무시간이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입사 2개월 차에 CTO님과의 면담에서 보안했으면 좋겠는 것, 불편한 것 등을 물어봐주셨는데,&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;회사의 좋은 점과는 별개로 재택과 많은 자율성을 보장해 주는 게 100% 장점만 있는 건 아니었다.&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;또 궁금한 게 생겼을 때 극 I인 나는.. 채팅으로 질문하는 게 매우 매우 어려웠다. (지금도 조금..?)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채팅으로 내 말투가 조금이라도, 혹시라도 상대방 기분이 나쁠만한가, 내 의도가 잘 전달되는가에 대해 고민하느라&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;질문 한 줄을 입력하는데 10분이 넘게 걸리기도 한 적이 있다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;입사 일주일 후 주 4 재택을 했기 때문에 팀원분들 혹은 다른 팀 분들과 금방 친해지기 어려운 부분도 분명 존재했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 타 팀에 질문을 드리거나 요청을 할 때는 어떻게 해야 할지 계속 고민하고는 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 주 4 재택 말고 주 3 혹은 풀출근으로 변경되면 어떨 거냐고 물어본다면 &lt;b&gt;No.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연히 재택 장점이 더 많은 건 어쩔 수 없다..^^&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금은 나름 회사 분들과 나름 친해졌다고(?) 생각하고, 너무 만족하고 다니고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 내가 더 열심히 해야 하는 부분은 분명 존재하고 느끼고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에 좀 더 빨리 적응할 수 있도록, 다른 분들에게 도움이 될 수 있도록 더욱 열심히 공부하고 일해야겠다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  정리하며..&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올해 퇴사를 하고, 6개월의 멘토링을 통해 만족하는 두 번째 회사에 입사할 수 있는 내 인생의 오래 기억남을 한 해를 보냈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 &lt;b&gt;정말 최선을 다해 한 해를 보냈냐고 하면 &lt;span style=&quot;color: #ee2323;&quot;&gt;아니다.&lt;/span&gt;&lt;/b&gt; 1년 간 아쉬웠던 부분, 더 열심히 하고 싶었던 부분이 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;돌아보면 나태하게 시간을 보낸 날이 정말 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇지만, 새로 시작하는 2023년. 더 만족스러운 한 해를 보낼 수 있도록 보안하고 발전하면 되는 일이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 100세 인생 중 1/4을 살면서 나 스스로 고민하고, 선택한 일이 많은 한 해였다.&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;</description>
      <category>HisStory</category>
      <category>2022년</category>
      <category>회고</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/119</guid>
      <comments>https://kdhyo98.tistory.com/119#entry119comment</comments>
      <pubDate>Mon, 16 Jan 2023 08:00:28 +0900</pubDate>
    </item>
    <item>
      <title>[DataBase] CLI에서 쿼리할 때도 트랜잭션을 쓰자</title>
      <link>https://kdhyo98.tistory.com/118</link>
      <description>&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령문을 작성하고 모니터를 바라보면서 내가 뭘 고민하는지도 모르지만 고민을 하면서 바라본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실수라도 하게되면.. 진짜 눈물난다.. &lt;s&gt;(경험담)&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring에서 아주 쉽게 애노테이션으로 트랜잭션을 사용하지만, 왜 CLI에서 할 생각은 못했을까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;후회하면서 트랜잭션 하는 법을 정리한다..&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1673591278795&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;BEGIN; /* or START TRANSACTION */
SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
UPDATE table2 SET summary=@A WHERE type=1;
COMMIT; /* or ROLLBACK */&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;꼭.. 꼭 하자.. (나한테 하는 말)&lt;/p&gt;
&lt;p data-ke-size=&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;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/commit.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dev.mysql.com/doc/refman/8.0/en/commit.html&lt;/a&gt;&lt;/p&gt;</description>
      <category>DataBase</category>
      <category>MySQL</category>
      <category>sql</category>
      <category>Transaction</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/118</guid>
      <comments>https://kdhyo98.tistory.com/118#entry118comment</comments>
      <pubDate>Sun, 15 Jan 2023 16:32:28 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] 그냥되는 건 없다 1 - Spring-Boot AutoConfiguration</title>
      <link>https://kdhyo98.tistory.com/117</link>
      <description>&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;spring-boot 2.6.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;스프링부트에서 빈 기본설정파일들을 intellij로 아무리 눌러도 불러오는 곳을 쉽게 찾지 못한 김에 정리하게 된 기본설정하는 곳.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;197&quot; data-origin-height=&quot;46&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bKGron/btrVOdoFPXd/N8webmyRFlFUP11npkvKd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bKGron/btrVOdoFPXd/N8webmyRFlFUP11npkvKd1/img.png&quot; data-alt=&quot;mainApplication&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bKGron/btrVOdoFPXd/N8webmyRFlFUP11npkvKd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbKGron%2FbtrVOdoFPXd%2FN8webmyRFlFUP11npkvKd1%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;197&quot; height=&quot;46&quot; data-origin-width=&quot;197&quot; data-origin-height=&quot;46&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;mainApplication&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yUZnL/btrVCebDMfr/OvT9c2x4ndsXkfaHaWFC20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yUZnL/btrVCebDMfr/OvT9c2x4ndsXkfaHaWFC20/img.png&quot; data-alt=&quot;SpringBootApplication&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yUZnL/btrVCebDMfr/OvT9c2x4ndsXkfaHaWFC20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyUZnL%2FbtrVCebDMfr%2FOvT9c2x4ndsXkfaHaWFC20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;839&quot; height=&quot;197&quot; data-origin-width=&quot;839&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SpringBootApplication&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nvSPt/btrVBRHKOql/WAZMtlFr2GNYRQN0LgGDoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nvSPt/btrVBRHKOql/WAZMtlFr2GNYRQN0LgGDoK/img.png&quot; data-alt=&quot;AutoConfigurationImportSelector&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nvSPt/btrVBRHKOql/WAZMtlFr2GNYRQN0LgGDoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnvSPt%2FbtrVBRHKOql%2FWAZMtlFr2GNYRQN0LgGDoK%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;751&quot; height=&quot;250&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AutoConfigurationImportSelector&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qWPa4/btrVA1DSkbC/T8dWikKnz9kwew4xVqJkC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qWPa4/btrVA1DSkbC/T8dWikKnz9kwew4xVqJkC0/img.png&quot; data-alt=&quot;AutoConfigurationImportSelector - getCandidateConfigurations&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qWPa4/btrVA1DSkbC/T8dWikKnz9kwew4xVqJkC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqWPa4%2FbtrVA1DSkbC%2FT8dWikKnz9kwew4xVqJkC0%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;1158&quot; height=&quot;252&quot; data-origin-width=&quot;1158&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AutoConfigurationImportSelector - getCandidateConfigurations&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1292&quot; data-origin-height=&quot;323&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JGYUz/btrVF9gAXmr/VWagcC0U8AIj52iljO7W0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JGYUz/btrVF9gAXmr/VWagcC0U8AIj52iljO7W0k/img.png&quot; data-alt=&quot;spring.factories&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JGYUz/btrVF9gAXmr/VWagcC0U8AIj52iljO7W0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJGYUz%2FbtrVF9gAXmr%2FVWagcC0U8AIj52iljO7W0k%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;1292&quot; height=&quot;323&quot; data-origin-width=&quot;1292&quot; data-origin-height=&quot;323&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;spring.factories&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;133개의 설정파일들이 정의되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 AopAutoConfiguration, BatchAutoConfiguration과 같이 기본적으로 의존성이 추가되어 있지 않는 녀석들이 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVuHvN/btrVOz6u6xx/BSoggGOG2lONMpTlNtygbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVuHvN/btrVOz6u6xx/BSoggGOG2lONMpTlNtygbK/img.png&quot; data-alt=&quot;AopAutoConfiguration&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVuHvN/btrVOz6u6xx/BSoggGOG2lONMpTlNtygbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVuHvN%2FbtrVOz6u6xx%2FBSoggGOG2lONMpTlNtygbK%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;904&quot; height=&quot;674&quot; data-origin-width=&quot;904&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;AopAutoConfiguration&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;@ConditionalOnProperty&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- property가 참일 경우 컨테이너 등록&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;127&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w386z/btrVGZrU56j/krHJVNqNak4AEfHh4JUKMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w386z/btrVGZrU56j/krHJVNqNak4AEfHh4JUKMK/img.png&quot; data-alt=&quot;metadata.json&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w386z/btrVGZrU56j/krHJVNqNak4AEfHh4JUKMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw386z%2FbtrVGZrU56j%2FkrHJVNqNak4AEfHh4JUKMK%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;492&quot; height=&quot;127&quot; data-origin-width=&quot;492&quot; data-origin-height=&quot;127&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;metadata.json&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@ConditionalOnClass&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;@ConditionalOnMissingClass&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 해당 클래스가 존재하지 않을 경우 컨테이너 등록&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 스프링부트와 호환된다고 명시된 녀석들의 의존성을 추가하면 자동으로 설정되도록 미리 구현해 놓았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외에도 더 다양한 어노테이션이 존재하고, 궁금하다면 아래 참조 링크를 확인하길 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;525&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsZuxw/btrVIvjWu40/OyRp2xsfXfBMkyJkOKBsVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsZuxw/btrVIvjWu40/OyRp2xsfXfBMkyJkOKBsVK/img.png&quot; data-alt=&quot;configurations&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsZuxw/btrVIvjWu40/OyRp2xsfXfBMkyJkOKBsVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsZuxw%2FbtrVIvjWu40%2FOyRp2xsfXfBMkyJkOKBsVK%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;834&quot; height=&quot;525&quot; data-origin-width=&quot;834&quot; data-origin-height=&quot;525&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;configurations&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 의존성으로 filter를 거친 후 살아남은 Configuration은 24개정도&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 그만큼 내부는 복잡하다.. 한 번 보려고 하면 쉽게 타고타고 보기 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 하나씩 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;언제나 피드백은 환영입니다~!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참조&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pipe0502.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%9E%90%EB%8F%99%EC%84%A4%EC%A0%95-%EC%A1%B0%EA%B1%B4-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://pipe0502.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%9E%90%EB%8F%99%EC%84%A4%EC%A0%95-%EC%A1%B0%EA%B1%B4-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1673242711893&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;스프링부트의 자동설정시 사용 가능한 일부 조건 어노테이션에 대한 의미 @ConditionalOnBean: 특정 BEAN CLASS나 이름이 Bean Factory에 포함되면 진행 @ConditionalOnClass: 특정 CLASS가 경로에 있으면 진행 @Condi&quot; data-og-host=&quot;pipe0502.tistory.com&quot; data-og-source-url=&quot;https://pipe0502.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%9E%90%EB%8F%99%EC%84%A4%EC%A0%95-%EC%A1%B0%EA%B1%B4-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98&quot; data-og-url=&quot;https://pipe0502.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%9E%90%EB%8F%99%EC%84%A4%EC%A0%95-%EC%A1%B0%EA%B1%B4-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cU6mo9/hyRdMIEZgi/8aDrTIGnu4K6YHxycDBJ30/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cut1wb/hyRdFQh2ND/gk6qiwFgCypt0F02UKMey0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/CRGYE/hyRcBWg7IK/zR1KwOmk5bFWKnM8WcK8fK/img.png?width=1122&amp;amp;height=1125&amp;amp;face=0_0_1122_1125&quot;&gt;&lt;a href=&quot;https://pipe0502.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%9E%90%EB%8F%99%EC%84%A4%EC%A0%95-%EC%A1%B0%EA%B1%B4-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://pipe0502.tistory.com/entry/%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-%EC%9E%90%EB%8F%99%EC%84%A4%EC%A0%95-%EC%A1%B0%EA%B1%B4-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cU6mo9/hyRdMIEZgi/8aDrTIGnu4K6YHxycDBJ30/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/cut1wb/hyRdFQh2ND/gk6qiwFgCypt0F02UKMey0/img.png?width=800&amp;amp;height=800&amp;amp;face=0_0_800_800,https://scrap.kakaocdn.net/dn/CRGYE/hyRcBWg7IK/zR1KwOmk5bFWKnM8WcK8fK/img.png?width=1122&amp;amp;height=1125&amp;amp;face=0_0_1122_1125');&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;스프링부트의 자동설정시 사용 가능한 일부 조건 어노테이션에 대한 의미 @ConditionalOnBean: 특정 BEAN CLASS나 이름이 Bean Factory에 포함되면 진행 @ConditionalOnClass: 특정 CLASS가 경로에 있으면 진행 @Condi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;pipe0502.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://goodgid.github.io/Spring-Boot-EnableAutoConfiguration/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://goodgid.github.io/Spring-Boot-EnableAutoConfiguration/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1673242709546&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;@EnableAutoConfiguration 어노테이션을 선언하면 내부적으로 어떤 일이 일어날까?&quot; data-og-description=&quot;Index&quot; data-og-host=&quot;goodgid.github.io&quot; data-og-source-url=&quot;https://goodgid.github.io/Spring-Boot-EnableAutoConfiguration/&quot; data-og-url=&quot;https://goodgid.github.io/Spring-Boot-EnableAutoConfiguration/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dCBqTW/hyRcOafN8E/jRFAdWtJlbvE8Dd2t3wpt1/img.png?width=589&amp;amp;height=420&amp;amp;face=0_0_589_420&quot;&gt;&lt;a href=&quot;https://goodgid.github.io/Spring-Boot-EnableAutoConfiguration/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://goodgid.github.io/Spring-Boot-EnableAutoConfiguration/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dCBqTW/hyRcOafN8E/jRFAdWtJlbvE8Dd2t3wpt1/img.png?width=589&amp;amp;height=420&amp;amp;face=0_0_589_420');&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;@EnableAutoConfiguration 어노테이션을 선언하면 내부적으로 어떤 일이 일어날까?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Index&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;goodgid.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>JVM/Spring</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/117</guid>
      <comments>https://kdhyo98.tistory.com/117#entry117comment</comments>
      <pubDate>Mon, 9 Jan 2023 19:00:03 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] CaffeineCache key는 Object</title>
      <link>https://kdhyo98.tistory.com/116</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;122&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hk3QK/btrUQbgpROG/8xXdHqruhKN7o21sEg7yX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hk3QK/btrUQbgpROG/8xXdHqruhKN7o21sEg7yX1/img.png&quot; data-alt=&quot;CaffeineCache&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hk3QK/btrUQbgpROG/8xXdHqruhKN7o21sEg7yX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHk3QK%2FbtrUQbgpROG%2F8xXdHqruhKN7o21sEg7yX1%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;732&quot; height=&quot;122&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;122&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CaffeineCache&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;key가 Object이기 때문에 key를 지정할 때 타입을 신경써서 해야된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자칫 Integer로 지정했다가 String으로 조회하게 되면 조회가 안된다..&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;개인적으로는 하나의 타입으로 통일 (ex - String)하는 게 헷갈리지 않고 좋을 것 같다.&lt;/p&gt;</description>
      <category>JVM/Spring</category>
      <category>cache</category>
      <category>caffeineCache</category>
      <category>localcache</category>
      <category>Spring</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/116</guid>
      <comments>https://kdhyo98.tistory.com/116#entry116comment</comments>
      <pubDate>Fri, 30 Dec 2022 12:32:19 +0900</pubDate>
    </item>
    <item>
      <title>[kotlin] kotest After/before each not working for withData</title>
      <link>https://kdhyo98.tistory.com/115</link>
      <description>&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;kotest version 5.5&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;data-driven test를 위해 withData를 사용했을 때 afterEach / beforeEach가 예상과 달리 동작하지 않았다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;간단하게 kotest의 TestType부터 살펴보고 넘어가보자면..&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;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;b&gt;Type&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.3023%;&quot;&gt;&lt;b&gt;Description&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;b&gt;Container&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.3023%;&quot;&gt;다른 테스트를 포함할 수 있는 컨테이너&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;b&gt;Test&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.3023%;&quot;&gt;중첩 테스트를 포함할 수 없는 리프 테스트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 15.6977%;&quot;&gt;&lt;b&gt;Dynamic&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 84.3023%;&quot;&gt;Container, Test 둘 다 일 수 있으며, Propery test, data test와 같은 기능을 통해 테스트가 동적으로 추가될 때 사용&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;198&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KdlN2/btrUws2Lw1v/Rh1NsvcpLVWYUOU3XqgxBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KdlN2/btrUws2Lw1v/Rh1NsvcpLVWYUOU3XqgxBK/img.png&quot; data-alt=&quot;withData&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KdlN2/btrUws2Lw1v/Rh1NsvcpLVWYUOU3XqgxBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKdlN2%2FbtrUws2Lw1v%2FRh1NsvcpLVWYUOU3XqgxBK%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;1102&quot; height=&quot;198&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;198&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;withData&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;withData는 보다시피 TestType이 Dynamic을 사용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식문서에서 나온 내용으로 살펴보자면 Dynamic은 모든 테스트 타입에서 동작해야 한다.&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;961&quot; data-origin-height=&quot;239&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLOnjY/btrUvVKWt9x/kbWAqk6pNTK0tkVJETKAb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLOnjY/btrUvVKWt9x/kbWAqk6pNTK0tkVJETKAb1/img.png&quot; data-alt=&quot;before / after each&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLOnjY/btrUvVKWt9x/kbWAqk6pNTK0tkVJETKAb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLOnjY%2FbtrUvVKWt9x%2FkbWAqk6pNTK0tkVJETKAb1%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;961&quot; height=&quot;239&quot; data-origin-width=&quot;961&quot; data-origin-height=&quot;239&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;before / after each&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림에 나온 befor/after each는 TestType.Test이고, Dynamic도 당연하게 실행이 되어야 된다고 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 예상과 다르게 동작하지 않았고 해당 코드를 따라가보니..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;660&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TkoPB/btrUuv6RcPt/vCAK7ofF4wiKORdxkE4KCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TkoPB/btrUuv6RcPt/vCAK7ofF4wiKORdxkE4KCK/img.png&quot; data-alt=&quot;beforeTestBeforeAnyBeforeContainer&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TkoPB/btrUuv6RcPt/vCAK7ofF4wiKORdxkE4KCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTkoPB%2FbtrUuv6RcPt%2FvCAK7ofF4wiKORdxkE4KCK%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;814&quot; height=&quot;660&quot; data-origin-width=&quot;814&quot; data-origin-height=&quot;660&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;beforeTestBeforeAnyBeforeContainer&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TestType이 Dynamic이 실행된다는 부분은 어디에도 보이지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 &lt;b&gt;어 나도 오픈소스에 이슈를 남겨볼 기회인가?!&lt;/b&gt; 하고 kotest를 들어가보니..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kotest/kotest/pull/3300&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/kotest/kotest/pull/3300&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671962893571&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Invoking After/before each for dynamic tests by Kantis &amp;middot; Pull Request #3300 &amp;middot; kotest/kotest&quot; data-og-description=&quot;fixes #3290 Invokes beforeEach / afterEach between each case of a data-driven test (withData)&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/kotest/kotest/pull/3300&quot; data-og-url=&quot;https://github.com/kotest/kotest/pull/3300&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fLTDo/hyQ1rdRCBc/aEiBucKzlD4tErlkGrbtq0/img.png?width=1200&amp;amp;height=600&amp;amp;face=971_121_1029_184&quot;&gt;&lt;a href=&quot;https://github.com/kotest/kotest/pull/3300&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/kotest/kotest/pull/3300&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fLTDo/hyQ1rdRCBc/aEiBucKzlD4tErlkGrbtq0/img.png?width=1200&amp;amp;height=600&amp;amp;face=971_121_1029_184');&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;Invoking After/before each for dynamic tests by Kantis &amp;middot; Pull Request #3300 &amp;middot; kotest/kotest&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;fixes #3290 Invokes beforeEach / afterEach between each case of a data-driven test (withData)&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이미 논의 중인 내용&lt;/b&gt;&lt;/span&gt;이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6.0에 적용될 내용으로 이야기가 되고 있는 걸로 보이는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순히 each메소드에 추가할지, 다른 메소드를 만들지는 논의하고 있는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kotest/kotest-extensions-spring/pull/23&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/kotest/kotest-extensions-spring/pull/23&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1671963030262&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Run Spring lifecycle before/after for TestType.Dynamic by Kantis &amp;middot; Pull Request #23 &amp;middot; kotest/kotest-extensions-spring&quot; data-og-description=&quot;Closes kotest/kotest#2899&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/kotest/kotest-extensions-spring/pull/23&quot; data-og-url=&quot;https://github.com/kotest/kotest-extensions-spring/pull/23&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/Q7p20/hyQ1mXU82o/mBWSd3kw6XrsKJWIkPsCGK/img.png?width=1200&amp;amp;height=600&amp;amp;face=971_121_1029_184&quot;&gt;&lt;a href=&quot;https://github.com/kotest/kotest-extensions-spring/pull/23&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/kotest/kotest-extensions-spring/pull/23&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/Q7p20/hyQ1mXU82o/mBWSd3kw6XrsKJWIkPsCGK/img.png?width=1200&amp;amp;height=600&amp;amp;face=971_121_1029_184');&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;Run Spring lifecycle before/after for TestType.Dynamic by Kantis &amp;middot; Pull Request #23 &amp;middot; kotest/kotest-extensions-spring&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Closes kotest/kotest#2899&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 테스트 쪽에서는 수정했는데 아마 kotest에서 단순히 수정하기에는&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;withData와 같은 data-driven test를 진행할 때 after/before를 사용할 일이 있다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단은 after/before any 혹은 after/before test를 사용하면 된다!&lt;/p&gt;
&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kotest.io/docs/framework/lifecycle-hooks.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kotest.io/docs/framework/lifecycle-hooks.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kotest/kotest/pull/3300&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/kotest/kotest/pull/3300&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kotest/kotest-extensions-spring/pull/23&quot;&gt;https://github.com/kotest/kotest-extensions-spring/pull/23&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>JVM/Kotlin</category>
      <category>before/after</category>
      <category>kotest</category>
      <category>Kotlin</category>
      <category>withData</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/115</guid>
      <comments>https://kdhyo98.tistory.com/115#entry115comment</comments>
      <pubDate>Tue, 27 Dec 2022 10:00:05 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] Spring의 ObjectMapper 쉽게 Custom 만들기</title>
      <link>https://kdhyo98.tistory.com/114</link>
      <description>&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;프로젝트를 진행하다 보면 objectMapper를 새로 만들어서 할 일이 종종 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 새로 만들게 되면 Spring에서 기본적으로 제공해주는 옵션들을 찾아 동일하게&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;231&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2HPYZ/btrUtjeq2st/K0h1c4RlRQ45L3deBY3j90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2HPYZ/btrUtjeq2st/K0h1c4RlRQ45L3deBY3j90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2HPYZ/btrUtjeq2st/K0h1c4RlRQ45L3deBY3j90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2HPYZ%2FbtrUtjeq2st%2FK0h1c4RlRQ45L3deBY3j90%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;649&quot; height=&quot;231&quot; data-origin-width=&quot;649&quot; data-origin-height=&quot;231&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링에서 기본적으로 설정하는 properties와 기본적으로 넣어주는 모듈들이다.&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;스프링에서 기본으로 제공하는 ObjectMapper를 쉽게 만드는 법은 간단하다.&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;fun objectMapper(): ObjectMapper =
        Jackson2ObjectMapperBuilder().build()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위처럼 Jackson2ObjectMapperBuilder 를 사용해서 build를 하면 된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;281&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mzKPB/btrUtKiuWfJ/UCf7fd2sCuJIx5pp3F5M41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mzKPB/btrUtKiuWfJ/UCf7fd2sCuJIx5pp3F5M41/img.png&quot; data-alt=&quot;build&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mzKPB/btrUtKiuWfJ/UCf7fd2sCuJIx5pp3F5M41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmzKPB%2FbtrUtKiuWfJ%2FUCf7fd2sCuJIx5pp3F5M41%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;788&quot; height=&quot;281&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;281&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;build&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 build()를 보면 configure(mapper); 가 있는데 해당 부분에서 위에서 설명했던 기본적인 설정들을 진행해 준다.&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 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;527&quot; data-origin-height=&quot;52&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MwOT4/btrUtFBxNvU/L8k4NFyu4oPyxQsTEzqVH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MwOT4/btrUtFBxNvU/L8k4NFyu4oPyxQsTEzqVH1/img.png&quot; data-alt=&quot;@Deprecated&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MwOT4/btrUtFBxNvU/L8k4NFyu4oPyxQsTEzqVH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMwOT4%2FbtrUtFBxNvU%2FL8k4NFyu4oPyxQsTEzqVH1%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;527&quot; height=&quot;52&quot; data-origin-width=&quot;527&quot; data-origin-height=&quot;52&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;@Deprecated&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;new ObjectMapper()로 만들면 MapperFeature를 받는 부분들이 모두 @Deprecated가 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 외에도 많은 부분이 deprecated가 되었는데 objectMapper 측에서&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;3.0부터는 @Deprecated된 메서드들은 지워질 거라고 설명하기 때문에 언제 3.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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;그럼 어떻게 바꾸냐?&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1671808258302&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;fun objectMapper(): ObjectMapper =
        JsonMapper.builder().disable(MapperFeature.DEFAULT_VIEW_INCLUSION).build()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JsonMapper.builder()로 변경할 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;아예 새로운 ObjectMapper를 만들고 싶을 땐 당연히 새로 만들면 됩니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 내용은, Spring에서 정의한 ObjectMapper에서 속성을 추가 및 변경을 하고 싶을 때입니다.&lt;/p&gt;
&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>JVM/Spring</category>
      <category>ObjectMapper</category>
      <category>Spring</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/114</guid>
      <comments>https://kdhyo98.tistory.com/114#entry114comment</comments>
      <pubDate>Mon, 26 Dec 2022 10:00:52 +0900</pubDate>
    </item>
    <item>
      <title>[SQL] MODIFY 시 기존 옵션 조심!</title>
      <link>https://kdhyo98.tistory.com/113</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cE8rsp/btrUo4N2Z3H/Bc5603PTyaLFZclejC6zsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cE8rsp/btrUo4N2Z3H/Bc5603PTyaLFZclejC6zsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cE8rsp/btrUo4N2Z3H/Bc5603PTyaLFZclejC6zsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcE8rsp%2FbtrUo4N2Z3H%2FBc5603PTyaLFZclejC6zsK%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;342&quot; height=&quot;177&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;MODIFY로 comment를 추가할 일이 있어서 추가를 진행했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데, 적용 후에 확인해보니 not null -&amp;gt; null로 변경되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;72&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EllUT/btrUpCqgH05/TsHwG5xUmk8Bf9IBjf502k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EllUT/btrUpCqgH05/TsHwG5xUmk8Bf9IBjf502k/img.png&quot; data-alt=&quot;before&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EllUT/btrUpCqgH05/TsHwG5xUmk8Bf9IBjf502k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEllUT%2FbtrUpCqgH05%2FTsHwG5xUmk8Bf9IBjf502k%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;739&quot; height=&quot;72&quot; data-origin-width=&quot;739&quot; data-origin-height=&quot;72&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;before&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1671766270902&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ALTER TABLE user
    MODIFY name varchar(50) COMMENT '사용자명';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 적용하면 not null 옵션이 null로 변경된다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;77&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tqGOs/btrUpDbGVz7/vVex0xrVt0Aut23SYmaF6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tqGOs/btrUpDbGVz7/vVex0xrVt0Aut23SYmaF6k/img.png&quot; data-alt=&quot;after&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tqGOs/btrUpDbGVz7/vVex0xrVt0Aut23SYmaF6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtqGOs%2FbtrUpDbGVz7%2FvVex0xrVt0Aut23SYmaF6k%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;744&quot; height=&quot;77&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;77&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;after&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1671766295848&quot; class=&quot;routeros&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ALTER TABLE user
    MODIFY name varchar(50) not null COMMENT '사용자명';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;not null이었어도 not null을 명시해주어야 null로 변경되지 않는다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style4&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;null만 그러냐? 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번엔 NOT NULL이 빠졌으니 NOT NULL 옵션만을 추가해보자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;343&quot; data-origin-height=&quot;163&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dNZEez/btrUo5e6mLM/7UZwJxKytkqj9IppUVY62K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dNZEez/btrUo5e6mLM/7UZwJxKytkqj9IppUVY62K/img.png&quot; data-alt=&quot;before datagrip auto-generated&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dNZEez/btrUo5e6mLM/7UZwJxKytkqj9IppUVY62K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdNZEez%2FbtrUo5e6mLM%2F7UZwJxKytkqj9IppUVY62K%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;343&quot; height=&quot;163&quot; data-origin-width=&quot;343&quot; data-origin-height=&quot;163&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;before datagrip auto-generated&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1671767435970&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ALTER TABLE user
    MODIFY name varchar(50) NOT NUll;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;257&quot; data-origin-height=&quot;157&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AMFQD/btrUrs8CjtJ/vC1LCYwnU5RI90wRdMflY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AMFQD/btrUrs8CjtJ/vC1LCYwnU5RI90wRdMflY1/img.png&quot; data-alt=&quot;after datagrip auto-generated&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AMFQD/btrUrs8CjtJ/vC1LCYwnU5RI90wRdMflY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAMFQD%2FbtrUrs8CjtJ%2FvC1LCYwnU5RI90wRdMflY1%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;257&quot; height=&quot;157&quot; data-origin-width=&quot;257&quot; data-origin-height=&quot;157&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;after datagrip auto-generated&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;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;modify를 할 일이 있다면 기존 옵션도 명시해주어야 한다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DataBase</category>
      <category>MySQL</category>
      <category>sql</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/113</guid>
      <comments>https://kdhyo98.tistory.com/113#entry113comment</comments>
      <pubDate>Fri, 23 Dec 2022 12:52:49 +0900</pubDate>
    </item>
    <item>
      <title>[독서] 식사가 잘못 됐습니다.</title>
      <link>https://kdhyo98.tistory.com/112</link>
      <description>&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;중3, 고1부터 나기 시작했던 여드름이 25살인 올해까지 멈추지 않고 끊임 없이 난다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;식습관이 잘못됐나 먹는 걸 좀 바꾸면서 이 기회에 건강한 식습관을 가져볼까 하면서 책을 읽기로 마음먹었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요즘 책을 읽으면서 드는 생각은, 책 모든 내용을 기억할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 사람들도 그런가.. 난 책을 읽다보면 앞 부분을 계속 까먹게 된다. 다 읽고 나서도 기억되는 부분이 많지는 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 난 새로 알게 된 것들과, 알고는 있었지만 앞으로 계속 기억하고 싶은 것들, 꾸준히 지켜보고 싶은 것들을 정리하려한다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&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;li&gt;단백질 보충제는 신장을 망친다.&lt;/li&gt;
&lt;li&gt;과일도 많이 먹으면 살이 찐다.&lt;/li&gt;
&lt;li&gt;몸에 좋은 음식
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;올리브유, 와인, 초콜릿, 콩, 치즈, 블루베리, 커피, 식초, 날것(회)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;하루 2리터의 물을 마시자.&lt;/li&gt;
&lt;li&gt;올리브유는 혈당치를 낮춘다.&lt;/li&gt;
&lt;li&gt;화이트와인을 마시면 살이 빠진다.&lt;/li&gt;
&lt;li&gt;아침, 점심, 저녁 비율은 3:5:2&lt;/li&gt;
&lt;li&gt;아침에는 키위, 블루베리가 좋다.&lt;/li&gt;
&lt;li&gt;요구르트는 조금씩 매일 먹는다. (하루 100그램 전후)&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;잠들기 4시간 전에는 먹지 말자.&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 style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;장어, 닭고기, 참치&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;위장의 7할만 채우면 장수한다.&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;/li&gt;
&lt;li&gt;체온을 올리면 면역력이 높아진다.&lt;/li&gt;
&lt;li&gt;초콜릿은 카카오 70% 이상제품으로 하루에 한 25그램 정도 섭취하자.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 무리하게 `밀가루 아예 안먹고 밥도 정량만 딱 먹고, 위 모든 내용을 지킬거야!`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게는 못 산다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 아 그렇구나. 앞으론 먹을 때 조금은 신경쓰면서 먹어야지 정도로 책을 봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(개인적으로 술을 좋아해서 저녁에 하루 와인 한, 두잔은 실천을 꼭 해볼 예정ㅇ..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책정보&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://product.kyobobook.co.kr/detail/S000001301701&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://product.kyobobook.co.kr/detail/S000001301701&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1670054070892&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;식사가 잘못됐습니다 | 마키타 젠지 - 교보문고&quot; data-og-description=&quot;식사가 잘못됐습니다 | 도대체 무엇이 올바른 식사법일까?우리가 취해야 할 바람직한 식사를 최신의 과학적 근거를 바탕으로 설명하는 『식사가 잘못됐습니다』. 오랜 세월 비만의 원흉으로 지&quot; data-og-host=&quot;product.kyobobook.co.kr&quot; data-og-source-url=&quot;https://product.kyobobook.co.kr/detail/S000001301701&quot; data-og-url=&quot;https://product.kyobobook.co.kr/detail/S000001301701&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bQwhPS/hyQMA91nzE/kLp07RuGVSmeiPg5IHKZ5k/img.jpg?width=458&amp;amp;height=685&amp;amp;face=0_0_458_685,https://scrap.kakaocdn.net/dn/bFS4nO/hyQL8ztTUc/EDkHAOpQx589uJNGLWcjBk/img.jpg?width=458&amp;amp;height=685&amp;amp;face=0_0_458_685,https://scrap.kakaocdn.net/dn/dC3rQR/hyQMFKgPfy/IK5yV8PH0GTG808xWt4FkK/img.jpg?width=814&amp;amp;height=2174&amp;amp;face=594_1311_672_1399&quot;&gt;&lt;a href=&quot;https://product.kyobobook.co.kr/detail/S000001301701&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://product.kyobobook.co.kr/detail/S000001301701&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bQwhPS/hyQMA91nzE/kLp07RuGVSmeiPg5IHKZ5k/img.jpg?width=458&amp;amp;height=685&amp;amp;face=0_0_458_685,https://scrap.kakaocdn.net/dn/bFS4nO/hyQL8ztTUc/EDkHAOpQx589uJNGLWcjBk/img.jpg?width=458&amp;amp;height=685&amp;amp;face=0_0_458_685,https://scrap.kakaocdn.net/dn/dC3rQR/hyQMFKgPfy/IK5yV8PH0GTG808xWt4FkK/img.jpg?width=814&amp;amp;height=2174&amp;amp;face=594_1311_672_1399');&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;product.kyobobook.co.kr&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;</description>
      <category>HisStory</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/112</guid>
      <comments>https://kdhyo98.tistory.com/112#entry112comment</comments>
      <pubDate>Sat, 3 Dec 2022 16:55:50 +0900</pubDate>
    </item>
    <item>
      <title>Kotest 5.1 이상 버전 java.lang.NoClassDefFoundError: kotlinx/coroutines/test/TestDispatcher 해결방법</title>
      <link>https://kdhyo98.tistory.com/111</link>
      <description>&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kotlin - 1.6&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kotest - 5.5.4&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spring boot - 2.6.x&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;kotest 도입을 위해 모듈을 추가해서 테스트를 돌렸더니 아래와 같은 에러가 발생했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;250&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qc6Nx/btrSlW6QsZJ/Tq0Kjh5PkCjqHkG3Hf8fl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qc6Nx/btrSlW6QsZJ/Tq0Kjh5PkCjqHkG3Hf8fl0/img.png&quot; data-alt=&quot;error&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qc6Nx/btrSlW6QsZJ/Tq0Kjh5PkCjqHkG3Hf8fl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQc6Nx%2FbtrSlW6QsZJ%2FTq0Kjh5PkCjqHkG3Hf8fl0%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;849&quot; height=&quot;250&quot; data-origin-width=&quot;849&quot; data-origin-height=&quot;250&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;error&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;원인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kotest 5.1 버전부터 kotlin-coroutiones 1.6 버전을 사용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, spring boot 2.6.x 대의 kotlin-coroutiones 버전은 1.5.2 를 사용하고 있어서 문제가 발생했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;144&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLHRZ9/btrSlWyWjaN/m96mIFOPChpvDOSxK4xewK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLHRZ9/btrSlWyWjaN/m96mIFOPChpvDOSxK4xewK/img.png&quot; data-alt=&quot;spring boot dependency&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLHRZ9/btrSlWyWjaN/m96mIFOPChpvDOSxK4xewK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLHRZ9%2FbtrSlWyWjaN%2Fm96mIFOPChpvDOSxK4xewK%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;360&quot; height=&quot;144&quot; data-origin-width=&quot;360&quot; data-origin-height=&quot;144&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;spring boot dependency&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOMedY/btrSm0t13ei/mIvSlxR77YAqkfMOtuP0Pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOMedY/btrSm0t13ei/mIvSlxR77YAqkfMOtuP0Pk/img.png&quot; data-alt=&quot;기존 spring boot 버전정보&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOMedY/btrSm0t13ei/mIvSlxR77YAqkfMOtuP0Pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOMedY%2FbtrSm0t13ei%2FmIvSlxR77YAqkfMOtuP0Pk%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;449&quot; height=&quot;280&quot; data-origin-width=&quot;449&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;기존 spring boot 버전정보&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1335&quot; data-origin-height=&quot;247&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dU1tOb/btrSmsK4MlR/KaUbBKbQQVLxLvpdWy8DQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dU1tOb/btrSmsK4MlR/KaUbBKbQQVLxLvpdWy8DQ1/img.png&quot; data-alt=&quot;kotest dependencies&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dU1tOb/btrSmsK4MlR/KaUbBKbQQVLxLvpdWy8DQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdU1tOb%2FbtrSmsK4MlR%2FKaUbBKbQQVLxLvpdWy8DQ1%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;1335&quot; height=&quot;247&quot; data-origin-width=&quot;1335&quot; data-origin-height=&quot;247&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;kotest dependencies&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;해결방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;io.spring.dependency-management 에서 정의한 기본 버전정보를 변경해주면 된다.&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;build.gradle.kts&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1669700981620&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;extra[&quot;kotlin-coroutines.version&quot;] = &quot;1.6.0&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;or&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;gradle.properties&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1669701058734&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;kotlin-coroutines.version=1.6.0&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;275&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSZceC/btrSnVsuajL/4l8Jk2rtc1v1k42KFPk9o1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSZceC/btrSnVsuajL/4l8Jk2rtc1v1k42KFPk9o1/img.png&quot; data-alt=&quot;버전 변경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSZceC/btrSnVsuajL/4l8Jk2rtc1v1k42KFPk9o1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSZceC%2FbtrSnVsuajL%2F4l8Jk2rtc1v1k42KFPk9o1%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;447&quot; height=&quot;275&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;275&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;버전 변경&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;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;spring boot 2.7.x 부터는 kotlinx-corutines 버전을 1.6.x 를 사용하고 있기에 이상 버전부터는 문제없이 돌아간다.&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/kotest/kotest/issues/2782&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/kotest/kotest/issues/2782&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://mvnrepository.com/artifact/io.kotest/kotest-framework-api-jvm/5.1.0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://mvnrepository.com/artifact/io.kotest/kotest-framework-api-jvm/5.1.0&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/spring-projects/spring-boot/blob/v2.6.2/spring-boot-project/spring-boot-dependencies/build.gradle#L1048&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/spring-projects/spring-boot/blob/v2.6.2/spring-boot-project/spring-boot-dependencies/build.gradle#L1048&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>JVM/Kotlin</category>
      <category>Coroutines</category>
      <category>kotest</category>
      <category>Kotlin</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/111</guid>
      <comments>https://kdhyo98.tistory.com/111#entry111comment</comments>
      <pubDate>Tue, 29 Nov 2022 14:57:48 +0900</pubDate>
    </item>
    <item>
      <title>Spring JacksonObjectMapper는 어떻게 jackson-module-kotlin을 등록하나</title>
      <link>https://kdhyo98.tistory.com/110</link>
      <description>&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;이전에는 jackson-module-kotlin 모듈을 추가하면 자동으로 spring objectMapper에서 사용한다길래&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;찾아보게 된 계기는, 회사에서 만든 objectMapper가 jackson-module-kotlin 모듈을 추가했음에도 제대로 동작하지 않았었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 다른 문제 때문이라 생각했지만, 몇 번 다시 보니 objectMapper에 KotlinModule()을 넣어주는 부분이 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;역시 모듈만 추가 한다고 자동으로 모든 objectMapper에서 적용되지 않을 텐데.. 생각이 매우 짧았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 스프링에서는 어떻게 모듈 추가만으로 jackson-module-kotlin&amp;nbsp;를 사용하는지 궁금해서 찾아보게 되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;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;처음으로 1차원적으로 찾아보려고 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;jackson-module-kotlin을 추가해서 사용되는 거니까 당연히 해당 모듈에서 스프링을 어떻게 수정해서 넣나?&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;다음 생각은 역시 spring에서 사용하니 spring에서 해당 모듈의 여부를 체크해서 사용하겠구나 였다.&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;644&quot; data-origin-height=&quot;276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pmKQi/btrSagwWMgS/44n6xqSiRUyjAXqNwnEPW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pmKQi/btrSagwWMgS/44n6xqSiRUyjAXqNwnEPW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pmKQi/btrSagwWMgS/44n6xqSiRUyjAXqNwnEPW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpmKQi%2FbtrSagwWMgS%2F44n6xqSiRUyjAXqNwnEPW0%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;276&quot; data-origin-width=&quot;644&quot; data-origin-height=&quot;276&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Jackson2ObjectMapperBuilder&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;973&quot; data-origin-height=&quot;342&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/banjqA/btrSbUmCWM6/NctkXQCClf0T4fP1tjk640/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/banjqA/btrSbUmCWM6/NctkXQCClf0T4fP1tjk640/img.png&quot; data-alt=&quot;configure&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/banjqA/btrSbUmCWM6/NctkXQCClf0T4fP1tjk640/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbanjqA%2FbtrSbUmCWM6%2FNctkXQCClf0T4fP1tjk640%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;973&quot; height=&quot;342&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;342&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;configure&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;findWellKnownModules&lt;/b&gt; 변수는 defualt로 true가 설정되어있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;registerWellKnownModulesIfAvailable&lt;/b&gt;&lt;/span&gt; 메서드가 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드 이름을 '&lt;b&gt;잘 알려진 모듈이 사용가능한 경우 등록&lt;/b&gt;'으로 해석할 수 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 메서드명만 보고 어 여긴가 이런 생각이 들 정도니.. 이래서 &lt;b&gt;네이밍이 중요하구나&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;1006&quot; data-origin-height=&quot;520&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czdr1W/btrR9v9ctsk/BKpJZ70k708NYxuyTUPeu0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czdr1W/btrR9v9ctsk/BKpJZ70k708NYxuyTUPeu0/img.png&quot; data-alt=&quot;registerWellKnownModulesIfAvailable 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czdr1W/btrR9v9ctsk/BKpJZ70k708NYxuyTUPeu0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fczdr1W%2FbtrR9v9ctsk%2FBKpJZ70k708NYxuyTUPeu0%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;1006&quot; height=&quot;520&quot; data-origin-width=&quot;1006&quot; data-origin-height=&quot;520&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;registerWellKnownModulesIfAvailable 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/FasterXML/jackson-datatype-jdk8&quot;&gt;jackson-datatype-jdk8&lt;/a&gt; /&amp;nbsp;&lt;a href=&quot;https://github.com/FasterXML/jackson-datatype-jsr310&quot;&gt;jackson-datatype-jsr310&lt;/a&gt;&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;959&quot; data-origin-height=&quot;762&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pp4ML/btrR84xtEOJ/5Q1eGB6tX9B3NgZT6PWjAK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pp4ML/btrR84xtEOJ/5Q1eGB6tX9B3NgZT6PWjAK/img.png&quot; data-alt=&quot;registerWellKnownModulesIfAvailable 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pp4ML/btrR84xtEOJ/5Q1eGB6tX9B3NgZT6PWjAK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fpp4ML%2FbtrR84xtEOJ%2F5Q1eGB6tX9B3NgZT6PWjAK%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;959&quot; height=&quot;762&quot; data-origin-width=&quot;959&quot; data-origin-height=&quot;762&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;registerWellKnownModulesIfAvailable 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/FasterXML/jackson-datatype-joda&quot; data-pjax=&quot;#repo-content-pjax-container&quot; data-turbo-frame=&quot;repo-content-turbo-frame&quot;&gt;jackson-datatype-joda&lt;/a&gt; / &lt;a href=&quot;https://github.com/FasterXML/jackson-module-kotlin&quot; data-pjax=&quot;#repo-content-pjax-container&quot; data-turbo-frame=&quot;repo-content-turbo-frame&quot;&gt;jackson-module-kotlin&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 모듈에 대해서는 등록이 가능한지 체크 후에 추가해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 찾던 부분이 여있었다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;kotlin을 사용중이면 jackson-module-kotlin을 사용하려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모듈이 없다면 logger.warn으로 추가해야 한다고 알려준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;spring에서도 이렇게 경고를 띄워줄 정도로 kotlin을 사용할 땐 jackson-module-kotlin을 사용하는 것이이점이 많다는 걸 알 수 있다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;어떤 모듈들은 Spring 공식지원이라면서 모듈 추가만 해줘도 자동으로 사용이 가능한 것들이 종종 있다.&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;피드백은 언제나 환영입니다 ! (__)&lt;/p&gt;
&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/FasterXML/jackson-module-kotlin&quot;&gt;https://github.com/FasterXML/jackson-module-kotlin&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JVM/Spring</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/110</guid>
      <comments>https://kdhyo98.tistory.com/110#entry110comment</comments>
      <pubDate>Sun, 27 Nov 2022 14:08:14 +0900</pubDate>
    </item>
    <item>
      <title>[F-Lab] 2022-02 ~ 2022-09 6개월.2주(?) 멘토링 후기</title>
      <link>https://kdhyo98.tistory.com/109</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;780&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgEpoS/btrQ0vINpqK/vYtVaDoKz46k7gvc6bddj0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgEpoS/btrQ0vINpqK/vYtVaDoKz46k7gvc6bddj0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgEpoS/btrQ0vINpqK/vYtVaDoKz46k7gvc6bddj0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgEpoS%2FbtrQ0vINpqK%2FvYtVaDoKz46k7gvc6bddj0%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;345&quot; height=&quot;192&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;780&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;F-Lab을 통해서 좋은 멘토와 멘티를 만날 수 있었고, 의미 있는 시간을 통해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4월~9월 약 6개월의 공백 후 SI 회사에서 내가 원하는 서비스회사로 이직할 수 있게 되었다.&lt;/p&gt;
&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;2040&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AVx5N/btrQ2efMvDl/9NkknO9ZANwGPJ4FVlHQSk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AVx5N/btrQ2efMvDl/9NkknO9ZANwGPJ4FVlHQSk/img.jpg&quot; data-alt=&quot;허위광고가 아니었다..(?)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AVx5N/btrQ2efMvDl/9NkknO9ZANwGPJ4FVlHQSk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAVx5N%2FbtrQ2efMvDl%2F9NkknO9ZANwGPJ4FVlHQSk%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;280&quot; height=&quot;508&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;2040&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  서론&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;지원 동기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭐 많은 취준생, 신입 개발자들과 크게 다르지 않은 고민을 통해서 지원하게 되었다.&lt;/p&gt;
&lt;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;SI 회사에서 서비스회사로의 이직&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;또한, 유명한 IT 회사들이 자신의 회사들의 개발자들을 모집할 때 홍보하는 것 중&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;아니라면, 어떤 방향으로 살아가야 할지, 지금보다 나아지려면 어떻게 발전해야 할지, 미래에 대한 궁금증이 컸다.&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;F-Lab에서 IT 기업의 현직 시니어 개발자분들이 멘토라는 점에서 나의 궁금증을 해소할 수 있을 것 같다는 생각에 끌리게 되었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검색하면서 찾다 보니 페이스북과 인스타그램 알고리즘 녀석이 계속 더 보라고 광고를 계속 보여줘서.. 자연스레 끌리게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;지원 고민&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제일 큰 고민은 시간과 돈이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나에게 800만 원이라는 돈은 정말 큰돈이었고, 큰 결심이 있어야만 도전해볼 수 있었다.&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;F-Lab 멘토가 아무리 좋다고 해도 내가 처음 쉬어보는 6개월간의 백수 기간을.. 공부에만 올인할 수 있을지 나에 대한 의심도 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;결심&lt;/b&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;내가 필요한 게 있을 때마다 입에 달고 사는 말이다.&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;내가 50에서 60으로 성장한다고 해도 현재보단 나아질 거라는 믿음이 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;어차피 지원했을 때 지금보다 나아지는 게 확신한다면 일단은 해보자! 라는 생각으로 지원&lt;/b&gt;을 하게 되었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;6개월간의 멘토링 기간 동안 아쉬운 점도 많았고, 좋았던 점도 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 장단점이 확실히 느껴지게 되어서 순전히 내가 6개월간 느낀 장단점을 적으려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 랜덤 멘토 멘티&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;물론, F-Lab에서 나랑 가장 잘 맞을 것 같은 사람들로 구성해준다고는 하지만..&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월부터 멘토링을 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2월에 같이 시작하기로 한 멘토와 멘티 두 분 다 개인 사정으로 인해 2주 만에 F-Lab을 그만두었다.&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;지원하기 전부터 이 부분이 걱정되어 F-Lab에도 문의했었지만, 지금까지는 멘토가 먼저 그만두는 예는 없었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토분들도 현직에 계신 분들이기 때문에 본인 이미지도 중요하여 그런 일은 거의 없을 거라 하셨었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쩔 수 없는.. 개인사정이 나에게 적용될 줄은 몰랐다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, 이런 경우는 정말 드문 케이스이긴 하지만, 당사자로서는 나도 그만둘까.. 라는 생각이 들 정도로 조금 싱숭생숭했던 점이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 멘토와 멘티도 걱정이 됐었다. 또 그만두면 어쩌지라는..? 내가 .. 돈 주고 이런 고민까지 해야하나.. 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 케이스가 아니라도 나랑 마음에 맞지 않는 멘티와 매치가 된다면 6개월 정말 힘들 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 진짜 운에 기대야 하고, F-Lab의 안목을 전적으로 믿는 수밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(물론, 두 번째로 만난 멘토와 멘티는 다행히 잘 맞아서 6개월의 시간을 같이 잘 보낼 수 있었다.)&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;2. 비싼 금액&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;800만 원이라는 금액은 너무도 큰 금액이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;몇 달 뒤에 멘토링을 신청하면 어느 정도 할인이 들어가서 700 중후반이 되긴 하지만 그래도 큰 금액이다.&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;안 그러면 시간이 순식간에 흘러서 800이 증발해버릴 수도 있다.&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;3. 일주일, 한 시간 멘토링 나머지 시간은 자율학습&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;일주일에 한 번, 하루 한 시간.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 경우는 6개월간 27번의 멘토링 시간이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정식 시간이 한 시간으로 정하긴 했어도 멘토님이 더 열심히 설명해주시느라 시간을 초과한 경우가 매우 많기는 하지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 짧은 시간이라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, 어느 걸 공부하는 게 좋을지에 대한 방향성은 잡아주시기는 하지만,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지 시간에 내가 알아서, 스스로 공부하고 프로젝트하고, 본인의 의지력으로 노력해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 본인의 노력과 의지력을 통해 대부분의 6개월의 시간을 보내야 한다는 것, 이 부분이 내가 제일 힘들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나름대로 의지가 강하고 학습하는 걸 좋아한다고 생각했지만.. 막상 인생 첫 백수 생활을 즐기느라..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의지력이 매우 줄어서 내가 처음 생각했던 학습량의 1/3도 하지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좀 더 열심히 하지 못했던 게 내가 멘토링을 하면서 제일 아쉬웠던 부분이다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;F-Lab과 정말 잘 어울리고, 큰 시너지 효과를 낼 수 있는 사람은 &lt;b&gt;MBTI로 따지자면, E&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 공부 의지가 있는 사람들의 모임&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 단점에서도 얘기했듯 큰 금액을 내야 F-Lab을 참여할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 큰 금액을 주면서까지 본인의 성장을 추구하는 사람들이 모여있는 곳이 F-Lab이다.&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;F-Lab은 멘티들이 친해질 수 있는 계기를 만들어주기 위해 모각코나 각종 행사를 하고는 한다.&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 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1-1. F-Lab 주최 행사 및 멘티 주최 스터디&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;F-Lab 주관으로 멘티들이 친해질 수 있는 행사를 종종 하고는 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토링 처음 시작할 때 같은 기수들과 오리엔테이션을 하고, 이사했을 때 집들이 파티도 하고, F-Lab 직원분들과의 점심 식사 자리,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;독서 스터디 등 멘티들이 잘 적응하고, 친해지고, 더 F-Lab 활동을 의미 있게 지낼 수 있도록 노력을 많이 해주신다.&lt;/p&gt;
&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;F-Lab이라는 울타리 안에서 스터디를 구해서 진행하는 것이 중간 포기율이 현저히 적고, 참여율이 더 높을 거로 생각한다.&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;2. 좋은 멘토와 멘티&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;정말 거의 모든 멘토는 멘티를 잘 성장시키고 싶어 하고, 멘티는 잘 성장하고 싶어 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인들의 돈과 시간을 써가면서 이 F-Lab에 참여한 만큼, 잘되고 싶은 마음이 큰 사람들이 모였다.&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;물어보고 싶은 것을 진짜 100개 이상을 물어봐도 멘토님은 친절하게 다 설명해주실 거다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘티가 잘 안되길 바라는 멘토는 없으므로 본인이 궁금한 것들을 적극적으로 질문하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토링 방향성이 원하는 방향성이 아니라면 피드백을 주면서 멘토링 시간을 알차게 보내기 위해 노력한다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정말 유의미한 시간을 보낼 수 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나의 경우 멘토링 후반에는 멘토에게 질문 좀 했지만, 일단 혼자 끝까지 찾아보고 시간을 많이 버리는 스타일이어서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;초반에 질문을 많이 하지 않았던 점이 아쉬웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;될 수 있으면 사소한 거라도 물어보고 토론하고 이야기해보는 게 좋다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'메서드 네이밍 이렇게 했는데 잘 읽히나요?' 이런 사소한 질문도 잘 답변해주실거로 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당연하지만, 멘티와도 가깝게 지내는 게 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어쨌든 6개월의 시간을 나와 함께 보낼 사람이고, F-Lab에서 제일 이야기를 많이 할 사람이다.&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 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3. 슬랙을 통한 커뮤니케이션&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토링 시간이 일주일 한 번, 한 시간으로 멘토링 시간이 짧은 것을 단점에 뽑았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이건 정말 아무리 생각해도.. 단점이 맞다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 큰돈을 써가면서 수업을 듣는 정식 시간 27시간.. 대학교 등록금보다 몇 배는 비싸다.&lt;/p&gt;
&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;F-Lab에서는 궁금하거나 질문이 있을 때 아무 때나 진짜 새벽(?)에 보내도 괜찮...을거다.. (새벽 시간은 멘토한테 양해를..)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 아무 때나 궁금한 걸 물어보고, 토론하고 이야기할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, 멘토님들도 다 현직자분들이기 때문에 칼답을 바랄 수는 없지만, 질문에 답은 꼭 해주신다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본인만 노력하면 다 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토님이 아니라더라도 F-Lab Community에 '무엇이든_물어보세요' 라는 채널이 있어서&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 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 개발자의 마인드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자가 어떻게 살아가면 좋을지 멘토께서 조언을 정말 많이 해주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 객체에 대해 이야기할 때 카페 같은 곳에 가서도 의자 책상 등을 어떤 공통점으로 묶을 것인지 이런 생각들을 하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현실의 존재하는 것을 어떻게 코드로 문제해결을 할 수 있을지에 관해서도 이야기를 많이 해주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어찌 보면 당연한 거지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기업 블로그들을 보면서 트렌드를 쫓아야한다는 이야기, 출퇴근 시간에 어떤 걸 보면 좋을지 등 정말 다양하게 이야기 해주셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다 쓰기에는 너무 많지만, 앞으로 개발자로 살아갈 때 마음가짐에 대해 큰 도움이 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4. 이력서 피드백 + 모의 면접&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;사실 난 이 장점으로 충분히 멘토링 하길 잘했다고 생각한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;멘토링 이전에 작성했던 내 이력서와 멘토링 이후의 이력서를 비교하면 아 면접관들이 누굴 뽑고 싶어하겠구나를 알 수 있게 되었다.&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;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;정말 사람들 앞에서 한 마디만 내뱉어도 얼굴이 붉어지는 내가 그래도 면접을 보러 갈 수 있던 계기지 않을까 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인적으로 멘토링 기간을 정말 80%도 활용하지 못했고, 많이 나태한 시간을 보냈다는 생각이 들었는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이력서 피드백과 모의 면접을 통해 난 만족하는 회사에 이직할 수 있었다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;개인적으로 본인이 너무 소심하고, 의지력이 부족해서 누군가가 이끌어줘야 학습할 수 있다고 생각한다면 F-Lab은 반대하고 싶다.&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;&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;F-Lab을 추천하고 싶다. (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;비싼 금액과 긴 시간만큼 본인이 원하는 걸 이루기 위해서는 본인의 노력이 정말 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;F-Lab을 하겠다고 생각한다면 하루 10시간 공부할 각오로 지원하는 게 좋다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에 다니면서도 할 수 있다고 적혀있긴 하지만..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사 다니면서 한 달 해본 경험으로서 매우 힘들고 정말 강한 의지가 있지 않고는 힘들 거라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 부트캠프를 들어본 적이 없어서 비교할 수는 없지만 F-Lab 개인적으로 좋은 경험이었다. 돈, 시간 아깝지 않았다.&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;581&quot; data-origin-height=&quot;458&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Rnv0x/btrQ28y6XEn/IoK5VcmYV6kMLYAklxxggk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Rnv0x/btrQ28y6XEn/IoK5VcmYV6kMLYAklxxggk/img.png&quot; data-alt=&quot;멘토링 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Rnv0x/btrQ28y6XEn/IoK5VcmYV6kMLYAklxxggk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRnv0x%2FbtrQ28y6XEn%2FIoK5VcmYV6kMLYAklxxggk%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;581&quot; height=&quot;458&quot; data-origin-width=&quot;581&quot; data-origin-height=&quot;458&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;</description>
      <category>HisStory</category>
      <category>F-Lab</category>
      <category>부트캠프</category>
      <category>에프랩</category>
      <category>후기</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/109</guid>
      <comments>https://kdhyo98.tistory.com/109#entry109comment</comments>
      <pubDate>Sun, 13 Nov 2022 17:21:48 +0900</pubDate>
    </item>
    <item>
      <title>[일기] 실행계획을 사용해서 꼭 어떻게 동작하는 지 확인하자!</title>
      <link>https://kdhyo98.tistory.com/108</link>
      <description>&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;20만 건 이상의 데이터가 존재하는 테이블이었고, 컬럼을 추가한 다음 추가된 컬럼을 여러 조건에 따라&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;처음엔 쿼리를 바로 짠 다음 일단 돌렸는데.. 1시간 18분이 걸렸다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pk로 검색했는데 속도가 이상하다고 느꼈고, 처음으로 실행계획을 통해 확인을 해왔는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;type이 ALL로 풀스캔을 하고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건을 변경하여 인덱스를 타도록 수정하였고, 결과는 1시간 18분이 걸리던 업데이트가 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;지금까진 실행계획을 알고만 있고, jpa로 짜면서 사용할 기회(?), 생각이 별로 없었는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 기회를 통해 실행계획을 왜 사용하는지도 알았고, 인덱스가 왜 중요한지도 뼈저리게 느꼈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;좋은 경험이었다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행계획의 분석 내용은, 잘 정리된 블로그가 있길래 링크를 남겨놓고 필요할 때마다 봐야겠당..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jeong-pro.tistory.com/243&quot;&gt;https://jeong-pro.tistory.com/243&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1666679560393&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;MySQL 실행 계획(좋은 쿼리는 못 만들어도 뭐같은 쿼리는 만들지 말아야지)&quot; data-og-description=&quot;DB의 꽃 옵티마이저의 실행 계획 수립 RDBMS에서 가장 복잡하면서 가장 중요한 것은 옵티마이저(Optimizer)가 쿼리를 어떻게 실행할지 실행 계획을 결정하는 부분이다. 똑같은 쿼리라 할지라도 다양&quot; data-og-host=&quot;jeong-pro.tistory.com&quot; data-og-source-url=&quot;https://jeong-pro.tistory.com/243&quot; data-og-url=&quot;https://jeong-pro.tistory.com/243&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b44HYK/hyQhHCVcqr/CBRMBjW72hXmaCdCg9mcik/img.png?width=800&amp;amp;height=416&amp;amp;face=0_0_800_416,https://scrap.kakaocdn.net/dn/cV3j7b/hyQhBCHPHJ/jBkbZLZqRfzQN6jglkP7MK/img.png?width=800&amp;amp;height=416&amp;amp;face=0_0_800_416,https://scrap.kakaocdn.net/dn/hsDPV/hyQlAvmhIn/LPxR1ScfWZfuOtSKkod8Z1/img.png?width=1373&amp;amp;height=714&amp;amp;face=0_0_1373_714&quot;&gt;&lt;a href=&quot;https://jeong-pro.tistory.com/243&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://jeong-pro.tistory.com/243&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b44HYK/hyQhHCVcqr/CBRMBjW72hXmaCdCg9mcik/img.png?width=800&amp;amp;height=416&amp;amp;face=0_0_800_416,https://scrap.kakaocdn.net/dn/cV3j7b/hyQhBCHPHJ/jBkbZLZqRfzQN6jglkP7MK/img.png?width=800&amp;amp;height=416&amp;amp;face=0_0_800_416,https://scrap.kakaocdn.net/dn/hsDPV/hyQlAvmhIn/LPxR1ScfWZfuOtSKkod8Z1/img.png?width=1373&amp;amp;height=714&amp;amp;face=0_0_1373_714');&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;MySQL 실행 계획(좋은 쿼리는 못 만들어도 뭐같은 쿼리는 만들지 말아야지)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;DB의 꽃 옵티마이저의 실행 계획 수립 RDBMS에서 가장 복잡하면서 가장 중요한 것은 옵티마이저(Optimizer)가 쿼리를 어떻게 실행할지 실행 계획을 결정하는 부분이다. 똑같은 쿼리라 할지라도 다양&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;jeong-pro.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>HisStory</category>
      <category>실행계획</category>
      <category>인덱스</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/108</guid>
      <comments>https://kdhyo98.tistory.com/108#entry108comment</comments>
      <pubDate>Thu, 27 Oct 2022 23:02:14 +0900</pubDate>
    </item>
    <item>
      <title>[Error] Invalid character found in method name.HTTP method names must be tokens</title>
      <link>https://kdhyo98.tistory.com/106</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;  서론&lt;/b&gt;&lt;/span&gt;&lt;/h2&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;보내는 쪽 에러&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; font-size: 16px; letter-spacing: 0px;&quot;&gt;Unsupported or unrecognized SSL message&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; font-size: 16px; letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;받는 쪽 에러&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Invalid character found in method name[~~].HTTP method names must be tokens&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;원인&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;https 호출이 가능하지 않는 곳에 https를 호출한 경우&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;해결방법&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span style=&quot;color: #000000;&quot;&gt;호출 url을 https -&amp;gt; http 로 호출하면 된다.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;  결론&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;파파고, 구글 없이 개발 모태&lt;/span&gt;&lt;/p&gt;</description>
      <category>JVM/Spring</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/106</guid>
      <comments>https://kdhyo98.tistory.com/106#entry106comment</comments>
      <pubDate>Fri, 21 Oct 2022 18:03:13 +0900</pubDate>
    </item>
    <item>
      <title>9월 핑계, 10월 다짐</title>
      <link>https://kdhyo98.tistory.com/105</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;205&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccQ7QL/btrOlg2hXzb/PRZMFzkXMfKjeyiKF88Yfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccQ7QL/btrOlg2hXzb/PRZMFzkXMfKjeyiKF88Yfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccQ7QL/btrOlg2hXzb/PRZMFzkXMfKjeyiKF88Yfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccQ7QL%2FbtrOlg2hXzb%2FPRZMFzkXMfKjeyiKF88Yfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;205&quot; height=&quot;322&quot; data-origin-width=&quot;205&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;9월은 면접을 준비하고, 면접을 보러 다니느라 블로그 글을 코틀린 공부 시작한다는 히스토리 글밖에 작성하지 않았지만,&lt;br /&gt;이전에 작성했던 글들을 많은 분이 찾아주셨고, 이전에 비해 댓글도 한 두 분씩 달아주셔서 감격이었다..&lt;br /&gt;&lt;br /&gt;면접을 준비하고, 면접을 보고, 면접 회고를 하고, 회사에 합격하고, 여행을 가고, 뒤늦은 코로나에 걸리고..&lt;br /&gt;이런저런 핑곗거리들로 인해 글을 작성하지 못했지만, 10월에는 좀 더 열심히 공부한 내용을 정리해봐야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;물론 학습이 1순위!&lt;/b&gt;&lt;br /&gt;시간이&amp;nbsp;된다면&amp;nbsp;첫&amp;nbsp;회사&amp;nbsp;퇴사&amp;nbsp;여정&amp;nbsp;및&amp;nbsp;6개월간&amp;nbsp;F-Lab&amp;nbsp;관련&amp;nbsp;회고도&amp;nbsp;작성하도록&amp;nbsp;노력해야지..!&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>HisStory</category>
      <category>핑계</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/105</guid>
      <comments>https://kdhyo98.tistory.com/105#entry105comment</comments>
      <pubDate>Wed, 12 Oct 2022 00:22:39 +0900</pubDate>
    </item>
    <item>
      <title>[Kotlin] 코틀린 학습 시작!</title>
      <link>https://kdhyo98.tistory.com/104</link>
      <description>&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;취업을 준비하고, 회사 채용공고를 보면서 가장 많이 느껴진 부분은 이제 Java가 아닌 Kotlin을 정말 많이 사용하고 있다는 걸 느꼈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇게 생각한 이유는 아무래도 대부분의 회사에서 자격요건에 Java만을 표기하기 보다는 Kotlin을 곁들인 경우가 많았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 지금까지 내 주위에서 Kotlin을 써본 사람들 모두 입을 모아 이렇게 말한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&quot;자바로 돌아가기 싫다.&quot;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모두 코틀린의 장점으로 무조건 나오는 말은, Java에 비해 매우 간결하고, Java와 호환이 되며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 &lt;b&gt;Null 처리에 대해서 아주아주 칭찬이 많았다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜 어떻게 Java를 대체하려고 웅성웅성인지 이제 너무 궁금해서 한 번 공부해봐야겠다!&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;696&quot; data-origin-height=&quot;139&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ybrBa/btrLGLWtz9o/mUKUaQIwIamNvYXA4gfEN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ybrBa/btrLGLWtz9o/mUKUaQIwIamNvYXA4gfEN1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ybrBa/btrLGLWtz9o/mUKUaQIwIamNvYXA4gfEN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FybrBa%2FbtrLGLWtz9o%2FmUKUaQIwIamNvYXA4gfEN1%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;106&quot; data-origin-width=&quot;696&quot; data-origin-height=&quot;139&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;427&quot; data-origin-height=&quot;93&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cq99Gc/btrLE9qeaJy/72odpo75oiw77GXkWi7Kkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cq99Gc/btrLE9qeaJy/72odpo75oiw77GXkWi7Kkk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cq99Gc/btrLE9qeaJy/72odpo75oiw77GXkWi7Kkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcq99Gc%2FbtrLE9qeaJy%2F72odpo75oiw77GXkWi7Kkk%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;363&quot; height=&quot;79&quot; data-origin-width=&quot;427&quot; data-origin-height=&quot;93&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;439&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/btw4In/btrLDRj1U4F/Si0e7B24c14POoaWF7ZzA0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/btw4In/btrLDRj1U4F/Si0e7B24c14POoaWF7ZzA0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/btw4In/btrLDRj1U4F/Si0e7B24c14POoaWF7ZzA0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbtw4In%2FbtrLDRj1U4F%2FSi0e7B24c14POoaWF7ZzA0%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;266&quot; height=&quot;159&quot; data-origin-width=&quot;439&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>JVM/Kotlin</category>
      <category>Kotlin</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/104</guid>
      <comments>https://kdhyo98.tistory.com/104#entry104comment</comments>
      <pubDate>Thu, 8 Sep 2022 00:30:17 +0900</pubDate>
    </item>
    <item>
      <title>[OS] 스레드 종류 알아보기  - 하드웨어, OS, 커널, 유저, 그린 ...</title>
      <link>https://kdhyo98.tistory.com/103</link>
      <description>&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;java에서 사용하는 스레드라는 용어와 하드웨어에서 사용하는 스레드 그 외에도 커널 스레드..&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;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=vorIqiLM7jc&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/9fNjQ/hyPBVHizhy/EHYT6Z1pK67hk92YPD6jAk/img.jpg?width=1280&amp;amp;height=720&amp;amp;face=0_0_1280_720&quot; data-video-width=&quot;860&quot; data-video-height=&quot;484&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;484&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;iframe src=&quot;https://www.youtube.com/embed/vorIqiLM7jc&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;220&quot; data-origin-height=&quot;174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qpwi5/btrKMouWrNr/KUnC385ZG2FiWUhWQ7wKCk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qpwi5/btrKMouWrNr/KUnC385ZG2FiWUhWQ7wKCk/img.png&quot; data-alt=&quot;OS 구성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qpwi5/btrKMouWrNr/KUnC385ZG2FiWUhWQ7wKCk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fqpwi5%2FbtrKMouWrNr%2FKUnC385ZG2FiWUhWQ7wKCk%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;276&quot; height=&quot;218&quot; data-origin-width=&quot;220&quot; data-origin-height=&quot;174&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;OS 구성&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Applications&lt;/b&gt; - 사용자의 프로그램들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Kernel&lt;/b&gt; - OS (Windows, Linux, MacOS...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CPU, Memory, Devices&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Hardware Thread&lt;/b&gt;&lt;/h3&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;636&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pxQav/btrKGP12xGY/8j28Ni32309CXGDIBXYG81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pxQav/btrKGP12xGY/8j28Ni32309CXGDIBXYG81/img.png&quot; data-alt=&quot;인텔 코어i5-10세대 10400&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pxQav/btrKGP12xGY/8j28Ni32309CXGDIBXYG81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpxQav%2FbtrKGP12xGY%2F8j28Ni32309CXGDIBXYG81%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;636&quot; height=&quot;259&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인텔 코어i5-10세대 10400&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인텔의 CPU를 보시면, 6개의 Core와 12개의 thread가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Core는 물리적인 연산장치이고, thread는 한 코어에서 코어의 작업을 극대화하기 위해서&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;b&gt;여기서 말하는 스레드가 바로 Hardware Thread&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;OS는 논리적인 스레드를 코어로 인식해서 윈도우의 작업 관리자를 켜게 되면 12개의 Core가 있다고 나오게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 12개의 코어가 있다고 인식하고 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;core와 hardware thread에 대해서는 &lt;a href=&quot;https://kdhyo98.tistory.com/102&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;이전 글&lt;/a&gt;을 보시면 조금 더 이해에 도움이 될 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OS Thread (or Kernel Thread)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;커널에 대해서 간단하게 설명하고 넘어가겠습니다.&lt;/p&gt;
&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;커널(Kernel)&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OS Thread&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;CPU에서 실제로 실행되는 단위&lt;/li&gt;
&lt;li&gt;결국 CPU 스케줄링의 단위를 의미&lt;/li&gt;
&lt;li&gt;OS 스레드의 컨텍스트 스위칭은 커널이 개입 -&amp;gt; 컨텍스트 스위칭에 따른 비용이 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OS 스레드의 다른 용어&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;커널 스레드 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;*&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;커널-레벨 스레드&lt;/li&gt;
&lt;li&gt;OS-레벨 스레드&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Kernel Thread&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문서에 따라서 OS 커널을 수행하는 스레드라고 해석을 하는 글도 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OS 스레드와 동일한 의미로 사용되기도 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;User Thread&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;유저 레벨 스레드로 불리기도 함&lt;/li&gt;
&lt;li&gt;스레드 개념을 프로그래밍 레벨에서 '추상화'한 것&lt;/li&gt;
&lt;li&gt;유저 스레드가 CPU에서 실행되려면 반드시 OS 스레드와 연결되어야 한다.&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;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;추상화&lt;/b&gt;&lt;/span&gt;'라는 점입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바의 클래스로 예를 들면 한 클래스의 main 클래스가 실행될 때 실행되는 단위를 '&lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;유저 스레드&lt;/span&gt;&lt;/b&gt;'라고 볼 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특징에서도 적었다시피&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;유저 스레드는 실행되기 위해서는 반드시 OS 스레드와 연결&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;그 이유는, OS 스레드에서도 설명드렸다시피 &lt;b&gt;CPU에서 실행되는 단위는 OS 스레드&lt;/b&gt;이기 때문이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 유저 스레드는 반드시 OS 스레드와 연결이 되어야 하고, 그 후에 OS 스레드가 CPU에서 실행이 됩니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그렇다면, User Thread와 OS Thread를 어떻게 연결시킬까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3가지 방법이 있습니다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;One-to-One Model&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;494&quot; data-origin-height=&quot;187&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wCSZF/btrKHu4aBig/Qynk5b8Erk682a6zXoZ7xk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wCSZF/btrKHu4aBig/Qynk5b8Erk682a6zXoZ7xk/img.jpg&quot; data-alt=&quot;One-to-One&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wCSZF/btrKHu4aBig/Qynk5b8Erk682a6zXoZ7xk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwCSZF%2FbtrKHu4aBig%2FQynk5b8Erk682a6zXoZ7xk%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;494&quot; height=&quot;187&quot; data-origin-width=&quot;494&quot; data-origin-height=&quot;187&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;One-to-One&lt;/figcaption&gt;
&lt;/figure&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:1 관계로 User Thread와 Kernel Thread(or OS Thread) 연결&lt;/li&gt;
&lt;li&gt;스레드 관리를 Kernel(OS)에 위임&lt;/li&gt;
&lt;li&gt;스케줄링도 커널에서 수행&lt;/li&gt;
&lt;li&gt;CPU Thread에 매핑을 잘 시켜주기 때문에 멀티코어를 활용&lt;/li&gt;
&lt;li&gt;한 스레드가 Block이 돼도 다른 스레드는 정상 동작&lt;/li&gt;
&lt;li&gt;경쟁상태(race condition) 발생 가능성&lt;/li&gt;
&lt;li&gt;자바 1.2 이후부터 사용 중인 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Many-to-One Model&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;403&quot; data-origin-height=&quot;398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/I2B1I/btrKHw8Sv4S/bUycDI3CRJqLYKI6K3F4Dk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/I2B1I/btrKHw8Sv4S/bUycDI3CRJqLYKI6K3F4Dk/img.jpg&quot; data-alt=&quot;Many-to-One&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/I2B1I/btrKHw8Sv4S/bUycDI3CRJqLYKI6K3F4Dk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FI2B1I%2FbtrKHw8Sv4S%2FbUycDI3CRJqLYKI6K3F4Dk%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;403&quot; height=&quot;398&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;398&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Many-to-One&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;M:1 관계로 User Thread와 Kernel Thread(or OS Thread) 연결&lt;/li&gt;
&lt;li&gt;커널 개입 없이 유저 스레드끼리의 스위칭이 발생하기 때문에 one-to-one 모델보다 빠르다.&lt;/li&gt;
&lt;li&gt;경쟁상태(race condition) 발생 가능성이 적다.&lt;/li&gt;
&lt;li&gt;결국 실제로 동작하는 건 하나의 Kernel Thread이기 때문에 멀티코어를 활용하지 못한다.&lt;/li&gt;
&lt;li&gt;한 스레드가 Block I/O가 발생하면 모든 스레드들이 Block이 발생한다.&lt;/li&gt;
&lt;li&gt;Block 방지를 위해 non Block I/O 방식을 진행한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Many-to-Many Model&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;469&quot; data-origin-height=&quot;399&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIFsrB/btrKLhbHCPZ/x9amzZShNkUa1pDr6uFlo0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIFsrB/btrKLhbHCPZ/x9amzZShNkUa1pDr6uFlo0/img.jpg&quot; data-alt=&quot;Many-to-Many&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIFsrB/btrKLhbHCPZ/x9amzZShNkUa1pDr6uFlo0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIFsrB%2FbtrKLhbHCPZ%2Fx9amzZShNkUa1pDr6uFlo0%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;469&quot; height=&quot;399&quot; data-origin-width=&quot;469&quot; data-origin-height=&quot;399&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Many-to-Many&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;M:N 관계로 User Thread와&amp;nbsp;Kernel Thread(or OS Thread) 연결&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Two-Level Model&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;483&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Qjt5Y/btrKQSbav5h/L1Ld5KbKoKHnvA8m19pgn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Qjt5Y/btrKQSbav5h/L1Ld5KbKoKHnvA8m19pgn1/img.png&quot; data-alt=&quot;Two-level&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Qjt5Y/btrKQSbav5h/L1Ld5KbKoKHnvA8m19pgn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQjt5Y%2FbtrKQSbav5h%2FL1Ld5KbKoKHnvA8m19pgn1%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;483&quot; height=&quot;328&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Two-level&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Many-to-Many와 One-to-One 모델을 합쳐 보완된 모델&lt;/li&gt;
&lt;li&gt;중요한 작업은 One-to-One 구조로 처리&lt;/li&gt;
&lt;li&gt;나머지 작업은 Many-to-Many 구조로 처리&lt;/li&gt;
&lt;li&gt;혹시나 있을 중요한 작업에서의 기다림 현상을 단축&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;문서에 따른 유저 스레드&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저 스레드를 지칭하는 건 문서에 따라 다를 수가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떠한 기술 문서에서는 One-to-One 모델을 제외한 모델들을 유저 스레드로 지칭하고는 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 os와 독립적으로 유저 레벨에서 스케줄링되는 스레드를 부르기 위해서라고 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Green Thread&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;자바 1.2 이전 버전에서 사용&lt;/li&gt;
&lt;li&gt;Many-to-One 모델을 사용&lt;/li&gt;
&lt;li&gt;위에서 설명한 OS 스레드와 독립적으로 동작하기 때문에 유저 스레드와 같은 의미로 사용됨&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하드웨어 스레드&amp;nbsp; &amp;nbsp;===&amp;nbsp; CPU 레벨 용어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OS 스레드&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;===&amp;nbsp; OS 레벨 용어&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;User 스레드&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ===&amp;nbsp; 프로그래밍 언어 혹은 프로그래밍 언어의 virtual machine 용어 (JVM 등)&lt;/p&gt;</description>
      <category>OS</category>
      <category>OS스레드</category>
      <category>thread</category>
      <category>User스레드</category>
      <category>스레드</category>
      <category>하드웨어스레드</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/103</guid>
      <comments>https://kdhyo98.tistory.com/103#entry103comment</comments>
      <pubDate>Mon, 29 Aug 2022 01:05:59 +0900</pubDate>
    </item>
    <item>
      <title>[OS] 하드웨어의 CPU, Core, Thread</title>
      <link>https://kdhyo98.tistory.com/102</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;  서론&lt;/span&gt;&lt;/b&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;&lt;span style=&quot;color: #333333;&quot;&gt;어느정도 알고 있다고 생각했지만, 막상 면접 질문으로 받으니 자세히 모르고 있었던 것 같아서 공부한 내용을 바탕으로 정리를 해봅니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;  본론&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;컴퓨터 구조&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;490&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oUWNx/btrKOIsI2ej/mMDJmqEgaKn0w5OKxirtKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oUWNx/btrKOIsI2ej/mMDJmqEgaKn0w5OKxirtKk/img.jpg&quot; data-alt=&quot;폰노이만 아키텍처&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oUWNx/btrKOIsI2ej/mMDJmqEgaKn0w5OKxirtKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoUWNx%2FbtrKOIsI2ej%2FmMDJmqEgaKn0w5OKxirtKk%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;561&quot; height=&quot;393&quot; data-origin-width=&quot;700&quot; data-origin-height=&quot;490&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;&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;681&quot; data-origin-height=&quot;429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dlp9IX/btrKIzcxwuv/WcI0oj9eU3kkofu0CFcAH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dlp9IX/btrKIzcxwuv/WcI0oj9eU3kkofu0CFcAH1/img.png&quot; data-alt=&quot;실행 중인 프로세스 목록&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dlp9IX/btrKIzcxwuv/WcI0oj9eU3kkofu0CFcAH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdlp9IX%2FbtrKIzcxwuv%2FWcI0oj9eU3kkofu0CFcAH1%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;282&quot; data-origin-width=&quot;681&quot; data-origin-height=&quot;429&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;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;RAM&lt;/b&gt;&lt;/span&gt;)에 각각 올라가게 되고 (이를 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;프로세스&lt;/b&gt;&lt;/span&gt;라고 부릅니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에 적재된 프로세스를 CPU(혹은 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;프로세서&lt;/b&gt;&lt;/span&gt;)에서 실행을 하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 10개도 넘는 프로그램을 한 번에 실행도 할 수 있고, 20개도!! 넘는 프로그램들을 한 번에 실행할 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 CPU는 이 많은 프로그램들을 다 병행으로 실행을 하고 있을까요??&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;CPU Core와 Thread&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/E5Xfp/btrKK8MeOuv/lWqtxkH0iZh8Se7vDLpejk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/E5Xfp/btrKK8MeOuv/lWqtxkH0iZh8Se7vDLpejk/img.png&quot; data-alt=&quot;인텔 코어i5-10세대 10400&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/E5Xfp/btrKK8MeOuv/lWqtxkH0iZh8Se7vDLpejk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FE5Xfp%2FbtrKK8MeOuv%2FlWqtxkH0iZh8Se7vDLpejk%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;636&quot; height=&quot;259&quot; data-origin-width=&quot;636&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인텔 코어i5-10세대 10400&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중앙 처리 장치 (CPU: Central Processing Unit)&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;컴퓨터에서 기억, 해석, 연산, 제어라는 4대 주요 기능을 관할하는 장치를 말한다.&lt;br /&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 style=&quot;color: #333333;&quot;&gt;흔한 인텔의 CPU 스펙입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;저희가 여기서 살펴볼 부분은 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;CORE&lt;/b&gt;&lt;/span&gt;와 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;THREADS&lt;/b&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Core&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;CPU의 부품 중 하나 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;물리적으로 CPU가 일하는 공간입니다.&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;요즘은 CPU마다 코어가 2개 이상인 멀티 코어를 통해 CPU의 성능을 높입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;듀얼코어(2코어), 쿼드코어(4코어), 헥사코어(6코어), 옥타코어(8코어) ...&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;50% 성능을 내는 싱글코어와 100%의 성능을 내는 멀티코어. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;두 개의 CPU가 있습니다.&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;&lt;span style=&quot;color: #333333;&quot;&gt;A 프로그램은 코어의 30%를 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;B 프로그램은 코어의 80%를 사용합니다.&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;이때 A프로그램은 싱글코어와 듀얼코어 모두 순조롭게 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;B프로그램은 싱글코어에서는 제대로 돌리기 힘들고, 듀얼코어에서는 돌릴 수 있어보입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;하지만, B프로그램이 싱글코어에 맞게 개발이 되었다면, 멀티코어에서 제대로 효율을 내지 못하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;결국 B프로그램 자체도 멀티코어에서 제대로된 성능을 내기 위해 개발이 되어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;이러한 방식이 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;멀티스레드 방식&lt;/b&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Thread&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;위에서 &lt;b&gt;Core는 물리적으로 구별이 되었다면, Thread는 논리적으로 구별&lt;/b&gt;이 되었다고 보면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&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;우리가 잘 알던 &lt;span style=&quot;color: #ef5369;&quot;&gt;&lt;b&gt;소프트웨어의 thread&lt;/b&gt;&lt;/span&gt;와 &lt;b&gt;&lt;span style=&quot;color: #ef5369;&quot;&gt;하드웨어의 thread&lt;/span&gt;&lt;/b&gt;를 분리해서 바라보아야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;위 &lt;b&gt;Core&lt;/b&gt;에서 설명했던 &lt;b&gt;멀티코어는 '하드웨어 관점'&lt;/b&gt;에서의 물리적인 구성 단위입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;우리가 프로그래밍할 때 보통 부르는 &lt;b&gt;멀티스레드/멀리스레딩은 '소프트웨어 관점'&lt;/b&gt;에서의 논리적 작업처리 단위입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;이 파트에서 설명하는 Thread는 '소프트웨어 관점'이 아닌 '하드웨어 관점'의 Thread&lt;/b&gt;에 대해서 설명을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;Core와 Thread&lt;/span&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;507&quot; data-origin-height=&quot;321&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c1fjTz/btrKHdg1ZzV/omOPvC0sbcwXop2INFVu7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c1fjTz/btrKHdg1ZzV/omOPvC0sbcwXop2INFVu7k/img.png&quot; data-alt=&quot;Simultaneous Multi-Threading&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c1fjTz/btrKHdg1ZzV/omOPvC0sbcwXop2INFVu7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc1fjTz%2FbtrKHdg1ZzV%2FomOPvC0sbcwXop2INFVu7k%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;507&quot; height=&quot;321&quot; data-origin-width=&quot;507&quot; data-origin-height=&quot;321&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Simultaneous Multi-Threading&lt;/figcaption&gt;
&lt;/figure&gt;
&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;&lt;span style=&quot;color: #333333;&quot;&gt;4개의 코어가 있다면 4개의 스레드가 있었던거죠.&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;동시 멀티스레딩&lt;/b&gt;&amp;nbsp;(SMT: Simultaneous Multi Threading)이라는 기술을 통해&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: #333333;&quot;&gt;AMD에서는 &lt;b&gt;SMT&lt;/b&gt;라고 부르고, 인텔에서는 &lt;b&gt;하이퍼쓰레딩&lt;/b&gt;&lt;span&gt;(HT:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;Hyper Threading)이라고 부릅니다.&lt;/span&gt;&lt;span style=&quot;color: #333333;&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개를 논리적인 2개 이상의 스레드로 실행단위를 나눌 수 있게 되었습니다.&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;b&gt;하드웨어의 스레드는 물리적인 코어의 논리적인 실행단위를 의미&lt;/b&gt;하고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &amp;nbsp; 1코어에서 하나의 프로세서가 실행된다면 어떻게 20개의 프로그램이 동시에 실행이 되는거지?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 인텔 스펙에서 보면 6코어의 12스레드를 탑재하고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국, 많아봐야 12개의 스레드에서 병렬 작업이 가능하단 소리죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 저희는 20개의 프로그램들을 동시에 켜놓고 작업을 진행하곤 할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때  &lt;b&gt;Context Switch(Context Switching)&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;CPU&lt;/b&gt;: 컴퓨터의 뇌&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Core&lt;/b&gt;: 작업하는 물리적 위치&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Thread&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=_dhLLWJNhwY&quot;&gt;https://www.youtube.com/watch?v=_dhLLWJNhwY&lt;/a&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=1grtWKqTn50&quot;&gt;https://www.youtube.com/watch?v=1grtWKqTn50&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>OS</category>
      <category>contextswitch</category>
      <category>CORE</category>
      <category>CPU</category>
      <category>thread</category>
      <category>스레드</category>
      <category>프로세스</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/102</guid>
      <comments>https://kdhyo98.tistory.com/102#entry102comment</comments>
      <pubDate>Sun, 28 Aug 2022 22:56:34 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 락(Lock) - MySQL 8.0 InnoDB</title>
      <link>https://kdhyo98.tistory.com/101</link>
      <description>&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트랜잭션을 통해 하나의 작업 단위를 묶어서 ACID 원칙을 지키기 위해 노력합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, ACID 원칙이 언제나 완벽하게 지켜지진 않습니다.&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;그렇기 때문에 ACID 원칙을 적절하게, 상황에 맞게 유지시키면서 동시성을 높일 수 있게 DB에서 기능을 제공합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 Isolation level을 통해서요! (트랜잭션에 대한 추가 설명은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://kdhyo98.tistory.com/31?category=971130&quot;&gt;이전 글&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;결국, Isolation level 별 적절한 Lock을 진행하고, 이는 DBMS마다 다릅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 MySQL InnoDB 기준으로 어떤 Lock이 있는지 알아보도록 하겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MySQL InnoDB 락(Lock)의 종류&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;락 적용 요소에 따른 분류&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Shared Locks (S)&lt;/li&gt;
&lt;li&gt;Exclusive Locks (X)&lt;/li&gt;
&lt;li&gt;Intention Locks&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;락이 적용되는 상황에 따른 분류&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Row Locks&lt;/li&gt;
&lt;li&gt;Record Locks&lt;/li&gt;
&lt;li&gt;Gap Locks&lt;/li&gt;
&lt;li&gt;Next-Key Locks&lt;/li&gt;
&lt;li&gt;Insert Intentation Locks&lt;/li&gt;
&lt;li&gt;AUTO-INC Locks&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;락 적용 요소에 따른 분류&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Shared Lock (공유 잠금)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Row Level Lock&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;특정 Row를 읽을 때 사용되므로 다른 말로 &lt;b&gt;Read Lock&lt;/b&gt; 이라고도 한다.&lt;/li&gt;
&lt;li&gt;다른 트랜잭션이 해당 row에 대해 베타 락은 획득이 불가능하지만, 공유 락은 획득이 가능하다.&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;blockquote data-ke-style=&quot;style2&quot;&gt;SELECT ... LOCK IN SHARE MODE (8.0부터는 FOR SHARE로 가능)&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Exclusive Lock (베타적 잠금)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Row Level Lock&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;특정 Row를 변경 혹은 삭제하고자 할 때 사용되므로 다른 말로 &lt;b&gt;Write Lock&lt;/b&gt; 이라고도 한다.&lt;/li&gt;
&lt;li&gt;다른 트랜잭션이 해당 row에 대해 공유 락 / 베타 락 모두 획득하지 못하도 대기하게 된다.&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;blockquote data-ke-style=&quot;style2&quot;&gt;SELECT ... FOR UPDATE&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Intention Lock (의도 잠금)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Table Level Lock&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;해당 테이블 row 중 나중에 row-level lock이 걸릴 것이라는 걸 미리 알려주기 위해 사용된다.&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;blockquote data-ke-style=&quot;style2&quot;&gt;LOCK TABLE ... READ;&lt;br /&gt;SELECT ... LOCK IN SHARE MODE&lt;/blockquote&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Intention Shared Lock (IS)이 테이블에 걸린다.&lt;/li&gt;
&lt;li&gt;row-level에 Shared Lock (S)이 걸린다.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;LOCK TABLE ... WRITE;&lt;br /&gt;SELECT ... FOR UPDATE (or INSERT, DELETE)&lt;/blockquote&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Intention Exclusive Lock (IX)이 테이블에 걸린다.&lt;/li&gt;
&lt;li&gt;row-level에 Exclusive Lock (X)이 걸린다.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IS, IX 락은 여러 트랜잭션에서 동시에 접근이 가능하다. (서로 block하지 않는다.)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;하지만 row-level의 실제 Lock(S or X)에서 접근 제어를 하게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LOCK TABLES (or ALTER TABLE, DROP TABLE) 이 실행될 때는 IS, IX를 모두 block 하는 table-level 락이 걸린다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;즉 IS, IX lock을 획득 하려는 트랜잭션은 대기 상태로 빠지게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Table-level에서 한 번, Row-level에서 한 번, 2단계(2-phase)로 Lock을 적용하는 이유는?&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;A트랜잭션에서 이미 테이블에 대해 락이 걸려있는데, B 트랜잭션에서 해당 테이블의 특정 row에 lock을 거는 것을 원천적으로 방지할 수 있다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예) row-level의 write이 일어나고 있을 때 테이블 스키마가 변경되서는 안 된다. write query의 경우 이미 IX 락을 획득한 상태이기 때문에 해당 테이블의 스키마가 변경되는 것을 막을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Share Lock, Exclusive Lock, Intention Lock 호환 표&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 93px;&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: 17px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px;&quot;&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px;&quot;&gt;&lt;b&gt;IX&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px;&quot;&gt;&lt;b&gt;S&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 17px;&quot;&gt;&lt;b&gt;IS&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;충돌&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;충돌&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;충돌&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;충돌&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;IX&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;충돌&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;호환&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;충돌&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;호환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;S&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;충돌&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;충돌&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;호환&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;호환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;IS&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;충돌&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;호환&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;호환&lt;/td&gt;
&lt;td style=&quot;width: 20%; height: 19px;&quot;&gt;호환&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;락이 적용되는 상황에 따른 분류&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Row Lock&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;테이블 row에 걸리는 Lock을 의미한다.&lt;/li&gt;
&lt;li&gt;각 row에 S-Lock, X-Lock을 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Record Lock&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;primary key, unique index로 조회해서 하나의 인덱스 레코드(=row)에만 lock을 거는 것을 의미한다.&lt;/li&gt;
&lt;li&gt;각 Index record에 S-Lock, X-Lock을 사용할 수 있다.&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예) SELECT id FROM t WHERE id = 10 LOCK IN SHARE MODE
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 쿼리를 실행하면 id=10 인 레코드에 대해 S lock이 걸린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;예) SELECT id FROM t WHERE id = 10 FOR UPDATE
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 쿼리를 실행하면 id=10인 레코드에 대해 X lock이 걸린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Gap Lock (=Range Lock)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;범위를 지정하기 위해 인덱스 레코드 사이 범위(gap)에 락을 거는 것을 의미한다.&lt;/li&gt;
&lt;li&gt;최초 레코드 이전, 마지막 레코드 이후를 가상의 인덱스 레코드로 생각해서 lock을 적용하는 것이 가능하다.&lt;/li&gt;
&lt;li&gt;Gap lock을 통해서 같은 SELECT 쿼리를 두 번 실행했을 때 다른 트랜잭션에서 데이터가 수정되었더라도 같은 결과가 리턴되는 것을 보장할 수 있다. (Phantom read 방지)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예) SELECT id FROM t WHERE id BETWEEN 10 and 20 FOR UPDATE&lt;br /&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;위 쿼리를 실행하면 id = 10~20 사이에 X lock이 걸리기 때문에 다른 트랜잭션에서 id = 15를 가지는 데이터를 INSERT 하려면 대기 상태로 빠지게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;컬럼에 대한 WHERE 절로 하나의 레코드만 추출되었을 때, Record lock과 Gap lcok 어느 것이 사용될까?
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컬럼에 unique index가 걸려있는 경우에 gap lock이 필요 없다. (record lock이 사용된다.)&lt;/li&gt;
&lt;li&gt;컬럼에 index가 걸려있지 않거나, index가 걸려 있어도 unique하지 않는다면 gap lock이 필요하다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;index가 걸려 있다면 row를 찾기 위해 스캔했던 index range에 대해서 gap lock 적용&lt;/li&gt;
&lt;li&gt;index가 걸려있지 않다면 결국 테이블 전체를 스캔해야 되기 때문에 모든 row에 대해 lock이 걸린다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Next-Key Lock&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실제 범위 지정 쿼리를 실행하면 위에서 설명한 Record Lock, Gap Lock이 복합적으로 발생하는 Lock이다.&lt;/li&gt;
&lt;li&gt;Repeatable Read인 상태에서는 phantom Read를 예방하기 위해 인덱스 scan을 하면 이 Lock이 발생한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B9PLx/btrI11vqrUA/rwRbODFh00SBlXWKtoRK8k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B9PLx/btrI11vqrUA/rwRbODFh00SBlXWKtoRK8k/img.png&quot; data-alt=&quot;SELECT * WHERE pk &amp;amp;gt; 99 FOR UPDATE 실행 시 일어나는 일들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B9PLx/btrI11vqrUA/rwRbODFh00SBlXWKtoRK8k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB9PLx%2FbtrI11vqrUA%2FrwRbODFh00SBlXWKtoRK8k%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;552&quot; height=&quot;420&quot; data-origin-width=&quot;1064&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;SELECT * WHERE pk &amp;gt; 99 FOR UPDATE 실행 시 일어나는 일들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Insert Intention Lock&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;INSERT 구문이 실행될 때 InnoDB 엔진 내부적으로 implicit(암시적)하게 획득하는 특수한 형태의 Gap Lock.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;gap lock은 일반적으로 explicit(명시적)하게 locking read를 위한 SELECT 구문이 실행될 때 발생하지만&lt;/li&gt;
&lt;li&gt;이 lock은 INSERT 시점에 implicit 하게 자동으로 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;여러 개의 트랜잭션이 gap 안의 다른 위치에 insert를 동시 수행할 때 기다릴 필요가 없도록 하는 것이 목적
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;INSERT Intention Lock들 간에는 충돌이 일어나지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; INSERT 될 row에 대해서 exclusive lock을 걸기 전에 먼저 insert intention lock을 건다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예) pk = 3, pk = 6의 레코드가 존재하는 테이블이 존재
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A트랜잭션에서 pk=5에 INSERT, B 트랜잭션에서 pk=4에 INSERT 시도
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;만약 일반적인 gap lock을 사용한다면:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A트랜잭션이 pk=5를 INSERT 하는 과정에서 pk=3~5에는 gap lock이 걸림.&lt;/li&gt;
&lt;li&gt;B트랜잭션이 pk=4에 INSERT 시도 시 pk=3~5에 gap lock이 걸려있기 때문에 A가 트랜잭션이 완전히 종료될 때까지 기다려야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;대기시간이 존재!&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Insert Intention Lock 사용 시:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A트랜잭션이 pk=5를 INSERT하는 과정에서 pk=3~5에는 insert intention lock 걸림.&lt;/li&gt;
&lt;li&gt;B트랜잭션이 pk=4에 INSERT 시도 시 pk=3~5에 insert intention lock이 걸려 있더라도 pk가 겹치지 않기 때문에 바로 진행 가능.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;대기시간 없음!&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;실제 InnoDB의 동작방식&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;AUTO-INC Lock&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AUTO_INCREMENT 컬럼의 값을 일관성을 보장하기 위해 사용하는 Lock&lt;/li&gt;
&lt;li&gt;하나의 트랜잭션이 해당 컬럼 내의 연속 숫자를 부여받기 위해서 해당 Lock을 걸고, 이로 인해 다른 트랜잭션들이 대기함으로써 순차적으로 연속 숫자를 부여받도록 해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;락으로 해결되지 않는 문제점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;락은 이처럼 장점들이 존재하지만 만능은 아닙니다.&lt;/p&gt;
&lt;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;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;A트랜잭션과 B트랜잭션이 동시에 a row를 변경할 경우&lt;br /&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A가 먼저 실행되고 B가 다음으로 실행됐다면, A에서 변경한 내용은 무시된다.&lt;/li&gt;
&lt;li&gt;예) 유저 테이블의 집 주소 칼럼에 대해 A-T은 서울시로 변경하고, B-T은 수원시로 변경할 경우 수원시로 최종 저장된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데드락이 발생할 수 있다.
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아래 예시처럼 각각의 트랜잭션이 A, B를 각각 잠그고 서로 잠근 테이블에 요청할 경우 데드락(무한대기현상)에 빠지게 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k54Uu/btrI9m6lT5g/cNb6OIN0cU3R0Jkhgn8vv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k54Uu/btrI9m6lT5g/cNb6OIN0cU3R0Jkhgn8vv1/img.png&quot; data-alt=&quot;데드락 발생 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k54Uu/btrI9m6lT5g/cNb6OIN0cU3R0Jkhgn8vv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk54Uu%2FbtrI9m6lT5g%2FcNb6OIN0cU3R0Jkhgn8vv1%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;543&quot; height=&quot;281&quot; data-origin-width=&quot;1052&quot; data-origin-height=&quot;544&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; &amp;zwj;♂️ 결론&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 DB 별로 약간씩 락이 다릅니다.&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;잘못된 부분이 있다면 댓글로 알려주시면 감사하겠습니다! (__)&lt;/p&gt;
&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dbknowledge.tistory.com/23&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dbknowledge.tistory.com/23&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://suhwan.dev/2019/06/09/transaction-isolation-level-and-lock/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://jaeseongdev.github.io/development/2021/06/16/Lock%EC%9D%98-%EC%A2%85%EB%A5%98-(Shared-Lock,-Exclusive-Lock,-Record-Lock,-Gap-Lock,-Next-key-Lock)/&quot;&gt;https://jaeseongdev.github.io/development/2021/06/16/Lock%EC%9D%98-%EC%A2%85%EB%A5%98-(Shared-Lock,-Exclusive-Lock,-Record-Lock,-Gap-Lock,-Next-key-Lock)/&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://taes-k.github.io/2020/05/17/mysql-transaction-lock/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://taes-k.github.io/2020/05/17/mysql-transaction-lock/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@soyeon207/DB-Lock-%EC%B4%9D%EC%A0%95%EB%A6%AC-1-InnoDB-%EC%9D%98-Lock#lock-%EC%9D%B4-%ED%95%B4%EC%A0%9C%EB%90%98%EB%8A%94-%ED%83%80%EC%9D%B4%EB%B0%8D&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@soyeon207/DB-Lock-%EC%B4%9D%EC%A0%95%EB%A6%AC-1-InnoDB-%EC%9D%98-Lock#lock-%EC%9D%B4-%ED%95%B4%EC%A0%9C%EB%90%98%EB%8A%94-%ED%83%80%EC%9D%B4%EB%B0%8D&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.letmecompile.com/mysql-innodb-lock-deadlock/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.letmecompile.com/mysql-innodb-lock-deadlock/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-predicate-locks&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-predicate-locks&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://krksap.tistory.com/541&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://krksap.tistory.com/541&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DataBase</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/101</guid>
      <comments>https://kdhyo98.tistory.com/101#entry101comment</comments>
      <pubDate>Sun, 7 Aug 2022 20:14:06 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 상황에 맞는 Unique ID 생성 방법</title>
      <link>https://kdhyo98.tistory.com/100</link>
      <description>&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 PK가 있을 수도 있고, 쿠폰번호가 있을 수도 있고, 결제번호가 될수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니크한 값을 만드는 방식들은 어떤 게 있고, 어떤 상황에 어떤 방식을 사용하는 게 좋을지 정리를 해보겠습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;먼저 3가지의 유니크 ID를 생성 종류에 대해서 알아보고 각각 어떨 때 적용하면 좋을지에 대해 개인적인 생각을 적어보겠습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. RDBMS 의 Auto Increment&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;디비에서 자동으로 만들어주는 자동증가 값으로 PK 용도로 사용된다.&lt;/p&gt;
&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;구현이 매우 간단하다.&lt;/li&gt;
&lt;li&gt;숫자 증가기 때문에 재정렬이 필요 없다.&lt;/li&gt;
&lt;li&gt;순서가 보장된다.&lt;/li&gt;
&lt;li&gt;물리삭제가 되지 않는 특성의 테이블의 경우 마지막 row id 값만으로도 대략 테이블 데이터의 수를 파악할 수 있다.&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;b&gt;단점&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대의 DB에서 생성하기 때문에 스케일 아웃을 통한 확장을 할 수 없다.&lt;/li&gt;
&lt;li&gt;따라서 처리 성능을 확장하기 어렵다.&lt;/li&gt;
&lt;li&gt;insert 후에야 PK값이 생성되기 때문에 디비에 저장되기 전에는 id를 알 수 없다. (디비에 디펜던시가 생기게 된다.)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. UUID&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GUID (Globally Unique IDentifier)라고도 하는 UUID (Universally Unique IDentifier)는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 상에서 고유성이 보장되는 ID를 만들기 위한 표준 규약이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;128 Bit 데이터로 표현한다.&lt;/li&gt;
&lt;li&gt;5개의 그룹으로 8-4-4-4-12 형식으로 총 36자 (32개의 영숫자 및 4개의 하이픈)&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;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;831&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l9BGp/btrIK726F3P/dpeux9J2k6R9neVsYV1r40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l9BGp/btrIK726F3P/dpeux9J2k6R9neVsYV1r40/img.png&quot; data-alt=&quot;UUID&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l9BGp/btrIK726F3P/dpeux9J2k6R9neVsYV1r40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl9BGp%2FbtrIK726F3P%2Fdpeux9J2k6R9neVsYV1r40%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;831&quot; height=&quot;528&quot; data-origin-width=&quot;831&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;UUID&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 121px;&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: 35.4263%; text-align: center; height: 20px;&quot;&gt;이름&lt;/td&gt;
&lt;td style=&quot;width: 11.7054%; text-align: center; height: 20px;&quot;&gt;길이 (Bit)&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%; text-align: center; height: 20px;&quot;&gt;내용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 35.4263%; height: 20px;&quot;&gt;&amp;nbsp;time_low&lt;/td&gt;
&lt;td style=&quot;width: 11.7054%; height: 20px;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%; height: 20px;&quot;&gt;시간의 low 32비트를 부여하는 정수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 35.4263%; height: 20px;&quot;&gt;time_mid&lt;/td&gt;
&lt;td style=&quot;width: 11.7054%; height: 20px;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%; height: 20px;&quot;&gt;시간의 middle 16비트를 부여하는 정수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 35.4263%; height: 21px;&quot;&gt;time_hi_and_version&lt;/td&gt;
&lt;td style=&quot;width: 11.7054%; height: 21px;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%; height: 21px;&quot;&gt;최상위 비트에서 4비트 &quot;version&quot;, 그리고 시간의 high 12비트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 35.4263%; height: 20px;&quot;&gt;clock_seq_hi_and_res clock_seq_low&lt;/td&gt;
&lt;td style=&quot;width: 11.7054%; height: 20px;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%; height: 20px;&quot;&gt;최상위 비트에서 1-3비트, 그리고 13-15비트 클럭 시퀀스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 35.4263%; height: 20px;&quot;&gt;node&lt;/td&gt;
&lt;td style=&quot;width: 11.7054%; height: 20px;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 52.8682%; height: 20px;&quot;&gt;48비트 노드 ID&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&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;멀티환경에서도 병렬로 동작하기 때문에 유일한 ID를 생성할 수 있다.&lt;/li&gt;
&lt;li&gt;자바에서 UUID를 제공해주기 때문에 쉽게 사용할 수 있다.&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;b&gt;단점&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;128bit로 너무 길고, 데이터베이스에서 많은 공간을 차지하므로 인덱스 구축에 적합하지 않다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. SnowFlake&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Twitter에서 OSS로 공개하고 있는 ID 생성기 (현재 초기버전은 종료되고 별도 라이브러리로 제공되고 있음)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/twitter/snowflake&quot;&gt;https://github.com/twitter/snowflake&lt;/a&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Time-base로 한 ID&lt;/li&gt;
&lt;li&gt;64 Bit의 Long 값으로 데이터로 표현한다.&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;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;440&quot; data-origin-height=&quot;126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmyBG7/btrIOQ7ztvG/xjcKUOlvwkEXRrQme4PZmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmyBG7/btrIOQ7ztvG/xjcKUOlvwkEXRrQme4PZmk/img.png&quot; data-alt=&quot;snowFlake&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmyBG7/btrIOQ7ztvG/xjcKUOlvwkEXRrQme4PZmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmyBG7%2FbtrIOQ7ztvG%2FxjcKUOlvwkEXRrQme4PZmk%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;440&quot; height=&quot;126&quot; data-origin-width=&quot;440&quot; data-origin-height=&quot;126&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;snowFlake&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 70px;&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: 33.3333%; text-align: center; height: 20px;&quot;&gt;이름&lt;/td&gt;
&lt;td style=&quot;width: 13.5658%; text-align: center; height: 20px;&quot;&gt;길이(Bit)&lt;/td&gt;
&lt;td style=&quot;width: 53.1008%; text-align: center; height: 20px;&quot;&gt;내용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 14px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 14px;&quot;&gt;timestamp&lt;/td&gt;
&lt;td style=&quot;width: 13.5658%; height: 14px;&quot;&gt;41&lt;/td&gt;
&lt;td style=&quot;width: 53.1008%; height: 14px;&quot;&gt;&lt;span&gt;epoch time으로 millisec 혹은 sec 단위&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;instance&lt;/td&gt;
&lt;td style=&quot;width: 13.5658%; height: 18px;&quot;&gt;10&lt;/td&gt;
&lt;td style=&quot;width: 53.1008%; height: 18px;&quot;&gt;Machine ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 18px;&quot;&gt;sequence&lt;/td&gt;
&lt;td style=&quot;width: 13.5658%; height: 18px;&quot;&gt;12&lt;/td&gt;
&lt;td style=&quot;width: 53.1008%; height: 18px;&quot;&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;밀리초&lt;span&gt; &lt;/span&gt;이내에&lt;span&gt; &lt;/span&gt;동시에&lt;span&gt; &lt;/span&gt;생성된&lt;span&gt;&amp;nbsp;&lt;/span&gt;일련번호 같은 시간, 같은 머신에서 중복되는는 것을 방지&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&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;멀티 환경에서도 병렬로 동작하기 때문에 유일한 ID를 생성할 수 있다.&lt;/li&gt;
&lt;li&gt;1초 당 생성 가능한 개수가 4,096,000 개로 매우 빠른 속도로 생성이 가능하다.&lt;/li&gt;
&lt;li&gt;timestamp 값을 기초로 하기 때문에 ID 정렬이 가능하다.&lt;/li&gt;
&lt;li&gt;ID 값에서 ID 생성시의 timestamp 값을 복원할 수 있다.&lt;/li&gt;
&lt;li&gt;정수 열 압축을 이용한 효율적인 정보 압축이 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점&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;OS의 시각 차이에 약하다.&lt;/li&gt;
&lt;li&gt;시간이 잘못 역전될 경우 고장이 발생할 수도 있고, 재가동 후 시간이 초과될 수 있다.&lt;/li&gt;
&lt;li&gt;ID 채번 시에 snowflake 서버에 thrift 경유로 접속하도록 되어 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  어떨 때 뭘 쓸까?&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;테이블의 PK&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PK는 Auto Increment를 사용하는 게 가장 좋다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;샤딩이 적용된 프로젝트의 경우에는 어쩔 수 없이 다른 방법을 써야겠지만, 아닌 경우에는 장점이 너무 많다고 느껴집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;db에서 알아서 최적화를 잘 해주기 때문에 성능도 크게 신경 쓸 필요가 없고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자동증가로 인해 정렬도 신경 쓸 필요가 없고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;페이징을 할 때에도 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;다만, 자동증가로 인한 단점으로는 외부에 노출됐을 경우입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 유저의 pk 값으로 유저의 정보를 조회하는 서비스가 있다고 가정을 해봅시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저의 pk값이 41일 경우 마음먹고 악용한다고 한다면, 42 43 .. 등 다른 값을 날려서 다른 사용자의 정보를 볼 수 있게 될 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 pk값을 외부로 노출하게 되면 사용자에게 악용될 여지를 남겨두는 것이라 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 때 UUID나 snowflake 를 사용한다면 사용자가 다음 값을 추측하기 어려워집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다고, PK값을 Auto Increment 대신 UUID나 snowflake를 사용하는 건 위에 말했던&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Auto Increment의 장점을 다 버리는 것이기 때문에 그것보단 별도 컬럼을 추가해서 외부 노출용 ID를 만드는 게 좋다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;쿠폰&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의미 있는 값(예를 들어 중복사용이 가능한 이벤트 쿠폰)을 직접 기입할 수도 있고, 유니크한 값을 만들 수도 있는 쿠폰의 경우&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유니크한 값을 만들 때에는 UUID나 snowflake를 적용해보는 것을 고민해볼 수 있을 것 같습니다.&lt;/p&gt;
&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;그럴 땐 UUID와 snowflake의 구성을 보고 본인 서비스에 맞는 유니크한 값 생성하는 로직을 만들어보면 될 것 같습니다.&lt;/p&gt;
&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 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;CGV의 경우 0041-0802-xxxx-xxx 이러한 번호를 사용 중입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞의 4자리는 상영관 고유번호, 두번 째 4자리는 예매 날짜&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3 - 4 번째는 시퀀스로 판단됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 상황에 따라 직접 고유번호를 만들어서 사용하는 것도 생각해보면 좋습니다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;UUID와 snowflake를 활용하면 String이나 Long타입의 유니크한 값을 쉽게 만들 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 본인 도메인과 현 상황에 맞는 유니크한 값을 직접 만들고 싶을 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럴 때에는 다른 GUID는 어떤 식으로 만드는지에 대한 구성을 살펴보고, 영감을 얻는 게 좋습니다.&lt;/p&gt;
&lt;p data-ke-size=&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;snowflake에서 영감을 받아 만든 generate id 가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 식으로 만들었는지 참고하면 좋을 것 같습니다. (&lt;a href=&quot;https://github.com/callicoder/java-snowflake&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;링크&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.slideshare.net/jacking/twitter-snowflake&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.slideshare.net/jacking/twitter-snowflake&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.huskyhoochu.com/what-is-uuid/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.huskyhoochu.com/what-is-uuid/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://darkstart.tistory.com/147&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://darkstart.tistory.com/147&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://howtodoinjava.com/java/java-uuid/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://howtodoinjava.com/java/java-uuid/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developpaper.com/talking-about-distributed-unique-id-this-article-is-very-real/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://developpaper.com/talking-about-distributed-unique-id-this-article-is-very-real/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.baeldung.com/java-generate-alphanumeric-uuid&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.baeldung.com/java-generate-alphanumeric-uuid&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;baeldung.com/java-uuid&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>DataBase</category>
      <category>GUID</category>
      <category>PK</category>
      <category>snowflake</category>
      <category>UUID</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/100</guid>
      <comments>https://kdhyo98.tistory.com/100#entry100comment</comments>
      <pubDate>Tue, 2 Aug 2022 19:51:24 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] How to change the CamelCase to SnakeCase  when i use POST form-url-encoded in Spring Cloud feign Client</title>
      <link>https://kdhyo98.tistory.com/99</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  서론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1tIUr/btrHd1czc45/3bqELKkr0lCDkoMObX8qTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1tIUr/btrHd1czc45/3bqELKkr0lCDkoMObX8qTk/img.png&quot; data-alt=&quot;&amp;amp;lt;사진1&amp;amp;gt; 두둥 넷플릭스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1tIUr/btrHd1czc45/3bqELKkr0lCDkoMObX8qTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1tIUr%2FbtrHd1czc45%2F3bqELKkr0lCDkoMObX8qTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;433&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진1&amp;gt; 두둥 넷플릭스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KakaoPay API 통신을 feign client를 통해 진행하는 중&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;POST로 form-urlencoded 타입으로 전송해야 하는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@JsonNaming 애노테이션이 form-urlencoded 타입에서는 정상적으로 작동하지 않아 해결한 내용을 정리해봅니다.. ㅜ&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;이 글은, feign Client를 통해 요청을 보내는 방법을 정리합니다.&lt;br /&gt;본인의 서버 컨트롤러로 받는 방법으로는&amp;nbsp;&lt;a href=&quot;https://github.com/spring-projects/spring-framework/issues/18012&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;&amp;nbsp;에서 많은 해결책이 나와있습니다.&amp;nbsp;참고 바랍니다!!&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;FeignClient&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1657720254983&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@FeignClient(name = &quot;kakaoPay&quot;, url = &quot;https://kapi.kakao.com/v1&quot;, path = &quot;/payment&quot;, configuration = CoreFeignConfiguration.class)
public interface KakaoPayClient {

	@RequestMapping(value = &quot;/ready&quot;, method = POST,
		consumes = APPLICATION_FORM_URLENCODED_VALUE)
	@Headers(&quot;Content-Type: application/x-www-form-urlencoded;charset=utf-8&quot;)
	KakaoPayReadyResponse ready(@RequestHeader(value = &quot;Authorization&quot;) String authorization, KakaoPayReadyRequest request);

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;기존 방식&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1657720216138&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class)
@JsonInclude(Include.NON_NULL)
public class SnakeCaseStrategy {

}

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class KakaoPayReadyRequest extends SnakeCaseStrategy {

	// 가맹점 코드
	@NotEmpty
	private String cid = &quot;TC0ONETIME&quot;;

	// 가맹점 코드 인증키
	private String cidSecret;
    
    ...
    
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KakaoPayReadyRequest 객체를 통해 전송할 때 @JsonNaming을 사용해서 보내려 했지만 변경이 안됐습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Json 타입으로 보낼 때에만 정상적으로 작동하더군요..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;이렇게 하면 됩니다.&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1657720457117&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class CoreFeignConfiguration {

	...
    
	@Bean
	Encoder formEncoder() {
		return new feign.form.FormEncoder();
	}

}

public class KakaoPayReadyRequest {

	// 가맹점 코드
	@NotEmpty
	private String cid = &quot;TC0ONETIME&quot;;

	// 가맹점 코드 인증키
	@feign.form.FormProperty(&quot;cid_secret&quot;)
	private String cidSecret;

	// 가맹점 주문번호
	@NotEmpty
	@feign.form.FormProperty(&quot;partner_order_id&quot;)
	private String partnerOrderId;
    
    ...
}&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;Feign Client에서 사용하는 Configuration에 formEncoder() 메서드를 빈으로 등록 후에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;@feign. form.FormProperty(&quot;...&quot;)를 모든 프로퍼티에 붙여 변경하는 방법을 취했습니다.&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;803&quot; data-origin-height=&quot;20&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MehVf/btrHd2WSkzl/WKo79M1hZ4yXRe0z6EeKvK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MehVf/btrHd2WSkzl/WKo79M1hZ4yXRe0z6EeKvK/img.png&quot; data-alt=&quot;&amp;amp;lt;사진2&amp;amp;gt; 정상 변경&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MehVf/btrHd2WSkzl/WKo79M1hZ4yXRe0z6EeKvK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMehVf%2FbtrHd2WSkzl%2FWKo79M1hZ4yXRe0z6EeKvK%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;803&quot; height=&quot;20&quot; data-origin-width=&quot;803&quot; data-origin-height=&quot;20&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진2&amp;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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;/p&gt;
&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/35803093/how-to-post-form-url-encoded-data-with-spring-cloud-feign&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://stackoverflow.com/questions/35803093/how-to-post-form-url-encoded-data-with-spring-cloud-feign&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/spring-projects/spring-framework/issues/18012&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/spring-projects/spring-framework/issues/18012&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JVM/Spring</category>
      <category>camelcase</category>
      <category>feignClient</category>
      <category>snakecase</category>
      <category>Spring</category>
      <category>springcloud</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/99</guid>
      <comments>https://kdhyo98.tistory.com/99#entry99comment</comments>
      <pubDate>Thu, 14 Jul 2022 12:21:05 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] Spring Cloud Feign logging 설정</title>
      <link>https://kdhyo98.tistory.com/98</link>
      <description>&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;처음에 설정했을땐 logging not working..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;logging이 작동하지 않아 간단하게 정리해봅니다.&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;433&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cJmcyU/btrG9MOtkIQ/S3aK59lkG4PsWOmWEMny2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cJmcyU/btrG9MOtkIQ/S3aK59lkG4PsWOmWEMny2K/img.png&quot; data-alt=&quot;&amp;amp;lt;사진1&amp;amp;gt; 넷플릭스~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cJmcyU/btrG9MOtkIQ/S3aK59lkG4PsWOmWEMny2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcJmcyU%2FbtrG9MOtkIQ%2FS3aK59lkG4PsWOmWEMny2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;433&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;433&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진1&amp;gt; 넷플릭스~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;pre id=&quot;code_1657714764047&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class CoreFeignConfiguration {

	@Bean
	Logger.Level feignLoggerLevel() {
		return Level.FULL;
	}

}

@FeignClient(configuration = CoreFeignConfiguration.class)
public interface KakaoPayClient {

...

}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드를 추가해도 로깅이 찍히지 않아서 검색해본 결과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;application.yml 에서도 logging을 설정해주어야 했었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Fiegn Client가 포함된 패키지 혹은 클래스에 대해서 Spring Boot 로깅 수준을 DEBUG로 설정해주면 됩니다!&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;logging: &lt;br /&gt;&amp;nbsp; level:&lt;br /&gt;&amp;nbsp; &amp;nbsp; {Package Name}.{Class Name}: DEBUG&lt;br /&gt;&lt;br /&gt;예시&lt;br /&gt;logging:&lt;br /&gt;&amp;nbsp; level:&lt;br /&gt;&amp;nbsp; &amp;nbsp; com.ticketing.server.payment.api.KakaoPayClient: DEBUG&lt;/blockquote&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;624&quot; data-origin-height=&quot;395&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d3riMV/btrHeqJTxyE/U0dchM0m2HDMjsk2WsPtz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d3riMV/btrHeqJTxyE/U0dchM0m2HDMjsk2WsPtz0/img.png&quot; data-alt=&quot;&amp;amp;lt;사진2&amp;amp;gt; 로깅 출력 성공&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d3riMV/btrHeqJTxyE/U0dchM0m2HDMjsk2WsPtz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd3riMV%2FbtrHeqJTxyE%2FU0dchM0m2HDMjsk2WsPtz0%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;624&quot; height=&quot;395&quot; data-origin-width=&quot;624&quot; data-origin-height=&quot;395&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진2&amp;gt; 로깅 출력 성공&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Logging Level&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;287&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bF7qCE/btrHaS1NhRq/IkodK393u2TowrTv1wvItk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bF7qCE/btrHaS1NhRq/IkodK393u2TowrTv1wvItk/img.png&quot; data-alt=&quot;&amp;amp;lt;사진3&amp;amp;gt; 로깅 레벨&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bF7qCE/btrHaS1NhRq/IkodK393u2TowrTv1wvItk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbF7qCE%2FbtrHaS1NhRq%2FIkodK393u2TowrTv1wvItk%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;594&quot; height=&quot;287&quot; data-origin-width=&quot;594&quot; data-origin-height=&quot;287&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진3&amp;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;저의 경우 테스트이기 때문에 모든 로그를 확인하고 싶어 FULL 로 설정해서 진행했습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;/p&gt;
&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.baeldung.com/java-feign-logging&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.baeldung.com/java-feign-logging&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>JVM/Spring</category>
      <category>Feign</category>
      <category>Log</category>
      <category>logging</category>
      <category>Spring</category>
      <category>springcloud</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/98</guid>
      <comments>https://kdhyo98.tistory.com/98#entry98comment</comments>
      <pubDate>Wed, 13 Jul 2022 21:31:26 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] Error creating bean with name 'configurationPropertiesBeans' defined in class path resource - Spring Cloud</title>
      <link>https://kdhyo98.tistory.com/97</link>
      <description>&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;스프링 클라우드 gradle 설정 시 만난 오류..&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[main] ERROR org.springframework.boot.SpringApplication - Application run failed org.springframework.beans.factory.BeanCreationException: &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Error creating bean with name 'configurationPropertiesBeans' defined in class path resource&lt;/b&gt;&lt;/span&gt; [org/springframework/cloud/autoconfigure/ConfigurationPropertiesRebinderAutoConfiguration.class]: Post-processing of merged bean definition failed; nested exception is java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.context.properties.ConfigurationPropertiesBeans] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@ed17bee] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:597) ~[spring-beans-5.3.19.jar:5.3.19] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.19.jar:5.3.19] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.19.jar:5.3.19] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.19.jar:5.3.19] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.19.jar:5.3.19] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:213) ~[spring-beans-5.3.19.jar:5.3.19] at org.springframework.context.support.PostProcessorRegistrationDelegate.registerBeanPostProcessors(PostProcessorRegistrationDelegate.java:270) ~[spring-context-5.3.19.jar:5.3.19] at org.springframework.context.support.AbstractApplicationContext.registerBeanPostProcessors(AbstractApplicationContext.java:762) ~[spring-context-5.3.19.jar:5.3.19] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:567) ~[spring-context-5.3.19.jar:5.3.19] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:164) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:212) ~[spring-cloud-context-2.2.5.RELEASE.jar:2.2.5.RELEASE] at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:117) ~[spring-cloud-context-2.2.5.RELEASE.jar:2.2.5.RELEASE] at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:74) ~[spring-cloud-context-2.2.5.RELEASE.jar:2.2.5.RELEASE] at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176) ~[spring-context-5.3.19.jar:5.3.19] at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169) ~[spring-context-5.3.19.jar:5.3.19] at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143) ~[spring-context-5.3.19.jar:5.3.19] at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131) ~[spring-context-5.3.19.jar:5.3.19] at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:85) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:66) ~[spring-boot-2.6.7.jar:2.6.7] at java.util.ArrayList.forEach(ArrayList.java:1541) ~[?:?] at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:114) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:339) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.SpringApplication.run(SpringApplication.java:297) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.7.jar:2.6.7] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.7.jar:2.6.7] at com.ticketing.server.ServerApplication.main(ServerApplication.java:17) ~[classes/:?] Caused by: java.lang.IllegalStateException: Failed to introspect Class [org.springframework.cloud.context.properties.ConfigurationPropertiesBeans] from ClassLoader [jdk.internal.loader.ClassLoaders$AppClassLoader@ed17bee] at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:485) ~[spring-core-5.3.19.jar:5.3.19] at org.springframework.util.ReflectionUtils.doWithLocalMethods(ReflectionUtils.java:321) ~[spring-core-5.3.19.jar:5.3.19] at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.buildPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:417) ~[spring-orm-5.3.19.jar:5.3.19] at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.findPersistenceMetadata(PersistenceAnnotationBeanPostProcessor.java:388) ~[spring-orm-5.3.19.jar:5.3.19] at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessMergedBeanDefinition(PersistenceAnnotationBeanPostProcessor.java:335) ~[spring-orm-5.3.19.jar:5.3.19] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyMergedBeanDefinitionPostProcessors(AbstractAutowireCapableBeanFactory.java:1116) ~[spring-beans-5.3.19.jar:5.3.19] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:594) ~[spring-beans-5.3.19.jar:5.3.19] ... 30 more&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 클라우드 설정 중 위와 같은 에러를 만났습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  원인&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 버전 별로 호환되는 스프링 클라우드 버전이 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csBvI0/btrHfRfExeL/PcQEbHO1FJ6U21rZIvOjKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csBvI0/btrHfRfExeL/PcQEbHO1FJ6U21rZIvOjKk/img.png&quot; data-alt=&quot;&amp;amp;lt;사진1&amp;amp;gt;&amp;amp;amp;nbsp;Adding Spring Cloud To An Existing Spring Boot Application&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csBvI0/btrHfRfExeL/PcQEbHO1FJ6U21rZIvOjKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsBvI0%2FbtrHfRfExeL%2FPcQEbHO1FJ6U21rZIvOjKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;806&quot; height=&quot;354&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진1&amp;gt;&amp;amp;nbsp;Adding Spring Cloud To An Existing Spring Boot Application&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;Boot&lt;/b&gt;는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;2.6.7&lt;/b&gt;&lt;/span&gt; 버전을 사용 중인데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Cloud&lt;/b&gt; 는 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Hoxton&lt;/span&gt;&lt;/b&gt; 버전을 사용하려고 했기 때문에 호환이 안되서 발생한 오류였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버전 확인은 &lt;a href=&quot;https://spring.io/projects/spring-cloud&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식사이트&lt;/a&gt; 에서 확인할 수 있습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  어떤 버전을 선택하면 되지?&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;206&quot; data-origin-height=&quot;53&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6NW97/btrHev5ldur/DQElRgFKXl9pbJM9KBK950/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6NW97/btrHev5ldur/DQElRgFKXl9pbJM9KBK950/img.png&quot; data-alt=&quot;&amp;amp;lt;사진2&amp;amp;gt; M버전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6NW97/btrHev5ldur/DQElRgFKXl9pbJM9KBK950/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6NW97%2FbtrHev5ldur%2FDQElRgFKXl9pbJM9KBK950%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;206&quot; height=&quot;53&quot; data-origin-width=&quot;206&quot; data-origin-height=&quot;53&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진2&amp;gt; M버전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;43&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvWmv9/btrHdI5aA3n/bQLwgwOF3HRfujNKMXzCqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvWmv9/btrHdI5aA3n/bQLwgwOF3HRfujNKMXzCqk/img.png&quot; data-alt=&quot;&amp;amp;lt;사진3&amp;amp;gt; RC1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvWmv9/btrHdI5aA3n/bQLwgwOF3HRfujNKMXzCqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvWmv9%2FbtrHdI5aA3n%2FbQLwgwOF3HRfujNKMXzCqk%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;227&quot; height=&quot;43&quot; data-origin-width=&quot;227&quot; data-origin-height=&quot;43&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진3&amp;gt; RC1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 버전 옆에 -M3 나 -RC1 이 붙은 건 피해서 사용하시길 바랍니다.&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;RC1 (Release Candidate 1)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;안정화가 될 후보 버전&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;M1, M2, M3 (Milestone)&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발 중인 버전&lt;/li&gt;
&lt;/ul&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;142&quot; data-origin-height=&quot;43&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/V1NXC/btrHdK9Xbuo/LMX0spfnt012u33ZT1kOIk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/V1NXC/btrHdK9Xbuo/LMX0spfnt012u33ZT1kOIk/img.png&quot; data-alt=&quot;&amp;amp;lt;사진4&amp;amp;gt; 안정화 버전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/V1NXC/btrHdK9Xbuo/LMX0spfnt012u33ZT1kOIk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FV1NXC%2FbtrHdK9Xbuo%2FLMX0spfnt012u33ZT1kOIk%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;142&quot; height=&quot;43&quot; data-origin-width=&quot;142&quot; data-origin-height=&quot;43&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진4&amp;gt; 안정화 버전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 옆에 아무것도 안 붙여져 있는 게 안정화버전 이니 안정화버전을 찾아 사용하시면 될 것 같습니다!&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;다들 각자 Boot 버전에 맞는 Cloud 버전을 설정하시길 바랍니다!&lt;/p&gt;
&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;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://spring.io/projects/spring-cloud&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://spring.io/projects/spring-cloud&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2021.0-Release-Notes&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2021.0-Release-Notes&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://darkstart.tistory.com/309&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://darkstart.tistory.com/309&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://pythontoomuchinformation.tistory.com/278&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://pythontoomuchinformation.tistory.com/278&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>JVM/Spring</category>
      <category>exception</category>
      <category>Feign</category>
      <category>Spring</category>
      <category>springcloud</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/97</guid>
      <comments>https://kdhyo98.tistory.com/97#entry97comment</comments>
      <pubDate>Wed, 13 Jul 2022 21:07:21 +0900</pubDate>
    </item>
    <item>
      <title>[Ticketing] 유저 PK 대신 유니크 ID 만들어 사용하게 된 계기 (유니크 ID 생성)</title>
      <link>https://kdhyo98.tistory.com/96</link>
      <description>&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;현재 진행 중인 Ticketing 프로젝트는 시스템이 분리되어있다는 가정 하에 진행된 프로젝트입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk4IRt/btrG8sanzdg/EH6WHvNi1Pd1FBIGs0KqZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk4IRt/btrG8sanzdg/EH6WHvNi1Pd1FBIGs0KqZk/img.png&quot; data-alt=&quot;&amp;amp;lt;사진1&amp;amp;gt; 시스템 정보&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk4IRt/btrG8sanzdg/EH6WHvNi1Pd1FBIGs0KqZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk4IRt%2FbtrG8sanzdg%2FEH6WHvNi1Pd1FBIGs0KqZk%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;502&quot; height=&quot;165&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진1&amp;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;처음 설계 당시에는 유저 PK 값을 넣어서 사용하려 했지만, 몇 가지 문제가 있어서 대체 유니크키 생성을 결정하게 되었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 내용을 정리해보려 합니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;271&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ceXk1l/btrG5rckl1R/F4857kIUD0fpJkZ1wjjZI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ceXk1l/btrG5rckl1R/F4857kIUD0fpJkZ1wjjZI1/img.png&quot; data-alt=&quot;&amp;amp;lt;사진2&amp;amp;gt; Before ERD&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ceXk1l/btrG5rckl1R/F4857kIUD0fpJkZ1wjjZI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FceXk1l%2FbtrG5rckl1R%2FF4857kIUD0fpJkZ1wjjZI1%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;658&quot; height=&quot;271&quot; data-origin-width=&quot;658&quot; data-origin-height=&quot;271&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진2&amp;gt; Before ERD&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;기존 ERD 구조입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 Payment 에서 User의 pk 값을 가지고 있죠.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고민의 시작인 API의 간단한 &lt;b&gt;Sequence Diagram&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;940&quot; data-origin-height=&quot;363&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2g8gs/btrG5qYQbdC/KDbibQ5NiqLtK0pE3icQR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2g8gs/btrG5qYQbdC/KDbibQ5NiqLtK0pE3icQR1/img.png&quot; data-alt=&quot;&amp;amp;lt;사진3&amp;amp;gt; 로그인된 계정 결제 목록 조회 API Sequence Diagram - mermaid&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2g8gs/btrG5qYQbdC/KDbibQ5NiqLtK0pE3icQR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2g8gs%2FbtrG5qYQbdC%2FKDbibQ5NiqLtK0pE3icQR1%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;940&quot; height=&quot;363&quot; data-origin-width=&quot;940&quot; data-origin-height=&quot;363&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진3&amp;gt; 로그인된 계정 결제 목록 조회 API Sequence Diagram - mermaid&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 결제 목록 요청을 할 때 각 유저의 고유한 값을 Payment에서 가지고 있어야&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;여기서 기존엔 User의 PK를 사용했는데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;왜 고민했는지 Email, Unique Id를 왜 고민했고 어떤 걸 선택했는지&lt;/b&gt; 알아봅시다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  PK를 고민한 이유.&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 PK를 그냥 사용해도 됩니다.&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;하지만 문제로 생각했던 부분은 PK가 순차적으로 증가하는 값이란 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, 순차적으로 증가하는 값을 사용된다는 걸 아는 사용자가 UserSystem을 거치지 않고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PaymentSystem을 바로 결제 목록 요청을 하게 되면 어떻게 될까요??&lt;/p&gt;
&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, 2, 3, 4, ... 로 늘려보면서 다른 사용자들의 결제 목록을 조회&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;물론, UserSystem 외의 접근을 막을 수도 있지만&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 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;1. 유니크 값으로 하나밖에 존재하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 이미 존재하는 값이고, 현재 이에 맞게 설계 되었기 때문에 변경할 게 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 사용자에게 PK가 노출될 경우 악용될 가능성이 있다. (예 - 다른 사용자의 정보 조회)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt; &lt;span&gt; &amp;nbsp;&lt;/span&gt;&lt;/b&gt;Email을 고민한 이유.&lt;/b&gt;&lt;/h3&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;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;1. 유니크 값으로 하나밖에 존재하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. JWT에 존재하는 값으로 Payment로 바로 호출하는 API 개발 시 UserSystem을 호출하지 않아도 된다.&lt;/p&gt;
&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;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;1. Email은 결국 변경이 가능한 사용자의 데이터다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 변경 가능한 값으로 공유하게 되면, 관리하기가 힘들어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. &lt;a href=&quot;https://jojoldu.tistory.com/672?category=1011740&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;현실세계 데이터에 의존하지 말자.&lt;/a&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  그러면 답은 새로운 Unique Key!&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자가 유추하기 힘든 Unique 값을 새로 추가하여 외부에 노출할 때에는 이 값을 사용하는 방법입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;New Unique Key&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;&lt;b&gt;장점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 유저가 유추할 수 없는 유니크 값을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 현실세계에 의존하지 않는 값으로 변경 가능성이 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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 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;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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그럼 UUID를 사용할까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 UUID가 아닌, 트위치에서 처음 발표한 &lt;a href=&quot;https://github.com/callicoder/java-snowflake&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Snowflake 를 모방한 알고리즘&lt;/a&gt;을 사용하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;UUID를 사용하지 않은 이유&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 128Bit으로 크기가 크고, 무겁다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 알파벳과 뒤섞인 값보다는 숫자로만 된 값이 좀 더 파악하기가 용이하다고 판단했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러가지 방법을 생각한 후 현재 상황에 어떤 게 좀 더 우리한테 맞을까를 고민한 후 결정해보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저희가 선택한 방법이 무조건적인 정답이라 생각하진 않지만, 설득력이 있는 결정이었으면 좋겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;피드백은 언제나 환영입니다!&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에는 메모장에 적어둔 Unique ID 생성하는 방법을 정리해보도록 하겠습니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Project</category>
      <category>java</category>
      <category>snowflake</category>
      <category>unique</category>
      <category>UUID</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/96</guid>
      <comments>https://kdhyo98.tistory.com/96#entry96comment</comments>
      <pubDate>Tue, 12 Jul 2022 22:50:18 +0900</pubDate>
    </item>
    <item>
      <title>[Ticketing] 다른 테이블에 중복 데이터를 추가한 이유</title>
      <link>https://kdhyo98.tistory.com/95</link>
      <description>&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블 설계 이후 구현 단계에서 다른 테이블에 중복 컬럼을 왜 추가하게 됐는지 정리해보려 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(많이 History 느낌의 글입니다.)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;  본론&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;현재 프로젝트 상황&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;패키지&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 구조는 아래와 같습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HPIvY/btrGGbsBXC6/RkU0sTmdctCWqTgdfuVhU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HPIvY/btrGGbsBXC6/RkU0sTmdctCWqTgdfuVhU0/img.png&quot; data-alt=&quot;&amp;amp;lt;사진1&amp;amp;gt; 시스템 정보&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HPIvY/btrGGbsBXC6/RkU0sTmdctCWqTgdfuVhU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHPIvY%2FbtrGGbsBXC6%2FRkU0sTmdctCWqTgdfuVhU0%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;502&quot; height=&quot;165&quot; data-origin-width=&quot;502&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진1&amp;gt; 시스템 정보&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나중에 MSA 구조로 분리하기 위해 현재는 패키지만 분리해둔 상태입니다.&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;ERD&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;1319&quot; data-origin-height=&quot;858&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7t49K/btrGEmWBK2n/MngD4BFBvBDBXLwpHMw1F1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7t49K/btrGEmWBK2n/MngD4BFBvBDBXLwpHMw1F1/img.png&quot; data-alt=&quot;&amp;amp;lt;사진2&amp;amp;gt; ERD 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7t49K/btrGEmWBK2n/MngD4BFBvBDBXLwpHMw1F1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7t49K%2FbtrGEmWBK2n%2FMngD4BFBvBDBXLwpHMw1F1%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;1319&quot; height=&quot;858&quot; data-origin-width=&quot;1319&quot; data-origin-height=&quot;858&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진2&amp;gt; ERD 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&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;결제 서비스와 유저 서비스에선 각각 1개의 테이블이 있는 구조입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;요구사항 분석&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;회원 결제목록 조회
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;로그인된 사용자의 정보를 이용해서 결제 목록을 얻어온다.&lt;/li&gt;
&lt;li&gt;결제목록은 영화제목, 금액, 결제상태가 존재한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;177039884-31130554-9eec-44f2-a487-3a4d37e00a2a.png&quot; data-origin-width=&quot;425&quot; data-origin-height=&quot;709&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWmw6x/btrGDKQ7EYl/pwlia5m9AxWeg97vzFg3W0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWmw6x/btrGDKQ7EYl/pwlia5m9AxWeg97vzFg3W0/img.png&quot; data-alt=&quot;&amp;amp;lt;사진3&amp;amp;gt; 프로토타입 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWmw6x/btrGDKQ7EYl/pwlia5m9AxWeg97vzFg3W0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWmw6x%2FbtrGDKQ7EYl%2Fpwlia5m9AxWeg97vzFg3W0%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;425&quot; height=&quot;709&quot; data-filename=&quot;177039884-31130554-9eec-44f2-a487-3a4d37e00a2a.png&quot; data-origin-width=&quot;425&quot; data-origin-height=&quot;709&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진3&amp;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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;요구사항을 위해서는?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결제목록을 가져오는 요구사항은, &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;현재 설계된 모든 서비스&lt;/span&gt;&lt;/b&gt;를 거치게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 현재 설계된 ERD 기준으로 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;영화제목&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;은 Movie 서비스&lt;/span&gt;&lt;/b&gt;에 있고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;결제 타입과 결제 금액은 Payment 서비스&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;만약, msa가 아닌 하나의 서비스였다면 join으로 해결할 수도 있습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;user join payment join ticket join movie_time join movie&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;join이 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;하지만, 저희는 MSA 구조로 모듈을 나눠 진행하고 있으며, 그렇게 되면 3번의 api 통신이 이루어지게 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;504&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yiZRi/btrGDKQ8itw/N1QnP1S0DmGftvF0QDKLp1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yiZRi/btrGDKQ8itw/N1QnP1S0DmGftvF0QDKLp1/img.png&quot; data-alt=&quot;&amp;amp;lt;사진4&amp;amp;gt; 흐름도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yiZRi/btrGDKQ8itw/N1QnP1S0DmGftvF0QDKLp1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyiZRi%2FbtrGDKQ8itw%2FN1QnP1S0DmGftvF0QDKLp1%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;520&quot; height=&quot;504&quot; data-origin-width=&quot;520&quot; data-origin-height=&quot;504&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;&amp;lt;사진4&amp;gt; 흐름도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;여기서 고민이 생기게 되었습니다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;3개의 통신을 굳이 해야 할까?&lt;/li&gt;
&lt;li&gt;통신을 어떻게 줄일 수 있을까?&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결제시스템을 조회 후 결제 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;그렇다면 통신을 줄이기 위해서는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유저서비스에 결제정보를 저장하거나, 결제서비스에 영화제목을 저장하면 현재 요구사항에서는 API통신을 줄일 수 있을 것으로 보입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;유저서비스 안에 결제정보 ?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일단, 결제시스템에 있는 정보는 유저에 넣을 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 1대N 관계이기 때문이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A유저가 '범죄도시2'와 '탑건'을 예매했을 경우 유저테이블에 결제정보가 있다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A유저에 대한 컬럼이 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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;결제서비스 안에 영화제목 ?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면, 결제시스템에 '&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;영화 제목&lt;/b&gt;&lt;/span&gt;'을 넣는 건 어떨까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'범죄도시2' 결제내역과 '탑건' 결제내역은 이미 분리가 되어있기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결제시스템에서는 결제정보가 중복으로 생기진 않고, '&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;영화 제목&lt;/span&gt;&lt;/b&gt;' 컬럼만 추가하여 끝낼 수 있을 것 같습니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;어떤 걸 고려해야 할까?&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;데이터 관리&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 동일한 데이터를 여러 서비스(테이블)에서 관리하는 건 무척 신중해야 하는 일입니다.&lt;/p&gt;
&lt;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;background-color: #f6e199;&quot;&gt;&lt;b&gt;영화 제목&lt;/b&gt;&lt;/span&gt;'은 어떨까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;영화 제목&lt;/b&gt;&lt;/span&gt;'은 한 번 등록되면 변경되는 경우가 거의 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;거의 변하지 않는 데이터라 봐도 무방하죠.&lt;/p&gt;
&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;트래픽이 없는 시간에 Movie 테이블과 Payment 테이블의 영화 제목을 변경을 순조롭게 진행할 수 있을 것 같습니다.&lt;/p&gt;
&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;여러 영화를 한 번에 결제할 경우에는 어떻게 할 것인가?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 영화를 한 번에 결제할 경우 유저 - 결제정보 에서 발생했던 문제와 동일한 문제가 발생할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결제테이블에서 동일한 결제정보가 중복으로 생기는 문제말이죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 저희 프로젝트에서는 여러 영화를 선택해서 한 번에 결제하는 기능을 구현하지 않을 예정입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 프로토타입 설계 시 영화를 선택하고 해당 영화를 결제하도록 진행시켰습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배달의 민족처럼 장바구니에 여러 영화를 담고 결제하지 않죠.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러므로 해당 문제는 저희 시스템에서 발생하지 않는 문제라는 결론을 내렸습니다.&lt;/p&gt;
&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;장단점&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼, 결제 서비스에 '&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;영화 제목&lt;/b&gt;&lt;/span&gt;' 을 추가하여 나온 장단점을 분석해보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;- 만약 영화제목이 변경되었을 경우 영화서비스, 결제서비스 두 곳 다 변경을 해주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - (관리할 곳이 늘어남)&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;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;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;영화 제목&lt;/b&gt;&lt;/span&gt;' 특성 상 변경이 한 번 등록되면 변경이 거의 변경하지 않을 것으로 보아&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결제시스템에서 중복으로 관리하는 것이 큰 부담이 없을 것으로 판단하여 추가하는 것으로 결정하였습니다.&lt;/p&gt;
&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;여기서 이야기 하고 싶은 부분은 payment에 '&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;영화 제목&lt;/b&gt;&lt;/span&gt;'을 넣냐 빼냐를 얘기하고 싶었던 게 아닙니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'어떤 문제'를 발견하고, 여러 '해결 방법'을 고민해보면서 저희 현재 요구사항에 맞는 결정을 내리는.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉, 무슨&lt;/span&gt;&amp;nbsp;이유로 해당 문제를 어떤 방식으로 해결하려고 했는지. 이런 고민이 개발자로선 중요한 부분이라 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 상황에 일치하는 정답은 없다고 생각합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각자의 상황 속에서 팀원들이 생각하는 최선의 답을 찾는 과정이 의미있다 생각합니다.&lt;/p&gt;</description>
      <category>Project</category>
      <author>Hyo Kim</author>
      <guid isPermaLink="true">https://kdhyo98.tistory.com/95</guid>
      <comments>https://kdhyo98.tistory.com/95#entry95comment</comments>
      <pubDate>Thu, 7 Jul 2022 01:39:16 +0900</pubDate>
    </item>
  </channel>
</rss>