<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>너구리의 코딩 블로그</title>
    <link>https://javacoding.tistory.com/</link>
    <description>





개발자를 꿈꾸는 너구리</description>
    <language>ko</language>
    <pubDate>Wed, 17 Jun 2026 22:36:00 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>코딩하는 너구리</managingEditor>
    <image>
      <title>너구리의 코딩 블로그</title>
      <url>https://tistory1.daumcdn.net/tistory/3197075/attach/ca8b3f89e48d4f20819d46f834da924e</url>
      <link>https://javacoding.tistory.com</link>
    </image>
    <item>
      <title>[MySQL] Windows 11 MySQL 설치/다운로드 방법</title>
      <link>https://javacoding.tistory.com/185</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 data-ke-size=&quot;size26&quot;&gt;MySQL 다운로드&lt;/h2&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;오늘은 Windows 11 버전에서 MySQL 다운로드 하는 방법에 대해서 포스팅하겠습니다.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h3 data-ke-size=&quot;size23&quot;&gt;1.&amp;nbsp; MySQL 홈페이지로 이동&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;아래 링크를 눌러 mysql 다운로드 페이지로 이동합시다!&lt;br&gt;&amp;nbsp;&lt;br&gt;&lt;a href=&quot;https://www.mysql.com/downloads/&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://www.mysql.com/downloads/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;MySQL :: MySQL Downloads&quot; data-ke-align=&quot;alignCenter&quot; data-og-host=&quot;www.mysql.com&quot; data-og-source-url=&quot;https://www.mysql.com/downloads/&quot; data-og-url=&quot;https://www.mysql.com/downloads/&quot;&gt;&lt;a href=&quot;https://www.mysql.com/downloads/&quot; target=&quot;_blank&quot; data-source-url=&quot;https://www.mysql.com/downloads/&quot;&gt;&lt;div class=&quot;og-image&quot;&gt;&lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;MySQL :: MySQL Downloads&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;www.mysql.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;size18&quot;&gt;스크롤을 아래로 내려, &lt;a href=&quot;https://dev.mysql.com/downloads/&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #0074a3;&quot;&gt;MySQL Community (GPL) Downloads »&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; 을 클릭합니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;542&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cde3DX/btsEQNBiyxF/3fagKVEzfVHvRKYnvDU7H0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cde3DX/btsEQNBiyxF/3fagKVEzfVHvRKYnvDU7H0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cde3DX/btsEQNBiyxF/3fagKVEzfVHvRKYnvDU7H0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcde3DX%2FbtsEQNBiyxF%2F3fagKVEzfVHvRKYnvDU7H0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1388&quot; height=&quot;542&quot; data-origin-width=&quot;1388&quot; data-origin-height=&quot;542&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;다음 화면에서 &lt;/span&gt;&lt;a href=&quot;https://dev.mysql.com/downloads/mysql/&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #0074a3;&quot;&gt;MySQL Community Server&lt;/span&gt;&lt;/span&gt;&lt;/a&gt; 를 클릭합니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;590&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rGvlS/btsEP9EE8l8/YBqBucs4MrWUbmSlAlCVf1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rGvlS/btsEP9EE8l8/YBqBucs4MrWUbmSlAlCVf1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rGvlS/btsEP9EE8l8/YBqBucs4MrWUbmSlAlCVf1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrGvlS%2FbtsEP9EE8l8%2FYBqBucs4MrWUbmSlAlCVf1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;949&quot; height=&quot;590&quot; data-origin-width=&quot;949&quot; data-origin-height=&quot;590&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;br&gt;설치하기 편한 MSI Installer로 선택해주세요 [ &lt;b&gt;Windows (x86, 64-bit), MSI Installer&lt;/b&gt; ]&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1921&quot; data-origin-height=&quot;1033&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cWga3Q/btsEVOL44jg/NzOP671lM3jPLKcubJxtkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cWga3Q/btsEVOL44jg/NzOP671lM3jPLKcubJxtkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cWga3Q/btsEVOL44jg/NzOP671lM3jPLKcubJxtkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcWga3Q%2FbtsEVOL44jg%2FNzOP671lM3jPLKcubJxtkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1921&quot; height=&quot;1033&quot; data-origin-width=&quot;1921&quot; data-origin-height=&quot;1033&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;br&gt;다운로드 화면에서는 [ &lt;a href=&quot;https://dev.mysql.com/get/Downloads/MySQL-8.3/mysql-8.3.0-winx64.msi&quot; target=&quot;_self&quot;&gt;&lt;span&gt;&lt;span style=&quot;color: #0074a3;&quot;&gt;No thanks, just start my download.&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;] 를 클릭해주세요&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;532&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bL8gQW/btsES2kouZM/apNoZWKzIk6UCYrmrL2BKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bL8gQW/btsES2kouZM/apNoZWKzIk6UCYrmrL2BKK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bL8gQW/btsES2kouZM/apNoZWKzIk6UCYrmrL2BKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbL8gQW%2FbtsES2kouZM%2FapNoZWKzIk6UCYrmrL2BKK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;922&quot; height=&quot;532&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;532&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;지금부터는 쭉 MSI 실행 화면입니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;382&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GuicU/btsERAvcJ4y/90tklYIkSIKtqnh48Q7PC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GuicU/btsERAvcJ4y/90tklYIkSIKtqnh48Q7PC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GuicU/btsERAvcJ4y/90tklYIkSIKtqnh48Q7PC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGuicU%2FbtsERAvcJ4y%2F90tklYIkSIKtqnh48Q7PC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;488&quot; height=&quot;382&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;382&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;495&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QPCwe/btsES61pM2u/pIjSk8hyWkPRrZ2BBWa6ok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QPCwe/btsES61pM2u/pIjSk8hyWkPRrZ2BBWa6ok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QPCwe/btsES61pM2u/pIjSk8hyWkPRrZ2BBWa6ok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQPCwe%2FbtsES61pM2u%2FpIjSk8hyWkPRrZ2BBWa6ok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;495&quot; height=&quot;387&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;387&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;495&quot; data-origin-height=&quot;388&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FOJ9z/btsEQbilYNC/Xmvc5CFf0HaC99hKSh6rE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FOJ9z/btsEQbilYNC/Xmvc5CFf0HaC99hKSh6rE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FOJ9z/btsEQbilYNC/Xmvc5CFf0HaC99hKSh6rE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFOJ9z%2FbtsEQbilYNC%2FXmvc5CFf0HaC99hKSh6rE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;495&quot; height=&quot;388&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;388&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;483&quot; data-origin-height=&quot;381&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/reUuN/btsEV8p9UG4/gOpT8mDxpEPAVkoAiFUp10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/reUuN/btsEV8p9UG4/gOpT8mDxpEPAVkoAiFUp10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/reUuN/btsEV8p9UG4/gOpT8mDxpEPAVkoAiFUp10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FreUuN%2FbtsEV8p9UG4%2FgOpT8mDxpEPAVkoAiFUp10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;381&quot; data-origin-width=&quot;483&quot; data-origin-height=&quot;381&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;488&quot; data-origin-height=&quot;379&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kzTAk/btsERz37PCX/x47K4D4wZkDi0fmCgavOJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kzTAk/btsERz37PCX/x47K4D4wZkDi0fmCgavOJ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kzTAk/btsERz37PCX/x47K4D4wZkDi0fmCgavOJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkzTAk%2FbtsERz37PCX%2Fx47K4D4wZkDi0fmCgavOJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;488&quot; height=&quot;379&quot; data-origin-width=&quot;488&quot; data-origin-height=&quot;379&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;이제부터 설정화면으로 넘어갑니다&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/AXJnq/btsEVkq3KME/GcDWc27StbA6kCVnYbfjo0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/AXJnq/btsEVkq3KME/GcDWc27StbA6kCVnYbfjo0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/AXJnq/btsEVkq3KME/GcDWc27StbA6kCVnYbfjo0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAXJnq%2FbtsEVkq3KME%2FGcDWc27StbA6kCVnYbfjo0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;611&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;611&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;788&quot; data-origin-height=&quot;616&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Com1U/btsETitJ3pM/YO6zbSyCeK7SKquUbRfKkK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Com1U/btsETitJ3pM/YO6zbSyCeK7SKquUbRfKkK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Com1U/btsETitJ3pM/YO6zbSyCeK7SKquUbRfKkK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCom1U%2FbtsETitJ3pM%2FYO6zbSyCeK7SKquUbRfKkK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;616&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;616&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;791&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/II7jc/btsEP69bjc9/rKOW9L6LmhK3nKydZWEJF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/II7jc/btsEP69bjc9/rKOW9L6LmhK3nKydZWEJF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/II7jc/btsEP69bjc9/rKOW9L6LmhK3nKydZWEJF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FII7jc%2FbtsEP69bjc9%2FrKOW9L6LmhK3nKydZWEJF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;791&quot; height=&quot;611&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;611&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;616&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KF7uX/btsETh9qIlR/cCKqVLRKUg741dpoRLSyFk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KF7uX/btsETh9qIlR/cCKqVLRKUg741dpoRLSyFk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KF7uX/btsETh9qIlR/cCKqVLRKUg741dpoRLSyFk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKF7uX%2FbtsETh9qIlR%2FcCKqVLRKUg741dpoRLSyFk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;616&quot; data-origin-width=&quot;788&quot; data-origin-height=&quot;616&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;783&quot; data-origin-height=&quot;607&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HDOmO/btsEVLWeH1I/HjK3aPGzpDcgooCzfVon2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HDOmO/btsEVLWeH1I/HjK3aPGzpDcgooCzfVon2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HDOmO/btsEVLWeH1I/HjK3aPGzpDcgooCzfVon2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHDOmO%2FbtsEVLWeH1I%2FHjK3aPGzpDcgooCzfVon2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;783&quot; height=&quot;607&quot; data-origin-width=&quot;783&quot; data-origin-height=&quot;607&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;785&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dtPBwn/btsETj7e40P/5StjyFUHCnHkqkIg7B9Tj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dtPBwn/btsETj7e40P/5StjyFUHCnHkqkIg7B9Tj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dtPBwn/btsETj7e40P/5StjyFUHCnHkqkIg7B9Tj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdtPBwn%2FbtsETj7e40P%2F5StjyFUHCnHkqkIg7B9Tj1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;785&quot; height=&quot;612&quot; data-origin-width=&quot;785&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;MySQL에서 파일 접근에 대한 권한을 받는 부분이니 가급적 Yes를 선택해주세요.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;613&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/behSlI/btsEP6OTJD9/x5vZwyh1miM30CTrYpTsCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/behSlI/btsEP6OTJD9/x5vZwyh1miM30CTrYpTsCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/behSlI/btsEP6OTJD9/x5vZwyh1miM30CTrYpTsCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbehSlI%2FbtsEP6OTJD9%2Fx5vZwyh1miM30CTrYpTsCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;780&quot; height=&quot;613&quot; data-origin-width=&quot;780&quot; data-origin-height=&quot;613&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;샘플 데이터베이스는 필요 없으므로 Next 선택해주었습니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;785&quot; data-origin-height=&quot;611&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ca0Af5/btsERAvdiex/KBTKG9pG6MqkuDtepZMeJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ca0Af5/btsERAvdiex/KBTKG9pG6MqkuDtepZMeJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ca0Af5/btsERAvdiex/KBTKG9pG6MqkuDtepZMeJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fca0Af5%2FbtsERAvdiex%2FKBTKG9pG6MqkuDtepZMeJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;785&quot; height=&quot;611&quot; data-origin-width=&quot;785&quot; data-origin-height=&quot;611&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;786&quot; data-origin-height=&quot;587&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bblTjZ/btsEV8KsS7s/CEWw5nnj1K0QzCm2ca3wz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bblTjZ/btsEV8KsS7s/CEWw5nnj1K0QzCm2ca3wz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bblTjZ/btsEV8KsS7s/CEWw5nnj1K0QzCm2ca3wz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbblTjZ%2FbtsEV8KsS7s%2FCEWw5nnj1K0QzCm2ca3wz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;786&quot; height=&quot;587&quot; data-origin-width=&quot;786&quot; data-origin-height=&quot;587&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;784&quot; data-origin-height=&quot;595&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/rVtO4/btsETVd0LYe/dYP6fiKDPCsOLJsg55kj01/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/rVtO4/btsETVd0LYe/dYP6fiKDPCsOLJsg55kj01/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/rVtO4/btsETVd0LYe/dYP6fiKDPCsOLJsg55kj01/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FrVtO4%2FbtsETVd0LYe%2FdYP6fiKDPCsOLJsg55kj01%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;784&quot; height=&quot;595&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;595&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;여기까지 MySQL Server 설치는 완료되었습니다. 이제 직접 접근해보도록 할게요.&lt;/p&gt;&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot;&gt;&lt;p data-ke-size=&quot;size18&quot;&gt;윈도우 키를 눌러 &quot;MySQL&quot;로 앱을 검색한 뒤 &quot;Command Line Client&quot;를 실행시켜주세요.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;694&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biUzY9/btsETYaL0Ld/UKnKqjZrKiHNqWTxxLMmhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biUzY9/btsETYaL0Ld/UKnKqjZrKiHNqWTxxLMmhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biUzY9/btsETYaL0Ld/UKnKqjZrKiHNqWTxxLMmhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiUzY9%2FbtsETYaL0Ld%2FUKnKqjZrKiHNqWTxxLMmhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;776&quot; height=&quot;694&quot; data-origin-width=&quot;776&quot; data-origin-height=&quot;694&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;실행 후 비밀번호를 입력해야 하는데, 가입 시 설정한 Root Password를 입력해주세요.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dZHkIQ/btsES68dApV/85k99RBs0EGzz6KZrwngZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dZHkIQ/btsES68dApV/85k99RBs0EGzz6KZrwngZ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dZHkIQ/btsES68dApV/85k99RBs0EGzz6KZrwngZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdZHkIQ%2FbtsES68dApV%2F85k99RBs0EGzz6KZrwngZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1104&quot; height=&quot;483&quot; data-origin-width=&quot;1104&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;489&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPyve5/btsERlLxPvD/0Gwp4Mhdapen8T71ccNxD0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPyve5/btsERlLxPvD/0Gwp4Mhdapen8T71ccNxD0/img.png&quot; data-alt=&quot;실행 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPyve5/btsERlLxPvD/0Gwp4Mhdapen8T71ccNxD0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPyve5%2FbtsERlLxPvD%2F0Gwp4Mhdapen8T71ccNxD0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1110&quot; height=&quot;489&quot; data-origin-width=&quot;1110&quot; data-origin-height=&quot;489&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실행 화면&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이것으로 Windows 11 환경에서의 MySQL 8.3 설치를 마치겠습니다.&lt;/p&gt;</description>
      <category>IT</category>
      <category>mysql</category>
      <category>MySQL 8.3</category>
      <category>MySQL DB</category>
      <category>MySQL 설치</category>
      <category>windows mysql 설치</category>
      <category>Windows11 MySQL</category>
      <category>Windows11 MySQL 설치</category>
      <category>윈도우 MySQL</category>
      <category>윈도우 mysql 설치</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/185</guid>
      <comments>https://javacoding.tistory.com/185#entry185comment</comments>
      <pubDate>Thu, 15 Feb 2024 15:33:08 +0900</pubDate>
    </item>
    <item>
      <title>[Flutter] Unable to boot simulator 해결 방법</title>
      <link>https://javacoding.tistory.com/184</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;앱을 개발하던 중 iOS Simulator가 실행되지 않는 문제가 발생했다.&lt;/p&gt;
&lt;p data-ke-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;544&quot; data-origin-height=&quot;378&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oOXDs/btstvOqXcFw/RosrKYp1cFryntidse3Sk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oOXDs/btstvOqXcFw/RosrKYp1cFryntidse3Sk0/img.png&quot; data-alt=&quot;에러 메시지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oOXDs/btstvOqXcFw/RosrKYp1cFryntidse3Sk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoOXDs%2FbtstvOqXcFw%2FRosrKYp1cFryntidse3Sk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;544&quot; height=&quot;378&quot; data-origin-width=&quot;544&quot; data-origin-height=&quot;378&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;에러 메시지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 에러 메시지가 나오며 시뮬레이터가 실행되지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결방법은 상당히 간단했는데 아래와 같이 캐시를 삭제해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1) 저장공간 접속&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;410&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lWSAU/btstx8aW0KG/Hao7bjsNmL1ajL069NADK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lWSAU/btstx8aW0KG/Hao7bjsNmL1ajL069NADK0/img.png&quot; data-alt=&quot;이 Mac에 관하여 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lWSAU/btstx8aW0KG/Hao7bjsNmL1ajL069NADK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlWSAU%2Fbtstx8aW0KG%2FHao7bjsNmL1ajL069NADK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;410&quot; data-origin-width=&quot;560&quot; data-origin-height=&quot;410&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이 Mac에 관하여 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;436&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bY1j3r/btstxmmZBSN/pY0X9BPau22tlOrzv7ZzG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bY1j3r/btstxmmZBSN/pY0X9BPau22tlOrzv7ZzG1/img.png&quot; data-alt=&quot;추가 정보 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bY1j3r/btstxmmZBSN/pY0X9BPau22tlOrzv7ZzG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbY1j3r%2FbtstxmmZBSN%2FpY0X9BPau22tlOrzv7ZzG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;514&quot; height=&quot;436&quot; data-origin-width=&quot;514&quot; data-origin-height=&quot;436&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;654&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lQ29x/btstq9oUqE2/FYhIytu0b5KfjaUjtTDAu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lQ29x/btstq9oUqE2/FYhIytu0b5KfjaUjtTDAu1/img.png&quot; data-alt=&quot;저장공간 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lQ29x/btstq9oUqE2/FYhIytu0b5KfjaUjtTDAu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlQ29x%2Fbtstq9oUqE2%2FFYhIytu0b5KfjaUjtTDAu1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1418&quot; height=&quot;654&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;654&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;저장공간 클릭&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;[이 Mac에 관하여] 메뉴 클릭 후 &amp;gt; [추가 정보...] 클릭 &amp;gt; 일반 &amp;gt; 저장공간 에 접근해주세요.&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1410&quot; data-origin-height=&quot;462&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Oa3Bp/btstxkinFJ3/25lBjxCORz8tFXjkitq5hK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Oa3Bp/btstxkinFJ3/25lBjxCORz8tFXjkitq5hK/img.png&quot; data-alt=&quot;개발자 클릭&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Oa3Bp/btstxkinFJ3/25lBjxCORz8tFXjkitq5hK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOa3Bp%2FbtstxkinFJ3%2F25lBjxCORz8tFXjkitq5hK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1410&quot; height=&quot;462&quot; data-origin-width=&quot;1410&quot; data-origin-height=&quot;462&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;개발자 오른쪽에 i 마크를 클릭해줍니다.&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;946&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bknzht/btstxkinGAM/gxML73CW25ENgM2kG90ds1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bknzht/btstxkinGAM/gxML73CW25ENgM2kG90ds1/img.png&quot; data-alt=&quot;캐시 삭제&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bknzht/btstxkinGAM/gxML73CW25ENgM2kG90ds1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbknzht%2FbtstxkinGAM%2FgxML73CW25ENgM2kG90ds1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;946&quot; height=&quot;760&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;760&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;이제 다시 iOS Simulator를 실행해보겠습니다.&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;716&quot; data-origin-height=&quot;1628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GTY10/btstrQbM0a9/L1FkQBnhRXxbHZKA0Z23b0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GTY10/btstrQbM0a9/L1FkQBnhRXxbHZKA0Z23b0/img.png&quot; data-alt=&quot;성공&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GTY10/btstrQbM0a9/L1FkQBnhRXxbHZKA0Z23b0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGTY10%2FbtstrQbM0a9%2FL1FkQBnhRXxbHZKA0Z23b0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;716&quot; height=&quot;1628&quot; data-origin-width=&quot;716&quot; data-origin-height=&quot;1628&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;h3 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;실행 성공 !&lt;/h3&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;057&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/057.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/057.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;</description>
      <category>IT</category>
      <category>Flutter ios simulator</category>
      <category>Flutter ios 시뮬레이터</category>
      <category>flutter Unable to boot simulator</category>
      <category>Flutter 시뮬레이터 에러</category>
      <category>iOS Simulator error</category>
      <category>iOS Simulator fail</category>
      <category>ios simulator not lunching</category>
      <category>iOS Simulator not working</category>
      <category>ios 시뮬레이터 unable</category>
      <category>Unable to boot simulator</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/184</guid>
      <comments>https://javacoding.tistory.com/184#entry184comment</comments>
      <pubDate>Sat, 9 Sep 2023 15:52:28 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS EC2 JDK 17 설치 방법</title>
      <link>https://javacoding.tistory.com/183</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;AWS EC2 인스턴스 설치 후 접속하기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS linux 서버를 기준으로 2023년 9월 기준 설치 방법입니다.&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;1162&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8wJzI/btstzv4ybYA/CMpW2jd4hcW79Qy6eSlpV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8wJzI/btstzv4ybYA/CMpW2jd4hcW79Qy6eSlpV1/img.png&quot; data-alt=&quot;EC2 접속 화면&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8wJzI/btstzv4ybYA/CMpW2jd4hcW79Qy6eSlpV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8wJzI%2Fbtstzv4ybYA%2FCMpW2jd4hcW79Qy6eSlpV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1162&quot; height=&quot;572&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;EC2 접속 화면&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;JDK 다운로드&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버에 접속한 뒤 JDK 설치부터 진행하겠습니다. JDK는 17 버전을 사용할 예정이며 temurin-jdk17을 다운받아보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1694240142445&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo yum install temurin-17-jdk&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;깃허브에서 JDK를 설치할 수 있도록 wget을 먼저 설치합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1694240530089&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo yum -y install wget curl&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;1178&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUAjE9/btstzk9Ndjf/PqSBRpkxnOBclNMfHHjkv0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUAjE9/btstzk9Ndjf/PqSBRpkxnOBclNMfHHjkv0/img.png&quot; data-alt=&quot;wget 설치&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUAjE9/btstzk9Ndjf/PqSBRpkxnOBclNMfHHjkv0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUAjE9%2Fbtstzk9Ndjf%2FPqSBRpkxnOBclNMfHHjkv0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1178&quot; height=&quot;550&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;wget 설치&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;깃허브 주소에서 jdk 17 tar 파일을 바로 다운받습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1694240613135&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;wget https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.2%2B8/OpenJDK17U-jdk_x64_linux_hotspot_17.0.2_8.tar.gz&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;1178&quot; data-origin-height=&quot;738&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bdrGCq/btstw2vvVn8/eHnePlbWJVSqsAcHQSBJ7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bdrGCq/btstw2vvVn8/eHnePlbWJVSqsAcHQSBJ7K/img.png&quot; data-alt=&quot;jdk-17 tar.gz 설치&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bdrGCq/btstw2vvVn8/eHnePlbWJVSqsAcHQSBJ7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbdrGCq%2Fbtstw2vvVn8%2FeHnePlbWJVSqsAcHQSBJ7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1178&quot; height=&quot;738&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;738&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;jdk-17 tar.gz 설치&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tar.gz 파일이 설치되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로 해당 파일 압축을 풀고, 이제 필요없는 .tar.gz 파일은 삭제해주겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1694240755460&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;tar -xvf OpenJDK17U-jdk_x64_linux_hotspot_17.*.tar.gz
rm -f OpenJDK17U-jdk_x64_linux_hotspot_17.*.tar.gz&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;1178&quot; data-origin-height=&quot;340&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ebGJZm/btstyvcDi9Y/veVPLyuycwIto1hB7TgGaK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ebGJZm/btstyvcDi9Y/veVPLyuycwIto1hB7TgGaK/img.png&quot; data-alt=&quot;JDK 17 설치 완료&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ebGJZm/btstyvcDi9Y/veVPLyuycwIto1hB7TgGaK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FebGJZm%2FbtstyvcDi9Y%2FveVPLyuycwIto1hB7TgGaK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1178&quot; height=&quot;340&quot; data-origin-width=&quot;1178&quot; data-origin-height=&quot;340&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;JDK 17 설치 완료&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;JDK 17 설치가 완료되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Java 경로를 지정하고 HOME_PATH를 지정해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1694240892888&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# JDK 경로 이동
sudo mv jdk-17.* /opt/jdk-17

# HOME_PATH 설정
vi ~/.bashrc
export JAVA_HOME=/opt/jdk-17
export PATH=$PATH:$JAVA_HOME/bin

# 저장 파일 반영
source ~/.bashrc&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치된 자바 HOME_PATH를 적용하기 위해 ~/.bashrc 파일을 열고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 export 2줄을 추가해줍니다. 설정 저장을 위해 파일 저장 후 source ~/.bashrc 명령을 실행해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설정 후 java -version 명령으로 확인해보면 아래와 같이 JDK-17 버전이 설정된 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1524&quot; data-origin-height=&quot;334&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cH59Zb/btsts1KIWYt/ll2uMujDywK4sifXjCfF1k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cH59Zb/btsts1KIWYt/ll2uMujDywK4sifXjCfF1k/img.png&quot; data-alt=&quot;JDK-17 설치 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cH59Zb/btsts1KIWYt/ll2uMujDywK4sifXjCfF1k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcH59Zb%2Fbtsts1KIWYt%2Fll2uMujDywK4sifXjCfF1k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1524&quot; height=&quot;334&quot; data-origin-width=&quot;1524&quot; data-origin-height=&quot;334&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;JDK-17 설치 확인&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 style=&quot;text-align: center;&quot; data-ke-size=&quot;size23&quot;&gt;JDK 17 설치가 완료되었습니다 !&lt;/h3&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;057&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/057.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/057.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;</description>
      <category>IT</category>
      <category>AWS EC2 자바 설치</category>
      <category>AWS JAVA 설치</category>
      <category>AWS JDK 설치</category>
      <category>AWS JDK17</category>
      <category>EC2 JAVA</category>
      <category>EC2 JDK 설치</category>
      <category>EC2 JDK17</category>
      <category>Linux JDK17 Install</category>
      <category>Linux JDK17 설치</category>
      <category>temurin jdk 17</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/183</guid>
      <comments>https://javacoding.tistory.com/183#entry183comment</comments>
      <pubDate>Sat, 9 Sep 2023 15:37:38 +0900</pubDate>
    </item>
    <item>
      <title>[AWS RDS] AWS 프리티어 RDS MariaDB 구성하기</title>
      <link>https://javacoding.tistory.com/182</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;AWS RDS를 사용할 일이 간혹 있었지만 매번 생성할 때마다 진행 순서대로 요약된 글을 찾으며 시간 보내는게 아까워서 기록해두려고 한다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;i&gt;AWS RDS 프리티어를 사용하는 이유?&lt;/i&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;- 토이프로젝트 혹은 개인 프로젝트를 진행하면서 DB 서버를 구성할 때, 수익화가 되지 않은 서비스를 유지하기 위해 서버비용을 지불하는것은 돈이 아깝다고 생각한다. 대부분의 개인 프로젝트의 경우 1년 이내에 서비스가 종료되기 때문에 무료에 가까운 비용으로 1,000명 이하가 사용하는 서비스의 DB 서버를 사용한다면 이보다 좋은 선택지는 없다고 생각한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;최근 RDS를 이용해서 구성한 DB서버 유지비용은 월 약 3,000원 정도였다.&lt;br&gt;아직까지 이것보다 좋은 대안은 발견하지 못했다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 130px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;&lt;tbody&gt;&lt;tr style=&quot;height: 20px;&quot;&gt;&lt;td style=&quot;height: 20px;&quot;&gt;RDS&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;단일 AZ db.t2.micro&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;0&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;프리티어&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;height: 20px;&quot;&gt;&lt;td style=&quot;height: 20px;&quot;&gt;RDS&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;DB 스토리지 20GB&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;0&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;프리티어&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;height: 20px;&quot;&gt;&lt;td style=&quot;height: 20px;&quot;&gt;RDS&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;DB 백업용 스토리지 20GB&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;0&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;프리티어&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;height: 20px;&quot;&gt;&lt;td style=&quot;height: 20px;&quot;&gt;기타&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;네트워크 통신 비용 등&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;2,000원&lt;/td&gt;&lt;td style=&quot;height: 20px;&quot;&gt;1년간 프리티어 적용&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;265&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZCNqJ/btstcRhzVSx/PayhuBECbG0Ft7py3HrFm0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZCNqJ/btstcRhzVSx/PayhuBECbG0Ft7py3HrFm0/img.png&quot; data-alt=&quot;RDS 프리티어 지원내용&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZCNqJ/btstcRhzVSx/PayhuBECbG0Ft7py3HrFm0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZCNqJ%2FbtstcRhzVSx%2FPayhuBECbG0Ft7py3HrFm0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;265&quot; height=&quot;375&quot; data-origin-width=&quot;265&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RDS 프리티어 지원내용&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;이제 차근차근 DB를 구성해보자. 2023년 9월 기준으로 AWS RDS를 생성하는 방법을 정리한 글입니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lNGCZ/btstcRIBLo5/okbzk0PeyyLFY0PH2jp9fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lNGCZ/btstcRIBLo5/okbzk0PeyyLFY0PH2jp9fk/img.png&quot; data-alt=&quot;RDS 선택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lNGCZ/btstcRIBLo5/okbzk0PeyyLFY0PH2jp9fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlNGCZ%2FbtstcRIBLo5%2Fokbzk0PeyyLFY0PH2jp9fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1103&quot; height=&quot;522&quot; data-origin-width=&quot;1103&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RDS 선택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;592&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8kyXy/btss90y8YsC/Zb2RkO9oSGvaiNVOzMNd7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8kyXy/btss90y8YsC/Zb2RkO9oSGvaiNVOzMNd7k/img.png&quot; data-alt=&quot;데이터베이스 생성 버튼&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8kyXy/btss90y8YsC/Zb2RkO9oSGvaiNVOzMNd7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8kyXy%2Fbtss90y8YsC%2FZb2RkO9oSGvaiNVOzMNd7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1098&quot; height=&quot;592&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;592&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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DPimN/btstmtTqjrN/ZB6cbXlqlqLVDffGLCD8fk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DPimN/btstmtTqjrN/ZB6cbXlqlqLVDffGLCD8fk/img.png&quot; data-alt=&quot;MariaDB 선택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DPimN/btstmtTqjrN/ZB6cbXlqlqLVDffGLCD8fk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDPimN%2FbtstmtTqjrN%2FZB6cbXlqlqLVDffGLCD8fk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;774&quot; height=&quot;810&quot; data-origin-width=&quot;774&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MariaDB 선택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;엔진은 MariaDB를 선택해줍니다.&lt;/p&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;i&gt;MariaDB를 선택한 이유?&lt;/i&gt;&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;- 쿼리 문법이 동일하게 사용은 동일하지만 속도 및 성능, 안정성에서 더 최적화되었다고 합니다. AWS에 기재된 내용이니 자세한 내용은 아래 링크를 참고하길 바랍니다.&lt;br&gt;&lt;a href=&quot;https://aws.amazon.com/ko/compare/the-difference-between-mariadb-vs-mysql/&quot; target=&quot;_blank&quot;&gt;&lt;span&gt;https://aws.amazon.com/ko/compare/the-difference-between-mariadb-vs-mysql/&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;MariaDB와 MySQL 비교 - 오픈 소스 관계형 데이터베이스 간의 차이점 - AWS&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;MySQL과 MariaDB는 모두 오픈 소스 데이터베이스 기술입니다. 이들 데이터베이스를 사용하여 행과 열이 있는 표 형식으로 데이터를 저장할 수 있습니다. MySQL은 가장 널리 채택된 오픈 소스 데이터&quot; data-og-host=&quot;aws.amazon.com&quot; data-og-source-url=&quot;https://aws.amazon.com/ko/compare/the-difference-between-mariadb-vs-mysql/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c3hSTT/hyTSukHrLb/y5HxRFtJyBePOZjsGA8HMk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/iBfpS/hyTSwW6LqC/nDR016W3d9naq8v2ZTL0K1/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/djd7KQ/hyTSqbwtyR/lvFtQZCeISsyws85HxseJk/img.png?width=1245&amp;amp;height=511&amp;amp;face=0_0_1245_511&quot; data-og-url=&quot;https://aws.amazon.com/ko/compare/the-difference-between-mariadb-vs-mysql/&quot;&gt;&lt;a href=&quot;https://aws.amazon.com/ko/compare/the-difference-between-mariadb-vs-mysql/&quot; target=&quot;_blank&quot; data-source-url=&quot;https://aws.amazon.com/ko/compare/the-difference-between-mariadb-vs-mysql/&quot;&gt;&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c3hSTT/hyTSukHrLb/y5HxRFtJyBePOZjsGA8HMk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/iBfpS/hyTSwW6LqC/nDR016W3d9naq8v2ZTL0K1/img.png?width=179&amp;amp;height=109&amp;amp;face=0_0_179_109,https://scrap.kakaocdn.net/dn/djd7KQ/hyTSqbwtyR/lvFtQZCeISsyws85HxseJk/img.png?width=1245&amp;amp;height=511&amp;amp;face=0_0_1245_511')&quot;&gt; &lt;/div&gt;&lt;div class=&quot;og-text&quot;&gt;&lt;p class=&quot;og-title&quot;&gt;MariaDB와 MySQL 비교 - 오픈 소스 관계형 데이터베이스 간의 차이점 - AWS&lt;/p&gt;&lt;p class=&quot;og-desc&quot;&gt;MySQL과 MariaDB는 모두 오픈 소스 데이터베이스 기술입니다. 이들 데이터베이스를 사용하여 행과 열이 있는 표 형식으로 데이터를 저장할 수 있습니다. MySQL은 가장 널리 채택된 오픈 소스 데이터&lt;/p&gt;&lt;p class=&quot;og-host&quot;&gt;aws.amazon.com&lt;/p&gt;&lt;/div&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;783&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TPGm9/btstlny8gKL/kBMDaFsGkGHTtGgjKZE04k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TPGm9/btstlny8gKL/kBMDaFsGkGHTtGgjKZE04k/img.png&quot; data-alt=&quot;MySQL vs MariaDB 비교&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TPGm9/btstlny8gKL/kBMDaFsGkGHTtGgjKZE04k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTPGm9%2Fbtstlny8gKL%2FkBMDaFsGkGHTtGgjKZE04k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;856&quot; height=&quot;783&quot; data-origin-width=&quot;856&quot; data-origin-height=&quot;783&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;MySQL vs MariaDB 비교&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;357&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MoHrw/btstfSz40ux/p9eYk4fPyM0YQoCNN408H1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MoHrw/btstfSz40ux/p9eYk4fPyM0YQoCNN408H1/img.png&quot; data-alt=&quot;프리티어 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MoHrw/btstfSz40ux/p9eYk4fPyM0YQoCNN408H1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMoHrw%2FbtstfSz40ux%2Fp9eYk4fPyM0YQoCNN408H1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;357&quot; data-origin-width=&quot;751&quot; data-origin-height=&quot;357&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프리티어 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프리티어를 선택해줍니다. AWS 프리티어 서비스는 정말 최고의 서비스입니다.  &lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;759&quot; data-origin-height=&quot;775&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/3pPLU/btstfloU2Px/KAxmA7UCqk9EUqIhXmi1Mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/3pPLU/btstfloU2Px/KAxmA7UCqk9EUqIhXmi1Mk/img.png&quot; data-alt=&quot;DB 기본계정 정보 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/3pPLU/btstfloU2Px/KAxmA7UCqk9EUqIhXmi1Mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F3pPLU%2FbtstfloU2Px%2FKAxmA7UCqk9EUqIhXmi1Mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;759&quot; height=&quot;775&quot; data-origin-width=&quot;759&quot; data-origin-height=&quot;775&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DB 기본계정 정보 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qwdKQ/btstbbtE3RR/XK1Cs97OfcwpLuEd5qwps0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qwdKQ/btstbbtE3RR/XK1Cs97OfcwpLuEd5qwps0/img.png&quot; data-alt=&quot;인스턴스 선택&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qwdKQ/btstbbtE3RR/XK1Cs97OfcwpLuEd5qwps0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqwdKQ%2FbtstbbtE3RR%2FXK1Cs97OfcwpLuEd5qwps0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;742&quot; height=&quot;466&quot; data-origin-width=&quot;742&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인스턴스 선택&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;626&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cW7m0Y/btstlkh8vtq/iDrSELMbpqaDRbqDAslZYk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cW7m0Y/btstlkh8vtq/iDrSELMbpqaDRbqDAslZYk/img.png&quot; data-alt=&quot;스토리지 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cW7m0Y/btstlkh8vtq/iDrSELMbpqaDRbqDAslZYk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcW7m0Y%2Fbtstlkh8vtq%2FiDrSELMbpqaDRbqDAslZYk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;626&quot; data-origin-width=&quot;744&quot; data-origin-height=&quot;626&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;스토리지 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스토리지는 20GB까지는 무료이므로 20GB로 선택해줍니다. 기본 최대 스토리지 임계값이 1000으로 되어있지만, 불필요 과금을 막기위해 저는 100GB로 설정했습니다. 개인프로젝트의 경우 스토리지 자동조절 기능도 보통 꺼두지만 저는 서비스 유연성을 위해 켜두었습니다&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;758&quot; data-origin-height=&quot;691&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bWiNLY/btss91riApc/uWiSmSv6xDuh9FkLpS1ywk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bWiNLY/btss91riApc/uWiSmSv6xDuh9FkLpS1ywk/img.png&quot; data-alt=&quot;연결 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bWiNLY/btss91riApc/uWiSmSv6xDuh9FkLpS1ywk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbWiNLY%2Fbtss91riApc%2FuWiSmSv6xDuh9FkLpS1ywk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;758&quot; height=&quot;691&quot; data-origin-width=&quot;758&quot; data-origin-height=&quot;691&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연결 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;EC2와 같이 사용한다면 'EC2 컴퓨팅 리소스에 연결'을 선택하시면 됩니다.&lt;br&gt;저는 RDS만을 구성하는 것이므로 연결 안함을 선택했습니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;699&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qsWRZ/btstfS1a3Zd/eZ8Ev3bMMLP9dwESBclpJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qsWRZ/btstfS1a3Zd/eZ8Ev3bMMLP9dwESBclpJ0/img.png&quot; data-alt=&quot;퍼블릭 액세스, 보안그룹 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qsWRZ/btstfS1a3Zd/eZ8Ev3bMMLP9dwESBclpJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqsWRZ%2FbtstfS1a3Zd%2FeZ8Ev3bMMLP9dwESBclpJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;757&quot; height=&quot;699&quot; data-origin-width=&quot;757&quot; data-origin-height=&quot;699&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;퍼블릭 액세스, 보안그룹 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #212529;&quot;&gt;퍼블릭 액세스는 '아니요'를 설정하면 내부에서만 DB 접근이 가능합니다. 저는 외부 API 서버에서 사용할 예정이므로 '예'를 선택했습니다. 다양한 DB 툴을 통해 접근하거나 개발시 IntelliJ에서 접근하려는 경우 '예'를 선택해야합니다.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #212529;&quot;&gt;+ 가용영역은 서울 리전을 사용하신다면 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #212529;&quot;&gt;&lt;b&gt;ap-northeast-2a&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;span style=&quot;color: #212529;&quot;&gt; 로 선택하면 됩니다.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lyJIu/btstcPxgtdR/OJkdmmqMP0kDjV0yyLKQg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lyJIu/btstcPxgtdR/OJkdmmqMP0kDjV0yyLKQg1/img.png&quot; data-alt=&quot;데이터베이스 기본 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lyJIu/btstcPxgtdR/OJkdmmqMP0kDjV0yyLKQg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlyJIu%2FbtstcPxgtdR%2FOJkdmmqMP0kDjV0yyLKQg1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;740&quot; height=&quot;610&quot; data-origin-width=&quot;740&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;데이터베이스 기본 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB를 실행시킬, DB 접속에 사용할 포트를 선택합니다. 이전에 설정한 계정/암호로 접근할 것이기 때문에 암호 인증을 선택해줍니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddNd4l/btstgfIH6TK/k0vv2nwqWCJjUq44itb7p1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddNd4l/btstgfIH6TK/k0vv2nwqWCJjUq44itb7p1/img.png&quot; data-alt=&quot;데이터베이스 추가 구성 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddNd4l/btstgfIH6TK/k0vv2nwqWCJjUq44itb7p1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddNd4l%2FbtstgfIH6TK%2Fk0vv2nwqWCJjUq44itb7p1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;749&quot; height=&quot;714&quot; data-origin-width=&quot;749&quot; data-origin-height=&quot;714&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;데이터베이스 추가 구성 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB 인스턴스 생성시 기본으로 생성할 database가 있다면 생성해줍니다.&lt;br&gt;그외 나머지 아래 값들은 기본으로 생성, 불필요한 모니터링 옵션들은 모두 비활성화 했습니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;730&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/csTkyp/btstkViC1jT/pcggDa750mPvxuz5t6P600/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/csTkyp/btstkViC1jT/pcggDa750mPvxuz5t6P600/img.png&quot; data-alt=&quot;DB 인스턴스 생성 확인창&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/csTkyp/btstkViC1jT/pcggDa750mPvxuz5t6P600/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcsTkyp%2FbtstkViC1jT%2FpcggDa750mPvxuz5t6P600%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;766&quot; height=&quot;730&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;730&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DB 인스턴스 생성 확인창&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;데이터베이스 생성 직전에 월별 추정 요금을 보고 식겁하시는 분들이 많이 계실거라고 보이는데요.&lt;br&gt;프리티어로 1년동안은 월 2,000 ~ 3,000원 정도의 요금으로 이용 가능하니 걱정하지 말고 데이터베이스를 생성하면 됩니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1381&quot; data-origin-height=&quot;184&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmvpcK/btstfnfT85e/KFMxzHab8PbZP0CoccxiN1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmvpcK/btstfnfT85e/KFMxzHab8PbZP0CoccxiN1/img.png&quot; data-alt=&quot;생성된 DB 인스턴스&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmvpcK/btstfnfT85e/KFMxzHab8PbZP0CoccxiN1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdmvpcK%2FbtstfnfT85e%2FKFMxzHab8PbZP0CoccxiN1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1381&quot; height=&quot;184&quot; data-origin-width=&quot;1381&quot; data-origin-height=&quot;184&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;생성된 DB 인스턴스&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 인스턴스 생성에는 성공했습니다.&lt;br&gt;추가적으로 보안그룹 설정 및 인코딩, DBMS 기준 서버시간 설정을 진행하도록 하겠습니다.&lt;br&gt;불필요한 설정은 하지 않아도 되지만 기본적으로 자주 설정하는 옵션들에 대한 설정 방법들입니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;추가 설정 1) 보안그룹 설정&lt;/h4&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;불필요한 외부 접근을 막기 위해 보안그룹을 설정해야 한다. 이는 사용자의 목적에 따라 다르지만 DB에 접근할 본인의 연결에 대한 정보만 허용하고 나머지는 허용하지 않도록 설정하면 된다.&lt;br&gt;&amp;nbsp;&lt;br&gt;보안그룹 수정을 위해 RDS 인스턴스를 클릭하고 보안 그룹을 선택하여 수정 화면으로 이동한다.&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;438&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oujIe/btstePqfd5Y/QYri4oR1sEN4XvvIdrqxoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oujIe/btstePqfd5Y/QYri4oR1sEN4XvvIdrqxoK/img.png&quot; data-alt=&quot;보안그룹 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oujIe/btstePqfd5Y/QYri4oR1sEN4XvvIdrqxoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoujIe%2FbtstePqfd5Y%2FQYri4oR1sEN4XvvIdrqxoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;438&quot; data-origin-width=&quot;400&quot; data-origin-height=&quot;438&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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1931&quot; data-origin-height=&quot;602&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b3UgR1/btsteNsqxkx/8tDMAAgMkC3oNK1GSkkV81/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b3UgR1/btsteNsqxkx/8tDMAAgMkC3oNK1GSkkV81/img.png&quot; data-alt=&quot;인바운드 규칙 편집&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b3UgR1/btsteNsqxkx/8tDMAAgMkC3oNK1GSkkV81/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb3UgR1%2FbtsteNsqxkx%2F8tDMAAgMkC3oNK1GSkkV81%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1931&quot; height=&quot;602&quot; data-origin-width=&quot;1931&quot; data-origin-height=&quot;602&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인바운드 규칙 편집&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보안그룹 선택 &amp;gt; 인바운드 규칙 &amp;gt; 인바운드 규칙 편집 클릭 후 접근 허용할 목록을 입력 후 저장해주면 된다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;h4 data-ke-size=&quot;size20&quot;&gt;추가 설정 2) 파라미터 그룹 설정&lt;/h4&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;463&quot; data-origin-height=&quot;713&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKruzy/btstmIJJG3K/gmrQwVVeg6dGB1KDch2g31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKruzy/btstmIJJG3K/gmrQwVVeg6dGB1KDch2g31/img.png&quot; data-alt=&quot;파라미터 그룹&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKruzy/btstmIJJG3K/gmrQwVVeg6dGB1KDch2g31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKruzy%2FbtstmIJJG3K%2FgmrQwVVeg6dGB1KDch2g31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;463&quot; height=&quot;713&quot; data-origin-width=&quot;463&quot; data-origin-height=&quot;713&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;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1153&quot; data-origin-height=&quot;362&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mOkPe/btstcPc1IeU/bXaEm4znRR1Kva0kKusZP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mOkPe/btstcPc1IeU/bXaEm4znRR1Kva0kKusZP1/img.png&quot; data-alt=&quot;파라미터 그룹 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mOkPe/btstcPc1IeU/bXaEm4znRR1Kva0kKusZP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmOkPe%2FbtstcPc1IeU%2FbXaEm4znRR1Kva0kKusZP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1153&quot; height=&quot;362&quot; data-origin-width=&quot;1153&quot; data-origin-height=&quot;362&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파라미터 그룹 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;524&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c63oRX/btstlL7Mcmd/AeNGPLlE27ecEKi3sbthrk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c63oRX/btstlL7Mcmd/AeNGPLlE27ecEKi3sbthrk/img.png&quot; data-alt=&quot;파라미터 그룹 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c63oRX/btstlL7Mcmd/AeNGPLlE27ecEKi3sbthrk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc63oRX%2FbtstlL7Mcmd%2FAeNGPLlE27ecEKi3sbthrk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;812&quot; height=&quot;524&quot; data-origin-width=&quot;812&quot; data-origin-height=&quot;524&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파라미터 그룹 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDS 인스턴스 생성시 선택한 타입과 버전을 선택합니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1397&quot; data-origin-height=&quot;374&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bDQbBN/btstksATM1V/zEpHqtzAdZcQ7S5ZMWdEHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bDQbBN/btstksATM1V/zEpHqtzAdZcQ7S5ZMWdEHK/img.png&quot; data-alt=&quot;파라미터 그룹 편집&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bDQbBN/btstksATM1V/zEpHqtzAdZcQ7S5ZMWdEHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbDQbBN%2FbtstksATM1V%2FzEpHqtzAdZcQ7S5ZMWdEHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1397&quot; height=&quot;374&quot; data-origin-width=&quot;1397&quot; data-origin-height=&quot;374&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파라미터 그룹 편집&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파라미터 그룹이 생성되면 [편집]을 클릭해서 설정을 추가하도록 하겠습니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;591&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zpuFL/btstlkoVYF5/YJvk2KxPCIWewrFCKrnCKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zpuFL/btstlkoVYF5/YJvk2KxPCIWewrFCKrnCKk/img.png&quot; data-alt=&quot;timezone 설정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zpuFL/btstlkoVYF5/YJvk2KxPCIWewrFCKrnCKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzpuFL%2FbtstlkoVYF5%2FYJvk2KxPCIWewrFCKrnCKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1097&quot; height=&quot;591&quot; data-origin-width=&quot;1097&quot; data-origin-height=&quot;591&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;timezone 설정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제일 먼저 timezone 설정입니다. Asia/Seoul로 설정했습니다.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1133&quot; data-origin-height=&quot;685&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GEmzW/btstazuJzZa/5GaHwKJrVbjYQUPbkYbBNK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GEmzW/btstazuJzZa/5GaHwKJrVbjYQUPbkYbBNK/img.png&quot; data-alt=&quot;인코딩 설정-1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GEmzW/btstazuJzZa/5GaHwKJrVbjYQUPbkYbBNK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGEmzW%2FbtstazuJzZa%2F5GaHwKJrVbjYQUPbkYbBNK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1133&quot; height=&quot;685&quot; data-origin-width=&quot;1133&quot; data-origin-height=&quot;685&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인코딩 설정-1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;453&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ba96o2/btstmrVC2je/hfBPgxvvhio4NjNJulBUJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ba96o2/btstmrVC2je/hfBPgxvvhio4NjNJulBUJ1/img.png&quot; data-alt=&quot;인코딩 설정 - 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ba96o2/btstmrVC2je/hfBPgxvvhio4NjNJulBUJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fba96o2%2FbtstmrVC2je%2FhfBPgxvvhio4NjNJulBUJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1070&quot; height=&quot;453&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;453&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;인코딩 설정 - 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두번째는 DB 인코딩 설정입니다. utf8mb4는 기본 문자, 한글 외에도 이모지와 같은 UTF-8 기준 모든 문자열 데이터를 저장할 수 있습니다. utf8mb4로 설정해주었습니다.&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;775&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eNImOO/btstg14Ds04/e5rq1TQBjUqqQsSdWwXS0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eNImOO/btstg14Ds04/e5rq1TQBjUqqQsSdWwXS0k/img.png&quot; data-alt=&quot;collation 수정 - 1&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eNImOO/btstg14Ds04/e5rq1TQBjUqqQsSdWwXS0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeNImOO%2Fbtstg14Ds04%2Fe5rq1TQBjUqqQsSdWwXS0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1088&quot; height=&quot;775&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;775&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;collation 수정 - 1&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;775&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B9Ern/btstg14Dtbh/BPEVMCdk4Htj4tv0rEIEOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B9Ern/btstg14Dtbh/BPEVMCdk4Htj4tv0rEIEOk/img.png&quot; data-alt=&quot;collation 수정 - 2&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B9Ern/btstg14Dtbh/BPEVMCdk4Htj4tv0rEIEOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB9Ern%2Fbtstg14Dtbh%2FBPEVMCdk4Htj4tv0rEIEOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1088&quot; height=&quot;775&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;775&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;collation 수정 - 2&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 설정 후 저장한다.&lt;br&gt;&amp;nbsp;&lt;br&gt;저장한 다음에는 DB 인스턴스에 해당 파라미터 설정을 적용해주어야 한다.&lt;br&gt;아래와 같이 [수정] 버튼 클릭 후 설정한 파라미터 그룹과 인스턴스를 연결해준뒤 설정 적용을 위해 재부팅을 진행해주자.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1134&quot; data-origin-height=&quot;356&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/odwnW/btstktmfdhG/KqwkFgVkV6K88sQTHC6Hhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/odwnW/btstktmfdhG/KqwkFgVkV6K88sQTHC6Hhk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/odwnW/btstktmfdhG/KqwkFgVkV6K88sQTHC6Hhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FodwnW%2FbtstktmfdhG%2FKqwkFgVkV6K88sQTHC6Hhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1134&quot; height=&quot;356&quot; data-origin-width=&quot;1134&quot; data-origin-height=&quot;356&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;714&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cjj17m/btstbclNW72/i5mRLvLy9WWLhJNYiUnhC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cjj17m/btstbclNW72/i5mRLvLy9WWLhJNYiUnhC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cjj17m/btstbclNW72/i5mRLvLy9WWLhJNYiUnhC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcjj17m%2FbtstbclNW72%2Fi5mRLvLy9WWLhJNYiUnhC0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;714&quot; height=&quot;298&quot; data-origin-width=&quot;714&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&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;i&gt;이제 기본 구성은 끝났다 !&lt;/i&gt;&lt;/h3&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;IntelliJ에서 Database를 연결해보자.&lt;/i&gt;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;664&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/doKI08/btstcOkU33Y/K9JIdzoRG042qHnWvYd1DK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/doKI08/btstcOkU33Y/K9JIdzoRG042qHnWvYd1DK/img.png&quot; data-alt=&quot;DB 접속&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/doKI08/btstcOkU33Y/K9JIdzoRG042qHnWvYd1DK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdoKI08%2FbtstcOkU33Y%2FK9JIdzoRG042qHnWvYd1DK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1098&quot; height=&quot;664&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;664&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DB 접속&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;273&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8v6ys/btstkrBYoks/4jSL3HGs0f1mfFJnye5lj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8v6ys/btstkrBYoks/4jSL3HGs0f1mfFJnye5lj0/img.png&quot; data-alt=&quot;엔드포인트 확인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8v6ys/btstkrBYoks/4jSL3HGs0f1mfFJnye5lj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8v6ys%2FbtstkrBYoks%2F4jSL3HGs0f1mfFJnye5lj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;255&quot; height=&quot;273&quot; data-origin-width=&quot;255&quot; data-origin-height=&quot;273&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;엔드포인트 확인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDS 엔드포인트 및 포트정보를 확인해서 작성해주자.&lt;br&gt;&amp;nbsp;&lt;/p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;1114&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1QZu4/btstfPpRfeK/wrtJ1dRkRioKFfmRJBkiiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1QZu4/btstfPpRfeK/wrtJ1dRkRioKFfmRJBkiiK/img.png&quot; data-alt=&quot;연결 성공&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1QZu4/btstfPpRfeK/wrtJ1dRkRioKFfmRJBkiiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1QZu4%2FbtstfPpRfeK%2FwrtJ1dRkRioKFfmRJBkiiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1594&quot; height=&quot;1114&quot; data-origin-width=&quot;1594&quot; data-origin-height=&quot;1114&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;연결 성공&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;br&gt;연결에 성공했다. 이제 외부에서 RDS로 구성한 DB에 접근하여 사용하도록 하자.&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;br&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>AWS</category>
      <category>AWS Database</category>
      <category>AWS DMBS</category>
      <category>AWS ec2</category>
      <category>AWS MariaDB</category>
      <category>aws mysql</category>
      <category>AWS RDB</category>
      <category>AWS RDS</category>
      <category>아마존 MySQL</category>
      <category>아마존 RDS</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/182</guid>
      <comments>https://javacoding.tistory.com/182#entry182comment</comments>
      <pubDate>Wed, 6 Sep 2023 23:39:08 +0900</pubDate>
    </item>
    <item>
      <title>점메추 사이트</title>
      <link>https://javacoding.tistory.com/180</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;text-align: center;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;아래 이미지를 클릭하여 점메추 사이트에 접속이 가능합니다.&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-26 오후 10.00.04.png&quot; data-origin-width=&quot;1371&quot; data-origin-height=&quot;735&quot;&gt;&lt;a href=&quot;http://15.165.124.38:8080&quot; target=&quot;_blank&quot; title=&quot;점메추 사이트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIIpyR/btsFlQiLjNA/k6vXaH1NAySMCluUkWywJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIIpyR%2FbtsFlQiLjNA%2Fk6vXaH1NAySMCluUkWywJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1371&quot; height=&quot;735&quot; data-filename=&quot;스크린샷 2024-02-26 오후 10.00.04.png&quot; data-origin-width=&quot;1371&quot; data-origin-height=&quot;735&quot;/&gt;&lt;/a&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;한식, 일식, 중식, 양식, 분식, 아시안, 디저트 다양한 점심 메뉴 추천 사이트입니다.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>맛집</category>
      <category>메뉴 추천</category>
      <category>점메추</category>
      <category>점심</category>
      <category>점심 메뉴 추천</category>
      <category>점심메뉴</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/180</guid>
      <comments>https://javacoding.tistory.com/180#entry180comment</comments>
      <pubDate>Mon, 3 Apr 2023 12:51:10 +0900</pubDate>
    </item>
    <item>
      <title>JAVA HttpClient와 CloseableHttpClient 차이점</title>
      <link>https://javacoding.tistory.com/179</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Java에서 HTTP API를 개발하기 위해 HttpClient를 자주 사용했었는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CloseableHttpClient&lt;/b&gt; 클래스가 새롭게 등장했다고 해서 처음 알게되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CloseableHttpClient&lt;/b&gt; 클래스는 Apache HttpClient 4.3 이상에서 새롭게 추가된 클래스로, &lt;b&gt;HttpClient&lt;/b&gt; 클래스의 문제점을 개선하여 구현이 간편하고 메모리 누수 등의 문제가 해결되었다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서, 새로운 프로젝트에서는 &lt;b&gt;CloseableHttpClient&lt;/b&gt; 클래스를 사용하는 것이 권고되고 있는데, 기존의 &lt;b&gt;HttpClient&lt;/b&gt; 클래스와의 차이점을 정리해보면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;생성 방식&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DefaultHttpClient: HttpClient 인스턴스를 생성하는 것이 가능한 방법 중 가장 기본적인 방식입니다.&lt;/li&gt;
&lt;li&gt;CloseableHttpClient: DefaultHttpClient의 기능을 확장하여 HttpClient 인스턴스의 생성을 지원하며, 각 Connection의 자원을 안정적으로 관리할 수 있는 메소드를 제공합니다.&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;close 메소드 사용 여부&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DefaultHttpClient: close 메소드를 제공하지 않습니다.&lt;/li&gt;
&lt;li&gt;CloseableHttpClient: close 메소드를 제공하여 HttpClient 인스턴스의 연결을 닫을 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예제&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;CloseableHttpClient httpClient = HttpClients.createDefault();
try {
  HttpGet httpGet = new HttpGet(&quot;&amp;lt;http://www.google.com&amp;gt;&quot;);
  CloseableHttpResponse response = httpClient.execute(httpGet);
  // Do something with response
} finally {
  httpClient.close();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTTP 통신 가능 회수&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DefaultHttpClient: HTTP 통신을 계속 할 수 있습니다.&lt;/li&gt;
&lt;li&gt;CloseableHttpClient: 각 Connection을 제대로 닫지 않으면 일정 횟수 이상 HTTP 통신이 불가능 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Connection Pool 사용 여부&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DefaultHttpClient와 CloseableHttpClient 모두 Connection Pool 기능을 제공&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT/Web</category>
      <category>CloseableHttpClient</category>
      <category>CloseableHttpResponse</category>
      <category>DefaultHttpClient</category>
      <category>httpclient</category>
      <category>JAVA HTTP API 개발</category>
      <category>Java HTTP Request</category>
      <category>JAVA HTTP 요청</category>
      <category>Spring boot HTTP 요청</category>
      <category>Spring boot HttpClient</category>
      <category>자바 HTTP 요청</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/179</guid>
      <comments>https://javacoding.tistory.com/179#entry179comment</comments>
      <pubDate>Fri, 3 Feb 2023 13:54:18 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 배열 두 배 만들기 JAVA</title>
      <link>https://javacoding.tistory.com/178</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;배열 두 배 만들기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수배열 numbers가 매개변수로 주어집니다. numbers의 각 원소에 두배한 원소를 가진 배열을 return하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;제한 사항&lt;/span&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;-10,000 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;numbers의 원소 &amp;le; 10,000&lt;/li&gt;
&lt;li&gt;1 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;numbers의 길이 &amp;le; 1,000&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 62.907%; height: 106px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 30.7397%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;numbers&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 38.2007%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 30.7397%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;[1, 2, 3, 4, 5]&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 38.2007%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;[2, 4, 6, 8, 10]&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 30.7397%; height: 17px;&quot;&gt;[1, 2, 100, -99, 1, 2, 3]&lt;/td&gt;
&lt;td style=&quot;width: 38.2007%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;[2, 4, 200, -198, 2, 4, 6]&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;&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;입출력 예 #1&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;[1, 2, 3, 4, 5]의 각 원소에 두배를 한 배열 [2, 4, 6, 8, 10]을 return합니다.&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;[1, 2, 100, -99, 1, 2, 3]의 각 원소에 두배를 한 배열 [2, 4, 200, -198, 2, 4, 6]을 return합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;009&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;문제 접근 방식&lt;/u&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for 반복문을 사용해 풀이하면 된다고 생각했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665733009424&quot; class=&quot;angelscript&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public int[] solution(int[] numbers) {
        for(int i = 0; i &amp;lt; numbers.length; i++) {
            numbers[i] *= 2;
        }
        return numbers;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;055&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span&gt;문제 풀이&lt;/span&gt;&lt;/b&gt;&lt;/u&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;for 반복문을 주어진 numbers 배열의 길이만큼 반복하며 각 요소에 2를 곱한 결과를 저장해주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;friends2&quot; data-emoticon-name=&quot;015&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends2/large/015.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends2/large/015.png&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;고수의 풀이&lt;/u&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;저는 for 반복문을 사용했지만, java 8 문법인 Stream을 사용하면 더 간결한 코드로 정답을 찾을 수 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stream의 map 메소드에서 각 요소인 i에 i*2해준 값들을 Array로 만들어 return 해주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665732944757&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;

class Solution {
    public int[] solution(int[] numbers) {
        return Arrays.stream(numbers).map(i -&amp;gt; i * 2).toArray();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;295&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8SPO9/btrOBrCFdqv/6Ze90KnCVZHjy8kLqpXsK0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8SPO9/btrOBrCFdqv/6Ze90KnCVZHjy8kLqpXsK0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8SPO9/btrOBrCFdqv/6Ze90KnCVZHjy8kLqpXsK0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8SPO9%2FbtrOBrCFdqv%2F6Ze90KnCVZHjy8kLqpXsK0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;295&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;295&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120807&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/120807&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665732721368&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120807&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mwelV/hyP9w06XUz/kOZpktF8RV7D4JQToVhVTk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/Cx3aS/hyP9tXDfFP/1xjKWbSe8d9oLpxiQtUINk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120807&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120807&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mwelV/hyP9w06XUz/kOZpktF8RV7D4JQToVhVTk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/Cx3aS/hyP9tXDfFP/1xjKWbSe8d9oLpxiQtUINk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&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;programmers.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>알고리즘 연습/Lv.0</category>
      <category>Java 기초</category>
      <category>java 알고리즘</category>
      <category>JAVA 코테</category>
      <category>programmers</category>
      <category>배열 두 배 만들기</category>
      <category>배열 두 배 만들기 java</category>
      <category>알고리즘 기초</category>
      <category>프로그래머스</category>
      <category>프로그래머스 java</category>
      <category>프로그래머스 lv0</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/178</guid>
      <comments>https://javacoding.tistory.com/178#entry178comment</comments>
      <pubDate>Fri, 14 Oct 2022 16:42:31 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 숫자 비교하기 JAVA</title>
      <link>https://javacoding.tistory.com/177</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;숫자 비교하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수 num1과 num2가 매개변수로 주어집니다. 두 수가 같으면 1 다르면 -1을 return 하도록 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;제한 사항&lt;/span&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;0 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 10,000&lt;/li&gt;
&lt;li&gt;0 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 10,000&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 57.907%; height: 44px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num1&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num2&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;-1&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;11&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;11&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 39.5564%;&quot;&gt;&lt;span&gt;&lt;span&gt;7&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%;&quot;&gt;&lt;span&gt;&lt;span&gt;99&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%;&quot;&gt;&lt;span&gt;&lt;span&gt;-1&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;&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;입출력 예 #1&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;num1이 10,&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 5이므로 10을 5로 나눈 몫 2를 return 합니다.&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;num1이 7,&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 2이므로 7을 2로 나눈 몫 3을 return 합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;009&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;문제 접근 방식&lt;/u&gt;&lt;/h3&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665672434340&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public int solution(int num1, int num2) {
        return num1 == num2 ? 1 : -1;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;055&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span&gt;문제 풀이&lt;/span&gt;&lt;/b&gt;&lt;/u&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;삼항 연산자를 이용해 같을 경우(==) 1을 return하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같지 않을 경우(다른 경우)에 -1을 return 하도록 해주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bt5nUq/btrOwngcASu/1Z2hKtDynkdZqDYxOZdkV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bt5nUq/btrOwngcASu/1Z2hKtDynkdZqDYxOZdkV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bt5nUq/btrOwngcASu/1Z2hKtDynkdZqDYxOZdkV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbt5nUq%2FbtrOwngcASu%2F1Z2hKtDynkdZqDYxOZdkV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;208&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120807&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/120807&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665672530940&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120807&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mwelV/hyP9w06XUz/kOZpktF8RV7D4JQToVhVTk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/Cx3aS/hyP9tXDfFP/1xjKWbSe8d9oLpxiQtUINk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120807&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120807&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mwelV/hyP9w06XUz/kOZpktF8RV7D4JQToVhVTk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/Cx3aS/hyP9tXDfFP/1xjKWbSe8d9oLpxiQtUINk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&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;programmers.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>알고리즘 연습/Lv.0</category>
      <category>Java 기초</category>
      <category>java 알고리즘</category>
      <category>JAVA 코테</category>
      <category>programmers</category>
      <category>숫자 비교하기</category>
      <category>숫자 비교하기 java</category>
      <category>알고리즘 기초</category>
      <category>프로그래머스</category>
      <category>프로그래머스 java</category>
      <category>프로그래머스 lv0</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/177</guid>
      <comments>https://javacoding.tistory.com/177#entry177comment</comments>
      <pubDate>Thu, 13 Oct 2022 23:49:28 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조] Java ArrayList 알아보기</title>
      <link>https://javacoding.tistory.com/176</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/169&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;2022.10.08 - [IT/자료구조] - [자료구조] 배열(Array)의 개념&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665582307090&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;[자료구조] 배열(Array)의 개념&quot; data-og-description=&quot;오늘은 자료구조에서 가장 기본으로 다루는 배열에 대해 정리해보겠습니다. 배열이란? 같은 타입의 변수들로 이루어진 유한 집합 배열은 같은 종류의 데이터를 다뤄야 하는 경우에 사용할 수 &quot; data-og-host=&quot;javacoding.tistory.com&quot; data-og-source-url=&quot;https://javacoding.tistory.com/169&quot; data-og-url=&quot;https://javacoding.tistory.com/169&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BxFEI/hyP78teT2C/686rkmFMRTBfGSfSeGZn71/img.png?width=600&amp;amp;height=211&amp;amp;face=0_0_600_211,https://scrap.kakaocdn.net/dn/yHq5B/hyP72s0jeR/TEspJFSkFZWnJYoBssbMkk/img.png?width=600&amp;amp;height=211&amp;amp;face=0_0_600_211,https://scrap.kakaocdn.net/dn/hd8Az/hyP78Uif2j/o1SRuGmHkt5kxXf3rTUux1/img.png?width=600&amp;amp;height=211&amp;amp;face=0_0_600_211&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/169&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://javacoding.tistory.com/169&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BxFEI/hyP78teT2C/686rkmFMRTBfGSfSeGZn71/img.png?width=600&amp;amp;height=211&amp;amp;face=0_0_600_211,https://scrap.kakaocdn.net/dn/yHq5B/hyP72s0jeR/TEspJFSkFZWnJYoBssbMkk/img.png?width=600&amp;amp;height=211&amp;amp;face=0_0_600_211,https://scrap.kakaocdn.net/dn/hd8Az/hyP78Uif2j/o1SRuGmHkt5kxXf3rTUux1/img.png?width=600&amp;amp;height=211&amp;amp;face=0_0_600_211');&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;[자료구조] 배열(Array)의 개념&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;javacoding.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ArrayList 개념&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;550&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9f5nU/btrOsaT3M7z/0QKOScGAhXx0jyxXpGjEv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9f5nU/btrOsaT3M7z/0QKOScGAhXx0jyxXpGjEv1/img.png&quot; data-alt=&quot;ArrayList 사용 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9f5nU/btrOsaT3M7z/0QKOScGAhXx0jyxXpGjEv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9f5nU%2FbtrOsaT3M7z%2F0QKOScGAhXx0jyxXpGjEv1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;550&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;550&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ArrayList 사용 예시&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;지난번 배열에 이어 두 번째 자료구조로 Array와 비슷한 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;ArrayList&lt;/span&gt;&lt;/b&gt;에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 가장 큰 특징 중 하나는 크기가 고정된다는 것입니다. 배열을 생성할 때 사용할 크기를 알고 있다면 배열을 사용하는 것이 속도나 메모리 사용의 측면에서 이점이 되겠지만&amp;nbsp;사용할 배열의 크기를 알지 못하거나 수정이 필요한 경우에는 &lt;u&gt;&lt;b&gt;가변적인 배열&lt;/b&gt;&lt;/u&gt;이 필요하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴때 적합한 자료구조가 바로 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;ArrayList&lt;/b&gt;&lt;/span&gt;입니다. 가장 큰 특징은 크기가 &lt;span style=&quot;color: #006dd7;&quot;&gt;가변적&lt;/span&gt;이라는 것인데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&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;blockquote data-ke-size=&quot;size16&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;b&gt;ArrayList&lt;/b&gt;를 가장 잘 표현할 수 있는 단어는 &lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;dynamic array&lt;/span&gt; 또는 &lt;span style=&quot;color: #006dd7;&quot;&gt;resizable array&lt;/span&gt; 라고 할 수 있습니다.&lt;/span&gt;&lt;/blockquote&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;ArrayList 구현&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IMSUS/btrOtGZirsq/hEazWpx4cjN5nPoYcf5jbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IMSUS/btrOtGZirsq/hEazWpx4cjN5nPoYcf5jbk/img.png&quot; data-alt=&quot;ArrayList 상속 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IMSUS/btrOtGZirsq/hEazWpx4cjN5nPoYcf5jbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIMSUS%2FbtrOtGZirsq%2FhEazWpx4cjN5nPoYcf5jbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;957&quot; height=&quot;408&quot; data-origin-width=&quot;957&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ArrayList 상속 구조&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ArrayList는 Java Collection 프레임워크의 클래스입니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ArrayList 특징&lt;/h2&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;기본적으로 삽입한 순서가 보장됩니다. (index 지정 추가/삭제한 경우 제외)&lt;/li&gt;
&lt;li&gt;Collection 인스턴스입니다.&lt;/li&gt;
&lt;li&gt;래퍼 클래스로만 사용 가능합니다. (기본 클래스(ex - int, char...)는 사용 불가능)&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;&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://www.javatpoint.com/arraylist-implementation-in-java&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.javatpoint.com/arraylist-implementation-in-java&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://marcus-biel.com/arraylist/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://marcus-biel.com/arraylist&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kjhoon0330.tistory.com/m/entry/Java-ArrayList%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%81%AC%EA%B8%B0%EA%B0%80-%EA%B0%80%EB%B3%80%EC%A0%81%EC%9D%BC%EA%B9%8C&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kjhoon0330.tistory.com/m/entry/Java-ArrayList%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%ED%81%AC%EA%B8%B0%EA%B0%80-%EA%B0%80%EB%B3%80%EC%A0%81%EC%9D%BC%EA%B9%8C&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/자료구조</category>
      <category>ArrayList</category>
      <category>ArrayList java</category>
      <category>ArrayList 개념</category>
      <category>ArrayList 구조</category>
      <category>java arraylist</category>
      <category>java List</category>
      <category>알고리즘</category>
      <category>자료구조</category>
      <category>자바 arraylist</category>
      <category>자바 리스트</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/176</guid>
      <comments>https://javacoding.tistory.com/176#entry176comment</comments>
      <pubDate>Wed, 12 Oct 2022 23:57:15 +0900</pubDate>
    </item>
    <item>
      <title>용인 역북 솥뚜껑 삽겹살 읏듬 (고기 존맛)</title>
      <link>https://javacoding.tistory.com/175</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;용인 역북동 주민 n년차의 추천글&lt;br /&gt;: 스타벅스 위에 고기집이 새로 생겨 방문해보았습니다   (미리말하자면 성공적)&lt;br /&gt;통유리로 되어있어 멀리서봐도 잘보이더라구요!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bHgA9B/btrOe98Oz43/vagDvDAF2AzYTu9vS2FKbK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bHgA9B/btrOe98Oz43/vagDvDAF2AzYTu9vS2FKbK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bHgA9B/btrOe98Oz43/vagDvDAF2AzYTu9vS2FKbK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbHgA9B%2FbtrOe98Oz43%2FvagDvDAF2AzYTu9vS2FKbK%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;3024&quot; height=&quot;4032&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; 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;3024&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oHD7g/btrN79ve3Hk/32EJMjgUU4YO3WkYkR0Q7k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oHD7g/btrN79ve3Hk/32EJMjgUU4YO3WkYkR0Q7k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oHD7g/btrN79ve3Hk/32EJMjgUU4YO3WkYkR0Q7k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoHD7g%2FbtrN79ve3Hk%2F32EJMjgUU4YO3WkYkR0Q7k%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;3024&quot; height=&quot;3024&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; 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;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BEe8F/btrN5auVeLL/G5elMIHf6RSKX4Yh4zGpdk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BEe8F/btrN5auVeLL/G5elMIHf6RSKX4Yh4zGpdk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BEe8F/btrN5auVeLL/G5elMIHf6RSKX4Yh4zGpdk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBEe8F%2FbtrN5auVeLL%2FG5elMIHf6RSKX4Yh4zGpdk%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;3024&quot; height=&quot;4032&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;요집의 특이점은 전통주를 판다는 것!&lt;br /&gt;전통주의 가격은 메뉴판에 나와있지 않아 아쉬웠지만&lt;br /&gt;주종이 다양해서 한번쯤 도전해볼만 한거같습니다ㅋ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/trpNm/btrOeRUHyD5/HzmumMQUtrtXjbqEPZpWmK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/trpNm/btrOeRUHyD5/HzmumMQUtrtXjbqEPZpWmK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/trpNm/btrOeRUHyD5/HzmumMQUtrtXjbqEPZpWmK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtrpNm%2FbtrOeRUHyD5%2FHzmumMQUtrtXjbqEPZpWmK%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;3024&quot; height=&quot;3024&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;반찬은 다양해서 좋았어요   (맛도 있음)&lt;br /&gt;고기는 셀프로 굽는 방식이고&lt;br /&gt;다 구워갈때쯤 김치, 고사리, 콩나물을&lt;br /&gt;같이 구워드시라고 말씀해주셨습니다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9wjKC/btrOhX7WZBm/iTcQGIgm2KfUQL3sj9AGBK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9wjKC/btrOhX7WZBm/iTcQGIgm2KfUQL3sj9AGBK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9wjKC/btrOhX7WZBm/iTcQGIgm2KfUQL3sj9AGBK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9wjKC%2FbtrOhX7WZBm%2FiTcQGIgm2KfUQL3sj9AGBK%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;3024&quot; height=&quot;3024&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;전체적으로 상이 넓어서 자리가 널널한게&lt;br /&gt;너어어무 좋았어요 ㅋㅋ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/S35qH/btrOfblfqkH/5wDYYrlKnza4giKo1XDNX1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/S35qH/btrOfblfqkH/5wDYYrlKnza4giKo1XDNX1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/S35qH/btrOfblfqkH/5wDYYrlKnza4giKo1XDNX1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FS35qH%2FbtrOfblfqkH%2F5wDYYrlKnza4giKo1XDNX1%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;3024&quot; height=&quot;3024&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;폭탄계란찜(4.0)&lt;br /&gt;누구나 다 아는 그 계란찜 맛ㅋㅋ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WP2nF/btrN5bUSlMT/DmTaaEHnwPzlerVWEFSd11/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WP2nF/btrN5bUSlMT/DmTaaEHnwPzlerVWEFSd11/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WP2nF/btrN5bUSlMT/DmTaaEHnwPzlerVWEFSd11/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWP2nF%2FbtrN5bUSlMT%2FDmTaaEHnwPzlerVWEFSd11%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;3024&quot; height=&quot;3024&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;이렇게 가격표를 같이 붙여서 주시더라구요!&lt;br /&gt;저희는 처음에&lt;br /&gt;읏듬 삽겹살(15.0)&lt;br /&gt;읏듬 특전지(10.0)&lt;br /&gt;시켰구요 다먹고 특전지 하나 더시켰습니다&lt;br /&gt;(특전지 저렴해서 기대안했는데 존맛임)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lgfyC/btrN5w5xVdQ/TUQn20eHn3zlR2GKElMVT1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lgfyC/btrN5w5xVdQ/TUQn20eHn3zlR2GKElMVT1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lgfyC/btrN5w5xVdQ/TUQn20eHn3zlR2GKElMVT1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlgfyC%2FbtrN5w5xVdQ%2FTUQn20eHn3zlR2GKElMVT1%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;3024&quot; height=&quot;4032&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;솥뚜껑이라 그런지 아주 빨리&lt;br /&gt;맛있게 잘 익어주었습니다 ㅎㅎ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/biERuY/btrN8zU2zR2/k7WbVuX12uPh3X3uYLaJSk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/biERuY/btrN8zU2zR2/k7WbVuX12uPh3X3uYLaJSk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/biERuY/btrN8zU2zR2/k7WbVuX12uPh3X3uYLaJSk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbiERuY%2FbtrN8zU2zR2%2Fk7WbVuX12uPh3X3uYLaJSk%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;3024&quot; height=&quot;4032&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;고기 질은 좋은거 같아요!&lt;br /&gt;특히 전지 진짜 부들부들&lt;br /&gt;씹는거 안좋아하는 사람은 무조건 시키세요 (저에요)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kFREg/btrN9q4FYn1/i0SuWKkDXRQWqUZKjThQBk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kFREg/btrN9q4FYn1/i0SuWKkDXRQWqUZKjThQBk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kFREg/btrN9q4FYn1/i0SuWKkDXRQWqUZKjThQBk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkFREg%2FbtrN9q4FYn1%2Fi0SuWKkDXRQWqUZKjThQBk%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;3024&quot; height=&quot;4032&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;소주 2000원 행사해서 2병 조져주었어요&lt;br /&gt;2병먹고 4000원 개꿀&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ububQ/btrOgSyXp8a/nrmqfEgFiaQvqBmUlroNs1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ububQ/btrOgSyXp8a/nrmqfEgFiaQvqBmUlroNs1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ububQ/btrOgSyXp8a/nrmqfEgFiaQvqBmUlroNs1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FububQ%2FbtrOgSyXp8a%2FnrmqfEgFiaQvqBmUlroNs1%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;3024&quot; height=&quot;3024&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;볶음밥 하나 더 시켜서 마무리했습니다&lt;br /&gt;고기랑 볶음밥 꼭 같이드세요&lt;br /&gt;죤맛이니까&amp;hellip;&amp;hellip; &lt;br /&gt;&lt;br /&gt;정보가 없어 소신껏 작성해본 글입니다 ㅋㅋ&lt;br /&gt;물론 광고 네버X이구요&lt;br /&gt;역북동에서 맛있는거 같이 먹어요  &lt;br /&gt;(계산하고 나와서 10분만에 쓰는 글입니다ㅋㅋ)&lt;/p&gt;</description>
      <category>맛집</category>
      <category>솥뚜껑삼겹살</category>
      <category>역북 맛집</category>
      <category>역북 웃듬</category>
      <category>역북 읏듬</category>
      <category>역북동 맛집</category>
      <category>역북동 읏듬</category>
      <category>웃듬</category>
      <category>읏듬</category>
      <category>읏듬 고기</category>
      <category>읏듬 삼겹살</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/175</guid>
      <comments>https://javacoding.tistory.com/175#entry175comment</comments>
      <pubDate>Mon, 10 Oct 2022 20:17:51 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 나머지 구하기 JAVA</title>
      <link>https://javacoding.tistory.com/174</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;나머지 구하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정수 num1, num2가 매개변수로 주어질 때, num1을 num2로 나눈 나머지를 return 하도록 solution 함수를 완성해주세요&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;b&gt;&lt;span&gt;제한 사항&lt;/span&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;0 &amp;lt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 100&lt;/li&gt;
&lt;li&gt;0 &amp;lt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 100&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 57.907%; height: 44px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num1&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num2&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;0&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;&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;입출력 예 #1&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;num1이 3,&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 2이므로 3을 2로 나눈 나머지 1을 return 합니다.&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;num1이 10,&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 5이므로 10을 5로 나눈 나머지 0을 return 합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;009&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;문제 접근 방식&lt;/u&gt;&lt;/h3&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665365125291&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public int solution(int num1, int num2) {
        return num1 % num2;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;055&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span&gt;문제 풀이&lt;/span&gt;&lt;/b&gt;&lt;/u&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;num1과 num2가 입력으로 주어지므로 바로 나머지 연산 결과를 return 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;217&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LDkW7/btrN40Z0D8F/UBPVUf6W5iCe65pNo651K0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LDkW7/btrN40Z0D8F/UBPVUf6W5iCe65pNo651K0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LDkW7/btrN40Z0D8F/UBPVUf6W5iCe65pNo651K0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLDkW7%2FbtrN40Z0D8F%2FUBPVUf6W5iCe65pNo651K0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;217&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;217&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;출처 :&lt;span&gt;&lt;span&gt;&lt;span&gt; &lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120810&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/120810&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665365179355&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120810&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/il6bE/hyP4DUU7XP/ck9oUnrk8yzKUuKBCjDpx0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bUi1DQ/hyP6ExRXoE/dtDXxjAFP4c7W3zjPp6fLk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120810&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120810&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/il6bE/hyP4DUU7XP/ck9oUnrk8yzKUuKBCjDpx0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/bUi1DQ/hyP6ExRXoE/dtDXxjAFP4c7W3zjPp6fLk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&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;programmers.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;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습/Lv.0</category>
      <category>Java 기초</category>
      <category>java 알고리즘</category>
      <category>JAVA 코테</category>
      <category>programmers</category>
      <category>나머지 구하기</category>
      <category>나머지 구하기 java</category>
      <category>알고리즘 기초</category>
      <category>코딩테스트 기초</category>
      <category>프로그래머스</category>
      <category>프로그래머스 lv0</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/174</guid>
      <comments>https://javacoding.tistory.com/174#entry174comment</comments>
      <pubDate>Mon, 10 Oct 2022 10:27:11 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 몫 구하기 JAVA</title>
      <link>https://javacoding.tistory.com/173</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;몫 구하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정수 num1과 num2가 매개변수로 주어질 때, num1을 num2로 나눈 몫을 return 하도록 solution 함수를 완성해주세요&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;b&gt;&lt;span&gt;제한 사항&lt;/span&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;0 &amp;lt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 100&lt;/li&gt;
&lt;li&gt;0 &amp;lt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 100&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 57.907%; height: 44px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num1&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num2&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;7&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;3&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;&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;입출력 예 #1&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;num1이 10,&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 5이므로 10을 5로 나눈 몫 2를 return 합니다.&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;num1이 7,&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 2이므로 7을 2로 나눈 몫 3을 return 합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;009&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;문제 접근 방식&lt;/u&gt;&lt;/h3&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665245938825&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public int solution(int num1, int num2) {
        return num1 / num2;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;055&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span&gt;문제 풀이&lt;/span&gt;&lt;/b&gt;&lt;/u&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;num1과 num2가 입력으로 주어지므로 바로 나눗셈 결과를 return 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/di77p8/btrN8AyB0iA/97TarQN9ztytndaoWKgUa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/di77p8/btrN8AyB0iA/97TarQN9ztytndaoWKgUa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/di77p8/btrN8AyB0iA/97TarQN9ztytndaoWKgUa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdi77p8%2FbtrN8AyB0iA%2F97TarQN9ztytndaoWKgUa0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;208&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;출처 :&lt;span&gt;&lt;span&gt; &lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120805&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/120805&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665245864638&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120805&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bGlZQv/hyP4Hu30Qi/204iQkZD8cZKqnZ5XkbfGk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/x82qU/hyP4ykAfDU/Sp7sZM0LzywmJDBl4Nkbyk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120805&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120805&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bGlZQv/hyP4Hu30Qi/204iQkZD8cZKqnZ5XkbfGk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/x82qU/hyP4ykAfDU/Sp7sZM0LzywmJDBl4Nkbyk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&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;programmers.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>알고리즘 연습/Lv.0</category>
      <category>Java 기초</category>
      <category>java 알고리즘</category>
      <category>JAVA 코테</category>
      <category>programmers</category>
      <category>몫 구하기</category>
      <category>몫 구하기 java</category>
      <category>알고리즘 기초</category>
      <category>프로그래머스</category>
      <category>프로그래머스 java</category>
      <category>프로그래머스 lv0</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/173</guid>
      <comments>https://javacoding.tistory.com/173#entry173comment</comments>
      <pubDate>Sun, 9 Oct 2022 01:19:03 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 두 수의 곱 JAVA</title>
      <link>https://javacoding.tistory.com/172</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;두 수의 곱&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정수 num1, num2가 매개변수로 주어집니다. num1과 num2를 곱한 값을 return 하도록 solution 함수를 완성해주세요.&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;b&gt;&lt;span&gt;제한 사항&lt;/span&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;0 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 100&lt;/li&gt;
&lt;li&gt;0 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 100&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 57.907%; height: 44px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num1&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num2&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;12&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;27&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;19&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;513&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;&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;입출력 예 #1&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;num1이 3,&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 4이므로 3 * 4 = 12를 return합니다.&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;num1이 27,&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 19이므로 27 * 19 = 513을 return합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;009&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;문제 접근 방식&lt;/u&gt;&lt;/h3&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;pre id=&quot;code_1665245631804&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public int solution(int num1, int num2) {
        return num1 * num2;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;055&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span&gt;문제 풀이&lt;/span&gt;&lt;/b&gt;&lt;/u&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;num1과 num2가 입력으로 주어지므로 바로 곱셈 결과를 return 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEVG3A/btrN6nTRBxc/YYCg9NKKUF9ecj1auW94gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEVG3A/btrN6nTRBxc/YYCg9NKKUF9ecj1auW94gK/img.png&quot; data-alt=&quot;최종 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEVG3A/btrN6nTRBxc/YYCg9NKKUF9ecj1auW94gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEVG3A%2FbtrN6nTRBxc%2FYYCg9NKKUF9ecj1auW94gK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;208&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;최종 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;출처 :&lt;span&gt;&lt;span&gt; &lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120804&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/120804&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665245668076&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120804&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/edFrBD/hyP4Hu2AqK/O12V5gxBMfp1STShKWNpa0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/lWymj/hyP4D7eUdy/b7YSEgcliJKGy7WK1AUf6K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120804&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120804&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/edFrBD/hyP4Hu2AqK/O12V5gxBMfp1STShKWNpa0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/lWymj/hyP4D7eUdy/b7YSEgcliJKGy7WK1AUf6K/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&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;programmers.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>알고리즘 연습/Lv.0</category>
      <category>Java 기초</category>
      <category>java 알고리즘</category>
      <category>JAVA 코테</category>
      <category>programmers</category>
      <category>두 수의 곱</category>
      <category>두 수의 곱 java</category>
      <category>알고리즘 기초</category>
      <category>프로그래머스</category>
      <category>프로그래머스 java</category>
      <category>프로그래머스 lv0</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/172</guid>
      <comments>https://javacoding.tistory.com/172#entry172comment</comments>
      <pubDate>Sun, 9 Oct 2022 01:15:23 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 두 수의 차 JAVA</title>
      <link>https://javacoding.tistory.com/171</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;두 수의 차&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정수 num1과 num2가 주어질 때, num1에서 num2를 뺀 값을 return 하도록 solution 함수를 완성해주세요.&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;b&gt;&lt;span&gt;제한 사항&lt;/span&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;-50000 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 50000&lt;/li&gt;
&lt;li&gt;-50000 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 50000&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 57.907%; height: 44px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num1&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num2&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;-1&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;100&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;98&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;&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;입출력 예 #1&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;num1이 2이고&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 3이므로 2 - 3 = -1을 return합니다.&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;num1이 100이고&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 2이므로 100 - 2 = 98을 return합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;009&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;문제 접근 방식&lt;/u&gt;&lt;/h3&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 data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1665245347221&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public int solution(int num1, int num2) {
        return num1 - num2;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;055&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span&gt;문제 풀이&lt;/span&gt;&lt;/b&gt;&lt;/u&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;num1과 num2가 입력으로 주어지므로 바로 뺄셈 결과를 return 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NHl9C/btrN4lbUNd4/NOxYJ7fzTU6dt9NyZ6NTWk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NHl9C/btrN4lbUNd4/NOxYJ7fzTU6dt9NyZ6NTWk/img.png&quot; data-alt=&quot;최종 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NHl9C/btrN4lbUNd4/NOxYJ7fzTU6dt9NyZ6NTWk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNHl9C%2FbtrN4lbUNd4%2FNOxYJ7fzTU6dt9NyZ6NTWk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;208&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;최종 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;출처 :&lt;span&gt;&lt;span&gt; &lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120803&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/120803&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665245409696&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120803&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/p9Xil/hyP4Jl30Sv/5MerlrnNyFKVoqzpQ535B0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/c11pPZ/hyP4D7dVfe/7mWfdabKH0VVfRRNRw2cAk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120803&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120803&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/p9Xil/hyP4Jl30Sv/5MerlrnNyFKVoqzpQ535B0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/c11pPZ/hyP4D7dVfe/7mWfdabKH0VVfRRNRw2cAk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&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;programmers.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>알고리즘 연습/Lv.0</category>
      <category>Java 기초</category>
      <category>java 알고리즘</category>
      <category>JAVA 코테</category>
      <category>programmers</category>
      <category>두 수의 차</category>
      <category>두 수의 차 java</category>
      <category>알고리즘 기초</category>
      <category>프로그래머스</category>
      <category>프로그래머스 java</category>
      <category>프로그래머스 lv0</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/171</guid>
      <comments>https://javacoding.tistory.com/171#entry171comment</comments>
      <pubDate>Sun, 9 Oct 2022 01:10:36 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 두 수의 합 JAVA</title>
      <link>https://javacoding.tistory.com/170</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;&lt;b&gt;두 수의 합&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정수 num1과 num2가 주어질 때, num1과 num2의 합을 return 하도록 solution 함수를 완성해주세요.&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;b&gt;&lt;span&gt;제한 사항&lt;/span&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;-50,000 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num1&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 50,000&lt;/li&gt;
&lt;li&gt;-50,000 &amp;le;&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;le; 50,000&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 57.907%; height: 44px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style8&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num1&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;num2&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;result&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 10px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 10px;&quot;&gt;&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 39.5564%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;100&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 35.7304%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.21%; height: 17px;&quot;&gt;&lt;span&gt;&lt;span&gt;102&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;&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;입출력 예 #1&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;num1이 2이고&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 3이므로 2 + 3 = 5를 return합니다.&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;num1이 100이고&lt;span&gt;&amp;nbsp;&lt;/span&gt;num2가 2이므로 100 + 2 = 102를 return합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;009&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/009.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;문제 접근 방식&lt;/u&gt;&lt;/h3&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;pre id=&quot;code_1665244755882&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public int solution(int num1, int num2) {
        return num1 + num2;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;055&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/large/055.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;u&gt;&lt;b&gt;&lt;span&gt;문제 풀이&lt;/span&gt;&lt;/b&gt;&lt;/u&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;num1과 num2가 입력으로 주어지므로 바로 덧셈 결과를 return 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mciLS/btrN4Pjd7w4/Lknhmhlv71flmGwYLwH4Y1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mciLS/btrN4Pjd7w4/Lknhmhlv71flmGwYLwH4Y1/img.png&quot; data-alt=&quot;최종 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mciLS/btrN4Pjd7w4/Lknhmhlv71flmGwYLwH4Y1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmciLS%2FbtrN4Pjd7w4%2FLknhmhlv71flmGwYLwH4Y1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;208&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;208&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;최종 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;출처 :&lt;span&gt; &lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120802&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/120802&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665244837608&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;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120802&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/prcYU/hyP4C8h0nH/lWI5Lx6BmDRZceqXlR1QgK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/diRK2s/hyP4GizfFT/ZgHYrSutFfzP9NKM2tKNmK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120802&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120802&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/prcYU/hyP4C8h0nH/lWI5Lx6BmDRZceqXlR1QgK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/diRK2s/hyP4GizfFT/ZgHYrSutFfzP9NKM2tKNmK/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&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;programmers.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>알고리즘 연습/Lv.0</category>
      <category>Java 기초</category>
      <category>java 알고리즘</category>
      <category>JAVA 코테</category>
      <category>programmers</category>
      <category>두 수의 합</category>
      <category>두 수의 합 java</category>
      <category>알고리즘 기초</category>
      <category>프로그래머스</category>
      <category>프로그래머스 java</category>
      <category>프로그래머스 lv0</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/170</guid>
      <comments>https://javacoding.tistory.com/170#entry170comment</comments>
      <pubDate>Sun, 9 Oct 2022 01:03:40 +0900</pubDate>
    </item>
    <item>
      <title>[자료구조] 배열(Array)의 개념</title>
      <link>https://javacoding.tistory.com/169</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 자료구조에서 가장 기본으로 다루는 배열에 대해 정리해보겠습니다.&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;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR'; color: #f89009;&quot;&gt;같은 타입의 변수들로 이루어진 유한 집합&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgXhqc/btrN4xpwYbC/Rb0kVxwmAlHIk35nvbAaCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgXhqc/btrN4xpwYbC/Rb0kVxwmAlHIk35nvbAaCK/img.png&quot; data-alt=&quot;배열의 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgXhqc/btrN4xpwYbC/Rb0kVxwmAlHIk35nvbAaCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgXhqc%2FbtrN4xpwYbC%2FRb0kVxwmAlHIk35nvbAaCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;212&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;211&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;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;같은 종류의 데이터&lt;/span&gt;&lt;/b&gt;를 다뤄야 하는 경우에 사용할 수 있는 가장 기본적인 자료구조 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 건 int 데이터를 모으는 int 배열, String 데이터를 모으는 String 배열처럼 같은 자료형 데이터들만 담을 수 있습니다.&lt;/p&gt;
&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: #006dd7;&quot;&gt;element&lt;/span&gt;&lt;/b&gt;라고 하며, 배열에서의 위치를 가리키는 숫자를 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;index&lt;/b&gt;&lt;/span&gt;라고 합니다. 자바에서 인덱스는 언제나 0부터 시작하며, &lt;u&gt;0을 포함한 양의 정수&lt;/u&gt;만을 가질 수 있습니다.&lt;/p&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차원 배열, 2차원 배열, 3차원 배열 등 다차원 배열로 선언이 가능하지만 현실적으로 이해하기 쉬운 2차원 배열까지가 주로 사용됩니다.&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;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;Java의 모든 배열은 &lt;span style=&quot;color: #f89009;&quot;&gt;동적으로 할당&lt;/span&gt;됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;동적 할당&lt;/span&gt; : 실행 시간(Runtime) 동안 사용할 공간을 힙(heap) 메모리에 할당하는 것을 말합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;배열의 크기&lt;/span&gt;는 &lt;span style=&quot;color: #f89009;&quot;&gt;정수값&lt;/span&gt;으로만 지정할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;배열의 변수는 순서가 지정되며 &lt;span style=&quot;color: #f89009;&quot;&gt;0부터 시작하는 인덱스&lt;/span&gt;를 가집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;배열에 n개의 데이터가 존재할 때 인덱스 번호는 [0 ~ n-1]으로 순차적임.&lt;br /&gt;인덱스도 정수값임.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;배열의 &lt;span style=&quot;color: #f89009;&quot;&gt;크기는 초기화되면 변경할 수 없습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;배열의 크기를 실시간으로 변경할 수 없지만 다른 배열을 가리키도록 만들 순 있음.&lt;br /&gt;다른 크기의 배열을 사용하기 위해서는 새 배열을 만들어 할당해야 함.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;다차원 배열 구현이 가능합니다. (보통 2차원 이상은 잘 사용하지 않음)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;가장 큰 특징은 &lt;span style=&quot;color: #f89009;&quot;&gt;순차적으로 데이터를 저장&lt;/span&gt;한다는 것입니다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;index&lt;/span&gt;를 사용해 &lt;span style=&quot;color: #f89009;&quot;&gt;특정 요소에 바로 접근&lt;/span&gt;이 가능한 것이 배열의 주요 장점입니다.&lt;br /&gt;&lt;br /&gt;순차적으로 존재하는 데이터 중간 요소를 삽입 또는 삭제하는 경우에는 요소 뒤쪽의 데이터들을 모두 한 칸씩 옮겨주어야 하기 때문에 상대적으로 번거롭습니다. &lt;br /&gt;-&amp;gt;&lt;span style=&quot;color: #f89009;&quot;&gt; 잦은 추가, 삭제시 배열 사용은 부적합&lt;/span&gt; 합니다.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;따라서 배열은 주식차트와 같이 &lt;span style=&quot;color: #f89009;&quot;&gt;순서가 주요한 경우에 적합한 자료구조&lt;/span&gt; 입니다.&lt;/blockquote&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;초기화란 잡아놓은 메모리에 값을 채워넣는 것을 말합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&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;1차원 배열은 주로 다음 두 가지 문법에 따라 선언합니다.&lt;/p&gt;
&lt;pre id=&quot;code_1665239825423&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 1. type[] name;
int[] array;

// 2. type name[];
int array[];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 1번의 방법을 사용합니다. 앞으로 예시에서는 모두 1번 방식을 사용하도록 하겠습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;타입&lt;/span&gt;은 배열 요소로 저장되는 &lt;span style=&quot;color: #006dd7;&quot;&gt;변수의 자료형&lt;/span&gt;을 나타냅니다.&lt;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;배열 이름&lt;/span&gt;은 배열이 선언된 후 &lt;span style=&quot;color: #006dd7;&quot;&gt;배열에 접근하기 위해 사용&lt;/span&gt;됩니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배열의 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1665240102848&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 타입[] 배열이름 = new 타입[배열 길이];
int[] array = new int[10];

String[] dayOfWeek = new String[7];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 배열 array는 int 자료형 10개를 담을 수 있는 배열입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 번째 배열 dayOfWeek는 String 자료형 7개를 담을 수 있는 배열입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;배열의 초기화&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: 배열 초기화는 필요한 시기에 따라 다양한 방식으로 이루어질 수 있습니다. 3가지 경우를 간단한 예시와 함께 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 배열 선언과 동시에 초기화&lt;/p&gt;
&lt;pre id=&quot;code_1665241952432&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int[] array = {10, 20, 30};

int[] array2 = new int[]{3, 6, 9};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2) 배열 선언 후 생성과 함께 초기화&lt;/p&gt;
&lt;pre id=&quot;code_1665242067109&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int[] array;
array = new int[]{1,2,3};&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;3) 인덱스를 이용한 접근 후 초기화&lt;/p&gt;
&lt;pre id=&quot;code_1665242277333&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;int[] array = new int[3];

for(int i = 0; i&amp;lt; 3; i++) {
    array[i] = i+1;
}

// array[0] = 1
// array[1] = 2
// array[2] = 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;for 반복문과 배열&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;pre id=&quot;code_1665243140527&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;String[] weeks = {&quot;월요일&quot;, &quot;화요일&quot;, &quot;수요일&quot;, &quot;목요일&quot;, &quot;금요일&quot;, &quot;토요일&quot;, &quot;일요일&quot;};

// 토요일 찾기
for(int i = 0; i&amp;lt; 7; i++) {
    if(weeks[i].equals(&quot;토요일&quot;)) {
        System.out.println(&quot;토요일은 &quot; + (i+1) +&quot;번째!&quot;);
    }
}

// 출력: &quot;토요일은 6번째!&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Array와 ArrayList 비교&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주요 차이점은 다음과 같습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;배열(Array)&lt;/span&gt;은 &lt;span style=&quot;color: #006dd7;&quot;&gt;크기가 고정적&lt;/span&gt;인데 반해 &lt;span style=&quot;color: #f89009;&quot;&gt;ArrayList&lt;/span&gt;는 &lt;span style=&quot;color: #f89009;&quot;&gt;크기가 가변적&lt;/span&gt;입니다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;배열(Array)&lt;/span&gt;는 초기화 시 &lt;span style=&quot;color: #006dd7;&quot;&gt;메모리에 할당되어 속도가 빠르지만&lt;/span&gt;, &lt;span style=&quot;color: #f89009;&quot;&gt;ArrayList&lt;/span&gt;는 &lt;span style=&quot;color: #f89009;&quot;&gt;데이터 추가 및 삭제시&lt;/span&gt; 메모리 재할당이 필요하여 배열에 비해 &lt;span style=&quot;color: #f89009;&quot;&gt;속도가 느립니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Array와 LinkedList 비교&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;span style=&quot;color: #006dd7;&quot;&gt;Array&lt;/span&gt;는 인덱스로 해당 원소에 접근할 수 있어 찾고자 하는 원소의 인덱스를 알고 있다면 &lt;span style=&quot;color: #006dd7;&quot;&gt;O(1)로 접근&lt;/span&gt; 가능&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;삭제시&lt;/span&gt;에는 이후 배열 요소들을 옮겨줘야 하기 때문에 &lt;span style=&quot;color: #006dd7;&quot;&gt;O(n)&lt;/span&gt;의 시간복잡도를 가짐&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&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: #f89009;&quot;&gt;LinkedList&lt;/span&gt;는 각각의 요소들은 자기 자신 다음에 어떤 요소인지만 기억하고 있기 때문에 이 부분을 다른 값으로 바꿔주면 &lt;span style=&quot;color: #f89009;&quot;&gt;O(1)&lt;/span&gt; 비용으로 &lt;span style=&quot;color: #f89009;&quot;&gt;삽입과 삭제&lt;/span&gt;가 가능함&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;원하는 위치에 한 번만 접근&lt;/span&gt;할 수 없다는 단점이 있음. 원하는 위치를 Search하는 과정에 있어서 첫번째 원소부터 다시 확인해봐야 함.&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: #006dd7;&quot;&gt;&lt;b&gt;Array&lt;/b&gt;&lt;/span&gt; -&amp;gt; 검색이 빠르지만 삽입, 삭제는 느림&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;LinkedList&lt;/b&gt;&lt;/span&gt; -&amp;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;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.softwaretestinghelp.com/c-sharp/csharp-arrays/&quot;&gt;https://www.softwaretestinghelp.com/c-sharp/csharp-arrays/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;http://tcpschool.com/java/java_array_oneDimensional&quot;&gt;http://tcpschool.com/java/java_array_oneDimensional&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://dev-coco.tistory.com/159?category=1056309&quot;&gt;https://dev-coco.tistory.com/159?category=1056309&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/자료구조</category>
      <category>array</category>
      <category>java array</category>
      <category>JAVA 배열</category>
      <category>배열</category>
      <category>자료구조</category>
      <category>자바 배열</category>
      <category>자바 배열 for문</category>
      <category>자바 배열 반복문</category>
      <category>자바 배열 선언</category>
      <category>자바 배열 예제</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/169</guid>
      <comments>https://javacoding.tistory.com/169#entry169comment</comments>
      <pubDate>Sat, 8 Oct 2022 23:59:09 +0900</pubDate>
    </item>
    <item>
      <title>[Network] TCP Packet(Segment) 분석</title>
      <link>https://javacoding.tistory.com/168</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/167&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://javacoding.tistory.com/167&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1665104982758&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;[Network] TCP 3 Way Handshaking &amp;amp; 4 Way Handshaking&quot; data-og-description=&quot;https://javacoding.tistory.com/162 TCP란? https://javacoding.tistory.com/160 IP(Internet Protocol) 내가 인터넷을 통해 정보를 원하는 곳으로 전달하고자 할 경우, 도착지를 알아야 한다. 나의 주소와 상대..&quot; data-og-host=&quot;javacoding.tistory.com&quot; data-og-source-url=&quot;https://javacoding.tistory.com/167&quot; data-og-url=&quot;https://javacoding.tistory.com/167&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/btfb6u/hyP2bqNn9E/mmpkJDRxKeXFBC5KcramPK/img.png?width=500&amp;amp;height=390&amp;amp;face=0_0_500_390,https://scrap.kakaocdn.net/dn/d1u9zy/hyP2eOBnns/AyIQAyGmmxwFD6BIg7wMm1/img.png?width=500&amp;amp;height=390&amp;amp;face=0_0_500_390,https://scrap.kakaocdn.net/dn/bjmt9q/hyP2iwGeHa/nb0zcyntRhsmxyTsEmPX3K/img.png?width=500&amp;amp;height=390&amp;amp;face=0_0_500_390&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/167&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://javacoding.tistory.com/167&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/btfb6u/hyP2bqNn9E/mmpkJDRxKeXFBC5KcramPK/img.png?width=500&amp;amp;height=390&amp;amp;face=0_0_500_390,https://scrap.kakaocdn.net/dn/d1u9zy/hyP2eOBnns/AyIQAyGmmxwFD6BIg7wMm1/img.png?width=500&amp;amp;height=390&amp;amp;face=0_0_500_390,https://scrap.kakaocdn.net/dn/bjmt9q/hyP2iwGeHa/nb0zcyntRhsmxyTsEmPX3K/img.png?width=500&amp;amp;height=390&amp;amp;face=0_0_500_390');&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;[Network] TCP 3 Way Handshaking &amp;amp; 4 Way Handshaking&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://javacoding.tistory.com/162 TCP란? https://javacoding.tistory.com/160 IP(Internet Protocol) 내가 인터넷을 통해 정보를 원하는 곳으로 전달하고자 할 경우, 도착지를 알아야 한다. 나의 주소와 상대..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;javacoding.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 글에서 3-way handshake와 4-way handshake에 대해 정리했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버와 클라이언트 간 확인을 위해 &lt;b&gt;SYN&lt;/b&gt;과 &lt;b&gt;ACK&lt;/b&gt;를 주고 받았는데요. 이 정보들은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;패킷(Packet)&lt;/b&gt;에 담아 전송됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 TCP 전송에 이용되는 Packet은 어떤 구조를 갖고 있을까요? 이번 글에서는 TCP 헤더 구조에 대해 알아보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Packet이라는 용어?&lt;/b&gt;&lt;br /&gt;이 글에서는 TCP 통신에 전달되는 데이터를 Packet으로 불렀습니다.&lt;br /&gt;하지만 프로토콜에서 전달되는 데이터는 프로토콜 계층(Layers)마다 부르는 이름이 조금씩 다릅니다.&lt;br /&gt;&lt;br /&gt;전달되는 payload(데이터)는 같지만 앞에 어떤 헤더 정보가 포함되어 있냐에 따라&amp;nbsp;&lt;br /&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;Physical Layer&lt;/b&gt;에서는 &lt;b&gt;&lt;u&gt;Bit&lt;/u&gt;&lt;/b&gt;를 단위로 하고, &lt;br /&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/b&gt;Data Link Layer&lt;/b&gt;에서는 &lt;b&gt;&lt;u&gt;Frame&lt;/u&gt;&lt;/b&gt;이라 하고,&lt;br /&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/b&gt;Network Layer&lt;/b&gt;에서는 &lt;u&gt;&lt;b&gt;Packet&lt;/b&gt;&lt;/u&gt;이라 하고,&lt;br /&gt;&lt;b&gt;&lt;b&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;/b&gt;Transport Layer&lt;/b&gt;에서는 &lt;u&gt;&lt;b&gt;Segment&lt;/b&gt;&lt;/u&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: #666666;&quot;&gt;따라서 오늘 정리해보려고 했던 TCP 데이터 구조는&lt;/span&gt;&lt;br /&gt;&lt;u&gt;발신지 포트, 목적지 포트, 시퀀스 번호&lt;/u&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;등을 포함하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;세그먼트(Segment)&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;라고 부르는 것이 더 정확합니다. &lt;/span&gt;&lt;span style=&quot;color: #666666;&quot;&gt;지금부터는 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;Packet&lt;/span&gt;&lt;/b&gt;이 아닌 TCP &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;Segment&lt;/b&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;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;TCP Segment 구조&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cN1uO1/btrNYTy5n4O/QQLBJcRavyKk621JgrJhak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cN1uO1/btrNYTy5n4O/QQLBJcRavyKk621JgrJhak/img.png&quot; data-alt=&quot;TCP 헤더 구조&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cN1uO1/btrNYTy5n4O/QQLBJcRavyKk621JgrJhak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcN1uO1%2FbtrNYTy5n4O%2FQQLBJcRavyKk621JgrJhak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;212&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;TCP 헤더 구조&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Source port, Destination port&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ct0MSL/btrN1yHnXoj/AI64iXWLeqQZ12KowC5zrK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ct0MSL/btrN1yHnXoj/AI64iXWLeqQZ12KowC5zrK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ct0MSL/btrN1yHnXoj/AI64iXWLeqQZ12KowC5zrK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fct0MSL%2FbtrN1yHnXoj%2FAI64iXWLeqQZ12KowC5zrK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;224&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;224&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Source port&lt;/b&gt; : 송신하는 application 포트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Destination port&lt;/b&gt; : 수신해야 할 application 포트&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출발지와 목적지의 포트 번호 정보를 담는 필드입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주소는 IP 주소와 포트 번호를 사용해서 나타낼 수 있는데, IP 정보는 IP 헤더에 담겨있고 TCP 헤더에는 포트 번호를 나타내는 필드가 존재합니다.&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;Sequence Number&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/2lwCx/btrN0nMWESG/cvCVebWMMgxqKXblmmA7a1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/2lwCx/btrN0nMWESG/cvCVebWMMgxqKXblmmA7a1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/2lwCx/btrN0nMWESG/cvCVebWMMgxqKXblmmA7a1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F2lwCx%2FbtrN0nMWESG%2FcvCVebWMMgxqKXblmmA7a1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;212&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;212&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Sequence number&lt;/b&gt; : TCP 세그먼트의 연속된 데이터 번호입니다.&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;송신측에서 데이터를 전송할 때는 난수를 생성하며 이후 자신이 보낼 데이터 1 bytes당 시퀀스 번호를 1씩 증가시키며 데이터 순서를 표현합니다.&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;Acknowledgment number&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eHsc74/btrN0n8vNKN/XGEL3KGOX4sZV4CaHOHzz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eHsc74/btrN0n8vNKN/XGEL3KGOX4sZV4CaHOHzz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eHsc74/btrN0n8vNKN/XGEL3KGOX4sZV4CaHOHzz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeHsc74%2FbtrN0n8vNKN%2FXGEL3KGOX4sZV4CaHOHzz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;224&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;224&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Acknowledgment number&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 상대방으로부터 받아야 하는 다음 TCP 세그먼트 데이터 번호입니다.&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;ACK number는 연결을 맺거나 해제할 때 3-way, 4-way handshake 과정에서는 &lt;b&gt;상대방이 보낸 시퀀스 번호에 +1&lt;/b&gt;을 자신의 ACK number를 만들어내지만, 실제 데이터를 주고 받을 때에는 &lt;b&gt;상대방이 보낸 시퀀스 번호 + 자신이 받은 데이터의 bytes&lt;/b&gt;로 ACK number를 만들어 냅니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 해당 번호 앞까지 데이터 처리가 완료되어 해당 번호 TCP 세그먼트를 전송해달라는 의미입니다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Q95VO/btrN0penBbW/9ObKaDUyF2tTRdYhkdyswK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Q95VO/btrN0penBbW/9ObKaDUyF2tTRdYhkdyswK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Q95VO/btrN0penBbW/9ObKaDUyF2tTRdYhkdyswK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQ95VO%2FbtrN0penBbW%2F9ObKaDUyF2tTRdYhkdyswK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;600&quot; height=&quot;224&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;224&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;TCP Segment 구조에서 알아보려 했던 Sequence number, ACK number를 제외한 나머지 구조에 대해서는 간략히 정의에 대해서만 정리하도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Data Offset&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 전체 세그먼트 중에서 헤더가 아닌 데이터가 시작되는 위치가 어디인지를 나타냅니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Reversed&lt;/b&gt; : 미래를 위해 예약된 필드로, 모두 0으로 채워져야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Flags&lt;/b&gt; : 현재 세그먼트의 속성을 나타내는 9개의 비트 플래그입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Window Size&lt;/b&gt; : 한번에 전송할 수 있는 데이터의 양을 의미합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Checksum&lt;/b&gt; : 데이터를 송신하는 중에 발생할 수 있는 오류를 검출하기 위한 값입니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Urgent Pointer&lt;/b&gt; : 긴급 포인터입니다. URG 플래그 값이 1이면 수신 측은 이 포인터가 가리키고 있는 데이터를 우선적으로 처리합니다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Options&lt;/b&gt; : TCP의 기능을 확장할 때 사용하는 필드들입니다.&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;&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;TCP의 특징에 대해서 정리해보면서 TCP Segment 구조에 대해서 공부해보게 되었는데, 공부할수록 부족한 부분들이 많이 보이는 것 같다. 조금씩 시간을 내서 네트워크에 대해 공부하는 시간을 갖도록 노력해야겠다.&lt;/p&gt;
&lt;p data-ke-size=&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://evan-moon.github.io/2019/11/10/header-of-tcp/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://evan-moon.github.io/2019/11/10/header-of-tcp/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT/Network</category>
      <category>Packet 구조</category>
      <category>TCP Packet</category>
      <category>TCP packet size</category>
      <category>TCP Packet 구조</category>
      <category>TCP Segment</category>
      <category>TCP sequence number</category>
      <category>TCP 패킷 분석</category>
      <category>패킷 구조</category>
      <category>패킷 전송</category>
      <category>패킷 헤더</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/168</guid>
      <comments>https://javacoding.tistory.com/168#entry168comment</comments>
      <pubDate>Fri, 7 Oct 2022 15:06:56 +0900</pubDate>
    </item>
    <item>
      <title>[Network] TCP 3 Way Handshaking &amp;amp; 4 Way Handshaking</title>
      <link>https://javacoding.tistory.com/167</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;a href=&quot;https://javacoding.tistory.com/162&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://javacoding.tistory.com/162&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;opengraph&quot; data-og-title=&quot;TCP란?&quot; data-ke-align=&quot;alignCenter&quot; data-og-description=&quot;https://javacoding.tistory.com/160 IP(Internet Protocol) 내가 인터넷을 통해 정보를 원하는 곳으로 전달하고자 할 경우, 도착지를 알아야 한다. 나의 주소와 상대의 주소는 어떻게 나타낼 수 있을까? 이때 PC..&quot; data-og-host=&quot;javacoding.tistory.com&quot; data-og-source-url=&quot;https://javacoding.tistory.com/162&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b0j4ag/hyP3Fp2LBx/TKN2jerAV1eqtq2oGxs2vk/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422,https://scrap.kakaocdn.net/dn/cJSw7y/hyP3HOVDYT/2pOIJpr0rah3l4WPSIvlok/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422,https://scrap.kakaocdn.net/dn/whyCm/hyP3DeGHBS/5MkOBDSK2sp5hgrMfaLKm0/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422&quot; data-og-url=&quot;https://javacoding.tistory.com/162&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/162&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://javacoding.tistory.com/162&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b0j4ag/hyP3Fp2LBx/TKN2jerAV1eqtq2oGxs2vk/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422,https://scrap.kakaocdn.net/dn/cJSw7y/hyP3HOVDYT/2pOIJpr0rah3l4WPSIvlok/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422,https://scrap.kakaocdn.net/dn/whyCm/hyP3DeGHBS/5MkOBDSK2sp5hgrMfaLKm0/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422');&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;TCP란?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://javacoding.tistory.com/160 IP(Internet Protocol) 내가 인터넷을 통해 정보를 원하는 곳으로 전달하고자 할 경우, 도착지를 알아야 한다. 나의 주소와 상대의 주소는 어떻게 나타낼 수 있을까? 이때 PC..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;javacoding.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이전에 TCP 프로토콜에 대해 정리하면서 확인한 &lt;b&gt;TCP의 가장 뚜렷한 특징중 하나&lt;/b&gt;는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;신뢰성&lt;/b&gt;&lt;/span&gt;이었습니다.&lt;br /&gt;TCP에서는 어떻게 송, 수신시에 신뢰성을 보장할 수 있을까요?&lt;br /&gt;&lt;br /&gt;TCP에서는 데이터를 보낼 때 &lt;b&gt;송신자와 수신자간 연결을 확인한 뒤 데이터를 전송&lt;/b&gt;하고,&lt;br /&gt;연결을 해제할 때에는 &lt;b&gt;연결을 해제해도 되는지 서로 확인 후에 해제&lt;/b&gt;합니다.&lt;br /&gt;&lt;br /&gt;연결 시 확인하는 과정이 &lt;b&gt;3-Way-HandShaking&lt;/b&gt;이고,&lt;br /&gt;연결 해제 시 확인하는 과정이 &lt;b&gt;4-Way-HandShaking&lt;/b&gt; 입니다.&lt;/p&gt;
&lt;hr 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;3-Way-HandShaking&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;응용프로그램이 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정을 의미합니다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;데이터 전송 전에 상대방이 수신할 준비되었는지 확인할 수 있습니다.&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;패킷&lt;/b&gt;에 담긴 정보를 확인해서 HandShaking 과정이 이루어지는데 다음 두 가지 정보가 주요 역할을 하니 알아 두도록 합시다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;SYN&lt;/b&gt;(sequence number) : 난수값, 이 값은 나중에 데이터를 주고 받을 때 기준이 되는 값으로 사용됨. &lt;br /&gt;* 난수값을 사용하는 이유? &lt;br /&gt;두 호스트가 연결을 맺을 때 사용하는 포트는 유한 범위 내에서 사용하고 시간이 지남에 따라 재사용 됨. 따라서 두 호스트는 과거에 사용된 포트번호 쌍을 사용할 가능성이 존재함. 그렇기 때문에 만약 난수가 아닌 연속된 숫자를 사용할 경우에 이전 연결에서 오는 패킷인지 구분이 안될 수 있기 때문에 난수로 사용함. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;ACK&lt;/b&gt;(acknowledgement) : 송신자가 보낸 SYN에 +1을 한 값. 송신자가 100을 보내고 수신자가 101을 보내면 서로의 존재를 인지하고 있다고 생각하면 됨.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;390&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5gAJN/btrN0D3dvO3/wr83kG2dLvlpP6DcojQ4Ck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5gAJN/btrN0D3dvO3/wr83kG2dLvlpP6DcojQ4Ck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5gAJN/btrN0D3dvO3/wr83kG2dLvlpP6DcojQ4Ck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5gAJN%2FbtrN0D3dvO3%2Fwr83kG2dLvlpP6DcojQ4Ck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;390&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;500&quot; data-origin-height=&quot;390&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3-way-handshaking 과정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;STEP 1&lt;/b&gt; - &lt;span style=&quot;color: #006dd7;&quot;&gt;클라이언트&lt;/span&gt;가 &lt;span style=&quot;color: #ee2323;&quot;&gt;서버&lt;/span&gt;에게 접속을 요청하는 SYN 패킷을 보냅니다.&lt;br /&gt;&lt;b&gt;STEP 2&lt;/b&gt; - &lt;span style=&quot;color: #ee2323;&quot;&gt;서버&lt;/span&gt;는 SYN 요청을 받고 &lt;span style=&quot;color: #006dd7;&quot;&gt;클라이언트&lt;/span&gt;에게 요청을 수락한다는 ACK와 SYN을 보냅니다.&lt;br /&gt;&lt;b&gt;STEP 3&lt;/b&gt; - &lt;span style=&quot;color: #006dd7;&quot;&gt;클라이언트&lt;/span&gt;가 &lt;span style=&quot;color: #ee2323;&quot;&gt;서버&lt;/span&gt;에게 ACK를 보냅니다.&lt;br /&gt;&lt;br /&gt;위의 과정을 통해서 서버와 클라이언트는 서로 연결되었음을 확인했습니다. 이후 데이터를 주고받게 됩니다. 상대방이 데이터를 받을 준비가 되었다는 것을 확인했으니 데이터를 제대로 보냈다고 생각할 수 있겠죠? &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;신뢰성&lt;/b&gt;&lt;/span&gt;이 느껴집니다.&lt;/p&gt;
&lt;hr 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;4-Way-HandShaking&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;응용프로그램이 상대방 컴퓨터와 세션을 해제하는 과정을 의미합니다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;연결 해제시 상대방이 더이상 보낼 데이터가 없는지 확인할 수 있습니다.&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;918&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVKHzO/btrNXsvNcaQ/b0MLNkgaKMsK6H9xKx50uK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVKHzO/btrNXsvNcaQ/b0MLNkgaKMsK6H9xKx50uK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVKHzO/btrNXsvNcaQ/b0MLNkgaKMsK6H9xKx50uK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVKHzO%2FbtrNXsvNcaQ%2Fb0MLNkgaKMsK6H9xKx50uK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1174&quot; height=&quot;918&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;1174&quot; data-origin-height=&quot;918&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;4-way-handshaking 과정&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;STEP 1&lt;/b&gt; - &lt;span style=&quot;color: #006dd7;&quot;&gt;클라이언트&lt;/span&gt;가 &lt;span style=&quot;color: #ee2323;&quot;&gt;서버&lt;/span&gt;에게 종료하겠다는 FIN을 보냅니다.&lt;br /&gt;&lt;b&gt;STEP 2&lt;/b&gt; - &lt;span style=&quot;color: #ee2323;&quot;&gt;서버&lt;/span&gt;는 FIN을 받고 ACK를 보낸 후 자신이 데이터를 모두 보낼때까지 기다립니다.&lt;br /&gt;&lt;b&gt;STEP 3&lt;/b&gt; - &lt;span style=&quot;color: #ee2323;&quot;&gt;서버&lt;/span&gt;가 데이터를 모두 보냈다면 FIN을 &lt;span style=&quot;color: #006dd7;&quot;&gt;클라이언트&lt;/span&gt;에게 보냅니다.&lt;br /&gt;&lt;b&gt;STEP 4&lt;/b&gt; - &lt;span style=&quot;color: #006dd7;&quot;&gt;클라이언트&lt;/span&gt;는 ACK를 보내 응답하고 &lt;span style=&quot;color: #ee2323;&quot;&gt;서버&lt;/span&gt;는 ACK를 수신하면 연결을 해제합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;STEP 2&lt;/b&gt; 과정에서 자신의 데이터를 모두 보낼때까지 대기하는데, 바로 연결을 해제하면 전송중이던 데이터가 유실될 수 있기 때문에 이를 방지하기 위함입니다.&lt;/p&gt;
&lt;hr data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;TCP&lt;/b&gt;의 &lt;b&gt;3-way-handshaking&lt;/b&gt;과 &lt;b&gt;4-way-handshaking&lt;/b&gt;에 대해 정리해보았습니다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;다음번 글에서는 주고받는 Packet에 대해 조금 더 상세히 알아보면 좋지 않을까 싶습니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;참고&lt;br /&gt;- &lt;a href=&quot;https://kosaf04pyh.tistory.com/162&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;&lt;span&gt;https://kosaf04pyh.tistory.com/162&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description>
      <category>IT/Network</category>
      <category>3 way handshake 데이터 전송</category>
      <category>3 way handshake 이유</category>
      <category>3 way handshaking</category>
      <category>3way handshake</category>
      <category>4 way handshake 데이터 전송</category>
      <category>4 way handshake 이유</category>
      <category>4 way handshaking</category>
      <category>4-way-handshake</category>
      <category>TCP handshake</category>
      <category>TCP 신뢰성</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/167</guid>
      <comments>https://javacoding.tistory.com/167#entry167comment</comments>
      <pubDate>Thu, 6 Oct 2022 23:47:18 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 데이터베이스 트랜잭션의 4가지 특징(ACID)</title>
      <link>https://javacoding.tistory.com/166</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버 개발자로서 DBMS를 사용할 때 가장 중요한 관심사 중의 하나는 데이터의 정합성 유지가 아닐까 생각합니다. DBMS가 일관된 결과를 생성하고 정합성을 유지하기 위해 트랜잭션을 이용해 작업을 처리하곤 합니다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;트랜잭션&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;트랜잭션은 데이터베이스의 내용을 접근하고 수정하는 &lt;b&gt;논리적 작업 단위&lt;/b&gt;입니다.&lt;br /&gt;&lt;br /&gt;트랜잭션은 &lt;b&gt;논리적인 작업들을 모두 완벽하게 처리하거나, 처리하지 못했을 경우에는 진행된 모든 작업들을 Rollback하고 원상태로 복구&lt;/b&gt;하여 작업의 일부만 적용되는 상황이 발생하지 않도록 하는 기능입니다.&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터베이스의 일관성을 유지하기 위해 트랜잭션 전후에 특정 속성을 따르는데, 이를 &lt;b&gt;ACID 속성&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;1040&quot; data-origin-height=&quot;630&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vyYLh/btrNSXVVL7D/cYfqX7Tt8NqwyicKJaZr9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vyYLh/btrNSXVVL7D/cYfqX7Tt8NqwyicKJaZr9K/img.png&quot; data-alt=&quot;ACID 속성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vyYLh/btrNSXVVL7D/cYfqX7Tt8NqwyicKJaZr9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvyYLh%2FbtrNSXVVL7D%2FcYfqX7Tt8NqwyicKJaZr9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;388&quot; data-origin-width=&quot;1040&quot; data-origin-height=&quot;630&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ACID 속성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ACID 속성&lt;/b&gt;은 &lt;u&gt;원자성, 일관성, 독립성, 지속성&lt;/u&gt;을 나타내는데 하나씩 살펴보도록 하겠습니다.&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;원자성 (Atomicity)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;원자성은 &lt;b&gt;트랜잭션을 구성하는 작업들이 모두 정상적으로 실행되거나 전혀 실행되지 않음&lt;/b&gt;을 의미합니다. &lt;br /&gt;트랜잭션이 부분적으로 발생하지 않습니다. 즉 중간은 없습니다.&amp;nbsp;&lt;br /&gt;원자성은 &lt;b&gt;&quot;All or nothing rule&quot; &lt;/b&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: #666666;&quot;&gt;각각의 특성을 설명할 때 이해를 돕기 위해 하나의 예시를 들어 확인해보겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;X의 계좌&lt;/span&gt;에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;Y의 계좌&lt;/span&gt;로 100원을 이체하는 과정입니다.&lt;/span&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/165rc/btrNROFvB0Q/cE66wMoDRhDrzDXX6XK2v0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/165rc/btrNROFvB0Q/cE66wMoDRhDrzDXX6XK2v0/img.png&quot; data-alt=&quot;트랜잭션 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/165rc/btrNROFvB0Q/cE66wMoDRhDrzDXX6XK2v0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F165rc%2FbtrNROFvB0Q%2FcE66wMoDRhDrzDXX6XK2v0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;213&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;548&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: #666666;&quot;&gt;- &lt;b&gt;Transaction T&lt;/b&gt;는 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;u&gt;T1 작업(100원 송금)&lt;/u&gt;&lt;/span&gt;과 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;u&gt;T2 작업(100원 입금)&lt;/u&gt;&lt;/span&gt;으로 구성되어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;이때 트랜잭션 &lt;span style=&quot;color: #006dd7;&quot;&gt;T1 작업이 완료&lt;/span&gt;되고 &lt;span style=&quot;color: #ee2323;&quot;&gt;T2 작업이 완료되기 전에 실패&lt;/span&gt;하면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;X의 계좌에서는 100원이 송금되고 Y의 계좌에는 100원이 입금되지 않은 상태여야 하지만 트랜잭션을 사용한다면&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;Transaction T의 작업이 롤백되어 모두 실행되지 않습니다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;일관성 (Consistency)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&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;span style=&quot;color: #666666;&quot;&gt;위의 예시에서는&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;TransactionT가 발생하기 이전의 상태는 &lt;span style=&quot;color: #006dd7;&quot;&gt;X계좌에 500원&lt;/span&gt;이 있고 &lt;span style=&quot;color: #ee2323;&quot;&gt;Y 계좌에 200원&lt;/span&gt;이 있어 &lt;b&gt;총 700원&lt;/b&gt;이 존재했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;TransactionT 작업이 진행된 이후에도 거래 전후의 총액을 유지해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;트랜잭션이 성공해서 &lt;span style=&quot;color: #006dd7;&quot;&gt;X계좌에 400원&lt;/span&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;Y계좌에 300원&lt;/span&gt;이 존재하거나, 트랜잭션이 실패해서 &lt;span style=&quot;color: #006dd7;&quot;&gt;X계좌에 500원&lt;/span&gt;, &lt;span style=&quot;color: #ee2323;&quot;&gt;Y계좌에 200원&lt;/span&gt;인 상태로 일관된 총액 700원을 유지해야 합니다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;독립성 (Isolation)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;지속성 (Durability)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;지속성은 트랜잭션 실행이 완료되면 데이터베이스에 대한 업데이트 및 수정 사항이 영구적으로 반영됨을 의미합니다.&lt;br /&gt;시스템 오류가 발생하더라도 해당 기록은 영구적이어야 합니다.&lt;/blockquote&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;이렇게 RDBMS에서 트랜잭션의 4가지 속성인 &lt;u&gt;&lt;b&gt;원자성, 일관성, 독립성, 지속성&lt;/b&gt;&lt;/u&gt;에 대해 살펴보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&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;DBMS 트랜잭션 상태&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d4wLLc/btrNSOkKC9X/C9vKIiV1taecsXaKsJLID1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d4wLLc/btrNSOkKC9X/C9vKIiV1taecsXaKsJLID1/img.png&quot; data-alt=&quot;Transaction 상태&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d4wLLc/btrNSOkKC9X/C9vKIiV1taecsXaKsJLID1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd4wLLc%2FbtrNSOkKC9X%2FC9vKIiV1taecsXaKsJLID1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;238&quot; data-origin-width=&quot;1288&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Transaction 상태&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;활성 상태(Active State)&lt;/b&gt; : 트랜잭션 명령이 실행중일 때 트랜잭션은 활성 상태에 있습니다. 모든 읽기 및 쓰기 작업이 오류 없이 수행되면 &lt;u&gt;&lt;b&gt;부분적 커밋 상태&lt;/b&gt;&lt;/u&gt;가 됩니다. 만약 명령이 실패하면 &lt;u&gt;&lt;b&gt;실패 상태&lt;/b&gt;&lt;/u&gt;가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;부분적 커밋 상태(Partially Committed State)&lt;/b&gt; : 모든 읽기 및 쓰기 작업이 완료된 후 변경사항이 데이터베이스에 영구적으로 적용되면 &lt;u&gt;&lt;b&gt;커밋된 상태&lt;/b&gt;&lt;/u&gt;로 변경되고 실패할 경우 &lt;u&gt;&lt;b&gt;실패 상태&lt;/b&gt;&lt;/u&gt;가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실패 상태(Failed State)&lt;/b&gt; : 트랜잭션 명령이 실패하면 실패 상태가 되거나 데이터베이스의 데이터를 영구적으로 변경하는 데 실패한 경우 &lt;u&gt;&lt;b&gt;실패 상태&lt;/b&gt;&lt;/u&gt;가 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;중단 상태(Abort State)&lt;/b&gt; : 오류가 발생한 후 트랜잭션은 &lt;u&gt;&lt;b&gt;실패 상태&lt;/b&gt;&lt;/u&gt;에서 &lt;u&gt;&lt;b&gt;중단 상태&lt;/b&gt;&lt;/u&gt;로 바뀌고 변경 사항이 삭제되거나 롤백됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;커밋 상태(Committed State)&lt;/b&gt; : 데이터베이스에서 변경 사항이 영구적으로 반영된 상태입니다. 이후 &lt;u&gt;&lt;b&gt;종료 상태&lt;/b&gt;&lt;/u&gt;에서 종료됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;종료 상태(Terminated State)&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;이렇게 해서 트랜잭션의 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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;참고 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.geeksforgeeks.org&quot;&gt;https://www.geeksforgeeks.org&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/DB</category>
      <category>ACID 속성</category>
      <category>ACID 특징</category>
      <category>DB 트랜잭션</category>
      <category>DBMS Transaction</category>
      <category>rollback</category>
      <category>데이터베이스 트랜잭션</category>
      <category>트랜잭션</category>
      <category>트랜잭션 ACID</category>
      <category>트랜잭션 속성</category>
      <category>트랜잭션 특징</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/166</guid>
      <comments>https://javacoding.tistory.com/166#entry166comment</comments>
      <pubDate>Thu, 6 Oct 2022 00:23:29 +0900</pubDate>
    </item>
    <item>
      <title>[DB] 데이터베이스 제약조건과 PK, FK</title>
      <link>https://javacoding.tistory.com/165</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발하면서 다양한 RDB를 사용하게 되는데, 이번 글에서는 데이터베이스 제약조건과 함께 PK, FK 특징에 대해 정리해볼까 합니다.&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 floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baZs4N/btrNSMzOTh9/6rd7Loz98HLBjHlxrNIkN0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baZs4N/btrNSMzOTh9/6rd7Loz98HLBjHlxrNIkN0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baZs4N/btrNSMzOTh9/6rd7Loz98HLBjHlxrNIkN0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaZs4N%2FbtrNSMzOTh9%2F6rd7Loz98HLBjHlxrNIkN0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;452&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 Constraint란 뜻에 대해 찾아보았는데요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;제약의 뜻을 가지고 있었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 데이터베이스에서 말하는 제약조건이란 무엇일까요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제약조건&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;제약 조건(constraint)이란 데이터의 무결성을 지키기 위해, 데이터를 입력받을 때 실행되는 검사 규칙을 의미합니다.&lt;br /&gt;이러한 제약 조건은 CREATE 문으로 테이블을 생성할 때나&amp;nbsp;ALTER 문으로 필드를 추가할 때도 설정할 수도 있습니다.&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;제약조건에는 어떤 종류가 있을까요? MySQL에서 사용할 수 있는 제약 조건은&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;NOT NULL&lt;/li&gt;
&lt;li&gt;UNIQUE&lt;/li&gt;
&lt;li&gt;PRIMARY KEY&lt;/li&gt;
&lt;li&gt;FOREIGN KEY&lt;/li&gt;
&lt;li&gt;DEFAULT&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NOT NULL부터 제약조건들을 하나씩 살펴보도록 하겠습니다.&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;NOT NULL&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;NOT NULL 제약 조건을 설정하면, 해당 필드는 &lt;b&gt;NULL 값을 저장할 수 없습니다.&lt;/b&gt;&lt;br /&gt;즉, 이&amp;nbsp;제약 조건이 설정된 필드는 무조건 데이터를 가지고 있어야 합니다.&lt;br /&gt;NOT NULL&amp;nbsp;제약 조건은 CREATE 문으로 테이블을 생성할 때나, 나중에 ALTER 문으로 추가할 수도 있습니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CREATE 시 NOT NULL 설정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;: CREATE 문으로 테이블을 생성할 때 해당 필드의 타입 뒤에 NOT NULL을 명시하면, 해당 필드는 NULL 값을 가질 수 없습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1664958253100&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE Test
(
    ID INT NOT NULL,
    Name VARCHAR(30),
    ReserveDate DATE,
    RoomNum INT
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 쿼리처럼 ID 필드에 NOT NULL 제약조건을 설정하고 테이블을 생성한 뒤 테이블의 상세 정보를 확인하면 다음과 같습니다.&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;762&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cyZvbm/btrNSOR00SI/9NRyvlSOFcaqyWYzPeCWck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cyZvbm/btrNSOR00SI/9NRyvlSOFcaqyWYzPeCWck/img.png&quot; data-alt=&quot;NOTNULL 적용 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cyZvbm/btrNSOR00SI/9NRyvlSOFcaqyWYzPeCWck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcyZvbm%2FbtrNSOR00SI%2F9NRyvlSOFcaqyWYzPeCWck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;184&quot; data-origin-width=&quot;762&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NOTNULL 적용 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제부터 Test 테이블에서 INSERT 문으로 새로운 레코드를 추가할 때 ID 필드의 값으로 NULL을 사용할 수 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NOT NULL 제약조건이란 해당 필드에 NULL 값을 저장할 수 없도록 설정하는 것으로, 해당 필드를 생략하지 못하도록 하는 제약조건은 아님을 기억해두길 바랍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 ID 필드가 생략된 경우에도 레코드 저장이 가능한데, SQL예시와 생성 결과는 아래와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1664958925604&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT INTO Test (Name, ReserveDate, RoomNum)
VALUES('이순신', '2016-02-16', 1108);&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;726&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dy1zKz/btrNTLG1pWW/ETsHyzanwQPIDK45nT9Fhk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dy1zKz/btrNTLG1pWW/ETsHyzanwQPIDK45nT9Fhk/img.png&quot; data-alt=&quot;NOTNULL 생략 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dy1zKz/btrNTLG1pWW/ETsHyzanwQPIDK45nT9Fhk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdy1zKz%2FbtrNTLG1pWW%2FETsHyzanwQPIDK45nT9Fhk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;105&quot; data-origin-width=&quot;726&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;NOTNULL 생략 예시&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;UNIQUE&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;UNIQUE 제약 조건을 설정하면,&amp;nbsp;&lt;b&gt;해당 필드는 서로 다른&amp;nbsp;값을 가져야&amp;nbsp;합니다.&lt;/b&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;span style=&quot;color: #666666;&quot;&gt;UNIQUE 제약 조건은 CREATE 문으로 테이블을 생성할 때나, 나중에 ALTER 문으로 추가할 수도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1664959206371&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. CREATE TABLE 테이블이름
(
	필드명 필드타입 UNIQUE,
    ...
)

2. CREATE TABLE 테이블이름
(
	필드이름 필드타입,
    ...
    [CONSTRAINT 제약조건이름] UNIQUE (필드이름)
)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 두 문법 모두 해당 필드에 &lt;b&gt;UNIQUE&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;CREATE 시 Test 테이블을 생성하면서 ID 필드에 UNIQUE 제약조건을 설정하는 예시를 살펴보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1664959364339&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE Test 

(

    ID INT UNIQUE,

    Name VARCHAR(30),

    ReserveDate DATE,

    RoomNum INT

);&lt;/code&gt;&lt;/pre&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;760&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkTFJZ/btrNTgAu2vP/NPLeo91zjXm6FxnvbqoDH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkTFJZ/btrNTgAu2vP/NPLeo91zjXm6FxnvbqoDH1/img.png&quot; data-alt=&quot;UNIQUE 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkTFJZ/btrNTgAu2vP/NPLeo91zjXm6FxnvbqoDH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkTFJZ%2FbtrNTgAu2vP%2FNPLeo91zjXm6FxnvbqoDH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;202&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;UNIQUE 예시&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 ID 필드에 UNIQUE 제약조건을 설정한 후에 Test 테이블의 정보를 확인하면 다음과 같습니다.&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;PRIMARY KEY&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;PRIMARY KEY 제약 조건을 설정하면, 해당 필드는&amp;nbsp;&lt;b&gt;NOT NULL&lt;/b&gt;과 &lt;b&gt;UNIQUE&lt;/b&gt; 제약 조건의 특징을 모두 가집니다.&lt;br /&gt;따라서 이 제약 조건이 설정된 필드는&amp;nbsp;NULL 값을 가질 수 없으며, 또한 중복된 값을 가져서도 안 됩니다.&lt;br /&gt;이러한&amp;nbsp;PRIMARY KEY 제약 조건을 기본 키라고 합니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;UNIQUE는 한 테이블의 여러 필드에 설정할 수 있지만, &lt;b&gt;PRIMARY KEY는 테이블당 오직 하나만 설정할 수 있습니다.&lt;/b&gt;&lt;br /&gt;이러한 PRIMARY KEY 제약 조건은&amp;nbsp;테이블의 데이터를 쉽고 빠르게 찾도록 도와주는 역할을 합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;PRIMARY KEY테이블의 각 레코드를 고유하게 식별합니다.&lt;/li&gt;
&lt;li&gt;기본 키는 UNIQUE 값을 포함해야 하며 NULL 값을 포함할 수 없습니다.&lt;/li&gt;
&lt;li&gt;테이블에는 하나의 PK(기본키)만 있을 수 있습니다.&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;CREATE시 PRIMARY KEY 제약조건을 설정하는 문법을 보도록 하겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 필드의 타입 뒤에 PRIMARY KEY를 명시하면, 해당 필드가 기본 키로 설정됩니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1664960129234&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. CREATE TABLE 테이블이름

(

    필드이름 필드타입 PRIMARY KEY,

    ...

)
2. CREATE TABLE 테이블이름

(

    필드이름 필드타입,

    ...,

    [CONSTRAINT 제약조건이름] PRIMARY KEY (필드이름)

)&lt;/code&gt;&lt;/pre&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;실제 쿼리와 생성된 테이블을 살펴보면 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1664960212500&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE Test 

(

    ID INT PRIMARY KEY,

    Name VARCHAR(30),

    ReserveDate DATE,

    RoomNum INT

);&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;760&quot; data-origin-height=&quot;384&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uwjqi/btrNSNySYZc/E7kKismK5Uw3WEGttn2KTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uwjqi/btrNSNySYZc/E7kKismK5Uw3WEGttn2KTK/img.png&quot; data-alt=&quot;PK 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uwjqi/btrNSNySYZc/E7kKismK5Uw3WEGttn2KTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fuwjqi%2FbtrNSNySYZc%2FE7kKismK5Uw3WEGttn2KTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;202&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;384&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;PK 예시&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;FOREIGN KEY&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;FOREIGN KEY 제약 조건을 설정한 필드는 &lt;b&gt;외래 키&lt;/b&gt;라고 부르며, &lt;b&gt;한 테이블을 다른 테이블과 연결해주는 역할&lt;/b&gt;을 합니다.&lt;br /&gt;외래 키가 설정된 테이블에 레코드를 입력하면, 기준이 되는 테이블의 내용을 참조해서 레코드가 입력됩니다.&lt;br /&gt;즉, FOREIGN KEY 제약 조건은&amp;nbsp;하나의 테이블을&amp;nbsp;다른 테이블에 의존하게 만듭니다.&lt;br /&gt;&amp;nbsp;&lt;br /&gt;FOREIGN KEY 제약 조건을 설정할 때 참조되는 테이블의 필드는 반드시 UNIQUE나 PRIMARY KEY 제약 조건이 설정되어 있어야 합니다.&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;CREATE시 FORIGN KEY를 설정하는 문법을 살펴보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블을 생성할 때 해당 필드의 타입 뒤에 FOREIGN KEY를 명시하면, 해당 필드가 외래 키로 설정됩니다.&lt;/p&gt;
&lt;pre id=&quot;code_1664960632796&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE 테이블이름

(

    필드이름 필드타입,

    ...,

    [CONSTRAINT 제약조건이름]

    FOREIGN KEY (필드이름)

    REFERENCES 테이블이름 (필드이름)

)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조되는 테이블의 이름은 REFERENCES 키워드 다음에 명시합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test2 테이블의 ParentID 필드에 Test1 테이블의 ID 필드를 참조하는 FOREIGN KEY 제약 조건을 설정하는 예시를 살펴보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1664960706161&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE Test2

(

    ID INT,

    ParentID INT,

    FOREIGN KEY (ParentID)

    REFERENCES Test1(ID) ON UPDATE CASCADE

);&lt;/code&gt;&lt;/pre&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;674&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPb4s8/btrNQqqUnwS/YKU2UATJqdXuMYC8ABZ8K0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPb4s8/btrNQqqUnwS/YKU2UATJqdXuMYC8ABZ8K0/img.png&quot; data-alt=&quot;FK 예시&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPb4s8/btrNQqqUnwS/YKU2UATJqdXuMYC8ABZ8K0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPb4s8%2FbtrNQqqUnwS%2FYKU2UATJqdXuMYC8ABZ8K0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;300&quot; height=&quot;126&quot; data-origin-width=&quot;674&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;FK 예시&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;ON DELETE, ON UPDATE&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;FOREIGN KEY 제약 조건에 의해 참조되는 테이블에서 데이터의 수정이나 삭제가 발생하면, 참조하고 있는 테이블의 데이터도 같이 영향을 받습니다.&lt;br /&gt;이때 참조하고 있는 테이블의 동작은&amp;nbsp;다음 키워드를 사용하여 FOREIGN KEY 제약 조건에서 미리 설정할 수&amp;nbsp;있습니다.&lt;br /&gt;&lt;br /&gt;참조되는 테이블의 값이&amp;nbsp;삭제될&amp;nbsp;경우의 동작은 ON DELETE 구문으로 설정할 수 있습니다.&lt;br /&gt;또한, 참조되는 테이블의 값이 수정될&amp;nbsp;경우의 동작은 ON UPDATE 구문으로 설정할 수 있습니다.&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;p data-ke-size=&quot;size16&quot;&gt;1. &lt;b&gt;CASCADE&lt;/b&gt; : 참조되는 테이블에서 데이터를 삭제하거나 수정하면, 참조하는 테이블에서도 삭제와 수정이 같이&amp;nbsp;이루어집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. &lt;b&gt;SET NULL&lt;/b&gt; : 참조되는 테이블에서 데이터를 삭제하거나 수정하면, 참조하는 테이블의 데이터는 NULL로 변경됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #575757;&quot;&gt;3. &lt;b&gt;NO ACTION&lt;/b&gt; : 참조되는 테이블에서 데이터를 삭제하거나 수정해도,&amp;nbsp;참조하는 테이블의 데이터는 변경되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;b&gt;SET DEFAULT&lt;/b&gt; : 참조되는 테이블에서 데이터를 삭제하거나 수정하면, 참조하는 테이블의 데이터는 필드의 기본값으로 설정됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. &lt;b&gt;RESTRICT&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;DEFAULT&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;DEFAULT 제약 조건은&amp;nbsp;해당 필드의 &lt;b&gt;기본값을 설정&lt;/b&gt;할 수 있게 해줍니다.&lt;br /&gt;만약 레코드를 입력할 때 해당 필드&amp;nbsp;값을 전달하지 않으면, 자동으로 설정된 기본값을 저장합니다.&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;CREATE 시 Test 테이블을 생성하면서 Name 필드에 DEFAULT 제약조건을 이용하여 기본값을 설정하는 예시를 살펴보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1664961363670&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE TABLE Test

(

    ID INT,

    Name VARCHAR(30) DEFAULT 'Anonymous',

    ReserveDate DATE,

    RoomNum INT

);&lt;/code&gt;&lt;/pre&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;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cESO95/btrNUafATlM/CuvFRgSq8epuC7MN44bsg0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cESO95/btrNUafATlM/CuvFRgSq8epuC7MN44bsg0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cESO95/btrNUafATlM/CuvFRgSq8epuC7MN44bsg0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcESO95%2FbtrNUafATlM%2FCuvFRgSq8epuC7MN44bsg0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;185&quot; data-origin-width=&quot;806&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;NOT NULL&lt;/u&gt;, &lt;u&gt;UNIQUE&lt;/u&gt;, &lt;u&gt;PRIMARY KEY&lt;/u&gt;, &lt;u&gt;FOREIGN KEY&lt;/u&gt;, &lt;u&gt;DEFAULT&lt;/u&gt; 와 같은 다양한 데이터베이스 제약조건에 대해 살펴보았습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 PK와 FK 설정시의 제약조건에 대해 알아보았습니다.&lt;/p&gt;
&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;RDB를 이용해서 서비스를 구현할 때 기본이 되는 내용이므로&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;꼭 숙지하여 DB를 설계하고 사용하는 것이 좋을 것 같습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고: &lt;a href=&quot;http://tcpschool.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;http://tcpschool.com&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT/DB</category>
      <category>DATABASE PK</category>
      <category>DB Constraint</category>
      <category>DB FK</category>
      <category>DB PK</category>
      <category>DB PK 제약조건</category>
      <category>DB 기본키</category>
      <category>DB 제약조건</category>
      <category>MySQL PK</category>
      <category>기본키 외래키</category>
      <category>데이터베이스 제약조건</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/165</guid>
      <comments>https://javacoding.tistory.com/165#entry165comment</comments>
      <pubDate>Wed, 5 Oct 2022 18:26:45 +0900</pubDate>
    </item>
    <item>
      <title>PORT 포트번호란</title>
      <link>https://javacoding.tistory.com/163</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP와 함께 PORT 번호에 대해서 들어보았을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP 프로토콜을 살펴볼 때 전송하는 패킷에 PORT 번호에 대한 정보가 포함되어 있었는데 PORT 번호가 무엇인지 간단하게 살펴보자.&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;733&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dzHCYI/btrJpfmWOZe/1H8VgXmwBVtnp0zOoy5s20/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dzHCYI/btrJpfmWOZe/1H8VgXmwBVtnp0zOoy5s20/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dzHCYI/btrJpfmWOZe/1H8VgXmwBVtnp0zOoy5s20/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdzHCYI%2FbtrJpfmWOZe%2F1H8VgXmwBVtnp0zOoy5s20%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;733&quot; height=&quot;460&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;460&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;포트 번호는 해당 IP주소가 가리키는 PC에 접속할 수 있는 통로이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 들자면, A 아파트 이름을 IP 주소라고 할 때 00동 00호로 상세한 집 주소를 나타내는 것과 같은 역할을 하는게 PORT 번호라고 생각하면 쉬울 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포트는 0번부터 65535번까지 있는데, 하나의 PC로 연결을 할때 포트 번호에 따라 6만 가지 이상으로 구분할 수 있다.&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;694&quot; data-origin-height=&quot;151&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Psy1D/btrJpObBEZH/OrxBZ8kisgOvKSkb83kzH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Psy1D/btrJpObBEZH/OrxBZ8kisgOvKSkb83kzH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Psy1D/btrJpObBEZH/OrxBZ8kisgOvKSkb83kzH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FPsy1D%2FbtrJpObBEZH%2FOrxBZ8kisgOvKSkb83kzH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;694&quot; height=&quot;151&quot; data-origin-width=&quot;694&quot; data-origin-height=&quot;151&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 0~1023번 포트는 잘 알려진 포트로 이미 사용되고 있거나, 상징성이 있기 때문에 해당 프로세스가 아닌 경우에는 다른 포트 번호를 사용하는게 일반적이다.&lt;/p&gt;
&lt;p data-ke-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;694&quot; data-origin-height=&quot;259&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cr1GCm/btrJreUGCQi/9poMKHi77ZIOyOKMoQ7O90/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cr1GCm/btrJreUGCQi/9poMKHi77ZIOyOKMoQ7O90/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cr1GCm/btrJreUGCQi/9poMKHi77ZIOyOKMoQ7O90/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcr1GCm%2FbtrJreUGCQi%2F9poMKHi77ZIOyOKMoQ7O90%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;694&quot; height=&quot;259&quot; data-origin-width=&quot;694&quot; data-origin-height=&quot;259&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 사용중인 포트는 중복해서 사용될 수 없으므로 포트 번호를 지정할 때 해당 포트가 사용중인지 확인이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555;&quot;&gt;참고 강의 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.inflearn.com/course/http-웹-네트워크&quot;&gt;https://www.inflearn.com/course/http-웹-네트워크&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660174153788&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의&quot; data-og-description=&quot;실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/http-웹-네트워크&quot; data-og-url=&quot;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/h24IK/hyPolAzAmI/2rXD7mtQr0g0B0FFSJgAfK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/br45rt/hyPpD0GI0K/5wVH2g6KsVt5ZoH8QwDPnK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/bNUa4q/hyPpAQqQbj/OivWBqjJiwgQRMUlQ8TSd0/img.jpg?width=1200&amp;amp;height=666&amp;amp;face=0_0_1200_666&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/http-웹-네트워크&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/http-웹-네트워크&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/h24IK/hyPolAzAmI/2rXD7mtQr0g0B0FFSJgAfK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/br45rt/hyPpD0GI0K/5wVH2g6KsVt5ZoH8QwDPnK/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/bNUa4q/hyPpAQqQbj/OivWBqjJiwgQRMUlQ8TSd0/img.jpg?width=1200&amp;amp;height=666&amp;amp;face=0_0_1200_666');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.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>IT/Web</category>
      <category>IP</category>
      <category>port</category>
      <category>Port Number</category>
      <category>PORT주소</category>
      <category>포트</category>
      <category>포트번호</category>
      <category>포트주소</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/163</guid>
      <comments>https://javacoding.tistory.com/163#entry163comment</comments>
      <pubDate>Thu, 11 Aug 2022 08:29:40 +0900</pubDate>
    </item>
    <item>
      <title>TCP란?</title>
      <link>https://javacoding.tistory.com/162</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/160&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://javacoding.tistory.com/160&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660089356772&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;IP(Internet Protocol)&quot; data-og-description=&quot;내가 인터넷을 통해 정보를 원하는 곳으로 전달하고자 할 경우, 도착지를 알아야 한다. 나의 주소와 상대의 주소는 어떻게 나타낼 수 있을까? 이때 PC마다의 주소를 지정할 수 있도록 한게 IP 체&quot; data-og-host=&quot;javacoding.tistory.com&quot; data-og-source-url=&quot;https://javacoding.tistory.com/160&quot; data-og-url=&quot;https://javacoding.tistory.com/160&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/u9ZUv/hyPoeAHzft/XlWGkghDv30t8HFiPWUIN1/img.jpg?width=800&amp;amp;height=511&amp;amp;face=0_0_800_511,https://scrap.kakaocdn.net/dn/tgwMu/hyPoeAHzia/WL9AqprFJB9E7JwoprRV40/img.jpg?width=800&amp;amp;height=511&amp;amp;face=0_0_800_511,https://scrap.kakaocdn.net/dn/f7AqB/hyPolT8pTm/5LdqSpdoktrWfUQkMftNLK/img.png?width=1936&amp;amp;height=582&amp;amp;face=0_0_1936_582&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/160&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://javacoding.tistory.com/160&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/u9ZUv/hyPoeAHzft/XlWGkghDv30t8HFiPWUIN1/img.jpg?width=800&amp;amp;height=511&amp;amp;face=0_0_800_511,https://scrap.kakaocdn.net/dn/tgwMu/hyPoeAHzia/WL9AqprFJB9E7JwoprRV40/img.jpg?width=800&amp;amp;height=511&amp;amp;face=0_0_800_511,https://scrap.kakaocdn.net/dn/f7AqB/hyPolT8pTm/5LdqSpdoktrWfUQkMftNLK/img.png?width=1936&amp;amp;height=582&amp;amp;face=0_0_1936_582');&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;IP(Internet Protocol)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;내가 인터넷을 통해 정보를 원하는 곳으로 전달하고자 할 경우, 도착지를 알아야 한다. 나의 주소와 상대의 주소는 어떻게 나타낼 수 있을까? 이때 PC마다의 주소를 지정할 수 있도록 한게 IP 체&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;javacoding.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 글에서 IP 프로토콜에 대해서 살펴보았는데, 조금 더 상위 계층의 TCP에 대해 간략히 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패킷이 소실되거나, 전달 순서가 바뀌거나, 불확실한 상대에게 데이터를 전달하는 등 IP 프로토콜에서 데이터 전송을 신뢰할 수 없는 여러 문제가 있었다. TCP는 이런 문제의 상당 부분을 해결해줄 수 있다는 점에서 신뢰할 수 있는 프로토콜로 많이 알려져 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brVkiM/btrJlWtloQt/XRGsnwdH5Xk7ntZRT2wnS1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brVkiM/btrJlWtloQt/XRGsnwdH5Xk7ntZRT2wnS1/img.png&quot; data-alt=&quot;https://developer.mozilla.org/ko/docs/Glossary/TCP&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brVkiM/btrJlWtloQt/XRGsnwdH5Xk7ntZRT2wnS1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbrVkiM%2FbtrJlWtloQt%2FXRGsnwdH5Xk7ntZRT2wnS1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;791&quot; height=&quot;270&quot; data-origin-width=&quot;791&quot; data-origin-height=&quot;270&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;https://developer.mozilla.org/ko/docs/Glossary/TCP&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;TCP 전송&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP 전송은 어떻게 이루어질까?&amp;nbsp;여러 프로그래밍 언어에서 TCP를 위해 보통 SOCKET 라이브러리를 많이 이용하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SOCKET을 통해 상대 서버로 데이터를 전달하는 그림 을&amp;nbsp;간략히 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;422&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kDZDx/btrJik3dXex/G9hmkeiaBwzqKhTfostjBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kDZDx/btrJik3dXex/G9hmkeiaBwzqKhTfostjBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kDZDx/btrJik3dXex/G9hmkeiaBwzqKhTfostjBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkDZDx%2FbtrJik3dXex%2FG9hmkeiaBwzqKhTfostjBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;712&quot; height=&quot;422&quot; data-origin-width=&quot;712&quot; data-origin-height=&quot;422&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림을 간략히 정리해보면&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;라이브러리를 통해 소켓을 만들고 메시지 데이터를 담는다.&lt;/li&gt;
&lt;li&gt;OS 계층의 TCP 단계를 거치며 TCP 정보(출발지PORT, 목적지 PORT, 전송 제어, 순서, 기타&amp;hellip;)들을 생성하여 메시지 데이터에 추가한다.&lt;/li&gt;
&lt;li&gt;IP단계를 거치며 IP 정보(출발지IP, 목적지IP, 기타&amp;hellip;)를 메시지 데이터에 추가한다.&lt;/li&gt;
&lt;li&gt;생성된 IP 패킷에 Ethernet frame정보를 추가한다.&lt;/li&gt;
&lt;li&gt;인터넷을 통해 상대 서버로 전달한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;TCP 특징&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP는 전송 제어 프로토콜(&lt;b&gt;T&lt;/b&gt;ransmission&amp;nbsp;&lt;b&gt;C&lt;/b&gt;ontrol&amp;nbsp;&lt;b&gt;P&lt;/b&gt;rotocol,&amp;nbsp;&lt;b&gt;TCP&lt;/b&gt;)이라고도 하는데 특징은 다음과 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;연결지향 - 3 way handshake&lt;/b&gt;&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;TCP는 장치들 사이에 논리적인 접속을 성립하기 위하여 3 way handshake를 사용한다. TCP 3 way Handshake는 TCP/IP프로토콜을 이용해서 통신을 하는 응용프로그램이 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 목적지 서버와의 연결을 진행하는 것이다.&lt;/li&gt;
&lt;li&gt;3 way handshaking을 통해 양쪽 모두 데이터를 전송할 준비가 되었다는 것을 보장하고, 데이터 전달이 시작하기 전에 상대쪽이 준비가 되었는지 확인해볼 수 있다.&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;607&quot; data-origin-height=&quot;351&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eONmOD/btrJlzStsfb/h7901I3AIwaGXGnRB81iW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eONmOD/btrJlzStsfb/h7901I3AIwaGXGnRB81iW1/img.png&quot; data-alt=&quot;출처: https://mindnet.tistory.com/entry/네트워크-쉽게-이해하기-22편-TCP-3-WayHandshake-4-WayHandshake&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eONmOD/btrJlzStsfb/h7901I3AIwaGXGnRB81iW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeONmOD%2FbtrJlzStsfb%2Fh7901I3AIwaGXGnRB81iW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;607&quot; height=&quot;351&quot; data-origin-width=&quot;607&quot; data-origin-height=&quot;351&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처: https://mindnet.tistory.com/entry/네트워크-쉽게-이해하기-22편-TCP-3-WayHandshake-4-WayHandshake&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HvOc2/btrJlFL7PXd/SvEN3MIb5T7vVszIZhK2JK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HvOc2/btrJlFL7PXd/SvEN3MIb5T7vVszIZhK2JK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HvOc2/btrJlFL7PXd/SvEN3MIb5T7vVszIZhK2JK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHvOc2%2FbtrJlFL7PXd%2FSvEN3MIb5T7vVszIZhK2JK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;724&quot; height=&quot;267&quot; data-origin-width=&quot;724&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 데이터 전달 보증&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;목적지에서 TCP 데이터가 도착하면 출발지쪽으로 메시지 도착을 알린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때 반환하는 것을&amp;nbsp;ACK라고 하며, TCP 헤더에 ACK 관련 정보를 넣은 TCP 세그먼트를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 출발지쪽은 ACK가 돌아오는 것을 보고 전송한 메시지가 무사히 목적지에 도착했다는 것을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 ACK가 오지 않는다면 문제가 발생한 것으로 보고 재전송, 재연결 등의 처리를 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TCP에서는 이렇게 ACK를 통해 데이터가 전달되었다는 것을 보증받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&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;3. 순서 보장&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;654&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wrLdO/btrJlVund6s/xZrkSc2JKWzJRZatdxkEZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wrLdO/btrJlVund6s/xZrkSc2JKWzJRZatdxkEZk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wrLdO/btrJlVund6s/xZrkSc2JKWzJRZatdxkEZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwrLdO%2FbtrJlVund6s%2FxZrkSc2JKWzJRZatdxkEZk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;654&quot; height=&quot;192&quot; data-origin-width=&quot;654&quot; data-origin-height=&quot;192&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;TCP 전송에서는 순서가 보장된다. TCP 세그먼트에 Sequence Number를 붙여 구현하기 때문인데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수신쪽에서는 수신한 세그먼트를 바로 전달하지 않고, 버퍼에 가지고 있다가 Sequence Number를 사용해서 세그먼트가 순서가 맞을때까지 기다린다. 이 순서가 맞춰진 세그먼트 data chunk를 결합시킨 후 전달한다.&lt;/p&gt;
&lt;p data-ke-size=&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;기본적인 TCP의 개념과 특징들에 대해서 살펴보았는데 정리해보면&amp;nbsp;IP 프로토콜에 비해 &lt;b&gt;TCP는 더 신뢰적이고 안정적&lt;/b&gt;이었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3-way handshaking&lt;/b&gt; 과정으로 연결지향적이었고, ACK를 이용하여 데이터가 &lt;b&gt;전달되었는지 보증&lt;/b&gt;받을 수 있었으며, Sequence Number를 이용하여 전달하는 데이터들의 &lt;b&gt;순서를 보장&lt;/b&gt;해주는 특징이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;참고 강의 :&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://www.inflearn.com/course/http-웹-네트워크&quot;&gt;https://www.inflearn.com/course/http-웹-네트워크&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660090049439&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의&quot; data-og-description=&quot;실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/http-웹-네트워크&quot; data-og-url=&quot;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ck7idB/hyPor06Yam/OwHzDz3PwYhzJMFlkeHUt0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/HFl5G/hyPohqFzhJ/FueYmr4WGwrTleuEfl0K81/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WHA8s/hyPokub57Y/nfIvsEh0xl8UJWIiM8MY6k/img.jpg?width=1200&amp;amp;height=666&amp;amp;face=0_0_1200_666&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/http-웹-네트워크&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/http-웹-네트워크&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ck7idB/hyPor06Yam/OwHzDz3PwYhzJMFlkeHUt0/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/HFl5G/hyPohqFzhJ/FueYmr4WGwrTleuEfl0K81/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/WHA8s/hyPokub57Y/nfIvsEh0xl8UJWIiM8MY6k/img.jpg?width=1200&amp;amp;height=666&amp;amp;face=0_0_1200_666');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.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>IT/Web</category>
      <category>http</category>
      <category>IP</category>
      <category>Java Socket</category>
      <category>SOCKET</category>
      <category>TCP</category>
      <category>TCP 개념</category>
      <category>TCP 기초</category>
      <category>TCP 전송</category>
      <category>TCP 특징</category>
      <category>TCP 프로토콜</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/162</guid>
      <comments>https://javacoding.tistory.com/162#entry162comment</comments>
      <pubDate>Wed, 10 Aug 2022 09:06:16 +0900</pubDate>
    </item>
    <item>
      <title>IP(Internet Protocol)</title>
      <link>https://javacoding.tistory.com/160</link>
      <description>&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;1280&quot; data-origin-height=&quot;818&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVLmG0/btrIMCvzORI/PoLAcksyISC2v0f7htjr9k/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVLmG0/btrIMCvzORI/PoLAcksyISC2v0f7htjr9k/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVLmG0/btrIMCvzORI/PoLAcksyISC2v0f7htjr9k/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVLmG0%2FbtrIMCvzORI%2FPoLAcksyISC2v0f7htjr9k%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;1280&quot; height=&quot;818&quot; data-origin-width=&quot;1280&quot; data-origin-height=&quot;818&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;이때 PC마다의 주소를 지정할 수 있도록 한게 IP 체계이다.&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;1936&quot; data-origin-height=&quot;582&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EC7zz/btrIK7PCMMN/BZ3KhNJXf2Nzq4H85Efla0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EC7zz/btrIK7PCMMN/BZ3KhNJXf2Nzq4H85Efla0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EC7zz/btrIK7PCMMN/BZ3KhNJXf2Nzq4H85Efla0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEC7zz%2FbtrIK7PCMMN%2FBZ3KhNJXf2Nzq4H85Efla0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1936&quot; height=&quot;582&quot; data-origin-width=&quot;1936&quot; data-origin-height=&quot;582&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;PC마다 지정된 IP 주소가 있기 때문에 우리는 목적지의 IP 주소로 정보를 보낼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 통신시에는 패킷(Packet)이라는 통신 단위를 사용하는데 간략하게 그림으로 나타내면 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;341&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cQ2UHS/btrIKnr9wab/Snw6rFQUq6nKeENRchR0RK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cQ2UHS/btrIKnr9wab/Snw6rFQUq6nKeENRchR0RK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cQ2UHS/btrIKnr9wab/Snw6rFQUq6nKeENRchR0RK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcQ2UHS%2FbtrIKnr9wab%2FSnw6rFQUq6nKeENRchR0RK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;659&quot; height=&quot;341&quot; data-origin-width=&quot;659&quot; data-origin-height=&quot;341&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP 패킷에는 출발지 IP, 목적지 IP와 같은 수많은 정보들로 이루어져 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP와 함께 사용하는 PORT 주소는 뭘까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/163&quot;&gt;https://javacoding.tistory.com/163&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660174259429&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;PORT 포트번호란&quot; data-og-description=&quot;IP와 함께 PORT 번호에 대해서 들어보았을 것이다. TCP 프로토콜을 살펴볼 때 전송하는 패킷에 PORT 번호에 대한 정보가 포함되어 있었는데 PORT 번호가 무엇인지 간단하게 살펴보자. 포트 번호는 해&quot; data-og-host=&quot;javacoding.tistory.com&quot; data-og-source-url=&quot;https://javacoding.tistory.com/163&quot; data-og-url=&quot;https://javacoding.tistory.com/163&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/e3EkO/hyPoszIwcw/Np3ULmQhVDffkwF3KesPbK/img.png?width=694&amp;amp;height=259&amp;amp;face=0_0_694_259,https://scrap.kakaocdn.net/dn/bAyUAa/hyPorOk06E/iqouoQLceyDTL7FgkQPenk/img.png?width=694&amp;amp;height=259&amp;amp;face=0_0_694_259,https://scrap.kakaocdn.net/dn/g5PmO/hyPojW4Sgt/DK9oYfgd0b0ixHOgP0cZkk/img.png?width=733&amp;amp;height=460&amp;amp;face=0_0_733_460&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/163&quot; data-source-url=&quot;https://javacoding.tistory.com/163&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/e3EkO/hyPoszIwcw/Np3ULmQhVDffkwF3KesPbK/img.png?width=694&amp;amp;height=259&amp;amp;face=0_0_694_259,https://scrap.kakaocdn.net/dn/bAyUAa/hyPorOk06E/iqouoQLceyDTL7FgkQPenk/img.png?width=694&amp;amp;height=259&amp;amp;face=0_0_694_259,https://scrap.kakaocdn.net/dn/g5PmO/hyPojW4Sgt/DK9oYfgd0b0ixHOgP0cZkk/img.png?width=733&amp;amp;height=460&amp;amp;face=0_0_733_460');&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;PORT 포트번호란&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;IP와 함께 PORT 번호에 대해서 들어보았을 것이다. TCP 프로토콜을 살펴볼 때 전송하는 패킷에 PORT 번호에 대한 정보가 포함되어 있었는데 PORT 번호가 무엇인지 간단하게 살펴보자. 포트 번호는 해&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;javacoding.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&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;403&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Wiaqc/btrII0Ei7Iq/cpIjuEJEoAEwSYrMkTXwW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Wiaqc/btrII0Ei7Iq/cpIjuEJEoAEwSYrMkTXwW0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Wiaqc/btrII0Ei7Iq/cpIjuEJEoAEwSYrMkTXwW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWiaqc%2FbtrII0Ei7Iq%2FcpIjuEJEoAEwSYrMkTXwW0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/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;403&quot; data-origin-width=&quot;973&quot; data-origin-height=&quot;403&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;내가 100.100.100.1 에서 특정 웹 서버인 200.200.200.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;&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;실제로 우리가 웹 사이트에 접속하거나 API 요청을 할때 IP 주소로 요청을 하는 경우는 드물다. IP 프로토콜의 한계가 있기 때문인데,&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IP 전송 방식의 특징을 살펴보면 다음과 같다.&lt;/p&gt;
&lt;p data-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;span style=&quot;background-color: #ffffff; color: #212529;&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;b&gt;&lt;b&gt;비연결성&lt;/b&gt;&lt;/b&gt;은 서로 연결되지 않은 송신자와 수신자간의 데이터를 전달하는 특징이며&amp;nbsp;&lt;b&gt;비신뢰성&lt;/b&gt;은 IP 프로토콜이 전송하는 정보가 정확하게  전달되었는지 확인하지 않는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&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;따라서 신뢰성있는 통신을 하기 위해서는 상위 레이어의 TCP와 같은 프로토콜을 활용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/162&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://javacoding.tistory.com/162&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1660090014097&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;TCP(Transmission Control Protocol) 프로토콜&quot; data-og-description=&quot;https://javacoding.tistory.com/160 IP(Internet Protocol) 내가 인터넷을 통해 정보를 원하는 곳으로 전달하고자 할 경우, 도착지를 알아야 한다. 나의 주소와 상대의 주소는 어떻게 나타낼 수 있을까? 이때 PC..&quot; data-og-host=&quot;javacoding.tistory.com&quot; data-og-source-url=&quot;https://javacoding.tistory.com/162&quot; data-og-url=&quot;https://javacoding.tistory.com/162&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bsyBxp/hyPosTgnBg/8k3gz3gCfp8PAHdgkzYCC0/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422,https://scrap.kakaocdn.net/dn/bCi6l5/hyPofTVaOm/99JauMCToasauusD6Iu4GK/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422,https://scrap.kakaocdn.net/dn/c2zmR5/hyPodPl3Or/J9f3xx6wFKEUKsUJtAXg7k/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422&quot;&gt;&lt;a href=&quot;https://javacoding.tistory.com/162&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://javacoding.tistory.com/162&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bsyBxp/hyPosTgnBg/8k3gz3gCfp8PAHdgkzYCC0/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422,https://scrap.kakaocdn.net/dn/bCi6l5/hyPofTVaOm/99JauMCToasauusD6Iu4GK/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422,https://scrap.kakaocdn.net/dn/c2zmR5/hyPodPl3Or/J9f3xx6wFKEUKsUJtAXg7k/img.png?width=712&amp;amp;height=422&amp;amp;face=0_0_712_422');&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;TCP(Transmission Control Protocol) 프로토콜&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;https://javacoding.tistory.com/160 IP(Internet Protocol) 내가 인터넷을 통해 정보를 원하는 곳으로 전달하고자 할 경우, 도착지를 알아야 한다. 나의 주소와 상대의 주소는 어떻게 나타낼 수 있을까? 이때 PC..&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;javacoding.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고 강의 : &lt;a href=&quot;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.inflearn.com/course/http-웹-네트워크&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1659483036004&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의&quot; data-og-description=&quot;실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...&quot; data-og-host=&quot;www.inflearn.com&quot; data-og-source-url=&quot;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&quot; data-og-url=&quot;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/3nitu/hyPjl0n7Gu/YOXUL1gIAzvy6edpkuTFOk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/Qzmfc/hyPjmLKIZN/gAKuJxs4vczLH9S8OkjPLk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/c7K1Np/hyPhs06UtH/GNFVBejnoTKuoJBMOgv1GK/img.jpg?width=1200&amp;amp;height=666&amp;amp;face=0_0_1200_666&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.inflearn.com/course/http-%EC%9B%B9-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/3nitu/hyPjl0n7Gu/YOXUL1gIAzvy6edpkuTFOk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/Qzmfc/hyPjmLKIZN/gAKuJxs4vczLH9S8OkjPLk/img.png?width=768&amp;amp;height=500&amp;amp;face=0_0_768_500,https://scrap.kakaocdn.net/dn/c7K1Np/hyPhs06UtH/GNFVBejnoTKuoJBMOgv1GK/img.jpg?width=1200&amp;amp;height=666&amp;amp;face=0_0_1200_666');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.inflearn.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>IT/Web</category>
      <category>http</category>
      <category>internet protocol</category>
      <category>IP</category>
      <category>IP 방식</category>
      <category>IP 프로토콜</category>
      <category>IP란?</category>
      <category>IP주소</category>
      <category>TCP</category>
      <category>비신뢰성</category>
      <category>비연결성</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/160</guid>
      <comments>https://javacoding.tistory.com/160#entry160comment</comments>
      <pubDate>Wed, 3 Aug 2022 08:31:56 +0900</pubDate>
    </item>
    <item>
      <title>Flutter DEBUG mark 지우기</title>
      <link>https://javacoding.tistory.com/158</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-origin-width=&quot;442&quot; data-origin-height=&quot;560&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bD7wyq/btrFFPFLAMS/YJFFXLvqbaGPd9yKh6C7P0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bD7wyq/btrFFPFLAMS/YJFFXLvqbaGPd9yKh6C7P0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bD7wyq/btrFFPFLAMS/YJFFXLvqbaGPd9yKh6C7P0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbD7wyq%2FbtrFFPFLAMS%2FYJFFXLvqbaGPd9yKh6C7P0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;442&quot; height=&quot;560&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;560&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter 개발 중에 시뮬레이터를 사용해서 테스트 하다 보면 우측 상단에 DEBUG가 적힌 리본이 보이는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가끔 모바일 기기에서 테스트 해보기도 하는데 이 마크가 은근 거슬린다.&lt;/p&gt;
&lt;p data-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: #f89009;&quot;&gt;&lt;b&gt;debugShowCheckedModeBanner&lt;/b&gt;&lt;/span&gt; 라는 옵션을 &lt;b&gt;&lt;span style=&quot;color: #f89009;&quot;&gt;false&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&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crOqPg/btrFImodTGu/QViDhbIhgqIOyXaO1EPzoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crOqPg/btrFImodTGu/QViDhbIhgqIOyXaO1EPzoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crOqPg/btrFImodTGu/QViDhbIhgqIOyXaO1EPzoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcrOqPg%2FbtrFImodTGu%2FQViDhbIhgqIOyXaO1EPzoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;605&quot; height=&quot;175&quot; data-origin-width=&quot;605&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>debugShowCheckedModeBanner</category>
      <category>flutter debug</category>
      <category>flutter debug mark</category>
      <category>flutter debug mode</category>
      <category>flutter debug remove</category>
      <category>flutter simulator debug</category>
      <category>remove debug mark</category>
      <category>simulator debug mark</category>
      <category>디버그 표시 제거</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/158</guid>
      <comments>https://javacoding.tistory.com/158#entry158comment</comments>
      <pubDate>Sat, 25 Jun 2022 12:24:13 +0900</pubDate>
    </item>
    <item>
      <title>Flutter - const Constructor</title>
      <link>https://javacoding.tistory.com/157</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Flutter를 공부하다가 const constructor에 대해서 알게 되었다. 알아둘 만한 내용이어서 기록해둘까 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확히 말하면 Dart언어의 const constructor인데, 가장 쉬운 예시는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1655015632417&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const var title = const Text('Hi!')&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;const를 왜 쓸까?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const 생성자를 사용하는 이유는 &lt;b&gt;최적화&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴파일러는 모든 const 객체에 대해 동일한 메모리 부분을 할당하여 객체를 불변으로 만든다. 쉽게 말하면 const로 지정해두면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱을 실행할 때 한 번만 생성한다는 것인데, 한 번만 만들기 때문에 리소스 낭비를 하지 않는다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const와 관련해서 가장 많이 비교하는게 const와 final이 있는데, 간단히만 적어두자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 dart 언어에는 final과 const가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 가지의 공통점은 '&lt;span data-token-index=&quot;1&quot; data-reactroot=&quot;&quot;&gt;한 번 설정한 값을 변경할 수 없다. 다른 값으로 변경하려고 시도하면 컴파일 오류가 발생한다.'&lt;/span&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 두 방식의 차이점으로는 const의 경우, 컴파일 타임에서 상수를 정의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴파일 타임에서 정의하고, 런타임에서 상수는 정의할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 보자면, Datetime.now()로 정의되는 값은, 런타임에서 결정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기 때문에 final로 Datetime.now()를 정의할 수 있지만, const로는 정의할 수 없다.&lt;/p&gt;
&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: #c14c8a;&quot; data-token-index=&quot;3&quot; data-reactroot=&quot;&quot;&gt;const는 그럼 언제 쓰는게 좋을까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 내에서 setState()를 사용할 경우가 굉장히 많아질텐데, setState()를 실행하면 범위에 해당하는 변수들이 모두 재생성된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Text()와 같은 정해진 상수의 경우에는 매번 재생성하는 것이 내부 리소스를 낭비하는 것이기 때문에, 이럴 때에는 const를 사용하여 자원을 낭비하지 않도록 해주는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1655016014356&quot; class=&quot;go&quot; data-ke-language=&quot;go&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const Text('build',)&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;간단히 Text 뿐만 아니라 간단한 Widget의 경우에도 const로 정의할 수 있기 때문에,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const 정의가 가능한 경우에는 const를 사용하도록 하자.&lt;/p&gt;</description>
      <category>IT</category>
      <category>const</category>
      <category>const constructor</category>
      <category>final</category>
      <category>flutter</category>
      <category>flutter const</category>
      <category>flutter final</category>
      <category>플러터</category>
      <category>플러터 const</category>
      <category>플러터 기초</category>
      <category>플러터 코딩</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/157</guid>
      <comments>https://javacoding.tistory.com/157#entry157comment</comments>
      <pubDate>Sun, 12 Jun 2022 15:43:24 +0900</pubDate>
    </item>
    <item>
      <title>오스윗리버 1박 2일 후기 (+글램핑)</title>
      <link>https://javacoding.tistory.com/156</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안녕하세요 ~&lt;br /&gt;이번에 회사에서 연수원으로 사용하는 곳을 &lt;br /&gt;숙박시설로 사용할 수 있다고 하여!!&lt;br /&gt;신청을 한 뒤에 당첨 안내를 받고&lt;br /&gt;오스윗리버에 다녀오게 되었습니다  &lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;3시에 체크인을 한 후 저희가 묵을 숙소는&lt;br /&gt;타워형 302호!&lt;br /&gt;들어가자마자 거실에서 보이는 뷰는&lt;br /&gt;끝내주더라구요  &lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;숙소에 집기류, 오븐, 세탁기 등등 거의 대부분이 비치되어 있었구요, 그 중 정수기가 있어서 너무 편리했습니다!!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c3rfEj/btriB6pId81/9jnTKU8tbSxH3LEBomuPMK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c3rfEj/btriB6pId81/9jnTKU8tbSxH3LEBomuPMK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c3rfEj/btriB6pId81/9jnTKU8tbSxH3LEBomuPMK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc3rfEj%2FbtriB6pId81%2F9jnTKU8tbSxH3LEBomuPMK%2Fimg.jpg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;방은 3개, 화장실은 2개였습니다&lt;br /&gt;안방에 있는 화장실에 욕조가 있었구요&lt;br /&gt;거실에 있는 다른 한개는 욕조가 없었습니다!&lt;br /&gt;&lt;br /&gt;아래 사진에 보이는 방에 킹사이즈 침대와&lt;br /&gt;욕조가 있는 화장실, 드레스룸, TV가 설치되어있었습니다! 완벽하더라구요  &lt;br /&gt;뷰까지 나이스..! &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;2000&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xzuIw/btriHBWhF4e/w9KmQANNVQYKJ8u6d1phr1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xzuIw/btriHBWhF4e/w9KmQANNVQYKJ8u6d1phr1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xzuIw/btriHBWhF4e/w9KmQANNVQYKJ8u6d1phr1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxzuIw%2FbtriHBWhF4e%2Fw9KmQANNVQYKJ8u6d1phr1%2Fimg.jpg&quot; data-origin-width=&quot;1125&quot; data-origin-height=&quot;2000&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;안방에 있는 화장실 욕조 뷰가 끝내줍니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2690&quot; data-origin-height=&quot;3586&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bMXgvi/btriDyspJ50/EcwkWRjo803Fbxj7en9lAk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bMXgvi/btriDyspJ50/EcwkWRjo803Fbxj7en9lAk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bMXgvi/btriDyspJ50/EcwkWRjo803Fbxj7en9lAk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbMXgvi%2FbtriDyspJ50%2FEcwkWRjo803Fbxj7en9lAk%2Fimg.jpg&quot; data-origin-width=&quot;2690&quot; data-origin-height=&quot;3586&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;다시 보는 거실 뷰&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cv5oyz/btriMJTwHy9/MpVkzd7NOz02K3B6PH1rNK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cv5oyz/btriMJTwHy9/MpVkzd7NOz02K3B6PH1rNK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cv5oyz/btriMJTwHy9/MpVkzd7NOz02K3B6PH1rNK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcv5oyz%2FbtriMJTwHy9%2FMpVkzd7NOz02K3B6PH1rNK%2Fimg.jpg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;저희는 글램핑도 예약했는데요&lt;br /&gt;신청할 때엔 저녁 7-8시로 예약했는데&lt;br /&gt;도착해서 안내 받을때는 &lt;br /&gt;오후 4-7라고 안내해주시더라구요&lt;br /&gt;(이 부분은 저희도 잘 모르는 부분이라&lt;br /&gt;확인을 꼭 하고 가시는 것이 좋을 것 같습니다)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J2UgH/btriB7a2g2F/2k2nskVYkGy7FSskeJlBmk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J2UgH/btriB7a2g2F/2k2nskVYkGy7FSskeJlBmk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J2UgH/btriB7a2g2F/2k2nskVYkGy7FSskeJlBmk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ2UgH%2FbtriB7a2g2F%2F2k2nskVYkGy7FSskeJlBmk%2Fimg.jpg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;글램핑장은 총 3개였습니다&lt;br /&gt;글램핑 안에 내부는 이렇구요 &lt;br /&gt;블루투스 스피커, 냉난방기,&lt;br /&gt;집게, 가위, 숯, 번개탄, 토치가 구비되어 있었습니다&lt;br /&gt;&lt;br /&gt;&lt;b&gt;** 쿠킹호일이 없으니 꼭 준비를 해가셔야 합니다!&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2816&quot; data-origin-height=&quot;3754&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cgJzIz/btriGjhfeZq/rNIzp17jeb5Aays3CE29rk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cgJzIz/btriGjhfeZq/rNIzp17jeb5Aays3CE29rk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cgJzIz/btriGjhfeZq/rNIzp17jeb5Aays3CE29rk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcgJzIz%2FbtriGjhfeZq%2FrNIzp17jeb5Aays3CE29rk%2Fimg.jpg&quot; data-origin-width=&quot;2816&quot; data-origin-height=&quot;3754&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;일회용 접시, 일회용 숟가락, 젓가락, 컵을 넉넉히&lt;br /&gt;챙겨오시는 것을 추천드립니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkVOCO/btriCFrNokL/bKPjUvMYO5tkKkG4zSYHWK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkVOCO/btriCFrNokL/bKPjUvMYO5tkKkG4zSYHWK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkVOCO/btriCFrNokL/bKPjUvMYO5tkKkG4zSYHWK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkVOCO%2FbtriCFrNokL%2FbKPjUvMYO5tkKkG4zSYHWK%2Fimg.jpg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;호일이 없어서 그을음이 올라와 약간의 어려움이&lt;br /&gt;있었지만 그조차도 잊게해주는 맛이었어요ㅠㅠ&lt;br /&gt;분위기도 최고..❤️❤️&lt;br /&gt;호일을 가져왔더라면 이것저것 더 구워먹을 수 있었을 것 같아요!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c8nIpZ/btriFhRuxsr/h5HXKQCK31ya9sUQtsjhMK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c8nIpZ/btriFhRuxsr/h5HXKQCK31ya9sUQtsjhMK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c8nIpZ/btriFhRuxsr/h5HXKQCK31ya9sUQtsjhMK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc8nIpZ%2FbtriFhRuxsr%2Fh5HXKQCK31ya9sUQtsjhMK%2Fimg.jpg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;사용 시간이 다 되어 방에 들어와 2차전을 벌였습니다&lt;br /&gt;ㅋㅋㅋㅋ&lt;br /&gt;&lt;br /&gt;여기까지는 좋았는데..&lt;br /&gt;정말 아쉬운 딱 한가지 문제점이 있더라구요&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: Noto Serif KR;&quot;&gt;바로 이곳엔 수건이 없었다는 점입니다..&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&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;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pT6Mv/btriMJ629bF/MAOP1J0kjbgsF8FQ82W1Bk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pT6Mv/btriMJ629bF/MAOP1J0kjbgsF8FQ82W1Bk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pT6Mv/btriMJ629bF/MAOP1J0kjbgsF8FQ82W1Bk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpT6Mv%2FbtriMJ629bF%2FMAOP1J0kjbgsF8FQ82W1Bk%2Fimg.jpg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;방에서 배부르게 쉰 후에 새벽에 나와서 하늘을 보니&lt;br /&gt;별이 정말 잘 보였습니다&lt;br /&gt;하늘이 깨끗했나봐요  &lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQie5U/btriGkmWeBV/t07cxxY7gbMFlEyRUIR1f0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQie5U/btriGkmWeBV/t07cxxY7gbMFlEyRUIR1f0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQie5U/btriGkmWeBV/t07cxxY7gbMFlEyRUIR1f0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQie5U%2FbtriGkmWeBV%2Ft07cxxY7gbMFlEyRUIR1f0%2Fimg.jpg&quot; data-origin-width=&quot;3024&quot; data-origin-height=&quot;4032&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;북한강 바로 앞에 있는 숙소라&lt;br /&gt;산책 겸 어딜 걸어도 장관이고 포토존 되더라구요&lt;br /&gt;해질녘 노을까지 더해지면 금상첨화 &lt;br /&gt;ㅋㅑ~~~&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;2804&quot; data-origin-height=&quot;3739&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7TYS0/btriDxUCsB6/ZkCfDbyFkKKX5jvHdikcQ1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7TYS0/btriDxUCsB6/ZkCfDbyFkKKX5jvHdikcQ1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7TYS0/btriDxUCsB6/ZkCfDbyFkKKX5jvHdikcQ1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7TYS0%2FbtriDxUCsB6%2FZkCfDbyFkKKX5jvHdikcQ1%2Fimg.jpg&quot; data-origin-width=&quot;2804&quot; data-origin-height=&quot;3739&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;저희가 간 날은 10월 말이라 추웠는데요&lt;br /&gt;숙소 거실에 이런 벽난로가 있어서&lt;br /&gt;너무너무너무 좋았습니다&lt;br /&gt;(진짜 벽난로는 아니구요 ㅋ 히터가 나오더라고요)&lt;br /&gt;이 벽난로 하나로&lt;br /&gt;숙소에 감성 100방울 떨어뜨린 느낌!!!&lt;br /&gt;&lt;br /&gt;난방도 잘 되고 뭐 하나 부족한 점 없이&lt;br /&gt;제대로 힐링하고 와서 너무 만족했던&lt;br /&gt;오스윗리버였습니다&lt;/p&gt;
&lt;figure data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;005&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/005.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/005.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;다음에 또 당첨되면&lt;br /&gt;수건, 호일 꼭꼭 챙겨서 오고싶네요&lt;br /&gt;재방문 의사 100000입니다&lt;br /&gt;&lt;br /&gt;도움이 되셨으면 좋겠어요!!!  &lt;/p&gt;</description>
      <category>여행</category>
      <category>가을여행지</category>
      <category>금남리</category>
      <category>남양주</category>
      <category>남양주여행</category>
      <category>바베큐</category>
      <category>북한강</category>
      <category>북한강숙소</category>
      <category>오스윗리버</category>
      <category>오스윗리버레이크힐</category>
      <category>캠핑</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/156</guid>
      <comments>https://javacoding.tistory.com/156#entry156comment</comments>
      <pubDate>Sun, 24 Oct 2021 23:46:42 +0900</pubDate>
    </item>
    <item>
      <title>금강산 감자탕(방이직영점) 추천해요</title>
      <link>https://javacoding.tistory.com/155</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;SE-81C914BC-55AD-40B5-8A64-947B45913BEA&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;감자탕 부시고 왔습니다!!!!!!!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZFvy3/btrcA1MMA1b/ZFp6kKAmq5Ki40taWbiPY0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZFvy3/btrcA1MMA1b/ZFp6kKAmq5Ki40taWbiPY0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZFvy3/btrcA1MMA1b/ZFp6kKAmq5Ki40taWbiPY0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZFvy3%2FbtrcA1MMA1b%2FZFp6kKAmq5Ki40taWbiPY0%2Fimg.jpg&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-DBFF9F67-7023-4032-9B14-7EA97053B81A&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;올림픽공원 들꽃마루에서 사진찍고&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-148B9C6B-9A9F-4F45-8998-EEE1CB4E41B7&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저녁을 먹기 위해 향한 금강산 감자탕!&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-C1B93574-9410-4F07-A4BB-8EB2FFBEF10C&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저희는 방이직영점으로 다녀왔습니다 ㅎㅎ&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-838F66A6-4B8E-4D5E-AD1C-9FF11A965929&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;SE-BFF3F312-1CC7-4BF4-9DE1-5DF25BD9B234&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;여섯시 좀 안되서 도착했는데 거의 만석이더라구요&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-E0365153-63EB-4A58-8071-7C4E1D7F0870&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;SE-339C14A8-4ABC-497D-81D1-2D7EF7D06E1F&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2명이서 일단 감자탕 소짜리를 시켜보았습니다&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-890E093B-18E2-442D-A04B-0A3273C95FCB&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;29000원이었어요! 감자탕을 많이 먹어보지 않아 잘 몰랐지만, 가격대비 엄청 푸짐하다고 느꼈어요!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WP9WT/btrczJTnceP/dfPOBPa7tIVnKpvM6Pw8sk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WP9WT/btrczJTnceP/dfPOBPa7tIVnKpvM6Pw8sk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WP9WT/btrczJTnceP/dfPOBPa7tIVnKpvM6Pw8sk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWP9WT%2FbtrczJTnceP%2FdfPOBPa7tIVnKpvM6Pw8sk%2Fimg.jpg&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-CC85E1D6-EE93-4BDF-9D49-7582EE00258A&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기본 반찬은 심플합니다 ㅎㅎ&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5rrhI/btrczJTncll/NixeYsTTNJ9SCQvhY9m5P1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5rrhI/btrczJTncll/NixeYsTTNJ9SCQvhY9m5P1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5rrhI/btrczJTncll/NixeYsTTNJ9SCQvhY9m5P1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5rrhI%2FbtrczJTncll%2FNixeYsTTNJ9SCQvhY9m5P1%2Fimg.jpg&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-0F2D252A-BCC5-49F4-A265-16A0D25B74D3&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;양이 미쳤어요.....&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-E97ADA0F-24E8-4B3B-A231-4E31632AD67B&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고기도 맛있고 감자도 많구 국물도 끝내주고요ㅠ&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-AB4DA3A1-3257-4739-8ABC-782A4239DBC1&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;고기를 드시면서 국물을 계속 끓이시면&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-6F28A4A1-386F-43C1-BB07-B8D71D6D48E2&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;국물이 점점 진해지는데.. 소주 그냥 들어갑니다&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-B5C95198-12D1-4D95-8BF1-06344238E001&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;(또 먹고싶어요&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-BCED39AD-042A-4813-993D-96EE888B5B39&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p id=&quot;SE-8995A1E6-61E1-44A3-A2C5-EA9598ADCB6F&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저희 둘은 많이 먹는 편인데도 불구하고 ㅋㅋ&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-4FF61558-F897-46E0-ACDF-DB1BFD836671&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;배불러서 토할뻔했어요 (심지어 아침점심도 안먹음)&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-A38EBA19-EC41-4174-8E93-690FB37484A7&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;볶음밥도 못먹었어요..............&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-FF12BC65-DEB0-49E8-BC9A-F1515A0A37E2&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;320&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dmK2GX/btrcAcVkmc4/XqKPKkehtZHqWbeK3BDth0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dmK2GX/btrcAcVkmc4/XqKPKkehtZHqWbeK3BDth0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dmK2GX/btrcAcVkmc4/XqKPKkehtZHqWbeK3BDth0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/dmK2GX/btrcAcVkmc4/XqKPKkehtZHqWbeK3BDth0/img.gif&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;320&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-FAD37D5F-E824-4614-9853-B066C440A16D&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oSFJt/btrcAbPFqK1/jvvXL5KnnSGyZ0oOnym4gK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oSFJt/btrcAbPFqK1/jvvXL5KnnSGyZ0oOnym4gK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oSFJt/btrcAbPFqK1/jvvXL5KnnSGyZ0oOnym4gK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoSFJt%2FbtrcAbPFqK1%2FjvvXL5KnnSGyZ0oOnym4gK%2Fimg.jpg&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-94E61726-A123-4DCD-8C8B-18B1A7FA3D94&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ㅋㅋㅋ 싹슬이..&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bGqjqo/btrcww7VxkM/1uAnlZyeHkanrftkFnOwVK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bGqjqo/btrcww7VxkM/1uAnlZyeHkanrftkFnOwVK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bGqjqo/btrcww7VxkM/1uAnlZyeHkanrftkFnOwVK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbGqjqo%2Fbtrcww7VxkM%2F1uAnlZyeHkanrftkFnOwVK%2Fimg.jpg&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-0F204B75-87A6-4066-B984-C9E4FFD27F43&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;올림픽공원 들꽃마루와 별로 멀지 않아&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-7BB8F7E1-5AC0-4F4C-BB9D-0EB71686CC95&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;데이트 하시고 점심 저녁으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-7F032574-806B-42B9-887C-11195ACE57FB&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;드시러 가시길 추천드릴게요!&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-491C0338-4345-40CD-A966-2E9C83200A25&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;석촌호수와도 별로 멀지 않더라구요&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/QRw6b/btrcAcOBb5Z/iE6rP6VohzYveKTS3vNpA1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/QRw6b/btrcAcOBb5Z/iE6rP6VohzYveKTS3vNpA1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/QRw6b/btrcAcOBb5Z/iE6rP6VohzYveKTS3vNpA1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FQRw6b%2FbtrcAcOBb5Z%2FiE6rP6VohzYveKTS3vNpA1%2Fimg.jpg&quot; width=&quot;664&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-167130D8-2D14-4DAE-8065-79CB12E1CE10&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;방문했을 때 있었던 스티키몬스터랩 (졸귀ㅠㅠ)&lt;/p&gt;
&lt;p id=&quot;SE-F7B4B04F-23C4-4D9E-BB4B-FC1FA706488A&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이상 금강산 감자탕 리뷰였습니다~~&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-AF24B9E3-4953-443B-82CE-F7069DD7A637&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;다시 한 번 외칠게요 존맛탱구리~~~~!~!~!~!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;320&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xkN4H/btrcxKebXKX/kVrYK1jBBL3SscsyycqnO1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xkN4H/btrcxKebXKX/kVrYK1jBBL3SscsyycqnO1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xkN4H/btrcxKebXKX/kVrYK1jBBL3SscsyycqnO1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/xkN4H/btrcxKebXKX/kVrYK1jBBL3SscsyycqnO1/img.gif&quot; data-origin-width=&quot;370&quot; data-origin-height=&quot;320&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>맛집</category>
      <category>감자탕</category>
      <category>감자탕맛집</category>
      <category>금강산감자탕</category>
      <category>금강산감자탕방이직영점</category>
      <category>방이동</category>
      <category>방이동맛집</category>
      <category>방이역맛집</category>
      <category>방이역찐맛집</category>
      <category>존맛</category>
      <category>존맛감자탕</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/155</guid>
      <comments>https://javacoding.tistory.com/155#entry155comment</comments>
      <pubDate>Wed, 18 Aug 2021 19:55:55 +0900</pubDate>
    </item>
    <item>
      <title>용인 파스타 맛집 다니식당</title>
      <link>https://javacoding.tistory.com/154</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;674&quot; data-filename=&quot;1.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tvpj6/btrczc2x3ww/ojmDEiPk92mA1dmI8fk7K1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tvpj6/btrczc2x3ww/ojmDEiPk92mA1dmI8fk7K1/img.jpg&quot; data-alt=&quot;매운 새우 크림 파스타&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tvpj6/btrczc2x3ww/ojmDEiPk92mA1dmI8fk7K1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ftvpj6%2Fbtrczc2x3ww%2FojmDEiPk92mA1dmI8fk7K1%2Fimg.jpg&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;674&quot; data-filename=&quot;1.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;매운 새우 크림 파스타&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;다니식당에는 파스타 종류가 참 다양한데요&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;이번에는 매운 새우 크림 파스타를 먹어봤습니다!ㅎㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignCenter&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;013&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/013.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/013.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&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;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;담백한게 제 입맛에 완전 잘맞았아요&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-filename=&quot;2.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zzNc7/btrcuq8oE4x/32AyXmv8A0S5MvDdNkRK41/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zzNc7/btrcuq8oE4x/32AyXmv8A0S5MvDdNkRK41/img.jpg&quot; data-alt=&quot;로제 치킨 파스타&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zzNc7/btrcuq8oE4x/32AyXmv8A0S5MvDdNkRK41/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzzNc7%2Fbtrcuq8oE4x%2F32AyXmv8A0S5MvDdNkRK41%2Fimg.jpg&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;898&quot; data-filename=&quot;2.jpeg&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;로제 치킨 파스타&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;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;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;크림 파스타랑은 다른 로제맛 파스타인데요, 일반 엽떡이나 치킨에 들어가는 로제랑 차원이 다른&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;찐 로제맛 나는 파스타입니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote id=&quot;SE-4A3755D9-A8E1-4C13-8A1F-643D00066B19&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;용인 역북동 명지대 앞 맛집&lt;/span&gt;&lt;/blockquote&gt;
&lt;p id=&quot;SE-5CA6722D-FF2D-416C-A916-61ACC4F65CC9&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;​&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-6275B6F0-14E6-4276-A203-07224265BF3F&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;저는 용인 역북 근처에 거주하고 있는 명지대생 입니다 ✌ &lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-904DB5A5-0455-43ED-BE3C-C921CEF08FB1&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;​&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-5D6D4943-B9B1-4A41-8FC7-169804078AEA&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앞으로 졸업하기 전까지 용인 맛집에 대해 자주 올려볼게용&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-04406F43-FD00-42CE-BE45-72B3D0A44D6A&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;​&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-24BB893B-9709-4EE2-9C90-C77F0CCACCBC&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여긴 실패한 적 없는 용인 찐맛집이에요&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-FAA61690-07B9-46A7-AA0F-AAA02EACC321&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;단, 꾸덕한 파스타 좋아하시는 분들에겐 다소 소스가 묽을수도 있다는 점~ 그렇다고 간이 약하거나 그러진 않아요!&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-CA44F96E-EC81-4E88-950A-412C1B6FC162&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;(제가 바로 그 꾸덕한 파스타 좋아하는 1인..)&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-0148B62A-A8A8-420E-B2AC-42C8D1B16813&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;​&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-84641BFC-409F-4A83-8D16-9FFBDF332CCB&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그래도!&lt;/span&gt;&lt;/p&gt;
&lt;p id=&quot;SE-BBE21482-4C35-4DA2-A597-4AB3AF780E4A&quot; style=&quot;text-align: center;&quot; 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 id=&quot;SE-70744485-6933-4F07-BAE1-96C7BFF5B678&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;분위기도 아늑하니 좋더라구여&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;(양도 많음)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;185&quot; data-origin-height=&quot;160&quot; data-ke-mobilestyle=&quot;widthOrigin&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPcNkF/btrczIGTZ7X/vKhMCzi5rf6z70k2TErGw0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPcNkF/btrczIGTZ7X/vKhMCzi5rf6z70k2TErGw0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPcNkF/btrczIGTZ7X/vKhMCzi5rf6z70k2TErGw0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bPcNkF/btrczIGTZ7X/vKhMCzi5rf6z70k2TErGw0/img.gif&quot; data-origin-width=&quot;185&quot; data-origin-height=&quot;160&quot; data-ke-mobilestyle=&quot;widthOrigin&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p id=&quot;SE-A9946904-0497-499A-9B10-13A87D4CF76A&quot; style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;역북동에 생긴건 많은데 뭐 먹지 하시는 분들은 당장 다니식당으로 달려가세요~~~~~~!&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;iframe mapdata=&quot;addr=%EA%B2%BD%EA%B8%B0%20%EC%9A%A9%EC%9D%B8%EC%8B%9C%20%EC%B2%98%EC%9D%B8%EA%B5%AC%20%EC%97%AD%EB%B6%81%EB%8F%99%20757%201%EC%B8%B5%20116%ED%98%B8&amp;amp;addtype=1&amp;amp;confirmid=1834340205&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A541525%2C%22mapCenterY%22%3A1036693%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A541525%2C%22y%22%3A1036695%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EB%8B%A4%EB%8B%88%EC%8B%9D%EB%8B%B9%22%2C%22confirmid%22%3A1834340205%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=541525&amp;amp;mapY=1036693&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=4146152000&amp;amp;tel=&amp;amp;title=%EB%8B%A4%EB%8B%88%EC%8B%9D%EB%8B%B9&quot; src=&quot;/proxy/plusmapViewer.php?id=maps_1629282626390&quot; id=&quot;maps_1629282626390&quot; width=&quot;540px&quot; height=&quot;350px&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-ke-type=&quot;map&quot; data-maps-data=&quot;addr=%EA%B2%BD%EA%B8%B0%20%EC%9A%A9%EC%9D%B8%EC%8B%9C%20%EC%B2%98%EC%9D%B8%EA%B5%AC%20%EC%97%AD%EB%B6%81%EB%8F%99%20757%201%EC%B8%B5%20116%ED%98%B8&amp;amp;addtype=1&amp;amp;confirmid=1834340205&amp;amp;docid=&amp;amp;idx=1&amp;amp;ifrH=362px&amp;amp;ifrW=490px&amp;amp;mapHeight=362&amp;amp;mapInfo=%7B%22version%22%3A2%2C%22mapWidth%22%3A490%2C%22mapHeight%22%3A362%2C%22mapCenterX%22%3A541525%2C%22mapCenterY%22%3A1036693%2C%22mapLevel%22%3A4%2C%22coordinate%22%3A%22wcongnamul%22%2C%22markInfo%22%3A%5B%7B%22markerType%22%3A%22standPlace%22%2C%22coordinate%22%3A%22wcongnamul%22%2C%22x%22%3A541525%2C%22y%22%3A1036695%2C%22clickable%22%3Atrue%2C%22draggable%22%3Atrue%2C%22icon%22%3A%7B%22width%22%3A35%2C%22height%22%3A56%2C%22offsetX%22%3A17%2C%22offsetY%22%3A56%2C%22src%22%3A%22%2F%2Ft1.daumcdn.net%2Flocalimg%2Flocalimages%2F07%2F2012%2Fattach%2Fpc_img%2Fico_marker2_150331.png%22%7D%2C%22content%22%3A%22%EB%8B%A4%EB%8B%88%EC%8B%9D%EB%8B%B9%22%2C%22confirmid%22%3A1834340205%7D%5D%2C%22graphicInfo%22%3A%5B%5D%2C%22roadviewInfo%22%3A%5B%5D%7D&amp;amp;mapWidth=490&amp;amp;mapX=541525&amp;amp;mapY=1036693&amp;amp;map_hybrid=false&amp;amp;map_level=4&amp;amp;map_type=TYPE_MAP&amp;amp;rcode=4146152000&amp;amp;tel=&amp;amp;title=%EB%8B%A4%EB%8B%88%EC%8B%9D%EB%8B%B9&quot; data-maps-mapx=&quot;541525&quot; data-maps-mapy=&quot;1036693&quot; data-maps-thumbnail=&quot;https://ssl.daumcdn.net/map3/staticmap/image?center=541525%2C1036693&amp;amp;lv=4&amp;amp;size=540x350&amp;amp;srs=WCONGNAMUL&amp;amp;markers=symbol%3Asc_marker%7Clocation%3A541525%2C1036695&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>맛집</category>
      <category>다니식당</category>
      <category>로제 파스타</category>
      <category>명지대 맛집</category>
      <category>명지대 파스타</category>
      <category>역북 다니식당</category>
      <category>역북동 맛집</category>
      <category>역북동 파스타</category>
      <category>용인 다니식당</category>
      <category>용인 맛집</category>
      <category>크림 파스타</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/154</guid>
      <comments>https://javacoding.tistory.com/154#entry154comment</comments>
      <pubDate>Wed, 18 Aug 2021 19:36:35 +0900</pubDate>
    </item>
    <item>
      <title>Netty 에코 서버-클라이언트 구현 (feat. 네트워크 소녀 Netty)</title>
      <link>https://javacoding.tistory.com/153</link>
      <description>&lt;h3&gt;에코 서버 구현&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Netty 를 이용하여 에코 서버를 만들어보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;통상적으로 네트워크 프로그램을 배울 때 가장 처음 예제로 에코 서버를 사용하는데&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그 이유는 프로그램의 구현이 간단할 뿐만 아니라 입출력 또는 송수신이라는 기본적인 동작 방식을 이해하는 데 유용하기 때문이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;먼저 &lt;b&gt;Server&lt;/b&gt; 쪽 코드를 작성해보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;8888번 포트를 사용하여 클라이언트의 연결을 대기하고,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;클라이언트 접속 요청에 의해 소켓 채널을 만들고, 소켓으로 데이터가 들어온다면 지정된 &lt;b&gt;EchoServerHandler&lt;/b&gt;가 되돌려주는 간단한 예제이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;// 에코 서버

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class EchoServer {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer&amp;lt;SocketChannel&amp;gt;() {
                        @Override
                        public void initChannel(SocketChannel ch) {
                            ChannelPipeline p = ch.pipeline();
                            p.addLast(new EchoServerHandler());
                        }
                    });
            ChannelFuture f = b.bind(8888).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음은, 서버로 입력된 데이터를 클라이언트에게 에코시키기 위해 필요한 에코 서버 핸들러 코드이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;channelRead&lt;/b&gt; 메서드에서 수신된 메시지를 &lt;b&gt;write()&lt;/b&gt;하고,&lt;/p&gt;
&lt;p&gt;write() 작업이 모두 완료된 후 &lt;b&gt;channelReadComplete&lt;/b&gt;() 메서드를 호출하여 클라이언트로 메시지 데이터를 보내준다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;package com.netty.test;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.concurrent.EventExecutorGroup;

import java.nio.charset.Charset;

public class EchoServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        String readMessage = ((ByteBuf) msg).toString(Charset.defaultCharset());
        System.out.println(&quot;수신한 문자열 [&quot; + readMessage + &quot;]&quot;);
        ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;구현한 &lt;b&gt;에코 서버 핸들러&lt;/b&gt;의 주요 기능은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;입력된 데이터를 처리하는 이벤트 핸들러인 &lt;b&gt;ChannelInboundHandlerAdapter&lt;/b&gt;를 상속받게 지정한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;channelRead&lt;/b&gt;는 데이터 수신 이벤트 처리 메서드다. 클라이언트로부터 데이터의 수신이 이루어졌을 때 네티가 자동으로 호출하는 이벤트 메서드다.&lt;/li&gt;
&lt;li&gt;수신된 데이터를 가지고 있는 네티의 &lt;b&gt;바이트 버퍼(ByteBuf)&lt;/b&gt; 객체로부터 문자열 데이터를 읽어온다.&lt;/li&gt;
&lt;li&gt;수신된 문자열을 콘솔로 출력한다.&lt;/li&gt;
&lt;li&gt;ctx는 &lt;b&gt;ChannelHandlerContext&lt;/b&gt; 인터페이스의 객체로서 채널 파이프라인에 대한 이벤트를 처리한다.
&lt;ul&gt;
&lt;li&gt;여기서는 서버로 연결된 클라이언트 채널로 입력받은 데이터를 그대로 전송하는 역할을 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;channelRead&lt;/b&gt; 이벤트의 처리가 완료된 후 자동으로 수행되는 이벤트 메서드인 &lt;b&gt;channelReadComplete()&lt;/b&gt; 메서드를 이용해 채널 파이프라인에 저장된 버퍼를 전송하는 flush 메서드를 호출한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이렇게 &lt;b&gt;에코 서버&lt;/b&gt; 구현을 완료하였습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이제 &lt;b&gt;에코 클라이언트&lt;/b&gt;도 구현해보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;클라이언트 프로그램은 에코 서버 &lt;b&gt;8888&lt;/b&gt;번 포트로 접속하여 &lt;b&gt;&quot;Hello Netty !&quot;&lt;/b&gt;라는 문자열을 전송하고 서버의 응답을 수신하도록 해보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이어서 수신한 데이터를 화면에 출력하고 연결된 소켓을 종료한다.&lt;/p&gt;
&lt;p&gt;클라이언트 코드도 서버와 마찬가지로 main 메서드가 포함된 &lt;b&gt;EchoClient&lt;/b&gt;와 데이터 핸들러인 &lt;b&gt;EchoClientHandler&lt;/b&gt;로 구성된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;// 에코 클라이언트

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class EchoClient {
    public static void main(String[] args) throws Exception{
        EventLoopGroup group = new NioEventLoopGroup();

        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer&amp;lt;SocketChannel&amp;gt;() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline p = ch.pipeline();
                            p.addLast(new EchoClientHandler());
                        }
                    });
            ChannelFuture f = b.connect(&quot;localhost&quot;, 8888).sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;클라이언트의 main 코드는 서버의 구조와 거의 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;이벤트 루프, 부트스트랩, 채널 파이프라인, 핸들러&lt;/b&gt; 등을 초기화하는 부분은 서버 부분과 거의 동일하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;서버와 다르게 &lt;b&gt;이벤트 루프 그룹&lt;/b&gt;을 &lt;u&gt;&lt;b&gt;하나만 설정&lt;/b&gt;&lt;/u&gt;했다.
&lt;ul&gt;
&lt;li&gt;클라이언트 애플리케이션은 서버에 연결된 채널 하나만 존재하기 때문에 이벤트 루프 그룹이 하나다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;클라이언트 애플리케이션이 생성하는 채널의 종류를 설정한다. 여기서는 NIO 소켓 채널인 &lt;b&gt;NioSocketChannel&lt;/b&gt;을 설정했다.&lt;/li&gt;
&lt;li&gt;채널 파이프라인의 설정에 일반 소켓 채널 클래스인 &lt;b&gt;SocketChannel&lt;/b&gt;을 설정한다.&lt;/li&gt;
&lt;li&gt;비동기 입출력 메서드인 &lt;b&gt;connect&lt;/b&gt;()를 호출한다. connect 메서드는 메서드의 호출 결과로 &lt;b&gt;ChannelFuture&lt;/b&gt; 객체를 돌려주는 이 객체를 통해서 비동기 메서드의 처리 결과를 확인할 수 있다.
&lt;ul&gt;
&lt;li&gt;ChannelFuture 객체의 &lt;b&gt;sync&lt;/b&gt; 메서드는 ChannelFuture 객체의 요청이 완료될 때까지 대기한다. 단, 실패시에는 예외를 던진다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음으로 &lt;b&gt;에코 클라이언트 데이터 핸들러&lt;/b&gt;를 구현해보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;// 클라이언트 핸들러

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.concurrent.EventExecutorGroup;

import java.nio.charset.Charset;

public class EchoClientHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String sendMessage = &quot;Hello, Netty !&quot;;

        ByteBuf messageBuffer = Unpooled.buffer();
        messageBuffer.writeBytes(sendMessage.getBytes());

        StringBuilder builder = new StringBuilder();
        builder.append(&quot;전송한 문자열 [&quot;);
        builder.append(sendMessage);
        builder.append(&quot;]&quot;);

        System.out.println(builder.toString());
        ctx.writeAndFlush(messageBuffer);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        String readMessage = ((ByteBuf)msg).toString(Charset.defaultCharset());

        StringBuilder builder = new StringBuilder();
        builder.append(&quot;수신한 문자열 [&quot;);
        builder.append(readMessage);
        builder.append(&quot;]&quot;);

        System.out.println(builder.toString());
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        ctx.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;서버와 클라이언트 두 핸들러 모두 &lt;b&gt;ChannelInboundHandlerAdapter&lt;/b&gt;를 상속하며 구현했는데,&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;클라이언트 핸들러에는 &lt;b&gt;channelActive&lt;/b&gt; 를 추가했다. 주요 설명은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;ChannelActive&lt;/b&gt; 이벤트는 소켓 채널이 활성화되었을 때 실행된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;writeAndFlush&lt;/b&gt; 메서드는 내부적으로 데이터 기록과 전송의 두 가지 메서드를 호출한다.&lt;/li&gt;
&lt;li&gt;서버로부터 수신된 데이터가 있을 때 &lt;b&gt;channelRead&lt;/b&gt;가 호출된다.&lt;/li&gt;
&lt;li&gt;수신된 데이터를 모두 읽었을 때 &lt;b&gt;channelReadComplete&lt;/b&gt;가 호출된다.&lt;/li&gt;
&lt;li&gt;수신된 데이터를 모두 읽은 후 서버와 연결된 채널을 닫는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이로써 서버와 클라이언트 코드 작성을 완료했다.&lt;/p&gt;
&lt;pre class=&quot;erlang-repl&quot;&gt;&lt;code&gt;// 에코 서버 실행 결과
수신한 문자열 Hello, netty !

// 에코 클라이언트 실행 결과
전송한 문자열 Hello, netty !
수신한 문자열 Hello, netty !&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네티에서 데이터 송신을 &lt;b&gt;아웃바운드 이벤트&lt;/b&gt;, 데이터 수신을 &lt;b&gt;인바운드 이벤트&lt;/b&gt;로 정의하고 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인바운드 이벤트와 아웃바운드 이벤트는 모두 프로그램을 기준으로 정의된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;출처 : &lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=9608322&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;book.naver.com/bookdb/book_detail.nhn?bid=9608322&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1609990588146&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;자바 네트워크 소녀 Netty&quot; data-og-description=&quot;자바 네트워크 프로그래밍의 최고의 선택 NETTY!이 책은 안정성과 성능을 세계적으로 인정받아 카카오톡, 애플, 트위터, 페이스북, 네이버 라인 등에서 사용하는 자바 네트워크 프레임워크 네티&quot; data-og-host=&quot;book.naver.com&quot; data-og-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=9608322&quot; data-og-url=&quot;http://book.naver.com/bookdb/book_detail.nhn?bid=9608322&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bm9wYN/hyIQTPVM6l/Qz8ge22j5H7Dstxkk9pimk/img.jpg?width=140&amp;amp;height=180&amp;amp;face=0_0_140_180&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=9608322&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=9608322&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bm9wYN/hyIQTPVM6l/Qz8ge22j5H7Dstxkk9pimk/img.jpg?width=140&amp;amp;height=180&amp;amp;face=0_0_140_180');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;자바 네트워크 소녀 Netty&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;자바 네트워크 프로그래밍의 최고의 선택 NETTY!이 책은 안정성과 성능을 세계적으로 인정받아 카카오톡, 애플, 트위터, 페이스북, 네이버 라인 등에서 사용하는 자바 네트워크 프레임워크 네티&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;book.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>JAVA Netty</category>
      <category>JAVA 네트워크</category>
      <category>java 코딩</category>
      <category>네트워크 프레임워크</category>
      <category>네트워크 프로그래밍</category>
      <category>네트워크소녀 네티</category>
      <category>에코 서버</category>
      <category>에코 클라이언트</category>
      <category>자바 네티</category>
      <category>자바 비동기</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/153</guid>
      <comments>https://javacoding.tistory.com/153#entry153comment</comments>
      <pubDate>Thu, 7 Jan 2021 12:34:25 +0900</pubDate>
    </item>
    <item>
      <title>Netty 코덱</title>
      <link>https://javacoding.tistory.com/150</link>
      <description>&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;b&gt;코덱(codec)이란?&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;네트워크에서는 데이터를 단순한 원시 바이트의 연속으로 취급하지만 애플리케이션에서는 이러한 바이트를 의미 있는 정보 구조로 만들어야 한다.&lt;/p&gt;
&lt;p&gt;애플리케이션 데이터와 네트워크 포맷 간의 변환을 수행하는 컴포넌트를 각각 &lt;b&gt;인코더&lt;/b&gt;와 &lt;b&gt;디코더&lt;/b&gt;라고 하며, 두 기능을 모두 가진 단일 컴포넌트를 &lt;b&gt;&lt;u&gt;코덱&lt;/u&gt;&lt;/b&gt;이라고 한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;인코더&lt;/u&gt;&lt;/b&gt;는 메시지를 전송하기에 적합한 형식으로 변환하며,&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;디코더&lt;/u&gt;&lt;/b&gt;는 네트워크 스트림을 다시 프로그램의 메시지 포맷으로 변환한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;인코더&lt;/u&gt;&lt;/b&gt;는 &lt;u&gt;아웃바운드 데이터&lt;/u&gt;를 처리하며&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;디코더&lt;/u&gt;&lt;/b&gt;는 인바운드 데이터를 처리한다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;디코더&lt;/h3&gt;
&lt;p&gt;네티의 디코더 클래스는 고유한 두 사용 사례를 지원한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;바이트 스트림을 메시지로 디코딩 : &lt;b&gt;ByteToMessageDecoder&lt;/b&gt; 및 &lt;b&gt;ReplayingDecoder&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;메시지를 다른 메시지 유형으로 디코딩 : &lt;b&gt;MessageToMessageDecoder&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;디코더는 인바운드 데이터를 다른 포맷으로 변환하는 일을 하므로 네티의 디코더는 자연스럽게 &lt;b&gt;ChannelInboundHandler&lt;/b&gt;를 구현한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;디코더는 언제 이용할까?&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;인바운드 데이터를 &lt;b&gt;ChannelPipeline&lt;/b&gt; 내의 &lt;u&gt;&lt;b&gt;다음 ChannelInboundHandler를 위해 변환할 때&lt;/b&gt;&lt;/u&gt; 이용한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;ByteToMessageDecoder&lt;/h4&gt;
&lt;p&gt;바이트 스트림을 메시지로 디코딩하는 작업은 매우 일반적이므로 네티는 이 작업을 위한 기본 클래스인 &lt;b&gt;ByteToMessageDecoder&lt;/b&gt;를 제공한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;원격 피어가 완성된 메시지를 한번에 보낼지는 알 수 없으므로,&lt;/p&gt;
&lt;p&gt;&lt;u&gt;인바운드 데이터가 처리할 만큼 모일 때까지 버퍼에 저장&lt;/u&gt;한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;decode&lt;/b&gt;(CHannelHandlerContext ctx, ByteBuf in, List &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;out) 메서드는&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;ByteBuf&lt;/b&gt;에 &lt;u&gt;읽을 바이트가 없을 때까지 반복&lt;/u&gt;하고&lt;/p&gt;
&lt;p&gt;List가 비어 있지 않은 경우 그 내용을 파이프라인의 &lt;u&gt;다음 핸들러로 전달&lt;/u&gt;한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;02.png&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;261&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cismeY/btqSsSjwlpu/uDDDeRvNhSyvDRDKWDdC2k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cismeY/btqSsSjwlpu/uDDDeRvNhSyvDRDKWDdC2k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cismeY/btqSsSjwlpu/uDDDeRvNhSyvDRDKWDdC2k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcismeY%2FbtqSsSjwlpu%2FuDDDeRvNhSyvDRDKWDdC2k%2Fimg.png&quot; data-filename=&quot;02.png&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;261&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;인바운드 &lt;u&gt;ByteBuf에서 4바이트씩 읽고&lt;/u&gt;, 이를 &lt;u&gt;int로 디코딩&lt;/u&gt;한 후 &lt;u&gt;List로 추가&lt;/u&gt;한다.&lt;/p&gt;
&lt;p&gt;List에 추가할 항목이 더 이상 없는 경우 그 내용을 담아 &lt;u&gt;ChannelInboundHandler로 전달&lt;/u&gt;한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;public class ToIntegerDecoder extends ByteToMessageDecoder {
    @Override
    public void decode(ChannelHandlerContext ctx, ByteBuf in, List&amp;lt;Object&amp;gt; out) throws Exception {
        if(in.readableBytes() &amp;gt;= 4) {
            out.add(in.readInt());
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;MessageToMessageDecoder&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;decode&lt;/b&gt;(CHannelHandlerContext ctx, I msg, List &lt;span style=&quot;letter-spacing: 0px;&quot;&gt;out)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I는 msg 인수의 형식, Object는 디코딩 후 추가될 List이다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;public class IntegerToStringDecoder extends MessageToMessageDecoder&amp;lt;Integer&amp;gt; {
    @Override
    public void decode(ChannelHandlerContext ctx, Integer msg, List&amp;lt;Object&amp;gt; out) throws Exception {
    out.add(String.valueOf(msg));
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;인코더&lt;/h3&gt;
&lt;p&gt;인코더는 ChannelOutboundHandler를 구현하고 아웃바운드 데이터를 한 포맷에서 다른 포맷으로 변환하며, 디코더의 반대 기능을 수행한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;메시지를 바이트로 인코딩&lt;/li&gt;
&lt;li&gt;메시지를 메시지로 인코딩&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;public class ShortToByteEncoder extendss MessageToByteEncoder&amp;lt;Short&amp;gt; {
    @Override
    public void encode(ChannelHandlerContext ctx, Short msg, ByteBuf out) throws Exception {
        out.writeShort(msg);    // Short를 ByteBuf에 기록
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;출처 : 네티인 액션&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1609852223263&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;네티 인 액션&quot; data-og-description=&quot;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&quot; data-og-host=&quot;book.naver.com&quot; data-og-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-url=&quot;http://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bmujbW/hyIPx7AmGH/KAQSK48cMIYT7pSXVVhx8K/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bmujbW/hyIPx7AmGH/KAQSK48cMIYT7pSXVVhx8K/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;네티 인 액션&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;book.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>JAVA Codec</category>
      <category>JAVA Netty</category>
      <category>JAVA 코덱</category>
      <category>Netty 디코더</category>
      <category>Netty 인코더</category>
      <category>네티 기초</category>
      <category>네티 인 액션</category>
      <category>네티 코덱</category>
      <category>자바 Netty</category>
      <category>자바 네티</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/150</guid>
      <comments>https://javacoding.tistory.com/150#entry150comment</comments>
      <pubDate>Tue, 5 Jan 2021 22:06:25 +0900</pubDate>
    </item>
    <item>
      <title>Netty ChannelHandler와 ChannelPipeline</title>
      <link>https://javacoding.tistory.com/149</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이미 앞부분에서 &lt;b&gt;ChannelPipeline&lt;/b&gt;안에 &lt;b&gt;ChannelHandler&lt;/b&gt;를 체인으로 연결해 처리 논리를 구성할 수 있다는 것을 배웠다. 이러한 클래스와 연관된 사용사례들과 &lt;b&gt;ChannelHandlerContext&lt;/b&gt;에 대해서도 알아보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;Channel의 수명주기&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Channel 인터페이스는 ChannelInboundHandler API와 밀접한 관계가 있으며 간단하지만 유용한 상태 모델을 정의한다.&lt;/p&gt;
&lt;p&gt;Channel의 네 가지 상태에 대해 알아보자.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;상태&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;ChannelUnregistered&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel이 생성됐지만 EventLoop에 등록되지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;ChannelRegistered&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel이 EventLoop에 등록됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;ChannelActive&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel이 활성화됨(원격 피어로 연결됨). 이제 데이터를 주고받을 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;ChannelInactive&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel이 원격 피어로 연결되지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Channel의 일반적인 생명 주기는&lt;/p&gt;
&lt;p&gt;&lt;b&gt;ChannelRegistered ==&amp;gt; ChannelActive ==&amp;gt; ChannelInactive ==&amp;gt; ChannelUnregistered&lt;/b&gt; 이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;ChannelHandler 수명주기&lt;/h3&gt;
&lt;p&gt;Channelhandler 인터페이스에서 정의하는 수명주기 메서드에 대해 알아보자. 이러한 메서드는 ChannelHandler가 ChannelPipeline에 추가 또는 제거된 후 호출된다. 각 메서드는 ChannelHandlerContext 인수를 받는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;메서드&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;handlerAdded&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channelhandler가 ChannelPipeline에 추가될 때 호출됨.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;handlerRemoved&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channelhandler가 ChannelPipeline에서 제거될 때 호출됨.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;exceptionCaught&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;ChannelPipeline에서 처리 중에 오류가 발생하면 호출됨.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네티는 다음과 같이 ChannelHandler의 가장 중요한 하위 인터페이스를 정의한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;ChannelInboundHandler&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;모든 유형의 인바운드 데이터와 상태 변경을 처리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ChannelOutboundHandler&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;아웃바운드 데이터를 처리하고 모든 작업의 가로채기를 허용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음으로 이러한 &lt;b&gt;ChannelInboundHandler&lt;/b&gt;와 &lt;b&gt;ChannelOutboundHandler&lt;/b&gt;에 대해 알아보자.&lt;/p&gt;
&lt;h4&gt;ChannelInboundHandler 인터페이스&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;메서드&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;channelRegistered&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel이 EventLoop에 등록되고 입출력을 처리할 수 있으면 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;channelUnregistered&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel이 EventLoop에서 등록 해제되고 입출력을 처리할 수 없으면 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;channelActive&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel의 연결과 바인딩이 완료되어 활성화되면 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;channelInactive&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel이 활성 상태에서 벗어나 로컷 피어에 대한 연결이 해제되면 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;channelReadComplete&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel에서 읽기 작업이 완료되면 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;channelRead&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel에서 데이터를 읽을 때 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;channelWritabilityChanged&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Channel의 기록 가능 상태가 변경되면 호출된다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;userEventTriggered&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;POJO가 ChannelPipeline을 통해서 전달돼서 ChannelInboundHandler.fireUserEventTriggered()가 트리거되면 호출됨.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;b&gt;ChannelInboundHandler&lt;/b&gt; 구현이 channelRead()를 재정의하는 경우 풀링된 ByteBuf 인스턴스의 메모리를 명시적으로 해제하는 역할을 맡는다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네티는 다음 예제와 같이 메모리를 해제할 수 있는 ReferenceCountUtil.release() 메서드를 제공한다.&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;@Sharable
public class DiscardHandler extends ChannelInboundHandlerAdapter {    // ChannelInboundHandlerAdapter를 확장
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {    // 수신한 메시지를 삭제
        ReferenceCountUtil.release(msg);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네티는 &lt;u&gt;해제되지 않은 리소스&lt;/u&gt;를 &lt;b&gt;WARN&lt;/b&gt; 수준 로그 메시지로 로깅하므로 코드에 문제가 되는 인스턴스가 있으면 쉽게 발견할 수 있다. 그러나 이렇게 매번 리소스를 관리하기는 번거로울 수 있으며, &lt;b&gt;&lt;u&gt;SimpleChannelInboundHandler&lt;/u&gt;&lt;/b&gt;를 이용하면 더 쉽게 리소스를 관리할 수 있다. 다음 예제를 보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;@Sharable
public class SimpleDiscardhandler extends SimpleChannelInboundHandler&amp;lt;Object&amp;gt; {    // SimpleChannelInboundHandler를 확장
    @Override
    public void channelRead0(ChannelHandlerContext ctx, Object msg) {
        // 다른 조치를 취할 필요가 없음
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;u&gt;SimpleChannelInboundHandler&lt;/u&gt;&lt;/b&gt;는 &lt;b&gt;리소스를 자동으로 해제&lt;/b&gt;하므로 메시지의 참조도 무효화된다. 즉, 메시지의 참조를 저장해 나중에 이용하려고 하면 안 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;ChannelOutboundHandler 인터페이스&lt;/h4&gt;
&lt;p&gt;아웃바운드 작업과 데이터는 ChannelOutboundHandler에 의해 처리되며, 여기에 포함된 메서드는 Channel, ChannelPipeline, ChannelHandlerContext에서 이용된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;ChannelOutboundHandler&lt;/b&gt;는 주문식으로 작업이나 이벤트를 지연하는 강력한 기능이 있어 정교하게 요청을 처리할 수 있다. 예를 들어 원격 피어에 대한 기록이 일시 중단된 경우 플러시 작업을 지연하고 나중에 재개할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;ChannelOutboundHandler 메서드&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;메서드&lt;/th&gt;
&lt;th&gt;설명&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;bind(ChannelHandlerContext, SocketAddress, ChannelPromise)&lt;/td&gt;
&lt;td&gt;Channel을 로컬 주소로 바인딩 요청 시 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;connect(ChannelHandlerContext, SocketAddress, SocketAddress, ChannelPromise)&lt;/td&gt;
&lt;td&gt;Channel을 원격 피어로 연결 요청 시 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;disconnect(ChannelHandlerContext, ChannelPromise)&lt;/td&gt;
&lt;td&gt;Channel을 원격 피어로부터 연결 해제 요청 시 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;close(ChannelhandlerContext, ChannelPromise)&lt;/td&gt;
&lt;td&gt;Channel을 닫는 요청 시 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;deregister(ChannelHandlerContext, ChannelPromise)&lt;/td&gt;
&lt;td&gt;Channel을 EventLoop에서 등록 해제 요청 시 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;read(ChannelHandlerContext)&lt;/td&gt;
&lt;td&gt;Channel에서 데이터를 읽기 요청 시 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;flush(ChannelHandlerContext)&lt;/td&gt;
&lt;td&gt;Channel을 통해 원격 피어로 큐에 있는 데이터의 플러시 요청 시 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;write(ChannelHandlerContext, Object, ChannelPromise)&lt;/td&gt;
&lt;td&gt;Channel을 통해 원격 피어로 데이터 기록 요청 시 호출됨&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;&lt;code&gt;ChannelPromise와 ChannelFuture 비교&lt;/code&gt;&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;ChannelOutboundHandler에 있는 대부분의 메서드에는 작업이 완료되면 알림을 전달받을 ChannelPromise 인수가 있다. ChannelPromise는 ChannelFuture의 하위 인터페이스로서 setSuccess()나 setFailure() 같은 기록 가능 메서드를 정의해 ChannelFuture를 읽기 전용으로 만든다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;리소스 관리&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;ChannelInboundHandler.channelRead()&lt;/b&gt; 또는 &lt;b&gt;ChannelOutboundHandler.write()&lt;/b&gt;를 호출해 데이터를 대상으로 작업할 때는 &lt;u&gt;리소스 누출이 발생하지 않게 주의해야 한다&lt;/u&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;네티는 참조 카운팅을 이용해 풀링되는 ByteBuf를 관리한다. 네티는 잠재적인 문제 진단을 돕기 위해 애플리케이션 버퍼 할당의 약 1%를 샘플링해 메모리 누출을 검사하는 ResourceLeakDetector 클래스를 제공한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;인바운드 메시지를 소비하는 쉬운 방법&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;u&gt;인바운드 데이터를 소비하고 해제하는 것은 아주 흔한 작업&lt;/u&gt;이다. 네티는 이 작업을 위해 SimpleChannelInboundHandler라는 특수한 ChannelInboundHandler 구현을 제공한다. 이 구현은 메시지가 ChannelRead0()에서 소비되면 &lt;b&gt;&lt;u&gt;자동으로 메시지를 해제&lt;/u&gt;&lt;/b&gt;한다.&lt;/p&gt;
&lt;p&gt;인바운드 핸들러를 활용할 때 &lt;b&gt;기본적으로 SimpleChannelInboundHandler를 사용하는 습관&lt;/b&gt;을 들여 손쉬운 리소스 관리를 하도록 하자.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;아웃바운드에서의 리소스 관리&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;아웃바운드 핸들러에서는 &lt;b&gt;write()&lt;/b&gt; 작업을 처리하고 메시지를 폐기하는 경우 직접 메시지를 해제해야 한다.&lt;/p&gt;
&lt;p&gt;또한 리소스를 해제하는 것 뿐만 아니라 &lt;u&gt;&lt;b&gt;ChannelPromise&lt;/b&gt;에 알리는 것도 중요&lt;/u&gt;하다.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;&lt;b&gt;ChannelFutureListener&lt;/b&gt;가 메시지가 처리된 것에 대한 알림을 받지 못하는 경우가 생길 수 있기 때문&lt;/u&gt;이다.&lt;/p&gt;
&lt;p&gt;따라서, 정리하자면 메시지가 소비 또는 폐기되어 다음 ChannelOutboundHandler로 전달되지 않는 경우 직접 &lt;b&gt;&lt;u&gt;ReferenceCountUtil.release()&lt;/u&gt;&lt;/b&gt;를 호출해야 한다. 전송 레이어에 도달한 메시지는 기록될 때 또는 Channel이 닫힐 때 자동으로 해제된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;ChannelPipeline&lt;/h2&gt;
&lt;p&gt;&lt;b&gt;ChannelPipeline&lt;/b&gt;을 &lt;u&gt;Channel을 통해 오가는 인바운드와 아웃바운드 이벤트를 가로채는 &lt;b&gt;Channelhandler 인스턴스의 체인&lt;/b&gt;&lt;/u&gt;이라고 생각하면, Channelhandler의 상호작용을 쉽게 이해할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;새로운 Channel이 생성될 때마다 새로운 Pipeline이 생성된다. 이 연결은 영구적이며 Channel을 다른 ChannelPipeline과 연결하거나 현재 연결을 해제할 수 없다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음 사항들을 기억해두자.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;ChannelPipeline은 한 Channel과 연결된 여러 ChannelHandler를 포함한다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;필요에 따라 동적으로 ChannelHandler를 추가하고 제거해 동적으로 ChannelPipeline을 수정할 수 있다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ChannelPipeline에는 인바운드와 아웃바운드 이벤트에 반응해 작업을 호출하는 풍부한 API가 있다.&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;ChannelHandlerContext&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;ChannelHandler는 &lt;b&gt;ChannelHandlerContext&lt;/b&gt;를 이용해 해당 ChannelPipeline 및 다른 핸들러와 상호작용할 수 있다. ChannelPipeline의 다음 ChannelHandler에 알림을 전달하는 것은 물론, 속해 있는 ChannelPipeline을 동적으로 수정할수도 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Channel&lt;/b&gt;이나 &lt;b&gt;ChannelPipeline&lt;/b&gt; 인스턴스에서 호출하면 메서드가 전체 파이프라인을 통해 전파된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;반면 동일한 메서드를 &lt;b&gt;ChannelHandlerContext&lt;/b&gt;에서 호출하면 현재 연결된 ChannelHandler에서 시작하며 파이프라인에서 이벤트를 처리할 수 있는 다음 ChannelHandler로만 전파된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;따라서 &lt;u&gt;이벤트 흐름이 짧은 ChannelHandlerContext를 잘 활용하면 성능상 이익을 거둘 수 있다&lt;/u&gt;.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h5&gt;Channel, ChannelPipeline, ChannelHandlerContext에 있는 메서드 동작에 대해 알아보자.&lt;/h5&gt;
&lt;p&gt;다음 예제는 &lt;b&gt;ChannelHandlerContext&lt;/b&gt;에서 Channel에 대한 참조를 얻은 다음, 해당 Channel에서 write()를 호출해 이벤트가 파이프라인 전체를 통과하게 한다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;ChannelHandlerContext ctx = ...;
Channel channel = ctx.channel();
channel.write(Unpooled.copiedBuffer(&quot;Netty in Action&quot;, CharsetUtil.UTF_8));&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;다음 예제도 비슷하지만 이번에는 ChannelPipeline을 통해 기록한다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;ChannelHandlerContext ctx = ...;
ChannelPipeline pipeline = ctx.pipeline();
pipeline.write(Unpooled.copiedBuffer(&quot;Netty in Action&quot;, CharsetUtil.UTF_8));&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Channel 또는 ChannelPipeline에서 호출된 write() 메서드는 파이프라인을 통해 끝까지 전파되는 점은 같지만,&lt;/p&gt;
&lt;p&gt;한 핸들러에서 다음 ChannelHandler단계로 전파하는 일은 &lt;b&gt;ChannelHandlerContext&lt;/b&gt;가 한다는 점이 다르다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;ChannelPipeline의 특정 지점에서 이벤트 전파를 시작하는 이유가 뭘까?&lt;/b&gt;
&lt;ul&gt;
&lt;li&gt;관련이 없는 ChannelHandler를 통과하면서 생기는 &lt;u&gt;오버헤드를 줄일 수 있다.&lt;/u&gt;&lt;/li&gt;
&lt;li&gt;이벤트와 관련된 핸들러에서 이벤트가 처리되는 것을 방지할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ChannelHandlerContext의 write() 호출의 예를 보자.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;ChannelHandlerContext ctx = ...;
ctx.write(Unpooled.copiedBuffer(&quot;Netty in Action&quot;, CharsetUtil.UTF_8));&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;정리&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;channelHandlerContext.jpg&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;320&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRHpRI/btqSgLRIPrs/dLK2aqTkMNCEsMAPuuYhD1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRHpRI/btqSgLRIPrs/dLK2aqTkMNCEsMAPuuYhD1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRHpRI/btqSgLRIPrs/dLK2aqTkMNCEsMAPuuYhD1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRHpRI%2FbtqSgLRIPrs%2FdLK2aqTkMNCEsMAPuuYhD1%2Fimg.jpg&quot; data-filename=&quot;channelHandlerContext.jpg&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;320&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Channel 하나당 ChannelPipeline 1개가 자동 할당된다.&lt;/li&gt;
&lt;li&gt;Pipeline안에는 여러 ChannelHandler로 구성된다.&lt;/li&gt;
&lt;li&gt;Channel, ChannelPipeline 메소드와 ChannelHandlerContext 메서드 적용의 차이점&lt;/li&gt;
&lt;li&gt;Channel, ChannelPipeline, ChannelHandlerContext의 다양한 메서드&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;출처 : 네티인 액션&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1609686007656&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;네티 인 액션&quot; data-og-description=&quot;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&quot; data-og-host=&quot;book.naver.com&quot; data-og-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-url=&quot;http://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eApEmo/hyIOeUzEnQ/2lCmbIOhwJUijQusczANlk/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eApEmo/hyIOeUzEnQ/2lCmbIOhwJUijQusczANlk/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;네티 인 액션&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;book.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>channel</category>
      <category>ChannelHandler</category>
      <category>ChannelHandlerContext</category>
      <category>ChannelPipeline</category>
      <category>InboundHandler</category>
      <category>JAVA Netty</category>
      <category>netty</category>
      <category>Netty ctx</category>
      <category>OutboundHandler</category>
      <category>자바 네티</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/149</guid>
      <comments>https://javacoding.tistory.com/149#entry149comment</comments>
      <pubDate>Sun, 3 Jan 2021 23:53:04 +0900</pubDate>
    </item>
    <item>
      <title>[Springboot/Gradle] JAVA SMTP로 비밀번호 찾기 메일 보내기(NAVER)</title>
      <link>https://javacoding.tistory.com/148</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;간단한 서비스를 개발하다가 회원들의 &lt;b&gt;비밀번호 찾기&amp;nbsp;&lt;/b&gt;기능이 필요하게 되었고,&lt;/p&gt;
&lt;p&gt;이메일 정보를 이용해 해당 기능을 구현하기로 결정하였습니다.&lt;/p&gt;
&lt;p&gt;JAVA SMTP가 잘 되어 있어서 어렵지 않게 구현할 수 있었으며 복잡한 내용은 아니므로 중간중간 사진을 첨부해 참고하기 편하도록 글을 남겨두려 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SMTP란?&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;b&gt;간이 전자 우편 전송 프로토콜&lt;/b&gt;&lt;span&gt;(Simple Mail Transfer Protocol,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;SMTP&lt;/b&gt;&lt;span&gt;)은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%9D%B8%ED%84%B0%EB%84%B7&quot;&gt;인터넷&lt;/a&gt;&lt;span&gt;에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%9D%B4%EB%A9%94%EC%9D%BC&quot;&gt;이메일&lt;/a&gt;&lt;span&gt;을 보내기 위해 이용되는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%ED%86%B5%EC%8B%A0_%ED%94%84%EB%A1%9C%ED%86%A0%EC%BD%9C&quot;&gt;프로토콜&lt;/a&gt;&lt;span&gt;이다. &lt;/span&gt;&lt;span&gt;메일 서버간의 송수신뿐만 아니라, 메일 클라이언트에서 메일 서버로 메일을 보낼 때에도 사용되는 경우가 많다. (출처 : 위키피디아 )&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;간단히 Simple Mail Transfer Protocol의 약어로 이메일을 전송하기 위해서 사용되는 정도로만 기억해두고 시작하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;개발 환경 - [NAVER] Springboot - Gradle&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;우선 기본 개발환경은 &lt;b&gt;Springboot&lt;/b&gt;와 &lt;b&gt;Gradle&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p&gt;Maven환경이어도 크게 다를 건 없지만 라이브러리를 셋팅하는 부분이 조금 다르니 그 부분은 잘 해결해주시길...&lt;/p&gt;
&lt;p&gt;Gmail이나 nate, daum 등 여러 메일이 있지만 사람들이 가장 많이 사용하는 &lt;b&gt;NAVER&lt;/b&gt;를 선택하게 되었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[의존성 설정] build.gradle에 의존성 설정하기&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1609605890645&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-mail'
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;build.gradle에 이렇게 한 줄 적어주시고 [&lt;b&gt;Ctrl + Shift + O&lt;/b&gt;] 눌러서 의존성 설정해주시면 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;gradle.PNG&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;243&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xXfjb/btqSbaKNh4j/hORKXhdjKJCS4YTrtrBbj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xXfjb/btqSbaKNh4j/hORKXhdjKJCS4YTrtrBbj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xXfjb/btqSbaKNh4j/hORKXhdjKJCS4YTrtrBbj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxXfjb%2FbtqSbaKNh4j%2FhORKXhdjKJCS4YTrtrBbj0%2Fimg.png&quot; data-filename=&quot;gradle.PNG&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;243&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[발신자 메일 정보 설정] application.yml에 NAVER 메일 정보 설정하기&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;SMTP를 통해 메일을 발신할 때, 발신자 메일 정보가 필요합니다. 이를 위해 제 NAVER 사용 정보를 application.yml에 지정해두겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1609606419886&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;spring:
  mail:
    host: smtp.naver.com
    port: 465
    username: 이메일@naver.com
    password: 비밀번호
    properties:
      mail.smtp.auth: true
      mail.smtp.ssl.enable: true&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;username에 메일 주소를, password의 비밀번호를 설정해주시면 됩니다. 실제 메일의 ID와 PWD를 입력해야 하니, Git에 커밋하실 때에는 꼭 &lt;b&gt;application.yml을 .gitignore 파일을 통해 계정 정보가 노출되지 않도록 조심하세요!&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;227&quot; data-filename=&quot;yml.PNG&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uItjb/btqSsSaFCAh/lOQKAWaBTgTCJjcBACHjJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uItjb/btqSsSaFCAh/lOQKAWaBTgTCJjcBACHjJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uItjb/btqSsSaFCAh/lOQKAWaBTgTCJjcBACHjJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuItjb%2FbtqSsSaFCAh%2FlOQKAWaBTgTCJjcBACHjJK%2Fimg.png&quot; data-origin-width=&quot;850&quot; data-origin-height=&quot;227&quot; data-filename=&quot;yml.PNG&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;[NAVER 설정] SMTP 사용 설정&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;다음으로 NAVER 계정을 통해 SMTP를 이용하기 위해서, NAVER 계정에 간단한 설정을 해보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;mail.PNG&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;579&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cOEbSD/btqSgNBwYg1/XjOcb2aSdPZWLvmboKqtB0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cOEbSD/btqSgNBwYg1/XjOcb2aSdPZWLvmboKqtB0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cOEbSD/btqSgNBwYg1/XjOcb2aSdPZWLvmboKqtB0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcOEbSD%2FbtqSgNBwYg1%2FXjOcb2aSdPZWLvmboKqtB0%2Fimg.png&quot; data-filename=&quot;mail.PNG&quot; data-origin-width=&quot;302&quot; data-origin-height=&quot;579&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;NAVER 메일에서 위 사진에 보이는 것처럼 톱니바퀴 모양을 눌러주세요.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;mail2.PNG&quot; data-origin-width=&quot;1537&quot; data-origin-height=&quot;769&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPZAna/btqSsSaFFSO/nI72jf61F1QchnsTSPNC30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPZAna/btqSsSaFFSO/nI72jf61F1QchnsTSPNC30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPZAna/btqSsSaFFSO/nI72jf61F1QchnsTSPNC30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPZAna%2FbtqSsSaFFSO%2FnI72jf61F1QchnsTSPNC30%2Fimg.png&quot; data-filename=&quot;mail2.PNG&quot; data-origin-width=&quot;1537&quot; data-origin-height=&quot;769&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;내용을 확인해본 뒤, &lt;b&gt;확인&lt;/b&gt; 버튼을 눌러 설정을 저장합니다.&lt;/p&gt;
&lt;p&gt;이렇게 하면 설정 부분은 모두 끝나게 됩니다.&lt;/p&gt;
&lt;p&gt;그럼 이제 코드에서 실제 메일을 보내보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&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;이제 Controller에 &lt;b&gt;&quot;비밀번호 찾기&quot; API&lt;/b&gt;를 만들어보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;먼저 메일 전송을 위해 JavaMailSender를 받아오겠습니다.&lt;/p&gt;
&lt;p&gt;일반적으로 &lt;b&gt;@Autowired&lt;/b&gt; 어노테이션을 이용하지만, 어노테이션을 선언하지 않은 이유는&lt;/p&gt;
&lt;p&gt;저는 UserController에 &lt;b&gt;@&lt;/b&gt;&lt;span&gt;&lt;b&gt;RequiredArgsConstructor&lt;/b&gt; 어노테이션을 활용하여 &lt;b&gt;@Autowired&lt;/b&gt;는 사용하지 않았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;캡처.PNG&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;248&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bg1Qqt/btqSxCFOif7/KHpe4d8MKucrCpBS6TNLnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bg1Qqt/btqSxCFOif7/KHpe4d8MKucrCpBS6TNLnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bg1Qqt/btqSxCFOif7/KHpe4d8MKucrCpBS6TNLnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbg1Qqt%2FbtqSxCFOif7%2FKHpe4d8MKucrCpBS6TNLnK%2Fimg.png&quot; data-filename=&quot;캡처.PNG&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;248&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위 사진처럼 javaMailSender를 선언해주면 이후 코드에서 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;이전에 build.gradle에서 설정해주었기 때문에 바로 불러올 수 있는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;추가적으로 발신자 메일 주소인 &lt;b&gt;from&lt;/b&gt; 값은 application.yml에 설정한 값을 &lt;b&gt;@Value&lt;/b&gt; 를 통해 가져왔습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그럼 이제 비밀번호 찾기 API에 적용해보도록 하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;b.PNG&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;532&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czdoSN/btqSxBfRmC3/4K8T5Zwvr9vw7PpGJUFos0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czdoSN/btqSxBfRmC3/4K8T5Zwvr9vw7PpGJUFos0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czdoSN/btqSxBfRmC3/4K8T5Zwvr9vw7PpGJUFos0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczdoSN%2FbtqSxBfRmC3%2F4K8T5Zwvr9vw7PpGJUFos0%2Fimg.png&quot; data-filename=&quot;b.PNG&quot; data-origin-width=&quot;1144&quot; data-origin-height=&quot;532&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;우선 MimeMessageHelper를 이용하였습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;비밀번호 찾기 안내 메일에서 이미지까지 첨부하고 싶었기 때문에 선택하게 되었고&lt;/p&gt;
&lt;p&gt;생각보다 사용하기 편하게 메서드가 잘 정의되어 있었기 때문입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;setFrom(발신자 메일 주소), setTo(수신인 주소), setSubject(제목), setText(메일 내용) 등&lt;/p&gt;
&lt;p&gt;메서드 이름만으로도 용도를 이해하기 쉽게 만들어져 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;메일의 본문 내용은 mailBodyUtil.getMailBody() 함수를 직접 정의하였습니다.&lt;/p&gt;
&lt;p&gt;함수는 String 형태로 HTML 코드를 리턴하도록 하였습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;중간에 사용한 addInline() 메서드는 본문에 첨부한 이미지를 위해 사용하였습니다.&lt;/p&gt;
&lt;p&gt;&quot;hago&quot; 라는 이름으로, 본문에서 &lt;span&gt;&amp;lt;img src=&lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;cid:hago&lt;/span&gt;&lt;span&gt;\&quot;&amp;gt; 형태의 HTML을 작성하였기 때문에&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;이미지에 해당하는 파일을 FileDataSource()를 통해 첨부해주는 방식입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;일반적으로 데스크톱에서 테스트 하신다면 FileDataSource(&quot;c:\...&quot;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;) 주소로 파일을 설정해주세요&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;값을 다 설정해준 뒤에는 javaSender.send()를 이용하여 발송해주었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;최종적으로 발송에 성공한 사진을 첨부해두겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;a.PNG&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;835&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/k7YVP/btqSdsZeEc3/gKx3ZrnfBQgiPRejPkEthK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/k7YVP/btqSdsZeEc3/gKx3ZrnfBQgiPRejPkEthK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/k7YVP/btqSdsZeEc3/gKx3ZrnfBQgiPRejPkEthK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fk7YVP%2FbtqSdsZeEc3%2FgKx3ZrnfBQgiPRejPkEthK%2Fimg.png&quot; data-filename=&quot;a.PNG&quot; data-origin-width=&quot;892&quot; data-origin-height=&quot;835&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT/Web</category>
      <category>JAVA SMTP</category>
      <category>JAVA 메일 구현</category>
      <category>JAVA 메일 보내기</category>
      <category>JAVA 메일 전송</category>
      <category>JAVA로 Naver메일 보내기</category>
      <category>naver smtp</category>
      <category>SMTP</category>
      <category>Springboot SMTP</category>
      <category>springboot 메일 인증</category>
      <category>자바 메일 보내기</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/148</guid>
      <comments>https://javacoding.tistory.com/148#entry148comment</comments>
      <pubDate>Sun, 3 Jan 2021 02:10:32 +0900</pubDate>
    </item>
    <item>
      <title>Netty ByteBuf - 바이트 버퍼</title>
      <link>https://javacoding.tistory.com/147</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;앞서 언급한 것처럼 네트워크 데이터의 기본 단위는 항상 &lt;b&gt;바이트&lt;/b&gt;이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;자바 NIO는 &lt;u&gt;ByteBuffer&lt;/u&gt;라는 자체 바이트 컨테이너를 제공하지만 이 클래스는 사용법이 너무 복잡해 사용하기 부담스럽다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네티에는 네트워크 개발자에게 더 나은 API를 제공하는 강력한 구현인 &lt;b&gt;&lt;u&gt;ByteBuf&lt;/u&gt;&lt;/b&gt;가 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네티는 데이터 처리를 위한 API를 &lt;b&gt;ByteBuf&lt;/b&gt; 추상 클래스와 &lt;b&gt;ByteBufHolder&lt;/b&gt; 인터페이스라는 두 컴포넌트를 통해 노출한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ByteBuf API의 장점은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;사용자 정의 버퍼 형식으로 확장할 수 있음&lt;/li&gt;
&lt;li&gt;내장 복합 버퍼 형식을 통해 투명한 &lt;b&gt;제로 카피&lt;/b&gt;를 달성할 수 있음.&lt;/li&gt;
&lt;li&gt;용량을 필요에 따라 확장할 수 있음(JDK의 StringBuilder와 비슷)&lt;/li&gt;
&lt;li&gt;ByteBuffer의 flip() 메서드 호출 없이도 리더와 라이터 모드 전환이 가능함&lt;/li&gt;
&lt;li&gt;읽기와 쓰기에 고유 인덱스를 적용함&lt;/li&gt;
&lt;li&gt;&lt;b&gt;메서드 체인&lt;/b&gt;이 지원됨&lt;/li&gt;
&lt;li&gt;&lt;b&gt;참조 카운팅&lt;/b&gt;이 지원됨&lt;/li&gt;
&lt;li&gt;&lt;b&gt;풀링&lt;/b&gt;이 지원됨&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;ByteBuf&lt;/h3&gt;
&lt;p&gt;모든 네트워크 통신은 직접 다루기 까다로운 바이트 시퀀스를 주고받는 방식으로 이뤄지므로 효율적이고 사용하기 쉬운 데이터 구조가 반드시 필요하다. ByteBuf에 대해 알아보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;작동 방식&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;ByteBuf&lt;/b&gt;는 읽기와 쓰기를 위한 고유한 두 인덱스를 유지한다. ByteBuf에서 데이터를 읽으면 ByteBuf의 &lt;b&gt;&lt;u&gt;readerIndex&lt;/u&gt;&lt;/b&gt;가 읽은 바이트 수만큼 증가한다. 비슷하게 데이터를 기록하면 &lt;b&gt;&lt;u&gt;writerIndex&lt;/u&gt;&lt;/b&gt;가 증가한다.&lt;/p&gt;
&lt;p&gt;ByteBuf 메서드 중 이름이 read나 write로 시작하는 메서드는 해당 인덱스를 증가시키지만,&lt;/p&gt;
&lt;p&gt;이름이 set이나 get으로 시작하는 메서드는 인덱스를 증가시키지 않으며, 메서드의 인수로 전달한 인덱스를 기준으로 작업한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;사용 패턴&lt;/h4&gt;
&lt;p&gt;네티를 사용하는 동안 ByteBuf의 몇 가지 공통적인 사용 패턴을 접하게 된다. 세 가지의 사용 패턴에 대해 알아보자.&lt;/p&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;힙 버퍼&lt;/h4&gt;
&lt;p&gt;보조 배열이라고 하는 &lt;u&gt;가장 자주 이용되는 ByteBuf 패턴&lt;/u&gt;이며, JVM의 &lt;b&gt;힙 공간에 데이터를 저장&lt;/b&gt;한다. 이 패턴은 풀링이 사용되지 않는 경우 빠른 할당과 해제 속도를 보여준다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;ByteBuf heapBuf = ...;
if (heapBuf.hasArray()) {    // ByteBuf에 배열이 있는지 확인
    byte[] array = heapBuf.array();    // 있는 경우 배열의 참조를 얻음
    int offset = heapBuf.arrayOffset() + heapBuf.readerIndex();    // 첫 번째 바이트에 대한 오프셋을 계산
    int length = heapBuf.readableBytes();    // 읽을 수 있는 바이트를 얻음
    handleArray(array, offset, length);    // 배열, 오프셋, 길이를 매개변수로 지정하고 메서드를 호출
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;다이렉트 버퍼&lt;/h4&gt;
&lt;p&gt;ByteBuf의 Javadoc을 보면 &quot;다이렉트 버퍼의 내용은 일반적인 가비지 컬렉션이 적용되는 힙 바깥에 위치한다&quot;라고 명시되어 있다. 다이렉트 버퍼가 &lt;b&gt;네트워크 데이터 전송&lt;/b&gt;에 이상적이기 때문이다. 데이터가 힙 할당 버퍼에 있는 경우 JVM은 소켓을 통해 전송하기 전에 내부적으로 버퍼를 다이렉트 버퍼로 복사해야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;다이렉트 버퍼&lt;/b&gt;의 &lt;u&gt;주요 단점&lt;/u&gt;은 힙 기반 버퍼보다 &lt;u&gt;할당과 해제의 비용 부담이 약간 더 크다는 것&lt;/u&gt;이다. 또한 레거시 코드를 이용하는 경우 다른 단점을 경험할 수 있는데, 데이터가 힙에 있지 않기 때문에 다음 예제에 나오는 것처럼 복사본을 만들어야 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;ByteBuf directBuf = ...;
if (!directBuf.hasArray()) {    // ByteBuf에 보조 배열이 있는 중 확인, 없는 경우 다이렉트 버퍼임
    int length = directBUf.readableBytes();
    byte[] array = new byte[length];
    directBuf.getBytes(directBuf.readerIndex(), array);    // 바이트를 배열로 복사
    handleArray(array, 0, length);
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;복합 버퍼&lt;/h4&gt;
&lt;p&gt;세 번째이자 마지막 패턴은 &lt;b&gt;복합 버퍼&lt;/b&gt;이다. 이 패턴에서는 ByteBuf 인스턴스를 필요에 따라 추가 및 삭제할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;헤더&lt;/b&gt;와 &lt;b&gt;본문&lt;/b&gt;의 두 부분으로 구성되는 메시지를 HTTP를 통해 전송하는 경우를 예로 들어보자. 두 부분은 애플리케이션의 각기 다른 모듈에서 생성되며, 메시지를 전송할 때 조립된다. 애플리케이션에는 동일한 메시지 본문을 여러 메시지에 재사용하는 옵션이 있으며, 이 옵션을 이용하는 경우 각 메시지에 새로운 헤더가 생성된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;CompositeByteBuf&lt;/b&gt;를 이용하면 메시지마다 &lt;b&gt;&lt;u&gt;두 버퍼를 다시 할당할 필요가 없어 아주 편리&lt;/u&gt;&lt;/b&gt;하며, 공통 ByteBuf API를 노출할 때 불필요하게 복사할 필요가 없게 해준다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;composite.png&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;136&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bRaJi2/btqROe0uQuT/COqzDebetlWyl0PcUwbXF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bRaJi2/btqROe0uQuT/COqzDebetlWyl0PcUwbXF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bRaJi2/btqROe0uQuT/COqzDebetlWyl0PcUwbXF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbRaJi2%2FbtqROe0uQuT%2FCOqzDebetlWyl0PcUwbXF1%2Fimg.png&quot; data-filename=&quot;composite.png&quot; data-origin-width=&quot;371&quot; data-origin-height=&quot;136&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;CompositeByteBuf messageBuf = Unpooled.compositeBuffer();
ByteBuf headerBuf = ...;
ByteBuf bodyBuf = ...;
messageBuf.addComponents(headerBuf, bodyBuf);
...
messageBuf.removeComponent(0);    // 헤더를 제거
for (ByteBuf buf : messageBuf) {
    System.out.println(buf.toString());
}&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;ByteBuf 메소드&lt;/h4&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;ByteBuf buffer = ...;

buffer.capacity()    // ByteBuf 인덱스는 [ 0 ~ capacity()-1 ]

buffer.discardReadBytes();    // 이미 읽은 바이트 공간 회수, 메모리 복사로 자주 사용하는건 좋지 않음

buffer.readByte();    // buffer에서 Byte를 읽음

buffer.isReadable();    // 읽을 수 있는 바이트가 있는지 확인

buffer.writableBytes();    // 버퍼에 공간이 충분한지 확인
// ex -&amp;gt; while(buffer.writableBytes() &amp;gt;= 4) ...

buffer.writeBytes(data);        // buffer에 data 내용을 씀
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;readerIndex, writerIndex 인덱스 관리&lt;/h4&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;// 인덱스를 지정한 위치로 이동하려면 readerIndex(int)나 writerIndex(int)를 호출하면 된다.

// clear()를 호출하면 readerIndex와 writerIndex를 모두 0으로 설정할 수 있다.

// clear()는 메모리를 복사하지 않으므로 discardReadBytes()보다 훨씬 비용이 낮다.

// indexOf(val) 지정한 값의 인덱스를 알아낸다.

// forEachByte(ByteBufProcessor.FIND_NUL)    NULL을 찾아낸다.
// forEachByte(ByteBufProcessor.FIND_CR)    리턴문자(\n)를 찾아낸다.&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;파생 버퍼&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;파생 버퍼는 ByteBuf의 내용을 특수한 방법으로 나타내는 뷰를 제공한다. 파생 버퍼의 종류는 다음과 같다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;duplicate()&lt;/li&gt;
&lt;li&gt;slice()&lt;/li&gt;
&lt;li&gt;slice(int, int)&lt;/li&gt;
&lt;li&gt;Unpooled.unmodifiableBuffer(...)&lt;/li&gt;
&lt;li&gt;order(ByteOrder)&lt;/li&gt;
&lt;li&gt;readSlice(int)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;파생 버퍼는 생성하는 비용은 낮지만 파생 버퍼의 내용을 수정하면 &lt;u&gt;원본 인스턴스&lt;/u&gt;까지 수정된다는 데 주의해야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ByteBuf 복사&lt;/p&gt;
&lt;p&gt;기존 버퍼의 복사본이 필요하면 copy()나 copy(int, int)를 이용하면 된다. 파생버퍼와 달리 이 메서드에서 반환하는 ByteBuf는 &lt;b&gt;&lt;u&gt;데이터의 독립된 복사본&lt;/u&gt;&lt;/b&gt;이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;출처 : 네티인 액션&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1609229475820&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;네티 인 액션&quot; data-og-description=&quot;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&quot; data-og-host=&quot;book.naver.com&quot; data-og-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-url=&quot;http://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/qaPJE/hyIJMdwTFH/n7723ht8frvKJQvnJoOvKk/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/qaPJE/hyIJMdwTFH/n7723ht8frvKJQvnJoOvKk/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;네티 인 액션&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;book.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>ByteBuf</category>
      <category>ByteBuffer</category>
      <category>JAVA Netty</category>
      <category>netty</category>
      <category>Netty 기초</category>
      <category>바이트버퍼</category>
      <category>버퍼</category>
      <category>자바 ByteBuf</category>
      <category>자바 네티</category>
      <category>자바 버퍼</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/147</guid>
      <comments>https://javacoding.tistory.com/147#entry147comment</comments>
      <pubDate>Tue, 29 Dec 2020 17:08:56 +0900</pubDate>
    </item>
    <item>
      <title>Netty 전송 API</title>
      <link>https://javacoding.tistory.com/146</link>
      <description>&lt;h1&gt;Ch04. 전송 API&lt;/h1&gt;
&lt;p&gt;네트워크를 통해 전송되는 데이터는 모두 &lt;b&gt;바이트&lt;/b&gt; 형식이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;네티는 모든 전송 구현에 공통 API를 기반 레이어로 활용하므로 JDK를 직접 이용할 때보다 블로킹-논블로킹 변환 작업이 훨씬 간단하게 이루어진다.&lt;/p&gt;
&lt;p&gt;코드가 구현 세부사항으로 오염될 우려가 적고, 전체 코드 기반을 광범위하게 리팩터링할 필요가 없다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;연결을 수락한 다음, 클라이언트로 &quot;Hi!&quot; 라는 메시지를 전송한 뒤 연결을 닫는 간단한 애플리케이션을 작성해보자.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;NettyNioServer&lt;/h1&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.util.CharsetUtil;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;

public class NettyNioServer {
    public static void main(String[] args) throws Exception{
        int port = 8888;
        final ByteBuf buf = Unpooled.copiedBuffer(&quot;Hi! \n&quot;, Charset.forName(&quot;UTF-8&quot;));
        EventLoopGroup group = new NioEventLoopGroup();    // 논블로킹 모드를 위해 NioEventGroup을 이용
        try {
            ServerBootstrap b = new ServerBootstrap();    // ServerBootstrap 생성
            b.group(group).channel(NioServerSocketChannel.class)
                    .localAddress(new InetSocketAddress(port))
                    .childHandler(new ChannelInitializer&amp;lt;SocketChannel&amp;gt;() {    // 연결이 수락될 때마다 호출될 ChannelInitializer를 지정
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){    // 이벤트를 수신하고 처리할 ChannelInboundHandlerAdapter를 추가
                                @Override
                                public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                    ctx.writeAndFlush(buf.duplicate())
                                        .addListener(ChannelFutureListener.CLOSE);
                                }
                            });
                        }
                    });
            ChannelFuture f = b.bind().sync();
            f.channel().closeFuture().sync();
        } finally {
            group.shutdownGracefully();
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;일반적으로 Netty를 사용하지 않은 구현에 비해 가독성이 높고, 간편하다는 것을 알 수 있다.&lt;/p&gt;
&lt;p&gt;모든 구현들이 Channel, ChannelPipeline, ChannelHandler를 기준으로 정의되고 있음을 기억해두자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Channel&lt;/b&gt; 인터페이스는 모든 입출력 작업에 이용되므로 전송 API의 핵심이라고 볼 수 있다.&lt;/p&gt;
&lt;p&gt;Channel에는 &lt;b&gt;ChannelPipeline&lt;/b&gt;과 &lt;b&gt;ChannelConfig&lt;/b&gt; 등이 할당되는데,&lt;/p&gt;
&lt;p&gt;&lt;b&gt;ChannelConfig&lt;/b&gt;는 Channel에 대한 모든 구성 설정을 포함하며, 임시 변경(hot change)을 지원한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;또, Channel은 고유하므로 정렬 순서를 보장하기 위해 java.lang.Comparable을 이용한다. 즉, 고유한 두 Channel 인스턴스가 동일한 해시코드를 반환하는 경우에는 Error가 발생한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;ChannelPipeline&lt;/b&gt;은 인바운드와 아웃바운드 데이터와 이벤트에 적용될 &lt;u&gt;ChannelHandler 인스턴스를 모두 포함&lt;/u&gt;한다.&lt;/p&gt;
&lt;p&gt;일반적인 ChannelPipeline의 용도는 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;데이터를 한 포맷에서 다른 포맷으로 변환&lt;/li&gt;
&lt;li&gt;예외에 대한 알림 제공&lt;/li&gt;
&lt;li&gt;Channel의 활성화 또는 비활성화에 대한 알림 제공&lt;/li&gt;
&lt;li&gt;Channel을 EventLoop에 등록할 때 또는 등록 해제할 때 알림 제공&lt;/li&gt;
&lt;li&gt;사용자 정의 이벤트에 대한 알림 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ChannelHandler 인스턴스를 필요에 따라 추가하거나 제거해 ChannelPipeline을 즉석으로 수정할 수 있으며, 이러한 네티의 특징을 활용하면 아주 유연한 애플리케이션을 개발할 수 있다는 것을 기억하자.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;원격 피어로 데이터를 기록하고 플러시하는 일반적인 Channel 작업의 예를 보자.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;Channel channel = ...
ByteBuf buf = Unpooled.copiedBuffer(&quot;your data&quot;, CharsetUtil.UTF_8);
ChannelFuture cf = channel.writeAndFlush(buf);    // 데이터를 기록하고 플러시
cf.addListerner(new ChannelFutureListener(){    // 기록이 완료되면 알림을 받을 ChannelFutureListener를 추가
    @Override
    public void operationComplete(ChannelFuture future) {
        if(future.isSuccess()){    // 기록이 완료될 경우
            System.out.println(&quot;Write success!&quot;);
        } else {
            System.out.println(&quot;Write error&quot;);    // 오류를 로깅
            future.cause().printStacktrace();
        }
    }
})&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;네티의 Channel 구현은 스레드에 대해 안전하므로&lt;/b&gt; 여러 스레드를 이용하는 경우에도 Channel의 참조를 저장하고 원격 피어에 뭔가를 출력할 때 이용할 수 있다. 다음 예제에는 여러 스레드로 기록을 수행하는 간단한 예를 보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;Channel channel = ...
ByteBuf buf = Unpooled.copiedBuffer(&quot;your data&quot;, CharsetUtil.UTF_8).retain();
Runnable writer = new Runnable() {    // 데이터를 채널로 기록하는 Runnable 생성
    @Override
    public void run() {
        channel.write(buf.duplicate());
    }
};

Executor executor = Executors.newCachedThreadPool();    //  스레드풀 Executor에 대한 참조를 얻음

// 한 스레드에 기록
executor.execute(writer);

// 다른 스레드에 기록
executor.execute(writer);

...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr /&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;NIO&lt;/h4&gt;
&lt;p&gt;NIO는 모든 입출력 작업의 완전한 비동기 구현을 제공하며 셀렉터 기반 API를 활용한다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;셀렉터&lt;/b&gt;의 기본 개념은 &lt;u&gt;Channel의 상태가 변경되면 요청이 알림을 받을 수 있는 레지스트리 역할을 하는 것&lt;/u&gt;이다.&lt;/p&gt;
&lt;p&gt;지원되는 상태 변경은 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;새로운 Channel이 수락되고 준비됨.&lt;/li&gt;
&lt;li&gt;Channel 연결이 완료됨&lt;/li&gt;
&lt;li&gt;Channel에 읽을 데이터가 있음&lt;/li&gt;
&lt;li&gt;Channel을 이용해 데이터를 기록할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;애플리케이션이 상태 변경에 반응한 후에는 셀렉터가 재설정되며 해당 스레드에서 변경을 검사하고 적절하게 반응하는 프로세스가 반복된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;논블로킹 코드 기반의 환경에서..&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;코드 기반에 블로킹 호출이 없거나 블로킹 호출을 제한할 수 있다면 &lt;b&gt;NIO&lt;/b&gt; 또는 &lt;b&gt;epoll&lt;/b&gt;(리눅스의 경우)을 이용하는 것이 좋다. &lt;u&gt;다수의 동시 연결을 처리&lt;/u&gt;하기 위한 것이지만 동시 연결이 많지 않은 경우에도 아주 잘 작동한다. 특히 &lt;u&gt;여러 연결에 스레드를 공유할 수 있다는 것이 장점&lt;/u&gt;이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;출처 : 네티인 액션&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1609164554249&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;네티 인 액션&quot; data-og-description=&quot;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&quot; data-og-host=&quot;book.naver.com&quot; data-og-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-url=&quot;http://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ruxEe/hyIJRFhAsY/FvPKDfVZO2FKAOoru6kJ71/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ruxEe/hyIJRFhAsY/FvPKDfVZO2FKAOoru6kJ71/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;네티 인 액션&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;book.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>JAVA Netty</category>
      <category>JAVA 논블로킹</category>
      <category>netty</category>
      <category>Netty Channel</category>
      <category>Netty NIO</category>
      <category>Netty Selector</category>
      <category>Netty 전송</category>
      <category>nio</category>
      <category>논블로킹</category>
      <category>자바 네티</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/146</guid>
      <comments>https://javacoding.tistory.com/146#entry146comment</comments>
      <pubDate>Mon, 28 Dec 2020 23:07:04 +0900</pubDate>
    </item>
    <item>
      <title>Netty 컴포넌트와 설계</title>
      <link>https://javacoding.tistory.com/145</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Channel, EventLoop, ChannelFuture&lt;/h2&gt;
&lt;p&gt;이제 네티의 네트워킹 추상화를 대표한다고 말할 수 있는 Channel, EventLoop, ChannelFuture 클래스를 더 자세히 알아보자. 이 세 가지 개념의 기능들을 다음과 같이 요약해볼 수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Channel&lt;/b&gt; : 소켓(Socket)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;EventLoop&lt;/b&gt; : 제어 흐름, 멀티스레딩, 동시성 제어&lt;/li&gt;
&lt;li&gt;&lt;b&gt;ChannelFuture&lt;/b&gt; : 비동기 알림&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Channel 인터페이스&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;자바 기반 네트워크에서 기본 구조는 &lt;b&gt;Socket&lt;/b&gt; 클래스다. 네티의 &lt;b&gt;Channel&lt;/b&gt; 인터페이스는 &lt;u&gt;&lt;b&gt;Socket으로 직접 작업할 때의 복잡성을 크게 완화하는 API를 제공&lt;/b&gt;&lt;/u&gt;한다.&lt;/p&gt;
&lt;p&gt;ex) EmbeddedChannel, LocalServerChannel, NioDatagramChannel, NioSctpChannel, NioSocketChannel...&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;EventLoop 인터페이스&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;EventLoop&lt;/b&gt;는 &lt;u&gt;&lt;b&gt;연결의 수명주기 중 발생하는 이벤트를 처리하는 네티의 핵심 추상화를 정의&lt;/b&gt;&lt;/u&gt;한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;다음 그림은 Channel, EventLoop, EventLoopGroup 간의 관계를 개략적으로 보여준다.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;이러한 관계를 정리하면 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;EventLoopGroup&lt;/b&gt;은 하나 이상의 &lt;b&gt;EventLoop&lt;/b&gt;를 포함한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;EventLoopGroup&lt;/b&gt;은 &lt;b&gt;Channel&lt;/b&gt;에 &lt;b&gt;EventLoop&lt;/b&gt;를 할당&lt;/li&gt;
&lt;li&gt;&lt;b&gt;EventLoop&lt;/b&gt;는 수명주기 동안 하나의 &lt;b&gt;Thread&lt;/b&gt;로 바인딩된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;EventLoop&lt;/b&gt;에서 처리되는 모든 입출력 이벤트는 해당 전용 &lt;b&gt;Thread&lt;/b&gt;에서 처리된다.&lt;/li&gt;
&lt;li&gt;하나의 &lt;b&gt;Channel&lt;/b&gt;은 수명주기 동안 하나의 &lt;b&gt;EventLoop&lt;/b&gt;에 등록할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;EventLoop&lt;/b&gt;를 하나 이상의 &lt;b&gt;Channel&lt;/b&gt;로 할당할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;2322&quot; data-origin-height=&quot;1460&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HwKiE/btqQE9ArMgQ/fWRfQ9RZ0mvqkY8DrElkG1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HwKiE/btqQE9ArMgQ/fWRfQ9RZ0mvqkY8DrElkG1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HwKiE/btqQE9ArMgQ/fWRfQ9RZ0mvqkY8DrElkG1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHwKiE%2FbtqQE9ArMgQ%2FfWRfQ9RZ0mvqkY8DrElkG1%2Fimg.jpg&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;2322&quot; data-origin-height=&quot;1460&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ChannelFuture 인터페이스&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;이전에 설명했듯이 네티의 모든 입출력 작업은 &lt;b&gt;비동기&lt;/b&gt;적이다. 즉, 작업이 즉시 반환되지 않을 수 있으므로 나중에 결과를 확인하는 방법이 필요하다. 이를 위해 네티는 &lt;b&gt;ChannelFuture&lt;/b&gt;를 제공하며, 이 인터페이스의 &lt;u&gt;&lt;b&gt;addListener() 메서드는 작업이 완료되면 알림을 받을 ChannelFutureListener 하나를 등록&lt;/b&gt;&lt;/u&gt;한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;ChannelFuture&lt;/b&gt;는 미래에 실행될 작업의 결과를 위한 표시자라고 생각할 수 있다. 실행되는 시점은 여러 요소에 의해 좌우되므로 정확한 시점을 예측하기는 불가능하지만 실행된다는 점은 확실하다. 또한 동일한 Channel에 속하는 모든 작업은 호출된 순서와 동일한 순서로 실행된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ChannelHandler 인터페이스&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;개발자의 관점에서 네티의 핵심 컴포넌트는 인바운드와 아웃바운드 데이터의 처리에 적용되는 &lt;u&gt;모든 애플리케이션 논리의 컨테이너 역할을 하는&lt;/u&gt; &lt;b&gt;ChannelHandler&lt;/b&gt;이다.&lt;/p&gt;
&lt;p&gt;이런게 가능한 이유는 ChannelHandler의 메서드가 네트워크 이벤트에 의해 트리거되기 때문이다.&lt;/p&gt;
&lt;p&gt;실제로 ChennelHandler는 데이터를 변환하거나 예외를 처리하는 등 거의 모든 종류의 작업에 활용할 수 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ChannelPipeline 인터페이스&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;ChannelPipeline은 ChannelHandler 체인을 위한 컨테이너를 제공하며, 체인 상에서 &lt;u&gt;인바운드와 아웃바운드 이벤트를 전파하는 API&lt;/u&gt;를 정의한다.&lt;/p&gt;
&lt;p&gt;Channel이 생성되면 여기에 자동으로 자체적인 ChannelPipeline이 할당된다. ChannelHandler는 다음과 같이 ChannelPipeline 안에 설치된다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;ChannelInitializer&lt;/b&gt; 구현은 &lt;b&gt;ServerBootstrap&lt;/b&gt;에 등록된다.&lt;/li&gt;
&lt;li&gt;ChannelInitializer.&lt;b&gt;initChannel()&lt;/b&gt;이 호출되면 ChannelInitializer가 &lt;b&gt;ChannelPipeline&lt;/b&gt;과 &lt;b&gt;ChannelHandler&lt;/b&gt;의 커스텀 집합을 파이프라인에 설치한다.&lt;/li&gt;
&lt;li&gt;ChannelInitializer는 ChannelPipeline에서 자신을 제거한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;데이터를 전송하거나 수신할 때 어떤 일이 일어나는지 확인하면서 ChannelHandler와 ChannelPipeline간의 관계를 더 자세히 알아보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;ChannelHandler&lt;/b&gt;는 ChannelPipeline을 통해 오가는 이벤트를 처리 코드를 위한 &lt;b&gt;범용 컨테이너&lt;/b&gt;라고 할 수 있다.&lt;/p&gt;
&lt;p&gt;파이프라인을 통해 이벤트를 이동시키는 역할은 Channelhandler가 담당한다.&lt;/p&gt;
&lt;p&gt;이벤트를 수신하고, 구현된 처리 논리를 실행하며 체인 상의 다음 핸들러로 데이터를 전달한다.&lt;/p&gt;
&lt;p&gt;핸들러가 실행되는 순서는 추가된 순서에 의해 결정된다.&lt;/p&gt;
&lt;p&gt;ChannelPipeline이라고 말할 때는 이러한 Channelhandler의 정렬된 배치 전체를 의미한다고 보면 된다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;41810890-b84ea390-7740-11e8-8b97-ee582172eab3.jpeg&quot; data-origin-width=&quot;866&quot; data-origin-height=&quot;334&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bVcupH/btqQNpuS3FD/oTzzEyJOioQ3NV2lgwFsV0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bVcupH/btqQNpuS3FD/oTzzEyJOioQ3NV2lgwFsV0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bVcupH/btqQNpuS3FD/oTzzEyJOioQ3NV2lgwFsV0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbVcupH%2FbtqQNpuS3FD%2FoTzzEyJOioQ3NV2lgwFsV0%2Fimg.jpg&quot; data-filename=&quot;41810890-b84ea390-7740-11e8-8b97-ee582172eab3.jpeg&quot; data-origin-width=&quot;866&quot; data-origin-height=&quot;334&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;클라이언트의 관점에서 서버로 움직이는 이벤트는 &lt;b&gt;아웃바운드&lt;/b&gt;이며, 그 반대는 &lt;b&gt;인바운드&lt;/b&gt;다.&lt;/p&gt;
&lt;p&gt;그림을 보면 인바운드와 아웃바운드 이벤트를 동일한 파이프라인에 설치할 수 있음을 알 수 있다. 메시지나 다른 인바운드 이벤트를 읽을 때는 파이프라인의 앞쪽에서 시작하며 첫 번째 ChannelInboundHandler로 전달된다. 데이터를 처리한 후에는 다음 ChannelInboundHandler로 데이터를 전달한다. 최종적으로 파이프라인의 뒤쪽에 이르면 모든 처리가 종료된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;데이터의 아웃바운드 이동 역시 개념상 동일하며 ChannelOutboundHandler가 뒤쪽에서 시작해 앞쪽까지 이를 때까지 이동한다. 이 지점에서 아웃바운드 데이터는 그림에 Socket으로 나오는 네트워크 전송에 도달한다. 보통은 이때 쓰기 작업이 트리거된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;인코더와 디코더&lt;/h2&gt;
&lt;p&gt;Netty로 메시지를 전송하거나 수신할 때는 데이터를 변환해야 한다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;u&gt;인바운드 메시지&lt;/u&gt;는 &lt;b&gt;바이트&lt;/b&gt;에서 &lt;b&gt;다른 포맷(보통 자바 객체)&lt;/b&gt;으로 변환되는 &lt;b&gt;디코딩&lt;/b&gt;을 거친다.&lt;/p&gt;
&lt;p&gt;&lt;u&gt;아웃바운드 메시지&lt;/u&gt;는 반대로 &lt;b&gt;현재 포맷&lt;/b&gt;에서 &lt;b&gt;바이트&lt;/b&gt;로 &lt;b&gt;인코딩&lt;/b&gt;된다.&lt;/p&gt;
&lt;p&gt;이러한 두 가지 변환이 필요한 이유는 &lt;u&gt;&lt;b&gt;네트워크 데이터는 반드시 연속된 바이트여야하기 때문&lt;/b&gt;&lt;/u&gt;이다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;부트스트랩&lt;/h2&gt;
&lt;p&gt;네티의 &lt;b&gt;부트스트랩&lt;/b&gt; 클래스는 &lt;b&gt;프로세스를 지정된 포트로 바인딩(서버 부트스트랩)&lt;/b&gt;하거나 프로세스를 &lt;b&gt;지정된 호스트의 지정된 포트에서 실행중인 다른 호스트로 연결(클라이언트 부트스트랩)&lt;/b&gt;하는 등의 일을 하는 애플리케이션의 네트워크 레이어를 구성하는 컨테이너를 제공한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;서버 부트스트랩은 ServerBootstrap을 이용하고 클라이언트 부트스트랩은 Bootstrap을 이용한다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;3.jpg&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfIDsc/btqQIVO6Zks/2PKqbbxAtTi95YV35i4eV1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfIDsc/btqQIVO6Zks/2PKqbbxAtTi95YV35i4eV1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfIDsc/btqQIVO6Zks/2PKqbbxAtTi95YV35i4eV1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfIDsc%2FbtqQIVO6Zks%2F2PKqbbxAtTi95YV35i4eV1%2Fimg.jpg&quot; data-filename=&quot;3.jpg&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;286&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;클라이언트를 부트스트랩할 때는 EventLoopGroup 하나가 필요하지만 서버는 두 개가 필요하다.&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;서버는 각기 다른 Channel의 두 집합을 필요로 한다.&lt;/p&gt;
&lt;p&gt;첫 번째 집합은 &lt;b&gt;로컬 포트로 바인딩된 서버 자체&lt;/b&gt;의 소켓을 나타내는 ServerChannel&lt;/p&gt;
&lt;p&gt;두 번째 집합은 &lt;b&gt;서버가 수락한 연결마다 하나씩 들어오는 클라이언트 연결을 처리하기 위해 생성된 모든 Channel&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;u&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/u&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Channel&lt;/span&gt;: &lt;/b&gt;자바 기반 네트워크에서 기본 입출력 작업을 하며 소켓(Socket)으로 작업할 때의 복잡성을 완화시켜주는 API&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Socket 통신에서 Socket 정도로 생각해두자.&lt;/p&gt;
&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;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;ChannelFuture&lt;/span&gt;&lt;/span&gt;:&amp;nbsp;&lt;/b&gt;비동기&amp;nbsp;작업에서&amp;nbsp;알림&amp;nbsp;기능을&amp;nbsp;함.&amp;nbsp;특정&amp;nbsp;시점에&amp;nbsp;할&amp;nbsp;행동들을&amp;nbsp;정의할&amp;nbsp;수&amp;nbsp;있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(&amp;nbsp;ex_채널이&amp;nbsp;연결되면&amp;nbsp;인증과정을&amp;nbsp;해라.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 설명한 것처럼 약속된 미래의 시점으로 생각해두자.(채널 연결됨, 채널 연결 끊어짐 등..)&lt;/p&gt;
&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;br /&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;ChannelPipeLine&lt;/span&gt;&lt;/span&gt;:&lt;/b&gt;&amp;nbsp;ChannelHandler&amp;nbsp;체인을&amp;nbsp;위한&amp;nbsp;컨테이너&amp;nbsp;역할.&amp;nbsp;채널이&amp;nbsp;생성되면&amp;nbsp;ChanelPipeline은&amp;nbsp;자동으로&amp;nbsp;할당된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Channel에 할당된 InboundHandler, OutboundHandler 등 이벤트들이 Channel 내에서 움직이는 통로 정도로 생각하자.&lt;/p&gt;
&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;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;ChannelHandler&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;/b&gt;이벤트&amp;nbsp;수신,&amp;nbsp;구현된&amp;nbsp;이벤트&amp;nbsp;논리&amp;nbsp;실행,&amp;nbsp;다음&amp;nbsp;핸들러로&amp;nbsp;데이터&amp;nbsp;전달&amp;nbsp;등&amp;nbsp;모든&amp;nbsp;애플리케이션&amp;nbsp;논리의&amp;nbsp;컨테이너&amp;nbsp;역할을&amp;nbsp;함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Channel 통로를 타고 이동하는 이벤트들.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ex ) 나는 서버에 채널이 연결되면 &quot;Hello&quot; 라고 보내야지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-&amp;gt; ChannelInboundHandler에서 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;channelActive()&lt;/span&gt; &lt;/b&gt;메소드에 &quot;Hello&quot; 를 전송하도록 설정.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EventLoopGroup&amp;nbsp;&lt;/span&gt;:&amp;nbsp;&lt;/b&gt;EventLoop들을&amp;nbsp;포함하는Group&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;br /&gt;&lt;span style=&quot;color: #006dd7; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EventLoop&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #006dd7; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;&lt;/span&gt;:&amp;nbsp;수명&amp;nbsp;주기동안&amp;nbsp;하나의&amp;nbsp;쓰레드로&amp;nbsp;바인딩되며&amp;nbsp;이벤트를&amp;nbsp;관리하여&amp;nbsp;제어흐름,&amp;nbsp;멀티스레딩,&amp;nbsp;동시성&amp;nbsp;제어&amp;nbsp;등의&amp;nbsp;기능을&amp;nbsp;수행할&amp;nbsp;수&amp;nbsp;있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Channel과 연결할 이벤트 묶음으로 생각해두자. Handler로 정의된 이벤트들의 묶음 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Channel당 하나의 EventLoop로 할당되므로 내가 (서버 또는 클라이언트에) 할당해줄 이벤트의 묶음을 EventLoop에 모아서 Channel에 할당해줄꺼야!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;네트워크 데이터는 연속된 &lt;u&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;바이트&lt;/span&gt;&lt;/u&gt;여야 하기 때문에 인코더와 디코더의 개념이 필요하다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;(JAVA)&lt;/span&gt; 내가 보낼 데이터 -&amp;gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;(인코딩)&lt;/span&gt; -&amp;gt; &lt;span style=&quot;color: #006dd7;&quot;&gt;(Byte)&lt;/span&gt; 데이터 전송 완료&lt;/b&gt;&lt;b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;인코더&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;/b&gt;아웃바운드&amp;nbsp;메시지는&amp;nbsp;현재&amp;nbsp;포맷에서&amp;nbsp;바이트로&amp;nbsp;인코딩하는&amp;nbsp;과정을&amp;nbsp;거치는데,&amp;nbsp;이&amp;nbsp;과정을&amp;nbsp;인코더가&amp;nbsp;수행 &lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;(Byte)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;내가 받을 데이터 -&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;(디코딩)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;-&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;(JAVA)&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;데이터 수신 완료&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;디코더&lt;/span&gt;&amp;nbsp;:&amp;nbsp;&lt;/span&gt;&lt;/b&gt;인바운드&amp;nbsp;메시지의&amp;nbsp;경우&amp;nbsp;바이트에서&amp;nbsp;다른&amp;nbsp;포맷(보통&amp;nbsp;자바&amp;nbsp;객체)로&amp;nbsp;변환하는&amp;nbsp;디코딩&amp;nbsp;과정을&amp;nbsp;거치는데,&amp;nbsp;이&amp;nbsp;과정을&amp;nbsp;디코더가&amp;nbsp;수행 &lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;부트스트랩 &lt;br /&gt;서버&amp;nbsp;vs&amp;nbsp;클라이언트&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;서버를 지정된 포트로 바인딩할 &lt;u&gt;&lt;b&gt;서버 부트스트랩&lt;/b&gt;&lt;/u&gt;과, &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;지정된 호스트의 지정된 포트에서 실행중인 호스트로 연결하는 &lt;u&gt;&lt;b&gt;클라이언트 부트스트랩&lt;/b&gt;&lt;/u&gt;이 있다는 정도만 알고 넘어가자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;출처 : 네티인 액션&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1608397240340&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;네티 인 액션&quot; data-og-description=&quot;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&quot; data-og-host=&quot;book.naver.com&quot; data-og-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-url=&quot;http://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bYUdgv/hyIC2TTFXd/6IwWiqFuDjkvKhkaiD1n10/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bYUdgv/hyIC2TTFXd/6IwWiqFuDjkvKhkaiD1n10/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;네티 인 액션&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;book.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>bootstrap</category>
      <category>netty</category>
      <category>Netty Channel</category>
      <category>Netty ChannelFuture</category>
      <category>Netty ChannelPipeline</category>
      <category>Netty EventHandler</category>
      <category>Netty EventLoop</category>
      <category>nio</category>
      <category>네티</category>
      <category>부트스트랩</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/145</guid>
      <comments>https://javacoding.tistory.com/145#entry145comment</comments>
      <pubDate>Thu, 10 Dec 2020 11:10:33 +0900</pubDate>
    </item>
    <item>
      <title>Java Netty 에코 서버-클라이언트 구현하기</title>
      <link>https://javacoding.tistory.com/144</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Echo 서버 만들기&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;모든 네티 서버에는 다음 항목이 필요하다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;하나 이상의 &lt;b&gt;ChannelHandler&lt;/b&gt; : 이 컴포넌트는 클라이언트로부터 받은 데이터를 서버측에서 처리하는 비즈니스 논리를 구현한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;부트스트랩&lt;/b&gt; : 서버를 구성하는 시동 코드를 의미한다. 최소한 서버가 연결 요청을 수신하는 포트 서버와 바인딩하는 코드가 있어야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;ChannelHandler와 비즈니스 논리&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;Echo 서버는 들어오는 메시지에 반응해야 하므로 인바운드 이벤트에 반응하는 메서드가 정의된 ChannelInboundHandler 인터페이스를 구현해야 한다.&lt;/p&gt;
&lt;p&gt;관심을 가질 메서드는 다음과 같다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;channelRead()&lt;/b&gt; : 메시지가 들어올 때마다 호출된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;channelReadComplete()&lt;/b&gt; : channelRead()의 마지막 호출에서 현재 일괄 처리의 마지막 메시지를 처리했음을 핸들러에 통보한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;exceptionCaught()&lt;/b&gt; : 읽기 작업 중 예외가 발생하면 호출된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EchoServerHandler&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1608220294992&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

@ChannelHandler.Sharable
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf in = (ByteBuf)msg;
        System.out.println(&quot;Server received : &quot; + in.toString(CharsetUtil.UTF_8));
        ctx.write(in); // 받은 메시지를 발신자에게로 Echo 시킨다.
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        System.out.println(&quot;Bye&quot;);
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER) // 대기중인 메시지를 플러시하고 채널을 닫음
                .addListener(ChannelFutureListener.CLOSE);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();	// 채널 닫기
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;ServerHandler 코드를 작성하면서 기억해둘 점은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ChannelHandler는 네 가지 이벤트 유형에 의해 호출된다.&lt;/li&gt;
&lt;li&gt;애플리케이션은 ChannelHandler를 구현하거나 확장해 이벤트 수명주기를 후크하고 커스텀 애플리케이션 논리를 제공한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&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;지금까지 EchoServerHandler가 구현하는 핵심 비즈니스 논리를 살펴봤다. 이제 다음 과정을 포함하는 서버의 부트스트랩을 진행해야 한다.&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;EchoServerHandler 인스턴스에 인바운드 메시지에 대해 알리도록 Channel을 구성한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;EchoServer 클래스&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1608221141153&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.net.InetSocketAddress;

public class EchoServer {
    private final int port;

    public EchoServer() {
        this.port = 8888;
    }

    public static void main(String[] args) throws Exception {
        new EchoServer().start();   // 서버의 start() 메소드 호출
    }

    private void start() throws Exception {
        final EchoServerHandler serverHandler = new EchoServerHandler();
        EventLoopGroup group = new NioEventLoopGroup(); // EventLoopGroup 생성
        try {
            ServerBootstrap b = new ServerBootstrap();  // ServerBootstrap 생성
            b.group(group)
                    .channel(NioServerSocketChannel.class)  // NIO 전송채널을 이용하도록 지정
                    .localAddress(new InetSocketAddress(port))  // 지정된 포트로 소켓 주소 설정
                    .childHandler(new ChannelInitializer&amp;lt;SocketChannel&amp;gt;() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception { // EchoServerHandler 하나를 채널의 Channel Pipeline 으로 추가
                            ch.pipeline().addLast(serverHandler);
                        }
                    });
            ChannelFuture f = b.bind().sync();  // 서버를 비동기식으로 바인딩
            f.channel().closeFuture().sync();   // 채널의 CloseFuture를 얻고 완료될 때까지 현재 스레드를 블로킹
        } finally {
            group.shutdownGracefully().sync();  // EventLoopGroup을 종료하고 모든 리소스 해제
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;지금 완성한 서버 구현에서 중요한 단계를 검토해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;EchoServerHandler&lt;/b&gt;는 비즈니스 논리를 구현한다.&lt;/li&gt;
&lt;li&gt;main() 메서드는 서버를 부트스트랩한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;부트스트랩&lt;/b&gt;에는 다음 단계가 필요하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버를 부트스트랩하고 바인딩하는 데 이용할 &lt;u&gt;ServerBootstrap 인스턴스를 생성&lt;/u&gt;한다.&lt;/li&gt;
&lt;li&gt;새로운 연결 수락 및 데이터 읽기/쓰기와 같은 이벤트 처리를 수행할 &lt;u&gt;NioEventLoopGroup 인스턴스를 생성하고 할당&lt;/u&gt;한다.&lt;/li&gt;
&lt;li&gt;서버가 바인딩하는 &lt;u&gt;로컬 InetSocketAddress를 지정&lt;/u&gt;한다.&lt;/li&gt;
&lt;li&gt;EchoServerHandler 인스턴스를 이용해 새로운 각 &lt;u&gt;Channel을 초기화&lt;/u&gt;한다.&lt;/li&gt;
&lt;li&gt;&lt;u&gt;ServerBootstrap.bind()&lt;/u&gt;를 호출해 서버를 바인딩한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Echo 클라이언트 만들기&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;Echo 클라이언트는 다음과 같은 일을 한다.&lt;/p&gt;
&lt;ol&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;/ol&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;ChannelHandler를 이용한 클라이언트 논리 구현&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;channelActive()&lt;/b&gt; : 서버에 대한 연결이 만들어지면 호출된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;chanelRead0()&lt;/b&gt; : 서버로부터 메시지를 수신하면 호출된다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;exceptionCaught()&lt;/b&gt; : 처리 중에 예외가 발생하면 호출된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이제 클라이언트의 ChannelHandler를 만들어 보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;EchoClientHandler&lt;/h3&gt;
&lt;pre id=&quot;code_1608222268033&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;

@ChannelHandler.Sharable
public class EchoClientHandler extends SimpleChannelInboundHandler&amp;lt;ByteBuf&amp;gt; {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(Unpooled.copiedBuffer(&quot;Netty Connect()&quot;, CharsetUtil.UTF_8)); // 채널 활성화 시 메시지 전송
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
        System.out.println(&quot;Client receive : &quot; + msg.toString(CharsetUtil.UTF_8));  // 수신한 메시지 로깅
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();    // 예외 시 오류를 로깅하고 채널 닫기
        ctx.close();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;우선 연결이 만들어지면 호출되는 ChannelActive()를 재정의했다.&lt;/p&gt;
&lt;p&gt;이&amp;nbsp; 예제에서는 &quot;Netty Connet()&quot;라는 문자열을 인코딩한 바이트 버퍼를 전송한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그런 다음, 데이터를 수신할 때 호출되는 channelRead0() 메서드를 재정의했다.&lt;/p&gt;
&lt;p&gt;주의할 점은 서버가 전송한 메시지가 여러 청크로 수신될 수 있다는 점이다. 즉, 서버가 5바이트를 전송할 때 5바이트가 모두 한 번에 수신된다는 보장이 없다. 다만 TCP는 스트림 기반 프로토콜이므로 서버가 보낸 순서대로 바이트를 수신할 수 있게 보장한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;EchoClient&lt;/h3&gt;
&lt;pre id=&quot;code_1608223553699&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.net.InetSocketAddress;

public class EchoClient {
    public EchoClient(){
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();  // bootstrap 생성
            b.group(group)  // 클라이언트 이벤트 처리할 EventLoopGroup을 지정.
                    .channel(NioSocketChannel.class)    // 채널 유형 NIO 지정
                    .remoteAddress(new InetSocketAddress(8888)) // 서버의 InetSocketAddress를 설정
                    .handler(new ChannelInitializer&amp;lt;SocketChannel&amp;gt;() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {    // 채널이 생성될 때 파이프라인에 EchoClientHandler 하나를 추가
                            ch.pipeline().addLast(new EchoClientHandler());
                        }
                    });
            ChannelFuture f = b.connect().sync();   // 원격 피어로 연결하고 연결이 완료되기를 기다림
            f.channel().closeFuture().sync();   // 채널이 닫힐 때까지 블로킹함.
        } finally {
            group.shutdownGracefully().sync();  // 스레드 풀을 종료하고 모든 리소스를 해제함
        }
    }

    public static void main(String[] args) throws Exception {
        new EchoClient().start();
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Client 과정 정리&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;클라이언트를 초기화하기 위한 &lt;b&gt;Bootstrap 인스턴스를 생성&lt;/b&gt;한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;새로운 연결을 생성하고 인바운드와 아웃바운드 데이터를 처리하는 것을 포함하는 이벤트 처리를 제어할 &lt;b&gt;NioEventLoopGroup 인스턴스를 만들고 할당&lt;/b&gt;한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;서버로 연결하기 위한 &lt;b&gt;InetSocketAddress를 생성&lt;/b&gt;한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;연결이 만들어지면 &lt;b&gt;파이프라인에 EchoClientHandler 하나를 추가&lt;/b&gt;한다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;모든 준비가 완료되면 &lt;b&gt;Bootstrap.connect()&lt;/b&gt;를 호출해 원격 서버로 연결한다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;빌드 및 실행&lt;/h3&gt;
&lt;p&gt;빌드 및 실행을 위해서는 Netty를 먼저 다운받아야 한다. 다운 받은 뒤, 프로젝트에 외부 라이브러리에 Netty를 추가해주면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://netty.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;netty.io/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1608223645792&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Netty: Home&quot; data-og-description=&quot;Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers &amp;amp; clients. Netty is a NIO client server framework which enables quick and easy development of network applications s&quot; data-og-host=&quot;netty.io&quot; data-og-source-url=&quot;https://netty.io/&quot; data-og-url=&quot;https://netty.io/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://netty.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://netty.io/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;Netty: Home&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers &amp;amp; clients. Netty is a NIO client server framework which enables quick and easy development of network applications s&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;netty.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이후 소스를 작성하고 Server와 Client를 각각 실행시켜 보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;IntelliJ 환경에서 실행된 모습&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;EchoServer&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Server.PNG&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;379&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4l7xD/btqQE80D5jd/7CyK8LehD75MhCbkjyLF60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4l7xD/btqQE80D5jd/7CyK8LehD75MhCbkjyLF60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4l7xD/btqQE80D5jd/7CyK8LehD75MhCbkjyLF60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4l7xD%2FbtqQE80D5jd%2F7CyK8LehD75MhCbkjyLF60%2Fimg.png&quot; data-filename=&quot;Server.PNG&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;379&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;EchoClient&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Client.PNG&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;512&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WG70S/btqQzRFB1lG/IKB8wh7OVVEqZB8qnYjgG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WG70S/btqQzRFB1lG/IKB8wh7OVVEqZB8qnYjgG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WG70S/btqQzRFB1lG/IKB8wh7OVVEqZB8qnYjgG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWG70S%2FbtqQzRFB1lG%2FIKB8wh7OVVEqZB8qnYjgG1%2Fimg.png&quot; data-filename=&quot;Client.PNG&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;512&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이상으로 JAVA Netty 에코 서버-클라이언트 구현을 마치겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;u&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/u&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;@Sharable&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;: 이 어노테이션이 붙은 클래스의 인스턴스는 여러 Channel에서 공유할 수 있음을 나타낸다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SimpleChannelInboundHandler와 ChannelInboundHandler 비교&lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;Client에서는 SimpleChannelInboundHandler를 사용했다.&lt;/p&gt;
&lt;p&gt;클라이언트에서 channelRead0()이 완료된 시점에서 들어오는 메시지는 이미 확보된 상태이며 메서드가 반환될 때 ByteBuf에 대한 메모리 참조를 해제한다.&lt;/p&gt;
&lt;p&gt;반면 서버에서는 ChannelRead()가 반환될 때까지 비동기의 write() 작업이 완료되지 않았을 수 있다. 이 메시지는 channelReadComplete()에서 writeAndFlush()가 호출될 때 해제된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이처럼 서로 메모리 해제하는 구간이 다르고, 메서드의 약간의 차이가 있으므로&lt;/p&gt;
&lt;p&gt;Client에서는 SimpleChannelInboundHandler를, Server에서는 ChannelInboundHandler를 사용하는 것으로 기억해두고 넘어가자.&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참고 : &lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1607690363912&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;네티 인 액션&quot; data-og-description=&quot;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&quot; data-og-host=&quot;book.naver.com&quot; data-og-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-url=&quot;http://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bZD8VK/hyIxtKQh8z/ICostZaqFNIsedLjccmgH0/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bZD8VK/hyIxtKQh8z/ICostZaqFNIsedLjccmgH0/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;네티 인 액션&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;book.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>Java TCP</category>
      <category>JAVA 소켓</category>
      <category>netty</category>
      <category>Netty Handler</category>
      <category>Netty 기초</category>
      <category>TCP</category>
      <category>네티인액션</category>
      <category>에코 클라이언트</category>
      <category>자바 Netty</category>
      <category>자바 네티</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/144</guid>
      <comments>https://javacoding.tistory.com/144#entry144comment</comments>
      <pubDate>Wed, 9 Dec 2020 18:39:42 +0900</pubDate>
    </item>
    <item>
      <title>Netty의 개념과 아키텍처</title>
      <link>https://javacoding.tistory.com/143</link>
      <description>&lt;h2&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Netty&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;h5&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;: 비동기식 이벤트 기반 네트워킹 프레임워크&lt;/span&gt;&lt;/h5&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;일반적인 JAVA 블로킹 입출력 예제&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1608975140413&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ServerSocket serverSocket = new ServerSocket(portNumber);
Socket clientSocket = serverSocket.accept();

BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);

String request, response;

while((request = in.readLine)) != null) {
	if (&quot;Done&quot;.equals(request))
    	break;
	response = processRequest(request);
    out.println(response);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;간단한 예제를 하나 살펴보자. 이 예제에서 accept()는 ServerSocket에서 연결될 때까지 진행을 &lt;b&gt;&lt;u&gt;블로킹&lt;/u&gt;&lt;/b&gt;하며 연결되면 클라이언트와 서버간 통신을 위한 새로운 Socket을 하나 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;또한 이 코드는 &lt;b&gt;&lt;u&gt;한 번에 한 연결만 처리&lt;/u&gt;&lt;/b&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;기본적인 Socket API의 문제점&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 방식을 살펴보면, 여러 스레드가 입력이나 출력 데이터가 들어오기를 기다리며 무한정 대기 상태에 빠질 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 무한 대기(좀비), 리소스 낭비, 오버헤드 등등..&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;자바 NIO&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위와 같은 문제를 갖는 블로킹 시스템 호출 방식 외에도 네이티브 소켓 라이브러리에는 오래전부터 네트워크 리소스 사용률을 세부적으로 제어할 수 있는 논블로킹 호출이 포함돼 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;* setsockopt()를 이용하면 데이터가 없을 때, 즉 블로킹 호출이라면 진행을 블로킹할 상황에서 읽기/쓰기 호출이 즉시 반환하도록 소켓을 구성할 수 있다.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;논블로킹 입출력을 위한 자바 지원 기능은 2002년 JDK 1.4 패키지인 java.nio와 함께 도입됐다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333; letter-spacing: 0px; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;NIO는 원래 NEW input/output의 약자였지만, 대부분의 사용자는 NIO가 논블로킹 입출력을 나타내며, 블로킹 입출력은 OIO라고 생각한다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Selector&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 아래 그림의 논블로킹 설계를 보면 이전에 설명한&lt;b&gt; 블로킹 방식의 단점이 사실상 완전히 해결&lt;/b&gt;된 것을 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 자바의 논블로킹 입출력 구현의 핵심으로서, &lt;b&gt;논블로킹&lt;/b&gt; Socket의 집합에서 입출력이 가능한 항목을 지정하기 위해 &lt;b&gt;이벤트 통지 API&lt;/b&gt;를 이용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;selector.png&quot; data-origin-width=&quot;701&quot; data-origin-height=&quot;499&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zFQi5/btqQu3GsnxJ/KZ1PFeZYSHKQyxaWo1SgH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zFQi5/btqQu3GsnxJ/KZ1PFeZYSHKQyxaWo1SgH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zFQi5/btqQu3GsnxJ/KZ1PFeZYSHKQyxaWo1SgH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzFQi5%2FbtqQu3GsnxJ%2FKZ1PFeZYSHKQyxaWo1SgH1%2Fimg.png&quot; data-filename=&quot;selector.png&quot; data-origin-width=&quot;701&quot; data-origin-height=&quot;499&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;언제든지 읽기나 쓰기 작업의 완료 상태를 확인할 수 있으므로 &lt;u&gt;한 스레드로 여러 동시 연결을 처리&lt;/u&gt;할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;적은 수의 스레드&lt;/b&gt;로 더 많은 연결을 처리할 수 있으므로 메모리 관리와 컨텍스트 전환에 따르는 &lt;b&gt;오버헤드가 감소&lt;/b&gt;한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;입출력을 처리하지 않을 때는 &lt;b&gt;스레드&lt;/b&gt;를 다른 작업에 활용할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;비동기성과 확장성은 어떻게 연결돼 있을까?&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;먼저 비동기의 개념에 대해 생각해보면 좋을 것 같다. 비동기의 좋은 예시로 이메일이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;보낸 메시지의 답장이 올 수도 있고 답장이 없을 수도 있다. 메시지를 보내는 동안 예기치 않는 메시지를 받을 수도 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;또한 비동기 이벤트는 정돈된 관계를 가질 수 있다는 것을 알아두자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;일반적으로 답변은 질문한 사항에 대해서만 받을 수 있고, 답변을 기다리는 동안 다른 일을 할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;비동기성과 확장성은 어떻게 연결돼 있을까?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;논블로킹&lt;/b&gt; 네트워크 연결은 작업 완료를 기다릴 필요가 없게 해준다. 완전 비동기 입출력은 이 특징을 바탕으로 한 단계 더 나아간다. &lt;u&gt;비동기 메서드는 즉시 반환하며 작업이 완료되면 직접 또는 나중에 이를 통지한다&lt;/u&gt;.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;셀렉터&lt;/b&gt;는 적은 수의 스레드로 여러 연결에서 이벤트를 모니터링할 수 있게 해준다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;u&gt;논블로킹 입출력을 이용하면 블로킹 입출력 방식을 이용할 때보다 더 많은 이벤트를 훨씬 빠르고 경제적으로 처리할 수 있다.&lt;/u&gt;&lt;/b&gt; 이것은 네트워킹 관점에서 우리가 구축하려는 시스템의 핵심이며, 앞으로 알아보겠지만 &lt;u&gt;&lt;b&gt;네티 설계의 핵심&lt;/b&gt;&lt;/u&gt;이기도 하다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;네티의 핵심 컴포넌트&lt;/span&gt;&lt;/h3&gt;
&lt;h4&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Channel&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;하나 이상의 입출력 작업(읽기 또는 쓰기)을 수행할 수 있는 하드웨어 장치, 파일, 네트워크 소켓, 프로그램 컴포넌트와 같은 엔티티에 대한 열린 연결&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;일단 &lt;b&gt;Channel&lt;/b&gt;을 들어오는 데이터와 나가는 데이터를 위한 운송수단이라고 생각하자. &lt;b&gt;Channel&lt;/b&gt;은 열거나 닫고, 연결하거나 연결을 끊을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;콜백&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;콜백은 간단히 말해 다른 메서드로 자신에 대한 참조를 제공할 수 있는 메서드다. &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;콜백은 관심 대상에게 작업 완료를 알리는 가장 일반적인 방법 중 하나다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;네티는 이벤트를 처리할 때 내부적으로 콜백을 이용한다. 콜백이 트리거되면 ChannelHandler 인터페이스의 구현을 통해 이벤트를 처리할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Future&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;Future는 작업이 완료되면 이를 애플리케이션에 알리는 한 방법이다. 이 객체는 비동기 작업의 결과를 담는 자리표시자 역할을 하며, 미래의 어떤 시점에 작업이 완료되면 그 결과에 접근할 수 있게 해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;JDK는 Future를 제공하지만, 수동으로 작업완료 여부를 확인하거나 완료되기 전까지 블로킹하는 기능만 있다. 따라서 네티는 &lt;b&gt;비동기 작업&lt;/b&gt;이 실행됐을 때 이용할 수 있는 자체 구현 &lt;b&gt;ChannelFuture&lt;/b&gt;를 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;네티의 모든&lt;u&gt; 아웃바운드 입출력 작업&lt;/u&gt;은 &lt;code&gt;ChannelFuture&lt;/code&gt;를 반환하며 진행을 블로킹하는 작업은 없다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;앞서 언급한 대로 &lt;b&gt;네티는 기본적으로 비동기식이며 이벤트 기반&lt;/b&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;ChannelFutureListener&lt;/b&gt;를 활용하는 방법을 살펴보자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;먼저 원격 피어로 연결한 다음, connect() 호출로 반환된 ChannelFuture를 이용해 새로운 ChannelFutureListener를 등록한다. 리스너가 연결이 만들어졌다는 알림을 받으면 상태를 확인한다. 작업이 정상적이면 데이터를 Chanel로 기록하며, 그렇지 않으면 ChannelFuture에서 Throwable을 가져온다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1608976821941&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Channel channel = ...;
// 블로킹하지 않음
ChannelFuture future = channel.connect(new InetSocketAddress(&quot;192.168.0.1&quot;, 25));

future.addListener(new ChannelFutureListener() {
	@Override
    public void operationComplete(ChannelFuture future){
    	if(future.isSuccess()){
        	ByteBuf buffer = Unpooled.copiedBuffer(&quot;Hello&quot;, Charset.defaultCharset());
            ChannelFuture wf = future.channel().writeAndFlush(buffer);
            ...
        } else {
        	Throwable cause = future.cause();
            cause.printStackTrace();
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;이벤트와 핸들러&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;네티는 &lt;b&gt;작업의 상태 변화&lt;/b&gt;를 알리기 위해 고유한 &lt;b&gt;이벤트를 이용&lt;/b&gt;하며, 발생한 이벤트를 기준으로 적절한 동작을 트리거할 수 있다. 다음과 같은 동작이 포함된다.&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;로깅&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;데이터 변환&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;흐름 제어&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;애플리케이션 논리&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;네티는 네트워크 프레임워크이므로 이벤트 역시 &lt;b&gt;인바운드 또는 아웃바운드 데이터 흐름&lt;/b&gt;에 대한 연관성을 기준으로 분류된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;인바운드&lt;/b&gt; 데이터나 연관된 상태 변화로 트리거되는 이벤트는 다음을 포함한다.&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;연결 활성화 또는 비활성화&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;데이터 읽기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;사용자 이벤트&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;오류 이벤트&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;아웃바운드 이벤트&lt;/b&gt;는 다음과 같이 미래에 한 동작을 트리거하는 작업의 결과들이다.&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;원격 피어로 연결 열기 또는 닫기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;소켓으로 데이터 쓰기 또는 플러시&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;01fig03_alt.jpg&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;144&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/WFLOW/btqQt6i4Tzp/tvrWVgBuTfKkZrb5F7CXl1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/WFLOW/btqQt6i4Tzp/tvrWVgBuTfKkZrb5F7CXl1/img.jpg&quot; data-alt=&quot;ChannelHandler의 체인을 통한 인바운드와 아웃바운드 이벤트의 흐름&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/WFLOW/btqQt6i4Tzp/tvrWVgBuTfKkZrb5F7CXl1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FWFLOW%2FbtqQt6i4Tzp%2FtvrWVgBuTfKkZrb5F7CXl1%2Fimg.jpg&quot; data-filename=&quot;01fig03_alt.jpg&quot; data-origin-width=&quot;590&quot; data-origin-height=&quot;144&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ChannelHandler의 체인을 통한 인바운드와 아웃바운드 이벤트의 흐름&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;u&gt;&lt;b&gt;정리&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;네티의 비동기 프로그래밍 모델은 &lt;b&gt;Future&lt;/b&gt;, &lt;b&gt;콜백&lt;/b&gt;의 개념, 그리고 더 깊은 단계에서 이벤트를 &lt;b&gt;핸들러 메서드&lt;/b&gt;로 발송하는 작업을 기반으로 작동한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;작업을 가로채고 인바운드나 아웃바운드 데이터를 즉시 변환하려면 콜백을 제공하거나 작업이 반환하는 &lt;b&gt;Future&lt;/b&gt;를 활용하면 간단하다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;또한 셀렉터, 이벤트, 이벤트 루프에 대해 알아두자.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;네티는 이벤트를 발생시켜 Selector를 애플리케이션 밖으로 추상화하므로 개발자가 발송 코드를 직접 작성할 필요가 없다. 각 Channel에 해당하는 EventLoop는 내부적으로 모든 이벤트를 처리한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 관심 이벤트 등록&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 이벤트를 ChannelHandler로 발송&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 추가 동작 스케쥴링&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;EventLoop 자체는 하나의 Channel의 모든 입출력 이벤트를 처리하는 스레드에 의해 제어되며, EventLoop의 수명 기간 동안 달라지지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;Chap1.PNG&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;392&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Zjme0/btqRqRelR4G/MvIpdKHKwXQKsNiKikWASK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Zjme0/btqRqRelR4G/MvIpdKHKwXQKsNiKikWASK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Zjme0/btqRqRelR4G/MvIpdKHKwXQKsNiKikWASK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZjme0%2FbtqRqRelR4G%2FMvIpdKHKwXQKsNiKikWASK%2Fimg.png&quot; data-filename=&quot;Chap1.PNG&quot; data-origin-width=&quot;841&quot; data-origin-height=&quot;392&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;두 유저가 전화를 한다고 가정했을 때, 두 사람 사이에 생긴 전화선을 &lt;b&gt;Channel(채널)&lt;/b&gt;로 본다면&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;왼쪽 유저의 입장에서 오른쪽으로 나가는 이벤트를 &lt;b&gt;아웃바운드 이벤트&lt;/b&gt;,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;반대로 상대로부터 들어오는 이벤트를 &lt;b&gt;인바운드 이벤트&lt;/b&gt;로 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;또 전화 연결, 전화 끊어짐, 통화중 등 미래에 발생할 수 있는 시점들이며 이를 &lt;b&gt;Future&lt;/b&gt;로 볼 수 있고&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이러한 이벤트를 알리는 것은 &lt;b&gt;Callback&lt;/b&gt;을 통해 이루어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;참고 &lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1608203767470&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;article&quot; data-og-title=&quot;네티 인 액션&quot; data-og-description=&quot;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&quot; data-og-host=&quot;book.naver.com&quot; data-og-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-url=&quot;http://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/pjFfP/hyIBZ3Vyua/hzhkFWwhjadBAdtMKJgxLk/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178&quot;&gt;&lt;a href=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://book.naver.com/bookdb/book_detail.nhn?bid=10462610&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/pjFfP/hyIBZ3Vyua/hzhkFWwhjadBAdtMKJgxLk/img.jpg?width=140&amp;amp;height=178&amp;amp;face=0_0_140_178');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;네티 인 액션&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;네티는 복잡한 네트워킹, 멀티스레드, 동시성을 관리하는 자바 기반 네트워킹 프레임워크로서, 반복적인 저수준 코드를 내부로 감춤으로써 비즈니스 논리를 분리하고 쉽게 재사용할 수 있게 해&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;book.naver.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>callback</category>
      <category>channel</category>
      <category>Future</category>
      <category>JAVA Netty</category>
      <category>netty</category>
      <category>Socket API</category>
      <category>네티</category>
      <category>네티 기본개념</category>
      <category>비동기</category>
      <category>자바 네티</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/143</guid>
      <comments>https://javacoding.tistory.com/143#entry143comment</comments>
      <pubDate>Wed, 9 Dec 2020 10:18:38 +0900</pubDate>
    </item>
    <item>
      <title>@PostMapping과 @PutMapping의 차이</title>
      <link>https://javacoding.tistory.com/142</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uBuqf/btqKSgZEDfZ/IRn49EMEGDGub5Ck0VZnkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uBuqf/btqKSgZEDfZ/IRn49EMEGDGub5Ck0VZnkk/img.png&quot; data-alt=&quot;일반적인 형태의 CRUD&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uBuqf/btqKSgZEDfZ/IRn49EMEGDGub5Ck0VZnkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuBuqf%2FbtqKSgZEDfZ%2FIRn49EMEGDGub5Ck0VZnkk%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;일반적인 형태의 CRUD&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;개발을 하면서 여느 때처럼 CRUD 코드를 만들고 있었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;@PostMapping&lt;/b&gt;과 &lt;b&gt;@PutMapping&lt;/b&gt;의 기능이 비슷한데 왜 따로 명시하는지 알고 있나?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;질문에 말문이 막혔습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;공식처럼 추가/등록은 @PostMapping을 사용하고 수정할 때에는 @PutMapping을 사용했기 때문에 인수인계 혹은 코드 리뷰에 코드를 읽는 사람을 위해 구분지어놓는 줄만 알았습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;관련 자료를 찾아보다가 mozilla 사이트의 글을 보고 차이를 조금 이해하게 되었습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/PUT&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;developer.mozilla.org/ko/docs/Web/HTTP/Methods/PUT&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1602721609022&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;PUT&quot; data-og-description=&quot;HTTP PUT 메서드는 요청 페이로드를 사용해 새로운 리소스를 생성하거나, 대상 리소스를 나타내는 데이터를 대체합니다.&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/PUT&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/PUT&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dmFte0/hyHRTkw6qY/phS3kzGrLYtEshkWqYCvPk/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/HMxzP/hyHRJWt3mD/eWQEfILQpL0AgNdQPsDi2K/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/PUT&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Web/HTTP/Methods/PUT&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dmFte0/hyHRTkw6qY/phS3kzGrLYtEshkWqYCvPk/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/HMxzP/hyHRJWt3mD/eWQEfILQpL0AgNdQPsDi2K/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;PUT&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;HTTP PUT 메서드는 요청 페이로드를 사용해 새로운 리소스를 생성하거나, 대상 리소스를 나타내는 데이터를 대체합니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;PUT&lt;span style=&quot;color: #333333;&quot;&gt;과&lt;span&gt; POST&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;의 차이는&lt;span&gt;&amp;nbsp;&lt;b&gt;멱등성&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #333333;&quot;&gt;으로 설명되어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;HTTP 요청에서 멱등성이란 &lt;span style=&quot;color: #333333;&quot;&gt;&lt;b&gt;&lt;u&gt;여러 번 연속해서 호출해도 클라이언트가 받는 응답은 동일&lt;/u&gt;&lt;/b&gt;하다는 것인데 멱등성에 대해 설명된 글을 읽고 차이점을 어느정도 이해하게 된 것 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Glossary/Idempotent&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;developer.mozilla.org/ko/docs/Glossary/Idempotent&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1602721858048&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;멱등성&quot; data-og-description=&quot;동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말합니다. 다른 말로는, 멱등성 메�&quot; data-og-host=&quot;developer.mozilla.org&quot; data-og-source-url=&quot;https://developer.mozilla.org/ko/docs/Glossary/Idempotent&quot; data-og-url=&quot;https://developer.mozilla.org/ko/docs/Glossary/Idempotent&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cE2UFq/hyHSNiFrqf/w04pGzUkogjCROX9jhnWZK/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/b7khAz/hyHSRk4bzz/GXiwOolPYzpJUQInPXhizk/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Glossary/Idempotent&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer.mozilla.org/ko/docs/Glossary/Idempotent&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cE2UFq/hyHSNiFrqf/w04pGzUkogjCROX9jhnWZK/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600,https://scrap.kakaocdn.net/dn/b7khAz/hyHSRk4bzz/GXiwOolPYzpJUQInPXhizk/img.png?width=600&amp;amp;height=600&amp;amp;face=0_0_600_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;멱등성&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;동일한 요청을 한 번 보내는 것과 여러 번 연속으로 보내는 것이 같은 효과를 지니고, 서버의 상태도 동일하게 남을 때, 해당 HTTP 메서드가 멱등성을 가졌다고 말합니다. 다른 말로는, 멱등성 메�&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;developer.mozilla.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;처음 관련 정보를 찾기 위해 구글링했을 때, 설명되어 있는 글이 부족하여 포스팅하게 되었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT/Web</category>
      <category>@Mapping</category>
      <category>HTTP POST</category>
      <category>HTTP PUT</category>
      <category>httprequest</category>
      <category>HTTP메소드</category>
      <category>PostMapping</category>
      <category>PutMapping</category>
      <category>REST API</category>
      <category>restful</category>
      <category>멱등성</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/142</guid>
      <comments>https://javacoding.tistory.com/142#entry142comment</comments>
      <pubDate>Thu, 15 Oct 2020 09:31:12 +0900</pubDate>
    </item>
    <item>
      <title>[ERROR] JSON 순환 참조 문제 해결하기</title>
      <link>https://javacoding.tistory.com/141</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;프로젝트를 진행하다가 순환참조 문제가 발생하였다.&lt;/p&gt;
&lt;p&gt;에러 메시지는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1600464177407&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt; Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;]-&amp;gt;org.hibernate.collection.internal.PersistentBag[0]-&amp;gt;com.mango.harugomin.domain.entity.UserHashtag[&quot;user&quot;]-&amp;gt;com.mango.harugomin.domain.entity.User[&quot;userHashtags&quot;])] with root cause
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;에러 메시지의 길이가 긴 이유는 &lt;b&gt;순환참조&lt;/b&gt;가 발생하였기 때문이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Hashtag 기능을 구현하려고 User와 HashTag 테이블이 있고, 양방향 매핑을 풀어주기 위해&lt;/p&gt;
&lt;p&gt;User, UserHashtag, HashTag 세 테이블을 이용하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5JeJe/btqI2ko86WY/3CTKnOfEZDQ0gnGbQyjLc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5JeJe/btqI2ko86WY/3CTKnOfEZDQ0gnGbQyjLc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5JeJe/btqI2ko86WY/3CTKnOfEZDQ0gnGbQyjLc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5JeJe%2FbtqI2ko86WY%2F3CTKnOfEZDQ0gnGbQyjLc1%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 상황에서 가운데에 위치한&amp;nbsp;&lt;b&gt;User_Tag&lt;/b&gt; 테이블을 관찰해보자.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;User에는 user_hashtag 이름으로 User_Tag 테이블을 담고 있고,&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;반대로 User_Tag 테이블에서는 user_id로 User를 담고 있었다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Cycle과 같이 서로를 계속 참조해서 발생하는 &lt;b&gt;순환참조 문제&lt;/b&gt;가 발생한 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;해결방법&lt;/h3&gt;
&lt;p&gt;&amp;nbsp;이러한 문제를 해결하는 방법으로 &lt;b&gt;@JsonIgnore&lt;/b&gt;를 사용하는 방법이 있고 &lt;b&gt;@JsonManagedReference&lt;/b&gt;와 &lt;b&gt;@JsonBackReference&lt;/b&gt;를 사용하는 방법이 있다. 표면적으로 두 방법 모두 순환참조를 방어하는 형태이지만 본질적으로 약간의 차이가 있다. &lt;b&gt;@JsonIgnore&lt;/b&gt;의 경우는 실제로 property에 null을 할당하는 방식이고 &lt;b&gt;@JsonManagedReference&lt;/b&gt;와 &lt;b&gt;@JsonBackReference&lt;/b&gt;는 본질적으로 순환참조를 방어하기 위한 Annotation이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;정리를 하자면 json serialize 과정에서 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;null&lt;/b&gt;&lt;/span&gt;로 세팅하고자 하면 &lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;b&gt;@JsonIgnore&lt;/b&gt;&lt;/span&gt; 사용하면 되고, 순환참조에 대한 문제를 해결하고자 한다면 &lt;span style=&quot;color: #f89009;&quot;&gt;부모 클래스측&lt;/span&gt;에 &lt;span style=&quot;color: #f89009;&quot;&gt;@JsonManagedReference&lt;/span&gt;를, &lt;span style=&quot;color: #009a87;&quot;&gt;자식측&lt;/span&gt;에 &lt;span style=&quot;color: #009a87;&quot;&gt;@JsonBackReference&lt;/span&gt;를 Annotation에 추가해주면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;기본적으로 DTO와 같이 별도의 전달 객체를 활용하여 Mapper를 이용한다면 위와 같은 문제가 없겠지만 경우에 따라 필요한 옵션이 있을 수 있어 찾아보았다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참조 : &lt;a href=&quot;https://binarycube.tistory.com/1&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;binarycube.tistory.com/1&lt;/a&gt;&lt;/p&gt;</description>
      <category>IT</category>
      <category>HttpMessageNotWritableException</category>
      <category>Infinite recursion</category>
      <category>JPA Cycle</category>
      <category>jpa 기초</category>
      <category>JPA 무한루프</category>
      <category>JPA 순환참조</category>
      <category>JsonBackReference</category>
      <category>JsonIgnore</category>
      <category>JsonManagedReference</category>
      <category>순환참조</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/141</guid>
      <comments>https://javacoding.tistory.com/141#entry141comment</comments>
      <pubDate>Sat, 19 Sep 2020 06:49:52 +0900</pubDate>
    </item>
    <item>
      <title>[ERROR] Error running '{ClassName}': Command line is too long. Shorten command line for {ClassName} IntelliJ 실행 에러</title>
      <link>https://javacoding.tistory.com/140</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;AWS S3 파일 업로드 작업을 진행하다가 IntelliJ에서 갑자기 오류 발생으로 프로젝트 실행이 되지 않았다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;관련 해결책을 찾다가 xml 수정도 해보았지만 해결되지 않았고, 제대로 된 해결책을 봐서 기록을 남긴다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;우선 에러가 발생하는 이유는&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;&quot; &lt;/span&gt;IntelliJ에서 바로 실행할 때에는 class path를 자동으로 잡게 하는데, 이 때문에 run command가 너무 길어져서 발생하는 문제이다. 정상적으로 실행되는 경우에도 알고 보면 아래처럼 어마 무시하게 run command가 길다.&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;run command 길이가 OS limit를 넘으면 실행할 수 없게 된다. 이를 해결하기 위해서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Run/Debug Configuration&lt;/b&gt;&lt;span&gt;에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Shorten command line&lt;/b&gt;&lt;span&gt;의 옵션을 수정해야 한다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sl9qi/btqIH46bVBw/slH6xdKYr9PrFQFtoIDYj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sl9qi/btqIH46bVBw/slH6xdKYr9PrFQFtoIDYj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sl9qi/btqIH46bVBw/slH6xdKYr9PrFQFtoIDYj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fsl9qi%2FbtqIH46bVBw%2FslH6xdKYr9PrFQFtoIDYj0%2Fimg.png&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span&gt;&lt;span&gt;4가지 옵션중 하나를 선택할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;None:&lt;/b&gt; 기본 옵션 값. IDE에서 긴 classpath를 줄여주지 않는다. command line이 OS limit를 초과하는 경우 IDEA는 애플리케이션을 실행할 수 없다. - 에러가 발생했다면 None으로 설정된 상태였을 것이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;JAR Manifest:&lt;/b&gt; IDE는 임시 claspath.jar를 사용해서 긴 classpath 사용을 회피한다. 실제 classpath는 classpath.jar의 MANIFEST.MF 안에 정의되어 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;classpath file:&lt;/b&gt; text 파일에 긴 classpath를 써둔다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;User-local default:&lt;/b&gt; Legacy property이다. IDE는 idea/workspace.xml 파일에서 지정된 옵션 값을 따른다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;쉽게 해결하기 위해서는 Shorten command line 옵션 값을 &lt;b&gt;JAR Manifest&lt;/b&gt;로 지정하여 해결하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참고 : deep-dive-dev.tistory.com/45&lt;/p&gt;</description>
      <category>IT</category>
      <category>AWS S3</category>
      <category>bug fix</category>
      <category>Command line is too long</category>
      <category>dev</category>
      <category>error fix</category>
      <category>Error running</category>
      <category>intellij</category>
      <category>JAR Manifest</category>
      <category>Shorten command line</category>
      <category>spring boot</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/140</guid>
      <comments>https://javacoding.tistory.com/140#entry140comment</comments>
      <pubDate>Sun, 13 Sep 2020 18:33:58 +0900</pubDate>
    </item>
    <item>
      <title>[ERROR] Can not issue data manipulation statements with executeQuery(). @Modifying 사용하기</title>
      <link>https://javacoding.tistory.com/139</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Can&amp;nbsp;not&amp;nbsp;issue&amp;nbsp;data&amp;nbsp;manipulation&amp;nbsp;statements&amp;nbsp;with&amp;nbsp;executeQuery().&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Servlet.service() for servlet [dispatcherServlet] in context with path threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: could&amp;nbsp;not&amp;nbsp;extract&amp;nbsp;ResultSet; nested&amp;nbsp;exception&amp;nbsp;is&amp;nbsp;org.hibernate.exception.GenericJDBCException:&amp;nbsp;could&amp;nbsp;not&amp;nbsp;extract&amp;nbsp;ResultSet]&amp;nbsp;with&amp;nbsp;root&amp;nbsp;cause&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1599548218662&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    @Query(value = &quot;update hashtag set posting_count = posting_count + 1, total_count = total_count + 1 where tag_id = ?1 &quot;, nativeQuery = true)
    void countUp(long userId);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;JPA를 이용하여 카운트, 또는 조회수를 카운트하다가 위와 같은 오류가 발생하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이 오류는 &lt;b&gt;UPDATE, INSERT, DELETE문을 사용할 때 executeUpdate()로 전송하지 않았을 경우에 발생&lt;/b&gt;한다고 한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;일반적으로 UPDATE, INSERT, DELETE문이 &lt;u&gt;&lt;b&gt;리턴값을 갖지 않기 때문에 발생하는 에러&lt;/b&gt;&lt;/u&gt;이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그래서 executeUpdate() 메서드의 리턴값은 쿼리를 전송해서 변화한 행의 갯수이다. 글 삭제나 변경같은 일반적인 경우에는 단 하나만 삭제되기 때문에 1이 반환될 것이고, 카테고리를 삭제한다면 가지고 있던 글들이 전부 삭제되어야 하기 때문에 리턴값이 조금 크게 나올 것이며, 의미없는 쿼리를 보낸다면 삭제할 일이 없을 것이기 때문에 0이 리턴될 것이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;원인을 읽어보면 의외로 해답은 간단하다. executeQuery() 대신 executeUpdate()로 쿼리를 전송하거나, executeUpdate() 대신 executeQuery()로 쿼리를 전송하면 된다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;@Modifying&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 어노테이션을 붙이지 않으면 &lt;/span&gt;결과값 응답을 기대하는&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;executeQuery() 함수를 사용하게 되는데 delete 쿼리 결과에는 결과값이 없으니 오류가 발생하는 것이다.&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;따라서 insert, update, delete 쿼리를 실행할 때는 executeUpdate() 함수를 사용하도록 @Modifying 어노테이션을 사용해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;또한 update 나 delete 쿼리 수행시 @Transactional 어노테이션을 함께 붙여줘야 javax.persistence.TransactionRequiredException 오류를 피할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1599548329403&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;    @Modifying(clearAutomatically = true)
    @Query(value = &quot;update hashtag set posting_count = posting_count + 1, total_count = total_count + 1 where tag_id = ?1 &quot;, nativeQuery = true)
    void countUp(long userId);&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;위와 같이 @Modifying 어노테이션을 이용하여 에러를 해결하였다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;추가적으로 clearAutomatically 옵션을 사용하였는데, 아래 설명을 보면 이해에 도움이 될 것 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;clearAutomatically&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 Attribute는 @Modifying 이 붙은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;해당 쿼리 메서드 실행 직 후, 역속성 컨텍스트를 clear&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;할 것인지를 지정하는 Attribute 입니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;default 값은 false&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;입니다. 하지만 default 값인 false를 그대로 사용할 경우, 영속성 컨텍스트의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;1차 캐시와 관련한&amp;nbsp;문제점&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&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;span style=&quot;color: #333333;&quot;&gt;참고:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://ammff.tistory.com/96&quot;&gt;https://ammff.tistory.com/96&lt;/a&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://m.blog.naver.com/PostView.nhn?blogId=kgj1&amp;amp;logNo=221115307403&amp;amp;proxyReferer=https:%2F%2Fwww.google.com%2F&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;m.blog.naver.com/PostView.nhn?blogId=kgj1&amp;amp;logNo=221115307403&amp;amp;proxyReferer=https:%2F%2Fwww.google.com%2F&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;a href=&quot;https://devhyogeon.tistory.com/4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;devhyogeon.tistory.com/4&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>IT</category>
      <category>@Modifying</category>
      <category>clearAutomatically</category>
      <category>error</category>
      <category>executeQuery</category>
      <category>jpa</category>
      <category>jpa 기초</category>
      <category>Modifying</category>
      <category>spring boot</category>
      <category>Spring Data JPA</category>
      <category>어노테이션</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/139</guid>
      <comments>https://javacoding.tistory.com/139#entry139comment</comments>
      <pubDate>Tue, 8 Sep 2020 16:03:49 +0900</pubDate>
    </item>
    <item>
      <title>[ 프로그래머스 ] 문자열 내 마음대로 정렬하기 JAVA</title>
      <link>https://javacoding.tistory.com/138</link>
      <description>&lt;h2&gt;&lt;span&gt;&lt;b&gt;문자열 내 마음대로 정렬하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 [sun, bed, car]이고 n이 1이면 각 단어의 인덱스 1의 문자 u, e, a로 strings를 정렬합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;제한 조건&lt;/span&gt;&lt;/p&gt;
&lt;ul data-mark=&quot;-&quot;&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;strings는 길이 1 이상, 50이하인 배열입니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;strings의 원소는 소문자 알파벳으로 이루어져 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;strings의 원소는 길이 1 이상, 100이하인 문자열입니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;모든 strings의 원소의 길이는 n보다 큽니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;인덱스 1의 문자가 같은 문자열이 여럿 일 경우, 사전순으로 앞선 문자열이 앞쪽에 위치합니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;[sun, bed, car]&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;[car, bed, sun]&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;[abce, abcd, cdx]&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;[abcd, abce, cdx]&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;입출력 예 설명&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;**&lt;/span&gt;&lt;b&gt;&lt;span&gt;입출력 예 1&lt;/span&gt;&lt;/b&gt;&lt;span&gt;**&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;sun, bed, car의 1번째 인덱스 값은 각각 u, e, a 입니다. 이를 기준으로 strings를 정렬하면 [car, bed, sun] 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;&lt;span&gt;**&lt;/span&gt;&lt;b&gt;&lt;span&gt;입출력 예 2&lt;/span&gt;&lt;/b&gt;&lt;span&gt;**&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;abce와 abcd, cdx의 2번째 인덱스 값은 c, c, x입니다. 따라서 정렬 후에는 cdx가 가장 뒤에 위치합니다. abce와 abcd는 사전순으로 정렬하면 abcd가 우선하므로, 답은 [abcd, abce, cdx] 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1598623243325&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.Arrays;
import java.util.Comparator;
class Solution {
  public String[] solution(String[] strings, int n) {
        Arrays.sort(strings, new Comparator&amp;lt;String&amp;gt;() {
			@Override
			public int compare(String o1, String o2) {
				if(o1.charAt(n) &amp;gt; o2.charAt(n))
					return 1;
				else if(o1.charAt(n) == o2.charAt(n))
					return o1.compareTo(o2);
				else
					return -1;
			}
		});
		return strings;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;입력으로 주어지는 문자열 strings배열을 바로 정렬하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문제 조건에 맞게 정렬하기 위해 Comparator를 사용하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;charAt() n번째의 문자로 정렬해주었으며,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;만약 n번째의 문자가 같을 경우에는 사전순으로 compareTo 함수를 이용하여 정렬해주었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;출처 :&lt;span&gt; &lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12915&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/12915&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1598623454973&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 문자열 내 마음대로 정렬하기&quot; data-og-description=&quot;문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 [sun, bed, car]이고 n이 1이면 각 단어의 인덱스 1�&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12915&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12915&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bxU7kW/hyHjRTLHm0/LVkfKJpkNYzCMQ16Qo3JZk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/Tc9Wg/hyHjLlITZk/ZKNgw2ghKZ3HBtNDaXKatK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12915&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12915&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bxU7kW/hyHjRTLHm0/LVkfKJpkNYzCMQ16Qo3JZk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/Tc9Wg/hyHjLlITZk/ZKNgw2ghKZ3HBtNDaXKatK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 문자열 내 마음대로 정렬하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;문자열로 구성된 리스트 strings와, 정수 n이 주어졌을 때, 각 문자열의 인덱스 n번째 글자를 기준으로 오름차순 정렬하려 합니다. 예를 들어 strings가 [sun, bed, car]이고 n이 1이면 각 단어의 인덱스 1�&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습</category>
      <category>Comparator</category>
      <category>CompareTo</category>
      <category>JAVA 문자열비교</category>
      <category>JAVA기초</category>
      <category>JAVA알고리즘</category>
      <category>JAVA코딩</category>
      <category>LV1문제풀이</category>
      <category>문자열비교</category>
      <category>알고리즘 기초</category>
      <category>프로그래머스</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/138</guid>
      <comments>https://javacoding.tistory.com/138#entry138comment</comments>
      <pubDate>Fri, 28 Aug 2020 23:04:51 +0900</pubDate>
    </item>
    <item>
      <title>[ 프로그래머스 ] 문자열 내 p와 y의 개수 JAVA</title>
      <link>https://javacoding.tistory.com/137</link>
      <description>&lt;h2&gt;&lt;span&gt;&lt;b&gt;문자열 내 p와 y의 개수&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 'p'의 개수와 'y'의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. 'p', 'y' 모두 하나도 없는 경우는 항상 True를 리턴합니다. 단, 개수를 비교할 때 대문자와 소문자는 구별하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;예를 들어 s가 pPoooyY면 true를 return하고 Pyy라면 false를 return합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;제한사항&lt;/span&gt;&lt;/p&gt;
&lt;ul data-mark=&quot;-&quot;&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;문자열 s의 길이 : 50 이하의 자연수&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;문자열 s는 알파벳으로만 이루어져 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;pPoooyY&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;Pyy&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;입출력 예 설명&lt;/span&gt;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;입출력 예 #1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;'p'의 개수 2개, 'y'의 개수 2개로 같으므로 true를 return 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;입출력 예 #2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;'p'의 개수 1개, 'y'의 개수 2개로 다르므로 false를 return 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1598622188123&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    boolean solution(String s) {
		boolean answer = true;
		int cnt = 0;
		char ch = ' ';
		
		for (int i = 0; i &amp;lt; s.length(); i++) {
			ch = s.charAt(i);
			if(ch == 'p' || ch== 'P')
				cnt++;
			else if (ch == 'y' || ch == 'Y')
				cnt--;
		}
		if(cnt != 0)
			return false;
		return true;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;입력으로 주어지는 문자열 s에 대하여&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;for문을 사용하여 p또는 P라면 cnt++,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;y또는 Y라면 cnt--연산을 수행하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;실행 결과가 0이 아닌 경우에 false를 리턴하고, 0이라면 true를 리턴해주었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;출처 :&lt;span&gt;&lt;span&gt; &lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12916&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/12916&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1598622297635&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 문자열 내 p와 y의 개수&quot; data-og-description=&quot;대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 'p'의 개수와 'y'의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. 'p', 'y' 모두 하나도 없는 경우는 항상 True를 &quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12916&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12916&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/G0aYX/hyHjVWaO87/X65m21NzaXz0wkKh3KgTmk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/qRR0j/hyHh2gvOmh/koaTrLj8iq6o11tNLrsatK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12916&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12916&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/G0aYX/hyHjVWaO87/X65m21NzaXz0wkKh3KgTmk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/qRR0j/hyHh2gvOmh/koaTrLj8iq6o11tNLrsatK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 문자열 내 p와 y의 개수&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;대문자와 소문자가 섞여있는 문자열 s가 주어집니다. s에 'p'의 개수와 'y'의 개수를 비교해 같으면 True, 다르면 False를 return 하는 solution를 완성하세요. 'p', 'y' 모두 하나도 없는 경우는 항상 True를&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습</category>
      <category>JAVA 기본</category>
      <category>Java 기초</category>
      <category>JAVA 문제풀이</category>
      <category>java 알고리즘</category>
      <category>java 코딩</category>
      <category>JAVA 코테</category>
      <category>알고리즘</category>
      <category>알고리즘 기초</category>
      <category>코딩테스트 준비</category>
      <category>프로그래머스</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/137</guid>
      <comments>https://javacoding.tistory.com/137#entry137comment</comments>
      <pubDate>Fri, 28 Aug 2020 22:45:23 +0900</pubDate>
    </item>
    <item>
      <title>[ 프로그래머스 ] 문자열 내림차순으로 배치하기 JAVA</title>
      <link>https://javacoding.tistory.com/136</link>
      <description>&lt;h2&gt;&lt;span&gt;&lt;b&gt;문자열 내림차순으로 배치하기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문자열 s에 나타나는 문자를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수, solution을 완성해주세요.&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;s는 영문 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로 간주합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;제한 사항&lt;/span&gt;&lt;/p&gt;
&lt;ul data-mark=&quot;-&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;span&gt;str은 길이 1 이상인 문자열입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;Zbcdefg&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;gfedcbZ&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1597930581524&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.ArrayList;
import java.util.Collections;

class Solution {
  public String solution(String s) {
		ArrayList&amp;lt;Character&amp;gt; list = new ArrayList&amp;lt;&amp;gt;();
      
		for (int i = 0; i &amp;lt; s.length(); i++) {
			list.add(s.charAt(i));
		}

		Collections.sort(list);
      
		StringBuilder sb = new StringBuilder();
      
		while (list.size() &amp;gt; 0) {
			sb.append(list.remove(list.size() - 1));
		}
      
        return sb.toString();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문자를 정렬한 뒤 출력해주는 문제입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;먼저, ArrayList를 활용하여 입력으로 주어진 s 문자열을 list에 담아주었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;이후 Collections의 sort 메소드를 사용하여 정렬해주었고&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;마지막으로 StringBuilder를 사용하여 정렬된 문자열을 출력해주었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;출처 :&lt;span&gt; &lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12917&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/12917&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1597930663559&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 문자열 내림차순으로 배치하기&quot; data-og-description=&quot;문자열 s에 나타나는 문자를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수, solution을 완성해주세요. s는 영문 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로 �&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12917&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12917&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ZQIF7/hyHdtzgox8/c1N532CTBH0Abcw0bTEt1K/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/ct4U3o/hyHdz7jnBi/r9mES8eKjtZiyR9lOA3S2K/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12917&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12917&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ZQIF7/hyHdtzgox8/c1N532CTBH0Abcw0bTEt1K/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/ct4U3o/hyHdz7jnBi/r9mES8eKjtZiyR9lOA3S2K/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 문자열 내림차순으로 배치하기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;문자열 s에 나타나는 문자를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수, solution을 완성해주세요. s는 영문 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로 �&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습</category>
      <category>Collections</category>
      <category>java</category>
      <category>java 코딩</category>
      <category>StringBuilder</category>
      <category>문자열내림차순으로배치하기</category>
      <category>문자열다루기</category>
      <category>알고리즘</category>
      <category>알고리즘 기초</category>
      <category>프로그래머스</category>
      <category>프로그래머스 기초</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/136</guid>
      <comments>https://javacoding.tistory.com/136#entry136comment</comments>
      <pubDate>Thu, 20 Aug 2020 22:38:23 +0900</pubDate>
    </item>
    <item>
      <title>[ 프로그래머스 ] 문자열 다루기 기본 JAVA</title>
      <link>https://javacoding.tistory.com/135</link>
      <description>&lt;h2&gt;&lt;span&gt;&lt;b&gt;문자열 다루기 기본&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요. 예를 들어 s가 a234이면 False를 리턴하고 1234라면 True를 리턴하면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;제한 사항&lt;/span&gt;&lt;/p&gt;
&lt;ul data-mark=&quot;-&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;`&lt;/span&gt;s&lt;span&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span&gt;는 길이 1 이상, 길이 8 이하인 문자열입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;a234&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;1234&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1597203222845&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
    public boolean solution(String s) {
        if(s.length() == 4 || s.length() == 6) {
			for (int i = 0; i &amp;lt; s.length(); i++) {
				char ch = s.charAt(i);
				if(ch &amp;lt; '0' || ch &amp;gt; '9')
					return false;
			}
			return true;
		} else
			return false;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;아주 간단한 문제였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;입력으로 주어지는 문자열 s의 길이를 먼저 확인한 뒤,&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;주어지는 문자들이 숫자로 구성되어 있는지 확인하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;출처 : &lt;/span&gt;&lt;span&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12918&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/12918&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1597203274070&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 문자열 다루기 기본&quot; data-og-description=&quot;문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요. 예를 들어 s가 a234이면 False를 리턴하고 1234라면 True를 리턴하면 됩니다. 제한 사항 s는 길이 1 이��&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12918&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12918&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/brgoBJ/hyG71WeY2t/jCbSQz9yUwUjGutz36OLm0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bF12K1/hyG5Gzr5Df/QyvhXnUYS74vuEsnKUQVU0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12918&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12918&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/brgoBJ/hyG71WeY2t/jCbSQz9yUwUjGutz36OLm0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bF12K1/hyG5Gzr5Df/QyvhXnUYS74vuEsnKUQVU0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 문자열 다루기 기본&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;문자열 s의 길이가 4 혹은 6이고, 숫자로만 구성돼있는지 확인해주는 함수, solution을 완성하세요. 예를 들어 s가 a234이면 False를 리턴하고 1234라면 True를 리턴하면 됩니다. 제한 사항 s는 길이 1 이��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습</category>
      <category>java</category>
      <category>JAVA 기본</category>
      <category>Java 기초</category>
      <category>java 알고리즘</category>
      <category>java 코딩</category>
      <category>문자열</category>
      <category>문자열 다루기</category>
      <category>문자열 다루기 기본</category>
      <category>코딩테스트 연습</category>
      <category>프로그래머스</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/135</guid>
      <comments>https://javacoding.tistory.com/135#entry135comment</comments>
      <pubDate>Wed, 12 Aug 2020 12:35:06 +0900</pubDate>
    </item>
    <item>
      <title>[ 프로그래머스 ] 서울에서 김서방 찾기 JAVA</title>
      <link>https://javacoding.tistory.com/134</link>
      <description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;서울에서 김서방 찾기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;String형 배열 seoul의 element중 Kim의 위치 x를 찾아, 김서방은 x에 있다는 String을 반환하는 함수, solution을 완성하세요. seoul에 Kim은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;제한 사항&lt;/span&gt;&lt;/p&gt;
&lt;ul data-mark=&quot;-&quot;&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;seoul은 길이 1 이상, 1000 이하인 배열입니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;seoul의 원소는 길이 1 이상, 20 이하인 문자열입니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span&gt;Kim은 반드시 seoul 안에 포함되어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;[Jane, Kim]&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;김서방은 1에 있다&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1596889263211&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
  public String solution(String[] seoul) {
      	String tmp = &quot;Kim&quot;;
		for (int i = 0; i &amp;lt; seoul.length; i++) {
			if(seoul[i].equals(tmp)) {
				tmp = &quot;김서방은 &quot; + i + &quot;에 있다&quot;;
                break;
			}
		}
      return tmp;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;String temp에 &quot;Kim&quot;을 저장해두고 for문을 이용하여 정답을 찾았습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;input으로 주어지는 seoul[i] 번째가 tmp와 같다면, &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;break한 뒤에 return 해주었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;출처 : &lt;/span&gt;&lt;span&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12919&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/12919&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1596889279817&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 서울에서 김서방 찾기&quot; data-og-description=&quot;String형 배열 seoul의 element중 Kim의 위치 x를 찾아, 김서방은 x에 있다는 String을 반환하는 함수, solution을 완성하세요. seoul에 Kim은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니다. 제&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12919&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12919&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/oJVgQ/hyG3TLV27f/s6mwYSRMB75iKcKoQOOBQ0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bTBgh7/hyG31wr9y0/mu3bEHlh4lfo8B90EOspDk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12919&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12919&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/oJVgQ/hyG3TLV27f/s6mwYSRMB75iKcKoQOOBQ0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bTBgh7/hyG31wr9y0/mu3bEHlh4lfo8B90EOspDk/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 서울에서 김서방 찾기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;String형 배열 seoul의 element중 Kim의 위치 x를 찾아, 김서방은 x에 있다는 String을 반환하는 함수, solution을 완성하세요. seoul에 Kim은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니다. 제&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습</category>
      <category>Java 기초</category>
      <category>java 알고리즘</category>
      <category>java 코딩</category>
      <category>programmers</category>
      <category>서울에서 김서방 찾기</category>
      <category>알고리즘</category>
      <category>코딩연습</category>
      <category>코테 연습</category>
      <category>프로그래머스</category>
      <category>프로그래머스 Lv1</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/134</guid>
      <comments>https://javacoding.tistory.com/134#entry134comment</comments>
      <pubDate>Sat, 8 Aug 2020 21:22:05 +0900</pubDate>
    </item>
    <item>
      <title>[ 프로그래머스 ] 소수 찾기 JAVA</title>
      <link>https://javacoding.tistory.com/133</link>
      <description>&lt;h2&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2&gt;&lt;span&gt;&lt;b&gt;소수 찾기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수, solution을 만들어 보세요.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;소수는 1과 자기 자신으로만 나누어지는 수를 의미합니다.&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;(1은 소수가 아닙니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;제한 조건&lt;/span&gt;&lt;/p&gt;
&lt;ul data-mark=&quot;-&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;span&gt;n은 2이상 1000000이하의 자연수입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;10&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;입출력 예 설명&lt;/span&gt;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;입출력 예 #1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1부터 10 사이의 소수는 [2,3,5,7] 4개가 존재하므로 4를 반환&lt;/span&gt;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;입출력 예 #2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;1부터 5 사이의 소수는 [2,3,5] 3개가 존재하므로 3를 반환&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1596887833556&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
  public int solution(int n) {
		int answer = 0;
		boolean[] checked = new boolean[n + 1];

		for (int i = 2; i &amp;lt;= n; i++) {
			if (!checked[i])
				answer++;
			for (int j = i; j &amp;lt;= n; j += i) {
				if (!checked[j])
					checked[j] = true;
			}
		}      
      return answer;
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;이전에 공부했었던 에라토스테네스의 체를 활용하여 풀이하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;**&lt;/span&gt;&lt;b&gt;&lt;span&gt;에라토스테네스의 체에 대해 알고 있다면 풀이에 도움이 될 것 같아 관련 자료를 찾아보았습니다.&lt;/span&gt;&lt;/b&gt;&lt;span&gt;**&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span data-src=&quot;https://blog.kakaocdn.net/dn/LucuQ/btqARxJsGyA/NgJbnKpoDwLeXhNQefa9ZK/img.gif&quot; data-root=&quot;C:\Users\user\Desktop\workalgo\java-algorithm-study\Solution_programmers_Lv1.md&quot; data-copy-from-path=&quot;C:\Users\user\Desktop\workalgo\java-algorithm-study\Solution_programmers_Lv1.md&quot;&gt;&lt;span&gt;&lt;span&gt;![img](&lt;/span&gt;&lt;span&gt;&lt;a href=&quot;https://blog.kakaocdn.net/dn/LucuQ/btqARxJsGyA/NgJbnKpoDwLeXhNQefa9ZK/img.gif&quot;&gt;https://blog.kakaocdn.net/dn/LucuQ/btqARxJsGyA/NgJbnKpoDwLeXhNQefa9ZK/img.gif&lt;/a&gt;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ciDoAz/btqGp153Ejx/RvDkMwkXetGLkUJ05gEVD1/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ciDoAz/btqGp153Ejx/RvDkMwkXetGLkUJ05gEVD1/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ciDoAz/btqGp153Ejx/RvDkMwkXetGLkUJ05gEVD1/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/ciDoAz/btqGp153Ejx/RvDkMwkXetGLkUJ05gEVD1/img.gif&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;**&lt;/span&gt;&lt;b&gt;&lt;span&gt;출처 : 위키백과&lt;/span&gt;&lt;/b&gt;&lt;span&gt;**&lt;/span&gt;&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4&quot;&gt;https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1596887977592&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;에라토스테네스의 체 - 위키백과, 우리 모두의 백과사전&quot; data-og-description=&quot;위키백과, 우리 모두의 백과사전. 수학에서 에라토스테네스의 체는 소수(素數, 발음: [소쑤])를 찾는 방법이다. 고대 그리스 수학자 에라토스테네스가 발견하였다. 알고리즘[편집] 2부터 소수를 �&quot; data-og-host=&quot;ko.wikipedia.org&quot; data-og-source-url=&quot;https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4&quot; data-og-url=&quot;https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bPnK0I/hyG3WPoPnt/Zl0pA3Rfxlo7K6fEr29RUK/img.gif?width=445&amp;amp;height=369&amp;amp;face=0_0_445_369&quot;&gt;&lt;a href=&quot;https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ko.wikipedia.org/wiki/%EC%97%90%EB%9D%BC%ED%86%A0%EC%8A%A4%ED%85%8C%EB%84%A4%EC%8A%A4%EC%9D%98_%EC%B2%B4&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bPnK0I/hyG3WPoPnt/Zl0pA3Rfxlo7K6fEr29RUK/img.gif?width=445&amp;amp;height=369&amp;amp;face=0_0_445_369');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;에라토스테네스의 체 - 위키백과, 우리 모두의 백과사전&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;위키백과, 우리 모두의 백과사전. 수학에서 에라토스테네스의 체는 소수(素數, 발음: [소쑤])를 찾는 방법이다. 고대 그리스 수학자 에라토스테네스가 발견하였다. 알고리즘[편집] 2부터 소수를 �&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;ko.wikipedia.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;**&lt;/span&gt;&lt;b&gt;&lt;span&gt;먼저 소수를 찾기 위해 boolean 배열 checked를 만들었습니다.&lt;/span&gt;&lt;/b&gt;&lt;span&gt;**&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;**&lt;/span&gt;&lt;b&gt;&lt;span&gt;그리고 나서, 2부터 n까지 i의 만큼씩 더해 반복하며 소수에 해당하지 않는 수는&lt;/span&gt;&lt;/b&gt;&lt;span&gt;**&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;**&lt;/span&gt;&lt;b&gt;&lt;span&gt;checked 배열에 true 처리하여 표시해주었습니다. ( 에라토스테네스의 체와 유사하게 )&lt;/span&gt;&lt;/b&gt;&lt;span&gt;**&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;**&lt;/span&gt;&lt;b&gt;&lt;span&gt;모두 표시해준 이후 checked 배열이 false인 숫자들만 카운트 해주었습니다.&lt;/span&gt;&lt;/b&gt;&lt;span&gt;**&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;출처 : &lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12921&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/12921&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1596887936555&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 소수 찾기&quot; data-og-description=&quot;1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수, solution을 만들어 보세요. 소수는 1과 자기 자신으로만 나누어지는 수를 의미합니다. (1은 소수가 아닙니다.) 제한 조건 n은 2이상&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12921&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12921&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BqV3B/hyG32vlkpH/IVKudovAXrMKtkRyTIK6P0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/ZBUxd/hyG3TSGwaz/Yi7PR6kAl0OFldQqPsXcwK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12921&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12921&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BqV3B/hyG32vlkpH/IVKudovAXrMKtkRyTIK6P0/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/ZBUxd/hyG3TSGwaz/Yi7PR6kAl0OFldQqPsXcwK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 소수 찾기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;1부터 입력받은 숫자 n 사이에 있는 소수의 개수를 반환하는 함수, solution을 만들어 보세요. 소수는 1과 자기 자신으로만 나누어지는 수를 의미합니다. (1은 소수가 아닙니다.) 제한 조건 n은 2이상&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습</category>
      <category>java 소수</category>
      <category>java 코딩</category>
      <category>JAVA 코테</category>
      <category>소수</category>
      <category>소수 알고리즘</category>
      <category>소수찾기</category>
      <category>알고리즘 기초</category>
      <category>에라토스테네스의체</category>
      <category>코딩테스트</category>
      <category>코테 연습</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/133</guid>
      <comments>https://javacoding.tistory.com/133#entry133comment</comments>
      <pubDate>Sat, 8 Aug 2020 21:04:41 +0900</pubDate>
    </item>
    <item>
      <title>[ 프로그래머스 ] 수박수박수박수박수박수?</title>
      <link>https://javacoding.tistory.com/132</link>
      <description>&lt;h2&gt;&lt;span&gt;&lt;b&gt;수박수박수박수박수박수?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;길이가 n이고, 수박수박수박수....와 같은 패턴을 유지하는 문자열을 리턴하는 함수, solution을 완성하세요. 예를들어 n이 4이면 수박수박을 리턴하고 3이라면 수박수를 리턴하면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;제한 조건&lt;/span&gt;&lt;/p&gt;
&lt;ul data-mark=&quot;-&quot;&gt;
&lt;li&gt;
&lt;p&gt;&lt;span&gt;n은 길이 10,000이하인 자연수입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;수박수&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;&lt;span&gt;수박수박&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1596632761392&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
  public String solution(int n) {
      	int m = n;
		StringBuilder sb = new StringBuilder();
		while (n &amp;gt; 0) {
			if ((m - n) % 2 == 0)
				sb.append(&quot;수&quot;);
			else
				sb.append(&quot;박&quot;);
			n--;
		}
		return sb.toString();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;StringBuilder를 사용하여 풀이하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;변수 m을 만들어 시작할 때의 n 값을 저장한 뒤&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;span&gt;**&lt;/span&gt;&lt;b&gt;&lt;span&gt;(m-n) % 2 == 0&lt;/span&gt;&lt;/b&gt;&lt;span&gt;**&lt;/span&gt;&lt;/span&gt;&lt;span&gt; 연산으로 n을 1씩 감소하며 문자를 덧붙여주었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;출처 : &lt;/span&gt;&lt;span&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12922&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/12922&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1596632749975&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 수박수박수박수박수박수?&quot; data-og-description=&quot;길이가 n이고, 수박수박수박수....와 같은 패턴을 유지하는 문자열을 리턴하는 함수, solution을 완성하세요. 예를들어 n이 4이면 수박수박을 리턴하고 3이라면 수박수를 리턴하면 됩니다. 제한 조��&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12922&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12922&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/zO444/hyG2oECXRQ/xp9XCFZAUPeeMypBbEpKsK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bAOVLt/hyG2iqScsZ/JTcyVdABCz0XTZVXRx3pm1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12922&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12922&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/zO444/hyG2oECXRQ/xp9XCFZAUPeeMypBbEpKsK/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bAOVLt/hyG2iqScsZ/JTcyVdABCz0XTZVXRx3pm1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 수박수박수박수박수박수?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;길이가 n이고, 수박수박수박수....와 같은 패턴을 유지하는 문자열을 리턴하는 함수, solution을 완성하세요. 예를들어 n이 4이면 수박수박을 리턴하고 3이라면 수박수를 리턴하면 됩니다. 제한 조��&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습</category>
      <category>java</category>
      <category>java 코딩</category>
      <category>JAVA기초</category>
      <category>기초 코딩</category>
      <category>알고리즘</category>
      <category>알고리즘 기초</category>
      <category>알고리즘 연습</category>
      <category>코딩 초보</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/132</guid>
      <comments>https://javacoding.tistory.com/132#entry132comment</comments>
      <pubDate>Wed, 5 Aug 2020 22:06:52 +0900</pubDate>
    </item>
    <item>
      <title>[ 프로그래머스 ] 문자열을 정수로 바꾸기 JAVA</title>
      <link>https://javacoding.tistory.com/131</link>
      <description>&lt;h2&gt;&lt;span&gt;&lt;b&gt;문자열을 정수로 바꾸기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문제 설명&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;문자열 s를 숫자로 변환한 결과를 반환하는 함수, solution을 완성하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;제한 조건&lt;/span&gt;&lt;/p&gt;
&lt;ul data-mark=&quot;-&quot;&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;s의 길이는 1 이상 5이하입니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;s의 맨앞에는 부호(+, -)가 올 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;s는 부호와 숫자로만 이루어져있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;span&gt;s는 0으로 시작하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span&gt;입출력 예&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;예를들어 str이 1234이면 1234를 반환하고, -1234이면 -1234를 반환하면 됩니다.&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;span&gt;str은 부호(+,-)와 숫자로만 구성되어 있고, 잘못된 값이 입력되는 경우는 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1596632030709&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
  public int solution(String s) {
      return Integer.parseInt(s);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;JAVA 언어를 사용하는 사람들에게는 너무 쉬운 문제입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Integer.parseInt() 함수를 사용하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;출처 : &lt;/span&gt;&lt;span&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12925&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/12925&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1596632023605&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 문자열을 정수로 바꾸기&quot; data-og-description=&quot;문자열 s를 숫자로 변환한 결과를 반환하는 함수, solution을 완성하세요. 제한 조건 s의 길이는 1 이상 5이하입니다. s의 맨앞에는 부호(+, -)가 올 수 있습니다. s는 부호와 숫자로만 이루어져있습니&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12925&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12925&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ffJc3/hyG2xO6gTa/YAmeFZEoyy3CwiMCFxFmd1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bUkLru/hyG2vqbFac/BzYtwZw99qcutviu9jS4Ok/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12925&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12925&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ffJc3/hyG2xO6gTa/YAmeFZEoyy3CwiMCFxFmd1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bUkLru/hyG2vqbFac/BzYtwZw99qcutviu9jS4Ok/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 문자열을 정수로 바꾸기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;문자열 s를 숫자로 변환한 결과를 반환하는 함수, solution을 완성하세요. 제한 조건 s의 길이는 1 이상 5이하입니다. s의 맨앞에는 부호(+, -)가 올 수 있습니다. s는 부호와 숫자로만 이루어져있습니&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습</category>
      <category>Integer.parseInt()</category>
      <category>Integer함수</category>
      <category>java</category>
      <category>Java 기초</category>
      <category>java 코딩</category>
      <category>JAVA 코테</category>
      <category>programmers</category>
      <category>문자열 기초</category>
      <category>코딩</category>
      <category>프로그래머스</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/131</guid>
      <comments>https://javacoding.tistory.com/131#entry131comment</comments>
      <pubDate>Wed, 5 Aug 2020 21:54:36 +0900</pubDate>
    </item>
    <item>
      <title>[ 프로그래머스 ] 시저암호 JAVA</title>
      <link>https://javacoding.tistory.com/130</link>
      <description>&lt;h2&gt;&lt;span&gt;&lt;b&gt;시저암호&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;문제 설명&lt;/p&gt;
&lt;p&gt;어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어&lt;span&gt;&amp;nbsp;&lt;/span&gt;AB는 1만큼 밀면&lt;span&gt;&amp;nbsp;&lt;/span&gt;BC가 되고, 3만큼 밀면&lt;span&gt;&amp;nbsp;&lt;/span&gt;DE가 됩니다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;z는 1만큼 밀면&lt;span&gt;&amp;nbsp;&lt;/span&gt;a가 됩니다. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수, solution을 완성해 보세요.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;제한 조건&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;공백은 아무리 밀어도 공백입니다.&lt;/li&gt;
&lt;li&gt;s는 알파벳 소문자, 대문자, 공백으로만 이루어져 있습니다.&lt;/li&gt;
&lt;li&gt;s의 길이는 8000이하입니다.&lt;/li&gt;
&lt;li&gt;n은 1 이상, 25이하인 자연수입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;입출력 예&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AB&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;BC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;z&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a B z&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;e F d&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1596249042423&quot; class=&quot;java&quot; style=&quot;margin: 20px auto 0px; display: block; overflow: auto; padding: 15px; color: #383a42; background: #f6f7f8; font-size: 14px; border-radius: 3px; font-family: Menlo, Consolas, Monaco, monospace; border: 1px solid #dddddd; cursor: default; z-index: 1;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution {
  public String solution(String s, int n) {
      	StringBuilder sb = new StringBuilder();

		for (int i = 0; i &amp;lt; s.length(); i++) {
			char ch = s.charAt(i);

			if (ch &amp;gt;= 'a' &amp;amp;&amp;amp; ch &amp;lt;= 'z') {
				ch = (char) (ch + n);
				if (ch &amp;gt; 'z')
					ch -= 26;
			} else if (ch &amp;gt;= 'A' &amp;amp;&amp;amp; ch &amp;lt;= 'Z') {
				ch = (char) (ch + n);
				if (ch &amp;gt; 'Z')
					ch -= 26;
			}

			sb.append(ch);
		}

		return sb.toString();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;StringBuilder와 문자의 덧셈을 이용하여 풀이하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;먼저 각 문자가 소문자인 경우 &lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;if (ch &amp;gt;= 'a' &amp;amp;&amp;amp; ch &amp;lt;= 'z')&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;와 &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;대문자인 경우 &lt;/span&gt;&lt;span&gt;&lt;b&gt;&lt;span&gt;else if (ch &amp;gt;= 'A' &amp;amp;&amp;amp; ch &amp;lt;= 'Z')&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;로 나누었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p contenteditable=&quot;true&quot;&gt;&lt;span&gt;각각의 경우에 모두 ch에 n을 더해주었고 'z' 혹은 'Z' 보다 커지는 경우에는 -26 연산을 이용하였습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12926&quot;&gt;&lt;span&gt;출처 : &lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12926&quot;&gt;https://programmers.co.kr/learn/courses/30/lessons/12926&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1596249149690&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-og-type=&quot;website&quot; data-og-title=&quot;코딩테스트 연습 - 시저 암호&quot; data-og-description=&quot;어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 AB는 1만큼 밀면 BC가 되고, 3만큼 밀면 DE가 됩니다. z는 1만큼 밀면 a가&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12926&quot; data-og-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12926&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/clpBQ8/hyGXFOwXBS/QX5aAAO27rJuz7AfUUDNd1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bEcJqn/hyGYLzCpoJ/48b6rB9VmT39M3yJiTkFv1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626&quot;&gt;&lt;a href=&quot;https://programmers.co.kr/learn/courses/30/lessons/12926&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://programmers.co.kr/learn/courses/30/lessons/12926&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/clpBQ8/hyGXFOwXBS/QX5aAAO27rJuz7AfUUDNd1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626,https://scrap.kakaocdn.net/dn/bEcJqn/hyGYLzCpoJ/48b6rB9VmT39M3yJiTkFv1/img.jpg?width=626&amp;amp;height=626&amp;amp;face=0_0_626_626');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot;&gt;코딩테스트 연습 - 시저 암호&lt;/p&gt;
&lt;p class=&quot;og-desc&quot;&gt;어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 AB는 1만큼 밀면 BC가 되고, 3만큼 밀면 DE가 됩니다. z는 1만큼 밀면 a가&lt;/p&gt;
&lt;p class=&quot;og-host&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘 연습</category>
      <category>JAVA 코테</category>
      <category>JAVA기초</category>
      <category>JAVA알고리즘</category>
      <category>programmers</category>
      <category>시저암호</category>
      <category>시저암호 JAVA</category>
      <category>알고리즘 기초</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <category>프로그래머스 Lv1</category>
      <author>코딩하는 너구리</author>
      <guid isPermaLink="true">https://javacoding.tistory.com/130</guid>
      <comments>https://javacoding.tistory.com/130#entry130comment</comments>
      <pubDate>Sat, 1 Aug 2020 11:33:15 +0900</pubDate>
    </item>
  </channel>
</rss>